项目背景
因在公司负责基础框架的开发设计,所以针对框架源代码的保护工作比较重视,之前也加入了一系列保护措施
例如自定义classloader加密保护,授权license保护等,但都是防君子不防小人,安全等级还比较低
经过调研各类加密混淆措施后,决定自研混淆插件,自主可控,能够贴合实际情况进行定制化,达到框架升级后使用零感知,零影响。
快速开始
项目地址:https://gitee.com/code2roc/xhood
在线文档:https://code2roc.gitee.io/xhood/#/
- 下载最新发行版到本地,执行maven install
- 工程项目配置maven plugin ,详细配置见在线文档
- <build>
- <plugins>
- <plugin>
- <groupId>com.code2roc</groupId>
- <artifactId>xhood</artifactId>
- <version>1.0.0</version>
- <executions>
- <execution>
- <goals>
- <goal>obscure</goal>
- </goals>
- <phase>compile</phase>
- </execution>
- </executions>
- <configuration>
-
- <packageName>com.xxx.xxx</packageName>
-
- <obscureIgnoreClasss>com.xxx.xxx.Application</obscureIgnoreClasss>
- </configuration>
- </plugin>
- </plugins>
- </build>
复制代码 方案设计
我们首先要清除代码混淆要实现什么,就是将原代码名称结构和内容使用一系列的规则码替换
达到阅读困难,理解困难,恢复困难的作用
混淆的事项包括方法,成员变量,临时变量,方法参数,常量,类,包,枚举
这些事项的混淆还需要遵循固定的顺序,因为事项之间还存在相互引用的情况
在完成结构混淆(类文件,包名)后,需要删除对应的原class文件
混淆前后的效果如下图所示


方案实现
pom引用
- <dependency>
- <groupId>org.ow2.asm</groupId>
- <artifactId>asm</artifactId>
- <version>9.0</version>
- </dependency>
- <dependency>
- <groupId>org.ow2.asm</groupId>
- <artifactId>asm-commons</artifactId>
- <version>9.0</version>
- </dependency>
- <dependency>
- <groupId>org.ow2.asm</groupId>
- <artifactId>asm-util</artifactId>
- <version>9.0</version>
- </dependency>
- <dependency>
- <groupId>org.ow2.asm</groupId>
- <artifactId>asm-tree</artifactId>
- <version>9.0</version>
- </dependency>
- <dependency>
- <groupId>org.ow2.asm</groupId>
- <artifactId>asm-analysis</artifactId>
- <version>9.0</version>
- </dependency>
复制代码 名称混淆
名称混淆指的是把类名,方法名,参数名,变量名等定义的名称进行规则码替换,以混淆方法名为例
- 混淆方法定义
自定义ClassVisitor重写visit方法
过滤枚举类的方法
过滤main方法,过滤lambda表达式方法,过滤构造函数方法
过滤非混淆范围内接口的实现方法
过滤非混淆范围内父类的重写方法
- 混淆方法调用
自定义MethodVisitor重写visitMethodInsn,visitInvokeDynamicInsn方法
visitMethodInsn修混淆方法定义中的方法
visitInvokeDynamicInsn修改接口的实现方法和父类的重写方法(混淆范围内且混淆方法定义中的方法)
结构混淆
结构混淆指的是修改类名,包名时对实体class文件和文件夹的重命名,以混淆类名为例
- 混淆类定义
自定义ClassVisitor重写visit方法
过滤非混淆范围内的class
重写visitSource,visitField,visitMethod,visitInnerClass,visitOuterClass等方法
- 混淆类定义调用
自定义MethodVisitor重写visitMethodInsn,visitFieldInsn,visitFrame,visitInvokeDynamicInsn等方法
- 混淆类重命名
定义ClassWriter获取class文件byte数组重新写入文件
注解混淆
注解的混淆比较特殊,需要继承AnnotationVisitor类来重写visit方法实现
针对注解中有枚举需要重写visitEnum方法
针对嵌套注解需要重写visitAnnotation方法
针对注解有参数有数组的,需要重写visitArray方法
visitAnnotation和visitArray方法需要返回AnnotationVisitor对象,调用super方法后返回自定义AnnotationVisitor对象递归处理即可
混淆规则
无论混淆哪一部分,我们总是要根据一个名称例如abc混淆后得到一个固定的规则码例如123
这时候我们会想到md5这种固定输入对应固定输出的信息摘要算法
md5内容太长,我们需要截取某几位进行简化
简化后的规则码在待混淆内容越多时越容易碰撞,需要需要动态调整,简单递归即可,最坏结果就是完整的md5表示
[code] public static String getTakeName(String name, int takeLimit, HashMap typeMap) { String obscureName = getObscureName(name); if (takeLimit |