2012-12-13 27 views
3

在Linux上的Mach內核API模擬,我需要我的內核模塊在任務剛創建或正在終止時被調用。Linux模塊:正在被通知任務創建和銷燬

在我的內核模塊中,這很可能是通過Linux安全模塊完成的,但是幾年前,他們通過取消導出所需符號來阻止外部模塊充當LSM。

我能找到的唯一方法是讓我的模塊像rootkit一樣工作。找到系統調用表並掛在那裏。

修補內核是不可能的。我需要我的應用程序很容易安裝。有沒有其他方法?

回答

3

您可以使用Kprobes,它使您能夠動態地掛接到內核中的代碼。您需要找到正確的功能,包括創建和銷燬爲您提供所需信息的流程。例如,對於創建的任務,fork.c中的do_fork()將是一個很好的開始。對於銷燬的任務,do_exit。你會想編寫一個retprobe,這是一種kprobe,它在函數執行結束時額外給予你控制權,然後返回。在函數返回之前你想要控制的原因是通過檢查返回值來檢查它是否成功地創建了進程。如果有錯誤,則函數會返回一個負值,或者在某些情況下可能爲0。

您將通過創建一個kretprobe結構做到這一點:

static struct kretprobe do_fork_probe = { 
    .entry_handler = (kprobe_opcode_t *) my_do_fork_entry, 
    .handler = (kprobe_opcode_t *) my_do_fork_ret, 
    .maxactive = 20, 
    .data_size = sizeof(struct do_fork_ctx) 
}; 

my_do_fork_entry時控制進入鉤被執行函數,並且my_do_fork_ret在它返回之前被執行。你會在如下把它掛:

do_fork_probe.kp.addr = 
    (kprobe_opcode_t *) kallsyms_lookup_name("do_fork"); 

if ((ret = register_kretprobe(&do_fork_probe)) <0) { 
    // handle error 
} 

在你掛鉤的實現,這是一個有點笨拙得到的參數和返回值。你通過保存的寄存器pt_regs數據結構得到這些信息。讓我們看一下返回鉤子,在x86上你可以通過regs-> ax獲得返回值。

static int my_do_fork_ret(struct kretprobe_instance *ri, struct pt_regs *regs) 
{ 
    struct do_fork_ctx *ctx = (struct do_fork_ctx *) ri->data; 
    int ret = regs->ax; // This is on x86 
    if (ret > 0) { 
     // It's not an error, probably a valid process 
    } 
} 

在入口點,您可以通過寄存器訪問參數。例如在x86上,regs-> di是第一個參數,regs-> si是第二個等。你可以谷歌獲得完整列表。請注意,您不應將這些寄存器用於返回掛鉤中的參數,因爲寄存器可能已被其他計算覆蓋。

你一定要跳過很多環節才能使這個工作,但希望這個筆記應該讓你在正確的方向。