Skip to content

Commit

Permalink
GP-4609: Add FileChoosers to launcher dialog.
Browse files Browse the repository at this point in the history
  • Loading branch information
nsadeveloper789 committed May 28, 2024
1 parent 2210345 commit fb4807e
Show file tree
Hide file tree
Showing 23 changed files with 474 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
::@menu-group local
::@icon icon.debugger
::@help TraceRmiLauncherServicePlugin#dbgeng
::@env OPT_PYTHON_EXE:str="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH."
::@env OPT_PYTHON_EXE:file="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH."
:: Use env instead of args, because "all args except first" is terrible to implement in batch
::@env OPT_TARGET_IMG:str="" "Image" "The target binary executable image"
::@env OPT_TARGET_IMG:file="" "Image" "The target binary executable image"
::@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
::@env OPT_USE_DBGMODEL:bool=true "Use dbgmodel" "Load and use dbgmodel.dll if it is available."
::@env WINDBG_DIR:str="" "Path to dbgeng.dll directory" "Path containing dbgeng and associated DLLS (if not Windows Kits)."
::@env WINDBG_DIR:dir="" "Path to dbgeng.dll directory" "Path containing dbgeng and associated DLLS (if not Windows Kits)."

@echo off

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
::@menu-group local
::@icon icon.debugger
::@help TraceRmiLauncherServicePlugin#dbgeng_ttd
::@env OPT_PYTHON_EXE:str="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH."
::@env OPT_PYTHON_EXE:file="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH."
:: Use env instead of args, because "all args except first" is terrible to implement in batch
::@env OPT_TARGET_IMG:str="" "Trace (.run)" "A trace associated with the target binary executable"
::@env OPT_TARGET_IMG:file="" "Trace (.run)" "A trace associated with the target binary executable"
::@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
::@env OPT_USE_DBGMODEL:bool=true "Use dbgmodel" "Load and use dbgmodel.dll if it is available."
::@env OPT_DBGMODEL_PATH:str="" "Path to dbgeng.dll & \\ttd" "Path containing dbgeng and associated DLLS (if not Windows Kits)."
::@env OPT_DBGMODEL_PATH:dir="" "Path to dbgeng.dll & \\ttd" "Path containing dbgeng and associated DLLS (if not Windows Kits)."

@echo off

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
#@icon icon.debugger
#@help TraceRmiLauncherServicePlugin#gdb
#@enum StartCmd:str run start starti
#@arg :str "Image" "The target binary executable image"
#@arg :file "Image" "The target binary executable image"
#@args "Arguments" "Command-line arguments to pass to the target"
#@env OPT_GDB_PATH:str="gdb" "gdb command" "The path to gdb. Omit the full path to resolve using the system PATH."
#@env OPT_GDB_PATH:file="gdb" "gdb command" "The path to gdb. Omit the full path to resolve using the system PATH."
#@env OPT_START_CMD:StartCmd="starti" "Run command" "The gdb command to actually run the target."
#@env OPT_EXTRA_TTY:bool=false "Inferior TTY" "Provide a separate terminal emulator for the target."
#@tty TTY_TARGET if env:OPT_EXTRA_TTY
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@
#@menu-group cross
#@icon icon.debugger
#@help TraceRmiLauncherServicePlugin#gdb_qemu
#@arg :str "Image" "The target binary executable image"
#@arg :file "Image" "The target binary executable image"
#@args "Arguments" "Command-line arguments to pass to the target"
#@env GHIDRA_LANG_EXTTOOL_qemu:str="" "QEMU command" "The path to qemu for the target architecture."
#@env GHIDRA_LANG_EXTTOOL_qemu:file="" "QEMU command" "The path to qemu for the target architecture."
#@env QEMU_GDB:int=12345 "QEMU Port" "Port for gdb connection to qemu"
#@env OPT_EXTRA_QEMU_ARGS:str="" "Extra qemu arguments" "Extra arguments to pass to qemu. Use with care."
#@env OPT_GDB_PATH:str="gdb-multiarch" "gdb command" "The path to gdb. Omit the full path to resolve using the system PATH."
#@env OPT_GDB_PATH:file="gdb-multiarch" "gdb command" "The path to gdb. Omit the full path to resolve using the system PATH."
#@env OPT_EXTRA_TTY:bool=false "QEMU TTY" "Provide a separate terminal emulator for the target."
#@tty TTY_TARGET if env:OPT_EXTRA_TTY

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#@menu-group raw
#@icon icon.debugger
#@help TraceRmiLauncherServicePlugin#gdb_raw
#@env OPT_GDB_PATH:str="gdb" "gdb command" "The path to gdb. Omit the full path to resolve using the system PATH."
#@env OPT_GDB_PATH:file="gdb" "gdb command" "The path to gdb. Omit the full path to resolve using the system PATH."
#@env OPT_ARCH:str="i386:x86-64" "Architecture" "Target architecture"

if [ -d ${GHIDRA_HOME}/ghidra/.git ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#@env OPT_HOST:str="localhost" "Host" "The hostname of the target"
#@env OPT_PORT:str="9999" "Port" "The host's listening port"
#@env OPT_ARCH:str="" "Architecture (optional)" "Target architecture override"
#@env OPT_GDB_PATH:str="gdb" "gdb command" "The path to gdb on the local system. Omit the full path to resolve using the system PATH."
#@env OPT_GDB_PATH:file="gdb" "gdb command" "The path to gdb on the local system. Omit the full path to resolve using the system PATH."

if [ -d ${GHIDRA_HOME}/ghidra/.git ]
then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#@env OPT_REMOTE_PORT:int=12345 "Remote Trace RMI Port" "A free port on the remote end to receive and forward the Trace RMI connection."
#@env OPT_EXTRA_SSH_ARGS:str="" "Extra ssh arguments" "Extra arguments to pass to ssh. Use with care."
#@env OPT_GDB_PATH:str="gdb" "gdb command" "The path to gdb on the remote system. Omit the full path to resolve using the system PATH."
#@env OPT_START_CMD:StartCmd="start" "Run command" "The gdb command to actually run the target."
#@env OPT_START_CMD:StartCmd="starti" "Run command" "The gdb command to actually run the target."

target_image="$1"
shift
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
#@env OPT_EXTRA_SSH_ARGS:str="" "Extra ssh arguments" "Extra arguments to pass to ssh. Use with care."
#@env OPT_GDBSERVER_PATH:str="gdbserver" "gdbserver command (remote)" "The path to gdbserver on the remote system. Omit the full path to resolve using the system PATH."
#@env OPT_EXTRA_GDBSERVER_ARGS:str="" "Extra gdbserver arguments" "Extra arguments to pass to gdbserver. Use with care."
#@env OPT_GDB_PATH:str="gdb" "gdb command" "The path to gdb on the local system. Omit the full path to resolve using the system PATH."
#@env OPT_GDB_PATH:file="gdb" "gdb command" "The path to gdb on the local system. Omit the full path to resolve using the system PATH."

if [ -d ${GHIDRA_HOME}/ghidra/.git ]
then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
#@menu-group cross
#@icon icon.debugger
#@help TraceRmiLauncherServicePlugin#gdb_wine
#@arg :str "Image" "The target binary executable image"
#@arg :file "Image" "The target binary executable image"
#@args "Arguments" "Command-line arguments to pass to the target"
#@env OPT_WINE_PATH:str="/usr/lib/wine/wine64" "Path to wine binary" "The path to the wine executable for your target architecture."
#@env OPT_GDB_PATH:str="gdb" "gdb command" "The path to gdb. Omit the full path to resolve using the system PATH."
#@env OPT_WINE_PATH:file="/usr/lib/wine/wine64" "Path to wine binary" "The path to the wine executable for your target architecture."
#@env OPT_GDB_PATH:file="gdb" "gdb command" "The path to gdb. Omit the full path to resolve using the system PATH."
#@env OPT_EXTRA_TTY:bool=false "Inferior TTY" "Provide a separate terminal emulator for the target."
#@tty TTY_TARGET if env:OPT_EXTRA_TTY

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
#@icon icon.debugger
#@help TraceRmiLauncherServicePlugin#lldb
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
#@arg :str "Image" "The target binary executable image"
#@arg :file "Image" "The target binary executable image"
#@args "Arguments" "Command-line arguments to pass to the target"
#@env OPT_LLDB_PATH:str="lldb" "lldb command" "The path to lldb. Omit the full path to resolve using the system PATH."
#@env OPT_LLDB_PATH:file="lldb" "lldb command" "The path to lldb. Omit the full path to resolve using the system PATH."
#@env OPT_START_CMD:StartCmd="process launch" "Run command" "The lldb command to actually run the target."
#@env OPT_EXTRA_TTY:bool=false "Target TTY" "Provide a separate terminal emulator for the target."
#@tty TTY_TARGET if env:OPT_EXTRA_TTY
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#@env OPT_HOST:str="localhost" "Host" "The hostname of the target"
#@env OPT_PORT:str="9999" "Port" "The host's listening port"
#@env OPT_ARCH:str="" "Architecture" "Target architecture override"
#@env OPT_LLDB_PATH:str="lldb" "lldb command" "The path to lldb on the local system. Omit the full path to resolve using the system PATH."
#@env OPT_LLDB_PATH:file="lldb" "lldb command" "The path to lldb on the local system. Omit the full path to resolve using the system PATH."

if [ -d ${GHIDRA_HOME}/ghidra/.git ]
then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#@menu-group raw
#@icon icon.debugger
#@help TraceRmiLauncherServicePlugin#python_raw
#@env OPT_PYTHON_EXE:str="python" "python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH."
#@env OPT_PYTHON_EXE:file="python" "python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH."
#@env OPT_LANG:str="DATA:LE:64:default" "Ghidra Language" "The Ghidra LanguageID for the trace"
#@env OPT_COMP:str="pointer64" "Ghidra Compiler" "The Ghidra CompilerSpecID for the trace"

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.charset.Charset;
import java.nio.file.Paths;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.*;
Expand All @@ -42,6 +43,7 @@
import ghidra.debug.api.tracermi.*;
import ghidra.framework.options.SaveState;
import ghidra.framework.plugintool.AutoConfigState.ConfigStateField;
import ghidra.framework.plugintool.AutoConfigState.PathIsFile;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.InstructionIterator;
Expand Down Expand Up @@ -263,6 +265,54 @@ protected void saveLauncherArgs(Map<String, ?> args,
saveState(saveLauncherArgsToState(args, params));
}

interface ImageParamSetter {
@SuppressWarnings("unchecked")
static ImageParamSetter get(ParameterDescription<?> param) {
if (param.type == String.class) {
return new StringImageParamSetter((ParameterDescription<String>) param);
}
if (param.type == PathIsFile.class) {
return new FileImageParamSetter((ParameterDescription<PathIsFile>) param);
}
Msg.warn(ImageParamSetter.class,
"'Image' parameter has unsupported type: " + param.type);
return null;
}

void setImage(Map<String, Object> map, Program program);
}

static class StringImageParamSetter implements ImageParamSetter {
private final ParameterDescription<String> param;

public StringImageParamSetter(ParameterDescription<String> param) {
this.param = param;
}

@Override
public void setImage(Map<String, Object> map, Program program) {
// str-type Image is a hint that the launcher is remote
String value = TraceRmiLauncherServicePlugin.getProgramPath(program, false);
param.set(map, value);
}
}

static class FileImageParamSetter implements ImageParamSetter {
private final ParameterDescription<PathIsFile> param;

public FileImageParamSetter(ParameterDescription<PathIsFile> param) {
this.param = param;
}

@Override
public void setImage(Map<String, Object> map, Program program) {
// file-type Image is a hint that the launcher is local
String str = TraceRmiLauncherServicePlugin.getProgramPath(program, true);
PathIsFile value = str == null ? null : new PathIsFile(Paths.get(str));
param.set(map, value);
}
}

/**
* Generate the default launcher arguments
*
Expand All @@ -277,15 +327,13 @@ protected void saveLauncherArgs(Map<String, ?> args,
protected Map<String, ?> generateDefaultLauncherArgs(
Map<String, ParameterDescription<?>> params) {
Map<String, Object> map = new LinkedHashMap<String, Object>();
ParameterDescription<String> paramImage = null;
ImageParamSetter imageSetter = null;
for (Entry<String, ParameterDescription<?>> entry : params.entrySet()) {
ParameterDescription<?> param = entry.getValue();
map.put(entry.getKey(), param.defaultValue);
if (PARAM_DISPLAY_IMAGE.equals(param.display)) {
if (param.type != String.class) {
Msg.warn(this, "'Image' parameter has unexpected type: " + paramImage.type);
}
paramImage = (ParameterDescription<String>) param;
imageSetter = ImageParamSetter.get(param);
// May still be null if type is not supported
}
else if (param.name.startsWith(PREFIX_PARAM_EXTTOOL)) {
String tool = param.name.substring(PREFIX_PARAM_EXTTOOL.length());
Expand All @@ -297,11 +345,8 @@ else if (param.name.startsWith(PREFIX_PARAM_EXTTOOL)) {
}
}
}
if (paramImage != null && program != null) {
File imageFile = TraceRmiLauncherServicePlugin.getProgramPath(program);
if (imageFile != null) {
paramImage.set(map, imageFile.getAbsolutePath());
}
if (imageSetter != null && program != null) {
imageSetter.setImage(map, program);
}
return map;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import java.io.*;
import java.math.BigInteger;
import java.net.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.Map.Entry;

Expand All @@ -28,6 +30,8 @@
import ghidra.dbg.target.TargetMethod.ParameterDescription;
import ghidra.dbg.util.ShellUtils;
import ghidra.framework.Application;
import ghidra.framework.plugintool.AutoConfigState.PathIsDir;
import ghidra.framework.plugintool.AutoConfigState.PathIsFile;
import ghidra.util.HelpLocation;
import ghidra.util.Msg;

Expand Down Expand Up @@ -79,13 +83,11 @@ public String toString() {
protected interface OptType<T> {
static OptType<?> parse(Location loc, String typeName,
Map<String, UserType<?>> userEnums) {
OptType<?> type = switch (typeName) {
case "str" -> BaseType.STRING;
case "int" -> BaseType.INT;
case "bool" -> BaseType.BOOL;
default -> userEnums.get(typeName);
};
OptType<?> type = BaseType.parseNoErr(typeName);
if (type == null) {
type = userEnums.get(typeName);
}
if (type == null) { // still
Msg.error(ScriptAttributesParser.class,
"%s: Invalid type %s".formatted(loc, typeName));
return null;
Expand All @@ -106,13 +108,20 @@ ParameterDescription<T> createParameter(String name, T defaultValue, String disp
}

protected interface BaseType<T> extends OptType<T> {
public static BaseType<?> parse(Location loc, String typeName) {
BaseType<?> type = switch (typeName) {
public static BaseType<?> parseNoErr(String typeName) {
return switch (typeName) {
case "str" -> BaseType.STRING;
case "int" -> BaseType.INT;
case "bool" -> BaseType.BOOL;
case "path" -> BaseType.PATH;
case "dir" -> BaseType.DIR;
case "file" -> BaseType.FILE;
default -> null;
};
}

public static BaseType<?> parse(Location loc, String typeName) {
BaseType<?> type = parseNoErr(typeName);
if (type == null) {
Msg.error(ScriptAttributesParser.class,
"%s: Invalid base type %s".formatted(loc, typeName));
Expand Down Expand Up @@ -179,6 +188,42 @@ public Boolean decode(Location loc, String str) {
}
};

public static final BaseType<Path> PATH = new BaseType<>() {
@Override
public Class<Path> cls() {
return Path.class;
}

@Override
public Path decode(Location loc, String str) {
return Paths.get(str);
}
};

public static final BaseType<PathIsDir> DIR = new BaseType<>() {
@Override
public Class<PathIsDir> cls() {
return PathIsDir.class;
}

@Override
public PathIsDir decode(Location loc, String str) {
return new PathIsDir(Paths.get(str));
}
};

public static final BaseType<PathIsFile> FILE = new BaseType<>() {
@Override
public Class<PathIsFile> cls() {
return PathIsFile.class;
}

@Override
public PathIsFile decode(Location loc, String str) {
return new PathIsFile(Paths.get(str));
}
};

default UserType<T> withCastChoices(List<?> choices) {
return new UserType<>(this, choices.stream().map(cls()::cast).toList());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,15 +150,23 @@ public static String extractFirstFsrl(Program program) {
return first.getPath();
}

public static File getProgramPath(Program program) {
public static String getProgramPath(Program program, boolean isLocal) {
if (program == null) {
return null;
}
File exec = tryProgramPath(program.getExecutablePath());
if (exec != null) {
return exec;
return exec.getAbsolutePath();
}
return tryProgramPath(extractFirstFsrl(program));
String first = extractFirstFsrl(program);
if (!isLocal) {
return first;
}
exec = tryProgramPath(first);
if (exec != null) {
return exec.getAbsolutePath();
}
return null;
}

protected final ToolOptions options;
Expand Down
Loading

0 comments on commit fb4807e

Please sign in to comment.