news 2026/5/27 1:13:25

在c++中使用HOOK修改sleep函数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
在c++中使用HOOK修改sleep函数

在c++中使用HOOK修改sleep函数

本篇文章将以sleep函数为例子介绍如何在c++中使用hook修改系统函数

HOOK是什么

Hook(钩子)是一种编程机制,它允许开发者在程序执行的特定点插入自定义代码,从而拦截、处理或修改原有的函数调用、消息传递或系统事件。

通俗地说,Hook就像是给程序安装了一个“监听器”或“拦截器”。当目标函数被调用时,控制权会先转移到你的Hook代码,你可以在执行原有操作之前或之后插入自定义逻辑,甚至完全替换原有行为。例如游戏外挂通过hook来对游戏运行时用到的函数或其他API进行修改来实现外挂的功能。同时,hook也常与协程搭配使用,修改系统函数来为类似sleep等阻塞线程的函数添加协程的功能。

如何使用hook来修改sleep函数

下面的代码是最简单的hook的实现

#include <iostream> #include <unistd.h> extern "C" unsigned int sleep(unsigned int seconds) { std::cout << "我们成功修改了系统提供的sleep函数!" << std::endl; return 0; } void test1() { std::cout << "使用sleep函数睡2s"<< std::endl; sleep(2); std::cout << "sleep函数睡完了"<< std::endl; }

调用函数test1(),程序运行结果如下:

使用sleep函数睡2s 我们成功修改了系统提供的sleep函数! sleep函数睡完了

在上面的代码中,我们仅做了两件事

  • 实现一个sleep函数,与unistd.h中的sleep函数签名一致
  • 使用extern "C"告诉C++编译器"按C语言的方式处理这个函数"

定义一个相同签名的sleep为什么链接过程中不会产生重定义问题呢?在链接器链接过程中,函数符号有类似强弱符号之分,在动态库中的函数会被新目标文件的函数替换,因此此处程序运行时会运行我们重新写的sleep函数而不是unistd.h内的。

至于加extern "C"的作用,在c++编译过程中,为了区分不同的重载函数,编译器会给同名函数加入随即字符进行区分,我们的目的是重写sleep函数,因此要确保函数名与unistd.h中相同,通过加入extern "C"来做到这一点

对上述代码的改进

上述代码存在很大的缺陷,最主要的是它失去了sleep函数最基本的功能。通常我们利用hook修改函数时,我们需要维持其原有功能。我们不可能真的去实现一个完整的sleep,但我们可以获得原sleep的函数指针

在不同的平台有不同的获取库函数指针的方法,下面时在linux平台来获取sleep函数指针的例子:

获取sleep函数指针

linux为获取库函数指针提供了特定的函数dlsym,定义在<dlfcn.h>中。其函数签名为:

void *dlsym(void *restrict handle, const char *restrict symbol);

dlsym返回值是函数指针,其第一个参数是指定查找的库,第二个参数传入函数名称。

在hook场景中,handle参数常取RTLD_NEXT,表示跳过当前库查找其他库。也就是说,当symbol传入"sleep"时,dlsym跳过当前库我们定义的sleep,找到了unistd.h定义的sleep函数,并返回其函数指针。

代码改进

有了上边提供的函数,我们可以保存原有sleep函数并给他加点"小料",代码如下:

#include <iostream> #include <unistd.h> #include <dlfcn.h> using sleep_fun_type = unsigned int (*)(unsigned int seconds); sleep_fun_type original_sleep = NULL; extern "C" unsigned int sleep(unsigned int seconds) { std::cout << "我们成功修改了系统提供的sleep函数!" << std::endl; return original_sleep(seconds); // <-----这里调用我们保存下来的原始的sleep } void test1() { original_sleep = (sleep_fun_type)dlsym(RTLD_NEXT, "sleep"); // <-----这里获得了unistd中的sleep std::cout << "使用sleep函数睡2s"<< std::endl; sleep(2); // <-----这里调用我们自己写的sleep std::cout << "sleep函数睡完了"<< std::endl; }

代码相较于开始,只做了一点改进,即保存原始sleep函数,并在我们自己定义的sleep函数中调用保存的原始sleep函数。

需注意的是,编译时应加上-ldl选项链接动态库

总结

上述代码仍有许多不完善的地方,实际过程中要检查dlsym返回值是否为NULL等问题,同时代码对初始化并不规范,可以使用下面的初始化方法(gcc编译器),也可以使用其他更兼容的方法进行初始化。

__attribute__((constructor)) void init_hook() // gcc编译器提供,main函数运行前,库和内存初始化完成后运行 { // 在main函数执行前先初始化—original_sleep。 original_sleep = (SleepFunc)dlsym(RTLD_NEXT,"sleep"); }

最后,需要注意的是,如果采用上述方法重新定义sleep,会使所有库运行的sleep函数都改变成我们自己定义的sleep,如果返回值与原sleep存在差异,可能导致一些其他的隐含问题。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/22 12:22:45

告别“大海捞针“:InternLM2.5-1M如何让百万字长文本变得触手可及?

还记得那个让你抓狂的场景吗&#xff1f;一份200页的合同摆在眼前&#xff0c;你需要在密密麻麻的条款中找出那个关键的风险点。或者面对上百篇学术论文&#xff0c;想要快速梳理出核心观点却无从下手。现在&#xff0c;这些困扰将成为过去式。 【免费下载链接】InternLM Offic…

作者头像 李华
网站建设 2026/5/21 21:12:11

如何快速解决PyTorch Geometric TUDataset加载问题:5个实战技巧

如何快速解决PyTorch Geometric TUDataset加载问题&#xff1a;5个实战技巧 【免费下载链接】pytorch_geometric Graph Neural Network Library for PyTorch 项目地址: https://gitcode.com/GitHub_Trending/py/pytorch_geometric PyTorch Geometric TUDataset是图神经网…

作者头像 李华
网站建设 2026/5/26 21:11:28

BetterDiscord 深度定制指南:打造属于你的专属聊天体验

BetterDiscord 深度定制指南&#xff1a;打造属于你的专属聊天体验 【免费下载链接】BetterDiscordApp Better Discord App enhances Discord desktop app with new features. 项目地址: https://gitcode.com/gh_mirrors/be/BetterDiscordApp 你是否曾经觉得 Discord 的…

作者头像 李华
网站建设 2026/5/26 10:03:24

BUUCTF[jarvisoj_level2_x64]

步骤使用checksec查看使用ida(pro)打开根进vulnerable_function函数依旧是栈溢出这道题我们无法使用上一题的32位来直接使用plt表来跳转到system,所以我们使用ROPgadget使用指令 ROPgadget --binary 文件名 来获取信息这里可以查看到pop rdi;ret的地址在64位中前几个参数我们是…

作者头像 李华
网站建设 2026/5/26 20:59:25

前端如何通过FormData实现大文件分片上传?

网工大三党文件上传救星&#xff1a;原生JS实现10G大文件上传&#xff08;Vue3IE8兼容&#xff09; 兄弟&#xff0c;作为刚入坑网络工程的山西老狗&#xff0c;我太懂你现在的处境了——老师要10G大文件上传的毕业设计&#xff0c;网上找的代码全是“断头路”&#xff0c;后端…

作者头像 李华
网站建设 2026/5/22 13:17:08

.NET WebForm如何支持大文件上传的进度显示?

毕业设计&#xff1a;企业级文件传输系统方案探索 在毕业设计选题阶段&#xff0c;我结合自身兴趣与计算机专业所学&#xff0c;确定了企业级文件传输系统这一课题。近期&#xff0c;我在网上搜索相关资料、参与论坛交流、加入多个QQ群和微信群&#xff0c;但收获不尽如人意。很…

作者头像 李华