PE文件手工压缩
序
本文要压缩的PE文件来自软件漏洞这门课上布置的作业,代码逻辑很简单,直接运行就能看出来,就是调库来弹两个对话窗口。笔者主要记录一下对这个文件的分析和一步步实现手工压缩的过程。在此提供原文件的下载方式供大家复现:PE程序下载
先是介绍各个部分要修改、要注意的地方,然后是说明一下以“在修改文件对齐方式后删除冗余数据”为主要方式,通过这种思路来压缩PE文件的做法。
PE文件各部分分析
0x0_DOS头+DOS_Stub
首先是开头0x4字节的MZ头不能动,然后0x3C的地方需要指向NT头的PE签名,除了这两个地方,DOS头和DOS_Stub的其他部分都可以删了,可以看到我把这些全都标识为1后程序正常运行。
下面也是一样的,我把能删的或者不会影响这个简单程序正常运行的地方都置1了,其实都是一点点试出来的,慢慢地改,就能发现到那些地方一被修改后,程序就不能正常运行了。

0xb0_NT头
NT头的前六个字节不能动,分别是四个字节的PE签名、两个字节的CPU的MAchine码,然后是两个字节的节区数目。
(下面开始以pfile的地址来说明)0xC4的可选头大小为固定值0xe0(0xc8-0x1a8=0xe0)
再往下,文件信息标志不能动,0xC8开始是可选头,前两个字节的可选头类型不能动。然后就到了0xD8的 Address of Entry Point,指向程序入口RVA,这个千万不能修改错。0xE4的镜像基址不能动,0xE8和0xEC的两个对齐大小需要注意。0xF8的主子系统版本号不能动,0x100的镜像在内存中大小,感觉改大了无所谓,别改小了导致不够用就行,这后面的 Size of Headers 标识着PE头的大小,要注意修改,不然就无法寻址到后面的节区了。0x10C开始的两个字节的子系统号和两个字节的DLL标志不能动,0x124是数据目录项数,是能改的,而且这个程序只需要导入表和导入地址表,但是一改就报错,所以先没管了... 然后这两个表的rva和size都是要去修改的,它俩的相对偏移也不能变

0x1A8_节表
这个程序有三个节,自然就有三个节表,分别是.text节表,.rdata节表,.data节表
这三个表的前八个字节都别去动,后面的真实大小不用管,要修改的是RVA,Size,Pointer,然后最后的四个字节的特征值也不能改,其他的都无所谓,每一个节表头都是这样
0x400_.text
注意改这些rva地址,分析的方法是丢进ida去看代码段的每一句汇编代码分别对应了什么字节码,对比着就很容易把这些直接寻址的地方找出来,要注意的是最后两个地址其实是与.rdata段存储的dll的名字有关的

0x600_.rdata
同样是丢进ida看,注意改这些rva地址,慢慢去算要修正成什么rva,得跟压缩前的指向同样的地方,改错了就无法寻址到了

0x800_.data
不需要做任何修改
开始压缩
先删除DOS_Stub,修改0x3C处的RVA地址指向新的PE头,然后NT头基本都不用动,删除多余的0后,就看着改下 Address of Entry Point, Section Alignment, File Alignment, Size of Image, Size of Headers, 然后是 IMPORT Table 和 IMPORT Address Table 的RVA和Size,对齐方式我两个都改成了0x4,这是最小的对齐单位了,另外,对齐方式设成一样其实对后续修改文件也有好处,这样pflie就和rva就一致了,改一些直接寻址的地方就不用考虑这么多了,毕竟有寻址的地方要做修改的话,找到目标位置看pfile是多少就改成多少就好
最后的三个节表按上述分析里说的 去改相应的地方,代码节和数据节删除掉多余的部分后,也是按上面分析中的图去修改红框处那些rva地址,最后修改完是732字节,如图所示

