OllyDebug,简称OD,一种反汇编软件,动态追踪工具,将IDA与SoftICE结合起来的思想,Ring 3 级的调试器。OllyDebug的使用界面是可视化操作。
OD有很多民间的版本,菜单栏和和工具栏的配置可能有所差别。比较好用的是吾爱破解和吾爱汇编的中文Ollydbg版本。
深入学习OllyDBG的调试技巧可以看《加密与解密》一书
真正的技术是练习得来的,工具本身的操作并没有多么神秘,常用核心操作很少,使用工具进行实战调试和积累各种正向工程的知识最重要
OD的基本使用不需要有任何基础知识,但是进行调试分析需要有一定的汇编语言基础
热闹中著一冷眼,便省去许多苦心思;冷落处存一热心,便得许多真趣味。
——洪应明
目录
1.光标可以点在任何一行汇编代码,双击EIP寄存器的值,可以回到当前动态调试执行的代码的地址,EIP寄存器的值是不能直接修改的
在逆向分析领域,分析者会利用相关的调试工具来分析软件的行为并验证分析结果
动态分析是随着程序运行,随时中断目标的指令流程
在某些场合不适合运行目标进行动态调试(例如病毒)
静态调试的王者是IDA pro (也可以动态调试)
动态分析的工具就是OD(Ollydbg)
IDA pro和OD是逆向工程中的倚天剑和屠龙刀
壮士愤,雄风生。
安得倚天剑,跨海斩长鲸。
——《临江王节士歌》
此外,还有x64dbg,x64dbg有自己的官方网站,OD非官方的民间修改版本比较流行
x64dbg可以调试64位程序,x32dbg可以调试32位程序,OD只有一个版本,只能调试32位程序
所以在面对64位文件的时候,我们需要使用X64dbg,不能使用OD
逆向工程必备的调试工具有:

OllyDbg(以其作者Oleh Yuschuk的名字命名)是一个用于直接分析二进制程序的x86调试器,通常应用于找不到源代码的程序的调试。它会跟踪寄存器、过程、API、I/O、表格、常量以及字符串等。它具有友好的GUI,并且可以通过安装第三方插件来扩展它的功能。其1.x版本在1.10开发完毕后终止。
2.0版本于2010年6月发布,该版本并没有延续1.x版本的代码,而是转而重写。尽管OllyDbg到现在为止还不支持反汇编x64处理器编译的二进制文件,但开发人员已经承诺将在以后的版本中支持调试x64处理器的程序。

开发者Oleh Yuschuk
脑补一下你想象中的hacker界面
可能是有很多的窗口
或者是影视中常见的字符串雨
这些画面看起来十分炫酷,显示中的hacker工作也需要在大量的数据中进行检索,找到自己需要的关键data或code
我们来看一下OD的界面

这是一个英文版的Ollydbg
如图,由5个窗口构成
反汇编窗口显示汇编语言指令
可以使用快捷键单步执行汇编指令
寄存器窗口会显示当前寄存器的值
数据窗口显示当前程序的十六进制表示

如图是反汇编窗口的三栏内容

如图所示,寄存器窗口显示了当前程序执行状态的寄存器的值
就是程序动态调试到这一步时,寄存器中存储的值

会显示程序的一些信息

上图是一款中文版OD的信息窗口
我们知道操作一个软件,可以使用菜单栏,工具栏
同时常用操作都有对应的快捷键,效果和菜单栏相同
下面是OD的基本操作和对应的快捷键
| 快捷键 | 操作 |
|---|---|
| F2 | 下断点,指定断点的地址 |
| F3 | 加载一个可执行程序,进行调试分析 |
| F4 | 程序执行到光标位置 |
| F5 | 缩小,还原当前窗口 |
| F7 | 单步步入(执行一个汇编指令,遇到过程调用会进入) |
| F8 | 单步步过(执行一个汇编指令,遇到过程调用会跳过) |
| F9 | 直接运行程序,遇到断点处,程序暂停 |
| Ctrl+F2 | 重新运行程序到起始处,一般用于重新调试程序 |
| Ctrl+F9 | 执行到函数返回处,用于快速跳出函数 |
| Alt+F9 | 执行到用户代码处,用于快速跳出系统函数 |
| Ctrl+G | 输入十六进制地址,快速定位到该地址处 |
| ALT+B | 显示断点编辑器对话框 |
| ; | 添加注释 |
更多详细操作见帮助文档,没必要掌握
基本操作部分演示视频
OD基操演示
在bilibili内观看更清晰
动态调试就是让程序运行起来调试,可以一步一步执行代码调试
我们在动态调试的时候,需要打断点,让程序在需要分析的地方停下来
Ollydbg中有两种类型的断点
OD中使用F2快捷键设置的断点就是INT3断点
打INT3断点的时候,断点处就会被CCh(INT3指令的机器码)替换
在指令处右击,按照以下方式选择

可以设置无数个断点
改变了原程序的指令
为了防止API被下断点,就会判断API的首地址是不是CCh
取函数的第一个字节,进行判断,是否下了断点
硬件断点和DRx调试器有很大关系
从Intel CPU体系架构中可以找到DRx的介绍
使用4个调试寄存器 DR0,DR1,DR2,DR3,设置地址
使用一个寄存器DR7设定状态
最多设置4个硬件断点
速度比较快,在INT3断点容易被发现的地方使用硬件断点
最多只有三个断点

执行用户编写的程序代码的领空
地址比较大(比较大的概念如图所示,灵活理解)

执行系统代码的领空
地址比较大(比较小的概念如图所示)

Some tips for how to use OD easily
一些经验上来讲常用的操作
不同的版本下列操作菜单会有出入,但是大致位置相同

打Messagebox断点:

MessageBox指的是显示一个模式对话框,其中包含一个系统图标、 一组按钮和一个简短的特定于应用程序消息,如状态或错误的信息。消息框返回一个整数值,该值指示用户单击了哪个按钮。
对话框往往是我们调试时候需要重点关注的
点击一个汇编指令,右击,用nop填充
nop是汇编语言中的空指令,不进行任何操作


下面对话框显示的是这句汇编语言的机器码,可以修改这个机器码
新手需要查阅汇编语言对应的机器码来修改
汇编语言与机器语言是一一对应的关系

从系统领空执行到程序领空

在汇编窗口右击

该操作会列出所有字符串

可以点击跟进任何一个一个字符串
另一种操作,在汇编窗口右击

我们一般搜索ASCII和UNICODE字符串,也可以选择智能搜索
在该界面右击->查找,或快捷键Ctrl+F
可以查找某个特定的字符串


点击字符串可以跟进

有时进入OD显示的窗口是这样的,可以点击左上角窗口最大化来回到我们熟悉的界面

在寄存器值处右击

EFLAG寄存器存有很多标志位,一个标志位占1bit,标志位可以更改
标志位是根据上面程序的执行结果进行记录,汇编语言进行跳转往往是根据标志位进行的
我们修改标志位的值,会影响跳转,影响程序执行流程

下面是EFLAGS寄存器存储标志位的图示

EIP寄存器的值不能直接修改,EIP存储当前执行的汇编代码在内存中的位置


可以输入windows API的名称,定位到windows API的位置
Alt+B快捷键打开断点窗口

各种版本的OD的工具栏中一般都可以自定义界面风格

本处只做概括性描述,一些不能领悟的请查阅资料体会
我们知道OD只有一个32位版本
调试一些64位文件适合使用x64dbg


可以看出界面和OD十分地相似,操作和OD也很类似
如下:


根据OD的使用经验可以自行探索学习
也有可以调试32位程序的x32dbg

