KeyboardHook, FAQ bsp will nicht funktionieren
-
Moi, SetWindowsHookEx mit !hmodule und ThreadID!=0 ?
SetWindowsHookEx
[...]
WH_KEYBOARD_LL Global only
[...]Also
hhkHook = SetWindowsHookEx (WH_KEYBOARD_LL, KeyboardHookProc, hDllInstance, 0);
-
zeusosc schrieb:
// Weise den Compiler an, die Variable hWindow in einem // separaten Abschnitt namens Shared unterzubringen // Darüber hinaus ist dann auch noch dem Linker mitzuteilen, // dass die Daten in diesem Abschnitt von allen Instanzen // dieser Anwendung gemeinsam verwendet werden sollen. // Ganz wichtig dabei ist, dass die Variablen initialisiert // sein müssen. #define SHARED __attribute__((section(".shr"), shared)) HWND hWindow = 0 ; // Weise den Compilern, den Abschnitt Shared als lesbar, // beschreibbar und zur gemeinsamen Verwendung zu deklarieren - "RSW". #pragma comment (linker, "/section:Shared,RWS")Ich habe nicht alles gelesen, stolpere nur hier über den Kommentar und die folgenden Instruktionen:
Laut Kommentar soll hWindow in einem shared-Segment untergebracht werden, das tust Du aber nicht. Du definierst zwar ein entsprechendes Makro für den MinGW, aber benutzt es nicht bei Definition von hWindow.
Das
#pragma comment (linker, "/section:Shared,RWS")
kannst Du hingegen weglassen, das gehört zu den MS-Compilern.
-
Also ich habe das folgend geändert:
#define SHARED __attribute__((section(".shr"), shared)) HWND SHARED hWindow = 0 ; HHOOK SHARED hhkHook =0 ; HINSTANCE SHARED hDllInstance =0; ; // Weise den Compilern, den Abschnitt Shared als lesbar, // beschreibbar und zur gemeinsamen Verwendung zu deklarieren - "RSW". LRESULT CALLBACK KeyboardHookProc (int, WPARAM, LPARAM) ; // Der Prototyp der Funktion KeyboardHookProc // 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 */ /************************************************************************/ BOOL WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved){ MessageBox(HWND_DESKTOP,"blub\n","",IDOK); 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 ; }der entry point DllMain wird anscheinend immer noch nicht aufgerufen,...
hmmm solangsam weiß ich nicht mehr weiter...
gruß
-
Die keyboard hooking FAQ hier ist halt veraltet. Heutzutage (Win2000 und neuer) funktioniert es ganz einfach (ohne DLL, ohne Injection, ohne Exports):
#include <Windows.h> #include <tchar.h> // Forward declarations of functions included in this code module: LRESULT CALLBACK WindowProcedure(HWND window, UINT messageId, WPARAM wordParameter, LPARAM longParameter); LRESULT CALLBACK LowLevelKeyboardHookProcedure(int code, WPARAM wordParameter, LPARAM longParameter); // required for the hook procedure as the message recipient window HWND g_mainWindow = NULL; int APIENTRY _tWinMain ( HINSTANCE instance, HINSTANCE previousInstance, LPTSTR commandLine, int showWindowCommand ) { UNREFERENCED_PARAMETER(previousInstance); UNREFERENCED_PARAMETER(commandLine); // low level hooking requires us to have a window message processing loop { const TCHAR* const windowClassName = TEXT("LLHook"); { WNDCLASSEX windowClass = {0}; windowClass.cbSize = sizeof(windowClass); windowClass.style = 0; windowClass.lpfnWndProc = WindowProcedure; windowClass.cbClsExtra = 0; windowClass.cbWndExtra = 0; windowClass.hInstance = instance; windowClass.hIcon = NULL; windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); windowClass.hbrBackground = (HBRUSH)(INT_PTR)(COLOR_WINDOW + 1); windowClass.lpszMenuName = NULL; windowClass.lpszClassName = windowClassName; windowClass.hIconSm = NULL; { const ATOM registerClassResult = RegisterClassEx(&windowClass); if (registerClassResult == 0) // If the function terminates before entering the message loop, it should return zero. return 0; } } { const HWND mainWindow = CreateWindow ( windowClassName, NULL, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, instance, NULL ); if (mainWindow == NULL) return 0; g_mainWindow = mainWindow; ShowWindow(mainWindow, showWindowCommand); UpdateWindow(mainWindow); } } { MSG message; // Main message loop while (GetMessage(&message, NULL, 0, 0)) DispatchMessage(&message); return (int) message.wParam; } } LRESULT CALLBACK WindowProcedure (HWND window, UINT messageId, WPARAM wordParameter, LPARAM longParameter) { switch (messageId) { case WM_CREATE: { const HHOOK hook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardHookProcedure, NULL, 0); if (hook == NULL) return -1; SetLastError(0); SetWindowLongPtr(window, GWLP_USERDATA, (LONG_PTR)hook); { const DWORD setWindowLongPointerError = GetLastError(); if (setWindowLongPointerError != 0) return -1; } } break; case WM_USER: { MessageBeep(0); } break; case WM_PAINT: { PAINTSTRUCT paintStructure = {0}; BeginPaint(window, &paintStructure); EndPaint(window, &paintStructure); } break; case WM_DESTROY: { const HHOOK hook = (HHOOK)SetWindowLongPtr(window, GWLP_USERDATA, 0); if (hook != NULL) UnhookWindowsHookEx(hook); PostQuitMessage(0); } break; default: return DefWindowProc(window, messageId, wordParameter, longParameter); } return 0; } LRESULT CALLBACK LowLevelKeyboardHookProcedure (int code, WPARAM wordParameter, LPARAM longParameter) { if (code == HC_ACTION) SendMessage(g_mainWindow, WM_USER, 0, 0); return CallNextHookEx(NULL, code, wordParameter, longParameter); }
-
ok, thx erstmal. Da taucht beim call der SetWindowHookEx ein error auf,
und zwarERROR_HOOK_NEEDS_HMOD
1428 (0x594)Cannot set nonlocal hook without a module handle.
Ich habe überlegt wie ich das problem lösen kann, dabei habe ich aus msdn
msdn schrieb:
hMod
[in] Handle to the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.mir überlegt einfache die instance des Progs zu nehmen, leider kommt dann die gleiche fehlermeldung,..
jemand eine idee?
gruß
-
*push*
-
hMod ist das Handle der DLL!
-
Jo Martin,
Wie du oben gelesen hast, habe ich schwierigkeiten mit der DLL, da der entrypoint nicht angesprochen wird.
(sonst würde ja die msg Box erscheinen).Deswegen habe ich aufgrund des vorletzten Post versucht inerhalb der eigenen instance den hook zu erzeugen...
dit will allet net so wie icke wil

