日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

【Hook技術(shù)】64位下Hook NtOpenProcess的實(shí)現(xiàn)進(jìn)程保護(hù) + 源碼 (升級(jí)篇)

 盛夏流年閃耀 2013-09-11

在我的上一篇文章中【Hook技術(shù)】實(shí)現(xiàn)從"任務(wù)管理器"中保護(hù)進(jìn)程不被關(guān)閉 + 附帶源碼 + 進(jìn)程保護(hù)知識(shí)擴(kuò)展 介紹了X86下基于IAT Hook技術(shù),通過(guò)Hook OpenProcess來(lái)實(shí)現(xiàn)從任務(wù)管理器中保護(hù)進(jìn)程,看到一些評(píng)論,有朋友問(wèn)該代碼是否適用于64位系統(tǒng)? 答案是肯定的,需要修改兩個(gè)地方:

a. 編譯時(shí)候,設(shè)置平臺(tái)為X64

b.修改SetWindowsHookEx第三個(gè)參數(shù)為0,關(guān)于這點(diǎn),是因?yàn)?4為下和32為下調(diào)用SetWindowsHookEx略有不同,官方關(guān)于該函數(shù)的有一段解析為:

SetWindowsHookEx can be used to inject a DLL into another process. A 32-bit DLL cannot be injected into a 64-bit process, and a 64-bit DLL cannot be injected into a 32-bit process. If an application requires the use of hooks in other processes, it is required that a 32-bit application call SetWindowsHookEx to inject a 32-bit DLL into 32-bit processes, and a 64-bit application call SetWindowsHookEx to inject a 64-bit DLL into 64-bit processes. The 32-bit and 64-bit DLLs must have different names.

如果你希望在X64下通過(guò)HOOK技術(shù)實(shí)現(xiàn)進(jìn)程的保護(hù),不推薦Hook OpenProcess,可以考慮通過(guò)Hook Ntdll的函數(shù)(NtOpenProcess)實(shí)現(xiàn),這也是樓主寫此文的目的的,介紹通過(guò)MHook實(shí)現(xiàn)對(duì)NtOpenProcess的hook實(shí)現(xiàn)進(jìn)程的保護(hù).


1. Hook技術(shù)基礎(chǔ)知識(shí)(Inline Hook)

   在開始本文的實(shí)例前想先通過(guò)對(duì)Hook技術(shù)做些簡(jiǎn)單的介紹,幫助大家更好的理解所謂的Hook技術(shù),所謂的hook技術(shù)其實(shí)就是修改函數(shù)行為的一種技術(shù),通過(guò)對(duì)函數(shù)行為的修改可以實(shí)現(xiàn)例如:文件的監(jiān)控/保護(hù) , 進(jìn)程的監(jiān)控/隱藏等,例如大多數(shù)的安全軟件都是基于這種技術(shù)實(shí)現(xiàn)的,還有些病毒木馬技術(shù)也會(huì)涉及到hook技術(shù)。一般的hook函數(shù)的流程:

 { 目標(biāo)API } ----- 【 Hook API 】 -------  修改函數(shù)入口前幾個(gè)字節(jié),添加跳轉(zhuǎn)指令 類似JMP DWORD Ptr Address

                               \ 

                           { jump 我們的代碼處 }  

                                |- a.  執(zhí)行我們代碼

                                |- b. 修復(fù)Hook

                                |- c. 調(diào)用目標(biāo)API

通過(guò)修改目標(biāo)函數(shù)的前幾個(gè)字節(jié),然后跳轉(zhuǎn)到我們的代碼執(zhí)行,等執(zhí)行完我們定制的代碼后,在調(diào)用真實(shí)的目標(biāo)API返回結(jié)果給調(diào)用程序.

大多數(shù)的系統(tǒng)API,前幾個(gè)字節(jié)都是對(duì)堆棧的操作,而hook技術(shù)就是利用了這幾個(gè)字節(jié)實(shí)現(xiàn)jmp的,偽代碼描述:

目標(biāo)函數(shù):

mov edi, edi          //              HOOK        Jmp DWORD PTR MyFunctionAddress    jump后      MyFunctionAddress內(nèi)部邏輯處理push ebp              //  堆棧操作 < ==========>   xor ecx ,exc                     <=========>   修復(fù)原函數(shù)堆棧操作 { mov edi,edi push ebp,...}mov ebp, esp          //                                                                         跳到原函數(shù)執(zhí)行JMP 【ADDRESS】xor ecx, ecx   ==> 標(biāo)記地址為【ADDRESS】

這是一種比較常用的HOOK思路,還有修改函數(shù)中部或者尾部的,思路相同,patch的位置不同

還有中Hook的思路是通過(guò)“跳板”函數(shù)實(shí)現(xiàn),定制函數(shù)和目標(biāo)函數(shù)之間的關(guān)系

{ Hook Api }

       \

      { Jump 定制函數(shù) }

              \

         { jump Trampoline(跳板函數(shù)) }

                      \ ______ { Call  目標(biāo)函數(shù)  }   ------ { 結(jié)果返回給調(diào)用程序 }

成功Hook函數(shù)后,跳轉(zhuǎn)我們定制的函數(shù)中執(zhí)行,當(dāng)我們定制的代碼執(zhí)行完后,并不是在函數(shù)內(nèi)部調(diào)用原目標(biāo)函數(shù),而是調(diào)用一個(gè)叫Trampoline的函數(shù),Trampoline的任務(wù)就是平衡堆棧,然后執(zhí)行原目標(biāo)函數(shù), 最后將結(jié)果返回給調(diào)用程序

