summaryrefslogtreecommitdiffstats
path: root/sploit/arch.py
blob: ac8ac14dd37e9d0d33e2c9936de1489be2a80f76 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
"""
Architecture-aware utilities and global architecture config

It is common within sploit and for users of sploit to need different behavior
depending on the architecture of the target.  This module encapsulates those
behaviors and bases them on a global architecture that is also configured here.

Users can set the global arch with arch.set() and all of the methods in this
module will honor it.  An architecture can be defined through the Arch dataclass
and there are also several predefined architecture constants that can be used.

arch (Arch): the architecture config that sploit will use whenever it needs to
know the architecture of the target

predefined architectures:
    x86
    x86_64
    ARM
    THUMB
"""

from dataclasses import dataclass

def btoi(b, signed=False):
    return int.from_bytes(b, arch.endianness, signed=signed)

def itob(i, signed=False):
    return i.to_bytes(arch.wordsize, arch.endianness, signed=signed)

@dataclass(frozen=True)
class Arch:
    """
    Dataclass of information about a target architecture

    wordsize (int): the width, in bytes, of the natural unit of data
    endianness (str): byte order. either "little" or "big"
    alignment (int): the multiple, in bytes, that return addresses must exist
    on the stack
    nopcode (bytes): the exact bytes of a "do nothing" instruction
    """

    wordsize: int
    endianness: str
    alignment: int
    nopcode: bytes

    def set(self,k):
        """Copy the given Arch into this instance."""
        self.__dict__.update(k.__dict__)

x86      = Arch( 4, 'little', 16, b'\x90')
x86_64   = Arch( 8, 'little', 16, b'\x90')
ARM      = Arch( 4, 'little',  8, b'\xe1\xa0\x00\x00')
THUMB    = Arch( 4, 'little',  8, b'\x46\xc0')

arch = Arch(**x86_64.__dict__)