• <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.¢%

            像打了激速一樣,以四倍的速度運轉(zhuǎn),開心的工作
            簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
            posts - 1098, comments - 335, trackbacks - 0, articles - 1
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
            詳談內(nèi)核三步走Inline?Hook實現(xiàn)

            (一)Inline?hook原理
            Inline?hook通俗的說就是對函數(shù)執(zhí)行流程進行修改,達到控制函數(shù)過濾操作的目的。理論上我們可以在函數(shù)任何地方把原來指令替換成我們的跳轉(zhuǎn)指令,也確實有些人在inline
            的時候做的很深,來躲避inline?的檢測,前提是必須對函數(shù)的流程和指令非常熟悉,且這種深層次的inlline?不具有通用性,穩(wěn)定性也是問題。本文討論的是具有通用性的兩類inline的實現(xiàn)。
            Inline?hook原理:解析函數(shù)開頭的幾條指令,把他們Copy到數(shù)組保存起來,然后用一個調(diào)用我們的函數(shù)的幾條指令來替換,如果要執(zhí)行原函數(shù),則在我們函數(shù)處理完畢,再執(zhí)行我們保存起來的開頭幾條指令,然后調(diào)回我們?nèi)≈噶钪蟮牡刂穲?zhí)行。
            整個Inline?hook的過程就大體這樣,中間牽扯到對函數(shù)的檢查,地址的獲取就直接調(diào)用函數(shù)即可。
            本文所要討論的兩類Inline?hook都是基于上面原理。?

            說明三點:
            1、堆棧平衡是重中之重,參數(shù)壓棧也需要格外注意
            2、CR0寄存器中的WP位控制處理器是否允許往只讀內(nèi)存頁寫入,為0禁用保護機制。
            3、提高中斷級別到DISPATCH_LEVEL,禁止線程切換產(chǎn)生的中斷
            ?????????????????????
            (二)inline?hook應用
            Inline?hook可分為兩類:
            (1)inline?導出函數(shù),選擇ObReferenceObjectByHandle做例子。
            (2)inline?未導出函數(shù),選擇KiInsertQueueApc做例子。
            導出函數(shù)前幾個字節(jié)可以利用windbg自己查看是什么內(nèi)容,而未導出函數(shù)就需要自己解析指令確定需要hook幾個字節(jié),其間還有很多問題需要注意。當大家真正的弄懂了我這篇文章,回頭再看inline?hook就會覺得inline也不過如此。
            下面通過2個例子來講inline?hook的使用(這部分知識網(wǎng)上也有很多,但都很零散不系統(tǒng),本文部分思路及代碼的確參考了網(wǎng)上資源,有抄襲之嫌,希望讀者諒解。我一直強調(diào)“授人以魚不如授人以漁”,代碼并不重要,關(guān)鍵是思想。)
            1、inline?hook?ObReferenceObjectByHandle保護進程
            ObReferenceObjectByHandle屬于ntoskrnl.exe導出函數(shù),在內(nèi)核中調(diào)用頻繁。
            NtCreateProcess創(chuàng)建進程需要調(diào)用ObReferenceObjectByHandle,NtTerminateProcess需要調(diào)用ObReferenceObjectByHandle,基于這我們就可以利用Hook來保護進程同時屏蔽進程的創(chuàng)建。
            效果:已經(jīng)運行的記事本任務管理器無法結(jié)束
            流程:
            HookObReferenceObjectByHandle------DetourMyObReferenceObjectByHa?ndle----------UnHookObReferenceObjectByHandle
            核心代碼分析如下:
            //=======================================inline?HOOK?ObReferenceObjectByHandle===========================

            //ObReferenceObjectByHandle是ntoskrnl.exe導出函數(shù),采用HOOK前五個字節(jié)的方式

            //字節(jié)型數(shù)據(jù)??unsigned?char
            ULONG??CR0VALUE;
            BYTE??OriginalBytes[5]={0};?????????????//保存原始函數(shù)前五個字節(jié)???????????
            BYTE?JmpAddress[5]={0xE9,0,0,0,0};???????//跳轉(zhuǎn)到HOOK函數(shù)的地址

            extern?POBJECT_TYPE?*PsProcessType;

            NTKERNELAPI?NTSTATUS?ObReferenceObjectByHandle(
            ?????????????????????????
            ?????????????????????????IN?HANDLE??Handle,
            ?????????????????????????IN?ACCESS_MASK??DesiredAccess,
            ?????????????????????????IN?POBJECT_TYPE??ObjectType??OPTIONAL,
            ?????????????????????????IN?KPROCESSOR_MODE??AccessMode,
            ?????????????????????????OUT?PVOID??*Object,
            ?????????????????????????OUT?POBJECT_HANDLE_INFORMATION??HandleInformation??OPTIONAL
            ?????????????????????????
            ?????????????????????????);

            //HOOK函數(shù)

            NTSTATUS?DetourMyObReferenceObjectByHandle(
            ???????????????????????
            ???????????????????????IN?HANDLE??Handle,???????????
            ???????????????????????IN?ACCESS_MASK??DesiredAccess
            ???????????????????????IN?POBJECT_TYPE??ObjectType??OPTIONAL,?
            ???????????????????????IN?KPROCESSOR_MODE??AccessMode,
            ???????????????????????OUT?PVOID??*Object,
            ???????????????????????OUT?POBJECT_HANDLE_INFORMATION??HandleInformation??OPTIONAL);

            //

            //hook流程?HookObReferenceObjectByHandle---DetourMyObReferenceObjectByHandle---UnHookObReferenceObjectByHandle

            void??HookObReferenceObjectByHandle()

            {
            ??
            ??//賦值前面定義的數(shù)組
            ??KIRQL?Irql;
            ??KdPrint(("[ObReferenceObjectByHandle]?:0x%x",ObReferenceObjectByHandle));??//地址驗證
            ??//保存函數(shù)前五個字節(jié)內(nèi)容
            ??RtlCopyMemory(OriginalBytes,(BYTE?*)ObReferenceObjectByHandle,5);
            ??//保存新函數(shù)五個字節(jié)之后偏移
            ??*(ULONG?*)(JmpAddress+1)=(ULONG)DetourMyObReferenceObjectByHandle-((ULONG)ObReferenceObjectByHandle+5);
            ??//開始inline?hook
            ??//關(guān)閉內(nèi)存寫保護
            ??_asm
            ????
            ??{
            ????push?eax
            ??????
            ??????mov?eax,?cr0?
            ??????mov?CR0VALUE,?eax?
            ??????and?eax,?0fffeffffh??
            ??????mov?cr0,?eax
            ??????pop?eax
            ??}
            ??
            ??//提升IRQL中斷級
            ??Irql=KeRaiseIrqlToDpcLevel();
            ??//函數(shù)開頭五個字節(jié)寫JMP?
            ??RtlCopyMemory((BYTE?*)ObReferenceObjectByHandle,JmpAddress,5);
            ??//恢復Irql
            ??KeLowerIrql(Irql);
            ??//開啟內(nèi)存寫保護
            ??
            ??__asm
            ????
            ??{???????
            ????
            ????push?eax
            ??????
            ??????mov?eax,?CR0VALUE?
            ??????
            ??????mov?cr0,?eax
            ??????
            ??????pop?eax
            ??????
            ??}
            ??
            }



            _declspec?(naked)?NTSTATUS?OriginalObReferenceObjectByHandle(IN?HANDLE??Handle,
            ???????????????????????????????
            ???????????????????????????????IN?ACCESS_MASK??DesiredAccess,
            ???????????????????????????????
            ???????????????????????????????IN?POBJECT_TYPE??ObjectType??OPTIONAL,
            ???????????????????????????????
            ???????????????????????????????IN?KPROCESSOR_MODE??AccessMode,
            ???????????????????????????????
            ???????????????????????????????OUT?PVOID??*Object,
            ???????????????????????????????
            ???????????????????????????????OUT?POBJECT_HANDLE_INFORMATION??HandleInformation??OPTIONAL)
            ???????????????????????????????
            {
            ??
            ??_asm
            ????
            ??{???
            ????
            ????mov?edi,edi
            ??????push?ebp
            ??????mov?ebp,esp
            ??????mov?eax,ObReferenceObjectByHandle
            ??????add?eax,5
            ??????jmp?eax????????????????
            ??????
            ??}
            ??
            }


            NTSTATUS?DetourMyObReferenceObjectByHandle(
            ???????????????????????
            ???????????????????????IN?HANDLE??Handle,
            ???????????????????????
            ???????????????????????IN?ACCESS_MASK??DesiredAccess,
            ???????????????????????
            ???????????????????????IN?POBJECT_TYPE??ObjectType??OPTIONAL,
            ??????????????????
            ???????????????????????IN?KPROCESSOR_MODE??AccessMode,
            ???????????????????????
            ???????????????????????OUT?PVOID??*Object,
            ???????????????????????
            ???????????????????????OUT?POBJECT_HANDLE_INFORMATION??HandleInformation??OPTIONAL)
            ???????????????????????
            {
            ??
            ??NTSTATUS?status;
            ??
            ??//調(diào)用原函數(shù)
            ??
            ??status=OriginalObReferenceObjectByHandle(Handle,DesiredAccess,ObjectType,AccessMode,Object,HandleInformation);
            ??
            ??if((status==STATUS_SUCCESS)&&(DesiredAccess==1))
            ????
            ??{???
            ????
            ????if(ObjectType==?*PsProcessType)
            ??????
            ????{
            ??????
            ??????if(?_stricmp((char?*)((ULONG)(*Object)+0x174),"notepad.exe")==0)
            ????????
            ??????{???
            ????????
            ????????ObDereferenceObject(*Object);
            ????????
            ????????return?STATUS_INVALID_HANDLE;
            ????????
            ??????}
            ??????
            ????}
            ????
            ??}
            ??
            ??return?status;
            ??
            }



            void?UnHookObReferenceObjectByHandle()

            {
            ??
            ??//把五個字節(jié)再寫回到原函數(shù)
            ??
            ??KIRQL?Irql;
            ??
            ????//關(guān)閉寫保護
            ??
            ??_asm
            ????
            ??{
            ????
            ????push?eax
            ??????
            ??????mov?eax,?cr0?
            ??????
            ??????mov?CR0VALUE,?eax?
            ??????
            ??????and?eax,?0fffeffffh??
            ??????
            ??????mov?cr0,?eax
            ??????
            ??????pop?eax
            ??????
            ??}
            ??
            ????//提升IRQL到Dpc
            ??
            ????Irql=KeRaiseIrqlToDpcLevel();
            ??
            ??RtlCopyMemory((BYTE?*)ObReferenceObjectByHandle,OriginalBytes,5);
            ??
            ??KeLowerIrql(Irql);
            ??
            ????//開啟寫保護
            ??
            ??__asm
            ????
            ??{???????
            ????
            ????????push?eax
            ??????mov?eax,?CR0VALUE?
            ??????mov?cr0,?eax
            ??????
            ??????pop?eax
            ??????
            ??}
            }

            驅(qū)動加載后,結(jié)束記事本程序如下:
            ?
            ????(圖?一)

            詳細分析:
            1、ObReferenceObjectByHandle分析
            NTSTATUS?
            ??ObReferenceObjectByHandle(
            ????IN?HANDLE??Handle,
            ????IN?ACCESS_MASK??DesiredAccess,
            ????IN?POBJECT_TYPE??ObjectType??OPTIONAL,
            ????IN?KPROCESSOR_MODE??AccessMode,
            ????OUT?PVOID??*Object,
            ????OUT?POBJECT_HANDLE_INFORMATION??HandleInformation??OPTIONAL
            ????);
            函數(shù)原型如上,由句柄獲取對象指針,函數(shù)返回值:
            STATUS_SUCCESS????????????????????????調(diào)用成功
            STATUS_OBJECT_TYPE_MISMATCH????????
            STATUS_ACCESS_DENIED?????????????????權(quán)限不夠
            STATUS_INVALID_HANDLE????????????????無效句柄?????????

            調(diào)用NtTerminateProcess需要調(diào)用ObReferenceObjectByHandle,因此我們通過對函數(shù)返回值進程修改來達到保護進程。但是NtCreateProcess(最終調(diào)用的PspCreateProcess)同樣調(diào)用這個函數(shù),如果不加區(qū)分的話,創(chuàng)建進程同樣被禁止了,那么如何區(qū)分到底是誰在調(diào)用呢。參考WRK,我發(fā)現(xiàn)可以通過第二個參數(shù)DesiredAccess來判別,創(chuàng)建進程和結(jié)束進程第二個參數(shù)明顯不同,PROCESS_CREATE_PROCESS和PROCESS_TERMINATE,問題就解決了。
            PspCreateProcess位于?WRK-v1.2\base\ntos\ps\create.c
            調(diào)用ObReferenceObjectByHandle代碼:
            Status?=?ObReferenceObjectByHandle?(ParentProcess,
            ????????????????????????????????????????????PROCESS_CREATE_PROCESS,
            ????????????????????????????????????????????PsProcessType,
            ????????????????????????????????????????????PreviousMode,
            ????????????????????????????????????????????&Parent,
            ????????????????????????????????????????????NULL);
            NtTerminateProcess位于?WRK-v1.2\base\ntos\ps\psdelete.c
            調(diào)用ObReferenceObjectByHandle代碼:
            st?=?ObReferenceObjectByHandle?(ProcessHandle,
            ????????????????????????????????????PROCESS_TERMINATE,
            ????????????????????????????????????PsProcessType,
            ????????????????????????????????????KeGetPreviousModeByThread(&Self->Tcb),
            ????????????????????????????????????&Process,
            ????????????????????????????????????NULL);
            DesiredAccess參數(shù)說明:
            #define?PROCESS_TERMINATE?????????(0x0001)?//?winnt
            #define?PROCESS_CREATE_THREAD?????(0x0002)?//?winnt
            #define?PROCESS_SET_SESSIONID?????(0x0004)?//?winnt
            #define?PROCESS_VM_OPERATION??????(0x0008)?//?winnt
            #define?PROCESS_VM_READ???????????(0x0010)?//?winnt
            #define?PROCESS_VM_WRITE??????????(0x0020)?//?winnt
            //?begin_ntddk?begin_wdm?begin_ntifs
            #define?PROCESS_DUP_HANDLE????????(0x0040)?//?winnt
            //?end_ntddk?end_wdm?end_ntifs
            #define?PROCESS_CREATE_PROCESS????(0x0080)?//?winnt
            #define?PROCESS_SET_QUOTA?????????(0x0100)?//?winnt
            #define?PROCESS_SET_INFORMATION???(0x0200)?//?winnt
            #define?PROCESS_QUERY_INFORMATION?(0x0400)?//?winnt
            #define?PROCESS_SET_PORT??????????(0x0800)
            #define?PROCESS_SUSPEND_RESUME????(0x0800)?//?winnt

            2、函數(shù)調(diào)用說明
            C語言中我們調(diào)用一個函數(shù)就直接寫函數(shù)名就可以,但是實際是進行了下面的操作:
            把函數(shù)參數(shù)壓入堆棧,壓入函數(shù)返回地址,調(diào)用函數(shù),為新函數(shù)開辟堆棧空間申請局部變量,
            恢復堆棧保持堆棧平衡
            (_stdcall調(diào)用方式)匯編代碼就是:
            Push?參數(shù)4
            Push?參數(shù)3
            Push?參數(shù)2
            Push?參數(shù)1
            Call??函數(shù)??;call指令同時完成2個操作,一是把返回地址壓入堆棧,二跳轉(zhuǎn)到調(diào)用函數(shù)入口地址

            Push??ebp
            Mov?ebp,esp
            Sub??esp,?XX??;開辟棧幀空間
            ……
            Add??esp?,XX
            Pop?ebp
            Retn??????????;恢復堆棧平衡
            堆棧詳細情況:
            ESP
            局部變量





            EBP
            返回地址
            參數(shù)1
            參數(shù)2
            參數(shù)3
            參數(shù)4
            堆棧是由高地址到低地址。
            參數(shù)就通過EBP來去,四字節(jié)對齊的

            參數(shù)4----------------------EBP+0x14
            參數(shù)3----------------------EBP+0x10
            參數(shù)2----------------------EBP+0xc
            參數(shù)1---------------------?EBP+0x8
            局部變量則通過Ebp-XX來獲取

            因此inline的時候要時刻考慮堆棧平衡,破壞了堆棧平衡就會導致函數(shù)崩潰。
            我通常inline?hook的思路就是三步走:
            HOOK函數(shù)-----DetourMy處理函數(shù)----------UnHook函數(shù)
            處理函數(shù)中對返回結(jié)果或者中間數(shù)據(jù)進行修改處理,然后調(diào)用原始函數(shù)。由于在我們處理的時候原始函數(shù)已經(jīng)被hook了,所以我自己構(gòu)造了一個原始函數(shù),但是由于參數(shù)在我們hook前已經(jīng)壓人堆棧了,所以這里我們不用重新開辟棧幀,因此聲名函數(shù)類型為_declspec?(naked)
            。有人就會問那么你調(diào)用處理函數(shù)的時候,參數(shù)不是重復壓棧了,這里請注意,我們是通過JMP方式跳轉(zhuǎn)到我們處理函數(shù)入口地址的,而不是Call的形式,所以并沒有執(zhí)行上面所說的函數(shù)調(diào)用過程,參數(shù)仍然是原始函數(shù)的。也就是說在真?zhèn)€inline?hook過程中我們不能破壞原始棧幀的EBP。

            關(guān)于函數(shù)調(diào)用很棧幀的相關(guān)聯(lián)系可能比較難理解,我也在盡肯能的用通俗的話來解釋清楚,有什么不理解的地方或者個人見解歡迎大家跟我交流。

            2、inline?hook?KiInsertQueueApc對抗插APC殺進程
            KiInsertQueueAPc為內(nèi)核未導出函數(shù),我下面提供的代碼可以作為未導出函數(shù)inline的通用模板來使用,大家根據(jù)自己需要進行修改,基于inline?ObReferenceObjectByHandle已經(jīng)把原理分析了,這部分我就不詳加分析,仍然采用的但不走,Hook函數(shù)---DetourMy函數(shù)---UnHook函數(shù)
            直接看核心代碼:
            //===================inline?hook?KiInsertQueueApc====================
            //KiInsertQueueApc為內(nèi)核未導出函數(shù),可以從導出函數(shù)KeInsertQueueApc定位
            //修改KiInsertQueueApc開頭5字節(jié)
            //處理函數(shù)思路:apc-->kthread---apc_state--eprocess--進程名字
            //HookKiInsertQueueApc---DetourMyKiInsertQueueApc---UnHookKiInsertQueueApc
            ULONG?CR0VALUE;
            ULONG?g_KiInsertQueueApc;
            ???????????
            BYTE?JmpAddress[5]={0xE9,0,0,0,0};???????//跳轉(zhuǎn)到HOOK函數(shù)的地址
            BYTE??OriginalBytes[5]={0};?????????????//保存原始函數(shù)前五個字

            VOID?FASTCALL?DetourMyKiInsertQueueApc(IN?PKAPC?Apc,IN?KPRIORITY?Increment);

            VOID?WPOFF()
            {
            ??_asm
            ????
            ??{
            ????
            ????push?eax
            ??????
            ??????mov?eax,?cr0?
            ??????
            ??????mov?CR0VALUE,?eax?
            ??????
            ??????and?eax,?0fffeffffh??
            ??????
            ??????mov?cr0,?eax
            ??????
            ??????pop?eax
            ??????cli
            ??????
            ??};
            ??
            }

            VOID?WPON()
            {
            ????__asm
            ????
            ??{???????
            ????sti
            ????push?eax
            ??????
            ??????mov?eax,?CR0VALUE?
            ??????
            ??????mov?cr0,?eax
            ??????
            ??????pop?eax
            ??????
            ??};
            }
            //1、獲取KiInsertQueueApc地址
            ULONG?GetFunctionAddr(?IN?PCWSTR?FunctionName)?????//PCWSTR常量指針,指向16位UNICODE
            {
            ??UNICODE_STRING?UniCodeFunctionName;
            ??RtlInitUnicodeString(?&UniCodeFunctionName,?FunctionName?);
            ??return?(ULONG)MmGetSystemRoutineAddress(?&UniCodeFunctionName?);???
            }

            ULONG?GetKiInsertQueueApcAddr()
            {
            ??ULONG?sp_code1=0x28,sp_code2=0xe8,sp_code3=0xd88a;??//特征碼,sp_code3?windbg顯示錯誤,應該為d88a
            ??ULONG?address=0;
            ??PUCHAR?addr;
            ??PUCHAR?p;
            ??addr=(PUCHAR)GetFunctionAddr(L"KeInsertQueueApc");
            ??for(p=addr;p<p+PAGE_SIZE;p++)
            ??{
            ????if((*(p-1)==sp_code1)&&(*p==sp_code2)&&(*(PUSHORT)(p+5)==sp_code3))
            ????{
            ??????address=*(PULONG)(p+1)+(ULONG)(p+5);
            ??????break;
            ????}
            ??}
            ??KdPrint(("[KeInsertQueueApc]?addr?%x\n",(ULONG)addr));
            ????KdPrint(("[KiInsertQueueApc]?address?%x\n",address));
            ????return?address;
            }

            VOID?HookKiInsertQueueApc()
            {???
            ??KIRQL?Irql;
            ??g_KiInsertQueueApc=GetKiInsertQueueApcAddr();
            ??KdPrint(("[KiInsertQueueApc]?KiInsertQueueApc?%x\n",g_KiInsertQueueApc));
            ????//?保存原函數(shù)的前字節(jié)內(nèi)容
            ????RtlCopyMemory?(OriginalBytes,?(BYTE*)g_KiInsertQueueApc,?5);
            ??//新函數(shù)對原函數(shù)的偏移地址
            ????*(?(ULONG*)(JmpAddress?+?1)?)?=?(ULONG)DetourMyKiInsertQueueApc?-?(ULONG)g_KiInsertQueueApc?-?5;
            ????//?禁止系統(tǒng)寫保護,提升IRQL到DPC
            ????WPOFF();
            ????Irql?=?KeRaiseIrqlToDpcLevel();
            ????//inline?hook函數(shù)
            ??RtlCopyMemory?(?(BYTE*)g_KiInsertQueueApc,?JmpAddress,?5?);
            ????//?恢復寫保護,降低IRQL
            ????KeLowerIrql(Irql);
            ????WPON();??
            }
            //原函數(shù)
            _declspec?(naked)?VOID?FASTCALL?OriginalKiInsertQueueApc(IN?PKAPC?Apc,IN?KPRIORITY?Increment)
            {
            ??_asm
            ??{
            ????//前五個字節(jié)
            ????mov?edi,edi
            ??????push?ebp
            ??????mov?ebp,esp
            ??????
            ??????mov?eax,g_KiInsertQueueApc
            ??????add?eax,5
            ??????jmp?eax
            ??}
            }
            //處理函數(shù)
            //apc--kthread--apc_state--eprocess
            VOID?FASTCALL?DetourMyKiInsertQueueApc(IN?PKAPC?Apc,IN?KPRIORITY?Increment)
            {
            ??ULONG?thread;
            ??ULONG?process;
            ??if(MmIsAddressValid((PULONG)((ULONG)Apc+0x008)))????//地址驗證?KAPC結(jié)構(gòu)+008--->kthread
            ????thread=*((PULONG)((ULONG)Apc+0x008));
            ??else
            ????return?;
            ??if(MmIsAddressValid((PULONG)((ULONG)thread+0x044)))?//kthread+30-->KAPC_STATE+10-->eprocess
            ????process=*((PULONG)((ULONG)thread+0x044));
            ??else
            ????return?;
            ????if(MmIsAddressValid((PULONG)((ULONG)process+0x174)))??//eprocess+174---->進程名字
            ??{
            ????if((_stricmp((char?*)((ULONG)process+0x174),"notepad.exe")==0)&&(Increment==2))
            ????{
            ??????return?;

            ????}
            ????else
            ??????OriginalKiInsertQueueApc(Apc,Increment);

            ??}
            ??else
            ????return;
            }

            //卸載函數(shù)
            VOID?UnHookKiInsertQueueApc()
            {
            ??KIRQL?Irql;
            ????WPOFF();
            ????Irql?=?KeRaiseIrqlToDpcLevel();
            ????//inline?hook函數(shù)
            ????RtlCopyMemory?(?(BYTE*)g_KiInsertQueueApc,?OriginalBytes,?5);
            ????//?恢復寫保護,降低IRQL
            ????KeLowerIrql(Irql);
            ????WPON();??
            }
            ?考慮到大家水平不一,對一些問題我詳細如下:
            1、特征碼的尋找
            利用windbg的kernel?debug來查找:
            uf??KeInsertQueueApc
            nt!KeInsertQueueApc+0x3b:
            804e6d0a?8b450c??????????mov?????eax,dword?ptr?[ebp+0Ch]
            804e6d0d?8b5514??????????mov?????edx,dword?ptr?[ebp+14h]
            804e6d10?894724??????????mov?????dword?ptr?[edi+24h],eax
            804e6d13?8b4510??????????mov?????eax,dword?ptr?[ebp+10h]
            804e6d16?8bcf????????????mov?????ecx,edi
            804e6d18?894728??????????mov?????dword?ptr?[edi+28h],eax
            804e6d1b?e8523fffff????????call????nt!KiInsertQueueApc?(804dac72)
            804e6d20?8ad8?(錯誤)??mov?????bl,al
            特征碼就是sp_code1=0x28?sp_code2=0xe8?sp_code3=0xd88a(windbg顯示有誤,應該是d88a

            這種方法就是通過已導出函數(shù)定位未導出函數(shù)通常使用的方法,具有通用性。詳細見代碼。

            2、取EPRocess的過程
            Apc-----kthread-----apc_state—eprocess
            dt??_KAPC?????????????偏移0x008指向KTHREAD
            dt??_KTHREAD?????????偏移0x034指向KAPC_STATE
            dt??_KAPC_STATE??????偏移0x10指向EPROCESS
            dt??_EPROCESS?????????偏移0x174指向進程名


            (三)總結(jié)
            ?很多人覺得inline?hook比較難,處理起來很麻煩。但是我相信看完我這篇文章,你一定不會這么認為了,inline?hook其實只要細心,注意細節(jié)跟別的hook沒什么兩樣。本人采用的三步走inline?hook做到了把inline簡單化,同時有保證了堆棧的平衡。
            ?由于代碼采用的硬編碼,編譯環(huán)境是sp3+VMware,請根據(jù)自己操作系統(tǒng)自行修改。歡迎讀者跟我交流。
            久久亚洲国产午夜精品理论片| 亚洲国产天堂久久综合| 久久97精品久久久久久久不卡| 久久精品国产秦先生| 看全色黄大色大片免费久久久| 97精品伊人久久久大香线蕉| 韩国三级大全久久网站| 日本WV一本一道久久香蕉| 国产91久久精品一区二区| 国内精品伊人久久久久妇| 91精品国产91久久综合| 久久久久亚洲av毛片大| 国产精品久久午夜夜伦鲁鲁| 久久综合五月丁香久久激情| 九九精品99久久久香蕉| 久久人妻少妇嫩草AV蜜桃| 国产精品成人久久久久三级午夜电影| 久久无码高潮喷水| 四虎亚洲国产成人久久精品| 久久99国产精品一区二区| 奇米综合四色77777久久| 亚洲日韩欧美一区久久久久我| 国产 亚洲 欧美 另类 久久| 国产成人无码久久久精品一 | 亚洲伊人久久综合中文成人网| 久久久综合九色合综国产| 激情五月综合综合久久69| 久久久国产乱子伦精品作者| 欧美激情一区二区久久久| 亚洲国产精品狼友中文久久久| 91麻豆精品国产91久久久久久 | 久久久久久久综合狠狠综合| 精品无码久久久久久久久久| 久久久精品久久久久久 | 香蕉久久夜色精品国产2020| 国产精品久久久久一区二区三区| 国产精品久久久久久久久| 久久亚洲综合色一区二区三区 | 伊人久久成人成综合网222| 久久99热这里只频精品6| 狠狠色噜噜色狠狠狠综合久久|