Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add JADX decompiler #27

Merged
merged 11 commits into from
Mar 10, 2024
11 changes: 11 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ dependencies {
implementation "net.fabricmc:cfr:${fabric_cfr_version}"
implementation "org.vineflower:vineflower:${vineflower_version}"
implementation "org.bitbucket.mstrobel:procyon-compilertools:${procyon_version}"
implementation ("io.github.skylot:jadx-core:${jadx_version}") {
exclude group: 'com.android.tools.build', module: 'aapt2-proto'
}
implementation ("io.github.skylot:jadx-java-input:${jadx_version}") {
exclude group: 'io.github.skylot', module: 'raung-disasm'
}
runtimeOnly "org.tinylog:tinylog-impl:${tinylog_version}"
runtimeOnly "org.tinylog:slf4j-tinylog:${tinylog_version}"

Expand Down Expand Up @@ -97,6 +103,11 @@ extraJavaModuleInfo {

// Procyon
automaticModule("org.bitbucket.mstrobel:procyon-compilertools", "procyon.compilertools")

// JADX
automaticModule("io.github.skylot:jadx-core", "jadx.core")
automaticModule("io.github.skylot:jadx-plugins-api", "jadx.plugins.api")
automaticModule("io.github.skylot:jadx-java-input", "jadx.plugins.java_input")
}

application {
Expand Down
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ asm_version = 9.6
fabric_cfr_version = 0.2.1
vineflower_version = 1.9.3
procyon_version = 0.6.0
jadx_version = 1.4.7
mappingio_version = 0.5.0
javaparser_version = 3.25.6
javafx_version = 21.0.1
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/matcher/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.io.Closeable;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UncheckedIOException;
import java.net.URI;
import java.net.URISyntaxException;
Expand Down Expand Up @@ -48,6 +50,15 @@ public static <T> Set<T> copySet(Set<T> set) {
}
}

public static String getStackTrace(Throwable t) {
if (t == null) return null;

StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
return sw.toString();
}

public static FileSystem iterateJar(Path archive, boolean autoClose, Consumer<Path> handler) {
boolean existing = false;
FileSystem fs = null;
Expand Down
1 change: 1 addition & 0 deletions src/main/java/matcher/srcprocess/BuiltinDecompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
public enum BuiltinDecompiler {
CFR("CFR", Cfr::new),
VINEFLOWER("Vineflower", Vineflower::new),
JADX("JADX", Jadx::new),
PROCYON("Procyon", Procyon::new);

BuiltinDecompiler(String name, Supplier<? extends Decompiler> supplier) {
Expand Down
75 changes: 75 additions & 0 deletions src/main/java/matcher/srcprocess/Jadx.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package matcher.srcprocess;

import java.io.IOException;
import java.util.function.Consumer;

import jadx.api.CommentsLevel;
import jadx.api.JadxArgs;
import jadx.api.JadxDecompiler;
import jadx.api.impl.NoOpCodeCache;
import jadx.api.plugins.input.data.IClassData;
import jadx.api.plugins.input.data.ILoadResult;
import jadx.api.plugins.input.data.IResourceData;
import jadx.plugins.input.java.JavaClassReader;
import jadx.plugins.input.java.data.JavaClassData;

import matcher.NameType;
import matcher.Util;
import matcher.type.ClassFeatureExtractor;
import matcher.type.ClassInstance;

public class Jadx implements Decompiler {
@Override
public String decompile(ClassInstance cls, ClassFeatureExtractor env, NameType nameType) {
String errorMessage = null;
final String fullClassName = cls.getName(NameType.PLAIN, true);

try (JadxDecompiler jadx = new JadxDecompiler(jadxArgs)) {
jadx.addCustomLoad(new ILoadResult() {
@Override
public void close() throws IOException { }

@Override
public void visitClasses(Consumer<IClassData> consumer) {
consumer.accept(new JavaClassData(new JavaClassReader(0,
fullClassName + ".class", cls.serialize(nameType))));
}

@Override
public void visitResources(Consumer<IResourceData> consumer) { }

@Override
public boolean isEmpty() {
return false;
}
});
jadx.load();

assert jadx.getClassesWithInners().size() == 1;
return jadx.getClassesWithInners().get(0).getCode();
} catch (Exception e) {
errorMessage = Util.getStackTrace(e);
}

throw new RuntimeException(errorMessage != null ? errorMessage : "JADX couldn't find the requested class");
}

private static final JadxArgs jadxArgs;

static {
jadxArgs = new JadxArgs() {
@Override
public void close() {
return;
}
};
jadxArgs.setCodeCache(NoOpCodeCache.INSTANCE);
jadxArgs.setShowInconsistentCode(true);
jadxArgs.setInlineAnonymousClasses(false);
jadxArgs.setInlineMethods(false);
jadxArgs.setSkipResources(true);
jadxArgs.setRenameValid(false);
jadxArgs.setRespectBytecodeAccModifiers(true);
jadxArgs.setCommentsLevel(CommentsLevel.INFO);
}
}
3 changes: 3 additions & 0 deletions src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
requires org.objectweb.asm.tree.analysis;
requires org.objectweb.asm.util;
requires procyon.compilertools;
requires jadx.core;
requires jadx.plugins.api;
requires jadx.plugins.java_input;
requires transitive net.fabricmc.mappingio;

uses matcher.Plugin;
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/tinylog-dev.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
writer = console
writer.format = {date: HH:mm:ss.SSS} [{thread}/{level}]: {message}
writer.level = debug

level@jadx = warn
2 changes: 2 additions & 0 deletions src/main/resources/tinylog.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
writer = console
writer.format = {date: HH:mm:ss} [{level}]: {message}
writer.level = info

level@jadx = error
Loading