“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);
}
答案 0 :(得分:1)
您研究的0X400000与普通文件映射无关。
你可以想象 MapViewOfFile作为你正在打开的文件的malloc + memcpy,仅此而已(在幕后它是相反的:malloc可以使用slab'ed内存映射)。所以MapViewOfFile通常只选择一个地址,它可以在文件视图的内存中连续放入文件视图的字节。
你可能想要的(因为你试图映射.exe)是用CreateProcess创建一个新的进程。
如果您确实需要将文件映射到特定地址,则可以使用MapViewOfFileEx,但无法保证。
答案 1 :(得分:0)
是的,MapViewOfFile返回已加载图像的虚拟内存基地址。此地址的值(内容)取决于图像是否已成功加载到其预定义地址(已由链接器设置)或图像是否已重新定位(因为所需的预定义地址已被占用或因为图片已选择支持ASLR)。
答案 2 :(得分:0)
要将RVA转换为文件偏移量,请找到增量并使用它。我假设您在PE文件的内存映射之后尝试做一些事情,比如查看PE文件的dataDirectory结构中的RVA指向的位置?查看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指向的部分。你应该编辑你的问题,以表明这是你要问的问题。