获取当前的图像基址

时间:2017-02-09 00:00:08

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

我进行了一些计算以获得相对虚拟地址(RVA)。

我计算了一个正确的RVA(根据.map文件),我想把它翻译成一个可调用的函数指针。

有没有办法将其翻译成实际地址?

我想过拍摄图像基地并添加它。根据{{​​3}},应该可以通过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)不正确。

1 个答案:

答案 0 :(得分:1)

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

假设基地址未重新定位到另一个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;
}