关于VB中数据的存储格式和寻址方式精品资料.doc

上传人:封****n 文档编号:96697045 上传时间:2024-03-10 格式:DOC 页数:24 大小:203.50KB
返回 下载 相关 举报
关于VB中数据的存储格式和寻址方式精品资料.doc_第1页
第1页 / 共24页
关于VB中数据的存储格式和寻址方式精品资料.doc_第2页
第2页 / 共24页
点击查看更多>>
资源描述

《关于VB中数据的存储格式和寻址方式精品资料.doc》由会员分享,可在线阅读,更多相关《关于VB中数据的存储格式和寻址方式精品资料.doc(24页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、关于VB中数据的存储格式和寻址方式前言:大家最喜欢破什么语言写的软件?相信没人会回答VB,好像一种语言越是“高级”,越是“傻瓜”,编译系统自动加入的代码就越多,会把源程序的意图隐藏起来,破解的难度反而越大(我指的是完全破解出算法,写出注册机)。用ASM直接写的程序,反汇编的结果和源程序相似得可怕,用VC写的也比较容易读懂,用DELPHI写的就有一定难度了,不过毕竟还有一个好用的DEDE,VB写的呢?冗长的代码,复杂的存储方式,铺天盖地的DLL,足以让人崩溃。以前大概用VB的还都是些菜鸟级的程序员,加的保护也非常简单,破解VB程序还不算太困难,到了现在,好像VB已经成了一种把代码复杂化的加壳软件

2、,纷纷被各路编程好手采用,把高难度的算法用超复杂的代码保护起来,呜呼哀哉!最近连遇几个软件,全是AsProtect+VB(好像还是P-CODE),令人郁闷的组合,几天破解未果,想从头把关于VB的一些东东仔细研究一下,于是就有了这篇文章。我想高手们大概早就研究过了,也许是不屑写出来而己,还请各位多多指点。先看看VB常用的数据类型有哪些:代码:Byte1个字节0到255Boolean2个字节True或FalseInteger2个字节-32,768到32,767Long(长整型)4个字节-2,147,483,648到2,147,483,647Single(单精度浮点型)4个字节负数时从-3.4028

3、23E38到-1.401298E-45正数时从1.401298E-45到3.402823E38Double(双精度浮点型)8个字节负数时从-1.79769313486232E308到-4.94065645841247E-324正数时从4.94065645841247E-324到1.79769313486232E308Currency(变比整型)8个字节从-922,337,203,685,477.5808到922,337,203,685,477.5807Decimal14个字节没有小数点时为+/-79,228,162,514,264,337,593,543,950,335而小数点右边有28位数时

4、为+/-7.9228162514264337593543950335最小的非零值为+/-0.0000000000000000000000000001Date8个字节100年1月1日到9999年12月31日Object4个字节任何Object引用String(变长)10字节+串长度0到大约20亿String(定长)字符串长度1到大约65,400Variant(数字)16个字节任何数字值,最大可达Double的范围Variant(字符)22个字节+串长度与变长String有相同的范围像Integer,Long,Single,Double等“直接”的类型比较容易,和其他的语言一样直接看内存就可以了。

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

6、ll来调用,比如_vbaVarTstEq,_vbaVarTstNe,_vbaVarMove,_vbaVarAdd,_vbaVarSub,VarBstrCmp等等。Variant变量的寻址方式在看雪的书中略有提及但不详细,我在这里补充一些:首先我们必须明白,那些未声明类型的Variant变量并不是真的没有数据类型,只不过是VB编译系统将这些变量的“类型信息”也包含在变量的数据中了,等到程序运行时根据对该变量所进行的操作来灵活地决定变量属于什么类型,比如有这么几句代码:DimrobaAsVariantroba=4321Text1.Text=roba程序声明了一个Variant变量roba(或者干脆

7、什么也没声明)又给它赋了一个值4321,那么编译器就知道这时候roba是一个Integer型变量,可是下面呢又把它赋值给了Text1.Text(也就是在一个文本框里把4321显示出来)这时候编译器马上又插入语句使roba变为字符串型变量。(真是难为M$那帮人了)那么这种变量究竟是怎样存储的呢?看下面的例子:代码:PrivateSubCommand1_Click()Dima,bAsVarianta=RoBab=Text1.TextIfa=bThenMsgBoxWelldone!,vbOKOnly,CrackEndIfEndSub用W32DASM反汇编,查找字串,很容易找到下面:代码:00401D

8、498D45DCleaeax,dwordptrebp-24:00401D4C8D4DCCleaecx,dwordptrebp-34:00401D4F50pusheax;变量a:00401D5051pushecx;变量b*ReferenceTo:MSVBVM60._vbaVarTstEq,Ord:0000h|:00401D51FF1540104000Calldwordptr00401040;比较:00401D576685C0testax,ax:00401D5A0F8484000000je00401DE4;不同就跳走了*ReferenceTo:MSVBVM60._vbaVarDup,Ord:000

9、0h|:00401D608B3D7C104000movedi,dwordptr0040107C:00401D66B904000280movecx,80020004:00401D6B894D8Cmovdwordptrebp-74,ecx:00401D6EB80A000000moveax,0000000A:00401D73894D9Cmovdwordptrebp-64,ecx:00401D768D9564FFFFFFleaedx,dwordptrebp+FFFFFF64:00401D7C8D4DA4leaecx,dwordptrebp-5C:00401D7F894584movdwordptrebp

10、-7C,eax:00401D82894594movdwordptrebp-6C,eax*PossibleStringDataReffromCodeObj-CCrack|:00401D85C7856CFFFFFFFC174000movdwordptrebp+FFFFFF6C,004017FC:00401D8F899D64FFFFFFmovdwordptrebp+FFFFFF64,ebx:00401D95FFD7calledi:00401D978D9574FFFFFFleaedx,dwordptrebp+FFFFFF74:00401D9D8D4DB4leaecx,dwordptrebp-4C*Po

11、ssibleStringDataReffromCodeObj-WWelldone!|:00401DA0C7857CFFFFFFE0174000movdwordptrebp+FFFFFF7C,004017E0:00401DAA899D74FFFFFFmovdwordptrebp+FFFFFF74,ebx:00401DB0FFD7calledi:00401DB28D5584leaedx,dwordptrebp-7C:00401DB58D4594leaeax,dwordptrebp-6C:00401DB852pushedx:00401DB98D4DA4leaecx,dwordptrebp-5C:00

12、401DBC50pusheax:00401DBD51pushecx:00401DBE8D55B4leaedx,dwordptrebp-4C:00401DC156pushesi:00401DC252pushedx*ReferenceTo:MSVBVM60.rtcMsgBox,Ord:0253h|:00401DC3FF1528104000Calldwordptr00401028;出现成功对话框很明显的比较方式,用SoftICE跟一下,胡乱输入1111,中断在401D51处,可是当Deax,Decx时只能看到08:deax016F:0063F3EC0800000000004A21-CC0F51008

13、6726F17.J!.Q.ro.016F:0063F3FCF4F86300B6104000-34F36300A0104000.c.4.c.016F:0063F40C010000001CF46300-73AD0266CC055100.c.s.f.Q.:decx016F:0063F3DC080000003618768B-E00F51000C000D00.6.v.Q.016F:0063F3EC0800000000004A21-CC0F510086726F17.J!.Q.ro.016F:0063F3FCF4F86300B6104000-34F36300A0104000.c.4.c.当然不可能是把两个0

14、8比较,实际的UNICODE字串地址是在8个字节后的地方。即510FCC和510FE0:d510fcc016F:00510FCC52006F0042006100-00000000140000A0R.o.B.a.016F:00510FDC0800000031003100-3100310000000000.1.1.1.1.016F:00510FEC110000A01C004100-0C004100EC0F5100.A.A.Q.:d510fe0016F:00510FE03100310031003100-00000000110000A01.1.1.1.016F:00510FF01C0041000C00

15、4100-EC0F5100020000A0.A.A.Q.016F:00511000?-?.那么08是什么意思呢?为什么EAX,ECX要指向这么一个莫名其妙的值呢?我猜想那个08就是表示Varient的实际类型,换一个类型试试:代码:PrivateSubCommand1_Click()DimbAsVariantb=Text1.TextIfb=5678ThenMsgBoxWelldone!,vbOKOnly,CrackEndIfEndSub代码:00401D1350pusheax:00401D1451pushecx:00401D15C7857CFFFFFF2E160000movdwordptreb

16、p+FFFFFF7C,0000162E;162Eh=5678:00401D1FC78574FFFFFF02800000movdwordptrebp+FFFFFF74,00008002;类型值*ReferenceTo:MSVBVM60._vbaVarTstEq,Ord:0000h|:00401D29FF1540104000Calldwordptr00401040:00401D2F6685C0testax,ax:00401D320F8484000000je00401DBC在401D29时,deax仍然看到08,d*(eax+8)可以看到我们随意输入的字符串,而decx时看到:decx016F:00

17、63F3840280000066242706-2E160000B000DD00.f$.016F:0063F3940000000000000000-0000000000000800.016F:0063F3A40000000010DB0100-0E84D73A00000000.:.可以看到02,那么按上面方面类推,ecx+8处是什么呢?162E,呵,不就是5678的十六进制吗,那么02当然就表示Integer了.(高位的80不知道什么作用,改成00似乎也没有影响)问题清楚一些了,Variant变量的第一个字节表示数据的实际类型,后面七个字节不知有什么用,在第九个字节处才是数据的值或数据的地址。我整

18、理出的Variant变量的各种实际类型的代码:代码:02Integer用deax+8可以看到,占两字节03Long用deax+8可以看到,占四字节04Single用dseax+8可以看到05Double用dleax+8可以看到08String用d*(eax+8)可以看到0BBoolean用deax+8可以看到,True为FFFFFFFF11Byte用deax+8可以看到,占一字节以后当你D出一个05,08这样的数字时不会再感到莫名其妙了吧。还是有许多不明白的地方,比如中间的七位到底有什么用,在那些有Var字样的函数内部实现的过程究竟是怎样(我跟进了一个vbaVarAdd发现极其复杂)等等,还请

19、各位大大指出来,帮助我们这些在黑暗中摸索的菜鸟们。标 题: 发信人:小楼 时 间:2004-07-02,21:34详细信息: 多谢RoBa文章对此的研究。我因此也看了一下。用oleview查看msvbvm60.dll,可以看到这样定义代码:typedefuuid(ED822010-6D7F-11CF-B949-00AA004455EA),helpcontext(0x0010fe25)enumvbEmpty=0,vbNull=1,vbInteger=2,vbLong=3,vbSingle=4,vbDouble=5,vbCurrency=6,vbDate=7,vbString=8,vbObject

20、=9,vbError=10,vbBoolean=11,vbVariant=12,vbDataObject=13,vbDecimal=14,vbByte=17,vbUserDefinedType=36,vbArray=8192VbVarType;上述这些应该是vb数据类型的十进制索引值引用: Variant变量的第一个字节表示数据的实际类型,后面七个字节不知有什么用,在第九个字节处才是数据的值或数据的地址。 关于“中间的7个字节”,我这样认为代码:00数据类型索引值0100或80引用:00401D1FC78574FFFFFF02800000movdwordptrebp+FFFFFF74,0000

21、8002;类型值注意这句,80由此赋值03000400,03、04位置应该都是00,这或许是编译器为了数据对齐而自动生成的05-08这里我想是无关数据发信人:小楼 时 间:2004-07-02,22:23详细信息: 关于数据“80”,跟踪到一点代码,对80进行一些校验以下来自msvbvm60.dll6.0.8964版本代码:ENGINE:6610ABCEpublic_vbaVarTstEqENGINE:6610ABCE_vbaVarTstEq:ENGINE:6610ABCEpushdwordptresp+8ENGINE:6610ABD2pushdwordptresp+8ENGINE:6610A

22、BD6push0ENGINE:6610ABD8callsub_66100017/enter代码:ENGINE:66100017pushebpENGINE:66100018movebp,espENGINE:6610001Asubesp,38hENGINE:6610001Dmovedx,ebp+arg_8ENGINE:66100020movecx,ebp+arg_4ENGINE:66100023pushebxENGINE:66100024pushesiENGINE:66100025movsi,ecxENGINE:66100028pushediENGINE:66100029movdi,edxENGI

23、NE:6610002Cmoveax,7FFFhENGINE:66100031andedi,eaxENGINE:66100033andesi,eax/esi=8002H,eax=7FFFHENGINE:66100035cmpdi,9ENGINE:66100039jzloc_66107812ENGINE:6610003Fcmpsi,9ENGINE:66100043jzloc_66107812附录资料:不需要的可以自行删除bat文件的基本应用bat是dos下的批处理文件 .cmd是nt内核命令行环境的另一种批处理文件 从更广义的角度来看,unix的shell脚本以及其它操作系统甚至应用程序中由外壳进

24、行解释执行的文本,都具有与批处理文件十分相似的作用,而且同样是由专用解释器以行为单位解释执行,这种文本形式更通用的称谓是脚本语言。所以从某个程度分析,batch, unix shell, awk, basic, perl 等脚本语言都是一样的,只不过应用的范围和解释的平台各有不同而已。甚至有些应用程序仍然沿用批处理这一称呼,而其内容和扩展名与dos的批处理却又完全不同。 = 首先批处理文件是一个文本文件,这个文件的每一行都是一条DOS命令(大部分时候就好象我们在DOS提示符下执行的命令行一样),你可以使用DOS下的Edit或者Windows的记事本(notepad)等任何文本文件编辑工具创建和

25、修改批处理文件。 = 注 = 批处理文件中完全可以使用非dos命令,甚至可以使用不具有可执行特性的普通数据性文件,这缘于windows系统这个新型解释平台的涉入,使得批处理的应用越来越边缘化。所以我们讨论的批处理应该限定在dos环境或者命令行环境中,否则很多观念和设定都需要做比较大的变动。 = 其次,批处理文件是一种简单的程序,可以通过条件语句(if)和流程控制语句(goto)来控制命令运行的流程,在批处理中也可以使用循环语句(for)来循环执行一条命令。当然,批处理文件的编程能力与C语言等编程语句比起来是十分有限的,也是十分不规范的。批处理的程序语句就是一条条的DOS命令(包括内部命令和外部

26、命令),而批处理的能力主要取决于你所使用的命令。 = 注 = 批处理文件(batch file)也可以称之为批处理程序(batch program),这一点与编译型语言有所不同,就c语言来说,扩展名为c或者cpp的文件可以称之为c语言文件或者c语言源代码,但只有编译连接后的exe文件才可以称之为c语言程序。因为批处理文件本身既具有文本的可读性,又具有程序的可执行性,这些称谓的界限是比较模糊的。 = 第三,每个编写好的批处理文件都相当于一个DOS的外部命令,你可以把它所在的目录放到你的DOS搜索路径(path)中来使得它可以在任意位置运行。一个良好的习惯是在硬盘上建立一个bat或者batch目录

27、(例如C:BATCH),然后将所有你编写的批处理文件放到该目录中,这样只要在path中设置上c:batch,你就可以在任意位置运行所有你编写的批处理程序。 = 注 = 纯以dos系统而言,可执行程序大约可以细分为五类,依照执行优先级由高到低排列分别是:DOSKEY宏命令(预先驻留内存),COMMAND.COM中的内部命令(根据内存的环境随时进驻内存),以com为扩展名的可执行程序(由 直接载入内存),以exe位扩展名的可执行程序(由 重定位后载入内存),以bat位扩展名的批处理程序(由 解释分析,根据其内容按优先级顺序调用第2,3,4,5种可执行程序,分析一行,执行一行,文件本身不载入内存)

28、= 第四,在DOS和Win9x/Me系统下,C:盘根目录下的AUTOEXEC.BAT批处理文件是自动运行批处理文件,每次系统启动时会自动运行该文件,你可以将系统每次启动时都要运行的命令放入该文件中,例如设置搜索路径,调入鼠标驱动和磁盘缓存,设置系统环境变量等。下面是一个运行于Windows 98下的autoexec.bat的示例: ECHO OFF PATH C:WINDOWS;C:WINDOWSCOMMAND;C:UCDOS;C:DOSTools; C:SYSTOOLS;C:WINTOOLS;C:BATCH LH SMARTDRV.EXE /X LH DOSKEY.COM /insert L

29、H CTMOUSE.EXE SET TEMP=D:TEMP SET TMP=D:TEMP = 注 = AUTOEXEC.BAT为DOS系统的自动运行批处理文件,由COMMAND.COM启动时解释执行; 而在Win9x环境中,不仅增加支持了 DOSSTART.BAT, WINSTART.BAT 等许多其它自动运行的批处理文件,对AUTOEXEC.BAT 也增加了 .DOS .W40 .BAK .OLD .PWS 等许多变体以适应复杂的环境和多变的需求。 = willsort 编注 = 以下关于命令的分类,有很多值得推敲的地方。常用命令中的本不是命令,而dir、copy等也很常用的命令却没有列入,

30、 而特殊命令中所有命令对我来说都是常用命令。建议将批处理所引用的命令分为内部命令、外部命令、第三方程序三类。而内部命令和外部命令中别有一类是专用于或常用于批处理中的命令可称之为批处理命令。 以下摘录MS-DOS 6.22 帮助文档中关于批处理命令的文字,当然,其中有些概念和定义已经有些落后了。 批处理命令 批处理文件或批处理程序是一个包含若干MS-DOS命令的正文文件,扩展名为.BAT。当在命令提示符下敲入批处理程序的名称时,MS-DOS成组执行此批处理程序中的命令。 任何在命令提示符下可使用的命令都可用在批处理程序中。此外,下面MS-DOS命令是专门在批处理程序中使用的。 = 常用命令 ec

31、ho、call、pause、rem(小技巧:用:代替rem)是批处理文件最常用的几个命令,我们就从他们开始学起。 = 注 = 首先, 不是一个命令, 而是DOS 批处理的一个特殊标记符, 仅用于屏蔽命令行回显. 下面是DOS命令行或批处理中可能会见到的一些特殊标记符: CR(0D) 命令行结束符 Escape(1B) ANSI转义字符引导符 Space(20) 常用的参数界定符 Tab(09) ; = 不常用的参数界定符 + COPY命令文件连接符 * ? 文件通配符 字符串界定符 | 命令管道符 文件重定向符 命令行回显屏蔽符 / 参数开关引导符 : 批处理标签引导符 % 批处理变量引导符

32、其次, : 确实可以起到rem 的注释作用, 而且更简洁有效; 但有两点需要注意: 第一, 除了 : 之外, 任何以 :开头的字符行, 在批处理中都被视作标号, 而直接忽略其后的所有内容, 只是为了与正常的标号相区别, 建议使用 goto 所无法识别的标号, 即在 :后紧跟一个非字母数字的一个特殊符号. 第二, 与rem 不同的是, :后的字符行在执行时不会回显, 无论是否用echo on打开命令行回显状态, 因为命令解释器不认为他是一个有效的命令行, 就此点来看, rem 在某些场合下将比 : 更为适用; 另外, rem 可以用于 config.sys 文件中. = echo 表示显示此命令

33、后的字符 echo off 表示在此语句后所有运行的命令都不显示命令行本身 与echo off相象,但它是加在每个命令行的最前面,表示运行时不显示这一行的命令行(只能影响当前行)。 call 调用另一个批处理文件(如果不用call而直接调用别的批处理文件,那么执行完那个批处理文件后将无法返回当前文件并执行当前文件的后续命令)。 pause 运行此句会暂停批处理的执行并在屏幕上显示Press any key to continue.的提示,等待用户按任意键后继续 rem 表示此命令后的字符为解释行(注释),不执行,只是给自己今后参考用的(相当于程序中的注释)。 = 注 = 此处的描述较为混乱,

34、不如直接引用个命令的命令行帮助更为条理 - ECHO 当程序运行时,显示或隐藏批处理程序中的正文。也可用于允许或禁止命令的回显。 在运行批处理程序时,MS-DOS一般在屏幕上显示(回显)批处理程序中的命令。 使用ECHO命令可关闭此功能。 语法 ECHO ON|OFF 若要用echo命令显示一条命令,可用下述语法: echo message 参数 ON|OFF 指定是否允许命令的回显。若要显示当前的ECHO的设置,可使用不带参数的ECHO 命令。 message 指定让MS-DOS在屏幕上显示的正文。 - CALL 从一个批处理程序中调用另一个批处理程序,而不会引起第一个批处理的中止。 语法

35、CALL drive:pathfilename batch-parameters 参数 drive:pathfilename 指定要调用的批处理程序的名字及其存放处。文件名必须用.BAT作扩展名。 batch-parameters 指定批处理程序所需的命令行信息。 - PAUSE 暂停批处理程序的执行并显示一条消息,提示用户按任意键继续执行。只能在批处 理程序中使用该命令。 语法 PAUSE REM 在批处理文件或CONFIG.SYS中加入注解。也可用REM命令来屏蔽命令(在CONFIG.SYS 中也可以用分号 ; 代替REM命令,但在批处理文件中则不能替代)。 语法 REM string 参

36、数 string 指定要屏蔽的命令或要包含的注解。 = 例1:用edit编辑a.bat文件,输入下列内容后存盘为c:a.bat,执行该批处理文件后可实现:将根目录中所有文件写入 a.txt中,启动UCDOS,进入WPS等功能。 批处理文件的内容为: 命令注释: echo off 不显示后续命令行及当前命令行 dir c:*.* a.txt 将c盘文件列表写入a.txt call c:ucdosucdos.bat 调用ucdos echo 你好 显示你好 pause 暂停,等待按键继续 rem 准备运行wps 注释:准备运行wps cd ucdos 进入ucdos目录 wps 运行wps 批处理文件的参数 批处理文件还可以像C语言的函数一样使用参数(相当于DOS命令的命令行参数),这需要用到一个参数表示符%。 %

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 期刊短文 > 互联网

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