《逆向工程核心原理》——IAThook

hook逻辑写入dll中,注入dll。

#include "pch.h"
#include <tchar.h>
#include "windows.h"
//WINBASEAPI
//BOOL
//WINAPI
//WriteFile(
//    _In_ HANDLE hFile,
//    _In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer,
//    _In_ DWORD nNumberOfBytesToWrite,
//    _Out_opt_ LPDWORD lpNumberOfBytesWritten,
//    _Inout_opt_ LPOVERLAPPED lpOverlapped
//);
typedef BOOL(WINAPI* PFWRITEFILE)(HANDLE hFile,
    LPCVOID lpBuffer,
    DWORD nNumberOfBytesToWrite,
    LPDWORD lpNumberOfBytesWritten,
    LPOVERLAPPED lpOverlapped);
FARPROC g_pOrgFunc = NULL;//全局变量

BOOL hook_iat(LPCSTR szDllName, PROC pfnOrg, PROC pfnNew)//负责勾取IAT
{

    LPCSTR szLibName;
    PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
    PIMAGE_THUNK_DATA64 pThunk;
    DWORD dwOldProtect;
    DWORD dwRVA;
    PBYTE pAddr;//8字节

    pAddr = (PBYTE)GetModuleHandle(NULL);//pAddr = ImageBase;获得内存中装载的地址
    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pAddr;//指向dos头
    PIMAGE_NT_HEADERS64 pNT = (PIMAGE_NT_HEADERS64)(pAddr + pDosHeader->e_lfanew);//指向pe头
    dwRVA = pNT->OptionalHeader.DataDirectory[1].VirtualAddress;//pe头--》可选头--》数据目录--》第2项 输入表;取得输入表rva
    pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)(pAddr + dwRVA);//输入表的内存地址

    for (; pImportDesc->Name; pImportDesc++)//循环遍历IDT;(IMAGE_IMPORT_DESCRIPTOR数组)
    {
        szLibName = (LPCSTR)(pAddr + pImportDesc->Name);// szLibName = VA to IMAGE_IMPORT_DESCRIPTOR.Name
        if (!_stricmp(szLibName, szDllName))//找到对应dll名的IID;(IMAGE_IMPORT_DESCRIPTOR)
        {
            // pThunk = IMAGE_IMPORT_DESCRIPTOR.FirstThunk
            //        = VA to IAT(Import Address Table)
            pThunk = (PIMAGE_THUNK_DATA64)(pAddr + pImportDesc->FirstThunk);//系统装载结束后,FirstThunk指向IAT,  pThunk就是IAT

            for (; pThunk->u1.Function; pThunk++)// pThunk->u1.Function = VA to API 遍历IAT
            {
                if (pThunk->u1.Function == (ULONGLONG)pfnOrg)//查找要hook函数的地址
                {
                    VirtualProtect((LPVOID)&pThunk->u1.Function, 8, PAGE_EXECUTE_READWRITE, &dwOldProtect);
                    pThunk->u1.Function = (ULONGLONG)pfnNew;//修改IAT的值
                    VirtualProtect((LPVOID)&pThunk->u1.Function, 8, dwOldProtect, &dwOldProtect);
                    return TRUE;
                }
            }
        }
    }    return FALSE;
}
BOOL WINAPI MyFunc(HANDLE hFile,
    LPCVOID lpBuffer,
    DWORD nNumberOfBytesToWrite,
    LPDWORD lpNumberOfBytesWritten,
    LPOVERLAPPED lpOverlapped)
{
    char* pc = (char*)lpBuffer;
    //小写转大写-0x20
    while (*pc) {
        if (*pc >= 'a' && *pc <= 'z')
            *pc -= 0x20;
        pc++;
    }
    return ((PFWRITEFILE)g_pOrgFunc)(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);//调用原WriteFile
}

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        g_pOrgFunc = GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "WriteFile");//保存原始API地址
        hook_iat("kernel32.dll", g_pOrgFunc, (PROC)MyFunc);//使用hookiat!MySetWindowText()勾取kernel32.dll中的WriteFile函数
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
        hook_iat("kernel32.dll", (PROC)MyFunc, g_pOrgFunc);//unhook,恢复IAT原来的值
        break;
    }
    return TRUE;
}

 

64位和32位pe有些结构大小不同,IMAGE_NT_HEADERS64;IMAGE_OPTIONAL_HEADER64;IMAGE_THUNK_DATA64……

posted @ 2020-08-12 21:20  DirWangK  阅读(315)  评论(0编辑  收藏  举报