我编写了一段简单的代码,试图找出我们是否可以在代码段中读取和打印内存:
#include <stdio.h>
void main() {
int *code_ptr = 0x4;
printf("code_ptr = %x\n", code_ptr);
printf("*code_ptr = %x\n", *code_ptr);
}我的系统是x86_64 +Ubuntu19.04 (Disco )。程序失败,输出如下:
code_ptr = 4
Segmentation fault (core dumped)在Linux中,代码段和数据段共享相同的基址。如果是这样的话,这个程序将读取代码段中的内存,而且我还以为不会有任何崩溃,因为0x04应该在数据段的范围内(从开始时开始)。这应该通过分页检查,因为代码段的映射内存是只读的,我们只在这里读取内存。
那么,我错过了什么吗?或者有没有其他机制阻止我们阅读这个%ds:0x4?
发布于 2020-06-08 03:09:07
我认为您的主要误解是,您认为名为“数据段”的8086硬件功能与可执行图像细分(也称为“数据段”)相同。泽尼瓦可能以这种方式使用了该硬件功能,但没有现代的x86 Unix这样做。在现代Unix上,%ds:0总是指向线性地址为零,而不是指向可执行文件数据段的开头。(同样,%cs:0指向线性地址为零,而不是可执行文件的文本段。)
可执行文件的所有段都将加载到线性地址0以上的线性地址空间中,在当前生成的OSes上,加载地址将在每次运行时随机分配。
没有获得指向可执行程序代码或数据段开头的指针的标准方法。在GNU系统上,您可以使用dl_iterate_phdr,而其他OSes可能在不同的名称下具有类似的功能。
https://stackoverflow.com/questions/62254091
复制相似问题