1. 中断机制的本质与寻址困境
在x86架构的实模式下,中断向量表(IVT)占据内存最低的1KB空间(0000:0000到0000:03FF),其中每个中断号对应4字节的入口地址(CS:IP)。当CPU接收到中断信号时,会暂停当前指令流,将FLAGS、CS和IP压栈,然后从中断向量表获取处理程序地址进行跳转。
但这里存在一个关键问题:通过INT指令直接调用的中断服务程序(ISR),可能并非硬件实际使用的中断处理程序。以经典的INT 13H(磁盘服务)为例,BIOS会在初始化时修改IVT中的原始入口,将其指向自己提供的服务程序。这种重定向机制使得开发者难以获取硬件层面的真实中断入口。
注意:在保护模式下,中断描述符表(IDT)取代了IVT,但地址重定向问题依然存在,只是实现机制更为复杂。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 传统获取方法的局限性
最直观的获取方法是直接读取IVT内容。例如获取INT 21H的入口地址:
assembly复制MOV AX, 0
MOV ES, AX ; 段地址设为0
MOV BX, 21h * 4 ; 每个中断向量占4字节
MOV AX, ES:[BX] ; 获取偏移地址
MOV DX, ES:[BX+2]; 获取段地址
这种方法看似有效,但存在三个致命缺陷:
- 钩子干扰:TSR程序(内存驻留程序)可能已经修改了IVT内容
- 虚拟化层拦截:某些环境(如DOSBox)会虚拟化中断机制
- 多级跳转:BIOS可能仅在此存放跳板代码,而非最终处理程序
3. 逆向追踪技术实战
3.1 硬件断点法
通过调试器设置执行断点,可以追踪中断调用的完整链路。以Turbo Debugger为例:
- 执行
INT 21H触发中断 - 在调试器中设置
trap on execution断点 - 单步执行直到遇到
IRET指令 - 记录所有跳转地址,最后一个非返回地址即为最底层处理程序
这种方法需要处理以下特殊情况:
- 可能遇到动态生成的代码段
- 需要识别并跳过标准的PUSH/POP等序言代码
- 注意处理自修改代码(Self-Modifying Code)
3.2 内存扫描技术
通过特征码扫描定位原始入口。以INT 13H为例:
- 获取IVT中
