analyzing-golang-malware-with-ghidra

使用 Ghidra 及专用脚本对 Go 编译的恶意软件进行逆向工程,包括函数恢复、字符串提取和去符号表 Go 二进制文件的类型重建。

9 stars

Best use case

analyzing-golang-malware-with-ghidra is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

使用 Ghidra 及专用脚本对 Go 编译的恶意软件进行逆向工程,包括函数恢复、字符串提取和去符号表 Go 二进制文件的类型重建。

Teams using analyzing-golang-malware-with-ghidra should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/analyzing-golang-malware-with-ghidra/SKILL.md --create-dirs "https://raw.githubusercontent.com/killvxk/cybersecurity-skills-zh/main/skills/analyzing-golang-malware-with-ghidra/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/analyzing-golang-malware-with-ghidra/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How analyzing-golang-malware-with-ghidra Compares

Feature / Agentanalyzing-golang-malware-with-ghidraStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

使用 Ghidra 及专用脚本对 Go 编译的恶意软件进行逆向工程,包括函数恢复、字符串提取和去符号表 Go 二进制文件的类型重建。

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# 使用 Ghidra 分析 Golang 恶意软件

## 概述

Go(Golang)因其跨平台编译能力、生成自包含二进制文件的静态链接以及逆向工程的复杂性,成为恶意软件作者的热门语言。Go 二进制文件包含整个运行时、标准库和所有依赖项的静态链接,产生大型二进制文件(通常 5-15MB),包含数千个函数。Ghidra 在处理 Go 特有的字符串格式(非空终止符)、去符号的函数名和 goroutine 并发模式时存在困难。Volexity 开发的 GoResolver 等专用工具使用控制流图相似性在去符号或混淆的 Go 二进制文件中自动去混淆并恢复函数名。

## 前置条件

- Ghidra 11.0+,配合 JDK 17+
- GoResolver 插件(用于函数名恢复)
- Go 逆向工程工具包(go-re.tk)
- Python 3.9+(用于辅助脚本)
- 了解 Go 运行时内部机制(goroutine、channel、interface)
- 熟悉 Go 二进制文件结构(pclntab、moduledata、itab)

## 核心概念

### Go 二进制文件结构

Go 二进制文件在 `pclntab`(PC 行表)结构中嵌入了丰富的元数据,将程序计数器映射到函数名、源文件和行号。即使去符号表的二进制文件也保留此元数据。`moduledata` 结构包含指向类型信息、itab(接口表)和 pclntab 本身的指针。Go 字符串以指针-长度对的形式存储,而非以空字符结尾的 C 字符串。

### 去符号表二进制文件中的函数恢复

尽管去除了符号表,Go 二进制文件仍在 pclntab 中保留函数名。然而,garble 等混淆工具会将函数重命名为随机字符串。GoResolver 通过计算混淆函数的控制流图签名,并与已知 Go 标准库和第三方包函数的数据库进行匹配来解决此问题。

### 包/依赖项提取

Go 的依赖管理将模块路径和版本字符串嵌入二进制文件。提取这些信息可揭示恶意软件的第三方依赖(HTTP 库、加密包、C2 框架),在不进行完整逆向工程的情况下了解其能力。

## 实操步骤

### 步骤 1:初始二进制分析

```python
#!/usr/bin/env python3
"""分析 Go 二进制文件元数据用于恶意软件分析。"""
import struct
import sys
import re


def find_go_build_info(data):
    """从二进制文件提取 Go 构建信息。"""
    # Go buildinfo 魔数:\xff Go buildinf:
    magic = b'\xff Go buildinf:'
    offset = data.find(magic)
    if offset == -1:
        return None

    print(f"[+] Go 构建信息位于偏移 0x{offset:x}")

    # 提取附近的 Go 版本字符串
    go_version = re.search(rb'go\d+\.\d+(?:\.\d+)?', data[offset:offset+256])
    if go_version:
        print(f"  Go 版本:{go_version.group().decode()}")

    return offset


def find_pclntab(data):
    """定位 pclntab(PC 行表)结构。"""
    # pclntab 魔数字节随 Go 版本而变化
    magics = {
        b'\xfb\xff\xff\xff\x00\x00': "Go 1.2-1.15",
        b'\xfa\xff\xff\xff\x00\x00': "Go 1.16-1.17",
        b'\xf1\xff\xff\xff\x00\x00': "Go 1.18-1.19",
        b'\xf0\xff\xff\xff\x00\x00': "Go 1.20+",
    }

    for magic, version in magics.items():
        offset = data.find(magic)
        if offset != -1:
            print(f"[+] pclntab 位于 0x{offset:x}({version})")
            return offset, version

    return None, None


def extract_function_names(data, pclntab_offset):
    """从 pclntab 提取函数名。"""
    if pclntab_offset is None:
        return []

    functions = []
    # 函数名字符串遵循特定模式
    func_pattern = re.compile(
        rb'(?:main|runtime|fmt|net|os|crypto|encoding|io|sync|'
        rb'syscall|reflect|strings|bytes|path|time|math|sort|'
        rb'github\.com|golang\.org)[/\.][\w/.]+',
    )

    for match in func_pattern.finditer(data):
        name = match.group().decode('utf-8', errors='replace')
        if len(name) > 4 and len(name) < 200:
            functions.append(name)

    return sorted(set(functions))


def extract_go_strings(data):
    """提取 Go 风格字符串(指针+长度对)。"""
    # Go 字符串不以空字符结尾;提取可读序列
    strings = []
    ascii_pattern = re.compile(rb'[\x20-\x7e]{10,}')

    for match in ascii_pattern.finditer(data):
        s = match.group().decode('ascii')
        # 过滤出有趣的恶意软件字符串
        interesting = [
            'http', 'https', 'tcp', 'udp', 'dns',
            'cmd', 'shell', 'exec', 'upload', 'download',
            'encrypt', 'decrypt', 'key', 'token', 'password',
            'c2', 'beacon', 'agent', 'implant', 'bot',
            'mutex', 'persist', 'registry', 'scheduled',
        ]
        if any(kw in s.lower() for kw in interesting):
            strings.append(s)

    return strings


def extract_dependencies(data):
    """从二进制文件提取 Go 模块依赖项。"""
    deps = []
    # 模块路径遵循模式:github.com/user/repo
    dep_pattern = re.compile(
        rb'((?:github\.com|gitlab\.com|golang\.org|gopkg\.in|'
        rb'go\.etcd\.io|google\.golang\.org)/[^\x00\s]{5,80})'
    )

    for match in dep_pattern.finditer(data):
        dep = match.group().decode('utf-8', errors='replace')
        deps.append(dep)

    unique_deps = sorted(set(deps))
    return unique_deps


def analyze_go_binary(filepath):
    """对 Go 恶意软件二进制文件进行完整分析。"""
    with open(filepath, 'rb') as f:
        data = f.read()

    print(f"[+] 正在分析 Go 二进制文件:{filepath}")
    print(f"  文件大小:{len(data):,} 字节")
    print("=" * 60)

    # 构建信息
    find_go_build_info(data)

    # pclntab
    pclntab_offset, go_version = find_pclntab(data)

    # 函数
    functions = extract_function_names(data, pclntab_offset)
    print(f"\n[+] 恢复了 {len(functions)} 个函数名")

    # 分类函数
    categories = {
        "network": [], "crypto": [], "os_exec": [],
        "file_io": [], "main": [], "third_party": [],
    }
    for f in functions:
        if 'net/' in f or 'http' in f.lower():
            categories["network"].append(f)
        elif 'crypto' in f:
            categories["crypto"].append(f)
        elif 'os/exec' in f or 'syscall' in f:
            categories["os_exec"].append(f)
        elif 'os.' in f or 'io/' in f:
            categories["file_io"].append(f)
        elif f.startswith('main.'):
            categories["main"].append(f)
        elif 'github.com' in f or 'golang.org' in f:
            categories["third_party"].append(f)

    for cat, funcs in categories.items():
        if funcs:
            print(f"\n  [{cat}]({len(funcs)} 个函数):")
            for fn in funcs[:10]:
                print(f"    {fn}")

    # 依赖项
    deps = extract_dependencies(data)
    print(f"\n[+] 依赖项({len(deps)} 个):")
    for dep in deps[:20]:
        print(f"    {dep}")

    # 可疑字符串
    sus_strings = extract_go_strings(data)
    print(f"\n[+] 可疑字符串({len(sus_strings)} 个):")
    for s in sus_strings[:20]:
        print(f"    {s}")


if __name__ == "__main__":
    if len(sys.argv) < 2:
        print(f"用法:{sys.argv[0]} <go_binary>")
        sys.exit(1)
    analyze_go_binary(sys.argv[1])
```

### 步骤 2:Ghidra 分析脚本

```python
# Ghidra 脚本(在 Ghidra 的脚本管理器中运行)
# 保存为 AnalyzeGoBinary.py 到 Ghidra scripts 目录

# @category MalwareAnalysis
# @description 分析 Go 二进制结构并恢复元数据

def analyze_go_binary_ghidra():
    """用于 Go 二进制分析的 Ghidra 脚本。"""
    from ghidra.program.model.mem import MemoryAccessException

    program = getCurrentProgram()
    memory = program.getMemory()
    listing = program.getListing()

    print("[+] Go 二进制分析脚本")
    print(f"  程序:{program.getName()}")

    # 查找 pclntab
    pclntab_magics = [
        bytes([0xf0, 0xff, 0xff, 0xff]),  # Go 1.20+
        bytes([0xf1, 0xff, 0xff, 0xff]),  # Go 1.18-1.19
        bytes([0xfa, 0xff, 0xff, 0xff]),  # Go 1.16-1.17
        bytes([0xfb, 0xff, 0xff, 0xff]),  # Go 1.2-1.15
    ]

    for magic in pclntab_magics:
        addr = memory.findBytes(
            program.getMinAddress(), magic, None, True, None
        )
        if addr:
            print(f"[+] pclntab 位于 {addr}")
            # 创建标签
            program.getSymbolTable().createLabel(
                addr, "go_pclntab", None,
                ghidra.program.model.symbol.SourceType.ANALYSIS
            )
            break

    # 修复 Go 字符串定义
    # Go 字符串是 ptr+len,不是空终止
    print("[+] 正在修复 Go 字符串引用...")

    # 搜索包含包路径的函数名
    symbol_table = program.getSymbolTable()
    func_count = 0
    for symbol in symbol_table.getAllSymbols(True):
        name = symbol.getName()
        if ('.' in name and
            any(pkg in name for pkg in
                ['main.', 'runtime.', 'net.', 'crypto.', 'os.'])):
            func_count += 1

    print(f"[+] 找到 {func_count} 个 Go 函数符号")


# 执行
analyze_go_binary_ghidra()
```

## 验证标准

- 从二进制文件提取 Go 版本和构建信息
- 定位并解析 pclntab 用于函数名恢复
- 识别第三方依赖项,揭示恶意软件能力
- 枚举 main 包函数用于有针对性的分析
- 对网络、加密和操作系统执行函数进行分类
- Ghidra 分析正确标记 Go 运行时结构

## 参考资料

- CUJO AI - 使用 Ghidra 逆向工程 Go 二进制文件
- Volexity GoResolver
- Go 逆向工程工具包
- SentinelOne AlphaGolang
- Go 二进制逆向笔记

Related Skills

reverse-engineering-rust-malware

9
from killvxk/cybersecurity-skills-zh

使用 IDA Pro 和 Ghidra 对 Rust 编译的恶意软件进行逆向工程,掌握处理非空终止字符串、提取 crate 依赖项和 Rust 特有控制流分析的专项技术。

reverse-engineering-malware-with-ghidra

9
from killvxk/cybersecurity-skills-zh

使用 NSA 的 Ghidra 反汇编器和反编译器对恶意软件二进制文件进行逆向工程,在汇编和伪 C 代码层面理解其内部逻辑、密码学例程、C2 协议和规避技术。适用于恶意软件逆向工程、反汇编分析、反编译、二进制分析或理解恶意软件内部机制等请求。

reverse-engineering-dotnet-malware-with-dnspy

9
from killvxk/cybersecurity-skills-zh

使用 dnSpy 反编译器和调试器对 .NET 恶意软件进行逆向工程,分析 C#/VB.NET 源代码,识别混淆技术,提取配置信息,理解包括信息窃取器、远程访问木马(RAT)和加载器在内的恶意功能。适用于 .NET 恶意软件分析、C# 恶意软件反编译、托管代码逆向工程或 .NET 混淆分析等请求。

reverse-engineering-android-malware-with-jadx

9
from killvxk/cybersecurity-skills-zh

使用 JADX 反编译器对恶意 Android APK 文件进行逆向工程,分析 Java/Kotlin 源代码,识别包括数据窃取、C2 通信、权限提升和覆盖攻击在内的恶意功能。检查 Manifest 权限、Receiver、Service 及原生库。适用于 Android 恶意软件分析、APK 逆向工程、移动端恶意软件调查或 Android 威胁分析等请求。

performing-static-malware-analysis-with-pe-studio

9
from killvxk/cybersecurity-skills-zh

使用 PEStudio 对 Windows PE(可移植可执行文件)恶意软件样本进行静态分析, 检查文件头、导入表、字符串、资源和指标,无需执行二进制文件。 识别可疑特征,包括加壳、反分析技术和恶意导入。适用于静态恶意软件分析、 PE 文件检查、Windows 可执行文件分析或执行前恶意软件分级等请求场景。

performing-malware-triage-with-yara

9
from killvxk/cybersecurity-skills-zh

使用 YARA 规则对文件模式、字符串、字节序列和结构特征进行匹配,快速分级和分类恶意软件样本, 识别已知恶意软件家族及可疑指标。涵盖规则编写、扫描和与分析流程的集成。适用于 YARA 规则创建、 恶意软件分类、模式匹配、样本分级或基于签名的检测等请求场景。

performing-malware-persistence-investigation

9
from killvxk/cybersecurity-skills-zh

系统性地调查 Windows 和 Linux 系统上的所有持久化机制,以识别恶意软件如何在重启后存活并维持访问。

performing-malware-ioc-extraction

9
from killvxk/cybersecurity-skills-zh

恶意软件 IOC(失陷指标)提取是指通过分析恶意软件,识别可操作的失陷指标,包括文件哈希、网络指标(C2 域名、IP 地址、URL)、注册表修改、互斥体名称、嵌入字符串和行为产物。

performing-malware-hash-enrichment-with-virustotal

9
from killvxk/cybersecurity-skills-zh

使用 VirusTotal API 富化恶意软件文件哈希,获取检测率、行为分析、YARA 匹配和上下文威胁情报,用于事件分类和 IOC 验证。

performing-firmware-malware-analysis

9
from killvxk/cybersecurity-skills-zh

分析固件镜像中嵌入的恶意软件、后门和未授权修改,目标包括路由器、IoT 设备、UEFI/BIOS 和嵌入式系统。涵盖固件提取、文件系统分析、二进制逆向工程和 Bootkit 检测。适用于固件安全 分析、IoT 恶意软件调查、UEFI Rootkit 检测或嵌入式设备入侵评估等请求场景。

performing-automated-malware-analysis-with-cape

9
from killvxk/cybersecurity-skills-zh

部署和操作 CAPEv2 沙箱,进行自动化恶意软件分析,具备行为监控、载荷提取、配置解析和反规避能力。

extracting-iocs-from-malware-samples

9
from killvxk/cybersecurity-skills-zh

从恶意软件样本中提取攻陷指标(IoC),包括文件哈希、网络指标(IP、域名、URL)、 主机痕迹(文件路径、注册表键、互斥锁)以及行为模式,用于威胁情报共享和检测规则创建。 适用于 IoC 提取、威胁指标采集、恶意软件指标收集或从样本构建检测内容等请求场景。