avatar

PE

PE结构

PE文件是windows操作系统下使用的可执行文件,PE文件值32位的可执行文件,也称为PE32. 64位的可执行文件称为PE+或PE32+,是PE文件的另一种扩展形式但是并不是PE64.

PE种类

image-20200312210159477

书中的例子用winhex打开notepad.exe文件:

image-20200312210418732

DOS头到节区头是PE的头部分,其他的地方成为PE体,文件中使用的是偏移(offest),内存中使用的VA(虚拟地址)来表示位置,文件加载到内存的时候,情况会发生变化(节区的大小,位置). 文件的内容一般分为代码(.text),数据(.data),资源(.rsrsc)节,分别去保存

PE文件加载到内存中的场景:

image-20200312210825662

VA&RVA

VA是进程虚拟内存的绝对地址,RVA指从某个基准位置开始的相对地址
$$
RVA+ImageBase=VA
$$
PE头内部信息大多以RVA存在,因为当加载到进程虚拟内存的特定位置时,该位置可能已经加载了其他的PE文件. 此时必须通过重定位,将其加载到其他的空白的位置,如果PE头信息使用的是VA,则无法正常访问. 因此使用RVA来定位信息,即使发生了重定位,只要相对的VA - ImageBase 没有发生变化,就能正常访问到指定信息

PE头

DOS头

刚开始创建PE文件格式的时候,人们都很多人在使用DOS文件,所以考虑了PE文件对DOS文件的兼容性. 添加了一个IMAGE_DOS_HEADER结构体

image-20200312224524787

大小为40字节,e_magic:DOS签名即:MZ e_lfanew:值NT头的偏移

image-20200312233110294

如果修改这些值,程序无法正常运行,因为已经不是PE文件了

DOS存根

DOS存根在DOS头的下方,即使没有DOS存根,程序也可以正常的运行。DOS存根由代码与数据混合而成

image-20200313145412903

40到4D区域为16位的汇编指令. 在DOS环境中运行Notepad.exe文件,或者使用debug.exe运行它,因为不认识PE文件格式,所以被识别为DOS EXE文件:

image-20200313153210178

NT头

IMAGE_NT_HEADERS结构体由三个成员组成,第一个成员为签名结构体,其值为50450000h PE00 另外两个为File Header文件头 和 Optional Header 可选头

image-20200313153538346

IMAGE_NT_HEADERS结构体的大小为F8

NT:文件头

1.Machine

每个CPU都有唯一的Machine码,兼容32位Intel x86芯片的Machine码为14C

image-20200313153808898

image-20200313153815432

image-20200313154432706

14C为Machine码

2.NumberOfSections

PE文件把代码,数据,资源等依据属性分类到各节区中存储,NumberOfSections代表文件中存在的节区数量,这个值一定要大于0,

3.SizeOfOptionalHeader

IMAGE_NT_HEADER结构体最后一个成员为IMAGE_OPTIONAL_HEADER32结构体,SizeOfOptionalHeader指出结构体的长度

4.Characteristics

该字段用于标识文件的属性,文件是否是可运行的形态,是否为DLL文件等信息,以bit OR形式组合起来

5.TimeDateStamp

这个的改变不影响文件运行 它来记录编译器创建此文件的时间

image-20200313161038494

image-20200313161213848

NT:可选头

IMAGE_OPTIONAL_HEADER32是PE头结构体中最大的

image-20200313161357938

1.Magic

IMAGE_OPTIONAL_HEADER32结构体时,Magic码为10B;为IMAGE_OPTIONAL_HEADER64结构体时,Maigc码为20B

2.AddressofEntryPoint

AddressofEntryPoint持有EP的RVA值,执行代码的其实地址(.text)

3.ImageBase

一般创建好EXE文件后,其ImageBase的值为00400000,DLL文件的ImageBase值为10000000(也可以为指定为其他的值)

4.SectionAlignment,FileAlignment

File Alignment指定了节区在磁盘文件中的最小单位,SectionAlignment则指定了节区在内存中的最小单位(一个文件中,他们值可能相同,也可能不同). 磁盘文件或内存的节区大小必定为他们值的整数倍.

5.SizeOfImage

指定了PE Image在虚拟内存中所占空间的大小

6.SizeOfHeader

PE头的大小,该值也必须时FileAlignment的整数倍

7.Subsystem

用来区分系统驱动文件(.sys)与普通的可执行文件(.exe .dll)image-20200313164919670

8.NumberOfRvaAndSizes

NumberOfRvaAndSizes用来指定DataDirectory(IMAGE_OPTIONAL_HEADER结构体的最后一个成员)数组的个数

9.DataDirectory

image-20200313165722242

WINHEX中查看:

image-20200313165916549

image-20200313170022855

image-20200313170033197

节区头

image-20200313170610783

IMAGE_SECTION_HEADER

image-20200313173446632

image-20200313173457413

image-20200313173524270

image-20200313173554418

节区头数组(3个节区)

image-20200313181332105

image-20200313181351973

RVA to RAW

PE文件加载到内存时,每个节区都要能准确完成内存地址与文件偏移间的映射。RVA to RAW:

(1)查找RVA所在节区 (2)使用公式计算文件偏移
$$
RAW-PointerToRawData=RVA-VirtualAddress
$$

$$
RAW=RVA-VirtualAddress+PointerToRawData
$$

IAT

用来记录程序正在使用那些库中的那些函数

IMAGE_IMPORT_DESCRIPTOR

记录PE文件要导入哪些库文件image-20200313183833456

