为什么每次我查看存储在磁盘(vbox vm)上的文件的地址都不同?

问题描述 投票:0回答:1

我知道 ASLR 每次都会在不同的内存位置加载程序,但是,我不确定为什么在我存储在 Linux 虚拟机的磁盘

/dev/sda2
上的文件的情况下会发生这种情况。

mp:projects-20:17:09-$ ./lseek_demo 
The end offset of file1 is 1268
The start  offset of file2 is 0
Diff between them is -1268
The mem address of file1 is 0x7ffce008e738
The mem address of file2 is 0x7ffce008e740


mp:projects-20:17:12-$ ./lseek_demo 
The end offset of file1 is 1268
The start  offset of file2 is 0
Diff between them is -1268
The mem address of file1 is 0x7fff9113e148
The mem address of file2 is 0x7fff9113e150

这是我正在使用的代码

#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <error.h>

void   offsets(const char* fname1,const char*  fname2)
{
        int fd0 = open(fname1, O_RDWR);
        int fd1 = open(fname2, O_RDWR);

        if (fd0 == -1 || fd1 == -1)
                perror("opne");

        off_t off_fd0 = lseek(fd0, -1, SEEK_END);
        off_t off_fd1 = lseek(fd1,0,SEEK_SET);


        close(fd0);
        close(fd1);

        printf ("The end offset of file1 is %ld\n The start  offset of file3 is %ld\n Diff between them is %ld\n",off_fd0, off_fd1,(off_fd1 - off_fd0));
        printf ("The mem address of file1 is %p\n The mem address of file2 is %p\n",&off_fd0,&off_fd1);
}

int main()
{
        offsets ("readme.txt","slack_space_calc.c");
        return 0;
}

这是编译于

ubuntu 6.8.0-38-generic #38-Ubuntu

c linux file
1个回答
0
投票

此代码:

        off_t off_fd0 = lseek(fd0, -1, SEEK_END);
        off_t off_fd1 = lseek(fd1,0,SEEK_SET);

声明两个(某些未指定位长度)有符号整数类型的局部变量,并将它们设置为

lseek()
的返回值。这些变量被下面的代码强制存储在堆栈上;稍后会详细介绍。

表达式

&off_fd0
返回指向
off_fd0
变量的指针,而不是“文件”的地址。因此,当您使用 %p 打印它时,您正在打印该堆栈变量的内存地址。

一个有趣的旁注。如果删除该 print 语句,编译器很可能会优化一个或两个变量。 IE。它将把

lseek()
调用的返回值保存在 CPU 寄存器中。此时,变量根本没有地址。 (这取决于您使用的编译器、目标 CPU 架构以及为编译选择的优化级别。)表达式
&off_fd0
的存在迫使编译器为该变量分配堆栈存储,并在此过程中您的代码效率稍低。

至于为什么这些变量的地址在一次运行中会有所不同。曾经有一段时间情况并非如此——每次运行程序时,堆栈都会位于同一个位置。欢迎来到 ASLR - 甚至堆栈也会移动。

© www.soinside.com 2019 - 2024. All rights reserved.