pe格式从入门到图形化显示(七)-导出表
文章目录
- 前言
- 一、什么是Windows PE格式中的导出表?
- 二、解析导出表并显示
- 1.导出表的结构
- 2.解析导出表
- 3.显示导出表
前言
通过分析和解析Windows PE格式,并使用qt进行图形化显示
一、什么是Windows PE格式中的导出表?
PE文件格式的导出表是PE文件中用于记录程序导出函数信息的数据结构。导出表位于数据目录表的第一项,索引值为0。导出表记录了当前文件对外开放的函数接口,使得其他程序可以通过这些接口调用该文件中的函数。
二、解析导出表并显示
1.导出表的结构
IMAGE_EXPORT_DIRECTORY结构体包含了导出表的特征、时间戳、版本号、导出函数数量、导出函数名称数量、导出函数地址表、导出函数名称表和导出函数序号表等信息。IMAGE_EXPORT_DIRECTORY的定义如下:
typedef struct _IMAGE_EXPORT_DIRECTORY {DWORD Characteristics;DWORD TimeDateStamp;WORD MajorVersion;WORD MinorVersion;DWORD Name;DWORD Base;DWORD NumberOfFunctions;DWORD NumberOfNames;DWORD AddressOfFunctions; // RVA from base of imageDWORD AddressOfNames; // RVA from base of imageDWORD AddressOfNameOrdinals; // RVA from base of image
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
IMAGE_EXPORT_DIRECTORY中的字段包括:
Characteristics:导出表的特征值,用于描述导出表的特性。
TimeDateStamp:时间戳,表示导出表创建或最后修改的时间。
MajorVersion和MinorVersion:导出表的主次版本号,用于标识导出表的版本信息。
Name:导出表的名称,通常为一个字符串,用于描述导出表的功能或用途。
Base:导出表中函数的起始序号,用于定位导出函数在文件中的位置。
NumberOfFunctions:导出表中导出的函数数量。
NumberOfNames:以名称导出的函数数量。
AddressOfFunctions:导出函数地址表在文件中的虚拟地址。
AddressOfNames:导出函数名称表在文件中的虚拟地址。
AddressOfNameOrdinals:导出函数序号表在文件中的虚拟地址。
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();return true;
}void PEParser::parserExportTable()
{DWORD address = 0;if (m_x86Flag){address = m_optionalHeader32.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;}else{address = m_optionalHeader64.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;}if (address == 0){return;}//将虚拟地址转换为文件地址RVA2FOAInfo info = RVA2FOA(address);//获取导出表数据IMAGE_EXPORT_DIRECTORY exportTable;memcpy(&exportTable, m_fileData.data() + info.FOA, sizeof(IMAGE_EXPORT_DIRECTORY));QList<DWORD> functionAddressList;QList<WORD> functionOrdinalsList;//获取导出函数序号表数据info = RVA2FOA(exportTable.AddressOfNameOrdinals);QByteArray ordinalsTempData = m_fileData.mid(info.FOA, exportTable.NumberOfFunctions * sizeof(WORD));//获取导出函数地址表数据info = RVA2FOA(exportTable.AddressOfFunctions);QByteArray addrTempData = m_fileData.mid(info.FOA, exportTable.NumberOfFunctions * sizeof(DWORD));//遍历导出表中导出函数的数据for (int i = 0; i < exportTable.NumberOfFunctions; ++i){DWORD addr = 0;memcpy(&addr, addrTempData.data() + i * sizeof(DWORD), sizeof(DWORD));functionAddressList.append(addr);WORD ordinal = 0;memcpy(&ordinal, ordinalsTempData.data() + i * sizeof(WORD), sizeof(WORD));functionOrdinalsList.append(ordinal);}//获取导出函数名称表数据info = RVA2FOA(exportTable.AddressOfNames);QByteArray nameTempData = m_fileData.mid(info.FOA, exportTable.NumberOfFunctions * sizeof(DWORD));//遍历导出表中以名称导出的数据QList<ExportFunctionInfo> exportFunctionInfo;for (int i = 0; i < exportTable.NumberOfNames; ++i){DWORD nameRVA = 0;memcpy(&nameRVA, nameTempData.data() + i * sizeof(DWORD), sizeof(DWORD));DWORD nameFOA = RVA2FOA(nameRVA).FOA;int index = m_fileData.indexOf('\0', nameFOA);ExportFunctionInfo info;info.name = m_fileData.mid(nameFOA, index - nameFOA);info.address = functionAddressList[functionOrdinalsList[i]];info.ordinal = functionOrdinalsList[i];exportFunctionInfo.append(info);}//按序号排序std::sort(exportFunctionInfo.begin(), exportFunctionInfo.end(), [=](const ExportFunctionInfo &info1, const ExportFunctionInfo &info2) -> bool{return info1.ordinal < info2.ordinal;});emit sendExportTable(exportFunctionInfo);
}
3.显示导出表
void MainWindow::showExportTable(const QList<ExportFunctionInfo> &exportTable)
{ui->tableWidget_exportTable->clearContents();ui->tableWidget_exportTable->setRowCount(0);for (int i = 0; i < exportTable.size(); ++i){ui->tableWidget_exportTable->insertRow(i);ui->tableWidget_exportTable->setItem(i, 0, new QTableWidgetItem(exportTable[i].name));ui->tableWidget_exportTable->setItem(i, 1, new QTableWidgetItem(QString::asprintf("%08lX", exportTable[i].address)));ui->tableWidget_exportTable->setItem(i, 2, new QTableWidgetItem(QString::asprintf("%08lX", exportTable[i].ordinal)));}
}
相关文章:
pe格式从入门到图形化显示(七)-导出表
文章目录 前言一、什么是Windows PE格式中的导出表?二、解析导出表并显示1.导出表的结构2.解析导出表3.显示导出表 前言 通过分析和解析Windows PE格式,并使用qt进行图形化显示 一、什么是Windows PE格式中的导出表? PE文件格式的导出表是P…...
图片地址生成二维码(通过前端实现)
文章目录 概要安装插件代码实例 概要 要将图片地址生成二维码,你可以使用 QrCode 库(假设你已经在项目中引入了该库)。以下是一个简单的示例代码,演示了如何使用 QrCode 库将图片地址转换为二维码并显示在页面上 安装插件 先下载…...
window安装maven和hadoop3.1.4
前面的文章已讲解如何安装idea和进行基本设置,本文主要带着大家安装配置好maven和hadoop. 大家不用去官网下载,直接使用我发给大家的压缩文件,注意解压后的文件夹不要放在中文目录下,课堂上我们讲解过原因。 这是我电脑上的路径&a…...
Redis系列之主从复制集群搭建
在上一篇博客,我们已经知道怎么搭建一个redis单机版,这篇博客基于之前的基础,来搭建一个redis主从同步,本博客框架是一主二从,一个主节点,其它两个从节点 实验环境 CentOS7Xshell6XFtp6Redis6.2.2 主从关…...
spring框架介绍
spring 1.优点 1)针对接口编程,解耦合 2)aop:变向切面编程,动态增加功能 3)方便集成框架,mybatis,hibernate,strust等 4)降低j2ee接口的使用难度 2.spring是干什么的 管理bean及bean…...
如果在 Ubuntu 系统中两个设备出现两个相同的端口号解决方案
问题描述: 自己的移动机器人在为激光雷达和IMU配置动态指定的端口时,发现激光雷达和深度相机配置的 idVendor 和 idProduct 相同,但是两个设备都具有不同的ttyUSB号,如下图所示 idVendor:代表着设备的生产商ID,由USB设…...
随手分享的APP链接,可能会让你“大型社死”
早晨上班路上,你在地铁百无聊赖地刷着短视频,看到一则好笑的,随手分享给了你的公司“饭搭子”,并配上了一串“哈哈哈哈哈哈”。 晚上下班路上你再次打开视频APP,发现首页弹窗给你推荐了一组“可能认识的人”ÿ…...
国内AI大模型已近80个,哪个最有前途?
根据中国新一代人工智能发展战略研究院发布的报告显示,目前全国已有3k+家人工智能企业,国内的AI大模型应该也近在200了!!! (原图图片过长了,这里就先放了20个) 面对如…...
美团一面:说说synchronized的实现原理?问麻了。。。。
引言 在现代软件开发领域,多线程并发编程已经成为提高系统性能、提升用户体验的重要手段。然而,多线程环境下的数据同步与资源共享问题也随之而来,处理不当可能导致数据不一致、死锁等各种并发问题。为此,Java语言提供了一种内置…...
P1123 取数游戏(dfs算法)
题目描述 一个 NM 的由非负整数构成的数字矩阵,你需要在其中取出若干个数字,使得取出的任意两个数字不相邻(若一个数字在另外一个数字相邻 8个格子中的一个即认为这两个数字相邻),求取出数字和最大是多少。 输入格式 第…...
交叉验证(Cross-Validation)
交叉验证的基本概念 交叉验证通常用于评估机器学习模型在未知数据上的性能。它将数据集分成k个不同的子集,然后进行k次训练和验证。在每次迭代中,选择一个子集作为测试集,其余的子集作为训练集。这样,每个子集都用作过测试集&…...
【kears】(01)keras使用介绍
文章目录 一.特点二.keras如何支持TensorFlow、CNTK 和 Theano2.1 使用 TensorFlow 后端引擎训练和评估模型2.2 使用 TensorFlow 后端引擎训练和评估模型2.3 使用 Theano后端引擎训练和评估模型2.4 不同深度学习框架如何选择1.1 keras.datasets:包含多种常用数据集1…...
2. TypeScript 安装与环境配置指南
TypeScript 是 JavaScript 的一个超集,它为 JavaScript 增加了类型系统和对 ES6 的支持。TypeScript 不仅能够帮助开发者捕获代码中的错误,还能提供更好的编辑器支持,包括代码补全、接口提示等。本文将详细介绍如何在您的开发环境中安装和配置…...
python pygame库的略学
文章目录 概述1. pygame的初始化和退出2. 创建游戏窗口(1)set_mode()(2)set_capyion()(3)update() 3. 游戏循坏与游戏时钟4. 图形和文本绘制(1)图形绘制(2)文…...
大模型日报2024-04-09
大模型日报 2024-04-09 大模型资讯 苹果预告超越ChatGPT的新AI模型ReaLM 摘要: 苹果公司最新宣布,即将推出一款名为ReaLM的人工智能模型。这款AI技术在理解复杂屏幕用户指令方面表现出高超的能力,并能与用户进行自然流畅的对话。ReaLM的推出预示着苹果在…...
抖音视频如何下载保存(方法分享)
有时刷抖音视频,看的喜欢的视频想要下载到本地,但是有很多视频无法下载或者下载下来是有水印的,那怎么办呢? 抖音视频下载有两种情况: 一种是可以直接点击分享下载,然后可以直接点击保存到相册。 视频就自动下载…...
MySQL-用户与权限管理:用户管理、权限管理、角色管理
用户与权限管理 用户与权限管理1.用户管理1.1 登录MySQL服务器1.2 创建用户1.3 修改用户1.4 删除用户1.5 设置当前用户密码1.6 修改其它用户密码 2. 权限管理2.1 权限列表2.2 授予权限的原则2.3 授予权限2.4 查看权限2.5 收回权限 访问控制连接核实阶段请求核实阶段 3. 角色管理…...
Vue.js中如何使用Vue Router处理浏览器返回键的功能
在Vue.js中,Vue Router默认提供了处理浏览器返回键的功能。当用户点击浏览器的返回键时,Vue Router会自动导航到历史记录中的上一个路由。然而,如果你想自定义返回键的行为或者在特定的页面上进行特殊处理,你可以使用Vue Router的…...
QT drawPixmap和drawImage处理图片模糊问题
drawPixmap和drawImage显示图片时,如果图片存在缩放时,会出现模糊现象,例如将一个100x100 的图片显示到30x30的区域,这个时候就会出现模糊。如下: 实际图片: 这个问题就是大图显示成小图造成的像素失真。 当…...
YOLOv9改进策略 :小目标 | 新颖的多尺度前馈网络(MSFN) | 2024年4月最新成果
💡💡💡本文独家改进:多尺度前馈网络(MSFN),通过提取不同尺度的特征来增强特征提取能力,2024年最新的改进思路 💡💡💡创新点:多尺度前馈网络创新十足,抢先使用 💡💡💡如何跟YOLOv8结合:1)放在backbone后增强对全局和局部特征的提取能力;2)放在detect…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
