窗口程序及其反汇编
2012-09-12 21:05
309 查看
首先先来看源程序:
然后是反汇编程序,我自己添加了些注释
只要和源程序对比,就很清晰了
首先是以0为参数,获取模块的句柄,句柄值放在eax中
然后将eax放入一个变量中,这里变量名为hInstance。
然后用GetCommandLine 获得程序的路径,并通过mov CommandLine,eax 保存到变量CommandLine中。
调用主函数WinMain
退出程序。
下面是WinMain:
感觉对消息机制还不是很了解。
在窗口注册函数RegisterClassEx中涉及到WNDCLASSEX结构,在WNDCLASSEX结构中涉及到消息处理函数WndProc
这样,当产生消息后,GetMessage获得消息,TranslateMessage转换键盘消息,DispatchMessage分派消息。
在消息处理函数中WndProc可以自己定义处理消息的方式,如果不是自己定义的处理,就交给DefWindowProc作默认处理。
.386 .model flat,stdcall option casemap:none ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;包含的文件 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> include windows.inc include user32.inc include kernel32.inc includelib user32.lib includelib kernel32.lib ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> WinMain proto :DWORD,:DWORD,:DWORD,:DWORD .DATA ; initialized data ClassName db "SimpleWinClass",0 ; the name of our window class AppName db "Our First Window",0 ; the name of our window .DATA? ; Uninitialized data hInstance HINSTANCE ? ; Instance handle of our program CommandLine LPSTR ? .CODE ; Here begins our code start: invoke GetModuleHandle, NULL ; get the instance handle of our program. ; Under Win32, hmodule==hinstance mov hInstance,eax mov hInstance,eax invoke GetCommandLine ; get the command line. You don't have to call this function IF ; your program doesn't process the command line. mov CommandLine,eax invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT ; call the main function invoke ExitProcess, eax WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD LOCAL wc:WNDCLASSEX LOCAL msg:MSG LOCAL hwnd:HWND mov wc.cbSize,SIZEOF WNDCLASSEX ; fill values in members of wc mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInstance pop wc.hInstance mov wc.hbrBackground,COLOR_WINDOW+1 mov wc.lpszMenuName,NULL mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax invoke RegisterClassEx, addr wc ; register our window class invoke CreateWindowEx,NULL,\ ADDR ClassName,\ ADDR AppName,\ WS_OVERLAPPEDWINDOW,\ CW_USEDEFAULT,\ CW_USEDEFAULT,\ CW_USEDEFAULT,\ CW_USEDEFAULT,\ NULL,\ NULL,\ hInst,\ NULL mov hwnd,eax invoke ShowWindow, hwnd,CmdShow ; display our window on desktop invoke UpdateWindow, hwnd ; refresh the client area .WHILE TRUE ; Enter message loop invoke GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax) invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ; return exit code in eax ret WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg==WM_DESTROY ; if the user closes our window invoke PostQuitMessage,NULL ; quit our application .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ; Default message processing ret .ENDIF xor eax,eax ret WndProc endp end start
然后是反汇编程序,我自己添加了些注释
00401000 >/$ 6A 00 push 0 ; /pModule = NULL 00401002 |. E8 8D010000 call <jmp.&kernel32.GetModuleHandleA> ; \GetModuleHandleA 00401007 |. A3 20304000 mov dword ptr [403020], eax ; mov hInstance,eax 0040100C |. E8 7D010000 call <jmp.&kernel32.GetCommandLineA> ; [GetCommandLineA 00401011 |. A3 24304000 mov dword ptr [403024], eax ; mov CommandLine,eax 00401016 |. 6A 0A push 0A ; SW_SHOWDEFAULT 00401018 |. FF35 24304000 push dword ptr [403024] ; CommandLine 0040101E |. 6A 00 push 0 ; NULL 00401020 |. FF35 20304000 push dword ptr [403020] ; hInstance 00401026 |. E8 06000000 call 00401031 ; WinMain 0040102B |. 50 push eax ; /ExitCode 0040102C \. E8 57010000 call <jmp.&kernel32.ExitProcess> ; \ExitProcess
只要和源程序对比,就很清晰了
start: invoke GetModuleHandle, NULL ; get the instance handle of our program. ; Under Win32, hmodule==hinstance mov hInstance,eax mov hInstance,eax invoke GetCommandLine ; get the command line. You don't have to call this function IF ; your program doesn't process the command line. mov CommandLine,eax invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT ; call the main function invoke ExitProcess, eax
首先是以0为参数,获取模块的句柄,句柄值放在eax中
然后将eax放入一个变量中,这里变量名为hInstance。
然后用GetCommandLine 获得程序的路径,并通过mov CommandLine,eax 保存到变量CommandLine中。
调用主函数WinMain
退出程序。
下面是WinMain:
00401031 /$ 55 push ebp 00401032 |. 8BEC mov ebp, esp 00401034 |. 83C4 B0 add esp, -50 00401037 |. C745 D0 30000>mov dword ptr [ebp-30], 30 ; mov wc.cbSize,SIZEOF WNDCLASSEX 0040103E |. C745 D4 03000>mov dword ptr [ebp-2C], 3 ; mov wc.style, CS_HREDRAW or CS_VREDRAW 00401045 |. C745 D8 19114>mov dword ptr [ebp-28], 00401119 ; mov wc.lpfnWndProc, OFFSET WndProc 0040104C |. C745 DC 00000>mov dword ptr [ebp-24], 0 ; mov wc.cbClsExtra,NULL 00401053 |. C745 E0 00000>mov dword ptr [ebp-20], 0 ; mov wc.cbWndExtra,NULL 0040105A |. FF35 20304000 push dword ptr [403020] ; push hInstance 00401060 |. 8F45 E4 pop dword ptr [ebp-1C] ; pop wc.hInstance 00401063 |. C745 F0 06000>mov dword ptr [ebp-10], 6 ; mov wc.hbrBackground,COLOR_WINDOW+1 0040106A |. C745 F4 00000>mov dword ptr [ebp-C], 0 ; mov wc.lpszMenuName,NULL 00401071 |. C745 F8 00304>mov dword ptr [ebp-8], 00403000 ; mov wc.lpszClassName,OFFSET ClassName 00401078 |. 68 007F0000 push 7F00 ; /RsrcName = IDI_APPLICATION 0040107D |. 6A 00 push 0 ; |hInst = NULL 0040107F |. E8 E0000000 call <jmp.&user32.LoadIconA> ; \LoadIconA 00401084 |. 8945 E8 mov dword ptr [ebp-18], eax 00401087 |. 8945 FC mov dword ptr [ebp-4], eax 0040108A |. 68 007F0000 push 7F00 ; /RsrcName = IDC_ARROW 0040108F |. 6A 00 push 0 ; |hInst = NULL 00401091 |. E8 C8000000 call <jmp.&user32.LoadCursorA> ; \LoadCursorA 00401096 |. 8945 EC mov dword ptr [ebp-14], eax 00401099 |. 8D45 D0 lea eax, dword ptr [ebp-30] ; wc结构体的起始位置 0040109C |. 50 push eax ; /pWndClassEx 0040109D |. E8 CE000000 call <jmp.&user32.RegisterClassExA> ; \RegisterClassExA 004010A2 |. 6A 00 push 0 ; /lParam = NULL 004010A4 |. FF75 08 push dword ptr [ebp+8] ; |hInstance 004010A7 |. 6A 00 push 0 ; |hMenu = NULL 004010A9 |. 6A 00 push 0 ; |hParent = NULL 004010AB |. 68 00000080 push 80000000 ; |Height = 80000000 (-2147483648.) 004010B0 |. 68 00000080 push 80000000 ; |Width = 80000000 (-2147483648.) 004010B5 |. 68 00000080 push 80000000 ; |Y = 80000000 (-2147483648.) 004010BA |. 68 00000080 push 80000000 ; |X = 80000000 (-2147483648.) 004010BF |. 68 0000CF00 push 0CF0000 ; |Style = WS_OVERLAPPED|WS_MINIMIZEBOX|WS_MAXIMIZEBOX |WS_SYSMENU|WS_THICKFRAME|WS_CAPTION 004010C4 |. 68 0F304000 push 0040300F ; |WindowName = "Our First Window" 004010C9 |. 68 00304000 push 00403000 ; |Class = "SimpleWinClass" 004010CE |. 6A 00 push 0 ; |ExtStyle = 0 004010D0 |. E8 71000000 call <jmp.&user32.CreateWindowExA> ; \CreateWindowExA 004010D5 |. 8945 B0 mov dword ptr [ebp-50], eax ; eax保存创建成功后的窗口句柄 004010D8 |. FF75 14 push dword ptr [ebp+14] ; /ShowState 004010DB |. FF75 B0 push dword ptr [ebp-50] ; |hWnd 004010DE |. E8 93000000 call <jmp.&user32.ShowWindow> ; \ShowWindow 004010E3 |. FF75 B0 push dword ptr [ebp-50] ; /hWnd 004010E6 |. E8 97000000 call <jmp.&user32.UpdateWindow> ; \UpdateWindow 004010EB |> 6A 00 /push 0 ; /MsgFilterMax = 0 004010ED |. 6A 00 |push 0 ; |MsgFilterMin = 0 004010EF |. 6A 00 |push 0 ; |hWnd = NULL 004010F1 |. 8D45 B4 |lea eax, dword ptr [ebp-4C] ; | 004010F4 |. 50 |push eax ; |pMsg 004010F5 |. E8 5E000000 |call <jmp.&user32.GetMessageA> ; \GetMessageA 004010FA |. 0BC0 |or eax, eax 004010FC |. 74 14 |je short 00401112 004010FE |. 8D45 B4 |lea eax, dword ptr [ebp-4C] 00401101 |. 50 |push eax ; /pMsg 00401102 |. E8 75000000 |call <jmp.&user32.TranslateMessage> ; \TranslateMessage 00401107 |. 8D45 B4 |lea eax, dword ptr [ebp-4C] 0040110A |. 50 |push eax ; /pMsg 0040110B |. E8 42000000 |call <jmp.&user32.DispatchMessageA> ; \DispatchMessageA 00401110 |.^ EB D9 \jmp short 004010EB 00401112 |> 8B45 BC mov eax, dword ptr [ebp-44] 00401115 |. C9 leave 00401116 \. C2 1000 retn 10
感觉对消息机制还不是很了解。
在窗口注册函数RegisterClassEx中涉及到WNDCLASSEX结构,在WNDCLASSEX结构中涉及到消息处理函数WndProc
这样,当产生消息后,GetMessage获得消息,TranslateMessage转换键盘消息,DispatchMessage分派消息。
在消息处理函数中WndProc可以自己定义处理消息的方式,如果不是自己定义的处理,就交给DefWindowProc作默认处理。
相关文章推荐
- win32汇编第一个窗口程序
- 一个用delphi写的整合汇编与api的简单的窗口程序
- WIN32汇编-第一个窗口程序
- 32位汇编第二讲,编写窗口程序,加载资源,响应消息,以及调用C库函数
- WIN32汇编下的窗口程序
- Source Insight查看ARM汇编源程序 && Source Insight打开project窗口出错 && 高亮显示程序 && 标题栏显示全路径
- OllyDBG(OD)内存映射属主找不到当前程序名解决办法和跟随ClassProc 反汇编窗口空白的解决办法
- 利用纯汇编写一个WIN32的窗口程序
- 32位汇编第二讲,编写窗口程序,加载资源,响应消息,以及调用C库函数
- OD 内存映射 属主找不到当前程序名解决办法 和 跟随ClassProc 反汇编窗口空白解决办法
- 另一个类型的窗口汇编程序及反汇编程序
- Win32汇编窗口程序设计[03]--第一个窗口程序
- 一个完整win32汇编窗口程序的分析
- windows下32位汇编语言学习笔记 第四章 第一个窗口程序 (windows的消息机制)
- 汇编如何建立窗口程序
- Source Insight查看ARM汇编源程序 && Source Insight打开project窗口出错 && 高亮显示程序 && 标题栏显示全路径 .
- windows下32位汇编语言学习笔记 第四章 第一个窗口程序 1 (消息的使用和入口代码)
- 一个简单程序的汇编及其反汇编
- Win32汇编——第一个窗口程序
- 基于MDK编程STM32程序无法使用,硬件仿真在汇编窗口看到停留在“0x0800XXXX BEAB BKPT 0xAB //进入调试模式”