时间限制,看我怎样突破你
本篇文章源自《黑客防线》2007年10月刊
转载请注明版权
文/图 Hokkien
===================================
Okoker Brains Practicer 1.9是一款益智游戏,小巧而精灵,很适合在工作之余小玩一把。但它是一款共享软件,不注册时有时间限制,只能玩2分钟。2分钟?呵呵,未免太不人道啦!那咱们今天就来玩玩它。
脱壳
查壳显示为“ASPack 2.12 -> Alexey Solodovnikov”,呵呵,这么简单的壳啊,那就用工具脱吧。试了一下,居然不行,脱不了啊。看来,这可能是个变形壳,那只有手脱啦。下面是手工脱壳过程。
用OD载入软件,停在下面的入口处。
00523001 > 60 PUSHAD
00523002 E8 03000000 CALL Brains_P.0052300A
00523007 - E9 EB045D45 JMP 45AF34F7
第一条语句是“PUSHAD”,在下面周围看看有没有“POPAD”,很遗憾,没有。那单步跟踪吧,呵呵,什么时候才到尽头啊。怎么办?不妨先看一下各个寄存器的值,如图1所示。
图1
根据堆栈平衡的原理,既然有“PUSHAD”,那么必然有类似“POPAD”的操作,从而达到堆栈平衡。先单步运行“PUSHAD”,此时观察堆栈情况,如图2所示,可以看到0012FFB0的值刚好是ESP的值,因而可以根据著名的“ESP定律”来脱了。我们下硬件访问断点,即在工具栏输入“hr 0012FFB0”,F9运行后,程序被断在下面的地方。
图2
005233A7 0BC9 OR ECX,ECX
005233A9 8985 A8030000 MOV DWORD PTR SS:[EBP+3A8],EAX
005233AF 61 POPAD
005233B0 75 08 JNZ SHORT Brains_P.005233BA
;断在这里
005233B2 B8 01000000 MOV EAX,1
005233B7 C2 0C00 RETN 0C
终于看到了熟悉的“POPAD”啦!再单步执行几步后,程序有个段间跳转,会来到下面的代码处。
004DCBEC 55 PUSH EBP
004DCBED 8BEC MOV EBP,ESP
004DCBEF 83C4 F0 ADD ESP,-10
004DCBF2 53 PUSH EBX
这是很典型的函数入口,那就DUMP下来吧,呵呵,查壳显示“Borland Delphi 6.0 - 7.0”。看来脱壳圆满成功。下面开始分析。
算法分析
用OD载入,查找一下字符串,没发现任何有用的信息。那就请出伟大的DeDe吧,分析后我们定位到下面的关键点。
004C53E4 55 push ebp
004C53E5 8BEC mov ebp, esp
为了让OD读取DeDe的分析结果,我们可以导出map文件,如图3所示。导出map文件后,用OD的插件LoadMap加载就可以啦。之后用OD动态调试,来到下面的关键位置。
图3
* Reference to: Controls.TControl.GetText(TControl):TCaption;|
004C5429 E85A36FAFF call 00468A88
004C542E 8B45F8 mov eax, [ebp-$08]
* Reference to: SysUtils.StrToInt(AnsiString):Integer;|
004C5431 E86632F4FF call 0040869C
;把输入的注册码转换为整数
004C5436 B9B9060000 mov ecx, $000006B9
004C543B 99 cdq
004C543C F7F9 idiv ecx ;除6B9
004C543E 81FAE0020000 cmp edx, $000002E0
;余数是否为2E0
004C5444 756A jnz 004C54B0 ;不是出错
004C5446 A140F74D00 mov eax, dword ptr [$004DF740]
004C544B 8B00 mov eax, [eax]
004C544D 8B8058050000 mov eax, [eax+$0558]
004C5453 33D2 xor edx, edx
天啊,不会这么简单吧?输入注册码模6B9应该为2E0。那就根据这个随便找个注册码试试,好的,成功啦!如图4所示。
图4
试用一下,没有限制。那是不是成功啦?我们重启一下,天啊,又计时!如图5所示。看来没这么简单,软件把验证的不同部分分别放在不同地方验证。因为学习比较忙,没有时间跟踪它的验证代码。但我们可以爆破它,其实爆破也不是那么容易的,不信大家试试,呵呵。
图5
突破时间限制
首先,想要找到时间限制关键点并不那么容易,我从中走了不少弯路,曾经考虑到API断点,包括注册表函数等等,但效果很不明显。其他弯路篇幅有限,就不一一列举啦。还是请出DeDe,如图6所示。
图6
来到这里你会发现好多函数,而跟计时器有关的函数有13个之多,我们要从中找到关键点谈何容易啊!不过,到了这个份上,就一个一个下断吧。最终,我们可以定位到以下地方。
004DC09C >/. 55 PUSH EBP
; <-TForm1@Timer13Timer
004DC09D |. 8BEC MOV EBP,ESP
004DC09F |. 6A 00 PUSH 0
004DC0A1 |. 53 PUSH EBX
004DC0A2 |. 56 PUSH ESI
004DC0A3 |. 8BD8 MOV EBX,EAX
004DC0A5 |. 33C0 XOR EAX,EAX
004DC0A7 |. 55 PUSH EBP
004DC0A8 |. 68 4DC14D00 PUSH <ss.->System.@HandleFinally;>
004DC0AD |. 64:FF30 PUSH DWORD PTR FS:[EAX]
004DC0B0 |. 64:8920 MOV DWORD PTR FS:[EAX],ESP
004DC0B3 |. 83BB 6C060000>CMP DWORD PTR DS:[EBX+66C],0
004DC0BA 7C 7B JL SHORT ss.004DC137
;关键跳转
004DC0BC |. B2 01 MOV DL,1
004DC0BE >|. 8B83 58050000 MOV EAX,DWORD PTR DS:[EBX+558]
; *Label17:TLabel
004DC0C4 >|. E8 DFC8F8FF CALL ss.004689A8
; ->Controls.TControl.SetVisible(TControl;Boolean);
004DC0C9 |. FF8B 6C060000 DEC DWORD PTR DS:[EBX+66C]
004DC0CF |. 8BB3 6C060000 MOV ESI,DWORD PTR DS:[EBX+66C]
004DC0D5 |. 83FE FF CMP ESI,-1
004DC0D8 |. 75 12 JNZ SHORT ss.004DC0EC
004DC0DA |. BA 64C14D00 MOV EDX,ss.004DC164; 0
004DC0DF >|. 8B83 58050000 MOV EAX,DWORD PTR DS:[EBX+558]
; *Label17:Tlabel
面对这么多代码,我开始有点迷茫。但不要忘记,我们是在动态分析,经过多次的失败尝试后,可以定位到“004DC0BA 7C 7B JL SHORT ss.004DC137”这个关键语句,只要改“JL”为“JG”,时间限制就自然突破了!保存文件运行一下,呵呵,成功啦!
破解Delphi软件最好用DeDe配合OD使用,可以事半功倍!还有,脱壳的时候要注意一些基本概念的运用,比如“堆栈平衡”等,只有这样,破解的时候才能游刃有余
上一篇: 还我胳膊
下一篇: 为什么男生追到一半就不追了?
推荐阅读