首页
社区
课程
招聘
关于VB中数据的存储格式和寻址方式 菜鸟献丑了~~~
2004-7-1 11:16 15581

关于VB中数据的存储格式和寻址方式 菜鸟献丑了~~~

RoBa 活跃值
16
2004-7-1 11:16
15581
关于VB中数据的存储格式和寻址方式

前言:
大家最喜欢破什么语言写的软件?相信没人会回答VB,好像一种语言越是“高级”,越是“傻瓜”,编译系统自动加入的代码就越多,会把源程序的意图隐藏起来,破解的难度反而越大(我指的是完全破解出算法,写出注册机)。用ASM直接写的程序,反汇编的结果和源程序相似得可怕,用VC写的也比较容易读懂,用DELPHI写的就有一定难度了,不过毕竟还有一个好用的DEDE,VB写的呢?冗长的代码,复杂的存储方式,铺天盖地的DLL,足以让人崩溃。以前大概用VB的还都是些菜鸟级的程序员,加的保护也非常简单,破解VB程序还不算太困难,到了现在,好像VB已经成了一种把代码复杂化的加壳软件,纷纷被各路编程好手采用,把高难度的算法用超复杂的代码保护起来,呜呼哀哉!最近连遇几个软件,全是AsProtect+VB(好像还是P-CODE),令人郁闷的组合,几天破解未果,想从头把关于VB的一些东东仔细研究一下,于是就有了这篇文章。我想高手们大概早就研究过了,也许是不屑写出来而己,还请各位多多指点。

先看看VB常用的数据类型有哪些:
Byte		1个字节		0到255	
Boolean		2个字节		True或False
Integer		2个字节		-32,768到32,767
Long(长整型)	4个字节		-2,147,483,648到2,147,483,647
Single(单精度浮点型)	4个字节		负数时从-3.402823E38到-1.401298E-45
					正数时从1.401298E-45到3.402823E38
Double(双精度浮点型)	8个字节		负数时从-1.79769313486232E308到-4.94065645841247E-324
					正数时从4.94065645841247E-324到1.79769313486232E308
Currency(变比整型)	8个字节		从-922,337,203,685,477.5808到922,337,203,685,477.5807
Decimal		14个字节	没有小数点时为+/-79,228,162,514,264,337,593,543,950,335
					而小数点右边有28位数时为+/-7.9228162514264337593543950335
					最小的非零值为+/-0.0000000000000000000000000001
Date		8个字节		100年1月1日到9999年12月31日
Object		4个字节		任何Object引用
String(变长)	10字节+串长度	0到大约20亿
String(定长)	字符串长度1到大约65,400
Variant(数字)	16个字节	任何数字值,最大可达Double的范围
Variant(字符)	22个字节+串长度	与变长String有相同的范围

像Integer,Long,Single,Double等“直接”的类型比较容易,和其他的语言一样直接看内存就可以了。
比较特殊的是Currency,他的值要除10000才是真正的值,不过这个用的不多。
最麻烦的是Variant类型,因为VB是设计成一种傻瓜式的语言,对数据类型没有严格的规定,甚至可以不用声明变量而直接使用,所以在反汇编后的VB程序中,关于类型转换的语句占了很大一部分,只要一涉及数据计算,总会看到一堆数来回转换,其中许多函数的参数,还有未经声明直接使用的变量等,都是Variant类型。这种类型在VB中到处要用到,十分重要,但又常常使人困惑。它在内存中的寻址方式很特殊,为此VB还专门为其提供了一组函数(多带有Var字样),这些函数其实大多放在Oleaut32.dll中,但往往再由msvbvm60.dll来调用,比如__vbaVarTstEq,__vbaVarTstNe,__vbaVarMove,__vbaVarAdd,__vbaVarSub,VarBstrCmp等等。Variant变量的寻址方式在看雪的书中略有提及但不详细,我在这里补充一些:

首先我们必须明白,那些未声明类型的Variant变量并不是真的没有数据类型,只不过是VB编译系统将这些变量的“类型信息”也包含在变量的数据中了,等到程序运行时根据对该变量所进行的操作来灵活地决定变量属于什么类型,比如有这么几句
Dim roba As Variant
roba=4321
Text1.Text=roba

程序声明了一个Variant变量roba(或者干脆什么也没声明)又给它赋了一个值4321,那么编译器就知道这时候roba是一个Integer型变量,可是下面呢又把它赋值给了Text1.Text(也就是在一个文本框里把4321显示出来)这时候编译器马上又插入语句使roba变为字符串型变量。(真是难为M$那帮人了)

那么这种变量究竟是怎样存储的呢?看下面的例子:
Private Sub Command1_Click()
Dim a, b As Variant
a = "RoBa"
b = Text1.Text
If a = b Then
MsgBox "Well done!", vbOKOnly, "Crack"
End If
End Sub

用W32DASM反汇编,查找字串,很容易找到下面:
:00401D49 8D45DC                  lea eax, dword ptr [ebp-24]
:00401D4C 8D4DCC                  lea ecx, dword ptr [ebp-34]
:00401D4F 50                      push eax			;变量a
:00401D50 51                      push ecx			;变量b

* Reference To: MSVBVM60.__vbaVarTstEq, Ord:0000h
                                  |
:00401D51 FF1540104000            Call dword ptr [00401040]	;比较
:00401D57 6685C0                  test ax, ax
:00401D5A 0F8484000000            je 00401DE4			;不同就跳走了

* Reference To: MSVBVM60.__vbaVarDup, Ord:0000h
                                  |
:00401D60 8B3D7C104000            mov edi, dword ptr [0040107C]
:00401D66 B904000280              mov ecx, 80020004
:00401D6B 894D8C                  mov dword ptr [ebp-74], ecx
:00401D6E B80A000000              mov eax, 0000000A
:00401D73 894D9C                  mov dword ptr [ebp-64], ecx
:00401D76 8D9564FFFFFF            lea edx, dword ptr [ebp+FFFFFF64]
:00401D7C 8D4DA4                  lea ecx, dword ptr [ebp-5C]
:00401D7F 894584                  mov dword ptr [ebp-7C], eax
:00401D82 894594                  mov dword ptr [ebp-6C], eax

* Possible StringData Ref from Code Obj ->"CCrack"
                                  |
:00401D85 C7856CFFFFFFFC174000    mov dword ptr [ebp+FFFFFF6C], 004017FC
:00401D8F 899D64FFFFFF            mov dword ptr [ebp+FFFFFF64], ebx
:00401D95 FFD7                    call edi
:00401D97 8D9574FFFFFF            lea edx, dword ptr [ebp+FFFFFF74]
:00401D9D 8D4DB4                  lea ecx, dword ptr [ebp-4C]

* Possible StringData Ref from Code Obj ->"WWell done!"
                                  |
:00401DA0 C7857CFFFFFFE0174000    mov dword ptr [ebp+FFFFFF7C], 004017E0
:00401DAA 899D74FFFFFF            mov dword ptr [ebp+FFFFFF74], ebx
:00401DB0 FFD7                    call edi
:00401DB2 8D5584                  lea edx, dword ptr [ebp-7C]
:00401DB5 8D4594                  lea eax, dword ptr [ebp-6C]
:00401DB8 52                      push edx
:00401DB9 8D4DA4                  lea ecx, dword ptr [ebp-5C]
:00401DBC 50                      push eax
:00401DBD 51                      push ecx
:00401DBE 8D55B4                  lea edx, dword ptr [ebp-4C]
:00401DC1 56                      push esi
:00401DC2 52                      push edx

* Reference To: MSVBVM60.rtcMsgBox, Ord:0253h
                                  |
:00401DC3 FF1528104000            Call dword ptr [00401028]	;出现成功对话框

很明显的比较方式,用SoftICE跟一下,胡乱输入1111,中断在401D51处,可是当D eax,D ecx时只能看到08
:d eax
016F:0063F3EC 08 00 00 00 00 00 4A 21-CC 0F 51 00 86 72 6F 17  ......J!..Q..ro.
016F:0063F3FC F4 F8 63 00 B6 10 40 00-34 F3 63 00 A0 10 40 00  ..c...@.4.c...@.
016F:0063F40C 01 00 00 00 1C F4 63 00-73 AD 02 66 CC 05 51 00  ......c.s..f..Q.
:d ecx
016F:0063F3DC 08 00 00 00 36 18 76 8B-E0 0F 51 00 0C 00 0D 00  ....6.v...Q.....
016F:0063F3EC 08 00 00 00 00 00 4A 21-CC 0F 51 00 86 72 6F 17  ......J!..Q..ro.
016F:0063F3FC F4 F8 63 00 B6 10 40 00-34 F3 63 00 A0 10 40 00  ..c...@.4.c...@.
当然不可能是把两个08比较,实际的UNICODE字串地址是在8个字节后的地方。即510FCC和510FE0
:d 510fcc
016F:00510FCC 52 00 6F 00 42 00 61 00-00 00 00 00 14 00 00 A0  R.o.B.a.........
016F:00510FDC 08 00 00 00 31 00 31 00-31 00 31 00 00 00 00 00  ....1.1.1.1.....
016F:00510FEC 11 00 00 A0 1C 00 41 00-0C 00 41 00 EC 0F 51 00  ......A...A...Q.
:d 510fe0
016F:00510FE0 31 00 31 00 31 00 31 00-00 00 00 00 11 00 00 A0  1.1.1.1.........
016F:00510FF0 1C 00 41 00 0C 00 41 00-EC 0F 51 00 02 00 00 A0  ..A...A...Q.....
016F:00511000 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ................
那么08是什么意思呢?为什么EAX,ECX要指向这么一个莫名其妙的值呢?我猜想那个08就是表示Varient的实际类型,换一个类型试试:
Private Sub Command1_Click()
Dim b As Variant
b = Text1.Text
If b = 5678 Then
MsgBox "Well done!", vbOKOnly, "Crack"
End If
End Sub

