Skip to content

Commit

Permalink
feat(gui): decompile to Jimple code (soot)
Browse files Browse the repository at this point in the history
  • Loading branch information
jpstotz committed May 15, 2019
1 parent 31a02a7 commit acd17b9
Show file tree
Hide file tree
Showing 12 changed files with 156 additions and 0 deletions.
2 changes: 2 additions & 0 deletions jadx-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@ dependencies {
}
compile 'com.google.guava:guava:27.1-jre'

compile 'ca.mcgill.sable:soot:3.3.0'

testCompile 'org.apache.commons:commons-lang3:3.8.1'
}
10 changes: 10 additions & 0 deletions jadx-core/src/main/java/jadx/api/JadxArgs.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ public class JadxArgs {

private boolean fsCaseSensitive;

private String sootAndroidJar;

public enum RenameEnum {
CASE, VALID, PRINTABLE
}
Expand Down Expand Up @@ -308,6 +310,14 @@ private void updateRenameFlag(boolean enabled, RenameEnum flag) {
}
}

public String getSootAndroidJar() {
return sootAndroidJar;
}

public void setSootAndroidJar(String sootAndroidJar) {
this.sootAndroidJar = sootAndroidJar;
}

@Override
public String toString() {
return "JadxArgs{" + "inputFiles=" + inputFiles
Expand Down
42 changes: 42 additions & 0 deletions jadx-core/src/main/java/jadx/api/JadxDecompiler.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package jadx.api;

import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
Expand All @@ -25,6 +28,12 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import soot.Main;
import soot.Printer;
import soot.Scene;
import soot.SootClass;
import soot.options.Options;

import jadx.core.Jadx;
import jadx.core.ProcessClass;
import jadx.core.dex.attributes.AFlag;
Expand Down Expand Up @@ -335,6 +344,39 @@ void generateSmali(ClassNode cls) {
}
}

public void generateJimple(ClassNode cls) {
try {
String jar = args.getSootAndroidJar();
if (jar == null || jar.trim().length() == 0) {
throw new RuntimeException("soot Android jar not set -> see Preferences");
}
Path jarPath = Paths.get(jar);
if (!Files.isRegularFile(jarPath)) {
throw new RuntimeException("soot Android jar not accessible: " + jarPath);
}

Options o = Options.v();
if (o.process_dir().size() == 0) {
Path path = cls.dex().getDexFile().getPath();
// Soot not initialized
o.set_process_multiple_dex(true);
o.set_allow_phantom_refs(true);
o.set_process_dir(Collections.singletonList(path.toAbsolutePath().toString()));
o.set_src_prec(Options.src_prec_apk);
o.set_force_android_jar(jarPath.toAbsolutePath().toString());
Main.v().autoSetOptions();
Scene.v().loadNecessaryClasses();
}
SootClass sootClass = Scene.v().getSootClass(cls.getFullName());
StringWriter sw = new StringWriter(4096);
PrintWriter writerOut = new PrintWriter(sw);
Printer.v().printTo(sootClass, writerOut);
cls.setJimple(sw.toString());
} catch (Exception e) {
cls.setJimple(e.toString());
}
}

RootNode getRoot() {
return root;
}
Expand Down
11 changes: 11 additions & 0 deletions jadx-core/src/main/java/jadx/api/JavaClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ public synchronized String getSmali() {
return cls.getSmali();
}

public String getJimple() {
if (decompiler == null) {
return null;
}
if (cls.getSmali() == null) {
decompiler.generateJimple(cls);
}
return cls.getJimple();
}

