pe格式从入门到图形化显示(九)-重定位表


文章目录

  • 前言
  • 一、什么是Windows PE格式中的重定位表表?
  • 二、解析重定位表并显示
    • 1.重定位表的结构
    • 2.解析重定位表
    • 3.显示重定位表


前言

通过分析和解析Windows PE格式,并使用qt进行图形化显示


一、什么是Windows PE格式中的重定位表表?

重定位表是Windows PE文件格式中的一种特殊数据结构,用于在程序加载到内存时修正地址。当程序被加载到内存时,它可能不会被加载到其预期的默认地址,而是被加载到其他地址。这就需要对程序中的地址进行重定位,以确保程序能够正确地运行。

总之,重定位表是PE文件格式中的一种关键数据结构,它用于在程序加载到内存时修正地址,确保程序能够正确地运行。

二、解析重定位表并显示

1.重定位表的结构

重定位表的结构如下:
重定位表是一个结构体数组,以全零元素结尾,每一个数组元素描述了4KB大小的区域的重定位信息。结构体包含两个重要成员:VirtualAddress和SizeOfBlock。VirtualAddress表示需要重定位的位置,这是一个RVA(相对虚拟地址);SizeOfBlock表示这个结构体的大小,包括TypeOffset数组的大小。

struct IMAGE_BASE_RELOCATION {DWORD VirtualAddress;DWORD SizeOfBlock;
};

TypeOffset数组是一个不定长度的数组,它紧随在结构体之后。TypeOffset数组中的每个元素都描述了一个相对于第一个元素描述的位置的偏移。这个偏移用于计算实际的内存地址。
TypeOffset数组中的每个元素都是一个32位的值,其中高12位表示重定位类型,低20位表示重定位的偏移。重定位类型有以下几种:
IMAGE_REL_BASED_ABSOLUTE:表示不需要重定位,这是一个占位符。
IMAGE_REL_BASED_HIGH:表示需要重定位的地址是一个16位的高位部分。
IMAGE_REL_BASED_LOW:表示需要重定位的地址是一个16位的低位部分。
IMAGE_REL_BASED_HIGHLOW:表示需要重定位的地址是一个32位的地址。
IMAGE_REL_BASED_HIGHADJ:表示需要重定位的地址是一个16位的高位部分,但是需要加上一个额外的16位的值。
IMAGE_REL_BASED_MIPS_JMPADDR:表示需要重定位的地址是一个MIPS架构的跳转地址。
IMAGE_REL_BASED_ARM_MOV32:表示需要重定位的地址是一个ARM架构的32位地址。
IMAGE_REL_BASED_THUMB_MOV32:表示需要重定位的地址是一个ARM Thumb架构的32位地址。
IMAGE_REL_BASED_MIPS_JMPADDR16:表示需要重定位的地址是一个MIPS架构的16位跳转地址。
IMAGE_REL_BASED_IA64_IMM64:表示需要重定位的地址是一个IA64架构的64位地址。
IMAGE_REL_BASED_DIR64:表示需要重定位的地址是一个64位的地址。

重定位表中的每个元素都对应于PE文件中的一个4KB大小的内存块。在这个块中,可能有一些地址需要被重定位。这些地址被记录在TypeOffset数组中,每个元素对应一个需要重定位的地址。当程序被加载到内存时,系统会使用重定位表中的信息来修正这些地址,以确保程序能够正确地运行。

2.解析重定位表

