NationalSecurityAgency / ghidra

Ghidra is a software reverse engineering (SRE) framework
https://www.nsa.gov/ghidra
Apache License 2.0
51.92k stars 5.89k forks source link

Ghidra headless script with custom library: NoClassDefFoundError #2117

Closed ghost closed 4 years ago

ghost commented 4 years ago

Hello there,

I am trying to launch a custom ghidra script MyScript.java that relies on an homemade library mylibrary based on the ghidra SDK.

I created a new module project via the GhidraDev eclipse plugin, and I am able to successfully use my script and my custom library when running ghidra in GUI mode.

However, when I switch to headless mode and run my script, I get the following error:

2020-07-20 11:28:28 ERROR (JavaScriptProvider) Unable to find class file for script file: /path/to/MyScriptjava java.lang.NoClassDefFoundError: mylibrary.CustomClass  

I have mylibrary stored in src/main/java, and MyScript.java in ghidra_scripts/. Additionnaly, I built my plugin using gradle with a simple gradle buildExtension, that puts my compiled classes in the build folder.

My invocation of the headless mode is as follows (when I am located in MyProject folder, the root one created by GhidraDev:

$GHIDRA_DIR/support/analyzeHeadless ~ my_project -import file.o -scriptPath ./ghidra_scripts/ -postScript MyScript.java -overwrite

Is there a way to tell ghidra in headless mode to check for classes in any specific directory ? Or is there any workaround for this issue ?

ryanmkurtz commented 4 years ago

Is your library a jar? If so, it should live in the lib folder of your GhidraDev module project.

ghost commented 4 years ago

I took my library's .jar generated by Gradle (in build/libs/) and put in in the lib/ folder but it didn't solve the issue

ryanmkurtz commented 4 years ago

Ghidra will take every jar it finds in the lib directories and add them to the classpath. So your jar ends up living at <GHIDRA_DIR>/Ghidra/Extensions/<YOUR_EXTENSION>/lib/<YOUR_JAR>.jar?

ghost commented 4 years ago

Indeed !

I checked mylibrary.jar and every .class file is available so I don't really know what to do next

ryanmkurtz commented 4 years ago

Can you try dropping your jar in <GHIDRA_DIR>/Ghidra/Features/Base/lib/ and then try again?

ghost commented 4 years ago

All right it worked

ryanmkurtz commented 4 years ago

Are you using Ghidra 9.1.2?

ghost commented 4 years ago

Yep

ryanmkurtz commented 4 years ago

Hmmm, it would have to be tested against 9.2-DEV to know if there's still a bug in there.

ghost commented 4 years ago

Tested on 9.2-DEV and it worked, so this should no longer be an issue ! I will be using this version from now :)

ghost commented 4 years ago

Is there a way to build & run my extension outside of the source tree (i.e somewhere else than the Extensions/ folder) ?

ryanmkurtz commented 4 years ago

If you are developing a module with GhidraDev, your Eclipse project for that module can live anywhere on the file system. When you launch Ghidra through Eclipse/GhidraDev, Eclipse puts your project on the classpath and Ghidra will automatically find it. When you install your extension from the distributable zip file, it will always get unzipped/installed to Ghidra/Extensions for 9.1.2, and now for 9.2-DEV, it will get installed to ~/.ghidra/.ghidra-<version>/Extensions.

Does that answer your question?

ghost commented 4 years ago

Yes, as I launched ghidra headless using a custom bash script and not the via the Eclipse/GhidraDev extension I guess my classpath was not updated ...

xzhou29 commented 3 years ago

All right it worked

How did you make it work

xzhou29 commented 3 years ago

tried to run -postScript for extension "BinExport.jar" under Ghidra/Extension/BinExport/lib/.

ERROR REPORT SCRIPT ERRPR: .......: BinExportExporter (HeadlessAnalyzer) java.lang.ClassNotFoundException: BinExportExporter

I'm using 9.1.2 ghidra headless

ryanmkurtz commented 3 years ago

The headless -postScript command line argument expects a GhidraScript filename, something like HelloWorldScript.java. You cannot give it a jar.