首页
社区
课程
招聘
[原创]消息钩子注册浅析
发表于: 2011-6-18 23:10 35634

[原创]消息钩子注册浅析

2011-6-18 23:10
35634

windows消息钩子很古老,但目前仍有很多地方需要用到,简单跟踪了一下函数执行流程,函数用法如下(MSDN):

函数功能:该函数将一个应用程序定义的挂钩处理过程安装到挂钩链中去,您可以通过安装挂钩处理过程来对系统的某些类型事件进行监控,这些事件与某个特定的线程或系统中的所有事件相关.
函数原形:

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

.text:77D31211 ; HHOOK __stdcall SetWindowsHookExA(int idHook, HOOKPROC lpfn, HINSTANCE hmod, DWORD dwThreadId)
.text:77D31211                 public _SetWindowsHookExA@16
.text:77D31211 _SetWindowsHookExA@16 proc near         ; DATA XREF: .text:off_77D13928.o
.text:77D31211
.text:77D31211 idHook          = dword ptr  8
.text:77D31211 lpfn            = dword ptr  0Ch
.text:77D31211 hModule         = dword ptr  10h
.text:77D31211 dwThreadId      = dword ptr  14h
.text:77D31211
.text:77D31211                 mov     edi, edi
.text:77D31213                 push    ebp
.text:77D31214                 mov     ebp, esp
.text:77D31216                 push    2               ;DWORD dwFlags
.text:77D31218                 push    [ebp+dwThreadId]
.text:77D3121B                 push    [ebp+hModule] 
.text:77D3121E                 push    [ebp+lpfn]
.text:77D31221                 push    [ebp+idHook]
.text:77D31224                 call    _SetWindowsHookExAW@20 ; SetWindowsHookExAW(x,x,x,x,x)
.text:77D31229                 pop     ebp
.text:77D3122A                 retn    10h
.text:77D3122A _SetWindowsHookExA@16 endp

HHOOK __stdcall SetWindowsHookExAW(int idHook, HOOKPROC lpfn, HINSTANCE hmod, DWORD dwThreadId,DWORD dwFlags

.text:77D28157 ; int __stdcall SetWindowsHookExAW(int idHook, int lpfn, HMODULE hModule, int dwThreadId, DWORD dwFlags
.text:77D28157 _SetWindowsHookExAW@20 proc near        ; CODE XREF: SetWindowsHookExW(x,x,x,x)+13.p
.text:77D28157                                         ; SetWindowsHookExA(x,x,x,x)+13.p
.text:77D28157
.text:77D28157 Filename        = word ptr -20Ch
.text:77D28157 var_4           = dword ptr -4
.text:77D28157 idHook          = dword ptr  8
.text:77D28157 lpfn            = dword ptr  0Ch
.text:77D28157 hModule         = dword ptr  10h
.text:77D28157 dwThreadId      = dword ptr  14h
.text:77D28157 Mod             = dword ptr  18h
.text:77D28157
.text:77D28157                 mov     edi, edi
.text:77D28159                 push    ebp
.text:77D2815A                 mov     ebp, esp
.text:77D2815C                 sub     esp, 20Ch       ; 为局部变量分配内存空间0x20Ch = 524字节,此为双字节数组,共261个元素,所以最大元素下标是260[MAX_PATH]
.text:77D28162                 mov     eax, ___security_cookie
.text:77D28167                 push    esi             ; 保存esi
.text:77D28168                 mov     esi, [ebp+hModule]
.text:77D2816B                 test    esi, esi
.text:77D2816D                 push    edi
.text:77D2816E                 mov     edi, [ebp+lpfn]
.text:77D28171                 mov     [ebp+var_4], eax
.text:77D28174                 jz      short loc_77D2818D ; hmod为NULL
.text:77D28176                 push    104h            ; nSize
.text:77D2817B                 lea     eax, [ebp+Filename]
.text:77D28181                 push    eax             ; lpFilename
.text:77D28182                 push    esi             ; hModule
.text:77D28183                 call    ds:__imp__GetModuleFileNameW@12 ; GetModuleFileNameW(x,x,x)
.text:77D28189                 test    eax, eax
.text:77D2818B                 jz      short loc_77D281AC ; 获取模块句柄失败
.text:77D2818D
.text:77D2818D loc_77D2818D:                           ; CODE XREF: SetWindowsHookExAW(x,x,x,x,x)+1D.j
.text:77D2818D                 push    [ebp+dwFlags]		
.text:77D28190                 mov     eax, esi			;esi也拥有模块句柄
.text:77D28192                 push    edi				;lpfn入栈
.text:77D28193                 push    [ebp+idHook]
.text:77D28196                 neg     eax				;取反操作,如果eax为NULL的话,CF位为0,否则CF置1
.text:77D28198                 push    [ebp+dwThreadId]
.text:77D2819B                 sbb     eax, eax			;若CF为0,eax = 0,否则eax为-1
.text:77D2819D                 lea     ecx, [ebp+Filename]
.text:77D281A3                 and     eax, ecx			;sbb后,若eax为0,则结果为0,否则为ecx
.text:77D281A5                 push    eax				;判断结果
.text:77D281A6                 push    esi				;esi拥有模块句柄
.text:77D281A7                 call    __SetWindowsHookEx@24 ; _SetWindowsHookEx(x,x,x,x,x,x)
.text:77D281AC
.text:77D281AC loc_77D281AC:                           ; CODE XREF: SetWindowsHookExAW(x,x,x,x,x)+34.j
.text:77D281AC                 mov     ecx, [ebp+var_4]
.text:77D281AF                 pop     edi
.text:77D281B0                 pop     esi
.text:77D281B1                 call    @__security_check_cookie@4 ; __security_check_cookie(x)
.text:77D281B6                 leave
.text:77D281B7                 retn    14h
.text:77D281B7 _SetWindowsHookExAW@20 endp
HHOOK __stdcall SetWindowsHookExAW(int idHook, HOOKPROC lpfn, HINSTANCE hmod, DWORD dwThreadId,DWORD dwFlags)
{
	WCHAR Filename[MAX_PATH];
	if (hmod != NULL)
	{
		//获取文件名
		if (!GetModuleFileNameW(hmod,Filename,MAX_PATH))
		{
			//该参数虽然存在,但经验证是伪造的,返回NULL
			return NULL;
		}
	}
	return _SetWindowsHookEx(hmod,(hmod == NULL) ? NULL:Filename,dwThreadId,idHook,lpfn,dwFlags);
}
.text:77D281BF ; int __stdcall _SetWindowsHookEx(HMODULE hmod, LPCWSTR Filename, DWORD dwThreadId, int idHook, HOOKPROC lpfn, DWORD dwFlags)
.text:77D281BF __SetWindowsHookEx@24 proc near         ; CODE XREF: SetWindowsHookExAW(x,x,x,x,x)+50.p
.text:77D281BF
.text:77D281BF usFileName      = byte ptr -10h
.text:77D281BF usModuleName    = dword ptr -8
.text:77D281BF var_4           = dword ptr -4
.text:77D281BF hmod            = dword ptr  8
.text:77D281BF Filename        = dword ptr  0Ch
.text:77D281BF dwThreadId      = dword ptr  10h
.text:77D281BF idHook          = dword ptr  14h
.text:77D281BF lpfn            = dword ptr  18h
.text:77D281BF Flags           = dword ptr  1Ch
.text:77D281BF
.text:77D281BF                 mov     edi, edi
.text:77D281C1                 push    ebp
.text:77D281C2                 mov     ebp, esp
.text:77D281C4                 sub     esp, 10h        ; 分配16字节大小堆栈空间
.text:77D281C7                 push    [ebp+Filename]  ; Filename入栈
.text:77D281CA                 and     [ebp+var_4], 0	;
.text:77D281CE                 lea     eax, [ebp+usFileName]
.text:77D281D1                 push    eax
.text:77D281D2                 mov     [ebp+usModuleName], eax
.text:77D281D5                 call    ds:__imp__RtlInitUnicodeString@8 ; RtlInitUnicodeString(x,x)
.text:77D281DB                 push    [ebp+dwFlags]
.text:77D281DE                 push    [ebp+lpfn]
.text:77D281E1                 push    [ebp+idHook]
.text:77D281E4                 push    [ebp+dwThreadId]
.text:77D281E7                 push    [ebp+usModuleName]
.text:77D281EA                 push    [ebp+hmod]
.text:77D281ED                 call    _NtUserSetWindowsHookEx@24 ; NtUserSetWindowsHookEx(x,x,x,x,x,x)
.text:77D281F2                 leave
.text:77D281F3                 retn    18h
.text:77D281F3 __SetWindowsHookEx@24 endp
HHOOK __stdcall _SetWindowsHookEx(HMODULE hmod,LPCWSTR Filename,DWORD dwThreadId,int idHook,HOOKPROC lpfn,DWORD dwFlags)
{
	UNICODE_STRING usFileName;
	
	//初始化UNICODE字符串结构
	RtlInitUnicodeString(&usFileName,Filename);
	return NtUserSetWindowsHookEx(hmod,&usFileName,dwThreadId,idHook,lpfn,dwFlags);
}

.text:77D281FB ; __stdcall NtUserSetWindowsHookEx(x, x, x, x, x, x)
.text:77D281FB _NtUserSetWindowsHookEx@24 proc near    ; CODE XREF: _SetWindowsHookEx(x,x,x,x,x,x)+2E.p
.text:77D281FB                 mov     eax, 1225h
.text:77D28200                 mov     edx, 7FFE0300h
.text:77D28205                 call    dword ptr [edx]
.text:77D28207                 retn    18h
.text:77D28207 _NtUserSetWindowsHookEx@24 endp
HHOOK
NTAPI
NtUserSetWindowsHookEx(
			HINSTANCE Mod,
			PUNICODE_STRING ModuleName,
			DWORD ThreadId,
			int HookId,
			HOOKPROC HookProc,
			DWORD dwFlags);

.text:BF85EA67 ; START OF FUNCTION CHUNK FOR _NtUserSetWindowsHookEx@24
.text:BF85EA67
.text:BF85EA67 loc_BF85EA67:                           ; CODE XREF: NtUserSetWindowsHookEx(x,x,x,x,x,x)+1C.j
.text:BF85EA67                 push    57h             ; 错误码:87 ,参数不正确
.text:BF85EA69                 call    _UserSetLastError@4 ; UserSetLastError(x)
.text:BF85EA6E                 jmp     short loc_BF85EAAE ; 准备退出
.text:BF85EA6E ; END OF FUNCTION CHUNK FOR _NtUserSetWindowsHookEx@24


.text:BF85EA75 ; int __stdcall NtUserSetWindowsHookEx(HINSTANCE Mod, PUNICODE_STRING ModuleName, DWORD ThreadId, int HookId, HOOKPROC HookProc, BOOL Ansi)
.text:BF85EA75 _NtUserSetWindowsHookEx@24 proc near    ; DATA XREF: .data:BF99E094.o
.text:BF85EA75
.text:BF85EA75 Mod             = dword ptr  8
.text:BF85EA75 ModuleName      = dword ptr  0Ch
.text:BF85EA75 ThreadId        = dword ptr  10h
.text:BF85EA75 HookId          = dword ptr  14h
.text:BF85EA75 HookProc        = dword ptr  18h
.text:BF85EA75 Ansi            = dword ptr  1Ch
.text:BF85EA75
.text:BF85EA75 ; FUNCTION CHUNK AT .text:BF85EA67 SIZE 00000009 BYTES
.text:BF85EA75
.text:BF85EA75                 mov     edi, edi
.text:BF85EA77                 push    ebp
.text:BF85EA78                 mov     ebp, esp
.text:BF85EA7A                 push    esi
.text:BF85EA7B                 call    _EnterCrit@0    ; EnterCrit()
.text:BF85EA80                 xor     esi, esi
.text:BF85EA82                 cmp     [ebp+ThreadId], esi
.text:BF85EA85                 jz      short loc_BF85EABA ; 进程ID为0,说明是系统全局消息钩子
.text:BF85EA87                 push    [ebp+ThreadId]
.text:BF85EA8A                 call    _PtiFromThreadId@4 ; 通过线程ID获取PTHREADINFO指针
.text:BF85EA8F                 cmp     eax, esi
.text:BF85EA91                 jz      short loc_BF85EA67 ; 没有获取
.text:BF85EA93
.text:BF85EA93 loc_BF85EA93:                           ; CODE XREF: NtUserSetWindowsHookEx(x,x,x,x,x,x)+47.j
.text:BF85EA93                 push    [ebp+dwFlags]
.text:BF85EA96                 push    [ebp+HookProc]
.text:BF85EA99                 push    [ebp+HookId]
.text:BF85EA9C                 push    eax
.text:BF85EA9D                 push    [ebp+ModuleName]
.text:BF85EAA0                 push    [ebp+Mod]
.text:BF85EAA3                 call    _zzzSetWindowsHookEx@24 ; zzzSetWindowsHookEx(x,x,x,x,x,x)
.text:BF85EAA8                 cmp     eax, esi        ; 判断结果为NULL
.text:BF85EAAA                 jz      short loc_BF85EAAE ; 失败则跳转
.text:BF85EAAC                 mov     esi, [eax]      ; 暂存结果
.text:BF85EAAE
.text:BF85EAAE loc_BF85EAAE:                           ; CODE XREF: NtUserSetWindowsHookEx(x,x,x,x,x,x)-7.j
.text:BF85EAAE                                         ; NtUserSetWindowsHookEx(x,x,x,x,x,x)+35.j
.text:BF85EAAE                 call    _LeaveCrit@0    ; LeaveCrit()
.text:BF85EAB3                 mov     eax, esi
.text:BF85EAB5                 pop     esi
.text:BF85EAB6                 pop     ebp
.text:BF85EAB7                 retn    18h
.text:BF85EABA ; ---------------------------------------------------------------------------
.text:BF85EABA
.text:BF85EABA loc_BF85EABA:                           ; CODE XREF: NtUserSetWindowsHookEx(x,x,x,x,x,x)+10.j
.text:BF85EABA                 xor     eax, eax
.text:BF85EABC                 jmp     short loc_BF85EA93
.text:BF85EABC _NtUserSetWindowsHookEx@24 endp

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (38)
雪    币: 19
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
先占楼再仔细看
2011-6-18 23:12
0
雪    币: 1163
活跃值: (137)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
3
对于想深入了解下钩子的同学,这篇文章太福音了。感谢楼主的分享。
2011-6-19 04:01
0
雪    币: 39
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
挺详细~~  mark 稍后来看
2011-6-19 09:32
0
雪    币: 212
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
太详细了   恢复标记一下 慢慢看
2011-6-19 11:37
0
雪    币: 220
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
嗯 不错 铭记一下
2011-6-19 11:59
0
雪    币: 693
活跃值: (108)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
7
好文章,收藏了
2011-6-19 12:43
0
雪    币: 278
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
8
学习一下,Mark一下。
2011-6-19 13:01
0
雪    币: 149
活跃值: (171)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
9
学习一下。马克。。。。
2011-6-19 13:23
0
雪    币: 2331
活跃值: (2220)
能力值: (RANK:400 )
在线值:
发帖
回帖
粉丝
10
好长啊, 先mark, 有空看之.
2011-6-19 17:06
0
雪    币: 89
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
应了那句话:百足之虫死而不僵。
古老的东西很强大。。
2011-6-19 20:40
0
雪    币: 656
活跃值: (448)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
12
太好了,什么时候能到达这种水平我就欣慰了,收藏之!
2011-6-19 21:15
0
雪    币: 14
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
很详细啊,顶一个。慢慢学吧
2011-6-19 21:33
0
雪    币: 7161
活跃值: (1175)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
真的很详细,好好学习下!
2011-6-19 21:56
0
雪    币: 30
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
额  详细的讲解  以后慢慢看
2011-6-19 23:20
0
雪    币: 133
活跃值: (587)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
16
首先MARK之,以后在看
2011-6-20 14:06
0
雪    币: 1259
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
stu
17
if (!CopyLZTechnology2Me())
    {
        MessageBox(NULL,CTXT("要加油!"),CTXT("提示!"),MB_OK);
    }
else
    {
        MessageBox(NULL,CTXT("要加薪!"),CTXT("Yeah!"),MB_OK);
    }
2011-6-20 18:12
0
雪    币: 615
活跃值: (172)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
18
不错, 收藏了!
2011-6-20 22:45
0
雪    币: 3800
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
果断收藏!!!!
2011-6-20 23:36
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
mark mark
2011-6-21 16:00
0
雪    币: 70
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
这个必须要Mark一下。
2011-6-21 16:15
0
雪    币: 40
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
22
对于想深入了解下钩子的同学,这篇文章太福音了。感谢楼主的分享。
2011-6-24 10:30
0
雪    币: 244
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
留着慢慢消化
2011-6-24 10:39
0
雪    币: 1414
活跃值: (396)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
古老的东西很强大。。
2011-6-26 10:43
0
雪    币: 563
活跃值: (106)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
好长收下!!
2011-6-27 12:40
0
游客
登录 | 注册 方可回帖
返回
//