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)
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 += 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 += f'\n{border}'
s += '\n'
s += str(self.libs)
return s
class __LIBS__(dict):
def __init__(self, libs):
super().__init__({lib.name:lib.path for lib in libs.values() if lib.path})
def __getitem__(self, lib):
get = super().__getitem__
if(type(get(lib))==str):self[lib] = ELF(get(lib))
return get(lib)
def __repr__(self):
s = ''
for name,lib in self.items():
s += '\n' + str(name) + ' => ' + (lib if(type(lib)==str) else str(lib.path))
return s.strip()
class __LOCALS__:
def __init__(self, elf):
self.elf = 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)]
def gadgets(self, *regexes, cont=False):
return r2.rop_gadgets(self.path, *regexes, cont=cont)
def gadget(self, *regexes):
return r2.rop_gadget(self.path, *regexes)