From 0229b93b0d38cec34cf1b1c630c5062c59e7da63 Mon Sep 17 00:00:00 2001 From: d-millar <33498836+d-millar@users.noreply.github.com> Date: Tue, 18 Jun 2024 09:36:27 -0400 Subject: [PATCH] GP-4677: post-post-review GP-4677: post-review fixes GP-4677: better fixes for opinions & psutil GP-4677: first pass lldb logic GP-4677: limit options by platform --- .../Debugger-agent-gdb/certification.manifest | 1 + .../data/debugger-launchers/local-gdb.bat | 53 ++++++++++++++++++ .../src/main/py/src/ghidragdb/arch.py | 4 +- .../src/main/py/src/ghidragdb/commands.py | 6 ++- .../certification.manifest | 1 + .../data/debugger-launchers/local-lldb.bat | 54 +++++++++++++++++++ .../src/main/py/src/ghidralldb/commands.py | 5 +- .../BatchScriptTraceRmiLaunchOpinion.java | 13 +++-- .../UnixShellScriptTraceRmiLaunchOpinion.java | 13 +++-- 9 files changed, 138 insertions(+), 12 deletions(-) create mode 100644 Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.bat create mode 100644 Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/local-lldb.bat diff --git a/Ghidra/Debug/Debugger-agent-gdb/certification.manifest b/Ghidra/Debug/Debugger-agent-gdb/certification.manifest index a81d11782d..0e3af12ba9 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/certification.manifest +++ b/Ghidra/Debug/Debugger-agent-gdb/certification.manifest @@ -1,6 +1,7 @@ ##VERSION: 2.0 ##MODULE IP: JSch License Module.manifest||GHIDRA||||END| +data/debugger-launchers/local-gdb.bat||GHIDRA||||END| data/scripts/fallback_info_proc_mappings.gdb||GHIDRA||||END| data/scripts/fallback_maintenance_info_sections.gdb||GHIDRA||||END| data/scripts/getpid-linux-i386.gdb||GHIDRA||||END| diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.bat b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.bat new file mode 100644 index 0000000000..4ff30ef732 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.bat @@ -0,0 +1,53 @@ +::@title gdb +::@desc +::@desc

Launch with gdb

+::@desc

+::@desc This will launch the target on the local machine using gdb. +::@desc For setup instructions, press F1. +::@desc

+::@desc +::@menu-group local +::@icon icon.debugger +::@help TraceRmiLauncherServicePlugin#gdb +::@enum StartCmd:str run start starti +::@arg :file "Image" "The target binary executable image" +::@args "Arguments" "Command-line arguments to pass to the target" +::@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 + +@echo off +set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-gdb\pypkg\src +set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\pypkg\src +IF EXIST %GHIDRA_HOME%\.git ( + set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-gdb\build\pypkg\src + set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src +) +IF EXIST %GHIDRA_HOME%\ghidra\.git ( + set PYTHONPATH0=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-agent-gdb\build\pypkg\src + set PYTHONPATH1=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src +) +set PYTHONPATH=%PYTHONPATH1%;%PYTHONPATH0%;%PYTHONPATH% + +set target_image=%1 +shift +set target_args=%* + +"%OPT_GDB_PATH%" ^ + -q ^ + -ex "set pagination off" ^ + -ex "set confirm off" ^ + -ex "show version" ^ + -ex "python import ghidragdb" ^ + -ex "target exec %target_image%" ^ + -ex "set args %target_args%" ^ + -ex "set inferior-tty %TTY_TARGET%" ^ + -ex "ghidra trace connect '%GHIDRA_TRACE_RMI_ADDR%'" ^ + -ex "ghidra trace start" ^ + -ex "ghidra trace sync-enable" ^ + -ex "%OPT_START_CMD%" ^ + -ex "set confirm on" ^ + -ex "set pagination on" ^ + + \ No newline at end of file diff --git a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/arch.py b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/arch.py index acf5633093..bd5367955e 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/arch.py +++ b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/arch.py @@ -85,9 +85,9 @@ data64_compiler_map = { x86_compiler_map = { 'GNU/Linux': 'gcc', - 'Windows': 'Visual Studio', + 'Windows': 'windows', # This may seem wrong, but Ghidra cspecs really describe the ABI - 'Cygwin': 'Visual Studio', + 'Cygwin': 'windows', } compiler_map = { diff --git a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/commands.py b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/commands.py index 51700fa3ea..6423fc61ad 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/commands.py +++ b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/commands.py @@ -19,9 +19,13 @@ import os.path import socket import time +try: + import psutil +except ImportError: + print(f"Unable to import 'psutil' - check that it has been installed") + from ghidratrace import sch from ghidratrace.client import Client, Address, AddressRange, TraceObject -import psutil import gdb diff --git a/Ghidra/Debug/Debugger-agent-lldb/certification.manifest b/Ghidra/Debug/Debugger-agent-lldb/certification.manifest index 19e8376a8d..7e99970896 100644 --- a/Ghidra/Debug/Debugger-agent-lldb/certification.manifest +++ b/Ghidra/Debug/Debugger-agent-lldb/certification.manifest @@ -3,6 +3,7 @@ ##MODULE IP: Apache License 2.0 with LLVM Exceptions Module.manifest||GHIDRA||||END| build.gradle||GHIDRA||||END| +data/debugger-launchers/local-lldb.bat||GHIDRA||||END| src/llvm-project/lldb/bindings/java/java-typemaps.swig||Apache License 2.0 with LLVM Exceptions||||END| src/llvm-project/lldb/bindings/java/java.swig||Apache License 2.0 with LLVM Exceptions||||END| src/main/py/LICENSE||GHIDRA||||END| diff --git a/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/local-lldb.bat b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/local-lldb.bat new file mode 100644 index 0000000000..66c9e5c584 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/local-lldb.bat @@ -0,0 +1,54 @@ +::@title lldb +::@desc +::@desc

