diff --git a/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java b/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java index 206c3d597f640b5bc19622d979a6aa943c1f34b5..1ad92ba5e8c06184d13d790a6ac3de15e041d086 100644 --- a/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java +++ b/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java @@ -130,7 +130,7 @@ public class JadxCLIArgs { * Used to merge saved options and options passed in command line. */ public boolean overrideProvided(String[] args) { - JCommanderWrapper jcw = new JCommanderWrapper<>(new JadxCLIArgs()); + JCommanderWrapper jcw = new JCommanderWrapper<>(newInstance()); if (!jcw.parse(args)) { return false; } @@ -138,6 +138,10 @@ public class JadxCLIArgs { return process(jcw); } + protected JadxCLIArgs newInstance() { + return new JadxCLIArgs(); + } + private boolean process(JCommanderWrapper jcw) { if (printHelp) { jcw.printUsage(); diff --git a/jadx-gui/src/main/java/jadx/gui/JadxWrapper.java b/jadx-gui/src/main/java/jadx/gui/JadxWrapper.java index ce265ca180e932d5beb017223778d07bbec32376..6d87c99f897d6d7ae03152f9a5fb02e3f06a1397 100644 --- a/jadx-gui/src/main/java/jadx/gui/JadxWrapper.java +++ b/jadx-gui/src/main/java/jadx/gui/JadxWrapper.java @@ -8,8 +8,9 @@ import java.util.List; import java.util.concurrent.ThreadPoolExecutor; import java.util.stream.Collectors; -import javax.swing.*; +import javax.swing.ProgressMonitor; +import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -133,4 +134,13 @@ public class JadxWrapper { public JadxArgs getArgs() { return decompiler.getArgs(); } + + /** + * @param fullName Full name of an outer class. Inner classes are not supported. + * @return + */ + public @Nullable JavaClass searchJavaClassByClassName(String fullName) { + return decompiler.getClasses().stream().filter(cls -> cls.getFullName().equals(fullName)) + .findFirst().orElse(null); + } } diff --git a/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java b/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java index 8c3e3a2b71fc808fa508c11770010c6ad45057aa..c28a8237e9a6816ebd2b1f97c88f5b2406d69618 100644 --- a/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java +++ b/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java @@ -15,13 +15,15 @@ import java.util.Map; import java.util.Set; import java.util.function.Consumer; -import javax.swing.*; +import javax.swing.JFrame; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.beust.jcommander.Parameter; + import jadx.api.JadxArgs; import jadx.cli.JadxCLIArgs; import jadx.gui.ui.MainWindow; @@ -65,6 +67,10 @@ public class JadxSettings extends JadxCLIArgs { private int settingsVersion = 0; + @JadxSettingsAdapter.GsonExclude + @Parameter(names = { "-sc", "--select-class" }, description = "GUI: Open the selected class and show the decompiled code") + private String cmdSelectClass = null; + public static JadxSettings makeDefault() { JadxSettings jadxSettings = new JadxSettings(); jadxSettings.fixOnLoad(); @@ -96,6 +102,10 @@ public class JadxSettings extends JadxCLIArgs { } } + public String getCmdSelectClass() { + return cmdSelectClass; + } + public Path getLastOpenFilePath() { return lastOpenFilePath; } @@ -412,4 +422,8 @@ public class JadxSettings extends JadxCLIArgs { sync(); } + @Override + protected JadxCLIArgs newInstance() { + return new JadxSettings(); + } } diff --git a/jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsAdapter.java b/jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsAdapter.java index b3210b2b89dec61428a9b4241ecdab261fee7e91..3ecc9a7ab861ea7a81b0c0ed9f0b04519301eb00 100644 --- a/jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsAdapter.java +++ b/jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsAdapter.java @@ -1,6 +1,10 @@ package jadx.gui.settings; import java.awt.Rectangle; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import java.lang.reflect.Modifier; import java.nio.file.Path; import java.util.prefs.Preferences; @@ -31,7 +35,8 @@ public class JadxSettingsAdapter { public boolean shouldSkipField(FieldAttributes f) { return JadxSettings.SKIP_FIELDS.contains(f.getName()) || f.hasModifier(Modifier.PUBLIC) - || f.hasModifier(Modifier.TRANSIENT); + || f.hasModifier(Modifier.TRANSIENT) + || (f.getAnnotation(GsonExclude.class) != null); } @Override @@ -96,4 +101,12 @@ public class JadxSettingsAdapter { .create() .fromJson(json, type); } + + /** + * Annotation for specifying fields that should not be be saved/loaded + */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + public @interface GsonExclude { + } } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java index 941722e3a122aa68a8e09508ba4feee1730e9e76..b3bc86f0d580e424bd9d1342798f0433efe98145 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java @@ -67,6 +67,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import jadx.api.JadxArgs; +import jadx.api.JavaNode; import jadx.api.ResourceFile; import jadx.gui.JadxWrapper; import jadx.gui.jobs.BackgroundWorker; @@ -178,10 +179,25 @@ public class MainWindow extends JFrame { } }); + processCommandLineArgs(); + } + + private void processCommandLineArgs() { if (settings.getFiles().isEmpty()) { openFileOrProject(); } else { open(Paths.get(settings.getFiles().get(0))); + if (settings.getCmdSelectClass() != null) { + JavaNode javaNode = wrapper.searchJavaClassByClassName(settings.getCmdSelectClass()); + if (javaNode == null) { + JOptionPane.showMessageDialog(this, + NLS.str("msg.cmd_select_class_error", settings.getCmdSelectClass()), + NLS.str("error_dialog.title"), JOptionPane.ERROR_MESSAGE); + } else { + JNode node = cacheObject.getNodeCache().makeFrom(javaNode); + tabbedPane.codeJump(new JumpPosition(node.getRootClass(), node.getLine())); + } + } } } diff --git a/jadx-gui/src/main/resources/i18n/Messages_en_US.properties b/jadx-gui/src/main/resources/i18n/Messages_en_US.properties index 41580de351fea95c9b23f6fa4bf1b35f7eb53755..a9012e76bc0276d4b4f59ec6a035fd2e5b7f1d84 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_en_US.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_en_US.properties @@ -32,6 +32,8 @@ tree.sources_title=Source code tree.resources_title=Resources tree.loading=Loading... +error_dialog.title=Error + search.previous=Previous search.next=Next search.mark_all=Mark All @@ -131,6 +133,7 @@ msg.project_error_title=Error msg.project_error=Project could not be loaded msg.rename_disabled_title=Rename disabled msg.rename_disabled=Some of rename settings are disabled, please take this into consideration +msg.cmd_select_class_error=Failed to select the class\n%s\nThe class does not exist. popup.undo=Undo popup.redo=Redo diff --git a/jadx-gui/src/main/resources/i18n/Messages_es_ES.properties b/jadx-gui/src/main/resources/i18n/Messages_es_ES.properties index 575ae9c6da1b3a350f148c656f8b2a877df7f8fc..1ba1af99a1936178123826f63bdc27998ff0d3d6 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_es_ES.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_es_ES.properties @@ -32,6 +32,8 @@ tree.sources_title=Código fuente tree.resources_title=Recursos tree.loading=Cargando... +#error_dialog.title= + search.previous=Anterior search.next=Siguiente search.mark_all=Marcar todo @@ -131,6 +133,7 @@ msg.index_not_initialized=Índice no inicializado, ¡la bósqueda se desactivar #msg.project_error= #msg.rename_disabled_title= #msg.rename_disabled= +#msg.cmd_select_class_error= popup.undo=Deshacer popup.redo=Rehacer diff --git a/jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties b/jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties index b4da822110a3e214ea22bd71ff67afe4c65bb063..f3bbcf8348eb50b12a88089ad082aaa5d2c800e1 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties @@ -32,6 +32,8 @@ tree.sources_title=源代码 tree.resources_title=资源文件 tree.loading=稍等... +#error_dialog.title= + search.previous=上一个 search.next=下一个 search.mark_all=标记全部 @@ -131,6 +133,7 @@ msg.index_not_initialized=索引尚未初始化,无法进行搜索! #msg.project_error= #msg.rename_disabled_title= #msg.rename_disabled= +#msg.cmd_select_class_error= popup.undo=撤销 popup.redo=重做