4,436
社区成员
发帖
与我相关
我的任务
分享
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/unistd.h>
#include <linux/fs.h>
#include <linux/kallsyms.h>
#include <linux/kprobes.h>
// log out put
void PRINT_LOGS(const char* data, int changeLine)
{
char buf[256] = { 0 };
char rbuf[512] = { 0 };
mm_segment_t fs;
loff_t pos = 0;
struct file *fp_w = filp_open("/home/x/Projects/log", O_RDWR | O_CREAT, 0644);
strcpy(buf, data);
if (changeLine) strcat(buf, "\n");
if (IS_ERR(fp_w)) return;
fs = get_fs();
set_fs(KERNEL_DS);
pos = 0;
vfs_read(fp_w, rbuf, 1024, &pos);
strcat(rbuf, buf);
pos = 0;
vfs_write(fp_w, rbuf, strlen(rbuf), &pos);
filp_close(fp_w, NULL);
set_fs(fs);
}
void PRINT_LOG(unsigned long ul)
{
char buf[256] = { 0 };
sprintf(buf, "%lu", ul);
PRINT_LOGS(buf, 1);
}
// find kallsyms_lookup_name addr
unsigned long(*kallsyms_lookup_name_fun)(const char *name) = NULL;
int noop_pre(struct kprobe *p, struct pt_regs *regs) {
return 0;
}
static struct kprobe kp = {
.symbol_name = "kallsyms_lookup_name",
};
int find_kallsyms_lookup_name(void) {
int ret = -1;
kp.pre_handler = noop_pre;
ret = register_kprobe(&kp);
if (ret < 0) {
PRINT_LOGS("register_kprobe failed", 1);
return ret;
}
PRINT_LOGS("kallsyms_lookup_name addr:", 0); PRINT_LOG((unsigned long)kp.addr);
kallsyms_lookup_name_fun = (void*)kp.addr;
unregister_kprobe(&kp);
return ret;
}
// hook function
asmlinkage long(*sys_openat_original)(int, const char *, int, umode_t);
asmlinkage long sys_openat_new(int dfd, const char *filename, int flags, umode_t mode)
{
PRINT_LOGS("filename :", 0); PRINT_LOGS(filename, 1);
return sys_openat_original(dfd, filename, flags, mode);
}
// enable and disable write protecion
static unsigned long __lkm_order;
static inline unsigned long lkm_read_cr0(void)
{
unsigned long val;
asm volatile("mov %%cr0,%0\n\t" : "=r" (val), "=m" (__lkm_order));
return val;
}
static inline void lkm_write_cr0(unsigned long val)
{
asm volatile("mov %0,%%cr0": : "r" (val), "m" (__lkm_order));
}
void disable_write_protection(void)
{
unsigned long cr0 = lkm_read_cr0();
clear_bit(16, &cr0);
lkm_write_cr0(cr0);
PRINT_LOGS("disable_write_protection complete!", 1);
}
void enable_write_protection(void)
{
unsigned long cr0 = lkm_read_cr0();
set_bit(16, &cr0);
lkm_write_cr0(cr0);
PRINT_LOGS("enable_write_protection complete!", 1);
}
// module init
static void **sys_call_table;
static int mod_init(void)
{
find_kallsyms_lookup_name();
sys_call_table = (void**)kallsyms_lookup_name_fun("sys_call_table");
if (!sys_call_table) {
PRINT_LOGS("find sys_call_table failed!", 1);
return 0;
}
disable_write_protection();
sys_openat_original = sys_call_table[__NR_openat];
PRINT_LOGS("sys_openat_old:", 0); PRINT_LOG((unsigned long)sys_openat_original);
sys_call_table[__NR_openat] = sys_openat_new;
PRINT_LOGS("sys_open_new:", 0); PRINT_LOG((unsigned long)sys_openat_new);
enable_write_protection();
PRINT_LOGS("init complete!", 1);
return 0;
}
static void mod_exit(void)
{
disable_write_protection();
sys_call_table[__NR_openat] = sys_openat_original;
enable_write_protection();
}
module_init(mod_init);
module_exit(mod_exit);
MODULE_LICENSE("GPL");