diff --git a/jadx-plugins/jadx-script/examples/scripts/replace_method_call.jadx.kts b/jadx-plugins/jadx-script/examples/scripts/replace_method_call.jadx.kts new file mode 100644 index 000000000..3a8a4522f --- /dev/null +++ b/jadx-plugins/jadx-script/examples/scripts/replace_method_call.jadx.kts @@ -0,0 +1,60 @@ +/** + * Replace method call with calculated result. + * Useful for custom string deobfuscation. + * + * Example for sample from issue https://github.com/skylot/jadx/issues/1251 + */ + +import jadx.core.dex.instructions.ConstStringNode +import jadx.core.dex.instructions.InvokeNode +import jadx.core.dex.instructions.args.InsnArg +import jadx.core.dex.instructions.args.InsnWrapArg +import jadx.core.dex.instructions.args.RegisterArg + + +val jadx = getJadxInstance() + +jadx.replace.insns { mth, insn -> + if (insn is InvokeNode + && insn.callMth.rawFullId == "com.xshield.aa.iIiIiiiiII(Ljava/lang/String;)Ljava/lang/String;" + ) { + val str = getConstStr(insn.getArg(0)) + if (str != null) { + val resultStr = decode(str) + log.info { "Decode '$str' to '$resultStr' in $mth" } + return@insns ConstStringNode(resultStr) + } + } + null +} + +fun getConstStr(arg: InsnArg): String? { + val insn = when (arg) { + is InsnWrapArg -> arg.wrapInsn + is RegisterArg -> arg.assignInsn + else -> null + } + if (insn is ConstStringNode) { + return insn.string + } + return null +} + +/** + * Decompiled method, automatically converted to Kotlin by IntelliJ Idea + */ +fun decode(str: String): String { + val length = str.length + val cArr = CharArray(length) + var i = length - 1 + while (i >= 0) { + val i2 = i - 1 + cArr[i] = (str[i].code xor 'z'.code).toChar() + if (i2 < 0) { + break + } + i = i2 - 1 + cArr[i2] = (str[i2].code xor '\u000c'.code).toChar() + } + return String(cArr) +}