国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Windows下的函數hook技術

2019-11-17 05:09:40
字體:
來源:轉載
供稿:網友

  都是很成熟的東西了,這幾天看了看,總結一下而已。
討論了Windows下hook函數的幾種方法。提供了一個hook TextOutA的完整例子。通過CreateRemoteThread的方法把hook dll注入到一個普通的應用程序中。Hooking Imported Functions by name調用imported functions'時的步驟/實現
在程序中調用從其它模塊引入的函數的方法和普通的函數調用有所不同。對于普通的函數調用,直接使用
call address來調用即可,但是對于
imported functions
,在編譯的時候
compiler/link
并不知道實際的函數實現會被加載到那個地址,函數實現在那個地址在運行的時候才會確定。對于
imported functions
,首先是
call
引入表中的一個函數,在運行時再初始化引入表,使用
jmp
跳轉到真實的函數實現。

引入表:
The PE file IMAGE_IMPORT_DESCRipTORstrUCture, which holds all the information about functions imported from a specific DLL, has pointers to two arrays in the executable. These arrays are called import address tables (IATs), or sometimes thunk data arrays. The first pointer references the real IAT, which the PRogram loader fixes up when the executable is loaded. The second pointer references the original IAT, which is untouched by the loader and lists the imported functions.

實現原理
  • 找到
    PE
    文件的
    Image_Import_Descriptor
    結構
  • 找到
    Original LAT

    Real LAT.
  • 通過要
    hook
    的函數的名字在
    Original LAT
    找到要
    hook

    imported function
    在數組中的
    index.
  • 保存并修改
    Real LAT
    在相應
    index

    function address
(refer to John Robbins, BugsLayerUtil.dll)

Hooking Imported Functions by ordinal

原理和
Hook Imported functions by name
一樣,只是是通過要
hook
的函數的
ordinal

original LAT
中找到
index.

Hooking a function in this dll

當一個
DLL
是通過
LoadLibrary
載入的時候,我們無法通過
hook imported function
的方法的
hook
它中的
function
。有兩種可能的辦法處理這種情況:
第一種方法,遍歷進程空間,發現
call
指定函數的地方替換為
call hookFunction.
太麻煩,而且不安全。


