一、前言
OS是软硬件之前的桥梁:操作系统管理硬件,最终以服务的形式提供给用户。如用户读取磁盘数据,OS设备管理将读出来的数据通过文件系统交给用户。OS管理员对CPU(进程)管理,对内存管理,对设备管理,对文件管理。
操作系统接口标准遵从POSIX标准,potable operating System interface of UNIX。
操作系统接口类型:图形接口(GUI)、命令行(shell)、编程接口(应用程序)
一次系统调用:用户态陷入到内核态,内核执行系统调用服务例程,处理结束后返回用户态。
DOS如何系统调用:DOS提供一组实现特殊功能的子程序,大概50多个,供编程人员使用减轻编程工作量。包括管理磁盘文件,负责磁盘空间分配,DOS与外层模块联系等
二、系统调用机制
LInux接口分为用户接口(图形),库函数接口,系统调用接口,再往下层是内核态。
系统调用是与具体的操作系统相关的,API遵循POSIX标准,API有的需要系统调用,有的不需要如strcpy。系统调用可以看做是内核与用户空间进行交互的接口。
查看 各个子系统相关的工具集,跟踪进程所调用的系统,通过strace命令查看一个应用程序所调用的系统调用,它是Linux下的程序调试工具,可以统计每一个系统调用执行的时间,被调用的次数和出错的次数。
strace -c 可执行文件名
从用户态到系统调用:fwrite -> 库glibc调用系统调用write->用户态陷入内核态,查找系统调用表系统服务例程sys_write
系统调用号:唯一标识系统调用
系统调用表:把系统调用号与系统服务例程关联起来
系统调用处理过程描述:触发系统调用时首先保护现场,4 x eax表示每个表项占4个字节。在系统调用表sys_call_table中找到入口地址,跳转到相应的服务程序。
fork(用来创建进程)调用例子:
系统调用机制的优化,引入Vsyscalls vDSO机制,使用软中断进行系统调用
Linux内核5X大约有380个系统调用,库函数大约2000多个。
三、系统调用实例
下面是系统调用日志收集系统:
该内容包括系统调用、工作队列、修改内核、内核编译,内核模块编写和插入。
uname -a 查看系统内核版本信息
1)打开系统系统调用表表项文件,增加系统调用表表项
目录arch/x86/entry/syscalls/syscall_64.tbl
添加335号系统调用,格式不变:系统调用号,common, 函数名,入口点
Linux系统调用表(system call table)_rtoax的博客-CSDN博客_linux 系统调用表
2)添加系统调用函数
Sudo vim arch/x86/kernel/myaudit.c
3)修改makefile文件,把myaudit.c添加到内核编译中
Sudo vim arch/x86/kernel/Makefile,添加obj-y += myaudit.o
4)增加函数声明
sudo vim include/Linux/syscalls.h,在endif之前添加函数声明
5) 拦截相关系统调用
sudo vim arch /x86/entry /common.c
找到do_syscall_64系统调用函数,加入对系统调用号nr处理
2号open
3号close
39号get_pid
56号clone
57号fork
59号exit
编译内核:
查看内核版本号:uname -r
sudo make menuconfig //加载内核5.0 .config文件 load , 保存ok,退出exit
sudo make olddefconfig
编译内核:sudo make bzImage -j2
6)安装内核,修改内核引导
sudo make modules_install
sudo make install
sudo update -grub2
sudo reboot 重启系统,系统切换为5.0
7)添加实现钩子函数的内核模块
打开 my_audit.c
syscall_audit实现了把拦截的系统调用参数赋值给结构体buff
sys_audit 实现了把内核的buff拿到用户buffer 中
把myaudit.c编译为内核模块Makefile
插入内核模块:sudo insmod my_audit.ko
查看日志:sudo dmesg
编写用户态测试程序