111111
精灵王
精灵王
  • 注册日期2010-12-08
  • 发帖数640
  • QQ
  • 火币1103枚
  • 粉丝120
  • 关注75
  • 社区明星
阅读:3664回复:0

GNUC库----调试系统问题并进行修订

楼主#
更多 发布于:2011-01-08 21:08
  一种调试 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 环境。


更多黑客技术 黑客软件 计算机技术 编程技术 网站技术 qq技术 IT新闻 黑客基地 请访问 灯火安全联盟  灯火黑客 www.hack8888.com/bbs

喜欢0 评分0
游客

返回顶部