首页
社区
课程
招聘
[原创]再度出击,完美破解飘云阁的某个CM
发表于: 2009-3-20 14:37 16191

[原创]再度出击,完美破解飘云阁的某个CM

2009-3-20 14:37
16191

标 题: 【原创】再度出击,完美破解飘云阁的某个CM
作 者: 不问年少
时 间: 2009-03-20,14:30

中午无聊,决定再来练习逆向,无奈近日看雪CM版块过于冷清,无从练手。高手们也都休养生息,决不露面,让我等小菜无所适从,只好自力更生,艰苦奋斗了。 

在天草论坛中发现一CM(等等,怎么标题说是飘云阁的CM啊?呵呵,这是从破解软件以后才发现是飘云阁的),又是VB编写的,为克服自己对VB的畏惧感,于是操刀再向VB行! 
    
点击此CM,冒出个扎眼的Make in H&Y的窗口,上书:NAG 我晕!点确定后来到主窗口,输入用户名密码后,发现“确定”按钮不让人点,这肯定又是作者给我们留下的第二个难题吧。(猜测的,要不然作者就是……了,呵呵),废话少说,下面来进行完破: 
    
下断rtcMsgBox,返回后,将调用rtcMsg的CALL直接NOP掉,运行之,无碍,NAG已消失!

下断EnableWindow,返回后,将参数Push 0,改为Push 1,也就是改成EnableWindow(OkbuttonHandle, TRUE),这样,每二关就过了。

下断__vbaVarTstEq,点击运行,立即来到关键比较处:

00403C6D   .  52            push    edx                  ;  假码
00403C6E   .  50            push    eax                  ;  真码s
00403C6F   .  C745 A8 00000>mov     dword ptr [ebp-58], >
00403C76   .  C745 94 08800>mov     dword ptr [ebp-6C], >
00403C7D   .  FF15 60104000 call    dword ptr [<&MSVBVM6>;  MSVBVM60.__vbaVarTstEq
00403C83   .  8D4D A4       lea     ecx, dword ptr [ebp->;  将真假码比较
00403C86   .  8BF0          mov     esi, eax
00403C88   .  FF15 E4104000 call    dword ptr [<&MSVBVM6>;  MSVBVM60.__vbaFreeObj
00403C8E   .  8D4D 94       lea     ecx, dword ptr [ebp->
00403C91   .  FF15 10104000 call    dword ptr [<&MSVBVM6>;  MSVBVM60.__vbaFreeVar
00403C97   .  66:85F6       test    si, si               ;  测试比较结果
00403C9A   .  0F84 A3000000 je      00403D43             ;  跳走就完蛋了

输入403C6E处得到的真码,直接成功~!就这样过了三关,但是一点没有成就感啊,哎!要分析算法才能进步,不能只是简单暴破,于是乎,抖擞精神,再度出击 !

下面来分析算法,从关键点向上找到函数开始处:很明显是经典的VB函数开头, On Error ....,写过VB程序的人都知道。

00403730   > \55            push    ebp
00403731   .  8BEC          mov     ebp, esp
00403733   .  83EC 0C       sub     esp, 0C
00403736   .  68 36114000   push    <jmp.&MSVBVM60.__vbaExceptHandle>;  SE 处理程序安装
0040373B   .  64:A1 0000000>mov     eax, dword ptr fs:[0]
00403741   .  50            push    eax
00403742   .  64:8925 00000>mov     dword ptr fs:[0], esp
00403749   .  81EC 68010000 sub     esp, 168
0040374F   .  53            push    ebx
00403750   .  56            push    esi
00403751   .  57            push    edi
00403752   .  8965 F4       mov     dword ptr [ebp-C], esp
00403755   .  C745 F8 00114>mov     dword ptr [ebp-8], 00401100
0040375C   .  8B75 08       mov     esi, dword ptr [ebp+8]
0040375F   .  8BC6          mov     eax, esi
00403761   .  83E0 01       and     eax, 1
....

继续向下跑:嘿嘿,为什么要说跑呢,对于VB,你不跑都不行啊,太多垃圾代码了!~来到这里,这是第1个计算,它计算了m的值,m是什么,自己看吧:

0040386F   .  51            push    ecx                              ;  计算用户名长度n
00403870   .  FF15 14104000 call    dword ptr [<&MSVBVM60.__vbaLenBs>;  MSVBVM60.__vbaLenBstr
00403876   .  6BC0 16       imul    eax, eax, 16                     ;  eax=n*16h
00403879   .  0F80 3C060000 jo      00403EBB
0040387F   .  05 29240000   add     eax, 2429                        ;  eax+=2429h
00403884   .  8D4D A8       lea     ecx, dword ptr [ebp-58]
00403887   .  0F80 2E060000 jo      00403EBB
0040388D   .  2D E8030000   sub     eax, 3E8                         ;  eax-=3E8h
00403892   .  0F80 23060000 jo      00403EBB
00403898   .  8985 84FEFFFF mov     dword ptr [ebp-17C], eax         ;  设Eax=m=len(username)*16h+2429h-3E8h
0040389E   .  DB85 84FEFFFF fild    dword ptr [ebp-17C]              ;  将eax转为整数载入
004038A4   .  DD5D B4       fstp    qword ptr [ebp-4C]               ;  保存m

看来 m = strlen(UserName)*0x16+0x2429-0x3E8;  //我用C语言描述,后面注册机用VB写, 这样更明了方便点。呵呵,再往后,过千山,涉万水,终于来到了计算注册码的第二部分: 

004039E2   .  FF15 34104000 call    dword ptr [<&MSVBVM60.__vbaVarFo>;  MSVBVM60.__vbaVarForInit
004039E8   .  8B1D 08104000 mov     ebx, dword ptr [<&MSVBVM60.__vba>;  MSVBVM60.__vbaVarMove
004039EE   .  8B35 1C104000 mov     esi, dword ptr [<&MSVBVM60.__vba>;  MSVBVM60.__vbaVarIdiv
004039F4   >  85C0          test    eax, eax
004039F6   .  0F84 7B010000 je      00403B77
004039FC   .  8B45 B0       mov     eax, dword ptr [ebp-50]          ;  得到用户名数组指针
004039FF   .  85C0          test    eax, eax
00403A01   .  74 33         je      short 00403A36

很明显,这是一个循环计算注册码开始处,经典的VB型 For... Next结构。再看:

00403A45   .  66:0FB60402   movzx   ax, byte ptr [edx+eax]           ;  取第i个用户名
00403A4A   .  8D95 00FFFFFF lea     edx, dword ptr [ebp-100]
00403A50   .  66:8985 08FFF>mov     word ptr [ebp-F8], ax
00403A57   .  89BD 00FFFFFF mov     dword ptr [ebp-100], edi
00403A5D   .  FFD3          call    ebx
00403A5F   .  8D4D BC       lea     ecx, dword ptr [ebp-44]
00403A62   .  8D95 00FFFFFF lea     edx, dword ptr [ebp-100]
00403A68   .  51            push    ecx
00403A69   .  8D45 94       lea     eax, dword ptr [ebp-6C]
00403A6C   .  52            push    edx
00403A6D   .  50            push    eax
00403A6E   .  C785 08FFFFFF>mov     dword ptr [ebp-F8], 6
00403A78   .  89BD 00FFFFFF mov     dword ptr [ebp-100], edi
00403A7E   .  C785 F8FEFFFF>mov     dword ptr [ebp-108], 4
00403A88   .  89BD F0FEFFFF mov     dword ptr [ebp-110], edi
00403A8E   .  C785 E8FEFFFF>mov     dword ptr [ebp-118], 0A
00403A98   .  89BD E0FEFFFF mov     dword ptr [ebp-120], edi
00403A9E   .  FFD6          call    esi                              ;  x=usernmae[i]/6
00403AA0   .  8D4D BC       lea     ecx, dword ptr [ebp-44]
00403AA3   .  50            push    eax                              ;  x
00403AA4   .  8D95 F0FEFFFF lea     edx, dword ptr [ebp-110]
00403AAA   .  51            push    ecx
00403AAB   .  8D45 84       lea     eax, dword ptr [ebp-7C]
00403AAE   .  52            push    edx
00403AAF   .  50            push    eax                              ;  y=username[i]/4
00403AB0   .  FFD6          call    esi
00403AB2   .  8D8D 74FFFFFF lea     ecx, dword ptr [ebp-8C]
00403AB8   .  50            push    eax
00403AB9   .  51            push    ecx                              ;  y*=x
00403ABA   .  FF15 74104000 call    dword ptr [<&MSVBVM60.__vbaVarMu>;  MSVBVM60.__vbaVarMul
00403AC0   .  50            push    eax                              ;  y
00403AC1   .  8D55 BC       lea     edx, dword ptr [ebp-44]
00403AC4   .  8D85 E0FEFFFF lea     eax, dword ptr [ebp-120]
00403ACA   .  52            push    edx
00403ACB   .  8D8D 64FFFFFF lea     ecx, dword ptr [ebp-9C]
00403AD1   .  50            push    eax
00403AD2   .  51            push    ecx                              ;  z=username[i]/=0ah
00403AD3   .  FFD6          call    esi
00403AD5   .  8D95 54FFFFFF lea     edx, dword ptr [ebp-AC]
00403ADB   .  50            push    eax                              ;  y/=z
00403ADC   .  52            push    edx
00403ADD   .  FFD6          call    esi
00403ADF   .  50            push    eax
00403AE0   .  FF15 D0104000 call    dword ptr [<&MSVBVM60.__vbaI2Err>;  MSVBVM60.__vbaI2ErrVar
00403AE6   .  66:8985 4CFFF>mov     word ptr [ebp-B4], ax
00403AED   .  8D85 44FFFFFF lea     eax, dword ptr [ebp-BC]
00403AF3   .  8D8D 34FFFFFF lea     ecx, dword ptr [ebp-CC]
00403AF9   .  50            push    eax
00403AFA   .  51            push    ecx
00403AFB   .  89BD 44FFFFFF mov     dword ptr [ebp-BC], edi
00403B01   .  FF15 C4104000 call    dword ptr [<&MSVBVM60.#613>]     ;  MSVBVM60.rtcVarStrFromVar
00403B07   .  8D95 34FFFFFF lea     edx, dword ptr [ebp-CC]          ;  将y转化为字串
00403B0D   .  8D85 24FFFFFF lea     eax, dword ptr [ebp-DC]
00403B13   .  52            push    edx
00403B14   .  50            push    eax
00403B15   .  FF15 48104000 call    dword ptr [<&MSVBVM60.#520>]     ;  MSVBVM60.rtcTrimVar
00403B1B   .  8D4D CC       lea     ecx, dword ptr [ebp-34]
00403B1B   .  8D4D CC       lea     ecx, dword ptr [ebp-34]          ;  去空格
00403B1E   .  8D95 24FFFFFF lea     edx, dword ptr [ebp-DC]
00403B24   .  51            push    ecx
00403B25   .  8D85 14FFFFFF lea     eax, dword ptr [ebp-EC]
00403B2B   .  52            push    edx
00403B2C   .  50            push    eax
00403B2D   .  FF15 C0104000 call    dword ptr [<&MSVBVM60.__vbaVarAd>;  MSVBVM60.__vbaVarAdd
00403B33   .  8BD0          mov     edx, eax                         ;  连接字串s+=y

再往下就是VB中For语句的结束标志 Next了,所以分析这个大循环的主要算法如下(伪代码,y没转化):
首先s = strcat(s, y),那么y呢, y = y*x/z的商, x = username[i]/6, y = username[i]/4, z = username[i]/10
呵呵,不要晕啊!这一步弄清了后面就简单多了!后面就是简单的字串连接操作了:

00403BB5   > \8B45 A8       mov     eax, dword ptr [ebp-58]          ;  -"PYG-"
00403BB8   .  8B4D B8       mov     ecx, dword ptr [ebp-48]
00403BBB   .  8B35 90104000 mov     esi, dword ptr [<&MSVBVM60.__vba>;  MSVBVM60.__vbaVarCat
00403BC1   .  8945 9C       mov     dword ptr [ebp-64], eax
00403BC4   .  8B45 B4       mov     eax, dword ptr [ebp-4C]
00403BC7   .  8D55 CC       lea     edx, dword ptr [ebp-34]
00403BCA   .  8985 08FFFFFF mov     dword ptr [ebp-F8], eax
00403BD0   .  898D 0CFFFFFF mov     dword ptr [ebp-F4], ecx
00403BD6   .  8D45 94       lea     eax, dword ptr [ebp-6C]
00403BD9   .  52            push    edx                              ;  将上面得到的结果y与-PYG-相连接
00403BDA   .  8D4D 84       lea     ecx, dword ptr [ebp-7C]          ;  设为s1
00403BDD   .  50            push    eax
00403BDE   .  51            push    ecx
00403BDF   .  C745 A8 00000>mov     dword ptr [ebp-58], 0
00403BE6   .  C745 94 08000>mov     dword ptr [ebp-6C], 8
00403BED   .  C785 00FFFFFF>mov     dword ptr [ebp-100], 5
00403BF7   .  FFD6          call    esi                              ;  <&MSVBVM60.__vbaVarCat>
00403BF9   .  50            push    eax                              ;  s1再与最先计算得到的m相连接,设为s
00403BFA   .  8D95 00FFFFFF lea     edx, dword ptr [ebp-100]
00403C00   .  8D85 74FFFFFF lea     eax, dword ptr [ebp-8C]
00403C06   .  52            push    edx
00403C07   .  50            push    eax
00403C08   .  FFD6          call    esi                              ;  EAX=s=计算后最终得到的真码

然后就是关键跳转处的比较了。呵呵!综上所述,可以得到注册算法如下,VB版的CM,当然用VB写注册机咯:)

Private Sub Command1_Click()
On Error GoTo Err:
Dim m As Long, x As Long, y As Long, z As Long, n As Long, s As String, i As Integer
m = Len(Username) * &H16 + &H2429 - &H3E8 '根据用户名计算的m值
For i = 1 To Len(Username)
    n = Asc(Mid(Username, i, 1))  '用户名的ASCII码
    x = (n - (n Mod 6)) / 6       '以下为了得到除以某数的整数部分,先减去多余的余数部分再进行相除
    z = (n - (n Mod 10)) / 10
    y = (n - (n Mod 4)) / 4
    y = y * x
    y = (y - (y Mod z)) / z
    s = s & y
Next
Codekey = s & "-PYG-" & m
Err:
End Sub

这样,这个CM的三关就被轻松拿下,完美破解了。我不知道有没有人分析过此CM,但这是我个人的心得,奉献给大家,愿大家和我一起进步! 
                                                                             
                                                                                                              
                                                                                                         by 不问年少


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (35)
雪    币: 1172
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
这么好的帖子居然没人顶!
2009-3-20 18:36
0
雪    币: 2575
活跃值: (502)
能力值: ( LV2,RANK:85 )
在线值:
发帖
回帖
粉丝
3
少年出英雄...
2009-3-20 18:44
0
雪    币: 2067
活跃值: (82)
能力值: ( LV9,RANK:180 )
在线值:
发帖
回帖
粉丝
4
只能学习...
2009-3-20 19:21
0
雪    币: 423
活跃值: (11)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
5
有点逆向和动态调试的感觉了。

逆向与编程的思维最大的不同:
逆向的精髓是寻求编程的漏洞,进行高效的攻击。
2009-3-21 08:12
0
雪    币: 1074
活跃值: (160)
能力值: ( LV13,RANK:760 )
在线值:
发帖
回帖
粉丝
6
  呵呵,多谢大侠们的捧场, 我应该向sessiondiy大侠学习才对!
2009-3-21 08:27
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
果然厉害!
只是看起来很好玩。。
2009-3-21 13:05
0
雪    币: 421
活跃值: (83)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
分析的透彻,偶还是一个简单的爆破手
你上面说的分析以外的事情差不多都能做到了
2009-3-21 15:25
0
雪    币: 261
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
9
怎么我的CM就那么多人分析呢?难到真的写的那么烂么!看来以后都是小心为上!
2009-3-22 14:55
0
雪    币: 1027
活跃值: (256)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
10
学习了,身在高手云集的地方啊。。。
2009-3-22 15:57
0
雪    币: 216
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
楼主厉害,学习中!
2009-3-22 18:14
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
呵呵,楼主,最近活跃的厉害
2009-3-23 09:22
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
大大,请问在那里可以下断EnableWindow的,
我在commandbar打bpx EnableWindow没有反应的?
2009-3-23 23:20
0
雪    币: 1074
活跃值: (160)
能力值: ( LV13,RANK:760 )
在线值:
发帖
回帖
粉丝
14
软件是有流程的,先破消息窗口,再破禁按钮,这样就有“反应”了,注意要返回程序领空
2009-3-24 10:31
0
雪    币: 563
活跃值: (95)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
分析的好详细
2009-3-25 13:14
0
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
真好的文章。可我还是很不明白。。下断rtcMsgBox 这个是什么函数啊。00403AAF   .  50            push    eax                              ;  y=username[i]/4
怎么就知道是      /4         最后——————我换不了行为什么。(如何发现经典。语句,需要收集整理吗?)
2009-3-30 21:50
0
雪    币: 1074
活跃值: (160)
能力值: ( LV13,RANK:760 )
在线值:
发帖
回帖
粉丝
17
rtcMsgBox是VB里面对话框函数,相当于VC中的MessageBox
push eax 是将eax压栈,看下面的call,结合上面的压栈情况就能知道此CALL是干啥的。
2009-3-31 08:04
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
感谢分享....
2009-4-2 10:56
0
雪    币: 315
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
又见到不问年少的大作了~
2009-4-4 11:05
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
楼主厉害,学习中!
2009-4-4 11:08
0
雪    币: 246
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
学习了!
谢谢楼主!
2009-4-19 21:17
0
雪    币: 319
活跃值: (49)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
22
下断后运行,会停在MSVBVM60.DLL的领空,shift+f9程序就运行起来了,咋没见到调用的CALL
2009-4-21 14:36
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
呵呵,贪心一下,如果LZ能加入分析过程,而不是直接告诉在什么函数上下断的话就更完美了。
谢谢LZ
2009-4-21 22:12
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
呵呵
很好啊
2009-4-23 21:50
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
你还叫菜鸟....
那我就算刚入门.
2009-4-27 08:57
0
游客
登录 | 注册 方可回帖
返回
//