diff options
author | Malfurious <m@lfurio.us> | 2025-01-01 06:51:10 -0500 |
---|---|---|
committer | Malfurious <m@lfurio.us> | 2025-01-01 06:51:10 -0500 |
commit | f01ec45e773291c3659a1dcaf8cd9a51ece19823 (patch) | |
tree | 0db3ef432a6f3b06c07060bdb0dd61c7fd164ad2 /sploit/payload/payload.py | |
parent | 3f5532857807d628a5dadaf5c30a384f873878ea (diff) | |
parent | 221742f7c5c89dc50ec4374bed5d2ccc0d7534bf (diff) | |
download | nsploit-f01ec45e773291c3659a1dcaf8cd9a51ece19823.tar.gz nsploit-f01ec45e773291c3659a1dcaf8cd9a51ece19823.zip |
Merge branch 'pkg-reorg'
This branch is a rework of nsploit's intended package imports. User
scripts need only import a given nsploit subpackage to obtain that
package's full collection of classes, functions, etc. This is the new
intended style for exploit scripts.
Along the way, some modules are reorganized into different packages, the
"builder" package is renamed to "payload", and some unnecessary files
are consolidated.
* pkg-reorg:
main: Automatically provide top-level sploit modules to user scripts
sploit: Expose modules' contents through package
Remove extra "main.py" file
comm: Promote from module to package
log: Move to sploit.util package
util: Promote from module to package
builder: Rename package to payload and expose contents
rev: Expose modules' contents through package
Remove outer __init__.py file
Diffstat (limited to 'sploit/payload/payload.py')
-rw-r--r-- | sploit/payload/payload.py | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/sploit/payload/payload.py b/sploit/payload/payload.py new file mode 100644 index 0000000..cf105c6 --- /dev/null +++ b/sploit/payload/payload.py @@ -0,0 +1,94 @@ +from sploit.arch import arch, itob +from sploit.symtbl import Symtbl + +class Payload: + MAGIC = b'\xef' + + def __init__(self, **kwargs): + self.payload = b'' + self.sym = Symtbl(**kwargs) + self.ctrs = {} + + def __len__(self): + return len(self.payload) + + def __call__(self, badbytes=b''): + found = [ hex(x) for x in set(self.payload).intersection(badbytes) ] + if len(found) > 0: + raise Exception(f'Payload: bad bytes in content: {found}') + return self.payload + + def _name(self, kind, sym): + if sym is not None: return sym + try: ctr = self.ctrs[kind] + except: ctr = 0 + self.ctrs[kind] = ctr + 1 + return f'{kind}_{ctr}' + + def _append(self, value, sym): + (self.sym @ 0)[sym] = len(self) + self.payload += value + return self + + def _prepend(self, value, sym): + self.sym >>= len(value) + (self.sym @ 0)[sym] = 0 + self.payload = value + self.payload + return self + + def end(self): + return self.sym.base + len(self) + + def bin(self, *values, sym=None): + return self._append(b''.join(values), sym=self._name('bin', sym)) + + def str(self, *values, sym=None): + values = [ v.encode() + b'\x00' for v in values ] + return self.bin(*values, sym=self._name('str', sym)) + + def int(self, *values, sym=None): + values = [ itob(v) for v in values ] + return self.bin(*values, sym=self._name('int', sym)) + + def int8(self, *values, sym=None): + values = [ itob(v, 1) for v in values ] + return self.bin(*values, sym=self._name('int', sym)) + + def int16(self, *values, sym=None): + values = [ itob(v, 2) for v in values ] + return self.bin(*values, sym=self._name('int', sym)) + + def int32(self, *values, sym=None): + values = [ itob(v, 4) for v in values ] + return self.bin(*values, sym=self._name('int', sym)) + + def int64(self, *values, sym=None): + values = [ itob(v, 8) for v in values ] + return self.bin(*values, sym=self._name('int', sym)) + + def ret(self, *values, sym=None): + return self.int(*values, sym=self._name('ret', sym)) + + def sbp(self, *values, sym=None): + if len(values) == 0: + return self.rep(self.MAGIC, arch.wordsize, sym=self._name('sbp', sym)) + return self.int(*values, sym=self._name('sbp', sym)) + + def rep(self, value, size, sym=None): + return self.bin(self._rep_helper(value, size), sym=self._name('rep', sym)) + + def pad(self, size, value=None, sym=None): + return self.bin(self._pad_helper(size, value), sym=self._name('pad', sym)) + + def pad_front(self, size, value=None, sym=None): + return self._prepend(self._pad_helper(size, value), sym=self._name('pad', sym)) + + def _rep_helper(self, value, size, *, explain=''): + if size < 0: + raise Exception(f'Payload: {explain}rep: available space is negative') + if (size := size / len(value)) != int(size): + raise Exception(f'Payload: {explain}rep: element does not divide the space evenly') + return value * int(size) + + def _pad_helper(self, size, value): + return self._rep_helper(value or arch.nopcode, size - len(self), explain='pad: ') |