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

时间:2015-03-13 13:18:24

标签: c windows operating-system

我在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;
}

谢谢。

5 个答案:

答案 0 :(得分:4)

SadSeven,我假设您是故意读取数组的末尾。你所看到的不是其他程序内存,它是程序内存中未初始化的内存。

每个程序都在它自己的虚拟内存空间内运行,os的虚拟内存管理器负责处理这个问题。你不能从你的程序访问另一个程序内存(除非你们都使用共享内存,但你必须故意这样做)

答案 1 :(得分:3)

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

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

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

答案 2 :(得分:2)

您看到的输出来自于读取自己的内存。当它到达未分配给该进程的内存时,它会崩溃。

修改

为了使计算机病毒更加困难,每次运行starting address of a program will be different时都会遇到问题。因此,如果多次运行它,您应该期望不同的输出。 In Windows, the adress space layout is not randomized by all programs

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

答案 3 :(得分:0)

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

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

它尝试从4 r的值开始访问超出范围的内存。结果是undefined behaviour

r1997之前,它可能正常运行,可能会在r4时崩溃,它可能会在r开始播放您播放列表中的歌曲}值2015,甚至。 r3后无法保证此行为。

答案 4 :(得分:0)

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

http://en.wikipedia.org/wiki/Address_space_layout_randomization了解ASLR 阅读有关虚拟内存的信息: http://en.wikipedia.org/wiki/Virtual_memory