Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

olevba dropping file extensions #811

Closed
samspoerl opened this issue Apr 5, 2023 · 2 comments · Fixed by #723
Closed

olevba dropping file extensions #811

samspoerl opened this issue Apr 5, 2023 · 2 comments · Fixed by #723
Assignees
Milestone

Comments

@samspoerl
Copy link

Affected tool:
olevba

Describe the bug
I'm trying to extract all the VBA code from an xlsm file. I'm initializing a VBA_Parser object then calling the extract_all_macros() method. When I iterate through the returned tuples, the vba_filename values are missing file extensions. The behavior is inconsistent as sometimes the file extensions are there (e.g., .bas or .cls), and sometimes they're not. The attached sample did not have them for me.

File/Malware sample to reproduce the bug
olevba_bug_no_vba_file_extensions.zip
password: sample

How To Reproduce the bug

import os
from oletools.olevba import VBA_Parser

KEEP_NAME = True # Set this to True if you want to keep "Attribute VB_Name"

workbook_path = os.path.join(os.getcwd(), "test.xlsm")

def parse(workbook_path):
    vba_path = workbook_path + 'WorkbookContent'
    vba_parser = VBA_Parser(workbook_path)
    vba_modules = vba_parser.extract_all_macros() if vba_parser.detect_vba_macros() else []

    for filename, stream_path, vba_filename, content in vba_modules:
        print("filename: " + filename)
        print("stream_path: " + stream_path)
        print("vba_filename: " + vba_filename)

        lines = []
        if '\r\n' in content:
            lines = content.split('\r\n')
        else:
            lines = content.split('\n')

        if lines:
            content = []
            for line in lines:
                if line.startswith('Attribute') and 'VB_' in line:
                    if 'VB_Name' in line and KEEP_NAME:
                        content.append(line)
                else:
                    content.append(line)
            if content and content[-1] == '':
                content.pop(len(content)-1)
                non_empty_lines_of_code = len([c for c in content if c])
                if non_empty_lines_of_code > 0:
                    if not os.path.exists(os.path.join(vba_path)):
                        os.makedirs(vba_path)
                    with open(os.path.join(vba_path, vba_filename), 'w', encoding='utf-8') as f:
                        f.write('\n'.join(content))

    # Close as per recommended
    vba_parser.close()

parse(workbook_path)

Expected behavior
For the vba_filename values returned from extract_all_macros() to have their original file extensions (e.g., .bas or .cls).

Console output / Screenshots
image

Version information:

  • OS: Windows
  • OS version: 22H2 - 64 bits
  • Python version: 3.11.2 - 64 bits
  • oletools version: 0.60.1

Additional context
N/A

@decalage2 decalage2 self-assigned this Apr 6, 2023
@decalage2 decalage2 added this to the Next Release milestone Apr 6, 2023
@beauvankirk
Copy link

I have observed this behavior as well and was quite confused, but I think the underlying issue must be some recent change in the way Excel writes the vbaproject.bin file. I had an old version of a .xlsm workbook on which I had been periodically running extract_vba without issue (where .bas and .cls files get created), then at some point the created files were missing their extensions. To confirm, I took an older copy of the document which when fed to extract_vba still generates .cls/.bas files, made a trivial change and resaved, and then extract_vba generated files with no extensions.

@decalage2
Copy link
Owner

Fixed by PR #723

@decalage2 decalage2 linked a pull request Jan 31, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants