ZDMA / LeechCore Integration Guide

Tutorials › ZDMA / LeechCore Integration Guide

How to Integrate ZDMA / LeechCore into Your Own Project

This guide is for ZDMA developers who want to integrate LeechCore into their own Windows software. It covers user-mode software integration and application distribution only. It does not include firmware flashing, JTAG, cabling, kernel driver installation, or any other hardware procedure.

1. Version Requirements

Check versions before writing code. Most integration issues come from mixing DLLs from different releases or placing dependent files in the wrong directory.

  • leechcore.dll and leechcore_driver.dll must come from the same release. Do not mix old and new versions.
  • If you use MemProcFS vmm.dll for process-level parsing, its version must match leechcore.dll.
  • FTD3XX.dll is the official FTDI 64-bit DLL. It is required for FT601 / USB3 boards. ZDMA uses Thunderbolt with its own driver.
  • ZDMA new firmware v4.17 / FPGA1 v4+ requires the latest leechcore.dll.
  • Practical recommendation: download the three DLLs from the same release and upgrade them together. Before running your own application, use pcileech.exe -device fpga probe to verify version alignment and connectivity.

2. User-Mode DLLs You Need

File Required Notes
leechcore.dll + leechcore_driver.dll Required Both files must come from the same release.
vmm.dll Optional Use it only when you need process-level or virtual-address reads. Its version must match leechcore.dll.
FTD3XX.dll Device-dependent Required only for FT601 boards. It is normally not needed for ZDMA Thunderbolt usage.

3. Method 1: Place the DLLs Next to Your exe

This is the simplest method and the recommended approach during development or for internal tools.

Release Directory Layout

your_app/
├─ your_app.exe
├─ leechcore.dll
├─ leechcore_driver.dll
├─ vmm.dll              optional
└─ FTD3XX.dll           only required for FT601 boards

When a Windows application starts, Windows searches for DLLs in the executable directory. Put your_app.exe, leechcore.dll, leechcore_driver.dll, (vmm.dll), and (FTD3XX.dll) in the same folder.

Minimal C/C++ Example

#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");

    // The device string may include parameters:
    // 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 OK\n");
    }

    // Write example, if your project needs it:
    // LcWrite(h, pa, cb, pb);

    // For high-throughput reads, use scatter reads:
    // LcReadScatter(h, ...);

    LcClose(h);
    return 0;
}

Reading Virtual Memory by Process

If your project needs to read virtual memory by process, add vmm.dll on top of LeechCore: initialize with VMMDLL_Initialize(-device fpga), then read with VMMDLL_MemRead.

// Pseudocode: integration flow
LPSTR argv[] = {
    "your_app.exe",
    "-device",
    "fpga"
};

VMM_HANDLE hVMM = VMMDLL_Initialize(3, argv);
if (!hVMM) {
    // Check whether vmm.dll and leechcore.dll are version-aligned.
}

DWORD pid = 1234;
QWORD va = 0x7ff600001000;
BYTE pb[0x1000] = {0};

VMMDLL_MemRead(hVMM, pid, va, pb, sizeof(pb));

4. Method 2: Package All DLLs into a Single exe

Key point: LeechCore is distributed as prebuilt DLLs only. There is no static library. Therefore, “single-file distribution” means embedding the DLLs as resources inside your exe, extracting them at runtime, and then loading them.

Route A: Embed DLL Resources → Extract at Startup → SetDllDirectory → LoadLibrary (Recommended)

  1. Embed leechcore.dll and leechcore_driver.dll as resources in your exe.
  2. Create a temporary directory when the application starts.
  3. Extract both DLLs into the same temporary directory.
  4. Call SetDllDirectory with that directory.
  5. Call LoadLibrary to load leechcore.dll.
// Pseudocode: required loading order
wchar_t dllDir[MAX_PATH] = L"C:\\Users\\...\\AppData\\Local\\Temp\\your_app_lc";

// Extract both DLLs from resources into the same directory:
// dllDir\\leechcore.dll
// dllDir\\leechcore_driver.dll

SetDllDirectoryW(dllDir);

HMODULE hLeechCore = LoadLibraryW(L"leechcore.dll");
if (!hLeechCore) {
    // Check extraction, directory placement, and version alignment.
}

// FARPROC pLcCreate = GetProcAddress(hLeechCore, "LcCreate");
// FARPROC pLcRead   = GetProcAddress(hLeechCore, "LcRead");

The version rule does not change: the two DLLs embedded into the exe must still come from the same release.

Route B: MemoryModule-Style In-Memory Loading (Pitfall)

Some projects try to load DLLs directly from memory with MemoryModule-style loaders. This is fragile here because leechcore.dll will still call LoadLibrary to load the driver DLL. That second-level dependency often fails in pure in-memory loading setups. In real projects, use Route A instead.

Single-File Options by Language

Language / Platform Recommended Approach
C/C++ Put DLLs into .rc resources → extract with FindResource → load with LoadLibrary.
C#/.NET Use <PublishSingleFile>true + <IncludeNativeLibrariesForSelfExtract>true, or use Costura.Fody.
Rust Use include_bytes! → write the DLLs to disk → load with libloading::Library::new.
Python Use pyinstaller --onefile --add-binary "leechcore.dll;.", and make sure all related DLLs are included.

5. Verification and Troubleshooting

Recommended Verification Order

pcileech.exe -device fpga probe
pcileech.exe -device fpga display -min 0x1000 -max 0x2000
Symptom Common Cause Suggested Fix
LcCreate returns NULL, or probe detects no device DLL versions do not match. Download leechcore.dll and leechcore_driver.dll again from the same release. If you use vmm.dll, update it together.
Reads return all 0xFF IOMMU / VT-d is blocking DMA. Disable IOMMU / VT-d in BIOS and verify again.
leechcore_driver.dll cannot be found In single-file mode, the second-level dependency was not extracted to the same directory. Extract both DLLs to the same directory and call SetDllDirectory before loading.

6. Comparison

Method Advantages Limitations Best For
DLLs next to exe Simple integration, easy debugging, DLLs can be replaced or upgraded individually. The release folder contains multiple files. Development and internal tools.
Single exe Clean distribution, one portable executable. DLL upgrades require repackaging the exe. External delivery.

Recommended workflow: During development, use the “DLLs next to exe” layout and confirm that probe works. For external delivery, switch to the single-file Route A. Always keep the LeechCore DLL pair from the same release.

References

Scroll to Top