Linux内核之hook机制:call_void_hook用法实例(六十一)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列原创干货持续更新中……】🚀
优质视频课程:AAOS车载系统+AOSP14系统攻城狮入门实战课原创干货持续更新中……】🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

🍉🍉🍉文章目录🍉🍉🍉

    • 🌻1.前言
    • 🌻2.Linux内核之hook机制介绍
      • 🐓2.1 call_void_hook内核源码中定义
      • 🐓2.2 call_void_hook介绍
    • 🌻3.代码实例
      • 🐓3.1 注册钩子函数并调用
      • 🐓3.2 模拟内核注册函数
      • 🐓3.3 自定义钩子函数

🌻1.前言

本篇目的:Linux内核之hook机制:call_void_hook用法实例

🌻2.Linux内核之hook机制介绍

🐓2.1 call_void_hook内核源码中定义

struct hlist_node {struct hlist_node *next, **pprev;
};struct hlist_head {struct hlist_node *first;
};union security_list_options {int (*binder_set_context_mgr)(const struct cred *mgr);};struct security_hook_list {struct hlist_node		list;struct hlist_head		*head;union security_list_options	hook;char				*lsm;
} __randomize_layout;struct security_hook_heads {struct hlist_head binder_set_context_mgr;};#define hlist_entry(ptr, type, member) container_of(ptr,type,member)#define hlist_entry_safe(ptr, type, member) \({ typeof(ptr) ____ptr = (ptr); \____ptr ? hlist_entry(____ptr, type, member) : NULL; \})	#define hlist_for_each_entry(pos, head, member)				\for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\pos;							\pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))	#define call_void_hook(FUNC, ...)				\do {							\struct security_hook_list *P;			\\hlist_for_each_entry(P, &security_hook_heads.FUNC, list) \P->hook.FUNC(__VA_ARGS__);		\} while (0)

🐓2.2 call_void_hook介绍

  • 在Linux内核中,call_void_hook 宏是一种用于调用安全模块钩子的便捷方式。它允许内核代码在特定的钩子点执行所有注册的安全模块回调函数。这种机制是Linux安全模块(LSM)框架的一部分,它允许不同的安全模块以插件的形式加入到内核中,从而提供各种安全特性,如访问控制、审计等。
  • call_void_hook 宏的定义如下:
#define call_void_hook(FUNC, ...)				\do {							\struct security_hook_list *P;			\\hlist_for_each_entry(P, &security_hook_heads.FUNC, list) \P->hook.FUNC(__VA_ARGS__);		\} while (0)
  • 这个宏接受一个钩子函数名 FUNC 和一个可变参数列表 ...。它的工作原理如下:
  1. do { ... } while (0) 构造确保了宏展开后成为一个独立的语句,避免了由于宏展开可能导致的语法错误。
  2. struct security_hook_list *P; 声明了一个指向 security_hook_list 结构的指针 P,这个结构用于表示钩子列表中的元素。
  3. hlist_for_each_entry 宏遍历 &security_hook_heads.FUNC 双链表中的每个元素,并将当前元素赋值给 Phlist_for_each_entry 宏定义了如何从列表中获取条目,并且它使用 hlist_entry_safe 来安全地获取条目。
  4. P->hook.FUNC(__VA_ARGS__); 调用当前钩子列表项中对应的函数 FUNC,并传递 __VA_ARGS__(可变参数)。
  • 在Linux内核中,hlist_nodehlist_head 结构用于实现哈希链表,这是一种内存效率较高的链表实现,特别适用于哈希表。hlist_node 包含指向链表中下一个节点的指针和指向前一个节点的前指针的指针。hlist_head 则包含指向链表第一个节点的指针。
    security_list_options 联合用于存储不同类型的安全钩子函数指针。在 security_hook_list 结构中,hook 字段是一个 security_list_options 类型的联合,用于存储钩子函数的指针。
  • security_hook_heads 结构包含了一个或多个 hlist_head 类型的字段,每个字段对应一个特定的钩子点。在 call_void_hook 宏中,&security_hook_heads.FUNC 表示特定钩子点的钩子列表头。
  • 通过使用 call_void_hook 宏,内核开发者可以在不修改现有代码的情况下,为特定的钩子点添加新的安全检查或操作。这种机制为内核的安全性提供了极大的灵活性和可扩展性。
  • 例如,当内核需要检查是否允许一个进程设置为binder上下文管理器时,它会调用 binder_set_context_mgr 钩子。使用 call_void_hook,内核代码可以这样调用钩子:
call_void_hook(binder_set_context_mgr, current_cred());
  • 这个调用会遍历 security_hook_heads.binder_set_context_mgr 钩子列表,并调用列表中每个钩子项的 binder_set_context_mgr 函数,传递当前进程的凭证作为参数。每个注册的安全模块都会有机会检查这个操作是否允许,并返回相应的结果。

🌻3.代码实例

🐓3.1 注册钩子函数并调用

#include <stdio.h>// 定义钩子函数的数据结构
struct security_hook_list {void (*hook)(int);
};struct {struct security_hook_list FUNC;
} security_hook_heads;// 定义调用钩子的宏
#define call_void_hook(FUNC, ...)		\do {						\struct security_hook_list *P;		\P = &security_hook_heads.FUNC;		\if (P->hook)				\P->hook(__VA_ARGS__);			\} while (0)void my_hook_function(int arg) {printf("Hook function called with argument: %d\n", arg);
}int main() {// 注册钩子函数security_hook_heads.FUNC.hook = my_hook_function;// 调用钩子函数call_void_hook(FUNC, 42);return 0;
}

🐓3.2 模拟内核注册函数

#include <stdio.h>// 定义钩子函数的数据结构
struct security_hook_list {void (*hook)(int);
};//全局变量 security_hook_heads,其中包含钩子函数的链表
struct {struct security_hook_list FUNC;
} security_hook_heads;// 定义调用钩子的宏
#define call_void_hook(FUNC, ...)		\do {						\struct security_hook_list *P;		\P = &security_hook_heads.FUNC;		\if (P->hook)				\P->hook(__VA_ARGS__);			\} while (0)void register_hook_in_kernel(void (*hook_func)(int), struct security_hook_list *hook_list) {hook_list->hook = hook_func;
}void my_hook_function(int arg) {printf("Hook function called in kernel with argument: %d\n", arg);
}int main() {// 在内核中注册钩子函数register_hook_in_kernel(my_hook_function, &security_hook_heads.FUNC);// 调用钩子call_void_hook(FUNC, 100);return 0;
}

🐓3.3 自定义钩子函数

