.net文件的压缩方法和装置的制作方法

文档序号:6585467阅读:206来源:国知局

专利名称::.net文件的压缩方法和装置的制作方法
技术领域
:本发明涉及计算机应用领域,具体而言,涉及一种.net文件的压縮方法和装置。
背景技术
:.Net是微软的新一代技术平台,是全新的基于互联网的跨语言软件开发平台,顺应了当今软件工业分布式计算、面向组件、企业级应用、软件服务化和以Web为中心等大趋势。.Net并非开发语言,但是在.Net开发平台上可以支持多种开发语言,如C#语言丄++、VisualBasic、Jscript等。智能卡是一种大小和普通名片相仿的塑料卡片,内含一块直径lcm左右的硅芯片,具有存储信息和进行复杂运算的功能。它被广泛地应用于电话卡、金融卡、身份识别卡以及移动电话、付费电视等领域。其中,智能卡的芯片上集成了微处理器、存储器以及输入/输出单元等,使得智能卡被认为是世界上最小的电子计算机。并且在智能卡上拥有一整套性能较强的安全保密控制机制,安全控制程序被固化在只读存储器中,因而具有无法复制密码等可靠的安全保证。智能卡与普通磁卡相比,还具有信息存储容量大,可利用微处理器来增加卡片功能等优点。.Net卡是一种含有可以运行.Net程序的.Net卡虚拟机的微处理器智能卡。所谓虚拟机,是指可以把它想象成一台用软件来模拟的机器,在这台机器里有处理器、内存、寄存器等各种硬件,模拟运行各种指令,在这台机器上运行的软件对运行环境没有特殊要求,所以虚拟机对在它上运行的程序来说是透明的。例如,x86虚拟机模拟的是x86指令程序的运行环境,c51虚拟机模拟的是c51指令程序的运行环境。.net程序包括命名空间、引用类型、定义类型、定义方法、引用方法、ILcode(IntermediateLanguagecode,中间语言代码)等,系统通过运行ILcode中的指令运行.net程序,即通过将各种语言先编译成ILcode,然后在执行时用即时编译器将ILcode编译成本地平台代码后运行.net程序。在.net文件中对定义方法信息进行存储时,以每一个自定义方法的方法头和方法体为一个数据块进行存储,方法头后紧跟的数据为方法体,方法头为对方法体的描述,方法头中包括标识、局部变量token等信息,方法体包括ILcode,其中在ILcode中的操作参数中又包括局部变量信息。但是目前的智能卡由于体积和存储芯片的限制,其存储空间仍然有限,随着软件的发展,部分功能大的程序占用存储空间较大,对于很多的.net程序并不能进行存储和运行。综上所述,相关技术中的.net程序压縮效果较差,不能很好地在小容量的存储介质(例如智能卡)上存储和运行,且针对该问题目前尚未提出有效的解决方案。
发明内容针对.net程序不能很好地在小容量的存储介质(例如智能卡)上存储和运行而4提出本发明,为此,本发明的主要目的在于提供一种.net文件的压縮方法和装置,以解决上述问题至少之一。为了实现上述目的,根据本发明的一个方面,提供了一种.net文件的压縮方法。根据本发明的.net文件的压縮方法包括获取.net文件中使用的定义方法的方法头;压縮所述定义方法中的方法体,得到所述方法体的压縮结果。优选的,所述压縮所述方法中的方法体的步骤包括根据所述方法头获取所述定义方法的局部变量,并根据所述局部变量的类型确定所述局部变量的偏移,所述局部变量的偏移指所述局部变量在所述.net文件对应的压縮结构中的偏移;根据所述方法头读取该定义方法的ILcode,并对所述ILcode进行压縮,计算压縮后的ILcode的长度;按照预先确定的格式对所述压縮后的ILcode的长度、所述局部变量的偏移和压縮后的ILcode进行组合,得到所述方法体的压縮结果。为了实现上述目的,根据本发明的另一方面,提供了一种.net文件的压縮装置,所述装置包括方法获取模块,用于获取.net文件中使用的定义方法的方法头,并根据所述方法头获取该定义方法的ILcode;压縮模块,用于压縮所述定义方法中的方法体,得到所述方法体的压縮结果。优选的,所述压縮模块包括局部变量偏移确定单元,用于根据所述方法获取模块获取的方法头获取所述定义方法的局部变量,并根据所述局部变量的类型确定所述局部变量的偏移,所述局部变量的偏移指所述局部变量在所述.net文件对应的压縮结构中的偏移;指令压縮与计算单元,用于对所述方法获取模块获取的ILcode进行压縮,并计算压縮后的ILcode的长度;组合单元,用于按照预先确定的格式对所述指令压縮与计算单元计算出的压縮后的ILcode的长度、所述局部变量偏移确定单元确定的局部变量的偏移和所述指令压縮与计算单元压縮后的ILcode进行组合,得到所述方法体的压縮结果。本发明采用对.net文件中定义方法中的方法体进行压縮,可以有效地降低.net文件占用的存储空间,使.net文件可以在小容量存储介质(例如智能卡)上存储并运行,进而增强了小容量存储介质(例如智能卡)的功能。此处所说明的附图用来提供对本发明的进一步理解,构成本申请的一部分,本发明的示意性实施例及其说明用于解释本发明,并不构成对本发明的不当限定。在附图中图1是本发明实施例1提供的.net文件的压縮装置的结构框图;图2是本发明实施例2提供的.net文件的压縮装置的结构框图;图3是本发明实施例3提供的.net文件的压縮方法流程图;图4是本发明实施例4提供的.net文件的压縮方法流程5图5是本发明实施例5提供的.net文件的压縮方法的流程图;图6是本发明实施例5提供的.net文件的结构示意图;图7是本发明实施例5提供的获取方法头的方法流程图图8是本发明实施例5提供的大头方法的数据格式示意图;图9是本发明实施例5提供的小头方法的数据格式示意图;图10是本发明实施例5提供的对ILcode进行压縮的方法流程图。具体实施例方式下文中将参考附图并结合实施例来详细说明本发明。需要说明的是,在不冲突的情况下,本申请中的实施例及实施例中的特征可以相互组合。下面结合附图对技术方案的实施作进一步的详细描述实施例1本实施例提供了一种.net文件的压縮装置,如图1所示,该装置包括方法获取模块102,用于获取.net文件中使用的定义方法的方法头;该方法头可以通过先读取元数据表MethodDef中的信息得到方法头的位置信息,例如RVA(RelativeVirtualAddress,相对虚拟地址),根据该位置信息得到该方法头的数据,并通过该方法头中记录的ILcode的长度读取该方法头后记录的ILcode;压縮模块104,用于压縮方法获取模块102获取的ILcode,通过压縮ILcode对方法体进行压縮,得到方法体的压縮结果。本实施例通过对.net文件的定义方法中的方法体进行压縮,可以有效地降低.net文件占用的存储空间,使.net文件可以在小容量存储介质(例如智能卡)上存储并运行,进而增强了小容量存储介质(例如智能卡)的功能。实施例2本实施例提供了一种.net文件的压縮装置,如图2所示,该装置包括方法获取模块102和压縮模块104,其中,压縮模块104包括局部变量偏移确定单元1042、指令压縮与计算单元1044和组合单元1046,其中,各模块的功能如下方法获取模块102,用于获取.net文件中使用的定义方法的方法头,并根据该方法头获取该定义方法对应的ILcode;方法头的具体获取方式和实施例1相同,这里不再详述。压縮模块104,用于压縮方法获取模块102获取的ILcode,通过压縮ILcode对方法体进行压縮,得到方法体的压縮结果。压縮模块104具体包括局部变量偏移确定单元1042,用于根据方法获取模块102获取的方法头获取该定义方法的局部变量,并根据此局部变量的类型确定局部变量的偏移,其中,局部变量的偏移指局部变量在上述.net文件对应的压縮结构中的偏移;当定义方法为小头方法(TinyHeaders)时,该定义方法中不存在局部变量,此时,获取的局部变量为空,对应的局部变量的偏移也为空,当定义方法为大头方法(FatHeaders)时,该定义方法中存在局部变量,此时,获取该局部变量,并确定该局部变量在压縮结构中的偏移;具体判断该定义方法是否为小头方法的依据是读取上述方法头的第一个字节,根据上述第一个字节判断定义方法是大头方法还是小头方法,当所读取的第一个字节的低两位为10时,该定义方法为小头方法,否则该定义方法为大头方法;指令压縮与计算单元1044,用于对方法获取模块102获取的ILcode进行压縮,计算压縮后的ILcode的长度;本实施例提到的ILcode包括操作指令和操作参数,其中,操作参数可以为空,也可以为标识token、指向局部变量在该方法体中的偏移或者为跳转的偏移量,对ILcode进行压縮时,可以根据具体的ILcode确定压縮方式,例如对于ILcode中的操作指令不带操作参数的情况,可以直接记录该操作指令;对于带操作参数的操作指令,可以针对以下三种情况分别处理(1)当操作参数为跳转的偏移量(即,该操作指令为跳转指令)时,根据跳转的偏移量确定被跳过的ILcode部分,根据被跳过的ILcode部分重新计算此操作指令(S卩,上述跳转指令)跳转的偏移量,记录此操作指令和重新计算出的跳转偏移量;例如该ILcode中有10个操作指令,其中,第3个操作指令为跳转指令,其操作参数为2,即指向后跳转两个字节,假如跳转两个字节后为跳转到第5个操作指令处,此时被跳过的ILcode部分就是第4个操作指令和它的操作参数,按照本实施例的方法,需要先对被跳过的ILcode部分进行压縮,根据压縮后的被跳过的ILcode部分的长度重新修改第3个操作指令的操作参数,将原来的跳转偏移量修改为压縮后的被跳过的ILcode部分的长度。进而实现ILcode中全部操作指令和操作参数均压縮后,不改变原来ILcode的含义。(2)当操作参数为指向局部变量在该方法体中的偏移量时,记录该操作指令和操作参数;(3)当操作参数为标识token时,确定该标识token在上述压縮结构中对应的偏移量,并记录该操作指令和确定的偏移量。上述记录的内容即为IL指令的压縮结果。组合单元1046,用于按照预先确定的格式对指令压縮与计算单元1044计算出的压縮后的ILcode的长度、局部变量偏移确定单元1042确定的局部变量的偏移和指令压縮与计算单元1044压縮后的ILcode进行组合,得到方法体的压縮结果。优选的,预先确定的格式为将计算出的压縮后的ILcode的长度、局部变量的偏移和压縮后的ILcode依次排列的格式,也可以任意改变这三部分的前后位置。本实施例提到的.net文件对应的压縮结构指.net文件中的数据是按顺序排列的,每行数据的偏移与该行数据的标识token相对应,例如命名空间中排列在第一行的数据的偏移为O,对应的token为O,排列在第二行的数据的偏移为l,对应的token为l,依次类推,为.net文件的压縮结构;需要说明的是,在类型、方法、字段这三种数据中,存在引用和定义两种类型的数据,引用的数据在压縮结构中排在定义数据前,并且定义数据的token也排在引用数据后,偏移应与token相对应,优选地,该偏移为一个字节,例如,引用类型已经存在6个,分别排在偏移为0-5的位置,那么定义类型模块中排列的第一个定义类型的token应该为6,偏移也为6。例如,.net文件的源代码如下publicStringMyS卿leMethod()StringstrHello=〃HelloWorld!〃if(strHello!=null)strHello+=〃Y〃;returnstrHello+callCount.ToStringO转换后的压縮结构为命名空间Namespace:0)01005E5F87001)010035F47B002)0100A17EC3003)070000F64D00A)0200ACE6EB00用类型TypeRef:(0)F55B01000000(1)D9F801000000(2)CB0F01000000(3)81CE00000000(4)271101000000(5)272200000000(6)497001000000(7)C06101000000(8)A1FA01000000(9)306401000000引用方法MethodRef0)E8CB1)CE722)90803)39734)90805)6A4D6)6AF27)9080引用字段FieldRef:Blob:8(O)ODOO(1)0100(2)0D00定义类型TypeDef:-----------------------------(A)A709140009000200定义方法MethodDef:-----------------------------(8)DFEE000600040104(9)9080020600000103上述数据中,每行数据第一个小括号里为该行数据的偏移,后面为该行具体数据。例如,在命名空间Namespace中,每一行数据记录一个命名空间信息,第一行数据(0)0100D93DEB00,其中,小括号中的0为该命名空间的偏移,该偏移并不是实际存在的,0100D93DEB00为该命名空间的具体信息,其他数据的结构与此行数据类似。上述数据仅为.net文件压縮结构的一部分,仅是为了说明.net文件中的标识token与压縮结构中偏移的对应关系。本实施例通过指令压縮与计算单元1044对ILcode进行压縮并计算压縮后的ILcode的长度,由组合单元1046组合压縮后的ILcode,压縮后的ILcode的长度以及局部变量的偏移作为方法体的压縮结果,可以有效地降低.net文件占用的存储空间,使.net文件可以在小容量存储介质(例如智能卡)上存储并运行,进而增强了小容量存储介质(例如智能卡)的功能。实施例3本实施例提供了一种.net文件的压縮方法,该方法以使用实施例l提供的压縮装置实现为例进行说明,如图3所示,该方法包括步骤S20:方法获取模块102获取.net文件中使用的定义方法的方法头,并根据该方法头获取该定义方法的ILcode;步骤S30:压縮模块104压縮上述方法中的ILcode,通过压縮ILcode压縮方法体,并得到方法体的压縮结果。本实施例通过对.net文件的定义方法中的方法体进行压縮,可以有效地降低.net文件占用的存储空间,使.net文件可以在小容量存储介质(例如智能卡)上存储并运行,进而增强了小容量存储介质(例如智能卡)的功能。实施例4本实施例提供了一种.net文件的压縮方法,该方法以使用实施例2提供的压縮装置实现为例进行说明,如图4所示,该方法包括步骤S202:方法获取模块102获取.net文件中使用的定义方法的方法头,并根据该方法头获取该定义方法的ILcode;在经过.net平台编译的.net文件中包括命名空间(Namespace)、引用类型(TypeRef)、定义类型(TypeDef)、定义方法(MethodDef)、字符串等,并以表和流的形式进行存储,在对.net文件中的IL进行压縮前,可以先将.net文件的结构变换为压縮结构,本9实施例中的压縮结构与实施例1中的压縮结构一样,这里不再赘述。IL包括操作指令和操作参数,操作参数可以为空,也可以为标识token、指向局部变量的偏移或者为跳转的偏移量。其中,标识token的前半部分指明了此操作指令对应的表,后半部分指明了为该表的第几行数据。获取方法头的具体实现可以是先获取.net文件中的元数据表MethodDef;从元数据表MethodDef中读取.net文件中使用的定义方法的地址信息;根据该地址信息读取该定义方法的方法头。根据方法头读取ILcode的步骤包括根据方法头中的信息确定ILcode的长度;根据确定的ILcode的长度读取ILcode。当该定义方法为大头方法时,方法头中的第5_8字节为该方法对应的IL的长度,第9-12字节为该方法中局部变量的标识token;当该定义方法为小头方法时,方法头中的高6位为ILcode的长度。步骤S204:局部变量偏移确定单元1042根据上述方法头获取该定义方法的局部变量,并根据该局部变量的类型确定该局部变量的偏移,其中,局部变量的偏移指该局部变量在.net文件对应的压縮结构中的偏移;因为小头方法中不存在局部变量,此时,获取的局部变量为空,对应的局部变量的偏移也为空,判断该定义方法为小头方法还是大头方法,判断的依据可以采用实施例1中的方法实现,这里不再详述。步骤S206:指令压縮与计算单元1044对读取的ILcode进行压縮,计算压縮后的ILcode的长度;对ILcode进行压縮时,可以根据具体的ILcode确定压縮方式,具体压縮方式可以参见实施例2中的ILcode的压縮方法实现,这里不再详述。优选的,当读取并压縮完一条操作指令后,判断该ILcode中所有的操作指令和操作参数是否都被读取并压縮,如果是,执行计算压縮后的IL的长度;否则,读取下一条操作指令并进行压縮。步骤S208:组合单元1046按照预先确定的格式对压縮后的ILcode的长度、上述局部变量的偏移和压縮后的ILcode进行组合,得到IL的压縮结果。优选的,预先确定的格式为将计算出的压縮后的ILcode的长度、局部变量的偏移和压縮后的ILcode依次排列的格式,也可以任意改变这三部分的前后位置。优选的,本实施例提供的压縮方法还可以包括判断是否上述.net文件中使用的所有定义方法的方法头都已经被读取并完成IL压縮,如果不是,继续读取下一个定义方法的方法头,并执行步骤S202-S208;否则,结束压縮。本实施例通过对ILcode进行压縮并计算压縮后的ILcode的长度,组合压縮后的ILcode,压縮后的ILcode的长度以及局部变量的偏移作为方法体的压縮结果,可以有效地降低.net文件占用的存储空间,使.net文件可以在小容量存储介质(例如智能卡)上存储并运行,进而增强了小容量存储介质(例如智能卡)的功能。实施例5本实施例提供了一种.net文件的压縮方法,如图5所示,该方法包括步骤S302:获取定义方法元数据表MethodDef;在.net文件中包含有多个表,其中定义方法元数据表MethodDef中记录了.net文件中各个定义方法的方法头的位置信息;本实施例以将下面的代码编译后得到的.net文件为例,说明获取其元数据表MethodDef的方法publicStringMyS卿leMethod(){StringstrHello=〃HelloWorld!〃;if(strHello!=null)strHello+=〃Y〃;returnstrHello+callCoimt.ToString();}对上述代码使用.net平台编译后得到helloworld.exe文件,并以二进制的形式存储在硬盘上,该二进制文件为.net文件,如图6所示,为本实施例提供的.net文件的结构示意图,该文件包括Dos头、PE特征以及元数据(MetaData),元数据中包括元数据头(MetaDataHeader)、元数据表(tables)等。读取元数据表MethodDef的过程如下a.定位.net文件Dos头,本实施例得到的Dos头为0x5a4d;b.从dos头后跳过第一约定个字节,读出PE特征的偏移地址,得到PE特征的偏移地址0x00000080;在本实施例中,第一约定个字节为0x003a个字节;c.根据PE特征偏移地址0x00000080定位PE特征,定位得到PE特征0x4550;d.在PE特征向后第二约定个字节处读取四个字节,在本实施例中,以32位机为例进行说明,第二约定个字节为从PE特征向后偏移0x0074字节后,读出4个字节的数据为0x00000010,此值说明该二进制文件中存在0x10个目录且包含.net数据;其中,.net文件的元数据头相对虚拟地址写在上述第0x0F个目录中,在64位机中第二约定个字节为0x0084个字节;e.从上述数据0x00000010,向后偏移第三约定个字节后读取八个字节数据,在本实施例中,优选地,第三约定个字节为112个字节,在此八个字节数据中,前四个字节为0x00002008,为.net数据头的相对虚拟地址,后四个字节为0x00000048,为.net数据头的长度;f.根据.net数据头的相对虚拟地址得到线性地址0x00000208,并读取.net数据头得到如下数据48000000020005008C210000A0090000090000000500000600000000000000005020000080000000000000000000000000需要说明的是,上述数据采用小端的存储方式,例如,上述数据前4个字节0x48000000为该数据的长度,转换成大端的存储方式为0x0000048;在本实施例中,线性地址为.net数据在.net文件中的地址,相对虚拟地址为相对于PE载入点的内存偏移,线性地址和相对虚拟地址的转换关系为线性地址=相对虚拟地址_节相对虚拟地址+节的文件偏移,在本实施例中,读取.net文件中.net数据目录的节的相对虚拟地址为0x00002000,节的文件偏移为0x00000200,则线性地址=0x00002008-0x00002000+0x00000200=0x00000208;g.由.net数据头向后偏移第四约定个字节处读取八个字节数据,在本实施例中第四约定个字节为从.net数据头向后偏移8个字节后,读取共8个字节,在这8个字节中,前四个字节为0x0000218c,为元数据头(MetaDataHeader)的相对虚拟地址,后四个字节为0x000009a0,为元数据的长度;h.将元数据头的相对虚拟地址0x0000218c转换得到线性地址0x0000038c,根据线性地址和元数据长度,得到元数据内容;i.由元数据头向后读取,当读取到标志"#"时,读取标志"#"前的八个字节,其中前四个字节为"#"的地址,通过该地址得到"#"流,在"#"流中第五约定个字节开始读取长度为8个字节的数据,即0x0000000920021c57,其二进制形式为100100100000000000100001110001010111;在本实施例中,第五约定个字节为"#"流中起始位开始算起第9个字节;i.根据步骤i中得到的二进制数据,从低位开始读取,例如,第1位代表元数据表Module是否存在,如果是1则证明存在元数据表Module,如果是0证明不存在,在本实施例中,存在元数据表Module,并且第2位为1,表示元数据表TypeRef存在,按此规律以位为单位由低位读向高位,第7位为l,表示元数据表MethodDef存在;其中,在步骤i中所得到的数据中,从低位开始,每一位代表.net文件中是否存在对应的表;k.在数据0x0000000920021c57后偏移第六约定个字节读取元数据表MethodDef的数据行数,在本实施例中第六约定个字节为24个字节,具体的为向后偏移24个字节后读取4个字节,得到数据0x00000002,判断得出元数据表MethodDef中存在2个数据行;其中,在元数据中,数据0x0000000900021C57向后偏移8个字节后的数据中以每4个字节为一个单位依次存储了在.net文件中存在的元数据表的数据行数,在表示数据行数的数据后,依次存储了每个元数据表的具体内容,为元数据表区域。在本实施例中,元数据表MethodDef前存在4个元数据表,因此在数据0x0000000900021C57后偏移8+4*4=24个字节后读取元数据表MethodDef的数据行数,上述为第六约定个字节的计算方法;1.根据约定的方法读取元数据表MethodDef的具体内容;其中,约定的方法如下,以本实施例中的.net文件为例进行说明,由步骤K中所述的方法,可得到元数据表MethodDef前的五个表中共存在28个数据行,其中元数据表Module包括数据行1行,元数据表TypeRef包括数据行23行,元数据表TypeDef包括数据行3行,元数据表Field包括数据行1个,其中,元数据表Module的数据行每行为10个字节,元数据表TypeRef的数据行每行为6个字节,元数据表TypeDef的数据行每行为为14个字节,元数据表Field的数据行每行为6个字节,因此元数据表MethodDef在元数据表区域的偏移为1*10+23*6+3*14+1*6=196个字节,元数据表MethodDef的数据行为2行,每行数据为14个字节,因此元数据表MethodDef的数据长度为2*14=28个字节;元数据表MethodDef的数据如下0C21000000008600890030000100472100000000861883002C000100其中,每行数据表示一个定义方法对应的信息,每行数据的前四个字节为该定义方法的方法头的相对虚拟地址RVA,为便于说明,将上述数据以列表的形式表示,参见表1:表l<table>tableseeoriginaldocumentpage13</column></row><table>表1中的数据使用的是大端的表示方法,例如第一个数据行的数据为0C21000000008600890030000100,对应的小端表示方法为0000210C00000086008900300001:步骤S304:读取定义方法中的方法头,根据方法头中的信息获取局部变量信息;在本实施例中以元数据表MethodDef中第一个定义方法为例进行说明,参见图7,为本实施例提供的获取定义方法中的方法头的方法流程图,包括步骤S304a:获取定义方法的方法头的地址,并读取方法头的第一个字节;根据步骤S302中得到的元数据表MethodDef中的数据,第一个定义方法的方法头的RVA为0x0000210C,由RVA转换得到线性地址为0x0000030C,根据地址0x0000030C在.net文件中读取数据,读取数据字节长度为一个字节;在本实施例中,读取得到的第一个字节为0x13;步骤S304b:判断该定义方法是大头方法还是小头方法,如果是大头方法,执行步骤S304d,如果是小头方法,执行步骤S304c;其中,判断该定义方法为大头方法还是小头方法的方法和实施例1、实施例2相同,这里不再详述。例如,在本实施例中,将步骤S304a中获得的数据0x13以二进制形式表示为00010011,最低两位为ll,为大头方法。步骤S304c:该定义方法为小头方法,不存在局部变量,将局部变量置为空,并获取完整的定义方法头信息和与该方法对应的ILcode;步骤S304d:获取完整的定义方法头信息和与该方法对应的ILcode,并获得局部变量token;参见图8,为本实施例提供的大头方法的数据格式示意图,由图8可知,大头方法标识由12个字节组成,前两个字节为标识信息,对应着图中的Flags项;之后的两个字节为最大栈大小信息,对应着图中的MaxStack项;再后的4个字节为与该方法对应的ILcode大小信息,对应着图中的CodeSize项;最后4个字节为局部变量token,对应着图中的LocalVariablesSignatureToken项。分析大头方法标识中的局部变量token的数据,如果该数据为O,则表明局部变量个数为0;否则,根据该值定位到元数据表的StandAloneSig表(独立特征描述符表,该表具有作为方法局部变量的复合特征),从该表中的Value项的内容读取到数据项签名的偏移,并读取局部变量个数;由大头方法的格式可知,方法头信息第5-8字节为ILcode长度,第9_12字节为局部变量token,局部变量token后为ILcode,本实施例中为0x11000002,局部变量token使用的是大端的表示方法。在本实施例中,获取方法头,并根据方法头获取与该方法对应的ILcode如下0281200000A0A061201281300000A281200000A0C2B00082A参见图9,为本实施例提供的小头方法的数据格式示意图,由图9可知,小头方法的方法头的高6位为ILcode的长度,低2位为说明其为小头方法的标识位。步骤S304e:根据局部变量token获取局部变量,根据局部变量的类型确定该局部变量在.net文件的压縮结构中的偏移;获取局部变量方法为根据局部变量token定位元数据表StandAloneSig的数据行,该表中记录了定义方法的局部变量信息在Blob流中的偏移,根据该偏移读取局部变量的信息;在本实施例中,局部变量token为0xll000002,0x11说明指向序号为0x11的元数据表,即元数据表StandAloneSig,0x000002为该表第二行数据,则该定义方法的局部变量对应元数据表StandAloneSig的第二行数据,得到的数据为0x0100,0x0100为局部变量在Blob流中的偏移,根据该偏移在Blob流中读取局部变量信息为0x0607040E080E02,其中,0x06表示局部变量信息的长度,0x07为局部变量标识,0x04表示局部变量的长度,0x0E表示局部变量的类型且局部变量类型为String,类型String为引用类型,根据.net的压縮结构可知,以String在引用类型TypeRef中的偏移为0x04为例进行说明,则将.net文件中存储该定义方法的局部变量替换为0x04,同理,08为引用类型Int,在.net文件的压縮结构中偏移为0x07,02为引用类型Boolean,在.net文件的压縮结构中偏移为0x05,在该定义方法中存在两个OxOE,说明该定义方法中存在两个为类型String的局部变量。其中,Blob流的定位方法如下压縮程序定位Blob流的位置,在步骤S302中的步骤h中获得元数据头的地址0x0000038c后,从元数据头开始向后读取,当发现标记"ftBlob"后,读取"ftBlob"的前8个字节,得到数据0x2006000098010000,其中高4个字节为Blob流相对于元数据头的偏移,低4个字节为Blob流的长度,高4个字节转换成大端的表示方式为0x00000620,低4个字节转换成大端的表示方式为0x00000198;压縮程序根据元数据头的地址0x0000038c,向后偏移0x00000620得到Blob流的数据区域;步骤S306:读取ILcode,并对ILcode进行压縮;在本实施例中,步骤S304d获取的上述定义方法的方法头和ILcode信息如下0281200000A0A061201281300000A281200000A0C2B00082A其中,局部变量tokenOxl1000002后为ILcode,第5-8字节数据0x0000002F表示ILcode的长度,确定ILcode为:140000A281200000A0C2B00082A.net文件中的IL包括一个或多个操作指令和操作参数,其中包括两种组合形式,一种为"操作指令opCOde+操作参数"的形式,另一种只有操作指令。其中,操作参数主要包括三种操作对象的token、偏移或指向局部变量在本方法ILcode中的偏移,一般情况下,跳转指令后的操作参数为偏移,指向局部变量在本方法ILcode中的偏移为局部变量在本定义方法中的局部变量中的序号。参见图10,为本实施例对ILcode进行压縮的方法流程图,对上述IL指令进行压縮的方法如下步骤S306a:获取ILcode中的操作指令;步骤S306b:判断该操作指令后是否有操作参数,如果没有,执行步骤S306c,如果有,执行步骤S306d;步骤S306c:直接记录该操作指令,执行步骤S306h;步骤S306d:根据操作指令判断其后的操作参数类型,如果操作参数为跳转偏移量,执行步骤S306e,如果操作参数为指向局部变量在其所属方法中的偏移量,执行步骤S306f,如果操作参数为token,执行步骤S306g;步骤S306e:重新计算操作指令的偏移,替换原有的偏移,执行步骤S306h;在实施例中,跳转指令后的操作参数为跳转偏移量,并且在本实施例中因对ILcode进行了压縮,导致了数据位置的改变,因此需重新计算偏移,替换原有偏移;例如,在本实施例所提供的ILcode中,存在一个跳转操作0x2B00,其中0x2B为跳转指令,OxOO为偏移,表示跳转到0x00后,在对本实施例所提供的ILcode压縮后,计算得知偏移仍为0x00,因此该ILcode压縮后仍为0x2B00;在本实施例中的另一个跳转操作0x2D0C,其中,0x2D为跳转操作,OxOC为跳转偏移,表示跳转到数据OxOC后12个字节的后面,即将ILcode部分0x0C067239000070281200000A0A跳过,在将该被跳转的ILcode部分压縮后,本实施例中ILcode0x0C067239000070281200000A0A被压縮为06720128030A,为6个字节,因此操作指令0x2D后的偏移应被重新计算为0x06,ILcode:0x2D0C被压縮为0x2D06;步骤S306f:记录该操作指令和操作参数,执行步骤S306h;在本歩骤中,说明一种特殊情况,操作指令0x0a、0x0b、0x0c、0x0d也为指向局部变量的操作指令,但是该操作指令本身已经指明局部变量偏移,操作指令OxOa指向该指令所属的方法的第一个局部变量,操作指令OxOb指向该指令所属的方法的第二个局部变量,操作指令OxOc指向该指令所属的方法的第三个局部变量,操作指令OxOd指向该指令所属的方法的第4个局部变量,因此,这些指令后没有操作参数,按照步骤S306c操作即可;当定义方法中的局部变量大于4个时,直接记录原操作指令和操作参数,例如ILcode:0xll04,操作指令Oxll指向该方法中第5个局部变量,压縮时对类似ILcode直接记录;需要说明的是,在步骤S306d和步骤S306f中,指向局部变量的偏移量中的偏移量指的是该局部变量在其所属的定义方法中所包括的所有局部变量中的排列序号;步骤S306g:记录该操作指令,并将操作参数中的token替换为压縮结构中的偏移,执行步骤S306h;本步骤具体为,将操作参数中指向具体数据的token替换为偏移,在.net文件中,token为四个字节,高一个字节记录所指向的元数据表,低三个字节标明了指向元数据表的例如,在本实施例中的ILcode:0x721D00007,转换成大端表示方法为0x721D00007,0x72为操作指令,0xlD00007为所指向数据的token,分析可知,高一个字节OxlD为元数据表序号,指向元数据表FieldRVA,0x000007为行数,应为第7行,则该IL指令指向.net文件中元数据表FieldRVA第7行数据,根据.net文件的压縮结构判断该行数据的偏移,例如该行数据与token对应的偏移为0x02,则原ILcode:721D00007可以替换如下Ox7202;步骤S306h:判断该定义方法的ILcode中是否所有操作指令和操作参数都已读取并压縮完成,如果是执行步骤S306i,如果不是,返回步骤S306a;在.net文件中,方法头中记录有ILcode长度,例如本实施例中长度为0x0000002F,当读取完该长度的ILcode数据后即认为该方法的ILcode中所有操作指令和操作参数都已读取并压縮完成;步骤S306i:计算该定义方法中压縮后的ILcode的长度;在本实施例中,对上述定义方法中ILcode压縮后得到的数据为[72](02)[OA][19][OB][14][FE01][OD][2D][72](01)为了方便说明,将数据中的操作指令加上中括号表示,操作参数使用小括号表示,计算长度为0x0020;步骤S308:判断是否所有定义方法的方法头均已读取并完成了对应的ILcode的压縮,如果是,执行步骤S310,如果不是,返回步骤S304,继续读取下一个定义方法头;在.net文件中,如步骤S302中步骤k中所述,记录了定义方法的行数,即定义方法的个数,在本实施例中为4个定义方法,当4个定义方法头均读取并完成对应的ILcode压縮时,认为所有定义方法头均已读取并完成对应的ILcode压縮;步骤S310:按照预先确定的格式组织压縮后的ILcode、压縮后的ILcode的长度和t偏移,得到压縮后的方法体;在本实施例中,优选地,预先确定的格式如表2所示表2局部变』压縮后的ILcode的长度局部变量的偏移压縮后的ILcode例如在本实施例中,方法体的压縮结果为[2000][(04)(07)(04)(05)][72](02)[OA][19][OB][14][FE01][OD][2D][72](01)[28](03)[OA][12][28](05)[28](03)[OC][2B][2A]上述压縮后的方法体使用小端的表示方法,其中,0x2000标识压縮后的ILcode的长度,(04)(07)(04)(05)分别标识4个局部变量在元数据表中的偏移,后面的数据为压縮后的ILcode,包括压縮后的操作指令及其参数。下面给出本实施例中第二个定义方法的方法体的压縮结果[][28](07)[2A]上述压縮结果中的压縮格式仅为最优的结构,可以做相应的变换,例如将局部变量的偏移放到压縮后的IL指令的长度前,或将局部变量的偏移放到压縮后的IL指令后等。本实施例所提供的方法通过对.net文件中的方法体进行压縮,有效地减小了.net文件占用的存储空间,可以降低.net文件的使用受存储空间的限制,有利于.net文件在小存储容量的设备上推广应用。需要说明的是,在附图的流程图示出的步骤可以在诸如一组计算机可执行指令的计算机系统中执行,并且,虽然在流程图中示出了逻辑顺序,但是在某些情况下,可以以不同于此处的顺序执行所示出或描述的步骤。此外,上述可执行指令可以存储于存储介质中,术语"存储介质"可以表示用于存储数据的一种或多种装置,包括只读存储器(R0M)、随机存取存储器(RAM)、磁RAM、磁心存储器、磁盘存储介质、光存储介质、闪存装置和/或用于存储信息的其他机器可读介质。术语"机器可读介质"包括但不限于便携式或固定存储装置、光存储装置、无线通道或能够存储、容纳、或承载指令和/或数据的各种其他介质。另外,可以通过硬件、软件、固件、中间件、微码、硬件描述语言或其组合来实现实施例。当用软件、固件、中间件或微码来实现时,可以在诸如存储介质的机器可读介质中存储用于执行必要任务的程序代码或码段。(多个)处理器可以执行必要任务。码段可以表示进程、函数、子程序、程序、例行程序、子例行程序、模块、对象、软件包、类、或指令、数据结构、或程序语言的任意组合。通过传输和/或接收信息、数据、自变量、或存储内容来将码段耦合到另一码段或硬件电路。信息、自变量、参数、数据等可以经由包括存储器共享、消息传递、令牌传递、网络传输等的任意合适方式来传递、传输、或传送。显然,本领域的技术人员应该明白,上述的本发明的各模块或各步骤可以用通用的计算装置来实现,它们可以集中在单个的计算装置上,或者分布在多个计算装置所组成的网络上,可选地,它们可以用计算装置可执行的程序代码来实现,从而,可以将它们存储在存储装置中由计算装置来执行,或者将它们分别制作成各个集成电路模块,或者将它们中的多个模块或步骤制作成单个集成电路模块来实现。这样,本发明不限制于任何特定的硬件和软件结合。以上所述仅为本发明的优选实施例而已,并不用于限制本发明,对于本领域的技术人员来说,本发明可以有各种更改和变化。凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。1权利要求一种.net文件的压缩方法,其特征在于,所述方法包括获取.net文件中使用的定义方法的方法头;压缩所述定义方法中的方法体,得到所述方法体的压缩结果。2.根据权利要求1所述的方法,其特征在于,所述压縮所述定义方法中的方法体的步骤包括根据所述方法头获取所述定义方法的局部变量,并根据所述局部变量的类型确定所述局部变量的偏移,所述局部变量的偏移指所述局部变量在所述.net文件对应的压縮结构中的偏移;根据所述方法头读取该定义方法的ILcode,并对所述ILcode进行压縮,计算压縮后的ILcode的长度;按照预先确定的格式对所述压縮后的ILcode的长度、所述局部变量的偏移和压縮后的ILcode进行组合,得到所述方法体的压縮结果。3.根据权利要求1所述的方法,其特征在于,所述获取.net文件中使用的定义方法的方法头的步骤包括获取.net文件中的元数据表MethodDef;从所述元数据表MethodDef中读取所述.net文件中使用的定义方法的方法头的地址信息;根据所述地址信息读取所述定义方法的方法头。4.根据权利要求2所述的方法,其特征在于,所述根据所述方法头获取所述定义方法的局部变量的步骤包括读取所述方法头的第一个字节,根据上述第一个字节判断所述定义方法是大头方法还是小头方法,如果是大头方法,根据所述大头方法中局部变量的标识token获取局部变量;如果是小头方法,将局部变量置空。5.根据权利要求2所述的方法,其特征在于,所述.net文件对应的压縮结构中的数据是按顺序排列的,每行数据的偏移与该行数据的标识token相对应。6.根据权利要求2所述的方法,其特征在于,所述根据所述方法头读取该定义方法的ILcode的步骤包括根据所述方法头中的信息确定该定义方法的ILcode的长度;根据确定的所述ILcode的长度读取所述ILcode。7.根据权利要求2所述的方法,其特征在于,所述对所述ILcode进行压縮的步骤包括读取所述ILcode中的操作指令,检查所述操作指令后是否有操作参数;如果没有,直接记录所述操作指令;否则,判断所述操作参数的类型;当所述操作参数为跳转的偏移量时,根据所述跳转的偏移量确定被跳过的ILcode,根据所述被跳过的ILcode重新计算所述跳转的偏移量,记录所述操作指令和重新计算出的跳转的偏移量;当所述操作参数为指向所述局部变量在所述方法体中的偏移量时,记录所述操作指令和所述操作参数;当所述操作参数为标识token时,确定所述标识token在所述压縮结构中对应的偏移量,记录所述操作指令和确定的偏移量。8.根据权利要求7所述的方法,其特征在于,所述对所述ILcode进行压縮的步骤包括判断所述ILcode中所有的操作指令和操作参数是否都被读取并压縮,如果是,执行所述计算压縮后的ILcode的长度的步骤;否则,读取下一条操作指令并进行压縮。9.根据权利要求2所述的方法,其特征在于,所述预先确定的格式指将所述压縮后的ILcode的长度、所述局部变量的偏移和压縮后的ILcode依次排列。10.根据权利要求1所述的方法,其特征在于,所述方法还包括判断是否所述.net文件中使用的所有定义方法的方法头都已经被读取并完成方法体的压縮,如果不是,继续读取下一个定义方法的方法头;否则,结束压縮。11.一种.net文件的压縮装置,其特征在于,所述装置包括方法获取模块,用于获取.net文件中使用的定义方法的方法头,并根据所述方法头获取该定义方法的ILcode;压縮模块,用于压縮所述定义方法中的方法体,得到所述方法体的压縮结果。12.根据权利要求11所述的装置,其特征在于,所述压縮模块包括局部变量偏移确定单元,用于根据所述方法获取模块获取的方法头获取所述定义方法的局部变量,并根据所述局部变量的类型确定所述局部变量的偏移,所述局部变量的偏移指所述局部变量在所述.net文件对应的压縮结构中的偏移;指令压縮与计算单元,用于对所述方法获取模块获取的ILcode进行压縮,并计算压縮后的ILcode的长度;组合单元,用于按照预先确定的格式对所述指令压縮与计算单元计算出的压縮后的ILcode的长度、所述局部变量偏移确定单元确定的局部变量的偏移和所述指令压縮与计算单元压縮后的ILcode进行组合,得到所述方法体的压縮结果。全文摘要本发明公开了一种.net文件的压缩方法和装置,根据本发明的.net文件的压缩方法包括获取.net文件中使用的定义方法的方法头,压缩所述定义方法中的方法体,得到所述方法体的压缩结果。所述装置包括方法获取模块和压缩模块。通过对方法体进行压缩可以有效地降低.net文件占用的存储空间,使.net文件可以在小容量存储介质(例如智能卡)上存储并运行,进而增强了小容量存储介质的功能。文档编号G06F9/44GK101794219SQ20091024416公开日2010年8月4日申请日期2009年12月30日优先权日2009年12月30日发明者于华章,陆舟申请人:北京飞天诚信科技有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1