bool PEParser::parserFileData(const QByteArray &fileData)
{//判断是否是MZ开头的文件if (fileData.left(2) != "MZ"){return false;}//解析DOS头parserDOSHeader(fileData.left(sizeof(IMAGE_DOS_HEADER)));//DOSStub数据m_dosStubData = fileData.mid(sizeof(IMAGE_DOS_HEADER), m_dosHeader.e_lfanew - sizeof(IMAGE_DOS_HEADER));long peAddress = m_dosHeader.e_lfanew;if (fileData.mid(peAddress, 2) != "PE"){return false;}m_fileData = fileData;//去除前4个字节的PE头标识long fileHeaderIndex = peAddress + 4;//记录文件头索引m_fileHeaderIndex = fileHeaderIndex;//解析标准PE文件头paserFileHeader(fileData.mid(fileHeaderIndex, sizeof(IMAGE_FILE_HEADER)));//解析扩展PE文件头long optionHeaderIndex = fileHeaderIndex + sizeof(IMAGE_FILE_HEADER);//记录扩展PE文件头索引m_optionHeaderIndex = optionHeaderIndex;//解析扩展PE文件头parserOptionHeader(fileData.mid(optionHeaderIndex, m_fileHeader.SizeOfOptionalHeader));//解析节表long sectionHeaderIndex = optionHeaderIndex + m_fileHeader.SizeOfOptionalHeader;//节表结构在文件中开始的偏移m_sectionHeaderIndex = sectionHeaderIndex;//解析节表parserSectionHeader(fileData.mid(sectionHeaderIndex,m_fileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER)));//解析数据目录parserDataDirectory();//解析导出表parserExportTable();//解析导入表parserImportTable();//解析重定位表parserRelocationTable();return true;
}void PEParser::parserRelocationTable()
{DWORD address = 0;if (m_x86Flag){address = m_optionalHeader32.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;}else{address = m_optionalHeader64.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;}if (address == 0){return;}RVA2FOAInfo info = RVA2FOA(address);IMAGE_BASE_RELOCATION *relocation = reinterpret_cast<IMAGE_BASE_RELOCATION *>(m_fileData.data() + info.FOA);while (relocation->VirtualAddress > 0 && relocation->SizeOfBlock > 0){RelocationInfo relocationInfo;int items = (relocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2;for (int i = 0; i < items; ++i){RelocationItem item;WORD word = 0;memcpy(&word, m_fileData.data() + info.FOA + sizeof(IMAGE_BASE_RELOCATION) + i * sizeof(WORD), sizeof(WORD));//需要进行重定位item.type = (word >> 12);item.RVA = relocation->VirtualAddress + (word & 0X0FFF);item.FOA = RVA2FOA(item.RVA).FOA;memcpy(&item.relocationRVA, m_fileData.data() + item.FOA, sizeof(item.relocationRVA));item.relocationRVA &= 0X00FFFFFF;item.relocationData = m_fileData.mid(RVA2FOA(item.relocationRVA).FOA, 11);relocationInfo.items.append(item);}relocationInfo.RVA = relocation->VirtualAddress;relocationInfo.sectionName = RVA2FOA(relocationInfo.RVA).sectionName;emit sendRelocationTable(relocationInfo);relocation = reinterpret_cast<IMAGE_BASE_RELOCATION *>(reinterpret_cast<char *>(relocation) + relocation->SizeOfBlock);}
}

3.显示重定位表

void MainWindow::on_tableWidget_relocationBase_clicked(const QModelIndex &index)
{if (ui->tableWidget_relocationBase->rowCount() > index.row()){QTableWidgetItem *item = ui->tableWidget_relocationBase->item(index.row(), 0);RelocationInfo info = item->data(100).value<RelocationInfo>();ui->tableWidget_relocationItem->clearContents();ui->tableWidget_relocationItem->setRowCount(0);for (int i = 0; i < info.items.size(); ++i){ui->tableWidget_relocationItem->insertRow(i);ui->tableWidget_relocationItem->setItem(i, 0, new QTableWidgetItem(QString::asprintf("%04X", i + 1)));ui->tableWidget_relocationItem->setItem(i, 1, new QTableWidgetItem(QString::asprintf("%08lX", info.items[i].RVA)));ui->tableWidget_relocationItem->setItem(i, 2, new QTableWidgetItem(QString::asprintf("%08lX", info.items[i].FOA)));ui->tableWidget_relocationItem->setItem(i, 3, new QTableWidgetItem(QString::asprintf("%08lX", info.items[i].relocationRVA)));QString type;switch (info.items[i].type){case IMAGE_REL_BASED_ABSOLUTE:{type = "ABSOLUTE";break;}case IMAGE_REL_BASED_HIGH:{type = "HIGH";break;}case IMAGE_REL_BASED_LOW:{type = "LOW";break;}case IMAGE_REL_BASED_HIGHLOW:{type = "HIGHLOW";break;}case IMAGE_REL_BASED_HIGHADJ:{type = "HIGHADJ";break;}case IMAGE_REL_BASED_MIPS_JMPADDR:{type = "JMPADDR";break;}case IMAGE_REL_BASED_THUMB_MOV32:{type = "MOV32";break;}case IMAGE_REL_BASED_MIPS_JMPADDR16:{type = "JMPADDR16";break;}case IMAGE_REL_BASED_DIR64:{type = "DIR64";break;}}ui->tableWidget_relocationItem->setItem(i, 4, new QTableWidgetItem(type));ui->tableWidget_relocationItem->setItem(i, 5, new QTableWidgetItem(QString(info.items[i].relocationData.toHex().toUpper())));ui->tableWidget_relocationItem->setItem(i, 6, new QTableWidgetItem(QString(info.items[i].relocationData)));}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/805778.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nandgame中的Grammar(语法)

题目说明&#xff1a; 语法定义涉及数字、括号和运算符和-的表达式的语法。起始符号为Expression。一个表达式应该对应于以下之一&#xff1a;一个数字标记Expression ExpressionExpression - Expression- Expression( Expression ) level help 通过语法来描述高级语言的…

[RK-Linux] RK3399使用开源TPL与SPL方式加载U-Boot

文章目录 一、U-Boot1.1 下载源码1.2 配置U-Boot1.2.1 配置串口波特率1.2.2 配置U-Boot启动倒计时1.2.3 开启调试信息1.3 编译U-Boot1.4 U-Boot镜像二、idbloader.img2.1 tpl/u-boot-tpl.bin2.2 spl/u-boot-spl.bin三、u-boot.idb3.1 FIT介绍

SMT用料全检抽检

下载地址百度网盘&#xff1a; https://pan.baidu.com/s/1kDn_l8P6ReC4Lj5tgt-v4w?pwd5y41 提取码:5y41 1、扫描输入车间线体 2、根据线体获取在线订单 3、选择(全检|抽检|换接新料)开始 4、根据提示扫描站位和料号核对 5、核对成功再扫描核对下一组

纯Python实现Qt的信号与槽机制

纯Python实现Qt的信号与槽机制 Qt中的信号与槽详解 在Qt框架中&#xff0c;信号与槽是一种非常有特色的机制&#xff0c;用于对象之间的通信。这一机制是Qt中实现事件驱动编程的核心部分。下面我将详细解释信号与槽的概念和它们是如何工作的。 信号&#xff08;Signals&#…

【复现】用友NC-Cloud文件上传漏洞_70

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 用友NC Cloud大型企业数字化平台&#xff0c;深度应用新一代数字智能技术&#xff0c;完全基于云原生架构&#xff0c;打造开放、…

碳交易机制下考虑需求响应的优化运行-MATLAB复现

读完《碳交易机制下考虑需求响应的综合能源系统优化运行——魏震波》这篇文章后&#xff0c;我对咱们能源系统的未来充满了期待。文章里头提到的那些复杂的数学模型和算法&#xff0c;虽然听起来有点高大上&#xff0c;但其实它们就像是给能源系统装上了一个智能大脑&#xff0…

vue3实现导出pdf、png功能

准备做的系统中出现了 想导出当前页面的png或者pdf设计数据较多后端做可能比较麻烦 就自己研究了一下 1、安装html2canvas 、jspdf包 npm install --save html2canvas // 可以将dom元素转为一张图片 npm install --save jspdf // 导出为PDF格式 2、vue组件中引用&#x…

【石上星光】context,go的上下文存储并发控制之道

目录 1 引言2 What&#xff1f;3 How&#xff1f; 3.1 用法一、上下文数据存储3.2 用法二、并发控制 3.2.1 场景1 主动取消3.2.2 场景2 超时取消 3.3 用法三、创建一个空Context&#xff08;emptyCtx&#xff09; 4 Why&#xff1f; 4.1 go中的上下文思想 4.1.1 上下文是什么…

html展示微信小程序二维码

1.生成微信小程序二维码 获取不限制的小程序码 | 微信开放文档 2.经过验证&#xff0c;下面两种方式可行 2.1直接将官方生成的内容直接在src标签里面是可以展示的 接口要支持GET请求 html代码 <body > <!--get请求可以&#xff0c;post请求不行--> <img src…

DataLoader类

DataLoader 类是 PyTorch 中用于构建数据加载器的一个重要工具&#xff0c;它可以对数据集进行批处理、洗牌和并行加载&#xff0c;以便于训练神经网络模型。 ### 输入参数&#xff1a; - **dataset**&#xff1a;数据集对象&#xff0c;通常是 torch.utils.data.Dataset 类的…

python爬虫———激发学习兴趣的案列(第十三天)

&#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; &#x1f388;&#x1f388;所属专栏&#xff1a;python爬虫学习&#x1f388;&#x1f388; ✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天…

工业通信原理——CAN通信精讲

工业通信原理——CAN通信精讲 前言 CAN总线是一种用于在控制系统中进行通信的串行总线标准,常用于汽车、工业控制等领域。它允许多个设备在同一总线上进行通信,而不需要中央控制器,因此具有分布式、实时性强等特点。 CAN总线的报文格式通常分为两种:数据帧(Data Frame)…

渲染农场实时画面怎么设置?云渲染农场实时预览效果查看

许多用户在使用渲染农场服务时&#xff0c;常常难以找到查看实时渲染画面的功能。由于渲染是一个时间消耗较大的任务&#xff0c;如果最终结果与预期不符&#xff0c;可能会对整个工作流程产生负面影响。因此&#xff0c;渲染平台若能提供实时预览渲染进度和效果的功能&#xf…

代码随想录算法训练营第五十天 | 123. 买卖股票的最佳时机 III、188. 买卖股票的最佳时机 IV

代码随想录算法训练营第五十天 | 123. 买卖股票的最佳时机 III、188. 买卖股票的最佳时机 IV 123. 买卖股票的最佳时机 III题目解法 188. 买卖股票的最佳时机 IV题目解法 感悟 123. 买卖股票的最佳时机 III 题目 解法 题解链接 1. class Solution { public:int maxProfit(ve…

【汇编语言实战】求三个已知数最大值

C语言描述该程序流程&#xff1a; #include <stdio.h> int main() {int a10,b20,c15;//scanf("%d %d",&a,&b);if(a>b){if(a>c){printf("%d",c);}else{printf("%d",a);}}else{if(b>c){printf("%d",b);}else{pr…

【C++】掌握C++函数重载和引用开启代码优化的新篇章

欢迎来CILMY23的博客 本篇主题为 掌握C函数重载和引用开启代码优化的新篇章 个人主页&#xff1a;CILMY23-CSDN博客 个人专栏&#xff1a; | | | CILMY23-CSDN博客 上一篇博客&#xff1a;第一个C结构&#xff0c;C关键字&#xff0c;命名空间&#xff0c;C的输入输出&…

IPEX-LLM(原名BigDL-LLM)环境配置

IPEX-LLM 是一个为Intel XPU (包括CPU和GPU) 打造的轻量级大语言模型加速库&#xff0c;在Intel平台上具有广泛的模型支持、最低的延迟和最小的内存占用。 您可以使用 IPEX-LLM 运行任何 PyTorch 模型&#xff08;例如 HuggingFace transformers 模型&#xff09;。在运行过程中…

TTL接口的输入输出

The Ins and Outs of the TTL Interface 串行通信可在相当长的距离内传输数据&#xff0c;通常与 TTL 标准有关。数据通过串行通信传输&#xff0c;串行通信通过单线传输比特位。数据通过双方--发送方和接收方--以二进制脉冲的形式使用各种串行数字二进制技术进行交换。 RS232 …

jquery按回车切换下一个文本框

/** *按回车切换下一个文本框 *param field *param event *returns Boolean *οnkeypress"return handleEnter(this,event)" */ function handleEnter(field,event){ var keyCode event.keyCode ? event.keyCode : event.which ? event.which :event.ch…

Sql缺失索引查询,自动创建执行语句

试图查询确实的索引 CREATE VIEW [dbo].[vw_Index_MissingIndex] ASSELECT [ d.name ] as DBName,[dbo].[fn_Index_CreateIndexName](mid.equality_columns,mid.Inequality_columns,mid.index_handlE) AS ID,REPLACE(mid.equality_columns,,, ASC,) AS equality_columns,REP…