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

相关文章

Linux中shell解析脚本的通配符、元字符、转义符说明

《Linux中shell解析脚本的通配符、元字符、转义符说明》:本文主要介绍shell通配符、元字符、转义符以及shell解析脚本的过程,通配符用于路径扩展,元字符用于多命令分割,转义符用于将特殊... 目录一、linux shell通配符(wildcard)二、shell元字符(特殊字符 Meta)三、s

Linux使用dd命令来复制和转换数据的操作方法

《Linux使用dd命令来复制和转换数据的操作方法》Linux中的dd命令是一个功能强大的数据复制和转换实用程序,它以较低级别运行,通常用于创建可启动的USB驱动器、克隆磁盘和生成随机数据等任务,本文... 目录简介功能和能力语法常用选项示例用法基础用法创建可启动www.chinasem.cn的 USB 驱动

Python 标准库time时间的访问和转换问题小结

《Python标准库time时间的访问和转换问题小结》time模块为Python提供了处理时间和日期的多种功能,适用于多种与时间相关的场景,包括获取当前时间、格式化时间、暂停程序执行、计算程序运行时... 目录模块介绍使用场景主要类主要函数 - time()- sleep()- localtime()- g

使用Python实现批量访问URL并解析XML响应功能

《使用Python实现批量访问URL并解析XML响应功能》在现代Web开发和数据抓取中,批量访问URL并解析响应内容是一个常见的需求,本文将详细介绍如何使用Python实现批量访问URL并解析XML响... 目录引言1. 背景与需求2. 工具方法实现2.1 单URL访问与解析代码实现代码说明2.2 示例调用

SSID究竟是什么? WiFi网络名称及工作方式解析

《SSID究竟是什么?WiFi网络名称及工作方式解析》SID可以看作是无线网络的名称,类似于有线网络中的网络名称或者路由器的名称,在无线网络中,设备通过SSID来识别和连接到特定的无线网络... 当提到 Wi-Fi 网络时,就避不开「SSID」这个术语。简单来说,SSID 就是 Wi-Fi 网络的名称。比如

SpringCloud配置动态更新原理解析

《SpringCloud配置动态更新原理解析》在微服务架构的浩瀚星海中,服务配置的动态更新如同魔法一般,能够让应用在不重启的情况下,实时响应配置的变更,SpringCloud作为微服务架构中的佼佼者,... 目录一、SpringBoot、Cloud配置的读取二、SpringCloud配置动态刷新三、更新@R

使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)

《使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)》在现代软件开发中,处理JSON数据是一项非常常见的任务,无论是从API接口获取数据,还是将数据存储为JSON格式,解析... 目录1. 背景介绍1.1 jsON简介1.2 实际案例2. 准备工作2.1 环境搭建2.1.1 添加

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

在C#中合并和解析相对路径方式

《在C#中合并和解析相对路径方式》Path类提供了几个用于操作文件路径的静态方法,其中包括Combine方法和GetFullPath方法,Combine方法将两个路径合并在一起,但不会解析包含相对元素... 目录C#合并和解析相对路径System.IO.Path类幸运的是总结C#合并和解析相对路径对于 C

Java解析JSON的六种方案

《Java解析JSON的六种方案》这篇文章介绍了6种JSON解析方案,包括Jackson、Gson、FastJSON、JsonPath、、手动解析,分别阐述了它们的功能特点、代码示例、高级功能、优缺点... 目录前言1. 使用 Jackson:业界标配功能特点代码示例高级功能优缺点2. 使用 Gson:轻量