CrackMe-013

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

avatar