OK - - 前几天再看 罗大侠的win32asm,
看到第11章使用SetWindowsHookex全局钩子,挂键盘的时候
对共享变量有了一些疑问,
觉得消息 窗口句柄这些不需要做成共享变量,所以祭起OD~分析了一下。
然后就明白了。
废话不多说,有XX有真相start:
.data
hInstance dd ?
szDllmsg db '进入DLL中...',0
.data?
hWnd dd ? ;同样 需要窗口具备句柄
dwMessage dd ? ;必须共享的参数,不然传送的时候发不过去,不是一个进程的。。a
hHook dd ?
szAscii db 4 dup (?);预留四字节
.code
这是在DLL中定义的变量,当然了/section:bss,s选项开启了。。
此时我先按照正常的编译一下。我们来看看代码~~~
首先是 安装挂钩的程序,我们先分析他是如何获得 句柄 消息以及如何传递的
00401000 /. 55 push ebp ; 解码为 <WinProc>
00401001 |. 8BEC mov ebp,esp
00401003 |. 83C4 FC add esp,-4
00401006 |. 53 push ebx
00401007 |. 57 push edi
00401008 |. 56 push esi
00401009 |. 8B45 0C mov eax,dword ptr ss:[ebp+C]
0040100C |. 83F8 10 cmp eax,10 ; Switch (cases 10..500)
0040100F |. 75 11 jnz short Main.00401022
00401011 |. E8 BE000000 call <jmp.&Hookdll.UninstallHook> ; Case 10 of switch 0040100C
00401016 |. 6A 00 push 0 ; /Result = 0
00401018 |. FF75 08 push dword ptr ss:[ebp+8] ; |hWnd
0040101B |. E8 96000000 call <jmp.&USER32.EndDialog> ; \EndDialog
00401020 |. EB 60 jmp short Main.00401082
00401022 |> 3D 10010000 cmp eax,110
00401027 |. 75 1D jnz short Main.00401046
00401029 |. 68 00050000 push 500 ; Case 110 of switch 0040100C 自定义的消息WM_HOOK ==WM_USER+100
0040102E |. FF75 08 push dword ptr ss:[ebp+8]
00401031 |. E8 98000000 call <jmp.&Hookdll.InstallHook> ;这些是安装挂钩
00401036 |. 0BC0 or eax,eax
00401038 |. 75 48 jnz short Main.00401082
0040103A |. 6A 00 push 0 ; /Result = 0
0040103C |. FF75 08 push dword ptr ss:[ebp+8] ; |hWnd
0040103F |. E8 72000000 call <jmp.&USER32.EndDialog> ; \EndDialog
00401044 |. EB 3C jmp short Main.00401082
00401046 |> 3D 00050000 cmp eax,500
0040104B |. 75 29 jnz short Main.00401076
0040104D |. 8B45 10 mov eax,dword ptr ss:[ebp+10] ; Case 500 of switch 0040100C
00401050 |. 3C 0D cmp al,0D
00401052 |. 75 05 jnz short Main.00401059
00401054 |. B8 0D0A0000 mov eax,0A0D
00401059 |> 8945 FC mov dword ptr ss:[ebp-4],eax
0040105C |. 8D45 FC lea eax,dword ptr ss:[ebp-4]
0040105F |. 50 push eax ; /lParam
00401060 |. 6A 00 push 0 ; |wParam = 0
00401062 |. 68 C2000000 push 0C2 ; |Message = EM_REPLACESEL
00401067 |. 68 E9030000 push 3E9 ; |ControlID = 3E9 (1001.)
0040106C |. FF75 08 push dword ptr ss:[ebp+8] ; |hWnd
0040106F |. E8 48000000 call <jmp.&USER32.SendDlgItemMessageA> ; \SendDlgItemMessageA
00401074 |. EB 0C jmp short Main.00401082
00401076 |> B8 00000000 mov eax,0 ; Default case of switch 0040100C
0040107B |. 5E pop esi
0040107C |. 5F pop edi
0040107D |. 5B pop ebx
0040107E |. C9 leave
0040107F |. C2 1000 retn 10
DLL 代码————————————————————————————10001000 Hookdll.<模块入口点> /$ 55 push ebp
10001001 |. 8BEC mov ebp,esp
10001003 |. FF75 08 push dword ptr ss:[ebp+8]
10001006 <Hookdll.DLL_handel>|. 8F05 00400010 pop dword ptr ds:[10004000] ; Hookdll.10000000
1000100C |. B8 01000000 mov eax,1
10001011 |. C9 leave
10001012 \. C2 0C00 retn 0C
10001015 Hookdll.HookProc /$ 55 push ebp
10001016 |. 8BEC mov ebp,esp
10001018 |. 81C4 00FFFFFF add esp,-100
1000101E |. FF75 10 push dword ptr ss:[ebp+10] ; /lParam
10001021 |. FF75 0C push dword ptr ss:[ebp+C] ; |wParam
10001024 |. FF75 08 push dword ptr ss:[ebp+8] ; |HookCode
10001027 |. FF35 08200010 push dword ptr ds:[10002008] ; |hHook = NULL
1000102D |. E8 9A000000 call <jmp.&user32.CallNextHookEx> ; \CallNextHookEx
10001032 |. 8D85 00FFFFFF lea eax,dword ptr ss:[ebp-100]
10001038 |. 50 push eax ; /pState
10001039 |. E8 9A000000 call <jmp.&user32.GetKeyboardState> ; \GetKeyboardState
1000103E |. 6A 10 push 10 ; /Key = VK_SHIFT
10001040 |. E8 8D000000 call <jmp.&user32.GetKeyState> ; \GetKeyState
10001045 |. 8885 10FFFFFF mov byte ptr ss:[ebp-F0],al ; 按下为81 释放为80 没按 为1
1000104B |. 8B4D 10 mov ecx,dword ptr ss:[ebp+10]
1000104E |. C1E9 10 shr ecx,10
10001051 |. 6A 00 push 0 ; /MenuActive = 0
10001053 |. 68 0C200010 push Hookdll.1000200C ; |szascii
10001058 |. 8D85 00FFFFFF lea eax,dword ptr ss:[ebp-100] ; |
1000105E |. 50 push eax ; |szKeyState
1000105F |. 51 push ecx ; |ScanCode
10001060 |. FF75 0C push dword ptr ss:[ebp+C] ; |Key
10001063 |. E8 82000000 call <jmp.&user32.ToAscii> ; \ToAscii
10001068 |. C680 0C200010 00 mov byte ptr ds:[eax+1000200C],0
1000106F |. 6A 00 push 0 ; /lParam = 0
10001071 |. FF35 0C200010 push dword ptr ds:[1000200C] ; |wParam = 0
10001077 |. FF35 04200010 push dword ptr ds:[10002004] ; |Message = MSG(500)
1000107D |. FF35 00200010 push dword ptr ds:[10002000] ; |hWnd = 4802FC
10001083 |. E8 56000000 call <jmp.&user32.SendMessageA> ; \SendMessageA
10001088 |. 33C0 xor eax,eax
1000108A |. C9 leave
1000108B \. C2 0C00 retn 0C
1000108E Hookdll.InstallHook /$ 55 push ebp
1000108F |. 8BEC mov ebp,esp
10001091 |. FF75 08 push dword ptr ss:[ebp+8]
10001094 |. 8F05 00200010 pop dword ptr ds:[10002000] ; 窗口句柄
1000109A |. FF75 0C push dword ptr ss:[ebp+C]
1000109D |. 8F05 04200010 pop dword ptr ds:[10002004] ; 消息ID
100010A3 |. 6A 00 push 0 ; /ThreadID = 0
100010A5 |. FF35 00400010 push dword ptr ds:[10004000] ; |hModule = 10000000 (Hookdll)
100010AB |. 68 15100010 push Hookdll.HookProc ; |Hookproc = Hookdll.HookProc
100010B0 |. 6A 02 push 2 ; |HookType = WH_KEYBOARD
100010B2 |. E8 2D000000 call <jmp.&user32.SetWindowsHookExA>
; \这里一定要注意 从这里,一定要开始使用鼠标,点击工具栏的“步入 OR 步过”来实现键盘的F7 F8。我也不知道为什么挂钩这个函数执行后,再次F7 F8 OD就会卡死,我觉得可能是因为是全局键盘钩子原因,但是具体原因,我也不是很清楚,如果哪位大侠调试过后,知道怎么回事了。还望告知一二~~这里把断点下再 被挂钩的程序中,不再OD中的HOOK dll下断就不会卡死,我也不知道为什么
当然这样以来 就分析 不到 安装钩子的过程了, 所以 我再分析怎样 得到句柄 和消息的时候还是再 主程序中分析的,分析程序的流程是再被挂钩的程序分析的~~~
这一点请大家注意一下~~~
—————————
1000108F |. 8BEC mov ebp,esp
10001091 |. FF75 08 push dword ptr ss:[ebp+8]
10001094 |. 8F05 00200010 pop dword ptr ds:[10002000] ; 窗口句柄
1000109A |. FF75 0C push dword ptr ss:[ebp+C]
1000109D |. 8F05 04200010 pop dword ptr ds:[10002004] ; 消息ID
这里我们可以看到 获得参数存到数据段~~~~
~~
OK,我们的目标达到了。 我们看一下 如果不是共享的会出现什么情况~
————————————————————————————————————————————我是邪恶的分割线,
.data
hInstance dd ?
szDllmsg db '进入DLL中...',0
hWnd dd ? ;同样 需要窗口具备句柄
dwMessage dd ? ;必须共享的参数,不然传送的时候发不过去,不是一个进程的。。a
我们把 hWnd 和dwMessage 放到 初始化节区,看看 发生了什么~~~
.data?
hHook dd ?
此时 这个 DLL还是 我们main.exe里面的hook dll10001091 |. FF75 08 push dword ptr ss:[ebp+8]
10001094 |. 8F05 11400010 pop dword ptr ds:[10004011] ; 窗口句柄
1000109A |. FF75 0C push dword ptr ss:[ebp+C]
1000109D |. 8F05 15400010 pop dword ptr ds:[10004015] ; 消息ID
这是没有共享变量时候 句柄和消息存放的地方
————————————————————————————————1000106F |. 6A 00 push 0 ; /lParam = 0
10001071 |. FF35 04200010 push dword ptr ds:[10002004] ; |wParam = 0
10001077 |. FF35 15400010 push dword ptr ds:[10004015] ; |Message = MSG(500)
1000107D |. FF35 11400010 push dword ptr ds:[10004011] ; |hWnd = 830382
10001083 |. E8 56000000 call <jmp.&user32.SendMessageA> ; \SendMessageA
这是 获得 数据 并且通过SendMessage 发送给窗口一个消息~~~
本进程当然没问题。数据段是有数据的~~~
可是 我们跟跟别的进程会发现~~~如下
——————————————————————————————————- 注入到别的进程的hook.dll1000106F |. 6A 00 push 0 ; /lParam = 0
10001071 |. FF35 04200010 push dword ptr ds:[10002004] ; |wParam = 0
10001077 |. FF35 15400010 push dword ptr ds:[10004015] ; |Message = WM_NULL
1000107D |. FF35 11400010 push dword ptr ds:[10004011] ; |hWnd = NULL
10001083 |. E8 56000000 call <jmp.&user32.SendMessageA> ; \SendMessageA
同样也是这个数据段
但是~~~DD一下数据断~~我们可以看到~~
10004011 00000000
10004015 00000000
这里根本没有数据~~~~ 当然 send也不知道send给谁了~~~~
此时我们明白了,虽然DLL是在同一个物理内存。通过不同的 内存映射,然后再每个进程都有一个HOOK.DLL
但是 数据段 如果不共享,那么,每个进程的数据 都是“隔离”的!!!
别的进程的hook.dll自然无法获取 Main.exe里面的DLL得到的 句柄和 消息了~~~10001091 |. FF75 08 push dword ptr ss:[ebp+8]
10001094 |. 8F05 11400010 pop dword ptr ds:[10004011] ; 窗口句柄
1000109A |. FF75 0C push dword ptr ss:[ebp+C]
1000109D |. 8F05 15400010 pop dword ptr ds:[10004015] ; 消息ID
就是这里 无法得到了~~也可能是别的DLL根本没有执行到这里,反正我再这里下断 是断不到,不知道大侠们有什么方法~~~
我说完了~~~~~~~~~~
同时,留下两个问题
1,谁能提供一个 支持代码着色的 工具, - - 以后贴代码的时候,就可以是彩色的了~~
2,就是这个卡死问题,哪位大侠能深入讲解一下??? |