From b7570e1f52898c387d65975b2a520596a14bb386 Mon Sep 17 00:00:00 2001 From: Dan <46821332+nsadeveloper789@users.noreply.github.com> Date: Fri, 4 Apr 2025 17:15:41 +0000 Subject: [PATCH] GP-5538: Add 'Image' to remote-[gdb,lldb].*. Convert to powershell. --- .../Debugger-agent-gdb/certification.manifest | 2 +- .../data/debugger-launchers/local-gdb.sh | 2 +- .../data/debugger-launchers/local-rr.sh | 2 +- .../data/debugger-launchers/qemu-gdb.sh | 45 +++++----- .../data/debugger-launchers/qemu-sys-gdb.sh | 2 +- .../data/debugger-launchers/remote-gdb.bat | 49 ----------- .../data/debugger-launchers/remote-gdb.ps1 | 61 ++++++++++++++ .../data/debugger-launchers/remote-gdb.sh | 41 +++++---- .../data/debugger-launchers/ssh-gdb.sh | 2 +- .../data/debugger-launchers/ssh-gdbserver.sh | 2 +- .../data/debugger-launchers/wine-gdb.sh | 2 +- .../certification.manifest | 2 +- .../data/debugger-launchers/remote-lldb.bat | 49 ----------- .../data/debugger-launchers/remote-lldb.ps1 | 52 ++++++++++++ .../data/debugger-launchers/remote-lldb.sh | 35 ++++---- .../data/debugger-launchers/ssh-lldb.sh | 2 +- .../src/main/py/src/ghidralldb/commands.py | 2 +- .../BatchScriptTraceRmiLaunchOffer.java | 4 - .../PowerShellScriptTraceRmiLaunchOffer.java | 83 +++++++++++++++++++ ...PowerShellScriptTraceRmiLaunchOpinion.java | 54 ++++++++++++ .../service/tracermi/TraceRmiHandler.java | 15 +++- .../store/local/LocalFileSystem.java | 4 +- 22 files changed, 341 insertions(+), 171 deletions(-) delete mode 100644 Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/remote-gdb.bat create mode 100644 Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/remote-gdb.ps1 delete mode 100644 Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/remote-lldb.bat create mode 100644 Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/remote-lldb.ps1 create mode 100644 Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/PowerShellScriptTraceRmiLaunchOffer.java create mode 100644 Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/PowerShellScriptTraceRmiLaunchOpinion.java diff --git a/Ghidra/Debug/Debugger-agent-gdb/certification.manifest b/Ghidra/Debug/Debugger-agent-gdb/certification.manifest index 3b3a4164d5..3749773967 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/certification.manifest +++ b/Ghidra/Debug/Debugger-agent-gdb/certification.manifest @@ -4,7 +4,7 @@ Module.manifest||GHIDRA||||END| README.md||GHIDRA||||END| data/debugger-launchers/local-gdb.bat||GHIDRA||||END| data/debugger-launchers/qemu-sys-gdb.bat||GHIDRA||||END| -data/debugger-launchers/remote-gdb.bat||GHIDRA||||END| +data/debugger-launchers/remote-gdb.ps1||GHIDRA||||END| data/debugger-launchers/ssh-gdb.bat||GHIDRA||||END| data/debugger-launchers/ssh-gdbserver.bat||GHIDRA||||END| data/scripts/fallback_info_proc_mappings.gdb||GHIDRA||||END| diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.sh b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.sh index ea68f6f07f..c41b463751 100755 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.sh +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.sh @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env bash ## ### # IP: GHIDRA # diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-rr.sh b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-rr.sh index f59a18b0a1..1de53b37ca 100755 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-rr.sh +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-rr.sh @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env bash ## ### # IP: GHIDRA # diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/qemu-gdb.sh b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/qemu-gdb.sh index ca511e0f0d..9b478141ea 100755 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/qemu-gdb.sh +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/qemu-gdb.sh @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env bash ## ### # IP: GHIDRA # @@ -66,32 +66,27 @@ fi # Give QEMU a moment to open the socket sleep 0.1 -gdb_args=( - -q - -ex "set pagination off" - -ex "set confirm off" - -ex "show version" - -ex "python import ghidragdb" - -ex "set architecture $OPT_ARCH" - -ex "set endian $OPT_ENDIAN" - -ex "file \"$target_image\"" - -ex "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" - -ex "ghidra trace start" - -ex "ghidra trace sync-enable" - -ex "target remote localhost:$QEMU_GDB" - -ex "set confirm on" - -ex "set pagination on" -) +declare -a args -# If using OPT_PULL_ALL_SECTIONS, append instructions to push all sections from qemu +args+=(-q) +args+=(-ex "set pagination off") +args+=(-ex "set confirm off") +args+=(-ex "show version") +args+=(-ex "python import ghidragdb") +args+=(-ex "set architecture $OPT_ARCH") +args+=(-ex "set endian $OPT_ENDIAN") +args+=(-ex "file '$target_image'") +args+=(-ex "ghidra trace connect '$GHIDRA_TRACE_RMI_ADDR'") +args+=(-ex "ghidra trace start") +args+=(-ex "ghidra trace sync-enable") +args+=(-ex "target remote localhost:$QEMU_GDB") if [ "$OPT_PULL_ALL_SECTIONS" = "true" ] then - gdb_args+=( - -ex "ghidra trace tx-start put-all-sections" - -ex "ghidra trace put-sections -all-objects" - -ex "ghidra trace tx-commit" - ) + args+=(-ex "ghidra trace tx-start put-all-sections") + args+=(-ex "ghidra trace put-sections -all-objects") + args+=(-ex "ghidra trace tx-commit") fi +args+=(-ex "set confirm on") +args+=(-ex "set pagination on") -IFS="" -"$OPT_GDB_PATH" ${gdb_args[*]} +"$OPT_GDB_PATH" "${args[@]}" diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/qemu-sys-gdb.sh b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/qemu-sys-gdb.sh index ae31199b9f..c1cf9f7064 100755 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/qemu-sys-gdb.sh +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/qemu-sys-gdb.sh @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env bash ## ### # IP: GHIDRA # diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/remote-gdb.bat b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/remote-gdb.bat deleted file mode 100644 index c1885e0f10..0000000000 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/remote-gdb.bat +++ /dev/null @@ -1,49 +0,0 @@ -::@title remote gdb -::@desc -::@desc

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

