Inside the Xhorse XT136 Super Chip
Sniffing a VVDI mini programmer as it resets the ID on an Xhorse XT136 super chip, and decoding what it says.
The XT136
After the post about the xt27a chip a few days ago I got hold of a second Xhorse super chip, the xt136, and captured the VVDI mini reading and resetting it. It turns out to be a close relative of the xt27a: same channel A, same LFSR, same op, ~op commands. Only the way the chip is detected, the seed constant and the memory layout differ. Load the two xt136 recordings from the drop-down in the second viewer to follow along.
This is a first look. It is decoded from six VVDI mini captures of two physical chips and has not yet been driven from a proxmark, so treat it with the same caution as the “inferred” items in the xt27a post.
Fig. 1 - Sniffed VVDI → XT136 session resetting the tag. Click a box (or a row in the table) for the decoded meaning. Encrypted messages show the ciphertext on the air and the plaintext recovered with the session keystream.
Telling the two chips apart
After XHORSE and 0x5AA5 the reader has to find out which family it is talking to, and it does that by asking each family’s own question in turn. The VVDI mini asks the xt27a question (0x072F) first. An xt136 does not answer it, so the reader turns the field off, powers up again, sends XHORSE again and asks the xt136 question instead.
| xt27a | xt136 | |
|---|---|---|
| Family query and reply | 0x072F → 0xC8F6B638 | 0xE20E → 0x604A027E |
| Seed query and reply | 0x7372 → 0x50xx..0x6Bxx | 0xE430 → 0x9BF2..0x9BF7 |
| Seed | bitrev16(reply) ^ 0xE12E | bitrev16(reply) ^ 0x8C07 |
| First encrypted command | always sel bank 1 (0x41BE) | none fixed: ctl 0x3F, ctl 0x30 or WRITE 0x00 |
| Memory | two banks, selected with sel | one flat page space, no sel seen |
The signature replies are constants: 0x604A027E came back in all test sessions, from two test chips, just as 0xC8F6B638 does for the xt27a. The seed replies of the two chips overlap, which fits a timing counter again rather than anything chip specific. The updated decoder uses this to pick the right seed constant, so the viewer above decrypts an xt136 session just like an xt27a one.
The seed constant was found by brute force. In the test read captures there were 26 reader commands in one session, and only one of the 65,536 possible seeds makde all 26 decrypt to valid op, ~op pairs. That seed is bitrev16(reply) ^ 0x8C07. The same constant also decrypts the other sessions, and every read-back decrypts to exactly the data that was just written.
1
2
3
4
5
6
7
8
9
10
reader (VVDI mini) chip (XT136)
-----------------------------------------------------------------------------
"XHORSE" (48 bits, ASCII) ------>
<------ 0x5AA5
0xE20E (16 bits) ------>
<------ 0x604A027E (32 bits) family constant
~90 T0 gap (0.7 ms)
0xE430 (16 bits) ------>
<------ 0x9BF3 (16 bits) timing counter = session seed
-------------------------- everything from here on is XORed with the LFSR keystream --------------
What the VVDI mini does
A read is an ordinary HITAG2 read (which is where the VVDI mini gets “type 46” from), followed by the probing described above, and then one encrypted frame: ctl 0x3F. It does not wait for a reply and turns the field off about 450 T0 later. The chip’s 16-byte ID is never read, so I don’t know if it has one.
A reset is three encrypted sessions, each starting with the field off for 130 ms and XHORSE 220 ms after power-up:
- Identify, just
ctl 0x3Fagain. - Config words. Three
ctl 0x30,0x31and0x32commands, each followed by a 32 bit data word and a read-back. These land in pages0x0D,0x0Eand0x0F. - The HITAG2 image (pages
0x00..0x0C). For each page:WRITE p(the chip echoes the command), the data, a 12.8 ms wait for the EEPROM, thenREAD pto verify.
So ctl 0x3n plus data is the config-word write on both families. On the xt27a it writes bank 1 pages 0x3D and 0x3E, on the xt136 pages 0x0D to 0x0F. Note that the echo of a ctl is ~op, op (swapped) while the echo of a WRITE is a straight copy.
The page map (as far as known)
| Page | Reset value | Meaning |
|---|---|---|
0x00 | 64B55D12 | the HITAG2 UID |
0x01..0x02 | 4D494B52, 00004F4E | the HITAG2 password, “MIKR” and “ON” |
0x03 | 06AA4854 | the HITAG2 config page |
0x04..0x07 | 00000000 | HITAG2 user pages |
0x08..0x0C | 00000018, 00282010, 00004141, 28148389, 55555555 | unknown, not visible through a HITAG2 read |
0x0D | 0000000E | config word 0 (ctl 0x30) |
0x0E | 361818CA | config word 1 (ctl 0x31). The top byte 0x36 matches the xt27a’s ID46 type byte |
0x0F | 56781234 | config word 2 (ctl 0x32) |
Pages above 0x0F were never accessed, so I don’t know whether they exist. Pages 0x00 to 0x07 are what a HITAG2 reader sees: after the reset, the UID the chip reports really is 64B55D12 in the “read after reset” capture.
Still unknown for the xt136
- What do pages
0x08..0x0C(00000018,00282010,00004141,28148389,55555555) do? The VVDI mini writes them on a reset, but a HITAG2 read never shows them. - Are there pages above
0x0F, and is there a unique chip ID somewhere? - The 16 bit frame
0xAF62sent after the unanswered0x072F, and the 8 bit0xF0probe, are the same in every trace but are still unidentified. (0xAF62is sent with no start pulse, straight after the field comes back on, so an early version of the decoder lost its first bit and showed it as a 15 bit value. The decoder now times that first bit from the field return.)
Viewer: viewer.js · decoder: decoder.js (written by claude and public domain help yourself).