十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

为什么 ‘ldd’ 和 ‘(gdb) info sharedlibrary’ 显示不同的动态库基地址?

为什么 ‘ldd’ 和 ‘(gdb) info sharedlibrary’ 显示不同的动态库基地址? 目录一、准备 二、疑问 三、回答 四、总结 本文在调试过程中发现ldd和(gdb) info sharedlibrary显示不同的动态库加载基地址然后查了一些资料后找到了这篇帖子【 传送门】现做一下复现但是还是不知道ldd 目标文件这个命令打印的地址是什么地址如果有哪位大佬知晓望不吝相告谢谢。一、准备 /* test.c */#includestdio,hintmain(intargc,constchar*argv[]){printf(hello world\n);while(1);}编译gcc -m32 -no-pie -fno-stack-protector -z execstack -o test test.c-m32生成32位的可执行文件。-no-pie关闭可执行文件位置无关代码默认是关闭的所以可不加有些加上该选项后还会报错。-fno-stack-protector关闭Stack Protector/Canary栈保护-z execstack关闭DEP/NX堆栈不可执行-o输出test编译生成文件的文件名test.c编译前的源文件查看ASLRcat /proc/sys/kernel/randomize_va_space如果为0表示处于关闭状态。切换至root用户关闭ASLRecho 0 /proc/sys/kernel/randomize_va_space当需要开启时将 0 换成 1 或 2 即可。这里复现时需要关闭掉 ASLR二、疑问 方式一、根据ldd命令可知libc的加载地址为0xb7e40000方式二、使用GDB调试命令info sharedlibrary可知libc的加载地址为0xb7e34f70方式三、当我们用手动的方式通过符号计算动态加载基地址首先通过GDB获得system函数加载的基地址0xb7e5d0b0。使用IDA Pro软件查看 system 函数在动态库中的偏移得到0x0003F0B0则动态库加载基地址为0xb7e5d0b0 - 0x0003F0B0 0xb7e1e000总共获得了三种结果所以哪一种结果是正确的方式一0xb7e40000方式二0xb7e34f70方式三0xb7e1e000三、回答 方式三获得的地址正确首先ldd命令并不能准确的确定动态库加载基地址至于这个地址是什么的地址目前还不知道。如果要获得动态库加载基地址需要用到环境变量LD_TRACE_LOADED_OBJECTS。这里需要关闭ASLR不然每次查找基地址时都会发生变化也正是由于这种变化才能保护程序不容易被攻破。用法LD_TRACE_LOADED_OBJECTS1 可执行程序 | grep libc例如LD_TRACE_LOADED_OBJECTS1 ./test | grep libc少./可能出错其次如何查看程序在运行时动态库加载的基地址方法一运用/proc/进程号/maps这里以libc.so.6该动态库为libc-2.15.so的软链接为例子① grep libc /proc/进程号/maps | head -n1② cat /proc/进程号/maps | grep libc方法二在 GDB 调试中使用info proc mapping查看。验证已经知道动态库加载基地址的正确地址那info sharedlibrary的地址是什么通过以下命令查看代码段在动态库中的偏移地址为0x00016f70。在开启ASLR的情况下动态库的每次加载地址都是随机的但是当通过GDB进行调试的时候会关闭ASLR功能。通过 GDB 中的info proc mapping命令查看动态库加载的基地址为0xb7e1e000通过info sharedlibrary命令查看动态库时的地址0xb7e34f70是什么地址如果将这三个数据进行一次运行结果会很明了0xb7e34f70 0xb7e1e000 0x00016f70因此可以推断出info sharedlibrary命令查看动态库代码段加载的基地址。四、总结 ldd 目标文件方式并不能准确的查看某个动态库的加载基地址目前该命令所显示的地址是什么地址还不明确。查看动态库的加载基地址方式有如下几种①LD_TRACE_LOADED_OBJECTS1 可执行程序 | grep 动态库名② 运用/proc/进程号/maps③ 在 GDB 调试中使用info proc mapping查看如果系统开启 ASLR则每次的加载地址都是变化的但是GDB调试时会将该功能禁止。在 GDB 调试中info sharedlibrary命令查看的是动态库代码段的起始地址。参考[1]: Why does ldd and (gdb) info sharedlibrary show a different library base address? [2]: linux动态库运行时函数地址怎么查看器,查看正在运行的动态链接的程序中某个动态库中函数的虚拟地址…
返回列表