2013-03-09 40 views
0

_AddPS函數不平衡堆棧,並且打算是StdCAll。我沒有更多的信息,而這只是我的第二段彙編代碼(我的第一個是模擬cdecl函數調用的測試.exe)。我的stdcall彙編代碼不平衡堆棧

.386 
.MODEL FLAT, STDCALL 
option casemap :none ; case sensitive 

.CODE 

_LibMain proc instance:dword, reason:dword, unused:dword 
    mov  EAX, 1  ; 
    ret 
_LibMain endp 

_AddPS proc a:dword, b:dword 
    push ebp   ; 
    mov  ebp, esp ; // ebp << esp 
    push EAX   ; 
    push EBX   ; 
    mov EAX, [ebp+8] ; 
    mov EBX, [ebp+4] ; 
    add  EAX, EBX ; 
    pop  EBX   ; 
    pop  EAX   ; 
    mov  esp, ebp ; 
    pop ebp  ; 
    RET 8 
_AddPS endp 
END _LibMain 

使用MASM和下面的命令行編譯:

c:\Asm\Test.asm /coff /Gz /FeC:\Asm\Test.dll /FoC:\Asm\Test.obj /link /SUBSYSTEM:WINDOWS /link /DLL 

編輯:下面的代碼工作,但我爲什麼朦朧:

_Test proc a:dword, b:dword 
    push ebp  ; Store the stack frame. 
    push EAX  ; Store EAX. Probably not needed. 
    mov EAX, a  ; Move a into EAX. 
    add EAX, b  ; Add b to EAX. 
    add esp, 4  ; Move past the stored EAX without popping. 
    pop ebp  ; pop the stack frame. 
    RET 8 // dword is 4 bytes in .386. We return past the parameters. 
_Test endp // Marks where to stop compiling the function. 
+0

您是否嘗試刪除「mov esp,ebp」?該指示不應該是必要的,並且(現在我猜測)可能是不平衡堆棧的原因。 – 2013-03-09 21:32:01

+0

你能解釋爲什麼沒有必要嗎?恢復指令指針似乎很重要。 – 2013-03-09 21:44:18

+0

「mov esp,ebp」恢復堆棧指針。但是,如果push和pop匹配的次數不足,則堆棧指針不必恢復。 ebp被用作基址指針來訪問堆棧中的局部變量和參數。例如。在「mov EAX,[ebp + 8]」和「mov EBX,[ebp + 4]」中,它是執行堆棧平衡的「RET 8」指令。 – 2013-03-09 22:00:32

回答

2

你正在創建堆棧幀!當您在MASM中使用PROC關鍵字創建過程時,MASM會創建標準序言和結尾! 前兩行是MASM生成序幕,最後兩行是你的序幕。

PUSH EBP 
MOV  EBP, ESP 
PUSH EBP 
MOV  EBP, ESP 

如果你想代碼,你做的方式,並創建MASM人工堆棧幀,並繼續使用MASM特效,你需要關閉序言/結尾的創建和重新打開它完成時上。

這應該工作:

option prologue:none ; turn off default prologue creation 
option epilogue:none ; turn off default epilogue creation 
_AddPS proc a:dword, b:dword 
    push ebp   ; 
    mov  ebp, esp ; // ebp << esp 
    push EAX   ; 
    push EBX   ; 
    mov EAX, [ebp+8] ; 
    mov EBX, [ebp+4] ; 
    add  EAX, EBX ; 
    pop  EBX   ; 
    pop  EAX   ; 
    mov  esp, ebp ; 
    pop ebp  ; 
    RET 8 
_AddPS endp 
option prologue:PrologueDef ; turn on default prologue creation 
option epilogue:EpilogueDef ; turn on default epilogue creation 

你甚至可以使用MASM自己的特殊序言/結尾,如果想要的。

如果你在像olly這樣的調試器中查看你的exe,你會發現錯誤。

+0

我加載了Ollydbg中的Test.exe並顯示ntdll。也沒有太多的文件。 – 2013-03-10 15:54:39

1
include masm32rt.inc 
.code 
start: 
    int 3 
    ret 

_AddPSOrg proc a:dword, b:dword 
    push ebp   ; 
    mov  ebp, esp ; // ebp << esp 
    push EAX   ; 
    push EBX   ; 
    mov EAX, [ebp+8] ; 
    mov EBX, [ebp+4] ; 
    add  EAX, EBX ; 
    pop  EBX   ; 
    pop  EAX   ; 
    mov  esp, ebp ; 
    pop ebp  ; 
    RET 8 

_AddPSOrg endp 

option prologue:none ; turn off default prologue creation 
option epilogue:none ; turn off default epilogue creation 
_AddPSGood proc a:dword, b:dword 
    push ebp   ; 
    mov  ebp, esp ; // ebp << esp 
    push EAX   ; 
    push EBX   ; 
    mov EAX, [ebp+8] ; 
    mov EBX, [ebp+4] ; 
    add  EAX, EBX ; 
    pop  EBX   ; 
    pop  EAX   ; 
    mov  esp, ebp ; 
    pop ebp  ; 
    RET 8 
_AddPSGood endp 
option prologue:PrologueDef ; turn on default prologue creation 
option epilogue:EpilogueDef ; turn on default epilogue creation  
end start 

當運行時,int 3將帶來你的程序olly。這是olly中的代碼: enter image description here

你能看出它的區別嗎?

所以,堆棧不是不平衡的,參數不是你期望的地方。

如果您想知道堆棧是否真的不平衡,請在調用函數之前打印esp的值,如果值不同,則堆棧不平衡。