公式

  1. RVA = 内存地址-ImageBase

  2. 判断RVA在哪一个节上:

    1. RVA>=节n.VirtualAddress
    2. RVA<=(节n.VirtualAddress+节.SizeofRawData)内存对齐

    偏移=RVA-节n.VirtualAddress

  3. FOA=节n.PointerToRawData+偏移

实验-对齐大小一样

#include <stdio.h>

char str[] = "ABC";
int main()
{
printf("Address: %p\n", &str);
printf("V: %s\n", str);
return 0;
}
  • 执行后输出:
Address: 00424D8C
V: ABC

获取ImageBase

  • ImageBase在扩展PE头上的第十个属性,基于扩展PE头偏移地址28个字节,大小为DWORD。
  • 00004000,小端存储转十六进制为0x00400000,所以ImageBase的地址为0x00400000。

计算RVA

  • RVA=内存地址-ImageBase=0x00024D8C

获取内存对齐和文件对齐

  • SectionAlignment 内存对齐 在扩展PE头上的第十一个属性,大小为DWORD。
  • FileAlignment 文件对齐 在扩展PE头上的第十二个属性,大小为DWORD。
  • 发现内存对齐和文件对齐都是1000h,实验完再找一个对齐不一样的试试。

判断在哪一个节

  • VirtualAddress在每一个节表的第三个属性,偏移为12个字节,大小为DWORD,得到第一个节表的VirtualAddress为00100000,小端转十六进制得到0x00001000。第二个节表的VirtualAddress为00200200,小端存储转十六进制得到0x00022000。第三个节表的VirtualAddress为00400200,小端存储转十六进制为00024000,RVA大于第二个节的VirtualAddress小于第三个节的VirtualAddress。所以在第二个节表里。

计算偏移

  • RVA-第二个节的VirtualAddress=0x00024D8C-0x00022000=0x00002D8C

获取节表的PointerToRawData

  • PointerToRawData在节表的第五个属性,基于节表偏移20个字节,大小为DWORD。
  • 获取第二个节表的PointerToRawData得到00200200,小端存储转十六进制为0x00022000

计算FOA

  • FOA=第二个节.PointerToRawData+偏移=0x00022000+0x00002D8C=0x00024D8C
  • 发现和RVA是一样的,所以结论是:如果内存对齐和文件对齐是一样的,FOA=RVA。

验证

  • 将0x00024D8C后面对应三个字节的改为41 41 41再执行等到
Address: 00424D8C
V: AAA

实验-对齐大小不一样

  • 预编译修改内存对齐和文件对齐,记得文件对齐不能大于内存对齐。因为重新编译了,所以要重新算。
#pragma comment(linker, "/ALIGN:0x4000")
#pragma comment(linker, "/FILEALIGN:0x1000") #include <stdio.h> char str[] = "ABCD";
int main()
{
printf("Address: %p\n", &str);
printf("V: %s\n", str);
return 0;
}
  • 执行后结果为:
Address: 0042CA30
V: ABCD

获取ImageBase

  • ImageBase在扩展PE头上的第十个属性,基于扩展PE头偏移地址28个字节,大小为DWORD。
  • 00004000,小端存储转十六进制为0x00400000,所以ImageBase的地址为0x00400000。

计算RVA

  • RVA=内存地址-ImageBase=0x0042CA30-0x00400000=0x0002CA30

获取内存对齐和文件对齐

  • SectionAlignment 内存对齐 在扩展PE头上的第十一个属性,基于扩展PE头偏移地址32个字节,大小为DWORD。
  • FileAlignment 文件对齐 在扩展PE头上的第十二个属性,基于扩展PE头偏移地址36个字节,大小为DWORD。
  • 发现内存对齐是4000h,文件对齐是1000h。

判断在哪一个节

  • VirtualAddress在每一个节表的第三个属性,偏移为12个字节,大小为DWORD,得到第一个节表的VirtualAddress为00400000,小端转十六进制得到0x00004000。第二个节表的VirtualAddress为00800200,小端存储转十六进制得到0x00020800。第三个节表的VirtualAddress为00C00200,小端存储转十六进制为0x0002C000,第四个节表的VirtualAddress为00400300,小端存储转十六进制为0x00034000,RVA大于第三个节的VirtualAddress小于第四个节的VirtualAddress。所以在第三个节表里。

计算偏移

  • RVA-第三个节的VirtualAddress=0x0002CA30-0x0002C000=0x00000A30

获取节表的PointerToRawData

  • PointerToRawData在节表的第五个属性,基于节表偏移20个字节,大小为DWORD。
  • 获取第三个节表的PointerToRawData得到00800200,小端存储转十六进制为0x00028000

计算FOA

  • FOA=第三个节.PointerToRawData+偏移=0x00024000+0x00000A30=0x00024A30

