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

x86-64架构下自定义Invalid opcode中断处理程序如何调用原内核处理程序

x86-64无效操作码自定义中断处理fallback实现方案

你需要先获取并保存原始无效操作码异常(中断向量号为6)的处理程序入口地址,再调整汇编逻辑即可实现fallback逻辑,具体操作如下:

前置准备

在注册自定义处理函数到IDT之前,先读取IDT中向量6对应的表项,提取出原始处理程序的入口地址,存储到一个全局变量中(比如命名为orig_ili_handler)。如果是Linux内核环境,也可以直接通过内核符号直接获取原生处理函数invalid_op的地址。

汇编代码调整

核心注意点是要完整保留异常栈帧结构,不能破坏原始处理程序需要的上下文:

  • 不要用call指令调用原始处理程序,call会额外向栈压入返回地址,破坏原有异常栈帧
  • 跳转到原始处理程序前,必须将寄存器、栈指针恢复到刚进入自定义处理函数时的状态

修改后的代码示例:

.globl my_ili_handler
    .extern orig_ili_handler  # 提前存储的原始处理程序地址的全局变量

.text
.align 4, 0x90
my_ili_handler:
# 先保存自定义处理逻辑会用到的寄存器,避免破坏异常上下文
push %rdi
push %rsi
push %rdx
push %rcx
push %r8
push %r9
push %rax

# ----------------------
# 这里写你的自定义处理逻辑
# 处理成功就跳转到success分支,处理失败则走到failed分支
# ----------------------

failed:
# 恢复之前保存的寄存器,回到异常刚触发时的寄存器状态
pop %rax
pop %r9
pop %r8
pop %rcx
pop %rdx
pop %rsi
pop %rdi
# 直接跳转到原始处理程序,栈帧完全保留,原始处理程序执行完会自行执行iretq返回
jmp *orig_ili_handler(%rip)

success:
# 处理成功的返回逻辑
pop %rax
pop %r9
pop %r8
pop %rcx
pop %rdx
pop %rsi
pop %rdi
iretq

注意事项

  • 如果你的自定义处理逻辑有修改栈指针的操作,跳转前必须把栈指针恢复到进入自定义处理函数时的数值,否则原始处理程序读取的栈帧会出错
  • 如果你是在用户态模拟IDT钩子,需要注意特权级切换带来的栈结构差异,要对应调整上下文恢复逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 19:15:03