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://xiahunao.cn/news/2980937.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【国产替代】航空电子通信总线航空电子通信总线产品为MIL-STD-1553和ARINC 429等协议提供原生支持

航空电子通信总线 航空电子通信总线产品为MIL-STD-1553和ARINC 429等协议提供原生支持。这些产品用于进行航空电子应用所需的开发、生产和系统测试。 PXIe&#xff0c;2通道PXI ARINC-664接口模块 AIM ARINC-664具有板载处理器&#xff0c;可自动处理所有与协议相关的活动&…

在vscode上面进行分支merge的记录

前言&#xff1a;在我们的项目中&#xff0c;有两个分支&#xff1a;master和liutielong。现在要将liutielong分支的改动merge到master分支中。 如果master分支已经更改了&#xff0c;所以要先pull&#xff08;这是在git bash里面的命令&#xff09;。 git pull origin master…

Java虚拟机类加载机制详细总结

1、概述 Java虚拟机把描述类的数据从Class文件加载到内存&#xff0c;并对数据进行校验、转换解析和初始化&#xff0c;最终形成可以被虚拟机直接使用的Java类型&#xff0c;这个过程被称作虚拟机的类加载机制。 2、类加载的时机 一个类型从被加载到虚拟机内存中开始&#xff…

网盘——查看文件

本文主要讲解文件操作过程中&#xff0c;查看文件如何实现&#xff0c;实现步骤如下&#xff1a; 1、实现步骤&#xff1a; A、首先客户端发送查看请求&#xff08;包含目录信息&#xff09; B、服务器将文件名字还有文件的类型发送给客户端&#xff08;只发送文件的名字&am…

基于小程序实现的查寝打卡系统

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】&#xff1a;Java 【框架】&#xff1a;ssm 【…

Esp32-S3 进行JSON解析

之前介绍了esp32-s3的http通信,对于返回的结果进行解析也是必须的,通常我们可以使用json格式进行通信,这样即便于理解也便于取值。今天我们介绍下JSON解析。 在这里用到的库是ujson,代码如下,将如下代码保存到设备即可 import micropython import json from json import …

S-Edge网关:柔性部署,让物联网接入更统一

S-Edge网关是什么&#xff1f; 网关是在实际物理世界与虚拟网络世界相连接的交叉点&#xff0c;为了让这个交叉点尽可能的复用&#xff0c;无需每种设备都配套一种连接方式&#xff0c;边缘网关主要就是用于传感器等物理设备与网络实现数据交互的通用设备&#xff0c;也称为物…

【简单讲解下如何学习C++】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

Windows10如何关闭Edge浏览器的Copilot

在Windows10更新后&#xff0c;打开Edge浏览器&#xff0c;无论复制什么内容&#xff0c;都会弹出Copilot人工智能插件&#xff0c;非常令人反感&#xff0c;网上搜索的关闭方法都非常麻烦&#xff0c;比如&#xff1a;组策略和注册表。自己摸索得出最简便有效的关闭方法。 1、…

Shadowsocks PAC模式自定义规则

Shadowsocks PAC模式自定义规则 关键词&#xff1a;Shadowsocks, PAC自动模式, 编辑PAC用户自定规则, PAC规则 Shadowsocks使用PAC自动模式时&#xff0c;访问一个网站要不要走代理&#xff0c;需要用户手动进行干预。 编辑PAC规则 点击菜单栏shadowsocks图标&#xff0c;在…

【网络安全】HTTP协议 — 基础

专栏文章索引&#xff1a;网络安全 有问题可私聊&#xff1a;QQ&#xff1a;3375119339 目录 学习目标​ 一、万维网的诞生与发展​编辑 1.万维网的诞生与发展 2.HTTP协议诞生与发展 二、网络基础 1.TCP/IP分层传输 1&#xff09;TCP/IP协议 2&#xff09;封装与拆封 …

云计算中的过度授权:安全隐患与应对策略

云计算凭借其弹性、可扩展等优势&#xff0c;已经成为诸多企业组织拓展业务的重要基础设施之一。然而&#xff0c;与传统IT架构相比&#xff0c;云计算环境的安全管理也面临着新的挑战。过度授权 (Overprivileging) 便是云安全领域亟待解决的主要问题之一&#xff0c;本文将带领…

mysql download 2024

好久没在官网下载 mysql server 安装包。今天想下载发现&#xff1a; 我访问mysql官网的速度好慢啊。mysql server 的下载页面在哪里啊&#xff0c;一下两下找不到。 最后&#xff0c;慢慢悠悠终于找到了下载页面&#xff0c;如下&#xff1a; https://dev.mysql.com/downlo…

OceanBase诊断调优 】—— 如何快速定位SQL问题

作者简介&#xff1a; 花名&#xff1a;洪波&#xff0c;OceanBase 数据库解决方案架构师&#xff0c;目前负责 OceanBase 数据库在各大型互联网公司及企事业单位的落地与技术指导&#xff0c;曾就职于互联网大厂和金融科技公司&#xff0c;主导过多项数据库升级、迁移、国产化…

uniapp APP检测更新

需求&#xff1a; 1.首次进入APP给出弹窗提示是否存在最新版本APP&#xff0c;可选择更新或者取消 2.选择取消后&#xff0c;在使用期间不再弹出该弹窗 3.在设置中增加按钮&#xff0c;点击进行版本检测&#xff0c;再弹窗 效果图&#xff1a; 使用到的插件&#xff1a;APP升…

消灭AI“耗电巨兽”?暴雨服务器推出液冷节能降耗算力方案

在科技飞速发展的今天&#xff0c;人工智能已成为驱动未来的重要力量。随着AI及大模型技术的进一步普及和应用场景的拓宽&#xff0c;相关算力需求呈指数级增长&#xff0c;大规模的AI训练和推理过程均需消耗大量电力&#xff0c;如同一个巨大的电力黑洞&#xff0c;吞噬着海量…

鸿蒙OpenHarmony【LED外设控制】 (基于Hi3861开发板)

概述 OpenHarmony WLAN模组基于Hi3861平台提供了丰富的外设操作能力&#xff0c;包含I2C、I2S、ADC、UART、SPI、SDIO、GPIO、PWM、FLASH等。本文介绍如何通过调用OpenHarmony的NDK接口&#xff0c;实现对GPIO控制&#xff0c;达到LED闪烁的效果。其他的IOT外设控制&#xff0…

【iOS开发】(五)react Native路由和导航20240421-22

【iOS开发】(五)react Native 路由和导航Navigation 20240421 在&#xff08;一&#xff09;&#xff08;二&#xff09;中我们 Reactnative搭建了开发环境、学习了 基础语法、状态管理&#xff0c;JSX、组件、状态和生命周期以及样式布局等。 在&#xff08;三&#xff09;&a…

【LeetCode】---118.杨辉三角

一、题目解析&#xff1a; 二、知识回顾&#xff1a; 1.二维数组&#xff1a; 2. C语言中的二维数组访问方式和vector二维数组的访问&#xff0c; 不同区别&#xff1a; &#xff08;1&#xff09;表面是一样的&#xff0c;但底层不同&#xff01; &#xff08;2&#xff09;静…

用户请求经过哪些处理(公网)

DNS服务器之间协作&#xff1a; 递归DNS查询&#xff1a;用户的请求首先发送到递归DNS服务器。 查询根DNS服务器&#xff1a;递归DNS服务器查询根DNS服务器&#xff0c;以找到管理.com顶级域的TLD DNS服务器。 查询TLD DNS服务器&#xff1a;根DNS服务器响应带有TLD DNS服务器…