160CrackMe-011

本文最后更新于:2021-08-16 下午

初探

打开程序看到主界面,不可以输入任何字符,只可以点击下面的这个小键盘来进行输入,右边提示一个状态上面写着未注册,猜测成功的话这里应该会发生变化,下面开始分析一下。

分析

无壳,使用VB语言编写

使用OD,直接搜索字符串,就可以搜索到一大串类似注册码的字符串和REGISTRIERT。

进入查看,可以看到在关键跳转前有一个比较,猜测应该是输入的内容经过一个计算之后与这个字符串进行比较。

查看栈,可以看到当前输入123456计算出来的注册码

开始寻找一下注册码的生成过程。

在跳转前面下断进行分析,可以看到流程是比较简单的,首先就是获取输入的第一位数字转为浮点数保存起来,然后每一位输入转为ascii码加上这个数字,第一位在前面加上一个0。也就是如果我们输入的是123456,那么我们输入的每一位字符都会加上数字1,也就是注册码第一位是0x31+1=0x32,然后是第一位所以要在前面加上一个0,就是032,第二位就是0x32+1=0x33,现在就是03233,以此类推就会生成前面图片中的字符串,0323334353637。

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
004048EB   .  52            push edx                                 ; /Step8 = NULL
004048EC . 8D4D 9C lea ecx,dword ptr ss:[ebp-0x64] ; |
004048EF . 50 push eax ; |/var18 = 005446A4
004048F0 . 51 push ecx ; ||retBuffer8 = 00530000
004048F1 . 89B5 4CFFFFFF mov dword ptr ss:[ebp-0xB4],esi ; ||msvbvm60.__vbaStrVarVal
004048F7 . 89B5 3CFFFFFF mov dword ptr ss:[ebp-0xC4],esi ; ||msvbvm60.__vbaStrVarVal
004048FD . FF15 30104000 call dword ptr ds:[<&MSVBVM60.__vbaLenVa>; |\__vbaLenVar
00404903 . 50 push eax ; |End8 = 005446A4
00404904 . 8D95 3CFFFFFF lea edx,dword ptr ss:[ebp-0xC4] ; |
0040490A . 8D85 08FFFFFF lea eax,dword ptr ss:[ebp-0xF8] ; |
00404910 . 52 push edx ; |Start8 = NULL
00404911 . 8D8D 18FFFFFF lea ecx,dword ptr ss:[ebp-0xE8] ; |
00404917 . 50 push eax ; |TMPend8 = 005446A4
00404918 . 8D55 DC lea edx,dword ptr ss:[ebp-0x24] ; |
0040491B . 51 push ecx ; |TMPstep8 = 00530000
0040491C . 52 push edx ; |Counter8 = NULL
0040491D . FF15 38104000 call dword ptr ds:[<&MSVBVM60.__vbaVarFo>; \__vbaVarForInit
00404923 . 8B35 80104000 mov esi,dword ptr ds:[<&MSVBVM60.__vbaSt>; msvbvm60.__vbaStrVarVal
00404929 . 8B1D B4104000 mov ebx,dword ptr ds:[<&MSVBVM60.#617>] ; msvbvm60.rtcLeftCharVar
0040492F > 85C0 test eax,eax
00404931 . 0F84 29010000 je Andréna.00404A60
00404937 . 8D45 BC lea eax,dword ptr ss:[ebp-0x44]
0040493A . 6A 01 push 0x1
0040493C . 8D4D 8C lea ecx,dword ptr ss:[ebp-0x74]
0040493F . 50 push eax
00404940 . 51 push ecx
00404941 . FFD3 call ebx ; msvbvm60.rtcLeftCharVar
00404943 . 8D55 8C lea edx,dword ptr ss:[ebp-0x74]
00404946 . 8D45 B0 lea eax,dword ptr ss:[ebp-0x50]
00404949 . 52 push edx
0040494A . 50 push eax
0040494B . FFD6 call esi ; msvbvm60.__vbaStrVarVal
0040494D . 50 push eax
0040494E . FF15 D8104000 call dword ptr ds:[<&MSVBVM60.#581>] ; 获取第一位数字转为浮点数以便后面计算
00404954 . DD9D 34FFFFFF fstp qword ptr ss:[ebp-0xCC]
0040495A . 8D4D 9C lea ecx,dword ptr ss:[ebp-0x64]
0040495D . 8D55 DC lea edx,dword ptr ss:[ebp-0x24]
00404960 . 51 push ecx
00404961 . 52 push edx
00404962 . C745 A4 01000>mov dword ptr ss:[ebp-0x5C],0x1
00404969 . C745 9C 02000>mov dword ptr ss:[ebp-0x64],0x2
00404970 . FF15 AC104000 call dword ptr ds:[<&MSVBVM60.__vbaI4Var>; msvbvm60.__vbaI4Var
00404976 . 50 push eax
00404977 . 8D45 BC lea eax,dword ptr ss:[ebp-0x44]
0040497A . 8D4D B8 lea ecx,dword ptr ss:[ebp-0x48]
0040497D . 50 push eax
0040497E . 51 push ecx
0040497F . FFD6 call esi ; msvbvm60.__vbaStrVarVal
00404981 . 50 push eax
00404982 . FF15 4C104000 call dword ptr ds:[<&MSVBVM60.#631>] ; msvbvm60.rtcMidCharBstr
00404988 . 8BD0 mov edx,eax
0040498A . 8D4D B4 lea ecx,dword ptr ss:[ebp-0x4C]
0040498D . FF15 BC104000 call dword ptr ds:[<&MSVBVM60.__vbaStrMo>; msvbvm60.__vbaStrMove
00404993 . 50 push eax ; /String = "7"
00404994 . FF15 20104000 call dword ptr ds:[<&MSVBVM60.#516>] ; \转为ascii
0040499A . 0FBFD0 movsx edx,ax
0040499D . 8995 FCFCFFFF mov dword ptr ss:[ebp-0x304],edx
004049A3 . C785 7CFFFFFF>mov dword ptr ss:[ebp-0x84],0x5
004049AD . DB85 FCFCFFFF fild dword ptr ss:[ebp-0x304]
004049B3 . DD9D F4FCFFFF fstp qword ptr ss:[ebp-0x30C]
004049B9 . DD85 F4FCFFFF fld qword ptr ss:[ebp-0x30C]
004049BF . DC85 34FFFFFF fadd qword ptr ss:[ebp-0xCC] ; 每一位字符ascii码加上第一位数字
004049C5 . DD5D 84 fstp qword ptr ss:[ebp-0x7C]
004049C8 . DFE0 fstsw ax
004049CA . A8 0D test al,0xD
004049CC . 0F85 FA1F0000 jnz Andréna.004069CC
004049D2 . 8D85 7CFFFFFF lea eax,dword ptr ss:[ebp-0x84]
004049D8 . 50 push eax
004049D9 . FF15 94104000 call dword ptr ds:[<&MSVBVM60.#572>] ; msvbvm60.rtcHexBstrFromVar
004049DF . 8D4D CC lea ecx,dword ptr ss:[ebp-0x34]
004049E2 . 8985 74FFFFFF mov dword ptr ss:[ebp-0x8C],eax
004049E8 . 8D95 6CFFFFFF lea edx,dword ptr ss:[ebp-0x94]
004049EE . 51 push ecx
004049EF . 8D85 5CFFFFFF lea eax,dword ptr ss:[ebp-0xA4]
004049F5 . 52 push edx
004049F6 . 50 push eax
004049F7 . C785 6CFFFFFF>mov dword ptr ss:[ebp-0x94],0x8
00404A01 . FF15 84104000 call dword ptr ds:[<&MSVBVM60.__vbaVarCa>; msvbvm60.__vbaVarCat
00404A07 . 8BD0 mov edx,eax
00404A09 . 8D4D CC lea ecx,dword ptr ss:[ebp-0x34]
00404A0C . FFD7 call edi ; msvbvm60.__vbaVarMove
00404A0E . 8D4D B0 lea ecx,dword ptr ss:[ebp-0x50]
00404A11 . 8D55 B4 lea edx,dword ptr ss:[ebp-0x4C]
00404A14 . 51 push ecx
00404A15 . 8D45 B8 lea eax,dword ptr ss:[ebp-0x48]
00404A18 . 52 push edx
00404A19 . 50 push eax
00404A1A . 6A 03 push 0x3
00404A1C . FF15 9C104000 call dword ptr ds:[<&MSVBVM60.__vbaFreeS>; msvbvm60.__vbaFreeStrList
00404A22 . 8D8D 6CFFFFFF lea ecx,dword ptr ss:[ebp-0x94]
00404A28 . 8D95 7CFFFFFF lea edx,dword ptr ss:[ebp-0x84]
00404A2E . 51 push ecx
00404A2F . 8D45 8C lea eax,dword ptr ss:[ebp-0x74]
00404A32 . 52 push edx
00404A33 . 8D4D 9C lea ecx,dword ptr ss:[ebp-0x64]
00404A36 . 50 push eax
00404A37 . 51 push ecx
00404A38 . 6A 04 push 0x4
00404A3A . FF15 14104000 call dword ptr ds:[<&MSVBVM60.__vbaFreeV>; msvbvm60.__vbaFreeVarList
00404A40 . 83C4 24 add esp,0x24
00404A43 . 8D95 08FFFFFF lea edx,dword ptr ss:[ebp-0xF8]
00404A49 . 52 push edx ; /TMPend8 = NULL
00404A4A . 8D85 18FFFFFF lea eax,dword ptr ss:[ebp-0xE8] ; |
00404A50 . 8D4D DC lea ecx,dword ptr ss:[ebp-0x24] ; |
00404A53 . 50 push eax ; |TMPstep8 = 005446A4
00404A54 . 51 push ecx ; |Counter8 = 00530000
00404A55 . FF15 C8104000 call dword ptr ds:[<&MSVBVM60.__vbaVarFo>; \__vbaVarForNext
00404A5B .^ E9 CFFEFFFF jmp Andréna.0040492F
00404A60 > 8D55 CC lea edx,dword ptr ss:[ebp-0x34]
00404A63 . 8D85 4CFFFFFF lea eax,dword ptr ss:[ebp-0xB4]
00404A69 . 52 push edx ; /var18 = NULL
00404A6A . 50 push eax ; |var28 = 005446A4
00404A6B . C785 54FFFFFF>mov dword ptr ss:[ebp-0xAC],Andréna.0040>; |0817E747D7AFF7C7F82836D74RR7A7F7E7B7C7D826D81KE7B7C
00404A75 . C785 4CFFFFFF>mov dword ptr ss:[ebp-0xB4],0x8008 ; |
00404A7F . FF15 5C104000 call dword ptr ds:[<&MSVBVM60.__vbaVarTs>; \__vbaVarTstEq

继续分析发现问题,最后比较的字符串第一位基本都是081,但是获取的第一位数字最大就是9,最大的9(0x39)+9也才是42,怎么都不会是81。仔细查看发现是自己的思路出现问题了,刚才搜索字符串有许多的地方,而我直接断在第一个地方进行分析,第一个地方只获取第一位数字,而后面会获取前两位数字,这样就对了。

只看这里获取前两位数字的部分即可,其他关键计算与上面是一样的。

1
2
3
4
5
6
7
8
9
10
11
12
13
004064B3   .  6A 02         push 0x2
004064B5 . 8D55 8C lea edx,dword ptr ss:[ebp-0x74]
004064B8 . 51 push ecx
004064B9 . 52 push edx
004064BA . FFD3 call ebx ; msvbvm60.rtcLeftCharVar
004064BC . 8D45 8C lea eax,dword ptr ss:[ebp-0x74]
004064BF . 8D4D B0 lea ecx,dword ptr ss:[ebp-0x50]
004064C2 . 50 push eax
004064C3 . 51 push ecx
004064C4 . FFD6 call esi ; msvbvm60.__vbaStrVarVal
004064C6 . 50 push eax
004064C7 . FF15 D8104000 call dword ptr ds:[<&MSVBVM60.#581>] ; msvbvm60.rtcR8ValFromBstr
004064CD . DD9D 34FFFFFF fstp qword ptr ss:[ebp-0xCC]

那么只有一组是正确的对比字符串,经过上述分析可以知道,生成的字符串肯定是十六进制的值,查看字符串可以发现有许多的字符串其中不是十六进制值,比如第一组,很明显RR,KE不是十六进制数。

分析发现只有一组数是全部都是十六进制的,那么这一组应该就是需要计算后并且比对的KEY了。下面可以开始写注册机了。

注册机编写

首先是对于那个每一位字符需要加上的数字的判断,假设这个数字是X,那么第一位数字就是X的十位数,然后这个数+X等于81,可以用这种方法来进行计算。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int getValue()
{
int a,b;
char c;
for (int i = 0x31; i < 0x3A; i++)
{
a = 0x81 - i;
b = a/10;
itoa(b, &c, 10);
if ( c==i )
{
printf("%x\n", a);
return a;
break;
}
}
}

其实我这种方法不太严谨,应该是第一位等于X的十位,第二位等于X的个位,同时满足才行。

1
2
3
4
5
6
7
8
9
10
11
int main()
{
int a= getValue();
int key[] = { 0x81,0x7E,0x74,0x7D,0x7A,0x7D,0x7C,0x7F,0x82,0x83,0x6D,0x74,0x74,0x7A,0x7F,0x7E,0x7B,0x7C,0x7D,0x82,0x6D,0x81,0x7E,0x7B,0x7C };
for (int i = 0; i < sizeof(key) / sizeof(int); i++)
{
key[i] -= a;
printf("%c", key[i]);
}
return 0;
}

总结

因为下断的原因一直分析第一个,那里只获取第一个数字,卡了半天,研究许久让我一度以为是CM的问题,有点蠢了。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!