From 55ea88ddb0ee5791fc811bcd9655ed99d85d77d4 Mon Sep 17 00:00:00 2001 From: d-millar <33498836+d-millar@users.noreply.github.com> Date: Mon, 10 Feb 2025 16:31:36 -0500 Subject: [PATCH] GP-5360: first pass - gdb working GP-5360: working lldb.bat GP-5360: allow empty listing for dbgeng GP-5360: bat equivs GP-5360: bat equivs GP-5360: ssh adds for lldb GP-5360: missed one GP-5360: missed one GP-5360: wow this sucks GP-5360: post-review --- .../debugger-launchers/local-dbgeng-ext.bat | 2 +- .../data/debugger-launchers/local-dbgeng.bat | 2 +- .../data/debugger-launchers/svrcx-dbgeng.bat | 2 +- .../data/support/local-dbgeng-ext.py | 10 +- .../data/support/local-dbgeng.py | 37 ++++---- .../data/debugger-launchers/local-gdb.bat | 8 ++ .../certification.manifest | 4 + .../data/debugger-launchers/android-lldb.bat | 95 +++++++++++++++++++ .../data/debugger-launchers/android-lldb.sh | 2 +- .../data/debugger-launchers/kernel-lldb.bat | 48 ++++++++++ .../data/debugger-launchers/local-lldb.bat | 58 ++++++----- .../data/debugger-launchers/remote-lldb.bat | 49 ++++++++++ .../data/debugger-launchers/ssh-lldb.bat | 51 ++++++++++ .../data/debugger-launchers/ssh-lldb.sh | 68 +++++++++++++ .../TraceRmiLauncherServicePlugin.html | 9 ++ 15 files changed, 393 insertions(+), 52 deletions(-) create mode 100644 Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/android-lldb.bat create mode 100644 Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/kernel-lldb.bat create mode 100644 Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/remote-lldb.bat create mode 100644 Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/ssh-lldb.bat create mode 100644 Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/ssh-lldb.sh diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng-ext.bat b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng-ext.bat index 224f6ea2a4..b695b8d1d2 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng-ext.bat +++ b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng-ext.bat @@ -12,7 +12,7 @@ ::@help TraceRmiLauncherServicePlugin#dbgeng_ext ::@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:file!="" "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:dir="" "Path to dbgeng.dll directory" "Path containing dbgeng and associated DLLS (if not Windows Kits)." diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng.bat b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng.bat index 8557a6e9b6..bbc7eb143c 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng.bat +++ b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng.bat @@ -12,7 +12,7 @@ ::@help TraceRmiLauncherServicePlugin#dbgeng ::@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:file!="" "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:dir="" "Path to dbgeng.dll directory" "Path containing dbgeng and associated DLLS (if not Windows Kits)." diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/svrcx-dbgeng.bat b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/svrcx-dbgeng.bat index 3c6c5e17a6..cdfa7cda4c 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/svrcx-dbgeng.bat +++ b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/svrcx-dbgeng.bat @@ -12,7 +12,7 @@ ::@help TraceRmiLauncherServicePlugin#dbgeng_svrcx ::@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:str="" "Image" "The target binary executable image" ::@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target" ::@env OPT_CONNECT_STRING:str="" "Connection" "Connection-string arguments (a la dbgsrv args)" ::@env OPT_USE_DBGMODEL:bool=true "Use dbgmodel" "Load and use dbgmodel.dll if it is available." diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/data/support/local-dbgeng-ext.py b/Ghidra/Debug/Debugger-agent-dbgeng/data/support/local-dbgeng-ext.py index e48f36c60a..7bb949bf67 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/data/support/local-dbgeng-ext.py +++ b/Ghidra/Debug/Debugger-agent-dbgeng/data/support/local-dbgeng-ext.py @@ -51,8 +51,14 @@ def main(): args = os.getenv('OPT_TARGET_ARGS') if args: args = ' ' + args + target = os.getenv('OPT_TARGET_IMG') + if target is None or target == "": + print("dbgeng requires a target image - please try again.") + cmd.ghidra_trace_disconnect() + return + cmd.ghidra_trace_create_ext( - os.getenv('OPT_TARGET_IMG') + args, + target + args, os.getenv('OPT_TARGET_DIR'), os.getenv('OPT_TARGET_ENV'), os.getenv('OPT_CREATE_FLAGS'), @@ -67,7 +73,7 @@ def main(): except KeyboardInterrupt as ki: dbg.interrupt() - cmd.ghidra_trace_start(os.getenv('OPT_TARGET_IMG')) + cmd.ghidra_trace_start(target) cmd.ghidra_trace_sync_enable() on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS, DbgEng.DEBUG_STATUS_BREAK) diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/data/support/local-dbgeng.py b/Ghidra/Debug/Debugger-agent-dbgeng/data/support/local-dbgeng.py index c20c802679..f47d3efecf 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/data/support/local-dbgeng.py +++ b/Ghidra/Debug/Debugger-agent-dbgeng/data/support/local-dbgeng.py @@ -1,17 +1,17 @@ ## ### -# 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. +# 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. ## import os @@ -51,8 +51,13 @@ def main(): args = os.getenv('OPT_TARGET_ARGS') if args: args = ' ' + args - cmd.ghidra_trace_create( - os.getenv('OPT_TARGET_IMG') + args, start_trace=False) + target = os.getenv('OPT_TARGET_IMG') + if target is None or target == "": + print("dbgeng requires a target image - please try again.") + cmd.ghidra_trace_disconnect() + return + + cmd.ghidra_trace_create(target + args, start_trace=False) # TODO: HACK try: @@ -60,7 +65,7 @@ def main(): except KeyboardInterrupt as ki: dbg.interrupt() - cmd.ghidra_trace_start(os.getenv('OPT_TARGET_IMG')) + cmd.ghidra_trace_start(target) cmd.ghidra_trace_sync_enable() on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS, DbgEng.DEBUG_STATUS_BREAK) 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 index 1c475a9cf5..e77eea81dd 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.bat +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.bat @@ -33,6 +33,14 @@ IF EXIST %GHIDRA_HOME%\ghidra\.git ( ) set PYTHONPATH=%PYTHONPATH1%;%PYTHONPATH0%;%PYTHONPATH% +:: NB: This works - a lot of things do not. Don't change unless you know what you're doing! +set OPT_TARGET_ARGS=%OPT_TARGET_ARGS:"=\"% +set OPT_TARGET_ARGS=%OPT_TARGET_ARGS:)=^)% +:: NB: This seems stupid, but there doesn't seem to be a logical way to test before the previous lines +if %OPT_TARGET_ARGS%=="=\" ( + set OPT_TARGET_ARGS=\"\" +) + IF "%OPT_TARGET_IMG%"=="" ( "%OPT_GDB_PATH%" ^ -q ^ diff --git a/Ghidra/Debug/Debugger-agent-lldb/certification.manifest b/Ghidra/Debug/Debugger-agent-lldb/certification.manifest index 622c4707b7..947c12bf90 100644 --- a/Ghidra/Debug/Debugger-agent-lldb/certification.manifest +++ b/Ghidra/Debug/Debugger-agent-lldb/certification.manifest @@ -4,7 +4,11 @@ Module.manifest||GHIDRA||||END| README.md||GHIDRA||||END| build.gradle||GHIDRA||||END| +data/debugger-launchers/android-lldb.bat||GHIDRA||||END| +data/debugger-launchers/kernel-lldb.bat||GHIDRA||||END| data/debugger-launchers/local-lldb.bat||GHIDRA||||END| +data/debugger-launchers/remote-lldb.bat||GHIDRA||||END| +data/debugger-launchers/ssh-lldb.bat||GHIDRA||||END| src/main/py/LICENSE||GHIDRA||||END| src/main/py/MANIFEST.in||GHIDRA||||END| src/main/py/README.md||GHIDRA||||END| diff --git a/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/android-lldb.bat b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/android-lldb.bat new file mode 100644 index 0000000000..604d25ab99 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/android-lldb.bat @@ -0,0 +1,95 @@ +::@title android lldb +::@desc +::@desc

Launch with local lldb and connect to a stub (e.g., gdbserver)

+::@desc

+::@desc This will start lldb on the local system and then use it to connect to the remote system. +::@desc For setup instructions, press F1. +::@desc

+::@desc +::@menu-group remote +::@icon icon.debugger +::@help TraceRmiLauncherServicePlugin#lldb_android +::@enum StartCmd:str "process launch" "process launch --stop-at-entry" +::@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_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:file="lldb" "lldb command" "The path to lldb on the local system. 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." + +@echo off +set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-lldb\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-lldb\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-lldb\build\pypkg\src + set PYTHONPATH1=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src +) +set PYTHONPATH=%PYTHONPATH1%;%PYTHONPATH0%;%PYTHONPATH% + +:: NB: This works - a lot of things do not. Don't change unless you know what you're doing! +set OPT_TARGET_IMG="%OPT_TARGET_IMG%" +set OPT_TARGET_ARGS="%OPT_TARGET_ARGS%" + +IF %OPT_ARCH%=="" ( + IF "%OPT_TARGET_ARGS%"=="" ( + "%OPT_LLDB_PATH%" ^ + -o "version" ^ + -o "script import ghidralldb" ^ + -o "platform select remote-android" ^ + -o "platform connect connect://%OPT_HOST%:%OPT_PORT%" ^ + -o "target create "%OPT_TARGET_IMG%"" ^ + -o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^ + -o "ghidra trace start" ^ + -o "ghidra trace sync-enable" ^ + -o "ghidra trace sync-synth-stopped" ^ + -o "%OPT_START_CMD%" + ) ELSE ( + "%OPT_LLDB_PATH%" ^ + -o "version" ^ + -o "script import ghidralldb" ^ + -o "platform select remote-android" ^ + -o "platform connect connect://%OPT_HOST%:%OPT_PORT%" ^ + -o "settings set target.default-arch %OPT_ARCH%" + -o "target create "%OPT_TARGET_IMG%"" ^ + -o "settings set target.run-args %OPT_TARGET_ARGS%" ^ + -o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^ + -o "ghidra trace start" ^ + -o "ghidra trace sync-enable" ^ + -o "ghidra trace sync-synth-stopped" ^ + -o "%OPT_START_CMD%" + ) +) ELSE ( + if %OPT_TARGET_ARGS=="" ( + "%OPT_LLDB_PATH%" ^ + -o "version" ^ + -o "script import ghidralldb" ^ + -o "platform select remote-android" ^ + -o "platform connect connect://%OPT_HOST%:%OPT_PORT%" ^ + -o "settings set target.default-arch %OPT_ARCH%" + -o "target create "%OPT_TARGET_IMG%"" ^ + -o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^ + -o "ghidra trace start" ^ + -o "ghidra trace sync-enable" ^ + -o "ghidra trace sync-synth-stopped" ^ + -o "%OPT_START_CMD%" + ) ELSE ( + "%OPT_LLDB_PATH%" ^ + -o "version" ^ + -o "script import ghidralldb" ^ + -o "platform select remote-android" ^ + -o "platform connect connect://%OPT_HOST%:%OPT_PORT%" ^ + -o "settings set target.default-arch %OPT_ARCH%" + -o "target create "%OPT_TARGET_IMG%"" ^ + -o "settings set target.run-args %OPT_TARGET_ARGS%" ^ + -o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^ + -o "ghidra trace start" ^ + -o "ghidra trace sync-enable" ^ + -o "ghidra trace sync-synth-stopped" ^ + -o "%OPT_START_CMD%" + ) +) \ No newline at end of file diff --git a/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/android-lldb.sh b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/android-lldb.sh index 679cf4ca0e..14e21b0bf9 100755 --- a/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/android-lldb.sh +++ b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/android-lldb.sh @@ -25,7 +25,7 @@ #@desc #@menu-group remote #@icon icon.debugger -#@help TraceRmiLauncherServicePlugin#lldb_remote +#@help TraceRmiLauncherServicePlugin#lldb_android #@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" diff --git a/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/kernel-lldb.bat b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/kernel-lldb.bat new file mode 100644 index 0000000000..c57e3bdd92 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/kernel-lldb.bat @@ -0,0 +1,48 @@ +::@title kernel lldb +::@desc +::@desc

Launch with local lldb and connect to a remote kernel

+::@desc

+::@desc This will start lldb on the local system and then use it to connect to the remote system. +::@desc For setup instructions, press F1. +::@desc

+::@desc +::@menu-group remote +::@icon icon.debugger +::@help TraceRmiLauncherServicePlugin#lldb_kernel +::@env OPT_HOST:str="localhost" "Host" "The hostname of the target" +::@env OPT_ARCH:str="" "Architecture" "Target architecture override" +::@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." + +@echo off +set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-lldb\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-lldb\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-lldb\build\pypkg\src + set PYTHONPATH1=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src +) +set PYTHONPATH=%PYTHONPATH1%;%PYTHONPATH0%;%PYTHONPATH% + +IF "%OPT_ARCH%"=="" ( + "%OPT_LLDB_PATH%" ^ + -o "version" ^ + -o "script import ghidralldb" ^ + -o "kdp-remote %OPT_HOST%" ^ + -o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^ + -o "ghidra trace start" ^ + -o "ghidra trace sync-enable" ^ + -o "ghidra trace sync-synth-stopped" +) ELSE ( + "%OPT_LLDB_PATH%" ^ + -o "version" ^ + -o "script import ghidralldb" ^ + -o "settings set target.default-arch %OPT_ARCH%" + -o "kdp-remote %OPT_HOST%" ^ + -o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^ + -o "ghidra trace start" ^ + -o "ghidra trace sync-enable" ^ + -o "ghidra trace sync-synth-stopped" +) \ No newline at end of file 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 index e92e16c73c..156228ddb2 100644 --- a/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/local-lldb.bat +++ b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/local-lldb.bat @@ -1,5 +1,5 @@ ::@title lldb -::@image-opt arg:1 +::@image-opt env:OPT_TARGET_IMG ::@desc ::@desc

Launch with lldb

::@desc

@@ -11,8 +11,8 @@ ::@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_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_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." @@ -29,38 +29,36 @@ IF EXIST %GHIDRA_HOME%\ghidra\.git ( ) set PYTHONPATH=%PYTHONPATH1%;%PYTHONPATH0%;%PYTHONPATH% -set target_image=%1 -shift -set target_args=<%* +:: NB: This works - a lot of things do not. Don't change unless you know what you're doing! +set OPT_TARGET_IMG="%OPT_TARGET_IMG%" +set OPT_TARGET_ARGS="%OPT_TARGET_ARGS%" -IF '%target_image%'=="" ( +IF %OPT_TARGET_IMG%=="" ( "%OPT_LLDB_PATH%" ^ -o "version" ^ -o "script import ghidralldb" ^ -o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^ -o "ghidra trace start" ^ -o "ghidra trace sync-enable" -) - -IF NOT '%target_image%'=="" IF "%target_args%"=="" ( - "%OPT_LLDB_PATH%" ^ - -o "version" ^ - -o "script import ghidralldb" ^ - -o "target create "%target_image%"" ^ - -o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^ - -o "ghidra trace start" ^ - -o "ghidra trace sync-enable" ^ - -o "%OPT_START_CMD%" -) - -IF NOT '%target_image%'=="" IF NOT "%target_args%"=="" ( - "%OPT_LLDB_PATH%" ^ - -o "version" ^ - -o "script import ghidralldb" ^ - -o "target create "%target_image%"" ^ - -o "settings set target.run-args %target_args%" ^ - -o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^ - -o "ghidra trace start" ^ - -o "ghidra trace sync-enable" ^ - -o "%OPT_START_CMD%" +) ELSE ( + IF "%OPT_TARGET_ARGS%"=="" ( + "%OPT_LLDB_PATH%" ^ + -o "version" ^ + -o "script import ghidralldb" ^ + -o "target create "%OPT_TARGET_IMG%"" ^ + -o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^ + -o "ghidra trace start" ^ + -o "ghidra trace sync-enable" ^ + -o "%OPT_START_CMD%" + ) ELSE ( + "%OPT_LLDB_PATH%" ^ + -o "version" ^ + -o "script import ghidralldb" ^ + -o "target create "%OPT_TARGET_IMG%"" ^ + -o "settings set target.run-args %OPT_TARGET_ARGS%" ^ + -o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^ + -o "ghidra trace start" ^ + -o "ghidra trace sync-enable" ^ + -o "%OPT_START_CMD%" + ) ) \ No newline at end of file diff --git a/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/remote-lldb.bat b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/remote-lldb.bat new file mode 100644 index 0000000000..1e13203962 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/remote-lldb.bat @@ -0,0 +1,49 @@ +::@title remote lldb +::@desc +::@desc

