mirror of
https://github.com/qilingframework/qiling.git
synced 2026-10-12 02:21:40 +00:00
fix asm listing for cortex_m and breakpoint
This commit is contained in:
@@ -252,7 +252,7 @@ class CtxManager(object):
|
||||
past_list.append(line)
|
||||
|
||||
# print four insns before current location
|
||||
for line in past_list[:-1][:4]:
|
||||
for line in past_list[:-1]:
|
||||
self.print_asm(line)
|
||||
|
||||
# assembly for current location
|
||||
|
||||
+29
-39
@@ -44,15 +44,26 @@ class QlQdb(cmd.Cmd, QlDebugger):
|
||||
# self.ql.loader.elf_entry # .text of binary
|
||||
|
||||
def bp_handler(ql, address, size, bp_list):
|
||||
if address in bp_list:
|
||||
ql.emu_stop()
|
||||
_ = bp_list.pop(address)
|
||||
|
||||
if (bp := self.bp_list.get(address, None)):
|
||||
|
||||
if isinstance(bp, TempBreakpoint):
|
||||
# remove TempBreakpoint once hitted
|
||||
self.del_breakpoint(bp)
|
||||
|
||||
else:
|
||||
if bp.hitted:
|
||||
return
|
||||
|
||||
print(f"{color.CYAN}[+] hit breakpoint at 0x{self.cur_addr:08x}{color.END}")
|
||||
bp.hitted = True
|
||||
|
||||
ql.stop()
|
||||
self.do_context()
|
||||
|
||||
self.ql.hook_code(bp_handler, self.bp_list)
|
||||
|
||||
if init_hook and self.ql.loader.entry_point != init_hook:
|
||||
breakpoint()
|
||||
self.do_breakpoint(init_hook)
|
||||
|
||||
self.cur_addr = self.ql.loader.entry_point
|
||||
@@ -82,27 +93,6 @@ class QlQdb(cmd.Cmd, QlDebugger):
|
||||
|
||||
self.ql.reg.arch_pc = address
|
||||
|
||||
def _bp_handler(self: QlQdb, *args) -> None:
|
||||
"""
|
||||
internal function for handling once breakpoint hitted
|
||||
"""
|
||||
|
||||
if (bp := self.bp_list.get(self.cur_addr, None)):
|
||||
|
||||
if isinstance(bp, TempBreakpoint):
|
||||
# remove TempBreakpoint once hitted
|
||||
self.del_breakpoint(bp)
|
||||
|
||||
else:
|
||||
if bp.hitted:
|
||||
return
|
||||
|
||||
print(f"{color.CYAN}[+] hit breakpoint at 0x{self.cur_addr:08x}{color.END}")
|
||||
bp.hitted = True
|
||||
|
||||
self.ql.stop()
|
||||
self.do_context()
|
||||
|
||||
def _save(self: QlQdb, *args) -> None:
|
||||
"""
|
||||
internal function for saving state of qiling instance
|
||||
@@ -220,6 +210,12 @@ class QlQdb(cmd.Cmd, QlDebugger):
|
||||
self._restore()
|
||||
self.do_context()
|
||||
|
||||
def update_reg_dump(self: QlQdb) -> None:
|
||||
"""
|
||||
internal function for updating registers dump
|
||||
"""
|
||||
self._saved_reg_dump = dict(filter(lambda d: isinstance(d[0], str), self.ql.reg.save().items()))
|
||||
|
||||
def do_step_in(self: QlQdb, *args) -> Optional[bool]:
|
||||
"""
|
||||
execute one instruction at a time, will enter subroutine
|
||||
@@ -229,8 +225,7 @@ class QlQdb(cmd.Cmd, QlDebugger):
|
||||
print(f"{color.RED}[!] The program is not being run.{color.END}")
|
||||
|
||||
else:
|
||||
# save reg dump for data highlighting changes
|
||||
self._saved_reg_dump = dict(filter(lambda d: isinstance(d[0], str), self.ql.reg.save().items()))
|
||||
self.update_reg_dump()
|
||||
|
||||
if self.rr:
|
||||
self._save()
|
||||
@@ -241,10 +236,9 @@ class QlQdb(cmd.Cmd, QlDebugger):
|
||||
return True
|
||||
|
||||
if self.ql.archtype == QL_ARCH.CORTEX_M:
|
||||
self.ql.count -= 1
|
||||
self.set_breakpoint(self.cur_addr, is_temp=True)
|
||||
|
||||
self._run(count=1)
|
||||
self.ql.arch.step()
|
||||
else:
|
||||
self._run(count=1)
|
||||
|
||||
self.do_context()
|
||||
|
||||
@@ -259,6 +253,7 @@ class QlQdb(cmd.Cmd, QlDebugger):
|
||||
else:
|
||||
|
||||
prophecy = self.predictor.predict()
|
||||
self.update_reg_dump()
|
||||
|
||||
if prophecy.going:
|
||||
cur_insn = disasm(self.ql, self.cur_addr)
|
||||
@@ -267,7 +262,7 @@ class QlQdb(cmd.Cmd, QlDebugger):
|
||||
else:
|
||||
self.set_breakpoint(prophecy.where, is_temp=True)
|
||||
|
||||
self._run(self.cur_addr)
|
||||
self._run()
|
||||
|
||||
def set_breakpoint(self: QlQdb, address: int, is_temp: bool = False) -> None:
|
||||
"""
|
||||
@@ -276,19 +271,14 @@ class QlQdb(cmd.Cmd, QlDebugger):
|
||||
|
||||
bp = TempBreakpoint(address) if is_temp else Breakpoint(address)
|
||||
|
||||
# if self.ql.archtype != QL_ARCH.CORTEX_M:
|
||||
# skip hook_address for cortex_m
|
||||
# bp.hook = self.ql.hook_address(self._bp_handler, address)
|
||||
|
||||
self.bp_list.update({address: bp})
|
||||
|
||||
def del_breakpoint(self: QlQdb, bp: Union[Breakpoint, TempBreakpoint]) -> None:
|
||||
"""
|
||||
internal function for removing breakpoints
|
||||
internal function for removing breakpoint
|
||||
"""
|
||||
|
||||
if self.bp_list.pop(bp.addr, None):
|
||||
bp.hook.remove()
|
||||
self.bp_list.pop(bp.addr, None)
|
||||
|
||||
def do_start(self: QlQdb, *args) -> None:
|
||||
"""
|
||||
|
||||
@@ -240,9 +240,9 @@ class BranchPredictor_ARM(BranchPredictor):
|
||||
if "#" in line.op_str:
|
||||
prophecy.where = read_int(line.op_str.split("#")[-1])
|
||||
else:
|
||||
prophecy.where = read_reg_val(line.op_str)
|
||||
prophecy.where = self.read_reg(line.op_str)
|
||||
|
||||
if regdst_eq_pc(line.op_str):
|
||||
if self.regdst_eq_pc(line.op_str):
|
||||
next_addr = cur_addr + line.size
|
||||
n2_addr = next_addr + len(read_inst(next_addr))
|
||||
prophecy.where += len(read_inst(n2_addr)) + len(read_inst(next_addr))
|
||||
@@ -285,11 +285,11 @@ class BranchPredictor_ARM(BranchPredictor):
|
||||
r, _, imm = rn_offset.strip("[]!").partition(", #")
|
||||
|
||||
if "]" in rn_offset.split(", ")[1]: # pre-indexed immediate
|
||||
prophecy.where = ql.unpack32(ql.mem.read(read_int(imm) + read_reg_val(r), self.INST_SIZE))
|
||||
prophecy.where = ql.unpack32(ql.mem.read(read_int(imm) + self.read_reg(r), self.INST_SIZE))
|
||||
|
||||
else: # post-indexed immediate
|
||||
# FIXME: weired behavior, immediate here does not apply
|
||||
prophecy.where = ql.unpack32(ql.mem.read(read_reg_val(r), self.INST_SIZE))
|
||||
prophecy.where = ql.unpack32(ql.mem.read(self.read_reg(r), self.INST_SIZE))
|
||||
|
||||
elif line.mnemonic in ("addls", "addne", "add") and self.regdst_eq_pc(line.op_str):
|
||||
V, C, Z, N = get_cpsr(ql.reg.cpsr)
|
||||
@@ -305,10 +305,10 @@ class BranchPredictor_ARM(BranchPredictor):
|
||||
n = read_int(expr[-1].strip("#")) * 2
|
||||
|
||||
if line.mnemonic == "addls" and (C == 0 or Z == 1):
|
||||
prophecy.where = extra + read_reg_val(r1) + read_reg_val(r2) * n
|
||||
prophecy.where = extra + self.read_reg(r1) + self.read_reg(r2) * n
|
||||
|
||||
elif line.mnemonic == "add" or (line.mnemonic == "addne" and Z == 0):
|
||||
prophecy.where = extra + read_reg_val(r1) + (read_reg_val(r2) * n if imm else read_reg_val(r2))
|
||||
prophecy.where = extra + self.read_reg(r1) + (self.read_reg(r2) * n if imm else self.read_reg(r2))
|
||||
|
||||
elif line.mnemonic in ("tbh", "tbb"):
|
||||
|
||||
@@ -322,11 +322,11 @@ class BranchPredictor_ARM(BranchPredictor):
|
||||
|
||||
if line.mnemonic == "tbh":
|
||||
|
||||
r1 = read_reg_val(r1) * n
|
||||
r1 = self.read_reg(r1) * n
|
||||
|
||||
elif line.mnemonic == "tbb":
|
||||
|
||||
r1 = read_reg_val(r1)
|
||||
r1 = self.read_reg(r1)
|
||||
|
||||
to_add = int.from_bytes(ql.mem.read(cur_addr+r1, 2 if line.mnemonic == "tbh" else 1), byteorder="little") * n
|
||||
prophecy.where = cur_addr + to_add
|
||||
@@ -348,11 +348,11 @@ class BranchPredictor_ARM(BranchPredictor):
|
||||
|
||||
elif line.mnemonic == "sub" and self.regdst_eq_pc(line.op_str):
|
||||
_, r, imm = line.op_str.split(", ")
|
||||
prophecy.where = read_reg_val(r) - read_int(imm.strip("#"))
|
||||
prophecy.where = self.read_reg(r) - read_int(imm.strip("#"))
|
||||
|
||||
elif line.mnemonic == "mov" and self.regdst_eq_pc(line.op_str):
|
||||
_, r = line.op_str.split(", ")
|
||||
prophecy.where = read_reg_val(r)
|
||||
prophecy.where = self.read_reg(r)
|
||||
|
||||
if prophecy.where & 1:
|
||||
prophecy.where -= 1
|
||||
@@ -544,17 +544,16 @@ class Breakpoint(object):
|
||||
"""
|
||||
dummy class for breakpoint
|
||||
"""
|
||||
def __init__(self, address: int):
|
||||
self.addr = address
|
||||
def __init__(self, addr):
|
||||
self.addr = addr
|
||||
self.hitted = False
|
||||
self.hook = None
|
||||
|
||||
class TempBreakpoint(Breakpoint):
|
||||
"""
|
||||
dummy class for temporay breakpoint
|
||||
"""
|
||||
def __init__(self, address):
|
||||
super().__init__(address)
|
||||
def __init__(self, addr):
|
||||
super().__init__(addr)
|
||||
|
||||
class ParseError(Exception):
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user