diff --git a/oletools/olevba.py b/oletools/olevba.py index 13c74027..1c7acde0 100644 --- a/oletools/olevba.py +++ b/oletools/olevba.py @@ -1672,6 +1672,8 @@ def __init__(self, ole, vba_root, project_path, dir_path, relaxed=True): self.relaxed = relaxed #: VBA modules contained in the project (list of VBA_Module objects) self.modules = [] + # to store the VBA Project Tools->References details + self.references = [] #: file extension for each VBA module self.module_ext = {} log.debug('Parsing the dir stream from %r' % dir_path) @@ -1858,12 +1860,12 @@ def __init__(self, ole, vba_root, project_path, dir_path, relaxed=True): break if check == 0x0016: - # REFERENCENAME + REFERENCENAME = "REFERENCENAME" # Specifies the name of a referenced VBA project or Automation type library. reference_id = check reference_sizeof_name = struct.unpack("References Info from the VBA Project # list of tuples for each module: (subfilename, stream_path, vba_filename, vba_code) self.modules = None # Analysis results: list of tuples (type, keyword, description) - See VBA_Scanner @@ -2749,6 +2753,7 @@ def __init__(self, filename, data=None, container=None, relaxed=True, encoding=D self.xlm_macrosheet_found = False self.template_injection_found = False + # call ftguess to identify file type: self.ftg = ftguess.FileTypeGuesser(self.filename, data=data) log.debug('ftguess: file type=%s - container=%s' % (self.ftg.ftype.name, self.ftg.container)) @@ -3534,18 +3539,19 @@ def extract_macros(self): self.find_vba_projects() # set of stream ids vba_stream_ids = set() + references = [] for vba_root, project_path, dir_path in self.vba_projects: # extract all VBA macros from that VBA root storage: # The function _extract_vba may fail on some files (issue #132) # TODO: refactor this loop, because if one module fails it stops parsing, # and the error is only logged, not stored for reporting anomalies try: - for stream_path, vba_filename, vba_code in \ + for stream_path, vba_filename, vba_code, references in \ _extract_vba(self.ole_file, vba_root, project_path, dir_path, self.relaxed): # store direntry ids in a set: vba_stream_ids.add(self.ole_file._find(stream_path)) - yield (self.filename, stream_path, vba_filename, vba_code) + yield (self.filename, stream_path, vba_filename, vba_code, references) except Exception as e: log.exception('Error in _extract_vba') # Also look for VBA code in any stream including orphans @@ -3605,14 +3611,17 @@ def extract_all_macros(self): """ Extract and decompress source code for each VBA macro found in the file by calling extract_macros(), store the results as a list of tuples - (filename, stream_path, vba_filename, vba_code) in self.modules. + (filename, stream_path, vba_filename, vba_code) in self.modules and self.references. See extract_macros for details. :returns: list of tuples (filename, stream_path, vba_filename, vba_code) """ + if self.modules is None: self.modules = [] - for (subfilename, stream_path, vba_filename, vba_code) in self.extract_macros(): + self.references = [] + for (subfilename, stream_path, vba_filename, vba_code, references) in self.extract_macros(): self.modules.append((subfilename, stream_path, vba_filename, vba_code)) + self.references = references self.nb_macros = len(self.modules) return self.modules