diff --git a/scripts/running_analysis.py b/scripts/running_analysis.py index 33bd4774927c3377e0657c09bea3187a44c69f4c..ad21da3e0c2fd6c1d4e6fe697e8fb9f64cd53410 100755 --- a/scripts/running_analysis.py +++ b/scripts/running_analysis.py @@ -27,6 +27,7 @@ import sys # add top level directory to PYTHONPATH sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), '..')) +from librarytrader.library import Library from librarytrader.librarystore import LibraryStore from librarytrader.interface_calls import resolve_calls @@ -91,6 +92,9 @@ class Runner(): parser.add_argument('--loaderlike', action='store_true', help='Resolve functions only from executables ' \ 'while respecting weak symbols') + parser.add_argument('--store-unused-lists', action='store', + help='Stores lists of unused functions per library ' \ + 'in directory. Implicitely sets -r, -i and -a.') self.args = parser.parse_args() loglevel = logging.WARNING @@ -105,6 +109,13 @@ class Runner(): if not self.args.store: self.args.store = "" + if self.args.store_unused_lists: + self.args.resolve_functions = True + self.args.interface_calls = True + self.args.transitive_users = True + else: + self.args.store_unused_lists = "" + if not self.args.load and not self.args.paths: logging.error('Please load results and/or provide paths to analyze') parser.print_help() @@ -158,6 +169,9 @@ class Runner(): if self.args.uprobe_strings: self.store.generate_uprobe_strings('{}_uprobe_strings'.format(self.args.store)) + if self.args.store_unused_lists: + self.store_unused_lists() + def _create_export_user_mapping(self): result = {} libobjs = self.store.get_entry_points(self.args.all_entries) @@ -357,6 +371,29 @@ class Runner(): for key, _ in sorted(self.store.items()): print(key) + def store_unused_lists(self): + crucial_symbols = [ 'main', ] + for path, content in self.store.items(): + if isinstance(content, Library): + libpath = content.fullname + outpath = "{}/{}.unused".format(self.args.store_unused_lists, libpath) + outdirpath = os.path.dirname(outpath) + if not os.path.isdir(outdirpath): + os.makedirs(outdirpath) + with open(outpath, 'w') as outfile: + for exported_name in content.exported_names: + if "@@" in exported_name: + index = exported_name.index("@@") + out_exported_name = exported_name[:index] + else: + out_exported_name = exported_name + if out_exported_name in crucial_symbols: + continue + func = content.exported_names[exported_name] + users = content.export_users[func] + if len(users) == 0: + outfile.write('{}\n'.format(out_exported_name)) + if __name__ == '__main__': runner = Runner() runner.process()