You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用MASM64设置异常及访问SEH异常链?

MASM64访问SEH异常链及兼容x86方式的说明

核心结论

x64环境下,线程环境块(TEB)由GS寄存器而非FS寄存器寻址,异常链的首节点存储在TEB的ExceptionList字段,对应偏移为0x18,所以需要通过gs:[0x18]访问,而非x86的fs:[0]。

关于沿用x86方式设置SEH的可行性

x64支持手动注册SEH链表(类似x86的链表式结构),但有几个关键差异必须注意:

  • 结构大小变化:x64的EXCEPTION_REGISTRATION_RECORD结构中,Next和Handler都是64位指针,而非x86的32位指针。
  • 异常处理函数签名:x64的异常处理函数需遵循x64调用约定,签名为:
    EXCEPTION_DISPOSITION _cdecl ExceptionHandler(
        _Inout_ PEXCEPTION_RECORD ExceptionRecord,
        _In_ PVOID EstablisherFrame,
        _Inout_ PCONTEXT ContextRecord,
        _Inout_ PVOID DispatcherContext
    );
    
    返回值EXCEPTION_DISPOSITION枚举值与x86一致,但所有参数均为64位指针。
  • 栈对齐要求:x64代码必须保证栈始终16字节对齐,构造SEH记录时需注意栈指针的调整。

MASM64手动设置SEH的示例

.code
; 异常处理函数
ExceptionHandler proc
    ; 简单返回继续执行,可根据需求添加处理逻辑
    mov rax, ExceptionContinueExecution
    ret
ExceptionHandler endp

Main proc
    ; 调整栈以满足x64的16字节对齐要求
    sub rsp, 28h

    ; 在栈上构造EXCEPTION_REGISTRATION_RECORD
    push ExceptionHandler
    push qword ptr gs:[0x18]  ; 保存原异常链首节点
    mov qword ptr gs:[0x18], rsp  ; 将新记录设为链首

    ; 触发测试异常(除零操作)
    xor rcx, rcx
    div rcx

    ; 恢复原异常链
    pop qword ptr gs:[0x18]
    add rsp, 28h
    ret
Main endp
end

注意事项

  • 手动修改SEH链需要足够权限,现代Windows的SEHOP等防护机制会校验链的合法性,非法修改可能导致进程崩溃。
  • 若配合C++代码使用,编译器会自动生成x64 SEH相关结构,手动修改链需避免破坏编译器生成的逻辑。

内容的提问来源于stack exchange,提问作者ginko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 21:50:22