首页
社区
课程
招聘
[原创]菜鸟啄硬壳(之二)――玩转PE文件头
发表于: 2007-1-21 13:13 15576

[原创]菜鸟啄硬壳(之二)――玩转PE文件头

wulje 活跃值
14
2007-1-21 13:13
15576

[摘要]        最后一个块表必须同时满足三个不等式:
        1)“内存地址+对齐尺寸<=填装载后尺寸”
        2)“对齐尺寸+文件地址<=文件的实际长度”
        3)“实际尺寸+内存地址>=文件的实际长度”
[正文]
        我的上篇文章提到的Keygen.exe的那个壳,把PE头搞得个七零八落,程序居然运行得十分舒畅,我突然觉得PE头可能就像一个报关单或银行存款报单等什么的,虽然项目繁多,但可填可不填的占多数。姓名、金额必填,但存一千,填一万也是过不了的。无法否定比尔.盖茨不是受到它的启发?
        我说这些看是“废话”的东西,未必不含有哲理。PE头长期来被初学者奉若神明,十分小心地呵护它的每个字节,思维被它束缚得紧紧的,虽然它是学习的必然,但长期跳不出它的束缚未必是好事?好了,“废话”再说下去,你们也会拂袖而去。话归主题。下面我把对PE头的一些数据的实验结果报告如下,因谁也没有XP的源代码,无法证明其结论一定正确,甚至根本就是错的?请高手辅正。
        一、竟然栽倒在自己的“警示”之中
        上篇文章《菜鸟啄硬壳―我的脱壳手记》提到的脱壳后的dump.exe,运行都很正常,就是不能用eXeScope对资源进行编辑。当时我丢下一句话:它可能对资源加密了,我争取下次将它解密。我当然希望能在网友面前将它解密?^_^。找来几个有名的Resource Tool,如Resource Hacker,FreeRes和eXeScope,个个都说没办法!怪了,这个壳会这么深奥?下来后我只好硬着头皮去肯“资源结构”,从头到尾花了大半天的功夫,对比dump.exe资源竟然没有发现它有任何异样(最大收获是发现keygen壳的压缩比没有解压前后尺寸比那么大,脱壳后的dump.exe中垃圾占了1/3),为什么运行中windows不觉得dump.exe没有什么不对,而eXeScope.exe却认为它的结构不能识别?百思不得其解。难道eXeScope权限高于windows?这不叫人笑掉大牙?忙找来几个eXeScope可以识别和不能识别的软件比照一下才真相大白,原来赫赫有名的eXeScope等居然也没有跳出PE头的思维束缚!!它对资源的识别只认“.rsrc”这几个字符(注意:不是认IMAGE_DATA_DIRECTORY结构,更不是认数据目录中的IMAGE_DIRECTORY_ENTRY_RESOURCE),那怕是在.rsrc后加个a字符它都不认!忙把dump的第二个节表添上“.rsrc”字样(在0000012C处),咳,它认了(苦笑!)!想不通我曾经鼎礼膜拜的工具竟然也犯这样低级的错误!唉,我不止一次地提醒不要迷信这些工具软件,结果我竟然栽倒在自己的“警示”之下!原来,keygen的脱壳已经很完整了,只是原软件作者故意把PE头搞得乱七八糟,在windows允许通过的情况下欺骗了不少软件。
        二、PE头中的关键数据
        1.对NumberOfSections(偏移=06h)和SizeOfImage(偏移=50h)数据的认识:
        PE文件头中的IMAGE_NT_HEADERS数据结构看了头都大了,要弄清楚每个数据的作用实在是强人所难,有必要么?谁写软件是这样一个个数据填写出来的么?我看有“刨根癖”的我等也不要无事找事!到是该注意这些结构的数据成员,不用则罢,用了就必须在规定的地址填写,这点windows是寸步不让的。
        其中NumberOfSections(偏移=06h)块数目和SizeOfImage(偏移=50h)装载后尺寸到是要小心修改,否则给你一个“不是有效的win32文件”的脸色!后面再说。
        2.块表(IMAGE_SECTION_HEADER)数据中的秘密:
        上篇文章中提到kengen脱壳前PE头中没有一个块表的名称,只有简单的几个数据。脱壳后OD自作聪明地加上了名为“.irdata2”的区块表。就因为块表中没有“.rsrc”名称,令一大堆Resource软件束手无策!打开.irdata2指向的数据一看,完全傻眼了,它是一堆垃圾。脱壳后的dump从0001CD14起以后的部分完全是脱壳后的垃圾,或者叫碎壳更准确。连垃圾代码都可以在windows中自由通行,那么windows就远不想象那么严密不可侵犯了。
        (1)块表中的三个不等式;
        1)显然所有块名称都可以省去!
        2)各块表的内存地址和文件地址数据必须准确,而文件的实际尺寸和对齐尺寸则可以在一个相当的范围内变化,甚至对齐尺寸可以为0。如果乱填的数据超过了windows的忍耐范围,它就会要么不作声的退出,要么就来个发送错误的报告,当最后一个块表的数据严重违规时,又会给你不是有效的win32文件的脸色。具体规律也没弄清楚。例如,把某程序的最后一个块表的数据按实际顺序排列如下:
------------------------------------------------------------------------------------------
块名称                实际尺寸        内存地址        对齐尺寸        文件地址          属性
……                 22A30                  4000                 22C00                  1400                C00000E0
------------------------------------------------------------------------------------------
        3)最后一个块表必须同时满足下列三条:
        “内存地址+对齐尺寸<=填装载后尺寸”,即PE头中SizeOfImage的数据;
        “对齐尺寸+文件地址<=文件的实际长度”;即磁盘文件最后一个字节地址+1的长度;
        “实际尺寸+内存地址>=文件的实际长度”。
        这些结论(无法证实是否100%准确),对喜欢DIY软件的Player来说无疑很有用。很多脱壳后的软件最后都有很多0或无用字节,你一删除就得到警告,这就是破坏了上面的条件。其实磁盘文件可以在任意字节上结束,其长度并不是按200对齐规则的。
        (2)添加、删除或合并块表;
        如果一个文件是“无缝”装载(即磁盘文件除第1块外,各块内容块已经按1000对齐了,装载后不会再在各内容块间插入零字节了),几乎所有的脱壳文件都是无缝装载(不知是不是绝对如此?)。那么这样的程序文件块可以简单地合并。只须修改要合并或删除块表的前面那个块表的“对齐尺寸”和“实际尺寸”使之满足上述条件即可。(将SizeOfImage数据减小也可以,但要相应删除文件的一些无用字节)。以脱壳后的dump.exe为例:
        在.irdata2表(从00000154开始)中找到第5字段=400,即对齐尺寸为400(好笑的是它文件尺寸第3字段=1000,居然文件尺寸>对齐尺寸,可见windows对不紧要的数据是不管的!),现在将前一个无名表的第5字段(0000013C)实际尺寸7000改为7400(这样就满足了三个不等式了),或同时也将对齐尺寸改为7400也是可以的。然后从00000154将后面的块表连同一串垃圾都删除,最后不要忘记将00000012处的块表数(偏移=06h)由3改为2,存盘即可。照这样下去,将所有块表合并成一块也很轻松。只须将实际尺寸和对齐尺寸上下各自对应相加到最前面一个块表中(一定满足三个不等式)就行了。但始终不要忘记对NumberOfSections块数目的修改。
        有了这个规律,你要在喜爱的软件中添加一些块扩展它的功能,这有何难!
        3.对SizeOfHeaders(偏移=54h)数据的认识:
        谁都知道该数据表示“头文件+块表”尺寸。其实它也是一个内容块,只是不包含在后面的块表中。装载时windows始终都要为它留出0―FFF空间,这就是为什么程序总是从401000开始的原因。但是SizeOfHeaders又是一个双字,难道这个特殊块可以长达4G?空想不如实干,马上动手。
        (1)奇想:把所有块内容都放在头文件块中去;
        有了这个想法,就用dump.exe作实验了,将它的块表数设为0,并删去所有的块表,把SizeOfHeaders设为23400(该文件的总长度)。目的是当头文件装载完成后,所有的数据都装载了,没有块表不会有关系吧?嘟的一声,报告说不是有效的win32文件。看来,没有块表windows是不认的。那么就给它添上一个全0字节长度为400的块数据和相应的块表吧,SizeOfHeaders 也应减少400(有了前面的不等式,添加块表易如反掌)。再试,啊~,诺盾急了,首先跳出来说发现了“Bloodhound.w32.EP”病毒!?这真是皇帝不急太监急,关闭吵闹不修的诺盾。运行程序,windows保持沉默,一运行就退出了。结论就这样,再研究下去就有些无聊了!只是不知道诺盾为什么认为它是病毒?
        (2)乾坤大挪移;
        我想文件头的这块地址是一个“避风港”,壳可以把程序设置在里面,我何尝不可以把常用、常要修改的块放在里面呢?马上把dump的资源表(0001C000开始,长度160)拷贝到00000130开始的位置(注意,是拷贝不是插入),并将资源目录表地址指向00000130,资源表则个字不改。运行,成功的。只是未运行时,程序名称前的图标变成了DOS程序的图标,而运行后,标题拦上的图标很正常。我一时也没有找出原因来。
        资源表的成功移动,鼓励我再把IID表和IAT表也挪一挪,这一下得修改表中地址了,虽说RVA=0,但原地址的RVA不为0。修改到也很简单,因为地址是真实值,按实填上就可以了。当然相应的导入表,函数地址表也要改一改。一切就绪后运行,windows报告初始化失败。啊~,PE头块属性是禁止写入的!我怎么就没有想到?怎么众多的书都没有警告过?别乱说,好象罗云彬在书中什么地方提到过,叫我给忘了!
        现在算是初步认识了PE头了。
        谢谢你把本文读完。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (29)
雪    币: 172
活跃值: (212)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
学习了,沙发
2007-1-21 13:16
0
雪    币: 2822
活跃值: (2285)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
学习!!!!!
2007-1-21 13:16
0
雪    币: 70
活跃值: (74)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
其实我觉得学PE最好的办法就是写个PE工具
LZ很认真啊  向你致敬!
2007-1-21 13:30
0
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
5
学PE最好是先把pecoff_v8.doc背了
2007-1-21 14:44
0
雪    币: 898
活跃值: (4039)
能力值: ( LV9,RANK:3410 )
在线值:
发帖
回帖
粉丝
6
鼓励一下
2007-1-21 15:37
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
支持,坚持写下去呀. :)
2007-1-21 17:42
0
雪    币: 263
活跃值: (10)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
8
好,顶一下
2007-1-21 21:29
0
雪    币: 212
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
牛啊!我的牙都啃得差一点掉光了。
2007-1-22 11:26
0
雪    币: 305
活跃值: (10)
能力值: ( LV9,RANK:570 )
在线值:
发帖
回帖
粉丝
10
谢谢几位版主和网友的鼓励、支持!学而后知不足,越深入越觉得没底。记得有个老外预言:20年后,谁也不会知道电脑是怎样在工作的?我想他不会无知乱说。电脑积累了全人类的智慧,个人能向这个智慧结晶挑战吗?
2007-1-22 12:10
0
雪    币: 146
活跃值: (33)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
11
菜鸟学习的经典..
可是还是觉得"婆婆话"多了点,有点累
2007-1-22 13:12
0
雪    币: 264
活跃值: (30)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
12
好文,不支持对不起楼主!!!
2007-1-22 17:25
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
学习!!!!!
2007-3-2 22:47
0
雪    币: 208
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
你写的很好 受教了~
2007-3-3 16:15
0
雪    币: 207
活跃值: (12)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
15
学习中 thanks.
2007-3-5 05:08
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
谢谢楼主的文章。我收藏了
2007-3-26 19:45
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
学习中,顶!!!
2007-3-28 08:37
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
ding!!
2007-3-28 14:09
0
雪    币: 200
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
看了,但是没看懂,汗一个!
2007-4-28 00:55
0
雪    币: 191
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
学习,虽然不知道在说些什么
2007-10-23 14:00
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
支持一下。。。
2007-10-23 15:57
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
学习学习,谢谢
2008-2-2 21:21
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
学习,~~~~~~~~~~~`
2008-2-20 00:11
0
雪    币: 206
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
你写的很好,不支持对不起楼主!!!
2008-6-5 14:20
0
雪    币: 208
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
把我发布的文章看看,和你说的又不太一样哦!希望大家也一起研究一下这个程序的PE格式,绝大部分不符合PE_COFF,却在windows下很好的运行。
请见 http://bbs.pediy.com/showthread.php?t=66053
2008-6-5 22:10
0
游客
登录 | 注册 方可回帖
返回
//