mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-25 05:32:14 +00:00
Merge remote-tracking branch 'origin/GP-3777_ghidra007_MakeSureAllClassFunctionsUseNewClassStructure--SQUASHED'
This commit is contained in:
commit
c4f766bd27
@ -17,7 +17,15 @@
|
||||
package classrecovery;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.*;
|
||||
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 ghidra.app.cmd.label.DemanglerCmd;
|
||||
import ghidra.app.plugin.core.analysis.ReferenceAddressPair;
|
||||
@ -26,20 +34,67 @@ import ghidra.app.util.demangler.DemangledObject;
|
||||
import ghidra.app.util.demangler.DemanglerUtil;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.flatapi.FlatProgramAPI;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.data.*;
|
||||
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.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.*;
|
||||
import ghidra.program.model.mem.*;
|
||||
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.scalar.Scalar;
|
||||
import ghidra.program.model.symbol.*;
|
||||
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.util.CodeUnitInsertionException;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.program.util.ProgramMemoryUtil;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.bytesearch.*;
|
||||
import ghidra.util.exception.*;
|
||||
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.task.TaskMonitor;
|
||||
|
||||
public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
@ -4508,12 +4563,16 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
|
||||
if (!recoveredClass.hasVftable()) {
|
||||
|
||||
Structure classStructure = createSimpleClassStructure(recoveredClass, null);
|
||||
if (classStructure == null) {
|
||||
Msg.error(this, "Could not create class structure for " +
|
||||
recoveredClass.getClassNamespace().getName(true));
|
||||
}
|
||||
// return here because if there is no vftable for a class the script cannot
|
||||
|
||||
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
|
||||
return;
|
||||
@ -4559,6 +4618,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||
fillInAndApplyVftableStructAndNameVfunctions(recoveredClass, vfPointerDataTypes,
|
||||
classStruct);
|
||||
|
||||
updateClassFunctionsNotUsingNewClassStructure(recoveredClass, classStruct);
|
||||
}
|
||||
|
||||
private Structure createSimpleClassStructure(RecoveredClass recoveredClass,
|
||||
|
@ -16,7 +16,14 @@
|
||||
//DO NOT RUN. THIS IS NOT A SCRIPT! THIS IS A CLASS THAT IS USED BY SCRIPTS.
|
||||
package classrecovery;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import ghidra.app.plugin.core.decompile.actions.FillOutStructureCmd;
|
||||
import ghidra.app.plugin.core.decompile.actions.FillOutStructureCmd.OffsetPcodeOpPair;
|
||||
@ -24,17 +31,41 @@ import ghidra.app.util.opinion.PeLoader;
|
||||
import ghidra.app.util.opinion.PeLoader.CompilerOpinion.CompilerEnum;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.flatapi.FlatProgramAPI;
|
||||
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.AddressOutOfBoundsException;
|
||||
import ghidra.program.model.address.AddressRange;
|
||||
import ghidra.program.model.address.AddressSet;
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
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.DataTypeConflictHandler;
|
||||
import ghidra.program.model.data.IntegerDataType;
|
||||
import ghidra.program.model.data.PointerDataType;
|
||||
import ghidra.program.model.data.Structure;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
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.Instruction;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.mem.MemoryBlock;
|
||||
import ghidra.program.model.pcode.HighFunction;
|
||||
import ghidra.program.model.pcode.HighVariable;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.program.model.symbol.Namespace;
|
||||
import ghidra.program.model.symbol.Reference;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.program.model.symbol.Symbol;
|
||||
import ghidra.program.model.symbol.SymbolIterator;
|
||||
import ghidra.program.model.symbol.SymbolType;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
@ -2180,7 +2211,11 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
throws CancelledException, Exception {
|
||||
|
||||
if (!recoveredClass.hasVftable()) {
|
||||
createClassStructureUsingRTTI(recoveredClass, null);
|
||||
Structure classStruct = createClassStructureUsingRTTI(recoveredClass, null);
|
||||
|
||||
if (classStruct != null) {
|
||||
updateClassFunctionsNotUsingNewClassStructure(recoveredClass, classStruct);
|
||||
}
|
||||
// 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
|
||||
return;
|
||||
@ -2226,6 +2261,10 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
fillInAndApplyVftableStructAndNameVfunctions(recoveredClass, vfPointerDataTypes,
|
||||
classStruct);
|
||||
|
||||
if (classStruct != null) {
|
||||
updateClassFunctionsNotUsingNewClassStructure(recoveredClass, classStruct);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,17 @@
|
||||
//DO NOT RUN. THIS IS NOT A SCRIPT! THIS IS A CLASS THAT IS USED BY SCRIPTS.
|
||||
package classrecovery;
|
||||
|
||||
import java.util.*;
|
||||
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.stream.Collectors;
|
||||
|
||||
import ghidra.app.cmd.function.ApplyFunctionSignatureCmd;
|
||||
@ -30,21 +40,80 @@ 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.*;
|
||||
import ghidra.program.model.data.*;
|
||||
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.lang.CompilerSpec;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.lang.PrototypeModel;
|
||||
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.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.listing.Variable;
|
||||
import ghidra.program.model.mem.MemoryBlock;
|
||||
import ghidra.program.model.pcode.*;
|
||||
import ghidra.program.model.symbol.*;
|
||||
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.util.ProgramLocation;
|
||||
import ghidra.program.util.ProgramMemoryUtil;
|
||||
import ghidra.util.InvalidNameException;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.bytesearch.*;
|
||||
import ghidra.util.bytesearch.GenericByteSequencePattern;
|
||||
import ghidra.util.bytesearch.GenericMatchAction;
|
||||
import ghidra.util.bytesearch.Match;
|
||||
import ghidra.util.bytesearch.MemoryBytePatternSearcher;
|
||||
import ghidra.util.datastruct.ListAccumulator;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class RecoveredClassHelper {
|
||||
@ -4772,6 +4841,90 @@ public class RecoveredClassHelper {
|
||||
return vfunctionSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to update any class functions that are not already using it to use the given
|
||||
* class structure
|
||||
* @param recoveredClass the given class
|
||||
* @param classStructure the given class structure
|
||||
* @throws CancelledException if cancelled
|
||||
*/
|
||||
protected void updateClassFunctionsNotUsingNewClassStructure(RecoveredClass recoveredClass,
|
||||
Structure classStructure) throws CancelledException {
|
||||
|
||||
if (classStructure == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Namespace classNamespace = recoveredClass.getClassNamespace();
|
||||
|
||||
SymbolIterator symbols = symbolTable.getSymbols(classNamespace);
|
||||
|
||||
FunctionManager functionManager = program.getFunctionManager();
|
||||
|
||||
while (symbols.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
|
||||
Symbol symbol = symbols.next();
|
||||
|
||||
Function function = functionManager.getFunctionAt(symbol.getAddress());
|
||||
|
||||
if (function == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.isThunk()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PrototypeModel callingConvention = function.getCallingConvention();
|
||||
if (callingConvention == null) {
|
||||
Msg.debug(this, "no calling convention for: " + function.getEntryPoint());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!callingConvention.hasThisPointer()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Parameter[] parameters = function.getParameters();
|
||||
if (parameters.length == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DataType dataType = parameters[0].getDataType();
|
||||
if (!(dataType instanceof Pointer pointer)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DataType pointedToDt = pointer.getDataType();
|
||||
if (!pointedToDt.equals(classStructure)) {
|
||||
Pointer classStructurePointer = new PointerDataType(classStructure);
|
||||
try {
|
||||
List<Variable> newParamList = new ArrayList<>();
|
||||
for (Parameter param : parameters) {
|
||||
|
||||
newParamList.add(param);
|
||||
}
|
||||
|
||||
FunctionUpdateType updateType = FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS;
|
||||
if (function.hasCustomVariableStorage()) {
|
||||
updateType = FunctionUpdateType.CUSTOM_STORAGE;
|
||||
}
|
||||
|
||||
newParamList.get(0).setDataType(classStructurePointer, SourceType.ANALYSIS);
|
||||
function.replaceParameters(newParamList,
|
||||
updateType, false, SourceType.ANALYSIS);
|
||||
}
|
||||
catch (InvalidInputException | DuplicateNameException e) {
|
||||
Msg.error(this, "Could not update function at " + function.getEntryPoint() +
|
||||
" with new class structure due to exception: " + e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasDeletingDestructorInNamespace(Address address, Namespace namespace)
|
||||
throws CancelledException {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user