Skip to content

Commit 379983a

Browse files
Jojekermahaloz
andauthored
Port Ghidra Plugin to Support Ghidra 11.3.1 (#108)
* Port Ghidra Plugin to Support Ghidra 11.3.1 A bunch of things were deprecated (ProgramEvents) and some small nits are added. * move builder to 11.3.1 * bump to gradle 8.5 * move Java to 21 *corsses fingers* * bump ghidra in readme * bump d2d version --------- Co-authored-by: mahaloz <[email protected]>
1 parent ab87951 commit 379983a

File tree

6 files changed

+47
-43
lines changed

6 files changed

+47
-43
lines changed

.github/workflows/ghidra-build.yml

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
name: Ghidra Extension Build
22

33
env:
4-
ghidra-url: https://github.com/NationalSecurityAgency/ghidra/releases/download/Ghidra_10.3.2_build/ghidra_10.3.2_PUBLIC_20230711.zip
5-
ghidra-zip-filename: ghidra_10.3.2_PUBLIC.zip
6-
ghidra-directory: ghidra_10.3.2_PUBLIC
4+
ghidra-url: https://github.com/NationalSecurityAgency/ghidra/releases/download/Ghidra_11.3.1_build/ghidra_11.3.1_PUBLIC_20250219.zip
5+
ghidra-zip-filename: ghidra_11.3.1_PUBLIC.zip
6+
ghidra-directory: ghidra_11.3.1_PUBLIC
77

88
on:
99
workflow_run:
@@ -37,19 +37,19 @@ jobs:
3737
args: unzip -qq ${{ steps.download-ghidra.outputs.file-path }} -d .
3838
- uses: actions/setup-java@v1
3939
with:
40-
java-version: '17.0.6'
40+
java-version: '21'
4141

4242
- name: Build extension
4343
uses: eskatos/gradle-command-action@v1
4444
with:
45-
gradle-version: '7.3'
45+
gradle-version: '8.5'
4646
build-root-directory: ${{ github.workspace }}/decompilers/d2d_ghidra/
4747
arguments: '-PGHIDRA_INSTALL_DIR=${{ github.workspace }}/${{ env.ghidra-directory }}'
4848

4949
- name: Rename extension
5050
run: cd decompilers/d2d_ghidra/dist/ && mv *.zip d2d-ghidra-plugin.zip
5151
- name: Upload built extension
52-
uses: actions/upload-artifact@v2
52+
uses: actions/upload-artifact@v4
5353
with:
5454
name: extension
5555
path: decompilers/d2d_ghidra/dist/d2d-ghidra-plugin.zip
@@ -61,7 +61,7 @@ jobs:
6161

6262
steps:
6363
- name: Download built extension
64-
uses: actions/download-artifact@v2
64+
uses: actions/download-artifact@v4
6565
with:
6666
name: extension
6767
- name: Upload To Github Release

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ For active help, join the BinSync Discord below, where we answer decomp2dbg ques
2121
### Decompilers
2222
- IDA Pro (>= 7.0): [Demo w/ GEF](https://asciinema.org/a/442740)
2323
- Binary Ninja (>= 2.4): [Demo w/ GEF](https://t.co/M2IZd0fmi3)
24-
- Ghidra (>= 10.1): [Demo w/ GEF](https://youtu.be/MK7N7uQTUNY)
24+
- Ghidra (>= 11.3.1): [Demo w/ GEF](https://youtu.be/MK7N7uQTUNY)
2525
- [angr-management](https://github.com/angr/angr-management) (>= 9.0)
2626

2727
### Debuggers

decomp2dbg/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "3.9.6"
1+
__version__ = "3.10.0"
22

33
try:
44
from .clients.client import DecompilerClient

decompilers/d2d_ghidra/src/main/java/decomp2dbg/D2DGhidraProcessorFactoryFactory.java

+2
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ public D2DGhidraProcessorFactoryFactory(D2DGhidraServerAPI api) {
1212
this.api = api;
1313
}
1414

15+
@Override
1516
public RequestProcessorFactory getRequestProcessorFactory(Class aClass)
1617
throws XmlRpcException {
1718
return factory;
1819
}
1920

2021
private class D2DGhidraProcessorFactory implements RequestProcessorFactory {
22+
@Override
2123
public Object getRequestProcessor(XmlRpcRequest xmlRpcRequest)
2224
throws XmlRpcException {
2325
return api;

decompilers/d2d_ghidra/src/main/java/decomp2dbg/D2DGhidraServerAPI.java

+9-7
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
import ghidra.app.util.bin.MemoryByteProvider;
1010
import ghidra.app.util.bin.format.elf.ElfException;
1111
import ghidra.app.util.bin.format.elf.ElfHeader;
12+
import ghidra.program.model.data.DataTypeComponent;
1213
import ghidra.program.model.listing.Function;
14+
import ghidra.program.model.listing.FunctionIterator;
1315
import ghidra.program.model.symbol.Symbol;
1416
import ghidra.program.model.symbol.SymbolType;
1517
import ghidra.util.Msg;
1618

1719
public class D2DGhidraServerAPI {
18-
private D2DGhidraServer server;
20+
private final D2DGhidraServer server;
1921

2022
public D2DGhidraServerAPI(D2DGhidraServer server) {
2123
this.server = server;
@@ -48,7 +50,7 @@ public Map<String, Object> decompile(Integer addr) {
4850

4951
var rebasedAddr = this.server.plugin.rebaseAddr(addr, false);
5052
var func = this.server.plugin.getNearestFunction(rebasedAddr);
51-
var rebasedAddrLong = rebasedAddr.getOffset();
53+
long rebasedAddrLong = rebasedAddr.getOffset();
5254

5355
if(func == null) {
5456
Msg.warn(server, "Failed to find a function by the address " + addr);
@@ -68,7 +70,7 @@ public Map<String, Object> decompile(Integer addr) {
6870
resp.put("decompilation", decLines);
6971

7072
PrettyPrinter pp = new PrettyPrinter(func, dec.getCCodeMarkup(), null);
71-
ArrayList<ClangLine> lines = pp.getLines();
73+
ArrayList<ClangLine> lines = (ArrayList<ClangLine>) pp.getLines();
7274

7375
// locate the decompilation line
7476
Boolean lineFound = false;
@@ -119,7 +121,7 @@ public Map<String, Object> function_headers() {
119121
Map<String, Object> resp = new HashMap<>();
120122
var program = this.server.plugin.getCurrentProgram();
121123
var fm = program.getFunctionManager();
122-
var functions = fm.getFunctions(true);
124+
FunctionIterator functions = fm.getFunctions(true);
123125
for (Function func : functions) {
124126
if(func == null)
125127
continue;
@@ -175,7 +177,7 @@ public Map<String, Object> structs() {
175177
Map<String, Object> structInfo = new HashMap<>();
176178
structInfo.put("name", struct.getName());
177179
// Enumerate members
178-
var members = struct.getComponents();
180+
DataTypeComponent[] members = struct.getComponents();
179181
// For unknown reasons, the API claims that some targets have structures with a crazy number of members (in the millions).
180182
// This causes an infinite loop.
181183
// May be caused by a bug in some other plugin, not sure.
@@ -262,7 +264,7 @@ public Map<String, Object> unions() {
262264
Map<String, Object> unionInfo = new HashMap<>();
263265
unionInfo.put("name", union.getName());
264266
// Enumerate members
265-
var members = union.getComponents();
267+
DataTypeComponent[] members = union.getComponents();
266268
ArrayList<Object> memberInfo = new ArrayList<>();
267269
for (var member : members) {
268270
Map<String, Object> memberData = new HashMap<>();
@@ -338,7 +340,7 @@ public Map<String, Object> elf_info() {
338340

339341
var program = this.server.plugin.getCurrentProgram();
340342
var provider = new MemoryByteProvider(program.getMemory(), program.getMinAddress());
341-
ElfHeader header = null;
343+
ElfHeader header;
342344
try {
343345
header = new ElfHeader(provider, null);
344346
}

decompilers/d2d_ghidra/src/main/java/decomp2dbg/D2DPlugin.java

+27-27
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
import ghidra.program.model.listing.Function;
3333
import ghidra.program.model.listing.Program;
3434
import ghidra.program.model.pcode.HighSymbol;
35-
import ghidra.program.util.ChangeManager;
3635
import ghidra.program.util.ProgramChangeRecord;
36+
import ghidra.program.util.ProgramEvent;
3737
import ghidra.util.Msg;
3838
import ghidra.util.task.ConsoleTaskMonitor;
3939

@@ -125,8 +125,8 @@ private void configureD2DServer() {
125125
};
126126

127127
int option = JOptionPane.showConfirmDialog(null, message, "Login", JOptionPane.OK_CANCEL_OPTION);
128-
String host = null;
129-
int port = 0;
128+
String host;
129+
int port;
130130
if (option == JOptionPane.OK_OPTION) {
131131
host = hostField.getText();
132132
try {
@@ -218,7 +218,7 @@ public Map<String, Object> getFuncData(Integer addr) {
218218
return funcInfo;
219219
}
220220

221-
ArrayList<HighSymbol> symbols = new ArrayList<HighSymbol>();
221+
ArrayList<HighSymbol> symbols = new ArrayList<>();
222222
Map<String, Object> regVars = new HashMap<>();
223223
Map<String, Object> stackVars = new HashMap<>();
224224
dec.getHighFunction().getLocalSymbolMap().getSymbols().forEachRemaining(symbols::add);
@@ -251,38 +251,38 @@ public void domainObjectChanged(DomainObjectChangedEvent ev) {
251251
// also look at:
252252
// https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AutoAnalysisManager.java
253253

254-
ArrayList<Integer> funcEvents = new ArrayList<>(Arrays.asList(
255-
ChangeManager.DOCR_FUNCTION_CHANGED,
256-
ChangeManager.DOCR_FUNCTION_BODY_CHANGED,
257-
ChangeManager.DOCR_VARIABLE_REFERENCE_ADDED,
258-
ChangeManager.DOCR_VARIABLE_REFERENCE_REMOVED
254+
ArrayList<ProgramEvent> funcEvents = new ArrayList<>(Arrays.asList(
255+
ProgramEvent.FUNCTION_CHANGED,
256+
ProgramEvent.FUNCTION_BODY_CHANGED,
257+
ProgramEvent.VARIABLE_REFERENCE_ADDED,
258+
ProgramEvent.VARIABLE_REFERENCE_REMOVED
259259
));
260260

261-
ArrayList<Integer> symDelEvents = new ArrayList<>(Arrays.asList(
262-
ChangeManager.DOCR_SYMBOL_REMOVED
261+
ArrayList<ProgramEvent> symDelEvents = new ArrayList<>(Arrays.asList(
262+
ProgramEvent.SYMBOL_REMOVED
263263
));
264264

265-
ArrayList<Integer> symChgEvents = new ArrayList<>(Arrays.asList(
266-
ChangeManager.DOCR_SYMBOL_ADDED,
267-
ChangeManager.DOCR_SYMBOL_RENAMED,
268-
ChangeManager.DOCR_SYMBOL_DATA_CHANGED
265+
ArrayList<ProgramEvent> symChgEvents = new ArrayList<>(Arrays.asList(
266+
ProgramEvent.SYMBOL_ADDED,
267+
ProgramEvent.SYMBOL_RENAMED,
268+
ProgramEvent.SYMBOL_DATA_CHANGED
269269
));
270270

271-
ArrayList<Integer> typeEvents = new ArrayList<>(Arrays.asList(
272-
ChangeManager.DOCR_DATA_TYPE_CHANGED,
273-
ChangeManager.DOCR_DATA_TYPE_REPLACED,
274-
ChangeManager.DOCR_DATA_TYPE_RENAMED,
275-
ChangeManager.DOCR_DATA_TYPE_SETTING_CHANGED,
276-
ChangeManager.DOCR_DATA_TYPE_MOVED,
277-
ChangeManager.DOCR_DATA_TYPE_ADDED
271+
ArrayList<ProgramEvent> typeEvents = new ArrayList<>(Arrays.asList(
272+
ProgramEvent.DATA_TYPE_CHANGED,
273+
ProgramEvent.DATA_TYPE_REPLACED,
274+
ProgramEvent.DATA_TYPE_RENAMED,
275+
ProgramEvent.DATA_TYPE_SETTING_CHANGED,
276+
ProgramEvent.DATA_TYPE_MOVED,
277+
ProgramEvent.DATA_TYPE_ADDED
278278
));
279279

280280
for (DomainObjectChangeRecord record : ev) {
281281
// only analyze changes to the current program
282282
if( !(record instanceof ProgramChangeRecord) )
283283
continue;
284284

285-
int chgType = record.getEventType();
285+
ProgramEvent chgType = (ProgramEvent) record.getEventType();
286286
var pcr = (ProgramChangeRecord) record;
287287
var obj = pcr.getObject();
288288
var newVal = pcr.getNewValue();
@@ -336,11 +336,11 @@ else if (symChgEvents.contains(chgType)) {
336336
/*
337337
* GlobalVar & Label
338338
*/
339-
else if(obj instanceof CodeSymbol) {
339+
else if(obj instanceof CodeSymbol codeSymbol) {
340340
if(this.gVarCache.isEmpty())
341341
continue;
342342

343-
var sym = (CodeSymbol) obj;
343+
var sym = codeSymbol;
344344
var newName = sym.getName();
345345
var addr = sym.getAddress().getOffset();
346346

@@ -353,11 +353,11 @@ else if(obj instanceof CodeSymbol) {
353353
/*
354354
* Function Name
355355
*/
356-
else if(obj instanceof FunctionSymbol) {
356+
else if(obj instanceof FunctionSymbol functionSymbol) {
357357
if(this.funcSymCache.isEmpty())
358358
continue;
359359

360-
var sym = (FunctionSymbol) obj;
360+
var sym = functionSymbol;
361361
var newName = sym.getName();
362362
var addr = sym.getAddress().getOffset();
363363

0 commit comments

Comments
 (0)