如果您正在关注这篇文章,那么您为什么不正确地恢复堆栈,如代码中所示?
文章中的代码:
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
你的代码:
NoException:
pop dword ptr fs:[0]
add esp, 8
ExceptionHandled:
该代码中的 32 是撤消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