海天一色001 发表于 2017-4-15 18:14

初练160个CrakeMe程序之002

本帖最后由 海天一色001 于 2017-4-15 19:10 编辑

4/13/2017 4:00:10 PM
老规矩,先查壳,PEID查无壳,是VB程序,首先反应过来的是字符串是Unicode不是Ascii的。
      
先运行一下,有消息框出来,有字符串提示。根据这段学习的内容,感到至少有两种方法爆破。一是用VB的消息框函数下断,二是查找字符串的方法(查找Try即可),关闭程序。
   
用OD载入程序,点击工具栏上的“设置API断点”,选择“VB APIs”中的rtcMsgBox命令或者在插件上选中“BP rtcMsgBox”命令,或者在OD界面下侧的命令行窗口里输入“BP rtcMsgBox”并回车,均是下了VB的消息框断点。F9运行程序,直接到达断点处,程序断在了系统模块(MSVBVM50.DLL)内。



此时右键点击堆栈窗口中第一行地址,选中“反汇编窗口中跟随”命令,OD就来到了00402622地址处,它的上一行可以看到调用这个函数的call了。



鼠标向上滚动一下,很快就在这个call上面看到了熟悉的字符串“Try Again”!!!!

查找字符串时同样来到了这里,下面就可以找关键跳了。

在错误提示“You Get Wrong”这一句上面有个jmp命令跳过了注册失败,但程序仍然没有到达成功,说明在这一句上面有其他的跳跳过了它。错误提示“You Get Wrong”这一句明显有个跳转到达的标志,沿着这条红线来到跳转处,这一句是跳过了注册成功,那么就用jnz和nop试试吧,成功!(同样jnz修改后会出现注册码正确时反而不能注册成功的问题)。继续。我要查找注册码了。试着用VB专用断点,从网上看到的资料,“BP _vbaStrCmp”是给文本比较下断,试用一下!重载程序,先禁用其他断点,再下断点“BP _vbaStrCmp”,F9运行,输入自己的用户名和假码,点击确定按钮,断下来,直接看到了可疑的字符串,这可能就是注册码了!!!!!!!!!!!

此时还在系统领空,先将这个不能确定真假的字符串复制下来,F9运行,弹出错误对话框,“确定”,然后粘贴上刚才那个字符串,再确定,弹出正确的消息框,这样找到了注册码。



但是注册码是怎么算出来的呢?还得继续研究。重载程序,运行,输入用户名,假码,点确定,(因为断点还在)程序断在了刚才的系统断点处,仍然从堆栈窗口的第一行右键,反汇编窗口中跟随:


来到了程序地址00422539处。它的上一句是调用文本比较函数的call,那么计算注册码肯定在它上方了。

向上好长一段代码,查找到段首(00402310)处,禁用其他断点,在此处下断,重新F9运行,键入用户名和注册码,点“ok”程序断在了这里。
F8单步运行,好多call啊,都在调用VB的运行库,小心翼翼地走吧。程序运行到这里,看到了用户名!

