
OllyDbg是一个32位汇编级的直观的分析调试器。
它在源代码不可得或者你用编译器遇到问题的时候特别有用。
运行需要。工作在Windows 95,98,Me,NT或者2000,可能XP上(没有测试)。
运行于任何奔腾级别的电脑上,但是如果想要流畅的调试,你可能需要一个至少300MHz的处理器。
Ollydbg是很耗内存的。如果你想要使用某些扩展特性比如追踪,我推荐128或更多内存。
支持的处理器。OllyDbg支持所有80x86,奔腾,MMX,3Dnow!,包括Athlon扩展,和SSE指令以及相应数据格式。
但不支持SSE2. 可配置性。大约有100个选项控制OllyDbg的行为和外观。
数据格式。
Dump窗口显示所有常规数据格式:
hex,ASCII,UNICODE,16和32位正/负/16进制整数,32/64/80位浮点数,地址,反汇编(MASM或IDEAL),或作为注释的
PE部首或者线程数据块。
帮助。
这个文件包含理解和使用OllyDbg所需的重要信息。
如果你有Windows API帮助文件(因为考虑到版权的原因没有附带),你可以把它附加到OllyDbg一起,以便在系统调
用的时候获得立即帮助。
启动。
你可以以命令行,文件菜单,拖放的方式指定可执行文件,重启最后调试过的程序或者把它附加到正在运行的程序上
。OllyDbg支持实时调试。安装是不必要的,你可以从软盘上启动OllyDbg。
线程。
OllyDbg可以调试多线程应用程序。你可以从一个线程切换到另一个,挂起,恢复和中止线程或者改变他们的优先级。
线程窗口显示每一个线程的错误信息(通过调用GetLastError来返回)
分析。
分析器是OllyDbg重要的一部分。它识别过程,简单和级联转换器,表,嵌入代码中的常数和字符串,复杂的结构,
API函数调用,函数参数号,输入段等等。分析可以使二进制代码可读性增强,使调试变得容易以及减少错误中断和崩
溃的可能性。它不是面向编译器的,可以于任何的PE程序工作得一样好。
对象扫描器。
OllyDbg扫描对象文件或库(都是按OMF和COFF格式的),释放代码段并在被调试的程序中定位它们。
IMPLIB扫描器。
一些DLLS只按照序数输出它们的Symbols,这对于人的眼睛来说是没什么意义的。如果你有相应的输入库,OllyDBg能
把序数翻译回symbolic名称。
全UNICODE支持。
几乎所有对ASCII串可用的 *** 作对于UNICODE串都是可用的,反之亦然。
名称。
OllyDbg显示所有输入和输出的symbols.它按照Borland格式把名称从调试信息中提取出来。对象扫描器允许识别库函
数。你可以增添你自己的名字和注释。如果某些DLL中的函数是通过序数输出的,你可以附加一个输入库到OllyDbg中
,以恢复原始名称。Ollydbg也可识别许多常数的symbolic名称,像窗口消息,错误代码或位段,然后在call中把他们
解码为已知的函数。
已知函数。
OllyDbg能通过名称识别大约2100个被C和Windows API频繁使用的函数,并能解码他们的参数。你可以添加你自己的描
述,或者分配预先定义的译码。你可以在已知函数上设置logging breakpoint(记录断点)并把参数记录到日志中。
堆栈。使用简单的试探,OllyDbg尝试识别返回地址和堆栈帧。
但注意,他们有可能是上一个call所留下的残余(译者:破解的时候有时反而需要!)。如果程序在已知的函数上暂
停,堆栈窗口解码实参。 搜索。大量的可能性!搜索命令(确切的或近似的),命令号,常数,二进制或者文本串(
不必是连续的),搜索参考地址的所有命令,常数或者地址范围,搜索名称,在整个分配的内存中搜索2进制序列。如
果发现多个地址,你可以在他们中间来回的切换。
资源。
如果Windows API函数参考资源串,OllyDbg可以释放并显示它(译者:w32dsam)。对其它类型的只是限制在列出附属
资源,转储和2进制编辑。 断点。OllyDbg支持所有种类的常规断点:简单断点,条件断点,中断并把信心写到日志文
件(例如,函数的参数),写或访问的内存断点,硬件断点(只能ME/NT/2000)。在hit trace(命中追踪)的极端例
子下,INT3中断可以设置在模块的每个命令下。在有500MHz处理器的Windows NT环境中,OllyDbg可以每秒钟处理
5000个以上的中断。 监视和查看工具。Watch是一个每次程序暂停时候都被计算的表达式。你可以使用寄存器,常数
,地址表达式,布尔和任何复杂的代数 *** 作符。你可以比较ASCII和UNICODE串。Inspector是包含2个索引并能以一个
2维表格的形式表示的watch,它可以解码数组和结构。
执行。
你可以一步步的执行程序,或者进入子过程,或者立刻执行它。你可以运行程序知道返回或者运行到指定的地方,或
者连续执行。当程序运行时,你仍然对其具有完全的控制,而且你还可以查看内存,设置断点,甚至在运行时实时调
整代码。而且,在任何时候你都能暂停和重启被调试的程序。 命中追踪。Hit trace显示到目前为止,那些命令或进
程被执行了,它允许你检测你代码的所有分支。Hit trace在每个指定的命令上下断点,并在命令被执行后(被命中
Hit)移去它。
运行追踪。
Run trace一步一步执行程序,并把执行结果摘要到一个大的缓冲中。这个摘要包括所有的寄存器(除了SSE),旗标
和线程错误,消息和已知函数的解码后的参数。你可以保存原始命令,这样可以使调试自改变程序变的容易。你可以
指定条件以停止追踪。或者按地址范围,表达式或者一个命令。你可以把run trace的结果保存到一个文件中并比较两
个独立的Run。Run trace允许回朔追综,并详细分析大量命令执行的经过。
摘要。
摘要计算某条指令在run trace缓冲区中被列出了多少次。用摘要,你可以知道哪部分代码消耗了最多的处理时间。
补丁。
内建的汇编器自动选择最短可能的代码。二进制编辑器同时以ASCII,UNICODE和16进制的形式同步显示数据。固有的拷
贝粘贴功能仍然是可用的。自动备份允许撤销改变。你可以直接修改后拷贝到可执行文件中去,OllyDbg甚至还能适当
调整你做的改变。
自解压文件。
当调试自解压文件时,你常常想要跳过自解压然后停在原始程序的入口点。OllDbg完成SFX(自解压)追踪,它尝试这
定位真实的入口。SFX追踪常常对于加了保护的自解压程序是无能为力的。发现入口(或者指定)后,OllyDbg可以更
快速和可靠的跳过解压程序。 插件。通过编写你自己的插件,你可以给OllyDbg添加功能。插件存取所有重要的数据
结构,添加菜单和快捷方式到存在的OllyDbg窗口并使用超过100个插件API函数,这些插件API有详细的文档说明。
UDD。
OllyDbg存储所有程序或模块相关信息到单个文件并在模块装载的时候读入。这些信息包括标签,注释,断点,监视,
分析数据,条件等等。 定制。你可以定制字体和颜色方案。
最简单的方法是启动OllyDbg,点击File|Open,然后选择你想调试的程序。程序需要命令行参数输入对话框下方的文本栏。重新开始调试最后一个程序的快捷键是Ctrl+F2,并且OllyDbg使用相同的参数。
你也可以点选历史记录。把程序拖入OllyDbg也可以开始调试。
当然,当启动OllyDbg时,你在命令行中也能指定被调试的程序名和参数。比如:
你可以创建桌面快捷方式指向OllyDbg,选择属性,到快捷方式,把程序名加入目
标栏。每次你双击这个快捷图标,OllyDbg自动装载被调试程序。
你可以attach OllyDbg到某个正在运行的进程。点击File|Attach,从列表中选择
该进程。注意:当你关闭OllyDbg,这个进程也会终止。不要试图attach系统进程
,这很可能使系统完全死机。(事实上,大多数情况下,OS不允许attach敏感进
程)
OllyDbg能作为just-in-time debugger。这需要在注册表中登记。点击
Options|Just-in-time debugging,在对话框中按“Make OllyDbg just-in-time
debugger”。现在,当一些程序崩溃,你会被询问是否调试它。这样, *** 作系统
可以启动OllyDbg并直接停在异常发生处。如果你选择attaching without
confirmation,OllyDbg不会询问直接启动。要恢复原来的just-in-time
debugger,在出现的对话框中按相应的按纽就行了。
其它方法还有,把OllyDbg加入可执行文件的d出式菜单。点击Options|Add to
Explorer,按“Add OllyDbg to menu in Windows Explorer”。以后你可以右击
可执行文件点选OllyDbg。这个选项创建注册表键
HKEY_CLASSES_ROOT/exefile/shell/Open with OllyDbg and
HKEY_CLASSES_ROOT/exefile/shell/Open with OllyDbg/command
OllyDbg可以调试控制台(基于文本)程序。
注意:WindowsNT或Windows2000下,你必须有管理员权限
OllyDbg的help-通用快捷键(翻译)
Golbal shortcuts(通用快捷键)
这些快捷键在OllyDbg中通用,不依赖于当前活动窗口。
Ctrl+F2---OllyDbg重置,重新开始调试。如果没有活动程序,OllyDbg装入历史列表中的第一个程序。OllyDbg重置会释放内存移除硬断点。
Alt+F2--关闭被调试的程序。如果程序还在活动状态,你会被询问是否执行该 *** 作。
F3--显示“Open 32-bit .exe file”对话框,这里可以选择可执行文件和指定参数
Alt+F5--使OllyDbg显示在屏幕最前方。如果被调试程序中断时显示窗口遮住OllyDbg的一些区域,不继续运行又不能移动或最小化它。激活OllyDbg按Alt+F5可以解决。如果你再次按Alt+F5,OllyDbg会恢复为普通窗口。OllyDbg的当前状态显示在状态栏。
F7--step into,执行下一条简单命令。如果该命令是一个函数调用,进入调用函数内部。如果命令有REP前缀,执行该命令的一步 *** 作。
Shift+F7--与F7相同,除了当被调试程序遇到某些异常时,首先尝试调用程序自己的异常处理过程。
Ctrl+F7--animate into,一步一步执行程序,也进入函数调用(就象你一直按着F7,不过更快)。当你执行一些单步或继续命令,程序到达有效断点,一些异常发生时,Animation终止。每步执行,OllyDbg重画所有窗口。要加速animation,关闭所有窗口而不要只改变现有窗口的大小。终止animation,也可按Esc。
F8-step over,执行下一条简单命令。如果该命令是一个函数调用,立刻执行完该函数(除非函数内部有断点或产生异常)如果命令有REP前缀,执行所有重复 *** 作,并停于下一条命令。
Shift+F8--与F8相同,除了当被调试程序遇到某些异常时,首先尝试调用程序自己的异常处理过程。
Ctrl+F8--animate over,一步一步执行程序,但不进入函数调用(就象你一直按着F8,不过更快)。当你执行一些单步或继续命令,程序Animation到达有效断点或异常发生时,Animation终止。每步执行,OllyDbg重画所有窗口。要加速animation,关闭所有窗口而不要只改变现有窗口的大小。终止animation也可按Esc。
F9--继续执行程序。
Shift+F9--与F9相同。除了当被调试程序遇到某些异常时,首先尝试调用程序自己的异常处理过程。
Ctrl+F11--run trace into,一步一步执行程序,要进入函数调用,记录寄存器内容。Run trace 不重绘CPU窗口.
F12-悬挂所有线程以停止程序执行。最好用继续键和菜单命令(像F9)恢复执行线程,而不要用其它手动方法恢复。
Ctrl+F12--run trace over,一步一步执行程序,不进入函数调用,记录寄存器内容。Run trace不重绘CPU窗口。
ESC--如果animation或跟踪正在进行,将被终止。如果CPU窗口显示跟踪时的数据,此时转为显示实际数据。
Alt+B--打开或恢复Breakpoint窗口。这里可以编辑,删除和观察断点。
Alt+C--打开或恢复CPU窗口。
Alt+E--打开或恢复模块列表
Alt+E--打开或恢复Call stack窗口。
Alt+L--打开或恢复Log窗口。
Alt+M--打开或恢复Memory窗口。
Alt+O--打开Option对话框
Ctrl+P--打开Patch窗口。
Ctrl+T--打开Pause run trace对话框
Alt+X-中断OllyDbg。
多数窗口可以使用下列快捷键:
Alt+F3--关闭活动窗口。
Ctrl+F4--关闭活动窗口。
F5--最大化或恢复活动窗口。
F6--激活下一个窗口。
Shift+F6--激活前一个窗口。
F10--打开激活窗口或面板的右键菜单。
LeftArrow--左移一个字符。
Ctrl+LeftArrow--左移一行。
RightArrow--右移一个字符。
Ctrl+RightArrow--右移一行。
OllyDbg的help-分析模块介绍(翻译)
分析
OllyDbg集成了快速超强的代码分析器。装载它,可以用d出式菜单或者CPU窗口
的反汇编栏按Ctrl+A或者在执行模块选“Analyze all modules”。
分析器非常有用。它在数据中分辨代码,标记入口点和jump的目标,辨认switch
tables,ASCII和UNICODE字符串,定位过程、循环、高级switch语句和解码标准
API函数参数(看范例)。OllyDbg的其它部分也广泛用于数据分析。
这怎么可能呢?我稍微介绍一下原理。首先,OllyDbg反汇编代码区所有可能的地
址,记下所有发现的调用及指向的目标。当然,许多这样的调用不正确,但是未
必会有两个错误的调用指向同一条命令,并且三个或三个以上更不可能。这样,
三个或更多调用指向同一地址,我就确信该地址是经常使用的子过程入口。从这
个入口开始,我跟踪所有的跳转和调用,反复 *** 作。这种方法使我99.9%确定所
有命令。然而,某些字节不在这条链中,我采用大约20个更高效的方法(最简单
的如:“MOV [RA],Ra"是无效命令).
过程检测也简单。过程,从分析器的角度看,就是从入口开始的代码的连续区域
,(理论上)可以到达其它命令(除NOP或对齐填充外)。你可以指定三种识别级
。Strict级严格确认一个入口和至少一个出口。heuristical级,分析器尝试确认
入口。如果你选择fuzzy级,或多或少相容的代码区被分离为过程。现代编译器把
过程分成几个部分作公用代码优化。这种情况下,fuzzy级特别有用!然而,误解
的概率也相当高。
类似的,loop是一个封闭的连续命令序列,这里最后的命令跳到开头、一个入口
几个出口。Loop相当于高级 *** 作语言中的do,while和for。OllyDbg能认识任何复
杂的嵌套循环。在反汇编区,他们用长长的大括号标记。如果入口不是循环的第
一条命令,OllyDbg用个小三角形作标记。
实现switch语句,多数编译器把switch变量装入寄存器,然后减去一部分,像下
面代码序列一样:
MOV EDX,<switch variable>
SUB EDX,100
JB DEFAULTCASE
JE CASE100 Case 100
DEC EDX
JNE DEFAULTCASE
... Case 101
这些序列也可能包含一级或两级switch表,直接比较,优化,填充等等。如果你
深入研究比较和跳转树,很难说哪一条命令是某个case语句。OllyDbg为你代劳。
它标记所有的case语句,包括default,甚至尝试猜测case的意思,如'A',
WM_PAINT 或者 EXCEPTION_ACCESS_VIOLATION。如果命令序列不修改寄存器(只
由比较命令构成),那么不大可能是switch语句,但可能是if嵌套:
if (i==0) {...}
else if (i==5) {...}
else if (i==10) {...}
让OllyDbg解码if嵌套为switch,选择Analysis1中相应的选项。
OllyDbg预置超过1900个常用API函数的描述。包括KERNEL32, GDI32, USER32,
ADVAPI32, COMDLG32, SHELL32, VERSION, SHLWAPI, COMCTL32, WINSOCK,
WS2_32 和 MSVCRT。你也可以加入自己的描述。如果分析器遇到已知函数名的调
用(或跳转到该函数),它尝试解码调用跟前的PUSH命令。因此,你可以粗略翻
译该调用的功能。OllyDbg也内置大约400个标准C函数的描述。如果你利用新库,
我建议你分析前先扫描对象文件。这种情况下,OllyDbg也会解码已知的C函数参
数。
如果选项“Guess number of arguments of unknown functions”被设置,分析
器尝试确认调用过程进栈的双字数目,并标记他们为参数Arg1,Arg2等等。注意:
如果有寄存器参数,OllyDbg还是不认识也不包括在上面的统计中。分析器采用了
一个安全的方法。例如,它不分辨无参数过程和返回前用POP恢复寄存器代替舍弃
参数的case语句。然而,能分辨出的函数数目相当多,并非常有助于提高代码的
可读性。
分析器能跟踪寄存器的值。现代优化编译器,特别是面向Pentium的,经常把常量
和地址装入寄存器便于重复使用或减小内存占用空间。如果一些常量装入寄存器
,分析器会注意它,并用于解码函数及其参数。还能执行简单的算术计算跟踪
push和pop命令。
分析器不能区别不同类型的名字。如果你用已有的名字命名一些函数,OllyDbg会
解码所有该地址的调用为原过程。WinMain,DllEntryPoint和WinProc是特殊的预
定义名。你可以使用这些标号标记主程序入口,DLL入口指针和window过程(注意
:OllyDbg不会检查用户定义标号的唯一性)。当然,最好的方法是显示已定义的
参数。
非常不幸,没有一般的规则用于100%的准确分析。有些情况下,例如当模块包含
p-代码或者代码区嵌入大量数据,分析器可能认为部分数据是代码。如果统计分
析显示代码可能被打包或加密,分析器会警告你。如果你想用hit跟踪方式,我建
议你不要用fuzzy分析方式,否则断点被设置在被误认为代码的数据上的几率很高。
自解压文件通常在主体代码外有解压代码。如果你选择SFX选项“Extend code
section to include self-extractor”,OllyDbg会扩大代码区,形式上允许分
析它并跟踪。
OllDbg的一般原理(翻译)部分
我希望你熟悉80x86兼容CPU的内部结构,并且有汇编写程序的经历。我也希望你
熟悉Microsoft Windows.
OllyDbg是一个单进程多线程的“机器代码级”debugger,用于Windows环境下的32位程序。它允许你debug和patch PE格式的可执行程序。OllDbg仅仅使用列入文档的Win32 API调用,所以可用于下一代32位Windows系统。OllDbg看来也可工作于Windows XP,但是我没有详尽的测试,因此不能保证功能完整。
OllyDbg不是面向编译器。它不含特别的规则显示某些情况下特定的编译程序生成哪些代码序列。因此,你可以一样对待任何编译器编译的,或者汇编书写的任何代码。
OllyDbg与被调试的程序同时工作。你可以浏览代码和数据、设置断点、停止或继续线程,甚至运行期修改内存(有时这叫作软调试方式)。当然,如果被请求的 *** 作不是最基本的,OllyDbg就会短时暂停程序,但这对用户透明。有时不在调试状态运行的程序会意外崩溃。OllyDbg,这个“及时”debugger,会指出异常发生的位置。
OllyDbg强烈面向模块。模块这里指启动时加载的或动态加载的主执行文件或动态连接库。在调试区,你可以设置断点,定义新标号和注释汇编语句。当一些模块从内存卸载后,OllyDbg保存这些信息到扩展名为.UDD名字同被调试模块的文件中。下次当装载这些模块时,OllyDbg自动复原所有调试信息,不论程序是否使用这些模块。比如:你调试使用Mydll的程序Myprog1,并且在Mydll中设置一些断点。那么当你调试Myprog2时,也使用Mydll,你会发现所有在Mydll中的断点还在那里,不管Mydll是否装载在不同的位置。
一些调试器把被调试进程的内存视为单个2**32字节区域。OllyDbg做了别的处理方法。内存由几个独立的块组成。任何内存 *** 作都限制于块内。在大多数案例中,这工作优良并且容易调试。但是模块包含几个执行部分等等,你将不能立刻看到整个代码。然而这些例外不常见。
OllyDbg是内存消耗大户。启动时就要分配3MB内存,甚至更多。每次分析,备份,跟踪或文件转储另外再分配。所以当你调试大工程时消耗40或60M内存很正常。
要有效的调试一些无源代码的程序,你首先必须理解它是如何工作的。OllyDbg提供了大量的手段使理解更容易
运行该指令不会对寄存器、内存以及堆栈造成任何影响,英文意思是”无 *** 作”,它没有特殊的用途例如,你用一个短指令来替换一个长指令的话,如果处理器没有错误多余的空间将会被NOP填充
适当数目的nop指令可以将其他指令完全替换掉
将 *** 作数压入堆栈,PUSH *** 作后会更新ESP指向新的栈顶地址,可 *** 作数值、寄存器和内存地址
堆栈保存数据窗口中颠倒过来的值,即倒序放置,读/写的内容在内存中倒序是处理器的特点之一
如data(CA 20 40 00)则stack(00 40 20 CA)
PUSH 401000 将数据401000压入栈
PUSH [401000] 取内存地址为401000中的数据压入栈
它会取出堆栈顶部的第一个字母或者第一个值,然后存放到指定的目标地址内存单元中
POP *** 作后会更新ESP指向新的栈顶地址
如,POP EAX从栈顶中取出第一个值存放到EAX中,随后的一个值随即变成栈顶
指令把所有通用寄存器的内容按一定顺序压入到堆栈中,相当于
"PUSH EAX,PUSH ECX,PUSH EDX,PUSH EBX,PUSH ESP,PUSH EBP,PUSH ESI,PUSH EDI"
PUSHA 等价于 "PUSH AX, CX, DX, BX, SP, BP, SI, DI"
与PUSHAD正好相反,它从堆栈中取值,并将它们放到相应的寄存器中,相当于
"POP EDI,POP ESI,POP ESP,POP ESP,POP EBX,POP EDX,POP ECX,POP EAX"
POPA 等价于 "pop DI, SI, BP, SP, BX, DX, CX, AX"
PUSHA,POPA/PUSHAD,POPAD在16位程序中使用,我们不感兴趣,OllyDbg是一个32位调试器
该指令将第二个 *** 作数赋值给第一个 *** 作数,如: MOV EAX, EBX
p2是寄存器也可能是内存单元,p1的位数比p2多,p2的符号位填充p1剩余部分
如:
EAX = 00000000,BX = F000
MOVSX EAX,BX
执行后EAX = FFFFF000,因为F000是负数,所以EAX的高位用F填充
EAX = 00000000,BX = 7FFF
MOVSX EAX,BX
执行后EAX = 00007FFFF,因为7FFF是正数,所以EAX的高位用0填充
16位范围0000~FFFF, 正 0000~7FFF, 负8000~FFFF
32位范围00000000~FFFFFFFF, 正 00000000~7FFFFFFF, 负80000000~FFFFFFFF
MOVZX类似于MOVSX,但是这种情况下,剩余的部分不根据第二个 *** 作数的正负来进行填充
剩余的部分总是被填充为0
类似于MOV指令, 但是第一个 *** 作数是一个通用寄存器,并且第二个 *** 作数是一个内存单元。
当计算的时候要依赖于之前的结果的话,那么这个指令就非常有用。
如:
LEA EAX, DWORD PTR DS:[ECX+38]
在这个例子中,LEA指令就计算ECX + 38的值,然后将计算的结果赋值给EAX
因为完成的是赋值 *** 作,所以我们会认为 *** 作数是内存单元中的值,
但实际上, *** 作数仅仅是内存单元的地址,而不是里面的内容
该指令交换两个 *** 作数的值
如:
XCHG EAX,ECX
EAX的值将被存放到ECX中,反之亦然,也可以交换寄存器和内存单元的值
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)