【问题标题】:Execute BYTE array in detoured function在迂回函数中执行 BYTE 数组
【发布时间】:2014-10-26 17:04:27
【问题描述】:

我知道这篇文章很长,但主要是代码和图片,可以快速阅读!首先,这是我想要做的:

我正在尝试在绕行的函数中执行 BYTE 数组,以便返回原始代码,就好像我没有绕道一样这是我的代码:

DllMain(DetourAddress 很重要):

BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved  )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        AllocConsole();
        freopen("CONOUT$", "w", stdout);

        DetourAddress((void*)HookAddress, (void*)&DetourFunc);

    case DLL_PROCESS_DETACH:
        FreeConsole();
        break;
    }

    return TRUE;
}

DetourAddress(我认为代码是不言自明的):

void DetourAddress(void* funcPtr, void* hook)
{
    // write jmp
    BYTE cmd[5] =
    { 
        0xE9, //jmp
        0x00, 0x00, 0x00, 0x00  //address
    };

    // make memory readable/writable
    DWORD dwProtect;
    VirtualProtect(funcPtr, 5, PAGE_EXECUTE_READWRITE, &dwProtect); 

    // read bytes about to be replaced
    ReadProcessMemory(GetCurrentProcess(), (LPVOID)funcPtr, mem, 5, NULL);

    // write jmp in cmd
    DWORD offset = ((DWORD)hook - (DWORD)funcPtr - 5);  // (dest address) - (source address) - (jmp size)
    memcpy(&cmd[1], &offset, 4); // write address into jmp
    WriteProcessMemory(GetCurrentProcess(), (LPVOID)funcPtr, cmd, 5, 0); // write jmp

    // reprotect
    VirtualProtect(funcPtr, 5, dwProtect, NULL);
}

DetourFunc:

_declspec(naked) void DetourFunc()
{
    __asm
    {
        PUSHFD
        PUSHAD
    }

    printf("function detoured\n");

    __asm
    {
        POPAD
        POPFD
    }

    // make memory readable/writable
    DWORD dwProtect;
    VirtualProtect(mem, 6, PAGE_EXECUTE_READWRITE, &dwProtect); 

    pByteExe();

    // reprotect
    VirtualProtect(mem, 6, dwProtect, NULL);

    __asm
    {
        jmp HookReturnAddress
    }
}

最后是全局变量,pByteExe() 的 typedef,包括:

#include <Windows.h>
#include <cstdio>

DWORD   HookAddress         = 0x08B1418,
        HookReturnAddress   = HookAddress+5;

typedef void ( * pFunc)();
BYTE mem[6] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0xC3 };
pFunc pByteExe = (pFunc) &mem

正如您在 DetourFunc 中看到的,我正在尝试直接执行我的字节数组 (mem)。使用 OllyDbg,这让我到了那里:

这正是我要执行的字节。唯一的问题是它在执行时给我一个访问冲突错误......知道为什么吗?我会想到“VirtualProtect(mem, 5, PAGE_EXECUTE_READWRITE, &dwProtect);”本来可以安全访问...感谢您的帮助!

编辑:我刚刚意识到发生了一些奇怪的事情......当我使用 ollydbg “进入”时,mem 指令是正确的,但只要我滚动一点,它们就会变回:

知道为什么吗?

【问题讨论】:

  • 你查看VirtualProtect的返回结果了吗? MSDN 上的 VirtualProtect 页面也说在修改指令后调用FlushInstructionCache
  • VirtualProtect 的错误代码是 998(对内存位置的访问无效。)即使在每次修改指令后我都调用了 FlushInstructionCache。不过感谢您的帮助!
  • 我发现了一些新东西...编辑了我的帖子
  • 这可能会引发访问冲突,因为 byte ptr ds:[esi+4] 不可访问。但是你的整体设计是有缺陷的。 x86 上的指令是可变大小的。您正在执行四个字节,但是如果指令不是 4 个字节大小怎么办?您还尝试从可能更改堆栈的代码中ret。你需要回到绘图板上。

标签: c++ windows winapi byte hook


【解决方案1】:

您忘记了模块偏移量...

DWORD module = (DWORD)GetModuleHandle(NULL);
DWORD real_address = module + (DWORD)ADDRESS;

ADDRESS 当然要相对于你的模块。 (模块偏移量并不总是相同的)

顺便说一句。为什么在注入 DLL 时使用 WriteProcessMemory?一个简单的 memcpy 就足够了...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    相关资源
    最近更新 更多