例如:

復(fù)制代碼
         edi, edi                                 addr1   customFunction ; //執(zhí)行完地址的邏輯后,跳到調(diào)用Trampoline函數(shù)         ebp           < ==== JUMP ====>         addr2   ecx,ecx         ebp, esp    
addr2    ecx, ecx
Trampoline函數(shù):
 edi, edi ebp             { 平衡堆棧 } ebp, esp addr2     ===>  然后跳到原函數(shù)某地址執(zhí)行
復(fù)制代碼

這種方法相對(duì)于第一種方式來(lái)說(shuō),安全了很多至少在多線程的環(huán)境下 ,一般trampoline跳轉(zhuǎn)函數(shù)都是被標(biāo)記為naked的,很多情況都是通過(guò)匯編實(shí)現(xiàn),由自己編碼控制堆棧。


2. 實(shí)戰(zhàn),X64下Hook NtOpenProcess

  本demo中使用的hook引擎是MHook,Mhook是開源的,采用的是第二種hook方式,相比于MinHook/easyHook來(lái)說(shuō),使用簡(jiǎn)單,只導(dǎo)出兩個(gè)函數(shù):

復(fù)制代碼
//安裝Hook//ppSystemFunction,原函數(shù)地址//pHookFunction ,定制的函數(shù)地址BOOL Mhook_SetHook(PVOID *ppSystemFunction, PVOID pHookFunction);//卸載HOOK//ppHookedFuntion.原函數(shù)地址BOOL Mhook_Unhook(PVOID *ppHookedFunction);
復(fù)制代碼

a. 下載Mhook,新建一個(gè)win32 DLL工程,名稱:HookNtOpenProcessLib

b. 聲明NtOpenProcess函數(shù)和我們定制的Hook_NtOpenProcess

View Code

定制的Hook_NtOpenProcess,設(shè)置進(jìn)程句柄為NULL,保護(hù)所有進(jìn)程,針對(duì)某個(gè)進(jìn)程保護(hù),請(qǐng)通過(guò)ProcesssHandler獲取PID然后做比較

復(fù)制代碼
//===========================================================//定制我們自己的NtOpenProcessULONG WINAPI Hook_pfnNtOpenProcess(
                   __out PHANDLE ProcessHandle,
                   __in ACCESS_MASK AccessMask ,
                   __in PVOID ObjectAttributes,
                   __in PCLIENT_ID ClientId){    //ULONG result  = _NtOpenProcess( ProcessHandle,AccessMask,ObjectAttributes,ClientId);    //DWORD pid = GetProcessIdByHandle( ProcessHandle);    //通過(guò)進(jìn)程句柄獲取PID,然后驗(yàn)證    //if(gProtectProcessID == pid ){    //  return STATUS_ACCESS_DENIED;    //}    
    //return result;    //===================================    //簡(jiǎn)單處理,直接設(shè)置ProcessHandle,保護(hù)所有
    ProcessHandle = NULL;    return  _NtOpenProcess( ProcessHandle, AccessMask,ObjectAttributes,ClientId);
}
復(fù)制代碼

c. 安裝消息鉤子,跟一篇博文一樣,通過(guò)SetWindowsHookEx,只是在調(diào)用該函數(shù)時(shí)候需要注意區(qū)別下32位系統(tǒng)和64位系統(tǒng)情況,例如:

復(fù)制代碼
extern "C" __declspec(dllexport)  BOOL InstallHook(DWORD pid)
{    
    BOOL bResult=FALSE;     //這里需要注意X86和X64下處理是不一樣的
    #ifdef _M_IX86
          glhHook = SetWindowsHookEx(WH_SHELL,ShellHookProc,glhInstance, 0);    #elif defined _M_X64
           glhHook = SetWindowsHookEx(WH_SHELL,ShellHookProc,0, 0);  //第三參數(shù)為0,而不是當(dāng)前模塊的實(shí)例句柄 
    #endif

    if(glhHook!=NULL)
    {
          gProtectProcessID = pid;
          bResult=TRUE;
    }    

    return bResult; 
}
復(fù)制代碼

d.C#調(diào)用HOOKNtOpenProcessLib.dll

View Code

e.程序運(yùn)行效果讀,第一張通過(guò)ARK工具查看inline hook了NtOpenProcess,NtOpenProcess進(jìn)入內(nèi)核后是通過(guò)調(diào)用ZwOpenProcess的,所以我們看到ZwOpenProcess也被Inline hook了,第2張通過(guò)任務(wù)管理器結(jié)束進(jìn)程

關(guān)于程序中一些注意問(wèn)題:

1. 編譯HookNtOpenProcessLib.dll時(shí)候,如果要運(yùn)行在64位系統(tǒng)下,通過(guò)“配置管理器”設(shè)置下平臺(tái)X64(也就是你要編譯兩份DLL,一份是平臺(tái)為win32的,一個(gè)是X64下的)

2. 附件中C#程序,如果希望運(yùn)行在32位和64位系統(tǒng)上,請(qǐng)通過(guò)“配置管理器”設(shè)置平臺(tái)為“AnyCPU”

3. 將編譯好的dll(32位和64位)的放在測(cè)試demo下,測(cè)試demo在調(diào)用InstallHook時(shí)候,內(nèi)部SetWindowsHookEx會(huì)根據(jù)當(dāng)前平臺(tái)調(diào)用對(duì)應(yīng)的HookNtOpenProcessLib.dll

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多