调用kprobe机制去获取kallsyms_lookup_name函数地址,再通过函数指针获取系统调用表地址
static int handler_pre(struct kprobe *p, struct pt_regs *regs){
return 0;}
static struct kprobe kp = {
.symbol_name = "kallsyms_lookup_name",
};
// 函数定义
typedef unsigned long (*kallsyms_lookup_name_t)(const char *name);
static kallsyms_lookup_name_t fn_kallsyms_lookup_name = 0;
int __get_kallsyms_lookup_name(void)
{
int ret = -1;
kp.pre_handler = handler_pre;
// register_kprobe成功返回0
ret = register_kprobe(&kp);
if (ret < 0) {
printk(KERN_INFO "register_kprobe failed, returned %d\n", ret);
return ret;
}
printk(KERN_INFO "Planted kprobe at %p\n", kp.addr);
fn_kallsyms_lookup_name = (kallsyms_lookup_name_t)(void*)kp.addr;
unregister_kprobe(&kp);
return ret;
}
syscall_t* _get_sys_call_table_by_kallsyms2(void)
{
unsigned long addr;
// 1. 获取kallsyms_lookup_name函数指针
get_kallsyms_lookup_name() ;
// 2. 使用kallsyms_lookup_name()获取系统调用表地址
addr = fn_kallsyms_lookup_name("sys_call_table");
return (syscall_t*)addr;
}