Win32 ASM堆栈覆盖

纳斯特

我在WindowPaint事件中调用BeginPaint(hWnd,lpPaint)遇到麻烦。似乎函数BeginPaint会覆盖堆栈。

一个小的C程序告诉我,PAINTSTRUCT(lpPaint)的大小应为34。如果我将地址设置为EBP-34或更多EBP-56作为lpPaint的返回值,它将崩溃。如果我允许大量堆叠并将返回地址放入EBP-170,它将起作用。

简单的代码:

;Note : All Win32 API functions preserve the EBP, EBX, ESI, and EDI registers

extern GetModuleHandleA
extern ExitProcess
extern GetCommandLineA
extern RegisterClassExA
extern LoadIconA
extern LoadCursorA
extern CreateWindowExA
extern ShowWindow
extern UpdateWindow
extern MessageBoxA
extern GetMessageA
extern TranslateMessage
extern DispatchMessageA
extern PostQuitMessage
extern DefWindowProcA
extern DrawTextA
extern BeginPaint
extern EndPaint

import GetModuleHandleA kernel32.dll
import ExitProcess kernel32.dll
import GetCommandLineA kernel32.dll
import RegisterClassExA user32.dll
import LoadIconA user32.dll
import LoadCursorA user32.dll
import CreateWindowExA user32.dll
import ShowWindow user32.dll
import UpdateWindow user32.dll
import MessageBoxA user32.dll
import GetMessageA user32.dll
import TranslateMessage user32.dll
import DispatchMessageA user32.dll
import PostQuitMessage user32.dll
import DefWindowProcA user32.dll
import DrawTextA user32.dll
import BeginPaint user32.dll
import EndPaint user32.dll

section .text use32
..start:

;Handle from calling process
push dword 0
call [GetModuleHandleA] 
mov dword [hInstance], eax

;Get command line
call [GetCommandLineA]
mov dword [commandLine], eax

;Main window
Call WindowMain

;Exit
Push eax
call [ExitProcess]


