#include // Needed by all modules #include // KERN_INFO #include // for_each_process, pr_info #include #include #include // For proc filesystem #include #define MAX_REPORTLEN 4196 char* report; size_t report_place = 0; ssize_t return_report(struct file *filp, char *buf, size_t count, loff_t *offp ) { char* readspot = report + *offp; size_t readlen = report_place > count? count:report_place; if(*offp >= strlen(report)) return 0; strncpy(buf, readspot, readlen); *offp += readlen; return readlen; } void add_to_report(const char* fmt, ...){ va_list args; va_start(args, fmt); report_place += vsnprintf(report + report_place, MAX_REPORTLEN - report_place, fmt, args); } void get_process_info(pid_t target_pid) { struct task_struct* task_list; report_place = 0; add_to_report("Looking for info on process with pid %d\n", target_pid); for_each_process(task_list) if(task_list->pid == target_pid) { add_to_report("Found our process, comm = %s\n", task_list->comm); add_to_report("recent_used_cpu = %d\n", task_list->recent_used_cpu); } } // Code 1 indicates a process info lookup // Argument for code 1 is the pid long handle_ioctl(struct file*, unsigned int a, unsigned long b) { if(a == 10) get_process_info(b); else printk("Invalid ioctl %d\n", a); return 0; } struct proc_ops proc_fops = { proc_read: return_report, proc_ioctl: handle_ioctl }; int init_module(void) { report = kmalloc(MAX_REPORTLEN, GFP_KERNEL); proc_create("process_info", 0, NULL, &proc_fops); return 0; } void cleanup_module(void) { kfree(report); remove_proc_entry("process_info", NULL); } MODULE_LICENSE("MIT");