c - 进程的虚拟地址空间的哪些部分是可覆盖的?

标签 c memory stack buffer-overflow virtual-memory

例如,假设缓冲区不是在堆栈的相反方向增长,而是在相同的方向增长。如果我有一个包含字符串“Hello world”的字符缓冲区,而不是将“H”放在最低地址,而是放在最高地址,依此类推。

如果复制到缓冲区的输入字符串溢出,它无法覆盖函数的返回地址,但肯定有其他东西可以覆盖。我的问题是——如果输入字符串足够长,哪些内容可以被覆盖?堆和栈之间是否存在可以被覆盖的库函数?堆变量可以被覆盖吗?我假设 data 和 bss 部分中的变量可以被覆盖,但是文本段是否受到写入保护?

最佳答案

进程在内存中的布局因系统而异。这个答案涵盖了 x86_64 处理器下的 Linux。

有一篇很好的文章说明了 Linux 进程的内存布局 here .

如果缓冲区是局部变量,那么它将与其他局部变量一起在堆栈上。如果缓冲区溢出,您可能遇到的第一件事是同一函数中的其他局部变量。

当您到达堆栈的末尾时,在下一个使用的内存段之前有一个随机大小的偏移量。如果您继续写入此地址空间,则会触发段错误(因为该地址空间未映射到任何物理 RAM)。

假设您设法跳过随机偏移而没有崩溃,并继续覆盖,接下来它可能命中的是内存映射段。该段包含文件映射,包括用于将动态共享库映射到地址空间的映射,以及匿名映射。动态库将是只读的,但如果进程有任何 RW 映射,您可能会覆盖其中的数据。

此段之后是另一个随机偏移量,然后才到达堆。同样,如果您尝试写入随机偏移量的地址空间,则会触发崩溃。

堆下面是另一个随机偏移量,然后是 BSS、数据,最后是文本段。 BSS 和数据中的静态变量可能会被覆盖。文本段不应是可写的。

您可以使用 pmap 检查进程的内存映射命令。

关于c - 进程的虚拟地址空间的哪些部分是可覆盖的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39693098/

相关文章:

c - 包含一个头文件,用于使用 Doxygen 预处理器解析所有其他文件

c++ - 是否有任何 C 标准函数可以将值 "1"传递给 all (%s)

linux - 如何以编程方式在 Linux 中确定物理 RAM 大小?

c++ - 了解使用堆栈实现队列的递归调用机制

algorithm - 队列中的前 n 个元素

c - 使数组读取文件并存储所有数据

c - 我无法在项目中使用输入文件,因为 Clion 似乎看不到该文件

c - 如何正确地将 C 结构写入磁盘上的文件,以便可以在其上使用 mmap?

linux - 计算 Linux 上使用的内存百分比

c - 如何修复与 C 中的动态数组指针/堆栈相关的崩溃?