SSDT知識點

0x00 Hook技術

hook技術分為兩塊:

  • Ring3層的Hook,俗稱應用層hook技術
  • Ring0層的Hook,俗稱內核層Hook技術

Ring3層的hook又分為兩種類型

  • Windows消息的hook
  • WindowsAPI的hook

如下圖所示:

hook1
hook2
hook1

關于Windows消息的Hook,相信很多朋友都有接觸過的,因為一個SetWindowsHookEx即可以完成消息 Hook,在這里簡要介紹一下消息 Hook,消息 Hook 是通過SetWindowsHookEx可以實現將自己的鉤子插入到鉤子鏈的最前端,而對于發送給被 Hook 的窗口(也有可能是所有的窗口,即全局 Hook)的消息都會被我們的鉤子處理函數所捕獲到,也就是我們可以優先于窗體先捕獲到這些消息,Windows 消息 Hook 可以實現為進程內消息 Hook 和全局消息 Hook,對于進程內消息 Hook,則可以簡單的將 Hook 處理函數直接寫在這個進程內,即是自己 Hook 自己,而對于用途更為廣泛的全局消息 Hook,則需要將 Hook 處理函數寫在一個 DLL 中,這樣才可以讓你的處理函數被所有的進程所加載(進程自動加載包含 Hook 消息處理函數的 DLL)。

對于 Windows 消息 Hook 呢,可以有個簡單的邪惡應用,就是記錄鍵盤按鍵消息,從而達到監視用戶輸入的鍵值信息的目的,這樣,對于一些簡單的用戶通過鍵盤輸入的密碼就可以被 Hook 獲取到,因為沒當用戶按下一個鍵時,Windows 都會產生一個按鍵消息(當然有按下,彈起等消息的區分),然后我們可以 Hook 到這個按鍵消息,這樣就可以在 Hook 的消息處理函數中獲取到用戶按下的是什么鍵了。

不過消息的hook不是本文的重點。

本文要講的SSDT hook呢其實是屬于內核Hook,常見于病毒以及殺軟中。

下圖展示了內核hook的幾個基本類型。

Kernel hook

0x01 SSDT簡介

SSDT全稱System Service Descriptor Table(系統描述符表),這個表用于將Ring3的Win32API和內核的API聯系起來。

SSDT并不僅僅只包含一個龐大的地址索引表,它還包含一些有用的信息,如地址索引的基地址,服務函數的個數等。通過修改此表可以達到對一些關心的系統動作進行過濾以及監控的目的。

在NT4.0的windows操作系統中,默認存在兩個系統服務描述符表,這兩個描述符表對應了兩類不同的系統服務,這兩個表為:KeServiceDescriptorTable(SSDT)和KeServiceDescriptorTable(SSDT Shadow)。其中SSDT負責處理來自Ring3層的Kernel32.dll的系統調用。而SSDT Shadow則主要處理來自User32.dll和GDI32.dll的系統調用。同時SSDT在ntoskrnl.exe中是導出的,而SSDT Shadow如其名是未被Windows所導出的,而關于SSDT的全部內容都是通KeServiceDescriptorTable來完成的。

以下截圖說明,KeServiceDescriptorTable是在ntoskrnl.exe中被導出的:

Export1

隨后我們看看看看Windows操作系統的源碼中如何定義KeServiceDescriptorTable的,通過觀察WRK可知,

KeServiceDescriptorTable in WRK

這么看還是有點蛋疼啊。改寫以下變量的名稱吧。

    typedef struct _KSYSTEM_SERVICE_TABLE{
        PULONG ServiceTableBase;            //SSDT的基地址指針
        PULONG ServiceCounterTableBase; //SSDT中每個服務被調用次數表的基地址指針
        ULONG NumberOfService;              //服務函數個數,NumberOfService*4就是整個地址表的大小
        ULONG ParamTableBase;               //SSPT的基地址
    }KSYSTEM_SERVICE_TABLE,*PKSYSTEM_SERVICE_TABLE;
    typedef struct _KSERVICE_TABLE_DESCRIPTOR{
        KSYSTEM_SERVICE_TABLE ntoskrnl;     //ntoskrnl.exe的服務函數
        KSYSTEM_SERVICE_TABLE win32k;       //win32k.sys的服務函數(GDI32/User32)
        KSYSTEM_SERVICE_TABLE notUsed1;
        KSYSTEM_SERVICE_TABLE notUsed2;
    }KSERVICE_TABLE_DESCRIPTOR,*PKSERVICE_TABLE_DESCRIPTOR;
    //導出由ntoskrnl.exe所導出的SSDT
    extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;

從上述介紹可知,KeServiceDescriptorTable可以看做是一個數組,是4個KSYSTEM_SERVICE_TABLE結構形成的數組,而每個KSYSTEM_SERVICE_TABLE對應一個PE文件導出的服務描述符表,根據這些服務描述符表我們可以獲得更加詳細的服務信息。在應用層ntdll.dll中的API在這個系統服務描述表中都存在一個與之對應的服務,當我們的應用程序調用ntdll.dll里的API時最終可以調用對應的系統服務函數,通知給內核一個索引,內核通過該索引在SSDT中查找對應的服務,內核調用服務完成應用的API調用請求。

