Post

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.

Inside the Xhorse XT136 Super Chip

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.

 xt27axt136
Family query and reply0x072F → 0xC8F6B6380xE20E → 0x604A027E
Seed query and reply0x7372 → 0x50xx..0x6Bxx0xE430 → 0x9BF2..0x9BF7
Seedbitrev16(reply) ^ 0xE12Ebitrev16(reply) ^ 0x8C07
First encrypted commandalways sel bank 1 (0x41BE)none fixed: ctl 0x3F, ctl 0x30 or WRITE 0x00
Memorytwo banks, selected with selone 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:

  1. Identify, just ctl 0x3F again.
  2. Config words. Three ctl 0x30, 0x31 and 0x32 commands, each followed by a 32 bit data word and a read-back. These land in pages 0x0D, 0x0E and 0x0F.
  3. 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, then READ p to 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)

PageReset valueMeaning
0x0064B55D12the HITAG2 UID
0x01..0x024D494B52, 00004F4Ethe HITAG2 password, “MIKR” and “ON”
0x0306AA4854the HITAG2 config page
0x04..0x0700000000HITAG2 user pages
0x08..0x0C00000018, 00282010, 00004141, 28148389, 55555555unknown, not visible through a HITAG2 read
0x0D0000000Econfig word 0 (ctl 0x30)
0x0E361818CAconfig word 1 (ctl 0x31). The top byte 0x36 matches the xt27a’s ID46 type byte
0x0F56781234config 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 0xAF62 sent after the unanswered 0x072F, and the 8 bit 0xF0 probe, are the same in every trace but are still unidentified. (0xAF62 is 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).

This post is licensed under CC BY 4.0 by the author.