使用dlsym()的RTLD_NEXT来实现库函数拦截

需求描述

需要对文件的打开与执行,加日志收集。

需求分析

本文对该需求,使用库函数钩子的方案。

库函数钩子

/** File: library_calls_hook.c* Author:** Compile:* gcc -fPIC -c -o library_calls_hook.o library_calls_hook.c* gcc -shared -o library_calls_hook.so library_calls_hook.o -ldl** Use:* LD_PRELOAD="./library_calls_hook.so" <command>** Copyright*/#define _GNU_SOURCE
#include <dlfcn.h>
#define _FCNTL_H
#include <sys/types.h>
#include <bits/fcntl.h>
#include <stddef.h>extern int errorno;int __thread (*_open)(const char * pathname, int flags, ...) = NULL;
int __thread (*_open64)(const char * pathname, int flags, ...) = NULL;int open(const char * pathname, int flags, mode_t mode)
{if (NULL == _open) {_open = (int (*)(const char * pathname, int flags, ...)) dlsym(RTLD_NEXT, "open");}printf("intercepted open: %s\n",pathname);if(flags & O_CREAT)return _open(pathname, flags | O_NOATIME, mode);elsereturn _open(pathname, flags | O_NOATIME, 0);
}int open64(const char * pathname, int flags, mode_t mode)
{if (NULL == _open64) {_open64 = (int (*)(const char * pathname, int flags, ...)) dlsym(RTLD_NEXT, "open64");}printf("intercepted open64: %s\n",pathname);if(flags & O_CREAT)return _open64(pathname, flags | O_NOATIME, mode);elsereturn _open64(pathname, flags | O_NOATIME, 0);
}static int (*real_execve)(const char *filename, char *const argv[], char *const envp[])=0;
int execve(const char *filename, char *const argv[], char *const envp[])
{if (!real_execve) {real_execve = dlsym(RTLD_NEXT, "execve");}printf("intercepted execve: %s\n", filename);return real_execve(filename, argv, envp);
}

为了方便演示,这里对库函数的修改部分只加了打印,执行时可以看到效果。

编译

thesre@HP-Z420-Workstation:~/library_call_intercept$ gcc -fPIC -c -o library_calls_hook.o library_calls_hook.c
library_calls_hook.c: In function ‘open’:
library_calls_hook.c:32:5: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]32 |     printf("intercepted open: %s\n",pathname);|     ^~~~~~
library_calls_hook.c:32:5: warning: incompatible implicit declaration of built-in function ‘printf’
library_calls_hook.c:21:1: note: include ‘<stdio.h>’ or provide a declaration of ‘printf’20 | #include <stddef.h>+++ |+#include <stdio.h>21 |
library_calls_hook.c: In function ‘open64’:
library_calls_hook.c:44:5: warning: incompatible implicit declaration of built-in function ‘printf’44 |     printf("intercepted open64: %s\n",pathname);|     ^~~~~~
library_calls_hook.c:44:5: note: include ‘<stdio.h>’ or provide a declaration of ‘printf’
library_calls_hook.c: In function ‘execve’:
library_calls_hook.c:57:5: warning: incompatible implicit declaration of built-in function ‘printf’57 |     printf("intercepted execve: %s\n", filename);|     ^~~~~~
library_calls_hook.c:57:5: note: include ‘<stdio.h>’ or provide a declaration of ‘printf’
thesre@HP-Z420-Workstation:~/library_call_intercept$ gcc -shared -o library_calls_hook.so library_calls_hook.o -ldl

通过LD_PRELOAD使用

thesre@HP-Z420-Workstation:~/library_call_intercept$ LD_PRELOAD=./library_calls_hook.so ./test
intercepted execve: /bin/date
intercepted open: /home/thesre/library_call_intercept/hello.txt
openfile succeeded!
thesre@HP-Z420-Workstation:~/library_call_intercept$ LD_PRELOAD=./library_calls_hook.so cat hello.txt
intercepted open: hello.txt
line 1
line 2
line 3
line 4
line 5

参考资料

http://optumsoft.com/dangers-of-using-dlsym-with-rtld_next/

Linux - 使用dlsym()的RTLD_NEXT来实现库函数拦截相关推荐

  1. 动态库装载及 dlsym的RTLD_NEXT参数详解

    在看公司spp框架代码的时候发现了如下一段宏定义,其中的dlsym函数及其RTLD_NEXT参数的含义不是很明白,于是网上搜了下这里做个记录. #define mt_hook_syscall(name ...

  2. Linux C高级编程——文件操作之库函数

    Linux C高级编程--文件操作之库函数 宗旨:技术的学习是有限的,分享的精神是无限的 --为什么要设计标准I/O库? 直接使用API进行文件访问时,需要考虑许多细节问题 例如:read.write ...

  3. linux下dlsym返回的函数地址的具体含义

    linux下动态链接的例子有很多,我从网上找到了一个,如下 动态链接示例地址: https://blog.csdn.net/fuyuande/article/details/82913961 对于ma ...

  4. LINUX下c语言调用math.h库函数的注意事项

    2019独角兽企业重金招聘Python工程师标准>>> 在Ubuntu上做C语言程序练习时,用到了sqrt函数,尽管在源文件中已包含了math.h头文件,但在编译的时候总是提示sqr ...

  5. linux 库函数拦截,如何使用net_dev_add()API过滤和拦截Linux数据包?

    您正在使您的模块处理所有以太网数据包. Linux将向所有匹配的协议处理程序发送数据包.由于IP已在您的内核中注册,因此您的模块和ip_rcv都将接收所有带有IP头的SKB. 如果不更改内核代码,则无 ...

  6. linux库函数实现复制文件,linux应用编程笔记(6)库函数方式实现文件复制编程...

    摘要:介绍了库函数文件编程常用的函数,打开,关闭,写,读,定位等,最后通过一个实例将这些函数都运用了一边,加深理解. 一.库函数文件编程常用函数 1.fopen(打开文件) 头文件 #include定 ...

  7. linux 数据库 函数是什么,MySQL数据库函数(一)

    一.数学函数 1.绝对值函数 ABS(x) :返回 x 的绝对值 mysql> select ABS(2),ABS(-2.3),ABS(-22); 返回的结果如下: 数学学得好的大佬应该知道(本 ...

  8. 动态链接函数dlsym()的参数RTLD_NEXT使用注意事项

    相比于已知函数的所在动态库,函数dlsym的参数RTLD_NEXT可以在对函数实现所在动态库名称未知的情况下完成对库函数的替代.这提供了巨大的便利.但是凡是有一利必有一弊,在使用该参数时,需要注意一些 ...

  9. Linux C: IO库函数,文件流缓冲,变参函数

    一.I/O 库函数与系统调用 在Linux 中有很多关于IO(输入输出)的库函数,其大部分都存在 stdio.h 头文件中.例如fopen,fread,fwrite,fseek,fclose , 这些 ...

最新文章

  1. 美团语音交互部招聘NLP/知识图谱/语音识别等算法职位(可实习)
  2. 百度腾讯齐刷刷强调“产业+AI”,李彦宏看深,马化腾见远
  3. c++指针引用导出文件
  4. PHP 计算两个两个文件的相对路径
  5. “约见”面试官系列之常见面试题之第五十四篇之语义化标签(建议收藏)
  6. php cgi漏洞,Nginx + PHP CGI的一个可能的安全漏洞
  7. Spring read-only=true 只读事务的一些概念
  8. 树莓派 摄像头 html5,视频演示如何给树莓派安装摄像头模块
  9. java职业规划怎么写_java个人职业生涯发展规划书范文
  10. JS睡眠sleep()
  11. java 日历工具_Java开发笔记(四十二)日历工具的常见应用
  12. 桌面右击没有WPS新建WORD文档
  13. FPM生成Allegro封装常见问题及解决方法
  14. debian live-buid
  15. 飞控和飞控固件的讲解
  16. 【读书笔记】算法的乐趣
  17. 如何在mac下拆分PDF
  18. Win10系统,如何让我的电脑显示在桌面上?
  19. weblogic10.3.6.0的安装和打补丁
  20. 深入了解人工智能在建筑领域中的应用

热门文章

  1. 加速度计和陀螺仪指南——数学模型和基本算法
  2. laravel图片和文件的上传
  3. 为什么你的数据分析报告,总被领导打回?
  4. 航空航天巨头罗尔斯·罗伊斯采用“混合方法”研究量子计算
  5. 愿世间项目再无node-sass
  6. 微信小程序 - 获取用户信息 “getUserInfo:fail auth deny“,“err_code“:“-12007“
  7. 微软认真了!微软Surface平板强来袭击,采用IntelX86 I5 CPU 支持Windows8 Pro版本 全面兼容PC端软件
  8. MySQL查找重复记录
  9. ftp服务器搭建步骤详解
  10. 谈一次java web系统的重构思路