Merge remote-tracking branch 'origin/Ghidra_11.1'

This commit is contained in:
Ryan Kurtz 2024-05-28 13:44:30 -04:00
commit db608a1a13
23 changed files with 474 additions and 48 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

View file

@ -20,6 +20,7 @@ import java.io.IOException;
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.*;
@ -42,6 +43,7 @@ import ghidra.debug.api.modules.ModuleMapProposal.ModuleMapEntry;
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;
@ -263,6 +265,54 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
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
*
@ -277,15 +327,13 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
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());
@ -297,11 +345,8 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
}
}
}
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;
}

View file

@ -18,6 +18,8 @@ package ghidra.app.plugin.core.debug.gui.tracermi.launcher;
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;
@ -28,6 +30,8 @@ import generic.theme.Gui;
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;
@ -79,13 +83,11 @@ public abstract class ScriptAttributesParser {
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;
@ -106,13 +108,20 @@ public abstract class ScriptAttributesParser {
}
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));
@ -179,6 +188,42 @@ public abstract class ScriptAttributesParser {
}
};
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());
}

View file

@ -150,15 +150,23 @@ public class TraceRmiLauncherServicePlugin extends Plugin
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;