5 《Undocumented Windows 2000 Secrets》翻译 --- 第四章( 二 )

<< X86_SELECTOR_SHIFT,
&pInterrupt->Selector))
{
fOk = FALSE;
}
if (!SpyIdtGate (&pInterrupt->Selector,
&pInterrupt->Gate))
{
fOk = FALSE;
}
if (!SpySegment (X86_SEGMENT_OTHER,
pInterrupt->Gate.Selector,
&pInterrupt->Segment))
{
fOk = FALSE;
}
pInterrupt->pOffset = SpyGateOffset (&pInterrupt->Gate);
}
else
{
RtlZeroMemory (pInterrupt, SPY_INTERRUPT_);
}
pInterrupt->fOk = fOk;
}
return fOk;
}
// -----------------------------------------------------------------
PVOID SpyGateOffset (PX86_GATE pGate)
{
return (PVOID) (pGate->Offset1 | (pGate->Offset2 << 16));
}
列表 4-18. 查询中断属性
表 4-3. 任务状态段( TSS )中的 CPU 状态域
偏移量
位数
ID
描 述
0x00
16
前一个任务的链接
0x04
32
ESP0
Ring0 级的堆栈指针寄存器
0x08
16
SS0
Ring0 级的堆栈段寄存器
0x0C
32
ESP1
Ring1 级的堆栈指针寄存器
0x10
16
SS1
Ring1 级的堆栈段寄存器
0x14
32
ESP2
Ring2 级的堆栈指针寄存器
0x18
16
SS2
Ring2 级的堆栈段寄存器
0x1C
32
CR3
页目录基址寄存器( PDBR )
0x20
32
EIP
指令指针寄存器
0x24
32
EFLAGS
处理器标志寄存器
0x28
32
EAX
通用寄存器
0x2C
32
ECX
通用寄存器
0x30
32
EDX
通用寄存器
0x34
32
EBX
通用寄存器
0x38
32
ESP
堆栈指针寄存器
0x3C
32
EBP
基地址指针寄存器
0x40
32
ESI
源索引寄存器
0x44
32
EDI
目标索引寄存器
0x48
16
ES
扩展段寄存器
0x4C
16
CS
代码段寄存器
0x50
16
SS
堆栈段寄存器
0x54
16
DS
数据段寄存器
0x58
16
FS
附加的数据段寄存器 #1
0x5C
16
GS
附加的数据段寄存器 #2
0x60
16
LDT
本地描述符标的段选择器
0x64
1
1
调试陷阱标志
0x66
16
I/O Map 的基地址
0x68
-
CPU 状态信息结束
SpyInterrupt() 调用的 SpySegment() 、 SpySelector() 函数已经在 列表 4-5 和 列表 4-16 中给出 。SpyGateOffset() 位于 列表 4-18 的末尾,它的工作和 SpyDescriptorBase() 、 SpyDescriptorLimit() 类似,从 X86_GATE 结构中取出 Offset1 和 Offset2 位域,并适当的组织它们以构成一个 32 位地址 。SpyIdtGaet() 定义于 列表 4-19。它与 SpyDescriptor() 十分类似 。汇编指令 SIDT 存储一个 48 位的值,该值就是 CPU 的 IDT 寄存器的内容,它由一个 16 位的表大小限制值和 IDT 的 32 位线性基地址构成 。列表 4-19 中的剩余代码将选择器的描述符索引和 IDT 的大小限制值进行比较,如果 OK,则对应的中断描述符将被复制到调用者提供的 X86_GATE 结构中 。否则,门结构的所有成员都将被设置为 0。
BOOL SpyIdtGate (PX86_SELECTOR pSelector,
PX86_GATE pGate)
{
X86_TABLE idt;
PX86_GATE pGates = NULL;
BOOL fOk = FALSE;
if (pGate != NULL)
{
if (pSelector != NULL)
{
__asm
{
sidt idt.wLimit
}
if ((pSelector->wValue & X86_SELECTOR_INDEX)
<= idt.wLimit)
{
pGates = idt.pGates;
}
}
if (pGates != NULL)
{
RtlCopyMemory (pGate,
pGatespSelector->Index,
X86_GATE_);
fOk = TRUE;

推荐阅读