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 ...
随机推荐
- 11.1 C++ STL 应用字典与列表
C++ STL 标准模板库提供了丰富的容器和算法,这些模板可以灵活组合使用,以满足不同场景下的需求.本章内容将对前面学习的知识进行总结,并重点讲解如何灵活使用STL中的vector和map容器,以及如 ...
- 《重学Java设计模式》作者开始录视频了!
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 1. 前言 哈哈哈,终于对B站下手了! 大家好,我是小傅哥,在紧张.羞涩到适应后,哈哈哈,终于 ...
- 关于TypeScript中提示xxx is declared but its value is never read的解决方法
首先,提示很明显,是定义了变量,但是却没有使用.解决方案有如下两种: 一: 需要确定变量是否真的没有使用到,如果没有使用直接删除即可. 二: 对于方法中的入参,是没法随便删除的.这时候我们可以利用Ty ...
- 使用DoraCloud免费版搭建办公桌面云
DoraCloud是一款多平台的桌面虚拟化管理软件,支持Hyper-V.VMware.Proxmox.XenServer等多种虚拟化平台.DoraCloud在虚拟化平台上具有极大的灵活性,允许您的组织 ...
- 关于ASP.NET WEB API(OWIN WEBAPI)的几个编码最佳实践总结
近期工作比较忙,确实没太多精力与时间写博文,博文写得少,但并不代表没有研究与总结,也不会停止我继续分享的节奏,最多有可能发博文间隔时间稍长一点.废话不多说,直接上干货,虽不是主流的ASP.NET CO ...
- [Ngbatis源码学习][SpringBoot] ApplicationContextInitializer接口类的使用和原理解读
ApplicationContextInitializer接口类的使用和原理解读 在看Ngbatis源码的过程中,看到了自定义的ApplicationContextInitializer实现类,对Ap ...
- CF1829H Don't Blame Me
题目链接 题解 知识点:线性dp,位运算. 考虑设 \(f_{i,j}\) 表示考虑了前 \(i\) 个数字,与和为 \(j\) 的方案数.转移方程显然. 注意初值为 \(f_{0,63} = 1\) ...
- NC23482 小A的最短路
题目链接 题目 题目描述 小A这次来到一个景区去旅游,景区里面有N个景点,景点之间有N-1条路径.小A从当前的一个景点移动到下一个景点需要消耗一点的体力值.但是景区里面有两个景点比较特殊,它们之间是可 ...
- NC14685 加边的无向图
题目链接 题目 题目描述 给你一个 n 个点,m 条边的无向图,求至少要在这个的基础上加多少条无向边使得任意两个点可达~ 输入描述 第一行两个正整数 n 和 m . 接下来的m行中,每行两个正整数 i ...
- Linux查看系统版本的方法
记录几种查看当前Linux系统的版本的方法 一.使用命令:cat /proc/version 查看 linux版本号:Linux version 5.4.0-99-generic (buildd@lg ...