在上一篇文章中,我们为读者详细介绍了如何启动Ghidra,以及在加载二进制文件时的各种可选项。实际上,这些只是为分析二进制文件做好了准备,在本文中,我们将为读者介绍如何使用Ghidra来分析二进制文件。
从本质上说,Ghidra就是一个由插件库控制的数据库应用程序,其中每个插件都有自己的功能。所有的项目数据都使用自定义数据库进行存储,该数据库会随着用户向项目添加信息而增长和演变。Ghidra提供的各种图形展示只是数据库的视图,以方便软件逆向工程师直观查看各种信息。用户对数据库所做的任何修改都反映在视图中并保存到数据库中,但这些更改对原始的可执行文件没有任何影响。Ghidra的强大之处在于,它为分析和操作数据库内的数据提供了丰富的工具。
CodeBrowser锚定了Ghidra中的许多可用工具,并提供了独特的功能来帮助您保持窗口井然有序,添加和删除工具,重新排列内容以及记录您的分析过程。默认情况下,CodeBrowser会同时打开Program Tree、 Symbol Tree、Data Type Manager、Listing、Decompiler和Console窗口。关于这些窗口的功能,我们将在后文中详细加以介绍。
迄今为止,我们已经介绍了创建项目并导入文件的过程,但是这些只属于准备工作,实际上,真正的分析工作并没有开始。当您双击Ghidra的Project(项目)窗口中的文件时,就会弹出CodeBrowser窗口,如图10所示。
图10 Ghidra的CodeBrowser窗口
如果这是您第一次选择已导入的文件,Ghidra将提供一个允许Ghidra完成自动分析的选项。图11为我们展示了一个使用Analysis Options对话框进行自动分析的示例。
图11 Analysis Options对话框
在大多数涉及二进制文件的情况下,自动分析可能是我们的首选,因为在绝大部分情况下,二进制文件都是来自通用平台并经由通用编译器进行构建的。您可以在任何时候通过单击CodeBrowser窗口右下角的红色stop按钮来停用自动分析过程。需要注意的是,该按钮仅在自动分析期间可见。
如果您对Ghidra的自动分析结果不满意,可以通过关闭CodeBrowser并选择不保存分析结果来放弃之前的工作;此后,您可以重新打开文件,并尝试不同的自动分析选项组合。在分析经过混淆处理的二进制文件,或者构建二进制文件的编译器,或者构建二进制文件的操作系统无法被Ghidra正确识别时,通常就需要修改自动分析选项。
请注意,如果您打开的是一个非常大的二进制文件(如10MB或更大),Ghidra可能需要几分钟到几小时的时间来进行自动分析。在这种情况下,您可以关闭某些比较耗时的分析程序(例如,Decompiler Switch Analysis、Decompiler ParameterID以及Stack)或为其设置超时。如图11所示,它高亮显示了一个分析器及其对应的描述信息,其中包括有关该分析器运行时间方面的警告信息。此外,这里还显示了该分析程序的Options框,其中的选项可以用来控制该分析程序的某些行为。当然,对于禁用或设置超时的任何分析程序,都可以通过Ghidra的Analysis菜单重新启用。
加载程序开始分析文件后,如果它在分析过程中遇到了问题,并且它认为该问题足够严重的话,它就会发送警告信息。举例来说,当分析PE文件的时候,如果没有找到相关的程序数据库(PDB)文件,那么在分析完成后,Auto Analysis Summary(自动分析摘要)对话框中会显示一条消息,指出遇到的所有问题,具体如图12所示。
图12 Auto Analysis Summary对话框
在大多数情况下,这些消息仅仅是参考性的。但是,在某些情况下,这些消息却具有指导意义,比如为解决问题提供具体的建议等。
在Ghidra自动分析文件之后,文件的新信息将补充到摘要信息中,如图13所示。
图13:通过Help菜单导入目标文件的摘要信息
Ghidra的自动分析是通过选定的各个分析程序处理新加载的二进制文件来完成的。关于每个分析程序的描述信息,请参考Analysis Options对话框以及Ghidra的Help菜单。我们之所以选择默认的分析程序,是因为根据Ghidra用户的经验来看,它们对于各种文件类型来说,通常是最有用的。下面,我们讨论在二进制文件的初始加载和随后的自动分析过程中提取出的最有用的信息。
正确识别构建软件所用的编译器,不仅可以帮助我们了解该二进制文件中使用的函数调用惯例,还能确定二进制文件可能链接了哪些库。如果在加载文件时能够识别编译器,Ghidra的自动分析就能够充分应用识别出来的编译器的特定行为方面的知识。使用不同的编译器和不同的编译选项时,得到的自动分析结果会有很大的区别。
对于每个已识别的函数(可通过符号表项和作为调用指令目标的地址进行识别),Ghidra都会对堆栈指针寄存器的行为进行细致的分析:不仅要找出对堆栈内的变量的访问情况,还要了解函数的堆栈帧的布局。同时,Ghidra还会根据这些变量是作为函数中的局部变量使用,还是用于函数调用过程中传递给函数的、在栈内分配内存空间的参数,自动为这些变量生成相应的名称。关于堆栈帧,这里先不多说,等以后再讲。
Ghidra能够利用其对常见库函数及其相关参数的了解来识别每个函数中使用的函数、数据类型和数据结构。这些信息将被添加到符号树和数据类型管理器窗口以及列表窗口中。这个功能可以为我们节省大量宝贵的时间,如果没有该功能的话,我们就必须从各种应用程序编程接口(API)资料中手动检索相关的信息。关于Ghidra处理库函数和相关数据类型的详细信息,我们将在后面的文章中加以解释。
在对新打开的文件进行初次分析期间,CodeBrowser桌面中会发生大量的活动。您可以通过查看CodeBrowser桌面右下方的分析更新来了解相关分析活动。同时,我们也可以藉此了解分析的最新进展。当然,这些信息的滚动速度很快,为此,我们可以打开相关的Ghidra日志文件,以更从容的了解这些信息。
那么,如何打开日志文件呢?很简单,只需从Ghidra的Project窗口中选择Help菜单下面的Show Log菜单项即可。需要注意的是,Show Log(显示日志)菜单选项仅在Ghidra的Project窗口中的Help菜单中可用,而在CodeBrowser窗口的Help菜单中是找不到该选项的。
以下输出来自Ghidra在对calc.exe进行自动分析期间生成的日志文件,实际上就是在自动分析过程中生成的各种消息。这些消息不仅可以用来描述分析过程,同时也给出了Ghidra的操作顺序,以及分析期间每项任务的耗时:
图14 分析日志
不必等到自动分析完成,您就可以开始浏览各种数据了。当自动分析完成后,您就可以对项目文件进行任意的修改了。
如果在分析过程中暂时休息一下的话,最好保存当前的工作。该操作并不复杂,可以在CodeBrowser窗口中通过下列任何一种方式完成:
l 使用CodeBrowser窗口File菜单中的保存选项。
l 单击CodeBrowser窗口工具栏中的Save图标。
l 关闭CodeBrowser窗口。
l 在Ghidra窗口中保存项目。
l 通过Ghidra的File菜单退出Ghidra。
在上述每种情况下,Ghidra都会提示您保存任何修改过的文件。关于更改CodeBrowser窗口以及其他Ghidra工具的外观和功能的方法,我们会在将来的文章中详细加以介绍。
由于Ghidra会显示大量的信息,从而导致桌面变得杂乱不堪。下面给出一些最大限度地利用桌面的技巧:
1. 如果条件允许,最好使用一台超大尺寸的显示器,或者使用多台显示器!
2. 别忘了,我们可以使用CodeBrowser的Window菜单来打开新视图,或恢复您无意中关闭的数据显示视图。实际上,有很多窗口也可以通过CodeBrowser的工具栏上的工具按钮打开。
3. 当您打开一个新窗口时,它可能会出现在一个现有窗口的前面。发生这种情况时,可以在窗口的顶部或底部查找完成窗口切换的选项卡。
4. 您可以关闭任何窗口,然后再根据需要重新打开它,并将其拖动到CodeBrowser桌面中的任意位置。
5. 您可以使用在Edit菜单Tool Options菜单项中的Display选项来控制显示界面的外观。
尽管上面介绍的只是各种技巧中的冰山一角,但是当您开始浏览Ghidra CodeBrowser桌面时,它们应该会对您有所帮助。
熟悉CodeBrowser桌面的好处在于,这能极大地提升您的Ghidra体验。逆向分析二进制代码的工作已经够难了,所以,使用的工具最好能够为我们分担一些烦恼。实际上,我们在初始加载阶段选择的选项以及由Ghidra执行的关联分析,能够为将来的分析工作打下良好的基础。甚至很多情况下,Ghidra替我们完成的工作就已经足够好了——对于简单的二进制文件来说,这些可能已经能够满足我们的需求了。另一方面,如果您想知道如何在逆向工程过程中获得更多控制权,则需要更深入地研究Ghidra各种数据显示视图的功能。在后面的文章中,我们将为读者介绍各种主要的显示视图,它们的适用场景,以及如何利用它们来优化工作流程。
本文作者:mssp299
本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/140673.html