kprobe_example.c 3.6 KB

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