C 程序是不是可以访问和更改分配给另一个程序的堆中的内存地址?

Posted

技术标签:

【中文标题】C 程序是不是可以访问和更改分配给另一个程序的堆中的内存地址?【英文标题】:Is it possible for a C program to access and changing a memory address in the heap allocated to another program?C 程序是否可以访问和更改分配给另一个程序的堆中的内存地址? 【发布时间】:2021-12-15 22:41:05 【问题描述】:

我们假设我有一个像这样的程序(我称之为程序 1):

#include <stdlib.h>
#include <stdio.h>
#define MAX 100
int main()
    int i;
    int *v;
    v = (int *)malloc (MAX * sizeof (int));

    for(i=0;i<MAX;i++)
        v[i] = i;
    
    printf("Address:%d\n",&v[0]);
    getchar();

    for(i=0;i<MAX;i++)
        printf("%d\n",v[i]);
    

让我们假设我有一个辅助程序(称为程序 2),就像这个:

#include <stdlib.h>
#include <stdio.h>
int main()
    int address;
    int *v;
    scanf("%d",&address)
    v = address;

    printf("%d\n",*v);
    *v = 100;

现在,让我们假设我运行程序 1 并收集它打印的地址。该程序将在 getchar() 函数中被阻止。并且,让我们假设,当程序 1 被阻塞时,我运行程序 2 并向 scanf 提供程序 1 打印的地址。我可以访问程序 2 中分配给程序 1 的相同内存地址吗?

最好的问候。

【问题讨论】:

绝对不是(在任何带有内存管理单元的现代处理器/操作系统上)。每个进程都在一个单独的地址空间中。可以使用操作系统的显式机制(例如共享内存)来共享内存。但肯定不是你描述的那样。 【参考方案1】:

在没有内存保护的旧操作系统(例如AmigaDOS 或Classic MacOS)中,所有进程都将在相同的内存空间中运行,您可以执行类似的技巧。当然,这也意味着任何有缺陷(或恶意)的程序都可能轻易地破坏其他程序,甚至使整个操作系统崩溃。所以现代操作系统给每个程序自己独立的虚拟内存空间,所以即使你的程序 2 有程序 1 打印的虚拟地址,当程序 2 试图取消引用该地址时,它会发现它指向不同的物理页面内存(或者可能根本没有物理内存页,导致分段错误)。

许多现代操作系统确实提供了 API 来设置共享内存区域(例如 POSIX 下的mmap),以便多个程序可以访问相同的物理内存,有些甚至具有允许您单方面访问另一个程序的私有内存的 API进程(例如 Windows 下的 ReadProcessMemory 和 WriteProcessMemory),但您通常需要管理员权限才能使用这些 API,而且出于显而易见的原因,它们很难安全使用。

【讨论】:

以上是关于C 程序是不是可以访问和更改分配给另一个程序的堆中的内存地址?的主要内容,如果未能解决你的问题,请参考以下文章

c语言里啥变量存储在堆中啥变量存储在栈中啊!

数据结构&算法_堆栈(堆栈)队列链表

Python:通过将对象分配给另一个对象来修改它

通过指针的堆数据结构

浅谈堆栈队列

静态值类型字段是不是在 C# 的堆中装箱?