您的位置:首页 > 编程语言

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

2012-09-13 21:54 176 查看
这个是源代码:

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming 2nd Edition>
; by 罗云彬, http://asm.yeah.net ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; FirstWindow.asm
; 窗口程序的模板代码
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff FirstWindow.asm
; Link /subsystem:windows FirstWindow.obj
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include        windows.inc
include        gdi32.inc
includelib    gdi32.lib
include        user32.inc
includelib    user32.lib
include        kernel32.inc
includelib    kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance    dd        ?
hWinMain    dd        ?

.const
szClassName    db    'MyClass',0
szCaptionMain    db    'My first Window !',0
szText        db    'Win32 Assembly, Simple and powerful !',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 窗口过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain    proc    uses ebx edi esi hWnd,uMsg,wParam,lParam
local    @stPs:PAINTSTRUCT
local    @stRect:RECT
local    @hDc

mov    eax,uMsg
;********************************************************************
.if    eax ==    WM_PAINT
invoke    BeginPaint,hWnd,addr @stPs
mov    @hDc,eax

invoke    GetClientRect,hWnd,addr @stRect
invoke    DrawText,@hDc,addr szText,-1,\
addr @stRect,\
DT_SINGLELINE or DT_CENTER or DT_VCENTER

invoke    EndPaint,hWnd,addr @stPs
;********************************************************************
.elseif    eax ==    WM_CLOSE
invoke    DestroyWindow,hWinMain
invoke    PostQuitMessage,NULL
;********************************************************************
.else
invoke    DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
;********************************************************************
xor    eax,eax
ret

_ProcWinMain    endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain    proc
local    @stWndClass:WNDCLASSEX
local    @stMsg:MSG

invoke    GetModuleHandle,NULL
mov    hInstance,eax
invoke    RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
;********************************************************************
; 注册窗口类
;********************************************************************
invoke    LoadCursor,0,IDC_ARROW
mov    @stWndClass.hCursor,eax
push    hInstance
pop    @stWndClass.hInstance
mov    @stWndClass.cbSize,sizeof WNDCLASSEX
mov    @stWndClass.style,CS_HREDRAW or CS_VREDRAW
mov    @stWndClass.lpfnWndProc,offset _ProcWinMain
mov    @stWndClass.hbrBackground,COLOR_WINDOW + 1
mov    @stWndClass.lpszClassName,offset szClassName
invoke    RegisterClassEx,addr @stWndClass
;********************************************************************
; 建立并显示窗口
;********************************************************************
invoke    CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,\
WS_OVERLAPPEDWINDOW,\
100,100,600,400,\
NULL,NULL,hInstance,NULL
mov    hWinMain,eax
invoke    ShowWindow,hWinMain,SW_SHOWNORMAL
invoke    UpdateWindow,hWinMain
;********************************************************************
; 消息循环
;********************************************************************
.while    TRUE
invoke    GetMessage,addr @stMsg,NULL,0,0
.break    .if eax    == 0
invoke    TranslateMessage,addr @stMsg
invoke    DispatchMessage,addr @stMsg
.endw
ret

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


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

error A2008: syntax error : invoke


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

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

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


对应的反汇编代码:

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


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

_WinMain    proc
local    @stWndClass:WNDCLASSEX
local    @stMsg:MSG

invoke    GetModuleHandle,NULL
mov    hInstance,eax
invoke    RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
;********************************************************************
; 注册窗口类
;********************************************************************
invoke    LoadCursor,0,IDC_ARROW
mov    @stWndClass.hCursor,eax
push    hInstance
pop    @stWndClass.hInstance
mov    @stWndClass.cbSize,sizeof WNDCLASSEX
mov    @stWndClass.style,CS_HREDRAW or CS_VREDRAW
mov    @stWndClass.lpfnWndProc,offset _ProcWinMain
mov    @stWndClass.hbrBackground,COLOR_WINDOW + 1
mov    @stWndClass.lpszClassName,offset szClassName
invoke    RegisterClassEx,addr @stWndClass
;********************************************************************
; 建立并显示窗口
;********************************************************************
invoke    CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,\
WS_OVERLAPPEDWINDOW,\
100,100,600,400,\
NULL,NULL,hInstance,NULL
mov    hWinMain,eax
invoke    ShowWindow,hWinMain,SW_SHOWNORMAL
invoke    UpdateWindow,hWinMain
;********************************************************************
; 消息循环
;********************************************************************
.while    TRUE
invoke    GetMessage,addr @stMsg,NULL,0,0
.break    .if eax    == 0
invoke    TranslateMessage,addr @stMsg
invoke    DispatchMessage,addr @stMsg
.endw
ret

_WinMain    endp


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

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


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

mov    @stWndClass.lpfnWndProc,offset _ProcWinMain


对应的反汇编代码为

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


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

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


再来看看对应的源代码:

_ProcWinMain    proc    uses ebx edi esi hWnd,uMsg,wParam,lParam
local    @stPs:PAINTSTRUCT
local    @stRect:RECT
local    @hDc

mov    eax,uMsg
;********************************************************************
.if    eax ==    WM_PAINT
invoke    BeginPaint,hWnd,addr @stPs
mov    @hDc,eax

invoke    GetClientRect,hWnd,addr @stRect
invoke    DrawText,@hDc,addr szText,-1,\
addr @stRect,\
DT_SINGLELINE or DT_CENTER or DT_VCENTER

invoke    EndPaint,hWnd,addr @stPs
;********************************************************************
.elseif    eax ==    WM_CLOSE
invoke    DestroyWindow,hWinMain
invoke    PostQuitMessage,NULL
;********************************************************************
.else
invoke    DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
;********************************************************************
xor    eax,eax
ret

_ProcWinMain    endp


对应起来差距不是很大,这样看代码会觉得清晰很多,如果我们写的代码和反汇编的代码基本一样,就说明技术过关了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