zoukankan      html  css  js  c++  java
  • 《逆向工程核心原理》——API HOOK

    编写dll处理hook逻辑,注入到目标进程,实现api hook。

    Windows10 notepad,通过hook kernel32.dll.WriteFile,实现小写字母转大写保存到文件。

    hook前kernel32.dll.WriteFile入口:

    kernel32.dll.WriteFile在调用时入口是条jmp指令

    跳转后

     hook时通过GetProcAddress得到的是jmp处的地址,在jmp指令周边有一些int 3指令,这些空间可以用来做一些跳转操作。

    #include "pch.h"
    #include <tchar.h>
    #define DLLNAME "kernel32.dll"
    #define WRITEFILE "WriteFile"
    BYTE g_pOrgBytes[6] = { 0 };
    FARPROC g_writefile = GetProcAddress(GetModuleHandleA(DLLNAME), WRITEFILE);
    
    //此函数用来将api前5个字节改为jmp xxxx 
    BOOL hook_by_code(FARPROC pfnOrg, PROC pfnNew, PBYTE pOrgBytes) {
        DWORD dwOldProtect, dwAddress;
        BYTE pBuf[6] = { 0xE9,0,0,0,0, 0x90};
        PBYTE pByte;
        pByte = (PBYTE)pfnOrg;
        if (pByte[0] == 0xE9)//若已被勾取,则返回False
            return FALSE;
        VirtualProtect((LPVOID)pfnOrg, 12, PAGE_EXECUTE_READWRITE, &dwOldProtect);//为了修改字节,先向内存添加“写”的属性
        memcpy(pOrgBytes, pfnOrg, 6);//备份原有代码
        dwAddress = (DWORD64)pfnNew - (DWORD64)pfnOrg - 5;//计算JMP地址   => XXXX = pfnNew - pfnOrg - 5
        memcpy(&pBuf[1], &dwAddress, 4);//E9,剩下后面4个字节为跳转的地址
        memcpy(pfnOrg, pBuf, 6);//复制指令,跳转到hook逻辑
        
        memcpy(&pByte[6], pOrgBytes, 6);//后面的int 3指令进行修改,跳转到原api逻辑
        pByte[8] -= 6;//修正跳转偏移
    
        VirtualProtect((LPVOID)pfnOrg, 12, dwOldProtect, &dwOldProtect);//恢复内存属性
        return TRUE;
    }
    
    BOOL unhook_by_code(FARPROC pFunc, PBYTE pOrgBytes) {
        
        DWORD dwOldProtect;
        PBYTE pByte;
        pByte = (PBYTE)pFunc;
        if (pByte[0] != 0xE9)//若已脱钩,则返回False
            return FALSE;
        VirtualProtect((LPVOID)pFunc, 6, PAGE_EXECUTE_READWRITE, &dwOldProtect);//向内存添加“写”的属性,为恢复原代码做准备
        memcpy(pFunc, pOrgBytes, 6);//脱钩
        VirtualProtect((LPVOID)pFunc, 6, dwOldProtect, &dwOldProtect);//恢复内存属性
        return TRUE;
    }
    //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)(
        _In_ HANDLE hFile,
        _In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer,
        _In_ DWORD nNumberOfBytesToWrite,
        _Out_opt_ LPDWORD lpNumberOfBytesWritten,
        _Inout_opt_ LPOVERLAPPED lpOverlapped
        );
    BOOL WINAPI  MyWriteFile(
        _In_ HANDLE hFile,
        _In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer,
        _In_ DWORD nNumberOfBytesToWrite,
        _Out_opt_ LPDWORD lpNumberOfBytesWritten,
        _Inout_opt_ LPOVERLAPPED lpOverlapped) {
        PBYTE ptr = (PBYTE)g_writefile;
        //unhook_by_code(g_writefile, g_pOrgBytes);
        BOOL ret = TRUE;
        char* pc = (char*)lpBuffer;
        while (*pc)
        {
            if (*pc >= 'a' && *pc <= 'z') {
                *pc -= 0x20;
            }
            pc++;
        }
        ret = ((PFWriteFile)(ptr+6))(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);//原入口偏移+6处是修正的原jmp指令
        //hook_by_code(g_writefile, (PROC)MyWriteFile, g_pOrgBytes);
        return ret;
    }
    
    BOOL APIENTRY DllMain(HMODULE hModule,
        DWORD  ul_reason_for_call,
        LPVOID lpReserved
    )
    {
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
            hook_by_code(g_writefile,(PROC)MyWriteFile, g_pOrgBytes);
            break;
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
            break;
        case DLL_PROCESS_DETACH:
            unhook_by_code(g_writefile,g_pOrgBytes);
            break;
        }
        return TRUE;
    }

    hook效果:

  • 相关阅读:
    PL/SQL详细介绍
    Linux服务器性能评估(转)
    oracle命令(转)
    Makefile介绍(转)
    delphi 指针
    浏览器的工作原理(转)
    高性能分布式计算与存储系统设计概要(上)(转)
    HTTP协议详解(转)
    MySQL性能优化(转)
    redhat 6.2安装telnet服务
  • 原文地址:https://www.cnblogs.com/DirWang/p/13498176.html
Copyright © 2011-2022 走看看