---
title: 2021q3 Homework1 (quiz1)
tags: Linux
image:
---
# 2021q3 Homework1 (quiz1)
contributed by < starlinking >
[toc]
## 0. 環境 (Ubuntu 20.04 VM running up)
```b$ uname -a
$ uname -r
5.4.0-80-generic
$ sudo apt install linux-headers-`uname -r`
$ dpkg -L linux-headers-5.4.0-80-generic | grep "/lib/modules"
/lib/modules
/lib/modules/5.4.0-80-generic
/lib/modules/5.4.0-80-generic/build
$ tree -L 2 hideproc/
hideproc/
├── main.c
└── Makefile
$ make
make -C /lib/modules/`uname -r`/build M=/home/star/workspace/linux/hideproc modules
make[1]: Entering directory '/usr/src/linux-headers-5.4.0-80-generic'
CC [M] /home/star/workspace/linux/hideproc/main.o
LD [M] /home/star/workspace/linux/hideproc/hideproc.o
Building modules, stage 2.
MODPOST 1 modules
CC [M] /home/star/workspace/linux/hideproc/hideproc.mod.o
LD [M] /home/star/workspace/linux/hideproc/hideproc.ko
make[1]: Leaving directory '/usr/src/linux-headers-5.4.0-80-generic'
$ tree -L 2 hideproc/
hideproc/
├── hideproc.ko
├── hideproc.mod
├── hideproc.mod.c
├── hideproc.mod.o
├── hideproc.o
├── main.c
├── main.o
├── Makefile
├── modules.order
└── Module.symvers
$ sudo insmod hideproc.ko
$ dmesg
[ 3006.672989] hideproc: module verification failed: signature and/or required key missing - tainting kernel
[ 3006.673303] @ _hideproc_init
$ pidof cron
661
$ echo "add 661" | sudo tee /dev/hideproc
add 661
$ pidof cron
$ echo "del 661" | sudo tee /dev/hideproc
del 661
$ pidof cron
661
$ sudo rmmod hideproc
$ dmesg
[ 3543.712336] @ _hideproc_exit
```
## 1. 解釋程式碼運作原理,包含 ftrace 的使用
:::info
Ftrace堪稱Linux官方tracer,一般只要有echo, cat指令的嵌入式環境,就可以開始。為了後續方便學習 Linux 核心,我們可以安裝 ftrace cmdline 工具 - trace-cmd。
`sudo apt install trace-cmd`
:::
* trace-cmd cheatsheet
```
usage:
trace-cmd [COMMAND] ...
```
| use case | cmd |
| -----------------------------------------| -------------------------- |
| How to know what functions we can trace? | sudo trace-cmd list -f |
| How to trace a function? | sudo trace-cmd record -p function -l do_page_fault |
| How to trace a process? | sudo trace-cmd record -p function -P 25314 |
```
-p run command with plugin enabled
-l filter function name
-P pid
```
* _hideproc_init
* init_hook
* hook_install: install the function hooks
* _hideproc_exit
* hook_remove(&hook): remove function hooks
>enable hook_remove function (==remove line 66 and 76==)
```c=66
#if 0
void hook_remove(struct ftrace_hook *hook)
{
int err = unregister_ftrace_function(&hook->ops);
if (err)
printk("unregister_ftrace_function() failed: %d\n", err);
err = ftrace_set_filter_ip(&hook->ops, hook->address, 1, 0);
if (err)
printk("ftrace_set_filter_ip() failed: %d\n", err);
}
#endif
```
> 增加幾行code,釋放相關資源,避免下次insmod hideproc.ko,出現錯誤,將dev_major宣告為全域變數。
```bash
$ dmesg
[ 9128.397812] sysfs: cannot create duplicate filename '/class/hideproc'
[ 9128.397814] CPU: 0 PID: 17645 Comm: insmod Tainted: G OE 5.4.0-80-generic #90-Ubuntu
[ 9128.397815] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
[ 9128.397816] Call Trace:
[ 9128.397821] dump_stack+0x6d/0x8b
[ 9128.397824] sysfs_warn_dup.cold+0x17/0x27
[ 9128.397827] sysfs_create_dir_ns+0xb8/0xd0
[ 9128.397829] kobject_add_internal+0xbd/0x2b0
[ 9128.397830] kset_register+0x4c/0x70
[ 9128.397832] __class_register+0xd8/0x190
[ 9128.397833] __class_create+0x51/0x80
[ 9128.397836] ? hook_remove.cold+0x26/0x26 [hideproc]
[ 9128.397837] _hideproc_init+0x6c/0x1c5 [hideproc]
[ 9128.397839] do_one_initcall+0x4a/0x200
[ 9128.397841] ? _cond_resched+0x19/0x30
[ 9128.397844] ? kmem_cache_alloc_trace+0x177/0x240
[ 9128.397846] do_init_module+0x62/0x260
[ 9128.397847] load_module+0x11e6/0x1320
[ 9128.397850] __do_sys_finit_module+0xbe/0x120
[ 9128.397851] ? __do_sys_finit_module+0xbe/0x120
[ 9128.397853] __x64_sys_finit_module+0x1a/0x20
[ 9128.397854] do_syscall_64+0x57/0x190
[ 9128.397856] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 9128.397857] RIP: 0033:0x7f1f4b2e989d
[ 9128.397858] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d c3 f5 0c 00 f7 d8 64 89 01 48
[ 9128.397859] RSP: 002b:00007ffc3ea5ab58 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
[ 9128.397860] RAX: ffffffffffffffda RBX: 0000557bf07c57a0 RCX: 00007f1f4b2e989d
[ 9128.397860] RDX: 0000000000000000 RSI: 0000557beeb2f358 RDI: 0000000000000003
[ 9128.397861] RBP: 0000000000000000 R08: 0000000000000000 R09: 00007f1f4b3bd260
[ 9128.397861] R10: 0000000000000003 R11: 0000000000000246 R12: 0000557beeb2f358
[ 9128.397862] R13: 0000000000000000 R14: 0000557bf07c5760 R15: 0000000000000000
[ 9128.397864] kobject_add_internal failed for hideproc with -EEXIST, don't try to register things with the same name in the same directory.
```
```c=234
static void _hideproc_exit(void)
{
printk(KERN_INFO "@ %s\n", __func__);
/* FIXME: ensure the release of all allocated resources */
hook_remove(&hook);
device_destroy(hideproc_class, MKDEV(dev_major, MINOR_VERSION));
class_destroy(hideproc_class);
cdev_del(&cdev);
unregister_chrdev_region(MKDEV(dev_major, MINOR_VERSION), MINOR_VERSION);
}
```
> 可以連續 insert, remove hideproc 核心模組!
```bash
$ dmesg
[ 1209.535616] @ _hideproc_init
[ 1299.288350] @ _hideproc_exit
[ 1323.978583] @ _hideproc_init
[ 1545.173048] @ _hideproc_exit
[ 1547.666741] @ _hideproc_init
[ 1549.172767] @ _hideproc_exit
```
:::danger
整個程式碼運作原理還未完全理解,需要再花一點時間內化,再補上。
:::
## 2. 本程式僅在 Linux v5.4 測試,若你用的核心較新,請試著找出替代方案
```
TODO: 先更新kernel版本,再試試!
```
## 3. 本核心模組只能隱藏單一 PID,請擴充為允許其 PPID 也跟著隱藏,或允許給定一組 PID 列表,而非僅有單一 PID
## 4. 指出程式碼可改進的地方,並動手實作
## Resource(s)
* Youtube
* https://www.youtube.com/watch?v=93uE_kWWQjs
* https://jvns.ca/blog/2017/03/19/getting-started-with-ftrace/
* https://xcellerator.github.io/posts/linux_rootkits_02/
* https://xcellerator.github.io/posts/linux_rootkits_04/