From d442ad2fae285470445ab5c84dacddf4adeb6e90 Mon Sep 17 00:00:00 2001
From: Andreas Ziegler <andreas.ziegler@fau.de>
Date: Fri, 4 Feb 2022 11:51:16 +0100
Subject: [PATCH] library, scripts: allow matching to global function via
 address as well

This change speeds up the marking process of additional functions
if the file was generated with the matching parse_collected_uprobes.py
version as only addresses have to be looked up (rather than doing
more expensive regular expression matches).
---
 librarytrader/library.py           |  5 ++++-
 scripts/parse_collected_uprobes.py |  5 ++---
 scripts/running_analysis.py        | 12 +++++++++++-
 3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/librarytrader/library.py b/librarytrader/library.py
index ff66a2a..065e287 100644
--- a/librarytrader/library.py
+++ b/librarytrader/library.py
@@ -1198,8 +1198,11 @@ class Library:
 
     def find_exports_by_pattern(self, requested_pattern):
         retval = set()
+        escaped_pattern = re.escape(requested_pattern)
         for name, addr in self.exported_names.items():
-            if re.fullmatch(re.escape(requested_pattern), name):
+            if re.fullmatch(escaped_pattern, name):
+                retval.add(addr)
+            elif re.fullmatch(escaped_pattern, name.split('@@')[0]):
                 retval.add(addr)
         return retval
 
diff --git a/scripts/parse_collected_uprobes.py b/scripts/parse_collected_uprobes.py
index d7d5c64..12112cc 100755
--- a/scripts/parse_collected_uprobes.py
+++ b/scripts/parse_collected_uprobes.py
@@ -82,8 +82,7 @@ with open(collectpath, 'r') as collectfd:
                     else:
                         traced_only_binaries += 1
 #                        parsed_mapping[lib.fullname].add('LOCAL_{}'.format(offset))
-                for name in lib.local_functions[offset]:
-                    parsed_mapping[lib.fullname].add('LOCAL_{}'.format(name))
+                parsed_mapping[lib.fullname].add('LOCAL_{}'.format(hex(offset)))
                 print('LOCAL_{}'.format(offset), 'name set: {}'.format(lib.local_functions[offset]))
             else:
                 print('no functions for {}:{}'.format(lib.fullname, hex(offset)))
@@ -100,7 +99,7 @@ with open(collectpath, 'r') as collectfd:
                 traced_only_libraries += 1
             else:
                 traced_only_binaries += 1
-        parsed_mapping[lib.fullname].add(fnames[0])
+        parsed_mapping[lib.fullname].add('GLOBAL_{}'.format(hex(offset)))
 
 n_export = 0
 n_local = 0
diff --git a/scripts/running_analysis.py b/scripts/running_analysis.py
index b45e100..19203b3 100755
--- a/scripts/running_analysis.py
+++ b/scripts/running_analysis.py
@@ -210,8 +210,18 @@ class Runner():
                         logging.debug('_mark_extra_functions: found match for '\
                                       'local function pattern \'%s\' at %s',
                                         function[6:], addrs)
+                elif function.startswith('GLOBAL_'):
+                    if function[7:].isdigit():
+                        addrs.add(int(function[7:]))
+                    elif function[7:].startswith('0x'):
+                        addrs.add(int(function[9:], base=16))
                 else:
-                    addrs.update(library.find_exports_by_pattern(function))
+                    export = library.find_exports_by_pattern(function)
+                    if export:
+                        logging.debug('_mark_extra_functions: found global '\
+                                      'addrs %s for %s', export, function)
+                    addrs.update(export)
+                    addrs.update(library.find_local_functions(function))
                 if not addrs:
                     logging.warning('mark_extra: %s not found in %s', function,
                                     library.fullname)
-- 
GitLab