折腾一天半,终于写出来了一个Hook实例,代码如下:
Hook.cpp
1
#include <TChar.h>
2
3
#include "Hook.h"
4
5
#pragma data_seg(".JIE")
6
HINSTANCE _hinst = NULL;
7
HWND _hwnd = NULL;
8
HHOOK _hhook = NULL;
9
UINT _nMsg = 0;
10
#pragma data_seg()
11
#pragma comment(linker, "/section:.JIE,rws")
12
13
LPCTSTR HOOK_NOTIFY_MSG_DEF = _T("MY_HOOK_NOTIFY_MSG_DEF");
14
15
BOOL 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
30
LRESULT 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
37
BOOL 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
65
BOOL 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
1
LIBRARY HookDll
2
EXPORTS
3
SetHook = SetHook
4
ClearHook = ClearHook 这部分代码是折腾最久,从我的理解看,应该使范围内定义的变量实现进程间共享,这样Hoook和调用Hook的进程才能使用相同的变量值进行通信。用Dumpbin查看,这部分果然是独立的一个段了。
1
#pragma data_seg(".JIE")
2
HINSTANCE _hinst = NULL;
3
HWND _hwnd = NULL;
4
HHOOK _hhook = NULL;
5
UINT _nMsg = 0;
6
#pragma data_seg()
7
#pragma comment(linker, "/section:.JIE,rws") 这里部分测试代码:
1
void 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
11
void 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
22
WXLRESULT 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
} 写代码和打拳类似,要做到拳不离手,不然真是--三天不打,手生啊。。。