PR
私が使っているPCガジェット類

作業環境で実際に使っている・気になっている周辺機器などをまとめました

※ 一部のリンクは広告(アフィリエイト)を含みます

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

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

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

ここで扱うのはVBAProject(マクロのコードを束ねている入れ物)にかけた保護パスワードで、これを知らないまま強制解除してコードを開く話です
古くはバイナリエディタで書き換える手もありましたが、今はVBAのプログラムを実行するだけでロックされたコードを確認できます

ひとつだけ先に整理しておくと、ファイルを開くときに求められる読み取りパスワードはこれとは別物です
あちらは中身をまるごと暗号化していて、忘れると誰も開けないので、この記事の手ではどうにもなりません、そこは混同しないでほしいところです

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

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

目次

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

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

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

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

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

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

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

マクロのパスワードを強制解除する手順

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

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

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

STEP
新規ファイルを作成

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

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

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

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

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

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

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

VBAProjectパスワード解除プログラム(64bit対応)

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

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になっているのがその印で、Microsoft 365を含む今どきの64bit版Excelでも動いたという報告が多いです
ただExcelのビルドや環境によっては実行時に落ちる・うまく効かないこともあるので、いきなり本番で試さずコピーで確認するのがおすすめです

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

操作動画

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

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

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

たてばやし淳

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

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

国本温子

増強改訂版 できる イラストで学ぶ 入社1年目からのExcel VBA

増強改訂版 できる イラストで学ぶ 入社1年目からのExcel VBA

きたみあきこ

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

注意点

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

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

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

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

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

「一時的なら困る、ちゃんと外したい」という場合は、フックで開けているあいだに保護を外すのが手です
VBエディタの「プロジェクトのプロパティ」から保護タブのパスワードのチェックを外して上書き保存すれば、次からは普通に開けます

つまり見るだけなら一時/保護を外して保存すれば恒久の二段構えです
まずは一時的に開いて中身を確認し、必要なら保護そのものを外す、と考えておくと分かりやすいと思います

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

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

もう一つの方法 DPBキーを書き換える(.xls / .xlsm)

APIフック以外に昔から知られているのが、バイナリを直接いじってDPBキーを書き換える方法です
DPBはVBAProjectの保護状態にひもづくキーで、ここのキー名を崩すとExcelが保護を無視してプロジェクトを開くようになります

古い.xls形式なら、バイナリエディタでvbaProject.bin相当の中の「DPB」を別の文字列(例 DPx)に書き換えるだけです
開いたあとにパスワードを空にして保存し直せば、そのまま恒久的に外せます

「これは古い.xls専用でしょ?」と思いがちですが、.xlsmでも同じことができます
xlsm(やxlsx)は中身がZIPなので、拡張子を.zipに変えて展開し、中のxl/vbaProject.binを取り出して同じDPB書き換えをして戻す、という流れです

バイナリ書き換えは1バイト間違えるとファイルごと壊れるので、コピーを取ってから作業するのが原則です
手軽さと安全さなら先ほどのプログラム実行(APIフック)のほうが上なので、慣れないうちはそちらがおすすめです

似た発想の「あとから保護を外す・中身を覗く」話として、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環境で作業するのが現実的だと思います

実行するとExcelが落ちる・フリーズします(64bit)

このプログラムはメモリを直接書き換えるので、Excelのビルドや環境によっては実行時に落ちることがあります、まず対象ファイルと作業用ファイルを同じExcelで開いているか、PtrSafe版の宣言が64bitと合っているかを確認してみてください、それでも落ちる場合は、コピーしたファイルで前述のDPBキー書き換えのほうを試す手もあります

総当たり(ブルートフォース)ツールでも解除できますか?

VBAProjectの保護は暗号化ではないので、総当たりツールを持ち出すまでもなく今回のプログラム実行やDPB書き換えで開けます、総当たり系のフリーソフトや有料ツールが本領を発揮するのはファイルを開くパスワード(暗号化)のほうで、そちらは短く単純なら現実的でも、長くて記号混じりだと事実上いつまでも終わりません、用途が別物なので目的に合った手段を選ぶのがコツです

シート保護やブックのパスワードも同じ方法で外せますか?

いいえ、今回のAPIフックはVBAProject(マクロのコード)の保護専用です、シート保護やブック構造の保護はまた別の仕組みで、こちらも暗号化ではないため外せますが、やり方が違います(xlsxをZIP展開して該当タグを消す等)、こちらは別記事で改めてまとめる予定です

あとがき

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

解除して開いたコードをこれから直す・書き足すなら、VBE(Visual Basic Editor)のおすすめ設定VBAの変数と定数の基本もあわせてどうぞ

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

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

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

たてばやし淳

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

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

国本温子

増強改訂版 できる イラストで学ぶ 入社1年目からのExcel VBA

増強改訂版 できる イラストで学ぶ 入社1年目からのExcel VBA

きたみあきこ

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


最後に・・・

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

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

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

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

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

78E62K

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

この記事を書いた人

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

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


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


ココナラのページへ

コメント

コメントする

目次