iis服务器助手广告广告
返回顶部
首页 > 资讯 > 操作系统 >怎么截获Linux操作系统异常处理
  • 479
分享到

怎么截获Linux操作系统异常处理

2023-06-16 19:06:46 479人浏览 安东尼
摘要

本篇内容介绍了“怎么截获linux操作系统异常处理”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在某些情况下,我们可能需要去截获Linux操

本篇内容介绍了“怎么截获linux操作系统异常处理”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

在某些情况下,我们可能需要去截获Linux操作系统的一些异常处理,比如截获page fault异常处理。

可以修改内核的情况下:

如果我们能够修改内核,那么截获page fault异常处理就会非常简单。以linux 3.8.0内核为例,系统中发生page fault之后,会进入page fault异常处理,调用do_page_fault函数。do_page_fault的代码如下:

dotraplinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) { exception_enter(regs); __do_page_fault(regs, error_code); exception_exit(regs); }

我们把do_page_fault函数的内容提取出来,写成一个新的函数default_do_page_fault。再增加一个函数指针do_page_fault_handler,初始化为default_do_page_fault。将原来的do_page_fault内部改为调用函数指针do_page_fault_handler。修改之后的代码如下:

void default_do_page_fault(struct pt_regs *regs, unsigned long error_code) { exception_enter(regs); __do_page_fault(regs, error_code); exception_exit(regs); } EXPORT_SYMBOL(default_do_page_fault); typedef void (*do_page_fault_handler_t)(struct pt_regs *, unsigned long); do_page_fault_handler_t do_page_fault_handler = default_do_page_fault; EXPORT_SYMBOL(do_page_fault_handler); dotraplinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code){ do_page_fault_handler(regs, error_code); }

由于do_page_fault_handler被EXPORT_SYMBOL导出,我们在内核模块中可以很方便地访问它。只要将do_page_fault_handler的值设置为自定义的page fault异常处理函数,就能完成截获功能。如果想要恢复原来的异常处理函数,只需要再次把do_page_fault_handler设置为default_do_page_fault即可。

不能修改内核的情况下:

但是有些情况下,我们不能直接修改内核代码,需要在已经编译好的内核上完成截获功能。

开始的时候,我考虑在do_page_fault函数开始处插入跳转代码,跳转到自定义的page fault处理函数中。但是实践的时候发现,内核不允许直接修改do_page_fault的代码。

经过一番调查,又想到一个新的办法,即通过更改IDT表的方式来截获page fault。

内核原有的IDT表肯定是不能直接写的,所以我申请了一个页,将原来的IDT表复制过来,再更改页面异常对应的ISR(Interrupt Service Routine)。page fault的ISR名称为page_fault,它将寄存器压栈,将error number压栈,然后调用do_page_fault,待do_page_fault返回之后再恢复寄存器,退出异常处理。

在Linux内核中,ISR是用汇编写的。例如,x86_64 Linux的ISR源码位于内核源码arch/x86/kernel/entry_64.S中,X86_32的位于arch/x86/kernel/entry_32.S中。如果去读entry_64.S或者entry_32.S,你会发现这两个文件非常复杂,利用了很多的汇编宏和宏定义,无法方便地基于它们写一个自定义的ISR出来。

我的解决办法是将内核编译出来,反汇编vmlinux.o,然后查找page_fault,找到其汇编代码。下面的汇编代码就是linux-3.8.0 X86_64内核的:

ffffffff8136f6f0 <page_fault>: ffffffff8136f6f0:       66 66 90                data32 xchg %ax,%ax ffffffff8136f6f3:       ff 15 07 0a 2b 00       callq  *0x2b0a07(%rip)        # ffffffff81620100 <pv_irq_ops+0x30> ffffffff8136f6f9:       48 83 ec 78             sub    $0x78,%rsp ffffffff8136f6fd:       e8 ae 01 00 00          callq  ffffffff8136f8b0 <error_entry> ffffffff8136f702:       48 89 e7                mov    %rsp,%rdi ffffffff8136f705:       48 8b 74 24 78          mov    0x78(%rsp),%rsi ffffffff8136f70a:       48 c7 44 24 78 ff ff    movq   $0xffffffffffffffff,0x78(%rsp) ffffffff8136f711:       ff ff ffffffff8136f713:       e8 1f 2e 00 00          callq  ffffffff81372537 <do_page_fault> 11 ffffffff8136f718:       e9 33 02 00 00          jmpq   ffffffff8136f950 <error_exit> 12 ffffffff8136f71d:       0f 1f 00                nopl   (%rax)

