CrackMe-013

发布于 2023-04-14  71 次阅读


Start

0x01 信息收集

查壳,VB程序:

image.png

运行存在两个CrackMe:

image.png

CM1.0为Serial:

image.png

CM2.0为Serial/Name:

image.png

CM2中如果Name长度小于5会在Serial中显示At least 5 characters

image.png

0x02 流程分析

CM1.0,下vb的api断点_vbaStrComp

image.png

运行程序,输入111111,点击Try程序断下:

image.png

单步往下可以看到将两个字符串以及输入的字符串的长度压入栈中,然后调用msvbvm50.dll的函数,猜测应该就是比较字符串的长度:

image.png

经过测试可以发现Serial是固定值7730050

image.png

重新运行程序,输入7730050,成功Crack:

image.png

选择CM2.0,在SetWindowsTextA的函数头下断,然后往回跟,这里就是注册失败的地方,往上的je指令是跳过提示失败的地方:

image20210823223956059.png

由于堆栈的内容是不会清空的,所以往下翻,翻到了疑似真正Serial的地方:26023-94362

image20210818231137084.png

VB Decompiler反编译找到关键回调函数,关键处理就在两个For循环:

Dim var_90 As Long
Dim var_1CC As Variant
If (Len(Me.Text1.Text) < 5) Then
   Me.Text2.Text = "At least 5 characters!"
   Exit Sub
End If
var_94 = "0110617121214051216101106141404110614140411091211100810101608040610121608100416"
var_98 = Me.Text1.Text
var_A8 = 1 'Variant
For var_108 = 4 To CVar(Len(var_98)): var_C8 = var_108 'Variant
 var_90 = CLng((CDbl(var_90) + (CDbl(Asc(Mid$(var_98, CLng(var_C8), 1))) * Val(Mid$(var_94, CLng((var_A8 * 3)), 3)))))
 If ((var_A8 + 1) >= 39) Then
   var_A8 = 0 'Variant
 End If
Next var_108 'Variant
var_A8 = 1 'Variant
For var_168 = 4 To CVar(Len(var_98)): var_C8 = var_168 'Variant
 var_1CC = CVar((CDbl((Asc(Mid$(var_98, CLng(var_C8), 1)) * Asc(Mid$(var_98, CLng((var_C8 - 1)), 1)))) * Val(Mid$(var_94, CLng((var_A8 * 2)), 2)))) 'Double
 var_178 = (var_178 + var_1CC) 'Variant
 If ((var_A8 + 1) >= 39) Then
   var_A8 = 0 'Variant
 End If
Next var_168 'Variant
If (Me.Text2.Text = LTrim$(Str$(var_90)) & "-" & LTrim$(Str$(var_178))) Then
  Me.Command2.Visible = False
  Me.Command1.Visible = False
  Me.Command5.Visible = True
  Me.Command3.Visible = False
  Me.Text2.Visible = False
  Me.Frame3.Visible = True
  Me.Label3.Caption = "Congratulation " & Me.Text1.Text & " !"
Else
  Me.Text2.Text = "Try Again!"
End If
Exit Sub

比较长拆分一下:

a = Mid$(var_98, CLng(var_C8), 1)
b = Mid$(var_94, CLng(var_A8 * 3), 3)
res1 = CLng(CDbl(Asc(a)) * Val(b))


a = Mid$(var_98, CLng(var_C8), 1)
b = Mid$(var_98, CLng((var_C8 - 1)), 1)
c = CDbl(Asc(a) * Asc(b))
d = Mid$(var_94, CLng((var_A8 * 2)), 2)
res2 = CVar(c * Val(d))

VB相关函数:

Asc: Asc("ab")=Asc("a")=97
Val: Val("123")=123; Val("011")=11
Mid: Mid("123", 1, 1)="1" ;注意这里的索引从1开始索引,类似于sql的substr也是从1开始索引
Str: Str(123)="123"
CDbl: 转成双精度浮点数
CLng: 转成长整型整数

0x03 注册机

这里是想用Python写注册机的,不过发现有点问题,所以直接用VB写,顺便学一下VB的语法,翻了一下教程基本上可以速成,这里反编译的语法跟实际的语法还是有区别:

Console Application版本:

Imports System

Module Program
   Sub Main(args As String())
       Dim a As String
       Dim b As String
       Dim name As String
       Dim j As VariantType
       Dim index As VariantType
       Dim res1 As VariantType
       Dim res2 As VariantType
       Dim key As String
       index = 1 'Variant
       '自己改name的值就行了'
       name = "123456"
       key = "0110617121214051216101106141404110614140411091211100810101608040610121608100416"
       res1 = 0
       For i = 4 To Len(name) : j = i 'Variant
           Console.WriteLine(i)
           a = Asc(Mid(name, i, 1))
           b = Val(CLng(Mid(key, index * 3, 3)))
           index += 1
           res1 += a * b
       Next i 'Variant

       index = 1 'Variant
       For i = 4 To Len(name) : j = i 'Variant
           Console.WriteLine(i)
           a = CDbl(Asc(Mid(name, j, 1)) * Asc(Mid(name, j - 1, 1)))
           b = Val(Mid(key, index * 2, 2)) 'Double
           index += 1
           res2 += a * b
       Next i 'Variant
       Console.WriteLine("Serial:" & res1 & "-" & res2)
   End Sub
End Module

Form Applicaton 版本:

Public Function GenerateSerial(name) As String
   Dim a As String
   Dim b As String
   Dim j As VariantType
   Dim index As VariantType
   Dim res1 As VariantType
   Dim res2 As VariantType
   Dim key As String
   index = 1 'Variant
   key = "0110617121214051216101106141404110614140411091211100810101608040610121608100416"
   res1 = 0
   For i = 4 To Len(name) : j = i 'Variant
   Console.WriteLine(i)
   a = Asc(Mid(name, i, 1))
   b = Val(CLng(Mid(key, index * 3, 3)))
   index += 1
   res1 += a * b
   Next i 'Variant
   index = 1 'Variant
   For i = 4 To Len(name) : j = i 'Variant
   Console.WriteLine(i)
   a = CDbl(Asc(Mid(name, j, 1)) * Asc(Mid(name, j - 1, 1)))
   b = Val(Mid(key, index * 2, 2)) 'Double
   index += 1
   res2 += a * b
   Next i 'Variant
   GenerateSerial = res1 & "-" & res2
End Function

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
   SerialText.Text = GenerateSerial(NameText.Text)
End Sub
image20210824234945319.png

Result:

image20210824234605516.png
image20210824234718517.png
image20210824235701365.png

ps: CM12 是16位的DOS程序没有运行环境就不写了

End