首页
社区
课程
招聘
[原创]VB P-code -- 伪代码的奥秘
发表于: 2004-12-26 11:02 17670

[原创]VB P-code -- 伪代码的奥秘

2004-12-26 11:02
17670

*岁末大盘点*
VB P-code -- 伪代码的奥秘
作者:cyclotron

   欢迎回到VB P-code伪代码世界。
   前两期我为大家介绍了VB P-code虚拟机的运行机制和P-code专用调试器WKTVBDebugger,相信大家已经对VB P-code程序有所了解了。我们的任务当然不仅仅局限于理论研究,解析VB P-code的最终目的还是加密解密和逆向工程。由于Microsoft没有公开VB P-code伪代码的技术文档,我们无法获得现成的伪代码指令说明,而单凭VB P-code反编译器给出的助记符信息是远远不够的,这就要求我们自行发掘伪代码执行的奥秘。
   可能有些朋友还不太明白,既然WKTVBDebugger作为一个伪代码级的调试器已经屏蔽了VB P-code虚拟机的解释过程,为什么还费神要去了解这些伪指令执行的细节呢?这里我请大家思考一个问题:假设你现在用WKTVBDebugger跟踪AddVar这句伪指令,你如何知道它的操作数和操作结果分别是多少?也许有人说,既然VB P-code虚拟机是基于堆栈的,那么操作数和操作结果一定存放在堆栈里了。不错,这些内容确实存在于堆栈中,但是你知道它的存放形式吗?是单个的操作数,是指针,还是其他复杂的数据结构?我敢说,如果你是第一次调试这句VB P-code指令,它一定会令你不知所措,即使你能最终解决这个问题,也一定会花上不少时间,结果也会令你觉得不可思议。此外,对于不同的P-code伪指令,其存放形式是各不相同的。如果你在调试一个软件时,不能看到每句指令的操作数和操作结果,那与静态反编译何异之有?WKTVBDebugger的调试功能还不是形同虚设?当然,这只是其中的一个方面。如果你连伪指令的抽象动作都不明白(毕竟不是所有的伪指令都能从其助记符看出其含义的),那又该如何呢?正如我前面所言,要理解这些伪指令的执行细节,是要费一番功夫的。

   既然如此,我们应当如何解决这些问题呢?答案将由黄金组合OllyDBG+WKTVBDebugger+VBParser来揭晓。为了方便,这次使用的例子程序还是上两篇使用的VB P-code.exe,我们将通过跟踪虚拟机的解释过程来研究P-code伪代码的执行细节。
首先使用ljtt的VBParser(非常专业的VB P-code反编译器)解析VB P-code.exe,得到伪代码如下:

FileName: D:\Contribution\VB P-code\VB P-code--伪代码的奥秘\VB P-code.exe

-----=====-----=====-----=====--Pcode--=====-----=====-----=====-----

[CommandButton]
Private Sub Command1_Click()
'-=-=-=-=-=-=-= ProcAddr Range: [004019C4 - 00401A54] , ProcSize: 90 =-=-=-=-=-=-=-
004019C4: 27 9C FE           LitVar_Missing          PushVarError 80020004 (missing)                                                   004019C7: 27 BC FE           LitVar_Missing          PushVarError 80020004 (missing)                                                   004019CA: 27 DC FE           LitVar_Missing          PushVarError 80020004 (missing)                                                   
004019CD: 27 FC FE           LitVar_Missing          PushVarError 80020004 (missing)                                                   
004019D0: 27 1C FF           LitVar_Missing          PushVarError 80020004 (missing)                                                   

*********** Referent String: "Input" ***********
                              |
004019D3: 3A 4C FF 00 00     LitVarStr               PushVarString Ptr_00401434
004019D8: 4E 3C FF           FStVarCopyObj           [local_C4]=vbaVarDup(Pop)
004019DB: 04 3C FF           FLdRfVar                Push local_C4

*********** Referent String: "Please input an integer" ***********
                              |
004019DE: 3A 6C FF 01 00     LitVarStr               PushVarString Ptr_00401400
004019E3: 4E 5C FF           FStVarCopyObj           [local_A4]=vbaVarDup(Pop)
004019E6: 04 5C FF           FLdRfVar                Push local_A4
004019E9: 0B 02 00 1C 00     ImpAdCallI2             Call Ptr_00401020; check stack 001C; Push EAX
004019EE: 46 7C FE           CVarStr                 
004019F1: FC F6 8C FE        FStVar                  

(……省略)
6A37D153  MOV AL,BYTE PTR DS:[ESI]			;中断在这句,开始读操作码了,注意esi的值为004019C4
6A37D155  INC ESI					;使esi指向操作数
6A37D156  JMP DWORD PTR DS:[EAX*4+6A37DA58]		;根据跳转地址表和操作码寻址解释单元
6A37D39F  MOVSX EDI,WORD PTR DS:[ESI]			;把字操作数带符号扩展到edi
6A37D3A2  ADD ESI,2					;esi指向下一句伪指令的操作码
6A37D3A5  MOV WORD PTR DS:[EDI+EBP],0A			;ebp显然是程序堆栈区某处的基址,但不是堆栈顶的指针,它把0A保存到edi指向的偏移地址处
6A37D3AB  MOV DWORD PTR DS:[EDI+EBP+8],80020004		;向下8个字节处存入80020004,根据VBParser的说明,这个数字表示空参数(缺省参数),事实上我在源代码中确实没有提供这个参数
6A37D3B3  ADD EDI,EBP					;这次edi得到0A所在的虚拟地址
6A37D3B5  PUSH EDI					;在堆栈中压入这个虚拟地址
6A37D3B6  XOR EAX,EAX					;清空eax,准备读取下一句伪指令
6A37D3B8  MOV AL,BYTE PTR DS:[ESI]			;读取下一句伪指令的操作码
6A37D3BA  INC ESI					;esi指向下一句伪指令的次级操作码或操作数
6A37D3BB  JMP DWORD PTR DS:[EAX*4+6A37DA58]		;根据地址跳转表和操作码寻址解释单元
0012F458   0012F494					;栈顶
0012F45C   00000000
0012F460   00000000
……………………
……………………
0012F488   00000000
0012F48C   00000000
0012F490   00000000
0012F494   0000000A					;这就是刚才压入栈顶的数据了
0012F498   00000000
0012F49C   80020004
0012F4A0   00000000
6A37D3B8  MOV AL,BYTE PTR DS:[ESI]			;esi=004019D3
6A37D3BA  INC ESI
6A37D3BB  JMP DWORD PTR DS:[EAX*4+6A37DA58]

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

收藏
免费 9
支持
分享
最新回复 (6)
雪    币: 97697
活跃值: (200824)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
2
支持!!!
2004-12-26 12:40
0
雪    币: 690
活跃值: (1826)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
3
good.
2004-12-26 15:42
0
雪    币: 61
活跃值: (160)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
4
支持!!!
2004-12-26 16:40
0
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
5
测试顺便支持~~~~~~~~`
2008-10-31 21:01
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
认真学习中...
2009-2-10 22:09
0
雪    币: 41
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
学习学习
2021-11-3 21:34
0
游客
登录 | 注册 方可回帖
返回
//