尧图精选

Windows 驱动实例分析系列:libwdi 驱动分析 - libwdi 篇(二)

🕒 发布时间:2026/10/2 2:18:51 📁 来源:尧图网络
子文档二资源嵌入模块embedder资源嵌入模块是 libwdi“单库全嵌入”策略的技术基石。它将所有外部依赖文件转换为 C 语言数组最终编译进库文件中使库在运行时无需任何外部文件即可工作。该模块由embedder.c、embedder.h和embedder_files.h三个文件组成在构建过程中作为预编译步骤执行。设计目标消除文件依赖无需在安装包中包含驱动 .sys、.dll、.inf 模板等文件。版本一致性库版本与嵌入的驱动版本绑定避免文件版本不匹配问题。简化部署最终应用程序只需分发 libwdi 库或静态链接即可。工作原理embedder是一个独立的可执行程序在构建时编译并运行其主要流程如下读取文件清单embedder_files.h中定义了一个全局结构体数组embeddable_fixed[]每个元素包含文件路径、提取子目录和“重用”标志。该清单列出了需要嵌入的所有文件包括WinUSB 协安装器WdfCoInstaller*.dll、winusbcoinstaller2.dlllibusb0 驱动libusb0.sys、libusb0.dll、install-filter.exelibusbK 驱动libusbK.sys、libusbK.dll各架构的安装器可执行文件installer_x86.exe、installer_x64.exe、installer_arm64.exeINF 模板winusb.inf.in、libusb0.inf.in、libusbk.inf.in、usbser.inf.inCAT 模板winusb.cat.in、libusb0.cat.in、libusbk.cat.in、usbser.cat.in支持用户自定义文件若在编译时定义了USER_DIR宏embedder会扫描该目录及其子目录将所有文件也纳入嵌入列表。这允许开发者嵌入自己签名的 INF 和 CAT 文件。文件读取与转换对于每个文件embedder使用fopen或_wfopen以二进制方式打开读取全部内容然后输出为 C 数组字面量constunsignedcharfile_000[]{0x4D,0x5A,0x90,0x00,...};生成索引表同时记录每个文件的提取子目录、文件名、大小和创建时间戳生成一个struct res resource[]数组供libwdi.c通过nb_resources和resource[i]访问。增量构建embedder会检查目标embedded.h的时间戳若所有源文件均未修改则跳过生成避免不必要的重建。关键实现细节路径处理get_full_path函数将相对路径转换为绝对路径并统一使用 Windows 风格反斜杠。目录扫描当启用USER_DIR时scan_dir递归遍历用户目录收集所有文件及其相对路径。重用标志reuse_last字段允许将同一文件在不同架构下重复使用例如 libusb0.dll 在 x86 和 x64 下对应不同文件但可以通过重用减少存储。跨平台支持embedder.c使用条件编译在 Windows 下使用FindFirstFile在 Linux 下使用opendir/readdir保证在交叉编译环境中也能运行。嵌入资源的使用在libwdi.c中通过全局变量nb_resources和resource[]访问嵌入资源。例如extract_binaries函数遍历所有资源将resource[i].data写入到目标目录的resource[i].subdir/resource[i].name文件中。wdi_tokenize_resource则根据资源名称查找对应的 INF 或 CAT 模板将其内容传递给令牌引擎进行替换。优点与局限性优点彻底消除了文件分发困扰。资源访问速度快直接从内存读取。防篡改只读数据段。局限性库体积较大约 200KB取决于嵌入的驱动数量。更新驱动版本需要重新编译库。对于需要频繁更新驱动签名的场景如 WHQL 认证自签名方式可能不够灵活但 libwdi 提供了USER_DIR让用户嵌入自己的签名文件。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →