高级玩家

- 贡献度
- 45
- 金元
- 1611
- 积分
- 371
- 精华
- 3
- 注册时间
- 2006-8-29

|
|
Safedisc 4.6破解实例
文章作者:仓鼠小布
软件名称:文明4原版1.61
软件类型:游戏
工具:peid看雪版(附带fly老大制作的特征库),OllyICE(OllyDBG的修改版),LoadPE,ucfir16f,winhex。
前言:
Safedisc是Macrovision公司开发的一个商用加壳软件,说道Macrovision公司,大家很快就能够想到installshield,但是它的safedisc在早年的游戏加密市场,那可谓龙头老大,虽然现在已经不复当年之勇(主要还是竞争对手过于强悍),但是仍旧是一款十分优秀的加密技术,完全值得一个cracker花下精力和时间去研究它。
本文选择文明4进行分析主要有两个原因,一个。。。按照老外的说法,文明4所使用的safedisc加密是最为齐全的,基本上把safedisc对游戏的加密手段都用上了,第二个原因。。。本人手头上是safedisc加密的游戏只有两个,一个是文明4,一个是中世纪2,中世纪2实在太大,只能选文明4了(囧),好了,废话不多说了,现在开始吧。
PS:下文为了方便起见把safedisc简称为sd,把OllyICE称为od。
第一章:躲过Anti—debug,到达OEP
首先,万年不变的第一步,先用peid查壳,我们发现,游戏是safedisc 4.6加密。
设置OllyICE忽略所有的异常选项。用IsDebuggerPresent插件去掉OllyDBD的调试器标志。
好了,我们用od载入文明4的exe文件,然后OD会停在这里:
00E0D06E > 55 push ebp
00E0D06F 8BEC mov ebp, esp
00E0D071 60 pushad //看,多么友好的提示啊。
00E0D072 BB 6ED0E000 mov ebx, offset <模块入口点>
00E0D077 B8 0DD0E000 mov eax, 00E0D00D
00E0D07C 33C9 xor ecx, ecx
00E0D07E 8A08 mov cl, byte ptr [eax]
00E0D080 85C9 test ecx, ecx
00E0D082 74 0C je short 00E0D090
00E0D084 B8 E4D0E000 mov eax, 00E0D0E4
00E0D089 2BC3 sub eax, ebx
00E0D08B 83E8 05 sub eax, 5
00E0D08E EB 0E jmp short 00E0D09E
00E0D090 51 push ecx
00E0D091 B9 2BD1E000 mov ecx, 00E0D12B
00E0D096 8BC1 mov eax, ecx
00E0D098 2BC3 sub eax, ebx
00E0D09A 0341 01 add eax, dword ptr [ecx+1]
00E0D09D 59 pop ecx
00E0D09E C603 E9 mov byte ptr [ebx], 0E9
00E0D0A1 8943 01 mov dword ptr [ebx+1], eax
00E0D0A4 51 push ecx
00E0D0A5 68 D9CFE000 push 00E0CFD9
00E0D0AA 33C0 xor eax, eax
00E0D0AC 85C9 test ecx, ecx
00E0D0AE 74 05 je short 00E0D0B5
00E0D0B0 8B45 08 mov eax, dword ptr [ebp+8]
00E0D0B3 EB 00 jmp short 00E0D0B5
00E0D0B5 50 push eax
00E0D0B6 E8 25FCFFFF call 00E0CCE0 //程序启动
00E0D0BB 83C4 08 add esp, 8
00E0D0BE 59 pop ecx
00E0D0BF 83F8 00 cmp eax, 0
00E0D0C2 74 1C je short 00E0D0E0
00E0D0C4 C603 C2 mov byte ptr [ebx], 0C2
00E0D0C7 C643 01 0C mov byte ptr [ebx+1], 0C
00E0D0CB 85C9 test ecx, ecx
00E0D0CD 74 09 je short 00E0D0D8
00E0D0CF 61 popad
00E0D0D0 5D pop ebp
00E0D0D1 B8 00000000 mov eax, 0
00E0D0D6 ^ EB 96 jmp short <模块入口点>
00E0D0D8 50 push eax
00E0D0D9 B8 F9CFE000 mov eax, 00E0CFF9
00E0D0DE FF10 call dword ptr [eax]
00E0D0E0 61 popad
00E0D0E1 5D pop ebp
00E0D0E2 EB 47 jmp short 00E0D12B
00E0D0E4 807C24 08 00 cmp byte ptr [esp+8], 0
00E0D0E9 75 40 jnz short 00E0D12B
00E0D0EB 51 push ecx
00E0D0EC 8B4C24 04 mov ecx, dword ptr [esp+4]
00E0D0F0 890D 25D1E000 mov dword ptr [E0D125], ecx
00E0D0F6 B9 02D1E000 mov ecx, 00E0D102
00E0D0FB 894C24 04 mov dword ptr [esp+4], ecx
00E0D0FF 59 pop ecx
00E0D100 EB 29 jmp short 00E0D12B
00E0D102 50 push eax
00E0D103 B8 FDCFE000 mov eax, 00E0CFFD
00E0D108 FF70 08 push dword ptr [eax+8]
00E0D10B 8B40 0C mov eax, dword ptr [eax+C]
00E0D10E FFD0 call eax
00E0D110 B8 FDCFE000 mov eax, 00E0CFFD
00E0D115 FF30 push dword ptr [eax]
00E0D117 8B40 04 mov eax, dword ptr [eax+4]
00E0D11A FFD0 call eax
00E0D11C 58 pop eax
00E0D11D B8 25D1E000 mov eax, 00E0D125
00E0D122 FF30 push dword ptr [eax]
00E0D124 C3 retn
00E0D125 72 16 jb short 00E0D13D
00E0D127 61 popad
00E0D128 1360 0D adc esp, dword ptr [eax+D]
00E0D12B - E9 5E31BAFF jmp 009B028E //OEP
00E0D130 66:833D 9043EA0>cmp word ptr [EA4390], 0
00E0D138 74 05 je short 00E0D13F
00E0D13A ^ E9 91FEFFFF jmp 00E0CFD0
00E0D13F C3 retn
破解过sd的cracker们会很容易发现每个sd的头部,无论其版本,竟然惊人得相似,而且代码的第三行的pushad永远是那么友好,有经验的cracker们一定知道,只要找到一个popad,下面的一个大跳转就是OEP了,但是下方有3个popad,分别是00E0D0CF,00E0D0E0,00E0D127处,究竟是哪一个呢,经验告诉我们第三个popad后的跳转就是真正的OEP了,不过,知道OEP还是没有用,大家可以看下面两张截图。


第一张是直接强跳到OEP后看到的代码,第二张是被破解的以后的OEP处的代码,二者的不同点相信大家都看到了吧,sd把加密过的PE分为两部分,第一部分是解码部分,通过Anti—debug和光盘验证以后,释放出95%的源代码,然后到达OEP,看来我们还是要到壳里面去逛逛才能见分晓了。
Sd对od的Anti—debug可以说是非常少的,sd会在你的C ocuments and Settings用户名Local SettingsTemp目录下生成~e5.0001.XXX.XXX的文件夹,其中里面有一个文件叫~df394b.tmp,sd的所有秘密都在这里面了。
据我所知,sd对od的Anti—debug只有IsDebuggerPresent,而我们有有IsDebuggerPresent插件躲过检测,所以可以高枕无忧了,但是还是看看比较好,bp IsDebuggerPresent,F9运行程序,到达断点以后,删除断点(切记是删除),Alt+F9,我们看到如下代码。
6670AF8C 8BF0 mov esi, eax
6670AF8E 66:85F6 test si, si
6670AF91 74 13 je short 6670AFA6 //IsDebuggerPresent检测
6670AF93 E8 2A63FFFF call 667012C2
6670AF98 66:8BF0 mov si, ax
6670AF9B 66:F7DE neg si
6670AF9E 1BF6 sbb esi, esi
6670AFA0 46 inc esi
6670AFA1 66:85F6 test si, si
6670AFA4 75 0F jnz short 6670AFB5
6670AFA6 8B4424 08 mov eax, dword ptr [esp+8]
6670AFAA 8120 EA894267 and dword ptr [eax], 674289EA
6670AFB0 66:8BC6 mov ax, si
6670AFB3 5E pop esi
6670AFB4 C3 retn
下面我们F8单步调试下去,到达如下代码。
6670557A 83C4 04 add esp, 4
6670557D 66:85C0 test ax, ax
66705580 0F85 02010000 jnz 66705688
66705586 F6C3 04 test bl, 4
66705589 76 12 jbe short 6670559D
6670558B 56 push esi
6670558C E8 EF580000 call 6670AE80
66705591 83C4 04 add esp, 4
66705594 66:85C0 test ax, ax
66705597 0F85 EB000000 jnz 66705688
6670559D F6C3 08 test bl, 8
667055A0 76 12 jbe short 667055B4
667055A2 56 push esi
667055A3 E8 18580000 call 6670ADC0
667055A8 83C4 04 add esp, 4
667055AB 66:85C0 test ax, ax
667055AE 0F85 D4000000 jnz 66705688
667055B4 F7C3 00080000 test ebx, 800
667055BA 76 12 jbe short 667055CE
667055BC 56 push esi
667055BD E8 1E570000 call 6670ACE0
667055C2 83C4 04 add esp, 4
667055C5 66:85C0 test ax, ax
667055C8 0F85 BA000000 jnz 66705688
667055CE F7C3 00100000 test ebx, 1000
667055D4 76 12 jbe short 667055E8
667055D6 56 push esi
667055D7 E8 44560000 call 6670AC20
667055DC 83C4 04 add esp, 4
667055DF 66:85C0 test ax, ax
667055E2 0F85 A0000000 jnz 66705688
667055E8 F7C3 00200000 test ebx, 2000
667055EE 76 12 jbe short 66705602
667055F0 56 push esi
667055F1 E8 7A550000 call 6670AB70
667055F6 83C4 04 add esp, 4
667055F9 66:85C0 test ax, ax
667055FC 0F85 86000000 jnz 66705688
66705602 F6C3 01 test bl, 1
66705605 76 0E jbe short 66705615
66705607 56 push esi
66705608 E8 53540000 call 6670AA60
6670560D 83C4 04 add esp, 4
66705610 66:85C0 test ax, ax
66705613 75 73 jnz short 66705688
66705615 F6C3 02 test bl, 2
66705618 76 0E jbe short 66705628
6670561A 56 push esi
6670561B E8 20530000 call 6670A940
66705620 83C4 04 add esp, 4
66705623 66:85C0 test ax, ax
66705626 75 60 jnz short 66705688
66705628 F6C3 10 test bl, 10
6670562B 76 0E jbe short 6670563B
6670562D 56 push esi
6670562E E8 BD520000 call 6670A8F0
66705633 83C4 04 add esp, 4
66705636 66:85C0 test ax, ax
66705639 75 4D jnz short 66705688
6670563B F6C3 20 test bl, 20
6670563E 76 0E jbe short 6670564E
66705640 56 push esi
66705641 E8 0A520000 call 6670A850
66705646 83C4 04 add esp, 4
66705649 66:85C0 test ax, ax
6670564C 75 3A jnz short 66705688
6670564E F6C3 40 test bl, 40
66705651 76 0E jbe short 66705661
66705653 56 push esi
66705654 E8 57510000 call 6670A7B0
66705659 83C4 04 add esp, 4
6670565C 66:85C0 test ax, ax
6670565F 75 27 jnz short 66705688
66705661 F7C3 80000000 test ebx, 80
66705667 76 0E jbe short 66705677
66705669 56 push esi
6670566A E8 11500000 call 6670A680
6670566F 83C4 04 add esp, 4
66705672 66:85C0 test ax, ax
66705675 75 11 jnz short 66705688
66705677 F7C3 00400000 test ebx, 4000
6670567D 76 09 jbe short 66705688
6670567F 56 push esi
66705680 E8 EB4E0000 call 6670A570
66705685 83C4 04 add esp, 4
66705688 5E pop esi
66705689 5B pop ebx
6670568A C3 retn
由于我们的od已经使用IsDebug插件了,所以这里不必处理,只是借用此断点来继续下面的流程,不过看看对大家还是有好处的,经过了6670568A处的retn以后,我们到了这里。
6670147F 83C4 08 add esp, 8
66701482 66:8945 F0 mov word ptr [ebp-10], ax
66701486 58 pop eax
66701487 0FB745 F0 movzx eax, word ptr [ebp-10]
6670148B 85C0 test eax, eax
6670148D 74 07 je short 66701496 //跳转完成
6670148F B8 00400000 mov eax, 4000
66701494 EB 05 jmp short 6670149B
66701496 B8 00000100 mov eax, 10000 // UNICODE "=::=::"
6670149B C9 leave
6670149C C3 retn
到达下面的代码。
66702E61 3D 00200000 cmp eax, 2000
66702E66 59 pop ecx
66702E67 59 pop ecx
66702E68 74 26 je short 66702E90
66702E6A 3D 00400000 cmp eax, 4000
66702E6F ^ 74 D9 je short 66702E4A
66702E71 33C9 xor ecx, ecx
66702E73 3D 00000100 cmp eax, 10000 ; UNICODE "=::=::"
66702E78 0F94C1 sete cl
66702E7B 49 dec ecx
66702E7C 81E1 6AFFFFFF and ecx, FFFFFF6A
66702E82 81C1 FA000000 add ecx, 0FA
66702E88 890D 2C0B7966 mov dword ptr [66790B2C], ecx
66702E8E C9 leave
66702E8F C3 retn
经过66702E8F处的retn,我们到达了下面,接下来就是一路的F8了,由于代码比较长,我就不全都打出来了,到达66704812处,我们可以停下了,接受光盘检测。
6670445B 6A 1C push 1C
6670445D E8 5AD20500 call 667616BC
66704462 83C4 20 add esp, 20
66704465 3BC7 cmp eax, edi
66704467 74 0A je short 66704473
66704469 57 push edi
6670446A 8BC8 mov ecx, eax
。
。
。
。
。
66704809 57 push edi
6670480A 8D4D 28 lea ecx, dword ptr [ebp+28]
6670480D E8 C81F0100 call 667167DA
66704812 E8 A6CEFFFF call 667016BD //光盘检测
66704817 66:85C0 test ax, ax
6670481A 75 17 jnz short 66704833
6670481C E8 B49D0100 call 6671E5D5
66704821 8D4D 28 lea ecx, dword ptr [ebp+28]
在此我想稍稍提及一下sd的光盘检测,sd加密过的光盘会有一个弱扇区,这个是故意损坏的扇区,比较老的虚拟光驱和刻录机是无法识别和复制这个弱扇区,sd的程序会检测光盘上是否有这个弱扇区,然后再检测光盘上的某几个其他普通扇区,然后才能进入游戏,以此来达到反盗版的目的,由于检测的普通扇区都是分开的,所以sd加密的游戏基本只能做出稀疏镜像,也就是所谓的极大镜像来骗过光盘验证。
这里由于本人学艺不精,无法在没有光盘的情况下手动骗过光盘验证,只能用极大镜像配合yasu混过光盘验证,如果有高人的话,请指导一下在下,在下不胜感激。
接下来就是一路F8不回头了,直到00E0D12B处,此处是一个大跳转,F8进入把,终于到了OEP了。
009B028E 6A 74 push 74
009B0290 68 587BB900 push 00B97B58
009B0295 E8 E6060000 call 009B0980
009B029A 33DB xor ebx, ebx
009B029C 895D E0 mov dword ptr [ebp-20], ebx
009B029F 53 push ebx
009B02A0 8B3D 8071B600 mov edi, dword ptr [B67180] ; kernel32.GetModuleHandleA
009B02A6 FFD7 call edi
看到了吧,一个很标准的用VC编译的头部,好了,我们用LoadPE把程序dump出来一份,取名为dumped.exe留着吧。
PS:其实sd的Anti—debug还不止IsDebuggerPresent这一个,用softICE调试过以后你就会发现暗桩密布,而且sd还有断点检测的Anti—debug,这就是为什么我开始要大家删除断点的理由,记住,破解时候就要养成好习惯,用过的断点要清理干净,如果实在要用就记在纸上,还有一个Anti—debug就是timeout之类的函数,如果你把程序载入以后,过个3分钟再跑,那是怎么都到不了OEP的。。。。。上面两个Anti—debug都完全可以避免,所以在这里就不赘述了。
第二章:输入表(IAT)修复
在进行这阶段前,希望大家对IAT有所了解,不熟悉的要去找资料学习学习,有了这个基础,下面的工作才好做.IAT修复就是对IAT表进行正常修复,加密软件几乎都处理IAT表,使IAT的内容改变成壳特定的内容,以防止dump出来后还原文件.我觉得这个阶段是难度较大而且也是赋挑战性的工作,是体现破解水平的一个方面也是整个解密工作的关键阶段.要完成这个阶段需要有很好的经验.
虽然我们dump出来了一份干净的程序,但是经过sd处理过的输入表自然是不能用了,没办法,修吧。
我们看到sd还是很厚道的,第一个GetModuleHandleA就是没有处理过的输入表,我们就从这里入手吧,看到指向GetModuleHandleA的指针了吗,B67180,再减去文件偏移400100,得到的地址是767080,这是第一个aip调用,这个时候就是用到winhex的时候了,我们用winhex打开文明4的原始执行文件,到达767080处看看。

我们在767080附近逛逛,寻找IAT的起始点,在IAT开始位置,一般前面是空记录(很多连续的00000000),在刚出现地址,并且是属于程序调用的模块的有效地址时,这就是IAT_start,记录下地址来,在这里是:767000。
IAT_stop比IAT_start更难找一点,需要经验和好的眼神,总的来说,一般是在结束时,后面跟的数据是属于无效的地址,并且"无效地址"数据前是00 00 00 00,这个是IAT表的规律,不同模块间间隔是00 00 00 00,这个只能靠多看程序,获得经验了,这里我们发现是在767bc0附近。

看到767bc0那一行了吧,好了,东西就在这里了,我们打开ucfir16f,选择civilization4.exe进程,自动查找IAT,ucfir16f果然是最好的输入表修复软件,找输入表果然准,得到的结果和真实结果相差很小,我们只需要把大小改为BD0即可,输入表这东西,个人推荐范围找大一点,宁可错杀1000,不可放过一个,我们得到如下结果。

我们把模块展开,发现有很多无效的指针,其实不是无效,而是被壳处理过了,我们可以看到,有130个指针要修复。。。。。。。可怕的东西啊,大家准备好干粮,别修到一半饿晕了,这个问题就麻烦了,^_^!!!。
我先来说明一下sd是如何加密IAT的,在程序通过验证以后,sd的~df394b.tmp并没有从内存中被释放出来,而是继续很猥琐地蹲在那里,干着它那邪恶的勾搭,那些指针指向代码惊人地相似,到后面我们就会看到,它压入一个特定值进入堆栈,然后交给~df394b.tmp处理一下,用~df394b.tmp间接调用需要的api,很天才的想法,这里我们只能够进入~df394b.tmp分析代码,以得到正确的api调用,好了开始吧。
我们载入原始执行文件,手动到达OEP,由于IAT的修复工作量巨大,而且都是机械工作,所以我就不一个一个讲了,我们以第一个模块中的第个指针作为例子来讲解,其他的就是照瓢画葫芦了。

看到第三个指针指向的地方了吗(这里我本来是想修第二个的,结果眼花一下,选到第三个去了,囧),01c5cf85,好,我们过去看看,结果看到如下代码。
01C5CF85 68 8612EABF push BFEA1286
01C5CF8A 9C pushfd //保护现场
01C5CF8B 60 pushad //保护现场
01C5CF8C 54 push esp
01C5CF8D 68 C5CFC501 push 1C5CFC5
01C5CF92 E8 45ADB164 call ~df394b.66777CDC //用壳间接调用api
01C5CF97 83C4 08 add esp, 8
01C5CF9A 6A 00 push 0
01C5CF9C 58 pop eax
01C5CF9D 61 popad //恢复现场
01C5CF9E 9D popfd //恢复现场
01C5CF9F C3 retn //调用完毕,跑路
我们设置01C5CF85为新的EIP,F8到01C5CF92处停下,F7步入,进入壳里面去逛逛,由于这是壳代码,我们要做的就是保证它一路向下即可,记得随时注意堆栈的变化。
66777CDC 55 push ebp
66777CDD 8BEC mov ebp, esp
66777CDF 83EC 34 sub esp, 34
66777CE2 53 push ebx
66777CE3 56 push esi
66777CE4 57 push edi
66777CE5 E8 94C6FBFF call 6673437E
66777CEA EB 0A jmp short 66777CF6
66777CEC EB 50 jmp short 66777D3E
。
。
。
。
。
66777F7C 8945 CC mov dword ptr [ebp-34], eax
66777F7F 8B45 CC mov eax, dword ptr [ebp-34]
66777F82 8B4D E0 mov ecx, dword ptr [ebp-20]
66777F85 8908 mov dword ptr [eax], ecx
66777F87 8B45 CC mov eax, dword ptr [ebp-34]
66777F8A 83C0 04 add eax, 4
66777F8D 50 push eax
66777F8E E8 59CDFBFF call 66734CEC
66777F93 59 pop ecx
66777F94 E8 01C4FBFF call 6673439A
66777F99 8B65 0C mov esp, dword ptr [ebp+C]
66777F9C 61 popad
66777F9D 9D popfd
66777F9E C3 retn //调用完毕,跑路
如果大家仔细一点的话,会发现右下角的堆栈的变化还是很令人欣喜的,在堆栈中出现了被间接调用的api的名字,ADVAPI32.GetUserNameA。

我们再看看第一个没有被处理过的api,也是ADVAPI32模块中的api,好了,就是它了,我们就把它推到正确的地方去。

好了,我们修好了第一个指针,庆贺一下,鲜花,掌声。。。。但是,还有129个指针,慢慢来吧,这个只有靠耐心了。
这里要说明一下,最后两个模块中的指针本来就是废指针,我们完全可以无视,附上我修好的IAT表,在下面附件下载,完成以后一共有730个指针,被落下哦。
修好以后按“修复转存文件”,我们选择那个dumped.exe,转存为dumped_.exe。
第三章:去暗桩
好了,你还活着吗,IAT修得够爽吧,呵呵,别以为这是结束,这个只是噩梦的开始>_<,原则上来说,IAT修好了,程序应该可以跑起来了,但是不然,我们点击dumped_.exe试试,毫无反应,呵呵,还有暗桩要去除,记得前面说过,sd在通过验证以后只会恢复95%的源代码,其他的5%只有靠我们自己修了。
这里先给sd的暗桩分分级,最为常见的就是call加密,前面虽然我们修好了IAT,但是对IAT的调用也是加密过的,不同的地址调用同样的指针,结果会call出不一样的api,比如:
45678912 call dword ptr [123456] // call a
98765432 call dword ptr [123456] // call b
这个是sd最喜欢用的加密了,由于api数量巨大分布广泛,而且有真有假,唯一的办法就是一个个检查了(让我想到了军训时候一个少将说过的东风31,囧)。
第二类暗桩就是SDK加密,比如00408990处的call
004010A9,我们到004010A9里面去看看,发现下面的代码。
004010A9 51 push ecx
004010AA 50 push eax
004010AB E8 630F0000 call 00402013 //交给壳处理一下
004010B0 56 push esi
004010B1 8BF1 mov esi, ecx
004010B3 8B06 mov eax, dword ptr [esi]
004010B5 83E8 0C sub eax, 0C
004010B8 74 10 je short 004010CA
004010BA 3D 5015CB00 cmp eax, 00CB1550
004010BF 74 09 je short 004010CA
004010C1 50 push eax
004010C2 E8 89F05A00 call 009B0150 //jmp 到MSVCR71.operatordelete[]
004010C7 83C4 04 add esp, 4
004010CA C706 5C15CB00 mov dword ptr [esi], 00CB155C
004010D0 5E pop esi
004010D1 C3 retn
看到了吧,00408990处的call
004010A9干的活就是让程序被壳处理一下,然后调用jmp .MSVCR71.operatordelete[],这个好办,我们只要搜索全部的call
004010A9,然后一个个分析一下,改一下调用即可,但是数量也不少哦。
第三种还是call的加密(sd真喜欢处理call),call里面干的活就是校验一下内存,这个其实也好办,只要稍稍改动一下代码即可,而且校验是连续的,所以不用担心漏掉哪个(要漏就是漏一串,^_^!!!)。
最后一种加密就比较可怕了,我们会发现一些地方的代码很搞笑,啪啪啪参数压好了,应该调用函数了,结果等来的却是一个jmp XXXXXXXX,跟进去一看,又是被~df394b.tmp处理,处理中间接调研api,然后一路F8,我们就会到达那个jmp XXXXXXXX的下面一步,这时候我们会很惊奇地发现,jmp XXXXXXXX下面的代码竟然和原来的完全不同,我们用鼠标滚轮滚两下,代码又变回原样,明白了吧,这就是sd的动态解压,以一个jmp代替call,然后再动态释放4~5行代码,有时候一个jmp可以代替3~4个call,由于这种jmp的加密数量稀少,但是分布得非常分散,稍不留神就会中标。。。。。可怕的东西。
由于这里的暗桩星云密布,我都已经不记得我修过几个了,只能从头开始,和大家一起来一遍,而且安装数量巨大,不可能都将一遍,我会各选取一个例子讲解一下,接下来就是靠大家自己了。
|
|