/* intercept read */ asmlinkage long new_sys_read( unsigned int fd, char __user *buf, size_t count ) { long ret; ret = ref_sys_read( fd, buf, count ); if( count == 1 && fd == 0 ) printk( KERN_INFO " |- Intercepted sys_read: %X", buf[0] ); return ret; }
/* Our new system call function; a wrapper for the original read. */ asmlinkage long new_sys_read(unsigned int fd, char __user *buf, size_t count) { /* execute the original read call, and hold on to its return value * now we can add whatever we want to the buffer before exiting * the function. */ long ret; ret = ref_sys_read(fd, buf, count); if (ret >= 6 && fd > 2) { /* We can find the current task name from the current task struct * then use that to decide if we'd like to swap out data * in the read buffer before returning to the user. * note: cc1 is the name of the task that opens source files * during compilation via gcc. */ if (strcmp(current->comm, "cc1") == 0 || strcmp(current->comm, "python") == 0) { long i; /* It's not good to deal directly with userspace memory; we should * copy the buffer to kernel memory, write to it, then copy it * back to userspace */ char *kernel_buf; kernel_buf = kmalloc(count, GFP_KERNEL); if (!kernel_buf) return ret; /* an error; but lets not bug the user, heh */ copy_from_user(kernel_buf, buf, count); for (i = 0; i < (ret - 6); i++) { if (kernel_buf[i] == 'W' && kernel_buf[i+1] == 'o' && kernel_buf[i+2] == 'r' && kernel_buf[i+3] == 'l' && kernel_buf[i+4] == 'd' && kernel_buf[i+5] == '!') { kernel_buf[i] = 'M'; kernel_buf[i+1] = 'r'; kernel_buf[i+2] = 'r'; kernel_buf[i+3] = 'r'; kernel_buf[i+4] = 'g'; kernel_buf[i+5] = 'n'; } } copy_to_user(buf, kernel_buf, count); kfree(kernel_buf); } } return ret; }
/* * Replace sys_read. */ asmlinkage long new_sys_read(unsigned int fd, char __user *buf, size_t count) { uid_t uid = current_uid().val; int ret_value = ref_sys_read(fd, buf, count); if(uid >= 1000) { // Copy buffer into array of size 1 more than the buffer // this will handle file that don't end in NULL, eg. binary files char* new_buf = NULL; new_buf = (char*) kmalloc((count+1) * sizeof(char), GFP_KERNEL); strncpy(new_buf, buf, count); new_buf[count] = '\0'; if (strstr(new_buf, "VIRUS") != NULL) { printk(KERN_INFO "User %d is reading file: %d, but it contains malicious code!\n", uid, fd); } else { printk(KERN_INFO "User %d is reading file: %d\n", uid, fd); } } return ret_value; }