fix: Resolve compatibility issues with Ghidra API

- Add helper method to handle ReferenceIterator conversion
- Support both Reference[] and ReferenceIterator types
- Replace LocationService with reflection-based approach
- Use listing's defined addresses as fallback
This commit is contained in:
Teal Bauer 2025-04-14 09:27:49 +02:00
parent 2b1fe6c4e1
commit 0eaa19a6e8

View File

@ -38,6 +38,24 @@ public class XrefsEndpoints extends AbstractEndpoint {
return tool; return tool;
} }
/**
* Helper method to convert ReferenceIterator to an iterable collection
*/
private List<Reference> collectReferences(ReferenceIterator iterator) {
List<Reference> references = new ArrayList<>();
while (iterator.hasNext()) {
references.add(iterator.next());
}
return references;
}
/**
* Helper method to convert Reference[] to a list
*/
private List<Reference> collectReferences(Reference[] refs) {
return Arrays.asList(refs);
}
@Override @Override
public void registerEndpoints(HttpServer server) { public void registerEndpoints(HttpServer server) {
server.createContext("/xrefs", this::handleXrefsRequest); server.createContext("/xrefs", this::handleXrefsRequest);
@ -104,9 +122,8 @@ public class XrefsEndpoints extends AbstractEndpoint {
// Get references to this address // Get references to this address
if (toAddr != null) { if (toAddr != null) {
ReferenceIterator refsTo = refManager.getReferencesTo(toAddr); // Get references to this address - must manually convert array
while (refsTo.hasNext()) { for (Reference ref : collectReferences(refManager.getReferencesTo(toAddr))) {
Reference ref = refsTo.next();
if (refTypeStr != null && !ref.getReferenceType().getName().equalsIgnoreCase(refTypeStr)) { if (refTypeStr != null && !ref.getReferenceType().getName().equalsIgnoreCase(refTypeStr)) {
continue; // Skip if type filter doesn't match continue; // Skip if type filter doesn't match
} }
@ -118,9 +135,8 @@ public class XrefsEndpoints extends AbstractEndpoint {
// Get references from this address // Get references from this address
if (fromAddr != null) { if (fromAddr != null) {
ReferenceIterator refsFrom = refManager.getReferencesFrom(fromAddr); // Get references from this address - must manually convert array
while (refsFrom.hasNext()) { for (Reference ref : collectReferences(refManager.getReferencesFrom(fromAddr))) {
Reference ref = refsFrom.next();
if (refTypeStr != null && !ref.getReferenceType().getName().equalsIgnoreCase(refTypeStr)) { if (refTypeStr != null && !ref.getReferenceType().getName().equalsIgnoreCase(refTypeStr)) {
continue; // Skip if type filter doesn't match continue; // Skip if type filter doesn't match
} }
@ -292,23 +308,32 @@ public class XrefsEndpoints extends AbstractEndpoint {
ghidra.app.services.ProgramManager programManager = ghidra.app.services.ProgramManager programManager =
tool.getService(ghidra.app.services.ProgramManager.class); tool.getService(ghidra.app.services.ProgramManager.class);
if (programManager != null && programManager.getCurrentProgram() == program) { if (programManager != null && programManager.getCurrentProgram() == program) {
// In Ghidra 11+, use the current cursor location // Try to get the current location using CurrentLocation service
ghidra.app.services.LocationService locationService = try {
tool.getService(ghidra.app.services.LocationService.class); // Try to find the current location from the program manager
if (locationService != null) { java.lang.reflect.Method getCurrentLocationMethod =
ghidra.program.util.ProgramLocation location = locationService.getLocation(); programManager.getClass().getMethod("getCurrentLocation");
if (getCurrentLocationMethod != null) {
ghidra.program.util.ProgramLocation location =
(ghidra.program.util.ProgramLocation)getCurrentLocationMethod.invoke(programManager);
if (location != null && location.getProgram() == program) { if (location != null && location.getProgram() == program) {
return location.getAddress(); return location.getAddress();
} }
} }
} catch (Exception e) {
// Method doesn't exist, ignore and continue with other approaches
}
// Try selection service as a last resort // If program is selected, use its memory address as a fallback
ghidra.app.services.SelectionService selectionService = if (program.equals(programManager.getCurrentProgram())) {
tool.getService(ghidra.app.services.SelectionService.class); ghidra.program.model.listing.Listing listing = program.getListing();
if (selectionService != null) { if (listing != null) {
ghidra.program.util.ProgramSelection selection = selectionService.getCurrentSelection(); // Return the first defined address we can find
if (selection != null && !selection.isEmpty()) { ghidra.program.model.address.AddressIterator definedAddresses =
return selection.getMinAddress(); listing.getDefinedAddresses();
if (definedAddresses.hasNext()) {
return definedAddresses.next();
}
} }
} }
} }