c - 有没有办法可靠地分配与先前释放的块相同的内存块,然后访问以前在其中的内容?
问题描述
我有以下 C 程序,它请求一些内存 ( str1
),将文件的内容读入该空间,然后释放它。接下来,请求相同大小 ( str2
) 的块,并将内容打印到标准输出。
我想要的是str2
包含的内容,str1
以便输出始终是文件的内容。
我知道我正在做的是未定义的行为,因为我无法保证已分配的内存内容将包含什么。但是,我正在尝试做一些不为人知的事情来进行演示,在该演示中,文件中的数据可以被泄露,而在代码审查中并不明显。
几乎所有时间,我都会在同一地址收到一块内存,用于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
意味着您告诉操作系统您已完成内存处理,并且无法撤消此操作。
我想要的是 str2 包含 str1 的内容,以便输出始终是文件的内容。
你在这里基本上有三个选择。
- 等待呼叫
free
- 在调用之前复制缓冲区
free
- 编写你自己的实现
malloc
和free
来自评论:
想象一下,我要分配一些内存,然后将一些敏感的东西(例如私钥)读入那个块并用它做一些事情。后来,我分配了一些相同大小的内存并将一些数据粘贴到其中,这些数据将保存到一个文件中。如果我不覆盖块中的所有数据,那么它可能包含一些将保存到文件中的敏感信息。在这种情况下,从代码审查中可能不会明显看出某些敏感数据泄露是可能的。我想证明敏感数据可以以不明显的方式被泄露。
好东西,但这些漏洞几乎总是依赖于未定义的行为。正如您自己所说,这是一个安全问题。因此,提供一种可靠的方法来做到这一点真的没有意义。
这是一个在 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
推荐阅读
- html - Bootstrap 4 Modal以自动宽度为中心
- python - 如何将熊猫数据框从 python 文件导入另一个 python 文件
- python - 来自 BioPython 的 Align.PairwiseAligner() 的 MemoryError
- javascript - ElasticSearch 使用 Javascript 进行精确搜索
- php - Google Drive API 列出所有出现的文件夹
- swift - 上传到 Firebase,有和没有图片
- javascript - 如果满足条件,则重新路由用户
- python - 我在 python 中制作列表列表时遇到了麻烦
- r - 如何制作出色的 R Raster 可重现示例
- android - 屏幕固定实际上足以建立一个统一游戏的无人亭吗?