Excel の各種パスワードを突破する方法まとめ

Excel のブックには、色々なパスワード保護をかけることができる。しかし、うっかりパスワードを忘れてしまったとか、引き継いだブックにパスワードが掛かっていたがパスワードを知る人が居なくなってしまっている、といったことがあるだろう。そういうときのために、パスワード保護の種類別に、解除方法をまとめる。

目次

シートの保護パスワードを解除する

シートごとに保護パスワードをかけている場合は、「パスワードを解除する」のではなく、シート全体を別の新規シートにコピペすることでも保護を解除できる。「シートの保護」は「シートのコピペ禁止」ではないのがミソだ。

別のやり方もある。

Excel 2007 以降の .xlsx 形式のブックは、内部的には Zip 化された XML ファイルの集合体だ。そこで、拡張子 .xlsx.zip に変更して解凍、出てきたファイル・フォルダ群の中にある xl/worksheets/sheet*.xml を書き換えるのだ。

<sheetProtection> 要素が見つかったら、password 属性の値を 83AF とでも書き換えよう。83AFpassword という文字列をハッシュ化したものだ。

<sheetProtection password="83AF" sheet="1" objects="1" scenarios="1"/>

つまり、これをまた Zip 圧縮すれば、「password」という文字列でシートの保護が解除できるようになる。

XML ファイルを書き換える時は、BOM なし UTF-8 で保存できるテキストエディタを使用すること。

ブックの保護パスワードを解除する

Excel 2007 以降の形式であれば、これも Zip 解凍して xl/workbook.xml の中身を以下のように書き換えると良い。こちらも、パスワードの文字列を「password」に変更するものだ。

<workbookProtection workbookPassword="83AF" lockStructure="1"/>

書き込みパスワードを解除する

これも同様。Zip 解凍して xl/workbook.xml の中身を以下のように書き換えると良い。パスワードの文字列を「password」に変更する。

<fileSharing userName="HogeFuga" reservationPassword="83AF"/>

VBA のパスワードを解除する

.xls ファイルをバイナリエディタで開き、「DPB=」以降のハッシュ化された文字列を書き換えることで変更できる。詳しくは以下。

もしくは、以下のマクロをコピペして実行することで、マクロのパスワードを解除することができる。

' 適当な新規ブックを作り、標準モジュール Module1 に以下をコピペする。
Option Explicit

Private Const PAGE_EXECUTE_READWRITE = &H40

Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Long, Source As Long, ByVal Length As Long)
Private Declare Function VirtualProtect Lib "kernel32" (lpAddress As Long, ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As Long
Private Declare Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function DialogBoxParam Lib "user32" Alias "DialogBoxParamA" (ByVal hInstance As Long, ByVal pTemplateName As Long, ByVal hWndParent As Long, ByVal lpDialogFunc As Long, ByVal dwInitParam As Long) As Integer

Dim HookBytes(0 To 5) As Byte
Dim OriginBytes(0 To 5) As Byte
Dim pFunc As Long
Dim Flag As Boolean

Private Function GetPtr(ByVal Value As Long) As Long
  GetPtr = Value
End Function

Public Sub RecoverBytes()
  If Flag Then MoveMemory ByVal pFunc, ByVal VarPtr(OriginBytes(0)), 6
End Sub

Public Function Hook() As Boolean
  Dim TmpBytes(0 To 5) As Byte
  Dim p As Long
  Dim OriginProtect As Long
  Hook = False
  pFunc = GetProcAddress(GetModuleHandleA("user32.dll"), "DialogBoxParamA")
  If VirtualProtect(ByVal pFunc, 6, PAGE_EXECUTE_READWRITE, OriginProtect) <> 0 Then
    MoveMemory ByVal VarPtr(TmpBytes(0)), ByVal pFunc, 6
    If TmpBytes(0) <> &H68 Then
      MoveMemory ByVal VarPtr(OriginBytes(0)), ByVal pFunc, 6
      p = GetPtr(AddressOf MyDialogBoxParam)
      HookBytes(0) = &H68
      MoveMemory ByVal VarPtr(HookBytes(1)), ByVal VarPtr(p), 4
      HookBytes(5) = &HC3
      MoveMemory ByVal pFunc, ByVal VarPtr(HookBytes(0)), 6
      Flag = True
      Hook = True
    End If
  End If
End Function

Private Function MyDialogBoxParam(ByVal hInstance As Long, ByVal pTemplateName As Long, ByVal hWndParent As Long, ByVal lpDialogFunc As Long, ByVal dwInitParam As Long) As Integer
  If pTemplateName = 4070 Then
    MyDialogBoxParam = 1
  Else
    RecoverBytes
    MyDialogBoxParam = DialogBoxParam(hInstance, pTemplateName, hWndParent, lpDialogFunc, dwInitParam)
    Hook
  End If
End Function

' 別の標準モジュール Module2 を作って、以下をコピペ
Sub unprotected()
  If Hook Then
    MsgBox "VBA Project is unprotected!", vbInformation, "*****"
  End If
End Sub

VBA のパスワードを解除したいブックを開いておき、unprotected() マクロを実行すれば解除できるはず。

読み取りパスワードを解除する

読み取り専用パスワードがかけられていると、シートやブックの保護パスワードを解除するための Zip 解凍すらうまくできない。

最後に取り上げていることからお察しかもしれないが、読み取り専用パスワードを解除する裏技はどうやら存在しないらしい。総当たりでパスワードを解読するしかないようだ。

自分が試したのは「Excel UnPassword」というツール。.xls 形式にしか対応していないが、VBA で作成されているため、コードを参照して総当たりのやり方を勉強することができる。

また、自分でも読み取り専用パスワードを解読する VBScript のツールを作ってみた。以下をご覧いただきたい。