本文内容主要转载自获得内核函数地址的四种方法

本文以获取内核函数vfs_read()的地址为例。

1. 从 System.map 文件中直接得到地址

内核镜像的System.map文件存储了内核符号表的信息, 可以通过此文件获取到具体的信息。

查看内核函数的地址:

1
sudo grep vfs_read /boot/System.map-`uname -r`

2. 从 /proc/kallsyms 文件获得地址

1
cat /proc/kallsyms | grep vfs_read

For more details, please man nm:

3. 使用内核函数接口

3.1 已知内核符号,获取内核符号地址

使用 kallsyms_lookup_name()

该函数在 kernel/kallsyms.c 文件中定义的, 要使用它必须启用 CONFIG_KALLSYMS 编译内核.

kallsyms_lookup_name() 接受一个字符串格式内核函数名, 返回那个内核函数的地址.

1
kallsyms_lookup_name("函数名");

3.2 已知内核符号地址, 获取内核符号名

使用 sprint_symbol 内核函数。

1
2
3
#include <linux/kallsyms.h>

int sprint_symbol(char *buffer, unsigned long address)

该函数根据一个内存中的地址 address 查找一个内核符号, 并将该符号的基本信息, 如符号名 name, 它在内核符号表中的偏移 offset 和大小 size, 所属的模块名(如果有的话)等信息连接成字符串赋值给文本缓冲区 buffer. 其中所查找的内核符号可以是原本就存在于内核中的符号, 也可以是位于动态插入的模块中的符号.


参考资料:

  1. 获得内核函数地址的四种方法
  2. 如何使用Linux内核中没有被导出的变量或函数
  3. LINUX使用内核模块添加系统调用的方法(无需编译内核)
  4. linux内核符号表kallsyms简介
  5. What is the difference between T and t in /proc/kallsyms