0

I tried several hours to find a way to get the operand address which is displayed in the ghidra listing, but without success:

indirect operand address

I know at least that the OperandType is "Address".

import ghidra.program.model.lang.OperandType;

int ot1 = ins1.getOperandType(1);
boolean indirect1 = OperandType.isAddress(ot1); 
                // --> result is true

The op_rep = ins1.getDefaultOperandRepresentation(1) is of course [a0]-0x38d8 but I want the resolved reference / address DAT_d0006b78, or with the next instruction, the address of the symbol in the first operand, the address of ACCI_trqDes.

If I use currentProgram.getAddressFactory().getAddress(op_rep) the resulting address is null.

I tried it also via PcodeOp[] pc = ins1.getPcode(opIndex); but I was much too stupid to understand it.

How can I get this? Thanks a lot!

2 Answers 2

3

This is done with the code/data references related API. See the code below (not checked too much, but runs on my last project, in python):

# These imports are accessible when you run the script inside Ghidra
from ghidra.program.model.listing import CodeUnit
from ghidra.program.model.symbol import RefType
from ghidra.program.database import ProgramDB
from ghidra.program.flatapi import FlatProgramAPI

# Mimic getting the current program (In Ghidra's Script Manager, currentProgram is globally available)
state = getState()  # Assume getState() returns the current program state
currentProgram = state.getCurrentProgram()

# Define FlatProgramAPI object for more convenient function calls
flat_api = FlatProgramAPI(currentProgram)

def getReferencesFrom(address):
    return flat_api.getReferencesFrom(address)

def find_data_references_from_address(source_address):
    # Convert the source_address parameter to a Ghidra Address object
    source_addr = currentProgram.getAddressFactory().getAddress(source_address)
        
    # Initialize an empty list to store the referred addresses
    referred_addresses = []
        
    # Get the references from the source address
    references = getReferencesFrom(source_addr)
        
    # Loop through the references to find data references
    for ref in references:
        # Determine the type of the reference
        ref_type = ref.getReferenceType()
            
        # Check if it's a data reference
        if ref_type.isData():
            # Get the address of the code unit that is referred by the source address
            to_addr = ref.getToAddress()
                
            # Add the referred address to our list
            referred_addresses.append(str(to_addr))

    return referred_addresses

# Example usage:
source_address = "0x11390"  # Replace with the source address you're interested in
result = find_data_references_from_address(source_address)
print("Addresses referred to by {}: {}".format(source_address, result))

References to Ghidra API documentation may be found here.

Java variant of the same script with small addition that determines if it is read/write or read+write reference:

import ghidra.app.script.GhidraScript;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.Reference;
import ghidra.program.model.symbol.ReferenceManager;
import ghidra.program.model.symbol.RefType;
import java.util.ArrayList;
import java.util.List;

public class FindDataReferences extends GhidraScript {

    public List<String> findDataReferencesFromAddress(Program program, String sourceAddress) throws Exception {
        List<String> referredAddresses = new ArrayList<>();

        Address sourceAddr = program.getAddressFactory().getAddress(sourceAddress);
        ReferenceManager refManager = program.getReferenceManager();

        Reference[] references = refManager.getReferencesFrom(sourceAddr);

        for (Reference ref : references) {
            RefType refType = ref.getReferenceType();
            
            String typeDescription = "";
            if (refType.isRead() && refType.isWrite()) {
                typeDescription = "read/write";
            } else if (refType.isRead()) {
                typeDescription = "read";
            } else if (refType.isWrite()) {
                typeDescription = "write";
            }

            if (!typeDescription.isEmpty()) {
                Address toAddr = ref.getToAddress();
                referredAddresses.add(String.format("%s (%s)", toAddr.toString(), typeDescription));
            }
        }

        return referredAddresses;
    }

    @Override
    public void run() throws Exception {
        String sourceAddress = "0x113e8"; // Replace this with your source address

        List<String> result = findDataReferencesFromAddress(currentProgram, sourceAddress);
        println("Addresses referred to by " + sourceAddress + ": " + result);
    }
}
1
  • Ah, you approach it from reverse direction. This works nicely, thanks!
    – karsten
    Aug 29, 2023 at 13:18
0
   14098c632 48 89 44 24 28            MOV      qword ptr [RSP + local_40],RAX=>KiSchedulerApc

for a line like above you want the operand Representation?

you mean something like this

>>> currentLocation
OperandFieldLocation@14098c632, refAddr=1402fa5b0, row=0, col=1, charOffset=12, OpRep = RAX=>KiSchedulerApc, subOpIndex = 0, VariableOffset = null
>>> currentLocation.getOperandRepresentation()
u'RAX=>KiSchedulerApc'
1
  • Thank you, but I wanted the address referenced, which is shown in the ghidra listing in the form of e.g. "=> DAT_d0006b78".
    – karsten
    Aug 30, 2023 at 8:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.