吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 217|回复: 0
上一主题 下一主题
收起左侧

[学习记录] java动态获取class

[复制链接]
跳转到指定楼层
楼主
李朗8 发表于 2026-2-15 15:15 回帖奖励

在只有 jar包 的情况下,动态获取 claaa
OS: Linux
JDK: 1.8.0_201、21.07

Arthas

https://github.com/alibaba/arthas/releases

java -jar burpsuite_pro.jar                                 // 启动目标 jar包
java -jar arthas-boot.jar                                    // 启动 Arthas,并选择 目标进程
sc burp.* > classList                                        // 查看指定 class列表,并输出到 classList
dump burp.qzo -d CLASS                                       // dump 指定class,到 CLASS目录下

心得
1、比JDK自带的顺手,8 或 21 下运行,终端输出,差异明显

sa-jdi.jar

// JDK9之前,位置:JAVA_HOME/lib/sa-jdi.jar
// CLHSDB(命令行)        HSDB(图形版)

java -cp $JAVA_HOME/lib/sa-jdi.jar sun.jvm.hotspot.CLHSDB        // 启动 Hotspot Debugger
java -jar burpsuite_pro.jar
jps -l 
hsdb> attach 5011
hsdb> classes > classList                                       // 查看所有 class,输出到 classList
hsdb> class burp.qzo                                           // 查看指定 class
burp/qzo @0x00000007c03fdc28
hsdb> dumpclass burp.qzo                                       // dump 指定class     ./burp/qzo.class

心得
1、只支持 JDK8
2、dump出来的class,与 Arthas的差异明显

jhsdb

// JDK8之后,位置:JAVA_HOME/bin/jhsdb                                // 用于取代 sa-jdi.jar

jhsdb --help
    clhsdb                          command line debugger
    hsdb                            ui debugger
    debugd --help                   to get more information
    jstack --help                   to get more information
    jmap   --help                   to get more information
    jinfo  --help                   to get more information
    jsnap  --help                   to get more information

jhsdb clhsdb                                                       // 启动命令行 hsdb
java -jar burpsuite_pro.jar
jcmd -l
hsdb> attach 2197
hsdb> classes > class.txt
hsdb> class burp/Zto
burp/Zto @0x00007f0b404bdab8
hsdb> dumpclass burp/Zto

心得
1、只 dumpclass,与 sa-jdi.jar 差异不大,也有图形版
2、jhsdb 其它工具功能挺强大,值得研究

ClassFileTransformer

import java.io.File;
import java.io.FileOutputStream;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;

public class ClassDumpAgent implements ClassFileTransformer {

    private static final String OUT_DIR = "dumpdir";
    private static final String[] EXCLUDED_PREFIXES = { "java/", "javax/", "sun/", "com/", "org/", "net/", "io/",
            "jdk/", "javafx/" };

    static {
        File dir = new File(OUT_DIR);

        if (!dir.exists()) {
            boolean created = dir.mkdir(); // 使用mkdir()创建目录
            if (!created) {
                System.err.println("无法创建目录: " + OUT_DIR);
            }
        }
        System.out.println("创建目录 " + OUT_DIR);
    }

    private static void saveClass(String className, byte[] classfileBuffer) throws Exception {

        System.out.println("开始saveClass()");
        // 文件路径转为类名,连接符(win、linux 用 / 连接)
        String fileName = OUT_DIR + "/" + className.replace("/", ".") + ".class";
        File classFile = new File(fileName);

        try (FileOutputStream fos = new FileOutputStream(classFile)) {
            fos.write(classfileBuffer);
        }
    }

    // 注册 ClassFileTransformer
    @Override
    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
            ProtectionDomain protectionDomain, byte[] classfileBuffer) {

        // loader == null 会过滤JDK系统核心类(java、javax、sun、com ......)
        if (loader == null) {
            return null;// 告诉JVM,不修改
        }

        // loader == null 与 EXCLUDED_PREFIXES 有重复,但更好用
        for (String prefix : EXCLUDED_PREFIXES) {
            if (className.startsWith(prefix)) {
                return null;
            }
        }

        if (classfileBuffer.length == 111989) {
            System.out.println("过滤后  " + loader + "     " + className + "       " + classfileBuffer.length);
        } else {
            return null;
        }

        try {
            saveClass(className, classfileBuffer);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void premain(String agentArgs, Instrumentation inst) throws Exception {
        System.out.println("进入 premain()");
        ClassDumpAgent cda = new ClassDumpAgent();
        inst.addTransformer(cda);
    }

}

// MANIFEST.MF

Premain-Class: ClassDumpAgent
...............                                // 此处需有1空行
// JDK8
javac -g ClassDumpAgent.java
jar cfmv ClassDumpAgent.jar MANIFEST.MF ClassDumpAgent.class

java -javaagent:ClassDumpAgent.jar -jar burpsuite_pro.jar                     // 会在当前目录生成指定 class

心得
可在 transform()中进行过滤,自定义性强

java.lang.ClassLoader

// JDK8,获取源码
cp $JAVA_HOME/src.zip .

// 粘出 java/lang/ClassLoader.java,并改写 defineClass(){}

protected final Class<?> defineClass(String name, byte[] b, int off, int len)
            throws ClassFormatError {

        if (len == 111989) {
            String classFileName = name.replace("/", ".") + ".class";
            File classFile = new File(classFileName);
            try (java.io.FileOutputStream fos = new java.io.FileOutputStream(classFile)) {
                fos.write(b, off, len);
            } catch (IOException e) {
                System.err.println("Error writing class file: " + e.getMessage());
                e.printStackTrace();
            }
        }
        return defineClass(name, b, off, len, null);
    }
// 创建目录,放入 ClassLoader.java
mkdir -p java/lang                mv ClassLoader.java java/lang/

// 创建 out,并编译
mkdir out
javac -g -bootclasspath $JAVA_HOME/jre/lib/rt.jar -sourcepath . java/lang/ClassLoader.java -d out

// 进入 out,并打包
jar cfv Loader.jar .

// dump 指定 .class
java -noverify -Xbootclasspath/p:Loader.jar -jar burpsuite_pro.jar             // 会在当前目录生成指定 class

心得
自定义性强,目前在 JDK8上测试通过

最终心得
1、dump all or one,java.lang.ClassLoader 或 ClassFileTransformer 都行
2、java.lang.ClassLoader、ClassFileTransformer、Arthas 与 JDK自带工具dump的结果,差异挺大
3、猜测这3种方式是在 JVM之外进行 dump,JDK自带的是在 JVM之内进行 dump

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-2-20 14:32

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表