Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 尝试挂接linux内核系统调用_C_Linux Kernel_Hook - Fatal编程技术网

C 尝试挂接linux内核系统调用

C 尝试挂接linux内核系统调用,c,linux-kernel,hook,C,Linux Kernel,Hook,我正在尝试从linux内核自定义模块钩住一个系统调用 模块加载,但似乎没有从新函数向dmesg打印任何内容 #include <linux/kernel.h> #include <linux/module.h> #include <linux/unistd.h> #include <linux/kallsyms.h> void **sys_call_table; int (*original_call) (const char*, int, m

我正在尝试从linux内核自定义模块钩住一个系统调用

模块加载,但似乎没有从新函数向dmesg打印任何内容

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/unistd.h>
#include <linux/kallsyms.h>

void **sys_call_table;

int (*original_call) (const char*, int, mode_t);

int our_sys_open(const char* file, int flags, mode_t mode)
{
   printk(KERN_INFO "A file was opened\n");

   return original_call(file, flags, mode);
}

void set_addr_rw(unsigned long addr)
{
    unsigned int level;
    pte_t *pte = lookup_address(addr, &level);

    if (pte->pte &~ _PAGE_RW) pte->pte |= _PAGE_RW;
}

void set_addr_ro(unsigned long addr)
{
    unsigned int level;
    pte_t *pte = lookup_address(addr, &level);

    pte->pte = pte->pte &~_PAGE_RW;
}

int init_module()
{
    printk("Loading custom module\n");

    sys_call_table = (void *) kallsyms_lookup_name("sys_call_table");
    original_call = sys_call_table[__NR_open];

    set_addr_rw((unsigned long) sys_call_table);
    sys_call_table[__NR_open] = our_sys_open;

    return 0;
}

void cleanup_module()
{
    printk("Unloading custom module\n");

    // Restore the original call
    sys_call_table[__NR_open] = original_call;

    set_addr_ro((unsigned long) sys_call_table);
}

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple Module");
MODULE_AUTHOR("OTO");
MODULE_VERSION("0.1");
模块加载后:

crash> x/1g &sys_call_table[2]
0xffffffffb7c013b0:     0xffffffffb6eda7e0
crash> x/1g &sys_call_table[2]
0xffffffffb7c013b0:     0xffffffffc06d508f

所以,变化实际上正在发生。

结果我不得不替换
openat
,而不是
open
。你这样做的方式是:

#include <linux/module.h>
#include <linux/kallsyms.h>
#include <asm/uaccess.h>
#include <linux/ratelimit.h>
​
MODULE_LICENSE("GPL");
​
asmlinkage int (*old_openat)(const struct pt_regs *);
static void **sys_call_table;
​
static asmlinkage long my_openat(const struct pt_regs *regs)
{
    printk_ratelimited("%s. proc:%s, pid:%d\n", __func__, current->group_leader->comm, current->tgid);
​
    return old_openat(regs);
}
​
void disable_write_protect(void)
{
    unsigned long value;
    asm volatile("mov %%cr0,%0" : "=r" (value));
    if (value & 0x00010000)
    {
        value &= ~0x00010000;
        asm volatile("mov %0,%%cr0": : "r" (value));
    }
}
​
void enable_write_protect(void)
{
    unsigned long value;
    asm volatile("mov %%cr0,%0" : "=r" (value));
    if (!(value & 0x00010000))
    {
        value |= 0x00010000;
        asm volatile("mov %0,%%cr0": : "r" (value));
    }
}
​
static int __init test_init(void)
{
    sys_call_table = (void *)kallsyms_lookup_name("sys_call_table");
    old_openat = sys_call_table[__NR_openat];
​
    printk("[info] %s. old_openat:0x%p\n", __func__, old_openat);
​
    disable_write_protect();
    sys_call_table[__NR_openat] = my_openat;
    enable_write_protect();
​
    printk("%s inserted.\n",__func__);
​
    return 0;
}
​
static void __exit test_exit(void)
{
    disable_write_protect();
    sys_call_table[__NR_openat] = old_openat;
    enable_write_protect();
​
    printk("%s removed.\n",__func__);
}
​
module_init(test_init);
module_exit(test_exit);
#包括
#包括
#包括
#包括
​
模块许可证(“GPL”);
​
ASMINT(*old_openat)(const struct pt_regs*);
静态无效**系统调用表;
​
静态链接长my_openat(常量结构pt_regs*regs)
{
printk_ratelimited(“%s.proc:%s,pid:%d\n”,\u func\u,current->group\u leader->comm,current->tgid);
​
返回旧的_openat(regs);
}
​
无效禁用\写入\保护(无效)
{
无符号长值;
asm易失性(“mov%%cr0,%0”:“=r”(值));
if(值&0x00010000)
{
值&=~0x00010000;
asm易失性(“mov%0,%%cr0”::“r”(值));
}
}
​
作废启用\写入\保护(作废)
{
无符号长值;
asm易失性(“mov%%cr0,%0”:“=r”(值));
如果(!(值&0x00010000))
{
值|=0x00010000;
asm易失性(“mov%0,%%cr0”::“r”(值));
}
}
​
静态整数初始化测试初始化(无效)
{
sys_call_table=(void*)kallsyms_lookup_name(“sys_call_table”);
old_openat=sys_call_table[\uu NR_openat];
​
printk(“[info]%s.old\u openat:0x%p\n”,\u func\u,old\u openat);
​
禁用写入保护();
sys\u call\u table[\uu NR\u openat]=my\u openat;
启用写入保护();
​
printk(“%s inserted.\n”,\uuuu func\uuuu);
​
返回0;
}
​
静态无效uuu退出测试u退出(无效)
{
禁用写入保护();
sys\u call\u table[\uu NR\u openat]=old\u openat;
启用写入保护();
​
printk(“%s已删除。\n”,\uuuu func\uuuu);
}
​
模块初始化(测试初始化);
模块退出(测试退出);

尝试运行
grep
以获取同一目录中的部分
printk()
字符串。运行
dmesg
有什么有趣的输出吗?您还可以查看控制台输出吗?grepping没有给出任何结果,而
dmesg
tail/var/log/kern.log
给出了相同的结果:“加载自定义模块”(从init_模块),仅此而已。那么,控制台输出是什么意思?