Commit 23169cd9e830567a3c4c5e06b79ebd5dd8a1264d

Authored by Philippe Lagadec
1 parent c3aa06c8

olevba: improved display, shows container file

Showing 1 changed file with 20 additions and 9 deletions
oletools/olevba.py
... ... @@ -92,6 +92,7 @@ https://github.com/unixfreak0037/officeparser
92 92 # - option -z to scan files in password-protected zips
93 93 # 2015-01-02 v0.11 PL: - improved filter_vba to detect colons
94 94 # 2015-01-03 v0.12 PL: - fixed detect_patterns to detect all patterns
  95 +# - process_file: improved display, shows container file
95 96  
96 97 __version__ = '0.12'
97 98  
... ... @@ -136,6 +137,7 @@ import math
136 137 import zipfile
137 138 import re
138 139 import optparse
  140 +import os.path
139 141  
140 142 import thirdparty.olefile as olefile
141 143 from thirdparty.prettytable import prettytable
... ... @@ -1025,27 +1027,34 @@ class VBA_Parser(object):
1025 1027 self.ole_file.close()
1026 1028  
1027 1029  
1028   -def process_file (filename, data):
  1030 +def process_file (container, filename, data):
1029 1031 """
1030 1032 Process a single file
  1033 +
  1034 + :param container: str, path and filename of container if the file is within
  1035 + a zip archive, None otherwise.
  1036 + :param filename: str, path and filename of file on disk, or within the container.
  1037 + :param data: bytes, content of the file if it is in a container, None if it is a file on disk.
1031 1038 """
1032 1039 #TODO: replace print by writing to a provided output file (sys.stdout by default)
1033   - print ''
  1040 + if container:
  1041 + display_filename = '%s in %s' % (filename, container)
  1042 + else:
  1043 + display_filename = filename
1034 1044 print '='*79
1035   - print 'File:', filename
  1045 + print 'FILE:', display_filename
1036 1046 try:
1037 1047 #TODO: handle olefile errors, when an OLE file is malformed
1038 1048 vba = VBA_Parser(filename, data)
1039 1049 print 'Type:', vba.type
1040 1050 if vba.detect_vba_macros():
1041   - print 'Contains VBA Macros:'
  1051 + #print 'Contains VBA Macros:'
1042 1052 for (subfilename, stream_path, vba_filename, vba_code) in vba.extract_macros():
1043 1053 # hide attribute lines:
1044 1054 vba_code = filter_vba(vba_code)
1045 1055 print '-'*79
1046   - print 'Filename :', subfilename
1047   - print 'OLE stream :', stream_path
1048   - print 'VBA filename:', vba_filename
  1056 + print 'VBA MACRO %s ' % vba_filename
  1057 + print 'in file: %s - OLE stream: %s' % (subfilename, stream_path)
1049 1058 print '- '*39
1050 1059 # detect empty macros:
1051 1060 if vba_code.strip() == '':
... ... @@ -1053,6 +1062,7 @@ def process_file (filename, data):
1053 1062 else:
1054 1063 print vba_code
1055 1064 print '- '*39
  1065 + print 'ANALYSIS:'
1056 1066 autoexec_keywords = detect_autoexec(vba_code)
1057 1067 if autoexec_keywords:
1058 1068 print 'Auto-executable macro keywords found:'
... ... @@ -1099,6 +1109,7 @@ def process_file (filename, data):
1099 1109 except: #TypeError:
1100 1110 #raise
1101 1111 print sys.exc_value
  1112 + print ''
1102 1113  
1103 1114  
1104 1115 #=== MAIN =====================================================================
... ... @@ -1130,10 +1141,10 @@ def main():
1130 1141  
1131 1142 logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.WARNING) #INFO)
1132 1143  
1133   - for filename, data in xglob.iter_files(args, recursive=options.recursive,
  1144 + for container, filename, data in xglob.iter_files(args, recursive=options.recursive,
1134 1145 zip_password=options.zip_password, zip_fname=options.zip_fname):
1135 1146 #data = open(filespec, 'rb').read()
1136   - process_file(filename, data)
  1147 + process_file(container, filename, data)
1137 1148  
1138 1149 if __name__ == '__main__':
1139 1150 main()
... ...