从零开发基于ASM字节码的Java代码混淆插件XHood

简介: 因在公司负责基础框架的开发设计,所以针对框架源代码的保护工作比较重视,之前也加入了一系列保护措施,例如自定义classloader加密保护,授权license保护等,但都是防君子不防小人,安全等级还比较低,经过调研各类加密混淆措施后,决定自研混淆插件,自主可控,能够贴合实际情况进行定制化,达到框架升级后使用零感知,零影响

项目背景

因在公司负责基础框架的开发设计,所以针对框架源代码的保护工作比较重视,之前也加入了一系列保护措施

例如自定义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表示

    public static String getTakeName(String name, int takeLimit, HashMap<String, String> typeMap) {
   
   
        String obscureName = getObscureName(name);
        if (takeLimit <= 16) {
   
   
            obscureName = obscureName.substring(8, 24);
        }
        String takeName = obscureName.substring(0, takeLimit);
        if (typeMap.containsValue(takeName)) {
   
   
            takeName = getTakeName(name, takeLimit + 1, typeMap);
        }
        return takeName;
    }

注意事项

开发事项

在混淆过程中,需要针对不同的情况进行细节处理,举例如下

  • 混淆名称中有相同部分的优先排序替换长度最长的部分

例如方法名HandleMethod和Handle两部分,Handle对应的规则码为123,我先替换Handle部分变成了123Method和123,那么123Method这个方法混淆后就会定义错误

  • 临时变量和方法变量都会调用MethodVisitor的visitLocalVariable方法,需要区分

先定义ParamterAdapter继承MethodVisitor重写visitParameter记录方法变量

使用事项

在springboot项目中,我们需要进行一些配置避免导致项目无法运行或运行错误**

  • 所有需要通过接口返回的实体类需要忽略,例如数据库实体DO

  • 通过ConfigurationProperties映射的yml文件配置项类需要忽略

  • 通过类名/字段名反射调用的类需要忽略

  • 针对@Aspect注解切面进行了兼容,参照如下写法则混淆无影响

    PointCut注解/类需要指定全名,Around注解指定方法名

    @Aspect
    @Component
    public class RepeatSubmitAspect {
         
         
        /**
         * 切面点 指定注解
         */
        @Pointcut("@annotation(com.code2roc.fastboot.framework.submitlock.SubmitLock) " +
                "|| @within(com.code2roc.fastboot.framework.submitlock.SubmitLock)")
        public void repeatSubmitAspect() {
         
         
    
        }
    
        /**
         * 拦截方法指定为 repeatSubmitAspect
         */
        @Around("repeatSubmitAspect()")
        public Object around(ProceedingJoinPoint point) throws Throwable {
         
         
            return point.proceed();
        }
    }
    
目录
相关文章
|
1月前
|
安全 前端开发 Java
《深入理解Spring》:现代Java开发的核心框架
Spring自2003年诞生以来,已成为Java企业级开发的基石,凭借IoC、AOP、声明式编程等核心特性,极大简化了开发复杂度。本系列将深入解析Spring框架核心原理及Spring Boot、Cloud、Security等生态组件,助力开发者构建高效、可扩展的应用体系。(238字)
|
2月前
|
消息中间件 人工智能 Java
抖音微信爆款小游戏大全:免费休闲/竞技/益智/PHP+Java全筏开源开发
本文基于2025年最新行业数据,深入解析抖音/微信爆款小游戏的开发逻辑,重点讲解PHP+Java双引擎架构实战,涵盖技术选型、架构设计、性能优化与开源生态,提供完整开源工具链,助力开发者从理论到落地打造高留存、高并发的小游戏产品。
|
2月前
|
存储 Java 关系型数据库
Java 项目实战基于面向对象思想的汽车租赁系统开发实例 汽车租赁系统 Java 面向对象项目实战
本文介绍基于Java面向对象编程的汽车租赁系统技术方案与应用实例,涵盖系统功能需求分析、类设计、数据库设计及具体代码实现,帮助开发者掌握Java在实际项目中的应用。
116 0
|
3月前
|
安全 Java 数据库
Java 项目实战病人挂号系统网站设计开发步骤及核心功能实现指南
本文介绍了基于Java的病人挂号系统网站的技术方案与应用实例,涵盖SSM与Spring Boot框架选型、数据库设计、功能模块划分及安全机制实现。系统支持患者在线注册、登录、挂号与预约,管理员可进行医院信息与排班管理。通过实际案例展示系统开发流程与核心代码实现,为Java Web医疗项目开发提供参考。
206 2
|
3月前
|
JavaScript 安全 前端开发
Java开发:最新技术驱动的病人挂号系统实操指南与全流程操作技巧汇总
本文介绍基于Spring Boot 3.x、Vue 3等最新技术构建现代化病人挂号系统,涵盖技术选型、核心功能实现与部署方案,助力开发者快速搭建高效、安全的医疗挂号平台。
225 3
|
3月前
|
安全 Oracle Java
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
308 0
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
|
4月前
|
并行计算 Java API
Java List 集合结合 Java 17 新特性与现代开发实践的深度解析及实战指南 Java List 集合
本文深入解析Java 17中List集合的现代用法,结合函数式编程、Stream API、密封类、模式匹配等新特性,通过实操案例讲解数据处理、并行计算、响应式编程等场景下的高级应用,帮助开发者提升集合操作效率与代码质量。
222 1
|
4月前
|
安全 Java API
Java 17 及以上版本核心特性在现代开发实践中的深度应用与高效实践方法 Java 开发实践
本项目以“学生成绩管理系统”为例,深入实践Java 17+核心特性与现代开发技术。采用Spring Boot 3.1、WebFlux、R2DBC等构建响应式应用,结合Record类、模式匹配、Stream优化等新特性提升代码质量。涵盖容器化部署(Docker)、自动化测试、性能优化及安全加固,全面展示Java最新技术在实际项目中的应用,助力开发者掌握现代化Java开发方法。
209 1
|
3月前
|
移动开发 Cloud Native 安全
Java:跨平台之魂,企业级开发的磐石
Java:跨平台之魂,企业级开发的磐石