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 7fe73ef841c..723ae1dd694 100644 --- a/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java +++ b/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java @@ -52,7 +52,7 @@ public class JadxSettings extends JadxCLIArgs { private static final Path USER_HOME = Paths.get(System.getProperty("user.home")); private static final int RECENT_PROJECTS_COUNT = 30; - private static final int CURRENT_SETTINGS_VERSION = 18; + private static final int CURRENT_SETTINGS_VERSION = 19; private static final Font DEFAULT_FONT = new RSyntaxTextArea().getFont(); @@ -110,6 +110,8 @@ public class JadxSettings extends JadxCLIArgs { private boolean jumpOnDoubleClick = true; + private XposedCodegenLanguage xposedCodegenLanguage = XposedCodegenLanguage.JAVA; + /** * UI setting: the width of the tree showing the classes, resources, ... */ @@ -732,6 +734,14 @@ public void setDockLogViewer(boolean dockLogViewer) { partialSync(settings -> this.dockLogViewer = dockLogViewer); } + public XposedCodegenLanguage getXposedCodegenLanguage() { + return xposedCodegenLanguage; + } + + public void setXposedCodegenLanguage(XposedCodegenLanguage language) { + this.xposedCodegenLanguage = language; + } + private void upgradeSettings(int fromVersion) { LOG.debug("upgrade settings from version: {} to {}", fromVersion, CURRENT_SETTINGS_VERSION); if (fromVersion <= 10) { @@ -769,6 +779,10 @@ private void upgradeSettings(int fromVersion) { checkForUpdates = true; fromVersion++; } + if (fromVersion == 18) { + xposedCodegenLanguage = XposedCodegenLanguage.JAVA; + fromVersion++; + } if (fromVersion != CURRENT_SETTINGS_VERSION) { LOG.warn("Incorrect settings upgrade. Expected version: {}, got: {}", CURRENT_SETTINGS_VERSION, fromVersion); } diff --git a/jadx-gui/src/main/java/jadx/gui/settings/XposedCodegenLanguage.kt b/jadx-gui/src/main/java/jadx/gui/settings/XposedCodegenLanguage.kt new file mode 100644 index 00000000000..6ef40fab99c --- /dev/null +++ b/jadx-gui/src/main/java/jadx/gui/settings/XposedCodegenLanguage.kt @@ -0,0 +1,6 @@ +package jadx.gui.settings + +enum class XposedCodegenLanguage { + JAVA, + KOTLIN, +} diff --git a/jadx-gui/src/main/java/jadx/gui/settings/ui/JadxSettingsWindow.java b/jadx-gui/src/main/java/jadx/gui/settings/ui/JadxSettingsWindow.java index 044d5c610ce..bbb55785ad9 100644 --- a/jadx-gui/src/main/java/jadx/gui/settings/ui/JadxSettingsWindow.java +++ b/jadx-gui/src/main/java/jadx/gui/settings/ui/JadxSettingsWindow.java @@ -38,6 +38,7 @@ import javax.swing.SwingUtilities; import javax.swing.WindowConstants; +import jadx.gui.settings.XposedCodegenLanguage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -622,6 +623,13 @@ private SettingsGroup makeOtherGroup() { needReload(); }); + JComboBox xposedCodegenLanguage = new JComboBox<>(XposedCodegenLanguage.getEntries().toArray(new XposedCodegenLanguage[0])); + xposedCodegenLanguage.setSelectedItem(settings.getXposedCodegenLanguage()); + xposedCodegenLanguage.addActionListener(e -> { + settings.setXposedCodegenLanguage((XposedCodegenLanguage) xposedCodegenLanguage.getSelectedItem()); + mainWindow.loadSettings(); + }); + SettingsGroup group = new SettingsGroup(NLS.str("preferences.other")); group.addRow(NLS.str("preferences.lineNumbersMode"), lineNumbersMode); group.addRow(NLS.str("preferences.jumpOnDoubleClick"), jumpOnDoubleClick); @@ -629,6 +637,7 @@ private SettingsGroup makeOtherGroup() { group.addRow(NLS.str("preferences.check_for_updates"), update); group.addRow(NLS.str("preferences.cfg"), cfg); group.addRow(NLS.str("preferences.raw_cfg"), rawCfg); + group.addRow(NLS.str("preferences.xposed_codegen_language"), xposedCodegenLanguage); return group; } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/XposedAction.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/XposedAction.java index e8e51414c2e..698b39f10c6 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/XposedAction.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/XposedAction.java @@ -6,6 +6,7 @@ import javax.swing.JOptionPane; +import jadx.gui.settings.XposedCodegenLanguage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -85,7 +86,8 @@ private String generateMethodSnippet(JMethod jMth) { methodName = "\"" + mth.getMethodInfo().getName() + "\", "; } String rawClassName = javaMethod.getDeclaringClass().getRawName(); - String xposedFormatStr = "XposedHelpers.%s(\"%s\", classLoader, %snew XC_MethodHook() {\n" + String javaXposedFormatStr = + "XposedHelpers.%s(\"%s\", classLoader, %snew XC_MethodHook() {\n" + " @Override\n" + " protected void beforeHookedMethod(MethodHookParam param) throws Throwable {\n" + " super.beforeHookedMethod(param);\n" @@ -95,6 +97,29 @@ private String generateMethodSnippet(JMethod jMth) { + " super.afterHookedMethod(param);\n" + " }\n" + "});"; + String kotlinXposedFormatStr = + "XposedHelpers.%s(\"%s\", classLoader, %sobject : XC_MethodHook() {\n" + + " override fun beforeHookedMethod(param: MethodHookParam) {\n" + + " super.beforeHookedMethod(param)\n" + + " }\n" + + "\n" + + " override fun afterHookedMethod(param: MethodHookParam) {\n" + + " super.afterHookedMethod(param)\n" + + " }\n" + + "})"; + + XposedCodegenLanguage language = getLanguage(); + String xposedFormatStr; + switch (language) { + case JAVA: + xposedFormatStr = javaXposedFormatStr; + break; + case KOTLIN: + xposedFormatStr = kotlinXposedFormatStr; + break; + default: + throw new JadxRuntimeException("Invalid Xposed code generation language: " + language); + } List mthArgs = mth.getArgTypes(); if (mthArgs.isEmpty()) { @@ -119,9 +144,28 @@ private String generateClassSnippet(JClass jc) { JavaClass javaClass = jc.getCls(); String rawClassName = javaClass.getRawName(); String shortClassName = javaClass.getName(); - return String.format("ClassLoader classLoader = lpparam.classLoader;\n" - + "Class %sClass = classLoader.loadClass(\"%s\");", - shortClassName, rawClassName); + + String javaXposedFormatStr = + "ClassLoader classLoader = lpparam.classLoader;\n" + + "Class %sClass = classLoader.loadClass(\"%s\");"; + String kotlinXposedFormatStr = + "val classLoader = lpparam.classLoader\n" + + "val %sClass = classLoader.loadClass(\"%s\")"; + + XposedCodegenLanguage language = getLanguage(); + String xposedFormatStr; + switch (language) { + case JAVA: + xposedFormatStr = javaXposedFormatStr; + break; + case KOTLIN: + xposedFormatStr = kotlinXposedFormatStr; + break; + default: + throw new JadxRuntimeException("Invalid Xposed code generation language: " + language); + } + + return String.format(xposedFormatStr, shortClassName, rawClassName); } private String generateFieldSnippet(JField jf) { @@ -129,6 +173,29 @@ private String generateFieldSnippet(JField jf) { String isStatic = javaField.getAccessFlags().isStatic() ? "Static" : ""; String type = PRIMITIVE_TYPE_MAPPING.getOrDefault(javaField.getFieldNode().getType().toString(), "Object"); String xposedMethod = "XposedHelpers.get" + isStatic + type + "Field"; - return String.format("%s(/*runtimeObject*/, \"%s\");", xposedMethod, javaField.getFieldNode().getFieldInfo().getName()); + + String javaXposedFormatStr = + "%s(/*runtimeObject*/, \"%s\");"; + String kotlinXposedFormatStr = + "%s(/*runtimeObject*/, \"%s\")"; + + XposedCodegenLanguage language = getLanguage(); + String xposedFormatStr; + switch (language) { + case JAVA: + xposedFormatStr = javaXposedFormatStr; + break; + case KOTLIN: + xposedFormatStr = kotlinXposedFormatStr; + break; + default: + throw new JadxRuntimeException("Invalid Xposed code generation language: " + language); + } + + return String.format(xposedFormatStr, xposedMethod, javaField.getFieldNode().getFieldInfo().getName()); + } + + private XposedCodegenLanguage getLanguage() { + return getCodeArea().getMainWindow().getSettings().getXposedCodegenLanguage(); } } diff --git a/jadx-gui/src/main/resources/i18n/Messages_de_DE.properties b/jadx-gui/src/main/resources/i18n/Messages_de_DE.properties index 7e5c4c1c08f..6beca6d0576 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_de_DE.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_de_DE.properties @@ -203,6 +203,7 @@ preferences.excludedPackages.button=Bearbeiten preferences.excludedPackages.editDialog=Liste der durch Leerzeichen getrennten Paketnamen, die nicht dekompiliert oder indiziert werden. (spart RAM)
z.B. android.support preferences.cfg=CFG-Grafiken für Methoden generieren (im 'dot'-Format) preferences.raw_cfg=RAW CFG-Grafiken generieren +#preferences.xposed_codegen_language=Xposed code generation language #preferences.integerFormat=Integer format preferences.font=Schrift ändern #preferences.smali_font= 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 d9e8e1072a6..f1aea460014 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_en_US.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_en_US.properties @@ -203,6 +203,7 @@ preferences.excludedPackages.button=Edit preferences.excludedPackages.editDialog=List of space separated package names that will not be decompiled or indexed (saves RAM)
e.g. android.support preferences.cfg=Generate methods CFG graphs (in 'dot' format) preferences.raw_cfg=Generate RAW CFG graphs +preferences.xposed_codegen_language=Xposed code generation language preferences.integerFormat=Integer format preferences.font=Editor font preferences.smali_font=Monospaced font (Smali/Hex) 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 712d617bb33..0e1b39c5f80 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_es_ES.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_es_ES.properties @@ -203,6 +203,7 @@ preferences.threads=Número de hilos a procesar #preferences.excludedPackages.editDialog= preferences.cfg=Generar methods CFG graphs (in 'dot' format) preferences.raw_cfg=Generate RAW CFG graphs +#preferences.xposed_codegen_language=Xposed code generation language #preferences.integerFormat=Integer format preferences.font=Fuente del editor #preferences.smali_font= diff --git a/jadx-gui/src/main/resources/i18n/Messages_id_ID.properties b/jadx-gui/src/main/resources/i18n/Messages_id_ID.properties index 3e26b386001..1b063399571 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_id_ID.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_id_ID.properties @@ -203,6 +203,7 @@ preferences.excludedPackages.button=Edit preferences.excludedPackages.editDialog=Daftar nama paket yang dipisahkan spasi yang tidak akan di deskompilasi atau diindeks (menghemat RAM)
contoh: android.support preferences.cfg=Hasilkan grafik CFG metode (dalam format 'dot') preferences.raw_cfg=Hasilkan grafik CFG mentah +#preferences.xposed_codegen_language=Xposed code generation language preferences.integerFormat=Format bilangan bulat preferences.font=Font editor preferences.smali_font=Font monospasi (Smali/Hex) diff --git a/jadx-gui/src/main/resources/i18n/Messages_ko_KR.properties b/jadx-gui/src/main/resources/i18n/Messages_ko_KR.properties index 1f84699d051..f5e835c0966 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_ko_KR.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_ko_KR.properties @@ -203,6 +203,7 @@ preferences.excludedPackages.button=Edit preferences.excludedPackages.editDialog=RAM 절약을 위해 디컴파일되거나 인덱싱하지 않을 패키지 이름 목록 (공백으로 항목 구분)
예: android.support preferences.cfg=메소드 CFG 그래프 생성 ('dot' 포맷) preferences.raw_cfg=RAW CFG 그래프 생성 +#preferences.xposed_codegen_language=Xposed code generation language #preferences.integerFormat=Integer format preferences.font=에디터 글씨체 #preferences.smali_font= diff --git a/jadx-gui/src/main/resources/i18n/Messages_pt_BR.properties b/jadx-gui/src/main/resources/i18n/Messages_pt_BR.properties index cd9a22451ed..c0aa1a98c6e 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_pt_BR.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_pt_BR.properties @@ -203,6 +203,7 @@ preferences.excludedPackages.button=Editar preferences.excludedPackages.editDialog=Lista espaço de pacotes que não vão ser descompilados ou indexados (economiza RAM)
ex: android.support preferences.cfg=Gera gráficos de métodos CFG no formato de pontos ('dot') preferences.raw_cfg=Gera gráficos CFG no formato RAW +#preferences.xposed_codegen_language=Xposed code generation language #preferences.integerFormat=Integer format preferences.font=Fonte do editor #preferences.smali_font= diff --git a/jadx-gui/src/main/resources/i18n/Messages_ru_RU.properties b/jadx-gui/src/main/resources/i18n/Messages_ru_RU.properties index ed6179f1933..d61080ab904 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_ru_RU.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_ru_RU.properties @@ -203,6 +203,7 @@ preferences.excludedPackages.button=Изменить preferences.excludedPackages.editDialog=Список пакетов, которые не будут декомпилироваться и индексироваться (экономит ОЗУ)
например: android.support
Разделитель - одинарный пробел preferences.cfg=Методы генерации графиков CFG (в "dot" формате) preferences.raw_cfg=Генерировать необработанные графики CFG +#preferences.xposed_codegen_language=Xposed code generation language #preferences.integerFormat=Integer format preferences.font=Шрифт редактора Java #preferences.smali_font= 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 d0d55eb1f10..ac62423c6f0 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties @@ -203,6 +203,7 @@ preferences.excludedPackages.button=编辑 preferences.excludedPackages.editDialog=排除于反编译或索引的以空格分隔的包名列表(节省 RAM)
例如android.support preferences.cfg=生成方法的 CFG 图('.dot') preferences.raw_cfg=生成原始的 CFG 图 +#preferences.xposed_codegen_language=Xposed code generation language preferences.integerFormat=数值格式化 preferences.font=编辑器字体 preferences.smali_font=等宽字体 (Smali/Hex) diff --git a/jadx-gui/src/main/resources/i18n/Messages_zh_TW.properties b/jadx-gui/src/main/resources/i18n/Messages_zh_TW.properties index 23def101879..3149880e7fe 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_zh_TW.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_zh_TW.properties @@ -203,6 +203,7 @@ preferences.excludedPackages.button=編輯 preferences.excludedPackages.editDialog=排除於索引或反編譯外的套件列表 (以空格分隔) (節省 RAM)
例如 android.support preferences.cfg=產生方法 CFG 圖表 ('dot' 格式) preferences.raw_cfg=產生 RAW CFG 圖表 +#preferences.xposed_codegen_language=Xposed code generation language preferences.integerFormat=整數模式 preferences.font=編輯器字型 preferences.smali_font=等寬字型 (Smali/Hex)