linux kprobe使用
使用场景
- 监控某个内核函数是否被调用
- 获取某个内核函数耗费的时间
- 获取某个内核函数的入参
- 获取某个内核函数的调用栈(
dump_stack()
) - 获取某个内核函数的返回值
参数传递规则
x86平台对pt_regs的定义
arch/x86/include/asm/ptrace.h
// i386架构
#ifdef __i386__struct pt_regs {/** NB: 32-bit x86 CPUs are inconsistent as what happens in the* following cases (where %seg represents a segment register):** - pushl %seg: some do a 16-bit write and leave the high* bits alone* - movl %seg, [mem]: some do a 16-bit write despite the movl* - IDT entry: some (e.g. 486) will leave the high bits of CS* and (if applicable) SS undefined.** Fortunately, x86-32 doesn't read the high bits on POP or IRET,* so we can just treat all of the segment registers as 16-bit* values.*/unsigned long bx;unsigned long cx;unsigned long dx;unsigned long si;unsigned long di;unsigned long bp;unsigned long ax;unsigned short ds;unsigned short __dsh;unsigned short es;unsigned short __esh;unsigned short fs;unsigned short __fsh;/* On interrupt, gs and __gsh store the vector number. */unsigned short gs;unsigned short __gsh;/* On interrupt, this is the error code. */unsigned long orig_ax;unsigned long ip;unsigned short cs;unsigned short __csh;unsigned long flags;unsigned long sp;unsigned short ss; unsigned short __ssh;
};#else /* __i386__ */
// ia64
struct pt_regs {
/** C ABI says these regs are callee-preserved. They aren't saved on kernel entry* unless syscall needs a complete, fully filled "struct pt_regs".*/unsigned long r15;unsigned long r14;unsigned long r13;unsigned long r12;unsigned long bp;unsigned long bx;
/* These regs are callee-clobbered. Always saved on kernel entry. */unsigned long r11;unsigned long r10;unsigned long r9;unsigned long r8;unsigned long ax;unsigned long cx;unsigned long dx;unsigned long si;unsigned long di;
/** On syscall entry, this is syscall#. On CPU exception, this is error code.* On hw interrupt, it's IRQ number:*/unsigned long orig_ax;
/* Return frame for iretq */unsigned long ip;unsigned long cs;unsigned long flags;unsigned long sp;unsigned long ss;
/* top of stack page */
};#endif /* !__i386__ */
从4.18的内核版本bpf
的相关源码/tools/testing/selftests/bpf/bpf_helpers.h
中可以窥探x86
结构和`arm``架构函数参数传递规则。
#if defined(bpf_target_x86)
#define PT_REGS_PARM1(x) ((x)->di)
#define PT_REGS_PARM2(x) ((x)->si)
#define PT_REGS_PARM3(x) ((x)->dx)
#define PT_REGS_PARM4(x) ((x)->cx)
#define PT_REGS_PARM5(x) ((x)->r8)
#define PT_REGS_RET(x) ((x)->sp)
#define PT_REGS_FP(x) ((x)->bp)
#define PT_REGS_RC(x) ((x)->ax)
#define PT_REGS_SP(x) ((x)->sp)
#define PT_REGS_IP(x) ((x)->ip)#elif defined(bpf_target_arm64)
#define PT_REGS_PARM1(x) ((x)->regs[0])
#define PT_REGS_PARM2(x) ((x)->regs[1])
#define PT_REGS_PARM3(x) ((x)->regs[2])
#define PT_REGS_PARM4(x) ((x)->regs[3])
#define PT_REGS_PARM5(x) ((x)->regs[4])
#define PT_REGS_RET(x) ((x)->regs[30])
#define PT_REGS_FP(x) ((x)->regs[29]) /* Works only with CONFIG_FRAME_POINTER */
#define PT_REGS_RC(x) ((x)->regs[0])
#define PT_REGS_SP(x) ((x)->sp)
#define PT_REGS_IP(x) ((x)->pc)
/samples/bpf/test_overhead_kprobe_kern.c
// 使用示例
SEC("kprobe/__set_task_comm")
int prog(struct pt_regs *ctx)
{struct signal_struct *signal;struct task_struct *tsk;char oldcomm[16] = {};char newcomm[16] = {};u16 oom_score_adj;u32 pid;tsk = (void *)PT_REGS_PARM1(ctx);pid = _(tsk->pid);bpf_probe_read(oldcomm, sizeof(oldcomm), &tsk->comm);bpf_probe_read(newcomm, sizeof(newcomm), (void *)PT_REGS_PARM2(ctx));signal = _(tsk->signal);oom_score_adj = _(signal->oom_score_adj);return 0;
}// 函数原型
/** These functions flushes out all traces of the currently running executable* so that a new one can be started*/
void __set_task_comm(struct task_struct *tsk, const char *buf, bool exec)
{task_lock(tsk);trace_task_rename(tsk, buf);strlcpy(tsk->comm, buf, sizeof(tsk->comm));task_unlock(tsk);perf_event_comm(tsk, exec);
}
- x86架构寄存器约定与函数参数传递
在 X86_64 架构中,寄存器的约定如上,当调用一个函数的时候,RDI 寄存器用于传递第一个参数,RSI 寄存器用于传递第二个寄存器,依次类推,R9 寄存器传递第六个参数, 函数返回值保存在 RAX 寄存器中。那么如果函数的参数超过六个,那么多余的参数参数如何传递? 在 X86_64 架构中,函数大于 6 个参数的参数通过堆栈进行传输。
其中RDI对应pt_regs结构体中的di,其他寄存器依次类推。
- ARM架构寄存器约定与函数参数传递
在 ARM64 架构中,使用 X0-X7 寄存器传递参数,第一个参数通过 X0 寄存器传递,第二个参数通过 X1 寄存器传递,以此类推. 返回值存储在 X0 寄存器中。
使用实例
/samples/kprobes/kprobe_example.c
/** NOTE: This example is works on x86 and powerpc.* Here's a sample kernel module showing the use of kprobes to dump a* stack trace and selected registers when _do_fork() is called.** For more information on theory of operation of kprobes, see* Documentation/kprobes.txt** You will see the trace data in /var/log/messages and on the console* whenever _do_fork() is invoked to create a new process.*/#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>#define MAX_SYMBOL_LEN 64
static char symbol[MAX_SYMBOL_LEN] = "_do_fork";
module_param_string(symbol, symbol, sizeof(symbol), 0644);/* For each probe you need to allocate a kprobe structure */
static struct kprobe kp = {.symbol_name = symbol,
};/* kprobe pre_handler: called just before the probed instruction is executed */
static int handler_pre(struct kprobe *p, struct pt_regs *regs)
{
#ifdef CONFIG_X86pr_info("<%s> pre_handler: p->addr = 0x%p, ip = %lx, flags = 0x%lx\n",p->symbol_name, p->addr, regs->ip, regs->flags);
#endif
#ifdef CONFIG_PPCpr_info("<%s> pre_handler: p->addr = 0x%p, nip = 0x%lx, msr = 0x%lx\n",p->symbol_name, p->addr, regs->nip, regs->msr);
#endif
#ifdef CONFIG_MIPSpr_info("<%s> pre_handler: p->addr = 0x%p, epc = 0x%lx, status = 0x%lx\n",p->symbol_name, p->addr, regs->cp0_epc, regs->cp0_status);
#endif
#ifdef CONFIG_ARM64pr_info("<%s> pre_handler: p->addr = 0x%p, pc = 0x%lx,"" pstate = 0x%lx\n",p->symbol_name, p->addr, (long)regs->pc, (long)regs->pstate);
#endif
#ifdef CONFIG_S390pr_info("<%s> pre_handler: p->addr, 0x%p, ip = 0x%lx, flags = 0x%lx\n",p->symbol_name, p->addr, regs->psw.addr, regs->flags);
#endif/* A dump_stack() here will give a stack backtrace */return 0;
}/* kprobe post_handler: called after the probed instruction is executed */
static void handler_post(struct kprobe *p, struct pt_regs *regs,unsigned long flags)
{
#ifdef CONFIG_X86pr_info("<%s> post_handler: p->addr = 0x%p, flags = 0x%lx\n",p->symbol_name, p->addr, regs->flags);
#endif
#ifdef CONFIG_PPCpr_info("<%s> post_handler: p->addr = 0x%p, msr = 0x%lx\n",p->symbol_name, p->addr, regs->msr);
#endif
#ifdef CONFIG_MIPSpr_info("<%s> post_handler: p->addr = 0x%p, status = 0x%lx\n",p->symbol_name, p->addr, regs->cp0_status);
#endif
#ifdef CONFIG_ARM64pr_info("<%s> post_handler: p->addr = 0x%p, pstate = 0x%lx\n",p->symbol_name, p->addr, (long)regs->pstate);
#endif
#ifdef CONFIG_S390pr_info("<%s> pre_handler: p->addr, 0x%p, flags = 0x%lx\n",p->symbol_name, p->addr, regs->flags);
#endif
}/** fault_handler: this is called if an exception is generated for any* instruction within the pre- or post-handler, or when Kprobes* single-steps the probed instruction.*/
static int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
{pr_info("fault_handler: p->addr = 0x%p, trap #%dn", p->addr, trapnr);/* Return 0 because we don't handle the fault. */return 0;
}static int __init kprobe_init(void)
{int ret;kp.pre_handler = handler_pre;kp.post_handler = handler_post;kp.fault_handler = handler_fault;ret = register_kprobe(&kp);if (ret < 0) {pr_err("register_kprobe failed, returned %d\n", ret);return ret;}pr_info("Planted kprobe at %p\n", kp.addr);return 0;
}static void __exit kprobe_exit(void)
{unregister_kprobe(&kp);pr_info("kprobe at %p unregistered\n", kp.addr);
}module_init(kprobe_init)
module_exit(kprobe_exit)
MODULE_LICENSE("GPL");
obj-m := kprobe.okprobe-y += kprobe_example.oBASEINCLUDE ?= /lib/modules/`uname -r`/buildall:$(MAKE) -C $(BASEINCLUDE) M=$(PWD) modules;clean:$(MAKE) -C $(BASEINCLUDE) M=$(PWD) clean;rm -f *.ko;
```
相关文章:
linux kprobe使用
使用场景 监控某个内核函数是否被调用获取某个内核函数耗费的时间获取某个内核函数的入参获取某个内核函数的调用栈(dump_stack())获取某个内核函数的返回值 参数传递规则 x86平台对pt_regs的定义 arch/x86/include/asm/ptrace.h // i386架构 #ifdef…...
2023年超全前端面试题-背完稳稳拿offer(欢迎补充)
HTML、CSS相关 HTML5 HTML5新特性 增强了表单,input新增了一些type: color----定义调色板 tel-----定义包含电话号码的输入域 email—定义包含email地址的输入域 search–定义搜索域 number–定义包含数值的输入域 date----定义选取日、月、年的输入域…...
python之web自动化测试框架
梳理下搭建web自动化框架的流程: 创建目录: cases:存放测试用例,unittest框架要求用例名必须以test开头,所以命名test_case.py test_case.py代码如下:继承unittest.TestCase类下面的方法setupclass(),te…...
算法笔记(十五)—— 动态规划(暴力递归到动态规划)习题训练!
通过递归到记忆化搜索再到严格表结构的动态规划 递归方法的评价:1. 单可变参数的维度;2. 可变参数的个数 记忆化搜索 在暴力递归中会存在很多的重复计算,可以使用存储结构来实现空间换时间。 严格表结构的动态规划 整理位置之间的依赖关系…...
云原生架构基础概念及应用办法
什么是云原生? 云原生是一种基于容器、微服务和自动化运维的软件开发和部署方法。它可以使应用程序更加高效、可靠和可扩展,适用于各种不同的云平台。 如果要更直接通俗的来解释下上面的概念。 云原生更准确来说就是一种文化,是一种潮流&a…...
RedisTemplate 的基本使用手把手教
下载实例源码 使用步骤 1、引入 spring-boot-starter-data-redis 依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency>2、在 application.yml 配置 R…...
Hbase -- Compact工具梳理
1. 背景 当前,线上HBase集群的自动Major Compact是关闭的,我们选择在凌晨业务空闲的时候进行手动触发Major Compact,Compact工具就是在运维平台上对资源组、RS、表进行Major Compact。目前线上有2种版本的Compact程序:Compact_v1…...
【java代码审计】SQL注入
1 原理 没有正确的对用户的输入进行检查,将用户的输入以拼接的方式带入到SQL语句中,导致SQL注入。 2 产生SQL注入的原因 2.1 JDBC拼接不当造成SQL注入 前置知识: JDBC执行SQL语句的两种方式: PrepareStatement:会对…...
前置知识-辛 Runge-Kutta 方法
1.3.3 辛 Runge-Kutta 方法 将方程 ( 1.10.2 ) (1.10 .2) (1.10.2) 改写为 d z d x =...
require 与 import 两种引入模块方式到底有什么区别?
关于JavaScript 的模块化规范,可以移步至: 【JavaScript高级】模块化规范「一文让你彻底搞懂前端模块化规范 & 区别」 下面进入正题 require 与 import 两种引入模块方式,到底有什么区别呢? 大致可以分为以下几个方面&#…...
软考信息系统监理师备考建议
用好备考方法,两三个月就可以过的。信息系统监理师备考最好以教材和历年真题为主,教学视频模拟题为辅。考试介绍与复习建议:考试设置的科目包括:(1)信息系统工程监理基础知识,考试时间150分钟&a…...
第八届蓝桥杯省赛——4承压计算(二维数组,嵌套循环)
题目:X星球的高科技实验室中整齐地堆放着某批珍贵金属原料。每块金属原料的外形、尺寸完全一致,但重量不同。金属材料被严格地堆放成金字塔形。7 5 8 7 8 8 9 2 7 2 8 1 4 9 1 8 1 8 8 4 1 7 9 6 1 4 5 4 5 6 5 5 6 9 5 6 5 5 4 7 9 3 5 5 1 7 5 7 9 7 4…...
【ECNU】3645. 莫干山奇遇(C++)
目录 题目 输入格式 输出格式 样例 提示 思路 代码 题目 单点时限: 2.0 sec 内存限制: 512 MB 出题人当然是希望出的题目有关 oxx,于是想方设法给题目配上一些有关 oxx 的背景故事,使得它看起来不那么无趣。但有的时候却无法引入合适的小姐姐&…...
为什么需要学习shell、shell的作用
课程基于B站于超课程笔记 03 Shebang的正确玩法_哔哩哔哩_bilibili P1 shell的作用 P2 shell执行命令的流程 P3 Shebang的正确玩法 什么是shell及组成 shell概念 shelll组成 Shebang概念 /bin/sh /bin/bash一样,都是指向一个bash解释器 [rootlocalhost ~]#…...
pgsql-Create_ALTER_GRANT_REVOKE命令语法
pgsql-Create_ALTER_GRANT_REVOKE命令语法 资料 语法约定 CREATE ROLE ALTER ROLE GRANT授权 REVOKE回收授权 权限类型说明 语法约定 下面的约定被用于命令的大纲:方括弧([和])表示可选的部分(在 Tcl 命令里,使…...
【linux】:进程概念
文章目录 冯诺依曼体系结构一:操作系统二: 进程总结冯诺依曼体系结构 我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系。 冯诺依曼体系如下图: 那么输入设备有哪些呢?…...
创建对象的方式和对属性的操作
javaScript支持多种编程范式,包括函数式编程和面向对象编程,javaScript的对象被设计成一组属性的无序集合,由key和value组成。 创建对象的两种方式 早期使用创建对象方式最多的是使用Object类,使用new关键字来创建一个对象&…...
GO时间相关操作说明
文章目录 GO时间相关操作时间转换成字符串字符串转换成时间时间戳和时间操作时间比较操作时间增加和减少操作休眠操作time.AfterFunc操作time.NewTicker操作GO时间相关操作 GO语言在使用时间转换的时候会用到2006-01-02 15:04:05 这是固定参数写法,类似java语言中的yyyy-M…...
选择和分支结构
选择和分支结构选择和分支结构一、复习问答二、选择结构2.1 基础选择结构2.2 if-else结构2.3 多重if结构2.4 嵌套if结构三、分支结构四、局部变量选择和分支结构 一、复习问答 1、Java中基本数据类型 2、类型的转换的两种情形 3、数据类型提升的规则 二、选择结构 2.1 基础选…...
Elasticsearch总结笔记
文章目录简介类型增删改查操作索引原理简介 底层使用的lucene引擎,lucene引擎直接使用相对复杂,有一定的学习成本,同样是使用Java编写,Elasticsearch使用的rest风格的进行交互,而数据呢则是以JSON的方式进行传输。学习…...
Ubuntu 安装指定版本 Mysql,并设置远程连接(以安装mysql 5.5 为例)
目录 一、安装Mysql 1、卸载Mysql(可跳过) 2、安装mysql 软件源 3、安装mysql 5.5 4、验证测试 二、设置远程登录 1、允许使用root账号远程连接 2、Mysql 允许远程登录 一、安装Mysql 1、卸载Mysql(可跳过) 如果之前安装…...
NumPy:Python中的强大数学工具
NumPy:Python中的强大数学工具 文章目录NumPy:Python中的强大数学工具一、NumPy简介二、创建数组三、数组尺寸四、数组运算五、数组切片六、数组连接七、数据存取八、数组形态变换九、数组排序与搜索十、矩阵与线性代数运算一、NumPy简介 当谈到数据科学…...
Hbase资源隔离操作指南
1.检查集群的环境配置 1.1 HBase版本号确认> 5.11.0 引入rsgroup的Patch: [HBASE-6721] RegionServer Group based Assignment - ASF JIRA RegionServer Group based Assignment 社区支持版本:2.0.0 引入rsgroup的CDH版本 5.11.0 https://www.…...
TPS2012B泰克Tektronix隔离通道示波器
简 述: 复杂环境中开发和测试你的设计,进行浮动或差 分测量;100MHz,2通道 主要特点和优点 100 MHz和200 MHz带宽 高达2 GS/s的实时采样率 2条或4条全面隔离和浮动通道,外加隔离外部触 发 在安装两块电池时可以连续…...
9.4 PIM-DM
实验目的 熟悉PIM-DM的应用场景掌握PIM-DM的配置方法 实验拓扑 实验拓扑如图9-28所示: 图9-28:PIM-DM 实验步骤 (1)IP地址的配置 MCS1的配置如图9-29所示: 图9-29:配置MCS1的IP地址 R1的配置 <Huawe…...
程序员推荐的良心网站合集!
今天来给大家推荐几个程序员必看的国外良心网站合集。 IBM developer 技术性很强的博客网站,网站自带真实示例代码和架构解决方案,大家可以在上面找到适合自己的语言方向开始学习交流。 https://developer.ibm.com/ infoq 技术论坛社区,内…...
信息安全概论之《密码编码学与网络安全----原理与实践(第八版)》
前言:在信息安全概论课程的学习中,参考了《密码编码学与网络安全----原理与实践(第八版)》一书。以下内容为以课件为主要参考,课本内容与网络资源为辅助参考,学习该课程后作出的总结。 一、信息安全概述 1…...
跬智信息全新推出云原生数据底座玄武,助力国产化数据服务再次升级
2月28日,跬智信息(Kyligence)宣布全新推出国产化云原生数据底座开源项目玄武(XUANWU),以助力企业加速数据平台上云,并实现国产化升级。玄武(XUANWU)是在容器化技术上形成…...
【离线数仓-9-数据仓库开发DWS层设计要点-DWS层汇总表以及数据装载】
离线数仓-9-数据仓库开发DWS层设计要点-DWS层汇总表以及数据装载离线数仓-9-数据仓库开发DWS层设计要点-DWS层汇总表以及数据装载一、交易域用户商品粒度订单最近1日/N日汇总表1.交易域用户商品粒度订单最近1日汇总表2.交易域用户商品粒度订单最近N日汇总表二、交易域优惠券粒度…...
我的十年编程路 序
算起来,从决定并从事编程开始,已十年有余了。 这十年是怎么算的呢? 我的本科是从2009年至2013年,现在回想起来,应该是从2012年下半年,也就是大四还未正式开始的时候决定从事Android开发。参加了培训班&am…...
wordpress主题开发文档/怎样创建网站平台
ROUND(A1*0.75,0)转载于:https://www.cnblogs.com/Ph-one/p/5501320.html...
查域名注册/百度seo原理
属性:公有属性 (属于类,每个类一份)普通属性 (属于对象,每个对象一份)私有属性 (属于对象,跟普通属性相似,只是不能通过对象直接访问)方法:(按作用)构造方法析构函数方法:(按类型)普通方法…...
vue响应式网站开发/营销型网站有哪些平台
0x00前言 今天在知道创宇上发现3月26日提交WordPress XSS和远程代码执行漏洞,于是试着复现了下远程代码执行漏洞 该漏洞源于Social Warfare组件,并且版本<3.5.2、且要是管理员登录状态,因此该漏洞是个后台代码执行 漏洞报告https://www.we…...
佛山专业做网站公司有哪些/百度客服24小时电话人工服务
Problem Description 给出组合数C(n,m), 表示从n个元素中选出m个元素的方案数。例如C(5,2) 10, C(4,2) 6.可是当n,m比较大的时候,C(n,m)很大!于是xiaobo希望你输出 C(n,m) mod p的值!思路:水题,练一下l&a…...
哪家做网站公司好/广州网络推广专员
原因:出现这个问题,可能有人move过表,或者disable 过索引。1、alter table xxxxxx move tablespace xxxxxxx 命令后,索引就会失效。2、alter index index_name unusable,命令使索引失效。 解决办法:1、重建…...
网站建设客户问到的问题/建网站的公司
XYPieChart创建动态饼 关键字:饼图 动态饼图 代码类库:绘图(Drawing) GitHub链接:https://github.com/xyfeng/XYPieChart 可以帮你简单地创建动态饼图。所有的动画都是用drawRect:方法实现。可自定义颜色文本标签选项显示实际值或者百分比当一…...