我被要求更新一些Excel 2003宏,但是VBA项目有密码保护,而且似乎缺乏文档…没人知道密码。

是否有一种方法可以删除或破解VBA项目的密码?


当前回答

Colin Pickard is mostly correct, but don't confuse the "password to open" protection for the entire file with the VBA password protection, which is completely different from the former and is the same for Office 2003 and 2007 (for Office 2007, rename the file to .zip and look for the vbaProject.bin inside the zip). And that technically the correct way to edit the file is to use a OLE compound document viewer like CFX to open up the correct stream. Of course, if you are just replacing bytes, the plain old binary editor may work.

顺便说一句,如果你想知道这些字段的确切格式,他们现在有文档:

http://msdn.microsoft.com/en-us/library/dd926151%28v=office.12%29.aspx

其他回答

删除VBA项目密码的一个简单方法是执行以下操作:

将xlsm文件转换为zip 打开VBAProject.bin文件(我更喜欢使用notepad++ (https://notepad-plus-plus.org/downloads/)) 搜索DPB字段 用DPx替换它 保存文件 将zip文件转换为XLSM 打开excel文件 如果出现消息框,请单击“是” 为VBA项目属性设置新密码 关闭并再次打开该文件 输入新密码取消保护

我基于Đức Thanh nguynun的精彩回答,让这种方法适用于64位版本的Excel。我在64位的Windows 7上运行Excel 2010 64位。

Open the file(s) that contain your locked VBA Projects. Create a new xlsm file and store this code in 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 Paste this code in Module2 and run it Sub unprotected() If Hook Then MsgBox "VBA Project is unprotected!", vbInformation, "*****" End If End Sub

这对我来说很有效,我在这里记录了它,希望它能帮助别人。我还没有完全测试过。请确保在继续此选项之前保存所有打开的文件。

接受的答案在Windows 10上的Excel 2019中无法正常工作。找到了查看锁定宏所需的额外步骤。我正在总结步骤。

Add a .zip to the end of the excel filename and hit enter Once the file has been changed to a ZIP file, open it by double clicking on it Inside you would see a folder called xl like below Inside xl, you'll find a file called vbaProject.bin, copy/paste it on the desktop Go to the online Hexadecimal Editor HexEd.it Search for the following texts DPB=... and change them to DPx=... Save the file and close HexEd.it Copy/Paste the updated file from your desktop inside the ZIP file (you would need to overwrite it) Remove the .zip extension from the end of the filename and add the excel extention again. Open the file in excel - you may receive a couple of error notifications, just click through them.

====在接受的答案=====之外的额外步骤

Open the Visual Basic window (usually ALT+F11 if I remember correctly) and open the VBAProject properties (Tools menu). Click on the Protection tab and change (do not remove at this stage) the password to something short and easy to remember (we'll be removing in next step). Save the workbook and then close and reopen. Open again the Visual Basic window and enter the password you just put in. Redo the previous step but this time you can remove (delete) the password. Save the workbook and you have now removed the password.

从以下站点采取额外步骤 https://confluence.jaytaala.com/display/TKB/Remove+Excel+VBA+password

我尝试了上面的一些解决方案,但没有一个适合我(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

您可以尝试这种不需要HEX编辑的直接VBA方法。它将适用于任何文件(*.xls, *.xls, *.xls)。xlsm, *。xlam……)。

测试和工作:

Excel 2007 Excel 2010 Excel 2013 - 32位版本 Excel 2016 - 32位版本

寻找64位版本?请看这个答案

它是如何工作的

我会尽我最大的努力解释它是如何工作的-请原谅我的英语。

The VBE will call a system function to create the password dialog box. If user enters the right password and click OK, this function returns 1. If user enters the wrong password or click Cancel, this function returns 0. After the dialog box is closed, the VBE checks the returned value of the system function if this value is 1, the VBE will "think" that the password is right, hence the locked VBA project will be opened. The code below swaps the memory of the original function used to display the password dialog with a user defined function that will always return 1 when being called.

使用代码

请先备份您的文件!

Open the file(s) that contain your locked VBA Projects Create a new xlsm file and store this code in 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 Paste this code under the above code in Module1 and run it Sub unprotected() If Hook Then MsgBox "VBA Project is unprotected!", vbInformation, "*****" End If End Sub Come back to your VBA Projects and enjoy.