海天一色001 发表于 2020-6-12 17:23

160个Crackme之038学习笔记

本帖最后由 海天一色001 于 2020-7-1 08:28 编辑

第38个CM程序,星级是?级,说明是Name/Serial类型(VB5程序)。先打开这个CyberBlade.2.exe程序,界面如下,需要填写name和key两个文本框;点击“Aboutt”菜单弹出一个提示窗口,作者要求必须找出正确的注册码才算是成功,和上一个有些不大的改变,仍然没有什么有用的信息。
   

不输入name,直接点击“Check”按钮,弹出第一个错误窗口;输入name=52pojie,再点击“Check”按钮,弹出第二个错误窗口;输入key=“1234567890”, 再点击“Check”按钮,弹出第三个错误窗口。
   
第一步、查壳:

无壳,VB程序。
第二步、追码:
用OD载入CyberBlade.2.exe,先出现代码压缩的提示,直接确定进入CPU窗口,中文搜索看看:

内容很少,而且显示内容没有任何错误提示或正确提示的文本,一直以来的文本搜索这次不管用了。那么还有一个查找按钮事件特征码的“816C24”,竟然也没找到,这就比较麻烦了。
先用VB Decompiler来反编译一下本程序吧。

左侧窗口中看到Crackmefrm窗体中有6段子程序,分别是退出按钮、窗体加载、窗体初始化、关于菜单、检查注册码按钮、键盘输入检查,
点击Checkcmd_Click_40E680,在右侧查看对应代码,这里看到了错误或正确提示的文本内容了。然后生成bas文件,再使用bas转map工具生成map文件,在OD中导入,再Ctrl+G,定位于0040E680处这个Check按钮事件的段首,下断点。好象有点不对,这个地址的内容显示不正常:使劲向上向下看,反汇编内绝大数都显示“dd 00”之类的东东。右键选“分析-分析代码”,弹出提示,确定后没有任何改变;

右键再选“分析-从模块中删除分析”,反汇编的内容显示倒是变了,但是内存地址都不对了,0040E680没了!

先不管显示结果了,F9运行,输入name=“52pojie”,key=“123456”,点击“Check”按钮,程序中断于……没有中断!情况有些不对,弹出内存不能读的错误!点击确定,程序中止。反复试了几次,都是这种现象!!!

于是想用其他反编译工具试一试,如SMARTCHK,可以看出在Command1_Click事件里分别取每个字符的ASC码值,但不知道取了之后干什么,所以没有什么用,或者说是自己还不会用:

还有一个WKTVBDebugger,一旦运行引导程序后进入主界面后就出现运行错误,在几个不同的虚拟机中均是同一情况,可能是WKTVBDebugger程序的问题吧。

没办法,回到VB Decompiler这个静态反编译程序中来,将Command1_Click事件反编译代码全部复制下来,再仔细查看:
Private Sub Command1_Click() '40E680
'Data Table: 402AEC
Dim var_98 As Variant                ‘定义var_98 变量 类型为 变体数据类型
Dim var_DC As Variant                ‘变体
Dim var_BC As Variant                ‘变体
Dim var_150 As String                ‘字符型
Dim var_11C As Variant                ‘变体
Dim var_176 As Integer                ‘整数型
loc_40E279: var_9C = Me.txtname.Text                        ‘var_9C=输入的名字
loc_40E289: var_98 = vbNull 'Ignore this                ‘var_98 =没有或者是空?
loc_40E28C: If (var_9C = vbNullString) Then      ‘如果没有输入内容,则弹出提示窗口,必须先键入名字
loc_40E2B0:   MsgBox("You have to enter you name first.", &H40, "Error", var_FC, var_11C)
loc_40E2B5:   var_BC = "": var_DC = "": var_FC = "" 'Ignore this
loc_40E2C0:   Exit Sub
loc_40E2C1: End If
以上部分,作用是要求名字不能为空:

