异常、调试、ptrace的过程和原理

前言

从今年上半年开始,一直在利用ptrace做plt hook的一些工作。在此之前,对ptrace并没有什么了解。在工作开始后,为了能尽快出成果,也只是快速的翻了一下ptrace的相关接口函数,然后根据查阅到的资料,在较短时间内达成了项目目标。对其中的原理,并未做深入研究。今天看了一些资料,做个简单总结,以此为记。

异常

什么是异常

异常是异常控制流的一种形式,一部分由硬件实现,一部分由操作系统实现;它是控制流中的突变,用来相应处理其状态中的某些变化;
——《深入理解计算机系统》
更详细的异常说明,可以参考:
Linux 对异常和中断处理
在这里插入图片描述
可以用下图来简单表示:
在这里插入图片描述


在这里插入图片描述

异常的种类

异常可以分为:
中断(interrupt)、陷阱(trap)、故障(fault)、终止(abort)
在这里插入图片描述
各自对应的典型例子:
中断:IO输入
陷阱:syscall
故障:缺页
终止:kill
各自对应的处理流程可以参考:《深入理解计算机系统》
或者: CSAPP笔记之异常控制流与进程

异常处理

在内核中,有一个保存异常处理程序的数组称为异常表。异常号实际上就是这个数组的下标。
一部分异常号是由处理器提供的(除0,缺页,断点,内存访问违规等)另一部分是由操作系统提供的(系统调用,外部 I/O 设备的信号)。
在这里插入图片描述
当程序运行时检测到哪种异常号,就去找到相应的异常处理程序。然后执行。
与普通的函数调用有以下区别:

1、异常处理后执行的指令有可能还是当前指令(例如页错误),有可能是下一条指令。而函数调用肯定是下一条指令。
2、异常处理程序运行在内核模式。

对linux而言,其异常处理流程一般如下:
1、准备阶段
在内核栈保存通用寄存器内容(称为现场信息),这部分大多用汇编语言程序实现
2、处理阶段
采用 C 函数进行具体处理。函数名由 do_ 前缀和处理程序名组成,如 do_overflow 为溢出处理函数。大部分函数的处理方式:保存硬件出错码(如果有的话)和异常类型号,然后,向当前进程发送一个信号
当前进程接受到信号后,若有对应信号处理程序,则转信号处理程序执行;若没有,则调用内核 abort 例 程,终止当前进程
3、恢复阶段
恢复保存在内核栈中的各个寄存器的内容,切换到用户态并返回到当前进程的断点处继续执行
——上述内容参考: Linux 对异常和中断处理

小结
异常–》产生信号
关于信号的一些知识,可以参考:
Linux下的信号简单理解

ptrace

什么是ptrace

ptrace() 是一个由 Linux 内核提供的系统调用,允许一个用户态进程检查、修改另一个进程的内存和寄存器,通常用在类似 gdb、strace 的调试器中,用来实现断点调试、系统调用的跟踪。
可以man一下ptrace:
在这里插入图片描述
在这里插入图片描述

注意:
observe and control the execution of another process
如何实现的呢?
任何发给被跟踪进程(tracee)的信号(除了 SIGKILL)将导致该进程停止运行,而跟踪进程(tracer)会通过 wait() 获得通知。 另外,该进程之后所有对 exec() 的调用都将使操作系统产生一个 SIGTRAP 信号发送给它,这让父进程有机会在新程序开始执行之前获得对子进程的控制权;

举例来说,如何实现gdb当中的断点功能:
1.根据输入的行数或者函数名或者其他有效信息,得到要断点的代码在进程中的具体位置——也就是代码所对应的虚拟地址
2.通过ptrace的接口,修改代码对应位置的执行码为 0xcc (debug专用)
3.当程序执行到该位置时,就会触发异常
4.在异常处理过程中,系统会向当前进程(被跟踪进程)发送一个SIGTRAP信号
5.被跟中进程被停止,兵器,跟踪进程截获了发送给被跟踪进程的SIGTRAP信号
6.这时候,可以通过相应的gdb命令,来查看调用栈(bt)或者某个变量的值
7.如果继续向下执行,gdb会通过ptrace的接口来把断点位置的机器码恢复,并控制被跟踪进程继续向下执行
。。。。。。

总结

简单概括,就是:
产生异常–>异常处理–>产生信号–>ptrace原理(跟踪进程截获被跟踪进程的信号并停止被跟踪进程)
关于linux内核调试的实现,可以参考:
关于linux内核调试的实现

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

lqw198421

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值