Thursday, May 5, 2011

How to hook external process with SetWindowsHookEx and WH_KEYBOARD

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;
}
From stackoverflow
  • 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.
    yoyoyoyosef : you also need to initialize `hhk` to `0` or it won't get shared properly
    RichieHindle : @yoyoyoyosef: Thanks - fixed.
  • 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...

    macbirdie : 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.

0 comments:

Post a Comment