【问题标题】:Allocate data at specific address in windows?在Windows中的特定地址分配数据?
【发布时间】:2013-07-28 20:47:13
【问题描述】:

我正在四处寻找要做的事情,我想到了在 Windows 中的特定地址分配内存。

所以我在这里阅读了一些关于 stackoverflow 的问题,但没有一个真正展示了一个有效的示例,所以我不得不提出自己的问题,因为我真的很想尝试:

#include <Windows.h>
#include <iostream>

struct Variable {
    int var;
};

#define ACCESS() ((Variable*)0x50000000)

int main()
{
    DWORD ptr;
    VirtualAlloc((void*)0x50000000,sizeof(Variable),MEM_COMMIT | MEM_RESERVE | MEM_PHYSICAL,PAGE_READWRITE);                    
    VirtualProtect((void*)0x50000000,sizeof(Variable),PAGE_READWRITE,&ptr);
    ACCESS()->var = 5;
    while(!GetAsyncKeyState('Q')){}
}

但这总是会导致访问失效..

在特定地址分配数据的正确方法是什么? 因为,这种方式在某种程度上是行不通的......但同时与“为什么不呢?”混淆。


编辑:

第一个答案后的第二个代码也不起作用:

#include <Windows.h>
#include <iostream>

struct Variable {
    int var;
};

#define ACCESS() ((Variable*)0x50000000)
int main()
{   
    std::cout << VirtualAlloc((void*)0x50000000,sizeof(Variable),MEM_COMMIT,PAGE_READWRITE) << std::endl;
    std::cout << GetLastError() << std::endl;
    ACCESS()->var = 6;
    std::cout << ACCESS() << std::endl;
    while(!GetAsyncKeyState('Q')){}
}

返回值为0,表示失败,GetLastError()等于487,

和487根据this page表示:

ERROR_INVALID_ADDRESS; 尝试访问无效地址。

那么,我在互联网上阅读的所有内容和堆栈溢出都是假的?您>不能


下一次编辑:

似乎完全有可能,工作代码:

#include <Windows.h>
#include <iostream>

struct Variable {
    int var;
};

#define ACCESS() ((Variable*)0x50000000)
int main()
{   
    std::cout << VirtualAlloc((void*)0x50000000,sizeof(Variable),MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE) << std::endl;
    std::cout << GetLastError() << std::endl;
    std::cout << ACCESS() << std::endl;
    ACCESS()->var = 6;
    std::cout << ACCESS()->var << std::endl;
    while(!GetAsyncKeyState('Q')){}
}

【问题讨论】:

  • 您在0x50000000 分配内存,然后尝试在0xDEADBEEF 修改内存。即使您已在指定地址成功分配内存,您仍然会在完全不同的地址处遇到访问冲突。此外,您不能设置内存保护或在如此小的块中分配虚拟内存。保护和虚拟分配是内存页的。 (请阅读VirtualProtect 的文档,您的代码没有意义。)
  • 哦,对不起,我在我的代码中相应地更改了它们,ACCESS 定义仅用于此代码 sn-p,我忘记更改 xD 无论如何感谢发现 /updated :)
  • 您对VirtualProtect 的调用仍会尝试在不存在的映射上设置保护。
  • 操作系统很贪心,你知道,就像它的创造一样……好吧,至少它阻止了你继续做那些疯狂的事情。 ;-)
  • @David 反转 2 行也不起作用,更新了代码;o

标签: c++ windows memory-management


【解决方案1】:

VirtualAlloc 的调用失败。如果您检查它的返回值,您会发现这一点。

它失败的原因直接来自documentationMEM_PHYSICAL 必须与MEM_RESERVE 一起使用,不能与其他值一起使用。无论如何,您可能不想要MEM_PHYSICAL,它与AWE 有关。去掉flag就会分配成功。

无需调用VirtualProtect

以下应该有效:

#include <windows.h>
int main()
{
    VirtualAlloc((void*)0x50000000,0x1000,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
    *((int*)0x50000000) = 5;
}

【讨论】:

  • 嗯更新了问题
  • @Gizmo,嗯,所以我告诉你删除 MEM_PHYSICAL,你也删除了 MEM_RESERVE?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-22
  • 1970-01-01
  • 2023-01-23
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
相关资源
最近更新 更多