有没有办法破解Excel VBA项目的密码?

Is there a way to crack the password on an Excel VBA Project?

提问人:Jonathan Sayce 提问时间:6/22/2009 最后编辑:Jonathan Sayce 更新时间:1/24/2023 访问量:1619911

问:

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

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

Excel VBA 密码

评论

0赞 B Hart 10/30/2013
您是否能够像链接中的示例所示将 .xls 而不是 .xla 另存为?不确定这是否会有所作为。
4赞 Qbik 11/16/2015
众所周知:XLSB对密码破解技巧很强大
34赞 jmbpiano 1/3/2018
@Fandango68 这个问题几年前在元上讨论过。TLDR:很多(大多数?)关于SO的问题都可能被不良行为者滥用,但除非有明确的证据证明有不当行为,否则我们假设是善意的。破解VBA密码有很多合法的法律和道德原因。此外,讨论当前系统的弱点最终有助于在未来提高安全性,并阻止人们现在盲目依赖不安全的系统。
2赞 Aditya Singh 8/17/2022
对于任何偶然发现这一点的人,请注意,您只需在 OpenOffice 中打开 excel 文件,它就会打开所有内容而无需输入密码。

答:

4赞 Treb 6/22/2009 #1

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

228赞 Colin Pickard 6/22/2009 #2

是的,只要您使用的是格式化电子表格(Excel 2003 之前的默认值)。对于 Excel 2007 及更高版本,默认值为 ,这是一种相当安全的格式,此方法将不起作用。.xls.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 的这个新答案

评论

0赞 Geoffrey 9/2/2009
如果没有以 CMG=...开头的行怎么办?
1赞 Colin Pickard 9/2/2009
在空白的 excel 文件中,还是在锁定的文件中?检查空白文件的文件大小。如果是锁定的文件,请确保您的备份是安全的,然后尝试仅更改其他两行。你确定它是加密文件吗?
6赞 Stewbob 9/11/2010
Excel 2007 密码保护(和文件格式)与 Excel 2003 截然不同。我在下面的回答中包含了一些关于它的细节。在我看来,Excel 2007 文件上的密码保护选项是 Microsoft Office 历史上第一次生成相当安全的文件。
1赞 Mescalito 2/29/2016
我无法在 excel 2016 新文件上设置 vba 密码。有人可以简单地共享十六进制以替换为 1234 吗?或者它可以从一台机器到另一台机器改变吗?
1赞 Drew Chapin 5/11/2016
这种方法在 .xlsm 文件上对我有用。我将其保存为 .xls,执行此操作,然后将其转换回 .xlsm。应该注意的是,如果新字符串比原始字符串长,您可以安全地增加文件的长度。CMG...
69赞 Stewbob 6/24/2009 #3

科林·皮卡德(Colin Pickard)有一个很好的答案,但有一个“小心”。在某些情况下(我还没有弄清楚原因),其中“CMG=........GC=....”文件中的条目从一个 Excel 文件到下一个 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 并浏览文件内容。

评论

0赞 Anonymous Type 9/28/2010
然后,您需要使用标准的zip黑客工具。它不再是“如何备份 excel 文件”的问题。
3赞 Treb 9/28/2010
@Anonymous类型:我认为拉链破解工具无济于事。据我了解,加密的不是 zip 文件中的文件条目,而是整个 zip 文件本身,其中应该包括标头和中央目录。
2赞 kizzx2 2/3/2011
只是好奇:当我只输入一个密码(对称)时,怎么可能是 RSA?
0赞 onlynone 10/6/2015
当您要进入的文件具有较短的键时如何?只是继续创建 vba 文档,直到你得到一个有 137 的文档?
1赞 Nigel Heffernan 10/19/2017
您确定在锁定 VBA 项目时对整个 zipfile 进行了加密吗?我仍然可以打开zip文件并查看文件结构。子文件夹 xl\ 包含文件 vbaProject.bin,其中包含熟悉的“CMG=...GC=“哈希块。
6赞 Scoob 4/12/2010 #4

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

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

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

我希望这会有所帮助。

评论

0赞 Matt Wanchap 10/6/2021
谢谢,这是唯一对我有用的东西!
6赞 Charles Duffy 4/12/2010 #5

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

17赞 greg 4/12/2010 #6

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

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

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

183赞 Pieter 11/5/2010 #7

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

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

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

评论

3赞 Joe Carroll 12/15/2012
不幸的是,这在Excel for Mac 2011 v14.2.5中对我不起作用。我可以选择修复文件,而不是重置密码,效果是丢失了所有VBA脚本。
0赞 Chris W 2/4/2013
完美的解决方案 - 我使用 HxD 十六进制编辑器对 2003 文件进行了此操作
4赞 KekuSemau 6/23/2013
我只是尝试了一下(.xls,Excel 2007),但它不起作用。结果是:模块是可见的,代码似乎确实有效,但是当打开模块时,它显示意外错误(40230)。
3赞 Owen B 8/15/2013
这里也有同样的错误(Excel 2010) - 但后来我意识到我跳过了 Pieter 的“设置新密码并保存/重新打开”(步骤 7-9)。
1赞 frarugi87 11/26/2022
试了一下,得到了“意外的错误(40230)”,阅读了评论,看到了@OwenB评论,脸掌,保存了......它奏效了:)Excel 2021,此解决方法仍然有效。谢谢
10赞 Yuhong Bao 11/30/2010 #8

Colin Pickard基本上是正确的,但不要将整个文件的“打开密码”保护与VBA密码保护混淆,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

评论

2赞 JohnLBevan 7/19/2012
以下链接提供了 XSLM 格式文件的详细信息。gbanik.blogspot.co.uk/2010/08/......该解决方案与上面 Yuhong Bao 概述的解决方案相同,但阅读起来很有趣,并包含屏幕截图。
34赞 Andy 3/25/2011 #9

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

评论

4赞 Qbik 6/17/2014
事实并非如此,我处理过无法从 xlsm 转换为 xls/xla 的文件,Excel 2007 和 2010 每次都崩溃,我尝试了各种实例,来自一条错误消息 - Kod wyjątku:c0000005 Przesunięcie wyjątku:005d211d
4赞 ZygD 10/2/2015
是的,你可以做到。我已经做过很多次了。如果工作表上有一些必要的内容并且没有转移到旧版本,我会这样做: 1. 将 .xlsm 转换为 .xls 2. 破解 .xls 的代码 3. 将 .xlsm 转换为 .xlsx 4 .将 .xls 中模块中的代码放入 .xlsx 并将其另存为 .xlsm
0赞 Purus 2/3/2017
如答案所示,它将 xlsm 转换为 xls 后即可工作。
16赞 Spangen 4/6/2011 #10

如果“已知密码”文件中的块比“未知密码”文件中的现有块短,请用尾随零填充十六进制字符串以达到正确的长度。CMG="XXXX"\r\nDPB="XXXXX"\r\nGC="XXXXXX"

例如:

CMG="xxxxxx"\r\nDPB="xxxxxxxx"\r\nGC="xxxxxxxxxx"

在未知密码文件中,应设置为

CMG="XXXX00"\r\nDPB="XXXXX000"\r\nGC="XXXXXX0000"以保留文件长度。

我也曾与.XLA(97/2003 格式)文件。

评论

1赞 tobriand 7/20/2013
这有效,但正如我最近发现(上面评论)的那样,您也可以简单地在 GC=“...”阻挡,直到你达到相同的长度。
0赞 Noam Brand 10/24/2022
当“未知密码”比现有块长时,您会怎么做?
4赞 Chris Spicer 5/3/2011 #11

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

评论

0赞 thanos.a 4/28/2020
我有测试这个工具并且运行良好,但是免费版本检索了前 53 行。为了恢复我的文件,我必须按照安迪的指示解锁密码。然后,我在两个窗格中都打开了带有 VbaDiff 的 xlsm,然后单击带有代码的工作表。我通过复制粘贴得到了它,并将其放入我恢复但 vba 为空的 excel 文件中。
7赞 SheetJS 10/8/2013 #12

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

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

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

