Skip to content

Instantly share code, notes, and snippets.

@CaledoniaProject
Created October 21, 2018 07:21
Show Gist options
  • Select an option

  • Save CaledoniaProject/1294d755be03a81d0073b3656017dbdb to your computer and use it in GitHub Desktop.

Select an option

Save CaledoniaProject/1294d755be03a81d0073b3656017dbdb to your computer and use it in GitHub Desktop.
Unlock-OfficeDocumentMacro
# Credit to https://chentiangemalc.wordpress.com/2012/01/17/powershell-script-to-remove-office-macro-protection/
# Function to unlock office 2000-2003 document by @chentiangemalc
# Proof-of-Concept Code lacking performance optimization & error handling
# This should not be considered example of how to write PowerShell code.
# Binary "IndexOf"
# too lazy (or busy…) to write this code in PowerShell, couldn’t find any good PowerShell example
# And this is fast. From http://stackoverflow.com/users/649008/foubar
# at http://stackoverflow.com/questions/283456/byte-array-pattern-search
$compilerParameters = New-Object System.CodeDom.Compiler.CompilerParameters
$compilerParameters.CompilerOptions="/unsafe"
Add-Type -PassThru -CompilerParameters $compilerParameters -TypeDefinition @"
using System;
using System.Collections.Generic;
public static class FastByte
{
public static unsafe long IndexOf(byte[] Haystack, byte[] Needle)
{
fixed (byte* H = Haystack) fixed (byte* N = Needle)
{
long i = 0;
for (byte* hNext = H, hEnd = H + Haystack.LongLength; hNext < hEnd; i++, hNext++)
{
bool Found = true;
for (byte* hInc = hNext, nInc = N, nEnd = N + Needle.LongLength; Found && nInc < nEnd; Found = *nInc == *hInc, nInc++, hInc++);
if (Found) return i;
}
return -1;
}
}
}
"@
Function Unlock-OfficeDocumentMacro
{
# To-do -
# * Check for valid office file formats. Currently works for Word/Acess/Excel 2000-2003 format
Param
(
[ValidateScript({Test-Path $_ -PathType Leaf})]
[String]
$InputFile
,
[String]
$OutputFile
)
Process
{
# We’ll work on the copy—just in case we mess up the original
Copy-Item $InputFile $OutputFile
# Load our target file all at once
# Not scalable … &c but works to test the concept
Write-Host "Loading $OutputFile"
$data=Get-Content -Encoding Byte $OutputFile
Write-Host "Searching file contents"
# The searchString is hex equivelant for string DPB=
[Byte[]] $searchBytes = 0×44,0×50,0×42,0x3D,0×22
[Byte[]] $replaceBytes = 0×44,0×50,0×78,0x3D,0×22
$index=[FastByte]::IndexOf($data,$searchBytes)
Write-Host "Found at $index"
# update file
# so many chances for failures here…add error checking!
[System.IO.Stream]$stream = [System.IO.File]::Open($OutputFile,[System.IO.FileMode]::Open)
$stream.Position=$index
$stream.Write($replaceBytes,0,$replaceBytes.Length)
$stream.Dispose()
Write-Host "Update Complete! Output file: $OutputFile"
}
}
Unlock-OfficeDocumentMacro -InputFile "c:\Support\Locked.xls" "c:\Support\Unlocked.xls"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment