3. 研究系統(tǒng)內部機制
微軟提供的Windows操作系統(tǒng)是一個“封閉”的系統(tǒng),很多內部資料都沒有公布,我們可以通過Hook技術來探測系統(tǒng)的內部數(shù)據(jù)結構和運行機制,學習操作系統(tǒng)內部的操作方式?;贖ook的Windows內核黑客技術(Kernel Hacking)是非常之流行和有效,在我們探測系統(tǒng)的一些未公開,未文檔化的技術細節(jié)時我們都可以使用鉤子技術。
4. 其他
其他如我們要調試一個非常麻煩的程序時就可以使用Hook技術,這樣就可以更好的幫助我們追蹤系統(tǒng)的行動,更好的了解程序內部的執(zhí)行過程。同樣,為了獲取系統(tǒng)的一些特殊性能數(shù)據(jù),我們也可以在特定的情況下使用Hook技術。
七> Hook系統(tǒng)服務調用的實現(xiàn)
在此我們討論Hook的對象僅限于由Windows 2000的ntoskrnl.exe提供的系統(tǒng)服務調用。Windows 2000系統(tǒng)服務調用為內核模式的代碼,所以我們必須書寫設備驅動程序來訪問系統(tǒng)服務調度表。如果你對Windows 2000下基本設備驅動程序的書寫不太清楚,請查閱相關的書籍,此處不做介紹。我們先回顧一下Win32內核API的實現(xiàn)流程。
Windows 2000系統(tǒng)服務調用向用戶提供了經(jīng)過包裝的用戶模式的函數(shù)接口(由NTDLL.dll提供)。當Kernel32.dll/Advapi32.dll中的函數(shù)執(zhí)行時,先調用NTDLL.dll中對應的相關接口,經(jīng)過參數(shù)檢查后使用int 0x2e指令進入內核模式,傳遞相關的服務號和參數(shù)列表。在ntoskrnl.exe中維護著兩個表系統(tǒng)服務調度表(System Service Dispath Table)和系統(tǒng)服務參數(shù)表(System Service Parameter Table),其中int 0x2e指令就是通過服務號在SSDT中查詢相關系統(tǒng)服務程序指針的?,F(xiàn)在我們已經(jīng)清楚了每個系統(tǒng)服務調用都對應一個服務號,同時也對應一個服務程序的地址!如果我們修改SSDT中的某個系統(tǒng)服務程序的入口地址為指向我們自定義的函數(shù)地址,在執(zhí)行完我們的代碼后再執(zhí)行原始系統(tǒng)服務地址處的代碼,這不就實現(xiàn)了對系統(tǒng)服務調用的了Hook嗎?
對我們來說,定位系統(tǒng)服務調度表是實現(xiàn)Hook的關鍵。在Windows 2000中有一個未公開的由ntoskrnl.exe導出的單元:KeServiceDescriptorTable,我們可以通過它來完成對SSDT的訪問與修改。KeServiceDescriptorTable對應于一個數(shù)據(jù)結構,定義如下:
typedef struct SystemServiceDescriptorTable
{
UINT *ServiceTableBase;
UINT *ServiceCounterTableBase;
UINT NumberOfService;
UCHAR *ParameterTableBase;
}SystemServiceDescriptorTable,*PSystemServiceDescriptorTable;
其中ServiceTableBase指向系統(tǒng)服務程序的地址,ParameterTableBase則指向SSPT中的參數(shù)地址,它們都包含了NumberOfService這么多個單元。我們只要由KeServiceDescriptorTable找到了我們關注的系統(tǒng)服務調用程序,就可以修改它的ServiceTableBase參數(shù)來實現(xiàn)對相關系統(tǒng)服務調用的Hook了!
八> T-ProcMon-1.0 關鍵源碼分析
1. 基于CUI的用戶模式控制程序
由于在此之前我已經(jīng)對Win32的系統(tǒng)服務進行了詳細的介紹,現(xiàn)在就不做多說了,大家如果有什么疑問請參閱我以前寫的文章,你可以到FZ5FZ的主頁(http://www.fz5fz.org/)閱讀相關文章,或下載相關源代碼。
2. 基于設備驅動的Hook代碼
定義在用戶模式與內核模式程序間通信的命令代碼:
#define PROCMON_MONITOR (ULONG) CTL_CODE(FILE_DEVICE_PROCMON,0x01,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define PROCMON_HIDDEN (ULONG) CTL_CODE(FILE_DEVICE_PROCMON,0x02,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define PROCMON_HOOK (ULONG) CTL_CODE(FILE_DEVICE_PROCMON,0x03,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define PROCMON_UNHOOK (ULONG) CTL_CODE(FILE_DEVICE_PROCMON,0x04,METHOD_BUFFERED,FILE_ANY_ACCESS)
將KeServiceDescriptorTable與相關數(shù)據(jù)結構聯(lián)系起來,定義系統(tǒng)調用:
__declspec(dllimport) ServiceDescriptorTableEntry KeServiceDescriptorTable;
#define SYSCALL(_function) KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function+1)]
微軟提供的Windows操作系統(tǒng)是一個“封閉”的系統(tǒng),很多內部資料都沒有公布,我們可以通過Hook技術來探測系統(tǒng)的內部數(shù)據(jù)結構和運行機制,學習操作系統(tǒng)內部的操作方式?;贖ook的Windows內核黑客技術(Kernel Hacking)是非常之流行和有效,在我們探測系統(tǒng)的一些未公開,未文檔化的技術細節(jié)時我們都可以使用鉤子技術。
4. 其他
其他如我們要調試一個非常麻煩的程序時就可以使用Hook技術,這樣就可以更好的幫助我們追蹤系統(tǒng)的行動,更好的了解程序內部的執(zhí)行過程。同樣,為了獲取系統(tǒng)的一些特殊性能數(shù)據(jù),我們也可以在特定的情況下使用Hook技術。
七> Hook系統(tǒng)服務調用的實現(xiàn)
在此我們討論Hook的對象僅限于由Windows 2000的ntoskrnl.exe提供的系統(tǒng)服務調用。Windows 2000系統(tǒng)服務調用為內核模式的代碼,所以我們必須書寫設備驅動程序來訪問系統(tǒng)服務調度表。如果你對Windows 2000下基本設備驅動程序的書寫不太清楚,請查閱相關的書籍,此處不做介紹。我們先回顧一下Win32內核API的實現(xiàn)流程。
Windows 2000系統(tǒng)服務調用向用戶提供了經(jīng)過包裝的用戶模式的函數(shù)接口(由NTDLL.dll提供)。當Kernel32.dll/Advapi32.dll中的函數(shù)執(zhí)行時,先調用NTDLL.dll中對應的相關接口,經(jīng)過參數(shù)檢查后使用int 0x2e指令進入內核模式,傳遞相關的服務號和參數(shù)列表。在ntoskrnl.exe中維護著兩個表系統(tǒng)服務調度表(System Service Dispath Table)和系統(tǒng)服務參數(shù)表(System Service Parameter Table),其中int 0x2e指令就是通過服務號在SSDT中查詢相關系統(tǒng)服務程序指針的?,F(xiàn)在我們已經(jīng)清楚了每個系統(tǒng)服務調用都對應一個服務號,同時也對應一個服務程序的地址!如果我們修改SSDT中的某個系統(tǒng)服務程序的入口地址為指向我們自定義的函數(shù)地址,在執(zhí)行完我們的代碼后再執(zhí)行原始系統(tǒng)服務地址處的代碼,這不就實現(xiàn)了對系統(tǒng)服務調用的了Hook嗎?
對我們來說,定位系統(tǒng)服務調度表是實現(xiàn)Hook的關鍵。在Windows 2000中有一個未公開的由ntoskrnl.exe導出的單元:KeServiceDescriptorTable,我們可以通過它來完成對SSDT的訪問與修改。KeServiceDescriptorTable對應于一個數(shù)據(jù)結構,定義如下:
typedef struct SystemServiceDescriptorTable
{
UINT *ServiceTableBase;
UINT *ServiceCounterTableBase;
UINT NumberOfService;
UCHAR *ParameterTableBase;
}SystemServiceDescriptorTable,*PSystemServiceDescriptorTable;
其中ServiceTableBase指向系統(tǒng)服務程序的地址,ParameterTableBase則指向SSPT中的參數(shù)地址,它們都包含了NumberOfService這么多個單元。我們只要由KeServiceDescriptorTable找到了我們關注的系統(tǒng)服務調用程序,就可以修改它的ServiceTableBase參數(shù)來實現(xiàn)對相關系統(tǒng)服務調用的Hook了!
八> T-ProcMon-1.0 關鍵源碼分析
1. 基于CUI的用戶模式控制程序
由于在此之前我已經(jīng)對Win32的系統(tǒng)服務進行了詳細的介紹,現(xiàn)在就不做多說了,大家如果有什么疑問請參閱我以前寫的文章,你可以到FZ5FZ的主頁(http://www.fz5fz.org/)閱讀相關文章,或下載相關源代碼。
2. 基于設備驅動的Hook代碼
定義在用戶模式與內核模式程序間通信的命令代碼:
#define PROCMON_MONITOR (ULONG) CTL_CODE(FILE_DEVICE_PROCMON,0x01,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define PROCMON_HIDDEN (ULONG) CTL_CODE(FILE_DEVICE_PROCMON,0x02,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define PROCMON_HOOK (ULONG) CTL_CODE(FILE_DEVICE_PROCMON,0x03,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define PROCMON_UNHOOK (ULONG) CTL_CODE(FILE_DEVICE_PROCMON,0x04,METHOD_BUFFERED,FILE_ANY_ACCESS)
將KeServiceDescriptorTable與相關數(shù)據(jù)結構聯(lián)系起來,定義系統(tǒng)調用:
__declspec(dllimport) ServiceDescriptorTableEntry KeServiceDescriptorTable;
#define SYSCALL(_function) KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function+1)]