带有空格。这避免了 CFB 容器尺寸问题。

13赞 user3761175 6/21/2014 #13

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

评论

1赞 Gimelist 10/27/2014
我可以确认这也适用于Excel 2010的.xlam文件。+1!
815赞 Đức Thanh Nguyễn 12/16/2014 #14

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

经过测试并适用于:

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项目并享受。

评论

1赞 ant1j 1/27/2016
这也适用于 PowerPoint 和文件.pptm.ppam
3赞 boogiehound 9/29/2016
在 Word 2016 中使用 docm 进行测试,效果很好!
9赞 Matthew Bond 11/21/2016
此代码在解锁VBA代码时可以完美运行,尽管每次我使用它时,它都会阻止我使用不同的密码重新保护项目,还有其他人遇到过这个问题吗?
7赞 B H 1/11/2018
我发现它破坏了 Excel 文件中的 VBA 项目,所以我不得不导出所有模块/类,然后将文件另存为 xlsx(非宏),然后关闭文件(愚蠢的 Excel),然后重新打开,然后导入模块并从类文件中复制代码。此时,我可以在VBA项目上使用自己的密码将文件另存为xlsm。
3赞 Chronocidal 5/19/2020
@thanos.a 只是创建一个新的工作簿(以便您打开 2 个),然后在其中创建模块?
221赞 kaybee99 6/23/2015 #15

我以 Đứ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
    

免責聲明这对我有用,我在这里记录了它,希望它能帮助到某人。我还没有完全测试过它。在继续此选项之前,请务必保存所有打开的文件。

评论

12赞 Erdne Htábrob 4/24/2020
我不确定为什么,但是当我在 Excel for 365 MSP 64 位 excel 上运行它时,它会关闭文件,当我重新启动它时,密码仍然存在。
0赞 thanos.a 4/28/2020
这不能再在 excel 中完成,因为上下文菜单中的选项是灰色的,因此您无法创建模块。
0赞 Timo 8/25/2020
@kaybee我知道我很紧张,但你能解释一下代码是做什么的,以及你是如何开发它并得到一个起点的吗?它看起来超级聪明。
3赞 FaneDuru 9/17/2020
看起来它不起作用。在 Excel 2016 Professional Plus 上测试。代码运行,它执行“某些操作”,但是在尝试查看 VBAProject 代码时 Excel 会崩溃。
3赞 Gr3go 10/19/2021
此代码似乎可以毫无问题地执行,但是当您查看 VBA 代码时,Excel 365 MSO (16.0.14326.20384) 64 位崩溃并自动重新启动,尝试打开相同的工作簿。该解决方案低于@VePe修改后的解决方案。
102赞 Matt 6/26/2015 #16

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

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

评论

13赞 LimaNightHawk 10/11/2016
曾在Excel 2016,Windows 10 64位工作。(XLSM 文件)
4赞 NBajanca 9/8/2017
曾在Word 2016,Windows 10 64位(dotm文件)中工作
11赞 nkatsar 6/20/2018
很棒的解决方案,在 Excel 2013 64 位中为我工作。如果您安装了 7-Zip,则可以跳过文件扩展名的更改。在这种情况下,您只需右键单击该文件并选择“7-Zip -> Open Archive”.zip.xlsm
1赞 Matt 11/15/2018
@ThierryMichel 结合以前的解决方案和反复试验!
1赞 thanos.a 4/28/2020
就我而言,它删除了密码并能够看到该对象,但是我被提示已删除 vba。我检查了我的代码,但它不在那里。
12赞 Luboš Suk 11/20/2015 #17

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

评论

