# 2021q3 Homework1 (lab0) contributed by <mickey30606> ## 降版本 依照 [Ubuntu Kernel 降版 - MIS-Chuck隨手筆記](https://mis-chuck.blogspot.com/2017/10/ubuntu-kernel.html) 教學。 1. 更新資料,並尋找可以安裝的版本。 ```cpp $ sudo apt-get update $ sudo apt-cache search linux-image ``` 2. 安裝所需版本及其 header 。(我安裝的是 linux 5.6-1056-oem) ```cpp $ sudo apt-get install linux-image-5.6-1056-oem $ sudo apt-get install linux-headers-5.6-1056-oem ``` 3. 更新開機系統 ```cpp $ sudo update-initramfs -u -k all $ sudo update-grub ``` 完成後重新開機,在開機選單中可以選擇 linux 的版本。 ## 運作原理 這個 module 分成 ftrace hook 和 hide process 兩個部份。 首先先看 hide process ,在 ```$ echo "add 725" | sudo tee /dev/hideproc``` 之後,會呼叫到 ```hide_proc()``` 把 725 新增到 ```hidden_proc``` 這個 linked list 裡面。而如果是 ```$ echo "add 725" | sudo tee /dev/hideproc``` 應該是要把 725 從 linked list 中刪除(這邊需要修復)。 再來是 ftrace hook , ftrace 可以追蹤幾乎每一個 kernel 中的 function ,在進入 function 之前會多加一個 mcount 的標籤,進入 ftrace function 進行追蹤,所以如果我們在 ftrace function 改變原本要去的 function address 的話,就可以換成執行別的 function 。 ```cpp static void notrace hook_ftrace_thunk(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *ops, struct pt_regs *regs) { struct ftrace_hook *hook = container_of(ops, struct ftrace_hook, ops); if (!within_module(parent_ip, THIS_MODULE)) regs->ip = (unsigned long) hook->func; } ``` 最前面 function 的修飾詞 notrace 代表這個 function 是被 ftrace 所使用的,沒有辦法被 register ,可以避免如果在這個函數中呼叫到了原本 hook 的函式造成無限遞迴。而這邊的 ```within_module()``` 是判斷 ```parent_ip``` 是不是由這個 module 所呼叫的,如果不是的話,就把它 hook 到想要的 function 當中。 ```cpp static struct pid *hook_find_ge_pid(int nr, struct pid_namespace *ns) { struct pid *pid = real_find_ge_pid(nr, ns); while (pid && is_hidden_proc(pid->numbers->nr)) pid = real_find_ge_pid(pid->numbers->nr + 1, ns); return pid; } ``` 而這個 module 是把原本 ```find_ge_pid()``` 這個 function 改變成執行 ```hook_find_ge_pid()``` 這個 funciton ,原本的 ```find_ge_pid()``` 是去尋找在這個 ```ns``` process namespace 當中大於等於 ```nr``` 這個數字的 pid (不過在 kernel 當中是 tgid ) ,所以當我們發現原本 ```find_ge_pid()``` 找到的 pid 是我們要隱藏的 pid 的話,就要求它去找比這個 pid 大的其他 pid 作為回傳值。 :::info 如果直接執行 ftrace 的話是找不到 ```find_ge_pid()``` 這個函式的,不過在 available_filter_functions 當中卻有看到這個函式,而如果把它加入 set_ftrace_filter 的話還是能夠找的到。透過兩次設定 ftrace filter 找到沒有更上面呼叫的函式: ```cpp ... ps-11834 [001] .... 7703.662392: next_tgid <-proc_pid_readdir ps-11834 [001] .... 7703.662395: find_ge_pid <-next_tgid ps-11834 [001] .... 7703.662402: next_tgid <-proc_pid_readdir ps-11834 [001] .... 7703.662403: find_ge_pid <-next_tgid ps-11834 [001] .... 7703.662405: next_tgid <-proc_pid_readdir ps-11834 [001] .... 7703.662405: find_ge_pid <-next_tgid ps-11834 [001] .... 7703.662407: next_tgid <-proc_pid_readdir ps-11834 [001] .... 7703.662407: find_ge_pid <-next_tgid ... ``` 而我也在沒有設置 filter 的 ftrace 中有看到```proc_pid_readdir```這個函式 ```cpp ... ps-11849 [001] .... 7797.158451: proc_pid_readdir <-proc_root_readdir ... ``` ::: ## 修改項目 1. 修正已 allocate 的 memory 沒有釋放完的問題。 2. 修正刪除會把全部東西都刪掉的問題。 3. 可以一次輸入多個 pid 進行隱藏或解除隱藏。 4. 除了隱藏輸入的 pid 之外,所有他的 children 都會被隱藏。 5. 除了解除隱藏的 pid 之外,所有他的 children 都會被解除隱藏。 :::danger 如果要解除隱藏的 pid 沒有經過隱藏的步驟的話,很有可能沒辦法解除隱藏其所有 children 的 pid 。 ::: 6. 如果輸入的 pid 並未在系統中找到,則不會加入隱藏的列表。 7. 將其顯示修改為顯示隱藏的 pid 以及其 parent pid 。 8. 已知問題:如果 concurrency 的話 hidden_proc 可能會出問題,應該于以保護,而且 read task_struct 也應該要 rcu read lock 比較安全。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up