zoukankan      html  css  js  c++  java
  • 《逆向工程核心原理》——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……

  • 相关阅读:
    23种设计模式(转载)
    RabbitMQ JAVA客户端调用
    JavaScript中的this
    RedisDesktopManager 踩坑之旅
    webmagic使用手册
    Maven 手动添加本地jar包
    根据端口号查询 进程 并杀掉进程
    从经典面试题看java中类的加载机制
    Java线程的5种状态及切换(透彻讲解)
    JVM 类加载机制详解
  • 原文地址:https://www.cnblogs.com/DirWang/p/13493058.html
Copyright © 2011-2022 走看看