Skip to content

Commit

Permalink
feat: add an option to generate kotlin code for xposed
Browse files Browse the repository at this point in the history
A new setting was added, bumping the settings version to 19.
  • Loading branch information
iscle committed Dec 28, 2023
1 parent e723c24 commit ac4755e
Show file tree
Hide file tree
Showing 13 changed files with 111 additions and 6 deletions.
16 changes: 15 additions & 1 deletion jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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, ...
*/
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package jadx.gui.settings

enum class XposedCodegenLanguage {
JAVA,
KOTLIN,
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -622,13 +623,21 @@ private SettingsGroup makeOtherGroup() {
needReload();
});

JComboBox<XposedCodegenLanguage> 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);
group.addRow(NLS.str("preferences.useAlternativeFileDialog"), useAltFileDialog);
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;
}

Expand Down
77 changes: 72 additions & 5 deletions jadx-gui/src/main/java/jadx/gui/ui/codearea/XposedAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import javax.swing.JOptionPane;

import jadx.gui.settings.XposedCodegenLanguage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -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"
Expand All @@ -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<ArgType> mthArgs = mth.getArgTypes();
if (mthArgs.isEmpty()) {
Expand All @@ -119,16 +144,58 @@ 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) {
JavaField javaField = jf.getJavaField();
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();
}
}
1 change: 1 addition & 0 deletions jadx-gui/src/main/resources/i18n/Messages_de_DE.properties
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ preferences.excludedPackages.button=Bearbeiten
preferences.excludedPackages.editDialog=<html>Liste der durch Leerzeichen getrennten Paketnamen, die nicht dekompiliert oder indiziert werden. (spart RAM)<br>z.B. <code>android.support</code></html>
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=
Expand Down
1 change: 1 addition & 0 deletions jadx-gui/src/main/resources/i18n/Messages_en_US.properties
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ preferences.excludedPackages.button=Edit
preferences.excludedPackages.editDialog=<html>List of space separated package names that will not be decompiled or indexed (saves RAM)<br>e.g. <code>android.support</code></html>
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)
Expand Down
1 change: 1 addition & 0 deletions jadx-gui/src/main/resources/i18n/Messages_es_ES.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
1 change: 1 addition & 0 deletions jadx-gui/src/main/resources/i18n/Messages_id_ID.properties
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ preferences.excludedPackages.button=Edit
preferences.excludedPackages.editDialog=<html>Daftar nama paket yang dipisahkan spasi yang tidak akan di deskompilasi atau diindeks (menghemat RAM)<br>contoh: <code>android.support</code></html>
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)
Expand Down
1 change: 1 addition & 0 deletions jadx-gui/src/main/resources/i18n/Messages_ko_KR.properties
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ preferences.excludedPackages.button=Edit
preferences.excludedPackages.editDialog=<html>RAM 절약을 위해 디컴파일되거나 인덱싱하지 않을 패키지 이름 목록 (공백으로 항목 구분)<br>예: <code>android.support</code></html>
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=
Expand Down
1 change: 1 addition & 0 deletions jadx-gui/src/main/resources/i18n/Messages_pt_BR.properties
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ preferences.excludedPackages.button=Editar
preferences.excludedPackages.editDialog=<html>Lista espaço de pacotes que não vão ser descompilados ou indexados (economiza RAM)<br>ex: <code>android.support</code></html>
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=
Expand Down
1 change: 1 addition & 0 deletions jadx-gui/src/main/resources/i18n/Messages_ru_RU.properties
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ preferences.excludedPackages.button=Изменить
preferences.excludedPackages.editDialog=<html>Список пакетов, которые не будут декомпилироваться и индексироваться (экономит ОЗУ)<br>например: <code>android.support</code><br>Разделитель - одинарный пробел</html>
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=
Expand Down
1 change: 1 addition & 0 deletions jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ preferences.excludedPackages.button=编辑
preferences.excludedPackages.editDialog=<html>排除于反编译或索引的以空格分隔的包名列表(节省 RAM)<br>例如<code>android.support</code></html>
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)
Expand Down
1 change: 1 addition & 0 deletions jadx-gui/src/main/resources/i18n/Messages_zh_TW.properties
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ preferences.excludedPackages.button=編輯
preferences.excludedPackages.editDialog=<html>排除於索引或反編譯外的套件列表 (以空格分隔) (節省 RAM) <br>例如 <code>android.support</code></html>
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)
Expand Down

0 comments on commit ac4755e

Please sign in to comment.