Функция обмена в таблице системных вызовов в x86

Я пытаюсь переопределить системный вызов для sys_open и отслеживать с его помощью поведение пользователя. Я использую ядро ​​Linux 4.13.0-041300. Это мой код до сих пор

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/syscalls.h>

MODULE_LICENSE ("GPL");

//this is where the original sys_open call position will be saved
asmlinkage long (*original_open)(const char __user *filename, int flags, umode_t mode);

unsigned long **sys_call_table;
//this is to track how often my replaced function was called...
static int zeug = 0;

//this is my open function that i want to be replaced in the sys_call_table
asmlinkage long replaced_open(const char __user *filename, int flags, umode_t mode)
{
    printk ("replaced wurde aufgerufen...\n");
    zeug++;
    return original_open(filename, flags, mode);
}

static void enable_page_protection(void)
{
    unsigned long value;
    asm volatile("mov %%cr0, %0" : "=r" (value));

    if ((value & 0x00010000))
        return;

    asm volatile("mov %0, %%cr0" : : "r" (value | 0x00010000));
}

static void disable_page_protection(void)
{
    unsigned long value;
    asm volatile("mov %%cr0, %0" : "=r" (value));

    if (!(value & 0x00010000))
        return;

    asm volatile("mov %0, %%cr0" : : "r" (value & ~0x00010000));
}

//the function to get the system_call_table
static unsigned long **aquire_sys_call_table(void)
{
    unsigned long int offset = PAGE_OFFSET;
    unsigned long **sct;

    while (offset < ULLONG_MAX) {
        sct = (unsigned long **)offset;

        if (sct[__NR_close] == (unsigned long *) sys_close)
            return sct;

        offset += sizeof(void *);
    }

    return NULL;
}

static int __init minit (void)
{
    printk ("minit: startet...\n");

    if (!(sys_call_table = aquire_sys_call_table()))
            return -1;

    printk ("minit: sys_call_table ersetzt...\n");

    disable_page_protection(); 
    {
        //here i print the function name of the current function in sys_call_table
        printk ("minit: eintrag vor ersetzen:%pF\n", sys_call_table[__NR_open]);

        //here i store the real sys_open function and change to my func
        original_open =(void * )xchg(&sys_call_table[__NR_open],(unsigned long *)replaced_open);

}
    enable_page_protection();
    return 0;
}

static void mexit (void)
{
    printk ("mexit gestartet.\n");
    printk ("Open was called %d times...\n",zeug);
    if (!sys_call_table) return;

    //here i print the stored function again
    printk ("bei exit:%pF\n", sys_call_table[__NR_open]);

    disable_page_protection();
    {
            //change back to original sys_open function
            xchg(&sys_call_table[__NR_open], (unsigned long *)original_open);
    }
    printk ("nach zurücksetzen:%pF\n", sys_call_table[__NR_open]);
    enable_page_protection();
}

module_init(minit);
module_exit(mexit);

Мой план: После вставки этого модуля в ядро ​​каждый системный вызов sys_open будет «перенаправлен» на мою функцию replace_open. Эта функция подсчитает свои вызовы, а затем вызовет исходную открытую функцию.

После rmmod моего модуля снова будет использован исходный файл system_call open.

Вроде замена работает. Итак, после insmmmod я получаю результат replace_open+0x0/0x40 [kroot]. Это означает, что исходная функция sys_open была заменена на мою replace_open, верно? и после удаления моего модуля я получаю сообщение SyS_open+0x0/0x20.

Так вроде замена работает.

Моя проблема: я не вижу никаких печатных сообщений из моей функции replace_open. Также кажется, что подсчет не работает.

Такое ощущение, что функция не была заменена должным образом.

У вас есть помощь для меня?

Вам, вероятно, следует изучить возможность использования хуков Модуль безопасности Linux. Он был разработан именно для этого, хотя и в целях безопасности, таких как добавление дополнительных проверок к системным вызовам, которые делает SELinux. Еще одна вещь, которую вам нужно решить: системные вызовы ядра должны быть многопоточными. Ваш приращение zeug++; не является атомарным - на самом деле это «прочитать значение, добавить 1 к значению, сохранить значение». Это просто вызовет неправильные подсчеты в вашем коде, но для чего-то критического, например подсчета ссылок, это может вызвать серьезные проблемы.

Andrew Henle 23.02.2019 15:12

Вы успешно нашли таблицу системных вызовов? Это кажется наиболее вероятным провалом. Вы смотрели на этот вопрос: stackoverflow.com/questions/39502198/…

Nick ODell 23.02.2019 15:48

Возможно, вам следует перепроверить, действительно ли вы нашли таблицу системных вызовов, например, проверив sys_closeиsys_fork или тому подобное.

Ctx 23.02.2019 15:55

когда я запускаю printk ("bei exit:%pF\n", sys_call_table[__NR_open]), я получаю в результате SyS_open+0x0/0x20. так должно быть правильно я думаю. Я получаю тот же результат, когда запускаю это, прежде чем что-либо менять.

Levin S 23.02.2019 16:17

sys_fork и sys_open и так далее неизвестны. я могу проверить SCT только с помощью sys_close.

Levin S 23.02.2019 17:21

Ваш код работает для меня здесь, должен быть ваш sct, чтобы найти неправильный, вы можете напечатать адрес указателя sct, сравнить с правильным sys_call_table на ядре. Можете ли вы использовать kallsyms_lookup_name("sys_call_table")?

ccxxshow 25.02.2019 11:26
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
169
0

Другие вопросы по теме