Last active
August 3, 2024 22:58
-
-
Save mrexodia/a48a9b2f5eac40a8efb2756e6483ff31 to your computer and use it in GitHub Desktop.
Actually nice to use references for Ghidra
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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