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

1 《Undocumented Windows 2000 Secrets》翻譯 --- 第二章( 三 )


表 B-1 (位于附錄 B 中)中有兩件事需要特別注意 。首先,NtCurrentTeb() 函數(shù)沒有對應(yīng)的 Zw* 函數(shù) 。這不是什么大問題,因為 ntdll.dll 以相似的方式導(dǎo)出 Nt* 和 Zw* 函數(shù) 。其次,ntoskrnl.exe 不再一貫的成對的導(dǎo)出 Nt/Zw 函數(shù) 。其中的一些僅以 Nt* 或 Zw* 的形式出現(xiàn) 。我不知道為什么會這樣,我猜測 ntoskrnl.exe 僅導(dǎo)出了在 Windows 2000 DDK 中有文檔記錄的函數(shù)以及其它系統(tǒng)模塊必須的那些函數(shù) 。注意,保留的 Native API 函數(shù)仍然實(shí)現(xiàn)于 ntoskrnl.exe 的內(nèi)部 。這些函數(shù)并沒有公開的進(jìn)入點(diǎn),但可通過 INT 2eh 到達(dá)他們 。
服務(wù)描述符表( The Service Descriptor Tables )
從 示例 2-1 給出的反編譯代碼可看出,INT 2eh 隨同傳入 CPU 寄存器 EAX 和 EDX 的兩個參數(shù)一起被調(diào)用 。我已經(jīng)提到過 EAX 中的“魔術(shù)”數(shù)字是一個分派 ID。除 NtCurrentTeb() 之外的所有 Native API 都采用此種方式,處理 INT 2eh 的代碼必須確定每個調(diào)用將被分配到那個函數(shù) 。這就是提供分派 ID 的原因 。位于 ntoskrnl.exe 中的中斷處理例程將 EAX 中的數(shù)值作為一個索引來查詢一個特定的表 。這個表被稱作系統(tǒng)服務(wù)表( System Service Table, SST )該表對應(yīng)的 C 結(jié)構(gòu)體 ---SYSTEM_SERVICE_TABLE 的定義在 列表 2-1 中給出 。在該列表中還包含 SERVICE_DESCRIPTOR_TABLE 結(jié)構(gòu)的定義,該結(jié)構(gòu)共有四個 SST 類型的數(shù)組,其中的前兩個用于特定目的 。
盡管上述的兩個表是系統(tǒng)基本的數(shù)據(jù)類型,但他們在 Windows 2000 DDK 中 并沒有相應(yīng)的文檔記載,本書中出現(xiàn)的許多代碼片斷都包含未文檔化的數(shù)據(jù)類型和函數(shù) 。因此,不能保證這些信息是完全真實(shí)可信的 。所有符號化的信息,如結(jié)構(gòu)名 稱、結(jié)構(gòu)成員和參數(shù)都是如此 。在創(chuàng)建這些符號時,我試圖使用適當(dāng)?shù)拿Q,這些名稱基于從已知符號的一個很小的子集(包括從符號文件中得到的那些)中得出的 命名方案 。然而,在很多場合這種啟發(fā)式方法并不成功 。只有在原始的代碼中包含所有的信息,但我無法得到它們 。實(shí)際上,我并不打算閱讀這些源代碼,因為這需 要和微軟簽訂一個 NDA ( Non-Disclosure Agreement,,不可泄漏協(xié)議),由于該 NDA 的限制,將很難寫出一本有關(guān)非文檔化信息的書 。
typedef NTSTATUS (NTAPI*NTPROC)();
typedef NTPROC* PNTPROC;
#define NTPROC_ sizeof(NTPROC)
typedef struct _SYSTEM_SERVICE_TABLE
{
PNTPROC ServiceTable; // array of entry points
PDOWRD CounterTable; // array of usage counters
DWord ServiceLimit; // number of table entries
PBYTE ArgumentTable; // array of byte counts
}
SYSTEM_SERVICE_TABLE,
*PSYSTEM_SERVICE_TABLE,
**PPSYSTEM_SERVICE_TABLE;
//-----------------------------------------------------------------------------------------------------------
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
SYSTEM_SERVICE_TABLE ntoskrnl; // ntoskrnl.exe ( native api )
SYSTEM_SERVICE_TABLE win32k; // win32k.sys (gdi/user support)
SYSTEM_SERVICE_TABLE Table3; // not used
SYSTEM_SERVICE_TABLE Table4; // not used
}
SYSTEM_DESCRIPTOR_TABLE,
*PSYSTEM_DESCRIPTOR_TABLE,
**PPSYSTEM_DESCRIPTOR_TABLE;
列表 2-1 系統(tǒng)服務(wù)描述符表的結(jié)構(gòu)定義
現(xiàn)在,回到 SDT ( Service Descriptor Table )的秘密上來 。從 列表 2-1 給出的該結(jié)構(gòu)的定義可看出該結(jié)構(gòu)的頭兩個數(shù)組保留給了 ntoskrnl.exe 和 Win32 子系統(tǒng)(位于 win32k.sys )中的內(nèi)核模式( kernel-mode )部分 。來自 gdi32.dll 和 user32.dll 的調(diào)用都通過 Win32k 的系統(tǒng)服務(wù)表( SST )進(jìn)行分派 。Ntolkrnl.exe 導(dǎo)出了一個指針(符號為 KeServiceDescriptorTable )指向其主服務(wù)描述符表( Main SDT ) 。內(nèi)核還維護(hù)了一個替代的 SDT,其名稱為: KeServiceDescriptorTableShadow,但這個 SDT 并沒有被導(dǎo)出 。從處于內(nèi)核模式的模塊中訪問主服務(wù)描述符表( SDT )非常容易,你只需要兩個 C 指令,如 列表 2-2 所示 。首先是由 extern 關(guān)鍵字修飾的變量說明,這告訴鏈接器該變量并不包含在此模塊中,而且不需要在鏈接時解析相應(yīng)的符號名稱 。當(dāng)該模塊被加載到進(jìn)程的地址空間后,針對該符號的引用才會動態(tài)連接到相應(yīng)的模塊中 。列表 2-2 中第二個 C 指令就是這樣的一個引用 。將類型為 PSERVER_DESCRIPTOR_TABLE 的變量賦值為 KeServiceDescriptorTable 時,就會和 ntoskrnl.exe 建立一個動態(tài)連接 。這很像調(diào)用一個 DLL 中的 API 函數(shù) 。

推薦閱讀