mirror of
https://github.com/qilingframework/qiling.git
synced 2026-10-12 02:21:40 +00:00
+60
-24
@@ -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, QL_VERBOSE
|
||||
from qiling.debugger import QlDebugger
|
||||
|
||||
from .utils import setup_context_render, setup_branch_predictor, setup_address_marker, SnapshotManager, run_qdb_script
|
||||
@@ -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
|
||||
@@ -45,9 +45,10 @@ class QlQdb(cmd.Cmd, QlDebugger):
|
||||
|
||||
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
|
||||
"""
|
||||
@@ -67,7 +68,7 @@ class QlQdb(cmd.Cmd, QlDebugger):
|
||||
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()
|
||||
@@ -75,12 +76,6 @@ class QlQdb(cmd.Cmd, QlDebugger):
|
||||
|
||||
self.ql.hook_code(bp_handler, self.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)
|
||||
|
||||
if self.ql.entry_point:
|
||||
self.cur_addr = self.ql.entry_point
|
||||
else:
|
||||
@@ -88,6 +83,39 @@ class QlQdb(cmd.Cmd, QlDebugger):
|
||||
|
||||
self.init_state = self.ql.save()
|
||||
|
||||
# stop emulator once interp. have been done emulating
|
||||
if addr_elf_entry := getattr(self.ql.loader, 'elf_entry'):
|
||||
handler = self.ql.hook_address(lambda ql: ql.stop(), addr_elf_entry)
|
||||
else:
|
||||
handler = self.ql.hook_address(lambda ql: ql.stop(), self.ql.loader.entry_point)
|
||||
|
||||
# suppress logging temporary
|
||||
_verbose = self.ql.verbose
|
||||
self.ql.verbose = QL_VERBOSE.DISABLED
|
||||
|
||||
# init os for integrity of hooks and patches,
|
||||
self.ql.os.run()
|
||||
|
||||
handler.remove()
|
||||
|
||||
# ignore the memory unmap error for now, due to the MIPS memory layout issue
|
||||
try:
|
||||
self.ql.mem.unmap_all()
|
||||
except:
|
||||
pass
|
||||
|
||||
self.ql.restore(self.init_state)
|
||||
|
||||
# resotre logging verbose
|
||||
self.ql.verbose = _verbose
|
||||
|
||||
if self.ql.os.type is QL_OS.BLOB:
|
||||
self.ql.loader.entry_point = self.ql.loader.load_address
|
||||
|
||||
elif init_hook:
|
||||
for each_hook in init_hook:
|
||||
self.do_breakpoint(each_hook)
|
||||
|
||||
if self._script:
|
||||
run_qdb_script(self, self._script)
|
||||
else:
|
||||
@@ -121,14 +149,7 @@ class QlQdb(cmd.Cmd, QlDebugger):
|
||||
if getattr(self.ql.arch, 'is_thumb', False):
|
||||
address |= 0b1
|
||||
|
||||
# assume we're running PE if on Windows
|
||||
if self.ql.os.type == QL_OS.WINDOWS:
|
||||
self.ql.count = count
|
||||
self.ql.entry_point = address
|
||||
self.ql.os.run()
|
||||
|
||||
else:
|
||||
self.ql.emu_start(begin=address, end=end, count=count)
|
||||
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):
|
||||
@@ -372,7 +393,6 @@ class QlQdb(cmd.Cmd, QlDebugger):
|
||||
"""
|
||||
|
||||
if self.ql.arch != QL_ARCH.CORTEX_M:
|
||||
|
||||
self.ql.restore(self.init_state)
|
||||
self.do_context()
|
||||
|
||||
@@ -528,13 +548,29 @@ class QlQdb(cmd.Cmd, QlDebugger):
|
||||
args = reg_args + stk_args
|
||||
qdb_print(QDB_MSG.INFO, f'args: {args}')
|
||||
|
||||
def do_show(self, *args) -> None:
|
||||
def do_show(self, keyword: Optional[str] = None, *args) -> None:
|
||||
"""
|
||||
show some runtime information
|
||||
"""
|
||||
|
||||
for info_line in self.ql.mem.get_formatted_mapinfo():
|
||||
qdb_print(QDB_MSG.INFO, info_line)
|
||||
qdb_print(QDB_MSG.INFO, f"Entry point: {self.ql.loader.entry_point:#x}")
|
||||
|
||||
if addr_elf_entry := getattr(self.ql.loader, 'elf_entry'):
|
||||
qdb_print(QDB_MSG.INFO, f"ELF entry: {addr_elf_entry:#x}")
|
||||
|
||||
info_lines = iter(self.ql.mem.get_formatted_mapinfo())
|
||||
|
||||
# print filed name first
|
||||
qdb_print(QDB_MSG.INFO, next(info_lines))
|
||||
|
||||
# keyword filtering
|
||||
if keyword:
|
||||
lines = filter(lambda line: keyword in line, info_lines)
|
||||
else:
|
||||
lines = info_lines
|
||||
|
||||
for line in lines:
|
||||
qdb_print(QDB_MSG.INFO, line)
|
||||
|
||||
qdb_print(QDB_MSG.INFO, f"Breakpoints: {[hex(addr) for addr in self.bp_list.keys()]}")
|
||||
qdb_print(QDB_MSG.INFO, f"Marked symbol: {[{key:hex(val)} for key,val in self.marker.mark_list]}")
|
||||
|
||||
+8
-5
@@ -350,15 +350,18 @@ def select_debugger(options: Union[str, bool]) -> Optional[QlClassInit['QlDebugg
|
||||
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')
|
||||
|
||||
Reference in New Issue
Block a user