# Performing Memory Forensics With Volatility3 Plugins

> 使用 Volatility3 插件分析内存转储，检测 Windows、Linux 和 macOS 内存镜像中的注入代码、Rootkit、凭据窃取和恶意软件痕迹。

- Skill: `killvxk/performing-memory-forensics-with-volatility3-plugins` (Agent Skill, multi-file: 8 files)
- Install (CLI): `npx skillmds@latest add killvxk/performing-memory-forensics-with-volatility3-plugins`
- Raw SKILL.md: https://api.skillmd.com/api/skills/killvxk/performing-memory-forensics-with-volatility3-plugins/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: Apache-2.0
- Author: killvxk (https://skillmd.com/u/killvxk)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/killvxk/performing-memory-forensics-with-volatility3-plugins

---

# 使用 Volatility3 插件进行内存取证

## 概述

Volatility3（v2.26.0+，2025 年 5 月发布功能对等版本）是内存取证的标准框架，取代了已弃用的 Volatility2。它分析来自 Windows、Linux 和 macOS 的 RAM 转储，可检测恶意进程、代码注入、Rootkit、凭据收集以及基于磁盘的取证无法发现的网络连接。主要插件包括：`windows.malfind`（检测表明注入的 RWX 内存区域）、`windows.psscan`（发现隐藏进程）、`windows.dlllist`（枚举已加载模块）、`windows.netscan`（活跃网络连接）和 `windows.handles`（打开的文件/注册表句柄）。2024 年插件大赛引入了 ETW Scan，用于从内存中提取 Windows 事件跟踪数据。

## 前置条件

- Python 3.9+，安装 `volatility3` 框架
- 内存转储文件（`.raw`、`.dmp`、`.vmem`、`.lime`）
- Windows 符号表（ISF 文件，自动下载）
- 了解 Windows 进程内存架构
- YARA 集成，用于内存模式扫描

## 操作步骤

### 步骤 1：进程分析以检测恶意软件

```python
#!/usr/bin/env python3
"""基于 Volatility3 的内存取证自动化工具，用于恶意软件分析。"""
import subprocess
import json
import sys
import os


class Vol3Analyzer:
    """自动化执行 Volatility3 插件进行恶意软件分析。"""

    def __init__(self, dump_path, vol3_path="vol"):
        self.dump_path = dump_path
        self.vol3 = vol3_path
        self.results = {}

    def run_plugin(self, plugin, extra_args=None):
        """执行 Volatility3 插件并捕获输出。"""
        cmd = [
            self.vol3, "-f", self.dump_path,
            "-r", "json", plugin,
        ]
        if extra_args:
            cmd.extend(extra_args)

        try:
            result = subprocess.run(
                cmd, capture_output=True, text=True, timeout=300
            )
            if result.returncode == 0:
                return json.loads(result.stdout)
        except (subprocess.TimeoutExpired, json.JSONDecodeError) as e:
            print(f"  [!] {plugin} 失败：{e}")
        return None

    def detect_process_injection(self):
        """使用 malfind 检测注入的代码区域。"""
        print("[+] 运行 windows.malfind（代码注入检测）")
        results = self.run_plugin("windows.malfind")

        injected = []
        if results:
            for entry in results:
                injected.append({
                    "pid": entry.get("PID"),
                    "process": entry.get("Process"),
                    "address": entry.get("Start VPN"),
                    "protection": entry.get("Protection"),
                    "hexdump": entry.get("Hexdump", "")[:200],
                })
                print(f"  [!] PID {entry.get('PID')} "
                      f"（{entry.get('Process')}）中发现注入，地址：{entry.get('Start VPN')}")

        self.results["injected_processes"] = injected
        return injected

    def find_hidden_processes(self):
        """比较 pslist 与 psscan 以发现隐藏进程。"""
        print("[+] 运行进程对比（pslist vs psscan）")

        pslist = self.run_plugin("windows.pslist")
        psscan = self.run_plugin("windows.psscan")

        if not pslist or not psscan:
            return []

        list_pids = {e.get("PID") for e in pslist}
        scan_pids = {e.get("PID") for e in psscan}

        hidden = scan_pids - list_pids
        if hidden:
            print(f"  [!] 发现 {len(hidden)} 个隐藏进程！")
            for entry in psscan:
                if entry.get("PID") in hidden:
                    print(f"    PID {entry['PID']}: {entry.get('ImageFileName')}")

        self.results["hidden_processes"] = list(hidden)
        return list(hidden)

    def analyze_network(self):
        """提取活跃网络连接。"""
        print("[+] 运行 windows.netscan")
        results = self.run_plugin("windows.netscan")

        connections = []
        if results:
            for entry in results:
                conn = {
                    "pid": entry.get("PID"),
                    "process": entry.get("Owner"),
                    "local": f"{entry.get('LocalAddr')}:{entry.get('LocalPort')}",
                    "remote": f"{entry.get('ForeignAddr')}:{entry.get('ForeignPort')}",
                    "state": entry.get("State"),
                    "protocol": entry.get("Proto"),
                }
                connections.append(conn)

        self.results["network_connections"] = connections
        return connections

    def extract_dlls(self, pid=None):
        """列出每个进程加载的 DLL。"""
        print(f"[+] 运行 windows.dlllist{f'（PID {pid}）' if pid else ''}")
        args = ["--pid", str(pid)] if pid else None
        results = self.run_plugin("windows.dlllist", args)

        dlls = []
        if results:
            for entry in results:
                dlls.append({
                    "pid": entry.get("PID"),
                    "process": entry.get("Process"),
                    "base": entry.get("Base"),
                    "name": entry.get("Name"),
                    "path": entry.get("Path"),
                    "size": entry.get("Size"),
                })

        self.results["loaded_dlls"] = dlls
        return dlls

    def scan_with_yara(self, rules_path):
        """使用 YARA 规则扫描内存。"""
        print(f"[+] 运行 windows.yarascan，规则文件：{rules_path}")
        results = self.run_plugin(
            "windows.yarascan",
            ["--yara-file", rules_path]
        )

        matches = []
        if results:
            for entry in results:
                matches.append({
                    "rule": entry.get("Rule"),
                    "pid": entry.get("PID"),
                    "process": entry.get("Process"),
                    "offset": entry.get("Offset"),
                })

        self.results["yara_matches"] = matches
        return matches

    def full_triage(self):
        """运行以恶意软件为重点的完整内存分级。"""
        print(f"[*] 完整内存分级：{self.dump_path}")
        print("=" * 60)

        self.detect_process_injection()
        self.find_hidden_processes()
        self.analyze_network()

        return self.results


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

    analyzer = Vol3Analyzer(sys.argv[1])
    results = analyzer.full_triage()
    print(json.dumps(results, indent=2, default=str))
```

## 验证标准

- 内存转储已成功使用正确的操作系统配置文件解析
- 通过 malfind 检测到具有 RWX 区域的注入进程
- 通过 pslist/psscan 对比识别出隐藏进程
- 网络连接揭示 C2 通信端点
- YARA 规则匹配内存中的已知恶意软件签名
- 从 lsass 进程内存中提取凭据痕迹

## 参考资料

- [Volatility Foundation](https://volatilityfoundation.org/)
- [Volatility3 GitHub](https://github.com/volatilityfoundation/volatility3)
- [2024 年 Volatility 插件大赛](https://volatilityfoundation.org/the-2024-volatility-plugin-contest-results-are-in/)
- [使用 Volatility 3 进行内存取证](https://newtonpaul.com/malware-analysis-memory-forensics-with-volatility-3/)
- [MITRE ATT&CK T1055 - 进程注入](https://attack.mitre.org/techniques/T1055/)