loc_40E2CE: var_9C = Me.txtkey.Text                        ‘此处‘var_9C=输入的注册码
loc_40E2DE: var_98 = vbNull 'Ignore this
loc_40E2E1: If (var_9C = vbNullString) Then
loc_40E305:   MsgBox("You have to enter a key first.", &H40, "Error", var_FC, var_11C)                ‘“你必须先键入一个注册码”
loc_40E30A:   var_BC = "": var_DC = "": var_FC = "" 'Ignore this
loc_40E315:   Exit Sub
loc_40E316: End If
以上部分,作用要求注册码不能为空:

   loc_40E323: var_9C = Me.txtkey.Text
loc_40E333: var_98 = vbNull 'Ignore this
loc_40E336: If (var_9C = vbNullString) Then                ‘注册码至少5个字符
loc_40E35A:   MsgBox("You have to enter at least 5 chars.", &H40, "Error", var_FC, var_11C)
loc_40E35F:   var_BC = "": var_DC = "": var_FC = "" 'Ignore this
loc_40E36A:   Exit Sub
loc_40E36B: End If
作用是要求注册码至少输入5个字符:

   loc_40E38D: var_9C = "" 'Ignore this
loc_40E390: var_98 = vbNull 'Ignore this
loc_40E393: For var_14C = 1 To CVar(Len(Me.txtname.Text)): var_12C = var_14C 'Variant                ‘以名字长度为循环变量的循环计算,Var_12C=Var_14C
loc_40E3C1:   var_FC = Mid(CVar(Me.txtname.Text), CLng(var_12C), 1)                                                ‘取每一个字符
loc_40E3D5:   var_11C = var_94 & CVar(Asc(CStr(var_FC)))                                                               ‘得到每个字符的ASC值并连接起来
loc_40E3D9:   var_94 = var_11C 'Variant
loc_40E3DD:   var_150 = "" 'Ignore this
loc_40E3E0:   var_98 = vbNull 'Ignore this
loc_40E3E3:   var_BC = "": var_DC = "" 'Ignore this
loc_40E3EF: Next var_14C 'Variant
loc_40E3F5: ' Referenced from: 40E422
loc_40E401: HardType 'Ignore this
loc_40E404: If (Len(var_94) > 9) Then                                                                              ‘如果新得到的数值长度大于9
loc_40E41E:   var_94 = Fix((var_94 / 3.141592654)) 'Variant                                        ‘这个数值除以圆周率,并取整
loc_40E422:   GoTo loc_40E3F5                                                                                        ‘直到数字串少于10位
loc_40E425: End If
作用是从Name字符串得出注册码相关的数值:

loc_40E449: var_94 = (var_94 Xor &H30F85678 - CVar(global_76)) 'Variant                              ‘global_76为全局变量,从哪里找到?
这一句执行顺序应该是先异或再相减,但这里的写法在注册算法执行时却是先相减后异或,结果错误。从下面VB Decompiler中复制出未优化的代码(红字部分)与优化后的代码比较,可以看出先异或得出var_94的值,再减去global_76的值。括号的位置写错了,正确的是var_94 = (var_94 Xor &H30F85678) - CVar(global_76)才对。
loc_40E425: push var_94                                                                                                                ‘var_94压栈
loc_40E428: Dim var_AC As Long: var_AC = &H30F85678                                                      ‘var_AC = &H30F85678(821581432)
loc_40E430: Dim var_BC As Variant: var_BC = from_stack_2 Xor from_stack_1                ‘var_BC = var_AC xor var_94
loc_40E434: var_94 = from_stack_1 'Variant                                                                              ‘var_94 =var_BC
loc_40E438: push var_94
loc_40E43B: push Me
loc_40E43E: push from_stack_1.global_76 'String
loc_40E441: Dim var_AC As Variant: var_AC = CVar(from_stack_1) 'Long                              ‘var_AC = CVar(global_76)
loc_40E445: Dim var_BC As Variant: var_BC = (from_stack_2 - from_stack_1)                        ‘var_BC = var_94 - var_AC
loc_40E449: var_94 = from_stack_1 'Variant                                                                              ‘var_94 = var_BC



loc_40E45A: For var_170 = 1 To 10: var_12C = var_170 'Variant                                        ‘这一段代码将注册码与global_52(CLng(var_12C)))反复比较了10次,却什么都不输出
loc_40E46D:   var_9C = Me.txtkey.Text
loc_40E486:   var_98 = vbNull 'Ignore this
loc_40E489:   If (var_9C = global_52(CLng(var_12C))) Then                                        ‘global_52(CLng(var_12C)))是10个假码,从Form_Load()中定义出数值
loc_40E48C:   End If
loc_40E48F: Next var_170 'Variant
本段代码作用不明:

   loc_40E4CE: HardType 'Ignore this
loc_40E4D1: var_150 = "" 'Ignore this
loc_40E4D4: var_98 = "" 'Ignore this
loc_40E4DB: var_BC = "" 'Ignore this

loc_40E4DE: If ((CVar(Me.txtkey.Text) - var_94) = CVar(Len(Me.txtname.Text))) Then                                                      ‘关键跳 如果输入的注册码 - 上面用name计算出的数值 = 输入名字的字符数,则弹出两个正确提示框
loc_40E502:   MsgBox("Wow, you have found a correct key!", &H40, "Correct key", var_FC, var_11C)
loc_40E507:   var_BC = "": var_DC = "": var_FC = "" 'Ignore this
loc_40E533:   MsgBox("Mail me, how you got it: CyberBlade@gmx.net ", &H40, "Correct key!", var_FC, var_11C)
loc_40E538:   var_BC = "": var_DC = "": var_FC = "" 'Ignore this
loc_40E550:   Me.Command2.Caption = "Exit"loc_40E555:   var_98 = vbNull 'Ignore this
以上是注册码正确则弹出正确提示来:

   loc_40E55B: Else                                                                                                                                                                        ‘否则弹出 错误提示框
loc_40E567:   global_80 = (global_80 + 1)                                                                                                                              ‘global_80 全局变量loc_40E570:   var_176 = global_80
loc_40E579:   If (var_176 = 6) Then
loc_40E587:   var_DC = "I can't stand it anymore"
loc_40E597:   var_BC = "-=Do you need a hint ?=-"
loc_40E5B3:   If (MsgBox("":   var_DC = "":   var_FC = "", &H24, var_DC, var_FC, var_11C) = 7) Then
loc_40E5B6:       Exit Sub
loc_40E5BA:   Else
loc_40E5DB:       MsgBox("Forget it.", &H40, "he, he...", var_FC, var_11C)
loc_40E5E0:       var_BC = "":   var_DC = "":   var_FC = "" 'Ignore this
loc_40E5F0:       global_80 = 0
loc_40E5F3:   End If
loc_40E5F6:   Else
loc_40E5FC:   If (var_176 > 3) Then
loc_40E620:       MsgBox("Have you ever been trying to be successful in cracking my password ?", &H20, "Failed", var_FC, var_11C)
loc_40E625:       var_BC = "":   var_DC = "":   var_FC = "" 'Ignore this
loc_40E633:   Else
loc_40E639:       If (var_176 <= 3) Then
loc_40E65D:         MsgBox("Sorry, wrong key.", &H40, "Failed", var_FC, var_11C)
loc_40E662:         var_BC = "":       var_DC = "":       var_FC = "" 'Ignore this
loc_40E66D:       End If
loc_40E66D:   End If
loc_40E66D:   End If
loc_40E66D: End If
以上是注册码错误,则弹出错误提示窗口。

loc_40E677: Me.txtkey.SetFocus
loc_40E67C: var_98 = vbNull 'Ignore this
loc_40E67F: Exit Sub
End Sub
从中可以得出注册算法(VB代码):
Option ExplicitPrivate Sub Command1_Click()
Dim Name As StringDim var_94 As Variant                  'var_94是CM程序中反编译出的地址,作为注册码使用
Dim i, global_76 As Integer            'global_76是CM程序中的全局变量,在Form_Load()和Form_Initialize()中定义并计算出数值
Name = Text1.Text
If Len(Name) < 5 Then    MsgBox ("请输入至少5个字符,如果不够5个字符,默认用户名为“52pojie”!")
    Text1.Text = "52pojie"
    Text2.Text = "346288390"
    Exit Sub
