使用ollydbg来调试release版本的程序
程序在用release跑时有时会出各种各样的问题, 如果使用debuglog来跟的话, 有时debuglog很多不知道是哪个才是真正出问题的地方, 对于这种情况,推荐一下ollydbg
ollydbg是一个二进制的调试工具, 一般用来反汇编代码及动态跟踪程序.相同的工具还有:
softice(dos窗口,完全手动的调试方法)
w32asm(静态分析代码的好工具, 不过动态跟踪能力不行)
IDA(强大的反汇编工具,但是用起来太复杂了)
windbg(强大的调试工具, 不过个人感觉不够直观)
相对来说ollydbg是里面比较好用的工具,特点如下:
GUI界面,所有的功能都可以通过菜单及右键菜单查找到(比softice要方便)
代码分析, 可以显示寄存器,循环,api调用,表,常量和字符串等(而不只是汇编代码)
可以从map或是lib中加载符号表(没有符号表,那程序中使用到的函数一般是像libc.1234,有了符号表就可以变成libc.printf这样子)
直接加载动态库(IDA需要运行程序时才会把这个程序需要的所有库都加载,ollydbg是打开这个exe就会载入所有使用的动态库)
加大的插件功能
可以自己订制标签,注释和函数描述
可以保存不同会话的补丁(不做cracker,所以这个基本上用不到)
绿色不需要安装
强大的断点功能,除了普通的代码断点外还有内存断点和硬件断点.内存断点可以设置成访问这块内存或是写入这块内存时中断,不过内存断点有时会无效,硬件断点则是再试调试时断点依然存在,
更多的特点可以在它的网站上看到
使用ollydbg来帮助定位错误的步骤:
1 下载与安装
2 把要调试的程序加载到内存(可以使用open或是attach方式)
3 在ollydbg中加载程序的符号表(map文件)和动态库的符号表(lib文件)
4 运行直到出错
5 使用ollydbg查看调用堆栈("查看"->"调用堆栈")定位出错的函数
6 在ollydbg的CPU窗口中定位出错的代码行()
7 查看出错原因, 如调用函数的参数等, 还可以提到windows的getlasterror的值, 帮助定位
8 如果在上一步发现问题所在那是最好, 如果没有发现,可以在附近添加debug log,来帮助定位出错原因
使用:
下载:
在google上查找 "ollydbg 下载", 推荐使用中文版本的, 因为中文版带有很多常用插件并且解决了汉字的问题
安装:
直接解压到某个目录下,然后运行
选择菜单 "选项"->"界面选项",在 "目录" 中设置udd与plugin的绝对路径
界面介绍:
状态栏上有一个命令行窗口,可以直接在这里输入一些命令来简化操作, 当然这些命令实现的功能也可以通过右键菜单来实现
调试前准备:
为了方便的看exe程序的符号, 你需要这个exe的map.
MAP 文件是程序的全局符号、源文件和代码行号信息的唯一的文本表示方法,是整个程序工程信息的静态文本。它可以在任何地方、任何时候使用,不需要有额外的程序进行支持,仅仅通过一个文本阅读工具如Ultra Edit就可以打开了。而且,这是唯一能找出程序崩溃代码行的救星。
那么我们应该如何生成 MAP文件呢?在 VC 中,我们可以按下 Alt+F7,打开“Project Settings”选项页,选择 C/C++ 选项卡,并在最下面的 Project Options 里面输入:/Zd ,然后要选择 Link 选项卡,选中“Generate mapfile”复选框,并在最下面的 Project Options 里面输入:/mapinfo:lines,表示生成 MAP 文件时,加入行信息。最后按下 F7 来编译生成 EXE 可执行文件和 MAP 文件,此时可以在工程的Debug目录下找到刚刚生成的MAP文件,文件名为“工程名.map”。
调试的方法:
ollydbg提供三种调试方法,
1 直接在File->Open菜单里面载入一个程序,然后加好断点后点 Run开始调试
2 在 File->Attach菜单中附加到一个进程,然后开始调试. 注意如果ollydbg退出时这个进程也会被停掉
3 在 选项->实时调试设置里面设置 ollydbg为系统默认的调试器, 然后当程序异常时系统会自动调出ollydbg进行调试.
一般我觉得第三种不一定能保存出错前的堆栈信息.所以最好还是使用第一第二比较保险, 但也有时候堆栈被破坏的
调试步骤:
1 使用ollydbg加载需要调试的程序,可以是open方式打开也可以是attach方式打开
2 使用"插件"->"load map"菜单导入这个exe的map文件,如果这个exe使用了其它动态库,并且有这些动态库的lib文件,在 "调试"->"选择导入库" 里面增加静态库
3 按ctrl+A进行代码分析
4 如果想看程序中的所有函数名等,那可以:
a.在CPU窗口点右键,选择 "查找"-> "当前模块中的名称"或"所有模块中的名称"
b.在命令行中输入sn
5 如果需要加普通断点,有几个方法:
a.直接在cpu窗口中对应的代码那里按F2,或是点右键出来选择"切换断点"
b.如果是想在某个函数的入口添加断点, 那可以在上面弹出的符号窗口中对应的函数点右键, 然后选择"切换断点", 命令行是 "bp 符号名"
c. 如果是想所有调用这个函数的地方加断点, 那在符号窗口中对应的函数点右建, 选择"查找参考", 然后在弹出窗口点右键,选择 "每个参考上设置断点". 命令行是 "bpx 符号名"
6 运行, 等待出错,出错了就查看调用堆栈,看是哪个函数中出错的
7 看当前代码周围有没有什么特殊的东西,如字符串,或是系统api名字等, 这样可以帮助你定位出错的代码行
Trackback: http://tb.donews.net/TrackBack.aspx?PostId=828112