【文章标题】: crackmes.de上的一个CM
【文章作者】: qianyicy
【下载地址】: 己上传
【保护方式】: 无
【编写语言】: VB6.0
【使用工具】: OllyDbg
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
用ollydbg载入,输入用户名"qianyicy"密码"74747474"
习惯性的先看下有什么可用的字符串吧,ok,找到个"Nice,now code a KeyGen"双击,我们来到:
00405FA5 . FFD6 call esi ; <&MSVBVM60.__vbaVarDup>
00405FA7 . 8D95 88FEFFFF lea edx,dword ptr ss:[ebp-178]
00405FAD . 8D8D 18FFFFFF lea ecx,dword ptr ss:[ebp-E8]
00405FB3 . C785 90FEFFFF A0>mov dword ptr ss:[ebp-170],KeyGenMe.004044A0 ; UNICODE "Nice, now code a KeyGen"
00405FBD . 899D 88FEFFFF mov dword ptr ss:[ebp-178],ebx
00405FC3 . FFD6 call esi
向上走,可以找到MSVBVM60.__vbaStrCmp这个函数,初步估计是真码和假码在此进行比较,不相等则跳错误处,
00405F27 > \8B45 90 mov eax,dword ptr ss:[ebp-70]
00405F2A . 8B4D D0 mov ecx,dword ptr ss:[ebp-30]
00405F2D . 50 push eax
00405F2E . 51 push ecx
00405F2F . FF15 78104000 call dword ptr ds:[<&MSVBVM60.__vbaStrCmp>] ; MSVBVM60.__vbaStrCmp
00405F35 . 8BF0 mov esi,eax
在00405F2E处下断试试手气,F9运行:OK断下来了,看看右边的数据窗口,出现了什么?
EAX 0016289C UNICODE "74747474"
ECX 00176F84 UNICODE "XT9285-DMC530-PW4058-A042TP-FI9028-0588AK"
EDX 01030608
EBX 733B48DF MSVBVM60.rtcMidCharBstr
ESP 0013F2E0
EBP 0013F508
ESI 010413F4
EDI 73491073 MSVBVM60.__vbaFreeVarList
EIP 00405F2E KeyGenMe.00405F2E
呵,看来运气不错,真码出来了,UNICODE "XT9285-DMC530-PW4058-A042TP-FI9028-0588AK"
OK下面我们来找找他的算法,写个注册机试试,
先看下他有些什么可利用的函数,不过,看到注册码这个形式,我初步判断是用了字符串连接函数,vbaStrCat,在这个函数上下
断,再试下手气,^_^
重新载入,F9运行,清除三个断点后,CM跳出来了,输入用户名注册码,OK,再次被我们断了下来,看来,运气真的不错....
00405C24 . FFD6 call esi
00405C26 . 8B3D 30104000 mov edi,dword ptr ds:[<&MSVBVM60.__vbaStrCat>>; MSVBVM60.__vbaStrCat
00405C2C . 50 push eax
00405C2D . FFD7 call edi ; <&MSVBVM60.__vbaStrCat>
00405C2F . 8BD0 mov edx,eax
00405C31 . 8D4D 84 lea ecx,dword ptr ss:[ebp-7C]
00405C34 . FFD6 call esi
00405C36 . 50 push eax
00405C37 . 68 98444000 push KeyGenMe.00404498
这时右边数据窗口里显示
EAX 00176FD4 UNICODE "285"
ECX 0013F490
EDX 00176FD4 UNICODE "285"
EBX 733B48DF MSVBVM60.rtcMidCharBstr
MSVBVM60.rtcMidCharBstr这个函数的作用是在特定字符串中取特定字符,
向上走几步可以看见程序多次吊用call ebx(rtcMidCharBstr)这个函数
00405BE3 . 51 push ecx
00405BE4 . 52 push edx
00405BE5 . 50 push eax
00405BE6 . 89BD B8FEFFFF mov dword ptr ss:[ebp-148],edi
00405BEC . 89BD A8FEFFFF mov dword ptr ss:[ebp-158],edi
00405BF2 . 89BD 98FEFFFF mov dword ptr ss:[ebp-168],edi
00405BF8 . FFD3 call ebx ; <&MSVBVM60.#631>
00405BFA . 8BD0 mov edx,eax
00405BFC . 8D4D 8C lea ecx,dword ptr ss:[ebp-74]
00405BFF . FFD6 call esi
00405C01 . 0FBF55 E4 movsx edx,word ptr ss:[ebp-1C]
00405C05 . 8D8D 08FFFFFF lea ecx,dword ptr ss:[ebp-F8]
00405C0B . 50 push eax
00405C0C . 51 push ecx
00405C0D . 8D45 A0 lea eax,dword ptr ss:[ebp-60]
00405C10 . 52 push edx
00405C11 . 8D4D 90 lea ecx,dword ptr ss:[ebp-70]
00405C14 . 50 push eax
00405C15 . 51 push ecx
00405C16 . FF15 B4104000 call dword ptr ds:[<&MSVBVM60.__vbaStrVarVal>>; MSVBVM60.__vbaStrVarVal
00405C1C . 50 push eax
00405C1D . FFD3 call ebx
00405C1F . 8BD0 mov edx,eax
00405C21 . 8D4D 88 lea ecx,dword ptr ss:[ebp-78]
00405C24 . FFD6 call esi
00405C26 . 8B3D 30104000 mov edi,dword ptr ds:[<&MSVBVM60.__vbaStrCat>>; MSVBVM60.__vbaStrCat
我们把断点向上移下试试,在00405BE3 . 51 push ecx这里下断
再次载入,F9运行,断下来后,看下右边的数据窗口,嘿嘿,又有了好东西,
EAX:
MRZLB1CA042TPSYJHVKEDGU8635X7WN9TB0S3DZG6ELU5J2MY74H9N8ARPX1VCKWRPD3UYZK1X49VA7TBGNLH0JC8W6S25MELJV7KUN3206B
8DMCXT9PW4GHE5YRA1SZ5TN8Z6GK23LDCMEBA4VH91UW0P7JRSXYU4P7Y6HBEL3SJ98AGCN502ZDVWKMRX1TZJ7S3PERN5X29GVL8DBMTY0A
W64CH1UKSVBX8A05H247RZ13DWNUC6JY9GPTEMLK
EAX为指字符串,EDX通过运算取字符串特定位置的字符,通过跟进(00405BF8 . FFD3 call ebx)
可知:具体运算为edx*2-2=X, 从字符串(X/2+1)位置起,一次性取三个字符
继续跟进,直到00405C1C:push eax,我们又可以发现另一组字符:
EAX:
ZHDGTERAFDRDHHFH46FN38DFC32JC83JC8932KX9299DJOA92JAPD192EA3RUJCW903RUAIJF39RFJJFIJW85SIOIFJW390U32IOJSLKFJ32
42058W09FI902853095890588AKIDJFAWE8UTRQ3845QF456E4F5A64F65AE4F654564FS564RF65S4RG65S4H65S4JH65456W3TGIOSUB89
5SUAOSV?YFAUIEJFA?PWIOERFJAWIOEFJWIOEFJW
好了,到此,关键两组字符己经出来了,我们现在要搞清楚的就是取字符串特定位置的值是如何来的,搞清楚这点的话,就可以
写注册机了,
我们从断点处向上走,
00405BB9 . 0FBF55 E8 movsx edx,word ptr ss:[ebp-18]
值是从ss:[ebp-18]这来的,我们跟进到内存地址看看,
0013F4D0 00 6F 00 00 00 o...
0013F4E0 74 00 00 00 7B 00 00 00 6E 00 00 00 79 00 00 00 t...{...n...y...
0013F4F0 71 00 00 00 q...
如果开始你有向下继续跟几个call ebx的话,可以发现,取特定位置字符的数字就是o...t...{...n...y...q...这几个在起作
用:
把断点继续向上推,多试几次,注意看0013f4f0,(别怕麻烦,破解简直就是麻烦的代名词)直到我们来到:
00405AD9 . 51 push ecx
00405ADA . FFD3 call ebx ; 得第一位的ascii码; <&MSVBVM60.#516>
00405ADC . 8B55 C0 mov edx,dword ptr ss:[ebp-40] ; 注册名最后一位地址送edx
00405ADF . 8945 E8 mov dword ptr ss:[ebp-18],eax ; 注册名第一位送0013F4F0
00405AE2 . 52 push edx
00405AE3 . FFD3 call ebx
00405AE5 . 8945 E4 mov dword ptr ss:[ebp-1C],eax ; 注册名最后一位送0013F4EC
00405AE8 . 8B45 C8 mov eax,dword ptr ss:[ebp-38]
00405AEB . 50 push eax
00405AEC . FFD3 call ebx ; 得到注册名第一位ascii码设为x
00405AEE . 8B4D C0 mov ecx,dword ptr ss:[ebp-40] ; 注册名最后一位送ECX,设其ascii码为y
00405AF1 . 66:2D 0300 sub ax,3 ; x-3
00405AF5 . 0F80 04070000 jo KeyGenMe.004061FF ; 基本不会跳,如果是地球人的话
00405AFB . 51 push ecx
00405AFC . 8945 E0 mov dword ptr ss:[ebp-20],eax ; 把x-3送0013F4EB
00405AFF . FFD3 call ebx ; 得最后一位的ascii码
00405B01 . 8B55 C8 mov edx,dword ptr ss:[ebp-38]
00405B04 . 66:03C7 add ax,di ; y+2
00405B07 . 0F80 F2060000 jo KeyGenMe.004061FF ; 基本不会跳,如果是地球人的话
00405B0D . 52 push edx
00405B0E . 8945 DC mov dword ptr ss:[ebp-24],eax ; 把y-2送0013F4E4
00405B11 . FFD3 call ebx ; 得第一位的ascii码
00405B13 . 66:05 0300 add ax,3 ; x+3
00405B17 . 8D4D 90 lea ecx,dword ptr ss:[ebp-70]
00405B1A . 0F80 DF060000 jo KeyGenMe.004061FF ; 基本不会跳,如果是地球人的话
00405B20 . 8945 D8 mov dword ptr ss:[ebp-28],eax ; 把x+3送0013F4E0
00405B23 . 8D45 B0 lea eax,dword ptr ss:[ebp-50]
00405B26 . 50 push eax
00405B27 . 51 push ecx
00405B28 . FF15 B4104000 call dword ptr ds:[<&MSVBVM60.__vbaStrVarVal>; MSVBVM60.__vbaStrVarVal
00405B2E . 50 push eax
00405B2F . FFD3 call ebx ; 得第一位的ascii码
00405B31 . 66:2BC7 sub ax,di ; x-2
00405B34 . 8D4D 90 lea ecx,dword ptr ss:[ebp-70]
00405B37 . 0F80 C2060000 jo KeyGenMe.004061FF ; 基本不会跳,如果是地球人的话
00405B3D . 8945 D4 mov dword ptr ss:[ebp-2C],eax ; 把x-2送0013F4DC
00405B40 . FF15 1C114000 call dword ptr ds:[<&MSVBVM60.__vbaFreeStr>] ; MSVBVM60.__vbaFreeStr
00405B46 . 8B55 C8 mov edx,dword ptr ss:[ebp-38]
00405B49 . 52 push edx
00405B4A . FFD3 call ebx ; 得第一位的ascii码
00405B4C . 66:05 0400 add ax,4 ; x+4
00405B50 . 0F80 A9060000 jo KeyGenMe.004061FF ; 基本不会跳,如果是地球人的话
00405B56 . 8945 C4 mov dword ptr ss:[ebp-3C],eax ; 把x-2送0013F4CC
00405B59 . 8B45 C0 mov eax,dword ptr ss:[ebp-40]
00405B5C . 50 push eax
00405B5D . FFD3 call ebx ; 得最后一位的ascii码
00405B5F . 66:05 0900 add ax,9 ; y+9
00405B63 . 89BD 18FFFFFF mov dword ptr ss:[ebp-E8],edi
00405B69 . 0F80 90060000 jo KeyGenMe.004061FF ; 基本不会跳,如果是地球人的话
00405B6F . 8945 98 mov dword ptr ss:[ebp-68],eax ; 把Y+9送0013F4A0
看下0013F4F0处,OK,到此,我们所需的数据全部出来了,我们再次理清下思路,准备写注册机吧~~!
算法:
s1:
MRZLB1CA042TPSYJHVKEDGU8635X7WN9TB0S3DZG6ELU5J2MY74H9N8ARPX1VCKWRPD3UYZK1X49VA7TBGNLH0JC8W6S25MELJV7KUN3206B
8DMCXT9PW4GHE5YRA1SZ5TN8Z6GK23LDCMEBA4VH91UW0P7JRSXYU4P7Y6HBEL3SJ98AGCN502ZDVWKMRX1TZJ7S3PERN5X29GVL8DBMTY0A
W64CH1UKSVBX8A05H247RZ13DWNUC6JY9GPTEMLK
s2:
ZHDGTERAFDRDHHFH46FN38DFC32JC83JC8932KX9299DJOA92JAPD192EA3RUJCW903RUAIJF39RFJJFIJW85SIOIFJW390U32IOJSLKFJ32
42058W09FI902853095890588AKIDJFAWE8UTRQ3845QF456E4F5A64F65AE4F654564FS564RF65S4RG65S4H65S4JH65456W3TGIOSUB89
5SUAOSV?YFAUIEJFA?PWIOERFJAWIOEFJWIOEFJW
1)
注册名第一位的ascii码=x,通过(x*2-2)/2+1,取s1三个字符 & 注册名最后一位的ascii码=y,通过(y*2-2)/2+1,取s2三个字符,
构成第一组注册码,
2)
注册名第一位的ascii码-3=x,通过(x*2-2)/2+1,取s1三个字符 & 注册名最后一位的ascii码+2=x,通过(x*2-2)/2+1,取s2三个
字符,构成第二组注册码,
3)
注册名第一位的ascii码+3=x,通过(x*2-2)/2+1,取s1三个字符 & 注册名第一位的ascii码-2=x,通过(x*2-2)/2+1,取s2三个字
符,构成第三组注册码,
4)
计算注册名长度,设为x,取s1字符串x处6个字符,构成第四组注册码 (通过跟踪很容易得知)
5)
注册名第一位的ascii码+4=x,取s2字符串x处6个字符,构成第五组注册码 (通过F7跟进该处的call ebx可知)
6)
注册名最后一位的ascii码+9=x,取s2字符串x处6个字符,构成第六组注册码
每组注册码用"-"相连,即得最终注册码,
用户名:qianyicy
注册码:XT9285-DMC530-PW4058-A042TP-FI9028-0588AK
VB源码己丢,下面只附上CM和注册机,请见谅,看下表,到23:40了,该睡觉了,各位玩得开心
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2007年07月01日 23:47:01
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)