你可以使用用mingw编译的程序访问其他程序的内存吗?

Can you access other program's memory using program compiled with mingw?

我在 Windows 8.1 上编写了这个非常简单的程序,并使用 Mingw 的 gcc 对其进行了编译。我 运行 它与 "test.exe > t.txt" 和 "test.exe > t1.txt" 输出不同(即使它使用虚拟地址)。它 运行 了一会儿然后就崩溃了。我决定对此进行测试,因为我正在阅读一本关于操作系统的书。

是否正在读取其他程序的内存?那不是不应该发生的吗?我可能误会了什么...

#include <stdio.h>

int main(int argc, char *argv[]){
    int r = 0;
    int p[4] = {1,5,4,3};

    for(r=0; p[r]!=1111111111111111; r++){
        p[2] = p[r];
        printf("%d\n", p[2]);
    }

    return 0;
}

谢谢。

在您的代码中,for 循环是错误的。

for(r=0; p[r]!=1111111111111111; r++)

它尝试从 r4 值开始访问越界内存。结果是undefined behaviour

它可能 运行 没问题,直到 r1997,它可能会在 r4 时崩溃,它可能会开始播放您的歌曲播放列表 r2015,甚至。 r3.

后的行为无法保证

你看到的输出是读取它自己的内存。当它到达未分配给进程的内存时崩溃。

编辑:

为了让计算机病毒更难对付,starting address of a program will be different each time you run it. So you should expect different output if you run it several times. In Windows, the adress space layout is not randomized by all programs

您的程序超出了一个局部(自动)变量,这意味着它将遍历 stack frame(s)。堆栈帧包含局部变量、函数参数、保存的寄存器、函数调用的 return 地址以及指向前一个堆栈帧末尾的指针。如果变量都具有相同的值,则任何差异都可以通过不同的内存地址来解释。可能还有其他我不知道的原因,因为我不是 Windows.

中内存布局的专家

SadSeven,我假设您正在 purpose 上阅读数组末尾。您看到的不是其他程序内存,而是程序内存中未初始化的内存。

每个程序都在它自己的虚拟内存 space 中运行,os 的虚拟内存管理器会处理这个问题。你不能从你的程序访问另一个程序内存(除非你们都使用共享内存,但你必须在 purpose)

您还没有初始化 p[3] 以外的任何东西。 C 语言不保证当您尝试访问尚未使用数据初始化的地址时会发生什么。您可能会看到一堆垃圾,但您编写的程序并未定义这些垃圾是什么。可以是任何东西。

您在崩溃前访问的地址仍然属于当前进程,它只是存在于堆栈和堆之间的未初始化内存。

进程可能由于分段错误而崩溃,分段错误发生在进程试图访问不属于它的内存时。这将是它尝试访问其自身内存之外的点。

每个进程 运行 在其单独的 4GB 虚拟地址 space 中,尝试越界读取不会从另一个进程的内存中读取。它将从它自己的地址 space 读取垃圾。现在,您一直在问为什么输出不同,嗯,ASLR 随机化可执行文件的关键部分,从而在进程实例中提供不同的入口点和堆栈地址,因此即使是相同的进程也比 运行 多once会有不同的入口点

阅读有关 ASLR 的信息:http://en.wikipedia.org/wiki/Address_space_layout_randomization 在以下位置阅读有关虚拟内存的信息: http://en.wikipedia.org/wiki/Virtual_memory