diff --git a/qiling/debugger/qdb/context.py b/qiling/debugger/qdb/context.py index a3c71ef86..e4400f4b4 100644 --- a/qiling/debugger/qdb/context.py +++ b/qiling/debugger/qdb/context.py @@ -10,7 +10,7 @@ from capstone import CsInsn -from .misc import read_int +from .misc import read_int, InvalidInsn class Context: """ @@ -48,9 +48,9 @@ def disasm(self, address: int, detail: bool = False) -> Optional[CsInsn]: md = self.ql.arch.disassembler md.detail = detail - if (addr := self.read_insn(address)): - return next(md.disasm(addr, address), None) - return None + if (bytes_read := self.read_insn(address)): + return next(md.disasm(bytes_read, address), InvalidInsn(bytes_read, address)) + return InvalidInsn(bytes_read, address) def try_read(self, address: int, size: int) -> Optional[bytes]: """ diff --git a/qiling/debugger/qdb/misc.py b/qiling/debugger/qdb/misc.py index d9bf67362..a3cf29e1a 100644 --- a/qiling/debugger/qdb/misc.py +++ b/qiling/debugger/qdb/misc.py @@ -5,6 +5,8 @@ from typing import AnyStr, Callable, Optional +from dataclasses import dataclass + import ast def check_and_eval(line: str): @@ -25,6 +27,19 @@ def generic_visit(self, node): return eval(line) +@dataclass +class InvalidInsn: + """ + class for displaying invalid instruction + """ + bytes: bytes + address: bytes + mnemonic: str = 'invalid' + op_str: str = '' + + def __post_init__(self): + self.size = len(self.bytes) + class Breakpoint: """ diff --git a/qiling/debugger/qdb/qdb.py b/qiling/debugger/qdb/qdb.py index 0d1d1fbf6..7606cf3bc 100644 --- a/qiling/debugger/qdb/qdb.py +++ b/qiling/debugger/qdb/qdb.py @@ -78,7 +78,7 @@ 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 != init_hook: + elif init_hook and self.ql.loader.entry_point != int(init_hook, 0): self.do_breakpoint(init_hook) self.cur_addr = self.ql.loader.entry_point @@ -116,7 +116,7 @@ def _run(self, address: int = 0, end: int = 0, count: int = 0) -> None: address = self.cur_addr if getattr(self.ql.arch, 'is_thumb', False): - address |= 1 + address |= 0b1 # assume we're running PE if on Windows if self.ql.os.type == QL_OS.WINDOWS: @@ -157,6 +157,7 @@ def inner(self, *args, **kwargs): qdb_print(QDB_MSG.ERROR, "The program is not being run.") else: func(self, *args, **kwargs) + return inner def parseline(self, line: str) -> Tuple[Optional[str], Optional[str], str]: @@ -213,17 +214,19 @@ def do_run(self, *args) -> None: @SnapshotManager.snapshot @save_reg_dump @check_ql_alive - def do_step_in(self, *args) -> Optional[bool]: + def do_step_in(self, step: str = '', *args) -> Optional[bool]: """ execute one instruction at a time, will enter subroutine """ - prophecy = self.predictor.predict() if prophecy.where is True: - return True + qdb_print(QDB_MSG.INFO, 'program exited due to code end hitted') + self.do_context() + return False + + step = 1 if step == '' else int(step) - step = 1 # make sure follow branching if prophecy.going is True and self.ql.arch.type == QL_ARCH.MIPS: step += 1 @@ -574,7 +577,6 @@ def do_EOF(self, *args) -> None: if input(f"{color.RED}[!] Are you sure about saying good bye ~ ? [Y/n]{color.END} ").strip() == "Y": self.do_quit() - do_r = do_run do_s = do_step_in do_n = do_step_over diff --git a/qiling/debugger/qdb/render/render.py b/qiling/debugger/qdb/render/render.py index 4ce64fa1c..aa7a6022d 100644 --- a/qiling/debugger/qdb/render/render.py +++ b/qiling/debugger/qdb/render/render.py @@ -157,6 +157,7 @@ def print_asm(self, insn: CsInsn, to_jump: bool = False) -> None: """ opcode = "".join(f"{b:02x}" for b in insn.bytes) + trace_line = f"0x{insn.address:08x} │ {opcode:15s} {insn.mnemonic:10} {insn.op_str:35s}" cursor = "►" if self.cur_addr == insn.address else " " @@ -211,12 +212,9 @@ def context_asm(self) -> None: to_addr = self.cur_addr + self.disasm_num cur_addr = from_addr - while cur_addr != to_addr: + while cur_addr <= to_addr: insn = self.disasm(cur_addr) - # cur_addr += self.arch_insn_size cur_addr += insn.size - if not insn: - continue past_list.append(insn) bk_list = []