GP-4732: from the demo (lol)

GP-4732: frome review
GP-4732: working until we step
GP-4732: manifestGP-4732: works, except for resumeGP-4732: successGP-4732: frome review
This commit is contained in:
d-millar 2025-01-30 12:57:47 -05:00
parent e0fd708d30
commit 05ed589fa0
10 changed files with 272 additions and 67 deletions

View file

@ -162,7 +162,7 @@ def log_errors(func):
@log_errors
def on_state_changed(*args):
# print("ON_STATE_CHANGED")
# print("ON_STATE_CHANGED")
# print(args)
if args[0] == DbgEng.DEBUG_CES_CURRENT_THREAD:
return on_thread_selected(args)
@ -176,7 +176,7 @@ def on_state_changed(*args):
proc = util.selected_process()
if args[1] & DbgEng.DEBUG_STATUS_INSIDE_WAIT:
if proc in PROC_STATE:
# Process may have exited (so deleted) first
# Process may have exited (so deleted) first
PROC_STATE[proc].waiting = True
return S_OK
if proc in PROC_STATE:
@ -482,28 +482,45 @@ def on_exception(*args):
@util.dbg.eng_thread
def install_hooks():
# print("Installing hooks")
if HOOK_STATE.installed:
return
HOOK_STATE.installed = True
# print("Installing hooks")
if HOOK_STATE.installed:
return
HOOK_STATE.installed = True
events = util.dbg._base.events
events = util.dbg._base.events
if util.is_remote():
events.engine_state(handler=on_state_changed_async)
events.debuggee_state(handler=on_debuggee_changed_async)
events.session_status(handler=on_session_status_changed_async)
events.symbol_state(handler=on_symbol_state_changed_async)
events.system_error(handler=on_system_error_async)
events.engine_state(handler=on_state_changed)
events.debuggee_state(handler=on_debuggee_changed)
events.session_status(handler=on_session_status_changed)
events.symbol_state(handler=on_symbol_state_changed)
events.system_error(handler=on_system_error)
events.create_process(handler=on_new_process_async)
events.exit_process(handler=on_process_deleted_async)
events.create_thread(handler=on_threads_changed_async)
events.exit_thread(handler=on_threads_changed_async)
events.module_load(handler=on_modules_changed_async)
events.unload_module(handler=on_modules_changed_async)
events.create_process(handler=on_new_process)
events.exit_process(handler=on_process_deleted)
events.create_thread(handler=on_threads_changed)
events.exit_thread(handler=on_threads_changed)
events.module_load(handler=on_modules_changed)
events.unload_module(handler=on_modules_changed)
events.breakpoint(handler=on_breakpoint_hit_async)
events.exception(handler=on_exception_async)
else:
events.engine_state(handler=on_state_changed)
events.debuggee_state(handler=on_debuggee_changed)
events.session_status(handler=on_session_status_changed)
events.symbol_state(handler=on_symbol_state_changed)
events.system_error(handler=on_system_error)
events.breakpoint(handler=on_breakpoint_hit)
events.exception(handler=on_exception)
events.create_process(handler=on_new_process)
events.exit_process(handler=on_process_deleted)
events.create_thread(handler=on_threads_changed)
events.exit_thread(handler=on_threads_changed)
events.module_load(handler=on_modules_changed)
events.unload_module(handler=on_modules_changed)
events.breakpoint(handler=on_breakpoint_hit)
events.exception(handler=on_exception)
@util.dbg.eng_thread
@ -527,3 +544,59 @@ def disable_current_process():
if proc in PROC_STATE:
# Silently ignore already disabled
del PROC_STATE[proc]
@log_errors
def on_state_changed_async(*args):
util.dbg.run_async(on_state_changed, *args)
@log_errors
def on_debuggee_changed_async(*args):
util.dbg.run_async(on_debuggee_changed, *args)
@log_errors
def on_session_status_changed_async(*args):
util.dbg.run_async(on_session_status_changed, *args)
@log_errors
def on_symbol_state_changed_async(*args):
util.dbg.run_async(on_symbol_state_changed, *args)
@log_errors
def on_system_error_async(*args):
util.dbg.run_async(on_system_error, *args)
@log_errors
def on_new_process_async(*args):
util.dbg.run_async(on_new_process, *args)
@log_errors
def on_process_deleted_async(*args):
util.dbg.run_async(on_process_deleted, *args)
@log_errors
def on_threads_changed_async(*args):
util.dbg.run_async(on_threads_changed, *args)
@log_errors
def on_modules_changed_async(*args):
util.dbg.run_async(on_modules_changed, *args)
@log_errors
def on_breakpoint_hit_async(*args):
util.dbg.run_async(on_breakpoint_hit, *args)
@log_errors
def on_exception_async(*args):
util.dbg.run_async(on_exception, *args)

View file

@ -29,12 +29,13 @@ import traceback
from comtypes import CoClass, GUID
import comtypes
from comtypes.gen import DbgMod
from comtypes.hresult import S_OK
from comtypes.hresult import S_OK, S_FALSE
from pybag import pydbg, userdbg, kerneldbg, crashdbg
from pybag.dbgeng import core as DbgEng
from pybag.dbgeng import exception
from pybag.dbgeng import util as DbgUtil
from pybag.dbgeng.callbacks import DbgEngCallbacks
from pybag.dbgeng.idebugclient import DebugClient
from ghidradbg.dbgmodel.ihostdatamodelaccess import HostDataModelAccess
from _winapi import STILL_ACTIVE
@ -145,7 +146,7 @@ class DbgExecutor(object):
def _submit_no_exit(self, fn, /, *args, **kwargs):
f = Future()
if self._executing:
if self._executing and self._ghidra_dbg.IS_REMOTE == False:
f.set_exception(DebuggeeRunningException("Debuggee is Running"))
return f
w = _WorkItem(f, fn, args, kwargs)
@ -163,7 +164,8 @@ class DbgExecutor(object):
def _state_execute(self):
self._executing = True
self._clear_queue()
if self._ghidra_dbg.IS_REMOTE == False:
self._clear_queue()
def _state_break(self):
self._executing = False
@ -239,9 +241,25 @@ class GhidraDbg(object):
setattr(self, name, self.eng_thread(getattr(base, name)))
self.IS_KERNEL = False
self.IS_EXDI = False
self.IS_REMOTE = os.getenv('OPT_CONNECT_STRING') is not None
def _new_base(self):
self._protected_base = AllDbg()
remote = os.getenv('OPT_CONNECT_STRING')
if remote is not None:
remote_client = DbgEng.DebugConnect(remote)
debug_client = self._generate_client(remote_client)
self._protected_base = AllDbg(client=debug_client)
else:
self._protected_base = AllDbg()
def _generate_client(self, original):
cli = POINTER(DbgEng.IDebugClient)()
cliptr = POINTER(POINTER(DbgEng.IDebugClient))(cli)
hr = original.CreateClient(cliptr)
exception.check_err(hr)
return DebugClient(client=cli)
@property
def _base(self):
@ -655,6 +673,9 @@ def GetExitCode():
return STILL_ACTIVE
exit_code = c_ulong()
hr = dbg._base._client._cli.GetExitCode(byref(exit_code))
# DebugConnect targets return E_UNEXPECTED but the target is STILL_ACTIVE
if hr != S_OK and hr != S_FALSE:
return STILL_ACTIVE
return exit_code.value
@ -915,8 +936,20 @@ def set_kernel(value):
def is_kernel():
return dbg.IS_KERNEL
def set_exdi(value):
dbg.IS_EXDI = value
def is_exdi():
return dbg.IS_EXDI
def set_remote(value):
dbg.IS_REMOTE = value
def is_remote():
return dbg.IS_REMOTE