对着汇编参了一会,好像看懂了,哈哈,
这是为了调用 RtlUnwindEx,只传了俩参数,
这个函数要回到抛异常的现场,里面应该有longjmp
sub rsp, 30h
mov rax, pDispatcherContext
mov rax, [rax].DISPATCHER_CONTEXT.HistoryTable
mov [rsp+28h], rax
lea rax, originalExceptContext
mov [rsp+20h], rax
call RtlUnwindEx ; Must not return. If it returns there is an error.
add rsp, 30h ; We don't expect to come here, but anyway.
函数的签名:
NTSYSAPI VOID RtlUnwindEx(
[in, optional] PVOID TargetFrame,
[in, optional] PVOID TargetIp,
[in, optional] PEXCEPTION_RECORD ExceptionRecord,
[in] PVOID ReturnValue,
[in] PCONTEXT ContextRecord,
[in, optional] PUNWIND_HISTORY_TABLE HistoryTable
);
这个方案是:
1 通过修改 Proc:Frame属性,注册handler
2 定义汇编的MACRO,try/except/final,方便使用,记录try/catch的地址,记录到自定义的数据段,dataexcp
3 发生异常后,跳到handler。handler前面的拷贝、检测block嵌套没看懂,后面就是开头的RtlUnwindEx了…… 这顺利的话函数不会返回,一路跑完了退栈过程
【 在 z16166 的大作中提到: 】
: C++编译器生成的__try/__except的汇编代码也是这个机制,就是建立SEH chain。
: 而且C++是可以调用汇编的,用汇编写的asm文件编译成obj给c++调用就行。
: 嵌入asm也行。
: ...................
--
FROM 61.185.186.*