:00401D13 50                      push eax
:00401D14 51                      push ecx
:00401D15 C7857CFFFFFF2E160000    mov dword ptr [ebp+FFFFFF7C], 0000162E ;162Eh=5678
:00401D1F C78574FFFFFF02800000    mov dword ptr [ebp+FFFFFF74], 00008002 ;类型值

* Reference To: MSVBVM60.__vbaVarTstEq, Ord:0000h
                                  |
:00401D29 FF1540104000            Call dword ptr [00401040]
:00401D2F 6685C0                  test ax, ax
:00401D32 0F8484000000            je 00401DBC

在401D29时,d eax仍然看到08,d *(eax+8)可以看到我们随意输入的字符串,而d ecx时看到
:d ecx
016F:0063F384 02 80 00 00 66 24 27 06-2E 16 00 00 B0 00 DD 00  ....f$'.........
016F:0063F394 00 00 00 00 00 00 00 00-00 00 00 00 00 00 08 00  ................
016F:0063F3A4 00 00 00 00 10 DB 01 00-0E 84 D7 3A 00 00 00 00  ...........:....
可以看到02,那么按上面方面类推,ecx+8处是什么呢?162E,呵~~~~,不就是5678的十六进制吗,那么02当然就表示Integer了.(高位的80不知道什么作用,改成00似乎也没有影响)
问题清楚一些了,Variant变量的第一个字节表示数据的实际类型,后面七个字节不知有什么用,在第九个字节处才是数据的值或数据的地址。
我整理出的Variant变量的各种实际类型的代码:
02	Integer		用d eax+8可以看到,占两字节
03	Long		用d eax+8可以看到,占四字节
04	Single		用ds eax+8可以看到
05	Double		用dl eax+8可以看到
08	String		用d *(eax+8)可以看到
0B	Boolean		用d eax+8可以看到,True为FFFFFFFF
11	Byte		用d eax+8可以看到,占一字节

以后当你D出一个05,08这样的数字时不会再感到莫名其妙了吧。

还是有许多不明白的地方,比如中间的七位到底有什么用,在那些有Var字样的函数内部实现的过程究竟是怎样(我跟进了一个vbaVarAdd发现极其复杂)等等,还请各位大大指出来,帮助我们这些在黑暗中摸索的菜鸟们。


[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

收藏
点赞8
打赏
分享
最新回复 (24)
雪    币: 6051
活跃值: (1441)
能力值: ( LV15,RANK:1473 )
在线值:
发帖
回帖
粉丝
lelfei 23 2004-7-1 12:40
2
0
好!!
希望多研究一点!!!
雪    币: 2319
活跃值: (565)
能力值: (RANK:300 )
在线值:
发帖
回帖
粉丝
riijj 7 2004-7-1 12:58
3
0
好~~~  

我对 vb 的破解没有甚么信心…
雪    币: 674
活跃值: (1668)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
daxia200N 6 2004-7-1 13:16
4
0
不错
雪    币: 896
活跃值: (4039)
能力值: ( LV9,RANK:3410 )
在线值:
发帖
回帖
粉丝
fly 85 2004-7-1 13:44
5
0
辛苦
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
cyclotron 17 2004-7-1 15:20
6
0
好文!
雪    币: 253
活跃值: (27)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
呱叽呱叽 1 2004-7-1 16:42
7
0
好文:)
雪    币: 515
活跃值: (1223)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
RoBa 16 2004-7-2 16:50
8
0
我还有个问题,那个Decimal类型是怎么回事?我的VB6里面不让用dim来定义,好像要用new什么的,精VB的高人指点一下。
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
MissYou 2004-7-2 18:22
9
0
跟踪VB的程序最好用od,并且随时注意堆栈。
雪    币: 21
活跃值: (40)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
Jockey 1 2004-7-2 19:47
10
0
Byte (0到255)和Decimal(+/-0到2的96次方-1)
雪    币: 258
活跃值: (230)
能力值: ( LV12,RANK:770 )
在线值:
发帖
回帖
粉丝
qiweixue 19 2004-7-2 20:04
11
0
动静兼顾・
雪    币: 263
活跃值: (340)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
WXHing 5 2004-7-2 20:40
12
0
学习.
雪    币: 166
活跃值: (112)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
小楼 1 2004-7-2 21:34
13
0
多谢RoBa文章对此的研究。我因此也看了一下。
用oleview查看msvbvm60.dll,可以看到这样定义
typedef [uuid(ED822010-6D7F-11CF-B949-00AA004455EA), helpcontext(0x0010fe25)]
enum {
    vbEmpty                  = 0,
    vbNull                   = 1,
    vbInteger                = 2,
    vbLong                   = 3,
    vbSingle                 = 4,
    vbDouble                 = 5,
    vbCurrency               = 6,
    vbDate                   = 7,
    vbString                 = 8,
    vbObject                 = 9,
    vbError                  = 10,
    vbBoolean                = 11,
    vbVariant                = 12,
    vbDataObject             = 13,
    vbDecimal                = 14,
    vbByte                   = 17,
    vbUserDefinedType        = 36,
    vbArray                  = 8192
} VbVarType;

