x86-64 中断期间程序寄存器存储在哪里
Where are program registers stored during an interrupt in x86-64
对于大学作业,我的任务是使用 x86-64 中的汇编代码覆盖除以零中断处理程序,从而使除法运算结果为被除数 - 1。
所以据我了解,我需要在返回程序之前更改除法寄存器的值。
如何获取程序的原始寄存器值并更改它们?它们存储在哪里?
中断/异常仅在异常帧本身中保存 CS:RIP、RFLAGS 和用户-space SS:RSP。所有其他寄存器值均未修改。 x86 不像其他一些 ISA 那样进行寄存器组切换。
中断处理程序必须save/restore他们想使用的每个寄存器,以确保他们不修改用户-space状态。您将需要它来获得几个临时寄存器(除非您做出多个假设并且只支持一个操作数大小和指令长度),但是您要修改的 user-space 状态部分仍在寄存器。
幸运的是,股息位于固定位置,根据操作数的大小,可以是 AH:AL(又名 AX)、DX:AX、EDX:EAX 或 RDX:RAX除法指令 https://www.felixcloutier.com/x86/idiv 或 div
。 (或者,如果您包括 16 / 32 位兼容模式用户-space,也可能只是 aam imm8
的 AL)
因此您不必解码寻址模式,只需解码前缀和操作码,即可确定实际涉及 RDX 和 RAX 的哪些部分。
但是对于 return 和 RIP 指向 在 除法指令之后,你实际上需要计算出指令长度,例如2 字节 div ecx
与 div word [rdi + r10*2 + 256]
(9 字节:REX 和操作数大小前缀、操作码、modrm+SIB + disp32)。
你知道长度是 <= 15 个字节(包括可能的冗余前缀),否则它会用 #UD 而不是 #DE 出错。
对于大学作业,我的任务是使用 x86-64 中的汇编代码覆盖除以零中断处理程序,从而使除法运算结果为被除数 - 1。
所以据我了解,我需要在返回程序之前更改除法寄存器的值。
如何获取程序的原始寄存器值并更改它们?它们存储在哪里?
中断/异常仅在异常帧本身中保存 CS:RIP、RFLAGS 和用户-space SS:RSP。所有其他寄存器值均未修改。 x86 不像其他一些 ISA 那样进行寄存器组切换。
中断处理程序必须save/restore他们想使用的每个寄存器,以确保他们不修改用户-space状态。您将需要它来获得几个临时寄存器(除非您做出多个假设并且只支持一个操作数大小和指令长度),但是您要修改的 user-space 状态部分仍在寄存器。
幸运的是,股息位于固定位置,根据操作数的大小,可以是 AH:AL(又名 AX)、DX:AX、EDX:EAX 或 RDX:RAX除法指令 https://www.felixcloutier.com/x86/idiv 或 div
。 (或者,如果您包括 16 / 32 位兼容模式用户-space,也可能只是 aam imm8
的 AL)
因此您不必解码寻址模式,只需解码前缀和操作码,即可确定实际涉及 RDX 和 RAX 的哪些部分。
但是对于 return 和 RIP 指向 在 除法指令之后,你实际上需要计算出指令长度,例如2 字节 div ecx
与 div word [rdi + r10*2 + 256]
(9 字节:REX 和操作数大小前缀、操作码、modrm+SIB + disp32)。
你知道长度是 <= 15 个字节(包括可能的冗余前缀),否则它会用 #UD 而不是 #DE 出错。