.data?
hInstance dd ?
hWinMain dd ?
.const
szClassName db MyClass,0
szCaptionMain db My first Window !,0
szText db Win32 Assembly, Simple and powerful !,0
《〈〈〈〈〈〈程序头部
程序的入口 反编译程序: Program Entry Point
start: call 00401089
call _Main push 00000000
invoke ExitProcess,NULL Call 004011CA
end start int 03
主程序开始 程序开始的反编译程序:
_Main proc 00401089 push ebp :ebp指针入栈
local @stWndClass:WNDCLASSEX mov ebp, esp :将栈指针移入
local @stMsg:MSG add esp, FFFFFFB4:堆栈分配空间
invoke GetModuleHandle,NULL
mov hInstance,eax
.
.
.
; 注册窗口类
;********************************************************************
invoke LoadCursor,0,IDC_ARROW
mov @stWndClass.hCursor,eax
.
mov @stWndClass.lpfnWndProc,offset _ProcWinMain
.省略部分 mov [ebp-28], 00401000 :窗口过程地址
.
; 建立并显示窗口的api 这部分的反编译程序:
invoke CreateWindowEx,WS_EX_CLIENTEDGE, push 00000000
offset szClassName,offset szCaptionMain,\push dword ptr[00403000]
WS_OVERLAPPEDWINDOW,\ push 00000000
100,100,600,400,\ .省略部分
NULL,NULL,hInstance,NULL .压入这条api的参数
Call 00401176:执行 CreatWindowex
mov hWinMain,eax mov dword ptr [00403004], eax
:把存入eax的窗口句柄到hWinMain变量中
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
_Main endp
窗口过程:
_ProcWinMain proc uses ebx edi esi,hWnd,uMsg,wParam,lParam
反汇编代码:
local @stPs:PAINTSTRUCT push ebp
local @stRect:RECT mov ebp, esp
local @hDc add esp, FFFFFFAC
push ebx
push edi
push esi
mov eax, dword ptr [ebp+0C]
mov eax,uMsg :将uMsg装入eax
cmp eax, 0000000F
.if eax == WM_PAINT jne 0040104F :判断
invoke BeginPaint,hWnd,addr @stPs lea eax, dword ptr [ebp-40] push eax
push [ebp+08]
:这三条语句为beginpaint压入参数
Call 00401170 :执行beginpaint
mov @hDc,eax .
invoke GetClientRect,hWnd,addr @stRect . 省略
invoke DrawText,@hDc,addr szText,-1,\ .
addr @stRect,\
DT_SINGLELINE or DT_CENTER or DT_VCENTET
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 pop esi :返回
pop edi
pop ebx
leave
ret 0010
ret
_ProcWinMain endp
我的问题是在主程序中的执行CreatWindowsEX后的句柄存在dword ptr [00403004]这个变量中,后来在窗口过程中执行Beginpaint中用到此窗口的句柄时用push [ebp+08] 这样就使用了这个窗口的句柄,请问此句柄的地址是如何传递的??
窗口过程中的 push [ebp+08] 是系统传递给你的过程函数的一个参数, 因为系统知道哪个窗口需要进行消息处理, 所以将须进行消息处理的窗口的句柄、消息以及处理该消息所需要的参数一并传给了你的窗口处理函数。
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle of window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
通过堆栈,如果不使用invoke关键字,必须手动把参数压入堆栈,使用invoke可以直接在后面使用参数。