diff options
Diffstat (limited to 'sploit/payload/payload_entry.py')
-rw-r--r-- | sploit/payload/payload_entry.py | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/sploit/payload/payload_entry.py b/sploit/payload/payload_entry.py new file mode 100644 index 0000000..7088f83 --- /dev/null +++ b/sploit/payload/payload_entry.py @@ -0,0 +1,99 @@ +from sploit.arch import arch, itob +from sploit.types.index_entry import IndexEntry + +_PLACEHOLDER_MAGIC = b"\xef" + +class PayloadEntry(IndexEntry): + """Base class for dynamic Payload entries""" + + def __repr__(self): + """Return human-readable entry description.""" + return f"{self.__class__.__name__}{self.__dict__}" + + def payload_insert(self, payload): + """ + Called on insert into a payload object. + + Override this method to perform any initialization which requires a + reference to the payload object. self.base is set to the insertion + location. + """ + pass + + def payload_bytes(self, payload): + """ + Called to generate bytes for this entry. + + Override this method to generate and return the binary output for this + dynamic payload entry. self.base is set to the current entry address + or offset. + """ + return b"" + +# Concrete payload entry definitions + +class pointer(PayloadEntry): + """Generate an integer which is always a fixed offset from self.base.""" + + def __init__(self, target=None): + self.target = target + + def payload_insert(self, payload): + if self.target is None: + self.target = self.base + self.target -= self.base + + def payload_bytes(self, payload): + return itob(self.target + self.base) + +class padlen(PayloadEntry): + """Generate padding to reach a target payload length.""" + + def __init__(self, size, data=None): + self.size = size + self.data = data + + def _gen_padding(self, size): + data = self.data or arch.nopcode + if size < 0: + raise ValueError("padding: Available space is negative") + if (size := size / len(data)) != int(size): + raise ValueError("padding: Element does not divide the space evenly") + return data * int(size) + + def payload_bytes(self, payload): + return self._gen_padding(self.size - (self.base - payload.base)) + +class padabs(padlen): + """Generate padding to reach a target absolute address.""" + + def payload_bytes(self, payload): + return self._gen_padding(self.size - self.base) + +class padrel(padlen): + """Generate a fixed length of padding (aka: length relative to self).""" + + def payload_bytes(self, payload): + return self._gen_padding(self.size) + +class padalign(padlen): + """Generate padding to reach next aligned address.""" + + def __init__(self, size=None, data=None): + self.size = size + self.data = data + + def payload_bytes(self, payload): + size = self.size or arch.alignment + return self._gen_padding(-self.base % size) + +class placeholder(padlen): + """Generate fixed length of magic bytes, one word length by default.""" + + def __init__(self, size=None): + self.size = size + self.data = _PLACEHOLDER_MAGIC + + def payload_bytes(self, payload): + size = self.size or arch.wordsize + return self._gen_padding(size) |