160 个 CrackMe 之 112 - BaSiLik 和 138 - Sortof 的p-code代码算法分析和注册机实现
本帖最后由 solly 于 2019-7-3 13:20 编辑160 个 CrackMe 之 112 - BaSiLik 是一个 VB6 p-code 程序。并且使用 upx 1.0.1 打包压缩了,在其反调试代码中还有这方面的检查。
启动 CrackMe 后,如下图:
这个 Unique 码,是根据机器硬盘的信息生成的。另外还要输入用户名,公司名,序列号,一起进行验证。
用 VB Decompiler 打开,可以看到主要调用在 Form.Load() 和 cmdCheck_Click()中。如下两图所示:
以及:
具体的代码如下:Private Sub Form_Load() '404420
'Data Table: 4030F8
loc_4043FC: Proc_1_5_404640()' SmartCheck 检查,通过 FindWindow("NMSCMW50", 0) 检查
loc_404401: Proc_1_8_404C24()' crack 文件改名和 unpack 检查(文件大小检查)
loc_404406: Proc_1_6_404A48()' w32dasm8 检查,这个检查有问题,没有 %windir%\\w32dasm8.ini 文件也报安装了 W32Dasm,是由于UAC权限不够的原因导致的。
loc_40440B: Proc_1_4_404580()' Registry Monitor 检查,通过 FindWindow("RegmonClass", 0) 检查
loc_404410: Proc_1_3_404810()' IDA 检查。通过注册表检查,注册表项 "HKEY_CURRENT_USER\Software\Datarescue\IDA"
loc_404415: Proc_1_8_404C24()' 再一次crack 文件改名和 unpack 检查(文件大小检查)
loc_40441A: Proc_1_2_405180()' GetVolumeInformationA("C:\")
loc_40441F: Exit Sub
End Sub
以及:
Private Sub cmdCheck_Click() '404474
'Data Table: 4030F8
loc_404450: Proc_1_5_404640()' SmartCheck 检查,通过 FindWindow("NMSCMW50", 0) 检查
loc_404455: Proc_1_8_404C24()' crack 文件改名和 unpack 检查(文件大小检查)
loc_40445A: Proc_1_6_404A48()' w32dasm8 检查,这个检查有问题,没有 %windir%\\w32dasm8.ini 文件也报安装了 W32Dasm,是由于UAC权限不够的原因导致的。
loc_40445F: Proc_1_4_404580()' Registry Monitor 检查,通过 FindWindow("RegmonClass", 0) 检查
loc_404464: Proc_1_3_404810()' IDA 检查。通过注册表检查,注册表项 "HKEY_CURRENT_USER\Software\Datarescue\IDA"
loc_404469: Proc_1_7_404720()' SoftICE 检查。扫描 C 盘根目录文件,将每个文件通过调用 Proc_1_9_404920() 进行处理,就是检查 Autoexec.bat 文件中有没有包含 winice.exe 的命令行,这个检查会引起文件访问冲突,导致 Run-time error '70'。
loc_40446E: Proc_1_1_404EAC()' 对输入的用户名,公司名和序列号进行检查,只有这些数据的长度都大于8个字符时,才进行序列号验证,验证函数为 Proc_1_0_405730()。
loc_404473: Exit Sub
End Sub
我们主要分析其序列号验证过程,其它反调试代码不在这说明。
主要有两个过程,一个是生成 Unique 码(Proc_1_2_405180()),另一个是序列号验证(Proc_1_1_404EAC())。
我们通过 VB Decompiler 静态分析,Proc_1_2_405180() 反编译代码如下:
Public Sub Proc_1_2_405180
'Data Table: 402C8C
loc_404F05: Me(40) = CStr(Space(&H100))
loc_404F1F: Me(60) = CStr(Space(&H100))
loc_404F36: var_A0 = Me(60)
loc_404F85: Me(64) = GetVolumeInformationA("C:\", Me(40), Len(Me(40)), Me(44))
loc_404FC3: Me(40) = CStr(Left(Me(40), (InStr(1, Me(40), vbNullString, 0) - 1)))
loc_404FFC: Me(60) = CStr(Left(Me(60), (InStr(1, Me(60), vbNullString, 0) - 1)))
loc_405026: Me(48) = CStr(Trim(Hex(Me(44))))
loc_405062: Me(48) = CStr(String((8 - Len(Me(48))), "0") & CVar(Me(48)))
loc_4050B3: Me(48) = CStr(Left(Me(48), 4) & "-" & Right(Me(48), 4))
loc_4050E3: Me(48) = Replace(Me(48), "-", vbNullString, 1, -1, 0)
loc_4050F3: Me(48) = StrReverse(Me(48))
loc_40515C: Set var_148 = MemVar_406008.Text4
loc_405162: frmMain.Text4.Text = CStr(Left(Me(60), 1) & "54-" & CVar(Me(48)) & "-05" & Right(Me(60), 1))
loc_40517C: Exit Sub
End Sub
其中除了有一行反编译不正确其它基本还是正确的,翻译成 VB 代码如下:
Private Declare Function GetVolumeInformation Lib "kernel32.dll" _
Alias "GetVolumeInformationA" _
(ByVal p1 As String, _
ByVal p2 As String, _
ByVal p3 As Long, _
ByRef p4 As Long, _
ByRef p5 As Long, _
ByRef p6 As Long, _
ByVal p7 As String, _
ByVal p8 As Long) As Boolean
Public Function getUnique()
Dim result As Boolean
Dim nVolumeNameSize As Long, lpVolumeSerialNumber As Long, p2 As Long, p3 As Long
Dim lpVolimeNameBuffer As String
Dim lpFileSystemNameBuffer As String
Dim s1, s2, s3 As String
nVolumeNameSize = 255
lpVolimeNameBuffer = Space(256)
lpFileSystemNameBuffer = Space(256)
lpVolumeSerialNumber = 0
result = GetVolumeInformation("C:\", lpVolimeNameBuffer, nVolumeNameSize, lpVolumeSerialNumber, p2, p3, lpFileSystemNameBuffer, nVolumeNameSize)
If lpVolumeSerialNumber <> 0 Then
's1 = Left(lpVolimeNameBuffer, (InStr(1, lpVolimeNameBuffer, vbNullChar, vbBinaryCompare) - 1)) '去掉'\0'及后面的空格符
s2 = Left(lpFileSystemNameBuffer, (InStr(1, lpFileSystemNameBuffer, vbNullChar, vbBinaryCompare) - 1)) '去掉'\0'及后面的空格符,文件系统格式:"NTFS","FAT32" 等。
s3 = Trim(Hex(lpVolumeSerialNumber)) '序列号转成 Hex 格式字符串
s3 = String(8 - Len(s3), "0") & s3
's3 = Left(s3, 4) & "-" & Right(s3, 4)
's3 = Replace(s3, "-", vbNullString, 1, -1, vbBinaryCompare)
s3 = StrReverse(s3) '反转换序列号字符串
' 返回 Unique 字符串
getUnique = Left(s2, 1) & "54-" & s3 & "-05" & Right(s2, 1)
Else
getUnique = ""
End If
End Function
主要用到了磁盘C:\的序列号和文件系统格式(如 "NTFS","FAT32"等)。CrackMe 这段代码参考了以下地址的 Example 部分,连没有用到的代码都复制过来了(上面代码注释掉的部分):
http://www.jasinskionline.com/wi ... umeinformation.html
另一个过程 Proc_1_1_404EAC() 先验证输入的信息是否合法(输入信息的长度要大于或等于8),然后调用 Proc_1_0_405730() 验证序列号,这个验证过程(Proc_1_0_405730())内容如下:
Public Sub Proc_1_0_405730
'Data Table: 402C8C
Dim var_D0 As Integer
Dim var_E4 As Variant
Dim var_88 As TextBox
loc_4051E4: Set var_88 = MemVar_406008.Text4
loc_40520C: Me(68) = Replace(frmMain.Text4.Text, "-", vbNullString, 1, -1, 0)
loc_40521C: Me(76) = CStr(0)
loc_405230: For var_90 = 1 To CInt(Len(Me(68))): Me(96) = var_90 'Integer
loc_405257: Me(72) = CStr(Mid$(Me(68), CLng(Me(96)), 1))
loc_405279: Me(76) = CStr((CDbl(Asc(Me(72))) + CDbl(Me(76))))
loc_405284: Next var_90 'Integer
loc_40528D: Me(80) = CStr(0)
loc_4052A6: Set var_88 = MemVar_406008.Text1
loc_4052BC: For var_D4 = 1 To CInt(Len(frmMain.Text1.Text)): Me(98) = var_D4 'Integer
loc_4052CE: Set var_88 = MemVar_406008.Text1
loc_4052F6: Me(84) = CStr(Mid$(CVar(frmMain.Text1.Text), CLng(Me(98)), 1))
loc_40531D: Me(80) = CStr((CDbl(Asc(Me(84))) + CDbl(Me(80))))
loc_405328: Next var_D4 'Integer
loc_405331: Me(88) = CStr(0)
loc_40534A: Set var_88 = MemVar_406008.Text2
loc_405360: For var_E8 = 1 To CInt(Len(frmMain.Text2.Text)): Me(100) = var_E8 'Integer
loc_405372: Set var_88 = MemVar_406008.Text2
loc_40539A: Me(92) = CStr(Mid$(CVar(frmMain.Text2.Text), CLng(Me(100)), 1))
loc_4053C1: Me(88) = CStr((CDbl(Asc(Me(92))) + CDbl(Me(88))))
loc_4053CC: Next var_E8 'Integer
loc_4053DD: Set var_88 = MemVar_406008.Text1
loc_405424: Me(104) = CStr(Mid$(CVar(Replace(frmMain.Text1.Text, " ", vbNullString, 1, -1, 0)), 4, 2))
loc_405449: Set var_88 = MemVar_406008.Text2
loc_405490: Me(108) = CStr(Mid$(CVar(Replace(frmMain.Text2.Text, " ", vbNullString, 1, -1, 0)), 5, 3))
loc_4054B5: Set var_88 = MemVar_406008.Text4
loc_4054FC: Me(112) = CStr(Mid$(CVar(Replace(frmMain.Text4.Text, " ", vbNullString, 1, -1, 0)), 5, 3))
loc_405521: Set var_88 = MemVar_406008.Text3
loc_40552F: var_E4 = CVar(frmMain.Text3.Text) 'String
loc_40558C: var_D0 = Ucase(CVar("34" & Me(112) & "-" & Me(76) & StrReverse(Me(80)) & "-" & Me(108) & Me(88) & "-" & Me(104)))
loc_4055B7: If CBool(var_E4 <> var_D0) Then
loc_4055D3: MsgBox "Incorrect Serial Number!", 0, var_D0, var_E4, var_11C
loc_4055EF: Set var_88 = MemVar_406008.Text1
loc_4055F5: frmMain.Text1.Text = vbNullString
loc_405609: Set var_88 = MemVar_406008.Text2
loc_40560F: frmMain.Text2.Text = vbNullString
loc_405623: Set var_88 = MemVar_406008.Text3
loc_405629: frmMain.Text3.Text = vbNullString
loc_405631: Exit Sub
loc_405635: Else
loc_405646: (0).Visible = %x1b
loc_405659: Set var_88 = MemVar_406008.Text2
loc_40565F: frmMain.Text2.Visible = False
loc_405672: Set var_88 = MemVar_406008.Text3
loc_405678: frmMain.Text3.Visible = False
loc_40568B: Set var_88 = MemVar_406008.Text4
loc_405691: frmMain.Text4.Visible = False
loc_4056A4: Set var_88 = MemVar_406008.Label1
loc_4056AA: frmMain.Label1.Visible = False
loc_4056BD: Set var_88 = MemVar_406008.Label2
loc_4056C3: frmMain.Label2.Visible = False
loc_4056D6: Set var_88 = MemVar_406008.Label3
loc_4056DC: frmMain.Label3.Visible = False
loc_4056EF: Set var_88 = MemVar_406008.Label4
loc_4056F5: frmMain.Label4.Visible = False
loc_405708: Set var_88 = MemVar_406008.cmdCheck
loc_40570E: frmMain.cmdCheck.Visible = False
loc_405721: Set var_88 = MemVar_406008.Label5
loc_405727: frmMain.Label5.Visible = True
loc_40572F: End If
loc_40572F: Exit Sub
End Sub
跟据以上反编译代码,实现序列号的计算过程如下:
Public Function getSerial(unique As String, name As String, company As String) As String
Dim i As Long, j As Long, k As Long
Dim s1 As String, s2 As String, s3 As String, s4 As String
Dim s5 As String, s6 As String, s7 As String, s8 As String
Dim ss1 As Long, ss2 As Long, ss3 As Long
s1 = Replace(unique, "-", vbNullString, 1, -1, vbBinaryCompare)
ss1 = 0
For i = 1 To Len(s1)
ss1 = ss1 + Asc(Mid(s1, i, 1))
Next i
ss2 = 0
For i = 1 To Len(name)
ss2 = ss2 + Asc(Mid(name, i, 1))
Next i
ss3 = 0
For i = 1 To Len(company)
ss3 = ss3 + Asc(Mid(company, i, 1))
Next i
s3 = Replace(name, " ", vbNullString, 1, -1, vbBinaryCompare)
s4 = Mid(s3, 4, 2)
s5 = Replace(company, " ", vbNullString, 1, -1, vbBinaryCompare)
s6 = Mid(s5, 5, 3)
s7 = Replace(unique, " ", vbNullString, 1, -1, vbBinaryCompare)
s8 = Mid(s7, 5, 3)
getSerial = UCase("34" & s8 & "-" & CStr(ss1) & StrReverse(ss2) & "-" & s6 & ss3 & "-" & s4)
' clipboard
VB.Clipboard.Clear
VB.Clipboard.SetText getSerial, vbCFText
End Function
生成序列号后,返回界面输入:
点“Check it!”,得到成功信息提示:
实现的注册机的界面如下:
也是用 VB6 完成的。
下面针对 CrackMe 的问题进行相应的修改,让其可以在最新系统上可以正常运行,前面的反编译代码我也进行了注释,下面是修改内容:
'(1)
' 函数loc_404469: Proc_1_7_404720(),会引起错误:Run-time error '70': Permission denied
' 可以将此函数中的 For 循环的开始值改大(loc_4046DA: push 1 ),从而不进入循环来避免出错。
' 004046DAF4 01 AD 1A 74 FF FE 63 6E FF 96 00 04 68 FF 93
' 将 push 01 改成 push 7F, C 盘根目录一般不会有127个以上的文件吧(文件中的位置:0x000046DA)
' 004046DAF4 7F AD 1A 74 FF FE 63 6E FF 96 00 04 68 FF 93
'(2)
' 将文件名改名判断patch掉
' 00404AD31C 89 00 27 F4 FE 27 34 FF 27 54 FF F5 00 00 00
' 改成(文件中的位置:0x00004AD3)
' 00404AD31E 89 00 27 F4 FE 27 34 FF 27 54 FF F5 00 00 00
'(3)
' 将文件大小判断patch掉
' 00404BDC1C 92 01 27 F4 FE 27 34 FF 27 54 FF F5 00 00 00
' 改成(文件中的位置:0x00004BDC)
' 00404BDC1E 92 01 27 F4 FE 27 34 FF 27 54 FF F5 00 00 00
'(4)
' 函数 loc_404406: Proc_1_6_404A48() 由于 UAC 限制,需要管理员权限才能正常运行,也Patch掉
' 004049FE1C DC 00 27 F4 FE 27 14 FF 27 34 FF F5 00 00 00
' 改成(文件中的位置:0x000049FE)
' 004049FE1E DC 00 27 F4 FE 27 14 FF 27 34 FF F5 00 00 00
改完后,对比一下修改是否正确:I:\Downloads\crack\112_BaSiLiK>fc /b CrackMe_unpacked_cracked.exe CrackMe_unpacked.exe
正在比较文件 CrackMe_unpacked_cracked.exe 和 CRACKME_UNPACKED.EXE
000046DB: 7F 01
000049FE: 1E 1C
00004AD3: 1E 1C
00004BDC: 1E 1C
修改过程中用的二进制工具 UltraEditor。通过上面的反编译可以找到指令地址,在OD数据区可以找到指令数据,如下图:
上面的 1C 就是要修改的指令,复制出指令数据,直接在 UltraEditor 中搜索即可,不用去计算RAV之类的了:
可以搜到指令在文件中的位置:
然后直接修改保存就可以了。
完毕!!!
160 个 CrackMe 之 138 - Sortof 的注册算法分析和注册机实现
本帖最后由 solly 于 2019-7-4 09:09 编辑160 个 CrackMe 之 138 - Sortof 是一个 VB5 p-code的 CrackMe。
启动后界面如下,需要输入用户名和序列号进行验证:
使用 VB Decompliler 进行静态反编译分析,其验证算法在按钮事件处理过程内,如下:
Private Sub Command1_Click() '41AAF4
'Data Table: 401D40
Dim var_194 As String
Dim var_B4 As Variant
Dim var_1EC As Variant
loc_41A54C: On Error Goto loc_41AABF
loc_41A559: If Not((X = 1)) Then
loc_41A55C: GoTo loc_41AABF
loc_41A55F: End If
'X 是一个全局变量,在 Form_Load() 事件中赋值,X = 1
'If X = 0 Then
' Exit Sub()
'End If
loc_41A564: var_94 = vbNullString 'Variant
loc_41A578: var_C4 = Chr(&H32) 'Variant
loc_41A58C: var_D4 = Chr(&H33) 'Variant
loc_41A5A0: var_E4 = Chr(&H34) 'Variant
loc_41A5B4: var_F4 = Chr(&H35) 'Variant
loc_41A5C8: var_104 = Chr(&H36) 'Variant
loc_41A5DC: var_114 = Chr(&H37) 'Variant
loc_41A5E5: var_124 = 0 'Variant
' 初始化变量
'var_94 = ""
'var_C4 = "2", var_D4 = "3", var_E4 = "4", var_CF4 = "5", var_C104 = "6", var_C114 = "7"
'var_124 = 0
'
loc_41A6C3: var_194 = Me.Text1.Text & Me.Text1.Text & Me.Text1.Text & Me.Text1.Text & Me.Text1.Text & Me.Text1.Text & Me.Text1.Text & Me.Text1.Text & Me.Text1.Text
loc_41A711: var_1BC = CVar(var_194 & Me.Text1.Text & Me.Text1.Text & Me.Text1.Text) 'Variant
'取用户名,并重复12次
'var_1BC =Text1.Text & Text1.Text & Text1.Text & Text1.Text & Text1.Text & Text1.Text & Text1.Text & Text1.Text & Text1.Text & Text1.Text & Text1.Text & Text1.Text
'
loc_41A75F: ' Referenced from: 41A9C5
loc_41A7AF: var_1BC = Right(var_1BC, CLng((Len(var_1BC) - 1))) 'Variant
loc_41A811: var_1BC = Right(var_1BC, CLng((Len(var_1BC) - 1))) 'Variant
loc_41A873: var_1BC = Right(var_1BC, CLng((Len(var_1BC) - 1))) 'Variant
loc_41A87D: var_B4 = var_94 & (var_C4 + CVar(Asc(CStr(Left(var_1BC, 1))))) & (var_D4 + CVar(Asc(CStr(Left(var_1BC, 1))))) & (var_E4 + CVar(Asc(CStr(Left(var_1BC, 1)))))
loc_41A8D5: var_1BC = Right(var_1BC, CLng((Len(var_1BC) - 1))) 'Variant
loc_41A937: var_1BC = Right(var_1BC, CLng((Len(var_1BC) - 1))) 'Variant
loc_41A999: var_1BC = Right(var_1BC, CLng((Len(var_1BC) - 1))) 'Variant
loc_41A9A3: var_B4 = var_B4 & (var_F4 + CVar(Asc(CStr(Left(var_1BC, 1))))) & (var_104 + CVar(Asc(CStr(Left(var_1BC, 1))))) & (var_114 + CVar(Asc(CStr(Left(var_1BC, 1)))))
loc_41A9A7: var_94 = var_B4 'Variant
' 上面这几行伪代码的顺序有问题,var_B4 是分开多次赋值,这里全合并在一起,取值就不对了(是 VB Decompiler 优化的显示的问题)。正确应该如下顺序:
'var_B4 = var_94 & (var_C4 + CVar(Asc(CStr(Left(var_1BC, 1)))))
'var_1BC = Right(var_1BC, CLng((Len(var_1BC) - 1))) 'Variant
'var_B4 = var_B4 & (var_D4 + CVar(Asc(CStr(Left(var_1BC, 1)))))
'var_1BC = Right(var_1BC, CLng((Len(var_1BC) - 1))) 'Variant
'var_B4 = var_B4 & (var_E4 + CVar(Asc(CStr(Left(var_1BC, 1)))))
'var_1BC = Right(var_1BC, CLng((Len(var_1BC) - 1))) 'Variant
' 另外半部分
'var_B4 = var_B4 & (var_F4 + CVar(Asc(CStr(Left(var_1BC, 1)))))
'var_1BC = Right(var_1BC, CLng((Len(var_1BC) - 1))) 'Variant
'var_B4 = var_B4 & (var_104 + CVar(Asc(CStr(Left(var_1BC, 1)))))
'var_1BC = Right(var_1BC, CLng((Len(var_1BC) - 1))) 'Variant
'var_B4 = var_B4 & (var_114 + CVar(Asc(CStr(Left(var_1BC, 1)))))
'var_1BC = Right(var_1BC, CLng((Len(var_1BC) - 1))) 'Variant
'将值转赋给另一个变量,后面用新变量进行判断
' var_94 = var_B4
'
loc_41A9B6: If (var_124 = 1) Then
loc_41A9B9: GoTo loc_41A9DC
loc_41A9BC: End If
loc_41A9C1: var_124 = 1 'Variant
loc_41A9C5: GoTo loc_41A75F
'If var_124 = 0 Then
' var_124 = 1
'End If
'
loc_41A9D8: var_200 = CVar(Me.Left) 'Variant
loc_41A9DC: ' Referenced from: 41A9FE
loc_41A9DC: ' Referenced from: 41A9B9
loc_41A9EB: If (Len(var_94) < 12) Then
loc_41A9FA: var_94 = "0" & var_94 'Variant
loc_41A9FE: GoTo loc_41A9DC
loc_41AA01: End If
'当计算的序列号长度不足12位时,前面补"0"
'While Len(var_94) <12
' var_94 = "0" & var_94
'Wend
loc_41AA1B: var_210 = "1012041024412" 'Variant
loc_41AA22: var_94 = var_94 'Variant
loc_41AA35: If (Len(var_94) > 12) Then
loc_41AA4B: var_94 = Left(var_94, &HC) 'Variant
loc_41AA4F: End If
'var_210 = "1012041024412"' 迷惑用的,没有用到这个变量
'计算的序列号长度大于12时截成12位长度
'If (Len(var_94) > 12) Then
' var_94 = Left(var_94, 12)
'End If
loc_41AA58: If (X = 1) Then
loc_41AA7B: var_1EC = Not (CVar(Me.Text2.Text) = var_94)
loc_41AA87: If CBool(var_1EC) Then
loc_41AA8A: GoTo loc_41AABF
loc_41AA8D: End If
loc_41AA8D: End If
loc_41AAAE: MsgBox "Well I" & Chr(39) & "ll be damned!!nice job", 0, "correct", var_1EC, var_260
loc_41AABE: Exit Sub
'If X = 1 Then
' 计算的注册码与输入的注册码进行比较
' If Text2.Text = var_94 Then
' 提示注册成功
' MsgBox "Well I" & Chr(39) & "ll be damned!!nice job", 0, "correct"
' Exit Sub()
' End If
'End If
'下面是提示注册失败
loc_41AABF: ' Referenced from: 41AA8A
loc_41AABF: ' Referenced from: 41A55C
loc_41AABF: ' Referenced from: 41A54C
loc_41AAE0: MsgBox "sorry! try again", 0, "try again", var_1EC, var_260
loc_41AAF0: Exit Sub
End Sub
不过,VB Decompiler 进行伪代码显示优化时,调动了代码顺序,会有问题,主要是下面几行中代码,那个 var_B4 变量的赋值合并有问题,见我后面的代码:
loc_41A7AF: var_1BC = Right(var_1BC, CLng((Len(var_1BC) - 1))) 'Variant
loc_41A811: var_1BC = Right(var_1BC, CLng((Len(var_1BC) - 1))) 'Variant
loc_41A873: var_1BC = Right(var_1BC, CLng((Len(var_1BC) - 1))) 'Variant
loc_41A87D: var_B4 = var_94 & (var_C4 + CVar(Asc(CStr(Left(var_1BC, 1))))) & (var_D4 + CVar(Asc(CStr(Left(var_1BC, 1))))) & (var_E4 + CVar(Asc(CStr(Left(var_1BC, 1)))))
loc_41A8D5: var_1BC = Right(var_1BC, CLng((Len(var_1BC) - 1))) 'Variant
loc_41A937: var_1BC = Right(var_1BC, CLng((Len(var_1BC) - 1))) 'Variant
loc_41A999: var_1BC = Right(var_1BC, CLng((Len(var_1BC) - 1))) 'Variant
loc_41A9A3: var_B4 = var_B4 & (var_F4 + CVar(Asc(CStr(Left(var_1BC, 1))))) & (var_104 + CVar(Asc(CStr(Left(var_1BC, 1))))) & (var_114 + CVar(Asc(CStr(Left(var_1BC, 1)))))
去掉VB Decompiler 代码框上面的两个优化选项,重新反编译,就会恢复正常。
在 Excel 中将上面代码翻译成 VBA 代码,代码进行了优化,不完全与上面一致,如下:
Sub button1_Click()
Dim i As Long, n As Long
Dim name As String, name1 As String, base As String, sn As String
name = Sheet1.Cells(4, 4)
If name = "" Then
MsgBox "Please inter a name!", vbOKOnly, "ERROR"
Exit Sub
End If
While Len(name) < 6
name = name & name
Wend
sn = ""
'base = "234567"
For i = 1 To 6 Step 1
'sn = sn & (Val(Mid(base, i, 1)) + Asc(Mid(name, i, 1)))
sn = sn & ((i + 1) + Asc(Mid(name, i, 1)))
Next i
n = Len(sn)
If n < 12 Then
sn = String(12 - n, "0") & sn
End If
If n > 12 Then
sn = Left(sn, 12)
End If
Sheet1.Cells(5, 4) = sn
Range("D5").Select
Selection.Copy '可能有回车符的问题,复制出去的字符串后面带有隐藏的 vbCrLf,需要手动删除这2个不可见字符。
End Sub
并在 Excel 中做一个界面,如下图所示:
计算序列号并输入 CrackMe,如下:
点 "register",得到:
另外,如果用 OD 进行动态跟踪,核对算法的话,CrackMe 中有一个定时器事件,其代码会引发浮点精度的异常,当OD会断下来时,用 Shift+F9 忽略就可以了,就不会再对调试过程产生干扰了。
完毕!!!
6666666666 666666666666666666 楼主加油,看来我以前没弄明白的可以一个一个的弄明白了。 亲,我有个P-code 文件,有偿求高人破解,请联系rainrui15@gmail.com 大佬求助,怎么分析出Run-time error '70'的错误位置的,可以判断出问题出在 Proc_1_7_404720调用,但是对应在这个函数内部的0X004046DA处是怎么测试出来的呢 fenghl 发表于 2020-8-6 22:18
大佬求助,怎么分析出Run-time error '70'的错误位置的,可以判断出问题出在 Proc_1_7_404720调用,但是对 ...
执行打开文件操作时,VB运行库会报错。 solly 发表于 2020-8-6 22:30
执行打开文件操作时,VB运行库会报错。
谢谢大佬回复,我是小菜,在点击check时报错,报错后查看调用和堆栈,啥都没看出来,大佬怎么定位到导致错误发生的地址的,是在函数内部用断点测试么,还是有好办法呢。 fenghl 发表于 2020-8-6 22:39
谢谢大佬回复,我是小菜,在点击check时报错,报错后查看调用和堆栈,啥都没看出来,大佬怎么定位到导致 ...
在 vb decompiler 中找到事件函数,在od中下断点,F8或F7一步步找。
页:
[1]
2