Esempio n. 1
0
    def test_0_resolve_libs_with_symlinks(self):
        store = LibraryStore(ldconfig_file=LDCONFIG_FILE)

        store.resolve_libs_single_by_path(os.path.abspath(TEST_LIBC_LNK))

        # libc.so.6 -> libc-2.23.so, libc-2.23.so, /lib64/ld-linux-x86-64.so.2
        # from libc's .interp section and its target
        self.assertEqual(len(store.items()), 4)
        self.assertEqual(store.get_from_path(os.path.abspath(TEST_LIBC_LNK)),
                         store[os.path.abspath(TEST_LIBC)])
Esempio n. 2
0
def create_store_and_lib(libpath=TEST_LIBRARY,
                         parse=False,
                         resolve_libs_recursive=False,
                         call_resolve=False):
    store = LibraryStore(ldconfig_file=LDCONFIG_FILE)
    lib = Library(os.path.abspath(libpath), parse=parse)
    if resolve_libs_recursive:
        store.resolve_libs_recursive(lib)
    if call_resolve:
        resolve_calls(store)
    return store, lib
Esempio n. 3
0
    def test_6_propagate_calls_loaderlike(self):
        store = LibraryStore()
        bin1 = Library(os.path.abspath(TEST_LL))
        bin1a = Library(os.path.abspath(TEST_LL1A))
        bin2 = Library(os.path.abspath(TEST_LL2))

        # Save possibly set LD_LIBRARY_PATH
        backup = None
        if 'LD_LIBRARY_PATH' in os.environ:
            backup = os.environ['LD_LIBRARY_PATH']

        # Set LD_LIBRARY_PATH and resolve libraries
        os.environ['LD_LIBRARY_PATH'] = '$ORIGIN/'
        for binary in (bin1, bin1a, bin2):
            store.resolve_libs_recursive(binary)

        resolve_calls(store)
        store.resolve_all_functions_from_binaries()

        # Possibly restore LD_LIBRARY_PATH
        if backup:
            os.environ['LD_LIBRARY_PATH'] = backup
        else:
            del os.environ['LD_LIBRARY_PATH']

        lib1 = bin1.needed_libs['lib1.so']
        lib2 = store[lib1].needed_libs['lib2.so']
        # Check if the weak definition of 'wfunc' in 'lib2.so' is not used by
        # 'lib1.so' but overridden by the strong definition in 'bin'
        self.assertIn(lib1, store[bin1.fullname].get_users_by_name('wfunc'))
        self.assertNotIn(bin1.fullname, store[lib2].get_users_by_name('wfunc'))
        self.assertNotIn(lib1, store[lib2].get_users_by_name('wfunc'))
        # However, 'bin1a' and 'lib1a.so' should appear for 'wfunc' in 'lib2.so'
        # as bin1a does not override 'wfunc' itself
        lib1a = bin1a.needed_libs['lib1a.so']
        self.assertIn(bin1a.fullname, store[lib2].get_users_by_name('wfunc'))
        self.assertIn(lib1a, store[lib2].get_users_by_name('wfunc'))
        # Check that the weak definition in 'bin2' is only marked as external
        # but the use is actually overriden by the one in 'lib2.so'
        self.assertSetEqual(store[bin2.fullname].get_users_by_name('one_more'),
                            set(['TOPLEVEL']))
        # Check if the deepest transitively called functions has all binaries
        # as their user
        lib3 = store[lib2].needed_libs['lib3.so']
        for binary in (bin1, bin1a, bin2):
            self.assertIn(binary.fullname,
                          store[lib3].get_users_by_name('deeper'))
Esempio n. 4
0
    def test_6_propagate_calls_through_objects_32_bit(self):
        store = LibraryStore()

        os.environ['ALL_FUNCTIONS_FROM_OBJECTS'] = "1"

        for elf in (TEST_STRUCTS32, TEST_LIBSTRUCT32):
            store.resolve_libs_recursive_by_path(os.path.abspath(elf))

        resolve_calls(store)
        store.resolve_all_functions()
        store.propagate_call_usage()

        del os.environ['ALL_FUNCTIONS_FROM_OBJECTS']

        library = store.get_from_path(os.path.abspath(TEST_LIBSTRUCT32))
        self.assertIn(os.path.abspath(TEST_STRUCTS32),
                      store[library.fullname].get_users_by_name('helper'))
        self.assertIn(os.path.abspath(TEST_STRUCTS32),
                      store[library.fullname].get_users_by_name('from_obj'))
