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 的行首,也就是函数的第一行;通常情况下,当使用
bp
为API
设置断点时,该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 MessageBoxA
在API
的行首快速设置一个硬件执行断点
; 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
快速设置条件记录断点;
消息断点
- 消息断点实际上就是条件记录断点;
- 在操作窗口或控件时,都会发送一个消息;
- 在
OD
的W
窗口刷新来获取交互消息; - 检测交互(消息循环)来设置
消息断点
,如101 按键抬起
、202 鼠标左键抬起
等; - 断点生效后,修改条件来记录操作日志,在
OD
的L
窗口查看记录的日志或将日志输出到指定文件来进一步进行分析;
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 | 编辑数据 |
; | 添加注释 |
: | 添加标签 |
空格 | 编辑汇编指令 |
快速定位指定地址的四种方法
- goto 命令
- 设置断点
- 设置注释
- 设置标签
快速查找指定代码的四种方法
代码执行法
在程序代码量不大且功能明确的情况下,逐条执行指令,直到需要查找的指令被触发,例如,触发 MessageBox 会弹窗;
字符串检索法
检索 OD 载入程序时摘录出来的字符串列表;
API 检索法:在调试代码中设置断点
检索 OD 通过 IAT 摘录的 API 函数列表,查找符合程序行为特征的函数调用;
API 检索法:在 API 代码中设置断点
向 DLL 代码库中符合程序行为特征的 API 添加断点;