zoukankan      html  css  js  c++  java
  • 窗口程序及其反汇编

    首先先来看源程序:

      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作默认处理。

  • 相关阅读:
    开不了的窗_____window.open
    IIS项目发布完整流程
    理解MVC模式
    ASP.NET MVC 基础(01)
    C#之线程和并发
    vue时间格式化
    windows 2013 datacenter 安装sql server2008 r2兼容性
    SQL Server DBA十大必备工具使生活轻松
    ORACLE主要的系统表和系统视图
    Oracle中spool命令实现的两种方法比较
  • 原文地址:https://www.cnblogs.com/tk091/p/2682388.html
Copyright © 2011-2022 走看看