mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
GP-3846: fix for stripped quotes in dbgmodel args
GP-3846: fix for stripped quotes in dbgeng args
This commit is contained in:
parent
8cfd98f933
commit
3d69cf1ae9
5 changed files with 98 additions and 37 deletions
|
@ -372,8 +372,6 @@ public interface DbgManager extends AutoCloseable, DbgBreakpointInsertions {
|
||||||
*/
|
*/
|
||||||
CompletableFuture<Void> deleteBreakpoints(long... numbers);
|
CompletableFuture<Void> deleteBreakpoints(long... numbers);
|
||||||
|
|
||||||
CompletableFuture<?> launch(List<String> args);
|
|
||||||
|
|
||||||
CompletableFuture<Void> launch(Map<String, ?> args);
|
CompletableFuture<Void> launch(Map<String, ?> args);
|
||||||
|
|
||||||
/********** NEEDED FOR TESTING ************/
|
/********** NEEDED FOR TESTING ************/
|
||||||
|
|
|
@ -15,14 +15,17 @@
|
||||||
*/
|
*/
|
||||||
package agent.dbgeng.manager.cmd;
|
package agent.dbgeng.manager.cmd;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import agent.dbgeng.dbgeng.DebugClient;
|
||||||
import java.util.List;
|
import agent.dbgeng.dbgeng.DebugClient.DebugCreateFlags;
|
||||||
|
import agent.dbgeng.dbgeng.DebugClient.DebugEngCreateFlags;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import agent.dbgeng.dbgeng.DebugClient.DebugVerifierFlags;
|
||||||
|
import agent.dbgeng.dbgeng.DebugProcessInfo;
|
||||||
import agent.dbgeng.dbgeng.*;
|
import agent.dbgeng.dbgeng.DebugSystemObjects;
|
||||||
import agent.dbgeng.dbgeng.DebugClient.*;
|
import agent.dbgeng.dbgeng.DebugThreadId;
|
||||||
import agent.dbgeng.manager.*;
|
import agent.dbgeng.dbgeng.DebugThreadInfo;
|
||||||
|
import agent.dbgeng.manager.DbgEvent;
|
||||||
|
import agent.dbgeng.manager.DbgProcess;
|
||||||
|
import agent.dbgeng.manager.DbgThread;
|
||||||
import agent.dbgeng.manager.evt.AbstractDbgCompletedCommandEvent;
|
import agent.dbgeng.manager.evt.AbstractDbgCompletedCommandEvent;
|
||||||
import agent.dbgeng.manager.evt.DbgProcessCreatedEvent;
|
import agent.dbgeng.manager.evt.DbgProcessCreatedEvent;
|
||||||
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||||
|
@ -35,14 +38,14 @@ public class DbgLaunchProcessCommand extends AbstractDbgCommand<DbgThread> {
|
||||||
|
|
||||||
private DbgProcessCreatedEvent created = null;
|
private DbgProcessCreatedEvent created = null;
|
||||||
private boolean completed = false;
|
private boolean completed = false;
|
||||||
private List<String> args;
|
private String args;
|
||||||
private String initialDirectory;
|
private String initialDirectory;
|
||||||
private String environment;
|
private String environment;
|
||||||
private BitmaskSet<DebugCreateFlags> createFlags;
|
private BitmaskSet<DebugCreateFlags> createFlags;
|
||||||
private BitmaskSet<DebugEngCreateFlags> engCreateFlags;
|
private BitmaskSet<DebugEngCreateFlags> engCreateFlags;
|
||||||
private BitmaskSet<DebugVerifierFlags> verifierFlags;
|
private BitmaskSet<DebugVerifierFlags> verifierFlags;
|
||||||
|
|
||||||
public DbgLaunchProcessCommand(DbgManagerImpl manager, List<String> args,
|
public DbgLaunchProcessCommand(DbgManagerImpl manager, String args,
|
||||||
String initialDirectory, String environment,
|
String initialDirectory, String environment,
|
||||||
BitmaskSet<DebugCreateFlags> createFlags,
|
BitmaskSet<DebugCreateFlags> createFlags,
|
||||||
BitmaskSet<DebugEngCreateFlags> engCreateFlags,
|
BitmaskSet<DebugEngCreateFlags> engCreateFlags,
|
||||||
|
@ -81,11 +84,6 @@ public class DbgLaunchProcessCommand extends AbstractDbgCommand<DbgThread> {
|
||||||
DebugClient dbgeng = manager.getClient();
|
DebugClient dbgeng = manager.getClient();
|
||||||
//DebugControl control = dbgeng.getControl();
|
//DebugControl control = dbgeng.getControl();
|
||||||
|
|
||||||
List<String> newArgs = new ArrayList<>();
|
|
||||||
for (String arg : args) {
|
|
||||||
newArgs.add(fixPath(arg));
|
|
||||||
}
|
|
||||||
|
|
||||||
initialDirectory = fixPath(initialDirectory);
|
initialDirectory = fixPath(initialDirectory);
|
||||||
environment = fixPath(environment);
|
environment = fixPath(environment);
|
||||||
// NB: The intent here is to enable multi-line input via a single dialog field
|
// NB: The intent here is to enable multi-line input via a single dialog field
|
||||||
|
@ -93,7 +91,7 @@ public class DbgLaunchProcessCommand extends AbstractDbgCommand<DbgThread> {
|
||||||
environment = environment.replace("\\0", "\0");
|
environment = environment.replace("\\0", "\0");
|
||||||
}
|
}
|
||||||
|
|
||||||
dbgeng.createProcess(dbgeng.getLocalServer(), StringUtils.join(newArgs, " "),
|
dbgeng.createProcess(dbgeng.getLocalServer(), args,
|
||||||
initialDirectory, environment, createFlags, engCreateFlags, verifierFlags);
|
initialDirectory, environment, createFlags, engCreateFlags, verifierFlags);
|
||||||
manager.waitForEventEx();
|
manager.waitForEventEx();
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,8 +148,6 @@ import ghidra.async.AsyncReference;
|
||||||
import ghidra.async.AsyncUtils;
|
import ghidra.async.AsyncUtils;
|
||||||
import ghidra.async.TypeSpec;
|
import ghidra.async.TypeSpec;
|
||||||
import ghidra.comm.util.BitmaskSet;
|
import ghidra.comm.util.BitmaskSet;
|
||||||
import ghidra.dbg.target.TargetLauncher.CmdLineParser;
|
|
||||||
import ghidra.dbg.target.TargetLauncher.TargetCmdLineLauncher;
|
|
||||||
import ghidra.dbg.target.TargetObject;
|
import ghidra.dbg.target.TargetObject;
|
||||||
import ghidra.dbg.util.HandlerMap;
|
import ghidra.dbg.util.HandlerMap;
|
||||||
import ghidra.lifecycle.Internal;
|
import ghidra.lifecycle.Internal;
|
||||||
|
@ -1414,21 +1412,9 @@ public class DbgManagerImpl implements DbgManager {
|
||||||
return AsyncUtils.NIL;
|
return AsyncUtils.NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletableFuture<?> launch(List<String> args) {
|
|
||||||
BitmaskSet<DebugCreateFlags> cf = BitmaskSet.of(DebugCreateFlags.DEBUG_PROCESS);
|
|
||||||
BitmaskSet<DebugEngCreateFlags> ef =
|
|
||||||
BitmaskSet.of(DebugEngCreateFlags.DEBUG_ECREATE_PROCESS_DEFAULT);
|
|
||||||
BitmaskSet<DebugVerifierFlags> vf =
|
|
||||||
BitmaskSet.of(DebugVerifierFlags.DEBUG_VERIFIER_DEFAULT);
|
|
||||||
return execute(new DbgLaunchProcessCommand(this, args,
|
|
||||||
null, null, cf, ef, vf));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> launch(Map<String, ?> map) {
|
public CompletableFuture<Void> launch(Map<String, ?> map) {
|
||||||
List<String> args =
|
String args = (String) map.get("args");
|
||||||
CmdLineParser.tokenize(TargetCmdLineLauncher.PARAMETER_CMDLINE_ARGS.get(map));
|
|
||||||
String initDir = (String) map.get("dir");
|
String initDir = (String) map.get("dir");
|
||||||
String env = (String) map.get("env");
|
String env = (String) map.get("env");
|
||||||
|
|
||||||
|
|
|
@ -15,12 +15,12 @@
|
||||||
*/
|
*/
|
||||||
package agent.dbgeng.model.iface1;
|
package agent.dbgeng.model.iface1;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.Map;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
import agent.dbgeng.model.iface2.DbgModelTargetObject;
|
import agent.dbgeng.model.iface2.DbgModelTargetObject;
|
||||||
import ghidra.dbg.error.DebuggerUserException;
|
import ghidra.dbg.error.DebuggerUserException;
|
||||||
import ghidra.dbg.target.TargetLauncher.TargetCmdLineLauncher;
|
import ghidra.dbg.target.TargetCmdLineLauncherEx;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface which indicates this object is capable of launching targets.
|
* An interface which indicates this object is capable of launching targets.
|
||||||
|
@ -30,10 +30,10 @@ import ghidra.dbg.target.TargetLauncher.TargetCmdLineLauncher;
|
||||||
*
|
*
|
||||||
* @param <T> type for this
|
* @param <T> type for this
|
||||||
*/
|
*/
|
||||||
public interface DbgModelTargetLauncher extends DbgModelTargetObject, TargetCmdLineLauncher {
|
public interface DbgModelTargetLauncher extends DbgModelTargetObject, TargetCmdLineLauncherEx {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public default CompletableFuture<Void> launch(List<String> args) {
|
public default CompletableFuture<Void> launch(Map<String, ?> args) {
|
||||||
return getModel().gateFuture(getManager().launch(args)).exceptionally((exc) -> {
|
return getModel().gateFuture(getManager().launch(args)).exceptionally((exc) -> {
|
||||||
throw new DebuggerUserException("Launch failed for " + args);
|
throw new DebuggerUserException("Launch failed for " + args);
|
||||||
}).thenApply(__ -> null);
|
}).thenApply(__ -> null);
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/* ###
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package ghidra.dbg.target;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import ghidra.dbg.target.TargetMethod.ParameterDescription;
|
||||||
|
import ghidra.dbg.target.TargetMethod.TargetParameterMap;
|
||||||
|
|
||||||
|
public interface TargetCmdLineLauncherEx extends TargetLauncher {
|
||||||
|
String CMDLINE_ARGS_NAME = "args";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@code args} parameter
|
||||||
|
*/
|
||||||
|
ParameterDescription<String> PARAMETER_CMDLINE_ARGS = ParameterDescription.create(
|
||||||
|
String.class,
|
||||||
|
CMDLINE_ARGS_NAME, true, "", "Command Line", "space-separated command-line arguments");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A map of parameters suitable for invoking {@link #launch(List)}
|
||||||
|
*/
|
||||||
|
TargetParameterMap PARAMETERS = TargetMethod.makeParameters(PARAMETER_CMDLINE_ARGS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the given image path contains spaces, and surround it in double quotes
|
||||||
|
* ({@code "}) if necessary.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Without the quotes the launcher will likely confuse the spaces for separating arguments.
|
||||||
|
* When constructing the command-line to launch a program, this method must be used, even if
|
||||||
|
* the image is the only "argument."
|
||||||
|
*
|
||||||
|
* @param imagePath the path to the image on the target platform.
|
||||||
|
* @return the path, possibly surrounded in quotes.
|
||||||
|
*/
|
||||||
|
static String quoteImagePathIfSpaces(String imagePath) {
|
||||||
|
if (imagePath.contains(" ")) {
|
||||||
|
return '"' + imagePath + '"';
|
||||||
|
}
|
||||||
|
return imagePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default public TargetParameterMap getParameters() {
|
||||||
|
return PARAMETERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Launch a target using the given arguments
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This is mostly applicable to user-space contexts, in which case, this usually means to
|
||||||
|
* launch a new process with the given arguments, where the first argument is the path to
|
||||||
|
* the executable image on the target host's file system.
|
||||||
|
*
|
||||||
|
* @param args the arguments
|
||||||
|
* @return a future which completes when the command has been processed
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public default CompletableFuture<Void> launch(Map<String, ?> args) {
|
||||||
|
return launch(args);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue