From 81f8130fa479fd827bc84354ee9a72b80c9cde02 Mon Sep 17 00:00:00 2001 From: Malfurious Date: Wed, 6 Jul 2022 23:30:49 -0400 Subject: sploit: mem: Allow Symtbl base to be modified Allow a Symtbl's base to be modified in-place, without mapping into a new object. This is useful when working with the Symtbl aspect of a Payload. This includes setting a non-zero base on construction. As usual, when defining base on construction, any additional kwargs symbols are interpreted relative to the given base. The order of arguments does not matter. Signed-off-by: Malfurious Signed-off-by: dusoleil --- tools/sploit/sploit/mem.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tools/sploit/sploit/mem.py b/tools/sploit/sploit/mem.py index 3fee92f..9ae0575 100644 --- a/tools/sploit/sploit/mem.py +++ b/tools/sploit/sploit/mem.py @@ -1,8 +1,8 @@ import types class Symtbl: - def __init__(self, **kwargs): - object.__setattr__(self, '_namesp', types.SimpleNamespace(base=0,sym={},sub={})) + def __init__(self, *, base=0, **kwargs): + object.__setattr__(self, '_namesp', types.SimpleNamespace(base=base,sym={},sub={})) for k, v in {**kwargs}.items(): setattr(self, k, v) @@ -15,11 +15,13 @@ class Symtbl: 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 + if ident == 'base': + self.base = value + else: + 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 -- cgit v1.2.3 From 1480e6ba39fdaacaf558dd099ccf1b87c9b92d6a Mon Sep 17 00:00:00 2001 From: Malfurious Date: Wed, 6 Jul 2022 23:42:57 -0400 Subject: sploit: Fix bugs involving Symtbl base value Some code previously assumed a Symtbl's base value to always be zero. This was often the case, however the assumption would break (for example) when attempting to rebase() a mapped Symtbl. As of the previous patch enabling freer modification of base, the potentiality of these bugs will be higher. Signed-off-by: Malfurious Signed-off-by: dusoleil --- tools/sploit/sploit/mem.py | 2 +- tools/sploit/sploit/payload.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/sploit/sploit/mem.py b/tools/sploit/sploit/mem.py index 9ae0575..3a3e697 100644 --- a/tools/sploit/sploit/mem.py +++ b/tools/sploit/sploit/mem.py @@ -36,7 +36,7 @@ class Symtbl: self.sym[k] = v + off def rebase(self, off): - self.adjust(-off) + self.adjust(self.base - off) def __str__(_self): FMT = '\n{:<20} {:<20}' diff --git a/tools/sploit/sploit/payload.py b/tools/sploit/sploit/payload.py index 9fab65e..a7721e0 100644 --- a/tools/sploit/sploit/payload.py +++ b/tools/sploit/sploit/payload.py @@ -28,13 +28,13 @@ class Payload(Symtbl): return f'{kind}_{ctr}' def __append(self, value, sym): - setattr(self, sym, len(self)) + setattr(self, sym, self.base + len(self)) self._namesp.payload += value return self def __prepend(self, value, sym): self.adjust(len(value)) - setattr(self, sym, 0) + setattr(self, sym, self.base) self._namesp.payload = value + self._namesp.payload return self -- cgit v1.2.3 From fe63ef169d3ce1e6e14842f716cdbc62b458e1f1 Mon Sep 17 00:00:00 2001 From: Malfurious Date: Thu, 7 Jul 2022 00:00:41 -0400 Subject: sploit: rev: Properly base Symtbls for non-PIC binaries The baddr property identified by r2 is now used as the base address for ELF symbol tables. This should not change the addresses retrieved via the table normally, however should fix the internal offsets of the table so that rebasing makes sense. Note that for PIC/PIE binaries we would already get a Symtbl with 'correct' offsets, as r2 is unable to absolutely resolve them for us. In these cases, the Symtbl base value remains at zero. Signed-off-by: Malfurious Signed-off-by: dusoleil --- tools/sploit/sploit/rev/r2.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/sploit/sploit/rev/r2.py b/tools/sploit/sploit/rev/r2.py index bb3edb3..6dfd499 100644 --- a/tools/sploit/sploit/rev/r2.py +++ b/tools/sploit/sploit/rev/r2.py @@ -13,6 +13,11 @@ def get_elf_symbols(elf): ilog(f'Retrieving symbols of {elf} with r2...') out = {} + cmd_base = 'iI~baddr' + base = run_cmd(elf,cmd_base) + base = re.split(r'\s+',base[0])[1] + base = int(base,0) + cmd_syms = 'is' out_syms = run_cmd(elf,cmd_syms) out_syms = [re.split(r'\s+',sym) for sym in out_syms][4:] @@ -39,7 +44,7 @@ def get_elf_symbols(elf): out_strs = {sym[2][sym[2].rfind('.')+1:]:int(sym[0],0) for sym in out_strs} out.update(out_strs) - return Symtbl(**out) + return Symtbl(base=base, **out) def get_locals(binary,func): ilog(f'Retrieving local stack frame of {hex(func)} in {binary} with r2...') -- cgit v1.2.3