Skip to content

Commit

Permalink
qdb improvements: 1. allow multi-breakpoints, 2. both hooks and patch…
Browse files Browse the repository at this point in the history
…es are now effective in qdb
  • Loading branch information
ucgJhe committed Nov 8, 2023
1 parent 248c69a commit 0454493
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 14 deletions.
26 changes: 17 additions & 9 deletions qiling/debugger/qdb/qdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

import cmd

from typing import Optional, Tuple, Union
from typing import Optional, Tuple, Union, List
from contextlib import contextmanager

from qiling import Qiling
from qiling.const import QL_OS, QL_ARCH, QL_ENDIAN
from qiling.const import QL_OS, QL_ARCH, QL_ENDIAN, QL_STATE
from qiling.debugger import QlDebugger

from .utils import setup_context_render, setup_branch_predictor, setup_address_marker, SnapshotManager, run_qdb_script
Expand All @@ -25,7 +25,7 @@ class QlQdb(cmd.Cmd, QlDebugger):
The built-in debugger of Qiling Framework
"""

def __init__(self, ql: Qiling, init_hook: str = "", rr: bool = False, script: str = "") -> None:
def __init__(self, ql: Qiling, init_hook: List[str] = [], rr: bool = False, script: str = "") -> None:
"""
@init_hook: the entry to be paused at
@rr: record/replay debugging
Expand All @@ -45,9 +45,10 @@ def __init__(self, ql: Qiling, init_hook: str = "", rr: bool = False, script: st

super().__init__()

self.dbg_hook(init_hook)
# filter out entry_point of loader if presented
self.dbg_hook(list(filter(lambda d: int(d, 0) != self.ql.loader.entry_point, init_hook)))

def dbg_hook(self, init_hook: str):
def dbg_hook(self, init_hook: List[str]):
"""
initial hook to prepare everything we need
"""
Expand All @@ -67,7 +68,7 @@ def bp_handler(ql, address, size, bp_list):
if bp.hitted:
return

qdb_print(QDB_MSG.INFO, f"hit breakpoint at 0x{self.cur_addr:08x}")
qdb_print(QDB_MSG.INFO, f"hit breakpoint at {self.cur_addr:#x}")
bp.hitted = True

ql.stop()
Expand All @@ -78,8 +79,9 @@ def bp_handler(ql, address, size, bp_list):
if self.ql.os.type == QL_OS.BLOB:
self.ql.loader.entry_point = self.ql.loader.load_address

elif init_hook and self.ql.loader.entry_point != int(init_hook, 0):
self.do_breakpoint(init_hook)
elif init_hook:
for each_hook in init_hook:
self.do_breakpoint(each_hook)

if self.ql.entry_point:
self.cur_addr = self.ql.entry_point
Expand Down Expand Up @@ -128,7 +130,13 @@ def _run(self, address: int = 0, end: int = 0, count: int = 0) -> None:
self.ql.os.run()

else:
self.ql.emu_start(begin=address, end=end, count=count)

# use os.run instead if QL_STATE is NOT_SET, for keeping integrity of hooks and patches in Qdb
if self.ql._state is QL_STATE.NOT_SET:
self.ql.os.run()

else:
self.ql.emu_start(begin=address, end=end, count=count)

@contextmanager
def _save(self, reg=True, mem=True, hw=False, fd=False, cpu_context=False, os=False, loader=False):
Expand Down
13 changes: 8 additions & 5 deletions qiling/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,15 +350,18 @@ def __int_nothrow(v: str, /) -> Optional[int]:
return None

# qdb init args are independent and may include any combination of: rr enable, init hook and script
for a in args:
if a == 'rr':
arg_init_hook = []
for arg in args:
if arg == 'rr':
kwargs['rr'] = True

elif __int_nothrow(a) is not None:
kwargs['init_hook'] = a
elif __int_nothrow(arg) is not None:
arg_init_hook.append(arg)

else:
kwargs['script'] = a
kwargs['script'] = arg
else:
kwargs['init_hook'] = arg_init_hook

else:
raise QlErrorOutput('Debugger not supported')
Expand Down

0 comments on commit 0454493

Please sign in to comment.