linux kprobes
kprobes
kprobes Kretprobes是linux系统的一个动态调试机制,
使用它可以向内核添加探针(Probe),在代码执行前或执行后触发一个回调函数。
这个机制通常用于调试内核代码,跟踪应用程序执行或收集性能统计信息。
通过使用kprobe,开发人员可以在不影响系统运行逻辑的情况下,对操作系统进行深入的分析和调试。
reference:
linux/Documentation/kprobes.txt
Linux内核调试技术——kprobe使用与实现(一)
Linux内核调试技术——kprobe使用与实现(二)
kernel config:
General architecture-dependent options --->
[*] Kprobes
sample:
linux/samples/kprobes
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kprobes.h>
#include <linux/sched.h>
static int handler_pre(struct kprobe *p, struct pt_regs *regs)
{
struct task_struct *cur = current;
int sig = (int)regs->regs[0];
struct task_struct *task = (struct task_struct *)regs->regs[2];
/*pr_info("pre_handler, p->pc:0x%p, pc = 0x%lx\n", p->addr, regs->pc);*/
/* if (sig == 9 || sig == 14 || sig == 15) */
pr_info("signal:%d, cur_task:%s -> task:%s\n",
sig, cur->comm, task->comm);
return 0;
}
static void handler_post(struct kprobe *p, struct pt_regs *regs, unsigned long flags)
{
/* pr_info("post_handler, p->pc:0x%p, flags:0x%lx\n", p->addr, flags); */
}
static int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
{
pr_info("fault_handler, p->pc:0x%p, trap:%dn", p->addr, trapnr);
return 0;
}
static struct kprobe kp = {
.symbol_name = "do_send_sig_info",
.pre_handler = handler_pre,
.post_handler = handler_post,
.fault_handler = handler_fault,
};
static int __init kprobe_init(void)
{
int ret;
pr_info("%s()\n", __func__);
ret = register_kprobe(&kp);
if (ret < 0) {
pr_err("register_kprobe failed: %d\n", ret);
return ret;
}
pr_info("%s() done\n", __func__);
return 0;
}
static void __exit kprobe_exit(void)
{
unregister_kprobe(&kp);
pr_info("%s()\n", __func__);
}
module_init(kprobe_init);
module_exit(kprobe_exit);
MODULE_AUTHOR("wangyangkai");
MODULE_DESCRIPTION("arm64 kprobe example");
MODULE_LICENSE("GPL");
log:
~$
~$ killall top
[ 123.348849] signal:15, cur task:killall -> task:top
~$
written by wangyangkai on 2021.05.10