Skip to content

Latest commit

 

History

History
25 lines (20 loc) · 1.87 KB

定位linux内核函数地址.md

File metadata and controls

25 lines (20 loc) · 1.87 KB

hook技术就是针对函数的操纵,那么指定函数的获取则必然是需要的,除了operations这种内核函数指针获取函数的方式,2.6版本后引入了导出符号的机制。而内核函数也分为导出和非导出,也就是只有在内核中使用了EXPORT_SYMBOL或者EXPORT_SYMBOL_GPL导出的符号才能在内核模块中直接使用。

不管是导出的还是未导出的,可以通过这些方法来获取到指定函数的地址或者指定地址的函数

通过内核符号名取符号地址

kallsyms_lookup_name,这本身也是一个内核符号因此只有在导出后才能被使用,只有在编译内核时启用CONFIG_KALLSYMS编译内核才行,而且获取到的是内核中的虚拟地址。

通过符号地址取符号名

sprint_symbol根据内存地址获取到内核符号存入buffer,本身呢返回是一个int,所查找的内核符号可以是本就存在于内核中的符号,也可以是位于动态插入的模块中的符号。

通用方式

  • System.map中直接获取到对应信息
$ cat /usr/src/linux-4.18.16.arch1/System.map | grep proc_pid_readdir
ffffffff812e3c50 T proc_pid_readdir

这是在编译内核时产生的文件,记录了编译时候内核符号的地址,但是问题就是这种方法对于运行时动态插入的内核模块并不支持,而且文件本身必须与当前内核对应。

  • /proc/kallsyms 文件中获取信息 这也是一个虚拟文件,在读取时由内核动态生成内容,因此地址一定是正确的,但是2.6.37以后普通用户无法读到符号地址,但是据说内核符号数量上少于System.map

  • vmlinuz

$ nnm vmlinux|grep proc_root_readdir

不过这个我在我的发行版系统上使用并没有输出内核符号,应该还是内核编译的问题,而且是静态的地址,所以不推荐此方式