fix: scripts runtime code and docs clean up
This commit is contained in:
+4
-3
@@ -4,7 +4,6 @@ import jadx.api.plugins.JadxPlugin
|
||||
import jadx.api.plugins.JadxPluginContext
|
||||
import jadx.api.plugins.JadxPluginInfo
|
||||
import jadx.plugins.script.passes.JadxScriptAfterLoadPass
|
||||
import jadx.plugins.script.runner.ScriptEval
|
||||
import jadx.plugins.script.runtime.data.JadxScriptAllOptions
|
||||
|
||||
class JadxScriptPlugin : JadxPlugin {
|
||||
@@ -14,7 +13,9 @@ class JadxScriptPlugin : JadxPlugin {
|
||||
|
||||
override fun init(init: JadxPluginContext) {
|
||||
init.registerOptions(scriptOptions)
|
||||
val scriptStates = ScriptEval().process(init, scriptOptions) ?: return
|
||||
init.addPass(JadxScriptAfterLoadPass(scriptStates))
|
||||
val scripts = ScriptEval().process(init, scriptOptions)
|
||||
if (scripts.isNotEmpty()) {
|
||||
init.addPass(JadxScriptAfterLoadPass(scripts))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
package jadx.plugins.script
|
||||
|
||||
import jadx.api.JadxDecompiler
|
||||
import jadx.api.plugins.JadxPluginContext
|
||||
import jadx.plugins.script.runtime.JadxScriptData
|
||||
import jadx.plugins.script.runtime.JadxScriptTemplate
|
||||
import jadx.plugins.script.runtime.data.JadxScriptAllOptions
|
||||
import kotlin.script.experimental.api.EvaluationResult
|
||||
import kotlin.script.experimental.api.ResultValue
|
||||
import kotlin.script.experimental.api.ResultWithDiagnostics
|
||||
import kotlin.script.experimental.api.ScriptCompilationConfiguration
|
||||
import kotlin.script.experimental.api.ScriptDiagnostic.Severity
|
||||
import kotlin.script.experimental.api.ScriptEvaluationConfiguration
|
||||
import kotlin.script.experimental.api.compilerOptions
|
||||
import kotlin.script.experimental.api.constructorArgs
|
||||
import kotlin.script.experimental.host.toScriptSource
|
||||
import kotlin.script.experimental.jvmhost.BasicJvmScriptingHost
|
||||
import kotlin.script.experimental.jvmhost.createJvmCompilationConfigurationFromTemplate
|
||||
import kotlin.script.experimental.jvmhost.createJvmEvaluationConfigurationFromTemplate
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
class ScriptEval {
|
||||
|
||||
private val scriptingHost = BasicJvmScriptingHost()
|
||||
|
||||
fun process(init: JadxPluginContext, scriptOptions: JadxScriptAllOptions): List<JadxScriptData> {
|
||||
val jadx = init.decompiler as JadxDecompiler
|
||||
val scripts = jadx.args.inputFiles.filter { f -> f.name.endsWith(".jadx.kts") }
|
||||
if (scripts.isEmpty()) {
|
||||
return emptyList()
|
||||
}
|
||||
val scriptDataList = mutableListOf<JadxScriptData>()
|
||||
for (scriptFile in scripts) {
|
||||
val scriptData = JadxScriptData(jadx, init, scriptOptions, scriptFile)
|
||||
scriptDataList.add(scriptData)
|
||||
eval(scriptData)
|
||||
}
|
||||
return scriptDataList
|
||||
}
|
||||
|
||||
fun buildCompileConf(): ScriptCompilationConfiguration {
|
||||
return createJvmCompilationConfigurationFromTemplate<JadxScriptTemplate>() {
|
||||
compilerOptions(listOf("-Xuse-k2"))
|
||||
}
|
||||
}
|
||||
|
||||
fun buildEvalConf(scriptData: JadxScriptData): ScriptEvaluationConfiguration {
|
||||
return createJvmEvaluationConfigurationFromTemplate<JadxScriptTemplate> {
|
||||
constructorArgs(scriptData)
|
||||
}
|
||||
}
|
||||
|
||||
private fun eval(scriptData: JadxScriptData) {
|
||||
scriptData.log.debug { "Loading script: ${scriptData.scriptFile.absolutePath}" }
|
||||
val execTime = measureTimeMillis {
|
||||
val compilationConf = buildCompileConf()
|
||||
val evalConf = buildEvalConf(scriptData)
|
||||
val result = scriptingHost.eval(scriptData.scriptFile.toScriptSource(), compilationConf, evalConf)
|
||||
processEvalResult(result, scriptData)
|
||||
}
|
||||
scriptData.log.debug { "Script '${scriptData.scriptName}' executed in $execTime ms" }
|
||||
}
|
||||
|
||||
private fun processEvalResult(res: ResultWithDiagnostics<EvaluationResult>, scriptData: JadxScriptData) {
|
||||
val log = scriptData.log
|
||||
for (r in res.reports) {
|
||||
val msg = r.render(withSeverity = false)
|
||||
when (r.severity) {
|
||||
Severity.FATAL, Severity.ERROR -> log.error(r.exception) { "Script execution error: $msg" }
|
||||
Severity.WARNING -> log.warn { "Script execution issue: $msg" }
|
||||
Severity.INFO -> log.info { "Script report: $msg" }
|
||||
Severity.DEBUG -> log.debug { "Script report: $msg" }
|
||||
}
|
||||
}
|
||||
when (res) {
|
||||
is ResultWithDiagnostics.Success -> {
|
||||
when (val retVal = res.value.returnValue) {
|
||||
is ResultValue.Error -> log.error(retVal.error) { "Script execution error:" }
|
||||
is ResultValue.Value -> log.info { "Script execution result: $retVal" }
|
||||
is ResultValue.Unit -> {}
|
||||
ResultValue.NotEvaluated -> {}
|
||||
}
|
||||
}
|
||||
|
||||
is ResultWithDiagnostics.Failure -> {
|
||||
scriptData.error = true
|
||||
log.error { "Script execution failed: ${scriptData.scriptName}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-8
@@ -3,27 +3,24 @@ package jadx.plugins.script.passes
|
||||
import jadx.api.JadxDecompiler
|
||||
import jadx.api.plugins.pass.impl.SimpleJadxPassInfo
|
||||
import jadx.api.plugins.pass.types.JadxAfterLoadPass
|
||||
import jadx.plugins.script.runner.ScriptStates
|
||||
import mu.KotlinLogging
|
||||
import jadx.plugins.script.runtime.JadxScriptData
|
||||
|
||||
private val LOG = KotlinLogging.logger {}
|
||||
|
||||
class JadxScriptAfterLoadPass(private val scriptStates: ScriptStates) : JadxAfterLoadPass {
|
||||
class JadxScriptAfterLoadPass(private val scripts: List<JadxScriptData>) : JadxAfterLoadPass {
|
||||
|
||||
override fun getInfo() = SimpleJadxPassInfo("JadxScriptAfterLoad", "Execute scripts 'afterLoad' block")
|
||||
|
||||
override fun init(decompiler: JadxDecompiler) {
|
||||
for (script in scriptStates.getScripts()) {
|
||||
for (script in scripts) {
|
||||
if (script.error) {
|
||||
continue
|
||||
}
|
||||
try {
|
||||
for (b in script.scriptData.afterLoad) {
|
||||
for (b in script.afterLoad) {
|
||||
b.invoke()
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
script.error = true
|
||||
LOG.error(e) { "Error executing 'afterLoad' block in script: ${script.scriptFile.name}" }
|
||||
script.log.error(e) { "Error executing 'afterLoad' block in script: ${script.scriptFile.name}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-78
@@ -1,78 +0,0 @@
|
||||
package jadx.plugins.script.runner
|
||||
|
||||
import jadx.api.JadxDecompiler
|
||||
import jadx.api.plugins.JadxPluginContext
|
||||
import jadx.plugins.script.runtime.JadxScriptData
|
||||
import jadx.plugins.script.runtime.JadxScriptTemplate
|
||||
import jadx.plugins.script.runtime.data.JadxScriptAllOptions
|
||||
import mu.KotlinLogging
|
||||
import java.io.File
|
||||
import kotlin.script.experimental.api.EvaluationResult
|
||||
import kotlin.script.experimental.api.ResultValue
|
||||
import kotlin.script.experimental.api.ResultWithDiagnostics
|
||||
import kotlin.script.experimental.api.ScriptDiagnostic
|
||||
import kotlin.script.experimental.api.ScriptEvaluationConfiguration
|
||||
import kotlin.script.experimental.api.constructorArgs
|
||||
import kotlin.script.experimental.host.toScriptSource
|
||||
import kotlin.script.experimental.jvmhost.BasicJvmScriptingHost
|
||||
import kotlin.script.experimental.jvmhost.createJvmCompilationConfigurationFromTemplate
|
||||
import kotlin.script.experimental.jvmhost.createJvmEvaluationConfigurationFromTemplate
|
||||
|
||||
private val LOG = KotlinLogging.logger {}
|
||||
|
||||
class ScriptEval {
|
||||
|
||||
fun process(init: JadxPluginContext, scriptOptions: JadxScriptAllOptions): ScriptStates? {
|
||||
val jadx = init.decompiler as JadxDecompiler
|
||||
val scripts = jadx.args.inputFiles.filter { f -> f.name.endsWith(".jadx.kts") }
|
||||
if (scripts.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
val scriptStates = ScriptStates()
|
||||
for (scriptFile in scripts) {
|
||||
val scriptData = JadxScriptData(jadx, init, scriptOptions, scriptFile)
|
||||
load(scriptFile, scriptData)
|
||||
scriptStates.add(scriptFile, scriptData)
|
||||
}
|
||||
return scriptStates
|
||||
}
|
||||
|
||||
private fun load(scriptFile: File, scriptData: JadxScriptData) {
|
||||
LOG.debug { "Loading script: ${scriptFile.absolutePath}" }
|
||||
val result = eval(scriptFile, scriptData)
|
||||
processEvalResult(result, scriptFile)
|
||||
}
|
||||
|
||||
fun buildCompileConf() = createJvmCompilationConfigurationFromTemplate<JadxScriptTemplate>()
|
||||
|
||||
fun buildEvalConf(scriptData: JadxScriptData): ScriptEvaluationConfiguration {
|
||||
return createJvmEvaluationConfigurationFromTemplate<JadxScriptTemplate> {
|
||||
constructorArgs(scriptData)
|
||||
}
|
||||
}
|
||||
|
||||
private fun eval(scriptFile: File, scriptData: JadxScriptData): ResultWithDiagnostics<EvaluationResult> {
|
||||
val compilationConf = buildCompileConf()
|
||||
val evalConf = buildEvalConf(scriptData)
|
||||
return BasicJvmScriptingHost().eval(scriptFile.toScriptSource(), compilationConf, evalConf)
|
||||
}
|
||||
|
||||
private fun processEvalResult(res: ResultWithDiagnostics<EvaluationResult>, scriptFile: File) {
|
||||
when (res) {
|
||||
is ResultWithDiagnostics.Success -> {
|
||||
val result = res.value.returnValue
|
||||
if (result is ResultValue.Error) {
|
||||
result.error.printStackTrace()
|
||||
}
|
||||
}
|
||||
is ResultWithDiagnostics.Failure -> {
|
||||
LOG.error { "Script execution failed: ${scriptFile.name}" }
|
||||
res.reports
|
||||
.filter { it.severity >= ScriptDiagnostic.Severity.ERROR }
|
||||
.forEach { r ->
|
||||
LOG.error(r.exception) { r.render(withSeverity = false) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-20
@@ -1,21 +1 @@
|
||||
package jadx.plugins.script.runner
|
||||
|
||||
import jadx.plugins.script.runtime.JadxScriptData
|
||||
import java.io.File
|
||||
|
||||
data class ScriptStateData(
|
||||
val scriptFile: File,
|
||||
val scriptData: JadxScriptData,
|
||||
var error: Boolean = false,
|
||||
)
|
||||
|
||||
class ScriptStates {
|
||||
|
||||
private val data: MutableList<ScriptStateData> = ArrayList()
|
||||
|
||||
fun add(scriptFile: File, scriptData: JadxScriptData) {
|
||||
data.add(ScriptStateData(scriptFile, scriptData))
|
||||
}
|
||||
|
||||
fun getScripts() = data
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user