Merge remote-tracking branch

'origin/GP-1055_ghidra007_gcc_class_rec_improvements_for_stripped_binaries--SQUASHED'
into patch (Closes #3266)
This commit is contained in:
ghidra1 2021-08-02 17:03:04 -04:00
commit a9ab72ecc4
9 changed files with 1160 additions and 574 deletions

View File

@ -63,6 +63,8 @@ import ghidra.app.plugin.core.analysis.DecompilerFunctionAnalyzer;
import ghidra.app.script.GhidraScript;
import ghidra.app.services.Analyzer;
import ghidra.app.services.GraphDisplayBroker;
import ghidra.app.util.bin.format.dwarf4.next.DWARFFunctionImporter;
import ghidra.app.util.bin.format.dwarf4.next.DWARFProgram;
import ghidra.app.util.bin.format.pdb.PdbParserConstants;
import ghidra.app.util.importer.MessageLog;
import ghidra.framework.options.Options;
@ -127,7 +129,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
private static final String INDETERMINATE_BOOKMARK = "INDETERMINATE";
boolean programHasRTTIApplied = false;
boolean isPDBLoaded;
boolean hasDebugSymbols;
boolean isGcc = false;
boolean isWindows = false;
String ghidraVersion = null;
@ -155,11 +157,12 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
if (isWindows()) {
isPDBLoaded = isPDBLoadedInProgram();
nameVfunctions = !isPDBLoaded;
hasDebugSymbols = isPDBLoadedInProgram();
nameVfunctions = !hasDebugSymbols;
recoverClassesFromRTTI = new RTTIWindowsClassRecoverer(currentProgram,
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, hasDebugSymbols,
monitor);
}
else if (isGcc()) {
@ -168,10 +171,18 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
if (!runGcc) {
return;
}
nameVfunctions = true;
hasDebugSymbols = isDwarfLoadedInProgram();
if (hasDwarf() && !hasDebugSymbols) {
println(
"The program contains DWARF but the DWARF analyzer has not been run. Please run the DWARF analyzer to get best results from this script.");
return;
}
nameVfunctions = !hasDebugSymbols;
recoverClassesFromRTTI = new RTTIGccClassRecoverer(currentProgram, currentLocation,
state.getTool(), this, BOOKMARK_FOUND_FUNCTIONS,
USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS, nameVfunctions, monitor);
USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS, nameVfunctions, hasDebugSymbols,
monitor);
}
else {
println("This script will not work on this program type");
@ -245,7 +256,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
" class member functions to assign.");
if (!isPDBLoaded) {
if (!hasDebugSymbols) {
if (BOOKMARK_FOUND_FUNCTIONS) {
bookmarkFunctions(recoveredClasses);
@ -268,6 +279,10 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
decompilerUtils.disposeDecompilerInterface();
}
private boolean hasDwarf() {
return DWARFProgram.isDWARF(currentProgram);
}
/**
* Method to determine if pdb info has been applied to the program
* @return true if pdb info has been applied to program
@ -277,6 +292,12 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
return options.getBoolean(PdbParserConstants.PDB_LOADED, false);
}
private boolean isDwarfLoadedInProgram() {
return DWARFFunctionImporter.hasDWARFProgModule(currentProgram,
DWARFProgram.DWARF_ROOT_NAME);
}
public String validate() {
if (currentProgram == null) {
@ -454,8 +475,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
/**
* Script only works on versions of ghidra after 9.2, but not 9.2.1 because a method was
* accidentally removed from FillOutStructureCmd that is needed
* Script works on versions of ghidra including and after 9.2 except for 9.2.1 because a method
* was accidentally removed from FillOutStructureCmd that is needed
* @return true if script will work and false otherwise
*/
private boolean checkGhidraVersion() {
@ -571,9 +592,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
private String getVersionOfGhidra() {
Options options = currentProgram.getOptions("Program Information");
Object ghidraVersionObject = options.getObject("Created With Ghidra Version", null);
return ghidraVersionObject.toString();
return options.getString("Created With Ghidra Version", null);
}

View File

@ -1,19 +1,3 @@
/* ###
* 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;
/* ###
* IP: GHIDRA
*
@ -30,6 +14,7 @@ package classrecovery;
* limitations under the License.
*/
//DO NOT RUN. THIS IS NOT A SCRIPT! THIS IS A CLASS THAT IS USED BY SCRIPTS.
package classrecovery;
import ghidra.app.decompiler.*;
import ghidra.framework.options.ToolOptions;
import ghidra.framework.plugintool.PluginTool;

View File

@ -1,19 +1,3 @@
/* ###
* 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;
/* ###
* IP: GHIDRA
*
@ -30,6 +14,8 @@ package classrecovery;
* limitations under the License.
*/
//DO NOT RUN. THIS IS NOT A SCRIPT! THIS IS A CLASS THAT IS USED BY SCRIPTS.
package classrecovery;
import java.util.*;
import ghidra.program.model.data.*;
@ -347,6 +333,10 @@ public class EditStructureUtils {
public int getNumberOfUndefinedsBeforeOffset(Structure structure, int offset,
TaskMonitor monitor) throws CancelledException {
if (structure.getNumComponents() == 0) {
return -1;
}
int numUndefineds = 0;
int index = offset - 1;

View File

@ -13,23 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//DO NOT RUN. THIS IS NOT A SCRIPT! THIS IS A CLASS THAT IS USED BY SCRIPTS.
package classrecovery;
/* ###
* 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.
*/
//DO NOT RUN. THIS IS NOT A SCRIPT! THIS IS A CLASS THAT IS USED BY SCRIPTS.
import java.util.*;
import ghidra.app.cmd.function.CreateFunctionCmd;
@ -110,8 +96,8 @@ public class ExtraScriptUtils extends FlatProgramAPI {
return null;
}
Address possibleFunctionPointer = address.getNewAddress(offset);
return possibleFunctionPointer;
Address possiblePointer = address.getNewAddress(offset);
return possiblePointer;
}
catch (MemoryAccessException e) {
@ -686,6 +672,11 @@ public class ExtraScriptUtils extends FlatProgramAPI {
public boolean doesFunctionACallAnyListedFunction(Function aFunction, List<Function> bFunctions)
throws CancelledException {
if (aFunction == null) {
return false;
}
Iterator<Function> bFunctionsIterator = bFunctions.iterator();
while (bFunctionsIterator.hasNext()) {
monitor.checkCanceled();
@ -798,6 +789,14 @@ public class ExtraScriptUtils extends FlatProgramAPI {
public boolean doesFunctionACallFunctionB(Function aFunction, Function bFunction)
throws CancelledException {
if (aFunction == null) {
return false;
}
if (bFunction == null) {
return false;
}
Set<Function> calledFunctions = aFunction.getCalledFunctions(monitor);
if (calledFunctions.contains(bFunction)) {
return true;

View File

@ -1,19 +1,3 @@
/* ###
* 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;
/* ###
* IP: GHIDRA
*
@ -30,6 +14,8 @@ package classrecovery;
* limitations under the License.
*/
//DO NOT RUN. THIS IS NOT A SCRIPT! THIS IS A CLASS THAT IS USED BY SCRIPTS.
package classrecovery;
import java.util.*;
import ghidra.app.util.NamespaceUtils;
@ -52,10 +38,11 @@ public class RTTIClassRecoverer extends RecoveredClassUtils {
String ghidraVersion;
Program program;
TaskMonitor monitor;
boolean hasDebugSymbols;
RTTIClassRecoverer(Program program, ProgramLocation location, PluginTool tool,
FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates,
boolean nameVfunctions,
boolean nameVfunctions, boolean hasDebugSymbols,
TaskMonitor monitor) {
super(program, location, tool, api, createBookmarks, useShortTemplates, nameVfunctions,
@ -69,6 +56,7 @@ public class RTTIClassRecoverer extends RecoveredClassUtils {
this.createBookmarks = createBookmarks;
this.useShortTemplates = useShortTemplates;
this.nameVfunctions = nameVfunctions;
this.hasDebugSymbols = hasDebugSymbols;
ghidraVersion = getVersionOfGhidra();
}
@ -109,9 +97,7 @@ public class RTTIClassRecoverer extends RecoveredClassUtils {
public String getVersionOfGhidra() {
Options options = program.getOptions("Program Information");
Object ghidraVersionObject = options.getObject("Created With Ghidra Version", null);
return ghidraVersionObject.toString();
return options.getString("Created With Ghidra Version", null);
}

View File

@ -13,23 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//DO NOT RUN. THIS IS NOT A SCRIPT! THIS IS A CLASS THAT IS USED BY SCRIPTS.
package classrecovery;
/* ###
* 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.
*/
//DO NOT RUN. THIS IS NOT A SCRIPT! THIS IS A CLASS THAT IS USED BY SCRIPTS.
import java.util.*;
import ghidra.app.plugin.core.decompile.actions.FillOutStructureCmd;
@ -89,7 +75,7 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
TaskMonitor monitor) throws CancelledException {
super(program, location, tool, api, createBookmarks, useShortTemplates, nameVFunctions,
monitor);
isPDBLoaded, monitor);
this.isPDBLoaded = isPDBLoaded;

View File

@ -1,19 +1,3 @@
/* ###
* 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;
/* ###
* IP: GHIDRA
*
@ -30,6 +14,8 @@ package classrecovery;
* limitations under the License.
*/
//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.Map.Entry;
@ -97,6 +83,7 @@ public class RecoveredClass {
private boolean inheritsVirtualAncestor = false;
private boolean isPublicClass = false;
private boolean isDiamondShaped = false;
private Structure existingClassStructure = null;
private Structure computedClassStructure = null;
@ -283,6 +270,14 @@ public class RecoveredClass {
return isPublicClass;
}
public void setIsDiamondShaped(boolean setting) {
isDiamondShaped = setting;
}
public boolean isDiamondShaped() {
return isDiamondShaped;
}
public void setHasVftable(boolean setting) {
hasVftable = setting;
}

View File

@ -1,19 +1,3 @@
/* ###
* 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;
/* ###
* IP: GHIDRA
*
@ -30,6 +14,8 @@ package classrecovery;
* limitations under the License.
*/
//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.stream.Collectors;
@ -1512,7 +1498,7 @@ public class RecoveredClassUtils {
/**
* Method to get ancestors that do not have vfunctions
* @param recoveredClass the given class
* @return true if any of the given class's ancestors are inherited virtually, false otherwise
* @return List of ancestors without vfunctions
* @throws CancelledException if cancelled
*/
public List<RecoveredClass> getAncestorsWithoutVfunctions(RecoveredClass recoveredClass)
@ -2772,7 +2758,6 @@ public class RecoveredClassUtils {
}
// add it to the vftableAddress to Class map
//vftableToClassMap.put(vftableAddress, recoveredClass);
updateVftableToClassMap(vftableAddress, recoveredClass);
List<Address> referencesToVftable = getReferencesToVftable(vftableAddress);