From be2f4494189c925cd82c8f704ef899a96bf2ee15 Mon Sep 17 00:00:00 2001 From: ucgJhe Date: Mon, 3 Jan 2022 19:26:47 +0800 Subject: [PATCH 1/4] proper error message for examine_mem --- qiling/debugger/qdb/frontend.py | 24 ++++++++++++++++++++---- qiling/debugger/qdb/qdb.py | 7 ++----- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/qiling/debugger/qdb/frontend.py b/qiling/debugger/qdb/frontend.py index 4c07f686c..a2830ec5e 100644 --- a/qiling/debugger/qdb/frontend.py +++ b/qiling/debugger/qdb/frontend.py @@ -11,6 +11,8 @@ from qiling.const import QL_ARCH +import unicorn + from .utils import dump_regs, get_arm_flags, disasm, _parse_int, handle_bnj from .const import * @@ -83,7 +85,14 @@ def unpack(bs, sz): else: lines = 1 if ct <= 4 else math.ceil(ct / 4) - mem_read = [ql.mem.read(addr+(offset*sz), sz) for offset in range(ct)] + mem_read = [] + for offset in range(ct): + # append data if read successfully, otherwise return error message + if (data := _try_read(ql, addr+(offset*sz), sz))[0]: + mem_read.append(data[0]) + + else: + return data[1] for line in range(lines): offset = line * sz * 4 @@ -95,7 +104,6 @@ def unpack(bs, sz): prefix = "0x" if ft in ("x", "a") else "" pad = '0' + str(sz*2) if ft in ('x', 'a', 't') else '' ft = ft.lower() if ft in ("x", "o", "b", "d") else ft.lower().replace("t", "b").replace("a", "x") - print(f"{prefix}{data:{pad}{ft}}\t", end="") print() @@ -110,12 +118,20 @@ def get_terminal_size() -> Iterable: # try to read data from ql memory def _try_read(ql: Qiling, address: int, size: int) -> Optional[bytes]: + + result = None + err_msg = "" try: result = ql.mem.read(address, size) + + except unicorn.unicorn.UcError as err: + if err.errno == 6: # Invalid memory read (UC_ERR_READ_UNMAPPED) + err_msg = f"Can not access memory at address 0x{address:08x}" + except: - result = None + pass - return result + return (result, err_msg) # divider printer diff --git a/qiling/debugger/qdb/qdb.py b/qiling/debugger/qdb/qdb.py index c7df98b3c..68703cdf9 100644 --- a/qiling/debugger/qdb/qdb.py +++ b/qiling/debugger/qdb/qdb.py @@ -302,11 +302,8 @@ def do_examine(self: QlQdb, line: str) -> None: e.g. x/4wx 0x41414141 , print 4 word size begin from address 0x41414141 in hex """ - try: - if not examine_mem(self.ql, line): - self.do_help("examine") - except: - print(f"{color.RED}[!] something went wrong ...{color.END}") + if type(err_msg := examine_mem(self.ql, line)) is str: + print(f"{color.RED}[!] {err_msg} ...{color.END}") def do_show(self: QlQdb, *args) -> None: """ From c76900665c5c507906c2f2ba7dd2c959537655ac Mon Sep 17 00:00:00 2001 From: ucgJhe Date: Mon, 3 Jan 2022 19:37:44 +0800 Subject: [PATCH 2/4] use try_read instead of ql.mem.read for proper error message --- qiling/debugger/qdb/frontend.py | 39 ++++++++++++++------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/qiling/debugger/qdb/frontend.py b/qiling/debugger/qdb/frontend.py index a2830ec5e..ae6865616 100644 --- a/qiling/debugger/qdb/frontend.py +++ b/qiling/debugger/qdb/frontend.py @@ -88,7 +88,7 @@ def unpack(bs, sz): mem_read = [] for offset in range(ct): # append data if read successfully, otherwise return error message - if (data := _try_read(ql, addr+(offset*sz), sz))[0]: + if (data := _try_read(ql, addr+(offset*sz), sz))[0] is not None: mem_read.append(data[0]) else: @@ -231,27 +231,22 @@ def context_reg(ql: Qiling, saved_states: Optional[Mapping[str, int]] = None, /, val = ql.mem.read(addr, ql.pointersize) print(f"$sp+0x{idx*ql.pointersize:02x}│ [0x{addr:08x}] —▸ 0x{ql.unpack(val):08x}", end="") - try: # try to deference wether its a pointer - buf = ql.mem.read(addr, ql.pointersize) - except: - buf = None - - if (addr := ql.unpack(buf)): - try: # try to deference again - buf = ql.mem.read(addr, ql.pointersize) - except: - buf = None - - if buf: - try: - s = ql.mem.string(addr) - except: - s = None - - if s and s.isprintable(): - print(f" ◂— {ql.mem.string(addr)}", end="") - else: - print(f" ◂— 0x{ql.unpack(buf):08x}", end="") + # try to dereference wether it's a pointer + if (buf := _try_read(ql, addr, ql.pointersize))[0] is not None: + + if (addr := ql.unpack(buf[0])): + + # try to dereference again + if (buf := _try_read(ql, addr, ql.pointersize))[0] is not None: + try: + s = ql.mem.string(addr) + except: + s = None + + if s and s.isprintable(): + print(f" ◂— {ql.mem.string(addr)}", end="") + else: + print(f" ◂— 0x{ql.unpack(buf[0]):08x}", end="") print() From c10e5e07acd99dabc75e78df4834613a8d46f584 Mon Sep 17 00:00:00 2001 From: ucgJhe Date: Mon, 3 Jan 2022 20:19:06 +0800 Subject: [PATCH 3/4] suport addition in qdb commandline --- qiling/debugger/qdb/frontend.py | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/qiling/debugger/qdb/frontend.py b/qiling/debugger/qdb/frontend.py index ae6865616..fb93e6e4f 100644 --- a/qiling/debugger/qdb/frontend.py +++ b/qiling/debugger/qdb/frontend.py @@ -42,26 +42,38 @@ def extract_count(t): return (f, s, c) - fmt, addr = line.strip("/").split() + + fmt, *rest = line.strip("/").split() + + rest = "".join(rest) fmt = get_fmt(fmt) elif len(_args) == 1: # only address - addr = _args[0] + rest = _args[0] fmt = DEFAULT_FMT else: - return False - - addr = addr.strip('$') + rest = _args if ql.archtype in (QL_ARCH.ARM, QL_ARCH.ARM_THUMB): - addr = addr.replace("fp", "r11") + rest = rest.replace("fp", "r11") elif ql.archtype == QL_ARCH.MIPS: - addr = addr.replace("fp", "s8") + rest = rest.replace("fp", "s8") + + # for supporting addition of register with constant value + elems = rest.split("+") + elems = [elem.strip("$") for elem in elems] + + items = [] + for elem in elems: + if elem in ql.reg.register_mapping.keys(): + items.append(getattr(ql.reg, elem, None)) + else: + items.append(_parse_int(elem)) - addr = getattr(ql.reg, addr) if addr in ql.reg.register_mapping.keys() else _parse_int(addr) + addr = sum(items) def unpack(bs, sz): return { From 39f13bd3a17091d9d206548883f93a47a20243e3 Mon Sep 17 00:00:00 2001 From: ucgJhe Date: Tue, 4 Jan 2022 02:49:49 +0800 Subject: [PATCH 4/4] bring back try-catch for typo like error --- qiling/debugger/qdb/qdb.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/qiling/debugger/qdb/qdb.py b/qiling/debugger/qdb/qdb.py index 68703cdf9..819c04b51 100644 --- a/qiling/debugger/qdb/qdb.py +++ b/qiling/debugger/qdb/qdb.py @@ -302,8 +302,11 @@ def do_examine(self: QlQdb, line: str) -> None: e.g. x/4wx 0x41414141 , print 4 word size begin from address 0x41414141 in hex """ - if type(err_msg := examine_mem(self.ql, line)) is str: - print(f"{color.RED}[!] {err_msg} ...{color.END}") + try: + if type(err_msg := examine_mem(self.ql, line)) is str: + print(f"{color.RED}[!] {err_msg} ...{color.END}") + except: + print(f"{color.RED}[!] something went wrong ...{color.END}") def do_show(self: QlQdb, *args) -> None: """