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


485

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

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


如链接中的示例所示,您是否能够另存为.xls而不是.xla?不知道这是否会有所作为。
哈特

4
众所周知:xlsb具有强大的密码破解技巧
Qbik

19
@ Fandango68 几年前在meta上讨论了这个问题。TLDR:关于SO的很多(大多数?)问题可能会被不良行为者滥用,但是除非有明显的不当行为证据,否则我们将秉承真诚。破解VBA密码有很多合法的法律和道德理由。此外,讨论当前系统的弱点最终有助于将来改善安全性,并阻止人们盲目地依赖现在不安全的系统。
jmbpiano

Answers:


698

您可以尝试这种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项目并享受。


4
@克里斯,你绝对正确。因为在此代码中为Win 32定义了Windows API函数。
Đức清阮

8
一些解释将很好地说明这是如何工作的。
丹尼斯·G

20
现在剩下的唯一问题(在看到这种令人印象深刻的方法完美工作之后)是如何使我的VBA项目得到更强大的保护,以防止其他人对它使用此技术:)
EranG

6
尽管每次使用此代码都可以使该代码完美地解锁VBA代码,但它使我无法使用不同的密码重新保护该项目,还有其他人遇到此问题吗?
马修·邦德

2
我发现它破坏了Excel文件中的VBA项目,因此我不得不导出所有模块/类,然后将文件另存为xlsx(非宏),然后关闭文件(愚蠢的Excel),然后重新打开,然后导入模块并从类文件复制代码。此时,我可以使用自己的密码在VBA项目上将文件另存为xlsm。
BH

217

是的,只要您使用.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月:对于另一种看似很有希望的方法,请看ĐứcThanhNguyễn的新答案


如果没有以CMG = ...开头的行怎么办?
systemovich

1
在空白的excel文件中,还是在锁定的文件中?检查空白文件的文件大小。如果该文件处于锁定状态,请确保您的备份是安全的,然后尝试仅更改其他两行。您确定它是加密文件吗?
科林·皮卡德

6
Excel 2007密码保护(和文件格式)与Excel 2003根本不同。我在下面的回答中包括了一些有关它的细节。我认为,Excel 2007文件上的受密码保护的选项是Microsoft Office历史上首次产生合理安全的文件。
Stewbob 2010年

1
我无法在excel 2016新文件上设置vba密码。有人可以简单地共享十六进制以替换1234吗?还是可以随机器改变?
Mescalito '16

1
这种方法对.xlsm文件有效。我将其另存为.xls,执行了此操作,然后将其转换回.xlsm。请注意,如果新CMG...字符串比原始字符串长,则可以安全地增加文件的长度。
德鲁·查平

173

我基于ĐứcThanhNguyễ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

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


1
我不确定为什么,但是当我在365 MSP 64位excel的Excel上运行此命令时,它会关闭文件,当我重新启动它时,密码仍然存在。
eborbath

由于上下文菜单中的选项显示为灰色,因此无法在excel中完成此操作,因此无法创建模块。
thanos.a

170

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

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

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


3
不幸的是,这不适用于Excel for Mac 2011 v14.2.5。我可以选择修复文件,而不用重设密码,结果丢失了所有VBA脚本。
乔·卡罗尔

完美的解决方案-我使用HxD十六进制编辑器使用2003文件完成了此操作
Chris W

4
我只是尝试了一下(.xls,Excel 2007),但是没有用。结果是:模块可见,代码确实确实有效,但是在打开模块时,它显示意外错误(40230)
KekuSemau

2
同样的错误(Excel 2010)-但后来我意识到我跳过了Pieter的“设置新密码并保存/重新打开”(步骤7-9)。
Owen B

+1此方法也适用于我们开发不良的访问(.mdb)文件!现在,我们可以使事情变得更好,谢谢!
Er Gabriel Doronila 2014年

65

