[32位汇编系列]002 - 创建标准的windows窗口(3)

接着上面一篇文章 , 下面是反汇编代码的对照讲解:

现在我们来看一看反汇编的代码:

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>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值