分享
 
 
 

关于VB中数据的存储格式和寻址方式

王朝vb·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

关于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发现极其复杂)等等,还请各位大大指出来,帮助我们这些在黑暗中摸索的菜鸟们。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有