如何使用C获取特定的内存地址

tr9*_*9sh 9 c linux memory memory-management

对于我的学士论文,我想要可视化内存的数据剩余以及重启系统后它是如何存在的.

我有一个简单的想法,将图片映射到内存,关闭我的电脑,等待x秒,启动计算机,看看图片是否仍然存在.

int mmap_lena(void)
{
    FILE *fd = NULL;
    size_t lena_size;
    void *addr = NULL;

    fd = fopen("lena.png", "r");

    fseek(fd, 0, SEEK_END);
    lena_size = ftell(fd);

    addr = mmap((void *) 0x12345678, (size_t) lena_size, (int) PROT_READ, (int) MAP_SHARED, (int) fileno(fd), (off_t) 0);
    fprintf(stdout, "Addr = %p\n", addr);
    munmap((void *) addr, (size_t) lena_size);
    fclose(fd);
    fclose(fd_log);
    return EXIT_SUCCESS;
}

为了清楚起见,我省略了检查返回值.

所以在mmap之后我试图以某种方式获取地址,但我通常最终会遇到分段错误,因为我的理解是内存受我的操作系统保护.

int fetch_lena(void)
{
    FILE *fd = NULL;
    FILE *fd_out = NULL;
    size_t lenna_size;
    FILE *addr = (FILE *) 0x12346000;

    fd = fopen("lena.png", "r");
    fd_out = fopen("lena_out.png", "rw");

    fseek(fd, 0, SEEK_END);
    lenna_size = ftell(fd);

    // Segfault 
    fwrite((FILE *) addr, (size_t) 1, (size_t) lenna_size, (FILE *) fd_out);

    fclose(fd);
    fclose(fd_out);

    return 0;

}

还请注意我在这个例子中对地址进行了硬编码,因此每当你运行mmap_lena时,我在fetch_lena中使用的值可能是错误的,因为操作系统只将mmap的第一个参数作为提示(在我的系统上它总是默认为0x12346000)不知何故).

如果有任何微不足道的编码错误,我很抱歉,因为我的C技能还没有完全发展.

我想现在如果有任何方法来获取我想要的数据而不实现任何malloc挂钩或内存分配器黑客.

大卫先生,谢谢你

Chr*_*uin 20

您遇到的一个问题是您正在返回虚拟地址,而不是内存所在的物理地址.下次启动时,映射可能不一样.

这绝对可以在Linux的内核模块中完成,但我不认为你可以使用的用户空间中有任何类型的API.

如果你有权限(并且我假设如果你重新启动它可以在这台机器上是root用户),那么你可以查看/ dev/mem以查看实际的phyiscal布局.也许您应该尝试采样值,重新启动,并查看其中有多少值持续存在.

  • 我同意Chris的观点:你需要使用某种操作系统(或根本没有操作系统),它可以直接,无限制地访问RAM.如果您重新启动到Linux或具有受保护虚拟内存的任何其他操作系统,则无法保证您可以访问相同的内存页面.如果你想要一些易于使用的东西,如何重新启动到旧版本的DOS? (4认同)

rod*_*ion 12

有一个类似的项目,其中演示了冷启动攻击.该源代码是可用的,也许你可以得到一些启示那里.

然而,AFAIR他们首先读取内存而不加载操作系统,因此不必弄乱操作系统内存保护.也许您应该尝试这样做以避免在启动后被操作系统覆盖或清除内存.

(还要检查网站上的视频,这真是令人印象深刻;)


Tim*_*ost 5

Linux中的Direct Memory Access问题中,我们找出了实现这一目标所需的大部分基础知识.注意,mmap()不是这个的答案,正是由于其他人所说的原因......你需要一个真正的地址,而不是虚拟的,你只能进入内核(或者通过编写驱动程序将一个地址转发给用户空间) ).

最简单的方法是编写一个可以读取或写入的字符设备驱动程序,使用ioctl为您提供有效的开始或结束地址.同样,如果你想要在内核中使用的内存管理函数的指针,请参阅我链接到的问题..大多数问题都是在第一个(和接受的)答案的注释中解决的.