// Import SDT pointer
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
// Create SDT reference
PSERVICE_DESCRIPTOR_TABLE psdt = KeServiceDescriptorTable;
列表 2-2 訪問系統(tǒng)服務(wù)描述符表
SDT 中的每個 SST 的 ServiceTable 成員都是一個指針,指向一個由函數(shù)指針構(gòu)成的數(shù)組,此函數(shù)指針的類型為: NTPROC,這為 Native API 提供了占位符,這種方式和在 Win32 編程中使用的 PROC 類型很相似 。NTPROC 的定義在前面的 列表 2-1 中給出 。Native API 函數(shù)通常返回一個 NTSTATUS 類型的代碼并且使用 NTAPI 調(diào)用方式,NTAPI 實(shí)際上就是 _stdcall。ServiceLimit 成員保存在 ServieTable 數(shù)組中發(fā)現(xiàn)的入口地址的個數(shù) 。在 Windows 2000 中,其默認(rèn)值為 248。ArgumentTable 成員是一個 BTYE 類型的數(shù)組,它和 ServiceTable 所指的數(shù)組一一對應(yīng),并給出其中每個函數(shù)指針?biāo)璧膮?shù)在調(diào)用者的堆棧中的字節(jié)數(shù) 。此信息隨 EDX 寄存器提供的指針一起使用 。當(dāng)內(nèi)核從調(diào)用者的堆棧中復(fù)制參數(shù)到自己的堆棧時就需要這些信息 。CounterTable 成員在 Windows 2000 的 Free Build 版中不被使用 。在 Debug Build 版中,該成員指向一個 DWORD 類型的數(shù)組,作為每個函數(shù)的使用計(jì)數(shù)器( usage counters ) 。This information can be used for profiling purposes.
使用 Windows 2000 的內(nèi)核調(diào)試器可方便的顯示 SDT 中的內(nèi)容 。如果你還沒有設(shè)置好這個有用的程序,那請參考第一章 。在 示列 2-2 中,我首次使用了 dd KeServiceDescriptorTable 命令 。調(diào)試器會將此公開符號解析為 0x8046AB80,同時顯示該地址之后的 32 個 DWORD 的 16 進(jìn)制轉(zhuǎn)儲 。不過僅有前面的四行才是有意義的,它們分別對應(yīng) 列表 2-1 中的四個 SDT 成員 。為了更清晰些,它們都將以黑體顯示 。如果你仔細(xì)觀察,你會發(fā)現(xiàn)第五行與第一行十分相像,這是另一個 SDT 嗎?這是測試內(nèi)核調(diào)試器的 ln 命令的好機(jī)會 。在示列 2-2 中,在顯示完 KeServiceDescriptorTable 的十六進(jìn)制 dump 之后,我輸入 ln 8046abc0 命令 。顯然,調(diào)試器知道地址 0x8046abc0,它將此地址轉(zhuǎn)化為對應(yīng)的符號 KeServiceDescriptorTableShadow 可以看出,這是內(nèi)核維護(hù)的第二個 SDT。二者之間的顯著區(qū)別是:第二個 SDT 包含 Win32k.sys 的入口地址 。這兩個表的的第三和第四個成員都是空的 。Ntoskrnl.exe 提供了一個函數(shù) KeAddSystemServiceTabel() 來填充這兩個成員 。
注意,我截斷了 ln 命令的輸出信息,僅保留了基本的信息 。
從地址 0x8046ab88 開始,是 KeServiceDescriptorTable 的十六進(jìn)制轉(zhuǎn)儲,在那兒可以找到 ServiceLimit 成員,可看到其值為 0xF8 (十進(jìn)制 248 ),這和我們預(yù)期的一樣 。ServiceTable 和 ArgumentTable 的值分別指向地址 0x804704d8 和 0x804708bc。用 ln 命令察看著兩個地址,可得到其符號: KiServiceTable 和 KiArgumentTable。這兩個符號都沒有從 ntoskrnl.exe 中導(dǎo)出,但是調(diào)試器可通過察看 Windows 2000 的符號文件識別它們 。ln 命令還可應(yīng)用到 Win32k SST 指針上,針對其 ServiceTable 和 ArgumentTable 成員,調(diào)試器分別給出了其對應(yīng)的符號 w32pServiceTable 和 W32pArgumenTable。這兩個符號都來自 Win32k.sys 的符號文件 。如果調(diào)試器無法解析這些地址,可使用 .reload 命令強(qiáng)制重新加載所有可用符號文件,然后再進(jìn)行解析 。
示例 2-2 的剩余部分是 KiServiceTable 和 KiArgumentTable 最前面的 128 個字節(jié)的十六進(jìn)制轉(zhuǎn)儲 。到目前為止,如果我說的有關(guān) Native API 的東西都是正確的,那么 NtClose() 函數(shù)的地址應(yīng)位于 KiServiceTable 數(shù)組的第 24 個位置上,其地址為 0x80470538。在該地址處,可發(fā)現(xiàn)其值為 0x8044c422,在 dd KiServiceTable 的輸出中,該地址以黑體標(biāo)記 。用 ln 察看 0x8044c422,會看到其對應(yīng)的符號正是 NtClose()。
kd> dd KeServiceDescriptorTable
推薦閱讀
- 淺談非系統(tǒng)管理員用戶本地登錄Windows 2000 server
- 同床異夢秋瓷炫多少期
- Windows 2000進(jìn)程細(xì)述
- 《Undocumented Windows 2000 Secrets》翻譯 --- 3
- Windows2000的日志文件詳述及刪除方法
- 命令篇 Windows 2000/XP的CMD命令教程 (3)
- 2 《Undocumented Windows 2000 Secrets》翻譯 --- 第三章
- 如何安裝/卸載 Windows 2000 的公鑰證書頒發(fā)機(jī)構(gòu)
- 使用 Windows 2000 備份程序備份和還原系統(tǒng)狀態(tài)
- 8 《Undocumented Windows 2000 Secrets》翻譯 --- 第四章
