如何在64位ubuntu中截获内核模块的导出函数?
我想在64位ubuntu中截获内核模块的导出函数,求思路,最好是代码 回复 1# leishaoweiwu首先这ubuntu, 没什么关系.
模块的通过__EXPORT_SYMBOL把符号导出到
__attribute__((section("__ksymtab_strings")
如果你只是想将模块文件中的导出函数"截获", 以auth_rpcgss为例
/lib/modules/3.19.5-200.fc21.x86_64/kernel/net/sunrpc/auth_gss/auth_rpcgss.ko.xzreadelf-s auth_rpcgss.ko | grep __ksymtab_
220: 0000000000000020 16 OBJECTGLOBAL DEFAULT 10 __ksymtab_gss_pseudoflavo
238: 0000000000000020 16 OBJECTGLOBAL DEFAULT 12 __ksymtab_g_verify_token_
247: 0000000000000010 16 OBJECTGLOBAL DEFAULT 10 __ksymtab_gss_mech_put
288: 0000000000000030 16 OBJECTGLOBAL DEFAULT 12 __ksymtab_gss_mech_regist
303: 0000000000000000 16 OBJECTGLOBAL DEFAULT 10 __ksymtab_gss_mech_get
365: 0000000000000010 16 OBJECTGLOBAL DEFAULT 12 __ksymtab_g_token_size
366: 0000000000000000 16 OBJECTGLOBAL DEFAULT 12 __ksymtab_g_make_token_he
367: 0000000000000040 16 OBJECTGLOBAL DEFAULT 12 __ksymtab_gss_mech_unregi
379: 0000000000000050 16 OBJECTGLOBAL DEFAULT 12 __ksymtab_svcauth_gss_fla
383: 0000000000000060 16 OBJECTGLOBAL DEFAULT 12 __ksymtab_svcauth_gss_regor 这么做readelf -p __ksymtab_strings auth_rpcgss.ko
String dump of section '__ksymtab_strings':
[ 0]g_verify_token_header
[ 16]g_make_token_header
[ 2a]g_token_size
[ 37]gss_mech_put
[ 44]gss_pseudoflavor_to_service
[ 60]gss_mech_get
[ 6d]gss_mech_unregister
[ 81]gss_mech_register
[ 93]svcauth_gss_register_pseudoflavor
[ b5]svcauth_gss_flavor我觉得这应该不是你的需求, 你或许是在运行的内核中动态的检测截获加载的内核的符号导出表.
简单看了下load module的代码
你可以注册一个module 通知链
register_module_notifier
这个notifier block会在do_init_module调用, 正好是模块加载最后一步执行.
struct module的成员
const struct kernel_symbol *syms;正好指向__ksymtab这个section
你试着看看应该能找到所有export的代码
个人见解.
学习了,不过楼主这是要解决什么问题呢?安全问题? 谢谢您,我是想在64位的ubuntu中hook某个函数,比如说钩住usb_submit_urb这个函数,在执行这个函数之前先截获这个函数所提交的urb信息,再和我的白名单中的策略作对比,要是符合的话,就允许相应的外设访问,否则就禁止。32位ubuntu下的我已经实现了,现在在64位下研究,想在64位下找到相应的hook函数,或者还有没有其他的方法?回复 2# firocu
在64位的ubuntu中hook某个函数,比如说钩住usb_submit_urb这个函数,在执行这个函数之前先截获这个函数所提交的urb信息,再和我的白名单中的策略作对比,要是符合的话,就允许相应的外设访问,否则就禁止。回复 3# nswcfd
请问有什么好的思路吗?回复 5# leishaoweiwu
不好意思,不明白为什么32位跟64位有区别?跟hook机制有关系吗?
如果性能不是特别concern的话,可以使用kprobe/jprobe/kretprobe之类的。
* jprobe可以查看入口的参数值,但是怎么影响原始的控制流还有待研究(比如修改urb的某个字段为非法值?)。
* kretprobe在函数返回的时候起作用,作为访问控制的时机有些晚。
* 最强大的是kprobe,不过这就跟反汇编紧密的耦合起来,受版本变化影响。
还有一种方法,就是在你的访问控制模块里面,重新实现一遍usb_submit_urb函数,在入口的时候加上访问控制的代码。此外,把原始的usb_submit_urb的入口替换为一个jmp命令。
PS,如果允许重新编译vmlinx的话,就在usb_submit_urb的入口处插入一个callback(函数指针),导出这个符号。在访问控制模块中实现callback,注册函数指针。 恩,我在32位ubuntu中就是用第二种方法的,在原始的usb_submit_urb的入口替换为一个jmp命令,执行usb_submit_urb之前跳转到访问控制函数,然后再执行执行usb_submit_urb。已经能够成功实现,我现在想在64位ubuntu中用类似的思路实现,可是有问题,在32位ubuntu中要想hook函数必须将CPU寄存器CR0的写保护位置为0,我现在的不知道是不是64位ubuntu下只有把CPU寄存器CR0的写保护位置0才能hook函数?回复 7# nswcfd
不好意思,不太了解这个细节。最好参阅一下intel的cpu手册。
不过跟踪register_kprobe的反汇编,没有发现mov %cr0……
不管需不需要,先尝试一下呗,大不了crash一下,:p
页:
[1]