另一个类型的窗口汇编程序及反汇编程序

这个是源代码:

  1 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  2 ; Sample code for < Win32ASM Programming 2nd Edition>
  3 ; by 罗云彬, http://asm.yeah.net
  4 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  5 ; FirstWindow.asm
  6 ; 窗口程序的模板代码
  7 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  8 ; 使用 nmake 或下列命令进行编译和链接:
  9 ; ml /c /coff FirstWindow.asm
 10 ; Link /subsystem:windows FirstWindow.obj
 11 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 12         .386
 13         .model flat,stdcall
 14         option casemap:none
 15 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 16 ; Include 文件定义
 17 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 18 include        windows.inc
 19 include        gdi32.inc
 20 includelib    gdi32.lib
 21 include        user32.inc
 22 includelib    user32.lib
 23 include        kernel32.inc
 24 includelib    kernel32.lib
 25 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 26 ; 数据段
 27 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 28         .data?
 29 hInstance    dd        ?
 30 hWinMain    dd        ?
 31 
 32         .const
 33 szClassName    db    'MyClass',0
 34 szCaptionMain    db    'My first Window !',0
 35 szText        db    'Win32 Assembly, Simple and powerful !',0
 36 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 37 ; 代码段
 38 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 39         .code
 40 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 41 ; 窗口过程
 42 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 43 _ProcWinMain    proc    uses ebx edi esi hWnd,uMsg,wParam,lParam
 44         local    @stPs:PAINTSTRUCT
 45         local    @stRect:RECT
 46         local    @hDc
 47 
 48         mov    eax,uMsg
 49 ;********************************************************************
 50         .if    eax ==    WM_PAINT
 51             invoke    BeginPaint,hWnd,addr @stPs
 52             mov    @hDc,eax
 53 
 54             invoke    GetClientRect,hWnd,addr @stRect
 55             invoke    DrawText,@hDc,addr szText,-1,\
 56                 addr @stRect,\
 57                 DT_SINGLELINE or DT_CENTER or DT_VCENTER
 58 
 59             invoke    EndPaint,hWnd,addr @stPs
 60 ;********************************************************************
 61         .elseif    eax ==    WM_CLOSE
 62             invoke    DestroyWindow,hWinMain
 63             invoke    PostQuitMessage,NULL
 64 ;********************************************************************
 65         .else
 66             invoke    DefWindowProc,hWnd,uMsg,wParam,lParam
 67             ret
 68         .endif
 69 ;********************************************************************
 70         xor    eax,eax
 71         ret
 72 
 73 _ProcWinMain    endp
 74 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 75 _WinMain    proc
 76         local    @stWndClass:WNDCLASSEX
 77         local    @stMsg:MSG
 78 
 79         invoke    GetModuleHandle,NULL
 80         mov    hInstance,eax
 81         invoke    RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
 82 ;********************************************************************
 83 ; 注册窗口类
 84 ;********************************************************************
 85         invoke    LoadCursor,0,IDC_ARROW
 86         mov    @stWndClass.hCursor,eax
 87         push    hInstance
 88         pop    @stWndClass.hInstance
 89         mov    @stWndClass.cbSize,sizeof WNDCLASSEX
 90         mov    @stWndClass.style,CS_HREDRAW or CS_VREDRAW
 91         mov    @stWndClass.lpfnWndProc,offset _ProcWinMain
 92         mov    @stWndClass.hbrBackground,COLOR_WINDOW + 1
 93         mov    @stWndClass.lpszClassName,offset szClassName
 94         invoke    RegisterClassEx,addr @stWndClass
 95 ;********************************************************************
 96 ; 建立并显示窗口
 97 ;********************************************************************
 98         invoke    CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,\
 99             WS_OVERLAPPEDWINDOW,\
100             100,100,600,400,\
101             NULL,NULL,hInstance,NULL
102         mov    hWinMain,eax
103         invoke    ShowWindow,hWinMain,SW_SHOWNORMAL
104         invoke    UpdateWindow,hWinMain
105 ;********************************************************************
106 ; 消息循环
107 ;********************************************************************
108         .while    TRUE
109             invoke    GetMessage,addr @stMsg,NULL,0,0
110             .break    .if eax    == 0
111             invoke    TranslateMessage,addr @stMsg
112             invoke    DispatchMessage,addr @stMsg
113         .endw
114         ret
115 
116 _WinMain    endp
117 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
118 start:
119         call    _WinMain
120         invoke    ExitProcess,NULL
121 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
122         end    start

我在66行的位置处对invoke DefWindowProc,hWnd,uMsg,wParam,lParam没有进行换行处理,一直报错。(我先自己照着书写代码)

error A2008: syntax error : invoke

===============================================

===============================================

start:
        call    _WinMain
        invoke    ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        end    start

对应的反汇编代码:

1 00401163 >/$  E8 21FFFFFF   call    00401089                         ;  call    _WinMain
2 00401168  |.  6A 00         push    0                                ; /ExitCode = 0
3 0040116A  \.  E8 5B000000   call    <jmp.&kernel32.ExitProcess>      ; \ExitProcess

现在进入_WinMain,汇编代码为:

 1 _WinMain    proc
 2         local    @stWndClass:WNDCLASSEX
 3         local    @stMsg:MSG
 4 
 5         invoke    GetModuleHandle,NULL
 6         mov    hInstance,eax
 7         invoke    RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
 8 ;********************************************************************
 9 ; 注册窗口类
10 ;********************************************************************
11         invoke    LoadCursor,0,IDC_ARROW
12         mov    @stWndClass.hCursor,eax
13         push    hInstance
14         pop    @stWndClass.hInstance
15         mov    @stWndClass.cbSize,sizeof WNDCLASSEX
16         mov    @stWndClass.style,CS_HREDRAW or CS_VREDRAW
17         mov    @stWndClass.lpfnWndProc,offset _ProcWinMain
18         mov    @stWndClass.hbrBackground,COLOR_WINDOW + 1
19         mov    @stWndClass.lpszClassName,offset szClassName
20         invoke    RegisterClassEx,addr @stWndClass
21 ;********************************************************************
22 ; 建立并显示窗口
23 ;********************************************************************
24         invoke    CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,\
25             WS_OVERLAPPEDWINDOW,\
26             100,100,600,400,\
27             NULL,NULL,hInstance,NULL
28         mov    hWinMain,eax
29         invoke    ShowWindow,hWinMain,SW_SHOWNORMAL
30         invoke    UpdateWindow,hWinMain
31 ;********************************************************************
32 ; 消息循环
33 ;********************************************************************
34         .while    TRUE
35             invoke    GetMessage,addr @stMsg,NULL,0,0
36             .break    .if eax    == 0
37             invoke    TranslateMessage,addr @stMsg
38             invoke    DispatchMessage,addr @stMsg
39         .endw
40         ret
41 
42 _WinMain    endp

首先是填充WNDCLASSEX结构,然后是注册窗口类,显示窗口,更新窗口。

 1 00401089  /$  55            push    ebp
 2 0040108A  |.  8BEC          mov     ebp, esp
 3 0040108C  |.  83C4 B4       add     esp, -4C
 4 0040108F  |.  6A 00         push    0                                ; /pModule = NULL
 5 00401091  |.  E8 3A010000   call    <jmp.&kernel32.GetModuleHandleA> ; \GetModuleHandleA
 6 00401096  |.  A3 00304000   mov     dword ptr [403000], eax
 7 0040109B  |.  6A 30         push    30                               ; /Length = 30 (48.)
 8 0040109D  |.  8D45 D0       lea     eax, dword ptr [ebp-30]          ; |
 9 004010A0  |.  50            push    eax                              ; |Destination
10 004010A1  |.  E8 30010000   call    <jmp.&kernel32.RtlZeroMemory>    ; \RtlZeroMemory
11 004010A6  |.  68 007F0000   push    7F00                             ; /RsrcName = IDC_ARROW
12 004010AB  |.  6A 00         push    0                                ; |hInst = NULL
13 004010AD  |.  E8 F4000000   call    <jmp.&user32.LoadCursorA>        ; \LoadCursorA
14 004010B2  |.  8945 EC       mov     dword ptr [ebp-14], eax
15 004010B5  |.  FF35 00304000 push    dword ptr [403000]               ;  OtherDia.00400000
16 004010BB  |.  8F45 E4       pop     dword ptr [ebp-1C]
17 004010BE  |.  C745 D0 30000>mov     dword ptr [ebp-30], 30
18 004010C5  |.  C745 D4 03000>mov     dword ptr [ebp-2C], 3
19 004010CC  |.  C745 D8 00104>mov     dword ptr [ebp-28], 00401000
20 004010D3  |.  C745 F0 06000>mov     dword ptr [ebp-10], 6
21 004010DA  |.  C745 F8 50204>mov     dword ptr [ebp-8], 00402050      ;  ASCII "MyClass"
22 004010E1  |.  8D45 D0       lea     eax, dword ptr [ebp-30]
23 004010E4  |.  50            push    eax                              ; /pWndClassEx
24 004010E5  |.  E8 C8000000   call    <jmp.&user32.RegisterClassExA>   ; \RegisterClassExA
25 004010EA  |.  6A 00         push    0                                ; /lParam = NULL
26 004010EC  |.  FF35 00304000 push    dword ptr [403000]               ; |hInst = 00400000
27 004010F2  |.  6A 00         push    0                                ; |hMenu = NULL
28 004010F4  |.  6A 00         push    0                                ; |hParent = NULL
29 004010F6  |.  68 90010000   push    190                              ; |Height = 190 (400.)
30 004010FB  |.  68 58020000   push    258                              ; |Width = 258 (600.)
31 00401100  |.  6A 64         push    64                               ; |Y = 64 (100.)
32 00401102  |.  6A 64         push    64                               ; |X = 64 (100.)
33 00401104  |.  68 0000CF00   push    0CF0000                          ; |Style = WS_OVERLAPPED|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|
                                          ; WS_SYSMENU|WS_THICKFRAME|WS_CAPTION
34 00401109 |. 68 58204000 push 00402058 ; |WindowName = "My first Window !" 35 0040110E |. 68 50204000 push 00402050 ; |Class = "MyClass" 36 00401113 |. 68 00020000 push 200 ; |ExtStyle = WS_EX_CLIENTEDGE 37 00401118 |. E8 59000000 call <jmp.&user32.CreateWindowExA> ; \CreateWindowExA 38 0040111D |. A3 04304000 mov dword ptr [403004], eax 39 00401122 |. 6A 01 push 1 ; /ShowState = SW_SHOWNORMAL 40 00401124 |. FF35 04304000 push dword ptr [403004] ; |hWnd = NULL 41 0040112A |. E8 89000000 call <jmp.&user32.ShowWindow> ; \ShowWindow 42 0040112F |. FF35 04304000 push dword ptr [403004] ; /hWnd = NULL 43 00401135 |. E8 8A000000 call <jmp.&user32.UpdateWindow> ; \UpdateWindow 44 0040113A |> 6A 00 /push 0 ; /MsgFilterMax = 0 45 0040113C |. 6A 00 |push 0 ; |MsgFilterMin = 0 46 0040113E |. 6A 00 |push 0 ; |hWnd = NULL 47 00401140 |. 8D45 B4 |lea eax, dword ptr [ebp-4C] ; | 48 00401143 |. 50 |push eax ; |pMsg 49 00401144 |. E8 57000000 |call <jmp.&user32.GetMessageA> ; \GetMessageA 50 00401149 |. 0BC0 |or eax, eax 51 0040114B |. 74 14 |je short 00401161 52 0040114D |. 8D45 B4 |lea eax, dword ptr [ebp-4C] 53 00401150 |. 50 |push eax ; /pMsg 54 00401151 |. E8 68000000 |call <jmp.&user32.TranslateMessage> ; \TranslateMessage 55 00401156 |. 8D45 B4 |lea eax, dword ptr [ebp-4C] 56 00401159 |. 50 |push eax ; /pMsg 57 0040115A |. E8 29000000 |call <jmp.&user32.DispatchMessageA> ; \DispatchMessageA 58 0040115F |.^ EB D9 \jmp short 0040113A 59 00401161 |> C9 leave 60 00401162 \. C3 retn

我们看看这个窗口的窗口处理函数在哪个位置。

mov    @stWndClass.lpfnWndProc,offset _ProcWinMain

对应的反汇编代码为

004010CC  |.  C745 D8 00104>mov     dword ptr [ebp-28], 00401000     ;  mov @stWndClass.lpfnWndProc,offset _ProcWinMain

我们找到对应的地址并跳转过去看看

 1 00401000  /.  55            push    ebp
 2 00401001  |.  8BEC          mov     ebp, esp
 3 00401003  |.  83C4 AC       add     esp, -54
 4 00401006  |.  53            push    ebx
 5 00401007  |.  57            push    edi
 6 00401008  |.  56            push    esi
 7 00401009  |.  8B45 0C       mov     eax, dword ptr [ebp+C]
 8 0040100C  |.  83F8 0F       cmp     eax, 0F
 9 0040100F  |.  75 3E         jnz     short 0040104F
10 00401011  |.  8D45 C0       lea     eax, dword ptr [ebp-40]
11 00401014  |.  50            push    eax                              ; /pPaintstruct
12 00401015  |.  FF75 08       push    dword ptr [ebp+8]                ; |hWnd
13 00401018  |.  E8 53010000   call    <jmp.&user32.BeginPaint>         ; \BeginPaint
14 0040101D  |.  8945 AC       mov     dword ptr [ebp-54], eax
15 00401020  |.  8D45 B0       lea     eax, dword ptr [ebp-50]
16 00401023  |.  50            push    eax                              ; /pRect
17 00401024  |.  FF75 08       push    dword ptr [ebp+8]                ; |hWnd
18 00401027  |.  E8 6E010000   call    <jmp.&user32.GetClientRect>      ; \GetClientRect
19 0040102C  |.  6A 25         push    25                               ; /Flags = DT_CENTER|DT_VCENTER|DT_SINGLELINE
20 0040102E  |.  8D45 B0       lea     eax, dword ptr [ebp-50]          ; |
21 00401031  |.  50            push    eax                              ; |pRect
22 00401032  |.  6A FF         push    -1                               ; |Count = FFFFFFFF (-1.)
23 00401034  |.  68 6A204000   push    0040206A                         ; |Text = "Win32 Assembly, Simple and powerful !"
24 00401039  |.  FF75 AC       push    dword ptr [ebp-54]               ; |hDC
25 0040103C  |.  E8 4D010000   call    <jmp.&user32.DrawTextA>          ; \DrawTextA
26 00401041  |.  8D45 C0       lea     eax, dword ptr [ebp-40]
27 00401044  |.  50            push    eax                              ; /pPaintstruct
28 00401045  |.  FF75 08       push    dword ptr [ebp+8]                ; |hWnd
29 00401048  |.  E8 47010000   call    <jmp.&user32.EndPaint>           ; \EndPaint
30 0040104D  |.  EB 31         jmp     short 00401080
31 0040104F  |>  83F8 10       cmp     eax, 10
32 00401052  |.  75 14         jnz     short 00401068
33 00401054  |.  FF35 04304000 push    dword ptr [403004]               ; /hWnd = 001107D4 ('My first Window !',class='MyClass')
34 0040105A  |.  E8 23010000   call    <jmp.&user32.DestroyWindow>      ; \DestroyWindow
35 0040105F  |.  6A 00         push    0                                ; /ExitCode = 0
36 00401061  |.  E8 46010000   call    <jmp.&user32.PostQuitMessage>    ; \PostQuitMessage
37 00401066  |.  EB 18         jmp     short 00401080
38 00401068  |>  FF75 14       push    dword ptr [ebp+14]               ; /lParam
39 0040106B  |.  FF75 10       push    dword ptr [ebp+10]               ; |wParam
40 0040106E  |.  FF75 0C       push    dword ptr [ebp+C]                ; |Message
41 00401071  |.  FF75 08       push    dword ptr [ebp+8]                ; |hWnd
42 00401074  |.  E8 03010000   call    <jmp.&user32.DefWindowProcA>     ; \DefWindowProcA
43 00401079  |.  5E            pop     esi
44 0040107A  |.  5F            pop     edi
45 0040107B  |.  5B            pop     ebx
46 0040107C  |.  C9            leave
47 0040107D  |.  C2 1000       retn    10
48 00401080  |>  33C0          xor     eax, eax
49 00401082  |.  5E            pop     esi
50 00401083  |.  5F            pop     edi
51 00401084  |.  5B            pop     ebx
52 00401085  |.  C9            leave
53 00401086  \.  C2 1000       retn    10

再来看看对应的源代码:

 1 _ProcWinMain    proc    uses ebx edi esi hWnd,uMsg,wParam,lParam
 2         local    @stPs:PAINTSTRUCT
 3         local    @stRect:RECT
 4         local    @hDc
 5 
 6         mov    eax,uMsg
 7 ;********************************************************************
 8         .if    eax ==    WM_PAINT
 9             invoke    BeginPaint,hWnd,addr @stPs
10             mov    @hDc,eax
11 
12             invoke    GetClientRect,hWnd,addr @stRect
13             invoke    DrawText,@hDc,addr szText,-1,\
14                 addr @stRect,\
15                 DT_SINGLELINE or DT_CENTER or DT_VCENTER
16 
17             invoke    EndPaint,hWnd,addr @stPs
18 ;********************************************************************
19         .elseif    eax ==    WM_CLOSE
20             invoke    DestroyWindow,hWinMain
21             invoke    PostQuitMessage,NULL
22 ;********************************************************************
23         .else
24             invoke    DefWindowProc,hWnd,uMsg,wParam,lParam
25             ret
26         .endif
27 ;********************************************************************
28         xor    eax,eax
29         ret
30 
31 _ProcWinMain    endp

对应起来差距不是很大,这样看代码会觉得清晰很多,如果我们写的代码和反汇编的代码基本一样,就说明技术过关了。

原文地址:https://www.cnblogs.com/tk091/p/2684038.html