gruß
-
Ok, ich habe mir jetzt VC++2008 Express runtergeladen um die dll zu erzeugen, diesmal bekomme ich eine meldung des entrypoints DllMain ich werde mal in einem seperaten thread nachfragen wo das problem mit dem MinGW , bzw bei mir, liegt.
Ich werde mich jetzt nochmal am hooking probieren,..
grüüße
-
Sooo ich nochmal:
Wenn ich nur WH_KEYBOARD benutzte, funktioniert lokal alles einwandfrei, ich will mich aber in ein anderes programm hooken, das heisst WH_KEYBOARD_LL, das funktioniert nicht nur seeehhhr träge, sondern schmeisst mir immer egal welche taste die werte 256 und 257 raus, ich nehme mal an das das sooo nicht gedacht war,...
daher habe ich zwei fragen:
a) woran kann das liegen und wie kann ich das problem beheben
b) wie kann ich die dll nur auf spezielles programm anwenden und in meinen anderen programm die messages abfangen.Freue mich auf eure antworten, werde mich in der zwischenzeit belesen,.. gruuuß
-------------------------------------------------------------------------------
Edit:
Ok das Problem habe ich nun gelöst.
Nun habe ich mit WH_CALLWNDPROC versucht die Messages für einen bestimmten Thread zu bekommen.Ich bekomme die Message das der Hook instaliert wurde, und ich bekomme ein bzw. zweimal eine nachricht das MsgProc aufgerufen wurde. Wenn ich das Window des Thread aber mit dem Mauszeiger berühre (eine andere Application ist vorher als actives fenster gekennzeichnet), was ja eine Message auslöst, bekomme ich eine Exception,
Funktion der Adresse 0x7a4...... verweist auf den Speicher 0xffffffff (oder auch 0x000000..). "read" konnte nicht durchgeführt werden.
Leider will mein debugger nicht, daher weiß ich nicht ganz wie ich herausbekomme ob das ein verweis aus der dll oder aus meinen hauptprogramm ist das diesen Fehler verursacht.
Prinzipiell müsste ich die Adressen aller funktionen mit deren funktionszeiger auflisten, leider weiß ich net wie ich die adressen ohne einen 30zeiler als Hex im string darstellen kann. Wisst Ihr da vlt. Weiter?
( GetProcAddr(hMyDll,irgendeineFkt") gibt mir leider die vals:00 raus)
Grüüüße und *push*