首页
社区
课程
招聘
[原创]Key_Gen_Me_3算法详细分析
发表于: 2005-12-26 16:20 5604

[原创]Key_Gen_Me_3算法详细分析

2005-12-26 16:20
5604

【原创】Key_Gen_Me_3算法详细分析
【作者】WindayJiang
【破解声明】纯粹学习,算法简单,适合新手学习
【破解工具】OLLDBG
【破解难度】EASY
【软件保护】SN
【软件下载】附件:kengen.rar

这篇文章我打算写得详细点,希望借此能或多或少扫一扫大家对VB破解的雾区,写得不一定好,只望抛砖引玉罢了!

有兴趣了解VB破解的可以结合我之前的VB破解文章对比学习一下
http://bbs.pediy.com/showthread.php?s=&threadid=19703

好了,开工!

运行CRACKME,我们知道它不会把结果用对话框显示,取而代之的是写一个FEEDBACK.TXT到程序所在目录。所以不能用RTCMSGBOX,要用FILEOPE

N。用OD载入,ALT+E到模块MSVBVM60,CTRL+N查找参考,在__VBAFILEOPEN处下断,F9运行程序后中断取消断点,ALT+F9返回程序领空:

004058D8  CALL DWORD PTR DS:[<&MSVBVM60.__vbaFileO>;  MSVBVM60.__vbaFileOpen                //中断在这里
004058DE  LEA EAX,DWORD PTR SS:[EBP-28]
004058E1  PUSH EAX
004058E2  LEA ECX,DWORD PTR SS:[EBP-24]
004058E5  PUSH ECX
004058E6  PUSH 2
004058E8  CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeS>;  MSVBVM60.__vbaFreeStrList
004058EE  ADD ESP,0C
004058F1  LEA ECX,DWORD PTR SS:[EBP-38]
004058F4  CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeO>;  MSVBVM60.__vbaFreeObj
004058FA  MOV DWORD PTR SS:[EBP-4],9
00405901  PUSH Key_Gen_.00403878                   ;  UNICODE "You are incorrect! Try Again!"  //记事本写入此字串!

我们向上找一下,如你非要向下找的话,你会找到VBAEND,那是程序退出的函数来的,所以该向上找:
00405697  MOV DWORD PTR SS:[EBP-E4],Key_Gen_.00403>;  UNICODE "You are correct!"                //看到了吧?
004056A1  MOV DWORD PTR SS:[EBP-EC],8
004056AB  MOV DWORD PTR SS:[EBP-F4],Key_Gen_.00403>;  UNICODE "I cant believe it! "
004056B5  MOV DWORD PTR SS:[EBP-FC],8
004056BF  MOV DWORD PTR SS:[EBP-104],Key_Gen_.0040>;  UNICODE "Wait For crack me 4."
004056C9  MOV DWORD PTR SS:[EBP-10C],8
004056D3  MOV DWORD PTR SS:[EBP-114],Key_Gen_.0040>;  UNICODE "You cant solve that!"
.......再向上
004054A9  CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarTs>;  MSVBVM60.__vbaVarTstEq                        //是用变量比较
.......再向上
00405262  CALL DWORD PTR DS:[<&MSVBVM60.#611>]     ;  MSVBVM60.rtcGetTimeBstr                        //我最终选择在这里下断

..............................................

再重新运行程序后来到这里:
00405262  CALL DWORD PTR DS:[<&MSVBVM60.#611>]         ;  MSVBVM60.rtcGetTimeBstr//获取当前时间
00405268  MOV EDX,EAX                                  ;  //EAX是时间
0040526A  LEA ECX,DWORD PTR SS:[EBP-30]                ;  //缓冲区
0040526D  CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrMove>] ;  MSVBVM60.__vbaStrMove//移动字串
00405273  CALL DWORD PTR DS:[<&MSVBVM60.#609>]         ;  MSVBVM60.rtcGetDateBstr//获取当前日期
00405279  MOV EDX,EAX                                  ;  //EAX是日期
0040527B  LEA ECX,DWORD PTR SS:[EBP-34]                ;  //缓冲区
0040527E  CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrMove>] ;  MSVBVM60.__vbaStrMove//移动字串

.............................................

F8来到这里:
004052FE  MOV EAX,DWORD PTR SS:[EBP-24]                ;  //注册码到EAX
00405301  MOV DWORD PTR SS:[EBP-168],EAX               ;  //注册码放到[EBP-168]
00405307  MOV DWORD PTR SS:[EBP-24],0                  ;  //把原来的地址清空
0040530E  MOV ECX,DWORD PTR SS:[EBP-168]               ;  //注册码放到ECX
00405314  MOV DWORD PTR SS:[EBP-C4],ECX                ;  //注册码又写到[EBP-C4]
0040531A  MOV DWORD PTR SS:[EBP-CC],8008               ;  // 参数

这里一连串几个MOV,是初始化变量、参数等等为后来的算法做好准备

.............................................
F8来到这里:
0040539E  MOV EAX,DWORD PTR SS:[EBP-28]                ;  //用户名到EAX
004053A1  PUSH EAX                                     ;  //入栈
004053A2  CALL DWORD PTR DS:[<&MSVBVM60.#516>]         ;  MSVBVM60.rtcAnsiValueBstr//转换为ASCII码
004053A8  ADD AX,1                                     ;  //这里看得很清楚,第一个字符+1
004053AC  JO Key_Gen_.00405B4A
004053B2  MOVSX ECX,AX                 ;  //放到ECX
004053B5  PUSH ECX                                     ;  //入栈
004053B6  LEA EDX,DWORD PTR SS:[EBP-4C]                ;  //缓冲区地址
004053B9  PUSH EDX                                     ;  //入栈
004053BA  CALL DWORD PTR DS:[<&MSVBVM60.#608>]         ;  MSVBVM60.rtcVarBstrFromAnsi//转换ASCII码
004053C0  MOV EAX,DWORD PTR SS:[EBP-30]                ;  //时间到EAX
004053C3  MOV DWORD PTR SS:[EBP-16C],EAX               ;  //时间 ->ebp-16c
004053C9  MOV DWORD PTR SS:[EBP-30],0                  ;  //原来的清空
004053D0  MOV ECX,DWORD PTR SS:[EBP-16C]               ;  //时间到ECX
004053D6  MOV DWORD PTR SS:[EBP-54],ECX                ;  //放到EBP-54
004053D9  MOV DWORD PTR SS:[EBP-5C],8                  ;  //参数
004053E0  PUSH 2                                       ;  //参数2入栈,重要!
004053E2  LEA EDX,DWORD PTR SS:[EBP-5C]                ;  //时间缓冲区
004053E5  PUSH EDX                                     ;  //入栈
004053E6  LEA EAX,DWORD PTR SS:[EBP-6C]                ;  //缓冲区地址
004053E9  PUSH EAX                                     ;  //缓冲区入栈
004053EA  CALL DWORD PTR DS:[<&MSVBVM60.#619>]         ;  MSVBVM60.rtcRightCharVar//向时间右取2位字符
004053F0  MOV ECX,DWORD PTR SS:[EBP-34]                ;  //日期到ECX
004053F3  MOV DWORD PTR SS:[EBP-170],ECX               ;  //再存到EBP-170
004053F9  MOV DWORD PTR SS:[EBP-34],0                  ;  //原来地址清空
00405400  PUSH 2                                       ;  //参数2入栈
00405402  MOV EDX,DWORD PTR SS:[EBP-170]               ;  //EDX是日期
00405408  LEA ECX,DWORD PTR SS:[EBP-2C]                ;  //准备移动到的地址
0040540B  CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrMove>] ;  MSVBVM60.__vbaStrMove//字串移动
00405411  PUSH EAX                                     ;  //日期入栈
00405412  CALL DWORD PTR DS:[<&MSVBVM60.#618>]         ;  MSVBVM60.rtcRightCharBstr//向日期右取2位
00405418  MOV DWORD PTR SS:[EBP-84],EAX                ;  //日期右2位存到EBP-84
0040541E  MOV DWORD PTR SS:[EBP-8C],8                  ;
00405428  MOV DWORD PTR SS:[EBP-E4],Key_Gen_.004036F8  ;  UNICODE "Grand-Theft-Auto-Vice-City"
00405432  MOV DWORD PTR SS:[EBP-EC],8                  ;
0040543C  MOV DWORD PTR SS:[EBP-F4],Key_Gen_.00403734  ;  UNICODE "bbidhan-ThE-Great"
00405446  MOV DWORD PTR SS:[EBP-FC],8                  ;
.......................................................; 上面又是初始化
00405450  LEA EDX,DWORD PTR SS:[EBP-CC]                ;  //注册码的缓冲区
00405456  PUSH EDX
00405457  LEA EAX,DWORD PTR SS:[EBP-4C]                ;  //计算过的第一个字符
0040545A  PUSH EAX
0040545B  LEA ECX,DWORD PTR SS:[EBP-6C]                ;  //时间右2位
0040545E  PUSH ECX
0040545F  LEA EDX,DWORD PTR SS:[EBP-7C]                ;  //缓冲区
00405462  PUSH EDX
00405463  CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarCat>]  ;  MSVBVM60.__vbaVarCat//连接字符串
00405469  PUSH EAX                                     ;  //新字串缓冲区
0040546A  LEA EAX,DWORD PTR SS:[EBP-8C]
00405470  PUSH EAX                                     ;  //日期右2位的缓冲区
00405471  LEA ECX,DWORD PTR SS:[EBP-9C]
00405477  PUSH ECX                                     ;  //缓冲区
00405478  CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarCat>]  ;  MSVBVM60.__vbaVarCat//连接字符串
0040547E  PUSH EAX                                     ;  //新字串缓冲区
0040547F  LEA EDX,DWORD PTR SS:[EBP-EC]
00405485  PUSH EDX                                     ;  //“Grand-Theft-Auto-Vice-City”缓冲区
00405486  LEA EAX,DWORD PTR SS:[EBP-AC]
0040548C  PUSH EAX                                     ;  //缓冲区
0040548D  CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarCat>]  ;  MSVBVM60.__vbaVarCat//连接字符串
00405493  PUSH EAX                                     ;  //新字串缓冲区
00405494  LEA ECX,DWORD PTR SS:[EBP-FC]
0040549A  PUSH ECX                                     ;  //"bbidhan-ThE-Great"缓冲区
0040549B  LEA EDX,DWORD PTR SS:[EBP-BC]
004054A1  PUSH EDX                                     ;  //缓冲区
004054A2  CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarCat>]  ;  MSVBVM60.__vbaVarCat//连接字符串
004054A8  PUSH EAX                                     ;  //新字串缓冲区
004054A9  CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarTstEq>>;  MSVBVM60.__vbaVarTstEq//变量比较
004054AF  MOV WORD PTR SS:[EBP-150],AX                 ;  //比较后的标志值放到EBP-150

.......................................................
004054B6  LEA EAX,DWORD PTR SS:[EBP-34]
004054B9  PUSH EAX
004054BA  LEA ECX,DWORD PTR SS:[EBP-30]
004054BD  PUSH ECX
004054BE  LEA EDX,DWORD PTR SS:[EBP-2C]
004054C1  PUSH EDX
004054C2  LEA EAX,DWORD PTR SS:[EBP-28]
004054C5  PUSH EAX
004054C6  PUSH 4
004054C8  CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeStrLi>;  MSVBVM60.__vbaFreeStrList
004054CE  ADD ESP,14
004054D1  LEA ECX,DWORD PTR SS:[EBP-3C]
004054D4  PUSH ECX
004054D5  LEA EDX,DWORD PTR SS:[EBP-38]
004054D8  PUSH EDX
004054D9  PUSH 2
004054DB  CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeObjLi>;  MSVBVM60.__vbaFreeObjList
004054E1  ADD ESP,0C
004054E4  LEA EAX,DWORD PTR SS:[EBP-BC]
004054EA  PUSH EAX
004054EB  LEA ECX,DWORD PTR SS:[EBP-CC]
004054F1  PUSH ECX
004054F2  LEA EDX,DWORD PTR SS:[EBP-AC]
004054F8  PUSH EDX
004054F9  LEA EAX,DWORD PTR SS:[EBP-9C]
004054FF  PUSH EAX
00405500  LEA ECX,DWORD PTR SS:[EBP-8C]
00405506  PUSH ECX
00405507  LEA EDX,DWORD PTR SS:[EBP-7C]
0040550A  PUSH EDX
0040550B  LEA EAX,DWORD PTR SS:[EBP-6C]
0040550E  PUSH EAX
0040550F  LEA ECX,DWORD PTR SS:[EBP-4C]
00405512  PUSH ECX
00405513  LEA EDX,DWORD PTR SS:[EBP-5C]
00405516  PUSH EDX
00405517  PUSH 9
00405519  CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeVarLi>;  MSVBVM60.__vbaFreeVarList
0040551F  ADD ESP,28

上面一大段作释放字串、对象、变量动作,这些在破解时快速略过

..................................................................
00405522  MOVSX EAX,WORD PTR SS:[EBP-150]              ;  //把标志取出来
00405529  TEST EAX,EAX                                 ;  //比较
0040552B  JE Key_Gen_.004057C2                         ;  //等于0就GAMEOVE

算法总结一下:
(第一个字串ASC码+1)&时间右2位&日期右2位&Grand-Theft-Auto-Vice-City&bbidhan-ThE-Great

注册机我不会写,因为时间是变动的,程序中运行获取到的时间绝不可能跟我手动输入的时间相吻,估计要用到一些其他函数,我没有去仔细

想。我只要想了解一下VB的函数在汇编下是如何操作的。

VB破解再总结一下:
1. 由于VB的特殊,会用到大量内存寻址,这会令你觉得很头晕,如果你实在记性不好,建议你拿笔记下一些关键的内存地址,如[EBP-7C]什

么的等等

2. 遇到VBAFREEXXXLIST语句之前的LEA、PUSH,不要耗力气了,人家都处理完了,你看他释放内存有什么用呢??

3. 熟悉一下函数调用前什么参数入栈了

4. 还是那句话:耐心。对付VB,急也急不来!!

这是我本年度最后一篇文章了,谢谢观赏!C U NEXT YEAR!

////////////////////////////////////////////////////////////////
If you want to crack well, learn ASM well !

WiNDaYJiANg       2005-12-26
////////////////////////////////////////////////////////////////


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 7
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//