当前位置: 首页 > 编程日记 > 正文

Linux下HOOK动态链接库中API的方法

2012年,我写了一篇介绍Windows系统下Ring3层API的hook方案——《一种注册表沙箱的思路、实现——Hook Nt函数》,其在底层使用了微软的Detours库。5年后,我又遇到这么一个问题,但是系统变成了Linux。我最开始的想法是找一个Linux下的Detours库,于是找到了subhook。其原理是:修改被Hook函数起始地址处的汇编代码,让执行流程跳到我们定义的函数中。但是在实际使用中,我发现通过该库调用原始函数有错误——地址违例,导致进程崩溃,所以最终放弃了subhook的方案。(转载请指明出于breaksoftware的csdn博客)

后来发现,Linux用户层Hook非常简单。我们只要定义一个和被Hook的API相同名称、参数、返回值的函数即可。比如我们需要Hook获取用户UID的函数getuid(原来是在libc.so中实现的),则需要定义如下函数:

uid_t getuid(void) {return 800;
}

我们在main函数中调用之

int main() {printf("get_uid:%d\n", getuid());
}

函数返回


        我使用work账户登录的,其真实uid是502。而我们重写了程序中的getuid,则返回的是我们“指定”的800。

如果我们希望在被hook中的函数中调用原始函数,怎么做呢?这儿有个比较尴尬的问题,那就是我们定义的getuid地址将对应于符号getuid,那么原始的getuid(以后称libc中的getuid)地址将对应什么符号?我们怎么找到它?

可以想象libc中的getuid对应的符号不会因为我们的程序而被改变,那么就意味着程序运行中,将有两个getuid。事实也的确如此。

第一个getuid就是我们重定义的hook的函数体,第二个是动态链接库libc.so中的。于是我们在重定义的函数体中,使用

dlsym(RTLD_NEXT, "getuid")

就可以获得原始的函数地址。

所以这种方案的精髓就是RTLD_NEXT参数。我们看下dlsym函数参数的说明:

There are two special pseudo-handles, RTLD_DEFAULT and RTLD_NEXT. The former will find the first occurrence of the desired symbol using the default library search order. The latter will find the next occurrence of a function in the search order after the current library. This allows one to provide a wrapper around a function in another shared library.
        这段文字意思是:在默认的库查找顺序下,RTLD_DEFAULT是用于查找第一个符号匹配的函数地址,RTLD_NEXT是用于查找第二个符号匹配的函数地址。这种方式就提供了一种针对动态链接库中函数替换的功能。

以我们例子,RTLD_DEFAULT将找到我们自己定义的getuid,而RTLD_NEXT将找到libc.so中的。
        为了方便使用这种方式,我封装了相关调用

#ifndef HOOK_BASE
#define HOOK_BASE#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif#include <dlfcn.h>#define HOOK_FUNC_TEMPLATE(function_name) function_name##_func_t#define HOOK_FUNC_ORI_NAME(function_name) function_name##_ori#define HOOK_FUNC_INIT(function_name) static HOOK_FUNC_TEMPLATE(function_name) HOOK_FUNC_ORI_NAME(function_name);#define HOOK_FUNC(function_name) \if (!HOOK_FUNC_ORI_NAME(function_name)) {\HOOK_FUNC_ORI_NAME(function_name) = (HOOK_FUNC_TEMPLATE(function_name)) dlsym(RTLD_NEXT, #function_name);\}\#define ORIGINAL_FUNC(function_name) ((HOOK_FUNC_TEMPLATE(function_name)) HOOK_FUNC_ORI_NAME(function_name))#endif

我们只要关注HOOK_FUNC_INIT、HOOK_FUNC和ORIGINAL_FUNC三个宏。HOOK_FUNC_INIT方法声明了一个全局函数指针变量,其在HOOK_FUNC宏中被指定为被HOOK函数的原始地址。ORIGINAL_FUNC则是将这个指针进行类型转换,从而方便调用。

下一步我们要定义被HOOK的函数的类型

#ifndef HOOK_DEF
#define HOOK_DEF#include "hook_base.h"
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>typedef uid_t (*HOOK_FUNC_TEMPLATE(getuid))(void);
#endif

然后重定义我们要HOOK的函数

#include "hook_def.h"
#include <stdio.h>
#include <sys/types.h>HOOK_FUNC_INIT(getuid);uid_t getuid(void) {HOOK_FUNC(getuid);int uid = ORIGINAL_FUNC(getuid)();printf("getuid original:%d\n", uid);return 800;
}

这段代码,我们先调用原始的getuid函数,并打印出它的值。最后才返回一个我们定义的值——800。

在main函数中,我们只调用getuid。并使用 gcc src/*.c -ldl -o main 编译

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include "hook_def.h"int main() {printf("get_uid:%d\n", getuid());return 0;
}

其返回结果如下

相关文章:

NAT的配置与相关概念的理解

试验背景&#xff1a;随着接入因特网的计算机数量不断猛增&#xff0c;IPv4版本地址资源也就愈加显得捉襟见肘。好多企业申请的IP地址都是经过子网不断划分得到的。A类&#xff0c;B类地址基本已用完&#xff0c;而一般的用户根本就申请不到整段的公网C类地址。如果&#xff0c…

AAAI 2020论文解读:商汤科技发布新视频语义分割和光流联合学习算法

来源 | Every Frame Counts: Joint Learning of Video Segmentation and Optical Flow编辑 | Carol出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09; 商汤科技研究团队发表论文《Every Frame Counts: Joint Learning of VideoSegmentation and Optical Flo…

互联网+和创业潮,互联网+前提条件是什么?互联网+做什么?

在大众创业&#xff0c;万众创新的大浪下&#xff0c;凭着对新技术的敏感和青春激情&#xff0c;创业新军不断涌现.... 互联网创业浪潮, 如雨后春笋......,互联网渗透每个人的心中。创业不是赶时髦&#xff0c;而是一条非常孤独&#xff0c;艰难的路。实施“互联网&#xff0b;…

C++拾趣——C++11的语法糖auto

C是一种强类型的语言&#xff0c;比如变量a&#xff0c;如果声明它是整型&#xff0c;则之后只能将它作为整型来用。这和其他弱类型的语言有很大的区别&#xff0c;比如python中&#xff0c;我们可以让a在第一行是个整型&#xff0c;第三行是一个字符串。&#xff08;转载请指明…

“数学不行,啥都干不好!”骨灰级程序员:这比努力重要1000倍

之前有很多程序员读者向我们抱怨&#xff1a;1&#xff09;做算法优化时&#xff0c;只能现搬书里的算法&#xff0c;遇到不一样的问题&#xff0c;就不会了。2&#xff09;面试一旦涉及到算法和数据结构&#xff0c;如果数学不行&#xff0c;面试基本就凉凉了。3&#xff09;一…

跳槽 你准备好了吗

“人往高处走”&#xff0c;这固然没有错。但是&#xff0c;说来轻巧的一句话&#xff0c;它却包含了为什么“走”、什么是“高”、怎么“走”、什么时候“走”&#xff0c;以及“走”了以后怎么办等一系列问题。跳槽是一门学问&#xff0c;也是一种策略。“人往高处走”&#…

C++:常类型Const

常类型&#xff1a;使用类型修饰符const说明的类型&#xff0c;常类型的变量或对象成员的值在程序运行期间是不可改变的。 3.10.1 常引用 如果在说明引用时用const修饰&#xff0c;则被说明的引用为常引用。如果用常引用做形参&#xff0c;便不会产生对实参 的不希望的更改。常…

JQuery制作的toolTip,针对图片预览效果

昨天做了一个文字版的toolTip&#xff0c;后来想想现在大家都爱看图&#xff0c;文字未免有点单调了点&#xff0c;那我们就来个图片式的预览。代码比较简单&#xff0c;我就不多说了。 欢迎来到 买礼网 选购礼品&#xff01; 畅游鄂西山水风光尽在 恩施旅游资讯网首先看看调用…

29篇计算机视觉领域论文,篇篇惊艳!内附链接!

作者 | 微软亚洲研究院本文经授权转载自微软研究院AI头条&#xff08;ID&#xff1a;MSRAsia&#xff09;1. Deep High-Resolution Representation Learning for Human Pose Estimation论文链接&#xff1a;https://arxiv.org/pdf/1902.09212.pdf该论文在提出了一个新的网络Hig…

绑定CPU逻辑核心的利器——taskset

在工作中&#xff0c;我们可能遇到这样的需求&#xff1a;如何评估程序在一核和多核下的工作效率差距&#xff1f;最简单的想法是找一台只有一个CPU逻辑核的机器和一台有多个逻辑核的机器。&#xff08;转载请指明出于breaksoftware的csdn博客&#xff09;但是这种方式有明显的…

IDE set arguments

2019独角兽企业重金招聘Python工程师标准>>> code::blocks -> Project -->set programs arguments qtcreater -> Projects --> Build&Run --> Run --> Arguments xcode -> super < -->build-->arguments 转载于:https://my.osch…

2020年AI如何走?Jeff Dean和其他四位“大神”已做预测!

作者 | Khari Johnson译者 | 王艳妮 责编 | 胡巍巍出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;人工智能已经不再是随时准备改变世界的状态&#xff0c;而是已经在改变世界。在迈入2020年这新的一年、以及新的20年代之际&#xff0c;笔者请到了AI方面最…

zookeeper快速入门——简介

在几十年前&#xff0c;一个独立的计算机上往往部署着一套完整的应用系统。当时因为网络稳定性及速度的限制&#xff0c;将相关联的服务部署在一台机器上&#xff0c;让它们使用系统机制通信——比如管道&#xff0c;文件等&#xff0c;往往是最稳定和最高效的。然而随着网络技…

为TextMate扩展全屏功能

今天看代码&#xff0c;感觉TextMate那个窗口太小了点&#xff0c;越看越不爽&#xff0c;就想把它弄成全屏的。于是搜索啊搜索啊搜索&#xff0c;终于让我找到一款很yd的小软件&#xff0c;叫megazoomer&#xff0c; 下载地址是&#xff1a;[url]http://ianhenderson.org/mega…

hdu1406

一道很水很水的题&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;#include<iostream> using namespace std; int main(){int num1,num2,i,k,j,sum,n;while(cin>>n){ while(n--){cin&g…

zookeeper快速入门——部署

zookeeper有两种运行模式&#xff1a;独立模式和仲裁模式。独立模式就是只运行一个Zookeeper Server&#xff0c;这自然没法解决服务崩溃导致系统不可用的问题。仲裁模式就是以集群的方式运行Zookeeper Server&#xff0c;这样在Leader不可用时&#xff0c;集群内部会发起选举&…

2020,人工智能和深度学习未来的五大趋势

来源 | forbes编译 | Shawn编辑 | Carol出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;虽然近年来人工智能经常成为热门议题&#xff0c;但它还远未实现真正的成就。人工智能技术发展的主要障碍在于投资成本&#xff0c;投资成本影响短期内的回报。而当时…

电脑常见故障 1

死机恐怕是所有电脑故障里面最常见的一种了&#xff0c;但是死机的原因是多种多样的。 如果从硬件入手&#xff0c;先是看看机箱里的温度是否很高&#xff0c;要检查CPU的风扇是否正常运转&#xff0c;并要注意电脑的散热问题&#xff1b;其次可检查内存&#xff0c;检查完内存…

linux常用命令-date-clock-hwclock-type-whois--help-man-info-cal

date&#xff1a;时间管理电子表&#xff1a;晶体震荡器 石英震荡器Linux&#xff1a;rtc 硬件时间NTP&#xff1a;网络时间协义硬件时间&#xff08;命令&#xff1a;clock&#xff09;系统时间&#xff08;命令&#xff1a;date&#xff09;type COMMAND 判断命令是内部命令…

内存、性能问题分析的利器——valgraind

valgrind是一个知名的分析软件集。我们可以使用它进行内存、多线程及性能等各种问题的分析。它采用非侵入方式&#xff0c;所谓非侵入方式是指&#xff1a;我们不用在代码中插入分析工具的库。这对于开发者来说是友好的。因为如果要将工具编译到文件中&#xff0c;或者要调用其…

这是我见过最卡通的 Python 算法了,通俗易懂

普通程序员&#xff0c;不学算法&#xff0c;也可以成为大神吗&#xff1f;对不起&#xff0c;这个&#xff0c;绝对不可以。可是算法好难啊~~看两页书就想睡觉……所以就不学了吗&#xff1f;就一直当普通程序员吗&#xff1f;如果有一本算法书&#xff0c;看着很轻松……又有…

WebService(Axis2)视频教程与QQ交流群发布

Axis2是目前比较流行的WebService引擎。WebService被应用在很多不同的场景。例如&#xff0c;可以使用WebService来发布服务端 Java类的方法&#xff0c;以便使用不同的客户端进行调用。这样可以有效地集成多种不同的技术来完成应用系统。WebService还经常被使用在SOA中&#x…

fragment类onresume里面刷新操作处理

今天项目中涉及fragment中嵌套多个fragment&#xff0c;但是要根据tag去展示对应的fragment&#xff0c;而不是默认展示的第一个fragment&#xff0c;如果使用activity很容易想到onpause(),onResume()中进行处理&#xff0c;但是你会发现fragment的onpause和onresume只调用一次…

内存问题分析的利器——valgrind的memcheck

在《内存、性能问题分析的利器——valgrind》一文中我们简单介绍了下valgrind工具集&#xff0c;本文将使用memcheck工具分析各种内存问题。&#xff08;转载请指明出于breaksoftware的csdn博客&#xff09; 本文所有的代码都是使用g -O0 -g mem_error.c -o mem_erro编译&#…

类项目中的配置文件app.config在打包安装后的信息获取的问题

在一个项目中碰到这样的一个问题&#xff0c;做一个WORD插件&#xff0c;功能在类库项目中实现了&#xff0c;配置信息存在类库项目的配置文件app.config中&#xff0c;在进行打包后&#xff0c;获取的配置文件中的DocType节点信息时&#xff0c;使用以下方法 ConfigurationMa…

AAAI 2020论文解读:商汤科技提出新弱监督目标检测框架

来源 | Object Instance Mining for WeaklySupervised Object Detection编辑 | Carol出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;商汤科技视频大数据团队发表论文《Object Instance Mining forWeakly Supervised Object Detection》&#xff0c;该论文…

20135306黄韧 信息安全系统设计基础期中学习总结

信息安全系统设计基础第八周学习总结 知识点总结 第1章 计算机系统漫游 △计算机系统是由硬件和系统软件组成的&#xff0c;它们共同协作以运行应用程序。计算机内部的信息被表示为一组组的位&#xff0e;它们依据上下文有不同的解释方式。程序被其他程序翻译成不同的形式&…

使用SQL Server维护计划实现数据库定时自动备份

在SQL Server中出于数据安全的考虑&#xff0c;所以需要定期的备份数据库。而备份数据库一般又是在凌晨时间基本没有数据库操作的时候进行&#xff0c;所以我们不可能要求管理员每天守到晚上1点去备份数据库。要实现数据库的定时自动备份&#xff0c;最常用的方式就是使用SQL S…

AI 医疗公司“战疫”在前线

作者 | Just来源 | CSDN&#xff08;CSDNnews&#xff09;紧急驰援疫区&#xff0c;涉足AI医疗领域的公司也出动了。截止到2月6日&#xff0c;随着新冠病毒肺炎疫情的不断发展&#xff0c;全国累计已有31161例确诊病例&#xff0c;26359例疑似病例。不过&#xff0c;由于医疗资…

动态执行流程分析和性能瓶颈分析的利器——valgrind的callgrind

在《内存、性能问题分析的利器——valgrind》一文中我们简单介绍了下valgrind工具集&#xff0c;本文将使用callgrind工具进行动态执行流程分析和性能瓶颈分析。&#xff08;转载请指明出于breaksoftware的csdn博客&#xff09; 之前的《利器》系列中&#xff0c;我们介绍了两种…