标题：OLLYDBG
界面构成
OllyDbg发行版是一个ZIP压缩包，只要解压运行OllyDbg.exe即可。运行OllyDbg打开进程，主窗口显示反汇编清单。各窗口的外观属性如：“标题栏(bar）、字体(font）”等在右键菜单"界面选项（appearance)"里控制代码窗口  OllDbg运行窗口代码窗口（OllyDbg帮助文件自称反编汇窗口）显示被调试程序的代码。他有四个列
地址/Address(虚拟地址) HEX数据/HEX dump(机器码) 反汇编/Diassassembly（汇编代码） 注释/Comment（注释）
最后一列注释（Comment）显示相关API参数或运行简表，非常有用，有点类似于IDA Pro。
在代码窗口（地址行，不是列标题）双击时完成动作。
●地址（Address）列：显示相对被双击地址的地址，再次双击返回标准地址模式；
●HEX数据（HEX dump）列：设置或取消无条件断点，按F2键也能设置断点；
●反编汇(Diassassembly）列：调试编辑器，可直接修改汇编代码；
●注释（Comment）列：允许增加或编辑注释。
代码窗口允许浏览、分析、搜索和修改代码，保存改变到可执行文件，设置断点等。相关弹出式菜单包括100多项。信息窗口（Information window)动态跟踪时，与指令相关的各寄存器的值、API函数调用提示、跳转提示等信息显示。数据窗口以十六进制或内存方式显示文件在内容中的数据，类似于softICE的数据窗口。要显示数据可单击右键"转到→表达式（Go to→expression)"或按Ctrl+G键打开地址窗口，输入地址。寄存器（Registers window)显示CPU各寄存器的值，支持浮点（FPU）、MMX，3DNow！寄存器，可以单击鼠标右键切换。堆栈窗口（Stack window)堆栈窗口非常重要，各API函数、子程序等都利用它传递参数、变量等。OllyDbg堆栈窗口功能强大。如果传递的参数都是字符串，OllyDbg会在注释里直接将其显示出来，再也不用像SoftICE那样经常用D命令查看内存数据了。
详细介绍
运行环境：OllyDbg 可以以在任何采用奔腾处理器的 Windows 95、98、ME、NT 或是 XP（未经完全测试）操作系统中工作，但我们强烈建议您采用300-MHz以上的奔腾处理器以达到最佳效果。还有，OllyDbg 是极占内存的，因此如果您需要使用诸如追踪调试[Trace]之类的扩展功能话，建议您最好使用128MB以上的内存。
支持的处理器 OllyDbg 支持所有 80x86、奔腾、MMX、3DNOW！、Athlon 扩展指令集、SSE指令集以及相关的数据格式，但是不支持SSE2指令集。
配置：有多达百余个选项用来设置 OllyDbg 的外观和运行。
数据格式：OllyDbg 的数据窗口能够显示的所有数据格式：HEX、ASCⅡ、UNICODE、 16/32位有/无符号/HEX整数、32/64/80位浮点数、地址、反汇编（MASM、IDEAL或是HLA）、PE文件头或线程数据块。
帮助：此文件中包含了关于理解和使用 OllyDbg 的必要的信息。如果您还有 Windows API 帮助文件的话（由于版权的问题 win32.hlp 没有包括在内），您可以将它挂在 OllyDbg 中，这样就可以快速获得系统函数的相关帮助。
启动：您可以采用命令行的形式指定可执行文件、也可以从菜单中选择，或直接拖放到OllyDbg中，或者重新启动上一个被调试程序，或是挂接[Attach]一个正在运行的程序。OllyDbg支持即时调试。OllyDbg根本不需要安装，可直接在软盘中运行！
调试DLLs：您可以利用OllyDbg调试标准动态链接库 (DLLs）。OllyDbg 会自动运行一个可执行程序。这个程序会加载链接库，并允许您调用链接库的输出函数。
源码级调试：OllyDbg 可以识别所有 Borland 和 Microsoft 格式的调试信息。这些信息包括源代码、函数名、标签、全局变量、静态变量。有限度的支持动态（栈）变量和结构。
代码高亮：OllyDbg 的反汇编器可以高亮不同类型的指令（如：跳转、条件跳转、入栈、出栈、调用、返回、特殊的或是无效的指令）和不同的操作数（常规[general]、
FPU/SSE、段/系统寄存器、在栈或内存中的操作数，常量）。您可以定制个性化高亮方案。
线程：OllyDbg 可以调试多线程程序。因此您可以在多个线程之间转换，挂起、恢复、终止线程或是改变线程优先级。并且线程窗口将会显示每个线程的错误（就像调用 GETLASTERROR 返回一样）。
分析：OllyDbg 的最大特点之一就是分析。它会分析函数过程、循环语句、选择语句、表[tables]、常量、代码中的字符串、欺骗性指令[tricky constructs]、API调用、函数中参数的数目，import表等等.. 这些分析增加了二进制代码的可读性，减少了出错的可能性，使得我们的调试工作更加容易。
Object扫描。OllyDbg 可以扫描Object文件/库（包括 OMF 和 COFF 格式），解压代码段[code segments]并且对其位置进行定向。
Implib扫描。由于一些DLL文件的输出函数使用的索引号，对于人来说，这些索引号没有实际含义。如果您有与DLL相应的输入库[import library]，OllyDbg 就可以将序号转换成符号名称。
完全支持Unicode：几乎所有支持 ASCⅡ 的操作同时也支持 UNICODE，反之亦然。
名称：OllyDbg 可以根据 Borland 和 Microsoft 格式的调试信息，显示输入/输出符号及名称。Object 扫描器可以识别库函数。其中的名称和注释您可任意添加。如果DLL中的某些函数是通过索引号输出的，则您可通过挂接输入库[import library]来恢复原来的函数名称。不仅如此，OllyDbg还能识别大量的常量符号名（如：窗口消息、错误代码、位域[bit fields]…）并能够解码为已知的函数调用。
已知函数：OllyDbg 可以识别 2300 多个 C 和 Windows API 中的常用函数及其使用的参数。您可以添加描述信息、预定义解码。您还可以在已知函数设定 Log 断点并可以对参数进行记录。
函数调用：OllyDbg 可以在没有调试信息或函数过程使用非标准的开始部分[prolog]和结尾部分[epilog]的情况下，对递归调用进行回溯。
译者注：
004010D0 push ebp \
004010D1 mov ebp,esp |
004010D3 sub esp,10h |prolog
004010D6 push ebx |
004010D7 push esi |
004010D8 push edi /
……
004010C5 pop edi \ 
004010C6 pop esi |
004010C7 pop ebx |epilog
004010C8 mov esp,ebp |
004010CA pop ebp |
004010CB ret /
栈：在栈窗口中，OllyDbg 能智能识别返回地址和栈框架[Stack Frames]。并会留下一些先前的调用。如果程序停在已知函数上，堆栈窗口将会对其参数进行分析解码。
译者注：栈框架[Stack Frames]是指一个内存区域，用于存放函数参数和局部变量。
SEH 链：跟踪栈并显示结构化异常句柄链。全部链会显示在一个单独的窗口中。
搜索：方法真是太多了！可精确、模糊搜索命令或命令序列，搜索常数，搜索二进制、文本字符串，搜索全部命令地址，搜索全部常量或地址域[address range]，搜索所有能跳到选定地址的跳转，搜索所有调用和被调用的函数，搜索所有参考字符串，在不同模块中搜索所有调用、搜索函数名称，在全部已分配的内存中搜索二进制序列。如果搜索到多个结果，您可以对其进行快速操作。
窗口：OllyDbg 能够列出关于调试程序中的各种窗口，并且可以在窗口、类甚至选定的消息上设置断点。
资源：如果 Windows API 函数使用了参考资源串，OllyDbg 可以显示它。其支持显示的类型仅限于附带资源[attached resources]的列表、数据显示及二进制编辑、。
断点：OllyDbg 支持各种断点：一般断点、条件断点、记录断点（比如记录函数参数到记录窗口）、内存读写断点、硬件断点（只适用于ME/NT/2000）等。在Hit跟踪情况下，可以在模块的每条命令上都设置INT3断点。在使用500-MHZ处理器的 Windows NT 中，OllyDbg 每秒可以处理高达 5000 个中断。
监视与监察器：每个监视都是一个表达式并能实时显示表达式的值。您可以使用寄存器、常数、地址表达式、布尔值以及任何复杂代数运算，您还可以比较ASCⅡ和UNICODE
字符串。监察器[inspectors]是一种包含了两个的索引序列的监视[Watches]，它以二维表的形式呈现，可以对数组和结构进行解码分析。
Heap walk.：在基于Win95的系统中，OllyDbg 可以列出所有的已分配的堆。
句柄：在基于NT的系统中，OllyDbg 可列出被调试程序的所有系统句柄。
执行：.您可以单步执行、步入子程序或者步过子程序。您也可以执行程序直到函数返回时、执行到指定地址处，还可以自动执行。当程序运行时，您仍然可以操纵程序并能够查看内存、设置断点甚至修改代码。您也可以任意的暂停或重启被调试的程序。
Hit跟踪：.Hit跟踪可以显示出目前已执行的指令或函数过程，帮助您检验代码的各个分支。Hit跟踪会在指定指令到达之前设置断点，而在这个指令执行后，会把这个断点清除掉。
译者注：Hit在英文中是“击中”的意思，指令如果运行了就表示这个指令被“击中”了，没有执行的指令就是“未击中”，这样我们就很容易看出被调试程序哪些部分运行了，而哪些没有运行。
Run跟踪：Run跟踪可以单步执行程序，它会在一个很大的循环缓冲区中模拟运行程序。这个模拟器包含了除了SSE指令集以外的所以寄存器、标志、线程错误、消息、已经函数的参数。您可以保存命令，这样可以非常方便地调试自修改代码（译者注：比如加壳程序）。您可以设置条件中断，条件包括地址范围、表达式、命令。您可以将Run
跟踪信息保存到一个文件中，这样就可以对比两次运行的差别。Run跟踪可以回溯分析已执行过的上百万条命令的各种细节。
OllyDbg完全支持 UNICODE，几乎所有对 ASCⅡ 字符串的操作都可以同样应用于 UNICODE。
汇编指令都是很相似的。您经常会搞不清自己是不是已经跟踪过某一段代码。在 OllyDbg 中您可以加入自己的标签[labels]和注释[comments]。这些极大地方便了调试。注意一旦您注释了某个DLL，以后每次加载这个DLL时，注释和标签都有效----尽管您在调试不同的程序。
OllyDbg可以跟踪标准的栈帧[stack frames]（由PUSH EBP; MOV EBP,ESP所创建的）。现代编译器有禁止产生标准栈框架的选项，在这种情况下分配栈[stack walk
]是不可能的。当程序运行到已知的函数时，栈窗口[stack window]解析它的参数，调用栈[Call stack]窗口显示到达当前位置所调用函数的序列。
现代的面向对象应用程序广泛地使用了一种叫做结构化异常处理[Structured Exception Handling,SHE]的技术。SHE窗口[SEH window] 可以显示异常处理链。
多种不同的搜索[search]选项可以让您找到二进制代码或数据、命令或命令序列、常量或字符串、符号名或在 Run跟踪中的一条记录。
对于任何地址或常量，OllyDbg 可以找出参考[referencing]到该地址或常量的全部命令的列表。然后您可以在这个列表里找出对您来说是重要的参考。举例来说，某个函数可能被直接调用，或者经过编译器优化后把地址放入寄存器间接调用，或者把地址压入堆栈作为一个参数----没问题，OllyDbg 会找出所有这样的地方。它甚至能找到并列出所有和某个指定的位置有关的跳转。（真的？哦，天哪！……）
OllyDbg 支持所有标准类型的断点[breakpoints]----非条件和条件断点、内存断点（写入或访问）、硬件断点或在整个内存块上下断点（后两项功能只在Window ME,NT,2000,XP中有效）。条件表达式可以非常复杂（“当 [ESP+8] 的第 2 位被设置，并且 123456 位置处的字[word]小于10，或者 EAX 指向一个以“ABC”开头的 UNICODE 字串，但跳过前10次断点而在第11次中断”）。您可以设定一条或多条指令，当程序暂停时由OllyDbg传递给插件插件[plugins]。除了暂停，您还可以记录某个表达式的值（可以带有简短的说明），或者记录 OllyDbg 已知的函数的参数。在Athlon 2600+、Windows2000 环境下，OllyDbg 可以每秒处理多达 25000 个条件断点。
另一个有用的特性是跟踪。OllyDbg 支持两种方式的跟踪：hit和run。在第一种情况下，它对指定范围内的每条指令上设置断点（比如在全部可执行代码中）。当到达设断的指令后，OllyDbg 清除断点并且把该指令标记为hit。这种方法可以用来检测某段代码是否被执行。Hit跟踪速度惊人的快，在一个很短时间的启动后程序几乎达到了全速（译者注：这应该是与不进行调试时速度相比而言）。因为INT3断点可能对数据有灾难性的影响，所以我建议不要使用模糊识别过程。当代码没有被分析时Hit跟踪是不可以使用的。
Run跟踪[Run trace] 是一步一步地执行程序，同时记录精确的运行历史和所有寄存器的内容、已知的参数和可选的指令（当代码是自修改时会有帮助）。当然，这需要大量的内存（每个指令需要15至50个字节，取决于调试的模式）但是可以精确地回溯和分析。您可以只在选定的一段代码甚至是一条指令中进行Run跟踪，或者您可以跳过无关紧要的代码。对于每个地址，OllyDbg能够计算这个地址在Run跟踪日志中出现的次数，虽然会导致执行缓慢但是可以得到代码执行的统计。比如说，某命令让您在每个已识别的过程入口处进行Run跟踪，那么统计[profile]就会给您每个过程被调用的次数。在到达某条指令、某个地址范围或指令计数器达到某一数值时Run跟踪可以自动地暂停[pause]。
在多线程程序里OllyDbg可以自动管理线程[threads]，如果您单步调试或跟踪程序，它会自动恢复当前线程而挂起其它线程。如果您运行程序，OllyDbg 会恢复先前的线程状态。
您可以为内存块建立快照（叫做备份）。OllyDbg会高亮显示所有的改动。您可以把备份保存到文件或从文件中读取出来，从而发现两次运行的不同之处。您可以查看备份，搜索下一处改动，恢复全部或选定的改动。补丁管理器[Patch manager]记录了上次应用到程序中的所有补丁，在下次调试时可以再次应用它们。
您可以很容易地把您的补丁加在可执行文件上。OllyDbg 会自动进行修正。
您不能在带有 Win32 的16位 Windows 下使用 OllyDbg。这种32位扩展操作系统无法实现某些必需的调试功能。
函数[Procedure]（或 函数/参数[Procedure / arguments]）显示了被调用函数的地址，在某些情况下，OllyDbg并不能保证该地址是正确的并会添加如下标记之一：
找到的入口点不可靠
可能[Maybe] OllyDbg无法找到精确的入口点，报告的地址是用启发式算法猜测的。
包含[Includes] OllyDbg无法找到入口点，仅知道该函数包含显示的地址
通过按例标题栏上的按钮或从菜单中选择“隐藏/显示参数[Hide/Show arguments]”，可以在显示或隐藏函数的参数之间切换。
调用来自[Called from]用于显示调用该函数的命令地址。最后一栏是框架[Frame]这一栏默认是隐藏的，如果框架指针的值（寄存器EBP）已知的话，则该栏用于显示这个值。
当调用函数经过分析[analyzed].后，栈移动会更可靠并且迅速。十六，调用树[Call tree]
调用树（快捷键：在反汇编窗口中Ctrl+K）利用分析[Analysis]的结果来找出指定函数过程直接或间接调用的函数列表，同时列出指定函数过程被调用的地址。为了避免由此可能造成的副作用。调用树会判断选定函数是否明确地是递归的。“明确地”意味着它不会跟踪目标未知的调用，比如CALL EAX。如果函数过程中有未知调用，调用树将会添加标记“未知目标”。
某些函数调用将会添加如下注释之一：
当自解压选项[SFX options]要求跟踪真正入口时，OllyDbg 在整个代码节[Code section]设置内存断点，最初这里是空的，或者只包含压缩数据。当程序试图执行某个在这个保护区域的命令，而这些命令不是 RET 和 JMP 时，OllyDbg 会报告真正的入口。这就是提取工作的原理。
上面的方法非常慢。有另外一种比较快的方法。每次读取数据发生异常时，OllyDbg 使这个4K内存区域变为可读，而使原先可读的区域变为无效。而每次发生写数据异常时，
OllyDbg 使这个区域变为可写，而使原先可写的区域变为无效。当程序执行在保留的保护区域中的指令时，OllyDbg 报告真正的入口。但是，当真正的入口点在可读或可写区域内部时，报告的地址就可能有误。
您可以纠正入口位置，选择新的入口，从反汇编窗口的快捷菜单中选择“断点[Breakpoint]|设置真正的自解压入口[Set real SFX entry here]”。如果相应的SFX选项是开启的，OllyDbg下次可以迅速而可靠的跳过自提取程序。
注意：OllyDbg 在跟踪采取了保护或者反调试技术的解压程序时通常会失败。 ；二十，单步执行与自动执行[Step-by-step execution and animation]
您可以通过按 F7（单步步入）或 F8（单步步过），对程序进行单步调试。这两个单步执行操作的主要区别在于：如果当前的命令是一个子函数，按F7，将会进入子函数，并停在子函数的第一条命令上；而按 F8，将会一次运行完这个子函数。如果您单步步过的子函数中含有断点或其他调试事件，执行将会被暂停，但 OllyDbg 会在子函数的后一条命令上，自动下一个断点，而这个断点您迟早会碰到。
如果被调试程序停在异常上，您可以跳过它，并转到被调试程序建立的句柄处。只需简单的 Shift 键和任何一个单步命令。
如果需要连续按F7、F8键上百次，您可以使用自动执行（Ctrl+F7或者Ctrl+F8）功能。在这种情况下，OllyDbg 将自动重复F7或者F8操作，并且实时更新所有的窗口。这个过程会在下面情况停止：
- 按 Esc 键或发出任何单步命令
- OllyDbg 遇到断点
- 被调试程序发生异常
使用“+”和“-”按键，可以回朔以前的执行历史[execution history].
注意：当执行停止时 OllyDbg 将会刷新大部分窗口。如果动态执行过程非常慢，可以尝试关掉或最小化没有用的窗口。
另外，更快捷的找到以前执行指令的办法是Run跟踪[run trace]。它将创建一个执行协议并告知您指定指令的执行时间和次数二一，Hit跟踪[Hit trace]
Hit跟踪能够让您辨别哪一部分代码执行了，哪一部分没有。OllyDbg的实现方法相当简单。它将选中区域的每一条命令处均设置一个INT3断点。当中断发生的时候，OllyDbg便把它去除掉，并把该命令标志为命中[hit]。因为每个跟踪断点只执行一次，所以这种方法速度非常快。
在使用Hit跟踪的时候，一定要注意不能在数据中设置断点，否则应用程序极有可能崩溃。因此，您必须打开相关的菜单选项，以进行代码分析[analyze]。我推荐您选择严格或启发式函数识别[strict or heuristical procedure recognition]。如果选择模糊[Fuzzy]的话，可能会产生很多难以容忍的错误，而且经常把本不是函数的代码段识别成函数。
只要您在模块中设置了跟踪断点，哪怕只设了一个，OllyDbg都会分配两倍于代码段大小的缓冲区。
注意：当您退出Hit跟踪的时候，Run跟踪也会同时退出。
[color=blue]Run 跟踪[Run trace][/color]
Run跟踪是一种反方向跟踪程序执行的方式，可以了解以前发生的事件。您还可以使用Run跟踪来了解运行的简单统计[profile]。基本上，OllyDbg 是一步一步地执行被调试程序的，就像动画[animation]演示一样，但不会实时刷新窗口，最重要的是它能将地址、寄存器的内容、消息以及已知的操作数记录到Run跟踪缓冲区中。如果被调试的代码是自修改的，您就能够保存原始的命令。可以通过按Ctrl+F11（Run跟踪步入，进入子函数）或者Ctrl+F12（Run跟踪步过，一次执行完子函数）开始Run跟踪，并用F12或者Esc键停止跟踪。
您可以指定在Run跟踪时执行每一步的条件集（快捷键：Ctrl+T）。如果条件符合，Run跟踪将暂停。条件包括：
当CPU窗口中的反汇编面板[Disassembler pane]处于激活状态时，您可以使用以下快捷键：
回车键 - 将选中的命令添加到命令历史[command history]中，如果当前命令是一个跳转、函数或者是转换表的一个部分，则进入到目的地址。
退格键 - 移除选中部分的自动分析信息。如果分析器将代码误识别为数据，这个快捷键就非常有用。请参考解码提示[decoding hints].
Alt+退格键 - 撤消所选部分的修改，以备份数据的相应内容替换所选部分。仅当备份数据存在且与所选部分不同时可用。
Ctrl+F1 -如果API帮助文件已经选择，将打开与首个选择行内的符号名相关联的帮助主题。
F2 -在首个选择的命令上开关INT3 断点[Breakpoint]，也可以双击该行第二列。
Shift+F2 -在首个选择命令设置条件断点，参见忽略Kernel32中内存访问异常[Ignore memory access violations in Kernel32]。
F4 -执行到所选行，在首个选择的命令上设置一次性断点，然后继续执行调试程序，直到OllyDbg捕获到异常或者停止在该断点上。在程序执行到该命令之前，该一次性断点一直有效。如有必要，可在断点窗口[Breakpoints window]中删除它。
Shift+F4 -设置记录断点（一种条件断点，当条件满足时一些表达式的值会记录下来）， 详情参见断点[Breakpoint]。
Ctrl+F5 -打开与首个选择的命令相对应的源文件。
Alt+F7 -转到上一个找到的参考。
Alt+F8 -转到下一个找到参考。
Ctrl+A -分析当前模块的代码段。
Ctrl+B - 开始二进制搜索。
Ctrl+C -复制所选内容到剪贴板。复制时会简单地按列宽截断不可见内容，如果希望排除不需要的列，可把这些列的宽度调整到最小。
Ctrl+E -以二进制（十六进制）格式编辑所选内容。
Ctrl+F -开始命令搜索。
Ctrl+G -转到某地址。该命令将弹出输入地址或表达式的窗口。该命令不会修改 EIP。
Ctrl+J -列出所有的涉及到该位置的调用和跳转，在您用这个功能之前，您必须使用分析代码功能。
Ctrl+K - 查看与当前函数相关的调用树[Call tree]。在您用这个功能之前，您必须使用分析代码功能。
Ctrl+L - 搜索下一个，重复上一次的搜索内容。
Ctrl+N - 打开当前模块的名称（标签）列表。
Ctrl+O - 扫描object文件。扫描Object文件。该命令会显示扫描Object文件对话框，您可以在该对话框中选择Object文件或者lib文件，并扫描这个文件，试图找到在实际代码段中用到的目标模块。
Ctrl+R -搜索所选命令的参考。该命令扫描激活模块的全部可执行代码，以找到涉及到首个选中的命令的全部相关参考（包括：常量、跳转及调用），您可以在参考中使用快捷键 Alt+F7 和 Alt+F8来浏览这些参考。为便于您使用，被参考的命令也包含在该列表中。
Ctrl+S -命令搜索。该命令显示命令查找[Find command]对话框供您输入汇编命令，并从当前命令开始搜索。
星号[Asterisk](*) -转到原始位置（激活线程的EIP处）。
Ctrl+星号（*) - 指定新的起始位置，设置当前所选线程的EIP为首个选择字节的地址。您可以在选择EIP并撤消该操作。
加号[Plus](+) -如果run跟踪[run trace] 没有激活，则根据命令历史[command history]跳到下一条运行过命令的地方；否则跳到Run跟踪的下一个记录。
Ctrl+加号 - 跳到前一个函数开始处。（注意只是跳到，并不执行）
减号[Minus](-) - 如果run跟踪[run trace] 没有激活，则根据命令历史[command history]跳到前一条运行过命令的地方；否则跳到Run跟踪的前一个记录。
Ctrl+减号 - 跳到下一个函数开始处。（注意只是跳到，并不执行）
空格[Space] - 修改命令。您可在显示对话框中以汇编语言修改实际指令或输入新指令，这些指令将替换实际代码，您也可以在想要修改的指令处双击鼠标。
冒号[Colon](:) - 添加标签。显示添加标签窗口[Add label]或修改标签窗口[Change label]，您可在此输入与首个选择的命令中的第一个字节相关联的标签（符号名）。注意，在多种编程语言中，冒号可以是标签的一部分。
分号[Semicolon](;) - 添加注释[comment]。显示添加注释窗口[Add label]或修改注释窗口[Change label]，您可在此输入与首条所选命令的第一个字节相关联的注释（注释串会显示在最后一列中）。注意，多种汇编语言使用分号作为注释开始。您也可以在注释列双击需要注释的命令行。
插件[Plugins]
插件是一个DLL，存放在OllyDbg的目录中，用于增加 OllyDbg 的功能。您可以从 OllyDbg 的主页上（[url]http://home.t-online. de/home/Ollydbg[/url]）免费下载插件开发工具包
plug110.zip。
插件可以设置断点，增加标签和注释，修改寄存器和内存。插件可以添加到主菜单和很多的窗口（比如反汇编窗口、内存窗口）的快捷菜单中，也可以拦截快捷键。插件还可以创建MDI（多文档界面）窗口。插件还可以根据模块信息和OllyDbg.ini文件，将自己数据写到.udd文件中；并能读取描述被调试程序的各种数据结构。插件API包含了多达170
个函数。
许多第三方插件都可以从Internet网上获得，比如由网友TBD创建并维护的OllyDbg的论坛（[url]http://ollydbg.win32asmcommunity. net[/url]）。
安装插件的方法：将DLL复制到插件目录[plugin directory]中，然后重新启动Ollydbg。默认情况下，这个插件目录为ollydbg.exe文件所在的目录。
现在的版本中已经包含了两个“原始”插件：书签[Bookmark] and 命令行[Command line]. 他们的源代码都保存在plug110.zip.文件中。这些插件都是免费的，您可以任意修改或使用它们。
[color=blue]技巧提示[Tips and tricks][/color]
?OllyDbg 可以作为二进制编辑器使用。选择视图[View]→文件[File]并选定需要查看的文件。文件不能大于剩余内存数量。
?假使您修改了内存中的执行文件，这时您想恢复修改的部分，但是您忘记哪里被修改了，您可以把原始文件当作备份进行加载，这样您就可以找到修改的部分了。
分析前，先扫描 OBJ 文件。这时 OllyDbg 会对已知 C 函数的参数进行解码。
一些表格中包含了隐藏数据。可以通过增加列宽来显示出来。
所有数据窗口（包括反汇编窗口），可以通过双击显示相对的地址。
您可以通过 Ctrl +↑ 或 Ctrl+↓ 对数据窗口翻动一个字节。
[color=darkblue]调试独立的DLL[Debugging of stand-alone DLLs][/color]
打开DLL，也可以直接将其从资源管理器拖放到 OllyDbg 上。OllyDbg 会询问您并将该文件的全路径作为参数传递给loaddll.exe.。然后链接库被加载并停在代码的入口（
）。您可以设置断点，运行或跟踪启动代码，等等。在初始化完成后，应该程序会再次暂停。这次停在标签名为 Firstbp 的位置，其在立即进入主消息循环之前。
现在，您可以调用DLL函数。从主菜单选择“调试[Debug]|调用DLL输出[Call DLL export]”。这时会弹出一个对话框。由于这个对话框是无模式对话框，因此您仍然能够使用OllyDbg的全部功能，比如查看代码、数据，查看断点，修改内存等等。
选择您想调用的函数。例如我们将开始使用 USER32.DLL 里的MessageBox 函数。注意loaddll.exe 已经使用了这个链接库，因此会假定这个 DLL 已经初始化而不再调用入口。MessageBox 这个函数名是通用函数名，实事上，这个函数有处理 ASCⅡ 的 MessageBoxA 和处理 Unicode 的MessageBoxW 两种。我们继续往下看：在我们选择这个函数后，右边的消息框中会出现 Number of arguments: 4（有四个参数）的字样。OllyDbg 会根据函数尾部的RET 10语句来正确识别参数的数量。RET nnn 
是使用PASCAL调用约定的函数的典型特征。（参数被放入栈中，第一个参数会被最后一个压入栈中，函数调用完毕后，参数会被遗弃）。大多数的 Windows API 函数都是
PASCAL形式的。
下一步，我们要设定栈中参数的个数。在这个例子中，不必做进行这个操作，因为OllyDbg已经知道了MessageBoxW函数的参数数量。但是，如果您愿意的话，也可以单击左边的复选框，改变成您认为合适的参数数量
现在填写参数列表。这个对话框中支持至多10个参数. 参数可以是任何有效的表达式，而不必使用寄存器。如果操作数指向了内存，则参数右边的缓冲区窗口会显示内存中的数据。Loaddll.exe 有10个大小为1K的缓冲区，这些缓冲区被标记为Arg1 .. Arg10，，您可以方便自由的使用它们。另外，对话框还支持两个伪变量：由loaddll.exe创建的父窗口句柄， 以及loaddll的实例句柄。为了方便您的使用，在您第一次使用调用输出函数时，OllyDbg就已经将这两个伪变量加到了历史列表中去了。
MessageBoxW e函数需要4个参数：
?父窗口句柄。这里我们选择 ；handle of owner window. Here,we simply select ;
?在消息框中UNICODE文本的地址。选择Arg2并按回车。缓冲区窗口会以16进制的格式显现内存中的缓冲区。这个缓冲区初始化全是0。点击第一个字节，并按快捷键
Ctrl+E（另外，也可以从菜单中选择“二进制[Binary]|编辑[Edit]”）。这时会出现一个对话框，在对话框中键入“Text in box”或者其他希望显示的字符串；
?消息框标题的UNICODE文本的地址。选择Arg3并在Unicode格式的内存中写上“Box title”；
?消息框的风格。使用常量MB_xxx进行组合.OllyDbg 可以识别这些常量。在这里我们键入：MB_OK|MB_ICONEXCLAMATION。
这里不需要寄存器参数。
现在我们准备调用输出函数。选项“在调用时隐藏[Hide on call]”意思是说，当函数运行时对话框将会从屏幕消失。当我们执行一个会运行很长时间的函数，或者设置了断点的时候，这个选项非常的有用。您也可以手动关闭对话框。当函数执行完毕后，OllyDbg会重新自动打开。“调用输出函数”对话框。选项“在调用后暂停[Pause after call]”意思是说，在执行完函数后，loaddll将会被暂停。
按“调用[Call]按钮”后，OllyDbg 会自动备份所有的内存、校验、参数、寄存器等信息。并隐藏对话框，然后调用 MessageBoxW 函数。和期望的一样，消息框在屏幕中出现了：
[img]http://groups.msn. com/_Secure/0cgDvAt0gqCx*VnJiVlT79*fFmiyfIJrL1diSHtf7m4m3LNGaibFjk1iUQSsMo3d!8GXeH6em0*I9Mk21pTpPMxIYYOtm2HvNluWwbU*OK*oFBjq4eIf0ezBiGKAKJKdU67ObrqhBIK9jR!25g*3Ow5dP08iL4hVZNZyO0JeS8Bc/%E8%B0%E8%AF%E7%AC%E7%AB%E7DLL2.JPG?dc=4675538092381011503[/img]
函数 MessageBoxW 不会修改参数。如果您调用的函数更新了内存，比如函数 GetWindowName，修改的字节将会在数据区里高亮。注意：EAX 返回值为1，表示成功。
其他的例子请访问我的网站：
[url]http://home.t-online. de/home/Ollydbg/Loaddll.htm.[/url]
不幸的是，您不能通过这种方式调试OllyDbg的插件，插件关联到ollydbg.exe文件，Windows系统不能在同一个应用程序里加载并运行两个可执行文件。
[color=blue]解码提示[Decoding hints][/color]
在某些情况下，分析器不能区分代码和数据。让我们看看下面的例子：
const char s[11] = "0123456789";
...
for (i=0x30; i内存中间码
内存中间码 = 中间码| { 符号标志 大小标志 前缀} [表达式 ]
中间码 = （表达式）| 一元操作符 内存中间码 | 带符号寄存器 | 寄存器 | FPU寄存器 | 段寄存器 | 整型常量 | 浮点常量 | 串常量 | 参数 | 伪变量
一元操作符 = ! | ~ | + |
带符号寄存器 = 寄存器.
寄存器 = AL | BL | CL ... | AX | BX | CX ... | EAX | EBX | ECX ...
FPU寄存器 = ST | ST0 | ST1 ...
段寄存器 = CS | DS | ES | SS | FS | GS
整型常量 = . | | |
浮点常量 =
串常量 = ""
符号标志 = SIGNED | UNSIGNED
大小标志 = BYTE | CHAR | WORD | SHORT | DWORD | LONG | QWORD | FLOAT | DOUBLE | FLOAT10 | STRING | UNICODE
前缀 = 中间码：
参数 = %A | %B // 仅允许在监察器[inspector] 中使用
伪变量 = MSG // 窗口消息中的代码
这个语法并不严格。在解释[WORD [EAX]]或类似的表达式时会产生歧义。可以理解为以寄存器EAX所指向地址的两字节内容为地址，所指向的双字内容；也可以理解为以寄存器EAX所指向地址的四字节内容为地址，所指向的两字节内容。而OllyDbg会将修饰符尽可能的放在地址最外面，所以在这种情况下，[WORD [EAX]] 等价于 WORD [[EAX]]。
默认情况下，BYTE、WORD 和 DWORD 都是无符号的，而CHAR、SHORT 和 LONG都是带符号的。也可以使用明确的修饰符SIGNED 或 UNSIGNED。例如在二元操作时，如果一个操作数是浮点的，那么另外一个就要转成浮点数；或者如果一个是无符号胆，那么另外一个要转成无符号的。浮点类型不支持UNSIGNED。大小修饰符后面跟 MASM兼容关键字PTR（如：BYTE PTR）也允许的，也可以不要PTR。寄存器名和大小修饰符不区分大小写。
您可以使用下面类C的运算符（0级最高）：
优先级 类型 运算符
0 一元运算符 ! ~ + -
1 乘除运算 * / %
2 加减运算 + -
3 位移动 >
4 比较 >=
5 比较 == !=
6 按位与 &
7 按位异或 ^
8 按位或 |
9 逻辑与 &&
10 逻辑或 ||
在计算时，中间结果以 DWORD 或 FLOAT10 形式保存。某些类型组合和操作是不允许的。例如：QWODRD 类型只能显示；STRING 和 UNICODE 只能进行加减操作（像C语言里的指针）以及与 STRING、UNICODE 类型或串常量进行比较操作；您不能按位移动 浮点[FLOAT] 类型，等等。
自定义函数描述[Custom function descriptions]
概论[Introduction]
OllyDbg包含（做为内部资源）1900多种标准函数以及400多种标准C函数的名称和参数。分析器[Analyzer] 用这些描述使被调试程序更加易懂。比较下面一个例子，分析器的函数CreateFont：
PUSH OT.00469F2A ; ASCⅡ "Times New Roman"
PUSH 12 
PUSH 2 
PUSH 0 
PUSH 0 
PUSH 0 
PUSH 0 
PUSH 0 
MOV EAX,DWORD PTR [49FA70]
PUSH EAX
PUSH 190 
PUSH 0 
PUSH 0 
PUSH 0 
PUSH 10 
CALL
这是分析后的：
MOV EAX,DWORD PTR [49FA70] 
PUSH OT.00469F2A ;FaceName = "Times New Roman"
PUSH 12 ;PitchAndFamily = VARIABLE_PITCH|FF_ROMAN
PUSH 2 ;Quality = PROOF_QUALITY
PUSH 0 ;ClipPrecision = CLIP_DEFAULT_PRECIS
PUSH 0 ;OutputPrecision = OUT_DEFAULT_PRECIS
PUSH 0 ;CharSet = ANSI_CHARSET
PUSH 0 ;StrikeOut = FALSE
PUSH 0 ;Underline = FALSE
PUSH EAX ;Italic => TRUE
PUSH 190 ;Weight = FW_NORMAL
PUSH 0 ;Orientation = 0
PUSH 0 ;Escapement = 0
PUSH 0 ;Width = 0
PUSH 10 ;Height = 10 （16.)
CALL ;CreateFontA
显然，后面的代码更容易理解。API函数CreateFont 有14个参数。分析器标记所有这些参数的名称并解码他们的值。如果寄存器跟踪开启，那么分析器同时会解码参数Italic
的值为地址49FA70处双字长的内容。解码使用参数的真实值，所以如果[49FA70]里的内容改变了，那么参数Italic的值也会随之改变。当EIP指向跳转或调用该函数的命令，或指向入口时，OllyDbg也会在栈中对已知函数的参数进行解码。
OllyDbg可以对像printf()这样参数个数可变的函数进行参数解码：
PUSH EAX ;
PUSH E8 ; = E8 （232.)
PUSH EBX ;
PUSH Mymodule.004801D2 ;format = "Size %08X (%.*s) bytes"
PUSH ESI ;s
CALL Mymodule.sprintf ;sprintf
您可以定义自己的函数。每次您打开某个应用程序时，OllyDbg都会重新设置函数参数表并用内嵌描述添充这个表。然后尝试打开文件“\common.arg”和“\.arg”，这里使用8.3格式（DOS）被调试程序文件名（不带路径和扩展名）。
下面看一个简单的.arg文件实例：
INFO Simple .ARG file that decodes CreateHatchBrush
TYPE HS_X
IF 0 "HS_HORIZONTAL"
IF 1 "HS_VERTICAL"
IF 2 "HS_FDIAGONAL"
IF 3 "HS_BDIAGONAL"
IF 4 "HS_CROSS"
IF 5 "HS_DIAGCROSS"
ELSEINT
END
TYPE COLORREF
IF 0 ""
IF 00FFFFFF ""
OTHERWISE
TEXT "RGB("
FIELD 000000FF
UINT
TEXT ","
FIELD 0000FF00
UINT
TEXT ","
FIELD 00FF0000
UINT
TEXT ")"
END
STDFUNC CreateHatchBrush
"style" HS_X
"colorref" COLORREF
END
标准Windos API函数CreateHatchBrush(int style,int colorref) 有两个参数。第一个必须是阴影风格[hatch style]，第二个是常量由红色、绿色、蓝色组成，并用一个32
位整数的低三字节表示。为了解码这些参数，文件定义了两个新的参数类型：HS_X 和 COLORREF。
阴影风格是一个简单的枚举类型，如0表示HS_HORIZONTAL（水平风格）、1表示HS_VERTICAL（垂直风格）。IF关键字比较参数与第一个操作数（注意：其总是十六进制的），如果相同则显示第二个操作数里的文本。但万一匹配失败会如何？关键字ELSEINT 会然OllyDbg会将参数解释为一个整数。
COLORREF 更复杂一些。首先尝试解码两个广泛使用的颜色值：黑（全0组成）与白（全0xFF组成）。如果匹配失败，COLORREF尝试解码颜色为一个结构包含红、绿、蓝的亮度。FIELD会用第一个操作数与参数进行逻辑与操作。然后转换结果为整数，并同时按位右移第一个操作及该整数，直到第一个操作数的二进制个位数字为1，这时整数按位右移的结果以无符号10进制显示出来。这个例子做了三次这样的操作，以分离出每个颜色成份。TEXT关键字用于无条件显示文本。如果参数为00030201，那么
COLORREF将其解码为RGB（1.,2.,3.）。
大多断API函数都会从栈中移除参数并保护寄存器EBX,EBP,ESI 和 EDI。声明这样的函数为STDFUNC，以告诉分析器该函数做了这样的事情。否则请其描述为FUNCTION
。
万一某个参数由多个域及比特值组成，比如上面提到的fdwPitchAndFamily ，我们该怎么办？请看下面这个例子：
TYPE FF_PITCH
MASK 03
IF 00 "DEFAULT_PITCH"
IF 01 "FⅨED_PITCH"
IF 02 "VARIABLE_PITCH"
ELSEHEX
TEXT "|"
MASK 0C
BIT 04 "4|"
BIT 08 "8|"
MASK FFFFFFF0
IF 00 "FF_DONTCARE"
IF 10 "FF_ROMAN"
IF 20 "FF_SWISS"
IF 30 "FF_MODERN"
IF 40 "FF_SCRIPT"
IF 50 "FF_DECORATⅣE"
ELSEHEX
END
前两个比特位（第0和等1位）表示倾斜度，必须一起解码。我们使用 MASK 03 来提取这两个比特并通过IF序列来解码。增加了连接符“|”，分别提取第2和第3个比特位，并分别单独解码。最后提取剩余部分并进行解码。
OllyDbg 会移除生成串尾部的连接符“|”、空格、冒号、逗号、分号和等号。
目前版本的分析仅能够解码32位参数。如您不能解码双精度浮点或长双精度浮点的函数参数。
格式描述
自定义解码信息由函数描述和类型描述两部分组成。函数描述部分非常的简单：
FUNCTION|STDFUNC [模块名]函数名
……
END
如果函数从栈中移除参数并保护寄存器EBX,EBP,ESI 和 EDI，请使用关键字STDFUNC。大多少函数都遵循这样的规则。其他情况则声明为FUNCTION。模块（EXE 或 DLL）名是可选的。如果模块名被忽略，OllyDbg会对尝试匹配任何模块。模块名不区分大小写。
函数名称总是区分大小写的。有针对UNICODE的函数必须使用后缀 A 或 W 加以区分，比如SetWindowTextA.。
参数的顺序又C风格的参数使用惯例一致。而16位Windows和32位API函数也是按惯例使用。如果参数名由多个字组成，或者包含特殊字符，那么请将其用两个单引号引起来。与在C语言中一样，省略号（叄┦且桓鎏厥獾募锹加糜诒硎静问 靠杀洹K 匦朐诤 枋龅淖詈蟆 llyDbg不会尝试解码这样的参数。如果函数的参数为空，则按functionname(void）对待
OllyDbg 仅支持32位的参数。某些参数已经预定义好了：
INT ；以十六进制和带符号整数两种格式显示值
UINT ；以十六进制和无符号整数两种格式显示值
HEX ；以十六进制格式显示值
BOOL TRUE 或 FALSE
CHAR ASCⅡ 字符
WCHAR UNICODE 字符
FLOAT 32位浮点数
ERRCODE 系统错误代码（像由函数GetLastError()报告的）
ADDR,PTR ；地址（特殊情况：NULL）
ASCⅡ ASCⅡ 串指针
UNICODE UNICODE 串指针
FORMAT 在类似函数printf()（不包括wscanfW()！）使用的 ASCⅡ 格式串
WFORMAT 类似函数wsprintfW()（不包括scanf()！）使用的 UNICODE 格式串
RECT RECT（矩形）结构指针
MESSAGE MSG（ASCⅡ 窗口消息）结构指针
WMESSAGE MSG（UNICODE 窗口消息）结构指针
HANDLE ；句柄（特殊情况：NULL,ERROR_INVALID_HANDLE）
HWND 窗口句柄
HMODULE 模块句柄
RSRC_STRING 带索引的资源串
NULL,DUMMY ；有参数，但解码时跳过了
您不能重定义预定义类型。自定义类型允许您将参数分离成几个域并分别解码。类型描述有以下几种格式：
TYPE 类型名
[TEXT "任何文本"]
[]
[TEXT "任何文本"]
[PURGE]
...
[TEXT "任何文本"]
END
类型名的程度限制在16个字符以内。OllyDbg会无条件将"任何文本"作为生成的解码。域选择器提取一部分参数用于解码。以下域选择器，可以用于提取域：
MASK 十六进制掩码 - 域等于参数同十六进制掩码按位与（AND）的结果。
FIELD 十六进制掩码 - 参数同十六进制掩码按位与（AND）的数值，然后OllyDbg同时按位右移掩码和计算的数值直到掩码的二进制个位为1，这时数值按位右移的结果就是域的值。例如参数0xC250， FIELD F0，得到的结果是5。
SIGFIELD十六进制掩码 -参数同十六进制掩码按位与（AND）的数值，然后OllyDbg同时按位右移掩码和计算的数值直到掩码的二进制个位为1，这时数值按位右移的结果转成带符号32位数就是域的值。例如参数0xC250 ，SIGFIELD FF00，得到的结果是0xFFFFFFC2。
简单域的解码会一次显示整个域的内容：
HEX - 以十六进制形式显示域内容；
INT - 以带符号十进制形式显示域内容（带小数点）；
UINT -以无符号十进制形式显示域内容（带小数点）；
CHAR - 以 ASCⅡ 字符形式显示域内容。
域若是一个枚举类型，则可以使用IF序列，如果必要的话还可以在IF序列后跟关键字 TRYxxx 与 ELSExxx：
IF 十六进制值 "文本" - 如果域等于十六进制值，则将文本作为输出字符串；
TRYASCⅡ - 如果域是一个指向ASCⅡ串的指针，则显示这个串；
TRYUNICODE - 如果域是一个指向UNICODE串的指针，则显示这个串；
TRYORDINAL - 如果域是一序号（有16位均为0），则会显示为序号（“#”后跟整数）；
OTHERWISE - 如果前面IF语句为真，则停止解码，否则继续解码；
ELSEINT - 如果前面所有的 IF 和 TRYxxx 语句均失败，则以带符号十进制数形式（带小数点）显示这个域；
ELSEHEX -如果前面所有的 IF 和 TRYxxx 语句均为失败，则以十六进制形式显示这个域；
ELSECHAR -如果前面所有的 IF 和 TRYxxx 语句均为失败，则以 ASCⅡ 字符形式显示这个域；
ELSEWCHAR -如果前面所有的 IF 和 TRYxxx 语句均为失败，则以 UNICODE 字符形式显示这个域。
如果域是一个二进制位集，则可以使用BIT序列，如果必要的话可以后面跟关键字 BITZ 与 BITHEX ：
BIT 十六进制掩码 "文本" - 如果值与十六进制掩码按位与（AND）的结果不是0，则将文本做为输出串；
BITZ十六进制掩码 "文本" - 如果值与十六进制掩码按位与（AND）的结果是0，则将文本做为输出串；
BITHEX十六进制掩码 - 如果值与十六进制掩码按位与（AND）的结果不是0，则将结果以十六进制形式显示。
常见问题
怎样保存ollydbg的调试信息以便下次使用?
调试菜单->；选择符号路径 然后在弹出的对话框设置路径即可。注意调试文件为udd格式，，当被调试文件路径发生变化时调试信息不再可用，，比如：你在C盘有一个文件用ollydby调试并加入注视或断点后，，把这个文件移到别的路径下，再用ollydbg打开调试信息注视和断点不被显示。
注意：断点和注释窗口只能查看到当前模块的断点和注释，且当前被ollydbg分析为代码的断点和注释才能被看到。