[舊帖] [原創]檢測SSDT獲得hook rootkit驅動模組資訊
gjden發表於2010-02-11
檢測SSDT獲得hook rootkit驅動模組資訊
一直十分崇尚看雪裡的大牛們,很興奮的註冊了個會員,卻只是個臨時會員,小弟我當臨時會員好多年呀,這次也來跪求一下邀請碼,向看雪牛人靠近。
本人是初學者,高手飄過,如果不嫌髒的話,呵呵來坐坐,給我這個菜鳥點訓示。這是用C++寫的,在2000,xp,2003下透過,檢測SSDT獲取hook rootkit的核心模組的各項資訊(這裡只列出了全路徑檔名)。技術很古老了,網上也大堆相關的資料,原理很簡單,程式碼是我自己硬著頭皮從頭到尾全重寫的,編碼有點亂,不過還算是在各個版本上透過了。
首先,關於SSDT我都不介紹了,看雪上大牛們在n年前都講過了。但還是說說原理吧,也給和我一樣的菜鳥們拍拍磚。
我們要實現檢測透過hook SSDT 的rootkit, 首先必須解決如下幾個問題:
1. 如何找到SSDT的服務函式?
2. 如何判定這個服務函式是否被hook?
3. 如果這個服務函式被hook,那麼這個hook函式是屬於哪個驅動程式或rookit ?
現在我們來一個一個的解決。
第一個問題:在ntoskrnl.exe中匯出了一個指標變數KeServiceDescriptorTable,她是服務描述符表SERVICE_DESCRIPTOR_TABLE的地址,結構定義如下:
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
PVOID ServiceTableBase;
PULONG ServiceCounterTableBase;
ULONG NumberOfService;
ULONG ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE;
透過ServiceTableBase我們可以找到服務函式表的基地址,透過NumberOfService我們可以遍歷任何一個服務函式,呵呵就這麼簡單地解決了第一個問題。
第二個問題:根據我的觀察發現,在windows 2000, xp(sp1,sp2,sp3),2003(其他的沒有試過)下,SSDT中的服務函式地址開頭都是0x80xxxxxx形式的,其實核心模組ntoskrnl.exe和硬體抽象層hal.dll都是在0x80xxxxxx的虛擬地址空間中,而其他驅動程式都在0xfoxxxxxx的地址空間,當然rootkit的地址空間也無一例外(當然也有可能有例外)。因此服務函式地址被hook後的地址也在此0xfoxxxxxx的地址空間中。我們可以將第一步得到的地址進行判斷即可。其實含有另外一種通用的辦法,就是透過查詢系統模組資訊表項(接下來講到)來獲取各個模組的基地址和範圍來判斷。我把這種方法用在判斷地址所屬的具體模組上了。我只是覺得這種方法簡單,還比較快而已。
第三個問題:當我們發現了這個服務函式地址被hook後,就根據它來判斷是被哪個模組hook了。因此,我們要首先獲取所有的系統模組資訊,這裡我採用了比較簡單的方法,就是透過系統模組資訊表項來查詢模組,這裡涉及幾個結構, SYSTEM_MODULE_INFORMATION, SYSTEM_MODULE_INFORMATION_ENTRY和SYSTEM_INFORMATION_CLASS,它們分別是系統模組資訊,系統模組資訊和系統資訊類,定義在以下程式中。ntdll.dll匯出了一個函式是:NTSTATUS ZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
); 但在ntddk.h中未宣告,程式中自己宣告,這個東西我都不介紹了,因為都是老生常談的東東,免得人家笑話,呵呵。函式和變數的匯入在程式中(注意匯入時我加了個extern “c”,因為我的程式是.cpp檔案)。透過ZwQuerySystemInformation我們可以獲得一個緩衝區,緩衝區中的資訊就是系統模組資訊項的內容,不過前四個位元組是系統模組資訊項的個數。迴圈獲得系統模組資訊,根據模組的基地址和範圍來確定這個地址所屬的模組,並列印模組的全路徑。不多說了,貼出程式碼,結構定義比較長。
下面是標頭檔案的定義:(檔案:checkhook.h)
#ifdef __cplusplus
extern "C"
{
#endif
#include <NTDDK.h>
#ifdef __cplusplus
}
#endif typedef
//模組詳細資訊結構如下
struct _SYSTEM_MODULE_INFORMATION_ENTRY {
HANDLE Section;
PVOID MappedBase;
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT PathLength;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;
//systemModulInformation
typedef struct _SYSTEM_MODULE_INFORMATION {
ULONG Count;
SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
PVOID ServiceTableBase;
PULONG ServiceCounterTableBase;
ULONG NumberOfService;
ULONG ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE;
///////////////////////////////////////////////////////////
//systemInformationClass系統資訊類
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemBasicInformation, // 0 Y N
SystemProcessorInformation, // 1 Y N
SystemPerformanceInformation, // 2 Y N
SystemTimeOfDayInformation, // 3 Y N
SystemNotImplemented1, // 4 Y N
SystemProcessesAndThreadsInformation, // 5 Y N
SystemCallCounts, // 6 Y N
SystemConfigurationInformation, // 7 Y N
SystemProcessorTimes, // 8 Y N
SystemGlobalFlag, // 9 Y Y
SystemNotImplemented2, // 10 Y N
SystemModuleInformation, // 11 Y N
SystemLockInformation, // 12 Y N
SystemNotImplemented3, // 13 Y N
SystemNotImplemented4, // 14 Y N
SystemNotImplemented5, // 15 Y N
SystemHandleInformation, // 16 Y N
SystemObjectInformation, // 17 Y N
SystemPagefileInformation, // 18 Y N
SystemInstructionEmulationCounts, // 19 Y N
SystemInvalidInfoClass1, // 20
SystemCacheInformation, // 21 Y Y
SystemPoolTagInformation, // 22 Y N
SystemProcessorStatistics, // 23 Y N
SystemDpcInformation, // 24 Y Y
SystemNotImplemented6, // 25 Y N
SystemLoadImage, // 26 N Y
SystemUnloadImage, // 27 N Y
SystemTimeAdjustment, // 28 Y Y
SystemNotImplemented7, // 29 Y N
SystemNotImplemented8, // 30 Y N
SystemNotImplemented9, // 31 Y N
SystemCrashDumpInformation, // 32 Y N
SystemExceptionInformation, // 33 Y N
SystemCrashDumpStateInformation, // 34 Y Y/N
SystemKernelDebuggerInformation, // 35 Y N
SystemContextSwitchInformation, // 36 Y N
SystemRegistryQuotaInformation, // 37 Y Y
SystemLoadAndCallImage, // 38 N Y
SystemPrioritySeparation, // 39 N Y
SystemNotImplemented10, // 40 Y N
SystemNotImplemented11, // 41 Y N
SystemInvalidInfoClass2, // 42
SystemInvalidInfoClass3, // 43
SystemTimeZoneInformation, // 44 Y N
SystemLookasideInformation, // 45 Y N
SystemSetTimeSlipEvent, // 46 N Y
SystemCreateSession, // 47 N Y
SystemDeleteSession, // 48 N Y
SystemInvalidInfoClass4, // 49
SystemRangeStartInformation, // 50 Y N
SystemVerifierInformation, // 51 Y Y
SystemAddVerifier, // 52 N Y
SystemSessionProcessesInformation // 53 Y N
}SYSTEM_INFORMATION_CLASS;
//變數及函式定義如下:
extern "C" PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
extern "C" NTKERNELAPI //宣告ZwQuerySystemInformation匯出函式
NTSTATUS ZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
VOID Unload(IN PDRIVER_OBJECT DriverObject);
//檢測SSDT中被HOOK的函式及程式
void check();
//根據函式名取得模組資訊
VOID findModuleNameByAddress(PVOID address, BOOLEAN isDoubt);
下面就是程式碼了(檔案 CheckRootkit.cpp):
#extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING registryPath)
{
pDriver->DriverUnload=Unload;
check();
return STATUS_SUCCESS;
}
//檢測SSDT中是否有地址被hook了
void check()
{
ULONG32 *pBase=NULL;
ULONG32 i=0;
BOOLEAN isDoubt=FALSE;
//取得服務函式表基地址;
pBase=(ULONG32 *)KeServiceDescriptorTable->ServiceTableBase;
for (i=0;i<KeServiceDescriptorTable->NumberOfService;i++)
{
isDoubt=FALSE;
//如何高一位元組不為80的話,確定其為可疑(即已經被hook)
if ((pBase[i]>>24)!=0x80)
{
isDoubt=TRUE;
findModuleNameByAddress((PVOID)pBase[i],isDoubt);
}
}
}
VOID findModuleNameByAddress(PVOID address, BOOLEAN isDoubt)
{
ULONG32 i=0;
ULONG32 base=0;//模組基地址
ULONG32 end=0;//模組空間結束地址
ULONG32 currentAddress=(ULONG32)address;
ULONG cbBuffer = 0x10000; //要分配足夠多的空間
ULONG *pSize=NULL;
PVOID pBuffer=NULL;//返回緩衝
PSYSTEM_MODULE_INFORMATION pModuleInf;
pBuffer=ExAllocatePool(PagedPool,cbBuffer);
ZwQuerySystemInformation(SystemModuleInformation,
pBuffer,
cbBuffer,
NULL);
pModuleInf=(PSYSTEM_MODULE_INFORMATION)pBuffer;
for (i=0;i<pModuleInf->Count;i++)
{
base=(ULONG32)(pModuleInf->Module[i].Base);//當前模組基地址
end=(ULONG32)(base+pModuleI-
一直十分崇尚看雪裡的大牛們,很興奮的註冊了個會員,卻只是個臨時會員,小弟我當臨時會員好多年呀,這次也來跪求一下邀請碼,向看雪牛人靠近。
本人是初學者,高手飄過,如果不嫌髒的話,呵呵來坐坐,給我這個菜鳥點訓示。這是用C++寫的,在2000,xp,2003下透過,檢測SSDT獲取hook rootkit的核心模組的各項資訊(這裡只列出了全路徑檔名)。技術很古老了,網上也大堆相關的資料,原理很簡單,程式碼是我自己硬著頭皮從頭到尾全重寫的,編碼有點亂,不過還算是在各個版本上透過了。
首先,關於SSDT我都不介紹了,看雪上大牛們在n年前都講過了。但還是說說原理吧,也給和我一樣的菜鳥們拍拍磚。
我們要實現檢測透過hook SSDT 的rootkit, 首先必須解決如下幾個問題:
1. 如何找到SSDT的服務函式?
2. 如何判定這個服務函式是否被hook?
3. 如果這個服務函式被hook,那麼這個hook函式是屬於哪個驅動程式或rookit ?
現在我們來一個一個的解決。
第一個問題:在ntoskrnl.exe中匯出了一個指標變數KeServiceDescriptorTable,她是服務描述符表SERVICE_DESCRIPTOR_TABLE的地址,結構定義如下:
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
PVOID ServiceTableBase;
PULONG ServiceCounterTableBase;
ULONG NumberOfService;
ULONG ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE;
透過ServiceTableBase我們可以找到服務函式表的基地址,透過NumberOfService我們可以遍歷任何一個服務函式,呵呵就這麼簡單地解決了第一個問題。
第二個問題:根據我的觀察發現,在windows 2000, xp(sp1,sp2,sp3),2003(其他的沒有試過)下,SSDT中的服務函式地址開頭都是0x80xxxxxx形式的,其實核心模組ntoskrnl.exe和硬體抽象層hal.dll都是在0x80xxxxxx的虛擬地址空間中,而其他驅動程式都在0xfoxxxxxx的地址空間,當然rootkit的地址空間也無一例外(當然也有可能有例外)。因此服務函式地址被hook後的地址也在此0xfoxxxxxx的地址空間中。我們可以將第一步得到的地址進行判斷即可。其實含有另外一種通用的辦法,就是透過查詢系統模組資訊表項(接下來講到)來獲取各個模組的基地址和範圍來判斷。我把這種方法用在判斷地址所屬的具體模組上了。我只是覺得這種方法簡單,還比較快而已。
第三個問題:當我們發現了這個服務函式地址被hook後,就根據它來判斷是被哪個模組hook了。因此,我們要首先獲取所有的系統模組資訊,這裡我採用了比較簡單的方法,就是透過系統模組資訊表項來查詢模組,這裡涉及幾個結構, SYSTEM_MODULE_INFORMATION, SYSTEM_MODULE_INFORMATION_ENTRY和SYSTEM_INFORMATION_CLASS,它們分別是系統模組資訊,系統模組資訊和系統資訊類,定義在以下程式中。ntdll.dll匯出了一個函式是:NTSTATUS ZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
); 但在ntddk.h中未宣告,程式中自己宣告,這個東西我都不介紹了,因為都是老生常談的東東,免得人家笑話,呵呵。函式和變數的匯入在程式中(注意匯入時我加了個extern “c”,因為我的程式是.cpp檔案)。透過ZwQuerySystemInformation我們可以獲得一個緩衝區,緩衝區中的資訊就是系統模組資訊項的內容,不過前四個位元組是系統模組資訊項的個數。迴圈獲得系統模組資訊,根據模組的基地址和範圍來確定這個地址所屬的模組,並列印模組的全路徑。不多說了,貼出程式碼,結構定義比較長。
下面是標頭檔案的定義:(檔案:checkhook.h)
#ifdef __cplusplus
extern "C"
{
#endif
#include <NTDDK.h>
#ifdef __cplusplus
}
#endif typedef
//模組詳細資訊結構如下
struct _SYSTEM_MODULE_INFORMATION_ENTRY {
HANDLE Section;
PVOID MappedBase;
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT PathLength;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;
//systemModulInformation
typedef struct _SYSTEM_MODULE_INFORMATION {
ULONG Count;
SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
PVOID ServiceTableBase;
PULONG ServiceCounterTableBase;
ULONG NumberOfService;
ULONG ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE;
///////////////////////////////////////////////////////////
//systemInformationClass系統資訊類
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemBasicInformation, // 0 Y N
SystemProcessorInformation, // 1 Y N
SystemPerformanceInformation, // 2 Y N
SystemTimeOfDayInformation, // 3 Y N
SystemNotImplemented1, // 4 Y N
SystemProcessesAndThreadsInformation, // 5 Y N
SystemCallCounts, // 6 Y N
SystemConfigurationInformation, // 7 Y N
SystemProcessorTimes, // 8 Y N
SystemGlobalFlag, // 9 Y Y
SystemNotImplemented2, // 10 Y N
SystemModuleInformation, // 11 Y N
SystemLockInformation, // 12 Y N
SystemNotImplemented3, // 13 Y N
SystemNotImplemented4, // 14 Y N
SystemNotImplemented5, // 15 Y N
SystemHandleInformation, // 16 Y N
SystemObjectInformation, // 17 Y N
SystemPagefileInformation, // 18 Y N
SystemInstructionEmulationCounts, // 19 Y N
SystemInvalidInfoClass1, // 20
SystemCacheInformation, // 21 Y Y
SystemPoolTagInformation, // 22 Y N
SystemProcessorStatistics, // 23 Y N
SystemDpcInformation, // 24 Y Y
SystemNotImplemented6, // 25 Y N
SystemLoadImage, // 26 N Y
SystemUnloadImage, // 27 N Y
SystemTimeAdjustment, // 28 Y Y
SystemNotImplemented7, // 29 Y N
SystemNotImplemented8, // 30 Y N
SystemNotImplemented9, // 31 Y N
SystemCrashDumpInformation, // 32 Y N
SystemExceptionInformation, // 33 Y N
SystemCrashDumpStateInformation, // 34 Y Y/N
SystemKernelDebuggerInformation, // 35 Y N
SystemContextSwitchInformation, // 36 Y N
SystemRegistryQuotaInformation, // 37 Y Y
SystemLoadAndCallImage, // 38 N Y
SystemPrioritySeparation, // 39 N Y
SystemNotImplemented10, // 40 Y N
SystemNotImplemented11, // 41 Y N
SystemInvalidInfoClass2, // 42
SystemInvalidInfoClass3, // 43
SystemTimeZoneInformation, // 44 Y N
SystemLookasideInformation, // 45 Y N
SystemSetTimeSlipEvent, // 46 N Y
SystemCreateSession, // 47 N Y
SystemDeleteSession, // 48 N Y
SystemInvalidInfoClass4, // 49
SystemRangeStartInformation, // 50 Y N
SystemVerifierInformation, // 51 Y Y
SystemAddVerifier, // 52 N Y
SystemSessionProcessesInformation // 53 Y N
}SYSTEM_INFORMATION_CLASS;
//變數及函式定義如下:
extern "C" PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
extern "C" NTKERNELAPI //宣告ZwQuerySystemInformation匯出函式
NTSTATUS ZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
VOID Unload(IN PDRIVER_OBJECT DriverObject);
//檢測SSDT中被HOOK的函式及程式
void check();
//根據函式名取得模組資訊
VOID findModuleNameByAddress(PVOID address, BOOLEAN isDoubt);
下面就是程式碼了(檔案 CheckRootkit.cpp):
#extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING registryPath)
{
pDriver->DriverUnload=Unload;
check();
return STATUS_SUCCESS;
}
//檢測SSDT中是否有地址被hook了
void check()
{
ULONG32 *pBase=NULL;
ULONG32 i=0;
BOOLEAN isDoubt=FALSE;
//取得服務函式表基地址;
pBase=(ULONG32 *)KeServiceDescriptorTable->ServiceTableBase;
for (i=0;i<KeServiceDescriptorTable->NumberOfService;i++)
{
isDoubt=FALSE;
//如何高一位元組不為80的話,確定其為可疑(即已經被hook)
if ((pBase[i]>>24)!=0x80)
{
isDoubt=TRUE;
findModuleNameByAddress((PVOID)pBase[i],isDoubt);
}
}
}
VOID findModuleNameByAddress(PVOID address, BOOLEAN isDoubt)
{
ULONG32 i=0;
ULONG32 base=0;//模組基地址
ULONG32 end=0;//模組空間結束地址
ULONG32 currentAddress=(ULONG32)address;
ULONG cbBuffer = 0x10000; //要分配足夠多的空間
ULONG *pSize=NULL;
PVOID pBuffer=NULL;//返回緩衝
PSYSTEM_MODULE_INFORMATION pModuleInf;
pBuffer=ExAllocatePool(PagedPool,cbBuffer);
ZwQuerySystemInformation(SystemModuleInformation,
pBuffer,
cbBuffer,
NULL);
pModuleInf=(PSYSTEM_MODULE_INFORMATION)pBuffer;
for (i=0;i<pModuleInf->Count;i++)
{
base=(ULONG32)(pModuleInf->Module[i].Base);//當前模組基地址
end=(ULONG32)(base+pModuleI-
相關文章
- 原創文章檢測工具,原創文章檢測軟體,檢測文章相似度2020-06-15
- [原創]移遠RM500U-CN模組驅動移植2022-07-16
- 原創文章檢測工具,檢測原創文章,過不了原創賬號的原因在這2020-06-29
- 求助帖:JMeter 介面自動化測試——資料驅動2020-05-06JMeter
- Arduino 驅動火焰感測器模組2024-07-02UI
- 文章相似度檢測,相似度檢測工具,原創度檢測工具2020-06-10
- 敏捷聯盟Gordon Pask獎獲得者講“測試驅動開發”(TDD)2010-07-22敏捷Go
- Arduino 驅動煙霧感測器模組2024-07-02UI
- 原創度檢測工具哪個好?文章原創度檢測軟體是這樣提高原創度的2020-06-12
- 免費文章原創度檢測工具2020-06-23
- win10驅動檢測操作方法_win10怎麼檢測驅動是否正常2020-07-30Win10
- 【實驗】【檢視】使用v$bgprocess檢視獲得所有後臺程式資訊2009-08-08
- 【原創】Linux PCI驅動框架分析(一)2020-12-20Linux框架
- 【原創】Linux PCI驅動框架分析(二)2020-12-29Linux框架
- java 獲得系統資訊2005-01-26Java
- linux驅動之獲取裝置樹資訊2021-07-15Linux
- 業務驅動創新,傳統IDC如何破局舊有業務模式?2020-12-09模式
- [原創]發一個批量檢測xcode ghost病毒的檢測工具2015-09-19XCode
- ModStartCMS模組化萬能建站系統v3.2.0 相容環境檢測 自動稽核驅動2022-02-11
- Arduino 驅動模擬溫度感測器模組2024-07-02UI
- 文章原創度檢測工具,可以讓自媒體賬號過原創嗎?2020-06-29
- 文章原創度檢測軟體,增加你原創賬號透過機率2020-06-08
- [轉帖]利用WebClient和WebRequest類獲得網頁原始碼2005-08-19Webclient網頁原始碼
- WindowsXP安裝舊驅動三妙方(轉)2007-08-10Windows
- python自動化測試-原創2020-11-25Python
- Linux下基於記憶體分析的Rootkit檢測方法2020-08-19Linux記憶體
- 用Java獲得當前效能資訊2008-05-01Java
- 檢測文章原創度的軟體哪個好用?2020-06-16
- ABAP 從檢視獲得資料2021-01-27
- 完美獲得SAS檢視原始碼2009-07-03原始碼
- Helloworld 驅動模組載入2022-05-21
- 為什麼驅動精靈檢測不到獨立顯示卡_驅動精靈檢測不到獨立顯示卡解決步驟2020-07-19
- 【原創】對Rav
2005中HOOK的初步分析2004-12-07Hook
- 【原創】erlang模組之rpc2016-05-12RPC
- Apache 的資訊檢視模組(轉)2007-08-09Apache
- 自媒體原創度檢測工具,教你怎麼修改原創度不高的語句2020-06-08
- [原創]淺談移動App安全測試2014-07-15APP
- 21年-25年美國創作者獲得社交媒體訂閱收入及同比預測(附原資料表) 2024-11-16