解密 ClassFinal 加密的 Java Jar包

ClassFinal 是一款java class文件安全加密工具,支持直接加密jar包或war包,无需修改任何项目代码,兼容spring-framework;可避免源码泄漏或字节码被反编译。

要点

  • 拿到 password

    • 可能内置了

      • META-INF/.classes/org.springframework.config.Pass
    • 可能需要通过外部方式获取

      • 命令行参数或者环境变量或者拦截 Class 加载
    • 总的来说比较容易获取
  • 将 jar 添加到 classpath - 方便直接调用 net.roseboy.classfinal 内内容

    • 通过 IDE 或者通过命令行参数
  • 解压 jar 到当前 目录 tmp
  • 解密 class
  • 反编译得到 java
  • 添加 lib 目录到 classpath
  • 通过 IDEA 可直接调用原始 jar 里内容或直接启动 Application

    • 可能需要修改反编译后的 java 文件 - 部分反编译语法错误
package main;

import net.roseboy.classfinal.JarDecryptor;
import net.roseboy.classfinal.util.EncryptUtils;
import net.roseboy.classfinal.util.StrUtils;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class DecryptClassFinal {
    public static void main(String[] args) throws IOException {
        String src =System.getProperty("user.dir") +  "/tmp/META-INF/.classes";
        String dst = System.getProperty("user.dir") + "/src/main/class";

        File srcDir = new File(src);
        JarDecryptor.getInstance();
        // 默认 password 位置
        String pass = Files.readString(Path.of(src+"/org.springframework.config.Pass"));
        char[] password =  EncryptUtils.md5(pass.toCharArray());

        System.out.printf("src:%s\n", src);
        System.out.printf("dst:%s\n", dst);
        System.out.printf("password:%s\n", pass);

        if (srcDir.isDirectory()) {
            for (File file : srcDir.listFiles()) {
                String fp = file.getName();
                if (fp.startsWith("org.springframework")) {
                    continue;
                }

                byte[] fileBytes = Files.readAllBytes(file.toPath());
                byte[] out = dec(password, fp, fileBytes);

                String[] split = fp.split("[.]");
                String fn = split[split.length-1];

                String p = dst+"/"+ fp.substring(0, fp.lastIndexOf('.')).replaceAll("[.]", "/");
                new File(p).mkdirs();
                String f = p+"/"+ fn +".class";

                System.out.println("Write to: "+f+" Len:"+out.length);
                Files.write(new File(f).toPath(), out);
            }
        }

    }

    public static byte[] dec(char[] password, String fileName, byte[] bytes){
        char[] pass;
        pass = StrUtils.merger(new char[][]{password, fileName.toCharArray()});
        return  EncryptUtils.de(bytes, pass, 1);
    }
}

运行 main 后 src/main/class 目录下会生成解密后的 class 文件。

# 假设是 macOS 安装的 IDEA
# IDEA 自带的反编译工具解密即可
java -cp ~/Applications/IntelliJ\ IDEA\ Ultimate.app/Contents/plugins/java-decompiler/lib/java-decompiler.jar \
  org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler \
  -dgs=true \
  src/main/class/ src/main/java/

执行后 src/main/java 目录下会生成反编译后的 java 文件。

解压得到的 lib 目录(sprint-boot 的 jar),可以直接加入到 classpath 中,然后即可直接在代码中调用 jar 或者直接运行 Application。

标签: Java, 安全

相关文章

Java中线程池遇到父子任务示例及避坑

在Java中使用线程池可以有效地管理和调度线程,提高系统的并发处理能力。然而,当涉及到父子任务时,可能会遇到一些常见的Bug,特别是在子线程中查询数据并行处理时。本文将通过示例代码展示这些常见问...

java中异步任务的实现详解

在Java中实现异步任务是一种提高应用程序性能和响应性的常用技术。异步编程允许某些任务在等待其他任务完成时继续执行,从而避免了阻塞。本文将介绍几种在Java中实现异步任务的方法,并讨论它们的解决...

surge中配置wireguard客户端连接

surge还是挺好用的,不过最近研究内网穿透,想试试wireguard的设置,然后折腾了一下,虽然秒被封,但是至少这个配置是成功的,可以参考在surge中新建一个配置,内容按如下做调整即可[Pr...

图片Base64编码

CSR生成

图片无损放大

图片占位符

Excel拆分文件