summaryrefslogtreecommitdiffstats
path: root/sploit/payload/payload_entry.py
diff options
context:
space:
mode:
authorMalfurious <m@lfurio.us>2024-05-16 14:31:57 -0400
committerMalfurious <m@lfurio.us>2025-01-02 02:50:40 -0500
commit675aea7d480c72e3b60ad1a41ff97f4e8893621f (patch)
treec6f801f8c829f0331e7f5895f7d185849a968723 /sploit/payload/payload_entry.py
parent778c0ca5c319a4dd2b34eae62062846e572a2411 (diff)
downloadnsploit-675aea7d480c72e3b60ad1a41ff97f4e8893621f.tar.gz
nsploit-675aea7d480c72e3b60ad1a41ff97f4e8893621f.zip
payload: Separate length and bytes calculations
Previously, the len(payload) operation required the generation of the full payload binary content, in order to count how many bytes long it was. This is no longer the case, as there are opportunities for optimizations, primarily regarding fixed-length dynamic payload entries where we can simply grab the size parameter without having to generate a buffer. In addition to potential speedups, this fix also allows the user to insert PayloadEntry pointers for fields which are not yet present in the payload being built (ie: whenever the pointer is to exist before the pointed-to data). Whereas previously, the inability to generate the ill-formed pointer would break length calculations necessary to insert additional data. Signed-off-by: Malfurious <m@lfurio.us>
Diffstat (limited to 'sploit/payload/payload_entry.py')
-rw-r--r--sploit/payload/payload_entry.py45
1 files changed, 28 insertions, 17 deletions
diff --git a/sploit/payload/payload_entry.py b/sploit/payload/payload_entry.py
index 7088f83..4dca83d 100644
--- a/sploit/payload/payload_entry.py
+++ b/sploit/payload/payload_entry.py
@@ -20,15 +20,23 @@ class PayloadEntry(IndexEntry):
"""
pass
+ def payload_len(self, payload):
+ """
+ Called to compute size of this entry.
+
+ Implement this method to calculate the length of this dynamic payload
+ entry. self.base is set to the current entry address or offset.
+ """
+ raise NotImplementedError
+
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.
+ Implement this method to generate the binary output for this dynamic
+ payload entry. self.base is set to the current entry address or offset.
"""
- return b""
+ raise NotImplementedError
# Concrete payload entry definitions
@@ -43,6 +51,9 @@ class pointer(PayloadEntry):
self.target = self.base
self.target -= self.base
+ def payload_len(self, payload):
+ return arch.wordsize
+
def payload_bytes(self, payload):
return itob(self.target + self.base)
@@ -53,7 +64,11 @@ class padlen(PayloadEntry):
self.size = size
self.data = data
- def _gen_padding(self, size):
+ def payload_len(self, payload):
+ return self.size - (self.base - payload.base)
+
+ def payload_bytes(self, payload):
+ size = self.payload_len(payload)
data = self.data or arch.nopcode
if size < 0:
raise ValueError("padding: Available space is negative")
@@ -61,20 +76,17 @@ class padlen(PayloadEntry):
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)
+ def payload_len(self, payload):
+ return 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)
+ def payload_len(self, payload):
+ return self.size
class padalign(padlen):
"""Generate padding to reach next aligned address."""
@@ -83,9 +95,9 @@ class padalign(padlen):
self.size = size
self.data = data
- def payload_bytes(self, payload):
+ def payload_len(self, payload):
size = self.size or arch.alignment
- return self._gen_padding(-self.base % size)
+ return -self.base % size
class placeholder(padlen):
"""Generate fixed length of magic bytes, one word length by default."""
@@ -94,6 +106,5 @@ class placeholder(padlen):
self.size = size
self.data = _PLACEHOLDER_MAGIC
- def payload_bytes(self, payload):
- size = self.size or arch.wordsize
- return self._gen_padding(size)
+ def payload_len(self, payload):
+ return self.size or arch.wordsize