在Linux可加载内核模块中探秘(9)
第二部分:趣味LKM
第三章:整蛊内核符号表
作者:CoolBoy
还记得第一部分第三章里面讲的内核符号表吧?整个系统中存在着的各种实体(无论是函数,变量,还是结构)都需要在内核符号表中去分配到一个固定的符号(也就是一个8位16进制数字),这样才好在内存中去表示它们。那么,既然这个文件是可见的(/proc/ksyms),甚至是可写的,我们的LKM又能通过这个文件做点什么呢?下面是一点点从笔者的/proc/ksyms中摘录的东西,大家可以从中看出有很多东西是十分有趣的。
...
001bf1dc ppp_register_compressor
001bf23c ppp_unregister_compressor
001e7a10 ppp_crc16_table
001b9cec slhc_init
001b9ebc slhc_free
001baa20 slhc_remember
......
00154e30 ip_masq_new
00154e64 ip_masq_set_expire
001ddf80 ip_masq_free_ports
001ddfdc ip_masq_expire
001548f0 ip_masq_out_get_2
001391e8 register_firewall
00139258 unregister_firewall
00139318 call_in_firewall
0013935c call_out_firewall
001392d4 call_fw_firewall
...
看到call_in_firewall了吗,不用说,大家都能猜到这是在内核中调用的管理防火墙的函数。如果我们将这个函数换成一个我们自己的,又会怎么样呢?
看看这个LKM:
#define MODULE
#define __KERNEL__
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
extern int *call_in_firewall;
int new_call_in_firewall()
{
return 0;
}
int init_module(void)
{
call_in_firewall=new_call_in_firewall;
return 0;
}
void cleanup_module(void)
{
}
编译后加载这个LKM,再运行一下“ipfwadm -I -a deny”。然后若是再“ping 127.0.0.1”,#&*%!,一个很漂亮的错误信息就会出现在你的眼帘啦——哈哈。因为防火墙管理函数已经被替换了。
其实,这样直接去改动内核输出符号是一种非常“不人道”的行为。若要想是利用这些技巧做点“好事”,比如为某个文件打打补丁什么的,就可以通过在反汇编的代码里去查找某些特定的内核符号(比如一个函数的符号),然后为这个函数加上补丁(比如函数有If..then..结构,就可以去查找相应的JNE、JE之类的指令 )。
下一章我们将学习如何利用LKM来改动Linux的文件系统。
发布人:Crystal 来自:Linux专区