# 2021q3 Homework1 (quiz1) contributed by <`ian910297`> ###### tags: `linux-kernel-2021` 實驗環境 * AMD Ryzen 9 3900X 12-Core Processor * Linux demonic-System-Product-Name 5.4.0-81-generic #91~18.04.1-Ubuntu SMP Fri Jul 23 13:36:29 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux ## 延伸 1. 解釋上述程式碼運作原理,包含 [ftrace](https://www.kernel.org/doc/Documentation/trace/ftrace.txt) 的使用 :::info 參考資料 * [Using ftrace to hook to functions](https://www.kernel.org/doc/html/v4.17/trace/ftrace-uses.html) * [在 RISC-V 上的 ftrace 及 perf 工具移植經驗 - Alan Kao/高魁良](https://hackmd.io/c/coscup18-kernel/%2Fcoscup18-kernel-risc-v-ftrace-perf?fbclid=IwAR322YhRGPyplDksNsIZNZa0FgnznHO8INxl7rT1_OZQmVtPdzqSFyoy3co) ::: * 使用 list_for_each_entry_safe 系列的巨集來操作 Linked List,這是 Linux Kernel 中常用的手法, * atomic operation * 透過 `container_of` 這個巨集,讓我們可以不管你是什麼樣的 structure 都可 * 這程式的目的是,隱藏 PID,那他是怎麼實現這個功能的? * 所有要被 hide 的 process,都丟到 hidden_proc 這個 linked list 進行儲存 * 透過 ftrace 來實現隱藏,因為 ftrace 會去綁架我們指定的 function `find_ge_pid`,可以在進入的時候去呼叫我們指定的 callback `hook_find_ge_pid`,而這個 function 就是拿來判斷拿 PID 用的......,已經被改成要去 check 我們的 linked list,來決定要不要跟他講答案 ## 延伸 3. 本核心模組只能隱藏單一 PID,請擴充為允許其 PPID 也跟著隱藏,或允許給定一組 PID 列表,而非僅有單一 PID (Ongoing) * PPID 也跟著隱藏 * 了解如何從 PID 拿到 PPID * 使用 ftrace 綁架 get PPID 的 function * 允許給定 PID 列表 * 用 space 做分隔,允許同時輸入多個 PID ```clike static ssize_t device_write(struct file *filep, const char *buffer, size_t len, loff_t *offset) { long pid; char *message; char *start; char *end; char buf[10]; char add_message[] = "add", del_message[] = "del"; if (len < sizeof(add_message) - 1 && len < sizeof(del_message) - 1) return -EAGAIN; message = kmalloc(len + 1, GFP_KERNEL); memset(message, 0, len + 1); copy_from_user(message, buffer, len); if (!memcmp(message, add_message, sizeof(add_message) - 1)) { start = message + sizeof(add_message); while (1) { for (; *start == ' ' && *start != '\0'; start++ ) { // remove space at head } memset(buf, '\0', 10); end = strchr(start + 1, ' '); if (end==NULL) { kstrtol(start, 10, &pid); hide_process(pid); break; } else { memcpy(buf, start, sizeof(start) - sizeof(end)); kstrtol(start, 10, &pid); hide_process(pid); } start = end; } } else if (!memcmp(message, del_message, sizeof(del_message) - 1)) { start = message + sizeof(del_message); while (1) { for (; *start == ' ' && *start != '\0'; start++ ) { // remove space at head } memset(buf, '\0', 10); end = strchr(start + 1, ' '); if (end==NULL) { kstrtol(start, 10, &pid); unhide_process(pid); break; } else { memcpy(buf, start, sizeof(start) - sizeof(end)); kstrtol(start, 10, &pid); unhide_process(pid); } start = end; } } else { kfree(message); return -EAGAIN; } *offset = len; kfree(message); return len; } ``` ## 延伸 4. 指出程式碼可改進的地方,並動手實作 ```clike ```