PE 基础求解
将RVA转换为File Offset,给大家一个非常经典的公式:
设:VK为相对虚拟地址RVA与文件偏移地址File Offset的差值
VA=ImageBase+RVA
File Offset = RVA ---VK
File Offset = VA---ImageBase---VK
这个里面 VK 怎么知道?
[解决办法]
贴一段我当年写的代码
extern vector<Section_Header*> *sh_table;extern vector<Import_Table*> *it_table;extern Pe_Header *ph;/* RVA即(Relative Virtual Address)相对与可执行文件加载地址的虚拟地址。* VA即(Virtual Address)虚拟地址,即可执行文件在加载到内存中的地址。* 偏移量则为可执行文件存在磁盘上的偏移地址。** 由于在磁盘上与内存中有不同的对齐方式,因此在第一个段之后,RVA与文件偏移不同。* 在第一个段之前,RVA与偏移地址是相同的。** 因此,在分析一个没被Loader加载到内存的可执行文件映像,需要计算RVA。* RVA计算方法* 1. 遍历可执行文件中的每一个段,根据各个段的起始RVA(IMAGE_SECTION_HEADER->VirtualSize),* 以及该段的原始大小(IMAGE_SECTION_HEADER->SizeOfRawData),计算该段结束RVA。** 2. 测试欲计算的RVA,在哪一个段中,找到后,用应计算RVA减去该段起始RVA,得到相对于该段起始RVA* 的偏移RVA。** 3. 在段表中获取该段的文件所属偏移,加上上一步得到的偏移RVA,即欲计算的目标RVA的偏移地址。*/DWORD RvaToVa(DWORD rva){ static DWORD (*sections)[3] = NULL; //设置为static变量,目的在于对于一个可执行文件, //只计算一次各段的起始地址、段尾地址、以及原始指针数组 //However,I do not know why I set the type to a pointer to a array of three DWORDs, //but just a original array of three DWORDs. DWORD numberOfSection = ph->GetSectionNumber (); if (sections == NULL){ sections = new DWORD[numberOfSection][3] ; for (DWORD i = 0;i < numberOfSection; i++) { sections[i][0] = (*sh_table)[i]->VirtualAddress; //sections[i][0]:段的起始RVA:VirtualAddress sections[i][1] = (*sh_table)[i]->SizeOfRawData + sections[i][0]; //sections[i][1]:段尾:VirtualAddress + SizeOfRawData sections[i][2] = (*sh_table)[i]->PointerToRawData; //sections[i][3]:段原始偏移指针: PointerToRawData } } for (DWORD i = 0;i < numberOfSection;i++) { if ( rva > sections[i][0] && rva < sections[i][1] ){ DWORD va = rva - sections[i][0]; va += sections[i][2]; return va; } } return -1;}