有没有一种方法可以破解Excel VBA项目的密码?

577

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

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


你能否将文件另存为 .xls 格式,而不是像你链接中的示例那样保存为 .xla 格式?不确定这是否会有所不同。 - B Hart
4
好的了解:xlsb对密码破解技巧具有强大的抵抗能力。 - Qbik
34
@Fandango68 这个问题在数年前的 meta 上已经讨论过了(https://meta.stackexchange.com/q/137086)。简而言之:SO上的很多(大多数?)问题都有可能被不良分子滥用,但除非有明确的不良行为证据,我们会假定其善意。破解VBA密码存在着合法和道德层面的原因。此外,讨论当前系统的弱点最终有助于提高未来的安全性并防止人们盲目地依赖不安全的系统。 - jmbpiano
3
对于那些偶然看到这篇文章的人,请注意你可以在 OpenOffice 中打开这个 Excel 文件,它会在不需要输入密码的情况下打开所有内容。 - Aditya Singh
25个回答

815

您可以尝试这种直接的VBA方法,它不需要HEX编辑。它适用于任何文件(*.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

    代码由越南开发者Siwtom(昵称)提供

    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中的上面代码下方并运行它
  3. Sub unprotected()
        If Hook Then
            MsgBox "VBA Project is unprotected!", vbInformation, "*****"
        End If
    End Sub
    
  4. 回到你的VBA项目并享受它。


1
这对于 PowerPoint 和 .pptm .ppam 文件也非常完美地工作。 - ant1j
3
在 Word 2016 中使用 docm 进行测试,完美运行! - boogiehound
9
这段代码可以完美解锁VBA代码,但每次使用后我无法使用另一个密码重新保护项目,其他人是否遇到过这个问题? - Matthew Bond
7
我发现这会损坏Excel文件中的VBA项目,所以我不得不导出所有的模块/类,然后将文件另存为xlsx格式(无宏),然后关闭文件(愚蠢的Excel),重新打开,再导入模块并从类文件复制代码。此时,我可以在VBA项目上设置自己的密码,将文件保存为xlsm格式。 - B H
3
你可以创建一个新的工作簿(这样你就有了两个打开的工作簿),并在其中创建该模块,如此即可。 - Chronocidal
显示剩余7条评论

228
是的,只要您使用的是 .xls 格式电子表格(默认为 Excel 2003 及以下版本),就有办法。但对于 Excel 2007 及以后版本,默认格式为 .xlsx,这种方法将无效。

就像 Treb 所说的那样,这是一种简单的比较方法。其中一种方法是仅需使用十六进制编辑器替换文件中的密码条目 (参见:Windows下的十六进制编辑器)。具体步骤如下:

  1. 创建一个新的简单的 Excel 文件。
  2. 在 VBA 部分设置一个简单密码(例如:1234)。
  3. 保存该文件并退出。然后,请检查文件大小 - 请参见 Stewbob's gotcha
  4. 使用十六进制编辑器打开刚刚创建的文件。
  5. 复制以以下键开始的行:
  6. CMG=....
    DPB=...
    GC=...
    
  7. 首先备份你不知道VBA密码的Excel文件,然后用十六进制编辑器打开它,并从虚拟文件中复制上面的行。

  8. 保存Excel文件并退出。
  9. 现在,打开你需要查看VBA代码的Excel文件。VBA代码的密码将简单地是1234(如我所示的例子)。

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

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


1
在空白的Excel文件中还是锁定的文件里?检查一下空白文件的大小。如果是已锁定的文件,请确保您的备份是安全的,然后尝试仅更改另外两行。确定它是加密文件吗? - Colin Pickard
6
Excel 2007 的密码保护(和文件格式)与 Excel 2003 大不相同。我在下面的回答中提供了一些具体信息。在我看来,Excel 2007 上的密码保护选项是微软办公套件历史上第一次生产出相对安全的文件。 - Stewbob
@tobriand 或者用空格替换现有字符 - SheetJS
1
我无法在Excel 2016新文件上设置VBA密码。有人可以简单地分享用于替换1234的HEX吗?或者它会因机器而异? - Mescalito
1
这种方法对我在一个.xlsm文件上起作用。我将其保存为.xls,然后进行了此操作,最后将其转换回.xlsm。需要注意的是,如果新的“CMG...”字符串比原始字符串更长,您可以安全地增加文件的长度。 - Drew Chapin
显示剩余8条评论

221

我在Đứ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
将此代码粘贴到 Module2 中并运行它
Sub unprotected()
    If Hook Then
        MsgBox "VBA Project is unprotected!", vbInformation, "*****"
    End If
End Sub

免责声明 这对我有用,我在这里记录下来以希望能帮助到某些人。 我还没有完全测试过它。 在执行此选项之前,请务必保存所有打开的文件。


12
我不确定为什么,但当我在Excel上运行365 MSP 64位时,它会崩溃并关闭文件。当我重新启动后,密码仍然存在。请问是否可以翻译其他内容? - Erdne Htábrob
3
似乎它不起作用。在Excel 2016专业增强版上进行了测试。代码运行,做了“某些事情”,但是当尝试查看VBAProject代码时,Excel会崩溃。 - FaneDuru
3
这段代码似乎可以正常执行,但是当您尝试查看VBA代码时,Excel 365 MSO (16.0.14326.20384) 64位崩溃并自动重启,试图打开相同的工作簿。解决方案在@VePe修改后的解决方案下面。 - Gr3go
我刚在Excel 365上执行了这个操作,确实成功了,密码被移除了。 - undefined
这对我在Excel 365上有效。只需注意它说“创建新的xlxm文件”的位置,然后打开受保护的文件和新文件,按Alt+F11进入VBA窗口,在新文件上按照指示创建Module1和Module2。如果你尝试在受保护的文件上这样做,创建模块的选项将被禁用,但在新文件上不会。然后运行“取消保护”程序,Excel会崩溃。然后返回并打开受保护的文件,按Alt+F11打开代码,哇!现在你可以看到代码,因为它现在是未受保护的。谢谢keybee99。 - undefined
显示剩余6条评论

184

还有一种(相对容易)的解决方案,没有大小问题。我今天使用了这种方法(在一个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会报告错误(意外错误),然后当您访问VBA模块列表时,您现在将看到源模块的名称,但在尝试打开表单/代码等时会收到另一个错误。要解决此问题,请返回VBA项目属性,并将密码设置为新值。保存并重新打开Excel文档,您应该就可以继续使用了!


3
很遗憾,对于我所使用的Excel for Mac 2011 v14.2.5无效。我得到了修复文件而非重置密码的选项,结果是丢失了所有的VBA脚本。 - Joe Carroll
4
我刚刚尝试了一下(.xls,Excel 2007),但没有成功。结果是:模块是可见的,代码似乎确实能够运行,但当打开一个模块时,会出现“意外错误(40230)”的提示。 - KekuSemau
3
同样的错误在这里(Excel 2010) - 但后来我意识到我跳过了 Pieter 的“设置新密码并保存/重新打开”(第7-9步骤)。 - Owen B
这个方法是在 Excel 2013 上使用的,在 .xls 文件上。我不记得很多年前我用过它的 Office 版本是什么了。当我第一次打开文件(步骤4)时,宏内容被禁用了。启用后,我收到了几条“意外错误”信息。我点了所有的消息,然后按照其他步骤操作。保存文件后似乎可以正常工作。 - Leo
1
尝试过了,出现了“意外错误(40230)”,阅读了评论,看到@OwenB的评论,扇了一巴掌,保存了……它奏效了 :) Excel 2021,这个解决方法仍然有效。谢谢! - frarugi87
显示剩余8条评论

116

编辑:这是已被接受答案的更新版本,可适用于更多版本的 Office。虽然很困难,但让我们把这个答案排到最前面!

借用 kaybee99 出色的答案和 Đức Thanh Nguyễn 极好的答案,我要进行改进,以便此方法可用于 Office 的32/64位版本。

更改的概述,我们避免使用限制在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
  • 将此代码粘贴到Module2中并运行

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

    6
    完美!适用于 Windows Server 2016、Excel 2016 32 位。 - Zin Min
    2
    这个在Excel Office 365的.xlsm文件上运行成功了。谢谢! - Ryan James
    3
    2019年仍可使用,Office 365 64位最新版本,太棒了! - XavierAM
    1
    这适用于我在 Windows 10 下使用带有数字签名的 VBA 项目。解锁后,我打开了 VBA 项目设置并启用了“无需密码查看”功能,然后保存了 .xlsm 文件(这样可以避免每次都需要从第二个工作表解锁)。 - Oliver
    2
    完美运行。比使用十六进制编辑器和压缩文件更高效,更好。 - West
    显示剩余9条评论

    102
    对于一个.xlsm.dotm文件类型,你需要以稍微不同的方式来完成。
    1. .xlsm文件的扩展名更改为.zip
    2. 使用WinZip或WinRar等软件打开.zip文件并转到xl文件夹。
    3. 提取vbaProject.bin文件,并在十六进制编辑器中打开它(我使用 HxD,完全免费且轻巧)。
    4. 搜索DPB并替换为DPx,然后保存该文件。
    5. 用这个新的vbaProject.bin文件替换压缩文件中的旧文件。
    6. 将文件扩展名改回.xlsm
    7. 打开工作簿,跳过警告信息。
    8. 在Excel中打开Visual Basic。
    9. 转到 工具 > VBA项目属性 > 保护选项卡。
    10. 输入新密码并保存.xlsm文件。
    11. 关闭并重新打开文件,您的新密码将起作用。

    13
    使用 Excel 2016,在 Windows 10 64位操作系统下工作。(xlsm 文件) - LimaNightHawk
    4
    在Word 2016和Windows 10 64位操作系统中工作(.dotm文件)。 - NBajanca
    11
    很好的解决方案,在我的 Excel 2013 64 位版本上有效。如果你已经安装了 7-Zip ,可以跳过将文件扩展名更改为 .zip 的步骤。在这种情况下,您只需右键单击 .xlsm 文件,然后选择 “7-Zip->打开归档文件” - nkatsar
    1
    在我的情况下,它移除了密码并能够查看对象,但是我收到提示说 VBA 已被移除。我检查了我的代码,但它不在那里。 - thanos.a
    1
    似乎无法与 Microsoft 365 企业版 Excel 应用程序配合使用。 - David Metcalfe
    显示剩余12条评论

    70

    Colin Pickard在这个问题上给出了一个很好的答案,但是有一点需要注意。存在某些情况(我还没有找出原因),文件中“CMG=........GC=....”条目的总长度会因excel文件而异。在某些情况下,该条目的长度为137个字节,在其他情况下,它将是143个字节。137个字节长度是比较奇怪的,如果您使用“1234”密码创建文件时发生这种情况,请重新创建另一个文件,然后它应该会跳到143个字节的长度。

    如果您尝试将错误数量的字节粘贴到文件中,则在尝试使用Excel打开文件时,您将失去VBA项目。

    编辑

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

    但是,当您使用RSA加密来保护Excel 2007文件时,整个.zip(.xlsx)文件都被加密。无法再将扩展名更改为.zip并浏览文件内容。


    然后,您需要使用标准的压缩文件破解工具。这已经不再是“如何备份Excel文件”的问题了。 - Anonymous Type
    3
    @匿名类型:我认为破解工具对此无济于事。据我理解,Stewbob所说的不是压缩文件中的文件条目被加密,而是整个压缩文件本身都被加密,包括头部和中央目录。 - Treb
    2
    只是好奇:我只输入一个密码(对称密码),这怎么可能是RSA? - kizzx2
    当你想要进入的文件具有较短的密钥时怎么办?只需不断创建VBA文档,直到找到一个具有137个字符的文档即可。 - onlynone
    1
    你确定在锁定VBA项目时整个zip文件都被加密了吗?我仍然可以打开zip文件并查看文件结构...子文件夹xl\包含文件vbaProject.bin,其中有熟悉的“CMG=...GC=”哈希块。 - Nigel Heffernan

    34

    值得指出的是,如果你有一个Excel 2007 (xlsm)文件,那么你可以将其另存为Excel 2003 (xls)文件,然后使用其他答案中概述的方法。


    4
    那不是真的,我曾经处理过一些文件,无法从xlsm格式转换为xls/xla格式,尝试使用Excel 2007和2010进行转换时每次都会崩溃,我尝试了多个实例,出现了一个错误信息 - Kod wyjątku: c0000005 Przesunięcie wyjątku: 005d211d。 - Qbik
    4
    可以的,我已经做过很多次了。如果有一些在表格上必要但没有转移到旧版本中的东西,我会按照以下步骤操作:**1.** 将 .xlsm 文件转换为 .xls 文件 2. 破解 .xls 文件的代码 3. 将 .xlsm 文件转换为 .xlsx 文件 4. 将模块中的代码从 .xls 复制到 .xlsx 文件中并将其另存为 .xlsm 文件。 - ZygD
    在答案中将xlsm转换为xls后,它可以正常工作。 - Purus

    21

    Access、Excel、PowerPoint或Word文档的VBA项目密码(2007、2010、2013或2016版本,扩展名为.ACCDB .XLSM .XLTM .DOCM .DOTM .POTM .PPSM)可以被轻松地移除

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

    步骤概述:

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

    此时,如果需要,您可以完全删除密码。

    完整说明和我创建的逐步视频(“很久以前”)在YouTube这里。请注意,所有HTML标签仍然保留。

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


    故事的寓意?

    微软Office VBA项目密码不应被视为任何敏感信息的安全保障。如果安全很重要,请使用第三方加密软件。


    不要告诉微软这不好。 - Puneet Sharma

    17

    你尝试过在OpenOffice.org中打开它们吗?

    我以前也遇到过类似的问题,发现Excel和Calc无法理解彼此的加密,因此可以直接访问几乎所有内容。

    这是一段时间以前的事情,如果那不仅仅是我的偶然情况,那么它也可能已经修复了。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接