summaryrefslogtreecommitdiffstats
path: root/sploit/arch.py
diff options
context:
space:
mode:
Diffstat (limited to 'sploit/arch.py')
-rw-r--r--sploit/arch.py153
1 files changed, 0 insertions, 153 deletions
diff --git a/sploit/arch.py b/sploit/arch.py
deleted file mode 100644
index a9dea61..0000000
--- a/sploit/arch.py
+++ /dev/null
@@ -1,153 +0,0 @@
-"""
-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.
-These are accessible by name at module scope. (i.e. sploit.arch.x86_64)
-
-arch (Arch): the architecture config that sploit will use whenever it needs to
-know the architecture of the target
-
-DEFAULT_ARCH (Arch): the default architecture that arch is set to
-"""
-
-from dataclasses import dataclass
-
-def __define_architectures():
- # All predefined architectures should be listed here
- # These will also be added to the module's namespace
- __arch_list = {
- 'x86' : Arch('x86', 4, 'little', 16, 'ret', 'int 0x80', b'\x90', ['pop {}','ret'], [r'add esp, (\w+)','ret'], [r'mov dword \[(?P<dst>\w+)\], (?P<src>\w+)','ret'], [], ['eax','ebx','ecx','edx','esi','edi','ebp']),
- 'x86_64' : Arch('x86', 8, 'little', 16, 'ret', 'syscall', b'\x90', ['pop {}','ret'], [r'add rsp, (\w+)','ret'], [r'mov qword \[(?P<dst>\w+)\], (?P<src>\w+)','ret'], ['rdi','rsi','rdx','rcx','r8','r9'], ['rax','rdi','rsi','rdx','r10','r8','r9']),
- 'ARM' : Arch('arm', 4, 'little', 8, 'pop {pc}', 'svc 0', b'\xe1\xa0\x00\x00', ['pop {{{}, pc}}'], [r'add sp, sp, ([^r]\w*)','pop {pc}'], [r'str (?P<src>\w+), \[(?P<dst>\w+)\]','pop {pc}'], ['r0','r1','r2','r3'], ['r7','r0','r1','r2','r3','r4','r5']),
- 'THUMB' : Arch('arm', 4, 'little', 8, 'pop {pc}', 'svc 0', b'\x46\xc0', ['pop {{{}, pc}}'], [r'add sp, sp, ([^r]\w*)','pop {pc}'], [r'str (?P<src>\w+), \[(?P<dst>\w+)\]','pop {pc}'], ['r0','r1','r2','r3'], ['r7','r0','r1','r2','r3','r4','r5']),
- }
- globals().update(__arch_list)
- global __arch_lookup
- __arch_lookup = {(a.arch_string, a.wordsize, a.endianness) : a for a in reversed(__arch_list.values())}
-
-@dataclass(frozen=True)
-class Arch:
- """
- Dataclass of information about a target architecture
-
- arch_string (str): string returned by r2 iI in the arch field
- 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
- ret (str): mnemonic for a "return" instruction
- syscall (str): mnemonic for a "syscall" or "service call" instruction
- nopcode (bytes): the exact bytes of a "do nothing" instruction
- popgad (list[str]): ROP gadget template used to pop a value into a register
- cleangad (list[str]): ROP gadget template used to remove values from the
- stack
- writegad (list[str]): ROP gadget template used to write data to memory
- funcargs (list[str]): function argument registers used by the architecture
- calling convention
- kernargs (list[str]): kernel syscall argument registers
- """
-
- arch_string: str
- wordsize: int
- endianness: str
- alignment: int
- ret: str
- syscall: str
- nopcode: bytes
- popgad: list
- cleangad: list
- writegad: list
- funcargs: list
- kernargs: list
-
- def set(self,new_arch):
- """Copy the given Arch into this instance."""
- if type(new_arch) is not Arch:
- raise TypeError(f'arch: new_arch must be an Arch: {new_arch}')
- self.__dict__.update(new_arch.__dict__)
-__define_architectures()
-
-DEFAULT_ARCH = x86_64
-arch = Arch(**DEFAULT_ARCH.__dict__)
-
-def lookup_arch(arch_string, wordsize, endianness):
- """
- Return an Arch object with the matching search parameters.
-
- If a predefined Arch matches the specified fields, it will be returned.
- Otherwise, None is returned.
-
- arch_string (str): The "arch" string returned from r2 iI.
- wordsize (int): The natural width of an int in bytes.
- endianness (str): The order of bytes in an int (either "little" or "big")
- """
- return __arch_lookup.get((arch_string, wordsize, endianness))
-
-def sint(i):
- """Convert given int to signed int of arch.wordsize width."""
- return __int(i, True)
-
-def uint(i):
- """Convert given int to unsigned int of arch.wordsize width."""
- return __int(i, False)
-
-def int8(i):
- """Convert given int to signed 8 bit int."""
- return __int(i, True, 1)
-
-def int16(i):
- """Convert given int to signed 16 bit int."""
- return __int(i, True, 2)
-
-def int32(i):
- """Convert given int to signed 32 bit int."""
- return __int(i, True, 4)
-
-def int64(i):
- """Convert given int to signed 64 bit int."""
- return __int(i, True, 8)
-
-def uint8(i):
- """Convert given int to unsigned 8 bit int."""
- return __int(i, False, 1)
-
-def uint16(i):
- """Convert given int to unsigned 16 bit int."""
- return __int(i, False, 2)
-
-def uint32(i):
- """Convert given int to unsigned 32 bit int."""
- return __int(i, False, 4)
-
-def uint64(i):
- """Convert given int to unsigned 64 bit int."""
- return __int(i, False, 8)
-
-def btoi(b, byteorder=None):
- """Convert given byte array to an int."""
- byteorder = byteorder or arch.endianness
- return int.from_bytes(b, byteorder, signed=False)
-
-def itob(i, width=None, byteorder=None):
- """Convert given int to a byte array."""
- width = width or arch.wordsize
- byteorder = byteorder or arch.endianness
- return __int(i,False,width).to_bytes(width, byteorder, signed=False)
-
-def __int(i, signed=False, width=None):
- # type conversion from int to int of given sign and width
- i = int(i)
- width = width or arch.wordsize
- bits = 8 * width
- if signed:
- sign_bit = 1 << (bits - 1)
- return (i & (sign_bit - 1)) - (i & sign_bit)
- else:
- mask = (1 << bits) - 1
- return i & mask