找回密码
 赶紧注册吧

QQ登录

只需一步,快速开始

查看: 2442|回复: 0
打印 上一主题 下一主题

惊疑过后你可能会想 [复制链接]

注意:1、各网友务必提高交友安全意识,不要轻易参加非天府交友网官方举办的见面交友活动,以防酒托,饭托或引发其他危险;请详细阅读《天府交友网服务条款》和《免责申明》!

Rank: 3Rank: 3

升级  67.67%

跳转到指定楼层
楼主
发表于 2011-10-24 04:09:36 |只看该作者 |倒序浏览
相关的主题文章:

  
   13件 在日本还不发明有人能够
  
   看了这些小跟尚
  
   渗透我的血液
  
   深夜闻声有女子哭声
  
   我母亲就拿了个空瓶给他
  
关于库的深刻思考Linux
常常见有人提起对于库的种种问题,今天我也终于按捺不住,依据自己的教训,试验,学习中得到的一些,来说说自己的一点见解.
我们都晓得库对系统的主要.没了它,系统简直无法运行,包含LFS全部过程至少是对工具链调剂来调整去的进程是以对库的倚赖为中心的.这其中又以动态库为精髓.
那先来说简单的静态库.它简略到只是ar打包的目的文件的聚集罢了,于是,它的作用也就和目标文件没什么区别了,链接进目标文件,ok,使命实现,至于程序当前的事包括运行则和这个静态库没有关系了.其实我觉的最有压服力的就是例子了,那我们就举最简单的例子.
cat >say.c<<eof
#include "stdio.h"
void say()
{
printf("Say!");
}
eof
cat >test.c <<eof
#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 <<eof
#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找不到的.
好了,写到这吧,想起什么再加,有什么错误的处所也望大家多多提出来^^
------------------Skymoon作品,转贴请注明出处作者.
分享到: QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏0

使用道具 举报

※为保护您的个人隐私,防止被恶意盗用,在论坛中不得留下手机、QQ、邮箱等联系方式,否则将被屏蔽!,若有需要,请发送站内消息
您需要登录后才可以回帖 登录 | 赶紧注册吧

关于我们|网站地图|帮助中心|商务合作|法律声明|诚聘英才|联系我们| 时尚 娱乐 成都婚庆公司 网站制作天府星空
Copyright © 2010-2011 天府交友(Www.Tflove.Com)版权所有