[反汇编练习] 160个CrackMe之013. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注册机的东西。 其中,文章中按照如下逻辑编排(解决如下问题): 1、使用什么环境和工具 2、程序分析 3、思路分析和破解流程 4、注册机的探索 ---------------------------------- 提醒各位看客: 如果文章中的逻辑看不明白,那你一定是没有亲手操刀!OD中的跳转提示很强大,只要你跟踪了,不用怎么看代码就理解了! ---------------------------------- 1、工具和环境: WinXP SP3 + 52Pojie六周年纪念版OD + PEID + 汇编金手指。 160个CrackMe的打包文件。 下载地址: http://pan.baidu.com/s/1xUWOY 密码: jbnq 注: 1、Win7系统对于模块和程序开启了随机初始地址的功能,会给分析带来很大的负担,所以不建议使用Win7进行分析。 2、以上工具都是在52PoJie论坛下的原版程序,NOD32不报毒,个人承诺绝对不会进行任何和木马病毒相关内容。 2、程序分析: 想要破解一个程序,必须先了解这个程序。所以,在破解过程中,对最初程序的分析很重要,他可以帮助我们理解作者的目的和意图,特别是对于注册码的处理细节,从而方便我们反向跟踪和推导。 和上一节一样,打开CHM,选择第13个badboy.exe,保存下来。运行程序,程序界面如下: 列表框分别对应了两个验证: 我们随意输入用户名和序列号,点击Try!,好吧,没有对话框,只是在Serial编辑框里输出Try again! 使用PEID查看:VB5.0-6.0的,无壳。
3、思路分析和破解流程 由于没有信息框,所以没办法使用暂停,然后堆栈查找的方式。但是既然这里有文本提示,我们可以尝试加载到OD,使用右键->中文搜索插件->智能搜索,但是….一无所有! 到了这里,基本上傻眼了!(为什么没有012?因为其实我在那里已经傻了!) 上网搜索一些VB调试相关的信息,很多人都提到了VB万能断点,Ctrl+B,搜索816C24,但是不是很会用,然后就有人提到了使用VB的API下断,看到这里我立马想到了之前用到过的bp __vbaStrCmp/__vbaStrComp/__vbaVarTstEq,看起来也很靠谱! 1、打开OD,将exe拖进去,F9运行。 2、在最下面的输入框,输入bp __vbavartsteq,我们就完成了对这个函数的下断。 3、在exe程序中选择第一个,随意输入121212,然后点击【Try】按钮,发现OD断下来了!查看右下角堆栈信息: [Asm] 纯文本查看 复制代码 0012F42C 7402461B RETURN to msvbvm50.7402461B from msvbvm50.__vbaStrComp
0012F430 00000000
0012F434 0016E98C UNICODE "7703622"
0012F438 0016FBFC UNICODE "121212"
0012F43C 7411EA99 RETURN to msvbvm50.7411EA99 from msvbvm50.740245FC
0012F440 00000000
0012F444 0016E98C UNICODE "7703622"
0012F448 0016FBFC UNICODE "121212"
0012F44C 0016E98C UNICODE "7703622"
0012F450 0091C394
哈哈,比较的内容是不是很明确!我们将7703622输入serial,点击Try,界面变了:
其实此时还没完,点击OK,继续点Try,发现Try Again!又失败了,怎么回事?回到OD,查看右下角堆栈信息: [Asm] 纯文本查看 复制代码 0012F42C 7402461B RETURN to msvbvm50.7402461B from msvbvm50.__vbaStrComp
0012F430 00000000
0012F434 00175574 UNICODE "Congratulation !"
0012F438 0016FBFC UNICODE "7703622"
0012F43C 7411EA99 RETURN to msvbvm50.7411EA99 from msvbvm50.740245FC
0012F440 00000000
0012F444 00175574 UNICODE "Congratulation !"
0012F448 0016FBFC UNICODE "7703622"
0012F44C 00175574 UNICODE "Congratulation !"
0012F450 0091C394
原来此时比较的字符变了,是提示我们成功的字符串!【Congratulation !】,继续输入,OK! 我们重启程序,多做几次测试,发现第一个的Serial是固定的7703622. 重启程序,选择第二个,重复第一个的过程,输入伪码Name:bbdxf Serial:123456,堆栈信息如下: [Asm] 纯文本查看 复制代码 ;第一次
0012F2D4 7402461B RETURN to msvbvm50.7402461B from msvbvm50.__vbaStrComp
0012F2D8 00000000
0012F2DC 00175A0C UNICODE "30162-205440"
0012F2E0 0016FBFC UNICODE "123456"
0012F2E4 7411EA99 RETURN to msvbvm50.7411EA99 from msvbvm50.740245FC
0012F2E8 00000000
0012F2EC 00175A0C UNICODE "30162-205440"
0012F2F0 0016FBFC UNICODE "123456"
0012F2F4 00000000
0012F2F8 00175A0C UNICODE "30162-205440"
;第二次
0012F42C 7402461B RETURN to msvbvm50.7402461B from msvbvm50.__vbaStrComp
0012F430 00000000
0012F434 00175ABC UNICODE "Congratulation bbdxf !"
0012F438 0016E98C UNICODE "7703622"
0012F43C 7411EA99 RETURN to msvbvm50.7411EA99 from msvbvm50.740245FC
0012F440 00000000
0012F444 00175ABC UNICODE "Congratulation bbdxf !"
0012F448 0016E98C UNICODE "7703622"
0012F44C 00175ABC UNICODE "Congratulation bbdxf !"
0012F450 0091C394
;第三次
0012F42C 7402461B RETURN to msvbvm50.7402461B from msvbvm50.__vbaStrComp
0012F430 00000000
0012F434 00175ABC UNICODE "Congratulation bbdxf !"
0012F438 0016E98C UNICODE "Try Again!"
0012F43C 7411EA99 RETURN to msvbvm50.7411EA99 from msvbvm50.740245FC
0012F440 00000000
0012F444 00175ABC UNICODE "Congratulation bbdxf !"
0012F448 0016E98C UNICODE "Try Again!"
0012F44C 00175ABC UNICODE "Congratulation bbdxf !"
0012F450 0091C394
很容易看出,Serial是根据Name计算出来的,所以,这一步想要爆破它,需要找到进行比较的位置,然后像以前一样,修改跳转。 但是.. 我们如何能知道在程序哪里进行比较的呢? 我不知道。。。 我尝试在右下角的堆栈信息里查找,但是除了找到一个类似有点用的信息外,什么也没有: 0012F448 00175A0C UNICODE "bbdxf"
0012F44C 0017580C UNICODE "01106171212140512161011061414041106141404110912111"
0012F450 000075D2
0012F454 0016E98C UNICODE "123321" 看来只是用OD是解决不了的,先试试上一节用到的VBxxxx那个软件吧: 发现,触发按钮的名称为Command2,大概进行了如下工作,分析部分:
key = 0110617121214051216101106141404110614140411091211100810101608040610121608100416
name = bbdxf
mid name 4 1 ; x
mid key 3 3 ; 106
mid name 5 1 ; f
mid key 6 3 ; 171
mid key 2 2 ; 11 mid name 4 1 ; x mid name 3 1 ; d
mid key 4 2 ; 6 mid name 5 1 ; f mid name 4 1 ; x Str ; 30162
LTrim
Str ; 205440
LTrim
最后组成了一个我们看到的那个序列号。但是,我们还是没有办法使用OD跟踪和修改。 好吧,去网络上找大神吧! 经过搜索发现,VB还是有专门进行反汇编的软件,如SmartCheck,刚将exe拖进去就提示编译了p代码:
p代码是什么?为什么以前从未听说过?还好没人知道,不怕丢人,赶快搜索一下。原来,VB的编译除了常规的方式之外,还可以编译为PCODE,并且PCODE对反汇编分析有很大的干扰,至少现在我是分析不出来。 继续查找PCODE的资料,重点看了两篇: http://www.pediy.com/kssd/pediy06/pediy6272.htm
http://blog.sina.com.cn/s/blog_5000f4c901013iiy.html 果然不是随便就能搞定的,继续使用SmartCheck分析代码,虽然感觉已经做了很多功课了,但是发现几乎无法理解,太坑了! [Visual Basic] 纯文本查看 复制代码 'Data Table: 403D90
loc_4055CC: FLdRfVar var_8C
loc_4055CF: FLdPrThis
loc_4055D0: VCallAd Text1
loc_4055D3: FStAdFunc var_88
loc_4055D6: FLdPr var_88
loc_4055D9: = Me.Text
loc_4055DE: ILdRf var_8C
loc_4055E1: FnLenStr
loc_4055E2: LitI4 5
loc_4055E7: LtI4
loc_4055E8: FFree1Str var_8C
loc_4055EB: FFree1Ad var_88
loc_4055EE: BranchF loc_405607
loc_4055F1: LitStr "At least 5 characters!"
loc_4055F4: FLdPrThis
loc_4055F5: VCallAd Text2
loc_4055F8: FStAdFunc var_88
loc_4055FB: FLdPr var_88
loc_4055FE: Me.Text =
loc_405603: FFree1Ad var_88
loc_405606: ExitProcHresult
loc_405607: LitStr "0110617121214051216101106141404110614140411091211100810101608040610121608100416"
loc_40560A: FStStrCopy var_94
loc_40560D: FLdRfVar var_8C
loc_405610: FLdPrThis
loc_405611: VCallAd Text1
loc_405614: FStAdFunc var_88
loc_405617: FLdPr var_88
loc_40561A: = Me.Text
loc_40561F: FLdZeroAd var_8C
loc_405622: FStStr var_98
loc_405625: FFree1Ad var_88
loc_405628: LitVarI2 var_B8, 1
loc_40562D: FStVar
loc_405631: LitVarI2 var_E8, 4
loc_405636: FLdRfVar var_C8
loc_405639: ILdRf var_98
loc_40563C: FnLenStr
loc_40563D: CVarI4
loc_405641: ForVar var_108
loc_405647: LitVarI2 var_118, 1
loc_40564C: FLdRfVar var_C8
loc_40564F: CI4Var
loc_405651: ILdRf var_98
loc_405654: ImpAdCallI2 Mid$(, , )
loc_405659: FStStrNoPop var_8C
loc_40565C: ImpAdCallI2 Asc()
loc_405661: FStI2 var_13E
loc_405664: LitVarI2 var_138, 3
loc_405669: FLdRfVar var_A8
loc_40566C: LitVarI2 var_D8, 3
loc_405671: MulVar var_128
loc_405675: CI4Var
loc_405677: ILdRf var_94
loc_40567A: ImpAdCallI2 Mid$(, , )
loc_40567F: FStStrNoPop var_13C
loc_405682: ImpAdCallFPR4 push Val()
loc_405687: FStFPR8 var_148
loc_40568A: ILdRf var_90
loc_40568D: CR8I4
loc_40568E: FLdI2 var_13E
loc_405691: CR8I2
loc_405692: FLdFPR8 var_148
loc_405695: MulR8
loc_405696: AddR8
loc_405697: CI4R8
loc_405698: FStR4 var_90
loc_40569B: FFreeStr var_8C = ""
loc_4056A2: FFreeVar var_118 = ""
loc_4056A9: FLdRfVar var_A8
loc_4056AC: LitVarI2 var_B8, 1
loc_4056B1: AddVar var_118
loc_4056B5: FStVar
loc_4056B9: FLdRfVar var_A8
loc_4056BC: LitVarI2 var_B8, 39
loc_4056C1: HardType
loc_4056C2: GeVarBool
loc_4056C4: BranchF loc_4056D0
loc_4056C7: LitVarI2 var_B8, 0
loc_4056CC: FStVar
loc_4056D0: FLdRfVar var_C8
loc_4056D3: NextStepVar var_108
loc_4056D9: LitVarI2 var_B8, 1
loc_4056DE: FStVar
loc_4056E2: LitVarI2 var_E8, 4
loc_4056E7: FLdRfVar var_C8
loc_4056EA: ILdRf var_98
loc_4056ED: FnLenStr
loc_4056EE: CVarI4
loc_4056F2: ForVar var_168
loc_4056F8: LitVarI2 var_1B8, 2
loc_4056FD: FLdRfVar var_A8
loc_405700: LitVarI2 var_188, 2
loc_405705: MulVar var_198
loc_405709: CI4Var
loc_40570B: ILdRf var_94
loc_40570E: ImpAdCallI2 Mid$(, , )
loc_405713: FStStrNoPop var_1BC
loc_405716: ImpAdCallFPR4 push Val()
loc_40571B: FStFPR8 var_148
loc_40571E: FLdRfVar var_178
loc_405721: LitVarI2 var_118, 1
loc_405726: FLdRfVar var_C8
loc_405729: CI4Var
loc_40572B: ILdRf var_98
loc_40572E: ImpAdCallI2 Mid$(, , )
loc_405733: FStStrNoPop var_8C
loc_405736: ImpAdCallI2 Asc()
loc_40573B: LitVarI2 var_138, 1
loc_405740: FLdRfVar var_C8
loc_405743: LitVarI2 var_D8, 1
loc_405748: SubVar var_128
loc_40574C: CI4Var
loc_40574E: ILdRf var_98
loc_405751: ImpAdCallI2 Mid$(, , )
loc_405756: FStStrNoPop var_13C
loc_405759: ImpAdCallI2 Asc()
loc_40575E: MulI2
loc_40575F: CR8I2
loc_405760: FLdFPR8 var_148
loc_405763: MulR8
loc_405764: CVarR8
loc_405768: AddVar var_1DC
loc_40576C: FStVar
loc_405770: FFreeStr var_8C = "": var_13C = ""
loc_405779: FFreeVar var_118 = "": var_138 = ""
loc_405782: FLdRfVar var_A8
loc_405785: LitVarI2 var_B8, 1
loc_40578A: AddVar var_118
loc_40578E: FStVar
loc_405792: FLdRfVar var_A8
loc_405795: LitVarI2 var_B8, 39
loc_40579A: HardType
loc_40579B: GeVarBool
loc_40579D: BranchF loc_4057A9
loc_4057A0: LitVarI2 var_B8, 0
loc_4057A5: FStVar
loc_4057A9: FLdRfVar var_C8
loc_4057AC: NextStepVar var_168
loc_4057B2: FLdRfVar var_90
loc_4057B5: CVarRef
loc_4057BA: ImpAdCallI2 push Chr()
loc_4057BF: FStStrNoPop var_8C
loc_4057C2: ImpAdCallI2 push LTrim$()
loc_4057C7: FStStrNoPop var_13C
loc_4057CA: LitStr "-"
loc_4057CD: ConcatStr
loc_4057CE: FStStrNoPop var_1E0
loc_4057D1: FLdRfVar var_178
loc_4057D4: ImpAdCallI2 push Chr()
loc_4057D9: FStStrNoPop var_1BC
loc_4057DC: ImpAdCallI2 push LTrim$()
loc_4057E1: FStStrNoPop var_1E4
loc_4057E4: ConcatStr
loc_4057E5: FStStr var_1E8
loc_4057E8: FFreeStr var_8C = "": var_13C = "": var_1BC = "": var_1E0 = ""
loc_4057F5: FLdRfVar var_8C
loc_4057F8: FLdPrThis
loc_4057F9: VCallAd Text2
loc_4057FC: FStAdFunc var_88
loc_4057FF: FLdPr var_88
loc_405802: = Me.Text
loc_405807: ILdRf var_8C
loc_40580A: ILdRf var_1E8
loc_40580D: EqStr
loc_40580F: FFree1Str var_8C
loc_405812: FFree1Ad var_88
loc_405815: BranchF loc_4058D5
loc_405818: LitI2_Byte 0
loc_40581A: FLdPrThis
loc_40581B: VCallAd Command2
loc_40581E: FStAdFunc var_88
loc_405821: FLdPr var_88
loc_405824: Me.Visible =
loc_405829: FFree1Ad var_88
loc_40582C: LitI2_Byte 0
loc_40582E: FLdPrThis
loc_40582F: VCallAd Command1
loc_405832: FStAdFunc var_88
loc_405835: FLdPr var_88
loc_405838: Me.Visible =
loc_40583D: FFree1Ad var_88
loc_405840: LitI2_Byte &HFF
loc_405842: FLdPrThis
loc_405843: VCallAd Command5
loc_405846: FStAdFunc var_88
loc_405849: FLdPr var_88
loc_40584C: Me.Visible =
loc_405851: FFree1Ad var_88
loc_405854: LitI2_Byte 0
loc_405856: FLdPrThis
loc_405857: VCallAd Command3
loc_40585A: FStAdFunc var_88
loc_40585D: FLdPr var_88
loc_405860: Me.Visible =
loc_405865: FFree1Ad var_88
loc_405868: LitI2_Byte 0
loc_40586A: FLdPrThis
loc_40586B: VCallAd Text2
loc_40586E: FStAdFunc var_88
loc_405871: FLdPr var_88
loc_405874: Me.Visible =
loc_405879: FFree1Ad var_88
loc_40587C: LitI2_Byte &HFF
loc_40587E: FLdPrThis
loc_40587F: VCallAd Frame3
loc_405882: FStAdFunc var_88
loc_405885: FLdPr var_88
loc_405888: Me.Visible =
loc_40588D: FFree1Ad var_88
loc_405890: LitStr "Congratulation "
loc_405893: FLdRfVar var_8C
loc_405896: FLdPrThis
loc_405897: VCallAd Text1
loc_40589A: FStAdFunc var_88
loc_40589D: FLdPr var_88
loc_4058A0: = Me.Text
loc_4058A5: ILdRf var_8C
loc_4058A8: ConcatStr
loc_4058A9: FStStrNoPop var_13C
loc_4058AC: LitStr " !"
loc_4058AF: ConcatStr
loc_4058B0: FStStrNoPop var_1BC
loc_4058B3: FLdPrThis
loc_4058B4: VCallAd Label3
loc_4058B7: FStAdFunc var_1EC
loc_4058BA: FLdPr var_1EC
loc_4058BD: Me.Caption =
loc_4058C2: FFreeStr var_8C = "": var_13C = ""
loc_4058CB: FFreeAd var_88 = ""
loc_4058D2: Branch loc_4058EA
loc_4058D5: LitStr "Try Again!"
loc_4058D8: FLdPrThis
loc_4058D9: VCallAd Text2
loc_4058DC: FStAdFunc var_88
loc_4058DF: FLdPr var_88
loc_4058E2: Me.Text =
loc_4058E7: FFree1Ad var_88
loc_4058EA: ExitProcHresult
没办法,继续找一个好用一点的吧!然后就找到了VB Explorer,代码还是很乱,虽然有一些具体的函数,但是,哎,模模糊糊,看不明白啊!(其实是能看到代码的地址的,但是使用OD查看地址处,发现完全无法解正常析代码!然后使用IDA,发现他解析的代码和VB Explorer的完全不一样,晕死!)
然后继续寻找,发现PCODE由于微软不公开,他的反汇编很稀有,所以才会这样,但是曾经有一个团队专门研究这个,最终发现了VB PCODE的神器,vb decompiler pro,前前后后找了不下5个版本,但是没有一个是能反汇编源码的,因为这个软件pro版本是收费的,费了老大的Jin,终于在一个边边角角里找到了它!反编译之后的VB代码如下: command2.click [Visual Basic] 纯文本查看 复制代码 Private Sub Command2_Click() '4058EC
'Data Table: 403D90
Dim var_90 As Long
Dim var_1CC As Variant
If (Len(Me.Text1.Text) < 5) Then
loc_4055FE: Me.Text2.Text = "At least 5 characters!"
loc_405606: Exit Sub
End If
loc_40560A: var_94 = "0110617121214051216101106141404110614140411091211100810101608040610121608100416"
loc_405622: var_98 = Me.Text1.Text
loc_40562D: var_A8 = 1 'Variant
For var_108 = 4 To CVar(Len(var_98)): var_C8 = var_108 'Variant
loc_405698: 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
loc_4056CC: var_A8 = 0 'Variant
End If
Next var_108 'Variant
loc_4056DE: var_A8 = 1 'Variant
For var_168 = 4 To CVar(Len(var_98)): var_C8 = var_168 'Variant
loc_405764: 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
loc_40576C: var_178 = (var_178 + var_1CC) 'Variant
If ((var_A8 + 1) >= 39) Then
loc_4057A5: var_A8 = 0 'Variant
End If
Next var_168 'Variant
If (Me.Text2.Text = LTrim$(Str(var_90)) & "-" & LTrim$(Str(var_178))) Then
loc_405824: Me.Command2.Visible = False
loc_405838: Me.Command1.Visible = False
loc_40584C: Me.Command5.Visible = True
loc_405860: Me.Command3.Visible = False
loc_405874: Me.Text2.Visible = False
loc_405888: Me.Frame3.Visible = True
loc_4058BD: Me.Label3.Caption = "Congratulation " & Me.Text1.Text & " !"
loc_4058D5: Else
loc_4058E2: Me.Text2.Text = "Try Again!"
End If
loc_4058EA: Exit Sub
End Sub
看着很乱,没办法,但是已经比之前的好多了,边搜索,边修改,注释之后如下: [Visual Basic] 纯文本查看 复制代码 ub Command2_Click() '4058EC
'Data Table: 403D90
Dim numSub1 As Long
Dim var_1CC As Variant
' 判断注册码长度,5个以上
If (Len(Me.Text1.Text) < 5) Then
Me.Text2.Text = "At least 5 characters!"
Exit Sub
End If
' 产生一个码表
var_94 = "0110617121214051216101106141404110614140411091211100810101608040610121608100416"
strText1 = Me.Text1.Text
'第一部分
nforStep = 1 'Variant
For nforStart = 4 To (Len(strText1)): nforStep = nforStart 'Variant
' CLng 转为long, CDbl 转换为double, Asc 取ASCII值
numSub1 = CLng((CDbl(numSub1) + (CDbl(Asc(Mid$(strText1, CLng(nforStep), 1))) * Val(Mid$(var_94, CLng((nforStep * 3)), 3)))))
If ((nforStep + 1) >= 39) Then
nforStep = 0 'Variant
End If
Next nforStart 'Variant
' 第二部分
nforStep = 1 'Variant
For nforStart2 = 4 To (Len(strText1)): nforStep = nforStart2 'Variant
var_1CC = ((CDbl((Asc(Mid$(strText1, CLng(nforStep), 1)) * Asc(Mid$(strText1, CLng((nforStep - 1)), 1)))) * Val(Mid$(var_94, CLng((nforStep * 2)), 2)))) 'Double
numSub2 = (numSub2 + var_1CC) 'Variant
If ((nforStep + 1) >= 39) Then
nforStep = 0 'Variant
End If
Next nforStart2 'Variant
If (Me.Text2.Text = LTrim$(Str(numSub1)) & "-" & LTrim$(Str(numSub2))) 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
End Sub
最终,还在VS上修改了一个可以修改的版本,可是,可是…运行之后的结果完全和调试的不一样!!坑啊!! ---- PS:以上内容虽不多,但是,我为了未见面的012和这个013,从周一就开始准备了(我上周事先大概分析过了)。012因为是使用TPascal编写,语言太过小众,然后还是16位程序!我先先后后使用了Tubo Debuger,TDebug,C32Asm,windows自带Debug,OD,IDA,还有一个古董级别的分析出了汇编代码和信息框位置,但是无法修改和调试!还有一些似乎能用的调试工具,但是均已失败告终!TNND,我都有骂人的冲动了!013相对中规中矩,但是没想到使用了之前从未听说过的PCODE,哎,然后又将所有知道的和搜索到的反汇编工具一一尝试,最终,最终就是你们看到的这个VB代码了!玩完没想到啊!啥也不说了!
4、注册机探索 无
012胎死腹中,有缘再见! BY 笨笨D幸福
|