一部のExcel 2003マクロを更新するように求められましたが、VBAプロジェクトはパスワードで保護されており、ドキュメントが不足しているようです...誰もパスワードを知りません。
VBAプロジェクトでパスワードを削除またはクラックする方法はありますか?
一部のExcel 2003マクロを更新するように求められましたが、VBAプロジェクトはパスワードで保護されており、ドキュメントが不足しているようです...誰もパスワードを知りません。
VBAプロジェクトでパスワードを削除またはクラックする方法はありますか?
回答:
VBA
HEX編集を必要としないこの直接的なアプローチを試すことができます。任意のファイル(* .xls、*。xlsm、*。xlam ...)で機能します。
テスト済みで動作します:
Excel 2007
Excel 2010
Excel 2013-32 ビットバージョン
Excel 2016-32 ビットバージョン
64ビット版をお探しですか?この回答を見る
私はそれがどのように機能するかを説明するために最善を尽くします-私の英語を許しませんでした。
最初にファイルをバックアップしてください!
新しいxlsmファイルを作成し、このコードをModule1に保存します
code credited to Siwtom (nick name), a Vietnamese developer
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
このコードをModule1の上記のコードの下に貼り付けて実行します
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
VBAプロジェクトに戻って楽しんでください。
はい、.xls
フォーマットスプレッドシートを使用している限り、あります(2003年までのExcelのデフォルト)。Excel 2007以降の場合、デフォルトは.xlsx
であり、これはかなり安全な形式であり、この方法は機能しません。
Trebが言うように、これは単純な比較です。1つの方法は、16進エディターを使用してファイル内のパスワードエントリを単純に交換することです(Windowsの16進エディターを参照)。ステップバイステップの例:
次のキーで始まる行をコピーします。
CMG=....
DPB=...
GC=...
VBAパスワードがわからないExcelファイルを最初にバックアップし、それを16進エディターで開いて、ダミーファイルからコピーした上記の行を貼り付けます。
:は、Excel 2007または2010で作業する必要がある場合は、特にこれらの、役立つかもしれないその下にいくつかの他の回答がある1、2、3。
2015年2月の編集:非常に有望に見える別の方法については、ĐứcThanhNguyễnによるこの新しい答えを見てください。
CMG...
文字列が元の文字列よりも長い場合は、ファイルの長さを安全に増やすことができることに注意してください。
このメソッドを64ビットバージョンのExcelで動作させるために、builtc ThanhNguyễnの素晴らしい答えを基に作成しました。Excel 2010 64ビットを64ビットWindows 7で実行しています。
新しいxlsmファイルを作成し、このコードを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
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 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
このコードをModule2に貼り付けて実行します
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
免責事項これは私のために働いた、そして私はそれが誰かを助けることを望んでここにそれを文書化した。私はそれを完全にテストしていません。このオプションを続行する前に、開いているすべてのファイルを必ず保存してください。
サイズの問題のない別の(やや簡単な)解決策があります。私はこの方法を(2003 XLSファイルで、Excel 2007を使用して)使用し、成功しました。
DPB=...
パーツを見つけます。DPB=...
に文字列をDPx=...
*注意:パスワードを必ず新しい値に変更してください。そうしないと、次にスプレッドシートを開いたときにExcelでエラー(予期しないエラー)が報告され、VBAモジュールのリストにアクセスすると、名前が表示されます。ソースモジュールがフォーム/コード/などを開こうとすると、別のエラーを受け取ります。これを修正するには、VBAプロジェクトプロパティに戻り、パスワードを新しい値に設定します。Excelドキュメントを保存して再度開くと、問題ありません。
Colin Pickardは素晴らしい答えを持っていますが、これには「注意」が1つあります。ファイルの「CMG = ........ GC = ....」エントリの全長が1つのExcelファイルと異なる場合があります(原因はまだわかりません)。次。このエントリは137バイトになる場合もあれば、143バイトになる場合もあります。137バイトの長さは奇妙な長さです。これが「1234」パスワードでファイルを作成するときに発生する場合は、別のファイルを作成するだけで、143バイトの長さにジャンプします。
間違ったバイト数をファイルに貼り付けようとすると、Excelでファイルを開こうとすると、VBAプロジェクトが失われます。
編集
これは、Excel 2007/2010ファイルでは無効です。標準の.xlsxファイル形式は、実際には、フォーマット、レイアウト、コンテンツなどを含む多数のサブフォルダーを含む.zipファイルであり、xmlデータとして保存されます。保護されていないExcel 2007ファイルの場合は、拡張子.xlsxを.zipに変更してから、zipファイルを開いてすべてのxmlデータを確認します。とても簡単です。
ただし、Excel 2007ファイルをパスワードで保護すると、.zip(.xlsx)ファイル全体がRSA暗号化を使用して実際に暗号化されます。拡張子を.zipに変更してファイルの内容を参照することはできなくなりました。
以下のため.xlsm
か、.dotm
ファイルの種類、あなたはそれを少し異なる方法を行う必要があります。
.xlsm
ファイルの拡張子をに変更します.zip
。vbaProject.bin
ファイルを抽出して16進エディターで開きます(私はHxDを使用しています。完全に無料で軽量です)。DPB
を検索して置換しDPx
、保存します。vbaProject.bin
ファイルを、zipファイル内のこの新しいファイルに置き換えます。.xlsm
。.xlsm
ファイルを保存します。Excel 2007(xlsm)ファイルがある場合、それをExcel 2003(xls)ファイルとして保存し、他の回答で概説されている方法を使用できることを指摘する価値があります。
1.
。.xlsmを.xlsに変換します。.xls 2.
のコードをクラックします3.
。.xlsmを.xlsxに変換4.
します。モジュールからのコードを.xlsから。 xlsx、それを.xlsmとして保存
私の番では、これはkaybee99の優れた答えに基づいて構築されています。これは、ĐứcThanhNguyễnの素晴らしい答えに基づいて構築されており、Officeのx86バージョンとamd64バージョンの両方でこのメソッドを使用できます。
変更点の概要。32ビットアドレスに制限されているpush / retを回避し、mov / jmp regに置き換えます。
テストされ、動作します
Word / Excel 2016-32 ビットバージョン。
Word / Excel 2016-64ビットバージョン。
使い方
上記と同じタイプの新しいファイルを作成し、このコードを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 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
このコードをModule2に貼り付けて実行します
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
イベントでのあなたのブロックという
CMG="XXXX"\r\nDPB="XXXXX"\r\nGC="XXXXXX"
あなたの「知られているパスワード」ファイルでは、正しい長さに到達するために後続ゼロを使用して進文字列「不明パスワード」ファイル内の既存のブロック、パッドよりも短くなっています。
例えば
CMG="xxxxxx"\r\nDPB="xxxxxxxx"\r\nGC="xxxxxxxxxx"
不明なパスワードファイルで、に設定する必要があります
CMG="XXXX00"\r\nDPB="XXXXX000"\r\nGC="XXXXXX0000"
ファイルの長さを保持します。
また、Office 2007でこれを.XLA(97/2003形式)ファイルで処理しました。
Excel 2007以降の場合、ファイル拡張子を.zipに変更する必要があります。アーカイブにはサブフォルダーxlがあり、そこにvbaProject.binがあります。上記の手順に従ってvbaProject.binを実行し、アーカイブに保存します。拡張機能を元に戻し、失敗します。(上記の手順に従うことを意味します)
Access、Excel、Powerpoint、またはWordドキュメント(2007, 2010, 2013 or 2016
拡張子付きのバージョン.ACCDB .XLSM .XLTM .DOCM .DOTM .POTM .PPSM
)のVBAプロジェクトパスワードは簡単に削除できます。
これは単に、ファイル名拡張子をに変更し、ファイルを.ZIP
解凍し、基本的な16進エディター(XVI32など)を使用して既存のパスワードを「解読」するだけです。これにより、Officeが「混乱」し、ファイルが次に使用されたときに新しいパスワードの入力を求められます。開いた。
.ZIP
拡張子を付けます。ZIP
移動しXL
ます。vbaProject.bin
Hex Editorで抽出して開きますDPB
へDPX
。.bin
ファイルをzipに戻し、通常の拡張子に戻して、通常のようにファイルを開きます。VBA Project Properties
。Protection
タブ、新しいパスワードを設定します。OK
、ファイルを閉じ、再度開き、Alt + F11キーを押します。この時点で、必要に応じてパスワードを完全に削除できます。
詳細な手順私が作ったステップバイステップのビデオで「いつ戻って道を」上にあるYouTubeのここ。
この回避策が何年にもわたって存在していて、Microsoftが問題を修正していないことは、一種のショックです。
物語の教訓?
Microsoft Office VBAプロジェクトのパスワードは、機密情報のセキュリティのために信頼されるべきではありません。セキュリティが重要な場合は、サードパーティの暗号化ソフトウェアを使用してください。
Colin Pickardはほぼ正しいですが、ファイル全体の「開くパスワード」保護とVBAパスワード保護を混同しないでください。VBAパスワード保護は、以前のものとは完全に異なり、Office 2003および2007でも同じです(Office 2007の場合は、名前を変更します)ファイルを.zipし、zip内のvbaProject.binを探します)。そして、技術的にファイルを編集する正しい方法は、CFXのようなOLE複合ドキュメントビューアを使用して正しいストリームを開くことです。もちろん、バイトを置き換えるだけの場合は、通常のバイナリエディタが機能する場合があります。
ところで、これらのフィールドの正確な形式について疑問に思っている場合は、ここで文書化されています。
http://msdn.microsoft.com/en-us/library/dd926151%28v=office.12%29.aspx
ファイルが有効なzipファイルである場合(最初の数バイトは50 4B
-などの形式で使用されます.xlsm
)、ファイルを解凍してサブファイルを探しますxl/vbaProject.bin
。これは、ファイルと同様にCFBファイル.xls
です。XLS形式(サブファイルに適用)の指示に従い、内容を圧縮します。
XLS形式については、この投稿の他の方法のいくつかに従うことができます。私は個人的にDPB=
ブロックを検索してテキストを置き換えることを好みます
CMG="..."
DPB="..."
GC="..."
空白スペースあり。これにより、CFBコンテナーのサイズの問題が回避されます。
上記の解決策をいくつか試しましたが、どれもうまくいきません(Excel 2007 xlsmファイル)。次に、パスワードを解読するだけでなく、パスワードを取得する別のソリューションを見つけました。
このコードをモジュールに挿入して実行し、しばらく時間をかけてください。力ずくでパスワードを回復します。
Sub PasswordBreaker()
'Breaks worksheet password protection.
Dim i As Integer, j As Integer, k As Integer
Dim l As Integer, m As Integer, n As Integer
Dim i1 As Integer, i2 As Integer, i3 As Integer
Dim i4 As Integer, i5 As Integer, i6 As Integer
On Error Resume Next
For i = 65 To 66: For j = 65 To 66: For k = 65 To 66
For l = 65 To 66: For m = 65 To 66: For i1 = 65 To 66
For i2 = 65 To 66: For i3 = 65 To 66: For i4 = 65 To 66
For i5 = 65 To 66: For i6 = 65 To 66: For n = 32 To 126
ActiveSheet.Unprotect Chr(i) & Chr(j) & Chr(k) & _
Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & Chr(i3) & _
Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
If ActiveSheet.ProtectContents = False Then
MsgBox "One usable password is " & Chr(i) & Chr(j) & _
Chr(k) & Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & _
Chr(i3) & Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
Exit Sub
End If
Next: Next: Next: Next: Next: Next
Next: Next: Next: Next: Next: Next
End Sub
ElcomSoftは、ドキュメントがOffice 2007以前で作成されている限り、このケースに該当する可能性があるAdvanced Office Password BreakerおよびAdvanced Office Password Recovery製品を製造しています。
トム-バイトサイズを確認しなかったため、最初に男子生徒のエラーが発生しました。代わりに、「CMG」設定から次のエントリにコピーして貼り付けました。ただし、これは2つのファイル間で2つの異なるテキストサイズであり、Stewbobが警告したように、VBAプロジェクトを失いました。
HxDを使用すると、選択しているファイルの量を追跡するカウンターがあります。CMGからコピーして、カウンターが8F(143の場合は16進数)を読み取るまで、そして同様にロックされたファイルに貼り付けるときにコピーします-貼り付けの最後に「...」の数が2倍になりました。不自然ですが、うまくいきました。
それが重要かどうかはわかりませんが、ファイルをExcelで再び開く前に、16進エディターとExcelの両方をシャットダウンしたことを確認しました。次に、メニューを操作してVBエディターを開き、VBProjectのプロパティに移動し、「新しい」パスワードを入力してコードのロックを解除しました。
これがお役に立てば幸いです。
Windows 10マシン上の64ビットのExcel 2016の場合、保護されたxlaのパスワードを変更できるように16進エディターを使用しました(他の拡張機能でこれをテストしていません)。 ヒント:これを行う前にバックアップを作成してください。
私が取った手順:
これが皆さんのお役に立てば幸いです。
Excelファイルの拡張子がxmlに変更されます。そしてそれをメモ帳で開きます。パスワードテキストはxmlファイルで見つかります。
以下のように見えます。
Sheets("Sheet1").Unprotect Password:="blabla"
(私の悪い英語でごめんなさい)
あなたが働いているJava
なら、あなたは試すことができますVBAMacroExtractor
。VBAスクリプトを抽出した後.xlsm
、プレーンテキストのパスワードが見つかりました。