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,因此在第二次调用中,我得到的LastDllError为87 -“参数不正确。”我非常确定内存最初是受保护的,因为删除对VirtualProtect的调用会使我的程序崩溃,而包含它却是成功的。但我不能重置保护装置。
作为参考,这是我正在翻译的:
BOOL VirtualProtect(
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flNewProtect,
PDWORD lpflOldProtect
);
发布于 2021-09-02 14:08:06
是的,声明是正确的。
问题是在我的实际代码中,originalProtection
是一个公共类变量。
公共类变量不能通过ByRef传递给函数,因为它们实际上是作为带有隐藏私有变量的属性Get/Let过程实现的,因此只有一个临时值传递给VirtualProtect,而不是要写入的底层变量。
解决方案是使用Dim
声明一个局部变量以接收该值,然后将其写入我的类变量。
https://stackoverflow.com/questions/69030133
复制相似问题