Skip to content

Commit 4a1418a

Browse files
Merge branch 'qilingframework:dev' into dev
2 parents 7a81888 + 187e0f3 commit 4a1418a

File tree

12 files changed

+355
-273
lines changed

12 files changed

+355
-273
lines changed

examples/netgear_6220_mips32el_linux.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def my_bind(ql: Qiling):
5858

5959
def my_netgear(path, rootfs):
6060
ql = Qiling(path, rootfs, verbose=QL_VERBOSE.DEBUG, profile="netgear_6220.ql", multithread=False)
61-
ql.root = False
61+
ql.os.root = False
6262

6363
ql.add_fs_mapper('/proc', '/proc')
6464
ql.set_syscall(4004, my_syscall_write)

qiling/core.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ def __init__(
9696
self._patch_lib = []
9797
self._debug_stop = False
9898
self._debugger = None
99-
self._root = False
10099

101100
###############################
102101
# Properties configured later #
@@ -588,19 +587,6 @@ def debugger(self) -> Union[str, bool]:
588587
def debugger(self, dbger):
589588
self._debugger = dbger
590589

591-
@property
592-
def root(self) -> bool:
593-
""" Whether run current program as root?
594-
595-
Type: bool
596-
Examples: ql.root = True
597-
"""
598-
return self._root
599-
600-
@root.setter
601-
def root(self, root):
602-
self._root = root
603-
604590
@property
605591
def filter(self) -> str:
606592
""" Filter logs with regex.

qiling/debugger/qdb/frontend.py

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

6-
import math, copy, os
6+
from __future__ import annotations
7+
from typing import Optional, Mapping, Iterable, Union
8+
9+
import copy, math, os
710
from contextlib import contextmanager
811

912
from qiling.const import QL_ARCH
10-
from .utils import dump_regs, get_arm_flags, disasm
11-
from .const import color
13+
14+
from .utils import dump_regs, get_arm_flags, disasm, parse_int
15+
from .const import *
1216

1317

1418
# read data from memory of qiling instance
15-
def examine_mem(ql, addr, fmt):
19+
def examine_mem(ql: Qiling, line: str) -> Union[bool, (str, int, int)]:
20+
21+
_args = line.split()
22+
DEFAULT_FMT = ('x', 4, 1)
23+
24+
if line.startswith("/"): # followed by format letter and size letter
25+
26+
def get_fmt(text):
27+
def extract_count(t):
28+
return "".join([s for s in t if s.isdigit()])
29+
30+
f, s, c = DEFAULT_FMT
31+
if extract_count(text):
32+
c = int(extract_count(text))
33+
34+
for char in text.strip(str(c)):
35+
if char in SIZE_LETTER.keys():
36+
s = SIZE_LETTER.get(char)
37+
38+
elif char in FORMAT_LETTER:
39+
f = char
40+
41+
return (f, s, c)
42+
43+
fmt, addr = line.strip("/").split()
44+
45+
fmt = get_fmt(fmt)
46+
47+
elif len(_args) == 1: # only address
48+
addr = _args[0]
49+
fmt = DEFAULT_FMT
50+
51+
else:
52+
return False
53+
54+
addr = addr.strip('$')
55+
56+
if ql.archtype in (QL_ARCH.ARM, QL_ARCH.ARM_THUMB):
57+
addr = addr.replace("fp", "r11")
58+
59+
elif ql.archtype == QL_ARCH.MIPS:
60+
addr = addr.replace("fp", "s8")
61+
62+
addr = getattr(ql.reg, addr) if addr in ql.reg.register_mapping.keys() else parse_int(addr)
1663

1764
def unpack(bs, sz):
1865
return {
@@ -29,7 +76,7 @@ def unpack(bs, sz):
2976
for offset in range(addr, addr+ct*4, 4):
3077
line = disasm(ql, offset)
3178
if line:
32-
print("0x{:x}: {}\t{}".format(line.address, line.mnemonic, line.op_str))
79+
print(f"0x{line.address:x}: {line.mnemonic}\t{line.op_str}")
3380

3481
print()
3582

@@ -40,27 +87,29 @@ def unpack(bs, sz):
4087

4188
for line in range(lines):
4289
offset = line * sz * 4
43-
print("0x{:x}:\t".format(addr+offset), end="")
90+
print("0x{addr+offset:x}:\t", end="")
4491

45-
idx = line * 4
46-
for each in mem_read[idx:idx+4]:
92+
idx = line * ql.pointersize
93+
for each in mem_read[idx:idx+ql.pointersize]:
4794
data = unpack(each, sz)
4895
prefix = "0x" if ft in ("x", "a") else ""
4996
pad = '0' + str(sz*2) if ft in ('x', 'a', 't') else ''
5097
ft = ft.lower() if ft in ("x", "o", "b", "d") else ft.lower().replace("t", "b").replace("a", "x")
5198

52-
print("{}{{:{}{}}}\t".format(prefix, pad, ft).format(data), end="")
99+
print(f"{prefix}{data:{pad}{ft}}\t", end="")
53100

54101
print()
55102

103+
return True
104+
56105

57106
# get terminal window height and width
58-
def get_terminal_size():
107+
def get_terminal_size() -> Iterable:
59108
return map(int, os.popen('stty size', 'r').read().split())
60109

61110

62111
# try to read data from ql memory
63-
def _try_read(ql, address, size):
112+
def _try_read(ql: Qiling, address: int, size: int) -> Optional[bytes]:
64113
try:
65114
result = ql.mem.read(address, size)
66115
except:
@@ -71,14 +120,14 @@ def _try_read(ql, address, size):
71120

72121
# divider printer
73122
@contextmanager
74-
def context_printer(ql, field_name, ruler="="):
123+
def context_printer(ql: Qiling, field_name: str, ruler: str = "=") -> None:
75124
_height, _width = get_terminal_size()
76125
print(field_name, ruler * (_width - len(field_name) - 1))
77126
yield
78127
print(ruler * _width)
79128

80129

81-
def context_reg(ql, saved_states=None, *args, **kwargs):
130+
def context_reg(ql: Qiling, saved_states: Optional[Mapping[str, int]] = None, /, *args, **kwargs) -> None:
82131

83132
# context render for registers
84133
with context_printer(ql, "[Registers]"):
@@ -104,7 +153,7 @@ def context_reg(ql, saved_states=None, *args, **kwargs):
104153
line = "{}{}: 0x{{:08x}} {}\t".format(_colors[(idx-1) // 4], r, color.END)
105154

106155
if _diff and r in _diff:
107-
line = "{}{}".format(color.UNDERLINE, color.BOLD) + line
156+
line = f"{color.UNDERLINE}{color.BOLD}{line}"
108157

109158
if idx % 4 == 0 and idx != 32:
110159
line += "\n"
@@ -152,45 +201,61 @@ def context_reg(ql, saved_states=None, *args, **kwargs):
152201
_val = ql.mem.read(_addr, ql.pointersize)
153202
print(f"$sp+0x{idx*4:02x}|[0x{_addr:08x}]=> 0x{ql.unpack(_val):08x}", end="")
154203

155-
try: # try to deference wether its a pointer
156-
_deref = ql.mem.read(_addr, 4)
204+
try: # try to deference wether its a pointer
205+
_deref = ql.mem.read(_addr, ql.pointersize)
157206
except:
158207
_deref = None
159208

160209
if _deref:
161210
print(f" => 0x{ql.unpack(_deref):08x}")
162211

163212

164-
def print_asm(ql, instructions):
165-
for ins in instructions:
166-
fmt = (ins.address, ins.mnemonic.ljust(6), ins.op_str)
167-
if ql.reg.arch_pc == ins.address:
168-
print(f"PC ==> 0x{fmt[0]:x}\t{fmt[1]} {fmt[2]}")
169-
else:
170-
print(f"\t0x{fmt[0]:x}\t{fmt[1]} {fmt[2]}")
213+
def print_asm(ql: Qiling, ins: CsInsn) -> None:
214+
fmt = (ins.address, ins.mnemonic.ljust(6), ins.op_str)
215+
if ql.reg.arch_pc == ins.address:
216+
print(f"PC ==> 0x{fmt[0]:x}\t{fmt[1]} {fmt[2]}")
217+
else:
218+
print(f"\t0x{fmt[0]:x}\t{fmt[1]} {fmt[2]}")
171219

172220

173-
def context_asm(ql, address, size, *args, **kwargs):
221+
def context_asm(ql: Qiling, address: int) -> None:
174222

175223
with context_printer(ql, field_name="[Code]"):
176-
md = ql.create_disassembler()
177224

178225
# assembly before current location
179226

180-
pre_tmp = _try_read(ql, address-0x10, 0x10)
181-
if pre_tmp:
182-
pre_ins = md.disasm(pre_tmp, address-0x10)
183-
print_asm(ql, pre_ins)
227+
past_list = []
228+
229+
if ql.archtype in (QL_ARCH.MIPS, QL_ARCH.ARM, QL_ARCH.ARM_THUMB):
230+
231+
line = disasm(ql, address-0x10)
232+
233+
while line:
234+
if line.address == address:
235+
break
236+
237+
addr = line.address + line.size
238+
line = disasm(ql, addr)
239+
240+
if not line:
241+
break
242+
243+
past_list.append(line)
244+
245+
# print four insns before current location
246+
for line in past_list[:-1][:4]:
247+
print_asm(ql, line)
184248

185-
# assembly for current locaton
249+
# assembly for current location
186250

187-
tmp = ql.mem.read(address, size)
188-
cur_ins = md.disasm(tmp, address)
251+
cur_ins = disasm(ql, address)
189252
print_asm(ql, cur_ins)
190253

191-
# assembly after current locaton
254+
# assembly after current location
192255

193-
pos_tmp = _try_read(ql, address+4, 0x10)
194-
if pos_tmp:
195-
pos_ins = md.disasm(pos_tmp, address+4)
196-
print_asm(ql, pos_ins)
256+
forward_insn_size = cur_ins.size
257+
for _ in range(5):
258+
forward_insn = disasm(ql, address+forward_insn_size)
259+
if forward_insn:
260+
print_asm(ql, forward_insn)
261+
forward_insn_size += forward_insn.size

0 commit comments

Comments
 (0)