原文链接:https://www.shogunlab.com/blog/2019/04/12/here-be-dragons-ghidra-0.html
翻译:看雪翻译小组-玉林小学生
校对:看雪翻译小组-Nxe
欢迎来到Ghidra逆向工程系列教程第一部分!本系列教程关注于如何使用NSA发布的新逆向工具来逆向Windows可执行程序。目的是引导新手进入逆向工程领域,并为逆向高手重点介绍Ghidra的独特功能。
本文将向你介绍Ghidra中的许多主窗口,后面是一个使用它逆向简单CreakMe二进制文件的教程。本系列教程中,我们的所有样例都运行在Windows主机上。你可以在这里找到一个使用免费版Windows 64位系统的虚拟机。或者,你更喜欢在你的本地机器上直接运行,也没问题!在介绍开始前,我们先获取最新版本的Ghidra并运行。
首先,Ghidra需要预先安装好一些依赖软件。Ghidra需要JDK 11,从这里下载、安装并运行它。安装完JDK成后,从官方页面获到Ghidra最新版本。下载完成后,解压文件并双击“runGhidra.bat”来启动Ghidra。首次运行应该会看到用户协议,在一些加载过程后,你会看到弹出项目窗口。如果对安装或其它上面的操作有问题,在这里查看说明文档。
在项目窗口中可以加载二进制文件并组织项目内的文件。文中涉及的Windows二进制文件可以在这里的“IOLI-crackme/bin-win32”目录下找到。创建一个新项目并在下一步中使用Ghidra的batch import功能一次性导入所有文件。在project窗口,选择“File > Batch import…”,浏览“bin-win32”目录并选择要导入的所有文件。等待操作完成,可以看到CreakMe文件被加载了。
第一次,我们从“crackme0x00.exe”开始,双击它将打开code browser。会弹出一个消息框询问你是否分析二进制文件,选择“Yes”后你会看到可以执行的不同类型分析。对于本项目选择默认的即可,选择“Analyze”并等Ghidra完成。当全部完成后,可以在code browser中看到加载的二进制汇编代码及主窗口。
让我们来看看Ghidra在代码浏览器中提供的主要窗口。Ghidra的一个有趣地方是上下文帮助菜单。对于大多数界面元素,你可以在悬停于上面时按F1来调出一个帮助向导,里面可能有你想知道的东西。下图尝试使用上下文帮助来学习关于“Program Trees”窗口的更多知识。
在“Program Trees”窗口中,可以通过右键点击“crackme0x00”目录来以不同方式组织反汇编代码的各个sections。可以点击“Modularize By”并选择“Subroutine”、“Complexity Depth”或“Dominance”。你也可以创建新目录并根据自己的组织爱好拖拽各个sections。
“Program Trees”窗口下面的窗口是“Symbol Tree”窗口,从里面可以看到二进制文件的导入、导出、函数、标签、类和命名空间信息。扩展“Imports”节来查看目标程序使用的各种DLL和函数。如果你想看某个导入的函数在哪里被调用,可以右键该函数并点击“Show references to”,然后双击列出的条目以查看完整内容。
从“Data Type Manager”中可以查看所有定义的类型,包括内建类型,二进制文件特有类型和其它人工包含进Ghidra的类型(如在这里看到的Windows下叫做“windows_vs12_32”的类型)。扩展书本样式按钮并右键一个数据类型,点击“Find uses of”可以查看该数据类型在二进制文件的哪里被使用。
现在,我们看看最吸引人的地方,“Listing”窗口。在这里,你可以看到反汇编代码然后慢慢理解二进制代码的每一部分功能。Ghidra向你提供了许多自定义listing窗口的方法,可以点击右上方的“Edit the listing fields”图标并点击“Instruction/Data”标签页。Listing界面上的每个元素都可以修改大小、移动、禁用或删除。也可以通过右键菜单来增加新元素。可以尝试下修改“Address”域的大小使其更小,并删除“Bytes”域。
可以通过在汇编代码的任一位置右键看到listing窗口的上下文菜单。可以执行修改指令、设置书签、注释和编辑标签功能。尝试在listing窗口右键一个汇编指令并增加一个注释。你可以通过双击CALL指令引用的函数来到达函数代码以了解函数的功能。通过点击左上方保存图标旁边的箭头按钮来实现向前、向后跳转,或者使用快捷键“Alt-左箭头按键”和“Alt-右箭头按键”进行。试试看你能不能知道每个CALL .text指令调用的是哪个函数并通过编辑标签来设置合适的函数名称。尝试增加一两个注释来描述不同代码片段的功能。
熟悉IDA Pro的人喜欢首先查看图形模式。Ghidra中对应的窗口是“Function Graph”窗口,该窗口可以通过点击“Window”和“Function Graph”打开。函数图可以使用“Edit the listing fields”来进行类似地自定义。Ghidra中的图形默认不显示注释,可以使用域编辑器加入。你可能会注意到它的行为与IDA Pro的图形模式有些不同,并且开始时不是全放大状态。要配置函数图,在图形上点击右键,选择“Properties”然后在“View Settings”下拉列表中选择“Start Fully Zoomed In”。
最后,我们在右边看到反编译窗口,其中是Ghidra估计的listing或unction graph窗口中的汇编代码对应的高层代码。尝试在反编译窗口高亮一个“if”表达式,你可以看到相应的汇编指令被高亮了。这是我最喜爱的Ghidra特征之一,这在高级语言表达式和一组汇编指令之间建立了映射。
可以右键变量并重命名它们或者在反编译中给变量增加注释,这些操作也会在disassembly listing或function graph窗口中反应出来。Ghidra自动在这些窗口中进行同步。如果你想修改任一反编译显示选项,可以在窗口中点击右键并选择“Properties”。以更易理解的方式重命名本地变量,并查看进行的修改是否也在listing窗口显示。
如果你到了这里,你已经了解了Ghidra的主要界面并准备好了解决CreakMe(如果你还没有)。运行crackme0x0.exe文件看看程序运行的结果。你被要求输入一个密码,根据输入进行判断,如果输入不正确,返回“Invalid Password!”消息。
我们先通过在“Window > Defined Strings”窗口查看程序的字符串。可以看到在命令行中显示的字符串。我们查看引用“Password”字符串的汇编代码。在“Defined Strings”窗口右键“Password”项,会跳转到程序中代码段所在的节。
左键地址并选择“References > Show References to Address”,你可以点击列出的引用“Password”的代码段中的项。找到比较用户输入和正确密码的代码段。重命名变量和函数为更有意义的名字并增加注释来帮助分析。
在引用“Password”的地方后面,有一个scanf调用来获得用户输入,之后还有一个strcmp。可以看到用户输入保存在EAX中并保存在本地变量local_40中。字符串“250382”存储在本地变量local_3c中,这两个变量都被传输给strcmp。如果比较函数返回的结果是0,打印“Password OK :)”。否则,执行jmp指令并打印“Invalid Password!”。再次运行“crackme0x00.exe”,输入“250382”,成功。
我们使用Ghidra解决了第一个CrackMe!祝贺你和我们一起走到这里。用于逆向工程这个程序的通用方法如下:
我们还学习了Ghidra的主窗口和部分功能,如:
如果你是逆向新手,这第一篇文章能够让你轻松进入该领域,并且第一次尝试到CreakMe的胜利。如果你是一个逆向老手,期望你能获得如何在每日的逆向任务中使用Ghidra的思路并且熟悉其主要的UI元素。感谢阅读本教程。
阅读下一部分,点击这里(看雪翻译版),我们将讨论转换、应用数据类型,函数调用树、图和脚本管理器有关内容。
如果有任何不清楚的地方,或者有任何建议与反馈,在Twitter(@shogun_lab)上或通过e-mail [email protected]给我发消息。