3DMGAME 3DM首页 新闻中心 前瞻 | 评测 游戏库 热门 | 最新 攻略中心 攻略 | 秘籍 下载中心 游戏 | 汉化 购买正版 论坛

注册 登录

QQ登录

只需一步,快速开始

查看: 16950|回复: 152
打印 上一主题 下一主题

[水σ]Safedisc 4.6破解实例

  [复制链接]

0

主题

248

帖子

371

积分

高级玩家

Rank: 4

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

上古探险家

跳转到指定楼层
主题
发表于 2007-12-14 22:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
Safedisc 4.6破解实例




文章作者:仓鼠小布
软件名称:文明4原版1.61
软件类型:游戏
工具:peid看雪版(附带fly老大制作的特征库),OllyICEOllyDBG的修改版),LoadPEucfir16fwinhex


前言:
SafediscMacrovision公司开发的一个商用加壳软件,说道Macrovision公司,大家很快就能够想到installshield,但是它的safedisc在早年的游戏加密市场,那可谓龙头老大,虽然现在已经不复当年之勇(主要还是竞争对手过于强悍),但是仍旧是一款十分优秀的加密技术,完全值得一个cracker花下精力和时间去研究它。
本文选择文明4进行分析主要有两个原因,一个。。。按照老外的说法,文明4所使用的safedisc加密是最为齐全的,基本上把safedisc对游戏的加密手段都用上了,第二个原因。。。本人手头上是safedisc加密的游戏只有两个,一个是文明4,一个是中世纪2,中世纪2实在太大,只能选文明4了(囧),好了,废话不多说了,现在开始吧。
PS:下文为了方便起见把safedisc简称为sd,把OllyICE称为od


第一章:躲过Antidebug,到达OEP

首先,万年不变的第一步,先用peid查壳,我们发现,游戏是safedisc 4.6加密。





设置OllyICE忽略所有的异常选项。用IsDebuggerPresent插件去掉OllyDBD的调试器标志。


好了,我们用
od载入文明4exe文件,然后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

破解过sdcracker们会很容易发现每个sd的头部,无论其版本,竟然惊人得相似,而且代码的第三行的pushad永远是那么友好,有经验的cracker们一定知道,只要找到一个popad,下面的一个大跳转就是OEP了,但是下方有3popad,分别是00E0D0CF00E0D0E000E0D127处,究竟是哪一个呢,经验告诉我们第三个popad后的跳转就是真正的OEP了,不过,知道OEP还是没有用,大家可以看下面两张截图。







第一张是直接强跳到OEP后看到的代码,第二张是被破解的以后的OEP处的代码,二者的不同点相信大家都看到了吧,sd把加密过的PE分为两部分,第一部分是解码部分,通过Antidebug和光盘验证以后,释放出95%的源代码,然后到达OEP,看来我们还是要到壳里面去逛逛才能见分晓了。
SdodAntidebug可以说是非常少的,sd会在你的Cocuments and Settings用户名Local SettingsTemp目录下生成~e5.0001.XXX.XXX的文件夹,其中里面有一个文件叫~df394b.tmpsd的所有秘密都在这里面了。
据我所知,sdodAntidebug只有IsDebuggerPresent,而我们有有IsDebuggerPresent插件躲过检测,所以可以高枕无忧了,但是还是看看比较好,bp IsDebuggerPresentF9运行程序,到达断点以后,删除断点(切记是删除),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_stopIAT_start更难找一点,需要经验和好的眼神,总的来说,一般是在结束时,后面跟的数据是属于无效的地址,并且"无效地址"数据前是00 00 00 00,这个是IAT表的规律,不同模块间间隔是00 00 00 00,这个只能靠多看程序,获得经验了,这里我们发现是在767bc0附近。




看到767bc0那一行了吧,好了,东西就在这里了,我们打开ucfir16f,选择civilization4.exe进程,自动查找IATucfir16f果然是最好的输入表修复软件,找输入表果然准,得到的结果和真实结果相差很小,我们只需要把大小改为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,然后再动态释放45行代码,有时候一个jmp可以代替34call,由于这种jmp的加密数量稀少,但是分布得非常分散,稍不留神就会中标。。。。。可怕的东西。
由于这里的暗桩星云密布,我都已经不记得我修过几个了,只能从头开始,和大家一起来一遍,而且安装数量巨大,不可能都将一遍,我会各选取一个例子讲解一下,接下来就是靠大家自己了。










回复

使用道具 举报

13

主题

642

帖子

425

积分

高级玩家

Rank: 4

贡献度
6
金元
4006
积分
425
精华
0
注册时间
2014-3-27

2026年3DM官方水友

QQ
舒服的沙发
发表于 2023-10-6 11:15 | 只看该作者
仓鼠小布 发表于 2007-12-15 22:06
最好先学c,然后是汇编,接下来就是运气了。。。。。[em33]

我查了壳 三国志8的简体版 也是   Safedisc 4.6的壳,麻烦兄弟帮忙脱一下呗,这种壳我不会脱
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|3DMGAME ( 京ICP备14006952号-1  沪公网安备 31011202006753号

GMT+8, 2026-3-15 21:00 , Processed in 0.030950 second(s), 17 queries , Memcached On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表