- UID
- 47821
注册时间2008-3-1
阅读权限10
最后登录1970-1-1
周游历练
该用户从未签到
|
【破文标题】【原创】手脱Armadillo双进程
【破文作者】天琴空唱
【作者邮箱】
【作者主页】
【破解工具】OD,PEID,FI
【破解平台】xp
【软件名称】俄罗斯方块外挂终结者 2.1++
【软件大小】
【原版下载】http://www.skycn.com/soft/19491.html
【保护方式】Armadillo
【软件简介】完全自动玩俄罗斯方块游戏,支持QQ火拼俄罗斯、联众。支持自动开始,自动发道具。速度快,可达到几近疯狂的速度。效率高,联众单机上测试可以几万行不死。是一款用来练习提高的好工具。
使用说明:
使用方法简单明了,您只要选择相应的俄罗斯方块类型(目前支持:QQ火拼俄罗斯、联众俄罗斯单机版和网络版)
然后按“开始”键就可以了。窗口上的小鱼图标如果变成彩色就说明开始工作,如果是灰色的说明暂停状态。
【破解声明】本文是对网上脱穿山甲壳方法的一些补充。这是我写的第一个破文,简单了些,希望大家不要见笑。
------------------------------------------------------------------------
【破解过程】用PEID查壳发现是Armadillo 3.00a - 3.61 -> Silicon Realms Toolworks。
用FI查显示为Armadillo 3.05
脱壳之前在网上参考了一些文章,按照他们做最后总是出现问题。后来自己摸索了一下终于脱壳成功
运行程序,打开任务管理器发现有2个进程,所以是双进程的壳。用AMD探测软件得到如下信息:
<------- 28-01-2009 14:45:10 ------->
D:\Program Files\方块终结者\TetrisTerminator.exe
!- Protected Armadillo
Protection system (Basic)
!- <Protection Options>
Standard protection or Minimum protection
!- <Backup Key Options>
No Registry Keys at All
!- <Compression Options>
Best/Slowest Compression
!- <Other Options>
Store Environment Vars Externally
Disable Monitoring Thread
!- Child detach
Child process ID: 00000A6C
Entry point: 00476000
Original bytes: 60E8
!- Elapsed Time 00h 00m 00s 438ms
************************************************
用OD载入,忽略所有异常,并且忽略C000001E异常,
一开始按照常规方法BP OpenMutexA, F9看堆栈
0012F588 0045ADA6 /CALL 到 OpenMutexA 来自 TetrisTe.0045ADA0
0012F58C 001F0001 |Access = 1F0001
0012F590 00000000 |Inheritable = FALSE
0012F594 0012FBC8 \MutexName = "1064::DA07E2D882" ★ 记住0012FBC8 这个地址
此处0012FBC8 和其它破文的地址不一样,切记不可照搬。
然后Ctrl+G:401000 键入以下代码
00401000 60 pushad
00401001 9C pushfd
00401002 68 B4FB1200 push 0012FBC8 ★ 堆栈里看到的值
00401007 33C0 xor eax,eax
00401009 50 push eax
0040100A 50 push eax
0040100B E8 B4B2A577 call kernel32.CreateMutexA
00401010 9D popfd
00401011 61 popad
00401012 E9 33F7A577 jmp kernel32.OpenMutexA
在401000处新建起源,F9运行,再次中断在OpenMutexA处。
返回401000,撤销修改。这一步在一些教程里被忽略掉了,但是很重要,不然后面恢复后的代码都是错的。
取消以前断点,下断:HE GetModuleHandleA。 我试过bp GetModuleHandleA+5和he GetModuleHandleA+5, 但是发现只能中断下来一次。所以保险起见不用+5,另外,如果用bp有时也拦截不下来,所以保险起见用he。具体原因不明。
取消先前的 OpenMutexA断点后F9运行。这里我发现我的堆栈并不像教程里的那样有很多个GetModuleHandleA, 而是只有1个。后来发现我理解错了。应该是按F9,会发现程序不断的调用GetModuleHandleA。我们要注意堆栈的变化,当出现
0012D3AC 00C86622 返回到 00C86622 来自 kernel32.GetModuleHandleA
0012D3B0 0012D4E8 ASCII "advapi32.dll"
时,再一次按F9,取消所有断点,按alt+f9 返回。(一共按了10次)
有人说按shift+f9运行,当经过一个call缓冲有点大时,一般是在堆栈窗口出现ASCII "kernel32.dll"和ASCII "VirtualFree“后,再运行一次,出现"kernel32.dll",就是返回时机,取消断点,按alt+f9执行到返回。但是我没有发现有"VirtualFree。
00B35B62 FF15 A450B500 call dword ptr [B550A4] ; kernel32.GetModuleHandleA
00B35B68 3945 08 cmp dword ptr [ebp+8], eax ; 返回到这里
00B35B6B 75 07 jnz short 00B35B74
00B35B6D B9 E873B500 mov ecx, 0B573E8
00B35B72 EB 52 jmp short 00B35BC6
00B35B74 393D E079B500 cmp dword ptr [B579E0], edi
00B35B7A B9 E079B500 mov ecx, 0B579E0
00B35B7F 0F84 93000000 je 00B35C18 ; Magic Jump, 将je改成jmp
00B35B85 8B35 60D8B500 mov esi, dword ptr [B5D860]
00B35B8B A1 E018B600 mov eax, dword ptr [B618E0]
00B35B90 F641 08 01 test byte ptr [ecx+8], 1
00B35B94 74 0E je short 00B35BA4
00B35B96 8B50 5C mov edx, dword ptr [eax+5C]
00B35B99 3350 48 xor edx, dword ptr [eax+48]
00B35B9C 3350 1C xor edx, dword ptr [eax+1C]
00B35B9F F6C2 80 test dl, 80
00B35BA2 75 13 jnz short 00B35BB7
00B35BA4 8B50 5C mov edx, dword ptr [eax+5C]
有人说还需要Ctrl+F在当前位置查找命令: salc,当看到jmp、salc、salc代码连在一起时,呵呵,恭喜,找到地方了,在salc上面的jmp处下断!
00C9C594 FF75 F4 push dword ptr ss:[ebp-C]
00C9C597 E8 A7540000 call 00CA1A43
00C9C59C FF75 BC push dword ptr ss:[ebp-44]
00C9C59F E8 8E430000 call 00CA0932
00C9C5A4 59 pop ecx
00C9C5A5 59 pop ecx
00C9C5A6 EB 03 jmp short 00C9C5AB//此处下断
00C9C5A8 D6 salc
00C9C5A9 D6 salc
F9运行,断在00C9C5A6处。当然,由于是动态解码,每次调试看到的地址可能是不同的,但代码是相同的!其实断在00C9C5A6处时,IAT解密已经完成了。现在我们返回Magic Jump 处,改回原先修改的代码,在00C9C24F处点右键->“撤销选择”即可。 为何要这样做?原作者说他发现程序在下面会依据原先的代码进行解码,以前下 硬件断点 操作没有修改原代码,所以解码正确。而直接修改Magic Jump后改变了原先的代码,导致解码不正确而异常出错!现在在解码以前恢复原先的代码,因此就不会再出错了!
经过多次实验发现这种说法并非完全正确,只有当AMD的版本大于3.6时才需要这么做。在这里如果断在jump处后将magic jump 改回je是不行的,因为只有程序还会运行到magic jump处,不像上面所说的断在00C9C5A6处时,IAT解密已经完成了。所以这里不需要改回去,也不需要找salc。
***********************************************************
Alt+M 查看内存,在401000开始的段上下 内存访问断点,F9运行,直接中断在OEP处
0041DE04 6A 60 push 60
0041DE06 68 20344400 push 00443420
0041DE0B E8 BC120000 call 0041F0CC
0041DE10 BF 94000000 mov edi, 94
0041DE15 8BC7 mov eax, edi
0041DE17 E8 44E7FFFF call 0041C560
0041DE1C 8965 E8 mov dword ptr [ebp-18], esp
0041DE1F 8BF4 mov esi, esp
0041DE21 893E mov dword ptr [esi], edi
0041DE23 56 push esi
0041DE24 FF15 E8E24300 call dword ptr [43E2E8] ; kernel32.GetVersionExA
0041DE2A 8B4E 10 mov ecx, dword ptr [esi+10]
使用LoedPE dump下完整的镜像,然后运行ImportREC 1.7,选择这个进程。把OEP改为0001DE04,点IT AutoSearch,CUT掉无效函数。FixDump,正常运行!
------------------------------------------------------------------------
【破解总结】壳虽然脱掉了,但是作者的加密方法仍然比较复杂。花了3个小时没有找到相应的破解方法,欢迎有兴趣的朋友共同探讨。
------------------------------------------------------------------------
【版权声明】
[ 本帖最后由 天琴空唱 于 2009-1-30 00:34 编辑 ] |
评分
-
查看全部评分
|