原文链接:Ghidra: A quick overview for the curious
Ghidra是由美国国家安全局(NSA)研究部门开发的软件逆向工程(SRE)套件,用于支持网络安全任务。它最近被公开出来,我对此感到好奇,想看看它是什么样的。
我还没有查过是否有其他人已经发过了类似的概述文章,不过,我还是决定写这篇文章,为了自己和那些不想自行运行Ghidra而只是想简单了解一下的人。
我知道将Ghidra与IDA Pro进行比较是不公平的,但我还是忍不住要比较,因为我是IDA Pro的长期用户,而且它是我在逆向工程工具方面的唯一参照物。
这篇文章很长,将包含很多截图。我刚刚开始上手Ghidra,因此,我可能是错的,或者可能会提供不准确或不完整的信息,所以请原谅我。
目录
Ghidra是一个软件逆向工程(SRE)框架,包括一套功能齐全的高端软件分析工具,使用户能够在各种平台上分析编译后的代码,包括Windows、Mac OS和Linux。功能包括反汇编,汇编,反编译,绘图和脚本,以及数百个其他功能。Ghidra支持各种处理器指令集和可执行格式,可以在用户交互模式和自动模式下运行。用户还可以使用公开的API开发自己的Ghidra插件和脚本。
我在解压缩的Ghidra安装档案中运行了tree命令。这是输出:
├───Configurations │ └───Public_Release │ ├───data │ └───lib ├───Extensions ├───Features │ ├───Base │ │ ├───data │ │ │ ├───formats │ │ │ ├───parserprofiles │ │ │ ├───stringngrams │ │ │ ├───symbols │ │ │ │ ├───win32 │ │ │ │ └───win64 │ │ │ └───typeinfo │ │ │ ├───generic │ │ │ ├───mac_10.9 │ │ │ └───win32 │ │ │ └───msvcrt │ │ ├───ghidra_scripts │ │ └───lib │ ├───BytePatterns │ │ ├───data │ │ │ └───test │ │ ├───ghidra_scripts │ │ └───lib │ ├───ByteViewer │ │ ├───data │ │ └───lib │ ├───DebugUtils │ │ └───lib │ ├───Decompiler │ │ ├───ghidra_scripts │ │ ├───lib │ │ └───os │ │ ├───linux64 │ │ ├───osx64 │ │ └───win64 │ ├───DecompilerDependent │ │ ├───data │ │ └───lib │ ├───FileFormats │ │ ├───data │ │ │ ├───android │ │ │ ├───crypto │ │ │ └───languages │ │ │ └───Dalvik │ │ ├───ghidra_scripts │ │ └───lib │ ├───FunctionGraph │ │ ├───data │ │ └───lib │ ├───FunctionGraphDecompilerExtension │ │ └───lib │ ├───FunctionID │ │ ├───data │ │ ├───ghidra_scripts │ │ └───lib │ ├───GhidraServer │ │ ├───data │ │ │ └───yajsw-stable-12.12 │ │ │ ├───doc │ │ │ ├───lib │ │ │ │ ├───core │ │ │ │ │ ├───commons │ │ │ │ │ ├───jna │ │ │ │ │ ├───netty │ │ │ │ │ └───yajsw │ │ │ │ └───extended │ │ │ │ ├───abeille │ │ │ │ ├───commons │ │ │ │ ├───cron │ │ │ │ ├───glazedlists │ │ │ │ ├───groovy │ │ │ │ ├───jgoodies │ │ │ │ ├───keystore │ │ │ │ ├───regex │ │ │ │ ├───velocity │ │ │ │ ├───vfs-dbx │ │ │ │ ├───vfs-webdav │ │ │ │ └───yajsw │ │ │ └───templates │ │ ├───lib │ │ └───os │ │ ├───linux64 │ │ ├───win32 │ │ └───win64 │ ├───GnuDemangler │ │ ├───ghidra_scripts │ │ └───lib │ ├───GraphFunctionCalls │ │ └───lib │ ├───MicrosoftCodeAnalyzer │ │ └───lib │ ├───MicrosoftDemangler │ │ └───lib │ ├───MicrosoftDmang │ │ └───lib │ ├───PDB │ │ ├───lib │ │ ├───os │ │ │ └───win64 │ │ └───src │ │ └───pdb │ │ ├───cpp │ │ └───headers │ ├───ProgramDiff │ │ └───lib │ ├───Python │ │ ├───data │ │ │ └───jython-2.7.1 │ │ ├───ghidra_scripts │ │ └───lib │ ├───Recognizers │ │ └───lib │ ├───SourceCodeLookup │ │ └───lib │ └───VersionTracking │ ├───data │ ├───ghidra_scripts │ └───lib ├───Framework │ ├───DB │ │ └───lib │ ├───Demangler │ │ └───lib │ ├───Docking │ │ ├───data │ │ └───lib │ ├───FileSystem │ │ └───lib │ ├───Generic │ │ ├───data │ │ └───lib │ ├───Graph │ │ └───lib │ ├───Help │ │ └───lib │ ├───Project │ │ ├───data │ │ └───lib │ ├───SoftwareModeling │ │ ├───data │ │ │ └───languages │ │ └───lib │ └───Utility │ └───lib ├───Processors │ ├───6502 │ │ └───data │ │ └───languages │ ├───68000 │ │ ├───data │ │ │ ├───languages │ │ │ └───manuals │ │ └───lib │ ├───6805 │ │ └───data │ │ └───languages │ ├───8051 │ │ ├───data │ │ │ ├───languages │ │ │ │ └───old │ │ │ └───manuals │ │ └───ghidra_scripts │ ├───8085 │ │ └───data │ │ └───languages │ ├───AARCH64 │ │ ├───data │ │ │ ├───languages │ │ │ └───patterns │ │ └───lib │ ├───ARM │ │ ├───data │ │ │ ├───languages │ │ │ │ └───old │ │ │ ├───manuals │ │ │ └───patterns │ │ └───lib │ ├───Atmel │ │ ├───data │ │ │ ├───languages │ │ │ └───manuals │ │ └───lib │ ├───CR16 │ │ └───data │ │ ├───languages │ │ └───manuals │ ├───DATA │ │ ├───data │ │ │ └───languages │ │ ├───ghidra_scripts │ │ └───lib │ ├───JVM │ │ ├───data │ │ │ ├───languages │ │ │ └───manuals │ │ └───lib │ ├───MIPS │ │ ├───data │ │ │ ├───languages │ │ │ ├───manuals │ │ │ └───patterns │ │ └───lib │ ├───PA-RISC │ │ └───data │ │ ├───languages │ │ ├───manuals │ │ └───patterns │ ├───PIC │ │ ├───data │ │ │ ├───languages │ │ │ └───manuals │ │ ├───ghidra_scripts │ │ └───lib │ ├───PowerPC │ │ ├───data │ │ │ ├───languages │ │ │ │ └───old │ │ │ ├───manuals │ │ │ └───patterns │ │ └───lib │ ├───Sparc │ │ ├───data │ │ │ ├───languages │ │ │ ├───manuals │ │ │ └───patterns │ │ └───lib │ ├───TI_MSP430 │ │ └───data │ │ ├───languages │ │ └───manuals │ ├───Toy │ │ ├───data │ │ │ └───languages │ │ │ └───old │ │ │ └───v01stuff │ │ └───lib │ ├───x86 │ │ ├───data │ │ │ ├───languages │ │ │ │ └───old │ │ │ ├───manuals │ │ │ └───patterns │ │ └───lib │ └───Z80 │ └───data │ ├───languages │ └───manuals └───Test └───IntegrationTest └───lib
可以看出这个项目非常有条理。深入挖掘,我注意到Ghidra已经包含了许多组件的源代码:
* -src.zip
我提到了源代码,因为在撰写本文时,Ghidra的GitHub仓库仍然不包含源代码,它的内容如下:
此仓库是完整开源版本的预备发布区。请放心,我们正在努力使这里的软件可用。在此期间,您可以在您的软件逆向工程(SRE)工作中使用Ghidra,开发自己的脚本和插件,并仔细阅读首次公开发行版本中发布的超过一百万行的Java和Sleigh代码。该版本可以从我们的项目主页下载。请考虑查看我们的贡献者指南,了解如何在项目可用时参与此开源项目。
在撰写本文时,Ghidra支持以下处理器模块:
它们位于C:\ghidra_9.0\Ghidra\Processors。处理器模块似乎是数据驱动的。它们的一些插件/扩展方面是用Java编写和实现的。例如,您可以在此处找到x86模块的一些源代码组件:C:\ghidra_9.0\Ghidra\Processors\x86\lib\x86-src.zip。处理器模块的可编程部分包含“重定位解码器”、“文件格式解码器”、“分析插件”等。
C:\ghidra_9.0\Ghidra\Processors
C:\ghidra_9.0\Ghidra\Processors\x86\lib\x86-src.zip
├───app │ ├───plugin │ │ └───core │ │ └───analysis │ └───util │ └───bin │ └───format │ ├───coff │ │ └───relocation │ └───elf │ ├───extend │ └───relocation └───feature └───fid └───hash
有趣的是,处理器模块参考了外部工具(即IDA Pro)中相应的处理器模块:
<language_definitions> <language processor="6502" endian="little" size="16" variant="default" version="1.0" slafile="6502.sla" processorspec="6502.pspec" id="6502:LE:16:default"> <description>6502 Microcontroller Family</description> <compiler name="default" spec="6502.cspec" id="default"/> <external_name tool="IDA-PRO" name="m6502"/> <external_name tool="IDA-PRO" name="m65c02"/> </language>
Ghidra功能齐全。它包括强大的代码浏览器,图形查看器,反编译器,数百个脚本,各种搜索工具,撤消/重做支持,协同工作服务器,程序差异比较工具等。由于Ghidra是巨大的,我无法涵盖每一个功能。那么,我将关注那些经验丰富的逆向工程师所认为的基础功能,也就是最重要和最有用的功能。
在Ghidra中,任何东西都是一个项目。与IDA不同,您不会使用输入文件开始逆向工程会话,而是从创建项目开始。在第一次运行时没有项目,您将看到此对话框: 在本文中,我将对我的开源的Wizmo工具(可在此处找到)进行逆向工程。如果你想跟着我一起使用Ghidra,请下载二进制文件。首先创建一个名为“Wizmo”的项目,然后导入“WizmoConsole.exe”程序: 导入文件后,将显示导入结果摘要对话框: 按“确定”后,您将看到代码浏览器窗口,并将被询问是否要开始分析该文件: 您可以随后从“分析”菜单中分析或重新分析该文件: 您还可以检查导入文件的属性: 您可以根据需要导入任意数量的文件。通常,导入项目的文件之间应该具有逻辑关系。例如EXE主程序及其DLL。 在上面的示例中,我导入了不相关的文件。 稍后,我们还将了解到可以通过编辑外部函数路径来创建从一个导入文件到另一个导入文件的链接。 例如,WizmoConsole.exe从user32.dll导入,因此我们可以链接WizmoConsole中导入的函数直接跳转到user32.dll。 这个功能真正构成了一个项目。 IDA Pro尚不支持项目概念。
WizmoConsole.exe
user32.dll
代码浏览器可以与IDA的主界面进行比较。 代码浏览器中有着Ghidra的所有可视元素:
程序反汇编列表是高度可定制的。 只需按下“编辑列表字段”按钮(如光标所示)即可查看所有自定义选项: 单击并拖动字段以重新排列反汇编列表(disasm视图)窗口中的可视元素。 这种高级可视化定制在IDA Pro中也不具备。 代码浏览器还可以显示其他辅助信息,例如程序概述和熵: 在代码浏览器反汇编列表中,您可以按“G”跳转到地址或标签: 或者只是重命名一个函数或标签: 您还可以右键单击列表中的数字,将其转换为另一个数字表示形式: 要在代码浏览器中查看有关指令的信息,只需右键单击并选择“指令信息”: 回到反汇编列表自定义这一主题,您还可以将某些操作数转换为枚举常量: Ghidra提供了一个很好的数据类型选择器,它可以帮助您输入完整的类型名称或直观地选择它。
使用符号树窗口可以查看程序中的所有符号,例如导出符号,导入符号,类,函数,标签等。 这里我正在浏览USER32.dll的导入符号: 在浏览导入的条目时,可以双击以在代码浏览器中跳转到该条目。 此外,如果您对导入条目的原型不满意,您可以随时编辑它: 之前,我提到您可以将外部函数链接到另一个导入的文件。 由于我们知道所有这些函数都来自user32.dll,我们可以将这些函数链接到项目中的导入文件: 选择:“路径”->编辑->并选择相关的导入文件(user32.dll)。
USER32.dll
反编译器是Ghidra中一个很酷的且最受欢迎的功能: 您可以从“窗口”菜单切换到反编译器视图。 反编译视图与反汇编列表同步。 因此,在反编译器视图中浏览时,您将在列表窗口中看到相应的反汇编行。与IDA的Hex-Rays反编译器插件一样,Ghidra的反编译器具有交互性和可定制性:
例如,这是CWizmo::CWizmo构造函数的完整(手动清理过的)反编译结果: 我必须首先使用“数据类型”窗口并选择“新建 -> 结构”来创建新的自定义结构: 然后我填充了新的结构字段: 如果您不想手动创建自定义结构,也可以解析C头文件: 反编译器有一个上下文弹出菜单: 它允许您在反编译列表中设置注释: 更改反编译的函数原型: 更改函数参数的原型: 修改函数的返回类型、签名或执行搜索: 值得注意的是,函数编辑器(使用“F”热键切换)与IDA的函数原型功能一样强大。 您可以编辑参数并为它们指定自定义存储(堆栈,寄存器等): x86输入文件的一些受支持的存储类型: 除了是一个交互式反编译器,您还拥有强大的搜索功能。 例如,我们可以从反编译列表中搜索给定数据类型的使用情况。在这里,我们右键单击memset的最后一个参数(0x2c,size_t)来查找所有反编译函数中“size_t”类型的所有使用情况(对于漏洞研究非常方便): 右键单击并选择:“查找size_t的使用情况” 结果显示了所有使用“size_t”类型的变量。
与IDA一样,Ghidra提供了许多功能来修补代码,然后保存修补结果。 要修补指令,只需右键单击并选择: 然后,您将看见指令编辑器/汇编器: 如果您希望像精英黑客一样从十六进制查看器中修补代码,只需从“窗口/字节”菜单切换十六进制视图: 然后使字节视图可编辑: 您现在可以编辑该程序: 十六进制查看器有一个上下文菜单,允许您复制字节,例如: 与在IDA Pro中一样,您可以通过从“文件”菜单中选择“添加到程序”来“加载其他二进制文件”: 选择要添加的文件后,可以指定其他加载选项(块名称、基地址等): 这非常有用,例如,如果要加载shellcode并在程序中对其进行分析: 然后,新代码在代码浏览器中以其自己的块名称很好地显示。如果没有导出/应用到外部,则不会完成修补。 Ghidra和IDA一样,允许你导出你的改动: 导出为二进制格式。 成功导出后,您将看到摘要: 如果您比较原始文件和修补文件,您应该看到差异,说明修补是被正确应用的: 等等
与IDA一样,Ghidra也支持图表视图。 结合“选择”菜单中的功能,图表视图成为一个强大的工具: “选择”菜单: 你可以放大: 您还可以更改基本块的颜色: 或者将基本块的内容折叠为具有您选择的标签的单个块: 您还可以尝试各种视觉辅助工具: 最后但并非最不重要的是,您可以在给定的基本块上选择“全屏”以更好地检查它:
Ghidra在“搜索”菜单下提供了各种搜索功能: 您可以搜索地址表,例如: 您可以同样搜索标量(IDA中的“立即数搜索”): 找到结果后: 您可以应用其他过滤器: 应用过滤器时,搜索结果会进一步细化: 如果要查找某些指令序列,可以从代码浏览器中选择一个或多个指令: 然后从搜索菜单中选择“For Instruction Pattern”以执行搜索:
如果一款软件逆向工程(SRE)工具没有强大的脚本工具,那么它不能说是完整的(从“窗口/脚本管理器”菜单中选择脚本)。 开箱即用的Ghidra附带了200多个用Java编写的脚本: 例如,FindImagesScript.java脚本在输入文件中查找PNG和GIF图像: 这些脚本使用Ghidra的API: 如果您不喜欢Java,可以使用Python(使用Jython托管)来编写脚本:
Ghidra还有许多值得一提的杂项功能。让我们从交叉引用功能开始。您可以让Ghidra计算几乎任何项目(字符串,指令,寄存器等)的交叉引用。例如,我们正在寻找字符串窗口中给定字符串的交叉引用: 使用字符串交叉引用,您可以发现恶意字符串或找到引用/实现某些功能的代码(基于您找到的字符串文本)。 与IDA一样,您可以手动创建交叉引用: 可以与IDA的“Segments窗口”进行比较的另一个功能是“Memory map”窗口: 在内存映射中,您可以看到程序分区(如果输入文件包含分区,如PE或ELF文件)。此外,您可以手动创建新分区:
几乎任何东西都可以通过选项功能在Ghidra中配置:
以下是Ghidra的一些其他截图:
在使用Ghidra的UI几个小时之后,我发现它很有用且功能强大,但这还不足以让我从IDA Pro切换到Ghidra:
Unidbg 模拟执行精讲
lofrank 不错,支持。 原文链接能贴下么?
茅山小僧 这个能下载使用吗,哪里可以下载
DMemory 楼主有 ghidra 的源码么