在IA-32汇编语言中,可以在没有LIDT,LGDT和LLDT指令的情况下修改/加载IDTR,GDTR或LDTR吗?
此外,是否有完整的指令列表可用于修改其他寄存器?我需要知道哪些指令可用于修改CR3,以及哪些指令可用于修改ECX。
我是IA-32装配的新手。我知道MOV,ADD,SUB等,但它需要是一个完整的列表,我相信可能有很多指令可能用于修改这些寄存器。
谢谢! :)
编辑:我想知道的原因是因为我正在考虑监控执行指令的指令跟踪(使用硬件调试)是否是一种可行的检测方法 - 在外部“完整性监控”机器中 - 任何恶意的rootkit都会改变这些寄存器中的地址执行所谓的地址转换重定向攻击(ATRA)。因此,我试图确定是否有可能确定修改每个寄存器的潜在恶意指令序列的完整列表。
答案 0 :(得分:3)
关于IDTR
,GDTR
和LDTR
,Intel System Programming Guide有答案:
第2.4.1节“全局描述符表注册”(GDTR
):
LGDT
和SGDT
指令加载并存储GDTR
寄存器, 分别
第2.4.2节“本地描述符表寄存器”(LDTR
):
LLDT
和SLDT
指令加载并存储段选择器 分别是LDTR
寄存器的一部分。包含的段LDT
必须在GDT
中包含一个段描述符。当LLDT
指令加载LDTR
中的段选择器:基址, 来自LDT
描述符的限制和描述符属性是自动的 在LDTR
中加载。发生任务切换时,LDTR
为 自动加载段选择器和描述符LDT
用于新任务。LDTR
的内容不会自动生效 在将新LDT
信息写入注册表之前保存。
因此,只有两条指令用于修改表,但是处理器中的任务切换(虽然它不再被任何主流操作系统使用,所以你是否应该担心这取决于你实际上是什么do)会导致该寄存器的内容发生变化。
第2.4.3节“IDTR
中断描述符表寄存器”:
LIDT
和SIDT
指令加载并存储IDTR
寄存器, 分别
然而,关于ECX
,没有一个明确的答案。由于它在实模式时代被用作“计数”寄存器,因此可能会隐式地通过一些与循环相关的指令进行修改。在我的头顶:
LOOP
(及其派生词),递减ECX
并跳跃,如果它不为零。但是,你不应该在新代码中真正看到这个指令,因为它主要是CISC时代的剩余部分,因此在为今天的CPU发布代码时不鼓励使用它。这是因为解码它需要相对较长的时间(与test
+跳转相比)。REP
(及其派生词),只要ECX
不为零,就会重复给定的指令。CPUID
,它使用所有寄存器返回CPU标识信息。我确信还有更多。如果这样的列表存在,我会感到惊讶,虽然它有时会很有用。
答案 1 :(得分:2)
IDTR,GDTR或LDTR可以通过以下方式修改:
请注意,此列表不包括保持IDTR,GDTR或LDTR相同并修改它们指向的数据(IDT,GDT或LDT)。
CR3可以通过以下方式更改:
mov cr3
指示可以通过以下方式更改ECX:
请注意,硬件任务切换几乎从不使用,在长模式下也不再支持;并且系统管理模式通常完全不能用于软件(包括以CPL = 0运行的软件),并且系统的固件只能使用它。