#include "sc_hook.h"
#include <linux/kthread.h>
MODULE_AUTHOR("xfliu");
MODULE_DESCRIPTION("Syscall hook");
MODULE_VERSION("0.01");
static sys_call_ptr_t* sys_call_table;
sys_call_ptr_t old_sys_table[MAX_SC_IDX];
int hook_sys_table[sc_end_type];
char hook_sys_name[sc_end_type][16];
atomic_t sc_ref_table[sc_end_type];
char* cur_module = NULL;
#define SC_FUNC_PART
#ifdef SC_FUNC_PART
int num=0;
static struct task_struct *kthread = NULL;
//此逻辑与架构无关
static int sc_hook_process(int sc_map_idx, int sc_table_idx, const char* file_name)
{
int name_len = 0;
int ret = 0;
if (!task_ctx) {
return 0;
}
if (file_name) {
SC_DEBUG(sc_debug, KERN_INFO "open file :%s\n", file_name);
if (IsFileIgnore(file_name)) {
return 0;
}
name_len = strlen(task_ctx->sc_task[sc_table_idx].filename);
// no file_name : hook action
if (0 == name_len) ret = 0;
// have file_name name but current name not equals file_name : pass
else if (0 !=
strcmp(file_name, task_ctx->sc_task[sc_table_idx].filename))
ret = 1;
// have file_name name and current name not equals file_name : hook
// actions
else
ret = 0;
}
if (1 == ret) return 0;
// check fault rate and decide whether hook action or not
if (task_ctx->sc_task[sc_table_idx].sc_para[sc_map_idx].drop_rate > 0) {
ret =
process_drop(&task_ctx->sc_task[sc_table_idx].sc_para[sc_map_idx]);
if (NF_ACCEPT == ret) {
SC_DEBUG(sc_debug,
KERN_INFO "systemcall miss this time:%d\n",
sc_table_idx);
return 0;
}
}
else {
SC_DEBUG(sc_debug, KERN_INFO "systemcall null:%d\n", sc_table_idx);
return 0;
}
SC_DEBUG(
sc_debug, KERN_INFO "systemcall match this time:%d\n", sc_table_idx);
if (task_ctx->sc_task[sc_table_idx].sc_para[sc_map_idx].err_code) {
SC_DEBUG(sc_debug,
KERN_INFO "systemcall err_code[%d]:%d\n",
task_ctx->sc_task[sc_table_idx].sc_para[sc_map_idx].err_code,
sc_table_idx);
return -task_ctx->sc_task[sc_table_idx].sc_para[sc_map_idx].err_code;
}
if (task_ctx->sc_task[sc_table_idx].sc_para[sc_map_idx].delay_time) {
SC_DEBUG(sc_debug,
KERN_INFO "systemcall sleep[%d]:%d\n",
task_ctx->sc_task[sc_table_idx].sc_para[sc_map_idx].delay_time,
sc_table_idx);
msleep(task_ctx->sc_task[sc_table_idx].sc_para[sc_map_idx].delay_time);
}
SC_DEBUG(sc_debug, KERN_INFO "systemcall do nothing:%d\n", sc_table_idx);
return 0;
}
# ifdef PTREGS_SYSCALL_STUBS
static long ref_sys_process(const struct pt_regs* regs, int sc_idx, int sc_type)
{
int ret = 0;
atomic_inc(&sc_ref_table[sc_type]);
ret = (old_sys_table[sc_idx])(regs);
atomic_dec(&sc_ref_table[sc_type]);
return ret;
}
static asmlinkage long hook_open(const struct pt_regs* regs)
{
char filetemp[256] = {0};
if (copy_from_user(filetemp, (char*)regs->regs[1], sizeof(filetemp)))
{
return ref_sys_process(regs, __NR_openat, sc_open_type);
}
int ret = 0;
if (!task_ctx) return ref_sys_process(regs, __NR_openat, sc_open_type); //__NR_open
ret = check_if_hook(sc_open_type);
if (ret < 0) return ref_sys_process(regs, __NR_openat, sc_open_type);
return sc_hook_process(sc_open_type, ret, filetemp);
}
static asmlinkage long hook_write(const struct pt_regs* regs)
{
int ret = 0;
if (!task_ctx) return ref_sys_process(regs, __NR_write, sc_write_type);
ret = check_if_hook(sc_write_type);
if (ret < 0) return ref_sys_process(regs, __NR_write, sc_write_type);
return sc_hook_process(sc_write_type, ret, NULL);
}
static asmlinkage long hook_read(const struct pt_regs* regs)
{
int ret = 0;
if (!task_ctx) return ref_sys_process(regs, __NR_read, sc_read_type);
ret = check_if_hook(sc_read_type);
if (ret < 0) return ref_sys_process(regs, __NR_read, sc_read_type);
return sc_hook_process(sc_read_type, ret, NULL);
}
static asmlinkage long hook_accept(const struct pt_regs* regs)
{
int ret = 0;
if (!task_ctx) return ref_sys_process(regs, __NR_accept, sc_accept_type);
ret = check_if_hook(sc_accept_type);
if (ret < 0) return ref_sys_process(regs, __NR_accept, sc_accept_type);
return sc_hook_process(sc_accept_type, ret, NULL);
}
static asmlinkage long hook_connect(const struct pt_regs* regs)
{
int ret = 0;
if (!task_ctx) return ref_sys_process(regs, __NR_connect, sc_connect_type);
ret = check_if_hook(sc_connect_type);
if (ret < 0) return ref_sys_process(regs, __NR_connect, sc_connect_type);
return sc_hook_process(sc_connect_type, ret, NULL);
}
static asmlinkage long hook_sendto(const struct pt_regs* regs)
{
int ret = 0;
if (!task_ctx) return ref_sys_process(regs, __NR_sendto, sc_send_type);
ret = check_if_hook(sc_send_type);
if (ret < 0) return ref_sys_process(regs, __NR_sendto, sc_send_type);
return sc_hook_process(sc_send_type, ret, NULL);
}
static asmlinkage long hook_recvfrom(const struct pt_regs* regs)
{
int ret = 0;
if (!task_ctx) return ref_sys_process(regs, __NR_recvfrom, sc_recv_type);
ret = check_if_hook(sc_recv_type);
if (ret < 0) return ref_sys_process(regs, __NR_recvfrom, sc_recv_type);
return sc_hook_process(sc_recv_type, ret, NULL);
}
static asmlinkage long hook_lseek(const struct pt_regs* regs)
{
int ret = 0;
if (!task_ctx)
return ref_sys_process(regs, __NR_lseek, sc_lseek_type);
ret = check_if_hook(sc_lseek_type);
if (ret < 0)
return ref_sys_process(regs, __NR_lseek, sc_lseek_type);
return sc_hook_process(sc_lseek_type, ret, NULL);
}
static asmlinkage long hook_fsync(const struct pt_regs* regs)
{
int ret = 0;
if (!task_ctx)
return ref_sys_process(regs, __NR_fsync, sc_fsync_type);
ret = check_if_hook(sc_fsync_type);
if (ret < 0)
return ref_sys_process(regs, __NR_fsync, sc_fsync_type);
return sc_hook_process(sc_fsync_type, ret, NULL);
}
static asmlinkage long hook_socket(const struct pt_regs* regs)
{
int ret = 0;
if (!task_ctx)
return ref_sys_process(regs, __NR_socket, sc_socket_type);
ret = check_if_hook(sc_socket_type);
if (ret < 0)
return ref_sys_process(regs, __NR_socket, sc_socket_type);
return sc_hook_process(sc_socket_type, ret, NULL);
}
static long asmlinkage hook_bind(const struct pt_regs* regs)
{
int ret = 0;
if (!task_ctx)
return ref_sys_process(regs, __NR_bind, sc_bind_type);
ret = check_if_hook(sc_bind_type);
if (ret < 0)
return ref_sys_process(regs, __NR_bind, sc_bind_type);
return sc_hook_process(sc_bind_type, ret, NULL);
}
static asmlinkage long hook_listen(const struct pt_regs* regs)
{
int ret = 0;
if (!task_ctx)
return ref_sys_process(regs, __NR_listen, sc_listen_type);
ret = check_if_hook(sc_listen_type);
if (ret < 0)
return ref_sys_process(regs, __NR_listen, sc_listen_type);
return sc_hook_process(sc_listen_type, ret, NULL);
}
static asmlinkage long hook_mount(const struct pt_regs* regs)
{
int ret = 0;
if (!task_ctx)
return ref_sys_process(regs, __NR_mount, sc_mount_type);
ret = check_if_hook(sc_mount_type);
if (ret < 0)
return ref_sys_process(regs, __NR_mount, sc_mount_type);
return sc_hook_process(sc_mount_type, ret, NULL);
}
static asmlinkage long hook_umount(const struct pt_regs* regs)
{
int ret = 0;
if (!task_ctx)
return ref_sys_process(regs, __NR_umount2, sc_umount2_type);
ret = check_if_hook(sc_umount2_type);
if (ret < 0)
return ref_sys_process(regs, __NR_umount2, sc_umount2_type);
return sc_hook_process(sc_umount2_type, ret, NULL);
}
static asmlinkage long hook_ioctl(const struct pt_regs* regs)
{
int ret = 0;
if (!task_ctx)
return ref_sys_process(regs, __NR_ioctl, sc_ioctl_type);
ret = check_if_hook(sc_ioctl_type);
if (ret < 0)
return ref_sys_process(regs, __NR_ioctl, sc_ioctl_type);
return sc_hook_process(sc_ioctl_type, ret, NULL);
}
# else
typedef long (*open_sys)(const char __user* filename, int flags, int mode);
static long ref_open_process(const char __user* filename, int flags, int mode,
int sc_idx, int sc_type)
{
int ret = 0;
atomic_inc(&sc_ref_table[sc_type]);
ret = ((open_sys) old_sys_table[sc_idx])(filename, flags, mode);
atomic_dec(&sc_ref_table[sc_type]);
return ret;
}
static asmlinkage long hook_open(const char __user* filename, int flags, int mode)
{
char filetemp[256] = {0};
int ret = 0;
if (copy_from_user(filetemp, filename, sizeof(filetemp)))
{
return ref_open_process(filename, flags, mode, __NR_open, sc_open_type);
}
if (!task_ctx)
return ref_open_process(filename, flags, mode, __NR_open, sc_open_type);
ret = check_if_hook(sc_open_type);
if (ret < 0)
return ref_open_process(filename, flags, mode, __NR_open, sc_open_type);
return sc_hook_process(sc_open_type, ret, filetemp);
}
typedef long (*fs_sys)(unsigned int fd, const char __user* buf, size_t count);
static long ref_fs_process(unsigned int fd, const char __user* buf, size_t count, int sc_idx, int sc_type)
{
int ret = 0;
atomic_inc(&sc_ref_table[sc_type]);
ret = ((fs_sys) old_sys_table[sc_idx])(fd, buf, count);
atomic_dec(&sc_ref_table[sc_type]);
return ret;
}
static asmlinkage long hook_read(unsigned int fd, char __user* buf, size_t count)
{
int ret = 0;
if (!task_ctx)
return ref_fs_process(fd, buf, count, __NR_read, sc_read_type);
ret = check_if_hook(sc_read_type);
if (ret < 0) return ref_fs_process(fd, buf, count, __NR_read, sc_read_type);
return sc_hook_process(sc_read_type, ret, NULL);
}
static asmlinkage long hook_write(unsigned int fd, const char __user* buf, size_t count)
{
int ret = 0;
if (!task_ctx || fd <= 2)
return ref_fs_process(fd, buf, count, __NR_write, sc_write_type);
ret = check_if_hook(sc_write_type);
if (ret < 0)
return ref_fs_process(fd, buf, count, __NR_write, sc_write_type);
return sc_hook_process(sc_write_type, ret, NULL);
}
typedef long (*socket_sys)(int family, int type, int protocol);
static long ref_socket_process(int family, int type, int protocol, int sc_idx, int sc_type)
{
int ret = 0;
atomic_inc(&sc_ref_table[sc_type]);
ret = ((socket_sys) old_sys_table[sc_idx])(family, type, protocol);
atomic_dec(&sc_ref_table[sc_type]);
return ret;
}
static asmlinkage long hook_socket(int family, int type, int protocol)
{
int ret = 0;
if (!task_ctx)
return ref_socket_process(family, type, protocol, __NR_socket, sc_socket_type);
ret = check_if_hook(sc_socket_type);
if (ret < 0)
return ref_socket_process(family, type, protocol, __NR_socket, sc_socket_type);
return sc_hook_process(sc_socket_type, ret, NULL);
}
typedef long (*bind_sys)(int fd, struct sockaddr __user *umyaddr, int addrlen);
static long ref_bind_process(int fd, struct sockaddr __user *umyaddr, int addrlen, int sc_idx, int sc_type)
{
int ret = 0;
atomic_inc(&sc_ref_table[sc_type]);
ret = ((bind_sys) old_sys_table[sc_idx])(fd, umyaddr, addrlen);
atomic_dec(&sc_ref_table[sc_type]);
return ret;
}
static long asmlinkage hook_bind(int fd, struct sockaddr __user *umyaddr, int addrlen)
{
int ret = 0;
if (!task_ctx)
return ref_bind_process(fd, umyaddr, addrlen, __NR_bind, sc_bind_type);
ret = check_if_hook(sc_bind_type);
if (ret < 0)
return ref_bind_process(fd, umyaddr, addrlen, __NR_bind, sc_bind_type);
return sc_hook_process(sc_bind_type, ret, NULL);
}
typedef long (*listen_sys)(int fd, int backlog);
static long ref_listen_process(int fd, int backlog, int sc_idx, int sc_type)
{
int ret = 0;
atomic_inc(&sc_ref_table[sc_type]);
ret = ((listen_sys) old_sys_table[sc_idx])(fd, backlog);
atomic_dec(&sc_ref_table[sc_type]);
return ret;
}
static asmlinkage long hook_listen(int fd, int backlog)
{
int ret = 0;
if (!task_ctx)
return ref_listen_process(fd, backlog, __NR_listen, sc_listen_type);
ret = check_if_hook(sc_listen_type);
if (ret < 0)
return ref_listen_process(fd, backlog, __NR_listen, sc_listen_type);
return sc_hook_process(sc_listen_type, ret, NULL);
}
typedef long (*netp_sys)(int, struct sockaddr __user*, int __user*);
static long ref_netp_process(int fd, struct sockaddr __user* user, int __user* id, int sc_idx, int sc_type)
{
int ret = 0;
atomic_inc(&sc_ref_table[sc_type]);
ret = ((netp_sys) old_sys_table[sc_idx])(fd, user, id);
atomic_dec(&sc_ref_table[sc_type]);
return ret;
}
static asmlinkage long hook_accept(int fd, struct sockaddr __user* user, int __user* id)
{
int ret = 0;
if (!task_ctx)
return ref_netp_process(fd, user, id, __NR_accept, sc_accept_type);
ret = check_if_hook(sc_accept_type);
if (ret < 0)
return ref_netp_process(fd, user, id, __NR_accept, sc_accept_type);
return sc_hook_process(sc_accept_type, ret, NULL);
}
typedef long (*neti_sys)(int, struct sockaddr __user*, int);
static long ref_neti_process(int fd, struct sockaddr __user* user, int id, int sc_idx, int sc_type)
{
int ret = 0;
atomic_inc(&sc_ref_table[sc_type]);
ret = ((neti_sys) old_sys_table[sc_idx])(fd, user, id);
atomic_dec(&sc_ref_table[sc_type]);
return ret;
}
static asmlinkage long hook_connect(int fd, struct sockaddr __user* user, int id)
{
int ret = 0;
if (!task_ctx)
return ref_neti_process(fd, user, id, __NR_connect, sc_connect_type);
ret = check_if_hook(sc_connect_type);
if (ret < 0)
return ref_neti_process(fd, user, id, __NR_connect, sc_connect_type);
return sc_hook_process(sc_connect_type, ret, NULL);
}
typedef long (*netli_sys)(int, void __user*, size_t, unsigned, struct sockaddr __user*, int);
static long ref_netli_process(int fd, void __user* user, size_t len, unsigned id, struct sockaddr __user* addr, int l_len, int sc_idx, int sc_type)
{
int ret = 0;
atomic_inc(&sc_ref_table[sc_type]);
ret = ((netli_sys) old_sys_table[sc_idx])(fd, user, len, id, addr, l_len);
atomic_dec(&sc_ref_table[sc_type]);
return ret;
}
static asmlinkage long hook_sendto(int fd, void __user* user, size_t len, unsigned id, struct sockaddr __user* addr, int l_len)
{
int ret = 0;
if (!task_ctx)
return ref_netli_process(fd, user, len, id, addr, l_len, __NR_sendto, sc_send_type);
ret = check_if_hook(sc_send_type);
if (ret < 0)
return ref_netli_process(fd, user, len, id, addr, l_len, __NR_sendto, sc_send_type);
return sc_hook_process(sc_send_type, ret, NULL);
}
typedef long (*netlp_sys)(int, void __user*, size_t, unsigned, struct sockaddr __user*, int __user*);
static long ref_netlp_process(int fd, void __user* user, size_t len, unsigned id, struct sockaddr __user* addr, int __user* l_len, int sc_idx, int sc_type)
{
int ret = 0;
atomic_inc(&sc_ref_table[sc_type]);
ret = ((netlp_sys) old_sys_table[sc_idx])(fd, user, len, id, addr, l_len);
atomic_dec(&sc_ref_table[sc_type]);
return ret;
}
static asmlinkage long hook_recvfrom(int fd, void __user* user, size_t len, unsigned id, struct sockaddr __user* addr, int __user* l_len)
{
int ret = 0;
if (!task_ctx)
return ref_netlp_process(fd, user, len, id, addr, l_len, __NR_recvfrom, sc_recv_type);
ret = check_if_hook(sc_recv_type);
if (ret < 0)
return ref_netlp_process(fd, user, len, id, addr, l_len, __NR_recvfrom, sc_recv_type);
return sc_hook_process(sc_recv_type, ret, NULL);
}
typedef long (*mount_sys)(char __user *dev_name, char __user *dir_name, char __user *type, unsigned long flags, void __user *data);
static long ref_mount_process(char __user *dev_name, char __user *dir_name, char __user *type, unsigned long flags, void __user *data, int sc_idx, int sc_type)
{
int ret = 0;
atomic_inc(&sc_ref_table[sc_type]);
ret = ((mount_sys) old_sys_table[sc_idx])(dev_name, dir_name, type, flags, data);
atomic_dec(&sc_ref_table[sc_type]);
return ret;
}
static asmlinkage long hook_mount(char __user *dev_name, char __user *dir_name, char __user *type, unsigned long flags, void __user *data)
{
int ret = 0;
if (!task_ctx)
return ref_mount_process(dev_name, dir_name, type, flags, data, __NR_mount, sc_mount_type);
ret = check_if_hook(sc_mount_type);
if (ret < 0)
return ref_mount_process(dev_name, dir_name, type, flags, data, __NR_mount, sc_mount_type);
return sc_hook_process(sc_mount_type, ret, NULL);
}
typedef long (*umount_sys)(char __user *name, int flags);
static long ref_umount_process(char __user *name, int flags, int sc_idx, int sc_type)
{
int ret = 0;
atomic_inc(&sc_ref_table[sc_type]);
ret = ((umount_sys) old_sys_table[sc_idx])(name, flags);
atomic_dec(&sc_ref_table[sc_type]);
return ret;
}
static asmlinkage long hook_umount(char __user *name, int flags)
{
int ret = 0;
if (!task_ctx)
return ref_umount_process(name, flags, __NR_umount2, sc_umount2_type);
ret = check_if_hook(sc_umount2_type);
if (ret < 0)
return ref_umount_process(name, flags, __NR_umount2, sc_umount2_type);
return sc_hook_process(sc_umount2_type, ret, NULL);
}
typedef long (*ioctl_sys)(unsigned int fd, unsigned int cmd, unsigned long arg);
static long ref_ioctl_process(unsigned int fd, unsigned int cmd, unsigned long arg, int sc_idx, int sc_type)
{
int ret = 0;
atomic_inc(&sc_ref_table[sc_type]);
ret = ((ioctl_sys) old_sys_table[sc_idx])(fd, cmd, arg);
atomic_dec(&sc_ref_table[sc_type]);
return ret;
}
static asmlinkage long hook_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
int ret = 0;
if (!task_ctx)
return ref_ioctl_process(fd, cmd, arg, __NR_ioctl, sc_ioctl_type);
ret = check_if_hook(sc_ioctl_type);
if (ret < 0)
return ref_ioctl_process(fd, cmd, arg, __NR_ioctl, sc_ioctl_type);
return sc_hook_process(sc_ioctl_type, ret, NULL);
}
typedef long (*lseek_sys)(unsigned int fd, off_t offset, unsigned int whence);
static long ref_lseek_process(unsigned int fd, off_t offset, unsigned int whence, int sc_idx, int sc_type)
{
int ret = 0;
atomic_inc(&sc_ref_table[sc_type]);
ret = ((lseek_sys) old_sys_table[sc_idx])(fd, offset, whence);
atomic_dec(&sc_ref_table[sc_type]);
return ret;
}
static asmlinkage long hook_lseek(unsigned int fd, off_t offset, unsigned int whence)
{
int ret = 0;
if (!task_ctx)
return ref_lseek_process(fd, offset, whence, __NR_lseek, sc_lseek_type);
ret = check_if_hook(sc_lseek_type);
if (ret < 0)
return ref_lseek_process(fd, offset, whence, __NR_lseek, sc_lseek_type);
return sc_hook_process(sc_lseek_type, ret, NULL);
}
typedef long (*fsync_sys)(unsigned int fd);
static long ref_fsync_process(unsigned int fd, int sc_idx, int sc_type)
{
int ret = 0;
atomic_inc(&sc_ref_table[sc_type]);
ret = ((fsync_sys) old_sys_table[sc_idx])(fd);
atomic_dec(&sc_ref_table[sc_type]);
return ret;
}
static asmlinkage long hook_fsync(unsigned int fd)
{
int ret = 0;
if (!task_ctx)
return ref_fsync_process(fd, __NR_fsync, sc_fsync_type);
ret = check_if_hook(sc_fsync_type);
if (ret < 0)
return ref_fsync_process(fd, __NR_fsync, sc_fsync_type);
return sc_hook_process(sc_fsync_type, ret, NULL);
}
# endif // end for PTREGS_SYSCALL_STUBS
#endif // end for SC_FUNC_PART
#define LOCAL_FUNC
#ifdef LOCAL_FUNC
#if 1
//初版
static int sysm_info_mgr(sys_call_ptr_t hook_fn, int sc_idx, int sc_type)
{
hook_sys_table[sc_type] = sc_idx;
printk("sysm_info_mgr sc_type:%d,index:%d \n", sc_type, sc_idx);
strcpy(hook_sys_name[sc_type], cur_module);
old_sys_table[sc_idx] = sys_call_table[sc_idx];
printk("sysm_info_mgr sc_type,index999999999999999999\n");
printk("准备读写入内核操作\n");
disable_write_protect();
sys_call_table[sc_idx] = hook_fn;
enable_write_protect();
printk("准备读写入内核操作完成9999999\n");
return 0;
}
#endif
#if 0
//初版
static void release_sc(void)
{
int i = 0;
int timer = 0;
bool bFInd = true;
long long timecount = 0;
disable_write_protect();
for (; i < sc_end_type; i++) {
sys_call_table[hook_sys_table[i]] = old_sys_table[hook_sys_table[i]];
printk("system-call:%dindex:%d \n", i, hook_sys_table[i]);
}
enable_write_protect();
/* unload system-call is tough trouble, i will explain it for you as the
* followings as we all know, system-call may in a blocked state.
* something horrible may happen when we do release_sc while a process
* stuck in a blocked state by system-call. cus the code segment was
* freed once we rmmod the ko. however, when blocked systerm-call wake
* up, it returns to the disappreared code segment. and this case may
* panic kernel.
*
* to prevent this happen, i have tryed a lot ways but not found a
* perfect one till now. a sc-reference protected by lock may work, but
* i give it up for the perfomance, use a atomic value instead! anyway,
* this is a dangerous function. remember to FIXME when you got an
* better idea
*/
while (1) { //如果某个系统调用被频繁使用,引用计数可能永远不会降为0,导致无限等待,会不会出现这种情况呢。
// every 1s tells users that where we stuck in
if (timer / 1000 >= 1) {
timer = 0;
for (i = 0; i < sc_end_type; i++) {
if (atomic_read(&sc_ref_table[i]) > 0) {
bFInd = false;
printk("system-call:%s is in use(%d) now, wait it to "
"exit\n",
hook_sys_name[i],
atomic_read(&sc_ref_table[i]));
}
}
if (bFInd) {
printk("module-sc-%s removed.\n", hook_sys_name[i]);
break;
}
}
msleep(ms_nap);
timer += ms_nap;
timecount += ms_nap;
if (timecount > 10 * 1000) {
printk("module-sc-%s removed.\n", hook_sys_name[i]);
break;
}
}
}
#endif
#if 1
//rmmod卸载问题修改
static void release_sc(void)
{
int i = 0;
int wait_count = 0;
const int MAX_WAIT = 300; // 最大等待30秒 (300 * 100ms)
// 1. 首先解除所有钩子
disable_write_protect();
for (i = 0; i < sc_end_type; i++) {
if (hook_sys_table[i] > 0) {
sys_call_table[hook_sys_table[i]] = old_sys_table[hook_sys_table[i]];
printk("unhook system-call:%d, index:%d\n", i, hook_sys_table[i]);
}
}
enable_write_protect();
// 2. 等待引用计数归零,但有超时机制
for (wait_count = 0; wait_count < MAX_WAIT; wait_count++) {
bool all_zero = true;
for (i = 0; i < sc_end_type; i++) {
int ref_count = atomic_read(&sc_ref_table[i]);
if (ref_count > 0) {
all_zero = false;
if (wait_count % 10 == 0) { // 每1秒打印一次
printk("waiting for %s, refcount: %d\n",
hook_sys_name[i], ref_count);
}
break;
}
}
if (all_zero) {
printk("all system calls released successfully\n");
break;
}
msleep(100); // 等待100ms
}
if (wait_count >= MAX_WAIT) {
printk("warning: forced unload after timeout, some syscalls may still be in use\n");
}
// 3. 清理状态
for (i = 0; i < sc_end_type; i++) {
hook_sys_table[i] = 0;
hook_sys_name[i][0] = '\0';
}
}
#endif
#endif
#if 1
//初版
//挂钩子崩溃
static int sc_reg(void)
{
int i = 0;
int ret = 0;
for (; i < sc_end_type; i++) {
atomic_set(&sc_ref_table[i], 0);
}
// hook open
cur_module = "open";
# ifdef PTREGS_SYSCALL_STUBS
ret = sysm_info_mgr(hook_open, __NR_openat, sc_open_type);
# else
ret = sysm_info_mgr((sys_call_ptr_t) hook_open, __NR_open, sc_open_type);
# endif
if (0 != ret) {
printk("ERROR: hook %s failed\n", cur_module);
return 1;
}
else {
printk("module-sc-%s inserted.\n", hook_sys_name[sc_open_type]);
}
// hook read
cur_module = "read";
ret = sysm_info_mgr((sys_call_ptr_t) hook_read, __NR_read, sc_read_type);
if (0 != ret) {
printk("ERROR: hook %s failed\n", cur_module);
return 1;
}
else {
printk("module-sc-%s inserted.\n", hook_sys_name[sc_read_type]);
}
// hook write
cur_module = "write";
ret = sysm_info_mgr((sys_call_ptr_t) hook_write, __NR_write, sc_write_type);
if (0 != ret) {
printk("ERROR: hook %s failed\n", cur_module);
return 1;
}
else {
printk("module-sc-%s inserted.\n", hook_sys_name[sc_write_type]);
}
// hook lseek
cur_module = "hook_lseek";
ret = sysm_info_mgr((sys_call_ptr_t) hook_lseek, __NR_lseek, sc_lseek_type);
if (0 != ret)
{
printk("ERROR: hook %s failed\n", cur_module);
return 1;
}
else
{
printk("module-sc-%s inserted.\n", hook_sys_name[sc_lseek_type]);
}
// hook fsync
cur_module = "hook_fsync";
ret = sysm_info_mgr((sys_call_ptr_t) hook_fsync, __NR_fsync, sc_fsync_type);
if (0 != ret)
{
printk("ERROR: hook %s failed\n", cur_module);
return 1;
}
else
{
printk("module-sc-%s inserted.\n", hook_sys_name[sc_fsync_type]);
}
// hook socket
cur_module = "socket";
ret = sysm_info_mgr((sys_call_ptr_t) hook_socket, __NR_socket, sc_socket_type);
if (0 != ret) {
printk("ERROR: hook %s failed\n", cur_module);
return 1;
}
else {
printk("module-sc-%s inserted.\n", hook_sys_name[sc_socket_type]);
}
//hook bind
cur_module = "bind";
ret = sysm_info_mgr((sys_call_ptr_t) hook_bind, __NR_bind, sc_bind_type);
if (0 != ret) {
printk("ERROR: hook %s failed\n", cur_module);
return 1;
}
else {
printk("module-sc-%s inserted.\n", hook_sys_name[sc_bind_type]);
}
//hook listen
cur_module = "listen";
ret = sysm_info_mgr((sys_call_ptr_t) hook_listen, __NR_listen, sc_listen_type);
if (0 != ret) {
printk("ERROR: hook %s failed\n", cur_module);
return 1;
}
else {
printk("module-sc-%s inserted.\n", hook_sys_name[sc_listen_type]);
}
// hook accept
cur_module = "accept";
ret = sysm_info_mgr(
(sys_call_ptr_t) hook_accept, __NR_accept, sc_accept_type);
if (0 != ret) {
printk("ERROR: hook %s failed\n", cur_module);
return 1;
}
else {
printk("module-sc-%s inserted.\n", hook_sys_name[sc_accept_type]);
}
// hook connect
cur_module = "connect";
ret = sysm_info_mgr((sys_call_ptr_t) hook_connect, __NR_connect, sc_connect_type);
if (0 != ret) {
printk("ERROR: hook %s failed\n", cur_module);
return 1;
}
else {
printk("module-sc-%s inserted.\n", hook_sys_name[sc_connect_type]);
}
// hook send/sendto
cur_module = "sendto-send";
ret =
sysm_info_mgr((sys_call_ptr_t) hook_sendto, __NR_sendto, sc_send_type);
if (0 != ret) {
printk("ERROR: hook %s failed\n", cur_module);
return 1;
}
else {
printk("module-sc-%s inserted.\n", hook_sys_name[sc_send_type]);
}
// hook recv/recvfrom
cur_module = "recvfrom-recv";
ret = sysm_info_mgr(
(sys_call_ptr_t) hook_recvfrom, __NR_recvfrom, sc_recv_type);
if (0 != ret) {
printk("ERROR: hook %s failed\n", cur_module);
return 1;
}
else {
printk("module-sc-%s inserted.\n", hook_sys_name[sc_recv_type]);
}
// hook mount
cur_module = "mount";
ret = sysm_info_mgr((sys_call_ptr_t) hook_mount, __NR_mount, sc_mount_type);
if (0 != ret)
{
printk("ERROR: hook %s failed\n", cur_module);
return 1;
}
else
{
printk("module-sc-%s inserted.\n", hook_sys_name[sc_mount_type]);
}
// hook umount
cur_module = "umount";
ret = sysm_info_mgr((sys_call_ptr_t) hook_umount, __NR_umount2, sc_umount2_type);
if (0 != ret)
{
printk("ERROR: hook %s failed\n", cur_module);
return 1;
}
else
{
printk("module-sc-%s inserted.\n", hook_sys_name[sc_umount2_type]);
}
// hook ioctl
cur_module = "hook_ioctl";
ret = sysm_info_mgr((sys_call_ptr_t) hook_ioctl, __NR_ioctl, sc_ioctl_type);
if (0 != ret)
{
printk("ERROR: hook %s failed\n", cur_module);
return 1;
}
else
{
printk("module-sc-%s inserted.\n", hook_sys_name[sc_ioctl_type]);
}
// FIXME TODO HERE
return 0;
}
#endif
static int reader_thread(void *data) {
while (!kthread_should_stop())
{
// printk(KERN_INFO "test content: %s\n", test);
// printk(KERN_INFO "buffer content: %s\n", buffer);
printk(KERN_INFO "process: %s\n", task_ctx->sc_task[1].process);
printk(KERN_INFO "pid: %s\n", task_ctx->sc_task[1].pid);
printk(KERN_INFO "start_time: %d\n", task_ctx->sc_task[1].start_time);
msleep(1000); // Sleep for 1 second
}
return 0;
}
static int __init scm_init(void)
{
// get sys_call_table
sys_call_table = get_sysm_name();//内核,获取系统调用表
if (!sys_call_table)
{
printk("%s-%s insert error, no sys_call_table\n", MODULE_NAME, __func__);
return 1;
}
if (0 != sc_reg()) goto release_resource;
printk(KERN_INFO "不挂钩子正常获取到了内核table1111111111111111");
// netfiletr mode init
if (nf)
{
if (0 != nf_reg())
{
printk("netfilter-%s insert error,失败99999999999, register failed\n", __func__);
goto release_resource;
}
printk("%s-%s inserted with nf,成功999999999999999999999999\n", MODULE_NAME, __func__);
}
else
{
printk("%s-%s inserted without nf\n", MODULE_NAME, __func__);
}
// shm module init
if (insert_dev)
{
// shm_size = sizeof(chaosRunTaskCtlTabInline);
printk("shm初始化成功91111111111111111\n");
printk("dev_reg-------------------\n");
if (0 != dev_reg())
{
printk("%s-%s insert error, dev register failed\n",MODULE_NAME,__func__);
goto release_resource;
}
printk("%s-%s inserted with dev\n", MODULE_NAME, __func__);
}
else
{
printk("%s-%s inserted without dev\n", MODULE_NAME, __func__);
}
// kthread = kthread_run(reader_thread, NULL, "sc_hook");
printk("task_ctx is %p, shm_size is %d(%lu)-----------------\n", task_ctx, shm_size, sizeof(chaosRunTaskCtlTabInline));
if(task_ctx)
{
printk("task_ctx init\n");
}
else
{
printk("task_ctx init error\n");
}
return 0;
release_resource:
release_sc();
nf_unreg();
return 1;
}
#if 0
//初版
static void __exit scm_exit(void)
{
if (insert_dev) dev_unreg();
printk("release nf\n");
if (nf) nf_unreg();
release_sc();
printk("%s-%s removed.\n", MODULE_NAME, __func__);
// wait for a while for safety
printk("wait netfilter exit(%dms)\n", NF_TIMEOUT);
msleep(NF_TIMEOUT);
printk("release shm dev:%s\n", MODULE_NAME);
}
#endif
//rmmod卸载问题
static void __exit scm_exit(void)
{
printk("starting module unload...\n");
// 2. 释放系统调用钩子
printk("releasing system call hooks...\n");
release_sc();
// 3. 释放netfilter
printk("releasing netfilter...\n");
if (nf) nf_unreg();
// 4. 最后释放设备
printk("releasing device...\n");
if (insert_dev) dev_unreg();
printk("%s-%s removed successfully.\n", MODULE_NAME, __func__);
}
module_init(scm_init);
module_exit(scm_exit);在调用钩子函数时disable_write_protect总是崩溃,我想知道在arm架构下的读写还可以怎么实现
最新发布