mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GP-4708 Adjustments to RecoverClassesFromRTTIScript and
FillOutStructureHelper
This commit is contained in:
parent
5ab72bf4f2
commit
184c657cfd
4 changed files with 112 additions and 119 deletions
|
@ -18,8 +18,6 @@ package classrecovery;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import ghidra.app.decompiler.DecompileOptions;
|
|
||||||
import ghidra.app.decompiler.component.DecompilerUtils;
|
|
||||||
import ghidra.app.decompiler.util.FillOutStructureHelper;
|
import ghidra.app.decompiler.util.FillOutStructureHelper;
|
||||||
import ghidra.app.decompiler.util.FillOutStructureHelper.OffsetPcodeOpPair;
|
import ghidra.app.decompiler.util.FillOutStructureHelper.OffsetPcodeOpPair;
|
||||||
import ghidra.app.util.opinion.PeLoader;
|
import ghidra.app.util.opinion.PeLoader;
|
||||||
|
@ -1480,10 +1478,7 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DecompileOptions decompileOptions =
|
FillOutStructureHelper fillStructHelper = new FillOutStructureHelper(program, monitor);
|
||||||
DecompilerUtils.getDecompileOptions(serviceProvider, program);
|
|
||||||
FillOutStructureHelper fillStructHelper =
|
|
||||||
new FillOutStructureHelper(program, decompileOptions, monitor);
|
|
||||||
|
|
||||||
for (Function constructor : constructorList) {
|
for (Function constructor : constructorList) {
|
||||||
|
|
||||||
|
@ -1568,7 +1563,7 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||||
|
|
||||||
monitor.checkCancelled();
|
monitor.checkCancelled();
|
||||||
|
|
||||||
fillStructHelper.processStructure(highVariable, function, true, false);
|
fillStructHelper.processStructure(highVariable, function, true, false, null);
|
||||||
List<OffsetPcodeOpPair> stores = fillStructHelper.getStorePcodeOps();
|
List<OffsetPcodeOpPair> stores = fillStructHelper.getStorePcodeOps();
|
||||||
stores = removePcodeOpsNotInFunction(function, stores);
|
stores = removePcodeOpsNotInFunction(function, stores);
|
||||||
|
|
||||||
|
@ -2484,7 +2479,7 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||||
baseClassDescriptorAddress.toString());
|
baseClassDescriptorAddress.toString());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Continue if the class has mult inh but base class is not on the parent list
|
// Continue if the class has mult inh but base class is not on the parent list
|
||||||
if (!recoveredClass.getParentList().contains(baseClass)) {
|
if (!recoveredClass.getParentList().contains(baseClass)) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -22,8 +22,6 @@ import java.util.stream.Collectors;
|
||||||
import ghidra.app.cmd.function.ApplyFunctionSignatureCmd;
|
import ghidra.app.cmd.function.ApplyFunctionSignatureCmd;
|
||||||
import ghidra.app.cmd.label.AddLabelCmd;
|
import ghidra.app.cmd.label.AddLabelCmd;
|
||||||
import ghidra.app.cmd.label.SetLabelPrimaryCmd;
|
import ghidra.app.cmd.label.SetLabelPrimaryCmd;
|
||||||
import ghidra.app.decompiler.DecompileOptions;
|
|
||||||
import ghidra.app.decompiler.component.DecompilerUtils;
|
|
||||||
import ghidra.app.decompiler.util.FillOutStructureHelper;
|
import ghidra.app.decompiler.util.FillOutStructureHelper;
|
||||||
import ghidra.app.decompiler.util.FillOutStructureHelper.OffsetPcodeOpPair;
|
import ghidra.app.decompiler.util.FillOutStructureHelper.OffsetPcodeOpPair;
|
||||||
import ghidra.app.plugin.core.navigation.locationreferences.LocationReference;
|
import ghidra.app.plugin.core.navigation.locationreferences.LocationReference;
|
||||||
|
@ -1135,10 +1133,7 @@ public class RecoveredClassHelper {
|
||||||
highVariables
|
highVariables
|
||||||
.addAll(getVariableThatStoresVftablePointer(highFunction, firstVftableReference));
|
.addAll(getVariableThatStoresVftablePointer(highFunction, firstVftableReference));
|
||||||
|
|
||||||
DecompileOptions decompileOptions =
|
FillOutStructureHelper fillStructHelper = new FillOutStructureHelper(program, monitor);
|
||||||
DecompilerUtils.getDecompileOptions(serviceProvider, program);
|
|
||||||
FillOutStructureHelper fillStructHelper =
|
|
||||||
new FillOutStructureHelper(program, decompileOptions, monitor);
|
|
||||||
|
|
||||||
Address vftableAddress = null;
|
Address vftableAddress = null;
|
||||||
for (HighVariable highVariable : highVariables) {
|
for (HighVariable highVariable : highVariables) {
|
||||||
|
@ -1146,7 +1141,8 @@ public class RecoveredClassHelper {
|
||||||
monitor.checkCancelled();
|
monitor.checkCancelled();
|
||||||
|
|
||||||
Structure structure =
|
Structure structure =
|
||||||
fillStructHelper.processStructure(highVariable, function, true, false);
|
fillStructHelper.processStructure(highVariable, function, true, false,
|
||||||
|
decompilerUtils.getDecompilerInterface());
|
||||||
|
|
||||||
NoisyStructureBuilder componentMap = fillStructHelper.getComponentMap();
|
NoisyStructureBuilder componentMap = fillStructHelper.getComponentMap();
|
||||||
|
|
||||||
|
@ -1202,13 +1198,12 @@ public class RecoveredClassHelper {
|
||||||
|
|
||||||
Address address = getTargetAddressFromPcodeOp(pcodeOp);
|
Address address = getTargetAddressFromPcodeOp(pcodeOp);
|
||||||
if (address.equals(vftableReference)) {
|
if (address.equals(vftableReference)) {
|
||||||
|
Varnode input = pcodeOp.getInput(1);
|
||||||
Varnode[] inputs = pcodeOp.getInputs();
|
if (input.getDef() != null && input.getDef().getOpcode() == PcodeOp.CAST) {
|
||||||
for (Varnode input : inputs) {
|
input = input.getDef().getInput(0);
|
||||||
monitor.checkCancelled();
|
}
|
||||||
if (input.getHigh() != null) {
|
if (input.getHigh() != null) {
|
||||||
highVars.add(input.getHigh());
|
highVars.add(input.getHigh());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5855,16 +5850,13 @@ public class RecoveredClassHelper {
|
||||||
highVariables
|
highVariables
|
||||||
.addAll(getVariableThatStoresVftablePointer(highFunction, firstVftableReference));
|
.addAll(getVariableThatStoresVftablePointer(highFunction, firstVftableReference));
|
||||||
|
|
||||||
DecompileOptions decompileOptions =
|
FillOutStructureHelper fillStructHelper = new FillOutStructureHelper(program, monitor);
|
||||||
DecompilerUtils.getDecompileOptions(serviceProvider, program);
|
|
||||||
FillOutStructureHelper fillStructHelper =
|
|
||||||
new FillOutStructureHelper(program, decompileOptions, monitor);
|
|
||||||
|
|
||||||
for (HighVariable highVariable : highVariables) {
|
for (HighVariable highVariable : highVariables) {
|
||||||
|
|
||||||
monitor.checkCancelled();
|
monitor.checkCancelled();
|
||||||
|
|
||||||
fillStructHelper.processStructure(highVariable, function, true, false);
|
fillStructHelper.processStructure(highVariable, function, true, false, null);
|
||||||
List<OffsetPcodeOpPair> stores = fillStructHelper.getStorePcodeOps();
|
List<OffsetPcodeOpPair> stores = fillStructHelper.getStorePcodeOps();
|
||||||
stores = removePcodeOpsNotInFunction(function, stores);
|
stores = removePcodeOpsNotInFunction(function, stores);
|
||||||
|
|
||||||
|
|
|
@ -66,23 +66,24 @@ public class FillOutStructureCmd extends BackgroundCommand<Program> {
|
||||||
throw new AssertionError("program does not match location");
|
throw new AssertionError("program does not match location");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Function function =
|
||||||
|
program.getFunctionManager().getFunctionContaining(location.getAddress());
|
||||||
|
if (function == null) {
|
||||||
|
setStatusMsg("Function not found at " + location.getAddress());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FillOutStructureHelper fillStructureHelper =
|
||||||
|
new FillOutStructureHelper(program, monitor);
|
||||||
|
DecompInterface decompInterface = fillStructureHelper.setUpDecompiler(decompileOptions);
|
||||||
try {
|
try {
|
||||||
Function function =
|
|
||||||
program.getFunctionManager().getFunctionContaining(location.getAddress());
|
|
||||||
if (function == null) {
|
|
||||||
setStatusMsg("Function not found at " + location.getAddress());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FillOutStructureHelper fillStructureHelper =
|
|
||||||
new FillOutStructureHelper(program, decompileOptions, monitor);
|
|
||||||
|
|
||||||
HighVariable var = null;
|
HighVariable var = null;
|
||||||
|
|
||||||
if (!(location instanceof DecompilerLocation dloc)) {
|
if (!(location instanceof DecompilerLocation dloc)) {
|
||||||
// if we don't have one, make one, and map variable to a varnode
|
// if we don't have one, make one, and map variable to a varnode
|
||||||
Address storageAddr = computeStorageAddress(function);
|
Address storageAddr = computeStorageAddress(function);
|
||||||
var = fillStructureHelper.computeHighVariable(storageAddr, function);
|
var =
|
||||||
|
fillStructureHelper.computeHighVariable(storageAddr, function, decompInterface);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
|
@ -108,7 +109,8 @@ public class FillOutStructureCmd extends BackgroundCommand<Program> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Structure structDT = fillStructureHelper.processStructure(var, function, false, true);
|
Structure structDT =
|
||||||
|
fillStructureHelper.processStructure(var, function, false, true, decompInterface);
|
||||||
if (structDT == null) {
|
if (structDT == null) {
|
||||||
setStatusMsg("Failed to fill-out structure");
|
setStatusMsg("Failed to fill-out structure");
|
||||||
return false;
|
return false;
|
||||||
|
@ -131,6 +133,9 @@ public class FillOutStructureCmd extends BackgroundCommand<Program> {
|
||||||
Msg.showError(this, null, "Auto Create Structure Failed",
|
Msg.showError(this, null, "Auto Create Structure Failed",
|
||||||
"Failed to create Structure variable", e);
|
"Failed to create Structure variable", e);
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
decompInterface.dispose();
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@ import java.util.Map.Entry;
|
||||||
import ghidra.app.cmd.label.RenameLabelCmd;
|
import ghidra.app.cmd.label.RenameLabelCmd;
|
||||||
import ghidra.app.decompiler.*;
|
import ghidra.app.decompiler.*;
|
||||||
import ghidra.app.decompiler.component.DecompilerUtils;
|
import ghidra.app.decompiler.component.DecompilerUtils;
|
||||||
import ghidra.framework.plugintool.ServiceProvider;
|
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.address.AddressSet;
|
import ghidra.program.model.address.AddressSet;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
|
@ -35,11 +34,16 @@ import ghidra.util.exception.InvalidInputException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatically creates a structure definition based on the references found by the decompiler.
|
* Automatically create a Structure data-type based on references found by the decompiler to a
|
||||||
*
|
* root parameter or other variable.
|
||||||
* If the parameter is already a structure pointer, any new references found will be added
|
|
||||||
* to the structure, even if the structure must grow.
|
|
||||||
*
|
*
|
||||||
|
* If the parameter is already a Structure pointer, any new references found can optionally be added
|
||||||
|
* to the existing Structure data-type.
|
||||||
|
* {@link #processStructure(HighVariable, Function, boolean, boolean, DecompInterface)} is the primary
|
||||||
|
* entry point to the helper, which computes the new or updated Structure based on an existing
|
||||||
|
* decompiled function. Decompilation, if not provided externally, can be performed by calling
|
||||||
|
* {@link #computeHighVariable(Address, Function, DecompInterface)}. A decompiler process,
|
||||||
|
* if not provided externally, can be started by calling {@link #setUpDecompiler(DecompileOptions)}.
|
||||||
*/
|
*/
|
||||||
public class FillOutStructureHelper {
|
public class FillOutStructureHelper {
|
||||||
|
|
||||||
|
@ -61,7 +65,6 @@ public class FillOutStructureHelper {
|
||||||
|
|
||||||
private Program currentProgram;
|
private Program currentProgram;
|
||||||
private TaskMonitor monitor;
|
private TaskMonitor monitor;
|
||||||
private DecompileOptions decompileOptions;
|
|
||||||
|
|
||||||
private static final int maxCallDepth = 1;
|
private static final int maxCallDepth = 1;
|
||||||
|
|
||||||
|
@ -75,36 +78,35 @@ public class FillOutStructureHelper {
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param program the current program
|
* @param program the current program
|
||||||
* @param decompileOptions decompiler options
|
|
||||||
* (see {@link DecompilerUtils#getDecompileOptions(ServiceProvider, Program)})
|
|
||||||
* @param monitor task monitor
|
* @param monitor task monitor
|
||||||
*/
|
*/
|
||||||
public FillOutStructureHelper(Program program, DecompileOptions decompileOptions,
|
public FillOutStructureHelper(Program program, TaskMonitor monitor) {
|
||||||
TaskMonitor monitor) {
|
|
||||||
this.currentProgram = program;
|
this.currentProgram = program;
|
||||||
this.decompileOptions = decompileOptions;
|
|
||||||
this.monitor = monitor;
|
this.monitor = monitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to create a structure data type for a variable in the given function.
|
* Create or update a Structure data-type given a function and a root pointer variable.
|
||||||
* Unlike the applyTo() action, this method will not modify the function, its variables,
|
* The function must already be decompiled, but if a decompiler interface is provided, this
|
||||||
* or any existing data-types. A new structure is always created.
|
* method will recursively follow variable references into CALLs, possibly triggering additional
|
||||||
* @param var a parameter, local variable, or global variable used in the given function
|
* decompilation.
|
||||||
* @param function the function to process
|
* @param var is the pointer variable
|
||||||
* @param createNewStructure if true a new structure with a unique name will always be generated,
|
* @param function is the function to process
|
||||||
* if false and variable corresponds to a structure pointer the existing structure will be
|
* @param createNewStructure if true a new Structure with a unique name will always be generated,
|
||||||
|
* if false and the variable corresponds to a Structure pointer, the existing Structure will be
|
||||||
* updated instead.
|
* updated instead.
|
||||||
* @param createClassIfNeeded if true and variable corresponds to a <B>this</B> pointer without
|
* @param createClassIfNeeded if true and variable corresponds to a <B>this</B> pointer without
|
||||||
* an assigned Ghidra Class (i.e., {@code void * this}), the function will be assigned to a
|
* an assigned Ghidra Class (i.e., {@code void * this}), the function will be assigned to a
|
||||||
* new unique Ghidra Class namespace with a new identically named structure returned. If false,
|
* new unique Ghidra Class namespace with a new identically named Structure returned. If false,
|
||||||
* a new uniquely structure will be created.
|
* a new unique Structure will be created.
|
||||||
* @return a filled-in structure or null if one could not be created
|
* @param decomplib is the (optional) decompiler interface, which can be used to recursively
|
||||||
|
* decompile into CALLs.
|
||||||
|
* @return a filled-in Structure or null if one could not be created
|
||||||
*/
|
*/
|
||||||
public Structure processStructure(HighVariable var, Function function,
|
public Structure processStructure(HighVariable var, Function function,
|
||||||
boolean createNewStructure, boolean createClassIfNeeded) {
|
boolean createNewStructure, boolean createClassIfNeeded, DecompInterface decomplib) {
|
||||||
|
|
||||||
if (var == null || var.getSymbol() == null || var.getOffset() >= 0) {
|
if (var == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +122,9 @@ public class FillOutStructureHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
fillOutStructureDef(var);
|
fillOutStructureDef(var);
|
||||||
pushIntoCalls();
|
if (decomplib != null) {
|
||||||
|
pushIntoCalls(decomplib);
|
||||||
|
}
|
||||||
|
|
||||||
long size = componentMap.getSize();
|
long size = componentMap.getSize();
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
|
@ -168,7 +172,7 @@ public class FillOutStructureHelper {
|
||||||
/**
|
/**
|
||||||
* Retrieve the component map that was generated when structure was created using decompiler
|
* Retrieve the component map that was generated when structure was created using decompiler
|
||||||
* info. Results are not valid until
|
* info. Results are not valid until
|
||||||
* {@link #processStructure(HighVariable, Function, boolean, boolean)} is invoked.
|
* {@link #processStructure(HighVariable, Function, boolean, boolean, DecompInterface)} is invoked.
|
||||||
* @return componentMap
|
* @return componentMap
|
||||||
*/
|
*/
|
||||||
public NoisyStructureBuilder getComponentMap() {
|
public NoisyStructureBuilder getComponentMap() {
|
||||||
|
@ -179,7 +183,7 @@ public class FillOutStructureHelper {
|
||||||
* Retrieve the offset/pcodeOp pairs that are used to store data into the variable
|
* Retrieve the offset/pcodeOp pairs that are used to store data into the variable
|
||||||
* used to fill-out structure.
|
* used to fill-out structure.
|
||||||
* Results are not valid until
|
* Results are not valid until
|
||||||
* {@link #processStructure(HighVariable, Function, boolean, boolean)} is invoked.
|
* {@link #processStructure(HighVariable, Function, boolean, boolean, DecompInterface)} is invoked.
|
||||||
* @return the pcodeOps doing the storing to the associated variable
|
* @return the pcodeOps doing the storing to the associated variable
|
||||||
*/
|
*/
|
||||||
public List<OffsetPcodeOpPair> getStorePcodeOps() {
|
public List<OffsetPcodeOpPair> getStorePcodeOps() {
|
||||||
|
@ -190,7 +194,7 @@ public class FillOutStructureHelper {
|
||||||
* Retrieve the offset/pcodeOp pairs that are used to load data from the variable
|
* Retrieve the offset/pcodeOp pairs that are used to load data from the variable
|
||||||
* used to fill-out structure.
|
* used to fill-out structure.
|
||||||
* Results are not valid until
|
* Results are not valid until
|
||||||
* {@link #processStructure(HighVariable, Function, boolean, boolean)} is invoked.
|
* {@link #processStructure(HighVariable, Function, boolean, boolean, DecompInterface)} is invoked.
|
||||||
* @return the pcodeOps doing the loading from the associated variable
|
* @return the pcodeOps doing the loading from the associated variable
|
||||||
*/
|
*/
|
||||||
public List<OffsetPcodeOpPair> getLoadPcodeOps() {
|
public List<OffsetPcodeOpPair> getLoadPcodeOps() {
|
||||||
|
@ -237,8 +241,9 @@ public class FillOutStructureHelper {
|
||||||
/**
|
/**
|
||||||
* Recursively visit calls that take the structure pointer as a parameter.
|
* Recursively visit calls that take the structure pointer as a parameter.
|
||||||
* Add any new references to the offsetToDataTypeMap.
|
* Add any new references to the offsetToDataTypeMap.
|
||||||
|
* @param decomplib is the active interface for decompiling
|
||||||
*/
|
*/
|
||||||
private void pushIntoCalls() {
|
private void pushIntoCalls(DecompInterface decomplib) {
|
||||||
AddressSet doneSet = new AddressSet();
|
AddressSet doneSet = new AddressSet();
|
||||||
|
|
||||||
while (addressToCallInputMap.size() > 0) {
|
while (addressToCallInputMap.size() > 0) {
|
||||||
|
@ -256,7 +261,7 @@ public class FillOutStructureHelper {
|
||||||
doneSet.addRange(addr, addr);
|
doneSet.addRange(addr, addr);
|
||||||
Function func = currentProgram.getFunctionManager().getFunctionAt(addr);
|
Function func = currentProgram.getFunctionManager().getFunctionAt(addr);
|
||||||
Address storageAddr = savedList.get(addr);
|
Address storageAddr = savedList.get(addr);
|
||||||
HighVariable paramHighVar = computeHighVariable(storageAddr, func);
|
HighVariable paramHighVar = computeHighVariable(storageAddr, func, decomplib);
|
||||||
if (paramHighVar != null) {
|
if (paramHighVar != null) {
|
||||||
fillOutStructureDef(paramHighVar);
|
fillOutStructureDef(paramHighVar);
|
||||||
}
|
}
|
||||||
|
@ -268,77 +273,73 @@ public class FillOutStructureHelper {
|
||||||
* Decompile a function and return the resulting HighVariable associated with a storage address
|
* Decompile a function and return the resulting HighVariable associated with a storage address
|
||||||
* @param storageAddress the storage address of the variable
|
* @param storageAddress the storage address of the variable
|
||||||
* @param function is the function
|
* @param function is the function
|
||||||
|
* @param decomplib is the active interface to use for decompiling
|
||||||
* @return the corresponding HighVariable or null
|
* @return the corresponding HighVariable or null
|
||||||
*/
|
*/
|
||||||
public HighVariable computeHighVariable(Address storageAddress, Function function) {
|
public HighVariable computeHighVariable(Address storageAddress, Function function,
|
||||||
|
DecompInterface decomplib) {
|
||||||
if (storageAddress == null) {
|
if (storageAddress == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
DecompInterface decomplib = setUpDecompiler();
|
|
||||||
HighVariable highVar = null;
|
HighVariable highVar = null;
|
||||||
|
|
||||||
// call decompiler to get syntax tree
|
// call decompiler to get syntax tree
|
||||||
try {
|
DecompileResults results = decomplib.decompileFunction(function,
|
||||||
if (!decomplib.openProgram(currentProgram)) {
|
decomplib.getOptions().getDefaultTimeout(), monitor);
|
||||||
return null;
|
if (monitor.isCancelled()) {
|
||||||
}
|
return null;
|
||||||
|
|
||||||
DecompileResults results = decomplib.decompileFunction(function,
|
|
||||||
decomplib.getOptions().getDefaultTimeout(), monitor);
|
|
||||||
if (monitor.isCancelled()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
HighFunction highFunc = results.getHighFunction();
|
|
||||||
|
|
||||||
// no decompile...
|
|
||||||
if (highFunc == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// try to map the variable
|
|
||||||
HighSymbol sym =
|
|
||||||
highFunc.getMappedSymbol(storageAddress, function.getEntryPoint().subtractWrap(1L));
|
|
||||||
if (sym == null) {
|
|
||||||
sym = highFunc.getMappedSymbol(storageAddress, null);
|
|
||||||
}
|
|
||||||
if (sym == null) {
|
|
||||||
sym = highFunc.getMappedSymbol(storageAddress, function.getEntryPoint());
|
|
||||||
}
|
|
||||||
if (sym == null) {
|
|
||||||
sym = highFunc.getLocalSymbolMap()
|
|
||||||
.findLocal(storageAddress, function.getEntryPoint().subtractWrap(1L));
|
|
||||||
}
|
|
||||||
if (sym == null) {
|
|
||||||
sym = highFunc.getLocalSymbolMap().findLocal(storageAddress, null);
|
|
||||||
}
|
|
||||||
if (sym == null) {
|
|
||||||
sym = highFunc.getLocalSymbolMap()
|
|
||||||
.findLocal(storageAddress, function.getEntryPoint());
|
|
||||||
}
|
|
||||||
if (sym == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
highVar = sym.getHighVariable();
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
decomplib.dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HighFunction highFunc = results.getHighFunction();
|
||||||
|
|
||||||
|
// no decompile...
|
||||||
|
if (highFunc == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to map the variable
|
||||||
|
HighSymbol sym =
|
||||||
|
highFunc.getMappedSymbol(storageAddress, function.getEntryPoint().subtractWrap(1L));
|
||||||
|
if (sym == null) {
|
||||||
|
sym = highFunc.getMappedSymbol(storageAddress, null);
|
||||||
|
}
|
||||||
|
if (sym == null) {
|
||||||
|
sym = highFunc.getMappedSymbol(storageAddress, function.getEntryPoint());
|
||||||
|
}
|
||||||
|
if (sym == null) {
|
||||||
|
sym = highFunc.getLocalSymbolMap()
|
||||||
|
.findLocal(storageAddress, function.getEntryPoint().subtractWrap(1L));
|
||||||
|
}
|
||||||
|
if (sym == null) {
|
||||||
|
sym = highFunc.getLocalSymbolMap().findLocal(storageAddress, null);
|
||||||
|
}
|
||||||
|
if (sym == null) {
|
||||||
|
sym = highFunc.getLocalSymbolMap()
|
||||||
|
.findLocal(storageAddress, function.getEntryPoint());
|
||||||
|
}
|
||||||
|
if (sym == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
highVar = sym.getHighVariable();
|
||||||
return highVar;
|
return highVar;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up a decompiler interface for recovering data-flow
|
* Set up a decompiler interface and prepare for decompiling on the currentProgram.
|
||||||
|
* The interface can be used to pass to computeHighVariable or to processStructure.
|
||||||
|
* @param options are the options to pass to the decompiler
|
||||||
* @return the decompiler interface
|
* @return the decompiler interface
|
||||||
*/
|
*/
|
||||||
private DecompInterface setUpDecompiler() {
|
public DecompInterface setUpDecompiler(DecompileOptions options) {
|
||||||
DecompInterface decomplib = new DecompInterface();
|
DecompInterface decomplib = new DecompInterface();
|
||||||
decomplib.setOptions(decompileOptions);
|
decomplib.setOptions(options);
|
||||||
decomplib.toggleCCode(true);
|
decomplib.toggleCCode(true);
|
||||||
decomplib.toggleSyntaxTree(true);
|
decomplib.toggleSyntaxTree(true);
|
||||||
decomplib.setSimplificationStyle("decompile");
|
decomplib.setSimplificationStyle("decompile");
|
||||||
|
if (!decomplib.openProgram(currentProgram)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return decomplib;
|
return decomplib;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue