Linux下C++中可使用的3种Hook方法
Hook即钩子,截获API调用的技术,是将执行流程重定向到你自己的代码,类似于hack。如使程序运行时调用你自己实现的malloc函数代替调用系统库中的malloc函数。这里介绍下Linux下C++中可使用的3中Hook方法:
1. GNU C库允许你通过指定适当的钩子函数(hook function)来修改malloc、realloc和free的行为,钩子函数的声明在malloc.h文件中,如__malloc_hook, __free_hook,你可以使用这些钩子来帮助你调试使用动态内存分配的程序,但是用GCC编译时会提示这些接口已被废弃。
测试代码如下:
#include <malloc.h>
#include <stdio.h>/* reference:http://www.gnu.org/software/libc/manual/html_node/Hooks-for-Malloc.htmlhttps://stackoverflow.com/questions/11356958/how-to-use-malloc-hook
*/
void* (*old_malloc_hook)(size_t, const void*);
void (*old_free_hook)(void* __ptr, const void*);
void my_free_hook(void* ptr, const void* caller);void* my_malloc_hook(size_t size, const void* caller)
{void *result;// Restore all old hooks__malloc_hook = old_malloc_hook;__free_hook = old_free_hook;// Call recursivelyresult = malloc(size);// Save underlying hooksold_malloc_hook = __malloc_hook;old_free_hook = __free_hook;// printf might call malloc, so protect it too.printf("malloc (%u) returns %p\n", (unsigned int) size, result);// Restore our own hooks__malloc_hook = my_malloc_hook;__free_hook = my_free_hook;return result;
}void my_free_hook(void *ptr, const void *caller)
{// Restore all old hooks__malloc_hook = old_malloc_hook;__free_hook = old_free_hook;// Call recursivelyfree(ptr);// Save underlying hooksold_malloc_hook = __malloc_hook;old_free_hook = __free_hook;// printf might call free, so protect it too.printf("freed pointer %p\n", ptr);// Restore our own hooks__malloc_hook = my_malloc_hook;__free_hook = my_free_hook;
}void my_init(void)
{old_malloc_hook = __malloc_hook;old_free_hook = __free_hook;__malloc_hook = my_malloc_hook;__free_hook = my_free_hook;
}int main()
{my_init();void* p = malloc(10);free(p);fprintf(stdout, "test finish\n");return 0;
}
build.sh内容如下:
#! /bin/bashg++ test.cpp
echo -e "**** start run ****\n"
./a.out
执行结果如下:
2. 使用LD_PRELOAD环境变量:可以设置共享库的路径,并且该库将在任何其它库之前加载,即这个动态库中符号优先级是最高的。如果系统库函数使用内联优化,如strcmp,则在编译程序时,可能需添加-fno-builtin-strcmp。
测试代码test.cpp如下:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>int main()
{srand(time(NULL));for (int i = 0; i < 2; ++i)fprintf(stdout, "value: %02d\n", rand() % 100);const char* str1 = "https://blog.csdn.net/fengbingchun";const char* str2 = "https://github.com/fengbingchun";fprintf(stdout, "are they equal: %d\n", strcmp(str1, str2));fprintf(stdout, "test finish\n");return 0;
}
测试代码hook.cpp如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int rand()
{fprintf(stdout, "_^_ set rand function to a constant: 88 _^_\n");return 88;
}int strcmp(const char* str1, const char* str2)
{fprintf(stdout, "_^_ set strcmp function to a constant: 0 _^_\n");return 0;
}
build.sh内容如下:
#! /bin/bashg++ -shared -fPIC -o libhook.so hook.cpp
g++ test.cpp
echo -e "**** start run ****\n"
LD_PRELOAD=${PWD}/libhook.so ./a.out
执行结果如下:
3. 使用GCC的--wrap选项:对symbol使用包装函数(wrapper function),任何对symbol未定义的引用(undefined reference)会被解析成__wrap_symbol,而任何对__real_symbol未定义的引用会被解析成symbol。即当一个名为symbol符号使用wrap功能时,程序中任何用到symbol符号的地方实际使用的是__wrap_symbol符号,任何用到__real_symbol的地方实际使用的是真正的symbol。注意:当__wrap_symbol是使用C++实现时,一定要加上extern “C”,否则将会出现”undefined reference to __wrap_symbol”。
测试代码test.cpp如下:
#include <stdio.h>
#include <stdlib.h>extern "C" {void* __real_malloc(size_t size);
void __real_free(void* ptr);
extern void foo();
void __real_foo();void* __wrap_malloc(size_t size)
{fprintf(stdout, "_^_ call wrap malloc function _^_\n");return __real_malloc(size);
}void __wrap_free(void* ptr)
{fprintf(stdout, "_^_ call wrap free function _^_\n");__real_free(ptr);
}void __wrap_foo()
{fprintf(stdout, "_^_ call wrap foo function _^_\n");
}} // extern "C"int main()
{foo();__real_foo();void* p1 = malloc(10);free(p1);fprintf(stdout, "test finish\n");return 0;
}
测试代码foo.cpp如下:
#include <stdio.h>extern "C" {void foo()
{fprintf(stdout, "call foo function\n");
}} // extern "C"
build.sh内容如下:
#! /bin/bashg++ foo.cpp test.cpp -Wl,--wrap=malloc -Wl,--wrap=free -Wl,--wrap=foo
echo -e "**** start run ****\n"
./a.out
执行结果如下:
Windwos上的Hook是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其它进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理Windows消息或特定事件。钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。
GitHub:https://github.com/fengbingchun/Linux_Code_Test
相关文章:

