Commit 7b3697b3c5795794bd016fde463aae9ec46db3fc

Authored by decalage2
1 parent 1892bb00

olevba: added option --pcode to disassemble and display the VBA P-Code using pcodedmp

oletools/olevba.py
... ... @@ -216,8 +216,9 @@ from __future__ import print_function
216 216 # 2019-03-18 PL: - added XLM/XLF macros detection for Excel OLE files
217 217 # 2019-03-25 CH: - added decryption of password-protected files
218 218 # 2019-04-09 PL: - decompress_stream accepts bytes (issue #422)
  219 +# 2019-05-23 v0.55 PL: - added option --pcode to call pcodedmp and display P-code
219 220  
220   -__version__ = '0.54.2'
  221 +__version__ = '0.55.dev1'
221 222  
222 223 #------------------------------------------------------------------------------
223 224 # TODO:
... ... @@ -285,6 +286,7 @@ except ImportError:
285 286 + "or http://effbot.org/zone/element-index.htm")
286 287  
287 288 import colorclass
  289 +from pcodedmp import pcodedmp
288 290  
289 291 # On Windows, colorclass needs to be enabled:
290 292 if os.name == 'nt':
... ... @@ -3518,7 +3520,7 @@ class VBA_Parser_CLI(VBA_Parser):
3518 3520 def process_file(self, show_decoded_strings=False,
3519 3521 display_code=True, hide_attributes=True,
3520 3522 vba_code_only=False, show_deobfuscated_code=False,
3521   - deobfuscate=False):
  3523 + deobfuscate=False, pcode=False):
3522 3524 """
3523 3525 Process a single file
3524 3526  
... ... @@ -3530,6 +3532,7 @@ class VBA_Parser_CLI(VBA_Parser):
3530 3532 otherwise each module is analyzed separately (old behaviour)
3531 3533 :param hide_attributes: bool, if True the first lines starting with "Attribute VB" are hidden (default)
3532 3534 :param deobfuscate: bool, if True attempt to deobfuscate VBA expressions (slow)
  3535 + :param pcode bool: if True, call pcodedmp to disassemble P-code and display it
3533 3536 """
3534 3537 #TODO: replace print by writing to a provided output file (sys.stdout by default)
3535 3538 # fix conflicting parameters:
... ... @@ -3599,6 +3602,23 @@ class VBA_Parser_CLI(VBA_Parser):
3599 3602 # display the exception with full stack trace for debugging
3600 3603 log.info('Error parsing form: %s' % exc)
3601 3604 log.debug('Traceback:', exc_info=True)
  3605 + if pcode:
  3606 + print('-' * 79)
  3607 + print('P-CODE disassembly:')
  3608 + # save sys.stdout, then modify it to capture pcodedmp's output
  3609 + stdout = sys.stdout
  3610 + output = BytesIO()
  3611 + sys.stdout = output
  3612 + class args:
  3613 + disasmOnly = True
  3614 + verbose = False
  3615 + try:
  3616 + # TODO: handle files in memory too
  3617 + pcodedmp.processFile(self.filename, args)
  3618 + except Exception:
  3619 + log.error('Error while running pcodedmp')
  3620 + sys.stdout = stdout
  3621 + print(output.getvalue())
3602 3622  
3603 3623 if not vba_code_only:
3604 3624 # analyse the code from all modules at once:
... ... @@ -3786,6 +3806,8 @@ def parse_args(cmd_line_args=None):
3786 3806 help="Attempt to deobfuscate VBA expressions (slow)")
3787 3807 parser.add_option('--relaxed', dest="relaxed", action="store_true", default=False,
3788 3808 help="Do not raise errors if opening of substream fails")
  3809 + parser.add_option('--pcode', dest="pcode", action="store_true", default=False,
  3810 + help="Disassemble and display the P-code (using pcodedmp)")
3789 3811  
3790 3812 (options, args) = parser.parse_args(cmd_line_args)
3791 3813  
... ... @@ -3823,7 +3845,7 @@ def process_file(filename, data, container, options, crypto_nesting=0):
3823 3845 display_code=options.display_code,
3824 3846 hide_attributes=options.hide_attributes, vba_code_only=options.vba_code_only,
3825 3847 show_deobfuscated_code=options.show_deobfuscated_code,
3826   - deobfuscate=options.deobfuscate)
  3848 + deobfuscate=options.deobfuscate, pcode=options.pcode)
3827 3849 elif options.output_mode == 'triage':
3828 3850 # summarized output for triage:
3829 3851 vba_parser.process_file_triage(show_decoded_strings=options.show_decoded_strings,
... ...
requirements.txt
... ... @@ -3,3 +3,4 @@ olefile>=0.46
3 3 easygui
4 4 colorclass
5 5 msoffcrypto-tool
  6 +pcodedmp>=1.2.4
6 7 \ No newline at end of file
... ...
setup.py
... ... @@ -30,6 +30,7 @@ to install this package.
30 30 # 2018-10-27 PL: - fixed issue #359 (bug when importing log_helper)
31 31 # 2019-02-26 CH: - add optional dependency msoffcrypto for decryption
32 32 # 2019-05-22 PL: - 'msoffcrypto-tool' is now a required dependency
  33 +# 2019-05-23 v0.55 PL: - added pcodedmp as dependency
33 34  
34 35 #--- TODO ---------------------------------------------------------------------
35 36  
... ... @@ -319,6 +320,7 @@ def main():
319 320 "easygui",
320 321 'colorclass',
321 322 'msoffcrypto-tool',
  323 + 'pcodedmp>=1.2.4',
322 324 ],
323 325 )
324 326  
... ...