【问题标题】:(ubuntu) ASLR - clear the mess, weird result(ubuntu) ASLR - 清除混乱,奇怪的结果
【发布时间】:2018-12-17 08:19:27
【问题描述】:

您好,我使用的是 Ubuntu,刚刚关闭了我的 ASLR 以检查 2 个文件(dumb.c 和dumber.c)

dumb正在创建文件并输入变量地址

笨蛋正在阅读并打印我有一个问题,无法理解为什么在某些计算机上打印 16 而其他计算机打印 32767

哑巴.c

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

int main()
{
    int i = 7;
    int j = 12;
    int k = 15;
    int *p = &j;

    FILE *fp;

    if(0 == (fp = fopen("dumb.txt", "w")))
    {
        printf("well, that didn\'t work!\n");
        return -1;
    }

    fprintf(fp, "%p\n", (void*)p);
    printf("Address from Dumb: %p, value: %d\n", (void *)p, *p);

    if(fclose(fp))
    {
        printf("oh well.");
        return -1;
    }

    sleep(300);

    return EXIT_SUCCESS;
}

dumber.c

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

int main()
{
    int i = 8;
    int j = 16;
    int k = 32;
    int *p = &j;

    FILE *fp;

    if(0 == (fp = fopen("dumb.txt", "r")))
    {
        printf("well, that didn\'t work!\n");
        return -1;
    }

    fscanf(fp, "%p\n", &p);

    if(fclose(fp))
    {
        printf("oh well.");
        return -1;
    }

    printf("\nDumber Address: %p\n", (void *)p);
    printf("p points to: %d\n", *p);

    return EXIT_SUCCESS;
}

【问题讨论】:

  • fscanf(fp, "%p\n", &amp;p);...你确定吗? &amp; 不是额外的吗?
  • 谢谢你的回答,是的,我很确定.. :/
  • 在多个dumber 运行中使用的dumb.txt 文件(生成一次)是否相同?
  • 请澄清并给我们所有打印的值...哪些打印给出了 16 或 32767?
  • 再次感谢您的快速回复!!,在dumber.c 文件中,值p 的pritnf 指向我的笔记本电脑上我得到32767 而在另一台计算机上得到16 在同一行。

标签: c linux ubuntu aslr


【解决方案1】:

dumber.c,你有:

fscanf(fp, "%p\n", &amp;p); /* getting address dumb process put there */

那么你有:

printf("p points to: %d\n", *p); /* reading memory content at that address */

因此,在较笨的进程中,您读取了笨拙的进程放在那里的地址,并且从这一点p 不指向j

现在一般来说,由于这两个主进程是不同的进程,所以哑进程看到的内存地址的内容很可能与哑进程在同一地址的值不同,而不管 ASLR。 这就是进程的工作方式(我假设这些进程在 Linux\Windows\Mac 中运行),它们被加载到不同的物理地址,具有不同的虚拟和物理地址映射,而且你不知道在愚蠢的进程中这个地址是否指向有效地址。

现在,这里发生的情况是,当您使用 ASLR 运行时,两个进程之间的进程地址空间(进程使用的虚拟地址)肯定是不同的。 如果没有 ASLR,所有进程的进程地址空间都是相同的,在任何情况下物理地址都可能不同。 由于两个进程的堆栈使用相同,哑进程将j的偏移量(虚拟地址)写入文件,哑进程读取此偏移量,因为哑进程有它j在与dumber 进程相同的偏移量处,您将访问dumber 的j。使用 ASLR,dumber 看到的地址对于dumber 进程来说是一个有效地址,但对于dumber 来说很可能不是一个有效地址(对于dumber 来说,这个地址可能没有映射)

您可以通过在其中一个进程中更改 j 的位置来验证它,这样做,您将永远不会看到 16 打印为在较笨的进程中 j 指向的地址处的值。

【讨论】:

  • 感谢您的回复!!,如果没有 ASLR,程序会因为分段错误而崩溃并运行。所以我没有得到的部分是为什么不管 ASLR 值会有所不同,主要问题是为什么我得到 32767 和其他计算机打印 16(哑铃中 j 的值)
  • printf("p points to: %d\n", *p); 不打印 j 的值。一旦你执行了这个fscanf(fp, "%p\n", &amp;p); p 指向天知道在哪里
  • 还有一个严重的问题,在我的电脑上,fscanf 中的地址 p 与dumber.c j 变量的地址不同,而在其他计算机上它们获得相同的地址
  • 这取决于 1. ASLR 2. 编译器是否将 j 放在两个进程的相同偏移量
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-05
  • 1970-01-01
  • 2018-06-28
  • 1970-01-01
  • 2016-11-28
  • 2012-12-16
  • 2012-12-06
相关资源
最近更新 更多