I’m installing a kprobe on sys_kill and I want to monitor PID and Signals.
While I can install the kprobe and getting some data in dmesg but they are either wrong or I cannot make sense of them.
Below is the code that I have,
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kprobes.h>
#include <linux/ptrace.h>
#include <linux/signal.h>
#include <linux/sched.h>
static struct kprobe kp;
static int handler_pre(struct kprobe *p, struct pt_regs *regs)
{
pid_t pid = (pid_t)regs->di;
int sig = (int)regs->si;
printk(KERN_INFO "kprobe pre_handler: kill syscall - PID: %d, Signal: %dn", pid, sig);
return 0;
}
static void handler_post(struct kprobe *p, struct pt_regs *regs, unsigned long flags)
{
pid_t pid = (pid_t)regs->di;
int sig = (int)regs->si;
printk(KERN_INFO "kprobe post_handler: kill syscall - PID: %d, Signal: %dn", pid, sig);
}
static int __init kprobe_init(void)
{
kp.symbol_name = "__x64_sys_kill";
kp.pre_handler = handler_pre;
kp.post_handler = handler_post;
int ret = register_kprobe(&kp);
if (ret < 0) {
printk(KERN_INFO "register_kprobe failed, returned %dn", ret);
return ret;
}
printk(KERN_INFO "kprobe registered for __x64_sys_killn");
return 0;
}
static void __exit kprobe_exit(void)
{
unregister_kprobe(&kp);
printk(KERN_INFO "kprobe unregisteredn");
}
module_init(kprobe_init)
module_exit(kprobe_exit)
MODULE_LICENSE("GPL");
It gives me the following output,
kernel: [ 2605.007657] kprobe pre_handler: kill syscall - PID: 6029144, Signal: 62
kernel: [ 2605.007658] kprobe post_handler: kill syscall - PID: 6029144, Signal: 62
kernel: [ 2605.007660] kprobe pre_handler: kill syscall - PID: 6029144, Signal: 62
kernel: [ 2605.007661] kprobe post_handler: kill syscall - PID: 6029144, Signal: 62
kernel: [ 2605.007662] kprobe pre_handler: kill syscall - PID: 6029144, Signal: 62
kernel: [ 2605.007663] kprobe post_handler: kill syscall - PID: 6029144, Signal: 62
kernel: [ 2605.007666] kprobe pre_handler: kill syscall - PID: 6029144, Signal: 62
kernel: [ 2605.007667] kprobe post_handler: kill syscall - PID: 6029144, Signal: 62
kernel: [ 2605.007668] kprobe pre_handler: kill syscall - PID: 6029144, Signal: 62
kernel: [ 2605.007669] kprobe post_handler: kill syscall - PID: 6029144, Signal: 62
kernel: [ 2605.007671] kprobe pre_handler: kill syscall - PID: 6029144, Signal: 62
kernel: [ 2605.007672] kprobe post_handler: kill syscall - PID: 6029144, Signal: 62
kernel: [ 2605.007674] kprobe pre_handler: kill syscall - PID: 6029144, Signal: 62
kernel: [ 2605.007675] kprobe post_handler: kill syscall - PID: 6029144, Signal: 62
kernel: [ 2605.007676] kprobe pre_handler: kill syscall - PID: 6029144, Signal: 62
kernel: [ 2605.007677] kprobe post_handler: kill syscall - PID: 6029144, Signal: 62
I tried different approaches,
- I tried kretprobes, got the same result
- I tried to check the ax value to make sure it is the kill system call by checkint ax with
__NR_kill
it never got past the if condition.
long syscall_nr = regs->orig_ax;
// Check if it is the kill syscall (syscall number 62 on x86_64)
if (syscall_nr == __NR_kill) {
// NEVER GOT HERE
}
So I thought I ask for help here. I do not do this as part of a project, my goal is to learn kernel programming and linux kernel internals.
Thanks