第二種方法,改寫要
hook
的函數
FuncA
。比較好的方法
  1. 實現
    HookFuncA
    ,最后的實現墊入
    n

    nop.
  2. 找到要
    hook
    的函數
    FuncA
    的絕對地址,改寫前
    5
    個字節為
    jmp hookFuncA(
    假定前
    5
    個字節為
    n
    個完整的指令
    )

  3. FuncA
    的前
    5
    個字節拷貝到
    hookFuncA
    的后面,在加上一條指令jmp funcA+5.
    ----Code of HookDLL.dll, 可以通過CreateRemoteThread的方法把hook dll注入到一個普通的應用程序中。
    // HookDLL.cpp : Defines the entry point for the DLL application.
    //
    #include "stdafx.h"
    #include "HookDLL.h"
    #include "Log.h"
    //forward declare.
    LRESULT WINAPI InstallTextoutHook();
    LRESULT WINAPI UninstallTextoutHook();
    BOOL APIENTRY DllMain( HANDLE hModule,
    DWord ul_reason_for_call,
    LPVOID lpReserved
    )
    {
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    if (InstallTextoutHook())
    {
    WriteLog("Install hook success./n");
    }else
    {
    WriteLog("Intall hook failed./n");
    }
    break;
    case DLL_THREAD_ATTACH:
    break;
    case DLL_THREAD_DETACH:
    break;
    case DLL_PROCESS_DETACH:
    if (UninstallTextoutHook())
    {
    WriteLog("Uninstall hook success./n");
    }else
    {
    WriteLog("Unintall hook failed./n");
    }
    break;
    }
    return TRUE;
    }
    #define DWORD_PTR DWORD*
    #define __LOCAL_SIZE 40h
    #define NAKED_PROLOG() /
    DWORD_PTR dwRet ; /
    DWORD_PTR dwESI ; /
    { /
    __asm PUSH EBP /* Set up the standard frame.*//
    __asm MOV EBP , ESP /
    __asm SUB ESP , __LOCAL_SIZE /* Save room for the local *//
    /* variables. *//
    __asm MOV EAX , EBP /* EBP has the stack coming *//
    /* into the fn. in it. *//
    __asm ADD EAX , 4 /* Account for PUSH EBP *//
    __asm MOV EAX , [EAX] /* Get return address. *//
    __asm MOV [dwRet] , EAX /* Save return address. *//
    __asm MOV [dwESI] , ESI /* Save ESI so chkesp in dbg *//
    /* builds works. *//
    }// The common epilog part that can be shared between the stdcall and
    // cdecl hook functions.
    #define EPILOG_COMMON() /
    { /
    __asm MOV ESI , [dwESI] /* Restore ESI. *//

    __asm ADD ESP , __LOCAL_SIZE /* Take away local var space *//
    __asm MOV ESP, EBP /* Restore standard frame. *//
    __asm POP EBP /
    }
    #define COPY_CODE_LENGTH 5
    BYTE g_abOriCode[COPY_CODE_LENGTH];
    BYTE g_abJmpCode[COPY_CODE_LENGTH];
    PROC g_oriTextout;
    BOOL g_blHooked = FALSE;
    LRESULT WINAPI InstallTextoutHook()
    {
    if (g_blHooked)
    return TRUE;
    //Get TextOutA's address.
    HMODULE hGdi32 = ::LoadLibrary(_T("Gdi32.dll"));
    g_oriTextout = GetProcAddress(hGdi32, _T("TextOutA"));
    if (NULL == g_oriTextout)
    return FALSE;
    //Get the hook'a address.
    HMODULE hModule = GetModuleHandle(_T("HookDLL.dll"));
    if (NULL == hModule)
    return FALSE;
    DWORD dwHookAddr = NULL;
    __asm
    {
    mov esi, offset HookLabel;
    mov edi, 0x10000000;//0x10000000 is the dll's base address.
    sub esi, edi;
    add esi, hModule;
    mov [dwHookAddr], esi;
    }
    //Get the NOP's address.
    DWORD dwNOPAddr = NULL;
    __asm
    {
    mov esi, offset NOPLabel;
    mov edi, 0x10000000;//0x10000000 is the dll's base address.
    sub esi, edi;
    add esi, hModule;
    mov [dwNOPAddr], esi;
    }
    //Save the first 5 byte of TextOutA to g_abOriCode
    __asm
    {
    mov esi, g_oriTextout;
    lea edi, g_abOriCode;
    cld;
    movsd;
    movsb;
    }
    //Generate the jmp Hook function.
    g_abJmpCode[0] = 0xe9;
    __asm
    {
    mov eax, dwHookAddr;
    mov ebx, g_oriTextout;
    add ebx, 5;
    sub eax, ebx;
    mov dword ptr[g_abJmpCode+1], eax;
    }
    //Write the jump instruction to the textoutA.
    DWORD dwProcessId = GetCurrentProcessId();
    HANDLE hProcess = OpenProcess (PROCESS_ALL_access,
    FALSE, dwProcessId);
    if (NULL == hProcess)
    return FALSE;
    DWORD dwOldFlag;
    VirtualProtectEx(hProcess, g_oriTextout, 5, PAGE_READWRITE, &dwOldFlag);
    WriteProcessMemory(hProcess, g_oriTextout, g_abJmpCode, sizeof(g_abJmpCode), NULL);
    VirtualProtectEx(hProcess, g_oriTextout, 5, dwOldFlag, NULL);
    //Write g_abOriTextout to the end of Hook function(NOP addr), then write the jmp instruction.
    VirtualProtectEx(hProcess, (LPVOID)dwNOPAddr, 10, PAGE_READWRITE, &dwOldFlag);
    WriteProcessMemory(hProcess, (LPVOID)dwNOPAddr, g_abOriCode, sizeof(g_abOriCode), NULL);
    //Generate the jmp TextoutA + 5
    __asm
    {
    mov eax, g_oriTextout;
    mov ebx, dwNOPAddr;
    add ebx, 5;
    sub eax, ebx;
    mov dword ptr[g_abJmpCode+1], eax;
    }
    WriteProcessMemory(hProcess, (LPVOID)(dwNOPAddr+5), g_abJmpCode, sizeof(g_abJmpCode), NULL);

    VirtualProtectEx(hProcess, (LPVOID)dwNOPAddr, 10, dwOldFlag, NULL);
    g_blHooked = TRUE;
    if(TRUE)
    return TRUE;
    HookLabel:
    NAKED_PROLOG ( ) ;
    int nx, ny;
    LPCSTR lp;
    lp = NULL;
    _asm
    {
    mov esi, ebp;
    add esi, 0Ch;
    lea edi, nx;
    movsd;
    lea edi, ny;
    movsd;

    lea edi, lp;
    movsd;
    }
    WriteLog_F("Try to ouput /"%s/" at (%d,%d)/n", lp, nx, ny);
    // Do the common epilog.
    EPILOG_COMMON ( ) ;
    NOPLabel:
    _asm NOP
    _asm NOP
    _asm NOP
    _asm NOP
    _asm NOP
    _asm NOP
    _asm NOP
    _asm NOP
    _asm NOP
    _asm NOP
    _asm NOP
    }
    LRESULT WINAPI UninstallTextoutHook()
    {
    if (!g_blHooked)
    return FALSE;
    //Restore the first 5 bytes code of TextOutA
    DWORD dwProcessId = GetCurrentProcessId();
    HANDLE hProcess = OpenProcess (PROCESS_ALL_ACCESS,
    FALSE, dwProcessId);
    if (NULL == hProcess)
    return FALSE;
    DWORD dwOldFlag;
    VirtualProtectEx(hProcess, g_oriTextout, 5, PAGE_READWRITE, &dwOldFlag);
    WriteProcessMemory(hProcess, g_oriTextout, g_abOriCode, sizeof(g_abOriCode), NULL);
    VirtualProtectEx(hProcess, g_oriTextout, 5, dwOldFlag, NULL);
    g_blHooked = FALSE;
    return TRUE;
    }
更多文章 更多內容請看Windows操作系統安全集  Windows操作系統安裝  Windows頻道專題,或

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 仁化县| 商城县| 榆林市| 景东| 黑水县| 十堰市| 嘉义县| 吉林省| 扎鲁特旗| 丘北县| 张家港市| 澄江县| 新竹市| 凉城县| 育儿| 岚皋县| 中江县| 潍坊市| 察哈| 垣曲县| 璧山县| 敦化市| 南京市| 平昌县| 施秉县| 阳山县| 高陵县| 河津市| 宿迁市| 巨鹿县| 调兵山市| 吉林市| 蓝田县| 萍乡市| 邓州市| 抚顺市| 佛山市| 修文县| 枣强县| 建湖县| 公主岭市|