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系统调用,可以按照以下步骤进行操作:
首先,获取sys_call_table的地址。sys_call_table是一个数组,存储了系统调用的函数指针。可以使用kallsyms_lookup_name函数来获取它的地址。
然后,禁用写保护。Linux内核默认会将sys_call_table设置为只读,需要禁用写保护才能修改其中的函数指针。
接下来,将需要hook的系统调用的函数指针替换为自定义的hook函数。你提到的是想hook execve系统调用,所以将__NR_execve对应的函数指针替换为自定义的hook_stub_execve函数。
最后,启用写保护,确保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其他系统调用,可以按照类似的方式进行修改。