End If
For i = 1 To Len(Name)
      var_94 = var_94 & CVar(Asc(Mid(Name, i, 1)))
      'Form1.Print var_94
Next
Text1.Text = Name
While (Len(var_94) > 9)                                       '如果新得到的数字串长度大于9
   var_94 = Int(var_94 / 3.141592654) 'Variant                           '反复除以圆周率,并取整,直到数字少于10位
Wend
'var_94 = var_94 Xor &H30F85678 - global_76                  '这个运算顺序是先减再异或,从CM中看到是先异或后减,所以结果老出错,郁闷了很久才找到问题所在
'var_94 = (var_94 Xor &H30F85678) - global_76 'Variant         '&H30F85678(821581432) global_76为全局变量,从哪里找到?
var_94 = (var_94 Xor 821581432) - 55475 + Len(Name)
Text2.Text = var_94
End Sub
用注册机算出Name=“52pojie”,Key=“346288390”;Name=“haitianyise”,Key=“717489583”,分别输入CyberBlade.2.exe中运行,均成功了。

第三步、爆破:
从追码过程中已知loc_40E4DE一句是关键跳,跳走则是失败,那么就让它不跳即可。
在VB Decompiler的反编译窗口中0040E4DE处显示为
loc_40E4DE: If ((CVar(Me.txtkey.Text) - var_94) = CVar(Len(Me.txtname.Text))) Then
在反汇编窗口0040E4DE则显示为下图中
loc_40E4DE: BranchF loc_40E55B

从网上查看了许多参考资料,包括论坛中大神鬼手56的《160个Crackme038之P-Code初窥门径》、Pnmker的《160个CrackMe练手之038》、china豪的《160个CrackMe之038 菜鸟初探p-code》等文章,基本上明白是将BranchF 改为BranchT。
习惯性用OD加载上CyberBlade.2.exe,在CPU窗口右键转到0040E4DE处,在HEX数据栏中右键点击“1C”,选择“二进制—编辑”选项,在弹出窗口中将C改成D,



确定后再将修改后的文件保存为CyberBlade.2.BranchT.exe,运行后随意输入5个字符以上的Name,再随意输入数字,点击“Check”按钮,弹出第一个正确提示窗口,确定后又弹出第二个提示窗口,爆破成功。
练习完这个程序,感觉VB的P-code代码确实很难理解。160个CM中还有一些用VB的P-code代码编写的,下一步还得努力学习这方面的知识,特别是这次没有成功运行的WKTVBDebugger程序,需要研究一下到底怎么回事。盼望有大神指点!
附件,含CM原程序、爆破后的程序、注册机、OD的调试文件、VB Decompiler生成的bas文件等。百度链接是:http://pan.baidu.com/s/1skMkJY9,密码: 86pm,160个CM、我已练习过的前38个crackme程序(不含012)都在里面。
上个百度链接被百度封了,只能单独分享一个文件了,文件夹无法再分享了!!!!下面的链接只有第38个CM,没有其他的了!
链接:https://pan.baidu.com/s/13jxgHy3KiZ_Qq0d1KOuY4Q
提取码:us2u

Johnny_alex 发表于 2020-6-14 22:32

本人小白,但悟性较高,一直期待成为 像楼主一样的或高于楼主的 “高手”,不期望能成为“大神”,就是不知道什么时候才能像 楼主的“高手”一样……,求能有 好的师傅带一带,指点一二……。

2321490 发表于 2020-6-12 18:20

感谢分享!!

z236293824 发表于 2020-6-12 21:07

感谢分享!!

lostguard 发表于 2020-6-12 21:59

多谢分享

超大红细胞 发表于 2020-6-12 22:51

牛逼了,感谢分享~~

白泽1994 发表于 2020-6-12 23:50

大佬流弊,谢谢大佬分享

bennyt 发表于 2020-6-13 00:08

不错的笔记,支持个。

wapjcxz 发表于 2020-6-13 07:00

我……默默地看

OO2OO 发表于 2020-6-13 07:17

很详细,学习了,感谢分享

海贼王是路飞的 发表于 2020-6-13 13:55

感谢分享
页: [1] 2
查看完整版本: 160个Crackme之038学习笔记