Kprobes

Kprobes enables you to dynamically break into any kernel routine and collect debugging and performance information non-disruptively. You can trap at almost any kernel code address 1, specifying a handler routine to be invoked when the breakpoint is hit.

目前有两种探针:

  • kprobes:几乎可以插入内核中的任何指令(当然也有黑名单)
  • kretprobes:在指定函数返回时触发

可以通过两种方式使用kprobes:

  • 一种是编写内核模块,调用register_kprobe/unregister_kprobe,向内核注册探测点,灵活编写pre_handler 和 post_handler回调函数;
  • 另一种是使用 kprobes + ftrace

1. 实践

1.1. kprobe_example.c、kretprobe_example.c

源码在内核samples/kprobes目录下

# 编译kprobe_example.ko
# insmod kprobe_example.ko
# 随便敲几个命令
# dmesg
[ 3116.494530] handler_pre: <kernel_clone> p->addr = 0x0000000005f99348, ip = ffffffffa20fffc5, flags = 0x206
[ 3116.494535] handler_post: <kernel_clone> p->addr = 0x0000000005f99348, flags = 0x206
[ 3119.966756] handler_pre: <kernel_clone> p->addr = 0x0000000005f99348, ip = ffffffffa20fffc5, flags = 0x206
[ 3119.966762] handler_post: <kernel_clone> p->addr = 0x0000000005f99348, flags = 0x206

# rmmod kprobe_example

1.2. kprobes + ftrace

/sys/kernel/debug/kprobes/list: 内核中已经设置kprobes断点的函数
/sys/kernel/debug/kprobes/enabled: kprobes开关
/sys/kernel/debug/kprobes/blacklist: kprobes黑名单(无法设置断点函数)
/proc/sys/debug/kprobes-optimization: kprobes优化开关
# 开启trace
echo 1 > /sys/kernel/debug/tracing/tracing_on

# 注册
echo 'p:myprobe icmp_rcv' > /sys/kernel/debug/tracing/kprobe_events
echo 1 > /sys/kernel/debug/tracing/events/kprobes/myprobe/enable

# 随便ping几个包到本机
# 查看
cat /sys/kernel/debug/tracing/trace
# tracer: nop
#
# entries-in-buffer/entries-written: 6/6   #P:4
#
#                                _-----=> irqs-off/BH-disabled
#                               / _----=> need-resched
#                              | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| / _-=> migrate-disable
#                              |||| /     delay
#           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
#              | |         |   |||||     |         |
          <idle>-0       [001] ..s1.  4084.212468: myprobe: (icmp_rcv+0x4/0x3c0)
          <idle>-0       [001] ..s1.  4085.213941: myprobe: (icmp_rcv+0x4/0x3c0)
          <idle>-0       [001] ..s1.  4135.129815: myprobe: (icmp_rcv+0x4/0x3c0)
          <idle>-0       [001] ..s1.  4136.132458: myprobe: (icmp_rcv+0x4/0x3c0)

# 删除
echo 0 > /sys/kernel/debug/tracing/events/kprobes/myprobe/enable
echo '-:myprobe' > /sys/kernel/debug/tracing/events/kprobe_events

2. 原理

3. 参考

https://www.kernel.org/doc/html/latest/trace/kprobes.html https://www.kernel.org/doc/html/latest/trace/kprobetrace.html

results matching ""

    No results matching ""