Merge branch 'GP-5619_emteere_VariousSpeedImprovements_VERSION2'

This commit is contained in:
ghidra1 2025-05-08 16:18:38 -04:00
commit 0bf8f03a1e
79 changed files with 2290 additions and 1275 deletions

View file

@ -1,4 +1,4 @@
::@title dbgeng-kernel
::@title dbgeng kernel
::@desc <html><body width="300px">
::@desc <h3>Kernel debugging using <tt>dbgeng</tt> (in a Python interpreter)</h3>
::@desc <p>
@ -6,7 +6,7 @@
::@desc For setup instructions, press <b>F1</b>.
::@desc </p>
::@desc </body></html>
::@menu-group local
::@menu-group dbgeng
::@icon icon.debugger
::@help dbgeng#win_kernel
::@enum Connection:str Remote Local EXDI

View file

@ -1,4 +1,4 @@
::@title dbgeng-attach
::@title dbgeng attach
::@desc <html><body width="300px">
::@desc <h3>Attach with <tt>dbgeng</tt> (in a Python interpreter)</h3>
::@desc <p>
@ -6,7 +6,7 @@
::@desc For setup instructions, press <b>F1</b>.
::@desc </p>
::@desc </body></html>
::@menu-group local
::@menu-group dbgeng
::@icon icon.debugger
::@help dbgeng#attach
::@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."

View file

@ -1,4 +1,4 @@
::@title dbgeng-ext
::@title dbgeng extra options
::@image-opt env:OPT_TARGET_IMG
::@desc <html><body width="300px">
::@desc <h3>Launch with <tt>dbgeng</tt> (in a Python interpreter)</h3>
@ -7,7 +7,7 @@
::@desc For setup instructions, press <b>F1</b>.
::@desc </p>
::@desc </body></html>
::@menu-group local
::@menu-group dbgeng
::@icon icon.debugger
::@help dbgeng#ext
::@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."

View file

@ -1,4 +1,4 @@
::@title dbgeng-trace
::@title dbgeng TTD
::@desc <html><body width="300px">
::@desc <h3>Open trace with <tt>dbgeng</tt> (in a Python interpreter)</h3>
::@desc <p>
@ -6,7 +6,7 @@
::@desc For setup instructions, press <b>F1</b>.
::@desc </p>
::@desc </body></html>
::@menu-group local
::@menu-group dbgeng
::@icon icon.debugger
::@help dbgeng#ttd
::@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."

View file

@ -7,7 +7,7 @@
::@desc For setup instructions, press <b>F1</b>.
::@desc </p>
::@desc </body></html>
::@menu-group local
::@menu-group dbgeng
::@icon icon.debugger
::@help dbgeng#local
::@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."

View file

@ -1,4 +1,4 @@
::@title dbgeng-remote
::@title dbgeng remote
::@desc <html><body width="300px">
::@desc <h3>Connect to a remote debugger (via the .server interface)</h3>
::@desc <p>
@ -6,7 +6,7 @@
::@desc For setup instructions, press <b>F1</b>.
::@desc </p>
::@desc </body></html>
::@menu-group local
::@menu-group dbgeng
::@icon icon.debugger
::@help dbgeng#remote
::@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."

View file

@ -1,4 +1,4 @@
::@title dbgeng-svrcx
::@title dbgeng svrcx
::@image-opt env:OPT_TARGET_IMG
::@desc <html><body width="300px">
::@desc <h3>Connect to a remote <tt>dbgeng</tt> connection server and launch the target (in a Python interpreter)</h3>
@ -7,7 +7,7 @@
::@desc For setup instructions, press <b>F1</b>.
::@desc </p>
::@desc </body></html>
::@menu-group local
::@menu-group dbgeng
::@icon icon.debugger
::@help dbgeng#svrcx
::@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."

View file

@ -17,25 +17,16 @@
import os
import sys
home = os.getenv('GHIDRA_HOME')
if os.path.isdir(f'{home}\\ghidra\\.git'):
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-agent-dbgeng\\build\\pypkg\\src')
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-rmi-trace\\build\\pypkg\\src')
elif os.path.isdir(f'{home}\\.git'):
sys.path.append(
f'{home}\\Ghidra\\Debug\\Debugger-agent-dbgeng\\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-dbgeng\\pypkg\\src')
sys.path.append(f'{home}\\Ghidra\\Debug\\Debugger-rmi-trace\\pypkg\\src')
def append_paths():
sys.path.append("../../../Debugger-rmi-trace/data/support")
from gmodutils import ghidra_module_pypath
sys.path.append(ghidra_module_pypath("Debug/Debugger-rmi-trace"))
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
def main():
append_paths()
# Delay these imports until sys.path is patched
from ghidradbg import commands as cmd
from ghidradbg import util
@ -70,9 +61,14 @@ def main():
cmd.ghidra_trace_start("System")
cmd.ghidra_trace_sync_enable()
on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS, DbgEng.DEBUG_STATUS_BREAK)
on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS,
DbgEng.DEBUG_STATUS_BREAK)
cmd.repl()
if __name__ == '__main__':
try:
main()
except SystemExit as x:
if x.code != 0:
print(f"Exited with code {x.code}")

View file

@ -18,25 +18,15 @@ import os
import sys
home = os.getenv('GHIDRA_HOME')
if os.path.isdir(f'{home}\\ghidra\\.git'):
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-agent-dbgeng\\build\\pypkg\\src')
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-rmi-trace\\build\\pypkg\\src')
elif os.path.isdir(f'{home}\\.git'):
sys.path.append(
f'{home}\\Ghidra\\Debug\\Debugger-agent-dbgeng\\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-dbgeng\\pypkg\\src')
sys.path.append(f'{home}\\Ghidra\\Debug\\Debugger-rmi-trace\\pypkg\\src')
def append_paths():
sys.path.append("../../../Debugger-rmi-trace/data/support")
from gmodutils import ghidra_module_pypath
sys.path.append(ghidra_module_pypath("Debug/Debugger-rmi-trace"))
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
def main():
append_paths()
# Delay these imports until sys.path is patched
from ghidradbg import commands as cmd
from pybag.dbgeng import core as DbgEng
@ -61,9 +51,14 @@ def main():
cmd.ghidra_trace_start(os.getenv('OPT_TARGET_IMG'))
cmd.ghidra_trace_sync_enable()
on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS, DbgEng.DEBUG_STATUS_BREAK)
on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS,
DbgEng.DEBUG_STATUS_BREAK)
cmd.repl()
if __name__ == '__main__':
try:
main()
except SystemExit as x:
if x.code != 0:
print(f"Exited with code {x.code}")

View file

@ -18,25 +18,15 @@ import os
import sys
home = os.getenv('GHIDRA_HOME')
if os.path.isdir(f'{home}\\ghidra\\.git'):
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-agent-dbgeng\\build\\pypkg\\src')
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-rmi-trace\\build\\pypkg\\src')
elif os.path.isdir(f'{home}\\.git'):
sys.path.append(
f'{home}\\Ghidra\\Debug\\Debugger-agent-dbgeng\\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-dbgeng\\pypkg\\src')
sys.path.append(f'{home}\\Ghidra\\Debug\\Debugger-rmi-trace\\pypkg\\src')
def append_paths():
sys.path.append("../../../Debugger-rmi-trace/data/support")
from gmodutils import ghidra_module_pypath
sys.path.append(ghidra_module_pypath("Debug/Debugger-rmi-trace"))
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
def main():
append_paths()
# Delay these imports until sys.path is patched
from ghidradbg import commands as cmd
from pybag.dbgeng import core as DbgEng
@ -76,9 +66,14 @@ def main():
cmd.ghidra_trace_start(target)
cmd.ghidra_trace_sync_enable()
on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS, DbgEng.DEBUG_STATUS_BREAK)
on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS,
DbgEng.DEBUG_STATUS_BREAK)
cmd.repl()
if __name__ == '__main__':
try:
main()
except SystemExit as x:
if x.code != 0:
print(f"Exited with code {x.code}")

View file

@ -18,25 +18,15 @@ import os
import sys
home = os.getenv('GHIDRA_HOME')
if os.path.isdir(f'{home}\\ghidra\\.git'):
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-agent-dbgeng\\build\\pypkg\\src')
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-rmi-trace\\build\\pypkg\\src')
elif os.path.isdir(f'{home}\\.git'):
sys.path.append(
f'{home}\\Ghidra\\Debug\\Debugger-agent-dbgeng\\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-dbgeng\\pypkg\\src')
sys.path.append(f'{home}\\Ghidra\\Debug\\Debugger-rmi-trace\\pypkg\\src')
def append_paths():
sys.path.append("../../../Debugger-rmi-trace/data/support")
from gmodutils import ghidra_module_pypath
sys.path.append(ghidra_module_pypath("Debug/Debugger-rmi-trace"))
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
def main():
append_paths()
# Delay these imports until sys.path is patched
from ghidradbg import commands as cmd
from pybag.dbgeng import core as DbgEng
@ -73,4 +63,8 @@ def main():
if __name__ == '__main__':
try:
main()
except SystemExit as x:
if x.code != 0:
print(f"Exited with code {x.code}")

View file

@ -18,25 +18,15 @@ import os
import sys
home = os.getenv('GHIDRA_HOME')
if os.path.isdir(f'{home}\\ghidra\\.git'):
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-agent-dbgeng\\build\\pypkg\\src')
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-rmi-trace\\build\\pypkg\\src')
elif os.path.isdir(f'{home}\\.git'):
sys.path.append(
f'{home}\\Ghidra\\Debug\\Debugger-agent-dbgeng\\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-dbgeng\\pypkg\\src')
sys.path.append(f'{home}\\Ghidra\\Debug\\Debugger-rmi-trace\\pypkg\\src')
def append_paths():
sys.path.append("../../../Debugger-rmi-trace/data/support")
from gmodutils import ghidra_module_pypath
sys.path.append(ghidra_module_pypath("Debug/Debugger-rmi-trace"))
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
def main():
append_paths()
# Delay these imports until sys.path is patched
from ghidradbg import commands as cmd
from pybag.dbgeng import core as DbgEng
@ -68,9 +58,14 @@ def main():
cmd.ghidra_trace_start(target)
cmd.ghidra_trace_sync_enable()
on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS, DbgEng.DEBUG_STATUS_BREAK)
on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS,
DbgEng.DEBUG_STATUS_BREAK)
cmd.repl()
if __name__ == '__main__':
try:
main()
except SystemExit as x:
if x.code != 0:
print(f"Exited with code {x.code}")

View file

@ -18,25 +18,15 @@ import os
import sys
home = os.getenv('GHIDRA_HOME')
if os.path.isdir(f'{home}\\ghidra\\.git'):
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-agent-dbgeng\\build\\pypkg\\src')
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-rmi-trace\\build\\pypkg\\src')
elif os.path.isdir(f'{home}\\.git'):
sys.path.append(
f'{home}\\Ghidra\\Debug\\Debugger-agent-dbgeng\\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-dbgeng\\pypkg\\src')
sys.path.append(f'{home}\\Ghidra\\Debug\\Debugger-rmi-trace\\pypkg\\src')
def append_paths():
sys.path.append("../../../Debugger-rmi-trace/data/support")
from gmodutils import ghidra_module_pypath
sys.path.append(ghidra_module_pypath("Debug/Debugger-rmi-trace"))
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
def main():
append_paths()
# Delay these imports until sys.path is patched
from ghidradbg import commands as cmd
from pybag.dbgeng import core as DbgEng
@ -54,9 +44,14 @@ def main():
cmd.ghidra_trace_sync_enable()
dbg.interrupt()
on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS, DbgEng.DEBUG_STATUS_BREAK)
on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS,
DbgEng.DEBUG_STATUS_BREAK)
cmd.repl()
if __name__ == '__main__':
try:
main()
except SystemExit as x:
if x.code != 0:
print(f"Exited with code {x.code}")

View file

@ -20,25 +20,15 @@ import os
import sys
home = os.getenv('GHIDRA_HOME')
if os.path.isdir(f'{home}\\ghidra\\.git'):
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-agent-dbgeng\\build\\pypkg\\src')
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-rmi-trace\\build\\pypkg\\src')
elif os.path.isdir(f'{home}\\.git'):
sys.path.append(
f'{home}\\Ghidra\\Debug\\Debugger-agent-dbgeng\\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-dbgeng\\pypkg\\src')
sys.path.append(f'{home}\\Ghidra\\Debug\\Debugger-rmi-trace\\pypkg\\src')
def append_paths():
sys.path.append("../../../Debugger-rmi-trace/data/support")
from gmodutils import ghidra_module_pypath
sys.path.append(ghidra_module_pypath("Debug/Debugger-rmi-trace"))
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
def main():
append_paths()
# Delay these imports until sys.path is patched
from ghidradbg import commands as cmd
from pybag.dbgeng import core as DbgEng
@ -72,9 +62,14 @@ def main():
cmd.ghidra_trace_start(target)
cmd.ghidra_trace_sync_enable()
on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS, DbgEng.DEBUG_STATUS_BREAK)
on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS,
DbgEng.DEBUG_STATUS_BREAK)
cmd.repl()
if __name__ == '__main__':
try:
main()
except SystemExit as x:
if x.code != 0:
print(f"Exited with code {x.code}")

View file

@ -18,25 +18,15 @@ import os
import sys
home = os.getenv('GHIDRA_HOME')
if os.path.isdir(f'{home}\\ghidra\\.git'):
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-agent-dbgeng\\build\\pypkg\\src')
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-rmi-trace\\build\\pypkg\\src')
elif os.path.isdir(f'{home}\\.git'):
sys.path.append(
f'{home}\\Ghidra\\Debug\\Debugger-agent-dbgeng\\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-dbgeng\\pypkg\\src')
sys.path.append(f'{home}\\Ghidra\\Debug\\Debugger-rmi-trace\\pypkg\\src')
def append_paths():
sys.path.append("../../../Debugger-rmi-trace/data/support")
from gmodutils import ghidra_module_pypath
sys.path.append(ghidra_module_pypath("Debug/Debugger-rmi-trace"))
sys.path.append(ghidra_module_pypath("Debug/Debugger-agent-dbgeng"))
def main():
append_paths()
# Delay these imports until sys.path is patched
from ghidradbg import commands as cmd
from pybag.dbgeng import core as DbgEng
@ -65,9 +55,14 @@ def main():
cmd.ghidra_trace_start(os.getenv('OPT_TARGET_IMG'))
cmd.ghidra_trace_sync_enable()
on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS, DbgEng.DEBUG_STATUS_BREAK)
on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS,
DbgEng.DEBUG_STATUS_BREAK)
cmd.repl()
if __name__ == '__main__':
try:
main()
except SystemExit as x:
if x.code != 0:
print(f"Exited with code {x.code}")

View file

@ -14,6 +14,11 @@
# limitations under the License.
##
# NOTE: libraries must precede EVERYTHING, esp pybag and DbgMod
try:
import pybag
except Exception as e:
from ghidratrace.setuputils import prompt_and_mitigate_dependencies
prompt_and_mitigate_dependencies("Debug/Debugger-agent-dbgeng")
# NOTE: libraries must precede EVERYTHING, esp pybag and DbgMod
from . import libraries, util, commands, methods, hooks

View file

@ -14,7 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
#@title drgn-core
#@title drgn core
#@desc <html><body width="300px">
#@desc <h3>Launch with <tt>drgn-core</tt></h3>
#@desc <p>

View file

@ -14,7 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
#@title drgn-kernel
#@title drgn kernel
#@desc <html><body width="300px">
#@desc <h3>Launch with <tt>drgn-kernel</tt></h3>
#@desc <p>

View file

@ -2,15 +2,16 @@
##MODULE IP: JSch License
Module.manifest||GHIDRA||||END|
README.md||GHIDRA||||END|
data/debugger-launchers/local-gdb.bat||GHIDRA||||END|
data/debugger-launchers/qemu-sys-gdb.bat||GHIDRA||||END|
data/debugger-launchers/local-gdb.ps1||GHIDRA||||END|
data/debugger-launchers/qemu-sys-gdb.ps1||GHIDRA||||END|
data/debugger-launchers/remote-gdb.ps1||GHIDRA||||END|
data/debugger-launchers/ssh-gdb.bat||GHIDRA||||END|
data/debugger-launchers/ssh-gdbserver.bat||GHIDRA||||END|
data/debugger-launchers/ssh-gdb.ps1||GHIDRA||||END|
data/debugger-launchers/ssh-gdbserver.ps1||GHIDRA||||END|
data/scripts/fallback_info_proc_mappings.gdb||GHIDRA||||END|
data/scripts/fallback_maintenance_info_sections.gdb||GHIDRA||||END|
data/scripts/getpid-linux-i386.gdb||GHIDRA||||END|
data/scripts/wine32_info_proc_mappings.gdb||GHIDRA||||END|
data/support/gdbsetuputils.ps1||GHIDRA||||END|
src/main/help/help/TOC_Source.xml||GHIDRA||||END|
src/main/help/help/topics/gdb/gdb.html||GHIDRA||||END|
src/main/help/help/topics/gdb/images/GdbLauncher.png||GHIDRA||||END|

View file

@ -1,75 +0,0 @@
::@title gdb
::@image-opt env:OPT_TARGET_IMG
::@desc <html><body width="300px">
::@desc <h3>Launch with <tt>gdb</tt></h3>
::@desc <p>
::@desc This will launch the target on the local machine using <tt>gdb</tt>.
::@desc For setup instructions, press <b>F1</b>.
::@desc </p>
::@desc </body></html>
::@menu-group local
::@icon icon.debugger
::@help gdb#local
::@enum StartCmd:str run start starti
::@enum Endian:str auto big little
::@env OPT_TARGET_IMG:file="" "Image" "The target binary executable image"
::@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
::@env OPT_GDB_PATH:file="gdb" "gdb command" "The path to gdb. Omit the full path to resolve using the system PATH."
::@env OPT_START_CMD:StartCmd="starti" "Run command" "The gdb command to actually run the target."
::@env OPT_ARCH:str="auto" "Architecture" "Target architecture"
::@env OPT_ENDIAN:Endian="auto" "Endian" "Target byte order"
@echo off
set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-gdb\pypkg\src
set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\pypkg\src
IF EXIST %GHIDRA_HOME%\.git (
set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-gdb\build\pypkg\src
set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src
)
IF EXIST %GHIDRA_HOME%\ghidra\.git (
set PYTHONPATH0=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-agent-gdb\build\pypkg\src
set PYTHONPATH1=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src
)
set PYTHONPATH=%PYTHONPATH1%;%PYTHONPATH0%;%PYTHONPATH%
:: NB: This works - a lot of things do not. Don't change unless you know what you're doing!
set OPT_TARGET_ARGS=%OPT_TARGET_ARGS:"=\"%
set OPT_TARGET_ARGS=%OPT_TARGET_ARGS:)=^)%
:: NB: This seems stupid, but there doesn't seem to be a logical way to test before the previous lines
if %OPT_TARGET_ARGS%=="=\" (
set OPT_TARGET_ARGS=\"\"
)
IF "%OPT_TARGET_IMG%"=="" (
"%OPT_GDB_PATH%" ^
-q ^
-ex "set pagination off" ^
-ex "set confirm off" ^
-ex "show version" ^
-ex "python import ghidragdb" ^
-ex "set architecture %OPT_ARCH%" ^
-ex "set endian %OPT_ENDIAN%" ^
-ex "ghidra trace connect '%GHIDRA_TRACE_RMI_ADDR%'" ^
-ex "ghidra trace start" ^
-ex "ghidra trace sync-enable" ^
-ex "set confirm on" ^
-ex "set pagination on"
) ELSE (
"%OPT_GDB_PATH%" ^
-q ^
-ex "set pagination off" ^
-ex "set confirm off" ^
-ex "show version" ^
-ex "python import ghidragdb" ^
-ex "set architecture %OPT_ARCH%" ^
-ex "set endian %OPT_ENDIAN%" ^
-ex "target exec %OPT_TARGET_IMG%" ^
-ex "set args %OPT_TARGET_ARGS%" ^
-ex "ghidra trace connect '%GHIDRA_TRACE_RMI_ADDR%'" ^
-ex "ghidra trace start" ^
-ex "ghidra trace sync-enable" ^
-ex "%OPT_START_CMD%" ^
-ex "set confirm on" ^
-ex "set pagination on"
)

