From 98c491856cb4dcbbee2af41194aa22e1ce0515a3 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 --- sploit/mem.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/sploit/mem.py b/sploit/mem.py index 3fee92f..9ae0575 100644 --- a/sploit/mem.py +++ b/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 20dad07b1d9b666a0b86d11204e195af7be9d212 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 --- sploit/mem.py | 2 +- sploit/payload.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sploit/mem.py b/sploit/mem.py index 9ae0575..3a3e697 100644 --- a/sploit/mem.py +++ b/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/sploit/payload.py b/sploit/payload.py index 9fab65e..a7721e0 100644 --- a/sploit/payload.py +++ b/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 e2665bbeac88d55b78be6a97cb6c247ee57b8dbd 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 --- sploit/rev/r2.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sploit/rev/r2.py b/sploit/rev/r2.py index bb3edb3..6dfd499 100644 --- a/sploit/rev/r2.py +++ b/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