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

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

评论

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

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

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

#1 楼

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

经过测试并可以在以下软件上使用:


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


是否正在寻找64位版本?查看此答案

它是如何工作的

我将尽力解释它的工作原理-请原谅我的英语。


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

使用代码

请先备份文件!


打开包含锁定的VBA项目的文件

创建一个新的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



粘贴此代码并在Module1中的上述代码下运行,并运行它。

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


回到您的VBA项目并享受。


评论


@克里斯,你绝对正确。因为在此代码中Windows API函数是为win 32定义的。

– ThanhNguyễn
2015年2月25日在21:21

一些解释将很好地说明这是如何工作的。

–丹尼斯G
15年3月21日在12:53

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

– EranG
16年1月25日在12:01

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

–马修·邦德
16年11月21日在12:49

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

– B H
18年1月10日在16:25

#2 楼

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

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


创建一个新的简单excel文件。
在VBA部分中,设置一个简单密码(例如-1234)。
保存文件然后退出。然后检查文件大小-请参见Stewbob的问题

使用十六进制编辑器打开您刚创建的文件。

复制以以下键开头的行:

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


首先备份您不知道VBA密码的excel文件,然后使用十六进制编辑器将其打开,然后从虚拟文件中粘贴上面复制的行。
保存excel文件并退出。
现在,打开需要查看VBA代码的excel文件。VBA代码
的密码将仅为1234(如我在此处显示的示例所示) )。

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

EDIT Feb 2015年:对于另一种看似很有希望的方法,请看ĐứcThanhNguyễn提出的新答案。

评论


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

–杰弗里
09年9月2日于13:03

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

–科林·皮卡德(Colin Pickard)
09年9月2日于13:43

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

– Stewbob
2010-09-10 17:42

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

– Mescalito
16-2-28在23:58

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

–德鲁·查平(Drew Chapin)
16年5月10日在16:33

#3 楼

我基于ĐứcThanhNguyễn的绝妙答案,允许该方法与Excel的64位版本一起使用。我正在64位Windows 7上运行Excel 2010 64位。


打开包含锁定的VBA项目的文件。

创建一个新的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



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

评论


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

– eborbath
4月24日10:35

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

–thanos.a
4月27日22:08

@kaybee我知道我很紧张,但是您能解释一下代码的功能以及如何开发它并获得一个起点吗?看来超级聪明。

– Timo
8月25日5:56



看来它不起作用。在Excel 2016 Professional Plus上测试。该代码运行,它执行“某些操作”,但是当尝试查看VBAProject代码时,Excel崩溃了。

–FaneDuru
9月16日17:08

@ thanos.a正如您在发布相同评论的另一个答案中已经提到的,您可以在同时打开的另一个Excel工作簿中创建VBA模块。

– TylerH
12月7日18:28

#4 楼

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


备份xls文件
在HEX编辑器中打开文件并找到DPB=...部分
DPB=...字符串更改为DPx=...

在Excel中打开xls文件
打开VBA编辑器(ALT + F11)

Excel发现无效密钥(DPx)并询问您是否要继续加载该项目(基本上不考虑保护)
您将能够覆盖密码,因此将其更改为您可以记住的名称
保存xls文件*
关闭并重新打开文档即可进行操作VBA magic!

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

评论


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

–乔·卡洛尔
2012年12月15日上午10:49

完美的解决方案-我使用HxD Hex Editor处理了2003文件

–克里斯·W
13年2月4日在14:26

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

– KekuSemau
13年6月22日在17:07

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

–欧文B
13年8月15日在11:08

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

–E-r Gabriel Doronila
2014年6月6日5:34



#5 楼

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


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


评论


在Excel 2016,Windows 10 64bit中工作。 (xlsm文件)

– LimaNightHawk
16-10-11在13:16

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

– NBajanca
17年9月8日在13:11

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

– nkatsar
18年6月20日在9:31

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

–马特
18-11-15在9:36

就我而言,它删除了密码并能够看到该对象,但是提示我vba已删除。我检查了我的代码,它不在那里。

–thanos.a
4月27日22:19

#6 楼

科林·皮卡德(Colin Pickard)有一个很好的答案,但是对此有一个“警惕”。在某些情况下(我还没有找到原因),文件中“ CMG = ........ GC = ....”条目的总长度与一个excel文件不同。下一个。在某些情况下,该条目将为137个字节,在其他情况下将为143个字节。 137个字节的长度是奇数,如果在使用“ 1234”密码创建文件时发生这种情况,则只需创建另一个文件,它应跳到143个字节的长度。

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

EDIT

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

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

评论


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

–匿名类型
2010-09-27 22:37

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

–特雷布
2010-09-28 6:58

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

– kizzx2
2011年2月2日在18:58

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

–onlynone
2015年10月5日,19:43

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

–奈杰尔·赫弗南(Nigel Heffernan)
17-10-19在15:10



#7 楼

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

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

经过测试,可以在


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


工作原理


打开包含已锁定的VBA项目的文件。

创建与上述类型相同的新文件,并将此代码存储在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




评论


完善!使用Windows Server 2016,Excel 2016 32位

–振民
19年5月30日在10:26

这适用于Excel Office 365上的.xlsm文件。谢谢!

–瑞安·詹姆斯(Ryan James)
19-10-21在19:04

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

– Xavier
19年11月6日在13:58

感谢更新的代码,我在运行以前的版本(64位)时遇到崩溃,但是对于您的版本来说一切都很好

–emjaySX
1月20日23:21

它在Office 365中不起作用,因为他们已停用上下文菜单,因此您不能插入新模块。

–thanos.a
4月27日22:21

#8 楼

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

评论


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

– Qbik
2014年6月17日在7:02



是的,您可以做到。我已经做了很多次了。如果页面上有必要的东西,并且没有转移到旧版本,我可以这样做:1.将.xlsm转换为.xls 2.破解.xls的代码3.将.xlsm转换为.xlsx 4.将代码从.xls中的模块到.xlsx并将其另存为.xlsm

–ZygD
2015年10月1日在18:45



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

–普鲁斯
17年2月3日在7:08

#9 楼

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

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

这是前一段时间,因此,如果这不只是我的uke幸,那它也可能已被修补。

#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"以保留文件长度。

我也曾在Office 2007中处理.XLA(97/2003格式)文件。

评论


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

–tobriand
13年7月20日在11:21

#11 楼

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

评论


我也可以使用Excel 2010确认该方法适用于.xlam文件。 +1!

–Gimelist
14-10-27在14:17

#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并用十六进制编辑器打开
将“ DPB”更改为“ DPX”,“搜索并替换”以“全部替换”。
保存更改,将.bin文件放回zip文件,将其恢复为正常扩展名,然后像正常一样打开文件。
ALT + F11进入VB编辑器,然后在Project Explorer中右键单击以选择VBA Project Properties
Protection选项卡上,设置新密码。
单击q 4312079q,关闭文件,重新打开,然后按ALT + F11。
输入您设置的新密码。此时,您可以选择完全删除密码。

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

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



故事的寓意是什么?

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


#13 楼

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

评论


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

–JohnLBevan
2012年7月19日在10:51

#14 楼

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


评论


真好!我认为您一票赞成,因为您的解决方案可以解锁工作表而不是VBA模块。不过,我发现它很有帮助-非常感谢!

– PBD10017
16年4月16日在18:05

我将其作为我的个人工作簿。作者引用了鲍勃·麦考密克(Bob McCormick)作为原作者,后来由诺曼·哈克(Norman Harker)和JE·麦金普西(JE McGimpsey)于2002年修改。

–查尔斯·伯恩(Charles Byrne)
18年4月18日在19:53

#15 楼

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

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

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


替换为空格。这样可以避免CFB容器尺寸问题。

#16 楼

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

#17 楼

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

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

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

希望对您有所帮助。

#18 楼

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

评论


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

–thanos.a
4月27日22:40

#19 楼

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

#20 楼

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

我执行的步骤:


在十六进制编辑器(例如XVI)中打开vba
在此DPB上搜索
将DPB更改为DPX之类的其他内容
保存它!
重新打开.xla,将出现一条错误消息,请继续。
您现在可以更改.xla的密码。通过打开属性并转到“密码”标签。

希望对您有所帮助!

评论


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

– Starnes学生
5月19日9:53



#21 楼

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

您会看到下面的一行;

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


(对不起我的英语不好)

评论


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

–诺埃尔·威德默(Noel Widmer)
17年5月5日在11:09

我的解决方案没有代码。所以非常紧凑的解决方案。

– Developer33
17年6月6日在11:32

您提供的此解决方案在2019年不起作用。

–丹尼尔·范登博斯(Daniel L. VanDenBosch)
19年8月7日在14:27

#22 楼

如果您在Java中工作,则可以尝试VBAMacroExtractor。从.xlsm提取VBA脚本后,我发现密码以明文形式存在。