思维的逆境转移——智破NO1 Video Converter 4.1.37
文/图 Hokkien
===================================
不可否认,算法分析是一项耐力与信心的折磨。笔者做算法分析的时间也不算短,面对形形色色的算法折磨,能挺过去的固然是好,不能挺过去的也只有中途*放弃。本文是笔者在逆境中转换角度思考的典型例子,相信看了本文,大家会有所收获的。
认识软件
#1 Video Converter是一款视频格式转换软件,支持所有格式的转换,简单易用,感觉相当不错。但可惜的是一款共享软件,不注册时只能转化部分文件。我们今天就来解禁它。
通过软件查壳显示使用VC++编译,整体感知,软件用MFC编写,这给分析软件增加了一定的难度。先说明一下,该软件可以爆破,但爆破不是我们的主题。
跟踪过程
打开注册窗口,试探性地输入假信息,如图1所示,结果当然会报错,顺着出错提示,我们很容易定位到如下的代码处。
图1
0041D2E8 . 68 98A64300 PUSH #1_Video.0043A698
;sorry
0041D2ED . 68 6CA64300 PUSH #1_Video.0043A66C
; invalid username or registration code sorry
在上面随便找个位置下断点,重新调试,软件被断在如下地方。
0041D291 . E8 FABA0000 CALL <JMP.&MFC42.#540_??0CString@@QAE@XZ>
0041D296 . 6A 01 PUSH 1
0041D298 . 8BCE MOV ECX,ESI
0041D29A . C74424 20 000>MOV DWORD PTR SS:[ESP+20],0
0041D2A2 E869BF0000
CALL <JMP.&MFC42.#6334_?UpdateData@CWnd@@QAEHH@Z>
0041D2A7 E8B2BF0000
CALL <JMP.&MFC42.#1168_?AfxGetModuleState@@YGPAVAFX_MODULE_>
看到这里,大家应该知道软件是采用MFC编写的,这给我们的跟踪增加了很大的难度。点击F8来到下面的代码处。
0041D2D8 . 50 PUSH EAX ;注册码
0041D2D9 . 51 PUSH ECX ;用户名
0041D2DA . E8 81FAFFFF CALL #1_Video.0041CD60
0041D2DF . 83C4 08 ADD ESP,8
0041D2E2 . 85C0 TEST EAX,EAX
0041D2E4 . 75 18 JNZ SHORT #1_Video.0041D2FE
0041D2E6 . 6A 40 PUSH 40
0041D2E8 . 68 98A64300 PUSH #1_Video.0043A698
;sorry
0041D2ED . 68 6CA64300 PUSH #1_Video.0043A66C
;invalid username or registration code sorry
很明显,“CALL #1_Video.0041CD60”是关键。原本以为定位到关键函数应该差不多了,但没有料想的这么简单。我们步入0041CD60会发现代码真是海量,好像有用的信息不多,但我们还是可以找到下面的几个数字,不知道算不算有用信息。
0041CD89 |. C74424 60 73C>MOV DWORD PTR SS:[ESP+60],3C49C573
0041CD91 |. C74424 64 0C4>MOV DWORD PTR SS:[ESP+64],7A5A460C
0041CD99 |. C74424 68 388>MOV DWORD PTR SS:[ESP+68],79768038
0041CDA1 |. C74424 6C 67B>MOV DWORD PTR SS:[ESP+6C],8E8DBE67
0041CDA9 |. C74424 70 A62>MOV DWORD PTR SS:[ESP+70],723026A6
0041CDB1 |. C74424 74 2E8>MOV DWORD PTR SS:[ESP+74],96C1812E
0041CDB9 |. C74424 78 07C>MOV DWORD PTR SS:[ESP+78],602C507
0041CDC1 |. C74424 7C 571>MOV DWORD PTR SS:[ESP+7C],230D1157
好像是什么专门的加密算法啊,百度一下,很遗憾,没有任何信息。由此我们可以推断,这些数字不是专门的加密算法的常数。当我们试图再跟踪下去的时候会发现,软件的流程非常的乱,很不清晰,而且生成注册码的关键位置不明确。因为时间与人力有限,我们陷入了僵局……放弃?还是继续?
柳暗花明
我们忍着继续跟踪下去,来到了下面的关键位置。
0041CFBB |. 50 PUSH EAX ;关键位置
0041CFBC |. 51 PUSH ECX ;用户名地址
0041CFBD |. FFD6 CALL ESI ;比较
0041CFBF |. 83C4 08 ADD ESP,8
0041CFC2 |. 8D4C24 10 LEA ECX,DWORD PTR SS:[ESP+10]
0041CFC6 |. 85C0 TEST EAX,EAX
0041CFC8 |. C68424 A40000>MOV BYTE PTR SS:[ESP+A4],6
0041CFD0 0F84 86000000 JE #1_Video.0041D05C
这里有个跳转,是对EAX赋不同的值,即标志位。凭经验,这个就是成败的关键。顺便说明一下,把“JE”改成“JNE”就可以爆破,但这不是我们的主题。这里是用户名与某一字符串进行比较,因而我们知道软件采用的注册模型是:“F(输入的注册码)?=输入的用户名”。现在我们已经知道了注册模型,那就转到EAX对应的地址看看,如图2所示。看到没有,注册码“12345abcde”对应的用户名是不可打印字符的。因而,如果我们试图通过任意输入注册码以获取用户名就遇到了很大的麻烦!又一次陷入了僵局……
图2
想了好一阵,有了!写个内存注册机,随便输入注册码,让它中断在相应处读取相应值,不就可以显示对应的用户名了吗?而我们再粘贴复制一下不就可以获得用户名了吗?呵呵,让我们有请KeyMake。在0041CFBB下断,读取此时的EAX对应地址的内容。配置如图3所示。生成注册机后,放到与软件同一目录下,在INI文件中随便输入用户名与注册码,运行注册机,如图4所示。
图3
图4
呵呵,很奇怪的字符啊。不过不要紧,我们复制它,然后在注册窗口的用户名一栏粘贴,注册码就输入“12345abcde”,如图5所示。点OK,看看我们的杰作吧,如图6所示,呵呵,成功啦!
图5
图6
总结
面对诸多限制,如果能够换一种思维去破解,那么才能在算法的折磨中稍作喘息。该软件因为时间及人力的各方面限制,我没有好好地进行算法分析。但可喜的是,我从另一个角度接近完美地破解了这款软件,但愿这段小经历能对大家有点帮助