/*
RvaToFileOffset:将内存偏移转换为文件偏移
参数说明:
pFileBuffer FileBuffer指针
dwRva RVA的值
返回值说明:返回转换后的FOA的值 如果失败返回0
*/
DWORD RvaToFileOffset(IN LPVOID pFileBuffer,IN DWORD dwRva)
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
DWORD dwFOA = 0;
//判断传进来的文件地址是否正确
if(!pFileBuffer)
{
printf("分配空间失败!");
return 0;
}
//判断是否遵守PE格式
if(*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("不是有效的MZ头\n");
return 0;
}
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
if(*((PDWORD)((DWORD)pFileBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("不是有效的PE标志\n");
return 0;
}
//NT头地址
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew);
//标准PE头地址
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 0x04);
//可选PE头地址
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
//第一个节表地址
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);
if (dwRva - (pOptionHeader->ImageBase) < 0)
{
return 0;
}
for (int i = 0; i < pPEHeader->NumberOfSections; i++)
{
DWORD VirtualRvaAddress = dwRva - (pOptionHeader->ImageBase);
if (VirtualRvaAddress >= pSectionHeader->VirtualAddress && VirtualRvaAddress < pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize)
{
VirtualRvaAddress -= pSectionHeader->VirtualAddress;
dwFOA = VirtualRvaAddress + pSectionHeader->PointerToRawData;
return dwFOA;
}
pSectionHeader++;
}
return 0;
}
RVA的值转换成FOA(C语言)
于 2023-12-17 14:49:21 首次发布