繁体   English   中英

C - 运行时内联汇编补丁

[英]C - Inline asm patching at runtime

我正在用 C 编写一个程序,我使用内联汇编。 在内联汇编代码中有一些地址,我想在运行时修补它们。

代码的一个快速示例是这样的:

void __declspec(naked) inline(void)
{
      mov eax, 0xAABBCCDD
      call 0xAABBCCDD
}

说我想修改主 C 程序中的 0xAABBCCDD 值。 我试图做的是调用 VirtualProtect 和函数的指针以使其可写,然后调用 memcpy 将适当的值添加到代码中。

DWORD old;
VirtualProtect(inline, len, PAGE_EXECUTE_READWRITE, &old);

但是 VirtualProtect 失败并且 GetLastError() 返回 487,这意味着访问无效地址。 任何人都有这个问题的线索? 谢谢

如何在运行时对另一个进程执行此操作,

  1. 创建一个保存程序基地址的变量
  2. 获取目标 RVA(相对虚拟地址)
  3. 然后像这样计算真实地址 PA=RVA + BASE
  4. 然后从您的内联程序集中调用它

你可以像这样获得基地址

DWORD dwGetModuleBaseAddress(DWORD dwProcessID)
{
    TCHAR zFileName[MAX_PATH];
    ZeroMemory(zFileName, MAX_PATH);

    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, true, dwProcessID);
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessID);
    DWORD dwModuleBaseAddress = 0;

    if (hSnapshot != INVALID_HANDLE_VALUE)
    {
        MODULEENTRY32 ModuleEntry32 = { 0 };
        ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
        if (Module32First(hSnapshot, &ModuleEntry32))
        {
            do
            {
                if (wcscmp(ModuleEntry32.szModule, L"example.exe") == 0)
                {
                    dwModuleBaseAddress = (DWORD_PTR)ModuleEntry32.modBaseAddr;
                    break;
                }
            } while (Module32Next(hSnapshot, &ModuleEntry32));
        }
        CloseHandle(hSnapshot);
        CloseHandle(hProcess);
    }
    return dwModuleBaseAddress;
}

假设你有一个局部变量和你的基地址

mov     dword ptr ss : [ebp - 0x14] , eax;
mov     eax, dword ptr BaseAddress;
add     eax, PA;
call    eax;
mov     eax, dword ptr ss : [ebp - 0x14] ;

您必须在调用返回后恢复 Register 的值,因为该值可能会在代码执行的某个地方使用,假设您正在尝试修补可能在调用后依赖于 eax 寄存器的现有应用程序。 虽然这种方法有它的缺点,但至少它会让任何人知道该怎么做。

这不行吗?

int X = 0xAABBCCDD;

void __declspec(naked) inline(void)
{
      mov eax, [X]
      call [X]
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM