From 2a64784a3356418f839c54aaf1b36c6553caedd8 Mon Sep 17 00:00:00 2001 From: weishu Date: Wed, 20 Mar 2024 14:21:14 +0800 Subject: [PATCH] kernel: hook syscall instead of unstable symbol --- kernel/arch.h | 4 ++++ kernel/ksud.c | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/kernel/arch.h b/kernel/arch.h index 1678fd1b..4a7b9351 100644 --- a/kernel/arch.h +++ b/kernel/arch.h @@ -20,8 +20,10 @@ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0) #define PRCTL_SYMBOL "__arm64_sys_prctl" +#define SYS_READ_SYMBOL "__arm64_sys_read" #else #define PRCTL_SYMBOL "sys_prctl" +#define SYS_READ_SYMBOL "sys_read" #endif #elif defined(__x86_64__) @@ -41,8 +43,10 @@ #define __PT_IP_REG ip #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0) #define PRCTL_SYMBOL "__x64_sys_prctl" +#define SYS_READ_SYMBOL "__x64_sys_read" #else #define PRCTL_SYMBOL "sys_prctl" +#define SYS_READ_SYMBOL "sys_read" #endif #else diff --git a/kernel/ksud.c b/kernel/ksud.c index 95cea549..bff47a43 100644 --- a/kernel/ksud.c +++ b/kernel/ksud.c @@ -1,7 +1,10 @@ #include "asm/current.h" #include "linux/compat.h" +#include "linux/compiler_attributes.h" +#include "linux/cred.h" #include "linux/dcache.h" #include "linux/err.h" +#include "linux/file.h" #include "linux/fs.h" #include "linux/version.h" #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) @@ -384,6 +387,15 @@ int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr, return 0; } +int ksu_handle_sys_read(unsigned int fd, char __user **buf_ptr, size_t *count_ptr) +{ + struct file *file = fget_raw(fd); + if (!file) { + return 0; + } + return ksu_handle_vfs_read(&file, buf_ptr, count_ptr, NULL); +} + static unsigned int volumedown_pressed_count = 0; static bool is_volumedown_enough(unsigned int count) @@ -459,7 +471,8 @@ static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs) return ksu_handle_execveat_ksud(fd, filename_ptr, &argv, NULL, NULL); } -static int read_handler_pre(struct kprobe *p, struct pt_regs *regs) +// remove this later! +__maybe_unused static int vfs_read_handler_pre(struct kprobe *p, struct pt_regs *regs) { struct file **file_ptr = (struct file **)&PT_REGS_PARM1(regs); char __user **buf_ptr = (char **)&PT_REGS_PARM2(regs); @@ -469,6 +482,20 @@ static int read_handler_pre(struct kprobe *p, struct pt_regs *regs) return ksu_handle_vfs_read(file_ptr, buf_ptr, count_ptr, pos_ptr); } +static int sys_read_handler_pre(struct kprobe *p, struct pt_regs *regs) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0) + struct pt_regs *real_regs = (struct pt_regs *)PT_REGS_PARM1(regs); +#else + struct pt_regs *real_regs = regs; +#endif + unsigned int fd = PT_REGS_PARM1(real_regs); + char __user **buf_ptr = (char __user **)&PT_REGS_PARM2(real_regs); + size_t count_ptr = (size_t *) &PT_REGS_PARM3(real_regs); + + return ksu_handle_sys_read(fd, buf_ptr, count_ptr); +} + static int input_handle_event_handler_pre(struct kprobe *p, struct pt_regs *regs) { @@ -489,10 +516,17 @@ static struct kprobe execve_kp = { .pre_handler = execve_handler_pre, }; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) +static struct kprobe vfs_read_kp = { + .symbol_name = SYS_READ_SYMBOL, + .pre_handler = sys_read_handler_pre, +}; +#else static struct kprobe vfs_read_kp = { .symbol_name = "vfs_read", - .pre_handler = read_handler_pre, + .pre_handler = vfs_read_handler_pre, }; +#endif static struct kprobe input_handle_event_kp = { .symbol_name = "input_handle_event",