(ubuntu) ASLR - 清除混乱,奇怪的结果

(ubuntu) ASLR - clear the mess, weird result

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

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

dumber 正在阅读并打印我无法理解为什么在某些计算机上打印 16 而在其他计算机上打印 32767 的原因

dumb.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;
}

dumber.c 你有:

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

那么你有:

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

所以在 dumber 进程中你读取了那个 dumb 进程放在那里的地址,并且从这一点 p 不指向 j

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

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

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