From e3a394859c67aeb57e12602243a57da8f9babeb1 Mon Sep 17 00:00:00 2001 From: michael Date: Thu, 16 Jul 2026 18:27:07 -0700 Subject: [PATCH] =?UTF-8?q?docs:=20correct=20the=20T5577=20block-order=20f?= =?UTF-8?q?inding=20=E2=80=94=20MAXBLK=3D1=20test=20is=20the=20decisive=20?= =?UTF-8?q?one?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The block-3 write-read-back wasn't decisive: writebl and readbl share the address path, so they round-trip regardless of addressing correctness. Since proxmark, Flipper, and pm3py all write the EM4100 header into block 1, ruling out a pm3py 1<->2 read-swap required an addressing-free read. Set MAXBLK=1 so regular-read streams only physical block 1, read it off the air, and it matched READ(1) (non-header BDEF7BC0). Confirmed: the tag is a genuine reverse-order clone, pm3py reads it correctly, no addressing bug. Restored MAXBLK=2. Co-Authored-By: Claude Opus 4.8 --- ...-16-c-client-oracle-and-lf-demod-parity.md | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/plans/2026-07-16-c-client-oracle-and-lf-demod-parity.md b/docs/plans/2026-07-16-c-client-oracle-and-lf-demod-parity.md index eb03beb..48c917a 100644 --- a/docs/plans/2026-07-16-c-client-oracle-and-lf-demod-parity.md +++ b/docs/plans/2026-07-16-c-client-oracle-and-lf-demod-parity.md @@ -68,15 +68,21 @@ write-read-back** — and there is **no read/addressing bug**: firmware sends) reads *only the addressed block*, repetitively. A clean 32-bit repeat in the capture proves block-read mode engaged (the 64-bit emulation stream can't produce one). - `T55xx_SetBits` clocks the address MSB-first; pm3py's `readbl` payload matches the firmware - struct byte-for-byte. Addressing is correct end-to-end. -- **Write-read-back (decisive):** wrote `DEADBEEF` to unused block 3 → `READ(3)` returned - `~DEADBEEF` at **rot 0**, and *only* block 3 changed. So `READ(N)` addresses block N, reads - the right bits, and the only artifact is a **consistent Manchester polarity inversion**. + struct byte-for-byte. Addressing is stock-proxmark, verified end-to-end. +- A block-3 write-read-back was **not** decisive on its own: `writebl` and `readbl` share the + same address path, so they round-trip regardless of whether addressing is correct (it only + proved the demod inverts). Proxmark, Flipper, and pm3py all write the header into block 1, so + the alternative "pm3py reads 1↔2 swapped" had to be excluded with an **addressing-free** read. +- **Decisive test (MAXBLK=1):** temporarily set the config MAXBLK field to 1 (`00148040 → + 00148020`) so regular-read streams *only physical block 1* (datasheet §5.11.1), read it off + the air (no read-command addressing), then restored `00148040`. Physical block 1 came back as + `~BDEF7BC0` — the **non-header** half — matching `READ(1)`. So `READ(1)` == physical block 1. Conclusion: this tag was simply **cloned with the two EM4100 halves in reverse order** -(block 1 = `BDEF7BC0`, block 2 = `FF801EF7`); both orders stream the same cyclic waveform and -read as `00FFFFFFFF`. pm3py reads them correctly. The "wrong" appearance was polarity (inversion) -+ rotation, i.e. the documented "best-effort — bit alignment not verified". +(block 1 = `BDEF7BC0`, block 2 = `FF801EF7`) by a non-proxmark/Flipper/pm3py tool; both orders +stream the same cyclic waveform and read as `00FFFFFFFF`. pm3py reads them correctly. The "wrong" +appearance was polarity (inversion) + rotation, i.e. the documented "best-effort — bit alignment +not verified". **Real improvement (open):** `read_t55xx_block` should *resolve* data-block polarity/rotation instead of leaving it best-effort. Polarity is determinable — read block 0 (config), resolve its