Доброго времени суток.
Возникла проблема с заменой оригинального системного вызова на свой собственный. В ядрах версии 2.6 таблица системных вызовов не экспортируется, но порывшись в интернете наткнулся на решение этой проблемы в виде функции
unsigned long **find_sys_call_table(void)
{
unsigned long **sctable;
unsigned long ptr;
extern unsigned long loops_per_jiffy;
sctable = NULL;
for (ptr = (unsigned long)&unlock_kernel;
ptr < (unsigned long)&loops_per_jiffy;
ptr += sizeof(void *))
{
unsigned long *p;
p = (unsigned long *)ptr;
if (p[__NR_close] == (unsigned long) sys_close)
{
sctable = (unsigned long **)p;
return &sctable[0];
}
}
return NULL;
}
Написав простенький модуль с её использованием получаем:
pdk@pdk-laptop:~$ dmesg
[71379.874638] Hi
[71379.874662] Syscall table address c0326520
Сравниваю с
pdk@pdk-laptop:~$ cat /boot/System.map-2.6.24-23-generic | grep sys_call_table
c0326520 R sys_call_table
делаю вывод, что работает верно.
Дальше казалось бы всё просто, но не тут то было

При попытке заменить системный вызов, к примеру, mkdir путём:
int (*orig_mkdir)(const char *path);
int my_mkdir(const char *path)
{
printk(KERN_INFO"My own mkdir()\n");
orig_mkdir(path);
return 0;
}
static int __init module_ini(void)
{
printk(KERN_INFO "Hi \n");
sys_call_table = find_sys_call_table();
if (sys_call_table == NULL)
{
printk(KERN_ERR "Cannot find the system call address\n");
return -1; // do not load
}
printk(KERN_ERR "Syscall table address %p\n",sys_call_table);
orig_mkdir = sys_call_table[__NR_mkdir];
sys_call_table[__NR_mkdir] = my_mkdir;
return 0;
}
загружаю модуль:
pdk@pdk-laptop:~$./insmod
Segmentation fault
pdk@pdk-laptop:~$dmesg
[72116.141979] Hi
[72116.142005] Syscall table address c0326520
[72116.142034] BUG: unable to handle kernel paging request at virtual address c03265bc
[72116.142038] printing eip: f8b59042 *pde = 1f956163 *pte = 00326161
[72116.142045] Oops: 0003 [#1] SMP
и так далее ...
Хотелось бы узнать как это дело заставить работать, у самого опыта в таких вещах нету

P.S. Хотя можете мне подсказать другой способ мониторинга за обращениями к системным вызовам из модуля ядра - буду только рад (мне важно знать только сам факт запуска системного вызова)
