C访问另一个程序内存?

时间:2018-01-20 09:05:11

标签: c pointers memory

我写了这段代码,所以我可以看到变量foo的地址。

#include <stdio.h>
#include <stdlib.h>

int main(){

char* foo=(char*) malloc(1);
*foo='s';
printf(" foo addr : %p\n\n" ,&foo);
int pause;

scanf("%d",&pause);
return 0;

}

然后暂停它并在这里使用foo的地址:

#include <stdio.h>
int main(){
char * ptr=(char *)0x7ffebbd57fc8; //this was the output from the first code
printf("\n\n\n\n%c\n\n\n",*ptr);
}

但我一直在分段错误。为什么这段代码不起作用?

3 个答案:

答案 0 :(得分:2)

Oups,您的问题与C语言无关,但实际上取决于操作系统,如果有的话。

首先让我们从纯C语言的角度来看它:

char * ptr=(char *)0x7ffebbd57fc8;

您正在将无符号整数转换为char *。当你从另一个程序中获得整数值时,你可以确定它有一个可接受的范围,所以你确实得到一个指向该地址的指针。由于它是一个char *指针,您可以使用它来读取将位于该地址的任何对象的字节表示。直到那里仍然很好。但是常见的系统使用虚拟地址并限制每个进程只访问自己的页面,因此默认情况下进程无法访问另一个进程的内存。此外,随着虚拟内存的普遍使用,没有理由任何两个非内核进程共享公共地址。真实地址的例外情况是:

  • 真实内存操作系统(MS / DOS和衍生产品,如FreeDOS,CP / M和其他人体系统)
  • 内核模式:内核可以访问系统的整个内存 - 谁可以加载你的程序?
  • 特殊功能:某些操作系统提供特殊的API让一个进程读取另一个进程的内存(Windows确实如此),但它并不像直接读取地址那样简单......

由于我假设您不是前两种情况中的任何一种,因此当前进程的任何地址都没有映射,因此错误。

答案 1 :(得分:1)

这不是C问题/问题,而是运行时支持问题。在大多数OS程序中运行在虚拟环境中,尤其是有关其内存空间的程序。在这种情况下,存储器是虚拟存储器,这意味着当程序访问给定地址 x 时,实际(物理)存储器被计算为 f(x) f 是由OS实现的功能,用于确保给定进程(表示OS中代码运行的对象)具有与专用于其他进程的内存分离的自己的保留内存。这称为虚拟内存

答案 2 :(得分:0)

在系统上使用虚拟内存时,您可以使用一系列可供用户进程使用的逻辑地址。这些地址范围被细分为称为PAGES的单元,其大小取决于处理器(512b至1MB)。

页面在映射到流程之前无效。操作系统将具有允许应用程序映射页面的系统调用。如果您尝试访问无效的页面,则会出现某种异常。

虽然操作系统只分配内存页面,但应用程序用于调用,例如malloc(),它们分配任意大小的内存块。

在幕后,malloc()映射页面(即使它们有效)以创建用于返回少量内存的内存池。

当省略malloc()时,内存未被映射。

请注意,每个进程都有自己的逻辑地址范围。包含0x7ffebbd57fc8的一个进程的页面可能会映射到与另一个进程的0x7ffebbd57fc8不同的物理页面帧。如果不是这种情况,一个用户可能会与另一个用户混淆。 (所有进程都共享一系列地址,但这只能在内核模式下访问。)

现在许多系统将进程随机映射到逻辑地址空间中的不同位置,这使您的问题变得更加复杂。在这样的系统上,您可以多次运行第一个程序并获得不同的地址。

  

为什么这段代码不起作用?

您需要在操作系统上调用系统服务,将内存映射到进程中,并使包含0x7ffebbd57fc8的页面可以访问。