Java Properties 类
Properties 继承于 Hashtable.表示一个持久的属性集.属性列表中每个键及其对应值都是一个字符串。 Properties 类被许多Java类使用。例如,在获取环境变量时它就作为System.getProperties()方法的返回值。 Properties 定义如下实例变量.这个变量持有一个Properties对…
国产数据库年终大盘点
作者 | 马超 编辑 | 胡巍巍出品 | CSDN(ID:CSDNnews)去“IOE”这个概念,最早由王坚院士在刚刚加入阿里时提出,其目标是将IBM 的小型机、Oracle数据库、EMC存储设备从阿里的IT体系中去除,代之以自主研发的系…

解密FFmpeg播放track mode控制
上一篇文章(http://www.cnblogs.com/yangdanny/p/4421130.html)我们解决了在FFmpeg下如何处理H264和AAC的扩展数据,根据解出的NALU长度恢复了H264的起始码和AAC的ADTS头,这样一般来说播放是没有问题。本篇文章来谈谈如何实现基于FFmpeg的track mode控制&…

UIButton防止按钮和手势的暴力点击
首先理解下几个概念 1、IMP:它是指向一个方法具体实现的指针,每一个方法都有一个对应的IMP,当你发起一个消息之后,最终它会执行的那段代码,就是由IMP这个函数指针指向了这个方法实现的 2、SEL:方法名称的描…

使用Windows7上的VS Code打开远程机Ubuntu上的文件操作步骤
之前在https://blog.csdn.net/fengbingchun/article/details/118991855 中介绍过在Windows10通过VS Code打开Ubuntu 16.04上的文件或文件夹的操作步骤。Windows7上的操作与Windows10有所不同,这里记录下。 Visual Studio Code Remote - SSH扩展允许你在任何远程机器…
微众银行殷磊:AI+卫星,从上帝视角洞察资产管理|BDTC 2019
出品 | AI科技大本营(ID:rgznai100)12月5日-7日,2019中国大数据技术大会(BDTC)于北京隆重举办,大会已成功举办十二届,是大数据领域极具影响力的行业盛会。本届大会汇聚了学术界、企业界上千位知…

【二分答案】【最短路】bzoj1614 [Usaco2007 Jan]Telephone Lines架设电话线
对于二分出的答案x而言,验证答案等价于将所有边权>x的边赋成1,否则赋成0,然后判断从1到n的最短路是否<K。 #include<cstdio> #include<cstring> #include<queue> using namespace std; #define N 1001 #define M 100…

Python3中装饰器@typing.overload的使用
typing.py的源码在:https://github.com/python/cpython/blob/main/Lib/typing.py 。此模块为类型提示(Type Hints)提供运行时支持。这里介绍下typing.overload的使用,从python 3.5版本开始将Typing作为标准库引入。 python3中增加了Function Annotation(…
19年NAACL纪实:自然语言处理的实用性见解 | CSDN博文精选
作者 | Nikita Zhiltsov翻译 | 王威力校对 | 李海明本文为你概述处理不同NLP问题时的具有卓越性能的方法、技术和框架等。计算语言:人类语言技术学会北美分会2019年年会(North American Chapter of the Association for Computational Linguistics: Huma…

高并发场景下数据库的常见问题及解决方案
一、分库分表 (1)为什么要分库分表 随着系统访问量的增加,QPS越来越高,数据库磁盘容量不断增加,一般数据库服务器的QPS在800-1200的时候性能最佳,当超过2000的时候sql就会变得很慢并且很容易被请求打死&a…

典型用户 persona
persona 典型用户 1、姓名:王涛 2、年龄:22 3、收入:基本无收入 4、代表用户在市场上的比例和重要性:王涛为铁道学生。本软件的用户主要是学生和老师,尤其是广大的铁大学子,所以此典型用户的重要性不言而喻…

PyTorch中nn.Module类简介
torch.nn.Module类是所有神经网络模块(modules)的基类,它的实现在torch/nn/modules/module.py中。你的模型也应该继承这个类,主要重载__init__、forward和extra_repr函数。Modules还可以包含其它Modules,从而可以将它们嵌套在树结构中。 只要…

什么是三层交换机、网关、DNS、子网掩码、MAC地址
一、什么是vlan? 二、单臂路由与三层交换机 三、什么是网关 一、什么是网关 二、如何来理解网关 三、网关的ip地址 四、网关是如何实现通信? 五、什么是默认网关? 四、什么是DNS 五、MAC地址 六、子网掩码 很多朋友多次问到什么是网关、dns、子网掩码&…
20行代码发一篇NeurIPS:梯度共享已经不安全了
整理 | 夕颜,Jane出品 | AI科技大本营(ID:rgznai100)【导读】12 月 8 日-14 日,NeurIPS 2019 在加拿大温哥华举行,和往常一样,今年大会吸引了数万名专家参会,并展示了计算机领域的最新进展。其中…

关于页面打印window.print()的样式问题
当我们打印网页的时候。有时候会发现。打印出来的。跟网页上看到的样式的差别有点大。这其中可能有的问题是。样式问题。 当调用打印(window.print())方法时。打印机会在网页的样式中查找 media print{}的样式,并适应到要打印的网页中。 所以 如果要打印的页面符合看…

Python3中参数*args和**kwargs介绍
在Python中,我们可以使用两种特殊符号将可变数量的参数传递给函数:*args和**kwargs。你可以使用任何单词代替args和kwargs,但通常做法是使用args和kwargs。 *args允许函数接受任意数量的位置参数(positional arguments)。 **kwargs收集所有未…
4大主流CPU处理器技术架构,不知道就out了!
作者 | 王艺威责编 | 阿秃RISC(精简指令集计算机)是一种执行较少类型计算机指令的微处理器,起源于80年代的MIPS主机(即RISC机),RISC机中采用的微处理器统称RISC处理器。这样一来,它能够以更快的…

grunt-connect-proxy解决开发时跨域问题
最近的项目中前后端是完全分离开发的,前端用grunt管理项目。这样就会导致一个问题:开发时前端调用后台的接口时因为不在一个服务器,所以会出现跨域问题。但是也不能用JSONP或CROS方式实现真正的跨域,因为项目发布时其实是在同一个…
混合推荐系统就是多个推荐系统“大杂烩”吗?
作者丨gongyouliu编辑丨zandy【导读】在本篇文章中,我们会介绍混合推荐系统(Hybrid Recommender Systems),就是利用多种推荐算法配合起来做推荐,期望避免单个推荐算法存在的问题,最终获得比单个算法更好的推荐效果。本篇文章我们从…

Python3中collections.OrderedDict介绍
Python3中的collections模块实现了特定目标的容器,以提供Python标准内建容器dict、list、set和tuple的替代选择,包括namedtuple、deque、ChainMap、Counter、OrderedDict、defaultdict、UserDict、UserList、UserString。这里介绍下OrderedDictÿ…

汗!雅虎中国个人空间
今天发现雅虎中国有了个人空间,偷偷试了下,让人失望到极点,几乎没有什么特点,和MSN很相似,空间相册放着好好的Flickr不用,偏偏弄了个很垃圾的相册,还有整合能力也不行。都不知道del.icio.us和Fl…

关于v$process与v$session中process的理解
v$session有个process字段,V$PROCESS有个SPID字段,这两个字段是不是一个意思呢?是不是都代表会话的操作系统进程呢?官方文档上的解释:SPID VARCHAR2(12) Operating system process identifierPROCESS VARCHAR2…

Python3中lambda表达式介绍
Python3中的lambda表达式或lambda函数是匿名函数(anonymous function),意味着该函数没有名称。def关键字用于在Python3中创建一个普通函数,类似地,lambda关键字用于在Python3中创建匿名函数。 Python3 lambda函数语法: lambda pa…
6大理由,告诉你为什么这个大会你不能错过! | 文末有福利
作者 | Carol出品 | 区块链大本营(blockchain_camp)* 文末可参与活动赢赠票!如果说有一个什么领域,能让中科院、华为、腾讯、京东、360、微众银行的大咖汇聚在一起,那一定是——区块链。悄咪咪地给大家剧透一下&#x…

魔与道的反复较量 反垃圾邮件技术
反垃圾邮件武器库不同的反垃圾邮件产品采用的技术有所不同,但总体来说,不外乎以下几种技术,其中,针对垃圾邮件的核心技术有贝叶斯智能分析、垃圾邮件评分、垃圾邮件指纹识别。转载于:https://blog.51cto.com/aonlin/17074

在Centos 7下编译openwrt+njit-client
首先要有一个centos7 step1:更新系统的源: yum install update 但是发现官方的源好像被墙了,于是自己又去换源,找163的源换。具体的操作最后的链接。 可是换完源之后发现163的源只支持到centos6、、、、、、但是就泪崩了。于是又把源换了回来…

Python3中内置函数callable介绍
Python3中的内置函数callable接受一个对象参数,如果此对象参数看起来可调用,则callable函数返回True,否则返回False。如果返回True,则调用仍有可能失败;但如果返回False,则调用对象将永远不会成功。 类是可…

户外广告新创意
近来,各大城市纷纷加大了对户外广告的监管力度,部分城市甚至停止审批户外广告牌。这让户外广告运营者和广告发布商甚为头疼。 长期以来,户外广告牌扮演着截然相反的“双重角色”,在户外广告运营者和广告发布商眼中,“寸…
百度重新定义「智能屏」,瞄准10后
加入「公开课」交流群,获取更多学习资料、课程及热招岗位等信息记者 | 阿司匹林作为中国智能音箱主力推手中的一员,百度从 2017 年已经开始布局。根据数据机构Strategy Analytics发布智能音箱市场报告,2019年第三季度,百度旗下人工…

jQuery最简单的表单提交方式
第一步:绑定事件 常用的与ajax相关的事件参考如下: 1、$(selector).click(function) 2、$(selector).change(function) 3、$(selector).keyup(function) 4、$(selector).submit(function) 提交表单前&#…