Linux kernel function / system call hijacking

想要 hijack 某個 Linux kernel 的 function ,所以開始了這次的搜尋。

Linux kernel 各部分之間的 function 呼叫有2種,一種是直接把要呼叫的 function header file include 進來,如果是在同一個檔案當然也不需要 include。另一種是呼叫 exported function ,允許外部呼叫的 function 在定義之後會加上 EXPORT_SYMBOL(function_name) ,這個 function 的記憶體位址就可以從 kernel symbol table 找到(symbol table 裏面不只有 function ,也有變數)。外部呼叫是指 kernel 的其他部分還有 kernel module ,外部呼叫時會去 symbol table 找位址再進行呼叫(應該吧)。

所以只要修改 symbol table 的內容,就可以 hijack 特定的 function,讓他去找我們自己定義的位址的 function 去呼叫了。不對

但是一般 kernel symbol table 是唯讀的,看一下 /proc/kallsyms 的內容,第一欄是記憶體位址,第二欄是屬性(是否可讀寫等等,標籤代表的意義請 man nm),第三欄是變數或函式名稱。

system call table 裏面存了所有 system call 的記憶體位址,它的 symbol 叫做 sys_call_table ,在大部分的 Linux 上面應該是 R (唯讀)需要先解除 page write protection 才能修改。(其他參考)HTC Android kernel 的 sys_call_table 標籤居然是 T ,意思好像是可讀寫?

syscall table 裏面存了所有 syscall 的進入點(記憶體位址),用 sys_call_table[CONSTANT] 的方式可以找到特定 syscall 的進入點,像是如果要找 fork() 的進入點,就這樣寫:sys_call_table[__NR_fork]__NR_fork 這些 constant 定義於 unistd.h ,依處理器架構會有不同。上面連結的那兩篇有如何 hijack syscall 的教學。

後來發現我要的不是 syscall hijacking ,而是 kernel function hijacking ,我搞混了這兩個。syscall 是 userspace 程式和 kernel 溝通的界面,一般來說都是由應用程式呼叫;kernel function 是 kernel 內部的函式,提供給其他 kernelspace (可能在 kernel 或是 kernel module )的函式調用,又有是否 export 之分,有 export 的 function 在宣告後會加上 EXPORT_SYMBOL(function_name) ,它的位址就在 symbol table 找得到。

要 hijack kernel function 似乎要牽涉到一些 shellcode… 而且是 platform-specific ,還有待研究。(順帶一看

搜尋的過程當中找到這幾個問答:

發現若不是要 hijack 的話,基本的 debug 可以透過 kprobe

 

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 變更 )

Twitter picture

You are commenting using your Twitter account. Log Out / 變更 )

Facebook照片

You are commenting using your Facebook account. Log Out / 變更 )

Google+ photo

You are commenting using your Google+ account. Log Out / 變更 )

連結到 %s