buddama 发表于 2017-4-16 15:45

破与追-160个crackme之09:Andrénalin.2

本帖最后由 buddama 于 2017-4-16 16:06 编辑


先打开程序点点看。
乱输入一个Name:xxxxxxxx和Key:1111111111,会弹出错误提示的对话框。


如果输入正确的话,理应也有个通知的对话框,最后可以看到是介个样子:



有提示框就简单多了不是?马上开工。OD载入,查找ASCII。我去,坑爹呢,没有有用的线索。


那就用函数下断。OD重新载入,输入上面的Name和Key,点击OK按钮,弹出错误对话框。暂停,查看调用堆栈,发现最后一个对话框调用:
右键追踪调用处,来到这里:
0040240F   .FF15 28414000 call dword ptr ds:[<&MSVBVM50.#rtcMsgBox_595>]   ;rtcMsgBox 错误!

很好好继续往上翻。

很快就找到另一个rtcMsgBox,猜测就是提示正确的对话框。



往上找关键判断和跳转:
004022C8   .66:85DB       test bx,bx
004022CB   .0F84 C0000000 je 160-9_An.00402391                               ;关键跳;
如果在此处修改z标志的值,就能让程序显示正确对话框。说明以上的判断正确。
因此爆破的话此处改为jne。
现在继续往上,找到正确的Key。因为关键判断考察的是bx,所以首先要搞清EBX怎么来的,不是?
往上翻,很快发现一个比较函数。
004022AE   .FF15 48414000 call dword ptr ds:[<&MSVBVM50.__vbaVarTstEq>]      ; \__vbaVarTstEq
004022B4   .8D4D A4       lea ecx,dword ptr ss:
004022B7   .8BD8          mov ebx,eax                                        ;msctf.775D4440

翻了下VB库函数手册,发现此函数比较二数如相同eax返回-1;否则返回0。因为输入的错码,eax当然是0;后面eax赋值给了ebx。
这样的话,我们F7进入004022AE,此后要一直注意eax的赋值:
7412B99E >FF7424 08       push dword ptr ss:
7412B9A2    FF7424 08       push dword ptr ss:
7412B9A6    6A 00         push 0x0
7412B9A8    E8 E74AFFFF   call MSVBVM50.74120494
7412B9AD    8B0485 D4C51074 mov eax,dword ptr ds:
7412B9B4    C2 0800         retn 0x8
这里发现了一个call,F7追进去。一路F8,同时观察信息窗。
74120632    FF73 08         push dword ptr ds:                        ; 假码出现了
74120635    FF72 08         push dword ptr ds:                        ; 118-1851-4400
74120638    FF75 08         push dword ptr ss:
7412063B    E8 BC3FF0FF   call MSVBVM50.740245FC

什么鬼?那个118-1851-4400就是注册码吧。运行过7412063B后,发现eax变为了FFFFFFFF,一直到返回,eax的赋值不变。
F7进7412063B,我去,vbaStrComp。原本可以想办法利用这个下断点的。
740245FC    66:837C24 04 00 cmp word ptr ss:,0x0
74024602    B8 00000000   mov eax,0x0
74024607    0F85 D9F20500   jnz MSVBVM50.740838E6
7402460D    FF7424 0C       push dword ptr ss:
74024611    FF7424 0C       push dword ptr ss:
74024615    50            push eax
74024616    E8 48EFFFFF   call MSVBVM50.__vbaStrComp
7402461B    C2 0C00         retn 0xC
到此为止我们直到了真假码比较的过程。将118-1851-4400输入Key,果然提示正确。
此处我们得到了一个正确的组合Name:xxxxxxxx,Key: 118-1851-4400。下一步就是分析算法了。


因为堆栈 ds:=001B3F7C, (UNICODE "118-1851-4400")
在内存001B3F7C设内存写入断点,来到xxxxxxxx,看到一大串的字符复制过程,从这里可以追溯最早的真码出现的地方。发现这个地址的字符串是1185185174400,很明显是做了某些简单的运算后就可以得到真码。
75FA981E    89448F E8       mov dword ptr ds:,eax            ; 这部分在复制key,原地址在
F8继续,很快进入到系统领空,观察到通过函数vbaMidsStmtVar“-”替换“5”,变成了堆栈 ds:=001B3F7C, (UNICODE "118-185174400")。可以推测这个替换还要发生一次,我们跟踪一下。
回到程序领空00402231   .8D45 CC       lea eax,dword ptr ss:
果然又是一次vbaMidsStmtVar。F7进入:
740FF6B6    E8 04000000   call MSVBVM50.__vbaMidStmtVarB
740FF723    E8 2C000000   call MSVBVM50.__vbaMidStmtBstrB                ; 这个函数在替换字符为-。
回到程序领空发现确实替换完成了118-1851-4400。可见,原始注册码生成13位数字后,要将第4位和第9位替换为“-”。
换成其他的Name后发现还是这么个规律:生成一个13位数,并用“-”替换其4,9位。

现在我们把注意力放在原始的Key是怎么来的。

还是回到比较函数哪里:
004022AE   .FF15 48414000 call dword ptr ds:[<&MSVBVM50.__vbaVarTstEq>]; \__vbaVarTstEq
往上翻,在接近段首的位置下断。
00401FF0   > \55            push ebp
重新运行,输入“abcdefgh”和“1111111111”,F8步进。因为已经知道在哪里找到真码了,我视线把它写出来,方便寻找线索abcdefgh---à 992-9258-560。
很快发现Name出现在信息窗里。
004020AE   > \8B45 A8       mov eax,dword ptr ss:                ;出现Name->eax
很好,快接近了。
下面可以看到一些对象初始化和变量拷贝和初始化的过程(根据函数名推测),紧接着出现一个循环体:
00402132   > /85C0          test eax,eax
00402134   . |0F84 9C000000 je 160-9_An.004021D6
0040213A   . |8D55 94       lea edx,dword ptr ss:
0040213D   . |8D45 DC       lea eax,dword ptr ss:
00402140   . |52            push edx
00402141   . |50            push eax
00402142   . |C745 9C 01000>mov dword ptr ss:,0x1
00402149   . |895D 94       mov dword ptr ss:,ebx
0040214C   . |FF15 90414000 call dword ptr ds:[<&MSVBVM50.__vbaI4Var>]   ;MSVBVM50.__vbaI4Var
00402152   . |8D4D BC       lea ecx,dword ptr ss:                ; |
00402155   . |50            push eax                                       ; |1
00402156   . |8D55 84       lea edx,dword ptr ss:                ; |
00402159   . |51            push ecx                                       ; |8
0040215A   . |52            push edx                                       ; |0
0040215B   . |FF15 38414000 call dword ptr ds:[<&MSVBVM50.#rtcMidCharVar_6>; \rtcMidCharVar 截取字符操作
00402161   . |8D45 84       lea eax,dword ptr ss:
00402164   . |8D4D A8       lea ecx,dword ptr ss:
00402167   . |50            push eax                                       ; /00120008
00402168   . |51            push ecx                                       ; |0
00402169   . |FF15 70414000 call dword ptr ds:[<&MSVBVM50.__vbaStrVarVal>] ; \__vbaStrVarVal
0040216F   . |50            push eax                                       ; /截取的Name的单个字母
00402170   . |FF15 0C414000 call dword ptr ds:[<&MSVBVM50.#rtcAnsiValueBst>; \Unicode转ANSI函数call
00402176   . |66:8985 4CFFF>mov word ptr ss:,ax                  ;
0040217D   . |8D55 CC       lea edx,dword ptr ss:                ;0
00402180   . |8D85 44FFFFFF lea eax,dword ptr ss:                ;0
00402186   . |52            push edx                                       ; /0
00402187   . |8D8D 74FFFFFF lea ecx,dword ptr ss:                ; |00120008
0040218D   . |50            push eax                                       ; |2
0040218E   . |51            push ecx                                       ; |0
0040218F   . |899D 44FFFFFF mov dword ptr ss:,ebx                ; |2
00402195   . |FF15 94414000 call dword ptr ds:[<&MSVBVM50.__vbaVarAdd>]    ; \vbavaradd;累加各字母十六进制数值。
0040219B   . |8BD0          mov edx,eax
0040219D   . |8D4D CC       lea ecx,dword ptr ss:
004021A0   . |FFD6          call esi                                       ;MSVBVM50.__vbaVarMove
004021A2   . |8D4D A8       lea ecx,dword ptr ss:
004021A5   . |FF15 B8414000 call dword ptr ds:[<&MSVBVM50.__vbaFreeStr>]   ;MSVBVM50.__vbaFreeStr
004021AB   . |8D55 84       lea edx,dword ptr ss:
004021AE   . |8D45 94       lea eax,dword ptr ss:
004021B1   . |52            push edx
004021B2   . |50            push eax
004021B3   . |53            push ebx
004021B4   . |FFD7          call edi                                       ;MSVBVM50.__vbaFreeVarList
004021B6   . |83C4 0C       add esp,0xC
004021B9   . |8D8D E8FEFFFF lea ecx,dword ptr ss:
004021BF   . |8D95 F8FEFFFF lea edx,dword ptr ss:
004021C5   . |8D45 DC       lea eax,dword ptr ss:
004021C8   . |51            push ecx                                       ; /3
004021C9   . |52            push edx                                       ; |3
004021CA   . |50            push eax                                       ; |3
004021CB   . |FF15 AC414000 call dword ptr ds:[<&MSVBVM50.__vbaVarForNext>>; \__vbaVarForNext
004021D1   .^\E9 5CFFFFFF   jmp 160-9_An.00402132

原来是Name各位在累加。累加的细节不贴了,感兴趣的追进去看看。可得Sum(a..h)=0x324,下面还会见到。
继续往下走。
004021D9   .8D95 54FFFFFF lea edx,dword ptr ss:
004021DF   .51            push ecx                                       ; /2
004021E0   .8D45 94       lea eax,dword ptr ss:                ; |
004021E3   .52            push edx                                       ; |2
004021E4   .50            push eax                                       ; |SaveTo8 = 0012F408
004021E5   .C785 5CFFFFFF>mov dword ptr ss:,0x499602D2         ; |
004021EF   .C785 54FFFFFF>mov dword ptr ss:,0x3                ; |
004021F9   .FF15 5C414000 call dword ptr ds:[<&MSVBVM50.__vbaVarMul>]    ; \vbavarmul
这里出现了一个vbavarmul函数,乘法啊;F7追进去;
74121A09   /0F85 A86B0000   jnz MSVBVM50.741285B7
74121A0F   |66:C745 FE 0200 mov word ptr ss:,0x2
74121A15   |66:894E 08      mov word ptr ds:,cx
74121A19   |EB 78         jmp short MSVBVM50.74121A93
74121A1B   |0FBF4F 08       movsx ecx,word ptr ds:                ; Name的hex之和出现了。a+b+c...+h=324
74121A1F   |56            push esi                                       ; MSVBVM50.__vbaVarMove
74121A20   |FF73 08         push dword ptr ds:
74121A23   |51            push ecx
74121A24   |E8 1DCCF3FF   call MSVBVM50.7405E646
74121A29   |EB 6F         jmp short MSVBVM50.74121A9A
74121A2B   |0FBF47 08       movsx eax,word ptr ds:
……
……
F8追到74121A24   |E8 1DCCF3FF   call MSVBVM50.7405E646时F7进去看看。
7405E646    55            push ebp
7405E647    8BEC            mov ebp,esp
7405E649    8B45 08         mov eax,dword ptr ss:      ; eax=324
7405E64C    F76D 0C         imul dword ptr ss:         ; 与499602D2相乘;存储于EDX:EAX=E71B20DB88
7405E64F    8B4D 10         mov ecx,dword ptr ss:
7405E652    0F80 2CC70300   jo MSVBVM50.7409AD84
……
……
7409AD84    52            push edx
7409AD85    50            push eax
7409AD86    DF2C24          fild qword ptr ss:               ; fild是将整数转化为长双精;即
7409AD89    66:C701 0500    mov word ptr ds:,0x5
7409AD8E    DD59 08         fstp qword ptr ds:         ; 转化为浮点数。我靠,瞧结果是多少?992592583560,原始Key啊。
7409AD91    66:83C4 08      add sp,0x8
7409AD95^ E9 C638FCFF   jmp MSVBVM50.7405E660




到这里已经很清楚了,用Name的各位十六进制累加后,与499602D2相乘,其结果在转化为双精度数字,即为原始的Key。随后在进行字符的替换,我们上面已经清楚了。
让我们随便试试几个看对不对?
我们的用户名为(sdnbyyzcnm),又称“山的那边有一只草泥马”,计算其累加和为:(73+64+6E+62+79+79+7A+63+6E+6D)=451;451乘499602D2(即十进制1234567890)得13DA0822C72,十进制为1364197518450,替换一下字符得136-1975-8450,输入试试。我草,把我的手机号码给算出来了。



好了。现在来写个简单的注册机。楼主熟悉perl,就Perl吧。

#!/usr/bin/perl
print "Usage: perl register.pl name\n";
my $name=$ARGV;
my @arr=split(//,$name);
for my $letter(@arr){
         $sum += ord($letter);
                   }
$cons=hex("499602D2");
$product=$sum*$cons;
# print $cons,"\t",$product,"\n";
my @digits=split(//,$product);
my $result;
for($i=0;$i<=scalar(@digits)-1;$i++){
         if($i eq 3 || $i eq 8){
                   $result .= "-";
                   }
         else{
                   $result .= $digits[$i];
                   }
                   }
print "Your Name is \"$name\", Your Key is \"$result\".\n";

总结:楼主是新手,从前到后走了不少弯路,请大牛们不要嘲笑。我猜直接用OK按钮的button_up事件拦截应该最方便了,可是我还不知道怎么做。有一些具体的细节我没有仔细研究,等有时间吧。

好了,收工。欢迎各位指导,你们多指导我才能多进步。请多鼓励鼓励新手,谢谢啦。

buddama 发表于 2019-7-9 17:10

吾爱和平 发表于 2019-7-8 08:48
没有发布附件吗?如果发布exe的我可以练习一下 这样只看图 没有实际操作还是觉得少点什么。。。

请在论坛搜一下160个crack,会下到一个压缩包,里面有。

buddama 发表于 2017-4-19 21:56

Hmily 发表于 2017-4-19 18:29
@buddama 代码可以用代码框处理一下,看起来会舒服一些,挤在一起看得比较累。

谢谢hmily大牛提醒!我下次会注意的,毕竟新手爱做挫事......

buddama 发表于 2017-4-16 16:07

发现排版真费力啊!

buddama 发表于 2017-4-17 12:11

审核怎么这么久?

KaQqi 发表于 2017-4-17 21:17

buddama 发表于 2017-4-16 16:07
发现排版真费力啊!

辛苦了。vb,perl我还没玩过,哈哈。学习加膜拜

buddama 发表于 2017-4-17 22:51

cqr2287 发表于 2017-4-17 21:17
辛苦了。vb,perl我还没玩过,哈哈。学习加膜拜

楼主是新手,我们一起进步!

yue2363311 发表于 2017-4-18 10:31

哇,好厉害的帖子,看完好累。

Hmily 发表于 2017-4-19 18:29

@buddama 代码可以用代码框处理一下,看起来会舒服一些,挤在一起看得比较累。

xiaohong 发表于 2017-4-20 06:20

弹出错误提示的对话框。

pwrgod 发表于 2018-3-1 15:11

很详细,很清楚啊~
页: [1] 2
查看完整版本: 破与追-160个crackme之09:Andrénalin.2