Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
#!/usr/bin/env python
import unittest
import logging
import os
import sys
import subprocess
import tempfile
import shutil
import lief
from lief import Logger
Logger.set_level(lief.LOGGING_LEVEL.INFO)
from subprocess import Popen
from unittest import TestCase
from utils import get_compiler
BINADD_C = """\
#include
#include
int add(int a, int b);
int main(int argc, char **argv) {
if (argc != 3) {
printf("Usage: %s <a> <b>\\n", argv[0]);
exit(-1);</b></a>
print("'{}' has no manifest. Abort!".format(mfc.name))
sys.exit(1)
if not cmd_resources_manger.has_icons:
print("'{}' has no manifest. Abort!".format(mfc.name))
sys.exit(1)
mfc_icons = mfc_resources_manger.icons
cmd_icons = cmd_resources_manger.icons
for i in range(min(len(mfc_icons), len(cmd_icons))):
mfc_resources_manger.change_icon(mfc_icons[i], cmd_icons[i])
output = os.path.join(self.tmp_dir, "mfc_test_change_icon.exe")
builder = lief.PE.Builder(mfc)
builder.build_resources(True)
builder.build()
builder.write(output)
if sys.platform.startswith("win"):
subprocess_flags = 0x8000000 # win32con.CREATE_NO_WINDOW?
p = Popen(["START", output], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, creationflags=subprocess_flags)
time.sleep(3)
q = Popen(["taskkill", "/im", "mfc_test_change_icon.exe"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout, _ = p.communicate()
self.logger.debug(stdout.decode("utf8"))
stdout, _ = q.communicate()
self.logger.debug(stdout.decode("utf8"))
def test_change_note(self):
_, output = tempfile.mkstemp(prefix="change_note_")
etterlog = lief.parse(get_sample('ELF/ELF64_x86-64_binary_etterlog.bin'))
build_id = etterlog[lief.ELF.NOTE_TYPES.BUILD_ID]
new_desc = [i & 0xFF for i in range(500)]
build_id.description = new_desc
etterlog.write(output)
etterlog_updated = lief.parse(output)
self.assertEqual(etterlog[lief.ELF.NOTE_TYPES.BUILD_ID], etterlog_updated[lief.ELF.NOTE_TYPES.BUILD_ID])
self.safe_delete(output)
def test_pgo(self):
path = get_sample("PE/PE32_x86_binary_PGO-LTCG.exe")
sample = lief.parse(path)
debugs = sample.debug
self.assertEqual(len(debugs), 3)
debug_entry = debugs[2]
self.assertTrue(debug_entry.has_pogo)
pogo = debug_entry.pogo
self.assertEqual(pogo.signature, lief.PE.POGO_SIGNATURES.LCTG)
pogo_entries = pogo.entries
self.assertEqual(len(pogo_entries), 33)
self.assertEqual(pogo_entries[23].name, ".xdata$x")
self.assertEqual(pogo_entries[23].start_rva, 0x8200)
self.assertEqual(pogo_entries[23].size, 820)
with open(binaddc, 'w') as f:
f.write(BINADD)
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)
add_hidden_static = libadd.get_static_symbol("add_hidden")
libadd.add_exported_function(add_hidden_static.value, add_hidden_static.name)
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,
input=binaddc))
self.assertTrue(r, msg="Unable to compile binadd")
os.close(fd)
def test_exports_trie(self):
target = lief.parse(get_sample('MachO/MachO64_x86-64_binary_exports-trie-LLVM.bin'))
self.assertTrue(target.has_dyld_info)
exports = target.dyld_info.exports
self.assertEqual(len(exports), 6)
self.assertEqual(exports[0].address, 0)
self.assertEqual(exports[0].symbol.name, "_malloc")
self.assertEqual(exports[1].address, 0)
self.assertEqual(exports[1].symbol.name, "_myfree")
self.assertEqual(exports[2].address, 0xf70)
self.assertEqual(exports[2].symbol.name, "_myWeak")
self.assertEqual(exports[3].address, 0x1018)
self.assertEqual(exports[3].symbol.name, "_myTLV")
def test_change_libname(self):
sample = LibAddSample()
libadd = lief.parse(sample.libadd)
binadd = lief.parse(sample.binadd)
new_name = "libwhichhasalongverylongname.so"
self.assertIn(lief.ELF.DYNAMIC_TAGS.SONAME, libadd)
so_name = libadd[lief.ELF.DYNAMIC_TAGS.SONAME]
self.logger.debug("DT_SONAME: {}".format(so_name.name))
so_name.name = new_name
libfoo_path = os.path.join(sample.directory, new_name)
self.logger.debug(libfoo_path)
libadd.write(libfoo_path)
libfoo = lief.parse(libfoo_path)
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 setUp(self):
self.logger = logging.getLogger(__name__)
self.sectionless = lief.ELF.parse(get_sample('ELF/ELF64_x86-64_binary_rvs.bin'), lief.ELF.DYNSYM_COUNT_METHODS.HASH)
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)