Не работает подключение системного вызова к драйверу ядра Linux

#c #linux #linux-device-driver #kernel-module

#c #linux #linux-device-driver #kernel-module

Вопрос:

Я следую этой статье https://exploit.ph/linux-kernel-hacking/2014/07/10/system-call-hooking/index.html , но, похоже, я не могу заставить это работать. Я попытался добавить некоторые printk для целей отладки, но что-то кажется странным. Это код, который я запускаю —

 #include <linux/init.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/unistd.h>
#include <linux/semaphore.h>
#include <linux/dirent.h>
#include <asm/cacheflush.h>

MODULE_AUTHOR("Tamir");
MODULE_LICENSE("GPL");

void **sys_call_table;

#define FILE_NAME "1.txt"

asmlinkage int (*original_getdents64) (unsigned int fd, struct linux_dirent64 *dirp, unsigned int count);

asmlinkage int sys_getdents64_hook(unsigned int fd, struct linux_dirent64 *dirp, unsigned int count)
{
    printk("Inside hook :)");
    int rtn;
    struct linux_dirent64 *cur = dirp;
    int i = 0;
    rtn = original_getdents64(fd, dirp, count);
    while (i < rtn) {
        if (strncmp(cur->d_name, FILE_NAME, strlen(FILE_NAME)) == 0) {
            int reclen = cur->d_reclen;
            char *next_rec = (char *)cur   reclen;
            int len = (int)dirp   rtn - (int)next_rec;
            memmove(cur, next_rec, len);
            rtn -= reclen;
            continue;
        }
        i  = cur->d_reclen;
        cur = (struct linux_dirent64*) ((char*)dirp   i);
    }
    return rtn;
}

int set_page_rw(unsigned long addr)
{
    unsigned int level;
    pte_t *pte = lookup_address(addr, amp;level);
    if (pte->pte amp;~ _PAGE_RW) pte->pte |= _PAGE_RW;
    return 0;
}

int set_page_ro(unsigned long addr)
{
    unsigned int level;
    pte_t *pte = lookup_address(addr, amp;level);
    pte->pte = pte->pte amp;~_PAGE_RW;
    return 0;
}

static int __init getdents_hook_init(void)
{
  printk("----------------nInit Modulen");
  sys_call_table = (void*) 0xc18af1e0;
  original_getdents64 = sys_call_table[__NR_getdents64];

  set_page_rw(sys_call_table);
  sys_call_table[__NR_getdents64] = sys_getdents64_hook;
  printk("After hooked");
  return 0;
}

static void __exit getdents_hook_exit(void)
{
  printk("Exiting modulen-----------------------nn");
  sys_call_table[__NR_getdents64] = original_getdents64;
  set_page_ro(sys_call_table);
  return 0;
}

module_init(getdents_hook_init);
module_exit(getdents_hook_exit);
  

После компиляции и вставки с помощью insmod я использую ls команду, но файл все еще отображался.
Раньше я dmesg видел распечатки ядра, и я вижу только строку «Init Module», а не «После подключения».

Когда я удаляю модуль (rmmod) и снова просматриваю распечатки ядра, я вижу «после подключения» и «Выход из модуля».

Я не совсем уверен, что я могу сделать или как я могу отладить его дальше, чтобы понять, что пошло не так.

**

Комментарии:

1. Какова ваша архитектура? Кроме того, добавьте n ко всем вашим printk() вызовам, иначе вы не увидите результат on dmesg .

2. Я добавил » n», все еще не видя его. Кроме rmmod того, я вижу «После подключения» с меткой времени инициализации. Процессор Arch — i686 в режиме — 32-разрядный, 64-разрядный

3. Какая версия ядра? x86_64 переключился CONFIG_ARCH_HAS_SYSCALL_WRAPPER на версию ядра 4.17, а i386 переключился на версию ядра 5.7.

4. (void *)0xc18af1e0 Действительно ли магическое число является местоположением таблицы системных вызовов в вашем ядре?

5. Адрес правильный, я grep sys_call_table /boot/System.map-`uname -r также проверяю его, это версия ядра 4.15.0-120-generic