1 混淆器retroGuard的介绍:
本节介绍如何使用retroGuard来进行字节混淆来防止反编译和反向工程。
1.1 关于RetroGuard
RetroGuard是一个字节级的混淆器,一个替换可以识别的变量和属性为无意义的字符串的工具,这使得反向工程和反编译无法正常工作。编译后的代码容量会减小。
RetroGuard是一个免费的软件,使用GNU Lesser General Public License.
特性包括:
1, 降低java代码的容量,(最大可以节省将近50%,一般情况下可以节省20%-30%),这样对于你的applets程序,可以大大加速了下载时间。
2, 设计合理,可以与java工程的自动化编译过程无缝兼容。
3, 允许全部用户定义的混淆过程。
4, 支持多种对java代码的切入点——可以访问应用程序,applets,javaBeans和类库接口。
5, 使用jar 这个标准的java打包方案。
6, 混淆过程可以被灵活的脚本语言来控制。
7, 提供了一个图形化的向导程序来管理脚本文件。
8, 通过对方法和文件名的大量过载来取得高安全性
9, 生成的代码有效,符合java虚拟机规范。
10, 自动更新清单文件,使用混淆后的类名,并且自动生成MD5和SHA-1的消息摘要 (automatically generated MD5 and SHA-1 message digests)
1.2 关于混淆(obfuscation)
java字节代码(class文件)包含了所有的信息,部分源文件中注释。使用decompiler工具可以很轻易的取得源码。为了对抗这种行为,我们需要再部署软件时混淆你的类文件。
混淆过程剔除了所有不需要的信息,包括行号表,本地变量名和源文件名。同时,类,接口,字段和方法标示被重新命名。运行这些代码的Java虚拟机,并不在意这些变化。然而,这种版本的classes文件反编译之后,难以理解的。
决定哪个类需要被混淆,大多数混淆器提供一个单一的切入点(通常是一个应用程序的main方法,或则是applet),并且从这个切入点引出一个类树出来。不幸的是,该方法是非常有限的仅仅适用于小的cases当中的,如果java代码包含了多个切入点,这个方法就不是很灵活的。
相反的,RetroGuard混淆类和接口是在jar文件内进行的。所有的切入点可以通过描述文件类定义的。
(Corruption of class技术 ,不太理解,主要的意思是这样处理过的代码会挑虚拟机的,只在部分机器上可以运行的)
使用多种技术方案来混淆字节代码,他完全可以使市场上一些简易的编译器失效。
由于以上原因,RetroGuard 混淆器只产生通过验证的字节代码,完全兼容Java虚拟机规范。
与Corrupting the bytecode不同,RetroGuard使用标示符得过载技术。
1.3 安装使用
RetroGuard的安装很简单,只需要将retroGuard.jar包放到CLASSPATH路径下就可以了。
命令行格式为:
java RetroGuard [INPUT-JAR [OUTPUT-JAR [SCRIPT [LOGFILE]]]]
例如: java RetroGuard mytest.jar mytesto.jar
1.4 混淆过程的控制
脚本文件可以控制RetroGuard的混淆过程,脚本文件可以定义那种标示符不被改变。
脚本文件可以通过手写的方式,也可以使用图形化工具来生成的:
java RGgui
如果一个应用程序的入口程序是 MyApp.class,那么在脚本文件中可以这样写:
.class MyApp public method
如果需要访问到一个applet程序MyApplet.class, 那么在脚本文件中可以这样写:
.class MyApp ,这样将保留类的文件名不被混淆
如果需要访问一个JavaBean类,MyBean.class, 那么在脚本文件中可以这样写:
.class MyBean protected,这样将保留类名,pulic方法,保护方法和可以访问的方法和字段。
脚本文件的例子:
# All text in a line following '#' is treated as a comment, and is ignored.
# Preserve the class name 'MyClass' in package 'COM.widgetco'
# (note that the package identifiers 'COM' and 'widgetco' are
# automatically preserved also, so that 'MyClass' remains fully
# accessible):
.class COM/widgetco/MyClass
# Preserve the class name 'MyClass' and all public methods and
# fields declared in it:
.
# Preserve the class name 'MyClass' in package 'COM.widgetco'
# (note that the package identifiers 'COM' and 'widgetco' are
# automatically preserved also, so that 'MyClass' remains fully
# accessible):
.class COM/widgetco/MyClass
# Preserve the class name 'MyClass' and all public methods and
# fields declared in it:
.
class COM/widgetco/MyClass public
# Preserve the class name 'MyClass' and all public, protected or
# default-access (package) methods and fields declared in it:
.class COM/widgetco/MyClass protected
# Preserve the class name 'MyClass' and all public, protected or
# default-access (package) methods (but not fields) declared in it:
.class COM/widgetco/MyClass protected method
# Preserve the class name 'MyClass' and all public and protected
# (but not default-access, package) methods and fields declared in it:
.class COM/widgetco/MyClass pub_prot_only
# Preserve all classes and their public fields in the package
# Preserve the class name 'MyClass' and all public, protected or
# default-access (package) methods and fields declared in it:
.class COM/widgetco/MyClass protected
# Preserve the class name 'MyClass' and all public, protected or
# default-access (package) methods (but not fields) declared in it:
.class COM/widgetco/MyClass protected method
# Preserve the class name 'MyClass' and all public and protected
# (but not default-access, package) methods and fields declared in it:
.class COM/widgetco/MyClass pub_prot_only
# Preserve all classes and their public fields in the package
# 'COM.widgetco':
# (Reference to all classes in a package is the only situation
# where wildcards are allowed)
.class COM/widgetco/* public field
# Preserve the 'SourceFile' debugging attribute of all classes:
.attribute SourceFile
# Preserve the method 'double getValue(Object obj)' in class 'MyClass':
.method COM/widgetco/MyClass/getValue (Ljava/lang/Object;)D
# Preserve the field 'char aCharacter' in class 'MyClass':
.field COM/widgetco/MyClass/aCharacter C
# (Reference to all classes in a package is the only situation
# where wildcards are allowed)
.class COM/widgetco/* public field
# Preserve the 'SourceFile' debugging attribute of all classes:
.attribute SourceFile
# Preserve the method 'double getValue(Object obj)' in class 'MyClass':
.method COM/widgetco/MyClass/getValue (Ljava/lang/Object;)D
# Preserve the field 'char aCharacter' in class 'MyClass':
.field COM/widgetco/MyClass/aCharacter C
1.5 对非class类文件的处理
这些资源文件包括了图形,音频文件,本地化代码,jar包文件包含了一个清单文件和一些数字签名的文件。RetroGuard可以处理上面所有文件(打在jar中的)
一般来说,我们访问资源文件的方法是:
1. 使用相对路径和java的类方法
InputStream getResourceAsStream(String relativePath)
URL getResource(String relativePath)
2. 使用绝对路径和ClassLoader的方法
InputStream getResourceAsStream(String absolutePath)
URL getResource(String absolutePath)
我们提倡大家采用相对路径的方式来访问资源。
签名:首先用RetroGuard将源包混淆后,在进行签名的。
1.6 创建补丁文件
RetroGuard(1.1版本以后)支持增量混淆,这样可以大大降低了程序的下载量。
使用方法 :java RGpatch WHOLE-JAR PATCH-JAR LOGFILE LISTFILE
举例:
初始版本:
java RetroGuard jtool-unobf-1.0.jar jtool-1.0.jar s jtool-1.0.log
(其中,s 内容为.class JTool public method)
该公司可以将jtool-1.0.jar发布,提供给客户下载,日志文件jtool-1.0.log包含了混淆映射关系,这个log文件对于软件和补丁是非常重要的。
几周后,客户发现了新的问题,修复这个问题需要类和资源的改变。我们就可以创建一个小的补丁包来完成程序的更新。
第一次编译和打包的jar包是jtool-unobf-1.1.jar.
java RetroGuard jtool-unobf-1.1.jar jtool-1.1.jar jtool-1.0.log jtool-1.1.log
注意到:这次使用的是jtool-1.0.log文件,而不是s.这样生成1.1版本包是与1.0版本包完全兼容的。
剩下的工作就是将变化的类和资源从jtool-1.1.jar包中提取出来。
首先需要建立一个jtool-patch-1.文本表示变化类的名字
COM/widgetco/MyClass.class
COM/widgetco/anImage.gif
Java Rgpatch jtool-1.1.jar jtool-patch-1.0-1.1.jar jtool-1.1.log jtool-patch-1.
jre -cp jtool-1.0.jar JTool
they could now take advantage of the bug-fix by using the patch file:
jre -cp jtool-patch-1.0-1.1;jtool-1.0.jar JTool
2 混淆器jdoc的介绍:
jdoc混淆编译器是在Sun JDK中提供的Java编译器(javac)的基础上完成的,修改了代码生成过程,对编译器生成的中间代码进行混淆,最后再生成class文件,这样编译和混淆只需要一个步骤就可以完成。另外可以在源程序中插入符号保留指令来控制哪些符号需要保留,不需要单独的配置。
2.1 Xobfuscate命令参数说明
运行java -jar joc.jar就可以启动Java混淆编译器,joc的命令行参数和javac完全相同,但增加了一个新的参数-Xobfuscate,它的用法如下:
-Xobfuscate:
其中指定混淆级别,可以是以下几种级别:
-Xobfuscate:none 不进行混淆
-Xobfuscate:private 对所有private访问级别的元素进行混淆
java混淆工具-Xobfuscate:package 对所有private或package private元素进行混淆
-Xobfuscate:protected 对所有private, package private, protected元素进行混淆
-Xobfuscate:public 对所有的元素都进行混淆
-Xobfuscate:all 相当于-Xobfuscate:public
如果使用-Xobfuscate不带级别参数,则相当于-Xobfuscate:package
其中指定混淆级别,可以是以下几种级别:
-Xobfuscate:none 不进行混淆
-Xobfuscate:private 对所有private访问级别的元素进行混淆
java混淆工具-Xobfuscate:package 对所有private或package private元素进行混淆
-Xobfuscate:protected 对所有private, package private, protected元素进行混淆
-Xobfuscate:public 对所有的元素都进行混淆
-Xobfuscate:all 相当于-Xobfuscate:public
如果使用-Xobfuscate不带级别参数,则相当于-Xobfuscate:package
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论