IAT挂钩实现和检测

  • IAT - Import Address Table ,导入地址列表。这里保存着各个导入的函数加载后的地址,它是动态的,随着Dll的加载的位置不同而不同。
  • PE - Portable Execute 可执行的程序结构。在PE结构中有个数据目录(Data Directory) 内部保存导入表的数据。格式大概如下:
    dll-数据 1
    函数数据1
    函数数据2
    函数数据3

    dll-数据 2
  • 我们根据PE的格式找到函数的已经定位的位置,然后修改这个位置,就能用自己的函数替换这个函数。(再此之前保留好原来的函数)
  • 下面以win32 的程序为例,代码如下
#include <windows.h>
#include <stdio.h>
void* test()
{
    void* a = MessageBoxA;
    return a;
}
VOID* g_lpMsgBox = NULL;
typedef int(WINAPI *LpMsgBox)(HWND wnd, char* msg, char* title, UINT btn);

int WINAPI MyMessageBox(HWND wnd, char* msg, char* title, UINT btn)
{
    char buf[256] = {0};
    strcpy(buf, msg);
    strcat(buf, "+mybox");
    ((LpMsgBox)g_lpMsgBox)(wnd, buf, title, btn);
    return 0;
}

BOOL checkIATHook()
{
    PIMAGE_DOS_HEADER dos_header = GetModuleHandle(NULL);
    PIMAGE_NT_HEADERS nt_headers = (LPBYTE)dos_header + dos_header->e_lfanew;
    DWORD import_rva = nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
    LPBYTE import_va = (LPBYTE)dos_header + import_rva;
    PIMAGE_IMPORT_DESCRIPTOR imp_desc = import_va;
    while (1){
        if (imp_desc->Name)
        {
            char* name = (LPBYTE)dos_header + imp_desc->Name;
            HMODULE imp_dll = GetModuleHandleA(name);

            PIMAGE_THUNK_DATA thunk = (LPBYTE)dos_header + imp_desc->FirstThunk;
            PIMAGE_THUNK_DATA thunk1 = (LPBYTE)dos_header + imp_desc->OriginalFirstThunk;
            for (;;)
            {
                if (thunk->u1.ForwarderString == 0)
                {
                    break;
                }
                //序号导入
                if (thunk->u1.ForwarderString & IMAGE_ORDINAL_FLAG)
                {
                    //
                    __asm nop;
                }
                else
                {
                    //名称导入
                    PIMAGE_IMPORT_BY_NAME fnName = (LPBYTE)dos_header + thunk1->u1.AddressOfData;
                    DWORD proc_addr = GetProcAddress(imp_dll, fnName->Name);
                    if (thunk->u1.Function != proc_addr)
                    {
                        printf("%s be hooked : 0x%x\n", fnName->Name, thunk->u1.Function);
                    }
                    __asm nop;
                }
                thunk += 1;
                thunk1 += 1;
            }
            imp_desc += 1;
        }
        else
        {
            break;
        }
    }
    return TRUE;
}
void hookMessageBoxA()
{
    PIMAGE_DOS_HEADER dos_header = GetModuleHandle(NULL);
    PIMAGE_NT_HEADERS nt_headers = (LPBYTE)dos_header + dos_header->e_lfanew;
    DWORD import_rva = nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
    LPBYTE import_va = (LPBYTE)dos_header + import_rva;
    PIMAGE_IMPORT_DESCRIPTOR imp_desc = import_va;
    while (1){
        if (imp_desc->Name)
        {
            char* name = (LPBYTE)dos_header + imp_desc->Name;
            if (stricmp(name, "user32.dll") == 0)
            {
                PIMAGE_THUNK_DATA thunk = (LPBYTE)dos_header + imp_desc->FirstThunk;
                PIMAGE_THUNK_DATA thunk1 = (LPBYTE)dos_header + imp_desc->OriginalFirstThunk;
                for (;;)
                {
                    if (thunk->u1.ForwarderString == 0)
                    {
                        break;
                    }
                    if (thunk->u1.ForwarderString&IMAGE_ORDINAL_FLAG)
                    {
                        //
                        __asm nop;
                    }
                    else
                    {
                        PIMAGE_IMPORT_BY_NAME fnName = (LPBYTE)dos_header + thunk1->u1.AddressOfData;
                        if (strcmp(fnName->Name, "MessageBoxA")==0)
                        {
                            g_lpMsgBox = thunk->u1.Function;
                            DWORD prFlag;
                            BOOL b = VirtualProtect(&imp_desc->FirstThunk, 4, PAGE_EXECUTE_READWRITE, &prFlag);
                            if (b)
                            {
                                *(DWORD*)thunk = MyMessageBox;
                            }
                            VirtualProtect(&imp_desc->FirstThunk, 4, prFlag, &prFlag);
                        }
                        return;
                        __asm nop;
                    }
                    thunk += 1;
                }
            }
            imp_desc += 1;
        }
        else
        {
            break;
        }
    }

}
int main(int argc, char** argv)
{
    test();
    hookMessageBoxA();
    checkIATHook();
    MessageBoxA(NULL, "msg", "haha", MB_OK);

    return 0;
}

猜你喜欢

转载自blog.csdn.net/justin_bkdrong/article/details/77649927