Fork me on GitHub

动态调试技术


知识点

本章会重点介绍两个调试器:OllyDbgWinDbg,调试器监控程序执行的能力在恶意代码分析的过程中十分重要,调试器允许我们查看任意内存地址的内容,寄存器的内容以及每个函数参数的值。调试器也允许我们在任意时刻改变运行中的程序中的值。

源代码级调试器与汇编级调试器:源代码级调试器指在代码编写期间运行的调试器,汇编级调试器也成为底层调试器,他的操作对象使源代码而不是汇编代码。

内核模式与用户模式调试:在用户模式中调试器调试的程序是单个可执行程序,操作系统会将它与其他可执行程序隔离。内核模式调试一般需要两个系统,一个系统运行被调试的代码,另一个系统运行调试器,我们需要开启操作系统的内核调试功能并将两个系统连接。WinDbg是一个常用的内核调试器,OD是一个常用的用户模式调试器。

单步调试:单步调试状态下,每运行一条指令,控制权就返回到调试器,单步调试可以帮助我们看到程序中的每一个细节,但是也容易使我们陷入细节而忽略大局。

单步跳过和单步跳入:这两个选项可以让我们选择在即将运行到一个函数的调用过程时,我们是选择单步步入进入此程序还是单步步过跳过此程序,有时因为单步跳过可能会使程序缺少一个正确的返回值而影响调试结果。

断点:断点被用来暂停程序的运行并使你查看程序的运行状态,程序在断点处暂停运行被称为中断。

  • 硬断点:利用专门的硬件寄存器来存储设置断点的位置,当运行到指定位置时就会产生中断。
  • 软断点:调试器通过0xCCINT 3的机器码来重写指令的首个字节来实现软断点
  • 条件断点:当满足某些条件的时候触发断点,如对某个指令的调用或者对函数的调用。

异常:异常是调试器取得运行中的程序的执行权的基本方式。本质上,除了断点产生异常外,与调试无关的事件如非法内存访问、除0操作也会产生异常。

首次和二次异常处理:调试器通常有两个机会来处理同一个异常,调试器第一次附加到进程时会产生一个异常,此时程序停止执行,调试器取得控制权,调试器可以选择自己处理这个异常或者将异常移交给应用程序本身的异常处理函数,但是如果应用程序没有处理异常,调试器将会获得第二次异常处理的机会,此时调试器必须处理这个异常以防止应用程序的崩溃。在调试过程中,如果碰到了二次异常说明恶意代码中可能存在BUG或者使恶意代码不想在当前环境中运行。

常见异常:

  • INT 3异常。
  • 单步调试产生的异常,标志寄存器中的陷阱标志(trap flag)为1时,处理器每执行一条指令就会产生一个异常。
  • 程序访问无效地址产生的异常。
  • 一些指令只能在特权模式才能运行,如果程序尝试在非特权模式下运行则会产生异常。

使用调试器修改可执行文件:调试器可以通过修改控制标志、指令指针或者代码本身等方式来改变程序执行的方式。

课后练习

本章无课后练习


本章结束🎊

您的支持是我最大的动力🍉