UPack 压缩PE头文件分析(特点总结)

UPack 头文件分析(特点总结)

概述

UPack是用来将pe文件压缩成很不规则形式的压缩器,书上说是国人编写的,牛。

压缩方法

在终端输入指令

upack notepad.exe

在这里插入图片描述
压缩后不会生成新文件,压缩的是其本身,所以做好备份
此时peview已经看不到很多东西了:
在这里插入图片描述

PE文件头部分的特征

表现特征

1.开头的MZ和PE签名离得太近了

1.没有dos存根
在这里插入图片描述

3.出现很多字符串和代码

4.等等等

具体改变

重叠文件头

将MZ文件头(IMAGE_DOS_HEADER)和PE文件头(IMAGE_NT_HEADER) 重叠在一起

{节约空间增加代码,提高复杂性}

具体

PE规定NT头的起始位置是可变的,由e_flanew决定,下面是MZ和e_flanew

在这里插入图片描述

一般情况下e_flanew有以下值:

在这里插入图片描述

UPack将其改为10
在这里插入图片描述

达到重叠的效果。

修改文件头(IMAGE_FILE_HEADER)中可选头(IMAGE_OPTIONAL_HEADER)的长度(E0)

原理(创造空间,插入代码)

UPack将其改为148(E0->148), 这样做可以向文件头插入解码代码

在这里插入图片描述

经过这样的改动 , (IMAGE_OPTIONAL_HEADER)和(IMAGE_SECTION_HEADER)之间就添加了一段额外的空间

原因

1.PE规定 IMAGE_OPTIONAL_HEADER的大小(sizeof…) 是要另外输入的

(为了可以插入不同形态的IMAGE_OPTIONAL_HEADER结构体,而不同形态的他们之间大小也不同

2.IMAGE_SECTION_HEADER 并不是紧跟在IMAGE_OPTIONAL_HEADER 结构体后面的,而应该 在IMAGE_OPTIONAL_HEADER加上SizeOfOptionalHeader的地址后的位置

3.根据2便可以知道,将E0修改为148(>E0)会在 IMAGE_OPTIONAL_HEADER 和 IMAGE_SECTION_HEADER之间多出来一大块额外空间。

查看插入的代码

先看 IMAGE_OPTIONAL_HEADER 的结束位置

在这里插入图片描述

在D7附近

在stud_PE查看D7~170(节区起始位置)

在这里插入图片描述

再放入od中看一下这段地址的代码

在这里插入图片描述

之所以pe查看程序会出错,是因为将上面的解码代码错误的识别为PE文件头信息。

修改可选头中的NumberOfRvaAndSize

NumberOfRvaAndSize

是用来指出后面的IMAGE_DATA_DERICTOR结构体的元素数量
在这里插入图片描述

具体修改

NumberOfRvaAndSize 的改变也是为了在文件头中插入自身代码

原本的值是10

在这里插入图片描述

修改后为A

在这里插入图片描述

所以它的后6个元素就可以自由使用,添加代码了

88~ D7是data directory数组,剩下的蓝色部分是自由添加的代码(D8~107

在这里插入图片描述

在od中同样可以看到解码代码

在这里插入图片描述

IMAGE_SECTION_HEADER的空间利用

节区中有很多不会影响程序正常运行的区域

在这里插入图片描述

上图为IMAGE_SECTION_HEADER,方框内的区域便不会影响正常运行

重叠节区

在这里插入图片描述

看一下节区头,发现 第一节区和第三节区的大小和文件偏移地址是一样的 ,内存的起始RVA和内存大小是不一样的

正常情况下,PE装载器会把文件分别映射到3个不同的内存位置(文件头、第一节区、第三节区)。就是说用相同的文件可以分别创建出处于不同位置的、大小不同的内存映像。

因此,可以理解为,在文件中,第二个节区很大,文件就压缩存储在这里,在程序运行的时候,PE装载器会对文件进行解压缩并且进行内存的映射,将文件还原到第一个节区。(原来的文件有三个节区,都被解压到第一个节区)。
在这里插入图片描述

所以说,压缩的notepad在内存的第二节区,解压缩时被记录到第一节区。

并且原文件的 内存映像 会被整体解压,所以程序能正常运行。

RVA to RAW的特征

UPack的 FileAlignment 的值是200,所以PointerOfRawData 会被转换为200的整数倍,不足200的为0。

此文件的EP值是1018
在这里插入图片描述

根据rva to raw的转换

在这里插入图片描述

计算出压缩后的EP为:28

在这里插入图片描述

由于 PointerOfRawData 会被转换为200的整数倍 ,所以上面的计算是错误的,PointerOfRawData 的值应该是0

所以EP正确的Raw值是18.

在od中查看

在这里插入图片描述

IMAGE_IMPORT_DESCRIPTOR array(导入表)的特征

导入表是 一系列 IMAGE_IMPORT_DESCRIPTOR 结构体组成的数组

在这里插入图片描述

而且该数组(导入表)的 结尾必须是一个NULL结构体

原理

利用文件内容映射到内存时, 只映射文件结束地址前的内容 ,所以映射到内存中的节区结尾部分(如下图内存27200后的节区)永远被NULL填充,符合

结尾必须是一个NULL结构体

的要求,所以程序可以正常运行。

在这里插入图片描述

IAT(导入地址表,从dll额外导入了哪些API?)

导入表(经RVA to RAW转换后得到的地址1EE):

在这里插入图片描述

在这里插入图片描述

通过上面两图进行对应的映射后,得到结构体重要成员的信息:

在这里插入图片描述

因为header区域中RVA 和 RAW 值相等

所以在hxd看
在这里插入图片描述

它占用了原本不使用的DOS头区域(好节省)

所以知道了dll的名称,看看从中导入了哪些API函数

将IAT的RVA(11E8,一节区) 转化成RAW: 1E8 (一节区的RawOffset被强制换成0)

IAT(文件偏移):

在这里插入图片描述

其中记录着28 和 BE 两个地址值:

由于header区域rva和raw相同,所以看一下28 和 BE
在这里插入图片描述

在这里插入图片描述

可以看到导入的两个API:

LoadLibraryA
GetProcAddress
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zsc_02

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值