欧美vvv,亚洲第一成人在线,亚洲成人欧美日韩在线观看,日本猛少妇猛色XXXXX猛叫

新聞資訊

    、HOOK介紹(鉤子,掛鉤)

    是一種實現Windows平臺下類似于中斷的機制。HOOK機制允許應用程序攔截并處理Windows消息或指定事件,當指定的消息發出后,HOOK程序就可以在消息到達目標窗口之前將其捕獲,從而得到對消息的控制權,進而可以對該消息進行處理或修改,加入我們所需的功能。私信小編“01”獲取資料與聽課權限

    鉤子按使用范圍分,可分為線程鉤子和系統鉤子,其中,系統鉤子具有相當大的功能,幾乎可以實現對所有Windows消息的攔截、處理和監控。這項技術涉及到兩個重要的API:

    一個是SetWindowsHookEx,安裝鉤子。

    另一個是UnHookWindowsHookEx,卸載鉤子。

    本文介紹的HOOK API技術,是指截獲系統或進程對某個API函數的調用,使得API的執行流程轉向我們指定的代碼段,從而實現我們所需的功能。

    Windows下的每個進程均擁有自己的地址空間,并且進程只能調用其地址空間內的函數,因此HOOK API尤為關鍵的一步是,設法將自己的代碼段注入到目標進程中,才能進一步實現對該進程調用的API進行攔截。

    然而微軟并沒有提供HOOK API的調用接口,這就需要開發者自己編程實現,大家所熟知的防毒軟件、防火墻軟件等均采用HOOK API實現。

    2、常用的HOOK類型

    1、WH_CALLWNDPROC和WH_CALLWNDPROCRET Hooks

    WH_CALLWNDPROC和WH_CALLWNDPROCRET Hooks使你可以監視發送到窗口過程的消息。系統在消息發送到接收窗口過程之前調用WH_CALLWNDPROC Hook子程,并且在窗口過程處理完消息之后調用WH_CALLWNDPROCRET Hook子程。WH_CALLWNDPROCRET Hook傳遞指針到CWPRETSTRUCT結構,再傳遞到Hook子程。CWPRETSTRUCT結構包含了來自處理消息的窗口過程的返回值,同樣也包括了與這個消息關聯的消息參數。

    2、WH_CBT Hook

    在以下事件之前,系統都會調用WH_CBT Hook子程,這些事件包括:

    激活,建立,銷毀,最小化,最大化,移動,改變尺寸等窗口事件;

    完成系統指令;

    來自系統消息隊列中的移動鼠標,鍵盤事件;

    設置輸入焦點事件;

    同步系統消息隊列事件。

    Hook子程的返回值確定系統是否允許或者防止這些操作中的一個。

    3、WH_DEBUG Hook

    在系統調用系統中與其他Hook關聯的Hook子程之前,系統會調用WH_DEBUG Hook子程。你可以使用這個Hook來決定是否允許系統調用與其他Hook關聯的Hook子程。

    4、WH_FOREGROUNDIDLE Hook

    當應用程序的前臺線程處于空閑狀態時,可以使用WH_FOREGROUNDIDLE Hook執行低優先級的任務。當應用程序的前臺線程大概要變成空閑狀態時,系統就會調用WH_FOREGROUNDIDLE Hook子程。

    5、WH_GETMESSAGE Hook

    應用程序使用WH_GETMESSAGE Hook來監視從GetMessage or PeekMessage函數返回的消息。你可以使用WH_GETMESSAGE Hook去監視鼠標和鍵盤輸入,以及其他發送到消息隊列中的消息。

    6、WH_JOURNALPLAYBACK Hook

    WH_JOURNALPLAYBACK Hook使應用程序可以插入消息到系統消息隊列??梢允褂眠@個Hook回放通過使用WH_JOURNALRECORD Hook記錄下來的連續的鼠標和鍵盤事件。只要WH_JOURNALPLAYBACK Hook已經安裝,正常的鼠標和鍵盤事件就是無效的。WH_JOURNALPLAYBACK Hook是全局Hook,它不能象線程特定Hook一樣使用。WH_JOURNALPLAYBACK Hook返回超時值,這個值告訴系統在處理來自回放Hook當前消息之前需要等待多長時間(毫秒)。這就使Hook可以控制實時事件的回放。WH_JOURNALPLAYBACK是system-wide local hooks,它們不會被注射到任何行程位址空間。(估計按鍵精靈是用這個hook做的)

    7、WH_JOURNALRECORD Hook

    WH_JOURNALRECORD Hook用來監視和記錄輸入事件。典型的,可以使用這個Hook記錄連續的鼠標和鍵盤事件,然后通過使用WH_JOURNALPLAYBACK Hook來回放。WH_JOURNALRECORD Hook是全局Hook,它不能象線程特定Hook一樣使用。WH_JOURNALRECORD是system-wide local hooks,它們不會被注射到任何行程位址空間。

    8、WH_KEYBOARD Hook

    在應用程序中,WH_KEYBOARD Hook用來監視WM_KEYDOWN and WM_KEYUP消息,這些消息通過GetMessage or PeekMessage function返回。可以使用這個Hook來監視輸入到消息隊列中的鍵盤消息。

    9、WH_KEYBOARD_LL Hook

    WH_KEYBOARD_LL Hook監視輸入到線程消息隊列中的鍵盤消息。

    10、WH_MOUSE Hook

    WH_MOUSE Hook監視從GetMessage 或者 PeekMessage 函數返回的鼠標消息。使用這個Hook監視輸入到消息隊列中的鼠標消息。

    11、WH_MOUSE_LL Hook

    WH_MOUSE_LL Hook監視輸入到線程消息隊列中的鼠標消息。

    12、WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks

    WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks使我們可以監視菜單,滾動條,消息框,對話框消息并且發現用戶使用ALT+TAB or ALT+ESC 組合鍵切換窗口。WH_MSGFILTER Hook只能監視傳遞到菜單,滾動條,消息框的消息,以及傳遞到通過安裝了Hook子程的應用程序建立的對話框的消息。WH_SYSMSGFILTER Hook監視所有應用程序消息。WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks使我們可以在模式循環期間過濾消息,這等價于在主消息循環中過濾消息。通過調用CallMsgFilter function可以直接的調用WH_MSGFILTER Hook。通過使用這個函數,應用程序能夠在模式循環期間使用相同的代碼去過濾消息,如同在主消息循環里一樣。

    13、WH_SHELL Hook

    外殼應用程序可以使用WH_SHELL Hook去接收重要的通知。當外殼應用程序是激活的并且當頂層窗口建立或者銷毀時,系統調用WH_SHELL Hook子程。

    WH_SHELL 共有5鐘情況:

    只要有個top-level、unowned 窗口被產生、起作用、或是被摧毀;

    當Taskbar需要重畫某個按鈕;

    當系統需要顯示關于Taskbar的一個程序的最小化形式;

    當目前的鍵盤布局狀態改變;

    當使用者按Ctrl+Esc去執行Task Manager(或相同級別的程序)。

    按照慣例,外殼應用程序都不接收WH_SHELL消息。所以,在應用程序能夠接收WH_SHELL消息之前,應用程序必須調用SystemParametersInfo function注冊它自己。

    以上是13種常用的hook類型!

    3、鉤子部分的實現

    鉤子安裝函數

    其中:

    對消息WH_MOUSE_LL進行了鉤取。

    當捕捉到該消息時,交由LowLevelMouseProc函數進行操作。

    g_hInstance是返回自身句柄的函數

    鉤子處理函數

    鉤子處理函數向g_hWnd句柄發送WM_HOOKMSG消息。

    然后將上述函數打包成DLL文件。

    4、調用鉤子的實現

    導入DLL并安裝消息鉤子

    5、實現效果

    在沒有使用鉤子情況下,不會對鼠標消息進行捕捉。

    當點擊啟動鼠標HOOK后,會隨著鼠標進行移動,并捕獲鼠標消息。


    6、小結

    本次HOOK選擇的目標是自己,下一節將會介紹如何HOOK其他進程。

    hook技術應用廣泛,如熱補丁升級技術,API劫持,軟件破解等,是一門很實用的逆向安全技術。本文就簡明的講解hook技術的基本原理,實現方法,同時送上demo實例。

    一. HOOK技術的基本原理


    HOOK的基本原理

    Hook技術的原理的:就是修改程序的運行時PC指針,讓程序跳到我們指定的代碼中運行,運行完我們的程序,程序PC指針又回到原來程序的下一條指令。簡而言之:就篡改程序的運行路徑,來執行我們的程序。

    二.Hook技術的實現

    1)需求分析

    Hook的基本流程

    原來的程序中的test.exe調用myprintf,現在我們要實現不編譯源代碼test.exe和test_dll源代碼的前提下(你懂的,破解軟件都是拿不到源代碼的)讓test.exe去調用MyPrintf_new。

    其中:

    test_dll的實現:

    int MyPintf(int d)
    {
         printf("hello,this is test ,test value is %d\n", d);
          return d+1;
    }
    

    test.exe的實現:

    int _tmain(int argc, _TCHAR* argv[])
    {
        int d = 0;
        d = MyPintf(2);
        printf("d %d\n", d);
        getchar();
        return 0;
    }
    

    我們目標要實現main函數調用MyPintf_new

    int  MyPintf_new(int d)
    {
        printf("hello,this is my hook test ,test value is %d\n", d);
        return d+10;
    }
    

    其中MyPintf_new我們在hook_dll中實現。

    2)關鍵代碼的實現

    在hook_dll加載時篡改MyPintf的跳轉指令。

    其中

    GetApiEntrance()備份原來的跳轉指令,構造新函數的跳轉指令。

    HookOn()用于改寫進程空間中目標函數的跳轉指令

    HookOff()用于還原進程空間中目標函數的跳轉指令

    void GetApiEntrance()
    {
    
        //獲取原API入口地址
        HMODULE hmod = ::GetModuleHandle(L"test_dll.dll");
        OldFun = (fun)::GetProcAddress(hmod, "MyPintf");
        pfOldFun = (FARPROC)OldFun;
        if (pfOldFun == NULL)
        {
            printf("獲取原API入口地址出錯");
            return;
        }
    //    OldFun(88);
    #ifndef WIN64
        // 將原API的入口前5個字節代碼保存到OldCode[]
        _asm
        {
               lea edi, OldCode     //獲取OldCode數組的地址,放到edi
                mov esi, pfOldFun //獲取原API入口地址,放到esi
                cld   //方向標志位,為以下兩條指令做準備
                movsd //復制原API入口前4個字節到OldCode數組
                movsb //復制原API入口第5個字節到OldCode數組
        }
    
    
        NewCode[0] = 0xe9;//實際上0xe9就相當于jmp指令
    
        //獲取MyPintf_new的相對地址,為Jmp做準備
        //int nAddr= UserFunAddr – SysFunAddr - (我們定制的這條指令的大小);
        //Jmp nAddr;
        //(我們定制的這條指令的大?。? 這里是5,5個字節嘛
        //BYTE NewCode[5];
        _asm
        {
                lea eax, MyPintf_new //獲取我們的MyPintf_new函數地址
                mov ebx, pfOldFun  //原系統API函數地址
                sub eax, ebx             //int nAddr= UserFunAddr – SysFunAddr
                sub eax, 5           //nAddr=nAddr-5
                mov dword ptr[NewCode + 1], eax //將算出的地址nAddr保存到NewCode后面4個字節
                //注:一個函數地址占4個字節
        }
    
    #else
    //    JMP_X64(OldCode, pfOldFun, NewCode);
    #endif
    
        //填充完畢,現在NewCode[]里的指令相當于Jmp MyPintf_new
        //既然已經獲取到了Jmp MyMessageBoxW
        //現在該是將Jmp MyMessageBoxW寫入原API入口前5個字節的時候了
        //知道為什么是5個字節嗎?
        //Jmp指令相當于0xe9,占一個字節的內存空間
        //MyMessageBoxW是一個地址,其實是一個整數,占4個字節的內存空間
        //int n=0x123;   n占4個字節和MyPintf_new占4個字節是一樣的
        //1+4=5,知道為什么是5個字節了吧
        HookOn();
    }
    //開啟鉤子的函數
    void HookOn()
    {
    #ifdef WIN64
    //to do it 
    #else
        DWORD dwPid = ::GetCurrentProcessId();
        //printf("pid %d\n", dwPid);
        hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, dwPid);
        assert(hProcess != NULL);
        //printf("HookOn now,hProcess %d\n", hProcess);
        DWORD dwTemp = 0;
        DWORD dwOldProtect;
    
        //修改API函數入口前5個字節為jmp xxxxxx
        VirtualProtectEx(hProcess, pfOldFun, 5, PAGE_READWRITE, &dwOldProtect);
        WriteProcessMemory(hProcess, pfOldFun, NewCode, 5, 0);
        VirtualProtectEx(hProcess, pfOldFun, 5, dwOldProtect, &dwTemp);
    #endif
        printf("HookOn end\n");
    
    }
    
    //關閉鉤子的函數
    void HookOff()
    {
    #ifdef WIN64
    //to do it
    #else
        assert(hProcess != NULL);
    
        DWORD dwTemp = 0;
        DWORD dwOldProtect;
    
        //恢復API函數入口前5個字節
        VirtualProtectEx(hProcess, pfOldFun, 5, PAGE_READWRITE, &dwOldProtect);
        WriteProcessMemory(hProcess, pfOldFun, OldCode, 5, 0);
        VirtualProtectEx(hProcess, pfOldFun, 5, dwOldProtect, &dwTemp);
    #endif
    }
    
    4)使用工具將hook_dll.dll打進test.exe導入表,讓test.exe拉起hook_dll.dll。
    這樣test.exe啟動時就能加載hook_dll.dll,同時調用GetApiEntrance完成hook的初始化。
    

    三 結果演示

    原始的test.exe 演示效果

    Hook之后的test.exe演示效果

    對于64位hook,由于64位系統的指令系統,寄存器空間也不一樣。需要研究一下X64的指令系統以及寄存器使用?;舅悸肥且粯拥?,唯獨就是JMP那條指令實現不一樣,敬請期待。

    更多更詳細信息請關注公眾號:AV_Chat

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有