asmlinkage

内核中有些函数有asmlinkage修饰符,比如:

这里基于5.15.133版本分析一下这个“修饰符”。

asmlinkage本身是个宏定义,X86/IA64以外的架构定义在include/linux/linkage.h头文件中。

也就是asmlinkage本身就是extern “C”。

主要的目的是让C++程序能够调用到这个C语言定义的函数。

比如下面的程序:

main.c:

callee.c:

我们用gcc命令进行编译的时候会报undefined reference错误。

如果给hello函数加个extern “C”,

编译会顺利进行。

#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架构下的读写还可以怎么实现
最新发布
10-22
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值