Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom Batch Renaming for Class Names, Fields, and Methods #2126

Open
ArjunaKumarMohanta opened this issue Mar 17, 2024 · 11 comments
Open

Custom Batch Renaming for Class Names, Fields, and Methods #2126

ArjunaKumarMohanta opened this issue Mar 17, 2024 · 11 comments

Comments

@ArjunaKumarMohanta
Copy link

ArjunaKumarMohanta commented Mar 17, 2024

Describe your idea

I propose adding a feature to JADX that enables users to perform batch renaming of class names, fields, and methods. This feature would allow users to change class names, fields, and method names to custom names of their choice.

For instance, some applications utilize obfuscation techniques like using 'O' and '0' in class, field, and method names, such as "O0000OO000OO0O00OO0O" for a class name, "O00O0000000000000000" for a field name, and "O0000000000000000000" for a method name.
Screenshot_20240317-193714.png

With this feature, users could rename class names to consist of 5 or 4 different English letters like "Ahhsb.java" or "Akjs.java," rename field names to consist of 6 English letters like "Ishkkw," and rename method names to consist of 6 English letters like "Ikbajj."

@ArjunaKumarMohanta ArjunaKumarMohanta changed the title Custom Batch Renaming for Class Names, Fields, and Methods Custom Batch Renaming for Class Names, Fields, and Methods for Command line interface Mar 17, 2024
@ArjunaKumarMohanta ArjunaKumarMohanta changed the title Custom Batch Renaming for Class Names, Fields, and Methods for Command line interface Custom Batch Renaming for Class Names, Fields, and Methods Mar 17, 2024
@skylot
Copy link
Owner

skylot commented Mar 17, 2024

@ArjunaKumarMohanta to support custom renaming scenarios, jadx now support scripting.
Please try latest unstable build with deobf.jadx.kts script, it allows change regexp from preferences.
For details of using scripts, check this readme.
If you have any questions, feel free to ask 🙂

@ArjunaKumarMohanta

This comment has been minimized.

@skylot
Copy link
Owner

skylot commented Mar 18, 2024

Could you please provide the CLI commands

jadx app.apk deobf.jadx.kts -Pjadx-script.deobf.regex="[Oo0]+" --log-level info

Here regex option is optional and can be changed directly in script.
Log level adjusted to check script messages.

could you briefly explain the deobf.jadx.kts code?

/**
 * Custom regexp deobfuscator
 */

// get jadx decompiler instance
val jadx = getJadxInstance()

// disable build in deobfuscation and all renames (optional)
jadx.args.isDeobfuscationOn = false
jadx.args.renameFlags = emptySet()

// register custom option to simplify regexp value change, usage:
// - in cli add '-Pjadx-script.deobf.regex="[Oo0]+"' argument
// - in gui go to Preferences -> Plugins -> Scripts -> deobf
val regexOpt = jadx.options.registerString(
	name = "regex",
	desc = "Apply rename for names matches regex",
	defaultValue = "[Oo0]+",
)

// get option value and build regex instance
val regex = regexOpt.value.toRegex()
var n = 0

// check names of all nodes (classes, fields, methods)
// if name match regex rename node to 'NodeTypeN', for class it will become 'class2'
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 {
	// this will be printed after all renames done
	log.info { "Renames count: $n" }
}

Actually, custom option register here is mostly for example, regex value can be set in script directly:

val regex = "[Oo0]+".toRegex()

Hope, this will be helpful 😄

@ArjunaKumarMohanta
Copy link
Author

Thanks

@ArjunaKumarMohanta

This comment has been minimized.

@skylot
Copy link
Owner

skylot commented Mar 20, 2024

@ArjunaKumarMohanta I commit example script for resources rename here, but I also change core classes, so you need to download latest unstable build once again.

@ArjunaKumarMohanta
Copy link
Author

Thanks

@ArjunaKumarMohanta

This comment has been minimized.

@skylot
Copy link
Owner

skylot commented Mar 21, 2024

@ArjunaKumarMohanta It feels like I am ChatGPT 🤣
Anyway, here combined script deobf-OZero.jadx.kts:

import jadx.api.plugins.options.OptionFlag.PER_PROJECT

/**
 * Custom regexp deobfuscator
 */

val jadx = getJadxInstance()
jadx.args.isDeobfuscationOn = false
jadx.args.renameFlags = emptySet()

val regexOpt = jadx.options.registerString(
        name = "regex",
        desc = "Apply rename for nodes with names matches regex",
        defaultValue = "[Oo0]+",
).flags(PER_PROJECT)

val resRegexOpt = jadx.options.registerString(
        name = "resRegex",
        desc = "Rename resource files with names matches regex",
        defaultValue = """[Oo0]+\.xml""",
).flags(PER_PROJECT)

var n = 0

val regex = regexOpt.value.toRegex()
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
        }
}

val resRegex = resRegexOpt.value.toRegex()
jadx.stages.prepare {
        for (resFile in jadx.internalDecompiler.resources) {
                val fullName = resFile.originalName
                val name = fullName.substringAfterLast('/')
                if (name matches resRegex) {
                        val path = fullName.substringBeforeLast('/') // TODO: path also may be obfuscated
                        val ext = name.substringAfterLast('.')
                        val newName = "$path/res-${n++}.$ext"
                        log.info { "renaming resource: '$fullName' to '$newName'" }
                        resFile.deobfName = newName
                }
        }
}

jadx.afterLoad {
        log.info { "Renames count: $n" }
}

@ArjunaKumarMohanta
Copy link
Author

@ArjunaKumarMohanta It feels like I am ChatGPT 🤣
Anyway, here combined script deobf-OZero.jadx.kts:

import jadx.api.plugins.options.OptionFlag.PER_PROJECT

/**
 * Custom regexp deobfuscator
 */

val jadx = getJadxInstance()
jadx.args.isDeobfuscationOn = false
jadx.args.renameFlags = emptySet()

val regexOpt = jadx.options.registerString(
        name = "regex",
        desc = "Apply rename for nodes with names matches regex",
        defaultValue = "[Oo0]+",
).flags(PER_PROJECT)

val resRegexOpt = jadx.options.registerString(
        name = "resRegex",
        desc = "Rename resource files with names matches regex",
        defaultValue = """[Oo0]+\.xml""",
).flags(PER_PROJECT)

var n = 0

val regex = regexOpt.value.toRegex()
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
        }
}

val resRegex = resRegexOpt.value.toRegex()
jadx.stages.prepare {
        for (resFile in jadx.internalDecompiler.resources) {
                val fullName = resFile.originalName
                val name = fullName.substringAfterLast('/')
                if (name matches resRegex) {
                        val path = fullName.substringBeforeLast('/') // TODO: path also may be obfuscated
                        val ext = name.substringAfterLast('.')
                        val newName = "$path/res-${n++}.$ext"
                        log.info { "renaming resource: '$fullName' to '$newName'" }
                        resFile.deobfName = newName
                }
        }
}

jadx.afterLoad {
        log.info { "Renames count: $n" }
}

Thanks

@ArjunaKumarMohanta
Copy link
Author

ArjunaKumarMohanta commented Mar 22, 2024

Screenshot_20240322-143102.png

@skylot Fix the jadx script to rename R.layout.* references, which do not exist. Replace R.layout.* with the appropriate references from deobf-resources.jadx.kts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants