覆盖 GNU C 库 ― 轻而易举

2024-01-14 09:32
文章标签 覆盖 gnu 轻而易举

本文主要是介绍覆盖 GNU C 库 ― 轻而易举,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

覆盖 GNU C 库 ― 轻而易举

调试系统问题并进行快速修订


级别: 初级

Jay Allen (jaydallen@us.ibm.com), 程序员, IBM

2002 年 4 月 01 日

一种调试 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_PATHLD_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 联系。


From: http://www.ibm.com/developerworks/cn/linux/l-tip-prompt/tip18/index.html

这篇关于覆盖 GNU C 库 ― 轻而易举的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/604709

相关文章

最大流=最小割=最小点权覆盖集=sum-最大点权独立集

二分图最小点覆盖和最大独立集都可以转化为最大匹配求解。 在这个基础上,把每个点赋予一个非负的权值,这两个问题就转化为:二分图最小点权覆盖和二分图最大点权独立集。   二分图最小点权覆盖     从x或者y集合中选取一些点,使这些点覆盖所有的边,并且选出来的点的权值尽可能小。 建模:     原二分图中的边(u,v)替换为容量为INF的有向边(u,v),设立源点s和汇点t

POJ3041 最小顶点覆盖

N*N的矩阵,有些格子有物体,每次消除一行或一列,最少要几次消灭完。 行i - >列j 连边,表示(i,j)处有物体,即 边表示 物体。 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;impo

G++(GNU C++)安装及使用(windows)

安装步骤: 1、下载 Cygnus 的G++编译器(http://www.claremontmckenna.edu/math/ALee/g++/full.exe),并保存到E盘(或其它任意盘),格式为E:full.exe。 2、直接运行该文件,可能需要十几分钟的时间(中间会有停顿甚至没有任何提示性图片或者符号,需要耐心等待哦)。       或者Win + R ,输入cmd,按Ent

Minimal coverage -uva 覆盖线段,贪心

一道经典的贪心问题,具体方法就是将(an,bn)区间,按照an从小到大的顺序进行排序,之后从0开始, 取最大的有效区间,这里用到了结构体的快排,否则可能会超时. #include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX_SIZE 100000 + 10#define BOTTOM -50000 - 10str

过滤器:覆盖过滤器如何在凝结水处理系统中应用

本文介绍了覆盖过滤器的基本原理,阐述了覆盖过滤器处理凝结水中悬浮物和胶体的工艺流程及铺膜、过滤、爆膜等环节的操作规范。指出覆盖过滤器在运行中存在铺不上膜、铺膜不匀、脱膜等常见的故障并提出处理方法。   0·引言   凝结水处理系统设置覆盖过滤器的目的是除去凝结水中的金属腐蚀物及油类等杂质。这些杂质通常为悬浮颗粒和胶体,如果不被滤除,会污染离子交换树脂,反冲洗过滤器原理使其交换量下降,工作周

GNU工具集和MinGW

GNU工具集         GNU工具集包含了一系列的基本工具和实用程序,这些工具为系统管理员、开发人员和普通用户提供了丰富的功能和工具支持。         许多开源软件和项目都依赖于GNU工具集提供的稳定和强大的功能,因此GNU工具集的发展与完善对整个开源社区都具有重要意义。通过GNU工具集,用户可以在命令行下完成各种任务,如文件操作、进程管理、编程开发等,为用户提供了强大的工具支持。

AcWing907. 区间覆盖

参考的视频讲解:↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 【贪心算法08-区间问题03-区间覆盖】 每次贪心就是选择左端点里面<起始端点里面右边界最大的,这样就是保证了最少区间个数! 然后每次迭代都会更新一次起始端点st,反复运用本算法。 一定要仔细看视频讲解!!! #include<iostream>#include<algorithm>#define N 100010#define INF 2

GNU的伪操作 (25)

这里主要是 对 GNU的 各个伪操作进行 详细的解释。 先来看着几个 伪操作。 .byte,  .short,  .long,  .quad , .float ,  这个是关于 字节的。 .string   .ascii 是关于字符串的。 这个字符串编译器是可以自动在末尾补0 的。 举例: val:         .word 0x11223344         m

牛客网《剑指Offer》 矩形覆盖

题目描述 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? class Solution {public:int rectCover(int number) {if(number==0) return 0;if(number==1) return 1;if(number==2) return 2;retu

【HDU】3861 The King’s Problem 强连通缩点+有向图最小路径覆盖

传送门:【HDU】3861 The King’s Problem 题目分析:首先强连通缩点,因为形成一个环的王国肯定在一条路径中,这样才能保证拆的少。 然后缩点后就是DAG图了,由于题目要求的是最小路径覆盖,那么二分匹配即可。 代码如下: #include <cstdio>#include <cstring>#include <algorithm>#includ