查看正在运行的动态链接的程序中,某个动态库中函数的虚拟地址

目前,大部分可执行程序为了节省内存空间等目的,都是动态链接的, 动态链接的程序在每次运行时,所依赖的动态库的地址总是变化的,那么库中的函数地址也跟着变化。如何在程序(动态链接的)运行期间,查看某个库函数的虚拟地址?

方法很简单,首先确定,你需要查看的函数,在哪个动态库中,并且确定该函数相对于该动态库的相对地址。其次,在程序运行期间,查看程序的映射表,找到动态库的加载地址。最后将这两个地址相加,就是你要的库函数在运行时的虚拟地址。

我的系统是64位Ubuntu 12.04.1 LTS。

举例如下:

1、编写测试程序hello.c:

#include <stdio.h>
int main()
{
        printf("Hello world\n");
        sleep(-1);
        return 0;
}

加sleep的原因是,我们需要看到该程序运行时的状态,执行完了就看不到其链接状态了。printf就是动态库libc-2.15.so中的一个函数(在你的系统上也有可能是其他库的名字比如libc-2.13.so)。

2、编译运行

# gcc hello.c  (不加-static,默认就是动态链接)

# ./a.out & (后台运行,并且打印出程序pid)

           [3] 1049   

3、打印进程映射信息,得到进程运行时的动态库基地址:

root@Heron :/home# cat /proc/1049/maps 
00400000-00401000 r-xp 00000000 08:01 2364347                            /home/zhangqianlong/Lib_test/a.out
00600000-00601000 r--p 00000000 08:01 2364347                            /home/zhangqianlong/Lib_test/a.out
00601000-00602000 rw-p 00001000 08:01 2364347                            /home/zhangqianlong/Lib_test/a.out
7fa5b9f44000-7fa5ba0f9000 r-xp 00000000 08:01 5243800                    /lib/x86_64-linux-gnu/libc-2.15.so
7fa5ba0f9000-7fa5ba2f8000 ---p 001b5000 08:01 5243800                    /lib/x86_64-linux-gnu/libc-2.15.so
7fa5ba2f8000-7fa5ba2fc000 r--p 001b4000 08:01 5243800                    /lib/x86_64-linux-gnu/libc-2.15.so
7fa5ba2fc000-7fa5ba2fe000 rw-p 001b8000 08:01 5243800                    /lib/x86_64-linux-gnu/libc-2.15.so
7fa5ba2fe000-7fa5ba303000 rw-p 00000000 00:00 0 
7fa5ba303000-7fa5ba325000 r-xp 00000000 08:01 5243815                    /lib/x86_64-linux-gnu/ld-2.15.so
7fa5ba508000-7fa5ba50b000 rw-p 00000000 00:00 0 
7fa5ba522000-7fa5ba525000 rw-p 00000000 00:00 0 
7fa5ba525000-7fa5ba526000 r--p 00022000 08:01 5243815                    /lib/x86_64-linux-gnu/ld-2.15.so
7fa5ba526000-7fa5ba528000 rw-p 00023000 08:01 5243815                    /lib/x86_64-linux-gnu/ld-2.15.so
7ffff2260000-7ffff2281000 rw-p 00000000 00:00 0                          [stack]
7ffff2383000-7ffff2384000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

 

以上内容,红色部分就是动态库libc-2.15.so的运行时基地址

对于maps文件的解析:

一共有6列
第一列代表内存段的虚拟地址
第二列代表执行权限,r,w,x不必说,p=私有 s=共享
不用说,heap和stack段不应该有x,否则就容易被xx,不过这个跟具体的版本有关
第三列代表在进程地址里的偏移量
第四列映射文件的主设备号和次设备号
通过 cat /proc/devices
得知fd是253 device-mapper

第五列映像文件的节点号,即inode

第六列是映像文件的路径

 

4、查看动态库中,printf函数的相对地址:

# nm -D libc-2.15.so |grep -w printf  

0000000000053840T printf

nm意思不懂得自己去man以下,-w是抓取一个字,以上红色部分就是printf函数对于动态库libc-2.15.so的相对地址

5、计算函数printf在动态运行时的虚拟地址:

0000000000053840 +7fa5b9f44000=7FA5B9F97840

 

不同的系统,得出的结果有可能是不一样的,同一个系统,测试两次结果肯定是不一样的,因为动态链接的库,每次的加载地址都不一样。

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值