linuxso库的深化了解ITeye - 千亿集团

linuxso库的深化了解ITeye

2019年02月19日10时41分39秒 | 作者: 鸿朗 | 标签: 程序,途径,运转 | 浏览: 829


cat say.c  #include "stdio.h"
void say()
{
printf("Say!");
}
eof
cat test.c  #include "stdio.h"
void say();
main(){
say();
}
eof
gcc -c say.c
ar -r say.a say.o
gcc test.c say.a -o test
ldd test
输出成果让咱们看不到任何跟say.a这个咱们自己写的静态库的联系.阐明程序运转时现已不需求这个静态库了,它现已被ld链接进终究的程序了.
那么动态库,咱们持续
gcc -fPIC -shared say.c -o say.so
gcc test.c say.so -o test
ldd test
假如不出意外的话,会呈现say.so = not found.这时的./test是不能运转的.但至少阐明程序运转时是需求这个库的.那为什么找不到这个库呢?那就让咱们看看体系是怎样寻觅这些库的吧.
首要是ld-linux.so.2这个不能不说,它太重要了,以至于也决议了后边的查找办法.
先是程序内部决议的.
strings test 
还好咱们这个test程序不大,不必过滤输出,好,你看见什么,/lib/ld-linux.so.2,say.so,libc.so.6,对,用到的库!
但咱们发现不同,有的有途径,有的没有,先不论没有途径的怎样寻觅,有途径的肯定是能找到了,那好,咱们让say.so也有了途径.
gcc test.c ./say.so -o test2
strings test2
咱们发现本来的输出中本来的say.so现已变成了./say.so.运转一下./test2,能够运转了!好,找到库了,这儿用的相对途径,无疑,咱们将say.so移动到非当前文件夹.那test就又不能运转了.这样无疑是把咱们用到的库硬编码进了程序里.我不喜欢硬编码,太呆板.那不硬编码体系怎样找到咱们需求的文件呢.
在程序没有把库地址硬编码经进去的前提下,体系会寻觅LD_LIBRARY_PATH环境变量中的地址.
LD_LIBRARY_PATH=./ ./test2
如咱们所愿,程序正常运转.
假如体系在这一步也没发现咱们需求的库呢.
/etc/ld.so.cache这个由ldconfig生成的文件,记载着在/etc/ld.so.conf文件中指明的一切库途径加上/lib,/usr/lib里的一切库的信息.
其实以上这句话只是在大多数情况下是正确的,是否是这个文件由ld-linux.so.2决议.如过你的LFS中的第一遍东西链/tools还在的话,
strings /tools/lib/ld-linux.so.2|grep etc
输出很或许是/tools/etc/ld.so.cache.那么它用的哪个文件咱们就清楚了吧.
可这个途径前面的/tools究竟和什么有关呢?首要咱们或许会想到与ld-linux地点的方位有关.还好咱们有3套glib,感谢LFS,现在咱们拿第二遍的东西链下手.假定咱们的LFS在/lfsroot
strings /lfsroot/lib/ld-linux.so.2
很奇怪的是输出竟然是/etc/ld.so.cache!那这究竟和什么有关呢,没错就是咱们编译时分的prefix有关.
现在再看这个/etc/ld.so.conf,和/lib,/usr/lib这些默许ldconfig途径.也都要加上个这个prefix了.
strings /tools/sbin/ldconfig|grep etc
strings /tools/sbin/ldconfig|grep /lib

验证一下吧.

那要是ld.so.cache里也没有记载这个库的地址怎样办呢.
最终在默许途径里找.这个途径一般是/lib,/usr/lib,但也不全是.
strings /tools/lib/ld-linux.so.2|grep /lib
仍是要加个prefix.
现在咱们反过来考虑,不必程序中硬编码的/lib/ld-linux.so.2做动态加载器了.这也能够?!是的!尽管不必定成功.

LD_TRACE_LOADED_OBJECTS=y /tools/lib/ld-linux.so.2 /bin/test
LD_TRACE_LOADED_OBJECTS=y /lib/ld-linux.so.2 /bin/test
LD_TRACE_LOADED_OBJECTS=y /lfsroot/lib/ld-linux.so.2 /bin/test
试着比较成果吧.
不出意外的话第一个是在/tools/lib中查找的库,二三个都是在/lib中的库.原因我想上面现已说清楚了.
下面以第二个为例阐明问题:
LD_LIBRARY_PATH=./ /tools/lib/ld-linux.so.2 ./test
/tools/sbin/ldconfig ./;/tools/lib/ld-linux.so.2 ./test
cp ./say.so /tools/lib/;/tools/lib/ld-linux.so.2 ./test
三种办法应该都会呈现咱们想要的成果,这儿阐明/tools/lib/ld-linux.so.2在这儿的意义,是用/tools/lib/ld- linux.so.2这个做动态装载器.不信把这个去掉,后两种办法必定不可.由于以./test自己硬编码进去的/lib/ld-linux.so.2 来说,是不会去管/tools/etc/ld.so.cache,和/tools/lib下的库的.

为了阐明次序,咱们做如下很风险的试验:
ldconfig /lfsroot/lib;
ldconfig -p
会呈现许多内容,但不要试着过滤,由于这时的体系应该许多程序不能运转了.先踏下心来调查.你会发现许多库呈现两次/lfsroot/lib,和/lib 并且/lfsroot/lib在前,阐明ldconfig先处理参数给出的地址,最终是默许地址.但次序也不必定,应该还和编译glibc时咱们的参数- -enable-kernel有关(我依据种种体现猜想).
加上export LD_LIBRARY_PATH=/lib 环境变量在前面,不能运转的程序又能运转了,阐明LD_LIBRARY_PATH变量的优先级优于ld.so.cache
unset LD_LIBRARY_PATH
echo /etc/ld.so.cache
ldconfig -p
应该什么都不呈现,可大部分程序能运转.阐明ld-linux.so.2决议的默许途径起了效果(留意,这儿的ldconfig的默许途径没有效果)
ldconfig
康复体系正常.
假如你本意,能够chroot /lfsroot后,再做相似的操作看有什么不同.

懂了原理咱们就来使用一下.
拿./test2为例.
咱们把它的库给换了!!!
cat saa.c  #include "stdio.h"
say(){
printf("I can do something here!!!");
}
eof
gcc -fPIC -shared saa.c -o saa.so
sed "s#\./say\.so#./saa.so#" test test3
./test3
看看成果吧!
很令人惊讶是么,假如是setuid程序的话...其实这个也很难,由于这种程序咱们一般是无法写的(给自己搞破坏不算).这也就理解了为什么长久以来对setuid程序的权限一直如此注重由于太风险了.
惊讶往后你或许会想,关于未硬编码库地址的程序,咱们直接把LD_LIBRARY_PATH改了不也行么?!指向咱们的地址,用咱们的库,然后...底子不必改什么文件了,要什么写权限了.
呵呵,要真那么简单咱们心爱的Linux不也太软弱了,这恐怕就玩大了,也是你我都不本意见到的.所以,ld-linux.so.2早以作出限止,setsid程序,LD_LIBRARY_PATH变量不起效果.不过文件中的仍是有效果的.
最终,说一下ld,和ld-linux.so.2的差异,一个编译时用,一个运转时用,ld担任在它的查找途径里找到要求的库,并检查是否有供给了需求的符号(如函数等),假如有,记载相关信息到程序中,由ld-linux.so.2在执行时查找到该库并,并依据相关信息进行需求符号的重定位等作业.留意这两者的查找库的办法是不同的.
LC_ALL=C ld verbose|grep search -i
显现了它默许的查找地址.咱们能够做个试验.一般它会有个相似i686-pc-linux-gnu/lib的途径,一起是不在ld-linux.so.2的查找途径里的.其他的是咱们编译是with-lib-path和LIB_PATH变量指定的.
mv ./say.so XXXX/i686-pc-linux-gnu/lib/libsay.so
gcc -o test4 -lsay test.c 
ldd ./test4
成果肯定是libsay.so找不到的.

 

转自:

版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表千亿集团立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章

阅读排行

  • 1

    linuxso库的深化了解ITeye

    程序,途径,运转
  • 2
  • 3

    Linux操作笔记千亿集团

    目录,文件,体系
  • 4

    squid更新缓存csdn

    服务器,地址
  • 5

    几个有用的开源镜像环球

    体系,探究,总结
  • 6
  • 7

    用户指令alibaba

    用户,指令,修正
  • 8

    两台linux文件复制环球

    文件,运用,地址
  • 9
  • 10