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也是同理...

  1. /************************************************************************/
  2. /*
  3. 功能:虚拟内存相对地址和文件偏移的转换
  4. 参数:stRVA: 虚拟内存相对偏移地址
  5. lpFileBuf: 文件起始地址
  6. 返回:转换后的文件偏移地址
  7. */
  8. /************************************************************************/
  9. size_t RVAToOffset(size_t stRVA,PVOID lpFileBuf)
  10. {
  11. PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpFileBuf;
  12. size_t stPEHeadAddr = (size_t)lpFileBuf + pDos ->e_lfanew;
  13. PIMAGE_NT_HEADERS32 pNT = (PIMAGE_NT_HEADERS32)stPEHeadAddr;
  14. //区段数
  15. DWORD dwSectionCount = pNT->FileHeader.NumberOfSections;
  16. //内存对齐大小
  17. DWORD dwMemoruAil = pNT->OptionalHeader.SectionAlignment;
  18. PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNT);
  19. //距离命中节的起始虚拟地址的偏移值。
  20. DWORD dwDiffer = 0;
  21. for (DWORD i = 0; i < dwSectionCount; i++)
  22. {
  23. //模拟内存对齐机制
  24. DWORD dwBlockCount = pSection[i].SizeOfRawData/dwMemoruAil;
  25. dwBlockCount += pSection[i].SizeOfRawData%dwMemoruAil? 1 : 0;
  26. DWORD dwBeginVA = pSection[i].VirtualAddress;
  27. DWORD dwEndVA = pSection[i].VirtualAddress + dwBlockCount * dwMemoruAil;
  28. //如果stRVA在某个区段中
  29. if (stRVA >= dwBeginVA && stRVA < dwEndVA)
  30. {
  31. dwDiffer = stRVA - dwBeginVA;
  32. return pSection[i].PointerToRawData + dwDiffer;
  33. }
  34. else if (stRVA < dwBeginVA)//在文件头中直接返回
  35. {
  36. return stRVA;
  37. }
  38. }
  39. return 0;
  40. }
  41. /************************************************************************/
  42. /*
  43. 功能:文件偏移地址和虚拟地址的转换
  44. 参数:stOffset:文件偏移地址
  45. lpFileBuf:虚拟内存起始地址
  46. 返回:转换后的虚拟地址
  47. */
  48. /************************************************************************/
  49. size_t Offset2VA(size_t stOffset, PVOID lpFileBuf)
  50. {
  51. //获取DOS头
  52. PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpFileBuf;
  53. //获取PE头
  54. //e_lfanew:PE头相对于文件的偏移地址
  55. size_t stPEHeadAddr = (size_t)lpFileBuf + pDos ->e_lfanew;
  56. PIMAGE_NT_HEADERS32 pNT = (PIMAGE_NT_HEADERS32)stPEHeadAddr;
  57. //区段数
  58. DWORD dwSectionCount = pNT->FileHeader.NumberOfSections;
  59. //映像地址
  60. DWORD dwImageBase = pNT->OptionalHeader.ImageBase;
  61. //区段头
  62. PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNT);
  63. //相对大小
  64. DWORD dwDiffer = 0;
  65. for (DWORD i = 0; i < dwSectionCount; i++)
  66. {
  67. //区段的起始地址和结束地址
  68. DWORD dwBeginVA = pSection[i].PointerToRawData;
  69. DWORD dwEndVA = pSection[i].PointerToRawData + pSection[i].SizeOfRawData;
  70. //如果文件偏移地址在dwBeginVA和dwEndVA之间
  71. if (stOffset >= dwBeginVA && stOffset < dwEndVA)
  72. {
  73. //相对大小
  74. dwDiffer = stOffset - dwBeginVA;
  75. //进程的起始地址 + 区段的相对地址 + 相对区段的大小
  76. //return dwImageBase + pSection[i].VirtualAddress + dwDiffer;
  77. return pSection[i].VirtualAddress + dwDiffer;
  78. }
  79. else if (stOffset < dwBeginVA) //如果文件偏移地址不在区段中
  80. {
  81. return dwImageBase + stOffset;
  82. }
  83. }
  84. return 0;
  85. }

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

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

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. Android JNI入门第三篇——jni头文件分析

    一. 首先写了java文件: public class HeaderFile { private native void  doVoid(); native int doShort(); native ...

  6. conan使用(三)--打包只有头文件的库

    参考:https://docs.conan.io/en/latest/howtos/header_only.html?highlight=header%20only 对于只含头文件的库打包非常简单,以 ...

  7. Windows PE 第十三章 PE补丁技术

    PE补丁技术 这章很多东西之前都见过,也单独总结过,比如动态补丁里说的远程代码注入,还有hijack什么的.之前整理过的这里就不细说了,大体说下思路.这里总结一些之前没总结过的东西. 资料中把补丁分为 ...

  8. Python开发【第三章】:文件操作

    一.文件操作模式概述 1.打开文件的模式: r, 只读模式[默认] w,只写模式[不可读:不存在则创建:存在则删除内容:] a, 追加模式[不可读:不存在则创建:存在则只追加内容:] 2." ...

  9. 【PE结构】由浅入深PE基础学习-菜鸟手动查询导出表、相对虚拟地址(RVA)与文件偏移地址转换(FOA)

    0 前言 此篇文章想写如何通过工具手查导出表.PE文件代码编程过程中的原理.文笔不是很好,内容也是查阅了很多的资料后整合出来的.希望借此加深对PE文件格式的理解,也希望可以对看雪论坛有所贡献.因为了解 ...

随机推荐

  1. C#类中的成员

    @ 目录 字段 属性 方法 构造函数 类和对象的简单解释 创建类和对象 类中成员的归属问题 字段 字段的声明与声明变量类似,可以添加访问修饰符,通常情况下字段设置为私有的,然后定义属性对字段的读写进行 ...

  2. 漏洞复现-ActiveMq反序列化漏洞(CVE-2015-5254)

          0x00 实验环境 攻击机:Win 10 靶机也可作为攻击机:Ubuntu18 (docker搭建的vulhub靶场) 0x01 影响版本 Apache ActiveMQ 5.13.0之前 ...

  3. FreeBSD Fcitx 输入法框架设置

    #FreeBSD# 在.cshrc和/etc/csh.cshrc中进行如下配置,此配置可以解决部分窗口fcitx无效的问题. setenv QT4_IM_MODULE fcitx setenv GTK ...

  4. LNMP配置——Nginx配置 —— Nginx解析PHP

    一.配置 #vi /usr/local/nginx/conf/vhost/test.com.conf 写入: server { listen 80; server_name test.com test ...

  5. addEventListener的第三个参数详解

    示例代码 element.addEventListener("mousedown", func, { passive: true });  element.addEventList ...

  6. Hi3559AV100 NNIE开发(5)mobilefacenet.wk仿真成功量化及与CNN_convert_bin_and_print_featuremap.py输出中间层数据对比过程

    前面随笔给出了NNIE开发的基本知识,下面几篇随笔将着重于Mobilefacenet NNIE开发,实现mobilefacenet.wk的chip版本,并在Hi3559AV100上实现mobilefa ...

  7. linux库文件编程

    参考博文链接: https://www.cnblogs.com/guochaoxxl/p/7141447.html https://www.cnblogs.com/tuhooo/p/8757192.h ...

  8. Web实验报告

  9. 周期串(JAVA语言)

    package 第三章习题; /*  * 如果一个字符可以由某个长度为k的字符串重复多次得到,则称该串以k为周期.  * 例如:abcabcabcabc 以3为周期(注意:它也以6和12为周期)  * ...

  10. 仿String()构造器函数 【总结】

    需求 实现以下方法: 控制台结果: 需求分析: 首先确定new调用的this和什么对象绑定,如果跟默认返回的对象绑定肯定做不到 [ ] 这样的访问,所以要在构造器内部返回一个包装过的数组 1.leng ...