LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

如何把Excel的VBA程序封装成DLL并分发给他人使用

admin
2024年9月17日 22:40 本文热度 546
虽然VBA程序加了密码使程序代码不可见,但这也很容易被破解。网上一查,果然有一段VBA代码写了如何破解Excel里的VBA密码。破解的方法是新建一个Excel文件,用开发工具创建一个模块,只要把下面这段代码写到这个模块里,然后打开待破解的带宏程序的Excel文件,运行下面代码中的PasswordCracking()方法,就可以把待破解的宏程序密码去除。

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
Private Sub RecoverBytes()
   If Flag Then MoveMemory ByVal pFunc, ByVal VarPtr(OriginBytes(0)), 12
End Sub
Private 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
Sub PasswordCracking()
   If Hook Then
       MsgBox "VBA Project password protection has been removed.", vbInformation, "Password Cracking"
   Else
       MsgBox "No encryption VBA Project found.", vbInformation, "Password Cracking"
   End If
End Sub
对于solidworks的VBA程序也有其他工具可以轻松破解,无论是多长多复杂的密码,都能轻松破解。为了保护程序代码,必须另辟蹊径,使用封装DLL的方法可能是其中一个选择。下面就以最简单的实例说明如何制作dll文件,并在Excel里使用。
首先,在Visual Studio里创建一个VB类库项目,如下图所示。注意选择的是含有.NET Framework、VB和Windows这三个特征的那种类库,不要选成“通用windows”类库。项目名称可使用默认的ClassLibrary1,当然也可以自行命名。

创建好项目后,程序自动打开项目,可在资源管理器里看到当前项目已自动创建了一个类Class1。右键选中这个Class1,删除它。

在资源管理中再用右键选中项目名称,选择“添加”-->"类",在弹出的选项里选择“COM类”,这时就自动创建了一个名为COMClass1的类,并自动生成了如下的代码:
<ComClass(ComClass1.ClassId, ComClass1.InterfaceId, ComClass1.EventsId)> _
Public Class ComClass1

#Region "COM GUID"
   ' 这些 GUID 提供此类的 COM 标识
   ' 及其 COM 接口。若更改它们,则现有的
   ' 客户端将不再能访问此类。
   Public Const ClassId As String = "9bc632f6-cb98-40dd-809d-584ac35f7dd9"
   Public Const InterfaceId As String = "09b8d875-d7b9-4531-9634-65b97fe76177"
   Public Const EventsId As String = "3a401de1-af99-4f46-9347-c1fc9298a453"
#End Region

   ' 可创建的 COM 类必须具有一个不带参数的 Public Sub New()
   ' 否则, 将不会在
   ' COM 注册表中注册此类,且无法通过
   ' CreateObject 创建此类。
   Public Sub New()
       MyBase.New()
   End Sub

End Class
我们需要在这个类里添加自己的方法,但是不能删除原有的代码,下面添加一个方法Test,用于计算2个整数相加,代码改成下面这样:
<ComClass(ComClass1.ClassId, ComClass1.InterfaceId, ComClass1.EventsId)> _
Public Class ComClass1

#Region "COM GUID"
   ' 这些 GUID 提供此类的 COM 标识
   ' 及其 COM 接口。若更改它们,则现有的
   ' 客户端将不再能访问此类。
   Public Const ClassId As String = "9bc632f6-cb98-40dd-809d-584ac35f7dd9"
   Public Const InterfaceId As String = "09b8d875-d7b9-4531-9634-65b97fe76177"
   Public Const EventsId As String = "3a401de1-af99-4f46-9347-c1fc9298a453"
#End Region

   ' 可创建的 COM 类必须具有一个不带参数的 Public Sub New()
   ' 否则, 将不会在
   ' COM 注册表中注册此类,且无法通过
   ' CreateObject 创建此类。
   Public Sub New()
       MyBase.New()
   End Sub
   Public Function Test(ByVal a As Integer, ByVal b As Integer) As Integer
       Test = a + b
   End Function
End Class
程序写完后,在Visual Studio的主菜单里选择“生成”-->"生成ClassLibrary1",(可能会要求以管理员身份打开Visual Studio才可以生成),ClassLibrary1是默认的项目名称,根据你所取的项目名称不同,这个子菜单名称也会不同。此时在项目目录下的bin\debug文件夹中就生成了ClassLibrary1.dll文件和ClassLibrary1.tlb文件。
此时,新建一个Excel文件,打开开发工具,新建一个Visual Basic模块,在编辑器的主菜单中选择“工具”-->"引用"就可以看到ClassLibrary1已经被添加到引用里,勾选ClassLibrary1,如下图。

在Excel的模块里写下调用方法,如下:
Sub main()
   Dim cls As New ComClass1
   Debug.Print cls.Test(10, 20)
End Sub
至此,程序在本机运行完全没问题了。但是把Excel保存成xlsm文件后复制到其它电脑运行,却是报错的。原因是找不到ClassLibrary1.tlb这个文件,即使我们把这个文件也复制过去,仍然是报错,这是因为这个自定义的dll文件没有在这台电脑里注册过。为什么在其它电脑没注册就不可以使用,在自己电脑同样也没注册却可以使用?这是因为在用Visual Studio编译程序时,Visual Studio已经自动注册了这个dll,这也是为什么要求用管理员身份运行Visual Studio才可以编译程序的原因。那么在其它电脑该如何注册dll文件呢。
首先,要新建一个注册批处理文件regist.bat,用记事本或其它文本编辑器在regist.bat里写下如下代码:
set p=ClassLibrary1
set w=C:\Windows\
copy =%~dp0%p%.dll %w%%p%.dll
C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe %w%%p%.dll /tlb:%w%%p%.tlb /codebase
pause
上面这段批处理文件的意思是,先将当前目录下(%~dp0%就表示当前批处理文件所在目录)的ClassLibrary1.dll文件复制到C:\windows\目录下,然后调用C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe程序,注册ClassLibrary1.dll文件,同时在C:\windows\里生成一个ClassLibrary1.tlb文件。
批处理文件写好后,把ClassLibrary1.dll文件和批处理文件regist.bat放在同一个文件夹里。用管理员身份运行regist.bat文件,完成dll文件注册。
此时再打开带有宏程序的Excel文件,运行程序就不会再报错了。


该文章在 2024/9/18 9:02:53 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved