【问题标题】:Get current Image Base address获取当前图像基地址
【发布时间】:2017-02-09 00:00:08
【问题描述】:

我做了一些计算得到一个相对虚拟地址(RVA)。

我计算了一个正确的 RVA(根据 .map 文件)并且我想将它转换为一个可调用的函数指针。

有没有办法把它翻译成物理地址?

我想到了获取图像基地址并添加它。根据this thread,应该可以通过GetModuleHandle(NULL),但结果是“错误的”。只有当我从 .map 文件中定义的函数的 RVA 中减去一个函数的指针时,我才会得到一个好的结果。

是否有 WINAPI 可以将 RVA 转换为物理地址,或者获取图像基地址,或者获取物理地址的 RVA?

下面是一些示例代码:

#include <stdio.h>
#include <Windows.h>
#include <WinNT.h>

static int count = 0;
void reference()       // According to .map RVA = 0x00401000
{
}
void toCall()          // According to .map RVA = 0x00401030
{
    printf("Called %d\n", ++count);
}

int main()
{
    typedef void (*fnct_t)();
    fnct_t fnct;
    fnct = (fnct_t) (0x00401030 + (((int) reference) - 0x00401000));
    fnct(); // works
    fnct = (fnct_t) (0x00401030 + ((int) GetModuleHandle(NULL)) - 0x00400000);
    fnct(); // often works
    return 0;
}

我主要担心的是,有时(可能在线程上下文中)GetModuleHandle(NULL) 似乎不正确。

【问题讨论】:

  • GetModuleHandle(NULL) but the result is "wrong". - 你是什么意思? physical address - 你的意思是 虚拟地址 (VA) ? VA== ImageBase + RVA
  • 发布您的代码。
  • 物理地址与驱动程序相关。您使用虚拟地址。你的意思是绝对的而不是物理的?
  • 大概,我的意思是“能够从函数指针调用它的正确级别”,是虚拟地址吗?

标签: c++ c windows visual-studio winapi


【解决方案1】:

要在编译时不直接预定义入口点的情况下获取映像库,您可以执行简单的搜索,从当前 VA 对齐 eax@1000h 并循环直到在当前 VA 中找到有效的 PE 签名“MZ”内存页。

假设基地址没有重定位到另一个 PE 映像中。我为你准备了一个函数:

DWORD FindImageBase() {
    DWORD* VA = (DWORD *) &FindImageBase, ImageBase;
    __asm {
            mov eax, VA
            and eax, 0FFFF0000h
        search:
            cmp word ptr [eax], 0x5a4d
            je stop
            sub eax, 00010000h
            jmp search
        stop:
            mov [ImageBase], 0
            mov [ImageBase], eax
    }
    return ImageBase;
}

【讨论】:

  • 为什么mov [ImageBase], 0mov [ImageBase], eax 之前?
猜你喜欢
  • 2014-04-12
  • 2021-08-31
  • 1970-01-01
  • 2021-07-04
  • 1970-01-01
  • 2016-05-04
  • 2013-01-12
  • 2018-12-18
  • 2016-12-04
相关资源
最近更新 更多