linux/samples/kprobes/kprobe_example.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Here's a sample kernel module showing the use of kprobes to dump a
   4 * stack trace and selected registers when kernel_clone() is called.
   5 *
   6 * For more information on theory of operation of kprobes, see
   7 * Documentation/trace/kprobes.rst
   8 *
   9 * You will see the trace data in /var/log/messages and on the console
  10 * whenever kernel_clone() is invoked to create a new process.
  11 */
  12
  13#define pr_fmt(fmt) "%s: " fmt, __func__
  14
  15#include <linux/kernel.h>
  16#include <linux/module.h>
  17#include <linux/kprobes.h>
  18
  19#define MAX_SYMBOL_LEN  64
  20static char symbol[MAX_SYMBOL_LEN] = "kernel_clone";
  21module_param_string(symbol, symbol, sizeof(symbol), 0644);
  22
  23/* For each probe you need to allocate a kprobe structure */
  24static struct kprobe kp = {
  25        .symbol_name    = symbol,
  26};
  27
  28/* kprobe pre_handler: called just before the probed instruction is executed */
  29static int __kprobes handler_pre(struct kprobe *p, struct pt_regs *regs)
  30{
  31#ifdef CONFIG_X86
  32        pr_info("<%s> p->addr = 0x%p, ip = %lx, flags = 0x%lx\n",
  33                p->symbol_name, p->addr, regs->ip, regs->flags);
  34#endif
  35#ifdef CONFIG_PPC
  36        pr_info("<%s> p->addr = 0x%p, nip = 0x%lx, msr = 0x%lx\n",
  37                p->symbol_name, p->addr, regs->nip, regs->msr);
  38#endif
  39#ifdef CONFIG_MIPS
  40        pr_info("<%s> p->addr = 0x%p, epc = 0x%lx, status = 0x%lx\n",
  41                p->symbol_name, p->addr, regs->cp0_epc, regs->cp0_status);
  42#endif
  43#ifdef CONFIG_ARM64
  44        pr_info("<%s> p->addr = 0x%p, pc = 0x%lx, pstate = 0x%lx\n",
  45                p->symbol_name, p->addr, (long)regs->pc, (long)regs->pstate);
  46#endif
  47#ifdef CONFIG_ARM
  48        pr_info("<%s> p->addr = 0x%p, pc = 0x%lx, cpsr = 0x%lx\n",
  49                p->symbol_name, p->addr, (long)regs->ARM_pc, (long)regs->ARM_cpsr);
  50#endif
  51#ifdef CONFIG_RISCV
  52        pr_info("<%s> p->addr = 0x%p, pc = 0x%lx, status = 0x%lx\n",
  53                p->symbol_name, p->addr, regs->epc, regs->status);
  54#endif
  55#ifdef CONFIG_S390
  56        pr_info("<%s> p->addr, 0x%p, ip = 0x%lx, flags = 0x%lx\n",
  57                p->symbol_name, p->addr, regs->psw.addr, regs->flags);
  58#endif
  59
  60        /* A dump_stack() here will give a stack backtrace */
  61        return 0;
  62}
  63
  64/* kprobe post_handler: called after the probed instruction is executed */
  65static void __kprobes handler_post(struct kprobe *p, struct pt_regs *regs,
  66                                unsigned long flags)
  67{
  68#ifdef CONFIG_X86
  69        pr_info("<%s> p->addr = 0x%p, flags = 0x%lx\n",
  70                p->symbol_name, p->addr, regs->flags);
  71#endif
  72#ifdef CONFIG_PPC
  73        pr_info("<%s> p->addr = 0x%p, msr = 0x%lx\n",
  74                p->symbol_name, p->addr, regs->msr);
  75#endif
  76#ifdef CONFIG_MIPS
  77        pr_info("<%s> p->addr = 0x%p, status = 0x%lx\n",
  78                p->symbol_name, p->addr, regs->cp0_status);
  79#endif
  80#ifdef CONFIG_ARM64
  81        pr_info("<%s> p->addr = 0x%p, pstate = 0x%lx\n",
  82                p->symbol_name, p->addr, (long)regs->pstate);
  83#endif
  84#ifdef CONFIG_ARM
  85        pr_info("<%s> p->addr = 0x%p, cpsr = 0x%lx\n",
  86                p->symbol_name, p->addr, (long)regs->ARM_cpsr);
  87#endif
  88#ifdef CONFIG_RISCV
  89        pr_info("<%s> p->addr = 0x%p, status = 0x%lx\n",
  90                p->symbol_name, p->addr, regs->status);
  91#endif
  92#ifdef CONFIG_S390
  93        pr_info("<%s> p->addr, 0x%p, flags = 0x%lx\n",
  94                p->symbol_name, p->addr, regs->flags);
  95#endif
  96}
  97
  98static int __init kprobe_init(void)
  99{
 100        int ret;
 101        kp.pre_handler = handler_pre;
 102        kp.post_handler = handler_post;
 103
 104        ret = register_kprobe(&kp);
 105        if (ret < 0) {
 106                pr_err("register_kprobe failed, returned %d\n", ret);
 107                return ret;
 108        }
 109        pr_info("Planted kprobe at %p\n", kp.addr);
 110        return 0;
 111}
 112
 113static void __exit kprobe_exit(void)
 114{
 115        unregister_kprobe(&kp);
 116        pr_info("kprobe at %p unregistered\n", kp.addr);
 117}
 118
 119module_init(kprobe_init)
 120module_exit(kprobe_exit)
 121MODULE_LICENSE("GPL");
 122