-
Notifications
You must be signed in to change notification settings - Fork 55
Usage
JADXecute is a plugin integrated into the latest version of JADX. To use, simply download the release from this repository and execute it as usual. Once JADX is open, locate the coffee cup icon in the top left corner and click it.
Upon clicking, the JADXecute dialog will appear:
Once you've written your code, hit run and you should either see successful console output or the list of code compilation errors that Java encountered when compiling your jadx-scripting code.
In order for JADXecute to be able to execute your dynamic code, you must declare your class with:
public static String userCodeMain(MainWindow mainWindow)
Also, don't forget to include any imports you need as you normally would in Java code!
To print values to the console window, you must append them to the string value that is returned by the "userCodeMain" function in the JADXecute window. In the sample code, this string is named jadxecuteOutput. After your code has successfully run, the console displays the final value of this string. Optionally, you could also create a logger object for the class if you would prefer to print values to the JADX Log Viewer.
If your code has a compiler error, the console will display the Java error message:
Additionally, if your program fails during execution, the stack trace is printed to the console.
Alternatively, JADXecute allows you to import your own Java file. To do so, click the "Browse" button and select the desired Java file. The code in the "Java Input" section will update accordingly. Remember to click "Run" once you are ready to execute your script.
If you are already familiar with the JADX API, start with the following template and add code as you normally would to call JADX API methods:
import jadx.gui.ui.MainWindow;
public class UserCodeClass {
public static String userCodeMain(MainWindow mainWindow) {
String jadxScriptingOutput = "";
// Your code goes here!
return jadxScriptingOutput;
}
}
Utilize the examples below as a starting point for your JADXecute coding. Look for comments labeled "Update here" in the code to identify locations where you should edit the code to match your method or class names. All these examples can be modified and expanded upon.
Find many more examples inside jadx.gui.JadxWrapper or in the JADX API classes! Use the following code as an example for initializing and using the JadxWrapper class:
import jadx.gui.ui.MainWindow;
import jadx.gui.JadxWrapper;
import jadx.api.JavaClass;
public class UserCodeClass {
public static String userCodeMain(MainWindow mainWindow) {
String jadxecuteOutput = "Example output...";
JadxWrapper wrapper = mainWindow.getWrapper();
// Here's an example of using the wrapper object. Update here!
for (JavaClass cls : wrapper.getClasses()) {
jadxecuteOutput += cls.getName() + "\n";
}
return jadxecuteOutput;
}
}
import jadx.gui.ui.MainWindow;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.RootNode;
import java.util.List;
public class UserCodeClass {
public static String userCodeMain(MainWindow mainWindow) {
String jadxecuteOutput = "";
// Add all strings to the jadxecute output to be printed
RootNode root = mainWindow.getWrapper().getDecompiler().getRoot();
List<ClassNode> classes = root.getClasses();
for (ClassNode cls : classes) {
jadxecuteOutput += cls.getFullName() + "\n";
}
return jadxecuteOutput;
}
}
import jadx.gui.ui.MainWindow;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.nodes.RootNode;
import java.util.List;
public class UserCodeClass {
public static String userCodeMain(MainWindow mainWindow) {
String jadxecuteOutput = "";
ClassNode selectedClassNode = null;
String searchClassName = "exampleClassName"; // Update this
// Add all strings to the jadxecute output to be printed
RootNode root = mainWindow.getWrapper().getDecompiler().getRoot();
List<ClassNode> classes = root.getClasses();
for (ClassNode cls : classes) {
if (cls.getFullName().contains(searchClassName)) {
jadxecuteOutput += "Found class: " + cls.getFullName() + "\n";
selectedClassNode = cls;
}
}
if (selectedClassNode != null) {
jadxecuteOutput += "Methods:\n";
// Print all methods in the selected class
for (MethodNode method : selectedClassNode.getMethods()) {
jadxecuteOutput += method.getAlias() + "\n"; // Use the alias since this includes user updates
}
} else {
jadxecuteOutput += "Could not find class " + searchClassName;
}
return jadxecuteOutput;
}
}
import jadx.gui.ui.MainWindow;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.FieldNode;
import jadx.core.dex.nodes.RootNode;
import java.util.List;
public class UserCodeClass {
public static String userCodeMain(MainWindow mainWindow) {
String jadxecuteOutput = "";
ClassNode selectedClassNode = null;
String searchClassName = "exampleClassName"; // Update this
// Add all strings to the jadxecute output to be printed
RootNode root = mainWindow.getWrapper().getDecompiler().getRoot();
List<ClassNode> classes = root.getClasses();
for (ClassNode cls : classes) {
if (cls.getFullName().contains(searchClassName)) {
jadxecuteOutput += "Found class: " + cls.getFullName() + "\n";
selectedClassNode = cls;
}
}
if (selectedClassNode != null) {
jadxecuteOutput += "Fields:\n";
// Print all field in the selected class
for (FieldNode field : selectedClassNode.getFields()) {
jadxecuteOutput += field.getAlias() + "\n"; // Use the alias since this includes user updates
}
} else {
jadxecuteOutput += "Could not find class " + searchClassName;
}
return jadxecuteOutput;
}
}
import jadx.gui.ui.MainWindow;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.RootNode;
import java.util.List;
import jadx.core.dex.instructions.args.ArgType;
public class UserCodeClass {
public static String userCodeMain(MainWindow mainWindow) {
String jadxecuteOutput = "";
String searchClassName = "IntentService"; // Update this
ArgType superClassType = null;
// Add all strings to the jadxecute output to be printed
RootNode root = mainWindow.getWrapper().getDecompiler().getRoot();
List<ClassNode> classes = root.getClasses();
jadxecuteOutput += "Classes extending " + searchClassName + ":\n";
for (ClassNode cls : classes) {
superClassType = cls.getSuperClass();
if (superClassType != null && superClassType.toString().contains(searchClassName)) {
jadxecuteOutput += cls.getFullName() + "\n";
}
}
return jadxecuteOutput;
}
}
import jadx.gui.ui.MainWindow;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.RootNode;
import java.util.List;
public class UserCodeClass {
public static String userCodeMain(MainWindow mainWindow) {
String jadxecuteOutput = "";
String searchClassName = "exampleClassName"; // Update this
// Loop through all classes and add desired name to return output
RootNode root = mainWindow.getWrapper().getDecompiler().getRoot();
List<ClassNode> classes = root.getClasses();
for (ClassNode cls : classes) {
// Example: finds all user-renamed classes renamed like "mw_MyClassA"
if (cls.getFullName().contains(searchClassName)) {
jadxecuteOutput += cls.getFullName() + "\n";
}
}
return jadxecuteOutput;
}
}
import jadx.gui.ui.MainWindow;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.RootNode;
import java.util.List;
import jadx.gui.treemodel.JClass;
import jadx.api.JavaClass;
import jadx.gui.plugins.jadxecute.RenameObjectHelper;
public class UserCodeClass {
public static String userCodeMain(MainWindow mainWindow) {
String jadxecuteOutput = "";
String searchClassName = "exampleClassName"; // Update this
// Find desired class
RootNode root = mainWindow.getWrapper().getDecompiler().getRoot();
List<ClassNode> classes = root.getClasses();
for (ClassNode cls : classes) {
if (cls.getFullName().contains(searchClassName)) {
RenameObjectHelper renameObjectHelper = new RenameObjectHelper();
JClass jclass = new JClass(cls.getJavaNode());
// Rename found class to desired name
jadxecuteOutput += renameObjectHelper.renameObject(mainWindow, jclass, "newClassName");
// Optionally return here or you could add functionality to change all
// matched objects to different names and return out of the loop
return jadxecuteOutput;
}
}
return jadxecuteOutput;
}
}
import jadx.gui.ui.MainWindow;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.RootNode;
import java.util.List;
import jadx.gui.treemodel.JClass;
import jadx.api.JavaClass;
import jadx.gui.plugins.jadxecute.RenameObjectHelper;
public class UserCodeClass {
public static String userCodeMain(MainWindow mainWindow) {
String jadxecuteOutput = "";
String searchClassName = "exampleClassName"; // Update this
// Find desired class
RootNode root = mainWindow.getWrapper().getDecompiler().getRoot();
List<ClassNode> classes = root.getClasses();
for (ClassNode cls : classes) {
if (cls.getFullName().contains(searchClassName)) {
RenameObjectHelper renameObjectHelper = new RenameObjectHelper();
jadxecuteOutput += "Found class " + searchClassName + ":\n\n";
jadxecuteOutput += cls.getJavaNode().getCodeInfo().toString();
return jadxecuteOutput;
}
}
return jadxecuteOutput;
}
}
Note: This is based on the smali index of the instruction, but will appear in the Java code. The smali index for the method starts from 0 as the first instruction. Select a blank line in the smali code within your corresponding Java line number to have the comment appear in the decompilation.
import jadx.gui.ui.MainWindow;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.nodes.RootNode;
import java.util.List;
import jadx.gui.plugins.jadxecute.AddCommentHelper;
public class UserCodeClass {
public static String userCodeMain(MainWindow mainWindow) {
String jadxecuteOutput = "";
ClassNode selectedClassNode = null;
MethodNode selectedMethodNode = null;
String searchClassName = "exampleClassName"; // Update this
String searchMethodName = "exampleMethodName"; // Update this
String commentToAdd = "This is a new comment!"; // Update this
int smaliInstructionIndex = 0; // Update this
// Add all strings to the jadxecute output to be printed
RootNode root = mainWindow.getWrapper().getDecompiler().getRoot();
List<ClassNode> classes = root.getClasses();
for (ClassNode cls : classes) {
if (cls.getFullName().contains(searchClassName)) {
jadxecuteOutput += "Found class: " + cls.getFullName() + "\n";
selectedClassNode = cls;
}
}
if (selectedClassNode != null) {
for (MethodNode method : selectedClassNode.getMethods()) {
if (method.getAlias().contains(searchMethodName)) {
jadxecuteOutput += "Found method: " + method.getAlias() + "\n";
selectedMethodNode = method;
}
}
// Add the comment if the method was found
if (selectedMethodNode != null) {
AddCommentHelper addCommentHelper = new AddCommentHelper(mainWindow, selectedMethodNode.getJavaNode());
jadxecuteOutput += addCommentHelper.addInstructionComment(commentToAdd, smaliInstructionIndex);
}
} else {
jadxecuteOutput += "Could not find class " + searchClassName;
}
return jadxecuteOutput;
}
}