c - (ubuntu) ASLR - 清理困惑,奇怪的结果

标签 c linux ubuntu aslr

嗨,我正在使用 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;
}

笨蛋.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);/* 获取地址哑进程放在那里 */

那么你有:

printf("p 指向:%d\n", *p);/* 读取该地址处的内存内容 */

因此,在哑进程中,您读取哑进程放在那里的地址,从此时起,p不再指向j

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

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

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

关于c - (ubuntu) ASLR - 清理困惑,奇怪的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53811237/

相关文章:

c - 从二维字符数组指针获取字符,该指针是 C 中结构指针的属性

c++ - 除法作为乘法和 LUT ?/fast float 除法倒数

scala - 由于内存不足(无法分配新内存),无法在 ec2 上运行 sbt

python greenlet段错误

c - 对 main -collect2 : ld returned 1 exit status 的 undefined reference

c - 读取 posix 消息队列时文件描述符错误

linux - 使用 PID 文件杀死守护进程

linux - 如何在多台Linux机器上同时触发某个shell脚本?

c - 如何在按键后立即读取终端的输入缓冲区

ubuntu - Visual Studio : how can I debug a remote application which is running as root?