Open 5c4lar opened 2 years ago
Mmh, none that I have setup yet, but in theory it should be quite possible. You can simply call IkotlinKt.embedKernel(connectionFile, EmptyResolutionInfoProvider.INSTANCE, null);}
in a postScript and it will set up the kernel, so using the jupyter-console
is fairly trivial. For the notebook I guess there just needs to be one function that handles the initial setup of the notebook, which requires a bit of trickery so the Jupyter Notebook thinks that it started the server. I assume that the Jupyter Notebook server would be running on the same host as the Ghidra instance, and you would just be connecting to the notebook server from a remote client?
Thanks! @fmagin
I assume that the Jupyter Notebook server would be running on the same host as the Ghidra instance, and you would just be connecting to the notebook server from a remote client?
This is exactly what I'm trying to do.
Okay, quickly gave this a try: The first issue is that the NotebookThread
constructor takes a PluginTool
as an argument, which is not available in headless mode.
But when I change the NotebookProxy
class to be public, you can run the following script and it will somewhat start the kernel. It's a bit finicky about when you start the kernel in the Jupyter web interface and when to run the script, because most of the times it fails with Could not initialize class org.slf4j.LoggerFactory (HeadlessAnalyzer) java.lang.NoClassDefFoundError: Could not initialize class org.slf4j.LoggerFactory
but sometimes it works.
Could not initialize class org.slf4j.LoggerFactory (HeadlessAnalyzer) java.lang.NoClassDefFoundError: Could not initialize class org.slf4j.LoggerFactory
at org.jetbrains.kotlinx.jupyter.config.LoggingKt.getLogger(logging.kt:9)
at org.jetbrains.kotlinx.jupyter.config.LoggingKt.getLogger$default(logging.kt:9)
at org.jetbrains.kotlinx.jupyter.libraries.ResolutionUtilKt.<clinit>(resolutionUtil.kt:9)
at org.jetbrains.kotlinx.jupyter.KernelConfig$Companion.create(config.kt:167)
at org.jetbrains.kotlinx.jupyter.IkotlinKt.embedKernel(ikotlin.kt:105)
at HeadlessNotebook.run(HeadlessNotebook.kt:27)
at ghidra.app.script.GhidraScript.executeNormal(GhidraScript.java:379)
at ghidra.app.script.GhidraScript.doExecute(GhidraScript.java:234)
at ghidra.app.script.GhidraScript.execute(GhidraScript.java:212)
at ghidra.app.util.headless.HeadlessAnalyzer.runScript(HeadlessAnalyzer.java:576)
at ghidra.app.util.headless.HeadlessAnalyzer.runScriptsList(HeadlessAnalyzer.java:909)
at ghidra.app.util.headless.HeadlessAnalyzer.processWithImport(HeadlessAnalyzer.java:1765)
at ghidra.app.util.headless.HeadlessAnalyzer.processLocal(HeadlessAnalyzer.java:445)
at ghidra.app.util.headless.AnalyzeHeadless.launch(AnalyzeHeadless.java:121)
at ghidra.GhidraLauncher.launch(GhidraLauncher.java:59)
at ghidra.GhidraLauncher.main(GhidraLauncher.java:74)
@tmr232 you built the Notebook proxy, what do you think is the best way to allow this to work both in the GUI and from a script in headless mode? I'm quite confused why this logging class error only happens sometimes, I guess there are some kind of incompatible libraries involved here.
Script:
import GhidraJupyterKotlin.CellContext
import GhidraJupyterKotlin.NotebookProxy
import ghidra.app.script.GhidraScript
import ghidra.util.Msg
import ghidra.util.task.DummyCancellableTaskMonitor
import org.jetbrains.kotlinx.jupyter.embedKernel
import org.jetbrains.kotlinx.jupyter.libraries.EmptyResolutionInfoProvider
import java.nio.file.Path
import java.util.*
class HeadlessNotebook : GhidraScript() {
override fun run() {
val proxyPath = Path.of(
Optional.ofNullable(System.getenv("GHIDRA_JUPYTER_PROXY"))
.orElse(
Path.of(System.getProperty("user.home"))
.resolve(".ghidra")
.resolve("notebook_proxy")
.toString()
)
)
val connectionFile = NotebookProxy(proxyPath).waitForConnection(DummyCancellableTaskMonitor())
Msg.info(this, connectionFile.toString())
embedKernel(
connectionFile,
EmptyResolutionInfoProvider, listOf<CellContext>(CellContext(this))
)
}
}
Is there a way to run a kotlin jupyter notebook without starting the Ghidra GUI? That would be helpful when developing scripts on a server.