PE文件关于虚拟相对地址RVA与基于文件的偏移地址关系

本文探讨了在PE文件加载到内存时,如何从虚拟内存的相对地址(RVA)转换为基于文件的偏移地址。通过示例代码详细解释了在解析PE文件导入表时,如何利用RVA找到对应的函数和DLL名称,并介绍了转换过程中关键函数`GetPtrFromRVA`的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 由PE装载器将PE文件加到虚拟内存时使用的地址均是RVA地址, 而在文件中存放的数据的地址是基于文件的偏移地址, 因此存在一个从RVA到偏移地址的转换过程。当我们通过内存映射文件的方式获取文件数据内容时使用的是基于文件的偏移地址,这样才能正确获取我们所要获取的数据。

template <class T> void DumpImportsSection(PBYTE pImageBase, T * pNTHeader) // 'T' = PIMAGE_NT_HEADERS
{
    PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
    DWORD importsStartRVA;

    // Look up where the imports section is (normally in the .idata section)
    // but not necessarily so.  Therefore, grab the RVA from the data dir.
    importsStartRVA = GetImgDirEntryRVA(pNTHeader,IMAGE_DIRECTORY_ENTRY_IMPORT);
    if ( !importsStartRVA )
        return;

    pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)GetPtrFromRVA(importsStartRVA,pNTHeader,pImageBase);
 for (;pImportDesc->Name;pImportDesc++)
 {
  if (pImportDesc->Name ==NULL)
   return;

  LPSTR pszDllName = (LPSTR)GetPtrFromRVA(pImportDesc->Name,pNTHeader,pImageBase);

  //寻找我们想要的函数
  DWORD dwThunkRVA = pImportDesc->OriginalFirstThunk;
  if (dwThunkRVA == 0)
  {
   dwThunkRVA = pImportDesc->FirstThunk;
  }
  PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA) GetPtrFromRVA(dwThunkRVA,pNTHeader,pImageBase);//IAT
  for (;pThunk->u1.Function;pThunk++)
  {
   DWORD dwImportNameRVA = pThunk->u1.AddressOfData;
   PIMAGE_IMPORT_BY_NAME pImportName = (PIMAGE_IMPORT_BY_NAME) GetPtrFromRVA(dwImportNameRVA,pNTHeader,pImageBase);//IAT

   int i = 0;
  }
  if ( !pImportDesc )
   return;
 }
    

}

 

template <class T> LPVOID GetPtrFromRVA( DWORD rva, T* pNTHeader, PBYTE imageBase ) // 'T' = PIMAGE_NT_HEADERS
{
 PIMAGE_SECTION_HEADER pSectionHdr;
 INT delta;
  
 pSectionHdr = GetEnclosingSectionHeader( rva, pNTHeader );
 if ( !pSectionHdr )
  return 0;

 delta = (INT)(pSectionHdr->VirtualAddress-pSectionHdr->PointerToRawData);
 return (PVOID) ( imageBase + rva - delta );
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值