日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SSDT Hook的妙用-对抗ring0 inline hook

發布時間:2024/4/11 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SSDT Hook的妙用-对抗ring0 inline hook 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

*******************************************************
*
標題:【原創】SSDT?Hook的妙用-對抗ring0?inline?hook??*
*
作者:墮落天才????????????????????????????????????????*
*
日期:2007310???????????????????????????????????*
*
聲明:本文章的目的僅為技術交流討論????????????????????*
*******************************************************

1,SSDT
?????SSDT
即系統服務描述符表,它的結構如下(參考《Undocument?Windows?2000?Secretes》第二章):
?????typedef?struct?_SYSTEM_SERVICE_TABLE
?????{
???????PVOID???ServiceTableBase;????????//
這個指向系統服務函數地址表
???????PULONG??ServiceCounterTableBase;
???????ULONG???NumberOfService;?????????//
服務函數的個數,NumberOfService*4?就是整個地址表的大小
???????ULONG???ParamTableBase;
?????}SYSTEM_SERVICE_TABLE,*PSYSTEM_SERVICE_TABLE;???
?????
?????typedef?struct?_SERVICE_DESCRIPTOR_TABLE
?????{
???????SYSTEM_SERVICE_TABLE???ntoskrnel;??//ntoskrnl.exe
的服務函數
???????SYSTEM_SERVICE_TABLE???win32k;?????//win32k.sys
的服務函數,(gdi.dll/user.dll的內核支持)
???????SYSTEM_SERVICE_TABLE???NotUsed1;
???????SYSTEM_SERVICE_TABLE???NotUsed2;
?????}SYSTEM_DESCRIPTOR_TABLE,*PSYSTEM_DESCRIPTOR_TABLE;
?????
?????
內核中有兩個系統服務描述符表,一個是KeServiceDescriptorTable(ntoskrnl.exe導出),一個是?KeServieDescriptorTableShadow(沒有導出)。兩者的區別是,KeServiceDescriptorTable僅有?ntoskrnel一項,KeServieDescriptorTableShadow包含了ntoskrnel以及win32k。一般的?Native?API的服務地址由KeServiceDescriptorTable分派,gdi.dll/user.dll的內核API調用服務地址由?KeServieDescriptorTableShadow分派。還有要清楚一點的是win32k.sys只有在GUI線程中才加載,一般情況下是不加 載的,所以要Hook?KeServieDescriptorTableShadow的話,一般是用一個GUI程序通過IoControlCode來觸發?(想當初不明白這點,藍屏死機了N次都想不明白是怎么回事)
?
?2
SSDT?HOOK?
????SSDT?HOOK?
的原理其實非常簡單,我們先實際看看KeServiceDescriptorTable是什么樣的。????
????lkd>?dd?KeServiceDescriptorTable
????8055ab80??804e3d20?00000000?0000011c?804d9f48
????8055ab90??00000000?00000000?00000000?00000000
????8055aba0??00000000?00000000?00000000?00000000
????8055abb0??00000000?00000000?00000000?00000000???
????
windbg.exe中我們就看得比較清楚,KeServiceDescriptorTable中就只有第一項有數據,其他都是0。其中804e3d20就是
KeServiceDescriptorTable.ntoskrnel.ServiceTableBase
,服務函數個數為0x11c個。我們再看看804e3d20地址里是什么東西:
????lkd>?dd?804e3d20
????804e3d20??80587691?805716ef?8057ab71?80581b5c
????804e3d30??80599ff7?80637b80?80639d05?80639d4e
????804e3d40??8057741c?8064855b?80637347?80599539
????804e3d50??8062f4ec?8057a98c?8059155e?8062661f
????
如上,80587691?805716ef?8057ab71?80581b5c?這些就是系統服務函數的地址了。比如當我們在ring3調用?OpenProcess時,進入sysenterID0x7A(XP?SP2),然后系統查KeServiceDescriptorTable,大概 是這樣?KeServiceDescriptorTable.ntoskrnel.ServiceTableBase(804e3d20)?+?0x7A?*?4?=?804E3F08,?然后804E3F08?->8057559e?這個就是OpenProcess系統服務函數所在,我們再跟蹤看看:
????lkd>?u?8057559e
????nt!NtOpenProcess:
????8057559e?68c4000000??????push????0C4h
????805755a3?6860b54e80??????push????offset?nt!ObReferenceObjectByPointer+0x127?(804eb560)
????805755a8?e8e5e4f6ff??????call????nt!InterlockedPushEntrySList+0x79?(804e3a92)
????805755ad?33f6????????????xor?????esi,esi
????
原來8057559e就是NtOpenProcess函數所在的起始地址。??
????
嗯,如果我們把8057559e改為指向我們函數的地址呢?比如?MyNtOpenProcess,那么系統就會直接調用MyNtOpenProcess,而不是原來的NtOpenProcess了。這就是SSDT?HOOK?原理所在。

