From 734e1ab455a12e2880c697fb96b61519d3968e7c Mon Sep 17 00:00:00 2001 From: elicn Date: Mon, 19 Sep 2022 16:29:50 +0300 Subject: [PATCH 01/13] Relocate catch_KeyboardInterrupt and rename to hookcallback --- qiling/core_hooks.py | 19 ++++++++++++++++--- qiling/utils.py | 10 ---------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/qiling/core_hooks.py b/qiling/core_hooks.py index 0a8e4cb83..f142684fd 100644 --- a/qiling/core_hooks.py +++ b/qiling/core_hooks.py @@ -8,6 +8,7 @@ # handling hooks # ############################################## +import functools from typing import Any, Callable, MutableMapping, MutableSequence, Protocol from typing import TYPE_CHECKING @@ -15,7 +16,6 @@ from unicorn.unicorn_const import * from .core_hooks_types import Hook, HookAddr, HookIntr, HookRet -from .utils import catch_KeyboardInterrupt from .const import QL_HOOK_BLOCK from .exception import QlErrorCoreHook @@ -86,6 +86,19 @@ def __call__(self, __ql: 'Qiling', intno: int, *__context: Any) -> Any: pass +def hookcallback(ql: 'Qiling', callback: Callable): + + functools.wraps(callback) + def wrapper(*args, **kwargs): + try: + return callback(*args, **kwargs) + except (KeyboardInterrupt, Exception) as ex: + ql.stop() + ql._internal_exception = ex + + return wrapper + + # Don't assume self is Qiling. class QlCoreHooks: def __init__(self, uc: Uc): @@ -235,13 +248,13 @@ def _hook_addr_cb(self, uc: Uc, addr: int, size: int, pack_data): # Class Hooks # ############### def _ql_hook_internal(self, hook_type: int, callback: Callable, context: Any, *args) -> int: - _callback = catch_KeyboardInterrupt(self, callback) + _callback = hookcallback(self, callback) return self._h_uc.hook_add(hook_type, _callback, (self, context), 1, 0, *args) def _ql_hook_addr_internal(self, callback: Callable, address: int) -> int: - _callback = catch_KeyboardInterrupt(self, callback) + _callback = hookcallback(self, callback) return self._h_uc.hook_add(UC_HOOK_CODE, _callback, self, address, address) diff --git a/qiling/utils.py b/qiling/utils.py index 34ce265e1..b3b048019 100644 --- a/qiling/utils.py +++ b/qiling/utils.py @@ -32,15 +32,6 @@ T = TypeVar('T') QlClassInit = Callable[['Qiling'], T] -def catch_KeyboardInterrupt(ql: 'Qiling', func: Callable): - def wrapper(*args, **kw): - try: - return func(*args, **kw) - except BaseException as e: - ql.stop() - ql._internal_exception = e - - return wrapper def __name_to_enum(name: str, mapping: Mapping[str, T], aliases: Mapping[str, str] = {}) -> Optional[T]: key = name.casefold() @@ -473,7 +464,6 @@ def verify_ret(ql: 'Qiling', err): raise __all__ = [ - 'catch_KeyboardInterrupt', 'os_convert', 'arch_convert', 'debugger_convert', From 24b737336862c5d919d102164e75c4c70cc358b6 Mon Sep 17 00:00:00 2001 From: elicn Date: Mon, 19 Sep 2022 16:35:39 +0300 Subject: [PATCH 02/13] Revisit propagation of emulation exceptions --- qiling/core.py | 8 ++++++-- qiling/os/dos/dos.py | 3 --- qiling/os/macos/macos.py | 3 --- qiling/os/uefi/uefi.py | 7 +------ 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/qiling/core.py b/qiling/core.py index e040144a6..a25c2d354 100644 --- a/qiling/core.py +++ b/qiling/core.py @@ -710,7 +710,11 @@ def emu_start(self, begin: int, end: int, timeout: int = 0, count: int = 0): if self._arch.type in (QL_ARCH.ARM, QL_ARCH.CORTEX_M) and self._arch._init_thumb: begin |= 1 + # reset exception status before emulation starts + self._internal_exception = None + self.uc.emu_start(begin, end, timeout, count) - if self._internal_exception is not None: - raise self._internal_exception + # if an exception was raised during emulation, propagate it up + if self.internal_exception is not None: + raise self.internal_exception diff --git a/qiling/os/dos/dos.py b/qiling/os/dos/dos.py index fb7f55c17..d1e3a85da 100644 --- a/qiling/os/dos/dos.py +++ b/qiling/os/dos/dos.py @@ -117,6 +117,3 @@ def run(self): except UcError: self.emu_error() raise - - if self.ql._internal_exception != None: - raise self.ql._internal_exception diff --git a/qiling/os/macos/macos.py b/qiling/os/macos/macos.py index eb7f38ee2..2c700e01f 100644 --- a/qiling/os/macos/macos.py +++ b/qiling/os/macos/macos.py @@ -216,6 +216,3 @@ def callback_ret(ql): raise self.RUN = False - - if self.ql._internal_exception != None: - raise self.ql._internal_exception \ No newline at end of file diff --git a/qiling/os/uefi/uefi.py b/qiling/os/uefi/uefi.py index 67163e90b..a3f481cf0 100644 --- a/qiling/os/uefi/uefi.py +++ b/qiling/os/uefi/uefi.py @@ -220,18 +220,13 @@ def run(self): self.PE_RUN = True self.ql.emu_start(self.ql.loader.entry_point, self.exit_point, self.ql.timeout, self.ql.count) - except KeyboardInterrupt as ex: + except KeyboardInterrupt: self.ql.log.critical(f'Execution interrupted by user') - if self.ql._internal_exception is ex: - self.ql._internal_exception = None except UcError: self.emu_error() raise - if self.ql._internal_exception is not None: - raise self.ql._internal_exception - def stop(self) -> None: self.ql.emu_stop() self.PE_RUN = False From 7cbe2b56ffd03d8d6f7894239264276bcca4cfb6 Mon Sep 17 00:00:00 2001 From: elicn Date: Mon, 19 Sep 2022 16:40:12 +0300 Subject: [PATCH 03/13] Make r2 extention tests depended on libr --- tests/test_r2.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/test_r2.py b/tests/test_r2.py index 97c180288..b25681089 100644 --- a/tests/test_r2.py +++ b/tests/test_r2.py @@ -5,12 +5,18 @@ sys.path.append("..") from qiling import Qiling from qiling.const import QL_VERBOSE -from qiling.extensions.r2.r2 import R2 +try: + from qiling.extensions.r2.r2 import R2 +except ImportError: + test_r2 = False +else: + test_r2 = True EVM_CODE = bytes.fromhex("6060604052341561000f57600080fd5b60405160208061031c833981016040528080519060200190919050508060018190556000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050610299806100836000396000f300606060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806318160ddd1461005c57806370a0823114610085578063a9059cbb146100d2575b600080fd5b341561006757600080fd5b61006f61012c565b6040518082815260200191505060405180910390f35b341561009057600080fd5b6100bc600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610132565b6040518082815260200191505060405180910390f35b34156100dd57600080fd5b610112600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061017a565b604051808215151515815260200191505060405180910390f35b60015481565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600080826000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205403101515156101cb57600080fd5b816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060019050929150505600a165627a7a7230582098f1551a391a3e65b3ce45cfa2b3fa5f91eea9a3e7181a81454e025ea0d7151c0029") +@unittest.skipUnless(test_r2, 'libr is missing') class R2Test(unittest.TestCase): def test_shellcode_disasm(self): ql = Qiling(code=EVM_CODE, archtype="evm", verbose=QL_VERBOSE.DISABLED) From 135560aea5766548d4255a49534e75708e21de26 Mon Sep 17 00:00:00 2001 From: elicn Date: Wed, 28 Sep 2022 19:47:05 +0300 Subject: [PATCH 04/13] Minor linter-friendly tweaks --- qiling/core.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/qiling/core.py b/qiling/core.py index a25c2d354..90e555dcb 100644 --- a/qiling/core.py +++ b/qiling/core.py @@ -78,9 +78,9 @@ def __init__( ############################### self.entry_point = None self.exit_point = None - self.timeout = None - self.count = None - self._initial_sp = None + self.timeout = 0 + self.count = 0 + self._initial_sp = 0 """ Qiling Framework Core Engine @@ -203,7 +203,7 @@ def mem(self) -> "QlMemoryManager": def hw(self) -> "QlHwManager": """ Qiling hardware manager. - Example: + Example: """ return self._hw @@ -298,13 +298,13 @@ def env(self) -> MutableMapping[AnyStr, AnyStr]: return self._env @property - def code(self) -> bytes: + def code(self) -> Optional[bytes]: """ The shellcode to execute. Note: It can't be used with "argv" parameter. Type: bytes - Example: Qiling(code=b"\x90", ostype="macos", archtype="x8664") + Example: Qiling(code=b"\\x90", ostype="macos", archtype="x8664") """ return self._code @@ -318,7 +318,7 @@ def path(self) -> str: @property def targetname(self) -> str: - """ The target name of the executable. e.g. "c.exe" in "a\b\c.exe" + """ The target name of the executable. e.g. "c.exe" in "a\\b\\c.exe" Type: str """ @@ -573,7 +573,7 @@ def run(self, begin: Optional[int] = None, end: Optional[int] = None, timeout: i # patch code to memory address - def patch(self, offset: int, data: bytes, target: str = None) -> None: + def patch(self, offset: int, data: bytes, target: Optional[str] = None) -> None: """Volatilely patch binary and libraries with arbitrary content. Patching may be done prior to emulation start. @@ -590,7 +590,7 @@ def patch(self, offset: int, data: bytes, target: str = None) -> None: # save all qiling instance states - def save(self, reg=True, mem=True, hw=False, fd=False, cpu_context=False, os=False, loader=False, *, snapshot: str = None): + def save(self, reg=True, mem=True, hw=False, fd=False, cpu_context=False, os=False, loader=False, *, snapshot: Optional[str] = None): saved_states = {} if reg: @@ -622,7 +622,7 @@ def save(self, reg=True, mem=True, hw=False, fd=False, cpu_context=False, os=Fal # restore states qiling instance from saved_states - def restore(self, saved_states: Mapping[str, Any] = {}, *, snapshot: str = None): + def restore(self, saved_states: Mapping[str, Any] = {}, *, snapshot: Optional[str] = None): # snapshot will be ignored if saved_states is set if (not saved_states) and (snapshot is not None): @@ -658,7 +658,7 @@ def add_fs_mapper(self, ql_path: Union["PathLike", str], real_dest): # Remove "ql_path" mapping. def remove_fs_mapper(self, ql_path: Union["PathLike", str]): self.os.fs_mapper.remove_fs_mapping(ql_path) - + # push to stack bottom, and update stack register def stack_push(self, data): return self.arch.stack_push(data) @@ -684,17 +684,17 @@ def stack_write(self, offset, data): # stop emulation def emu_stop(self): self.uc.emu_stop() - + # stop emulation def stop(self): if self.multithread: - self.os.thread_management.stop() + self.os.thread_management.stop() elif self.baremetal: self.os.stop() else: - self.uc.emu_stop() + self.uc.emu_stop() # start emulation def emu_start(self, begin: int, end: int, timeout: int = 0, count: int = 0): @@ -715,6 +715,6 @@ def emu_start(self, begin: int, end: int, timeout: int = 0, count: int = 0): self.uc.emu_start(begin, end, timeout, count) - # if an exception was raised during emulation, propagate it up + # if an exception was raised during emulation, propagate it up if self.internal_exception is not None: raise self.internal_exception From 9a9d592007f0426c081fc6f6d48b4412a5109b1f Mon Sep 17 00:00:00 2001 From: elicn Date: Wed, 28 Sep 2022 19:48:11 +0300 Subject: [PATCH 05/13] Delay QlHost creation --- qiling/core.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/qiling/core.py b/qiling/core.py index 90e555dcb..a0d510827 100644 --- a/qiling/core.py +++ b/qiling/core.py @@ -4,6 +4,7 @@ # import os, pickle +from functools import cached_property from typing import TYPE_CHECKING, Any, AnyStr, List, Mapping, MutableMapping, Optional, Sequence, Tuple, Union # See https://stackoverflow.com/questions/39740632/python-type-hinting-without-cyclic-imports @@ -109,8 +110,6 @@ def __init__( ################# # arch os setup # ################# - self._host = QlHost() - if type(archtype) is str: archtype = arch_convert(archtype) @@ -348,12 +347,12 @@ def baremetal(self) -> bool: return self.os.type in QL_OS_BAREMETAL - @property + @cached_property def host(self) -> QlHost: """Provide an interface to the hosting platform where Qiling runs on. """ - return self._host + return QlHost() @property def internal_exception(self) -> Optional[Exception]: From f498b6a8501b6bb39758969eae5a2afa4318f806 Mon Sep 17 00:00:00 2001 From: elicn Date: Wed, 28 Sep 2022 20:18:59 +0300 Subject: [PATCH 06/13] Make path and targetname properties dynamic --- qiling/core.py | 6 ++---- qiling/loader/macho.py | 1 - qiling/os/posix/syscall/unistd.py | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/qiling/core.py b/qiling/core.py index a0d510827..d62290970 100644 --- a/qiling/core.py +++ b/qiling/core.py @@ -96,8 +96,6 @@ def __init__( raise QlErrorFileNotFound(f'Target binary not found: "{argv[0]}"') self._argv = argv - self._path = self.argv[0] - self._targetname = os.path.basename(self.path) ################ # rootfs setup # @@ -313,7 +311,7 @@ def path(self) -> str: Type: str """ - return self._path + return self.argv[0] @property def targetname(self) -> str: @@ -321,7 +319,7 @@ def targetname(self) -> str: Type: str """ - return self._targetname + return os.path.basename(self.path) @property def interpreter(self) -> bool: diff --git a/qiling/loader/macho.py b/qiling/loader/macho.py index 5c0e5c21a..a7e7f87bc 100644 --- a/qiling/loader/macho.py +++ b/qiling/loader/macho.py @@ -80,7 +80,6 @@ def __init__(self, ql, dyld_path=None): self.kext_name = os.path.splitext(basename)[0] filename = self.ql.argv self.ql._argv = [self.ql.argv[0] + "/Contents/MacOS/" + self.kext_name] - self.ql._path = self.ql.argv[0] self.plist = plistlib.load(open(filename[0] + "/Contents/Info.plist", "rb")) if "IOKitPersonalities" in self.plist: self.IOKit = True diff --git a/qiling/os/posix/syscall/unistd.py b/qiling/os/posix/syscall/unistd.py index 9d715bfa0..6ce90c2de 100644 --- a/qiling/os/posix/syscall/unistd.py +++ b/qiling/os/posix/syscall/unistd.py @@ -481,7 +481,7 @@ def __read_str_array(addr: int) -> Iterator[str]: ql.loader.argv = args ql.loader.env = env - ql._path = real_path + ql._argv = [real_path] + args ql.mem.map_info = [] ql.clear_ql_hooks() From 207fd9466f6807fe7943aaaa85f617ecc7a5dcbc Mon Sep 17 00:00:00 2001 From: elicn Date: Wed, 28 Sep 2022 20:20:45 +0300 Subject: [PATCH 07/13] Redefine QlDebugger --- qiling/debugger/__init__.py | 4 ++-- qiling/debugger/debugger.py | 24 ++++++++---------------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/qiling/debugger/__init__.py b/qiling/debugger/__init__.py index eeadc6bf8..57e0576ed 100644 --- a/qiling/debugger/__init__.py +++ b/qiling/debugger/__init__.py @@ -1,3 +1,3 @@ from .debugger import QlDebugger -from .disassember import QlDisassember -from .utils import QlReadELF +# from .disassember import QlDisassember +# from .utils import QlReadELF diff --git a/qiling/debugger/debugger.py b/qiling/debugger/debugger.py index 233f655e6..fe8f2812e 100644 --- a/qiling/debugger/debugger.py +++ b/qiling/debugger/debugger.py @@ -3,24 +3,16 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -from qiling import Qiling +from typing import TYPE_CHECKING -class QlDebugger(): - def __init__(self, ql:Qiling): - self.ql = ql - - def dbg_start(self): - pass +if TYPE_CHECKING: + from qiling import Qiling - def dbg_run(self, begin_addr=None, end_addr=None): - self.ql.emu_start(begin=begin_addr, end=end_addr) - - def dbg_step(self): - pass - def dbg_continue(self): - pass +class QlDebugger: + def __init__(self, ql: 'Qiling'): + self.ql = ql - def dbg_set_breakpoint(self): - pass + def run(self): + raise NotImplementedError From 2bd8003dc8817674e2e104715fb99e66bb960591 Mon Sep 17 00:00:00 2001 From: elicn Date: Wed, 28 Sep 2022 20:51:36 +0300 Subject: [PATCH 08/13] Better corner case handling for GetProcAddress --- .../os/windows/dlls/kernel32/libloaderapi.py | 48 ++++++++++++------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/qiling/os/windows/dlls/kernel32/libloaderapi.py b/qiling/os/windows/dlls/kernel32/libloaderapi.py index 2f0370c22..29b4ce88f 100644 --- a/qiling/os/windows/dlls/kernel32/libloaderapi.py +++ b/qiling/os/windows/dlls/kernel32/libloaderapi.py @@ -134,37 +134,49 @@ def hook_GetProcAddress(ql: Qiling, address: int, params): hModule = params['hModule'] lpProcName = params['lpProcName'] + procname = None + ordinal = None + + # if lpProcName is a short integer, it is an ordinal. otherwise, that is a function name. if lpProcName > MAXUSHORT: - # Look up by name - params["lpProcName"] = ql.os.utils.read_cstring(lpProcName) - lpProcName = bytes(params["lpProcName"], "ascii") - else: - # Look up by ordinal - lpProcName = params["lpProcName"] + procname = ql.os.utils.read_cstring(lpProcName) - # TODO fix for gandcrab - if lpProcName == "RtlComputeCrc32": - return 0 + # let log output reflect a human-readable procname + params["lpProcName"] = procname + + # WORKAROUND for gandcrab + if procname == "RtlComputeCrc32": + return 0 + + procname = procname.encode('latin1') + + else: + ordinal = lpProcName - # Check if dll is loaded + # get dll name by handle (module base) dll_name = next((os.path.basename(image.path).casefold() for image in ql.loader.images if image.base == hModule), None) if dll_name is None: - ql.log.info('Failed to import function "%s" with handle 0x%X' % (lpProcName, hModule)) + ql.log.info(f'Failed to import function "{lpProcName}" with handle {hModule:#x}') return 0 # Handle case where module is self if dll_name == os.path.basename(ql.loader.path).casefold(): - for addr, export in ql.loader.export_symbols.items(): - if export['name'] == lpProcName: - return addr + if procname is not None: + search_func = lambda entry: entry['name'] == procname - iat = ql.loader.import_address_table[dll_name] + elif ordinal is not None: + search_func = lambda entry: entry['ord'] == ordinal + + else: + raise AssertionError + + return next((addr for addr, entry in ql.loader.export_symbols.items() if search_func(entry)), 0) - if lpProcName in iat: - return iat[lpProcName] + # in any other case, look through the import address table for that dll + iat = ql.loader.import_address_table[dll_name] - return 0 + return iat.get(procname or ordinal, 0) def _LoadLibrary(ql: Qiling, address: int, params): lpLibFileName = params["lpLibFileName"] From 6b9a4187130c289141af9ae28f8f40f6a61c168b Mon Sep 17 00:00:00 2001 From: elicn Date: Sun, 2 Oct 2022 19:22:03 +0300 Subject: [PATCH 09/13] Add hardware debug registers to x86 arch --- qiling/arch/x86.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qiling/arch/x86.py b/qiling/arch/x86.py index 0a787e8b9..0147c1a31 100644 --- a/qiling/arch/x86.py +++ b/qiling/arch/x86.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# +# # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # @@ -71,6 +71,7 @@ def regs(self) -> QlRegisterManager: **x86_const.reg_map_16, **x86_const.reg_map_32, **x86_const.reg_map_cr, + **x86_const.reg_map_dr, **x86_const.reg_map_st, **x86_const.reg_map_misc ) @@ -104,6 +105,7 @@ def regs(self) -> QlRegisterManager: **x86_const.reg_map_32, **x86_const.reg_map_64, **x86_const.reg_map_cr, + **x86_const.reg_map_dr, **x86_const.reg_map_st, **x86_const.reg_map_misc, **x86_const.reg_map_64_b, From fa8a840e77d845460e55bc6a110e476edb592328 Mon Sep 17 00:00:00 2001 From: elicn Date: Tue, 4 Oct 2022 15:25:24 +0300 Subject: [PATCH 10/13] Improve core attributes documentation --- qiling/core.py | 114 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 77 insertions(+), 37 deletions(-) diff --git a/qiling/core.py b/qiling/core.py index d62290970..452b42138 100644 --- a/qiling/core.py +++ b/qiling/core.py @@ -248,12 +248,7 @@ def log(self) -> "Logger": @property def multithread(self) -> bool: - """ Specify whether multithread has been enabled. - - WARNING: This property shouldn't be set after Qiling.__init__. - - Type: bool - Example: Qiling(multithread=True) + """Detremine whether multi-threading has been enabled. """ return self._multithread @@ -271,18 +266,32 @@ def profile(self) -> "ConfigParser": @property def argv(self) -> Sequence[str]: - """ The program argv. + """Emulated program arguments. + Note that `code` and `argv` are mutually exclusive. - Example: Qiling(argv=['/bin/ls', '-a']) + Example: + >>> ql = Qiling([r'myrootfs/path/to/target.bin', 'arg1'], 'myrootfs') + >>> ql.argv + ['myrootfs/path/to/target.bin', 'arg1'] """ return self._argv @property def rootfs(self) -> str: - """ The program rootfs. For some common rootfs, see examples/rootfs/ for details. + """Path to emulated system root directory, to which the emulated program + will be confined to. - Type: str - Example: Qiling(argv=['/bin/ls', '-a'], rootfs='examples/rootfs/x8664_linux/') + Everything under rootfs is accessible by the emulated program. DO NOT USE + the hosting system root directory unless you ABSOLUTLEY TRUST the emulated + program. + + For commonly used rootfs, see directories under examples/rootfs/ + + Example: + >>> ROOTFS = r'examples/rootfs/x8664_linux' + >>> ql = Qiling([rf'{ROOTFS}/bin/ping', '-n', '-4'], ROOTFS) + >>> ql.rootfs + 'examples/rootfs/x8664_linux' """ return self._rootfs @@ -296,47 +305,56 @@ def env(self) -> MutableMapping[AnyStr, AnyStr]: @property def code(self) -> Optional[bytes]: - """ The shellcode to execute. - - Note: It can't be used with "argv" parameter. - - Type: bytes - Example: Qiling(code=b"\\x90", ostype="macos", archtype="x8664") + """The shellcode that was set for execution, or `None` if not set. + Note that `code` and `argv` are mutually exclusive. + + Example: + >>> EXIT_SYSCALL = bytes.fromhex( + '''31 c0 ''' # xor eax, eax + '''40 ''' # inc eax + '''cd 80 ''' # int 0x80 + ) + >>> ql = Qiling(code=EXIT_SYSCALL, ostype=QL_OS.LINUX, archtype=QL_ARCH.X86) + >>> ql.code + b'1\\xc0@\\xcd\\x80' """ return self._code @property def path(self) -> str: - """ The file path of the executable. + """Emulated binary path as specified in argv. - Type: str + Example: + >>> ql = Qiling([r'myrootfs/path/to/target.bin', 'arg1'], 'myrootfs') + >>> ql.targetname + 'myrootfs/path/to/target.bin' """ return self.argv[0] @property def targetname(self) -> str: - """ The target name of the executable. e.g. "c.exe" in "a\\b\\c.exe" + """Emulated binary base name. - Type: str + Example: + >>> ql = Qiling([r'myrootfs/path/to/target.bin', 'arg1'], 'myrootfs') + >>> ql.targetname + 'target.bin' """ return os.path.basename(self.path) @property def interpreter(self) -> bool: - """ Interpreter Engine - - Blockchain related - - Java engine? + """Indicate whether an interpreter engine is being emulated. - Type: bool + Currently supporting: EVM """ return self.arch.type in QL_ARCH_INTERPRETER @property def baremetal(self) -> bool: - """ MCU / Bare Metal type - - STM32, RTOS + """Indicate whether a baremetal system is being emulated. - Type: bool + Currently supporting: MCU """ # os is not initialized for interpreter archs @@ -354,7 +372,7 @@ def host(self) -> QlHost: @property def internal_exception(self) -> Optional[Exception]: - """ Internal exception catched during Unicorn callback. Not intended for regular users. + """Internal exception caught during Unicorn callback. Not intended for regular users. Type: Exception """ @@ -362,7 +380,7 @@ def internal_exception(self) -> Optional[Exception]: @property def verbose(self) -> QL_VERBOSE: - """Set verbosity level. + """Set logging verbosity level. Values: `QL_VERBOSE.DISABLED`: turn off logging @@ -568,8 +586,6 @@ def run(self, begin: Optional[int] = None, end: Optional[int] = None, timeout: i if debugger and self.debugger: debugger.run() - - # patch code to memory address def patch(self, offset: int, data: bytes, target: Optional[str] = None) -> None: """Volatilely patch binary and libraries with arbitrary content. Patching may be done prior to emulation start. @@ -585,9 +601,23 @@ def patch(self, offset: int, data: bytes, target: Optional[str] = None) -> None: else: self.patch_lib.append((offset, data, target)) - - # save all qiling instance states def save(self, reg=True, mem=True, hw=False, fd=False, cpu_context=False, os=False, loader=False, *, snapshot: Optional[str] = None): + """Pack Qiling's current state into an object and optionally dump it to a file. + Specific components may be included or excluded from the save state. + + Args: + reg : include all registers values + mem : include memory layout and content + hw : include hardware entities state (baremetal only) + fd : include OS file descriptors table, where supported + cpu_context : include underlying Unicorn state + os : include OS-related state + loader : include Loader-related state + snapshot : specify a filename to dump the state into (optional) + + Returns: a dictionary holding Qiling's current state + """ + saved_states = {} if reg: @@ -617,9 +647,18 @@ def save(self, reg=True, mem=True, hw=False, fd=False, cpu_context=False, os=Fal return saved_states - - # restore states qiling instance from saved_states def restore(self, saved_states: Mapping[str, Any] = {}, *, snapshot: Optional[str] = None): + """Unpack and apply a saved Qiling state. + Only saved components will be restored; the rest remains intact. + + Args: + saved_states : a saved state dictionary originally created by the `save` method + snapshot : path of a snapshot file containing a dumped saved state. + + Notes: + Only restore a saved state provided by a trusted entity. + In case both arguments are provided, snapshot file will be ignored + """ # snapshot will be ignored if saved_states is set if (not saved_states) and (snapshot is not None): @@ -701,7 +740,7 @@ def emu_start(self, begin: int, end: int, timeout: int = 0, count: int = 0): begin : emulation starting address end : emulation ending address timeout : max emulation time (in microseconds); unlimited by default - count : max emulation steps (instructions count); unlimited by default + count : max emulation steps (instructions count); unlimited by default """ if self._arch.type in (QL_ARCH.ARM, QL_ARCH.CORTEX_M) and self._arch._init_thumb: @@ -710,6 +749,7 @@ def emu_start(self, begin: int, end: int, timeout: int = 0, count: int = 0): # reset exception status before emulation starts self._internal_exception = None + # effectively start the emulation. this returns only after uc.emu_stop is called self.uc.emu_start(begin, end, timeout, count) # if an exception was raised during emulation, propagate it up From 11e63707371f440787ee7260de3730da0ba708b8 Mon Sep 17 00:00:00 2001 From: elicn Date: Tue, 4 Oct 2022 15:27:09 +0300 Subject: [PATCH 11/13] Remove an obsolete DOS profile setting --- qiling/profiles/dos.ql | 1 - 1 file changed, 1 deletion(-) diff --git a/qiling/profiles/dos.ql b/qiling/profiles/dos.ql index 550d0f8d0..2d865a9a5 100644 --- a/qiling/profiles/dos.ql +++ b/qiling/profiles/dos.ql @@ -10,5 +10,4 @@ stack_size = 0x4000 base_address = 0x7000 [MISC] -automatize_input = False current_path = A:\ \ No newline at end of file From 4ead520dedc6ea00fcea2efecfd3c29ecd3fa20d Mon Sep 17 00:00:00 2001 From: elicn Date: Thu, 6 Oct 2022 18:20:34 +0300 Subject: [PATCH 12/13] Add ARM Qx and Sx registers --- qiling/arch/arm.py | 4 ++- qiling/arch/arm_const.py | 54 ++++++++++++++++++++++++++++++++++ qiling/debugger/gdb/xmlregs.py | 4 ++- 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/qiling/arch/arm.py b/qiling/arch/arm.py index 394258f79..519a56932 100644 --- a/qiling/arch/arm.py +++ b/qiling/arch/arm.py @@ -43,7 +43,9 @@ def uc(self) -> Uc: def regs(self) -> QlRegisterManager: regs_map = dict( **arm_const.reg_map, - **arm_const.reg_vfp + **arm_const.reg_vfp, + **arm_const.reg_map_q, + **arm_const.reg_map_s ) pc_reg = 'pc' diff --git a/qiling/arch/arm_const.py b/qiling/arch/arm_const.py index 2a268cdfd..42dbf3c3b 100644 --- a/qiling/arch/arm_const.py +++ b/qiling/arch/arm_const.py @@ -64,3 +64,57 @@ "d31" : UC_ARM_REG_D31, "fpscr" : UC_ARM_REG_FPSCR } + +reg_map_q = { + "q0": UC_ARM_REG_Q0, + "q1": UC_ARM_REG_Q1, + "q2": UC_ARM_REG_Q2, + "q3": UC_ARM_REG_Q3, + "q4": UC_ARM_REG_Q4, + "q5": UC_ARM_REG_Q5, + "q6": UC_ARM_REG_Q6, + "q7": UC_ARM_REG_Q7, + "q8": UC_ARM_REG_Q8, + "q9": UC_ARM_REG_Q9, + "q10": UC_ARM_REG_Q10, + "q11": UC_ARM_REG_Q11, + "q12": UC_ARM_REG_Q12, + "q13": UC_ARM_REG_Q13, + "q14": UC_ARM_REG_Q14, + "q15": UC_ARM_REG_Q15 +} + +reg_map_s = { + "s0": UC_ARM_REG_S0, + "s1": UC_ARM_REG_S1, + "s2": UC_ARM_REG_S2, + "s3": UC_ARM_REG_S3, + "s4": UC_ARM_REG_S4, + "s5": UC_ARM_REG_S5, + "s6": UC_ARM_REG_S6, + "s7": UC_ARM_REG_S7, + "s8": UC_ARM_REG_S8, + "s9": UC_ARM_REG_S9, + "s10": UC_ARM_REG_S10, + "s11": UC_ARM_REG_S11, + "s12": UC_ARM_REG_S12, + "s13": UC_ARM_REG_S13, + "s14": UC_ARM_REG_S14, + "s15": UC_ARM_REG_S15, + "s16": UC_ARM_REG_S16, + "s17": UC_ARM_REG_S17, + "s18": UC_ARM_REG_S18, + "s19": UC_ARM_REG_S19, + "s20": UC_ARM_REG_S20, + "s21": UC_ARM_REG_S21, + "s22": UC_ARM_REG_S22, + "s23": UC_ARM_REG_S23, + "s24": UC_ARM_REG_S24, + "s25": UC_ARM_REG_S25, + "s26": UC_ARM_REG_S26, + "s27": UC_ARM_REG_S27, + "s28": UC_ARM_REG_S28, + "s29": UC_ARM_REG_S29, + "s30": UC_ARM_REG_S30, + "s31": UC_ARM_REG_S31 +} diff --git a/qiling/debugger/gdb/xmlregs.py b/qiling/debugger/gdb/xmlregs.py index 7385a303f..e475897e2 100644 --- a/qiling/debugger/gdb/xmlregs.py +++ b/qiling/debugger/gdb/xmlregs.py @@ -9,6 +9,8 @@ from qiling.arch.arm_const import reg_map as arm_regs from qiling.arch.arm_const import reg_vfp as arm_regs_vfp +from qiling.arch.arm_const import reg_map_q as arm_regs_q +from qiling.arch.arm_const import reg_map_s as arm_regs_s from qiling.arch.arm64_const import reg_map as arm64_regs from qiling.arch.arm64_const import reg_map_v as arm64_regs_v from qiling.arch.mips_const import reg_map as mips_regs_gpr @@ -121,7 +123,7 @@ def __load_regsmap(archtype: QL_ARCH, xmltree: ElementTree.ElementTree) -> Seque QL_ARCH.A8086 : dict(**x86_regs_32, **x86_regs_misc, **x86_regs_cr, **x86_regs_st), QL_ARCH.X86 : dict(**x86_regs_32, **x86_regs_misc, **x86_regs_cr, **x86_regs_st, **x86_regs_xmm), QL_ARCH.X8664 : dict(**x86_regs_64, **x86_regs_misc, **x86_regs_cr, **x86_regs_st, **x86_regs_xmm, **x86_regs_ymm), - QL_ARCH.ARM : dict(**arm_regs, **arm_regs_vfp), + QL_ARCH.ARM : dict(**arm_regs, **arm_regs_vfp, **arm_regs_q, **arm_regs_s), QL_ARCH.CORTEX_M : arm_regs, QL_ARCH.ARM64 : dict(**arm64_regs, **arm64_regs_v), QL_ARCH.MIPS : dict(**mips_regs_gpr, **mips_regs_fpu) From 0ea5fc435eefa9bf35d60996e9a8099492d73b5d Mon Sep 17 00:00:00 2001 From: elicn Date: Thu, 6 Oct 2022 19:13:50 +0300 Subject: [PATCH 13/13] Minor PEP8 and linter-friendly tweaks --- qiling/arch/arch.py | 12 +- qiling/arch/arm.py | 3 +- qiling/arch/arm64.py | 3 +- qiling/arch/arm64_const.py | 466 ++++++++++++++++----------------- qiling/arch/arm_const.py | 108 ++++---- qiling/arch/arm_utils.py | 6 +- qiling/arch/cortex_m.py | 17 +- qiling/arch/cortex_m_const.py | 58 ++-- qiling/arch/mips.py | 11 +- qiling/arch/mips_const.py | 180 ++++++------- qiling/arch/msr.py | 3 +- qiling/arch/ppc.py | 4 +- qiling/arch/ppc_const.py | 55 ++-- qiling/arch/register.py | 17 +- qiling/arch/riscv.py | 9 +- qiling/arch/riscv64.py | 3 +- qiling/arch/riscv_const.py | 326 +++++++++++------------ qiling/arch/utils.py | 22 +- qiling/arch/x86.py | 5 + qiling/arch/x86_const.py | 153 ++++++----- qiling/arch/x86_utils.py | 5 +- qiling/core.py | 12 +- qiling/debugger/gdb/xmlregs.py | 71 ++--- 23 files changed, 779 insertions(+), 770 deletions(-) diff --git a/qiling/arch/arch.py b/qiling/arch/arch.py index e1b84d186..0687d3dc2 100644 --- a/qiling/arch/arch.py +++ b/qiling/arch/arch.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# +# # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # @@ -15,6 +15,7 @@ from .register import QlRegisterManager from .utils import QlArchUtils + class QlArch: type: QL_ARCH bits: int @@ -57,7 +58,6 @@ def stack_push(self, value: int) -> int: return self.regs.arch_sp - def stack_pop(self) -> int: """Pop a value from the architectural stack. @@ -69,7 +69,6 @@ def stack_pop(self) -> int: return data - def stack_read(self, offset: int) -> int: """Peek the architectural stack at a specified offset from its top, without affecting the top of the stack. @@ -86,7 +85,6 @@ def stack_read(self, offset: int) -> int: return self.ql.mem.read_ptr(self.regs.arch_sp + offset) - def stack_write(self, offset: int, value: int) -> None: """Write a value to the architectural stack at a specified offset from its top, without affecting the top of the stack. @@ -101,17 +99,14 @@ def stack_write(self, offset: int, value: int) -> None: self.ql.mem.write_ptr(self.regs.arch_sp + offset, value) - # Unicorn's CPU state save def save(self) -> UcContext: return self.uc.context_save() - # Unicorn's CPU state restore method def restore(self, saved_context: UcContext): self.uc.context_restore(saved_context) - @property @abstractmethod def disassembler(self) -> Cs: @@ -120,7 +115,6 @@ def disassembler(self) -> Cs: pass - @property @abstractmethod def assembler(self) -> Ks: @@ -135,4 +129,4 @@ def endian(self) -> QL_ENDIAN: """Get processor endianess. """ - pass \ No newline at end of file + pass diff --git a/qiling/arch/arm.py b/qiling/arch/arm.py index 519a56932..9c6a0ce8b 100644 --- a/qiling/arch/arm.py +++ b/qiling/arch/arm.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# +# # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # @@ -15,6 +15,7 @@ from qiling.arch.register import QlRegisterManager from qiling.const import QL_ARCH, QL_ENDIAN + class QlArchARM(QlArch): type = QL_ARCH.ARM bits = 32 diff --git a/qiling/arch/arm64.py b/qiling/arch/arm64.py index 659496694..c7578fa62 100644 --- a/qiling/arch/arm64.py +++ b/qiling/arch/arm64.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# +# # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # @@ -14,6 +14,7 @@ from qiling.arch.register import QlRegisterManager from qiling.const import QL_ARCH, QL_ENDIAN + class QlArchARM64(QlArch): type = QL_ARCH.ARM64 bits = 64 diff --git a/qiling/arch/arm64_const.py b/qiling/arch/arm64_const.py index ee2b55167..50d6ec167 100644 --- a/qiling/arch/arm64_const.py +++ b/qiling/arch/arm64_const.py @@ -6,16 +6,16 @@ from unicorn.arm64_const import * reg_map = { - "x0": UC_ARM64_REG_X0, - "x1": UC_ARM64_REG_X1, - "x2": UC_ARM64_REG_X2, - "x3": UC_ARM64_REG_X3, - "x4": UC_ARM64_REG_X4, - "x5": UC_ARM64_REG_X5, - "x6": UC_ARM64_REG_X6, - "x7": UC_ARM64_REG_X7, - "x8": UC_ARM64_REG_X8, - "x9": UC_ARM64_REG_X9, + "x0": UC_ARM64_REG_X0, + "x1": UC_ARM64_REG_X1, + "x2": UC_ARM64_REG_X2, + "x3": UC_ARM64_REG_X3, + "x4": UC_ARM64_REG_X4, + "x5": UC_ARM64_REG_X5, + "x6": UC_ARM64_REG_X6, + "x7": UC_ARM64_REG_X7, + "x8": UC_ARM64_REG_X8, + "x9": UC_ARM64_REG_X9, "x10": UC_ARM64_REG_X10, "x11": UC_ARM64_REG_X11, "x12": UC_ARM64_REG_X12, @@ -45,245 +45,245 @@ } reg_map_b = { - "b0" : UC_ARM64_REG_B0, - "b1" : UC_ARM64_REG_B1, - "b2" : UC_ARM64_REG_B2, - "b3" : UC_ARM64_REG_B3, - "b4" : UC_ARM64_REG_B4, - "b5" : UC_ARM64_REG_B5, - "b6" : UC_ARM64_REG_B6, - "b7" : UC_ARM64_REG_B7, - "b8" : UC_ARM64_REG_B8, - "b9" : UC_ARM64_REG_B9, - "b10" : UC_ARM64_REG_B10, - "b11" : UC_ARM64_REG_B11, - "b12" : UC_ARM64_REG_B12, - "b13" : UC_ARM64_REG_B13, - "b14" : UC_ARM64_REG_B14, - "b15" : UC_ARM64_REG_B15, - "b16" : UC_ARM64_REG_B16, - "b17" : UC_ARM64_REG_B17, - "b18" : UC_ARM64_REG_B18, - "b19" : UC_ARM64_REG_B19, - "b20" : UC_ARM64_REG_B20, - "b21" : UC_ARM64_REG_B21, - "b22" : UC_ARM64_REG_B22, - "b23" : UC_ARM64_REG_B23, - "b24" : UC_ARM64_REG_B24, - "b25" : UC_ARM64_REG_B25, - "b26" : UC_ARM64_REG_B26, - "b27" : UC_ARM64_REG_B27, - "b28" : UC_ARM64_REG_B28, - "b29" : UC_ARM64_REG_B29, - "b30" : UC_ARM64_REG_B30, - "b31" : UC_ARM64_REG_B31 + "b0": UC_ARM64_REG_B0, + "b1": UC_ARM64_REG_B1, + "b2": UC_ARM64_REG_B2, + "b3": UC_ARM64_REG_B3, + "b4": UC_ARM64_REG_B4, + "b5": UC_ARM64_REG_B5, + "b6": UC_ARM64_REG_B6, + "b7": UC_ARM64_REG_B7, + "b8": UC_ARM64_REG_B8, + "b9": UC_ARM64_REG_B9, + "b10": UC_ARM64_REG_B10, + "b11": UC_ARM64_REG_B11, + "b12": UC_ARM64_REG_B12, + "b13": UC_ARM64_REG_B13, + "b14": UC_ARM64_REG_B14, + "b15": UC_ARM64_REG_B15, + "b16": UC_ARM64_REG_B16, + "b17": UC_ARM64_REG_B17, + "b18": UC_ARM64_REG_B18, + "b19": UC_ARM64_REG_B19, + "b20": UC_ARM64_REG_B20, + "b21": UC_ARM64_REG_B21, + "b22": UC_ARM64_REG_B22, + "b23": UC_ARM64_REG_B23, + "b24": UC_ARM64_REG_B24, + "b25": UC_ARM64_REG_B25, + "b26": UC_ARM64_REG_B26, + "b27": UC_ARM64_REG_B27, + "b28": UC_ARM64_REG_B28, + "b29": UC_ARM64_REG_B29, + "b30": UC_ARM64_REG_B30, + "b31": UC_ARM64_REG_B31 } reg_map_d = { - "d0" : UC_ARM64_REG_D0, - "d1" : UC_ARM64_REG_D1, - "d2" : UC_ARM64_REG_D2, - "d3" : UC_ARM64_REG_D3, - "d4" : UC_ARM64_REG_D4, - "d5" : UC_ARM64_REG_D5, - "d6" : UC_ARM64_REG_D6, - "d7" : UC_ARM64_REG_D7, - "d8" : UC_ARM64_REG_D8, - "d9" : UC_ARM64_REG_D9, - "d10" : UC_ARM64_REG_D10, - "d11" : UC_ARM64_REG_D11, - "d12" : UC_ARM64_REG_D12, - "d13" : UC_ARM64_REG_D13, - "d14" : UC_ARM64_REG_D14, - "d15" : UC_ARM64_REG_D15, - "d16" : UC_ARM64_REG_D16, - "d17" : UC_ARM64_REG_D17, - "d18" : UC_ARM64_REG_D18, - "d19" : UC_ARM64_REG_D19, - "d20" : UC_ARM64_REG_D20, - "d21" : UC_ARM64_REG_D21, - "d22" : UC_ARM64_REG_D22, - "d23" : UC_ARM64_REG_D23, - "d24" : UC_ARM64_REG_D24, - "d25" : UC_ARM64_REG_D25, - "d26" : UC_ARM64_REG_D26, - "d27" : UC_ARM64_REG_D27, - "d28" : UC_ARM64_REG_D28, - "d29" : UC_ARM64_REG_D29, - "d30" : UC_ARM64_REG_D30, - "d31" : UC_ARM64_REG_D31 + "d0": UC_ARM64_REG_D0, + "d1": UC_ARM64_REG_D1, + "d2": UC_ARM64_REG_D2, + "d3": UC_ARM64_REG_D3, + "d4": UC_ARM64_REG_D4, + "d5": UC_ARM64_REG_D5, + "d6": UC_ARM64_REG_D6, + "d7": UC_ARM64_REG_D7, + "d8": UC_ARM64_REG_D8, + "d9": UC_ARM64_REG_D9, + "d10": UC_ARM64_REG_D10, + "d11": UC_ARM64_REG_D11, + "d12": UC_ARM64_REG_D12, + "d13": UC_ARM64_REG_D13, + "d14": UC_ARM64_REG_D14, + "d15": UC_ARM64_REG_D15, + "d16": UC_ARM64_REG_D16, + "d17": UC_ARM64_REG_D17, + "d18": UC_ARM64_REG_D18, + "d19": UC_ARM64_REG_D19, + "d20": UC_ARM64_REG_D20, + "d21": UC_ARM64_REG_D21, + "d22": UC_ARM64_REG_D22, + "d23": UC_ARM64_REG_D23, + "d24": UC_ARM64_REG_D24, + "d25": UC_ARM64_REG_D25, + "d26": UC_ARM64_REG_D26, + "d27": UC_ARM64_REG_D27, + "d28": UC_ARM64_REG_D28, + "d29": UC_ARM64_REG_D29, + "d30": UC_ARM64_REG_D30, + "d31": UC_ARM64_REG_D31 } reg_map_h = { - "h0" : UC_ARM64_REG_H0, - "h1" : UC_ARM64_REG_H1, - "h2" : UC_ARM64_REG_H2, - "h3" : UC_ARM64_REG_H3, - "h4" : UC_ARM64_REG_H4, - "h5" : UC_ARM64_REG_H5, - "h6" : UC_ARM64_REG_H6, - "h7" : UC_ARM64_REG_H7, - "h8" : UC_ARM64_REG_H8, - "h9" : UC_ARM64_REG_H9, - "h10" : UC_ARM64_REG_H10, - "h11" : UC_ARM64_REG_H11, - "h12" : UC_ARM64_REG_H12, - "h13" : UC_ARM64_REG_H13, - "h14" : UC_ARM64_REG_H14, - "h15" : UC_ARM64_REG_H15, - "h16" : UC_ARM64_REG_H16, - "h17" : UC_ARM64_REG_H17, - "h18" : UC_ARM64_REG_H18, - "h19" : UC_ARM64_REG_H19, - "h20" : UC_ARM64_REG_H20, - "h21" : UC_ARM64_REG_H21, - "h22" : UC_ARM64_REG_H22, - "h23" : UC_ARM64_REG_H23, - "h24" : UC_ARM64_REG_H24, - "h25" : UC_ARM64_REG_H25, - "h26" : UC_ARM64_REG_H26, - "h27" : UC_ARM64_REG_H27, - "h28" : UC_ARM64_REG_H28, - "h29" : UC_ARM64_REG_H29, - "h30" : UC_ARM64_REG_H30, - "h31" : UC_ARM64_REG_H31 + "h0": UC_ARM64_REG_H0, + "h1": UC_ARM64_REG_H1, + "h2": UC_ARM64_REG_H2, + "h3": UC_ARM64_REG_H3, + "h4": UC_ARM64_REG_H4, + "h5": UC_ARM64_REG_H5, + "h6": UC_ARM64_REG_H6, + "h7": UC_ARM64_REG_H7, + "h8": UC_ARM64_REG_H8, + "h9": UC_ARM64_REG_H9, + "h10": UC_ARM64_REG_H10, + "h11": UC_ARM64_REG_H11, + "h12": UC_ARM64_REG_H12, + "h13": UC_ARM64_REG_H13, + "h14": UC_ARM64_REG_H14, + "h15": UC_ARM64_REG_H15, + "h16": UC_ARM64_REG_H16, + "h17": UC_ARM64_REG_H17, + "h18": UC_ARM64_REG_H18, + "h19": UC_ARM64_REG_H19, + "h20": UC_ARM64_REG_H20, + "h21": UC_ARM64_REG_H21, + "h22": UC_ARM64_REG_H22, + "h23": UC_ARM64_REG_H23, + "h24": UC_ARM64_REG_H24, + "h25": UC_ARM64_REG_H25, + "h26": UC_ARM64_REG_H26, + "h27": UC_ARM64_REG_H27, + "h28": UC_ARM64_REG_H28, + "h29": UC_ARM64_REG_H29, + "h30": UC_ARM64_REG_H30, + "h31": UC_ARM64_REG_H31 } reg_map_q = { - "q0" : UC_ARM64_REG_Q0, - "q1" : UC_ARM64_REG_Q1, - "q2" : UC_ARM64_REG_Q2, - "q3" : UC_ARM64_REG_Q3, - "q4" : UC_ARM64_REG_Q4, - "q5" : UC_ARM64_REG_Q5, - "q6" : UC_ARM64_REG_Q6, - "q7" : UC_ARM64_REG_Q7, - "q8" : UC_ARM64_REG_Q8, - "q9" : UC_ARM64_REG_Q9, - "q10" : UC_ARM64_REG_Q10, - "q11" : UC_ARM64_REG_Q11, - "q12" : UC_ARM64_REG_Q12, - "q13" : UC_ARM64_REG_Q13, - "q14" : UC_ARM64_REG_Q14, - "q15" : UC_ARM64_REG_Q15, - "q16" : UC_ARM64_REG_Q16, - "q17" : UC_ARM64_REG_Q17, - "q18" : UC_ARM64_REG_Q18, - "q19" : UC_ARM64_REG_Q19, - "q20" : UC_ARM64_REG_Q20, - "q21" : UC_ARM64_REG_Q21, - "q22" : UC_ARM64_REG_Q22, - "q23" : UC_ARM64_REG_Q23, - "q24" : UC_ARM64_REG_Q24, - "q25" : UC_ARM64_REG_Q25, - "q26" : UC_ARM64_REG_Q26, - "q27" : UC_ARM64_REG_Q27, - "q28" : UC_ARM64_REG_Q28, - "q29" : UC_ARM64_REG_Q29, - "q30" : UC_ARM64_REG_Q30, - "q31" : UC_ARM64_REG_Q31 + "q0": UC_ARM64_REG_Q0, + "q1": UC_ARM64_REG_Q1, + "q2": UC_ARM64_REG_Q2, + "q3": UC_ARM64_REG_Q3, + "q4": UC_ARM64_REG_Q4, + "q5": UC_ARM64_REG_Q5, + "q6": UC_ARM64_REG_Q6, + "q7": UC_ARM64_REG_Q7, + "q8": UC_ARM64_REG_Q8, + "q9": UC_ARM64_REG_Q9, + "q10": UC_ARM64_REG_Q10, + "q11": UC_ARM64_REG_Q11, + "q12": UC_ARM64_REG_Q12, + "q13": UC_ARM64_REG_Q13, + "q14": UC_ARM64_REG_Q14, + "q15": UC_ARM64_REG_Q15, + "q16": UC_ARM64_REG_Q16, + "q17": UC_ARM64_REG_Q17, + "q18": UC_ARM64_REG_Q18, + "q19": UC_ARM64_REG_Q19, + "q20": UC_ARM64_REG_Q20, + "q21": UC_ARM64_REG_Q21, + "q22": UC_ARM64_REG_Q22, + "q23": UC_ARM64_REG_Q23, + "q24": UC_ARM64_REG_Q24, + "q25": UC_ARM64_REG_Q25, + "q26": UC_ARM64_REG_Q26, + "q27": UC_ARM64_REG_Q27, + "q28": UC_ARM64_REG_Q28, + "q29": UC_ARM64_REG_Q29, + "q30": UC_ARM64_REG_Q30, + "q31": UC_ARM64_REG_Q31 } reg_map_s = { - "s0" : UC_ARM64_REG_S0, - "s1" : UC_ARM64_REG_S1, - "s2" : UC_ARM64_REG_S2, - "s3" : UC_ARM64_REG_S3, - "s4" : UC_ARM64_REG_S4, - "s5" : UC_ARM64_REG_S5, - "s6" : UC_ARM64_REG_S6, - "s7" : UC_ARM64_REG_S7, - "s8" : UC_ARM64_REG_S8, - "s9" : UC_ARM64_REG_S9, - "s10" : UC_ARM64_REG_S10, - "s11" : UC_ARM64_REG_S11, - "s12" : UC_ARM64_REG_S12, - "s13" : UC_ARM64_REG_S13, - "s14" : UC_ARM64_REG_S14, - "s15" : UC_ARM64_REG_S15, - "s16" : UC_ARM64_REG_S16, - "s17" : UC_ARM64_REG_S17, - "s18" : UC_ARM64_REG_S18, - "s19" : UC_ARM64_REG_S19, - "s20" : UC_ARM64_REG_S20, - "s21" : UC_ARM64_REG_S21, - "s22" : UC_ARM64_REG_S22, - "s23" : UC_ARM64_REG_S23, - "s24" : UC_ARM64_REG_S24, - "s25" : UC_ARM64_REG_S25, - "s26" : UC_ARM64_REG_S26, - "s27" : UC_ARM64_REG_S27, - "s28" : UC_ARM64_REG_S28, - "s29" : UC_ARM64_REG_S29, - "s30" : UC_ARM64_REG_S30, - "s31" : UC_ARM64_REG_S31 + "s0": UC_ARM64_REG_S0, + "s1": UC_ARM64_REG_S1, + "s2": UC_ARM64_REG_S2, + "s3": UC_ARM64_REG_S3, + "s4": UC_ARM64_REG_S4, + "s5": UC_ARM64_REG_S5, + "s6": UC_ARM64_REG_S6, + "s7": UC_ARM64_REG_S7, + "s8": UC_ARM64_REG_S8, + "s9": UC_ARM64_REG_S9, + "s10": UC_ARM64_REG_S10, + "s11": UC_ARM64_REG_S11, + "s12": UC_ARM64_REG_S12, + "s13": UC_ARM64_REG_S13, + "s14": UC_ARM64_REG_S14, + "s15": UC_ARM64_REG_S15, + "s16": UC_ARM64_REG_S16, + "s17": UC_ARM64_REG_S17, + "s18": UC_ARM64_REG_S18, + "s19": UC_ARM64_REG_S19, + "s20": UC_ARM64_REG_S20, + "s21": UC_ARM64_REG_S21, + "s22": UC_ARM64_REG_S22, + "s23": UC_ARM64_REG_S23, + "s24": UC_ARM64_REG_S24, + "s25": UC_ARM64_REG_S25, + "s26": UC_ARM64_REG_S26, + "s27": UC_ARM64_REG_S27, + "s28": UC_ARM64_REG_S28, + "s29": UC_ARM64_REG_S29, + "s30": UC_ARM64_REG_S30, + "s31": UC_ARM64_REG_S31 } reg_map_w = { - "w0" : UC_ARM64_REG_W0, - "w1" : UC_ARM64_REG_W1, - "w2" : UC_ARM64_REG_W2, - "w3" : UC_ARM64_REG_W3, - "w4" : UC_ARM64_REG_W4, - "w5" : UC_ARM64_REG_W5, - "w6" : UC_ARM64_REG_W6, - "w7" : UC_ARM64_REG_W7, - "w8" : UC_ARM64_REG_W8, - "w9" : UC_ARM64_REG_W9, - "w10" : UC_ARM64_REG_W10, - "w11" : UC_ARM64_REG_W11, - "w12" : UC_ARM64_REG_W12, - "w13" : UC_ARM64_REG_W13, - "w14" : UC_ARM64_REG_W14, - "w15" : UC_ARM64_REG_W15, - "w16" : UC_ARM64_REG_W16, - "w17" : UC_ARM64_REG_W17, - "w18" : UC_ARM64_REG_W18, - "w19" : UC_ARM64_REG_W19, - "w20" : UC_ARM64_REG_W20, - "w21" : UC_ARM64_REG_W21, - "w22" : UC_ARM64_REG_W22, - "w23" : UC_ARM64_REG_W23, - "w24" : UC_ARM64_REG_W24, - "w25" : UC_ARM64_REG_W25, - "w26" : UC_ARM64_REG_W26, - "w27" : UC_ARM64_REG_W27, - "w28" : UC_ARM64_REG_W28, - "w29" : UC_ARM64_REG_W29, - "w30" : UC_ARM64_REG_W30 + "w0": UC_ARM64_REG_W0, + "w1": UC_ARM64_REG_W1, + "w2": UC_ARM64_REG_W2, + "w3": UC_ARM64_REG_W3, + "w4": UC_ARM64_REG_W4, + "w5": UC_ARM64_REG_W5, + "w6": UC_ARM64_REG_W6, + "w7": UC_ARM64_REG_W7, + "w8": UC_ARM64_REG_W8, + "w9": UC_ARM64_REG_W9, + "w10": UC_ARM64_REG_W10, + "w11": UC_ARM64_REG_W11, + "w12": UC_ARM64_REG_W12, + "w13": UC_ARM64_REG_W13, + "w14": UC_ARM64_REG_W14, + "w15": UC_ARM64_REG_W15, + "w16": UC_ARM64_REG_W16, + "w17": UC_ARM64_REG_W17, + "w18": UC_ARM64_REG_W18, + "w19": UC_ARM64_REG_W19, + "w20": UC_ARM64_REG_W20, + "w21": UC_ARM64_REG_W21, + "w22": UC_ARM64_REG_W22, + "w23": UC_ARM64_REG_W23, + "w24": UC_ARM64_REG_W24, + "w25": UC_ARM64_REG_W25, + "w26": UC_ARM64_REG_W26, + "w27": UC_ARM64_REG_W27, + "w28": UC_ARM64_REG_W28, + "w29": UC_ARM64_REG_W29, + "w30": UC_ARM64_REG_W30 } reg_map_v = { - "v0" : UC_ARM64_REG_V0, - "v1" : UC_ARM64_REG_V1, - "v2" : UC_ARM64_REG_V2, - "v3" : UC_ARM64_REG_V3, - "v4" : UC_ARM64_REG_V4, - "v5" : UC_ARM64_REG_V5, - "v6" : UC_ARM64_REG_V6, - "v7" : UC_ARM64_REG_V7, - "v8" : UC_ARM64_REG_V8, - "v9" : UC_ARM64_REG_V9, - "v10" : UC_ARM64_REG_V10, - "v11" : UC_ARM64_REG_V11, - "v12" : UC_ARM64_REG_V12, - "v13" : UC_ARM64_REG_V13, - "v14" : UC_ARM64_REG_V14, - "v15" : UC_ARM64_REG_V15, - "v16" : UC_ARM64_REG_V16, - "v17" : UC_ARM64_REG_V17, - "v18" : UC_ARM64_REG_V18, - "v19" : UC_ARM64_REG_V19, - "v20" : UC_ARM64_REG_V20, - "v21" : UC_ARM64_REG_V21, - "v22" : UC_ARM64_REG_V22, - "v23" : UC_ARM64_REG_V23, - "v24" : UC_ARM64_REG_V24, - "v25" : UC_ARM64_REG_V25, - "v26" : UC_ARM64_REG_V26, - "v27" : UC_ARM64_REG_V27, - "v28" : UC_ARM64_REG_V28, - "v29" : UC_ARM64_REG_V29, - "v30" : UC_ARM64_REG_V30, - "v31" : UC_ARM64_REG_V31 + "v0": UC_ARM64_REG_V0, + "v1": UC_ARM64_REG_V1, + "v2": UC_ARM64_REG_V2, + "v3": UC_ARM64_REG_V3, + "v4": UC_ARM64_REG_V4, + "v5": UC_ARM64_REG_V5, + "v6": UC_ARM64_REG_V6, + "v7": UC_ARM64_REG_V7, + "v8": UC_ARM64_REG_V8, + "v9": UC_ARM64_REG_V9, + "v10": UC_ARM64_REG_V10, + "v11": UC_ARM64_REG_V11, + "v12": UC_ARM64_REG_V12, + "v13": UC_ARM64_REG_V13, + "v14": UC_ARM64_REG_V14, + "v15": UC_ARM64_REG_V15, + "v16": UC_ARM64_REG_V16, + "v17": UC_ARM64_REG_V17, + "v18": UC_ARM64_REG_V18, + "v19": UC_ARM64_REG_V19, + "v20": UC_ARM64_REG_V20, + "v21": UC_ARM64_REG_V21, + "v22": UC_ARM64_REG_V22, + "v23": UC_ARM64_REG_V23, + "v24": UC_ARM64_REG_V24, + "v25": UC_ARM64_REG_V25, + "v26": UC_ARM64_REG_V26, + "v27": UC_ARM64_REG_V27, + "v28": UC_ARM64_REG_V28, + "v29": UC_ARM64_REG_V29, + "v30": UC_ARM64_REG_V30, + "v31": UC_ARM64_REG_V31 } diff --git a/qiling/arch/arm_const.py b/qiling/arch/arm_const.py index 42dbf3c3b..1726a8071 100644 --- a/qiling/arch/arm_const.py +++ b/qiling/arch/arm_const.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# +# # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # @@ -30,52 +30,52 @@ } reg_vfp = { - "d0" : UC_ARM_REG_D0, - "d1" : UC_ARM_REG_D1, - "d2" : UC_ARM_REG_D2, - "d3" : UC_ARM_REG_D3, - "d4" : UC_ARM_REG_D4, - "d5" : UC_ARM_REG_D5, - "d6" : UC_ARM_REG_D6, - "d7" : UC_ARM_REG_D7, - "d8" : UC_ARM_REG_D8, - "d9" : UC_ARM_REG_D9, - "d10" : UC_ARM_REG_D10, - "d11" : UC_ARM_REG_D11, - "d12" : UC_ARM_REG_D12, - "d13" : UC_ARM_REG_D13, - "d14" : UC_ARM_REG_D14, - "d15" : UC_ARM_REG_D15, - "d16" : UC_ARM_REG_D16, - "d17" : UC_ARM_REG_D17, - "d18" : UC_ARM_REG_D18, - "d19" : UC_ARM_REG_D19, - "d20" : UC_ARM_REG_D20, - "d21" : UC_ARM_REG_D21, - "d22" : UC_ARM_REG_D22, - "d23" : UC_ARM_REG_D23, - "d24" : UC_ARM_REG_D24, - "d25" : UC_ARM_REG_D25, - "d26" : UC_ARM_REG_D26, - "d27" : UC_ARM_REG_D27, - "d28" : UC_ARM_REG_D28, - "d29" : UC_ARM_REG_D29, - "d30" : UC_ARM_REG_D30, - "d31" : UC_ARM_REG_D31, - "fpscr" : UC_ARM_REG_FPSCR + "d0": UC_ARM_REG_D0, + "d1": UC_ARM_REG_D1, + "d2": UC_ARM_REG_D2, + "d3": UC_ARM_REG_D3, + "d4": UC_ARM_REG_D4, + "d5": UC_ARM_REG_D5, + "d6": UC_ARM_REG_D6, + "d7": UC_ARM_REG_D7, + "d8": UC_ARM_REG_D8, + "d9": UC_ARM_REG_D9, + "d10": UC_ARM_REG_D10, + "d11": UC_ARM_REG_D11, + "d12": UC_ARM_REG_D12, + "d13": UC_ARM_REG_D13, + "d14": UC_ARM_REG_D14, + "d15": UC_ARM_REG_D15, + "d16": UC_ARM_REG_D16, + "d17": UC_ARM_REG_D17, + "d18": UC_ARM_REG_D18, + "d19": UC_ARM_REG_D19, + "d20": UC_ARM_REG_D20, + "d21": UC_ARM_REG_D21, + "d22": UC_ARM_REG_D22, + "d23": UC_ARM_REG_D23, + "d24": UC_ARM_REG_D24, + "d25": UC_ARM_REG_D25, + "d26": UC_ARM_REG_D26, + "d27": UC_ARM_REG_D27, + "d28": UC_ARM_REG_D28, + "d29": UC_ARM_REG_D29, + "d30": UC_ARM_REG_D30, + "d31": UC_ARM_REG_D31, + "fpscr": UC_ARM_REG_FPSCR } reg_map_q = { - "q0": UC_ARM_REG_Q0, - "q1": UC_ARM_REG_Q1, - "q2": UC_ARM_REG_Q2, - "q3": UC_ARM_REG_Q3, - "q4": UC_ARM_REG_Q4, - "q5": UC_ARM_REG_Q5, - "q6": UC_ARM_REG_Q6, - "q7": UC_ARM_REG_Q7, - "q8": UC_ARM_REG_Q8, - "q9": UC_ARM_REG_Q9, + "q0": UC_ARM_REG_Q0, + "q1": UC_ARM_REG_Q1, + "q2": UC_ARM_REG_Q2, + "q3": UC_ARM_REG_Q3, + "q4": UC_ARM_REG_Q4, + "q5": UC_ARM_REG_Q5, + "q6": UC_ARM_REG_Q6, + "q7": UC_ARM_REG_Q7, + "q8": UC_ARM_REG_Q8, + "q9": UC_ARM_REG_Q9, "q10": UC_ARM_REG_Q10, "q11": UC_ARM_REG_Q11, "q12": UC_ARM_REG_Q12, @@ -85,16 +85,16 @@ } reg_map_s = { - "s0": UC_ARM_REG_S0, - "s1": UC_ARM_REG_S1, - "s2": UC_ARM_REG_S2, - "s3": UC_ARM_REG_S3, - "s4": UC_ARM_REG_S4, - "s5": UC_ARM_REG_S5, - "s6": UC_ARM_REG_S6, - "s7": UC_ARM_REG_S7, - "s8": UC_ARM_REG_S8, - "s9": UC_ARM_REG_S9, + "s0": UC_ARM_REG_S0, + "s1": UC_ARM_REG_S1, + "s2": UC_ARM_REG_S2, + "s3": UC_ARM_REG_S3, + "s4": UC_ARM_REG_S4, + "s5": UC_ARM_REG_S5, + "s6": UC_ARM_REG_S6, + "s7": UC_ARM_REG_S7, + "s8": UC_ARM_REG_S8, + "s9": UC_ARM_REG_S9, "s10": UC_ARM_REG_S10, "s11": UC_ARM_REG_S11, "s12": UC_ARM_REG_S12, diff --git a/qiling/arch/arm_utils.py b/qiling/arch/arm_utils.py index 3f7ff87f5..14181a699 100644 --- a/qiling/arch/arm_utils.py +++ b/qiling/arch/arm_utils.py @@ -1,11 +1,12 @@ #!/usr/bin/env python3 -# +# # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # from qiling import Qiling from qiling.const import QL_ENDIAN + def init_linux_traps(ql: Qiling, address_map) -> None: # If the compiler for the target does not provides some primitives for some # reasons (e.g. target limitations), the kernel is responsible to assist @@ -84,7 +85,8 @@ def init_linux_traps(ql: Qiling, address_map) -> None: ql.log.debug(f'Set kernel trap: {trap_name} at {address_map[trap_name]:#x}') + def swap_endianness(s: bytes, blksize: int = 4) -> bytes: blocks = (s[i:i + blksize] for i in range(0, len(s), blksize)) - return b''.join(bytes(reversed(b)) for b in blocks) \ No newline at end of file + return b''.join(bytes(reversed(b)) for b in blocks) diff --git a/qiling/arch/cortex_m.py b/qiling/arch/cortex_m.py index 72c7e59be..d1ce5a883 100644 --- a/qiling/arch/cortex_m.py +++ b/qiling/arch/cortex_m.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# +# # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # @@ -29,7 +29,7 @@ def __enter__(self): for reg in self.reg_context: val = self.ql.arch.regs.read(reg) self.ql.arch.stack_push(val) - + if self.ql.verbose >= QL_VERBOSE.DISASM: self.ql.log.info(f'Enter into interrupt') @@ -46,21 +46,22 @@ def __exit__(self, *exc): # switch the stack accroding exc_return old_ctrl = self.ql.arch.regs.read('control') if retval & EXC_RETURN.RETURN_SP: - self.ql.arch.regs.write('control', old_ctrl | CONTROL.SPSEL) + self.ql.arch.regs.write('control', old_ctrl | CONTROL.SPSEL) else: self.ql.arch.regs.write('control', old_ctrl & ~CONTROL.SPSEL) # Restore stack for reg in reversed(self.reg_context): val = self.ql.arch.stack_pop() - if reg == 'xpsr': + if reg == 'xpsr': self.ql.arch.regs.write('XPSR_NZCVQG', val) else: - self.ql.arch.regs.write(reg, val) + self.ql.arch.regs.write(reg, val) if self.ql.verbose >= QL_VERBOSE.DISASM: self.ql.log.info('Exit from interrupt') + class QlArchCORTEX_M(QlArchARM): type = QL_ARCH.ARM bits = 32 @@ -87,7 +88,7 @@ def disassembler(self) -> Cs: @cached_property def assembler(self) -> Ks: return Ks(KS_ARCH_ARM, KS_MODE_ARM + KS_MODE_THUMB) - + @property def is_thumb(self) -> bool: return True @@ -157,10 +158,10 @@ def interrupt_handler(self, ql, intno): offset = isr * 4 entry = ql.mem.read_ptr(offset) - exc_return = 0xFFFFFFFD if self.using_psp() else 0xFFFFFFF9 + exc_return = 0xFFFFFFFD if self.using_psp() else 0xFFFFFFF9 self.regs.write('ipsr', isr) self.regs.write('pc', entry) - self.regs.write('lr', exc_return) + self.regs.write('lr', exc_return) self.uc.emu_start(self.effective_pc, 0, 0, 0) diff --git a/qiling/arch/cortex_m_const.py b/qiling/arch/cortex_m_const.py index cae4f4393..8f915163d 100644 --- a/qiling/arch/cortex_m_const.py +++ b/qiling/arch/cortex_m_const.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# +# # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # @@ -7,38 +7,39 @@ from enum import IntEnum reg_map = { - "r0": UC_ARM_REG_R0, - "r1": UC_ARM_REG_R1, - "r2": UC_ARM_REG_R2, - "r3": UC_ARM_REG_R3, - "r4": UC_ARM_REG_R4, - "r5": UC_ARM_REG_R5, - "r6": UC_ARM_REG_R6, - "r7": UC_ARM_REG_R7, - "r8": UC_ARM_REG_R8, - "r9": UC_ARM_REG_R9, - "r10": UC_ARM_REG_R10, + "r0": UC_ARM_REG_R0, + "r1": UC_ARM_REG_R1, + "r2": UC_ARM_REG_R2, + "r3": UC_ARM_REG_R3, + "r4": UC_ARM_REG_R4, + "r5": UC_ARM_REG_R5, + "r6": UC_ARM_REG_R6, + "r7": UC_ARM_REG_R7, + "r8": UC_ARM_REG_R8, + "r9": UC_ARM_REG_R9, + "r10": UC_ARM_REG_R10, "r11": UC_ARM_REG_R11, - "r12": UC_ARM_REG_R12, - "sp": UC_ARM_REG_SP, - "lr": UC_ARM_REG_LR, - "pc": UC_ARM_REG_PC, + "r12": UC_ARM_REG_R12, + "sp": UC_ARM_REG_SP, + "lr": UC_ARM_REG_LR, + "pc": UC_ARM_REG_PC, # cortex-M Special Register - "msp": UC_ARM_REG_MSP, - "psp": UC_ARM_REG_PSP, - "xpsr": UC_ARM_REG_XPSR, - "apsr": UC_ARM_REG_APSR, - "ipsr": UC_ARM_REG_IPSR, - "epsr": UC_ARM_REG_EPSR, - "primask": UC_ARM_REG_PRIMASK, + "msp": UC_ARM_REG_MSP, + "psp": UC_ARM_REG_PSP, + "xpsr": UC_ARM_REG_XPSR, + "apsr": UC_ARM_REG_APSR, + "ipsr": UC_ARM_REG_IPSR, + "epsr": UC_ARM_REG_EPSR, + "primask": UC_ARM_REG_PRIMASK, "faultmask": UC_ARM_REG_FAULTMASK, - "basepri": UC_ARM_REG_BASEPRI, - "control": UC_ARM_REG_CONTROL, + "basepri": UC_ARM_REG_BASEPRI, + "control": UC_ARM_REG_CONTROL, "xpsr_nzcvqg": UC_ARM_REG_XPSR_NZCVQG, } + class IRQ(IntEnum): NMI = -14 HARD_FAULT = -13 @@ -50,16 +51,19 @@ class IRQ(IntEnum): SYSTICK = -1 NOTHING = 0 + class CONTROL(IntEnum): FPCA = 0b100 SPSEL = 0b010 PRIV = 0b001 + class EXC_RETURN(IntEnum): MASK = 0xfffffff0 RETURN_SP = 0b0100 RETURN_MODE = 0b1000 + class EXCP(IntEnum): UDEF = 1 # undefined instruction SWI = 2 # software interrupt @@ -68,8 +72,8 @@ class EXCP(IntEnum): IRQ = 5 FIQ = 6 BKPT = 7 - EXCEPTION_EXIT = 8 # Return from v7M exception. - KERNEL_TRAP = 9 # Jumped to kernel code page. + EXCEPTION_EXIT = 8 # Return from v7M exception. + KERNEL_TRAP = 9 # Jumped to kernel code page. HVC = 11 # HyperVisor Call HYP_TRAP = 12 SMC = 13 # Secure Monitor Call diff --git a/qiling/arch/mips.py b/qiling/arch/mips.py index 9368634f2..5a32481dc 100644 --- a/qiling/arch/mips.py +++ b/qiling/arch/mips.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# +# # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # @@ -15,6 +15,7 @@ from qiling.arch.register import QlRegisterManager from qiling.const import QL_ARCH, QL_ENDIAN + class QlArchMIPS(QlArch): type = QL_ARCH.MIPS bits = 32 @@ -49,8 +50,8 @@ def regs(self) -> QlRegisterManager: @cached_property def disassembler(self) -> Cs: endian = { - QL_ENDIAN.EL : CS_MODE_LITTLE_ENDIAN, - QL_ENDIAN.EB : CS_MODE_BIG_ENDIAN + QL_ENDIAN.EL: CS_MODE_LITTLE_ENDIAN, + QL_ENDIAN.EB: CS_MODE_BIG_ENDIAN }[self.endian] return Cs(CS_ARCH_MIPS, CS_MODE_MIPS32 + endian) @@ -58,8 +59,8 @@ def disassembler(self) -> Cs: @cached_property def assembler(self) -> Ks: endian = { - QL_ENDIAN.EL : KS_MODE_LITTLE_ENDIAN, - QL_ENDIAN.EB : KS_MODE_BIG_ENDIAN + QL_ENDIAN.EL: KS_MODE_LITTLE_ENDIAN, + QL_ENDIAN.EB: KS_MODE_BIG_ENDIAN }[self.endian] return Ks(KS_ARCH_MIPS, KS_MODE_MIPS32 + endian) diff --git a/qiling/arch/mips_const.py b/qiling/arch/mips_const.py index 8e3141f4f..1c4467ebb 100644 --- a/qiling/arch/mips_const.py +++ b/qiling/arch/mips_const.py @@ -1,120 +1,120 @@ #!/usr/bin/env python3 -# +# # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # from unicorn.mips_const import * reg_map = { - "r0" : UC_MIPS_REG_0, - "r1" : UC_MIPS_REG_1, - "r2" : UC_MIPS_REG_2, - "r3" : UC_MIPS_REG_3, - "r4" : UC_MIPS_REG_4, - "r5" : UC_MIPS_REG_5, - "r6" : UC_MIPS_REG_6, - "r7" : UC_MIPS_REG_7, - "r8" : UC_MIPS_REG_8, - "r9" : UC_MIPS_REG_9, - "r10" : UC_MIPS_REG_10, - "r11" : UC_MIPS_REG_11, - "r12" : UC_MIPS_REG_12, - "r13" : UC_MIPS_REG_13, - "r14" : UC_MIPS_REG_14, - "r15" : UC_MIPS_REG_15, - "r16" : UC_MIPS_REG_16, - "r17" : UC_MIPS_REG_17, - "r18" : UC_MIPS_REG_18, - "r19" : UC_MIPS_REG_19, - "r20" : UC_MIPS_REG_20, - "r21" : UC_MIPS_REG_21, - "r22" : UC_MIPS_REG_22, - "r23" : UC_MIPS_REG_23, - "r24" : UC_MIPS_REG_24, - "r25" : UC_MIPS_REG_25, - "r26" : UC_MIPS_REG_26, - "r27" : UC_MIPS_REG_27, - "r28" : UC_MIPS_REG_28, - "r29" : UC_MIPS_REG_29, - "r30" : UC_MIPS_REG_30, - "r31" : UC_MIPS_REG_31, + "r0": UC_MIPS_REG_0, + "r1": UC_MIPS_REG_1, + "r2": UC_MIPS_REG_2, + "r3": UC_MIPS_REG_3, + "r4": UC_MIPS_REG_4, + "r5": UC_MIPS_REG_5, + "r6": UC_MIPS_REG_6, + "r7": UC_MIPS_REG_7, + "r8": UC_MIPS_REG_8, + "r9": UC_MIPS_REG_9, + "r10": UC_MIPS_REG_10, + "r11": UC_MIPS_REG_11, + "r12": UC_MIPS_REG_12, + "r13": UC_MIPS_REG_13, + "r14": UC_MIPS_REG_14, + "r15": UC_MIPS_REG_15, + "r16": UC_MIPS_REG_16, + "r17": UC_MIPS_REG_17, + "r18": UC_MIPS_REG_18, + "r19": UC_MIPS_REG_19, + "r20": UC_MIPS_REG_20, + "r21": UC_MIPS_REG_21, + "r22": UC_MIPS_REG_22, + "r23": UC_MIPS_REG_23, + "r24": UC_MIPS_REG_24, + "r25": UC_MIPS_REG_25, + "r26": UC_MIPS_REG_26, + "r27": UC_MIPS_REG_27, + "r28": UC_MIPS_REG_28, + "r29": UC_MIPS_REG_29, + "r30": UC_MIPS_REG_30, + "r31": UC_MIPS_REG_31, - "zero": UC_MIPS_REG_ZERO, - "at": UC_MIPS_REG_AT, + "zero": UC_MIPS_REG_ZERO, + "at": UC_MIPS_REG_AT, "v0": UC_MIPS_REG_V0, - "v1": UC_MIPS_REG_V1, - "a0": UC_MIPS_REG_A0, + "v1": UC_MIPS_REG_V1, + "a0": UC_MIPS_REG_A0, "a1": UC_MIPS_REG_A1, - "a2": UC_MIPS_REG_A2, - "a3": UC_MIPS_REG_A3, + "a2": UC_MIPS_REG_A2, + "a3": UC_MIPS_REG_A3, "t0": UC_MIPS_REG_T0, - "t1": UC_MIPS_REG_T1, - "t2": UC_MIPS_REG_T2, + "t1": UC_MIPS_REG_T1, + "t2": UC_MIPS_REG_T2, "t3": UC_MIPS_REG_T3, - "t4": UC_MIPS_REG_T4, - "t5": UC_MIPS_REG_T5, + "t4": UC_MIPS_REG_T4, + "t5": UC_MIPS_REG_T5, "t6": UC_MIPS_REG_T6, - "t7": UC_MIPS_REG_T7, + "t7": UC_MIPS_REG_T7, "s0": UC_MIPS_REG_S0, "s1": UC_MIPS_REG_S1, - "s2": UC_MIPS_REG_S2, - "s3": UC_MIPS_REG_S3, + "s2": UC_MIPS_REG_S2, + "s3": UC_MIPS_REG_S3, "s4": UC_MIPS_REG_S4, - "s5": UC_MIPS_REG_S5, - "s6": UC_MIPS_REG_S6, + "s5": UC_MIPS_REG_S5, + "s6": UC_MIPS_REG_S6, "s7": UC_MIPS_REG_S7, - "t8": UC_MIPS_REG_T8, - "t9": UC_MIPS_REG_T9, + "t8": UC_MIPS_REG_T8, + "t9": UC_MIPS_REG_T9, "k0": UC_MIPS_REG_K0, "k1": UC_MIPS_REG_K1, - "gp": UC_MIPS_REG_GP, + "gp": UC_MIPS_REG_GP, "sp": UC_MIPS_REG_SP, "s8": UC_MIPS_REG_S8, "ra": UC_MIPS_REG_RA, - "status": UC_MIPS_REG_INVALID, - "lo": UC_MIPS_REG_LO, - "hi": UC_MIPS_REG_HI, + "status": UC_MIPS_REG_INVALID, + "lo": UC_MIPS_REG_LO, + "hi": UC_MIPS_REG_HI, "badvaddr": UC_MIPS_REG_INVALID, - "cause":UC_MIPS_REG_INVALID, - "pc": UC_MIPS_REG_PC, + "cause": UC_MIPS_REG_INVALID, + "pc": UC_MIPS_REG_PC } reg_map_afpr128 = { - "cp0_config3" : UC_MIPS_REG_CP0_CONFIG3, - "cp0_userlocal": UC_MIPS_REG_CP0_USERLOCAL, + "cp0_config3": UC_MIPS_REG_CP0_CONFIG3, + "cp0_userlocal": UC_MIPS_REG_CP0_USERLOCAL } reg_map_fpu = { - "f0" : UC_MIPS_REG_F0, - "f1" : UC_MIPS_REG_F1, - "f2" : UC_MIPS_REG_F2, - "f3" : UC_MIPS_REG_F3, - "f4" : UC_MIPS_REG_F4, - "f5" : UC_MIPS_REG_F5, - "f6" : UC_MIPS_REG_F6, - "f7" : UC_MIPS_REG_F7, - "f8" : UC_MIPS_REG_F8, - "f9" : UC_MIPS_REG_F9, - "f10" : UC_MIPS_REG_F10, - "f11" : UC_MIPS_REG_F11, - "f12" : UC_MIPS_REG_F12, - "f13" : UC_MIPS_REG_F13, - "f14" : UC_MIPS_REG_F14, - "f15" : UC_MIPS_REG_F15, - "f16" : UC_MIPS_REG_F16, - "f17" : UC_MIPS_REG_F17, - "f18" : UC_MIPS_REG_F18, - "f19" : UC_MIPS_REG_F19, - "f20" : UC_MIPS_REG_F20, - "f21" : UC_MIPS_REG_F21, - "f22" : UC_MIPS_REG_F22, - "f23" : UC_MIPS_REG_F23, - "f24" : UC_MIPS_REG_F24, - "f25" : UC_MIPS_REG_F25, - "f26" : UC_MIPS_REG_F26, - "f27" : UC_MIPS_REG_F27, - "f28" : UC_MIPS_REG_F28, - "f29" : UC_MIPS_REG_F29, - "f30" : UC_MIPS_REG_F30, - "f31" : UC_MIPS_REG_F31 + "f0": UC_MIPS_REG_F0, + "f1": UC_MIPS_REG_F1, + "f2": UC_MIPS_REG_F2, + "f3": UC_MIPS_REG_F3, + "f4": UC_MIPS_REG_F4, + "f5": UC_MIPS_REG_F5, + "f6": UC_MIPS_REG_F6, + "f7": UC_MIPS_REG_F7, + "f8": UC_MIPS_REG_F8, + "f9": UC_MIPS_REG_F9, + "f10": UC_MIPS_REG_F10, + "f11": UC_MIPS_REG_F11, + "f12": UC_MIPS_REG_F12, + "f13": UC_MIPS_REG_F13, + "f14": UC_MIPS_REG_F14, + "f15": UC_MIPS_REG_F15, + "f16": UC_MIPS_REG_F16, + "f17": UC_MIPS_REG_F17, + "f18": UC_MIPS_REG_F18, + "f19": UC_MIPS_REG_F19, + "f20": UC_MIPS_REG_F20, + "f21": UC_MIPS_REG_F21, + "f22": UC_MIPS_REG_F22, + "f23": UC_MIPS_REG_F23, + "f24": UC_MIPS_REG_F24, + "f25": UC_MIPS_REG_F25, + "f26": UC_MIPS_REG_F26, + "f27": UC_MIPS_REG_F27, + "f28": UC_MIPS_REG_F28, + "f29": UC_MIPS_REG_F29, + "f30": UC_MIPS_REG_F30, + "f31": UC_MIPS_REG_F31 } diff --git a/qiling/arch/msr.py b/qiling/arch/msr.py index 08409cffe..8ea13cafc 100644 --- a/qiling/arch/msr.py +++ b/qiling/arch/msr.py @@ -1,10 +1,11 @@ #!/usr/bin/env python3 -# +# # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # from unicorn import Uc + class QlMsrManager: """Enables access to Intel MSR. """ diff --git a/qiling/arch/ppc.py b/qiling/arch/ppc.py index 4e6d099db..9863648a9 100644 --- a/qiling/arch/ppc.py +++ b/qiling/arch/ppc.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# +# # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # @@ -9,12 +9,12 @@ from capstone import Cs, CS_ARCH_PPC, CS_MODE_32, CS_MODE_BIG_ENDIAN from keystone import Ks, KS_ARCH_PPC, KS_MODE_PPC32, KS_MODE_BIG_ENDIAN -from qiling import Qiling from qiling.arch.arch import QlArch from qiling.arch import ppc_const from qiling.arch.register import QlRegisterManager from qiling.const import QL_ARCH, QL_ENDIAN + class QlArchPPC(QlArch): type = QL_ARCH.PPC bits = 32 diff --git a/qiling/arch/ppc_const.py b/qiling/arch/ppc_const.py index 732cba1c9..c2fa86d42 100644 --- a/qiling/arch/ppc_const.py +++ b/qiling/arch/ppc_const.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# +# # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # @@ -7,16 +7,17 @@ from enum import IntEnum reg_map = { - "r0": UC_PPC_REG_0, - "r1": UC_PPC_REG_1, - "r2": UC_PPC_REG_2, - "r3": UC_PPC_REG_3, - "r4": UC_PPC_REG_4, - "r5": UC_PPC_REG_5, - "r6": UC_PPC_REG_6, - "r7": UC_PPC_REG_7, - "r8": UC_PPC_REG_8, - "r9": UC_PPC_REG_9, + "pc": UC_PPC_REG_PC, + "r0": UC_PPC_REG_0, + "r1": UC_PPC_REG_1, + "r2": UC_PPC_REG_2, + "r3": UC_PPC_REG_3, + "r4": UC_PPC_REG_4, + "r5": UC_PPC_REG_5, + "r6": UC_PPC_REG_6, + "r7": UC_PPC_REG_7, + "r8": UC_PPC_REG_8, + "r9": UC_PPC_REG_9, "r10": UC_PPC_REG_10, "r11": UC_PPC_REG_11, "r12": UC_PPC_REG_12, @@ -39,25 +40,24 @@ "r29": UC_PPC_REG_29, "r30": UC_PPC_REG_30, "r31": UC_PPC_REG_31, - "pc": UC_PPC_REG_PC, - "msr": UC_PPC_REG_MSR, - "cr": UC_PPC_REG_CR0, - "lr": UC_PPC_REG_LR, - "ctr": UC_PPC_REG_CTR, + "cr": UC_PPC_REG_CR0, + "lr": UC_PPC_REG_LR, "xer": UC_PPC_REG_XER, + "ctr": UC_PPC_REG_CTR, + "msr": UC_PPC_REG_MSR } reg_float_map = { - "f0": UC_PPC_REG_FPR0, - "f1": UC_PPC_REG_FPR1, - "f2": UC_PPC_REG_FPR2, - "f3": UC_PPC_REG_FPR3, - "f4": UC_PPC_REG_FPR4, - "f5": UC_PPC_REG_FPR5, - "f6": UC_PPC_REG_FPR6, - "f7": UC_PPC_REG_FPR7, - "f8": UC_PPC_REG_FPR8, - "f9": UC_PPC_REG_FPR9, + "f0": UC_PPC_REG_FPR0, + "f1": UC_PPC_REG_FPR1, + "f2": UC_PPC_REG_FPR2, + "f3": UC_PPC_REG_FPR3, + "f4": UC_PPC_REG_FPR4, + "f5": UC_PPC_REG_FPR5, + "f6": UC_PPC_REG_FPR6, + "f7": UC_PPC_REG_FPR7, + "f8": UC_PPC_REG_FPR8, + "f9": UC_PPC_REG_FPR9, "f10": UC_PPC_REG_FPR10, "f11": UC_PPC_REG_FPR11, "f12": UC_PPC_REG_FPR12, @@ -79,9 +79,10 @@ "f28": UC_PPC_REG_FPR28, "f29": UC_PPC_REG_FPR29, "f30": UC_PPC_REG_FPR30, - "f31": UC_PPC_REG_FPR31, + "f31": UC_PPC_REG_FPR31 } + class MSR(IntEnum): SF = 1 << 63 TAG = 1 << 62 diff --git a/qiling/arch/register.py b/qiling/arch/register.py index 368864f6f..15b426765 100644 --- a/qiling/arch/register.py +++ b/qiling/arch/register.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# +# # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # @@ -7,6 +7,7 @@ from unicorn import Uc + class QlRegisterManager: """This class exposes the ql.arch.regs features that allows you to directly access or assign values to CPU registers of a particular architecture. @@ -40,7 +41,6 @@ def __getattr__(self, name: str) -> Any: else: return super().__getattribute__(name) - def __setattr__(self, name: str, value: Any): name = name.lower() @@ -50,35 +50,30 @@ def __setattr__(self, name: str, value: Any): else: super().__setattr__(name, value) - - # read register def read(self, register: Union[str, int]): """Read a register value. """ - if type(register) is str: + if isinstance(register, str): register = self.register_mapping[register.lower()] return self.uc.reg_read(register) - def write(self, register: Union[str, int], value: int) -> None: """Write a register value. """ - if type(register) is str: + if isinstance(register, str): register = self.register_mapping[register.lower()] return self.uc.reg_write(register, value) - def save(self) -> MutableMapping[str, Any]: """Save CPU context. """ return dict((reg, self.read(reg)) for reg in self.register_mapping) - def restore(self, context: MutableMapping[str, Any] = {}) -> None: """Restore CPU context. """ @@ -86,7 +81,6 @@ def restore(self, context: MutableMapping[str, Any] = {}) -> None: for reg, val in context.items(): self.write(reg, val) - @property def arch_pc(self) -> int: """Get the value of the architectural program counter register. @@ -94,7 +88,6 @@ def arch_pc(self) -> int: return self.uc.reg_read(self.uc_pc) - @arch_pc.setter def arch_pc(self, value: int) -> None: """Set the value of the architectural program counter register. @@ -102,7 +95,6 @@ def arch_pc(self, value: int) -> None: return self.uc.reg_write(self.uc_pc, value) - @property def arch_sp(self) -> int: """Get the value of the architectural stack pointer register. @@ -110,7 +102,6 @@ def arch_sp(self) -> int: return self.uc.reg_read(self.uc_sp) - @arch_sp.setter def arch_sp(self, value: int) -> None: """Set the value of the architectural stack pointer register. diff --git a/qiling/arch/riscv.py b/qiling/arch/riscv.py index e3d06af47..ded5f6302 100644 --- a/qiling/arch/riscv.py +++ b/qiling/arch/riscv.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# +# # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # @@ -16,6 +16,7 @@ from qiling.const import QL_ARCH, QL_ENDIAN from qiling.exception import QlErrorNotImplemented + class QlArchRISCV(QlArch): type = QL_ARCH.RISCV bits = 32 @@ -59,10 +60,10 @@ def enable_float(self): def init_context(self): self.regs.pc = 0x08000000 - + def unicorn_exception_handler(self, ql, intno): - if intno == 2: + if intno == 2: ql.log.warning(f'[{hex(self.regs.arch_pc)}] Illegal instruction') - + else: raise QlErrorNotImplemented(f'Unhandled interrupt number ({intno})') diff --git a/qiling/arch/riscv64.py b/qiling/arch/riscv64.py index 295cf1171..5dfafcde7 100644 --- a/qiling/arch/riscv64.py +++ b/qiling/arch/riscv64.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# +# # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # @@ -15,6 +15,7 @@ from .riscv import QlArchRISCV + class QlArchRISCV64(QlArchRISCV): type = QL_ARCH.RISCV64 bits = 64 diff --git a/qiling/arch/riscv_const.py b/qiling/arch/riscv_const.py index d85b68f76..4598674ce 100644 --- a/qiling/arch/riscv_const.py +++ b/qiling/arch/riscv_const.py @@ -1,23 +1,22 @@ #!/usr/bin/env python3 -# +# # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # from unicorn.riscv_const import * from enum import IntEnum - reg_general_map = { - "x0": UC_RISCV_REG_X0, - "x1": UC_RISCV_REG_X1, - "x2": UC_RISCV_REG_X2, - "x3": UC_RISCV_REG_X3, - "x4": UC_RISCV_REG_X4, - "x5": UC_RISCV_REG_X5, - "x6": UC_RISCV_REG_X6, - "x7": UC_RISCV_REG_X7, - "x8": UC_RISCV_REG_X8, - "x9": UC_RISCV_REG_X9, + "x0": UC_RISCV_REG_X0, + "x1": UC_RISCV_REG_X1, + "x2": UC_RISCV_REG_X2, + "x3": UC_RISCV_REG_X3, + "x4": UC_RISCV_REG_X4, + "x5": UC_RISCV_REG_X5, + "x6": UC_RISCV_REG_X6, + "x7": UC_RISCV_REG_X7, + "x8": UC_RISCV_REG_X8, + "x9": UC_RISCV_REG_X9, "x10": UC_RISCV_REG_X10, "x11": UC_RISCV_REG_X11, "x12": UC_RISCV_REG_X12, @@ -39,31 +38,31 @@ "x28": UC_RISCV_REG_X28, "x29": UC_RISCV_REG_X29, "x30": UC_RISCV_REG_X30, - "x31": UC_RISCV_REG_X31, + "x31": UC_RISCV_REG_X31 } reg_csr_map = { - "ustatus": UC_RISCV_REG_USTATUS, - "uie": UC_RISCV_REG_UIE, - "utvec": UC_RISCV_REG_UTVEC, - "uscratch": UC_RISCV_REG_USCRATCH, - "uepc": UC_RISCV_REG_UEPC, - "ucause": UC_RISCV_REG_UCAUSE, - "utval": UC_RISCV_REG_UTVAL, - "uip": UC_RISCV_REG_UIP, - "fflags": UC_RISCV_REG_FFLAGS, - "frm": UC_RISCV_REG_FRM, - "fcsr": UC_RISCV_REG_FCSR, - "cycle": UC_RISCV_REG_CYCLE, - "time": UC_RISCV_REG_TIME, - "instret": UC_RISCV_REG_INSTRET, - "hpmcounter3": UC_RISCV_REG_HPMCOUNTER3, - "hpmcounter4": UC_RISCV_REG_HPMCOUNTER4, - "hpmcounter5": UC_RISCV_REG_HPMCOUNTER5, - "hpmcounter6": UC_RISCV_REG_HPMCOUNTER6, - "hpmcounter7": UC_RISCV_REG_HPMCOUNTER7, - "hpmcounter8": UC_RISCV_REG_HPMCOUNTER8, - "hpmcounter9": UC_RISCV_REG_HPMCOUNTER9, + "ustatus": UC_RISCV_REG_USTATUS, + "uie": UC_RISCV_REG_UIE, + "utvec": UC_RISCV_REG_UTVEC, + "uscratch": UC_RISCV_REG_USCRATCH, + "uepc": UC_RISCV_REG_UEPC, + "ucause": UC_RISCV_REG_UCAUSE, + "utval": UC_RISCV_REG_UTVAL, + "uip": UC_RISCV_REG_UIP, + "fflags": UC_RISCV_REG_FFLAGS, + "frm": UC_RISCV_REG_FRM, + "fcsr": UC_RISCV_REG_FCSR, + "cycle": UC_RISCV_REG_CYCLE, + "time": UC_RISCV_REG_TIME, + "instret": UC_RISCV_REG_INSTRET, + "hpmcounter3": UC_RISCV_REG_HPMCOUNTER3, + "hpmcounter4": UC_RISCV_REG_HPMCOUNTER4, + "hpmcounter5": UC_RISCV_REG_HPMCOUNTER5, + "hpmcounter6": UC_RISCV_REG_HPMCOUNTER6, + "hpmcounter7": UC_RISCV_REG_HPMCOUNTER7, + "hpmcounter8": UC_RISCV_REG_HPMCOUNTER8, + "hpmcounter9": UC_RISCV_REG_HPMCOUNTER9, "hpmcounter10": UC_RISCV_REG_HPMCOUNTER10, "hpmcounter11": UC_RISCV_REG_HPMCOUNTER11, "hpmcounter12": UC_RISCV_REG_HPMCOUNTER12, @@ -86,9 +85,9 @@ "hpmcounter29": UC_RISCV_REG_HPMCOUNTER29, "hpmcounter30": UC_RISCV_REG_HPMCOUNTER30, "hpmcounter31": UC_RISCV_REG_HPMCOUNTER31, - "cycleh": UC_RISCV_REG_CYCLEH, - "timeh": UC_RISCV_REG_TIMEH, - "instreth": UC_RISCV_REG_INSTRETH, + "cycleh": UC_RISCV_REG_CYCLEH, + "timeh": UC_RISCV_REG_TIMEH, + "instreth": UC_RISCV_REG_INSTRETH, "hpmcounter3h": UC_RISCV_REG_HPMCOUNTER3H, "hpmcounter4h": UC_RISCV_REG_HPMCOUNTER4H, "hpmcounter5h": UC_RISCV_REG_HPMCOUNTER5H, @@ -118,69 +117,69 @@ "hpmcounter29h": UC_RISCV_REG_HPMCOUNTER29H, "hpmcounter30h": UC_RISCV_REG_HPMCOUNTER30H, "hpmcounter31h": UC_RISCV_REG_HPMCOUNTER31H, - "mcycle": UC_RISCV_REG_MCYCLE, - "minstret": UC_RISCV_REG_MINSTRET, - "mcycleh": UC_RISCV_REG_MCYCLEH, - "minstreth": UC_RISCV_REG_MINSTRETH, - "mvendorid": UC_RISCV_REG_MVENDORID, - "marchid": UC_RISCV_REG_MARCHID, - "mimpid": UC_RISCV_REG_MIMPID, - "mhartid": UC_RISCV_REG_MHARTID, - "mstatus": UC_RISCV_REG_MSTATUS, - "misa": UC_RISCV_REG_MISA, - "medeleg": UC_RISCV_REG_MEDELEG, - "mideleg": UC_RISCV_REG_MIDELEG, - "mie": UC_RISCV_REG_MIE, - "mtvec": UC_RISCV_REG_MTVEC, - "mcounteren": UC_RISCV_REG_MCOUNTEREN, - "mstatush": UC_RISCV_REG_MSTATUSH, - "mucounteren": UC_RISCV_REG_MUCOUNTEREN, - "mscounteren": UC_RISCV_REG_MSCOUNTEREN, - "mhcounteren": UC_RISCV_REG_MHCOUNTEREN, - "mscratch": UC_RISCV_REG_MSCRATCH, - "mepc": UC_RISCV_REG_MEPC, - "mcause": UC_RISCV_REG_MCAUSE, - "mtval": UC_RISCV_REG_MTVAL, - "mip": UC_RISCV_REG_MIP, - "mbadaddr": UC_RISCV_REG_MBADADDR, - "sstatus": UC_RISCV_REG_SSTATUS, - "sedeleg": UC_RISCV_REG_SEDELEG, - "sideleg": UC_RISCV_REG_SIDELEG, - "sie": UC_RISCV_REG_SIE, - "stvec": UC_RISCV_REG_STVEC, - "scounteren": UC_RISCV_REG_SCOUNTEREN, - "sscratch": UC_RISCV_REG_SSCRATCH, - "sepc": UC_RISCV_REG_SEPC, - "scause": UC_RISCV_REG_SCAUSE, - "stval": UC_RISCV_REG_STVAL, - "sip": UC_RISCV_REG_SIP, - "sbadaddr": UC_RISCV_REG_SBADADDR, - "sptbr": UC_RISCV_REG_SPTBR, - "satp": UC_RISCV_REG_SATP, - "hstatus": UC_RISCV_REG_HSTATUS, - "hedeleg": UC_RISCV_REG_HEDELEG, - "hideleg": UC_RISCV_REG_HIDELEG, - "hie": UC_RISCV_REG_HIE, - "hcounteren": UC_RISCV_REG_HCOUNTEREN, - "htval": UC_RISCV_REG_HTVAL, - "hip": UC_RISCV_REG_HIP, - "htinst": UC_RISCV_REG_HTINST, - "hgatp": UC_RISCV_REG_HGATP, - "htimedelta": UC_RISCV_REG_HTIMEDELTA, - "htimedeltah": UC_RISCV_REG_HTIMEDELTAH, + "mcycle": UC_RISCV_REG_MCYCLE, + "minstret": UC_RISCV_REG_MINSTRET, + "mcycleh": UC_RISCV_REG_MCYCLEH, + "minstreth": UC_RISCV_REG_MINSTRETH, + "mvendorid": UC_RISCV_REG_MVENDORID, + "marchid": UC_RISCV_REG_MARCHID, + "mimpid": UC_RISCV_REG_MIMPID, + "mhartid": UC_RISCV_REG_MHARTID, + "mstatus": UC_RISCV_REG_MSTATUS, + "misa": UC_RISCV_REG_MISA, + "medeleg": UC_RISCV_REG_MEDELEG, + "mideleg": UC_RISCV_REG_MIDELEG, + "mie": UC_RISCV_REG_MIE, + "mtvec": UC_RISCV_REG_MTVEC, + "mcounteren": UC_RISCV_REG_MCOUNTEREN, + "mstatush": UC_RISCV_REG_MSTATUSH, + "mucounteren": UC_RISCV_REG_MUCOUNTEREN, + "mscounteren": UC_RISCV_REG_MSCOUNTEREN, + "mhcounteren": UC_RISCV_REG_MHCOUNTEREN, + "mscratch": UC_RISCV_REG_MSCRATCH, + "mepc": UC_RISCV_REG_MEPC, + "mcause": UC_RISCV_REG_MCAUSE, + "mtval": UC_RISCV_REG_MTVAL, + "mip": UC_RISCV_REG_MIP, + "mbadaddr": UC_RISCV_REG_MBADADDR, + "sstatus": UC_RISCV_REG_SSTATUS, + "sedeleg": UC_RISCV_REG_SEDELEG, + "sideleg": UC_RISCV_REG_SIDELEG, + "sie": UC_RISCV_REG_SIE, + "stvec": UC_RISCV_REG_STVEC, + "scounteren": UC_RISCV_REG_SCOUNTEREN, + "sscratch": UC_RISCV_REG_SSCRATCH, + "sepc": UC_RISCV_REG_SEPC, + "scause": UC_RISCV_REG_SCAUSE, + "stval": UC_RISCV_REG_STVAL, + "sip": UC_RISCV_REG_SIP, + "sbadaddr": UC_RISCV_REG_SBADADDR, + "sptbr": UC_RISCV_REG_SPTBR, + "satp": UC_RISCV_REG_SATP, + "hstatus": UC_RISCV_REG_HSTATUS, + "hedeleg": UC_RISCV_REG_HEDELEG, + "hideleg": UC_RISCV_REG_HIDELEG, + "hie": UC_RISCV_REG_HIE, + "hcounteren": UC_RISCV_REG_HCOUNTEREN, + "htval": UC_RISCV_REG_HTVAL, + "hip": UC_RISCV_REG_HIP, + "htinst": UC_RISCV_REG_HTINST, + "hgatp": UC_RISCV_REG_HGATP, + "htimedelta": UC_RISCV_REG_HTIMEDELTA, + "htimedeltah": UC_RISCV_REG_HTIMEDELTAH } reg_float_map = { - "f0": UC_RISCV_REG_F0, - "f1": UC_RISCV_REG_F1, - "f2": UC_RISCV_REG_F2, - "f3": UC_RISCV_REG_F3, - "f4": UC_RISCV_REG_F4, - "f5": UC_RISCV_REG_F5, - "f6": UC_RISCV_REG_F6, - "f7": UC_RISCV_REG_F7, - "f8": UC_RISCV_REG_F8, - "f9": UC_RISCV_REG_F9, + "f0": UC_RISCV_REG_F0, + "f1": UC_RISCV_REG_F1, + "f2": UC_RISCV_REG_F2, + "f3": UC_RISCV_REG_F3, + "f4": UC_RISCV_REG_F4, + "f5": UC_RISCV_REG_F5, + "f6": UC_RISCV_REG_F6, + "f7": UC_RISCV_REG_F7, + "f8": UC_RISCV_REG_F8, + "f9": UC_RISCV_REG_F9, "f10": UC_RISCV_REG_F10, "f11": UC_RISCV_REG_F11, "f12": UC_RISCV_REG_F12, @@ -202,80 +201,81 @@ "f28": UC_RISCV_REG_F28, "f29": UC_RISCV_REG_F29, "f30": UC_RISCV_REG_F30, - "f31": UC_RISCV_REG_F31, + "f31": UC_RISCV_REG_F31 } reg_map = { - "pc": UC_RISCV_REG_PC, "zero": UC_RISCV_REG_ZERO, - "ra": UC_RISCV_REG_RA, - "sp": UC_RISCV_REG_SP, - "gp": UC_RISCV_REG_GP, - "tp": UC_RISCV_REG_TP, - "t0": UC_RISCV_REG_T0, - "t1": UC_RISCV_REG_T1, - "t2": UC_RISCV_REG_T2, - "s0": UC_RISCV_REG_S0, - "fp": UC_RISCV_REG_FP, - "s1": UC_RISCV_REG_S1, - "a0": UC_RISCV_REG_A0, - "a1": UC_RISCV_REG_A1, - "a2": UC_RISCV_REG_A2, - "a3": UC_RISCV_REG_A3, - "a4": UC_RISCV_REG_A4, - "a5": UC_RISCV_REG_A5, - "a6": UC_RISCV_REG_A6, - "a7": UC_RISCV_REG_A7, - "s2": UC_RISCV_REG_S2, - "s3": UC_RISCV_REG_S3, - "s4": UC_RISCV_REG_S4, - "s5": UC_RISCV_REG_S5, - "s6": UC_RISCV_REG_S6, - "s7": UC_RISCV_REG_S7, - "s8": UC_RISCV_REG_S8, - "s9": UC_RISCV_REG_S9, - "s10": UC_RISCV_REG_S10, - "s11": UC_RISCV_REG_S11, - "t3": UC_RISCV_REG_T3, - "t4": UC_RISCV_REG_T4, - "t5": UC_RISCV_REG_T5, - "t6": UC_RISCV_REG_T6, - "ft0": UC_RISCV_REG_FT0, - "ft1": UC_RISCV_REG_FT1, - "ft2": UC_RISCV_REG_FT2, - "ft3": UC_RISCV_REG_FT3, - "ft4": UC_RISCV_REG_FT4, - "ft5": UC_RISCV_REG_FT5, - "ft6": UC_RISCV_REG_FT6, - "ft7": UC_RISCV_REG_FT7, - "fs0": UC_RISCV_REG_FS0, - "fs1": UC_RISCV_REG_FS1, - "fa0": UC_RISCV_REG_FA0, - "fa1": UC_RISCV_REG_FA1, - "fa2": UC_RISCV_REG_FA2, - "fa3": UC_RISCV_REG_FA3, - "fa4": UC_RISCV_REG_FA4, - "fa5": UC_RISCV_REG_FA5, - "fa6": UC_RISCV_REG_FA6, - "fa7": UC_RISCV_REG_FA7, - "fs2": UC_RISCV_REG_FS2, - "fs3": UC_RISCV_REG_FS3, - "fs4": UC_RISCV_REG_FS4, - "fs5": UC_RISCV_REG_FS5, - "fs6": UC_RISCV_REG_FS6, - "fs7": UC_RISCV_REG_FS7, - "fs8": UC_RISCV_REG_FS8, - "fs9": UC_RISCV_REG_FS9, + "ra": UC_RISCV_REG_RA, + "sp": UC_RISCV_REG_SP, + "gp": UC_RISCV_REG_GP, + "tp": UC_RISCV_REG_TP, + "t0": UC_RISCV_REG_T0, + "t1": UC_RISCV_REG_T1, + "t2": UC_RISCV_REG_T2, + "s0": UC_RISCV_REG_S0, + "fp": UC_RISCV_REG_FP, + "s1": UC_RISCV_REG_S1, + "a0": UC_RISCV_REG_A0, + "a1": UC_RISCV_REG_A1, + "a2": UC_RISCV_REG_A2, + "a3": UC_RISCV_REG_A3, + "a4": UC_RISCV_REG_A4, + "a5": UC_RISCV_REG_A5, + "a6": UC_RISCV_REG_A6, + "a7": UC_RISCV_REG_A7, + "s2": UC_RISCV_REG_S2, + "s3": UC_RISCV_REG_S3, + "s4": UC_RISCV_REG_S4, + "s5": UC_RISCV_REG_S5, + "s6": UC_RISCV_REG_S6, + "s7": UC_RISCV_REG_S7, + "s8": UC_RISCV_REG_S8, + "s9": UC_RISCV_REG_S9, + "s10": UC_RISCV_REG_S10, + "s11": UC_RISCV_REG_S11, + "t3": UC_RISCV_REG_T3, + "t4": UC_RISCV_REG_T4, + "t5": UC_RISCV_REG_T5, + "t6": UC_RISCV_REG_T6, + "ft0": UC_RISCV_REG_FT0, + "ft1": UC_RISCV_REG_FT1, + "ft2": UC_RISCV_REG_FT2, + "ft3": UC_RISCV_REG_FT3, + "ft4": UC_RISCV_REG_FT4, + "ft5": UC_RISCV_REG_FT5, + "ft6": UC_RISCV_REG_FT6, + "ft7": UC_RISCV_REG_FT7, + "fs0": UC_RISCV_REG_FS0, + "fs1": UC_RISCV_REG_FS1, + "fa0": UC_RISCV_REG_FA0, + "fa1": UC_RISCV_REG_FA1, + "fa2": UC_RISCV_REG_FA2, + "fa3": UC_RISCV_REG_FA3, + "fa4": UC_RISCV_REG_FA4, + "fa5": UC_RISCV_REG_FA5, + "fa6": UC_RISCV_REG_FA6, + "fa7": UC_RISCV_REG_FA7, + "fs2": UC_RISCV_REG_FS2, + "fs3": UC_RISCV_REG_FS3, + "fs4": UC_RISCV_REG_FS4, + "fs5": UC_RISCV_REG_FS5, + "fs6": UC_RISCV_REG_FS6, + "fs7": UC_RISCV_REG_FS7, + "fs8": UC_RISCV_REG_FS8, + "fs9": UC_RISCV_REG_FS9, "fs10": UC_RISCV_REG_FS10, "fs11": UC_RISCV_REG_FS11, - "ft8": UC_RISCV_REG_FT8, - "ft9": UC_RISCV_REG_FT9, + "ft8": UC_RISCV_REG_FT8, + "ft9": UC_RISCV_REG_FT9, "ft10": UC_RISCV_REG_FT10, "ft11": UC_RISCV_REG_FT11, + "pc": UC_RISCV_REG_PC } + class MSTATUS(IntEnum): - FS_OFF = 0 - FS_INITIAL = 1 << 13 - FS_CLEAN = 2 << 13 - FS_DIRTY = 3 << 13 + FS_OFF = 0 + FS_INITIAL = 1 << 13 + FS_CLEAN = 2 << 13 + FS_DIRTY = 3 << 13 diff --git a/qiling/arch/utils.py b/qiling/arch/utils.py index 7c6bcd9c8..cc0c3d606 100644 --- a/qiling/arch/utils.py +++ b/qiling/arch/utils.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# +# # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # @@ -18,6 +18,7 @@ from qiling import Qiling from qiling.const import QL_ARCH, QL_ENDIAN, QL_VERBOSE + class QlArchUtils: def __init__(self, ql: Qiling): self.ql = ql @@ -83,6 +84,7 @@ def ql_hook_block_disasm(ql: Qiling, address: int, size: int): if verbosity >= QL_VERBOSE.DUMP: self._block_hook = self.ql.hook_block(ql_hook_block_disasm) + # used by qltool prior to ql instantiation. to get an assembler object # after ql instantiation, use the appropriate ql.arch method def assembler(arch: QL_ARCH, endianess: QL_ENDIAN, is_thumb: bool) -> Ks: @@ -97,20 +99,20 @@ def assembler(arch: QL_ARCH, endianess: QL_ENDIAN, is_thumb: bool) -> Ks: """ endian = { - QL_ENDIAN.EL : KS_MODE_LITTLE_ENDIAN, - QL_ENDIAN.EB : KS_MODE_BIG_ENDIAN + QL_ENDIAN.EL: KS_MODE_LITTLE_ENDIAN, + QL_ENDIAN.EB: KS_MODE_BIG_ENDIAN }[endianess] thumb = KS_MODE_THUMB if is_thumb else 0 asm_map = { - QL_ARCH.ARM : (KS_ARCH_ARM, KS_MODE_ARM + endian + thumb), - QL_ARCH.ARM64 : (KS_ARCH_ARM64, KS_MODE_ARM), - QL_ARCH.MIPS : (KS_ARCH_MIPS, KS_MODE_MIPS32 + endian), - QL_ARCH.A8086 : (KS_ARCH_X86, KS_MODE_16), - QL_ARCH.X86 : (KS_ARCH_X86, KS_MODE_32), - QL_ARCH.X8664 : (KS_ARCH_X86, KS_MODE_64), - QL_ARCH.PPC : (KS_ARCH_PPC, KS_MODE_PPC32 + KS_MODE_BIG_ENDIAN) + QL_ARCH.ARM: (KS_ARCH_ARM, KS_MODE_ARM + endian + thumb), + QL_ARCH.ARM64: (KS_ARCH_ARM64, KS_MODE_ARM), + QL_ARCH.MIPS: (KS_ARCH_MIPS, KS_MODE_MIPS32 + endian), + QL_ARCH.A8086: (KS_ARCH_X86, KS_MODE_16), + QL_ARCH.X86: (KS_ARCH_X86, KS_MODE_32), + QL_ARCH.X8664: (KS_ARCH_X86, KS_MODE_64), + QL_ARCH.PPC: (KS_ARCH_PPC, KS_MODE_PPC32 + KS_MODE_BIG_ENDIAN) } if arch in asm_map: diff --git a/qiling/arch/x86.py b/qiling/arch/x86.py index 0147c1a31..6db9e664c 100644 --- a/qiling/arch/x86.py +++ b/qiling/arch/x86.py @@ -15,6 +15,7 @@ from qiling.arch import x86_const from qiling.const import QL_ARCH, QL_ENDIAN + class QlArchIntel(QlArch): @property def endian(self) -> QL_ENDIAN: @@ -27,6 +28,7 @@ def msr(self) -> QlMsrManager: return QlMsrManager(self.uc) + class QlArchA8086(QlArchIntel): type = QL_ARCH.A8086 bits = 16 @@ -56,6 +58,7 @@ def disassembler(self) -> Cs: def assembler(self) -> Ks: return Ks(KS_ARCH_X86, KS_MODE_16) + class QlArchX86(QlArchIntel): type = QL_ARCH.X86 bits = 32 @@ -89,6 +92,7 @@ def disassembler(self) -> Cs: def assembler(self) -> Ks: return Ks(KS_ARCH_X86, KS_MODE_32) + class QlArchX8664(QlArchIntel): type = QL_ARCH.X8664 bits = 64 @@ -121,6 +125,7 @@ def regs(self) -> QlRegisterManager: sp_reg = 'rsp' return QlRegisterManager(self.uc, regs_map, pc_reg, sp_reg) + @cached_property def disassembler(self) -> Cs: return Cs(CS_ARCH_X86, CS_MODE_64) diff --git a/qiling/arch/x86_const.py b/qiling/arch/x86_const.py index 1e60479fb..d4716ba6e 100644 --- a/qiling/arch/x86_const.py +++ b/qiling/arch/x86_const.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# +# # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # @@ -60,7 +60,7 @@ "dh": UC_X86_REG_DH, "dl": UC_X86_REG_DL, "bh": UC_X86_REG_BH, - "bl": UC_X86_REG_BL, + "bl": UC_X86_REG_BL } reg_map_16 = { @@ -72,44 +72,44 @@ "bp": UC_X86_REG_BP, "si": UC_X86_REG_SI, "di": UC_X86_REG_DI, - "ip": UC_X86_REG_IP, + "ip": UC_X86_REG_IP } reg_map_32 = { - "eax": UC_X86_REG_EAX, - "ecx": UC_X86_REG_ECX, + "eax": UC_X86_REG_EAX, + "ecx": UC_X86_REG_ECX, "edx": UC_X86_REG_EDX, "ebx": UC_X86_REG_EBX, - "esp": UC_X86_REG_ESP, + "esp": UC_X86_REG_ESP, "ebp": UC_X86_REG_EBP, - "esi": UC_X86_REG_ESI, - "edi": UC_X86_REG_EDI, - "eip": UC_X86_REG_EIP, + "esi": UC_X86_REG_ESI, + "edi": UC_X86_REG_EDI, + "eip": UC_X86_REG_EIP } reg_map_64 = { "rax": UC_X86_REG_RAX, - "rbx": UC_X86_REG_RBX, - "rcx": UC_X86_REG_RCX, + "rbx": UC_X86_REG_RBX, + "rcx": UC_X86_REG_RCX, "rdx": UC_X86_REG_RDX, - "rsi": UC_X86_REG_RSI, + "rsi": UC_X86_REG_RSI, "rdi": UC_X86_REG_RDI, "rbp": UC_X86_REG_RBP, - "rsp": UC_X86_REG_RSP, - "r8": UC_X86_REG_R8, - "r9": UC_X86_REG_R9, + "rsp": UC_X86_REG_RSP, + "r8": UC_X86_REG_R8, + "r9": UC_X86_REG_R9, "r10": UC_X86_REG_R10, "r11": UC_X86_REG_R11, - "r12": UC_X86_REG_R12, - "r13": UC_X86_REG_R13, + "r12": UC_X86_REG_R12, + "r13": UC_X86_REG_R13, "r14": UC_X86_REG_R14, "r15": UC_X86_REG_R15, - "rip": UC_X86_REG_RIP, + "rip": UC_X86_REG_RIP } reg_map_seg_base = { - "fsbase" : UC_X86_REG_FS_BASE, - "gsbase" : UC_X86_REG_GS_BASE + "fsbase": UC_X86_REG_FS_BASE, + "gsbase": UC_X86_REG_GS_BASE } reg_map_64_b = { @@ -120,7 +120,7 @@ "r12b": UC_X86_REG_R12B, "r13b": UC_X86_REG_R13B, "r14b": UC_X86_REG_R14B, - "r15b": UC_X86_REG_R15B, + "r15b": UC_X86_REG_R15B } reg_map_64_w = { @@ -131,7 +131,7 @@ "r12w": UC_X86_REG_R12W, "r13w": UC_X86_REG_R13W, "r14w": UC_X86_REG_R14W, - "r15w": UC_X86_REG_R15W, + "r15w": UC_X86_REG_R15W } reg_map_64_d = { @@ -142,48 +142,48 @@ "r12d": UC_X86_REG_R12D, "r13d": UC_X86_REG_R13D, "r14d": UC_X86_REG_R14D, - "r15d": UC_X86_REG_R15D, + "r15d": UC_X86_REG_R15D } reg_map_cr = { - "cr0": UC_X86_REG_CR0, + "cr0": UC_X86_REG_CR0, "cr1": UC_X86_REG_CR1, - "cr2": UC_X86_REG_CR2, - "cr3": UC_X86_REG_CR3, + "cr2": UC_X86_REG_CR2, + "cr3": UC_X86_REG_CR3, "cr4": UC_X86_REG_CR4, "cr8": UC_X86_REG_CR8 } reg_map_dr = { - "dr0": UC_X86_REG_DR0, + "dr0": UC_X86_REG_DR0, "dr1": UC_X86_REG_DR1, - "dr2": UC_X86_REG_DR2, - "dr3": UC_X86_REG_DR3, + "dr2": UC_X86_REG_DR2, + "dr3": UC_X86_REG_DR3, "dr4": UC_X86_REG_DR4, - "dr5": UC_X86_REG_DR5, - "dr6": UC_X86_REG_DR6, - "dr7": UC_X86_REG_DR7, + "dr5": UC_X86_REG_DR5, + "dr6": UC_X86_REG_DR6, + "dr7": UC_X86_REG_DR7 } reg_map_st = { - "st0": UC_X86_REG_ST0, + "st0": UC_X86_REG_ST0, "st1": UC_X86_REG_ST1, - "st2": UC_X86_REG_ST2, - "st3": UC_X86_REG_ST3, + "st2": UC_X86_REG_ST2, + "st3": UC_X86_REG_ST3, "st4": UC_X86_REG_ST4, - "st5": UC_X86_REG_ST5, - "st6": UC_X86_REG_ST6, + "st5": UC_X86_REG_ST5, + "st6": UC_X86_REG_ST6, "st7": UC_X86_REG_ST7 } reg_map_misc = { - "eflags": UC_X86_REG_EFLAGS, - "cs": UC_X86_REG_CS, + "eflags": UC_X86_REG_EFLAGS, + "cs": UC_X86_REG_CS, "ss": UC_X86_REG_SS, - "ds": UC_X86_REG_DS, - "es": UC_X86_REG_ES, + "ds": UC_X86_REG_DS, + "es": UC_X86_REG_ES, "fs": UC_X86_REG_FS, - "gs": UC_X86_REG_GS, + "gs": UC_X86_REG_GS } reg_map_fp = { @@ -194,20 +194,20 @@ "fp4": UC_X86_REG_FP4, "fp5": UC_X86_REG_FP5, "fp6": UC_X86_REG_FP6, - "fp7": UC_X86_REG_FP7, + "fp7": UC_X86_REG_FP7 } reg_map_xmm = { - "xmm0": UC_X86_REG_XMM0, - "xmm1": UC_X86_REG_XMM1, - "xmm2": UC_X86_REG_XMM2, - "xmm3": UC_X86_REG_XMM3, - "xmm4": UC_X86_REG_XMM4, - "xmm5": UC_X86_REG_XMM5, - "xmm6": UC_X86_REG_XMM6, - "xmm7": UC_X86_REG_XMM7, - "xmm8": UC_X86_REG_XMM8, - "xmm9": UC_X86_REG_XMM9, + "xmm0": UC_X86_REG_XMM0, + "xmm1": UC_X86_REG_XMM1, + "xmm2": UC_X86_REG_XMM2, + "xmm3": UC_X86_REG_XMM3, + "xmm4": UC_X86_REG_XMM4, + "xmm5": UC_X86_REG_XMM5, + "xmm6": UC_X86_REG_XMM6, + "xmm7": UC_X86_REG_XMM7, + "xmm8": UC_X86_REG_XMM8, + "xmm9": UC_X86_REG_XMM9, "xmm10": UC_X86_REG_XMM10, "xmm11": UC_X86_REG_XMM11, "xmm12": UC_X86_REG_XMM12, @@ -229,20 +229,20 @@ "xmm28": UC_X86_REG_XMM28, "xmm29": UC_X86_REG_XMM29, "xmm30": UC_X86_REG_XMM30, - "xmm31": UC_X86_REG_XMM31, + "xmm31": UC_X86_REG_XMM31 } reg_map_ymm = { - "ymm0": UC_X86_REG_YMM0, - "ymm1": UC_X86_REG_YMM1, - "ymm2": UC_X86_REG_YMM2, - "ymm3": UC_X86_REG_YMM3, - "ymm4": UC_X86_REG_YMM4, - "ymm5": UC_X86_REG_YMM5, - "ymm6": UC_X86_REG_YMM6, - "ymm7": UC_X86_REG_YMM7, - "ymm8": UC_X86_REG_YMM8, - "ymm9": UC_X86_REG_YMM9, + "ymm0": UC_X86_REG_YMM0, + "ymm1": UC_X86_REG_YMM1, + "ymm2": UC_X86_REG_YMM2, + "ymm3": UC_X86_REG_YMM3, + "ymm4": UC_X86_REG_YMM4, + "ymm5": UC_X86_REG_YMM5, + "ymm6": UC_X86_REG_YMM6, + "ymm7": UC_X86_REG_YMM7, + "ymm8": UC_X86_REG_YMM8, + "ymm9": UC_X86_REG_YMM9, "ymm10": UC_X86_REG_YMM10, "ymm11": UC_X86_REG_YMM11, "ymm12": UC_X86_REG_YMM12, @@ -264,20 +264,20 @@ "ymm28": UC_X86_REG_YMM28, "ymm29": UC_X86_REG_YMM29, "ymm30": UC_X86_REG_YMM30, - "ymm31": UC_X86_REG_YMM31, + "ymm31": UC_X86_REG_YMM31 } reg_map_zmm = { - "zmm0": UC_X86_REG_ZMM0, - "zmm1": UC_X86_REG_ZMM1, - "zmm2": UC_X86_REG_ZMM2, - "zmm3": UC_X86_REG_ZMM3, - "zmm4": UC_X86_REG_ZMM4, - "zmm5": UC_X86_REG_ZMM5, - "zmm6": UC_X86_REG_ZMM6, - "zmm7": UC_X86_REG_ZMM7, - "zmm8": UC_X86_REG_ZMM8, - "zmm9": UC_X86_REG_ZMM9, + "zmm0": UC_X86_REG_ZMM0, + "zmm1": UC_X86_REG_ZMM1, + "zmm2": UC_X86_REG_ZMM2, + "zmm3": UC_X86_REG_ZMM3, + "zmm4": UC_X86_REG_ZMM4, + "zmm5": UC_X86_REG_ZMM5, + "zmm6": UC_X86_REG_ZMM6, + "zmm7": UC_X86_REG_ZMM7, + "zmm8": UC_X86_REG_ZMM8, + "zmm9": UC_X86_REG_ZMM9, "zmm10": UC_X86_REG_ZMM10, "zmm11": UC_X86_REG_ZMM11, "zmm12": UC_X86_REG_ZMM12, @@ -299,6 +299,5 @@ "zmm28": UC_X86_REG_ZMM28, "zmm29": UC_X86_REG_ZMM29, "zmm30": UC_X86_REG_ZMM30, - "zmm31": UC_X86_REG_ZMM31, + "zmm31": UC_X86_REG_ZMM31 } - diff --git a/qiling/arch/x86_utils.py b/qiling/arch/x86_utils.py index f0f58706f..587477ad7 100644 --- a/qiling/arch/x86_utils.py +++ b/qiling/arch/x86_utils.py @@ -8,6 +8,7 @@ from qiling.exception import QlGDTError, QlMemoryMappedError from qiling.os.memory import QlMemoryManager + class GDTArray: entsize = QL_X86_GDT_ENTRY_SIZE @@ -48,7 +49,7 @@ def get_next_free(self, start: Optional[int] = None, end: Optional[int] = None) class GDTManager: - def __init__(self, ql: Qiling, base = QL_X86_GDT_ADDR, limit = QL_X86_GDT_LIMIT, num_entries = 16): + def __init__(self, ql: Qiling, base=QL_X86_GDT_ADDR, limit=QL_X86_GDT_LIMIT, num_entries=16): ql.log.debug(f'Mapping GDT at {base:#x} with limit {limit:#x}') if not ql.mem.is_available(base, limit): @@ -144,7 +145,7 @@ def setup_cs_ds_ss_es(self, base: int, size: int) -> None: self.arch.regs.cs = selector # TODO : The section permission here should be QL_X86_A_PRIV_3, but I do n’t know why it can only be set to QL_X86_A_PRIV_0. - # While debugging the Linux kernel segment, I found that the three segments DS, SS, and ES all point to the same location in the GDT table. + # While debugging the Linux kernel segment, I found that the three segments DS, SS, and ES all point to the same location in the GDT table. # This position is the fifth segment table of GDT. access = QL_X86_A_PRESENT | QL_X86_A_DATA | QL_X86_A_DATA_WRITABLE | QL_X86_A_PRIV_0 | QL_X86_A_DIR_CON_BIT selector = self.gdtm.register_gdt_segment(5, base, size - 1, access) diff --git a/qiling/core.py b/qiling/core.py index 452b42138..b745668ad 100644 --- a/qiling/core.py +++ b/qiling/core.py @@ -3,7 +3,8 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import os, pickle +import os +import pickle from functools import cached_property from typing import TYPE_CHECKING, Any, AnyStr, List, Mapping, MutableMapping, Optional, Sequence, Tuple, Union @@ -27,7 +28,7 @@ from .core_struct import QlCoreStructs from .core_hooks import QlCoreHooks -# Mixin Pattern + class Qiling(QlCoreHooks, QlCoreStructs): def __init__( self, @@ -204,7 +205,6 @@ def hw(self) -> "QlHwManager": """ return self._hw - @property def arch(self) -> "QlArch": """ Qiling architecture layer. @@ -548,7 +548,6 @@ def write_exit_trap(self): elif QL_STOP.EXIT_TRAP in self.stop_options: self.log.debug(f'Loader requested to skip exit_trap!') - ############### # Qiling APIS # ############### @@ -686,7 +685,6 @@ def restore(self, saved_states: Mapping[str, Any] = {}, *, snapshot: Optional[st if "loader" in saved_states: self.loader.restore(saved_states["loader"]) - # Map "ql_path" to any objects which implements QlFsMappedObject. def add_fs_mapper(self, ql_path: Union["PathLike", str], real_dest): self.os.fs_mapper.add_fs_mapping(ql_path, real_dest) @@ -699,24 +697,20 @@ def remove_fs_mapper(self, ql_path: Union["PathLike", str]): def stack_push(self, data): return self.arch.stack_push(data) - # pop from stack bottom, and update stack register def stack_pop(self): return self.arch.stack_pop() - # read from stack, at a given offset from stack bottom # NOTE: unlike stack_pop(), this does not change stack register def stack_read(self, offset): return self.arch.stack_read(offset) - # write to stack, at a given offset from stack bottom # NOTE: unlike stack_push(), this does not change stack register def stack_write(self, offset, data): return self.arch.stack_write(offset, data) - # stop emulation def emu_stop(self): self.uc.emu_stop() diff --git a/qiling/debugger/gdb/xmlregs.py b/qiling/debugger/gdb/xmlregs.py index e475897e2..89b68964b 100644 --- a/qiling/debugger/gdb/xmlregs.py +++ b/qiling/debugger/gdb/xmlregs.py @@ -3,30 +3,39 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -from typing import Iterator, Mapping, Optional, Sequence, Tuple +from typing import Iterator, List, Mapping, Optional, Sequence, Tuple from pathlib import PurePath from xml.etree import ElementTree, ElementInclude -from qiling.arch.arm_const import reg_map as arm_regs -from qiling.arch.arm_const import reg_vfp as arm_regs_vfp -from qiling.arch.arm_const import reg_map_q as arm_regs_q -from qiling.arch.arm_const import reg_map_s as arm_regs_s -from qiling.arch.arm64_const import reg_map as arm64_regs -from qiling.arch.arm64_const import reg_map_v as arm64_regs_v -from qiling.arch.mips_const import reg_map as mips_regs_gpr -from qiling.arch.mips_const import reg_map_fpu as mips_regs_fpu -from qiling.arch.x86_const import reg_map_32 as x86_regs_32 -from qiling.arch.x86_const import reg_map_64 as x86_regs_64 -from qiling.arch.x86_const import reg_map_misc as x86_regs_misc -from qiling.arch.x86_const import reg_map_cr as x86_regs_cr -from qiling.arch.x86_const import reg_map_st as x86_regs_st -from qiling.arch.x86_const import reg_map_xmm as x86_regs_xmm -from qiling.arch.x86_const import reg_map_ymm as x86_regs_ymm +from qiling.arch.arm_const import ( + reg_map as arm_regs, + reg_vfp as arm_regs_vfp, + reg_map_q as arm_regs_q, + reg_map_s as arm_regs_s +) +from qiling.arch.arm64_const import ( + reg_map as arm64_regs, + reg_map_v as arm64_regs_v +) +from qiling.arch.mips_const import ( + reg_map as mips_regs_gpr, + reg_map_fpu as mips_regs_fpu +) +from qiling.arch.x86_const import ( + reg_map_32 as x86_regs_32, + reg_map_64 as x86_regs_64, + reg_map_misc as x86_regs_misc, + reg_map_cr as x86_regs_cr, + reg_map_st as x86_regs_st, + reg_map_xmm as x86_regs_xmm, + reg_map_ymm as x86_regs_ymm +) from qiling.const import QL_ARCH, QL_OS RegEntry = Tuple[Optional[int], int, int] + class QlGdbFeatures: def __init__(self, archtype: QL_ARCH, ostype: QL_OS): xmltree = QlGdbFeatures.__load_target_xml(archtype, ostype) @@ -81,13 +90,13 @@ def __wrapped(href: str, parse, encoding=None): # earlier gdb versions use 'Cygwin' instead abitag = { - QL_OS.LINUX : 'GNU/Linux', - QL_OS.FREEBSD : 'FreeBSD', - QL_OS.MACOS : 'Darwin', - QL_OS.WINDOWS : 'Windows', - QL_OS.UEFI : 'Windows', - QL_OS.DOS : 'Windows', - QL_OS.QNX : 'QNX-Neutrino' + QL_OS.LINUX: 'GNU/Linux', + QL_OS.FREEBSD: 'FreeBSD', + QL_OS.MACOS: 'Darwin', + QL_OS.WINDOWS: 'Windows', + QL_OS.UEFI: 'Windows', + QL_OS.DOS: 'Windows', + QL_OS.QNX: 'QNX-Neutrino' }.get(ostype, 'unknown') osabi.text = abitag @@ -120,20 +129,20 @@ def __load_regsmap(archtype: QL_ARCH, xmltree: ElementTree.ElementTree) -> Seque # retreive the relevant set of registers; their order of appearance is not # important as it is determined by the info read from the xml files ucregs: Mapping[str, int] = { - QL_ARCH.A8086 : dict(**x86_regs_32, **x86_regs_misc, **x86_regs_cr, **x86_regs_st), - QL_ARCH.X86 : dict(**x86_regs_32, **x86_regs_misc, **x86_regs_cr, **x86_regs_st, **x86_regs_xmm), - QL_ARCH.X8664 : dict(**x86_regs_64, **x86_regs_misc, **x86_regs_cr, **x86_regs_st, **x86_regs_xmm, **x86_regs_ymm), - QL_ARCH.ARM : dict(**arm_regs, **arm_regs_vfp, **arm_regs_q, **arm_regs_s), - QL_ARCH.CORTEX_M : arm_regs, - QL_ARCH.ARM64 : dict(**arm64_regs, **arm64_regs_v), - QL_ARCH.MIPS : dict(**mips_regs_gpr, **mips_regs_fpu) + QL_ARCH.A8086: dict(**x86_regs_32, **x86_regs_misc, **x86_regs_cr, **x86_regs_st), + QL_ARCH.X86: dict(**x86_regs_32, **x86_regs_misc, **x86_regs_cr, **x86_regs_st, **x86_regs_xmm), + QL_ARCH.X8664: dict(**x86_regs_64, **x86_regs_misc, **x86_regs_cr, **x86_regs_st, **x86_regs_xmm, **x86_regs_ymm), + QL_ARCH.ARM: dict(**arm_regs, **arm_regs_vfp, **arm_regs_q, **arm_regs_s), + QL_ARCH.CORTEX_M: arm_regs, + QL_ARCH.ARM64: dict(**arm64_regs, **arm64_regs_v), + QL_ARCH.MIPS: dict(**mips_regs_gpr, **mips_regs_fpu) }[archtype] regsinfo = sorted(QlGdbFeatures.__walk_xml_regs(xmltree)) # pre-allocate regmap and occupy it with null entries last_regnum = regsinfo[-1][0] - regmap: Sequence[RegEntry] = [(None, 0, 0)] * (last_regnum + 1) + regmap: List[RegEntry] = [(None, 0, 0)] * (last_regnum + 1) pos = 0