PE文件解析(2):RVA与FOA转换和区段表

2023-10-12 02:40
文章标签 转换 解析 pe foa rva 区段

本文主要是介绍PE文件解析(2):RVA与FOA转换和区段表,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • RVA与FOA
  • 区段表
  • RVA到FOA的转换

RVA与FOA

VA: 虚拟内存地址(Virtual Address)PE 文件被操作系统加载进内存后的地址。

RVA: 程序在内存中的偏移地址(Relative Virual Address)
PE文件的相对虚拟地址是PE文件中的数据、模块等运行在内存中的实际地址相对PE文件装载到内存的基址之间的距离。举例说明,如果PE文件装入虚拟地址(VA)空间的400000h处,且进程从虚址401000h开始执行,我们可以说进程执行起始地址在RVA 1000h。

FOA:程序在文件,硬盘中的偏移地址(File Offset Address)
文件偏移地址,和内存无关,它是指某个位置距离文件头的偏移。


一个程序的各段在内存和文件中的对齐方式是不一样的。

FOA:文件对齐值是0x200。
RVA:内存对齐是0x1000
在这里插入图片描述

区段表

我们在上节已经解析了Dos头和Nt头部分,下面我们来解析下一个部分:区段表部分:
一个程序有很多的区段组成:
.text
.data
.rdata
.idata
.edata
…等等
这些区段都有着各自的信息,每一个块都是一个结构体:

typedef struct _IMAGE_SECTION_HEADER {BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];union {DWORD   PhysicalAddress;DWORD   VirtualSize;//区段在内存中的真实大小} Misc;DWORD   VirtualAddress;//RVA :区段在内存中的偏移地址DWORD   SizeOfRawData;	//区段在文件中对齐后大小 DWORD   PointerToRawData;//RVA: 区段在文件中的偏移位置	DWORD   PointerToRelocations;DWORD   PointerToLinenumbers;WORD    NumberOfRelocations;WORD    NumberOfLinenumbers;DWORD   Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

010editor解析:
在这里插入图片描述

代码解析:

BOOL PE::GetSelctionInfo()
{PIMAGE_SECTION_HEADER pSelctionHeader = IMAGE_FIRST_SECTION(pNtHeader);for (UINT i = 0; i < pFileHeader->NumberOfSections; i++){printf("区段名:%s\n", pSelctionHeader->Name);pSelctionHeader++;}return 0;
}
  1. pFileHeader结构体成员存储着区段的数量:NumberOfSections。
  2. 得到区段表的方法:
  • 利用偏移:NT部分的标准NT头大小是不变的,而可选NT头部分是可变的,但是标准NT头部分有一个成员存储着可选NT头的大小,我们利用 区段表地址 = NT头起始地址 + NT标识区大小(4) + 标准NT头大小 + 可选NT头大小,就可以得到区段表的地址:
PIMAGE_SECTION_HEADER pSelctionHeader =(PIMAGE_SECTION_HEADER)((DWORD)pNtHeader + FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) +//FIELD_OFFSET可以直接计算出可选NT头到NT首地址的大小。pFileHeader->SizeOfOptionalHeader);
  • 一个宏:
//IMAGE_FIRST_SECTION可以直接得到区段表地址,只需传递NT头的起始位置。
PIMAGE_SECTION_HEADER pSelctionHeader = IMAGE_FIRST_SECTION(pNtHeader);

程序运行如下:
在这里插入图片描述

RVA到FOA的转换

通常情况下,我们需要将RVA转换为FOA:

在这里插入图片描述

  • 数据的RVA - 区段的RVA = 数据 在内存中距离区段头的距离 s1
  • 数据的FOA - 区段的FOA = 数据 在文件中距离区段头的距离 s2
  • s1 = s2
  • 数据的RVA - 区段的RVA =数据的FOA - 区段的FOA
  • 数据的FOA = 数据的RVA(传参) - 区段的RVA + 区段的FOA

DWORD cPE::RvaToFoa(DWORD rva)
{//获得区段表/*Nt头的起始位置 + 可选头到Nt头的距离 + 可选头的大小*/PIMAGE_SECTION_HEADER pSelctionHeader = (PIMAGE_SECTION_HEADER)((ULONG_PTR)pNtHeader + FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) + pFileHeader->SizeOfOptionalHeader);// 遍历每一个区段,看看 RVA(某个东西在内存中的偏移地址)是否落在某个区段上for (UINT i = 0; i < pFileHeader->NumberOfSections; i++){/*数据的RVA - 区段的RVA = 数据 在内存中距离区段头的距离 s1数据的FOA - 区段的FOA = 数据 在文件中距离区段头的距离 s2s1=s2 数据的FOA - 区段的FOA = 数据的RVA - 区段的RVA所以:已知数据的RVA求数据的FOA: 数据的FOA = 数据的RVA - 区段的RVA + 区段的FOA*/if (rva >= pSelctionHeader->VirtualAddress && rva < pSelctionHeader->VirtualAddress + pSelctionHeader->Misc.VirtualSize){//rva必须在某一个区段的里面, 大于区段头部偏移,小于区段头加大小return rva - pSelctionHeader->VirtualAddress + pSelctionHeader->PointerToRawData;}pSelctionHeader++;}return 0;
}

这篇关于PE文件解析(2):RVA与FOA转换和区段表的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/192665

相关文章

nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析(结合应用场景)

《nginx-t、nginx-sstop和nginx-sreload命令的详细解析(结合应用场景)》本文解析Nginx的-t、-sstop、-sreload命令,分别用于配置语法检... 以下是关于 nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析,结合实际应

MyBatis中$与#的区别解析

《MyBatis中$与#的区别解析》文章浏览阅读314次,点赞4次,收藏6次。MyBatis使用#{}作为参数占位符时,会创建预处理语句(PreparedStatement),并将参数值作为预处理语句... 目录一、介绍二、sql注入风险实例一、介绍#(井号):MyBATis使用#{}作为参数占位符时,会

PostgreSQL的扩展dict_int应用案例解析

《PostgreSQL的扩展dict_int应用案例解析》dict_int扩展为PostgreSQL提供了专业的整数文本处理能力,特别适合需要精确处理数字内容的搜索场景,本文给大家介绍PostgreS... 目录PostgreSQL的扩展dict_int一、扩展概述二、核心功能三、安装与启用四、字典配置方法

深度解析Java DTO(最新推荐)

《深度解析JavaDTO(最新推荐)》DTO(DataTransferObject)是一种用于在不同层(如Controller层、Service层)之间传输数据的对象设计模式,其核心目的是封装数据,... 目录一、什么是DTO?DTO的核心特点:二、为什么需要DTO?(对比Entity)三、实际应用场景解析

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

深度解析Java项目中包和包之间的联系

《深度解析Java项目中包和包之间的联系》文章浏览阅读850次,点赞13次,收藏8次。本文详细介绍了Java分层架构中的几个关键包:DTO、Controller、Service和Mapper。_jav... 目录前言一、各大包1.DTO1.1、DTO的核心用途1.2. DTO与实体类(Entity)的区别1

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

使用Python绘制3D堆叠条形图全解析

《使用Python绘制3D堆叠条形图全解析》在数据可视化的工具箱里,3D图表总能带来眼前一亮的效果,本文就来和大家聊聊如何使用Python实现绘制3D堆叠条形图,感兴趣的小伙伴可以了解下... 目录为什么选择 3D 堆叠条形图代码实现:从数据到 3D 世界的搭建核心代码逐行解析细节优化应用场景:3D 堆叠图

深度解析Python装饰器常见用法与进阶技巧

《深度解析Python装饰器常见用法与进阶技巧》Python装饰器(Decorator)是提升代码可读性与复用性的强大工具,本文将深入解析Python装饰器的原理,常见用法,进阶技巧与最佳实践,希望可... 目录装饰器的基本原理函数装饰器的常见用法带参数的装饰器类装饰器与方法装饰器装饰器的嵌套与组合进阶技巧

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决