PE文件(四)FileBuffer-ImageBuffer

文件执行的总过程

当文件从硬盘中读入虚拟内存(FileBuffer)中时,文件数据会被原封不动的复制一份到虚拟内存中,然后进行拉伸对齐。此时虚拟内存中文件数据叫做文件印象或者内存印象,即ImageBuffer。此时ImageBuffer中的文件的数据满足文件运行的条件,但文件仍然不能真正的运行。只有当操作系统将文件真正的装入物理内存中, CPU进行分配执行后,文件才算真正运行了

SizeOfRawData与Misc.VirtualSize

SizeOfRawData表示此节在硬盘上经过文件对齐后的大小,Misc.VirtualSize表示此节在内存中对齐前的大小,即文件数据在内存中真正分配的大小

当我们初始化一个全局变量,如数组int arr[1000] = {0}时,编译器将编译好的.exe文件存放在硬盘上,这1000个int类型的0会存放在某一个节中,并分配1000个0的空间。并且这个空间大小在硬盘中和在内存中是一致的。由于SizeOfRawData的大小加上了文件对齐时多出来的空间,所以SizeOfRawData一般大于或等于Misc.VirtualSize

但是当我们只声明不初始化该数组时,文件在硬盘上的数据对此数组有声明但是不会分配这1000的空间的。所以SizeOfRawData在计算时不会算上这未初始化的空间。但是当文件真正加载到物理内存中时,操作系统会分配这1000的空间,所以Misc.VirtualSize在计算时会加上未初始化的空间的。在这种情况下Misc.VirtualSize可能大于SizeOfRawData

手动模拟FileBuffer到ImageBuffer过程

1.获取FileBuffer:先在硬盘上找一个可执行文件,将该文件的数据复制到缓冲区中,即FileBuffer中

2.申请ImageBuffer:根据SizeOfImage即文件加载到4GB虚拟内存中的大小,使用malloc开辟另一块缓冲区ImageBufferb并初始化,用来存放文件虚拟内存中的数据

3.复制PE头字段:由于经过文件对齐后的所有头和节表的数据加载到ImageBuffer的过程中是不会改变的,所以可以通过sizeofheads获取这些数据的内存大小,直接从FileBuffer中复制到ImageBuffer中

4.复制所有的节:通过第一个节对应节表中的PointerToRawData的值确定该节在FileBuffer的起始地址,然后通过SizeOfRawData的值确定该节在FileBuffer中需要复制的数据的大小,再通过VirtualAddress再加上ImageBase得到此节在ImageBuffer中的起始地址,最后将FileBuffer对应的数据在ImageBuffer中的起始地址位置开始复制,完成第一个节的复制。剩下的节如此循环赋值即可。

选择SizeOfRawData来确定需要复制的节的大小的原因:在极端情况下,当节中存在足够大未初始化的数据时,按照Misc.VirtualSize值将FileBuffer中的数据复制到ImageBuffer中,很可能会把FileBuffer中下一个节的数据也复制过去,这样就会造成复制错误。所以直接用SizeOfRawData就可以了。在这两个选择中更好的做法是比较SizeOfRawData和VirtualSize,选择较小值。但实际上这两种选择哪一个都可以

内存偏移地址与文件偏移地址换算

在此之前我们应该知道DOS头的起始地址和imagebase没有关系,现在假设有一个文件在4GB虚拟内存中起始位置0x500000,有一个数据,其地址为0x501234。我们要求出该地址对应的硬盘内存地址:

1.先算出此数据虚拟内存地址相对于文件在虚拟内存中的起始地址的偏移量

2.通过这个偏移量和每一个节的VirtualAddress做循环比较,当此偏移量大于某一个节的VirtualAddress并且小于此VirtualAddress + Misc.VirtualSize,就说明这个内存地址就在这个节中

3.用此偏移量-此节的VirtualAddress得到这个数据的虚拟内存地址相对于所在节的偏移量

4.找该数据虚拟内存地址所在节对应节表中PointerToRawData,通过PointerToRawData + 内存地址相对于所在节的偏移量来得到此内存地址在硬盘上时相对于文件的偏移量

举例:现在我们要找0x501234对应的文件偏移是多少?

