Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion qiling/debugger/qdb/qdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ def _run(self: Qldbg, address: int = 0, end: int = 0, count: int = 0) -> None:
else:
print(f"{color.CYAN}[+] hit breakpoint at 0x{self.cur_addr:08x}{color.END}")

self.do_context()
break

self.ql.arch.step()
Expand Down
55 changes: 31 additions & 24 deletions qiling/debugger/qdb/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,8 @@ def regdst_eq_pc(op_str):
to_jump = cb_table.get(line.mnemonic)(read_reg_val(line.op_str.split(", ")[0]))

if to_jump:
if '#' in line.op_str:
ret_addr = _parse_int(line.op_str.split('#')[-1])
if "#" in line.op_str:
ret_addr = _parse_int(line.op_str.split("#")[-1])
else:
ret_addr = read_reg_val(line.op_str)

Expand Down Expand Up @@ -301,55 +301,62 @@ def regdst_eq_pc(op_str):

ret_addr = next_addr

return ret_addr

elif line.mnemonic in ("ldr",):

if regdst_eq_pc(line.op_str):
_pc, _, rn_offset = line.op_str.partition(", ")
_, _, rn_offset = line.op_str.partition(", ")
r, _, imm = rn_offset.strip("[]!").partition(", #")

if "]" in rn_offset.split(", ")[1]: # pre-indexed immediate
_, r, imm = line.op_str.replace("[", "").replace("]", "").replace("!", "").replace("#", "").split(", ")
ret_addr = ql.unpack32(ql.mem.read(_parse_int(imm) + read_reg_val(r), 4))
ret_addr = ql.unpack32(ql.mem.read(_parse_int(imm) + read_reg_val(r), ARM_INST_SIZE))

else: # post-indexed immediate
# FIXME: weired behavior, immediate here does not apply
_, r, imm = line.op_str.replace("[", "").replace("]", "").replace("!", "").replace("#", "").split(", ")
ret_addr = ql.unpack32(ql.mem.read(read_reg_val(r), 4))
ret_addr = ql.unpack32(ql.mem.read(read_reg_val(r), ARM_INST_SIZE))

elif line.mnemonic in ("addls", "addne", "add") and regdst_eq_pc(line.op_str):
V, C, Z, N = get_cpsr(ql.reg.cpsr)
r0, r1, r2, *imm = line.op_str.split(", ")

if line.mnemonic == "addls" and (C == 0 or Z == 1):
r0, r1, r2, imm = line.op_str.split(", ")
# program counter is awalys 8 bytes ahead , when it comes with pc need to add extra 8 bytes
ret_addr = 8 + read_reg_val(r1) + read_reg_val(r2) * 4
# program counter is awalys 8 bytes ahead when it comes with pc, need to add extra 8 bytes
extra = 8 if 'pc' in (r0, r1, r2) else 0

if imm:
expr = imm[0].split()
# TODO: should support more bit shifting and rotating operation
if expr[0] == "lsl": # logical shift left
n = _parse_int(expr[-1].strip("#")) * 2

elif line.mnemonic == "addne" and Z == 0:
r0, r1, r2, *rest = line.op_str.split(", ")
ret_addr = 8 + read_reg_val(r1) + (read_reg_val(r2) * 4 if rest else read_reg_val(r2))
if line.mnemonic == "addls" and (C == 0 or Z == 1):
ret_addr = extra + read_reg_val(r1) + read_reg_val(r2) * n

elif line.mnemonic == "add":
r0, r1, r2 = line.op_str.split(", ")
ret_addr = 8 + sum(map(read_reg_val, [r1, r2]))
elif line.mnemonic == "add" or (line.mnemonic == "addne" and Z == 0):
ret_addr = extra + read_reg_val(r1) + (read_reg_val(r2) * n if imm else read_reg_val(r2))

elif line.mnemonic in ("tbh", "tbb"):

cur_addr += ARM_INST_SIZE
r0, r1, *imm = line.op_str.strip("[]").split(", ")

if imm:
expr = imm[0].split()
if expr[0] == "lsl": # logical shift left
n = _parse_int(expr[-1].strip("#")) * 2

if line.mnemonic == "tbh":
r0, r1, _ = line.op_str.strip("[").strip("]").split(", ")
r1 = read_reg_val(r1) * 2

r1 = read_reg_val(r1) * n

elif line.mnemonic == "tbb":
r0, r1 = line.op_str.strip("[").strip("]").split(", ")

r1 = read_reg_val(r1)

to_add = int.from_bytes(ql.mem.read(cur_addr+r1, 2 if line.mnemonic == "tbh" else 1), byteorder="little") * 2
to_add = int.from_bytes(ql.mem.read(cur_addr+r1, 2 if line.mnemonic == "tbh" else 1), byteorder="little") * n
ret_addr = cur_addr + to_add

elif line.mnemonic.startswith("pop") and "pc" in line.op_str:

ret_addr = ql.stack_read(line.op_str.strip("{").strip("}").split(", ").index("pc") * 4)
ret_addr = ql.stack_read(line.op_str.strip("{}").split(", ").index("pc") * ARM_INST_SIZE)
if not { # step to next instruction if cond does not meet
"pop" : lambda *_: True,
"pop.w": lambda *_: True,
Expand Down