第2章:动态调试技术--OllyDbg
OllyDbg 是有 Oleh Yuschuk 编写的一款具有可视化界面的用户模式调试器.可以在各种版本的 Windows 上运行,但在 NT 架构上是最好的.
plugin 目录中存放插件,直接将插件放里面,OD即可检测到.
Debug -> Select Import Librariers ,可以将符号库( Lib )导入,让OD以函数名的形式显示 DLL 中的函数.这个功能类似于 IDA 的 FLIRT.
EIP 的值不能直接修改,在 CPU 界面对选中的代码 右键 -> New Origin Here.
call xxxxxxx 进入子程序后,栈中会将 call 指令的下一条指令最为返回地址压入栈中.
Crtl + F9 执行到第一个返回命令处( ret , retf , iret ) . Crtl + F7/8 会一直执行 , 直到按 ESC 或者遇到断点.
领空是指程序在某一时刻 CPU 执行的代码的拥有者.
API 函数大多采用 __stdcall 调用,按照逆序将数据入栈.
爆破是指 : 修改代码,改变其功能,使程序保护的方式失效.
Int 3 断点(软件断点)可以有无数个,但是容易被检测到.
BOOL IsCC() { FARPROC Uaddr ; BYTE Mark = 0; (FARPROC&) Uaddr =GetProcAddress ( LoadLibrary("user32.dll"),"MessageBoxA"); Mark = *((BYTE*)Uaddr); // 取MessageBoxA函数第一字节 if(Mark ==0xCC) // 如该字节为CC,则认为MessageBoxA函数被下断 return TRUE; else return FALSE; }
硬件断点与 DRx 调试寄存器有关( DR6 :调试寄存器组状态寄存器 , DR7: 调试寄存器组控制寄存器 ):
硬件断点的调试原理是:使用DR0~DR3 设定地址,并使用DR7设定状态.因此硬件断点最多只能存在4个.
内存断点: 对所设的地址赋予 不可访问/不可写属性 ,这样当 访问/写入 时会产生异常,并由调试器接管这个异常.
每次异常都需要比较来确定是否应该中断,因此过多的内存断点会让调试器的运行速度变慢.
内存一次性断点: 断住后就删除断点.这类断点仅仅在 NT 架构下可用.
消息断点: 只有窗口被创建之后才能被设置. 所有发送的消息包含四个参数 : 句柄( hwnd ),消息编号( msg )和两个32位长( long )的参数.
句柄用来表示它所代表的对象,比如单击了哪个按钮,发送消息给对用的程序.
在 View -> 窗口 处,选择 按钮,然后选择 消息断点和类型.运行后即断在系统底层代码领空,在用户代码领空( 一般为 .text )设置内存访问断点,继续运行即可到代码处.
条件断点:
①按存储器条件中断
以 CreateFile 为例:
如果要找到多个文件中的一个文件,在栈中选择 "Relative to ESP" :
[ STRING [esp+4 ] ] == "c:\\1212.txt" 或者是 [ UNICODE [ esp+4 ] ] == "c:\\1212.txt"
②按寄存器条件中断
条件记录断点:
以 CreateFile 为例,
假如要记录 这个函数被调用的情况,在该 API 的开头选中,然后按 Shift+F4 ,
打开条件记录窗口表达式表示要记录的值,填 EAX,则表示要记录 EAX 的值.如果填的是 [ esp+4 ] ,则可以选择解码表达式.
下面用于设置遇到断点时是否进行相应的操作.
最下面的表示暂停时执行的命令:如果输入" .d esp ",条件断点断下时会执行" d esp ".
插件: Run Trace 在调试设置中设置一个大的缓冲区,在工具栏 调试 -> 打开或清除跟踪. 开启后将自动记录数据变化,也可以检查每个可识别函数的被调用次数
Hit trace : 能够让调试者辨别哪一部分的代码被执行了.
但是不能在数据区使用,因为它会在每个指令前设 Int 3 断点,命中就删除,会改变数据使程序发生错误.
调试符号 :
符号格式: ① SYM 早期用于 MS-DOS 和16位 Win ,现在只作为 Win 9x (16位) 的调试符使用.
② COFF 是 UNIX 供应商所遵循规范的一部分,由 Windows NT 2.1 首次引进使用.微软以抛弃.
③ CodeView 格式现在已经支持 Win32 系统,支持的调试符号是 C7 格式,其在执行模块中是自我包含的,符号信息和二进制代码混合(调试文件很大).
④ PDB( Program Database ) 是微软自己定义的未公开的格式,PDB 符号可以根据应用程序不同的链接方式保存在单独的或者多个文件中.
⑤ DBG 是系统调试符,用于显示系统函数名,链接器不创建 DBG 文件,微软将操作系统调试符分配在 DBG 文件 ( 包含其它调试符的文件例如, COFF 和 C7 )中.
⑥ MAP 文件是程序的全局符号,源文件,行号代码信息的唯一文本表示方式.此文件不需要程序支持,通用性极好.
创建调试文件 :
OD 以两种方式加载目标程序:
①使用 CreateProcess API,即在 OD 中打开一个文件( F3 ),可以附带参数.
②使用 DebugActiveProcess API. 将调试器捆绑到一个正在运行的进程上,即 Attach .
如果是隐藏进程,在命令行界面输入 :" C:\OllyDbg.exe -p pid 值 "
一些问题 :