在IA-32汇编语言中,可以在没有LIDT,LGDT和LLDT指令的情况下修改或“加载”IDTR,GDTR或LDTR吗?

时间:2015-06-28 20:08:23

标签: assembly cpu-registers ia-32

在IA-32汇编语言中,可以在没有LIDT,LGDT和LLDT指令的情况下修改/加载IDTR,GDTR或LDTR吗?

此外,是否有完整的指令列表可用于修改其他寄存器?我需要知道哪些指令可用于修改CR3,以及哪些指令可用于修改ECX。

我是IA-32装配的新手。我知道MOV,ADD,SUB等,但它需要是一个完整的列表,我相信可能有很多指令可能用于修改这些寄存器。

谢谢! :)

编辑:我想知道的原因是因为我正在考虑监控执行指令的指令跟踪(使用硬件调试)是否是一种可行的检测方法 - 在外部“完整性监控”机器中 - 任何恶意的rootkit都会改变这些寄存器中的地址执行所谓的地址转换重定向攻击(ATRA)。因此,我试图确定是否有可能确定修改每个寄存器的潜在恶意指令序列的完整列表。

2 个答案:

答案 0 :(得分:3)

关于IDTRGDTRLDTRIntel System Programming Guide有答案:

第2.4.1节“全局描述符表注册”(GDTR):

  

LGDTSGDT指令加载并存储GDTR寄存器,   分别

第2.4.2节“本地描述符表寄存器”(LDTR):

  

LLDTSLDT指令加载并存储段​​选择器   分别是LDTR寄存器的一部分。包含的段   LDT必须在GDT中包含一个段描述符。当LLDT   指令加载LDTR中的段选择器:基址,   来自LDT描述符的限制和描述符属性是自动的   在LDTR中加载。发生任务切换时,LDTR为   自动加载段选择器和描述符   LDT用于新任务。 LDTR的内容不会自动生效   在将新LDT信息写入注册表之前保存。

因此,只有两条指令用于修改表,但是处理器中的任务切换(虽然它不再被任何主流操作系统使用,所以你是否应该担心这取决于你实际上是什么do)会导致该寄存器的内容发生变化。

第2.4.3节“IDTR中断描述符表寄存器”:

  

LIDTSIDT指令加载并存储IDTR寄存器,   分别

然而,关于ECX,没有一个明确的答案。由于它在实模式时代被用作“计数”寄存器,因此可能会隐式地通过一些与循环相关的指令进行修改。在我的头顶:

  • LOOP(及其派生词),递减ECX并跳跃,如果它不为零。但是,你不应该在新代码中真正看到这个指令,因为它主要是CISC时代的剩余部分,因此在为今天的CPU发布代码时不鼓励使用它。这是因为解码它需要相对较长的时间(与test +跳转相比)。
  • REP(及其派生词),只要ECX不为零,就会重复给定的指令。
  • CPUID,它使用所有寄存器返回CPU标识信息。

我确信还有更多。如果这样的列表存在,我会感到惊讶,虽然它有时会很有用。

答案 1 :(得分:2)

IDTR,GDTR或LDTR可以通过以下方式修改:

  • LIDT,LGDT和LLDT指令
  • 进入系统管理模式,修改“状态保存”区域中的值,然后离开系统管理模式以使加载修改后的值
  • 使用硬件虚拟化扩展,主机可以修改guest虚拟机使用的虚拟IDTR,GDTR或LDTR

请注意,此列表不包括保持IDTR,GDTR或LDTR相同并修改它们指向的数据(IDT,GDT或LDT)。

CR3可以通过以下方式更改:

  • mov cr3指示
  • 硬件任务切换
  • 以系统管理模式运行的代码
  • 硬件虚拟化扩展(主机修改访客)

可以通过以下方式更改ECX:

  • 几百条不同的指示(太多无法列出)
  • 硬件任务切换
  • 以系统管理模式运行的代码
  • 硬件虚拟化扩展(主机修改访客)

请注意,硬件任务切换几乎从不使用,在长模式下也不再支持;并且系统管理模式通常完全不能用于软件(包括以CPL = 0运行的软件),并且系统的固件只能使用它。