【发布时间】:2013-12-16 16:34:06
【问题描述】:
我正在分析进程加载的各种模块。不幸的是,我无法创建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 地址是正确的。是什么原因?
【问题讨论】:
-
这不是正确的代码,您必须立即调用 GetLastError()。 cout 调用可以轻松修改值,因为它们也使用 winapi 调用。
-
在
VirtualProtect之后调用GetLastError()的结果是一样的 -
kernel32.dll 有点特别。阻止你干扰它是有道理的——例如防止各种注入攻击。
-
winspool.drv也是同样的情况
-
只是说,当我使用“调试函数”API 编写调试器时,我遇到了同样的问题:这些调试函数允许您创建用户模式调试器,但不能创建内核模式调试器(我无法进入或暂停进程进入内核函数)。因此,如果我没记错的话,如果我在管理员模式下运行我的代码,kernerl32.dll 是可调试和可编辑的,但不是 ntdll.dll 和许多其他 nt*.dll 文件。在使用 Visual C++ 调试程序时,您可以看到同样的事实:它不允许您输入 NT 函数(即使在单步执行汇编程序时),因为它是一个用户模式调试器。
标签: c++ windows winapi dll kernel32