// Imports data from a file produced by the EnhancedExport script. // // @category Import import ghidra.app.script.GhidraScript; import ghidra.app.services.DataTypeQueryService; import ghidra.program.model.address.Address; import ghidra.program.model.data.DataType; import ghidra.program.model.listing.Data; import ghidra.program.model.listing.Function; import ghidra.program.model.symbol.Namespace; import ghidra.program.model.symbol.SourceType; import ghidra.program.model.symbol.Symbol; import java.io.FileReader; import java.util.Arrays; import java.util.List; import java.util.Optional; public class EnhancedImport extends GhidraScript{ @Override public void run() throws Exception { final FileReader in = new FileReader(askFile("Select input file", "OK")); final List lines = in.readAllLines(); in.close(); for (int i = 0; i < lines.size(); i++) { final String[] parts = lines.get(i).split("\t");; final Address addr = toAddr(parts[0]); switch (parts[1]) { case "data": importData(addr, parts); break; case "func": importFunc(addr, parts); break; default: throw new Exception( "Symbol type \"" + parts[1] + "\" on line " + Integer.toString(i) + " is not \"data\" or \"func\"" ); } } } private void importData( final Address addr, final String[] parts ) throws Exception { final String name = unqualified(parts[3]); print("Importing data symbol \"" + parts[3] + "\"..."); // Create symbol final Namespace ns = importNamespace(parts[3]); final Symbol s = Optional.ofNullable(getSymbolAt(addr)) .orElse(createLabel(addr, name, ns, true, SourceType.USER_DEFINED)); // Create data (TODO: parse type name to get base name, then pass base type to PointerDataType and ArrayDataType constructors to create final type) final List foundTypes = state.getTool() .getService(DataTypeQueryService.class) .findDataTypes(parts[2], null); if (foundTypes.size() == 0) { println(" can't find data type \"" + parts[2] + "\", skipping."); return; } final DataType t = foundTypes.get(0); // Boldly assume first is right clearListing(addr, addr.add(Math.max(t.getLength(), 1) - 1)); currentProgram.getListing().createData(addr, t); println(" done."); } private static String unqualified(final String qualifiedName) { /* Strips the namespaces off of a qualified name */ final String[] parts = qualifiedName.split("::"); return parts[parts.length - 1]; } private Namespace importNamespace(final String qualifiedName) throws Exception { /* Creates namespaces from the given name, returning the deepest one Returns null if the qualified name is in the global namespace. */ final String[] parts = qualifiedName.split("::"); if (parts.length < 2) return null; final String[] names = Arrays.copyOfRange(parts, 0, parts.length - 1); Namespace ns = null; for (final String name : names) ns = createNamespace(ns, name); return ns; } private void importFunc( final Address addr, final String[] parts ) throws Exception { println("TODO: function \"" + parts[6] + "\""); } }