Chinaunix首页 | 论坛 | 博客
  • 博客访问: 562087
  • 博文数量: 61
  • 博客积分: 2438
  • 博客等级: 大尉
  • 技术积分: 871
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-28 08:04
文章分类
文章存档

2013年(1)

2012年(8)

2011年(15)

2010年(37)

分类: LINUX

2012-07-23 11:30:09

在一当中主要是对内核修改的部分做了介绍,我们接着介绍:
在myaudit.c文件中有两个函数指针,下来介绍实现。

点击(此处)折叠或打开

  1. #include <linux/module.h>
  2. #include <linux/init.h>
  3. #include <linux/kernel.h>
  4. #include <linux/types.h>
  5. #include <asm/current.h>
  6. #include <linux/sched.h>
  7. #include <asm/uaccess.h>

  8. #define COMM_SIZE 16

  9. struct syscall_buf {
  10.     u32 serial;
  11.     u32 ts_sec;
  12.     u32 syscall;
  13.     u32 status;
  14.     pid_t pid;
  15.     uid_t uid;
  16.     u8 comm[COMM_SIZE];
  17. };

  18. //初始化一个队列buffer_wait
  19. DECLARE_WAIT_QUEUE_HEAD(buffer_wait);

  20. #define AUDIT_BUF_SIZE 100
  21. //长度为100的缓冲区。
  22. static struct syscall_buf audit_buf[AUDIT_BUF_SIZE];
  23. static int current_pos = 0;//缓冲区中的位置.
  24. static u32 serial = 0;//序列号

  25. void write_buf_audit(int syscall,int return_value)
  26. {
  27.     struct syscall_buf *ppb_tmp;
  28.     printk("write_buf_audit is execing!\n");
  29.     if (current_pos < AUDIT_BUF_SIZE) {
  30.         ppb_tmp = &audit_buf[current_pos];
  31.         ppb_tmp->serial = serial++;
  32.         ppb_tmp->ts_sec = 1;
  33.         ppb_tmp->syscall = syscall;
  34.         ppb_tmp->status = return_value;
  35.         ppb_tmp->pid = current->pid;
  36.         ppb_tmp->uid = current->tgid;
  37.         memcpy(ppb_tmp->comm,current->comm,COMM_SIZE);

  38.         if (++current_pos == AUDIT_BUF_SIZE *1/10) {
  39.          printk("in syscall_audit,it near full!\n");
  40.                 wake_up_interruptible(&buffer_wait);
  41.         }
  42.     }
  43.     return ;
  44. }

  45. int read_buf_audit(u8 type,u8 *us_buf,u16 us_buf_size,u8 reset)
  46. {
  47.     int ret = 0;
  48.     printk("read_buf_audit is execving!\n");
  49.     if (!type) {
  50.         if (clear_user((void *)us_buf, (unsigned long)us_buf_size)) {
  51.             printk("error:clear_user!\n");
  52.             return 0;
  53.         }
  54.         ret= wait_event_interruptible(buffer_wait,current_pos >= AUDIT_BUF_SIZE*1/10);
  55.         if (copy_to_user((void *)us_buf,audit_buf,(current_pos)*sizeof(struct syscall_buf))) {
  56.             printk("error:copy error!\n");
  57.             return 0;
  58.         }
  59.         ret = current_pos;
  60.         current_pos = 0;
  61.     }
  62.     return ret;
  63. }

  64. static int __init audit_init(void)
  65. {
  66.     my_audit = write_buf_audit;
  67.     my_sysaudit = read_buf_audit;
  68.     printk("starting syscall audit!\n");
  69.     return 0;
  70. }

  71. static void __exit audit_exit(void)
  72. {
  73.     my_audit = NULL;
  74.     my_sysaudit = NULL;
  75.     printk("exiting syscall audit!\n");
  76.     return ;
  77. }

  78. module_init(audit_init);
  79. module_exit(audit_exit);
  80. MODULE_LICENSE("GPL");
这个是总控程序,用来从内核收集信息,并写到用户BUF中。
Makefile:

点击(此处)折叠或打开

  1. obj-m := mod.o
  2. Kernel_path=/home/linux/kernel/linux-2.6.36  #这个是我重新编译内核后的路径
  3. all:
  4.     make -C $(Kernel_path) M=$(PWD) modules
  5. clean:
  6.     make -C $(Kernel_path) M=$(PWD) clean
然后插入模块就ok了。

用户态监控/显示程序:

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <errno.h>
  4. #include <signal.h>
  5. #include <unistd.h>
  6. #include <sys/syscall.h>
  7. #include <sys/types.h>

  8. typedef unsigned char u8;
  9. typedef unsigned int u32;

  10. #define COMM_SIZE 16

  11. struct syscall_buf {
  12.     u32 serial;
  13.     u32 ts_sec;
  14.     u32 syscall;
  15.     u32 status;
  16.     pid_t pid;
  17.     uid_t uid;
  18.     u8 comm[COMM_SIZE];
  19. };

  20. #define AUDIT_BUF_SIZE 100*sizeof(struct syscall_buf)

  21. int main(int argc, char *argv[])
  22. {
  23.     u8 col_buf[AUDIT_BUF_SIZE];
  24.     unsigned char reset = 1;
  25.     int num = 0;
  26.     struct syscall_buf *p = NULL;
  27.     u8 j = 0;
  28.     int i;

  29.     while (1) {
  30.         num = syscall(__NR_myaudit, 0, col_buf, AUDIT_BUF_SIZE, reset);
  31.         printf("num is: %d\n", num);
  32.         p = (struct syscall_buf *)col_buf;
  33.         for (i = 0; i < num; i++) {
  34.             printf("serial: %d ", p[i].serial);
  35.             printf("syscall: %d ", p[i].syscall);
  36.             printf("ts_sec: %d ", ((struct syscall_buf *)col_buf)[i].ts_sec);
  37.             printf("status: %d ", p[i].status);
  38.             printf("pid: %d ", ((struct syscall_buf *)col_buf)[i].pid);
  39.             printf("uid: %d ", ((struct syscall_buf *)col_buf)[i].uid);
  40.             printf("comm: %s\n", ((struct syscall_buf *)col_buf)[i].comm);
  41.         }
  42.     }

  43.     return 0;
  44. }
将收集到的信息显示出来。

触发程序:

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include
  4. #include <sys/sysinfo.h>

  5. int main()
  6. {
  7.     int ret, i;
  8.     pid_t pid;
  9.     struct sysinfo info;
  10.     for (i = 100; i >= 0; i--) {
  11.         ret = sysinfo(&info);
  12.         pid = getpid();
  13.     }

  14.     exit(1);
  15. }

该程序的运行过程:
1、先将模块程序插入内核,属于内核态下的监控程序。
2、运行用户态下的监控程序,该程序会向系统发出系统调用,如果内核态下的满足条件,则这边会显示。
3、运行触发程序。

小结:该程序(系统调用日志收集系统)主要是从内核态下监控系统,防止一些用户非法的申请资源,从而达到对系统安全维护的一种措施。该程序还有许多要扩充的地方,例如,用户态下的监控程序可以做成一个守护进程,可以对非法用户采取一定的措施。
阅读(2598) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~