首页
社区
课程
招聘
[原创]VB P-code -- 最后的战役
发表于: 2004-12-26 11:05 16888

[原创]VB P-code -- 最后的战役

2004-12-26 11:05
16888

*岁末大盘点*
VB P-code -- 最后的战役
作者:cyclotron

   首先感谢您对这个VB P-code系列的关注。在前几期的文章中,我已经为大家详细介绍了关于对VB P-code程序动、静态结合的调试方法,相信大家对这部分内容已经非常熟悉了。如果您自己写过一些小程序进行调试研究,我相信您已经能够独立地完成本文提及的这个CrackMe的破解了。
   在本文中,我选择了由CyberBlade编写的一个中级VB P-code CrackMe作为范例来为大家介绍VB P-code程序的调试过程,希望能帮助大家熟悉一部分P-code伪指令,为将来的研究学习打下基础。由于我在前几期中已经讲解了对陌生的VB P-code伪指令的处理方法(用OllyDBG跟踪其解释过程),这次我将完全从伪代码的层面上对程序进行调试,也就是说,我将以伪指令为单位说明程序各部分所实现的功能。这种方法乍看起来可能不太直观,但是请相信,一旦您熟悉了这样的调试方法,将给您今后的学习带来极大的方便。
   好了,我们这就开始了。这次我首先使用Josephco的Exdec来生成该CrackMe的反编译代码,然后结合WKTVBDebugger和OllyDBG来进行调试。像往常一样,我们在WKTVBDebugger的Form Manager中对Check按钮下断点,记住这是个不同于其他程序调试的极其有效的断点方式,对于事件驱动的注册验证过程,这种断点是百分之百有效的。点下Check按钮以后,我们停在下面的代码上(从Exdec抓取):

Proc: 40e680

40E26C: 04 FLdRfVar                local_009C
40E26F: 21 FLdPrThis              
40E270: 0f VCallAd                 text
40E273: 19 FStAdFunc               local_0098
40E276: 08 FLdPr                   local_0098
40E279: 0d VCallHresult            get__ipropTEXTEDIT	;这是一个很常见的调用,其功能是取得编辑框的字符串("TEXTEDIT"已经透露了秘密),很明显,这里取得的就是我们输入的用户名了
40E27E: 6c ILdRf                   local_009C
40E281: 1b LitStr:                  
40E284: Lead0/30 EqStr            
40E286: 2f FFree1Str               local_009C
40E289: 1a FFree1Ad                local_0098
40E28C: 1c BranchF:                40E2C1		;上面这一段检验输入的用户名是否为空,没有输入的话当然就直接fail了,注意Branch这个词表示分支,F表示False

………………
………………

40E2CE: 0d VCallHresult            get__ipropTEXTEDIT	;又来了,这回是取试炼码了
40E2D3: 6c ILdRf                   local_009C
40E2D6: 1b LitStr:                  
40E2D9: Lead0/30 EqStr            
40E2DB: 2f FFree1Str               local_009C
40E2DE: 1a FFree1Ad                local_0098
40E2E1: 1c BranchF:                40E316		;试炼码是否为空?
40E2E4: 27 LitVar_Missing         
40E2E7: 27 LitVar_Missing         
40E2EA: 3a LitVarStr:              ( local_00CC ) Error
40E2EF: 4e FStVarCopyObj           local_00DC
40E2F2: 04 FLdRfVar                local_00DC
40E2F5: f5 LitI4:                  0x40  64  (...@)
40E2FA: 3a LitVarStr:              ( local_00AC ) You have to enter a key first.
							;这个提示很熟悉吧?

………………
………………

继续往下走,还有一次关于试炼码合法性的初步检验,跟上面的差不多:

40E323: 0d VCallHresult            get__ipropTEXTEDIT	;取试炼码
40E328: 6c ILdRf                   local_009C
40E32B: 1b LitStr:                  
40E32E: Lead0/30 EqStr            
40E330: 2f FFree1Str               local_009C
40E333: 1a FFree1Ad                local_0098
40E336: 1c BranchF:                40E36B		;不足5位就走下去
40E339: 27 LitVar_Missing         
40E33C: 27 LitVar_Missing         
40E33F: 3a LitVarStr:              ( local_00CC ) Error
40E344: 4e FStVarCopyObj           local_00DC
40E347: 04 FLdRfVar                local_00DC
40E34A: f5 LitI4:                  0x40  64  (...@)
40E34F: 3a LitVarStr:              ( local_00AC ) You have to enter at least 5 chars.
40E354: 4e FStVarCopyObj           local_00BC		;试炼码必须大于等于5位
40E357: 04 FLdRfVar                local_00BC

	注意,下面要开始真正的计算了:

40E36B: 28 LitVarI2:               ( local_00EC ) 0x1  (1);立即数1入栈,Lit表示立即数
40E370: 04 FLdRfVar                local_012C		;FLd表示压栈,这里保存的是循环计数器
40E373: 04 FLdRfVar                local_009C
40E376: 21 FLdPrThis              
40E377: 0f VCallAd                 text
40E37A: 19 FStAdFunc               local_0098
40E37D: 08 FLdPr                   local_0098
40E380: 0d VCallHresult            get__ipropTEXTEDIT	;再次读取用户名
40E385: 6c ILdRf                   local_009C
40E388: 4a FnLenStr               			;取用户名的长度,这个伪指令是很常见的
40E389: Lead2/69 CVarI4            local_00CC		;转换(C-Convert)为变体型(Var就是Variant),这里要利用这个长度作为循环次数
40E38D: 2f FFree1Str               local_009C
40E390: 1a FFree1Ad                local_0098
40E393: Lead3/68 ForVar:           (when done) 40E3F5	;ForVar,呵呵,循环从这里开始了
40E399: 04 FLdRfVar                local_009C
40E39C: 21 FLdPrThis              
40E39D: 0f VCallAd                 text
40E3A0: 19 FStAdFunc               local_0098
40E3A3: 08 FLdPr                   local_0098
40E3A6: 0d VCallHresult            get__ipropTEXTEDIT	;再取用户名……
40E3AB: 04 FLdRfVar                local_0094		;这是用户名的指针--我怎么知道?用OllyDBG调试一下您也就知道了
40E3AE: 28 LitVarI2:               ( local_00DC ) 0x1  (1)	;立即数1入栈
40E3B3: 04 FLdRfVar                local_012C		;记得吗,刚才的那个循环计数器
40E3B6: Lead1/22 CI4Var           			;转换为整型
40E3B8: 3e FLdZeroAd               local_009C		;取得用户名字符串一级指针
40E3BB: 46 CVarStr                 local_00BC		;转换为变体型
40E3BE: 04 FLdRfVar                local_00FC		;用户名字符串指针入栈
40E3C1: 0a ImpAdCallFPR4:           			;这句调用rtcMidCharVar,调试的时候您就可以看到了,用意很明显:每轮循环取用户名的一个字符
40E3C6: 04 FLdRfVar                local_00FC		;取得的字母入栈
40E3C9: Lead2/fe CStrVarVal        local_0150		;转换为字符串型
40E3CD: 0b ImpAdCallI2             			;调用rtcAnsiValueBstr转换为ASCII码
40E3D2: 44 CVarI2                  local_00CC		;再转换为变体型
40E3D5: Lead0/ef ConcatVar        			;将每轮循环得到的十进制数作为字符串相连接,假定输入是cyclotron,那么循环最后得到的就是"9912199108111116114111110",当然这个字符串在内存中是以Unicode的形式出现的
40E3D9: Lead1/f6 FStVar           			;保存字符串(St-Save to)
40E3DD: 2f FFree1Str               local_0150
40E3E0: 1a FFree1Ad                local_0098
40E3E3: 36 FFreeVar
40E3EC: 04 FLdRfVar                local_012C
40E3EF: Lead3/7e NextStepVar:      (continue) 40E399	;下一轮循环
40E3F5: 04 FLdRfVar                local_0094		;这里是把前面循环得到的字符串入栈
40E3F8: Lead0/eb FnLenVar         			;取它的长度
40E3FC: 28 LitVarI2:               ( local_00AC ) 0x9  (9);立即数9入栈
40E401: 5d HardType               
40E402: Lead0/74 GtVarBool        			;是否大于9?
40E404: 1c BranchF:                40E425
40E407: 04 FLdRfVar                local_0094
40E40A: Lead3/c4 LitVarR8         			;浮点立即数3.1415926540000000000入栈,R8就表示Real of 8 bytes,如何得到这个浮点立即数的精确值?这里有一个小技巧,我待会儿会给大家介绍:)
40E416: Lead0/bc DivVar           			;Div--很明显是做除法,记住:先入栈的是被除数,后入栈的是除数,其他算术运算指令也遵循这个规则
40E41A: Lead0/e1 FnFixVar     				;对除法的结果取整,学过VB的朋友应该熟悉这个指令    
40E41E: Lead1/f6 FStVar           			;保存结果为保存为Variant型
40E422: 1e Branch:                 40e3f5
40E425: 04 FLdRfVar                local_0094
40E428: Lead3/c1 LitVarI4:         ( local_param_5678FF54 ) 0x30f85678  (821581432)
							;立即数0x30f85678入栈
