hook技术--IAT hook

1.简介

当程序运行后IAT表才会被系统根据pe文件的导入表等信息填充该IAT字段,
填充后的IAT的函数地址是对应模块加载后真正的函数地址,程序中对dll中
的导出函数的调用也是通过该IAT的记录来调用的.因此可以通过注入dll后,
通过dll中的代码修改IAT表的记录,来实现hook.
原来的调用过程:
call [aaaaa] => IAT[aaaaaa]::bbbbb => xxx.dll::bbbbb
ret后
next code of call [aaaaa] <= next ret of xxx.dll::bbbbb
注入后的调用过程:
call [aaaaa] => IAT[aaaaaa]::ccccc => hook.dll::ccccc => xxx.dll::bbbbb
ret后
next code of call [aaaaa] <= next ret of hook.dll::ccccc => next ret of xxx.dll::bbbbb

2.测试,将calc的显示改为中文文字零到九

效果图:

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include<Windows.h>
#include<malloc.h>
#include<wchar.h>
//要hook的API所属的dll名字
#define dllName "user32.dll" 
#define funcName "SetWindowTextW"
DWORD imageBase;
DWORD funcBase;
typedef BOOL (WINAPI *TypeSetWindowTextW)(
    __in HWND hWnd,
    __in_opt LPCWSTR lpString);
DWORD hookSetWindowTextW(HWND hWnd, LPWSTR lpBuffer);
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    funcBase = (DWORD)(GetProcAddress(GetModuleHandleA(dllName), funcName));
    imageBase = (DWORD)GetModuleHandle(0);//获取本模块基址(句柄)
    IMAGE_DOS_HEADER *dosHeader = (IMAGE_DOS_HEADER*)imageBase;
    PIMAGE_NT_HEADERS32 ntHeader;
    ntHeader=(PIMAGE_NT_HEADERS32)(imageBase+dosHeader->e_lfanew);
    IMAGE_IMPORT_DESCRIPTOR *importTable = (IMAGE_IMPORT_DESCRIPTOR *)(ntHeader->OptionalHeader.DataDirectory[1].VirtualAddress + imageBase);
    IMAGE_THUNK_DATA32* iat;
    DWORD page;
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        MessageBoxA(0,"inject","inject",0);
        for(;importTable->Name;importTable++)
        {
            //MessageBoxA(0,"inject1","inject1",0);
            if(stricmp((char*)(imageBase + importTable->Name),dllName)==0)
            {
                break;
            }
        }

        if (importTable->Name!=0)
        {
            iat = (IMAGE_THUNK_DATA32*)(importTable->FirstThunk + imageBase);
            while (iat->u1.Function!=funcBase)
            {
                iat++;
            }
            if (iat->u1.Function)
            {
                VirtualProtect(&iat->u1.Function, 4, PAGE_EXECUTE_READWRITE, &page);
            
                iat->u1.Function = (DWORD)hookSetWindowTextW;
                VirtualProtect(&iat->u1.Function, 4, page, &page);
            }
        }
        
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

DWORD hookSetWindowTextW(HWND hWnd, LPWSTR lpBuffer)
{
    WCHAR chinese[] = L"零一二三四五六七八九";
    WCHAR temp[2] = { 0 };
    int index;
    for (int i = 0; i < lstrlen(lpBuffer); i++)
    {
        if (lpBuffer[i] >= L'0'&&lpBuffer[i] <= L'9')
        {
            temp[0] = lpBuffer[i];
            index = _wtoi(temp);
            lpBuffer[i] = chinese[index];
        }
    }
    return ((TypeSetWindowTextW)funcBase)(hWnd, lpBuffer);
}
原文地址:https://www.cnblogs.com/freesec/p/6558848.html