應用層調用Win32API流程

有了以上的SSDT基礎后,我們再來看看在應用層調用Win32API(主要指ntdll.dll中的API)的流程,我們主要針對ntdll.dll中的NtQuerySystemInformation這個API的調用流程來進行闡述。

這里存在四個類似的API。

4APIs

再給出這些API的調用流程。

calling way

這里我們可以看到ntdll.dll中的nt和zw都會進入內核層去調用ntoskrnl的zw函數,而zw最終會調用nt函數,這個函數作為內核API最終去請求系統服務的執行。
用exescope工具可以打開ntdll.dll,看到NtQuerySystemInformation以及ZwQuerySystemInformation。

ntdll1

ntdll2

而實質上zw和nt都是同一函數,指向同一區域,入口地址相同。

因此Ntdll.dll中的API都是對內核API的封裝,當Kernel32.dll中的API通過Ntdll.dll去調用系統API時,會進行參數檢查,并調用中斷(int 2Eh或SysEnter),從而從Ring3進入Ring0,并將所要調用的服務號,即SSDT數組的索引值,存放進寄存器EAX中,并且將參數地址放到指定的寄存器EDX中,再復制參數到內核地址空間,根據存放在EAX中的索引值來在SSDT數組中調用指定的服務。

經過上面步驟我們來到Ring0層。使用exescope看看ntoskrnl.exe中的ZwQuerySystemInformation以及NtQuerySystemInformation。

ntoskrnl1
ntoskrnl2

再反匯編ntoskrnl這個文件可以看到Zw函數中調用KiSystemService系統服務分發函數時往EAX中存放了索引號ADh。如圖:

ZwQSystemInfor

隨后根據該索引值檢索SSDT項,最后根據該SSDT項中所存放的系統服務地址來調用這個系統服務。在這里就是調用KeServiceDescriptorTable[ADh]處保存的地址對應的系統服務。那就是Ring0下的NtQuerySystemInformation。

0x02 詳解SSDT

這節內我們用WinDbg來調試XP系統,借此說明SSDT是個什么鬼。
據我們上文的結構定義可知,KeServiceDescriptorTable是一個指向4個KSYSTEM_SERVICE_TABLE結構首地址的指針,以下圖為例吧。

dd KeServiceDescriptorTable

這里的0x80563520這一行就是ntoskrnl對應的服務描述符表結構KSYSTEM_SERVICE_TABLE。那么第一個32位的0x804e58a0則是對應ntoskrnl對應的KSYSTEM_SERVICE_TABLE中的SSDT Base,即服務描述符表的首地址。通過對該首地址的dump,我們可以看到許多以128位為一組排列的服務描述符,每個描述符中的第一個32位(0x80591bfb)對應著系統服務的入口地址。通過對該入口地址的反匯編,可以看到這是SSDT第一個系統服務NtAcceptConnectPort函數。如圖:

NtAcceptConnectPort

那么知道了SSDT首地址,同時知道了索引,那么我們就可以通過索引來找到對應的系統服務入口地址了。通過計算“SSDT中系統服務地址所在的地址 = SSDT首地址 + 4 * 索引值”,可以推算出NtQuerySystemInformation的起始地址位0x80586ff1,對該地址進行反匯編,可得下圖:

NtQuerySystemInformation

由此可知,SSDT就是個保存Windows系統服務地址的數組。

0x03 SSDT hook原理

從上面的分析中我們可以看到SSDT數組中保存了系統服務的地址,如Ring0下的NtQuerySystemInformation系統服務地址,就保存在KeServiceDescriptorTable[ADh]中,既然hook就是取出這個地址后替換上我們的hook函數,在hook函數中執行原函數即可。

參考文獻:

http://www.cnblogs.com/boyxiao/archive/2011/09/03/2164574.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,622評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,716評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,746評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,991評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,706評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,036評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,029評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,203評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,725評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,451評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,677評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,161評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,857評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,266評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,606評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,407評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,643評論 2 380

推薦閱讀更多精彩內容

  • 一、溫故而知新 1. 內存不夠怎么辦 內存簡單分配策略的問題地址空間不隔離內存使用效率低程序運行的地址不確定 關于...
    SeanCST閱讀 7,865評論 0 27
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,836評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,775評論 25 708
  • 1. 結構體和共同體的區別。 定義: 結構體struct:把不同類型的數據組合成一個整體,自定義類型。共同體uni...
    breakfy閱讀 2,138評論 0 22
  • 我不是 注定和這黑夜 分不出彼此 如果藍色就是憂郁 在海邊我就要死死把你抱住
    薩先生閱讀 256評論 0 0