Bonjour.
Je ne suis pas un pro du Hook et j’ai un peu oublié tout ca, mais vu toutes les bonnes sources et annotations qui trônent ici, je pensais pouvoir m’y remettre m’en sortir seul; et bien non !
J’essaie de faire un Hook sur une window (ou toutes…) pour récurer quelques messages.
J’ai fait un simple essai (exe console Win32 plus DLL win32). J’ai essayé avec ou sans thread, création du hook dans exe ou dll, en debug et release…
(Merci à tous les auteurs, sources des mes sources.)
C’est probablement tout con, mais j’ai besoin d’aide. Merci.
Quand j’utilise WH_KEYBOARD_LL ou WH_KEYBOARD, je rentre bien dans mon hook mais ca fini par planter dans ma fonction MsgLoop, au niveau du GetMessage :
Exception de première chance à 0x00a1febe dans TstHookExe.exe : 0xC0000005: Violation d'accès lors de la lecture de l'emplacement 0x41163000.
Je précise que 0x41163000 ne correspond pas a mes fonctions (me semble t-il !)
Quand j’utilise WH_GETMESSAGE ou WH_CBT ca ne plante pas, mais ca ne passe pas dans le hook !!
Rien ne sort du GetMessage. GRRrrrr !
Merci tout plein ! (même si je vais me prendre une gamelle de débutant…)
Voici donc les sources:
(J'aurai bien voulu mettre le zip de tout le (petit) projet, mais c'est contraire à la charte de deposé des source qui ne marche pas...)
L'EXE (projet console win32 MVS2005, C++):
#include "stdafx.h"
#define _WIN32_WINNT 0x0501
#include <windows.h>
typedef LRESULT (* typHookWnd) (int nCode, WPARAM wParam, LPARAM lParam);
typHookWnd HookWnd;
void MsgLoop()
{
MSG message;
BOOL bRet = FALSE;
int ii=0;
while(TRUE)
{
bRet = GetMessage(&message, NULL, 0, 0);
printf("runing %d\n", ii++);
if (!bRet)
{
printf ("Quit\n");
break;
}
else if (bRet == -1)
{
printf ("Erreur boucle des messages: %d\n", GetLastError());
}
else
{
TranslateMessage(&message);
DispatchMessage(&message);
}
}
}
DWORD WINAPI theThread(LPVOID lpParameter)
{
HMODULE hMod = LoadLibraryA("tstHookDll");
if (!hMod)
{
printf ("Erreur charement dll: %d\n", GetLastError());
return 0;
}
HookWnd = (typHookWnd) GetProcAddress(hMod,(LPCSTR)1); // par ordinal, c'est plus rapide et plus simple (les nons sont decorés)
if (!HookWnd)
{
printf("Fonction HookWnd non trouvée dans la Dll, Erreur: %d", GetLastError());
FreeLibrary(hMod);
return 0;
}
HHOOK hhkWnd = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)HookWnd, hMod, 0);
if (!hhkWnd) printf("erreur creation Hook windows: %d\n", GetLastError());
MsgLoop();
BOOL bb = UnhookWindowsHookEx(hhkWnd);
if(!bb) printf("erreur liberation Hook windows: %d\n", GetLastError());
FreeLibrary(hMod);
printf("fin\n");
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hThread;
DWORD dwThread;
printf("debut\n");
// on crée le thread qui va démarrer le hook
hThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE) theThread, (LPVOID)NULL, NULL, &dwThread);
if (hThread)
{
/*
Sleep(5000);
printf("test\n");
HookWnd(-1234, 0,0); //test d'appel
*/
return WaitForSingleObject(hThread,INFINITE);
}
else
{
printf("Erreur de creation du thread: %d", GetLastError());
return 0;
}
return 0;
}
LA DLL (projet DLL win32 MVS2005, C++):
#include "stdafx.h"
#include <stdio.h>
HMODULE g_hModule;
HHOOK g_hhkWnd;
__declspec(dllexport) LRESULT HookWnd(int nCode, WPARAM wParam, LPARAM lParam)
{
printf ("in HookWnd !!\n");
if (nCode==-1234) {printf("bidon\n"); return 0;}
// if (nCode <0 || nCode != HC_ACTION)
return CallNextHookEx(NULL, nCode, wParam, lParam);
printf ("todo !!\n");
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
/*
#ifdef _MANAGED
#pragma managed(push, off)
#endif
*/
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
// case DLL_THREAD_ATTACH:
g_hModule = hModule;
// g_hhkWnd = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)HookWnd, g_hModule, 0);
// if (!g_hhkWnd) printf("erreur creation Hook windows: %d\n", GetLastError());
break;
// case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
// BOOL bb = UnhookWindowsHookEx(g_hhkWnd);
// if(!bb) printf("erreur fin Hook windows: %d\n", GetLastError());
g_hhkWnd = 0;
break;
}
return TRUE;
}
/*
#ifdef _MANAGED
#pragma managed(pop)
#endif
*/