新手破解练习Crackme160之017 - BJCM30A
016与014完全一样,跳过~
-
暴力破解,
1). VB Decomiler查看反编译源码00404230处是按钮入口, 直接OD在此处下断点, F9运行, 不输入数据点按钮直接F8单步执行找关键跳, 00404393处一直循环, 果断选择跳过, je改jmp, 0040459F处nop掉, 到此暴力完成~ 经测试, 有输入时还是报错, 需要继续暴破~
2). 重新开始, 随便输入一些数据, 重新从头开始单步一直跟踪, 0040459F处nop掉, 继续一直跟踪到00404941处跳转到失败分支, 我们把它nop掉, 继续跟踪到00404E30处又一次判断是否要跳转到失败, 所以继续nop掉不让它跳, 到此, 所有跳转到失败分支的地方我们都给它nop掉了, 保存测试, 成功完事~,
这个暴力破解还是有点难度的, 得分析好几个分支~ 前面那些暴力破解部分都算不上星, 这个感觉可以算上1星了_ -
正常破解, 程序还是VB写的, 继续请上VB Decomiler, 找到点击事件, 破解版的可能有限制还是什么, 反编译出来的代码可读性还是很差, 如下:
Private Sub Command1_Click() '404230
Dim var_A4 As Variant
Dim var_A8 As Variant
loc_0040432C: var_5C = CLng(Timer) '当前时间戳'
loc_0040438B: For var_80 = 1 To 1000 Step 1 '大循环' 1000*250次循环,
loc_00404393: If var_14C = 0 Then GoTo loc_00404461
loc_004043ED: For var_58 = 1 To 250 Step 1 '内部继续循环'
loc_004043F5: If var_16C = 0 Then GoTo loc_00404444
loc_00404409: If (global_00402A34 = global_00402A34) Then GoTo loc_0040442A
loc_00404424: var_24 = CInt(1)
loc_0040442A: ' Referenced from: 00404409
loc_0040443C: Next var_58
loc_00404442: GoTo loc_004043F3
loc_00404444: ' Referenced from: 004043F5
loc_00404456: Next var_80
loc_0040445C: GoTo loc_00404391
loc_00404461: ' Referenced from: 00404393
loc_00404479: If (CLng(Timer) - var_5C) <= 5 Then GoTo loc_0040452C '验证程序执行到这里是否超过5秒时间'
loc_00404505: MsgBox(" You have SmartCheck loaded!...Close it and try again!!!", 0, "Cheater!!! CHEATER!!! Cheater!!! CHEATER!!!", 10, 10)
loc_00404527: GoTo loc_00404F86
loc_0040452C: ' Referenced from: 00404479
loc_0040454F: var_84 = CrackmeV30a.Text1.Text
loc_0040459F: If (Len(var_84) < 5) Then GoTo loc_00404EDE
loc_004045F8: var_84 = CrackmeV30a.Text1.Text
loc_0040466E: For var_6C = 1 To Len(var_84) Step 1
loc_0040467A: var_1D0 = var_18C
loc_0040469E: If var_1D0 = 0 Then GoTo loc_00404899
loc_004046B5: Set var_A4 = CrackmeV30a.Text1
loc_004046C5: var_12C = var_A4
loc_004046CB: var_84 = var_A4.Text
loc_00404700: Set var_A8 = CrackmeV30a.Text1
loc_00404710: var_134 = var_A8
loc_00404716: var_88 = var_A8.Text
loc_0040483B: If (Mid$(var_84, CLng(var_6C), 1) = Mid$(var_88, CLng(var_6C + 1), 1)) + 1 = 0 Then GoTo loc_00404874
loc_0040486E: var_48 = var_48 + 1
loc_00404874: ' Referenced from: 0040483B
loc_00404886: Next var_6C
loc_0040488C: var_1D0 = Next var_6C
loc_00404894: GoTo loc_00404698
loc_00404899: ' Referenced from: 0040469E
loc_004048AA: Set var_A4 = CrackmeV30a.Text1
loc_004048BA: var_12C = var_A4
loc_004048C0: var_84 = var_A4.Text
loc_00404941: If (var_48 = Len(var_84)(-1)) Then GoTo loc_00404EDE
loc_0040496C: Set var_A4 = CrackmeV30a.Text1
loc_0040497C: var_12C = var_A4
loc_00404982: var_84 = var_A4.Text
loc_004049FE: For var_6C = 1 To Len(var_84) Step 1
loc_00404A0A: var_1D4 = var_1BC
loc_00404A28: If var_1D4 = 0 Then GoTo loc_00404D4B
loc_00404A3F: Set var_A4 = CrackmeV30a.Text1
loc_00404A4F: var_12C = var_A4
loc_00404A55: var_84 = var_A4.Text
loc_00404B0B: var_8048 = Asc(CStr(Left(CrackmeV30a.Text1, 1)))
loc_00404B17: var_E0 = var_8048
loc_00404B91: var_98 = global_0008.hexfunc(Hex$(Len(var_84)), Hex$(var_8048), "*") '第一位ascii码 * 长度'
loc_00404BBC: var_38 = var_98
loc_00404C45: Set var_A4 = CrackmeV30a.Text1
loc_00404C55: var_12C = var_A4
loc_00404C5B: var_84 = var_A4.Text
loc_00404CBD: var_8058 = Asc(Mid$(var_84, CLng(var_6C), 1)) '每一位的ascii码'
loc_00404CC3: var_100 = var_8058
loc_00404CF1: var_34 = var_34 + var_8058 '加起来'
loc_00404D3A: Next var_6C
loc_00404D40: var_1D4 = Next var_6C
loc_00404D46: GoTo loc_00404A22
loc_00404D4B: ' Referenced from: 00404A28
loc_00404DA0: var_8C = CrackmeV30a.hexfunc(var_38, Hex$(var_34), "=") '比较*值与+值是否相等'
loc_00404E27: var_8064 = (var_8C = "FFFF")
loc_00404E30: If var_8064 = 0 Then GoTo loc_00404EE3
loc_00404EB7: MsgBox("Good job, tell me how you do that!", 0, "Correct serial!", 10, 10)
loc_00404ED9: GoTo loc_00404F86
loc_00404EDE: ' Referenced from: 0040459F
loc_00404EE3: ' Referenced from: 00404E30
loc_00404F64: MsgBox("Sorry, try again!", 0, "Wrong serial!", 10, 10)
loc_00404F86: ' Referenced from: 00404527
loc_00404F86: ' Referenced from: 00404ED9
loc_00404F9A: GoTo loc_0040501A
loc_00405019: Exit Sub
loc_0040501A: ' Referenced from: 00404F9A
End Sub
前面的 for(1~1000){ for(1~250){ } } 感觉这两个循环是防破解用的, 里面没看到什么实际有用的代码, 下面的时间验证, 明显就是给破解者用的
第一层判断输入字符串长度是否小于5
第二层进入循环, 说明需要一位一位的验证了, if( Mid$(var_84, CLng(var_6C), 1) = Mid$(var_88, CLng(var_6C + 1), 1) )
这句中var_84, var_88都是同一个值, 就是输入的数据, var_6C就是循环变量, 这是验证当前位与下一位是否相等
第三层取出输入串第一次的ascii码, 乘以输入串的长度 与 每一位ascii码值和 相比, 从这里看上一层的比较是要求相邻两位不能相同
到这里算法就结束了, 最关键的就是第三层, * = +, 这不难看出这是一个平均数公式, 第一位就是所有数(ascii值)和的平均数, 所以这个系列号的解就是(设长度为5时), 连续的5个数, 把中间那个数移到第一位就可以了, 后面几位顺序不限,
比如: 12345=>31245 / 35421 / 34512, abcde=>cabde, 测试完全正确
如果是偶数位, 那就中间两个数一样就行了, 如: abccde=>cabcde, 到此正常破解完成
也写个注册机吧, 写个纯数字或纯字母的系列号, 其他特殊符号我们就不考虑了, 下面代码保存为: KeyGen.vbs
Function GetRandomMath(m,n)
Randomize
GetRandomMath = Int(((n-m+1) * Rnd) + m)
End Function
rlt = ""
serial_type = GetRandomMath(0,1)
slen = GetRandomMath(5, 10)
middle_num = int(slen / 2)
if serial_type = 1 then '纯数字
rlt = rlt & middle_num
for i=0 to middle_num-1
rlt = rlt & i
next
for i=middle_num+1 to slen-1
rlt = rlt & i
next
if slen mod 2 = 0 then
rlt = rlt & middle_num
end if
else '纯字母
middle_char = 97 + GetRandomMath(middle_num, 26 - middle_num)
rlt = rlt & chrW(middle_char)
for i=0 to middle_num-1
rlt = rlt & chrW(middle_char - middle_num + i)
next
for i=middle_num+1 to slen-1
rlt = rlt & chrW(middle_char - middle_num + i)
next
if slen mod 2 = 0 then
rlt = rlt & chrW(middle_char)
end if
end if
msgbox("系列号为: " & rlt)
相关软件与破解示例程序可到前十个练习处下载
下面是我的OD的界面布局,我觉得这4个是最常用的界面,其它的我基本上没用到~


浙公网安备 33010602011771号