google / binexport

Export disassemblies into Protocol Buffers
Apache License 2.0
1.03k stars 197 forks source link

Can't use latest ghidra_BinExport.zip with Ghidra 10.1.x #91

Closed throwaway-a closed 5 months ago

throwaway-a commented 2 years ago

I have Ghidra 10.1.2 installed, and when I try to "Install Extension" for this I get the error

Extension version for [ghidra_BinExport.zip] is incompatible with Ghidra.
---------------------------------------------------
Build Date: 2022-Jan-25 1526 EST
Ghidra Version: 10.1.2
Java Home: /home/user/jdk-17
JVM Version: Oracle Corporation 17
OS: Linux 5.13.0-51-generic amd64
Workstation: ubuntu
throwaway-a commented 2 years ago

Interestingly, I would note that that version also doesn't work on 10.0.4, whereas this one does. Why did it stop working for just a newer release, but the same version of Ghidra? Was the availability of the thing called "ghidra_BinExport" in the release mentioning BinaryNinja in error?)

cblichmann commented 2 years ago

No that wasn't an error. It's likely due to the way BinExport is built (internally, we still build with 10.1.3). Ghidra's extension versioning is... not great. They basically treat each release, however minor, as a major breaking API change and plugins need to specify versions in a very particular way. If you'd build BinExport yourself on your machine, I'm pretty sure the resulting .zip will work.

cblichmann commented 2 years ago

Labelling as "Enhancement", as this should really only need an upgrade to the build host to use a newer Ghidra.

throwaway-a commented 2 years ago

Updating request for a 10.1.4 version, since that's the latest version available for BinDiffHelper (even though 10.1.5 is out right now.)

cblichmann commented 2 years ago

I'll update the release binaries a bit later. Here is one for 10.1.4: ghidra_BinExport.zip

tosbaha commented 2 years ago

This one crashes during export with Ghidra 10.1.4. It says

2022-08-13 | 13:02:27 | ERROR | (ExportTask) Exception exporting java.lang.NullPointerException
-- | -- | -- | --
  |   |   | at com.google.security.binexport.BinExport2Builder.buildFlowGraphs(BinExport2Builder.java:291)
  |   |   | at com.google.security.binexport.BinExport2Builder.build(BinExport2Builder.java:543)
  |   |   | at com.google.security.binexport.BinExportExporter.export(BinExportExporter.java:99)
  |   |   | at ghidra.app.plugin.core.exporter.ExporterDialog$ExportTask.run(ExporterDialog.java:489)
  |   |   | at ghidra.util.task.Task.monitoredRun(Task.java:134)
  |   |   | at ghidra.util.task.TaskRunner.lambda$startTaskThread$0(TaskRunner.java:106)
  |   |   | at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
  |   |   | at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
  |   |   | at java.base/java.lang.Thread.run(Thread.java:829)
cblichmann commented 2 years ago

Thanks, does this happen for every binary? I might be able to look into this later today.

tosbaha commented 2 years ago

I have tried this on 2 eCos binaries that I have decompiled successfully. It could be because of this file type or some functions that point to memory regions that don't exist. Null reference error could be because of wrong decompiled regions. I am attaching the binary and I hope it helps. I used the following settings to decompile it

Language MIPS default 32 Big Endian
Base Address 0x80004000

original.out.zip

cblichmann commented 2 years ago

Thanks that should make debugging a bit easier

cblichmann commented 2 years ago

I had some time to look into this today. It seems that Ghidra does not enumerate all basic blocks when iterating over all instructions of the program versus when iterating over the basic blocks of the function. I have yet to understand why. For example, in the binary you shared, BinExport will not create a basic block for the one at 0x80004fa8 and hence the lookup in buildFlowGraphs() will fail. Hower, all the instructions are there (and are properly indexed). Since this does not seem to happen on other archs, my guess is that it has something to do with the branch-delay slots and the way we create initial basic blocks for the BinExport proto. Simply skipping the basic blocks with errors leads to a useless .BinExport file, as probably expected.