Released under terms of Artistic License 2.0
This document outlines the procedure used to regain access to password-protected VBA macro projects in Microsoft Office files (e.g., .xlsm, .dotm).
Microsoft Office files are fundamentally ZIP archives. The VBA project, including its password protection, is stored in a binary file named vbaProject.bin within this archive. The protection mechanism relies on a data structure identified by the byte sequence "DPB". By programmatically altering this identifier to "DPx", we can corrupt the password check, causing the Office application to bypass it and open the VBA project in an unprotected state.
The following PowerShell script, unprotect-macros.ps1, automates this entire process. It works on a copy of the original file, ensuring the procedure is non-destructive.
param (
[string]$InputFile,
[string]$OutputFile
)
$scriptPath = $PSScriptRoot
$tempDir = Join-Path $scriptPath "temp_unprotect"
# 1. Setup temporary directory
if (Test-Path $tempDir) {
Remove-Item $tempDir -Recurse -Force
}
New-Item -ItemType Directory -Path $tempDir
# 2. Treat as a ZIP archive and extract
$zipFile = Join-Path $tempDir "archive.zip"
Copy-Item (Join-Path $scriptPath $InputFile) $zipFile
Expand-Archive -Path $zipFile -DestinationPath $tempDir
# 3. Locate the VBA file and modify the protection flag
$vbaProjectBin = Get-ChildItem -Path $tempDir -Filter "vbaProject.bin" -Recurse
if ($vbaProjectBin) {
$vbaPath = $vbaProjectBin.FullName
Write-Host "Found vbaProject.bin at $($vbaPath)"
$encoding = [System.Text.Encoding]::GetEncoding('iso-8859-1')
$contentBytes = Get-Content -Path $vbaPath -Encoding Byte -Raw
$contentAsString = $encoding.GetString($contentBytes)
if ($contentAsString.Contains("DPB")) {
Write-Host "Found 'DPB' protection flag. Patching file..."
$modifiedContentAsString = $contentAsString.Replace("DPB", "DPx")
$modifiedContentBytes = $encoding.GetBytes($modifiedContentAsString)
Set-Content -Path $vbaPath -Value $modifiedContentBytes -Encoding Byte
Write-Host "File patched successfully."
} else {
Write-Warning "'DPB' protection flag not found. The macros may not be password protected, or use a different method. The file will be re-packaged without modification."
}
} else {
Write-Error "vbaProject.bin not found in the archive."
Exit 1
}
# 4. Re-package the file
Remove-Item $zipFile -Force
$tempZipFile = Join-Path $scriptPath "temp_archive.zip"
$outputFileFullPath = Join-Path $scriptPath $OutputFile
if (Test-Path $outputFileFullPath) {
Remove-Item $outputFileFullPath -Force
}
if (Test-Path $tempZipFile) {
Remove-Item $tempZipFile -Force
}
Push-Location $tempDir
Compress-Archive -Path * -DestinationPath $tempZipFile -Force
Pop-Location
Move-Item -Path $tempZipFile -Destination $outputFileFullPath -Force
# 5. Cleanup
Remove-Item $tempDir -Recurse -Force
Write-Host "Successfully created unprotected file: $OutputFile"- Save the code above into a file named
unprotect-macros.ps1. - Place the script in the same directory as the Office file you wish to unprotect.
- Open a PowerShell terminal in that directory.
- Execute the script, providing the name of the file to unprotect (
-InputFile) and the desired name for the new, unprotected file (-OutputFile).
To unprotect a file named MyWorkbook.xlsm, you would run the following command:
powershell.exe -ExecutionPolicy Bypass -File ".\unprotect-macros.ps1" -InputFile "MyWorkbook.xlsm" -OutputFile "MyWorkbook_unprotected.xlsm"After the script runs, open the newly created _unprotected file. Microsoft Office will likely display a warning about "errors" or "unreadable content." This is expected; click Yes to proceed. Once the file is open, you should be able to access the VBA editor (Alt + F11) and view the macro source code.