第二章 动态调试技术
动态分析技术中最重要的工具是调试器,分为用户模式和内核模式两种类型。
用户模式调试器: 用来调试用户模式应用程序的调试器,工作在Ring3级,例如OllyDbg、x64dbg。也存在有VisualC++等编译器自带的调试器。
内核模式调试器: 能调试操作系统内核的调试器,例如WinDbg。
OllyDbg
简称OD,用户级调试器。OD是一款十分强大的32位调试器,虽然作者早已停止更新,但作为学习工具还是可以的。实践中建议使用x64dbg的32位版本。
64位平台可以使用x64dbg、IDA Pro等
操作窗口
配置
ollydbg.ini: OD中Options菜单里的所有设置,保存在ollydbg.ini中
UDD文件: OD的工程文件,用于保存当前调试的一些状态,例如断点、注释等,以便下次调试时继续使用。
插件: OD支持插件,并提供了相关api。这使得其扩展性非常好。
调试设置
单击“Options” —“Debugsingoplions” 选项,打开调试设置选项对话框,一般保持默认即可。其中,“Exceptions” (异常)选项用于设置让OllyDbg 忽路或不忽略某些异常,建议全部选择。 有关异常的知识将在第8 章讲解。
加载符号文件
点击“Debug”- "Seleet importlibraries” 选项,打开导入库窗口进行加载。符号文件可以在调试过程中,让函数以函数名字表示。比如存在一个函数叫“abc”,但是在调试器中很可能是一串数字”004012f7“,而符号文件就能让它显示为”abc“。
基本操作
常见快捷键:
全部:
https://www.cnblogs.com/YiShen/p/9742872.html
断点
常用断点有:INT3断点、硬件断点、消息断点。
INT3断点
当你使用bp命令或者按下F2时,所设的断点为INT3断点。原理是把下断点的地方的指令换成CC指令来引发异常,调试器捕获异常后中断,并把原指令还原。例如:
004011F3 68 D0404000
||||||||||||
004011F3 CC D0404000
优点: 可以设置无数个INT3断点,只要电脑受得住。
缺点: 由于修改了程序,所以易被检测
硬件断点
设断方法是在指定的代码行单击右键,执行快捷菜单中的“Breakpoint” 一 "Hardware,on execution”(“断点〞一,“硬件执行”)命令(也可以在命令行中设置“HE地址”)
最多可以设置四个硬件断点。
其中DR0、DR1、DR2、DR3可以设定地址,用来断下,DR7用来控制状态。
原理: 设置好断点后,运行到改地址时,CPU会向调试器发送异常,调试器捕获后中断。
优点: 执行速度快,不易被检测
缺点: 只能设置四个
OD中的F4快捷键,就是用了硬件断点,用完后自动删除该断点,相当于一次性。
硬件断点和DRx调试寄存器有关。在IntelCPU体系架构手册中可以找到对DRx调试寄存器的介绍。
内存断点
设定方法为右键菜单中的“Breakpoint”里含“Memory”字段的选项。
原理: 对所设地址赋予“不可访问\不可写属性”,程序试图访问\写入时,会引发异常。调试器截获后,会将异常地址与断点地址比较,如果相等就中断。
优点: 不易被检测,可作为硬件断点的替代品
缺点: 在OD里只能设置一个。
内存访问一次性断点:
Windows对内存采用段页式的管理方法,使用快捷键“Alt+M”可查看内存。在想设置断点的区段上按下F2,当你的程序执行到该区段时,便会断下。
消息断点
Windows本身由消息驱动,因此当你在调试时没有找到合适的断点时,可以尝试消息断点。
详情见《加密与解密》p31
条件断点
条件断点是一个带有条件表达式的普通INT3断点。当调试器遇到这类断点时,断点将计算表达式的值,如果结果非零或者表达式有效,则断点生效。
OllyDbg的条件断点可以按寄存器、存储器、消息等设断。
按寄存器条件中断:
例如,在选中的地址00401476按下“Shift+F2“,在出现文本框中输入“eax==0400000“,则档程序运行到该地址时,如果eax的值为0400000,则断下。
按储存器条件中断:
例如,在反汇编窗口中,将光标移到CreatFileA函数的第一行,按下“Shift+F2”,输入 “ [STRING[esp+4]]=="c:\1212.txt" “ ,则当程序试图打开该路径下的文件时,就会中断。
按储存器条件中断,其实就是根据栈的内容来中断。
条件记录断点:
在条件断点的基础上,增加记录操作。能够在断下来后,记录某些数据。
如下图中的“Expression”,里面填上你想记录的内容。
如果你想记录EAX的值,那就写EAX。
Run trace(跟踪)
简单来说,就是实现按下+或-时的功能。
也可以保存走过的代码的各项数据
也可以显示函数被调用的次数
Hit trace
能够帮助调试者查看哪一些代码被执行了。
尤其是跳转分支较多时,可以线性查看。
第二章之后的内容没那么重要,在次略过。