linux arm 5.4 在内核中如何hook 系统调用

linux arm 5.4 在内核中如何hook 系统调用,__NR_evecve,
代码简要如下:

typedef long (*syscall_fn_t)(const struct pt_regs *regs);
init(){
update_mapping_prot = (void *)kallsyms_lookup_name("update_mapping_prot");
 start_rodata = (unsigned long)kallsyms_lookup_name("__start_rodata");
 init_begin= (unsigned long)kallsyms_lookup_name("__init_begin");
hook_table_addr=(unsigned long)kallsyms_lookup_name("sys_call_table");
stop_machine(hook_do,NULL,0);
}
hook_do(){
disable_wirte_protection();
p_call[__NR_execve]=(syscall_fn_t )hook_stub_execve;
enable_wirte_protection();
}
hook_stub_execve()
{
return old_execve_addr(pt_regs);
}

hook后系统无法执行任何程序

引用 皆我百晓生 小程序回复内容作答:
在Linux ARM内核中,要hook系统调用,可以按照以下步骤进行操作:

  1. 首先,获取sys_call_table的地址。sys_call_table是一个数组,存储了系统调用的函数指针。可以使用kallsyms_lookup_name函数来获取它的地址。

  2. 然后,禁用写保护。Linux内核默认会将sys_call_table设置为只读,需要禁用写保护才能修改其中的函数指针。

  3. 接下来,将需要hook的系统调用的函数指针替换为自定义的hook函数。你提到的是想hook execve系统调用,所以将__NR_execve对应的函数指针替换为自定义的hook_stub_execve函数。

  4. 最后,启用写保护,确保sys_call_table的修改生效。

下面是代码示例:

#include <linux/kallsyms.h>
#include <linux/stop_machine.h>
#include <linux/pt_regs.h>

#define __NR_execve 11

typedef long (*syscall_fn_t)(const struct pt_regs *regs);

static void disable_write_protection(void)
{
    write_cr0(read_cr0() & (~0x10000)); // 清除写保护位
}

static void enable_write_protection(void)
{
    write_cr0(read_cr0() | 0x10000); // 设置写保护位
}

static long hook_stub_execve(const struct pt_regs *regs)
{
    // 在这里可以添加你的hook逻辑
    return old_execve_addr(regs);
}

static int hook_do(void *data)
{
    syscall_fn_t *sys_call_table;
    unsigned long sys_call_table_addr;

    // 获取sys_call_table的地址
    sys_call_table_addr = (unsigned long)kallsyms_lookup_name("sys_call_table");
    sys_call_table = (syscall_fn_t *)sys_call_table_addr;

    // 禁用写保护
    disable_write_protection();

    // 使用hook_stub_execve来替换原始的execve函数指针
    old_execve_addr = sys_call_table[__NR_execve];
    sys_call_table[__NR_execve] = (syscall_fn_t)hook_stub_execve;

    // 启用写保护
    enable_write_protection();

    return 0;
}

static int __init hook_init(void)
{
    on_each_cpu(hook_do, NULL, 1);
    return 0;
}

static void __exit hook_exit(void)
{
    // 恢复原始的execve函数指针
    disable_write_protection();
    sys_call_table[__NR_execve] = old_execve_addr;
    enable_write_protection();
}

module_init(hook_init);
module_exit(hook_exit);

MODULE_LICENSE("GPL");

这是一个简单的示例,使用了Linux内核的stop_machine机制来确保在每个核上执行hook操作。需要注意的是,修改sys_call_table需要的是root权限。另外,上述代码只hook了execve系统调用,如果需要hook其他系统调用,可以按照类似的方式进行修改。