mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-02-06 05:21:49 +08:00
Merge remote-tracking branch 'origin/GP-6374_d-millar_handlers_for_dbgeng'
This commit is contained in:
@@ -1068,6 +1068,10 @@ def put_single_breakpoint(bp, ibobj, nproc: int, ikeys: List[str]) -> None:
|
||||
tid = "%04x" % tid
|
||||
except exception.E_NOINTERFACE_Error:
|
||||
tid = "****"
|
||||
try:
|
||||
handler = util.BPT_HANDLERS[bp.GetId()]
|
||||
except Exception:
|
||||
handler = ""
|
||||
|
||||
if bp.GetType()[0] == DbgEng.DEBUG_BREAKPOINT_DATA:
|
||||
width, prot = bp.GetDataParameters()
|
||||
@@ -1103,6 +1107,8 @@ def put_single_breakpoint(bp, ibobj, nproc: int, ikeys: List[str]) -> None:
|
||||
brkobj.set_value('Flags', bp.GetFlags())
|
||||
if tid != None:
|
||||
brkobj.set_value('Match TID', tid)
|
||||
if handler != None:
|
||||
brkobj.set_value('Handler', handler)
|
||||
brkobj.set_value('Command', bp.GetCommand())
|
||||
brkobj.insert()
|
||||
|
||||
@@ -1531,6 +1537,11 @@ def put_single_exception(obj: TraceObject, objpath: str,
|
||||
exc_cmd2 = util.GetExceptionFilterSecondCommand(
|
||||
offset + index, p.SecondCommandSize)
|
||||
exc_code = hex(p.ExceptionCode)
|
||||
try:
|
||||
util.EXC_CODES[index] = exc_code
|
||||
handler = util.EXC_HANDLERS[exc_code]
|
||||
except Exception:
|
||||
handler = ""
|
||||
obj.set_value('Code', exc_code)
|
||||
trace = STATE.require_trace()
|
||||
contobj = trace.create_object(objpath+".Cont")
|
||||
@@ -1545,6 +1556,8 @@ def put_single_exception(obj: TraceObject, objpath: str,
|
||||
obj.set_value('Cmd', exc_cmd)
|
||||
if exc_cmd2 is not None:
|
||||
obj.set_value('Cmd2', exc_cmd2)
|
||||
if handler is not None:
|
||||
obj.set_value('Handler', handler)
|
||||
obj.set_value('_display', "{} {} [{}]".format(index, exc_name, exc_code))
|
||||
obj.insert()
|
||||
|
||||
|
||||
@@ -382,6 +382,7 @@ def on_cont(*args) -> None:
|
||||
|
||||
|
||||
def on_stop(*args) -> None:
|
||||
# print("ON STOP")
|
||||
proc = util.selected_process()
|
||||
if proc not in PROC_STATE:
|
||||
return
|
||||
@@ -505,12 +506,28 @@ def on_breakpoint_deleted(bpid) -> None:
|
||||
@log_errors
|
||||
def on_breakpoint_hit(*args) -> None:
|
||||
# print("ON_BREAKPOINT_HIT: args={}".format(args))
|
||||
id = util.get_breakpoint_id(args[0])
|
||||
if id in util.BPT_HANDLERS:
|
||||
try:
|
||||
handler = util.BPT_HANDLERS[id]
|
||||
func = globals()[handler]
|
||||
func(*args)
|
||||
except Exception as e:
|
||||
print(f"Error in breakpoint handler: {e}")
|
||||
return DbgEng.DEBUG_STATUS_NO_CHANGE
|
||||
|
||||
|
||||
@log_errors
|
||||
def on_exception(*args) -> None:
|
||||
# print("ON_EXCEPTION: args={}".format(args))
|
||||
id = str(hex(args[0][0].ExceptionCode))
|
||||
if id in util.EXC_HANDLERS:
|
||||
try:
|
||||
handler = util.EXC_HANDLERS[id]
|
||||
func = globals()[handler]
|
||||
func(*args)
|
||||
except Exception as e:
|
||||
print(f"Error in exception handler: {e}")
|
||||
return DbgEng.DEBUG_STATUS_NO_CHANGE
|
||||
|
||||
|
||||
|
||||
@@ -321,6 +321,14 @@ class ExceptionContainer(TraceObject):
|
||||
pass
|
||||
|
||||
|
||||
class Event(TraceObject):
|
||||
pass
|
||||
|
||||
|
||||
class Exception(TraceObject):
|
||||
pass
|
||||
|
||||
|
||||
class ContinueOption(TraceObject):
|
||||
pass
|
||||
|
||||
@@ -865,5 +873,49 @@ def refresh_trace_events_custom(node: State,
|
||||
commands.ghidra_trace_put_trace_events_custom(prefix, cmd)
|
||||
|
||||
|
||||
@REGISTRY.method(action='add_handler', display='Add Handler')
|
||||
def add_handler_breakpoint(node: BreakpointSpec, handler: str) -> None:
|
||||
"""
|
||||
Add python handler
|
||||
"""
|
||||
mat = PROC_BREAKBPT_PATTERN.fullmatch(node.path)
|
||||
if mat is None:
|
||||
raise TypeError(f"{node} is not {err_msg}")
|
||||
bptnum = int(mat['breaknum'])
|
||||
with commands.open_tracked_tx('Add Exception Handler'):
|
||||
util.BPT_HANDLERS[bptnum] = handler
|
||||
commands.ghidra_trace_put_breakpoints()
|
||||
|
||||
|
||||
@REGISTRY.method(action='add_handler', display='Add Handler')
|
||||
def add_handler_exception(node: Exception, handler: str) -> None:
|
||||
"""
|
||||
Add python handler
|
||||
"""
|
||||
mat = PROC_EXCEPTION_PATTERN.fullmatch(node.path)
|
||||
if mat is None:
|
||||
raise TypeError(f"{node} is not {err_msg}")
|
||||
excnum = int(mat['excnum'])
|
||||
with commands.open_tracked_tx('Add Exception Handler'):
|
||||
exc_code = util.EXC_CODES[excnum]
|
||||
util.EXC_HANDLERS[exc_code] = handler
|
||||
commands.ghidra_trace_put_exceptions()
|
||||
|
||||
|
||||
# TODO?
|
||||
# @REGISTRY.method(action='add_handler', display='Add Handler')
|
||||
# def add_handler_event(node: Event, handler: str) -> None:
|
||||
# """
|
||||
# Add python handler
|
||||
# """
|
||||
# mat = PROC_EVENT_PATTERN.fullmatch(node.path)
|
||||
# if mat is None:
|
||||
# raise TypeError(f"{node} is not {err_msg}")
|
||||
# evtnum = int(mat['eventnum'])
|
||||
# with commands.open_tracked_tx('Add Event Handler'):
|
||||
# util.EVT_HANDLERS[evtnum] = handler
|
||||
# commands.ghidra_trace_put_events()
|
||||
|
||||
|
||||
def dbg():
|
||||
return util.dbg._base
|
||||
|
||||
@@ -44,12 +44,17 @@ from pybag.dbgeng import core as DbgEng # type: ignore
|
||||
from pybag.dbgeng import exception # type: ignore
|
||||
from pybag.dbgeng import util as DbgUtil # type: ignore
|
||||
from pybag.dbgeng.callbacks import DbgEngCallbacks # type: ignore
|
||||
from pybag.dbgeng.idebugbreakpoint import DebugBreakpoint # type: ignore
|
||||
from pybag.dbgeng.idebugclient import DebugClient # type: ignore
|
||||
|
||||
DESCRIPTION_PATTERN = '[{major:X}:{minor:X}] {type}'
|
||||
|
||||
DbgVersion = namedtuple('DbgVersion', ['full', 'name', 'dotted', 'arch'])
|
||||
|
||||
BPT_HANDLERS: Dict[int, str] = {}
|
||||
EXC_CODES: Dict[int, str] = {}
|
||||
EXC_HANDLERS: Dict[str, str] = {}
|
||||
EVT_HANDLERS: Dict[int, str] = {}
|
||||
|
||||
class StdInputCallbacks(CoClass):
|
||||
# This is the UUID listed for IDebugInputCallbacks in DbgEng.h
|
||||
@@ -501,6 +506,12 @@ def get_breakpoints() -> Iterable[Tuple[str, str, str, str, str]]:
|
||||
return zip(offset_set, expr_set, prot_set, width_set, stat_set)
|
||||
|
||||
|
||||
@dbg.eng_thread
|
||||
def get_breakpoint_id(bp: DbgEng.IDebugBreakpoint) -> int:
|
||||
bpt = DebugBreakpoint(bp)
|
||||
return bpt.GetId()
|
||||
|
||||
|
||||
@dbg.eng_thread
|
||||
def selected_process() -> int:
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user