image-20200313183841610

认识壳

在自然界里,植物用壳来保护种子,动物用壳来保护身体,那么在计算机软件也有专门负责保护软件不被非法修改或者编译的程序。他们附加在原始程序上,通过windows加载器载入内存后,在原始程序前执行,得到控制权,在执行过程中对原始的程序进行解密,还原,还原后把控制权还给原始程序,执行原来的代码。加上外壳之后,原始程序代码在磁盘文件中一般是以加密后的形式存在的,只在执行时在内存中还原。这样不仅可以比较好的防止破解的对文件的非法修改,也可以防止程序被静态反编译。我们把这个叫做壳

压缩壳

不用的外壳的侧重方面不一样,有的侧重加密,比如压缩壳的特点就是减小软件的体积,加密保护不是重点

加密壳

加密壳的种类比较多,不同的壳侧重点也不同,一些壳只保护程序,另一些壳提供额外的功能,例如注册机制,使用次数,时间限制等,加密壳还有一个特点,越有名的加密壳,研究的人越多,被脱壳的可能性就越大

DUMP

windows中一个可执行性程序被执行后,或者其他的数据文件,只要被影射到了某个进程的地址空间就有机会将它dump出来,这种技术到底有何用,举个例子,比如你有一个软件,并且设置了注册机制,而且用过特殊加密措施,比如用UPX,PECompact加密,但是如果在内存中将其给dump出来,所有的加密的壳都化为乌有,软件的保护也就化为乌有

image-20200313192630577

我们用winhex进行一个dump

image-20200313192651083

从PE文件头开始 复制到Winhex

image-20200313202959597

演示一下我们运行起来的时候发现dump出来报错了,我们不运行时候dump出来不会报错,正常停在oep时候不运行,可以直接运行的

当我们一个程序跑起来的时候,pe会拉伸到内存中进行一个对齐,我们主要看一下.data

image-20200313204835679

Virtual Size代表他在内存中的大小 Raw Size代表他在文件中的大小,VirtualSize大于了RawSize说明在内存中拉伸了,那么后面的节需要往后拖

image-20200313205336240

那么我们可以把资源往上拖

image-20200313205657420

image-20200313205704694

可以看到在原来的.rsrc的RVA对应的地方是有数据的,但是现在被后挪了,我们往后找一下

image-20200313205908567

我们去找到原始的AC000处然后把BC000到后面的复制然后把到AC000删除粘贴

image-20200313210217542

我们再保存出来发现就可以运行了

image-20200313211208527

修改Raw Address也可以,把指针指下去就可以

UPX

然后看一下ppt,停在OEP DUMP是最好的,脱壳的流程查壳 寻找OEP 下断点 断下后DUMP 修复输入表,当我们了解了这个本质之后,其实什么壳子都可以拖的

我们来看一下这个结构,这时候用vmp举个例子,改成image-20200322144028323

但他不是upx,upx有个典型的一个特征,如果加了前的节会合并到一起,我们来看一下

如果看一下这个是什么壳子

image-20200313211935651

看一下区段 发现是upx,一般这个节表里的名称可以改的,但是一般软件检测的话,改名字是没用的,upx的特征是前面的节都合在了一起

image-20200313212134076

pushad 把寄存器的值依次压入堆栈,那么我们随便把寄存器的一个下一个硬件访问断点.那么一定会有一个popad进行一个对应把这些值调用回去,esp定律的原理就是保存现场,堆栈平衡

image-20200313212326442

我们f9

image-20200313212435445

upx脱壳一般就是popad之后再走一点就会到oep了

不能随便的搜索popad是不好使的,有很多花指令的

image-20200313220321645

这个就是我们拖下来的,我们将其dump下来,发现执行不了

image-20200313220638290

我们看一下发现没有地址,IAT表需要修复

image-20200313232152971

用了Scylla(臭师傅的工具就是强) 原理就是在没修复的时候,操作系统会键查我们的iat的结构的数据,如果不对就会报错,所以我们要修复

在od切换一下,切换成长整型,地址,给大家看一下整个程序的表都在这里,到后面一大堆0的地方结束,这个工具在作什么呢,就是自动帮我们寻找到iat,只不过我们现在是手动的

image-20200322190134207

VMP

image-20200314115228068

这是加壳后的结构

OD进行分析,直接找GetVersion转过去,然后dump下来

image-20200314115426806

这样的脱壳是有问题,这个并不是什么重定位,而是iat的问题,他在我们电脑里是可以运行的,但是发给别人就会报错,我们跟一下

原来我们的程序是什么样的,他是一个call然后什么version什么的,你会发现vmp加密是这样的,我们跟一下f7走进去,看到了吗,他其实也是调用了GetVersion但是在vmp里他给加密了

然后把脱好的在虚拟机和本机看一下ret的返回地址的那个,大家可以看到在虚拟机里面,这个是直接没有了的,所以当让报错了的,这个被称为什么,称为跨平台,vmp脱壳后无法跨平台,没有办法挂各种的操作系统,我的电脑拖好了你不能用,这就叫跨平台,证明我们的这个vmp里面会有检测,他进行了一些算法的

学脱壳主要看别人的脱壳的脚本

ASPack

ASPack是款Win32可执行文件压缩软件,可压缩Windows 32位可执行文件(.exe)以及库文件(.dll、.ocx),文件压缩比率高达40%~70%

Author: L0x1c
Link: https://l0x1c.github.io/2020/04/26/2020-3-02/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
    微信
  • 支付寶
    支付寶