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

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

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

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

是的,只要你使用的是.xls格式的电子表格(2003年以前Excel的默认格式)。对于Excel 2007以后,默认是.xlsx,这是一个相当安全的格式,这个方法将不起作用。

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

  1. 创建一个新的简单excel文件。
  2. 在VBA部分,设置一个简单的密码(例如- 1234)。
  3. 保存文件并退出。# EYZ0
  4. 用十六进制编辑器打开刚刚创建的文件。
  5. 复制以以下键开始的行:

    CMG=....
    DPB=...
    GC=...
    
  6. FIRST BACKUP the excel file you don't know the VBA password for, then open it with your hex editor, and paste the above copied lines from the dummy file.

  7. Save the excel file and exit.
  8. Now, open the excel file you need to see the VBA code in. The password for the VBA code will simply be 1234 (as in the example I'm showing here).

If you need to work with Excel 2007 or 2010, there are some other answers below which might help, particularly these: 1, 2, 3.

EDIT Feb 2015: for another method that looks very promising, look at this new answer by Đức Thanh Nguyễn.

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并浏览文件内容。

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

使用HxD,有一个计数器跟踪您选择了多少文件。从CMG开始复制,直到计数器读取8F(十六进制为143),同样地,当粘贴到锁定文件时-我最终在粘贴的末尾使用了两倍的“…”,这看起来有点奇怪,感觉几乎不自然,但它起作用了。

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

我希望这能有所帮助。

ElcomSoft生产高级办公室密码破解器高级办公室密码恢复产品,只要该文档是在Office 2007或更早版本中创建的,就可以适用于这种情况。

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

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

这是一段时间以前,所以如果这不仅仅是我的侥幸,它也可能已经被修补。

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

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

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

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

顺便说一句,如果你想知道这些字段的确切格式,他们现在有文档:

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

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

如果你的block of # EYZ0 如果您的“已知密码”文件比“未知密码”文件中的现有块短,请用后面的零填充您的十六进制字符串以达到正确的长度

如。

# EYZ0

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

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

我在office 2007中也使用过。xla(97/2003格式)文件。

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

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

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

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

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

对于Excel 2007,您需要将文件扩展名更改为。zip 在存档中有一个子文件夹xl,在那里你会发现vbaProject.bin。 使用vbaProject.bin执行上面的步骤,然后将其保存回存档中。 修改回您的扩展名和voilà!(意思是遵循上面的步骤)

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

测试和工作:

< p > Excel 2007 < br > Excel 2010 < br > Excel 2013 - 32位版本
Excel 2016 - 32位版本

寻找64位版本?看到# EYZ0

它是如何工作的

我会尽我最大的努力解释它是如何工作的-请原谅我的英语。

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

使用代码

请先备份您的文件!

  1. 打开包含您锁定的VBA项目的文件
  2. 创建一个新的xlsm文件,并将此代码存储在Module1的

    # EYZ0

    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. Paste this code under the above code in Module1 and run it

    Sub unprotected()
    If Hook Then
    MsgBox "VBA Project is unprotected!", vbInformation, "*****"
    End If
    End Sub
    
  4. Come back to your VBA Projects and enjoy.

我基于Đức Thanh nguynun的精彩回答,让这种方法适用于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. Paste this code in Module2 and run it

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

DISCLAIMER This worked for me and I have documented it here in the hope it will help someone out. I have not fully tested it. Please be sure to save all open files before proceeding with this option.

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

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

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

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

你看下面这条线;

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

(抱歉我的英语不好)

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

我采取的步骤:

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

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

VBA项目在Access、Excel、Powerpoint或Word文档上的密码(扩展名为.ACCDB .XLSM .XLTM .DOCM .DOTM .POTM .PPSM2007, 2010, 2013 or 2016版本)可以是< >强很容易删除< / >强

这只是一个简单的问题,更改文件名扩展名.ZIP,解压缩文件,并使用任何基本的十六进制编辑器(如XVI32) quot;break"现有的密码,“;混淆”;以便下次打开文件时提示输入新密码。

步骤总结:

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

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

完整的说明和我制作的“way back when”;的一步一步的视频在这里YouTube <强> < / >强上。

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


这个故事的寓意是什么?

Microsoft Office VBA项目密码not to be rely upon用于任何敏感信息的安全性。如果安全性很重要,请使用第三方加密软件。

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

轮到我了,这是建立在kaybee99的优秀答案之上的,这个答案是建立在Đức Thanh nguynun的出色答案之上的,允许这个方法在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. Paste this code in Module2 and run it

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

接受的答案在Windows 10上的Excel 2019中无法正常工作。找到了查看锁定宏所需的额外步骤。我正在总结步骤。

  1. 在excel文件名的末尾添加一个.zip,然后按enter键

  2. 一旦文件被更改为ZIP文件,双击它来打开它

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

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

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

  6. 查询以下文本 DPB =… 把它们改成 DPx =…< / p >

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

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

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

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

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

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

从以下站点采取额外步骤 # EYZ0 < / p >

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

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

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

# EYZ0例子:

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

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"
}

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