ядро 2.6.3
написал маленький модуль,который должен подменить системный вызов execve
#include <linux/types.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/unistd.h>
# define print(fmt, args...) printk( KERN_INFO "smotrel: " fmt, ## args)
unsigned *sys_call_table;int (*o_execve)(struct pt_regs);
int n_execve (struct pt_regs regs){
print ("hello\n");
return o_execve(regs);
}unsigned *find_sc(void)
{
....
}int init_module(){
print("module inserted\n");
sys_call_table=find_sc();
print("sys_call_table adress:0x%x\n",sys_call_table);
o_execve=(void *)sys_call_table[__NR_execve];
print("execve in sys_call_table:0x%x\n",&sys_call_table[__NR_execve]);
print("execve aress:0x%x\n",o_execve);
//sys_call_table[__NR_execve]=(unsigned)n_execve;
return 0;
}
void cleanup_module(){
//sys_call_table[__NR_execve]=(unsigned)o_execve;
print("module removed\n");
}
после выполнения insmod rmmod вывод такой :
[root@localhost mod]# tail /var/log/messages
Mar 25 05:18:38 localhost kernel: smotrel: module inserted
Mar 25 05:18:38 localhost kernel: smotrel: sys_call_table adress:0xc0323be0
Mar 25 05:18:38 localhost kernel: smotrel: execve in sys_call_table:0xc0323c0c
Mar 25 05:18:38 localhost kernel: smotrel: execve aress:0xc01099e0
Mar 25 05:18:42 localhost kernel: smotrel: module removed
проверил все с помощью gdb- все адреса правильные.
(gdb) disas 0xc01099e0
Dump of assembler code for function sys_execve:
0xc01099e0 <sys_execve+0>: push %ebp
0xc01099e1 <sys_execve+1>: mov %esp,%ebp
0xc01099e3 <sys_execve+3>: push %esi
.....(gdb) info functions sys_execve
All functions matching regular expression "sys_execve":File arch/i386/kernel/process.c:
int sys_execve(struct pt_regs);и объявил я sys_exec правильно.
но если раскомментировать строчки в init_module cleanup_module
то после insmod начинает выдаваться сообщение Segmentation fault.в чем я неправ?
на других сист вызовах работает...проверил на sys_chmod все отлично. долгожданное hello появляется в логах.в чем особенность sys_execve?
Надеюсь ты ничего плохого не замыслил ? Типа root-toolkit решил создать ?
>(gdb) disas 0xc01099e0
>Dump of assembler code for function sys_execve:
>0xc01099e0 <sys_execve+0>: push %ebp
>0xc01099e1 <sys_execve+1>: mov %esp,%ebp
>0xc01099e3 <sys_execve+3>: push %esi
>.....
>
>(gdb) info functions sys_execve
>All functions matching regular expression "sys_execve":
>
>File arch/i386/kernel/process.c:
>int sys_execve(struct pt_regs);
>
>и объявил я sys_exec правильно.
>но если раскомментировать строчки в init_module cleanup_module
>то после insmod начинает выдаваться сообщение Segmentation fault.
>
>в чем я неправ?
>на других сист вызовах работает...проверил на sys_chmod все отлично. долгожданное hello
>появляется в логах.
>
>в чем особенность sys_execve?
в том, что в случае "удачи" возврата из него не происходит. екзекв "раскручивает стэк" для проведения "зачистки" старого имиджа и после этого формирует начальный стэк нового. в твоем случае в стэке появляется лишний фрейм - от n_execve.
если на ассемблере х86, то "финал" твоего n_execve выглядит как:
call o_execve
pop bp
ret
если вместо этого будет просто
jmp o_execve
то, возможно, работать будет. надо сверять как формируется стэковый фрейм у тебя и у настоящего экзеква."чиста на C" этого, боюс, нельзя сделать.
\^P^/
или другой вариант. Например, проблема не в exec, а в том, как создается новый процесс: fork или vfork. Если vfork - то потомок и родитель имеют общий стек, с чем и может быть связана бага.