我做了一些计算来获得相对虚拟地址(RVA)。
我计算一个正确的RVA(根据.map
文件),我想把它翻译成一个可调用的函数指针。
有没有办法把它翻译成实际地址?
我曾想过拍摄图像基地址并添加它。 根据这个线程应该可以通过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)
是不正确的。
为了在编译时直接获取没有预定义入口点的图像库,可以通过从当前VA对齐eax @ 1000h的简单搜索并循环,直到在当前内存页中找到有效的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; }