541

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

有没有办法删除或破解 VBA 项目的密码?

4

24 回答 24

772

您可以尝试这种VBA不需要十六进制编辑的直接方法。它适用于任何文件(*.xls、*.xlsm、*.xlam ...)。

经过测试并适用于:

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

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

这个怎么运作

我会尽力解释它是如何工作的——请原谅我的英语。

  1. VBE 将调用系统函数来创建密码对话框。
  2. 如果用户输入正确的密码并单击确定,该函数返回 1。如果用户输入错误的密码或单击取消,该函数返回 0。
  3. 对话框关闭后,VBE检查系统函数的返回值
  4. 如果此值为 1,VBE 将“认为”密码正确,因此将打开锁定的 VBA 项目。
  5. 下面的代码将用于显示密码对话框的原始函数的内存与用户定义的函数交换,该函数在被调用时将始终返回 1。

使用代码

请先备份您的文件!

  1. 打开包含锁定的 VBA 项目的文件
  2. 创建一个新的 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
    
  3. 将此代码粘贴到Module1中的上述代码下并运行它

    Sub unprotected()
        If Hook Then
            MsgBox "VBA Project is unprotected!", vbInformation, "*****"
        End If
    End Sub
    
  4. 回到您的 VBA 项目并享受。

于 2014-12-16T15:32:01.403 回答
226

是的,只要您使用.xls格式电子表格(Excel 到 2003 年的默认设置)。对于 Excel 2007 及更高版本,默认值为.xlsx,这是一种相当安全的格式,此方法将不起作用。

正如 Treb 所说,这是一个简单的比较。一种方法是使用十六进制编辑器简单地换出文件中的密码条目(请参阅Windows 的十六进制编辑器)。一步一步的例子:

  1. 创建一个新的简单excel文件。
  2. 在 VBA 部分,设置一个简单的密码(比如 - 1234)。
  3. 保存文件并退出。然后检查文件大小 - 查看Stewbob 的问题
  4. 使用十六进制编辑器打开您刚刚创建的文件。
  5. 复制以以下键开头的行:

    CMG=....
    DPB=...
    GC=...
    
  6. 首先备份你不知道 VBA 密码的 excel 文件,然后用你的十六进制编辑器打开它,然后从虚拟文件中粘贴上面复制的行。

  7. 保存excel文件并退出。
  8. 现在,打开您需要在其中查看 VBA 代码的 excel 文件。VBA 代码的密码将只是 1234(如我在此处显示的示例中所示)。

如果您需要使用 Excel 2007 或 2010,下面还有一些其他答案可能会有所帮助,尤其是这些:123

2015 年 2 月编辑:对于另一种看起来非常有前途的方法,请查看 Đức Thanh Nguyễn 的这个新答案

于 2009-06-22T10:58:24.917 回答
202

我建立在 Đức Thanh Nguyễn 的出色答案的基础上,以允许此方法与 64 位版本的 Excel 一起使用。我在 64 位 Windows 7 上运行 Excel 2010 64 位。

  1. 打开包含锁定的 VBA 项目的文件。
  2. 创建一个新的 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
    
  3. 将此代码粘贴到Module2并运行它

    Sub unprotected()
        If Hook Then
            MsgBox "VBA Project is unprotected!", vbInformation, "*****"
        End If
    End Sub
    

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

于 2015-06-23T14:32:21.277 回答
178

还有另一种(稍微简单的)解决方案,没有尺寸问题。我今天使用了这种方法(在 2003 XLS 文件上,使用 Excel 2007)并且成功了。

  1. 备份 xls 文件
  2. 在 HEX 编辑器中打开文件并找到DPB=...零件
  3. DPB=...将字符串更改为DPx=...
  4. 在 Excel 中打开 xls 文件
  5. 打开 VBA 编辑器 ( ALT+ F11)
  6. 神奇之处: Excel 发现无效密钥(DPx)并询问您是否要继续加载项目(基本上忽略保护)
  7. 您将能够覆盖密码,因此请将其更改为您可以记住的密码
  8. 保存 xls 文件*
  9. 关闭并重新打开文档并使用您的 VBA 魔法!

*注意:请确保您已将密码更改为新值,否则下次打开电子表格时 Excel 会报错(Unexpected Error),然后当您访问 VBA 模块列表时,您现在将看到源模块,但在尝试打开表单/代码/等时收到另一个错误。要解决此问题,请返回 VBA 项目属性并将密码设置为新值。保存并重新打开 Excel 文档,您应该一切顺利!

于 2010-11-05T15:25:55.630 回答
92

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

  1. .xlsm将文件的扩展名更改为.zip.
  2. 打开 .zip 文件(使用 WinZip 或 WinRar 等)并转到 xl 文件夹。
  3. 提取vbaProject.bin文件并在十六进制编辑器中打开它(我使用HxD,它完全免费且轻量级。)
  4. 搜索DPB并替换为DPx并保存文件。
  5. 用压缩文件中的这个新文件替换旧vbaProject.bin文件。
  6. 将文件扩展名改回.xlsm.
  7. 打开工作簿跳过警告消息。
  8. 在 Excel 中打开 Visual Basic。
  9. 转到工具 > VBAProject 属性 > 保护选项卡。
  10. 输入新密码并保存.xlsm文件。
  11. 关闭并重新打开,您的新密码将起作用。
于 2015-06-26T12:21:37.550 回答
68

Colin Pickard 有一个很好的答案,但有一个“小心”。在某些情况下(我还没有弄清楚原因)文件中“CMG=........GC=....”条目的总长度与一个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 并浏览文件内容。

于 2009-06-24T14:36:12.263 回答
63

轮到我了,这是建立在 kaybee99 的出色答案之上的,该答案是建立在 Đức Thanh Nguyễn 的出色答案之上的,以允许此方法适用于 x86 和 amd64 版本的 Office。

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

经过测试和工作

Word/Excel 2016 - 32 位版本
Word/Excel 2016 - 64 位版本

这个怎么运作

  1. 打开包含锁定的 VBA 项目的文件。
  2. 创建一个与上面相同类型的新文件并将此代码存储在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
    
  3. 将此代码粘贴到Module2并运行它

    Sub unprotected()
        If Hook Then
            MsgBox "VBA Project is unprotected!", vbInformation, "*****"
        End If
    End Sub
    
于 2018-11-18T08:03:29.980 回答
34

值得指出的是,如果您有 Excel 2007 (xlsm) 文件,那么您可以简单地将其保存为 Excel 2003 (xls) 文件并使用其他答案中概述的方法。

于 2011-03-25T01:29:54.353 回答
17

您是否尝试过在 OpenOffice.org 中简单地打开它们?

前段时间我遇到了类似的问题,发现 Excel 和 Calc 不了解彼此的加密,因此允许直接访问几乎所有内容。

这是不久前的事情,所以如果这不仅仅是我的侥幸,它也可能已被修补。

于 2010-04-12T15:50:42.723 回答
16

如果 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 格式)文件。

于 2011-04-06T14:21:38.890 回答
15

Access、Excel、Powerpoint 或 Word 文档(2007, 2010, 2013 or 2016带有扩展名的版本.ACCDB .XLSM .XLTM .DOCM .DOTM .POTM .PPSM)上的 VBA 项目密码可以轻松删除

只需将文件扩展名更改为.ZIP,解压缩文件,并使用任何基本的十六进制编辑器(如XVI32)来“破解”现有密码,这会“混淆”Office,因此它会在下次文件时提示输入新密码打开。

步骤总结:

  • 重命名文件,使其具有.ZIP扩展名。
  • 打开ZIP并转到XL文件夹。
  • 提取vbaProject.bin并使用十六进制编辑器打开它
  • “搜索和替换”到“全部替换”更改DPBDPX.
  • 保存更改,将.bin文件放回 zip 中,将其恢复为正常扩展名,然后像平常一样打开文件。
  • ALT+F11 进入VB编辑器,在项目资源管理器中右击选择VBA Project Properties.
  • Protection选项卡上,设置新密码。
  • 单击OK,关闭文件,重新打开,按 ALT+F11。
  • 输入您设置的新密码。

