GP-380: Better quick launch using opinions and offers.

This commit is contained in:
Dan 2021-04-21 16:54:30 -04:00
parent 93b2f5cc64
commit 808c20ab7f
28 changed files with 1210 additions and 310 deletions

View file

@ -0,0 +1,51 @@
/* ###
* 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 agent.gdb;
import java.io.IOException;
import java.lang.ProcessBuilder.Redirect;
import java.util.*;
import ghidra.dbg.util.ShellUtils;
public enum GdbCompatibility {
INSTANCE;
public static boolean checkGdbPresent(String path) {
try {
ProcessBuilder builder = new ProcessBuilder(path, "--version");
builder.redirectError(Redirect.INHERIT);
builder.redirectOutput(Redirect.INHERIT);
@SuppressWarnings("unused")
Process gdb = builder.start();
// TODO: Once supported versions are decided, check the version.
return true;
}
catch (IOException e) {
return false;
}
}
private final Map<String, Boolean> cache = new HashMap<>();
public boolean isCompatible(String gdbCmd) {
List<String> args = ShellUtils.parseArgs(gdbCmd);
if (args.isEmpty()) {
return false;
}
return cache.computeIfAbsent(gdbCmd, p -> checkGdbPresent(args.get(0)));
}
}

View file

@ -17,14 +17,12 @@ package agent.gdb;
import java.util.concurrent.CompletableFuture;
import agent.gdb.gadp.GdbLocalDebuggerModelFactory;
import agent.gdb.manager.GdbManager;
import agent.gdb.model.impl.GdbModelImpl;
import agent.gdb.pty.linux.LinuxPtyFactory;
import ghidra.dbg.DebuggerModelFactory;
import ghidra.dbg.DebuggerObjectModel;
import ghidra.dbg.LocalDebuggerModelFactory;
import ghidra.dbg.util.ConfigurableFactory.FactoryDescription;
import ghidra.util.classfinder.ExtensionPointProperties;
/**
* Note this is in the testing source because it's not meant to be shipped in the release.... That
@ -34,8 +32,7 @@ import ghidra.util.classfinder.ExtensionPointProperties;
brief = "IN-VM GNU gdb local debugger", //
htmlDetails = "Launch a GDB session in this same JVM" //
)
@ExtensionPointProperties(priority = 80)
public class GdbInJvmDebuggerModelFactory implements LocalDebuggerModelFactory {
public class GdbInJvmDebuggerModelFactory implements DebuggerModelFactory {
private String gdbCmd = GdbManager.DEFAULT_GDB_CMD;
@FactoryOption("GDB launch command")
@ -56,7 +53,7 @@ public class GdbInJvmDebuggerModelFactory implements LocalDebuggerModelFactory {
@Override
public boolean isCompatible() {
return GdbLocalDebuggerModelFactory.checkGdbPresent(gdbCmd);
return GdbCompatibility.INSTANCE.isCompatible(gdbCmd);
}
public String getGdbCommand() {

View file

@ -19,16 +19,15 @@ import java.util.concurrent.CompletableFuture;
import agent.gdb.model.impl.GdbModelImpl;
import agent.gdb.pty.ssh.GhidraSshPtyFactory;
import ghidra.dbg.DebuggerModelFactory;
import ghidra.dbg.DebuggerObjectModel;
import ghidra.dbg.LocalDebuggerModelFactory;
import ghidra.dbg.util.ConfigurableFactory.FactoryDescription;
import ghidra.util.classfinder.ExtensionPointProperties;
import ghidra.dbg.util.ConfigurableFactory.FactoryOption;
@FactoryDescription(
brief = "GNU gdb via SSH",
htmlDetails = "Launch a GDB session over an SSH connection")
@ExtensionPointProperties(priority = 60)
public class GdbOverSshDebuggerModelFactory implements LocalDebuggerModelFactory {
public class GdbOverSshDebuggerModelFactory implements DebuggerModelFactory {
private String gdbCmd = "gdb";
@FactoryOption("GDB launch command")

View file

@ -15,10 +15,9 @@
*/
package agent.gdb.gadp;
import java.io.IOException;
import java.lang.ProcessBuilder.Redirect;
import java.util.List;
import agent.gdb.GdbCompatibility;
import agent.gdb.manager.GdbManager;
import ghidra.dbg.gadp.server.AbstractGadpLocalDebuggerModelFactory;
import ghidra.dbg.util.ConfigurableFactory.FactoryDescription;
@ -26,31 +25,11 @@ import ghidra.dbg.util.ShellUtils;
import ghidra.util.classfinder.ExtensionPointProperties;
@FactoryDescription( //
brief = "GNU gdb local agent via GADP/TCP", //
htmlDetails = "Launch a new agent using GDB. This may start a new session or join an existing one." //
brief = "GNU gdb local agent via GADP/TCP", //
htmlDetails = "Launch a new agent using GDB. This may start a new session or join an existing one." //
)
@ExtensionPointProperties(priority = 100)
public class GdbLocalDebuggerModelFactory extends AbstractGadpLocalDebuggerModelFactory {
public static boolean checkGdbPresent(String gdbCmd) {
List<String> args = ShellUtils.parseArgs(gdbCmd);
if (args.isEmpty()) {
return false;
}
try {
ProcessBuilder builder = new ProcessBuilder(args.get(0), "--version");
builder.redirectError(Redirect.INHERIT);
builder.redirectOutput(Redirect.INHERIT);
@SuppressWarnings("unused")
Process gdb = builder.start();
// TODO: Once supported versions are decided, check the version.
return true;
}
catch (IOException e) {
return false;
}
}
protected Boolean isSuitable;
private String gdbCmd = GdbManager.DEFAULT_GDB_CMD;
@FactoryOption("GDB launch command")
@ -62,15 +41,10 @@ public class GdbLocalDebuggerModelFactory extends AbstractGadpLocalDebuggerModel
public final Property<Boolean> useExistingOption =
Property.fromAccessors(boolean.class, this::isUseExisting, this::setUseExisting);
// TODO: A factory which connects to GDB via SSH. Would need to refactor manager.
@Override
public boolean isCompatible() {
// TODO: Could potentially support GDB on Windows, but the pty thing would need porting.
if (isSuitable != null) {
return isSuitable;
}
return isSuitable = checkGdbPresent(gdbCmd);
return GdbCompatibility.INSTANCE.isCompatible(gdbCmd);
}
public String getGdbCommand() {