【文章标题】: tetris 4000&tetris 5000crack
【文章作者】: dogkarl
【作者邮箱】: [email]xiangpizhu126@yahoo.com.cn[/email]
【软件名称】: tetris 4000&tetris 5000
【软件大小】: 10.5M&4.45M
【下载地址】: http://www.softsea.net/soft/114964.htm
【加壳方式】: SoftWrap
【编写语言】: C
【使用工具】: Peid0.94,OllyIce,dup2.0
【操作平台】: winXP
【软件介绍】: 很好玩的俄罗斯方块,画面绚丽,而且是3D的。
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
暑假来临,奉母亲大人之命,寻找俄罗斯方块,结果找到两个很pretty的俄罗斯方块。然而寻注册而不可得,只好自己解决。
首先介绍tetris 4000,这个是用softwarp5.1.2加壳的,参考了SoftWrap 6.1.1 Loader By: Gabri3l / ARTeam
http://cracking.accessroot.com 一文的思路,因此本文也可以作为该文的中文翻译补充版。
1.例行的第一步,用peid 0.94扫描文件,首先会显示FSG v1.10 (Eng) -> dulek/xt *,但是在hardcore scan之下,显出了庐山真面目
Softwrap (encrypted) main stub / XLok,但是peid没有给出具体的版本号。在第一个窗口中按下buy,可以看到版本号是5.1.2。
2.开始破解每个软件之前,我们都要理好思路,定好目标。
对于tetris4000,由于它被一个加密壳加密,最好的方法是完全脱掉它。但是我们今天用的思路却是用 内存补丁对加密壳实施爆破。要暴破
,关键就是要找到壳中关键的判断分支。
3.有了思路现在开始工作。打开OllyIce,加载Tetris4000.exe,然后在选项-〉调试设置中忽略以下异常:
INT 3异常
单步异常
整数除零
无效或异常指令
4.按下运行程序按钮,我们来到第一个对话框处。(try按钮是不是灰的无关紧要)softwrap会提醒你只有三次机会等等。
5.按下暂停程序按钮,然后在“察看”菜单中选择“调用堆栈”命令。你会看到大致如下的信息:
调用堆栈: 主线程
地址 堆栈 函数过程 调用来自
0012F4FC 77D19418 包含ntdll.KiFastSystemCallRet USER32.77D19416
0012F500 77D2E2A2 USER32.WaitMessage USER32.77D2E29D
0012F534 77D261C6 USER32.77D2E113 USER32.77D261C1
0012F55C 77D26208 USER32.77D26110 USER32.77D26203
0012F57C 77D3B168 USER32.DialogBoxIndirectParamAorW USER32.77D3B163 此行就是用来创建你看到的对话框的
0012F5A8 00F31276 softwrap.00FAA5EC softwrap.00F31270 此函数调用了DialogBoxIndirectParamAorW
0012F5C0 00F316A4 softwrap.00F31251 softwrap.00F3169F
0012F5DC 00F31CE7 softwrap.00F31502 softwrap.00F31CE2 -〉关键的跳转就是在这个函数里
0012FE24 00F219CC ? softwrap.00F316A9 softwrap.00F219C7
0012FE58 004A364C 包含softwrap.00F219CC Tetris40.004A364A
0012FF9C 004A1C00 ? Tetris40.004A3598 Tetris40.004A1BFB
6.现在我们来分析:softwrap.00FAA5EC这个函数调用了DialogBoxIndirectParamAorW这个函数来创建对话框,双击它,我们看到以下的代码:
00FAA5EC 6A 00 push 0
00FAA5EE 9C pushfd
00FAA5EF 50 push eax
00FAA5F0 53 push ebx
00FAA5F1 8B5C24 10 mov ebx, [esp+10]
00FAA5F5 53 push ebx
00FAA5F6 83EB 06 sub ebx, 6
00FAA5F9 68 911F0000 push 1F91
00FAA5FE 68 0000FD00 push 0FD0000
00FAA603 C3 retn //这个retn实际上调用了softwrap中的一段代码
00FAA604 B8 B41E90E0 mov eax, E0901EB4
00FAA609 64:B1 1C mov cl, 1C
00FAA60C 895C24 0C mov [esp+C], ebx
00FAA610 5B pop ebx
00FAA611 58 pop eax
00FAA612 9D popfd
00FAA613 C3 retn
7.看来这里不会有关键的跳转了。经过一层层向上查找后(为了节省时间,我直接给出关键跳转的位置。我怎么找到的?主要就是尝试,另外
如果你有一些经验的话,看到dec eax和一串je xxxxx捆在一起,这明显就是c中的switch-case 语句的遗迹)。
双击0012F5DC 00F31CE7 softwrap.00F31502 这一行,向下滚动,找到以下代码:
00D31522 E8 5CD7FFFF call 00D2EC83
00D31527 0FBEC0 movsx eax, al
00D3152A 33DB xor ebx, ebx
00D3152C 48 dec eax
00D3152D 881D B88BD600 mov [D68BB8], bl
00D31533 881D B98BD600 mov [D68BB9], bl
00D31539 74 2F je short 00D3156A //If eax==1
00D3153B 48 dec eax
00D3153C 0F84 5D010000 je 00D3169F //If eax==2
00D31542 48 dec eax
00D31543 74 1B je short 00D31560 //If eax==3
00D31545 48 dec eax
00D31546 0F85 58010000 jnz 00D316A4
00D3154C C705 9C8DD600 01000000 mov dword ptr [D68D9C], 1 //If eax==4
很好,这里是关键的判断处。下一步,究竟eax 是多少时我们的程序可以运行呢?由于这是在进入我们现在这个对话框之前就执行过的代码,
现在在这里下断点是没有用的。
8.很好,那么让我们按下重新开始程序按钮。在代码行上右击,在菜单中选择“转到->表达式”,在对话框中输入:“00D31527”,程序提示
:指定地址无内存。这是因为softwrap.dll还没有加载。看来得想个办法。
9.在选项-〉调试设置中选择“事件”,钩选"中断于新模块"。现在按下运行程序按钮,有几个模块在“executable modules”中显示出来,可
惜没有softwrap.dll。多次按下运行程序按钮,直到softwrap.dll被加载而在“executable modules”中高亮显示出来为止。现在在选项-〉调
试设置中选择“事件”,取消钩选"中断于新模块"。
10.现在在代码行上右击,在菜单中选择“转到->表达式”,在对话框中输入:“00D31527”,你会看到:
00D31527 B5 4E mov ch, 4E
怎么和先前的不一样?因为softwrap.dll还没有解压。
11.在00D31522这一行右击,在菜单中选择“断点->内存访问”。
12.执行程序,开始你会中断到解压的代码中,多按几次运行程序按钮,直到你来到
00D31527 0FBEC0 movsx eax, al
现在可以自由修改eax的值,看看到底各个分支到什么地方。
13. 为了节省时间,下面给出各个分支的注释
00D31527 0FBEC0 movsx eax, al
00D3152A 33DB xor ebx, ebx
00D3152C 48 dec eax
00D3152D 881D B88BD600 mov [D68BB8], bl
00D31533 881D B98BD600 mov [D68BB9], bl
00D31539 74 2F je short 00D3156A //If eax==1 ,程序报告xlok服务器错误
00D3153B 48 dec eax
00D3153C 0F84 5D010000 je 00D3169F //If eax==2 ,程序会把我们送到那个你一直看到的对话框那里
00D31542 48 dec eax
00D31543 74 1B je short 00D31560 //If eax==3 ,程序会威胁你说如果你再实施破解,就让你永远用不成这个软件;-)
00D31545 48 dec eax
00D31546 0F85 58010000 jnz 00D316A4
00D3154C C705 9C8DD600 01000000 mov dword ptr [D68D9C], 1 //If eax==4,这个分支就是我梦想要的!直接进游戏!
很好,看来我们希望无论如何都去执行分支4。如果你先前注意的话,一般eax 的值都是02.
14.那么我们需要把分支02的 je 00D3169F 改成 je 00D3154C .在OllyIce中修改后,我们知道要把00D3153C处的0F 84 5D 01 00 00修改为74
0E 90 90 90 90。
15.现在问题出现了。由于文件自解压,自校验,我们不能直接修改文件,因此需要创建一个内存补丁,在程序自解压,自校验之后,但是运行
到00D3153C之前修改指令。不过幸运的是,早有人写好了专门用于这个问题的软件。
16. 现在打开dup2.0。首先新建方案,命名为tetris4000,然后点“添加”,在对话框里选“偏移量补丁”,选择你创建的“偏移量补丁”,
点编辑,把目标文件设为tetris4000.exe, 然后选择虚拟地址模式,因为我们要在内存中打补丁。
17.现在在"添加与编辑"对话框中,输入偏移量(00D3153C),原始字节(0f), 新的字节(74)。继续输入,直到看起来是这个样子:
Virtual Address 原始字节 新的字节
00D3153C 0F 74
00D3153D 84 0E
00D3153E 5D 90
00D3153F 01 90
00D31540 00 90
00D31541 00 90
18.现在只剩下一个问题了,加载器怎么把握好时机,在程序自解压,自校验之后,但是运行到00D3153C之前修改指令呢? 看到右下角的"启用内
存校验"选项了吗?这就是解决方法.加载器会监视一个内存地址,当这个内存地址的一个双字被修改为我们事先设定的一个值时,就修改指令.
19.现在的任务就是去寻找这样一个地址了.到哪里去找呢? 在选项-〉调试设置中选择“事件”,钩选"中断于新模块"。多次按下运行程序按钮
,直到softwrap.dll被加载而在“executable modules”中高亮显示出来为止。现在在选项-〉调试设置中选择“事件”,取消钩选"中断于新
模块"。在代码行上右击,在菜单中选择“转到->表达式”,在对话框中输入:“00D31527”,在00D31522这一行右击,在菜单中选择“断点->
内存访问”。
20.执行程序,开始你会中断到解压的代码中,多按几次运行程序按钮,直到你来到
00D31527 0FBEC0 movsx eax, al
21。现在察看调用堆栈,如下:
调用堆栈: 主线程
地址 堆栈 函数过程 调用来自
0012F5DC 00D31CE7 softwrap.00D31502 softwrap.00D31CE2 //这是我们所在的地方
0012FE24 00D219CC ? softwrap.00D316A9 softwrap.00D219C7 //这三个函数都可以作为寻找的目标。
0012FE58 004A364C 包含softwrap.00D219CC Tetris40.004A364A//我在这里找到的
0012FF9C 004A1C00 ? Tetris40.004A3598 Tetris40.004A1BFB
我们要在其中找到一个改变内存中双字的指令。不过我为了节省时间,直接给出结果:
双击0012FE58 004A364C 包含softwrap.00D219CC这一行,看到:
00D21941 > 55 push ebp
00D21942 8BEC mov ebp, esp
00D21944 83EC 10 sub esp, 10
00D21947 8B45 10 mov eax, [ebp+10]
00D2194A FF05 647ED600 inc dword ptr [D67E64] <-注意这里
00D21950 833D 647ED600 0>cmp dword ptr [D67E64], 2
00D21957 53 push ebx
00D21958 56 push esi
00D21959 57 push edi
00D2195A A3 788ED600 mov [D68E78], eax
00D2195F 7C 56 jl short 00D219B7
00D21961 E8 1B260200 call 00D43F81
00D21966 8BF0 mov esi, eax
00D21968 C1E6 10 shl esi, 10
00D2196B E8 11260200 call 00D43F81
00D21970 6A 10 push 10
00D21972 03F0 add esi, eax
00D21974 33DB xor ebx, ebx
00D21976 8D45 F0 lea eax, [ebp-10]
00D21979 53 push ebx
00D2197A 50 push eax
00D2197B 33FF xor edi, edi
00D2197D E8 CE1A0200 call 00D43450
00D21982 8D45 F0 lea eax, [ebp-10]
00D21985 50 push eax
00D21986 FF75 08 push dword ptr [ebp+8]
00D21989 56 push esi
00D2198A E8 62FDFFFF call 00D216F1
00D2198F 83C4 18 add esp, 18
00D21992 83F8 FF cmp eax, -1
00D21995 74 1C je short 00D219B3
00D21997 6A 01 push 1
00D21999 8D45 F0 lea eax, [ebp-10]
00D2199C 50 push eax
00D2199D FF75 0C push dword ptr [ebp+C]
00D219A0 E8 0DFFFFFF call 00D218B2
00D219A5 83C4 0C add esp, 0C
00D219A8 83F8 FF cmp eax, -1
00D219AB 75 04 jnz short 00D219B1
00D219AD 0BF8 or edi, eax
00D219AF EB 02 jmp short 00D219B3
00D219B1 8BFE mov edi, esi
00D219B3 8BC7 mov eax, edi
00D219B5 EB 67 jmp short 00D21A1E
00D219B7 6A 01 push 1
00D219B9 68 D923D500 push 00D523D9
00D219BE 33DB xor ebx, ebx
00D219C0 53 push ebx
00D219C1 FF35 687ED600 push dword ptr [D67E68] ; softwrap.00D20000
00D219C7 E8 DDFC0000 call 00D316A9 ;在这里调用了下层函数
00D219CC E8 B0250200 call 00D43F81
00D219D1 8BF0 mov esi, eax
00D219D3 C1E6 10 shl esi, 10
00D219D6 E8 A6250200 call 00D43F81
00D219DB 6A 10 push 10
00D219DD 03F0 add esi, eax
00D219DF E8 D11A0200 call 00D434B5
00D219E4 6A 10 push 10
00D219E6 8BF8 mov edi, eax
00D219E8 53 push ebx
00D219E9 57 push edi
00D219EA E8 611A0200 call 00D43450
00D219EF 57 push edi
00D219F0 FF75 08 push dword ptr [ebp+8]
00D219F3 56 push esi
00D219F4 E8 F8FCFFFF call 00D216F1
00D219F9 83C4 1C add esp, 1C
00D219FC 83F8 FF cmp eax, -1
00D219FF 74 14 je short 00D21A15
00D21A01 57 push edi
00D21A02 FF75 0C push dword ptr [ebp+C]
00D21A05 E8 16FEFFFF call 00D21820
00D21A0A 83CB FF or ebx, FFFFFFFF
00D21A0D 3BC3 cmp eax, ebx
00D21A0F 59 pop ecx
00D21A10 59 pop ecx
00D21A11 74 02 je short 00D21A15
00D21A13 8BDE mov ebx, esi
00D21A15 57 push edi
00D21A16 E8 951A0200 call 00D434B0
00D21A1B 59 pop ecx
00D21A1C 8BC3 mov eax, ebx
00D21A1E 5F pop edi
00D21A1F 5E pop esi
00D21A20 5B pop ebx
00D21A21 C9 leave
00D21A22 C3 retn
我选择了0D2194A FF05 647ED600 inc dword ptr [D67E64]这条指令,注意,如果你另外找到了很好的数值地址,一样可以用。经过
跟踪,我知道他会从00000000变为00000001。
22.现在在dup2.0中,在内存检验中,钩选“启用内存检验”,在“内存地址”一栏中,填写D67E64,在“内存值”一栏中,填写00000001。现
在保存项目,并创建加载器。
23.点击加载器,tetris4000顺利运行!Bingo!
至于tetris5000,由于是asprotect 1.xx-2.xx的壳,轻松剥掉就行了。然后把"game directory"\data\scripts\general\init.txt 中的
nag_level = 5改为nag_level = 500就行了。Have fun!
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2006年07月19日 上午 02:15:16
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)