失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 消息钩子学习工程

消息钩子学习工程

时间:2021-02-24 17:41:42

相关推荐

消息钩子学习工程

前奏

近来一直在自学Windows Hook相关的知识,已经尝试多种注入方式。尤其对消息钩子方式很感兴趣,因为看到Spy++能够截获系统中绝大多数应用的消息流,就很想知道它的工作原理,打算制作属于自己的Spy++。消息钩子简介:消息钩子简言之就是Windows处理消息的一个平台,用户可以在此平台获取或过滤所需应用的消息(例如某鼠标位置,键盘击下等),这些被监控的消息都会在目标窗口处理函数之前被截获。系统在拿到消息后会问你:这是不是你想要的消息?如果是,则恭喜你,你可以在回调函数里做相应操作了。消息钩子函数背景消息钩子主要由三部分组成:钩子安装函数钩子回调函数钩子卸载函数钩子安装函数原型:

HHOOK WINAPI SetWindowsHookEx(_In_ int idHook,_In_ HOOKPROC lpfn,_In_ HINSTANCE hMod,_In_ DWORD dwThreadId);

SetWindowsHookEx

x

1

HHOOK WINAPI SetWindowsHookEx(

2

_In_ int idHook,

3

_In_ HOOKPROC lpfn,

4

_In_ HINSTANCE hMod,

5

_In_ DWORD dwThreadId

6

);

参数1-idHook:这个函数代表了你要安装钩子的种类,比如键盘钩子,鼠标钩子,窗体钩子等等。以下我列了一张表,结合MSDN供大家参考。参数2-HOOKPROC lpfn:此参数是钩子回调函数的地址,对应上述不同种类的钩子类型,其钩子回调函数原型基本是一致的。请见下(需要注意的是,wParam和lParam针对不同类型的钩子,传递参数所代表意义不同,因种类繁多,请各位查阅MSDN):

LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam){// process event...return CallNextHookEx(NULL, nCode, wParam, lParam);}

121

LRESULT CALLBACK HookProc(

2

int nCode,

3

WPARAM wParam,

4

LPARAM lParam

5

)

6

{

7

// process event

8

...

9

10

return CallNextHookEx(NULL, nCode, wParam, lParam);

11

}

nCode:int,此参数指示Hook例程是否需要处理消息,如果nCode为HC_ACTION,则需要处理;如果小于0,不予处理,须调用CallNextHookEx函数返回。wParam与lParam:针对不同类型的钩子,代表的意义不同,但总体是针对当前类型钩子的消息。后面以例子做出验证。参数3-HINSTANCE hMod:包含Hook例程的Dll所在模块基址。参数4-DWORD dwThreadId:所要注入程序的主线程ID。如果此项填0,则代表钩子为系统钩子,基本所有在运行的进程都会被注入。如果此项指定线程ID,则是有针对性的线程钩子。返回值:HHOOK类型的句柄。钩子回调函数请见上。钩子卸载函数

BOOL WINAPI UnhookWindowsHookEx(_In_ HHOOK hhk);

1

BOOL WINAPI UnhookWindowsHookEx(

2

_In_ HHOOK hhk

3

);

参数:SetWindowsHookEx的返回值。键盘消息钩子及CBT钩子程序代码

首先我们要明确下,钩子从安装到回显的流程编写Dll,在Dll中实现我们所需要的钩子回调函数及安装函数。Dll中除了要编写与钩子相关的处理函数,也要编写与显示程序通信的模块,以便验证钩子消息的正确性。Dll需要导出钩子启动函数与卸载函数。回显程序处理已安装钩子发送的信息。至此,框架已经明了,我们分步拆解完成这个小项目。(整体代码请见附件,VS编译)结构体及枚举的定义

typedef struct COMMPACK{int nType;//Hook类型WPARAM wParam;//参数1LPARAM lParam;//参数2TCHAR szMsg[16];//额外的字符串信息,取决于具体钩子} COMMPACK, *PCOMMPACK;//与回显程序通讯的包结构typedef struct HOOKSTC{int nType;//Hook类型HOOKPROC hkproc;//Hook回调HHOOK hhook;//Hook句柄} HOOKSTC, *PHOOKSTC;HOOKSTC m_Array4Hooks[NHOOKNUMS] = { 0 };//创建多钩子类型的结构体数组enum { M_CALLWNDPROC, M_CBT, M_DEBUG, M_GETMESSAGE, M_KEYBOARD, M_MOUSE, M_MSGFILTER };//钩子类型枚举enum { IDHCBT_ACTIVATE, IDHCBT_CLICKSKIPPED, IDHCBT_CREATEWND, IDHCBT_DESTROYWND, IDHCBT_KEYSKIPPED,IDHCBT_MINMAX, IDHCBT_MOVESIZE, IDHCBT_QS, IDHCBT_SETFOCUS, IDHCBT_SYSCOMMAND, IDUnknown};//CBT钩子的消息群

221

typedef struct COMMPACK

2

{

3

int nType;//Hook类型

4

WPARAM wParam;//参数1

5

LPARAM lParam;//参数2

6

TCHAR szMsg[16];//额外的字符串信息,取决于具体钩子

7

} COMMPACK, *PCOMMPACK;//与回显程序通讯的包结构

8

9

typedef struct HOOKSTC

10

{

11

int nType;//Hook类型

12

HOOKPROC hkproc;//Hook回调

13

HHOOK hhook;//Hook句柄

14

} HOOKSTC, *PHOOKSTC;

15

16

HOOKSTC m_Array4Hooks[NHOOKNUMS] = { 0 };//创建多钩子类型的结构体数组

17

18

enum { M_CALLWNDPROC, M_CBT, M_DEBUG, M_GETMESSAGE, M_KEYBOARD, M_MOUSE, M_MSGFILTER };//钩子类型枚举

19

20

enum { IDHCBT_ACTIVATE, IDHCBT_CLICKSKIPPED, IDHCBT_CREATEWND, IDHCBT_DESTROYWND, IDHCBT_KEYSKIPPED,

21

IDHCBT_MINMAX, IDHCBT_MOVESIZE, IDHCBT_QS, IDHCBT_SETFOCUS, IDHCBT_SYSCOMMAND, IDUnknown

22

};//CBT钩子的消息群

CBT钩子的回调函数

LRESULT WINAPI m_CBTProc(int nCode, WPARAM wParam, LPARAM lParam){if (nCode < 0)return CallNextHookEx(m_Array4Hooks[M_CBT].hhook, nCode, wParam, lParam);CHAR szCode[16] = { 0 };PCOMMPACK pCP = new COMMPACK;pCP->nType = M_CBT;switch (nCode){case HCBT_ACTIVATE://系统要激活一个窗口pCP->lParam = (LPARAM)IDHCBT_ACTIVATE;pCP->wParam = IDHCBT_ACTIVATE;break;case HCBT_CLICKSKIPPED://系统已经从系统消息队列中删除了一个鼠标消息pCP->lParam = (LPARAM)IDHCBT_CLICKSKIPPED;pCP->wParam = IDHCBT_CLICKSKIPPED;break;case HCBT_CREATEWND://一个窗口将要被创建pCP->lParam = (LPARAM)IDHCBT_CREATEWND;pCP->wParam = IDHCBT_CREATEWND;break;case HCBT_DESTROYWND://一个窗口将要被销毁pCP->lParam = (LPARAM)IDHCBT_DESTROYWND;pCP->wParam = IDHCBT_DESTROYWND;break;case HCBT_KEYSKIPPED://系统已从系统消息队列中删除了一个键盘消息pCP->lParam = (LPARAM)IDHCBT_KEYSKIPPED;pCP->wParam = IDHCBT_KEYSKIPPED;break;case HCBT_MINMAX://一个窗口将被最小化或最大化pCP->lParam = (LPARAM)IDHCBT_MINMAX;pCP->wParam = IDHCBT_MINMAX;break;case HCBT_MOVESIZE://一个窗口将被移动或改变尺寸pCP->lParam = (LPARAM)IDHCBT_MOVESIZE;pCP->wParam = IDHCBT_MOVESIZE;break;case HCBT_QS://系统已从系统消息队列中取到一个WM_QUEUESYNC 消息pCP->lParam = (LPARAM)IDHCBT_QS;pCP->wParam = IDHCBT_QS;break;case HCBT_SETFOCUS://一个窗口将要获得键盘焦点pCP->lParam = (LPARAM)IDHCBT_SETFOCUS;pCP->wParam = IDHCBT_SETFOCUS;break;case HCBT_SYSCOMMAND://一个系统命令将被执行pCP->lParam = (LPARAM)IDHCBT_SYSCOMMAND;pCP->wParam = IDHCBT_SYSCOMMAND;break;default://其他pCP->lParam = (LPARAM)IDUnknown;pCP->wParam = IDUnknown;break;}m_Com(pCP);//与回显程序通信delete pCP;return CallNextHookEx(m_Array4Hooks[M_CBT].hhook, nCode, wParam, lParam);}

561571

LRESULT WINAPI m_CBTProc(int nCode, WPARAM wParam, LPARAM lParam)

2

{

3

if (nCode < 0)return CallNextHookEx(m_Array4Hooks[M_CBT].hhook, nCode, wParam, lParam);

4

CHAR szCode[16] = { 0 };

5

PCOMMPACK pCP = new COMMPACK;

6

pCP->nType = M_CBT;

7

switch (nCode)

8

{

9

case HCBT_ACTIVATE://系统要激活一个窗口

10

pCP->lParam = (LPARAM)IDHCBT_ACTIVATE;

11

pCP->wParam = IDHCBT_ACTIVATE;

12

break;

13

case HCBT_CLICKSKIPPED://系统已经从系统消息队列中删除了一个鼠标消息

14

pCP->lParam = (LPARAM)IDHCBT_CLICKSKIPPED;

15

pCP->wParam = IDHCBT_CLICKSKIPPED;

16

break;

17

case HCBT_CREATEWND://一个窗口将要被创建

18

pCP->lParam = (LPARAM)IDHCBT_CREATEWND;

19

pCP->wParam = IDHCBT_CREATEWND;

20

break;

21

case HCBT_DESTROYWND://一个窗口将要被销毁

22

pCP->lParam = (LPARAM)IDHCBT_DESTROYWND;

23

pCP->wParam = IDHCBT_DESTROYWND;

24

break;

25

case HCBT_KEYSKIPPED://系统已从系统消息队列中删除了一个键盘消息

26

pCP->lParam = (LPARAM)IDHCBT_KEYSKIPPED;

27

pCP->wParam = IDHCBT_KEYSKIPPED;

28

break;

29

case HCBT_MINMAX://一个窗口将被最小化或最大化

30

pCP->lParam = (LPARAM)IDHCBT_MINMAX;

31

pCP->wParam = IDHCBT_MINMAX;

32

break;

33

case HCBT_MOVESIZE://一个窗口将被移动或改变尺寸

34

pCP->lParam = (LPARAM)IDHCBT_MOVESIZE;

35

pCP->wParam = IDHCBT_MOVESIZE;

36

break;

37

case HCBT_QS://系统已从系统消息队列中取到一个WM_QUEUESYNC 消息

38

pCP->lParam = (LPARAM)IDHCBT_QS;

39

pCP->wParam = IDHCBT_QS;

40

break;

41

case HCBT_SETFOCUS://一个窗口将要获得键盘焦点

42

pCP->lParam = (LPARAM)IDHCBT_SETFOCUS;

43

pCP->wParam = IDHCBT_SETFOCUS;

44

break;

45

case HCBT_SYSCOMMAND://一个系统命令将被执行

46

pCP->lParam = (LPARAM)IDHCBT_SYSCOMMAND;

47

pCP->wParam = IDHCBT_SYSCOMMAND;

48

break;

49

default://其他

50

pCP->lParam = (LPARAM)IDUnknown;

51

pCP->wParam = IDUnknown;

52

break;

53

}

54

m_Com(pCP);//与回显程序通信

55

delete pCP;

56

return CallNextHookEx(m_Array4Hooks[M_CBT].hhook, nCode, wParam, lParam);

57

}

键盘钩子的回调函数

LRESULT WINAPI m_KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam){if ((nCode < 0 || !((DWORD)lParam & 0x40000000)))return CallNextHookEx(m_Array4Hooks[M_KEYBOARD].hhook, nCode, wParam, lParam);PCOMMPACK pCP = new COMMPACK;pCP->lParam = lParam;pCP->wParam = wParam;//这个值就是按键的VirtualKeypCP->nType = M_KEYBOARD;m_Com(pCP);//与回显程序通讯delete pCP;return CallNextHookEx(m_Array4Hooks[M_KEYBOARD].hhook, nCode, wParam, lParam);}

111

LRESULT WINAPI m_KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)

2

{

3

if ((nCode < 0 || !((DWORD)lParam & 0x40000000)))return CallNextHookEx(m_Array4Hooks[M_KEYBOARD].hhook, nCode, wParam, lParam);

4

PCOMMPACK pCP = new COMMPACK;

5

pCP->lParam = lParam;

6

pCP->wParam = wParam;//这个值就是按键的VirtualKey

7

pCP->nType = M_KEYBOARD;

8

m_Com(pCP);//与回显程序通讯

9

delete pCP;

10

return CallNextHookEx(m_Array4Hooks[M_KEYBOARD].hhook, nCode, wParam, lParam);

11

}

与回显程序通讯的函数

void m_Com(PCOMMPACK& pCP, int addi){hTarget = ::FindWindow(NULL, L"HookApp");//寻找回显程序窗口标题COPYDATASTRUCT stcCDS;//采用WM_COPYDATA消息方式进程间通讯stcCDS.cbData = sizeof(COMMPACK);stcCDS.dwData = addi;stcCDS.lpData = pCP;//打包消息结构体::SendMessage(hTarget, WM_COPYDATA, 0, (LPARAM)&stcCDS);}

1

void m_Com(PCOMMPACK& pCP, int addi)

2

{

3

hTarget = ::FindWindow(NULL, L"HookApp");//寻找回显程序窗口标题

4

COPYDATASTRUCT stcCDS;//采用WM_COPYDATA消息方式进程间通讯

5

stcCDS.cbData = sizeof(COMMPACK);

6

stcCDS.dwData = addi;

7

stcCDS.lpData = pCP;//打包消息结构体

8

::SendMessage(hTarget, WM_COPYDATA, 0, (LPARAM)&stcCDS);

9

}

钩子初始化函数

void InitHooks(){hTarget = ::FindWindow(NULL, L"HookApp");m_Array4Hooks[M_CALLWNDPROC].hkproc = m_CallWndProc;m_Array4Hooks[M_CALLWNDPROC].nType = WH_CALLWNDPROC;m_Array4Hooks[M_CBT].hkproc = m_CBTProc;m_Array4Hooks[M_CBT].nType = WH_CBT;//m_Array4Hooks[M_DEBUG]->hkproc = m_DebugProc;//m_Array4Hooks[M_DEBUG]->nType = WH_DEBUG;//m_Array4Hooks[M_GETMESSAGE]->hkproc = m_GetMsgProc;//m_Array4Hooks[M_GETMESSAGE]->nType = WH_GETMESSAGE;m_Array4Hooks[M_KEYBOARD].hkproc = m_KeyboardProc;m_Array4Hooks[M_KEYBOARD].nType = WH_KEYBOARD;m_Array4Hooks[M_MOUSE].hkproc = m_MouseProc;m_Array4Hooks[M_MOUSE].nType = WH_MOUSE;//m_Array4Hooks[M_MSGFILTER]->hkproc = m_MessageFilterProc;//m_Array4Hooks[M_MSGFILTER]->nType = WH_MSGFILTER;for (int i = 0; i < NHOOKNUMS; ++i){m_Array4Hooks[i].hhook = 0;}}

x

1

void InitHooks()

2

{

3

hTarget = ::FindWindow(NULL, L"HookApp");

4

m_Array4Hooks[M_CALLWNDPROC].hkproc = m_CallWndProc;

5

m_Array4Hooks[M_CALLWNDPROC].nType = WH_CALLWNDPROC;

6

m_Array4Hooks[M_CBT].hkproc = m_CBTProc;

7

m_Array4Hooks[M_CBT].nType = WH_CBT;

8

//m_Array4Hooks[M_DEBUG]->hkproc = m_DebugProc;

9

//m_Array4Hooks[M_DEBUG]->nType = WH_DEBUG;

10

//m_Array4Hooks[M_GETMESSAGE]->hkproc = m_GetMsgProc;

11

//m_Array4Hooks[M_GETMESSAGE]->nType = WH_GETMESSAGE;

12

m_Array4Hooks[M_KEYBOARD].hkproc = m_KeyboardProc;

13

m_Array4Hooks[M_KEYBOARD].nType = WH_KEYBOARD;

14

m_Array4Hooks[M_MOUSE].hkproc = m_MouseProc;

15

m_Array4Hooks[M_MOUSE].nType = WH_MOUSE;

16

//m_Array4Hooks[M_MSGFILTER]->hkproc = m_MessageFilterProc;

17

//m_Array4Hooks[M_MSGFILTER]->nType = WH_MSGFILTER;

18

for (int i = 0; i < NHOOKNUMS; ++i)

19

{

20

m_Array4Hooks[i].hhook = 0;

21

}

22

}

钩子安装及卸载函数

void InstallHook(DWORD dwProcessID){g_dwThreadID = GetThreadInfo(dwProcessID);//由注入器传入指定注入进程ID,遍历获得主线程IDInitHooks();//初始化钩子for (int i = 0; i < NHOOKNUMS; ++i){if (m_Array4Hooks[i].hkproc == NULL)continue;m_Array4Hooks[i].hhook = SetWindowsHookEx(m_Array4Hooks[i].nType, m_Array4Hooks[i].hkproc, g_Module, g_dwThreadID);}}void UnInstallHook(){for (int i = 0; i < NHOOKNUMS; ++i){UnhookWindowsHookEx(m_Array4Hooks[i].hhook);}}

121

void InstallHook(DWORD dwProcessID)

2

{

3

g_dwThreadID = GetThreadInfo(dwProcessID);//由注入器传入指定注入进程ID,遍历获得主线程ID

4

5

InitHooks();//初始化钩子

6

7

for (int i = 0; i < NHOOKNUMS; ++i)

8

{

9

if (m_Array4Hooks[i].hkproc == NULL)continue;

10

m_Array4Hooks[i].hhook = SetWindowsHookEx(m_Array4Hooks[i].nType, m_Array4Hooks[i].hkproc, g_Module, g_dwThreadID);

11

}

12

}

13

14

void UnInstallHook()

15

{

16

for (int i = 0; i < NHOOKNUMS; ++i)

17

{

18

UnhookWindowsHookEx(m_Array4Hooks[i].hhook);

19

}

20

}

线程遍历函数

DWORD GetThreadInfo(DWORD dwProcessID){HANDLE hSnThread = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);if (hSnThread == INVALID_HANDLE_VALUE) {return 0;}// 开始遍历线程THREADENTRY32 threadEntry = { sizeof(THREADENTRY32) };// 获取快照中的第一个线程的信息Thread32First(hSnThread, &threadEntry);DWORD dwSuspendCount = 0;do {// 判断遍历到的线程是否属于这个进程的.if (threadEntry.th32OwnerProcessID == dwProcessID) {return threadEntry.th32ThreadID;}// 获取快照中的下一个线程信息} while (Thread32Next(hSnThread, &threadEntry));return 1;}

251

DWORD GetThreadInfo(DWORD dwProcessID)

2

{

3

HANDLE hSnThread = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);

4

if (hSnThread == INVALID_HANDLE_VALUE) {

5

return 0;

6

}

7

8

// 开始遍历线程

9

THREADENTRY32 threadEntry = { sizeof(THREADENTRY32) };

10

11

// 获取快照中的第一个线程的信息

12

Thread32First(hSnThread, &threadEntry);

13

14

DWORD dwSuspendCount = 0;

15

do {

16

17

// 判断遍历到的线程是否属于这个进程的.

18

if (threadEntry.th32OwnerProcessID == dwProcessID) {

19

return threadEntry.th32ThreadID;

20

}

21

// 获取快照中的下一个线程信息

22

} while (Thread32Next(hSnThread, &threadEntry));

23

return 1;

24

}

函数导出

EXTERN_C _declspec(dllexport) void InstallHook(DWORD dwProcessID);EXTERN_C _declspec(dllexport) void UnInstallHook();

1

EXTERN_C _declspec(dllexport) void InstallHook(DWORD dwProcessID);

2

EXTERN_C _declspec(dllexport) void UnInstallHook();

至此DLL部分结束,开始回显程序的消息处理

BOOL CHookAppDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct){// TODO: 在此添加消息处理程序代码和/或调用默认值static int nIndex = 0;PCOMMPACK pCP = new COMMPACK;pCP = (PCOMMPACK)pCopyDataStruct->lpData;switch (pCP->nType)//根据消息的类型进行定义{case M_CALLWNDPROC:{}break;case M_CBT:{static int nIndex = 0;CString strCallWndProc;switch (pCP->wParam){case IDHCBT_ACTIVATE:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_ACTIVATE", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case IDHCBT_CLICKSKIPPED:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_CLICKSKIPPED", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case IDHCBT_CREATEWND:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_CLICKSKIPPED", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case IDHCBT_DESTROYWND:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_DESTROYWND", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case IDHCBT_KEYSKIPPED:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_KEYSKIPPED", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case IDHCBT_MINMAX:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_MINMAX", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case IDHCBT_MOVESIZE:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_MOVESIZE", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case IDHCBT_QS:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_QS", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case IDHCBT_SETFOCUS:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_SETFOCUS", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case IDHCBT_SYSCOMMAND:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_SYSCOMMAND", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case IDUnknown:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"Unknown", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;default:break;}}break;case M_DEBUG:{}break;case M_GETMESSAGE:{}break;case M_KEYBOARD:{static int nIndex = 0;CString strCallWndProc;strCallWndProc.Format(L"KEYBOARD [%d] - VK: %c ", nIndex, char(pCP->wParam));strCallWndProc += L"\r\n";m_StrKeyBoard += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case M_MOUSE:{}break;case M_MSGFILTER:{}break;default:break;}return CDialogEx::OnCopyData(pWnd, pCopyDataStruct);}

x

1

BOOL CHookAppDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)

2

{

3

// TODO: 在此添加消息处理程序代码和/或调用默认值

4

static int nIndex = 0;

5

PCOMMPACK pCP = new COMMPACK;

6

pCP = (PCOMMPACK)pCopyDataStruct->lpData;

7

8

switch (pCP->nType)//根据消息的类型进行定义

9

{

10

case M_CALLWNDPROC:

11

{

12

13

}break;

14

15

case M_CBT:

16

{

17

static int nIndex = 0;

18

CString strCallWndProc;

19

switch (pCP->wParam)

20

{

21

case IDHCBT_ACTIVATE:

22

{

23

strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_ACTIVATE", pCP->wParam);

24

strCallWndProc += L"\r\n";

25

m_StrCBT += strCallWndProc;

26

UpdateData(FALSE);

27

++nIndex;

28

}break;

29

case IDHCBT_CLICKSKIPPED:

30

{

31

strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_CLICKSKIPPED", pCP->wParam);

32

strCallWndProc += L"\r\n";

33

m_StrCBT += strCallWndProc;

34

UpdateData(FALSE);

35

++nIndex;

36

}break;

37

case IDHCBT_CREATEWND:

38

{

39

strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_CLICKSKIPPED", pCP->wParam);

40

strCallWndProc += L"\r\n";

41

m_StrCBT += strCallWndProc;

42

UpdateData(FALSE);

43

++nIndex;

44

}break;

45

case IDHCBT_DESTROYWND:

46

{

47

strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_DESTROYWND", pCP->wParam);

48

strCallWndProc += L"\r\n";

49

m_StrCBT += strCallWndProc;

50

UpdateData(FALSE);

51

++nIndex;

52

}break;

53

case IDHCBT_KEYSKIPPED:

54

{

55

strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_KEYSKIPPED", pCP->wParam);

56

strCallWndProc += L"\r\n";

57

m_StrCBT += strCallWndProc;

58

UpdateData(FALSE);

59

++nIndex;

60

}break;

61

case IDHCBT_MINMAX:

62

{

63

strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_MINMAX", pCP->wParam);

64

strCallWndProc += L"\r\n";

65

m_StrCBT += strCallWndProc;

66

UpdateData(FALSE);

67

++nIndex;

68

}break;

69

case IDHCBT_MOVESIZE:

70

{

71

strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_MOVESIZE", pCP->wParam);

72

strCallWndProc += L"\r\n";

73

m_StrCBT += strCallWndProc;

74

UpdateData(FALSE);

75

++nIndex;

76

}break;

77

case IDHCBT_QS:

78

{

79

strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_QS", pCP->wParam);

80

strCallWndProc += L"\r\n";

81

m_StrCBT += strCallWndProc;

82

UpdateData(FALSE);

83

++nIndex;

84

}break;

85

case IDHCBT_SETFOCUS:

86

{

87

strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_SETFOCUS", pCP->wParam);

88

strCallWndProc += L"\r\n";

89

m_StrCBT += strCallWndProc;

90

UpdateData(FALSE);

91

++nIndex;

92

}break;

93

case IDHCBT_SYSCOMMAND:

94

{

95

strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_SYSCOMMAND", pCP->wParam);

96

strCallWndProc += L"\r\n";

97

m_StrCBT += strCallWndProc;

98

UpdateData(FALSE);

99

++nIndex;

100

}break;

101

case IDUnknown:

102

{

103

strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"Unknown", pCP->wParam);

104

strCallWndProc += L"\r\n";

105

m_StrCBT += strCallWndProc;

106

UpdateData(FALSE);

107

++nIndex;

108

}break;

109

default:

110

break;

111

}

112

}break;

113

case M_DEBUG:

114

{

115

116

}break;

117

case M_GETMESSAGE:

118

{

119

120

}break;

121

case M_KEYBOARD:

122

{

123

static int nIndex = 0;

124

CString strCallWndProc;

125

strCallWndProc.Format(L"KEYBOARD [%d] - VK: %c ", nIndex, char(pCP->wParam));

126

strCallWndProc += L"\r\n";

127

m_StrKeyBoard += strCallWndProc;

128

UpdateData(FALSE);

129

++nIndex;

130

131

}break;

132

case M_MOUSE:

133

{

134

135

}break;

136

case M_MSGFILTER:

137

{

138

139

}break;

140

141

default:

142

break;

143

}

144

145

return CDialogEx::OnCopyData(pWnd, pCopyDataStruct);

146

}

147

注入器部分代码:

BOOL _Inject_::m_WindowsHook(PWCHAR pszDllName, LPCSTR pszDllProc, DWORD dwPID){typedef void* (*HookOnProto)(DWORD);//声明导出函数原型HookOnProto HookOn;hInstDll = LoadLibrary(pszDllName);if (hInstDll == NULL)return FALSE;HookOn = (HookOnProto)GetProcAddress(hInstDll, pszDllProc);//从指定Dll导出所需函数if (HookOn == NULL)return FALSE;HookOn(dwPID);//钩子安装return TRUE;}BOOL _Inject_::m_UnWinHook(PWCHAR pszDllName, LPCSTR pszDllProc){typedef void* (*HookOffProto)(void);HookOffProto HookOff;HookOff = (HookOffProto)GetProcAddress(hInstDll, pszDllProc);if (HookOff == NULL)return FALSE;HookOff();}

241

BOOL _Inject_::m_WindowsHook(PWCHAR pszDllName, LPCSTR pszDllProc, DWORD dwPID)

2

{

3

typedef void* (*HookOnProto)(DWORD);//声明导出函数原型

4

HookOnProto HookOn;

5

hInstDll = LoadLibrary(pszDllName);

6

if (hInstDll == NULL)return FALSE;

7

8

HookOn = (HookOnProto)GetProcAddress(hInstDll, pszDllProc);//从指定Dll导出所需函数

9

if (HookOn == NULL)return FALSE;

10

11

HookOn(dwPID);//钩子安装

12

13

return TRUE;

14

}

15

16

BOOL _Inject_::m_UnWinHook(PWCHAR pszDllName, LPCSTR pszDllProc)

17

{

18

typedef void* (*HookOffProto)(void);

19

HookOffProto HookOff;

20

21

HookOff = (HookOffProto)GetProcAddress(hInstDll, pszDllProc);

22

if (HookOff == NULL)return FALSE;

23

HookOff();

24

}

效果演示:(以注入notepad++为例)安装消息钩子前

安装消息钩子后

由于钩子种类繁多,我暂时没有全部实现,有兴趣的各位可以在我的基础上试试其他的,代码写的不好,让各位见笑了,如有错误,也恳请各位指正。

来自为知笔记(Wiz)

如果觉得《消息钩子学习工程》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。