将RVA(相对虚拟地址)地址转化成Offset VA(偏移地址)

将RVA(相对虚拟地址)地址转化成Offset VA(偏移地址)
  
      原创:星绽紫辉 2009-1-4     转载请注明出处:  http://www.cppblog.com/rawdata
     
      RVA(reverse virtual address) 和 VA 地址的概念我就不说了,网上一大堆,就看你有没有心去找了。在解析PE文件格式时,需要将RVA地址转化成VA地址,才能对如:IMAGE_IMPORT_DESCRIPTOR类的结构进行正确访问。这样,exe/dll等导出的函数和导入的函数等重要信息你就可以获得了。

      我写的这段函数是参考罗云彬的汇编主页上的PE文件格式的汇编代码,是由GuFeng翻译 Iczelion的,现在我写成C/C++的形式,以供参考。


// RVA To Offset
DWORD CPEReaderDlg::RVAToOffset(DWORD pMapping,DWORD dwRVA)
{
    
//Defines
    DWORD pNTDst = 0;
    IMAGE_DOS_HEADER
* pidh = (IMAGE_DOS_HEADER*)pMapping;
    pNTDst 
= pMapping + pidh->e_lfanew;
    DWORD pSeDst 
= pNTDst;
    IMAGE_NT_HEADERS
* pinh = (IMAGE_NT_HEADERS*)pNTDst;
    IMAGE_SECTION_HEADER
* pish = NULL;

    
//First Session
    pSeDst = pNTDst + sizeof(IMAGE_NT_HEADERS);
    pish 
= (IMAGE_SECTION_HEADER*)pSeDst;
    
    
//Session Count
    UINT nCount = pinh->FileHeader.NumberOfSections;
    DWORD dwPosTmp 
= 0;

    
//Scan
    for(UINT i=0;i<nCount;i++)
    
{
        
if(dwRVA>=pish->VirtualAddress)
        
{
            dwPosTmp 
= pish->VirtualAddress;
            dwPosTmp 
+= pish->SizeOfRawData;
        }

        
if(dwRVA<dwPosTmp)
        
{
            dwRVA 
= dwRVA - pish->VirtualAddress;
            
return dwRVA + pish->PointerToRawData;
        }

        pish 
= pish + 1;//sizeof(IMAGE_SECTION_HEADER);
    }

    
return -1;
}
      
      其中的pMapping 是目标exe/dll文件的内存映像指针,由(MapViewOfFile返回),dwRVA为相对地址,返回的是该PE程序在内存的对应dwRVA的偏移地址,得到VA就很简单了:VA = pMapping + 返回值. (返回-1标识无效.)



      如果代码有什么谬误或者待完善的地方,请留言或EmailToMe:[email protected].

      2009-1-4   星绽紫辉(rawdata)    

你可能感兴趣的:(将RVA(相对虚拟地址)地址转化成Offset VA(偏移地址))