summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordusoleil <howcansocksbereal@gmail.com>2023-03-16 18:47:10 -0400
committerdusoleil <howcansocksbereal@gmail.com>2023-03-16 18:47:10 -0400
commitd0aee78d96aade08c8e6180a4b8f067c947cf20a (patch)
tree277d32b05d823ebde228654c361a113a782c133f
parent0bdf7d37fc2aa3cfc2fa02348f006996fa0bcce8 (diff)
downloadsploit-d0aee78d96aade08c8e6180a4b8f067c947cf20a.tar.gz
sploit-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.py63
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)]