系統服務描述符表,system service dispatch table,ssdt
windows在核心層提供了兩張表,分別為ssdt(system service descriptor table,系統服務描述表)和shadow ssdt 。使用者層的api實現,實際是層簡單的包裝,最終都是轉到核心呼叫相應的api,然後執行完成後返回到使用者層的。而為了方便起見,所有使用者層的api呼叫都會轉到ssdt或者shadow ssdt這張表中,這樣就使不同的api呼叫不需要在核心編寫不同的呼叫規則,只需要轉到對應ssdt表中的位置就行了。關於這點可以在後面慢慢理解。
typedef struct servicedescriptorentry servicedescriptortableentry_t, *pservicedescriptortableentry_t;
keservicedescriptortable是由核心匯出的表。該錶擁有乙個指標(其實僅有ntoskrnel一項,沒有包含win32k),指向ssdt中包含由ntoskrnl.exe實現的核心系統服務的相應部分,它是核心的主要組成部分。
typedef struct _systemservicedescriptortable
pvoid servicetablebase;
pulong servicecountertablebase;
ulong numberofservice;
ulong paramtablebase;
}systemservicedescriptortable,*psystemservicedescriptortable;
其中ssdt包含了所有核心匯出函式的位址。每個位址長度為4個位元組。所以要獲得某個函式在ssdt中的偏移量,可以用:keservicedescriptortable->servicetablebase + 函式id* 4獲取。
那麼怎麼獲取函式id呢?
其實很簡單,ntoskrnl.exe匯出的zw*函式和nt*函式,大家肯定都注意到了很多函式都是同名的,只是字首不同。其實是這樣的,nt*函式是私有函式,其位址列於ssdt中。zw*函式是由核心為使用裝置驅動程式和其他核心元件而匯出的函式,目的就在於同過zw*函式去呼叫核心的nt函式。(ssdt中的每一項和每個zw*函式之間不存在一對一的對應關係)
核心中的所有zw*函式都以操作碼mov eax, ulong起始,其中ulong是系統呼叫在ssdt中的索引號。
說的具體點,就是每個zw*號函式的第一行中的 ulong值 就是其所對應的nt*函式在ssdt中的索引號。
舉個例子,如果我現在想獲取 ntopenprocess的id號,那麼就可以在windbg中執行 u zwopenprocess
u zwopenprocess
nt!zwopenprocess:
805016c4 b87a000000 mov eax,7ah
805016c9 8d542404 lea edx,[esp+4]
805016cd 9c pushfd
805016ce 6a08 push 8
805016d0 e88c0d0400 call nt!kisystemservice (80542461)
805016d5 c21000 ret 10h
獲取到的0x7a就是ntopenprocess在ssdt中的id號了。
ssdt函式索引號 乙個獲取系統服務索引號的小工具
好久沒寫部落格了,最近想抽點時間補上之前的東西,有些東西要記錄下來,以後看了會覺得很有意思。這個小工具沒有什麼可以說的,直接vc編譯連線就可以用了。下面附上 include stdio.h include int main printf 請輸入要獲得索引號的函式的名稱 n char apiname ...
019 讀出原函式位址 恢復 ssdt
include ntddk.h pragma pack 1 寫這個記憶體以一位元組對齊 如果不寫是以4位元組的對齊的 typedef struct servicedescriptorentry servicedescriptortableentry t,pservicedescriptortable...
X64ssdt 列舉函式偏移位址
emmmmm 這個其實 和windows x86差不多 這裡參考了 看雪論壇分享的 資料 作者是 tesla.angela gdut.hwl 下面是 include include pragma intrinsic readmsr typedef struct system service tabl...