内核查找符号指针函数kallsyms_lookup_name

测试环境:openEuler 22.03

架构:x86_64 

Linux内核原本提供了kallsyms_lookup_name用于获取未exported函数的指针位置,但是在Linux Kernel 5.7.0版本之后,kallsyms_lookup_name函数也没有export了,下面模块代码中提供了一种通过kprobe获得kallsyms_lookup_name函数起始地址的方式。

代码主要流程:

(1)调用register_kprobe获得kallsyms_lookup_name函数的地址指针kallsyms_lookup_name_func

(2)调用kallsyms_lookup_name_func获取其它未export的函数的地址指针(print_modules)

// allsyms_lookup_name_test

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kallsyms.h>
#include <linux/kprobes.h>

int noop_pre(struct kprobe *p, struct pt_regs *regs) { return 0; }

static struct kprobe kp = {   
	.symbol_name = "kallsyms_lookup_name",  
};

unsigned long (*kallsyms_lookup_name_fun)(const char *name) = NULL;

// 调用kprobe找到kallsyms_lookup_name的地址位置
int find_kallsyms_lookup_name(void)
{ 
	int ret = -1;
	kp.pre_handler = noop_pre;
	ret = register_kprobe(&kp);
    if (ret < 0) {  
	    printk(KERN_INFO "register_kprobe failed, error:%d\n", ret); 
        return ret; 
	}
	printk(KERN_INFO "kallsyms_lookup_name addr: %p\n", kp.addr); 
	kallsyms_lookup_name_fun = (void*)kp.addr; 
	unregister_kprobe(&kp);
	return ret;
}

static int __init kallsyms_lookup_name_test_init(void)
{
    int ret;
    ret = find_kallsyms_lookup_name();
    if (ret < 0) {
        printk(KERN_INFO "find kallsyms_lookup_name failed\n");
        return ret;
    }
    static typeof(&print_modules) print_modules_p;
    //调用kallsyms_lookup_name_fun指针找到print_modules函数起始地址位置
    print_modules_p = (typeof(&print_modules))kallsyms_lookup_name_fun("print_modules");
    //打印内核加载的模块
    print_modules_p();
    printk(KERN_INFO "print_modules_p: 0x%p", print_modules_p);
	
    return 0;
}

static void __exit kallsyms_lookup_name_test_exit(void) { return; }

module_init(kallsyms_lookup_name_test_init);
module_exit(kallsyms_lookup_name_test_exit);
MODULE_LICENSE("GPL");

Makefile如下:

obj-m+=kallsyms_lookup_name_test.o

all:
	make -C /lib/modules/$(shell uname -r)/build/ M=${PWD} modules
clean:
	make -C /lib/modules/$(shell uname -r)/build/ M=${PWD} clean

测试结果:

参考资料:

linux内核查找符号_wjx5210的博客-CSDN博客_linux 符号查找

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值