记录下小坑
NT头
NT头里的Size of Headers要看好来改,不然直接找不到下面那些块了,数据表的IMPORT Address Table里的东西也是要改的,这个比较容易遗漏
.rdata
rdata节里面,直接把后面的所有'\x00'都删掉是不可以的,我一开始改的时候就注意到一个问题,发现如果把后面的'\x00'都删掉了,最后面存储的库名就会和data段的数据拼接起来,这样的话去进行字符串匹配肯定是会出问题的,所以得要'\x00'来截断,果不其然,去看了下.rdata的真实大小是0x92,这就是原程序为什么非要多加两个'\x00'在后面了,所以我们修改的.rdata的Size of Raw Data得是0x94,用'\x00'补齐
后续压缩思路
想要继续往下压缩就得走别的思路了,首先可以看见还有很多没有用到的标识成'\x00'的数据,但是又删不得,就好比,头有用,尾有用,如果删掉了中间部分,头尾拼接在一起,就不能用 ”头+偏移“ 的方式去寻址到尾了,所以情况的这种核心思路就是见缝插针,即将有用的数据填充到一个都是'\x00'的新地方,然后修改索引这些数据的指针指向这个新的地址
其次就是靠合并,比如将DOS头和NT头合二为一;以及将数据节和代码节合二为一,这样能省下一个节表的空间....
PE文件手工压缩的更多相关文章
- 手写PE文件(二)
[文章标题]: 纯手工编写的PE可执行程序 [文章作者]: Kinney [作者邮箱]: mohen_ng@sina.cn [下载地址]: 自己搜索下载 [使用工具]: C32 [操作平台]: win ...
- 打造XP下可运行的微型PE文件
前几天和朋友交流技术,提到手工打造微型PE文件,他说现在网上流传的大部分版本在XP SP3下都不能运行,于是心血来潮,拍着胸脯说:“你放心,忙完了帮你做一个.”后来花了半天时间,终于打造出一个XP下可 ...
- PE文件详解(八)
本文转载自小甲鱼PE文件详解系列教程原文传送门 当应用程序需要调用DLL中的函数时,会由系统将DLL中的函数映射到程序的虚拟内存中,dll中本身没有自己的栈,它是借用的应用程序的栈,这样当dll中出现 ...
- 【黑客免杀攻防】读书笔记6 - PE文件知识在免杀中的应用
0x1 PE文件与免杀思路 基于PE文件结构知识的免杀技术主要用于对抗启发式扫描. 通过修改PE文件中的一些关键点来达到欺骗反病毒软件的目的. 修改区段名 1.1 移动PE文件头位置免杀 工具:PeC ...
- 向PE文件中空白处添加代码
// mem.cpp : 定义控制台应用程序的入口点. //PE文件从文件加载到内存,再从内存读取,然后存盘到文件 #include "stdafx.h" #include < ...
- PE文件从文件加载到内存,再从内存读取,然后存盘到文件
// mem.cpp : 定义控制台应用程序的入口点. //PE文件从文件加载到内存,再从内存读取,然后存盘到文件 #include "stdafx.h" #include < ...
- 【C#公共帮助类】WinRarHelper帮助类,实现文件或文件夹压缩和解压,实战干货
关于本文档的说明 本文档使用WinRAR方式来进行简单的压缩和解压动作,纯干货,实际项目这种压缩方式用的少一点,一般我会使用第三方的压缩dll来实现,就如同我上一个压缩类博客,压缩的是zip文件htt ...
- 获取pe文件的文件类型
工程文件petype.cpp通过调用pefile类中的函数获取文件类型. 文件类型的判断通过5个监测点完成. 监测点1:dos头的e_magic 监测点2:nt头的Signature 监测点3:文件头 ...
- 浅析MSIL中间语言——PE文件结构篇
一.开篇 开篇我想讲一下于本文无关的话题,其实我很想美化一下自己博客园一直没时间弄,无意间找了博客园李宝亨的博客园里面有一篇分享自己主题的文章,我就将这个模板暂时用作我的blog主题,我要讲述一个关于 ...
- C#文件或文件夹压缩和解压方法(通过ICSharpCode.SharpZipLib.dll)
我在网上收集一下文件的压缩和解压的方法,是通过ICSharpCode.SharpZipLib.dll 来实现的 一.介绍的目录 第一步:下载压缩和解压的 ICSharpCode.SharpZipLib ...
随机推荐
- 使用.NET Core实现不同服务器SQL Server 数据库同步方案
代码片段: 1 using DataSync.Core; 2 using Furion.Logging.Extensions; 3 using Microsoft.Data.SqlClient; 4 ...
- [zookeeper] 集群搭建及启动后查询服务器状态异常解决
一.集群搭建 1.每台服务器上部署zookeeper 1.将zookeeper压缩包解压到指定位置,在zookeeper解压后目录下创建数据目录zkData 2.在zkData下创建myid文件,内容 ...
- ubuntu系统单网卡配置多网段IP
环境 系统版本:Ubuntu 16.04.5 LTS 配置 ubuntu系统网卡文件是interfaces,修改网卡配置文件vim /etc/network/interfaces添加2个IP地址: a ...
- Postgresql-数据库无法停止,报错:pg_ctl server does not shut down
根据您的查询,pg_ctl server does not shut down(pg_ctl服务无法关闭)的原因可能有很多.以下是一些可能的解决方案和代码示例: (1)杀死所有与PostgreSQL相 ...
- 【译】发布 .NET Aspire 预览版 2(二)
原文 | Damian Edwards 翻译 | 郑子铭 组件更新 组件包现在有单独的图标 大多数 Aspire 组件的 NuGet 包现在都具有代表性图标,以便在 NuGet 包管理器对话框中更轻松 ...
- 开源.NetCore通用工具库Xmtool使用连载 - 散列算法篇
[Github源码] <上一篇>详细介绍了Xmtool工具库中的加解密类库,今天我们继续为大家介绍其中的散列算法类库. 散列算法在某些特殊场景也可以当做加密方法使用:其特点是不可逆,同一内 ...
- Iot学习笔记记录
前言 2024.1.13 沙青图书馆 甚至一开始打成了2023年.各位新年快乐.有时间会写下2023的年度总结.不过在此要提前开一个博客,记录一下接下来学习Iot安全的记录了.实在是再不学就要被学弟学 ...
- 内核5.4以上, Realtek 8111网卡初始化失败
在Centos7中, 升级内核到5.4.x或5.11.x时, 都会出现realtek8111网卡无法启动的问题, 在dmesg中能看到这个错误 $ dmesg |grep -i r8169 ... r ...
- 【Unity3D】GUI控件
1 前言 Unity 3D 提供了 GUI.NGUI.UGUI 等图形系统,以增强玩家与游戏的交互性.GUI 在编译时不能可视化,在运行时才能可视化.GUI 代码需要在 OnGUI 函数中调用才能 ...
- React虚拟DOM的理解
React虚拟DOM的理解 Virtual DOM是一棵以JavaScript对象作为基础的树,每一个节点可以将其称为VNode,用对象属性来描述节点,实际上它是一层对真实DOM的抽象,最终可以通过渲 ...