-::@desc

-::@desc This will start gdb 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 gdb#remote -::@enum TargetType:str remote extended-remote -::@enum Endian:str auto big little -::@env OPT_TARGET_TYPE:TargetType="remote" "Target" "The type of remote target" -::@env OPT_HOST:str="localhost" "Host" "The hostname of the target" -::@env OPT_PORT:int=9999 "Port" "The host's listening port" -::@env OPT_GDB_PATH:file="gdb" "gdb command" "The path to gdb on the local system. Omit the full path to resolve using the system PATH." -::@env OPT_ARCH:str="auto" "Architecture" "Target architecture override" -::@env OPT_ENDIAN:Endian="auto" "Endian" "Target byte order" - -@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% - -"%OPT_GDB_PATH%" ^ - -q ^ - -ex "set pagination off" ^ - -ex "set confirm off" ^ - -ex "show version" ^ - -ex "python import ghidragdb" ^ - -ex "set architecture %OPT_ARCH%" ^ - ex "set endian %OPT_ENDIAN%" ^ - -ex "echo Connecting to %OPT_HOST%:%OPT_PORT%... " ^ - -ex "target %OPT_TARGET_TYPE% %OPT_HOST%:%OPT_PORT%" ^ - -ex "ghidra trace connect '%GHIDRA_TRACE_RMI_ADDR%'" ^ - -ex "ghidra trace start" ^ - -ex "ghidra trace sync-enable" ^ - -ex "ghidra trace sync-synth-stopped" ^ - -ex "set confirm on" ^ - -ex "set pagination on" diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/remote-gdb.ps1 b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/remote-gdb.ps1 new file mode 100644 index 0000000000..64a32a8453 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/remote-gdb.ps1 @@ -0,0 +1,61 @@ +#@title remote gdb +#@image-opt arg:1 +#@desc +#@desc

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

+#@desc

