星绽紫辉(rawdata)的Blog

快乐地学习,快乐地工作!

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  16 Posts :: 0 Stories :: 37 Comments :: 0 Trackbacks

常用链接

留言簿(5)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜

  
     原创:星绽紫辉 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:xiaolu69soft@yahoo.com.cn.

      2009-1-4   星绽紫辉(rawdata)    
posted on 2009-01-04 12:41 星绽紫辉 阅读(2406) 评论(1)  编辑 收藏 引用

Feedback

# re: 将RVA(相对虚拟地址)地址转化成Offset VA(偏移地址) 2012-03-03 16:18 凭凡 fire_the_hole@163.com
NICE,我直接复制走了~~~谢谢哈  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理