Skip to content

Commit f803a04

Browse files
committed
Merge branch 'dev' of https://github.com/qilingframework/qiling into dev
2 parents d33da19 + bace0ea commit f803a04

28 files changed

+1464
-1182
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
4+
#
5+
6+
import sys
7+
sys.path.append("../..")
8+
9+
from qiling.core import Qiling
10+
from qiling.const import QL_VERBOSE
11+
from qiling.extensions.mcu.stm32f4 import stm32f407
12+
from qiling.hw.external_device.oled.ssd1306 import PyGameSSD1306Spi
13+
14+
15+
ql = Qiling(["../rootfs/mcu/stm32f407/ai-sine-test.elf"],
16+
archtype="cortex_m", env=stm32f407, verbose=QL_VERBOSE.DEFAULT)
17+
18+
ql.hw.create('rcc')
19+
ql.hw.create('pwr')
20+
ql.hw.create('flash interface')
21+
ql.hw.create('gpioa')
22+
ql.hw.create('gpiob')
23+
ql.hw.create('gpiod')
24+
ql.hw.create('spi1')
25+
ql.hw.create('crc')
26+
27+
oled = PyGameSSD1306Spi(dc=(ql.hw.gpiod, 5))
28+
ql.hw.spi1.connect(oled)
29+
30+
def indicator(ql):
31+
ql.log.info('PA7 set')
32+
33+
ql.hw.gpioa.hook_set(7, indicator, ql)
34+
ql.hw.systick.ratio = 1000
35+
36+
ql.run(count=800000)

qiling/debugger/qdb/qdb.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,8 @@ def dbg_hook(self: QlQdb, init_hook: str):
4040
# self.ql.loader.entry_point # ld.so
4141
# self.ql.loader.elf_entry # .text of binary
4242

43-
if init_hook:
44-
pause_entry = _parse_int(init_hook)
45-
else:
46-
pause_entry = self.ql.loader.entry_point
47-
48-
self.set_breakpoint(pause_entry, is_temp=True)
43+
if init_hook and self.ql.loader.entry_point != init_hook:
44+
self.do_breakpoint(init_hook)
4945

5046
self.cur_addr = self.ql.loader.entry_point
5147

@@ -55,9 +51,7 @@ def dbg_hook(self: QlQdb, init_hook: str):
5551
else:
5652
self._init_state = self.ql.save()
5753

58-
if pause_entry != self.cur_addr:
59-
self.do_context()
60-
54+
self.do_context()
6155
self.interactive()
6256

6357
@property
@@ -129,7 +123,6 @@ def _run(self: Qldbg, address: int = 0, end: int = 0, count: int = 0) -> None:
129123
else:
130124
print(f"{color.CYAN}[+] hit breakpoint at 0x{self.cur_addr:08x}{color.END}")
131125

132-
self.do_context()
133126
break
134127

135128
self.ql.arch.step()
@@ -239,7 +232,8 @@ def do_step(self: QlQdb, *args) -> Optional[bool]:
239232
self.ql.count -= 1
240233

241234
else:
242-
self._run(count=1)
235+
count = 1 if next_stop == self.cur_addr + 4 else 2
236+
self._run(count=count)
243237

244238
self.do_context()
245239

qiling/debugger/qdb/utils.py

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,8 @@ def regdst_eq_pc(op_str):
260260
to_jump = cb_table.get(line.mnemonic)(read_reg_val(line.op_str.split(", ")[0]))
261261

262262
if to_jump:
263-
if '#' in line.op_str:
264-
ret_addr = _parse_int(line.op_str.split('#')[-1])
263+
if "#" in line.op_str:
264+
ret_addr = _parse_int(line.op_str.split("#")[-1])
265265
else:
266266
ret_addr = read_reg_val(line.op_str)
267267

@@ -301,55 +301,62 @@ def regdst_eq_pc(op_str):
301301

302302
ret_addr = next_addr
303303

304-
return ret_addr
305-
306304
elif line.mnemonic in ("ldr",):
305+
307306
if regdst_eq_pc(line.op_str):
308-
_pc, _, rn_offset = line.op_str.partition(", ")
307+
_, _, rn_offset = line.op_str.partition(", ")
308+
r, _, imm = rn_offset.strip("[]!").partition(", #")
309309

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

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

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

322-
if line.mnemonic == "addls" and (C == 0 or Z == 1):
323-
r0, r1, r2, imm = line.op_str.split(", ")
324-
# program counter is awalys 8 bytes ahead , when it comes with pc need to add extra 8 bytes
325-
ret_addr = 8 + read_reg_val(r1) + read_reg_val(r2) * 4
321+
# program counter is awalys 8 bytes ahead when it comes with pc, need to add extra 8 bytes
322+
extra = 8 if 'pc' in (r0, r1, r2) else 0
323+
324+
if imm:
325+
expr = imm[0].split()
326+
# TODO: should support more bit shifting and rotating operation
327+
if expr[0] == "lsl": # logical shift left
328+
n = _parse_int(expr[-1].strip("#")) * 2
326329

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

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

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

337338
cur_addr += ARM_INST_SIZE
339+
r0, r1, *imm = line.op_str.strip("[]").split(", ")
340+
341+
if imm:
342+
expr = imm[0].split()
343+
if expr[0] == "lsl": # logical shift left
344+
n = _parse_int(expr[-1].strip("#")) * 2
338345

339346
if line.mnemonic == "tbh":
340-
r0, r1, _ = line.op_str.strip("[").strip("]").split(", ")
341-
r1 = read_reg_val(r1) * 2
347+
348+
r1 = read_reg_val(r1) * n
342349

343350
elif line.mnemonic == "tbb":
344-
r0, r1 = line.op_str.strip("[").strip("]").split(", ")
351+
345352
r1 = read_reg_val(r1)
346353

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

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

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

0 commit comments

Comments
 (0)