上述这些应该是vb数据类型的十进制索引值

Variant变量的第一个字节表示数据的实际类型,后面七个字节不知有什么用,在第九个字节处才是数据的值或数据的地址。

关于“中间的7个字节”,我这样认为
+00          数据类型索引值
  01          00或80
                  
:00401D1F C78574FFFFFF02800000 mov dword ptr [ebp FFFFFF74], 00008002 ;类型值
注意这句,80由此赋值 03 "00" 04 "00", 03、04位置应该都是00,这或许是编译器为了数据对齐而自动生成的 05 -- 08 这里我想是无关数据
雪    币: 515
活跃值: (1223)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
RoBa 16 2004-7-2 21:48
14
0
老大出手,果然不凡 又学了一招oleView
那个80有时候去掉还不行,真麻烦。
雪    币: 166
活跃值: (112)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
小楼 1 2004-7-2 22:23
15
0
关于数据“80”,跟踪到一点代码,对80进行一些校验
以下来自msvbvm60.dll 6.0.8964版本
ENGINE:6610ABCE                 public __vbaVarTstEq
ENGINE:6610ABCE __vbaVarTstEq:
ENGINE:6610ABCE                 push    dword ptr [esp+8]
ENGINE:6610ABD2                 push    dword ptr [esp+8]
ENGINE:6610ABD6                 push    0
ENGINE:6610ABD8                 call    sub_66100017    // enter

ENGINE:66100017                 push    ebp
ENGINE:66100018                 mov     ebp, esp
ENGINE:6610001A                 sub     esp, 38h
ENGINE:6610001D                 mov     edx, [ebp+arg_8]
ENGINE:66100020                 mov     ecx, [ebp+arg_4]
ENGINE:66100023                 push    ebx
ENGINE:66100024                 push    esi
ENGINE:66100025                 mov     si, [ecx]
ENGINE:66100028                 push    edi
ENGINE:66100029                 mov     di, [edx]
ENGINE:6610002C                 mov     eax, 7FFFh
ENGINE:66100031                 and     edi, eax
ENGINE:66100033                 and     esi, eax    // esi=8002H, eax=7FFFH
ENGINE:66100035                 cmp     di, 9
ENGINE:66100039                 jz      loc_66107812
ENGINE:6610003F                 cmp     si, 9
ENGINE:66100043                 jz      loc_66107812
雪    币: 208
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
skeeter 2004-8-25 13:50
16
0
好文好文 顶一下
雪    币: 85328
活跃值: (198625)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
linhanshi 2004-8-25 16:54
17
0
good post!
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
saiterlz 2004-8-25 20:48
18
0
支持,写的好!
雪    币: 251
活跃值: (260)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
yesky1 5 2004-8-25 23:46
19
0
good guy
雪    币: 208
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xy8092 2004-10-4 18:32
20
0
精彩!!顶!
雪    币: 625
活跃值: (1057)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
xzchina 1 2004-10-5 18:17
21
0
看了之后真是受易非浅
雪    币: 410
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Alax 2005-1-9 16:40
22
0
看到关于vb的破解,我的机器正好中了一个毒,是vb的,不停的写我的注册表,名字是c:\windows\csrss.exe,瑞星杀不掉,nnd,烦人,不知道哪位大哥有兴趣看一下啊,只有17k。
可是我不知道怎么上传附件
雪    币: 257
活跃值: (369)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
newsearch 9 2005-1-9 18:55
23
0
csrss.exe是进程文件。

是客户端服务子系统,用以控制Windows图形相关子系统,是系统进程。另外蠕虫会以csrss.exe为文件名拷贝自己的副本文件到Windows目录下
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
panther666 2005-1-12 20:59
24
0
学习中。。。
雪    币: 1573
活跃值: (168)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
Thvoifar 1 2017-7-19 19:03
25
0
Mark一下,谢谢分享!
游客
登录 | 注册 方可回帖
返回