diff options
| author | dusoleil <howcansocksbereal@gmail.com> | 2023-03-16 18:47:10 -0400 | 
|---|---|---|
| committer | dusoleil <howcansocksbereal@gmail.com> | 2023-03-16 18:47:10 -0400 | 
| commit | d0aee78d96aade08c8e6180a4b8f067c947cf20a (patch) | |
| tree | 277d32b05d823ebde228654c361a113a782c133f | |
| parent | 0bdf7d37fc2aa3cfc2fa02348f006996fa0bcce8 (diff) | |
| download | nsploit-d0aee78d96aade08c8e6180a4b8f067c947cf20a.tar.gz nsploit-d0aee78d96aade08c8e6180a4b8f067c947cf20a.zip | |
elf: Add bininfo to ELF under .info and .security
On ELF construction, call r2.get_bin_info() and keep the results under
the psuedo-namespaces .info and .security.  Also add a pretty-print to
these in a tabulated form.  Also rewrite the ELF pretty-print to just
summarize and not print out the entirety of .sym.  Lastly, fixed a small
bug where ELF could crash on construction if ldd fails (loading a
non-native ELF, for instance).
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
| -rw-r--r-- | sploit/rev/elf.py | 63 | 
1 files changed, 54 insertions, 9 deletions
| diff --git a/sploit/rev/elf.py b/sploit/rev/elf.py index d173897..e3c0a55 100644 --- a/sploit/rev/elf.py +++ b/sploit/rev/elf.py @@ -1,24 +1,35 @@  from sploit.rev import ldd, r2 +from itertools import zip_longest  class ELF:      def __init__(self, path):          self.path = path          self.sym = r2.get_elf_symbols(self.path) -        libs = ldd.get_libraries(self.path) +        try: +            libs = ldd.get_libraries(self.path) +        except: +            libs = {}          self.libs = self.__LIBS__(libs)          self.locals = self.__LOCALS__(self) +        bininfo = r2.get_bin_info(self.path) +        self.info = self.__BININFO__(bininfo) +        self.security = self.__SECINFO__(bininfo)      def __repr__(self):          s = 'ELF: '          s += self.path -        s += '\n------------' -        s += '\nSymbol Table' -        s += '\n------------' -        s += '\n' -        s += str(self.sym) -        s += '\n------------' +        s += f'\n{len(self.sym)} symbols @ {hex(self.sym)}' +        column_fmt = '\n{0:36}{1:36}' +        border = '------------' +        s += column_fmt.format(border,border) +        s += column_fmt.format('Binary Info','Security Info') +        s += column_fmt.format(border,border) +        for line in zip_longest(str(self.info).split('\n'),str(self.security).split('\n'),fillvalue=''): +            s += column_fmt.format(line[0],line[1]) +        s += f'\n{border}'          s += '\nLibraries' -        s += '\n------------' +        s += f'\n{border}' +        s += '\n'          s += str(self.libs)          return s @@ -33,7 +44,7 @@ class ELF:              s = ''              for name,lib in self.items():                  s += '\n' + str(name) + ' => ' + (lib if(type(lib)==str) else str(lib.path)) -            return s +            return s.strip()      class __LOCALS__:          def __init__(self, elf): @@ -41,6 +52,40 @@ class ELF:          def __getattr__(self, sym):              return r2.get_locals(self.elf.path, getattr(self.elf.sym, sym)) +    class __BININFO__: +        # Fancy magic class that provides a psuedo-namespace to get properties of the binary +        def __init__(self, bininfo): +            self.info = { +                    "type"          : bininfo.bintype, +                    "os"            : bininfo.os, +                    "baddr"         : int(bininfo.baddr,0), +                    "arch_string"   : bininfo.arch, +                    "wordsize"      : int(bininfo.bits)//8, +                    "endianness"    : bininfo.endian, +                } +        def __getattr__(self, k): +            return self.info[k] +        def __repr__(self): +            s = '' +            for name,val in self.info.items(): +                if name == 'baddr': val = hex(val) +                s += '\n{0:14}{1}'.format(name,val) +            return s.strip() + +    class __SECINFO__(__BININFO__): +        # Fancy magic class that provides a psuedo-namespace to get security properties of the binary +        def __init__(self, bininfo): +            bool = lambda s : s == 'true' or s == 'True' +            self.info = { +                    "stripped"      : bool(bininfo.stripped), +                    "pic"           : bool(bininfo.pic), +                    "relro"         : bininfo.relro, +                    "relocs"        : bool(bininfo.relocs), +                    "canary"        : bool(bininfo.canary), +                    "nx"            : bool(bininfo.nx), +                    "rpath"         : bininfo.rpath, +                } +      def retaddr(self, caller, callee):          return [c.ret_addr for c in r2.get_call_returns(self.path, caller, callee)] | 
