Skip to content

Commit c1068de

Browse files
ucgJheucgJhe
authored andcommitted
move marking-related function into a class Marker
1 parent eb41e43 commit c1068de

File tree

3 files changed

+98
-37
lines changed

3 files changed

+98
-37
lines changed

qiling/debugger/qdb/misc.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
44
#
55

6-
from typing import Callable, Optional
6+
from typing import AnyStr, Callable, Optional
77

88
import ast
99

@@ -50,17 +50,27 @@ def read_int(s: str) -> int:
5050
return int(s, 0)
5151

5252

53+
def try_read_int(s: AnyStr) -> Optional[int]:
54+
"""
55+
try to read string as integer is possible
56+
"""
57+
try:
58+
ret = read_int(s)
59+
except:
60+
ret = None
61+
62+
return ret
63+
64+
5365
def parse_int(func: Callable) -> Callable:
5466
"""
5567
function dectorator for parsing argument as integer
5668
"""
5769
def wrap(qdb, s: str = "") -> int:
5870
assert type(s) is str
59-
try:
60-
ret = read_int(s)
61-
except:
62-
ret = None
71+
ret = try_read_int(s)
6372
return func(qdb, ret)
73+
6474
return wrap
6575

6676

qiling/debugger/qdb/qdb.py

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
from qiling.const import QL_OS, QL_ARCH, QL_VERBOSE
1212
from qiling.debugger import QlDebugger
1313

14-
from .utils import setup_context_render, setup_branch_predictor, SnapshotManager, run_qdb_script
14+
from .utils import setup_context_render, setup_branch_predictor, setup_address_marker, SnapshotManager, run_qdb_script
1515
from .memory import setup_memory_Manager
16-
from .misc import parse_int, Breakpoint, TempBreakpoint
16+
from .misc import parse_int, Breakpoint, TempBreakpoint, try_read_int
1717
from .const import color
1818

