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

发布时间 2023-11-09 09:43:44作者: 小满独家

内容来自 DOC https://q.houxu6.top/?s=有没有一种方法可以破解Excel VBA项目的密码?

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

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


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

经测试可用于:

Excel 2007

Excel 2010

Excel 2013 - 32位版本

Excel 2016 - 32位版本

想要64位版本?请参考这个答案

工作原理

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

  1. VBE(Visual Basic Editor)会调用一个系统函数来创建密码对话框。
  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

  1. 将下面的代码粘贴到Module1中上面的代码之后,并运行它。
Sub unprotected()
    If Hook Then
        MsgBox "VBA项目已取消保护!", vbInformation, "\*\*\*\*\*"
    End If
End Sub

  1. 返回到您的VBA项目并享用吧。