avoid calling GhidraScriptUtils.getScriptSourceDirectories

- when called from the GUI, the bundle host manages paths
- when used to find a script by name, use findScriptByName
This commit is contained in:
Jason P. Leasure
2020-04-28 17:23:08 -04:00
parent 2b49816c6c
commit 7ee2467016
7 changed files with 135 additions and 156 deletions
@@ -33,7 +33,8 @@ import docking.actions.KeyBindingUtils;
import docking.tool.ToolConstants; import docking.tool.ToolConstants;
import docking.widgets.table.GTable; import docking.widgets.table.GTable;
import generic.jar.ResourceFile; import generic.jar.ResourceFile;
import ghidra.app.script.*; import ghidra.app.script.GhidraScriptInfoManager;
import ghidra.app.script.ScriptInfo;
import ghidra.framework.Application; import ghidra.framework.Application;
import ghidra.framework.options.SaveState; import ghidra.framework.options.SaveState;
import ghidra.util.*; import ghidra.util.*;
@@ -79,7 +80,7 @@ class GhidraScriptActionManager {
} }
void restoreUserDefinedKeybindings(SaveState saveState) { void restoreUserDefinedKeybindings(SaveState saveState) {
List<ResourceFile> dirs = GhidraScriptUtil.getScriptSourceDirectories(); Collection<ResourceFile> dirs = provider.getBundleHost().getBundlePaths();
String[] names = saveState.getNames(); String[] names = saveState.getNames();
for (String name : names) { for (String name : names) {
@@ -790,35 +790,32 @@ public abstract class GhidraScript extends FlatProgramAPI {
*/ */
public void runScript(String scriptName, String[] scriptArguments, GhidraState scriptState) public void runScript(String scriptName, String[] scriptArguments, GhidraState scriptState)
throws Exception { throws Exception {
List<ResourceFile> dirs = GhidraScriptUtil.getScriptSourceDirectories(); ResourceFile scriptSource = GhidraScriptUtil.findScriptByName(scriptName);
for (ResourceFile dir : dirs) { if (scriptSource != null) {
ResourceFile scriptSource = new ResourceFile(dir, scriptName); GhidraScriptProvider provider = GhidraScriptUtil.getProvider(scriptSource);
if (scriptSource.exists()) {
GhidraScriptProvider provider = GhidraScriptUtil.getProvider(scriptSource);
if (provider == null) { if (provider == null) {
throw new IOException("Attempting to run subscript '" + scriptName + throw new IOException("Attempting to run subscript '" + scriptName +
"': unable to run this script type."); "': unable to run this script type.");
}
GhidraScript script = provider.getScriptInstance(scriptSource, writer);
script.setScriptArgs(scriptArguments);
if (potentialPropertiesFileLocs.size() > 0) {
script.setPotentialPropertiesFileLocations(potentialPropertiesFileLocs);
}
if (scriptState == state) {
updateStateFromVariables();
}
script.execute(scriptState, monitor, writer);
if (scriptState == state) {
loadVariablesFromState();
}
return;
} }
GhidraScript script = provider.getScriptInstance(scriptSource, writer);
script.setScriptArgs(scriptArguments);
if (potentialPropertiesFileLocs.size() > 0) {
script.setPotentialPropertiesFileLocations(potentialPropertiesFileLocs);
}
if (scriptState == state) {
updateStateFromVariables();
}
script.execute(scriptState, monitor, writer);
if (scriptState == state) {
loadVariablesFromState();
}
return;
} }
boolean shouldContinue = false; boolean shouldContinue = false;
@@ -129,13 +129,10 @@ public class GhidraScriptRunner implements GhidraLaunchable {
if (scriptSource.exists()) { if (scriptSource.exists()) {
return scriptSource; return scriptSource;
} }
List<ResourceFile> dirs = GhidraScriptUtil.getScriptSourceDirectories();
for (ResourceFile dir : dirs) {
scriptSource = new ResourceFile(dir, scriptName);
if (scriptSource.exists()) { scriptSource = GhidraScriptUtil.findScriptByName(scriptName);
return scriptSource; if (scriptSource != null) {
} return scriptSource;
} }
throw new IllegalArgumentException("Script not found: " + scriptName); throw new IllegalArgumentException("Script not found: " + scriptName);
} }
@@ -676,12 +676,9 @@ public class HeadlessAnalyzer {
if (scriptSource.exists()) { if (scriptSource.exists()) {
return scriptSource; return scriptSource;
} }
List<ResourceFile> dirs = GhidraScriptUtil.getScriptSourceDirectories(); scriptSource = GhidraScriptUtil.findScriptByName(scriptName);
for (ResourceFile dir : dirs) { if (scriptSource != null) {
scriptSource = new ResourceFile(dir, scriptName); return scriptSource;
if (scriptSource.exists()) {
return scriptSource;
}
} }
throw new IllegalArgumentException("Script not found: " + scriptName); throw new IllegalArgumentException("Script not found: " + scriptName);
} }
@@ -16,7 +16,6 @@
package ghidra.app.util.headless; package ghidra.app.util.headless;
import java.io.IOException; import java.io.IOException;
import java.util.List;
import generic.jar.ResourceFile; import generic.jar.ResourceFile;
import ghidra.app.script.*; import ghidra.app.script.*;
@@ -338,8 +337,8 @@ public abstract class HeadlessScript extends GhidraScript {
* @throws IOException if there are issues creating the folder * @throws IOException if there are issues creating the folder
* @throws InvalidNameException if folder name is invalid * @throws InvalidNameException if folder name is invalid
*/ */
public void setHeadlessImportDirectory(String importDir) throws ImproperUseException, public void setHeadlessImportDirectory(String importDir)
IOException, InvalidNameException { throws ImproperUseException, IOException, InvalidNameException {
checkHeadlessStatus(); checkHeadlessStatus();
// Do nothing if not importing -- we don't want to have arbitrary folders // Do nothing if not importing -- we don't want to have arbitrary folders
@@ -397,57 +396,52 @@ public abstract class HeadlessScript extends GhidraScript {
resolveContinuationOptionWith(scriptSetOption); resolveContinuationOptionWith(scriptSetOption);
scriptSetOption = null; scriptSetOption = null;
} }
ResourceFile scriptSource = GhidraScriptUtil.findScriptByName(scriptName);
if (scriptSource != null) {
GhidraScriptProvider provider = GhidraScriptUtil.getProvider(scriptSource);
List<ResourceFile> dirs = GhidraScriptUtil.getScriptSourceDirectories(); if (provider == null) {
for (ResourceFile dir : dirs) { throw new IOException("Attempting to run subscript '" + scriptName +
ResourceFile scriptSource = new ResourceFile(dir, scriptName); "': unable to run this script type.");
if (scriptSource.exists()) {
GhidraScriptProvider provider = GhidraScriptUtil.getProvider(scriptSource);
if (provider == null) {
throw new IOException("Attempting to run subscript '" + scriptName +
"': unable to run this script type.");
}
GhidraScript script = provider.getScriptInstance(scriptSource, writer);
isHeadlessScript = script instanceof HeadlessScript ? true : false;
if (potentialPropertiesFileLocs.size() > 0) {
script.setPotentialPropertiesFileLocations(potentialPropertiesFileLocs);
}
if (scriptState == state) {
updateStateFromVariables();
}
if (isHeadlessScript) {
((HeadlessScript) script).setHeadlessInstance(headless);
((HeadlessScript) script).setRunningInnerScript(true);
}
script.setScriptArgs(scriptArguments);
script.execute(scriptState, monitor, writer);
if (scriptState == state) {
loadVariablesFromState();
}
// Resolve continuations options, if they have changed
if (isHeadlessScript) {
HeadlessContinuationOption innerScriptOpt =
((HeadlessScript) script).getHeadlessContinuationOption();
if (innerScriptOpt != null) {
resolveContinuationOptionWith(innerScriptOpt);
}
((HeadlessScript) script).setRunningInnerScript(false);
}
return;
} }
GhidraScript script = provider.getScriptInstance(scriptSource, writer);
isHeadlessScript = script instanceof HeadlessScript ? true : false;
if (potentialPropertiesFileLocs.size() > 0) {
script.setPotentialPropertiesFileLocations(potentialPropertiesFileLocs);
}
if (scriptState == state) {
updateStateFromVariables();
}
if (isHeadlessScript) {
((HeadlessScript) script).setHeadlessInstance(headless);
((HeadlessScript) script).setRunningInnerScript(true);
}
script.setScriptArgs(scriptArguments);
script.execute(scriptState, monitor, writer);
if (scriptState == state) {
loadVariablesFromState();
}
// Resolve continuations options, if they have changed
if (isHeadlessScript) {
HeadlessContinuationOption innerScriptOpt =
((HeadlessScript) script).getHeadlessContinuationOption();
if (innerScriptOpt != null) {
resolveContinuationOptionWith(innerScriptOpt);
}
((HeadlessScript) script).setRunningInnerScript(false);
}
return;
} }
throw new IllegalArgumentException("Script does not exist: " + scriptName); throw new IllegalArgumentException("Script does not exist: " + scriptName);
@@ -113,8 +113,8 @@ public class ShowConstantUse extends GhidraScript {
for (int i = 0; i < clangStmt.numChildren(); i++) { for (int i = 0; i < clangStmt.numChildren(); i++) {
ClangNode child = clangStmt.Child(i); ClangNode child = clangStmt.Child(i);
if (child.equals(clangVar)) { if (child.equals(clangVar)) {
constLocs = constLocs = backtrackParamToConstant(f, paramIndex,
backtrackParamToConstant(f, paramIndex, tableDialog); tableDialog);
break; break;
} }
if (child instanceof ClangVariableToken) { if (child instanceof ClangVariableToken) {
@@ -254,9 +254,8 @@ public class ShowConstantUse extends GhidraScript {
@Override @Override
public String getColumnValue(AddressableRowObject rowObject) { public String getColumnValue(AddressableRowObject rowObject) {
ConstUseLocation entry = (ConstUseLocation) rowObject; ConstUseLocation entry = (ConstUseLocation) rowObject;
Function func = Function func = entry.getProgram().getFunctionManager().getFunctionContaining(
entry.getProgram().getFunctionManager().getFunctionContaining( entry.getAddress());
entry.getAddress());
if (func == null) { if (func == null) {
return ""; return "";
} }
@@ -336,20 +335,15 @@ public class ShowConstantUse extends GhidraScript {
} }
public void runScript(String name, Program prog, Address loc) { public void runScript(String name, Program prog, Address loc) {
GhidraState scriptState = GhidraState scriptState = new GhidraState(state.getTool(), state.getProject(), prog,
new GhidraState(state.getTool(), state.getProject(), prog, new ProgramLocation( new ProgramLocation(prog, loc), null, null);
prog, loc), null, null);
try { try {
List<ResourceFile> dirs = GhidraScriptUtil.getScriptSourceDirectories(); ResourceFile scriptSource = GhidraScriptUtil.findScriptByName(name);
for (ResourceFile dir : dirs) { if (scriptSource != null) {
ResourceFile scriptSource = new ResourceFile(dir, name); GhidraScriptProvider provider = GhidraScriptUtil.getProvider(scriptSource);
if (scriptSource.exists()) { GhidraScript script = provider.getScriptInstance(scriptSource, writer);
GhidraScriptProvider provider = script.execute(scriptState, monitor, writer);
GhidraScriptUtil.getProvider(scriptSource); return;
GhidraScript script = provider.getScriptInstance(scriptSource, writer);
script.execute(scriptState, monitor, writer);
return;
}
} }
} }
catch (Exception exc) { catch (Exception exc) {
@@ -615,7 +609,8 @@ public class ShowConstantUse extends GhidraScript {
Varnode pvnode = null; Varnode pvnode = null;
Parameter parm = f.getParameter(paramIndex); Parameter parm = f.getParameter(paramIndex);
if (parm == null) { if (parm == null) {
this.popup("Please put the cursor on a function parameter variable\nIf the function has not had it's parameters identified\nplease do so and try again"); this.popup(
"Please put the cursor on a function parameter variable\nIf the function has not had it's parameters identified\nplease do so and try again");
return constUse; return constUse;
} }
@@ -672,9 +667,8 @@ public class ShowConstantUse extends GhidraScript {
if (refFunc == null) { if (refFunc == null) {
localConstUse.put(refAddr, null); localConstUse.put(refAddr, null);
String problem = String problem = "*** No function at " + refAddr +
"*** No function at " + refAddr + ".\nCould not analyze constant use past this undefined function!";
".\nCould not analyze constant use past this undefined function!";
addConstantProblem(tableChooserDialog, refAddr, problem); addConstantProblem(tableChooserDialog, refAddr, problem);
refFunc = UndefinedFunction.findFunction(currentProgram, refAddr, monitor); refFunc = UndefinedFunction.findFunction(currentProgram, refAddr, monitor);
} }
@@ -736,11 +730,10 @@ public class ShowConstantUse extends GhidraScript {
// call dest // call dest
if (parm == null) { if (parm == null) {
constUse.put(instr.getAddress(), null); constUse.put(instr.getAddress(), null);
String problem = String problem = " *** Warning, it appears that function '" +
" *** Warning, it appears that function '" + funcVarUse.getName() + funcVarUse.getName() + "' at " + funcVarUse.getAddress() +
"' at " + funcVarUse.getAddress() + " does not have it's parameters recovered!\n" +
" does not have it's parameters recovered!\n" + " Use Commit Params/Return in the decompiler on this function.";
" Use Commit Params/Return in the decompiler on this function.";
addErrorNote(instr.getAddress(), problem); addErrorNote(instr.getAddress(), problem);
break; break;
} }
@@ -805,7 +798,8 @@ public class ShowConstantUse extends GhidraScript {
value = value & pcodeOp.getInput(1).getOffset(); value = value & pcodeOp.getInput(1).getOffset();
} }
else { else {
throw new InvalidInputException(" Unhandled Pcode OP " + pcodeOp.toString()); throw new InvalidInputException(
" Unhandled Pcode OP " + pcodeOp.toString());
} }
break; break;
default: default:
@@ -855,7 +849,8 @@ public class ShowConstantUse extends GhidraScript {
long value = def.getInput(0).getOffset(); long value = def.getInput(0).getOffset();
try { try {
value = applyDefUseList(value, defUseList); value = applyDefUseList(value, defUseList);
constUse.put(remapAddress(funcEntry, def.getOutput().getPCAddress()), value); constUse.put(remapAddress(funcEntry, def.getOutput().getPCAddress()),
value);
println(" " + function.getName() + " " + println(" " + function.getName() + " " +
def.getOutput().getPCAddress() + " : 0x" + Long.toHexString(value)); def.getOutput().getPCAddress() + " : 0x" + Long.toHexString(value));
} }
@@ -954,7 +949,7 @@ public class ShowConstantUse extends GhidraScript {
break; break;
case PcodeOp.PTRSUB: // Pointer + some sub element access (usually a case PcodeOp.PTRSUB: // Pointer + some sub element access (usually a
// structure ref) // structure ref)
Varnode offsetVal = def.getInput(1); Varnode offsetVal = def.getInput(1);
if (!offsetVal.isConstant()) { if (!offsetVal.isConstant()) {
break; break;
@@ -965,7 +960,8 @@ public class ShowConstantUse extends GhidraScript {
long value = baseVal.getOffset() + offsetVal.getOffset(); long value = baseVal.getOffset() + offsetVal.getOffset();
try { try {
value = applyDefUseList(value, defUseList); value = applyDefUseList(value, defUseList);
constUse.put(remapAddress(funcEntry, def.getOutput().getPCAddress()), value); constUse.put(remapAddress(funcEntry, def.getOutput().getPCAddress()),
value);
println(" " + function.getName() + " " + println(" " + function.getName() + " " +
def.getOutput().getPCAddress() + " : 0x" + Long.toHexString(value)); def.getOutput().getPCAddress() + " : 0x" + Long.toHexString(value));
} }
@@ -997,8 +993,9 @@ public class ShowConstantUse extends GhidraScript {
// println(" Lost IT! " + vnode.getPCAddress()); // println(" Lost IT! " + vnode.getPCAddress());
} }
private void followThroughGlobal(HashMap<Address, Long> constUse, private void followThroughGlobal(HashMap<Address, Long> constUse, ArrayList<PcodeOp> defUseList,
ArrayList<PcodeOp> defUseList, HighVariable hvar, ArrayList<FunctionParamUse> funcList, HighVariable hvar,
ArrayList<FunctionParamUse> funcList,
HashSet<SequenceNumber> doneSet) { HashSet<SequenceNumber> doneSet) {
Address loc = hvar.getRepresentative().getAddress(); Address loc = hvar.getRepresentative().getAddress();
PcodeOp def = hvar.getRepresentative().getDef(); PcodeOp def = hvar.getRepresentative().getDef();
@@ -1068,9 +1065,8 @@ public class ShowConstantUse extends GhidraScript {
// don't decompile the function again if it was the same as the last one // don't decompile the function again if it was the same as the last one
// //
if (!f.getEntryPoint().equals(lastDecompiledFuncAddr)) { if (!f.getEntryPoint().equals(lastDecompiledFuncAddr)) {
lastResults = lastResults = decompInterface.decompileFunction(f,
decompInterface.decompileFunction(f, decompInterface.getOptions().getDefaultTimeout(), monitor);
decompInterface.getOptions().getDefaultTimeout(), monitor);
} }
hfunction = lastResults.getHighFunction(); hfunction = lastResults.getHighFunction();
@@ -59,34 +59,31 @@ public class PythonScript extends GhidraScript {
throw new AssertException("Could not get Ghidra Python interpreter!"); throw new AssertException("Could not get Ghidra Python interpreter!");
} }
} }
ResourceFile scriptSource = GhidraScriptUtil.findScriptByName(scriptName);
for (ResourceFile dir : GhidraScriptUtil.getScriptSourceDirectories()) { if (scriptSource != null) {
ResourceFile scriptSource = new ResourceFile(dir, scriptName); GhidraScriptProvider provider = GhidraScriptUtil.getProvider(scriptSource);
if (scriptSource.exists()) { GhidraScript ghidraScript = provider.getScriptInstance(scriptSource, writer);
GhidraScriptProvider provider = GhidraScriptUtil.getProvider(scriptSource); if (ghidraScript == null) {
GhidraScript ghidraScript = provider.getScriptInstance(scriptSource, writer); throw new IllegalArgumentException("Script does not exist: " + scriptName);
if (ghidraScript == null) {
throw new IllegalArgumentException("Script does not exist: " + scriptName);
}
if (scriptState == state) {
updateStateFromVariables();
}
if (ghidraScript instanceof PythonScript) {
ghidraScript.set(scriptState, monitor, writer);
PythonScript pythonScript = (PythonScript) ghidraScript;
interpreter.execFile(pythonScript.getSourceFile(), pythonScript);
}
else {
ghidraScript.execute(scriptState, monitor, writer);
}
if (scriptState == state) {
loadVariablesFromState();
}
return;
} }
if (scriptState == state) {
updateStateFromVariables();
}
if (ghidraScript instanceof PythonScript) {
ghidraScript.set(scriptState, monitor, writer);
PythonScript pythonScript = (PythonScript) ghidraScript;
interpreter.execFile(pythonScript.getSourceFile(), pythonScript);
}
else {
ghidraScript.execute(scriptState, monitor, writer);
}
if (scriptState == state) {
loadVariablesFromState();
}
return;
} }
throw new IllegalArgumentException("Script does not exist: " + scriptName); throw new IllegalArgumentException("Script does not exist: " + scriptName);
} }