2004年11月
文章编号:1001-9081(2004)11-0063-03
计算机应用
ComputerApplications
Vol.24No.11Nov.2004
Java混淆器的设计与实现
史 扬,曹立明,王小平
(同济大学计算机科学与工程系,上海200092)
(cnshiyang@yahoo.com.cn)
摘 要:根据Java虚拟机规范,通过对Java类文件结构,尤其是常量池结构的分析,设计并实现了一个Java混淆器。该混淆器在保证程序语义不变的同时改变java类文件中函数和变量的名字,从而使得混淆后的类文件的反编译结果可读性极低。同时也实现了对控制流的混淆变换,已经成功的应用于保护移动代码的研究当中。
关键词:Java;类文件;混淆器中图分类号:TP311.52 文献标识码:A
DesignandimplementionofJavaobfuscator
SHIYang,CAOLi-ming,WANGXiao-ping
(DepartmentofComputerScienceandEngineering,TongjiUniversity,Shanghai200092,China)
Abstract:BasedonJavaVirtualMachinespecification,thoroughanalysisofJavaclassfileformat,especiallytheconstantpoolwascarriedout,andaJavaobfuscatorhasbeensuccessfullydeveloped.TheJavaobfuscatorisabletoobfuscatethenamesoffunctionsandvariablesinJavaclassfileswithoutchangingtheirsemanticsinordertoabasethereadabilityofoutputofdecompile.Theobfuscatorisalsocapableofobfuscatingthecontrolflowandhasbeensuccessfullyappliedintheresearchofprotectingmobilecode.
Keywords:Java;classfile;obfuscator
设T是从原来的程序P到目标程序P′的一个变换,如果
P和P′具有相同的可观测行为,则称T为一个从P到P′的混淆变换。更准确的说,当同时满足以下两个条件时T才是一个合法的混淆变换:
1)如果P无法中止或者以错误的状态中止,则P′可以中止也可以不中止。
2)否则P′必须中止并且产生和P相同的输出结果。
混淆变换的原理参见图1所示。
0 引言
随着计算机网络和分布式系统的发展,Java语言以其良好的平台无关性在学术研究和商业开发中都得到了日益广泛的应用。为了保证程序能够跨平台运行,Java程序的运行不得不借助Java虚拟机(JavaVirtualMachine,JVM)。通过javac之类的编译工具,Java源代码被编译成为Java字节码,也就是class文件(class文件中还包含有符号表及其他辅助信息)。由于这种编译并不生成可以直接在操作系统上运行的可执行文件,而是生成一种需要在JVM上被解释运行的字节码,所以也有人称其为“伪编译”,并且称Java为编译-解释型语言。基于这种特点,Java语言的反编译较之C、C++等经典的编译型语言容易得多,目前已经有许多比较成熟的反编译工具软件可供使用,例如DJJavaDecompiler等等。
由于容易被反编译,Java的应用受到了相当程度的,这主要表现在两个方面:(1)软件的知识产权得不到保护;(2)移动代码的安全较容易受到威胁。为此,有必要在保证程序语义不变的前提下采取某些技术手段来破坏反编译结果的可读性。
图1 混淆变换原理示意图
通常在用于软件的知识产权保护要求读懂混淆后程序的代价不低于重新开发同类程序的代价,而在用于增强移动代码安全性[2]时则要求在规定的保护时限内无法被攻击者理解且每次混淆时都应该带有一些随机参数以保证任意两次混淆的结果都不会相同。1.2 混淆变换的分类根据变换所设计的对象,混淆变换主要分为三类[3]:
(1)词法变换:对函数和变量的名称进行扰乱,使其违背见名知义的软件工程原则。
(2)控制流变换:在语义不变的前提下扰乱原有程序的控制结构使其难以被理解。
(3)数据变换:通过对原有的数据结构进行重组以增加观测的困难性。
1 混淆变换
1.1 混淆变换的定义
混淆器的实质是提供了一种转换机制,使转换后的Java程序(或者转换后的class文件的反编译结果)难以被理解。这种转换机制被称为混淆变换(ObfuscatingTransformation),定义[1]如下:
收稿日期:2004-04-19 基金项目:国家自然科学基金(70171061)
作者简介:史扬(1977-),男,江苏南京人,博士研究生,主要研究方向:分布式系统安全; 曹立明(1944-),男,浙江上虞人,教授,博士生导师,主要研究方向:分布式系统安全; 王小平(1965-),男,江苏扬中人,副教授,博士,主要研究方向:复杂系统.
计算机应用
16bits,u4表示32bits。
2004年
目前广泛使用的混淆器(例如Proguard、Retroguard和joc等)大多只针对第一类混淆变换,这对于保护知识产权方面的应用通常已经足够,但是对于保护移动代码的安全则缺少随机性,为此我们设计的混淆器不仅实现了词法变换,还实现了控制流变换。已经将混淆变换与可以保护敏感数据的同态加密[4]技术相结合成功的应用于保护移动代码的研究之中。
2.2 常量池
常量池是由cp_info类型的数据项组成的集合,每一个数据项都包括两个部分:
(1)一个用于标志自身属性的8位字节,有关其含义的详细介绍参见Java虚拟机规范[5]。(2)一个或若干个字段,这些字段可以用来指向常量池中其他的数据项,也可以包含某些数值或者字符串。
在常量池类型众多的数据项中,和词法变换混淆关系最为密切的是CONSTANT_Fieldref_info类型和CONSTANT_Methodref_info类型,它们形式相同,均由三个部分构成:
(1)属性标志位。
(2)类索引。类索引指向当前常量池中某个CONSTANT_Class_info类型的数据项,表示该field或者method的声明所在的类。
(3)名称和类型索引。这个索引指向当前常量池中某个CONSTANT_NameAndType_info类型的数据项,表示该field或者method的名称和类型。
在对类文件进行混淆时,最主要的操作就是根据相关的CONSTANT_NameAndType_info数据项来找到存储名字的CONSTANT_Utf8_info数据项,而这个用以存储名字的数据项在当前常量池中的索引就被存放在CONSTANT_NameAndType_info数据结构的第二个字段中。2.3 类文件的读取基于前面对ClassFile结构的分析,不难实现对类文件的读取。在读取类文件的同时将相应的值赋给一个ClassFile类即可得到进行词法变换所需的数据结构。我们参考dumpclass[6]使用Java语言实现了对类文件的读取。
2 类文件结构解析
2.1 ClassFile结构
表1 ClassFile结构
名称magicminor_version
长度u4u2
用途
用以表征Java类文件的幻数,值为
0xCAFEBABE次版本号
主版本号与次版本号合在一起构成版本号,被JVM的实现用来判定当前的类文件是否可以在其上运行
constant_pool_countconstant_poolaccess_flagsthis_class
u2可变u2u2
记录常量池的长度
常量池,由constant_pool_count-1个cp_info类型的数据项构成当前类或接口的访问控制标志常量池中表示当前类的数据项的索引,该数据项为必须CONSTANT_
Class类型
常量池中表示当前类的父类的数
super_class
u2
据项的索引,该数据项必须为
CONSTANT_Class类型
记录当前类或接口的直接父接口的数目
由interfaces_count个长度为u2的常
interfaces
可变
量池数据项索引组成,所有相关的数据项必须为CONSTANT_Class类型,每一项均代表一个当前类或接口的直接父接口
fields_countfieldsmethods_countmethodsattributes_countattributes
u2可变u2可变u2可变
记录当前类或接口的成员变量的数目
成员变量集合,由fields_count个field_info类型的数据项组成记录当前类或接口的成员函数的数目
成员函数集合,由methods_count个
method_info类型数据项组成记录当前类或接口的属性表中数据项的数目
由attributes_count个attribute_info类型的数据项组成
major_versionu2主版本号
interfaces_countu2
3 词法变换的算法
由于Java程序的发布和运行通常是以包为单位来进行
的,所以在设计词法变换算法时也是以包为单位来考虑的,具体步骤如下:
(1)依次扫描包中各个类的superclass和superinterface,构造各个类的继承树。
对于存在于其他类库中的superclass,设置booleaninPackage=false;否则设置inPackage=true。
(2)依次扫描包中各个类函数表,注册各个类中的abstractmethods,具体方法是:
对应inPackage值为true的类,abstractmethods按照其是public或者protected,对该类的子类的同名且同属性的成员函数,均作同样注册以保证它们按照统一的名字被混淆。(3)依次扫描包中各个类函数表,混淆各个类中的成员函数,具体方法是:
对有native属性的成员函数不论其访问属性如何均不进行混淆,否则:
对访问属性为public的成员函数不进行混淆;对访问属性为protected的成员函数(除当前类的构造函数外),如果该函数是从抽象父类继承来的抽象函数,则按照一个统一的名字对所以相关的类中的这个函数进行混淆,否
在Java虚拟机规范[5]中要求一个类文件为一个8位的字节流。所有的16位,32位和位数分别由读入两个,四个和八个相邻的8位字节来构造,多字节的数据条目按照big-endian(高位在后)方式来存储。Java虚拟机规范规定一个类文件必须对应于一个ClassFile结构(表1),表中u2表示
[5]
第11期史扬等:Java混淆器的设计与实现 65
74计算机应用2004年
里的规则也可能会存在冲突,这就涉及到规则的处理问题,所以我们必须将存在冲突的规则从规则库中删掉,即规则的提取。具体算法如下:
步骤1:对信息表中条件属性进行逐列考察,除去该列后,若产生冲突记录,则保留冲突记录的原该属性值;若未产生冲突但含有重复记录,则将重复记录的该属性值标为“*”;对其他记录,将该属性值标为“?”。
步骤2:删除可能产生的重复记录,并考察每条含有标记“?”的记录。若仅由未被标记的属性值即可做出决策,则将“?”标记为“*”。否则,修改为原属性值;若某条记录的所有条件属性均被标记,则将标有“?”的属性修改为原属性的值。
步骤3:删除所有条件属性均被标记为“*”的记录及可能产生的重复记录。
步骤4:如果两条记录仅有一个条件属性值不同,且其中一条记录的该属性被标为“*”,那么,当可由未被标记的属性值对该记录做出决策时,则删除另外一条记录;否则,删除本记录。
规则匹配:从规则库中提取规则,与已知的条件属性进行比较来预测决策属性的值。
通过风机故障知识库的建立和数据挖掘技术的应用,不仅实现了风机故障的监测,而且实现了风机故障的预测,提高了系统运行的可靠性。
4 结语
随着信息技术和计算机网络技术的发展,大型设备要求在安全、可靠的状态下尽可能长时间、满负荷运行,这对设备
的远程监测和故障诊断提出了更高的要求。传统的设备监测与故障诊断,往往不能得到专家的现场指导,大型设备运行每时都产生大量的监测数据,单纯用人工诊断,很难胜任。基于以上分析,本文将数据挖掘技术引入远程故障诊断领域,设计一套基于数据挖掘技术的远程故障诊断系统,以解决该领域中的远程性、复杂性、继承性,以及诊断技术向自动化、智能化方向发展所面临的问题。参考文献:
[1] 许踌,等.旋转机械故障诊断知识库的形成[J].南京工业大学学
报,2002,7(4):30-33.
[2] 秦锋,扬学兵.二维立方体中关联规则挖掘算法研究[J].微机发
展,2003,2(2):86-88.
[3] 周庆敏,李永生,等.基于粗集理论的数据挖掘应用[J].南京工
业大学学报,2003,3(2):44-48.
[4] 杜威,邹先霞,等.一个基于数据挖掘的环境质量预测系统[J].
计算机工程与设计,2002,4(4):88-90.
[5] 赵纪元,田会珍,等.谐波小波与不同尺度下轴心轨迹分析[J].
石家庄铁道学院学报,1999,12(4):15-18.
[6] 陈堂敏,蔡业彬,等.振动温度在线监测系统研制[J].石油化工
自动化,2000,12(6):61-62.
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- dcrkj.com 版权所有 赣ICP备2024042791号-2
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务