首页 理论教育 深入剖析Linux内核安全模块,动态链接可执行文件

深入剖析Linux内核安全模块,动态链接可执行文件

时间:2023-11-22 理论教育 版权反馈
【摘要】:将它编译为使用动态链接库的可执行文件:运行的结果是:开始的三个地址区,对应被执行文件mem_layout,没有被随机化处理。结合ELF文件格式,我们再看:mem_layout的ELF文件类型是可执行文件,并且有一个“INTERP”段。这两条是动态链接的可执行文件的特征。ELF文件中规定的两个虚拟地址,一个是0x400000,一个是0x600e10,页对齐后为0x600000,由此可见,内核对动态链接的可执行文件的code区和data区没有做地址随机化处理。

深入剖析Linux内核安全模块,动态链接可执行文件

下面这个小程序,读出/proc/self/maps内容,写到标准输出之中。

将它编译为使用动态链接库的可执行文件:

运行的结果是:

开始的三个地址区,对应被执行文件mem_layout,没有被随机化处理。无论运行多少遍,地址都是一样的。这三个地址区中,第一个是代码,第二个和第三个是数据。其后的地址区,依次是堆、mmap区、栈、vdso和vsyscall。除了最后一个vsyscall外,地址都被内核做了随机化处理。(www.xing528.com)

结合ELF文件格式,我们再看:

mem_layout的ELF文件类型是可执行文件(EXEC),并且有一个“INTERP”段。这两条是动态链接的可执行文件的特征。它有两个“LOAD”段,第一个对应代码,规定加载入进程的虚拟地址起始于0x400000,这个和前面运行程序的输出一致。第二个对应数据,规定数据起始于文件的偏移0xe10,在文件中长度为0x260,加载入进程的虚拟地址起始于0x600e10,在进程中长度为0x268。这里有两个问题,首先是由于内核内存管理要页对齐,Linux内核在x86架构下一页是4096B,即0x1000。0xe10向上对齐页面地址得到的地址值为0,所以内核将起始于文件偏移0的两页数据映射入进程的虚拟地址空间,在进程中起始地址为0x600000。其次,文件的长度和进程中内存的长度不一致,一个是0x260,一个是0x268。多出的部分就是所谓的bss [7] ,对应一些初始值为0的变量,没有必要在文件中占用空间,内核初始化内存时自动将这部分对应内存清为0。ELF文件中规定的两个虚拟地址,一个是0x400000,一个是0x600e10,页对齐后为0x600000,由此可见,内核对动态链接的可执行文件的code区和data区没有做地址随机化处理。

还有一个问题,ELF文件中有两个LOAD段,而在进程中有三个地址区和ELF文件对应,一个代码,两个数据。这是为什么呢?这是加载程序(loader)做的手脚,内核准备好内存后,就将运行控制交给了用户态的加载程序,在本例中就是/lib64/ld-linux-x86-64.so.2。在这个时候data区还只有一个,而且是可读可写。加载程序修改了一个或几个数据后,通过系统调用mprotect将一部分data区标记为只读。内核响应请求就将data区一分为二,一部分只读,一部分可读可写。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