I tried to probe a simple function (e.g. myfunc) which I added in the kernel as following:
- I created a file (myfile.c) under
~/source/kernel/
i.e.~/source/kernel/myfile.c
- I added a simple system call
mysyscall
and a local functionmyfunc
in this file.mysyscall
function callsmyfunc
function.
I can get the address of the function using
cat /proc/kallsyms | grep myfunc
But the kprobe handler doesn't get called when I call the myfunc.
I can probe the system call 'mysyscall'. But when I try to probe 'myfunc', the handler doesn't get called.
Can anyone please explain why this is the behavior? Thanks.
As asked by Eugene, below is the code for kprobe and, mysyscall & myfunc. The kprobe handler doesn't get called in the following code. But if i uncomment Line B and comment A in kprobe code given below, then kprobe handler gets called.
I used kernel version 4.8. I added ~/source/kernel/myfile.c to write mysyscall and myfunc as given below:
#include <linux/linkage.h>
#include <linux/export.h>
#include <linux/time.h>
#include <asm/uaccess.h>
#include <linux/printk.h>
#include <linux/slab.h>
extern int myfunc(int ax)
{
int x = 6;
return x;
}
asmlinkage int* sys_mysyscall(int bx){
int *retval;
int ret = 0;
printk(KERN_ALERT "Hello World!\n");
ret = myfunc(10);
retval = kmalloc(sizeof(int), GFP_KERNEL);
*retval = 55;
printk("sum: %d\n", *retval);
printk("myfunc return value: %d\n", ret);
return retval;
}
EXPORT_SYMBOL(sys_mysyscall);
kprobe module code is as below:
#include<linux/module.h>
#include<linux/version.h>
#include<linux/kernel.h>
#include<linux/init.h>
#include<linux/kprobes.h>
//Line A
static const char *probed_func = "myfunc";
//Line B
//static const char *probed_func = "sys_mysyscall";
static unsigned int counter = 0;
int Pre_Handler(struct kprobe *p, struct pt_regs *regs){
printk("Pre_Handler: counter=%u\n",counter++);
return 0;
}
void Post_Handler(struct kprobe *p, struct pt_regs *regs, unsigned long flags){
printk("Post_Handler: counter=%u\n",counter++);
}
static struct kprobe kp;
int myinit(void)
{
int error;
printk("module inserted\n ");
kp.pre_handler = Pre_Handler;
kp.post_handler = Post_Handler;
kp.addr = (kprobe_opcode_t *)kallsyms_lookup_name(probed_func);
error = register_kprobe(&kp);
if(error)
{
pr_err("can't register_kprobe :(\n");
return error;
}
else
{
printk("probe registration successful\n");
}
return 0;
}
void myexit(void)
{
unregister_kprobe(&kp);
printk("module removed\n ");
}
module_init(myinit);
module_exit(myexit);
MODULE_AUTHOR("psin");
MODULE_DESCRIPTION("KPROBE MODULE");
MODULE_LICENSE("GPL");
I use a kernel module to call mysyscall as below:
sys_mysyscall(12);//12 is some random integer as parameter