mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 02:09:44 +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
|
::@menu-group dbgeng
|
||||||
::@icon icon.debugger
|
::@icon icon.debugger
|
||||||
::@help dbgeng#win_kernel
|
::@help dbgeng#win_kernel
|
||||||
|
::@depends Debugger-rmi-trace
|
||||||
::@enum Connection:str Remote Local EXDI
|
::@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."
|
::@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
|
:: Use env instead of args, because "all args except first" is terrible to implement in batch
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
::@menu-group dbgeng
|
::@menu-group dbgeng
|
||||||
::@icon icon.debugger
|
::@icon icon.debugger
|
||||||
::@help dbgeng#attach
|
::@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_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_TARGET_PID:int=0 "Process id" "The target process id"
|
||||||
::@env OPT_ATTACH_FLAGS:int=0 "Attach flags" "Attach flags"
|
::@env OPT_ATTACH_FLAGS:int=0 "Attach flags" "Attach flags"
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
::@menu-group dbgeng
|
::@menu-group dbgeng
|
||||||
::@icon icon.debugger
|
::@icon icon.debugger
|
||||||
::@help dbgeng#ext
|
::@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."
|
::@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
|
:: Use env instead of args, because "all args except first" is terrible to implement in batch
|
||||||
::@env OPT_TARGET_IMG:file="" "Image" "The target binary executable image"
|
::@env OPT_TARGET_IMG:file="" "Image" "The target binary executable image"
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
::@menu-group dbgeng
|
::@menu-group dbgeng
|
||||||
::@icon icon.debugger
|
::@icon icon.debugger
|
||||||
::@help dbgeng#ttd
|
::@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."
|
::@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
|
:: 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"
|
::@env OPT_TARGET_TRACE:file="" "Trace (.run)" "The target trace image"
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
::@menu-group dbgeng
|
::@menu-group dbgeng
|
||||||
::@icon icon.debugger
|
::@icon icon.debugger
|
||||||
::@help dbgeng#local
|
::@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."
|
::@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
|
:: Use env instead of args, because "all args except first" is terrible to implement in batch
|
||||||
::@env OPT_TARGET_IMG:file="" "Image" "The target binary executable image"
|
::@env OPT_TARGET_IMG:file="" "Image" "The target binary executable image"
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
::@menu-group dbgeng
|
::@menu-group dbgeng
|
||||||
::@icon icon.debugger
|
::@icon icon.debugger
|
||||||
::@help dbgeng#remote
|
::@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_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 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)."
|
::@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
|
::@menu-group dbgeng
|
||||||
::@icon icon.debugger
|
::@icon icon.debugger
|
||||||
::@help dbgeng#svrcx
|
::@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."
|
::@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
|
:: Use env instead of args, because "all args except first" is terrible to implement in batch
|
||||||
::@env OPT_TARGET_IMG:str="" "Image" "The target binary executable image"
|
::@env OPT_TARGET_IMG:str="" "Image" "The target binary executable image"
|
||||||
|
|
|
@ -19,10 +19,11 @@ import sys
|
||||||
|
|
||||||
|
|
||||||
def append_paths():
|
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
|
from gmodutils import ghidra_module_pypath
|
||||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-rmi-trace"))
|
sys.path.append(ghidra_module_pypath("Debugger-rmi-trace"))
|
||||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
|
sys.path.append(ghidra_module_pypath())
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -19,10 +19,11 @@ import sys
|
||||||
|
|
||||||
|
|
||||||
def append_paths():
|
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
|
from gmodutils import ghidra_module_pypath
|
||||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-rmi-trace"))
|
sys.path.append(ghidra_module_pypath("Debugger-rmi-trace"))
|
||||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
|
sys.path.append(ghidra_module_pypath())
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -19,10 +19,11 @@ import sys
|
||||||
|
|
||||||
|
|
||||||
def append_paths():
|
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
|
from gmodutils import ghidra_module_pypath
|
||||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-rmi-trace"))
|
sys.path.append(ghidra_module_pypath("Debugger-rmi-trace"))
|
||||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
|
sys.path.append(ghidra_module_pypath())
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -19,10 +19,11 @@ import sys
|
||||||
|
|
||||||
|
|
||||||
def append_paths():
|
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
|
from gmodutils import ghidra_module_pypath
|
||||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-rmi-trace"))
|
sys.path.append(ghidra_module_pypath("Debugger-rmi-trace"))
|
||||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
|
sys.path.append(ghidra_module_pypath())
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -19,10 +19,11 @@ import sys
|
||||||
|
|
||||||
|
|
||||||
def append_paths():
|
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
|
from gmodutils import ghidra_module_pypath
|
||||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-rmi-trace"))
|
sys.path.append(ghidra_module_pypath("Debugger-rmi-trace"))
|
||||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
|
sys.path.append(ghidra_module_pypath())
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -19,10 +19,11 @@ import sys
|
||||||
|
|
||||||
|
|
||||||
def append_paths():
|
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
|
from gmodutils import ghidra_module_pypath
|
||||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-rmi-trace"))
|
sys.path.append(ghidra_module_pypath("Debugger-rmi-trace"))
|
||||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
|
sys.path.append(ghidra_module_pypath())
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -21,10 +21,11 @@ import sys
|
||||||
|
|
||||||
|
|
||||||
def append_paths():
|
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
|
from gmodutils import ghidra_module_pypath
|
||||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-rmi-trace"))
|
sys.path.append(ghidra_module_pypath("Debugger-rmi-trace"))
|
||||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
|
sys.path.append(ghidra_module_pypath())
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -19,10 +19,11 @@ import sys
|
||||||
|
|
||||||
|
|
||||||
def append_paths():
|
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
|
from gmodutils import ghidra_module_pypath
|
||||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-rmi-trace"))
|
sys.path.append(ghidra_module_pypath("Debugger-rmi-trace"))
|
||||||
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
|
sys.path.append(ghidra_module_pypath())
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -18,7 +18,7 @@ try:
|
||||||
import pybag
|
import pybag
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
from ghidratrace.setuputils import prompt_and_mitigate_dependencies
|
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
|
# NOTE: libraries must precede EVERYTHING, esp pybag and DbgMod
|
||||||
from . import libraries, util, commands, methods, hooks
|
from . import libraries, util, commands, methods, hooks
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#@menu-group drgn
|
#@menu-group drgn
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help drgn#core
|
#@help drgn#core
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@env OPT_TARGET_IMG:file!="" "Core dump" "The target core dump"
|
#@env OPT_TARGET_IMG:file!="" "Core dump" "The target core dump"
|
||||||
|
|
||||||
export OPT_TARGET_KIND="coredump"
|
export OPT_TARGET_KIND="coredump"
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#@menu-group drgn
|
#@menu-group drgn
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help drgn#linux_kernel
|
#@help drgn#linux_kernel
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
|
|
||||||
export OPT_TARGET_KIND="kernel"
|
export OPT_TARGET_KIND="kernel"
|
||||||
sudo -E drgn ../support/local-drgn.py
|
sudo -E drgn ../support/local-drgn.py
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#@menu-group drgn
|
#@menu-group drgn
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help drgn#attach
|
#@help drgn#attach
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@env OPT_TARGET_PID:int=44068 "PID" "The target's process id"
|
#@env OPT_TARGET_PID:int=44068 "PID" "The target's process id"
|
||||||
|
|
||||||
export OPT_TARGET_KIND="user"
|
export OPT_TARGET_KIND="user"
|
||||||
|
|
|
@ -22,25 +22,18 @@ import sys
|
||||||
|
|
||||||
import drgn.cli
|
import drgn.cli
|
||||||
|
|
||||||
home = os.getenv('GHIDRA_HOME')
|
|
||||||
|
|
||||||
if os.path.isdir(f'{home}/ghidra/.git'):
|
def append_paths():
|
||||||
sys.path.append(
|
sys.path.append(
|
||||||
f'{home}/ghidra/Ghidra/Debug/Debugger-agent-drgn/build/pypkg/src')
|
f"{os.getenv('MODULE_Debugger_rmi_trace_HOME')}/data/support")
|
||||||
sys.path.append(
|
from gmodutils import ghidra_module_pypath
|
||||||
f'{home}/ghidra/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src')
|
sys.path.append(ghidra_module_pypath("Debugger-rmi-trace"))
|
||||||
elif os.path.isdir(f'{home}/.git'):
|
sys.path.append(ghidra_module_pypath())
|
||||||
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')
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
append_paths()
|
||||||
|
|
||||||
from ghidradrgn import commands as cmd
|
from ghidradrgn import commands as cmd
|
||||||
cmd.ghidra_trace_connect(address=os.getenv('GHIDRA_TRACE_RMI_ADDR'))
|
cmd.ghidra_trace_connect(address=os.getenv('GHIDRA_TRACE_RMI_ADDR'))
|
||||||
cmd.ghidra_trace_create(start_trace=True)
|
cmd.ghidra_trace_create(start_trace=True)
|
||||||
|
@ -49,9 +42,7 @@ def main():
|
||||||
cmd.ghidra_trace_txcommit()
|
cmd.ghidra_trace_txcommit()
|
||||||
cmd.ghidra_trace_activate()
|
cmd.ghidra_trace_activate()
|
||||||
drgn.cli.run_interactive(cmd.prog)
|
drgn.cli.run_interactive(cmd.prog)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#@menu-group gdb
|
#@menu-group gdb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help gdb#local
|
#@help gdb#local
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@enum StartCmd:str run start starti
|
#@enum StartCmd:str run start starti
|
||||||
#@enum Endian:str auto big little
|
#@enum Endian:str auto big little
|
||||||
#@arg :file "Image" "The target binary executable image"
|
#@arg :file "Image" "The target binary executable image"
|
||||||
|
@ -21,8 +22,8 @@
|
||||||
|
|
||||||
. ..\support\gdbsetuputils.ps1
|
. ..\support\gdbsetuputils.ps1
|
||||||
|
|
||||||
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
|
$pypathTrace = Ghidra-Module-PyPath "Debugger-rmi-trace"
|
||||||
$pypathGdb = Ghidra-Module-PyPath "Debug/Debugger-agent-gdb"
|
$pypathGdb = Ghidra-Module-PyPath
|
||||||
$Env:PYTHONPATH = "$pypathGdb;$pypathTrace;$Env:PYTHONPATH"
|
$Env:PYTHONPATH = "$pypathGdb;$pypathTrace;$Env:PYTHONPATH"
|
||||||
|
|
||||||
$arglist = Compute-Gdb-Usermode-Args `
|
$arglist = Compute-Gdb-Usermode-Args `
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#@menu-group gdb
|
#@menu-group gdb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help gdb#local
|
#@help gdb#local
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@enum StartCmd:str run start starti
|
#@enum StartCmd:str run start starti
|
||||||
#@enum Endian:str auto big little
|
#@enum Endian:str auto big little
|
||||||
#@arg :file "Image" "The target binary executable image, empty for no target"
|
#@arg :file "Image" "The target binary executable image, empty for no target"
|
||||||
|
@ -39,8 +40,8 @@
|
||||||
|
|
||||||
. ../support/gdbsetuputils.sh
|
. ../support/gdbsetuputils.sh
|
||||||
|
|
||||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||||
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
|
pypathGdb=$(ghidra-module-pypath)
|
||||||
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
||||||
|
|
||||||
target_image="$1"
|
target_image="$1"
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#@menu-group gdb
|
#@menu-group gdb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help gdb#rr
|
#@help gdb#rr
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@enum StartCmd:str run start starti
|
#@enum StartCmd:str run start starti
|
||||||
#@enum Endian:str auto big little
|
#@enum Endian:str auto big little
|
||||||
#@arg :file "Trace Dir" "The target trace directory (e.g. .local/share/rr/trace)"
|
#@arg :file "Trace Dir" "The target trace directory (e.g. .local/share/rr/trace)"
|
||||||
|
@ -36,8 +37,8 @@
|
||||||
|
|
||||||
. ../support/gdbsetuputils.sh
|
. ../support/gdbsetuputils.sh
|
||||||
|
|
||||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||||
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
|
pypathGdb=$(ghidra-module-pypath)
|
||||||
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
||||||
|
|
||||||
target_trace="$1"
|
target_trace="$1"
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#@menu-group gdb
|
#@menu-group gdb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help gdb#qemu
|
#@help gdb#qemu
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@enum Endian:str auto big little
|
#@enum Endian:str auto big little
|
||||||
#@arg :file! "Image" "The target binary executable image"
|
#@arg :file! "Image" "The target binary executable image"
|
||||||
#@args "Arguments" "Command-line arguments to pass to the target"
|
#@args "Arguments" "Command-line arguments to pass to the target"
|
||||||
|
@ -42,8 +43,8 @@
|
||||||
|
|
||||||
. ../support/gdbsetuputils.sh
|
. ../support/gdbsetuputils.sh
|
||||||
|
|
||||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||||
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
|
pypathGdb=$(ghidra-module-pypath)
|
||||||
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
||||||
|
|
||||||
target_image="$1"
|
target_image="$1"
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#@menu-group gdb
|
#@menu-group gdb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help gdb#qemu
|
#@help gdb#qemu
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@enum Endian:str auto big little
|
#@enum Endian:str auto big little
|
||||||
#@env OPT_TARGET_IMG:file!="" "Image" "The target binary executable image"
|
#@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."
|
#@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
|
. ..\support\gdbsetuputils.ps1
|
||||||
|
|
||||||
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
|
$pypathTrace = Ghidra-Module-PyPath "Debugger-rmi-trace"
|
||||||
$pypathGdb = Ghidra-Module-PyPath "Debug/Debugger-agent-gdb"
|
$pypathGdb = Ghidra-Module-PyPath
|
||||||
$Env:PYTHONPATH = "$pypathGdb;$pypathTrace;$Env:PYTHONPATH"
|
$Env:PYTHONPATH = "$pypathGdb;$pypathTrace;$Env:PYTHONPATH"
|
||||||
|
|
||||||
$qemuargs = @("`"$Env:GHIDRA_LANG_EXTTOOL_qemu_system`"")
|
$qemuargs = @("`"$Env:GHIDRA_LANG_EXTTOOL_qemu_system`"")
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#@menu-group gdb
|
#@menu-group gdb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help gdb#qemu
|
#@help gdb#qemu
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@enum Endian:str auto big little
|
#@enum Endian:str auto big little
|
||||||
#@arg :file! "Image" "The target binary executable image"
|
#@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."
|
#@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
|
. ../support/gdbsetuputils.sh
|
||||||
|
|
||||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||||
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
|
pypathGdb=$(ghidra-module-pypath)
|
||||||
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
||||||
|
|
||||||
target_image="$1"
|
target_image="$1"
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#@menu-group gdb
|
#@menu-group gdb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help gdb#remote
|
#@help gdb#remote
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@enum TargetType:str remote extended-remote
|
#@enum TargetType:str remote extended-remote
|
||||||
#@enum Endian:str auto big little
|
#@enum Endian:str auto big little
|
||||||
#@arg :file "Image" "The target binary executable image (a copy on the local system)"
|
#@arg :file "Image" "The target binary executable image (a copy on the local system)"
|
||||||
|
@ -22,8 +23,8 @@
|
||||||
|
|
||||||
. ..\support\gdbsetuputils.ps1
|
. ..\support\gdbsetuputils.ps1
|
||||||
|
|
||||||
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
|
$pypathTrace = Ghidra-Module-PyPath "Debugger-rmi-trace"
|
||||||
$pypathGdb = Ghidra-Module-PyPath "Debug/Debugger-agent-gdb"
|
$pypathGdb = Ghidra-Module-PyPath
|
||||||
$Env:PYTHONPATH = "$pypathGdb;$pypathTrace;$Env:PYTHONPATH"
|
$Env:PYTHONPATH = "$pypathGdb;$pypathTrace;$Env:PYTHONPATH"
|
||||||
|
|
||||||
$arglist = Compute-Gdb-Remote-Args `
|
$arglist = Compute-Gdb-Remote-Args `
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#@menu-group gdb
|
#@menu-group gdb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help gdb#remote
|
#@help gdb#remote
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@enum TargetType:str remote extended-remote
|
#@enum TargetType:str remote extended-remote
|
||||||
#@enum Endian:str auto big little
|
#@enum Endian:str auto big little
|
||||||
#@arg :file "Image" "The target binary executable image (a copy on the local system)"
|
#@arg :file "Image" "The target binary executable image (a copy on the local system)"
|
||||||
|
@ -38,8 +39,8 @@
|
||||||
|
|
||||||
. ../support/gdbsetuputils.sh
|
. ../support/gdbsetuputils.sh
|
||||||
|
|
||||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||||
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
|
pypathGdb=$(ghidra-module-pypath)
|
||||||
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
||||||
|
|
||||||
target_image="$1"
|
target_image="$1"
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#@timeout 60000
|
|
||||||
#@title gdb via ssh
|
#@title gdb via ssh
|
||||||
#@image-opt arg:1
|
#@image-opt arg:1
|
||||||
#@desc <html><body width="300px">
|
#@desc <html><body width="300px">
|
||||||
|
@ -11,6 +10,7 @@
|
||||||
#@menu-group gdb
|
#@menu-group gdb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help gdb#ssh
|
#@help gdb#ssh
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@enum StartCmd:str run start starti
|
#@enum StartCmd:str run start starti
|
||||||
#@enum Endian:str auto big little
|
#@enum Endian:str auto big little
|
||||||
#@arg :str "Image" "The target binary executable image on the remote system"
|
#@arg :str "Image" "The target binary executable image on the remote system"
|
||||||
|
@ -61,7 +61,7 @@ finished, try launching again.
|
||||||
|
|
||||||
if ($answer) {
|
if ($answer) {
|
||||||
Write-Host "Copying Wheels to $Env:OPT_HOST"
|
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"
|
Write-Host "Installing Wheels into GDB's embedded Python"
|
||||||
$arglist = Compute-Gdb-PipInstall-Args "'-f'" "os.environ['HOME']" "'ghidragdb>=$version'"
|
$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
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
##
|
##
|
||||||
#@timeout 60000
|
|
||||||
#@title gdb via ssh
|
#@title gdb via ssh
|
||||||
#@image-opt arg:1
|
#@image-opt arg:1
|
||||||
#@desc <html><body width="300px">
|
#@desc <html><body width="300px">
|
||||||
|
@ -27,6 +26,7 @@
|
||||||
#@menu-group gdb
|
#@menu-group gdb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help gdb#ssh
|
#@help gdb#ssh
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@enum StartCmd:str run start starti
|
#@enum StartCmd:str run start starti
|
||||||
#@enum Endian:str auto big little
|
#@enum Endian:str auto big little
|
||||||
#@arg :str "Image" "The target binary executable image on the remote system"
|
#@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
|
" "Would you like to install 'ghidragdb>=$version'?"; then
|
||||||
|
|
||||||
echo "Copying Wheels to $OPT_HOST"
|
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"
|
echo "Installing Wheels into GDB's embedded Python"
|
||||||
do-installation
|
do-installation
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#@timeout 60000
|
|
||||||
#@title gdb + gdbserver via ssh
|
#@title gdb + gdbserver via ssh
|
||||||
#@image-opt arg:1
|
#@image-opt arg:1
|
||||||
#@desc <html><body width="300px">
|
#@desc <html><body width="300px">
|
||||||
|
@ -11,6 +10,7 @@
|
||||||
#@menu-group gdb
|
#@menu-group gdb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help gdb#gdbserver_ssh
|
#@help gdb#gdbserver_ssh
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@enum Endian:str auto big little
|
#@enum Endian:str auto big little
|
||||||
#@arg :str! "Image" "The target binary executable image on the remote system"
|
#@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"
|
#@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
|
||||||
|
@ -25,8 +25,8 @@
|
||||||
|
|
||||||
. ..\support\gdbsetuputils.ps1
|
. ..\support\gdbsetuputils.ps1
|
||||||
|
|
||||||
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
|
$pypathTrace = Ghidra-Module-PyPath "Debugger-rmi-trace"
|
||||||
$pypathGdb = Ghidra-Module-PyPath "Debug/Debugger-agent-gdb"
|
$pypathGdb = Ghidra-Module-PyPath
|
||||||
$Env:PYTHONPATH = "$pypathGdb;$pypathTrace;$Env:PYTHONPATH"
|
$Env:PYTHONPATH = "$pypathGdb;$pypathTrace;$Env:PYTHONPATH"
|
||||||
|
|
||||||
$arglist = Compute-Gdb-Remote-Args `
|
$arglist = Compute-Gdb-Remote-Args `
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
##
|
##
|
||||||
#@timeout 60000
|
|
||||||
#@title gdb + gdbserver via ssh
|
#@title gdb + gdbserver via ssh
|
||||||
#@image-opt arg:1
|
#@image-opt arg:1
|
||||||
#@desc <html><body width="300px">
|
#@desc <html><body width="300px">
|
||||||
|
@ -27,6 +26,7 @@
|
||||||
#@menu-group gdb
|
#@menu-group gdb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help gdb#gdbserver_ssh
|
#@help gdb#gdbserver_ssh
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@enum Endian:str auto big little
|
#@enum Endian:str auto big little
|
||||||
#@arg :str! "Image" "The target binary executable image on the remote system"
|
#@arg :str! "Image" "The target binary executable image on the remote system"
|
||||||
#@args "Arguments" "Command-line arguments to pass to the target"
|
#@args "Arguments" "Command-line arguments to pass to the target"
|
||||||
|
@ -41,8 +41,8 @@
|
||||||
|
|
||||||
. ../support/gdbsetuputils.sh
|
. ../support/gdbsetuputils.sh
|
||||||
|
|
||||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||||
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
|
pypathGdb=$(ghidra-module-pypath)
|
||||||
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
||||||
|
|
||||||
target_image="$1"
|
target_image="$1"
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#@menu-group gdb
|
#@menu-group gdb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help gdb#wine
|
#@help gdb#wine
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@enum Endian:str auto big little
|
#@enum Endian:str auto big little
|
||||||
#@arg :file! "Image" "The target binary executable image"
|
#@arg :file! "Image" "The target binary executable image"
|
||||||
#@args "Arguments" "Command-line arguments to pass to the target"
|
#@args "Arguments" "Command-line arguments to pass to the target"
|
||||||
|
@ -39,8 +40,8 @@
|
||||||
|
|
||||||
. ../support/gdbsetuputils.sh
|
. ../support/gdbsetuputils.sh
|
||||||
|
|
||||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||||
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
|
pypathGdb=$(ghidra-module-pypath)
|
||||||
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
|
||||||
|
|
||||||
target_image="$1"
|
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 {
|
function Add-Gdb-Init-Args {
|
||||||
param([ref]$ArgList)
|
param([ref]$ArgList)
|
||||||
|
@ -48,7 +48,7 @@ function Add-Gdb-Tail-Args {
|
||||||
param([ref]$ArgList)
|
param([ref]$ArgList)
|
||||||
|
|
||||||
$ArgList.Value+=("-ex", "`"set confirm on`"")
|
$ArgList.Value+=("-ex", "`"set confirm on`"")
|
||||||
$ArgList.Value+=("-ex", "`"set pagination on`"")
|
# $ArgList.Value+=("-ex", "`"set pagination on`"")
|
||||||
}
|
}
|
||||||
|
|
||||||
function Compute-Gdb-Usermode-Args {
|
function Compute-Gdb-Usermode-Args {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
##
|
##
|
||||||
. ../../../Debugger-rmi-trace/data/support/setuputils.sh
|
. $MODULE_Debugger_rmi_trace_HOME/data/support/setuputils.sh
|
||||||
|
|
||||||
add-gdb-init-args() {
|
add-gdb-init-args() {
|
||||||
args+=(-q)
|
args+=(-q)
|
||||||
|
@ -64,7 +64,7 @@ add-gdb-start-if-image() {
|
||||||
|
|
||||||
add-gdb-tail-args() {
|
add-gdb-tail-args() {
|
||||||
args+=(-ex "set confirm on")
|
args+=(-ex "set confirm on")
|
||||||
args+=(-ex "set pagination on")
|
# args+=(-ex "set pagination on")
|
||||||
}
|
}
|
||||||
|
|
||||||
compute-gdb-usermode-args() {
|
compute-gdb-usermode-args() {
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#@menu-group lldb
|
#@menu-group lldb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help lldb#android
|
#@help lldb#android
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
|
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
|
||||||
#@arg :file "Image" "The target binary executable image"
|
#@arg :file "Image" "The target binary executable image"
|
||||||
#@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
|
#@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
|
||||||
|
@ -21,8 +22,8 @@
|
||||||
|
|
||||||
. ..\support\lldbsetuputils.ps1
|
. ..\support\lldbsetuputils.ps1
|
||||||
|
|
||||||
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
|
$pypathTrace = Ghidra-Module-PyPath "Debugger-rmi-trace"
|
||||||
$pypathLldb = Ghidra-Module-PyPath "Debug/Debugger-agent-lldb"
|
$pypathLldb = Ghidra-Module-PyPath
|
||||||
$Env:PYTHONPATH = "$pypathLldb;$pypathTrace;$Env:PYTHONPATH"
|
$Env:PYTHONPATH = "$pypathLldb;$pypathTrace;$Env:PYTHONPATH"
|
||||||
|
|
||||||
$arglist = Compute-Lldb-Platform-Args `
|
$arglist = Compute-Lldb-Platform-Args `
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#@menu-group lldb
|
#@menu-group lldb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help lldb#android
|
#@help lldb#android
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
|
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
|
||||||
#@arg :file "Image" "The target binary executable image"
|
#@arg :file "Image" "The target binary executable image"
|
||||||
#@args "Arguments" "Command-line arguments to pass to the target"
|
#@args "Arguments" "Command-line arguments to pass to the target"
|
||||||
|
@ -37,8 +38,8 @@
|
||||||
|
|
||||||
. ../support/lldbsetuputils.sh
|
. ../support/lldbsetuputils.sh
|
||||||
|
|
||||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||||
pypathLldb=$(ghidra-module-pypath "Debug/Debugger-agent-lldb")
|
pypathLldb=$(ghidra-module-pypath)
|
||||||
export PYTHONPATH=$pypathLldb:$pypathTrace:$PYTHONPATH
|
export PYTHONPATH=$pypathLldb:$pypathTrace:$PYTHONPATH
|
||||||
|
|
||||||
target_image="$1"
|
target_image="$1"
|
||||||
|
|
|
@ -9,14 +9,15 @@
|
||||||
#@menu-group lldb
|
#@menu-group lldb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help lldb#macos_kernel
|
#@help lldb#macos_kernel
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@env OPT_HOST:str="localhost" "Host" "The hostname of the target"
|
#@env OPT_HOST:str="localhost" "Host" "The hostname of the target"
|
||||||
#@env OPT_ARCH:str="" "Architecture" "Target architecture override"
|
#@env OPT_ARCH:str="" "Architecture" "Target architecture override"
|
||||||
#@env OPT_LLDB_PATH:file="lldb" "lldb command" "The path to lldb on the local system. Omit the full path to resolve using the system PATH."
|
#@env OPT_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
|
. ..\support\lldbsetuputils.ps1
|
||||||
|
|
||||||
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
|
$pypathTrace = Ghidra-Module-PyPath "Debugger-rmi-trace"
|
||||||
$pypathLldb = Ghidra-Module-PyPath "Debug/Debugger-agent-lldb"
|
$pypathLldb = Ghidra-Module-PyPath
|
||||||
$Env:PYTHONPATH = "$pypathLldb;$pypathTrace;$Env:PYTHONPATH"
|
$Env:PYTHONPATH = "$pypathLldb;$pypathTrace;$Env:PYTHONPATH"
|
||||||
|
|
||||||
$arglist = Compute-Lldb-Remote-Args `
|
$arglist = Compute-Lldb-Remote-Args `
|
||||||
|
|
|
@ -25,14 +25,15 @@
|
||||||
#@menu-group lldb
|
#@menu-group lldb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help lldb#macos_kernel
|
#@help lldb#macos_kernel
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@env OPT_HOST:str="localhost" "Host" "The hostname of the target"
|
#@env OPT_HOST:str="localhost" "Host" "The hostname of the target"
|
||||||
#@env OPT_ARCH:str="" "Architecture" "Target architecture override"
|
#@env OPT_ARCH:str="" "Architecture" "Target architecture override"
|
||||||
#@env OPT_LLDB_PATH:file="lldb" "lldb command" "The path to lldb on the local system. Omit the full path to resolve using the system PATH."
|
#@env OPT_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
|
. ../support/lldbsetuputils.sh
|
||||||
|
|
||||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||||
pypathLldb=$(ghidra-module-pypath "Debug/Debugger-agent-lldb")
|
pypathLldb=$(ghidra-module-pypath)
|
||||||
export PYTHONPATH=$pypathLldb:$pypathTrace:$PYTHONPATH
|
export PYTHONPATH=$pypathLldb:$pypathTrace:$PYTHONPATH
|
||||||
|
|
||||||
function launch-lldb() {
|
function launch-lldb() {
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#@menu-group lldb
|
#@menu-group lldb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help lldb#local
|
#@help lldb#local
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
|
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
|
||||||
#@arg :file "Image" "The target binary executable image"
|
#@arg :file "Image" "The target binary executable image"
|
||||||
#@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
|
#@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
|
||||||
|
@ -18,8 +19,8 @@
|
||||||
|
|
||||||
. ..\support\lldbsetuputils.ps1
|
. ..\support\lldbsetuputils.ps1
|
||||||
|
|
||||||
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
|
$pypathTrace = Ghidra-Module-PyPath "Debugger-rmi-trace"
|
||||||
$pypathLldb = Ghidra-Module-PyPath "Debug/Debugger-agent-lldb"
|
$pypathLldb = Ghidra-Module-PyPath
|
||||||
$Env:PYTHONPATH = "$pypathLldb;$pypathTrace;$Env:PYTHONPATH"
|
$Env:PYTHONPATH = "$pypathLldb;$pypathTrace;$Env:PYTHONPATH"
|
||||||
|
|
||||||
$arglist = Compute-Lldb-Usermode-Args `
|
$arglist = Compute-Lldb-Usermode-Args `
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#@menu-group lldb
|
#@menu-group lldb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help lldb#local
|
#@help lldb#local
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
|
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
|
||||||
#@arg :file "Image" "The target binary executable image"
|
#@arg :file "Image" "The target binary executable image"
|
||||||
#@args "Arguments" "Command-line arguments to pass to the target"
|
#@args "Arguments" "Command-line arguments to pass to the target"
|
||||||
|
@ -36,8 +37,8 @@
|
||||||
|
|
||||||
. ../support/lldbsetuputils.sh
|
. ../support/lldbsetuputils.sh
|
||||||
|
|
||||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||||
pypathLldb=$(ghidra-module-pypath "Debug/Debugger-agent-lldb")
|
pypathLldb=$(ghidra-module-pypath)
|
||||||
export PYTHONPATH=$pypathLldb:$pypathTrace:$PYTHONPATH
|
export PYTHONPATH=$pypathLldb:$pypathTrace:$PYTHONPATH
|
||||||
|
|
||||||
target_image="$1"
|
target_image="$1"
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#@menu-group lldb
|
#@menu-group lldb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help lldb#remote
|
#@help lldb#remote
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@arg :file "Image" "The target binary executable image (a copy on the local system)"
|
#@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_HOST:str="localhost" "Host" "The hostname of the target"
|
||||||
#@env OPT_PORT:str="9999" "Port" "The host's listening port"
|
#@env OPT_PORT:str="9999" "Port" "The host's listening port"
|
||||||
|
@ -18,8 +19,8 @@
|
||||||
|
|
||||||
. ..\support\lldbsetuputils.ps1
|
. ..\support\lldbsetuputils.ps1
|
||||||
|
|
||||||
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
|
$pypathTrace = Ghidra-Module-PyPath "Debugger-rmi-trace"
|
||||||
$pypathLldb = Ghidra-Module-PyPath "Debug/Debugger-agent-lldb"
|
$pypathLldb = Ghidra-Module-PyPath
|
||||||
$Env:PYTHONPATH = "$pypathLldb;$pypathTrace;$Env:PYTHONPATH"
|
$Env:PYTHONPATH = "$pypathLldb;$pypathTrace;$Env:PYTHONPATH"
|
||||||
|
|
||||||
$arglist = Compute-Lldb-Remote-Args `
|
$arglist = Compute-Lldb-Remote-Args `
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#@menu-group lldb
|
#@menu-group lldb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help lldb#remote
|
#@help lldb#remote
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@arg :file "Image" "The target binary executable image (a copy on the local system)"
|
#@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_HOST:str="localhost" "Host" "The hostname of the target"
|
||||||
#@env OPT_PORT:str="9999" "Port" "The host's listening port"
|
#@env OPT_PORT:str="9999" "Port" "The host's listening port"
|
||||||
|
@ -34,8 +35,8 @@
|
||||||
|
|
||||||
. ../support/lldbsetuputils.sh
|
. ../support/lldbsetuputils.sh
|
||||||
|
|
||||||
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
|
pypathTrace=$(ghidra-module-pypath "Debugger-rmi-trace")
|
||||||
pypathLldb=$(ghidra-module-pypath "Debug/Debugger-agent-lldb")
|
pypathLldb=$(ghidra-module-pypath)
|
||||||
export PYTHONPATH=$pypathLldb:$pypathTrace:$PYTHONPATH
|
export PYTHONPATH=$pypathLldb:$pypathTrace:$PYTHONPATH
|
||||||
|
|
||||||
target_image="$1"
|
target_image="$1"
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#@timeout 60000
|
|
||||||
#@title lldb via ssh
|
#@title lldb via ssh
|
||||||
#@image-opt arg:1
|
#@image-opt arg:1
|
||||||
#@desc <html><body width="300px">
|
#@desc <html><body width="300px">
|
||||||
|
@ -11,6 +10,7 @@
|
||||||
#@menu-group lldb
|
#@menu-group lldb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help lldb#ssh
|
#@help lldb#ssh
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
|
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
|
||||||
#@enum Endian:str auto big little
|
#@enum Endian:str auto big little
|
||||||
#@arg :str "Image" "The target binary executable image on the remote system"
|
#@arg :str "Image" "The target binary executable image on the remote system"
|
||||||
|
@ -60,7 +60,7 @@ finished, try launching again.
|
||||||
|
|
||||||
if ($answer) {
|
if ($answer) {
|
||||||
Write-Host "Copying Wheels to $Env:OPT_HOST"
|
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"
|
Write-Host "Installing Wheels into LLDB's embedded Python"
|
||||||
$arglist = Compute-Lldb-PipInstall-Args "'-f'" "os.environ['HOME']" "'ghidralldb>=$version'"
|
$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
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
##
|
##
|
||||||
#@timeout 60000
|
|
||||||
#@title lldb via ssh
|
#@title lldb via ssh
|
||||||
#@image-opt arg:1
|
#@image-opt arg:1
|
||||||
#@desc <html><body width="300px">
|
#@desc <html><body width="300px">
|
||||||
|
@ -27,6 +26,7 @@
|
||||||
#@menu-group lldb
|
#@menu-group lldb
|
||||||
#@icon icon.debugger
|
#@icon icon.debugger
|
||||||
#@help lldb#ssh
|
#@help lldb#ssh
|
||||||
|
#@depends Debugger-rmi-trace
|
||||||
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
|
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
|
||||||
#@enum Endian:str auto big little
|
#@enum Endian:str auto big little
|
||||||
#@arg :str "Image" "The target binary executable image on the remote system"
|
#@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
|
" "Would you like to install 'ghidralldb>=$version'?"; then
|
||||||
|
|
||||||
echo "Copying Wheels to $OPT_HOST"
|
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"
|
echo "Installing Wheels into LLDB's embedded Python"
|
||||||
do-installation
|
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 {
|
function Add-Lldb-Init-Args {
|
||||||
param([ref]$ArgList)
|
param([ref]$ArgList)
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
##
|
##
|
||||||
. ../../../Debugger-rmi-trace/data/support/setuputils.sh
|
. $MODULE_Debugger_rmi_trace_HOME/data/support/setuputils.sh
|
||||||
|
|
||||||
add-lldb-init-args() {
|
add-lldb-init-args() {
|
||||||
args+=(-o "version")
|
args+=(-o "version")
|
||||||
|
|
|
@ -86,8 +86,9 @@ public class JavaTraceRmiLaunchOffer extends AbstractScriptTraceRmiLaunchOffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void launchBackEnd(TaskMonitor monitor, Map<String, TerminalSession> sessions,
|
protected TraceRmiBackEnd launchBackEnd(TaskMonitor monitor,
|
||||||
Map<String, ValStr<?>> args, SocketAddress address) throws Exception {
|
Map<String, TerminalSession> sessions, Map<String, ValStr<?>> args,
|
||||||
|
SocketAddress address) throws Exception {
|
||||||
List<String> commandLine = new ArrayList<>();
|
List<String> commandLine = new ArrayList<>();
|
||||||
Map<String, String> env = new HashMap<>(System.getenv());
|
Map<String, String> env = new HashMap<>(System.getenv());
|
||||||
prepareSubprocess(commandLine, env, args, address);
|
prepareSubprocess(commandLine, env, args, address);
|
||||||
|
@ -101,18 +102,28 @@ public class JavaTraceRmiLaunchOffer extends AbstractScriptTraceRmiLaunchOffer {
|
||||||
sessions.put(ns.name(), ns);
|
sessions.put(ns.name(), ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TraceRmiBackEnd result = new TraceRmiBackEnd();
|
||||||
if (hasKeyReally(env, "OPT_JSHELL_PATH")) {
|
if (hasKeyReally(env, "OPT_JSHELL_PATH")) {
|
||||||
String classPath = computeClassPath(env);
|
String classPath = computeClassPath(env);
|
||||||
commandLine.add(0, "--startup");
|
commandLine.add(0, "--startup");
|
||||||
commandLine.add(0, "--class-path=" + classPath);
|
commandLine.add(0, "--class-path=" + classPath);
|
||||||
commandLine.add(0, env.get("OPT_JSHELL_PATH"));
|
commandLine.add(0, env.get("OPT_JSHELL_PATH"));
|
||||||
sessions.put("Shell",
|
PtyTerminalSession session =
|
||||||
runInTerminal(commandLine, env, script.getParentFile(), sessions.values()));
|
runInTerminal(commandLine, env, script.getParentFile(), sessions.values());
|
||||||
|
sessions.put("Shell", session);
|
||||||
|
session.terminal().addTerminalListener(result);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
JdiClientThread thread = new JdiClientThread(env);
|
JdiClientThread thread = new JdiClientThread(env) {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
super.run();
|
||||||
|
result.terminated(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String computeClassPath(Map<String, String> env) {
|
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_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"
|
#@env OPT_COMP:str="pointer64" "Ghidra Compiler" "The Ghidra CompilerSpecID for the trace"
|
||||||
|
|
||||||
if [ -d ${GHIDRA_HOME}/ghidra/.git ]
|
. ../support/setuputils.sh
|
||||||
then
|
|
||||||
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
|
pypathTrace=$(ghidra-module-pypath)
|
||||||
elif [ -d ${GHIDRA_HOME}/.git ]
|
export PYTHONPATH=$pypathTrace:$PYTHONPATH
|
||||||
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
|
|
||||||
|
|
||||||
"$OPT_PYTHON_EXE" -i ../support/raw-python3.py
|
"$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.
|
that, consider ghidratrace.setuputils.
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
|
from typing import Optional
|
||||||
home = os.getenv('GHIDRA_HOME')
|
|
||||||
|
|
||||||
|
|
||||||
def ghidra_module_pypath(name: str) -> str:
|
def ghidra_module_pypath(name: Optional[str]=None) -> str:
|
||||||
installed = f'{home}/Ghidra/{name}/pypkg/src'
|
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):
|
if os.path.isdir(installed):
|
||||||
return installed
|
return installed
|
||||||
dev1 = f'{home}/Ghidra/{name}/build/pypkg/src'
|
dev = f'{mod_home}/build/pypkg/src'
|
||||||
if os.path.isdir(dev1):
|
if os.path.isdir(dev):
|
||||||
return dev1
|
return dev
|
||||||
dev2 = f'{home}/ghidra/Ghidra/{name}/build/pypkg/src'
|
|
||||||
if os.path.isdir(dev2):
|
|
||||||
return dev2
|
|
||||||
raise Exception(
|
raise Exception(
|
||||||
f"Cannot find Python source for {name}. Try gradle assemblePyPackage?")
|
f"Cannot find Python source for {name}. Try gradle assemblePyPackage?")
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
## ###
|
## ###
|
||||||
# IP: GHIDRA
|
# IP: GHIDRA
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
# You may obtain a copy of the License at
|
# You may obtain a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
##
|
##
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
import os
|
import os
|
||||||
|
@ -33,4 +33,4 @@ client = Client(
|
||||||
print(f"Connected to {client.description} at {host}:{port}")
|
print(f"Connected to {client.description} at {host}:{port}")
|
||||||
|
|
||||||
trace = client.create_trace("noname", os.getenv(
|
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 {
|
function Find-App-Properties {
|
||||||
[IO.FileInfo] $simple = "$Env:GHIDRA_HOME\Ghidra\applications.properties"
|
[IO.FileInfo] $props = "$Env:GHIDRA_HOME\application.properties"
|
||||||
if ($simple.Exists) {
|
if ($props.Exists) {
|
||||||
return $simple
|
return $props
|
||||||
}
|
|
||||||
[IO.FileInfo] $dev2 = "$Env:GHIDRA_HOME\ghidra\Ghidra\application.properties"
|
|
||||||
if ($dev2.Exists) {
|
|
||||||
return $dev2
|
|
||||||
}
|
}
|
||||||
throw "Cannot find application.properties"
|
throw "Cannot find application.properties"
|
||||||
}
|
}
|
||||||
|
@ -17,33 +13,39 @@ function Get-Ghidra-Version {
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ghidra-Module-PyPath {
|
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) {
|
if ($installed.Exists) {
|
||||||
return "$installed"
|
return "$installed"
|
||||||
}
|
}
|
||||||
[IO.DirectoryInfo] $dev1 = "$Env:GHIDRA_HOME\Ghidra\$($args[0])\build\pypkg\src"
|
[IO.DirectoryInfo] $dev = "$modhome\build\pypkg\src"
|
||||||
if ($dev1.Exists) {
|
if ($dev.Exists) {
|
||||||
return "$dev1"
|
return "$dev"
|
||||||
}
|
|
||||||
[IO.DirectoryInfo] $dev2 = "$Env:GHIDRA_HOME\ghidra\Ghidra\$($args[0])\build\pypkg\src"
|
|
||||||
if ($dev2.Exists) {
|
|
||||||
return "$dev2"
|
|
||||||
}
|
}
|
||||||
throw "Cannot find Python source for $($args[0]). Try gradle assemblePyPackage?"
|
throw "Cannot find Python source for $($args[0]). Try gradle assemblePyPackage?"
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ghidra-Module-PyDist {
|
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) {
|
if ($installed.Exists) {
|
||||||
return "$installed"
|
return "$installed"
|
||||||
}
|
}
|
||||||
[IO.DirectoryInfo] $dev1 = "$Env:GHIDRA_HOME\Ghidra\$($args[0])\build\pypkg\dist"
|
[IO.DirectoryInfo] $dev = "$modhome\build\pypkg\dist"
|
||||||
if ($dev1.Exists) {
|
if ($dev.Exists) {
|
||||||
return "$dev1"
|
return "$dev"
|
||||||
}
|
|
||||||
[IO.DirectoryInfo] $dev2 = "$Env:GHIDRA_HOME\ghidra\Ghidra\$($args[0])\build\pypkg\dist"
|
|
||||||
if ($dev2.Exists) {
|
|
||||||
return "$dev2"
|
|
||||||
}
|
}
|
||||||
throw "Cannot find Python package for $($args[0]). Try gradle buildPyPackage?"
|
throw "Cannot find Python package for $($args[0]). Try gradle buildPyPackage?"
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,14 +14,9 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
##
|
##
|
||||||
find-app-properties() {
|
find-app-properties() {
|
||||||
local simple="$GHIDRA_HOME/Ghidra/application.properties"
|
local props="$GHIDRA_HOME/application.properties"
|
||||||
if [ -f "$simple" ]; then
|
if [ -f "$props" ]; then
|
||||||
echo $simple
|
echo $props
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
local dev2="$GHIDRA_HOME/ghidra/Ghidra/application.properties"
|
|
||||||
if [ -f "$dev2" ]; then
|
|
||||||
echo $dev2
|
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
echo >&2 "Cannot find application.properties"
|
echo >&2 "Cannot find application.properties"
|
||||||
|
@ -45,19 +40,21 @@ get-ghidra-version() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ghidra-module-pypath() {
|
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
|
if [ -d "$installed" ]; then
|
||||||
echo $installed
|
echo $installed
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
dev1="$GHIDRA_HOME/Ghidra/$1/build/pypkg/src"
|
local dev="$modhome/build/pypkg/src"
|
||||||
if [ -d "$dev1" ]; then
|
if [ -d "$dev" ]; then
|
||||||
echo $dev1
|
echo $dev
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
dev2="$GHIDRA_HOME/ghidra/Ghidra/$1/build/pypkg/src"
|
|
||||||
if [ -d "$dev2" ]; then
|
|
||||||
echo $dev2
|
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
echo >&2 "Cannot find Python source for $1. Try gradle assemblePyPackage?"
|
echo >&2 "Cannot find Python source for $1. Try gradle assemblePyPackage?"
|
||||||
|
@ -65,19 +62,21 @@ ghidra-module-pypath() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ghidra-module-pydist() {
|
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
|
if [ -d "$installed" ]; then
|
||||||
echo $installed
|
echo $installed
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
dev1="$GHIDRA_HOME/Ghidra/$1/build/pypkg/dist"
|
local dev="$modhome/build/pypkg/dist"
|
||||||
if [ -d "$dev1" ]; then
|
if [ -d "$dev" ]; then
|
||||||
echo $dev1
|
echo $dev
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
dev2="$GHIDRA_HOME/ghidra/Ghidra/$1/build/pypkg/dist"
|
|
||||||
if [ -d "$dev2" ]; then
|
|
||||||
echo $dev2
|
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
echo >&2 "Cannot find Python package for $1. Try gradle buildPyPackage?"
|
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,
|
protected void prepareSubprocess(List<String> commandLine, Map<String, String> env,
|
||||||
Map<String, ValStr<?>> args, SocketAddress address) {
|
Map<String, ValStr<?>> args, SocketAddress address) {
|
||||||
ScriptAttributesParser.processArguments(commandLine, env, script, attrs.parameters(), args,
|
ScriptAttributesParser.processArguments(commandLine, env, script, attrs.parameters(), args,
|
||||||
address);
|
attrs.dependencies(), address);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void launchBackEnd(TaskMonitor monitor, Map<String, TerminalSession> sessions,
|
protected TraceRmiBackEnd launchBackEnd(TaskMonitor monitor,
|
||||||
Map<String, ValStr<?>> args, SocketAddress address) throws Exception {
|
Map<String, TerminalSession> sessions, Map<String, ValStr<?>> args,
|
||||||
|
SocketAddress address) throws Exception {
|
||||||
List<String> commandLine = new ArrayList<>();
|
List<String> commandLine = new ArrayList<>();
|
||||||
Map<String, String> env = new HashMap<>(System.getenv());
|
Map<String, String> env = new HashMap<>(System.getenv());
|
||||||
prepareSubprocess(commandLine, env, args, address);
|
prepareSubprocess(commandLine, env, args, address);
|
||||||
|
@ -112,7 +113,8 @@ public abstract class AbstractScriptTraceRmiLaunchOffer extends AbstractTraceRmi
|
||||||
if (imageParameter != null) {
|
if (imageParameter != null) {
|
||||||
ValStr<?> valStr = args.get(imageParameter.name());
|
ValStr<?> valStr = args.get(imageParameter.name());
|
||||||
if (valStr != null && !valStr.str().contains(program.getName())) {
|
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());
|
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(ent.getKey(), ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
sessions.put("Shell",
|
PtyTerminalSession session =
|
||||||
runInTerminal(commandLine, env, script.getParentFile(), sessions.values()));
|
runInTerminal(commandLine, env, script.getParentFile(), sessions.values());
|
||||||
|
sessions.put("Shell", session);
|
||||||
|
TraceRmiBackEnd result = new TraceRmiBackEnd();
|
||||||
|
session.terminal().addTerminalListener(result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -17,16 +17,18 @@ package ghidra.app.plugin.core.debug.gui.tracermi.launcher;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.*;
|
||||||
import java.net.SocketAddress;
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
import javax.swing.Icon;
|
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.DebuggerResources;
|
||||||
import ghidra.app.plugin.core.debug.gui.action.ByModuleAutoMapSpec;
|
import ghidra.app.plugin.core.debug.gui.action.ByModuleAutoMapSpec;
|
||||||
import ghidra.app.plugin.core.debug.gui.tracermi.launcher.LaunchFailureDialog.ErrPromptResponse;
|
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 String PREFIX_PARAM_EXTTOOL = "env:GHIDRA_LANG_EXTTOOL_";
|
||||||
|
|
||||||
public static final int DEFAULT_TIMEOUT_MILLIS = 10000;
|
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,
|
protected record PtyTerminalSession(Terminal terminal, Pty pty, PtySession session,
|
||||||
Thread waiter) implements TerminalSession {
|
Thread waiter) implements TerminalSession {
|
||||||
@Override
|
@Override
|
||||||
public void terminate() throws IOException {
|
public void terminate() throws IOException {
|
||||||
terminal.terminated();
|
terminal.terminated(-1);
|
||||||
session.destroyForcibly();
|
session.destroyForcibly();
|
||||||
pty.close();
|
pty.close();
|
||||||
waiter.interrupt();
|
waiter.interrupt();
|
||||||
|
@ -80,7 +84,7 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
|
||||||
implements TerminalSession {
|
implements TerminalSession {
|
||||||
@Override
|
@Override
|
||||||
public void terminate() throws IOException {
|
public void terminate() throws IOException {
|
||||||
terminal.terminated();
|
terminal.terminated(-1);
|
||||||
pty.close();
|
pty.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +139,7 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int getConnectionTimeoutMillis() {
|
protected int getConnectionTimeoutMillis() {
|
||||||
return getTimeoutMillis();
|
return DEFAULT_CONNECTION_TIMEOUT_MILLIS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -415,8 +419,9 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
|
||||||
param.display()));
|
param.display()));
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
Msg.warn(this, "Could not load saved launcher arg '%s' (%s) - %s".formatted(param.name(),
|
Msg.warn(this,
|
||||||
param.display(), e.getMessage()));
|
"Could not load saved launcher arg '%s' (%s) - %s".formatted(param.name(),
|
||||||
|
param.display(), e.getMessage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return args;
|
return args;
|
||||||
|
@ -490,8 +495,8 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
|
||||||
|
|
||||||
Thread waiter = new Thread(() -> {
|
Thread waiter = new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
session.waitExited();
|
int exitcode = session.waitExited();
|
||||||
terminal.terminated();
|
terminal.terminated(exitcode);
|
||||||
pty.close();
|
pty.close();
|
||||||
|
|
||||||
for (TerminalSession ss : subordinates) {
|
for (TerminalSession ss : subordinates) {
|
||||||
|
@ -538,10 +543,43 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
|
||||||
return terminalSession;
|
return terminalSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void launchBackEnd(TaskMonitor monitor,
|
protected abstract TraceRmiBackEnd launchBackEnd(TaskMonitor monitor,
|
||||||
Map<String, TerminalSession> sessions, Map<String, ValStr<?>> args,
|
Map<String, TerminalSession> sessions, Map<String, ValStr<?>> args,
|
||||||
SocketAddress address) throws Exception;
|
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 static class NoStaticMappingException extends Exception {
|
||||||
public NoStaticMappingException(String message) {
|
public NoStaticMappingException(String message) {
|
||||||
super(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() {
|
protected AutoMapSpec getAutoMapSpec() {
|
||||||
DebuggerAutoMappingService auto = tool.getService(DebuggerAutoMappingService.class);
|
DebuggerAutoMappingService auto = tool.getService(DebuggerAutoMappingService.class);
|
||||||
return auto == null ? ByModuleAutoMapSpec.instance() : auto.getAutoMapSpec();
|
return auto == null ? ByModuleAutoMapSpec.instance() : auto.getAutoMapSpec();
|
||||||
|
@ -660,12 +709,16 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
|
||||||
monitor.increment();
|
monitor.increment();
|
||||||
|
|
||||||
monitor.setMessage("Launching back-end");
|
monitor.setMessage("Launching back-end");
|
||||||
launchBackEnd(monitor, sessions, args, acceptor.getAddress());
|
TraceRmiBackEnd backEnd =
|
||||||
|
launchBackEnd(monitor, sessions, args, acceptor.getAddress());
|
||||||
monitor.increment();
|
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");
|
monitor.setMessage("Waiting for connection");
|
||||||
acceptor.setTimeout(getConnectionTimeoutMillis());
|
connection = acceptOrSessionEnds(acceptor, backEnd);
|
||||||
connection = acceptor.accept();
|
|
||||||
connection.registerTerminals(sessions.values());
|
connection.registerTerminals(sessions.values());
|
||||||
monitor.increment();
|
monitor.increment();
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.util.Map.Entry;
|
||||||
|
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
|
|
||||||
|
import generic.jar.ResourceFile;
|
||||||
import generic.theme.GIcon;
|
import generic.theme.GIcon;
|
||||||
import generic.theme.Gui;
|
import generic.theme.Gui;
|
||||||
import ghidra.debug.api.ValStr;
|
import ghidra.debug.api.ValStr;
|
||||||
|
@ -40,12 +41,15 @@ import ghidra.util.*;
|
||||||
*/
|
*/
|
||||||
public abstract class ScriptAttributesParser {
|
public abstract class ScriptAttributesParser {
|
||||||
public static final String ENV_GHIDRA_HOME = "GHIDRA_HOME";
|
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_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_HOST = "GHIDRA_TRACE_RMI_HOST";
|
||||||
public static final String ENV_GHIDRA_TRACE_RMI_PORT = "GHIDRA_TRACE_RMI_PORT";
|
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_ARG = "@arg";
|
||||||
public static final String AT_ARGS = "@args";
|
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_DESC = "@desc";
|
||||||
public static final String AT_ENUM = "@enum";
|
public static final String AT_ENUM = "@enum";
|
||||||
public static final String AT_ENV = "@env";
|
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,
|
public record ScriptAttributes(String title, String description, List<String> menuPath,
|
||||||
String menuGroup, String menuOrder, Icon icon, HelpLocation helpLocation,
|
String menuGroup, String menuOrder, Icon icon, HelpLocation helpLocation,
|
||||||
Map<String, LaunchParameter<?>> parameters, Map<String, TtyCondition> extraTtys,
|
Map<String, LaunchParameter<?>> parameters, Set<String> dependencies,
|
||||||
int timeoutMillis, LaunchParameter<?> imageOpt) {
|
Map<String, TtyCondition> extraTtys, int timeoutMillis, LaunchParameter<?> imageOpt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -355,14 +359,35 @@ public abstract class ScriptAttributesParser {
|
||||||
* @param script the script file
|
* @param script the script file
|
||||||
* @param parameters the descriptions of the parameters
|
* @param parameters the descriptions of the parameters
|
||||||
* @param args the arguments to process
|
* @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
|
* @param address the address of the listening TraceRmi socket
|
||||||
*/
|
*/
|
||||||
public static void processArguments(List<String> commandLine, Map<String, String> env,
|
public static void processArguments(List<String> commandLine, Map<String, String> env,
|
||||||
File script, Map<String, LaunchParameter<?>> parameters, Map<String, ValStr<?>> args,
|
File script, Map<String, LaunchParameter<?>> parameters, Map<String, ValStr<?>> args,
|
||||||
SocketAddress address) {
|
Set<String> dependencies, SocketAddress address) {
|
||||||
|
|
||||||
commandLine.add(script.getAbsolutePath());
|
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) {
|
if (address != null) {
|
||||||
env.put(ENV_GHIDRA_TRACE_RMI_ADDR, sockToString(address));
|
env.put(ENV_GHIDRA_TRACE_RMI_ADDR, sockToString(address));
|
||||||
if (address instanceof InetSocketAddress tcp) {
|
if (address instanceof InetSocketAddress tcp) {
|
||||||
|
@ -402,8 +427,9 @@ public abstract class ScriptAttributesParser {
|
||||||
private List<String> menuPath;
|
private List<String> menuPath;
|
||||||
private final Map<String, UserType<?>> userTypes = new HashMap<>();
|
private final Map<String, UserType<?>> userTypes = new HashMap<>();
|
||||||
private final Map<String, LaunchParameter<?>> parameters = new LinkedHashMap<>();
|
private final Map<String, LaunchParameter<?>> parameters = new LinkedHashMap<>();
|
||||||
|
private final Set<String> dependencies = new LinkedHashSet<>();
|
||||||
private final Map<String, TtyCondition> extraTtys = new LinkedHashMap<>();
|
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;
|
private String imageOptKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -493,6 +519,7 @@ public abstract class ScriptAttributesParser {
|
||||||
switch (parts[0].trim()) {
|
switch (parts[0].trim()) {
|
||||||
case AT_ARG -> parseArg(loc, parts[1], ++argc);
|
case AT_ARG -> parseArg(loc, parts[1], ++argc);
|
||||||
case AT_ARGS -> parseArgs(loc, parts[1]);
|
case AT_ARGS -> parseArgs(loc, parts[1]);
|
||||||
|
case AT_DEPENDS -> parseDepends(loc, parts[1]);
|
||||||
case AT_DESC -> parseDesc(loc, parts[1]);
|
case AT_DESC -> parseDesc(loc, parts[1]);
|
||||||
case AT_ENUM -> parseEnum(loc, parts[1]);
|
case AT_ENUM -> parseEnum(loc, parts[1]);
|
||||||
case AT_ENV -> parseEnv(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) {
|
protected void parseDesc(Location loc, String str) {
|
||||||
if (description == null) {
|
if (description == null) {
|
||||||
description = new StringBuilder();
|
description = new StringBuilder();
|
||||||
|
@ -796,9 +830,11 @@ public abstract class ScriptAttributesParser {
|
||||||
AT_IMAGE_OPT, imageOptKey));
|
AT_IMAGE_OPT, imageOptKey));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// NOTE: Don't use copyOf, or else we lose ordering
|
||||||
return new ScriptAttributes(title, getDescription(), List.copyOf(menuPath), menuGroup,
|
return new ScriptAttributes(title, getDescription(), List.copyOf(menuPath), menuGroup,
|
||||||
menuOrder, new GIcon(iconId), helpLocation,
|
menuOrder, new GIcon(iconId), helpLocation,
|
||||||
Collections.unmodifiableMap(new LinkedHashMap<>(parameters)),
|
Collections.unmodifiableMap(new LinkedHashMap<>(parameters)),
|
||||||
|
Collections.unmodifiableSet(new LinkedHashSet<>(dependencies)),
|
||||||
Collections.unmodifiableMap(new LinkedHashMap<>(extraTtys)), timeoutMillis, imageOpt);
|
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",
|
"Operating System :: OS Independent",
|
||||||
]
|
]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"protobuf >= 6.31.0",
|
"protobuf>=6.31.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
|
|
|
@ -18,7 +18,7 @@ try:
|
||||||
from . import trace_rmi_pb2 as bufs
|
from . import trace_rmi_pb2 as bufs
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
from .setuputils import prompt_and_mitigate_dependencies
|
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 collections import deque
|
||||||
from concurrent.futures import Executor, Future
|
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.
|
module, and so we place the setup logic here.
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
from typing import List, Sequence
|
from typing import List, Optional, Sequence
|
||||||
|
|
||||||
|
|
||||||
home = os.getenv('GHIDRA_HOME')
|
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)
|
||||||
def ghidra_module_src(name: str) -> str:
|
installed = f'{mod_home}/pypkg'
|
||||||
installed = f'{home}/Ghidra/{name}/pypkg'
|
|
||||||
if os.path.isdir(installed):
|
if os.path.isdir(installed):
|
||||||
return installed
|
return installed
|
||||||
dev1 = f'{home}/Ghidra/{name}/src/main/py'
|
dev = f'{mod_home}/src/main/py'
|
||||||
if os.path.isdir(dev1):
|
if os.path.isdir(dev):
|
||||||
return dev1
|
return dev
|
||||||
dev2 = f'{home}/ghidra/Ghidra/{name}/src/main/py'
|
|
||||||
if os.path.isdir(dev2):
|
|
||||||
return dev2
|
|
||||||
raise Exception(f"""
|
raise Exception(f"""
|
||||||
Cannot find Python source for {name}.
|
Cannot find Python source for {name}.
|
||||||
If this is a remote system, we shouldn't even be here. Chances are,
|
If this is a remote system, we shouldn't even be here. Chances are,
|
||||||
|
@ -63,9 +59,9 @@ def get_module_dependencies(name: str) -> List[str]:
|
||||||
elif seen_deps and l == ']':
|
elif seen_deps and l == ']':
|
||||||
return [r for r in result if not 'ghidra' in r]
|
return [r for r in result if not 'ghidra' in r]
|
||||||
elif seen_deps:
|
elif seen_deps:
|
||||||
if l.endswith(','): # Last one may not have ,
|
if l.endswith(','): # Last one may not have ,
|
||||||
l = l[:-1].strip()
|
l = l[:-1].strip()
|
||||||
result.append(l[1:-1]) # Remove 's or "s
|
result.append(l[1:-1]) # Remove 's or "s
|
||||||
raise Exception("Could not parse pyproject.toml")
|
raise Exception("Could not parse pyproject.toml")
|
||||||
|
|
||||||
|
|
||||||
|
@ -93,15 +89,29 @@ def mitigate_by_pip_install(*args: str) -> None:
|
||||||
runpy.run_module("pip", run_name="__main__")
|
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:
|
def prompt_and_mitigate_dependencies(name: str) -> None:
|
||||||
deps = get_module_dependencies(name)
|
deps = get_module_dependencies(name)
|
||||||
deps_str = ' '.join(f"'{d}'" for d in deps)
|
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
|
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
|
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
|
installed the packages to a different Python environment than is being used
|
||||||
right now.
|
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 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
|
this manually, answer no to the next question and then see Ghidra's help by
|
||||||
pressing F1 in the dialog of launch parameters.
|
pressing F1 in the dialog of launch parameters.
|
||||||
|
@ -121,4 +131,3 @@ finished, close this terminal, and try launching again.
|
||||||
|
|
||||||
if answer:
|
if answer:
|
||||||
mitigate_by_pip_install('-f', '../../pypkg/dist', *deps)
|
mitigate_by_pip_install('-f', '../../pypkg/dist', *deps)
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -41,8 +41,8 @@ public class DefaultTerminal implements Terminal {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void terminated() {
|
public void terminated(int exitcode) {
|
||||||
provider.terminated();
|
provider.terminated(exitcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -38,4 +38,12 @@ public interface TerminalListener {
|
||||||
*/
|
*/
|
||||||
default void retitled(String title) {
|
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.*;
|
||||||
import ghidra.app.plugin.core.terminal.vt.VtHandler.*;
|
import ghidra.app.plugin.core.terminal.vt.VtHandler.*;
|
||||||
import ghidra.app.services.ClipboardService;
|
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.
|
* A VT100 terminal emulator in a panel.
|
||||||
|
@ -180,7 +182,8 @@ public class TerminalPanel extends JPanel implements FieldLocationListener, Fiel
|
||||||
protected TerminalClipboardProvider clipboardProvider;
|
protected TerminalClipboardProvider clipboardProvider;
|
||||||
protected String selectedText;
|
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 VtOutput outputCb;
|
||||||
protected final TerminalAwtEventEncoder eventEncoder;
|
protected final TerminalAwtEventEncoder eventEncoder;
|
||||||
|
@ -363,25 +366,15 @@ public class TerminalPanel extends JPanel implements FieldLocationListener, Fiel
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void notifyTerminalResized(short cols, short rows) {
|
protected void notifyTerminalResized(short cols, short rows) {
|
||||||
for (TerminalListener l : terminalListeners) {
|
terminalListeners.invoke().resized(cols, rows);
|
||||||
try {
|
|
||||||
l.resized(cols, rows);
|
|
||||||
}
|
|
||||||
catch (Throwable t) {
|
|
||||||
Msg.showError(this, null, "Error", t.getMessage(), t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void notifyTerminalRetitled(String title) {
|
protected void notifyTerminalRetitled(String title) {
|
||||||
for (TerminalListener l : terminalListeners) {
|
terminalListeners.invoke().retitled(title);
|
||||||
try {
|
}
|
||||||
l.retitled(title);
|
|
||||||
}
|
protected void notifyTerminalTerminated(int exitcode) {
|
||||||
catch (Throwable t) {
|
terminalListeners.invoke().terminated(exitcode);
|
||||||
Msg.showError(this, null, "Error", t.getMessage(), t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -53,7 +53,7 @@ import ghidra.util.Swing;
|
||||||
* This also provides UI actions for searching the terminal's contents.
|
* This also provides UI actions for searching the terminal's contents.
|
||||||
*/
|
*/
|
||||||
public class TerminalProvider extends ComponentProviderAdapter {
|
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");
|
private static final Color COLOR_TERMINATED = new GColor("color.border.provider.disconnected");
|
||||||
|
|
||||||
protected class FindDialog extends DialogComponentProvider {
|
protected class FindDialog extends DialogComponentProvider {
|
||||||
|
@ -433,10 +433,13 @@ public class TerminalProvider extends ComponentProviderAdapter {
|
||||||
* <p>
|
* <p>
|
||||||
* The title and sub title are adjusted and all terminal listeners are removed. If/when the
|
* 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.
|
* 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(() -> {
|
Swing.runIfSwingOrRunLater(() -> {
|
||||||
terminated = true;
|
terminated = true;
|
||||||
|
panel.terminalListeners.invoke().terminated(exitcode);
|
||||||
removeLocalAction(actionTerminate);
|
removeLocalAction(actionTerminate);
|
||||||
panel.terminalListeners.clear();
|
panel.terminalListeners.clear();
|
||||||
panel.setOutputCallback(buf -> {
|
panel.setOutputCallback(buf -> {
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -201,8 +201,10 @@ public interface Terminal extends AutoCloseable {
|
||||||
* <p>
|
* <p>
|
||||||
* The title and sub title are adjust and all listeners are removed. If/when the terminal is
|
* 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.
|
* 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
|
* 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 {
|
public abstract class AbstractDrgnTraceRmiTest extends AbstractGhidraHeadedDebuggerTest {
|
||||||
|
|
||||||
protected static String CORE = "core.12137";
|
protected static final String CORE = "core.12137";
|
||||||
protected static String MDO = "/New Traces/" + CORE;
|
protected static final String MDO = "/New Traces/" + CORE;
|
||||||
public static String PREAMBLE = """
|
public static final String PREAMBLE = """
|
||||||
import os
|
import os
|
||||||
import drgn
|
import drgn
|
||||||
import drgn.cli
|
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;
|
package agent.gdb.rmi;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.Assert.assertTrue;
|
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.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.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import agent.AbstractRmiConnectorsTest;
|
||||||
import db.Transaction;
|
import db.Transaction;
|
||||||
import generic.Unique;
|
import generic.jar.ResourceFile;
|
||||||
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerIntegrationTest;
|
|
||||||
import ghidra.app.plugin.core.debug.gui.action.BySectionAutoMapSpec;
|
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.EarlyTerminationException;
|
||||||
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.util.importer.AutoImporter;
|
import ghidra.app.util.importer.AutoImporter;
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
import ghidra.debug.api.ValStr;
|
|
||||||
import ghidra.debug.api.action.AutoMapSpec;
|
import ghidra.debug.api.action.AutoMapSpec;
|
||||||
import ghidra.debug.api.tracermi.TerminalSession;
|
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer.LaunchResult;
|
||||||
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer;
|
import ghidra.framework.Application;
|
||||||
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer.*;
|
|
||||||
import ghidra.framework.OperatingSystem;
|
|
||||||
import ghidra.framework.plugintool.AutoConfigState.PathIsFile;
|
import ghidra.framework.plugintool.AutoConfigState.PathIsFile;
|
||||||
import ghidra.pty.testutil.DummyProc;
|
import ghidra.pty.testutil.DummyProc;
|
||||||
import ghidra.util.SystemUtilities;
|
|
||||||
|
|
||||||
public class GdbConnectorsTest extends AbstractGhidraHeadedDebuggerIntegrationTest {
|
public class GdbConnectorsTest extends AbstractRmiConnectorsTest {
|
||||||
private TraceRmiLauncherService launchService;
|
|
||||||
private DebuggerAutoMappingService autoMappingService;
|
@Override
|
||||||
|
protected List<ResourceFile> getPipLinkModules() {
|
||||||
|
return List.of(
|
||||||
|
Application.getModuleRootDir("Debugger-rmi-trace"),
|
||||||
|
Application.getModuleRootDir("Debugger-agent-gdb"));
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void checkManual() throws Exception {
|
public void setUpGdb() throws Exception {
|
||||||
assumeFalse(SystemUtilities.isInTestingBatchMode());
|
// Make sure system doesn't cause path failures to pass
|
||||||
addPlugin(tool, DebuggerStaticMappingServicePlugin.class);
|
unpip("ghidragdb", "ghidratrace");
|
||||||
addPlugin(tool, DebuggerModulesPlugin.class);
|
// Ensure a compatible version of protobuf
|
||||||
autoMappingService =
|
pip("protobuf==6.31.0");
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLocalGdbSetup() throws Exception {
|
public void testLocalGdbSetup() throws Exception {
|
||||||
new ProcessBuilder().command("pip", "install", "protobuf==3.19.0")
|
pipOob("protobuf==3.19.0");
|
||||||
.inheritIO()
|
|
||||||
.start()
|
|
||||||
.waitFor();
|
|
||||||
try (LaunchResult result = doLaunch("gdb", Map.of("arg:1", chooseImage()))) {
|
try (LaunchResult result = doLaunch("gdb", Map.of("arg:1", chooseImage()))) {
|
||||||
assertTrue(result.exception() instanceof SocketTimeoutException);
|
assertTrue(result.exception() instanceof EarlyTerminationException);
|
||||||
TerminalSession term = Unique.assertOne(result.sessions().values());
|
assertThat(result.sessions().get("Shell").content(),
|
||||||
while (!term.isTerminated()) {
|
Matchers.containsString("Would you like to install"));
|
||||||
Thread.sleep(1000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
try (LaunchResult result = doLaunch("gdb", Map.of("arg:1", chooseImage()))) {
|
try (LaunchResult result = doLaunch("gdb", Map.of("arg:1", chooseImage()))) {
|
||||||
checkResult(result);
|
checkResult(result);
|
||||||
|
@ -206,6 +126,7 @@ public class GdbConnectorsTest extends AbstractGhidraHeadedDebuggerIntegrationTe
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGdbViaSsh() throws Exception {
|
public void testGdbViaSsh() throws Exception {
|
||||||
|
pip("ghidragdb==%s".formatted(Application.getApplicationVersion()));
|
||||||
try (LaunchResult result = doLaunch("gdb via ssh", Map.ofEntries(
|
try (LaunchResult result = doLaunch("gdb via ssh", Map.ofEntries(
|
||||||
Map.entry("arg:1", "/bin/ls"),
|
Map.entry("arg:1", "/bin/ls"),
|
||||||
Map.entry("OPT_HOST", "localhost")))) {
|
Map.entry("OPT_HOST", "localhost")))) {
|
||||||
|
@ -215,15 +136,12 @@ public class GdbConnectorsTest extends AbstractGhidraHeadedDebuggerIntegrationTe
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGdbViaSshSetupGhidraGdb() throws Exception {
|
public void testGdbViaSshSetupGhidraGdb() throws Exception {
|
||||||
new ProcessBuilder().command("pip", "uninstall", "ghidragdb").inheritIO().start().waitFor();
|
|
||||||
try (LaunchResult result = doLaunch("gdb via ssh", Map.ofEntries(
|
try (LaunchResult result = doLaunch("gdb via ssh", Map.ofEntries(
|
||||||
Map.entry("arg:1", "/bin/ls"),
|
Map.entry("arg:1", "/bin/ls"),
|
||||||
Map.entry("OPT_HOST", "localhost")))) {
|
Map.entry("OPT_HOST", "localhost")))) {
|
||||||
assertTrue(result.exception() instanceof SocketTimeoutException);
|
assertTrue(result.exception() instanceof EarlyTerminationException);
|
||||||
TerminalSession term = Unique.assertOne(result.sessions().values());
|
assertThat(result.sessions().get("Shell").content(),
|
||||||
while (!term.isTerminated()) {
|
Matchers.containsString("Would you like to install"));
|
||||||
Thread.sleep(1000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
try (LaunchResult result = doLaunch("gdb via ssh", Map.ofEntries(
|
try (LaunchResult result = doLaunch("gdb via ssh", Map.ofEntries(
|
||||||
Map.entry("arg:1", "/bin/ls"),
|
Map.entry("arg:1", "/bin/ls"),
|
||||||
|
@ -234,18 +152,15 @@ public class GdbConnectorsTest extends AbstractGhidraHeadedDebuggerIntegrationTe
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGdbViaSshSetupProtobuf() throws Exception {
|
public void testGdbViaSshSetupProtobuf() throws Exception {
|
||||||
new ProcessBuilder().command("pip", "install", "protobuf==3.19.0")
|
pip("ghidragdb==%s".formatted(Application.getApplicationVersion()));
|
||||||
.inheritIO()
|
// Overwrite with an incompatible version we don't include
|
||||||
.start()
|
pipOob("protobuf==3.19.0");
|
||||||
.waitFor();
|
|
||||||
try (LaunchResult result = doLaunch("gdb via ssh", Map.ofEntries(
|
try (LaunchResult result = doLaunch("gdb via ssh", Map.ofEntries(
|
||||||
Map.entry("arg:1", "/bin/ls"),
|
Map.entry("arg:1", "/bin/ls"),
|
||||||
Map.entry("OPT_HOST", "localhost")))) {
|
Map.entry("OPT_HOST", "localhost")))) {
|
||||||
assertTrue(result.exception() instanceof SocketTimeoutException);
|
assertTrue(result.exception() instanceof EarlyTerminationException);
|
||||||
TerminalSession term = Unique.assertOne(result.sessions().values());
|
assertThat(result.sessions().get("Shell").content(),
|
||||||
while (!term.isTerminated()) {
|
Matchers.containsString("Would you like to install"));
|
||||||
Thread.sleep(1000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
try (LaunchResult result = doLaunch("gdb via ssh", Map.ofEntries(
|
try (LaunchResult result = doLaunch("gdb via ssh", Map.ofEntries(
|
||||||
Map.entry("arg:1", "/bin/ls"),
|
Map.entry("arg:1", "/bin/ls"),
|
||||||
|
|
|
@ -15,132 +15,52 @@
|
||||||
*/
|
*/
|
||||||
package agent.lldb.rmi;
|
package agent.lldb.rmi;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assume.assumeFalse;
|
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.nio.file.Path;
|
||||||
import java.util.*;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
|
|
||||||
|
import agent.AbstractRmiConnectorsTest;
|
||||||
import db.Transaction;
|
import db.Transaction;
|
||||||
import generic.Unique;
|
import generic.jar.ResourceFile;
|
||||||
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerIntegrationTest;
|
|
||||||
import ghidra.app.plugin.core.debug.gui.action.BySectionAutoMapSpec;
|
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.EarlyTerminationException;
|
||||||
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.util.importer.AutoImporter;
|
import ghidra.app.util.importer.AutoImporter;
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
import ghidra.debug.api.ValStr;
|
|
||||||
import ghidra.debug.api.action.AutoMapSpec;
|
import ghidra.debug.api.action.AutoMapSpec;
|
||||||
import ghidra.debug.api.tracermi.TerminalSession;
|
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer.LaunchResult;
|
||||||
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer;
|
import ghidra.framework.Application;
|
||||||
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer.*;
|
|
||||||
import ghidra.framework.OperatingSystem;
|
import ghidra.framework.OperatingSystem;
|
||||||
import ghidra.framework.plugintool.AutoConfigState.PathIsFile;
|
import ghidra.framework.plugintool.AutoConfigState.PathIsFile;
|
||||||
import ghidra.pty.testutil.DummyProc;
|
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
|
* 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
|
* lldb working in a command prompt. Ensure that it can import socket, and then re-launch Eclipse
|
||||||
* from there.
|
* from there.
|
||||||
*/
|
*/
|
||||||
public class LldbConnectorsTest extends AbstractGhidraHeadedDebuggerIntegrationTest {
|
public class LldbConnectorsTest extends AbstractRmiConnectorsTest {
|
||||||
private TraceRmiLauncherService launchService;
|
|
||||||
private DebuggerAutoMappingService autoMappingService;
|
@Override
|
||||||
|
protected List<ResourceFile> getPipLinkModules() {
|
||||||
|
return List.of(
|
||||||
|
Application.getModuleRootDir("Debugger-rmi-trace"),
|
||||||
|
Application.getModuleRootDir("Debugger-agent-lldb"));
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void checkManual() throws Exception {
|
public void setupLldb() throws Exception {
|
||||||
assumeFalse(SystemUtilities.isInTestingBatchMode());
|
// Make sure system doesn't cause path failures to pass
|
||||||
addPlugin(tool, DebuggerStaticMappingServicePlugin.class);
|
unpip("ghidralldb", "ghidratrace");
|
||||||
addPlugin(tool, DebuggerModulesPlugin.class);
|
// Ensure a compatible version of protobuf
|
||||||
autoMappingService =
|
pip("protobuf==6.31.0");
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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
|
* 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.
|
* the screen, and this circumstance <em>should</em> be rare.
|
||||||
*
|
*
|
||||||
* @throws Exception
|
* @throws Exception because
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testLocalLldbSetup() throws Exception {
|
public void testLocalLldbSetup() throws Exception {
|
||||||
new ProcessBuilder().command("python", "-m", "pip", "install", "protobuf==3.19.0")
|
pipOob("protobuf==3.19.0");
|
||||||
.inheritIO()
|
|
||||||
.start()
|
|
||||||
.waitFor();
|
|
||||||
try (LaunchResult result = doLaunch("lldb", Map.of("arg:1", chooseImage()))) {
|
try (LaunchResult result = doLaunch("lldb", Map.of("arg:1", chooseImage()))) {
|
||||||
assertTrue(result.exception() instanceof SocketTimeoutException);
|
assertTrue(result.exception() instanceof EarlyTerminationException);
|
||||||
TerminalSession term = Unique.assertOne(result.sessions().values());
|
assertThat(result.sessions().get("Shell").content(),
|
||||||
while (!term.isTerminated()) {
|
Matchers.containsString("Would you like to install"));
|
||||||
Thread.sleep(1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try (LaunchResult result = doLaunch("lldb", Map.of("arg:1", chooseImage()))) {
|
|
||||||
checkResult(result);
|
|
||||||
}
|
}
|
||||||
|
// NOTE: lldb will not let me prompt the user, so cannot test automatic mitigation
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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
|
* This has proven difficult to test on Windows, probably because the version of lldb and
|
||||||
* gdbserver I'm using are not compatible?
|
* gdbserver I'm using are not compatible?
|
||||||
*
|
*
|
||||||
* @throws Exception
|
* @throws Exception because
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testLldbRemoteGdb() throws Exception {
|
public void testLldbRemoteGdb() throws Exception {
|
||||||
|
@ -237,6 +150,7 @@ public class LldbConnectorsTest extends AbstractGhidraHeadedDebuggerIntegrationT
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLldbViaSsh() throws Exception {
|
public void testLldbViaSsh() throws Exception {
|
||||||
|
pip("ghidralldb==%s".formatted(Application.getApplicationVersion()));
|
||||||
try (LaunchResult result = doLaunch("lldb via ssh", Map.ofEntries(
|
try (LaunchResult result = doLaunch("lldb via ssh", Map.ofEntries(
|
||||||
Map.entry("arg:1", "/bin/ls"),
|
Map.entry("arg:1", "/bin/ls"),
|
||||||
Map.entry("OPT_HOST", "localhost")))) {
|
Map.entry("OPT_HOST", "localhost")))) {
|
||||||
|
@ -246,19 +160,12 @@ public class LldbConnectorsTest extends AbstractGhidraHeadedDebuggerIntegrationT
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLldbViaSshSetupGhidraLldb() throws Exception {
|
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(
|
try (LaunchResult result = doLaunch("lldb via ssh", Map.ofEntries(
|
||||||
Map.entry("arg:1", "/bin/ls"),
|
Map.entry("arg:1", "/bin/ls"),
|
||||||
Map.entry("OPT_HOST", "localhost")))) {
|
Map.entry("OPT_HOST", "localhost")))) {
|
||||||
assertTrue(result.exception() instanceof SocketTimeoutException);
|
assertTrue(result.exception() instanceof EarlyTerminationException);
|
||||||
TerminalSession term = Unique.assertOne(result.sessions().values());
|
assertThat(result.sessions().get("Shell").content(),
|
||||||
while (!term.isTerminated()) {
|
Matchers.containsString("Would you like to install"));
|
||||||
Thread.sleep(1000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
try (LaunchResult result = doLaunch("lldb via ssh", Map.ofEntries(
|
try (LaunchResult result = doLaunch("lldb via ssh", Map.ofEntries(
|
||||||
Map.entry("arg:1", "/bin/ls"),
|
Map.entry("arg:1", "/bin/ls"),
|
||||||
|
@ -269,18 +176,15 @@ public class LldbConnectorsTest extends AbstractGhidraHeadedDebuggerIntegrationT
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLldbViaSshSetupProtobuf() throws Exception {
|
public void testLldbViaSshSetupProtobuf() throws Exception {
|
||||||
new ProcessBuilder().command("python", "-m", "pip", "install", "protobuf==3.19.0")
|
pip("ghidralldb==%s".formatted(Application.getApplicationVersion()));
|
||||||
.inheritIO()
|
// Overwrite with an incompatible version we don't include
|
||||||
.start()
|
pipOob("protobuf==3.19.0");
|
||||||
.waitFor();
|
|
||||||
try (LaunchResult result = doLaunch("lldb via ssh", Map.ofEntries(
|
try (LaunchResult result = doLaunch("lldb via ssh", Map.ofEntries(
|
||||||
Map.entry("arg:1", "/bin/ls"),
|
Map.entry("arg:1", "/bin/ls"),
|
||||||
Map.entry("OPT_HOST", "localhost")))) {
|
Map.entry("OPT_HOST", "localhost")))) {
|
||||||
assertTrue(result.exception() instanceof SocketTimeoutException);
|
assertTrue(result.exception() instanceof EarlyTerminationException);
|
||||||
TerminalSession term = Unique.assertOne(result.sessions().values());
|
assertThat(result.sessions().get("Shell").content(),
|
||||||
while (!term.isTerminated()) {
|
Matchers.containsString("Would you like to install"));
|
||||||
Thread.sleep(1000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
try (LaunchResult result = doLaunch("lldb via ssh", Map.ofEntries(
|
try (LaunchResult result = doLaunch("lldb via ssh", Map.ofEntries(
|
||||||
Map.entry("arg:1", "/bin/ls"),
|
Map.entry("arg:1", "/bin/ls"),
|
||||||
|
|
|
@ -187,7 +187,7 @@ public class ScriptTraceRmiLaunchOfferTest extends AbstractGhidraHeadedDebuggerT
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void terminated() {
|
public void terminated(int exitcode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -67,8 +67,10 @@ public class TestTraceRmiLaunchOpinion implements TraceRmiLaunchOpinion {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 {
|
Map<String, ValStr<?>> args, SocketAddress address) throws Exception {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue