Commit 2b4c84f296ca28771f29fbfb777e21083dc6b4be
1 parent
8adff0e0
print compliant python3.5
Showing
1 changed file
with
47 additions
and
47 deletions
oletools/olevba.py
| ... | ... | @@ -239,9 +239,9 @@ except ImportError: |
| 239 | 239 | # Python <2.5: standalone ElementTree install |
| 240 | 240 | import elementtree.cElementTree as ET |
| 241 | 241 | except ImportError: |
| 242 | - raise ImportError, "lxml or ElementTree are not installed, " \ | |
| 242 | + raise(ImportError, "lxml or ElementTree are not installed, " \ | |
| 243 | 243 | + "see http://codespeak.net/lxml " \ |
| 244 | - + "or http://effbot.org/zone/element-index.htm" | |
| 244 | + + "or http://effbot.org/zone/element-index.htm") | |
| 245 | 245 | |
| 246 | 246 | import thirdparty.olefile as olefile |
| 247 | 247 | from thirdparty.prettytable import prettytable |
| ... | ... | @@ -1105,7 +1105,7 @@ def decompress_stream(compressed_container): |
| 1105 | 1105 | # copy tokens (reference to a previous literal token) |
| 1106 | 1106 | flag_byte = ord(compressed_container[compressed_current]) |
| 1107 | 1107 | compressed_current += 1 |
| 1108 | - for bit_index in xrange(0, 8): | |
| 1108 | + for bit_index in range(0, 8): | |
| 1109 | 1109 | # log.debug('bit_index=%d / compressed_current=%d / compressed_end=%d' % (bit_index, compressed_current, compressed_end)) |
| 1110 | 1110 | if compressed_current >= compressed_end: |
| 1111 | 1111 | break |
| ... | ... | @@ -1861,7 +1861,7 @@ def json2ascii(json_obj, encoding='utf8', errors='replace'): |
| 1861 | 1861 | log.debug('json2ascii: with: {0} (len {1})' |
| 1862 | 1862 | .format(dencoded, len(dencoded))) |
| 1863 | 1863 | return dencoded |
| 1864 | - elif isinstance(json_obj, unicode): | |
| 1864 | + elif isinstance(json_obj, str): | |
| 1865 | 1865 | log.debug('json2ascii: encode unicode: {0}' |
| 1866 | 1866 | .format(json_obj.encode(encoding, errors))) |
| 1867 | 1867 | # cannot put original into logger |
| ... | ... | @@ -1904,18 +1904,18 @@ def print_json(json_dict=None, _json_is_last=False, **json_parts): |
| 1904 | 1904 | json_dict = json_parts |
| 1905 | 1905 | |
| 1906 | 1906 | if not _have_printed_json_start: |
| 1907 | - print '[' | |
| 1907 | + print('[') | |
| 1908 | 1908 | _have_printed_json_start = True |
| 1909 | 1909 | |
| 1910 | 1910 | lines = json.dumps(json2ascii(json_dict), check_circular=False, |
| 1911 | 1911 | indent=4, ensure_ascii=False).splitlines() |
| 1912 | 1912 | for line in lines[:-1]: |
| 1913 | - print ' {0}'.format(line) | |
| 1913 | + print(' {0}'.format(line)) | |
| 1914 | 1914 | if _json_is_last: |
| 1915 | - print ' {0}'.format(lines[-1]) # print last line without comma | |
| 1916 | - print ']' | |
| 1915 | + print(' {0}'.format(lines[-1])) # print last line without comma | |
| 1916 | + print(']') | |
| 1917 | 1917 | else: |
| 1918 | - print ' {0},'.format(lines[-1]) # print last line with comma | |
| 1918 | + print(' {0},'.format(lines[-1])) # print last line with comma | |
| 1919 | 1919 | |
| 1920 | 1920 | |
| 1921 | 1921 | class VBA_Scanner(object): |
| ... | ... | @@ -2569,7 +2569,7 @@ class VBA_Parser(object): |
| 2569 | 2569 | # Also look for VBA code in any stream including orphans |
| 2570 | 2570 | # (happens in some malformed files) |
| 2571 | 2571 | ole = self.ole_file |
| 2572 | - for sid in xrange(len(ole.direntries)): | |
| 2572 | + for sid in range(len(ole.direntries)): | |
| 2573 | 2573 | # check if id is already done above: |
| 2574 | 2574 | log.debug('Checking DirEntry #%d' % sid) |
| 2575 | 2575 | d = ole.direntries[sid] |
| ... | ... | @@ -2635,7 +2635,7 @@ class VBA_Parser(object): |
| 2635 | 2635 | # Also look for VBA code in any stream including orphans |
| 2636 | 2636 | # (happens in some malformed files) |
| 2637 | 2637 | ole = self.ole_file |
| 2638 | - for sid in xrange(len(ole.direntries)): | |
| 2638 | + for sid in range(len(ole.direntries)): | |
| 2639 | 2639 | # check if id is already done above: |
| 2640 | 2640 | log.debug('Checking DirEntry #%d' % sid) |
| 2641 | 2641 | if sid in vba_stream_ids: |
| ... | ... | @@ -2870,7 +2870,7 @@ class VBA_Parser_CLI(VBA_Parser): |
| 2870 | 2870 | """ |
| 2871 | 2871 | # print a waiting message only if the output is not redirected to a file: |
| 2872 | 2872 | if sys.stdout.isatty(): |
| 2873 | - print 'Analysis...\r', | |
| 2873 | + print('Analysis...\r') | |
| 2874 | 2874 | sys.stdout.flush() |
| 2875 | 2875 | results = self.analyze_macros(show_decoded_strings, deobfuscate) |
| 2876 | 2876 | if results: |
| ... | ... | @@ -2886,9 +2886,9 @@ class VBA_Parser_CLI(VBA_Parser): |
| 2886 | 2886 | if not is_printable(description): |
| 2887 | 2887 | description = repr(description) |
| 2888 | 2888 | t.add_row((kw_type, keyword, description)) |
| 2889 | - print t | |
| 2889 | + print(t) | |
| 2890 | 2890 | else: |
| 2891 | - print 'No suspicious keyword or IOC found.' | |
| 2891 | + print('No suspicious keyword or IOC found.') | |
| 2892 | 2892 | |
| 2893 | 2893 | def print_analysis_json(self, show_decoded_strings=False, deobfuscate=False): |
| 2894 | 2894 | """ |
| ... | ... | @@ -2902,7 +2902,7 @@ class VBA_Parser_CLI(VBA_Parser): |
| 2902 | 2902 | """ |
| 2903 | 2903 | # print a waiting message only if the output is not redirected to a file: |
| 2904 | 2904 | if sys.stdout.isatty(): |
| 2905 | - print 'Analysis...\r', | |
| 2905 | + print('Analysis...%s\r') | |
| 2906 | 2906 | sys.stdout.flush() |
| 2907 | 2907 | return [dict(type=kw_type, keyword=keyword, description=description) |
| 2908 | 2908 | for kw_type, keyword, description in self.analyze_macros(show_decoded_strings, deobfuscate)] |
| ... | ... | @@ -2931,11 +2931,11 @@ class VBA_Parser_CLI(VBA_Parser): |
| 2931 | 2931 | display_filename = '%s in %s' % (self.filename, self.container) |
| 2932 | 2932 | else: |
| 2933 | 2933 | display_filename = self.filename |
| 2934 | - print '=' * 79 | |
| 2935 | - print 'FILE:', display_filename | |
| 2934 | + print('=' * 79) | |
| 2935 | + print('FILE:', display_filename) | |
| 2936 | 2936 | try: |
| 2937 | 2937 | #TODO: handle olefile errors, when an OLE file is malformed |
| 2938 | - print 'Type:', self.type | |
| 2938 | + print('Type: %s', self.type) | |
| 2939 | 2939 | if self.detect_vba_macros(): |
| 2940 | 2940 | #print 'Contains VBA Macros:' |
| 2941 | 2941 | for (subfilename, stream_path, vba_filename, vba_code) in self.extract_all_macros(): |
| ... | ... | @@ -2944,29 +2944,29 @@ class VBA_Parser_CLI(VBA_Parser): |
| 2944 | 2944 | vba_code_filtered = filter_vba(vba_code) |
| 2945 | 2945 | else: |
| 2946 | 2946 | vba_code_filtered = vba_code |
| 2947 | - print '-' * 79 | |
| 2948 | - print 'VBA MACRO %s ' % vba_filename | |
| 2949 | - print 'in file: %s - OLE stream: %s' % (subfilename, repr(stream_path)) | |
| 2947 | + print('-' * 79) | |
| 2948 | + print('VBA MACRO %s ' % vba_filename) | |
| 2949 | + print('in file: %s - OLE stream: %s' % (subfilename, repr(stream_path))) | |
| 2950 | 2950 | if display_code: |
| 2951 | - print '- ' * 39 | |
| 2951 | + print('- ' * 39) | |
| 2952 | 2952 | # detect empty macros: |
| 2953 | 2953 | if vba_code_filtered.strip() == '': |
| 2954 | - print '(empty macro)' | |
| 2954 | + print('(empty macro)') | |
| 2955 | 2955 | else: |
| 2956 | - print vba_code_filtered | |
| 2956 | + print(vba_code_filtered) | |
| 2957 | 2957 | for (subfilename, stream_path, form_string) in self.extract_form_strings(): |
| 2958 | - print '-' * 79 | |
| 2959 | - print 'VBA FORM STRING IN %r - OLE stream: %r' % (subfilename, stream_path) | |
| 2960 | - print '- ' * 39 | |
| 2961 | - print form_string | |
| 2958 | + print('-' * 79) | |
| 2959 | + print('VBA FORM STRING IN %r - OLE stream: %r' % (subfilename, stream_path)) | |
| 2960 | + print('- ' * 39) | |
| 2961 | + print(form_string) | |
| 2962 | 2962 | if not vba_code_only: |
| 2963 | 2963 | # analyse the code from all modules at once: |
| 2964 | 2964 | self.print_analysis(show_decoded_strings, deobfuscate) |
| 2965 | 2965 | if show_deobfuscated_code: |
| 2966 | - print 'MACRO SOURCE CODE WITH DEOBFUSCATED VBA STRINGS (EXPERIMENTAL):\n\n' | |
| 2967 | - print self.reveal() | |
| 2966 | + print('MACRO SOURCE CODE WITH DEOBFUSCATED VBA STRINGS (EXPERIMENTAL):\n\n') | |
| 2967 | + print(self.reveal()) | |
| 2968 | 2968 | else: |
| 2969 | - print 'No VBA macros found.' | |
| 2969 | + print('No VBA macros found.') | |
| 2970 | 2970 | except OlevbaBaseException: |
| 2971 | 2971 | raise |
| 2972 | 2972 | except Exception as exc: |
| ... | ... | @@ -2974,7 +2974,7 @@ class VBA_Parser_CLI(VBA_Parser): |
| 2974 | 2974 | log.info('Error processing file %s (%s)' % (self.filename, exc)) |
| 2975 | 2975 | log.debug('Traceback:', exc_info=True) |
| 2976 | 2976 | raise ProcessingError(self.filename, exc) |
| 2977 | - print '' | |
| 2977 | + print('') | |
| 2978 | 2978 | |
| 2979 | 2979 | |
| 2980 | 2980 | def process_file_json(self, show_decoded_strings=False, |
| ... | ... | @@ -3060,7 +3060,7 @@ class VBA_Parser_CLI(VBA_Parser): |
| 3060 | 3060 | if self.detect_vba_macros(): |
| 3061 | 3061 | # print a waiting message only if the output is not redirected to a file: |
| 3062 | 3062 | if sys.stdout.isatty(): |
| 3063 | - print 'Analysis...\r', | |
| 3063 | + print('Analysis...\r') | |
| 3064 | 3064 | sys.stdout.flush() |
| 3065 | 3065 | self.analyze_macros(show_decoded_strings=show_decoded_strings, |
| 3066 | 3066 | deobfuscate=deobfuscate) |
| ... | ... | @@ -3078,7 +3078,7 @@ class VBA_Parser_CLI(VBA_Parser): |
| 3078 | 3078 | base64obf, dridex, vba_obf) |
| 3079 | 3079 | |
| 3080 | 3080 | line = '%-12s %s' % (flags, self.filename) |
| 3081 | - print line | |
| 3081 | + print(line) | |
| 3082 | 3082 | |
| 3083 | 3083 | # old table display: |
| 3084 | 3084 | # macros = autoexec = suspicious = iocs = hexstrings = 'no' |
| ... | ... | @@ -3171,7 +3171,7 @@ def main(): |
| 3171 | 3171 | |
| 3172 | 3172 | # Print help if no arguments are passed |
| 3173 | 3173 | if len(args) == 0: |
| 3174 | - print __doc__ | |
| 3174 | + print(__doc__) | |
| 3175 | 3175 | parser.print_help() |
| 3176 | 3176 | sys.exit(RETURN_WRONG_ARGS) |
| 3177 | 3177 | |
| ... | ... | @@ -3182,7 +3182,7 @@ def main(): |
| 3182 | 3182 | url='http://decalage.info/python/oletools', |
| 3183 | 3183 | type='MetaInformation') |
| 3184 | 3184 | else: |
| 3185 | - print 'olevba %s - http://decalage.info/python/oletools' % __version__ | |
| 3185 | + print('olevba %s - http://decalage.info/python/oletools' % __version__) | |
| 3186 | 3186 | |
| 3187 | 3187 | logging.basicConfig(level=LOG_LEVELS[options.loglevel], format='%(levelname)-8s %(message)s') |
| 3188 | 3188 | # enable logging in the modules: |
| ... | ... | @@ -3202,8 +3202,8 @@ def main(): |
| 3202 | 3202 | # Column headers (do not know how many files there will be yet, so if no output_mode |
| 3203 | 3203 | # was specified, we will print triage for first file --> need these headers) |
| 3204 | 3204 | if options.output_mode in ('triage', 'unspecified'): |
| 3205 | - print '%-12s %-65s' % ('Flags', 'Filename') | |
| 3206 | - print '%-12s %-65s' % ('-' * 11, '-' * 65) | |
| 3205 | + print('%-12s %-65s' % ('Flags', 'Filename')) | |
| 3206 | + print('%-12s %-65s' % ('-' * 11, '-' * 65)) | |
| 3207 | 3207 | |
| 3208 | 3208 | previous_container = None |
| 3209 | 3209 | count = 0 |
| ... | ... | @@ -3221,14 +3221,14 @@ def main(): |
| 3221 | 3221 | if isinstance(data, Exception): |
| 3222 | 3222 | if isinstance(data, PathNotFoundException): |
| 3223 | 3223 | if options.output_mode in ('triage', 'unspecified'): |
| 3224 | - print '%-12s %s - File not found' % ('?', filename) | |
| 3224 | + print('%-12s %s - File not found' % ('?', filename)) | |
| 3225 | 3225 | elif options.output_mode != 'json': |
| 3226 | 3226 | log.error('Given path %r does not exist!' % filename) |
| 3227 | 3227 | return_code = RETURN_FILE_NOT_FOUND if return_code == 0 \ |
| 3228 | 3228 | else RETURN_SEVERAL_ERRS |
| 3229 | 3229 | else: |
| 3230 | 3230 | if options.output_mode in ('triage', 'unspecified'): |
| 3231 | - print '%-12s %s - Failed to read from zip file %s' % ('?', filename, container) | |
| 3231 | + print('%-12s %s - Failed to read from zip file %s' % ('?', filename, container)) | |
| 3232 | 3232 | elif options.output_mode != 'json': |
| 3233 | 3233 | log.error('Exception opening/reading %r from zip file %r: %s' |
| 3234 | 3234 | % (filename, container, data)) |
| ... | ... | @@ -3255,7 +3255,7 @@ def main(): |
| 3255 | 3255 | # print container name when it changes: |
| 3256 | 3256 | if container != previous_container: |
| 3257 | 3257 | if container is not None: |
| 3258 | - print '\nFiles in %s:' % container | |
| 3258 | + print('\nFiles in %s:' % container) | |
| 3259 | 3259 | previous_container = container |
| 3260 | 3260 | # summarized output for triage: |
| 3261 | 3261 | vba_parser.process_file_triage(show_decoded_strings=options.show_decoded_strings, |
| ... | ... | @@ -3273,8 +3273,8 @@ def main(): |
| 3273 | 3273 | |
| 3274 | 3274 | except (SubstreamOpenError, UnexpectedDataError) as exc: |
| 3275 | 3275 | if options.output_mode in ('triage', 'unspecified'): |
| 3276 | - print '%-12s %s - Error opening substream or uenxpected ' \ | |
| 3277 | - 'content' % ('?', filename) | |
| 3276 | + print('%-12s %s - Error opening substream or uenxpected ' \ | |
| 3277 | + 'content' % ('?', filename)) | |
| 3278 | 3278 | elif options.output_mode == 'json': |
| 3279 | 3279 | print_json(file=filename, type='error', |
| 3280 | 3280 | error=type(exc).__name__, message=str(exc)) |
| ... | ... | @@ -3285,7 +3285,7 @@ def main(): |
| 3285 | 3285 | else RETURN_SEVERAL_ERRS |
| 3286 | 3286 | except FileOpenError as exc: |
| 3287 | 3287 | if options.output_mode in ('triage', 'unspecified'): |
| 3288 | - print '%-12s %s - File format not supported' % ('?', filename) | |
| 3288 | + print('%-12s %s - File format not supported' % ('?', filename)) | |
| 3289 | 3289 | elif options.output_mode == 'json': |
| 3290 | 3290 | print_json(file=filename, type='error', |
| 3291 | 3291 | error=type(exc).__name__, message=str(exc)) |
| ... | ... | @@ -3295,7 +3295,7 @@ def main(): |
| 3295 | 3295 | else RETURN_SEVERAL_ERRS |
| 3296 | 3296 | except ProcessingError as exc: |
| 3297 | 3297 | if options.output_mode in ('triage', 'unspecified'): |
| 3298 | - print '%-12s %s - %s' % ('!ERROR', filename, exc.orig_exc) | |
| 3298 | + print('%-12s %s - %s' % ('!ERROR', filename, exc.orig_exc)) | |
| 3299 | 3299 | elif options.output_mode == 'json': |
| 3300 | 3300 | print_json(file=filename, type='error', |
| 3301 | 3301 | error=type(exc).__name__, |
| ... | ... | @@ -3310,9 +3310,9 @@ def main(): |
| 3310 | 3310 | vba_parser.close() |
| 3311 | 3311 | |
| 3312 | 3312 | if options.output_mode == 'triage': |
| 3313 | - print '\n(Flags: OpX=OpenXML, XML=Word2003XML, MHT=MHTML, TXT=Text, M=Macros, ' \ | |
| 3313 | + print('\n(Flags: OpX=OpenXML, XML=Word2003XML, MHT=MHTML, TXT=Text, M=Macros, ' \ | |
| 3314 | 3314 | 'A=Auto-executable, S=Suspicious keywords, I=IOCs, H=Hex strings, ' \ |
| 3315 | - 'B=Base64 strings, D=Dridex strings, V=VBA strings, ?=Unknown)\n' | |
| 3315 | + 'B=Base64 strings, D=Dridex strings, V=VBA strings, ?=Unknown)\n') | |
| 3316 | 3316 | |
| 3317 | 3317 | if count == 1 and options.output_mode == 'unspecified': |
| 3318 | 3318 | # if options -t, -d and -j were not specified and it's a single file, print details: | ... | ... |