;========================================================================================
; Create a main windows
;========================================================================================
WindowMain:
    push ebp
    mov ebp, esp

    ;Local variable
    ;==============
    ;EBP-48 = WNDCLASSEX Structure 48 bytes
    ;EBP-72 = MSG 24 bytes
    ;EBP-76 = HWND, handle of our window 4 bytes
    sub esp, 76 

    lea ebx, [ebp-48] ;EBX is now address of WNDCLASSEX

    ;WNDCLASSEX Structure : http://msdn.microsoft.com/en-us/library/ms633577(v=vs.85).aspx
    mov dword [ebx+00], 48 ;Size of the structure
    mov dword [ebx+04], 3 ;Style of the window
    mov dword [ebx+08], WindowProcedure ;Callback function for events
    mov dword [ebx+12], 0 
    mov dword [ebx+16], 0
    mov dword [ebx+20], hInstance ;Handle to the window
    ;[ebx+24] =  HICON
    ;[ebx+28] =  HCURSOR
    mov dword [ebx+32], 6 ;Background brush
    mov dword [ebx+36], 0 ;Menu name NULL
    mov dword [ebx+40], ClassName ;Class name for the window
    ;[ebx+44] =  HICON

    ;LoadIconA(0, IDI_APPLICATION);
    push 32512
    push 0
    call [LoadIconA]
    mov dword [ebx+24], eax ;Icon for our window
    mov dword [ebx+44], eax ;Small icon for our window

    ;LoadCursorA(0, IDC_ARROW);
    push dword 32512 
    push 0
    call [LoadCursorA]
    mov dword [ebx+28], eax

    ;RegisterClassExA(WNDCLASSEX address);
    push ebx 
    call [RegisterClassExA]

    ;CreateWindowEx(0, ClassName, window title, WS_OVERLAPPEDWINDOW, x, y, width, height, handle to parent window, handle to menu, hInstance, NULL); 
    push 0
    push hInstance
    push 0
    push 0
    push 400 ;High
    push 500 ;Wide
    push dword 0x80000000 ;CW_USEDEFAULT
    push dword 0x80000000 ;CW_USEDEFAULT
    ;WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX  
    push dword 0x00 | 0xC00000 | 0x80000 | 0x40000 | 0x20000 | 0x10000    ;WS_OVERLAPPEDWINDOW 
    push dword ApplicationName
    push dword ClassName
    push dword 0
    call [CreateWindowExA]
    mov dword [ebp-76], eax ;Handle of our window

    cmp eax, 0
    jz .newWindowsFailed

    ;ShowWindow(hWind, SW_SHOWDEFAULT);
    push dword 10
    push dword [ebp-76] 
    call [ShowWindow]

    ;UpdateWindow(hWind);
    push dword [ebp-76]
    call [UpdateWindow]

    .MessageLoop:
        ;GetMessageA(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
        push dword 0
        push dword 0
        push dword 0
        lea ebx, [ebp-72]
        push ebx
        call [GetMessageA]

        cmp eax, 0 ;WM_QUIT
        jz .MessageLoopExit

        ;TranslateMessage(lpMsg);
        lea ebx, [ebp-72]
        push ebx
        call [TranslateMessage]

        ;DispatchMessageA(lpMsg);
        lea ebx, [ebp-72]
        push ebx
        call [DispatchMessageA]

        jmp .MessageLoop
    .MessageLoopExit:

    jmp .finish

    .newWindowsFailed:      
        push dword 0
        push dword 0
        push errMsg
        push 0
        call [MessageBoxA]

        mov eax, 1 ;Return error
        mov esp, ebp
        pop ebp
        ret

    .finish:        
    mov esp, ebp
    pop ebp 
ret

;========================================================================================
; Handle the events that our window sends us.
;========================================================================================
;LRESULT CALLBACK WindowProc(
;  _In_  HWND hwnd,
;  _In_  UINT uMsg,
;  _In_  WPARAM wParam,
;  _In_  LPARAM lParam
;);
;========================================================================================
WindowProcedure: 
    push ebp
    mov ebp, esp

    ;Local variable
    ;==============
    ;EBP-56 = PAINTSTRUCT   <- RECALCULER LA TAILLE DE LA STUCTURE!!!
    ;EBP-60 = HDC
    ;EBP-76 = RECT
    sub esp, 170

    mov eax, dword [ebp+12] ;uMsg

    cmp eax, 2 ;WM_DESTROY
    jz .WindowDestroy
    cmp eax, 0X0F ;WM_PAINT
    jz .WindowPaint

    .WindowDefault:
        push dword [ebp+20] 
        push dword [ebp+16] 
        push dword [ebp+12] 
        push dword [ebp+08] 
        call [DefWindowProcA] 

        ;The return value is from DefWindowProcA so we can't change EAX
        mov esp, ebp
        pop ebp
        ret 16  

    .WindowDestroy:
        ;We pass 0 as an argument to the PostQuitMessage() function, to tell it 
        ;to pass 0 as the value of wParam for the next message. At that point, 
        ;GetMessage() will return 0, and the message loop will terminate. 
        ;PostQuitMessage(nExitCode);
        push dword 0 
        call [PostQuitMessage] 
        jmp .WindowProcedureFinish

    .WindowPaint:
        ;BeginPaint(hWnd, lpPaint);
        lea ebx, [ebp-34]
        push ebx
        push dword [ebp+8]
        call [BeginPaint]
        mov dword [ebp-60], eax ;Save device context


        jmp .WindowProcedureFinish

    .WindowProcedureFinish:
    xor eax, eax
    mov esp, ebp
    pop ebp
ret 16

msgBox:
    ; MessageBoxA(0, msg1, title, 0);
    push dword 0
    push dword ClassName
    push dword TextLabel
    push dword 0
    call [MessageBoxA]
ret

section .data
ClassName       db "Main Window", 0
ApplicationName db "Win32 Assembler", 0
errMsg          db "An error occured while making the new window.", 0
TextLabel       db "Welcom to the main event!", 13, 10, 13, 10, 0

section .bss
hInstance       resd 1
commandLine     resd 1

编译:

nasm -fobj main.asm
alink -oPE main.obj -o main.exe 
炮手

一个小的C程序告诉我,PAINTSTRUCT(lpPaint)的大小应为34

真的吗?那是什么C编译器???如果您PAINTSTRUCT在MSDN上查找

typedef struct tagPAINTSTRUCT { 
  HDC  hdc; 
  BOOL fErase; 
  RECT rcPaint; 
  BOOL fRestore; 
  BOOL fIncUpdate; 
  BYTE rgbReserved[32]; 
} PAINTSTRUCT, *PPAINTSTRUCT; 

hdc = 4个字节
fErase = 4个字节
rcPaint = RECT` = 16个字节
fRestore = 4个字节
fIncUpdate = 4个字节
rgbReserved = 32个字节

RECT

typedef struct _RECT { 
  LONG left; 
  LONG top; 
  LONG right; 
  LONG bottom; 
} RECT, *PRECT; 

所有这些加在一起就为您提供了64个字节!!!
这就是为什么[EBP-56]不起作用但[EBP-170]会起作用的原因,该结构有足够的空间。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何使用Win32 API获取任何线程的堆栈大小和堆栈限制

来自分类Dev

如何使用Win32 API获取任何线程的堆栈大小和堆栈限制

来自分类Dev

Win32 GUARD内存:如何使用PAGE_GUARD实现堆栈

来自分类Dev

Boehm GC是否将Win32光纤堆栈识别为根?

来自分类Dev

如何在外部Win32应用程序的窗口上添加WPF覆盖?

来自分类Dev

如何在窗口周围绘制矩形而不覆盖Win32中的标题栏

来自分类Dev

Win32的Cortana

来自分类Dev

Win32线程

来自分类Dev

win32 ExportAsFixedFormat

来自分类Dev

当窗口失去对Win32的关注时,为什么覆盖的非客户区域显示默认值?

来自分类Dev

是否可以用另一个透明窗口覆盖win32窗口而不影响用户体验?

来自分类Dev

Win32 mkdir与_mkdir

来自分类Dev

Python Win32:错误

来自分类Dev

GetMenuBarInfo()Win32函数

来自分类Dev

C ++,Win32错误

来自分类Dev

字体布局算法,Win32

来自分类Dev

GetGuiResources WIn32 API使用

来自分类Dev

无法安装Python win32库?

来自分类Dev

Win32,MFC:结束线程

来自分类Dev

什么是Win32消息编组?

来自分类Dev

崩溃调试Win32 App

来自分类Dev

在Win32上处理CTRL + C

来自分类Dev

从Win32按钮删除边框

来自分类Dev

在Win32 TIB中保存数据

来自分类Dev

WPF程序-程序无效win32

来自分类Dev

Win32 PlaySound重叠音频

来自分类Dev

如何禁用按钮-Win32 API

来自分类Dev

Win32 API SearchPath失败

来自分类Dev

Win32 WinAPI EditBoX样式