diff options
author | Malfurious <m@lfurio.us> | 2022-03-15 22:21:46 -0400 |
---|---|---|
committer | Malfurious <m@lfurio.us> | 2022-03-17 03:48:34 -0400 |
commit | 13748fdf493f3076411f689e30fcdf158ef1c860 (patch) | |
tree | 0aae7650cefb3a0ef386f6330d97b95a626fd808 | |
parent | 380bc782b53bdafc2b1d5d37afb16d6d7b91a0e5 (diff) | |
download | lib-des-gnux-13748fdf493f3076411f689e30fcdf158ef1c860.tar.gz lib-des-gnux-13748fdf493f3076411f689e30fcdf158ef1c860.zip |
sploit: Fix bugs and simplify Symtbl
The recent implementation of the new design for Symtbl contained a few
bugs:
- Attempting to access .base on a Symtbl or intermediate
__InnerTable__ caused an exception.
- Symtbl objects all used the same static collection of nested
subtables, rather than an instanced one. If two table objects
contained the same named key, they would refer to the same
nested table from both locations.
- Printing the contents of a table accessed via an absolute
nesting (aka: via an __InnerTable__ object) would not show the
offsets adjusted for the curent context.
In addition to these fixes, the class implementation is largely
simplified as well. This is in part due to the removal of unnecessary
logic, such as the way our __getattribute__ overloads were implemented.
Mainly, this came down to merging the redundant abstractions in our
original design.
Over time, the differences between these interfaces became blurred to
the point where simply reusing one is not at all problematic. It is
very much the intent of this patch to preserve the semantics of the
tool's design (that being: flexable, nestable tables, to which a
separate, but linked, mapped view may be obtained), but to state it as
cleanly as possible.
Note that all of the working state of a Symtbl is kept in its new
_namesp member. This is primarily done to enable subclassing the Symtbl
class. Ordinarily, setattr() on self would force the incoming value
into the actual symbol table, making it impossible for subclasses to
store separate instance data. Furthermore, the consolidation of
properties into this object creates fewer potential collisions with
user-defined symbols.
Signed-off-by: Malfurious <m@lfurio.us>
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
-rw-r--r-- | tools/sploit/sploit/mem.py | 127 |
1 files changed, 45 insertions, 82 deletions
diff --git a/tools/sploit/sploit/mem.py b/tools/sploit/sploit/mem.py index ac2bbb1..3fee92f 100644 --- a/tools/sploit/sploit/mem.py +++ b/tools/sploit/sploit/mem.py @@ -1,88 +1,51 @@ -from sploit.util import __attr_filter__ +import types class Symtbl: - __subs__ = {} def __init__(self, **kwargs): - self.__dict__ = {**kwargs} - - def subtable(self, sym, off, table): - setattr(self, sym, off) - self.__subs__[sym] = table - - class __InnerTable__: - def __init__(self,off,tbl): - self.off = off - self.tbl = tbl - def __getattribute__(self,sym): - if(sym in (['off','tbl'] + __attr_filter__)): - return object.__getattribute__(self,sym) - addr = getattr(self.tbl,sym) - if(type(addr)==int): - return addr + self.off - if(type(addr)==self.__class__): - addr.off += self.off - return addr - return addr - def __setattr__(self,sym,off): - if(sym in ['off','tbl']): - return object.__setattr__(self,sym,off) - return setattr(self.tbl,sym,off-self.off) - def __str__(self): - return str(self.tbl) - - def __getattribute__(self, sym): - addr = object.__getattribute__(self,sym) - if(sym in (['__subs__'] + __attr_filter__)): - return addr - if(sym == 'base'):return 0 - if(sym in self.__subs__): - return self.__InnerTable__(addr,self.__subs__[sym]) - return addr + object.__setattr__(self, '_namesp', types.SimpleNamespace(base=0,sym={},sub={})) + for k, v in {**kwargs}.items(): + setattr(self, k, v) + + def __getattr__(self, ident): + self = self._namesp + if ident == 'base': return self.base + off = self.base + self.sym[ident] + if ident in self.sub: return self.sub[ident].map(off) + return off + + def __setattr__(self, ident, value): + if ident in dir(self): raise Exception(f'Symtbl: assignment would shadow non-symbol "{ident}"') + if ident == 'base': raise Exception('Symtbl: may not redefine symbol "base"') + self = self._namesp + if type(value) is tuple: self.sub[ident], off = value + else: off = value + self.sym[ident] = off - self.base + + def map(self, addr, off=0): + self = self._namesp + mm = Symtbl() + mm._namesp.sym, mm._namesp.sub = self.sym, self.sub + mm._namesp.base = addr - off + return mm def adjust(self, off): - self.__dict__ = {k:v+off for k,v in self.__dict__.items()} - - def rebase(self, sym): - self.adjust(-sym) - - def __str__(self): - return __str__(self,self.__dict__) - -class Memmap: - def __init__(self, tbl, sym, addr): - self.__tbl__ = tbl - self.base = addr - sym - - def __getattribute__(self, sym): - if(sym in (['__tbl__','base'] + __attr_filter__)): - return object.__getattribute__(self, sym) - addr = getattr(self.__tbl__, sym) - if(type(addr)==Symtbl.__InnerTable__): - addr.off += self.base - return addr - return self.base + addr - - def __setattr__(self, sym, addr): - if(sym in ['__tbl__','base']): - return object.__setattr__(self,sym,addr) - return setattr(self.__tbl__,sym,addr-self.base) - - def __str__(self): - s = __str__(self,self.__tbl__.__dict__) - pos = -1 - for i in range(2): - pos = s.find('\n',pos+1) - s = s[:pos] + __tbl_format__.format(hex(self.base),'base') + s[pos:] + self = self._namesp + for k, v in self.sym.items(): + self.sym[k] = v + off + + def rebase(self, off): + self.adjust(-off) + + def __str__(_self): + FMT = '\n{:<20} {:<20}' + self = _self._namesp + + s = f'{len(self.sym)} symbols @ {hex(_self.base)}' + s += FMT.format('ADDRESS', 'SYMBOL') + for sym, _ in sorted(self.sym.items(), key=lambda x:x[1]): + addr = getattr(_self, sym) + if type(addr) is Symtbl: + s += FMT.format(hex(addr.base), f'[{sym}]') + else: + s += FMT.format(hex(addr), sym) return s - -__tbl_format__ = '\n{:<20} {:<20}' -def __str__(self,tbl): - s = 'symbols: ' + str(len(tbl)) - s += __tbl_format__.format('ADDRESS', 'SYMBOL') - for sym,off in sorted(tbl.items(),key=lambda x:x[1]): - addr = getattr(self,sym) - if(type(addr)==Symtbl.__InnerTable__): - s += __tbl_format__.format(hex(addr.off),f'[{sym}]') - else: - s += __tbl_format__.format(hex(addr),sym) - return s |