此时,您可以选择完全删除密码。

完整的说明以及我在YouTube 上制作“时光倒流”的分步视频。

令人震惊的是,这种解决方法已经存在多年,而微软还没有解决这个问题。


这个故事的主旨?

不应依赖Microsoft Office VBA Project 密码来保护任何敏感信息的安全。如果安全很重要,请使用第三方加密软件。

于 2018-02-10T14:57:49.493 回答
13

对于 Excel 2007 及更高版本,您需要将文件扩展名更改为 .zip 在存档中有一个子文件夹 xl,您将在其中找到 vbaProject.bin。使用 vbaProject.bin 执行上述步骤,然后将其保存回存档中。修改你的扩展,瞧!(意思是按照上面的步骤)

于 2014-06-20T18:11:07.937 回答
9

Colin Pickard 大部分是正确的,但不要将整个文件的“密码打开”保护与 VBA 密码保护混淆,这与前者完全不同,对于 Office 2003 和 2007 相同(对于 Office 2007,重命名将文件转换为 .zip 并在 zip 中查找 vbaProject.bin)。从技术上讲,编辑文件的正确方法是使用 OLE 复合文档查看器(如 CFX)打开正确的流。当然,如果您只是替换字节,普通的旧二进制编辑器可能会工作。

顺便说一句,如果您想知道这些字段的确切格式,他们现在已经记录在案:

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

于 2010-11-30T00:41:16.097 回答
9

