2025年3月19日 星期三 甲辰(龙)年 月十八 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > VB

解除VBA 密码,适用于新的offices

时间:02-22来源:作者:点击数:10

解除VBA 密码,适用于新的offices

  • 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() '若已经hook,则恢复原API开头的6字节,也就是恢复原来函数的功能
  • 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
  • 'VBE6.dll调用DialogBoxParamA显示VB6INTL.dll资源中的第4070号对话框(就是输入密码的窗口)
  • '若DialogBoxParamA返回值非0,则VBE会认为密码正确,所以我们要hook DialogBoxParamA函数
  • #If Win64 Then
  • osi = 1
  • #Else
  • osi = 0
  • #End If
  • pFunc = GetProcAddress(GetModuleHandleA("user32.dll"), "DialogBoxParamA")
  • '标准api hook过程之一: 修改内存属性,使其可写
  • If VirtualProtect(ByVal pFunc, 12, PAGE_EXECUTE_READWRITE, OriginProtect) <> 0 Then
  • '标准api hook过程之二: 判断是否已经hook,看看API的第一个字节是否为&H68,
  • '若是则说明已经Hook
  • MoveMemory ByVal VarPtr(TmpBytes(0)), ByVal pFunc, osi + 1
  • If TmpBytes(osi) <> &HB8 Then
  • '标准api hook过程之三: 保存原函数开头字节,这里是6个字节,以备后面恢复
  • MoveMemory ByVal VarPtr(OriginBytes(0)), ByVal pFunc, 12
  • '用AddressOf获取MyDialogBoxParam的地址
  • '因为语法不允许写成p = AddressOf MyDialogBoxParam,这里我们写一个函数
  • 'GetPtr,作用仅仅是返回AddressOf MyDialogBoxParam的值,从而实现将
  • 'MyDialogBoxParam的地址付给p的目的
  • p = GetPtr(AddressOf MyDialogBoxParam)
  • '标准api hook过程之四: 组装API入口的新代码
  • 'HookBytes 组成如下汇编
  • 'push MyDialogBoxParam的地址
  • 'ret
  • '作用是跳转到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
  • '标准api hook过程之五: 用HookBytes的内容改写API前6个字节
  • MoveMemory ByVal pFunc, ByVal VarPtr(HookBytes(0)), 12
  • '设置hook成功标志
  • 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
  • '有程序调用DialogBoxParamA装入4070号对话框,这里我们直接返回1,让VBE以为密码正确了
  • MyDialogBoxParam = 1
  • Else '有程序调用DialogBoxParamA,但装入的不是4070号对话框,这里我们调用RecoverBytes函数恢复原来函数的功能,在进行原来的函数
  • RecoverBytes
  • MyDialogBoxParam = DialogBoxParam(hInstance, pTemplateName, _
  • hWndParent, lpDialogFunc, dwInitParam)
  • Hook '原来的函数执行完毕,再次hook
  • End If
  • End Function

 

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
上一篇:如何用VBS编写一个简单的恶搞脚本 下一篇:很抱歉没有了
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