重写类装入器以获取每个加载的类字节和名称



是的,所以我试图做的是在运行时获取jvm加载的每个加载类的类字节。检测不适用于这种情况,因为 im 尝试加载的程序已加密了他的类文件并使用自己的类加载器加载它。

这是我的尝试:https://gist.github.com/MalikDz/944cae9c168fa05fbd0a

这里的输出(错误):https://gist.github.com/MalikDz/fdf20df16b951d41cb78

多谢!

您可以使用 Java 代理来执行此技巧:

代理非常简单:它注册一个类转换器,可以访问字节码:

import java.lang.instrument.Instrumentation;
import java.lang.instrument.ClassFileTransformer;
public class ClassDumpAgent
{
    /**
     * This method is called before the application’s main-method is called, when
     * this agent is specified to the Java VM.
     **/
    public static void premain(String agentArgs, Instrumentation inst)
    {
        ClassFileTransformer trans = new ClassDumpTransformer();
        inst.addTransformer(trans);
    }
}

使用的 ClassFileTransformer 只是将带有字节码的字节数组转储到文件系统:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
public class ClassDumpTransformer implements ClassFileTransformer
{
    private File rootFolder = new File("C:\temp\dump");
    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, 
                            ProtectionDomain protectionDomain, byte[] classfileBuffer)
            throws IllegalClassFormatException
    {
        File dumpFile = new File(rootFolder,className+".class");
        dumpFile.getParentFile().mkdirs();
        try {
            FileOutputStream out = new FileOutputStream(dumpFile);
            try {
                out.write(classfileBuffer);
            } finally {
                out.close();
            }
        } catch (IOException e) {
            throw new IllegalClassFormatException(e.getMessage());
        }
        return classfileBuffer;
    }
}

若要打包此类转储代理,需要对这两个类进行 JAR 并包含一个 MANIFEST。此代理的 MF

Manifest-Version: 1.0
PreMain-Class: ClassDumpAgent

若要使用此代理运行应用程序,请使用如下所示的命令行:

java -javaagent:cldumpagent.jar MyApplication

关于解决方案的一些评论:

  1. 这些类被转储到硬编码文件夹 (C:\TEMP\DUMP) 中,你可能想要更改此设置。
  2. 转换器将转储所有类,包括 JDK 运行时。您可能希望筛选转储的包。
  3. 小心逆向工程,在某些国家/地区,这可能被视为非法。

巴里

最新更新