diff options
| -rw-r--r-- | sploit/__init__.py | 4 | ||||
| -rw-r--r-- | sploit/payload.py | 64 | 
2 files changed, 66 insertions, 2 deletions
diff --git a/sploit/__init__.py b/sploit/__init__.py index 5082cfa..7180910 100644 --- a/sploit/__init__.py +++ b/sploit/__init__.py @@ -1,2 +1,2 @@ -__all__ = ["log","comm","until","arch","mem"] -from sploit import log, comm, until, arch, mem +__all__ = ["log","comm","until","arch","mem","payload"] +from sploit import log, comm, until, arch, mem, payload 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: ')  | 