??3,?ring0?inline?hook
?????ring0?inline?hook?
ring3的沒什么區別了,如果硬說有的話,那么就是ring3發生什么差錯的話程序會掛 掉,ring0發生什么差錯的話系統就掛掉,所以一定要很小心。inline?hook的基本思想就是在目標函數中JMP到自己的監視函數,做一些判斷然 后再JMP回去。一般都是修改函數頭,不過再其他地方JMP也是可以的。下面我們來點實際的吧:
?????lkd>?u?nt!NtOpenProcess
?????nt!NtOpenProcess:
?????8057559e?e95d6f4271??????jmp?????f199c500
?????805755a3?e93f953978??????jmp?????f890eae7
?????805755a8?e8e5e4f6ff??????call????nt!InterlockedPushEntrySList+0x79?(804e3a92)
?????...
?????
同時打開冰刃“Rootkit?Unhooker”我們就能在NtOpenProcess函數頭看到這樣的奇觀”,第一個jmp冰 刃的,第二個jmp“Rootkit?Unhooker”的。他們這樣是防止被惡意程序通過TerminateProcess關閉。當然冰刃還?HookNtTerminateProcess等函數。

×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
????
好了,道理就說完了,下面就進入本文正題。
????
對付ring0?inline?hook的基本思路是這樣的,自己寫一個替換的內核函數,以NtOpenProcess為例,就是?MyNtOpenProcess。然后修改SSDT表,讓系統服務進入自己的函數MyNtOpenProcess。而MyNtOpenProcess要做 的事就是,實現NtOpenProcess10字節指令,然后再JMP到原來的NtOpenProcess的十字節后。這樣NtOpenProcess?函數頭寫的JMP都失效了,在ring3直接調用OpenProcess再也毫無影響。
***************************************************************************************************************************
#include

typedef?struct?_SERVICE_DESCRIPTOR_TABLE
{
??PVOID???ServiceTableBase;
??PULONG??ServiceCounterTableBase;
??ULONG???NumberOfService;
??ULONG???ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE;?//
由于KeServiceDescriptorTable只有一項,這里就簡單點了
extern?PSERVICE_DESCRIPTOR_TABLE????KeServiceDescriptorTable;//KeServiceDescriptorTable
為導出函數

/
VOID?Hook();
VOID?Unhook();
VOID?OnUnload(IN?PDRIVER_OBJECT?DriverObject);
//
ULONG?JmpAddress;//
跳轉到NtOpenProcess里的地址
ULONG?OldServiceAddress;//
原來NtOpenProcess的服務地址
//
__declspec(naked)?NTSTATUS?__stdcall?MyNtOpenProcess(PHANDLE?ProcessHandle,
???????????????ACCESS_MASK?DesiredAccess,
???????????????POBJECT_ATTRIBUTES?ObjectAttributes,
???????????????PCLIENT_ID?ClientId)?
{
??DbgPrint("NtOpenProcess()?called");
??__asm{
????push????0C4h
????push????804eb560h??//
共十個字節
????jmp?????[JmpAddress]?????
??}
}
///
NTSTATUS?DriverEntry(IN?PDRIVER_OBJECT?DriverObject,PUNICODE_STRING?RegistryPath)
{
??DriverObject->DriverUnload?=?OnUnload;
??DbgPrint("Unhooker?load");
??Hook();
??return?STATUS_SUCCESS;
}
/
VOID?OnUnload(IN?PDRIVER_OBJECT?DriverObject)
{
??DbgPrint("Unhooker?unload!");
??Unhook();
}
/
VOID?Hook()
{
??ULONG??Address;
??Address?=?(ULONG)KeServiceDescriptorTable->ServiceTableBase?+?0x7A?*?4;//0x7A
NtOpenProcess服務ID
??DbgPrint("Address:0xX",Address);

??OldServiceAddress?=?*(ULONG*)Address;//
保存原來NtOpenProcess的地址
??DbgPrint("OldServiceAddress:0xX",OldServiceAddress);

??DbgPrint("MyNtOpenProcess:0xX",MyNtOpenProcess);

??JmpAddress?=?(ULONG)NtOpenProcess?+?10;?//
跳轉到NtOpenProcess函數頭+10的地方,這樣在其前面寫的JMP都失效了
??DbgPrint("JmpAddress:0xX",JmpAddress);
????
??__asm{//
去掉內存保護
????cli
?????????mov??eax,cr0
????and??eax,not?10000h
????mov??cr0,eax
??}

??*((ULONG*)Address)?=?(ULONG)MyNtOpenProcess;//HOOK?SSDT

??__asm{//
恢復內存保護??
??????????mov??eax,cr0
????or???eax,10000h
????mov??cr0,eax
????sti
??}
}
//
VOID?Unhook()
{
??ULONG??Address;
??Address?=?(ULONG)KeServiceDescriptorTable->ServiceTableBase?+?0x7A?*?4;//
查找SSDT

??__asm{
????cli
??????????mov??eax,cr0
????and??eax,not?10000h
????mov??cr0,eax
??}

??*((ULONG*)Address)?=?(ULONG)OldServiceAddress;//
還原SSDT

??__asm{??
?????????mov??eax,cr0
????or???eax,10000h
????mov??cr0,eax
????sti
??}

??DbgPrint("Unhook");
}
××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
????
就這么多了,或許有人說,沒必要那么復雜,直接恢復NtOpenProcess不就行了嗎?對于象冰刃”“Rookit?Unhooker”這 些善良之輩的話是沒問題的,但是象NP這些窮兇極惡之流的話,它會不斷檢測NtOpenProcess是不是已經被寫回去,是的話,嘿嘿,機器馬 上重啟。這也是這種方法的一點點妙用。

總結

以上是生活随笔為你收集整理的SSDT Hook的妙用-对抗ring0 inline hook的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。