Merge remote-tracking branch 'origin/GP-3464_ghidra007_gcc_split_out_internal_parent_structures--SQUASHED'

This commit is contained in:
Ryan Kurtz
2023-08-30 10:53:43 -04:00
5 changed files with 426 additions and 305 deletions
@@ -150,28 +150,27 @@ public class RTTIClassRecoverer extends RecoveredClassHelper {
RecoveredClass recoveredClass = recoveredClassIterator.next();
// if class is non-virtual have to search for an existing class datatype
if (!recoveredClass.hasVftable()) {
DataType[] possibleExistingClassStructures =
extendedFlatAPI.getDataTypes(recoveredClass.getName());
if (possibleExistingClassStructures.length == 0) {
DataType[] possibleExistingClassStructures =
extendedFlatAPI.getDataTypes(recoveredClass.getName());
if (possibleExistingClassStructures.length == 0) {
continue;
}
for (int i = 0; i < possibleExistingClassStructures.length; i++) {
monitor.checkCancelled();
if (!(possibleExistingClassStructures[i] instanceof Structure)) {
continue;
}
for (int i = 0; i < possibleExistingClassStructures.length; i++) {
monitor.checkCancelled();
if (!(possibleExistingClassStructures[i] instanceof Structure)) {
continue;
}
if (possibleExistingClassStructures[i].isNotYetDefined()) {
continue;
}
Structure existingClassStructure =
(Structure) possibleExistingClassStructures[i];
recoveredClass.addExistingClassStructure(existingClassStructure);
break;
if (possibleExistingClassStructures[i].isNotYetDefined()) {
continue;
}
Structure existingClassStructure = (Structure) possibleExistingClassStructures[i];
recoveredClass.addExistingClassStructure(existingClassStructure);
break;
}
//Iterate over constructor/destructor functions
List<Function> constructorOrDestructorFunctions =
recoveredClass.getConstructorOrDestructorFunctions();
File diff suppressed because it is too large Load Diff
@@ -16,17 +16,7 @@
//DO NOT RUN. THIS IS NOT A SCRIPT! THIS IS A CLASS THAT IS USED BY SCRIPTS.
package classrecovery;
import java.util.ArrayList;
import java.util.Arrays;
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.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import ghidra.app.cmd.function.ApplyFunctionSignatureCmd;
@@ -40,78 +30,21 @@ import ghidra.app.util.NamespaceUtils;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.database.data.DataTypeUtilities;
import ghidra.program.flatapi.FlatProgramAPI;
import ghidra.program.model.address.Address;
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.address.GlobalNamespace;
import ghidra.program.model.data.ArrayDataType;
import ghidra.program.model.data.Category;
import ghidra.program.model.data.CategoryPath;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.DataTypeComponent;
import ghidra.program.model.data.DataTypeConflictHandler;
import ghidra.program.model.data.DataTypeDependencyException;
import ghidra.program.model.data.DataTypeManager;
import ghidra.program.model.data.FunctionDefinition;
import ghidra.program.model.data.FunctionDefinitionDataType;
import ghidra.program.model.data.NoisyStructureBuilder;
import ghidra.program.model.data.ParameterDefinition;
import ghidra.program.model.data.Pointer;
import ghidra.program.model.data.PointerDataType;
import ghidra.program.model.data.Structure;
import ghidra.program.model.data.StructureDataType;
import ghidra.program.model.data.Undefined1DataType;
import ghidra.program.model.data.Undefined4DataType;
import ghidra.program.model.data.Undefined8DataType;
import ghidra.program.model.data.VoidDataType;
import ghidra.program.model.address.*;
import ghidra.program.model.data.*;
import ghidra.program.model.lang.CompilerSpec;
import ghidra.program.model.listing.Bookmark;
import ghidra.program.model.listing.BookmarkManager;
import ghidra.program.model.listing.BookmarkType;
import ghidra.program.model.listing.CircularDependencyException;
import ghidra.program.model.listing.Data;
import ghidra.program.model.listing.FlowOverride;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.*;
import ghidra.program.model.listing.Function.FunctionUpdateType;
import ghidra.program.model.listing.FunctionManager;
import ghidra.program.model.listing.FunctionSignature;
import ghidra.program.model.listing.Instruction;
import ghidra.program.model.listing.InstructionIterator;
import ghidra.program.model.listing.Listing;
import ghidra.program.model.listing.Parameter;
import ghidra.program.model.listing.Program;
import ghidra.program.model.listing.ReturnParameterImpl;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.model.pcode.HighFunction;
import ghidra.program.model.pcode.HighVariable;
import ghidra.program.model.pcode.PcodeOp;
import ghidra.program.model.pcode.PcodeOpAST;
import ghidra.program.model.pcode.Varnode;
import ghidra.program.model.symbol.Namespace;
import ghidra.program.model.symbol.RefType;
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.SymbolTable;
import ghidra.program.model.symbol.SymbolType;
import ghidra.program.model.pcode.*;
import ghidra.program.model.symbol.*;
import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramMemoryUtil;
import ghidra.util.InvalidNameException;
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.bytesearch.*;
import ghidra.util.datastruct.ListAccumulator;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.DuplicateNameException;
import ghidra.util.exception.InvalidInputException;
import ghidra.util.exception.*;
import ghidra.util.task.TaskMonitor;
public class RecoveredClassHelper {
@@ -4490,7 +4423,7 @@ public class RecoveredClassHelper {
recoveredClass.getName(), structLen, dataTypeManager);
int numComponents = computedClassDataStructure.getNumDefinedComponents();
for (int i = 1; i < numComponents; i++) {
for (int i = 0; i < numComponents; i++) {
monitor.checkCancelled();
DataTypeComponent component = computedClassDataStructure.getComponent(i);
int offset = component.getOffset();
@@ -7711,7 +7644,9 @@ public class RecoveredClassHelper {
Address[] functionThunkAddresses = function.getFunctionThunkAddresses(true);
List<Address> functionAddresses = new ArrayList<>();
// add any thunk addresses to the list
List<Address> functionAddresses = new ArrayList<Address>();
// add the function itself to the list
functionAddresses.add(function.getEntryPoint());
if (functionThunkAddresses != null) {
@@ -7719,6 +7654,10 @@ public class RecoveredClassHelper {
functionAddresses.addAll(Arrays.asList(functionThunkAddresses));
}
if (functionThunkAddresses != null) {
functionAddresses.addAll(Arrays.asList(functionThunkAddresses));
}
for (Address address : functionAddresses) {
monitor.checkCancelled();
@@ -0,0 +1,95 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package classrecovery;
import java.util.ArrayList;
import java.util.List;
import ghidra.program.model.address.Address;
import ghidra.program.model.symbol.Namespace;
public class Vftable {
private Address vftableAddress;
private Namespace namespace;
private Vtable vtable;
private RecoveredClass containingClass;
private Long classOffset;
private RecoveredClass associatedClass;
private boolean isInternal;
private List<Address> vfunctions = new ArrayList<Address>();
public Vftable(Address vttAddress, Namespace namespace, Vtable vtable, boolean isInternal) {
this.vftableAddress = vttAddress;
this.namespace = namespace;
this.vtable = vtable;
this.isInternal = isInternal;
}
public Address getAddress() {
return vftableAddress;
}
public Namespace getNamespace() {
return namespace;
}
public Vtable getAssociatedVtable() {
return vtable;
}
public boolean isInternal() {
return isInternal;
}
public boolean isPrimary() {
return !isInternal;
}
public void setContainingClass(RecoveredClass recoveredClass) {
containingClass = recoveredClass;
}
public RecoveredClass getContainingClass() {
return containingClass;
}
public void setOffset(Long offset) {
classOffset = offset;
}
public Long getClassOffset() {
return classOffset;
}
public void setAssociatedClass(RecoveredClass recoveredClass) {
associatedClass = recoveredClass;
}
public RecoveredClass getAssociatedClass() {
return associatedClass;
}
public void addVfunction(Address address) {
vfunctions.add(address);
}
public int getNumVfunctions() {
return vfunctions.size();
}
//TODO: return num non-null vfunctions
}
@@ -18,32 +18,12 @@ package classrecovery;
import java.util.ArrayList;
import java.util.List;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressOutOfBoundsException;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.address.GlobalNamespace;
import ghidra.program.model.data.ArrayDataType;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.DataTypeManager;
import ghidra.program.model.data.LongDataType;
import ghidra.program.model.data.LongLongDataType;
import ghidra.program.model.address.*;
import ghidra.program.model.data.*;
import ghidra.program.model.lang.Register;
import ghidra.program.model.listing.Bookmark;
import ghidra.program.model.listing.BookmarkType;
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.Listing;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.Memory;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.model.symbol.Namespace;
import ghidra.program.model.symbol.SourceType;
import ghidra.program.model.symbol.Symbol;
import ghidra.program.model.symbol.SymbolTable;
import ghidra.program.model.listing.*;
import ghidra.program.model.mem.*;
import ghidra.program.model.symbol.*;
import ghidra.util.Msg;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
@@ -152,8 +132,6 @@ public class Vtable {
return;
}
// setIsConstructionVtable();
if (!isValid) {
return;
}
@@ -227,7 +205,6 @@ public class Vtable {
protected void setTypeinfoAddress() {
GccTypeinfo typeinfo = getReferencedTypeinfo();
typeinfoAddress = typeinfo.getAddress();
typeinfoNamespace = typeinfo.getNamespace();
@@ -303,7 +280,6 @@ public class Vtable {
protected void setHasVfunctions() throws CancelledException {
Address typeinfoRefAddress = getTypeinfoRefAddress();
if (isPrimary == null) {
isValid = false;
return;
@@ -539,6 +515,22 @@ public class Vtable {
return length;
}
public List<Long> getOffsets() {
List<Long> offsetValues = new ArrayList<Long>();
offsetValues.add(topOffsetValue);
// skip to next offset above the first one which we already knew and have added
// add all the values until all including the value at the vtableAddress are added
Address nextOffsetAddress = typeinfoRefAddress.subtract(2 * defaultPointerSize);
while (nextOffsetAddress.getOffset() <= vtableAddress.getOffset()) {
offsetValues.add(extendedFlatAPI.getLongValueAt(nextOffsetAddress));
nextOffsetAddress = nextOffsetAddress.subtract(defaultPointerSize);
}
return offsetValues;
}
private void findInternalVtables() throws CancelledException {
// if the current table is already an internal vtable there won't be any
@@ -725,7 +717,7 @@ public class Vtable {
}
public Data createVftableArray(Address vftableAddress, int numFunctionPointers)
throws CancelledException, AddressOutOfBoundsException {
throws AddressOutOfBoundsException {
listing.clearCodeUnits(vftableAddress,
vftableAddress.add((numFunctionPointers * defaultPointerSize - 1)), false);