我仿照着写了一个,名为my_page_fault:

asmlinkage void my_page_fault(void); asm("   .text"); asm("   .type my_page_fault,@function"); asm("my_page_fault:"); //the first 3 bytes of the routine basically do nothing, //but I decide to keep them because kernel may rely on them for some special purpose asm("   .byte 0x66"); asm("   xchg %ax, %ax"); asm("   callq *addr_adjust_exception_frame"); asm("   sub $0x78, %rsp"); asm("   callq *addr_error_entry"); asm("   mov %rsp, %rdi"); asm("   mov 0x78(%rsp), %rsi"); asm("   movq $0xffffffffffffffff, 0x78(%rsp)"); asm("   callq my_do_page_fault"); asm("   jmpq *addr_error_exit"); asm("   nopl (%rax)");

其中第9行addr_adjust_exception_frame是(pv_irq_ops+0x30)地址处存储的值;第11行addr_error_entry是error_entry的地址;第16行addr_error_exit是error_exit的地址。这几个值需要从System.map文件中查询,然后用内核模块参数的形式传入。而my_do_page_fault则是我们自己定义的page fault处理函数。

如果需要截获X86_32的page fault,可以参考这个C文件。不过需要注意的是,新版内核有所变动,这里的代码需要根据自己的情况做一些调整。

有了自定义的ISR之后,就可以将这个ISR填到IDT中,加载新的IDT表之后,自定义的page fault处理函数就开始发挥作用了。这个过程主要有以下几个步骤:

  • 用store_idt(&default_idtr)保存现有的IDT寄存器值

  • 从default_idtr中读出IDT表首地址和表的大小

  • 申请一个页面

  • 将原来的idt表拷贝到新申请的页面中

  • 利用pack_gate将my_page_fault(注意不是my_do_page_fault)填入到对应的IDT项中

  • 在idtr中填写新的IDT表地址和大小,用load_idt(&idtr)加载新的IDT表到当前CPU

  • 利用smp_call_function,将新的IDT表加载到其他CPU上。

如果想恢复原来的IDT表,则用load(&default_idtr)和smp_call_function加载原来的IDT表,释放申请的页面。

“怎么截获Linux操作系统异常处理”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: 怎么截获Linux操作系统异常处理

本文链接: https://www.lsjlt.com/news/284812.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 怎么截获Linux操作系统异常处理
    本篇内容介绍了“怎么截获Linux操作系统异常处理”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在某些情况下,我们可能需要去截获Linux操...
    99+
    2023-06-16
  • Java异常分类处理抛出捕获操作详解
    目录什么是异常1.算术异常2.数组越界异常3.空指针异常异常的分类异常的抛出(throw关键字)异常的捕获throws关键字try catch关键字finally关键字总结什么是异常...
    99+
    2022-11-13
  • SpringBoot怎么配置全局异常处理器捕获异常
    本篇内容主要讲解“SpringBoot怎么配置全局异常处理器捕获异常”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“SpringBoot怎么配置全局异常处理器捕获异常”吧!1.前言任何系统,我们不...
    99+
    2023-07-05
  • Linux香港服务器常见操作系统有什么差异
    Linux香港服务器常见操作系统的差异是:1、Ubuntu和Debian操作系统,Ubuntu提供更人性化系统配置和更强大的系统操作,且功能性完善,对新手友好度更高,上手容易,Debian对新手不太友好,难上手;2、Red Hat和Cent...
    99+
    2022-10-20
  • 自定义注解和springAOP捕获Service层异常,并处理自定义异常操作
    一 自定义异常 public class NoParamsException extends Exception { //用详细信息指定一个异常 public ...
    99+
    2022-11-12
  • 怎么备份Linux操作系统
    本篇内容主要讲解“怎么备份Linux操作系统”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么备份Linux操作系统”吧! tar:  特点  1、保留权限  2、适合备份整个目录  3、可以选...
    99+
    2023-06-10
  • LINUX操作系统死机怎么办
    本篇内容主要讲解“LINUX操作系统死机怎么办”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“LINUX操作系统死机怎么办”吧!LINUX死机后可以 Ctrl+Alt+F1,Root登录,用top...
    99+
    2023-06-10
  • linux操作系统下RAR怎么用
    这篇文章主要为大家展示了“linux操作系统下RAR怎么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“linux操作系统下RAR怎么用”这篇文章吧。============zip文件的操作==...
    99+
    2023-06-10
  • SpringBoot怎么进行统一异常处理
    这篇文章主要介绍“SpringBoot怎么进行统一异常处理”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“SpringBoot怎么进行统一异常处理”文章能帮助大家解决问题。1、处理前异常代码@ApiO...
    99+
    2023-06-29
  • Linux操作系统怎么实现的传真系统
    本篇内容主要讲解“Linux操作系统怎么实现的传真系统”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Linux操作系统怎么实现的传真系统”吧!传真是企业中的常规使用,许多商贸往来的信息交换都须要...
    99+
    2023-06-17
  • Linux操作系统信息怎么查看
    要查看Linux操作系统的信息,可以使用以下命令: `uname -a`:显示操作系统的内核版本、操作系统版本信息和硬件架构。 `...
    99+
    2023-10-26
    Linux
  • Linux操作文件系统怎么调用
    本篇内容介绍了“Linux操作文件系统怎么调用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!需要引入的头文件:#inlcude<uni...
    99+
    2023-06-21
  • Linux操作系统命令dd怎么用
    小编给大家分享一下Linux操作系统命令dd怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!dd 是 Linux/UNIX 下的一个非常有用的命令,作用是用指...
    99+
    2023-06-16
  • Linux操作系统问题怎么解决
    这篇文章主要讲解了“Linux操作系统问题怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux操作系统问题怎么解决”吧!在多人共用一台电脑或管理局域网时,常常会遇到这种情况:普通...
    99+
    2023-06-17
  • 怎么释放Linux操作系统空间
    这篇文章给大家分享的是有关怎么释放Linux操作系统空间的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1. 移除不再需要的软件包如果你了解过 apt-get 或 apt 命令的详细用法,应该知道 autoremo...
    99+
    2023-06-16
  • Linux 系统下如何处理大规模文件操作?
    在现代计算机系统中,我们经常需要处理大规模的文件操作,如日志文件、备份文件等等。这些文件的处理通常需要花费大量的时间和资源。在 Linux 系统下,有许多强大的工具和技术可以帮助我们高效地处理大规模文件操作。 一、使用 find 命令查找...
    99+
    2023-08-21
    编程算法 linux 文件
  • python中文件操作与异常的处理是怎样的
    本篇文章为大家展示了python中文件操作与异常的处理是怎样的,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。一、 文件的操作1.1创建文件格式:f = open(‘文件', ‘w')...
    99+
    2023-06-22
  • vbs怎么获取操作系统及其版本号
    这篇文章给大家分享的是有关vbs怎么获取操作系统及其版本号的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。vbs获取操作系统及其版本号'***********************************...
    99+
    2023-06-08
  • Linux系统中怎么操作网络端口
    Linux系统中怎么操作网络端口,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。关闭端口代码如下:iptables -A INPUT -p tcp --dport 111 -...
    99+
    2023-06-12
  • 怎么在Windows中玩转Linux操作系统
    本篇文章给大家分享的是有关怎么在Windows中玩转Linux操作系统,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。众所周知,Linux和Unix系统的稳定性是很好的,并且因为...
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作