在IA-32汇编语言中,如果没有LIDT、LGDT和LLDT指令,是否可以修改IDTR、GDTR或LDTR或'loaded'?
In IA-32 assembly language, can IDTR, GDTR or LDTR be modified or 'loaded' without the LIDT, LGDT and LLDT instructions?
在 IA-32 汇编语言中,是否可以修改 IDTR、GDTR 或 LDTR/'loaded' 没有 LIDT、LGDT 和 LLDT 指令?
另外,是否有可用于修改其他寄存器的完整指令列表?我想知道哪些指令可以用来修改CR3,哪些指令可以用来修改ECX
我是 IA-32 装配的新手。我知道 MOV、ADD、SUB 等,但是它需要是一个完整的列表,我相信可能有很多指令可以用来修改这些寄存器。
谢谢! :)
编辑:我想知道的原因是因为我正在考虑监视已执行指令的指令跟踪(使用硬件调试)是否是一种可行的检测方法 - 在外部 'integrity monitoring' 机器中 - 任何恶意软件Rootkit 更改这些寄存器中的地址以执行所谓的地址转换重定向攻击 (ATRA)。因此,我试图确定是否有可能确定修改每个寄存器的潜在恶意指令序列的完整列表。
Regarding IDTR
, GDTR
, and LDTR
, the Intel System Programming Guide has the answers :
Section 2.4.1, "Global Descriptor Table Register" (GDTR
) :
The LGDT
and SGDT
instructions load and store the GDTR
register,
respectively.
Section 2.4.2, "Local Descriptor Table Register" (LDTR
) :
The LLDT
and SLDT
instructions load and store the segment selector
part of the LDTR
register, respectively. The segment that contains the
LDT
must have a segment descriptor in the GDT
. When the LLDT
instruction loads a segment selector in the LDTR
: the base address,
limit, and descriptor attributes from the LDT
descriptor are auto-
matically loaded in the LDTR
. When a task switch occurs, the LDTR
is
automatically loaded with the segment selector and descriptor for the
LDT
for the new task. The contents of the LDTR
are not automatically
saved prior to writing the new LDT
information into the register.
So, there are only two instructions used for modifying the table, but task switching in the processor (though it's not used by any of the mainstream operating systems anymore, so whether you should worry about this depends on what you're actually doing) can cause the contents of this register to change.
Section 2.4.3, "IDTR
Interrupt Descriptor Table Register" :
The LIDT
and SIDT
instructions load and store the IDTR
register,
respectively.
Regarding ECX
, however, there is no one clear answer. Since it was used as a "count" register back in the days of real mode, it might be modified by some loop-related instructions implicitly. Off the top of my head :
LOOP
(and its derivatives), which decrements ECX
and jumps if it's not zero. However, you shouldn't really see this instruction a lot in new code, as it's mostly a leftover from CISC days and as such its use is discouraged when emitting code for today's CPUs. This is due to relatively long time (compared to test
+ jump) it takes to decode it.
REP
(and its derivatives), which repeats a given instruction as long as ECX
is not zero.
CPUID
, which uses all the registers to return CPU identification information.
I'm sure there's some more. I'd be surprised if such a list exists, though it would certainly be useful sometimes.
可以通过以下方式修改 IDTR、GDTR 或 LDTR:
- LIDT、LGDT 和 LLDT 指令
- 进入系统管理模式,修改"state save"区域中的值,然后离开系统管理模式导致加载修改的值
- 使用硬件虚拟化扩展,其中主机能够修改来宾使用的虚拟 IDTR、GDTR 或 LDTR
请注意,此列表不包括保持 IDTR、GDTR 或 LDTR 相同以及修改它们指向的数据(IDT、GDT 或 LDT)。
CR3 可以通过以下方式更改:
mov cr3
说明
- 硬件任务切换
- 代码运行系统管理模式
- 硬件虚拟化扩展(主机修改来宾)
ECX 可以通过以下方式更改:
- 数百种不同的指令(太多无法列出)
- 硬件任务切换
- 代码运行系统管理模式
- 硬件虚拟化扩展(主机修改来宾)
请注意,硬件任务切换几乎从未使用过,并且在长模式下也不再受支持;系统管理模式通常对软件完全不可用(包括软件 运行 at CPL=0),只有系统的固件才能真正使用它。
在 IA-32 汇编语言中,是否可以修改 IDTR、GDTR 或 LDTR/'loaded' 没有 LIDT、LGDT 和 LLDT 指令?
另外,是否有可用于修改其他寄存器的完整指令列表?我想知道哪些指令可以用来修改CR3,哪些指令可以用来修改ECX
我是 IA-32 装配的新手。我知道 MOV、ADD、SUB 等,但是它需要是一个完整的列表,我相信可能有很多指令可以用来修改这些寄存器。
谢谢! :)
编辑:我想知道的原因是因为我正在考虑监视已执行指令的指令跟踪(使用硬件调试)是否是一种可行的检测方法 - 在外部 'integrity monitoring' 机器中 - 任何恶意软件Rootkit 更改这些寄存器中的地址以执行所谓的地址转换重定向攻击 (ATRA)。因此,我试图确定是否有可能确定修改每个寄存器的潜在恶意指令序列的完整列表。
Regarding IDTR
, GDTR
, and LDTR
, the Intel System Programming Guide has the answers :
Section 2.4.1, "Global Descriptor Table Register" (GDTR
) :
The
LGDT
andSGDT
instructions load and store theGDTR
register, respectively.
Section 2.4.2, "Local Descriptor Table Register" (LDTR
) :
The
LLDT
andSLDT
instructions load and store the segment selector part of theLDTR
register, respectively. The segment that contains theLDT
must have a segment descriptor in theGDT
. When theLLDT
instruction loads a segment selector in theLDTR
: the base address, limit, and descriptor attributes from theLDT
descriptor are auto- matically loaded in theLDTR
. When a task switch occurs, theLDTR
is automatically loaded with the segment selector and descriptor for theLDT
for the new task. The contents of theLDTR
are not automatically saved prior to writing the newLDT
information into the register.
So, there are only two instructions used for modifying the table, but task switching in the processor (though it's not used by any of the mainstream operating systems anymore, so whether you should worry about this depends on what you're actually doing) can cause the contents of this register to change.
Section 2.4.3, "IDTR
Interrupt Descriptor Table Register" :
The
LIDT
andSIDT
instructions load and store theIDTR
register, respectively.
Regarding ECX
, however, there is no one clear answer. Since it was used as a "count" register back in the days of real mode, it might be modified by some loop-related instructions implicitly. Off the top of my head :
LOOP
(and its derivatives), which decrementsECX
and jumps if it's not zero. However, you shouldn't really see this instruction a lot in new code, as it's mostly a leftover from CISC days and as such its use is discouraged when emitting code for today's CPUs. This is due to relatively long time (compared totest
+ jump) it takes to decode it.REP
(and its derivatives), which repeats a given instruction as long asECX
is not zero.CPUID
, which uses all the registers to return CPU identification information.
I'm sure there's some more. I'd be surprised if such a list exists, though it would certainly be useful sometimes.
可以通过以下方式修改 IDTR、GDTR 或 LDTR:
- LIDT、LGDT 和 LLDT 指令
- 进入系统管理模式,修改"state save"区域中的值,然后离开系统管理模式导致加载修改的值
- 使用硬件虚拟化扩展,其中主机能够修改来宾使用的虚拟 IDTR、GDTR 或 LDTR
请注意,此列表不包括保持 IDTR、GDTR 或 LDTR 相同以及修改它们指向的数据(IDT、GDT 或 LDT)。
CR3 可以通过以下方式更改:
mov cr3
说明- 硬件任务切换
- 代码运行系统管理模式
- 硬件虚拟化扩展(主机修改来宾)
ECX 可以通过以下方式更改:
- 数百种不同的指令(太多无法列出)
- 硬件任务切换
- 代码运行系统管理模式
- 硬件虚拟化扩展(主机修改来宾)
请注意,硬件任务切换几乎从未使用过,并且在长模式下也不再受支持;系统管理模式通常对软件完全不可用(包括软件 运行 at CPL=0),只有系统的固件才能真正使用它。