diff --git a/ghidra/ghidra_scripts/EnhancedExport.java b/ghidra/ghidra_scripts/EnhancedExport.java index de693af..e8f294a 100644 --- a/ghidra/ghidra_scripts/EnhancedExport.java +++ b/ghidra/ghidra_scripts/EnhancedExport.java @@ -1,17 +1,19 @@ -// TODO +// Writes user-defined data and function symbols to a specified TSV file for +// re-import by the EnhancedImport script. // // @category Export import ghidra.app.script.GhidraScript; -import ghidra.program.flatapi.FlatProgramAPI; +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.SourceType; import ghidra.program.model.symbol.Symbol; -import ghidra.program.model.symbol.SymbolIterator; import java.io.FileWriter; import java.util.Arrays; +import java.util.Optional; public class EnhancedExport extends GhidraScript{ @@ -19,41 +21,18 @@ public class EnhancedExport extends GhidraScript{ public void run() throws Exception { final FileWriter out = new FileWriter(askFile("Specify output file", "OK")); - final SymbolIterator iter = currentProgram.getSymbolTable() - .getPrimarySymbolIterator(true); - while (iter.hasNext() && !monitor.isCancelled()) { - final Symbol s = iter.next(); + for (final Symbol s : currentProgram.getSymbolTable() + .getPrimarySymbolIterator(true)) { if (s.getSource() != SourceType.USER_DEFINED) continue; final Object obj = s.getObject(); if (obj != null) switch (obj) { case Data d: - out.write( - "0x" + s.getAddress().toString() + "\t" + - "d" + "\t" + - d.getDataType().getDisplayName() + "\t" + - s.getName(true) + "\n" - ); + outputData(s.getAddress(), d.getDataType(), s.getName(true), out); break; case Function f: - out.write( - "0x" + s.getAddress().toString() + "\t" + - "f" + "\t" + - f.getSignature(true).getReturnType() - .getDisplayName() + "\t" + - f.getCallingConventionName() + "\t" + - f.getName(true) + - String.join( - "\t", - Arrays.stream(f.getSignature(true).getArguments()) - .map(arg -> "\t" + - arg.getDataType().getDisplayName() + "\t" + - arg.getName() - ).toArray(String[]::new) - ) + - (f.hasVarArgs() ? "\t..." : "") + "\n" - ); + outputFunc(s.getAddress(), f, out); break; default: {} @@ -62,4 +41,46 @@ public class EnhancedExport extends GhidraScript{ out.close(); } + + private static void outputData( + final Address addr, + final DataType type, + final String name, + final FileWriter out + ) throws Exception { + out.write( + "0x" + addr.toString() + "\t" + + "data" + "\t" + + type.getDisplayName() + "\t" + + name + "\n" + ); + } + + private static void outputFunc( + final Address addr, + final Function f, + final FileWriter out + ) throws Exception { + out.write( + "0x" + addr.toString() + "\t" + + "func" + "\t" + + f.getSignature(true).getReturnType() + .getDisplayName() + "\t" + + f.getCallingConventionName() + "\t" + + (f.isInline() ? "inline" : "notinline") + "\t" + + Optional.ofNullable(f.getCallFixup()) + .orElse("nofixup") + "\t" + + f.getName(true) + + String.join( + "\t", + Arrays.stream(f.getSignature(true) + .getArguments()) + .map(arg -> + "\t" + arg.getDataType().getDisplayName() + + "\t" + arg.getName() + ).toArray(String[]::new) + ) + + (f.hasVarArgs() ? "\t..." : "") + "\n" + ); + } }