Launch with lldb

+::@desc

+::@desc This will launch the target on the local machine using lldb. +::@desc For setup instructions, press F1. +::@desc

+::@desc +::@menu-group local +::@icon icon.debugger +::@help TraceRmiLauncherServicePlugin#lldb +::@enum StartCmd:str "process launch" "process launch --stop-at-entry" +::@arg :file "Image" "The target binary executable image" +::@args "Arguments" "Command-line arguments to pass to the target" +::@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 + +@echo off +set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-gdb\pypkg\src +set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\pypkg\src +IF EXIST %GHIDRA_HOME%\.git ( + set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-gdb\build\pypkg\src + set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src +) +IF EXIST %GHIDRA_HOME%\ghidra\.git ( + set PYTHONPATH0=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-agent-gdb\build\pypkg\src + set PYTHONPATH1=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src +) +set PYTHONPATH=%PYTHONPATH1%;%PYTHONPATH0%;%PYTHONPATH% + +set target_image=%1 +shift +set target_args=%* + +IF DEFINED target_args ( + argspart=-o "settings set target.run-args %target_args%" +) + +IF DEFINED TARGET_TTY ( + ttypart=-o "settings set target.output-path %TTY_TARGET%" -o "settings set target.input-path $TTY_TARGET" +) + +"%OPT_LLDB_PATH%" ^ + -o "version" ^ + -o "script import ghidralldb" ^ + -o "target create %target_image%" ^ + %argspart% ^ + %ttypart% ^ + -o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^ + -o "ghidra trace start" ^ + -o "ghidra trace sync-enable" ^ + -o "%OPT_START_CMD%" diff --git a/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/commands.py b/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/commands.py index 23edde4dfe..a71055cdbb 100644 --- a/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/commands.py +++ b/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/commands.py @@ -23,7 +23,10 @@ import socket import sys import time -import psutil +try: + import psutil +except ImportError: + print(f"Unable to import 'psutil' - check that it has been installed") from ghidratrace import sch from ghidratrace.client import Client, Address, AddressRange, TraceObject diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/BatchScriptTraceRmiLaunchOpinion.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/BatchScriptTraceRmiLaunchOpinion.java index c3bc5da027..e9fc4708df 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/BatchScriptTraceRmiLaunchOpinion.java +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/BatchScriptTraceRmiLaunchOpinion.java @@ -16,11 +16,13 @@ package ghidra.app.plugin.core.debug.gui.tracermi.launcher; import java.util.Collection; +import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; import generic.jar.ResourceFile; import ghidra.debug.api.tracermi.TraceRmiLaunchOffer; +import ghidra.framework.OperatingSystem; import ghidra.program.model.listing.Program; import ghidra.util.Msg; @@ -29,10 +31,13 @@ public class BatchScriptTraceRmiLaunchOpinion extends AbstractTraceRmiLaunchOpin @Override public Collection getOffers(TraceRmiLauncherServicePlugin plugin, Program program) { - return getScriptPaths(plugin.getTool()) - .flatMap(rf -> Stream.of(rf.listFiles(crf -> crf.getName().endsWith(".bat")))) - .flatMap(sf -> createOffer(plugin, program, sf)) - .collect(Collectors.toList()); + if (OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS) { + return getScriptPaths(plugin.getTool()) + .flatMap(rf -> Stream.of(rf.listFiles(crf -> crf.getName().endsWith(".bat")))) + .flatMap(sf -> createOffer(plugin, program, sf)) + .collect(Collectors.toList()); + } + return List.of(); } protected Stream createOffer(TraceRmiLauncherServicePlugin plugin, diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/UnixShellScriptTraceRmiLaunchOpinion.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/UnixShellScriptTraceRmiLaunchOpinion.java index aebfa87aa2..6b535aa62d 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/UnixShellScriptTraceRmiLaunchOpinion.java +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/UnixShellScriptTraceRmiLaunchOpinion.java @@ -16,11 +16,13 @@ package ghidra.app.plugin.core.debug.gui.tracermi.launcher; import java.util.Collection; +import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; import generic.jar.ResourceFile; import ghidra.debug.api.tracermi.TraceRmiLaunchOffer; +import ghidra.framework.OperatingSystem; import ghidra.program.model.listing.Program; import ghidra.util.Msg; @@ -29,10 +31,13 @@ public class UnixShellScriptTraceRmiLaunchOpinion extends AbstractTraceRmiLaunch @Override public Collection getOffers(TraceRmiLauncherServicePlugin plugin, Program program) { - return getScriptPaths(plugin.getTool()) - .flatMap(rf -> Stream.of(rf.listFiles(crf -> crf.getName().endsWith(".sh")))) - .flatMap(sf -> createOffer(plugin, program, sf)) - .collect(Collectors.toList()); + if (OperatingSystem.CURRENT_OPERATING_SYSTEM != OperatingSystem.WINDOWS) { + return getScriptPaths(plugin.getTool()) + .flatMap(rf -> Stream.of(rf.listFiles(crf -> crf.getName().endsWith(".sh")))) + .flatMap(sf -> createOffer(plugin, program, sf)) + .collect(Collectors.toList()); + } + return List.of(); } protected Stream createOffer(TraceRmiLauncherServicePlugin plugin,