庞大资源库的计算机教程网站!
设为首页
加入收藏
总编信箱
投稿或申请专栏请先 [登 陆]
首页 操作系统 程序设计 图形图像 媒体动画 机械电子 WEB开发 数 据 库 办公系列 路由技术 网络原理 网络应用
认证考试 安全技术
首页>操作系统>Linux>编程开发>正文
资料搜索
Google搜索
Google
返回上级列表

推荐文章

快速保存网页中所有图片的方法
Windows中让光驱巧妙“隐身”技
防范非法用户入侵Win 2000/XP系
两款比较典型的ASP木马防范方法
有关表格边框的css语法整理
Windows XP中可以被禁用的服务
SQL Server导出导入数据方法
Javascript所有对象的属性的获
网页(HTML)中的特殊字符
与篮球共舞,尽显模式本色
QQ病毒的手工清除方法
Photoshop为极品美女打造性感睫
天衣无缝:IIS与PHP水火也相容
SQL Server存储过程编写和优化

覆盖 GNU C 库轻而易举

 作者:本站收集   日期:2005-4-14
字号选择〖 〗/ 双击滚屏 单击停止   
调试系统问题并进行快速修订

一种调试 glibc 函数的好方法是用您自己的版本覆盖所关注的函数。在没有 root 许可权和不必重新编译 libc 源代码的情况下就可以完成这个任务。想象一下编写您自己的 open() 版本该有多激动啊!

如果您没有应用程序的源代码并且由于 C 的 GNU 库(glibc)函数正将某些错误信息返回给该应用程序而使它失败,那么您该怎么办?因为 glibc 是开放源码,所以您当然可以获得其源代码、对它进行更改、重新构建和安装。然而,这不适合那些胆怯的人,因为虽然 API 有很好的文档说明,但 GNU C 库的内部组织却没有。查找正确的函数原型只是众多挑战中的第一个。它还是一个很大的包,所以第一次编译时,它将花一些时间(glibc 2.2.2 有 8552 个文件和 1775440 行代码,包括注释)。

更好的方法

比重新构建 glibc 更好的方法是选择性地覆盖一个函数。许多现代的 Unix 都支持预装入用户定义库这一概念。这些库可以是完整的替代(即,glibc 的专用版本)也可以是子集 — 甚至是一个函数。首先,通过设置 LD_LIBRARY_PATH 来包含库的专用版本,您可以使用 glibc 的专用版本。可通过使用 LD_PRELOAD 环境值来使用您编写的库例程的子集。LD_LIBRARY_PATH 和 LD_PRELOAD 都是由动态 ELF 链接器/装入器控制的。它使用第一个匹配来满足任何符号名。通过预装入您自己的库或函数版本,您“短路”了正常路径,这样就允许您覆盖它。

这里是一个示例 makefile,它覆盖 glibc 函数 setresgid():

覆盖 setresgid() 的 Makefile
#
# Makefile
#

all: libs setresgid-tester

#
# Make a shared Library
#
libs: libfuncs.c
gcc -shared -Wl,-soname,libfuncs.so.1 -o libfuncs.so.1.0 libfuncs.c
ln -s libfuncs.so.1.0 libfuncs.so.1
ln -s libfuncs.so.1 libfuncs.so

#
# Here is a program that calls setresgid() for testing
#
setresgid-tester: setresgid-tester.c
gcc -o setresgid-tester setresgid-tester.c



文件 libfuncs.c 包含我的 setresgid() 专用版本。实现它以支持与原始 setresgid() 相同的参数数目时要小心,并在其它方面完成与原始 setresgid() 相同的操作,尽管我的版本欺骗该应用程序并始终返回 0。

关注的第二个文件是 setresgid-tester.c。它通过调用 setresgid() 试验新函数

这是动态库的源代码:

替换库
/*
Put all the functions you want to override here
*/
#include
#include
#include

int errno;

int
setresgid(rgid, egid, sgid)
gid_t rgid,egid,sgid;
{
errno=1;
printf("It me the shim, Hi there!\n");
return(0);

}



您还需要一个简单方法来测试您的 setresgid() 专用版本。可以使用 strace 或 ltrace 来监视进程运行。这是普通测试示例的源代码:

普通测试示例
/*
setresgid() system/library call tester
*/
#include
#include
main(){
setresgid(0,0,0);
}



现在,编译该库,设置 LD_PRELOAD shell 变量,然后运行测试应用程序。您可能还需要设置 LD_LIBRARY_PATH。

运行测试应用程序
export LD_PRELOAD=libfuncs.so
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./setresgid-tester
It's me the shim, Hi there!



还可以通过使用 ldd 列出动态链接库来确认是否正在使用专用库:

确认专用库的使用
[jay@prion ld_preload]$ ldd setresgid-tester
libfuncs.so => libfuncs.so (0x40018000)
libc.so.6 => /lib/libc.so.6 (0x40022000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)



结束语

编写 GNU C 库函数的专用版本是调试系统问题或进行快速修正的好方法。使用 LD_PRELOAD shell 变量,可以选择性地用您自己的专用版本来覆盖系统 C 库函数。这种技术可用于 Linux 和 Solaris 环境。

关于作者

Jay Allen 是 IBM Linux for Service Providers Lab(LSPL)的程序员。可以通过 jaydallen@us.ibm.com 与 Jay 联系。
上一篇:Linux文件系统的桌面应用    下一篇:如何得到constructor 和 copy constructor 执行次数  
[发送给好友]  [关闭窗口]  [返回顶部]   转载请注明来源:www.it00.com   
特别声明: 本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系编辑人员,我们尽快予以更正。
责任编辑: 原点 投稿作者: 本站收集
信息来源: 网络 录入时间: 2005-4-14
关于我们 - 广告服务 - 版权申明 - 网站地图 - 联系方式 - 总编信箱 - 会员投稿