views:

3090

answers:

2

I am trying to hook for example Notepad without sucess. Making a global hook seems to work fine.

Testing on XP SP2.

Edit: Amended code works now.

MyDLL code

#include <windows.h>
#include <iostream>
#include <stdio.h>

HINSTANCE hinst;
#pragma data_seg(".shared")
HHOOK hhk;
#pragma data_seg()
//#pragma comment(linker, "/SECTION:.shared,RWS") compiler error in VC++ 2008 express

LRESULT CALLBACK wireKeyboardProc(int code, WPARAM wParam,LPARAM lParam) {  
    if (code < 0) {
     return CallNextHookEx(0, code, wParam, lParam);
    }
    Beep(1000, 20);
    return CallNextHookEx(hhk, code, wParam, lParam);
}

extern "C" __declspec(dllexport) void install(unsigned long threadID) { 
    hhk = SetWindowsHookEx(WH_KEYBOARD, wireKeyboardProc, hinst, threadID);
}
extern "C" __declspec(dllexport) void uninstall() {
    UnhookWindowsHookEx(hhk); 
}

BOOL WINAPI DllMain(__in HINSTANCE hinstDLL, __in  DWORD fdwReason, __in  LPVOID lpvReserved) {
    hinst = hinstDLL;
    return TRUE;
}

My program

#include <Windows.h>

unsigned long GetTargetThreadIdFromWindow(char *className, char *windowName)
{
    HWND targetWnd;
    HANDLE hProcess;
    unsigned long processID = 0;

    targetWnd = FindWindow(className, windowName);
    return GetWindowThreadProcessId(targetWnd, &processID);
} 

int _tmain(int argc, _TCHAR* argv[]) {
    unsigned long threadID = GetTargetProcessIdFromWindow("Notepad", "Untitled - Notepad");
    printf("TID: %i", threadID); 

    HINSTANCE hinst = LoadLibrary(_T("MyDLL.dll")); 

    if (hinst) {
     typedef void (*Install)(unsigned long);
     typedef void (*Uninstall)();

     Install install = (Install) GetProcAddress(hinst, "install");
     Uninstall uninstall = (Uninstall) GetProcAddress(hinst, "uninstall");

     install(threadID);

     Sleep(20000);

     uninstall();
    }

    return 0;
}
+7  A: 

Three problems:

You're using the process ID when you should be using the thread ID.

Your HHOOK needs to go into shared memory:

#pragma data_seg(".shared")
HHOOK hhk = NULL;
#pragma data_seg()
#pragma comment(linker, "/SECTION:.shared,RWS")

You need to pass your HHOOK to CallNextHookEx:

return CallNextHookEx( hhk, code, wParam, lParam);
RichieHindle
GetWindowThreadProcessId() returns the thread ID you need (as its return value). Whatever you're doing with inline assembler and ReadProcessMemory is not necessary, and almost certainly not working.
RichieHindle
you also need to initialize `hhk` to `0` or it won't get shared properly
yoyoyoyosef
@yoyoyoyosef: Thanks - fixed.
RichieHindle
A: 

You absolutely don't need any DLL Notepad hooking source code has been posted many times on Google Groups. See mainly on winapigroup http://tinyurl.com/cmhb5g (C code)

Yes, right, even in C++. It's one of the most classic hook samples for more than 15 years ! It's incredible to post again such a question...

Wow, you people are really persistent. Get over the usenet/google groups already. If you really wanted to be helpful, you'd post a link to the post that answers the question at hand, not to group's index page.
macbirdie