【VBA】マクロのパスワードを解除する方法 仕組みと注意点

VBAマクロのパスワード解除

理由はさておきVBAのパスワードを解除したくなることってありませんか?

自分で作ったマクロにパスワードをかけたのに肝心の合言葉を忘れてしまって中身を直せない、なんて話は私も身に覚えがあります

古くはバイナリエディタで書き換える手もありましたが、今はVBAのプログラムを実行するだけでロックされたコードを確認できるようになっています

このページでは自分のファイル(自作マクロのパスワード忘れ)を救済する前提で手順をまとめます、他人や業務で受け取ったファイルへ無断で使うものではないので、そこだけ先にお伝えしておきますね

解除に使うプログラムは記事の下のほうに置いてあります、先にコードだけ見たい方はそちらまで飛んでください

目次

そもそもVBAのパスワード保護とは

手順に入る前に、なぜパスワードがかかっているのに回避できてしまうのかを軽く押さえておきます

VBAProject(マクロのコードを束ねている入れ物)にかけるパスワードは、ファイルの中身をガッチリ暗号化しているわけではなくて、エディタ上でコードを表示させないための制限に近い仕組みです

正しいパスワードを入れたかどうかをExcel側が確認して、合っていればコードを開く、という判定をしているだけなんですね

裏を返すと、その判定の部分に「もう正解が入りましたよ」と思い込ませることができれば、パスワードを知らなくてもコードが開けてしまうわけです

今回紹介するプログラムは、まさにこの判定をすり抜けるアプローチをとっています、つまりVBAのパスワードはセキュリティとしては弱めで、おまけ程度の鍵だと思っておくのが現実的です

VBAProjectのパスワードは「コードの表示を抑える程度の保護」です、機密データを守る暗号化とは別物なので、本当に見られたくない情報をマクロ内に直書きするのは避けるのがおすすめです

解除手順

細かい操作はほとんどないので、サクッと4ステップにまとめました

STEP
パスワードを解除したいエクセルファイルを開く

とりあえず対象のファイルを開いておきます、このあと操作するExcelと同じウィンドウで開いている状態にしておくのがポイントです

STEP
新規ファイルを作成

プログラムを実行するための作業用ファイルを新しく作ります、対象ファイル自体をいじるのではなく、別のブックから操作する形ですね

STEP
新規ファイルでモジュールを作成

新規ファイルのVBエディタを開いて標準モジュールを挿入し、このあと載せるプログラムをまるごと貼り付けます

プログラムは記事の下にあるので、そこからコピペしてください

STEP
貼り付けたプログラムを実行

貼り付けたVBAProjectパスワード解除のプロシージャを実行して、成功のメッセージが出れば完了です

本来ならパスワードを入れないと展開されないはずの対象ファイルのプロジェクトが、そのまま開けるようになっています

保護解除プログラム

実際に使うプログラムはこちらなので、新規ファイルの標準モジュールにコピペでどうぞ↓↓

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 VBAProjectパスワード解除()
  If Hook Then
    MsgBox "VBAProjectのパスワード解除成功!", vbInformation, "Congratulations"
  End If
End Sub

このコードがやっているのは、Windowsがダイアログを出すときに呼び出すDialogBoxParamAという関数の動きを横取りすることです

VBAのパスワード入力ダイアログが出ようとした瞬間に「もう正解が返ってきたことにする」よう差し替えるイメージで、専門的にはAPIフックと呼ばれる手法ですね

差し替えのためにVirtualProtectやMoveMemoryといったメモリ操作の関数を使っていて、ここがエラーになりやすいので軽くだけ補足しておきます

掲載しているのは64bit版Excelに対応したPtrSafe版です、各宣言にPtrSafeが付いていて型がLongPtrになっているのがその印で、今どきのExcel(Microsoft 365含む)なら基本このまま動きます

もし古い32bit環境でコンパイルエラーが出る場合は、宣言の書き方を32bit向けに直す必要があります、このあたりはFAQでも触れるので、エラーで止まった方はそちらも見てみてください

操作動画

手順を動画化しただけですが、文字だけだと伝わりにくい時の参考にどうぞ

注意点

便利な手順ですが、いくつか性質を知っておかないと「あれ?元に戻ってる?」と戸惑うことになります

大事なのは、この手順を使ってもパスワードそのものが消えるわけではないという点です

あくまでメモリ上で一時的にダイアログを回避しているだけなので、上書き保存をしてもファイルを閉じて開き直すと、また同じパスワードが効いた状態に戻ります

そういう意味では「パスワードを解除する」というよりこっそり中身を覗くと言ったほうがしっくりくるかもしれないですね

この方法は恒久的な解除ではなく一時的な閲覧です、開き直すとロックが戻るので、見られたコードは別ファイルに控えておくのがおすすめです

もう一点、メモリを直接書き換える手法なので、環境によっては実行時にExcelが落ちることもあります

大事なファイルでいきなり試すのは怖いので、事前にコピーをとってから作業するのが安心です