1.0x501234 - 0x500000 = 0x1234

2.因为0x1000 < 0x1234 < 0x1000 + Misc.VirtualSize,所以0x501234在可执行文件的第一个节中

3.0x1234 - 0x1000 = 0x234获取该数据相对于该节的偏移量

由于第一个节的PointerToRawData为0x400,且假设FileBuffer的起始地址为0(相对与文件在真实内存起始地址),则0x501234对应的文件偏移地址为0x400 + 0x234 = 0x634

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

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

相关文章

42.乐理基础-拍号-看懂拍号的意义

到这必然是已经知道 X、Y的意思了&#xff1a; 然后带入数字&#xff1a; 然后念拍号的时候&#xff0c;在国内&#xff0c;百分之九十的地方是从下往上念&#xff0c;念作四二拍&#xff0c;还有百分之十的地方是和国外一样&#xff0c;从上往下念&#xff0c;念作二四拍&…

使用vant组件库

官方文档&#xff1a;Vant 4 - A lightweight, customizable Vue UI library for mobile web apps. vue2对应vant2&#xff0c;vue3对应vant3/vant4 1.安装 官网的快速上手里都有介绍。 # Vue 3 项目&#xff0c;安装最新版 Vant&#xff1a; npm i vant -S# Vue 2 项目&am…

跨境支付行业研究

1. 行业基本情况 随着全球人均购买力增强、互联网普及率提升、支付渠道的进一步成熟、物流等配套设施的完善&#xff0c;网络购物已经成为全球兴起的消费习惯。另一方面&#xff0c;跨境电商对传统贸易的替代已经成为趋势。跨境电商在交易成本和便利程度上都有明显的优势 图1 …

【问题记录】ORA-31603 对象 ““ 属于类型 , 在方案 ““ 中未找到,存储过程procedure执行报错

文章目录 问题&#xff1a;解决方法 问题&#xff1a; ORA-31603: 对象 “V_RST_UTC01390” 属于类型 VIEW, 在方案 “RISKCONFIG_BAK” 中未找到 ORA-06512: 在 “SYS.DBMS_METADATA”, line 5805 ORA-06512: 在 “SYS.DBMS_METADATA”, line 8344 ORA-06512: 在 line 1&…

大数据API技术分享:使用API接口采集淘宝数据(商品详情丨关键词搜索丨店铺所有商品)

使用API接口采集淘宝数据&#xff08;商品详情、关键词搜索、店铺所有商品&#xff09;是大数据领域常见的应用场景。以下是一些关于如何使用API接口进行这些操作的技术分享&#xff1a; 1. 获取API权限 首先&#xff0c;你需要在淘宝开放平台注册成为开发者&#xff0c;并创建…

想做视频号小店,为何不建议开通个体店?开店步骤+做店思路如下

我是王路飞。 如果你想在视频号开通店铺的话&#xff0c;那么一定不要使用个体执照开通个体店&#xff1f; 这是为什么呢&#xff1f; 原因很简单&#xff0c;视频号个体店是无法入驻优选联盟的&#xff0c;只能企业店可以入驻。 因为现阶段视频号小店的自然流量很少&#…

五一 作业

#include <iostream>using namespace std; class Num { private:int a; public:Num() {}Num(int a):a(a){}//设置a的值void set(int a){this->aa;}//1-a的和void Sum(){if(a<1){cout<<"a<1"<<endl;return;}int sum0;for(int i1;i<a;i)…

开源模型应用落地-CodeQwen模型小试-探索更多使用场景(三)

一、前言 代码专家模型是基于人工智能的先进技术&#xff0c;它能够自动分析和理解大量的代码库&#xff0c;并从中学习常见的编码模式和最佳实践。这种模型可以提供准确而高效的代码建议&#xff0c;帮助开发人员在编写代码时避免常见的错误和陷阱。 通过学习代码专家模型&…

使用QT开发ROS可视化界面

Q&#xff1a; undefined reference to non-virtual thunk to MyViz A&#xff1a; 该问题主要由于QT中的MOC File没有正确生成&#xff0c;导致虚函数列表出现问题。另外&#xff0c;需要注意虚函数的virtual关键字需要放在类的声明&#xff0c;不能放在类的定义。 qt5_wrap…

获取Android Native堆栈

文章目录 工具和方法获取当前线程的堆栈信息获取任意线程的堆栈信息GCC生成符号的规律总结 在Android系统中&#xff0c;我们有时需要获取Native层的堆栈信息&#xff0c;例如在进行性能分析、问题定位和调试等场景。本文将介绍如何在Android Native层获取堆栈信息&#xff0c;…

计算机视觉——OpenCV Otsu阈值法原理及实现

算法简介 Otsu阈值法&#xff0c;也被称为大津算法&#xff0c;是一种在图像处理中广泛使用的自动阈值分割技术。这种方法由日本学者大津展之于1979年提出&#xff0c;旨在根据图像的灰度直方图来自动选择最佳全局阈值。Otsu阈值法的核心思想是最小化类内方差或最大化类间方差…

《设计一款蓝牙热敏打印机》

主控芯片用易兆威蓝牙ic&#xff0c;通讯接口&#xff1a;蓝牙、串口、usb 安卓apk用java kotlin编写、上位机用Qt编写。

【微磁学】对于现阶段微磁学仿真发展的思考1-理论篇

系列文章目录 对于现阶段微磁学仿真发展的思考1-理论篇 对于现阶段微磁学仿真发展的思考2-工具篇 文章目录 系列文章目录前言一、微磁学的数学区二、微磁学的物理区三、微磁学仿真现存的一些问题四、微磁学代码区&#xff1a;上手操作&#xff0c;理解更深入栗子1: 能量最小化…

【代码随想录】day50

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、123买卖股票的最佳时机III二、188买卖股票的最佳时机IV 一、123买卖股票的最佳时机III 超时了。。。 class Solution { public:int helper(vector<int>…

lsof 查看进程是被哪个文件占用

要查看进程被哪个文件占用&#xff0c;可以使用lsof命令&#xff08;list open files&#xff09;。可以使用以下命令来查看指定进程的打开文件&#xff1a; lsof -p <PID>其中&#xff0c;<PID>是要查询的进程的进程ID。这将列出指定进程打开的所有文件。如果想查…

WouoUIPagePC端实现

WouoUIPagePC端实现 WouoUIPage是一个与硬件平台无关&#xff0c;纯C语言的UI库&#xff08;目前只能应用于128*64的单色OLED屏幕上&#xff0c;后期会改进&#xff0c;支持更多尺寸&#xff09;。因此&#xff0c;我们可以在PC上实现它&#xff0c;本文就以在PC上使用 VScode…

Java面试题:Spring里面的@RestController和@ResponseBody有什么作用?

ResponseBody ResponseBody一般是加在方法上&#xff0c;将返回的对象解析成xml或者json&#xff0c;返回给请求的调用者。一般是用于服务之间的调用&#xff0c;或者前端请求后端时&#xff0c;使用ajax请求。 如果不加ResponseBody&#xff0c;一般就是返回的url&#xff0c…

研发效能 | Jacoco dump基于k8s的实现

问题描述 总所周知&#xff0c;jacoco的dump操作如果是使用server模式只需要使用以下命令就能获取到 exec 文件。 java -jar jacococli.jar dump --address 192.169.110.1 --port 6300 --destfile ./jacoco-demo.exec 如果是非 k8s 的集群&#xff0c;也只需要遍历执行这条命…

Python实现打砖块游戏

提供学习或者毕业设计使用&#xff0c;功能基本都有&#xff0c;不能和市场上正式游戏相提比论&#xff0c;请理性对待&#xff01; 在本文中&#xff0c;我们将使用 Pygame 和 Tkinter 创建一个简单的打砖块游戏。游戏的目标是通过控制挡板来击碎屏幕上的砖块&#xff0c;同时…

基于 OpenHarmony compress 三方件使用指南~

关于 提供了一个轻量级的图像压缩库。将允许您将大照片压缩成小 尺寸的照片&#xff0c;图像质量损失或可以忽略不计 compress 的依赖添加 为你的应用添加 compress-debug.har。将 compress-debug.har 复制到 entry\libs 目录下即可&#xff08;由于 build.gradle 中已经依赖…