首页
社区
课程
招聘
[原创]学写压缩壳心得系列之二 掌握PE结构 ,曲径通幽
发表于: 2012-2-5 17:41 16767

[原创]学写压缩壳心得系列之二 掌握PE结构 ,曲径通幽

2012-2-5 17:41
16767

1.数据与指令,以及加载前期相关概念(已完成)
2.pe文件的结构解析(已完成)
3.pe文件load的过程(已完成)
4.壳的处理(已完成)

PE文件中的结构众多,但是其实,这些结构一多半是告诉loader怎么去加载自身PE的。正常的PE文件总是很严格去填充自身的内部结构,但是也有一小部分变形PE文件没有那么的中规中矩,所以PE结构中有的信息到了loader可能最终也只是起到了一个校验作用。在纵观PE整个大结构的时候,不应该去拘泥于每一个数据结构的特征,应该从大体上去把握它。本文试图通过loader加载方式的类比和举例的角度,介绍了loader是如何讲PE结构中相关重要数据进行加载的。因为介绍PE的优秀文章有很多加上作者水平很有限,如果有错误,请各位指正。

下面,就开始逐一的介绍相关重要的结构:
1.各种表头
  1.1 Dos表头
  1.2 pe文件头
  1.3 区块表头
2.导入表
3.导出表
4.重定位表
5.资源
6.附加数据


1.表头

一共包含了有三个类型的表头,一个是Dos表头,目的是为了兼容以前的平台。一个是pe文件头,包含了pe自身加载的各个配置信息,还有一个就是区块表头,包含pe文件各个区块的信息。整个表头,就给loader提供了一个这样的信息:“这个PE是什么属性,整个PE如何在内存分布的,又会被加载到哪里去“。

1.1 Dos表头
为了兼容以前的DOS平台,MS在设计的PE格式的时候考虑到了MS-DOS头部。其中有一个结构是MZ值,也就是相对偏移00处。在壳程序判断是否是PE文件的时候,这个是条件之一。另一个条件就是距离偏移0X3Ch处。这里保存了一个地址,这个地址指向了(PE header)PE文件头。这个才是装载器开始装载真正意义上的PE开始的地方。在相对于PE header偏移0h的地方,保存着一个“PE”标识。

根据上面两个信息,我们就可以判断被加壳的文件是否为PE文件了。

1.2 pe文件头
PE标识的下面一个偏移,就是FILE_HEADER了,它被称之为PE头,其中相对FILE_HEADER偏移0x06h的NumberOfSections表示的是文件的块数目。0x14h偏移处的SizeOfOptionalHeader表示的是可选头的大小,这个值可以用来定位节表可选头OptionalHeader的大小。

PE头0x18h偏移处就是OptionalHeader了。OptionalHeader是PE中相对重要的结构。虽然译做可选头,但是里面的很多选项都是必选的。

其中以下的结构是比较重要的:

AddressOfEntryPoint
指出文件载入内存后,代码开始执行的地方,也就是我们常说的OEP。例如我们对文件进行加壳之后,原来的入口点保存后,修改其中的值,指向外壳代码,使加壳的后PE能够先进行解压,再跳到原始的入口点继续运行。

ImageBase
指出文件的优先装入地址。Loader优先将文件装入到由ImageBase字段指定的地址中,若指定地址装载失效,才被装入到其他地址中。
EXE文件通常即指定,即装载,所以EXE总是能够按照这个地址装入。因为ms为每一个exe文件设定了单独的4GB进程空间,对于装载来说,exe的地位是优先的,所以总能够保证其装载ImageBase成功。
而DLL文件来说,不能保证优先装入地址没有被其他的DLL使用,因为一个exe可以装载不同的dll到其地址空间去,所以DLL通常含有重定位信息来进行二次定位,即该地址若被占用,调用重定位表的偏移,重新定位。

SectionAlignmentFileAlignment
这里即是内存对齐粒度和文件对齐粒度,参见第一篇的阐述。

DataDirectory
数据表它由16个相同的IMAGE_DATA_DIRECTORY结构组成,因为PE文件中有很多的表块,例如导入表,导出表,重定位表等等,这样就需要有一个结构,保存着这些表的相关信息,来告诉Loader去加载哪里并且如何加载这些表。IMAGE_DATA_DIRECTORY结构指出了某种数据表的位置和长度。

1.3 区块表头
紧跟在IMAGE_NT_HEADERS后面的是区块表。在未载入这个块表信息之前Loader只知道根据前面提供的NumberOfSections,知道有多少个块,可是块的大小,块的各个偏移和名称却不知道,所以有一个结构来告诉Loader。这样loader就可以按照载入的规则将所以的块信息放入内存了。

