首页 > 代码库 > [反汇编练习] 160个CrackMe之002

[反汇编练习] 160个CrackMe之002

[反汇编练习] 160个CrackMe之002。

本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注册机的东西。

其中,文章中按照如下逻辑编排(解决如下问题):

1、使用什么环境和工具

2、程序分析

3、思路分析和破解流程

4、注册机的探索


1、工具和环境:

WinXP SP3 + 52Pojie六周年纪念版OD + PEID + 汇编金手指。

160个CrackMe的打包文件。

下载地址: http://pan.baidu.com/s/1xUWOY  密码: jbnq

注:

1、Win7系统对于模块和程序开启了随机初始地址的功能,会给分析带来很大的负担,所以不建议使用Win7进行分析。

2、以上工具都是在52PoJie论坛下的原版程序,NOD32不报毒,个人承诺绝对不会进行任何和木马病毒相关内容。

image_thumb2

 

2、程序分析:

想要破解一个程序,必须先了解这个程序。所以,在破解过程中,对最初程序的分析很重要,他可以帮助我们理解作者的目的和意图,特别是对于注册码的处理细节,从而方便我们反向跟踪和推导。

和上一节一样,打开CHM,选择第二个Afkayas,保存下来。运行程序,崩溃,缺少msvbvm50.dll,程序无法运行。没办法,上网上搜索一个,放到程序同一级目录,再次运行,OK。程序界面如下:

image

这是一个标准的Name/Serial注册码方式,二话不说,来个伪码测试:

Name: 111222    Serial: 3334444

点击OK,弹出了一个错误对话框,You Get Wrong,Try again!

3、思路分析和破解流程:

首先,按照经验,有对话框提示的程序可以通过堆栈查找调用的位置。方法如下:输入伪码,点击OK,弹出错误对话框,此时不要关闭这个对话框,切换到OD,点击暂停程序,然后Ctrl+K到堆栈视图,如下:

image

到了这里基本蒙圈了,竟然不是一般的C/C++代码,看看后面的Called from大部分来自msvbvm50,user32,根据名称百度一下,发现是使用VB的模块写的。再查看红色部分,发现表面上和对话框相关的只有msvbvm50.rtcmsgbox和user32.MessageBoxIndirectA,最主要的是msvbvm50.rtcMsgBox的调用来自AfKayas_.0040261C,所以我们基本可以断定rtcMsgBox是Vb中弹出对话框相关的东西,不要犹豫,选中它,右键->show call。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
004025E3   . /EB 56         jmp short 0040263B
004025E5   > |68 C81B4000   push 00401BC8                            ;  UNICODE "You Get Wrong"
004025EA   . |68 9C1B4000   push 00401B9C                            ;  ASCII "\r"
004025EF   . |FFD7          call edi
004025F1   . |8BD0          mov edx,eax
004025F3   . |8D4D E8       lea ecx,dword ptr ss:[ebp-0x18]
004025F6   . |FFD3          call ebx
004025F8   . |50            push eax
004025F9   . |68 E81B4000   push 00401BE8                            ;  UNICODE "Try Again"
004025FE   . |FFD7          call edi
00402600   . |8945 CC       mov dword ptr ss:[ebp-0x34],eax
00402603   . |8D45 94       lea eax,dword ptr ss:[ebp-0x6C]
00402606   . |8D4D A4       lea ecx,dword ptr ss:[ebp-0x5C]
00402609   . |50            push eax
0040260A   . |8D55 B4       lea edx,dword ptr ss:[ebp-0x4C]
0040260D   . |51            push ecx
0040260E   . |52            push edx
0040260F   . |8D45 C4       lea eax,dword ptr ss:[ebp-0x3C]
00402612   . |6A 00         push 0x0
00402614   . |50            push eax
00402615   . |C745 C4 08000>mov dword ptr ss:[ebp-0x3C],0x8
0040261C   . |FF15 10414000 call dword ptr ds:[<&MSVBVM50.#595>]     ;  msvbvm50.rtcMsgBox

将代码稍微向上查看,发现最近的地方就有“Try again”和“You get wrong”的提示,我们基本就可以断定就是这里了。继续向上,看看判断的逻辑部分在哪里:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
00402569   .  83C4 0C       add esp,0xC
0040256C   .  B9 04000280   mov ecx,0x80020004
00402571   .  B8 0A000000   mov eax,0xA
00402576   .  894D 9C       mov dword ptr ss:[ebp-0x64],ecx
00402579   .  66:85F6       test si,si
0040257C   .  8945 94       mov dword ptr ss:[ebp-0x6C],eax
0040257F   .  894D AC       mov dword ptr ss:[ebp-0x54],ecx
00402582   .  8945 A4       mov dword ptr ss:[ebp-0x5C],eax
00402585   .  894D BC       mov dword ptr ss:[ebp-0x44],ecx
00402588   .  8945 B4       mov dword ptr ss:[ebp-0x4C],eax
0040258B   .  74 58         je short 004025E5               ; 判断应该是这里吧?
0040258D   .  68 801B4000   push 00401B80                            ;  UNICODE "You Get It"
00402592   .  68 9C1B4000   push 00401B9C                            ;  ASCII "\r"
00402597   .  FFD7          call edi
00402599   .  8BD0          mov edx,eax
0040259B   .  8D4D E8       lea ecx,dword ptr ss:[ebp-0x18]
0040259E   .  FFD3          call ebx
004025A0   .  50            push eax
004025A1   .  68 A81B4000   push 00401BA8                            ;  UNICODE "KeyGen It Now"
004025A6   .  FFD7          call edi
004025A8   .  8D4D 94       lea ecx,dword ptr ss:[ebp-0x6C]
004025AB   .  8945 CC       mov dword ptr ss:[ebp-0x34],eax
004025AE   .  8D55 A4       lea edx,dword ptr ss:[ebp-0x5C]
004025B1   .  51            push ecx
004025B2   .  8D45 B4       lea eax,dword ptr ss:[ebp-0x4C]
004025B5   .  52            push edx
004025B6   .  50            push eax
004025B7   .  8D4D C4       lea ecx,dword ptr ss:[ebp-0x3C]
004025BA   .  6A 00         push 0x0
004025BC   .  51            push ecx
004025BD   .  C745 C4 08000>mov dword ptr ss:[ebp-0x3C],0x8
004025C4   .  FF15 10414000 call dword ptr ds:[<&MSVBVM50.#595>]     ;  msvbvm50.rtcMsgBox
004025CA   .  8D4D E8       lea ecx,dword ptr ss:[ebp-0x18]
004025CD   .  FF15 80414000 call dword ptr ds:[<&MSVBVM50.__vbaFreeS>;  msvbvm50.__vbaFreeStr
004025D3   .  8D55 94       lea edx,dword ptr ss:[ebp-0x6C]
004025D6   .  8D45 A4       lea eax,dword ptr ss:[ebp-0x5C]
004025D9   .  52            push edx
004025DA   .  8D4D B4       lea ecx,dword ptr ss:[ebp-0x4C]
004025DD   .  50            push eax
004025DE   .  8D55 C4       lea edx,dword ptr ss:[ebp-0x3C]
004025E1   .  51            push ecx
004025E2   .  52            push edx
004025E3   .  EB 56         jmp short 0040263B
004025E5   >  68 C81B4000   push 00401BC8                            ;  UNICODE "You Get Wrong"
004025EA   .  68 9C1B4000   push 00401B9C                            ;  ASCII "\r"
004025EF   .  FFD7          call edi
004025F1   .  8BD0          mov edx,eax
004025F3   .  8D4D E8       lea ecx,dword ptr ss:[ebp-0x18]
004025F6   .  FFD3          call ebx
004025F8   .  50            push eax
004025F9   .  68 E81B4000   push 00401BE8                            ;  UNICODE "Try Again"
004025FE   .  FFD7          call edi

很简单吧?直接在”You get it ”的旁边就有一个JE跳转,在OD查看发现如果跳转实现就提示错误,不实现就提示正确,爆破开始啦!选中je那一行,右键->Binary->Fill with NOPs. 这时在程序里随意输入试试,哈哈,爆破成功!


4、注册机探索:

由于我们在跳转附近没有发现任何类注册码的东西,所以,我们需要将这里块的内容F8跟踪一下,大概地看看那些地方可能和注册码相关。我们向上查找,在这段程序的开头(即找到最近的那个retn,下面开头一般是push ebp等)下断点:

00402310   > \55            push ebp  // 程序段头

单步F8跟踪,将重要信息添加注释,特别是和Name/Serial相关的东西,分析后代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
00402403   .  FF15 04414000 call dword ptr ds:[<&MSVBVM50.__vbaHresultChec>;  MSVBVM50.__vbaHresultCheckObj
00402409   >  8B95 50FFFFFF mov edx,dword ptr ss:[ebp-0xB0]
0040240F   .  8B45 E4       mov eax,dword ptr ss:[ebp-0x1C]
00402412   .  50            push eax                                       ;  //eax=111222,name
00402413   .  8B1A          mov ebx,dword ptr ds:[edx]
00402415   .  FF15 E4404000 call dword ptr ds:[<&MSVBVM50.__vbaLenBstr>]   ;  MSVBVM50.__vbaLenBstr
0040241B   .  8BF8          mov edi,eax                                    ;  edi=6
0040241D   .  8B4D E8       mov ecx,dword ptr ss:[ebp-0x18]                ;  ecx=1111222地址
00402420   .  69FF FB7C0100 imul edi,edi,0x17CFB                           ;  // 乘法,edi*0x17CFB
00402426   .  51            push ecx
00402427   .  0F80 91020000 jo 004026BE
0040242D   .  FF15 F8404000 call dword ptr ds:[<&MSVBVM50.#516>]           ;  MSVBVM50.rtcAnsiValueBstr
00402433   .  0FBFD0        movsx edx,ax
00402436   .  03FA          add edi,edx                                    ;  // edi=edi+edx(0x31)
00402438   .  0F80 80020000 jo 004026BE
0040243E   .  57            push edi
0040243F   .  FF15 E0404000 call dword ptr ds:[<&MSVBVM50.__vbaStrI4>]     ;  MSVBVM50.__vbaStrI4
00402445   .  8BD0          mov edx,eax                                    ;  // eax=585235
00402447   .  8D4D E0       lea ecx,dword ptr ss:[ebp-0x20]
0040244A   .  FF15 70414000 call dword ptr ds:[<&MSVBVM50.__vbaStrMove>]   ;  MSVBVM50.__vbaStrMove
00402450   .  8BBD 50FFFFFF mov edi,dword ptr ss:[ebp-0xB0]
00402456   .  50            push eax                                       ;  // 585235
00402457   .  57            push edi                                       ;  // 0091B51C
00402458   .  FF93 A4000000 call dword ptr ds:[ebx+0xA4]
0040245E   .  85C0          test eax,eax                                   ;  // ==0
00402460   .  7D 12         jge short 00402474
00402462   .  68 A4000000   push 0xA4
00402467   .  68 5C1B4000   push 00401B5C
0040246C   .  57            push edi
0040246D   .  50            push eax
0040246E   .  FF15 04414000 call dword ptr ds:[<&MSVBVM50.__vbaHresultChec>;  MSVBVM50.__vbaHresultCheckObj
00402474   >  8D45 E0       lea eax,dword ptr ss:[ebp-0x20]
00402477   .  8D4D E4       lea ecx,dword ptr ss:[ebp-0x1C]
0040247A   .  50            push eax
0040247B   .  8D55 E8       lea edx,dword ptr ss:[ebp-0x18]
0040247E   .  51            push ecx
0040247F   .  52            push edx
00402480   .  6A 03         push 0x3
00402482   .  FF15 5C414000 call dword ptr ds:[<&MSVBVM50.__vbaFreeStrList>;  MSVBVM50.__vbaFreeStrList
00402488   .  83C4 10       add esp,0x10
0040248B   .  8D45 D4       lea eax,dword ptr ss:[ebp-0x2C]
0040248E   .  8D4D D8       lea ecx,dword ptr ss:[ebp-0x28]
00402491   .  8D55 DC       lea edx,dword ptr ss:[ebp-0x24]
00402494   .  50            push eax
00402495   .  51            push ecx
00402496   .  52            push edx
00402497   .  6A 03         push 0x3
00402499   .  FF15 F4404000 call dword ptr ds:[<&MSVBVM50.__vbaFreeObjList>;  MSVBVM50.__vbaFreeObjList
0040249F   .  8B06          mov eax,dword ptr ds:[esi]
004024A1   .  83C4 10       add esp,0x10
004024A4   .  56            push esi
004024A5   .  FF90 04030000 call dword ptr ds:[eax+0x304]
004024AB   .  8B1D 0C414000 mov ebx,dword ptr ds:[<&MSVBVM50.__vbaObjSet>] ;  MSVBVM50.__vbaObjSet
004024B1   .  50            push eax
004024B2   .  8D45 DC       lea eax,dword ptr ss:[ebp-0x24]
004024B5   .  50            push eax
004024B6   .  FFD3          call ebx                                       ;  <&MSVBVM50.__vbaObjSet>
004024B8   .  8BF8          mov edi,eax
004024BA   .  8D55 E8       lea edx,dword ptr ss:[ebp-0x18]
004024BD   .  52            push edx
004024BE   .  57            push edi
004024BF   .  8B0F          mov ecx,dword ptr ds:[edi]
004024C1   .  FF91 A0000000 call dword ptr ds:[ecx+0xA0]
004024C7   .  85C0          test eax,eax                                   ;  eax=0,zf=1
004024C9   .  7D 12         jge short 004024DD
004024CB   .  68 A0000000   push 0xA0
004024D0   .  68 5C1B4000   push 00401B5C
004024D5   .  57            push edi
004024D6   .  50            push eax
004024D7   .  FF15 04414000 call dword ptr ds:[<&MSVBVM50.__vbaHresultChec>;  MSVBVM50.__vbaHresultCheckObj
004024DD   >  56            push esi
004024DE   .  FF95 40FFFFFF call dword ptr ss:[ebp-0xC0]
004024E4   .  50            push eax
004024E5   .  8D45 D8       lea eax,dword ptr ss:[ebp-0x28]
004024E8   .  50            push eax
004024E9   .  FFD3          call ebx
004024EB   .  8BF0          mov esi,eax
004024ED   .  8D55 E4       lea edx,dword ptr ss:[ebp-0x1C]
004024F0   .  52            push edx
004024F1   .  56            push esi
004024F2   .  8B0E          mov ecx,dword ptr ds:[esi]
004024F4   .  FF91 A0000000 call dword ptr ds:[ecx+0xA0]
004024FA   .  85C0          test eax,eax                                   ;  eax=0
004024FC   .  7D 12         jge short 00402510
004024FE   .  68 A0000000   push 0xA0
00402503   .  68 5C1B4000   push 00401B5C
00402508   .  56            push esi
00402509   .  50            push eax
0040250A   .  FF15 04414000 call dword ptr ds:[<&MSVBVM50.__vbaHresultChec>;  MSVBVM50.__vbaHresultCheckObj
00402510   >  8B45 E8       mov eax,dword ptr ss:[ebp-0x18]                ;  eax=3334444
00402513   .  8B4D E4       mov ecx,dword ptr ss:[ebp-0x1C]                ;  ecx=585235
00402516   .  8B3D 00414000 mov edi,dword ptr ds:[<&MSVBVM50.__vbaStrCat>] ;  MSVBVM50.__vbaStrCat
0040251C   .  50            push eax                                       ;  eax=3334444
0040251D   .  68 701B4000   push 00401B70                                  ;  UNICODE "AKA-"
00402522   .  51            push ecx                                       ;  ecx=585235
00402523   .  FFD7          call edi                                       ;  <&MSVBVM50.__vbaStrCat>
00402525   .  8B1D 70414000 mov ebx,dword ptr ds:[<&MSVBVM50.__vbaStrMove>>;  MSVBVM50.__vbaStrMove
0040252B   .  8BD0          mov edx,eax                                    ;  edx=eax=AKA-585235
0040252D   .  8D4D E0       lea ecx,dword ptr ss:[ebp-0x20]
00402530   .  FFD3          call ebx                                       ;  <&MSVBVM50.__vbaStrMove>
00402532   .  50            push eax
00402533   .  FF15 28414000 call dword ptr ds:[<&MSVBVM50.__vbaStrCmp>]    ;  MSVBVM50.__vbaStrCmp
00402539   .  8BF0          mov esi,eax                                    ;  eax=-1
0040253B   .  8D55 E0       lea edx,dword ptr ss:[ebp-0x20]
0040253E   .  F7DE          neg esi                                        ;  取补
00402540   .  8D45 E8       lea eax,dword ptr ss:[ebp-0x18]
00402543   .  52            push edx
00402544   .  1BF6          sbb esi,esi
00402546   .  8D4D E4       lea ecx,dword ptr ss:[ebp-0x1C]
00402549   .  50            push eax
0040254A   .  46            inc esi
0040254B   .  51            push ecx
0040254C   .  6A 03         push 0x3
0040254E   .  F7DE          neg esi
00402550   .  FF15 5C414000 call dword ptr ds:[<&MSVBVM50.__vbaFreeStrList>;  MSVBVM50.__vbaFreeStrList
00402556   .  83C4 10       add esp,0x10
00402559   .  8D55 D8       lea edx,dword ptr ss:[ebp-0x28]
0040255C   .  8D45 DC       lea eax,dword ptr ss:[ebp-0x24]
0040255F   .  52            push edx
00402560   .  50            push eax
00402561   .  6A 02         push 0x2
00402563   .  FF15 F4404000 call dword ptr ds:[<&MSVBVM50.__vbaFreeObjList>;  MSVBVM50.__vbaFreeObjList
00402569   .  83C4 0C       add esp,0xC
0040256C   .  B9 04000280   mov ecx,0x80020004
00402571   .  B8 0A000000   mov eax,0xA
00402576   .  894D 9C       mov dword ptr ss:[ebp-0x64],ecx
00402579   .  66:85F6       test si,si                                     ;  esi=0,ZF=1
0040257C   .  8945 94       mov dword ptr ss:[ebp-0x6C],eax
0040257F   .  894D AC       mov dword ptr ss:[ebp-0x54],ecx
00402582   .  8945 A4       mov dword ptr ss:[ebp-0x5C],eax
00402585   .  894D BC       mov dword ptr ss:[ebp-0x44],ecx
00402588   .  8945 B4       mov dword ptr ss:[ebp-0x4C],eax
0040258B      74 58         je short 004025E5                              ;  // 爆破关键跳,NOP
0040258D   .  68 801B4000   push 00401B80                                  ;  UNICODE "You Get It"
00402592   .  68 9C1B4000   push 00401B9C                                  ;  ASCII "\r"
00402597   .  FFD7          call edi

其实代码很简单,经过一遍跟踪,基本都出来了,重点分析部分如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
00402412   .  50            push eax                                       ;  //eax=111222,name
00402413   .  8B1A          mov ebx,dword ptr ds:[edx]
00402415   .  FF15 E4404000 call dword ptr ds:[<&MSVBVM50.__vbaLenBstr>]   ;  MSVBVM50.__vbaLenBstr
0040241B   .  8BF8          mov edi,eax                                    ;  edi=6
0040241D   .  8B4D E8       mov ecx,dword ptr ss:[ebp-0x18]                ;  ecx=1111222地址
00402420   .  69FF FB7C0100 imul edi,edi,0x17CFB                           ;  // 乘法,edi*0x17CFB
00402426   .  51            push ecx
00402427   .  0F80 91020000 jo 004026BE
0040242D   .  FF15 F8404000 call dword ptr ds:[<&MSVBVM50.#516>]           ;  MSVBVM50.rtcAnsiValueBstr
00402433   .  0FBFD0        movsx edx,ax
00402436   .  03FA          add edi,edx                                    ;  // edi=edi+edx(0x31)
00402438   .  0F80 80020000 jo 004026BE
0040243E   .  57            push edi
0040243F   .  FF15 E0404000 call dword ptr ds:[<&MSVBVM50.__vbaStrI4>]     ;  MSVBVM50.__vbaStrI4
00402445   .  8BD0          mov edx,eax                                    ;  // eax=585235

首先,eax为Name的地址,经过__vbaLenBstr计算的长度赋值给edi,然后edi=edi*0x17CFB,接着edi=edi+edx,而edx为Name字符串第一个字符Ansi的值,最后进过__vbaStrI4将edi的整数值转换为十进制字符串585235。

然后向下跟踪和字符串585235相关的东西:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
00402510   >  8B45 E8       mov eax,dword ptr ss:[ebp-0x18]                ;  eax=3334444
00402513   .  8B4D E4       mov ecx,dword ptr ss:[ebp-0x1C]                ;  ecx=585235
00402516   .  8B3D 00414000 mov edi,dword ptr ds:[<&MSVBVM50.__vbaStrCat>] ;  MSVBVM50.__vbaStrCat
0040251C   .  50            push eax                                       ;  eax=3334444
0040251D   .  68 701B4000   push 00401B70                                  ;  UNICODE "AKA-"
00402522   .  51            push ecx                                       ;  ecx=585235
00402523   .  FFD7          call edi                                       ;  <&MSVBVM50.__vbaStrCat>
00402525   .  8B1D 70414000 mov ebx,dword ptr ds:[<&MSVBVM50.__vbaStrMove>>;  MSVBVM50.__vbaStrMove
0040252B   .  8BD0          mov edx,eax                                    ;  edx=eax=AKA-585235
0040252D   .  8D4D E0       lea ecx,dword ptr ss:[ebp-0x20]
00402530   .  FFD3          call ebx                                       ;  <&MSVBVM50.__vbaStrMove>
00402532   .  50            push eax
00402533   .  FF15 28414000 call dword ptr ds:[<&MSVBVM50.__vbaStrCmp>]    ;  MSVBVM50.__vbaStrCmp
00402539   .  8BF0          mov esi,eax                                    ;  eax=-1

这段代码中将585235通过__vbaStrCat与”AKA-”连接到一起组成字符串”AKA-585235”,然后通过__vbaStrCmp函数与我们的Serial比较结果,最后返回值放到eax中,通过返回值确定是否正确。将这里的分析与上一块合到一起,很容易就可以得出最终的注册码。

小结一下:先取出注册码的长度len, 然后取出注册码第一个字符的ANSI值cName, 让后计算len*0x17CFB+cName,将计算的值转换为10进制文本,前面加上”AKA-”组成最后的注册码。

C/CPP代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// CrackMe160.cpp : 定义控制台应用程序的入口点。
// 002
 
#include "stdafx.h"
#include <stdio.h>
#include "iostream"
 
char buff[100] = {0};
int _tmain(int argc, _TCHAR* argv[])
{
    printf("160CrackMe-002 Name/Serial\r\n\r\n");
    printf("Name:");
    gets_s(buff,100);
    int nLen = strlen(buff);
    if ( nLen > 0 )
    {
        int nRet = nLen * 0x17CFB;
        nRet += buff[0];
        printf("AKA-%d\r\n",nRet);
    }else{
        printf("Input error!\r\n");
    }
    system("pause");
    return 0;
}

image