zoukankan      html  css  js  c++  java
  • 添加linux系统调用的两种方式

    原文:https://blog.csdn.net/sdulibh/article/details/51889279

    向linux内核添加系统调用,一是通过编译内核添加,二是通过内核模块的方式添加:

    一:编译内核

    第一步,下载内核版本。(我用的是2.6.39.2)
                   然后在指定的目录下解压。
    -------------------------------------------------------------------------------------
    第二步,在arch/x86/include/asm/unistd_32.h
    文件中添加系统调用号。
    -------------------------------------------------------------------------------------
    第三步,在arch/x86/kernel/syscall_table.s
    文件中添加相应的表项。
    -------------------------------------------------------------------------------------
    第四步:实现系统调用的服务历程。
     理论上,这个函数的位置没有固定,最好加在arch/x86/kernel/目录
    下的文件里面。我这次是加在arch/x86/kernel/sys_i386_32.c文件中
    -------------------------------------------------------------------------------------
    第五步:重新编译内核。
    5.1,内核使用默认的配置,make menuconfig直接选择exit退出
    5.2,使用如下命令编译内核
    -------------------------------------------------------------------------------------
    第六步:用户态测试系统调用。(注意内核安装好后,重启后选择新的内核)
    运行结果:
    -------------------------------------------------------------------------------------

    二: 使用内核模块方式添加简单系统调用 

    1,为什么要使用内核模块的方式添加系统调用?

        1.1,编译内核的方式费时间,一般的PC机都要两三个小时。
        1.2,不方便调试,一旦出现问题前面的工作都前功尽弃。
    -------------------------------------------------------
    2,首先要获取系统调用表sys_call_table的地址(虚拟地址)
       因为sys_call_table在内核中没有导出,可以使用如下命令查看。
     
    1. cat /proc/kallsyms | grep sys_call_tables
    注意点:当我把模块在一个机子上运行成功后,如果移植到另外一个机子上马上就会出现
            错误,为什么呢?因为每个机子上sys_call_table的地址可能不一样。
    -------------------------------------------------------
    3,需要查看预留的系统调用号。
      可以到arch/x86/include/asm/unistd.h文件中查看预留的系统调用号。
    可以看出223就是一个预留的系统调用号。
    -------------------------------------------------------
    4,实例:

    1. #include <linux/init.h>
    2. #include <linux/module.h>
    3. #include <linux/kernel.h>
    4. #include <linux/unistd.h>
    5. #include <asm/uaccess.h>
    6. #include <linux/sched.h>
    7. #define my_syscall_num 223
    8. //如下的这个值要到你机子上查。cat /proc/kallsyms | grep sys_call_table
    9. #define sys_call_table_adress 0xc1511160
    10. unsigned int clear_and_return_cr0(void);
    11. void setback_cr0(unsigned int val);
    12. asmlinkage long sys_mycall(void);
    13. int orig_cr0;
    14. unsigned long *sys_call_table = 0;
    15. static int (*anything_saved)(void);
    16. unsigned int clear_and_return_cr0(void)
    17. {
    18.  unsigned int cr0 = 0;
    19.  unsigned int ret;
    20.  asm("movl %%cr0, %%eax":"=a"(cr0));
    21.  ret = cr0;
    22.  cr0 &= 0xfffeffff;
    23.  asm("movl %%eax, %%cr0"::"a"(cr0));
    24.  return ret;
    25. }
    26. void setback_cr0(unsigned int val) //读取val的值到eax寄存器,再将eax寄存器的值放入cr0中
    27. {
    28.  asm volatile("movl %%eax, %%cr0"::"a"(val));
    29. }
    30. static int __init init_addsyscall(void)
    31. {
    32.  printk("hello, kernel ");
    33.  sys_call_table = (unsigned long *)sys_call_table_adress;//获取系统调用服务首地址
    34.  anything_saved = (int(*)(void)) (sys_call_table[my_syscall_num]);//保存原始系统调用的地址
    35.  orig_cr0 = clear_and_return_cr0();//设置cr0可更改
    36.  sys_call_table[my_syscall_num] = (unsigned long)&sys_mycall;//更改原始的系统调用服务地址
    37.  setback_cr0(orig_cr0);//设置为原始的只读cr0
    38.  return 0;
    39. }
    40. asmlinkage long sys_mycall(void)
    41. {
    42.  printk("This is my_syscall! ");
    43.  return current->pid;
    44. }
    45. static void __exit exit_addsyscall(void)
    46. {
    47.  //设置cr0中对sys_call_table的更改权限。
    48.  orig_cr0 = clear_and_return_cr0();//设置cr0可更改
    49.  //恢复原有的中断向量表中的函数指针的值。
    50.  sys_call_table[my_syscall_num] = (unsigned long)anything_saved;
    51.  
    52.  //恢复原有的cr0的值
    53.  setback_cr0(orig_cr0);
    54.  printk("call exit ");
    55. }
    56. module_init(init_addsyscall);
    57. module_exit(exit_addsyscall);
    58. MODULE_LICENSE("GPL");
    -------------------------------------------------------
    5,将模块插入成功后,剩下的就是在用户态下测试是否成功了。
  • 相关阅读:
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第50章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第49章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第48章 读书笔记(待更新)
    Spring Boot 中使用 Quartz 实现任务调度
    实战 FastDFS Java 客户端上传文件
    分布式文件系统之 FastDFS
    Java 持久层框架之 MyBatis
    C语言实现贪吃蛇
    [转载]分享三篇非常好的学习心得
    selenium加载cookie报错问题:selenium.common.exceptions.InvalidCookieDomainException: Message: invalid cookie domain
  • 原文地址:https://www.cnblogs.com/wangliangblog/p/9234463.html
Copyright © 2011-2022 走看看