Launch with local lldb and connect to a stub (e.g., gdbserver)

+::@desc

+::@desc This will start lldb on the local system and then use it to connect to the remote system. +::@desc For setup instructions, press F1. +::@desc

+::@desc +::@menu-group remote +::@icon icon.debugger +::@help TraceRmiLauncherServicePlugin#lldb_remote +::@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:file="lldb" "lldb command" "The path to lldb on the local system. Omit the full path to resolve using the system PATH." + +@echo off +set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-lldb\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-lldb\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-lldb\build\pypkg\src + set PYTHONPATH1=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src +) +set PYTHONPATH=%PYTHONPATH1%;%PYTHONPATH0%;%PYTHONPATH% + +IF %OPT_ARCH%=="" ( + "$OPT_LLDB_PATH" ^ + -o "version" ^ + -o "script import ghidralldb" ^ + -o "gdb-remote %OPT_HOST%:%OPT_PORT%" ^ + -o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^ + -o "ghidra trace start" ^ + -o "ghidra trace sync-enable" ^ + -o "ghidra trace sync-synth-stopped" +) ELSE ( + "$OPT_LLDB_PATH" ^ + -o "version" ^ + -o "script import ghidralldb" ^ + -o "settings set target.default-arch %OPT_ARCH%" + -o "gdb-remote %OPT_HOST%:%OPT_PORT%" ^ + -o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^ + -o "ghidra trace start" ^ + -o "ghidra trace sync-enable" ^ + -o "ghidra trace sync-synth-stopped" +) \ No newline at end of file diff --git a/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/ssh-lldb.bat b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/ssh-lldb.bat new file mode 100644 index 0000000000..083c7e0181 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/ssh-lldb.bat @@ -0,0 +1,51 @@ +::@timeout 60000 +::@title lldb via ssh +::@image-opt env:OPT_TARGET_IMG +::@desc +::@desc

Launch with lldb via ssh

+::@desc

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

+::@desc +::@menu-group remote +::@icon icon.debugger +::@help TraceRmiLauncherServicePlugin#lldb_ssh +::@enum StartCmd:str "process launch" "process launch --stop-at-entry" +::@enum Endian:str auto big little +::@env OPT_TARGET_IMG:str="" "Image" "The target binary executable image on the remote system" +::@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target" +::@env OPT_SSH_PATH:file!="ssh" "ssh command" "The path to ssh on the local system. Omit the full path to resolve using the system PATH." +::@env OPT_HOST:str="localhost" "[User@]Host" "The hostname or user@host" +::@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_LLDB_PATH:str="lldb" "lldb command" "The path to lldb on the remote system. 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_ARCH:str="x86_64" "Architecture" "Target architecture" + +@echo off + +IF "%OPT_TARGET_ARGS%" == "" ( + set cmd=TERM='%TERM%' '%OPT_LLDB_PATH%' ^ + -o 'version' ^ + -o 'script import ghidralldb' ^ + -o 'settings set target.default-arch %OPT_ARCH%' ^ + -o 'ghidra trace connect \"localhost:%OPT_REMOTE_PORT%\"' ^ + -o 'target create \"%OPT_TARGET_IMG%\"' ^ + -o 'ghidra trace start' ^ + -o 'ghidra trace sync-enable' ^ + -o '%OPT_START_CMD%' +) ELSE ( + set cmd=TERM='%TERM%' '%OPT_LLDB_PATH%' ^ + -o 'version' ^ + -o 'script import ghidralldb' ^ + -o 'settings set target.default-arch %OPT_ARCH%' ^ + -o 'ghidra trace connect \"localhost:%OPT_REMOTE_PORT%\"' ^ + -o 'target create \"%OPT_TARGET_IMG%\"' ^ + -o 'settings set target.run-args %OPT_TARGET_ARGS%' ^ + -o 'ghidra trace start' ^ + -o 'ghidra trace sync-enable' ^ + -o '%OPT_START_CMD%' +) + +"%OPT_SSH_PATH%" "-R%OPT_REMOTE_PORT%:%GHIDRA_TRACE_RMI_ADDR%" -t %OPT_EXTRA_SSH_ARGS% "%OPT_HOST%" "%cmd%" diff --git a/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/ssh-lldb.sh b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/ssh-lldb.sh new file mode 100644 index 0000000000..f24f9f6a8b --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/ssh-lldb.sh @@ -0,0 +1,68 @@ +#!/usr/bin/bash +## ### +# 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. +## +#@timeout 60000 +#@title lldb via ssh +#@image-opt arg:1 +#@desc +#@desc

Launch with lldb via ssh

+#@desc

+#@desc This will launch the target on a remote machine using lldb via ssh. +#@desc For setup instructions, press F1. +#@desc

+#@desc +#@menu-group remote +#@icon icon.debugger +#@help TraceRmiLauncherServicePlugin#lldb_ssh +#@enum StartCmd:str "process launch" "process launch --stop-at-entry" +#@enum Endian:str auto big little +#@arg :str "Image" "The target binary executable image on the remote system" +#@args "Arguments" "Command-line arguments to pass to the target" +#@env OPT_SSH_PATH:file!="ssh" "ssh command" "The path to ssh on the local system. Omit the full path to resolve using the system PATH." +#@env OPT_HOST:str="localhost" "[User@]Host" "The hostname or user@host" +#@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_LLDB_PATH:str="lldb" "lldb command" "The path to lldb on the remote system. 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_ARCH:str="x86_64" "Architecture" "Target architecture" + +target_image="$1" +shift +target_args="$@" + +if [ -z "$target_image" ] +then + "$OPT_SSH_PATH" "-R$OPT_REMOTE_PORT:$GHIDRA_TRACE_RMI_ADDR" -t $OPT_EXTRA_SSH_ARGS "$OPT_HOST" "TERM='$TERM' '$OPT_LLDB_PATH' \ + -o 'version' ^ + -o 'script import ghidralldb' ^ + -o 'settings set target.default-arch %OPT_ARCH%' ^ + -o 'ghidra trace connect \"localhost:%OPT_REMOTE_PORT%\"' ^ + -o 'target create \"%OPT_TARGET_IMG%\"' ^ + -o 'ghidra trace start' ^ + -o 'ghidra trace sync-enable' ^ + -o '%OPT_START_CMD%' +else + "$OPT_SSH_PATH" "-R$OPT_REMOTE_PORT:$GHIDRA_TRACE_RMI_ADDR" -t $OPT_EXTRA_SSH_ARGS "$OPT_HOST" "TERM='$TERM' '$OPT_LLDB_PATH' \ + -o 'version' ^ + -o 'script import ghidralldb' ^ + -o 'settings set target.default-arch %OPT_ARCH%' ^ + -o 'ghidra trace connect \"localhost:%OPT_REMOTE_PORT%\"' ^ + -o 'target create \"%OPT_TARGET_IMG%\"' ^ + -o 'settings set target.run-args %OPT_TARGET_ARGS%' ^ + -o 'ghidra trace start' ^ + -o 'ghidra trace sync-enable' ^ + -o '%OPT_START_CMD%' +fi diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/help/help/topics/TraceRmiLauncherServicePlugin/TraceRmiLauncherServicePlugin.html b/Ghidra/Debug/Debugger-rmi-trace/src/main/help/help/topics/TraceRmiLauncherServicePlugin/TraceRmiLauncherServicePlugin.html index a40d2eae05..37904af009 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/help/help/topics/TraceRmiLauncherServicePlugin/TraceRmiLauncherServicePlugin.html +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/help/help/topics/TraceRmiLauncherServicePlugin/TraceRmiLauncherServicePlugin.html @@ -703,6 +703,15 @@ perl -i -pe 's/(?<=pendingNMI\x00{4})\x00/\x01/' macOS_15-1234567.vmss
  • lldb command: This works the same as in LLDB.
  • +

    LLDB via SSH

    + +

    This works the same as the "GDB via SSH" launcher, but runs lldb on a remote system via ssh. + +

    Android LLDB

    + +

    This has the same options as the "LLDB via SSH" launcher, which are necessary for connecting to the Android debugger, + but executes via the normal lldb mechanism. +

    Stock Windows Debugger (WinDbg) Launchers

    The following launchers based on Microsoft's dbgeng.dll are included out of the