Excel 64Bit版 VBAマクロ パスワード解除方法

Excel 64Bit版 VBAでパスワードロックを解除する方法です。

Excel 64Bit版 VBAマクロ パスワード解除方法

以前「Excel VBAマクロ パスワード解除方法」では32Bit版のVBAマクロのパスワード解除方法を紹介しました。

当時紹介したのは32Bit版のVBAマクロのパスワード解除方法なので、当然64Bit版のOfficeでは動作しません。

コンパイルエラー:
このプロジェクトのコードは、64ビットシステムで使用するために更新する必要があります。Declaerステートメントの確認および更新を行い、次にDeclareステートメントにPtsSafe属性を設定してください。

なんとか64Bit版のVBAマクロのパスワード解除をしたいとお問い合わせをいただいたので解決方法を紹介したいと思います。

ここでは Excel 64Bit版 VBAでパスワードロックを解除する方法 を紹介します。

全て自己責任において実施してください。当方では一切の責任を負いません。


32Bit版と64Bit版のVBAコードの違い

実は32Bit版と64Bit版のVBAコードは、ほとんど変更する必要はないんですよね。ただ、DeclareステートメントでWindows APIを呼び出す場合は注意が必要です。具体的にはLongのような32Bitデータ型を使用している場合には、64Bit版のLongPtrに置換するなどの対応が必要になります。

詳しいことは「64 ビット版または 32 ビット版の Office を選択する」に書いてあるので読んでみてください。

VBA コードで Declare ステートメントを使用する ほとんどの VBA コードは、64 ビット版と 32 ビット版を使用する場合、変更する必要はありません。ただし、ポインターやハンドル用に、Long のような 32 ビット データ型を使用して、Declare ステートメントで Windows API を呼び出す場合は、変更が必要です。 ほとんどの場合、PtrSafe を Declare に追加して、Long を LongPtr に置換すると、Declare ステートメントは 32 ビット版と 64 ビット版の両方に対応します。 ただしこれは、まれなケースで Declare する 64 ビット版 API が存在しない場合は、実行できません。

support.microsoft.com

64Bit版VBAパスワードの解除方法

では、64Bit版VBAパスワードの解除方法を紹介します。基本的には32Bit版の時と同じ要領で実施します。

まずはパスワードロックされているxlsmファイルを開きます。

パスワードロックされているxlsmファイルを開

ふむふむ、ロックされておりますな。

では、新規のブックを開いて「名前を付けて保存」からファイルの種類をxlsmとして適当な場所に保存します。

ここでは「unlocked.xlsm」として保存しました。

VBAの画面を開いてModule1を作成し、下記のソースを貼り付けます。

Option Explicit

Private Const PAGE_EXECUTE_READWRITE = &H40

Private Declare PtrSafe Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As LongPtr, Source As LongPtr, ByVal Length As LongPtr)
Private Declare PtrSafe Function VirtualProtect Lib "kernel32" (lpAddress As LongPtr, ByVal dwSize As LongPtr, ByVal flNewProtect As LongPtr, lpflOldProtect As LongPtr) As LongPtr
Private Declare PtrSafe Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As LongPtr
Private Declare PtrSafe Function GetProcAddress Lib "kernel32" (ByVal hModule As LongPtr, ByVal lpProcName As String) As LongPtr
Private Declare PtrSafe Function DialogBoxParam Lib "user32" Alias "DialogBoxParamA" (ByVal hInstance As LongPtr, ByVal pTemplateName As LongPtr, ByVal hWndParent As LongPtr, ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer
Dim HookBytes(0 To 5) As Byte
Dim OriginBytes(0 To 5) As Byte
Dim pFunc As LongPtr
Dim Flag As Boolean

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

Private 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 LongPtr
  Dim OriginProtect As LongPtr

  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 LongPtr, ByVal pTemplateName As LongPtr, ByVal hWndParent As LongPtr, ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer
  If pTemplateName = 4070 Then
    MyDialogBoxParam = 1
  Else
    RecoverBytes
    MyDialogBoxParam = DialogBoxParam(hInstance, pTemplateName, hWndParent, lpDialogFunc, dwInitParam)
    Hook
  End If
End Function

Public Sub unprotected()
  If Hook Then
    MsgBox "VBA Project is unprotected!", vbInformation, "*****"
  End If
End Sub

保存したら「Sub/ユーザー フォームの実行」ボタンを押下するか「F5キー」を押下しましょう。

Sub/ユーザー フォームの実行ボタンを押下するかF5キーを押下

unprotectedを実行します。

unprotectedを実行する

このメッセージが出ればパスワードロックは解除されています。

VBA 64BIt版 パスワード解除のメッセージ

おおおー、パスワードロックが解除されたー^^

VBA 64BIt版 パスワード解除された

参考サイト

まとめ

Excel 64Bit版 VBAでパスワードロックを解除する方法を紹介しました。

実は今回紹介した方法はWin8/Office2013頃に紹介しようと思ったのですがお蔵入りしたソースコードです。マクロ実行してもフリーズして動作しなくて紹介しませんでした。

当時のOfficeでは32Bit版と64Bit版のDeclareステートメントの宣言を分ける方法を分けてコーディングする必要もあったりと苦労した記憶があります。

今回の検証で使ったのはOffice2016 32Bit版ですが、64Bit版のコードを書いても32Bit版で動作するという新たな発見がありました。おまけにパスワードの再設定をしてもExcelが破損しなかったので、新しいブックを作ってインポートという作業も不要でした。便利になったなー^^

皆さんも試してみてください。

追記

いただいたコメントから察するに、どうも64ビット版のコードは動作不安定なようです。周囲にExcel 32ビット版を使われている方がいれば、その方に頼んでみてください。実際、解決できたというコメントをいただいていますので、解決できる角度は高いかと思われます。

本ページのコードが動作しない上に周囲にExcel 32ビット版を使われている方がいない、という方はご相談ください。コメントからでもお問い合わせページからでも可能です。

バイナリエディタを使ってVBAパスワードを解除する

おつかれさまでした。

この記事がお役に立ちましたら シェア をお願いいたします。