{"id":2659,"library":"pcodedmp","title":"VBA P-Code Disassembler","description":"pcodedmp is a Python library and command-line tool for disassembling VBA p-code from Microsoft Office documents. It supports various Office formats (e.g., `.docm`, `.xlsm`, `.pptm`) and aims to provide detailed insight into embedded VBA macros for analysis. The current version is 1.2.6, with releases typically tied to bug fixes or feature additions for better p-code parsing.","status":"active","version":"1.2.6","language":"en","source_language":"en","source_url":"https://github.com/bontchev/pcodedmp","tags":["vba","malware-analysis","disassembler","office-documents","reverse-engineering"],"install":[{"cmd":"pip install pcodedmp","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Required for parsing OLE2 and Open XML file formats used by Microsoft Office documents.","package":"olefile"}],"imports":[{"note":"The main functions like `dump_file` reside in the `pcodedmp.py` module within the `pcodedmp` package structure, thus requiring the explicit `pcodedmp.pcodedmp` import path.","wrong":"from pcodedmp import dump_file","symbol":"dump_file","correct":"from pcodedmp.pcodedmp import dump_file"},{"note":"For disassembling a specific VBA stream directly.","symbol":"dump_stream","correct":"from pcodedmp.pcodedmp import dump_stream"}],"quickstart":{"code":"import os\nimport io\nimport sys\nfrom pcodedmp.pcodedmp import dump_file\n\n# This library processes existing Office documents containing VBA macros.\n# Replace 'path/to/your/document.docm' with the actual path to your target file.\n# For example, create a simple .docm file with a basic macro (e.g., MsgBox 'Hello').\n#\n# If the file does not exist, the library will raise a FileNotFoundError.\n# This example is designed to be runnable and show the expected output,\n# whether it's successful disassembly or an error due to a missing file.\ndocument_path = \"path/to/your/document.docm\" # Replace with a real path if you have one.\n\n# Capture stdout to inspect the disassembly output without writing to console\noriginal_stdout = sys.stdout\ncaptured_output = io.StringIO()\nsys.stdout = captured_output\n\ntry:\n    print(f\"Attempting to disassemble VBA p-code from: {document_path}\")\n    # The dump_file function writes output to sys.stdout by default.\n    # You can also specify an output file: dump_file(document_path, output_file=open('output.txt', 'w'))\n    dump_file(document_path)\n\n    # Get the captured output\n    output_lines = captured_output.getvalue().strip().split('\\n')\n    print(\"\\n--- Disassembly Attempt Result ---\")\n    if output_lines and output_lines[0].startswith('VBA p-code disassembler'): # Check for actual content\n        print(\"\\n\".join(output_lines[:10])) # Print first 10 lines of actual disassembly\n        if len(output_lines) > 10:\n            print(\"...\")\n        print(f\"(Full output length: {len(output_lines)} lines)\")\n    else:\n        # No relevant output from disassembly, likely an error message from the library itself\n        print(\"No relevant disassembly output. See error messages below if any.\")\n\nexcept FileNotFoundError:\n    print(f\"\\nERROR: Input file not found at '{document_path}'.\")\n    print(\"Please replace 'path/to/your/document.docm' with a valid path to an Office document containing VBA.\")\nexcept Exception as e:\n    print(f\"\\nAn unexpected error occurred: {e}\")\nfinally:\n    sys.stdout = original_stdout # Restore original stdout\n\nprint(\"\\nQuickstart finished. Check the 'Disassembly Attempt Result' above.\")","lang":"python","description":"This quickstart demonstrates how to use `pcodedmp` to disassemble VBA p-code from an Office document. It shows how to call the `dump_file` function and capture its output. Replace the placeholder `document_path` with an actual path to a `.docm`, `.xlsm`, or `.pptm` file containing VBA macros. The example gracefully handles `FileNotFoundError` and other exceptions."},"warnings":[{"fix":"Upgrade to version 1.2.1 or newer for Python 3.x support: `pip install --upgrade pcodedmp`.","message":"Prior to v1.2.1, pcodedmp only officially supported Python 2.6+. Attempting to use older versions on Python 3.x will likely result in compatibility errors.","severity":"gotcha","affected_versions":"<1.2.1"},{"fix":"Ensure you are using version 1.2.3 or newer for straightforward `pip` installation.","message":"Before v1.2.3, installation via `pip install pcodedmp` was not fully supported, requiring manual setup. Users attempting to install or use older versions might encounter difficulties.","severity":"gotcha","affected_versions":"<1.2.3"},{"fix":"Be aware of potential edge cases when analyzing highly complex or specifically obfuscated 64-bit VBA macros. Consult the project's 'Known problems' section in the README for details.","message":"While support for 64-bit Office documents and VBA7 features (like `PtrSafe`) improved in versions 1.1.0 and 1.2.1, the library's README still notes known limitations. Disassembly of some complex or obscure 64-bit specific p-code instructions might be incomplete or incorrect.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Update calls to `dump_file` or `dump_stream` to explicitly pass `output_file=sys.stdout` or an open file object for cleaner output handling: `dump_file(filename, output_file=my_file_handle)`.","message":"In v1.2.5, output functions like `dump_file` gained an `output_file` parameter, allowing explicit control over where disassembly output is written. While implicitly writing to `sys.stdout` still works by default, explicitly passing `output_file=sys.stdout` or a file handle is the recommended and more robust approach.","severity":"deprecated","affected_versions":"<1.2.5"}],"env_vars":null,"last_verified":"2026-04-10T00:00:00.000Z","next_check":"2026-07-09T00:00:00.000Z"}