前言
上篇调试(一)对程序调试在开发者尤其是对逆向工程师或者黑客而言的重要性,同时也将调试进行原理解释,本篇将深入调试原理分享。
通用寄存器
寄存器被认为是位于CPU上的小型存储器,CPU获取数据的最快方式是直接访问寄存器,理解寄存器的用途是设计一个调试器的重要基础。
(对寄存器的更多认识可以参见此网友博文——寄存器)
栈
栈是一种非常重要的数据结构,栈是一个先进后出(FILO)的数据结构,参数在函数调用前被压入栈并在函数结束调用后出栈(详细可见Python基础语法——函数(二))。而在寄存器中的ESP和EBP寄存器分别用于记录当前栈帧的顶部和底部,栈是由内存高地址向内存低地址的方向增长的。
而调试器会实时跟踪函数调用时栈帧的变化,并记录基于栈类型的溢出事件。
调试事件
一个调试器必须捕获以下常见的调试事件(也存在其他类型的调试事件):
- 非法触发
- 非法内存操作
- 由被调试程序抛出的异常
当一个调试事件发生时,调试器会被激活并调用相应的处理例程处理该事件,当事件处理例程被调用时,被调试的目标进程暂停执行并等待调试器做出如何继续的指令。
断点
断点的设置可以使一个进程的执行暂停在一个符合某种特定条件的位置上,而这个位置可以由调试者进行选择,此时调试者可以对程序变量、栈上的参数以及内存分配状态进行检测,并在目标进程对这些值做出改变之前将它们记录下来。
一般调试器会提供三种基本类型的断点:软断点,硬件断点和内存断点。
——————————
参考资料
- 《Python灰帽子》