如何从内存地址获取值?

时间:2012-07-05 02:11:15

标签: c++ windows memory

我希望从内存地址中获取值,而不会使程序崩溃。

这是我的代码:

int main(){
    int *ptr=(int*)0x09D37570;
    while(1){
        system("cls");
        cout<<(*ptr);
    }
    return 0;
}

但这会导致程序崩溃,它会通过调用* ptr崩溃,为什么会这样?如何才能毫无问题地获得价值?

3 个答案:

答案 0 :(得分:5)

你正在拿一个硬编码的地址并期望它能保持你看到的价值。但是,有一些问题:

如果担心自己的过程,你必须拥有那段记忆。你用new或类似的东西分配的东西最好抓住那个地址,否则不知道会发生什么。例如:

int *someAddress = new int (5);
int *somePtr = someAddress; //point to same address as newed
int someInt = *somePtr; //someInt is 5
++somePtr; //uh-oh, now we've left what we newed; it might not be allocated
someInt = *somePtr; //there's no telling if that memory was ok to use

如果确实有效,你只需获得一些随机数。事实上,如果你把它循环足够长,它最终会崩溃。然而,即使是一个问题,它甚至没有直接属于这里!

最大的问题是即使它具有相同的地址,也不是相同的内存。这可能听起来令人困惑,但这是一个非常棒的主题(http://en.wikipedia.org/wiki/Virtual_address_space)。基本上,每个进程具有相同的地址值,但它们映射到实际内存中的不同区域。因此,您的硬编码地址仅适用于您的流程。

至少可以在Windows上查看其他进程内存的一种方法是使用ReadProcessMemory。在页面上,您可以看到要求,例如对您正在阅读的流程具有PROCESS_VM_READ权限。如果失败,请务必检查GetLastError。有一个小例子here

请注意,VirtualQueryEx在调用ReadProcessMemory之前是一件好事。

它可能有用,或者它可能没有,但这是我所知道的最好的东西,可以在其他进程的内存空间中进行探索。如果你已经完成了这项工作,那值得一试。

答案 1 :(得分:3)

每个进程都有自己的内存空间,不同进程中的相同地址映射不同的物理地址,因此这样做毫无意义。

答案 2 :(得分:1)

如果您使用的是 Linux,则可以使用 gdb 附加到进程,并在某个时候按 Ctrl-C,然后检查内存。命令是x,所以

x 0x09D37570

你应该也能做到

print *(int*)0x09D37570;

使用 gdb,您处于进程的受保护内存空间。

如果没有操作系统,您正在尝试做的确实有效。如果您正在开发固件,则 是获取内存的正确方法,无需虚拟内存地址。

https://sourceware.org/gdb/current/onlinedocs/gdb/Memory.html