好的,下面的函数什么意思?网上搜一搜吧:取字串长度,在这里是用户名的长度啊。联想到crackme001,是不是也要用到判断用户名空或者长度不小于某个数值呢?小心再小心!
4/15/2017 2:47:18 PM
下面是部分代码及自己的注释:
00402403   .FF15 04414000 call dword ptr ds:[<&MSVBVM50.__vbaHresultCheckObj>] ;MSVBVM50.__vbaHresultCheckObj
00402409   >8B95 50FFFFFF mov edx,dword ptr ss:
0040240F   .8B45 E4       mov eax,dword ptr ss:
00402412   .50            push eax                                             ; /String   取用户名
00402413   .8B1A          mov ebx,dword ptr ds:                           ; |
00402415   .FF15 E4404000 call dword ptr ds:[<&MSVBVM50.__vbaLenBstr>]         ; \__vbaLenBstr得到用户名长度,存入eax
0040241B   .8BF8          mov edi,eax                                          ;edi=eax
0040241D   .8B4D E8       mov ecx,dword ptr ss:
00402420   .69FF FB7C0100 imul edi,edi,0x17CFB                                 ;edi=edi*0x17cfb
00402426   .51            push ecx                                             ; /String
00402427   .0F80 91020000 jo Afkayas_.004026BE                                 ; |溢出则跳
0040242D   .FF15 F8404000 call dword ptr ds:[<&MSVBVM50.#516>]               ; \\rtcAnsiValueBstr ,asc(string)结果在eax中返回 interger
00402433   .0FBFD0      movsx edx,ax                                       ;取用户名第一个字的16进制数值
00402436   .03FA          add edi,edx                                          ;edi=edi+ax=edi+asc(用户名第一个字)
00402438   .0F80 80020000 jo Afkayas_.004026BE0040243E   .57            push edi
0040243F   .FF15 E0404000 call dword ptr ds:[<&MSVBVM50.__vbaStrI4>]         ;将edi中的值由16进制转换成10进制的
00402445   .8BD0          mov edx,eax00402447   .8D4D E0       lea ecx,dword ptr ss:
0040244A   .FF15 70414000 call dword ptr ds:[<&MSVBVM50.__vbaStrMove>]         ;MSVBVM50.__vbaStrMove 将变量值串拷贝到内存中
00402450   .8BBD 50FFFFFF mov edi,dword ptr ss:00402456   .50            push eax
00402457   .57            push edi
接下来又是一堆的不知所云的VB函数,太痛苦了!继续单步至此:
00402510   > \8B45 E8       mov eax,dword ptr ss:                      ;取假码
00402513   .8B4D E4       mov ecx,dword ptr ss:                      ;取真码的一部分
00402516   .8B3D 00414000 mov edi,dword ptr ds:[<&MSVBVM50.__vbaStrCat>]       ;将vbastrcat函数的调用地址存入edi中
0040251C   .50            push eax                                             ;取假码
0040251D   .68 701B4000   push Afkayas_.00401B70                               ;UNICODE "AKA-"
00402522   .51            push ecx                                             ; /String
00402523   .FFD7          call edi                                             ; \vbaStrCat(a,b):把b字符串添加到a字符串后面,得到注册码
00402525   .8B1D 70414000 mov ebx,dword ptr ds:[<&MSVBVM50.__vbaStrMove>]      ;MSVBVM50.__vbaStrMove
0040252B   .8BD0          mov edx,eax
0040252D   .8D4D E0       lea ecx,dword ptr ss:
00402530   .FFD3          call ebx                                             ;<&MSVBVM50.__vbaStrMove>
00402532   .50            push eax
00402533   .FF15 28414000 call dword ptr ds:[<&MSVBVM50.__vbaStrCmp>]          ;MSVBVM50.__vbaStrCmp以字符串比较的形式比较真假码,存入eax中
00402539   .8BF0          mov esi,eax
从代码中没有找到判断用户名长度与注册失败关系的语句,除了不能为空,这个程序没有象CrackMe001那样的保护了。
注册算法:用VB编一个注册机,设上保护,如果用户名未输入或者是其他什么不应该输入的,提示输入错误。
这个地方的算法是,取输入的name的长度,把name的长度乘以0x17cfb,然后加上输入的name的第一个字符的ascii值,得到一个数值,再转成10进制的数,再把得到的值(数字)转换为字符串,附加到字符串“AKA-”后面。
以我输入的用户名为例:
Name:haitian
Serial=vbaLenBstr(“haitian”)=0x7
Serial= Serial*0x17CFB=0x7*0x17CFB=0x A6ADD
Serial=Serial+ rtcAnsiValueBstr(‘h’)= 0x A6ADD+0x68=0x6AB45
Serial=__vbaStrI4(Serial)=682821
Serial=AKA-682821
终于将注册算法找出来了。16进制算法看上去很不舒服,在下面VB的算法部分中直接改成了10进制的:
Private Sub Command1_Click()
'这里未考虑变量的类型,字符与数值直接相连了
Dim str1, lend, str2, str3, str4
If Text1.Text <> "" Then
str1 = (Text1.Text)
lend = Len(str1)
str2 = lend * 97531
str3 = Asc(str1)
str4 = str2 + str3
Text2.Text = "AKA-" & str4Else: MsgBox ("用户名不能为空")
End If
End Sub
下步是汉化,巩固自己的学习成果吧。源程序和注册机、汉化后的程序均已打包上传,另外在百度上也有分享的地址,地址是:
链接: http://pan.baidu.com/s/1nviCB7F 密码: 2cfb

cyril2017 发表于 2017-4-20 21:57

个个都是破解高手啊,新手学习中。支持楼主!{:1_927:}

bjt123 发表于 2017-5-3 13:10

{:1_918:}楼主把整套程序发出来啊

zhanghong 发表于 2017-5-3 13:30

66666666666666666

海天一色001 发表于 2017-5-4 08:13

bjt123 发表于 2017-5-3 13:10
楼主把整套程序发出来啊

源程序和注册机、汉化后的程序均已打包上传   002.rar (19.7 KB, 下载次数: 0) ,另外在百度上也有分享的地址,地址是:
链接: http://pan.baidu.com/s/1nviCB7F 密码: 2cfb

ghoob321 发表于 2017-6-4 08:34

楼主把整套程序发出来啊

orachard 发表于 2017-6-7 16:31

爆破是最简单的,其次是追码,最难就是分析算法!!这个我1年前就完成前两步了,最后的算法分析比较难,很多算法分析非常复杂

zzcl558 发表于 2018-6-28 04:43

谢谢分享!

lushan63 发表于 2018-7-26 23:37

收听了楼主。虽然一个也没看懂,但是还是觉得很有意思。
页: [1]
查看完整版本: 初练160个CrakeMe程序之002