需要系统学习操作系统
对于系统了解越多,有正向开发的经验,越有利于逆向工程
可以通过操作系统的API进行内核操作
操作系统只信任自己的API,要通过API才能实现对内核的操作
Read this for quick start. Consult help file for details and more features.
Installation is not necessary. Create new directory and unpack odbg110.zip - now you can start!
Pop-up menus display only items that apply. Frequently used menu functions:
| Function | Window | Menu command | Shortcut |
| Edit memory as binary, ASCII or UNICODE string | Disassembler, Stack Dump | Binary|Edit | Ctrl+E |
| Undo changes | Disassembler, Dump Registers | Undo selection Undo | Alt+BkSp |
| Run application | Main | Debug|Run | F9 |
| Run to selection | Disassembler | Breakpoint|Run to selection | F4 |
| Execute till return | Main | Debug|Execute till return | Ctrl+F9 |
| Execute till user code | Main | Debug|Execute till user code | Alt+F9 |
| Set/reset INT3 breakpoint | Disassembler Names, Source | Breakpoint|Toggle Toggle breakpoint | F2 |
| Set/edit conditional INT3 breakpoint | Disassembler Names, Source | Breakpoint|Conditional Conditional breakpoint | Shift+F2 |
| Set/edit conditional logging breakpoint (logs into the Log window) | Disassembler Names, Source | Breakpoint|Conditional log Conditional log breakpoint | Shift+F4 |
| Temporarily disable/restore INT3 breakpoint | Breakpoints | Disable Enable | Space |
| Set memory breakpoint (only one is allowed) | Disassembler, Dump | Breakpoint|Memory, on access Breakpoint|Memory, on write | |
| Remove memory breakpoint | Disassembler, Dump | Breakpoint|Remove memory breakpoint | |
| Set hardware breakpoint (ME/NT/2000 only) | Disassembler, Dump | Breakpoint|Hardware (select type and size!) | |
| Remove hardware breakpoint | Main | Debug|Hardware breakpoints | |
| Set single-short break on access to memory block (NT/2000 only) | Memory | Set break-on-access | F2 |
| Set break on module, thread, debug string | Options | Events | |
| Set new origin | Disassembler | New origin here | |
| Display list of all symbolic names | Disassembler, Dump Modules | Search for|Name (label) View names | Ctrl+N |
| Context-sensitive help (requires external help file!) | Disassembler, Names | Help on symbolic name | Ctrl+F1 |
| Find all references in code to selected address range | Disassembler Dump | Find references to|Command Find references | Ctrl+R |
| Find all references in code to the constant | Disassembler | Find references to|Constant Search for|All constants | |
| Search whole allocated memory | Memory | Search Search next | Ctrl+L |
| Go to address or value of expression | Disassembler Dump | Go to|Expression Go to expression | Ctrl+G |
| Go to previous address/run trace item | Disassembler | Go to|Previous | Minus |
| Go to next address/run trace item | Disassembler | Go to|Next | Plus |
| Go to previous procedure | Disassembler | Go to|Previous procedure | Ctrl+Minus |
| Go to next procedure | Disassembler | Go to|Next procedure | Ctrl+Plus |
| View executable file | Disassembler, Dump, Modules | View|Executable file | |
| Copy changes to executable file | Disassembler | Copy to executable file | |
| Analyse executable code | Disassembler | Analysis|Analyse code | Ctrl+A |
| Scan object files and libraries | Disassembler | Scan object files | Ctrl+O |
| View resources | Modules, Memory | View all resources View resource strings | |
| Suspend/resume thread | Threads | Suspend Resume | |
| Display relative addresses | Disassembler, Dump, Stack | Doubleclick address | |
| Copy | Most of windows | Copy to clipboard | Ctrl+C |
Frequently used global shortcuts:
| Ctrl+F2 | Restart program |
| Alt+F2 | Close program |
| F3 | Open new program |
| F5 | Maximize/restore active window |
| Alt+F5 | Make OllyDbg topmost |
| F7 | Step into (entering functions) |
| Ctrl+F7 | Animate into (entering functions) |
| F8 | Step over (executing function calls at once) |
| Ctrl+F8 | Animate over (executing function calls at once) |
| F9 | Run |
| Shift+F9 | Pass exception to standard handler and run |
| Ctrl+F9 | Execute till return |
| Alt+F9 | Execute till user code |
| Ctrl+F11 | Trace into |
| F12 | Pause |
| Ctrl+F12 | Trace over |
| Alt+B | Open Breakpoints window |
| Alt+C | Open CPU window |
| Alt+E | Open Modules window |
| Alt+L | Open Log window |
| Alt+M | Open Memory window |
| Alt+O | Open Options dialog |
| Ctrl+T | Set condition to pause Run trace |
| Alt+X | Close OllyDbg |
Frequently used Disasembler shortcuts:
| F2 | Toggle breakpoint |
| Shift+F2 | Set conditional breakpoint |
| F4 | Run to selection |
| Alt+F7 | Go to previous reference |
| Alt+F8 | Go to next reference |
| Ctrl+A | Analyse code |
| Ctrl+B | Start binary search |
| Ctrl+C | Copy selection to clipboard |
| Ctrl+E | Edit selection in binary format |
| Ctrl+F | Search for a command |
| Ctrl+G | Follow expression |
| Ctrl+J | Show list of jumps to selected line |
| Ctrl+K | View call tree |
| Ctrl+L | Repeat last search |
| Ctrl+N | Open list of labels (names) |
| Ctrl+O | Scan object files |
| Ctrl+R | Find references to selected command |
| Ctrl+S | Search for a sequence of commands |
| Asterisk (*) | Origin |
| Enter | Follow jump or call |
| Plus (+) | Go to next location/next run trace item |
| Minus (-) | Go to previous location/previous run trace item |
| Space ( ) | Assemble |
| Colon (:) | Add label |
| Semicolon (;) | Add comment |
一篇博客不能掌握动态调试和破解软件的技巧,需要自己体会,真正的CTF没有套路,网络安全没有固定套路
安全方面的博客关注看雪论坛
北落明星动光彩,南征猛将如云雷。手中电曳倚天剑,直斩长鲸海水开。
——《司马将军歌》
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po