ghidra/Ghidra/Features/Decompiler/ghidra_scripts/WindowsResourceReference.java

781 lines
26 KiB
Java

/* ###
* 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.
*/
/*
* Given certain Key windows API calls, tries to create references at the use of windows Resources.
* This script uses the decompiler and the simplified Pcode AST to locate constant values passed to key
* functions like LoadStringW, LoadIconW, etc...
*
* 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.
*
* The assumption is made that default program analysis has already been run in order to retrieve
* the best results from this script.
* @category Windows
*/
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
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.address.AddressSetView;
import ghidra.program.model.listing.*;
import ghidra.program.model.pcode.*;
import ghidra.program.model.symbol.*;
import ghidra.program.model.util.AddressSetPropertyMap;
import ghidra.util.UndefinedFunction;
import ghidra.util.exception.*;
public class WindowsResourceReference extends GhidraScript {
private static final String WINDOWS_RESOURCE_CHECKED_PROPERTYMAP = "WindowsResourceChecked";
private DecompInterface decomplib;
ArrayList<Address> routines = new ArrayList<>(); //Holds the address of found resource routines
ArrayList<Integer> paramIndexes = new ArrayList<>(); //Holds the index of resource arguments on the stack
ArrayList<ArrayList<PcodeOp>> defUseLists = new ArrayList<>();
protected AddressSetPropertyMap alreadyDoneAddressSetPropertyMap;
public AddressSetPropertyMap getOrCreatePropertyMap(Program program, String mapName) {
if (alreadyDoneAddressSetPropertyMap != null) {
return alreadyDoneAddressSetPropertyMap;
}
alreadyDoneAddressSetPropertyMap = program.getAddressSetPropertyMap(mapName);
if (alreadyDoneAddressSetPropertyMap != null) {
return alreadyDoneAddressSetPropertyMap;
}
try {
alreadyDoneAddressSetPropertyMap = program.createAddressSetPropertyMap(mapName);
}
catch (DuplicateNameException e) {
throw new AssertException(
"Can't get DuplicateNameException since we tried to get it first");
}
return alreadyDoneAddressSetPropertyMap;
}
@Override
public void run() throws Exception {
// This code was added so that the analyzer (which calls a script) would not print script messages but if
// run as a script it would still show output in the console.
// It was also added to get the createBookmark option from the analyzer options.
// The printScriptMsgs flag is checked every time the script tries to print.
// The createBookmarks flag is checked every time the script tries to make a bookmark.
// This also allows headless scripts to print if no args are passed but if they want no messages they
// should pass the argument "false".
// This also allows headless scripts to create bookmarks if no arguments are passed but if they want no
// bookmarks they should pass the argument "false".
// These are the default values if no arguments set them.
boolean printScriptMsgs = true;
boolean createBookmarks = true;
// This gets the first argument if there are one or more arguments.
String[] scriptArgs = getScriptArgs();
if (scriptArgs.length >= 1) {
if ("false".equals(scriptArgs[0])) {
printScriptMsgs = false;
}
}
// This gets the second argument if there is one.
if (scriptArgs.length == 2) {
if ("false".equals(scriptArgs[1])) {
createBookmarks = false;
}
}
AddressSetView restrictedSet = currentSelection;
getOrCreatePropertyMap(currentProgram, WINDOWS_RESOURCE_CHECKED_PROPERTYMAP);
// If this is the whole address space, look at everything
// and ignore already done property
if (restrictedSet == null || restrictedSet.isEmpty() ||
restrictedSet.hasSameAddresses(currentProgram.getMemory())) {
restrictedSet = null;
alreadyDoneAddressSetPropertyMap.clear();
}
// If this is a partial address set, then ignore anywhere with a done it property
try {
decomplib = setUpDecompiler(currentProgram);
if (decomplib == null) {
if (printScriptMsgs) {
println("Decompile Error: " + decomplib.getLastMessage());
}
return;
}
// Hold address and lookup constant value pairs for each resource lookup
HashMap<Address, Long> constLocs;
// Set of Resource name lookups. If unknown or variable Rsrc_ name
// Rsrc_* wildcard allowed except when calling addResourceTableReferences()
constLocs = associateResource("AfxMessageBox", 1, restrictedSet, printScriptMsgs);
addResourceTableReferences(constLocs, "Rsrc_StringTable", printScriptMsgs,
createBookmarks);
constLocs = associateResource("CreateDialogParamA", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_Dialog", printScriptMsgs, createBookmarks);
constLocs = associateResource("CreateDialogParamW", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_Dialog", printScriptMsgs, createBookmarks);
constLocs = associateResource("DialogBoxParamA", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_Dialog", printScriptMsgs, createBookmarks);
constLocs = associateResource("DialogBoxParamW", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_Dialog", printScriptMsgs, createBookmarks);
constLocs = associateResource("FindResourceA", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_*", printScriptMsgs, createBookmarks);
constLocs = associateResource("FindResourceW", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_*", printScriptMsgs, createBookmarks);
constLocs = associateResource("FindResourceHandle", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_*", printScriptMsgs, createBookmarks);
constLocs = associateResource("LoadAcceleratorsA", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_Accelerator", printScriptMsgs, createBookmarks);
constLocs = associateResource("LoadAcceleratorsW", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_Accelerator", printScriptMsgs, createBookmarks);
constLocs = associateResource("LoadBitmapA", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_Bitmap", printScriptMsgs, createBookmarks);
constLocs = associateResource("LoadBitmapW", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_Bitmap", printScriptMsgs, createBookmarks);
constLocs = associateResource("LoadCursorA", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_*", printScriptMsgs, createBookmarks);
constLocs = associateResource("LoadCursorW", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_*", printScriptMsgs, createBookmarks);
constLocs = associateResource("LoadIconA", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_GroupIcon", printScriptMsgs, createBookmarks);
constLocs = associateResource("LoadIconW", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_GroupIcon", printScriptMsgs, createBookmarks);
constLocs = associateResource("LoadImageA", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_*", printScriptMsgs, createBookmarks);
constLocs = associateResource("LoadImageW", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_*", printScriptMsgs, createBookmarks);
constLocs = associateResource("RegLoadMUIStringW", 6, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_MUI", printScriptMsgs, createBookmarks);
constLocs = associateResource("LoadMenuA", 2, restrictedSet, printScriptMsgs);
addResourceTableReferences(constLocs, "Rsrc_Menu", printScriptMsgs, createBookmarks);
constLocs = associateResource("LoadMenuW", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_Menu", printScriptMsgs, createBookmarks);
constLocs = associateResource("LoadRegTypeLib", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_*", printScriptMsgs, createBookmarks);
constLocs = associateResource("LoadStringA", 2, restrictedSet, printScriptMsgs);
addResourceTableReferences(constLocs, "Rsrc_StringTable", printScriptMsgs,
createBookmarks);
constLocs = associateResource("LoadStringW", 2, restrictedSet, printScriptMsgs);
addResourceTableReferences(constLocs, "Rsrc_StringTable", printScriptMsgs,
createBookmarks);
constLocs = associateResource("LoadTypeLib", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_*", printScriptMsgs, createBookmarks);
constLocs = associateResource("LoadTypeLibEx", 2, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_*", printScriptMsgs, createBookmarks);
constLocs = associateResource("PlaySoundW", 1, restrictedSet, printScriptMsgs);
addResourceReferences(constLocs, "Rsrc_WAVE", printScriptMsgs, createBookmarks);
}
finally {
decomplib.dispose();
}
}
/**
* Associates a resource name with the name and ID of that resource
* @param resourceRoutine - Name of the resource routine
* @param paramIndex - Argument index of windows function call for resource lookup
* @param restrictedSet - Address space to use
* @param printScriptMsgs - if true, print output; if false, do not print any output;
* @return HashMap<Address, Long> map of addresses
*/
private HashMap<Address, Long> associateResource(String resourceRoutine, int paramIndex,
AddressSetView restrictedSet, boolean printScriptMsgs) {
HashMap<Address, Long> constUse = new HashMap<>();
Symbol symbol = lookupRoutine(resourceRoutine, printScriptMsgs);
if (symbol == null) {
return constUse;
}
//Continue along if a symbol was found
routines.add(symbol.getAddress());
paramIndexes.add(paramIndex);
ArrayList<PcodeOp> defUseList = new ArrayList<>();
defUseLists.add(defUseList);
HashSet<Address> doneRoutines = new HashSet<>();
//Have a list of routines found based on symbol lookups
while (routines.size() > 0) {
// get the next routine to lookup
Address addr = routines.remove(0);
paramIndex = paramIndexes.remove(0);
defUseList = defUseLists.remove(0);
if (doneRoutines.contains(addr)) {
continue;
}
doneRoutines.add(addr);
// Get the list of references to this address
ReferenceIterator referencesTo =
currentProgram.getReferenceManager().getReferencesTo(addr);
for (Reference reference : referencesTo) {
if (monitor.isCancelled()) {
break;
}
// Get the address of the function which is referenced
Address refAddr = reference.getFromAddress();
// if set is null, do no checks
if (restrictedSet != null && !restrictedSet.contains(refAddr)) {
continue;
}
// was this location already checked?
if (alreadyDoneAddressSetPropertyMap != null) {
if (alreadyDoneAddressSetPropertyMap.contains(refAddr)) {
continue;
}
alreadyDoneAddressSetPropertyMap.add(refAddr, refAddr);
}
Function refFunc =
currentProgram.getFunctionManager().getFunctionContaining(refAddr);
if (refFunc == null) {
refFunc = UndefinedFunction.findFunction(currentProgram, refAddr, monitor);
}
// this is an indirect reference, need to add the references to here.
if (refFunc == null && reference.isExternalReference()) {
routines.add(reference.getFromAddress());
paramIndexes.add(paramIndex);
defUseLists.add(new ArrayList<PcodeOp>());
continue;
}
if (refFunc == null) {
continue;
}
// decompile function
// look for call to this function
// display call
@SuppressWarnings("unchecked")
ArrayList<PcodeOp> localDefUseList = (ArrayList<PcodeOp>) defUseList.clone();
monitor.setMessage(
"Analyzing : " + refFunc.getName() + " for refs to " + resourceRoutine);
analyzeFunction(constUse, decomplib, currentProgram, refFunc, refAddr, paramIndex,
localDefUseList);
}
}
return constUse;
}
/**
* Checks to see if the current resource routine is found in the
* programs symbol table.
* @param resourceRoutine - Name of the resource routine
* @param printScriptMsgs - if true, print output; if false, do not print any output;
* @return Symbol - found symbol based on resourceRoutine
*/
private Symbol lookupRoutine(String resourceRoutine, boolean printScriptMsgs) {
Symbol foundSym = null;
// Get the symbols that match the current resource routine
SymbolIterator symbols = currentProgram.getSymbolTable().getSymbols(resourceRoutine);
while (symbols.hasNext()) {
//If a match is found get the function at the address of the found symbol
foundSym = symbols.next();
Function functionAt =
currentProgram.getFunctionManager().getFunctionAt(foundSym.getAddress());
if (functionAt != null) {
return foundSym;
}
}
if (foundSym != null && printScriptMsgs) {
println("References to the " + resourceRoutine + " routine:");
}
return foundSym;
}
/**
* Analyze a functions references.
* Populates the address/value pairs of resource address and ID
* @param constUse - resource address/value pairs
*/
public void analyzeFunction(HashMap<Address, Long> constUse, DecompInterface decompiler,
Program prog, Function f, Address refAddr, int paramIndex,
ArrayList<PcodeOp> defUseList) {
if (f == null) {
return;
}
Instruction instr = prog.getListing().getInstructionAt(refAddr);
if (instr == null) {
return;
}
decompileFunction(f, decompiler);
if (hfunction == null) {
return; // failed to decompile
}
Iterator<PcodeOpAST> ops = hfunction.getPcodeOps(refAddr);
while (ops.hasNext()) {
if (monitor.isCancelled()) {
break;
}
PcodeOpAST pcodeOpAST = ops.next();
if (pcodeOpAST.getOpcode() == PcodeOp.CALL) {
// get the second parameter
Varnode parm = pcodeOpAST.getInput(paramIndex); // 1st param is the call dest
if (parm == null) {
return;
}
// 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, defUseList);
constUse.put(instr.getAddress(), value);
}
catch (InvalidInputException exc) {
// don't worry about error
}
}
else {
followToParam(constUse, defUseList, hfunction, parm, null);
}
// if this is anything else, get the high variable to see if it can be traced back to a param
// then repeat with any calls to this function at whatever the param is
}
}
}
/**
* Decompile the function
* @param f
* @param decompiler
* @return boolean - true if successful
*/
public boolean decompileFunction(Function f, DecompInterface decompiler) {
// don't decompile the function again if it was the same as the last one
if (f.getEntryPoint().equals(lastDecompiledFuncAddr)) {
return true;
}
DecompileResults decompRes =
decompiler.decompileFunction(f, decompiler.getOptions().getDefaultTimeout(), monitor);
hfunction = decompRes.getHighFunction();
if (hfunction == null) {
return false;
}
lastDecompiledFuncAddr = f.getEntryPoint();
return true;
}
/**
* Prints out the address of a found resource along with the name of
* the resource.
* @param constLocs - Address value pairs of the resource function
* @param resourceName - name of the resource
* @param printScriptMsgs - if true, print output; if false, do not print any output;
* @param createBookmarks - if true, create bookmarks where references are found; if false, do not create any bookmarks;
* @throws CancelledException
*/
private void addResourceReferences(HashMap<Address, Long> constLocs, String resourceName,
boolean printScriptMsgs, boolean createBookmarks) throws CancelledException {
Set<Address> keys;
Iterator<Address> locIter;
keys = constLocs.keySet();
locIter = keys.iterator();
while (locIter.hasNext()) {
monitor.checkCanceled();
Address loc = locIter.next();
Instruction instr = currentProgram.getListing().getInstructionAt(loc);
long rsrcID = constLocs.get(loc);
Address rsrcAddr = findResource(resourceName + "_" + Long.toHexString(rsrcID), 0);
if (rsrcAddr != null) {
//Get the full symbol name including constant digits
String symName = getSymbolAt(rsrcAddr).getName();
//Match on the name without the constant digit values
String pattern = "([a-z]|[A-Z])*_?([a-z]|[A-Z])*(_[A-Z]+[a-z]+)?";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(symName);
//Default to resourceName argument passed in unless found better match below
String rsrcName = resourceName;
if (m.find()) {
rsrcName = m.group();
}
instr.addMnemonicReference(rsrcAddr, RefType.DATA, SourceType.ANALYSIS);
if (createBookmarks) {
currentProgram.getBookmarkManager().setBookmark(instr.getMinAddress(),
BookmarkType.ANALYSIS, "WindowsResourceReference",
"Added Resource Reference");
}
if (printScriptMsgs) {
println(" " + instr.getMinAddress().toString() + " : Found " + rsrcName +
" reference");
}
}
}
}
/**
* Prints out the address of a found resource along with the name of
* the resource.
* @param constLocs - Address value pairs of the resource function
* @param tableName - Name of the resource table
* @param printScriptMsgs - if true, print output; if false, do not print any output;
* @param createBookmarks - if true, create bookmarks where references are found; if false, do not create any bookmarks;
* @throws CancelledException
*/
private void addResourceTableReferences(HashMap<Address, Long> constLocs, String tableName,
boolean printScriptMsgs, boolean createBookmarks) throws CancelledException {
Set<Address> keys;
Iterator<Address> locIter;
//Get the set of address locations which call the resource function
keys = constLocs.keySet();
locIter = keys.iterator();
//Iterate though the set of address locations
while (locIter.hasNext()) {
monitor.checkCanceled();
Address loc = locIter.next();
Instruction instr = currentProgram.getListing().getInstructionAt(loc);
Long rsrcID = constLocs.get(loc);
Address rsrcAddr = null;
if (rsrcID != null) {
rsrcAddr = findResource(tableName, rsrcID);
}
if (rsrcAddr != null) {
instr.addMnemonicReference(rsrcAddr, RefType.DATA, SourceType.ANALYSIS);
if (createBookmarks) {
currentProgram.getBookmarkManager().setBookmark(instr.getMinAddress(),
BookmarkType.ANALYSIS, "WindowsResourceReference",
"Added Resource Table Reference");
}
if (printScriptMsgs) {
println(" " + instr.getMinAddress().toString() + " : Found " +
tableName + " table reference " + rsrcID);
}
}
}
}
/**
* Returns the address of the resource located in the program
* @param tableName - Name of the resource table
* @param rsrcID - ID of the resource to find
* @return Address of the found resource
* @throws CancelledException
*/
private Address findResource(String tableName, long rsrcID) throws CancelledException {
SymbolIterator siter =
currentProgram.getSymbolTable().getSymbolIterator(tableName + "*", true);
if (!siter.hasNext()) {
return null;
}
// Search each table
while (siter.hasNext()) {
monitor.checkCanceled();
Symbol sym = siter.next();
String symName = sym.getName();
long curRsrcID = rsrcID;
if (rsrcID != 0) {
symName = symName.replaceAll(tableName + "_", "");
//Find the specific table number of the resource
String pattern = "_+[0-9]+";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(symName);
String hexString = "";
if (m.find()) {
//Strip off the constant value to leave just the resource number
hexString = symName.replaceAll(m.group(), "");
}
curRsrcID = Integer.parseInt(hexString, 16);
curRsrcID = (curRsrcID - 1) * 0x10;
curRsrcID = rsrcID - curRsrcID;
if (curRsrcID > 0x10) {
continue; // tables have 16 entries
}
if (curRsrcID < 0) {
continue;
}
}
Address currItemAddr = sym.getAddress();
Data data = currentProgram.getListing().getDataAt(currItemAddr);
while (curRsrcID > 0) {
currItemAddr = data.getAddress();
data = currentProgram.getListing().getDataAfter(currItemAddr);
if (data == null || !data.isDefined()) {
break;
}
curRsrcID--;
}
if (data == null) {
continue;
}
if (curRsrcID == 0) {
return data.getAddress();
}
}
return null;
}
private long applyDefUseList(long value, ArrayList<PcodeOp> defUseList)
throws InvalidInputException {
if (defUseList == null || defUseList.size() <= 0) {
return value;
}
Iterator<PcodeOp> iterator = defUseList.iterator();
while (iterator.hasNext()) {
PcodeOp pcodeOp = iterator.next();
int opcode = pcodeOp.getOpcode();
switch (opcode) {
case PcodeOp.INT_AND:
if (pcodeOp.getInput(0).isConstant()) {
value = value & pcodeOp.getInput(0).getOffset();
}
else if (pcodeOp.getInput(1).isConstant()) {
value = value & pcodeOp.getInput(1).getOffset();
}
else {
throw new InvalidInputException(
" Unhandled Pcode OP " + pcodeOp.toString());
}
break;
default:
throw new InvalidInputException(" Unhandled Pcode OP " + pcodeOp.toString());
}
}
return value;
}
/**
* Finds the parameter passed into the resource function call
* @param constUse - Key value pairs of the resource function calls
* @param defUseList
* @param highFunction
* @param vnode
* @param doneSet
*/
private void followToParam(HashMap<Address, Long> constUse, ArrayList<PcodeOp> defUseList,
HighFunction highFunction, Varnode vnode, HashSet<SequenceNumber> doneSet) {
HighVariable hvar = vnode.getHigh();
if (hvar instanceof HighParam) {
Function function = highFunction.getFunction();
routines.add(function.getEntryPoint());
paramIndexes.add(((HighParam) hvar).getSlot() + 1);
defUseLists.add(defUseList);
return;
}
// follow back up through
PcodeOp def = vnode.getDef();
if (def == null) {
return;
}
// have we done this vnode source already?
Address vPCAddr = vnode.getPCAddress();
SequenceNumber seqnum = def.getSeqnum();
if (doneSet == null) {
doneSet = new HashSet<>();
}
if (seqnum != null && doneSet.contains(seqnum)) {
return;
}
doneSet.add(seqnum);
int opcode = def.getOpcode();
switch (opcode) {
case PcodeOp.COPY:
if (def.getInput(0).isConstant()) {
long value = def.getInput(0).getOffset();
try {
value = applyDefUseList(value, defUseList);
constUse.put(def.getOutput().getPCAddress(), value);
}
catch (InvalidInputException exc) {
// ignore
}
return;
}
followToParam(constUse, defUseList, highFunction, def.getInput(0), doneSet);
return;
case PcodeOp.INT_ZEXT:
followToParam(constUse, defUseList, highFunction, def.getInput(0), doneSet);
return;
case PcodeOp.MULTIEQUAL:
followToParam(constUse, defUseList, highFunction, def.getInput(0), doneSet);
@SuppressWarnings("unchecked")
ArrayList<PcodeOp> splitUseList = (ArrayList<PcodeOp>) defUseList.clone();
followToParam(constUse, splitUseList, highFunction, def.getInput(1), doneSet);
return;
case PcodeOp.CAST:
// Cast will expose more Pcode, and could be attached to the same address!
if (vPCAddr.equals(def.getInput(0).getPCAddress())) {
doneSet.remove(vPCAddr);
}
followToParam(constUse, defUseList, highFunction, def.getInput(0), doneSet);
return;
case PcodeOp.INDIRECT:
if (def.getOutput().getAddress().equals(def.getInput(0).getAddress())) {
followToParam(constUse, defUseList, highFunction, def.getInput(0), doneSet);
return;
}
break;
case PcodeOp.INT_AND:
if (def.getInput(1).isConstant()) {
defUseList.add(0, def);
followToParam(constUse, defUseList, highFunction, def.getInput(0), doneSet);
return;
}
break;
case PcodeOp.INT_ADD:
if (def.getInput(1).isConstant()) {
defUseList.add(0, def);
followToParam(constUse, defUseList, highFunction, def.getInput(0), doneSet);
return;
}
if (vnode.getHigh() instanceof HighParam) {
// don't handle non-constants for now
}
break;
}
// println(" Lost IT! " + vnode.getPCAddress());
}
@SuppressWarnings("unused")
private boolean isHexDigit(char charAt) {
if (Character.isDigit(charAt)) {
return true;
}
if ("abcdef".indexOf(charAt) >= 0) {
return true;
}
if ("ABCDEF".indexOf(charAt) >= 0) {
return true;
}
return false;
}
// Decompiler stuff
private HighFunction hfunction = null;
private Address lastDecompiledFuncAddr = null;
private DecompInterface setUpDecompiler(Program program) {
DecompInterface decompiler = 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);
}
}
decompiler.setOptions(options);
decompiler.toggleCCode(true);
decompiler.toggleSyntaxTree(true);
decompiler.setSimplificationStyle("decompile");
decompiler.openProgram(program);
return decompiler;
}
}