diff options
| -rw-r--r-- | sploit/__init__.py | 10 | ||||
| -rw-r--r-- | sploit/arch.py | 8 | ||||
| -rw-r--r-- | sploit/payload.py | 64 | 
3 files changed, 76 insertions, 6 deletions
diff --git a/sploit/__init__.py b/sploit/__init__.py index 5082cfa..9e637df 100644 --- a/sploit/__init__.py +++ b/sploit/__init__.py @@ -1,2 +1,8 @@ -__all__ = ["log","comm","until","arch","mem"] -from sploit import log, comm, until, arch, mem +from sploit import ( +        arch, +        comm, +        log, +        mem, +        payload, +        until, +) diff --git a/sploit/arch.py b/sploit/arch.py index d75bbda..ce88111 100644 --- a/sploit/arch.py +++ b/sploit/arch.py @@ -5,24 +5,24 @@ def itob(i, signed=False):      return i.to_bytes(arch.wordsize, arch.endianness, signed=signed)  class Arch: -    def __init__(self, wordsize, endianness, alignment, nop): +    def __init__(self, wordsize, endianness, alignment, nopcode):          self.wordsize = wordsize          self.endianness = endianness          self.alignment = alignment -        self.nop = nop +        self.nopcode = nopcode  archx86 = Arch(      wordsize = 4,      endianness = "little",      alignment = 16, -    nop = b'\x90' +    nopcode = b'\x90'  )  archx86_64 = Arch(      wordsize = 8,      endianness = "little",      alignment = 16, -    nop = b'\x90' +    nopcode = b'\x90'  )  arch = archx86_64 diff --git a/sploit/payload.py b/sploit/payload.py new file mode 100644 index 0000000..49e0c04 --- /dev/null +++ b/sploit/payload.py @@ -0,0 +1,64 @@ +from sploit.arch import arch, itob +from sploit.mem import Symtbl + +# Users can set this to the (absolute) address of a 'ret' ROP gadget.  Some +# features may require it. +RETGADGET : int = None + +class Placeholder(bytearray): +    def __init__(self, text='_unnamed_'): +        self += bytearray(itob(0)) +        self.text = text + +class Payload: +    def __init__(self, size=0, base=0, **kwargs): +        self.payload = b'' +        self.size = size +        self.alignstart = None +        self.tab = Symtbl(base=base, **kwargs) + +    def __len__(self): +        return len(self.payload) + +    def __getattr__(self, sym): +        return getattr(self.tab, sym) + +    def data(self, x, sym='_'): +        off = len(self) +        self.payload += x +        setattr(self.tab, sym, off) +        return getattr(self.tab, sym) + +    def value(self, x, sym='_', signed=False): +        return self.data(itob(x, signed=signed), sym=sym) + +    def ret(self, x, sym='_'): +        self.align() +        return self.value(x, sym=sym) + +    def stuff(self, x, size, sym='_', *, explain=''): +        if size >= 0: +            if (size := size / len(x)) == int(size): +                if size == 0 or not isinstance(x, Placeholder): +                    return self.data(x * int(size), sym=sym) + +                raise Exception(explain+"Can not stuff payload: " +                        f"Placeholder for {x.text} detected") +            raise Exception(explain+"Can not stuff payload: " +                    "Element does not divide the space evenly") +        raise Exception(explain+"Can not stuff payload: " +                "Available space is negative") + +    def pad(self, x=None, sym='_'): +        size = self.size - len(self) +        return self.stuff((x or arch.nopcode), size, sym=sym, +                explain='Error padding payload: ') + +    def align(self, x=None, sym='_'): +        if self.alignstart is None: +            self.alignstart = len(self) + +        retgad = (itob(RETGADGET) if RETGADGET else Placeholder('ret gadget')) +        size = (self.alignstart - len(self)) % arch.alignment +        return self.stuff((x or retgad), size, sym=sym, +                explain='Error aligning payload: ')  | 
