Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_simple(self):
sample_path = get_sample('ELF/ELF64_x86-64_binary_ls.bin')
output = os.path.join(self.tmp_dir, "ls.section")
ls = lief.parse(sample_path)
for i in range(10):
section = Section(".test.{:d}".format(i), lief.ELF.SECTION_TYPES.PROGBITS)
section += lief.ELF.SECTION_FLAGS.EXECINSTR
section += lief.ELF.SECTION_FLAGS.WRITE
section.content = STUB.segments[0].content # First LOAD segment which holds payload
if i % 2 == 0:
section = ls.add(section, loaded=True)
ls.header.entrypoint = section.virtual_address + STUB.header.entrypoint
else:
section = ls.add(section, loaded=False)
ls.write(output)
st = os.stat(output)
os.chmod(output, st.st_mode | stat.S_IEXEC)
p = Popen(output, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout, _ = p.communicate()
def test_io(self):
lspath = get_sample('ELF/ELF64_x86-64_binary_ls.bin')
ls = lief.parse(lspath)
self.assertIsNotNone(ls.abstract.header)
with io_open(lspath, 'r') as f:
ls = lief.parse(f)
self.assertIsNotNone(ls.abstract.header)
with io_open(lspath, 'rb') as f:
ls = lief.parse(f)
self.assertIsNotNone(ls.abstract.header)
with io_open(lspath, 'rb') as f:
ls = lief.ELF.parse(f)
self.assertIsNotNone(ls.abstract.header)
with io_open(get_sample('PE/PE64_x86-64_binary_HelloWorld.exe'), 'rb') as f:
binary = lief.PE.parse(f)
self.assertIsNotNone(binary.abstract.header)
with io_open(get_sample('MachO/MachO64_x86-64_binary_dd.bin'), 'rb') as f:
binary = lief.MachO.parse(f)[0]
self.assertIsNotNone(binary.abstract.header)
with open(lspath, 'rb') as f: # As bytes
ls = lief.parse(f.read())
self.assertIsNotNone(ls.abstract.header)
with open(lspath, 'rb') as f: # As io.BufferedReader
ls = lief.parse(f)
with open(libaddc, 'w') as f:
f.write(LIBADD)
compiler = get_compiler()
# Compile libadd
r = self.run_cmd("{compiler} -Wl,--export-dynamic -mcmodel=large -fPIE -pie -o {output} {input}".format(
compiler=compiler,
output=libadd,
input=libaddc))
self.assertTrue(r, msg="Unable to compile libadd")
libadd = lief.parse(libadd)
libadd_hidden = libadd.get_symbol("add_hidden")
libadd_hidden.binding = lief.ELF.SYMBOL_BINDINGS.GLOBAL
libadd_hidden.visibility = lief.ELF.SYMBOL_VISIBILITY.DEFAULT
libadd_hidden = libadd.add_dynamic_symbol(libadd_hidden, lief.ELF.SymbolVersion.global_)
self._logger.debug(libadd_hidden)
libadd.add(lief.ELF.DynamicSharedObject(os.path.basename(libadd2)))
libadd.write(libadd2)
lib_directory = os.path.dirname(libadd2)
libname = os.path.basename(libadd2)[3:-3] # libadd.so ---> add
r = self.run_cmd("{compiler} -Wl,--export-dynamic -mcmodel=large -fPIE -pie -Wl,-rpath={libdir} -L{libdir} -o {output} {input} -l{libadd2}".format(
compiler=compiler,
libdir=lib_directory,
libadd2=libname,
output=binadd,
def test_simple(self):
self.compile_libadd(self.libadd_path)
self.compile_binadd(self.binadd_path)
libadd = lief.parse(self.libadd_so)
for i in range(10):
segment = libadd.add(STUB.segments[0])
segment.alignment = 0x1000
new_ep = (STUB.header.entrypoint - STUB.segments[0].virtual_address) + segment.virtual_address
if libadd.has(lief.ELF.DYNAMIC_TAGS.INIT_ARRAY):
init_array = libadd.get(lief.ELF.DYNAMIC_TAGS.INIT_ARRAY)
callbacks = init_array.array
callbacks[0] = new_ep
init_array.array = callbacks
if libadd.has(lief.ELF.DYNAMIC_TAGS.INIT):
init = libadd.get(lief.ELF.DYNAMIC_TAGS.INIT)
init.value = new_ep
libadd.write(self.libadd_so)
st = os.stat(self.libadd_so)
os.chmod(self.libadd_so, st.st_mode | stat.S_IEXEC)
p = Popen([self.binadd_bin, '1', '2'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env={"LD_LIBRARY_PATH": self.tmp_dir})
stdout, _ = p.communicate()
def print_relocations(binary, relocations):
f_title = "|{:<10} | {:<10}| {:<8}| {:<8}| {:<8}| {:<15}| {:<30} |"
f_value = "|0x{:<8x} | {:<10}| {:<8d}| {:<8d}| {:<8x}| {:<15}| {:<30} |"
print(f_title.format("Address", "Type", "Info", "Size", "Addend", "Purpose", "Symbol"))
for relocation in relocations:
type = str(relocation.type)
if binary.header.machine_type == ELF.ARCH.x86_64:
type = str(ELF.RELOCATION_X86_64(relocation.type))
elif binary.header.machine_type == ELF.ARCH.i386:
type = str(ELF.RELOCATION_i386(relocation.type))
elif binary.header.machine_type == ELF.ARCH.ARM:
type = str(ELF.RELOCATION_ARM(relocation.type))
elif binary.header.machine_type == ELF.ARCH.AARCH64:
type = str(ELF.RELOCATION_AARCH64(relocation.type))
symbol_name = str(relocation.symbol.name) if relocation.has_symbol else ""
print(f_value.format(
relocation.address,
type.split(".")[-1],
relocation.info,
relocation.size,
relocation.addend,
str(relocation.purpose).split(".")[-1],
symbol_name))
def analyse():
if len(sys.argv) < 2:
print("[USAGE]: {0} ".format(sys.argv[0]))
sys.exit(1)
try:
binary = lief.ELF.parse(sys.argv[1])
except lief.bad_file as err:
print("Error: {0}".format(err))
sys.exit(1)
check_entrypoint(binary)
check_rwx_sections(binary)
check_ctors_array(binary)
check_got_and_plt(binary)
check_funcs_trampoline(binary, sys.argv[1])
check_dynamic_entries(binary)
def print_relocations(binary, relocations):
f_title = "|{:<10} | {:<10}| {:<8}| {:<8}| {:<8}| {:<15}| {:<30} |"
f_value = "|0x{:<8x} | {:<10}| {:<8d}| {:<8d}| {:<8x}| {:<15}| {:<30} |"
print(f_title.format("Address", "Type", "Info", "Size", "Addend", "Purpose", "Symbol"))
for relocation in relocations:
type = str(relocation.type)
if binary.header.machine_type == ELF.ARCH.x86_64:
type = str(ELF.RELOCATION_X86_64(relocation.type))
elif binary.header.machine_type == ELF.ARCH.i386:
type = str(ELF.RELOCATION_i386(relocation.type))
elif binary.header.machine_type == ELF.ARCH.ARM:
type = str(ELF.RELOCATION_ARM(relocation.type))
elif binary.header.machine_type == ELF.ARCH.AARCH64:
type = str(ELF.RELOCATION_AARCH64(relocation.type))
symbol_name = str(relocation.symbol.name) if relocation.has_symbol else ""
print(f_value.format(
relocation.address,
type.split(".")[-1],
relocation.info,
relocation.size,
relocation.addend,
str(relocation.purpose).split(".")[-1],
Display segments of ELF, Mach-O and OAT formats
"""
if not self.__check_session():
return
rows = []
if self.IS_OAT or self.IS_ELF:
for segment in self.lief.segments:
flags = []
if lief.ELF.SEGMENT_FLAGS.R in segment:
flags.append(self.liefConstToString(lief.ELF.SEGMENT_FLAGS.R))
if lief.ELF.SEGMENT_FLAGS.W in segment:
flags.append(self.liefConstToString(lief.ELF.SEGMENT_FLAGS.W))
if lief.ELF.SEGMENT_FLAGS.X in segment:
flags.append(self.liefConstToString(lief.ELF.SEGMENT_FLAGS.X))
if lief.ELF.SEGMENT_FLAGS.NONE in segment:
flags.append(self.liefConstToString(lief.ELF.SEGMENT_FLAGS.NONE))
rows.append([
self.liefConstToString(segment.type),
hex(segment.physical_address),
hex(segment.physical_size),
hex(segment.virtual_address),
hex(segment.virtual_size),
':'.join(flags),
self.getEntropy(bytes(segment.content))
])
self.log("info", "Segments : ")
self.log("table", dict(header=["Type", "PhysicalAddress", "FileSize", "VirtuAddr", "MemSize", "Flags", "Entropy"], rows=rows))
elif self.IS_MACHO:
self.log("info", "MachO segments : ")
for segment in self.lief.segments:
self.log("info", "Information of segment {0} : ".format(segment.name))
self.log("item", "{0:<18} : {1}".format("Name", segment.name)),
def deintercept(asan_dso, output_dso):
global arch
print("Patching", asan_dso)
lib = lief.parse(asan_dso)
names = []
for index, symbol in enumerate(lib.symbols):
if symbol.type == lief.ELF.SYMBOL_TYPES.FUNC and symbol.name.startswith("__interceptor_"):
names.append(lib.symbols[index].name[len("__interceptor_"):])
#names = ["malloc", "calloc", "realloc", "valloc", "pvalloc", "memalign", "posix_memalign", "free"]
for index, symbol in enumerate(lib.symbols):
if symbol.type == lief.ELF.SYMBOL_TYPES.FUNC and symbol.binding == lief.ELF.SYMBOL_BINDINGS.WEAK and symbol.name in names:
print("Renaming ", symbol)
lib.symbols[index].name = "__qasan_" + symbol.name
lib.write(output_dso)