【エクセル】VBAのパスワードが解除できない!

VBAのパスワードを忘れたり、他人から引き継いだ際にパスワードが分からなくて困ったときはありますか?
解除する方法を紹介している方がいたので、それを参考に試してみたいと思います。

VBAのパスワードを解除したい時は?

注意
パスワードの解除は、すべて自己責任で行ってください。

パスワードのかかったエクセルを開こう

まずは、パスワードのかかったエクセルファイルを開きます。
ファイル名は「lock.xlsm」としました。

VBAにパスワードをかける方法はこちら

新規のブックでVBAを開こう

新規のブックで、VBAを開き「標準モジュール」を追加します。
ファイル名は「unlock.xlsm」としました。

VBAの使い方はこちら。

コードを記述しよう

今回、使用したコードはこちら。

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 11) As Byte
Dim OriginBytes(0 To 11) As Byte
Dim pFunc As LongPtr
Dim Flag As Boolean

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

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

Public Function Hook() As Boolean
    Dim TmpBytes(0 To 11) As Byte
    Dim p As LongPtr, osi As Byte
    Dim OriginProtect As LongPtr

    Hook = False

    #If Win64 Then
        osi = 1
    #Else
        osi = 0
    #End If

    pFunc = GetProcAddress(GetModuleHandleA("user32.dll"), "DialogBoxParamA")

    If VirtualProtect(ByVal pFunc, 12, PAGE_EXECUTE_READWRITE, OriginProtect) <> 0 Then

        MoveMemory ByVal VarPtr(TmpBytes(0)), ByVal pFunc, osi + 1
        If TmpBytes(osi) <> &HB8 Then

            MoveMemory ByVal VarPtr(OriginBytes(0)), ByVal pFunc, 12

            p = GetPtr(AddressOf MyDialogBoxParam)

            If osi Then HookBytes(0) = &H48
            HookBytes(osi) = &HB8
            osi = osi + 1
            MoveMemory ByVal VarPtr(HookBytes(osi)), ByVal VarPtr(p), 4 * osi
            HookBytes(osi + 4 * osi) = &HFF
            HookBytes(osi + 4 * osi + 1) = &HE0

            MoveMemory ByVal pFunc, ByVal VarPtr(HookBytes(0)), 12
            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

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

※自分が作成したものではありません。
 参考元はこちら。

これを「unlock.xlsm」の「標準モジュール」に貼り付けます。

実行してみよう

では実行していきます。

「unprotected」を選択して「実行」します。

このようなMsgBoxが表示されるはずです。
では、解除されていることを確認しましょう。

解除されていますね。

「ツール」の「VBAプロジェクトのプロパティ」を開いて、「プロジェクトのロック」を解除しておきましょう。
この状態で上書き保存してあげれば、次回からもパスワードなしで開くことができるとおもいます。

まとめ

再度お願いしますが、この方法は自己責任で行ってください。
いかなる場合でも、一切責任を負いません。
困っている人の助けになれば幸いです。
それではまた。

  • X

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です