首页 > 代码库 > [反汇编练习] 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不报毒,个人承诺绝对不会进行任何和木马病毒相关内容。

wps_clip_image-880

2、程序分析:

想要破解一个程序,必须先了解这个程序。所以,在破解过程中,对最初程序的分析很重要,他可以帮助我们理解作者的目的和意图,特别是对于注册码的处理细节,从而方便我们反向跟踪和推导。

和上一节一样,打开CHM,选择第13个badboy.exe,保存下来。运行程序,程序界面如下:

image

列表框分别对应了两个验证:

imageimage

我们随意输入用户名和序列号,点击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,界面变了:

1

其实此时还没完,点击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代码:

2

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幸福