Hook funktioniert nicht
-
Hi,
ich wollte einen Tastaturhook bauen. deshalb habe ich viel rumgesucht, hab aber nirgends eine brauchbare lauffähige Lösung gefunden
Irgendwann hab ich dann den code für die dll gefunden, der auch kompiliert hat. Aus einem ähnlichen programm habe ich dann auch noch den code für die main-funktion gefunden.(den hab ich gebraucht, weil ich nicht wusste, wie ich sonst an die variable hwnd komme.)
Aber es funktioniert nicht(siehe unten)hookdll.c
#include <iostream> #include <windows.h> #include "hookdll.h" #pragma data_seg ("Shared") HWND hWindow = 0 ; #pragma data_seg () #pragma comment (linker, "/section:Shared,RWS") LRESULT CALLBACK KeyboardHookProc (int, WPARAM, LPARAM) ; // Der Prototyp der Funktion KeyboardHookProc HHOOK hhkHook ; HINSTANCE hDllInstance ; // Definition globaler Variablen /************************************************************************/ /* DllMain: wird automatisch aufgerufen, wenn die DLL mit LoadLibrary() */ /* geladen, oder mit FreeLibrary wieder freigegeben wird. */ /* Eingabe Parameter: Systemspezifische Daten */ /* Return-Wert: TRUE */ /************************************************************************/ int APIENTRY DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved){ switch (fdwReason){ case DLL_PROCESS_ATTACH : // Die DLL wird in den Adressraum des aktuellen Prozesses // eingeblendet. hDllInstance = hInstance ; // Initialisierung der globalen Variable break ; } return TRUE ; } /***********************************************************/ /* SetupHook: EXPORT Funktion, setzt den Keyboardhook */ /* Eingabe Parameter: HWND des aufrufenden Fensters */ /* Return-Wert: TRUE */ /***********************************************************/ EXPORT BOOL CALLBACK SetupHook (HWND hParent){ [b]std::cout << "b";[/b] hWindow = hParent ; // Initialisierung der globalen Variable mit dem Eingabe Parameter hhkHook = SetWindowsHookEx (WH_KEYBOARD, KeyboardHookProc, hDllInstance, NULL) ; // Keyboardhook setzen und das Ergebnis in der globalen Variable // hhkHook speichern. return TRUE ; } /*******************************************************************/ /* KeyboardHookProc: wird jedes mal aufgerufen, wenn eine Taste */ /* betätigt wird */ /* Eingabe Parameter: Systemspezifische Daten */ /* Return-Wert: s. u. */ /*******************************************************************/ LRESULT CALLBACK KeyboardHookProc (int nCode, WPARAM wParam, LPARAM lParam){ [b]std::cout << "c";[/b] if (nCode == HC_ACTION){ // Verhindern das eine Nachricht mehrmals verarbeitet wird. if ((lParam & 1073741824) != 1073741824){ // Überprüfen ab vor dem Aufruf dieser Funktion die Taste bereits gedrückt war SendMessage ((HWND) hWindow, (WM_USER + 2), (WPARAM) wParam, (LPARAM) lParam) ; // Senden der Nachricht (WM_USER + 2) und den Tastencode der gedrückten // Taste (gespeichert in "wParam") an das in der globalen Variable // hWindow gespeicherte Fensterhandle. } } return CallNextHookEx (hhkHook, nCode, wParam, lParam) ; // Die Nachrichten an den nächsten Hook weiterreichen. } /*********************************************************************/ /* UninstalHook: EXPORT Funktion, löscht den über die Funktion */ /* SetupHook gesetzten Hook */ /* Eingabe Parameter: keine */ /* Return-Wert: TRUE */ /*********************************************************************/ EXPORT BOOL CALLBACK UninstallHook (void){ UnhookWindowsHookEx (hhkHook) ; // den in der globalen Variable hhkHook gespeicherten Hook löschen. return TRUE ; }
hookdll.h
#ifdef __cplusplus #define EXPORT extern "C" __declspec (dllexport) #else #define EXPORT __declspec (dllexport) #endif // Funktonalität sowohl unter C als auch unter C++ gegeben EXPORT BOOL CALLBACK SetupHook (HWND) ; EXPORT BOOL CALLBACK UninstallHook (void) ; // Die Prototypen der EXPORT Funktionen
Aus diesen beiden Dateien mache ich mittels:
g++ -shared hookdll.c -o hookdll.dll
die hookdll.dll
Dann kommt mein Hauptprogramm:
#include <windows.h> #include "hookdll.h" #include <iostream> /* Declare Windows procedure */ LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); /* Make the class name into a global variable */ char szClassName[ ] = "WindowsApp"; int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) { HWND hwnd; /* This is the handle for our window */ MSG messages; /* Here messages to the application are saved */ WNDCLASSEX wincl; /* Data structure for the windowclass */ /* The Window structure */ wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ wincl.style = CS_DBLCLKS; /* Catch double-clicks */ wincl.cbSize = sizeof (WNDCLASSEX); /* Use default icon and mouse-pointer */ wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wincl.hCursor = LoadCursor (NULL, IDC_ARROW); wincl.lpszMenuName = NULL; /* No menu */ wincl.cbClsExtra = 0; /* No extra bytes after the window class */ wincl.cbWndExtra = 0; /* structure or the window instance */ /* Use Windows's default color as the background of the window */ wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; /* Register the window class, and if it fails quit the program */ if (!RegisterClassEx (&wincl)) return 0; /* The class is registered, let's create the program*/ hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ "Windows App", /* Title Text */ WS_OVERLAPPEDWINDOW, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ 544, /* The programs width */ 375, /* and height in pixels */ HWND_DESKTOP, /* The window is a child-window to desktop */ NULL, /* No menu */ hThisInstance, /* Program Instance handler */ NULL /* No Window Creation data */ ); SetupHook (hwnd); [b]std::cout << "a";[/b] /* Make the window visible on the screen */ ShowWindow (hwnd, nFunsterStil); /* Run the message loop. It will run until GetMessage() returns 0 */ while (GetMessage (&messages, NULL, 0, 0)) { /* Translate virtual-key messages into character messages */ TranslateMessage(&messages); /* Send message to WindowProcedure */ DispatchMessage(&messages); } /* The program return-value is 0 - The value that PostQuitMessage() gave */ return messages.wParam; } /* This function is called by the Windows function DispatchMessage() */ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) /* handle the messages */ { case WM_DESTROY: PostQuitMessage (0); /* send a WM_QUIT to the message queue */ break; default: /* for messages that we don't deal with */ return DefWindowProc (hwnd, message, wParam, lParam); } return 0; }
daraus mache ich dann mittels:
g++ main.cpp hookdll.dll -o main.exe
eine ausführbare datei.
wenn ich die starte, wird auf der konsole aber nur "ba" ausgegeben, und niemals "c". woran liegt das?Mfg DerBaer
-
also erstmal denke ich das du nicht ganz verstanden hast wozu so ein keyhook gut ist.
was willst du mit dem keyhook in deinem programm? da ist er doch sinlos. in deinem programm kannst du tastaturnachrichten mit DEINER WindowProcedure abfangen.
einen Keyhook schleust man in ein fremdes programm ein, wenn man wissen will welche taste dort getrückt wurde.
und "ba" steht bei dir weil du in deiner WinMain die Funktion
SetupHook (HWND hParent)
aufrufst und direckt danach
std::cout << "a";
-
@rT!f@Ct schrieb:
also erstmal denke ich das du nicht ganz verstanden hast wozu so ein keyhook gut ist.
möglich. vielleicht verwechsel ich auch grad was.
was willst du mit dem keyhook in deinem programm? da ist er doch sinlos. in deinem programm kannst du tastaturnachrichten mit DEINER WindowProcedure abfangen.
einen Keyhook schleust man in ein fremdes programm ein, wenn man wissen will welche taste dort getrückt wurde.Im prinzip will ich folgendes:
wenn der benutzer irgendwann, irgendwo(in irgendeinem programm) irgendeine taste drückt, etwas machen. Z.b. sobald man F10 drückt schaltet sich der computer aus.und "ba" steht bei dir weil du in deiner WinMain die Funktion
SetupHook (HWND hParent)
aufrufst und direckt danach
std::cout << "a";wieso "ba" ausgegebn wird weiß ich, aber wieso niemls "c" ausgegeben wird weiß ich nicht.
/*******************************************************************/
/* KeyboardHookProc: wird jedes mal aufgerufen, wenn eine Taste betätigt wird */Das heißt für mich, dass ich entweder keine taste gedrückt habe, oder das irgend ein fehler im programm ist.
Achja, das gepostete programm ist natürlich noch sinnlos, aber erst sollte es prinzipiell funktionieren, dann baue ich die echten funktionen ein.
Mfg
-
wenn der benutzer irgendwann, irgendwo(in irgendeinem programm) irgendeine taste drückt, etwas machen. Z.b. sobald man F10 drückt schaltet sich der computer aus
dann solltest du den hook systemweit installieren und nicht in deinem programm.
kann nämlich gut möglich sein, das genau aus diesem grund (in deinem prog) der hook nicht funzt.ich habe vor etwas längere zeit das gleiche beispiel genutzt wie du und bei mir hat es geklappt.
auch solltest du in der Main.cpp folgendes definieren
typedef BOOL (*SetupHookDll)(HWND); typedef BOOL (*UninstallHookDll)(void); SetupHookDll m_pSetupHookDll = NULL; UninstallHookDll m_pUninstallHookDll = NULL;
in einer Funktion von der aus du den Hook inizialisieren willst sollte folgendes stehen.
HMODULE hMyDll = NULL; hMyDll = LoadLibrary("C:\\PfadZuDerHookDll\\KeyHook.dll"); if(hMyDll == NULL) { MessageBox(0,"Dll nicht gefunden!\n","",IDOK); return; } m_pSetupHookDll = (SetupHookDll)GetProcAddress(hMyDll, "SetupHook"); if(m_pSetupHookDll == NULL) { MessageBox(0,"SetupHookDll Funktionen nicht gefunden!\n","",IDOK); return; } m_pSetupHookDll(hWnd);
-
quark der code da oben funzt genauso gut. aber wenn du keine ahnung von der arbeitsweise von hooks hast, solltest du sie auch nicht verwenden. immer das gleiche hier, echt man. die hook callback wird im kontext des jeweiligen prozesses aufgerufen, d.h. die hook.dll wird in den prozess eingeblendet. mach dir das bitte klar und lies mal die msdn durch, glaubste bill gates und steve balmer haben das alles zum spaß da aufgeschrieben, damit es keiner liest??
-
ascda schrieb:
quark
Japp. Er verwendet einfach nur den falschen Hook.
Ich würde den da:WH_KEYBOARD_LL
LL = Low Level
verwenden, wobei die Hook-Prozedur in einer DLL liegen sollte. Nach M-Schrott darf sie auch Applications-Scope haben.
-
WH_KEYBOARD_LL ist ned global hook
-
ascda schrieb:
WH_KEYBOARD_LL ist ned global hook
Dann hat sich M-Schrott wohl geirrt:
Hook Scope
WH_CALLWNDPROC Thread or global
WH_CALLWNDPROCRET Thread or global
WH_CBT Thread or global
WH_DEBUG Thread or global
WH_FOREGROUNDIDLE Thread or global
WH_GETMESSAGE Thread or global
WH_JOURNALPLAYBACK Global only
WH_JOURNALRECORD Global only
WH_KEYBOARD Thread or global
WH_KEYBOARD_LL Global only << hier ....
WH_MOUSE Thread or global
WH_MOUSE_LL Global only
WH_MSGFILTER Thread or global
WH_SHELL Thread or global
WH_SYSMSGFILTER Global onlyWir schreiben einen Brief nach Redmond.
-
However, the WH_KEYBOARD_LL hook is not injected into another process. Instead, the context switches back to the process that installed the hook and it is called in its original context. Then the context switches back to the application that generated the event.
-
ascda schrieb:
However, the WH_KEYBOARD_LL hook is not injected into another process. Instead, the context switches back to the process that installed the hook and it is called in its original context. Then the context switches back to the application that generated the event.
Selbst wenn der Low Level Keyboard Hook nicht injeziert wird, ist er dennoch ein globaler Hook!
-
Hi,
danke erstmal die die vielen Antworten.
Ich hab jetzt einiges rumprobiert und auch den Code von @rT!f@Ct eingebaut. Es kommt die Meldung, dass er die Funktion "SetupHook" nicht findet. Die Dll findet er aber, was die vermutung nahelegt, dass das problem an der Dll, bzw. der Verwendung der dll liegt.Und wenn ich Zeile 46:
hhkHook = SetWindowsHookEx (WH_KEYBOARD, KeyboardHookProc, hDllInstance, NULL) ;
durch
hhkHook = SetWindowsHookEx (WH_KEYBOARD, KeyboardHookProc, NULL, GetCurrentThreadId()) ;
ersetzte, werden TastaturEvents registriert(Ausgabe von "c"), solange der Focus bei meiner eigenen Form ist, sonst nicht(mit WH_KEYBOARD_LL geht es gar nicht)
Mfg
-
ich denke das dein fehler in der deklaration der Funktionen UninstallHook & SetupHook liegt
UninstallHook & SetupHook sind KEINE Callback funktionen ändere mal die deklaration der beiden funktionen in der header & quellcode datei der DLL wie folgt ab
*.h
EXPORT BOOL UninstallHook (void); EXPORT BOOL SetupHook (HWND hParent);
*.cpp
EXPORT BOOL UninstallHook (void) { //..... } EXPORT BOOL SetupHook (HWND hParent) { //...... }
-
Hi,
VIELEN DANK
Das EXPORT war die entscheidende Stelle. Jetzt funktioniert er prima.
Danke für die viele Arbeit, die ihr da reingesteckt habtMfg DerBaer