Skip to content

sercanarga/PCILeechGen

Repository files navigation

PCILeechGen

Custom firmware generator for PCILeech FPGA boards. Reads a real PCI/PCIe
donor device through VFIO, clones its identity (config space, BARs,
capabilities), and builds a ready-to-flash .bin bitstream via Vivado.

Discord Community: https://discord.gg/kcWVCAhNSg

******************************************************************************
* WARNING: FOR EDUCATIONAL AND RESEARCH USE ONLY                             *
*                                                                            *
* This tool is provided for educational and research purposes only. The      *
* authors do not condone cheating, anti-cheat circumvention, or any use that *
* violates terms of service. Users are responsible for compliance with all   *
* applicable laws and agreements.                                            *
******************************************************************************


SPECIAL THANKS
--------------
  Pachi Tactico  Sponsorship
                 https://hypservicesdma.com
  FTWDMA         Sponsorship
                 https://ftwdma.com
  sgorm0         Sponsorship
                 https://github.com/sgorm0
  TrueTuring     Sponsorship, NVMe and xHCI fixes
                 https://github.com/TrueTuring
  CaptainDMA     Sponsorship
                 https://captaindma.com
  pcileech-fpga  The FPGA framework this project builds upon
                 https://github.com/ufrisk/pcileech-fpga


PREREQUISITES
-------------
  - Go 1.26+
  - Linux with IOMMU/VFIO enabled
  - Vivado 2023.2 (for synthesis)

  VFIO needs IOMMU enabled in BIOS and in the kernel parameters
  (intel_iommu=on or amd_iommu=on).


HOW IT WORKS
------------
  scan  ->  check  ->  build  ->  flash

  scan     enumerate PCI devices, detect VFIO status
  check    validate the donor device, read config space and BARs
  build    clone identity -> generate SV/COE/TCL -> Vivado synthesis -> .bin
  flash    write the bitstream to the FPGA board

The donor device is read through VFIO; its config space, BARs and
capabilities are cloned, scrubbed, and compiled into ready-to-flash
firmware. Run the stages in order.


QUICK START
-----------
  git clone --recurse-submodules https://github.com/sercanarga/PCILeechGen.git
  cd PCILeechGen && make build

  sudo ./bin/pcileechgen scan
  sudo ./bin/pcileechgen check --bdf 0000:02:00.0
  sudo ./bin/pcileechgen build --bdf 0000:02:00.0 --board CaptainDMA_100T

  Run "check" before "build" to verify donor and board compatibility.
  Full synthesis takes 30-60 minutes; add --skip-vivado for artifacts only.


COMMANDS
--------
  scan             list PCI devices with VFIO status
  check            validate a donor device (BAR size vs board BRAM)
  build            generate firmware artifacts (+ Vivado)
  validate         verify artifacts match the donor context
  verify-manifest  check SHA256 integrity of build output
  mmio-trace       capture live or import saved BAR MMIO access traces
  boards           list supported FPGA boards
  version          print version

  Common build flags:
    --bdf <addr>       donor device BDF (required)
    --board <name>     target board (required)
    --skip-vivado      artifacts only, no synthesis
    --force            allow donor BAR > board BRAM (may truncate)
    --from-json <f>    offline build from saved device_context.json
    --output <dir>     output directory (default: pcileech_datastore)

  Output directories are ownership-protected. Point --output at a new path;
  later builds may reuse it only when it contains PCILeechGen's generated
  ownership marker. This prevents generated artifacts from overwriting an
  arbitrary existing directory.

  Offline MMIO trace import:
    pcileechgen mmio-trace --trace-file mmiotrace.txt --bar-base 0xf7800000 \
      --bar-index 2 --bar-size 4096 --class-code 0x010802 --json


VMD / INTEL RST HOST PLACEMENT
------------------------------
  The generated endpoint presents as an NVMe controller (PCIe class code
  010802), not an Intel VMD controller. Intel VMD ownership is selected by
  the host BIOS for a specific root port or port group, so the card must sit
  on a VMD-mapped port or adapter path to come up under VMD.

  Requirements for VMD / Intel RST operation:
    - Intel CPU, 11th generation or newer, in the host that holds the card.
    - Intel VMD enabled in BIOS for the physical PCIe port or M.2 adapter
      path used by the card.
    - Matching Intel RST / VMD drivers installed on Windows.

  If Windows lists the board as a generic SCSI or storage controller with no
  NVMe driver, the active bitstream was built with the wrong PCIe class code.
  Keep the endpoint class as 010802 and use a VMD-mapped slot or adapter path.


FEATURES
--------
  Device identity
    - VID/DID/REV, subsystem IDs, class code
    - Device Serial Number (stripped when the donor has none)

  BAR emulation
    - dynamic BAR0 sizing from the donor (capped by board bram_size)
    - 64-bit BAR preservation, power-of-2 rounding
    - MSI-X table placement that avoids NVMe doorbell overlap

  NVMe
    - CC.EN -> CSTS.RDY handshake
    - admin queue responder (Identify, Features, Create IO CQ/SQ)
    - DMA bridge (doorbell + completion)

  Config space
    - 4KB shadow + 17-pass scrubbing pipeline
    - per-register write masks, capability filtering/pruning
    - PCIe cap injection, power-management lock, vendor quirks

  Stealth and timing
    - TLP latency emulation (xorshift128+ CDF reproduction)
    - write-completion emulation, completion timeout
    - ASPM clamping, AER mask normalization, DSN jitter
    - per-build placement randomization, VSEC entropy embed

  Diagnostics
    - VFIO diagnostics, BAR vs BRAM compatibility checks
    - post-build validation, build manifest, config-space diff report


