剖析Windows系統(tǒng)服務(wù)調(diào)用機(jī)制(中)

字號(hào):

四> Windows 2000系統(tǒng)服務(wù)調(diào)用機(jī)制
    Windows 2000的陷阱調(diào)度(Trap Dispatching)機(jī)制包括了:中斷(Interrupt),延遲過程調(diào)用(Deferred Procedure Call),異步過程調(diào)用(Asynchronous Procedure Call),異常調(diào)度(Exception Dispatching)和系統(tǒng)服務(wù)調(diào)用。在Intel x86的Windows 2000系統(tǒng)中,處理器執(zhí)行int 0x2e指令來激活Windows系統(tǒng)服務(wù)調(diào)用;在Intel x86的Windows XP系統(tǒng)中處理器卻是通過執(zhí)行sysenter指令使系統(tǒng)陷入系統(tǒng)服務(wù)調(diào)用程序中;而在AMD的Windows XP中使用了指令syscall來實(shí)現(xiàn)同樣的功能。我們暫時(shí)使用x86的Windows 2000為例來演示。我們先給出一個(gè)系統(tǒng)服務(wù)調(diào)用的模型:
    mov eax, ServiceId
    lea edx, ParameterTable
    int 2eh
    ret ParamTableBytes
    其中,ServiceId清楚的說明了傳遞給系統(tǒng)服務(wù)調(diào)用的系統(tǒng)服務(wù)號(hào),內(nèi)核使用這個(gè)標(biāo)識(shí)符來查找系統(tǒng)服務(wù)調(diào)度表(System Service Dispath Table)中的對(duì)應(yīng)系統(tǒng)服務(wù)信息。在系統(tǒng)服務(wù)調(diào)度表中的每一項(xiàng)包含了一個(gè)指向系統(tǒng)服務(wù)程序的指針,我們Hook時(shí)就是修改這個(gè)指針使其指向我們自定義的系統(tǒng)服務(wù)的地址。ParameterTable是傳遞的參數(shù),系統(tǒng)服務(wù)調(diào)用程序KiSystemService必須嚴(yán)格校驗(yàn)傳遞的每一個(gè)參數(shù),并將其參數(shù)從線程的用戶堆棧中復(fù)制到系統(tǒng)的核心堆棧以備使用。由于執(zhí)行int指令會(huì)導(dǎo)致陷阱發(fā)生,所以在Windows 2000內(nèi)的中斷描述表(IDT = Interrupt Descriptor Table)中的0x2e項(xiàng)指向了系統(tǒng)服務(wù)調(diào)用程序。最后返回的ParamTableBytes是關(guān)于參數(shù)個(gè)數(shù)的信息。
    現(xiàn)在我們已經(jīng)看得出來了,系統(tǒng)服務(wù)調(diào)用只是一個(gè)接口,它提供了將用戶模式下的請(qǐng)求轉(zhuǎn)發(fā)到Windows 2000內(nèi)核的功能,并引發(fā)處理器模式的切換。在用戶看來,系統(tǒng)服務(wù)調(diào)用接口就是Windows內(nèi)核組件功能實(shí)現(xiàn)對(duì)外的一個(gè)界面。系統(tǒng)服務(wù)調(diào)用接口定義了Windows內(nèi)核提供的大量服務(wù)。
    五> Windows 2000系統(tǒng)服務(wù)調(diào)用類型
    在Windows 2000中默認(rèn)存在兩個(gè)系統(tǒng)服務(wù)調(diào)度表,它們對(duì)應(yīng)了兩類不同的系統(tǒng)服務(wù)。這兩個(gè)系統(tǒng)服務(wù)調(diào)度表分別是:KeServiceDescriptorTable和KeServiceDescriptorTableShadow。
    Windows 2000執(zhí)行程序服務(wù)對(duì)應(yīng)于NTDLL.dll為我們提供的系統(tǒng)服務(wù)調(diào)用。子系統(tǒng)通過調(diào)用NTDLL.dll中的函數(shù)接口來實(shí)現(xiàn)它們需要的功能。系統(tǒng)服務(wù)調(diào)度表KeServiceDescriptorTable定義了在ntoskrln.exe中實(shí)現(xiàn)的系統(tǒng)服務(wù),通常在kernel32.dll/advapi32.dll中提供的函數(shù)接口均是調(diào)用的這個(gè)系統(tǒng)服務(wù)調(diào)度表中。
    同時(shí)存在于Windows 2000操作系統(tǒng)中還有在Win32k.sys中實(shí)現(xiàn)的相關(guān)Win32USER和GDI函數(shù),它們是屬于另一類系統(tǒng)服務(wù)調(diào)用。與之對(duì)應(yīng)的系統(tǒng)服務(wù)調(diào)度表為KeServiceDescriptorTableShadow,它提供了內(nèi)核模式實(shí)現(xiàn)的USER和GDI服務(wù)。函數(shù)KeAddSystemServiceTable允許Win32.sys和其他設(shè)備驅(qū)動(dòng)程序添加系統(tǒng)服務(wù)表。除了Win32k.sys服務(wù)表外,使用KeAddSystemServiceTable添加的服務(wù)表會(huì)被同時(shí)復(fù)制到KeServiceDescriptorTable和KeServiceDescriptorTableShadow中去。
    我們可以看出這兩類函數(shù)實(shí)現(xiàn)在服務(wù)調(diào)度上的區(qū)別:Win32內(nèi)核API經(jīng)過Kernel32.dll/advapi32.dll進(jìn)入NTDLL.dll后使用int 0x2e中斷進(jìn)入內(nèi)核,最后在Ntoskrnl.exe中實(shí)現(xiàn)了真正的函數(shù)調(diào)用;Win32 USER/GDI API直接通過User32.dll/Gdi32.dll進(jìn)入了內(nèi)核,最后卻是在Win32k.sys中實(shí)現(xiàn)了真正的函數(shù)調(diào)用。在此我們只討論與NTDLL.dll相關(guān)的函數(shù),也就是我們例子中處理的函數(shù)。
    六> Hook系統(tǒng)服務(wù)調(diào)用的作用
    鉤子(Hooking)是一種攔截/監(jiān)聽可執(zhí)行代碼在執(zhí)行過程中相關(guān)信息的一種通用機(jī)制。它使我們了解系統(tǒng)內(nèi)部結(jié)構(gòu),運(yùn)作機(jī)制甚至修改系統(tǒng)行為的想法成為可能。在一個(gè)像M$存在的世界里,Windows的很多內(nèi)部信息我們都是無法得知的,因?yàn)閃indows不是Linux,但這并不意味著我們就此放棄!只要開動(dòng)你的大腦,很多事情都會(huì)變成可能。
    1. 事件追蹤
    你想知道Windows在什么時(shí)候會(huì)打開一個(gè)進(jìn)程嗎?你想知道Windows任務(wù)管理器中進(jìn)程相關(guān)信息的獲取調(diào)用了哪些函數(shù)嗎?我們都可以使用Hook技術(shù)來實(shí)現(xiàn)這些你想要的信息。我們可以追蹤ZwOpenProcess的執(zhí)行情況,我們同樣也可以追蹤ZwQueryInformationProcess的執(zhí)行情況,包括傳遞的參數(shù)和返回的結(jié)果。大家可以看到本文相關(guān)的程序T-ProcMon就是一個(gè)進(jìn)程監(jiān)視工具,它會(huì)追蹤系統(tǒng)中與進(jìn)程相關(guān)的各種信息。在某些我們期望的事件發(fā)生時(shí),程序會(huì)通知用戶發(fā)生了什么,這也是我們期望看到的結(jié)果。
    2. 修改系統(tǒng)行為
    操作系統(tǒng)為我們提供了一些通用的功能,如查詢系統(tǒng)進(jìn)程信息ZwQuerySystemInformation(SystemInformationClass == 5),它會(huì)返回系統(tǒng)中當(dāng)前所有進(jìn)程/線程的相關(guān)信息。如果我們希望隱藏一些特殊的進(jìn)程那該怎么辦呢?那就是修改系統(tǒng)服務(wù)調(diào)用,也就是修改ZwQuerySystemInformation的行為。在查詢系統(tǒng)進(jìn)程時(shí),系統(tǒng)會(huì)返回一個(gè)進(jìn)程信息隊(duì)列,每個(gè)單元對(duì)應(yīng)一個(gè)進(jìn)程,如果我們想隱藏其中的某個(gè)進(jìn)程,只須修改隊(duì)列中的某些數(shù)據(jù),然后返回給上層函數(shù),它們就不會(huì)發(fā)現(xiàn)Xxx.exe進(jìn)程存在于系統(tǒng)之中了。