【问题标题】:Why are the last digits of the memory addresses same each time为什么每次内存地址的最后一位都一样
【发布时间】:2021-09-04 16:41:12
【问题描述】:

这更像是一个请帮助我理解的问题,而不是调试问题。所以,我最近开始研究 C 语言,在使用指针一段时间的过程中遇到了这种情况。

#include <stdio.h>

int main()
{
        char *name="Bob";
        for(int i=0;i<3;i++)
        {
                printf("Address is %0x and value is %ld",name,*name);
                printf("\n");
                name++;
        }
        printf("\n");
        return 0;
}

我运行了 3 次程序,得到了类似 -->

的输出
Address is 9a756008 and value is 66
Address is 9a756009 and value is 111
Address is 9a75600a and value is 98

Address is ba49d008 and value is 66
Address is ba49d009 and value is 111
Address is ba49d00a and value is 98

Address is 2cb44008 and value is 66
Address is 2cb44009 and value is 111
Address is 2cb4400a and value is 98

我的问题是:内存每次都是随机分配的,那么为什么所有三种情况下的最后三位数字(每次运行程序都得到相同的结果)相同?内存分配有固定的规则吗?

感谢任何信息。谢谢! :)

【问题讨论】:

  • "内存是每次随机分配的" --> 不,不是随机的。 “内存分配有固定的规则吗?” --> C 没有指定固定的规则。
  • 这只是您的操作系统选择的方式。它有一个很好的理由或“规则”,但你不知道它是什么,也不应该指望它是任何特定的方式,因为它可以在任何重新启动时甚至在任何时候改变。
  • @chux-ReinstateMonica:是的,它是随机的。好的现代系统使用address space layout randomization

标签: c pointers memory-address


【解决方案1】:

地址由程序加载器故意随机化。这种随机化只影响地址的较高位。

如果程序中存在某些缺陷,并且攻击者知道程序存储某些数据或代码的地址,则攻击者可能能够利用这些缺陷来获取他们不应访问的权限或数据。例如,如果一个程序错误地接受了太多输入,它在程序为数据保留的数组上运行,额外的输入可能会覆盖内存中的其他内容,例如堆栈上的返回地址。当攻击者知道代码在内存中的位置时,他们可以制作输入,以便用攻击者选择的地址覆盖返回地址,从而允许攻击者选择程序执行的代码。

为了减少这种情况发生的可能性,优秀的现代程序加载器使用address space layout randomization。程序加载时,程序各部分在内存中的起始位置是随机选择的。这可以防止攻击者知道数据或代码的确切位置。

程序加载器可以选择的起始位置可能受到操作系统的各种规则和可执行文件格式的限制。操作系统仅以称为 pages 的某种大小为单位分配内存。 4096 字节是典型的页面大小。程序可能期望其布局的某些部分(常量数据、程序代码、初始化的非常量数据等)从页面边界开始。在这种情况下,程序加载器只能选择作为页面边界的随机地址。如果一页为 4096 字节,则每一页的起始地址为 100016 的倍数(十六进制 1000 = 4096)。

这意味着起始地址将具有 xxx00016 的形式,其中 xxx 是程序加载器选择的随机值,而 000是页面的开始。页面中的任何内容都会受到 xxx 更改的影响,但 000 中的更改不会影响它。

因此,如果某些数据位于相对于其程序段开头的偏移 678 处,则其地址将始终具有某个值 xxx678,而 xxx 将程序运行之间会有所不同,但 678 不会。

这些规则来自操作系统和程序加载器的行为,它们是 C 实现的一部分。它们不是 C 标准的一部分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-17
    • 1970-01-01
    • 2015-07-19
    • 2016-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多