2014年11月11日 星期二

[Kernel] 叫你的kernel 跑你程式

Ask your kernel to run your mama userspace process

上面僅供參考。

通常來說Linux kernel/user space 分際是很嚴謹的,尤其是記憶體存取,往往得靠 copy_to_user copy_from_user 至於操作就更多了,netlink、 proc、ioctl 、open/read/write/fcntl。
Linux效率上會輸給輕鬆達成zero-copy 的Cisco IOS,看完IOS的Source code發現根本就是逆天阿(下略5千字...),天生作message/packet control 的奇才....  @@

既然兩個模式楚河漢界,能突破這種規範就真的非常值得玩玩。

下面就一起來跑你.....(下略




首先抓完Linux  入手看到 Linux source 先從 linux/init/main.c 開始,把他當作是Linux 最開始執行的部分(是啦... 細細分當然不是這樣,別鞭我阿)。題外話: 你看看麗娜斯老爸人家寫程式也是從main 開始(驚

--
裡面有一段:
    run_init_process("/bin/init");
    run_init_process("/bin/sh");
赫然發現... kernel 是可以直接執行 file system 裡面 user space 的程式!!!
流程:  run_init_process() -->kernel_execve()--> 自行往下... 看到asm code 就可以去喝涼水了

既然這種二督六脈~路徑沒問題,事實上kernel 的確有提供API 可供 kernel module 執行的時候呼叫

call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait)

內部內容 -> kernel working queue ... 啪啦啪啦,別人都寫得很好了。
像這個 還有這個 還有聖經

要注意的是最後一個參數:
enum umh_wait {
    UMH_NO_WAIT = -1,   /* don't wait at all */
    UMH_WAIT_EXEC = 0,  /* wait for the exec, but not the process */
    UMH_WAIT_PROC = 1,  /* wait for the process to complete */
};

這個 helper 如果要執行在 中斷區間的話,就得使用 UMH_NO_WAIT ,而且不保證執行成功... 使用上要多加考慮。(hotplug 到底是怎麼保證的阿 ?! 找時間再來看看好了...)

教學網路很多,來的sample 方便筆記,腦袋裝東西越來越困難了。寫程是不靠google 查API的神人,大概不會是我 T^T。

static int call_user(char *exec)
{
   char *argv[] = {exec, NULL};
    
// Daemon stdin out err is disable from kernel, so no msg
    static char *envp[] = {
        "HOME=/",
        "TERM=linux",
        "PATH=/sbin:/bin:/usr/sbin:/usr/bin", NULL };
    
    printk("Call user now \n");
    call_usermodehelper(argv[0], argv, envp, UMH_NO_WAIT); 
    return 0;
}

說到用途?! 配合kernel timer + 變數monitor ,可以逆向來作一些事囉。