kprobe_example.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /* https://cirosantilli.com/linux-kernel-module-cheat#kprobes
  2. *
  3. * Adapted from: https://github.com/torvalds/linux/blob/v4.17/samples/kprobes/kprobe_example.c
  4. */
  5. /* NOTE: This example is works on x86 and powerpc.
  6. * Here's a sample kernel module showing the use of kprobes to dump a
  7. * stack trace and selected registers when _do_fork() is called.
  8. *
  9. * For more information on theory of operation of kprobes, see
  10. * Documentation/kprobes.txt
  11. *
  12. * You will see the trace data in /var/log/messages and on the console
  13. * whenever _do_fork() is invoked to create a new process.
  14. */
  15. #include <linux/kernel.h>
  16. #include <linux/module.h>
  17. #include <linux/kprobes.h>
  18. #define MAX_SYMBOL_LEN 64
  19. static char symbol[MAX_SYMBOL_LEN] = "_do_fork";
  20. module_param_string(symbol, symbol, sizeof(symbol), 0644);
  21. /* For each probe you need to allocate a kprobe structure */
  22. static struct kprobe kp = {
  23. .symbol_name = symbol,
  24. };
  25. /* kprobe pre_handler: called just before the probed instruction is executed */
  26. static int handler_pre(struct kprobe *p, struct pt_regs *regs)
  27. {
  28. #ifdef CONFIG_X86
  29. pr_info("<%s> pre_handler: p->addr = 0x%px, ip = %lx, flags = 0x%lx\n",
  30. p->symbol_name, p->addr, regs->ip, regs->flags);
  31. #endif
  32. #ifdef CONFIG_PPC
  33. pr_info("<%s> pre_handler: p->addr = 0x%px, nip = 0x%lx, msr = 0x%lx\n",
  34. p->symbol_name, p->addr, regs->nip, regs->msr);
  35. #endif
  36. #ifdef CONFIG_MIPS
  37. pr_info("<%s> pre_handler: p->addr = 0x%px, epc = 0x%lx, status = 0x%lx\n",
  38. p->symbol_name, p->addr, regs->cp0_epc, regs->cp0_status);
  39. #endif
  40. #ifdef CONFIG_ARM64
  41. pr_info("<%s> pre_handler: p->addr = 0x%px, pc = 0x%lx,"
  42. " pstate = 0x%lx\n",
  43. p->symbol_name, p->addr, (long)regs->pc, (long)regs->pstate);
  44. #endif
  45. #ifdef CONFIG_S390
  46. pr_info("<%s> pre_handler: p->addr, 0x%px, ip = 0x%lx, flags = 0x%lx\n",
  47. p->symbol_name, p->addr, regs->psw.addr, regs->flags);
  48. #endif
  49. /* A dump_stack() here will give a stack backtrace */
  50. return 0;
  51. }
  52. /* kprobe post_handler: called after the probed instruction is executed */
  53. static void handler_post(struct kprobe *p, struct pt_regs *regs,
  54. unsigned long flags)
  55. {
  56. #ifdef CONFIG_X86
  57. pr_info("<%s> post_handler: p->addr = 0x%px, flags = 0x%lx\n",
  58. p->symbol_name, p->addr, regs->flags);
  59. #endif
  60. #ifdef CONFIG_PPC
  61. pr_info("<%s> post_handler: p->addr = 0x%px, msr = 0x%lx\n",
  62. p->symbol_name, p->addr, regs->msr);
  63. #endif
  64. #ifdef CONFIG_MIPS
  65. pr_info("<%s> post_handler: p->addr = 0x%px, status = 0x%lx\n",
  66. p->symbol_name, p->addr, regs->cp0_status);
  67. #endif
  68. #ifdef CONFIG_ARM64
  69. pr_info("<%s> post_handler: p->addr = 0x%px, pstate = 0x%lx\n",
  70. p->symbol_name, p->addr, (long)regs->pstate);
  71. #endif
  72. #ifdef CONFIG_S390
  73. pr_info("<%s> pre_handler: p->addr, 0x%px, flags = 0x%lx\n",
  74. p->symbol_name, p->addr, regs->flags);
  75. #endif
  76. }
  77. /*
  78. * fault_handler: this is called if an exception is generated for any
  79. * instruction within the pre- or post-handler, or when Kprobes
  80. * single-steps the probed instruction.
  81. */
  82. static int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
  83. {
  84. pr_info("fault_handler: p->addr = 0x%px, trap #%dn", p->addr, trapnr);
  85. /* Return 0 because we don't handle the fault. */
  86. return 0;
  87. }
  88. static int __init kprobe_init(void)
  89. {
  90. int ret;
  91. kp.pre_handler = handler_pre;
  92. kp.post_handler = handler_post;
  93. kp.fault_handler = handler_fault;
  94. ret = register_kprobe(&kp);
  95. if (ret < 0) {
  96. pr_err("register_kprobe failed, returned %d\n", ret);
  97. return ret;
  98. }
  99. pr_info("Planted kprobe at %px\n", kp.addr);
  100. return 0;
  101. }
  102. static void __exit kprobe_exit(void)
  103. {
  104. unregister_kprobe(&kp);
  105. pr_info("kprobe at %px unregistered\n", kp.addr);
  106. }
  107. module_init(kprobe_init)
  108. module_exit(kprobe_exit)
  109. MODULE_LICENSE("GPL");