Esempio n. 5
0
    def __init__(self):
        self._parse_arguments()
        self.store = LibraryStore()
        self.paths = self._get_paths()

        for arg in [self.args.entry_list, self.args.used_functions]:
            if arg:
                entry_points = []
                with open(arg, 'r') as fdesc:
                    for line in fdesc:
                        # .split(':') is only required for used_functions but
                        # doesn't harm in entry_list as we need the first
                        # element anyway (which is the full match if ':' does
                        # not exist in the input line)
                        cur_lib = line.strip().split(':')[0]
                        if os.path.isfile(cur_lib):
                            entry_points.append(cur_lib)
                entry_points = list(sorted(set(entry_points)))
                self.store.set_additional_entry_points(entry_points)
                self.paths.extend(entry_points)

        self.all_resolved_functions = None
Esempio n. 6
0
    def test_7_store_load(self):
        store, binary = create_store_and_lib(TEST_BINARY,
                                             resolve_libs_recursive=True,
                                             call_resolve=True)
        lib = Library(os.path.abspath(TEST_LIBRARY))

        resolved_functions = store.resolve_all_functions(all_entries=True)
        store.propagate_call_usage(all_entries=True)

        # Create a temporary file, close it (we only need the path) and dump
        fd, name = tempfile.mkstemp()
        os.close(fd)
        store.dump(name)

        # Reload into an empty store
        new_store = LibraryStore(ldconfig_file=LDCONFIG_FILE)
        new_store.load(name)

        # The file is no longer needed, delete it
        os.remove(name)

        # Assert restoration of store
        self.assertEqual(store.keys(), new_store.keys())
        self.assertIn(lib.fullname, new_store.keys())
        self.assertIn(binary.fullname, new_store.keys())

        # Assert restoration of needed_libs
        self.assertIn(lib.fullname,
                      new_store[binary.fullname].needed_libs.values())

        lib = new_store[lib.fullname]
        # Assert restoration of calls
        self.assertIn(binary.fullname, lib.get_users_by_name('external'))
        self.assertIn(binary.fullname,
                      lib.get_users_by_name('external_caller'))
        self.assertIn(binary.fullname,
                      lib.get_users_by_name('second_level_caller'))
Esempio n. 7
0
    dref['total/local functions before'] = csv['local functions before'].sum()
    dref['total/local functions after'] = csv['local functions after'].sum()

    dref['total/exported functions before'] = csv['exported functions before'].sum()
    dref['total/exported functions after'] = csv['exported functions after'].sum()

    dref['total/functions before'] = csv['exported functions before'].sum() + csv['local functions before'].sum()
    dref['total/functions after'] = csv['exported functions after'].sum() + csv['local functions after'].sum()

    dref['total/number of libraries'] = len(csv)
else:
# The following are for the kernel CSV files
    dref['total/number of files original'] = csv['number of files original'].sum()
    dref['total/number of files tailored'] = csv['number of files tailored'].sum()
    dref['total/number of features original'] = csv['number of features original'].sum()
    dref['total/number of features tailored'] = csv['number of features tailored'].sum()

if store_path and mode == 'library':
    from librarytrader.librarystore import LibraryStore
    s = LibraryStore()
    s.load(store_path)
    non_libraries = 0
    for l in s.get_library_objects():
        if '.so' in l.fullname or os.path.basename(l.fullname).startswith('lib'):
            continue
        non_libraries += 1
    dref['total/number of binaries'] = non_libraries

dref.flush()
import collections
import matplotlib.pyplot as plt
import numpy
import pandas
import statistics
import sys

from librarytrader.librarystore import LibraryStore

#if len(sys.argv) >= 4:
print('Arguments: {} <librarystore> <output_filename> [cutoff_x]'.format(
    sys.argv[0]))
#    sys.exit(1)

print(' * Loading LibraryStore...')
store = LibraryStore()
store.load(sys.argv[1])
print('  * ... done!')

print(' * Collecting all non-zero ranges...')
all_ranges = [
    size for library in store.get_library_objects()
    for size in library.ranges.values() if size > 0
]
print('  * ... done!')

df = pandas.DataFrame(all_ranges, columns=["Function Size"])

if len(sys.argv) >= 4:
    max_x = int(sys.argv[3])
else:
Esempio n. 9
0
 def test_0_fail_on_elferror(self):
     store = LibraryStore(ldconfig_file=LDCONFIG_FILE)
     # Makefile isn't an ELF file, so we fail in store._get_or_create_library
     store.resolve_libs_single_by_path(
         os.path.abspath(FILE_PATH + 'Makefile'))
     self.assertEqual(len(store.items()), 0)