DeepCut / CodeCut GUI 的 Ghidra 插件
CodeCut 允许用户将函数分配给 Ghidra 中的目标文件,然后在目标文件级别与二进制文件进行交互。通过设置 Ghidra 数据库中的 Namespace 字段,可以将函数分配给目标文件。DeepCut 尝试建立初始的目标文件边界,用户随后可以使用 CodeCut Table 窗口进行调整。
大多数二进制文件来自多个源代码文件。在进行逆向工程时,逆向分析师通常会形成一种感觉,即哪些函数是相关的,因此可能属于同一个源文件。CodeCut 允许分析师形成这样的假设:“我认为这一组函数是操作系统函数。” 现在,如果该区域中存在未探索的函数,它们将在反汇编和反编译中显示为 OS::FUN_XXXXXXXX,而不是仅显示为 FUN_XXXXXXXX。这有助于在上下文中查看时更快地理解函数可能用于什么用途。
按照常规的 Ghidra 扩展安装步骤操作。将 CodeCut 和 DeepCut 扩展 zip 复制到 $GHIDRA_INSTALL_DIR/Extensions,然后在 Ghidra 主窗口中选择 文件 -> 安装扩展(File -> Install Extensions),并勾选 CodeCut 和 DeepCut 复选框。Ghidra 会提示您需要重启。由于现在 Ghidra 仅要求插件与基础版本的主/次版本号匹配,而不要求与补丁版本号匹配,我们预计只会发布主/次版本号均为偶数的版本。
注意: 重启并加载 CodeBrowser 窗口后,Ghidra 会提示您发现了新插件,并询问是否要配置它们。在此窗口中只会显示 CodeCut。这是因为 DeepCut 是一个“一次性”分析器(它仍然已安装)。
CodeCut 和 DeepCut 都依赖本机 PyGhidra 扩展,并且与 Jython 不兼容。CodeCut 使用本机 Python 来猜测模块名称。DeepCut 的模型推理在本机 Python 中运行。
CodeCut:
DeepCut:
要安装依赖项,请使用与您的 PyGhidra 关联的 Python 安装运行:
pip install nltk
pip install torch torch-geometric networkx scipy
DeepCut 最好在初始自动分析之后作为一次性分析器运行。选择 分析 -> 一次性 -> Deepcut(Analysis -> One Shot -> Deepcut)。DeepCut 运行完成后,您可以通过查看 符号表(Symbol Table)视图中的 Namespace 字段来查看结果。

DeepCut 运行后,您可以通过 CodeCut Table 视图在目标文件级别进行交互。选择 窗口 -> CodeCut Table(Window -> CodeCut Table)来显示该表格。CodeCut 表格本质上是符号表的组合,每个模块对应一个符号表。
您可以在此 CodeCut Table 窗口中选择 分析 -> 猜测模块名称(Analysis -> Guess Module Names),让 CodeCut 猜测模块名称(基于字符串引用)。如果目标可执行文件包含大量调试字符串,这将很有帮助。名称猜测脚本会首先尝试查找源文件名,然后回退到重复出现多次的字符串(包括二元组和三元组)。
您可以通过右键单击某个对象并选择 在此处拆分命名空间(Split Namespace Here)/合并命名空间(Combine Namespaces)来拆分/合并目标文件。您可以通过拖放将函数移动到其他目标文件之间(从而改变目标文件的边界)。
CodeCut 包含两个选项,用于在 CodeCut 表格中右键单击模块时,通过 导出(Export)菜单将整个模块或模块的子范围导出为可重新编译的 C。此功能标记为实验性(EXPERIMENTAL),尚未经过充分测试。

CodeCut 现在提供了一个图形选项,用于查看二进制文件中模块之间的交互/层次结构。通过在 CodeCut Table 中右键单击函数并选择 将命名空间添加到图形(Add Namespace to Graph),可以将命名空间添加到图形视图。您可以通过右键单击并选择 在图形过滤器中显示命名空间(Show Namespaces in Graph Filter)来从图形中移除模块。
虽然看起来您可以右键单击右侧的模块名称,但实际上 CodeCut 关注的是表格中当前高亮的函数。例如,如果您在 object3 中高亮了一个函数,然后右键单击左侧灰色的 object2 框,并单击“合并/拆分”或“重命名命名空间”,CodeCut 将从您在 object3 中高亮的函数执行该操作。
CodeCut 会尝试按起始地址对命名空间进行排序。CodeCut 列出的模块可能看起来顺序不对,但这通常是由于 Ghidra 的反汇编不规则性所致。例如,假设我们有一个如下所示的内存映射:
object2: 0x00010000 - 0x00018000
object3: 0x00018004 - 0x00020000
...
object50: 0x00480000 - 0x00480a00
假设位于 0x00480000 的函数分支或跳转到地址 0x00016008。这应该是一个新的函数入口点,但如果只有一个函数使用它,Ghidra 可能不会将其标记为函数入口点,而只是将其视为 FUN_00480000 的一部分。这意味着 object50 的实际范围是 0x00016008 - 0x00480a00。因此,object50 会在表格中显示在 object2 和 object3 之间。CodeCut 会将模块范围输出到 Ghidra 的应用程序日志中,以帮助调试此问题。在这种情况下,将 0x00016008 定义为函数将使 object50 的边界恢复正确值,并且 object50 将显示在表格中的正确位置。
在 DeepCut 分析运行之后定义的函数,默认情况下会被添加到 Global 命名空间。未来我们计划添加一项功能,将它们自动添加到最近的命名空间,或者提供一种机制,以便更轻松地将单个函数直接分配给特定的命名空间。
具体的构建说明在 DeepCut 和 CodeCut 子文件夹中提供。