Skip to content

[core] Kotlin script compiler fails to resolve JADX script plugin runtime/receiver #2795

@Dev4Mod

Description

@Dev4Mod

Issue details

When attempting to execute a Kotlin script (.kts) in JADX to create a ScriptOrderedDecompilePass, the compiler fails to recognize the plugin's base classes and the script receiver. This prevents the use of essential functions such as getJadxInstance() and the implementation of custom visitors.

Relevant log output or stacktrace

ERROR: Cannot access implicit script receiver class 'jadx.plugins.script.kotlin.runtime.JadxScriptTemplate'. Check your module classpath for missing or conflicting dependencies.
ERROR: Unresolved reference: script (deobf_from_tostring.jadx.kts:13:21)
ERROR: Unresolved reference: getJadxInstance (deobf_from_tostring.jadx.kts:15:12)
ERROR: Unresolved reference: ScriptOrderedDecompilePass (deobf_from_tostring.jadx.kts:17:23)
ERROR: 'visit' overrides nothing (deobf_from_tostring.jadx.kts:22:2)

code

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.InvokeNode
import jadx.core.dex.instructions.args.InsnArg
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()

jadx.addPass(object : ScriptOrderedDecompilePass(
    jadx,
    "DeobfFromToString",
    runAfter = listOf("SimplifyVisitor"),
) {
    override fun visit(mth: MethodNode) {
        // Target: only toString() methods
        if (mth.methodInfo.shortId == "toString()Ljava/lang/String;") {
            val returnBlock = mth.exitBlock.predecessors.firstOrNull { it.contains(AFlag.RETURN) }
            val lastInsn = returnBlock?.instructions?.lastOrNull()
            
            // Check if last instruction is a return of a string
            if (lastInsn != null && lastInsn.type == InsnType.RETURN) {
                val arg = lastInsn.getArg(0)
                if (arg is InsnWrapArg) {
                    val wrappedInsn = arg.wrapInsn
                    if (wrappedInsn is ConstStringNode) {
                          // code
                    }
                }
            }
        }
    }
})

Jadx version

1.5.4

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions