破与追-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事件拦截应该最方便了,可是我还不知道怎么做。有一些具体的细节我没有仔细研究,等有时间吧。
好了,收工。欢迎各位指导,你们多指导我才能多进步。请多鼓励鼓励新手,谢谢啦。 吾爱和平 发表于 2019-7-8 08:48
没有发布附件吗?如果发布exe的我可以练习一下 这样只看图 没有实际操作还是觉得少点什么。。。
请在论坛搜一下160个crack,会下到一个压缩包,里面有。 Hmily 发表于 2017-4-19 18:29
@buddama 代码可以用代码框处理一下,看起来会舒服一些,挤在一起看得比较累。
谢谢hmily大牛提醒!我下次会注意的,毕竟新手爱做挫事...... 发现排版真费力啊! 审核怎么这么久? buddama 发表于 2017-4-16 16:07
发现排版真费力啊!
辛苦了。vb,perl我还没玩过,哈哈。学习加膜拜 cqr2287 发表于 2017-4-17 21:17
辛苦了。vb,perl我还没玩过,哈哈。学习加膜拜
楼主是新手,我们一起进步! 哇,好厉害的帖子,看完好累。 @buddama 代码可以用代码框处理一下,看起来会舒服一些,挤在一起看得比较累。 弹出错误提示的对话框。 很详细,很清楚啊~
页:
[1]
2