San7o/linux-kprobe-example
Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Repository files navigation
linux-kprobe-example
====================
Example kernel module that registers a kprobe on a syscall.
Author: Giovanni Santini
Mail: giovanni.santini@proton.me
License: GPLv2
Overview
--------
Kprobes are probably my favorite hack I have ever seen. They are so
brutal and so unsafe and it feels like you own your cpu. Essentially
they can force a jump to a function we control anywhere in the
code. For example, if I want to check all the times the syscall `open`
is called, I can just force a jump to my handler that logs this
information or increments some sort of counter.
The way this works is to literally patch the first instruction in
memory at the address where a function lives, with a breakpoint that
will give control to us, all during runtime! We can then jump to the
original address + offset if we want to return to the original flow,
or maybe not.
This can also be done when a function is about to return (kretprobe),
by changing the return address that was placed in the stack by the
caller.
If the architecture allows it, instead of setting up a breakpoint we
just to a jpm on our handler.
Compilation
-----------
To build and load the kernel module, you first need the kernel
sources. In addition to building the module, we will also build the
kernel and an image to boot it with qemu for development. This is
advised since kernel panics in your module may crash the system.
Download a kernel version:
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.19.3.tar.xz
tar -xvf linux-6.19.3.tar.xz && mv linux-6.19.3 linux
cd linux
make defconfig && make -j$(nproc)
cd ..
Build the module:
make KVERSION=6.19.3
Clean the build:
make clean
Create an image, copy the module, and boot with qemu:
make img
make copy
make qemu
Usage
-----
Inside the image, you will find the module in the /root directory. You
can load it with `insmod`
insmod ./hello-kprobe.ko
Check messages in `dmeg`:
dmesg
Remove the module with:
rmmod ./hello-kprobe.ko
Debugging
---------
Follow this guide to debug kernel modules with gdb:
https://www.kernel.org/doc/html/v6.17/process/debugging/gdb-kernel-debugging.html
cat /sys/module/<your_module_name>/sections/.text
make qemu-debug
gdb ./linux/arch/x86/boot/vmlinux
(gdb) target remote :1234
(gdb) add-symbol-file /path/to/your/module.ko 0xffffffffa0000000