• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            S.l.e!ep.¢%

            像打了激速一樣,以四倍的速度運轉,開心的工作
            簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
            posts - 1098, comments - 335, trackbacks - 0, articles - 1
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            SSDT Hook的妙用-對抗ring0 inline hook

            Posted on 2009-10-28 22:46 S.l.e!ep.¢% 閱讀(458) 評論(0)  編輯 收藏 引用 所屬分類: RootKit
            【原創(chuàng)】SSDT Hook的妙用-對抗ring0 inline hook
            墮落天才 當前離線

            標 題: 【原創(chuàng)】SSDT Hook的妙用-對抗ring0 inline hook
            作 者: 墮落天才
            時 間: 2007-03-10,15:18
            鏈 接: http://bbs.pediy.com/showthread.php?t=40832

            *******************************************************
            *標題:【原創(chuàng)】SSDT?Hook的妙用-對抗ring0?inline?hook??*
            *作者:墮落天才????????????????????????????????????????*
            *日期:2007年3月10號???????????????????????????????????*
            *聲明:本文章的目的僅為技術交流討論????????????????????*
            *******************************************************

            1,SSDT
            ?????SSDT即系統(tǒng)服務描述符表,它的結構如下(參考《Undocument?Windows?2000?Secretes》第二章):
            ?????typedef?struct?_SYSTEM_SERVICE_TABLE
            ?????{
            ???????PVOID???ServiceTableBase;????????//這個指向系統(tǒng)服務函數(shù)地址表
            ???????PULONG??ServiceCounterTableBase;
            ???????ULONG???NumberOfService;?????????//服務函數(shù)的個數(shù),NumberOfService*4?就是整個地址表的大小
            ???????ULONG???ParamTableBase;
            ?????}SYSTEM_SERVICE_TABLE,*PSYSTEM_SERVICE_TABLE;???
            ?????
            ?????typedef?struct?_SERVICE_DESCRIPTOR_TABLE
            ?????{
            ???????SYSTEM_SERVICE_TABLE???ntoskrnel;??//ntoskrnl.exe的服務函數(shù)
            ???????SYSTEM_SERVICE_TABLE???win32k;?????//win32k.sys的服務函數(shù),(gdi.dll/user.dll的內核支持)
            ???????SYSTEM_SERVICE_TABLE???NotUsed1;
            ???????SYSTEM_SERVICE_TABLE???NotUsed2;
            ?????}SYSTEM_DESCRIPTOR_TABLE,*PSYSTEM_DESCRIPTOR_TABLE;
            ?????
            ?????內核中有兩個系統(tǒng)服務描述符表,一個是KeServiceDescriptorTable(由ntoskrnl.exe導出),一個是KeServieDescriptorTableShadow(沒有導出)。兩者的區(qū)別是,KeServiceDescriptorTable僅有ntoskrnel一項,KeServieDescriptorTableShadow包含了ntoskrnel以及win32k。一般的Native?API的服務地址由KeServiceDescriptorTable分派,gdi.dll/user.dll的內核API調用服務地址由KeServieDescriptorTableShadow分派。還有要清楚一點的是win32k.sys只有在GUI線程中才加載,一般情況下是不加載的,所以要Hook?KeServieDescriptorTableShadow的話,一般是用一個GUI程序通過IoControlCode來觸發(fā)(想當初不明白這點,藍屏死機了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中就只有第一項有數(shù)據(jù),其他都是0。其中804e3d20就是
            KeServiceDescriptorTable.ntoskrnel.ServiceTableBase,服務函數(shù)個數(shù)為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?這些就是系統(tǒng)服務函數(shù)的地址了。比如當我們在ring3調用OpenProcess時,進入sysenter的ID是0x7A(XP?SP2),然后系統(tǒng)查KeServiceDescriptorTable,大概是這樣KeServiceDescriptorTable.ntoskrnel.ServiceTableBase(804e3d20)?+?0x7A?*?4?=?804E3F08,然后804E3F08?->8057559e?這個就是OpenProcess系統(tǒng)服務函數(shù)所在,我們再跟蹤看看:
            ????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函數(shù)所在的起始地址。??
            ????嗯,如果我們把8057559e改為指向我們函數(shù)的地址呢?比如?MyNtOpenProcess,那么系統(tǒng)就會直接調用MyNtOpenProcess,而不是原來的NtOpenProcess了。這就是SSDT?HOOK?原理所在。

            ??3,?ring0?inline?hook
            ?????ring0?inline?hook?跟ring3的沒什么區(qū)別了,如果硬說有的話,那么就是ring3發(fā)生什么差錯的話程序會掛掉,ring0發(fā)生什么差錯的話系統(tǒng)就掛掉,所以一定要很小心。inline?hook的基本思想就是在目標函數(shù)中JMP到自己的監(jiān)視函數(shù),做一些判斷然后再JMP回去。一般都是修改函數(shù)頭,不過再其他地方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函數(shù)頭看到這樣的“奇觀”,第一個jmp是“冰刃”的,第二個jmp是“Rootkit?Unhooker”的。他們這樣是防止被惡意程序通過TerminateProcess關閉。當然“冰刃”還Hook了NtTerminateProcess等函數(shù)。

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

            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為導出函數(shù)

            /////////////////////////////////////
            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??//共十個字節(jié)
            ????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:0x%08X",Address);

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

            ??DbgPrint("MyNtOpenProcess:0x%08X",MyNtOpenProcess);

            ??JmpAddress?=?(ULONG)NtOpenProcess?+?10;?//跳轉到NtOpenProcess函數(shù)頭+10的地方,這樣在其前面寫的JMP都失效了
            ??DbgPrint("JmpAddress:0x%08X",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是不是已經被寫回去,是的話,嘿嘿,機器馬上重啟。這也是這種方法的一點點妙用。
            国产精品欧美久久久天天影视 | 欧美777精品久久久久网| 久久婷婷午色综合夜啪| 欧美精品福利视频一区二区三区久久久精品 | 欧美丰满熟妇BBB久久久| 欧洲人妻丰满av无码久久不卡| 久久精品免费一区二区| 久久精品国产亚洲AV香蕉| 无码人妻精品一区二区三区久久| 国内精品伊人久久久久777| 99精品国产综合久久久久五月天| 久久夜色精品国产噜噜麻豆| 久久精品国产亚洲AV麻豆网站| 精品国产一区二区三区久久| 国产综合免费精品久久久| 久久亚洲中文字幕精品一区四| 亚洲а∨天堂久久精品| 日韩精品无码久久久久久| 日本久久久久久中文字幕| 久久免费视频一区| 色婷婷久久综合中文久久蜜桃av| 99久久国产综合精品麻豆| 精品视频久久久久| 亚洲日韩中文无码久久| 久久亚洲国产午夜精品理论片| 久久996热精品xxxx| 久久久久国产精品人妻| 久久青草国产精品一区| 久久国产欧美日韩精品免费| 97久久久久人妻精品专区| 亚洲国产精品无码久久青草 | 久久精品一区二区国产| 色诱久久av| 国产日产久久高清欧美一区| 日批日出水久久亚洲精品tv| 久久99精品久久久久子伦| 久久久这里有精品中文字幕| 国产亚洲精品美女久久久| 久久久这里只有精品加勒比| 国产精品久久国产精品99盘 | 午夜精品久久久久久|