+#@desc This will start gdb 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 gdb#remote +#@enum TargetType:str remote extended-remote +#@enum Endian:str auto big little +#@arg :file "Image" "The target binary executable image (a copy on the local system)" +#@env OPT_TARGET_TYPE:TargetType="remote" "Target" "The type of remote target" +#@env OPT_HOST:str="localhost" "Host" "The hostname of the target" +#@env OPT_PORT:int=9999 "Port" "The host's listening port" +#@env OPT_GDB_PATH:file="gdb" "gdb command" "The path to gdb on the local system. Omit the full path to resolve using the system PATH." +#@env OPT_ARCH:str="auto" "Architecture" "Target architecture override" +#@env OPT_ENDIAN:Endian="auto" "Endian" "Target byte order" + +[IO.DirectoryInfo] $repo = "$Env:GHIDRA_HOME\.git" +[IO.DirectoryInfo] $repoParent = "$Env:GHIDRA_HOME\ghidra\.git" +if ($repo.Exists) { + $pypathGdb = "$Env:GHIDRA_HOME\Ghidra\Debug\Debugger-agent-gdb\build\pypkg\src" + $pypathTrace = "$Env:GHIDRA_HOME\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src" +} +elseif ($repoParent.Exists) { + $pypathGdb = "$Env:GHIDRA_HOME\ghidra\Ghidra\Debug\Debugger-agent-gdb\build\pypkg\src" + $pypathTrace = "$Env:GHIDRA_HOME\ghidra\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src" +} +else { + $pypathGdb = "$Env:GHIDRA_HOME\Ghidra\Debug\Debugger-agent-gdb\pypkg\src" + $pypathTrace = "$Env:GHIDRA_HOME\Ghidra\Debug\Debugger-rmi-trace\pypkg\src" +} +$Env:PYTHONPATH = "$pypathGdb;$pypathTrace;$Env:PYTHONPATH" + +$arglist = @() + +$arglist+=("-q") +$arglist+=("-ex", "`"set pagination off`"") +$arglist+=("-ex", "`"set confirm off`"") +$arglist+=("-ex", "`"show version`"") +$arglist+=("-ex", "`"python import ghidragdb`"") +$arglist+=("-ex", "`"set architecture $Env:OPT_ARCH`"") +$arglist+=("-ex", "`"set endian $Env:OPT_ENDIAN`"") +if ("$($args[0])" -ne "") { + $image = $args[0] -replace "\\", "\\\\" + $arglist+=("-ex", "`"file '$image'`"") +} +$arglist+=("-ex", "`"echo Connecting to $Env:OPT_HOST`:$Env:OPT_PORT... `"") +$arglist+=("-ex", "`"target $Env:OPT_TARGET_TYPE $Env:OPT_HOST`:$Env:OPT_PORT`"") +$arglist+=("-ex", "`"ghidra trace connect '$Env:GHIDRA_TRACE_RMI_ADDR'`"") +$arglist+=("-ex", "`"ghidra trace start`"") +$arglist+=("-ex", "`"ghidra trace sync-enable`"") +$arglist+=("-ex", "`"ghidra trace sync-synth-stopped`"") +$arglist+=("-ex", "`"set confirm on`"") +$arglist+=("-ex", "`"set pagination on`"") + +Start-Process -FilePath $Env:OPT_GDB_PATH -ArgumentList $arglist -NoNewWindow -Wait diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/remote-gdb.sh b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/remote-gdb.sh index 02ec35ec05..8e59bdb434 100755 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/remote-gdb.sh +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/remote-gdb.sh @@ -15,6 +15,7 @@ # limitations under the License. ## #@title remote gdb +#@image-opt arg:1 #@desc #@desc

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

#@desc

@@ -27,6 +28,7 @@ #@help gdb#remote #@enum TargetType:str remote extended-remote #@enum Endian:str auto big little +#@arg :file "Image" "The target binary executable image (a copy on the local system)" #@env OPT_TARGET_TYPE:TargetType="remote" "Target" "The type of remote target" #@env OPT_HOST:str="localhost" "Host" "The hostname of the target" #@env OPT_PORT:int=9999 "Port" "The host's listening port" @@ -47,19 +49,26 @@ else export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/pypkg/src:$PYTHONPATH fi -"$OPT_GDB_PATH" \ - -q \ - -ex "set pagination off" \ - -ex "set confirm off" \ - -ex "show version" \ - -ex "python import ghidragdb" \ - -ex "set architecture $OPT_ARCH" \ - -ex "set endian $OPT_ENDIAN" \ - -ex "echo Connecting to $OPT_HOST:$OPT_PORT... " \ - -ex "target $OPT_TARGET_TYPE $OPT_HOST:$OPT_PORT" \ - -ex "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \ - -ex "ghidra trace start" \ - -ex "ghidra trace sync-enable" \ - -ex "ghidra trace sync-synth-stopped" \ - -ex "set confirm on" \ - -ex "set pagination on" +declare -a args + +args+=(-q) +args+=(-ex "set pagination off") +args+=(-ex "set confirmation off") +args+=(-ex "show version") +args+=(-ex "python import ghidragdb") +args+=(-ex "set architecture $OPT_ARCH") +args+=(-ex "set endian $OPT_ENDIAN") +if [ -n "$1" ] +then + args+=(-ex "file '$1'") +fi +args+=(-ex "echo Connecting to $OPT_HOST:$OPT_PORT...") +args+=(-ex "target $OPT_TARGET_TYPE $OPT_HOST:$OPT_PORT") +args+=(-ex "ghidra trace connect '$GHIDRA_TRACE_RMI_ADDR'") +args+=(-ex "ghidra trace start") +args+=(-ex "ghidra trace sync-enable") +args+=(-ex "ghidra trace sync-synth-stopped") +args+=(-ex "set confirm on") +args+=(-ex "set pagination on") + +"$OPT_GDB_PATH" "${args[@]}" diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdb.sh b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdb.sh index ede3276821..f5a80ac53b 100755 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdb.sh +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdb.sh @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env bash ## ### # IP: GHIDRA # diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdbserver.sh b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdbserver.sh index 4a38e9c61e..f31c5bd16c 100755 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdbserver.sh +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdbserver.sh @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env bash ## ### # IP: GHIDRA # diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/wine-gdb.sh b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/wine-gdb.sh index 0dd83d75dd..59640057b0 100755 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/wine-gdb.sh +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/wine-gdb.sh @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env bash ## ### # IP: GHIDRA # diff --git a/Ghidra/Debug/Debugger-agent-lldb/certification.manifest b/Ghidra/Debug/Debugger-agent-lldb/certification.manifest index 5235f673b0..48021f6ccd 100644 --- a/Ghidra/Debug/Debugger-agent-lldb/certification.manifest +++ b/Ghidra/Debug/Debugger-agent-lldb/certification.manifest @@ -7,7 +7,7 @@ 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/remote-lldb.ps1||GHIDRA||||END| data/debugger-launchers/ssh-lldb.bat||GHIDRA||||END| src/main/help/help/TOC_Source.xml||GHIDRA||||END| src/main/help/help/topics/lldb/lldb.html||GHIDRA||||END| 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 deleted file mode 100644 index c9e283b890..0000000000 --- a/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/remote-lldb.bat +++ /dev/null @@ -1,49 +0,0 @@ -::@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 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/remote-lldb.ps1 b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/remote-lldb.ps1 new file mode 100644 index 0000000000..a9bc9457dc --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/remote-lldb.ps1 @@ -0,0 +1,52 @@ +#@title remote lldb +#@image-opt arg:1 +#@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 lldb#remote +#@arg :file "Image" "The target binary executable image (a copy on the local system)" +#@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." + +[IO.DirectoryInfo] $repo = "$Env:GHIDRA_HOME\.git" +[IO.DirectoryInfo] $repoParent = "$Env:GHIDRA_HOME\ghidra\.git" +if ($repo.Exists) { + $pypathLldb = "$Env:GHIDRA_HOME\Ghidra\Debug\Debugger-agent-lldb\build\pypkg\src" + $pypathTrace = "$Env:GHIDRA_HOME\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src" +} +elseif ($repoParent.Exists) { + $pypathLldb = "$Env:GHIDRA_HOME\ghidra\Ghidra\Debug\Debugger-agent-lldb\build\pypkg\src" + $pypathTrace = "$Env:GHIDRA_HOME\ghidra\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src" +} +else { + $pypathLldb = "$Env:GHIDRA_HOME\Ghidra\Debug\Debugger-agent-lldb\pypkg\src" + $pypathTrace = "$Env:GHIDRA_HOME\Ghidra\Debug\Debugger-rmi-trace\pypkg\src" +} +$Env:PYTHONPATH = "$pypathLldb;$pypathTrace;$Env:PYTHONPATH" + +$arglist = @() + +$arglist+=("-o", "`"version`"") +$arglist+=("-o", "`"script import ghidralldb`"") +if ("$Env:OPT_ARCH" -ne "") { + $arglist+=("-o", "`"settings set target.default-arch $Env:OPT_ARCH`"") +} +if ("$($args[0])" -ne "") { + $image = $args[0] + $arglist+=("-o", "`"file '$image'`"") +} +$arglist+=("-o", "`"gdb-remote $Env:OPT_HOST`:$Env:OPT_PORT`"") +$arglist+=("-o", "`"ghidra trace connect '$Env:GHIDRA_TRACE_RMI_ADDR'`"") +$arglist+=("-o", "`"ghidra trace start`"") +$arglist+=("-o", "`"ghidra trace sync-enable`"") +$arglist+=("-o", "`"ghidra trace sync-synth-stopped`"") + +Start-Process -FilePath $Env:OPT_LLDB_PATH -ArgumentList $arglist -NoNewWindow -Wait diff --git a/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/remote-lldb.sh b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/remote-lldb.sh index d6c34c6b0c..4f595b9817 100755 --- a/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/remote-lldb.sh +++ b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/remote-lldb.sh @@ -15,6 +15,7 @@ # limitations under the License. ## #@title remote lldb +#@image-opt arg:1 #@desc #@desc

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

