mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 02:09:44 +02:00
GP-973 Added ApplyClassFunctionSignatureUpdatesScript and ApplyClassFunctionDefinitionUpdatesScript fix-up scripts for when users update RecoveredClass virtual function signatures or definitions.
This commit is contained in:
parent
8c488aaacf
commit
b6a5ce659b
7 changed files with 1306 additions and 299 deletions
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//Script to graph class hierarchies given metadata found in class structure description that
|
//Script to graph class hierarchies given metadata found in class structure description that
|
||||||
// was applied using the ExtractClassInfoFromRTTIScript.
|
// was applied using the RecoverClassesFromRTTIScript.
|
||||||
//@category C++
|
//@category C++
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
|
|
@ -1,191 +0,0 @@
|
||||||
/* ###
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
//Script to update the given class's virtual functions' function signature data types and
|
|
||||||
// the given class's vfunction structure field name for any differing functions in
|
|
||||||
// the class virtual function table(s). To run, put the cursor on any of the desired class's
|
|
||||||
// virtual functions or at the top a class vftable. The script will not work if the <class>_vftable
|
|
||||||
// structure is not applied to the vftable using the ExtractClassInfoFromRTTIScript.
|
|
||||||
//@category C++
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
|
||||||
import ghidra.program.model.address.Address;
|
|
||||||
import ghidra.program.model.data.*;
|
|
||||||
import ghidra.program.model.listing.*;
|
|
||||||
import ghidra.program.model.symbol.*;
|
|
||||||
import ghidra.util.exception.CancelledException;
|
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
|
||||||
|
|
||||||
public class UpdateClassFunctionDataScript extends GhidraScript {
|
|
||||||
@Override
|
|
||||||
public void run() throws Exception {
|
|
||||||
|
|
||||||
if (currentProgram == null) {
|
|
||||||
println("There is no open program");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Function function = getFunctionContaining(currentAddress);
|
|
||||||
if (function != null) {
|
|
||||||
|
|
||||||
Namespace parentNamespace = function.getParentNamespace();
|
|
||||||
|
|
||||||
Parameter thisParam = function.getParameter(0);
|
|
||||||
if (thisParam.getName().equals("this")) {
|
|
||||||
DataType dataType = thisParam.getDataType();
|
|
||||||
if (dataType instanceof Pointer) {
|
|
||||||
Pointer pointer = (Pointer) dataType;
|
|
||||||
DataType baseDataType = pointer.getDataType();
|
|
||||||
if (baseDataType.getName().equals(parentNamespace.getName())) {
|
|
||||||
// call update
|
|
||||||
println("updating class " + parentNamespace.getName());
|
|
||||||
updateClassFunctionDataTypes(parentNamespace);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Symbol primarySymbol = currentProgram.getSymbolTable().getPrimarySymbol(currentAddress);
|
|
||||||
if (primarySymbol.getName().equals("vftable") ||
|
|
||||||
primarySymbol.getName().substring(1).startsWith("vftable")) {
|
|
||||||
updateClassFunctionDataTypes(primarySymbol.getParentNamespace());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateClassFunctionDataTypes(Namespace classNamespace)
|
|
||||||
throws CancelledException, DuplicateNameException, DataTypeDependencyException {
|
|
||||||
|
|
||||||
List<Symbol> classVftableSymbols = getClassVftableSymbols(classNamespace);
|
|
||||||
|
|
||||||
Iterator<Symbol> vftableIterator = classVftableSymbols.iterator();
|
|
||||||
while (vftableIterator.hasNext()) {
|
|
||||||
monitor.checkCanceled();
|
|
||||||
Symbol vftableSymbol = vftableIterator.next();
|
|
||||||
Address vftableAddress = vftableSymbol.getAddress();
|
|
||||||
Data data = getDataAt(vftableAddress);
|
|
||||||
if (data == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
DataType baseDataType = data.getBaseDataType();
|
|
||||||
if (!(baseDataType instanceof Structure)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Structure vfunctionStructure = (Structure) baseDataType;
|
|
||||||
|
|
||||||
Category category = getDataTypeCategory(vfunctionStructure);
|
|
||||||
|
|
||||||
if (category == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check that the structure name starts with <classname>_vtable and that it is in
|
|
||||||
// the dt folder with name <classname>
|
|
||||||
if (category.getName().equals(classNamespace.getName()) &&
|
|
||||||
vfunctionStructure.getName().startsWith(classNamespace.getName() + "_vftable")) {
|
|
||||||
println(
|
|
||||||
"Updating vfunction signature data types and (if necessary) vtable structure for vftable at address " +
|
|
||||||
vftableAddress.toString());
|
|
||||||
updateVfunctionDataTypes(data, vfunctionStructure, vftableAddress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to find any function signatures in the given vfunction structure that have changed
|
|
||||||
* and update the function signature data types
|
|
||||||
* @throws DuplicateNameException
|
|
||||||
* @throws DataTypeDependencyException
|
|
||||||
*/
|
|
||||||
private void updateVfunctionDataTypes(Data structureAtAddress, Structure vfunctionStructure,
|
|
||||||
Address vftableAddress) throws DuplicateNameException, DataTypeDependencyException {
|
|
||||||
|
|
||||||
DataTypeManager dtMan = currentProgram.getDataTypeManager();
|
|
||||||
|
|
||||||
int numVfunctions = structureAtAddress.getNumComponents();
|
|
||||||
|
|
||||||
for (int i = 0; i < numVfunctions; i++) {
|
|
||||||
Data dataComponent = structureAtAddress.getComponent(i);
|
|
||||||
|
|
||||||
Reference[] referencesFrom = dataComponent.getReferencesFrom();
|
|
||||||
if (referencesFrom.length != 1) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Address functionAddress = referencesFrom[0].getToAddress();
|
|
||||||
Function vfunction = getFunctionAt(functionAddress);
|
|
||||||
if (vfunction == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
FunctionDefinitionDataType functionSignatureDataType =
|
|
||||||
(FunctionDefinitionDataType) vfunction.getSignature();
|
|
||||||
|
|
||||||
DataTypeComponent structureComponent = vfunctionStructure.getComponent(i);
|
|
||||||
DataType componentDataType = structureComponent.getDataType();
|
|
||||||
if (!(componentDataType instanceof Pointer)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Pointer pointer = (Pointer) componentDataType;
|
|
||||||
DataType pointedToDataType = pointer.getDataType();
|
|
||||||
if (functionSignatureDataType.equals(pointedToDataType)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// update data type with new new signature
|
|
||||||
dtMan.replaceDataType(pointedToDataType, functionSignatureDataType, true);
|
|
||||||
if (!structureComponent.getFieldName().equals(vfunction.getName())) {
|
|
||||||
structureComponent.setFieldName(vfunction.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private Category getDataTypeCategory(DataType dataType) {
|
|
||||||
|
|
||||||
DataTypeManager dataTypeManager = currentProgram.getDataTypeManager();
|
|
||||||
CategoryPath originalPath = dataType.getCategoryPath();
|
|
||||||
Category category = dataTypeManager.getCategory(originalPath);
|
|
||||||
|
|
||||||
return category;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Symbol> getClassVftableSymbols(Namespace classNamespace)
|
|
||||||
throws CancelledException {
|
|
||||||
|
|
||||||
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
|
||||||
List<Symbol> vftableSymbols = new ArrayList<Symbol>();
|
|
||||||
|
|
||||||
SymbolIterator symbols = symbolTable.getSymbols(classNamespace);
|
|
||||||
while (symbols.hasNext()) {
|
|
||||||
|
|
||||||
monitor.checkCanceled();
|
|
||||||
Symbol symbol = symbols.next();
|
|
||||||
if (symbol.getName().equals("vftable") ||
|
|
||||||
symbol.getName().substring(1).startsWith("vftable")) {
|
|
||||||
vftableSymbols.add(symbol);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return vftableSymbols;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
/* ###
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
// Script to apply any changes the user has made to class virtual function definitions, ie ones they
|
||||||
|
// have edited in the data type manager. To run the script, put the cursor on any member of the
|
||||||
|
// desired class in the listing then run the script. For each function definition in the given class
|
||||||
|
// that differs from the associated function signature in the listing, the script will update the
|
||||||
|
// listing function signatures of any related virtual vunctions (ie parents and children) and update
|
||||||
|
// related data types such as function definitions of the given class and related classes and also
|
||||||
|
// field names in related vftable structures.
|
||||||
|
// Note: The script will not work if the vftable structures were not originally applied to
|
||||||
|
// the vftables using the RecoverClassesFromRTTIScript.
|
||||||
|
// At some point, the Ghidra API will be updated to do this automatically instead of needing the script to do so.
|
||||||
|
//@category C++
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import classrecovery.RecoveredClassUtils;
|
||||||
|
import ghidra.app.script.GhidraScript;
|
||||||
|
import ghidra.program.model.data.FunctionDefinition;
|
||||||
|
import ghidra.program.model.data.Structure;
|
||||||
|
import ghidra.program.model.listing.Function;
|
||||||
|
import ghidra.program.model.symbol.Namespace;
|
||||||
|
import ghidra.program.model.symbol.Symbol;
|
||||||
|
|
||||||
|
public class ApplyClassFunctionDefinitionUpdatesScript extends GhidraScript {
|
||||||
|
@Override
|
||||||
|
public void run() throws Exception {
|
||||||
|
|
||||||
|
if (currentProgram == null) {
|
||||||
|
println("There is no open program");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RecoveredClassUtils classUtils = new RecoveredClassUtils(currentProgram, currentLocation,
|
||||||
|
state.getTool(), this, false, false, false, monitor);
|
||||||
|
|
||||||
|
Namespace classNamespace = classUtils.getClassNamespace(currentAddress);
|
||||||
|
if (classNamespace == null) {
|
||||||
|
println(
|
||||||
|
"Either cannot retrieve class namespace or cursor is not in a member of a class namepace");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Symbol> classVftableSymbols = classUtils.getClassVftableSymbols(classNamespace);
|
||||||
|
if (classVftableSymbols.isEmpty()) {
|
||||||
|
println("There are no vftables in this class");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
println(
|
||||||
|
"Applying differing function definitions for class " + classNamespace.getName(true));
|
||||||
|
|
||||||
|
List<Object> changedItems =
|
||||||
|
classUtils.applyNewFunctionDefinitions(classNamespace, classVftableSymbols);
|
||||||
|
|
||||||
|
if (changedItems.isEmpty()) {
|
||||||
|
println("No differences found for class " + classNamespace.getName(true) +
|
||||||
|
" between the vftable listing function signatures and their associated data type manager function definition data types");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Structure> structuresOnList = classUtils.getStructuresOnList(changedItems);
|
||||||
|
List<FunctionDefinition> functionDefinitionsOnList =
|
||||||
|
classUtils.getFunctionDefinitionsOnList(changedItems);
|
||||||
|
List<Function> functionsOnList = classUtils.getFunctionsOnList(changedItems);
|
||||||
|
|
||||||
|
println();
|
||||||
|
println("Updated structures:");
|
||||||
|
for (Structure structure : structuresOnList) {
|
||||||
|
monitor.checkCanceled();
|
||||||
|
println(structure.getPathName());
|
||||||
|
}
|
||||||
|
|
||||||
|
println();
|
||||||
|
println("Updated function definitions:");
|
||||||
|
for (FunctionDefinition functionDef : functionDefinitionsOnList) {
|
||||||
|
monitor.checkCanceled();
|
||||||
|
println(functionDef.getPathName());
|
||||||
|
}
|
||||||
|
|
||||||
|
println();
|
||||||
|
println("Updated functions:");
|
||||||
|
for (Function function : functionsOnList) {
|
||||||
|
monitor.checkCanceled();
|
||||||
|
println(function.getEntryPoint().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
/* ###
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
// Script to apply any changes the user has made to class virtual function signatures, ie ones they
|
||||||
|
// have edited in the listing. To run the script, put the cursor on any member of the desired class in
|
||||||
|
// the listing then run the script. For each function signature in the given class that differs from
|
||||||
|
// the associated function definition in the data type manager, the script will update the listing
|
||||||
|
// function signatures of any related virtual vunctions (ie parents and children) and update related
|
||||||
|
// data types such as function definitions of the given class and related classes and also field names
|
||||||
|
// in related vftable structures.
|
||||||
|
// Note: The script will not work if the vftable structures were not originally applied to
|
||||||
|
// the vftables using the RecoverClassesFromRTTIScript.
|
||||||
|
// At some point, the Ghidra API will be updated to do this automatically instead of needing the script to do so.
|
||||||
|
//@category C++
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import classrecovery.RecoveredClassUtils;
|
||||||
|
import ghidra.app.script.GhidraScript;
|
||||||
|
import ghidra.program.model.data.FunctionDefinition;
|
||||||
|
import ghidra.program.model.data.Structure;
|
||||||
|
import ghidra.program.model.listing.Function;
|
||||||
|
import ghidra.program.model.symbol.Namespace;
|
||||||
|
import ghidra.program.model.symbol.Symbol;
|
||||||
|
|
||||||
|
public class ApplyClassFunctionSignatureUpdatesScript extends GhidraScript {
|
||||||
|
@Override
|
||||||
|
public void run() throws Exception {
|
||||||
|
|
||||||
|
if (currentProgram == null) {
|
||||||
|
println("There is no open program");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RecoveredClassUtils classUtils = new RecoveredClassUtils(currentProgram, currentLocation,
|
||||||
|
state.getTool(), this, false, false, false, monitor);
|
||||||
|
|
||||||
|
Namespace classNamespace = classUtils.getClassNamespace(currentAddress);
|
||||||
|
if (classNamespace == null) {
|
||||||
|
println(
|
||||||
|
"Either cannot retrieve class namespace or cursor is not in a member of a class namepace");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Symbol> classVftableSymbols = classUtils.getClassVftableSymbols(classNamespace);
|
||||||
|
if (classVftableSymbols.isEmpty()) {
|
||||||
|
println("There are no vftables in this class");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
println("Applying differing virtual function signatures for class " +
|
||||||
|
classNamespace.getName(true));
|
||||||
|
|
||||||
|
List<Object> changedItems =
|
||||||
|
classUtils.applyNewFunctionSignatures(classNamespace, classVftableSymbols);
|
||||||
|
|
||||||
|
if (changedItems.isEmpty()) {
|
||||||
|
println("No differences found for class " + classNamespace.getName(true) +
|
||||||
|
" between the listing virtual function signatures and their associated data type manager function definition data types.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Structure> structuresOnList = classUtils.getStructuresOnList(changedItems);
|
||||||
|
List<FunctionDefinition> functionDefinitionsOnList =
|
||||||
|
classUtils.getFunctionDefinitionsOnList(changedItems);
|
||||||
|
List<Function> functionsOnList = classUtils.getFunctionsOnList(changedItems);
|
||||||
|
|
||||||
|
println();
|
||||||
|
println("Updated structures:");
|
||||||
|
for (Structure structure : structuresOnList) {
|
||||||
|
monitor.checkCanceled();
|
||||||
|
println(structure.getPathName());
|
||||||
|
}
|
||||||
|
|
||||||
|
println();
|
||||||
|
println("Updated function definitions:");
|
||||||
|
for (FunctionDefinition functionDef : functionDefinitionsOnList) {
|
||||||
|
monitor.checkCanceled();
|
||||||
|
println(functionDef.getPathName());
|
||||||
|
}
|
||||||
|
|
||||||
|
println();
|
||||||
|
println("Updated functions:");
|
||||||
|
for (Function function : functionsOnList) {
|
||||||
|
monitor.checkCanceled();
|
||||||
|
println(function.getEntryPoint().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -37,6 +37,17 @@
|
||||||
// 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 have not been recovered yet but if the program
|
// in early stages of development. Gcc class data types have not been recovered yet but if the program
|
||||||
// has DWARF, there will be some amount of data recovered by the DWARF analyzer in the DWARF data folder.
|
// has DWARF, there will be some amount of data recovered by the DWARF analyzer in the DWARF data folder.
|
||||||
|
// NOTE: For likely the best results, run this script on freshly analyzed programs. No testing has been
|
||||||
|
// done on user marked-up programs.
|
||||||
|
// NOTE: After running this script if you edit function signatures in the listing for a particular
|
||||||
|
// class and wish to update the corresponding class data (function definition data types, vftable
|
||||||
|
// structure field names, ...) then you can run the ApplyClassFunctionSignatureUpdatesScript.java
|
||||||
|
// to have it do so for you.
|
||||||
|
// Conversely, if you update a particular class's function definitions in the data type manager and
|
||||||
|
// wish to have related function signatures in the listing updated, as well as other data types that
|
||||||
|
// are related, then run the ApplyClassFunctionDefinitionsUpdatesScript.java to do so. At some point,
|
||||||
|
// the Ghidra API will be updated to do this all automatically instead of needing the scripts to do so.
|
||||||
|
|
||||||
//@category C++
|
//@category C++
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -124,8 +135,6 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
||||||
|
|
||||||
int defaultPointerSize;
|
int defaultPointerSize;
|
||||||
|
|
||||||
RecoveredClassUtils classUtils;
|
|
||||||
|
|
||||||
RTTIClassRecoverer recoverClassesFromRTTI;
|
RTTIClassRecoverer recoverClassesFromRTTI;
|
||||||
|
|
||||||
ExtraScriptUtils extraUtils;
|
ExtraScriptUtils extraUtils;
|
||||||
|
@ -143,25 +152,18 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
||||||
|
|
||||||
|
|
||||||
if (isWindows()) {
|
if (isWindows()) {
|
||||||
|
|
||||||
// TODO: check for typeinfo using the other way i had then pull the hasRTTI in and if first
|
|
||||||
// is true and second isn't then run the analyzer - move all this into a method
|
|
||||||
isPDBLoaded = isPDBLoadedInProgram();
|
isPDBLoaded = isPDBLoadedInProgram();
|
||||||
nameVfunctions = !isPDBLoaded;
|
nameVfunctions = !isPDBLoaded;
|
||||||
recoverClassesFromRTTI = new RTTIWindowsClassRecoverer(currentProgram,
|
recoverClassesFromRTTI = new RTTIWindowsClassRecoverer(currentProgram,
|
||||||
currentLocation, state.getTool(), this, BOOKMARK_FOUND_FUNCTIONS,
|
currentLocation, state.getTool(), this, BOOKMARK_FOUND_FUNCTIONS,
|
||||||
USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS, nameVfunctions, isPDBLoaded, monitor);
|
USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS, nameVfunctions, isPDBLoaded, monitor);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (isGcc()) {
|
else if (isGcc()) {
|
||||||
|
// for now assume gcc has named vfunctions until a way to check is developed
|
||||||
// for now assume gcc has named vfunctions
|
|
||||||
nameVfunctions = true;
|
nameVfunctions = true;
|
||||||
recoverClassesFromRTTI = new RTTIGccClassRecoverer(currentProgram, currentLocation,
|
recoverClassesFromRTTI = new RTTIGccClassRecoverer(currentProgram, currentLocation,
|
||||||
state.getTool(), this, BOOKMARK_FOUND_FUNCTIONS,
|
state.getTool(), this, BOOKMARK_FOUND_FUNCTIONS,
|
||||||
USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS, nameVfunctions, monitor);
|
USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS, nameVfunctions, monitor);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
println("This script will not work on this program type");
|
println("This script will not work on this program type");
|
||||||
|
@ -185,9 +187,6 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
decompilerUtils = recoverClassesFromRTTI.getDecompilerUtils();
|
decompilerUtils = recoverClassesFromRTTI.getDecompilerUtils();
|
||||||
DecompInterface decompInterface = decompilerUtils.getDecompilerInterface();
|
DecompInterface decompInterface = decompilerUtils.getDecompilerInterface();
|
||||||
|
|
||||||
|
@ -962,12 +961,12 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
||||||
println("Total number of indetermined constructor/destructors: " +
|
println("Total number of indetermined constructor/destructors: " +
|
||||||
remainingIndeterminates.size());
|
remainingIndeterminates.size());
|
||||||
|
|
||||||
//TODO: need to get from the new class
|
println("Total fixed incorrect FID functions: " +
|
||||||
// println("Total fixed incorrect FID functions: " + badFIDFunctions.size());
|
recoverClassesFromRTTI.getBadFIDFunctions().size());
|
||||||
// println("Total resolved functions that had multiple FID possiblities: " +
|
println("Total resolved functions that had multiple FID possiblities: " +
|
||||||
// resolvedFIDFunctions.size());
|
recoverClassesFromRTTI.getResolvedFIDFunctions().size());
|
||||||
// println("Total fixed functions that had incorrect data types due to incorrect FID: " +
|
println("Total fixed functions that had incorrect data types due to incorrect FID: " +
|
||||||
// fixedFIDFunctions.size());
|
recoverClassesFromRTTI.getFixedFIDFunctions().size());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ package classrecovery;
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//DO NOT RUN. THIS IS NOT A SCRIPT! THIS IS A CLASS THAT IS USED BY SCRIPTS.
|
//DO NOT RUN. THIS IS NOT A SCRIPT! THIS IS A CLASS THAT IS USED BY SCRIPTS.
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import ghidra.app.cmd.function.CreateFunctionCmd;
|
import ghidra.app.cmd.function.CreateFunctionCmd;
|
||||||
|
@ -506,20 +506,19 @@ public class ExtraScriptUtils extends FlatProgramAPI {
|
||||||
* Method to create a function in the given program at the given address
|
* Method to create a function in the given program at the given address
|
||||||
* @param prog the given program
|
* @param prog the given program
|
||||||
* @param addr the given address
|
* @param addr the given address
|
||||||
* @param tMonitor a cancellable task monitor
|
|
||||||
* @return true if the function was created, false otherwise
|
* @return true if the function was created, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean createFunction(Program prog, Address addr, TaskMonitor tMonitor) {
|
public boolean createFunction(Program prog, Address addr) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
AddressSet subroutineAddresses = getSubroutineAddresses(prog, addr, tMonitor);
|
AddressSet subroutineAddresses = getSubroutineAddresses(prog, addr);
|
||||||
if (subroutineAddresses.isEmpty()) {
|
if (subroutineAddresses.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateFunctionCmd cmd = new CreateFunctionCmd(null, subroutineAddresses.getMinAddress(),
|
CreateFunctionCmd cmd = new CreateFunctionCmd(null, subroutineAddresses.getMinAddress(),
|
||||||
null, SourceType.DEFAULT);
|
null, SourceType.DEFAULT);
|
||||||
if (cmd.applyTo(prog, tMonitor)) {
|
if (cmd.applyTo(prog, monitor)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,12 +534,11 @@ public class ExtraScriptUtils extends FlatProgramAPI {
|
||||||
* Method to figure out a subroutine address set given an address contained in it
|
* Method to figure out a subroutine address set given an address contained in it
|
||||||
* @param program the given program
|
* @param program the given program
|
||||||
* @param address address in the potential subroutine
|
* @param address address in the potential subroutine
|
||||||
* @param monitor allows canceling
|
|
||||||
* @return address set of the subroutine to be created
|
* @return address set of the subroutine to be created
|
||||||
* @throws CancelledException if cancelled
|
* @throws CancelledException if cancelled
|
||||||
*/
|
*/
|
||||||
public static AddressSet getSubroutineAddresses(Program program, Address address,
|
public AddressSet getSubroutineAddresses(Program program, Address address)
|
||||||
TaskMonitor monitor) throws CancelledException {
|
throws CancelledException {
|
||||||
|
|
||||||
// Create a new address set to hold the entire selection.
|
// Create a new address set to hold the entire selection.
|
||||||
AddressSet subroutineAddresses = new AddressSet();
|
AddressSet subroutineAddresses = new AddressSet();
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue