chore(script): adjust scripts format
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Custom regexp deobfuscator
|
||||
*/
|
||||
|
||||
val jadx = getJadxInstance()
|
||||
jadx.args.isDeobfuscationOn = false
|
||||
jadx.args.renameFlags = emptySet()
|
||||
|
||||
val regexOpt = jadx.options.registerString(
|
||||
"regex",
|
||||
"Apply rename for names matches regex",
|
||||
defaultValue = "[Oo0]+",
|
||||
)
|
||||
|
||||
val regex = regexOpt.value.toRegex()
|
||||
var n = 0
|
||||
jadx.rename.all { name, node ->
|
||||
when {
|
||||
name matches regex -> {
|
||||
val newName = "${node.typeName()}${n++}"
|
||||
log.info { "renaming ${node.typeName()} '$node' to '$newName'" }
|
||||
newName
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
jadx.afterLoad {
|
||||
log.info { "Renames count: $n" }
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Animal deobfuscator ^_^
|
||||
*/
|
||||
|
||||
@file:DependsOn("com.github.javafaker:javafaker:1.0.2")
|
||||
|
||||
import com.github.javafaker.Faker
|
||||
import jadx.core.deobf.NameMapper
|
||||
import java.util.Random
|
||||
|
||||
val jadx = getJadxInstance()
|
||||
jadx.args.isDeobfuscationOn = false
|
||||
jadx.args.renameFlags = emptySet()
|
||||
|
||||
val regex = """[Oo0]+""".toRegex()
|
||||
val usedNames = mutableSetOf<String>()
|
||||
val faker = Faker(Random(1))
|
||||
var dups = 1
|
||||
|
||||
jadx.rename.all { name, node ->
|
||||
when {
|
||||
name matches regex -> {
|
||||
val prefix = node.typeName().first()
|
||||
val alias = faker.name().firstName().cap() + faker.animal().name().cap()
|
||||
makeUnique(prefix, alias)
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun makeUnique(prefix: Char, name: String): String {
|
||||
while (true) {
|
||||
val resName = prefix + NameMapper.removeInvalidCharsMiddle(name)
|
||||
return if (usedNames.add(resName)) resName else "$resName${dups++}"
|
||||
}
|
||||
}
|
||||
|
||||
jadx.afterLoad {
|
||||
log.info { "Renames count: ${usedNames.size + dups}, names: ${usedNames.size}, dups: $dups" }
|
||||
}
|
||||
|
||||
fun String.cap() = this.replaceFirstChar(Char::uppercaseChar)
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Rename method if specified string is found
|
||||
*/
|
||||
|
||||
import jadx.api.plugins.input.insns.Opcode
|
||||
import jadx.core.dex.nodes.MethodNode
|
||||
|
||||
val renamesMap = mapOf(
|
||||
"specificString" to "newMethodName",
|
||||
)
|
||||
|
||||
val jadx = getJadxInstance()
|
||||
|
||||
var n = 0
|
||||
jadx.rename.all { _, node ->
|
||||
var newName: String? = null
|
||||
if (node is MethodNode) {
|
||||
// use quick instructions scanner
|
||||
node.codeReader?.visitInstructions { insn ->
|
||||
if (insn.opcode == Opcode.CONST_STRING) {
|
||||
insn.decode()
|
||||
val constStr = insn.indexAsString
|
||||
val renameStr = renamesMap[constStr]
|
||||
if (renameStr != null) {
|
||||
log.info { "Found '$constStr' in method $node, renaming to '$renameStr'" }
|
||||
newName = renameStr
|
||||
n++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
newName
|
||||
}
|
||||
|
||||
jadx.afterLoad {
|
||||
log.info { "Script '$scriptName' renamed $n methods" }
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* Rename class and fields using strings from toString() method
|
||||
*/
|
||||
|
||||
import jadx.core.deobf.NameMapper
|
||||
import jadx.core.dex.attributes.AFlag
|
||||
import jadx.core.dex.attributes.nodes.RenameReasonAttr
|
||||
import jadx.core.dex.info.FieldInfo
|
||||
import jadx.core.dex.instructions.ConstStringNode
|
||||
import jadx.core.dex.instructions.IndexInsnNode
|
||||
import jadx.core.dex.instructions.InsnType
|
||||
import jadx.core.dex.instructions.args.InsnWrapArg
|
||||
import jadx.core.dex.nodes.InsnNode
|
||||
import jadx.core.dex.nodes.MethodNode
|
||||
import jadx.plugins.script.runtime.data.ScriptOrderedDecompilePass
|
||||
|
||||
val jadx = getJadxInstance()
|
||||
|
||||
// StringBuilder chain replaced by STR_CONCAT instruction in SimplifyVisitor
|
||||
// Search for return with STR_CONCAT and process args
|
||||
jadx.addPass(object : ScriptOrderedDecompilePass(
|
||||
jadx,
|
||||
"DeobfFromToString",
|
||||
runAfter = listOf("SimplifyVisitor"),
|
||||
) {
|
||||
override fun visit(mth: MethodNode) {
|
||||
if (mth.methodInfo.shortId == "toString()Ljava/lang/String;") {
|
||||
val returnBlock = mth.exitBlock.predecessors.firstOrNull { it.contains(AFlag.RETURN) }
|
||||
val lastInsn = returnBlock?.instructions?.lastOrNull()
|
||||
if (lastInsn != null && lastInsn.type == InsnType.RETURN) {
|
||||
val arg = lastInsn.getArg(0)
|
||||
if (arg.isInsnWrap) {
|
||||
val wrapInsn = (arg as InsnWrapArg).wrapInsn
|
||||
if (wrapInsn.type == InsnType.STR_CONCAT) {
|
||||
log.info { "Renaming using 'toString' in class: ${mth.parentClass}" }
|
||||
processArgs(mth, wrapInsn)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val clsSepRgx = Regex("[ ({:]")
|
||||
|
||||
private fun processArgs(mth: MethodNode, wrapInsn: InsnNode): Boolean {
|
||||
try {
|
||||
var fldName: String? = null
|
||||
for ((i, arg) in wrapInsn.arguments.withIndex()) {
|
||||
val insn = arg.unwrap() ?: return false
|
||||
if (i % 2 == 0) {
|
||||
if (insn !is ConstStringNode) {
|
||||
return false
|
||||
}
|
||||
var str = insn.string
|
||||
if (i == 0) {
|
||||
// class and first field name
|
||||
val parts = str.split(clsSepRgx)
|
||||
val clsName = parts[0]
|
||||
if (NameMapper.isValidIdentifier(clsName)) {
|
||||
mth.parentClass.run {
|
||||
log.info { "rename class '$name' to '$clsName'" }
|
||||
rename(clsName)
|
||||
RenameReasonAttr.forNode(this).append("from toString()")
|
||||
}
|
||||
}
|
||||
str = parts[1]
|
||||
}
|
||||
fldName = str.trim('\'', '=', ',', ' ', ':')
|
||||
} else {
|
||||
if (insn.type != InsnType.IGET) {
|
||||
return false
|
||||
}
|
||||
val iget = insn as IndexInsnNode
|
||||
val fldInfo = iget.index as FieldInfo
|
||||
val fld = mth.parentClass.searchField(fldInfo)
|
||||
if (fld != null && NameMapper.isValidIdentifier(fldName)) {
|
||||
log.info { "rename field '${fld.name}' to '$fldName'" }
|
||||
fld.rename(fldName)
|
||||
RenameReasonAttr.forNode(fld).append("from toString()")
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
} catch (e: Exception) {
|
||||
log.error(e) { "Args process failed" }
|
||||
return false
|
||||
}
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user