Hook技术--③Linux系统调用劫持 hook

文章介绍了如何在Linux系统中劫持系统调用,通过获取sys_call_table地址、控制页表属性并替换特定系统调用(如__NR_getdents)实现。作者提供了示例代码和恢复原状的方法,展示了这一技术的应用和潜在安全性问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.3 Linux系统调用劫持 hook

1.3.1 理解

系统调用劫持的目的是改变系统中原有的系统调用,用我们自己的程序替换原有的系统调用。Linux内核中所有的系统调用都是放在一个叫做sys_ call _table的内核数组中,数组的值就表示这个系统调用服务程序的入口地址。整个系统调用的流程如下:

1698300470361

当用户态发起一个系统调用时,会通过80软中断进入到syscall hander,进而进入全局的系统调用表sys_ call _table去查找具体的系统调用,那么如果我们将这个数组中的地址改成我们自己的程序地址,就可以实现系统调用劫持。但是内核为了安全,对这种操作做了一些限制

  • sys_ call _table的符号没有导出,不能直接获取。
  • sys_ call _table所在的内存页是只读属性的,无法直接进行修改。

对于以上两个问题,解决方案如下(方法不止一种):

  • 获取sys call table的地址 :grep sys_call_table /boot/ -r

在这里插入图片描述

  • 控制页表只读属性是由CR0寄存器的WP位控制的,只要将这个位清零就可以对只读页表进行修改。
/* make the page writable */
int make_rw(unsigned long address) {
    unsigned int level;
    pte_t *pte = lookup_address(address, &level);//查找虚拟地址所在的页表地址
    pte->pte |= _PAGE_RW;//设置页表读写属性
    return 0;
}
/* make the page write protected */
int make_ro(unsigned long address) {
    unsigned int level;
    pte_t *pte = lookup_address(address, &level);
    pte->pte &= ~_PAGE_RW;//设置只读属性
    return 0;
}

1.3.2 示例

开始替换系统调用,本文实现的是对 ls 这个命令对应的系统调用,系统调用号是 __NR_getdents。

在linux内核中,比较常见并且关键的就是系统调用表,系统调用表实际上是指针数组,下标是系统调用号,应用层发起的所有活动基本上都绕不过系统调用,控制了系统调用表基本上就是控制了整个系统.

hook只需要两个信息:系统调用表的起始地址和系统调用号,之后就能像修改指针一样进行劫持。

static int syscall_init_module(void) {
    orig_getdents = sys_call_table[__NR_getdents];
    make_rw((unsigned long)sys_call_table); //修改页属性
    sys_call_table[__NR_getdents] = (unsigned long *)hacked_getdents; //设置新的系统调用地址
    make_ro((unsigned long)sys_call_table);
    return 0;
}

恢复原状:

static void syscall_cleanup_module(void) {
    printk(KERN_ALERT "Module syscall unloaded.\n");
    make_rw((unsigned long)sys_call_table);
    sys_call_table[__NR_getdents] = (unsigned long *)orig_getdents;
    make_ro((unsigned long)sys_call_table);
}

使用Makefile编译,insmod插入内核模块后,再执行ls时,就会进入到我们的系统调用,我们可以在hook代码中删掉某些文件,ls就不会显示这些文件,但是这些文件还是存在的。

1.3.3 文章参考

http://t.csdnimg.cn/A4r9U

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

霜晨月c

谢谢老板地打赏~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值