RVA-FOA之间转换

1.首先PE头加载到内存之后是和文件头内容一样的,就算是偏移不同,一个是磁盘扇区大小(400H)另一个是内存页大小(1000H),但是因为两个都是开头位置,所以相同。

2.看下IMAGE_SECTION_HEADER定义

也就是这样:

然后就可以算了(RVA->FOA)

(1) RVA20 < RVA < RVA30 可以知道在第二节

(2) 然后 off = RVA - RVA20 ,得出距离第二节的偏移off

(3) FOA = FOA 20 + off 求出FOA

计算FOA->RVA也是同理...

/************************************************************************/
/*
功能:虚拟内存相对地址和文件偏移的转换
参数:stRVA:    虚拟内存相对偏移地址lpFileBuf: 文件起始地址
返回:转换后的文件偏移地址
*/
/************************************************************************/
size_t RVAToOffset(size_t stRVA,PVOID lpFileBuf)
{  PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpFileBuf;  size_t stPEHeadAddr = (size_t)lpFileBuf + pDos ->e_lfanew;  PIMAGE_NT_HEADERS32 pNT = (PIMAGE_NT_HEADERS32)stPEHeadAddr;  //区段数  DWORD dwSectionCount = pNT->FileHeader.NumberOfSections;  //内存对齐大小  DWORD dwMemoruAil = pNT->OptionalHeader.SectionAlignment;  PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNT);  //距离命中节的起始虚拟地址的偏移值。  DWORD  dwDiffer = 0;  for (DWORD i = 0; i < dwSectionCount; i++)  {  //模拟内存对齐机制  DWORD dwBlockCount  = pSection[i].SizeOfRawData/dwMemoruAil;  dwBlockCount       += pSection[i].SizeOfRawData%dwMemoruAil? 1 : 0;  DWORD dwBeginVA     = pSection[i].VirtualAddress;  DWORD dwEndVA       = pSection[i].VirtualAddress + dwBlockCount * dwMemoruAil;  //如果stRVA在某个区段中  if (stRVA >= dwBeginVA && stRVA < dwEndVA)  {  dwDiffer = stRVA - dwBeginVA;  return pSection[i].PointerToRawData + dwDiffer;  }  else if (stRVA < dwBeginVA)//在文件头中直接返回  {  return stRVA;  }  }  return 0;
}  /************************************************************************/
/*
功能:文件偏移地址和虚拟地址的转换
参数:stOffset:文件偏移地址lpFileBuf:虚拟内存起始地址
返回:转换后的虚拟地址
*/
/************************************************************************/
size_t Offset2VA(size_t stOffset, PVOID lpFileBuf)
{  //获取DOS头  PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpFileBuf;  //获取PE头  //e_lfanew:PE头相对于文件的偏移地址  size_t stPEHeadAddr = (size_t)lpFileBuf + pDos ->e_lfanew;  PIMAGE_NT_HEADERS32 pNT = (PIMAGE_NT_HEADERS32)stPEHeadAddr;  //区段数  DWORD dwSectionCount = pNT->FileHeader.NumberOfSections;  //映像地址  DWORD dwImageBase    = pNT->OptionalHeader.ImageBase;  //区段头  PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNT);  //相对大小  DWORD  dwDiffer = 0;  for (DWORD i = 0; i <  dwSectionCount; i++)  {  //区段的起始地址和结束地址  DWORD dwBeginVA     = pSection[i].PointerToRawData;  DWORD dwEndVA       = pSection[i].PointerToRawData + pSection[i].SizeOfRawData;  //如果文件偏移地址在dwBeginVA和dwEndVA之间  if (stOffset >= dwBeginVA && stOffset < dwEndVA)  {  //相对大小  dwDiffer = stOffset - dwBeginVA;  //进程的起始地址 + 区段的相对地址 + 相对区段的大小  //return dwImageBase + pSection[i].VirtualAddress + dwDiffer;
return  pSection[i].VirtualAddress + dwDiffer;}  else if (stOffset < dwBeginVA)    //如果文件偏移地址不在区段中  {  return dwImageBase + stOffset;  }  }  return 0;
}  

测试了上面两个函数,没发现什么问题,测试结果:

随手写了个简单的工具,直接控制台写的,功能简单,懒得写界面了。源码在:

http://download.csdn.net/detail/u013761036/9643230

运行效果:

Windows Pe 第三章 PE头文件-EX-相关编程-2(RVA_FOA转换)相关推荐

  1. Windows Pe 第三章 PE头文件(上)

    第三章  PE头文件 本章是全书重点,所以要好好理解,概念比较多,但是非常重要. PE头文件记录了PE文件中所有的数据的组织方式,它类似于一本书的目录,通过目录我们可以快速定位到某个具体的章节:通过P ...

  2. Windows Pe 第三章 PE头文件(下)

    3.5  数据结构字段详解 3.5.1  PE头IMAGE_NT_HEADER的字段 1.IMAGE_NT_HEADER.Signature +0000h,双字.PE文件标识,被定义为00004550 ...

  3. Windows Pe 第三章 PE头文件(中)

    这一章的上半部分大体介绍了下PE文件头,下半部分是详细介绍里面的内容,这一章一定要多读几遍,好好记记基础概念和知识,方便之后的学习. 简单回忆一下: 3.4  PE文件头部解析 3.4.1 DOS M ...

  4. Windows Pe 第三章 PE头文件-EX-相关编程-1(PE头内容获取)

    获取pE头相关的内容,就是类似如下内容 原理:比较简单,直接读取PE到内存,然后直接强转就行了. #include <windows.h> #include <stdio.h> ...

  5. Windows API 之joystickapi(游戏摇杆)头文件2

    文章目录 前言 函数joyGetDevCaps 语法 参数 返回值 补充 支持 结构体 JOYCAPS 语法 成员 支持 前言 在上篇博文中,已经介绍了windows底层对于游戏摇杆的支持头文件. 在 ...

  6. C语言头文件路径相关问题总结说明

    聊聊系统路径位置,绝对路径与相对路径,正斜杠 `/` 与 反斜杠 `\` 使用说明 ...... by 矜辰所致 目录 前言 一.C语言中的头文件引用 二.KEIL 中的头文件路径 2.1 Incud ...

  7. windows 程序设计 第三章读书笔记(上)

    娘的,今天晚上在阳台做饭把水管一脚踢爆了,水流到下面的住户的阳台,让个老娘们把我骂了一顿,本着做错事的原则,我装的很绅士还说了个对不起,擦,真是条纯汉子,能屈能伸. 大爷,别看我年轮小,我都给总结了, ...

  8. QtCreator里添加外部第三库、头文件路径的方法(.pro文件)

    一.前言 在项目开发过程中,经常需要用到第三方库,需要在QtCreator工程里指定第三库的路径.头文件路径.引用的库名称等等:并且可能还需要编写通用工程针对不同的编译器类型,位数选择不同的库,针对不 ...

  9. 51单片机c语言编程的头文件,51单片机编程的头文件reg51.h详解

    我们在用c语言编程时往往第一行就是头文件,51单片机为reg51.h或reg52.h,51单片机相对来说比较简单,头文件里面内容不多,像飞思卡尔.ARM系列的单片机头文件往往内容就非常多,尽管如此,对 ...

最新文章

  1. 使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
  2. python中cd是什么意思_python的cd的
  3. 结合webpack配置_前端 Webpack 工程化的最佳实践
  4. 在SharePoint 2010中创建网站的权限级别
  5. php 关于日期的知识总结
  6. 小程序-读取视频数据 每个N帧采样保存
  7. 单链表的尾插,头插,遍历,查找和插入
  8. 我很生气,帮了不足一个月就离开了
  9. 高速PCB中常见存储器之FLASH引脚图、布局布线设计
  10. 【生信进阶练习1000days】day3-Bioconductor annotation resources
  11. 模式识别(五)聚类的几种算法
  12. 正解:《Java 程序员的黄金 5 年》看完我才知道当时有多蠢
  13. 高通X12平台XO信号干扰灵敏度的解决方案
  14. 深度学习GPU显卡的浮点计算性能指标分析
  15. android wifi音箱,(原创)图文并茂教程,手把手教你用安卓手机当电脑的无线扬声器(喇叭)...
  16. 初试 Kubernetes 暴漏服务类型之 Nginx Ingress
  17. 关于零基础入门金融风控挑战赛的笔记系列
  18. 如何给原图添加文字水印和图片水印
  19. android闪光灯测心率,手指放在手机摄像头和闪光灯前检测心率的应用是什么原理?...
  20. sap BusinessObject Enterprise XI 4.0 安装载图

热门文章

  1. 从宏观经济状况看目前股市
  2. Python爬虫(三)_urllib2:get和post请求
  3. 秋招 百度二轮面试---血淋淋的经历写实
  4. 第44节:Java当中的JVM
  5. Springmvc与Struts2不同
  6. 洛谷 P1985 翻转棋
  7. 动态可订制属性的 PropertyGrid(转载)
  8. ExtJs服务器端代理(Ajax)
  9. 自定义MIME类型支持FLV的相关设置
  10. ubuntu rar文件乱码