哎呀,发现自己不会用模块的方式用kprobe啊,弱爆了
在内核外面编译模块,会报warning函数名undefined的错误,解决方法是把函数给export出来:EXPORT_SYMBOL
一直以来,用kprobe比较多的是kprobe event的用法,之前用过模块的方式编译过kprobe,但是感觉比较麻烦啊
今天要看看怎么用模块的方法简单编译kprobe:
如何单独编译内核模块
http://blog.sina.com.cn/s/blog_9011bd8c01015ms7.html
这个说得还是比较清楚,但是有几个东西还是不清楚呢,比如make设置了源码的目录,那么内核里面的数据结构他是怎么知道的呢?
1 obj-m := kprobe_example.o 2 obj-m += hello.o 3 CURRENT_PATH := $(shell pwd) 4 KERNEL_SRC :=/home/hon/f2fs 5 MAKE := /usr/bin/make 9 all: 10 $(MAKE) ARCH=arm64 CROSS_COMPILE=aarch64-buildroot-linux-gnu- -C $(KERNEL_SRC) M=$(CURRENT_PATH) modules 11 all: 12 clean: 13 rm *.ko
并且还有一个问题,我在一个.c文件中使用了f2fs的一个结构体 f2fs_sb_info,这个时候是要加头文件的
13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/kprobes.h>
20161203
习惯了qemu,就想着改变了。虚拟机当然好,整坏了也和主机无关,但是现在就想着在真实物理机上整,整坏了也不怕,这台机器就贡献出来折腾了了:
linux在/lib目录下提供了我们编译模块的环境,再也不用担心如何去下代码编模块了!
1 obj-m = main.o
2 KVER = $(shell uname -r)
3 CURRENT_PATH := $(shell pwd)
5
6 all:
7 make -C /lib/modules/$(KVER)/build M=$(CURRENT_PATH) modules
8 clean:
9 rm *.ko
但是我们似乎又发现一个问题,那就是我企图使用iterate_supers去检测系统中所有的super_block时,以探测f2fs全局管理结构f2fs_sb_info时发现:iterate_supers函数并没有export_symbols出来,所以要获取到iterate_supers的虚拟地址,我们直接调用它!
怎么通过函数名获得函数执行的地址呢?可以参考kprobe的实现啊,在kprobe中,也是通过函数名得到的函数虚拟地址,跟踪一下发现是用了函数:kallsyms_lookup_name。成功解析出了我Ubuntu上iterate_supers函数的地址。
我机器上iterate_supers函数的地址是:ffffffff812113f0;
其实得到这个sbi的方法有很多,包括使用kprobe打点也是一种方法,然后函数的第一个