日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

5 《Undocumented Windows 2000 Secrets》翻譯 --- 第四章( 三 )


}
else
{
RtlZeroMemory (pGate, X86_GATE_);
}
}
return fOk;
}
列表 4-19. 獲取 IDT 門的值
IOCTL 函數(shù) SPY_IO_PHYSICAL
SPY_IO_PHYSICAL 函數(shù)很簡單,它完全依賴于 ntoskrnl.exe 導出的 MmGetPhysicalAddress() 函數(shù) 。該 IOCTL 函數(shù)通過簡單的調(diào)用 SpyInputPointer() (參見 列表 4-10 )來獲取需要轉(zhuǎn)換的線性地址,然后讓 MmGetPhysicalAddress() 查找對應的物理地址,最后將結果作為 PHYSICAL_ADDRESS 結構返回給調(diào)用者 。注意,PHYSICAL_ADDRESS 是一個 64 位的 LARGE_INTEGER。在大多數(shù) i386 系統(tǒng)上,其高 32 位總是為 0。不過,若系統(tǒng)啟用了物理地址擴展( Physical Address Extension, PAE ),并且安裝的內(nèi)存大于 4GB,這些位可能就是非 0 值了 。
MmGetPhysicalAddress() 使用起始于線性地址 0xC0000000 的 PTE 數(shù)組,來進行物理地址的查找 。其基本的工作機制如下:
l 如果線性地址位于: 0x80000000----0x9FFFFFFF,則其高 3 位將被設為零,最后產(chǎn)生的物理地址位于: 0x00000000-----0x1FFFFFFF。
l 否則,線性地址的高 20 位將作為 PTE 數(shù)組(起始于 0xC0000000 )的索引 。
l 如果目標 PTE 的 P 位已被設置,這表示其對應得數(shù)據(jù)頁存在于物理內(nèi)存中 。除了 20 位的 PFN 外,所有的 PTE 位都可以被剝離出來,線性地址最低的 12 位將作為在數(shù)據(jù)頁中的偏移量被加到最后的 32 位物理地址上去 。
l 如果數(shù)據(jù)頁沒有存在于物理內(nèi)存中,MmGetPhysicalAddress() 返回 0。
MmGetPhysicalAddress() 假設內(nèi)核內(nèi)存范圍: 0x80000000----0x9FFFFFF 之外的所有線性地址都使用 4KB 的頁 。而其他函數(shù),如 MmIsAddressValid(),會首先加載線性地址的 PDE,并且檢查該 PDE 的 PS 位,以檢查頁大小是 4KB 還是 4MB。這是一個非常通用的方法,可以處理任意的內(nèi)存配置 。不過上述兩個函數(shù)都會返回正確的結果,這是因為 Windows 2000 僅針對內(nèi)存范圍: 0x80000000-----0x9FFFFFFF,使用 4MB 頁 。不過某些內(nèi)核 API 函數(shù),顯然設計的比其它的靈活許多 。
IOCTL 函數(shù) SPY_IO_CPU_INFO
個別的 CPU 指令僅對運行于 Ring 0 級的代碼有效,Ring 0 是五個特權級( Intel 系列的 CPU 只支持兩個特權級: Ring0 和 Ring3 )中級別最高的一個 。用 Windows 術語來說,Ring 0 意味著內(nèi)核模式( Kernel-mode ) 。這些被禁止的指令有:讀取控制寄存器 CR0 、 CR2 和 CR3 的內(nèi)容 。因為這些寄存器中保存著非常有趣的信息,應用程序可能想要找到一個辦法來訪問它們,解決方案就是 SPY_IO_CPU_INFO 函數(shù) 。如 列表 4-20 所示,IOCTL 處理例程調(diào)用的 SpyOutputCpuInfo() 函數(shù)使用了一些嵌入式匯編來讀取控制寄存器,以及其他一些有價值的信息,比如 IDT 的內(nèi)容,GDT 和 LDT 寄存器以及存儲在寄存器 CS 、 DS 、 ES 、 FS 、 GS 、 SS 和 TR 中的段選擇器 。任務寄存器( Task Register, TR )還包含一個涉及當前任務的 TSS 的選擇器 。
typedef struct _SPY_CPU_INFO
{
X86_REGISTER cr0;
X86_REGISTER cr2;
X86_REGISTER cr3;
SPY_SEGMENT cs;
SPY_SEGMENT ds;
SPY_SEGMENT es;
SPY_SEGMENT fs;
SPY_SEGMENT gs;
SPY_SEGMENT ss;
SPY_SEGMENT tss;
X86_TABLE idt;
X86_TABLE gdt;
X86_SELECTOR ldt;
}
SPY_CPU_INFO, *PSPY_CPU_INFO, **PPSPY_CPU_INFO;
#define SPY_CPU_INFO_ sizeof (SPY_CPU_INFO)
// -----------------------------------------------------------------
NTSTATUS SpyOutputCpuInfo (PVOID pOutput,
DWORD dOutput,
PDWORD pdInfo)
{
SPY_CPU_INFO sci;
PSPY_CPU_INFO psci = &sci;
__asm
{
push eax
push ebx
mov ebx, psci
mov eax, cr0
mov [ebx.cr0], eax
mov eax, cr2
mov [ebx.cr2], eax
mov eax, cr3
mov [ebx.cr3], eax

推薦閱讀