可能重复:
为什么装载机不能在所需位置装载
“MapViewOfFile”,这个函数是否将一个文件映射到虚拟内存中并返回映射内存的基地址? 如果是,那么下面的代码应该输出0X400000,默认情况下,exe的加载在这个位置,但是输出是0X360000。 为什么??
#include<iostream> #include<Windows.h> #include<stdio.h> #include<WinNT.h> int main() { HANDLE hFile,hFileMapping; LPVOID lpFileBase; if((hFile = CreateFile(TEXT("c:\\linked list.exe"),GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0)) == INVALID_HANDLE_VALUE) std::cout<<"unable to open"; if((hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL)) == 0) { CloseHandle(hFile); std::cout<<"unable to open for mapping"; } if((lpFileBase = MapViewOfFile(hFileMapping,FILE_MAP_READ,0,0,0))== 0) { CloseHandle(hFile); CloseHandle(hFileMapping); std::cout<<"couldn't map view of file"; } printf("%x\n",lpFileBase); }
您研究的0X400000与普通文件映射无关。
你可以把MapViewOfFile 想象成你正在打开的文件的malloc + memcpy,没有什么更多的东西(相反,malloc可以使用slab内存映射)。 所以MapViewOfFile通常只是选择一个地址,在那里它可以连续的存储文件视图的字节。
你可能想要的(因为你正在试图映射.exe)是用CreateProcess创建一个新的进程。
如果您确实需要将文件映射到特定地址,则可以使用MapViewOfFileEx ,但不能保证。
是的,MapViewOfFile返回已加载图像的虚拟内存基地址。 这个地址的值(内容)取决于图像是否被成功加载到其预定义的地址(已经由链接器设置)或者图像是否已经被重新定位(因为期望的,预定义的地址已经被占用或者因为图像已经选择支持ASLR )。
要将RVA转换为文件偏移量,请查找增量并使用它。 我假设你正在尝试做一些事情,比如PE文件的dataDirectory结构中的RVA指向内存映射PE文件之后? 看看IMAGE_SECTION_HEADER结构:
typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; union { DWORD PhysicalAddress; DWORD VirtualSize; } Misc; DWORD VirtualAddress; DWORD SizeOfRawData; DWORD PointerToRawData; DWORD PointerToRelocations; DWORD PointerToLinenumbers; WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics; } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
您将需要查找该部分的VirtualAddress和PointerToRawData值之间的差异。 然后,对于一个RVA到一个给定的部分,分割三角洲获得文件偏移量。
根据我的经验,每个部分都是不同的。 因此,如果您在节表中列出的第二部分中有RVA,则增量将与节中列出的第二部分不同。 为此,有助于确定一个RVA指向的部分。 你应该编辑你的问题,以表明这是你问的问题。