Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/Ghidra_10.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanmkurtz committed Nov 12, 2021
2 parents d9788c0 + 3aa234e commit 0e3da48
Show file tree
Hide file tree
Showing 12 changed files with 300 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public interface PtySession {
* @return the status code, if applicable and implemented
* @throws InterruptedException if the wait is interrupted
*/
Integer waitExited() throws InterruptedException;
int waitExited() throws InterruptedException;

/**
* Take the greatest efforts to terminate the session (leader and descendants)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public LocalProcessPtySession(Process process) {
}

@Override
public Integer waitExited() throws InterruptedException {
public int waitExited() throws InterruptedException {
return process.waitFor();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public SshPtySession(Channel channel) {
}

@Override
public Integer waitExited() throws InterruptedException {
public int waitExited() throws InterruptedException {
// Doesn't look like there's a clever way to wait. So do the spin sleep :(
while (!channel.isEOF()) {
Thread.sleep(1000);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public void testSessionBash() throws IOException, InterruptedException {
PtySession bash =
pty.getChild().session(new String[] { DummyProc.which("bash") }, null);
pty.getParent().getOutputStream().write("exit\n".getBytes());
assertEquals(0, bash.waitExited().intValue());
assertEquals(0, bash.waitExited());
}
}

Expand All @@ -78,7 +78,7 @@ public void testForkIntoNonExistent() throws IOException, InterruptedException {
* NOTE: Java subprocess dies with code 1 on unhandled exception. TODO: Is there a nice
* way to distinguish whether the code is from java or the execed image?
*/
assertEquals(1, dies.waitExited().intValue());
assertEquals(1, dies.waitExited());
}
}

