(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
指向的地址处的值。
您好,我正在使用 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
指向的地址处的值。