注意:在进行区块装载的时候,有可能被装载的PE是个变形文件,所以,当其结构提供的数据代码和loader装载规律不一致的时候,就要按照loader对齐粒度来进行装载了。

那么如何读取了,首先要定位到各个头的起始位置(参见前面介绍的判断是否是PE文件中的方法定位),因为偏移是固定的,只需移动的固定的偏移读取即可。

至此,头表的重要结构都介绍完毕了,我们发现,这些结构都是按照固定偏移寻址读取的,告诉loader怎么去装载PE文件的,从宏观上,大致的表述了一个PE文件粗枝大叶的部分。可以说,这就如同之前所形容的那样,loader只是将这些作为数据来对待,进行读取,然后和自身的装载规则作比较。

下面就来介绍PE中比较重要的几个区块:
2.导入表
  Exe要用到外部DLL提供函数,在装载的时候,loader需要将各个函数的地址分配过去。在生成exe的时候,连接器为了统一一种形式将所有的调用函数统一成call [xxxxxxxx]的形式,而这个地址一开始会被PE文件预留,只有当要被加载的时候,loader进行填充真正的函数地址到xxxxxxxx地址处。

例如某一处的代码:

00401000  CALL  [[COLOR="Red"]00404000[/COLOR]]
 Dword OriginalFirstThunk //输入名称表结构 IMAGE_THUNK_DATA ->指向 IMAGE_IMPORT_BY_NAME
  Dword TimeDateStamp 
  Dword ForwarderChain 
  Dword Name1             //DLL名字指针
  Dword FirstThunk        //输入地址表结构 IMAGE_THUNK_DATA ->指向 IMAGE_IMPORT_BY_NAME

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 6
支持
分享
最新回复 (28)
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
这么详细
太好了
2012-2-5 17:51
0
雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
呵呵呵,看标题吸引进来的。。顶
2012-2-5 18:08
0
雪    币: 195
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
请问,sys文件可以压缩的更小吗?
2012-2-5 18:14
0
雪    币: 1163
活跃值: (137)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
5
期待楼主后续文章
2012-2-5 19:11
0
雪    币: 967
活跃值: (1138)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
6
个人觉得这样搞没有任何意义
(你可以说和我没有关系)
真想学好
哪怕慢点
但是不得不说 写壳吧
哪怕壳很简单
2012-2-5 22:06
0
雪    币: 223
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
顶 顶 顶 顶 顶 顶
2012-2-5 22:15
0
雪    币: 408
活跃值: (156)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
8
呵呵,这是我学习PE格式的一些心得体会和记录,所以发上来了:)
没有明白前辈的意思,看前辈以前的发的帖子,原来也对写壳颇有心得,可否指点一下小菜呀。
2012-2-5 23:29
0
雪    币: 408
活跃值: (156)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
9
SyS文件也是属于PE格式的范畴,记得论坛上有写可以压缩sys的帖子:)
2012-2-5 23:38
0
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
图文并茂,很不错
可能是因为基础的原因吧,还是不怎么懂

能不能弄个视频教程啊

谢谢啦
2012-2-6 00:36
0
雪    币: 76
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
本来我自认为对pe结构很熟悉的,结果读了这篇帖子却糊涂了
2012-2-6 09:41
0
雪    币: 408
活跃值: (156)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
12
我也是一个菜鸟,水平有限,不足之处希望和你多多交流 :)
2012-2-6 10:03
0
雪    币: 220
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
嗯 挺细 顶一下
2012-2-7 15:15
0
雪    币: 1708
活跃值: (586)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝
14
学习....
2012-2-7 15:20
0
雪    币: 231
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
学习了,讲解的很详细。
2012-2-7 15:22
0
雪    币: 321
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
很好的文章 谢谢
2012-2-7 16:36
0
雪    币: 1737
活跃值: (110)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
又有写壳的啊~~ 佩服~~
2012-2-8 09:32
0
雪    币: 184
活跃值: (56)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
马克~~~谢谢楼主分享
2012-2-8 21:41
0
雪    币: 243
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
不错,特别是曲径通幽四个字很有点别的意思。。。
2012-2-9 01:02
0
雪    币: 240
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
有的程序的附加数据是正常运行时需要的,loader不载入运行会报错
2012-2-11 09:56
0
雪    币: 130
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
mark一下
2012-2-13 13:11
0
雪    币: 442
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
好文章..........
2012-2-13 13:13
0
雪    币: 210
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
非常好,这么详细实用,顶!
2012-2-15 17:39
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
确实看的不怎么懂,也许火候不到.
2012-3-5 15:52
0
雪    币: 210
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
写得非常好,值得我们学习
2012-3-18 20:02
0
游客
登录 | 注册 方可回帖
返回
//