1919
from .utils import QDB_MSG, qdb_print
@@ -34,7 +34,7 @@ def __init__(self, ql: Qiling, init_hook: str = "", rr: bool = False, script: st
3434
self._saved_reg_dump = None
3535
self._script = script
3636
self.bp_list = {}
37-
self.mark_list = {}
37+
self.marker = setup_address_marker()
3838

3939
self.rr = SnapshotManager(ql) if rr else None
4040
self.mm = setup_memory_Manager(ql)
@@ -352,54 +352,60 @@ def do_context(self, *args) -> None:
352352
self.render.context_stack()
353353
self.render.context_asm()
354354

355-
def do_jump(self, address, *args) -> None:
355+
def do_jump(self, loc: str, *args) -> None:
356356
"""
357357
seek to where ever valid location you want
358358
"""
359359

360-
symbol, addr = None, None
361-
try:
362-
addr = int(address, 0)
363-
except:
364-
symbol = address
365-
366-
if symbol:
367-
addr = self.mark_list.get(symbol, None)
360+
sym = self.marker.get_symbol(loc)
361+
addr = sym if sym is not None else try_read_int(loc)
368362

363+
# check validation of the address to be seeked
369364
if self.ql.mem.is_mapped(addr, 4):
370-
qdb_print(QDB_MSG.INFO, f"seek to 0x{addr:08x} ...")
365+
if sym:
366+
qdb_print(QDB_MSG.INFO, f"seek to {loc} @ 0x{addr:08x} ...")
367+
else:
368+
qdb_print(QDB_MSG.INFO, f"seek to 0x{addr:08x} ...")
369+
371370
self.cur_addr = addr
372371
self.do_context()
373372

374373
else:
375374
qdb_print(QDB_MSG.ERROR, f"the address to be seeked isn't mapped")
376375

377-
def do_mark(self, args):
376+
def do_mark(self, args=""):
378377
"""
379378
mark a user specified address as a symbol
380379
"""
381380

382381
args = args.split()
383-
if len(args) == 1:
384-
try:
385-
tmp = int(args[0], 0)
386-
except:
387-
tmp = args[0]
388-
389-
if type(tmp) is str:
390-
symbol = tmp
391-
else:
392-
address = tmp
382+
if len(args) == 0:
383+
loc = self.cur_addr
384+
sym_name = self.marker.mark_only_loc(loc)
393385

394-
else:
395-
symbol, address = args
386+
elif len(args) == 1:
387+
if (loc := try_read_int(args[0])):
388+
sym_name = self.marker.mark_only_loc(loc)
396389

397-
if symbol:
398-
addr = self.cur_addr if address is None else int(address, 0)
399-
self.mark_list.update({symbol: addr})
400-
qdb_print(QDB_MSG.INFO, f"mark symbol '{symbol}' at address: 0x{addr:08x} ...")
390+
else:
391+
loc = self.cur_addr
392+
sym_name = args[0]
393+
if (err := self.marker.mark(sym_name, loc)):
394+
qdb_print(QDB_MSG.ERROR, err)
395+
return
396+
397+
elif len(args) == 2:
398+
sym_name, addr = args
399+
if (loc := try_read_int(addr)):
400+
self.marker.mark(sym_name, loc)
401+
else:
402+
qdb_print(QDB_MSG.ERROR, f"unable to mark symbol at address: '{addr}'")
403+
return
401404
else:
402405
qdb_print(QDB_MSG.ERROR, "symbol should not be empty ...")
406+
return
407+
408+
qdb_print(QDB_MSG.INFO, f"mark symbol '{sym_name}' at address: 0x{loc:08x} ...")
403409

404410
def do_show(self, *args) -> None:
405411
"""
@@ -410,7 +416,7 @@ def do_show(self, *args) -> None:
410416
self.ql.log.info(info_line)
411417

412418
qdb_print(QDB_MSG.INFO, f"Breakpoints: {[hex(addr) for addr in self.bp_list.keys()]}")
413-
qdb_print(QDB_MSG.INFO, f"Marked symbol: {[{key:hex(val)} for key,val in self.mark_list.items()]}")
419+
qdb_print(QDB_MSG.INFO, f"Marked symbol: {[{key:hex(val)} for key,val in self.marker.mark_list]}")
414420
if self.rr:
415421
qdb_print(QDB_MSG.INFO, f"Snapshots: {len([st for st in self.rr.layers if isinstance(st, self.rr.DiffedState)])}")
416422

qiling/debugger/qdb/utils.py

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
from qiling.const import QL_ARCH
1313

1414
from .context import Context
15-
from .misc import read_int
1615

1716
from .render import (
1817
ContextRenderX86,
@@ -51,6 +50,52 @@ def print_info(msg):
5150
print(color_coated)
5251

5352

53+
def setup_address_marker():
54+
55+
class Marker:
56+
def __init__(self):
57+
self._mark_list = {}
58+
59+
def get_symbol(self, sym):
60+
return self._mark_list.get(sym, None)
61+
62+
@property
63+
def mark_list(self):
64+
return self._mark_list.items()
65+
66+
def gen_sym_name(self):
67+
"""
68+
generating symbol name automatically
69+
"""
70+
71+
sym_name, idx = "sym0", 0
72+
while sym_name in self._mark_list:
73+
idx += 1
74+
sym_name = f"sym{idx}"
75+
76+
return sym_name
77+
78+
def mark_only_loc(self, loc):
79+
"""
80+
mark when location provided only
81+
"""
82+
83+
sym_name = self.gen_sym_name()
84+
self.mark(sym_name, loc)
85+
return sym_name
86+
87+
def mark(self, sym: str, loc: int):
88+
"""
89+
mark loc as sym
90+
"""
91+
92+
if sym not in self.mark_list:
93+
self._mark_list.update({sym: loc})
94+
else:
95+
return f"dumplicated symbol name: {sym} at address: 0x{loc:08x}"
96+
97+
return Marker()
98+
5499
"""
55100
56101
helper functions for setting proper branch predictor and context render depending on different arch

0 commit comments

Comments
 (0)