本帖最后由 ICEY 于 2021-2-3 22:59 编辑
前言:
1、这篇文章不建议纯小白阅读。
2、完全看懂需要 会一些简单的汇编语言、简单的脱壳步骤、一些耐心。
3、壳过时了,但思路和方法并不会过时。最重要的是学习思路。
4、我白,轻喷。
那我们就开始吧!
这个壳,论坛的爱盘上有。
环境:win 10 x64
一、 找OEP
把程序拖入OD后,最先开始的是一个CALL,F7几次后,就可以看到一个pushad。此时用ESP定律,再F7若干次就可以到达OEP了。(最简单的方法)。当然你也可以研究壳到OEP的流程,断在最后一步完成后的位置,然后F7单步到OEP。(刚开始研究时我就是用这种方法,因为对于加密壳,我是默认为用ESP定律是几乎没什么作用的。后来查阅资料才知道原来ESP定律可以秒杀)。
ZP壳到OEP(大致)流程:
申请内存写入API解密代码 --> 往输入表填充重定向地址 --> 写入壳代码(重定向地址里的代码) --> 向输入表中的重定向地址+0(干扰)--> OEP
以上是我稍微研究了一下得出来的结论,有错误的话请多多包含。二、 API调用分析ZProtect 1.4.9.0对于API的加密方式有两种。可是,这两种加密方式几乎没有区别,解密的时候都是调用同一个CALL的,也就是不同API的解密密钥不一样的。流程如图: 可以发现所以不管它的加密方式是什么,它总要得到真实的API,我们就瞄输出结果这里,就可以得到真实的API了。 如图:
知道了这个,我们就手动跟一次。我们先到OEP。然后用输入表的第一个重定向位置做例子。(分析我在图中写出来了)注意看地址,不然不知道顺序。
Ctrl + G 输入5845F4 回车,然后右键,设置此处为新EIP。
我们继续跟:
继续
进CALL
这一段就是解密API了。此时我已经跟到了输出结果了,可以知道结果先放进了EAX。
出call后
以上就是 壳 完整的一次api调用。
如果你要彻底弄清楚 从密钥换算成API真实入口的算法。你还要分析一个CALL。
但是这一步可以,但没必要,我们要的只是修复IAT并脱壳,并不需要知道它怎么换算。但是为了满足一些同学的好奇心。我也稍微追了一下这个CALL,以下是我的结论。这个结论并不通用,因为不同的加壳姿势会产生不同的密钥、换算参数。但是换算公式应该是相同的。(我只是把关键的变化步骤展示出来)
[Asm] 纯文本查看 复制代码 00030334 F7D9 neg ecx ; 密钥一次变化[/align]0003007C 81F1 05760C09 xor ecx,0x90C7605 ; 密钥二次变化
ecx放入edx
00030320 81C2 0353E037 add edx,0x37E05303 ; 密钥三次变化。
00030420 8D92 8F537D24 lea edx,dword ptr ds:[edx+0x247D538F] ; 密钥四次变化
0003045C F7DA neg edx ; 5
000303C1 81C2 1768082D add edx,0x2D086817 ; 6
edx放入edi
00030357 81F7 30755410 xor edi,0x10547530 ; 7
000304AF 8DBF AC1C5047 lea edi,dword ptr ds:[edi+0x47501CAC] ; 8
0003011B 81F7 C858CC24 xor edi,0x24CC58C8 ; 9
00030401 81EF A14BFC4A sub edi,0x4AFC4BA1 ; 10
edi放入eax
出call
三、 IAT修复。
准备工作:1.到达OEP(并记录地址) 2.知道IAT的头部和尾部(写脚本要用)
前面我们得到了解密CALL的具体流程。我们投机取巧,将API的解密代码复制下来,用作我们写修复脚本用。上面我们讲到,获得真实的API地址会放到EAX。我们就利用这个函数,但我们不能直接用,我们要复制粘贴一个相同作用的call,然后稍微改动一下。。
开始: 到达OEP后,用上面的方法到重定向地址找解密代码段,然后做一些小改动(如图),并以二进制的方式复制下来。找个笔记本粘贴上去,等下要用到。
改一个JMP,然后结果入栈那一行nop掉。
然后利用StrongOD分配一段内存,用作写脚本。没错,我们要用汇编语言写脚本。看图(记得注意地址和注释):开头点: 我猜你们会有疑问,为什么push [edx+0x1]是压入密钥。 因为重定向地址的第一行就是 push 0x密钥。 而push就只有一个字节 68 。 push [重定向地址+1]刚好是压入密钥了。
结束点
刚刚复制的魔改版解密call,二进制形式粘贴下来
二次判断点:
注意:上面说过解密API的代码是一开始申请内存再写入的。但每一次申请的内存地址都是不一样的。所以脚本中的魔改版解密代码 这一段,每次重载程序到OEP后,都要你自己去找原代码复制粘贴。
例如: 红框框框起来的数据,每次重载程序后都不一样。 所以这壳要一次脱好,重载程序就要重新收集数据。
做好上面的步骤后,将EIP更改到pushad那一行。(记得在还原寄存器那一行popad下一个断点。不然程序直接跑飞触发异常结束了。)
我们先试试我们写的脚本。 每一次循环,就修复一个API
那我们就直接F9,一会就断在POPAD那一行了。此时看看IAT,它已经修复好了最后一个被重定向的API。 popad后,刚到OEP时的寄存器就恢复了。我们回到OEP那一行,右键 此处为新EIP。
这里我提供一下我写的脚本。(脚本并不是拿来就能用的,上面有说,脚本中有一段解密代码是要你们自己去复制,然后修改我的脚本后,才能用。)
[Asm] 纯文本查看 复制代码 60 9C 33 C0 33 C9 33 D2 BB 00 10 48 00 8B 13 83 FA 00 0F 84 27 02 00 00 FF 72 01 E8 67 01 00 00
89 03 83 C3 04 81 FB 94 16 48 00 77 17 90 90 90 90 EB DA 90 90 90 90 90 90 90 00 00 00 00 00 00
90 90 90 90 9D 61 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90 90 90 90 90 90
90 90 90 90 90 90 90 A1 44 66 4B 02 80 78 34 00 74 57 FF 15 E8 10 4A 02 8B C8 2B 0D 10 65 4B 02
81 F9 88 13 00 00 76 41 FF 35 14 65 4B 02 A3 10 65 4B 02 FF 15 58 10 4A 02 83 3D 9C 6C 4B 02 03
EB 08 6A 00 FF 15 EC 10 4A 02 80 3D 90 66 4B 02 00 74 08 FF 05 9C 6C 4B 02 EB 07 83 25 9C 6C 4B
02 00 C6 05 90 66 4B 02 01 56 FF 74 24 08 FF 15 2C 65 4B 02 8B F0 A1 64 6C 4B 02 2B 05 60 6C 4B
02 C1 F8 02 3B F0 72 05 E8 76 49 FF FF A1 60 6C 4B 02 8B 04 B0 90 90 90 90 5E C2 04 00 90 90 90
90 90 90 90 90 90 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 81
FB 94 16 48 00 0F 87 F9 FD FF FF E9 D2 FD FF FF 90
很多00,你们可以自己优化一下。
接下来用LordPE修复镜像dump出来,再用ImportREC,填好OEP偏移,按自动获取IAT表。转存一下,就可以了。 修复好的程序是可以正常运行的 例子下载:
例子.zip
(2.08 MB, 下载次数: 215)
四、感叹:
关于这个壳,它早已过时。网络上也有许多对应的脱壳教程,但教程中大多利用了脱ZP专用的工具,只说了步骤,很少说为什么这么做。我相信很多人都知道怎么脱这个壳,但是应该也有许多人只知道 这样能脱,不知道为什么这样能脱。这样就导致了,你对于不同的壳,只能生硬地记住对这个壳的脱壳步骤,才能脱。在我看来,这是没有意义的。只有搞懂了原理,理清了思路,才能对不同的壳都能得心应手。
如果你觉得我这篇文章还行,请给我一个免费的热心值,求求了,这对我真的很重要! |