From e1776460c44ec8e8f2b7386a86d3ae8ed181c6a4 Mon Sep 17 00:00:00 2001 From: d-millar <33498836+d-millar@users.noreply.github.com> Date: Fri, 13 Feb 2026 12:51:27 -0500 Subject: [PATCH] GP-6401: better setuptuils GP-6401: missed one GP-6401: more re-run tweaks GP-6401: allow re-run GP-6401: minor fixes GP-6401: post-review GP-6401: help GP-6401: attach variants GP-6401: opt dbgmodel GP-6401: args fix GP-6401: better x64dbg GP-6401: simpler dbgeng GP-6401: x64dbg impl GP-6401: first pass w/ file GP-6401: first pass w/ file GP-6401: first successful attempt --- .../data/debugger-launchers/local-dbgeng.bat | 2 +- .../data/debugger-launchers/local-dbgeng.ps1 | 66 ++++++++++ .../debugger-launchers/ssh-dbgeng-attach.ps1 | 102 ++++++++++++++++ .../data/debugger-launchers/ssh-dbgeng.ps1 | 105 ++++++++++++++++ .../data/support/dbgsetuputils.ps1 | 27 +++++ .../data/support/local-dbgeng-attach.py | 37 ++++-- .../data/support/local-dbgeng.py | 43 +++++-- .../src/main/help/help/TOC_Source.xml | 3 + .../main/help/help/topics/dbgeng/dbgeng.html | 30 ++++- .../data/debugger-launchers/local-x64dbg.bat | 2 +- .../data/debugger-launchers/local-x64dbg.ps1 | 68 +++++++++++ .../debugger-launchers/ssh-x64dbg-attach.ps1 | 105 ++++++++++++++++ .../data/debugger-launchers/ssh-x64dbg.ps1 | 114 ++++++++++++++++++ .../data/support/local-x64dbg-attach.py | 31 ++++- .../data/support/local-x64dbg.py | 46 +++++-- .../data/support/x64dbgsetuputils.ps1 | 27 +++++ .../src/main/help/help/TOC_Source.xml | 3 + .../main/help/help/topics/x64dbg/x64dbg.html | 29 ++++- .../src/main/py/src/ghidraxdbg/hooks.py | 16 ++- .../data/support/setuputils.ps1 | 16 ++- .../data/support/setuputils.sh | 6 +- 21 files changed, 835 insertions(+), 43 deletions(-) create mode 100644 Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng.ps1 create mode 100644 Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/ssh-dbgeng-attach.ps1 create mode 100644 Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/ssh-dbgeng.ps1 create mode 100644 Ghidra/Debug/Debugger-agent-dbgeng/data/support/dbgsetuputils.ps1 create mode 100644 Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/local-x64dbg.ps1 create mode 100644 Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/ssh-x64dbg-attach.ps1 create mode 100644 Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/ssh-x64dbg.ps1 create mode 100644 Ghidra/Debug/Debugger-agent-x64dbg/data/support/x64dbgsetuputils.ps1 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 49fdaa01dd..ed1324ef72 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 @@ -13,7 +13,7 @@ :: See the License for the specific language governing permissions and :: limitations under the License. :: ## -::@title dbgeng +::@title dbgeng (.bat) ::@image-opt env:OPT_TARGET_IMG ::@desc ::@desc

Launch with dbgeng (in a Python interpreter)

diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng.ps1 b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng.ps1 new file mode 100644 index 0000000000..691cb22b75 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng.ps1 @@ -0,0 +1,66 @@ +## ### +# 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. +## +#@title dbgeng (.ps1) +#@image-opt env:OPT_TARGET_IMG +#@desc +#@desc

Launch with dbgeng

+#@desc

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

+#@desc +#@menu-group dbgeng +#@icon icon.debugger +#@help dbgeng#local +#@depends Debugger-rmi-trace +#@arg :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_PYTHON_EXE:file!="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH." +#@env OPT_PYTHON_ARGS:str="" "python cmd args" "Arguments passed to python (versus 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)." + +. ..\support\dbgsetuputils.ps1 + +function Compute-Python-Args { + param($TempFile) + + $arglist = @("$Env:OPT_PYTHON_EXE") + if ("$Env:OPT_PYTHON_ARGS" -ne "") { + $arglist+=($Env:OPT_PYTHON_ARGS) + } + $arglist+=($TempFile) + + $arglist+=($Env:GHIDRA_TRACE_RMI_ADDR) + $arglist+=($Env:OPT_USE_DBGMODEL) + $arglist+=($Env:OPT_TARGET_IMG) + + if ("$Env:OPT_TARGET_ARGS" -ne "") { + $arglist+=($Env:OPT_TARGET_ARGS) + } + return $arglist +} + +$pypathTrace = Ghidra-Module-PyPath "Debugger-rmi-trace" +$pypathDbg = Ghidra-Module-PyPath +$Env:PYTHONPATH = "$pypathDbg;$pypathTrace;$Env:PYTHONPATH" + +$tmpfile = "..\support\local-dbgeng.py" +$arglist = Compute-Python-Args -TempFile $tmpfile + +Start-Process -FilePath $arglist[0] -ArgumentList $arglist[1..$arglist.Count] ` + -NoNewWindow -Wait diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/ssh-dbgeng-attach.ps1 b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/ssh-dbgeng-attach.ps1 new file mode 100644 index 0000000000..a4ad65fa9b --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/ssh-dbgeng-attach.ps1 @@ -0,0 +1,102 @@ +## ### +# 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. +## +#@title dbgeng attach via ssh +#@desc +#@desc

Attach with dbgeng (in a Python interpreter)

+#@desc

+#@desc This will attach to a running target on the local machine using dbgeng.dll. +#@desc For setup instructions, press F1. +#@desc

+#@desc +#@menu-group dbgeng +#@icon icon.debugger +#@help dbgeng#ssh +#@depends Debugger-rmi-trace +#@env OPT_TARGET_PID:int=0 "Process id" "The target process id" +#@env OPT_ATTACH_FLAGS:int=0 "Attach flags" "Attach flags" +#@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_PYTHON_EXE:file!="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH." +#@env OPT_PYTHON_ARGS:str="" "python cmd args" "Arguments passed to python (versus the target)" +#@env OPT_USE_DBGMODEL:bool=true "Use dbgmodel" "Load and use dbgmodel.dll if it is available." + +. ..\support\dbgsetuputils.ps1 + +function Compute-Python-Args { + param($TempFile) + + $arglist = @("$Env:OPT_PYTHON_EXE") + if ("$Env:OPT_PYTHON_ARGS" -ne "") { + $arglist+=($Env:OPT_PYTHON_ARGS) + } + $arglist+=($TempFile) + + $arglist+=("localhost:$Env:OPT_REMOTE_PORT") + $arglist+=($Env:OPT_USE_DBGMODEL) + $arglist+=($Env:OPT_TARGET_PID) + $arglist+=($Env:OPT_ATTACH_FLAGS) + + return $arglist +} + +$tmpfile = "local-dbgeng-attach.py" +$arglist = Compute-Python-Args -TempFile $tmpfile + +$scpargs = Compute-Scp-Args "..\support\$tmpfile" +$sshargs = Compute-Ssh-Args $arglist True + +$scpproc = Start-Process -FilePath $scpargs[0] -ArgumentList $scpargs[1..$scpargs.Count] -NoNewWindow -Wait -PassThru +$sshproc = Start-Process -FilePath $sshargs[0] -ArgumentList $sshargs[1..$sshargs.Count] -NoNewWindow -Wait -PassThru + +$version = Get-Ghidra-Version +$answer = Check-Result-And-Prompt-Mitigation $sshproc @" +It appears ghidradbg is missing from the remote system. This can happen if you +forgot to install the required package. This can also happen if you installed +the packages to a different Python environment than is being used by the +remote's gdb. + +This script is about to offer automatic resolution. If you'd like to resolve +this manually, answer no to the next question and then see Ghidra's help by +pressing F1 in the dialog of launch parameters. + +WARNING: Answering yes to the next question will invoke pip to try to install +missing or incorrectly-versioned dependencies. It may attempt to find packages +from the PyPI mirror configured on the REMOTE system. If you have not configured +one, it will connect to the official one. + +WARNING: We invoke pip with the --break-system-packages flag, because some +debuggers that embed Python (gdb, lldb) may not support virtual environments, +and so the packages must be installed to your user environment. + +NOTE: This will copy Python wheels into the HOME directory of the user on the +remote system. You may be prompted to authenticate a few times while packages +are copied and installed. + +NOTE: Automatic resolution will cause this session to terminate. When it has +finished, try launching again. +"@ "Would you like to install 'ghidradbg>=$version'?" + +if ($answer) { + Write-Host "Copying Wheels to $Env:OPT_HOST" + Mitigate-Scp-PyModules "Debugger-rmi-trace" "" + + Write-Host "Installing Wheels into python" + $arglist = Compute-Dbg-PipInstall-Args "'-f'" "os.environ['HOME']" "'ghidradbg>=$version'" + $sshargs = Compute-Ssh-Args $arglist False + Start-Process -FilePath $sshargs[0] -ArgumentList $sshargs[1..$sshargs.Count] -NoNewWindow -Wait +} diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/ssh-dbgeng.ps1 b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/ssh-dbgeng.ps1 new file mode 100644 index 0000000000..35837b3ffd --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/ssh-dbgeng.ps1 @@ -0,0 +1,105 @@ +## ### +# 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. +## +#@title dbgeng via ssh +#@image-opt env:OPT_TARGET_IMG +#@desc +#@desc

Launch with dbgeng via ssh

+#@desc

+#@desc This will start dbgeng on the remote system via a Python interpreter. +#@desc For setup instructions, press F1. +#@desc

+#@desc +#@menu-group dbgeng +#@icon icon.debugger +#@help dbgeng#ssh +#@depends Debugger-rmi-trace +#@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_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_PYTHON_EXE:file!="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH." +#@env OPT_PYTHON_ARGS:str="" "python cmd args" "Arguments passed to python (versus the target)" +#@env OPT_USE_DBGMODEL:bool=true "Use dbgmodel" "Load and use dbgmodel.dll if it is available." + +. ..\support\dbgsetuputils.ps1 + +function Compute-Python-Args { + param($TempFile) + + $arglist = @("$Env:OPT_PYTHON_EXE") + if ("$Env:OPT_PYTHON_ARGS" -ne "") { + $arglist+=($Env:OPT_PYTHON_ARGS) + } + $arglist+=($TempFile) + + $arglist+=("localhost:$Env:OPT_REMOTE_PORT") + $arglist+=($Env:OPT_USE_DBGMODEL) + $arglist+=($Env:OPT_TARGET_IMG) + + if ("$Env:OPT_TARGET_ARGS" -ne "") { + $arglist+=($Env:OPT_TARGET_ARGS) + } + return $arglist +} + +$tmpfile = "local-dbgeng.py" +$arglist = Compute-Python-Args -TempFile $tmpfile + +$scpargs = Compute-Scp-Args "..\support\$tmpfile" +$sshargs = Compute-Ssh-Args $arglist True + +$scpproc = Start-Process -FilePath $scpargs[0] -ArgumentList $scpargs[1..$scpargs.Count] -NoNewWindow -Wait -PassThru +$sshproc = Start-Process -FilePath $sshargs[0] -ArgumentList $sshargs[1..$sshargs.Count] -NoNewWindow -Wait -PassThru + +$version = Get-Ghidra-Version +$answer = Check-Result-And-Prompt-Mitigation $sshproc @" +It appears ghidradbg is missing from the remote system. This can happen if you +forgot to install the required package. This can also happen if you installed +the packages to a different Python environment than is being used by the +remote's gdb. + +This script is about to offer automatic resolution. If you'd like to resolve +this manually, answer no to the next question and then see Ghidra's help by +pressing F1 in the dialog of launch parameters. + +WARNING: Answering yes to the next question will invoke pip to try to install +missing or incorrectly-versioned dependencies. It may attempt to find packages +from the PyPI mirror configured on the REMOTE system. If you have not configured +one, it will connect to the official one. + +WARNING: We invoke pip with the --break-system-packages flag, because some +debuggers that embed Python (gdb, lldb) may not support virtual environments, +and so the packages must be installed to your user environment. + +NOTE: This will copy Python wheels into the HOME directory of the user on the +remote system. You may be prompted to authenticate a few times while packages +are copied and installed. + +NOTE: Automatic resolution will cause this session to terminate. When it has +finished, try launching again. +"@ "Would you like to install 'ghidradbg>=$version'?" + +if ($answer) { + Write-Host "Copying Wheels to $Env:OPT_HOST" + Mitigate-Scp-PyModules "Debugger-rmi-trace" "" + + Write-Host "Installing Wheels into python" + $arglist = Compute-Dbg-PipInstall-Args "'-f'" "os.environ['HOME']" "'ghidradbg>=$version'" + $sshargs = Compute-Ssh-Args $arglist False + Start-Process -FilePath $sshargs[0] -ArgumentList $sshargs[1..$sshargs.Count] -NoNewWindow -Wait +} diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/data/support/dbgsetuputils.ps1 b/Ghidra/Debug/Debugger-agent-dbgeng/data/support/dbgsetuputils.ps1 new file mode 100644 index 0000000000..a9181ae5e8 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-dbgeng/data/support/dbgsetuputils.ps1 @@ -0,0 +1,27 @@ +## ### +# 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. +## +. $Env:MODULE_Debugger_rmi_trace_HOME\data\support\setuputils.ps1 + +function Compute-Dbg-PipInstall-Args { + $argvpart = $args -join ", " + $arglist = @("$Env:OPT_PYTHON_EXE -c `"") + $arglist+=("import os, sys, runpy") + $arglist+=("sys.argv=['pip', 'install', '--force-reinstall', $argvpart]") + $arglist+=("os.environ['PIP_BREAK_SYSTEM_PACKAGE']='1'") + $arglist+=("runpy.run_module('pip', run_name='__main__')") + + return $arglist +} diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/data/support/local-dbgeng-attach.py b/Ghidra/Debug/Debugger-agent-dbgeng/data/support/local-dbgeng-attach.py index f4c9eb6231..ff0222ff8b 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/data/support/local-dbgeng-attach.py +++ b/Ghidra/Debug/Debugger-agent-dbgeng/data/support/local-dbgeng-attach.py @@ -17,13 +17,36 @@ import os import sys +cxn = os.getenv('GHIDRA_TRACE_RMI_ADDR') +target = os.getenv('OPT_TARGET_PID') +args = os.getenv('OPT_ATTACH_FLAGS') + +def parse_parameters(): + global cxn, target, args + os.environ['OPT_OS_WINDOWS'] = "true" + argc = len(sys.argv) + if argc == 1: + return True + if argc >= 4: + cxn = sys.argv[1] + os.environ['OPT_USE_DBGMODEL'] = sys.argv[2] + target = sys.argv[3] + if argc > 4: + args = sys.argv[4] + return True + print("Error: expected (cxn, use_dbgmodel, target, ...)") + return False + def append_paths(): sys.path.append( f"{os.getenv('MODULE_Debugger_rmi_trace_HOME')}/data/support") - from gmodutils import ghidra_module_pypath - sys.path.append(ghidra_module_pypath("Debugger-rmi-trace")) - sys.path.append(ghidra_module_pypath()) + try: + from gmodutils import ghidra_module_pypath + sys.path.append(ghidra_module_pypath("Debugger-rmi-trace")) + sys.path.append(ghidra_module_pypath()) + except Exception as e: + pass def main(): @@ -38,10 +61,8 @@ def main(): global repl repl = cmd.repl - cmd.ghidra_trace_connect(os.getenv('GHIDRA_TRACE_RMI_ADDR')) - flags = os.getenv('OPT_ATTACH_FLAGS') - cmd.ghidra_trace_attach( - os.getenv('OPT_TARGET_PID'), flags, start_trace=False) + cmd.ghidra_trace_connect(cxn) + cmd.ghidra_trace_attach(target, args, start_trace=False) # TODO: HACK try: @@ -49,7 +70,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, 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 99b878b101..8c2016210f 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/data/support/local-dbgeng.py +++ b/Ghidra/Debug/Debugger-agent-dbgeng/data/support/local-dbgeng.py @@ -17,17 +17,44 @@ import os import sys +cxn = os.getenv('GHIDRA_TRACE_RMI_ADDR') +target = os.getenv('OPT_TARGET_IMG') +args = os.getenv('OPT_TARGET_ARGS') + +def parse_parameters(): + global cxn, target, args + os.environ['OPT_OS_WINDOWS'] = "true" + argc = len(sys.argv) + if argc == 1: + return True + if argc >= 4: + cxn = sys.argv[1] + os.environ['OPT_USE_DBGMODEL'] = sys.argv[2] + target = sys.argv[3] + if argc > 4: + args = sys.argv[4] + return True + print("Error: expected (cxn, use_dbgmodel, target, ...)") + return False + def append_paths(): sys.path.append( f"{os.getenv('MODULE_Debugger_rmi_trace_HOME')}/data/support") - from gmodutils import ghidra_module_pypath - sys.path.append(ghidra_module_pypath("Debugger-rmi-trace")) - sys.path.append(ghidra_module_pypath()) + try: + from gmodutils import ghidra_module_pypath + sys.path.append(ghidra_module_pypath("Debugger-rmi-trace")) + sys.path.append(ghidra_module_pypath()) + except Exception as e: + pass def main(): + global cxn, target, args append_paths() + if parse_parameters() is False: + return + # Delay these imports until sys.path is patched from ghidradbg import commands as cmd from pybag.dbgeng import core as DbgEng @@ -38,17 +65,15 @@ def main(): global repl repl = cmd.repl - cmd.ghidra_trace_connect(os.getenv('GHIDRA_TRACE_RMI_ADDR')) - args = os.getenv('OPT_TARGET_ARGS') - if args: - args = ' ' + args - target = os.getenv('OPT_TARGET_IMG') + cmd.ghidra_trace_connect(cxn) 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) + if args: + target = target + ' ' + args + cmd.ghidra_trace_create(target, start_trace=False) # TODO: HACK try: diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/help/help/TOC_Source.xml b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/help/help/TOC_Source.xml index 3f4fed1048..a6553a74e0 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/help/help/TOC_Source.xml +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/help/help/TOC_Source.xml @@ -17,6 +17,9 @@ + + diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/help/help/topics/dbgeng/dbgeng.html b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/help/help/topics/dbgeng/dbgeng.html index 9596589755..c13e013a87 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/help/help/topics/dbgeng/dbgeng.html +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/help/help/topics/dbgeng/dbgeng.html @@ -170,7 +170,35 @@ python3 -m pip install --no-index -f Debugger-rmi-trace\pypkg\dist -f Debugger-a -

