0

我试图探测我在内核中添加的一个简单函数(例如 myfunc),如下所示:

  1. ~/source/kernel/我在ie下创建了一个文件(myfile.c)~/source/kernel/myfile.c
  2. 我在这个文件中 添加了一个简单的系统调用mysyscall和一个本地函数。函数调用函数。myfuncmysyscallmyfunc

我可以使用获取函数的地址

cat /proc/kallsyms | grep myfunc

但是当我调用 myfunc 时不会调用 kprobe 处理程序。

我可以探测系统调用“mysyscall”。但是当我尝试探测“myfunc”时,处理程序不会被调用。

谁能解释为什么这是这种行为?谢谢。

正如 Eugene 所问,下面是 kprobe 和 mysyscall 和 myfunc 的代码。在以下代码中未调用 kprobe 处理程序。但是,如果我在下面给出的 kprobe 代码中取消注释 B 行并注释 A,则调用 kprobe 处理程序。

我使用的是内核版本 4.8。我添加了 ~/source/kernel/myfile.c 来编写 mysyscall 和 myfunc ,如下所示:

#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 模块代码如下:

#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");

我使用内核模块调用 mysyscall,如下所示:

sys_mysyscall(12);//12 is some random integer as parameter
4

0 回答 0