mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 02:09:44 +02:00
GP-2679 Gcc class recovery improvements. Created classes for Vtable,
Typeinfo, etc. Reworked vtable, const vtable and vtt discovery. Now works for static gcc and for mingw/cygwin programs.
This commit is contained in:
parent
269ea1ae7a
commit
1d14222f37
14 changed files with 4937 additions and 2131 deletions
|
@ -34,7 +34,7 @@
|
|||
// NOTE: As this is a prototype script, the location, names, and design of data types created by
|
||||
// this script and default vfunctions named by this script are likely to change in the future
|
||||
// once an official design for Object Oriented representation is determined.
|
||||
// NOTE: Windows class recovery is more complete and tested than gcc class recovery, which is still
|
||||
// NOTE: Windows class recovery is more complete and tested than Gcc class recovery, which is still
|
||||
// in early stages of development. Gcc class data types are only recovered for classes without
|
||||
// virtual inheritance but if the program contains DWARF, there will be some amount of data recovered
|
||||
// by the DWARF analyzer.
|
||||
|
@ -54,10 +54,20 @@
|
|||
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import classrecovery.*;
|
||||
import classrecovery.DecompilerScriptUtils;
|
||||
import classrecovery.RTTIClassRecoverer;
|
||||
import classrecovery.RTTIGccClassRecoverer;
|
||||
import classrecovery.RTTIWindowsClassRecoverer;
|
||||
import classrecovery.RecoveredClass;
|
||||
import classrecovery.RecoveredClassHelper;
|
||||
import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import ghidra.app.decompiler.DecompInterface;
|
||||
import ghidra.app.plugin.core.analysis.AutoAnalysisManager;
|
||||
|
@ -71,15 +81,32 @@ import ghidra.app.util.bin.format.dwarf4.next.sectionprovider.DWARFSectionProvid
|
|||
import ghidra.app.util.bin.format.dwarf4.next.sectionprovider.DWARFSectionProviderFactory;
|
||||
import ghidra.app.util.bin.format.pdb.PdbParserConstants;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.app.util.opinion.ElfLoader;
|
||||
import ghidra.app.util.opinion.PeLoader;
|
||||
import ghidra.framework.options.Options;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSet;
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
import ghidra.program.model.data.CategoryPath;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.DataTypeComponent;
|
||||
import ghidra.program.model.data.DataTypeManager;
|
||||
import ghidra.program.model.data.Structure;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.Parameter;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.mem.MemoryBlock;
|
||||
import ghidra.program.util.GhidraProgramUtilities;
|
||||
import ghidra.service.graph.*;
|
||||
import ghidra.service.graph.AttributedEdge;
|
||||
import ghidra.service.graph.AttributedGraph;
|
||||
import ghidra.service.graph.AttributedVertex;
|
||||
import ghidra.service.graph.GraphDisplay;
|
||||
import ghidra.service.graph.GraphDisplayOptions;
|
||||
import ghidra.service.graph.GraphDisplayOptionsBuilder;
|
||||
import ghidra.service.graph.GraphDisplayProvider;
|
||||
import ghidra.service.graph.GraphType;
|
||||
import ghidra.service.graph.GraphTypeBuilder;
|
||||
import ghidra.service.graph.VertexShape;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.GraphException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
@ -140,10 +167,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
private static final String DESTRUCTOR_BOOKMARK = "DESTRUCTOR";
|
||||
|
||||
private static final String INDETERMINATE_BOOKMARK = "INDETERMINATE";
|
||||
|
||||
boolean hasDebugSymbols;
|
||||
boolean isGcc = false;
|
||||
boolean isWindows = false;
|
||||
boolean programHasRTTIApplied = false;
|
||||
boolean hasDebugSymbols = false;
|
||||
String ghidraVersion = null;
|
||||
|
||||
DecompilerScriptUtils decompilerUtils;
|
||||
|
@ -159,15 +184,16 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
|
||||
|
||||
String errorMsg = validate();
|
||||
|
||||
if (!errorMsg.isEmpty()) {
|
||||
println(errorMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isWindows()) {
|
||||
|
||||
|
||||
if (!isGcc() && isWindows()) {
|
||||
|
||||
if (!isRttiAnalyzed()) {
|
||||
println("Running the RTTIAnalyzer...");
|
||||
analysisMode = AnalysisMode.ENABLED;
|
||||
|
@ -192,11 +218,27 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
this, BOOKMARK_FOUND_FUNCTIONS, USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS,
|
||||
nameVfunctions, hasDebugSymbols, monitor);
|
||||
}
|
||||
else if (isPE() && isGcc()){
|
||||
|
||||
println("Program is a gcc compiled PE.");
|
||||
boolean runGcc = askYesNo("Gcc Class Recovery Still Under Development",
|
||||
"I understand that Gcc class recovery is still under development and my results will be incomplete but want to run this anyway.");
|
||||
if (!runGcc) {
|
||||
return;
|
||||
}
|
||||
//run fixup old elf relocations script
|
||||
runScript("FixElfExternalOffsetDataRelocationScript.java");
|
||||
recoverClassesFromRTTI =
|
||||
new RTTIGccClassRecoverer(currentProgram, currentLocation, state.getTool(), this,
|
||||
BOOKMARK_FOUND_FUNCTIONS, USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS,
|
||||
nameVfunctions, hasDebugSymbols, monitor);
|
||||
}
|
||||
else if (isGcc()) {
|
||||
|
||||
boolean runGcc = askYesNo("GCC Class Recovery Still Under Development",
|
||||
"I understand that gcc class recovery is still under development and my results " +
|
||||
"will be incomplete but want to run this anyway.");
|
||||
println("Before popping up dialog..");
|
||||
printTime();
|
||||
boolean runGcc= askYesNo("Gcc Class Recovery Still Under Development",
|
||||
"I understand that Gcc class recovery is still under development and my results will be incomplete but want to run this anyway.");
|
||||
|
||||
if (!runGcc) {
|
||||
return;
|
||||
}
|
||||
|
@ -376,8 +418,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
}
|
||||
|
||||
if (!isGcc() && !isWindows()) {
|
||||
return ("This script only handles Windows and gcc programs");
|
||||
|
||||
return ("This script only handles Windows PE and Gcc programs");
|
||||
}
|
||||
|
||||
defaultPointerSize = currentProgram.getDefaultPointerSize();
|
||||
|
@ -438,7 +479,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
AttributedGraph g = new AttributedGraph("Recovered Classes Graph", graphType);
|
||||
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
|
||||
AttributedVertex classVertex =
|
||||
g.addVertex(recoveredClass.getClassPath().getPath(), recoveredClass.getName());
|
||||
|
@ -470,7 +511,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
recoveredClass.getParentToBaseTypeMap();
|
||||
|
||||
for (RecoveredClass parent : parents) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
AttributedVertex parentVertex =
|
||||
g.addVertex(parent.getClassPath().getPath(), parent.getName());
|
||||
|
||||
|
@ -541,11 +582,11 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
throws CancelledException {
|
||||
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
|
||||
List<RecoveredClass> classHierarchyList = recoveredClass.getClassHierarchy();
|
||||
for (RecoveredClass currentClass : classHierarchyList) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
println(currentClass.getName());
|
||||
}
|
||||
|
||||
|
@ -567,15 +608,26 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method to check if executable format is PE
|
||||
*/
|
||||
private boolean isPE() {
|
||||
|
||||
if (!PeLoader.PE_NAME.equals(currentProgram.getExecutableFormat())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to set the global variable isGcc
|
||||
*/
|
||||
private boolean isGcc() {
|
||||
|
||||
if (!ElfLoader.ELF_NAME.equals(currentProgram.getExecutableFormat())) {
|
||||
return false;
|
||||
}
|
||||
boolean isGcc;
|
||||
|
||||
boolean isCompilerSpecGcc = currentProgram.getCompilerSpec()
|
||||
.getCompilerSpecID()
|
||||
|
@ -584,6 +636,11 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
if (isCompilerSpecGcc) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String compiler = currentProgram.getCompiler();
|
||||
if(compiler != null && compiler.contains("gcc")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
MemoryBlock commentBlock = currentProgram.getMemory().getBlock(".comment");
|
||||
if (commentBlock == null) {
|
||||
|
@ -610,6 +667,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
|
||||
return isGcc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method to set the global variable isWindows
|
||||
|
@ -618,7 +676,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
|
||||
String compilerID =
|
||||
currentProgram.getCompilerSpec().getCompilerSpecID().getIdAsString().toLowerCase();
|
||||
isWindows = compilerID.contains("windows");
|
||||
boolean isWindows = compilerID.contains("windows");
|
||||
return isWindows;
|
||||
}
|
||||
|
||||
|
@ -741,7 +799,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
stringBuffer.append(" : ");
|
||||
int lastColon = stringBuffer.lastIndexOf(":");
|
||||
for (RecoveredClass parentClass : classHierarchyMap.keySet()) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
if (classHierarchyMap.size() == 1) {
|
||||
//stringBuffer.append(" : ");
|
||||
getSimpleClassHierarchyString(stringBuffer, parentClass);
|
||||
|
@ -752,7 +810,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
|
||||
//int lastColon = stringBuffer.lastIndexOf(":");
|
||||
for (int i = 0; i <= lastColon; i++) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
stringBuffer.append(" ");
|
||||
}
|
||||
getSimpleClassHierarchyString(stringBuffer, parentClass);
|
||||
|
@ -775,7 +833,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
MemoryBlock[] blocks = currentProgram.getMemory().getBlocks();
|
||||
|
||||
for (MemoryBlock block : blocks) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
|
||||
if (block.isInitialized()) {
|
||||
dataAddresses.add(block.getStart(), block.getEnd());
|
||||
|
@ -793,7 +851,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
throws CancelledException {
|
||||
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
bookmarkFunctionsOnList(recoveredClass.getConstructorList(), CONSTRUCTOR_BOOKMARK);
|
||||
}
|
||||
}
|
||||
|
@ -807,7 +865,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
throws CancelledException {
|
||||
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
bookmarkFunctionsOnList(recoveredClass.getDestructorList(), DESTRUCTOR_BOOKMARK);
|
||||
bookmarkFunctionsOnList(recoveredClass.getNonThisDestructors(), DESTRUCTOR_BOOKMARK);
|
||||
}
|
||||
|
@ -822,7 +880,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
List<RecoveredClass> recoveredClasses) throws CancelledException {
|
||||
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
bookmarkFunctionsOnList(recoveredClass.getIndeterminateList(), INDETERMINATE_BOOKMARK);
|
||||
}
|
||||
}
|
||||
|
@ -841,7 +899,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
}
|
||||
|
||||
for (Function function : functions) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
Address address = function.getEntryPoint();
|
||||
recoverClassesFromRTTI.bookmarkAddress(address, comment);
|
||||
}
|
||||
|
@ -902,7 +960,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
private void printClassDefinitions(List<RecoveredClass> recoveredClasses)
|
||||
throws CancelledException {
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
if (!recoveredClass.hasParentClass()) {
|
||||
println(createClassDefinitionString(recoveredClass).toString());
|
||||
}
|
||||
|
@ -912,7 +970,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
private void outputClassDefinitions(List<RecoveredClass> recoveredClasses, PrintWriter out)
|
||||
throws CancelledException {
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
if (!recoveredClass.hasParentClass()) {
|
||||
out.append(createClassDefinitionString(recoveredClass));
|
||||
}
|
||||
|
@ -928,7 +986,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
*/
|
||||
private void printClassInfo(List<RecoveredClass> recoveredClasses) throws CancelledException {
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
if (!recoveredClass.hasParentClass()) {
|
||||
println(createClassInfoString(recoveredClass).toString());
|
||||
}
|
||||
|
@ -938,12 +996,12 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
private void printClassParents(List<RecoveredClass> recoveredClasses)
|
||||
throws CancelledException {
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
String printString = new String("\n" + recoveredClass.getName() + "\n");
|
||||
if (recoveredClass.hasParentClass()) {
|
||||
List<RecoveredClass> parentList = recoveredClass.getParentList();
|
||||
for (RecoveredClass parent : parentList) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
printString = printString.concat("\t" + parent.getName() + "\n");
|
||||
}
|
||||
}
|
||||
|
@ -963,7 +1021,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
StringBuffer wholeBuffer = new StringBuffer();
|
||||
wholeBuffer.append("\r\n");
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
if (!recoveredClass.hasChildClass()) {
|
||||
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
|
@ -990,7 +1048,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
wholeBuffer.append("\r\n");
|
||||
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
if (!recoveredClass.hasChildClass()) {
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
wholeBuffer.append(
|
||||
|
@ -1011,7 +1069,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
throws CancelledException {
|
||||
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
if (!recoveredClass.hasParentClass()) {
|
||||
out.append(createClassInfoString(recoveredClass).toString());
|
||||
}
|
||||
|
@ -1070,7 +1128,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
|
||||
int total = 0;
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
List<Function> constructorList = recoveredClass.getConstructorOrDestructorFunctions();
|
||||
total += constructorList.size();
|
||||
}
|
||||
|
@ -1088,7 +1146,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
|
||||
int total = 0;
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
List<Function> inlineList = recoveredClass.getInlinedConstructorList();
|
||||
total += inlineList.size();
|
||||
}
|
||||
|
@ -1102,7 +1160,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
*/
|
||||
private void printAddresses(List<Address> addresses) throws CancelledException {
|
||||
for (Address element : addresses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
println(element.toString());
|
||||
}
|
||||
}
|
||||
|
@ -1117,7 +1175,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
PrintWriter out) throws CancelledException {
|
||||
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
out.append(printClassParentsandChildren(recoveredClass));
|
||||
}
|
||||
}
|
||||
|
@ -1131,7 +1189,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
throws CancelledException {
|
||||
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
println(printClassParentsandChildren(recoveredClass).toString());
|
||||
}
|
||||
}
|
||||
|
@ -1157,7 +1215,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
if (recoveredClass.hasParentClass()) {
|
||||
Set<RecoveredClass> keySet = recoveredClass.getClassHierarchyMap().keySet();
|
||||
for (RecoveredClass parent : keySet) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
stringBuffer.append("\t" + parent.getName() + "\r\n");
|
||||
}
|
||||
}
|
||||
|
@ -1168,7 +1226,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
if (recoveredClass.hasChildClass()) {
|
||||
List<RecoveredClass> childClasses = recoveredClass.getChildClasses();
|
||||
for (RecoveredClass element : childClasses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
stringBuffer.append("\t" + element.getName() + "\r\n");
|
||||
}
|
||||
|
||||
|
@ -1209,7 +1267,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
recoveredClass.getParentToBaseTypeMap();
|
||||
Set<RecoveredClass> ancestors = parentToBaseTypeMap.keySet();
|
||||
for (RecoveredClass ancestor : ancestors) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
if (directParents.contains(ancestor)) {
|
||||
|
||||
Boolean isVirtualParent = parentToBaseTypeMap.get(ancestor);
|
||||
|
@ -1232,7 +1290,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
if (recoveredClass.hasChildClass()) {
|
||||
List<RecoveredClass> childClasses = recoveredClass.getChildClasses();
|
||||
for (RecoveredClass element : childClasses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
stringBuffer.append("\t" + element.getName() + "\r\n");
|
||||
}
|
||||
|
||||
|
@ -1243,7 +1301,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
stringBuffer.append("constructor(s):\r\n");
|
||||
List<Function> constructorList = recoveredClass.getConstructorList();
|
||||
for (Function constructorFunction : constructorList) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
stringBuffer.append("\t" + constructorFunction.getName() + " " +
|
||||
constructorFunction.getEntryPoint().toString() + "\r\n");
|
||||
}
|
||||
|
@ -1254,7 +1312,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
if (inlinedConstructorList.size() > 0) {
|
||||
stringBuffer.append("inlined constructor(s):\r\n");
|
||||
for (Function inlinedConstructorFunction : inlinedConstructorList) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
stringBuffer.append("\t" + inlinedConstructorFunction.getName() + " " +
|
||||
inlinedConstructorFunction.getEntryPoint().toString() + "\r\n");
|
||||
}
|
||||
|
@ -1265,7 +1323,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
stringBuffer.append("destructor(s):\r\n");
|
||||
List<Function> destructorList = recoveredClass.getDestructorList();
|
||||
for (Function destructorFunction : destructorList) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
stringBuffer.append("\t" + destructorFunction.getName() + " " +
|
||||
destructorFunction.getEntryPoint().toString() + "\r\n");
|
||||
}
|
||||
|
@ -1276,7 +1334,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
if (inlinedDestructorList.size() > 0) {
|
||||
stringBuffer.append("inlined destructor(s):\r\n");
|
||||
for (Function inlinedDestructorFunction : inlinedDestructorList) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
stringBuffer.append("\t" + inlinedDestructorFunction.getName() + " " +
|
||||
inlinedDestructorFunction.getEntryPoint().toString() + "\r\n");
|
||||
}
|
||||
|
@ -1287,7 +1345,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
if (indeterminateList.size() > 0) {
|
||||
stringBuffer.append("\r\nindeterminate constructor(s) or destructor(s):\r\n");
|
||||
for (Function indeterminateFunction : indeterminateList) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
stringBuffer.append("\t" + indeterminateFunction.getName() + " " +
|
||||
indeterminateFunction.getEntryPoint().toString() + "\r\n");
|
||||
}
|
||||
|
@ -1299,7 +1357,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
stringBuffer.append("member function(s):\r\n");
|
||||
List<Function> virtualFunctions = recoveredClass.getAllVirtualFunctions();
|
||||
for (Function vfunction : virtualFunctions) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
stringBuffer.append(
|
||||
"\t" + vfunction.getName() + " " + vfunction.getEntryPoint().toString() + "\r\n");
|
||||
}
|
||||
|
@ -1318,7 +1376,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
|
||||
DataTypeComponent[] definedComponents = memberDataStructure.getDefinedComponents();
|
||||
for (int i = 0; i < numDefinedComponents; i++) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
|
||||
stringBuffer.append("\t" + definedComponents[i].getDataType() + " " +
|
||||
definedComponents[i].getFieldName() + "\r\n");
|
||||
|
@ -1330,7 +1388,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
if (recoveredClass.hasChildClass()) {
|
||||
List<RecoveredClass> childClasses = recoveredClass.getChildClasses();
|
||||
for (RecoveredClass element : childClasses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
stringBuffer.append(createClassInfoString(element));
|
||||
}
|
||||
}
|
||||
|
@ -1377,7 +1435,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
}
|
||||
else {
|
||||
for (int i = autoParamCount - 1; i < paramCount; i++) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
Parameter param = function.getParameter(i);
|
||||
stringBuffer.append(param.getDataType().getDisplayName() + " " + param.getName());
|
||||
if (i == paramCount) {
|
||||
|
@ -1412,7 +1470,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
stringBuffer.append("constructor(s):\r\n");
|
||||
List<Function> constructorList = recoveredClass.getConstructorList();
|
||||
for (Function constructorFunction : constructorList) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
String functionSignatureString = getFunctionSignatureString(constructorFunction, true);
|
||||
|
||||
stringBuffer.append(functionSignatureString);
|
||||
|
@ -1423,7 +1481,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
stringBuffer.append("\r\ndestructor(s):\r\n");
|
||||
List<Function> destructorList = recoveredClass.getDestructorList();
|
||||
for (Function destructorFunction : destructorList) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
String functionSignatureString = getFunctionSignatureString(destructorFunction, true);
|
||||
stringBuffer.append(functionSignatureString);
|
||||
stringBuffer.append("\r\n");
|
||||
|
@ -1434,7 +1492,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
if (indeterminateList.size() > 0) {
|
||||
stringBuffer.append("\r\nindeterminate constructor or destructor function(s):\r\n");
|
||||
for (Function indeterminateFunction : indeterminateList) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
String functionSignatureString =
|
||||
getFunctionSignatureString(indeterminateFunction, true);
|
||||
stringBuffer.append(functionSignatureString);
|
||||
|
@ -1446,7 +1504,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
stringBuffer.append("\r\nmember function(s):\r\n");
|
||||
List<Function> virtualFunctions = recoveredClass.getAllVirtualFunctions();
|
||||
for (Function vfunction : virtualFunctions) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
String functionSignatureString = getFunctionSignatureString(vfunction, true);
|
||||
stringBuffer.append(functionSignatureString);
|
||||
stringBuffer.append("\r\n");
|
||||
|
@ -1466,7 +1524,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
|
||||
DataTypeComponent[] definedComponents = memberDataStructure.getDefinedComponents();
|
||||
for (int i = 0; i < numDefinedComponents; i++) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
stringBuffer.append("\t" + definedComponents[i].getDataType() + " " +
|
||||
definedComponents[i].getFieldName() + "\r\n");
|
||||
}
|
||||
|
@ -1477,7 +1535,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
if (recoveredClass.hasChildClass()) {
|
||||
List<RecoveredClass> childClasses = recoveredClass.getChildClasses();
|
||||
for (RecoveredClass element : childClasses) {
|
||||
monitor.checkCanceled();
|
||||
monitor.checkCancelled();
|
||||
stringBuffer.append(createClassDefinitionString(element));
|
||||
}
|
||||
}
|
||||
|
@ -1485,4 +1543,12 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
return stringBuffer;
|
||||
}
|
||||
|
||||
|
||||
private void printTime() {
|
||||
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
println(dtf.format(now));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue