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

Windows/MASM中如何修改异常处理函数的指令指针避免无限循环?

解决汇编异常处理中的无限循环问题

你的问题根源在于:ud2触发#UD异常后,CPU会将当前指向ud2的RIP保存到异常上下文里。你的处理程序直接ret,没有修改这个RIP,导致恢复执行后再次触发ud2,形成无限循环。要解决这个问题,需要修改异常上下文里的RIP,让程序跳过出错的ud2指令继续执行。

关键修改点

  • 异常处理程序需要正确接收结构化异常处理(SEH)的标准参数,尤其是包含CPU上下文的ContextRecord。
  • 修改ContextRecord中的Rip值,使其指向ud2之后的指令(ud2是2字节指令,所以RIP加2)。
  • 返回ExceptionContinueExecution,通知系统使用修改后的上下文恢复执行。

修改后的代码示例

_TEXT segment para 'CODE'
    ; SEH异常处理程序标准原型:
    ; EXCEPTION_DISPOSITION _stdcall MyHandler(
    ;     PEXCEPTION_RECORD ExceptionRecord,
    ;     PVOID EstablisherFrame,
    ;     PCONTEXT ContextRecord,
    ;     PVOID DispatcherContext
    ; )
    MyHandler proc _ExceptionRecord, _EstablisherFrame, _ContextRecord, _DispatcherContext
        push rbp
        mov rbp, rsp
        sub rsp, 32h ; 分配x86-64调用约定要求的阴影空间

        call printout ; 执行自定义打印逻辑

        ; 修改上下文里的RIP,跳过ud2指令(ud2占2字节)
        mov rax, [_ContextRecord]
        add [rax + CONTEXT.Rip], 2

        mov rsp, rbp
        pop rbp
        mov eax, ExceptionContinueExecution ; 返回继续执行的标志
        ret
    MyHandler endp

    public SyntaxTest
    SyntaxTest proc frame:MyHandler
        .endprolog
        ud2 ; 触发#UD异常
        .beginepilog
        ret ; 异常处理后会跳到这里执行
    SyntaxTest endp
_TEXT ends

说明

  1. 参数处理:SEH处理程序必须接收四个标准参数,这里用MASM的参数声明方式定义,同时分配x86-64调用约定要求的32字节阴影空间。
  2. 修改RIP:通过ContextRecord指针找到RIP字段,加上ud2的长度(2字节),让程序恢复执行时跳过出错指令。
  3. 返回标志:ExceptionContinueExecution是系统定义的常量(值为0),告诉系统使用修改后的上下文继续执行,而非重新触发异常或终止程序。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 05:43:22