TA的每日心情 | 擦汗 2019-10-17 06:41 |
---|
签到天数: 182 天 [LV.7]常住居民III
|
本帖最后由 小圈圈 于 2016-6-21 15:38 编辑
1.Hook简介:作用是拦截某些消息,关键函数是SetWindowsHookEX()
2实例:编写一个屏蔽所有进程和所有线程的钩子程序。钩子函数在DLL中,要被某个程序调用才行。
1.新建一个DLL工程名为0616Hook
2.增加0616Hook.cpp
3.代码如下:
#include <windows.h>包含头文件
HHOOK g_hMouse=NULL;
HHOOK g_hKeyboard=NULL;
#pragma data_seg("MySec")新建了一个节,用于将下 面的这个变量设为全局共享。
HWND g_hWnd=NULL;这个变量是全局共享的。
#pragma data_seg()
//#pragma comment(linker,"/section:MySec,RWS")
/*HINSTANCE g_hInst;
BOOL WINAPI DllMain(
HINSTANCE hinstDLL, // handle to the DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpvReserved // reserved
)
{
g_hInst=hinstDLL;
}*/
LRESULT CALLBACK MouseProc(
int nCode, // hook code
WPARAM wParam, // message identifier
LPARAM lParam // mouse coordinates
)
{
return 1;拦截了鼠标消息。
}
LRESULT CALLBACK KeyboardProc(
int code, // hook code
WPARAM wParam, // virtual-key code
LPARAM lParam // keystroke-message information
)
{
if(VK_F2==wParam)如果是F2键,则退出。
{
SendMessage(g_hWnd,WM_CLOSE,0,0);
UnhookWindowsHookEx(g_hMouse);当退出时将钩子卸掉。
UnhookWindowsHookEx(g_hKeyboard);
}
return 1;
}
void SetHook(HWND hwnd)此函数设置了钩子。
{
g_hWnd=hwnd;注意这种传递调用它的进程的句柄的方法,比较巧妙!
g_hMouse=SetWindowsHookEx(WH_MOUSE,MouseProc,GetModuleHandle("Hook"),0);
g_hKeyboard=SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,GetModuleHandle("Hook"),0);
}
0616Hook.DEF的代码如下:
LIBRARY Hook
EXPORTS
SetHook @2
SEGMENTS
MySec READ WRITE SHARED 也可以设置节的属性。
4.新建一个工程调用此钩子函数。工程名为0619HookTest,基于对话框的。在OnInitDialog()中调用SetHook(),要事先声明_declspec(dllimport) void SetHook(HWND hwnd);
然后在右键工程->属性->链接器->输入 加入0616Hook.lib,并将0616Hook.dll和0616Hook.lib拷贝到当前目录。
int cxScreen,cyScreen;
cxScreen=GetSystemMetrics(SM_CXSCREEN);
cyScreen=GetSystemMetrics(SM_CYSCREEN);
SetWindowPos(&wndTopMost,0,0,cxScreen,cyScreen,SWP_SHOWWINDOW);将窗口保持在最前面。
SetHook(m_hWnd);
但是最终运行的时候出现一个问题:窗口能正常打开关闭,但是写入的钩子函数没起作用,想要调试定位,但是……
由于dll是自己写的,调试的时候要加载编译dll生成的pdb文件,但问题是不知道怎么把这个pdb加载进来(下面的浏览并查找0616Hook.pdb试过了,没用的)
这时改造函数,让SetHook函数有返回值,根据返回值MessageBox弹出不同窗口。
bool SetHook(HWND hwnd)
{
g_hwnd = hwnd;
g_hMouse = ::SetWindowsHookEx(WH_MOUSE, MouseProc, GetModuleHandle("0616Hook.dll"), 0);
g_hKeyboard = ::SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, GetModuleHandle("0616Hook.dll"), 0);
if (g_hMouse)
return true;
else
return false;
}
窗口测试程序修改为
if (!SetHook(m_hWnd))
{
MessageBox("创建钩子失败!");
}
最终定位到
::SetWindowsHookEx(WH_MOUSE, MouseProc, GetModuleHandle("0616Hook.dll"), 0);
::SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, GetModuleHandle("0616Hook.dll"), 0);
这两个函数返回的是空指针
那么问题来了,0616Hook.dll和0616Hook.lib已经放在测试程序的根目录下了,.lib文件也链接了,但SetWindowsHookEx函数就是不生效。问了一下冰琥珀,说把GetModuleHandle("0616Hook.dll")单拎出来看返回值,没想到奇迹出现了
全局钩子竟然生效了,虽然还有些许问题,想必这是第一次看到360报警还这么激动吧!
这次学会了两个东西:1、debug的时候思路要灵活,没有de不掉的bug 2、有些bug就是这么稀里糊涂的被de掉的,谁也说不清楚为什么。。
|
-
|