summaryrefslogtreecommitdiffstats
path: root/sploit/symtbl.py
diff options
context:
space:
mode:
authorMalfurious <m@lfurio.us>2025-01-01 07:22:26 -0500
committerMalfurious <m@lfurio.us>2025-01-01 07:22:26 -0500
commit70c7c16a157f0e2056d0b96b96f6e13c83841bc3 (patch)
tree5f6d84642fc8b0aa89a32ef17f4b374605c7e089 /sploit/symtbl.py
parentf01ec45e773291c3659a1dcaf8cd9a51ece19823 (diff)
parent438c66673f7daca0fdc2d23b1a4fd39517528576 (diff)
downloadnsploit-70c7c16a157f0e2056d0b96b96f6e13c83841bc3.tar.gz
nsploit-70c7c16a157f0e2056d0b96b96f6e13c83841bc3.zip
Merge branch 'indextbl'
This branch is a major semantic redesign of Symtbl and Payload. These two classes are now implemented as derivitives of the newly refactored IndexTbl mechanism. Necessary cascading changes have been made to keep these tools in working order. * indextbl: payload: rop: Update for new Payload class Update ROP gadget types to extend IndexEntry payload: Refactor as a concrete IndexTbl lict: Add new list-dictionary hybrid type symtbl: Refactor abstract IndexTbl interface
Diffstat (limited to 'sploit/symtbl.py')
-rw-r--r--sploit/symtbl.py112
1 files changed, 44 insertions, 68 deletions
diff --git a/sploit/symtbl.py b/sploit/symtbl.py
index a471958..86800f5 100644
--- a/sploit/symtbl.py
+++ b/sploit/symtbl.py
@@ -73,112 +73,88 @@ with the Symtbl base address.
print(s.a, s.b, s.c, s.d) # "998 999 1000 1001"
"""
+from sploit.types.indextbl import IndexTbl
+from sploit.types.index_entry import IndexEntry
+
def Symtbl(*, base=0, **symbols):
"""
Create a new Symtbl object.
Return an empty Symtbl or, optionally, one initialized with the given
- symbol values. Arguments _must_ be keyword arguments.
+ symbol values. Arguments must be keyword arguments.
Users should call this function instead of attempting to construct the
Symtbl class. Construction is implemented via a normal function to prevent
any argument name from conflicting with __init__'s bound instance parameter.
"""
- self = SymtblImpl({}, 0, base)
+ self = SymtblImpl(base, 0, dict())
for k, v in symbols.items():
self[k] = v
return self
-class SymtblImpl:
+class SymtblImpl(IndexTbl):
"""Symtbl implementation class"""
- def __init__(self, entries, adjust, base):
+ def __init__(self, base, adjust, entries):
"""Construct Symtbl from instance data."""
+ super().__init__(base)
+ object.__setattr__(self, "__adjust__", adjust)
object.__setattr__(self, "__entries__", entries)
- object.__setattr__(self, "__adjust__", adjust)
- object.__setattr__(self, "base", base)
- def __index__(self):
- """Convert object to integer using base value."""
- return self.base
+ def __repr__(self):
+ """Return human-readable Symtbl."""
+ FMT = "\n{:<20} {:<20}"
+ s = f"{len(self)} symbols @ {hex(self)}"
- def __matmul__(self, base):
- """Create remapped version of object at absolute base."""
- return SymtblImpl(self.__entries__, self.__adjust__, int(base))
+ if len(self) > 0:
+ s += FMT.format("ADDRESS", "SYMBOL")
- def __add__(self, offset):
- """Create remapped version of object at relative base."""
- return self @ (self.base + offset)
+ for key, value in self:
+ key = f"[{key}]" if isinstance(value, IndexEntry) else key
+ s += FMT.format(hex(value), key)
- def __sub__(self, offset):
- """Create remapped version of object at relative base."""
- return self @ (self.base - offset)
+ return s
def __rshift__(self, offset):
- """Create symbol adjusted version of object."""
- return SymtblImpl(self.__entries__, self.__adjust__ + int(offset), self.base)
+ """Return symbol-adjusted version of object."""
+ adjust = self.__adjust__ + int(offset)
+ return SymtblImpl(self.base, adjust, self.__entries__)
def __lshift__(self, offset):
- """Create symbol adjusted version of object."""
+ """Return symbol-adjusted version of object."""
return self >> (-offset)
def __mod__(self, offset):
- """Create symbol rebased version of object."""
+ """Return symbol-rebased version of object."""
return self >> (self.base - offset)
- def __getattr__(self, symbol):
- """Return symbol offset or subtable via pseudo-attribute."""
- return self[symbol]
+ # IndexTbl abstract methods
- def __setattr__(self, symbol, value):
- """Set symbol offset or subtable via pseudo-attribute."""
- self[symbol] = value
+ def __copy__(self):
+ """Return copy of object with shared symbol entries."""
+ return SymtblImpl(self.base, self.__adjust__, self.__entries__)
- def __delattr__(self, symbol):
- """Unset symbol via pseudo-attribute."""
- del self[symbol]
+ def __iter__(self):
+ """Iterate over table items, sorted by offsets."""
+ it = { k: self[k] for k in self.__entries__}.items()
+ return iter(sorted(it, key=lambda x: int(x[1])))
def __len__(self):
"""Return number of defined symbols."""
return len(self.__entries__)
- def __getitem__(self, symbol):
- """Return symbol offset, subtable, or translated offset via subscript."""
- if symbol == "base":
- return self.base
- offset = self.__entries__[symbol] if type(symbol) is str else symbol
+ def __getindex__(self, index):
+ """Return symbol value or translated offset."""
+ if isinstance(index, (int, IndexEntry)): offset = index
+ else: offset = self.__entries__[index]
return offset + (self.base + self.__adjust__)
- def __setitem__(self, symbol, value):
- """Set symbol offset or subtable via subscript."""
- if symbol == "base":
- object.__setattr__(self, "base", int(value))
- elif symbol in dir(self):
- raise KeyError(f"Symtbl: key is reserved: {symbol}")
- elif type(symbol) is not str:
- raise TypeError(f"Symtbl: key must be a string: {symbol}")
- else:
- self.__entries__[symbol] = value - (self.base + self.__adjust__)
-
- def __delitem__(self, symbol):
- """Unset symbol via subscript."""
- del self.__entries__[symbol]
+ def __setindex__(self, index, value):
+ """Set symbol value."""
+ if isinstance(index, (int, IndexEntry)):
+ raise TypeError(f"Symtbl: Unsupported key type: {type(index)}")
+ self.__entries__[index] = value - (self.base + self.__adjust__)
- def __iter__(self):
- """Iterate over table entries as key:value tuples, like dict.items()."""
- return iter(sorted({ k: self[k] for k in self.__entries__ }.items(), key=lambda v: int(v[1])))
-
- def __contains__(self, symbol):
- """Test symbol name membership in table."""
- return symbol in self.__entries__
-
- def __repr__(self):
- """Return human-readable Symtbl."""
- FMT = "\n{:<20} {:<20}"
- s = f"{len(self)} symbols @ {hex(self)}"
- if len(self) > 0:
- s += FMT.format("ADDRESS", "SYMBOL")
- for symbol, offset in self:
- disp = f"[{symbol}]" if type(offset) is not int else symbol
- s += FMT.format(hex(offset), disp)
- return s
+ def __delindex__(self, index):
+ """Delete symbol."""
+ del self.__entries__[index]