首页 > 代码库 > [反汇编练习] 160个CrackMe之013
[反汇编练习] 160个CrackMe之013
[反汇编练习] 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断下来了!查看右下角堆栈信息:
0012F42C 7402461B RETURN to msvbvm50.7402461B from msvbvm50.__vbaStrComp0012F430 000000000012F434 0016E98C UNICODE "7703622"0012F438 0016FBFC UNICODE "121212"0012F43C 7411EA99 RETURN to msvbvm50.7411EA99 from msvbvm50.740245FC0012F440 000000000012F444 0016E98C UNICODE "7703622"0012F448 0016FBFC UNICODE "121212"0012F44C 0016E98C UNICODE "7703622"0012F450 0091C394
哈哈,比较的内容是不是很明确!我们将7703622输入serial,点击Try,界面变了:
其实此时还没完,点击OK,继续点Try,发现Try Again!又失败了,怎么回事?回到OD,查看右下角堆栈信息:
0012F42C 7402461B RETURN to msvbvm50.7402461B from msvbvm50.__vbaStrComp0012F430 000000000012F434 00175574 UNICODE "Congratulation !"0012F438 0016FBFC UNICODE "7703622"0012F43C 7411EA99 RETURN to msvbvm50.7411EA99 from msvbvm50.740245FC0012F440 000000000012F444 00175574 UNICODE "Congratulation !"0012F448 0016FBFC UNICODE "7703622"0012F44C 00175574 UNICODE "Congratulation !"0012F450 0091C394
原来此时比较的字符变了,是提示我们成功的字符串!【Congratulation !】,继续输入,OK!
我们重启程序,多做几次测试,发现第一个的Serial是固定的7703622.
重启程序,选择第二个,重复第一个的过程,输入伪码Name:bbdxf Serial:123456,堆栈信息如下:
;第一次0012F2D4 7402461B RETURN to msvbvm50.7402461B from msvbvm50.__vbaStrComp0012F2D8 000000000012F2DC 00175A0C UNICODE "30162-205440"0012F2E0 0016FBFC UNICODE "123456"0012F2E4 7411EA99 RETURN to msvbvm50.7411EA99 from msvbvm50.740245FC0012F2E8 000000000012F2EC 00175A0C UNICODE "30162-205440"0012F2F0 0016FBFC UNICODE "123456"0012F2F4 000000000012F2F8 00175A0C UNICODE "30162-205440";第二次0012F42C 7402461B RETURN to msvbvm50.7402461B from msvbvm50.__vbaStrComp0012F430 000000000012F434 00175ABC UNICODE "Congratulation bbdxf !"0012F438 0016E98C UNICODE "7703622"0012F43C 7411EA99 RETURN to msvbvm50.7411EA99 from msvbvm50.740245FC0012F440 000000000012F444 00175ABC UNICODE "Congratulation bbdxf !"0012F448 0016E98C UNICODE "7703622"0012F44C 00175ABC UNICODE "Congratulation bbdxf !"0012F450 0091C394;第三次0012F42C 7402461B RETURN to msvbvm50.7402461B from msvbvm50.__vbaStrComp0012F430 000000000012F434 00175ABC UNICODE "Congratulation bbdxf !"0012F438 0016E98C UNICODE "Try Again!"0012F43C 7411EA99 RETURN to msvbvm50.7411EA99 from msvbvm50.740245FC0012F440 000000000012F444 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分析代码,虽然感觉已经做了很多功课了,但是发现几乎无法理解,太坑了!
‘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
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 SubEnd Sub
看着很乱,没办法,但是已经比之前的好多了,边搜索,边修改,注释之后如下:
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 SubEnd Sub
最终,还在VS上修改了一个可以修改的版本,可是,可是…运行之后的结果完全和调试的不一样!!坑啊!!
----
PS:以上内容虽不多,但是,我为了未见面的012和这个013,从周一就开始准备了(我上周事先大概分析过了)。012因为是使用TPascal编写,语言太过小众,然后还是16位程序!我先先后后使用了Tubo Debuger,TDebug,C32Asm,windows自带Debug,OD,IDA,还有一个古董级别的分析出了汇编代码和信息框位置,但是无法修改和调试!还有一些似乎能用的调试工具,但是均已失败告终!TNND,我都有骂人的冲动了!013相对中规中矩,但是没想到使用了之前从未听说过的PCODE,哎,然后又将所有知道的和搜索到的反汇编工具一一尝试,最终,最终就是你们看到的这个VB代码了!玩完没想到啊!啥也不说了!
4、注册机探索
无
012胎死腹中,有缘再见!
BY 笨笨D幸福