#@desc

@@ -25,6 +26,7 @@ #@menu-group remote #@icon icon.debugger #@help lldb#remote +#@arg :file "Image" "The target binary executable image (a copy on the local system)" #@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" @@ -43,19 +45,22 @@ else export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/pypkg/src:$PYTHONPATH fi -if [ -z "$OPT_ARCH" ] -then - archcmd= -else - archcmd=-o "settings set target.default-arch $OPT_ARCH" -fi +declare -a args -"$OPT_LLDB_PATH" \ - -o "version" \ - -o "script import ghidralldb" \ - $archcmd \ - -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" +args+=(-o version) +args+=(-o "script import ghidralldb") +if [ -n "$OPT_ARCH" ] +then + args+=(-o "settings set target.default-arch $OPT_ARCH") +fi +if [ -n "$1" ] +then + args+=(-o "file '$1'") +fi +args+=(-o "gdb-remote $OPT_HOST:$OPT_PORT") +args+=(-o "ghidra trace connect '$GHIDRA_TRACE_RMI_ADDR'") +args+=(-o "ghidra trace start") +args+=(-o "ghidra trace sync-enable") +args+=(-o "ghidra trace sync-synth-stopped") + +"$OPT_LLDB_PATH" "${args[@]}" 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 index 05e7724a63..8935da4c19 100644 --- a/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/ssh-lldb.sh +++ b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/ssh-lldb.sh @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env bash ## ### # IP: GHIDRA # 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 c7347d182f..c5ac6b0bfa 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 @@ -1698,8 +1698,8 @@ def should_query_regions() -> bool: def put_regions() -> None: regions = [] + proc = util.get_process() if should_query_regions(): - proc = util.get_process() try: regions = util.REGION_INFO_READER.get_regions() except Exception: diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/BatchScriptTraceRmiLaunchOffer.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/BatchScriptTraceRmiLaunchOffer.java index ee2ecd2ff7..411cdcea1a 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/BatchScriptTraceRmiLaunchOffer.java +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/BatchScriptTraceRmiLaunchOffer.java @@ -17,12 +17,8 @@ package ghidra.app.plugin.core.debug.gui.tracermi.launcher; import java.io.File; import java.io.FileNotFoundException; -import java.net.SocketAddress; -import java.util.List; -import java.util.Map; import ghidra.app.plugin.core.debug.gui.tracermi.launcher.ScriptAttributesParser.ScriptAttributes; -import ghidra.debug.api.ValStr; import ghidra.program.model.listing.Program; /** diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/PowerShellScriptTraceRmiLaunchOffer.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/PowerShellScriptTraceRmiLaunchOffer.java new file mode 100644 index 0000000000..f6a6863485 --- /dev/null +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/PowerShellScriptTraceRmiLaunchOffer.java @@ -0,0 +1,83 @@ +/* ### + * 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.app.plugin.core.debug.gui.tracermi.launcher; + +import java.io.File; +import java.io.FileNotFoundException; +import java.net.SocketAddress; +import java.util.List; +import java.util.Map; + +import ghidra.app.plugin.core.debug.gui.tracermi.launcher.ScriptAttributesParser.ScriptAttributes; +import ghidra.debug.api.ValStr; +import ghidra.program.model.listing.Program; + +/** + * A launcher implemented by a Window PowerShell file. + * + *

+ * The script must start with an attributes header in a comment block. See + * {@link ScriptAttributesParser}. + */ +public class PowerShellScriptTraceRmiLaunchOffer extends AbstractScriptTraceRmiLaunchOffer { + public static final String REM = "#"; + public static final int REM_LEN = REM.length(); + + /** + * Create a launch offer from the given PowerShell file. + * + * @param plugin the launcher service plugin + * @param program the current program, usually the target image. In general, this should be used + * for at least two purposes. 1) To populate the default command line. 2) To ensure + * the target image is mapped in the resulting target trace. + * @param script the PowerShell file that implements this offer + * @return the offer + * @throws FileNotFoundException if the batch file does not exist + */ + public static PowerShellScriptTraceRmiLaunchOffer create(TraceRmiLauncherServicePlugin plugin, + Program program, File script) throws FileNotFoundException { + ScriptAttributesParser parser = new ScriptAttributesParser() { + @Override + protected boolean ignoreLine(int lineNo, String line) { + return line.isBlank(); + } + + @Override + protected String removeDelimiter(String line) { + String stripped = line.stripLeading(); + if (!stripped.startsWith(REM)) { + return null; + } + return stripped.substring(REM_LEN); + } + }; + ScriptAttributes attrs = parser.parseFile(script); + return new PowerShellScriptTraceRmiLaunchOffer(plugin, program, script, + "PS1_FILE:" + script.getName(), attrs); + } + + private PowerShellScriptTraceRmiLaunchOffer(TraceRmiLauncherServicePlugin plugin, + Program program, File script, String configName, ScriptAttributes attrs) { + super(plugin, program, script, configName, attrs); + } + + @Override + protected void prepareSubprocess(List commandLine, Map env, + Map> args, SocketAddress address) { + super.prepareSubprocess(commandLine, env, args, address); + commandLine.add(0, "powershell"); + } +} diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/PowerShellScriptTraceRmiLaunchOpinion.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/PowerShellScriptTraceRmiLaunchOpinion.java new file mode 100644 index 0000000000..d6635ca807 --- /dev/null +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/PowerShellScriptTraceRmiLaunchOpinion.java @@ -0,0 +1,54 @@ +/* ### + * 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.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; + +public class PowerShellScriptTraceRmiLaunchOpinion extends AbstractTraceRmiLaunchOpinion { + + @Override + public Collection getOffers(TraceRmiLauncherServicePlugin plugin, + Program program) { + if (OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS) { + return getScriptPaths(plugin.getTool()) + .flatMap(rf -> Stream.of(rf.listFiles(crf -> crf.getName().endsWith(".ps1")))) + .flatMap(sf -> createOffer(plugin, program, sf)) + .collect(Collectors.toList()); + } + return List.of(); + } + + protected Stream createOffer(TraceRmiLauncherServicePlugin plugin, + Program program, ResourceFile scriptFile) { + try { + return Stream.of(PowerShellScriptTraceRmiLaunchOffer.create(plugin, program, + scriptFile.getFile(false))); + } + catch (Exception e) { + Msg.error(this, "Could not offer " + scriptFile + ": " + e.getMessage(), e); + return Stream.of(); + } + } +} diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiHandler.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiHandler.java index 4b65d596bb..747839ac30 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiHandler.java +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiHandler.java @@ -45,6 +45,7 @@ import ghidra.framework.model.*; import ghidra.framework.plugintool.AutoService; import ghidra.framework.plugintool.AutoService.Wiring; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; +import ghidra.framework.store.local.LocalFileSystem; import ghidra.program.model.address.*; import ghidra.program.model.lang.*; import ghidra.program.util.DefaultLanguageService; @@ -861,8 +862,20 @@ public class TraceRmiHandler extends AbstractTraceRmiConnection { return ReplyCreateTrace.getDefaultInstance(); } + protected static String sanitizeName(String name) { + StringBuffer buf = new StringBuffer(name.length()); + for (int i = 0; i < name.length(); i++) { + char c = name.charAt(i); + buf.append(LocalFileSystem.isValidNameCharacter(c) ? c : '_'); + } + return buf.toString(); + } + protected static List sanitizePath(String path) { - return Stream.of(path.split("\\\\|/")).filter(p -> !p.isBlank()).toList(); + return Stream.of(path.split("\\\\|/")) + .filter(n -> !n.isBlank()) + .map(n -> sanitizeName(n)) + .toList(); } protected ReplyDeleteBytes handleDeleteBytes(RequestDeleteBytes req) diff --git a/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/local/LocalFileSystem.java b/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/local/LocalFileSystem.java index e20b930f0a..fbce15768b 100644 --- a/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/local/LocalFileSystem.java +++ b/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/local/LocalFileSystem.java @@ -4,9 +4,9 @@ * 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.