mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 02:09:44 +02:00
GP-972 Improvements to Gcc RTTI Class Recovery
This commit is contained in:
parent
c553971388
commit
e1953ebb22
7 changed files with 652 additions and 254 deletions
|
@ -35,18 +35,20 @@
|
|||
// this script and default vfunctions named by this script are likely to change in the future
|
||||
// once an official design for Object Oriented representation is determined.
|
||||
// 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
|
||||
// has DWARF, there will be some amount of data recovered by the DWARF analyzer in the DWARF data folder.
|
||||
// in early stages of development. Gcc class data types are only recovered for classes without multiple or
|
||||
// virtual inheritance but if the program contains DWARF, there will be some amount of data recovered
|
||||
// by the DWARF analyzer.
|
||||
// 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
|
||||
// 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.
|
||||
// to have it do so for you. See that script's description for more info.
|
||||
// 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.
|
||||
// are related, then run the ApplyClassFunctionDefinitionsUpdatesScript.java to do so. See that script's
|
||||
// description for more info. At some point, the Ghidra API will be updated to do the updates
|
||||
// automatically instead of needing the mentioned scripts to do so.
|
||||
|
||||
//@category C++
|
||||
|
||||
|
@ -152,6 +154,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
|
||||
|
||||
if (isWindows()) {
|
||||
|
||||
isPDBLoaded = isPDBLoadedInProgram();
|
||||
nameVfunctions = !isPDBLoaded;
|
||||
recoverClassesFromRTTI = new RTTIWindowsClassRecoverer(currentProgram,
|
||||
|
@ -159,7 +162,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS, nameVfunctions, isPDBLoaded, monitor);
|
||||
}
|
||||
else if (isGcc()) {
|
||||
// for now assume gcc has named vfunctions until a way to check is developed
|
||||
|
||||
nameVfunctions = true;
|
||||
recoverClassesFromRTTI = new RTTIGccClassRecoverer(currentProgram, currentLocation,
|
||||
state.getTool(), this, BOOKMARK_FOUND_FUNCTIONS,
|
||||
|
@ -176,7 +179,6 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
return;
|
||||
}
|
||||
|
||||
// possibly more picky subtype than just checking windows/gcc
|
||||
if (!recoverClassesFromRTTI.isValidProgramType()) {
|
||||
println("This script will not work on this program type");
|
||||
return;
|
||||
|
@ -465,9 +467,41 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
*/
|
||||
private boolean isGcc() {
|
||||
|
||||
isGcc =
|
||||
boolean isELF = currentProgram.getExecutableFormat().contains("ELF");
|
||||
if (!isELF) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isCompilerSpecGcc =
|
||||
currentProgram.getCompilerSpec().getCompilerSpecID().getIdAsString().equalsIgnoreCase(
|
||||
"gcc");
|
||||
if (isCompilerSpecGcc) {
|
||||
return true;
|
||||
}
|
||||
|
||||
MemoryBlock commentBlock = currentProgram.getMemory().getBlock(".comment");
|
||||
if (commentBlock == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!commentBlock.isLoaded()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// check memory bytes in block for GCC: bytes
|
||||
byte[] gccBytes = { (byte) 0x47, (byte) 0x43, (byte) 0x43, (byte) 0x3a };
|
||||
byte[] maskBytes = { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
|
||||
|
||||
Address found = currentProgram.getMemory().findBytes(commentBlock.getStart(),
|
||||
commentBlock.getEnd(), gccBytes, maskBytes, true, monitor);
|
||||
if (found == null) {
|
||||
isGcc = false;
|
||||
}
|
||||
else {
|
||||
isGcc = true;
|
||||
}
|
||||
|
||||
return isGcc;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue