代码如下
DLL:
HHOOK g_hook=NULL;
extern "C" _declspec(dllexport)
LRESULT CALLBACK CallWndProc(
int nCode, // hook code
WPARAM wParam, // current-process flag
LPARAM lParam // address of structure with message data
)
{
if(nCode <0) return (CallNextHookEx(g_hook, nCode, wParam, lParam));
switch(nCode)
{
case HC_ACTION:
switch(wParam)
{
case WH_CALLWNDPROC:
break;
default:
break;
}
break;
default:
break;
}
return (CallNextHookEx(g_hook, nCode, wParam, lParam));
}
exe代码段:
DWORD dwThreadID = GetWindowThreadProcessId(hwnd, NULL);
HINSTANCE gDLL = ::LoadLibrary(L"../Release/Hook.dll");
//HINSTANCE gDLL = ::LoadLibrary(L"Hook.dll");
HHOOK gHook = ::SetWindowsHookEx(WH_CALLWNDPROC,(HOOKPROC)GetProcAddress(gDLL, "CallWndProc"),gDLL,dwThreadID);
代码意图:通过加载HOOK注入DLL拦截指定窗口的特定消息
查看线程,已经正常加载Hook.dll文件,可为啥gHook的值为零...
刚学钩子..很迷糊这个!!!边学边看边练边用!请教高手了!!!如果可能的话,可否给个这类相关代码段!
自己找了,看了!!汗一个!!资料是多,可多了也让人犯晕!
觉得分给的少的话,解决问题后,可以再加分,谢谢,在线等
是不是路径有问题?
在watch窗口输入@err,hr,看看错误提示。
要把sethook函数放到dll里,比如我上面发这个例子
还有一种方法就是把g_Hook放到共享数据段里才可以
全局钩子不是这么写的,给你一个全局键盘的参考吧
http://www.3800hk.com/Article/cxsj/cjiajia/xtkzcjj/2005-08-06/Article_27326.html
重新帖一下代码:
看的容易,清楚一点,本来想修改一下...不过好像自己的权限不够,不能编辑修改!
Dll代码:
-
C/C++ code
-
HHOOK g_hook = NULL; extern " C " _declspec(dllexport) LRESULT CALLBACK CallWndProc( int nCode, // hook code WPARAM wParam, // current-process flag LPARAM lParam // address of structure with message data ) { if (nCode < 0 ) return (CallNextHookEx(g_hook, nCode, wParam, lParam)); switch (nCode) { case HC_ACTION: switch (wParam) { case WH_CALLWNDPROC: // sprintf("jp"); break ; default : break ; } break ; default : break ; } return (CallNextHookEx(g_hook, nCode, wParam, lParam)); }
EXE代码:
-
C/C++ code
-
dwThreadID = GetWindowThreadProcessId(hwnd, NULL); // hmodHook = GetModuleHandle(L"../Release/Hook.dll"); gDLL = ::LoadLibrary(L " ../Release/Hook.dll " ); // gDLL = ::LoadLibrary(L"PetHook.dll"); HHOOK gHook = ::SetWindowsHookEx(WH_CALLWNDPROC,(HOOKPROC)GetProcAddress(gDLL, " CallWndProc " ),gDLL,dwThreadID); CPoint mouse; GetCursorPos( & mouse); ::SetWindowLong(hwnd,GWL_WNDPROC,(LONG)MyWndProc);(本来想直接用这个的,不过跨进程了,返回值为NU )
用dumpbin查看了一下dll发现函数名变了....
_CallWndProc@12
修改成这个,HOOK值也还是O
钩子是钩进别的进程里,但本身也和自己的进程也可以共享数据的!不然钩子就没啥作用了!!
全局钩子换0,我知道,但那样收到的消息就太多了,不方便处理,我要的是指定窗口的线程窗口消息!!!
就像SPY++那样,可以拦截特定窗口的特定消息...
extern "C" _declspec(dllexport)
定义输出会改变函数名....
改成相应的函数名也没办法认到!
所以后来我换成了
-
C/C++ code
-
#include " stdafx.h " #pragma data_seg("Shared") HHOOK g_Hook = NULL; #pragma data_seg() // extern "C" _declspec(dllexport) LRESULT [color = # 993300 ]WINAPI[ / color] CALLBACK CallWndProc( int nCode, // hook code WPARAM wParam, // current-process flag LPARAM lParam // address of structure with message data ) { if (nCode < 0 ) return CallNextHookEx(g_Hook, nCode, wParam, lParam); switch (nCode) { case HC_ACTION: switch (wParam) { case WH_CALLWNDPROC: break ; default : break ; } break ; default : break ; } return CallNextHookEx(g_Hook, nCode, wParam, lParam); }
得出来的值也还是NULL
效果是点按扭后,会加载DLL,然后拦截指定窗口特定的消息.
再有一个问题,我用其它查看线程工具,看加载的DLL是否有定义加载进去的DLL和hook文件...好像也没有查找到
汗一个,自己搞定了
原来是因为DLL输出函数名变化的原因..
修正一下函数名就可以了!
-
C/C++ code
-
HHOOK gHook = ::SetWindowsHookEx(WH_CALLWNDPROC,(HOOKPROC)GetProcAddress(hModule, " _CallWndProc@12 " ),hModule,dwThreadID);
结帖了
弱弱的说下:
嘿,嘿,改成extern "C" 又出现NULL错误了
又找不着了那个生成的函数名了....
改成__declspec(dllimport)
提示说,不能使用!!
我也犯晕中
dll 里
导出用 __declspec(dllexport)
导入用 __declspec(dllimport)
exe里
我直接生成一个.def 在里头直接导出...
现在可以了认到DLL函数符号了!
再弱弱的问一下:
-
C/C++ code
-
#include " stdafx.h " #include " PetHook.h " #pragma data_seg("sharedata") // 共享数据段 HHOOK glhHook = NULL; // 钩子句柄。 // HINSTANCE glhInstance=NULL; // DLL实例句柄 #pragma data_seg() static HMODULE ModuleFromAddress(PVOID pv) { MEMORY_BASIC_INFORMATION mbi; if (::VirtualQuery(pv, & mbi, sizeof (mbi)) != 0 ) { return (HMODULE)mbi.AllocationBase; } else { return NULL; } } static LRESULT WINAPI GetMsgProc( int nCode , WPARAM wParam, LPARAM lParam ) { if (nCode < 0 ) return CallNextHookEx(glhHook, nCode, wParam, lParam); switch (nCode) { case HC_ACTION: switch (wParam) { case WH_CALLWNDPROC: break ; default : break ; } break ; default : break ; } return CallNextHookEx(glhHook, nCode, wParam, lParam); } BOOL WINAPI SetHook(BOOL bInstall , HWND hWnd) // 安装钩子。 { BOOL bOk; if (bInstall) { DWORD dwThreadID = GetWindowThreadProcessId( hWnd, NULL); glhHook = SetWindowsHookEx(WH_CALLWNDPROC,GetMsgProc,ModuleFromAddress(GetMsgProc),dwThreadID); bOk = (glhHook != NULL); } else { bOk = ::UnhookWindowsHookEx(glhHook); glhHook = NULL; } return bOk; }
为什么我在DLL文件里下断点,然后附加到进程中,只提示说找到断点,却不会在指定的位置停下来
再有拦截指定的WM_ACTIVATE
GetMsgProc函数里??能直接swicth ->nCode吗???主要是我下断,没办法停在我指定的位置.没办法判断值!!
高人指导一下下!!这样写回调GetMsgProc,应该可以吧!!
WINAPI == CALLBACK 是成立的吧!!!查了资料是这样说的,不过这边确认一下!