# NFCGate: an Android NFC capture and relay toolkit that depends on a hooking framework for most of its modes

> Built by a university security lab, this app captures, relays, replays and clones NFC traffic from a phone, exports it as pcapng, and spends most of its documentation explaining which cards and readers it cannot handle.

**nfcgate/nfcgate** — An NFC research toolkit application for Android

- Repository: https://github.com/nfcgate/nfcgate
- Stars: 2,391 · Forks: 274
- Language: Java
- License: Apache-2.0
- Published: 2026-10-07 · Updated: 2026-10-07 · Language: en
- Canonical page: https://hysenlabs.com/projects/nfcgate-nfcgate

## Four modes, four different sets of prerequisites

NFCGate is an Android application for capturing, analysing or modifying NFC traffic, described in the README as a research tool for reverse engineering protocols or assessing their security against traffic modification. It was developed for security research purposes by students of the Secure Mobile Networking Lab at TU Darmstadt.

Four modes are documented, each with its own instructions in its own file under `doc/mode/`: on-device capture, relay, replay and clone. What separates them is not the UI but the mechanism.

On-device capture records NFC traffic sent and received by other applications on the device. Relay forwards traffic between two devices through a separate server project, with one device acting as a reader reading a physical tag and the other emulating a tag using Host Card Emulation. Replay resends previously captured traffic in either reader or tag mode. Clone copies the initial tag information, for example the tag ID.

The base requirements are modest: NFC support, Android 5 or later at API level 21 or higher, and Host Card Emulation for the modes that need it. The catch is in the second tier.

| Requirement | Applies to |
|---|---|
| Xposed-compatible hooking framework (EdXposed, or LSPosed with Zygisk or Riru) | on-device capture, relay tag mode, replay tag mode, clone mode |
| ARMv8-A or ARMv7 | relay tag mode, replay tag mode, clone mode |
| Host Card Emulation | relay tag mode, replay tag mode, clone mode |

That table is the single most useful thing in the README. Three of the four modes need a hooking framework, which on a modern device means a rooted or repatched system, and there is no version of this tool that captures other applications' traffic without one.

## Interception happens in another process, which is why Xposed is required

The architecture explains the dependency. Capturing another application's NFC traffic means hooking the system NFC service, which lives in a different process from the app doing the capturing. The README is direct about this: on-device capture, relay tag mode, replay tag mode and clone mode all require an Xposed-compatible framework, naming EdXposed and LSPosed with Zygisk or Riru as the supported options.

The mode that does not need a framework is the reader side of relay, which makes sense. Acting as a reader means talking to a tag the phone can see, so no interception of another process is involved.

For anyone evaluating this, the practical consequence is that NFCGate is not an F-Droid-and-go app. The F-Droid listing is real, at the package id `de.tu_darmstadt.seemoo.nfcgate`, but installing it does not give you capture mode on a stock device. The in-app status check exists precisely because of this, and the README points to a compatibility document for further notes rather than pretending the matrix is complete.

The default branch of the repository is `v2`, which is unusual and worth knowing before you clone. It matches the release line, since current releases are v2.5.0, v2.6.0 and v2.6.1, so `v2` is where the current work lives rather than being an unusual branch name to work around. The repository has 2,391 stars, 274 forks, 12 open issues and a last push on 2026-07-20.

## Where the Android NFC stack stops it

The Known Issues and Caveats section is longer than the Features section, and it is the more useful half of the README.

Card support is the first limit. NFCGate can only proxy tags that Android supports, and the README gives a concrete example: Android no longer offers support for MiFare Classic chips, so those cards are out. At the moment every tag technology supported by Android's HCE is handled, which is A, B and F, but NFC-B and NFC-F remain untested. NFC-A is called out as the most common, naming both MiFare DESFire and the chips used in electronic passports, while warning that other tags may cause problems. The recommended diagnostic is to check tag compatibility with an NFC tag info application before trying.

The HCE stack itself has a requirement. Modes that use it need the phone to implement the NFC Controller Interface specification, which most phones offering HCE do. The v2.6.0 release added ATS parsing and emulation with NCI value visualisation in the interface, which is exactly the layer where that specification matters.

There is also a physical limit that no software fixes. The README reports cases where the NFC field generated by the phone was not strong enough to power the cryptographic operations in more advanced chips, since the phone is emulating rather than presenting a real card. If you are testing a chip nobody has tried before, this is the failure mode to expect.

One documented workaround arrived in v2.6.0 as well: a preference for a variable presence-check interval, added to improve tag connection reliability. That is the kind of fix that only appears after real hardware testing, alongside another for TB1 nibble swapping to work around a quirk in some NFC stacks.

## Why relay mode fails against a secure reader

Relay mode moves a card's responses through a network to another device, and that architecture has an inherent weakness the README states plainly: it only works with readers that implement no additional security measures.

The specific measure that breaks it is timing. A reader that checks how long the card takes to respond will reject the proxied reply, because the network transmission adds a noticeable delay to every transaction. The more general name for the same defence is distance bounding. Any reader implementing either will refuse the proxied responses, and no amount of tuning on the NFCGate side changes that, since the delay is inherent to forwarding over a network.

The README is careful to note this does not affect the other operating modes, which is correct. Capture, replay and clone do not insert a network hop into a live transaction.

Confidentiality on the relay channel is a separate concern, and it is configurable. The README recommends Transport Layer Security, which can be enabled in settings, and requires either a CA-issued or a self-signed certificate. Certificates from system-trusted CAs are trusted automatically; self-signed ones can be trusted by the user on first use, which is the trust-on-first-use model. For a research setup that is the right trade-off, and for anything else it is not, since anyone who can reach the relay server sees the traffic unless TLS is on.

The relay server is a separate repository, `nfcgate/server`, rather than something bundled here. That separation keeps this project focused on the phone side, but it means a relay setup involves two builds and a deployment decision of its own.

## pcapng export, releases and a false malware positive

The export path is the feature that makes this useful to people who are not Android specialists. Captured traffic can be exported to and imported from the pcapng file format, and Wireshark can read it, with the detailed import and export behaviour documented in `doc/pcapng.md`. Once traffic is in pcapng, existing protocol analysis tooling applies, which is the point of a research tool with a capture mode.

Building requires submodules and either Android Studio or Gradle:

```bash
git submodule update --init
```

The tree explains the structure: `app/` for the application, `nfcd/` for the NFC daemon side, `common/` for shared code, `protobuf/` for the wire format, `doc/` for the per-mode documentation, `fastlane/` for release automation, and `chore/` alongside `build.gradle` and `settings.gradle` for the build.

The release history shows the cost of hooking into system services. v2.5.0, released 2025-06-14, had to fix compatibility with Android 15 and later caused by new linker namespace restrictions, allow delayed native hook installation to improve LG device compatibility, improve NFC library detection to avoid hooking the wrong library, and fix an ARMv7 bug in ELF file parsing. It also added an informational message for unsupported tag types such as Mifare Classic and Ultralight, and refactored the native hooking architecture for stability. v2.6.0 in May 2026 added Android 16 support, fixed 16KiB page size handling, and fixed a large capture data transfer problem between hook and app.

One practical warning belongs at the top of any evaluation: the README states that NFCGate is currently being falsely detected as NGate malware, with a tracking issue for current information. If you hit an antivirus warning on an APK you downloaded from here, that is the explanation.

## Conclusion

NFCGate is a research instrument rather than a general NFC tool, and the requirements table is the document to read first. Three of its four modes need LSPosed or EdXposed, and the relay mode fails against any reader that times responses, which excludes most payment terminals. What it gives you in exchange is a full transaction log in pcapng form that Wireshark reads directly, which is the thing that makes protocol reverse engineering tractable on a phone. Start with the on-device capture mode, which has the fewest prerequisites, and read the compatibility document before assuming a card will work.

## FAQ

### Do I need root or a hooking framework to use NFCGate?

For most modes, yes. On-device capture, relay tag mode, replay tag mode and clone mode all require an Xposed-compatible hooking framework such as EdXposed, or LSPosed with Zygisk or Riru. The reader side of relay is the exception, and the app's in-app status check exists to report compatibility.

### Which NFC cards does NFCGate support?

Only tags that Android itself supports. MiFare Classic is explicitly out because Android no longer supports it. Every technology in Android's HCE set is handled, which is A, B and F, though NFC-B and NFC-F remain untested, and NFC-A is the most commonly supported with MiFare DESFire and e-passport chips named as examples.

### Why does relay mode fail with payment terminals and some card readers?

Relay forwards responses over a network, which adds measurable delay. Readers that check response timing, or that implement distance bounding, reject the proxied replies because the latency is too high. The README notes this does not affect capture, replay or clone modes.

### How do I build NFCGate from source?

Initialise the git submodules, then build with Android Studio or Gradle. The repository's default branch is v2, matching the current release line, and the mode-specific instructions live in separate files under doc/mode rather than in the README.

## Sources

- [Issues](https://github.com/nfcgate/nfcgate/issues)
- [License: Apache-2.0](https://github.com/nfcgate/nfcgate/blob/v2/LICENSE)
- [nfcgate/nfcgate on GitHub](https://github.com/nfcgate/nfcgate)
- [README](https://github.com/nfcgate/nfcgate/blob/v2/README.md)
- [Releases](https://github.com/nfcgate/nfcgate/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/nfcgate-nfcgate
