Java源码混淆

Java程序的编译过程与C/C++程序的编译过程截然不同。C/C++程序经编译后生成的是二进制的机器码,这种代码只有在特定平台上才能运行,通过查找表编译器可以将所有变量和方法符号的引用转换成特定的内存偏移量。而Java编译器却既不能把变量和方法等符号的引用转换为数值引用,也不能确定程序执行过程中的内存布局,而是将这些符号的引用信息保留在class文件中,由解释器在运行过程中创建内存布局,然后再通过查找表来确定一个变量或方法所在的地址。

因此Java字节码文件中保留了所有方法和变量的信息符号,而这些符号根据编码规则通常带有语义信息,这就为反编译Java类文件提供了可能。也正是由于Java本身的这种特性,使得Java类文件很容易被反编译成与原文件非常相似的文件。

代码混淆技术是一种重要的软件保护方法,混淆的实质就是一种变换,通过这种变换把原来的代码变成与其功能相同或相近的,但是更难被理解和反编译的代码。由于混淆技术可以根据不同的目的,不同的混淆对象采用不同的方法,这使得混淆方法非常多。

代码混淆的分类

根据混淆变换原理,本文将代码混淆技术分为词法变换、控制混淆、数据混淆和类结构混淆,以下将分别对这四种混淆技术加以阐述。

词法变换
词法变换的原理是对函数和变量的名称进行变换,使其违背Java命名规范中见名知义的原则。其原理依照Java虚拟机规范中有关类文件结构的规定,对常量池中存储的类、字段、方法和变量等名称的“CONSTANT Utf8 info”类型的数据项加以混淆,在保持程序语义不变的前提下将名字更改为毫无意义、无规律的字符串。这种方法具有单向性,并且没有引入额外的执行代价。目前Java字节码混淆器和混淆编译器大多支持这一功能。

为了提高混淆算法的隐蔽性,Roo和Oord提出了使用标识符交换来进行词法变换,其思想是用标识符作交换而非更改成毫无意义的名字。标识符交换包括交换变量名、函数名和类型三种。使用标识符交换来进行词法变换在提高隐蔽性的同时,由于标识符的保留也为反编译者提供了方便,不具有单向性。

控制混淆

控制混淆是一种被广泛使用的代码混淆技术,其基本原理是通过改变程序的判断条件,或向程序中添加不透明谓词等方法来增加程序的复杂度,并且可以通过对程序结构和执行路径的调整,来增加反编译工具反编译程序的难度。目前较为流行的控制混淆变换主要有以下几种:分支插入变换、循环条件插入变换、将可化简的控制流转换成不可化简的控制流、使用对象和别名的不透明谓词和使用并行技术构建不透明谓词等。

不透明谓词:一个谓词P在P点若其值在混淆时,混淆者可知而反编译者 很难获知,则称它为不透明谓词。

4 weeks ago, this page was being read.


Subscribe to Comments