LD_PRELOAD和ld --wrap
前言
LD_PRELOAD和ld --wrap都能实现不修改原始代码,替换指定函数的实现。通常我们会使用这些方法,替换如malloc)()/free()、read()/write()等函数,并在替换函数中做一些记录,以便能分析程序执行时的内存分配和IO情况。这些函数一般叫包裹函数。
LD_PRELAD
链接器会检查LD_PRELOAD这个环境变量,如果不为空,则优先使用LD_PRELOAD指定的动态库中的符号,以malloc()/free()为例。
代码清单 main.c
int main()
{
malloc(10);
return 0;
}
代码清单 my.c
void* malloc(size_t size)
{
void (*__real_malloc)(int) = NULL;
// 获取真实的malloc()地址
__real_malloc = dlsym(RTLD_NEXT, "malloc");
void* ptr = __real_malloc(size);
printf("[malloc] addr=%p, size=%u\n", ret, size);
return ptr;
}
void free(void* ptr)
{
printf("[free] addr=%p", ptr);
void (*__real_free)(void*) = NULL;
__real_free = dlsym(RTLD_NEXT, "free");
return __real_free(ptr);
}
gcc main.c -o test将main.c编译成test,gcc -fPIC -shared my.c -o libmy.somy.c编译成libmy.so。
export LD_PRELOAD=./libmy.so后执行test会发现,main()中执行的malloc()实际是libmy.so中的malloc(),其会输出分配的内存地址和大小。因为没有free的输出,所以我们可以得知test存在内存泄漏。这是一个很简陋的例子。
export使得LD_PRELOAD对所有该终端执行的程序都生效,不使用时还需要unset LD_PRELOAD,我们可以通过LD_PRELOAD=./libmy.so ./test使得其只对test生效。
LD_PRELOAD的本质是先加载的先使用。就像我们在编译时会发现如果两个库中有同名函数,那么哪个库在前,就用哪个库中的函数。
ld --wrap
ld --wrap是一个编译链接时的参数,其原理是在编译时将--wrap指定的函数名进行替换,其替换规则就是替换规则就是包裹函数前加__wrap_,真实函数前加__real_,比如gcc main.c -o test -Wl,--wrap=malloc,编译器会将调用malloc()的地方替换为__wrap_malloc(),并将__real_malloc()符号名映射到真实malloc()的地址。
此时my.c的实现就不一样了,我们需要提供__wrap_malloc(),并在真正需要调用malloc()的地方使用__real_malloc()。
void* __wrap_malloc(size_t size)
{
void* ptr = __real_malloc(size);
printf("[malloc] addr=%p, size=%u\n", ret, size);
return ptr;
}
void __wrap_free(void* ptr)
{
printf("[free] addr=%p", ptr);
return __real_free(ptr);
}
如果有比较多的--wrap,那么可以将其放在一个文件中,假设文件名为ld-opt,其内容如下
--wrap=malloc
--wrap=free
使用gcc main.c -o test -Wl,@ld-opt就能替换malloc和free了。
ld --wrap的本质是按指定规则替换符号名(malloc->__wrap_malloc),并将特定符号与执行代码关联(__real_malloc->maloc代码)。
LD_PRELOAD和ld --wrap的更多相关文章
- Linux下的库操作工具-nm、ar、ldd、ldconfig和ld.so
Linux下的库操作工具-nm.ar.ldd.ldconfig和ld.so .nm [options] file 列出file中的所有符号 [option] -c 将符号转化为用户级的名字 -s 当用 ...
- CSAPP CH7链接的应用:静动态库制作与神奇的库打桩机制
目录 创建静态库 创建动态库 库打桩机制 编译时打桩: 链接时打桩 运行时打桩 运行时打桩的printf与malloc循环调用debug 使用LD_PRELOAD对任意可执行程序调用运行时打桩 总结 ...
- How to install 64-bit Google Chrome 28+ on 64-bit RHEL/CentOS 6 or 7
How to install 64-bit Google Chrome 28+ on 64-bit RHEL/CentOS 6 or 7 The problem Google developers s ...
- ERROR: ld.so: object '/usr/lib64/libtcmalloc.so.4' from LD_PRELOAD cannot be preloaded: ignored
出现错误: ERROR: ld.so: object '/usr/lib64/libtcmalloc.so.4' from LD_PRELOAD cannot be preloaded: ignore ...
- Linux Dynamic Shared Library && LD Linker
目录 . 动态链接的意义 . 地址无关代码: PIC . 延迟版定(PLT Procedure Linkage Table) . 动态链接相关结构 . 动态链接的步骤和实现 . Linux动态链接器实 ...
- gcc ld 链接器相关知识,调试指令(程序员的自我修养----链接、装载与库)
最近解决一个动态链接上的问题,因为以前从来没有接触过这方面的知识,所以恶补了一下,首先要了解gcc编译指令(makefile),ld链接器的选项(还有连接脚本section指定内存位置),熟悉查看连接 ...
- 【Linux】LD_PRELOAD用法
转载https://blog.csdn.net/iEearth/article/details/49952047 还有一篇博客也可以看看https://blog.csdn.net/xp5xp6/art ...
- LD_PRELOAD & LD_LIBRARY_PATH 动态库路径
参考:http://www.cnblogs.com/waterlin/archive/2011/07/14/2106056.html 143上的glibc较低,同学又不能进行升级(造成全局影响),所以 ...
- 使用LD_Preload的Linux权限升级技巧
0x00 前言 共享库是程序在启动时加载的库.正确安装共享库后,之后启动的所有程序将自动使用新的共享库. 0x01 共享库名称 每个共享库都有一个名为soname的特殊名称.soname有前缀li ...
随机推荐
- k8s学习 - 概念 - ReplicationController
k8s学习 - 概念 - ReplicationController 我们有了 pod,那么就需要对 pod 进行控制,就是同一个服务的 podv我需要启动几个?如果需要扩容了,怎么办?这里就有个控制 ...
- NOIP2015斗地主题解 7.30考试
问题 B: NOIP2015 斗地主 时间限制: 3 Sec 内存限制: 1024 MB 题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共 ...
- vmware的卸载
vmware出了点问题,在控制面板里或者是360都没法删除干净.在网上搜了点资料,找到一些删除的方法,参考链接如下: http://zhidao.baidu.com/question/30902992 ...
- python爬虫笔记之爬取足球比赛赛程
目标:爬取某网站比赛赛程,动态网页,则需找到对应ajax请求(具体可参考:https://blog.csdn.net/you_are_my_dream/article/details/53399949 ...
- 自定义new和delete
#include "stdafx.h" #include <stdlib.h> #include <malloc.h> #include <iostr ...
- c++小游戏——拯救公主
#include<stdio.h> #include<ctime> #include<time.h> //suiji #include<windows.h&g ...
- java高并发系列 - 第15天:JUC中的Semaphore,最简单的限流工具类,必备技能
这是java高并发系列第15篇文章 Semaphore(信号量)为多线程协作提供了更为强大的控制方法,前面的文章中我们学了synchronized和重入锁ReentrantLock,这2种锁一次都只能 ...
- 个人永久性免费-Excel催化剂功能第36波-新增序列函数用于生成规律性的循环重复或间隔序列
啃过Excel函数的表哥表姐们,一定对函数的嵌套.数组公式等高级的应用有很深的体会,威力是大,但也烧死不少脑细胞,不少人就在这样的绕函数中光荣地牺牲了,走向从入门到放弃.Excel催化剂的创立,初衷就 ...
- python函数闭包-装饰器-03
可调用对象 callable() # 可调用的(这个东西加括号可以执行特定的功能,类和函数) 可调用对象即 callable(对象) 返回为 True 的对象 x = 1 print(cal ...
- 十、SQL中EXISTS的用法 十三、sql server not exists
十.SQL中EXISTS的用法 EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False EXISTS 指定一个子查询,检测 行 的存在. 语法 ...