吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9291|回复: 6
收起左侧

[原创] 160个CrackMe – 002

[复制链接]
天清地宁 发表于 2015-8-21 20:11
1. 爆破

2. 找算法

一:爆破程序
    这个程序是一个VB的程序,以前并没有摸过除C++之外的程序。程序载入时,下BP MessageBoxA和MessageBoxW都无法断下弹窗。
    临时看下《加密解密三》VB程序得知VB的显示对话框函数为:rtcMsgBox。吾爱的OD插件中有VB函数断点,点击下即可下rtcMsgBox断点。然后输入账户tqdn密码1234点击控件OK让程序跑起来。
1.jpg
.     程序跑起来后断在了MSVBVM50的动态链接库中。这里应该就是rtcMsgBox函数范围内。直接F8走出这个函数。F8往下的过程中会弹出消息框显示“You Get Wrong   Try Again”估摸着就是错误的消息吧。
.     走出函数后就返回到下面

[Asm] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
004025E1   .  51            push ecx
004025E2   .  52            push edx
004025E3   .  EB 56         jmp XAfkayas_.0040263B                            ;  跳过了错误的显示
004025E5   >  68 C81B4000   push Afkayas_.00401BC8                            ;  UNICODE "You Get Wrong"
004025EA   .  68 9C1B4000   push Afkayas_.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 Afkayas_.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>]              ;  显示错误信息弹框的函数
00402622   .  8D4D E8       lea ecx,dword ptr ss:[ebp-0x18]                   ;  当前EIP的位置

.     在当前EIP处往上看,离最近的是一个JMP指令,这条指令在OD上点上去是直接跳过了这个显示错误信息的函数。那么在往上面找找。有没有什么跳转指令。

[Asm] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
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
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                         ;  比较SI是否为0
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 XAfkayas_.004025E5              ;  如果SI等于0那么跳转到错误的显示
0040258D   .  68 801B4000   push Afkayas_.00401B80             ;  UNICODE "You Get It"
00402592   .  68 9C1B4000   push Afkayas_.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 Afkayas_.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.__vba>;  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 XAfkayas_.0040263B             ;  跳过了错误的显示
004025E5   >  68 C81B4000   push Afkayas_.00401BC8             ;  UNICODE "You Get Wrong"
004025EA   .  68 9C1B4000   push Afkayas_.00401B9C             ;  ASCII "\r"
004025EF   .  FFD7          call edi
004025F1   .  8BD0          mov edx,eax
004025F3   .  8D4D E8       lea ecx,dword ptr ss:[ebp-0x18]

.     往上找找到了一个靠谱的跳转点:
.     0040258B  je XAfkayas_.004025E5  ;  如果SI等于0那么跳转到错误的显示
.     尝试把此处的JE修改成nop。然后跑程序试试~~ 爆破成功!

2.jpg
二:找出算法
.     首先想找算法那么先应该在爆破点下断点,并且跑到这里来。
[Asm] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
00402561   .  6A 02         push 0x2
00402563   .  FF15 F4404000 call dword ptr ds:[<&MSVBVM50.__vba>;  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                         ;  比较SI是否为0
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 XAfkayas_.004025E5              ;  如果SI等于0那么跳转到错误的显示
0040258D   .  68 801B4000   push Afkayas_.00401B80             ;  UNICODE "You Get It"
00402592   .  68 9C1B4000   push Afkayas_.00401B9C             ;  ASCII "\r"
00402597   .  FFD7          call edi

.     JE的跳转是由TEST SI, SI来控制,所以我们应当找到那里给SI赋值的指令。
[Asm] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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.__vba>;  msvbvm50.__vbaStrCmp
00402539   .  8BF0          mov esi,eax                        ;  vbaStrCmp 字符串比较函数的返回值给了ESI
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.__vba>;  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.__vba>;  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                         ;  比较SI是否为0
0040257C   .  8945 94       mov dword ptr ss:[ebp-0x6C],eax
0040257F   .  894D AC       mov dword ptr ss:[ebp-0x54],ecx

.     从 TEST SI, SI 处往上找,在很近的地方vbaStrCmp 字符串比较函数的返回值给了ESI。我们在vbaStrCmp 处下断点,OD跑过来看看比较的是什么内容。观察栈中可以看到函数直接是以明文方式作比较,我输入的密码1234和程序计算出来的KEY值。
3.jpg
.     我们往上看看反汇编代码.     我们往上看看反汇编代码
[Asm] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
004024FC   .  7D 12         jge XAfkayas_.00402510
004024FE   .  68 A0000000   push 0xA0
00402503   .  68 5C1B4000   push Afkayas_.00401B5C
00402508   .  56            push esi
00402509   .  50            push eax
0040250A   .  FF15 04414000 call dword ptr ds:[<&MSVBVM50.__vbaHresu>;  msvbvm50.__vbaHresultCheckObj
00402510   >  8B45 E8       mov eax,dword ptr ss:[ebp-0x18]
00402513   .  8B4D E4       mov ecx,dword ptr ss:[ebp-0x1C]
00402516   .  8B3D 00414000 mov edi,dword ptr ds:[<&MSVBVM50.__vbaSt>;  msvbvm50.__vbaStrCat
0040251C   .  50            push eax
0040251D   .  68 701B4000   push Afkayas_.00401B70                  ;  UNICODE "AKA-"
00402522   .  51            push ecx                                ; /String
00402523   .  FFD7          call edi                                ; \__vbaStrCat
00402525   .  8B1D 70414000 mov ebx,dword ptr ds:[<&MSVBVM50.__vbaSt>;  msvbvm50.__vbaStrMove
0040252B   .  8BD0          mov edx,eax
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.__vbaStrCm>;  msvbvm50.__vbaStrCmp
00402539   .  8BF0          mov esi,eax                             ;  vbaStrCmp 字符串比较函数的返回值给了ESI

.     vbaStrCmp的第一个参数是由vbaStrMove的返回值给的。观察反汇编
[Asm] 纯文本查看 复制代码
1
2
3
4
5
6
7
00402525   .  8B1D 70414000 mov ebx,dword ptr ds:[<&MSVBVM50.__vbaSt>;  msvbvm50.__vbaStrMove
0040252B   .  8BD0          mov edx,eax
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.__vbaStrCm>;  msvbvm50.__vbaStrCmp
00402539   .  8BF0          mov esi,eax                             ;  vbaStrCmp 字符串比较函数的返回值给了ESI

. 并没有看到vbaStrMove存在PUSH参数的指令。我们在这里下断点进去看看vbaStrMove的实现是什么样子的。
[Asm] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
vbaStrMove的实现
7403F8DA >  56              push esi
7403F8DB    57              push edi
7403F8DC    8B01            mov eax,dword ptr ds:[ecx]              ; ECX去一个DWORD给EAX
7403F8DE    8BFA            mov edi,edx                             ; EDX的内容给EDI
7403F8E0    8BF1            mov esi,ecx                             ; ECX的内容给ESI
7403F8E2    85C0            test eax,eax                            ; 判断ECX 去内容是否为NULL
7403F8E4    75 07           jnz Xmsvbvm50.7403F8ED
7403F8E6    8BC7            mov eax,edi
7403F8E8    893E            mov dword ptr ds:[esi],edi              ; ECX取内容不等于NULL就将EDI存放至ECX中
7403F8EA    5F              pop edi
7403F8EB    5E              pop esi
7403F8EC    C3              retn
7403F8ED    50              push eax
7403F8EE    FF15 88190274   call dword ptr ds:[<&OLEAUT32.#6>]      ; oleaut32.SysFreeString
7403F8F4  ^ EB F0           jmp Xmsvbvm50.7403F8E6                  ; 否则就直接返回了

.     通过解释反汇编,可以知道vbaStrMove不是使用栈来传参数而是使用了两个寄存器EDX和ECX。结合反汇编,EDX是由vbaStrCat的返回值给与的。ECX由ebp-0x20来的。
4.jpg
.     vbaStrCat的两个参数是直接push一个字符串”AKA-”和push了一个ECX,ECX指向了一个字符串“390240”。最开始在爆破点下断点得出来的KEY位“AKA-390240”理算法很近了。我们接下来需要就是找到ECX是从哪来的。但是失败了。我对VB不熟悉,函数这里给出的结果让我很莫名其妙。

.     所以我决定在用最挫的方式重新在爆破点的函数头下断点,然后单步跟一次流程。并且关注函数的返回值和传出参数(lea EXX, ebp-XX,遇见这种考虑是传出参数,直接在十六进制窗口查看当前地址是什么内容,函数走完后修改成了什么数据!)

[Asm] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
004023ED   .  FF90 A0000000 call dword ptr ds:[eax+0xA0]                  ;  这里获得了账户
004023F3   .  3BC7          cmp eax,edi
004023F5   .  7D 12         jge XAfkayas_.00402409
004023F7   .  68 A0000000   push 0xA0                                     ;  如果返回值小于0就走这里
004023FC   .  68 5C1B4000   push Afkayas_.00401B5C
00402401   .  53            push ebx
00402402   .  50            push eax
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]               ;  vbaLenBstr 获取 账户的长度,eax返回长度
00402412   .  50            push eax                                      ; /String
00402413   .  8B1A          mov ebx,dword ptr ds:[edx]                    ; |
00402415   .  FF15 E4404000 call dword ptr ds:[<&MSVBVM50.__vbaLenBstr>]  ; \__vbaLenBstr
0040241B   .  8BF8          mov edi,eax                                   ;  账户长度存储在EDI中
0040241D   .  8B4D E8       mov ecx,dword ptr ss:[ebp-0x18]
00402420   .  69FF FB7C0100 imul edi,edi,0x17CFB                          ;  将账户长度 * 0x17CFB
00402426   .  51            push ecx                                      ; /String
00402427   .  0F80 91020000 jo Afkayas_.004026BE                          ; |计算出来的结果>=0x80000000 就异常
0040242D   .  FF15 F8404000 call dword ptr ds:[<&MSVBVM50.#516>]          ; \rtcAnsiValueBstr
00402433   .  0FBFD0        movsx edx,ax                                  ;  返回账户的第一个字符代码
00402436   .  03FA          add edi,edx                                   ;  返回的字符代码与账户长度 * 0x17CFB相加
00402438   .  0F80 80020000 jo Afkayas_.004026BE                          ;  结果大于0x80000000就异常
0040243E   .  57            push edi                                      ;  这个函数是将I4转换成STR
0040243F   .  FF15 E0404000 call dword ptr ds:[<&MSVBVM50.__vbaStrI4>]    ;  msvbvm50.__vbaStrI4
00402445   .  8BD0          mov edx,eax                                   ;  返回值为390240字符串

.    这里得到了字符串为390240,通过第一次失败的跟踪。那么可以知道这个地方是算出后面整数字符串的地方,对于KEY只需要在字符串前拼接一个”AKA-”就好了

.    这个算法很简单,也是和001一样只取了账户的第一个字节。不过这个账户有取账户长度做计算得出的结果。所以一个账户算出来的KEY只能在首字母和账户长度都相等的情况才能正常得出正确的结果!

[C] 纯文本查看 复制代码
1
2
3
4
5
6
7
void Fun(char *ZhangHu)
{
    char szBuff[256];
    unsigned long data = strlen(ZhangHu) * 0x17CFB + (unsigned long)ZhangHu[0];
    sprintf(szBuff, "AKA-%d", data);
    printf("%s \r\n", szBuff);
}


免费评分

参与人数 1威望 +2 热心值 +1 收起 理由
Hmily + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩.

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Cizel 发表于 2015-8-21 20:16
会分析算法,很厉害~
苏紫方璇 发表于 2015-8-21 20:59
膜拜会分析算法的大神,希望楼主有毅力把160的cm都做完(我是没这毅力
头像被屏蔽
panjb 发表于 2016-5-9 00:37
妖精的旋律 发表于 2016-5-9 02:50
厉害厉害
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-6-14 00:03

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表