您现在的位置: 晨光科技 >> 文章 >> 技术 >> IT >> 正文  
  PE文件头         
PE文件头
[ 作者:佚名    转贴自:http://hi.baidu.com/xiamenyu/blog/item/d801c6168e543f4221a4e91e.html    点击数:86    更新时间:2010/11/27    文章录入:admin ]
[注:本站登载的某些文章并不代表本站支持或反对其观点或肯定其真实性]

PE文件头(转CVC神奇小子 )

PS:虽然不太清楚作者是谁?不过还是要感谢他!!

摘要]   最后一个块表必须同时满足三个不等式:
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,居然文件尺寸& gt;对齐尺寸,可见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头了。

  • 上一篇文章: 扭曲变换加密 防止软件破解最好方法

  • 下一篇文章: RVA字串乾坤大挪移--偏移量转换器的简单用法
  •    
    [注:标题搜索比内容搜索快]
    发表评论】【告诉好友】【打印此文】【关闭窗口
     最新5篇热点文章
  • 轨道钢承重计算公式及应用[109]

  • 【选型】如何为变频器选取阻值…[86]

  • AIS2023参展厂商名录[346]

  • AGV综合选型[170]

  • APIE 2023第4届亚太国际智能装…[138]

  •  
     最新5篇推荐文章
  • 外媒:正在唤醒中国的习近平[305]

  • 中国反伪科学运动背后的CIA黑手…[494]

  • [转载]袁隆平真言:中国最大的…[668]

  • 台专家:当年我们造IDF时 大陆…[572]

  • 旅日华人:中国严重误判日本民…[577]

  •  
     相 关 文 章
    没有相关文章

      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
        没有任何评论
    设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 管理登录 | 
    版权所有 Copyright© 2003 晨光科技        站长:璀璨星辰        页面执行时间:156.25毫秒
    Powered by:MyPower Ver3.5