需要编写一个内核模块,带有一个exec的钩子.我找到了sys_calls_tablelsm的方法.据我所知,sys_calls_table更像是一个黑客而不是一个正确的解决方案,我没有找到lsm的正常例子.

如何在现代内核版本中正确拦截系统调用?我很乐意举一些例子.

推荐答案

没有正确的方法可以做到这一点.

LSM(Linux安全模块)不支持系统调用拦截,

据我所知,有两种截获系统调用的替代方法:

  1. 钩住可以获得的sys_call_table,并用新函数覆盖指针:

    unsigned long *sys_call_table_ptr = kallsyms_lookup_name("sys_call_table");
    unsigned long cr0 = read_cr0();
    write_cr0(cr0 & ~x86_CR0_WP);
    sys_call_table_ptr[__NR_getpid] = new_getpid;
    write_cr0(cr0);
    
  2. 使用kprobe:Syscall函数,函数名以前缀__do_sys_展开(请参见__SYSCALL_DEFINEx).

    static struct kprobe kp = {
        .symbol_name    = "__do_sys_finit_module",
    };
    
    static int handler_pre(struct kprobe *p, struct pt_regs *regs) {
        // do your logic
        // obtain function arguments using register (calling convetion)
    }
    
    static int __init kprobe_init(void)
    {
        kp.pre_handler = handler_pre;
        ret = register_kprobe(&kp);
        if (ret < 0) {
            printk(KERN_INFO "register_kprobe failed, returned %d\n", ret);
            return ret;
        }
        printk(KERN_INFO "Planted kprobe at %p\n", kp.addr);
        return 0;
    }
    
    static void __exit kprobe_exit(void)
    {
        unregister_kprobe(&kp);
        printk(KERN_INFO "kprobe at %p unregistered\n", kp.addr);
    }
    

C++相关问答推荐

使用sd-设备列举设备导致seg错误

带双指针的2D数组

try 使用sigqueue函数将指向 struct 体的指针数据传递到信号处理程序,使用siginfo_t struct 体从一个进程传递到另一个进程

如何将已分配的数组(运行时已知的大小)放入 struct 中?

如何确保在C程序中将包含uft8字符的字符串正确写入MySQL?

每次除以或乘以整数都会得到0.0000

FRIDA-服务器成为端口扫描的目标?

在进程之间重定向输出和输入流的问题

Tic-tac-toe:从文件加载存储

按长度对argv中的单词进行排序

如何在双向表中实现线程安全,每个条目仅使用4位,同时避免任何全局锁?

将回调/基于事件的C API转换为非回调API

使用Open62541向OPCUA服务器发送读请求时内存泄漏

如何将两个uint32_t值交织成一个uint64_t?

如何在C宏定义中包含双引号?

C:面筋蛋白';为什么不刷新窗口?

解密Chrome加密密钥

通过char*访问指针的对象表示是未定义的行为吗?

比 * 更快的乘法

OpenGL 中的非渐变 colored颜色 变化