mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-22 04:05:39 +00:00
GP-4441: new option for target remote
GP-4441: post-review edits GP-4441: first pass GP-4441: working remote gdb/lldbGP-4441: updated via 4437GP-4441: embedded updatesGP-4441: set arch conditionally
This commit is contained in:
parent
f034eca003
commit
918d38c468
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
## ###
|
||||
# IP: GHIDRA
|
||||
#
|
||||
@ -30,9 +30,11 @@
|
||||
#@menu-group remote
|
||||
#@icon icon.debugger
|
||||
#@help TraceRmiLauncherServicePlugin#gdb
|
||||
#@arg :str "Image" "The target binary executable image on the remote system"
|
||||
#@enum TargetType:str remote extended-remote
|
||||
#@env OPT_TARGET_TYPE:TargetType="remote" "Target" "The type of remote 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 (optional)" "Target architecture override"
|
||||
#@env OPT_GDB_PATH:str="gdb" "Path to gdb" "The path to gdb on the local system. Omit the full path to resolve using the system PATH."
|
||||
|
||||
if [ -d ${GHIDRA_HOME}/ghidra/.git ]
|
||||
@ -48,13 +50,21 @@ else
|
||||
export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/pypkg/src:$PYTHONPATH
|
||||
fi
|
||||
|
||||
if [ -z "$OPT_ARCH" ]
|
||||
then
|
||||
archcmd=
|
||||
else
|
||||
archcmd=-ex "set arch $OPT_ARCH"
|
||||
fi
|
||||
|
||||
"$OPT_GDB_PATH" \
|
||||
-q \
|
||||
-ex "set pagination off" \
|
||||
-ex "set confirm off" \
|
||||
-ex "show version" \
|
||||
-ex "python import ghidragdb" \
|
||||
-ex "target remote $OPT_HOST:$OPT_PORT" \
|
||||
$archcmd \
|
||||
-ex "target $OPT_TARGET_TYPE $OPT_HOST:$OPT_PORT" \
|
||||
-ex "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \
|
||||
-ex "ghidra trace start" \
|
||||
-ex "ghidra trace sync-enable" \
|
||||
|
@ -1524,7 +1524,7 @@ def ghidra_trace_sync_synth_stopped(*, is_mi, **kwargs):
|
||||
"""
|
||||
|
||||
hooks.on_stop(object()) # Pass a fake event
|
||||
|
||||
|
||||
|
||||
@cmd('ghidra util wait-stopped', '-ghidra-util-wait-stopped', gdb.COMMAND_NONE, False)
|
||||
def ghidra_util_wait_stopped(timeout='1', *, is_mi, **kwargs):
|
||||
|
@ -541,18 +541,18 @@ def install_hooks():
|
||||
HOOK_STATE.mem_catchpoint.enabled = True
|
||||
else:
|
||||
breaks_before = set(gdb.breakpoints())
|
||||
gdb.execute("""
|
||||
catch syscall group:memory
|
||||
commands
|
||||
silent
|
||||
hooks-ghidra event-memory
|
||||
cont
|
||||
end
|
||||
""")
|
||||
bpts = gdb.breakpoints()
|
||||
# NB: this is unnecessary for gdb 11+
|
||||
if len(bpts) > 0:
|
||||
HOOK_STATE.mem_catchpoint = (set(bpts) - breaks_before).pop()
|
||||
try:
|
||||
gdb.execute("""
|
||||
catch syscall group:memory
|
||||
commands
|
||||
silent
|
||||
hooks-ghidra event-memory
|
||||
cont
|
||||
end
|
||||
""")
|
||||
HOOK_STATE.mem_catchpoint = (set(gdb.breakpoints()) - breaks_before).pop()
|
||||
except Exception as e:
|
||||
print(f"Error setting memory catchpoint: {e}")
|
||||
|
||||
gdb.events.cont.connect(on_cont)
|
||||
gdb.events.stop.connect(on_stop)
|
||||
|
@ -74,7 +74,7 @@ THREADS_PATTERN = extre(INFERIOR_PATTERN, '\.Threads')
|
||||
THREAD_PATTERN = extre(THREADS_PATTERN, '\[(?P<tnum>\\d*)\]')
|
||||
STACK_PATTERN = extre(THREAD_PATTERN, '\.Stack')
|
||||
FRAME_PATTERN = extre(STACK_PATTERN, '\[(?P<level>\\d*)\]')
|
||||
REGS_PATTERN = extre(FRAME_PATTERN, '.Registers')
|
||||
REGS_PATTERN = extre(FRAME_PATTERN, '\.Registers')
|
||||
MEMORY_PATTERN = extre(INFERIOR_PATTERN, '\.Memory')
|
||||
MODULES_PATTERN = extre(INFERIOR_PATTERN, '\.Modules')
|
||||
MODULE_PATTERN = extre(MODULES_PATTERN, '\[(?P<modname>.*)\]')
|
||||
|
67
Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/remote-lldb.sh
Executable file
67
Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/remote-lldb.sh
Executable file
@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env bash
|
||||
## ###
|
||||
# IP: GHIDRA
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
##
|
||||
#@title remote 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>This will start <tt>lldb</tt> on the local system and then use it to connect to the remote system.
|
||||
#@desc The actual command used is, e.g:</p>
|
||||
#@desc <pre>gdb-remote host:port</pre>
|
||||
#@desc <p>It may be worth testing this manually to ensure everything is configured correctly.
|
||||
#@desc LLDB must be installed on your local system, it must be compatible with the remote system,
|
||||
#@desc and it must embed the Python 3 interpreter. You will also need <tt>protobuf</tt> installed
|
||||
#@desc for Python 3 on the local system. There are no Python requirements for the remote system.
|
||||
#@desc Please ensure that Ghidra's current program and the target's image match. Otherwise, the
|
||||
#@desc modules may not map.</p>
|
||||
#@desc </body></html>
|
||||
#@menu-group remote
|
||||
#@icon icon.debugger
|
||||
#@help TraceRmiLauncherServicePlugin#lldb
|
||||
#@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:str="lldb" "Path to lldb" "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
|
||||
|
||||
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" \
|
||||
$archcmd \
|
||||
-o "gdb-remote $OPT_HOST:$OPT_PORT" \
|
||||
-o "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \
|
||||
-o "ghidra trace start" \
|
||||
-o "ghidra trace sync-enable" \
|
||||
-o "ghidra trace sync-synth-stopped"
|
||||
|
@ -22,18 +22,93 @@ from . import util
|
||||
# NOTE: This map is derived from the ldefs using a script
|
||||
language_map = {
|
||||
'aarch64': ['AARCH64:BE:64:v8A', 'AARCH64:LE:64:AppleSilicon', 'AARCH64:LE:64:v8A'],
|
||||
'arm': ['ARM:BE:32:v8', 'ARM:BE:32:v8T', 'ARM:LE:32:v8', 'ARM:LE:32:v8T'],
|
||||
'armv4': ['ARM:BE:32:v4', 'ARM:LE:32:v4'],
|
||||
'armv4t': ['ARM:BE:32:v4t', 'ARM:LE:32:v4t'],
|
||||
'armv5': ['ARM:BE:32:v5', 'ARM:LE:32:v5'],
|
||||
'armv5e': ['ARM:BE:32:v5t', 'ARM:LE:32:v5t'],
|
||||
'armv5t': ['ARM:BE:32:v5t', 'ARM:LE:32:v5t'],
|
||||
'armv6': ['ARM:BE:32:v6', 'ARM:LE:32:v6'],
|
||||
'armv6m': ['ARM:BE:32:Cortex', 'ARM:LE:32:Cortex'],
|
||||
'armv7': ['ARM:BE:32:v7', 'ARM:LE:32:v7'],
|
||||
'armv7k': ['ARM:BE:32:v7', 'ARM:LE:32:v7'],
|
||||
'armv7l': ['ARM:BE:32:v7', 'ARM:LE:32:v7'],
|
||||
'armv7f': ['ARM:BE:32:v7', 'ARM:LE:32:v7'],
|
||||
'armv7s': ['ARM:BE:32:v7', 'ARM:LE:32:v7'],
|
||||
'arm64': ['AARCH64:BE:64:v8A', 'AARCH64:LE:64:v8A'],
|
||||
'arm64_32': ['ARM:BE:32:v8', 'ARM:LE:32:v8'],
|
||||
'arm64e': ['AARCH64:BE:64:v8A', 'AARCH64:LE:64:v8A'],
|
||||
'i386': ['x86:LE:32:default'],
|
||||
'armv7k': ['ARM:BE:32:v7', 'ARM:LE:32:v7'],
|
||||
'armv7m': ['ARM:BE:32:v7', 'ARM:LE:32:v7'],
|
||||
'armv7em': ['ARM:BE:32:Cortex', 'ARM:LE:32:Cortex'],
|
||||
'xscale': ['ARM:BE:32:v6', 'ARM:LE:32:v6'],
|
||||
'thumbv5': ['ARM:BE:32:v5', 'ARM:LE:32:v5'],
|
||||
'thumbv5e': ['ARM:BE:32:v5', 'ARM:LE:32:v5'],
|
||||
'thumbv6': ['ARM:BE:32:v6', 'ARM:LE:32:v6'],
|
||||
'thumbv6m': ['ARM:BE:32:Cortex', 'ARM:LE:32:Cortex'],
|
||||
'thumbv7': ['ARM:BE:32:v7', 'ARM:LE:32:v7'],
|
||||
'thumbv7k': ['ARM:BE:32:v7', 'ARM:LE:32:v7'],
|
||||
'thumbv7f': ['ARM:BE:32:v7', 'ARM:LE:32:v7'],
|
||||
'thumbv7s': ['ARM:BE:32:v7', 'ARM:LE:32:v7'],
|
||||
'thumbv7k': ['ARM:BE:32:v7', 'ARM:LE:32:v7'],
|
||||
'thumbv7m': ['ARM:BE:32:v7', 'ARM:LE:32:v7'],
|
||||
'thumbv7em': ['ARM:BE:32:Cortex', 'ARM:LE:32:Cortex'],
|
||||
'armv8': ['ARM:BE:32:v8', 'ARM:LE:32:v8'],
|
||||
'armv8l': ['ARM:BE:32:v8', 'ARM:LE:32:v8'],
|
||||
'arm64': ['ARM:BE:64:v8', 'ARM:LE:64:v8'],
|
||||
'arm64e': ['ARM:BE:64:v8', 'ARM:LE:64:v8'],
|
||||
'arm64_32': ['ARM:BE:32:v8', 'ARM:LE:32:v8'],
|
||||
'mips': ['MIPS:BE:32:default', 'MIPS:LE:32:default'],
|
||||
'mipsr2': ['MIPS:BE:32:default', 'MIPS:LE:32:default'],
|
||||
'mipsr3': ['MIPS:BE:32:default', 'MIPS:LE:32:default'],
|
||||
'mipsr5': ['MIPS:BE:32:default', 'MIPS:LE:32:default'],
|
||||
'mipsr6': ['MIPS:BE:32:default', 'MIPS:LE:32:default'],
|
||||
'mipsel': ['MIPS:BE:32:default', 'MIPS:LE:32:default'],
|
||||
'mipsr2el': ['MIPS:BE:32:default', 'MIPS:LE:32:default'],
|
||||
'mipsr3el': ['MIPS:BE:32:default', 'MIPS:LE:32:default'],
|
||||
'mipsr5el': ['MIPS:BE:32:default', 'MIPS:LE:32:default'],
|
||||
'mipsr6el': ['MIPS:BE:32:default', 'MIPS:LE:32:default'],
|
||||
'mips64': ['MIPS:BE:3264:default', 'MIPS:LE:64:default'],
|
||||
'mips64r2': ['MIPS:BE:64:default', 'MIPS:LE:64:default'],
|
||||
'mips64r3': ['MIPS:BE:64:default', 'MIPS:LE:64:default'],
|
||||
'mips64r5': ['MIPS:BE:64:default', 'MIPS:LE:64:default'],
|
||||
'mips64r6': ['MIPS:BE:64:default', 'MIPS:LE:64:default'],
|
||||
'mips64el': ['MIPS:BE:64:default', 'MIPS:LE:64:default'],
|
||||
'mips64r2el': ['MIPS:BE:64:default', 'MIPS:LE:64:default'],
|
||||
'mips64r3el': ['MIPS:BE:64:default', 'MIPS:LE:64:default'],
|
||||
'mips64r5el': ['MIPS:BE:64:default', 'MIPS:LE:64:default'],
|
||||
'mips64r6el': ['MIPS:BE:64:default', 'MIPS:LE:64:default'],
|
||||
'msp:430X': ['TI_MSP430:LE:16:default'],
|
||||
'powerpc': ['PowerPC:BE:32:4xx', 'PowerPC:LE:32:4xx'],
|
||||
'ppc601': ['PowerPC:BE:32:4xx', 'PowerPC:LE:32:4xx'],
|
||||
'ppc602': ['PowerPC:BE:32:4xx', 'PowerPC:LE:32:4xx'],
|
||||
'ppc603': ['PowerPC:BE:32:4xx', 'PowerPC:LE:32:4xx'],
|
||||
'ppc603e': ['PowerPC:BE:32:4xx', 'PowerPC:LE:32:4xx'],
|
||||
'ppc603ev': ['PowerPC:BE:32:4xx', 'PowerPC:LE:32:4xx'],
|
||||
'ppc604': ['PowerPC:BE:32:4xx', 'PowerPC:LE:32:4xx'],
|
||||
'ppc604e': ['PowerPC:BE:32:4xx', 'PowerPC:LE:32:4xx'],
|
||||
'ppc620': ['PowerPC:BE:32:4xx', 'PowerPC:LE:32:4xx'],
|
||||
'ppc750': ['PowerPC:BE:32:4xx', 'PowerPC:LE:32:4xx'],
|
||||
'ppc7400': ['PowerPC:BE:32:4xx', 'PowerPC:LE:32:4xx'],
|
||||
'ppc7450': ['PowerPC:BE:32:4xx', 'PowerPC:LE:32:4xx'],
|
||||
'ppc970': ['PowerPC:BE:32:4xx', 'PowerPC:LE:32:4xx'],
|
||||
'powerpc64': ['PowerPC:BE:64:4xx', 'PowerPC:LE:64:4xx'],
|
||||
'powerpc64le': ['PowerPC:BE:64:4xx', 'PowerPC:LE:64:4xx'],
|
||||
'ppc970-64': ['PowerPC:BE:64:4xx', 'PowerPC:LE:64:4xx'],
|
||||
's390x': [],
|
||||
'sparc': ['sparc:BE:32:default', 'sparc:BE:64:default'],
|
||||
'sparcv9': ['sparc:BE:32:default', 'sparc:BE:64:default'],
|
||||
'i386': ['x86:LE:32:default'],
|
||||
'i486': ['x86:LE:32:default'],
|
||||
'i486sx': ['x86:LE:32:default'],
|
||||
'i686': ['x86:LE:64:default'],
|
||||
'x86_64': ['x86:LE:64:default'],
|
||||
'wasm32': ['x86:LE:64:default'],
|
||||
'x86_64h': ['x86:LE:64:default'],
|
||||
'hexagon': [],
|
||||
'hexagonv4': [],
|
||||
'hexagonv5': [],
|
||||
'riscv32': ['RISCV:LE:32:RV32G', 'RISCV:LE:32:RV32GC', 'RISCV:LE:32:RV32I', 'RISCV:LE:32:RV32IC', 'RISCV:LE:32:RV32IMC', 'RISCV:LE:32:default'],
|
||||
'riscv64': ['RISCV:LE:64:RV64G', 'RISCV:LE:64:RV64GC', 'RISCV:LE:64:RV64I', 'RISCV:LE:64:RV64IC', 'RISCV:LE:64:default'],
|
||||
'unknown-mach-32': ['DATA:LE:32:default', 'DATA:LE:32:default'],
|
||||
'unknown-mach-64': ['DATA:LE:64:default', 'DATA:LE:64:default'],
|
||||
'arc': [],
|
||||
'avr': ['avr8:LE:24:xmega'],
|
||||
'wasm32': ['x86:LE:32:default'],
|
||||
}
|
||||
|
||||
data64_compiler_map = {
|
||||
@ -52,6 +127,8 @@ default_compiler_map = {
|
||||
'windows': 'Visual Studio',
|
||||
# This may seem wrong, but Ghidra cspecs really describe the ABI
|
||||
'Cygwin': 'Visual Studio',
|
||||
'default': 'default',
|
||||
'unknown': 'gcc',
|
||||
}
|
||||
|
||||
compiler_map = {
|
||||
@ -97,8 +174,8 @@ def get_osabi():
|
||||
# thing on that line. ("auto" may appear earlier on the line.)
|
||||
triple = util.get_target().triple
|
||||
# this is an unfortunate feature of the tests
|
||||
if triple is None:
|
||||
return "linux"
|
||||
if triple is None or '-' not in triple:
|
||||
return "default"
|
||||
return triple.split('-')[2]
|
||||
|
||||
|
||||
|
@ -220,6 +220,8 @@ elif lldb.debugger:
|
||||
'command script add -f ghidralldb.commands.ghidra_trace_sync_enable ghidra trace sync-enable')
|
||||
lldb.debugger.HandleCommand(
|
||||
'command script add -f ghidralldb.commands.ghidra_trace_sync_disable ghidra trace sync-disable')
|
||||
lldb.debugger.HandleCommand(
|
||||
'command script add -f ghidralldb.commands.ghidra_trace_sync_synth_stopped ghidra trace sync-synth-stopped')
|
||||
lldb.debugger.HandleCommand(
|
||||
'command script add -f ghidralldb.commands.ghidra_util_mark _mark_')
|
||||
#lldb.debugger.HandleCommand('target stop-hook add -P ghidralldb.hooks.StopHook')
|
||||
@ -1581,6 +1583,18 @@ def ghidra_trace_sync_disable(debugger, command, result, internal_dict):
|
||||
hooks.disable_current_process()
|
||||
|
||||
|
||||
@convert_errors
|
||||
def ghidra_trace_sync_synth_stopped(debugger, command, result, internal_dict):
|
||||
"""
|
||||
Act as though the target has just stopped.
|
||||
|
||||
This may need to be invoked immediately after 'ghidra trace sync-enable',
|
||||
to ensure the first snapshot displays the initial/current target state.
|
||||
"""
|
||||
|
||||
hooks.on_stop(None) # Pass a fake event
|
||||
|
||||
|
||||
@convert_errors
|
||||
def ghidra_util_wait_stopped(debugger, command, result, internal_dict):
|
||||
"""
|
||||
|
@ -67,8 +67,11 @@ class ProcessState(object):
|
||||
hashable_frame = (thread.GetThreadID(), frame.GetFrameID())
|
||||
if first or hashable_frame not in self.visited:
|
||||
banks = frame.GetRegisters()
|
||||
commands.putreg(frame, banks.GetFirstValueByName(
|
||||
commands.DEFAULT_REGISTER_BANK))
|
||||
primary = banks.GetFirstValueByName(commands.DEFAULT_REGISTER_BANK)
|
||||
if primary.value is None:
|
||||
primary = banks[0]
|
||||
commands.DEFAULT_REGISTER_BANK = primary.name
|
||||
commands.putreg(frame, primary)
|
||||
commands.putmem("$pc", "1", result=None)
|
||||
commands.putmem("$sp", "1", result=None)
|
||||
self.visited.add(hashable_frame)
|
||||
@ -473,7 +476,7 @@ def on_cont(event):
|
||||
|
||||
|
||||
def on_stop(event):
|
||||
proc = lldb.SBProcess.GetProcessFromEvent(event)
|
||||
proc = lldb.SBProcess.GetProcessFromEvent(event) if event is not None else util.get_process()
|
||||
if proc.GetProcessID() not in PROC_STATE:
|
||||
print("not in state")
|
||||
return
|
||||
|
@ -73,7 +73,7 @@ def find_proc_by_pattern(object, pattern, err_msg):
|
||||
|
||||
|
||||
def find_proc_by_obj(object):
|
||||
return find_proc_by_pattern(object, PROCESS_PATTERN, "an Process")
|
||||
return find_proc_by_pattern(object, PROCESS_PATTERN, "a Process")
|
||||
|
||||
|
||||
def find_proc_by_procbreak_obj(object):
|
||||
|
@ -426,6 +426,9 @@
|
||||
<attribute name="Floating Point Registers" schema="RegisterBank" />
|
||||
<attribute name="Advanced Vector Extensions" schema="RegisterBank" />
|
||||
<attribute name="Memory Protection Extensions" schema="RegisterBank" />
|
||||
<attribute name="float" schema="RegisterBank" />
|
||||
<attribute name="general" schema="RegisterBank" />
|
||||
<attribute name="system" schema="RegisterBank" />
|
||||
<attribute name="_descriptions" schema="RegisterValueContainer" />
|
||||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
|
Loading…
Reference in New Issue
Block a user