菜鸟啄硬壳―我的脱壳手记
菜鸟啄硬壳―我的脱壳手记
[摘要] 1.轻松找出脱壳后的OEP。
........2.ESP定律和pushad、popad成对理论都是不对的。
........3.RVA困扰将不复存在,菜鸟也可轻易玩脱壳,只需了解简单地加减400000的原则。[预备知识] 只须对PE文件头结构有初步的了解。
我贴了几篇烂文就有点沾沾自喜起来,闲着没事又打起了“壳”的歪主意。我想找一个短小的“软壳蛋”来小试一下鸡刀,没想挑选到了一个“铁核桃”,差点没把牙齿啃脱。壮着胆子闯下去,咳~!终于出来了,还悟出不少道理来。
秀才耍棍棒,还得要点基本功。“壳”这个东西对菜鸟有些神秘化,主要原因是缺乏对PE文件结构的了解,更对RVA的转换头痛。脱壳之前先将段钢的“加密与解密”或罗云彬的“汇编程序设计”中关于PE文件结构部分读三遍就可以应负了!下面用脱FantaMorph.exe 的注册机Keygen.exe(老外写的)的壳为例,谈点脱壳思路和方法。(Keygen.exe见附件,请高手验证一个该壳是软还是硬?)
一、奇怪的PE头和脱壳的初试牛刀
1.没见过这样的PE头:
先用16进制编辑器打开keygen.exe文件,看看它的PE头,如下:
00400000 4D 5A 00 00 00 00 00 00 00 00 00 00 50 45 00 00 MZ..........PE..
00400010 4C 01 02 00 46 53 47 21 00 00 00 00 00 00 00 00 L .FSG!........
00400020 E0 00 0F 01 0B 01 00 00 00 2C 00 00 00 50 01 00 ? ...,...P .
00400030 00 00 00 00 54 01 00 00 00 10 00 00 0C 00 00 00 ....T ... ......
00400040 00 00 40 00 00 10 00 00 00 02 00 00 04 00 00 00 ..@.. ... .. ...
00400050 00 00 00 00 04 00 00 00 00 00 00 00 00 30 02 00 .... ........0 .
00400060 00 02 00 00 00 00 00 00 02 00 00 00 00 00 10 00 . ...... ..... .
00400070 00 10 00 00 00 00 10 00 00 10 00 00 00 00 00 00 . .... .. ......
00400080 10 00 00 00 00 00 00 00 00 00 00 00 98 23 02 00 ...........? .
00400090 84 00 00 00 00 C0 01 00 14 0D 00 00 00 00 00 00 ?...?. .......
004000A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
004000B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
004000C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
004000D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
004000E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
004000F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00400100 00 00 00 00 00 00 00 00 00 00 00 00 00 B0 01 00 .............?.
00400110 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . ..............
00400120 00 00 00 00 00 00 00 00 E0 00 00 C0 00 00 00 00 ........?.?...
00400130 00 00 00 00 00 70 00 00 00 C0 01 00 19 64 00 00 .....p...?. d..
00400140 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . ..............
00400150 E0 00 00 C0 87 25 DC 23 42 00 61 94 55 A4 B6 80 ?.?%?B.a?ざ?
00400160 FF 13 73 F9 33 C9 FF 13 73 16 33 C0 FF 13 73 1F ?s?? s 3? s
00400170 B6 80 41 B0 10 FF 13 12 C0 73 FA 75 3A AA EB E0 ?A?? 荔?:?
00400180 FF 53 08 02 F6 83 D9 01 75 0E FF 53 04 EB 24 AC ? ??uS ?
00400190 D1 E8 74 2D 13 C9 EB 18 91 48 C1 E0 08 AC FF 53 谚t- 呻 ?拎 ?S
004001A0 04 3B 43 F8 73 0A 80 FC 05 73 06 83 F8 7F 77 02 ;C?.?s ?w
004001B0 41 41 95 8B C5 B6 00 56 8B F7 2B F0 F3 A4 5E EB AA?哦.V?+痼ま
004001C0 9F 5E AD 97 AD 50 FF 53 10 95 8B 07 40 78 F3 75 ???? ?@x篚
004001D0 03 FF 63 0C 50 55 FF 53 14 AB EB EE 33 C9 41 FF ?.PU? ??闪?
004001E0 13 13 C9 FF 13 72 F8 C3 02 D2 75 05 8A 16 46 12 ? r? 阴 ?F
004001F0 D2 C3 4B 45 52 4E 45 4C 33 32 2E 64 6C 6C 00 00 颐KERNEL32.dll..
这是什么PE文件头啊?PE标记怎么跑到第1行上去了?怎么一个区段块都没有?别急,按着标准结构一步步找下去。开始的DOS头标记“MZ”存在,在 DOS的IMAGE_DOS_HEADER结构中,成员e_lfanew(名字不重要,只要知道“偏移”=3Ch就足够了)是指向PE头的。该成员在0+ 3Ch处,值是0C(双字,低位在前),显然PE二字标记该出现在0C位置。果然,但却跑到IMAGE_DOS_HEADER结构中去了。(这是我们以前不敢想的事,也给我们启发:只要MZ字符在,e_ifanew成员在,IMAGE_DOS_HEADER结构中的其它字节都可以任意修改。)
(1)找到PE头后,往下走(要比照到PE头结构表查找),4C01是CPU类型,0200是块数目,2块?这是欺骗比尔.盖茨让他放行的,脱壳后块数目可以会增加很多。46 53 47 21是日期,E0 00是PE头结构大小,这个大小目前好象没人敢动?我想比尔.盖茨把它放在这里是可以改动的,只要相应地增加PE头的尺寸与这个数据相符是可以的?前面DOS文件头和PE文件头交织在一起不就是很好的例证吗?
(2)其它不用多说。重要的是 34h(对PE头的偏移=28h)位置的54 01 00 00是入口地址。60h位置的00 02 00 00是PE头+节表的尺寸,总长度才 200h,程序入口怎么跑到节表里面来了?看来,你只要向比尔.盖茨递交几个确定文件属性和位置的必要数据后,其它懒得管你!
(3)对PE头就先认识到到这里。以后还要回来和它打交道。其实你先可以连入口地址都不必急于去认识,OD一运行就自动停在入口了。
2.何必这样劳神费力,找几个脱壳工具试试?
这话有理,忙找来几个壳识别工具上阵,个个都摇头不认识!更不说脱壳了,这道也是,没准那天我也搞出个什么壳来,这些工具认得过来吗?特别是菜鸟们不要迷信那些工具,大多是为一些特例设计的,当人们不再使用众人皆知壳时,它就没用了。自己动手成长可能还会更快一些。Dump,Dump吧,就用OD自带的 dump插件吧!运行后一试,OD反到问你:OEP定在那里?自动吧,结果令你哭笑不得,OEP居然跑到kernel32.dll中去了。原来它们判断 OEP的方法大概是找jmp最远的地址?记住,凡事都有例外!
3.脱壳的ESP定律、pushad,popad成对的定律有些不灵了:
有些网友总结出脱壳的一些“定律”,如ESP定律、pushad,popad成对等定律。这些经验不能不说可贵,但一旦上升为“定律”,就不得不论证了。写软件就象写小说,谁知道作者怎样编造故事情节?谁说call后的[ebp+4]就一定是返回地址?程序轻易就可以将该值偷换了。不信就看看这个壳。
该程序的解壳代码总长不过9Eh字节,从154~1F1。一开始就是popad:
00400154 8725 DC234200.......xchg dword ptr ds:[4223DC],esp
0040015A 61..................popad
0040015B 94..................xchg eax,esp
0040015C 55..................push ebp
0040015D A4..................movs byte ptr es:[edi],byte ptr ds:[esi]
0040015E B6 80...............mov dh,80
00400160 FF13................call dword ptr ds:[ebx]
00400162 73 F9...............jnb short 0040015D ; 0040015D
00400164 33C9................xor ecx,ecx
00400166 FF13................call dword ptr ds:[ebx]
154 是入口地址,15A就popad,从头到尾找不到pushad。没有pushad那来popad?这不仅仅是事实,而且软件运行得很正常。原来第1句 154将esp指向了内存4223DC,第2句popad将内存4223DC前的8个双字弹到了寄存器中去了,第3句将esp还原!好绝啊!这里 pushad,popad成对理论是没戏了。再看ESP定律,在我的电脑中,开始esp=13FFC4,若用HW 13FFC0设断,大概只能单步单步地走了,你看看接下来的一连串的call [ebx],个个都要入栈出栈,能连续运行吗?ESP定律也不灵了。
二、壳的基本属性和功能
我先声明,我只读过文中开始提到的那两本书,不敢说对壳有深入的了解!而且才开始学脱壳。何况壳是人写的,没准明天有人就在里面添加了什么新花样。
有人说,壳在程序运行前先取得控制权,解壳后才将控制权交给应用程序。我认为过程大概是没错,但说法似乎不太准确。壳其实就是应用程序的一部分,windows将控制权交给应用程序不是在解壳后,而是在解壳前。准确地说,windows将文件读入内存后,首先查找IAT表(导入地址表),若有,就装载相关的API函数地址,再将与程序有关的dll和数据作一些初始化的工作,完了之后就查找入口地址,将eip指向入口后,就将控制权交给了程序。以后控制权的事是属于程序内部的权利之争,windows是不管的。我说这些,不是说我有什么知识,了解这些为后面找到OEP和脱
上一篇: 网络基础 操作系统 编译与体系结构 30题知识点总结
下一篇: ZAP介绍-1
推荐阅读