2013-11-18 2 views
3

я могу использовать kprobe механизм для подключения обработчиков, используя следующий пример кода:Kernel зонд не вставлен для system_call функции

#include <asm/uaccess.h> 
#include <linux/module.h> 
#include <linux/kernel.h> 
#include <linux/version.h> 
#include <linux/kallsyms.h> 
#include <linux/slab.h> 
#include <linux/init.h> 
#include <linux/kprobes.h> 

static struct kprobe kp; 

int Pre_Handler(struct kprobe *p, struct pt_regs *regs){ 
    printk("pre_handler\n"); 
    return 0; 
} 

void Post_Handler(struct kprobe *p, struct pt_regs *regs, unsigned long flags) { 
    printk("post_handler\n"); 
} 

int __init init (void) { 
    kp.pre_handler = Pre_Handler; 
    kp.post_handler = Post_Handler; 
    kp.addr = (kprobe_opcode_t *)kallsyms_lookup_name("sys_fork"); 
    printk("%d\n", register_kprobe(&kp)); 
    return 0; 
} 

void __exit cleanup(void) { 
    unregister_kprobe(&kp); 
} 

MODULE_LICENSE("GPL"); 
module_init(init); 
module_exit(cleanup); 

Однако, похоже, не все процедуры ядра могут быть отслежены таким образом. Я пытался прикрепить обработчики system_call, что их называют с любым исполнением системного вызова со следующими изменениями:

kp.addr = (kprobe_opcode_t *)kallsyms_lookup_name("system_call"); 

и зонды не вставлены. dmesg показывает, что register_kprobe возвращает -22, который является -EINVAL. Почему эту функцию невозможно отслеживать? Можно ли подключить обработчик kprobe перед отправкой любого системного вызова?

$ uname -r 
3.8.0-29-generic 

ответ

2

system_call защищен от kprobes, невозможно проверить функцию system_call. Я думаю, что у нас нет никакой полезной информации, которую вы можете получить до того, как будет вызван какой-либо действительный системный вызов. Например, если вы видите функцию system_call:

RING0_INT_FRAME     # can't unwind into user space anyway 
    ASM_CLAC 
    pushl_cfi %eax     # save orig_eax 
    SAVE_ALL 
    GET_THREAD_INFO(%ebp) 
            # system call tracing in operation/emulation 
    testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) 
    jnz syscall_trace_entry 
    cmpl $(NR_syscalls), %eax 
    jae syscall_badsys 
    syscall_call: 
    call *sys_call_table(,%eax,4) 

есть несколько инструкций, прежде чем ваша текущая система вызова вызывается. да, я не уверен, нужна ли вам информация в этих инструкциях.

+0

Знаете ли вы о каком-либо рабочем неинвазивном способе выполнения какого-либо кода перед любым системным вызовом? – Nykakin

+2

Посмотрите проект procmon по адресу https://github.com/alexandernst/procmon. Это будет полезно. CC: @alexandernst –

Смежные вопросы