Finish Ghidra data symbol import

Function import still remains.
This commit is contained in:
KeybadeBlox 2026-02-16 21:38:28 -05:00
parent 0922356a40
commit 5d22c39db6

View file

@ -5,15 +5,20 @@
import ghidra.app.script.GhidraScript; import ghidra.app.script.GhidraScript;
import ghidra.app.services.DataTypeQueryService; import ghidra.app.services.DataTypeQueryService;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.data.ArrayDataType;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataType;
import ghidra.program.model.data.PointerDataType;
import ghidra.program.model.listing.Data; import ghidra.program.model.listing.Data;
import ghidra.program.model.listing.Function; import ghidra.program.model.listing.Function;
import ghidra.program.model.symbol.Namespace; import ghidra.program.model.symbol.Namespace;
import ghidra.program.model.symbol.SourceType; import ghidra.program.model.symbol.SourceType;
import ghidra.program.model.symbol.Symbol; import ghidra.program.model.symbol.Symbol;
import ghidra.util.StringUtilities;
import java.io.FileReader; import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -34,7 +39,7 @@ public class EnhancedImport extends GhidraScript{
case "func": importFunc(addr, parts); break; case "func": importFunc(addr, parts); break;
default: throw new Exception( default: throw new Exception(
"Symbol type \"" + parts[1] + "Symbol type \"" + parts[1] +
"\" on line " + Integer.toString(i) + "\" on line " + String.valueOf(i) +
" is not \"data\" or \"func\"" " is not \"data\" or \"func\""
); );
} }
@ -45,7 +50,7 @@ public class EnhancedImport extends GhidraScript{
final Address addr, final Address addr,
final String[] parts final String[] parts
) throws Exception { ) throws Exception {
final String name = unqualified(parts[3]); final String name = unqualified(parts[3]);
print("Importing data symbol \"" + parts[3] + "\"..."); print("Importing data symbol \"" + parts[3] + "\"...");
@ -54,21 +59,14 @@ public class EnhancedImport extends GhidraScript{
final Symbol s = Optional.ofNullable(getSymbolAt(addr)) final Symbol s = Optional.ofNullable(getSymbolAt(addr))
.orElse(createLabel(addr, name, ns, true, SourceType.USER_DEFINED)); .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) // Create data
final List<DataType> foundTypes = state.getTool() final Optional<DataType> t_maybe = makeType(parts[2]);
.getService(DataTypeQueryService.class) if (t_maybe.orElse(null) instanceof DataType t) {
.findDataTypes(parts[2], null); clearListing(addr, addr.add(Math.max(t.getLength(), 1) - 1));
if (foundTypes.size() == 0) { currentProgram.getListing().createData(addr, t);
println(" can't find data type \"" + parts[2] + "\", skipping.");
return;
}
final DataType t = foundTypes.get(0); // Boldly assume first is right println(" done.");
} else println(", skipping.");
clearListing(addr, addr.add(Math.max(t.getLength(), 1) - 1));
currentProgram.getListing().createData(addr, t);
println(" done.");
} }
private static String unqualified(final String qualifiedName) { private static String unqualified(final String qualifiedName) {
@ -93,6 +91,64 @@ public class EnhancedImport extends GhidraScript{
return ns; return ns;
} }
private Optional<DataType> makeType(final String type) throws Exception {
/* Attempt to create the described type from a known base type */
final String baseName = StringUtilities.findWord(type, 0);
final List<DataType> foundTypes = state.getTool()
.getService(DataTypeQueryService.class)
.findDataTypes(baseName, null);
if (foundTypes.size() == 0) {
print(" can't find data type \"" + baseName + "\"");
return Optional.empty();
}
return Optional.of(derivedType(
foundTypes.get(0), // Boldly assume first is right
type.substring(baseName.length())
));
}
private static DataType derivedType(
final DataType t,
final String modifiers
) throws Exception {
/* Return the given datatype with given pointer/array modifiers */
DataType ret = t;
for (int i = 0; i < modifiers.length(); i++) switch (modifiers.charAt(i)) {
case '*':
ret = new PointerDataType(ret);
continue;
case '[':
// Read array dimensions
final ArrayList<Integer> dims = new ArrayList<>();
do {
final String n = StringUtilities.findWord(modifiers, i+1);
i += n.length() + 1;
dims.add(Integer.valueOf(n));
} while (modifiers.charAt(i) == '[');
// Apply array
Collections.reverse(dims);
for (int dim : dims) ret = new ArrayDataType(ret, dim);
continue;
case ' ':
continue;
default:
throw new Exception(
"Unexpected character \"" +
String.valueOf(modifiers.charAt(i)) +
"\" in type modifiers"
);
}
return ret;
}
private void importFunc( private void importFunc(
final Address addr, final Address addr,
final String[] parts final String[] parts