mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-04-26 01:35:22 +02:00
GP-4408 Refactor of FillOutStructureCmd. Added FillOutStructureHelper and additional DecompilerUtils methods.
This commit is contained in:
@@ -17,84 +17,28 @@
|
||||
package classrecovery;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.app.cmd.label.DemanglerCmd;
|
||||
import ghidra.app.plugin.core.analysis.ReferenceAddressPair;
|
||||
import ghidra.app.util.NamespaceUtils;
|
||||
import ghidra.app.util.demangler.DemangledObject;
|
||||
import ghidra.app.util.demangler.DemanglerUtil;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.framework.plugintool.ServiceProvider;
|
||||
import ghidra.program.flatapi.FlatProgramAPI;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressIterator;
|
||||
import ghidra.program.model.address.AddressOutOfBoundsException;
|
||||
import ghidra.program.model.address.AddressRange;
|
||||
import ghidra.program.model.address.AddressRangeIterator;
|
||||
import ghidra.program.model.address.AddressSet;
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
import ghidra.program.model.data.ArrayDataType;
|
||||
import ghidra.program.model.data.CategoryPath;
|
||||
import ghidra.program.model.data.CharDataType;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.DataTypeComponent;
|
||||
import ghidra.program.model.data.DataTypeConflictHandler;
|
||||
import ghidra.program.model.data.DataUtilities;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.DataUtilities.ClearDataMode;
|
||||
import ghidra.program.model.data.InvalidDataTypeException;
|
||||
import ghidra.program.model.data.LongDataType;
|
||||
import ghidra.program.model.data.LongLongDataType;
|
||||
import ghidra.program.model.data.Pointer;
|
||||
import ghidra.program.model.data.PointerDataType;
|
||||
import ghidra.program.model.data.PointerTypedef;
|
||||
import ghidra.program.model.data.StringDataType;
|
||||
import ghidra.program.model.data.Structure;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.program.model.data.TerminatedStringDataType;
|
||||
import ghidra.program.model.data.UnsignedIntegerDataType;
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.listing.Bookmark;
|
||||
import ghidra.program.model.listing.BookmarkType;
|
||||
import ghidra.program.model.listing.CircularDependencyException;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.FunctionManager;
|
||||
import ghidra.program.model.listing.Instruction;
|
||||
import ghidra.program.model.listing.InstructionIterator;
|
||||
import ghidra.program.model.listing.Listing;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.mem.DumbMemBufferImpl;
|
||||
import ghidra.program.model.mem.MemBuffer;
|
||||
import ghidra.program.model.mem.Memory;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.mem.MemoryBlock;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.mem.*;
|
||||
import ghidra.program.model.scalar.Scalar;
|
||||
import ghidra.program.model.symbol.Namespace;
|
||||
import ghidra.program.model.symbol.Reference;
|
||||
import ghidra.program.model.symbol.ReferenceIterator;
|
||||
import ghidra.program.model.symbol.ReferenceManager;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.program.model.symbol.Symbol;
|
||||
import ghidra.program.model.symbol.SymbolIterator;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.program.util.ProgramMemoryUtil;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.bytesearch.GenericByteSequencePattern;
|
||||
import ghidra.util.bytesearch.GenericMatchAction;
|
||||
import ghidra.util.bytesearch.Match;
|
||||
import ghidra.util.bytesearch.MemoryBytePatternSearcher;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
import ghidra.util.bytesearch.*;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
@@ -151,23 +95,20 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
private Map<RecoveredClass, Map<RecoveredClass, Long>> classToParentOffsetMap =
|
||||
new HashMap<RecoveredClass, Map<RecoveredClass, Long>>();
|
||||
|
||||
private Map<RecoveredClass, List<Vftable>> classToVftableMap = new HashMap<>();
|
||||
|
||||
boolean isDwarfLoaded;
|
||||
boolean replaceClassStructs;
|
||||
|
||||
FunctionManager functionManager = null;
|
||||
Listing listing;
|
||||
protected final FunctionManager functionManager;
|
||||
protected final Listing listing;
|
||||
|
||||
public RTTIGccClassRecoverer(Program program, ProgramLocation location, PluginTool tool,
|
||||
FlatProgramAPI api,
|
||||
boolean createBookmarks, boolean useShortTemplates, boolean nameVfunctions,
|
||||
boolean isDwarfLoaded,
|
||||
TaskMonitor monitor) throws Exception {
|
||||
public RTTIGccClassRecoverer(Program program, ServiceProvider serviceProvider,
|
||||
FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates,
|
||||
boolean nameVfunctions, boolean isDwarfLoaded, TaskMonitor monitor) throws Exception {
|
||||
|
||||
super(program, location, tool, api, createBookmarks, useShortTemplates, nameVfunctions,
|
||||
super(program, serviceProvider, api, createBookmarks, useShortTemplates, nameVfunctions,
|
||||
isDwarfLoaded, monitor);
|
||||
|
||||
this.isDwarfLoaded = isDwarfLoaded;
|
||||
|
||||
functionManager = program.getFunctionManager();
|
||||
@@ -208,8 +149,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
List<ReferenceAddressPair> directReferenceList = new ArrayList<ReferenceAddressPair>();
|
||||
|
||||
ProgramMemoryUtil.loadDirectReferenceList(program, 1, initializedMem.getMinAddress(),
|
||||
initializedMem,
|
||||
directReferenceList, monitor);
|
||||
initializedMem, directReferenceList, monitor);
|
||||
createGlobalDirectRefMap(directReferenceList);
|
||||
|
||||
Msg.debug(this, "Creating Special Typeinfos");
|
||||
@@ -287,7 +227,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
/**
|
||||
* Method to update the labels of vftables that belong to classes with multiple vftables in
|
||||
* order to distinguish which base class the vftable is for.
|
||||
* @param recoveredClasses the list of RecoveredClass objects
|
||||
* @throws CancelledException if cancelled
|
||||
* @throws InvalidInputException if bad chars trying to label
|
||||
* @throws DuplicateNameException if duplicate name
|
||||
@@ -364,8 +303,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
|
||||
private GccTypeinfo findSpecialTypeinfoSymbol(String namespaceName,
|
||||
String mangledNamespaceString)
|
||||
throws CancelledException {
|
||||
String mangledNamespaceString) throws CancelledException {
|
||||
|
||||
// try finding with normal symbol name and namespace
|
||||
Symbol typeinfoSymbol =
|
||||
@@ -384,9 +322,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
if (typeinfoSymbol == null) {
|
||||
// then try finding with mangled namespace string in memory
|
||||
typeinfoSymbol =
|
||||
findTypeinfoSymbolUsingMangledNamespaceString(mangledNamespaceString,
|
||||
namespaceName);
|
||||
typeinfoSymbol = findTypeinfoSymbolUsingMangledNamespaceString(
|
||||
mangledNamespaceString, namespaceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -397,8 +334,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
|
||||
private Symbol findTypeinfoUsingNotInProgramMemoryVtableSymbol(String namespaceName,
|
||||
String mangledNamespaceString)
|
||||
throws CancelledException {
|
||||
String mangledNamespaceString) throws CancelledException {
|
||||
|
||||
// try finding with normal symbol name and namespace
|
||||
Symbol vtableSymbol =
|
||||
@@ -433,8 +369,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
Symbol typeinfoSymbol;
|
||||
try {
|
||||
typeinfoSymbol = symbolTable.createLabel(vtableAddress, "typeinfo",
|
||||
vtableSymbol.getParentNamespace(),
|
||||
SourceType.ANALYSIS);
|
||||
vtableSymbol.getParentNamespace(), SourceType.ANALYSIS);
|
||||
// api.setPlateComment(typeinfoAddress, "typeinfo for " + namespace);
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
@@ -484,8 +419,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
// TODO: this assumes only one and returns the first found - have never seen
|
||||
// more than one but should probably check
|
||||
private Symbol findAndReturnDemangledSymbol(String mangledSymbolName,
|
||||
String specialClassNamespaceName,
|
||||
String classNamespaceName, String label) {
|
||||
String specialClassNamespaceName, String classNamespaceName, String label) {
|
||||
|
||||
SymbolIterator symbolIterator = symbolTable.getSymbolIterator(mangledSymbolName, true);
|
||||
if (symbolIterator.hasNext()) {
|
||||
@@ -504,9 +438,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
|
||||
try {
|
||||
Symbol demangledSymbol =
|
||||
symbolTable.createLabel(symbolAddress, label, classNamespace,
|
||||
SourceType.ANALYSIS);
|
||||
Symbol demangledSymbol = symbolTable.createLabel(symbolAddress, label,
|
||||
classNamespace, SourceType.ANALYSIS);
|
||||
demangledSymbol.setPrimary();
|
||||
return demangledSymbol;
|
||||
}
|
||||
@@ -520,8 +453,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
// TODO: can this be used for regular ones too?
|
||||
private Symbol findTypeinfoSymbolUsingMangledNamespaceString(String mangledNamespace,
|
||||
String namespaceName)
|
||||
throws CancelledException {
|
||||
String namespaceName) throws CancelledException {
|
||||
|
||||
Symbol specialTypeinfoSymbol = findTypeinfoUsingMangledString(mangledNamespace);
|
||||
if (specialTypeinfoSymbol == null) {
|
||||
@@ -539,9 +471,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
boolean isExternal =
|
||||
typeinfoAddress.isExternalAddress() || inExternalBlock(typeinfoAddress);
|
||||
|
||||
GccTypeinfo gccTypeinfo =
|
||||
new GccTypeinfo(typeinfoSymbol.getAddress(), typeinfoSymbol.getParentNamespace(),
|
||||
isSpecial, !isExternal);
|
||||
GccTypeinfo gccTypeinfo = new GccTypeinfo(typeinfoSymbol.getAddress(),
|
||||
typeinfoSymbol.getParentNamespace(), isSpecial, !isExternal);
|
||||
return gccTypeinfo;
|
||||
}
|
||||
|
||||
@@ -578,10 +509,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
boolean isGcc;
|
||||
|
||||
boolean isCompilerSpecGcc = program.getCompilerSpec()
|
||||
.getCompilerSpecID()
|
||||
.getIdAsString()
|
||||
.equalsIgnoreCase("gcc");
|
||||
boolean isCompilerSpecGcc =
|
||||
program.getCompilerSpec().getCompilerSpecID().getIdAsString().equalsIgnoreCase("gcc");
|
||||
if (isCompilerSpecGcc) {
|
||||
return true;
|
||||
}
|
||||
@@ -605,8 +534,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
byte[] maskBytes = { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
|
||||
|
||||
Address found = program.getMemory()
|
||||
.findBytes(commentBlock.getStart(), commentBlock.getEnd(), gccBytes,
|
||||
maskBytes, true, monitor);
|
||||
.findBytes(commentBlock.getStart(), commentBlock.getEnd(), gccBytes, maskBytes,
|
||||
true, monitor);
|
||||
if (found == null) {
|
||||
isGcc = false;
|
||||
}
|
||||
@@ -726,9 +655,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
// parent isn't a known class - cannot continue processing recoveredClass
|
||||
if (parentClass == null) {
|
||||
Msg.error(this,
|
||||
"Removing class: " + recoveredClass.getName() + " from list to" +
|
||||
" process since parent information is not availalbe.");
|
||||
Msg.error(this, "Removing class: " + recoveredClass.getName() +
|
||||
" from list to" + " process since parent information is not availalbe.");
|
||||
recoveredClasses.remove(recoveredClass);
|
||||
}
|
||||
continue;
|
||||
@@ -801,9 +729,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
Vtable vtable = processMainVtable(mainVtable, map.get(mainVtable));
|
||||
if (vtable == null) {
|
||||
Msg.debug(this,
|
||||
"MISSING expected vtable for simple class " +
|
||||
typeinfo.getNamespace().getName(true));
|
||||
Msg.debug(this, "MISSING expected vtable for simple class " +
|
||||
typeinfo.getNamespace().getName(true));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1051,8 +978,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
|
||||
private boolean isPossibleVttStart(Address address, List<Vtable> vtables,
|
||||
List<Address> knownVtts)
|
||||
throws CancelledException {
|
||||
List<Address> knownVtts) throws CancelledException {
|
||||
|
||||
// make list of all vtable tops and vftable tops
|
||||
List<Address> vtableAndVftableAddrs = getListOfVtableAndVftableTops(vtables);
|
||||
@@ -1164,7 +1090,9 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
* construction ones to the passed in list
|
||||
*
|
||||
* @param typeinfo
|
||||
* @param map
|
||||
* @param constructionVtables
|
||||
* @param numBaseRefs
|
||||
* @return address of main vtable for this class
|
||||
* @throws CancelledException
|
||||
*/
|
||||
@@ -1468,8 +1396,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
|
||||
private Address getMainVtableUsingSymbols(List<Address> vtableAddresses,
|
||||
List<Address> constructionVtables)
|
||||
throws CancelledException {
|
||||
List<Address> constructionVtables) throws CancelledException {
|
||||
|
||||
List<Address> mainVtableCandidates = new ArrayList<Address>();
|
||||
for (Address vtableAddress : vtableAddresses) {
|
||||
@@ -1662,8 +1589,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
|
||||
symbolTable.createLabel(vtableAddress, internalString + constructionString + VTABLE_LABEL,
|
||||
classNamespace,
|
||||
SourceType.ANALYSIS);
|
||||
classNamespace, SourceType.ANALYSIS);
|
||||
|
||||
}
|
||||
|
||||
@@ -1690,8 +1616,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
|
||||
symbolTable.createLabel(vtable.getVfunctionTop(),
|
||||
internalString + constructionString + VFTABLE_LABEL,
|
||||
classNamespace, SourceType.ANALYSIS);
|
||||
internalString + constructionString + VFTABLE_LABEL, classNamespace,
|
||||
SourceType.ANALYSIS);
|
||||
|
||||
}
|
||||
|
||||
@@ -1871,8 +1797,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
Namespace newNamespace;
|
||||
try {
|
||||
newNamespace = NamespaceUtils.createNamespaceHierarchy(name,
|
||||
namespaceIn.getParentNamespace(), program,
|
||||
SourceType.ANALYSIS);
|
||||
namespaceIn.getParentNamespace(), program, SourceType.ANALYSIS);
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
return null;
|
||||
@@ -1893,8 +1818,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
|
||||
public Map<Address, Set<Address>> findTypeinfoReferencesNotInTypeinfoStructsOld(
|
||||
List<Address> typeinfoAddresses)
|
||||
throws CancelledException {
|
||||
List<Address> typeinfoAddresses) throws CancelledException {
|
||||
|
||||
MemoryBytePatternSearcher searcher = new MemoryBytePatternSearcher("Typeinfo References");
|
||||
|
||||
@@ -1934,7 +1858,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
searchSet.add(addressRange.getMinAddress(), addressRange.getMaxAddress());
|
||||
}
|
||||
Map<Address, Set<Address>> directRefMap = new HashMap<Address, Set<Address>>();
|
||||
Map<Address, Set<Address>> refMap = new HashMap<Address, Set<Address>>();
|
||||
|
||||
AddressIterator addrIter =
|
||||
initializedSet.getAddresses(initializedSet.getMinAddress(), true);
|
||||
@@ -1944,11 +1868,11 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
// check direct refs to see if they are in undefined area or not in function
|
||||
byte[] bytes = ProgramMemoryUtil.getDirectAddressBytes(program, address);
|
||||
|
||||
addByteSearchPatternDirRefs(searcher, directRefMap, address, bytes, monitor);
|
||||
addByteSearchPatternDirRefs(searcher, refMap, address, bytes, monitor);
|
||||
|
||||
}
|
||||
searcher.search(program, searchSet, monitor);
|
||||
return directRefMap;
|
||||
return refMap;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1997,8 +1921,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
|
||||
public Map<Address, Set<Address>> findTypeinfoReferencesNotInTypeinfoStructs(
|
||||
List<GccTypeinfo> typeinfos)
|
||||
throws CancelledException {
|
||||
List<GccTypeinfo> typeinfos) throws CancelledException {
|
||||
|
||||
MemoryBytePatternSearcher searcher = new MemoryBytePatternSearcher("Typeinfo References");
|
||||
|
||||
@@ -2104,8 +2027,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
* @param taskMonitor a cancellable monitor
|
||||
*/
|
||||
private void addByteSearchPattern(MemoryBytePatternSearcher searcher,
|
||||
Map<Address, Set<Address>> typeinfoRefMap,
|
||||
Address typeinfoAddress, byte[] bytes, TaskMonitor taskMonitor) {
|
||||
Map<Address, Set<Address>> typeinfoRefMap, Address typeinfoAddress, byte[] bytes,
|
||||
TaskMonitor taskMonitor) {
|
||||
|
||||
// no pattern bytes.
|
||||
if (bytes == null) {
|
||||
@@ -2195,8 +2118,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
* @throws CancelledException if cancelled
|
||||
*/
|
||||
private Vtable processVtable(Address vtableAddress, GccTypeinfoRef typeinfoRef,
|
||||
Boolean isConstruction)
|
||||
throws CancelledException {
|
||||
Boolean isConstruction) throws CancelledException {
|
||||
|
||||
Vtable vtable = null;
|
||||
boolean isSpecial = false;
|
||||
@@ -2296,9 +2218,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
api.clearListing(vtableAddress);
|
||||
|
||||
SpecialVtable specialVtable =
|
||||
new SpecialVtable(program, vtableAddress, typeinfoRef, isExternal,
|
||||
vtableSymbol.getParentNamespace(), monitor);
|
||||
SpecialVtable specialVtable = new SpecialVtable(program, vtableAddress, typeinfoRef,
|
||||
isExternal, vtableSymbol.getParentNamespace(), monitor);
|
||||
return specialVtable;
|
||||
}
|
||||
|
||||
@@ -2421,9 +2342,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
.equals(VMI_CLASS_TYPEINFO_NAMESPACE)) {
|
||||
specialTypeinfoNamespaceName = VMI_CLASS_TYPEINFO_NAMESPACE;
|
||||
typeinfoToStructuretypeMap.put(typeinfoAddress, VMI_CLASS_TYPE_INFO_STRUCTURE);
|
||||
Structure vmiClassTypeinfoStructure =
|
||||
getOrCreateVmiTypeinfoStructure(typeinfoAddress,
|
||||
baseClassTypeInfoStructure);
|
||||
Structure vmiClassTypeinfoStructure = getOrCreateVmiTypeinfoStructure(
|
||||
typeinfoAddress, baseClassTypeInfoStructure);
|
||||
if (vmiClassTypeinfoStructure != null) {
|
||||
newStructure =
|
||||
applyTypeinfoStructure(vmiClassTypeinfoStructure, typeinfoAddress);
|
||||
@@ -2500,8 +2420,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
|
||||
private void updateTypeinfosWithBases(List<GccTypeinfo> typeinfos,
|
||||
Map<Address, GccTypeinfo> typeinfoMap)
|
||||
throws CancelledException {
|
||||
Map<Address, GccTypeinfo> typeinfoMap) throws CancelledException {
|
||||
|
||||
List<GccTypeinfo> invalidTypeinfos = new ArrayList<GccTypeinfo>();
|
||||
for (GccTypeinfo typeinfo : typeinfos) {
|
||||
@@ -2549,9 +2468,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
// SI_CLASS_TYPE_INFO_STRUCTURE
|
||||
if (!isTypeinfoStruct(siTypeinfoStructure)) {
|
||||
throw new IllegalArgumentException(
|
||||
siTypeinfoStructure.getAddressString(false, false) +
|
||||
" is not a typeinfo structure");
|
||||
throw new IllegalArgumentException(siTypeinfoStructure.getAddressString(false, false) +
|
||||
" is not a typeinfo structure");
|
||||
}
|
||||
|
||||
Data baseClassPointer = siTypeinfoStructure.getComponent(2);
|
||||
@@ -2604,9 +2522,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
extendedFlatAPI.getReferencedAddress(baseClassStructureAddress, false);
|
||||
|
||||
if (baseTypeinfoAddress == null) {
|
||||
Msg.debug(this,
|
||||
typeinfo.getAddress() +
|
||||
": invalid typeinfo - cannot get address at baseTypeinfo[" + i + "]");
|
||||
Msg.debug(this, typeinfo.getAddress() +
|
||||
": invalid typeinfo - cannot get address at baseTypeinfo[" + i + "]");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2674,8 +2591,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
DataType inheritanceFlagDataType = inheritanceFlagComponent.getDataType();
|
||||
MemBuffer buf = new DumbMemBufferImpl(program.getMemory(), flagAddress);
|
||||
Scalar scalar = (Scalar) inheritanceFlagDataType.getValue(buf,
|
||||
inheritanceFlagDataType.getDefaultSettings(),
|
||||
inheritanceFlagDataType.getLength());
|
||||
inheritanceFlagDataType.getDefaultSettings(), inheritanceFlagDataType.getLength());
|
||||
long inheritanceFlagValue = scalar.getUnsignedValue();
|
||||
return inheritanceFlagValue;
|
||||
}
|
||||
@@ -2693,8 +2609,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
DataType numBaseClassesDataType = numBaseClassesComponent.getDataType();
|
||||
MemBuffer buf = new DumbMemBufferImpl(program.getMemory(), numBaseClassesAddress);
|
||||
Scalar scalar = (Scalar) numBaseClassesDataType.getValue(buf,
|
||||
numBaseClassesDataType.getDefaultSettings(),
|
||||
numBaseClassesDataType.getLength());
|
||||
numBaseClassesDataType.getDefaultSettings(), numBaseClassesDataType.getLength());
|
||||
int numBaseClasses = (int) scalar.getUnsignedValue();
|
||||
|
||||
return numBaseClasses;
|
||||
@@ -2810,9 +2725,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
|
||||
// get or create the vmiClassTypeInfoStruct
|
||||
Structure vmiClassTypeinfoStructure =
|
||||
(Structure) dataTypeManager.getDataType(classDataTypesCategoryPath,
|
||||
VMI_CLASS_TYPE_INFO_STRUCTURE + numBases);
|
||||
Structure vmiClassTypeinfoStructure = (Structure) dataTypeManager
|
||||
.getDataType(classDataTypesCategoryPath, VMI_CLASS_TYPE_INFO_STRUCTURE + numBases);
|
||||
if (vmiClassTypeinfoStructure == null) {
|
||||
vmiClassTypeinfoStructure =
|
||||
createVmiClassTypeInfoStructure(baseClassTypeInfoStructure, numBases);
|
||||
@@ -2821,7 +2735,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
|
||||
private Symbol createDemangledTypeinfoSymbol(Address typeinfoAddress)
|
||||
throws DuplicateNameException, InvalidInputException, CancelledException {
|
||||
throws DuplicateNameException, InvalidInputException {
|
||||
|
||||
// TODO: 1. see if there is a mangled name that didn't get demangled at
|
||||
// TODO: 2 - refactor the three places that call this to just call getSymbolAt
|
||||
@@ -2919,9 +2833,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
Namespace classNamespace = typeinfoNameSymbol.getParentNamespace();
|
||||
|
||||
if (classNamespace.isGlobal()) {
|
||||
Msg.debug(this,
|
||||
typeinfoAddress.toString() +
|
||||
"Could not create a class namespace for demangled namespace string ");
|
||||
Msg.debug(this, typeinfoAddress.toString() +
|
||||
"Could not create a class namespace for demangled namespace string ");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -2987,7 +2900,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
private String getDefinedStringAt(Address address) {
|
||||
|
||||
Listing listing = program.getListing();
|
||||
Data stringData = listing.getDataAt(address);
|
||||
|
||||
if (stringData == null) {
|
||||
@@ -3218,15 +3130,11 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
|
||||
public void assignConstructorsAndDestructorsUsingExistingNameNew(
|
||||
List<RecoveredClass> recoveredClasses)
|
||||
throws CancelledException, InvalidInputException, DuplicateNameException,
|
||||
CircularDependencyException {
|
||||
List<RecoveredClass> recoveredClasses) throws CancelledException, InvalidInputException,
|
||||
DuplicateNameException, CircularDependencyException {
|
||||
|
||||
Iterator<RecoveredClass> recoveredClassIterator = recoveredClasses.iterator();
|
||||
while (recoveredClassIterator.hasNext()) {
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCancelled();
|
||||
RecoveredClass recoveredClass = recoveredClassIterator.next();
|
||||
|
||||
Namespace classNamespace = recoveredClass.getClassNamespace();
|
||||
String name = classNamespace.getName();
|
||||
SymbolIterator classSymbols = symbolTable.getSymbols(classNamespace);
|
||||
@@ -3353,8 +3261,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
|
||||
private void removeFromIndeterminateLists(List<RecoveredClass> recoveredClasses,
|
||||
Function function)
|
||||
throws CancelledException {
|
||||
Function function) throws CancelledException {
|
||||
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCancelled();
|
||||
@@ -3373,8 +3280,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
if (hasExternalRelocations()) {
|
||||
PointerTypedef classTypeInfoPtr =
|
||||
new PointerTypedef(null, null, -1, program.getDataTypeManager(),
|
||||
componentOffset);
|
||||
new PointerTypedef(null, null, -1, program.getDataTypeManager(), componentOffset);
|
||||
classTypeInfoStructure.add(classTypeInfoPtr, "classTypeinfoPtr", null);
|
||||
|
||||
}
|
||||
@@ -3393,18 +3299,15 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
|
||||
private StructureDataType createSiClassTypeInfoStructure(
|
||||
StructureDataType classTypeInfoStructure)
|
||||
throws CancelledException {
|
||||
StructureDataType classTypeInfoStructure) throws CancelledException {
|
||||
|
||||
StructureDataType siClassTypeInfoStructure =
|
||||
new StructureDataType(classDataTypesCategoryPath,
|
||||
SI_CLASS_TYPE_INFO_STRUCTURE, 0, dataTypeManager);
|
||||
StructureDataType siClassTypeInfoStructure = new StructureDataType(
|
||||
classDataTypesCategoryPath, SI_CLASS_TYPE_INFO_STRUCTURE, 0, dataTypeManager);
|
||||
|
||||
CharDataType characterDT = new CharDataType();
|
||||
|
||||
PointerTypedef classTypeInfoPtr =
|
||||
new PointerTypedef(null, null, -1, program.getDataTypeManager(),
|
||||
componentOffset);
|
||||
new PointerTypedef(null, null, -1, program.getDataTypeManager(), componentOffset);
|
||||
siClassTypeInfoStructure.add(classTypeInfoPtr, "classTypeinfoPtr", null);
|
||||
|
||||
DataType charPointer = dataTypeManager.getPointer(characterDT);
|
||||
@@ -3420,12 +3323,10 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
|
||||
private StructureDataType createBaseClassTypeInfoStructure(
|
||||
StructureDataType classTypeInfoStructure)
|
||||
throws InvalidDataTypeException {
|
||||
StructureDataType classTypeInfoStructure) throws InvalidDataTypeException {
|
||||
|
||||
StructureDataType baseclassTypeInfoStructure =
|
||||
new StructureDataType(classDataTypesCategoryPath,
|
||||
BASE_CLASS_TYPE_INFO_STRUCTURE, 0, dataTypeManager);
|
||||
StructureDataType baseclassTypeInfoStructure = new StructureDataType(
|
||||
classDataTypesCategoryPath, BASE_CLASS_TYPE_INFO_STRUCTURE, 0, dataTypeManager);
|
||||
|
||||
DataType classTypeInfoPointer = dataTypeManager.getPointer(classTypeInfoStructure);
|
||||
|
||||
@@ -3460,8 +3361,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
|
||||
private StructureDataType createVmiClassTypeInfoStructure(
|
||||
StructureDataType baseClassTypeInfoStructure,
|
||||
int numBaseClasses) throws CancelledException {
|
||||
StructureDataType baseClassTypeInfoStructure, int numBaseClasses)
|
||||
throws CancelledException {
|
||||
|
||||
StructureDataType vmiClassTypeInfoStructure =
|
||||
new StructureDataType(classDataTypesCategoryPath,
|
||||
@@ -3471,8 +3372,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
UnsignedIntegerDataType unsignedIntDT = new UnsignedIntegerDataType();
|
||||
|
||||
PointerTypedef classTypeInfoPtr =
|
||||
new PointerTypedef(null, null, -1, program.getDataTypeManager(),
|
||||
componentOffset);
|
||||
new PointerTypedef(null, null, -1, program.getDataTypeManager(), componentOffset);
|
||||
vmiClassTypeInfoStructure.add(classTypeInfoPtr, "classTypeinfoPtr", null);
|
||||
|
||||
DataType charPointer = dataTypeManager.getPointer(characterDT);
|
||||
@@ -3564,8 +3464,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
* @throws CancelledException if cancelled
|
||||
*/
|
||||
private List<RecoveredClass> addClassParentsAndFlagsForVmiClass(RecoveredClass recoveredClass,
|
||||
GccTypeinfo typeinfo)
|
||||
throws CancelledException {
|
||||
GccTypeinfo typeinfo) throws CancelledException {
|
||||
|
||||
long inheritanceFlagValue = typeinfo.getInheritanceFlagValue();
|
||||
|
||||
@@ -3646,8 +3545,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
|
||||
private Address findSpecialVtable(GccTypeinfo specialTypeinfo,
|
||||
List<GccTypeinfo> specialTypeinfos)
|
||||
throws CancelledException {
|
||||
List<GccTypeinfo> specialTypeinfos) throws CancelledException {
|
||||
|
||||
String namespaceName = specialTypeinfo.getNamespace().getName();
|
||||
String mangledNamespaceString = specialTypeinfo.getMangledNamespaceString();
|
||||
@@ -3663,9 +3561,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
// then try finding top of special vtable by finding ref to special typeinfo
|
||||
if (vtableSymbol == null) {
|
||||
Address vtableAddress =
|
||||
findSpecialVtableUsingSpecialTypeinfo(specialTypeinfo.getAddress(),
|
||||
specialTypeinfos);
|
||||
Address vtableAddress = findSpecialVtableUsingSpecialTypeinfo(
|
||||
specialTypeinfo.getAddress(), specialTypeinfos);
|
||||
|
||||
if (vtableAddress == null) {
|
||||
return null;
|
||||
@@ -3673,14 +3570,13 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
try {
|
||||
vtableSymbol = symbolTable.createLabel(vtableAddress, VTABLE_LABEL,
|
||||
specialTypeinfo.getNamespace(),
|
||||
SourceType.ANALYSIS);
|
||||
specialTypeinfo.getNamespace(), SourceType.ANALYSIS);
|
||||
api.setPlateComment(vtableAddress,
|
||||
"vtable for " + specialTypeinfo.getNamespace());
|
||||
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
vtableSymbol = null;
|
||||
// ignore
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3729,8 +3625,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
* len between the two
|
||||
*/
|
||||
private Address findSpecialVtableUsingSpecialTypeinfo(Address typeinfoAddress,
|
||||
List<GccTypeinfo> specialTypeinfos)
|
||||
throws CancelledException {
|
||||
List<GccTypeinfo> specialTypeinfos) throws CancelledException {
|
||||
|
||||
List<Address> referencesTo = getAllReferencesTo(typeinfoAddress);
|
||||
|
||||
@@ -3805,8 +3700,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
try {
|
||||
symbolTable.createLabel(findSingleMangledString, mangledNamespaceString,
|
||||
globalNamespace,
|
||||
SourceType.ANALYSIS);
|
||||
globalNamespace, SourceType.ANALYSIS);
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
|
||||
@@ -4096,7 +3990,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
monitor.checkCancelled();
|
||||
baseOffsets.add(baseTypeinfo.getOffset());
|
||||
}
|
||||
|
||||
|
||||
if (baseOffsets.size() != vftableAddresses.size()) {
|
||||
|
||||
@@ -4127,13 +4020,12 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
continue;
|
||||
}
|
||||
recoveredClass.addVftableToBaseClassMapping(correspondingVftableAddress, baseClass);
|
||||
|
||||
|
||||
//TODO: populate the new Vftable objects
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Use information from RTTI Base class Arrays to create class hierarchy lists
|
||||
* and maps
|
||||
@@ -4188,10 +4080,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
RecoveredClass recoveredClass = recoveredClassIterator.next();
|
||||
List<RecoveredClass> parentList = recoveredClass.getParentList();
|
||||
Iterator<RecoveredClass> parentIterator = parentList.iterator();
|
||||
while (parentIterator.hasNext()) {
|
||||
for (RecoveredClass parentClass : parentList) {
|
||||
monitor.checkCancelled();
|
||||
RecoveredClass parentClass = parentIterator.next();
|
||||
recoveredClass.addClassHierarchyMapping(parentClass,
|
||||
parentClass.getClassHierarchy());
|
||||
}
|
||||
@@ -4224,10 +4114,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
private boolean hasVirtualAncestor(RecoveredClass recoveredClass) throws CancelledException {
|
||||
|
||||
List<RecoveredClass> classHierarchy = recoveredClass.getClassHierarchy();
|
||||
Iterator<RecoveredClass> classIterator = classHierarchy.iterator();
|
||||
while (classIterator.hasNext()) {
|
||||
for (RecoveredClass ancestor : classHierarchy) {
|
||||
monitor.checkCancelled();
|
||||
RecoveredClass ancestor = classIterator.next();
|
||||
if (ancestor.inheritsVirtualAncestor()) {
|
||||
return true;
|
||||
}
|
||||
@@ -4287,11 +4175,9 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
classHierarchyList.add(recoveredClass);
|
||||
|
||||
List<RecoveredClass> parentList = recoveredClass.getParentList();
|
||||
Iterator<RecoveredClass> parentIterator = parentList.iterator();
|
||||
while (parentIterator.hasNext()) {
|
||||
for (RecoveredClass parentClass : parentList) {
|
||||
monitor.checkCancelled();
|
||||
|
||||
RecoveredClass parentClass = parentIterator.next();
|
||||
if (nonInheritedClasses.contains(parentClass)) {
|
||||
classHierarchyList.addAll(parentClass.getClassHierarchy());
|
||||
continue;
|
||||
@@ -4403,8 +4289,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
disassemble = api.disassemble(address);
|
||||
|
||||
Bookmark bookmark = getBookmarkAt(possibleFunctionPointer, BookmarkType.ERROR,
|
||||
"Bad Instruction",
|
||||
"conflicting data");
|
||||
"Bad Instruction", "conflicting data");
|
||||
if (bookmark != null) {
|
||||
api.removeBookmark(bookmark);
|
||||
}
|
||||
@@ -4418,8 +4303,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
|
||||
private Bookmark getBookmarkAt(Address address, String bookmarkType, String category,
|
||||
String commentContains)
|
||||
throws CancelledException {
|
||||
String commentContains) throws CancelledException {
|
||||
|
||||
Bookmark[] bookmarks = program.getBookmarkManager().getBookmarks(address);
|
||||
|
||||
@@ -4544,10 +4428,9 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
for (RecoveredClass parent : parentList) {
|
||||
monitor.checkCancelled();
|
||||
if (parent.getName().endsWith("_class_type_info")) {
|
||||
Msg.debug(this,
|
||||
"Not creating class data type for " +
|
||||
recoveredClass.getClassNamespace().getName(true) +
|
||||
" because it has a parent that is one of the special typeinfo classes.");
|
||||
Msg.debug(this, "Not creating class data type for " +
|
||||
recoveredClass.getClassNamespace().getName(true) +
|
||||
" because it has a parent that is one of the special typeinfo classes.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -4570,8 +4453,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
recoveredClass.getClassNamespace().getName(true));
|
||||
}
|
||||
|
||||
updateClassFunctionsNotUsingNewClassStructure(recoveredClass,
|
||||
classStructure);
|
||||
updateClassFunctionsNotUsingNewClassStructure(recoveredClass, classStructure);
|
||||
// return in this case because if there is no vftable for a class the script cannot
|
||||
// identify any member functions so there is no need to process the rest of this
|
||||
// method
|
||||
@@ -4664,8 +4546,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
// simple case the offset for vftablePtr is 0
|
||||
// if can fit or grow structure, add the vftablePtr to it
|
||||
EditStructureUtils.addDataTypeToStructure(classStructureDataType, 0,
|
||||
classVftablePointer,
|
||||
CLASS_VTABLE_PTR_FIELD_EXT, monitor);
|
||||
classVftablePointer, CLASS_VTABLE_PTR_FIELD_EXT, monitor);
|
||||
}
|
||||
// if single inheritance or multi non-virtual (wouldn't have called this method
|
||||
// if it were virtually inherited) put parent struct and data into class struct
|
||||
@@ -4674,18 +4555,16 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
Map<Integer, RecoveredClass> orderToParentMap =
|
||||
classToParentOrderMap.get(recoveredClass);
|
||||
if (orderToParentMap == null || orderToParentMap.isEmpty()) {
|
||||
Msg.error(this,
|
||||
"Vmi class " + recoveredClass.getClassNamespace().getName(true) +
|
||||
" should have a parent in the classToParentOrderMap but doesn't");
|
||||
Msg.error(this, "Vmi class " + recoveredClass.getClassNamespace().getName(true) +
|
||||
" should have a parent in the classToParentOrderMap but doesn't");
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<RecoveredClass, Long> parentToOffsetMap =
|
||||
classToParentOffsetMap.get(recoveredClass);
|
||||
if (parentToOffsetMap.isEmpty()) {
|
||||
Msg.error(this,
|
||||
"Vmi class " + recoveredClass.getClassNamespace().getName(true) +
|
||||
" should have a parent in the classToParentOffsetMap but doesn't");
|
||||
Msg.error(this, "Vmi class " + recoveredClass.getClassNamespace().getName(true) +
|
||||
" should have a parent in the classToParentOffsetMap but doesn't");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -4705,8 +4584,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
if (baseClassStructure == null) {
|
||||
Msg.error(this, "Parent structure: " +
|
||||
parent.getClassNamespace().getName(true) +
|
||||
" should exist but doesn't.");
|
||||
parent.getClassNamespace().getName(true) + " should exist but doesn't.");
|
||||
return null;
|
||||
}
|
||||
// if it fits at offset or is at the end and class structure can be grown,
|
||||
@@ -4728,22 +4606,19 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
int dataLen = UNKNOWN;
|
||||
if (dataOffset != NONE) {
|
||||
dataLen = EditStructureUtils.getNumberOfUndefinedsStartingAtOffset(
|
||||
classStructureDataType, dataOffset,
|
||||
monitor);
|
||||
classStructureDataType, dataOffset, monitor);
|
||||
}
|
||||
|
||||
if (dataLen != UNKNOWN && dataLen > 0) {
|
||||
|
||||
Structure recoveredClassDataStruct =
|
||||
createClassMemberDataStructure(recoveredClass, classStructureDataType,
|
||||
dataLen, dataOffset);
|
||||
Structure recoveredClassDataStruct = createClassMemberDataStructure(recoveredClass,
|
||||
classStructureDataType, dataLen, dataOffset);
|
||||
|
||||
if (recoveredClassDataStruct != null) {
|
||||
// if it fits at offset or is at the end and class structure can be grown,
|
||||
// copy the whole baseClass structure to the class Structure at the given offset
|
||||
EditStructureUtils.addDataTypeToStructure(classStructureDataType, dataOffset,
|
||||
recoveredClassDataStruct,
|
||||
"data", monitor);
|
||||
recoveredClassDataStruct, "data", monitor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user