折腾一天半,终于写出来了一个Hook实例,代码如下:
Hook.cpp
1#include <TChar.h>
2
3#include "Hook.h"
4
5#pragma data_seg(".JIE")
6HINSTANCE _hinst = NULL;
7HWND _hwnd = NULL;
8HHOOK _hhook = NULL;
9UINT _nMsg = 0;
10#pragma data_seg()
11#pragma comment(linker, "/section:.JIE,rws")
12
13LPCTSTR HOOK_NOTIFY_MSG_DEF = _T("MY_HOOK_NOTIFY_MSG_DEF");
14
15BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
16{
17 switch(reason)
18 {
19 case DLL_PROCESS_ATTACH:
20 _hinst = hinst;
21 break;
22 case DLL_PROCESS_DETACH:
23 ClearHook();
24 break;
25 default:;
26 }
27 return TRUE;
28}
29
30LRESULT CALLBACK HookProc(UINT code, WPARAM wparam, LPARAM lparam)
31{
32 if(code >= 0)
33 SendMessage(_hwnd, _nMsg, wparam, lparam);
34 return CallNextHookEx(_hhook, code, wparam, lparam);
35}
36
37BOOL SetHook(HWND hwnd, LPCTSTR classname, LPCTSTR wintitle, UINT* msgid)
38{
39 if(_hwnd != NULL)
40 return FALSE;
41
42 _nMsg = RegisterWindowMessage(HOOK_NOTIFY_MSG_DEF);
43 if(_nMsg == 0)
44 return FALSE;
45 *msgid = _nMsg;
46
47 HWND h = FindWindow(classname, wintitle);
48 if(h == NULL)
49 return FALSE;
50
51 DWORD tid = 0;
52 tid = GetWindowThreadProcessId(h, &tid);
53 if(tid == 0)
54 return FALSE;
55
56 _hhook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)HookProc, _hinst, tid);
57 if(_hhook == NULL)
58 return FALSE;
59
60 _hwnd = hwnd;
61
62 return TRUE;
63}
64
65BOOL ClearHook()
66{
67 if(_hwnd == NULL)
68 return FALSE;
69
70 BOOL uh = UnhookWindowsHookEx(_hhook);
71 if(uh == FALSE)
72 return FALSE;
73
74 _hwnd = NULL;
75
76 return TRUE;
77} Hook.def
1LIBRARY HookDll
2EXPORTS
3 SetHook = SetHook
4 ClearHook = ClearHook 这部分代码是折腾最久,从我的理解看,应该使范围内定义的变量实现进程间共享,这样Hoook和调用Hook的进程才能使用相同的变量值进行通信。用Dumpbin查看,这部分果然是独立的一个段了。
1#pragma data_seg(".JIE")
2HINSTANCE _hinst = NULL;
3HWND _hwnd = NULL;
4HHOOK _hhook = NULL;
5UINT _nMsg = 0;
6#pragma data_seg()
7#pragma comment(linker, "/section:.JIE,rws") 这里部分测试代码:
1void MyFrame::OnButton1(wxCommandEvent &event)
2{
3 hdll = LoadLibrary(_T("../HookDll/Debug/HookDll.dll"));
4 SetHookPtr sh = (SetHookPtr)GetProcAddress(hdll, "SetHook");
5 if(sh((HWND)this->GetHandle(), _T("Notepad"), NULL, &HOOK_NOTIFY_MSG) != TRUE)
6 {
7 wxMessageBox(_("SetHook Error"));
8 }
9}
10
11void MyFrame::OnButton2(wxCommandEvent &event)
12{
13 ClearHookPtr ch = (ClearHookPtr)GetProcAddress(hdll, "ClearHook");
14 if(ch() != TRUE)
15 {
16 wxMessageBox(_("UnHook Error"));
17 }
18
19 FreeLibrary(hdll);
20}
21
22WXLRESULT MyFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
23{
24 if(message == HOOK_NOTIFY_MSG)
25 wxLogDebug(_("msg:%d, wparam:%d, lparam:%d"), message, wParam, lParam);
26 return wxFrame::MSWWindowProc(message, wParam, lParam);
27} 写代码和打拳类似,要做到拳不离手,不然真是--三天不打,手生啊。。。