gpt4 book ai didi

c - 有没有办法可靠地分配与先前释放的 block 相同的内存块,然后访问以前在其中的内容?

转载 作者:行者123 更新时间:2023-12-04 08:01:11 25 4
gpt4 key购买 nike

我有以下 C 程序请求一些内存( str1 ),将文件的内容读入该空间然后释放它。接下来,请求相同大小的 block (str2),并将内容打印到标准输出。
我想要的是str2包含 str1 的内容这样输出始终是文件的内容。
我知道我正在做的是未定义的行为,因为我无法保证已分配的内存内容将包含什么。但是,我正在尝试做一些不为人知的事情来进行演示,在该演示中,文件中的数据可以在代码审查中不明显的情况下被泄露。
几乎所有时间,我都会在同一地址收到一 block 内存,用于两个 str1。和 str2 , 和 大多数时候当我在 macOS 和 Windows 上运行程序时,会打印文件的内容。它似乎永远不会在 Linux 上发生(在 Linux 上,调用 free() 似乎会将内存块归零)。
有没有办法让它在 Windows 和 macOS 上更可靠,是否有任何解释为什么它在 Linux 上根本不起作用?
我的代码是:

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

int main() {
FILE *file = fopen("data.txt", "r");
char *str1 = malloc(4096*sizeof(char));
fread(str1, 1, 4096, f);
free(str1);

char *str2 = malloc(4096);
printf("Content: %s\n", str2);
free(str2);
}

最佳答案

本质上,当你分配和释放时发生的事情对你来说是一个黑匣子。绝对没有可靠的方法来获得相同的地址。调用free意味着你告诉操作系统你已经完成了内存,并且没有撤销。

What I want is for str2 to contain the content of str1 so that the output is always the content of the file.


你在这里基本上有三个选择。
  • 等待调用 free
  • 在调用 free 之前复制缓冲区
  • 编写您自己的 malloc 实现和 free

  • 来自评论:

    imagine that I'm going to allocate some memory then read something sensitive (e.g. a private key) into that block and do something with it. Later, I allocate some memory of the same size and stick some data into it that will be saved to a file. If I don't overwrite all the data in the block then it may contain some sensitive info that would get saved to the file. In that case, it may not be obvious from a code review that some sensitive data exfiltration is possible. I want to demonstrate that sensitive data can be exfiltrated in a non-obvious manner.


    好东西,但这些漏洞几乎总是依赖于未定义的行为。正如您自己所说,这是一个安全问题。因此,提供一种可靠的方法来做到这一点真的没有意义。
    这是一个在 Fedora Linux 上为我工作的片段。
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>

    int main(void) {
    char *s = malloc(100);
    const char str[] = "Hello, World. Prepare to meet your doom.";
    strcpy(s, str);
    free(s);
    for(int i=0; i<strlen(str); i++)
    putchar(s[i]);
    puts("");
    }
    我的输出:
    $ ./a.out 
    ��epare to meet your doom.
    如您所见,我得到了部分数据,但不是全部。为了演示这种未定义的行为,这里有不同优化的输出:
    $ gcc k.c -O1
    $ ./a.out
    0Separe to meet your doom.
    $ gcc k.c -O2
    $ ./a.out
    @�
    $ gcc k.c -O3
    $ ./a.out

    您的方法对此非常不可靠,因为您将打印到字符串中的第一个 0。这是不会输出任何内容的代码,它可以欺骗您数据已被删除。这就是我使用 putchar 的原因。在上面的循环中。
    char str[] = "Hello, World";
    str[0] = '\0';
    printf("%s", str); // Will print nothing, but only first character is wiped

    关于c - 有没有办法可靠地分配与先前释放的 block 相同的内存块,然后访问以前在其中的内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66454053/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com