Skip to content

Instantly share code, notes, and snippets.

@mrexodia
Last active May 5, 2023 23:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrexodia/a48a9b2f5eac40a8efb2756e6483ff31 to your computer and use it in GitHub Desktop.
Save mrexodia/a48a9b2f5eac40a8efb2756e6483ff31 to your computer and use it in GitHub Desktop.
Actually nice to use references for Ghidra
// Emulate IDA's xref window
//@author Duncan Ogilvie
//@category Analysis
//@keybinding X
//@menupath Navigation.IDA References
//@toolbar
// Reference: https://www.reddit.com/r/ghidra/comments/h07yoo/comment/fukuj1c
import ghidra.app.cmd.data.CreateArrayCmd;
import ghidra.app.decompiler.ClangFuncNameToken;
import ghidra.app.decompiler.ClangVariableToken;
import ghidra.app.decompiler.DecompilerLocation;
import ghidra.app.plugin.core.references.ReferencesPlugin;
import ghidra.app.script.GhidraScript;
import ghidra.framework.cmd.CompoundCmd;
import ghidra.program.model.address.Address;
import ghidra.program.model.symbol.SymbolType;
import ghidra.program.util.*;
public class IDAReferences extends GhidraScript {
private boolean findReferences(Address addressTo, String type) {
println(String.format("References to %s => %s (%s):", type, addressTo, getSymbolAt(addressTo)));
for (var reference : getReferencesTo(addressTo)) {
var functionInfo = "";
var fromAddress = reference.getFromAddress();
var fromFunction = getFunctionContaining(fromAddress);
if (fromFunction != null) {
functionInfo = String.format(" from function: %s (%s)", fromFunction.getEntryPoint(), fromFunction.getName());
}
println(String.format("%s (%s)%s", fromAddress, reference.getReferenceType(), functionInfo));
}
return true;
}
private boolean handleLocation(ProgramLocation abstractLocation) {
if (abstractLocation instanceof AddressFieldLocation location) {
// User directly selected an address
return findReferences(location.getAddress(), "address");
} else if (abstractLocation instanceof LabelFieldLocation location) {
// User directly selected a label
return findReferences(location.getAddress(), "label");
} else if (abstractLocation instanceof FunctionLocation location) {
return findReferences(location.getAddress(), "function");
} else if (abstractLocation instanceof DecompilerLocation location) {
var token = location.getToken();
if (token instanceof ClangFuncNameToken funcName) {
var op = token.getPcodeOp();
if (op == null) {
try {
var decompiledFunction = funcName.getClangFunction().getHighFunction().getFunction();
if (funcName.getText().equals(decompiledFunction.getName())) {
// User selected the decompiled function itself
return findReferences(decompiledFunction.getEntryPoint(), "decompiled function");
}
} catch (NullPointerException x) {
return false;
}
} else if (op.getMnemonic().equals("CALL")) {
var address = op.getInput(0).getAddress();
return findReferences(address, "decompiler call");
} else {
printerr(String.format("Unsupported op: %s", op));
}
} else if (token instanceof ClangVariableToken varToken) {
var op = token.getPcodeOp();
if (op.getMnemonic().equals("PTRSUB")) {
var offset = op.getInput(1).getAddress().getOffset();
var address = currentProgram.getAddressFactory().getDefaultAddressSpace().getAddress(offset);
return findReferences(address, "decompiler ptrsub");
}
}
} else if (abstractLocation instanceof OperandFieldLocation location) {
var refAddress = location.getRefAddress();
if (refAddress != null) {
if (refAddress.getAddressSpace() != currentProgram.getAddressFactory().getDefaultAddressSpace()) {
// TODO: support operand references?
return false;
}
return findReferences(refAddress, "operand");
}
}
return false;
}
@Override
protected void run() throws Exception {
println(String.format("State:\naddress: %s\nhighlight: %s\nlocation: %s\nselection: %s", currentAddress, currentHighlight, currentLocation, currentSelection));
if (!handleLocation(currentLocation)) {
printerr(String.format("UNSUPPORTED: %s (performing heuristics)", currentLocation));
var refAddress = currentLocation.getRefAddress();
var exactFunction = getFunctionAt(currentAddress);
var symbol = getSymbolAt(currentAddress);
if (refAddress != null && refAddress.getAddressSpace() == currentProgram.getAddressFactory().getDefaultAddressSpace()) {
findReferences(refAddress, "reference");
} else if (exactFunction != null) {
findReferences(exactFunction.getEntryPoint(), "function (heuristic)");
} else if (symbol != null) {
findReferences(symbol.getAddress(), "symbol (heuristic)");
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment