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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# EditorConfig is awesome: https://editorconfig.org

# top-most EditorConfig file
root = true

[*.py]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
15 changes: 10 additions & 5 deletions qiling/arch/arch.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
#

from abc import abstractmethod
from abc import ABC, abstractmethod
from typing import ClassVar, Optional

from unicorn import Uc
from unicorn.unicorn import UcContext
Expand All @@ -12,16 +13,20 @@

from qiling import Qiling
from qiling.const import QL_ARCH, QL_ENDIAN

from .models import QL_CPU
from .register import QlRegisterManager
from .utils import QlArchUtils


class QlArch:
type: QL_ARCH
bits: int
class QlArch(ABC):
type: ClassVar[QL_ARCH]
bits: ClassVar[int]

def __init__(self, ql: Qiling):
def __init__(self, ql: Qiling, *, cputype: Optional[QL_CPU] = None):
self.ql = ql

self.cpu = cputype
self.utils = QlArchUtils(ql)

@property
Expand Down
19 changes: 13 additions & 6 deletions qiling/arch/arm.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#

from functools import cached_property, lru_cache
from typing import Optional

from unicorn import Uc, UC_ARCH_ARM, UC_MODE_ARM, UC_MODE_THUMB, UC_MODE_BIG_ENDIAN
from capstone import Cs, CS_ARCH_ARM, CS_MODE_ARM, CS_MODE_THUMB, CS_MODE_BIG_ENDIAN
Expand All @@ -12,6 +13,7 @@
from qiling import Qiling
from qiling.arch.arch import QlArch
from qiling.arch import arm_const
from qiling.arch.models import ARM_CPU_MODEL
from qiling.arch.register import QlRegisterManager
from qiling.const import QL_ARCH, QL_ENDIAN

Expand All @@ -20,8 +22,8 @@ class QlArchARM(QlArch):
type = QL_ARCH.ARM
bits = 32

def __init__(self, ql: Qiling, endian: QL_ENDIAN, thumb: bool):
super().__init__(ql)
def __init__(self, ql: Qiling, *, cputype: Optional[ARM_CPU_MODEL], endian: QL_ENDIAN, thumb: bool):
super().__init__(ql, cputype=cputype)

self._init_endian = endian
self._init_thumb = thumb
Expand All @@ -32,13 +34,18 @@ def __init__(self, ql: Qiling, endian: QL_ENDIAN, thumb: bool):
def uc(self) -> Uc:
mode = UC_MODE_ARM

if self._init_endian == QL_ENDIAN.EB:
if self._init_endian is QL_ENDIAN.EB:
mode += UC_MODE_BIG_ENDIAN

if self._init_thumb:
mode += UC_MODE_THUMB

return Uc(UC_ARCH_ARM, mode)
obj = Uc(UC_ARCH_ARM, mode)

if self.cpu is not None:
obj.ctl_set_cpu_model(self.cpu.value)

return obj

@cached_property
def regs(self) -> QlRegisterManager:
Expand Down Expand Up @@ -82,7 +89,7 @@ def disassembler(self) -> Cs:

mode = CS_MODE_ARM

if self.endian == QL_ENDIAN.EB:
if self.endian is QL_ENDIAN.EB:
mode += CS_MODE_BIG_ENDIAN

if self.is_thumb:
Expand All @@ -102,7 +109,7 @@ def assembler(self) -> Ks:

mode = KS_MODE_ARM

if self.endian == QL_ENDIAN.EB:
if self.endian is QL_ENDIAN.EB:
mode += KS_MODE_BIG_ENDIAN

if self.is_thumb:
Expand Down
13 changes: 12 additions & 1 deletion qiling/arch/arm64.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
#

from functools import cached_property
from typing import Optional

from unicorn import Uc, UC_ARCH_ARM64, UC_MODE_ARM
from capstone import Cs, CS_ARCH_ARM64, CS_MODE_ARM
from keystone import Ks, KS_ARCH_ARM64, KS_MODE_ARM

from qiling import Qiling
from qiling.arch.arch import QlArch
from qiling.arch import arm64_const
from qiling.arch.models import ARM64_CPU_MODEL
from qiling.arch.register import QlRegisterManager
from qiling.const import QL_ARCH, QL_ENDIAN

Expand All @@ -19,9 +22,17 @@ class QlArchARM64(QlArch):
type = QL_ARCH.ARM64
bits = 64

def __init__(self, ql: Qiling, *, cputype: Optional[ARM64_CPU_MODEL] = None):
super().__init__(ql, cputype=cputype)

@cached_property
def uc(self) -> Uc:
return Uc(UC_ARCH_ARM64, UC_MODE_ARM)
obj = Uc(UC_ARCH_ARM64, UC_MODE_ARM)

if self.cpu is not None:
obj.ctl_set_cpu_model(self.cpu.value)

return obj

@cached_property
def regs(self) -> QlRegisterManager:
Expand Down
21 changes: 13 additions & 8 deletions qiling/arch/cortex_m.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from functools import cached_property
from contextlib import ContextDecorator
from typing import Optional

from unicorn import UC_ARCH_ARM, UC_MODE_ARM, UC_MODE_MCLASS, UC_MODE_THUMB
from capstone import Cs, CS_ARCH_ARM, CS_MODE_ARM, CS_MODE_MCLASS, CS_MODE_THUMB
Expand All @@ -13,6 +14,7 @@
from qiling import Qiling
from qiling.arch.arm import QlArchARM
from qiling.arch import cortex_m_const
from qiling.arch.models import ARM_CPU_MODEL
from qiling.arch.register import QlRegisterManager
from qiling.arch.cortex_m_const import IRQ, EXC_RETURN, CONTROL, EXCP
from qiling.const import QL_ARCH, QL_ENDIAN, QL_VERBOSE
Expand Down Expand Up @@ -66,12 +68,14 @@ class QlArchCORTEX_M(QlArchARM):
type = QL_ARCH.CORTEX_M
bits = 32

def __init__(self, ql: Qiling):
super().__init__(ql, endian=QL_ENDIAN.EL, thumb=True)
def __init__(self, ql: Qiling, *, cputype: Optional[ARM_CPU_MODEL] = None):
super().__init__(ql, cputype=cputype, endian=QL_ENDIAN.EL, thumb=True)

@cached_property
def uc(self):
return MultiTaskUnicorn(UC_ARCH_ARM, UC_MODE_ARM + UC_MODE_MCLASS + UC_MODE_THUMB, 10)
cpu = self.cpu and self.cpu.value

return MultiTaskUnicorn(UC_ARCH_ARM, UC_MODE_ARM + UC_MODE_MCLASS + UC_MODE_THUMB, cpu, 10)

@cached_property
def regs(self) -> QlRegisterManager:
Expand All @@ -97,18 +101,18 @@ def is_thumb(self) -> bool:
def endian(self) -> QL_ENDIAN:
return QL_ENDIAN.EL

def is_handler_mode(self):
def is_handler_mode(self) -> bool:
return self.regs.ipsr > 1

def using_psp(self):
def using_psp(self) -> bool:
return not self.is_handler_mode() and (self.regs.control & CONTROL.SPSEL) > 0

def init_context(self):
def init_context(self) -> None:
self.regs.lr = 0xffffffff
self.regs.msp = self.ql.mem.read_ptr(0x0)
self.regs.pc = self.ql.mem.read_ptr(0x4)

def unicorn_exception_handler(self, ql, intno):
def unicorn_exception_handler(self, ql: Qiling, intno: int):
forward_mapper = {
EXCP.UDEF : IRQ.HARD_FAULT, # undefined instruction
EXCP.SWI : IRQ.SVCALL, # software interrupt
Expand Down Expand Up @@ -139,8 +143,9 @@ def unicorn_exception_handler(self, ql, intno):
except IndexError:
raise QlErrorNotImplemented(f'Unhandled interrupt number ({intno})')

def interrupt_handler(self, ql, intno):
def interrupt_handler(self, ql: Qiling, intno: int):
basepri = self.regs.basepri & 0xf0

if basepri and basepri <= ql.hw.nvic.get_priority(intno):
return

Expand Down
18 changes: 16 additions & 2 deletions qiling/arch/evm/evm.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
#
#
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework


Expand All @@ -11,6 +11,7 @@
from qiling.arch.evm.vm.message import Message
from qiling.const import *


class QlArchEVM(QlArch):
type = QL_ARCH.EVM
bits = 1
Expand Down Expand Up @@ -39,7 +40,19 @@ def stack_write(self, offset, data):

@property
def uc(self):
return None
raise AttributeError

@property
def regs(self):
raise AttributeError

@property
def disassembler(self):
raise AttributeError

@property
def assembler(self):
raise AttributeError

@property
def endian(self) -> QL_ENDIAN:
Expand All @@ -49,6 +62,7 @@ def endian(self) -> QL_ENDIAN:
def __evm_run(self, code: Message):
return self.arch.run(code)


def monkeypatch_core_methods(ql):
"""Monkeypatch core methods for evm
"""
Expand Down
6 changes: 4 additions & 2 deletions qiling/arch/mips.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#

from functools import cached_property
from typing import Optional

from unicorn import Uc, UC_ARCH_MIPS, UC_MODE_MIPS32, UC_MODE_BIG_ENDIAN, UC_MODE_LITTLE_ENDIAN
from capstone import Cs, CS_ARCH_MIPS, CS_MODE_MIPS32, CS_MODE_BIG_ENDIAN, CS_MODE_LITTLE_ENDIAN
Expand All @@ -12,6 +13,7 @@
from qiling import Qiling
from qiling.arch.arch import QlArch
from qiling.arch import mips_const
from qiling.arch.models import MIPS_CPU_MODEL
from qiling.arch.register import QlRegisterManager
from qiling.const import QL_ARCH, QL_ENDIAN

Expand All @@ -20,8 +22,8 @@ class QlArchMIPS(QlArch):
type = QL_ARCH.MIPS
bits = 32

def __init__(self, ql: Qiling, endian: QL_ENDIAN):
super().__init__(ql)
def __init__(self, ql: Qiling, *, cputype: Optional[MIPS_CPU_MODEL], endian: QL_ENDIAN):
super().__init__(ql, cputype=cputype)

self._init_endian = endian

Expand Down
Loading