接着上面一篇文章 , 下面是反汇编代码的对照讲解:
现在我们来看一看反汇编的代码:
00401000 /. 55 push ebp
00401001 |. 8BEC mov ebp, esp
00401003 |. 83C4 AC add esp, -54
00401006 |. 8B45 0C mov eax, dword ptr [ebp+C]
00401009 |. 83F8 0F cmp eax, 0F
0040100C |. 75 55 jnz short 00401063
0040100E |. 8D45 C0 lea eax, dword ptr [ebp-40]
00401011 |. 50 push eax ; /pPaintstruct
00401012 |. FF75 08 push dword ptr [ebp+8] ; |hWnd
00401015 |. E8 B0010000 call <jmp.&user32.BeginPaint> ; /BeginPaint
0040101A |. 8945 AC mov dword ptr [ebp-54], eax
0040101D |. 68 00FF0000 push 0FF00 ; /Color = <LIGHTGREEN>
00401022 |. FF75 AC push dword ptr [ebp-54] ; |hDC
00401025 |. E8 24020000 call <jmp.&gdi32.SetTextColor> ; /SetTextColor
0040102A |. 6A 00 push 0 ; /Color = <BLACK>
0040102C |. FF75 AC push dword ptr [ebp-54] ; |hDC
0040102F |. E8 14020000 call <jmp.&gdi32.SetBkColor> ; /SetBkColor
00401034 |. 8D45 B0 lea eax, dword ptr [ebp-50]
00401037 |. 50 push eax ; /pRect
00401038 |. FF75 08 push dword ptr [ebp+8] ; |hWnd
0040103B |. E8 B4010000 call <jmp.&user32.GetClientRect> ; /GetClientRect
00401040 |. 6A 25 push 25 ; /Flags = DT_CENTER|DT_VCENTER|DT_SINGLELINE
00401042 |. 8D45 B0 lea eax, dword ptr [ebp-50] ; |
00401045 |. 50 push eax ; |pRect
00401046 |. 6A FF push -1 ; |Count = FFFFFFFF (-1.)
00401048 |. 68 75204000 push 00402075 ; |Text = "things have changed from now"
0040104D |. FF75 AC push dword ptr [ebp-54] ; |hDC
00401050 |. E8 93010000 call <jmp.&user32.DrawTextA> ; /DrawTextA
00401055 |. 8D45 C0 lea eax, dword ptr [ebp-40]
00401058 |. 50 push eax ; /pPaintstruct
00401059 |. FF75 08 push dword ptr [ebp+8] ; |hWnd
0040105C |. E8 8D010000 call <jmp.&user32.EndPaint> ; /EndPaint
00401061 |. EB 2E jmp short 00401091
00401063 |> 83F8 10 cmp eax, 10
00401066 |. 75 14 jnz short 0040107C
00401068 |. FF35 04304000 push dword ptr [403004] ; /hWnd = NULL
0040106E |. E8 69010000 call <jmp.&user32.DestroyWindow> ; /DestroyWindow
00401073 |. 6A 00 push 0 ; /ExitCode = 0
00401075 |. E8 98010000 call <jmp.&user32.PostQuitMessage> ; /PostQuitMessage
0040107A |. EB 15 jmp short 00401091
0040107C |> FF75 14 push dword ptr [ebp+14] ; /lParam
0040107F |. FF75 10 push dword ptr [ebp+10] ; |wParam
00401082 |. FF75 0C push dword ptr [ebp+C] ; |Message
00401085 |. FF75 08 push dword ptr [ebp+8] ; |hWnd
00401088 |. E8 49010000 call <jmp.&user32.DefWindowProcA> ; /DefWindowProcA
0040108D |. C9 leave
0040108E |. C2 1000 retn 10
00401091 |> 33C0 xor eax, eax
00401093 |. C9 leave
00401094 /. C2 1000 retn 10
00401097 /$ 55 push ebp
00401098 |. 8BEC mov ebp, esp
0040109A |. 83C4 B4 add esp, -4C
0040109D |. 6A 00 push 0 ; /pModule = NULL
0040109F |. E8 92010000 call <jmp.&kernel32.GetModuleHandleA> ; /GetModuleHandleA
004010A4 |. A3 00304000 mov dword ptr [403000], eax
004010A9 |. 6A 30 push 30 ; /Length = 30 (48.)
004010AB |. 8D45 D0 lea eax, dword ptr [ebp-30] ; |
004010AE |. 50 push eax ; |Destination
004010AF |. E8 88010000 call <jmp.&kernel32.RtlZeroMemory> ; /RtlZeroMemory
004010B4 |. C745 D0 30000>mov dword ptr [ebp-30], 30
004010BB |. C745 D4 03000>mov dword ptr [ebp-2C], 3
004010C2 |. C745 D8 00104>mov dword ptr [ebp-28], 00401000
004010C9 |. FF35 00304000 push dword ptr [403000]
004010CF |. 8F45 E4 pop dword ptr [ebp-1C]
004010D2 |. 68 007F0000 push 7F00 ; /RsrcName = IDI_APPLICATION
004010D7 |. 6A 00 push 0 ; |hInst = NULL
004010D9 |. E8 28010000 call <jmp.&user32.LoadIconA> ; /LoadIconA
004010DE |. 8945 E8 mov dword ptr [ebp-18], eax
004010E1 |. 8945 FC mov dword ptr [ebp-4], eax
004010E4 |. 68 007F0000 push 7F00 ; /RsrcName = IDC_ARROW
004010E9 |. 6A 00 push 0 ; |hInst = NULL
004010EB |. E8 10010000 call <jmp.&user32.LoadCursorA> ; /LoadCursorA
004010F0 |. 8945 EC mov dword ptr [ebp-14], eax
004010F3 |. 6A 04 push 4 ; /ObjType = BLACK_BRUSH
004010F5 |. E8 48010000 call <jmp.&gdi32.GetStockObject> ; /GetStockObject
004010FA |. 8945 F0 mov dword ptr [ebp-10], eax
004010FD |. C745 F8 68204>mov dword ptr [ebp-8], 00402068 ; ASCII "NormalWindow"
00401104 |. 8D45 D0 lea eax, dword ptr [ebp-30]
00401107 |. 50 push eax ; /pWndClassEx
00401108 |. E8 0B010000 call <jmp.&user32.RegisterClassExA> ; /RegisterClassExA
0040110D |. 0BC0 or eax, eax
0040110F |. 75 15 jnz short 00401126
00401111 |. 6A 10 push 10 ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
00401113 |. 68 92204000 push 00402092 ; |Title = "Error"
00401118 |. 68 98204000 push 00402098 ; |Text = "This program requires NT !"
0040111D |. 6A 00 push 0 ; |hOwner = NULL
0040111F |. E8 E8000000 call <jmp.&user32.MessageBoxA> ; /MessageBoxA
00401124 |. C9 leave
00401125 |. C3 retn
00401126 |> 6A 00 push 0 ; /lParam = NULL
00401128 |. FF35 00304000 push dword ptr [403000] ; |hInst = NULL
0040112E |. 6A 00 push 0 ; |hMenu = NULL
00401130 |. 6A 00 push 0 ; |hParent = NULL
00401132 |. 68 00000080 push 80000000 ; |Height = 80000000 (-2147483648.)
00401137 |. 68 00000080 push 80000000 ; |Width = 80000000 (-2147483648.)
0040113C |. 68 00000080 push 80000000 ; |Y = 80000000 (-2147483648.)
00401141 |. 68 00000080 push 80000000 ; |X = 80000000 (-2147483648.)
00401146 |. 68 0000CF00 push 0CF0000 ; |Style = WS_OVERLAPPED|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU|WS_THICKFRAME|WS_CAPTION
0040114B |. 68 68204000 push 00402068 ; |WindowName = "NormalWindow"
00401150 |. 68 68204000 push 00402068 ; |Class = "NormalWindow"
00401155 |. 68 00020000 push 200 ; |ExtStyle = WS_EX_CLIENTEDGE
0040115A |. E8 71000000 call <jmp.&user32.CreateWindowExA> ; /CreateWindowExA
0040115F |. 0BC0 or eax, eax
00401161 |. 75 15 jnz short 00401178
00401163 |. 6A 10 push 10 ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
00401165 |. 68 92204000 push 00402092 ; |Title = "Error"
0040116A |. 68 B3204000 push 004020B3 ; |Text = "CreateWindow Error."
0040116F |. 6A 00 push 0 ; |hOwner = NULL
00401171 |. E8 96000000 call <jmp.&user32.MessageBoxA> ; /MessageBoxA
00401176 |. C9 leave
00401177 |. C3 retn
00401178 |> A3 04304000 mov dword ptr [403004], eax
0040117D |. 6A 01 push 1 ; /ShowState = SW_SHOWNORMAL
0040117F |. FF35 04304000 push dword ptr [403004] ; |hWnd = NULL
00401185 |. E8 94000000 call <jmp.&user32.ShowWindow> ; /ShowWindow
0040118A |. FF35 04304000 push dword ptr [403004] ; /hWnd = NULL
00401190 |. E8 95000000 call <jmp.&user32.UpdateWindow> ; /UpdateWindow
00401195 |> 6A 00 / push 0 ; /MsgFilterMax = 0
00401197 |. 6A 00 | push 0 ; |MsgFilterMin = 0
00401199 |. 6A 00 | push 0 ; |hWnd = NULL
0040119B |. 8D45 B4 | lea eax, dword ptr [ebp-4C] ; |
0040119E |. 50 | push eax ; |pMsg
0040119F |. E8 56000000 |call <jmp.&user32.GetMessageA> ; /GetMessageA
004011A4 |. 0BC0 | or eax, eax
004011A6 |. 74 14 | je short 004011BC
004011A8 |. 8D45 B4 | lea eax, dword ptr [ebp-4C]
004011AB |. 50 | push eax ; /pMsg
004011AC |. E8 73000000 |call <jmp.&user32.TranslateMessage> ; /TranslateMessage
004011B1 |. 8D45 B4 | lea eax, dword ptr [ebp-4C]
004011B4 |. 50 | push eax ; /pMsg
004011B5 |. E8 28000000 |call <jmp.&user32.DispatchMessageA> ; /DispatchMessageA
004011BA |.^ EB D9 / jmp short 00401195
004011BC |> C9 leave
004011BD /. C3 retn
004011BE >/$ E8 D4FEFFFF call 00401097
004011C3 |. 6A 00 push 0 ; /ExitCode = 0
004011C5 /. E8 66000000 call <jmp.&kernel32.ExitProcess> ; /ExitProcess
004011CA $- FF25 60204000 jmp dword ptr [<&user32.BeginPaint>] ; user32.BeginPaint
004011D0 $- FF25 58204000 jmp dword ptr [<&user32.CreateWindow>; user32.CreateWindowExA
004011D6 $- FF25 54204000 jmp dword ptr [<&user32.DefWindowPro>; user32.DefWindowProcA
004011DC $- FF25 4C204000 jmp dword ptr [<&user32.DestroyWindo>; user32.DestroyWindow
004011E2 $- FF25 50204000 jmp dword ptr [<&user32.DispatchMess>; user32.DispatchMessageA
004011E8 $- FF25 48204000 jmp dword ptr [<&user32.DrawTextA>] ; user32.DrawTextA
004011EE $- FF25 44204000 jmp dword ptr [<&user32.EndPaint>] ; user32.EndPaint
004011F4 $- FF25 30204000 jmp dword ptr [<&user32.GetClientRec>; user32.GetClientRect
004011FA $- FF25 20204000 jmp dword ptr [<&user32.GetMessageA>>; user32.GetMessageA
00401200 $- FF25 24204000 jmp dword ptr [<&user32.LoadCursorA>>; user32.LoadCursorA
00401206 $- FF25 28204000 jmp dword ptr [<&user32.LoadIconA>] ; user32.LoadIconA
0040120C $- FF25 2C204000 jmp dword ptr [<&user32.MessageBoxA>>; user32.MessageBoxA
00401212 $- FF25 5C204000 jmp dword ptr [<&user32.PostQuitMess>; user32.PostQuitMessage
00401218 $- FF25 34204000 jmp dword ptr [<&user32.RegisterClas>; user32.RegisterClassExA
0040121E $- FF25 38204000 jmp dword ptr [<&user32.ShowWindow>] ; user32.ShowWindow
00401224 $- FF25 3C204000 jmp dword ptr [<&user32.TranslateMes>; user32.TranslateMessage
0040122A $- FF25 40204000 jmp dword ptr [<&user32.UpdateWindow>; user32.UpdateWindow
00401230 .- FF25 14204000 jmp dword ptr [<&kernel32.ExitProces>; kernel32.ExitProcess
00401236 $- FF25 10204000 jmp dword ptr [<&kernel32.GetModuleH>; kernel32.GetModuleHandleA
0040123C $- FF25 18204000 jmp dword ptr [<&kernel32.RtlZeroMem>; ntdll.RtlZeroMemory
00401242 $- FF25 04204000 jmp dword ptr [<&gdi32.GetStockObjec>; GDI32.GetStockObject
00401248 $- FF25 00204000 jmp dword ptr [<&gdi32.SetBkColor>] ; GDI32.SetBkColor
0040124E $- FF25 08204000 jmp dword ptr [<&gdi32.SetTextColor>>; GDI32.SetTextColor
经过反汇编后的代码, 看起来是不是有些郁闷? 跟源程序比, 显得有些乱七八糟的, 其实好好分析一下, 也不难理解:
对于 004011CA $- FF25 60204000 jmp dword ptr [<&user32.BeginPaint>] ; user32.BeginPaint
以及后面的部分,我们就不需要去看了, 很显然, 是程序中用到的一些导入函数
004011BE >/$ E8 D4FEFFFF call 00401097
004011C3 |. 6A 00 push 0 ; /ExitCode = 0
004011C5 /. E8 66000000 call <jmp.&kernel32.ExitProcess> ; /ExitProcess
这个便是标签 start 和 end start 之间的内容
call 00401097 显然是调用主过程 _WinMain, 00401097是 _WinMain的地址
push 0
call <jmp.&kernel32.ExitProcess>
这 2句调用 ExitProcess函数, 传入的退出代码为 0
现在看看主过程 _WinMain对应的反汇编代码:
00401097 /$ 55 push ebp
00401098 |. 8BEC mov ebp, esp
0040109A |. 83C4 B4 add esp, -4C
这 3 句代码首先保存 ebp 的值, 然后将当前栈指针赋值给 ebp ,好在后面 通过 ebp 来访问各个参数
add esp, -4C 为局部变量
local @stWC:WNDCLASSEX
local @stMsg:MSG
分配临时栈空间 , sizeof @stWC 和 sizeof @stMsg 加起来正好 4CH 个字节
0040109D |. 6A 00 push 0 ; /pModule = NULL
0040109F |. E8 92010000 call <jmp.&kernel32.GetModuleHandleA> ; /GetModuleHandleA
004010A4 |. A3 00304000 mov dword ptr [403000], eax
调用 kernel32.dll 模块中的 GetModuleHandleA 函数,得到当前的实例句柄, 并且保存在全局变量 hInstance 中,
全局变量 hInstance 的地址为 403000
004010A9 |. 6A 30 push 30 ; /Length = 30 (48.)
004010AB |. 8D45 D0 lea eax, dword ptr [ebp-30] ; |
004010AE |. 50 push eax ; |Destination
004010AF |. E8 88010000 call <jmp.&kernel32.RtlZeroMemory> ; /RtlZeroMemory
调用 Kernel32 模块中的 RtlZeroMemory 函数, 将局部变量 @stWC 结构填充为 0
其中 @stWC 结构的大小为 30H 个字节, 地址是 ebp-30
004010B4 |. C745 D0 30000>mov dword ptr [ebp-30], 30
相当于 mov @stWC.cbSize, sizeof WNDCLASSEX
004010BB |. C745 D4 03000>mov dword ptr [ebp-2C], 3
相当于 mov @stWC.style, CS_HREDRAW or CS_VREDRAW
004010C2 |. C745 D8 00104>mov dword ptr [ebp-28], 00401000
相当于 mov @stWC.lpfnWndProc, offset _WinProc
004010C9 |. FF35 00304000 push dword ptr [403000]
相当于 push hInstance
004010CF |. 8F45 E4 pop dword ptr [ebp-1C]
相当于 pop @stWC.hInstance
004010D2 |. 68 007F0000 push 7F00 ; /RsrcName = IDI_APPLICATION
004010D7 |. 6A 00 push 0 ; |hInst = NULL
004010D9 |. E8 28010000 call <jmp.&user32.LoadIconA> ; /LoadIconA
004010DE |. 8945 E8 mov dword ptr [ebp-18], eax
004010E1 |. 8945 FC mov dword ptr [ebp-4], eax
调用 user32.dll 模块中的 LoadIcon 函数,得到默认图标,分别填充 @stWC 结构的
@stWC.hIcon 和 @stWC.hIconSm 域
004010E4 |. 68 007F0000 push 7F00 ; /RsrcName = IDC_ARROW
004010E9 |. 6A 00 push 0 ; |hInst = NULL
004010EB |. E8 10010000 call <jmp.&user32.LoadCursorA> ; /LoadCursorA
004010F0 |. 8945 EC mov dword ptr [ebp-14], eax
调用 user32 模块中的 LoadCursor 函数, 得到默认光标,填充 @stWC 结构的 @stWC.hCursor 域
004010F3 |. 6A 04 push 4 ; /ObjType = BLACK_BRUSH
004010F5 |. E8 48010000 call <jmp.&gdi32.GetStockObject> ; /GetStockObject
004010FA |. 8945 F0 mov dword ptr [ebp-10], eax
调用 gdi32 模块中的 GetStockObject 填充 @stWC 结构的 @stWC.hbrBackground 域
004010FD |. C745 F8 68204>mov dword ptr [ebp-8], 00402068 ; ASCII "NormalWindow"
用字符串 'NormalWindow' 填充结构 @stWC 的 @stWC.lpszClassName 域
00401104 |. 8D45 D0 lea eax, dword ptr [ebp-30]
将局部变量 @stWC 的地址放入 eax 中
00401107 |. 50 push eax ; /pWndClassEx
00401108 |. E8 0B010000 call <jmp.&user32.RegisterClassExA> ; /RegisterClassExA
调用 user32 模块中的 RegisterClassExA 注册窗口类
0040110D |. 0BC0 or eax, eax
看 RegisterClassExA 的返回值 ea 是否为 0 ,如果为 0 , 则调用 MessageBoxA 对话框,显示错误讯息,并且执行
leave
retn
指令退出程序
否则,执行 jnz short 00401126 跳转到窗口创建部分
0040110F |. 75 15 jnz short 00401126
00401111 |. 6A 10 push 10 ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
00401113 |. 68 92204000 push 00402092 ; |Title = "Error"
00401118 |. 68 98204000 push 00402098 ; |Text = "This program requires NT !"
0040111D |. 6A 00 push 0 ; |hOwner = NULL
0040111F |. E8 E8000000 call <jmp.&user32.MessageBoxA> ; /MessageBoxA
00401124 |. C9 leave
00401125 |. C3 retn
leave 和 retn 两条指令用于恢复寄存器 ebp 的值以及平衡堆栈, 也就是将寄存器 ebp 和 esp 恢复到调用该过程前的值
下面是创建窗口的代码, 从右到左, 依次传入 CreateWindowExA 的各个参数
00401126 |> 6A 00 push 0 ; /lParam = NULL
00401128 |. FF35 00304000 push dword ptr [403000] ; |hInst = NULL
0040112E |. 6A 00 push 0 ; |hMenu = NULL
00401130 |. 6A 00 push 0 ; |hParent = NULL
00401132 |. 68 00000080 push 80000000 ; |Height = 80000000 (-2147483648.)
00401137 |. 68 00000080 push 80000000 ; |Width = 80000000 (-2147483648.)
0040113C |. 68 00000080 push 80000000 ; |Y = 80000000 (-2147483648.)
00401141 |. 68 00000080 push 80000000 ; |X = 80000000 (-2147483648.)
00401146 |. 68 0000CF00 push 0CF0000 ; |Style = WS_OVERLAPPED|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU|WS_THICKFRAME|WS_CAPTION
0040114B |. 68 68204000 push 00402068 ; |WindowName = "NormalWindow"
00401150 |. 68 68204000 push 00402068 ; |Class = "NormalWindow"
00401155 |. 68 00020000 push 200 ; |ExtStyle = WS_EX_CLIENTEDGE
0040115A |. E8 71000000 call <jmp.&user32.CreateWindowExA> ; /CreateWindowExA
CreateWindowExA 返回, 看看返回值 eax 的值是否为 0 , 如果为 0 , 则显示错误对话框, 调用 leave, retn 平衡堆栈, 并且退出该过程, 否则, 跳转到 ShowWindow 函数部分
0040115F |. 0BC0 or eax, eax
00401161 |. 75 15 jnz short 00401178 ; 跳转到 ShowWindow 的处理部分
00401163 |. 6A 10 push 10 ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
00401165 |. 68 92204000 push 00402092 ; |Title = "Error"
0040116A |. 68 B3204000 push 004020B3 ; |Text = "CreateWindow Error."
0040116F |. 6A 00 push 0 ; |hOwner = NULL
00401171 |. E8 96000000 call <jmp.&user32.MessageBoxA> ; /MessageBoxA
00401176 |. C9 leave
00401177 |. C3 retn
ShowWindow 处理部分, 首先将 CreateWindowExA 的返回值即窗口句柄 eax 存入全局变量 hWinMain
地址是 403004 , 然后调用 ShowWindow 和 UpdateWindow 显示窗口
00401178 |> A3 04304000 mov dword ptr [403004], eax
0040117D |. 6A 01 push 1 ; /ShowState = SW_SHOWNORMAL
0040117F |. FF35 04304000 push dword ptr [403004] ; |hWnd = NULL
00401185 |. E8 94000000 call <jmp.&user32.ShowWindow> ; /ShowWindow
0040118A |. FF35 04304000 push dword ptr [403004] ; /hWnd = NULL
00401190 |. E8 95000000 call <jmp.&user32.UpdateWindow> ; /UpdateWindow
剩下的代码就是消息循环了, 通过 je short 004011BC 跳出消息循环
通过 jmp short 00401195 执行 while 循环
00401195 |> 6A 00 /push 0 ; /MsgFilterMax = 0
00401197 |. 6A 00 |push 0 ; |MsgFilterMin = 0
00401199 |. 6A 00 |push 0 ; |hWnd = NULL
0040119B |. 8D45 B4 |lea eax, dword ptr [ebp-4C] ; |
0040119E |. 50 |push eax ; |pMsg
0040119F |. E8 56000000 |call <jmp.&user32.GetMessageA> ; /GetMessageA
004011A4 |. 0BC0 |or eax, eax
004011A6 |. 74 14 |je short 004011BC
004011A8 |. 8D45 B4 |lea eax, dword ptr [ebp-4C]
004011AB |. 50 |push eax ; /pMsg
004011AC |. E8 73000000 |call <jmp.&user32.TranslateMessage> ; /TranslateMessage
004011B1 |. 8D45 B4 |lea eax, dword ptr [ebp-4C]
004011B4 |. 50 |push eax ; /pMsg
004011B5 |. E8 28000000 |call <jmp.&user32.DispatchMessageA> ; /DispatchMessageA
004011BA |.^ EB D9 /jmp short 00401195
004011BC |> C9 leave
004011BD /. C3 retn
下面来看看窗口过程 _WinProc的反汇编代码:
00401000 /. 55 push ebp
00401001 |. 8BEC mov ebp, esp
00401003 |. 83C4 AC add esp, -54
跟 _WinMain 开头一样,保存 ebp, 为局部变量分配栈空间
00401006 |. 8B45 0C mov eax, dword ptr [ebp+C]
相当于 mov eax, uMsg
ebp + C 就是 uMsg 所在的栈位置
00401009 |. 83F8 0F cmp eax, 0F
看看 uMsg 是不是 WM_PAINT
如果不是,则转入 WM_CLOSE 判断,否则,处理 WM_PAINT 消息,然后通过
jmp short 00401091 退出过程
0040100C |. 75 55 jnz short 00401063
0040100E |. 8D45 C0 lea eax, dword ptr [ebp-40]
00401011 |. 50 push eax ; /pPaintstruct
00401012 |. FF75 08 push dword ptr [ebp+8] ; |hWnd
00401015 |. E8 B0010000 call <jmp.&user32.BeginPaint> ; /BeginPaint
0040101A |. 8945 AC mov dword ptr [ebp-54], eax
0040101D |. 68 00FF0000 push 0FF00 ; /Color = <LIGHTGREEN>
00401022 |. FF75 AC push dword ptr [ebp-54] ; |hDC
00401025 |. E8 24020000 call <jmp.&gdi32.SetTextColor> ; /SetTextColor
0040102A |. 6A 00 push 0 ; /Color = <BLACK>
0040102C |. FF75 AC push dword ptr [ebp-54] ; |hDC
0040102F |. E8 14020000 call <jmp.&gdi32.SetBkColor> ; /SetBkColor
00401034 |. 8D45 B0 lea eax, dword ptr [ebp-50]
00401037 |. 50 push eax ; /pRect
00401038 |. FF75 08 push dword ptr [ebp+8] ; |hWnd
0040103B |. E8 B4010000 call <jmp.&user32.GetClientRect> ; /GetClientRect
00401040 |. 6A 25 push 25 ; /Flags = DT_CENTER|DT_VCENTER|DT_SINGLELINE
00401042 |. 8D45 B0 lea eax, dword ptr [ebp-50] ; |
00401045 |. 50 push eax ; |pRect
00401046 |. 6A FF push -1 ; |Count = FFFFFFFF (-1.)
00401048 |. 68 75204000 push 00402075 ; |Text = "things have changed from now"
0040104D |. FF75 AC push dword ptr [ebp-54] ; |hDC
00401050 |. E8 93010000 call <jmp.&user32.DrawTextA> ; /DrawTextA
00401055 |. 8D45 C0 lea eax, dword ptr [ebp-40]
00401058 |. 50 push eax ; /pPaintstruct
00401059 |. FF75 08 push dword ptr [ebp+8] ; |hWnd
0040105C |. E8 8D010000 call <jmp.&user32.EndPaint> ; /EndPaint
00401061 |. EB 2E jmp short 00401091
00401063 |> 83F8 10 cmp eax, 10
看看 uMsg 是不是 WM_CLOSE
如果不是的,则转入 DefWindowProc 处理,否则,处理 WM_CLOSE 消息,然后通过
jmp short 00401091 退出过程
00401066 |. 75 14 jnz short 0040107C
00401068 |. FF35 04304000 push dword ptr [403004] ; /hWnd = NULL
0040106E |. E8 69010000 call <jmp.&user32.DestroyWindow> ; /DestroyWindow
00401073 |. 6A 00 push 0 ; /ExitCode = 0
00401075 |. E8 98010000 call <jmp.&user32.PostQuitMessage> ; /PostQuitMessage
0040107A |. EB 15 jmp short 00401091
0040107C |> FF75 14 push dword ptr [ebp+14] ; /lParam
0040107F |. FF75 10 push dword ptr [ebp+10] ; |wParam
00401082 |. FF75 0C push dword ptr [ebp+C] ; |Message
00401085 |. FF75 08 push dword ptr [ebp+8] ; |hWnd
00401088 |. E8 49010000 call <jmp.&user32.DefWindowProcA> ; /DefWindowProcA
0040108D |. C9 leave
0040108E |. C2 1000 retn 10
00401091 |> 33C0 xor eax, eax
00401093 |. C9 leave
00401094 /. C2 1000 retn 10
这部分相对比较简单, 主要 cmp进行比较各个消息,如果不是则跳转到下一个消息的比较入口,如果都不是则跳转到默认消息处理, 如果是要处理的消息, 则处理完毕之后, 通过 jmp short 00401091 跳到过程的出口, 平衡堆栈后返回到调用过程
OK , 对于本程序的分析到此为止,有源程序对照, 理解这些反汇编代码还是比较容易的。
<script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>