Linux 库打桩机制
库打桩机制
Linux 链接器截获对共享库函数调用,转而执行自己的代码。
创建一个包装函数,对库函数进行包装(装饰器模式)。利用打桩机制欺骗系统去调用包装函数。
编译时打桩
// malloc.c
// 对 malloc、free 的包装函数#ifdef COMPILETIME
#include <stdio.h>
#include <malloc.h>
void *my_malloc(size_t size) {void *ptr = malloc(size);printf("malloc(%d) = %p\n", (int) size, ptr);return ptr;
}
void my_free(void *ptr) {free(ptr);printf("free(%p)\n", ptr);
}
#endif
// malloc.h
// 包装函数声明,并且利用宏替换目标函数和包装函数#define malloc(size) my_malloc(size)
#define free(ptr) my_free(ptr)void *my_malloc(size_t);
void my_free(void *);
// main.c
// 测试代码#include <stdio.h>
#include <malloc.h>int main() {int *p = malloc(32);free(p);return 0;
}
$ gcc -c -DCOMPILETIME malloc.c # 编译模块
$ gcc -I. -o main main.c malloc.o # 进行链接,-I. 先从当前目录开始找头文件
$ ./main
# 执行结果如下
malloc(32) = 0xf5e2a0
free(0xf5e2a0)
在链接时引入的是自己的头文件,所以会执行宏替换,转而执行自己的包装函数。
链接时打桩
// malloc.c
// 对 malloc、free 的包装函数#ifdef LINKTIME
#include <stdio.h>void *__real_malloc(size_t);
void __real_free(void *);void *__wrap_malloc(size_t size) {void *ptr = __real_malloc(size);printf("malloc(%d) = %p\n", (int) size, ptr);return ptr;
}
void __wrap_free(void *ptr) {__real_free(ptr);printf("free(%p)\n", ptr);
}
#endif
$ gcc -DLINKTIME malloc.c -c
$ gcc -c main.c
# -W1 对链接器传递参数,`,` 会被转义为空格
$ gcc -Wl,--wrap,malloc -Wl,--wrap,free -o main main.o malloc.o
$ ./main
# 执行结果如下
malloc(32) = 0x22342a0
free(0x22342a0)
--wrap f
告诉链接器把 f
解析成 __wrap_f
,然后把 __real_f
解析成原本的 f
。
换句话说,就是原来的 f
就是 __real_f
,而别人调用的 f
就成了包装后的 __wrap_f
。
所以 main
中调用的 malloc
free
就成了包装后的函数。
运行时打桩
// malloc.c
// 对 malloc、free 的包装函数#ifdef RUNTIME
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>void *malloc(size_t size) {// printf 函数会调 malloc,所以要判断一下,防止无限递归爆栈static __thread int cnt = 0;cnt++;void *(*mallocp)(size_t) = dlsym(RTLD_NEXT, "malloc");void *ptr = mallocp(size);if (cnt == 1)printf("malloc(%d) = %p\n", (int) size, ptr);return ptr;
}
void free(void *ptr) {void *(*freep)(void *) = dlsym(RTLD_NEXT, "free");freep(ptr);printf("free(%p)\n", ptr);
}
#endif
$ gcc -DRUNTIME -shared -fpic -o malloc.so malloc.c -ldl
$ gcc -o main main.c
$ ./main
# 没有输出
$ LD_PRLOAD="./malloc.so" # 将路径加入环境变量下
$ ./main
# 执行结果如下
malloc(32) = 0x8b12a0
free(0x8b12a0)
动态链接器会先搜索环境变量 LD_PRELOAD
下的库,再搜索其他库。所以在 LD_PRELOAD
中放入自己实现的库,就可以实现运行时打桩。
总结
编译时打桩,需要访问源码,属于硬编码。
链接时打桩,虽然不用硬编码,但是必须要用到可重定位文件,再将其链接。也不够灵活。
运行时打桩,只需要在 LD_PRELOAD
环境变量下加入自己的动态链接库地址。非常灵活,也容易对别人的设备搞破坏。
Linux 库打桩机制相关推荐
- “偷梁换柱”的库打桩机制
原文地址:https://www.yanbinghu.com/2019/07/28/59484.html 前言 假如由于调试需要,你希望原先代码中的malloc函数更换为你自己写好的malloc函数, ...
- Linux 程序开发 之 库打桩机制
目录 前言 一.库打桩定义 二.编译时打桩 三.链接时打桩 四.运行时打桩 五.处理目标文件的工具 前言 Linux 链接器支持一个很强大的技术,称为库打桩(library interpositi ...
- Linux下的LD_PRELOAD环境变量与库打桩
Linux下的LD_PRELOAD环境变量与库打桩 LD_PRELOAD是Linux系统的一个环境变量,它可以影响程序的运行时的链接(Runtime linker),它允许你定义在程序运行前优先加载的 ...
- 动态链接--打桩机制
链接器的输出为可执行文件.可以在链接器上做事情,加载器是运行前置,加载器也可以做很多事情. 动态链接,在加载器加载可执行文件时,先加载和运行动态链接器,然后动态链接器动态链接共享库.用于解决静态库的缺 ...
- linux程序打桩,一文搞懂linux的库打桩
Linux下的链接器支持一个强大的库打桩(library interpositioning),允许你阻拦对系统标准库中某个目标函数的调用,取而代之执行自己的包装函数.它可以给我们带来两个好处,一是通过 ...
- Linux C 库打桩技术
文章目录 1.前言 2. 测试环境 3.编译时打桩 3.1.相关文件 3.1.1.main.c 3.1.2.newcalloc.h 3.1.3.newcalloc.c 3.2.编译命令 3.3.运行情 ...
- linux 环境变量文件_应急响应系列之Linux库文件劫持技术分析,有点硬核哟
0×01 菜逼阶段 Linux库文件劫持这种案例在今年的9月份遇到过相应的案例,当时的情况是有台服务器不断向个可疑IP发包,尝试建立连接,后续使用杀软杀出木马,重启后该服务器还是不断的发包,使用net ...
- 文件名为空linux,文件系统:隐匿在Linux背后的机制
原标题:文件系统:隐匿在Linux背后的机制 在 Linux 中,最直观.最可见的部分就是 文件系统(file system) .下面我们就来一起探讨一下关于 Linux 中国的文件系统,系统调用以及 ...
- Unix/BSD/Linux的口令机制初探(转)
Unix/BSD/Linux的口令机制初探(转) Freebird 1.概述 早期U N I X系统把用户口令保存在一个纯文本可读的"口令文件"中,这可能在系统管理员注意不到的情况 ...
最新文章
- Pycharm中如何安装python库
- JS(JavaScript)的初了解6(更新中···)
- MyBatis-Plus 代码生成器
- Linux中iptables的用法
- 编译安装Apache2.4.10
- linux下vi的一些简单的操作
- 电脑卡顿不流畅是什么原因_为什么安卓系统用久了会卡,苹果系统却依然流畅?原因找到了!...
- redis cli 删除key 模糊_不同操作系统下,Redis的使用命令
- 浅谈 C++ 中的 new/delete 和 new[]/delete[]
- CPU vector operations
- 1.极限——介绍_1
- mysql 乱码问题
- mysql主从数据库不同步的2种解决方法(转)
- 【转】EntityFramework之领域驱动设计实践(三)
- 兰州大学计算机英语分数线,兰州大学09MBA分数线A线140综合72英语42
- OpenCV(iOS)平滑处理(模糊,毛玻璃)(10)
- Luogu3387【模板】缩点(Kosaraju)
- MySQL 入门(一)—— 常用数据库介绍
- 晶体管电路设计 上 铃木雅臣 学习体会
- 在线OPML压缩工具
热门文章
- Kafka启动失败异常-InconsistentClusterIdException
- 用java做出聊天工具
- D35 Spark源代码(待补充)
- 让AI自己调整超参数,谷歌大脑新优化器火了,自适应不同任务,83个任务训练加速比经典Adam更快...
- 关于app2sd、a2sd、data2sd、a2sd+的区别的解释
- (转)[教你开启冻酸奶的app2sd] android2.2的APP TO SD功能启动方法
- 请问,我要去工商局申请一个工作室,法律上需要那些流程
- java淘金者_Java游戏淘金者源码JAVA游戏源码下载
- 2018 ACM-ICPC 宁夏预选赛网赛 B-Goldbach
- 2012第29周官方应用市场Top Grossing动态