EzPDB

December 23, 2025 · View on GitHub

EzPDB 是一个基于 Windows DbgHelp 的轻量 C++ 工具:先将目标模块对应的 PDB 按符号服务器规则下载到本地缓存,再基于本地 PDB 解析符号并计算 RVA。

运行环境

  • Windows 10/11
  • MSVC(项目默认使用 C++20)
  • 运行时需要 DbgHelp/SymSrv 组件(多数系统环境已具备;若符号下载失败,可安装 Windows SDK/Debugging Tools,或将 dbghelp.dll/symsrv.dll 放到程序同目录)

集成方式

  • EzPDB/ez_pdb.hEzPDB/ez_pdb.cpp 添加到你的工程
  • 链接依赖中加入 Dbghelp.lib

用法

#include "ez_pdb.h"

#include <iostream>

int main()
{
    ez_pdb pdb("C:\\Windows\\System32\\ntoskrnl.exe");
    if (!pdb.init())
    {
        return 1;
    }

    const auto rva = pdb.get_rva("PspCidTable");
    if (!rva.has_value())
    {
        return 1;
    }

    std::cout << std::hex << rva.value() << std::endl;
    return 0;
}

默认参数:

  • 符号服务器:https://msdl.microsoft.com/download/symbols
  • 缓存目录:./symbol

可通过构造函数覆盖:

ez_pdb pdb(
    "C:\\Windows\\System32\\ntoskrnl.exe",
    "https://msdl.microsoft.com/download/symbols",
    "D:\\symbols");

注意事项

  • 本实现使用 DbgHelp 的符号处理器(进程级全局资源),同一进程内的多实例会共享状态;如果你的进程中还有其他组件也在使用 DbgHelp,建议统一规划其生命周期与搜索路径设置。
  • 首次解析可能触发符号下载,耗时取决于网络与缓存命中情况。
  • init() 会先下载 PDB 到本地,然后将 DbgHelp 的搜索路径设置为“仅本地 PDB 目录”,确保解析阶段不依赖网络。

构建

使用 Visual Studio 打开 EzPDB.sln,选择目标配置(例如 Release|x64),手工执行构建。

验证

  • 在联网环境首次运行示例程序,确认会在缓存目录(默认 ./symbol)生成符号缓存
  • 运行 EzPDB 示例程序,期望看到类似 nt!PspCidTable = 0x... 的输出
  • 若符号下载失败,优先检查 dbghelp.dll/symsrv.dll 可用性与网络访问策略,然后将构造函数中的符号服务器改为 http://msdl.microsoft.com/download/symbols 再尝试一次

测试

  • 使用 Visual Studio 打开 EzPDB.sln
  • 选择 Debug|x64(或你的目标平台),构建解决方案
  • 打开“测试资源管理器(Test Explorer)”,运行 EzPDB.Tests 下的用例(需要已安装 Google Test Adapter)

当前测试用例基于 GoogleTest,默认“离线可运行”(不依赖符号下载),主要覆盖未初始化调用、无效目标文件、close() 幂等等路径。

如果你是通过 NuGet 安装的 Microsoft.googletest.*(例如 EzPDB.Tests\\packages.config),不需要手工填写 gtest*.lib 路径;确保已执行过 NuGet 程序包还原,且仓库根目录存在 packages/