文章插图
?
- 从上图可知 , eflags 寄存器的第8位就是单步调试模式的标志 。
- 所以 ptrace() 函数的以下2行代码就是设置 eflags 进程的单步调试标志:
tmp = get_stack_long(child, EFL_OFFSET) | TRAP_FLAG;put_stack_long(child, EFL_OFFSET, tmp);
- 而 get_stack_long(proccess, offset) 函数用于获取进程栈 offset 处的值 , 而 EFL_OFFSET 偏移量就是 eflags 寄存器的值 。
- 所以上面两行代码的意思就是:
- 获取进程的 eflags 寄存器的值 , 并且设置 Trap Flag 标志 。
- 把新的值设置到进程的 eflags 寄存器中 。
- 设置完 eflags 寄存器的值后 , 就调用 wake_up_process() 函数把被调试的进程唤醒 , 让其进入运行状态 。 单步调试过程如下图:
文章插图
?
- 处于单步调试模式时 , 被调试进程每执行一条指令都会触发一次 SIGTRAP 信号 , 而被调试进程处理 SIGTRAP 信号时会发送一个 SIGCHLD 信号给父进程(调试进程) , 并且让自己停止执行 。
- 而父进程(调试进程)接收到 SIGCHLD 后面 , 就可以对被调试的进程进行各种操作 , 比如读取被调试进程内存的数据和寄存器的数据 , 或者通过调用 ptrace(PTRACE_CONT, child,...) 来让被调试进程进行运行等 。
- 由于 ptrace() 的功能十分强大 , 所以本文只能抛砖引玉 , 没能对其所有功能进行分析 。另外断点功能并不是通过 ptrace() 函数实现的 , 而是通过 int3 指令来实现的 , 在 Eli Bendersky 大神的文章有所介绍 。而对于 ptrace() 的所有功能 , 只能读者自己慢慢看代码来体会了 。
推荐阅读
- IDE 一篇文章带你明白:什么是编译器,什么是集成开发环境?
- 中国女性为什么更愿意掌握家庭财权?
- 一文掌握shell脚本中shift的用法及功能
- 掌握排列数组合数基本公式的推导 排列组合怎么算
- 反射?看一篇文章你就会了
- 秋季如何把头发养护好?掌握方法很重要!这几个方法,务必试试
- GC 一篇文章彻底了解Java垃圾收集机制
- |面对集团高层的动荡,职场人士需要掌握的生存法则与破局思维
- 一篇感恩母亲的演讲,感动哭了 感恩母亲演讲稿
- 一文掌握linux系统路由跟踪指令traceroute