61 lines
1.4 KiB
Kotlin
61 lines
1.4 KiB
Kotlin
/**
|
|
* 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()
|
|
|
|
val mthSignature = "com.xshield.aa.iIiIiiiiII(Ljava/lang/String;)Ljava/lang/String;"
|
|
|
|
jadx.replace.insns { mth, insn ->
|
|
if (insn is InvokeNode && insn.callMth.rawFullId == mthSignature) {
|
|
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)
|
|
}
|