首页
社区
课程
招聘
[原创]对crackmes.de上的一个CM的分析
发表于: 2007-7-2 09:55 6633

[原创]对crackmes.de上的一个CM的分析

2007-7-2 09:55
6633

【文章标题】: 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期)

上传的附件:
收藏
免费 7
支持
分享
最新回复 (3)
雪    币: 164
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
vb的真麻烦,厉害,佩服……
2007-7-2 10:28
0
雪    币: 228
活跃值: (11)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
3
学习了!VB的程序……
2007-7-2 15:16
0
雪    币: 239
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
我也试试,学习
2010-1-26 23:46
0
游客
登录 | 注册 方可回帖
返回
//