验证

  • 将0x00024A30后面对应三个字节的改为41 41 41 41再执行等到
Address: 0042CA30
V: AAAA

哔哩哔哩

PE之RVA转FOA的更多相关文章

  1. PE知识复习之PE的RVA与FOA的转换

    PE知识复习之PE的RVA与FOA的转换 一丶简介PE的两种状态 首先我们知道PE有两种状态.一种是内存展开.一种是在文件中的状态.那么此时我们有一个需求. 我们想改变一个全局变量的初始值.此时应该怎 ...

  2. RVA到FOA的转换

    地址空间:这个地址空间指的是PE文件被加载到内存的空间,是一个虚拟的地址空间,之所以不是物理空间是因为数据在内存中的位置经常在变,这样既可以节约内存开支又可以避开错误的内存位置.这个地址空间的大小为4 ...

  3. PE文件RV转FOA及FOA转RVA

    /************************************************************************/ /* 功能:虚拟内存相对地址和文件偏移的转换 参数 ...

  4. Windows代码,添加一个节,以及RVA跟FOA互相转化,以及内存文件对齐代码.

    / 1.修改文件头节个数 +1 2.修改ImageBase 3.遍历节表,拷贝最后一个节表到下面 4.修改节的虚拟大小(节表.virtualSize) 5.修改节的虚拟地址(RVA 节表.virtua ...

  5. RVA与FOA的转换

    主要取决于文件对齐与内存对齐的值

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

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

  7. PE 学习之路 —— 区块表

    1. 前述 在 NT 头结束后,紧接着就是区块表,区块表包含每个块在映象中的信息,分别指向不同的区块实体. 2. 区块表 区块表是一个 IMAGE_SECTION_HEADER 结构数组,这个结构包含 ...

  8. C++PE文件格式解析类(轻松制作自己的PE文件解析器)

    PE是Portable Executable File Format(可移植的运行体)简写,它是眼下Windows平台上的主流可运行文件格式. PE文件里包括的内容非常多,详细我就不在这解释了,有兴趣 ...

  9. PE基础1

    PE文件概述 文件格式 .png ..mp4..gif..dll等等,这些文件都具有不同格式 不能随意修改这些文件,否则将无法打开 PE文件(可执行文件) 学习PE文件目标 掌握PE文件就掌握wino ...

随机推荐

  1. provide 和 inject高阶使用

    provide 在祖先里授权导出 inject在后代负责接收 foo可以是本组件的函数方法 或者 变量foo 也可以是祖先组件自己 祖先组件foo: this 后代组件 foo.$options.da ...

  2. 判断是app 或者 网页

    function openInWebview () { let ua = navigator.userAgent.toLowerCase(); if (ua.match(/MicroMessenger ...

  3. 支付接口API

    //微信支付SDK https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

  4. 传奇定时器OnTimer功能详解(泡点、时间触发、任务活动)

    传奇定时器OnTimer功能详解(泡点.时间触发.任务活动) 定时器功能,是传奇服务端中非常常见的一种功能,常见如:泡点脚本.赌博脚本,任务活动指定时间刷怪,时间触发一些都需要用到OnTimer功能, ...

  5. 传奇脚本:#AutoRun NPC SEC 参数说明

    传奇脚本:#AutoRun NPC SEC 参数说明 SEC:按秒运行MIN:按分运行HOUR:按小时运行DAY:按天运行RunOnDay:按每天什么时候运行RUNONWEEK:按星期几及时间运行机器 ...

  6. 【STM32H7教程】第58章 STM32H7的硬件JPEG应用之图片解码显示

    完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第58章       STM32H7的硬件JPEG应用之图片解 ...

  7. Python中令人迷惑的4个引用

    第一个:执行时机的差异 1. array = [1, 8, 15] g = (x for x in array if array.count(x) > 0) array = [2, 8, 22] ...

  8. 批量给文件加一个后缀 .bak , 一条命令去掉文件的后缀 linux

    给当前文件夹下面的所有文件加上一个后缀 == 一条命令解决 ll | awk '{print $9}' | grep -v '^[ ]*$' |sed -r 's#(.*)#mv \1 \1.bak# ...

  9. .NET中的字符串(1):字符串 - 特殊的引用类型

    C# string 特殊的引用类型 .Net 框架程序设计(修订版)中有这样一段描述:String类型直接继承自Object,这使得它成为一个引用类型,也就是说线程上的堆栈上不会驻留有任何字符串.(译 ...

  10. 一大波新款iPhone跟安卓厂商抢夺5G市场

    据外媒最新报道称,苹果已经基本完成了今年iPhone的推新阵容,其发布的多款新机中,将涵盖399美元-1149美元的售价区间,特别是5G手机,起步价可能会很亲民,其目的在于进一步占据市场. 今年苹果将 ...