教程 › ZDMA / LeechCore 集成指南
如何将 ZDMA / LeechCore 集成到自己的项目
本指南面向希望在自己的 Windows 软件中集成 LeechCore 的 ZDMA 开发者,仅涵盖用户态软件集成与应用分发,不包含固件刷写、JTAG、连线、内核驱动安装等任何硬件操作。
1. 版本要求
写代码之前先核对版本。绝大多数集成问题都源于混用不同 release 的 DLL,或把依赖文件放错目录。
leechcore.dll与leechcore_driver.dll必须来自同一个 release,不要新旧混用。- 如果使用 MemProcFS 的
vmm.dll做进程级解析,其版本必须与leechcore.dll匹配。 FTD3XX.dll是 FTDI 官方 64 位 DLL,仅 FT601 / USB3 板卡需要。ZDMA 使用 Thunderbolt 及其专用驱动。- ZDMA 新固件 v4.17 / FPGA1 v4+ 需要最新版
leechcore.dll。 - 实用建议:从同一个 release 下载三个 DLL 并一起升级。运行自己的应用之前,先用
pcileech.exe -device fpga probe验证版本对齐与连通性。
合法使用 / 免责声明
本产品仅可用于合法的内存取证、安全研究、经授权的渗透测试和调试。您只能在自己拥有的设备,或已取得书面授权的设备上使用本产品。禁止未经授权访问第三方系统。您必须遵守所有适用的当地法律,并对自己的使用行为承担全部责任。本产品按”现状”提供,LightningZ 对滥用行为不承担责任。
2. 所需的用户态 DLL
| 文件 | 是否必需 | 说明 |
|---|---|---|
leechcore.dll + leechcore_driver.dll |
必需 | 两个文件必须来自同一个 release。 |
vmm.dll |
可选 | 仅在需要进程级或虚拟地址读取时使用,版本必须与 leechcore.dll 匹配。 |
FTD3XX.dll |
视设备而定 | 仅 FT601 板卡需要。ZDMA Thunderbolt 用法通常不需要。 |
3. 方式一:DLL 与 exe 放在同一目录
这是最简单的方式,推荐在开发阶段或内部工具中使用。
发布目录结构
your_app/
├─ your_app.exe
├─ leechcore.dll
├─ leechcore_driver.dll
├─ vmm.dll 可选
└─ FTD3XX.dll 仅 FT601 板卡需要
Windows 应用启动时会在可执行文件目录中搜索 DLL。将 your_app.exe、leechcore.dll、leechcore_driver.dll、(vmm.dll)、(FTD3XX.dll) 放在同一文件夹即可。
C/C++ 最小示例
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "leechcore.h"
int main(void) {
LC_CONFIG cfg = {0};
cfg.dwVersion = LC_CONFIG_VERSION;
strcpy(cfg.szDevice, "fpga");
// 设备字符串可以携带参数:
// strcpy(cfg.szDevice, "fpga://algo=0,tmread=500,pciegen=2");
HANDLE h = LcCreate(&cfg);
if (!h) {
printf("LcCreate failed. Check DLL versions and device availability.n");
return 1;
}
QWORD pa = 0x1000;
DWORD cb = 0x1000;
BYTE pb[0x1000] = {0};
if (LcRead(h, pa, cb, pb)) {
printf("Read OKn");
}
// 如项目需要写入:
// LcWrite(h, pa, cb, pb);
// 高吞吐读取请使用 scatter 读:
// LcReadScatter(h, ...);
LcClose(h);
return 0;
}
按进程读取虚拟内存
如果项目需要按进程读取虚拟内存,在 LeechCore 之上加用 vmm.dll:用 VMMDLL_Initialize(-device fpga) 初始化,然后用 VMMDLL_MemRead 读取。
// 伪代码:集成流程
LPSTR argv[] = {
"your_app.exe",
"-device",
"fpga"
};
VMM_HANDLE hVMM = VMMDLL_Initialize(3, argv);
if (!hVMM) {
// 检查 vmm.dll 与 leechcore.dll 版本是否对齐。
}
DWORD pid = 1234;
QWORD va = 0x7ff600001000;
BYTE pb[0x1000] = {0};
VMMDLL_MemRead(hVMM, pid, va, pb, sizeof(pb));
4. 方式二:把所有 DLL 打包进单个 exe
关键点:LeechCore 仅以预编译 DLL 形式分发,没有静态库。因此”单文件分发”意味着把 DLL 作为资源嵌入 exe,运行时释放后再加载。
路线 A:嵌入 DLL 资源 → 启动时释放 → SetDllDirectory → LoadLibrary(推荐)
- 将
leechcore.dll和leechcore_driver.dll作为资源嵌入 exe。 - 应用启动时创建一个临时目录。
- 把两个 DLL 释放到同一个临时目录。
- 用该目录调用
SetDllDirectory。 - 调用
LoadLibrary加载leechcore.dll。
// 伪代码:必须遵守的加载顺序
wchar_t dllDir[MAX_PATH] = L"C:\Users\...\AppData\Local\Temp\your_app_lc";
// 从资源中把两个 DLL 释放到同一目录:
// dllDir\leechcore.dll
// dllDir\leechcore_driver.dll
SetDllDirectoryW(dllDir);
HMODULE hLeechCore = LoadLibraryW(L"leechcore.dll");
if (!hLeechCore) {
// 检查释放是否成功、目录位置和版本对齐。
}
// FARPROC pLcCreate = GetProcAddress(hLeechCore, "LcCreate");
// FARPROC pLcRead = GetProcAddress(hLeechCore, "LcRead");
版本规则不变:嵌入 exe 的两个 DLL 仍然必须来自同一个 release。
路线 B:MemoryModule 式内存加载(有坑)
有些项目尝试用 MemoryModule 式加载器直接从内存加载 DLL。在这里这种做法很脆弱,因为 leechcore.dll 仍会调用 LoadLibrary 去加载 driver DLL,这个二级依赖在纯内存加载方案中经常失败。实际项目请使用路线 A。
各语言的单文件方案
| 语言 / 平台 | 推荐做法 |
|---|---|
| C/C++ | 把 DLL 放入 .rc 资源 → 用 FindResource 释放 → 用 LoadLibrary 加载。 |
| C#/.NET | 使用 <PublishSingleFile>true + <IncludeNativeLibrariesForSelfExtract>true,或使用 Costura.Fody。 |
| Rust | 用 include_bytes! → 把 DLL 写到磁盘 → 用 libloading::Library::new 加载。 |
| Python | 使用 pyinstaller --onefile --add-binary "leechcore.dll;.",并确保包含所有相关 DLL。 |
5. 验证与排错
推荐验证顺序
pcileech.exe -device fpga probe
pcileech.exe -device fpga display -min 0x1000 -max 0x2000
| 症状 | 常见原因 | 建议处理 |
|---|---|---|
LcCreate 返回 NULL,或 probe 检测不到设备 |
DLL 版本不匹配。 | 从同一个 release 重新下载 leechcore.dll 和 leechcore_driver.dll;如使用 vmm.dll,一并更新。 |
读取结果全为 0xFF |
IOMMU / VT-d 拦截了 DMA。 | 在 BIOS 中关闭 IOMMU / VT-d 后重新验证。 |
找不到 leechcore_driver.dll |
单文件模式下二级依赖没有释放到同一目录。 | 把两个 DLL 释放到同一目录,并在加载前调用 SetDllDirectory。 |
6. 两种方式对比
| 方式 | 优点 | 限制 | 适用场景 |
|---|---|---|---|
| DLL 与 exe 同目录 | 集成简单、易于调试,DLL 可单独替换或升级。 | 发布目录包含多个文件。 | 开发与内部工具。 |
| 单文件 exe | 分发干净,一个可携带的可执行文件。 | 升级 DLL 需要重新打包 exe。 | 对外交付。 |
推荐工作流:开发阶段使用”DLL 与 exe 同目录”布局并确认 probe 可用;对外交付时切换到单文件路线 A。始终保持 LeechCore 的 DLL 成对来自同一个 release。