Expand Down Expand Up @@ -117,7 +117,7 @@ public Thread runExitCheck(int expected, PtySession session) {
while (true) {
try {
assertEquals("Early exit with wrong code", expected,
session.waitExited().intValue());
session.waitExited());
return;
}
catch (InterruptedException e) {
Expand Down Expand Up @@ -159,7 +159,7 @@ public void testSessionBashEchoTest() throws IOException, InterruptedException {
assertTrue("Not 'exit 3' or 'BASH:exit 3': '" + line + "'",
Set.of("BASH:exit 3", "exit 3").contains(line));

assertEquals(3, bash.waitExited().intValue());
assertEquals(3, bash.waitExited());
}
}

Expand Down Expand Up @@ -214,7 +214,7 @@ public void testSessionBashInterruptCat() throws IOException, InterruptedExcepti
writer.flush();
assertTrue(Set.of("BASH:exit 3", "exit 3").contains(reader.readLine()));

assertEquals(3, bash.waitExited().intValue());
assertEquals(3, bash.waitExited());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public void testSessionBash() throws IOException, InterruptedException {
out.write("exit\n".getBytes("UTF-8"));
out.flush();
new StreamPumper(pty.getParent().getInputStream(), System.out).start();
assertEquals(0, bash.waitExited().intValue());
assertEquals(0, bash.waitExited());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void run() throws Exception {
}

RecoveredClassUtils classUtils = new RecoveredClassUtils(currentProgram, currentLocation,
state.getTool(), this, false, false, false, monitor);
state.getTool(), this, false, false, false, false, monitor);

Namespace classNamespace = classUtils.getClassNamespace(currentAddress);
if (classNamespace == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void run() throws Exception {
}

RecoveredClassUtils classUtils = new RecoveredClassUtils(currentProgram, currentLocation,
state.getTool(), this, false, false, false, monitor);
state.getTool(), this, false, false, false, false, monitor);

Namespace classNamespace = classUtils.getClassNamespace(currentAddress);
if (classNamespace == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,37 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
// show shortened class template names in class structure field names
private static final boolean USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS = true;

// replace defined existing class structures (ie pdb, fid, demangler, or other)with ones created by
// this script and rename the existing ones with a _REPLACED suffix
// NOTE: currently does not replace DWARF
// NEW OPTION:
private static final boolean REPLACE_EXISTING_CLASS_STRUCTURES = true;

private static final String CLASS_DATA_STRUCT_NAME = "_data";

private static final String CONSTRUCTOR_BOOKMARK = "CONSTRUCTOR";
private static final String DESTRUCTOR_BOOKMARK = "DESTRUCTOR";

private static final String INDETERMINATE_BOOKMARK = "INDETERMINATE";

// If replacedClassStructuresOption is set to the following, no replaced structures will be removed
// from the data type manager
private static final int DO_NOT_REMOVE_REPLACED_CLASS_STRUCTURES = 0;

// If replacedClassStructuresOption is set to the following, only empty existing class structures
// that were replaced by this script will be removed from the data type manager
private static final int REMOVE_EMPTY_REPLACED_CLASS_STRUCTURES = 1;

// If replacedClassStructuresOption is set to the following, all existing class structures that
// were replaced by this script, including non-emtpy ones, will be removed from the data type
// manager
private static final int REMOVE_ALL_REPLACED_CLASS_STRUCTURES = 2;

// NEW OPTION -
// This option allows the user to decide whether and how to remove replaced existing class structures
// using one of the above three flags
int replacedClassStructuresOption = DO_NOT_REMOVE_REPLACED_CLASS_STRUCTURES;

boolean programHasRTTIApplied = false;
boolean hasDebugSymbols;
boolean isGcc = false;
Expand Down Expand Up @@ -162,6 +186,7 @@ public void run() throws Exception {
recoverClassesFromRTTI = new RTTIWindowsClassRecoverer(currentProgram,
currentLocation, state.getTool(), this, BOOKMARK_FOUND_FUNCTIONS,
USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS, nameVfunctions, hasDebugSymbols,
REPLACE_EXISTING_CLASS_STRUCTURES,
monitor);
}
else if (isGcc()) {
Expand All @@ -182,6 +207,7 @@ else if (isGcc()) {
recoverClassesFromRTTI = new RTTIGccClassRecoverer(currentProgram, currentLocation,
state.getTool(), this, BOOKMARK_FOUND_FUNCTIONS,
USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS, nameVfunctions, hasDebugSymbols,
REPLACE_EXISTING_CLASS_STRUCTURES,
monitor);
}
else {
Expand Down Expand Up @@ -275,6 +301,17 @@ else if (isGcc()) {
showGraph(graph);
}

if (replacedClassStructuresOption == REMOVE_EMPTY_REPLACED_CLASS_STRUCTURES) {
println("Removing all empty replaced class structures from the data type manager");
recoverClassesFromRTTI.removeReplacedClassStructures(recoveredClasses, false);
}

if (replacedClassStructuresOption == REMOVE_ALL_REPLACED_CLASS_STRUCTURES) {
println(
"Removing all replaced class structures from the data type manager, including non-empty ones");
recoverClassesFromRTTI.removeReplacedClassStructures(recoveredClasses, true);
}


decompilerUtils.disposeDecompilerInterface();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,14 @@ public class RTTIClassRecoverer extends RecoveredClassUtils {
TaskMonitor monitor;
boolean hasDebugSymbols;


RTTIClassRecoverer(Program program, ProgramLocation location, PluginTool tool,
FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates,
boolean nameVfunctions, boolean hasDebugSymbols,
boolean nameVfunctions, boolean hasDebugSymbols, boolean replaceClassStructures,
TaskMonitor monitor) {

super(program, location, tool, api, createBookmarks, useShortTemplates, nameVfunctions,
replaceClassStructures,
monitor);

this.program = program;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,19 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
new HashMap<RecoveredClass, Map<RecoveredClass, Long>>();

boolean isDwarfLoaded;
boolean replaceClassStructs;

public RTTIGccClassRecoverer(Program program, ProgramLocation location, PluginTool tool,
FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates,
boolean nameVfunctions, boolean isDwarfLoaded, TaskMonitor monitor) {
boolean nameVfunctions, boolean isDwarfLoaded, boolean replaceExistingClassStructures,
TaskMonitor monitor) {

super(program, location, tool, api, createBookmarks, useShortTemplates, nameVfunctions,
replaceExistingClassStructures,
isDwarfLoaded,
monitor);
this.isDwarfLoaded = isDwarfLoaded;
this.replaceClassStructs = replaceExistingClassStructures;
}

@Override
Expand Down Expand Up @@ -2898,12 +2902,14 @@ private void processDataTypes(RecoveredClass recoveredClass)
Structure classStruct = createSimpleClassStructure(recoveredClass, vfPointerDataTypes);

// check for DWARF -- if none add c/d/etc to class
//TODO: if decide to replace dwarf data types then remove this check so the replaces
// in the following methods can replace the dwarf data types
if (!isDwarfLoaded) {

// Now that we have a class data type
// name constructor and destructor functions and put into the class namespace
addConstructorsToClassNamespace(recoveredClass, classStruct);
addDestructorsToClassNamespace(recoveredClass);
addDestructorsToClassNamespace(recoveredClass, classStruct);
// addNonThisDestructorsToClassNamespace(recoveredClass);
// addVbaseDestructorsToClassNamespace(recoveredClass);
// addVbtableToClassNamespace(recoveredClass);
Expand All @@ -2914,15 +2920,16 @@ private void processDataTypes(RecoveredClass recoveredClass)
// createIndeterminateInlineComments(recoveredClass);

// add label on constructor destructor functions that could not be determined which were which
createIndeterminateLabels(recoveredClass);
createIndeterminateLabels(recoveredClass, classStruct);
}

// This is done after the class structure is created and added to the dtmanager
// because if done before the class structures are created
// then empty classes will get auto-created in the wrong place
// when the vfunctions are put in the class

fillInAndApplyVftableStructAndNameVfunctions(recoveredClass, vfPointerDataTypes);
fillInAndApplyVftableStructAndNameVfunctions(recoveredClass, vfPointerDataTypes,
classStruct);

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {

public RTTIWindowsClassRecoverer(Program program, ProgramLocation location, PluginTool tool,
FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates,
boolean nameVFunctions, boolean isPDBLoaded,
boolean nameVFunctions, boolean isPDBLoaded, boolean replaceClassStructures,
TaskMonitor monitor) throws CancelledException {

super(program, location, tool, api, createBookmarks, useShortTemplates, nameVFunctions,
isPDBLoaded, monitor);
isPDBLoaded, replaceClassStructures, monitor);

this.isPDBLoaded = isPDBLoaded;

Expand Down Expand Up @@ -2245,32 +2245,35 @@ private void processDataTypes(RecoveredClass recoveredClass)

applyVbtableStructure(recoveredClass);

// pdb already has good names so only name if no pdb
if (!isPDBLoaded) {

// Now that we have a class data type
// name constructor and destructor functions and put into the class namespace
addConstructorsToClassNamespace(recoveredClass, classStruct);
addDestructorsToClassNamespace(recoveredClass);
// Now that we have a class data type
// name constructor and destructor functions and put into the class namespace
// checks are internal for hasDebugSymbols since there
// are also replace methods that need to be called either way
addConstructorsToClassNamespace(recoveredClass, classStruct);
addDestructorsToClassNamespace(recoveredClass, classStruct);
addVbaseDestructorsToClassNamespace(recoveredClass, classStruct);

if (!hasDebugSymbols) {
addNonThisDestructorsToClassNamespace(recoveredClass);
addVbaseDestructorsToClassNamespace(recoveredClass);

addVbtableToClassNamespace(recoveredClass);

// add secondary label on functions with inlined constructors or destructors
createInlinedConstructorComments(recoveredClass);
createInlinedDestructorComments(recoveredClass);
createIndeterminateInlineComments(recoveredClass);

// add label on constructor destructor functions that could not be determined which were which
createIndeterminateLabels(recoveredClass);
}

// add label on constructor destructor functions that could not be determined which were which
createIndeterminateLabels(recoveredClass, classStruct);

// This is done after the class structure is created and added to the dtmanager
// because if done before the class structures are created
// then empty classes will get auto-created in the wrong place
// when the vfunctions are put in the class

fillInAndApplyVftableStructAndNameVfunctions(recoveredClass, vfPointerDataTypes);
fillInAndApplyVftableStructAndNameVfunctions(recoveredClass, vfPointerDataTypes,
classStruct);

}

Expand Down
Loading

0 comments on commit 0e3da48

Please sign in to comment.