OllyDbg 断点

断点的分类

F2 断点
  • F2断点又叫普通断点CC断点int3断点

  • OD反汇编窗口(C窗口)中,双击语句的某一行或按下 F2 会设置(触发)一个int3 断点

  • int3是一个断点(中断)指令,在汇编中机器码是CC,所以,F2断点又可以称为int3断点CC断点

  • 在使用 F2 设置断点后,CPU 会引发一个异常,而 OD 会捕获这个异常,从而中断程序;

  • 可以使用命令bp xxxxxxxx快速设置一个CC断点

  • bp可以为内存地址设置断点,也就是为某条语句设置断点;

  • bp当然也可以为API(函数)设置一个断点,如bp MessageBoxA,断点会设置在 API 的行首,也就是函数的第一行;

  • 通常情况下,当使用bpAPI设置断点时,该API应该是可见的,也就是在反汇编窗口按下Ctrl + N后,在函数窗口能找得到时,才能使用bp设置断点,不过偶尔在找不到的情况下,也能使用bp设置断点,这种情况时可以买一注彩票;

  • 使用bp MessageBoxA也就是为API设置断点后,会在系统领空下,这个API的行首设置断点;

  • 使用bpx MessageBoxA也就是为API设置断点后,会在程序领空下,所有调用这个API的位置设置断点;

  • F2断点的设置没有数量限制,可以设置无数个;

  • F2断点很容易被检测,从而触发反调试;

  • F2断点重载程序后不会丢失;

当执行一个 int3 断点时,对应指令处第 1 个字节的内容会被调试器用 CC 指令替换,此时 OD 将 int3 隐藏,显示出来的仍是中断前的指令,实际上已经被替换为 CC;

当被调试程序执行 int3 命令导致一个异常时,调试器就会捕捉到这个异常,从而停在断点处,然后将断点处的指令恢复成原来的指令;

由于 int3 断点改变了原程序机器码,所以很容易被软件检测到,躲过检测的方法是将断点设置在函数内部或尾部;

内存断点
  • 内存断点是通过修改内存属性为不可访问、不可执行来实现的;
  • 内存断点同时只能存在一个;
  • 内存断点在重载程序后会丢失,需要重新设置;
  • 内存断点会影响程序的运行速度;
内存访问一次性断点

在内存窗口(Alt + M),每个区段都有相应的权限(属性),选择区段并按下 F2 后,可以设置一次性断点,且属性可以单独设置;

当所在段被读取或执行时就会中断,断点生效后会被自动删除,所以叫做一次性断点;

硬件断点
  • 硬件断点最多可以设置 4 个;
  • 硬件断点在设置位置的下一条指令中断;
  • 可以使用命令HE xxxxxxxx快速设置一个硬件执行断点
  • 可以使用命令HE MessageBoxAAPI的行首快速设置一个硬件执行断点
  • HW xxxxxxxx设置硬件写入断点
  • HR xxxxxxxx设置硬件读取断点
  • 硬件断点只能手动删除或执行删除;

硬件断点和 DRx 调试寄存器有关;

DRx 调试器一共有 8 个(DR0 ~ DR7):

  • DR0 ~ DR3:调试地址寄存器,用于保存需要监视的地址,例如设置硬件断点;
  • DR4 ~ DR5:保留,未公开具体作用;
  • DR6:调试寄存器组状态寄存器;
  • DR7:调试寄存器组控制寄存器;

硬件断点的原理是使用 DR0 ~ DR3 设定地址,并使用 DR7 设定状态,因此最多设置 4 个断点;

硬件执行断点和 CC 断点的作用一样,但不会修改机器码,所以更难检测;

硬件断点的优点是速度快,在 int3 断点容易发现的地方设置硬件断点效果更好,缺点是只能设置 4 个;

单个硬件断点可以设置为 1 字节、2 字节或 4 字节,且不论选择的数据范围有多大,只有前 4 个字节有效;

OD 提供的快捷键F4可以执行到光标所在行,这也是利用了调试寄存器的原理,可以理解为:按下 F4 时设置了一个硬件断点,执行到所选行后自动删除断点,相当于执行了一个一次性的硬件断点;

硬件访问/写入断点于内存访问/写入断点不同的是:硬件访问/写入断点会在触发断点的下一行中断,而内存访问/写入断点则是在触发断点的当前行中断;

条件断点
  • 满足某个条件的CC断点;
  • 使用shift + F2快速设置条件断点;
  • OD 的条件断点可以按寄存器、存储器、消息等设断;
  • 条件断点是一个带有条件表达式的普通 int3 断点,当调试器遇到这类断点时,断点将计算表达式的值,如果结果非 0 或表达式有效,则断点生效;
条件记录断点
  • 多了记录断点处函数表达式或参数值的条件断点;
  • 也可以设置通过断点的次数,每次符合暂停条件,计数器的值都将减 1;
  • 使用shift + F4快速设置条件记录断点;
消息断点
  • 消息断点实际上就是条件记录断点;
  • 在操作窗口或控件时,都会发送一个消息;
  • ODW窗口刷新来获取交互消息;
  • 检测交互(消息循环)来设置消息断点,如101 按键抬起202 鼠标左键抬起等;
  • 断点生效后,修改条件来记录操作日志,在ODL窗口查看记录的日志或将日志输出到指定文件来进一步进行分析;

Windows 本身是由消息驱动的;

当某个特定窗口函数接收到某个特定消息时,消息断点将使程序中断;

消息断点与 int3 断点的区别是:int3 断点可以在程序启动前设置,消息断点只有在窗体被创建之后才能设置并拦截消息;

所有发送的消息都有 4 个参数:1 个窗口句柄(hwnd)、1 个消息编号(msg)和 2 个 32 位长(long)的参数;

Windows 通过句柄来标识它所代表的对象;

API 断点
  • 给系统提供的 API 设置的CC断点
  • MessageBoxA中的A表示使用ASCII编码;
  • MessageBoxW中的W表示使用Unicode编码;

OD 基本指令

快捷键含义
Ctrl + G跳转到指定地址
F2设置断点
Ctrl + F2重新载入
Alt + F2关闭调试的程序
F4运行到光标选定位置
F7单步步入
Ctrl + F7自动步入
F8单步步过
Ctrl + F8自动步过
F9运行程序,有断点运行到断点
Ctrl + F9执行到返回
Ctrl + F11跟踪步入
Ctrl + F12跟踪步过
Ctrl + T设置 RUN 跟踪的条件
Ctrl + E编辑数据
;添加注释
:添加标签
空格编辑汇编指令

快速定位指定地址的四种方法

  1. goto 命令
  2. 设置断点
  3. 设置注释
  4. 设置标签

快速查找指定代码的四种方法

  1. 代码执行法

    在程序代码量不大且功能明确的情况下,逐条执行指令,直到需要查找的指令被触发,例如,触发 MessageBox 会弹窗;

  2. 字符串检索法

    检索 OD 载入程序时摘录出来的字符串列表;

  3. API 检索法:在调试代码中设置断点

    检索 OD 通过 IAT 摘录的 API 函数列表,查找符合程序行为特征的函数调用;

  4. API 检索法:在 API 代码中设置断点

    向 DLL 代码库中符合程序行为特征的 API 添加断点;