public synchronized void unload() {
cls.unload();
}
Expand Down Expand Up @@ -268,4 +278,5 @@ public int hashCode() {
public String toString() {
return getFullName();
}

}
12 changes: 12 additions & 0 deletions jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ public class ClassNode extends LineAttrNode implements ILoadable, ICodeNode {
private CodeWriter code;
// store smali
private String smali;

// store Soot Jimple code
private String jimple;

// store parent for inner classes or 'this' otherwise
private ClassNode parentClass;

Expand Down Expand Up @@ -483,6 +487,14 @@ public void setSmali(String smali) {
this.smali = smali;
}

public String getJimple() {
return jimple;
}

public void setJimple(String jimple) {
this.jimple = jimple;
}

public String getSmali() {
return smali;
}
Expand Down
18 changes: 18 additions & 0 deletions jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ public class JadxSettings extends JadxCLIArgs {

private Map<String, WindowLocation> windowPos = new HashMap<>();
private int mainWindowExtendedState = JFrame.NORMAL;

private String sootAndroidJar;

/**
* UI setting: the width of the tree showing the classes, resources, ...
*/
Expand Down Expand Up @@ -377,6 +380,14 @@ public void setMainWindowExtendedState(int mainWindowExtendedState) {
partialSync(settings -> settings.mainWindowExtendedState = mainWindowExtendedState);
}

public String getSootAndroidJar() {
return sootAndroidJar;
}

public void setSootAndroidJar(String sootAndroidJar) {
this.sootAndroidJar = sootAndroidJar;
}

private void upgradeSettings(int fromVersion) {
LOG.debug("upgrade settings from version: {} to {}", fromVersion, CURRENT_SETTINGS_VERSION);
if (fromVersion == 0) {
Expand Down Expand Up @@ -430,6 +441,13 @@ private void upgradeSettings(int fromVersion) {
sync();
}

@Override
public JadxArgs toJadxArgs() {
JadxArgs jadxArgs = super.toJadxArgs();
jadxArgs.setSootAndroidJar(this.sootAndroidJar);
return jadxArgs;
}

@Override
protected JadxCLIArgs newInstance() {
return new JadxSettings();
Expand Down
25 changes: 25 additions & 0 deletions jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
import java.util.Collection;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -293,6 +296,27 @@ private SettingsGroup makeDecompilationGroup() {
needReload();
});

JTextField sootAndroidJar = new JTextField();
sootAndroidJar.setText(StringUtils.defaultString(settings.getSootAndroidJar()));
sootAndroidJar.getDocument().addDocumentListener(new DocumentListener() {

@Override
public void insertUpdate(DocumentEvent e) {
changedUpdate(e);
}

@Override
public void removeUpdate(DocumentEvent e) {
changedUpdate(e);
}

@Override
public void changedUpdate(DocumentEvent e) {
settings.setSootAndroidJar(sootAndroidJar.getText());
needReload();
}
});

SpinnerNumberModel spinnerModel = new SpinnerNumberModel(
settings.getThreadsCount(), 1, Runtime.getRuntime().availableProcessors() * 2, 1);
JSpinner threadsCount = new JSpinner(spinnerModel);
Expand Down Expand Up @@ -375,6 +399,7 @@ private SettingsGroup makeDecompilationGroup() {
other.addRow(NLS.str("preferences.fsCaseSensitive"), fsCaseSensitive);
other.addRow(NLS.str("preferences.fallback"), fallback);
other.addRow(NLS.str("preferences.skipResourcesDecode"), resourceDecode);
other.addRow("Soot Android JAR file: ", sootAndroidJar);
return other;
}

Expand Down
5 changes: 5 additions & 0 deletions jadx-gui/src/main/java/jadx/gui/treemodel/JClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ public String getSmali() {
return cls.getSmali();
}

@Override
public String getJimple() {
return cls.getJimple();
}

@Override
public String getSyntaxName() {
return SyntaxConstants.SYNTAX_STYLE_JAVA;
Expand Down
4 changes: 4 additions & 0 deletions jadx-gui/src/main/java/jadx/gui/treemodel/JNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ public String getSmali() {
return null;
}

public String getJimple() {
return null;
}

public String getSyntaxName() {
return SyntaxConstants.SYNTAX_STYLE_NONE;
}
Expand Down
3 changes: 3 additions & 0 deletions jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import soot.G;

import jadx.api.JadxArgs;
import jadx.api.JavaNode;
import jadx.api.ResourceFile;
Expand Down Expand Up @@ -368,6 +370,7 @@ private void update() {
}

protected void resetCache() {
G.reset();
cacheObject.reset();
// TODO: decompilation freezes sometime with several threads
int threadsCount = settings.getThreadsCount();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,22 @@ public final class ClassCodeContentPanel extends AbstractCodeContentPanel {

private final CodePanel javaCodePanel;
private final CodePanel smaliCodePanel;
private final CodePanel jimpleCodePanel;

private JTabbedPane areaTabbedPane = new JTabbedPane(JTabbedPane.BOTTOM);

public ClassCodeContentPanel(TabbedPane panel, JNode jnode) {
super(panel, jnode);

javaCodePanel = new CodePanel(this, new CodeArea(this));
smaliCodePanel = new CodePanel(this, new SmaliArea(this));
jimpleCodePanel = new CodePanel(this, new JimpleArea(this));

setLayout(new BorderLayout());

areaTabbedPane.add(javaCodePanel, NLS.str("tabs.code"));
areaTabbedPane.add(smaliCodePanel, NLS.str("tabs.smali"));
areaTabbedPane.add(jimpleCodePanel, "Jimple");
add(areaTabbedPane);

javaCodePanel.load();
Expand Down
20 changes: 20 additions & 0 deletions jadx-gui/src/main/java/jadx/gui/ui/codearea/JimpleArea.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package jadx.gui.ui.codearea;

import jadx.gui.ui.ContentPanel;

public final class JimpleArea extends AbstractCodeArea {
private static final long serialVersionUID = -747171470554800028L;

JimpleArea(ContentPanel contentPanel) {
super(contentPanel);
setEditable(false);
}

@Override
public void load() {
if (getText().isEmpty()) {
setText(node.getJimple());
setCaretPosition(0);
}
}
}

0 comments on commit acd17b9

Please sign in to comment.