收稿日期:2004-04-19 基金项目:国家自然科学基金(70171061)
作者简介:史扬(1977-),男,江苏南京人,博士研究生,主要研究方向:分布式系统安全; 曹立明(1944-),男,浙江上虞人,教授,博士生
导师,主要研究方向:分布式系统安全; 王小平(1965-),男,江苏扬中人,副教授,博士,主要研究方向:复杂系统.
文章编号:1001-9081(2004)11-0063-03
Java 混淆器的设计与实现
史 扬,曹立明,王小平
(同济大学计算机科学与工程系,上海200092)
(cnshiyang @yahoo )
摘 要:根据Java 虚拟机规范,通过对Java 类文件结构,尤其是常量池结构的分析,设计并实现了一个Java 混淆器。该混淆器在保证程序语义不变的同时改变java 类文件中函数和变量的名字,从而使得混淆后的类文件的反编译结果可读性极低。同时也实现了对控制流的混淆变换,已经成功的应用于保护移动代码的研究当中。
关键词:Java ;类文件;混淆器中图分类号:TP311.52 文献标识码:A
Design and implemention of Java obfuscator
SHI Yang ,C AO Li -ming ,W ANG Xiao -ping
(Department of Computer Science and Engineering ,Tongji University ,Shanghai 200092,C hina )
Abstract :Based on Java Virtual Machine specification ,thorough analysis of Java class file format ,especially the constant pool was carried out ,and a Java obfuscator has been successfully developed .The Java obfuscator is able to obfuscate the names of functions and variables in Java classfiles witho
ut changing their semantics in order to abase the readability of output of decompile .The obfuscator is also capable of obfuscating the control flow and has been successfully applied in the research of protecting mobile code .
Key words :Java ;classfile ;obfuscator
0 引言
随着计算机网络和分布式系统的发展,Java 语言以其良好的平台无关性在学术研究和商业开发中都得到了日益广泛的应用。为了保证程序能够跨平台运行,Java 程序的运行不得不借助Java 虚拟机(Java Virtual M achine ,JVM )。通过javac 之类的编译工具,Java 源代码被编译成为Java 字节码,也就是class 文件(class 文件中还包含有符号表及其他辅助信息)。由于这种编译并不生成可以直接在操作系统上运行的可执行文件,而是生成一种需要在JVM 上被解释运行的字节码,所以也有人称其为“伪编译”,并且称Java 为编译-解释型语言。基于这种特点,Java 语言的反编译较之C 、C ++等经典的编译型语言容易得多,目前已经有许多比较成熟的反编译工具软件可供使用,例如DJ Java Decompiler 等等。
由于容易被反编译,Java 的应用受到了相当程度的限制,这主要表现在两个方面:(1)软件的知识产权得不到保护;(2)移动代码的安全较容易受到威胁。为此,有必要在保证程序语义不变的前提下采取某些技术手段来破坏反编译结果的可读性。
1 混淆变换
1.1 混淆变换的定义
混淆器的实质是提供了一种转换机制,使转换后的Java 程序(或者转换后的class 文件的反编译结果)难以被理解。这种转换机制被称为混淆变换(Obfuscating Transformation ),定义[1]如下:
设T 是从原来的程序P 到目标程序P ′的一个变换,如果
P 和P ′具有相同的可观测行为,则称T 为一个从P 到P ′的混淆变换。更准确的说,当同时满足以下两个条件时T 才是一个合法的混淆变换:
1)如果P 无法中止或者以错误的状态中止,则P ′可以中止也可以不中止。
2)否则P ′必须中止并且产生和P 相同的输出结果。
混淆变换的原理参见图1所示。
图1 混淆变换原理示意图
通常在用于软件的知识产权保护要求读懂混淆后程序的代价不低于重新开发同类程序的代价,而在用于
增强移动代码安全性[2]时则要求在规定的保护时限内无法被攻击者理解且每次混淆时都应该带有一些随机参数以保证任意两次混淆的结果都不会相同。1.2 混淆变换的分类根据变换所设计的对象,混淆变换主要分为三类[3]:
(1)词法变换:对函数和变量的名称进行扰乱,使其违背见名知义的软件工程原则。
(2)控制流变换:在语义不变的前提下扰乱原有程序的控制结构使其难以被理解。
(3)数据变换:通过对原有的数据结构进行重组以增加观测的困难性。
第24卷第11期
2004年11月
计算机应用
Computer Applications
Vol .24No .11Nov .2004
目前广泛使用的混淆器(例如Proguard、Retroguard和joc 等)大多只针对第一类混淆变换,这对于保护知
识产权方面的应用通常已经足够,但是对于保护移动代码的安全则缺少随机性,为此我们设计的混淆器不仅实现了词法变换,还实现了控制流变换。已经将混淆变换与可以保护敏感数据的同态加密[4]技术相结合成功的应用于保护移动代码的研究之中。
2 类文件结构解析
2.1 ClassFile结构
表1 Class Fil e结构
名称长度用途
magic u4用以表征Java类文件的幻数,值为0xCAFEBABE
minor_vers ion u2次版本号major_version u2主版本号主版本号与次版本号合在一起构成版本号,被JV M的实现用来判定当前的类文件是否可以在其上运行
cons tant_pool_count u2记录常量池的长度
cons tant_pool可变常量池,由cons tant_pool_count-1个cp_info类型的数据项构成
access_flags u2当前类或接口的访问控制标志
字符串常量池存的是实例还是引用?this_class u2常量池中表示当前类的数据项的索引,该数据项为必须CON STANT_ Class类型
s uper_class u2常量池中表示当前类的父类的数据项的索引,该数据项必须为CONSTANT_Class类型
interfaces_count u2记录当前类或接口的直接父接口的数目
interfaces可变由interfaces_c ount个长度为u2的常量池数据项索引组成,所有相关的数据项必须为CON STANT_Cl as s类型,每一项均代表一个当前类或接口的直接父接口
fields_count u2记录当前类或接口的成员变量的数目
fields可变成员变量集合,由fields_c ount个field_info类型的数据项组成
methods_count u2记录当前类或接口的成员函数的数目
methods可变成员函数集合,由methods_count个method_info类型数据项组成
attributes_count u2记录当前类或接口的属性表中数据项的数目
attributes可变由attributes_count个attribute_info类型的数据项组成
在Java虚拟机规范[5]中要求一个类文件为一个8位的字节流。所有的16位,32位和64位数分别由读入两个,四个和八个相邻的8位字节来构造,多字节的数据条目按照big-endian(高位在后)方式来存储。Java虚拟机规范[5]规定一个类文件必须对应于一个ClassFile结构(表1),表中u2表示16bits,u4表示32bits。
2.2 常量池
常量池是由cp_info类型的数据项组成的集合,每一个数据项都包括两个部分:
(1)一个用于标志自身属性的8位字节,有关其含义的详细介绍参见Java虚拟机规范[5]。
(2)一个或若干个字段,这些字段可以用来指向常量池中其他的数据项,也可以包含某些数值或者字符串。
在常量池类型众多的数据项中,和词法变换混淆关系最为密切的是CONSTANT_Fieldref_info类型和C ONSTANT_ M ethodref_info类型,它们形式相同,均由三个部分构成:
(1)属性标志位。
(2)类索引。类索引指向当前常量池中某个C ONSTANT_ Class_info类型的数据项,表示该field或者method的声明所在的类。
(3)名称和类型索引。这个索引指向当前常量池中某个CONSTANT_NameAndType_info类型的数据项,表示该field或者method的名称和类型。
在对类文件进行混淆时,最主要的操作就是根据相关的CONSTANT_NameAndType_info数据项来到存储名字的CONSTANT_Utf8_info数据项,而这个用以存储名字的数据项在当前常量池中的索引就被存放在CONSTANT_NameAnd Type_ info数据结构的第二个字段中。
2.3 类文件的读取
基于前面对ClassFile结构的分析,不难实现对类文件的读取。在读取类文件的同时将相应的值赋给一个ClassFile类即可得到进行词法变换所需的数据结构。我们参考dumpclass[6]使用Java语言实现了对类文件的读取。
3 词法变换的算法
由于Java程序的发布和运行通常是以包为单位来进行的,所以在设计词法变换算法时也是以包为单位来考虑的,具体步骤如下:
(1)依次扫描包中各个类的super class和super interface,构造各个类的继承树。
对于存在于其他类库中的super class,设置boolean inPackage=false;否则设置inPackage=true。
(2)依次扫描包中各个类函数表,注册各个类中的abstract methods,具体方法是:
对应inPackage值为true的类,abstract methods按照其是public或者protected,对该类的子类的同名且同属性的成员函数,均作同样注册以保证它们按照统一的名字被混淆。
(3)依次扫描包中各个类函数表,混淆各个类中的成员函数,具体方法是:
对有native属性的成员函数不论其访问属性如何均不进行混淆,否则:
对访问属性为public的成员函数不进行混淆;
对访问属性为protected的成员函数(除当前类的构造函数外),如果该函数是从抽象父类继承来的抽象函数,则按照一个统一的名字对所以相关的类中的这个函数进行混淆,否
64
计算机应用2004年
65
第11期史扬等:Java混淆器的设计与实现
里的规则也可能会存在冲突,这就涉及到规则的处理问题,所以我们必须将存在冲突的规则从规则库中删掉,即规则的提取。具体算法如下:
步骤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
.
74 计算机应用2004年
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论