mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-08-08 07:40:39 -09:00
GP-6966: fix for tests
GP-6966: post-review GP-6966: in review GP-6966: not all tests pass, but... GP-6966: better messaging GP-6966: mods for x64dbg GP-6966: docs (GP-6972) GP-6966: fixes for linux->windows GP-6966: fix for exit; fix for WINDBG_DIR
This commit is contained in:
@@ -31,7 +31,7 @@
|
||||
#@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)."
|
||||
#@env WINDBG_DIR:dir="C:\Windows\System32" "Path to dbgeng.dll directory" "Path containing dbgeng and associated DLLS (if not Windows Kits)."
|
||||
|
||||
. ..\support\dbgsetuputils.ps1
|
||||
|
||||
@@ -47,6 +47,7 @@ function Compute-Python-Args {
|
||||
|
||||
$arglist+=($Env:GHIDRA_TRACE_RMI_ADDR)
|
||||
$arglist+=($Env:OPT_USE_DBGMODEL)
|
||||
$arglist+=($Env:WINDBG_DIR)
|
||||
$arglist+=($Env:OPT_TARGET_IMG)
|
||||
|
||||
if ("$Env:OPT_TARGET_ARGS" -ne "") {
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#@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="C:\Windows\System32" "Path to dbgeng.dll directory" "Path containing dbgeng and associated DLLS (if not Windows Kits)."
|
||||
|
||||
. ..\support\dbgsetuputils.ps1
|
||||
|
||||
@@ -49,6 +50,7 @@ function Compute-Python-Args {
|
||||
|
||||
$arglist+=("localhost:$Env:OPT_REMOTE_PORT")
|
||||
$arglist+=($Env:OPT_USE_DBGMODEL)
|
||||
$arglist+=($Env:WINDBG_DIR)
|
||||
$arglist+=($Env:OPT_TARGET_PID)
|
||||
$arglist+=($Env:OPT_ATTACH_FLAGS)
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
# limitations under the License.
|
||||
##
|
||||
#@title dbgeng attach via ssh (shell)
|
||||
#@image-opt arg:1
|
||||
#@desc <html><body width="300px">
|
||||
#@desc <h3>Launch with <tt>dbgeng</tt> via <tt>ssh</tt></h3>
|
||||
#@desc <p>
|
||||
@@ -36,11 +35,10 @@
|
||||
#@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="C:\\Windows\\System32" "Path to dbgeng.dll directory" "Path containing dbgeng and associated DLLS (if not Windows Kits)."
|
||||
|
||||
. ../support/dbgsetuputils.sh
|
||||
|
||||
target_image=$(echo $OPT_TARGET_IMG | sed 's/\\/\\\\/g')
|
||||
|
||||
OPT_OS_WINDOWS=true
|
||||
|
||||
function launch-dbg-scp() {
|
||||
@@ -52,7 +50,7 @@ function launch-dbg-scp() {
|
||||
|
||||
function launch-dbg-ssh() {
|
||||
local -a sshargs
|
||||
compute-ssh-args true "$OPT_PYTHON_EXE -i $OPT_PYTHON_ARGS .\\local-dbgeng-attach.py localhost:$OPT_REMOTE_PORT $OPT_USE_DBGMODEL $OPT_TARGET_PID $OPT_ATTACH_FLAGS"
|
||||
compute-ssh-args true "$OPT_PYTHON_EXE -i $OPT_PYTHON_ARGS .\\local-dbgeng-attach.py localhost:$OPT_REMOTE_PORT $OPT_USE_DBGMODEL $WINDBG_DIR $OPT_TARGET_PID $OPT_ATTACH_FLAGS"
|
||||
|
||||
"${sshargs[@]}"
|
||||
}
|
||||
@@ -98,7 +96,9 @@ finished, try launching again.
|
||||
" "Would you like to install 'ghidradbg>=$version'?"; then
|
||||
|
||||
echo "Copying Wheels to $OPT_HOST"
|
||||
mitigate-scp-pymodules "Debugger-rmi-trace" "<SELF>"
|
||||
if ! mitigate-scp-pymodules "Debugger-rmi-trace" "<SELF>"; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installing Wheels into Python"
|
||||
do-installation
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#@icon icon.debugger
|
||||
#@help dbgeng#ssh
|
||||
#@depends Debugger-rmi-trace
|
||||
#@env OPT_TARGET_IMG:file="" "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_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"
|
||||
@@ -35,6 +35,7 @@
|
||||
#@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="C:\Windows\System32" "Path to dbgeng.dll directory" "Path containing dbgeng and associated DLLS (if not Windows Kits)."
|
||||
|
||||
. ..\support\dbgsetuputils.ps1
|
||||
|
||||
@@ -50,6 +51,7 @@ function Compute-Python-Args {
|
||||
|
||||
$arglist+=("localhost:$Env:OPT_REMOTE_PORT")
|
||||
$arglist+=($Env:OPT_USE_DBGMODEL)
|
||||
$arglist+=($Env:WINDBG_DIR)
|
||||
$arglist+=($Env:OPT_TARGET_IMG)
|
||||
|
||||
if ("$Env:OPT_TARGET_ARGS" -ne "") {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
# limitations under the License.
|
||||
##
|
||||
#@title dbgeng via ssh (shell)
|
||||
#@image-opt arg:1
|
||||
#@image-opt env:OPT_TARGET_IMG
|
||||
#@desc <html><body width="300px">
|
||||
#@desc <h3>Launch with <tt>dbgeng</tt> via <tt>ssh</tt></h3>
|
||||
#@desc <p>
|
||||
@@ -27,7 +27,7 @@
|
||||
#@icon icon.debugger
|
||||
#@help dbgeng#ssh
|
||||
#@depends Debugger-rmi-trace
|
||||
#@env OPT_TARGET_IMG:file="" "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_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"
|
||||
@@ -36,6 +36,7 @@
|
||||
#@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="C:\\Windows\\System32" "Path to dbgeng.dll directory" "Path containing dbgeng and associated DLLS (if not Windows Kits)."
|
||||
|
||||
. ../support/dbgsetuputils.sh
|
||||
|
||||
@@ -52,7 +53,7 @@ function launch-dbg-scp() {
|
||||
|
||||
function launch-dbg-ssh() {
|
||||
local -a sshargs
|
||||
compute-ssh-args true "$OPT_PYTHON_EXE -i $OPT_PYTHON_ARGS .\\local-dbgeng.py localhost:$OPT_REMOTE_PORT $OPT_USE_DBGMODEL $target_image $OPT_TARGET_ARGS"
|
||||
compute-ssh-args true "$OPT_PYTHON_EXE -i $OPT_PYTHON_ARGS .\\local-dbgeng.py localhost:$OPT_REMOTE_PORT $OPT_USE_DBGMODEL $WINDBG_DIR $target_image $OPT_TARGET_ARGS"
|
||||
|
||||
"${sshargs[@]}"
|
||||
}
|
||||
@@ -98,7 +99,9 @@ finished, try launching again.
|
||||
" "Would you like to install 'ghidradbg>=$version'?"; then
|
||||
|
||||
echo "Copying Wheels to $OPT_HOST"
|
||||
mitigate-scp-pymodules "Debugger-rmi-trace" "<SELF>"
|
||||
if ! mitigate-scp-pymodules "Debugger-rmi-trace" "<SELF>"; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installing Wheels into Python"
|
||||
do-installation
|
||||
|
||||
@@ -20,5 +20,5 @@ compute-dbg-pipinstall-args() {
|
||||
printf -v argvpart ", %s" "$@"
|
||||
pipargs=("$OPT_PYTHON_EXE")
|
||||
pipargs+=(-c)
|
||||
pipargs+=("import os, sys, runpy; sys.argv=['pip', 'install', '--force-reinstall'$argvpart]; os.environ['PIP_BREAK_SYSTEM_PACKAGE']='1'; runpy.run_module('pip', run_name='__main__')")
|
||||
pipargs+=("\"import os, sys, runpy; sys.argv=['pip', 'install', '--force-reinstall'$argvpart]; os.environ['PIP_BREAK_SYSTEM_PACKAGE']='1'; runpy.run_module('pip', run_name='__main__')\"")
|
||||
}
|
||||
|
||||
@@ -28,7 +28,13 @@ def append_paths():
|
||||
|
||||
def main():
|
||||
append_paths()
|
||||
|
||||
# Delay these imports until sys.path is patched
|
||||
try:
|
||||
import ghidradbg
|
||||
except ModuleNotFoundError:
|
||||
os._exit(253)
|
||||
|
||||
from ghidradbg import commands as cmd
|
||||
from ghidradbg import util
|
||||
from pybag.dbgeng import core as DbgEng
|
||||
|
||||
@@ -27,14 +27,17 @@ def parse_parameters():
|
||||
global cxn, target, args
|
||||
os.environ['OPT_OS_WINDOWS'] = "true"
|
||||
argc = len(sys.argv)
|
||||
# This is the .bat case:
|
||||
if argc == 1:
|
||||
return True
|
||||
if argc >= 4:
|
||||
# Local and remote .ps1 cases
|
||||
if argc >= 5:
|
||||
cxn = sys.argv[1]
|
||||
os.environ['OPT_USE_DBGMODEL'] = sys.argv[2]
|
||||
target = sys.argv[3]
|
||||
if argc > 4:
|
||||
args = sys.argv[4]
|
||||
os.environ['WINDBG_DIR'] = sys.argv[3]
|
||||
target = sys.argv[4]
|
||||
if argc > 5:
|
||||
args = sys.argv[5]
|
||||
return True
|
||||
print("Error: expected (cxn, use_dbgmodel, target, ...)")
|
||||
return False
|
||||
@@ -59,8 +62,9 @@ def main():
|
||||
# Delay these imports until sys.path is patched
|
||||
try:
|
||||
import ghidradbg
|
||||
except Exception as e:
|
||||
exit(253)
|
||||
except ModuleNotFoundError:
|
||||
os._exit(253)
|
||||
|
||||
from ghidradbg import commands as cmd
|
||||
from pybag.dbgeng import core as DbgEng
|
||||
from ghidradbg.hooks import on_state_changed
|
||||
@@ -91,7 +95,5 @@ if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except SystemExit as x:
|
||||
if x.code == 253:
|
||||
exit(253)
|
||||
if x.code != 0:
|
||||
print(f"Exited with code {x.code}")
|
||||
|
||||
@@ -28,7 +28,13 @@ def append_paths():
|
||||
|
||||
def main():
|
||||
append_paths()
|
||||
|
||||
# Delay these imports until sys.path is patched
|
||||
try:
|
||||
import ghidradbg
|
||||
except ModuleNotFoundError:
|
||||
os._exit(253)
|
||||
|
||||
from ghidradbg import commands as cmd
|
||||
from pybag.dbgeng import core as DbgEng
|
||||
from ghidradbg.hooks import on_state_changed
|
||||
|
||||
@@ -28,7 +28,13 @@ def append_paths():
|
||||
|
||||
def main():
|
||||
append_paths()
|
||||
|
||||
# Delay these imports until sys.path is patched
|
||||
try:
|
||||
import ghidradbg
|
||||
except ModuleNotFoundError:
|
||||
os._exit(253)
|
||||
|
||||
from ghidradbg import commands as cmd
|
||||
from pybag.dbgeng import core as DbgEng
|
||||
from ghidradbg.hooks import on_state_changed
|
||||
|
||||
@@ -26,16 +26,19 @@ args = os.getenv('OPT_TARGET_ARGS')
|
||||
def parse_parameters():
|
||||
global cxn, target, args
|
||||
argc = len(sys.argv)
|
||||
# This is the .bat case:
|
||||
if argc == 1:
|
||||
return True
|
||||
if argc >= 4:
|
||||
# Local and remote .ps1 cases
|
||||
if argc >= 5:
|
||||
cxn = sys.argv[1]
|
||||
os.environ['OPT_USE_DBGMODEL'] = sys.argv[2]
|
||||
target = sys.argv[3]
|
||||
if argc > 4:
|
||||
args = sys.argv[4]
|
||||
os.environ['WINDBG_DIR'] = sys.argv[3]
|
||||
target = sys.argv[4]
|
||||
if argc > 5:
|
||||
args = sys.argv[5]
|
||||
return True
|
||||
print("Error: expected (cxn, use_dbgmodel, target, ...)")
|
||||
print("Error: expected (cxn, use_dbgmodel, windbg_dir, target, ...)")
|
||||
return False
|
||||
|
||||
def append_paths():
|
||||
@@ -52,14 +55,16 @@ def append_paths():
|
||||
def main():
|
||||
global cxn, target, args
|
||||
append_paths()
|
||||
|
||||
if parse_parameters() is False:
|
||||
return
|
||||
|
||||
# Delay these imports until sys.path is patched
|
||||
try:
|
||||
import ghidradbg
|
||||
except:
|
||||
exit(253)
|
||||
except ModuleNotFoundError:
|
||||
os._exit(253)
|
||||
|
||||
from ghidradbg import commands as cmd
|
||||
from pybag.dbgeng import core as DbgEng
|
||||
from ghidradbg.hooks import on_state_changed
|
||||
@@ -97,7 +102,5 @@ if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except SystemExit as x:
|
||||
if x.code == 253:
|
||||
exit(253)
|
||||
if x.code != 0:
|
||||
print(f"Exited with code {x.code}")
|
||||
|
||||
@@ -28,7 +28,13 @@ def append_paths():
|
||||
|
||||
def main():
|
||||
append_paths()
|
||||
|
||||
# Delay these imports until sys.path is patched
|
||||
try:
|
||||
import ghidradbg
|
||||
except ModuleNotFoundError:
|
||||
os._exit(253)
|
||||
|
||||
from ghidradbg import commands as cmd
|
||||
from pybag.dbgeng import core as DbgEng
|
||||
from ghidradbg.hooks import on_state_changed
|
||||
|
||||
@@ -28,7 +28,13 @@ def append_paths():
|
||||
|
||||
def main():
|
||||
append_paths()
|
||||
|
||||
# Delay these imports until sys.path is patched
|
||||
try:
|
||||
import ghidradbg
|
||||
except ModuleNotFoundError:
|
||||
os._exit(253)
|
||||
|
||||
from ghidradbg import commands as cmd
|
||||
from pybag.dbgeng import core as DbgEng
|
||||
from ghidradbg.hooks import on_state_changed
|
||||
|
||||
@@ -35,6 +35,26 @@
|
||||
might work around this by copying the affected DLLs from your WinDbg installation into your
|
||||
Python installation.</P>
|
||||
|
||||
<P>Also worth noting, there are now two local launchers, the original .bat-based launcher and a
|
||||
newer .ps1-based launcher. The powershell launcher is not signed. You must therefore set the
|
||||
current user's execution policy or permissions on the script:</P>
|
||||
|
||||
<UL style="list-style-type: none">
|
||||
<LI>
|
||||
<PRE>
|
||||
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
|
||||
</PRE>
|
||||
</LI>
|
||||
|
||||
<LI style="list-style: none">or</LI>
|
||||
|
||||
<LI>
|
||||
<PRE>
|
||||
Unblock-File "Ghidra\Debug\Debugger-agent-dbgeng\data\debugger-launchers\local-dbgeng.ps1"
|
||||
</PRE>
|
||||
</LI>
|
||||
</UL>
|
||||
|
||||
<H3><A name="setup"></A>Setup</H3>
|
||||
|
||||
<P>Installing WinDbg is highly recommended. If you wish to forego installing WinDbg, you can
|
||||
@@ -48,7 +68,7 @@
|
||||
<UL style="list-style-type: none">
|
||||
<LI>
|
||||
<PRE>
|
||||
python3 -m pip install pybag protobuf>=3.20.3
|
||||
python3 -m pip install pybag protobuf>=3.20.3
|
||||
</PRE>
|
||||
</LI>
|
||||
</UL>
|
||||
@@ -123,7 +143,7 @@ python3 -m pip install --no-index -f Debugger-rmi-trace\pypkg\dist -f Debugger-a
|
||||
|
||||
<LI><B>Env</B>: This is a composite string containg Environment Variable entries delineated
|
||||
by '/0' separators. For example, you could redefine USERNAME and USERPROFILE with the entry
|
||||
'USERNAME=SomeUser/0USERPROFILE=C:\Users\SomeUser'.</LI>
|
||||
"<TT>USERNAME=SomeUser/0USERPROFILE=C:\Users\SomeUser</TT>".</LI>
|
||||
|
||||
<LI><B>CreateFlags</B>: Flags used when creating the process, typically either
|
||||
DEBUG_PROCESS(1) or DEBUG_ONLY_THIS_PROCESS(2) if you do not wish to follow spawned
|
||||
@@ -163,42 +183,45 @@ python3 -m pip install --no-index -f Debugger-rmi-trace\pypkg\dist -f Debugger-a
|
||||
<LI>
|
||||
<B>Connection</B>: This is the connection string specifying the transport options for
|
||||
communicating with the remote debugger. A typical example might be
|
||||
'tcp:port=12345,server=192.168.0.2' for a debugger that has issued the command
|
||||
"<TT>tcp:port=12345,server=192.168.0.2</TT>" for a debugger that has issued the command
|
||||
<PRE>
|
||||
.server tcp:port=12345
|
||||
</PRE>
|
||||
</LI>
|
||||
</UL>
|
||||
|
||||
<H2><A name="ssh"></A>Remote via SSH</H2>
|
||||
<H2><A name="ssh"></A>Remote via SSH</H2>
|
||||
|
||||
<P>"<TT>ssh-dbgeng</TT>" is the remote equivalent to "<TT>dbgeng</TT>";
|
||||
"<TT>ssh-dbgeng-attach</TT>" is the remote equivalent to "<TT>dbgeng-attach</TT>".
|
||||
</P>
|
||||
<P>"<TT>ssh-dbgeng</TT>" is the remote equivalent to "<TT>dbgeng</TT>";
|
||||
"<TT>ssh-dbgeng-attach</TT>" is the remote equivalent to "<TT>dbgeng-attach</TT>".</P>
|
||||
|
||||
<H3><A name="remote_setup"></A>Setup</H3>
|
||||
<H3><A name="remote_setup"></A>Setup</H3>
|
||||
|
||||
<P>Instructions are indentical to those above but executed on the remote machine.</P>
|
||||
<P>Instructions are identical to those above but executed on the remote machine. Both of these
|
||||
commands are now implemented via powershell, so the same caveats listed above for the local
|
||||
.ps1 launcher apply here, i.e. you will need to set the current user's execution policy or
|
||||
permissions on the script. Separate launchers have also been added for starting the debugger on
|
||||
a remote Windows box from a local Linux machine.</P>
|
||||
|
||||
<H3>Additional Options</H3>
|
||||
<H3>Additional Options</H3>
|
||||
|
||||
<UL>
|
||||
<LI><B>ssh command</B>: The ssh command to execute, optionaly with full path.</LI>
|
||||
|
||||
<LI><B>[User@]Host</B>: This is the host name of the target system, optionally including a
|
||||
user name. This is passed as is to <TT>ssh</TT>, which may interpret it according to local
|
||||
configuration.</LI>
|
||||
<UL>
|
||||
<LI><B>ssh command</B>: The ssh command to execute, optionaly with full path.</LI>
|
||||
|
||||
<LI><B>Remote Trace RMI Port</B>: An available TCP port on the target system, which will
|
||||
listen for dbgeng's Trace RMI connection and forward it back to Ghidra.</LI>
|
||||
<LI><B>[User@]Host</B>: This is the host name of the target system, optionally including a
|
||||
user name. This is passed as is to <TT>ssh</TT>, which may interpret it according to local
|
||||
configuration.</LI>
|
||||
|
||||
<LI><B>Extra <TT>ssh</TT> arguments</B>: These are extra arguments to pass to <TT>ssh</TT>.
|
||||
They are inserted immediately after the <TT>ssh</TT> 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.</LI>
|
||||
</UL>
|
||||
<LI><B>Remote Trace RMI Port</B>: An available TCP port on the target system, which will
|
||||
listen for dbgeng's Trace RMI connection and forward it back to Ghidra.</LI>
|
||||
|
||||
<H2><A name="svrcx"></A>Process Server</H2>
|
||||
<LI><B>Extra <TT>ssh</TT> arguments</B>: These are extra arguments to pass to <TT>ssh</TT>.
|
||||
They are inserted immediately after the <TT>ssh</TT> 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.</LI>
|
||||
</UL>
|
||||
|
||||
<H2><A name="svrcx"></A>Process Server</H2>
|
||||
|
||||
<P>The "<TT>dbgeng-svrcx</TT>" launcher extends the base dbgeng launcher adding an option for
|
||||
connecting through a remote process server.</P>
|
||||
@@ -209,11 +232,10 @@ python3 -m pip install --no-index -f Debugger-rmi-trace\pypkg\dist -f Debugger-a
|
||||
<LI>
|
||||
<B>Connection</B>: This is the connection string specifying the transport options for
|
||||
communicating with the remote server. A typical example might be
|
||||
'tcp:port=12345,server=192.168.0.2' for a process server launched on the machine at
|
||||
192.168.0.2 using:
|
||||
"<TT>tcp:port=12345,server=192.168.0.2</TT>" for a process server launched on the machine
|
||||
at 192.168.0.2 using:
|
||||
<PRE>
|
||||
dbgsrv -t tcp:port=12345
|
||||
|
||||
dbgsrv -t tcp:port=12345
|
||||
</PRE>
|
||||
</LI>
|
||||
</UL>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
# limitations under the License.
|
||||
##
|
||||
#@title drgn core
|
||||
#@image-opt env:OPT_TARGET_IMG
|
||||
#@desc <html><body width="300px">
|
||||
#@desc <h3>Launch with <tt>drgn-core</tt></h3>
|
||||
#@desc <p>
|
||||
|
||||
@@ -118,7 +118,9 @@ finished, try launching again.
|
||||
" "Would you like to install 'ghidragdb>=$version'?"; then
|
||||
|
||||
echo "Copying Wheels to $OPT_HOST"
|
||||
mitigate-scp-pymodules "Debugger-rmi-trace" "<SELF>"
|
||||
if ! mitigate-scp-pymodules "Debugger-rmi-trace" "<SELF>"; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installing Wheels into GDB's embedded Python"
|
||||
do-installation
|
||||
|
||||
@@ -94,7 +94,9 @@ finished, try launching again.
|
||||
" "Would you like to install 'ghidragdb>=$version'?"; then
|
||||
|
||||
echo "Copying Wheels to $OPT_HOST"
|
||||
mitigate-scp-pymodules "Debugger-rmi-trace" "<SELF>"
|
||||
if ! mitigate-scp-pymodules "Debugger-rmi-trace" "<SELF>"; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installing Wheels into GDB's embedded Python"
|
||||
do-installation
|
||||
|
||||
@@ -116,7 +116,9 @@ finished, try launching again.
|
||||
" "Would you like to install 'ghidralldb>=$version'?"; then
|
||||
|
||||
echo "Copying Wheels to $OPT_HOST"
|
||||
mitigate-scp-pymodules "Debugger-rmi-trace" "<SELF>"
|
||||
if ! mitigate-scp-pymodules "Debugger-rmi-trace" "<SELF>"; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installing Wheels into LLDB's embedded Python"
|
||||
do-installation
|
||||
|
||||
@@ -93,7 +93,9 @@ finished, try launching again.
|
||||
" "Would you like to install 'ghidralldb>=$version'?"; then
|
||||
|
||||
echo "Copying Wheels to $OPT_HOST"
|
||||
mitigate-scp-pymodules "Debugger-rmi-trace" "<SELF>"
|
||||
if ! mitigate-scp-pymodules "Debugger-rmi-trace" "<SELF>"; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installing Wheels into LLDB's embedded Python"
|
||||
do-installation
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
# limitations under the License.
|
||||
##
|
||||
#@title x64dbg attach via ssh (shell)
|
||||
#@image-opt arg:1
|
||||
#@desc <html><body width="300px">
|
||||
#@desc <h3>Launch with <tt>x64dbg</tt> via <tt>ssh</tt></h3>
|
||||
#@desc <p>
|
||||
@@ -39,7 +38,6 @@
|
||||
|
||||
. ../support/x64dbgsetuputils.sh
|
||||
|
||||
target_image=$(echo $OPT_TARGET_IMG | sed 's/\\/\\\\/g')
|
||||
x64dbg_exe=$(echo $OPT_X64DBG_EXE | sed 's/\\/\\\\/g')
|
||||
|
||||
OPT_OS_WINDOWS=true
|
||||
@@ -62,7 +60,7 @@ version=$(get-ghidra-version)
|
||||
|
||||
function do-installation() {
|
||||
local -a pipargs
|
||||
compute-dbg-pipinstall-args "'-f'" "os.environ['HOME']" "'ghidraxdbg>=$version'"
|
||||
compute-x64dbg-pipinstall-args "'-f'" "os.environ['HOME']" "'ghidraxdbg>=$version'"
|
||||
local -a sshargs
|
||||
compute-ssh-args false "${pipargs[@]}"
|
||||
|
||||
@@ -96,10 +94,12 @@ 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'?"; then
|
||||
" "Would you like to install 'ghidraxdbg>=$version'?"; then
|
||||
|
||||
echo "Copying Wheels to $OPT_HOST"
|
||||
mitigate-scp-pymodules "Debugger-rmi-trace" "<SELF>"
|
||||
if ! mitigate-scp-pymodules "Debugger-rmi-trace" "<SELF>"; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installing Wheels into python"
|
||||
do-installation
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#@icon icon.debugger
|
||||
#@help x64dbg#ssh
|
||||
#@depends Debugger-rmi-trace
|
||||
#@env OPT_TARGET_IMG:file="" "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_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."
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
# limitations under the License.
|
||||
##
|
||||
#@title x64dbg via ssh (shell)
|
||||
#@image-opt arg:1
|
||||
#@image-opt env:OPT_TARGET_IMG
|
||||
#@desc <html><body width="300px">
|
||||
#@desc <h3>Launch with <tt>x64dbg</tt> via <tt>ssh</tt></h3>
|
||||
#@desc <p>
|
||||
@@ -27,7 +27,7 @@
|
||||
#@icon icon.debugger
|
||||
#@help x64dbg#ssh
|
||||
#@depends Debugger-rmi-trace
|
||||
#@env OPT_TARGET_IMG:file="" "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_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."
|
||||
@@ -97,10 +97,12 @@ 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'?"; then
|
||||
" "Would you like to install 'ghidraxdbg>=$version'?"; then
|
||||
|
||||
echo "Copying Wheels to $OPT_HOST"
|
||||
mitigate-scp-pymodules "Debugger-rmi-trace" "<SELF>"
|
||||
if ! mitigate-scp-pymodules "Debugger-rmi-trace" "<SELF>"; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installing Wheels into python"
|
||||
do-installation
|
||||
|
||||
@@ -55,8 +55,9 @@ def main():
|
||||
# Delay these imports until sys.path is patched
|
||||
try:
|
||||
import ghidraxdbg
|
||||
except:
|
||||
exit(253)
|
||||
except ModuleNotFoundError:
|
||||
os._exit(253)
|
||||
|
||||
from ghidraxdbg import commands as cmd
|
||||
from ghidraxdbg.hooks import on_state_changed
|
||||
from ghidraxdbg.util import dbg
|
||||
@@ -86,7 +87,5 @@ if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except SystemExit as x:
|
||||
if x.code == 253:
|
||||
exit(253)
|
||||
if x.code != 0:
|
||||
print(f"Exited with code {x.code}")
|
||||
|
||||
@@ -65,8 +65,9 @@ def main():
|
||||
# Delay these imports until sys.path is patched
|
||||
try:
|
||||
import ghidraxdbg
|
||||
except Exception as e:
|
||||
exit(253)
|
||||
except ModuleNotFoundError:
|
||||
os._exit(253)
|
||||
|
||||
from ghidraxdbg import commands as cmd
|
||||
from ghidraxdbg.hooks import on_state_changed
|
||||
from ghidraxdbg.util import dbg
|
||||
@@ -100,7 +101,5 @@ if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except SystemExit as x:
|
||||
if x.code == 253:
|
||||
exit(253)
|
||||
if x.code != 0:
|
||||
print(f"Exited with code {x.code}")
|
||||
|
||||
@@ -20,5 +20,5 @@ compute-x64dbg-pipinstall-args() {
|
||||
printf -v argvpart ", %s" "$@"
|
||||
pipargs=("$OPT_PYTHON_EXE")
|
||||
pipargs+=(-c)
|
||||
pipargs+=("import os, sys, runpy; sys.argv=['pip', 'install', '--force-reinstall'$argvpart]; os.environ['PIP_BREAK_SYSTEM_PACKAGE']='1'; runpy.run_module('pip', run_name='__main__')")
|
||||
pipargs+=("\"import os, sys, runpy; sys.argv=['pip', 'install', '--force-reinstall'$argvpart]; os.environ['PIP_BREAK_SYSTEM_PACKAGE']='1'; runpy.run_module('pip', run_name='__main__')\"")
|
||||
}
|
||||
|
||||
@@ -90,9 +90,6 @@ compute-ssh-args() {
|
||||
printf -v qargs '%q ' "$@"
|
||||
|
||||
sshargs+=("$OPT_SSH_PATH")
|
||||
if [ -n "$OPT_OS_WINDOWS" ]; then
|
||||
sshargs+=(-t)
|
||||
fi
|
||||
if [ "$forward" == "true" ]; then
|
||||
sshargs+=("-R$OPT_REMOTE_PORT:$GHIDRA_TRACE_RMI_ADDR")
|
||||
fi
|
||||
@@ -142,6 +139,9 @@ mitigate-scp-pymodules() {
|
||||
local -a scpargs
|
||||
for mod in "$@"; do
|
||||
dist=$(ghidra-module-pydist "$mod")
|
||||
if [ "$?" -ne "0" ]; then
|
||||
return 1
|
||||
fi
|
||||
scpargs+=("$dist"/*)
|
||||
done
|
||||
scp "${scpargs[@]}" "$OPT_HOST:~/"
|
||||
|
||||
@@ -15,11 +15,14 @@
|
||||
*/
|
||||
package agent;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assume.assumeFalse;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.*;
|
||||
import java.lang.annotation.*;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
@@ -33,14 +36,14 @@ import ghidra.app.plugin.core.debug.gui.modules.DebuggerModulesPlugin;
|
||||
import ghidra.app.plugin.core.debug.gui.tracermi.launcher.AbstractTraceRmiLaunchOffer.NoStaticMappingException;
|
||||
import ghidra.app.plugin.core.debug.gui.tracermi.launcher.TraceRmiLauncherServicePlugin;
|
||||
import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingServicePlugin;
|
||||
import ghidra.app.services.DebuggerAutoMappingService;
|
||||
import ghidra.app.services.TraceRmiLauncherService;
|
||||
import ghidra.app.services.*;
|
||||
import ghidra.debug.api.ValStr;
|
||||
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer;
|
||||
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer.*;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.OperatingSystem;
|
||||
import ghidra.framework.plugintool.AutoConfigState.PathIsFile;
|
||||
import ghidra.pty.*;
|
||||
import ghidra.util.SystemUtilities;
|
||||
|
||||
public abstract class AbstractRmiConnectorsTest
|
||||
@@ -52,9 +55,29 @@ public abstract class AbstractRmiConnectorsTest
|
||||
return "python";
|
||||
}
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface NoLocalSetup {
|
||||
}
|
||||
|
||||
boolean localSetup() throws Exception {
|
||||
Method method = null;
|
||||
try {
|
||||
method = getClass().getMethod(name.getMethodName());
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
return true;
|
||||
}
|
||||
NoLocalSetup annotation = method.getAnnotation(NoLocalSetup.class);
|
||||
return annotation == null;
|
||||
}
|
||||
|
||||
protected abstract List<ResourceFile> getPipLinkModules();
|
||||
|
||||
protected void unpip(String... specs) throws Exception {
|
||||
if (!localSetup()) {
|
||||
return;
|
||||
}
|
||||
List<String> args = new ArrayList<>();
|
||||
args.addAll(List.of(getPythonCmd(), "-m", "pip", "uninstall", "-y"));
|
||||
args.addAll(List.of(specs));
|
||||
@@ -63,6 +86,9 @@ public abstract class AbstractRmiConnectorsTest
|
||||
}
|
||||
|
||||
protected void pipOob(String... specs) throws Exception {
|
||||
if (!localSetup()) {
|
||||
return;
|
||||
}
|
||||
List<String> args = new ArrayList<>();
|
||||
args.addAll(List.of(getPythonCmd(), "-m", "pip", "install"));
|
||||
args.addAll(List.of(specs));
|
||||
@@ -71,6 +97,9 @@ public abstract class AbstractRmiConnectorsTest
|
||||
}
|
||||
|
||||
protected void pip(String... specs) throws Exception {
|
||||
if (!localSetup()) {
|
||||
return;
|
||||
}
|
||||
List<String> args = new ArrayList<>();
|
||||
args.addAll(List.of(getPythonCmd(), "-m", "pip", "install", "--no-index"));
|
||||
for (ResourceFile root : Application.getApplicationRootDirectories()) {
|
||||
@@ -90,6 +119,20 @@ public abstract class AbstractRmiConnectorsTest
|
||||
assertEquals("pip failed", 0, result);
|
||||
}
|
||||
|
||||
protected int runInTerminal(List<String> command, Map<String, String> env)
|
||||
throws IOException, InterruptedException {
|
||||
TerminalService terminalService = tool.getService(TerminalService.class);
|
||||
if (terminalService == null) {
|
||||
throw new NullPointerException("Terminal Service is not installed in test tool");
|
||||
}
|
||||
try (Pty pty = PtyFactory.local().openpty();
|
||||
Terminal term = terminalService.createWithStreams(Charset.forName("utf8"),
|
||||
pty.getParent().getInputStream(), pty.getParent().getOutputStream())) {
|
||||
PtySession session = pty.getChild().session(command.toArray(String[]::new), env);
|
||||
return session.waitExited();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isWindows() {
|
||||
return OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS;
|
||||
}
|
||||
|
||||
@@ -18,11 +18,14 @@ package agent.dbgeng.rmi;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.*;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -30,9 +33,11 @@ import org.junit.Test;
|
||||
import agent.AbstractRmiConnectorsTest;
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.app.plugin.core.debug.gui.tracermi.launcher.AbstractTraceRmiLaunchOffer.EarlyTerminationException;
|
||||
import ghidra.app.plugin.core.debug.gui.tracermi.launcher.AbstractTraceRmiLaunchOffer.NoStaticMappingException;
|
||||
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer.LaunchResult;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.plugintool.AutoConfigState.PathIsFile;
|
||||
import ghidra.pty.testutil.DummyProc;
|
||||
|
||||
public class DbgEngConnectorsTest extends AbstractRmiConnectorsTest {
|
||||
|
||||
@@ -122,8 +127,8 @@ public class DbgEngConnectorsTest extends AbstractRmiConnectorsTest {
|
||||
public void testDbgViaSsh() throws Exception {
|
||||
pip("ghidradbg==%s".formatted(Application.getApplicationVersion()));
|
||||
try (LaunchResult result = doLaunch("dbgeng via ssh", Map.ofEntries(
|
||||
Map.entry("env:OPT_TARGET_IMG", chooseImage()),
|
||||
Map.entry("OPT_HOST", "localhost")))) {
|
||||
Map.entry("env:OPT_TARGET_IMG", chooseImage().toString()),
|
||||
Map.entry("env:OPT_HOST", "localhost")))) {
|
||||
checkResult(result);
|
||||
}
|
||||
}
|
||||
@@ -136,15 +141,16 @@ public class DbgEngConnectorsTest extends AbstractRmiConnectorsTest {
|
||||
// Overwrite with an incompatible version we don't include
|
||||
pipOob("protobuf==3.19.0");
|
||||
try (LaunchResult result = doLaunch("dbgeng via ssh", Map.ofEntries(
|
||||
Map.entry("env:OPT_TARGET_IMG", chooseImage()),
|
||||
Map.entry("OPT_HOST", "localhost")))) {
|
||||
Map.entry("env:OPT_TARGET_IMG", chooseImage().toString()),
|
||||
Map.entry("env:OPT_HOST", "localhost")))) {
|
||||
// If the next line fails, make sure "python" on your box is 3.13
|
||||
assertTrue(result.exception() instanceof EarlyTerminationException);
|
||||
assertThat(result.sessions().get("Shell").content(),
|
||||
Matchers.containsString("Would you like to install"));
|
||||
}
|
||||
try (LaunchResult result = doLaunch("dbgeng via ssh", Map.ofEntries(
|
||||
Map.entry("env:OPT_TARGET_IMG", chooseImage()),
|
||||
Map.entry("OPT_HOST", "localhost")))) {
|
||||
Map.entry("env:OPT_TARGET_IMG", chooseImage().toString()),
|
||||
Map.entry("env:OPT_HOST", "localhost")))) {
|
||||
checkResult(result);
|
||||
}
|
||||
}
|
||||
@@ -152,19 +158,53 @@ public class DbgEngConnectorsTest extends AbstractRmiConnectorsTest {
|
||||
@Test
|
||||
public void testDbgViaSshSetupGhidraDbg() throws Exception {
|
||||
try (LaunchResult result = doLaunch("dbgeng via ssh", Map.ofEntries(
|
||||
Map.entry("env:OPT_TARGET_IMG", chooseImage()),
|
||||
Map.entry("OPT_HOST", "localhost")))) {
|
||||
Map.entry("env:OPT_TARGET_IMG", chooseImage().toString()),
|
||||
Map.entry("env:OPT_HOST", "localhost")))) {
|
||||
// If the next line fails, make sure "python" on your box is 3.13
|
||||
assertTrue(result.exception() instanceof EarlyTerminationException);
|
||||
assertThat(result.sessions().get("Shell").content(),
|
||||
Matchers.containsString("Would you like to install"));
|
||||
}
|
||||
try (LaunchResult result = doLaunch("dbgeng via ssh", Map.ofEntries(
|
||||
Map.entry("env:OPT_TARGET_IMG", chooseImage()),
|
||||
Map.entry("OPT_HOST", "localhost")))) {
|
||||
Map.entry("env:OPT_TARGET_IMG", chooseImage().toString()),
|
||||
Map.entry("env:OPT_HOST", "localhost")))) {
|
||||
checkResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@NoLocalSetup
|
||||
public void testLinuxToDbgViaSshSetupGhidraDbg() throws Exception {
|
||||
assumeFalse(isWindows());
|
||||
|
||||
String hostname = JOptionPane.showInputDialog("Windows Hostname");
|
||||
|
||||
assertEquals(0, runInTerminal(
|
||||
List.of(DummyProc.which("ssh"), hostname, "pip uninstall ghidradbg"), null));
|
||||
|
||||
try (LaunchResult result = doLaunch("dbgeng via ssh (shell)", Map.ofEntries(
|
||||
Map.entry("env:OPT_TARGET_IMG", chooseImage().toString()),
|
||||
Map.entry("env:OPT_HOST", hostname)))) {
|
||||
assertTrue(result.exception() instanceof EarlyTerminationException);
|
||||
assertThat(result.sessions().get("Shell").content(),
|
||||
Matchers.containsString("Would you like to install"));
|
||||
}
|
||||
try (LaunchResult result = doLaunch("dbgeng via ssh (shell)", Map.ofEntries(
|
||||
Map.entry("env:OPT_TARGET_IMG", chooseImage().toString()),
|
||||
Map.entry("env:OPT_HOST", hostname)))) {
|
||||
checkResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkResult(LaunchResult result) {
|
||||
// Exits to python shell, requires quit which generates early term exc.
|
||||
if (result.exception() != null &&
|
||||
!(result.exception() instanceof EarlyTerminationException) &&
|
||||
!(result.exception() instanceof NoStaticMappingException)) {
|
||||
throw new AssertionError(result);
|
||||
}
|
||||
}
|
||||
// LATER?: kernel
|
||||
// LATER?: attach (usermode by PID)
|
||||
// LATER?: ext
|
||||
|
||||
Reference in New Issue
Block a user