Process Server

+

Remote via SSH

+ +

"ssh-dbgeng" is the remote equivalent to "dbgeng"; + "ssh-dbgeng-attach" is the remote equivalent to "dbgeng-attach". +

+ +

Setup

+ +

Instructions are indentical to those above but executed on the remote machine.

+ +

Additional Options

+ +
    +
  • ssh command: The ssh command to execute, optionaly with full path.
  • + +
  • [User@]Host: This is the host name of the target system, optionally including a + user name. This is passed as is to ssh, which may interpret it according to local + configuration.
  • + +
  • Remote Trace RMI Port: An available TCP port on the target system, which will + listen for dbgeng's Trace RMI connection and forward it back to Ghidra.
  • + +
  • Extra ssh arguments: These are extra arguments to pass to ssh. + They are inserted immediately after the ssh command but before the host name. Beware + that syntax errors may cause strange behavior, and that not all features may be compatible + with this launcher.
  • +
+ +

Process Server

The "dbgeng-svrcx" launcher extends the base dbgeng launcher adding an option for connecting through a remote process server.

diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/local-x64dbg.bat b/Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/local-x64dbg.bat index 73d5c1e8fd..79185f0158 100644 --- a/Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/local-x64dbg.bat +++ b/Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/local-x64dbg.bat @@ -13,7 +13,7 @@ :: See the License for the specific language governing permissions and :: limitations under the License. :: ## -::@title x64dbg +::@title x64dbg (.bat) ::@image-opt env:OPT_TARGET_IMG ::@desc ::@desc

Launch with x64dbg (in a Python interpreter)

diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/local-x64dbg.ps1 b/Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/local-x64dbg.ps1 new file mode 100644 index 0000000000..89ee5794bb --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/local-x64dbg.ps1 @@ -0,0 +1,68 @@ +## ### +# 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. +## +#@title x64dbg (.ps1) +#@image-opt env:OPT_TARGET_IMG +#@desc +#@desc

Launch with x64dbg

+#@desc

+#@desc This will launch the target on the local machine using x64dbg.dll. +#@desc For setup instructions, press F1. +#@desc

+#@desc +#@menu-group x64dbg +#@icon icon.debugger +#@help x64dbg#local +#@depends Debugger-rmi-trace +#@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_TARGET_DIR:str="" "Dir" "Initial directory" +#@env OPT_X64DBG_EXE:file="C:\\Software\\release\\x64\\x64dbg.exe" "Path to x64dbg.exe" "Path to x64dbg.exe (or equivalent)." +#@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." +#@env OPT_PYTHON_ARGS:str="" "python cmd args" "Arguments passed to python (versus the target)" + +. ..\support\x64dbgsetuputils.ps1 + +function Compute-Python-Args { + param($TempFile) + + $arglist = @("$Env:OPT_PYTHON_EXE") + if ("$Env:OPT_PYTHON_ARGS" -ne "") { + $arglist+=($Env:OPT_PYTHON_ARGS) + } + $arglist+=($TempFile) + + $arglist+=($Env:GHIDRA_TRACE_RMI_ADDR) + if ("$Env:OPT_TARGET_IMG" -ne "") { + $arglist+=($Env:OPT_TARGET_IMG) + } + if ("$Env:OPT_TARGET_DIR" -ne "") { + $arglist+=($Env:OPT_TARGET_DIR) + } + if ("$Env:OPT_TARGET_ARGS" -ne "") { + $arglist+=($Env:OPT_TARGET_ARGS) + } + return $arglist +} + +$pypathTrace = Ghidra-Module-PyPath "Debugger-rmi-trace" +$pypathDbg = Ghidra-Module-PyPath +$Env:PYTHONPATH = "$pypathDbg;$pypathTrace;$Env:PYTHONPATH" + +$tmpfile = "..\support\local-x64dbg.py" +$arglist = Compute-Python-Args -TempFile $tmpfile + +Start-Process -FilePath $arglist[0] -ArgumentList $arglist[1..$arglist.Count] ` + -NoNewWindow -Wait diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/ssh-x64dbg-attach.ps1 b/Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/ssh-x64dbg-attach.ps1 new file mode 100644 index 0000000000..e7dbce57a8 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/ssh-x64dbg-attach.ps1 @@ -0,0 +1,105 @@ +## ### +# 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. +## +#@title x64dbg attach via ssh +#@desc +#@desc

Attach with x64dbg via ssh

+#@desc

+#@desc This will attach to a running target on the rempote machine using x64dbg.dll. +#@desc For setup instructions, press F1. +#@desc

+#@desc +#@menu-group x64dbg +#@icon icon.debugger +#@help x64dbg#ssh +#@depends Debugger-rmi-trace +#@env OPT_TARGET_PID:int=0 "Process id" "The target process id" +#@env OPT_TARGET_DIR:str="" "Dir" "Initial directory" +#@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_X64DBG_EXE:file="C:\\Software\\release\\x64\\x64dbg.exe" "Path to x64dbg.exe" "Path to x64dbg.exe (or equivalent)." +#@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." +#@env OPT_PYTHON_ARGS:str="" "python cmd args" "Arguments passed to python (versus the target)" + +. ..\support\x64dbgsetuputils.ps1 + +function Compute-Python-Args { + param($TempFile) + + $arglist = @("$Env:OPT_PYTHON_EXE") + if ("$Env:OPT_PYTHON_ARGS" -ne "") { + $arglist+=($Env:OPT_PYTHON_ARGS) + } + $arglist+=($TempFile) + if ("$Env:OPT_REMOTE_PORT" -ne "") { + $arglist+=("localhost:$Env:OPT_REMOTE_PORT") + } + else { + $arglist+=($Env:GHIDRA_TRACE_RMI_ADDR) + } + + $arglist+=($Env:OPT_TARGET_PID) + + return $arglist +} + +$tmpfile = "local-x64dbg-attach.py" +$arglist = Compute-Python-Args -TempFile $tmpfile + +$scpargs = Compute-Scp-Args "..\support\$tmpfile" +$sshargs = Compute-Ssh-Args $arglist True + +$scpproc = Start-Process -FilePath $scpargs[0] -ArgumentList $scpargs[1..$scpargs.Count] -NoNewWindow -Wait -PassThru +$sshproc = Start-Process -FilePath $sshargs[0] -ArgumentList $sshargs[1..$sshargs.Count] -NoNewWindow -Wait -PassThru + +$version = Get-Ghidra-Version +$answer = Check-Result-And-Prompt-Mitigation $sshproc @" +It appears ghidradbg is missing from the remote system. This can happen if you +forgot to install the required package. This can also happen if you installed +the packages to a different Python environment than is being used by the +remote's gdb. + +This script is about to offer automatic resolution. If you'd like to resolve +this manually, answer no to the next question and then see Ghidra's help by +pressing F1 in the dialog of launch parameters. + +WARNING: Answering yes to the next question will invoke pip to try to install +missing or incorrectly-versioned dependencies. It may attempt to find packages +from the PyPI mirror configured on the REMOTE system. If you have not configured +one, it will connect to the official one. + +WARNING: We invoke pip with the --break-system-packages flag, because some +debuggers that embed Python (gdb, lldb) may not support virtual environments, +and so the packages must be installed to your user environment. + +NOTE: This will copy Python wheels into the HOME directory of the user on the +remote system. You may be prompted to authenticate a few times while packages +are copied and installed. + +NOTE: Automatic resolution will cause this session to terminate. When it has +finished, try launching again. +"@ "Would you like to install 'ghidradbg>=$version'?" + +if ($answer) { + Write-Host "Copying Wheels to $Env:OPT_HOST" + Mitigate-Scp-PyModules "Debugger-rmi-trace" "" + + Write-Host "Installing Wheels into python" + $arglist = Compute-Dbg-PipInstall-Args "'-f'" "os.environ['HOME']" "'ghidradbg>=$version'" + $sshargs = Compute-Ssh-Args $arglist False + Start-Process -FilePath $sshargs[0] -ArgumentList $sshargs[1..$sshargs.Count] -NoNewWindow -Wait +} diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/ssh-x64dbg.ps1 b/Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/ssh-x64dbg.ps1 new file mode 100644 index 0000000000..f1336d3be3 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/ssh-x64dbg.ps1 @@ -0,0 +1,114 @@ +## ### +# 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. +## +#@title x64dbg via ssh +#@image-opt env:OPT_TARGET_IMG +#@desc +#@desc

Launch with x64dbg via ssh

+#@desc

+#@desc This will start x64dbg on the remote system via a Python interpreter. +#@desc For setup instructions, press F1. +#@desc

+#@desc +#@menu-group x64dbg +#@icon icon.debugger +#@help x64dbg#ssh +#@depends Debugger-rmi-trace +#@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_TARGET_DIR:str="" "Dir" "Initial directory" +#@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_X64DBG_EXE:file="C:\\Software\\release\\x64\\x64dbg.exe" "Path to x64dbg.exe" "Path to x64dbg.exe (or equivalent)." +#@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." +#@env OPT_PYTHON_ARGS:str="" "python cmd args" "Arguments passed to python (versus the target)" + +. ..\support\x64dbgsetuputils.ps1 + +function Compute-Python-Args { + param($TempFile) + + $arglist = @("$Env:OPT_PYTHON_EXE") + if ("$Env:OPT_PYTHON_ARGS" -ne "") { + $arglist+=($Env:OPT_PYTHON_ARGS) + } + $arglist+=($TempFile) + if ("$Env:OPT_REMOTE_PORT" -ne "") { + $arglist+=("localhost:$Env:OPT_REMOTE_PORT") + } + else { + $arglist+=($Env:GHIDRA_TRACE_RMI_ADDR) + } + + if ("$Env:OPT_TARGET_IMG" -ne "") { + $arglist+=($Env:OPT_TARGET_IMG) + } + if ("$Env:OPT_TARGET_DIR" -ne "") { + $arglist+=($Env:OPT_TARGET_DIR) + } + if ("$Env:OPT_TARGET_ARGS" -ne "") { + $arglist+=($Env:OPT_TARGET_ARGS) + } + return $arglist +} + +$tmpfile = "local-x64dbg.py" +$arglist = Compute-Python-Args -TempFile $tmpfile + +$scpargs = Compute-Scp-Args "..\support\$tmpfile" +$sshargs = Compute-Ssh-Args $arglist True + +$scpproc = Start-Process -FilePath $scpargs[0] -ArgumentList $scpargs[1..$scpargs.Count] -NoNewWindow -Wait -PassThru +$sshproc = Start-Process -FilePath $sshargs[0] -ArgumentList $sshargs[1..$sshargs.Count] -NoNewWindow -Wait -PassThru + +$version = Get-Ghidra-Version +$answer = Check-Result-And-Prompt-Mitigation $sshproc @" +It appears ghidradbg is missing from the remote system. This can happen if you +forgot to install the required package. This can also happen if you installed +the packages to a different Python environment than is being used by the +remote's gdb. + +This script is about to offer automatic resolution. If you'd like to resolve +this manually, answer no to the next question and then see Ghidra's help by +pressing F1 in the dialog of launch parameters. + +WARNING: Answering yes to the next question will invoke pip to try to install +missing or incorrectly-versioned dependencies. It may attempt to find packages +from the PyPI mirror configured on the REMOTE system. If you have not configured +one, it will connect to the official one. + +WARNING: We invoke pip with the --break-system-packages flag, because some +debuggers that embed Python (gdb, lldb) may not support virtual environments, +and so the packages must be installed to your user environment. + +NOTE: This will copy Python wheels into the HOME directory of the user on the +remote system. You may be prompted to authenticate a few times while packages +are copied and installed. + +NOTE: Automatic resolution will cause this session to terminate. When it has +finished, try launching again. +"@ "Would you like to install 'ghidradbg>=$version'?" + +if ($answer) { + Write-Host "Copying Wheels to $Env:OPT_HOST" + Mitigate-Scp-PyModules "Debugger-rmi-trace" "" + + Write-Host "Installing Wheels into python" + $arglist = Compute-Dbg-PipInstall-Args "'-f'" "os.environ['HOME']" "'ghidradbg>=$version'" + $sshargs = Compute-Ssh-Args $arglist False + Start-Process -FilePath $sshargs[0] -ArgumentList $sshargs[1..$sshargs.Count] -NoNewWindow -Wait +} diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/data/support/local-x64dbg-attach.py b/Ghidra/Debug/Debugger-agent-x64dbg/data/support/local-x64dbg-attach.py index 5885d3e8b6..b5845cfb89 100644 --- a/Ghidra/Debug/Debugger-agent-x64dbg/data/support/local-x64dbg-attach.py +++ b/Ghidra/Debug/Debugger-agent-x64dbg/data/support/local-x64dbg-attach.py @@ -17,13 +17,32 @@ import os import sys +cxn = os.getenv('GHIDRA_TRACE_RMI_ADDR') +target = os.getenv('OPT_TARGET_PID') + + +def parse_parameters(): + argc = len(sys.argv) + global cxn, target, args, initdir + if argc == 1: + return True + if argc >= 3: + cxn = sys.argv[1] + target = sys.argv[2] + return True + print("Error: expected (cxn, target, initdir, ...)") + return False + def append_paths(): sys.path.append( f"{os.getenv('MODULE_Debugger_rmi_trace_HOME')}/data/support") - from gmodutils import ghidra_module_pypath - sys.path.append(ghidra_module_pypath("Debugger-rmi-trace")) - sys.path.append(ghidra_module_pypath()) + try: + from gmodutils import ghidra_module_pypath + sys.path.append(ghidra_module_pypath("Debugger-rmi-trace")) + sys.path.append(ghidra_module_pypath()) + except Exception as e: + pass def main(): @@ -37,15 +56,15 @@ def main(): global repl repl = cmd.repl - cmd.ghidra_trace_connect(os.getenv('GHIDRA_TRACE_RMI_ADDR')) - cmd.ghidra_trace_attach(os.getenv('OPT_TARGET_PID'), start_trace=False) + cmd.ghidra_trace_connect(cxn) + cmd.ghidra_trace_attach(target, start_trace=False) try: dbg.wait() except KeyboardInterrupt as ki: dbg.interrupt() - cmd.ghidra_trace_start(os.getenv('OPT_TARGET_PID')) + cmd.ghidra_trace_start(target) cmd.ghidra_trace_sync_enable() cmd.ghidra_trace_txstart() diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/data/support/local-x64dbg.py b/Ghidra/Debug/Debugger-agent-x64dbg/data/support/local-x64dbg.py index c93ecfc8c5..9222e660b7 100644 --- a/Ghidra/Debug/Debugger-agent-x64dbg/data/support/local-x64dbg.py +++ b/Ghidra/Debug/Debugger-agent-x64dbg/data/support/local-x64dbg.py @@ -18,16 +18,51 @@ import os import sys +cxn = os.getenv('GHIDRA_TRACE_RMI_ADDR') +target = os.getenv('OPT_TARGET_IMG') +args = os.getenv('OPT_TARGET_ARGS') +initdir = os.getenv('OPT_TARGET_DIR') + + +def parse_parameters(): + global cxn, target, args, initdir + os.environ['OPT_OS_WINDOWS'] = "true" + argc = len(sys.argv) + if argc == 1: + return True + if argc >= 3: + cxn = sys.argv[1] + target = sys.argv[2] + if argc > 4: + initdir = sys.argv[3] + else: + initdir = "." + if argc > 4: + args = sys.argv[4] + else: + args = "" + return True + print("Error: expected (cxn, target, initdir, ...)") + return False + + def append_paths(): sys.path.append( f"{os.getenv('MODULE_Debugger_rmi_trace_HOME')}/data/support") - from gmodutils import ghidra_module_pypath - sys.path.append(ghidra_module_pypath("Debugger-rmi-trace")) - sys.path.append(ghidra_module_pypath()) + try: + from gmodutils import ghidra_module_pypath + sys.path.append(ghidra_module_pypath("Debugger-rmi-trace")) + sys.path.append(ghidra_module_pypath()) + except Exception as e: + pass def main(): + global cxn, target, args, initdir append_paths() + if parse_parameters() is False: + return + # Delay these imports until sys.path is patched from ghidraxdbg import commands as cmd from ghidraxdbg.hooks import on_state_changed @@ -37,10 +72,7 @@ def main(): global repl repl = cmd.repl - cmd.ghidra_trace_connect(os.getenv('GHIDRA_TRACE_RMI_ADDR')) - args = os.getenv('OPT_TARGET_ARGS') - initdir = os.getenv('OPT_TARGET_DIR') - target = os.getenv('OPT_TARGET_IMG') + cmd.ghidra_trace_connect(cxn) cmd.ghidra_trace_create(target, args=args, initdir=initdir, start_trace=False) diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/data/support/x64dbgsetuputils.ps1 b/Ghidra/Debug/Debugger-agent-x64dbg/data/support/x64dbgsetuputils.ps1 new file mode 100644 index 0000000000..25d7388d65 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-x64dbg/data/support/x64dbgsetuputils.ps1 @@ -0,0 +1,27 @@ +## ### +# 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. +## +. $Env:MODULE_Debugger_rmi_trace_HOME\data\support\setuputils.ps1 + +function Compute-X64dbg-PipInstall-Args { + $argvpart = $args -join ", " + $arglist = @("$Env:OPT_PYTHON_EXE -c `"") + $arglist+=("import os, sys, runpy") + $arglist+=("sys.argv=['pip', 'install', '--force-reinstall', $argvpart]") + $arglist+=("os.environ['PIP_BREAK_SYSTEM_PACKAGE']='1'") + $arglist+=("runpy.run_module('pip', run_name='__main__')") + + return $arglist +} diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/src/main/help/help/TOC_Source.xml b/Ghidra/Debug/Debugger-agent-x64dbg/src/main/help/help/TOC_Source.xml index 72360c1bea..28a08df927 100644 --- a/Ghidra/Debug/Debugger-agent-x64dbg/src/main/help/help/TOC_Source.xml +++ b/Ghidra/Debug/Debugger-agent-x64dbg/src/main/help/help/TOC_Source.xml @@ -11,6 +11,9 @@ + + diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/src/main/help/help/topics/x64dbg/x64dbg.html b/Ghidra/Debug/Debugger-agent-x64dbg/src/main/help/help/topics/x64dbg/x64dbg.html index bcaa0eceff..d90babca13 100644 --- a/Ghidra/Debug/Debugger-agent-x64dbg/src/main/help/help/topics/x64dbg/x64dbg.html +++ b/Ghidra/Debug/Debugger-agent-x64dbg/src/main/help/help/topics/x64dbg/x64dbg.html @@ -19,7 +19,7 @@ debugger launches a full x64dbg session by default, synchronized with the Ghidra debugger UI.

-

Two launchers are included out of the box, one for a local process and one for a local pid:

+

Local launchers are included, one for a local process and one for a local pid, and ssh equivalents:

Local

@@ -95,8 +95,33 @@ python3 -m pip install --no-index -f Debugger-rmi-trace\pypkg\dist -f Debugger-a

Options

-
    +
    • ProcessId: The pid of the process you wish to attach to.
    • +
    +

    Remote via SSH

    + +

    "ssh-x64dbg" is the remote equivalent to "x64dbg"; + "ssh-x64dbg-attach" is the remote equivalent to "x64dbg-attach". +

    + +

    Setup

    + +

    Instructions are indentical to those above but executed on the remote machine.

    + +
      +
    • ssh command: The ssh command to execute, optionaly with full path.
    • +
    • [User@]Host: This is the host name of the target system, optionally including a + user name. This is passed as is to ssh, which may interpret it according to local + configuration.
    • + +
    • Remote Trace RMI Port: An available TCP port on the target system, which will + listen for x64dbg's Trace RMI connection and forward it back to Ghidra.
    • + +
    • Extra ssh arguments: These are extra arguments to pass to ssh. + They are inserted immediately after the ssh command but before the host name. Beware + that syntax errors may cause strange behavior, and that not all features may be compatible + with this launcher.
    • +
    diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/hooks.py b/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/hooks.py index c8c53fd279..8ea5f31b33 100644 --- a/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/hooks.py +++ b/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/hooks.py @@ -161,6 +161,7 @@ def log_errors(func: C) -> C: def on_state_changed(*args) -> None: # print("ON_STATE_CHANGED") ev_type = args[0].event_type + ev_data = args[0].event_data # print(ev_type) proc = util.selected_process() trace = commands.STATE.require_trace() @@ -168,8 +169,11 @@ def on_state_changed(*args) -> None: with trace.open_tx("State changed proc {}".format(proc)): commands.put_state(proc) if proc not in PROC_STATE: + if ev_type == EventType.EVENT_CREATE_PROCESS: + enable_current_process() + on_new_process(ev_data) if ev_type == EventType.EVENT_EXIT_PROCESS: - on_process_deleted(args) + on_process_deleted(ev_data) return PROC_STATE[proc].waiting = False try: @@ -183,7 +187,7 @@ def on_state_changed(*args) -> None: @log_errors def on_breakpoint_hit(*args) -> None: - # print("ON_THREADS_CHANGED") + # print("ON_BREAKPOINT_HIT") proc = util.selected_process() if proc not in PROC_STATE: return @@ -218,10 +222,10 @@ def on_process_selected() -> None: @log_errors -def on_process_deleted(*args) -> None: +def on_process_deleted(ev_data) -> None: # print("PROCESS_DELETED: args={}".format(args)) proc = util.selected_process() - on_exited(args) + on_exited(ev_data) if proc in PROC_STATE: del PROC_STATE[proc] trace = commands.STATE.trace @@ -341,7 +345,7 @@ def on_stop(*args) -> None: commands.activate() -def on_exited(*args) -> None: +def on_exited(exit_process_data) -> None: # print("ON EXITED") trace = commands.STATE.trace if trace is None: @@ -350,7 +354,7 @@ def on_exited(*args) -> None: state.visited.clear() with trace.client.batch(): with trace.open_tx("Exited"): - exit_code = args[0][0].event_data.dwExitCode + exit_code = exit_process_data.dwExitCode state.record_exited(exit_code) commands.activate() diff --git a/Ghidra/Debug/Debugger-rmi-trace/data/support/setuputils.ps1 b/Ghidra/Debug/Debugger-rmi-trace/data/support/setuputils.ps1 index f2454b9db0..5c39b5990e 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/data/support/setuputils.ps1 +++ b/Ghidra/Debug/Debugger-rmi-trace/data/support/setuputils.ps1 @@ -78,11 +78,25 @@ function Compute-Ssh-Args { if ("$Env:OPT_EXTRA_SSH_ARGS" -ne "") { $sshargs+=("$Env:OPT_EXTRA_SSH_ARGS") } - $sshargs+=("$Env:OPT_HOST", "TERM='$Env:TERM' $cmdline") + $sshargs+=("$Env:OPT_HOST") + if ("$Env:OPT_OS_WINDOWS" -ne "") { + $sshargs+=("TERM='$Env:TERM'") + } + $sshargs+=($cmdline) return $sshargs } +function Compute-Scp-Args { + $tmpfile = $args[0] + + $scpargs = @($Env:OPT_SSH_PATH -replace "ssh", "scp") + $scpargs += ($tmpfile) + $scpargs+=("$Env:OPT_HOST`:~/") + + return $scpargs +} + function Check-Result-And-Prompt-Mitigation { $proc = $args[0] $msg = $args[1] diff --git a/Ghidra/Debug/Debugger-rmi-trace/data/support/setuputils.sh b/Ghidra/Debug/Debugger-rmi-trace/data/support/setuputils.sh index 4ea39f702d..fd0bdf8890 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/data/support/setuputils.sh +++ b/Ghidra/Debug/Debugger-rmi-trace/data/support/setuputils.sh @@ -98,7 +98,11 @@ compute-ssh-args() { sshargs+=($OPT_EXTRA_SSH_ARGS) fi sshargs+=("$OPT_HOST") - sshargs+=("TERM='$TERM' $qargs") + if [ "$OPT_OS_WINDOWS" ] && [ "$OPT_OS_WINDOWS" == true ]; then + sshargs+=("$@") + else + sshargs+=("TERM='$TERM' $qargs") + fi } check-result-and-prompt-mitigation() {