SUPPORTED BOARDS
----------------
  Board             FPGA           Lanes  Form factor
  --------------    -----------    -----  -----------
  CaptainDMA_M2_x1  XC7A35T-325    x1     M.2
  CaptainDMA_M2_x4  XC7A35T-325    x4     M.2
  CaptainDMA_35T    XC7A35T-484    x1     PCIe
  CaptainDMA_75T    XC7A75T-484    x1     PCIe
  CaptainDMA_100T   XC7A100T-484   x1     PCIe
  ScreamerM2        XC7A35T-325    x1     M.2
  pciescreamer      XC7A35T-484    x1     PCIe
  NeTV2_35T         XC7A35T-484    x1     M.2
  NeTV2_100T        XC7A100T-484   x1     M.2
  PCIeSquirrel      XC7A35T-484    x1     PCIe
  EnigmaX1          XC7A75T-484    x1     PCIe
  ZDMA              XC7A100T-484   x4     PCIe
  GBOX              XC7A35T-484    x1     Mini PCIe
  ac701_ft601       XC7A200T-676   x4     Dev Board
  acorn             XC7A200T-484   x4     M.2
  litefury          XC7A100T-484   x4     M.2
  sp605_ft601       XC6SLX45T-484  x1     Dev Board

  Boards with larger bram_size (EnigmaX1=8K, CaptainDMA_75T=16K,
  CaptainDMA_100T / ZDMA / NeTV2_100T / ac701_ft601 / acorn / litefury=32K)
  support larger BAR0 emulation. Run "boards" for the full list.


OUTPUT
------
  pcileech_datastore/
    device_context.json                 donor snapshot
    pcileech_cfgspace.coe               4KB scrubbed config space
    pcileech_cfgspace_writemask.coe     per-register write masks
    pcileech_bar_zero4k.coe             BAR0 content (sized to donor/BRAM)
    pcileech_bar_impl_device.sv         register-level BAR implementation
    pcileech_tlps128_bar_controller.sv  TLP BAR controller
    pcileech_tlp_normalizer.sv           normalized MRd/MWr decode + decisions
    pcileech_tlps128_bar_rdengine.sv     BE/RCB/MPS-aware read completions
    pcileech_tlp_ur_completer.sv        unsupported non-posted completions
    pcileech_msix_table.sv              MSI-X table + PBA
    pcileech_nvme_admin_responder.sv    (if NVMe)
    pcileech_nvme_dma_bridge.sv         (if NVMe)
    tlp_latency_emulator.sv             response latency emulation
    device_config.sv                    identity + feature flags
    config_space_init.hex               config space init ($readmemh)
    msix_table_init.hex                 MSI-X table init ($readmemh)
    identify_init.hex                   NVMe Identify ROM (if NVMe)
    vivado_generate_project.tcl         project creation
    vivado_build.tcl                    synthesis script
    build_manifest.json                 checksums + metadata
    src/                                patched board SV sources
    *.bin                               bitstream (after Vivado)


DEVELOPMENT
-----------
  make test           run all tests
  make test-coverage  tests with coverage report
  make lint           run linter
  make check          vet + lint + test


UTILITIES
---------
Windows device-history cleanup

  After flashing and testing, Windows can cache PCI/USB device metadata in
  the registry. Stale entries from earlier builds can cause conflicts, Code 10
  errors, or driver misidentification. The tools/ directory has an interactive
  cleanup utility:

    cleanup_device_history.bat      double-click launcher (runs as Admin)
    cleanup_device_history.ps1      PowerShell script with an interactive selector

  Usage:
    double-click cleanup_device_history.bat and confirm the UAC prompt, or
    open PowerShell as Administrator and run: .\cleanup_device_history.ps1

  Safety properties:
    - scans only PCI and USB instance keys in dynamically discovered,
      numbered ControlSets; it never acts through CurrentControlSet
    - exports every selected key before mutation; the manifest binds each
      absolute backup path to its byte length and SHA-256 digest
    - on failure, attempts both verified `.reg` re-import and restoration of the
      original DeviceInstall service state, even if service restoration is the
      first error
    - supports PowerShell WhatIf mode with zero writes:

        .\cleanup_device_history.ps1 -WhatIf

    - keeps setupapi/event-log/metadata purging opt-in; that irreversible mode
      always asks for the exact phrase `PURGE DEVICE HISTORY`

  To restore a failed cleanup manually, import each `.reg` file listed in the
  backup directory's `manifest.json` after checking its recorded SHA-256, for
  example:

    reg import "C:\Users\you\Desktop\PCILeechGen-DeviceHistory-YYYYMMDD-HHMMSS-GUID\registry-000.reg"

  Recovery scope: `.reg` export/import preserves registry keys and values, but
  not key ownership, ACLs, or other security descriptors. The optional purge of
  setup logs, event logs, and device metadata is irreversible and is never
  represented by the registry backup.

  Developer safety tests require Windows PowerShell 5.1 and exactly Pester
  5.7.1. CI installs that version side-by-side with Windows' bundled Pester 3.4.

  Requires Administrator privileges. Reboot after cleanup before reconnecting
  the device.


LICENSE
-------
  PolyForm Noncommercial License 1.0.0
  https://github.com/sercanarga/PCILeechGen/blob/main/LICENSE.md

  Unlicensed (fork pcileech-fpga modules)
  https://github.com/sercanarga/pcileech-fpga

About

PCILeech firmware generator tool

Topics

Resources

License

Stars

71 stars

Watchers

5 watching

Forks

Sponsor this project

 

Packages

 
 
 

Contributors