Skip to content

Commit 9f27c67

Browse files
committed
Merge remote-tracking branch 'qiling.io/dev' into dev
2 parents 54113d8 + aa69cd1 commit 9f27c67

File tree

11 files changed

+106
-92
lines changed

11 files changed

+106
-92
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ Qiling is an advanced binary emulation framework, with the following features:
2828

2929
Qiling also made its way to various international conferences.
3030

31+
2022:
32+
- [Black Hat, EU](https://www.blackhat.com/eu-22/arsenal/schedule/#reversing-mcu-with-firmware-emulation-29553)
33+
- [Black Hat, MEA](https://blackhatmea.com/node/724)
34+
3135
2021:
3236
- [Black Hat, USA](https://www.blackhat.com/us-21/arsenal/schedule/index.html#bringing-the-x-complete-re-experience-to-smart-contract-24119)
3337
- [Hack In The Box, Amsterdam](https://conference.hitb.org/hitbsecconf2021ams/sessions/when-qiling-framework-meets-symbolic-execution/)

qiling/arch/cortex_m.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from functools import cached_property
77
from contextlib import ContextDecorator
88

9-
from unicorn import Uc, UcError, UC_ARCH_ARM, UC_MODE_ARM, UC_MODE_MCLASS, UC_MODE_THUMB, UC_ERR_OK
9+
from unicorn import UC_ARCH_ARM, UC_MODE_ARM, UC_MODE_MCLASS, UC_MODE_THUMB
1010
from capstone import Cs, CS_ARCH_ARM, CS_MODE_ARM, CS_MODE_MCLASS, CS_MODE_THUMB
1111
from keystone import Ks, KS_ARCH_ARM, KS_MODE_ARM, KS_MODE_THUMB
1212

@@ -63,7 +63,7 @@ def __exit__(self, *exc):
6363

6464

6565
class QlArchCORTEX_M(QlArchARM):
66-
type = QL_ARCH.ARM
66+
type = QL_ARCH.CORTEX_M
6767
bits = 32
6868

6969
def __init__(self, ql: Qiling):

qiling/arch/utils.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,14 @@ def assembler(arch: QL_ARCH, endianess: QL_ENDIAN, is_thumb: bool) -> Ks:
106106
thumb = KS_MODE_THUMB if is_thumb else 0
107107

108108
asm_map = {
109-
QL_ARCH.ARM: (KS_ARCH_ARM, KS_MODE_ARM + endian + thumb),
110-
QL_ARCH.ARM64: (KS_ARCH_ARM64, KS_MODE_ARM),
111-
QL_ARCH.MIPS: (KS_ARCH_MIPS, KS_MODE_MIPS32 + endian),
112-
QL_ARCH.A8086: (KS_ARCH_X86, KS_MODE_16),
113-
QL_ARCH.X86: (KS_ARCH_X86, KS_MODE_32),
114-
QL_ARCH.X8664: (KS_ARCH_X86, KS_MODE_64),
115-
QL_ARCH.PPC: (KS_ARCH_PPC, KS_MODE_PPC32 + KS_MODE_BIG_ENDIAN)
109+
QL_ARCH.CORTEX_M: (KS_ARCH_ARM, KS_MODE_ARM + KS_MODE_LITTLE_ENDIAN + KS_MODE_THUMB),
110+
QL_ARCH.ARM: (KS_ARCH_ARM, KS_MODE_ARM + endian + thumb),
111+
QL_ARCH.ARM64: (KS_ARCH_ARM64, KS_MODE_ARM),
112+
QL_ARCH.MIPS: (KS_ARCH_MIPS, KS_MODE_MIPS32 + endian),
113+
QL_ARCH.A8086: (KS_ARCH_X86, KS_MODE_16),
114+
QL_ARCH.X86: (KS_ARCH_X86, KS_MODE_32),
115+
QL_ARCH.X8664: (KS_ARCH_X86, KS_MODE_64),
116+
QL_ARCH.PPC: (KS_ARCH_PPC, KS_MODE_PPC32 + KS_MODE_BIG_ENDIAN)
116117
}
117118

118119
if arch in asm_map:

qiling/const.py

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
#!/usr/bin/env python3
2-
#
2+
#
33
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
44
#
55

66
from enum import Enum, Flag, IntEnum
7-
from typing import Mapping, Type, TypeVar
7+
from typing import Final, Mapping, Type, TypeVar
8+
89

910
class QL_ENDIAN(IntEnum):
1011
EL = 1
1112
EB = 2
1213

14+
1315
class QL_ARCH(IntEnum):
1416
X86 = 101
1517
X8664 = 102
@@ -23,6 +25,7 @@ class QL_ARCH(IntEnum):
2325
RISCV64 = 111
2426
PPC = 112
2527

28+
2629
class QL_OS(IntEnum):
2730
LINUX = 201
2831
FREEBSD = 202
@@ -35,44 +38,53 @@ class QL_OS(IntEnum):
3538
MCU = 209
3639
BLOB = 210
3740

41+
3842
class QL_VERBOSE(IntEnum):
39-
DISABLED = -1 # turn off all the output
40-
OFF = 0 # output only warnings
41-
DEFAULT = 1 # output warnings and Qiling execute process information
42-
DEBUG = 4 # output all logs above and debug information, include syscall information
43-
DISASM = 10 # output all assembly instructions during Qiling execution
44-
DUMP = 20 # output any log Qiling can, include instructions and registers
43+
DISABLED = -1 # turn off all the output
44+
OFF = 0 # output only warnings
45+
DEFAULT = 1 # output warnings and Qiling execute process information
46+
DEBUG = 4 # output all logs above and debug information, include syscall information
47+
DISASM = 10 # output all assembly instructions during Qiling execution
48+
DUMP = 20 # output any log Qiling can, include instructions and registers
49+
4550

4651
class QL_DEBUGGER(IntEnum):
4752
GDB = 1
4853
IDAPRO = 2
4954
QDB = 3
5055

56+
5157
class QL_INTERCEPT(IntEnum):
5258
CALL = 1
5359
ENTER = 2
5460
EXIT = 3
5561

62+
5663
class QL_STOP(Flag):
5764
NONE = 0
5865
STACK_POINTER = (1 << 0)
59-
EXIT_TRAP = (1 << 1)
66+
EXIT_TRAP = (1 << 1)
67+
68+
69+
QL_ARCH_INTERPRETER: Final = (QL_ARCH.EVM,)
6070

61-
QL_ARCH_INTERPRETER = (QL_ARCH.EVM,)
71+
QL_OS_POSIX: Final = (QL_OS.LINUX, QL_OS.FREEBSD, QL_OS.MACOS, QL_OS.QNX)
72+
QL_OS_BAREMETAL: Final = (QL_OS.MCU,)
6273

63-
QL_OS_POSIX = (QL_OS.LINUX, QL_OS.FREEBSD, QL_OS.MACOS, QL_OS.QNX)
64-
QL_OS_BAREMETAL = (QL_OS.MCU,)
6574

6675
QL_HOOK_BLOCK = 0b0001
6776
QL_CALL_BLOCK = 0b0010
6877

6978
T = TypeVar('T', bound=Enum)
79+
80+
7081
def __casefold_enum(e: Type[T]) -> Mapping[str, T]:
7182
'''Create a casefolded mapping of an enum to allow case-insensitive lookup.
7283
'''
7384

7485
return dict((k.casefold(), v) for k, v in e._member_map_.items())
7586

87+
7688
debugger_map = __casefold_enum(QL_DEBUGGER)
7789
arch_map = __casefold_enum(QL_ARCH)
7890
os_map = __casefold_enum(QL_OS)

qiling/debugger/gdb/utils.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
from typing import Optional
77

88
from qiling import Qiling
9-
from qiling.const import QL_ARCH
109

1110
# this code is partially based on uDbg
1211
# @see: https://github.com/iGio90/uDdbg
1312

1413
PROMPT = r'gdb>'
1514

15+
1616
class QlGdbUtils:
1717
def __init__(self, ql: Qiling, entry_point: int, exit_point: int):
1818
self.ql = ql
@@ -32,10 +32,9 @@ def __entry_point_hook(ql: Qiling):
3232
# that hook will be used to set up the breakpoint handling hook
3333
ep_hret = ql.hook_address(__entry_point_hook, entry_point)
3434

35-
3635
def dbg_hook(self, ql: Qiling, address: int, size: int):
37-
if ql.arch.type == QL_ARCH.ARM and ql.arch.is_thumb:
38-
address += 1
36+
if getattr(ql.arch, 'is_thumb', False):
37+
address |= 1
3938

4039
# resuming emulation after hitting a breakpoint will re-enter this hook.
4140
# avoid an endless hooking loop by detecting and skipping this case
@@ -53,24 +52,21 @@ def dbg_hook(self, ql: Qiling, address: int, size: int):
5352
# ql.log.debug(f'{PROMPT} emulation entrypoint at {self.entry_point:#x}')
5453
# ql.log.debug(f'{PROMPT} emulation exitpoint at {self.exit_point:#x}')
5554

56-
5755
def bp_insert(self, addr: int):
5856
if addr not in self.bp_list:
5957
self.bp_list.append(addr)
6058
self.ql.log.info(f'{PROMPT} breakpoint added at {addr:#x}')
6159

62-
6360
def bp_remove(self, addr: int):
6461
self.bp_list.remove(addr)
6562
self.ql.log.info(f'{PROMPT} breakpoint removed from {addr:#x}')
6663

67-
6864
def resume_emu(self, address: Optional[int] = None, steps: int = 0):
6965
if address is None:
7066
address = self.ql.arch.regs.arch_pc
7167

72-
if self.ql.arch.type == QL_ARCH.ARM and self.ql.arch.is_thumb:
73-
address += 1
68+
if getattr(self.ql.arch, 'is_thumb', False):
69+
address |= 1
7470

7571
op = f'stepping {steps} instructions' if steps else 'resuming'
7672
self.ql.log.info(f'{PROMPT} {op} from {address:#x}')

qiling/debugger/qdb/qdb.py

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

6-
from typing import Callable, Optional, Mapping, Tuple, Union
7-
86
import cmd
97

8+
from typing import Optional, Tuple, Union
9+
1010
from qiling import Qiling
11-
from qiling.const import QL_OS, QL_ARCH, QL_VERBOSE
11+
from qiling.const import QL_OS, QL_ARCH
1212
from qiling.debugger import QlDebugger
1313

1414
from .utils import setup_context_render, setup_branch_predictor, setup_address_marker, SnapshotManager, run_qdb_script
@@ -18,6 +18,7 @@
1818

1919
from .utils import QDB_MSG, qdb_print
2020

21+
2122
class QlQdb(cmd.Cmd, QlDebugger):
2223
"""
2324
The built-in debugger of Qiling Framework
@@ -134,7 +135,7 @@ def _run(self, address: int = 0, end: int = 0, count: int = 0) -> None:
134135

135136
return
136137

137-
if self.ql.arch.type in (QL_ARCH.ARM, QL_ARCH.CORTEX_M) and self.ql.arch.is_thumb:
138+
if getattr(self.ql.arch, 'is_thumb', False):
138139
address |= 1
139140

140141
self.ql.emu_start(begin=address, end=end, count=count)
@@ -342,7 +343,7 @@ def do_examine(self, line: str) -> None:
342343

343344
if type(err_msg := self.mm.parse(line)) is str:
344345
qdb_print(QDB_MSG.ERROR, err_msg)
345-
346+
346347

347348
def do_set(self, line: str) -> None:
348349
"""

qiling/os/linux/linux.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,10 @@ def run(self):
163163

164164
elif self.ql.loader.elf_entry != self.ql.loader.entry_point:
165165
entry_address = self.ql.loader.elf_entry
166-
if self.ql.arch.type == QL_ARCH.ARM and entry_address & 1 == 1:
167-
entry_address -= 1
166+
167+
if self.ql.arch.type == QL_ARCH.ARM:
168+
entry_address &= ~1
169+
168170
self.ql.emu_start(self.ql.loader.entry_point, entry_address, self.ql.timeout)
169171
self.ql.do_lib_patch()
170172
self.run_function_after_load()

0 commit comments

Comments
 (0)