mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
Candidate release of source code.
This commit is contained in:
@@ -0,0 +1,657 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
// Identify and mark string parameters for functions by examining all references to defined strings
|
||||
// to see which functions they are passed into. If a defined string is passed into
|
||||
// a function, then that parameter must be a pointer to a string.
|
||||
//
|
||||
// WARNING: This script does not attempt to discover var-arg situations. It should be changed to do so.
|
||||
//
|
||||
// The engine for the script is the decompiler.
|
||||
//
|
||||
// The guts of this script past the main could be used to analyze
|
||||
// constants passed to any function on any processor.
|
||||
// It is not restricted to windows.
|
||||
//
|
||||
//@category Analysis
|
||||
|
||||
import ghidra.app.decompiler.*;
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.framework.options.ToolOptions;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.framework.plugintool.util.OptionsService;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.lang.PrototypeModel;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.pcode.*;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.util.exception.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class StringParameterPropagator extends GhidraScript {
|
||||
|
||||
// TODO!! Error handling needs a lot of work !!
|
||||
|
||||
private DecompInterface decomplib;
|
||||
|
||||
class FuncInfo {
|
||||
int minParamSeen = 256;
|
||||
int maxParamSeen = 0;
|
||||
BitSet paramsNoted = new BitSet();
|
||||
DataType dt = null;
|
||||
boolean conflictingDT = false;
|
||||
|
||||
// set that a given parameter had the attribute being tracked
|
||||
void setParamSeen(int paramIndex) {
|
||||
paramsNoted.set(paramIndex);
|
||||
}
|
||||
|
||||
void setDataTypeSeen(DataType dt) {
|
||||
if (conflictingDT) {
|
||||
return;
|
||||
}
|
||||
if (dt == null) {
|
||||
return;
|
||||
}
|
||||
if (this.dt != null && !this.dt.isEquivalent(dt)) {
|
||||
conflictingDT = true;
|
||||
return;
|
||||
}
|
||||
this.dt = dt;
|
||||
}
|
||||
|
||||
// record the number of parameters a particular function has
|
||||
void setNumParamsSeen(int numParams) {
|
||||
if (numParams < minParamSeen) {
|
||||
minParamSeen = numParams;
|
||||
}
|
||||
if (numParams > maxParamSeen) {
|
||||
maxParamSeen = numParams;
|
||||
}
|
||||
}
|
||||
|
||||
// true if all functions had the same number of parameters
|
||||
boolean numParamsAgree() {
|
||||
return (maxParamSeen == minParamSeen);
|
||||
}
|
||||
|
||||
int getMinParamsSeen() {
|
||||
return minParamSeen;
|
||||
}
|
||||
|
||||
DataType getDataType() {
|
||||
if (conflictingDT) {
|
||||
return DataType.DEFAULT;
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
|
||||
// get a list of parameter indexes that had the attribute being tracked
|
||||
ArrayList<Integer> getParamsSeen() {
|
||||
ArrayList<Integer> list = new ArrayList<Integer>();
|
||||
for (int i = 0; i <= maxParamSeen; i++) {
|
||||
if (paramsNoted.get(i)) {
|
||||
list.add(i);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public int getMaxParamsSeen() {
|
||||
return maxParamSeen;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
try {
|
||||
decomplib = setUpDecompiler(currentProgram);
|
||||
|
||||
if (!decomplib.openProgram(currentProgram)) {
|
||||
println("Decompile Error: " + decomplib.getLastMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
HashSet<Address> stringLocationSet = new HashSet<Address>();
|
||||
HashSet<Address> callingFuncLocationSet = new HashSet<Address>();
|
||||
|
||||
monitor.setMessage("Finding References to Data");
|
||||
long start = System.currentTimeMillis();
|
||||
// for each string data type defined
|
||||
collectStringDataReferenceLocations(stringLocationSet, callingFuncLocationSet);
|
||||
// collectDataRefenceLocations(stringLocationSet, callingFuncLocationSet);
|
||||
// collectSymbolDataRefenceLocations(stringLocationSet, callingFuncLocationSet);
|
||||
long end = System.currentTimeMillis();
|
||||
println("Initial search took : " + (end - start) / 1000 + " seconds");
|
||||
|
||||
// iterate over functions
|
||||
HashMap<Address, FuncInfo> funcParamMap = new HashMap<Address, FuncInfo>();
|
||||
//Iterator<Address> callingFuncIter = callingFuncLocationSet.iterator();
|
||||
while ((callingFuncLocationSet.size() > 0) && !monitor.isCancelled()) {
|
||||
Iterator<Address> callingFuncIter = callingFuncLocationSet.iterator();
|
||||
if (!callingFuncIter.hasNext()) {
|
||||
break;
|
||||
}
|
||||
Address entry = callingFuncIter.next();
|
||||
callingFuncIter.remove();
|
||||
|
||||
Function func = currentProgram.getFunctionManager().getFunctionAt(entry);
|
||||
if (func == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
monitor.setMessage("Analyzing calls in " + func.getName());
|
||||
|
||||
// look at each call
|
||||
// if param points to a string data type.
|
||||
// put on HashMap of function -> param#
|
||||
|
||||
analyzeFunction(funcParamMap, decomplib, currentProgram, func, stringLocationSet);
|
||||
}
|
||||
|
||||
// iterate over HashMap of functions
|
||||
HashSet<Address> doneItSet = new HashSet<Address>();
|
||||
Iterator<Address> entryIter = funcParamMap.keySet().iterator();
|
||||
while (entryIter.hasNext() && !monitor.isCancelled()) {
|
||||
Address entry = entryIter.next();
|
||||
FuncInfo funcInfo = funcParamMap.get(entry);
|
||||
|
||||
// TODO: Need to detect Var-args situation.
|
||||
// maybe record the number of params the function had last time, versus now?
|
||||
if (doneItSet.contains(entry)) {
|
||||
continue;
|
||||
}
|
||||
doneItSet.add(entry);
|
||||
|
||||
Function calledFunc = getFunctionAt(entry);
|
||||
|
||||
if (calledFunc == null) {
|
||||
calledFunc = createFunction(entry, null);
|
||||
}
|
||||
if (calledFunc == null || !decompileFunction(calledFunc, decomplib)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if Param not already char *
|
||||
// store params to database
|
||||
// set param# to char *
|
||||
|
||||
int minParams = funcInfo.getMinParamsSeen();
|
||||
int maxParams = funcInfo.getMaxParamsSeen();
|
||||
boolean couldBeVararg = !funcInfo.numParamsAgree();
|
||||
if (!funcInfo.numParamsAgree()) {
|
||||
currentProgram.getBookmarkManager().setBookmark(calledFunc.getEntryPoint(),
|
||||
BookmarkType.NOTE, this.getClass().getName(),
|
||||
"Number of parameters disagree min: " + minParams + " max: " + maxParams);
|
||||
|
||||
println("WARNING : Number of params disagree for " + calledFunc.getName() +
|
||||
" @ " + entry);
|
||||
if (minParams > 6) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<Integer> paramsSeen = funcInfo.getParamsSeen();
|
||||
while (paramsSeen.size() > 0) {
|
||||
int paramIndex = paramsSeen.remove(0);
|
||||
if (paramIndex > minParams) {
|
||||
println("WARNING: at " + calledFunc.getName() + ", Couldn't apply param " +
|
||||
paramIndex);
|
||||
continue;
|
||||
}
|
||||
DataType dt = new PointerDataType(funcInfo.getDataType());
|
||||
@SuppressWarnings("unused")
|
||||
boolean mustRedo =
|
||||
checkParams(calledFunc, dt, paramIndex, minParams, couldBeVararg);
|
||||
}
|
||||
|
||||
// if the signature changes, must redo the function
|
||||
// so get it off the done-list, and put it back on list of functions to look at
|
||||
// if (mustRedo) {
|
||||
// doneItSet.remove(entry);
|
||||
// // redo the function that called this function, because this function changed its parameters
|
||||
// redoAddress = func.getEntryPoint();
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
|
||||
end = System.currentTimeMillis();
|
||||
println("Total took : " + (end - start) / 1000 + " seconds");
|
||||
}
|
||||
finally {
|
||||
if (decomplib != null) {
|
||||
decomplib.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private void collectSymbolDataRefenceLocations(HashSet<Address> dataItemLocationSet,
|
||||
HashSet<Address> referringFuncLocationSet) {
|
||||
SymbolTable symtab = currentProgram.getSymbolTable();
|
||||
SymbolIterator symiter = symtab.getAllSymbols(true);
|
||||
int count = 0;
|
||||
while (symiter.hasNext() && !monitor.isCancelled()) {
|
||||
Symbol sym = symiter.next();
|
||||
if (!sym.hasReferences()) {
|
||||
continue;
|
||||
}
|
||||
Address addr = sym.getAddress();
|
||||
|
||||
if (count == 0) {
|
||||
monitor.setMessage("looking at : " + addr);
|
||||
}
|
||||
count = (count + 1) % 1024;
|
||||
|
||||
Data data = currentProgram.getListing().getDataAt(addr);
|
||||
if (data == null) {
|
||||
Function func = currentProgram.getFunctionManager().getFunctionAt(addr);
|
||||
if (func == null) {
|
||||
// no function, no data, get out
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Reference[] refs = sym.getReferences(null);
|
||||
for (int i = 0; i < refs.length && !monitor.isCancelled(); i++) {
|
||||
Reference ref = refs[i];
|
||||
// don't want flow references
|
||||
if (ref.getReferenceType().isFlow()) {
|
||||
continue;
|
||||
}
|
||||
// don't want reference to stack, although maybe we do...
|
||||
if (!ref.isMemoryReference()) {
|
||||
continue;
|
||||
}
|
||||
dataItemLocationSet.add(ref.getToAddress());
|
||||
|
||||
Function func =
|
||||
currentProgram.getFunctionManager().getFunctionContaining(ref.getFromAddress());
|
||||
if (func == null) {
|
||||
continue;
|
||||
}
|
||||
referringFuncLocationSet.add(func.getEntryPoint());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void collectStringDataReferenceLocations(HashSet<Address> stringLocationSet,
|
||||
HashSet<Address> referringFuncLocationSet) {
|
||||
DataIterator dataIter = currentProgram.getListing().getDefinedData(true);
|
||||
while (dataIter.hasNext() && !monitor.isCancelled()) {
|
||||
Data data = dataIter.next();
|
||||
// put string dt in addr set
|
||||
DataType dt = data.getDataType();
|
||||
if (!(dt instanceof StringDataType || dt instanceof TerminatedStringDataType ||
|
||||
dt instanceof UnicodeDataType || dt instanceof TerminatedUnicodeDataType)) {
|
||||
continue;
|
||||
}
|
||||
stringLocationSet.add(data.getAddress());
|
||||
ReferenceIterator refIter =
|
||||
currentProgram.getReferenceManager().getReferencesTo(data.getAddress());
|
||||
// find functions referencing the string
|
||||
while (refIter.hasNext()) {
|
||||
Reference ref = refIter.next();
|
||||
Function func =
|
||||
currentProgram.getFunctionManager().getFunctionContaining(ref.getFromAddress());
|
||||
if (func == null) {
|
||||
Data rData = currentProgram.getListing().getDefinedDataAt(ref.getFromAddress());
|
||||
if (rData == null) {
|
||||
continue;
|
||||
}
|
||||
if (rData.isPointer()) {
|
||||
ReferenceIterator dataRefIter = rData.getReferenceIteratorTo();
|
||||
while (dataRefIter.hasNext()) {
|
||||
Reference dataRef = dataRefIter.next();
|
||||
func =
|
||||
currentProgram.getFunctionManager().getFunctionContaining(
|
||||
dataRef.getFromAddress());
|
||||
if (func == null) {
|
||||
continue;
|
||||
}
|
||||
referringFuncLocationSet.add(func.getEntryPoint());
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
referringFuncLocationSet.add(func.getEntryPoint());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private void collectDataRefenceLocations(HashSet<Address> dataItemLocationSet,
|
||||
HashSet<Address> referringFuncLocationSet) {
|
||||
int count = 0;
|
||||
ReferenceIterator iter =
|
||||
currentProgram.getReferenceManager().getReferenceIterator(
|
||||
currentProgram.getMinAddress());
|
||||
while (iter.hasNext() && !monitor.isCancelled()) {
|
||||
Reference ref = iter.next();
|
||||
|
||||
if (count == 0) {
|
||||
monitor.setMessage("looking at : " + ref.getToAddress());
|
||||
}
|
||||
count = (count + 1) % 1024;
|
||||
|
||||
// don't want flow references
|
||||
if (ref.getReferenceType().isFlow()) {
|
||||
continue;
|
||||
}
|
||||
// don't want reference to stack, although maybe we do...
|
||||
if (!ref.isMemoryReference()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dataItemLocationSet.add(ref.getToAddress());
|
||||
|
||||
Function func =
|
||||
currentProgram.getFunctionManager().getFunctionContaining(ref.getFromAddress());
|
||||
if (func == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
referringFuncLocationSet.add(func.getEntryPoint());
|
||||
}
|
||||
}
|
||||
|
||||
private void markStringParam(HashMap<Address, FuncInfo> constUse, Address refAddr,
|
||||
Address entry, int paramIndex, int numParams) {
|
||||
FuncInfo curVal = constUse.get(entry);
|
||||
|
||||
if (curVal == null) {
|
||||
curVal = new FuncInfo();
|
||||
constUse.put(entry, curVal);
|
||||
}
|
||||
curVal.setNumParamsSeen(numParams); // saw this many params
|
||||
curVal.setParamSeen(paramIndex); // saw string at param x
|
||||
|
||||
Data data = currentProgram.getListing().getDefinedDataAt(refAddr);
|
||||
DataType dt = null;
|
||||
String name = "Ptr";
|
||||
if (data != null) {
|
||||
dt = data.getDataType();
|
||||
name = dt.getName();
|
||||
}
|
||||
curVal.setDataTypeSeen(dt);
|
||||
|
||||
println("found " + name + " param for " + entry + " param " + paramIndex);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private boolean checkParams(Function func, DataType dt, int paramIndex, int minParams,
|
||||
boolean couldBeVararg) {
|
||||
if (func == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PrototypeModel initialConvention = func.getCallingConvention();
|
||||
if (!func.hasVarArgs()) {
|
||||
fixupParams(func, minParams, couldBeVararg);
|
||||
}
|
||||
|
||||
// make sure prototype of called function didn't change!
|
||||
PrototypeModel convention = func.getCallingConvention();
|
||||
if (initialConvention == null && convention != null) {
|
||||
return true;
|
||||
}
|
||||
if (convention == null) {
|
||||
convention = currentProgram.getCompilerSpec().getDefaultCallingConvention();
|
||||
}
|
||||
if (initialConvention != null && !convention.getName().equals(initialConvention.getName())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// don't create strings past varargs
|
||||
if (func.hasVarArgs() && paramIndex >= func.getParameterCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Parameter param = func.getParameter(paramIndex);
|
||||
if (param != null && param.getDataType() instanceof PointerDataType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (param == null) {
|
||||
if (convention == null) {
|
||||
return false;
|
||||
}
|
||||
VariableStorage storage =
|
||||
convention.getArgLocation(paramIndex, func.getParameters(), dt, currentProgram);
|
||||
if (storage.isUnassignedStorage()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
param = new ParameterImpl(null, dt, storage, func.getProgram());
|
||||
// TODO: Fix deprecated method call
|
||||
param = func.addParameter(param, SourceType.USER_DEFINED);
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (param == null) {
|
||||
return false;
|
||||
}
|
||||
currentProgram.getBookmarkManager().setBookmark(func.getEntryPoint(), BookmarkType.NOTE,
|
||||
this.getClass().getName(), "Created " + dt.getName() + " parameter");
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void fixupParams(Function f, int minParams, boolean couldBeVararg) {
|
||||
if (f == null) {
|
||||
return;
|
||||
}
|
||||
if (couldBeVararg) {
|
||||
for (int i = f.getParameterCount(); i > minParams && i > 0; i--) {
|
||||
f.removeParameter(i - 1);
|
||||
}
|
||||
f.setVarArgs(true);
|
||||
}
|
||||
// must make number of parameters agree with function, because will be storing off a structure ptr
|
||||
LocalSymbolMap vmap = hfunction.getLocalSymbolMap();
|
||||
int numParams = vmap.getNumParams();
|
||||
if (f.getParameterCount() == numParams && f.getParameterCount() == minParams) {
|
||||
return;
|
||||
}
|
||||
if (minParams == numParams) {
|
||||
try {
|
||||
HighFunctionDBUtil.commitParamsToDatabase(hfunction, true, SourceType.USER_DEFINED);
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
throw new AssertException("Unexpected exception", e);
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
println(" ** problem at \n" + e.getMessage());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure prototype of called function didn't change!
|
||||
PrototypeModel convention = f.getCallingConvention();
|
||||
if (convention == null) {
|
||||
convention = currentProgram.getCompilerSpec().getDefaultCallingConvention();
|
||||
}
|
||||
|
||||
for (int i = 1; i <= minParams; i++) {
|
||||
if (i < f.getParameterCount()) {
|
||||
continue;
|
||||
}
|
||||
VariableStorage storage =
|
||||
convention.getArgLocation(i - 1, f.getParameters(), DataType.DEFAULT,
|
||||
currentProgram);
|
||||
if (storage.isUnassignedStorage()) {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
Parameter param =
|
||||
new ParameterImpl(null, DataType.DEFAULT, storage, f.getProgram());
|
||||
// TODO: Fix deprecated method call
|
||||
f.addParameter(param, SourceType.ANALYSIS);
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
println(" ** problem at \n" + e.getMessage());
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
println(" ** problem at \n" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyze a functions references
|
||||
* @param constUse
|
||||
*/
|
||||
public void analyzeFunction(HashMap<Address, FuncInfo> constUse,
|
||||
DecompInterface decompInterface, Program prog, Function f,
|
||||
HashSet<Address> stringLocationSet) {
|
||||
if (f == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!decompileFunction(f, decompInterface)) {
|
||||
return;
|
||||
}
|
||||
Address entry = f.getEntryPoint();
|
||||
|
||||
Iterator<PcodeOpAST> ops = hfunction.getPcodeOps();
|
||||
while (ops.hasNext() && !monitor.isCancelled()) {
|
||||
PcodeOpAST pcodeOpAST = ops.next();
|
||||
// System.out.println(pcodeOpAST);
|
||||
if (pcodeOpAST.getOpcode() != PcodeOp.CALL) {
|
||||
continue;
|
||||
}
|
||||
Varnode calledFunc = pcodeOpAST.getInput(0);
|
||||
|
||||
if (calledFunc == null || !calledFunc.isAddress()) {
|
||||
continue;
|
||||
}
|
||||
Address calledFuncAddr = calledFunc.getAddress();
|
||||
|
||||
// rifle through parameters
|
||||
int numParams = pcodeOpAST.getNumInputs();
|
||||
for (int i = 1; i < numParams; i++) {
|
||||
Varnode parm = pcodeOpAST.getInput(i); // 1st param is the call dest
|
||||
if (parm == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// follow back to a const if possible
|
||||
ArrayList<PcodeOp> localDefUseList = new ArrayList<PcodeOp>();
|
||||
|
||||
// check out the constUse list to see if we fished out a constant. Don't follow out of function
|
||||
// see if it is a constant
|
||||
if (parm.isConstant()) {
|
||||
// then this is a resource id
|
||||
// lookup the resource and create a reference
|
||||
long value = parm.getOffset();
|
||||
// TODO: not so fast, if there is a defUseList, must apply it to get the real constant USED!
|
||||
try {
|
||||
value = applyDefUseList(value, localDefUseList);
|
||||
// constUse.put(calledFuncAddr, i);
|
||||
}
|
||||
catch (InvalidInputException exc) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
long mask =
|
||||
0xffffffffffffffffL >>> ((8 - entry.getAddressSpace().getPointerSize()) * 8);
|
||||
Address possibleAddr = entry.getNewAddress(mask & value);
|
||||
if (stringLocationSet.contains(possibleAddr)) {
|
||||
markStringParam(constUse, possibleAddr, calledFuncAddr, i - 1,
|
||||
numParams - 1);
|
||||
}
|
||||
}
|
||||
if (parm.isAddress()) {
|
||||
if (stringLocationSet.contains(parm.getAddress())) {
|
||||
markStringParam(constUse, parm.getAddress(), calledFuncAddr, i - 1,
|
||||
numParams - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private long applyDefUseList(long value, ArrayList<PcodeOp> defUseList)
|
||||
throws InvalidInputException {
|
||||
if (defUseList.size() > 0)
|
||||
throw new InvalidInputException();
|
||||
return value;
|
||||
}
|
||||
|
||||
// Decompiler stuff
|
||||
|
||||
private HighFunction hfunction = null;
|
||||
|
||||
//private ClangTokenGroup docroot = null;
|
||||
|
||||
private Address lastDecompiledFuncAddr = null;
|
||||
|
||||
private DecompInterface setUpDecompiler(Program program) {
|
||||
DecompInterface decompInterface = new DecompInterface();
|
||||
|
||||
DecompileOptions options;
|
||||
options = new DecompileOptions();
|
||||
PluginTool tool = state.getTool();
|
||||
if (tool != null) {
|
||||
OptionsService service = tool.getService(OptionsService.class);
|
||||
if (service != null) {
|
||||
ToolOptions opt = service.getOptions("Decompiler");
|
||||
options.grabFromToolAndProgram(null, opt, program);
|
||||
}
|
||||
}
|
||||
decompInterface.setOptions(options);
|
||||
|
||||
decompInterface.toggleCCode(true);
|
||||
decompInterface.toggleSyntaxTree(true);
|
||||
decompInterface.setSimplificationStyle("decompile");
|
||||
|
||||
return decompInterface;
|
||||
}
|
||||
|
||||
public boolean decompileFunction(Function f, DecompInterface decompInterface) {
|
||||
// don't decompile the function again if it was the same as the last one
|
||||
//
|
||||
if (f.getEntryPoint().equals(lastDecompiledFuncAddr))
|
||||
return true;
|
||||
|
||||
try {
|
||||
DecompileResults decompRes =
|
||||
decompInterface.decompileFunction(f,
|
||||
decompInterface.getOptions().getDefaultTimeout(), monitor);
|
||||
|
||||
hfunction = decompRes.getHighFunction();
|
||||
}
|
||||
catch (Exception exc) {
|
||||
exc.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hfunction == null)
|
||||
return false;
|
||||
|
||||
lastDecompiledFuncAddr = f.getEntryPoint();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user