Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
ghostrings — 用于恢复 Go 二进制文件中字符串定义的 Ghidra 脚本 | Kitploit
工具/GitHubGitHub/nccgroup/ghostrings
代码分析逆向工程二进制分析
GitHubnccgroup/ghostrings

ghostrings

用于恢复 Go 二进制文件中字符串定义的 Ghidra 脚本

查看仓库网站
13898个月前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

Ghostrings

用于通过 P-Code 分析恢复 Go 二进制文件中字符串定义的脚本。 已在 x86、x86-64、ARM 和 ARM64 上测试。

脚本

Golang

这些可以在脚本管理器(Script Manager)的 Golang 类别中找到。

  • GoDynamicStrings.java
    • 分析 P-Code 以查找在栈上创建的字符串结构。使用较低层的“寄存器”风格分析。
  • GoFuncCallStrings.java
    • 分析 P-Code 以查找直接通过寄存器传递给函数调用而无需写入栈的字符串结构。使用“规范化”(normalize)风格分析,并借助 Ghidra 新的内置 Golang 支持(支持的 Golang 版本请参阅 Ghidra 发布说明)。
  • GoStaticStrings.java
    • 查找静态分配在只读内存中的 Go 字符串结构。
  • GoKnownStrings.java
    • 搜索标准的唯一字符串并进行定义。字符串数据从 data/known_strings.json 加载。
  • GoStringFiller.java
    • 在初始分析后,根据字符串数据的长度升序填充 go.string.* 中的空白。

还有一些动态字符串分析脚本的特殊变体:

  • GoDynamicStringsSingle.java
    • 执行与 GoDynamicStrings.java 相同的分析,但使用单个反编译器进程。如果在分析二进制文件时并行反编译器进程耗尽系统内存,请使用此脚本。
  • GoDynamicStringsHigh.java
    • 实验性脚本,使用更高级的“规范化”风格分析产生的 P-Code 输出。目前依赖于一项关闭反编译器中死代码消除的 hack(见 https://research.nccgroup.com/2022/05/20/earlyremoval-in-the-conservatory-with-the-wrench/)。此 hack 在 Ghidra 10.2 中已失效。

P-Code

这可以在脚本管理器(Script Manager)的 PCode 类别中找到。

  • PrintHighPCode.java
    • 将当前选中函数的高层 P-Code 输出打印到控制台,并可选择要使用的反编译器简化风格。主要用于开发 P-Code 分析脚本。

字符串恢复流程

以下是使用这些脚本恢复 Go 二进制文件中字符串定义的一般流程:

  1. 清除只读数据内存块中所有不正确或自动定义的字符串。
    • 在“已定义字符串”(Defined Strings)窗口中,启用“内存块”(Mem Block)列,并按内存块筛选以选择 .rodata、.rdata 或 __rodata 中的所有字符串。然后在代码列表中右键单击并选择“清除代码字节”(Clear Code Bytes)。
  2. (可选) 运行 GoKnownStrings.java 以检测一些标准字符串。
  3. 运行 GoStaticStrings.java。
  4. 运行 GoFuncCallStrings.java (如果 Ghidra 的内置 Golang 功能支持该 Golang 二进制版本)。
  5. 运行 GoDynamicStrings.java。
  6. 运行 GoStringFiller.java。
    • 如果检测到字符串数据长度升序被违反,请清除该区域中任何误报的字符串定义,然后重新运行脚本。有一个选项可以自动执行此操作。
    • 如果二进制文件已被剥离(stripped),请定位动态字符串脚本找到的单字节字符串区域。 确保它是已分组的非空终止字符串的起始位置(之后应定义更多字符串,长度按升序排列)。 在第一个单字节字符串处创建标签 go.string.*。
  7. 检查 go.string.* 中剩余的空白,并定义任何具有明显起点和终点的字符串。
    • 为了充分利用 GoStringFiller.java,请确定未定义字符串数据中字符串长度发生变化的位置,并定义最接近该边界的字符串。然后重新运行 ,以自动填充它能够正确确定剩余未定义字符串长度的位置。

设置

安装

在 Ghidra 中:

  1. 文件(File)-> 安装扩展(Install Extensions)-> 添加扩展(Add extension)
  2. 选择扩展 ZIP 文件

开发

对于带有 GhidraDev 插件的 Eclipse:

  1. 克隆仓库
  2. 文件(File)-> 导入(Import)-> 从文件夹或归档导入项目(Projects from Folder or Archive)
  3. 选择仓库目录
  4. GhidraDev -> 链接 Ghidra(Link Ghidra)...
  5. 选择导入的项目

构建

使用 Eclipse 构建:

  • GhidraDev -> 导出(Export)-> Ghidra 模块扩展(Ghidra Module Extension)...

直接使用 Gradle 构建:

root@kitploit:~
$ cd Ghostrings
$ gradle -PGHIDRA_INSTALL_DIR=<ghidra_install_dir>

背景

逆向工程 Go 程序时一个众所周知的问题是,Go 字符串缺少空终止符,这使得从编译后的二进制文件恢复字符串定义变得困难。Go 程序的许多常量字符串值在编译构建中会全部存储在一个巨大的数据块中,字符串数据中没有任何终止符来标记一个字符串在哪里结束、另一个字符串从哪里开始。即使是一个只打印 “Hello world!” 的简单程序,也有超过 1,500 个与 Go 运行时系统和其他标准库相关的字符串。这可能导致典型的 ASCII 字符串发现实现(例如 Ghidra 提供的实现)产生长达数万个字符的误报字符串定义。

Go 使用的不是以空字符结尾的字符串,而是一种由指针和长度值组成的字符串结构。许多这类字符串结构在运行时创建于程序栈上,因此恢复单个字符串的起始位置和长度值需要分析编译后的机器码。有一些现有脚本通过检查某些 x86-64 指令模式来执行此分析,但它们会漏掉那些最终对栈产生相同效果但指令变体未处理的字符串结构,而且它们也仅限于特定的 ISA。

Ghostrings 通过使用 Ghidra 反编译器分析生成的、与架构无关的简化 P-Code 操作来避免这两个问题。

发布信息

版权所有 2022 NCC Group。根据 GPLv3 许可证发布(见 LICENSE)。

项目主要作者:James Chambers [email protected]

下载工具
GoStringFiller.java
  • (可选) 重新运行 Ghidra 内置的 ASCII 字符串分析工具。
    • 禁止覆盖现有字符串。分别在需要空终止符和不需要空终止符的情况下运行。