# 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
```