mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-06-01 01:32:54 +08:00
Merge remote-tracking branch 'origin/GP-3464_ghidra007_gcc_split_out_internal_parent_structures--SQUASHED'
This commit is contained in:
@@ -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();
|
||||
|
||||
+276
-180
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);
|
||||
|
||||
Reference in New Issue
Block a user