Linux安装系统调用表更改模块时系统崩溃(unable to handle kernel paging request at XX)

安装内核模块时,如果里面有更改系统调用等情况,有时会崩溃,出现如下错误:

<1>BUG:unable to handle kernel paging request at virtual address c06357b4
printing eip:d0aac056 *pde = 0e9dd163 *pte = 00635161 

Oops: 0003 [#1] SMP 
Modules linked in: test2(U) addsym(U) nls_utf8autofs4 fuse rfcomm l2cap bluetooth sunrpc nf_conntrack_ftp nf_conntrack_ipv4xt_state nf_conntrack xt_tcpudp ipt_REJECT ip

 

原因:由于控制寄存器CR0的第16位若置位,则表示禁止系统进程写只有只读权限的页面(sys_call_table),

所以我们给sys_call_table添加内容的话就必须将CR0的第16位清零,在模块卸载的时候给还原

示例代码如下:

清除标志位:

static int clear_cr0(void)

{

    unsigned int cr0 = 0;

    unsigned int ret;

   

    asm volatile ("movq %%cr0, %%rax":"=a"(cr0));

    ret = cr0;

    cr0 &=0xfffeffff;

    asm volatile ("movq %%rax, %%cr0": :"a"(cr0));

 

    return ret;

 

}

恢复标志位:

static void setback_cr0(int val)

{

    asm volatile ("movq  %%rax,  %%cr0": :"a"(val));

   

}

 

注意:

在32位和64位的系统下汇编指令是有区别的,上面是32位系统下的代码,

从32位扩充到了64位,名字也发生了变化。8个通用寄存器(eax, ebx,ecx, edx, ebp, esp, esi, edi)在新的结构中被命名为rax,rbx, rcx, rdx, rbp, rsp, rsi, rdi。movl命令也需相应改成movq。

 

使用示例:

    orig_cr0= clear_cr0();//保留标志位

    sys_call_table[__NR_connect]= (unsigned long )test;//更改系统调用

    setback_cr0(orig_cr0);//恢复标志位

当卸载模块,需要恢复系统调用时,同理。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

浪游东戴河

你就是这个世界的唯一

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

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

打赏作者

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

抵扣说明:

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

余额充值