vba - Virtual Protect 的 64 位声明是否正确?
问题描述
Private Declare PtrSafe Function VirtualProtect Lib "kernel32" ( _
ByVal memAddress As LongPtr, _
ByVal lengthInBytes As LongPtr, _
ByVal newProtect As protectFlags, _
ByRef outOldProtect As protectFlags _
) As Long
Public Enum protectFlags 'an enum is a Long in VBA which is 32-bit so can be used in place of DWORD
PAGE_NOACCESS = &H1
PAGE_READONLY = &H2
PAGE_READWRITE = &H4
PAGE_WRITECOPY = &H8
PAGE_EXECUTE = &H10
PAGE_EXECUTE_READ = &H20
PAGE_EXECUTE_READWRITE = &H40
PAGE_EXECUTE_WRITECOPY = &H80
PAGE_GUARD = &H100
PAGE_NOCACHE = &H200
PAGE_WRITECOMBINE = &H400
End Enum
我这样称呼它:
Dim memoryAddress As LongPtr
memoryAddress = ... 'some protected memory
Dim originalProtection As protectFlags
If CBool(VirtualProtect(memoryAddress, 8, PAGE_EXECUTE_READWRITE, originalProtection)) Then
Debug.Print "Previous protection cached: &H"; Hex(originalProtection)
Else
Err.Raise 5, Description:="Memory address cannot be unprotected with PAGE_EXECUTE_READWRITE"
End If
...然后我正在恢复保护
VirtualProtect(memoryAddress, 8, originalProtection, temp)
问题是,originalProtection
第一次调用后仍然是 &H0,所以在第二次调用中我得到 87 的 LastDllError -“参数不正确。”。我很确定内存最初受到保护,因为删除对 VirtualProtect 的调用会使我的程序崩溃,而包含它是成功的。但我无法重置保护。
作为参考,这是我正在翻译的内容:
BOOL VirtualProtect(
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flNewProtect,
PDWORD lpflOldProtect
);
解决方案
是的,声明是正确的。
问题是在我的实际代码中,originalProtection
是一个公共类变量。
公共类变量不能通过 ByRef 传递给函数,因为它们实际上是作为具有隐藏私有变量的 Property Get/Let 过程在后台实现的,因此只有一个临时值被传递给 VirtualProtect 而不是要写入的基础变量。
解决方案是声明一个局部变量Dim
来接收该值,然后将其写入我的类变量。
推荐阅读
- asp.net-core - 如何为 OpenApi 3 的 Swashbuckle 5.6.3 中的 formData 参数启用文档和文件上传?
- flutter - 无法在 Flutter 应用中从 Cloud Firestore 获取数据
- youtube-api - Magento 2 Youtube V3 Api 错误:“请求无法完成,因为您已超出配额
- kubernetes - 在 values.yaml 中设置指针
- php - 自上次 wordpress 更新 5.5.3 以来的错误消息“第 69 行的 www/wp-includes/l10n.php”
- python - Python在列表列表中查找最大值
- tomcat - 配置 OpenAM 代理的问题
- harfbuzz - 为什么在我的 harfbuzz 整形示例中 y_offset 为 0?
- jenkins - 大量构建开始时,Jenkins 变得无响应
- python - 如何摆脱 Series.value_counts 中的 0 和 NaN?