ちなみに今回のAPIフック以外にも、古い.xls形式向けにバイナリエディタでvbaProject.binの中の「DPB」というキーを書き換える方法も知られています

こちらは仕組みとしては今でも紹介されていますが、書き換えをミスるとファイルが壊れる可能性があるので、扱いに慣れていないうちは今回のプログラム実行のほうが手軽だと思います、似た発想の「保護を後から外す」話として、PythonのExe化を逆コンパイルで覗く記事も書いているので興味があればどうぞ

PyInstallerでExe化したPythonを逆コンパイルする方法

使うときのマナー

仕組みを知ると応用したくなるところですが、使いどころは落ち着いて見極めたいですね

この手順が役に立つのは、自分で作ったマクロのパスワードを忘れてしまったような、自分のファイルを救済する場面です

一方で、他人が作ったファイルや業務で配布されたファイルにはパスワードをかけた人の意図があります、中を見たいときは作成者や権利者に許可をとるのが筋だと思います

このあたりは時点や状況によって考え方も変わりうるところなので、断定はしませんが、少なくとも無断で他人のロックを外して回るような使い方は避けておくのが無難です

  • 自分のファイル(自作マクロのパスワード忘れ)を救済する用途で使う
  • 他人や業務で受け取ったファイルは、作成者や権利者の許可を得てから
  • 作業前にファイルのコピーをとっておく

よくある質問

つまずきやすいポイントをQ&A形式でまとめておきます

32bit版のExcelでも動きますか?

掲載コードは64bit版に合わせたPtrSafe版です、32bit環境でコンパイルエラーが出る場合は、宣言部のLongPtrをLongに置き換えるなど32bit向けの書き方に直すと動くことが多いです、両対応にしたいときはVBA7で条件分岐させる書き方も知られています

xlsxやxlsmでも使えますか?

このAPIフック方式はファイルの拡張子に依存せず、VBエディタ上のダイアログを回避する仕組みなのでxlsmでも考え方は同じです、なおxlsxはマクロを保存できない形式なのでVBAProject自体が入っていないことが多く、その場合はそもそも保護を外す対象がない点だけ覚えておいてください

実行するとエラーが出るのですが?

まずコンパイルエラーなら32bit/64bitの宣言が環境と合っているかを確認します、実行時に落ちる場合は、対象ファイルと作業用ファイルが同じExcelで開かれているか、対象ファイルを先に開いているかをチェックしてみてください、メモリ操作を伴う性質上、念のため作業前にファイルのコピーをとっておくと安心です

パスワードを恒久的に消すことはできますか?

今回の方法はメモリ上で一時的にダイアログを回避するものなので、開き直すとパスワードは戻ります、恒久的に外したいなら、開けている間にVBエディタのプロジェクトのプロパティから保護のチェックを外して保存し直す、あるいは古い形式向けには前述のDPBキー書き換えといった方法が知られています、ただし書き換え系はファイル破損のリスクがあるので、コピーで試すのがおすすめです

Macでも同じ手順でいけますか?

このコードはWindowsのkernel32やuser32といったDLLを呼び出すので、Mac版Excelではそのままでは動きません、Mac環境ではWindows用のAPI宣言が使えないため、別のアプローチを探すか、Windows環境で作業するのが現実的だと思います

あとがき

VBAパスワードの解除方法は調べるといくつか出てきますが、今回のプログラム実行が一番手軽な気がします

仕組みとしてはパスワード入力の判定をすり抜けているだけなので、過信せず自分のファイルの救済に役立ててもらえたら嬉しいです

📚 VBAの独学に効く本PR
Excel VBA塾【動画×本で学ぶ!】

Excel VBA塾【動画×本で学ぶ!】

たてばやし淳

パーフェクトExcel VBA

パーフェクトExcel VBA

高橋宣成

Excel マクロ&VBA[実践ビジネス入門講座]完全版 第3版

Excel マクロ&VBA[実践ビジネス入門講座]完全版 第3版

国本温子

私のおすすめからランダムで3冊を表示しています


最後に・・・

クラウドワークスココナラでお仕事受け付けています!

PythonとExcelを中心に仕事に役立つ業務ツールや自動化、スクレイピングツールの作成を受注していて、クラウドワークスでは気が付けば100件以上のお仕事を受注してきました!

会社員をやりながらの副業なので時間の捻出は相応ですが、クライアントの方々と近い立場でこちらからも提案しながら活動していますのでお悩みあれば是非ご相談ください

ココナラのプロフィールページへ

"ココナラ"に新規登録する際は1,000Pもらえる紹介コード使ってください

78E62K

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

VBAとPythonを中心にユーザー側でできるITを自己学習しているので備忘録半分、学習履歴を残して同じ道を辿る人の参考になればとブログを始めました

副業でスクレイピングツール作成を中心にできることを色々やっていますのでご相談いただけるとありがたいです!


クラウドワークスのページへ


ココナラのページへ

コメント

コメントする

目次