View file

@ -0,0 +1,33 @@
#@title gdb
#@image-opt arg:1
#@desc <html><body width="300px">
#@desc <h3>Launch with <tt>gdb</tt></h3>
#@desc <p>
#@desc This will launch the target on the local machine using <tt>gdb</tt>.
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group gdb
#@icon icon.debugger
#@help gdb#local
#@enum StartCmd:str run start starti
#@enum Endian:str auto big little
#@arg :file "Image" "The target binary executable image"
#@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
#@env OPT_GDB_PATH:file="gdb" "gdb command" "The path to gdb. Omit the full path to resolve using the system PATH."
#@env OPT_START_CMD:StartCmd="starti" "Run command" "The gdb command to actually run the target."
#@env OPT_ARCH:str="auto" "Architecture" "Target architecture"
#@env OPT_ENDIAN:Endian="auto" "Endian" "Target byte order"
. ..\support\gdbsetuputils.ps1
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
$pypathGdb = Ghidra-Module-PyPath "Debug/Debugger-agent-gdb"
$Env:PYTHONPATH = "$pypathGdb;$pypathTrace;$Env:PYTHONPATH"
$arglist = Compute-Gdb-Usermode-Args `
-TargetImage $args[0] `
-RmiAddress "$Env:GHIDRA_TRACE_RMI_ADDR"
Start-Process -FilePath $arglist[0] -ArgumentList $arglist[1..$arglist.Count] `
-NoNewWindow -Wait

View file

@ -23,7 +23,7 @@
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group local
#@menu-group gdb
#@icon icon.debugger
#@help gdb#local
#@enum StartCmd:str run start starti
@ -37,57 +37,19 @@
#@env OPT_EXTRA_TTY:bool=false "Inferior TTY" "Provide a separate terminal emulator for the target."
#@tty TTY_TARGET if env:OPT_EXTRA_TTY
if [ -d ${GHIDRA_HOME}/ghidra/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
elif [ -d ${GHIDRA_HOME}/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
else
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-gdb/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/pypkg/src:$PYTHONPATH
fi
. ../support/gdbsetuputils.sh
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
target_image="$1"
shift
target_args="$@"
# Ghidra will leave TTY_TARGET empty when OPT_EXTRA_TTY is false. Gdb takes empty to mean the same terminal.
function launch-gdb() {
local -a args
compute-gdb-usermode-args "$target_image" "$GHIDRA_TRACE_RMI_ADDR" "$@"
if [ -z "$target_image" ]
then
"$OPT_GDB_PATH" \
-q \
-ex "set pagination off" \
-ex "set confirm off" \
-ex "show version" \
-ex "python import ghidragdb" \
-ex "set architecture $OPT_ARCH" \
-ex "set endian $OPT_ENDIAN" \
-ex "set inferior-tty $TTY_TARGET" \
-ex "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \
-ex "ghidra trace start" \
-ex "ghidra trace sync-enable" \
-ex "set confirm on" \
-ex "set pagination on"
else
"$OPT_GDB_PATH" \
-q \
-ex "set pagination off" \
-ex "set confirm off" \
-ex "show version" \
-ex "python import ghidragdb" \
-ex "set architecture $OPT_ARCH" \
-ex "set endian $OPT_ENDIAN" \
-ex "file \"$target_image\"" \
-ex "set args $target_args" \
-ex "set inferior-tty $TTY_TARGET" \
-ex "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \
-ex "ghidra trace start" \
-ex "ghidra trace sync-enable" \
-ex "$OPT_START_CMD" \
-ex "set confirm on" \
-ex "set pagination on"
fi
"${args[@]}"
}
launch-gdb

View file

@ -22,7 +22,7 @@
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group local
#@menu-group gdb
#@icon icon.debugger
#@help gdb#rr
#@enum StartCmd:str run start starti
@ -34,20 +34,13 @@
#@env OPT_EXTRA_TTY:bool=false "Inferior TTY" "Provide a separate terminal emulator for the target."
#@tty TTY_TARGET if env:OPT_EXTRA_TTY
if [ -d ${GHIDRA_HOME}/ghidra/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
elif [ -d ${GHIDRA_HOME}/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
else
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-gdb/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/pypkg/src:$PYTHONPATH
fi
. ../support/gdbsetuputils.sh
target_image="$1"
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
target_trace="$1"
# Ghidra will leave TTY_TARGET empty when OPT_EXTRA_TTY is false. Gdb takes empty to mean the same terminal.
@ -68,5 +61,5 @@ set confirm on
set pagination on
' > $RRINIT
"$OPT_RR_PATH" replay -x $RRINIT "$target_image"
"$OPT_RR_PATH" replay -x $RRINIT "$target_trace"

View file

@ -14,7 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
#@title qemu + gdb
#@title gdb + qemu
#@image-opt arg:1
#@desc <html><body width="300px">
#@desc <h3>Launch with <tt>qemu</tt> and connect with <tt>gdb</tt></h3>
@ -24,7 +24,7 @@
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group cross
#@menu-group gdb
#@icon icon.debugger
#@help gdb#qemu
#@enum Endian:str auto big little
@ -40,53 +40,33 @@
#@env OPT_PULL_ALL_SECTIONS:bool=false "Pull all section mappings" "Force gdb to send all mappings to Ghidra. This can be costly (see help)."
#@tty TTY_TARGET if env:OPT_EXTRA_TTY
if [ -d ${GHIDRA_HOME}/ghidra/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
elif [ -d ${GHIDRA_HOME}/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
else
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-gdb/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/pypkg/src:$PYTHONPATH
fi
. ../support/gdbsetuputils.sh
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
target_image="$1"
# No need to put QEMU_GDB on command line. It's already a recognized environment variable.
if [ -z "$TTY_TARGET" ]
then
"$GHIDRA_LANG_EXTTOOL_qemu" $OPT_EXTRA_QEMU_ARGS $@ &
"$GHIDRA_LANG_EXTTOOL_qemu" $OPT_EXTRA_QEMU_ARGS "$@" &
else
"$GHIDRA_LANG_EXTTOOL_qemu" $OPT_EXTRA_QEMU_ARGS $@ <$TTY_TARGET >$TTY_TARGET 2>&1 &
"$GHIDRA_LANG_EXTTOOL_qemu" $OPT_EXTRA_QEMU_ARGS "$@" <$TTY_TARGET >$TTY_TARGET 2>&1 &
fi
# Give QEMU a moment to open the socket
sleep 0.1
declare -a args
function launch-gdb() {
local -a args
compute-gdb-remote-args "$target_image" "remote localhost:$QEMU_GDB" "$GHIDRA_TRACE_RMI_ADDR"
args+=(-q)
args+=(-ex "set pagination off")
args+=(-ex "set confirm off")
args+=(-ex "show version")
args+=(-ex "python import ghidragdb")
args+=(-ex "set architecture $OPT_ARCH")
args+=(-ex "set endian $OPT_ENDIAN")
args+=(-ex "file '$target_image'")
args+=(-ex "ghidra trace connect '$GHIDRA_TRACE_RMI_ADDR'")
args+=(-ex "ghidra trace start")
args+=(-ex "ghidra trace sync-enable")
args+=(-ex "target remote localhost:$QEMU_GDB")
if [ "$OPT_PULL_ALL_SECTIONS" = "true" ]
then
args+=(-ex "ghidra trace tx-start put-all-sections")
args+=(-ex "ghidra trace put-sections -all-objects")
args+=(-ex "ghidra trace tx-commit")
if [ "$OPT_PULL_ALL_SECTIONS" = "true" ]; then
args+=(-ex "ghidra trace tx-open 'Put Sections' 'ghidra trace put-sections -all-objects'")
fi
args+=(-ex "set confirm on")
args+=(-ex "set pagination on")
"$OPT_GDB_PATH" "${args[@]}"
"${args[@]}"
}
launch-gdb

View file

@ -1,60 +0,0 @@
::@title qemu-system + gdb
::@image-opt env:OPT_TARGET_IMG
::@desc <html><body width="300px">
::@desc <h3>Launch with <tt>qemu-system</tt> and connect with <tt>gdb</tt></h3>
::@desc <p>
::@desc This will launch the target on the local machine using <tt>qemu-system</tt>.
::@desc Then in a second terminal, it will connect <tt>gdb</tt> to QEMU's GDBstub.
::@desc For setup instructions, press <b>F1</b>.
::@desc </p>
::@desc </body></html>
::@menu-group cross
::@icon icon.debugger
::@help gdb#qemu
::@enum Endian:str auto big little
::@env OPT_TARGET_IMG:file!="" "Image" "The target binary executable image"
::@env GHIDRA_LANG_EXTTOOL_qemu_system:file="" "QEMU command" "The path to qemu-system for the target architecture."
::@env QEMU_GDB:int=1234 "QEMU Port" "Port for gdb connection to qemu"
::@env OPT_EXTRA_QEMU_ARGS:str="" "Extra qemu arguments" "Extra arguments to pass to qemu. Use with care."
::@env OPT_GDB_PATH:file="gdb-multiarch" "gdb command" "The path to gdb. Omit the full path to resolve using the system PATH."
::@env OPT_ARCH:str="auto" "Architecture" "Target architecture"
::@env OPT_ENDIAN:Endian="auto" "Endian" "Target byte order"
::@env OPT_EXTRA_TTY:bool=false "QEMU TTY" "Provide a separate terminal emulator for qemu."
@echo off
set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-gdb\pypkg\src
set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\pypkg\src
IF EXIST %GHIDRA_HOME%\.git (
set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-gdb\build\pypkg\src
set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src
)
IF EXIST %GHIDRA_HOME%\ghidra\.git (
set PYTHONPATH0=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-agent-gdb\build\pypkg\src
set PYTHONPATH1=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src
)
set PYTHONPATH=%PYTHONPATH1%;%PYTHONPATH0%;%PYTHONPATH%
IF "%OPT_EXTRA_TTY%"=="true" (
start "qemu" "%GHIDRA_LANG_EXTTOOL_qemu_system%" %OPT_EXTRA_QEMU_ARGS% -gdb tcp::%QEMU_GDB% -S "%OPT_TARGET_IMG%"
) ELSE (
start /B "qemu" "%GHIDRA_LANG_EXTTOOL_qemu_system%" %OPT_EXTRA_QEMU_ARGS% -gdb tcp::%QEMU_GDB% -S "%OPT_TARGET_IMG%"
)
:: Give QEMU a moment to open the socket
powershell -nop -c "& {sleep -m 100}"
"%OPT_GDB_PATH%" ^
-q ^
-ex "set pagination off" ^
-ex "set confirm off" ^
-ex "show version" ^
-ex "python import ghidragdb" ^
ex "set architecture %OPT_ARCH%" ^
ex "set endian %OPT_ENDIAN%" ^
-ex "target exec '%OPT_TARGET_IMG%'" ^
-ex "ghidra trace connect '%GHIDRA_TRACE_RMI_ADDR%'" ^
-ex "ghidra trace start" ^
-ex "ghidra trace sync-enable" ^
-ex "target remote localhost:%QEMU_GDB%" ^
-ex "set confirm on" ^
-ex "set pagination on"

View file

@ -0,0 +1,52 @@
#@title gdb + qemu-system
#@image-opt env:OPT_TARGET_IMG
#@desc <html><body width="300px">
#@desc <h3>Launch with <tt>qemu-system</tt> and connect with <tt>gdb</tt></h3>
#@desc <p>
#@desc This will launch the target on the local machine using <tt>qemu-system</tt>.
#@desc Then in a second terminal, it will connect <tt>gdb</tt> to QEMU's GDBstub.
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group gdb
#@icon icon.debugger
#@help gdb#qemu
#@enum Endian:str auto big little
#@env OPT_TARGET_IMG:file!="" "Image" "The target binary executable image"
#@env GHIDRA_LANG_EXTTOOL_qemu_system:file="" "QEMU command" "The path to qemu-system for the target architecture."
#@env QEMU_GDB:int=1234 "QEMU Port" "Port for gdb connection to qemu"
#@env OPT_EXTRA_QEMU_ARGS:str="" "Extra qemu arguments" "Extra arguments to pass to qemu. Use with care."
#@env OPT_GDB_PATH:file="gdb-multiarch" "gdb command" "The path to gdb. Omit the full path to resolve using the system PATH."
#@env OPT_ARCH:str="auto" "Architecture" "Target architecture"
#@env OPT_ENDIAN:Endian="auto" "Endian" "Target byte order"
#@env OPT_EXTRA_TTY:bool=false "QEMU TTY" "Provide a separate terminal emulator for qemu."
. ..\support\gdbsetuputils.ps1
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
$pypathGdb = Ghidra-Module-PyPath "Debug/Debugger-agent-gdb"
$Env:PYTHONPATH = "$pypathGdb;$pypathTrace;$Env:PYTHONPATH"
$qemuargs = @("`"$Env:GHIDRA_LANG_EXTTOOL_qemu_system`"")
if ("$Env:OPT_EXTRA_QEMU_ARGS" -ne "") {
$qemuargs+=("$Env:OPT_EXTRA_QEMU_ARGS")
}
$qemuargs+=("-gdb", "tcp::$Env:QEMU_GDB", "-S")
$qemuargs+=("`"$Env:OPT_TARGET_IMG`"")
if ("$Env:OPT_EXTRA_TTY" -eq "true") {
Start-Process -FilePath $qemuargs[0] -ArgumentList $qemuargs[1..$qemuargs.Count]
}
else {
Start-Process -FilePath $qemuargs[0] -ArgumentList $qemuargs[1..$qemuargs.Count] -NoNewWindow
}
# Give QEMU a moment to open the socket
sleep -m 100
$arglist = Compute-Gdb-Remote-Args `
-TargetImage $args[0] `
-TargetCx "remote localhost:$Env:QEMU_GDB" `
-RmiAddress "$Env:GHIDRA_TRACE_RMI_ADDR"
Start-Process -FilePath $arglist[0] -ArgumentList $arglist[1..$arglist.Count] -NoNewWindow -Wait

View file

@ -14,7 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
#@title qemu-system + gdb
#@title gdb + qemu-system
#@image-opt arg:1
#@desc <html><body width="300px">
#@desc <h3>Launch with <tt>qemu-system</tt> and connect with <tt>gdb</tt></h3>
@ -24,7 +24,7 @@
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group cross
#@menu-group gdb
#@icon icon.debugger
#@help gdb#qemu
#@enum Endian:str auto big little
@ -39,57 +39,32 @@
#@env OPT_PULL_ALL_SECTIONS:bool=false "Pull all section mappings" "Force gdb to send all mappings to Ghidra. This can be costly (see help)."
#@tty TTY_TARGET if env:OPT_EXTRA_TTY
if [ -d ${GHIDRA_HOME}/ghidra/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
elif [ -d ${GHIDRA_HOME}/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
else
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-gdb/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/pypkg/src:$PYTHONPATH
fi
. ../support/gdbsetuputils.sh
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
target_image="$1"
if [ -z "$TTY_TARGET" ]
then
"$GHIDRA_LANG_EXTTOOL_qemu_system" $OPT_EXTRA_QEMU_ARGS -gdb tcp::$QEMU_GDB -S $1 &
"$GHIDRA_LANG_EXTTOOL_qemu_system" $OPT_EXTRA_QEMU_ARGS -gdb tcp::$QEMU_GDB -S $target_image &
else
"$GHIDRA_LANG_EXTTOOL_qemu_system" $OPT_EXTRA_QEMU_ARGS -gdb tcp::$QEMU_GDB -S $1 <$TTY_TARGET >$TTY_TARGET 2>&1 &
"$GHIDRA_LANG_EXTTOOL_qemu_system" $OPT_EXTRA_QEMU_ARGS -gdb tcp::$QEMU_GDB -S $target_image <$TTY_TARGET >$TTY_TARGET 2>&1 &
fi
# Give QEMU a moment to open the socket
sleep 0.1
gdb_args=(
-q
-ex "set pagination off"
-ex "set confirm off"
-ex "show version"
-ex "python import ghidragdb"
-ex "set architecture $OPT_ARCH"
-ex "set endian $OPT_ENDIAN"
-ex "file \"$target_image\""
-ex "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\""
-ex "ghidra trace start"
-ex "ghidra trace sync-enable"
-ex "target remote localhost:$QEMU_GDB"
-ex "set confirm on"
-ex "set pagination on"
)
function launch-gdb() {
local -a args
compute-gdb-remote-args "$target_image" "remote localhost:$QEMU_GDB" "$GHIDRA_TRACE_RMI_ADDR"
# If using OPT_PULL_ALL_SECTIONS, append instructions to push all sections from qemu
if [ "$OPT_PULL_ALL_SECTIONS" = "true" ]
then
gdb_args+=(
-ex "ghidra trace tx-start put-all-sections"
-ex "ghidra trace put-sections -all-objects"
-ex "ghidra trace tx-commit"
)
if [ "$OPT_PULL_ALL_SECTIONS" = "true" ]; then
args+=(-ex "ghidra trace tx-open 'Put Sections' 'ghidra trace put-sections -all-objects'")
fi
IFS=""
"$OPT_GDB_PATH" ${gdb_args[*]}
"${args[@]}"
}
launch-gdb

View file

@ -1,4 +1,4 @@
#@title remote gdb
#@title gdb remote
#@image-opt arg:1
#@desc <html><body width="300px">
#@desc <h3>Launch with local <tt>gdb</tt> and connect to a stub (e.g., <tt>gdbserver</tt>)</h3>
@ -7,7 +7,7 @@
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group remote
#@menu-group gdb
#@icon icon.debugger
#@help gdb#remote
#@enum TargetType:str remote extended-remote
@ -20,42 +20,15 @@
#@env OPT_ARCH:str="auto" "Architecture" "Target architecture override"
#@env OPT_ENDIAN:Endian="auto" "Endian" "Target byte order"
[IO.DirectoryInfo] $repo = "$Env:GHIDRA_HOME\.git"
[IO.DirectoryInfo] $repoParent = "$Env:GHIDRA_HOME\ghidra\.git"
if ($repo.Exists) {
$pypathGdb = "$Env:GHIDRA_HOME\Ghidra\Debug\Debugger-agent-gdb\build\pypkg\src"
$pypathTrace = "$Env:GHIDRA_HOME\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src"
}
elseif ($repoParent.Exists) {
$pypathGdb = "$Env:GHIDRA_HOME\ghidra\Ghidra\Debug\Debugger-agent-gdb\build\pypkg\src"
$pypathTrace = "$Env:GHIDRA_HOME\ghidra\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src"
}
else {
$pypathGdb = "$Env:GHIDRA_HOME\Ghidra\Debug\Debugger-agent-gdb\pypkg\src"
$pypathTrace = "$Env:GHIDRA_HOME\Ghidra\Debug\Debugger-rmi-trace\pypkg\src"
}
. ..\support\gdbsetuputils.ps1
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
$pypathGdb = Ghidra-Module-PyPath "Debug/Debugger-agent-gdb"
$Env:PYTHONPATH = "$pypathGdb;$pypathTrace;$Env:PYTHONPATH"
$arglist = @()
$arglist = Compute-Gdb-Remote-Args `
-TargetImage $args[0] `
-TargetCx "$Env:OPT_TARGET_TYPE $Env:OPT_HOST`:$Env:OPT_PORT" `
-RmiAddress "$Env:GHIDRA_TRACE_RMI_ADDR"
$arglist+=("-q")
$arglist+=("-ex", "`"set pagination off`"")
$arglist+=("-ex", "`"set confirm off`"")
$arglist+=("-ex", "`"show version`"")
$arglist+=("-ex", "`"python import ghidragdb`"")
$arglist+=("-ex", "`"set architecture $Env:OPT_ARCH`"")
$arglist+=("-ex", "`"set endian $Env:OPT_ENDIAN`"")
if ("$($args[0])" -ne "") {
$image = $args[0] -replace "\\", "\\\\"
$arglist+=("-ex", "`"file '$image'`"")
}
$arglist+=("-ex", "`"echo Connecting to $Env:OPT_HOST`:$Env:OPT_PORT... `"")
$arglist+=("-ex", "`"target $Env:OPT_TARGET_TYPE $Env:OPT_HOST`:$Env:OPT_PORT`"")
$arglist+=("-ex", "`"ghidra trace connect '$Env:GHIDRA_TRACE_RMI_ADDR'`"")
$arglist+=("-ex", "`"ghidra trace start`"")
$arglist+=("-ex", "`"ghidra trace sync-enable`"")
$arglist+=("-ex", "`"ghidra trace sync-synth-stopped`"")
$arglist+=("-ex", "`"set confirm on`"")
$arglist+=("-ex", "`"set pagination on`"")
Start-Process -FilePath $Env:OPT_GDB_PATH -ArgumentList $arglist -NoNewWindow -Wait
Start-Process -FilePath $arglist[0] -ArgumentList $arglist[1..$arglist.Count] -NoNewWindow -Wait

View file

@ -14,7 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
#@title remote gdb
#@title gdb remote
#@image-opt arg:1
#@desc <html><body width="300px">
#@desc <h3>Launch with local <tt>gdb</tt> and connect to a stub (e.g., <tt>gdbserver</tt>)</h3>
@ -23,7 +23,7 @@
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group remote
#@menu-group gdb
#@icon icon.debugger
#@help gdb#remote
#@enum TargetType:str remote extended-remote
@ -36,39 +36,18 @@
#@env OPT_ARCH:str="auto" "Architecture" "Target architecture override"
#@env OPT_ENDIAN:Endian="auto" "Endian" "Target byte order"
if [ -d ${GHIDRA_HOME}/ghidra/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
elif [ -d ${GHIDRA_HOME}/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
else
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-gdb/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/pypkg/src:$PYTHONPATH
fi
. ../support/gdbsetuputils.sh
declare -a args
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
args+=(-q)
args+=(-ex "set pagination off")
args+=(-ex "set confirmation off")
args+=(-ex "show version")
args+=(-ex "python import ghidragdb")
args+=(-ex "set architecture $OPT_ARCH")
args+=(-ex "set endian $OPT_ENDIAN")
if [ -n "$1" ]
then
args+=(-ex "file '$1'")
fi
args+=(-ex "echo Connecting to $OPT_HOST:$OPT_PORT...")
args+=(-ex "target $OPT_TARGET_TYPE $OPT_HOST:$OPT_PORT")
args+=(-ex "ghidra trace connect '$GHIDRA_TRACE_RMI_ADDR'")
args+=(-ex "ghidra trace start")
args+=(-ex "ghidra trace sync-enable")
args+=(-ex "ghidra trace sync-synth-stopped")
args+=(-ex "set confirm on")
args+=(-ex "set pagination on")
target_image="$1"
"$OPT_GDB_PATH" "${args[@]}"
function launch-gdb() {
local -a args
compute-gdb-remote-args "$target_image" "$OPT_TARGET_TYPE $OPT_HOST:$OPT_PORT" "$GHIDRA_TRACE_RMI_ADDR"
"${args[@]}"
}
launch-gdb

View file

@ -1,62 +0,0 @@
::@timeout 60000
::@title gdb via ssh
::@image-opt env:OPT_TARGET_IMG
::@desc <html><body width="300px">
::@desc <h3>Launch with <tt>gdb</tt> via <tt>ssh</tt></h3>
::@desc <p>
::@desc This will launch the target on a remote machine using <tt>gdb</tt> via <tt>ssh</tt>.
::@desc For setup instructions, press <b>F1</b>.
::@desc </p>
::@desc </body></html>
::@menu-group remote
::@icon icon.debugger
::@help gdb#ssh
::@enum StartCmd:str run start starti
::@enum Endian:str auto big little
::@env OPT_TARGET_IMG: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_SSH_PATH:file="ssh" "ssh command" "The path to ssh on the local system. Omit the full path to resolve using the system PATH."
::@env OPT_HOST:str="localhost" "[User@]Host" "The hostname or user@host"
::@env OPT_REMOTE_PORT:int=12345 "Remote Trace RMI Port" "A free port on the remote end to receive and forward the Trace RMI connection."
::@env OPT_EXTRA_SSH_ARGS:str="" "Extra ssh arguments" "Extra arguments to pass to ssh. Use with care."
::@env OPT_GDB_PATH:str="gdb" "gdb command" "The path to gdb on the remote system. Omit the full path to resolve using the system PATH."
::@env OPT_START_CMD:StartCmd="starti" "Run command" "The gdb command to actually run the target."
::@env OPT_ARCH:str="i386:x86-64" "Architecture" "Target architecture"
::@env OPT_ENDIAN:Endian="auto" "Endian" "Target byte order"
@echo off
IF "%OPT_TARGET_IMG%" == "" (
set cmd=TERM='%TERM%' '%OPT_GDB_PATH%' ^
-q ^
-ex 'set pagination off' ^
-ex 'set confirm off' ^
-ex 'show version' ^
-ex 'python import ghidragdb' ^
-ex 'set architecture %OPT_ARCH%' ^
ex 'set endian %OPT_ENDIAN%' ^
-ex 'ghidra trace connect \"localhost:%OPT_REMOTE_PORT%\"' ^
-ex 'ghidra trace start' ^
-ex 'ghidra trace sync-enable' ^
-ex 'set confirm on' ^
-ex 'set pagination on'
) ELSE (
set cmd=TERM='%TERM%' '%OPT_GDB_PATH%' ^
-q ^
-ex 'set pagination off' ^
-ex 'set confirm off' ^
-ex 'show version' ^
-ex 'python import ghidragdb' ^
-ex 'set architecture %OPT_ARCH%' ^
ex 'set endian %OPT_ENDIAN%' ^
-ex 'file \"%OPT_TARGET_IMG%\"' ^
-ex 'set args %OPT_TARGET_ARGS%' ^
-ex 'ghidra trace connect \"localhost:%OPT_REMOTE_PORT%\"' ^
-ex 'ghidra trace start' ^
-ex 'ghidra trace sync-enable' ^
-ex '%OPT_START_CMD%' ^
-ex 'set confirm on' ^
-ex 'set pagination on'
)
"%OPT_SSH_PATH%" "-R%OPT_REMOTE_PORT%:%GHIDRA_TRACE_RMI_ADDR%" -t %OPT_EXTRA_SSH_ARGS% "%OPT_HOST%" "%cmd%"

View file

@ -0,0 +1,70 @@
#@timeout 60000
#@title gdb via ssh
#@image-opt arg:1
#@desc <html><body width="300px">
#@desc <h3>Launch with <tt>gdb</tt> via <tt>ssh</tt></h3>
#@desc <p>
#@desc This will launch the target on a remote machine using <tt>gdb</tt> via <tt>ssh</tt>.
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group gdb
#@icon icon.debugger
#@help gdb#ssh
#@enum StartCmd:str run start starti
#@enum Endian:str auto big little
#@arg :str "Image" "The target binary executable image on the remote system"
#@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
#@env OPT_SSH_PATH:file="ssh" "ssh command" "The path to ssh on the local system. Omit the full path to resolve using the system PATH."
#@env OPT_HOST:str="localhost" "[User@]Host" "The hostname or user@host"
#@env OPT_REMOTE_PORT:int=12345 "Remote Trace RMI Port" "A free port on the remote end to receive and forward the Trace RMI connection."
#@env OPT_EXTRA_SSH_ARGS:str="" "Extra ssh arguments" "Extra arguments to pass to ssh. Use with care."
#@env OPT_GDB_PATH:str="gdb" "gdb command" "The path to gdb on the remote system. Omit the full path to resolve using the system PATH."
#@env OPT_START_CMD:StartCmd="starti" "Run command" "The gdb command to actually run the target."
#@env OPT_ARCH:str="i386:x86-64" "Architecture" "Target architecture"
#@env OPT_ENDIAN:Endian="auto" "Endian" "Target byte order"
. ..\support\gdbsetuputils.ps1
$arglist = Compute-Gdb-Usermode-Args -TargetImage $args[0] -RmiAddress "localhost:$Env:OPT_REMOTE_PORT"
$sshargs = Compute-Ssh-Args $arglist True
$sshproc = Start-Process -FilePath $sshargs[0] -ArgumentList $sshargs[1..$sshargs.Count] -NoNewWindow -Wait -PassThru
$version = Get-Ghidra-Version
$answer = Check-Result-And-Prompt-Mitigation $sshproc @"
It appears ghidragdb is missing from the remote system. This can happen if you
forgot to install the required package. This can also happen if you installed
the packages to a different Python environment than is being used by the
remote's gdb.
This script is about to offer automatic resolution. If you'd like to resolve
this manually, answer no to the next question and then see Ghidra's help by
pressing F1 in the dialog of launch parameters.
WARNING: Answering yes to the next question will invoke pip to try to install
missing or incorrectly-versioned dependencies. It may attempt to find packages
from the PyPI mirror configured on the REMOTE system. If you have not configured
one, it will connect to the official one.
WARNING: We invoke pip with the --break-system-packages flag, because some
debuggers that embed Python (gdb, lldb) may not support virtual environments,
and so the packages must be installed to your user environment.
NOTE: This will copy Python wheels into the HOME directory of the user on the
remote system. You may be prompted to authenticate a few times while packages
are copied and installed.
NOTE: Automatic resolution will cause this session to terminate. When it has
finished, try launching again.
"@ "Would you like to install 'ghidragdb==$version'?"
if ($answer) {
Write-Host "Copying Wheels to $Env:OPT_HOST"
Mitigate-Scp-PyModules "Debug/Debugger-rmi-trace" "Debug/Debugger-agent-gdb"
Write-Host "Installing Wheels into GDB's embedded Python"
$arglist = Compute-Gdb-PipInstall-Args "'-f'" "os.environ['HOME']" "'ghidragdb==$version'"
$sshargs = Compute-Ssh-Args $arglist False
Start-Process -FilePath $sshargs[0] -ArgumentList $sshargs[1..$sshargs.Count] -NoNewWindow -Wait
}

View file

@ -24,7 +24,7 @@
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group remote
#@menu-group gdb
#@icon icon.debugger
#@help gdb#ssh
#@enum StartCmd:str run start starti
@ -40,40 +40,61 @@
#@env OPT_ARCH:str="i386:x86-64" "Architecture" "Target architecture"
#@env OPT_ENDIAN:Endian="auto" "Endian" "Target byte order"
. ../support/gdbsetuputils.sh
target_image="$1"
shift
target_args="$@"
if [ -z "$target_image" ]
then
"$OPT_SSH_PATH" "-R$OPT_REMOTE_PORT:$GHIDRA_TRACE_RMI_ADDR" -t $OPT_EXTRA_SSH_ARGS "$OPT_HOST" "TERM='$TERM' '$OPT_GDB_PATH' \
-q \
-ex 'set pagination off' \
-ex 'set confirm off' \
-ex 'show version' \
-ex 'python import ghidragdb' \
-ex 'set architecture $OPT_ARCH' \
-ex 'set endian $OPT_ENDIAN' \
-ex 'ghidra trace connect \"localhost:$OPT_REMOTE_PORT\"' \
-ex 'ghidra trace start' \
-ex 'ghidra trace sync-enable' \
-ex 'set confirm on' \
-ex 'set pagination on'"
else
"$OPT_SSH_PATH" "-R$OPT_REMOTE_PORT:$GHIDRA_TRACE_RMI_ADDR" -t $OPT_EXTRA_SSH_ARGS "$OPT_HOST" "TERM='$TERM' '$OPT_GDB_PATH' \
-q \
-ex 'set pagination off' \
-ex 'set confirm off' \
-ex 'show version' \
-ex 'python import ghidragdb' \
-ex 'set architecture $OPT_ARCH' \
-ex 'set endian $OPT_ENDIAN' \
-ex 'file \"$target_image\"' \
-ex 'set args $target_args' \
-ex 'ghidra trace connect \"localhost:$OPT_REMOTE_PORT\"' \
-ex 'ghidra trace start' \
-ex 'ghidra trace sync-enable' \
-ex '$OPT_START_CMD' \
-ex 'set confirm on' \
-ex 'set pagination on'"
function launch-gdb-ssh() {
local -a args
compute-gdb-usermode-args "$target_image" "localhost:$OPT_REMOTE_PORT" "$@"
local -a sshargs
compute-ssh-args true "${args[@]}"
"${sshargs[@]}"
}
version=$(get-ghidra-version)
function do-installation() {
local -a pipargs
compute-gdb-pipinstall-args "'-f'" "os.environ['HOME']" "'ghidragdb==$version'"
local -a sshargs
compute-ssh-args false "${pipargs[@]}"
"${sshargs[@]}"
}
launch-gdb-ssh
if check-result-and-prompt-mitigation $? "
It appears ghidragdb is missing from the remote system. This can happen if you
forgot to install the required package. This can also happen if you installed
the packages to a different Python environment than is being used by the
remote's gdb.
This script is about to offer automatic resolution. If you'd like to resolve
this manually, answer no to the next question and then see Ghidra's help by
pressing F1 in the dialog of launch parameters.
WARNING: Answering yes to the next question will invoke pip to try to install
missing or incorrectly-versioned dependencies. It may attempt to find packages
from the PyPI mirror configured on the REMOTE system. If you have not configured
one, it will connect to the official one.
WARNING: We invoke pip with the --break-system-packages flag, because some
debuggers that embed Python (gdb, lldb) may not support virtual environments,
and so the packages must be installed to your user environment.
NOTE: This will copy Python wheels into the HOME directory of the user on the
remote system. You may be prompted to authenticate a few times while packages
are copied and installed.
NOTE: Automatic resolution will cause this session to terminate. When it has
finished, try launching again.
" "Would you like to install 'ghidragdb==$version'?"; then
echo "Copying Wheels to $OPT_HOST"
mitigate-scp-pymodules "Debug/Debugger-rmi-trace" "Debug/Debugger-agent-gdb"
echo "Installing Wheels into GDB's embedded Python"
do-installation
fi

View file

@ -1,53 +0,0 @@
::@timeout 60000
::@title gdb + gdbserver via ssh
::@image-opt env:OPT_TARGET_IMG
::@desc <html><body width="300px">
::@desc <h3>Launch with local <tt>gdb</tt> and <tt>gdbserver</tt> via <tt>ssh</tt></h3>
::@desc <p>
::@desc This will start <tt>gdb</tt> on the local system and then use it to connect and launch the target in <tt>gdbserver</tt> on the remote system via <tt>ssh</tt>.
::@desc For setup instructions, press <b>F1</b>.
::@desc </p>
::@desc </body></html>
::@menu-group remote
::@icon icon.debugger
::@help gdb#gdbserver_ssh
::@enum Endian:str auto big little
::@env OPT_TARGET_IMG: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_SSH_PATH:file="ssh" "ssh command" "The path to ssh on the local system. Omit the full path to resolve using the system PATH."
::@env OPT_HOST:str="localhost" "[User@]Host" "The hostname or user@host"
::@env OPT_EXTRA_SSH_ARGS:str="" "Extra ssh arguments" "Extra arguments to pass to ssh. Use with care."
::@env OPT_GDBSERVER_PATH:str="gdbserver" "gdbserver command (remote)" "The path to gdbserver on the remote system. Omit the full path to resolve using the system PATH."
::@env OPT_EXTRA_GDBSERVER_ARGS:str="" "Extra gdbserver arguments" "Extra arguments to pass to gdbserver. Use with care."
::@env OPT_GDB_PATH:file="gdb" "gdb command" "The path to gdb on the local system. Omit the full path to resolve using the system PATH."
::@env OPT_ARCH:str="auto" "Architecture" "Target architecture"
::@env OPT_ENDIAN:Endian="auto" "Endian" "Target byte order"
@echo off
set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-gdb\pypkg\src
set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\pypkg\src
IF EXIST %GHIDRA_HOME%\.git (
set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-gdb\build\pypkg\src
set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src
)
IF EXIST %GHIDRA_HOME%\ghidra\.git (
set PYTHONPATH0=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-agent-gdb\build\pypkg\src
set PYTHONPATH1=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src
)
set PYTHONPATH=%PYTHONPATH1%;%PYTHONPATH0%;%PYTHONPATH%
"%OPT_GDB_PATH%" ^
-q ^
-ex "set pagination off" ^
-ex "set confirm off" ^
-ex "show version" ^
-ex "python import ghidragdb" ^
-ex "set architecture %OPT_ARCH%" ^
ex "set endian %OPT_ENDIAN%" ^
-ex "target remote | '%OPT_SSH_PATH%' %OPT_EXTRA_SSH_ARGS% '%OPT_HOST%' '%OPT_GDBSERVER_PATH%' %OPT_EXTRA_GDBSERVER_ARGS% - '%OPT_TARGET_IMG%' %OPT_TARGET_ARGS%" ^
-ex "ghidra trace connect '%GHIDRA_TRACE_RMI_ADDR%'" ^
-ex "ghidra trace start" ^
-ex "ghidra trace sync-enable" ^
-ex "ghidra trace sync-synth-stopped" ^
-ex "set confirm on" ^
-ex "set pagination on"

View file

@ -0,0 +1,37 @@
#@timeout 60000
#@title gdb + gdbserver via ssh
#@image-opt arg:1
#@desc <html><body width="300px">
#@desc <h3>Launch with local <tt>gdb</tt> and <tt>gdbserver</tt> via <tt>ssh</tt></h3>
#@desc <p>
#@desc This will start <tt>gdb</tt> on the local system and then use it to connect and launch the target in <tt>gdbserver</tt> on the remote system via <tt>ssh</tt>.
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group gdb
#@icon icon.debugger
#@help gdb#gdbserver_ssh
#@enum Endian:str auto big little
#@arg :str! "Image" "The target binary executable image on the remote system"
#@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
#@env OPT_SSH_PATH:file="ssh" "ssh command" "The path to ssh on the local system. Omit the full path to resolve using the system PATH."
#@env OPT_HOST:str="localhost" "[User@]Host" "The hostname or user@host"
#@env OPT_EXTRA_SSH_ARGS:str="" "Extra ssh arguments" "Extra arguments to pass to ssh. Use with care."
#@env OPT_GDBSERVER_PATH:str="gdbserver" "gdbserver command (remote)" "The path to gdbserver on the remote system. Omit the full path to resolve using the system PATH."
#@env OPT_EXTRA_GDBSERVER_ARGS:str="" "Extra gdbserver arguments" "Extra arguments to pass to gdbserver. Use with care."
#@env OPT_GDB_PATH:file="gdb" "gdb command" "The path to gdb on the local system. Omit the full path to resolve using the system PATH."
#@env OPT_ARCH:str="auto" "Architecture" "Target architecture"
#@env OPT_ENDIAN:Endian="auto" "Endian" "Target byte order"
. ..\support\gdbsetuputils.ps1
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
$pypathGdb = Ghidra-Module-PyPath "Debug/Debugger-agent-gdb"
$Env:PYTHONPATH = "$pypathGdb;$pypathTrace;$Env:PYTHONPATH"
$arglist = Compute-Gdb-Remote-Args `
-TargetImage $args[0] `
-TargetCx "remote | '$Env:OPT_SSH_PATH' $Env:OPT_EXTRA_SSH_ARGS '$Env:OPT_HOST' '$Env:OPT_GDBSERVER_PATH' $Env:OPT_EXTRA_GDBSERVER_ARGS - '$($args[0])' $Env:OPT_TARGET_ARGS" `
-RmiAddress "$Env:GHIDRA_TRACE_RMI_ADDR"
Start-Process -FilePath $arglist[0] -ArgumentList $arglist[1..$arglist.Count] -NoNewWindow -Wait

View file

@ -24,7 +24,7 @@
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group remote
#@menu-group gdb
#@icon icon.debugger
#@help gdb#gdbserver_ssh
#@enum Endian:str auto big little
@ -39,31 +39,19 @@
#@env OPT_ARCH:str="auto" "Architecture" "Target architecture"
#@env OPT_ENDIAN:Endian="auto" "Endian" "Target byte order"
if [ -d ${GHIDRA_HOME}/ghidra/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
elif [ -d ${GHIDRA_HOME}/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
else
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-gdb/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/pypkg/src:$PYTHONPATH
fi
. ../support/gdbsetuputils.sh
"$OPT_GDB_PATH" \
-q \
-ex "set pagination off" \
-ex "set confirm off" \
-ex "show version" \
-ex "python import ghidragdb" \
-ex "set architecture $OPT_ARCH" \
-ex "set endian $OPT_ENDIAN" \
-ex "target remote | '$OPT_SSH_PATH' $OPT_EXTRA_SSH_ARGS '$OPT_HOST' '$OPT_GDBSERVER_PATH' $OPT_EXTRA_GDBSERVER_ARGS - $@" \
-ex "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \
-ex "ghidra trace start" \
-ex "ghidra trace sync-enable" \
-ex "ghidra trace sync-synth-stopped" \
-ex "set confirm on" \
-ex "set pagination on"
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
target_image="$1"
shift
function launch-gdb() {
local -a args
compute-gdb-remote-args "$target_image" "remote | '$OPT_SSH_PATH' $OPT_EXTRA_SSH_ARGS '$OPT_HOST' '$OPT_GDBSERVER_PATH' $OPT_EXTRA_GDBSERVER_ARGS - '$target_image' $@" "$GHIDRA_TRACE_RMI_ADDR"
"${args[@]}"
}
launch-gdb

View file

@ -14,7 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
#@title wine + gdb
#@title gdb + wine
#@image-opt arg:1
#@desc <html><body width="300px">
#@desc <h3>Launch with <tt>gdb</tt> and <tt>wine</tt></h3>
@ -23,7 +23,7 @@
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group cross
#@menu-group gdb
#@icon icon.debugger
#@help gdb#wine
#@enum Endian:str auto big little
@ -36,37 +36,20 @@
#@env OPT_EXTRA_TTY:bool=false "Inferior TTY" "Provide a separate terminal emulator for the target."
#@tty TTY_TARGET if env:OPT_EXTRA_TTY
if [ -d ${GHIDRA_HOME}/ghidra/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
elif [ -d ${GHIDRA_HOME}/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
else
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-gdb/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/pypkg/src:$PYTHONPATH
fi
# NOTE: Ghidra will leave TTY_TARGET empty, which gdb takes for the same terminal.
. ../support/gdbsetuputils.sh
"$OPT_GDB_PATH" \
-q \
-ex "set pagination off" \
-ex "set confirm off" \
-ex "show version" \
-ex "python import ghidragdb.wine" \
-ex "set architecture $OPT_ARCH" \
-ex "set endian $OPT_ENDIAN" \
-ex "file \"$OPT_WINE_PATH\"" \
-ex "set args $@" \
-ex "set inferior-tty $TTY_TARGET" \
-ex "starti" \
-ex "ghidra wine run-to-image \"$1\"" \
-ex "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \
-ex "ghidra trace start \"$1\"" \
-ex "ghidra trace sync-enable" \
-ex "ghidra trace sync-synth-stopped" \
-ex "set confirm on" \
-ex "set pagination on"
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
pypathGdb=$(ghidra-module-pypath "Debug/Debugger-agent-gdb")
export PYTHONPATH=$pypathGdb:$pypathTrace:$PYTHONPATH
target_image="$1"
shift
function launch-gdb() {
local -a args
compute-gdb-wine-args "$target_image" "$GHIDRA_TRACE_RMI_ADDR" "$@"
"${args[@]}"
}
launch-gdb

View file

@ -0,0 +1,92 @@
. ..\..\..\Debugger-rmi-trace\data\support\setuputils.ps1
function Add-Gdb-Init-Args {
param([ref]$ArgList)
$ArgList.Value+=("-q")
$ArgList.Value+=("-ex", "`"set pagination off`"")
$ArgList.Value+=("-ex", "`"set confirm off`"")
$ArgList.Value+=("-ex", "`"show version`"")
$ArgList.Value+=("-ex", "`"python import ghidragdb`"")
$ArgList.Value+=("-ex", "`"python if not 'ghidragdb' in locals(): exit(253)`"")
$ArgList.Value+=("-ex", "`"set architecture $Env:OPT_ARCH`"")
$ArgList.Value+=("-ex", "`"set endian $Env:OPT_ENDIAN`"")
}
function Add-Gdb-Image-And-Args {
param([ref]$ArgList, $TargetImage, $TargetArgs)
if ("$TargetImage" -ne "") {
$image = $TargetImage -replace "\\", "\\\\"
$ArgList.Value+=("-ex", "`"file '$image'`"")
}
if ("$TargetArgs" -ne "") {
$tgtargs = $TargetArgs -replace "`"", "\`""
# Escaping parentheses in the arguments is no longer necessary in powershell vs cmd
$ArgList.Value+=("-ex", "`"set args $tgtargs`"")
}
}
function Add-Gdb-Connect-And-Sync {
param([ref]$ArgList, $Address)
$ArgList.Value+=("-ex", "`"ghidra trace connect '$Address'`"")
$ArgList.Value+=("-ex", "`"ghidra trace start`"")
$ArgList.Value+=("-ex", "`"ghidra trace sync-enable`"")
}
function Add-Gdb-Start-If-Image {
param([ref]$ArgList, $TargetImage)
if ("$TargetImage" -ne "") {
$ArgList.Value+=("-ex", "`"$Env:OPT_START_CMD`"")
}
}
function Add-Gdb-Tail-Args {
param([ref]$ArgList)
$ArgList.Value+=("-ex", "`"set confirm on`"")
$ArgList.Value+=("-ex", "`"set pagination on`"")
}
function Compute-Gdb-Usermode-Args {
param($TargetImage, $RmiAddress)
$arglist = @("`"$Env:OPT_GDB_PATH`"")
Add-Gdb-Init-Args -ArgList ([ref]$arglist)
Add-Gdb-Image-And-Args -ArgList ([ref]$arglist) -TargetImage $TargetImage -TargetArgs $Env:OPT_TARGET_ARGS
Add-Gdb-Connect-And-Sync -ArgList ([ref]$arglist) -Address $RmiAddress
Add-Gdb-Start-If-Image -ArgList ([ref]$arglist) -TargetImage $TargetImage
Add-Gdb-Tail-Args -ArgList ([ref]$arglist)
return $arglist
}
function Compute-Gdb-Remote-Args {
param($TargetImage, $TargetCx, $RmiAddress)
$arglist = @("`"$Env:OPT_GDB_PATH`"")
Add-Gdb-Init-Args -ArgList ([ref]$arglist)
Add-Gdb-Image-And-Args -ArgList ([ref]$arglist) -TargetImge $TargetImage -TargetArgs ""
$arglist+=("-ex", "`"echo Connecting to $TargetCx\n`"")
$arglist+=("-ex", "`"target $TargetCx`"")
Add-Gdb-Connect-And-Sync -ArgList ([ref]$arglist) -Address $RmiAddress
$arglist+=("-ex", "`"ghidra trace sync-synth-stopped`"")
Add-Gdb-Tail-Args -ArgList ([ref]$arglist)
return $arglist
}
function Compute-Gdb-PipInstall-Args {
$argvpart = $args -join ", "
$arglist = @("`"$Env:OPT_GDB_PATH`"")
$arglist+=("-ex", "`"set pagination off`"")
$arglist+=("-ex", "`"python import os, sys, runpy`"")
$arglist+=("-ex", "`"python sys.argv=['pip', 'install', '--force-reinstall', $argvpart]`"")
$arglist+=("-ex", "`"python os.environ['PIP_BREAK_SYSTEM_PACKAGE']='1'`"")
$arglist+=("-ex", "`"python runpy.run_module('pip', run_name='__main__')`"")
return $arglist
}

View file

@ -0,0 +1,125 @@
## ###
# 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.
##
. ../../../Debugger-rmi-trace/data/support/setuputils.sh
add-gdb-init-args() {
args+=(-q)
args+=(-ex "set pagination off")
args+=(-ex "set confirm off")
args+=(-ex "show version")
args+=(-ex "python import ghidragdb")
args+=(-ex "python if not 'ghidragdb' in locals(): exit(253)")
args+=(-ex "set architecture $OPT_ARCH")
args+=(-ex "set endian $OPT_ENDIAN")
}
add-gdb-image-and-args() {
target_image=$1
target_args=$2
if [ -n "$target_image" ]; then
args+=(-ex "file '$target_image'")
fi
if [ -n "$target_args" ]; then
args+=(-ex "set args $target_args")
fi
}
add-gdb-inferior-tty() {
# Ghidra will leave TTY_TARGET empty when OPT_EXTRA_TTY is false.
# Gdb takes empty to mean the same terminal.
args+=(-ex "set inferior-tty $TTY_TARGET")
}
add-gdb-connect-and-sync() {
address=$1
args+=(-ex "ghidra trace connect '$address'")
args+=(-ex "ghidra trace start")
args+=(-ex "ghidra trace sync-enable")
}
add-gdb-start-if-image() {
target_image=$1
if [ -n "$target_image" ]; then
args+=(-ex "$OPT_START_CMD")
fi
}
add-gdb-tail-args() {
args+=(-ex "set confirm on")
args+=(-ex "set pagination on")
}
compute-gdb-usermode-args() {
target_image=$1
rmi_address=$2
shift
shift
args+=("$OPT_GDB_PATH")
add-gdb-init-args
add-gdb-image-and-args "$target_image" "$@"
add-gdb-inferior-tty
add-gdb-connect-and-sync "$rmi_address"
add-gdb-start-if-image "$target_image"
add-gdb-tail-args
}
compute-gdb-wine-args() {
target_image=$1
rmi_address=$2
shift
shift
args+=("$OPT_GDB_PATH")
add-gdb-init-args
add-gdb-image-and-args "$OPT_WINE_PATH" "$target_image" "$@"
add-gdb-inferior-tty
gdb+=(-ex "starti")
gdb+=(-ex "ghidra wine run-to-image '$target_image'")
add-gdb-connect-and-sync "$rmi_address"
gdb+=(-ex "ghidra trace sync-synth-stopped")
add-gdb-tail-args
}
compute-gdb-remote-args() {
target_image=$1
target_cx=$2
rmi_address=$3
args+=("$OPT_GDB_PATH")
add-gdb-init-args
add-gdb-image-and-args "$target_image" ""
args+=(-ex "echo Connecting to $target_cx\n")
args+=(-ex "target $target_cx")
add-gdb-connect-and-sync "$rmi_address"
args+=(-ex "ghidra trace sync-synth-stopped")
add-gdb-tail-args
}
compute-gdb-pipinstall-args() {
local argvpart
printf -v argvpart ", %s" "$@"
pipargs=("$OPT_GDB_PATH")
pipargs+=(-q)
pipargs+=(-ex "set pagination off")
pipargs+=(-ex "python import os, sys, runpy")
pipargs+=(-ex "python sys.argv=['pip', 'install', '--force-reinstall'$argvpart]")
pipargs+=(-ex "python os.environ['PIP_BREAK_SYSTEM_PACKAGE']='1'")
pipargs+=(-ex "python runpy.run_module('pip', run_name='__main__')")
}

View file

@ -4,11 +4,12 @@
Module.manifest||GHIDRA||||END|
README.md||GHIDRA||||END|
build.gradle||GHIDRA||||END|
data/debugger-launchers/android-lldb.bat||GHIDRA||||END|
data/debugger-launchers/kernel-lldb.bat||GHIDRA||||END|
data/debugger-launchers/local-lldb.bat||GHIDRA||||END|
data/debugger-launchers/android-lldb.ps1||GHIDRA||||END|
data/debugger-launchers/kernel-lldb.ps1||GHIDRA||||END|
data/debugger-launchers/local-lldb.ps1||GHIDRA||||END|
data/debugger-launchers/remote-lldb.ps1||GHIDRA||||END|
data/debugger-launchers/ssh-lldb.bat||GHIDRA||||END|
data/debugger-launchers/ssh-lldb.ps1||GHIDRA||||END|
data/support/lldbsetuputils.ps1||GHIDRA||||END|
src/main/help/help/TOC_Source.xml||GHIDRA||||END|
src/main/help/help/topics/lldb/lldb.html||GHIDRA||||END|
src/main/py/LICENSE||GHIDRA||||END|

View file

@ -1,95 +0,0 @@
::@title android lldb
::@desc <html><body width="300px">
::@desc <h3>Launch with local <tt>lldb</tt> and connect to a stub (e.g., <tt>gdbserver</tt>)</h3>
::@desc <p>
::@desc This will start <tt>lldb</tt> on the local system and then use it to connect to the remote system.
::@desc For setup instructions, press <b>F1</b>.
::@desc </p>
::@desc </body></html>
::@menu-group remote
::@icon icon.debugger
::@help lldb#android
::@enum StartCmd:str "process launch" "process launch --stop-at-entry"
::@env OPT_TARGET_IMG:file="" "Image" "The target binary executable image"
::@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
::@env OPT_HOST:str="localhost" "Host" "The hostname of the target"
::@env OPT_PORT:str="9999" "Port" "The host's listening port"
::@env OPT_ARCH:str="" "Architecture" "Target architecture override"
::@env OPT_LLDB_PATH:file="lldb" "lldb command" "The path to lldb on the local system. Omit the full path to resolve using the system PATH."
::@env OPT_START_CMD:StartCmd="process launch" "Run command" "The lldb command to actually run the target."
@echo off
set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-lldb\pypkg\src
set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\pypkg\src
IF EXIST %GHIDRA_HOME%\.git (
set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-lldb\build\pypkg\src
set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src
)
IF EXIST %GHIDRA_HOME%\ghidra\.git (
set PYTHONPATH0=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-agent-lldb\build\pypkg\src
set PYTHONPATH1=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src
)
set PYTHONPATH=%PYTHONPATH1%;%PYTHONPATH0%;%PYTHONPATH%
:: NB: This works - a lot of things do not. Don't change unless you know what you're doing!
set OPT_TARGET_IMG="%OPT_TARGET_IMG%"
set OPT_TARGET_ARGS="%OPT_TARGET_ARGS%"
IF %OPT_ARCH%=="" (
IF "%OPT_TARGET_ARGS%"=="" (
"%OPT_LLDB_PATH%" ^
-o "version" ^
-o "script import ghidralldb" ^
-o "platform select remote-android" ^
-o "platform connect connect://%OPT_HOST%:%OPT_PORT%" ^
-o "target create "%OPT_TARGET_IMG%"" ^
-o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^
-o "ghidra trace start" ^
-o "ghidra trace sync-enable" ^
-o "ghidra trace sync-synth-stopped" ^
-o "%OPT_START_CMD%"
) ELSE (
"%OPT_LLDB_PATH%" ^
-o "version" ^
-o "script import ghidralldb" ^
-o "platform select remote-android" ^
-o "platform connect connect://%OPT_HOST%:%OPT_PORT%" ^
-o "settings set target.default-arch %OPT_ARCH%"
-o "target create "%OPT_TARGET_IMG%"" ^
-o "settings set target.run-args %OPT_TARGET_ARGS%" ^
-o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^
-o "ghidra trace start" ^
-o "ghidra trace sync-enable" ^
-o "ghidra trace sync-synth-stopped" ^
-o "%OPT_START_CMD%"
)
) ELSE (
if %OPT_TARGET_ARGS=="" (
"%OPT_LLDB_PATH%" ^
-o "version" ^
-o "script import ghidralldb" ^
-o "platform select remote-android" ^
-o "platform connect connect://%OPT_HOST%:%OPT_PORT%" ^
-o "settings set target.default-arch %OPT_ARCH%"
-o "target create "%OPT_TARGET_IMG%"" ^
-o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^
-o "ghidra trace start" ^
-o "ghidra trace sync-enable" ^
-o "ghidra trace sync-synth-stopped" ^
-o "%OPT_START_CMD%"
) ELSE (
"%OPT_LLDB_PATH%" ^
-o "version" ^
-o "script import ghidralldb" ^
-o "platform select remote-android" ^
-o "platform connect connect://%OPT_HOST%:%OPT_PORT%" ^
-o "settings set target.default-arch %OPT_ARCH%"
-o "target create "%OPT_TARGET_IMG%"" ^
-o "settings set target.run-args %OPT_TARGET_ARGS%" ^
-o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^
-o "ghidra trace start" ^
-o "ghidra trace sync-enable" ^
-o "ghidra trace sync-synth-stopped" ^
-o "%OPT_START_CMD%"
)
)

View file

@ -0,0 +1,34 @@
#@title lldb Android
#@image-opt arg:1
#@desc <html><body width="300px">
#@desc <h3>Launch with local <tt>lldb</tt> and connect to a stub (e.g., <tt>gdbserver</tt>)</h3>
#@desc <p>
#@desc This will start <tt>lldb</tt> on the local system and then use it to connect to the remote system.
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group lldb
#@icon icon.debugger
#@help lldb#android
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
#@arg :file "Image" "The target binary executable image"
#@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
#@env OPT_HOST:str="localhost" "Host" "The hostname of the target"
#@env OPT_PORT:str="9999" "Port" "The host's listening port"
#@env OPT_ARCH:str="" "Architecture" "Target architecture override"
#@env OPT_LLDB_PATH:file="lldb" "lldb command" "The path to lldb on the local system. Omit the full path to resolve using the system PATH."
#@env OPT_START_CMD:StartCmd="process launch" "Run command" "The lldb command to actually run the target."
. ..\support\lldbsetuputils.ps1
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
$pypathLldb = Ghidra-Module-PyPath "Debug/Debugger-agent-lldb"
$Env:PYTHONPATH = "$pypathLldb;$pypathTrace;$Env:PYTHONPATH"
$arglist = Compute-Lldb-Platform-Args `
-TargetImage $args[0] `
-TargetType "remote-android" `
-TargetUrl "connect://$Env:OPT_HOST`:$Env:OPT_PORT" `
-RmiAddress "$Env:GHIDRA_TRACE_RMI_ADDR"
Start-Process -FilePath $arglist[0] -ArgumentList $arglist[1..$arglist.Count] -NoNewWindow -Wait

View file

@ -14,16 +14,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
#@title android lldb
#@title lldb Android
#@image-opt arg:1
#@desc <html><body width="300px">
#@desc <h3>Launch with local <tt>lldb</tt> and connect to a stub (e.g., <tt>gdbserver</tt>)</h3>
#@desc <h3>Launch with local <tt>lldb</tt> and connect to an Android target.</h3>
#@desc <p>
#@desc This will start <tt>lldb</tt> on the local system and then use it to connect to the remote system.
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group remote
#@menu-group lldb
#@icon icon.debugger
#@help lldb#android
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
@ -35,48 +35,20 @@
#@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_START_CMD:StartCmd="process launch" "Run command" "The lldb command to actually run the target."
if [ -d ${GHIDRA_HOME}/ghidra/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-agent-lldb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
elif [ -d ${GHIDRA_HOME}/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-lldb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
else
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-lldb/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/pypkg/src:$PYTHONPATH
fi
. ../support/lldbsetuputils.sh
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
pypathLldb=$(ghidra-module-pypath "Debug/Debugger-agent-lldb")
export PYTHONPATH=$pypathLldb:$pypathTrace:$PYTHONPATH
target_image="$1"
shift
target_args="$@"
if [ -z "$target_args" ]
then
argspart=
else
argspart=("-o" "settings set target.run-args $target_args")
fi
if [ -z "$OPT_ARCH" ]
then
archcmd=
else
archcmd=("-o" "settings set target.default-arch $OPT_ARCH")
fi
"$OPT_LLDB_PATH" \
-o "version" \
-o "script import ghidralldb" \
-o "platform select remote-android" \
-o "platform connect connect://$OPT_HOST:$OPT_PORT" \
"${archcmd[@]}" \
-o "target create \"$target_image\"" \
"${argspart[@]}" \
-o "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \
-o "ghidra trace start" \
-o "ghidra trace sync-enable" \
-o "ghidra trace sync-synth-stopped" \
-o "$OPT_START_CMD"
function launch-lldb() {
local -a args
compute-lldb-platform-args "$target_image" remote-android "connect://$OPT_HOST:$OPT_PORT" "$GHIDRA_TRACE_RMI_ADDR" "$@"
"${args[@]}"
}
launch-lldb

View file

@ -1,48 +0,0 @@
::@title kernel lldb
::@desc <html><body width="300px">
::@desc <h3>Launch with local <tt>lldb</tt> and connect to a remote kernel</h3>
::@desc <p>
::@desc This will start <tt>lldb</tt> on the local system and then use it to connect to the remote system.
::@desc For setup instructions, press <b>F1</b>.
::@desc </p>
::@desc </body></html>
::@menu-group remote
::@icon icon.debugger
::@help lldb#macos_kernel
::@env OPT_HOST:str="localhost" "Host" "The hostname of the target"
::@env OPT_ARCH:str="" "Architecture" "Target architecture override"
::@env OPT_LLDB_PATH:file="lldb" "lldb command" "The path to lldb on the local system. Omit the full path to resolve using the system PATH."
@echo off
set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-lldb\pypkg\src
set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\pypkg\src
IF EXIST %GHIDRA_HOME%\.git (
set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-lldb\build\pypkg\src
set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src
)
IF EXIST %GHIDRA_HOME%\ghidra\.git (
set PYTHONPATH0=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-agent-lldb\build\pypkg\src
set PYTHONPATH1=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src
)
set PYTHONPATH=%PYTHONPATH1%;%PYTHONPATH0%;%PYTHONPATH%
IF "%OPT_ARCH%"=="" (
"%OPT_LLDB_PATH%" ^
-o "version" ^
-o "script import ghidralldb" ^
-o "kdp-remote %OPT_HOST%" ^
-o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^
-o "ghidra trace start" ^
-o "ghidra trace sync-enable" ^
-o "ghidra trace sync-synth-stopped"
) ELSE (
"%OPT_LLDB_PATH%" ^
-o "version" ^
-o "script import ghidralldb" ^
-o "settings set target.default-arch %OPT_ARCH%"
-o "kdp-remote %OPT_HOST%" ^
-o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^
-o "ghidra trace start" ^
-o "ghidra trace sync-enable" ^
-o "ghidra trace sync-synth-stopped"
)

View file

@ -0,0 +1,27 @@
#@title lldb kernel (kdp)
#@desc <html><body width="300px">
#@desc <h3>Launch with local <tt>lldb</tt> and connect to a remote kernel</h3>
#@desc <p>
#@desc This will start <tt>lldb</tt> on the local system and then use it to connect to the remote system.
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group lldb
#@icon icon.debugger
#@help lldb#macos_kernel
#@env OPT_HOST:str="localhost" "Host" "The hostname of the target"
#@env OPT_ARCH:str="" "Architecture" "Target architecture override"
#@env OPT_LLDB_PATH:file="lldb" "lldb command" "The path to lldb on the local system. Omit the full path to resolve using the system PATH."
. ..\support\lldbsetuputils.ps1
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
$pypathLldb = Ghidra-Module-PyPath "Debug/Debugger-agent-lldb"
$Env:PYTHONPATH = "$pypathLldb;$pypathTrace;$Env:PYTHONPATH"
$arglist = Compute-Lldb-Remote-Args `
-TargetImage $args[0] `
-TargetCx "kdp-remote $Env:OPT_HOST" `
-RmiAddress "$Env:GHIDRA_TRACE_RMI_ADDR"
Start-Process -FilePath $arglist[0] -ArgumentList $arglist[1..$arglist.Count] -NoNewWindow -Wait

View file

@ -14,7 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
#@title kernel lldb
#@title lldb kernel (kdp)
#@desc <html><body width="300px">
#@desc <h3>Launch with local <tt>lldb</tt> and connect to a remote kernel</h3>
#@desc <p>
@ -22,39 +22,23 @@
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group remote
#@menu-group lldb
#@icon icon.debugger
#@help lldb#macos_kernel
#@env OPT_HOST:str="localhost" "Host" "The hostname of the target"
#@env OPT_ARCH:str="" "Architecture" "Target architecture override"
#@env OPT_LLDB_PATH:file="lldb" "lldb command" "The path to lldb on the local system. Omit the full path to resolve using the system PATH."
if [ -d ${GHIDRA_HOME}/ghidra/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-agent-lldb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
elif [ -d ${GHIDRA_HOME}/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-lldb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
else
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-lldb/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/pypkg/src:$PYTHONPATH
fi
. ../support/lldbsetuputils.sh
if [ -z "$OPT_ARCH" ]
then
archcmd=
else
archcmd=("-o" "settings set target.default-arch $OPT_ARCH")
fi
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
pypathLldb=$(ghidra-module-pypath "Debug/Debugger-agent-lldb")
export PYTHONPATH=$pypathLldb:$pypathTrace:$PYTHONPATH
"$OPT_LLDB_PATH" \
-o "version" \
-o "script import ghidralldb" \
"${archcmd[@]}" \
-o "kdp-remote $OPT_HOST" \
-o "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \
-o "ghidra trace start" \
-o "ghidra trace sync-enable" \
-o "ghidra trace sync-synth-stopped"
function launch-lldb() {
local -a args
compute-lldb-remote-args "" "kdp-remote $OPT_HOST" "$GHIDRA_TRACE_RMI_ADDR"
"${args[@]}"
}
launch-lldb

View file

@ -1,64 +0,0 @@
::@title lldb
::@image-opt env:OPT_TARGET_IMG
::@desc <html><body width="300px">
::@desc <h3>Launch with <tt>lldb</tt></h3>
::@desc <p>
::@desc This will launch the target on the local machine using <tt>lldb</tt>.
::@desc For setup instructions, press <b>F1</b>.
::@desc </p>
::@desc </body></html>
::@menu-group local
::@icon icon.debugger
::@help lldb#local
::@enum StartCmd:str "process launch" "process launch --stop-at-entry"
::@env OPT_TARGET_IMG:file="" "Image" "The target binary executable image"
::@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
::@env OPT_LLDB_PATH:file="lldb" "lldb command" "The path to lldb. Omit the full path to resolve using the system PATH."
::@env OPT_START_CMD:StartCmd="process launch" "Run command" "The lldb command to actually run the target."
@echo off
set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-lldb\pypkg\src
set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\pypkg\src
IF EXIST %GHIDRA_HOME%\.git (
set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-lldb\build\pypkg\src
set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src
)
IF EXIST %GHIDRA_HOME%\ghidra\.git (
set PYTHONPATH0=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-agent-lldb\build\pypkg\src
set PYTHONPATH1=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src
)
set PYTHONPATH=%PYTHONPATH1%;%PYTHONPATH0%;%PYTHONPATH%
:: NB: This works - a lot of things do not. Don't change unless you know what you're doing!
set OPT_TARGET_IMG="%OPT_TARGET_IMG%"
set OPT_TARGET_ARGS="%OPT_TARGET_ARGS%"
IF %OPT_TARGET_IMG%=="" (
"%OPT_LLDB_PATH%" ^
-o "version" ^
-o "script import ghidralldb" ^
-o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^
-o "ghidra trace start" ^
-o "ghidra trace sync-enable"
) ELSE (
IF "%OPT_TARGET_ARGS%"=="" (
"%OPT_LLDB_PATH%" ^
-o "version" ^
-o "script import ghidralldb" ^
-o "target create "%OPT_TARGET_IMG%"" ^
-o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^
-o "ghidra trace start" ^
-o "ghidra trace sync-enable" ^
-o "%OPT_START_CMD%"
) ELSE (
"%OPT_LLDB_PATH%" ^
-o "version" ^
-o "script import ghidralldb" ^
-o "target create "%OPT_TARGET_IMG%"" ^
-o "settings set target.run-args %OPT_TARGET_ARGS%" ^
-o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^
-o "ghidra trace start" ^
-o "ghidra trace sync-enable" ^
-o "%OPT_START_CMD%"
)
)

View file

@ -0,0 +1,30 @@
#@title lldb
#@image-opt arg:1
#@desc <html><body width="300px">
#@desc <h3>Launch with <tt>lldb</tt></h3>
#@desc <p>
#@desc This will launch the target on the local machine using <tt>lldb</tt>.
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group lldb
#@icon icon.debugger
#@help lldb#local
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
#@arg :file "Image" "The target binary executable image"
#@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
#@env OPT_LLDB_PATH:file="lldb" "lldb command" "The path to lldb. Omit the full path to resolve using the system PATH."
#@env OPT_START_CMD:StartCmd="process launch" "Run command" "The lldb command to actually run the target."
. ..\support\lldbsetuputils.ps1
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
$pypathLldb = Ghidra-Module-PyPath "Debug/Debugger-agent-lldb"
$Env:PYTHONPATH = "$pypathLldb;$pypathTrace;$Env:PYTHONPATH"
$arglist = Compute-Lldb-Usermode-Args `
-TargetImage $args[0] `
-RmiAddress "$Env:GHIDRA_TRACE_RMI_ADDR"
Start-Process -FilePath $arglist[0] -ArgumentList $arglist[1..$arglist.Count] `
-NoNewWindow -Wait

View file

@ -23,7 +23,7 @@
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group local
#@menu-group lldb
#@icon icon.debugger
#@help lldb#local
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
@ -34,55 +34,19 @@
#@env OPT_EXTRA_TTY:bool=false "Target TTY" "Provide a separate terminal emulator for the target."
#@tty TTY_TARGET if env:OPT_EXTRA_TTY
if [ -d ${GHIDRA_HOME}/ghidra/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-agent-lldb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
elif [ -d ${GHIDRA_HOME}/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-lldb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
else
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-lldb/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/pypkg/src:$PYTHONPATH
fi
. ../support/lldbsetuputils.sh
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
pypathLldb=$(ghidra-module-pypath "Debug/Debugger-agent-lldb")
export PYTHONPATH=$pypathLldb:$pypathTrace:$PYTHONPATH
target_image="$1"
shift
target_args="$@"
if [ -z "$target_args" ]
then
argspart=
else
argspart=("-o" "settings set target.run-args $target_args")
fi
function launch-lldb() {
local -a args
compute-lldb-usermode-args "$target_image" "$GHIDRA_TRACE_RMI_ADDR" "$@"
if [ -z "$TARGET_TTY" ]
then
ttypart=
else
ttypart=("-o" "settings set target.output-path $TTY_TARGET" "-o" "settings set target.input-path $TTY_TARGET")
fi
if [ -z "$target_image" ]
then
"$OPT_LLDB_PATH" \
-o "version" \
-o "script import ghidralldb" \
"${ttypart[@]}" \
-o "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \
-o "ghidra trace start" \
-o "ghidra trace sync-enable"
else
"$OPT_LLDB_PATH" \
-o "version" \
-o "script import ghidralldb" \
-o "target create \"$target_image\"" \
"${argspart[@]}" \
"${ttypart[@]}" \
-o "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \
-o "ghidra trace start" \
-o "ghidra trace sync-enable" \
-o "$OPT_START_CMD"
fi
"${args[@]}"
}
launch-lldb

View file

@ -1,4 +1,4 @@
#@title remote lldb
#@title lldb remote (gdb)
#@image-opt arg:1
#@desc <html><body width="300px">
#@desc <h3>Launch with local <tt>lldb</tt> and connect to a stub (e.g., <tt>gdbserver</tt>)</h3>
@ -7,7 +7,7 @@
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group remote
#@menu-group lldb
#@icon icon.debugger
#@help lldb#remote
#@arg :file "Image" "The target binary executable image (a copy on the local system)"
@ -16,37 +16,15 @@
#@env OPT_ARCH:str="" "Architecture" "Target architecture override"
#@env OPT_LLDB_PATH:file="lldb" "lldb command" "The path to lldb on the local system. Omit the full path to resolve using the system PATH."
[IO.DirectoryInfo] $repo = "$Env:GHIDRA_HOME\.git"
[IO.DirectoryInfo] $repoParent = "$Env:GHIDRA_HOME\ghidra\.git"
if ($repo.Exists) {
$pypathLldb = "$Env:GHIDRA_HOME\Ghidra\Debug\Debugger-agent-lldb\build\pypkg\src"
$pypathTrace = "$Env:GHIDRA_HOME\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src"
}
elseif ($repoParent.Exists) {
$pypathLldb = "$Env:GHIDRA_HOME\ghidra\Ghidra\Debug\Debugger-agent-lldb\build\pypkg\src"
$pypathTrace = "$Env:GHIDRA_HOME\ghidra\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src"
}
else {
$pypathLldb = "$Env:GHIDRA_HOME\Ghidra\Debug\Debugger-agent-lldb\pypkg\src"
$pypathTrace = "$Env:GHIDRA_HOME\Ghidra\Debug\Debugger-rmi-trace\pypkg\src"
}
. ..\support\lldbsetuputils.ps1
$pypathTrace = Ghidra-Module-PyPath "Debug/Debugger-rmi-trace"
$pypathLldb = Ghidra-Module-PyPath "Debug/Debugger-agent-lldb"
$Env:PYTHONPATH = "$pypathLldb;$pypathTrace;$Env:PYTHONPATH"
$arglist = @()
$arglist = Compute-Lldb-Remote-Args `
-TargetImage $args[0] `
-TargetCx "gdb-remote $Env:OPT_HOST`:$Env:OPT_PORT" `
-RmiAddress "$Env:GHIDRA_TRACE_RMI_ADDR"
$arglist+=("-o", "`"version`"")
$arglist+=("-o", "`"script import ghidralldb`"")
if ("$Env:OPT_ARCH" -ne "") {
$arglist+=("-o", "`"settings set target.default-arch $Env:OPT_ARCH`"")
}
if ("$($args[0])" -ne "") {
$image = $args[0]
$arglist+=("-o", "`"file '$image'`"")
}
$arglist+=("-o", "`"gdb-remote $Env:OPT_HOST`:$Env:OPT_PORT`"")
$arglist+=("-o", "`"ghidra trace connect '$Env:GHIDRA_TRACE_RMI_ADDR'`"")
$arglist+=("-o", "`"ghidra trace start`"")
$arglist+=("-o", "`"ghidra trace sync-enable`"")
$arglist+=("-o", "`"ghidra trace sync-synth-stopped`"")
Start-Process -FilePath $Env:OPT_LLDB_PATH -ArgumentList $arglist -NoNewWindow -Wait
Start-Process -FilePath $arglist[0] -ArgumentList $arglist[1..$arglist.Count] -NoNewWindow -Wait

View file

@ -14,7 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
#@title remote lldb
#@title lldb remote (gdb)
#@image-opt arg:1
#@desc <html><body width="300px">
#@desc <h3>Launch with local <tt>lldb</tt> and connect to a stub (e.g., <tt>gdbserver</tt>)</h3>
@ -23,7 +23,7 @@
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group remote
#@menu-group lldb
#@icon icon.debugger
#@help lldb#remote
#@arg :file "Image" "The target binary executable image (a copy on the local system)"
@ -32,35 +32,18 @@
#@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."
if [ -d ${GHIDRA_HOME}/ghidra/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-agent-lldb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
elif [ -d ${GHIDRA_HOME}/.git ]
then
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-lldb/build/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH
else
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-lldb/pypkg/src:$PYTHONPATH
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/pypkg/src:$PYTHONPATH
fi
. ../support/lldbsetuputils.sh
declare -a args
pypathTrace=$(ghidra-module-pypath "Debug/Debugger-rmi-trace")
pypathLldb=$(ghidra-module-pypath "Debug/Debugger-agent-lldb")
export PYTHONPATH=$pypathLldb:$pypathTrace:$PYTHONPATH
args+=(-o version)
args+=(-o "script import ghidralldb")
if [ -n "$OPT_ARCH" ]
then
args+=(-o "settings set target.default-arch $OPT_ARCH")
fi
if [ -n "$1" ]
then
args+=(-o "file '$1'")
fi
args+=(-o "gdb-remote $OPT_HOST:$OPT_PORT")
args+=(-o "ghidra trace connect '$GHIDRA_TRACE_RMI_ADDR'")
args+=(-o "ghidra trace start")
args+=(-o "ghidra trace sync-enable")
args+=(-o "ghidra trace sync-synth-stopped")
target_image="$1"
"$OPT_LLDB_PATH" "${args[@]}"
function launch-lldb() {
local -a args
compute-lldb-remote-args "$target_image" "gdb-remote $OPT_HOST:$OPT_PORT" "$GHIDRA_TRACE_RMI_ADDR"
"${args[@]}"
}
launch-lldb

View file

@ -1,51 +0,0 @@
::@timeout 60000
::@title lldb via ssh
::@image-opt env:OPT_TARGET_IMG
::@desc <html><body width="300px">
::@desc <h3>Launch with <tt>lldb</tt> via <tt>ssh</tt></h3>
::@desc <p>
::@desc This will launch the target on a remote machine using <tt>lldb</tt> via <tt>ssh</tt>.
::@desc For setup instructions, press <b>F1</b>.
::@desc </p>
::@desc </body></html>
::@menu-group remote
::@icon icon.debugger
::@help lldb#ssh
::@enum StartCmd:str "process launch" "process launch --stop-at-entry"
::@enum Endian:str auto big little
::@env OPT_TARGET_IMG: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_SSH_PATH:file!="ssh" "ssh command" "The path to ssh on the local system. Omit the full path to resolve using the system PATH."
::@env OPT_HOST:str="localhost" "[User@]Host" "The hostname or user@host"
::@env OPT_REMOTE_PORT:int=12345 "Remote Trace RMI Port" "A free port on the remote end to receive and forward the Trace RMI connection."
::@env OPT_EXTRA_SSH_ARGS:str="" "Extra ssh arguments" "Extra arguments to pass to ssh. Use with care."
::@env OPT_LLDB_PATH:str="lldb" "lldb command" "The path to lldb on the remote system. Omit the full path to resolve using the system PATH."
::@env OPT_START_CMD:StartCmd="process launch" "Run command" "The lldb command to actually run the target."
::@env OPT_ARCH:str="x86_64" "Architecture" "Target architecture"
@echo off
IF "%OPT_TARGET_ARGS%" == "" (
set cmd=TERM='%TERM%' '%OPT_LLDB_PATH%' ^
-o 'version' ^
-o 'script import ghidralldb' ^
-o 'settings set target.default-arch %OPT_ARCH%' ^
-o 'ghidra trace connect \"localhost:%OPT_REMOTE_PORT%\"' ^
-o 'target create \"%OPT_TARGET_IMG%\"' ^
-o 'ghidra trace start' ^
-o 'ghidra trace sync-enable' ^
-o '%OPT_START_CMD%'
) ELSE (
set cmd=TERM='%TERM%' '%OPT_LLDB_PATH%' ^
-o 'version' ^
-o 'script import ghidralldb' ^
-o 'settings set target.default-arch %OPT_ARCH%' ^
-o 'ghidra trace connect \"localhost:%OPT_REMOTE_PORT%\"' ^
-o 'target create \"%OPT_TARGET_IMG%\"' ^
-o 'settings set target.run-args %OPT_TARGET_ARGS%' ^
-o 'ghidra trace start' ^
-o 'ghidra trace sync-enable' ^
-o '%OPT_START_CMD%'
)
"%OPT_SSH_PATH%" "-R%OPT_REMOTE_PORT%:%GHIDRA_TRACE_RMI_ADDR%" -t %OPT_EXTRA_SSH_ARGS% "%OPT_HOST%" "%cmd%"

View file

@ -0,0 +1,69 @@
#@timeout 60000
#@title lldb via ssh
#@image-opt arg:1
#@desc <html><body width="300px">
#@desc <h3>Launch with <tt>lldb</tt> via <tt>ssh</tt></h3>
#@desc <p>
#@desc This will launch the target on a remote machine using <tt>lldb</tt> via <tt>ssh</tt>.
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group lldb
#@icon icon.debugger
#@help lldb#ssh
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
#@enum Endian:str auto big little
#@arg :str "Image" "The target binary executable image on the remote system"
#@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
#@env OPT_SSH_PATH:file!="ssh" "ssh command" "The path to ssh on the local system. Omit the full path to resolve using the system PATH."
#@env OPT_HOST:str="localhost" "[User@]Host" "The hostname or user@host"
#@env OPT_REMOTE_PORT:int=12345 "Remote Trace RMI Port" "A free port on the remote end to receive and forward the Trace RMI connection."
#@env OPT_EXTRA_SSH_ARGS:str="" "Extra ssh arguments" "Extra arguments to pass to ssh. Use with care."
#@env OPT_LLDB_PATH:str="lldb" "lldb command" "The path to lldb on the remote system. Omit the full path to resolve using the system PATH."
#@env OPT_START_CMD:StartCmd="process launch" "Run command" "The lldb command to actually run the target."
#@env OPT_ARCH:str="x86_64" "Architecture" "Target architecture"
. ..\support\lldbsetuputils.ps1
$arglist = Compute-Lldb-Usermode-Args -TargetImage $args[0] -RmiAddress "localhost:$Env:OPT_REMOTE_PORT"
$sshargs = Compute-Ssh-Args $arglist True
$sshproc = Start-Process -FilePath $sshargs[0] -ArgumentList $sshargs[1..$sshargs.Count] -NoNewWindow -Wait -PassThru
$version = Get-Ghidra-Version
$answer = Check-Result-And-Prompt-Mitigation $sshproc @"
It appears ghidralldb is missing from the remote system. This can happen if you
forgot to install the required package. This can also happen if you installed
the packages to a different Python environment than is being used by the
remote's lldb.
This script is about to offer automatic resolution. If you'd like to resolve
this manually, answer no to the next question and then see Ghidra's help by
pressing F1 in the dialog of launch parameters.
WARNING: Answering yes to the next question will invoke pip to try to install
missing or incorrectly-versioned dependencies. It may attempt to find packages
from the PyPI mirror configured on the REMOTE system. If you have not configured
one, it will connect to the official one.
WARNING: We invoke pip with the --break-system-packages flag, because some
debuggers that embed Python (gdb, lldb) may not support virtual environments,
and so the packages must be installed to your user environment.
NOTE: This will copy Python wheels into the HOME directory of the user on the
remote system. You may be prompted to authenticate a few times while packages
are copied and installed.
NOTE: Automatic resolution will cause this session to terminate. When it has
finished, try launching again.
"@ "Would you like to install 'ghidralldb==$version'?"
if ($answer) {
Write-Host "Copying Wheels to $Env:OPT_HOST"
Mitigate-Scp-PyModules "Debug/Debugger-rmi-trace" "Debug/Debugger-agent-lldb"
Write-Host "Installing Wheels into LLDB's embedded Python"
$arglist = Compute-Lldb-PipInstall-Args "'-f'" "os.environ['HOME']" "'ghidralldb==$version'"
$sshargs = Compute-Ssh-Args $arglist False
Start-Process -FilePath $sshargs[0] -ArgumentList $sshargs[1..$sshargs.Count] -NoNewWindow -Wait
}

View file

@ -24,7 +24,7 @@
#@desc For setup instructions, press <b>F1</b>.
#@desc </p>
#@desc </body></html>
#@menu-group remote
#@menu-group lldb
#@icon icon.debugger
#@help lldb#ssh
#@enum StartCmd:str "process launch" "process launch --stop-at-entry"
@ -39,30 +39,61 @@
#@env OPT_START_CMD:StartCmd="process launch" "Run command" "The lldb command to actually run the target."
#@env OPT_ARCH:str="x86_64" "Architecture" "Target architecture"
. ../support/lldbsetuputils.sh
target_image="$1"
shift
target_args="$@"
if [ -z "$target_image" ]
then
"$OPT_SSH_PATH" "-R$OPT_REMOTE_PORT:$GHIDRA_TRACE_RMI_ADDR" -t $OPT_EXTRA_SSH_ARGS "$OPT_HOST" "TERM='$TERM' '$OPT_LLDB_PATH' \
-o 'version' ^
-o 'script import ghidralldb' ^
-o 'settings set target.default-arch %OPT_ARCH%' ^
-o 'ghidra trace connect \"localhost:%OPT_REMOTE_PORT%\"' ^
-o 'target create \"%OPT_TARGET_IMG%\"' ^
-o 'ghidra trace start' ^
-o 'ghidra trace sync-enable' ^
-o '%OPT_START_CMD%'
else
"$OPT_SSH_PATH" "-R$OPT_REMOTE_PORT:$GHIDRA_TRACE_RMI_ADDR" -t $OPT_EXTRA_SSH_ARGS "$OPT_HOST" "TERM='$TERM' '$OPT_LLDB_PATH' \
-o 'version' ^
-o 'script import ghidralldb' ^
-o 'settings set target.default-arch %OPT_ARCH%' ^
-o 'ghidra trace connect \"localhost:%OPT_REMOTE_PORT%\"' ^
-o 'target create \"%OPT_TARGET_IMG%\"' ^
-o 'settings set target.run-args %OPT_TARGET_ARGS%' ^
-o 'ghidra trace start' ^
-o 'ghidra trace sync-enable' ^
-o '%OPT_START_CMD%'
function launch-lldb-ssh() {
local -a args
compute-lldb-usermode-args "$target_image" "localhost:$OPT_REMOTE_PORT" "$@"
local -a sshargs
compute-ssh-args true "${args[@]}"
"${sshargs[@]}"
}
version=$(get-ghidra-version)
function do-installation() {
local -a pipargs
compute-lldb-pipinstall-args "'-f'" "os.environ['HOME']" "'ghidralldb==$version'"
local -a sshargs
compute-ssh-args false "${pipargs[@]}"
"${sshargs[@]}"
}
launch-lldb-ssh
if check-result-and-prompt-mitigation $? "
It appears ghidralldb is missing from the remote system. This can happen if you
forgot to install the required package. This can also happen if you installed
the packages to a different Python environment than is being used by the
remote's lldb.
This script is about to offer automatic resolution. If you'd like to resolve
this manually, answer no to the next question and then see Ghidra's help by
pressing F1 in the dialog of launch parameters.
WARNING: Answering yes to the next question will invoke pip to try to install
missing or incorrectly-versioned dependencies. It may attempt to find packages
from the PyPI mirror configured on the REMOTE system. If you have not configured
one, it will connect to the official one.
WARNING: We invoke pip with the --break-system-packages flag, because some
debuggers that embed Python (gdb, lldb) may not support virtual environments,
and so the packages must be installed to your user environment.
NOTE: This will copy Python wheels into the HOME directory of the user on the
remote system. You may be prompted to authenticate a few times while packages
are copied and installed.
NOTE: Automatic resolution may cause this session to terminate. When it has
finished, try launching again.
" "Would you like to install 'ghidralldb==$version'?"; then
echo "Copying Wheels to $OPT_HOST"
mitigate-scp-pymodules "Debug/Debugger-rmi-trace" "Debug/Debugger-agent-lldb"
echo "Installing Wheels into LLDB's embedded Python"
do-installation
fi

View file

@ -0,0 +1,106 @@
. ..\..\..\Debugger-rmi-trace\data\support\setuputils.ps1
function Add-Lldb-Init-Args {
param([ref]$ArgList)
$ArgList.Value+=("-o", "`"version`"")
$ArgList.Value+=("-o", "`"script import os, ghidralldb`"")
$ArgList.Value+=("-o", "`"script if not 'ghidralldb' in locals(): os._exit(253)`"")
if ("$Env:OPT_ARCH" -ne "") {
$ArgList.Value+=("-o", "`"settings set target.default-arch $Env:OPT_ARCH`"")
}
}
function Add-Lldb-Image-And-Args {
param([ref]$ArgList, $TargetImage, $TargetArgs)
if ("$TargetImage" -ne "") {
if ("$Env:OPT_ARCH" -ne "") {
$ArgList.Value+=("-o", "`"target create --arch '$Env:OPT_ARCH' '$TargetImage'`"")
}
else {
$ArgList.Value+=("-o", "`"target create '$TargetImage'`"")
}
}
if ("$TargetArgs" -ne "") {
$tgtargs = $TargetArgs -replace "`"", "\`""
# Escaping parentheses in the arguments is no longer necessary in powershell vs cmd
$ArgList.Value+=("-o", "`"settings set target.run-args $tgtargs`"")
}
}
function Add-Lldb-Connect-And-Sync {
param([ref]$ArgList, $Address)
$ArgList.Value+=("-o", "`"ghidra trace connect '$Address'`"")
$ArgList.Value+=("-o", "`"ghidra trace start`"")
$ArgList.Value+=("-o", "`"ghidra trace sync-enable`"")
}
function Add-Lldb-Start-If-Image {
param([ref]$ArgList, $TargetImage)
if ("$TargetImage" -ne "") {
$ArgList.Value+=("-o", "`"$Env:OPT_START_CMD`"")
}
}
function Add-Lldb-Tail-Args {
param([ref]$ArgList)
# NOP
}
function Compute-Lldb-Usermode-Args {
param($TargetImage, $RmiAddress)
$arglist = @("`"$Env:OPT_LLDB_PATH`"")
Add-Lldb-Init-Args -ArgList ([ref]$arglist)
Add-Lldb-Image-And-Args -ArgList ([ref]$arglist) -TargetImage $TargetImage -TargetArgs $Env:OPT_TARGET_ARGS
Add-Lldb-Connect-And-Sync -ArgList ([ref]$arglist) -Address $RmiAddress
Add-Lldb-Start-If-Image -ArgList ([ref]$arglist) -TargetImage $TargetImage
Add-Lldb-Tail-Args -ArgList ([ref]$arglist)
return $arglist
}
function Compute-Lldb-Platform-Args {
param($TargetImage, $TargetType, $TargetUrl, $RmiAddress)
$argslist = @("`"$Env:OPT_LLDB_PATH`"")
Add-Lldb-Init-Args -ArgList ([ref]$arglist)
$argslist+=("-o", "`"platform select '$TargetType'`"")
$argslist+=("-o", "`"platform connect '$TargetUrl'`"")
Add-Lldb-Image-And-Args -ArgList ([ref]$arglistt) -TargetImage $TargetImage -TargetArgs $Env:OPT_TARGET_ARGS
Add-Lldb-Connect-And-Sync -ArgList ([ref]$arglist) -Address $RmiAddress
Add-Lldb-Start-If-Image -ArgList ([ref]$arglist) -TargetImage $TargetImage
Add-Lldb-Tail-Args -ArgList ([ref]$arglist)
return $arglist
}
function Compute-Lldb-Remote-Args {
param($TargetImage, $TargetCx, $RmiAddress)
$arglist = @("`"$Env:OPT_LLDB_PATH`"")
Add-Lldb-Init-Args -ArgList ([ref]$arglist)
Add-Lldb-Image-And-Args -ArgList ([ref]$arglist) -TargetImge $TargetImage -TargetArgs ""
$arglist+=("-o", "`"$TargetCx`"")
Add-Lldb-Connect-And-Sync -ArgList ([ref]$arglist) -Address $RmiAddress
$arglist+=("-o", "`"ghidra trace sync-synth-stopped`"")
Add-Lldb-Tail-Args -ArgList ([ref]$arglist)
return $arglist
}
function Compute-Lldb-PipInstall-Args {
$argvpart = $args -join ", "
$arglist = @("`"$Env:OPT_LLDB_PATH`"")
$arglist+=("-o", "`"script import os, sys, runpy`"")
$arglist+=("-o", "`"script sys.argv=['pip', 'install', '--force-reinstall', $argvpart]`"")
$arglist+=("-o", "`"script os.environ['PIP_BREAK_SYSTEM_PACKAGE']='1'`"")
$arglist+=("-o", "`"script runpy.run_module('pip', run_name='__main__')`"")
$arglist+=("-o", "`"quit`"")
return $arglist
}

View file

@ -0,0 +1,129 @@
## ###
# 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.
##
. ../../../Debugger-rmi-trace/data/support/setuputils.sh
add-lldb-init-args() {
args+=(-o "version")
args+=(-o "script import os, ghidralldb")
args+=(-o "script if not 'ghidralldb' in locals(): os._exit(253)")
if [ -n "$OPT_ARCH" ]; then
args+=(-o "settings set target.default-arch $OPT_ARCH")
fi
}
add-lldb-image-and-args() {
target_image=$1
target_args=$2
if [ -n "$target_image" ]; then
if [ -n "$OPT_ARCH" ]; then
args+=(-o "target create --arch '$OPT_ARCH' '$target_image'")
else
args+=(-o "target create '$target_image'")
fi
fi
if [ -n "$target_args" ]; then
args+=(-o "settings set target.run-args $target_args")
fi
}
add-lldb-io-tty() {
if [ -n "$TTY_TARGET" ]; then
args+=(-o "settings set target.output-path '$TTY_TARGET'")
args+=(-o "settings set target.input-path '$TTY_TARGET'")
fi
}
add-lldb-connect-and-sync() {
address=$1
args+=(-o "ghidra trace connect '$address'")
args+=(-o "ghidra trace start")
args+=(-o "ghidra trace sync-enable")
}
add-lldb-start-if-image() {
target_image=$1
if [ -n "$target_image" ]; then
args+=(-o "$OPT_START_CMD")
fi
}
add-lldb-tail-args() {
true
}
compute-lldb-usermode-args() {
target_image=$1
rmi_address=$2
shift
shift
args+=("$OPT_LLDB_PATH")
add-lldb-init-args
add-lldb-image-and-args "$target_image" "$@"
add-lldb-io-tty
add-lldb-connect-and-sync "$rmi_address"
add-lldb-start-if-image "$target_image"
add-lldb-tail-args
}
compute-lldb-platform-args() {
target_image=$1
target_type=$2
target_url=$3
rmi_address=$4
shift
shift
shift
shift
args+=("$OPT_LLDB_PATH")
add-lldb-init-args
args+=(-o "platform select '$target_type'")
args+=(-o "platform connect '$target_url'")
add-lldb-image-and-args "$target_image" "$@"
add-lldb-connect-and-sync "$rmi_address"
add-lldb-start-if-image "$target_image"
add-lldb-tail-args
}
compute-lldb-remote-args() {
target_image=$1
target_cx=$2
rmi_address=$3
args+=("$OPT_LLDB_PATH")
add-lldb-init-args
add-lldb-image-and-args "$target_image" ""
args+=(-o "$target_cx")
add-lldb-connect-and-sync "$rmi_address"
args+=(-o "ghidra trace sync-synth-stopped")
add-lldb-tail-args
}
compute-lldb-pipinstall-args() {
local argvpart
printf -v argvpart ", %s" "$@"
pipargs=("$OPT_LLDB_PATH")
pipargs+=(-o "script import os, sys, runpy")
pipargs+=(-o "script sys.argv=['pip', 'install', '--force-reinstall'$argvpart]")
pipargs+=(-o "script os.environ['PIP_BREAK_SYSTEM_PACKAGE']='1'")
pipargs+=(-o "script runpy.run_module('pip', run_name='__main__')")
pipargs+=(-o "quit")
}

View file

@ -1 +1 @@
include src/ghidragdb/schema.xml
include src/ghidralldb/schema.xml

View file

@ -24,6 +24,13 @@ import ghidra.trace.model.Trace;
*/
@ServiceInfo(defaultProviderName = "ghidra.app.plugin.core.debug.gui.modules.DebuggerModulesPlugin")
public interface DebuggerAutoMappingService {
/**
* Set the current auto-map specification in the Modules provider
*
* @param spec the new setting
*/
void setAutoMapSpec(AutoMapSpec spec);
/**
* Get the auto-map setting currently active in the Modules provider
*

View file

@ -398,21 +398,19 @@ public enum ControlMode {
return coordinates;
}
ScheduleForm form =
target.getSupportedTimeForm(coordinates.getObject(), coordinates.getSnap());
ScheduleForm form = coordinates.getObject() == null ? null
: target.getSupportedTimeForm(coordinates.getObject(), coordinates.getSnap());
if (form == null) {
if (coordinates.getTime().isSnapOnly() &&
coordinates.getSnap() == target.getSnap()) {
return coordinates;
}
else {
tool.setStatusInfo("""
Cannot navigate time in %s mode. Switch to Trace or Emulate mode first."""
.formatted(name),
true);
return null;
}
}
TraceSchedule norm = form.validate(coordinates.getTrace(), coordinates.getTime());
if (norm != null) {
return coordinates.time(norm);

View file

@ -7,7 +7,7 @@
//@desc For setup instructions, press <b>F1</b>.
//@desc </p>
//@desc </body></html>
//@menu-group attach
//@menu-group java
//@icon icon.debugger
//@help jpda#attach_port
//@enum Arch:str JVM Dalvik

View file

@ -7,7 +7,7 @@
//@desc For setup instructions, press <b>F1</b>.
//@desc </p>
//@desc </body></html>
//@menu-group attach
//@menu-group java
//@icon icon.debugger
//@help jpda#attach_pid
//@enum Arch:str JVM Dalvik

View file

@ -8,7 +8,7 @@
//@desc For setup instructions, press <b>F1</b>.
//@desc </p>
//@desc </body></html>
//@menu-group local
//@menu-group java
//@icon icon.debugger
//@help jpda#local
//@env OPT_TARGET_CLASS:file="" "Image" "The Main Class to launch (defaults to current program)."

View file

@ -5,6 +5,7 @@ DEVNOTES.txt||GHIDRA||||END|
Module.manifest||GHIDRA||||END|
README.md||GHIDRA||||END|
data/ExtensionPoint.manifest||GHIDRA||||END|
data/support/setuputils.ps1||GHIDRA||||END|
src/main/help/help/TOC_Source.xml||GHIDRA||||END|
src/main/help/help/topics/TraceRmiConnectionManagerPlugin/TraceRmiConnectionManagerPlugin.html||GHIDRA||||END|
src/main/help/help/topics/TraceRmiConnectionManagerPlugin/images/ConnectDialog.png||GHIDRA||||END|

View file

@ -0,0 +1,42 @@
## ###
# 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.
##
"""
This file holds utilities required by Python-based launch scripts. At
the moment, that includes only the launchers on Windows, since they're
just .bat files that invoke the .py file interactively. They require
this utility to set up the PYTHONPATH before importing the actual
connector's Python code.
This file MUST remain in a predictable location relative to the
working directory or module directory of the scripts needing it, so
that minimal logic is required to get it loaded.
This file CANNOT be assumed to be available on a remote target. For
that, consider ghidratrace.setuputils.
"""
def ghidra_module_pypath(name: str) -> str:
installed = f'{home}/Ghidra/{name}/pypkg/src'
if os.path.isdir(installed):
return installed
dev1 = f'{home}/Ghidra/{name}/build/pypkg/src'
if os.path.isdir(dev1):
return dev1
dev2 = f'{home}/ghidra/Ghidra/{name}/build/pypkg/src'
if os.path.isdir(dev2):
return dev2
raise Exception(
f"Cannot find Python source for {name}. Try gradle assemblePyPackage?")

View file

@ -0,0 +1,97 @@
function Find-App-Properties {
[IO.FileInfo] $simple = "$Env:GHIDRA_HOME\Ghidra\applications.properties"
if ($simple.Exists) {
return $simple
}
[IO.FileInfo] $dev2 = "$Env:GHIDRA_HOME\ghidra\Ghidra\application.properties"
if ($dev2.Exists) {
return $dev2
}
throw "Cannot find application.properties"
}
function Get-Ghidra-Version {
$props = Find-App-Properties
$m = Get-Content $props | Select-String -Pattern "application\.version=(.*)"
return $m.Matches.Groups[1].Value
}
function Ghidra-Module-PyPath {
[IO.DirectoryInfo] $installed = "$Env:GHIDRA_HOME\Ghidra\$($args[0])\pypkg\src"
if ($installed.Exists) {
return "$installed"
}
[IO.DirectoryInfo] $dev1 = "$Env:GHIDRA_HOME\Ghidra\$($args[0])\build\pypkg\src"
if ($dev1.Exists) {
return "$dev1"
}
[IO.DirectoryInfo] $dev2 = "$Env:GHIDRA_HOME\ghidra\Ghidra\$($args[0])\build\pypkg\src"
if ($dev2.Exists) {
return "$dev2"
}
throw "Cannot find Python source for $($args[0]). Try gradle assemblePyPackage?"
}
function Ghidra-Module-PyDist {
[IO.DirectoryInfo] $installed = "$Env:GHIDRA_HOME\Ghidra\$($args[0])\pypkg\dist"
if ($installed.Exists) {
return "$installed"
}
[IO.DirectoryInfo] $dev1 = "$Env:GHIDRA_HOME\Ghidra\$($args[0])\build\pypkg\dist"
if ($dev1.Exists) {
return "$dev1"
}
[IO.DirectoryInfo] $dev2 = "$Env:GHIDRA_HOME\ghidra\Ghidra\$($args[0])\build\pypkg\dist"
if ($dev2.Exists) {
return "$dev2"
}
throw "Cannot find Python package for $($args[0]). Try gradle buildPyPackage?"
}
function Compute-Ssh-Args {
$arglist = $args[0]
$forward = $args[1]
$cmdline = $arglist -join " " -replace "`"", "\`""
$sshargs = @("`"$Env:OPT_SSH_PATH`"")
$sshargs+=("-t")
if ($forward) {
$sshargs+=("-R$Env:OPT_REMOTE_PORT`:$Env:GHIDRA_TRACE_RMI_ADDR")
}
if ("$Env:OPT_EXTRA_SSH_ARGS" -ne "") {
$sshargs+=("$Env:OPT_EXTRA_SSH_ARGS")
}
$sshargs+=("$Env:OPT_HOST", "TERM='$Env:TERM' $cmdline")
return $sshargs
}
function Check-Result-And-Prompt-Mitigation {
$proc = $args[0]
$msg = $args[1]
$prompt = $args[2]
if ($proc.ExitCode -eq 253) {
Write-Host @"
--------------------------------------------------------------------------------
!!! INCORRECT OR INCOMPLETE SETUP !!!
--------------------------------------------------------------------------------
"@
Write-Host $msg
Write-Host ""
Write-Host "Select KEEP if you're seeing this in an error dialog."
Write-Host -NoNewline "$prompt [Y/n] "
$answer = Read-Host
return (("$answer" -eq "y") -or ("$answer" -eq "Y") -or ("$answer" -eq ""))
}
}
function Mitigate-Scp-PyModules {
$scpargs = $args | ForEach-Object {
$dist = Ghidra-Module-PyDist $_
return "$dist\*"
}
$scpargs+=("$Env:OPT_HOST`:~/")
Start-Process -FilePath "scp" -ArgumentList $scpargs -NoNewWindow -Wait
}

View file

@ -0,0 +1,135 @@
## ###
# 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.
##
find-app-properties() {
local simple="$GHIDRA_HOME/Ghidra/application.properties"
if [ -f "$simple" ]; then
echo $simple
return 0
fi
local dev2="$GHIDRA_HOME/ghidra/Ghidra/application.properties"
if [ -f "$dev2" ]; then
echo $dev2
return 0
fi
echo >&2 "Cannot find application.properties"
return 1
}
get-ghidra-version() {
local app_ver_re='application\.version=(.*)'
local props=$(find-app-properties)
local version=$(cat "$props" | while read line; do
if [[ $line =~ $app_ver_re ]]; then
echo "${BASH_REMATCH[1]}"
fi
done)
if [ -n "$version" ]; then
echo "$version"
return 0
fi
echo >&2 "Cannot determine Ghidra version"
return 1
}
ghidra-module-pypath() {
installed="$GHIDRA_HOME/Ghidra/$1/pypkg/src"
if [ -d "$instaled" ]; then
echo $installed
return 0
fi
dev1="$GHIDRA_HOME/Ghidra/$1/build/pypkg/src"
if [ -d "$dev1" ]; then
echo $dev1
return 0
fi
dev2="$GHIDRA_HOME/ghidra/Ghidra/$1/build/pypkg/src"
if [ -d "$dev2" ]; then
echo $dev2
return 0
fi
echo >&2 "Cannot find Python source for $1. Try gradle assemblePyPackage?"
return 1
}
ghidra-module-pydist() {
installed="$GHIDRA_HOME/Ghidra/$1/pypkg/dist"
if [ -d "$instaled" ]; then
echo $installed
return 0
fi
dev1="$GHIDRA_HOME/Ghidra/$1/build/pypkg/dist"
if [ -d "$dev1" ]; then
echo $dev1
return 0
fi
dev2="$GHIDRA_HOME/ghidra/Ghidra/$1/build/pypkg/dist"
if [ -d "$dev2" ]; then
echo $dev2
return 0
fi
echo >&2 "Cannot find Python package for $1. Try gradle buildPyPackage?"
return 1
}
compute-ssh-args() {
forward=$1
shift
local qargs
printf -v qargs '%q ' "$@"
sshargs+=("$OPT_SSH_PATH")
sshargs+=(-t)
if [ "$forward" == "true" ]; then
sshargs+=("-R$OPT_REMOTE_PORT:$GHIDRA_TRACE_RMI_ADDR")
fi
if [ -n "$OPT_EXTRA_SSH_ARGS" ]; then
sshargs+=($OPT_EXTRA_SSH_ARGS)
fi
sshargs+=("$OPT_HOST")
sshargs+=("TERM='$TERM' $qargs")
}
check-result-and-prompt-mitigation() {
exitcode=$1
msg=$2
prompt=$3
if [ "$exitcode" -eq "253" ]; then
cat << EOF
--------------------------------------------------------------------------------
!!! INCORRECT OR INCOMPLETE SETUP !!!
--------------------------------------------------------------------------------
EOF
echo "$msg"
echo ""
echo "Select KEEP if you're seeing this in an error dialog."
echo -n "$prompt [Y/n] "
read answer
[ "$answer" == "y" ] || [ "$answer" == "Y" ] || [ "$answer" == "" ]
return $?
fi
return 1
}
mitigate-scp-pymodules() {
local -a scpargs
for mod in "$@"; do
dist=$(ghidra-module-pydist "$mod")
scpargs+=("$dist"/*)
done
scp "${scpargs[@]}" "$OPT_HOST:~/"
}

View file

@ -534,7 +534,7 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
Map<String, TerminalSession> sessions, Map<String, ValStr<?>> args,
SocketAddress address) throws Exception;
static class NoStaticMappingException extends Exception {
public static class NoStaticMappingException extends Exception {
public NoStaticMappingException(String message) {
super(message);
}

View file

@ -91,7 +91,7 @@ public class LaunchAction extends MultiActionDockingAction {
.popupMenuIcon(offer.getIcon())
.helpLocation(offer.getHelpLocation())
.enabledWhen(ctx -> true)
.onAction(ctx -> plugin.relaunch(offer))
.onAction(ctx -> plugin.relaunch(ctx, offer))
.build());
}
return actions;
@ -148,7 +148,7 @@ public class LaunchAction extends MultiActionDockingAction {
Swing.runLater(() -> button.showPopup());
return;
}
plugin.relaunch(offer);
plugin.relaunch(context, offer);
}
@Override

View file

@ -78,6 +78,6 @@ public class PowerShellScriptTraceRmiLaunchOffer extends AbstractScriptTraceRmiL
protected void prepareSubprocess(List<String> commandLine, Map<String, String> env,
Map<String, ValStr<?>> args, SocketAddress address) {
super.prepareSubprocess(commandLine, env, args, address);
commandLine.add(0, "powershell");
commandLine.addAll(0, List.of("powershell", "-File"));
}
}

View file

@ -342,7 +342,8 @@ public abstract class ScriptAttributesParser {
public record ScriptAttributes(String title, String description, List<String> menuPath,
String menuGroup, String menuOrder, Icon icon, HelpLocation helpLocation,
Map<String, LaunchParameter<?>> parameters, Map<String, TtyCondition> extraTtys,
int timeoutMillis, LaunchParameter<?> imageOpt) {}
int timeoutMillis, LaunchParameter<?> imageOpt) {
}
/**
* Convert an arguments map into a command line and environment variables

View file

@ -15,6 +15,7 @@
*/
package ghidra.app.plugin.core.debug.gui.tracermi.launcher;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.util.*;
@ -25,6 +26,7 @@ import org.jdom.Element;
import org.jdom.JDOMException;
import db.Transaction;
import docking.ActionContext;
import docking.action.DockingActionIf;
import docking.action.builder.ActionBuilder;
import ghidra.app.events.ProgramActivatedPluginEvent;
@ -348,6 +350,16 @@ public class TraceRmiLauncherServicePlugin extends Plugin
executeTask(new ReLaunchTask(offer));
}
protected void relaunch(ActionContext ctx, TraceRmiLaunchOffer offer) {
int mods = ctx == null ? 0 : ctx.getEventClickModifiers();
if ((mods & ActionEvent.SHIFT_MASK) != 0) {
configureAndLaunch(offer);
}
else {
relaunch(offer);
}
}
protected void configureAndLaunch(TraceRmiLaunchOffer offer) {
executeTask(new ConfigureAndLaunchTask(offer));
}
@ -478,7 +490,8 @@ public class TraceRmiLauncherServicePlugin extends Plugin
toolLaunchConfigs.putSaveState(name, state);
}
protected record ConfigLast(String configName, long last, Program program) {}
protected record ConfigLast(String configName, long last, Program program) {
}
protected ConfigLast checkSavedConfig(Program program, ProgramUserData userData,
String propName) {

View file

@ -64,13 +64,16 @@ public abstract class AbstractTraceRmiConnection implements TraceRmiConnection {
if (!traceManager.getOpenTraces().contains(trace)) {
traceManager.openTrace(trace);
traceManager.activate(finalCoords, ActivationCause.SYNC_MODEL);
return;
}
else {
Trace currentTrace = traceManager.getCurrentTrace();
if (currentTrace == null || ownsTrace(currentTrace)) {
traceManager.activate(finalCoords, ActivationCause.SYNC_MODEL);
return;
}
}
// LATER: See if all this ownership checking is really necessary.
// For now, just always activate anyway
traceManager.activate(finalCoords, ActivationCause.SYNC_MODEL);
});
}
}

View file

@ -17,7 +17,7 @@ classifiers = [
"Operating System :: OS Independent",
]
dependencies = [
"protobuf >= 3, < 4",
"protobuf >= 3.20.0",
]
[project.urls]

View file

@ -13,7 +13,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
from typing import get_args, get_origin
try:
from . import trace_rmi_pb2 as bufs
except Exception as e:
from .setuputils import prompt_and_mitigate_dependencies
prompt_and_mitigate_dependencies("Debug/Debugger-rmi-trace")
from collections import deque
from concurrent.futures import Executor, Future
from contextlib import contextmanager
@ -26,12 +32,12 @@ import traceback
from typing import (Annotated, Any, Callable, Collection, Dict, Generator,
Generic, Iterable, List, MutableSequence, Optional,
Sequence, Tuple, TypeVar, Union)
from typing import get_args, get_origin
from google.protobuf.internal.containers import (
RepeatedCompositeFieldContainer as RCFC)
from . import sch
from . import trace_rmi_pb2 as bufs
from .util import send_delimited, recv_delimited
@ -188,7 +194,6 @@ class TraceObject:
else:
return '<Future>'
def insert(self, span: Optional[Lifespan] = None,
resolution: str = 'adjust') -> Union[
Lifespan, RemoteResult[Any, Lifespan]]:

View file

@ -0,0 +1,124 @@
## ###
# 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.
##
"""
This file holds utilities required by Python-based connectors. At the
moment, that includes all connectors except the ones targeting Java
applications. While uncommon, it is possible that dependencies turn up
missing on a remote target, and so the gmodutils.py file will not be
present. However, by the time such dependencies turn up missing,
whether remote or local, the PYTHONPATH should already include this
module, and so we place the setup logic here.
"""
import os
from typing import List, Sequence
home = os.getenv('GHIDRA_HOME')
def ghidra_module_src(name: str) -> str:
installed = f'{home}/Ghidra/{name}/pypkg'
if os.path.isdir(installed):
return installed
dev1 = f'{home}/Ghidra/{name}/src/main/py'
if os.path.isdir(dev1):
return dev1
dev2 = f'{home}/ghidra/Ghidra/{name}/src/main/py'
if os.path.isdir(dev2):
return dev2
raise Exception(f"""
Cannot find Python source for {name}.
If this is a remote system, we shouldn't even be here. Chances are,
the Python dependencies required by ghidra on the remote system were
removed or replaced with incompatible versions. If this is a local
system, your installation or development repo may be corrupt.
""")
def get_module_dependencies(name: str) -> List[str]:
src = ghidra_module_src(name)
# Can't rely on tomllib until Python 3.11 is minimum requirement.
# And, I'm in a place where I presume deps are missing, so do this garbage
# of a parse job.
with open(f"{src}/pyproject.toml") as project:
seen_deps = False
result: List[str] = []
for l in project.readlines():
l = l.strip()
if l == "dependencies = [":
seen_deps = True
elif seen_deps and l == ']':
return [r for r in result if not 'ghidra' in r]
elif seen_deps:
if l.endswith(','): # Last one may not have ,
l = l[:-1].strip()
result.append(l[1:-1]) # Remove 's or "s
raise Exception("Could not parse pyproject.toml")
def prompt_mitigation(msg: str, prompt: str) -> bool:
print("""
--------------------------------------------------------------------------------
!!! INCORRECT OR INCOMPLETE SETUP !!!
--------------------------------------------------------------------------------
""")
print(msg)
print("")
print("Select KEEP if you're seeing this in an error dialog.")
print(f"{prompt} [Y/n] ", end="")
answer = input()
return answer == 'y' or answer == 'Y' or answer == ''
def mitigate_by_pip_install(*args: str) -> None:
import sys
import runpy
sys.argv = [
'pip', 'install', '--force-reinstall', *args
]
os.environ['PIP_BREAK_SYSTEM_PACKAGES'] = '1'
runpy.run_module("pip", run_name="__main__")
def prompt_and_mitigate_dependencies(name: str) -> None:
deps = get_module_dependencies(name)
deps_str = ' '.join(f"'{d}'" for d in deps)
answer = prompt_mitigation("""
It appears dependencies are missing or have the wrong version. This can happen
if you forgot to install the required packages. This can also happen if you
installed the packages to a different Python environment than is being used
right now.
This script is about to offer automatic resolution. If you'd like to resolve
this manually, answer no to the next question and then see Ghidra's help by
pressing F1 in the dialog of launch parameters.
WARNING: Answering yes to the next question will invoke pip to try to install
missing or incorrectly-versioned dependencies. It may attempt to find packages
from your configured PyPI mirror. If you have not configured one, it will
connect to the official one.
WARNING: We invoke pip with the --break-system-packages flag, because some
debuggers that embed Python (gdb, lldb) may not support virtual environments,
and so the packages must be installed to your user environment.
NOTE: Automatic resolution may cause this session to terminate. When it has
finished, close this terminal, and try launching again.
""", f"Would you like to install {deps_str}?")
if answer:
mitigate_by_pip_install('-f', '../../pypkg/dist', *deps)

View file

@ -1388,6 +1388,7 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter
List.of(programManager.getAllOpenPrograms()));
}
@Override
public void setAutoMapSpec(AutoMapSpec spec) {
actionAutoMap.setCurrentActionStateByUserData(spec);
}

View file

@ -92,9 +92,11 @@ public class ConPtyChild extends ConPtyEndpoint implements PtyChild {
STARTUPINFOEX si = prepareStartupInfo();
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
String commandLine = ShellUtils.generateLine(Arrays.asList(args));
if (!ConsoleApiNative.INSTANCE.CreateProcessW(
null /*lpApplicationName*/,
new WString(ShellUtils.generateLine(Arrays.asList(args))),
new WString(commandLine),
null /*lpProcessAttributes*/,
null /*lpThreadAttributes*/,
false /*bInheritHandles*/,

View file

@ -0,0 +1,266 @@
/* ###
* 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.gdb.rmi;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.SocketTimeoutException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import org.junit.Before;
import org.junit.Test;
import db.Transaction;
import generic.Unique;
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerIntegrationTest;
import ghidra.app.plugin.core.debug.gui.action.BySectionAutoMapSpec;
import ghidra.app.plugin.core.debug.gui.modules.DebuggerModulesPlugin;
import ghidra.app.plugin.core.debug.gui.tracermi.launcher.AbstractTraceRmiLaunchOffer.NoStaticMappingException;
import ghidra.app.plugin.core.debug.gui.tracermi.launcher.TraceRmiLauncherServicePlugin;
import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingServicePlugin;
import ghidra.app.services.DebuggerAutoMappingService;
import ghidra.app.services.TraceRmiLauncherService;
import ghidra.app.util.importer.AutoImporter;
import ghidra.app.util.importer.MessageLog;
import ghidra.debug.api.ValStr;
import ghidra.debug.api.action.AutoMapSpec;
import ghidra.debug.api.tracermi.TerminalSession;
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer;
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer.*;
import ghidra.framework.OperatingSystem;
import ghidra.framework.plugintool.AutoConfigState.PathIsFile;
import ghidra.pty.testutil.DummyProc;
import ghidra.util.SystemUtilities;
public class GdbConnectorsTest extends AbstractGhidraHeadedDebuggerIntegrationTest {
private TraceRmiLauncherService launchService;
private DebuggerAutoMappingService autoMappingService;
@Before
public void checkManual() throws Exception {
assumeFalse(SystemUtilities.isInTestingBatchMode());
addPlugin(tool, DebuggerStaticMappingServicePlugin.class);
addPlugin(tool, DebuggerModulesPlugin.class);
autoMappingService =
Objects.requireNonNull(tool.getService(DebuggerAutoMappingService.class));
launchService = addPlugin(tool, TraceRmiLauncherServicePlugin.class);
}
protected PathIsFile chooseImage() {
if (OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS) {
return new PathIsFile(Path.of("C:\\Windows\\notepad.exe"));
}
return new PathIsFile(Path.of("/bin/ls"));
}
protected PathIsFile findQemu(String bin) {
if (OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS) {
return new PathIsFile(Path.of("C:\\msys64\\ucrt64\bin\\").resolve(bin));
}
return new PathIsFile(Path.of(bin));
}
protected PathIsFile createArmElfImage() throws Exception {
Path tempSrc = Files.createTempFile("hw", ".c");
Path tempObj = Files.createTempFile("hw", ".o");
Path tempImg = Files.createTempFile("hw", "");
try (OutputStream os = new FileOutputStream(tempSrc.toFile())) {
os.write("""
int main() {
return 0;
}
""".getBytes());
}
new ProcessBuilder().command(
"arm-linux-eabi-gcc", "-c",
"-o", tempObj.toAbsolutePath().toString(),
tempSrc.toAbsolutePath().toString()).inheritIO().start().waitFor();
new ProcessBuilder().command(
"arm-linux-eabi-ld",
"-o", tempImg.toAbsolutePath().toString(),
tempObj.toAbsolutePath().toString()).inheritIO().start().waitFor();
return new PathIsFile(tempImg);
}
protected PathIsFile createDummyQemuImage() throws Exception {
Path temp = Files.createTempFile("qemudummy", ".bin");
try (OutputStream os = new FileOutputStream(temp.toFile())) {
os.write(new byte[4096]);
}
return new PathIsFile(temp);
}
protected LaunchResult doLaunch(String title, Map<String, Object> args) {
TraceRmiLaunchOffer offer = Unique.assertOne(
launchService.getOffers(program).stream().filter(o -> o.getTitle().equals(title)));
return offer.launchProgram(monitor, new LaunchConfigurator() {
@Override
public Map<String, ValStr<?>> configureLauncher(TraceRmiLaunchOffer offer,
Map<String, ValStr<?>> arguments, RelPrompt relPrompt) {
Map<String, ValStr<?>> newArgs = new HashMap<>(arguments);
for (Map.Entry<String, Object> ent : args.entrySet()) {
newArgs.put(ent.getKey(), ValStr.from(ent.getValue()));
}
return newArgs;
}
});
}
protected void checkResult(LaunchResult result) {
if (result.exception() != null &&
!(result.exception() instanceof NoStaticMappingException)) {
throw new AssertionError(result);
}
}
@Test
public void testLocalGdbSetup() throws Exception {
new ProcessBuilder().command("pip", "install", "protobuf==3.19.0")
.inheritIO()
.start()
.waitFor();
try (LaunchResult result = doLaunch("gdb", Map.of("arg:1", chooseImage()))) {
assertTrue(result.exception() instanceof SocketTimeoutException);
TerminalSession term = Unique.assertOne(result.sessions().values());
while (!term.isTerminated()) {
Thread.sleep(1000);
}
}
try (LaunchResult result = doLaunch("gdb", Map.of("arg:1", chooseImage()))) {
checkResult(result);
}
}
@Test
public void testLocalGdbWithImage() throws Exception {
try (LaunchResult result = doLaunch("gdb", Map.of("arg:1", chooseImage()))) {
checkResult(result);
}
}
@Test
public void testGdbQemuUser() throws Exception {
PathIsFile image = createArmElfImage();
program = AutoImporter.importByUsingBestGuess(image.path().toFile(), null, "/", this,
new MessageLog(), monitor).getPrimaryDomainObject();
programManager.openProgram(program);
try (LaunchResult result = doLaunch("gdb + qemu", Map.ofEntries(
Map.entry("arg:1", image),
Map.entry("env:OPT_GDB_PATH", new PathIsFile(Path.of("gdb"))),
Map.entry("env:GHIDRA_LANG_EXTTOOL_qemu_system", findQemu("qemu-arm")),
Map.entry("env:OPT_PULL_ALL_SECTIONS", true)))) {
checkResult(result);
}
}
@Test
public void testGdbQemuSys() throws Exception {
autoMappingService
.setAutoMapSpec(AutoMapSpec.fromConfigName(BySectionAutoMapSpec.CONFIG_NAME));
PathIsFile dummy = createDummyQemuImage();
createProgram();
try (Transaction tx = program.openTransaction("Set name")) {
program.setName(dummy.toString());
}
programManager.openProgram(program);
try (LaunchResult result = doLaunch("gdb + qemu-system", Map.ofEntries(
Map.entry("arg:1", dummy),
Map.entry("env:OPT_GDB_PATH", new PathIsFile(Path.of("gdb"))),
Map.entry("env:GHIDRA_LANG_EXTTOOL_qemu_system", findQemu("qemu-system-aarch64")),
Map.entry("env:OPT_EXTRA_QEMU_ARGS", "-machine virt")))) {
checkResult(result);
}
}
@Test
public void testGdbRemote() throws Exception {
PathIsFile target = chooseImage();
try (
DummyProc gdbServer =
DummyProc.run("gdbserver", ":9999", target.path().toAbsolutePath().toString());
LaunchResult result = doLaunch("gdb remote", Map.ofEntries(
Map.entry("arg:1", target),
Map.entry("OPT_HOST", "localhost"),
Map.entry("OPT_PORT", 9999)))) {
checkResult(result);
}
}
@Test
public void testGdbViaSsh() throws Exception {
try (LaunchResult result = doLaunch("gdb via ssh", Map.ofEntries(
Map.entry("arg:1", "/bin/ls"),
Map.entry("OPT_HOST", "localhost")))) {
checkResult(result);
}
}
@Test
public void testGdbViaSshSetupGhidraGdb() throws Exception {
new ProcessBuilder().command("pip", "uninstall", "ghidragdb").inheritIO().start().waitFor();
try (LaunchResult result = doLaunch("gdb via ssh", Map.ofEntries(
Map.entry("arg:1", "/bin/ls"),
Map.entry("OPT_HOST", "localhost")))) {
assertTrue(result.exception() instanceof SocketTimeoutException);
TerminalSession term = Unique.assertOne(result.sessions().values());
while (!term.isTerminated()) {
Thread.sleep(1000);
}
}
try (LaunchResult result = doLaunch("gdb via ssh", Map.ofEntries(
Map.entry("arg:1", "/bin/ls"),
Map.entry("OPT_HOST", "localhost")))) {
checkResult(result);
}
}
@Test
public void testGdbViaSshSetupProtobuf() throws Exception {
new ProcessBuilder().command("pip", "install", "protobuf==3.19.0")
.inheritIO()
.start()
.waitFor();
try (LaunchResult result = doLaunch("gdb via ssh", Map.ofEntries(
Map.entry("arg:1", "/bin/ls"),
Map.entry("OPT_HOST", "localhost")))) {
assertTrue(result.exception() instanceof SocketTimeoutException);
TerminalSession term = Unique.assertOne(result.sessions().values());
while (!term.isTerminated()) {
Thread.sleep(1000);
}
}
try (LaunchResult result = doLaunch("gdb via ssh", Map.ofEntries(
Map.entry("arg:1", "/bin/ls"),
Map.entry("OPT_HOST", "localhost")))) {
checkResult(result);
}
}
@Test
public void testGdbServerViaSsh() throws Exception {
PathIsFile target = chooseImage();
createProgram();
try (LaunchResult result = doLaunch("gdb + gdbserver via ssh", Map.ofEntries(
Map.entry("arg:1", target.toString())))) {
checkResult(result);
}
}
}

View file

@ -0,0 +1,291 @@
/* ###
* 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.lldb.rmi;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.SocketTimeoutException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import org.junit.*;
import db.Transaction;
import generic.Unique;
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerIntegrationTest;
import ghidra.app.plugin.core.debug.gui.action.BySectionAutoMapSpec;
import ghidra.app.plugin.core.debug.gui.modules.DebuggerModulesPlugin;
import ghidra.app.plugin.core.debug.gui.tracermi.launcher.AbstractTraceRmiLaunchOffer.NoStaticMappingException;
import ghidra.app.plugin.core.debug.gui.tracermi.launcher.TraceRmiLauncherServicePlugin;
import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingServicePlugin;
import ghidra.app.services.DebuggerAutoMappingService;
import ghidra.app.services.TraceRmiLauncherService;
import ghidra.app.util.importer.AutoImporter;
import ghidra.app.util.importer.MessageLog;
import ghidra.debug.api.ValStr;
import ghidra.debug.api.action.AutoMapSpec;
import ghidra.debug.api.tracermi.TerminalSession;
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer;
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer.*;
import ghidra.framework.OperatingSystem;
import ghidra.framework.plugintool.AutoConfigState.PathIsFile;
import ghidra.pty.testutil.DummyProc;
import ghidra.util.SystemUtilities;
/**
* NOTE: On Windows, these tests may need to be run with lldb's version of Python at the front of
* PATH, and it's lib and DLLs dirs at the front of PYTHONPATH. It's probably easiest to just get
* lldb working in a command prompt. Ensure that it can import socket, and then re-launch Eclipse
* from there.
*/
public class LldbConnectorsTest extends AbstractGhidraHeadedDebuggerIntegrationTest {
private TraceRmiLauncherService launchService;
private DebuggerAutoMappingService autoMappingService;
@Before
public void checkManual() throws Exception {
assumeFalse(SystemUtilities.isInTestingBatchMode());
addPlugin(tool, DebuggerStaticMappingServicePlugin.class);
addPlugin(tool, DebuggerModulesPlugin.class);
autoMappingService =
Objects.requireNonNull(tool.getService(DebuggerAutoMappingService.class));
launchService = addPlugin(tool, TraceRmiLauncherServicePlugin.class);
}
protected PathIsFile chooseImage() {
if (OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS) {
return new PathIsFile(Path.of("C:\\Windows\\notepad.exe"));
}
return new PathIsFile(Path.of("/bin/ls"));
}
protected PathIsFile findQemu(String bin) {
if (OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS) {
return new PathIsFile(Path.of("C:\\msys64\\ucrt64\bin\\").resolve(bin));
}
return new PathIsFile(Path.of(bin));
}
protected PathIsFile createArmElfImage() throws Exception {
assumeTrue(OperatingSystem.LINUX == OperatingSystem.CURRENT_OPERATING_SYSTEM);
Path tempSrc = Files.createTempFile("hw", ".c");
Path tempObj = Files.createTempFile("hw", ".o");
Path tempImg = Files.createTempFile("hw", "");
try (OutputStream os = new FileOutputStream(tempSrc.toFile())) {
os.write("""
int main() {
return 0;
}
""".getBytes());
}
new ProcessBuilder().command(
"arm-linux-eabi-gcc", "-c",
"-o", tempObj.toAbsolutePath().toString(),
tempSrc.toAbsolutePath().toString()).inheritIO().start().waitFor();
new ProcessBuilder().command(
"arm-linux-eabi-ld",
"-o", tempImg.toAbsolutePath().toString(),
tempObj.toAbsolutePath().toString()).inheritIO().start().waitFor();
return new PathIsFile(tempImg);
}
protected PathIsFile createDummyQemuImage() throws Exception {
Path temp = Files.createTempFile("qemudummy", ".bin");
try (OutputStream os = new FileOutputStream(temp.toFile())) {
os.write(new byte[4096]);
}
return new PathIsFile(temp);
}
protected LaunchResult doLaunch(String title, Map<String, Object> args) {
TraceRmiLaunchOffer offer = Unique.assertOne(
launchService.getOffers(program).stream().filter(o -> o.getTitle().equals(title)));
return offer.launchProgram(monitor, new LaunchConfigurator() {
@Override
public Map<String, ValStr<?>> configureLauncher(TraceRmiLaunchOffer offer,
Map<String, ValStr<?>> arguments, RelPrompt relPrompt) {
Map<String, ValStr<?>> newArgs = new HashMap<>(arguments);
for (Map.Entry<String, Object> ent : args.entrySet()) {
newArgs.put(ent.getKey(), ValStr.from(ent.getValue()));
}
return newArgs;
}
@Override
public PromptMode getPromptMode() {
return title.contains("ssh") ? PromptMode.ALWAYS : PromptMode.NEVER;
}
});
}
protected void checkResult(LaunchResult result) {
if (result.exception() != null &&
!(result.exception() instanceof NoStaticMappingException)) {
throw new AssertionError(result);
}
}
/**
* This also doesn't quite work correctly on Windows. The prompt appears, but the user is not
* allowed to answer the question before the next lldb script command is run, which finds the
* package missing and exits with code 253. May just have to cut losses there. The message hits
* the screen, and this circumstance <em>should</em> be rare.
*
* @throws Exception
*/
@Test
public void testLocalLldbSetup() throws Exception {
new ProcessBuilder().command("python", "-m", "pip", "install", "protobuf==3.19.0")
.inheritIO()
.start()
.waitFor();
try (LaunchResult result = doLaunch("lldb", Map.of("arg:1", chooseImage()))) {
assertTrue(result.exception() instanceof SocketTimeoutException);
TerminalSession term = Unique.assertOne(result.sessions().values());
while (!term.isTerminated()) {
Thread.sleep(1000);
}
}
try (LaunchResult result = doLaunch("lldb", Map.of("arg:1", chooseImage()))) {
checkResult(result);
}
}
@Test
public void testLocalLldbWithImage() throws Exception {
try (LaunchResult result = doLaunch("lldb", Map.ofEntries(
Map.entry("arg:1", chooseImage()),
Map.entry("env:OPT_START_CMD", "process launch --stop-at-entry")))) {
checkResult(result);
}
}
@Test
@Ignore("TODO")
public void testLldbQemuUser() throws Exception {
assumeFalse(OperatingSystem.WINDOWS == OperatingSystem.CURRENT_OPERATING_SYSTEM);
PathIsFile image = createArmElfImage();
program = AutoImporter.importByUsingBestGuess(image.path().toFile(), null, "/", this,
new MessageLog(), monitor).getPrimaryDomainObject();
programManager.openProgram(program);
try (LaunchResult result = doLaunch("lldb + qemu", Map.ofEntries(
Map.entry("arg:1", image),
Map.entry("env:OPT_LLDB_PATH", new PathIsFile(Path.of("lldb"))),
Map.entry("env:GHIDRA_LANG_EXTTOOL_qemu_system", findQemu("qemu-arm")),
Map.entry("env:OPT_PULL_ALL_SECTIONS", true)))) {
checkResult(result);
}
}
@Test
@Ignore("TODO")
public void testLldbQemuSys() throws Exception {
autoMappingService
.setAutoMapSpec(AutoMapSpec.fromConfigName(BySectionAutoMapSpec.CONFIG_NAME));
PathIsFile dummy = createDummyQemuImage();
createProgram();
try (Transaction tx = program.openTransaction("Set name")) {
program.setName(dummy.toString());
}
programManager.openProgram(program);
try (LaunchResult result = doLaunch("lldb + qemu-system", Map.ofEntries(
Map.entry("arg:1", dummy),
Map.entry("env:OPT_LLDB_PATH", new PathIsFile(Path.of("lldb"))),
Map.entry("env:GHIDRA_LANG_EXTTOOL_qemu_system", findQemu("qemu-system-aarch64")),
Map.entry("env:OPT_EXTRA_QEMU_ARGS", "-machine virt")))) {
checkResult(result);
}
}
/**
* This has proven difficult to test on Windows, probably because the version of lldb and
* gdbserver I'm using are not compatible?
*
* @throws Exception
*/
@Test
public void testLldbRemoteGdb() throws Exception {
PathIsFile target = chooseImage();
try (
DummyProc gdbServer =
DummyProc.run("gdbserver", ":9999", target.path().toAbsolutePath().toString());
LaunchResult result = doLaunch("lldb remote (gdb)", Map.ofEntries(
Map.entry("arg:1", target),
Map.entry("OPT_HOST", "localhost"),
Map.entry("OPT_PORT", 9999)))) {
checkResult(result);
}
}
@Test
public void testLldbViaSsh() throws Exception {
try (LaunchResult result = doLaunch("lldb via ssh", Map.ofEntries(
Map.entry("arg:1", "/bin/ls"),
Map.entry("OPT_HOST", "localhost")))) {
checkResult(result);
}
}
@Test
public void testLldbViaSshSetupGhidraLldb() throws Exception {
// This only applies if we leave localhost in the dialog
new ProcessBuilder().command("python", "-m", "pip", "uninstall", "ghidralldb")
.inheritIO()
.start()
.waitFor();
try (LaunchResult result = doLaunch("lldb via ssh", Map.ofEntries(
Map.entry("arg:1", "/bin/ls"),
Map.entry("OPT_HOST", "localhost")))) {
assertTrue(result.exception() instanceof SocketTimeoutException);
TerminalSession term = Unique.assertOne(result.sessions().values());
while (!term.isTerminated()) {
Thread.sleep(1000);
}
}
try (LaunchResult result = doLaunch("lldb via ssh", Map.ofEntries(
Map.entry("arg:1", "/bin/ls"),
Map.entry("OPT_HOST", "localhost")))) {
checkResult(result);
}
}
@Test
public void testLldbViaSshSetupProtobuf() throws Exception {
new ProcessBuilder().command("python", "-m", "pip", "install", "protobuf==3.19.0")
.inheritIO()
.start()
.waitFor();
try (LaunchResult result = doLaunch("lldb via ssh", Map.ofEntries(
Map.entry("arg:1", "/bin/ls"),
Map.entry("OPT_HOST", "localhost")))) {
assertTrue(result.exception() instanceof SocketTimeoutException);
TerminalSession term = Unique.assertOne(result.sessions().values());
while (!term.isTerminated()) {
Thread.sleep(1000);
}
}
try (LaunchResult result = doLaunch("lldb via ssh", Map.ofEntries(
Map.entry("arg:1", "/bin/ls"),
Map.entry("OPT_HOST", "localhost")))) {
checkResult(result);
}
}
}