docs: correct the T5577 block-order finding — MAXBLK=1 test is the decisive one
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 <noreply@anthropic.com>
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user