def Extract(root, name): #olevba.process_file(None, sys.argv[1], None, show_decoded_strings=None) try: vba = olevba.VBA_Parser(os.path.join(root,name), None) if vba.detect_vba_macros(): try: extracted_macros = vba.extract_macros() except: return i = 0 for (subfilename, stream_path, vba_filename, vba_code) in extracted_macros: vba_code_filtered = olevba.filter_vba(vba_code) # detect empty macros if vba_code_filtered.strip() == '': #print '(empty macro)' continue else: try: fileaddr = os.path.join(root,name+"+"+vba_filename+".vb") resfile = open(fileaddr, "w") except IOError: fileaddr = os.path.join(root,name+"+"+str(i)+".vb") resfile = open(fileaddr, "w") i = i+1 resfile.write(vba_code_filtered) resfile.close() # else: # print 'No VBA macros found.' except: return
def main(): """ Main function, called when olevba is run from the command line """ global log DEFAULT_LOG_LEVEL = "warning" # Default log level LOG_LEVELS = { 'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARNING, 'error': logging.ERROR, 'critical': logging.CRITICAL } usage = 'usage: %prog [options] <filename> [filename2 ...]' parser = optparse.OptionParser(usage=usage) parser.add_option("-r", action="store_true", dest="recursive", help='find files recursively in subdirectories.') parser.add_option( "-z", "--zip", dest='zip_password', type='str', default=None, help= 'if the file is a zip archive, open all files from it, using the provided password (requires Python 2.6+)' ) parser.add_option( "-f", "--zipfname", dest='zip_fname', type='str', default='*', help= 'if the file is a zip archive, file(s) to be opened within the zip. Wildcards * and ? are supported. (default:*)' ) parser.add_option( '-l', '--loglevel', dest="loglevel", action="store", default=DEFAULT_LOG_LEVEL, help= "logging level debug/info/warning/error/critical (default=%default)") parser.add_option("-m", '--matches', action="store_true", dest="show_matches", help='Show matched strings.') # TODO: add logfile option (options, args) = parser.parse_args() # Print help if no arguments are passed if len(args) == 0: print __doc__ parser.print_help() print '\nAn exit code is returned based on the analysis result:' for result in (Result_NoMacro, Result_NotMSOffice, Result_MacroOK, Result_Error, Result_Suspicious): print ' - %d: %s' % (result.exit_code, result.name) sys.exit() # print banner with version print 'MacroRaptor %s - http://decalage.info/python/oletools' % __version__ print 'This is work in progress, please report issues at %s' % URL_ISSUES logging.basicConfig(level=LOG_LEVELS[options.loglevel], format='%(levelname)-8s %(message)s') # enable logging in the modules: log.setLevel(logging.NOTSET) t = tablestream.TableStream(style=tablestream.TableStyleSlim, header_row=['Result', 'Flags', 'Type', 'File'], column_width=[10, 5, 4, 56]) exitcode = -1 global_result = None # TODO: handle errors in xglob, to continue processing the next files for container, filename, data in xglob.iter_files( args, recursive=options.recursive, zip_password=options.zip_password, zip_fname=options.zip_fname): # ignore directory names stored in zip files: if container and filename.endswith('/'): continue full_name = '%s in %s' % (filename, container) if container else filename # try: # # Open the file # if data is None: # data = open(filename, 'rb').read() # except: # log.exception('Error when opening file %r' % full_name) # continue if isinstance(data, Exception): result = Result_Error t.write_row([result.name, '', '', full_name], colors=[result.color, None, None, None]) t.write_row(['', '', '', str(data)], colors=[None, None, None, result.color]) else: filetype = '???' try: vba_parser = olevba.VBA_Parser(filename=filename, data=data, container=container) filetype = TYPE2TAG[vba_parser.type] except Exception as e: # log.error('Error when parsing VBA macros from file %r' % full_name) # TODO: distinguish actual errors from non-MSOffice files result = Result_Error t.write_row([result.name, '', filetype, full_name], colors=[result.color, None, None, None]) t.write_row(['', '', '', str(e)], colors=[None, None, None, result.color]) continue if vba_parser.detect_vba_macros(): vba_code_all_modules = '' try: for (subfilename, stream_path, vba_filename, vba_code) in vba_parser.extract_all_macros(): vba_code_all_modules += vba_code + '\n' except Exception as e: # log.error('Error when parsing VBA macros from file %r' % full_name) result = Result_Error t.write_row([ result.name, '', TYPE2TAG[vba_parser.type], full_name ], colors=[result.color, None, None, None]) t.write_row(['', '', '', str(e)], colors=[None, None, None, result.color]) continue mraptor = MacroRaptor(vba_code_all_modules) mraptor.scan() if mraptor.suspicious: result = Result_Suspicious else: result = Result_MacroOK t.write_row( [result.name, mraptor.get_flags(), filetype, full_name], colors=[result.color, None, None, None]) if mraptor.matches and options.show_matches: t.write_row(['', '', '', 'Matches: %r' % mraptor.matches]) else: result = Result_NoMacro t.write_row([result.name, '', filetype, full_name], colors=[result.color, None, None, None]) if result.exit_code > exitcode: global_result = result exitcode = result.exit_code print '' print 'Flags: A=AutoExec, W=Write, X=Execute' print 'Exit code: %d - %s' % (exitcode, global_result.name) sys.exit(exitcode)