當系統載入一個驅動時,會為這個驅動建立一個_KLDR_DATA_TABLE_ENTRY結構體,DRIVER_OBJECT結構體的DriverSection成員指向這個結構體。以下是WRK中_KLDR_DATA_TABLE_ENTRY結構體的定義:
typedef struct _KLDR_DATA_TABLE_ENTRY {
LIST_ENTRY InLoadOrderLinks;
PVOID ExceptionTable;
ULONG ExceptionTableSize;
// ULONG padding on IA64
PVOID GpValue;
PNON_PAGED_DEBUG_INFO NonPagedDebugInfo;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT __Unused5;
PVOID SectionPointer;
ULONG CheckSum;
// ULONG padding on IA64
PVOID LoadedImports;
PVOID PatchInformation;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;
其中 PVOID DllBase; 成員指明了驅動的載入基址;
UNICODE_STRING FullDllName;指明了驅動.sys檔的全路徑;
所有驅動的結構體通過InLoadOrderLinks成員連結起來,鏈表頭部為PsLoadedModuleList,因此可以通過遍歷PsLoadedModuleList來得到所有載入的驅動。
在測試中發現,如果將某一驅動的DllBase或FullDllName.buffer填為0,那麼XueTr就不會顯示這個驅動,以下是將DllBase填0時的驗證代碼:
#include <ntddk.h>
//偷懶版,完整版定義見WRK的_KLDR_DATA_TABLE_ENTRY
typedef struct _LDR_DATA_TABLE_ENTRY {
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
}LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY;
PVOID pDllBase;
VOID Reinitialize( PDRIVER_OBJECT DriverObject, PVOID Context, ULONG Count )
{
((PLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection)->DllBase = NULL;//將DllBase填0
}
void testUnload(IN PDRIVER_OBJECT DriverObject)
{
((PLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection)->DllBase = pDllBase;//恢復DllBase,以便驅動能順利卸載
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
DriverObject->DriverUnload = testUnload;
pDllBase = ((PLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection)->DllBase;
IoRegisterDriverReinitialization(DriverObject,Reinitialize,NULL);
return STATUS_SUCCESS;
}
用InstDrv.exe載入編譯後的驅動test.sys,依次點擊安裝、啟動,然後用XueTr查看“驅動模組”,裡面沒有test.sys;用IceSword.exe 1.22查看“內核模組”,可以看到test.sys的存在。
以下是將FullDllName.buffer填為0時的驗證代碼:
/*
* 【作者:KiDebug】
* 【空間:http://hi.baidu.com/KiDebug/】
*/
#include <ntddk.h>
//偷懶版,完整版定義見WRK的_KLDR_DATA_TABLE_ENTRY
typedef struct _LDR_DATA_TABLE_ENTRY {
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
}LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY;
void testUnload(IN PDRIVER_OBJECT DriverObject)
{
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
DriverObject->DriverUnload = testUnload;
((PLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection)->FullDllName.Buffer=NULL;
return STATUS_SUCCESS;
}
先用InstDrv.exe載入編譯後的驅動test.sys,依次點擊安裝、啟動,然後按兩下打開IceSword.exe 1.22,提示“程式初始化失敗,錯誤代碼1”,然後提示“無法初始化,程式退出”;按兩下打開PowerTool.exe 3.6.2,藍屏。
打開XueTr.exe 0.39,查看“驅動模組”,顯示有可疑驅動的存在,如果在WinDBG中手動將ntkrnlpa.exe對應的FullDllName.buffer填為0,XueTr不會顯示ntkrnlpa.exe的存在。
濃縮版:
1:DllBase填0,無可疑驅動
2:FullDllName.buffer填0,有可疑驅動
3:XueTr 0.39
4:沒有建立DeviceObject
沒有留言:
張貼留言