40E430: Lead0/17 XorVar           			;Xor--异或运算
40E434: Lead1/f6 FStVar           			;保存为Variant型
40E438: 04 FLdRfVar                local_0094		;前面的运算结果入栈
40E43B: 08 FLdPr                   local_param_0008
40E43E: 8a MemLdStr               			;这里调入一个内存操作数0D8B3h,可以用OllyDBG跟踪一下看看
40E441: Lead2/69 CVarI4            local_00AC		;转换为变体型
40E445: Lead0/9c SubVar           			;两数相减
40E449: Lead1/f6 FStVar           			;保存为Variant型,我们记这个结果为S

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 7
支持
分享
最新回复 (18)
雪    币: 332
活跃值: (479)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
2
收藏
2004-12-26 11:06
0
雪    币: 494
活跃值: (629)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
3
谢谢,收藏
2004-12-26 11:16
0
雪    币: 257
活跃值: (369)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
4

分析得很好!
2004-12-26 11:42
0
雪    币: 98745
活跃值: (201039)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
5
支持!!!
2004-12-26 12:41
0
雪    币: 3686
活跃值: (1036)
能力值: (RANK:760 )
在线值:
发帖
回帖
粉丝
6
学习~
2004-12-26 13:36
0
雪    币: 127
活跃值: (212)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
7
不错,学习
2004-12-26 13:45
0
雪    币: 390
活跃值: (707)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
8
very very good

春节就拿你的文章学了。
2004-12-26 13:53
0
雪    币: 383
活跃值: (786)
能力值: ( LV12,RANK:730 )
在线值:
发帖
回帖
粉丝
9
呵呵。。。研究生:D
2004-12-26 15:06
0
雪    币: 61
活跃值: (160)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
10
支持!!!
2004-12-26 16:41
0
雪    币: 343
活跃值: (611)
能力值: ( LV9,RANK:810 )
在线值:
发帖
回帖
粉丝
11
昨天看完了。强者出手,果然不凡。
可贵的是cyclotron 给出了一种探索未知指令的一种方法。
VB在本机代码和伪代码之间有很多相通的东西。:D
2004-12-28 15:47
0
雪    币: 223
活跃值: (105)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
12
最近正准备开始研究VB程序,学习学习
2004-12-29 20:27
0
雪    币: 107
活跃值: (54)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
upup
2005-3-17 01:53
0
雪    币: 211
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
期待很久了,学习中....
2005-3-17 10:48
0
雪    币: 208
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
15
学习中,顶!!!
2005-3-17 12:25
0
雪    币: 107
活跃值: (54)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
最初由 suwenfeng 发布
期待很久了,学习中....


老兄这是04年发的贴呀
昨天我破VB程序时在论坛翻到的我那灌水的毛病还是改不了所以这个贴才浮了上来
2005-3-17 13:08
0
雪    币: 271
活跃值: (196)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
支持,学习,顶!
2005-4-4 12:57
0
雪    币: 158
活跃值: (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
支持你,希望继续
2005-4-8 20:11
0
雪    币: 173
活跃值: (2346)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
cwx
19
学习。。。支持!
2005-4-9 03:17
0
游客
登录 | 注册 方可回帖
返回
//