科林·皮卡德(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并浏览文件内容。


然后,您需要使用标准的zip黑客工具。它不再是“如何备份Excel文件”的问题。
匿名类型

3
@匿名类型:我认为一个zip破解工具将无济于事。据我了解,Stewbob并不是加密的zip文件中的文件条目,而是整个zip文件本身,其中应包括标题和中央目录。
Treb 2010年

2
只是好奇:当我只输入一个密码(对称)时,怎么可能是RSA?
kizzx2'2

如果要进入的文件具有较短的密钥,该怎么办?只是继续创建vba文档,直到获得包含137个文档的文档?
onlynone 2015年

1
您确定在锁定VBA项目时确定对整个zipfile进行了加密吗?我仍然可以打开zipfile并查看文件结构。...子文件夹xl \包含文件vbaProject.bin,该文件 具有熟悉的“ CMG = ... GC =”哈希块。
Nigel Heffernan

63

对于.xlsm.dotm文件类型,您需要使用稍微不同的方法。

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

8
在Excel 2016,Windows 10 64bit中工作。(xlsm档案)
LimaNightHawk

3
在Word 2016,Windows 10 64bit(dotm文件)中工作
NBajanca

7
很棒的解决方案,在Excel 2013 64位环境中为我工作。.zip如果安装了7-Zip,则可以跳过文件扩展名的更改。在这种情况下,您可以右键单击.xlsm文件,然后选择“ 7-
Zip-

适用于Word 2013,win7x64。(这是非常可悲的,很容易被骗去相信代码在某种程度上是安全的)。
Berry Tsakala

1
@ThierryMichel以前的解决方案与反复试验的结合!
马特

35

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


4
事实并非如此,我使用的文件无法从xlsm转换为xls / xla,Excel 2007和2010每次都崩溃,我曾尝试过一种错误消息中的各种实例-Kodwyjątku:c0000005Przesunięciewyjątku: 005d211d
Qbik 2014年

4
是的,您可以做到。我已经做了很多次了。如果工作表上有某些必要的东西,并且没有转移到旧版本,请执行以下操作:1.将.xlsm转换为.xls会2.破解.xls 的代码3.将.xlsm转换为.xlsx会将4.代码从.xls中的模块放入。 xlsx并将其另存为.xlsm
ZygD 2015年

如答案所示,将xlsm转换为xls后,它可以工作。
Purus

31

轮到我了,这是基于kaybee99的出色答案而建立的,它基于ĐứcThanhNguyễn的出色答案,使该方法可以同时用于x86和amd64版本的Office。

关于更改的概述,我们避免将push / ret限制为32位地址,而将其替换为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

3
完善!与Windows Server 2016的Excel 2016的32位工作
寻民

这适用于Excel Office 365上的.xlsm文件。谢谢!
瑞安·詹姆斯

仍然可以在2019年使用,Office 365 64位最新版本已构建,非常棒!
XavierAM

感谢您提供的更新代码,我在运行早期版本(64位)时
遇到


17

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

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

这是前一阵子,因此,如果这不只是我的fl幸,那它也可能已被修补。


15

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


1
这是可行的,但是正如我最近发现的(在上面评论),您也可以在GC =“ ...”块中的最终结束引号之后简单地添加空字符,直到达到相同的长度。
tobriand

13

从Excel 2007开始,您需要将文件扩展名更改为.zip。在存档中,有一个子文件夹xl,在该文件夹中将找到vbaProject.bin。对vbaProject.bin执行上述步骤,然后将其保存回存档中。修改回您的扩展名和名字!(表示按照上述步骤操作)


1
我也可以使用Excel 2010确认此方法适用于.xlam文件。+1!
Gimelist,2014年

12

可以轻松删除 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编辑器,然后在Project Explorer中右键单击以选择VBA Project Properties
  • Protection选项卡上,设置新密码。
  • 单击“开始” OK,关闭文件,重新打开它,然后按ALT + F11。
  • 输入您设置的新密码。

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

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

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


这个故事的主旨?

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


9

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

顺便说一句,如果您想知道这些字段的确切格式,请立即进行记录:

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


2
以下链接提供了有关XSLM格式文件的详细信息。gbanik.blogspot.co.uk/2010/08/…该解决方案与上述Yuhong Bao概述的解决方案相同,但有趣的是,其中包括屏幕截图。
JohnLBevan

7

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

对于XLS格式,可以遵循本文中的其他一些方法。我个人更喜欢搜索DPB=块并替换文本

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

与空格。这消除了CFB容器大小的问题。


7

我尝试了上面的一些解决方案,但没有一个适合我(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
真好!我认为您一票赞成,因为您的解决方案解锁了工作表而不是VBA模块。不过,我发现它很有帮助-非常感谢!
PBD10017 '16

1
我把它作为我的个人工作簿。作者引用了鲍勃·麦考密克作为原始作者,后来由诺曼·哈克(Norman Harker)和JE·麦金普西(JE McGimpsey)于2002
查尔斯·伯恩


4

汤姆(Tom)-我最初是因为出现了一个男生错误,因为我没有看到字节大小,而是从“ CMG”设置中复制并粘贴到后续条目。但是,这是两个文件之间的两种不同的文本大小,就像Stewbob警告的那样,我丢失了VBA项目。

使用HxD,有一个计数器跟踪您选择的文件数量。从CMG开始复制,直到计数器读取8F(十六进制为143),然后粘贴到锁定文件时也是如此-我最终在粘贴末尾添加了两倍于“ ...”的数字,看起来有点奇怪,几乎感觉到了不自然,但确实有效。

我不知道它是否很关键,但是在重新在Excel中打开文件之前,我确保关闭了十六进制编辑器并关闭了excel。然后,我不得不浏览菜单以打开VB编辑器,进入VBProject属性,然后输入“新”密码来解锁代码。

我希望这有帮助。


4

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


我已经测试过这个工具,并且效果很好,但是免费版本检索了前53行。要恢复我的文件,我必须按照Andy的指示解锁密码。然后,我在两个窗格中都使用VbaDiff打开了xlsm,然后单击包含代码的工作表。我通过复制粘贴将其放入并恢复到已恢复但vba空的excel文件中。
thanos.a

2

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


1

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

我采取的步骤:

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

希望对您有所帮助!


我成功在Windows 10的最新版本的Excel 365中使用它成功打开了一个旧的.xls,但是不幸的是,最重要的答案不再起作用了。我下载了HxD,并像建议的那样更改了最后一个字母,并跳过了错误。现在一切都很好,谢谢!
Starnes Student

0

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

您会看到下面的线条;

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

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


您能解释一下您的答案比已经提供的很好的答案如何吗?
Noel Widmer

我的解决方案没有代码。因此非常紧凑的解决方案。
Developer33

1
您提供的解决方案在2019
。– Daniel L. VanDenBosch

在Office 365中
它对

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.