1赞 PBD10017 4/17/2016
好!我认为您得到了一个反对票,因为您的解决方案解锁了工作表而不是 VBA 模块。尽管如此,我发现它很有帮助 - 所以谢谢!
1赞 Charles Byrne 4/19/2018
我有这个是我的个人工作簿。作者引用 Bob McCormick 作为原作者,后来由 Norman Harker 和 JE McGimpsey 修改,2002 年。
0赞 MS Berends 4/29/2021
替换为 Word 并且效果很好!ActiveWorkbookActiveDocument
0赞 Developer33 6/5/2017 #18

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

你看如下行;

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

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

评论

0赞 Noel Widmer 6/5/2017
你能解释一下你的答案为什么比已经提供的非常好的答案更好吗?
0赞 Developer33 6/6/2017
我的解决方案没有代码。所以非常紧凑的解决方案。
3赞 Daniel L. VanDenBosch 8/7/2019
您提供的此解决方案在 2019 年不起作用。
2赞 Edwin van der V 1/29/2018 #19

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

我采取的步骤:

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

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

评论

1赞 Starnes Student 5/19/2020
在最新版本的Excel 365中,我成功地在Windows 10上打开了旧的.xls,而不幸的是,顶部答案不再起作用。我下载了 HxD 并按照推荐的方式更改了最后一个字母,并跳过了错误。现在一切都好了,谢谢!
20赞 ashleedawg 2/10/2018 #20

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

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

步骤摘要:

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

此时,如果您愿意,您可以完全删除密码。

完整的说明以及我制作的“回到什么时候”的分步视频在 YouTube 上 这里.

令人震惊的是,这种解决方法已经存在多年,而Microsoft尚未解决该问题。


这个故事的寓意是什么?

Microsoft Office VBA 项目密码不能用于保护任何敏感信息。如果安全性很重要,请使用第三方加密软件。

评论

0赞 Puneet Sharma 5/2/2023
不要告诉微软这不好
1赞 Grez 4/8/2018 #21

如果您在其中工作,您可以尝试 VBAMacroExtractor。从中提取VBA脚本后,我找到了明文密码。Java.xlsm

116赞 VePe 11/18/2018 #22

编辑:这是已接受答案的更新版本,应该适用于更多办公版本。这很难,但让我们把这个答案放在首位!

轮到我了,这是建立在 kaybee99 的出色答案之上的,该答案建立在 Đức Thanh Nguyễn 的精彩答案之上,允许此方法适用于 32/64 位版本的 Office。

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

运作方式

  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
    

评论

6赞 Zin Min 5/30/2019
完善!使用 Windows Server 2016、Excel 2016 32 位
2赞 Ryan James 10/22/2019
这适用于 Excel Office 365 上的 .xlsm 文件。谢谢!
3赞 XavierAM 11/6/2019
在 2019 年仍然有效,Office 365 64 位最新版本,很棒的家伙!
1赞 emjaySX 1/21/2020
感谢您提供更新的代码,我在运行以前的版本(64 位)时遇到了崩溃,但您的版本一切正常
2赞 West 2/17/2022
完美工作。效率更高,比使用十六进制编辑器和 zip 文件更高效、更好
6赞 kunal Vyas 1/14/2021 #23

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

  1. 在 excel 文件名的末尾添加一个 .zip 并按 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 采取额外步骤

4赞 spicy.dll 1/13/2022 #24

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

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

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

oledump.py例子:

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

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'
...

旁边带有宏的流是宏,这是未加密的 VBA 代码M

提取流

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

这会将流中包含的代码输出到 。A3Module1.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"
}

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

0赞 Froodo 12/12/2022 #25

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

  1. 将xlsm个文件 转换为 zip
  2. 打开里面的 VBAProject.bin 文件(我更喜欢使用 Notepad++ (https://notepad-plus-plus.org/downloads/)
  3. 搜索 DPB 字段
  4. 将其替换为 DPx
  5. 保存文件
  6. 将 zip 文件转换为 xlsm
  7. 打开 Excel 文件
  8. 如果收到消息框,请单击“是”
  9. 为 VBA 项目属性设置新密码
  10. 关闭并再次打开文件
  11. 键入新密码以取消保护