If you are following this article , which it seems you are, then why aren't you properly restoring the stack as shown in the code there?
The code in the article:
18 NoException&;Handler: ;;No Exception Occured
19 pop dword ptr fs:[0] ;;Restore Old Exception Handler
20 add esp, 32 + 4 ;;ESP value before SEH was set. 32 for pushad and ...
21 ExceptionHandled&;Handler: ;;...4 for push offset Handler. (No Restore State)
22 ;;Exception has been handled, or no exception occured
Your code:
NoException:
pop dword ptr fs:[0]
add esp, 8
ExceptionHandled:
32 in that code is to undo pushad
,4將撤消push esi
。你爲什麼有8個? 32 + 4≠8
如果這就是你想從堆棧中刪除u32Param
(如果pFunc
你不這樣做),那麼你應該去做這兩條線之間:
call pFunc;
add esp, 4
jmp NoException
我的版本:
// file: tst.c
// compile with Open Watcom C/C++ 1.9: wcl386.exe /q /we /wx tst.c
// ditto with debug info: wcl386.exe /q /we /wx /d2 tst.c
#include <stdio.h>
unsigned __stdcall func(volatile unsigned* p)
{
return *p;
}
unsigned blah(unsigned (__stdcall *pFunc)(volatile unsigned*), volatile unsigned* u32Param)
{
unsigned result = 0;
__asm
{
pushad
// mov esi, offset Handler // Open Watcom C/C++ says Handler is undefined
// push esi
// lea eax, blah
// add eax, Handler - blah // this difference doesn't come out correct with Open Watcom C/C++
// add eax, 78 // 78 is Handler - blah // this is unreliable
// push eax
push 0xFDCB4321
jmp GetHandlerAddr
GotHandlerAddr:
pop eax
add esp, 4
push eax
push dword ptr fs:[0]
mov dword ptr fs:[0], esp
push u32Param
call dword ptr [pFunc]
jmp NoException
GetHandlerAddr:
call Handler // this will place &Handler on the stack
Handler:
cmp dword ptr [esp + 4], 0xFDCB4321
je GotHandlerAddr
mov esp, [esp + 8]
pop dword ptr fs:[0]
add esp, 4
popad
mov eax, 0x80000000
jmp ExceptionHandled
NoException:
pop dword ptr fs:[0]
add esp, 32 + 4
ExceptionHandled:
mov result, eax
}
return result;
}
int main(void)
{
volatile unsigned n = 0x113355AA;
printf("%08X\n", func(&n));
printf("%08X\n", blah(&func, &n));
printf("%08X\n", blah(&func, (volatile unsigned*)0));
printf("%08X\n", blah(&func, (volatile unsigned*)0));
return 0;
}
輸出:
113355AA
113355AA
80000000
80000000
嘗試獲得除了簡單的拆卸離子處理程序由vC++編譯,以查看注入哪些入口/出口代碼塊。 (相當於g中的-S - objdump -d file.o也會這樣)。在例程本身中也可能沒有特殊的入口/出口代碼,但是您需要將入口點作爲信號處理程序插入到例程中。 –
我已經看到由vc生成的生成的程序集,但問題不在於程序集源,它不適用於我的大項目是控制檯應用程序,當我創建一個新項目(不管Win32/Console)時,它的工作原理! –