#include <stdio.h>// 定义钩子函数的数据结构
struct security_hook_list {void (*hook)(int);
};//全局变量 security_hook_heads,其中包含钩子函数的链表
struct {struct security_hook_list FUNC;
} security_hook_heads;// 定义调用钩子的宏
#define call_void_hook(FUNC, ...)		\do {						\struct security_hook_list *P;		\P = &security_hook_heads.FUNC;		\if (P->hook)				\P->hook(__VA_ARGS__);			\} while (0)void my_hook_function(int arg) {printf("Custom hook function called with argument: %d\n", arg);
}int main() {// 注册自定义钩子函数security_hook_heads.FUNC.hook = my_hook_function;// 调用自定义钩子函数call_void_hook(FUNC, 200);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/643759.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在线音乐播放网站项目测试(selenium+Junit5)

在做完在线音乐播放网站项目之后&#xff0c;需要对项目的功能、接口进行测试&#xff0c;利用测试的工具&#xff1a;selenium以及Java的单元测试工具Junit进行测试&#xff0c;下面式测试的思维导图&#xff0c;列出该项目需要测试的所有测试用例&#xff1a; 测试结果&#…

友盟+|如何通过阿里云 Flink+Paimon 实现流式湖仓落地方案

01 友盟介绍 友盟 以“数据智能&#xff0c;驱动业务增长”为使命&#xff0c;为移动应用开发者和企业提供包括统计分析、性能监测、消息推送、智能认证等一站式解决方案。截止 2023 年 6 月&#xff0c;已累计为 270 万移动应用和 980 万家网站&#xff0c;提供十余年的专业数…

Python自学之路--001:Python + PyCharm安装图文详解教程

目录 1、概述 2、Python解释器 2.1、下载 2.2、Python安装 2.3、Python环境变量配置&#xff0c;必选项 3、PyCharm安装 3.1、PyCharm下载 3.2、PyCharm安装 4、建一个Hello World 5、Phcarm设置 5.1、Phcarm汉化 5.2、Phcarm工具栏显示在顶部 5.3、Phcarm通过pip安…

【服务器部署篇】Linux下Ansible安装和配置

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0c;产…

用这个方法,让你轻松从零搭建产品知识库

在市场竞争日益激烈的今天&#xff0c;一个系统化的产品知识库对于企业的重要性不言而喻。它不仅可以帮助团队成员快速掌握产品信息&#xff0c;提升服务效率&#xff0c;还能为客户提供及时准确的产品支持。那么&#xff0c;怎样才能从零开始&#xff0c;轻松搭建起一个合适的…

WebServer项目介绍文章【四叶专属】

Linux项目实战C轻量级Web服务器源码分析TinyWebServer 书接上文&#xff0c;学习开源项目的笔记没想到居然有不少阅读量&#xff0c;后面结合另一个前端开源项目简单做了点修改&#xff0c;没想到居然有需要的同学&#xff0c;那么我就专门为四叶开一篇文章吧&#xff0c;【源码…

探索未来的区块链DApp应用,畅享数字世界的无限可能

随着区块链技术的飞速发展&#xff0c;分布式应用&#xff08;DApp&#xff09;正成为数字经济中的一股强劲力量。DApp以其去中心化、透明公正的特点&#xff0c;为用户带来了全新的数字体验&#xff0c;开创了数字经济的新潮流。作为一家专业的区块链DApp应用开发公司&#xf…

BERT-CRF 微调中文 NER 模型

文章目录 数据集模型定义数据集预处理BIO 标签转换自定义Dataset拆分训练、测试集 训练验证、测试指标计算推理其它相关参数CRF 模块 数据集 CLUE-NER数据集&#xff1a;https://github.com/CLUEbenchmark/CLUENER2020/blob/master/pytorch_version/README.md 模型定义 imp…

VulnHub靶机 DC-8 打靶实战 详细渗透过程

VulnHub靶机 DC-8 打靶 详细渗透过程 目录 VulnHub靶机 DC-8 打靶 详细渗透过程一、将靶机配置导入到虚拟机当中二、渗透测试流程主机发现端口扫描Web渗透SQL注入登录后台反弹shell提权 一、将靶机配置导入到虚拟机当中 靶机地址&#xff1a; https://www.vulnhub.com/entry/…

人工智能时代的关键技术:深入探索向量数据库及其在AI中的应用

文章目录 1. 理解向量数据库&#xff1a;二维模型示例2. 向量数据库中的数据存储与检索3. 向量数据库如何工作&#xff1f;4. 向量数据库如何知道哪些向量相似&#xff1f; 在人工智能技术日益成熟的当下&#xff0c;向量数据库作为处理和检索高维数据的关键工具&#xff0c;对…

使用新版ESLint,搭配Prettier使用的配置方式

概述 ESLint重大更新(9.0.0版本)后,将不再支持非扁平化配置文件,并且移除了与Prettier冲突的规则,也就是说与Prettier搭配使用,不再需要使用插件“eslint-config-prettier”来处理冲突问题。 注:使用新版的前提条件是Node.js版本必须是18.18.0、20.9.0,或者是>=21.1…

鸿蒙官网学习3

鸿蒙官网学习3 每日小提示项目的模块类型跨设备预览调试阶段应用的替换方式有两种 打开老的demo工程报错UIAbility 每日小提示 项目的模块类型 moduleType分为三种&#xff0c;只有1&#xff0c;2的模块支持直接调试和运行 entryfeaturehar 跨设备预览 需要手动在config.j…