当前位置:Linux教程 - Linux - 在Linux可加载内核模块中探秘(9)

在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专区