JD-Core - Java 反编译开发包


GPLv3
跨平台
Java

软件简介

JD-Core 是 Java 反编译开发包,基于这个开发包有一个 GUI 的项目 jd-
gui
和一个 Eclipse 插件项目 jd-
eclipse

编译 jd-core 的方法:

> git clone https://github.com/java-decompiler/jd-core.git
> cd jd-core
> ./gradlew build

使用方法:

  1. 实现 jd.core.loader.Loader 接口,
  2. 实现 jd.core.printer.Printer 接口,
  3. 调用方法 “decompile(loader, printer, internalTypeName);”

示例代码:

  1. Implement the Loader interface:

    Loader loader = new Loader() {
    @Override
    public byte[] load(String internalName) throws LoaderException {
    InputStream is = this.getClass().getResourceAsStream(“/” + internalName + “.class”);

        if (is == null) {
            return null;
        } else {
            try (InputStream in=is; ByteArrayOutputStream out=new ByteArrayOutputStream()) {
                byte[] buffer = new byte[1024];
                int read = in.read(buffer);
    
                while (read > 0) {
                    out.write(buffer, 0, read);
                    read = in.read(buffer);
                }
    
                return out.toByteArray();
            } catch (IOException e) {
                throw new LoaderException(e);
            }
        }
    }
    
    @Override
    public boolean canLoad(String internalName) {
        return this.getClass().getResource("/" + internalName + ".class") != null;
    }
    

    };

  2. Implement the Printer interface

    Printer printer = new Printer() {
    protected static final String TAB = ” “;
    protected static final String NEWLINE = “\n”;

    protected int indentationCount = 0;
    protected StringBuilder sb = new StringBuilder();
    
    @Override public String toString() { return sb.toString(); }
    
    @Override public void start(int maxLineNumber, int majorVersion, int minorVersion) {}
    @Override public void end() {}
    
    @Override public void printText(String text) { sb.append(text); }
    @Override public void printNumericConstant(String constant) { sb.append(constant); }
    @Override public void printStringConstant(String constant, String ownerInternalName) { sb.append(constant); }
    @Override public void printKeyword(String keyword) { sb.append(keyword); }
    @Override public void printDeclaration(int flags, String internalTypeName, String name, String descriptor) { sb.append(name); }
    @Override public void printReference(int flags, String internalTypeName, String name, String descriptor, String ownerInternalName) { sb.append(name); }
    
    @Override public void indent() { this.indentationCount++; }
    @Override public void unindent() { if (this.indentationCount > 0) this.indentationCount--; }
    
    @Override public void startLine(int lineNumber) { for (int i=0; i<indentationCount; i++) sb.append(TAB); }
    @Override public void endLine() { sb.append(NEWLINE); }
    @Override public void extraLine(int count) { while (count-- > 0) sb.append(NEWLINE); }
    
    @Override public void startMarker(int type) {}
    @Override public void endMarker(int type) {}
    

    };

  3. And call the method “decompile(loader, printer, internalTypeName);”

    ClassFileToJavaSourceDecompiler decompiler = new ClassFileToJavaSourceDecompiler();

    decompiler.decompile(loader, printer, “path/to/YourClass”);

    String source = printer.toString();