// Find xrefs to cruise-related memory addresses in Cerato firmware
//@category Analysis
//@author cebers

import java.util.ArrayList;
import java.util.List;
import ghidra.app.script.GhidraScript;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressFactory;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.FunctionManager;
import ghidra.program.model.listing.Instruction;
import ghidra.program.model.listing.Listing;
import ghidra.program.model.symbol.Reference;
import ghidra.program.model.symbol.ReferenceIterator;
import ghidra.program.model.symbol.ReferenceManager;

public class FindCruise extends GhidraScript {

    private List<Reference> collect(ReferenceManager refMgr, Address a) {
        List<Reference> list = new ArrayList<>();
        ReferenceIterator it = refMgr.getReferencesTo(a);
        while (it.hasNext()) list.add(it.next());
        return list;
    }

    @Override
    public void run() throws Exception {
        AddressFactory af = currentProgram.getAddressFactory();
        Listing listing = currentProgram.getListing();
        ReferenceManager refMgr = currentProgram.getReferenceManager();
        FunctionManager fm = currentProgram.getFunctionManager();

        println("================================================================");
        println("CRUISE-ADDRESS XREF ANALYSIS");
        println("================================================================");

        // 1) Full cluster scan: 0x80020200..0x800202C0
        println("\n=== Scan 0x80020200..0x800202C0 (cruise-config region) ===");
        int totalRefs = 0;
        int hits = 0;
        for (long off = 0x80020200L; off < 0x800202C0L; off++) {
            Address a = af.getAddress(Long.toHexString(off));
            List<Reference> refs = collect(refMgr, a);
            if (refs.size() > 0) {
                hits++;
                println(String.format("\n  0x%08X: %d xrefs", off, refs.size()));
                totalRefs += refs.size();
                for (int i = 0; i < refs.size(); i++) {
                    Reference r = refs.get(i);
                    Address from = r.getFromAddress();
                    Function func = fm.getFunctionContaining(from);
                    String fname = (func != null) ? func.getName() : "<no-func>";
                    String fent = (func != null) ? func.getEntryPoint().toString() : "n/a";
                    Instruction ins = listing.getInstructionAt(from);
                    String insStr = (ins != null) ? ins.toString() : "<no-ins>";
                    println(String.format("    from 0x%s type=%s in func [%s @ 0x%s]",
                            from.toString(), r.getReferenceType().getName(), fname, fent));
                    println(String.format("      insn: %s", insStr));
                }
            }
        }
        println(String.format("\nSummary: %d addresses with xrefs, %d total xrefs", hits, totalRefs));

        println("\n================================================================");
        println("DONE");
    }
}
