窗口程序及其反汇编

首先先来看源程序:

  1 .386
  2 .model flat,stdcall
  3 option casemap:none
  4 
  5 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  6 ;包含的文件
  7 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  8 
  9 include windows.inc
 10 include user32.inc
 11 include kernel32.inc
 12 
 13 includelib user32.lib
 14 includelib kernel32.lib
 15 
 16 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 17 ;
 18 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 19 WinMain proto :DWORD,:DWORD,:DWORD,:DWORD 
 20 
 21 .DATA                     ; initialized data 
 22 ClassName db "SimpleWinClass",0        ; the name of our window class 
 23 AppName db "Our First Window",0        ; the name of our window 
 24 
 25 .DATA?                ; Uninitialized data 
 26 hInstance HINSTANCE ?        ; Instance handle of our program 
 27 CommandLine LPSTR ? 
 28 .CODE                ; Here begins our code 
 29 start: 
 30 invoke GetModuleHandle, NULL            ; get the instance handle of our program. 
 31                                                                        ; Under Win32, hmodule==hinstance mov hInstance,eax 
 32 mov hInstance,eax 
 33 invoke GetCommandLine                        ; get the command line. You don't have to call this function IF 
 34                                                                        ; your program doesn't process the command line. 
 35 mov CommandLine,eax 
 36 invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT        ; call the main function 
 37 invoke ExitProcess, eax  
 38 
 39 
 40 
 41 
 42 WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
 43     
 44     LOCAL wc:WNDCLASSEX
 45     LOCAL msg:MSG
 46     LOCAL hwnd:HWND
 47     
 48     mov   wc.cbSize,SIZEOF WNDCLASSEX                   ; fill values in members of wc 
 49     mov   wc.style, CS_HREDRAW or CS_VREDRAW 
 50     mov   wc.lpfnWndProc, OFFSET WndProc 
 51     mov   wc.cbClsExtra,NULL 
 52     mov   wc.cbWndExtra,NULL 
 53     push  hInstance 
 54     pop   wc.hInstance 
 55     mov   wc.hbrBackground,COLOR_WINDOW+1 
 56     mov   wc.lpszMenuName,NULL 
 57     mov   wc.lpszClassName,OFFSET ClassName 
 58     invoke LoadIcon,NULL,IDI_APPLICATION 
 59     mov   wc.hIcon,eax 
 60     mov   wc.hIconSm,eax 
 61     invoke LoadCursor,NULL,IDC_ARROW 
 62     mov   wc.hCursor,eax 
 63     invoke RegisterClassEx, addr wc                       ; register our window class 
 64     invoke CreateWindowEx,NULL,\ 
 65                 ADDR ClassName,\ 
 66                 ADDR AppName,\ 
 67                 WS_OVERLAPPEDWINDOW,\ 
 68                 CW_USEDEFAULT,\ 
 69                 CW_USEDEFAULT,\ 
 70                 CW_USEDEFAULT,\ 
 71                 CW_USEDEFAULT,\ 
 72                 NULL,\ 
 73                 NULL,\ 
 74                 hInst,\ 
 75                 NULL 
 76     mov   hwnd,eax 
 77     invoke ShowWindow, hwnd,CmdShow               ; display our window on desktop 
 78     invoke UpdateWindow, hwnd                                 ; refresh the client area 
 79 
 80     .WHILE TRUE                                                         ; Enter message loop 
 81                 invoke GetMessage, ADDR msg,NULL,0,0 
 82                 .BREAK .IF (!eax) 
 83                 invoke TranslateMessage, ADDR msg 
 84                 invoke DispatchMessage, ADDR msg 
 85    .ENDW 
 86     mov     eax,msg.wParam                                            ; return exit code in eax 
 87     ret 
 88 WinMain endp 
 89 
 90 WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM 
 91     .IF uMsg==WM_DESTROY                           ; if the user closes our window 
 92         invoke PostQuitMessage,NULL             ; quit our application 
 93     .ELSE 
 94         invoke DefWindowProc,hWnd,uMsg,wParam,lParam     ; Default message processing 
 95         ret 
 96     .ENDIF 
 97     xor eax,eax 
 98     ret 
 99 WndProc endp 
100 
101 end start 

然后是反汇编程序,我自己添加了些注释

 1 00401000 >/$  6A 00         push    0                                ; /pModule = NULL
 2 00401002  |.  E8 8D010000   call    <jmp.&kernel32.GetModuleHandleA> ; \GetModuleHandleA
 3 00401007  |.  A3 20304000   mov     dword ptr [403020], eax          ;  mov hInstance,eax
 4 0040100C  |.  E8 7D010000   call    <jmp.&kernel32.GetCommandLineA>  ; [GetCommandLineA
 5 00401011  |.  A3 24304000   mov     dword ptr [403024], eax          ;  mov CommandLine,eax
 6 00401016  |.  6A 0A         push    0A                               ;  SW_SHOWDEFAULT
 7 00401018  |.  FF35 24304000 push    dword ptr [403024]               ;  CommandLine
 8 0040101E  |.  6A 00         push    0                                ;  NULL
 9 00401020  |.  FF35 20304000 push    dword ptr [403020]               ;  hInstance
10 00401026  |.  E8 06000000   call    00401031                         ;  WinMain
11 0040102B  |.  50            push    eax                              ; /ExitCode
12 0040102C  \.  E8 57010000   call    <jmp.&kernel32.ExitProcess>      ; \ExitProcess

只要和源程序对比,就很清晰了

1 start: 
2 invoke GetModuleHandle, NULL            ; get the instance handle of our program. 
3                                                                        ; Under Win32, hmodule==hinstance mov hInstance,eax 
4 mov hInstance,eax 
5 invoke GetCommandLine                        ; get the command line. You don't have to call this function IF 
6                                                                        ; your program doesn't process the command line. 
7 mov CommandLine,eax 
8 invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT        ; call the main function 
9 invoke ExitProcess, eax  

首先是以0为参数,获取模块的句柄,句柄值放在eax中

然后将eax放入一个变量中,这里变量名为hInstance

然后用GetCommandLine 获得程序的路径,并通过mov CommandLine,eax 保存到变量CommandLine中。

调用主函数WinMain

退出程序。

下面是WinMain:

 1 00401031  /$  55            push    ebp
 2 00401032  |.  8BEC          mov     ebp, esp
 3 00401034  |.  83C4 B0       add     esp, -50
 4 00401037  |.  C745 D0 30000>mov     dword ptr [ebp-30], 30           ;  mov   wc.cbSize,SIZEOF WNDCLASSEX
 5 0040103E  |.  C745 D4 03000>mov     dword ptr [ebp-2C], 3            ;  mov   wc.style, CS_HREDRAW or CS_VREDRAW
 6 00401045  |.  C745 D8 19114>mov     dword ptr [ebp-28], 00401119     ;  mov   wc.lpfnWndProc, OFFSET WndProc
 7 0040104C  |.  C745 DC 00000>mov     dword ptr [ebp-24], 0            ;  mov   wc.cbClsExtra,NULL
 8 00401053  |.  C745 E0 00000>mov     dword ptr [ebp-20], 0            ;  mov   wc.cbWndExtra,NULL
 9 0040105A  |.  FF35 20304000 push    dword ptr [403020]               ;  push hInstance
10 00401060  |.  8F45 E4       pop     dword ptr [ebp-1C]               ;  pop   wc.hInstance
11 00401063  |.  C745 F0 06000>mov     dword ptr [ebp-10], 6            ;  mov   wc.hbrBackground,COLOR_WINDOW+1
12 0040106A  |.  C745 F4 00000>mov     dword ptr [ebp-C], 0             ;  mov   wc.lpszMenuName,NULL
13 00401071  |.  C745 F8 00304>mov     dword ptr [ebp-8], 00403000      ;  mov   wc.lpszClassName,OFFSET ClassName
14 00401078  |.  68 007F0000   push    7F00                             ; /RsrcName = IDI_APPLICATION
15 0040107D  |.  6A 00         push    0                                ; |hInst = NULL
16 0040107F  |.  E8 E0000000   call    <jmp.&user32.LoadIconA>          ; \LoadIconA
17 00401084  |.  8945 E8       mov     dword ptr [ebp-18], eax
18 00401087  |.  8945 FC       mov     dword ptr [ebp-4], eax
19 0040108A  |.  68 007F0000   push    7F00                             ; /RsrcName = IDC_ARROW
20 0040108F  |.  6A 00         push    0                                ; |hInst = NULL
21 00401091  |.  E8 C8000000   call    <jmp.&user32.LoadCursorA>        ; \LoadCursorA
22 00401096  |.  8945 EC       mov     dword ptr [ebp-14], eax
23 00401099  |.  8D45 D0       lea     eax, dword ptr [ebp-30]          ;  wc结构体的起始位置
24 0040109C  |.  50            push    eax                              ; /pWndClassEx
25 0040109D  |.  E8 CE000000   call    <jmp.&user32.RegisterClassExA>   ; \RegisterClassExA
26 004010A2  |.  6A 00         push    0                                ; /lParam = NULL
27 004010A4  |.  FF75 08       push    dword ptr [ebp+8]                ; |hInstance
28 004010A7  |.  6A 00         push    0                                ; |hMenu = NULL
29 004010A9  |.  6A 00         push    0                                ; |hParent = NULL
30 004010AB  |.  68 00000080   push    80000000                         ; |Height = 80000000 (-2147483648.)
31 004010B0  |.  68 00000080   push    80000000                         ; |Width = 80000000 (-2147483648.)
32 004010B5  |.  68 00000080   push    80000000                         ; |Y = 80000000 (-2147483648.)
33 004010BA  |.  68 00000080   push    80000000                         ; |X = 80000000 (-2147483648.)
34 004010BF  |.  68 0000CF00   push    0CF0000                          ; |Style = WS_OVERLAPPED|WS_MINIMIZEBOX|WS_MAXIMIZEBOX
|WS_SYSMENU|WS_THICKFRAME|WS_CAPTION
35 004010C4 |. 68 0F304000 push 0040300F ; |WindowName = "Our First Window" 36 004010C9 |. 68 00304000 push 00403000 ; |Class = "SimpleWinClass" 37 004010CE |. 6A 00 push 0 ; |ExtStyle = 0 38 004010D0 |. E8 71000000 call <jmp.&user32.CreateWindowExA> ; \CreateWindowExA 39 004010D5 |. 8945 B0 mov dword ptr [ebp-50], eax ; eax保存创建成功后的窗口句柄 40 004010D8 |. FF75 14 push dword ptr [ebp+14] ; /ShowState 41 004010DB |. FF75 B0 push dword ptr [ebp-50] ; |hWnd 42 004010DE |. E8 93000000 call <jmp.&user32.ShowWindow> ; \ShowWindow 43 004010E3 |. FF75 B0 push dword ptr [ebp-50] ; /hWnd 44 004010E6 |. E8 97000000 call <jmp.&user32.UpdateWindow> ; \UpdateWindow 45 004010EB |> 6A 00 /push 0 ; /MsgFilterMax = 0 46 004010ED |. 6A 00 |push 0 ; |MsgFilterMin = 0 47 004010EF |. 6A 00 |push 0 ; |hWnd = NULL 48 004010F1 |. 8D45 B4 |lea eax, dword ptr [ebp-4C] ; | 49 004010F4 |. 50 |push eax ; |pMsg 50 004010F5 |. E8 5E000000 |call <jmp.&user32.GetMessageA> ; \GetMessageA 51 004010FA |. 0BC0 |or eax, eax 52 004010FC |. 74 14 |je short 00401112 53 004010FE |. 8D45 B4 |lea eax, dword ptr [ebp-4C] 54 00401101 |. 50 |push eax ; /pMsg 55 00401102 |. E8 75000000 |call <jmp.&user32.TranslateMessage> ; \TranslateMessage 56 00401107 |. 8D45 B4 |lea eax, dword ptr [ebp-4C] 57 0040110A |. 50 |push eax ; /pMsg 58 0040110B |. E8 42000000 |call <jmp.&user32.DispatchMessageA> ; \DispatchMessageA 59 00401110 |.^ EB D9 \jmp short 004010EB 60 00401112 |> 8B45 BC mov eax, dword ptr [ebp-44] 61 00401115 |. C9 leave 62 00401116 \. C2 1000 retn 10

感觉对消息机制还不是很了解。

在窗口注册函数RegisterClassEx中涉及到WNDCLASSEX结构,在WNDCLASSEX结构中涉及到消息处理函数WndProc

这样,当产生消息后,GetMessage获得消息,TranslateMessage转换键盘消息,DispatchMessage分派消息。

 

在消息处理函数中WndProc可以自己定义处理消息的方式,如果不是自己定义的处理,就交给DefWindowProc作默认处理。

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