我尝试了上面的一些解决方案,但它们都不适合我(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
于 2015-11-20T11:52:39.020 回答
7

如果该文件是一个有效的 zip 文件(前几个字节50 4B- 以类似的格式使用.xlsm),则解压缩文件并查找子文件xl/vbaProject.bin。这是一个 CFB 文件,就像.xls文件一样。按照 XLS 格式的说明(应用于子文件),然后压缩内容。

对于 XLS 格式,您可以按照本文中的其他一些方法进行操作。我个人更喜欢搜索DPB=块并替换文本

CMG="..."
DPB="..."
GC="..."

有空格。这避免了 CFB 容器大小问题。

于 2013-10-08T02:32:30.947 回答
6

Tom - 我最初犯了一个小学生错误,因为我没有注意字节大小,而是从“CMG”设置复制并粘贴到后续条目。不过,这两个文件之间有两种不同的文本大小,正如 Stewbob 警告的那样,我丢失了 VBA 项目。

使用 HxD,有一个计数器跟踪您选择的文件数量。从 CMG 开始复制,直到计数器读数为 8F(十六进制表示 143),同样在粘贴到锁定文件时 - 我在粘贴结束时得到了两倍的“...”数量,不知何故看起来很奇怪,感觉几乎不自然,但它奏效了。

我不知道这是否至关重要,但我确保在 Excel 中重新打开文件之前关闭了十六进制编辑器和 excel。然后我必须通过菜单打开 VB 编辑器,进入 VBProject 属性并输入“新”密码来解锁代码。

我希望这有帮助。

于 2010-04-12T15:35:20.507 回答
6

只要文档是在 Office 2007 或更早版本中创建的, ElcomSoft生产的Advanced Office Password BreakerAdvanced Office Password Recovery产品可能适用于这种情况。

于 2010-04-12T15:44:18.357 回答
4

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

于 2011-05-03T10:02:39.010 回答
3

接受的答案在 Windows 10 上的 Excel 2019 中不起作用。找出我们需要采取的额外步骤来查看锁定的宏。我正在总结步骤。

  1. 将 .zip 添加到 excel 文件名的末尾,然后按 Enter

  2. 将文件更改为 ZIP 文件后,双击打开它

  3. 在里面你会看到一个名为 xl 的文件夹,如下所示

  4. 在 xl 中,您会找到一个名为 vbaProject.bin 的文件,将其复制/粘贴到桌面上

  5. 转到在线十六进制编辑器 HexEd.it

  6. 搜索以下文本 DPB=... 并将其更改为 DPx=...

  7. 保存文件并关闭 HexEd.it

  8. 将更新后的文件从桌面复制/粘贴到 ZIP 文件中(您需要覆盖它)

  9. 从文件名末尾删除 .zip 扩展名并再次添加 excel 扩展名。

  10. 在 excel 中打开文件 - 您可能会收到一些错误通知,只需单击它们即可。

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

  1. 打开 Visual Basic 窗口(如果我没记错的话通常是 ALT+F11)并打开 VBAProject 属性(工具菜单)。
  2. 单击“保护”选项卡并将密码更改(在此阶段不要删除)简短易记的密码(我们将在下一步中删除)。
  3. 保存工作簿,然后关闭并重新打开。
  4. 再次打开 Visual Basic 窗口并输入您刚刚输入的密码。重做上一步,但这次您可以删除(删除)密码。
  5. 保存工作簿,您现在已经删除了密码。

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

于 2021-01-14T06:44:33.007 回答
2

保护是 Excel 中的简单文本比较。在您最喜欢的调试器中加载 Excel(Ollydbg是我选择的工具),找到进行比较的代码并将其修复为始终返回 true,这应该可以让您访问宏。

于 2009-06-22T10:54:40.180 回答
2

对于 Windows 10 机器上的 Excel 2016 64 位,我使用了一个十六进制编辑器来更改受保护的 xla 的密码(尚未针对任何其他扩展进行测试)。 提示:在执行此操作之前创建一个备份。

我采取的步骤:

  1. 在十六进制编辑器中打开 vba(例如 XVI)
  2. 在此 DPB 上搜索
  3. 将 DPB 更改为其他内容,例如 DPX
  4. 保存!
  5. 重新打开.xla,会出现错误信息,继续。
  6. 您现在可以通过打开属性并转到密码选项卡来更改 .xla 的密码。

我希望这对你们中的一些人有所帮助!

于 2018-01-29T09:09:30.950 回答
2

事实上,大多数启用宏的 Office 文档的代码文件都没有加密,密码只会阻止使用 Office 程序打开项目。这意味着,正如其他答案所建议的那样,您通常可以使用 Office 替代方法来访问和编辑文件。

但是,如果您只需要访问代码,则可以使用oledump.py之类的工具来提取宏代码。这对于恶意软件分析以及从文件中获取大部分代码很有用,这样您就不必在忘记密码时从头开始。

此外,许多excel文件在打开文件时会动态设置密码。这意味着如果您可以阅读代码,通常可以找到明文密码或对其进行去混淆处理。

oledump.py例子:

列出办公文档中的所有“流”(嵌入的二进制文件或代码文件):

python oledump.py -v yourExcelFile.xlsm

输出:

A: xl/vbaProject.bin
 A1:      2000 'PROJECT'
 A2:      1500 'PROJECTwm'
 A3: M    1224 'VBA/Module1'
 A4: M   18694 'VBA/Module2'
 A5: M   11877 'VBA/Module3'
...

M旁边的流是宏,它是未加密的 VBA 代码

提取流

python oledump.py -s A3 -v yourExcelFile.xlsm > Module1.vba

这会将A3流中包含的代码输出到Module1.vba.

我通常将它与循环结合起来,将所有文件提取到一个文件夹中。这个快速的 PowerShell 脚本将提取大多数文件中的所有流:

New-Item -ItemType Directory "Output"

# just hardcode the highest stream outputted by oledump.py -v
$max = 5 
for ($i = 1; $i -le $max; $i++) {
    python oledump.py -s "A$i" -v yourExcelFile.xlsm > ".\Output\A$i"
}

请注意,这只会提取人类可读的文件。

于 2022-01-12T16:14:26.733 回答
0

您的 excel 文件的扩展名更改为 xml。并在记事本中打开。在 xml 文件中查找密码文本。

你看到像下面的线;

Sheets("Sheet1").Unprotect Password:="blabla"

(对不起,我的英语不好)

于 2017-06-05T10:43:17.540 回答
0

如果你在工作,Java你可以试试VBAMacroExtractor。从中提取 VBA 脚本后,.xlsm我发现那里有明文密码。

于 2018-04-08T13:37:56.967 回答