Chinaunix首页 | 论坛 | 博客
  • 博客访问: 914820
  • 博文数量: 119
  • 博客积分: 2493
  • 博客等级: 大尉
  • 技术积分: 2363
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-03 14:00
文章分类

全部博文(119)

文章存档

2013年(19)

2012年(100)

分类: LINUX

2012-07-17 20:39:25

接系统调用日志收集系统 (1)
---------------------------------------------------------------
3.8重新编译内核。
     如何编译内核就不再说了。
----------------------------------------------------------------
3.9插入模块。

  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");
------------------------------------------------------------------------------------------------------
3.10,启动用户测试程序。
 
  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(346, 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.         putchar('\n');
  43.     }

  44.     return 0;
  45. }
--------------------------------------------------------------------------------------------------------
3.11,其中用户触发程序。(向内核不断地申请系统调用)

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

  4. int main(void)
  5. {
  6.     struct sysinfo info;
  7.     unsigned long value = 0;
  8.     int i = 0;

  9.     while (1) {
  10.     sysinfo(&info);
  11.     printf("sysinfo is execving!\n");
  12.     value = (unsigned long)getpid();
  13.     printf("pid = %lu\n",value);
  14.     sleep(1);
  15.     }
  16.     return 0;
  17. }
----------------------------------------------------------------------------------------------------------------
感想:
          经过几天的时间调试这个程序,最终还是调试通过了,收获还是蛮大的,这个程序中
既要内核编程,还有编写内核模块,还要编写用户态程序。内核态和用户态协调合作。当然
在其中也出现了不少问题,开始我们就没有考虑到sysenter,结果导致使用库函数,对内核
就没有触发,只能使用int 0x80,直接在用户态使用汇编或嵌入汇编才能对其触发。后来把
sysenter这条路“堵死”就好了。
------------------------------------------------------------------------------------------------------------------




阅读(2503) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~