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

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


当前回答

编辑:这是已接受答案的更新版本,应该适用于更多的办公室版本。这很难,但让我们把这个答案说出来吧!

轮到我了,这是建立在kaybee99的优秀答案之上的,它建立在Đức Thanh nguykun的出色答案之上,允许这种方法与32/64位版本的Office一起工作。

概览一下更改的内容,我们避免了push/ret,它仅限于32位地址,并将其替换为mov/jmp reg。

它是如何工作的

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

其他回答

我的工具VbaDiff直接从文件中读取VBA,因此您可以使用它从大多数办公文档中恢复受保护的VBA代码,而无需求助于十六进制编辑器。

对于.xlsm或.dotm文件类型,您需要以稍微不同的方式进行操作。

Change the extension of the .xlsm file to .zip. Open the .zip file (with WinZip or WinRar etc) and go to the xl folder. Extract the vbaProject.bin file and open it in a Hex Editor (I use HxD, its completely free and lightweight.) Search for DPB and replace with DPx and save the file. Replace the old vbaProject.bin file with this new on in the zipped file. Change the file extension back to .xlsm. Open workbook skip through the warning messages. Open up Visual Basic inside Excel. Go to Tools > VBAProject Properties > Protection Tab. Put in a new password and save the .xlsm file. Close and re open and your new password will work.

ElcomSoft提供高级办公密码破断器和高级办公密码恢复产品,只要文档是在Office 2007或更早版本中创建的,就可以适用于这种情况。

Colin Pickard has an excellent answer, but there is one 'watch out' with this. There are instances (I haven't figured out the cause yet) where the total length of the "CMG=........GC=...." entry in the file is different from one excel file to the next. In some cases, this entry will be 137 bytes, and in others it will be 143 bytes. The 137 byte length is the odd one, and if this happens when you create your file with the '1234' password, just create another file, and it should jump to the 143 byte length.

如果您尝试将错误的字节数粘贴到文件中,当您尝试用Excel打开该文件时,您将丢失VBA项目。

EDIT

这对Excel 2007/2010文件无效。标准的。xlsx文件格式实际上是一个。zip文件,包含许多子文件夹,其中格式、布局、内容等存储为xml数据。对于未受保护的Excel 2007文件,只需将.xlsx扩展名更改为.zip,然后打开zip文件并查看所有xml数据。这很简单。

但是,当您对Excel 2007文件进行密码保护时,整个.zip (.xlsx)文件实际上是使用RSA加密进行加密的。不再可以将扩展名更改为.zip并浏览文件内容。

对于Excel 2007,您需要将文件扩展名更改为。zip 在存档中有一个子文件夹xl,在那里你会发现vbaProject.bin。 使用vbaProject.bin执行上面的步骤,然后将其保存回存档中。 修改回您的扩展名和voilà!(意思是遵循上面的步骤)