2009-05-04 11 views
6

Próbuję podłączyć np. Notatnik bez powodzenia. Tworzenie globalnego haka wydaje się działać dobrze.Jak podpiąć proces zewnętrzny za pomocą SetWindowsHookEx i WH_KEYBOARD

Testowanie w XP SP2.

Edytuj: Zmieniony kod działa teraz.

kod MyDLL

#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; 
} 

Mój 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; 
} 

Odpowiedz

13

trzy problemy:

Używasz identyfikator procesu, gdy powinien być używany identyfikator wątku.

Twój HHOOK musi iść do pamięci współdzielonej:

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

Trzeba zdać HHOOK do CallNextHookEx:

return CallNextHookEx(hhk, code, wParam, lParam); 
+1

GetWindowThreadProcessId() zwraca identyfikator wątku, czego potrzeba (jako wartości zwracanej) . Cokolwiek robisz z wbudowanym asemblerem i ReadProcessMemory nie jest konieczne i prawie na pewno nie działa. – RichieHindle

+2

musisz również zainicjować 'hhk' na' 0' lub nie zostanie ono poprawnie udostępnione – yoyoyoyosef

+0

@yoyoyoyosef: Thanks - fixed. – RichieHindle