Skip to content

Instantly share code, notes, and snippets.

@decalage2
Created November 16, 2016 22:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save decalage2/770b100acf31d8af1fdfc9f5b735f564 to your computer and use it in GitHub Desktop.
Save decalage2/770b100acf31d8af1fdfc9f5b735f564 to your computer and use it in GitHub Desktop.
olevba - how to access VBA project/dir and module streams
# sample code to demonstrate how to access VBA project/dir and module streams using olevba
from oletools.olevba import VBA_Parser, decompress_stream
from oletools.ezhexviewer import hexdump3
import sys
def dump_vba_projects(vbaparser):
vba_projects = vbaparser.find_vba_projects()
for vba_root, project_path, dir_path in vba_projects:
print('=' * 79)
print('VBA Project: %s - dir stream: %s' % (project_path, dir_path))
print('-' * 79)
print('VBA Project dump:')
project_data = vbaparser.ole_file.openstream(project_path).read()
# print('%d bytes' % len(project_data))
# print(hexdump3(project_data, length=16))
print(project_data)
print('-' * 79)
print('dir stream dump after decompression:')
dir_data_compressed = vbaparser.ole_file.openstream(dir_path).read()
dir_data = decompress_stream(dir_data_compressed)
print('%d bytes' % len(dir_data))
print(hexdump3(dir_data, length=16))
print('-' * 79)
print('Module streams:')
for line in project_data.splitlines():
line = line.strip()
module = None
if '=' in line:
# split line at the 1st equal sign:
name, value = line.split('=', 1)
# looking for code modules
value = value.lower()
if name == 'Document':
# split value at the 1st slash, keep 1st part:
value = value.split('/', 1)[0]
module = vba_root + 'VBA/' + value
elif name in ('Module', 'Class', 'BaseClass'):
module = vba_root + 'VBA/' + value
if module:
module_data = vbaparser.ole_file.openstream(module).read()
print ('%s - %d bytes' % (module, len(module_data)))
# here you can process module data
print('-' * 79)
print('_VBA_PROJECT stream dump:')
_vba_project_path = vba_root + 'VBA/_VBA_PROJECT'
_vba_project_data = vbaparser.ole_file.openstream(_vba_project_path).read()
print('%d bytes' % len(dir_data))
print(hexdump3(dir_data, length=16))
fname = sys.argv[1]
print('Opening file %s' % fname)
vbaparser = VBA_Parser(fname)
if vbaparser.ole_file is not None:
# This is an OLE file
dump_vba_projects(vbaparser)
else:
# This is an OpenXML file
for vbaparser2 in vbaparser.ole_subfiles:
dump_vba_projects(vbaparser2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment