VirtualProtect和kernel32.dll-试图访问无效地址
VirtualProtect and kernel32.dll - attempt to access invalid address
我正在分析进程加载的各种模块。不幸的是,我无法创建kernel32.dll
内存快照,尽管该功能可以与其他模块(例如ntddl.dll
)正常工作。问题出在以下代码上:
/* Copy code from memory */
if (VirtualProtect((BYTE*)virtualAddress, sizeOfCode, PAGE_EXECUTE_READWRITE, &flags) == 0) {
std::cout << "VirtualProtect failed!" << std::endl;
std::cout << "Virtual address: " << virtualAddress << std::endl;
std::cout << "Size of code: " << sizeOfCode << std::endl;
std::cout << "Error code: " << GetLastError() << std::endl;
}
为kernel32.dll
调用此代码的结果是:
Virtual address: 747d0000
Size of code: 6a000
Error code: 0x1e7
错误描述说:
ERROR_INVALID_ADDRESS
487 (0x1E7)
Attempt to access invalid address.
我检查了进程的内存映射和kernel32.dll地址是否正确。原因是什么?
很难验证地址是否正确,它非常低。我刚刚写了另一个程序来测试这个。它枚举kernel32.dll中的区域,并对它们调用VirtualProtect():
#include <Windows.h>
#include <assert.h>
#include <iostream>
int main()
{
HMODULE hmod = GetModuleHandle(L"kernel32.dll");
MEMORY_BASIC_INFORMATION info;
// Start at PE32 header
SIZE_T len = VirtualQuery(hmod, &info, sizeof(info));
assert(len > 0);
BYTE* dllBase = (BYTE*)info.AllocationBase;
BYTE* address = dllBase;
for (;;) {
len = VirtualQuery(address, &info, sizeof(info));
assert(len > 0);
if (info.AllocationBase != dllBase) break;
std::cout << "Address: " << std::hex << info.BaseAddress;
std::cout << " (" << std::hex << info.RegionSize << ") ";
std::cout << " protect = " << std::hex << info.Protect;
DWORD oldprotect;
if (info.Protect == 0) std::cout << ", VirtualProtect skipped" << std::endl;
else {
BOOL ok = VirtualProtect(info.BaseAddress, info.RegionSize, PAGE_EXECUTE_READWRITE, &oldprotect);
std::cout << ", VirtualProtect = " << (ok ? "okay" : "Failed!") << std::endl;
}
address = (BYTE*)info.BaseAddress + info.RegionSize;
}
return 0;
}
此程序在我的计算机上的输出,运行Windows 8.1 x64:
Address: 77470000 (1000) protect = 2, VirtualProtect = okay
Address: 77471000 (f000) protect = 0, VirtualProtect skipped
Address: 77480000 (62000) protect = 20, VirtualProtect = okay
Address: 774E2000 (e000) protect = 0, VirtualProtect skipped
Address: 774F0000 (7e000) protect = 2, VirtualProtect = okay
Address: 7756E000 (2000) protect = 0, VirtualProtect skipped
Address: 77570000 (1000) protect = 4, VirtualProtect = okay
Address: 77571000 (f000) protect = 0, VirtualProtect skipped
Address: 77580000 (1000) protect = 2, VirtualProtect = okay
Address: 77581000 (f000) protect = 0, VirtualProtect skipped
Address: 77590000 (1a000) protect = 2, VirtualProtect = okay
Address: 775AA000 (6000) protect = 0, VirtualProtect skipped
在64位模式下运行:
Address: 00007FFC4F870000 (1000) protect = 2, VirtualProtect = okay
Address: 00007FFC4F871000 (112000) protect = 20, VirtualProtect = okay
Address: 00007FFC4F983000 (1000) protect = 4, VirtualProtect = okay
Address: 00007FFC4F984000 (1000) protect = 8, VirtualProtect = okay
Address: 00007FFC4F985000 (24000) protect = 2, VirtualProtect = okay
很明显,您有不同的Windows版本,所以请确保在您的计算机上运行此程序以获得可比较的结果。
我得出的结论是,这类代码没有失败的根本原因。如果它在你的机器上发生了,那很可能是环境问题。有一个非常明显的候选人是你的反恶意软件,这当然在防止代码干扰kernel32.dll方面有很大的利害关系。我在我的机器上运行最低限度的保护。
相关文章:
- 无法访问嵌套类.类的使用无效
- (C++) 从另一个类访问变量时值无效
- 访问冲突投射到无效*并返回
- 调用 GetPointerFrameTouchInfo时出现错误 998(对内存位置的无效访问)
- (SDL 渲染问题)C++ 引发异常:读取访问冲突.这是无效的
- 在结构中访问数组时无效使用非静态数据成员
- 如果迭代器的迭代器永远不会无效,则是STD :: MAP访问线程安全
- JNA 参数问题:内存访问无效
- Valgrind 未显示使用不正确的 c_str() 的无效内存访问
- JNA无效的内存访问
- 访问无效的指针并进行地址
- 发生 JNI 调用 c++ dll "不满意链接错误: 对内存位置的无效访问"
- 我的代码中真的有无效的内存访问吗
- Valgrind 抱怨通过指向结构的指针访问结构成员时读取无效
- 具有deque的随机访问迭代器的迭代器无效
- 获取错误代码 998 尝试从命名管道读取时对内存位置的访问无效
- VirtualProtect和kernel32.dll-试图访问无效地址
- c++断言中的未定义行为:访问无效/空指针
- 对类成员的访问“无效地使用非静态数据成员”
- 对内存位置的访问无效-托管到非托管代码