mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
GP-5700: Expose module directories to scripts on request
This commit is contained in:
parent
7482131bcc
commit
f92076b936
73 changed files with 862 additions and 516 deletions
|
@ -9,6 +9,7 @@
|
|||
::@menu-group dbgeng
|
||||
::@icon icon.debugger
|
||||
::@help dbgeng#win_kernel
|
||||
::@depends Debugger-rmi-trace
|
||||
::@enum Connection:str Remote Local EXDI
|
||||
::@env OPT_PYTHON_EXE:file!="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH."
|
||||
:: Use env instead of args, because "all args except first" is terrible to implement in batch
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
::@menu-group dbgeng
|
||||
::@icon icon.debugger
|
||||
::@help dbgeng#attach
|
||||
::@depends Debugger-rmi-trace
|
||||
::@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_TARGET_PID:int=0 "Process id" "The target process id"
|
||||
::@env OPT_ATTACH_FLAGS:int=0 "Attach flags" "Attach flags"
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
::@menu-group dbgeng
|
||||
::@icon icon.debugger
|
||||
::@help dbgeng#ext
|
||||
::@depends Debugger-rmi-trace
|
||||
::@env OPT_PYTHON_EXE:file!="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH."
|
||||
:: Use env instead of args, because "all args except first" is terrible to implement in batch
|
||||
::@env OPT_TARGET_IMG:file="" "Image" "The target binary executable image"
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
::@menu-group dbgeng
|
||||
::@icon icon.debugger
|
||||
::@help dbgeng#ttd
|
||||
::@depends Debugger-rmi-trace
|
||||
::@env OPT_PYTHON_EXE:file!="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH."
|
||||
:: Use env instead of args, because "all args except first" is terrible to implement in batch
|
||||
::@env OPT_TARGET_TRACE:file="" "Trace (.run)" "The target trace image"
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
::@menu-group dbgeng
|
||||
::@icon icon.debugger
|
||||
::@help dbgeng#local
|
||||
::@depends Debugger-rmi-trace
|
||||
::@env OPT_PYTHON_EXE:file!="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH."
|
||||
:: Use env instead of args, because "all args except first" is terrible to implement in batch
|
||||
::@env OPT_TARGET_IMG:file="" "Image" "The target binary executable image"
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
::@menu-group dbgeng
|
||||
::@icon icon.debugger
|
||||
::@help dbgeng#remote
|
||||
::@depends Debugger-rmi-trace
|
||||
::@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_CONNECT_STRING:str="" "Connection" "Connection-string arguments (a la .server)"
|
||||
::@env WINDBG_DIR:dir="" "Path to dbgeng.dll directory" "Path containing dbgeng and associated DLLS (if not Windows Kits)."
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
::@menu-group dbgeng
|
||||
::@icon icon.debugger
|
||||
::@help dbgeng#svrcx
|
||||
::@depends Debugger-rmi-trace
|
||||
::@env OPT_PYTHON_EXE:file!="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH."
|
||||
:: Use env instead of args, because "all args except first" is terrible to implement in batch
|
||||
::@env OPT_TARGET_IMG:str="" "Image" "The target binary executable image"
|
||||
|
|
|
@ -19,10 +19,11 @@ import sys
|
|||
|
||||
|
||||
def append_paths():
|
||||
sys.path.append("../../../Debugger-rmi-trace/data/support")
|
||||
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("Debug/Debugger-rmi-trace"))
|
||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
|
||||
sys.path.append(ghidra_module_pypath("Debugger-rmi-trace"))
|
||||
sys.path.append(ghidra_module_pypath())
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -19,10 +19,11 @@ import sys
|
|||
|
||||
|
||||
def append_paths():
|
||||
sys.path.append("../../../Debugger-rmi-trace/data/support")
|
||||
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("Debug/Debugger-rmi-trace"))
|
||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
|
||||
sys.path.append(ghidra_module_pypath("Debugger-rmi-trace"))
|
||||
sys.path.append(ghidra_module_pypath())
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -19,10 +19,11 @@ import sys
|
|||
|
||||
|
||||
def append_paths():
|
||||
sys.path.append("../../../Debugger-rmi-trace/data/support")
|
||||
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("Debug/Debugger-rmi-trace"))
|
||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
|
||||
sys.path.append(ghidra_module_pypath("Debugger-rmi-trace"))
|
||||
sys.path.append(ghidra_module_pypath())
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -19,10 +19,11 @@ import sys
|
|||
|
||||
|
||||
def append_paths():
|
||||
sys.path.append("../../../Debugger-rmi-trace/data/support")
|
||||
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("Debug/Debugger-rmi-trace"))
|
||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
|
||||
sys.path.append(ghidra_module_pypath("Debugger-rmi-trace"))
|
||||
sys.path.append(ghidra_module_pypath())
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -19,10 +19,11 @@ import sys
|
|||
|
||||
|
||||
def append_paths():
|
||||
sys.path.append("../../../Debugger-rmi-trace/data/support")
|
||||
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("Debug/Debugger-rmi-trace"))
|
||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
|
||||
sys.path.append(ghidra_module_pypath("Debugger-rmi-trace"))
|
||||
sys.path.append(ghidra_module_pypath())
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -19,10 +19,11 @@ import sys
|
|||
|
||||
|
||||
def append_paths():
|
||||
sys.path.append("../../../Debugger-rmi-trace/data/support")
|
||||
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("Debug/Debugger-rmi-trace"))
|
||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
|
||||
sys.path.append(ghidra_module_pypath("Debugger-rmi-trace"))
|
||||
sys.path.append(ghidra_module_pypath())
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -21,10 +21,11 @@ import sys
|
|||
|
||||
|
||||
def append_paths():
|
||||
sys.path.append("../../../Debugger-rmi-trace/data/support")
|
||||
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("Debug/Debugger-rmi-trace"))
|
||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
|
||||
sys.path.append(ghidra_module_pypath("Debugger-rmi-trace"))
|
||||
sys.path.append(ghidra_module_pypath())
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -19,10 +19,11 @@ import sys
|
|||
|
||||
|
||||
def append_paths():
|
||||
sys.path.append("../../../Debugger-rmi-trace/data/support")
|
||||
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("Debug/Debugger-rmi-trace"))
|
||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
|
||||
sys.path.append(ghidra_module_pypath("Debugger-rmi-trace"))
|
||||
sys.path.append(ghidra_module_pypath())
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -18,7 +18,7 @@ try:
|
|||
import pybag
|
||||
except Exception as e:
|
||||
from ghidratrace.setuputils import prompt_and_mitigate_dependencies
|
||||
prompt_and_mitigate_dependencies("Debug/Debugger-agent-dbgeng")
|
||||
prompt_and_mitigate_dependencies("<SELF>")
|
||||
|
||||
# NOTE: libraries must precede EVERYTHING, esp pybag and DbgMod
|
||||
from . import libraries, util, commands, methods, hooks
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#@menu-group drgn
|
||||
#@icon icon.debugger
|
||||
#@help drgn#core
|
||||
#@depends Debugger-rmi-trace
|
||||
#@env OPT_TARGET_IMG:file!="" "Core dump" "The target core dump"
|
||||
|
||||
export OPT_TARGET_KIND="coredump"
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#@menu-group drgn
|
||||
#@icon icon.debugger
|
||||
#@help drgn#linux_kernel
|
||||
#@depends Debugger-rmi-trace
|
||||
|
||||
export OPT_TARGET_KIND="kernel"
|
||||
sudo -E drgn ../support/local-drgn.py
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#@menu-group drgn
|
||||
#@icon icon.debugger
|
||||
#@help drgn#attach
|
||||
#@depends Debugger-rmi-trace
|
||||
#@env OPT_TARGET_PID:int=44068 "PID" "The target's process id"
|
||||
|
||||
export OPT_TARGET_KIND="user"
|
||||
|
|
|
@ -22,25 +22,18 @@ import sys
|
|||
|
||||
import drgn.cli
|
||||
|
||||
home = os.getenv('GHIDRA_HOME')
|
||||
|
||||
if os.path.isdir(f'{home}/ghidra/.git'):
|
||||
def append_paths():
|
||||
sys.path.append(
|
||||
f'{home}/ghidra/Ghidra/Debug/Debugger-agent-drgn/build/pypkg/src')
|
||||
sys.path.append(
|
||||
f'{home}/ghidra/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src')
|
||||
elif os.path.isdir(f'{home}/.git'):
|
||||
sys.path.append(
|
||||
f'{home}/Ghidra/Debug/Debugger-agent-drgn/build/pypkg/src')
|
||||
sys.path.append(
|
||||
f'{home}/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src')
|
||||
else:
|
||||
sys.path.append(
|
||||
f'{home}/Ghidra/Debug/Debugger-agent-drgn/pypkg/src')
|
||||
sys.path.append(f'{home}/Ghidra/Debug/Debugger-rmi-trace/pypkg/src')
|
||||
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())
|
||||
|
||||
|
||||
def main():
|
||||
append_paths()
|
||||
|
||||
from ghidradrgn import commands as cmd
|
||||
cmd.ghidra_trace_connect(address=os.getenv('GHIDRA_TRACE_RMI_ADDR'))
|
||||
cmd.ghidra_trace_create(start_trace=True)
|
||||
|
@ -53,5 +46,3 @@ def main():
|
|||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#@menu-group gdb
|
||||
#@icon icon.debugger
|
||||
#@help gdb#local
|
||||
#@depends Debugger-rmi-trace
|
||||
#@enum StartCmd:str run start starti
|
||||
#@enum Endian:str auto big little
|
||||
#@arg :file "Image" "The target binary executable image"
|
||||
|
@ -21,8 +22,8 @@
|
|||
|
||||
. ..\support\gdbsetuputils.ps1
|
||||
|
||||
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
|
||||
$pypathGdb = Ghidra-Module-PyPath "Debug/Debugger-agent-gdb"
|
||||
$pypathTrace = Ghidra-Module-PyPath "Debugger-rmi-trace"
|
||||
$pypathGdb = Ghidra-Module-PyPath
|
||||
$Env:PYTHONPATH = "$pypathGdb;$pypathTrace;$Env:PYTHONPATH"
|
||||
|
||||
$arglist = Compute-Gdb-Usermode-Args `
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#@menu-group gdb
|
||||
#@icon icon.debugger
|
||||
#@help gdb#local
|
||||
#@depends Debugger-rmi-trace
|
||||
#@enum StartCmd:str run start starti
|
||||
#@enum Endian:str auto big little
|
||||
#@arg :file "Image" "The target binary executable image, empty for no target"
|
||||
|
@ -39,8 +40,8 @@
|
|||
|
||||
. ../support/gdbsetuputils.sh
|
||||
|
||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
||||
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
|
||||
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||
pypathGdb=$(ghidra-module-pypath)
|
||||
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
||||
|
||||
target_image="$1"
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#@menu-group gdb
|
||||
#@icon icon.debugger
|
||||
#@help gdb#rr
|
||||
#@depends Debugger-rmi-trace
|
||||
#@enum StartCmd:str run start starti
|
||||
#@enum Endian:str auto big little
|
||||
#@arg :file "Trace Dir" "The target trace directory (e.g. .local/share/rr/trace)"
|
||||
|
@ -36,8 +37,8 @@
|
|||
|
||||
. ../support/gdbsetuputils.sh
|
||||
|
||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
||||
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
|
||||
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||
pypathGdb=$(ghidra-module-pypath)
|
||||
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
||||
|
||||
target_trace="$1"
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#@menu-group gdb
|
||||
#@icon icon.debugger
|
||||
#@help gdb#qemu
|
||||
#@depends Debugger-rmi-trace
|
||||
#@enum Endian:str auto big little
|
||||
#@arg :file! "Image" "The target binary executable image"
|
||||
#@args "Arguments" "Command-line arguments to pass to the target"
|
||||
|
@ -42,8 +43,8 @@
|
|||
|
||||
. ../support/gdbsetuputils.sh
|
||||
|
||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
||||
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
|
||||
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||
pypathGdb=$(ghidra-module-pypath)
|
||||
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
||||
|
||||
target_image="$1"
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#@menu-group gdb
|
||||
#@icon icon.debugger
|
||||
#@help gdb#qemu
|
||||
#@depends Debugger-rmi-trace
|
||||
#@enum Endian:str auto big little
|
||||
#@env OPT_TARGET_IMG:file!="" "Image" "The target binary executable image"
|
||||
#@env GHIDRA_LANG_EXTTOOL_qemu_system:file="" "QEMU command" "The path to qemu-system for the target architecture."
|
||||
|
@ -23,8 +24,8 @@
|
|||
|
||||
. ..\support\gdbsetuputils.ps1
|
||||
|
||||
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
|
||||
$pypathGdb = Ghidra-Module-PyPath "Debug/Debugger-agent-gdb"
|
||||
$pypathTrace = Ghidra-Module-PyPath "Debugger-rmi-trace"
|
||||
$pypathGdb = Ghidra-Module-PyPath
|
||||
$Env:PYTHONPATH = "$pypathGdb;$pypathTrace;$Env:PYTHONPATH"
|
||||
|
||||
$qemuargs = @("`"$Env:GHIDRA_LANG_EXTTOOL_qemu_system`"")
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#@menu-group gdb
|
||||
#@icon icon.debugger
|
||||
#@help gdb#qemu
|
||||
#@depends Debugger-rmi-trace
|
||||
#@enum Endian:str auto big little
|
||||
#@arg :file! "Image" "The target binary executable image"
|
||||
#@env GHIDRA_LANG_EXTTOOL_qemu_system:file="" "QEMU command" "The path to qemu-system for the target architecture."
|
||||
|
@ -41,8 +42,8 @@
|
|||
|
||||
. ../support/gdbsetuputils.sh
|
||||
|
||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
||||
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
|
||||
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||
pypathGdb=$(ghidra-module-pypath)
|
||||
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
||||
|
||||
target_image="$1"
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#@menu-group gdb
|
||||
#@icon icon.debugger
|
||||
#@help gdb#remote
|
||||
#@depends Debugger-rmi-trace
|
||||
#@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)"
|
||||
|
@ -22,8 +23,8 @@
|
|||
|
||||
. ..\support\gdbsetuputils.ps1
|
||||
|
||||
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
|
||||
$pypathGdb = Ghidra-Module-PyPath "Debug/Debugger-agent-gdb"
|
||||
$pypathTrace = Ghidra-Module-PyPath "Debugger-rmi-trace"
|
||||
$pypathGdb = Ghidra-Module-PyPath
|
||||
$Env:PYTHONPATH = "$pypathGdb;$pypathTrace;$Env:PYTHONPATH"
|
||||
|
||||
$arglist = Compute-Gdb-Remote-Args `
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#@menu-group gdb
|
||||
#@icon icon.debugger
|
||||
#@help gdb#remote
|
||||
#@depends Debugger-rmi-trace
|
||||
#@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)"
|
||||
|
@ -38,8 +39,8 @@
|
|||
|
||||
. ../support/gdbsetuputils.sh
|
||||
|
||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
||||
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
|
||||
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||
pypathGdb=$(ghidra-module-pypath)
|
||||
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
||||
|
||||
target_image="$1"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#@timeout 60000
|
||||
#@title gdb via ssh
|
||||
#@image-opt arg:1
|
||||
#@desc <html><body width="300px">
|
||||
|
@ -11,6 +10,7 @@
|
|||
#@menu-group gdb
|
||||
#@icon icon.debugger
|
||||
#@help gdb#ssh
|
||||
#@depends Debugger-rmi-trace
|
||||
#@enum StartCmd:str run start starti
|
||||
#@enum Endian:str auto big little
|
||||
#@arg :str "Image" "The target binary executable image on the remote system"
|
||||
|
@ -61,7 +61,7 @@ finished, try launching again.
|
|||
|
||||
if ($answer) {
|
||||
Write-Host "Copying Wheels to $Env:OPT_HOST"
|
||||
Mitigate-Scp-PyModules "Debug/Debugger-rmi-trace" "Debug/Debugger-agent-gdb"
|
||||
Mitigate-Scp-PyModules "Debugger-rmi-trace" "<SELF>"
|
||||
|
||||
Write-Host "Installing Wheels into GDB's embedded Python"
|
||||
$arglist = Compute-Gdb-PipInstall-Args "'-f'" "os.environ['HOME']" "'ghidragdb>=$version'"
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
##
|
||||
#@timeout 60000
|
||||
#@title gdb via ssh
|
||||
#@image-opt arg:1
|
||||
#@desc <html><body width="300px">
|
||||
|
@ -27,6 +26,7 @@
|
|||
#@menu-group gdb
|
||||
#@icon icon.debugger
|
||||
#@help gdb#ssh
|
||||
#@depends Debugger-rmi-trace
|
||||
#@enum StartCmd:str run start starti
|
||||
#@enum Endian:str auto big little
|
||||
#@arg :str "Image" "The target binary executable image on the remote system"
|
||||
|
@ -93,7 +93,7 @@ finished, try launching again.
|
|||
" "Would you like to install 'ghidragdb>=$version'?"; then
|
||||
|
||||
echo "Copying Wheels to $OPT_HOST"
|
||||
mitigate-scp-pymodules "Debug/Debugger-rmi-trace" "Debug/Debugger-agent-gdb"
|
||||
mitigate-scp-pymodules "Debugger-rmi-trace" "<SELF>"
|
||||
|
||||
echo "Installing Wheels into GDB's embedded Python"
|
||||
do-installation
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#@timeout 60000
|
||||
#@title gdb + gdbserver via ssh
|
||||
#@image-opt arg:1
|
||||
#@desc <html><body width="300px">
|
||||
|
@ -11,6 +10,7 @@
|
|||
#@menu-group gdb
|
||||
#@icon icon.debugger
|
||||
#@help gdb#gdbserver_ssh
|
||||
#@depends Debugger-rmi-trace
|
||||
#@enum Endian:str auto big little
|
||||
#@arg :str! "Image" "The target binary executable image on the remote system"
|
||||
#@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
|
||||
|
@ -25,8 +25,8 @@
|
|||
|
||||
. ..\support\gdbsetuputils.ps1
|
||||
|
||||
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
|
||||
$pypathGdb = Ghidra-Module-PyPath "Debug/Debugger-agent-gdb"
|
||||
$pypathTrace = Ghidra-Module-PyPath "Debugger-rmi-trace"
|
||||
$pypathGdb = Ghidra-Module-PyPath
|
||||
$Env:PYTHONPATH = "$pypathGdb;$pypathTrace;$Env:PYTHONPATH"
|
||||
|
||||
$arglist = Compute-Gdb-Remote-Args `
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
##
|
||||
#@timeout 60000
|
||||
#@title gdb + gdbserver via ssh
|
||||
#@image-opt arg:1
|
||||
#@desc <html><body width="300px">
|
||||
|
@ -27,6 +26,7 @@
|
|||
#@menu-group gdb
|
||||
#@icon icon.debugger
|
||||
#@help gdb#gdbserver_ssh
|
||||
#@depends Debugger-rmi-trace
|
||||
#@enum Endian:str auto big little
|
||||
#@arg :str! "Image" "The target binary executable image on the remote system"
|
||||
#@args "Arguments" "Command-line arguments to pass to the target"
|
||||
|
@ -41,8 +41,8 @@
|
|||
|
||||
. ../support/gdbsetuputils.sh
|
||||
|
||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
||||
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
|
||||
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||
pypathGdb=$(ghidra-module-pypath)
|
||||
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
||||
|
||||
target_image="$1"
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#@menu-group gdb
|
||||
#@icon icon.debugger
|
||||
#@help gdb#wine
|
||||
#@depends Debugger-rmi-trace
|
||||
#@enum Endian:str auto big little
|
||||
#@arg :file! "Image" "The target binary executable image"
|
||||
#@args "Arguments" "Command-line arguments to pass to the target"
|
||||
|
@ -39,8 +40,8 @@
|
|||
|
||||
. ../support/gdbsetuputils.sh
|
||||
|
||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
||||
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
|
||||
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||
pypathGdb=$(ghidra-module-pypath)
|
||||
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
||||
|
||||
target_image="$1"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
. ..\..\..\Debugger-rmi-trace\data\support\setuputils.ps1
|
||||
. $Env:MODULE_Debugger_rmi_trace_HOME\data\support\setuputils.ps1
|
||||
|
||||
function Add-Gdb-Init-Args {
|
||||
param([ref]$ArgList)
|
||||
|
@ -48,7 +48,7 @@ function Add-Gdb-Tail-Args {
|
|||
param([ref]$ArgList)
|
||||
|
||||
$ArgList.Value+=("-ex", "`"set confirm on`"")
|
||||
$ArgList.Value+=("-ex", "`"set pagination on`"")
|
||||
# $ArgList.Value+=("-ex", "`"set pagination on`"")
|
||||
}
|
||||
|
||||
function Compute-Gdb-Usermode-Args {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
##
|
||||
. ../../../Debugger-rmi-trace/data/support/setuputils.sh
|
||||
. $MODULE_Debugger_rmi_trace_HOME/data/support/setuputils.sh
|
||||
|
||||
add-gdb-init-args() {
|
||||
args+=(-q)
|
||||
|
@ -64,7 +64,7 @@ add-gdb-start-if-image() {
|
|||
|
||||
add-gdb-tail-args() {
|
||||
args+=(-ex "set confirm on")
|
||||
args+=(-ex "set pagination on")
|
||||
# args+=(-ex "set pagination on")
|
||||
}
|
||||
|
||||
compute-gdb-usermode-args() {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#@menu-group lldb
|
||||
#@icon icon.debugger
|
||||
#@help lldb#android
|
||||
#@depends Debugger-rmi-trace
|
||||
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
|
||||
#@arg :file "Image" "The target binary executable image"
|
||||
#@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
|
||||
|
@ -21,8 +22,8 @@
|
|||
|
||||
. ..\support\lldbsetuputils.ps1
|
||||
|
||||
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
|
||||
$pypathLldb = Ghidra-Module-PyPath "Debug/Debugger-agent-lldb"
|
||||
$pypathTrace = Ghidra-Module-PyPath "Debugger-rmi-trace"
|
||||
$pypathLldb = Ghidra-Module-PyPath
|
||||
$Env:PYTHONPATH = "$pypathLldb;$pypathTrace;$Env:PYTHONPATH"
|
||||
|
||||
$arglist = Compute-Lldb-Platform-Args `
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#@menu-group lldb
|
||||
#@icon icon.debugger
|
||||
#@help lldb#android
|
||||
#@depends Debugger-rmi-trace
|
||||
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
|
||||
#@arg :file "Image" "The target binary executable image"
|
||||
#@args "Arguments" "Command-line arguments to pass to the target"
|
||||
|
@ -37,8 +38,8 @@
|
|||
|
||||
. ../support/lldbsetuputils.sh
|
||||
|
||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
||||
pypathLldb=$(ghidra-module-pypath "Debug/Debugger-agent-lldb")
|
||||
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||
pypathLldb=$(ghidra-module-pypath)
|
||||
export PYTHONPATH=$pypathLldb:$pypathTrace:$PYTHONPATH
|
||||
|
||||
target_image="$1"
|
||||
|
|
|
@ -9,14 +9,15 @@
|
|||
#@menu-group lldb
|
||||
#@icon icon.debugger
|
||||
#@help lldb#macos_kernel
|
||||
#@depends Debugger-rmi-trace
|
||||
#@env OPT_HOST:str="localhost" "Host" "The hostname of the target"
|
||||
#@env OPT_ARCH:str="" "Architecture" "Target architecture override"
|
||||
#@env OPT_LLDB_PATH:file="lldb" "lldb command" "The path to lldb on the local system. Omit the full path to resolve using the system PATH."
|
||||
|
||||
. ..\support\lldbsetuputils.ps1
|
||||
|
||||
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
|
||||
$pypathLldb = Ghidra-Module-PyPath "Debug/Debugger-agent-lldb"
|
||||
$pypathTrace = Ghidra-Module-PyPath "Debugger-rmi-trace"
|
||||
$pypathLldb = Ghidra-Module-PyPath
|
||||
$Env:PYTHONPATH = "$pypathLldb;$pypathTrace;$Env:PYTHONPATH"
|
||||
|
||||
$arglist = Compute-Lldb-Remote-Args `
|
||||
|
|
|
@ -25,14 +25,15 @@
|
|||
#@menu-group lldb
|
||||
#@icon icon.debugger
|
||||
#@help lldb#macos_kernel
|
||||
#@depends Debugger-rmi-trace
|
||||
#@env OPT_HOST:str="localhost" "Host" "The hostname of the target"
|
||||
#@env OPT_ARCH:str="" "Architecture" "Target architecture override"
|
||||
#@env OPT_LLDB_PATH:file="lldb" "lldb command" "The path to lldb on the local system. Omit the full path to resolve using the system PATH."
|
||||
|
||||
. ../support/lldbsetuputils.sh
|
||||
|
||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
||||
pypathLldb=$(ghidra-module-pypath "Debug/Debugger-agent-lldb")
|
||||
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||
pypathLldb=$(ghidra-module-pypath)
|
||||
export PYTHONPATH=$pypathLldb:$pypathTrace:$PYTHONPATH
|
||||
|
||||
function launch-lldb() {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#@menu-group lldb
|
||||
#@icon icon.debugger
|
||||
#@help lldb#local
|
||||
#@depends Debugger-rmi-trace
|
||||
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
|
||||
#@arg :file "Image" "The target binary executable image"
|
||||
#@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
|
||||
|
@ -18,8 +19,8 @@
|
|||
|
||||
. ..\support\lldbsetuputils.ps1
|
||||
|
||||
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
|
||||
$pypathLldb = Ghidra-Module-PyPath "Debug/Debugger-agent-lldb"
|
||||
$pypathTrace = Ghidra-Module-PyPath "Debugger-rmi-trace"
|
||||
$pypathLldb = Ghidra-Module-PyPath
|
||||
$Env:PYTHONPATH = "$pypathLldb;$pypathTrace;$Env:PYTHONPATH"
|
||||
|
||||
$arglist = Compute-Lldb-Usermode-Args `
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#@menu-group lldb
|
||||
#@icon icon.debugger
|
||||
#@help lldb#local
|
||||
#@depends Debugger-rmi-trace
|
||||
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
|
||||
#@arg :file "Image" "The target binary executable image"
|
||||
#@args "Arguments" "Command-line arguments to pass to the target"
|
||||
|
@ -36,8 +37,8 @@
|
|||
|
||||
. ../support/lldbsetuputils.sh
|
||||
|
||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
||||
pypathLldb=$(ghidra-module-pypath "Debug/Debugger-agent-lldb")
|
||||
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||
pypathLldb=$(ghidra-module-pypath)
|
||||
export PYTHONPATH=$pypathLldb:$pypathTrace:$PYTHONPATH
|
||||
|
||||
target_image="$1"
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#@menu-group lldb
|
||||
#@icon icon.debugger
|
||||
#@help lldb#remote
|
||||
#@depends Debugger-rmi-trace
|
||||
#@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"
|
||||
|
@ -18,8 +19,8 @@
|
|||
|
||||
. ..\support\lldbsetuputils.ps1
|
||||
|
||||
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
|
||||
$pypathLldb = Ghidra-Module-PyPath "Debug/Debugger-agent-lldb"
|
||||
$pypathTrace = Ghidra-Module-PyPath "Debugger-rmi-trace"
|
||||
$pypathLldb = Ghidra-Module-PyPath
|
||||
$Env:PYTHONPATH = "$pypathLldb;$pypathTrace;$Env:PYTHONPATH"
|
||||
|
||||
$arglist = Compute-Lldb-Remote-Args `
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#@menu-group lldb
|
||||
#@icon icon.debugger
|
||||
#@help lldb#remote
|
||||
#@depends Debugger-rmi-trace
|
||||
#@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"
|
||||
|
@ -34,8 +35,8 @@
|
|||
|
||||
. ../support/lldbsetuputils.sh
|
||||
|
||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
||||
pypathLldb=$(ghidra-module-pypath "Debug/Debugger-agent-lldb")
|
||||
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||
pypathLldb=$(ghidra-module-pypath)
|
||||
export PYTHONPATH=$pypathLldb:$pypathTrace:$PYTHONPATH
|
||||
|
||||
target_image="$1"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#@timeout 60000
|
||||
#@title lldb via ssh
|
||||
#@image-opt arg:1
|
||||
#@desc <html><body width="300px">
|
||||
|
@ -11,6 +10,7 @@
|
|||
#@menu-group lldb
|
||||
#@icon icon.debugger
|
||||
#@help lldb#ssh
|
||||
#@depends Debugger-rmi-trace
|
||||
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
|
||||
#@enum Endian:str auto big little
|
||||
#@arg :str "Image" "The target binary executable image on the remote system"
|
||||
|
@ -60,7 +60,7 @@ finished, try launching again.
|
|||
|
||||
if ($answer) {
|
||||
Write-Host "Copying Wheels to $Env:OPT_HOST"
|
||||
Mitigate-Scp-PyModules "Debug/Debugger-rmi-trace" "Debug/Debugger-agent-lldb"
|
||||
Mitigate-Scp-PyModules "Debugger-rmi-trace" "<SELF>"
|
||||
|
||||
Write-Host "Installing Wheels into LLDB's embedded Python"
|
||||
$arglist = Compute-Lldb-PipInstall-Args "'-f'" "os.environ['HOME']" "'ghidralldb>=$version'"
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
##
|
||||
#@timeout 60000
|
||||
#@title lldb via ssh
|
||||
#@image-opt arg:1
|
||||
#@desc <html><body width="300px">
|
||||
|
@ -27,6 +26,7 @@
|
|||
#@menu-group lldb
|
||||
#@icon icon.debugger
|
||||
#@help lldb#ssh
|
||||
#@depends Debugger-rmi-trace
|
||||
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
|
||||
#@enum Endian:str auto big little
|
||||
#@arg :str "Image" "The target binary executable image on the remote system"
|
||||
|
@ -92,7 +92,7 @@ finished, try launching again.
|
|||
" "Would you like to install 'ghidralldb>=$version'?"; then
|
||||
|
||||
echo "Copying Wheels to $OPT_HOST"
|
||||
mitigate-scp-pymodules "Debug/Debugger-rmi-trace" "Debug/Debugger-agent-lldb"
|
||||
mitigate-scp-pymodules "Debugger-rmi-trace" "<SELF>"
|
||||
|
||||
echo "Installing Wheels into LLDB's embedded Python"
|
||||
do-installation
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
. ..\..\..\Debugger-rmi-trace\data\support\setuputils.ps1
|
||||
. $Env:MODULE_Debugger_rmi_trace_HOME\data\support\setuputils.ps1
|
||||
|
||||
function Add-Lldb-Init-Args {
|
||||
param([ref]$ArgList)
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
##
|
||||
. ../../../Debugger-rmi-trace/data/support/setuputils.sh
|
||||
. $MODULE_Debugger_rmi_trace_HOME/data/support/setuputils.sh
|
||||
|
||||
add-lldb-init-args() {
|
||||
args+=(-o "version")
|
||||
|
|
|
@ -86,8 +86,9 @@ public class JavaTraceRmiLaunchOffer extends AbstractScriptTraceRmiLaunchOffer {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void launchBackEnd(TaskMonitor monitor, Map<String, TerminalSession> sessions,
|
||||
Map<String, ValStr<?>> args, SocketAddress address) throws Exception {
|
||||
protected TraceRmiBackEnd launchBackEnd(TaskMonitor monitor,
|
||||
Map<String, TerminalSession> sessions, Map<String, ValStr<?>> args,
|
||||
SocketAddress address) throws Exception {
|
||||
List<String> commandLine = new ArrayList<>();
|
||||
Map<String, String> env = new HashMap<>(System.getenv());
|
||||
prepareSubprocess(commandLine, env, args, address);
|
||||
|
@ -101,18 +102,28 @@ public class JavaTraceRmiLaunchOffer extends AbstractScriptTraceRmiLaunchOffer {
|
|||
sessions.put(ns.name(), ns);
|
||||
}
|
||||
|
||||
TraceRmiBackEnd result = new TraceRmiBackEnd();
|
||||
if (hasKeyReally(env, "OPT_JSHELL_PATH")) {
|
||||
String classPath = computeClassPath(env);
|
||||
commandLine.add(0, "--startup");
|
||||
commandLine.add(0, "--class-path=" + classPath);
|
||||
commandLine.add(0, env.get("OPT_JSHELL_PATH"));
|
||||
sessions.put("Shell",
|
||||
runInTerminal(commandLine, env, script.getParentFile(), sessions.values()));
|
||||
PtyTerminalSession session =
|
||||
runInTerminal(commandLine, env, script.getParentFile(), sessions.values());
|
||||
sessions.put("Shell", session);
|
||||
session.terminal().addTerminalListener(result);
|
||||
}
|
||||
else {
|
||||
JdiClientThread thread = new JdiClientThread(env);
|
||||
JdiClientThread thread = new JdiClientThread(env) {
|
||||
@Override
|
||||
public void run() {
|
||||
super.run();
|
||||
result.terminated(0);
|
||||
}
|
||||
};
|
||||
thread.start();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private String computeClassPath(Map<String, String> env) {
|
||||
|
|
|
@ -30,14 +30,9 @@
|
|||
#@env OPT_LANG:str="DATA:LE:64:default" "Ghidra Language" "The Ghidra LanguageID for the trace"
|
||||
#@env OPT_COMP:str="pointer64" "Ghidra Compiler" "The Ghidra CompilerSpecID for the trace"
|
||||
|
||||
if [ -d ${GHIDRA_HOME}/ghidra/.git ]
|
||||
then
|
||||
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
|
||||
elif [ -d ${GHIDRA_HOME}/.git ]
|
||||
then
|
||||
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
|
||||
else
|
||||
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/pypkg/src:$PYTHONPATH
|
||||
fi
|
||||
. ../support/setuputils.sh
|
||||
|
||||
pypathTrace=$(ghidra-module-pypath)
|
||||
export PYTHONPATH=$pypathTrace:$PYTHONPATH
|
||||
|
||||
"$OPT_PYTHON_EXE" -i ../support/raw-python3.py
|
||||
|
|
|
@ -28,19 +28,17 @@ This file CANNOT be assumed to be available on a remote target. For
|
|||
that, consider ghidratrace.setuputils.
|
||||
"""
|
||||
import os
|
||||
|
||||
home = os.getenv('GHIDRA_HOME')
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def ghidra_module_pypath(name: str) -> str:
|
||||
installed = f'{home}/Ghidra/{name}/pypkg/src'
|
||||
def ghidra_module_pypath(name: Optional[str]=None) -> str:
|
||||
mod_home_name = 'MODULE_HOME' if name is None else f'MODULE_{name.replace("-","_")}_HOME'
|
||||
mod_home = os.getenv(mod_home_name)
|
||||
installed = f'{mod_home}/pypkg/src'
|
||||
if os.path.isdir(installed):
|
||||
return installed
|
||||
dev1 = f'{home}/Ghidra/{name}/build/pypkg/src'
|
||||
if os.path.isdir(dev1):
|
||||
return dev1
|
||||
dev2 = f'{home}/ghidra/Ghidra/{name}/build/pypkg/src'
|
||||
if os.path.isdir(dev2):
|
||||
return dev2
|
||||
dev = f'{mod_home}/build/pypkg/src'
|
||||
if os.path.isdir(dev):
|
||||
return dev
|
||||
raise Exception(
|
||||
f"Cannot find Python source for {name}. Try gradle assemblePyPackage?")
|
||||
|
|
|
@ -33,4 +33,4 @@ client = Client(
|
|||
print(f"Connected to {client.description} at {host}:{port}")
|
||||
|
||||
trace = client.create_trace("noname", os.getenv(
|
||||
"OPT_LANG"), os.getenv("OPT_COMP"))
|
||||
"OPT_LANG"), os.getenv("OPT_COMP"), extra=None)
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
function Find-App-Properties {
|
||||
[IO.FileInfo] $simple = "$Env:GHIDRA_HOME\Ghidra\applications.properties"
|
||||
if ($simple.Exists) {
|
||||
return $simple
|
||||
}
|
||||
[IO.FileInfo] $dev2 = "$Env:GHIDRA_HOME\ghidra\Ghidra\application.properties"
|
||||
if ($dev2.Exists) {
|
||||
return $dev2
|
||||
[IO.FileInfo] $props = "$Env:GHIDRA_HOME\application.properties"
|
||||
if ($props.Exists) {
|
||||
return $props
|
||||
}
|
||||
throw "Cannot find application.properties"
|
||||
}
|
||||
|
@ -17,33 +13,39 @@ function Get-Ghidra-Version {
|
|||
}
|
||||
|
||||
function Ghidra-Module-PyPath {
|
||||
[IO.DirectoryInfo] $installed = "$Env:GHIDRA_HOME\Ghidra\$($args[0])\pypkg\src"
|
||||
if ($args.Count -eq 0 -or $args[0] -eq "<SELF>") {
|
||||
$modhomename = 'MODULE_HOME'
|
||||
} else {
|
||||
$modhomename = "MODULE_$($args[0])_HOME" -replace '-', '_'
|
||||
}
|
||||
$modhomeitem = Get-ChildItem Env:$modhomename
|
||||
$modhome = $modhomeitem.Value
|
||||
[IO.DirectoryInfo] $installed = "$modhome\pypkg\src"
|
||||
if ($installed.Exists) {
|
||||
return "$installed"
|
||||
}
|
||||
[IO.DirectoryInfo] $dev1 = "$Env:GHIDRA_HOME\Ghidra\$($args[0])\build\pypkg\src"
|
||||
if ($dev1.Exists) {
|
||||
return "$dev1"
|
||||
}
|
||||
[IO.DirectoryInfo] $dev2 = "$Env:GHIDRA_HOME\ghidra\Ghidra\$($args[0])\build\pypkg\src"
|
||||
if ($dev2.Exists) {
|
||||
return "$dev2"
|
||||
[IO.DirectoryInfo] $dev = "$modhome\build\pypkg\src"
|
||||
if ($dev.Exists) {
|
||||
return "$dev"
|
||||
}
|
||||
throw "Cannot find Python source for $($args[0]). Try gradle assemblePyPackage?"
|
||||
}
|
||||
|
||||
function Ghidra-Module-PyDist {
|
||||
[IO.DirectoryInfo] $installed = "$Env:GHIDRA_HOME\Ghidra\$($args[0])\pypkg\dist"
|
||||
if ($args.Count -eq 0 -or $args[0] -eq "<SELF>") {
|
||||
$modhomename = 'MODULE_HOME'
|
||||
} else {
|
||||
$modhomename = "MODULE_$($args[0])_HOME" -replace '-', '_'
|
||||
}
|
||||
$modhomeitem = Get-ChildItem Env:$modhomename
|
||||
$modhome = $modhomeitem.Value
|
||||
[IO.DirectoryInfo] $installed = "$modhome\pypkg\dist"
|
||||
if ($installed.Exists) {
|
||||
return "$installed"
|
||||
}
|
||||
[IO.DirectoryInfo] $dev1 = "$Env:GHIDRA_HOME\Ghidra\$($args[0])\build\pypkg\dist"
|
||||
if ($dev1.Exists) {
|
||||
return "$dev1"
|
||||
}
|
||||
[IO.DirectoryInfo] $dev2 = "$Env:GHIDRA_HOME\ghidra\Ghidra\$($args[0])\build\pypkg\dist"
|
||||
if ($dev2.Exists) {
|
||||
return "$dev2"
|
||||
[IO.DirectoryInfo] $dev = "$modhome\build\pypkg\dist"
|
||||
if ($dev.Exists) {
|
||||
return "$dev"
|
||||
}
|
||||
throw "Cannot find Python package for $($args[0]). Try gradle buildPyPackage?"
|
||||
}
|
||||
|
|
|
@ -14,14 +14,9 @@
|
|||
# limitations under the License.
|
||||
##
|
||||
find-app-properties() {
|
||||
local simple="$GHIDRA_HOME/Ghidra/application.properties"
|
||||
if [ -f "$simple" ]; then
|
||||
echo $simple
|
||||
return 0
|
||||
fi
|
||||
local dev2="$GHIDRA_HOME/ghidra/Ghidra/application.properties"
|
||||
if [ -f "$dev2" ]; then
|
||||
echo $dev2
|
||||
local props="$GHIDRA_HOME/application.properties"
|
||||
if [ -f "$props" ]; then
|
||||
echo $props
|
||||
return 0
|
||||
fi
|
||||
echo >&2 "Cannot find application.properties"
|
||||
|
@ -45,19 +40,21 @@ get-ghidra-version() {
|
|||
}
|
||||
|
||||
ghidra-module-pypath() {
|
||||
installed="$GHIDRA_HOME/Ghidra/$1/pypkg/src"
|
||||
local modhomename
|
||||
if [ -z "$1" ] || [ "$1" == "<SELF>" ]; then
|
||||
modhomename='MODULE_HOME'
|
||||
else
|
||||
modhomename="MODULE_${1//-/_}_HOME"
|
||||
fi
|
||||
local modhome="${!modhomename}"
|
||||
local installed="$modhome/pypkg/src"
|
||||
if [ -d "$installed" ]; then
|
||||
echo $installed
|
||||
return 0
|
||||
fi
|
||||
dev1="$GHIDRA_HOME/Ghidra/$1/build/pypkg/src"
|
||||
if [ -d "$dev1" ]; then
|
||||
echo $dev1
|
||||
return 0
|
||||
fi
|
||||
dev2="$GHIDRA_HOME/ghidra/Ghidra/$1/build/pypkg/src"
|
||||
if [ -d "$dev2" ]; then
|
||||
echo $dev2
|
||||
local dev="$modhome/build/pypkg/src"
|
||||
if [ -d "$dev" ]; then
|
||||
echo $dev
|
||||
return 0
|
||||
fi
|
||||
echo >&2 "Cannot find Python source for $1. Try gradle assemblePyPackage?"
|
||||
|
@ -65,19 +62,21 @@ ghidra-module-pypath() {
|
|||
}
|
||||
|
||||
ghidra-module-pydist() {
|
||||
installed="$GHIDRA_HOME/Ghidra/$1/pypkg/dist"
|
||||
local modhomename
|
||||
if [ -z "$1" ] || [ "$1" == "<SELF>" ]; then
|
||||
modhomename='MODULE_HOME'
|
||||
else
|
||||
modhomename="MODULE_${1//-/_}_HOME"
|
||||
fi
|
||||
local modhome="${!modhomename}"
|
||||
local installed="$modhome/pypkg/dist"
|
||||
if [ -d "$installed" ]; then
|
||||
echo $installed
|
||||
return 0
|
||||
fi
|
||||
dev1="$GHIDRA_HOME/Ghidra/$1/build/pypkg/dist"
|
||||
if [ -d "$dev1" ]; then
|
||||
echo $dev1
|
||||
return 0
|
||||
fi
|
||||
dev2="$GHIDRA_HOME/ghidra/Ghidra/$1/build/pypkg/dist"
|
||||
if [ -d "$dev2" ]; then
|
||||
echo $dev2
|
||||
local dev="$modhome/build/pypkg/dist"
|
||||
if [ -d "$dev" ]; then
|
||||
echo $dev
|
||||
return 0
|
||||
fi
|
||||
echo >&2 "Cannot find Python package for $1. Try gradle buildPyPackage?"
|
||||
|
|
|
@ -98,12 +98,13 @@ public abstract class AbstractScriptTraceRmiLaunchOffer extends AbstractTraceRmi
|
|||
protected void prepareSubprocess(List<String> commandLine, Map<String, String> env,
|
||||
Map<String, ValStr<?>> args, SocketAddress address) {
|
||||
ScriptAttributesParser.processArguments(commandLine, env, script, attrs.parameters(), args,
|
||||
address);
|
||||
attrs.dependencies(), address);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void launchBackEnd(TaskMonitor monitor, Map<String, TerminalSession> sessions,
|
||||
Map<String, ValStr<?>> args, SocketAddress address) throws Exception {
|
||||
protected TraceRmiBackEnd launchBackEnd(TaskMonitor monitor,
|
||||
Map<String, TerminalSession> sessions, Map<String, ValStr<?>> args,
|
||||
SocketAddress address) throws Exception {
|
||||
List<String> commandLine = new ArrayList<>();
|
||||
Map<String, String> env = new HashMap<>(System.getenv());
|
||||
prepareSubprocess(commandLine, env, args, address);
|
||||
|
@ -112,7 +113,8 @@ public abstract class AbstractScriptTraceRmiLaunchOffer extends AbstractTraceRmi
|
|||
if (imageParameter != null) {
|
||||
ValStr<?> valStr = args.get(imageParameter.name());
|
||||
if (valStr != null && !valStr.str().contains(program.getName())) {
|
||||
Msg.warn(this, "Possible mismatch for " + program.getName() + ": " + valStr.str());
|
||||
Msg.warn(this,
|
||||
"Possible mismatch for " + program.getName() + ": " + valStr.str());
|
||||
}
|
||||
}
|
||||
env.put("GHIDRA_LANGUAGE_ID", program.getLanguageID().toString());
|
||||
|
@ -127,8 +129,12 @@ public abstract class AbstractScriptTraceRmiLaunchOffer extends AbstractTraceRmi
|
|||
sessions.put(ent.getKey(), ns);
|
||||
}
|
||||
|
||||
sessions.put("Shell",
|
||||
runInTerminal(commandLine, env, script.getParentFile(), sessions.values()));
|
||||
PtyTerminalSession session =
|
||||
runInTerminal(commandLine, env, script.getParentFile(), sessions.values());
|
||||
sessions.put("Shell", session);
|
||||
TraceRmiBackEnd result = new TraceRmiBackEnd();
|
||||
session.terminal().addTerminalListener(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,16 +17,18 @@ package ghidra.app.plugin.core.debug.gui.tracermi.launcher;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.Duration;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
|
||||
import ghidra.app.plugin.core.debug.gui.DebuggerResources;
|
||||
import ghidra.app.plugin.core.debug.gui.action.ByModuleAutoMapSpec;
|
||||
import ghidra.app.plugin.core.debug.gui.tracermi.launcher.LaunchFailureDialog.ErrPromptResponse;
|
||||
|
@ -59,12 +61,14 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
|
|||
public static final String PREFIX_PARAM_EXTTOOL = "env:GHIDRA_LANG_EXTTOOL_";
|
||||
|
||||
public static final int DEFAULT_TIMEOUT_MILLIS = 10000;
|
||||
public static final int DEFAULT_CONNECTION_TIMEOUT_MILLIS =
|
||||
(int) Duration.ofMinutes(10).toMillis();
|
||||
|
||||
protected record PtyTerminalSession(Terminal terminal, Pty pty, PtySession session,
|
||||
Thread waiter) implements TerminalSession {
|
||||
@Override
|
||||
public void terminate() throws IOException {
|
||||
terminal.terminated();
|
||||
terminal.terminated(-1);
|
||||
session.destroyForcibly();
|
||||
pty.close();
|
||||
waiter.interrupt();
|
||||
|
@ -80,7 +84,7 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
|
|||
implements TerminalSession {
|
||||
@Override
|
||||
public void terminate() throws IOException {
|
||||
terminal.terminated();
|
||||
terminal.terminated(-1);
|
||||
pty.close();
|
||||
}
|
||||
|
||||
|
@ -135,7 +139,7 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
|
|||
}
|
||||
|
||||
protected int getConnectionTimeoutMillis() {
|
||||
return getTimeoutMillis();
|
||||
return DEFAULT_CONNECTION_TIMEOUT_MILLIS;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -415,7 +419,8 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
|
|||
param.display()));
|
||||
}
|
||||
catch (Exception e) {
|
||||
Msg.warn(this, "Could not load saved launcher arg '%s' (%s) - %s".formatted(param.name(),
|
||||
Msg.warn(this,
|
||||
"Could not load saved launcher arg '%s' (%s) - %s".formatted(param.name(),
|
||||
param.display(), e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
@ -490,8 +495,8 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
|
|||
|
||||
Thread waiter = new Thread(() -> {
|
||||
try {
|
||||
session.waitExited();
|
||||
terminal.terminated();
|
||||
int exitcode = session.waitExited();
|
||||
terminal.terminated(exitcode);
|
||||
pty.close();
|
||||
|
||||
for (TerminalSession ss : subordinates) {
|
||||
|
@ -538,10 +543,43 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
|
|||
return terminalSession;
|
||||
}
|
||||
|
||||
protected abstract void launchBackEnd(TaskMonitor monitor,
|
||||
protected abstract TraceRmiBackEnd launchBackEnd(TaskMonitor monitor,
|
||||
Map<String, TerminalSession> sessions, Map<String, ValStr<?>> args,
|
||||
SocketAddress address) throws Exception;
|
||||
|
||||
protected TraceRmiHandler acceptOrSessionEnds(DefaultTraceRmiAcceptor acceptor,
|
||||
TraceRmiBackEnd backEnd)
|
||||
throws SocketException, CancelledException, EarlyTerminationException {
|
||||
acceptor.setTimeout(getConnectionTimeoutMillis());
|
||||
CompletableFuture<TraceRmiHandler> futureConnection = CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
return acceptor.accept();
|
||||
}
|
||||
catch (CancelledException | IOException e) {
|
||||
return ExceptionUtils.rethrow(e);
|
||||
}
|
||||
});
|
||||
// Because of accept timeout, should be a finite wait
|
||||
try {
|
||||
CompletableFuture.anyOf(backEnd, futureConnection).get();
|
||||
if (backEnd.isDone()) {
|
||||
throw new EarlyTerminationException(
|
||||
"The back-end exited (code=%s) before receiving a connection"
|
||||
.formatted(backEnd.getNow(null)));
|
||||
}
|
||||
return futureConnection.get();
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
switch (e.getCause()) {
|
||||
case CancelledException ce -> throw ce;
|
||||
default -> throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static class NoStaticMappingException extends Exception {
|
||||
public NoStaticMappingException(String message) {
|
||||
super(message);
|
||||
|
@ -553,6 +591,17 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
|
|||
}
|
||||
}
|
||||
|
||||
public static class EarlyTerminationException extends Exception {
|
||||
public EarlyTerminationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
protected AutoMapSpec getAutoMapSpec() {
|
||||
DebuggerAutoMappingService auto = tool.getService(DebuggerAutoMappingService.class);
|
||||
return auto == null ? ByModuleAutoMapSpec.instance() : auto.getAutoMapSpec();
|
||||
|
@ -660,12 +709,16 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
|
|||
monitor.increment();
|
||||
|
||||
monitor.setMessage("Launching back-end");
|
||||
TraceRmiBackEnd backEnd =
|
||||
launchBackEnd(monitor, sessions, args, acceptor.getAddress());
|
||||
monitor.increment();
|
||||
|
||||
/**
|
||||
* LATER: We might be able to disable timeouts, now that we know if the back-end
|
||||
* terminates early
|
||||
*/
|
||||
monitor.setMessage("Waiting for connection");
|
||||
acceptor.setTimeout(getConnectionTimeoutMillis());
|
||||
connection = acceptor.accept();
|
||||
connection = acceptOrSessionEnds(acceptor, backEnd);
|
||||
connection.registerTerminals(sessions.values());
|
||||
monitor.increment();
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.util.Map.Entry;
|
|||
|
||||
import javax.swing.Icon;
|
||||
|
||||
import generic.jar.ResourceFile;
|
||||
import generic.theme.GIcon;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.debug.api.ValStr;
|
||||
|
@ -40,12 +41,15 @@ import ghidra.util.*;
|
|||
*/
|
||||
public abstract class ScriptAttributesParser {
|
||||
public static final String ENV_GHIDRA_HOME = "GHIDRA_HOME";
|
||||
public static final String ENV_MODULE_HOME = "MODULE_HOME";
|
||||
public static final String ENV_MODULE_HOME_PAT = "MODULE_%s_HOME";
|
||||
public static final String ENV_GHIDRA_TRACE_RMI_ADDR = "GHIDRA_TRACE_RMI_ADDR";
|
||||
public static final String ENV_GHIDRA_TRACE_RMI_HOST = "GHIDRA_TRACE_RMI_HOST";
|
||||
public static final String ENV_GHIDRA_TRACE_RMI_PORT = "GHIDRA_TRACE_RMI_PORT";
|
||||
|
||||
public static final String AT_ARG = "@arg";
|
||||
public static final String AT_ARGS = "@args";
|
||||
public static final String AT_DEPENDS = "@depends";
|
||||
public static final String AT_DESC = "@desc";
|
||||
public static final String AT_ENUM = "@enum";
|
||||
public static final String AT_ENV = "@env";
|
||||
|
@ -341,8 +345,8 @@ public abstract class ScriptAttributesParser {
|
|||
|
||||
public record ScriptAttributes(String title, String description, List<String> menuPath,
|
||||
String menuGroup, String menuOrder, Icon icon, HelpLocation helpLocation,
|
||||
Map<String, LaunchParameter<?>> parameters, Map<String, TtyCondition> extraTtys,
|
||||
int timeoutMillis, LaunchParameter<?> imageOpt) {
|
||||
Map<String, LaunchParameter<?>> parameters, Set<String> dependencies,
|
||||
Map<String, TtyCondition> extraTtys, int timeoutMillis, LaunchParameter<?> imageOpt) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -355,14 +359,35 @@ public abstract class ScriptAttributesParser {
|
|||
* @param script the script file
|
||||
* @param parameters the descriptions of the parameters
|
||||
* @param args the arguments to process
|
||||
* @param dependencies a set of module names this script needs
|
||||
* @param address the address of the listening TraceRmi socket
|
||||
*/
|
||||
public static void processArguments(List<String> commandLine, Map<String, String> env,
|
||||
File script, Map<String, LaunchParameter<?>> parameters, Map<String, ValStr<?>> args,
|
||||
SocketAddress address) {
|
||||
Set<String> dependencies, SocketAddress address) {
|
||||
|
||||
commandLine.add(script.getAbsolutePath());
|
||||
env.put(ENV_GHIDRA_HOME, Application.getInstallationDirectory().getAbsolutePath());
|
||||
|
||||
env.put(ENV_GHIDRA_HOME, Application.getApplicationRootDirectory().getAbsolutePath());
|
||||
ResourceFile myModule =
|
||||
Application.getModuleContainingResourceFile(new ResourceFile(script));
|
||||
if (myModule == null) {
|
||||
Msg.warn(ScriptAttributes.class, "Launch script is not contained in a module");
|
||||
}
|
||||
else {
|
||||
env.put(ENV_MODULE_HOME, myModule.getAbsolutePath());
|
||||
}
|
||||
for (String dep : dependencies) {
|
||||
ResourceFile module = Application.getModuleRootDir(dep);
|
||||
if (module == null) {
|
||||
Msg.warn(ScriptAttributes.class, "Could not find module " + dep);
|
||||
}
|
||||
else {
|
||||
env.put(ENV_MODULE_HOME_PAT.formatted(dep.replace('-', '_')),
|
||||
module.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
if (address != null) {
|
||||
env.put(ENV_GHIDRA_TRACE_RMI_ADDR, sockToString(address));
|
||||
if (address instanceof InetSocketAddress tcp) {
|
||||
|
@ -402,8 +427,9 @@ public abstract class ScriptAttributesParser {
|
|||
private List<String> menuPath;
|
||||
private final Map<String, UserType<?>> userTypes = new HashMap<>();
|
||||
private final Map<String, LaunchParameter<?>> parameters = new LinkedHashMap<>();
|
||||
private final Set<String> dependencies = new LinkedHashSet<>();
|
||||
private final Map<String, TtyCondition> extraTtys = new LinkedHashMap<>();
|
||||
private int timeoutMillis = AbstractTraceRmiLaunchOffer.DEFAULT_TIMEOUT_MILLIS;
|
||||
private int timeoutMillis = AbstractTraceRmiLaunchOffer.DEFAULT_CONNECTION_TIMEOUT_MILLIS;
|
||||
private String imageOptKey;
|
||||
|
||||
/**
|
||||
|
@ -493,6 +519,7 @@ public abstract class ScriptAttributesParser {
|
|||
switch (parts[0].trim()) {
|
||||
case AT_ARG -> parseArg(loc, parts[1], ++argc);
|
||||
case AT_ARGS -> parseArgs(loc, parts[1]);
|
||||
case AT_DEPENDS -> parseDepends(loc, parts[1]);
|
||||
case AT_DESC -> parseDesc(loc, parts[1]);
|
||||
case AT_ENUM -> parseEnum(loc, parts[1]);
|
||||
case AT_ENV -> parseEnv(loc, parts[1]);
|
||||
|
@ -549,6 +576,13 @@ public abstract class ScriptAttributesParser {
|
|||
}
|
||||
}
|
||||
|
||||
protected void parseDepends(Location loc, String str) {
|
||||
String moduleName = str.trim();
|
||||
if (!dependencies.add(moduleName)) {
|
||||
reportWarning("%s: Duplicate %s %s. Ignored.".formatted(loc, AT_DEPENDS, str));
|
||||
}
|
||||
}
|
||||
|
||||
protected void parseDesc(Location loc, String str) {
|
||||
if (description == null) {
|
||||
description = new StringBuilder();
|
||||
|
@ -796,9 +830,11 @@ public abstract class ScriptAttributesParser {
|
|||
AT_IMAGE_OPT, imageOptKey));
|
||||
}
|
||||
}
|
||||
// NOTE: Don't use copyOf, or else we lose ordering
|
||||
return new ScriptAttributes(title, getDescription(), List.copyOf(menuPath), menuGroup,
|
||||
menuOrder, new GIcon(iconId), helpLocation,
|
||||
Collections.unmodifiableMap(new LinkedHashMap<>(parameters)),
|
||||
Collections.unmodifiableSet(new LinkedHashSet<>(dependencies)),
|
||||
Collections.unmodifiableMap(new LinkedHashMap<>(extraTtys)), timeoutMillis, imageOpt);
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
package ghidra.app.plugin.core.debug.gui.tracermi.launcher;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import ghidra.app.plugin.core.terminal.TerminalListener;
|
||||
|
||||
public class TraceRmiBackEnd extends CompletableFuture<Integer> implements TerminalListener {
|
||||
@Override
|
||||
public void terminated(int exitcode) {
|
||||
complete(exitcode);
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@ classifiers = [
|
|||
"Operating System :: OS Independent",
|
||||
]
|
||||
dependencies = [
|
||||
"protobuf >= 6.31.0",
|
||||
"protobuf>=6.31.0",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
|
|
|
@ -18,7 +18,7 @@ try:
|
|||
from . import trace_rmi_pb2 as bufs
|
||||
except Exception as e:
|
||||
from .setuputils import prompt_and_mitigate_dependencies
|
||||
prompt_and_mitigate_dependencies("Debug/Debugger-rmi-trace")
|
||||
prompt_and_mitigate_dependencies("Debugger-rmi-trace")
|
||||
|
||||
from collections import deque
|
||||
from concurrent.futures import Executor, Future
|
||||
|
|
|
@ -23,22 +23,18 @@ whether remote or local, the PYTHONPATH should already include this
|
|||
module, and so we place the setup logic here.
|
||||
"""
|
||||
import os
|
||||
from typing import List, Sequence
|
||||
from typing import List, Optional, Sequence
|
||||
|
||||
|
||||
home = os.getenv('GHIDRA_HOME')
|
||||
|
||||
|
||||
def ghidra_module_src(name: str) -> str:
|
||||
installed = f'{home}/Ghidra/{name}/pypkg'
|
||||
def ghidra_module_src(name: Optional[str]=None) -> str:
|
||||
mod_home_name = 'MODULE_HOME' if name is None else f'MODULE_{name.replace("-","_")}_HOME'
|
||||
mod_home = os.getenv(mod_home_name)
|
||||
installed = f'{mod_home}/pypkg'
|
||||
if os.path.isdir(installed):
|
||||
return installed
|
||||
dev1 = f'{home}/Ghidra/{name}/src/main/py'
|
||||
if os.path.isdir(dev1):
|
||||
return dev1
|
||||
dev2 = f'{home}/ghidra/Ghidra/{name}/src/main/py'
|
||||
if os.path.isdir(dev2):
|
||||
return dev2
|
||||
dev = f'{mod_home}/src/main/py'
|
||||
if os.path.isdir(dev):
|
||||
return dev
|
||||
raise Exception(f"""
|
||||
Cannot find Python source for {name}.
|
||||
If this is a remote system, we shouldn't even be here. Chances are,
|
||||
|
@ -93,15 +89,29 @@ def mitigate_by_pip_install(*args: str) -> None:
|
|||
runpy.run_module("pip", run_name="__main__")
|
||||
|
||||
|
||||
def compute_suggestion(*args: str) -> None:
|
||||
def maybe_quote(a):
|
||||
if '>' in a or '<' in a or ' ' in a:
|
||||
return f"'{a}'"
|
||||
return a
|
||||
wquotes = ' '.join(maybe_quote(a) for a in args)
|
||||
return f"python -m pip install --force-reinstall {wquotes}"
|
||||
|
||||
|
||||
def prompt_and_mitigate_dependencies(name: str) -> None:
|
||||
deps = get_module_dependencies(name)
|
||||
deps_str = ' '.join(f"'{d}'" for d in deps)
|
||||
answer = prompt_mitigation("""
|
||||
suggestion = compute_suggestion(*deps)
|
||||
answer = prompt_mitigation(f"""
|
||||
It appears dependencies are missing or have the wrong version. This can happen
|
||||
if you forgot to install the required packages. This can also happen if you
|
||||
installed the packages to a different Python environment than is being used
|
||||
right now.
|
||||
|
||||
The following command should resolve the issue:
|
||||
|
||||
{suggestion}
|
||||
|
||||
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.
|
||||
|
@ -121,4 +131,3 @@ finished, close this terminal, and try launching again.
|
|||
|
||||
if answer:
|
||||
mitigate_by_pip_install('-f', '../../pypkg/dist', *deps)
|
||||
|
||||
|
|
|
@ -41,8 +41,8 @@ public class DefaultTerminal implements Terminal {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void terminated() {
|
||||
provider.terminated();
|
||||
public void terminated(int exitcode) {
|
||||
provider.terminated(exitcode);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -38,4 +38,12 @@ public interface TerminalListener {
|
|||
*/
|
||||
default void retitled(String title) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The terminal session was terminated
|
||||
*
|
||||
* @param exitcode the exit code of the session leader, or -1 if not applicable
|
||||
*/
|
||||
default void terminated(int exitcode) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,9 @@ import ghidra.app.plugin.core.terminal.TerminalFinder.TextTerminalFinder;
|
|||
import ghidra.app.plugin.core.terminal.vt.*;
|
||||
import ghidra.app.plugin.core.terminal.vt.VtHandler.*;
|
||||
import ghidra.app.services.ClipboardService;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.ColorUtils;
|
||||
import ghidra.util.Swing;
|
||||
import ghidra.util.datastruct.ListenerSet;
|
||||
|
||||
/**
|
||||
* A VT100 terminal emulator in a panel.
|
||||
|
@ -180,7 +182,8 @@ public class TerminalPanel extends JPanel implements FieldLocationListener, Fiel
|
|||
protected TerminalClipboardProvider clipboardProvider;
|
||||
protected String selectedText;
|
||||
|
||||
protected final ArrayList<TerminalListener> terminalListeners = new ArrayList<>();
|
||||
protected final ListenerSet<TerminalListener> terminalListeners =
|
||||
new ListenerSet<TerminalListener>(TerminalListener.class, false);
|
||||
|
||||
protected VtOutput outputCb;
|
||||
protected final TerminalAwtEventEncoder eventEncoder;
|
||||
|
@ -363,25 +366,15 @@ public class TerminalPanel extends JPanel implements FieldLocationListener, Fiel
|
|||
}
|
||||
|
||||
protected void notifyTerminalResized(short cols, short rows) {
|
||||
for (TerminalListener l : terminalListeners) {
|
||||
try {
|
||||
l.resized(cols, rows);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
Msg.showError(this, null, "Error", t.getMessage(), t);
|
||||
}
|
||||
}
|
||||
terminalListeners.invoke().resized(cols, rows);
|
||||
}
|
||||
|
||||
protected void notifyTerminalRetitled(String title) {
|
||||
for (TerminalListener l : terminalListeners) {
|
||||
try {
|
||||
l.retitled(title);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
Msg.showError(this, null, "Error", t.getMessage(), t);
|
||||
}
|
||||
terminalListeners.invoke().retitled(title);
|
||||
}
|
||||
|
||||
protected void notifyTerminalTerminated(int exitcode) {
|
||||
terminalListeners.invoke().terminated(exitcode);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -53,7 +53,7 @@ import ghidra.util.Swing;
|
|||
* This also provides UI actions for searching the terminal's contents.
|
||||
*/
|
||||
public class TerminalProvider extends ComponentProviderAdapter {
|
||||
// TODO: A separate color?
|
||||
// Should I use a separate color id?
|
||||
private static final Color COLOR_TERMINATED = new GColor("color.border.provider.disconnected");
|
||||
|
||||
protected class FindDialog extends DialogComponentProvider {
|
||||
|
@ -433,10 +433,13 @@ public class TerminalProvider extends ComponentProviderAdapter {
|
|||
* <p>
|
||||
* The title and sub title are adjusted and all terminal listeners are removed. If/when the
|
||||
* window is closed, it is removed from the tool.
|
||||
*
|
||||
* @param exitcode the exit code of the session leader, or -1 if not applicable
|
||||
*/
|
||||
public void terminated() {
|
||||
public void terminated(int exitcode) {
|
||||
Swing.runIfSwingOrRunLater(() -> {
|
||||
terminated = true;
|
||||
panel.terminalListeners.invoke().terminated(exitcode);
|
||||
removeLocalAction(actionTerminate);
|
||||
panel.terminalListeners.clear();
|
||||
panel.setOutputCallback(buf -> {
|
||||
|
|
|
@ -201,8 +201,10 @@ public interface Terminal extends AutoCloseable {
|
|||
* <p>
|
||||
* The title and sub title are adjust and all listeners are removed. If/when the terminal is
|
||||
* closed, it is permanently removed from the tool.
|
||||
*
|
||||
* @param exitcode the exit code of the session leader, or -1 if not applicable
|
||||
*/
|
||||
void terminated();
|
||||
void terminated(int exitcode);
|
||||
|
||||
/**
|
||||
* Allow the user to terminate the session forcefully
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
/* ###
|
||||
* 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 agent;
|
||||
|
||||
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.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
import org.junit.Before;
|
||||
|
||||
import generic.Unique;
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerIntegrationTest;
|
||||
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.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.util.SystemUtilities;
|
||||
|
||||
public abstract class AbstractRmiConnectorsTest
|
||||
extends AbstractGhidraHeadedDebuggerIntegrationTest {
|
||||
protected TraceRmiLauncherService launchService;
|
||||
protected DebuggerAutoMappingService autoMappingService;
|
||||
|
||||
protected String getPythonCmd() {
|
||||
return "python";
|
||||
}
|
||||
|
||||
protected abstract List<ResourceFile> getPipLinkModules();
|
||||
|
||||
protected void unpip(String... specs) throws Exception {
|
||||
List<String> args = new ArrayList<>();
|
||||
args.addAll(List.of(getPythonCmd(), "-m", "pip", "uninstall", "-y"));
|
||||
args.addAll(List.of(specs));
|
||||
int result = new ProcessBuilder().command(args).inheritIO().start().waitFor();
|
||||
assertEquals("pip failed", 0, result);
|
||||
}
|
||||
|
||||
protected void pipOob(String... specs) throws Exception {
|
||||
List<String> args = new ArrayList<>();
|
||||
args.addAll(List.of(getPythonCmd(), "-m", "pip", "install"));
|
||||
args.addAll(List.of(specs));
|
||||
int result = new ProcessBuilder().command(args).inheritIO().start().waitFor();
|
||||
assertEquals("pip failed", 0, result);
|
||||
}
|
||||
|
||||
protected void pip(String... specs) throws Exception {
|
||||
List<String> args = new ArrayList<>();
|
||||
args.addAll(List.of(getPythonCmd(), "-m", "pip", "install", "--no-index"));
|
||||
for (ResourceFile root : Application.getApplicationRootDirectories()) {
|
||||
if (root.getAbsolutePath().contains("ghidra.bin")) {
|
||||
for (; root != null; root = root.getParentFile()) {
|
||||
if (root.getName().equals("ghidra.bin")) {
|
||||
args.addAll(List.of("-f", root.getAbsolutePath() + "/ExternalPyWheels"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (ResourceFile module : getPipLinkModules()) {
|
||||
args.addAll(List.of("-f", module.getAbsolutePath() + "/build/pypkg/dist"));
|
||||
}
|
||||
args.addAll(List.of(specs));
|
||||
int result = new ProcessBuilder().command(args).inheritIO().start().waitFor();
|
||||
assertEquals("pip failed", 0, result);
|
||||
}
|
||||
|
||||
protected PathIsFile chooseImage() {
|
||||
if (OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS) {
|
||||
return new PathIsFile(Path.of("C:\\Windows\\notepad.exe"));
|
||||
}
|
||||
return new PathIsFile(Path.of("/bin/ls"));
|
||||
}
|
||||
|
||||
protected PathIsFile findQemu(String bin) {
|
||||
if (OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS) {
|
||||
return new PathIsFile(Path.of("C:\\msys64\\ucrt64\bin\\").resolve(bin));
|
||||
}
|
||||
return new PathIsFile(Path.of(bin));
|
||||
}
|
||||
|
||||
protected PathIsFile createArmElfImage() throws Exception {
|
||||
assumeTrue(OperatingSystem.LINUX == OperatingSystem.CURRENT_OPERATING_SYSTEM);
|
||||
Path tempSrc = Files.createTempFile("hw", ".c");
|
||||
Path tempObj = Files.createTempFile("hw", ".o");
|
||||
Path tempImg = Files.createTempFile("hw", "");
|
||||
try (OutputStream os = new FileOutputStream(tempSrc.toFile())) {
|
||||
os.write("""
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
||||
""".getBytes());
|
||||
}
|
||||
new ProcessBuilder().command(
|
||||
"arm-linux-eabi-gcc", "-c",
|
||||
"-o", tempObj.toAbsolutePath().toString(),
|
||||
tempSrc.toAbsolutePath().toString()).inheritIO().start().waitFor();
|
||||
new ProcessBuilder().command(
|
||||
"arm-linux-eabi-ld",
|
||||
"-o", tempImg.toAbsolutePath().toString(),
|
||||
tempObj.toAbsolutePath().toString()).inheritIO().start().waitFor();
|
||||
return new PathIsFile(tempImg);
|
||||
}
|
||||
|
||||
protected PathIsFile createDummyQemuImage() throws Exception {
|
||||
Path temp = Files.createTempFile("qemudummy", ".bin");
|
||||
try (OutputStream os = new FileOutputStream(temp.toFile())) {
|
||||
os.write(new byte[4096]);
|
||||
}
|
||||
return new PathIsFile(temp);
|
||||
}
|
||||
|
||||
protected LaunchResult doLaunch(String title, Map<String, Object> args) {
|
||||
TraceRmiLaunchOffer offer = Unique.assertOne(
|
||||
launchService.getOffers(program).stream().filter(o -> o.getTitle().equals(title)));
|
||||
return offer.launchProgram(monitor, new LaunchConfigurator() {
|
||||
@Override
|
||||
public Map<String, ValStr<?>> configureLauncher(TraceRmiLaunchOffer offer,
|
||||
Map<String, ValStr<?>> arguments, RelPrompt relPrompt) {
|
||||
Map<String, ValStr<?>> newArgs = new HashMap<>(arguments);
|
||||
for (Map.Entry<String, Object> ent : args.entrySet()) {
|
||||
newArgs.put(ent.getKey(), ValStr.from(ent.getValue()));
|
||||
}
|
||||
return newArgs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PromptMode getPromptMode() {
|
||||
return title.contains("ssh") &&
|
||||
OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS
|
||||
? PromptMode.ALWAYS
|
||||
: PromptMode.NEVER;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void checkResult(LaunchResult result) {
|
||||
if (result.exception() != null &&
|
||||
!(result.exception() instanceof NoStaticMappingException)) {
|
||||
throw new AssertionError(result);
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUpRmiConnectorsTest() throws Exception {
|
||||
// Check manual
|
||||
assumeFalse(SystemUtilities.isInTestingBatchMode());
|
||||
|
||||
addPlugin(tool, DebuggerStaticMappingServicePlugin.class);
|
||||
addPlugin(tool, DebuggerModulesPlugin.class);
|
||||
autoMappingService =
|
||||
Objects.requireNonNull(tool.getService(DebuggerAutoMappingService.class));
|
||||
launchService = addPlugin(tool, TraceRmiLauncherServicePlugin.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/* ###
|
||||
* 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 agent.dbgeng.rmi;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import agent.AbstractRmiConnectorsTest;
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.app.plugin.core.debug.gui.tracermi.launcher.AbstractTraceRmiLaunchOffer.EarlyTerminationException;
|
||||
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer.LaunchResult;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.plugintool.AutoConfigState.PathIsFile;
|
||||
|
||||
public class DbgEngConnectorsTest extends AbstractRmiConnectorsTest {
|
||||
|
||||
@Override
|
||||
protected String getPythonCmd() {
|
||||
return "C:\\Python313\\python";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ResourceFile> getPipLinkModules() {
|
||||
return List.of(
|
||||
Application.getModuleRootDir("Debugger-rmi-trace"),
|
||||
Application.getModuleRootDir("Debugger-agent-dbgeng"));
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUpDbgEng() throws Exception {
|
||||
// Make sure system doesn't cause path failures to pass
|
||||
unpip("ghidradbg", "ghidratrace");
|
||||
// Ensure a compatible version of protobuf
|
||||
pip("protobuf==6.31.0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalDbgSetup() throws Exception {
|
||||
pipOob("protobuf==3.19.0");
|
||||
try (LaunchResult result = doLaunch("dbgeng", Map.ofEntries(
|
||||
Map.entry("env:OPT_TARGET_IMG", chooseImage()),
|
||||
Map.entry("env:OPT_PYTHON_EXE",
|
||||
new PathIsFile(Path.of("C:\\Python313\\python.exe")))))) {
|
||||
assertThat(result.exception(), instanceOf(EarlyTerminationException.class));
|
||||
assertThat(result.sessions().get("Shell").content(),
|
||||
containsString("Would you like to install"));
|
||||
}
|
||||
try (LaunchResult result = doLaunch("dbgeng", Map.ofEntries(
|
||||
Map.entry("env:OPT_TARGET_IMG", chooseImage()),
|
||||
Map.entry("env:OPT_PYTHON_EXE",
|
||||
new PathIsFile(Path.of("C:\\Python313\\python.exe")))))) {
|
||||
checkResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalDbgWithImage() throws Exception {
|
||||
try (LaunchResult result = doLaunch("dbgeng", Map.ofEntries(
|
||||
Map.entry("env:OPT_TARGET_IMG", chooseImage()),
|
||||
Map.entry("env:OPT_PYTHON_EXE",
|
||||
new PathIsFile(Path.of("C:\\Python313\\python.exe")))))) {
|
||||
checkResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
// LATER?: kernel
|
||||
// LATER?: attach (usermode by PID)
|
||||
// LATER?: ext
|
||||
// LATER?: trace (TTD)
|
||||
// LATER?: remote (Start WinDbg and join session)
|
||||
// LATER?: svrcx (what scenario?)
|
||||
}
|
|
@ -52,9 +52,9 @@ import junit.framework.AssertionFailedError;
|
|||
|
||||
public abstract class AbstractDrgnTraceRmiTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
|
||||
protected static String CORE = "core.12137";
|
||||
protected static String MDO = "/New Traces/" + CORE;
|
||||
public static String PREAMBLE = """
|
||||
protected static final String CORE = "core.12137";
|
||||
protected static final String MDO = "/New Traces/" + CORE;
|
||||
public static final String PREAMBLE = """
|
||||
import os
|
||||
import drgn
|
||||
import drgn.cli
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/* ###
|
||||
* 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 agent.drgn.rmi;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import agent.AbstractRmiConnectorsTest;
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.app.plugin.core.debug.gui.tracermi.launcher.AbstractTraceRmiLaunchOffer.EarlyTerminationException;
|
||||
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer.LaunchResult;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.plugintool.AutoConfigState.PathIsFile;
|
||||
|
||||
public class DrgnConnectorsTest extends AbstractRmiConnectorsTest {
|
||||
|
||||
@Override
|
||||
protected List<ResourceFile> getPipLinkModules() {
|
||||
return List.of(
|
||||
Application.getModuleRootDir("Debugger-rmi-trace"),
|
||||
Application.getModuleRootDir("Debugger-agent-drgn"));
|
||||
}
|
||||
|
||||
protected PathIsFile chooseCore() throws FileNotFoundException {
|
||||
return new PathIsFile(Application
|
||||
.getModuleDataFile("TestResources", AbstractDrgnTraceRmiTest.CORE)
|
||||
.getFile(true)
|
||||
.toPath());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUpDrgn() throws Exception {
|
||||
// Make sure system doesn't cause path failures to pass
|
||||
unpip("ghidradrgn", "ghidratrace");
|
||||
// Ensure a compatible version of protobuf
|
||||
pip("protobuf==6.31.0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalDrgnSetup() throws Exception {
|
||||
pipOob("protobuf==3.19.0");
|
||||
try (LaunchResult result = doLaunch("drgn core", Map.ofEntries(
|
||||
Map.entry("env:OPT_TARGET_IMG", chooseCore())))) {
|
||||
assertTrue(result.exception() instanceof EarlyTerminationException);
|
||||
assertThat(result.sessions().get("Shell").content(),
|
||||
Matchers.containsString("Would you like to install"));
|
||||
}
|
||||
try (LaunchResult result = doLaunch("drgn core", Map.ofEntries(
|
||||
Map.entry("env:OPT_TARGET_IMG", chooseCore())))) {
|
||||
checkResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalDrgnWithCore() throws Exception {
|
||||
try (LaunchResult result = doLaunch("drgn core", Map.ofEntries(
|
||||
Map.entry("env:OPT_TARGET_IMG", chooseCore())))) {
|
||||
checkResult(result);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,134 +15,54 @@
|
|||
*/
|
||||
package agent.gdb.rmi;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assume.assumeFalse;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import agent.AbstractRmiConnectorsTest;
|
||||
import db.Transaction;
|
||||
import generic.Unique;
|
||||
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerIntegrationTest;
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.app.plugin.core.debug.gui.action.BySectionAutoMapSpec;
|
||||
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.plugin.core.debug.gui.tracermi.launcher.AbstractTraceRmiLaunchOffer.EarlyTerminationException;
|
||||
import ghidra.app.util.importer.AutoImporter;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.debug.api.ValStr;
|
||||
import ghidra.debug.api.action.AutoMapSpec;
|
||||
import ghidra.debug.api.tracermi.TerminalSession;
|
||||
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer;
|
||||
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer.*;
|
||||
import ghidra.framework.OperatingSystem;
|
||||
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer.LaunchResult;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.plugintool.AutoConfigState.PathIsFile;
|
||||
import ghidra.pty.testutil.DummyProc;
|
||||
import ghidra.util.SystemUtilities;
|
||||
|
||||
public class GdbConnectorsTest extends AbstractGhidraHeadedDebuggerIntegrationTest {
|
||||
private TraceRmiLauncherService launchService;
|
||||
private DebuggerAutoMappingService autoMappingService;
|
||||
public class GdbConnectorsTest extends AbstractRmiConnectorsTest {
|
||||
|
||||
@Override
|
||||
protected List<ResourceFile> getPipLinkModules() {
|
||||
return List.of(
|
||||
Application.getModuleRootDir("Debugger-rmi-trace"),
|
||||
Application.getModuleRootDir("Debugger-agent-gdb"));
|
||||
}
|
||||
|
||||
@Before
|
||||
public void checkManual() throws Exception {
|
||||
assumeFalse(SystemUtilities.isInTestingBatchMode());
|
||||
addPlugin(tool, DebuggerStaticMappingServicePlugin.class);
|
||||
addPlugin(tool, DebuggerModulesPlugin.class);
|
||||
autoMappingService =
|
||||
Objects.requireNonNull(tool.getService(DebuggerAutoMappingService.class));
|
||||
launchService = addPlugin(tool, TraceRmiLauncherServicePlugin.class);
|
||||
}
|
||||
|
||||
protected PathIsFile chooseImage() {
|
||||
if (OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS) {
|
||||
return new PathIsFile(Path.of("C:\\Windows\\notepad.exe"));
|
||||
}
|
||||
return new PathIsFile(Path.of("/bin/ls"));
|
||||
}
|
||||
|
||||
protected PathIsFile findQemu(String bin) {
|
||||
if (OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS) {
|
||||
return new PathIsFile(Path.of("C:\\msys64\\ucrt64\bin\\").resolve(bin));
|
||||
}
|
||||
return new PathIsFile(Path.of(bin));
|
||||
}
|
||||
|
||||
protected PathIsFile createArmElfImage() throws Exception {
|
||||
Path tempSrc = Files.createTempFile("hw", ".c");
|
||||
Path tempObj = Files.createTempFile("hw", ".o");
|
||||
Path tempImg = Files.createTempFile("hw", "");
|
||||
try (OutputStream os = new FileOutputStream(tempSrc.toFile())) {
|
||||
os.write("""
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
||||
""".getBytes());
|
||||
}
|
||||
new ProcessBuilder().command(
|
||||
"arm-linux-eabi-gcc", "-c",
|
||||
"-o", tempObj.toAbsolutePath().toString(),
|
||||
tempSrc.toAbsolutePath().toString()).inheritIO().start().waitFor();
|
||||
new ProcessBuilder().command(
|
||||
"arm-linux-eabi-ld",
|
||||
"-o", tempImg.toAbsolutePath().toString(),
|
||||
tempObj.toAbsolutePath().toString()).inheritIO().start().waitFor();
|
||||
return new PathIsFile(tempImg);
|
||||
}
|
||||
|
||||
protected PathIsFile createDummyQemuImage() throws Exception {
|
||||
Path temp = Files.createTempFile("qemudummy", ".bin");
|
||||
try (OutputStream os = new FileOutputStream(temp.toFile())) {
|
||||
os.write(new byte[4096]);
|
||||
}
|
||||
return new PathIsFile(temp);
|
||||
}
|
||||
|
||||
protected LaunchResult doLaunch(String title, Map<String, Object> args) {
|
||||
TraceRmiLaunchOffer offer = Unique.assertOne(
|
||||
launchService.getOffers(program).stream().filter(o -> o.getTitle().equals(title)));
|
||||
return offer.launchProgram(monitor, new LaunchConfigurator() {
|
||||
@Override
|
||||
public Map<String, ValStr<?>> configureLauncher(TraceRmiLaunchOffer offer,
|
||||
Map<String, ValStr<?>> arguments, RelPrompt relPrompt) {
|
||||
Map<String, ValStr<?>> newArgs = new HashMap<>(arguments);
|
||||
for (Map.Entry<String, Object> ent : args.entrySet()) {
|
||||
newArgs.put(ent.getKey(), ValStr.from(ent.getValue()));
|
||||
}
|
||||
return newArgs;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void checkResult(LaunchResult result) {
|
||||
if (result.exception() != null &&
|
||||
!(result.exception() instanceof NoStaticMappingException)) {
|
||||
throw new AssertionError(result);
|
||||
}
|
||||
public void setUpGdb() throws Exception {
|
||||
// Make sure system doesn't cause path failures to pass
|
||||
unpip("ghidragdb", "ghidratrace");
|
||||
// Ensure a compatible version of protobuf
|
||||
pip("protobuf==6.31.0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalGdbSetup() throws Exception {
|
||||
new ProcessBuilder().command("pip", "install", "protobuf==3.19.0")
|
||||
.inheritIO()
|
||||
.start()
|
||||
.waitFor();
|
||||
pipOob("protobuf==3.19.0");
|
||||
try (LaunchResult result = doLaunch("gdb", Map.of("arg:1", chooseImage()))) {
|
||||
assertTrue(result.exception() instanceof SocketTimeoutException);
|
||||
TerminalSession term = Unique.assertOne(result.sessions().values());
|
||||
while (!term.isTerminated()) {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
assertTrue(result.exception() instanceof EarlyTerminationException);
|
||||
assertThat(result.sessions().get("Shell").content(),
|
||||
Matchers.containsString("Would you like to install"));
|
||||
}
|
||||
try (LaunchResult result = doLaunch("gdb", Map.of("arg:1", chooseImage()))) {
|
||||
checkResult(result);
|
||||
|
@ -206,6 +126,7 @@ public class GdbConnectorsTest extends AbstractGhidraHeadedDebuggerIntegrationTe
|
|||
|
||||
@Test
|
||||
public void testGdbViaSsh() throws Exception {
|
||||
pip("ghidragdb==%s".formatted(Application.getApplicationVersion()));
|
||||
try (LaunchResult result = doLaunch("gdb via ssh", Map.ofEntries(
|
||||
Map.entry("arg:1", "/bin/ls"),
|
||||
Map.entry("OPT_HOST", "localhost")))) {
|
||||
|
@ -215,15 +136,12 @@ public class GdbConnectorsTest extends AbstractGhidraHeadedDebuggerIntegrationTe
|
|||
|
||||
@Test
|
||||
public void testGdbViaSshSetupGhidraGdb() throws Exception {
|
||||
new ProcessBuilder().command("pip", "uninstall", "ghidragdb").inheritIO().start().waitFor();
|
||||
try (LaunchResult result = doLaunch("gdb via ssh", Map.ofEntries(
|
||||
Map.entry("arg:1", "/bin/ls"),
|
||||
Map.entry("OPT_HOST", "localhost")))) {
|
||||
assertTrue(result.exception() instanceof SocketTimeoutException);
|
||||
TerminalSession term = Unique.assertOne(result.sessions().values());
|
||||
while (!term.isTerminated()) {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
assertTrue(result.exception() instanceof EarlyTerminationException);
|
||||
assertThat(result.sessions().get("Shell").content(),
|
||||
Matchers.containsString("Would you like to install"));
|
||||
}
|
||||
try (LaunchResult result = doLaunch("gdb via ssh", Map.ofEntries(
|
||||
Map.entry("arg:1", "/bin/ls"),
|
||||
|
@ -234,18 +152,15 @@ public class GdbConnectorsTest extends AbstractGhidraHeadedDebuggerIntegrationTe
|
|||
|
||||
@Test
|
||||
public void testGdbViaSshSetupProtobuf() throws Exception {
|
||||
new ProcessBuilder().command("pip", "install", "protobuf==3.19.0")
|
||||
.inheritIO()
|
||||
.start()
|
||||
.waitFor();
|
||||
pip("ghidragdb==%s".formatted(Application.getApplicationVersion()));
|
||||
// Overwrite with an incompatible version we don't include
|
||||
pipOob("protobuf==3.19.0");
|
||||
try (LaunchResult result = doLaunch("gdb via ssh", Map.ofEntries(
|
||||
Map.entry("arg:1", "/bin/ls"),
|
||||
Map.entry("OPT_HOST", "localhost")))) {
|
||||
assertTrue(result.exception() instanceof SocketTimeoutException);
|
||||
TerminalSession term = Unique.assertOne(result.sessions().values());
|
||||
while (!term.isTerminated()) {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
assertTrue(result.exception() instanceof EarlyTerminationException);
|
||||
assertThat(result.sessions().get("Shell").content(),
|
||||
Matchers.containsString("Would you like to install"));
|
||||
}
|
||||
try (LaunchResult result = doLaunch("gdb via ssh", Map.ofEntries(
|
||||
Map.entry("arg:1", "/bin/ls"),
|
||||
|
|
|
@ -15,132 +15,52 @@
|
|||
*/
|
||||
package agent.lldb.rmi;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assume.assumeFalse;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.*;
|
||||
|
||||
import agent.AbstractRmiConnectorsTest;
|
||||
import db.Transaction;
|
||||
import generic.Unique;
|
||||
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerIntegrationTest;
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.app.plugin.core.debug.gui.action.BySectionAutoMapSpec;
|
||||
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.plugin.core.debug.gui.tracermi.launcher.AbstractTraceRmiLaunchOffer.EarlyTerminationException;
|
||||
import ghidra.app.util.importer.AutoImporter;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.debug.api.ValStr;
|
||||
import ghidra.debug.api.action.AutoMapSpec;
|
||||
import ghidra.debug.api.tracermi.TerminalSession;
|
||||
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer;
|
||||
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer.*;
|
||||
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer.LaunchResult;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.OperatingSystem;
|
||||
import ghidra.framework.plugintool.AutoConfigState.PathIsFile;
|
||||
import ghidra.pty.testutil.DummyProc;
|
||||
import ghidra.util.SystemUtilities;
|
||||
|
||||
/**
|
||||
* NOTE: On Windows, these tests may need to be run with lldb's version of Python at the front of
|
||||
* PATH, and it's lib and DLLs dirs at the front of PYTHONPATH. It's probably easiest to just get
|
||||
* PATH, and its lib and DLLs dirs at the front of PYTHONPATH. It's probably easiest to just get
|
||||
* lldb working in a command prompt. Ensure that it can import socket, and then re-launch Eclipse
|
||||
* from there.
|
||||
*/
|
||||
public class LldbConnectorsTest extends AbstractGhidraHeadedDebuggerIntegrationTest {
|
||||
private TraceRmiLauncherService launchService;
|
||||
private DebuggerAutoMappingService autoMappingService;
|
||||
public class LldbConnectorsTest extends AbstractRmiConnectorsTest {
|
||||
|
||||
@Override
|
||||
protected List<ResourceFile> getPipLinkModules() {
|
||||
return List.of(
|
||||
Application.getModuleRootDir("Debugger-rmi-trace"),
|
||||
Application.getModuleRootDir("Debugger-agent-lldb"));
|
||||
}
|
||||
|
||||
@Before
|
||||
public void checkManual() throws Exception {
|
||||
assumeFalse(SystemUtilities.isInTestingBatchMode());
|
||||
addPlugin(tool, DebuggerStaticMappingServicePlugin.class);
|
||||
addPlugin(tool, DebuggerModulesPlugin.class);
|
||||
autoMappingService =
|
||||
Objects.requireNonNull(tool.getService(DebuggerAutoMappingService.class));
|
||||
launchService = addPlugin(tool, TraceRmiLauncherServicePlugin.class);
|
||||
}
|
||||
|
||||
protected PathIsFile chooseImage() {
|
||||
if (OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS) {
|
||||
return new PathIsFile(Path.of("C:\\Windows\\notepad.exe"));
|
||||
}
|
||||
return new PathIsFile(Path.of("/bin/ls"));
|
||||
}
|
||||
|
||||
protected PathIsFile findQemu(String bin) {
|
||||
if (OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS) {
|
||||
return new PathIsFile(Path.of("C:\\msys64\\ucrt64\bin\\").resolve(bin));
|
||||
}
|
||||
return new PathIsFile(Path.of(bin));
|
||||
}
|
||||
|
||||
protected PathIsFile createArmElfImage() throws Exception {
|
||||
assumeTrue(OperatingSystem.LINUX == OperatingSystem.CURRENT_OPERATING_SYSTEM);
|
||||
Path tempSrc = Files.createTempFile("hw", ".c");
|
||||
Path tempObj = Files.createTempFile("hw", ".o");
|
||||
Path tempImg = Files.createTempFile("hw", "");
|
||||
try (OutputStream os = new FileOutputStream(tempSrc.toFile())) {
|
||||
os.write("""
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
||||
""".getBytes());
|
||||
}
|
||||
new ProcessBuilder().command(
|
||||
"arm-linux-eabi-gcc", "-c",
|
||||
"-o", tempObj.toAbsolutePath().toString(),
|
||||
tempSrc.toAbsolutePath().toString()).inheritIO().start().waitFor();
|
||||
new ProcessBuilder().command(
|
||||
"arm-linux-eabi-ld",
|
||||
"-o", tempImg.toAbsolutePath().toString(),
|
||||
tempObj.toAbsolutePath().toString()).inheritIO().start().waitFor();
|
||||
return new PathIsFile(tempImg);
|
||||
}
|
||||
|
||||
protected PathIsFile createDummyQemuImage() throws Exception {
|
||||
Path temp = Files.createTempFile("qemudummy", ".bin");
|
||||
try (OutputStream os = new FileOutputStream(temp.toFile())) {
|
||||
os.write(new byte[4096]);
|
||||
}
|
||||
return new PathIsFile(temp);
|
||||
}
|
||||
|
||||
protected LaunchResult doLaunch(String title, Map<String, Object> args) {
|
||||
TraceRmiLaunchOffer offer = Unique.assertOne(
|
||||
launchService.getOffers(program).stream().filter(o -> o.getTitle().equals(title)));
|
||||
return offer.launchProgram(monitor, new LaunchConfigurator() {
|
||||
@Override
|
||||
public Map<String, ValStr<?>> configureLauncher(TraceRmiLaunchOffer offer,
|
||||
Map<String, ValStr<?>> arguments, RelPrompt relPrompt) {
|
||||
Map<String, ValStr<?>> newArgs = new HashMap<>(arguments);
|
||||
for (Map.Entry<String, Object> ent : args.entrySet()) {
|
||||
newArgs.put(ent.getKey(), ValStr.from(ent.getValue()));
|
||||
}
|
||||
return newArgs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PromptMode getPromptMode() {
|
||||
return title.contains("ssh") ? PromptMode.ALWAYS : PromptMode.NEVER;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void checkResult(LaunchResult result) {
|
||||
if (result.exception() != null &&
|
||||
!(result.exception() instanceof NoStaticMappingException)) {
|
||||
throw new AssertionError(result);
|
||||
}
|
||||
public void setupLldb() throws Exception {
|
||||
// Make sure system doesn't cause path failures to pass
|
||||
unpip("ghidralldb", "ghidratrace");
|
||||
// Ensure a compatible version of protobuf
|
||||
pip("protobuf==6.31.0");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -149,24 +69,17 @@ public class LldbConnectorsTest extends AbstractGhidraHeadedDebuggerIntegrationT
|
|||
* package missing and exits with code 253. May just have to cut losses there. The message hits
|
||||
* the screen, and this circumstance <em>should</em> be rare.
|
||||
*
|
||||
* @throws Exception
|
||||
* @throws Exception because
|
||||
*/
|
||||
@Test
|
||||
public void testLocalLldbSetup() throws Exception {
|
||||
new ProcessBuilder().command("python", "-m", "pip", "install", "protobuf==3.19.0")
|
||||
.inheritIO()
|
||||
.start()
|
||||
.waitFor();
|
||||
pipOob("protobuf==3.19.0");
|
||||
try (LaunchResult result = doLaunch("lldb", Map.of("arg:1", chooseImage()))) {
|
||||
assertTrue(result.exception() instanceof SocketTimeoutException);
|
||||
TerminalSession term = Unique.assertOne(result.sessions().values());
|
||||
while (!term.isTerminated()) {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
try (LaunchResult result = doLaunch("lldb", Map.of("arg:1", chooseImage()))) {
|
||||
checkResult(result);
|
||||
assertTrue(result.exception() instanceof EarlyTerminationException);
|
||||
assertThat(result.sessions().get("Shell").content(),
|
||||
Matchers.containsString("Would you like to install"));
|
||||
}
|
||||
// NOTE: lldb will not let me prompt the user, so cannot test automatic mitigation
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -219,7 +132,7 @@ public class LldbConnectorsTest extends AbstractGhidraHeadedDebuggerIntegrationT
|
|||
* This has proven difficult to test on Windows, probably because the version of lldb and
|
||||
* gdbserver I'm using are not compatible?
|
||||
*
|
||||
* @throws Exception
|
||||
* @throws Exception because
|
||||
*/
|
||||
@Test
|
||||
public void testLldbRemoteGdb() throws Exception {
|
||||
|
@ -237,6 +150,7 @@ public class LldbConnectorsTest extends AbstractGhidraHeadedDebuggerIntegrationT
|
|||
|
||||
@Test
|
||||
public void testLldbViaSsh() throws Exception {
|
||||
pip("ghidralldb==%s".formatted(Application.getApplicationVersion()));
|
||||
try (LaunchResult result = doLaunch("lldb via ssh", Map.ofEntries(
|
||||
Map.entry("arg:1", "/bin/ls"),
|
||||
Map.entry("OPT_HOST", "localhost")))) {
|
||||
|
@ -246,19 +160,12 @@ public class LldbConnectorsTest extends AbstractGhidraHeadedDebuggerIntegrationT
|
|||
|
||||
@Test
|
||||
public void testLldbViaSshSetupGhidraLldb() throws Exception {
|
||||
// This only applies if we leave localhost in the dialog
|
||||
new ProcessBuilder().command("python", "-m", "pip", "uninstall", "ghidralldb")
|
||||
.inheritIO()
|
||||
.start()
|
||||
.waitFor();
|
||||
try (LaunchResult result = doLaunch("lldb via ssh", Map.ofEntries(
|
||||
Map.entry("arg:1", "/bin/ls"),
|
||||
Map.entry("OPT_HOST", "localhost")))) {
|
||||
assertTrue(result.exception() instanceof SocketTimeoutException);
|
||||
TerminalSession term = Unique.assertOne(result.sessions().values());
|
||||
while (!term.isTerminated()) {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
assertTrue(result.exception() instanceof EarlyTerminationException);
|
||||
assertThat(result.sessions().get("Shell").content(),
|
||||
Matchers.containsString("Would you like to install"));
|
||||
}
|
||||
try (LaunchResult result = doLaunch("lldb via ssh", Map.ofEntries(
|
||||
Map.entry("arg:1", "/bin/ls"),
|
||||
|
@ -269,18 +176,15 @@ public class LldbConnectorsTest extends AbstractGhidraHeadedDebuggerIntegrationT
|
|||
|
||||
@Test
|
||||
public void testLldbViaSshSetupProtobuf() throws Exception {
|
||||
new ProcessBuilder().command("python", "-m", "pip", "install", "protobuf==3.19.0")
|
||||
.inheritIO()
|
||||
.start()
|
||||
.waitFor();
|
||||
pip("ghidralldb==%s".formatted(Application.getApplicationVersion()));
|
||||
// Overwrite with an incompatible version we don't include
|
||||
pipOob("protobuf==3.19.0");
|
||||
try (LaunchResult result = doLaunch("lldb via ssh", Map.ofEntries(
|
||||
Map.entry("arg:1", "/bin/ls"),
|
||||
Map.entry("OPT_HOST", "localhost")))) {
|
||||
assertTrue(result.exception() instanceof SocketTimeoutException);
|
||||
TerminalSession term = Unique.assertOne(result.sessions().values());
|
||||
while (!term.isTerminated()) {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
assertTrue(result.exception() instanceof EarlyTerminationException);
|
||||
assertThat(result.sessions().get("Shell").content(),
|
||||
Matchers.containsString("Would you like to install"));
|
||||
}
|
||||
try (LaunchResult result = doLaunch("lldb via ssh", Map.ofEntries(
|
||||
Map.entry("arg:1", "/bin/ls"),
|
||||
|
|
|
@ -187,7 +187,7 @@ public class ScriptTraceRmiLaunchOfferTest extends AbstractGhidraHeadedDebuggerT
|
|||
}
|
||||
|
||||
@Override
|
||||
public void terminated() {
|
||||
public void terminated(int exitcode) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -67,8 +67,10 @@ public class TestTraceRmiLaunchOpinion implements TraceRmiLaunchOpinion {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void launchBackEnd(TaskMonitor monitor, Map<String, TerminalSession> sessions,
|
||||
protected TraceRmiBackEnd launchBackEnd(TaskMonitor monitor,
|
||||
Map<String, TerminalSession> sessions,
|
||||
Map<String, ValStr<?>> args, SocketAddress address) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue