|
| 1 | +# 125KHz RFID/ID EM USB IC Card Reader Writer Copier Duplicator |
| 2 | + |
| 3 | +Analysis of a cheap RFID reader I got from Ebay. |
| 4 | + |
| 5 | +## Initial analysis |
| 6 | +- `lsusb` identifies it as `1a86:dd01 QinHeng Electronics`. |
| 7 | +- Searched online for cheap RFID readers, found: |
| 8 | +<https://gist.github.com/pgaultier/b870578515a18becc39ce4501a751574> |
| 9 | + - The gist said that the reader had a "CH341 USB / Serial Chip". I don't |
| 10 | + know what that is, have very less experience in hardware stuff. |
| 11 | + - The gist also had some messages for hello, read and write. |
| 12 | + - Didn't try the driver mentioned in the gist though. |
| 13 | + - I also found |
| 14 | + https://github.com/adrianmihalko/ch340g-ch34g-ch34x-mac-os-x-driver which |
| 15 | + said that for newer Mac OS you don't need the OEM drivers. |
| 16 | +- Opened the cover and found that the one I had with me had "CH552T" chip. |
| 17 | +- Searching for the chip, I found |
| 18 | +<https://github.com/MarsTechHAN/ch552tool/blob/master/ch55xtool.py>, to flash |
| 19 | +firmware on it. I used to code for references. |
| 20 | + - Tried the device identification code. It didn't provide the required |
| 21 | + response. Maybe the device is in some other mode. |
| 22 | + - Note: I ran pyusb on Linux VMware with USB forwarded because Mac OS didn't |
| 23 | + allow easy access to the HID interface. Maybe when the protocol is figured |
| 24 | + out, I can try hidapi (it has python bidnings) to try and connect from MacOS. |
| 25 | + |
| 26 | +- Found "USB Serial for Android" app. It had a connection profile for ch340, which |
| 27 | +was able to establish connection but erred out on some handshake profile. |
| 28 | + - Downloaded <https://github.com/mik3y/usb-serial-for-android> and looked at |
| 29 | + the code in `Ch34xSerialDriver` class. It has some control in, control out for |
| 30 | + init. When I reproduced the first one, it didn't work as expected. |
| 31 | +- Used chrome translate to reach <http://www.wch.cn/downloads/CH552EVT_ZIP.html> |
| 32 | +which lists some header files. The description also said about `CH554EVT.ZIP` |
| 33 | +which contains examples. |
| 34 | + - CH554EVT.ZIP had many C code, but a lot of them had comments in Chinese |
| 35 | + language. Used Google translate to read them. |
| 36 | + |
| 37 | +- Imaged the disk provided on another laptop and transferred the file here. Found |
| 38 | +the DLL file with protocol. |
| 39 | + - Tried to imitate the protocol with pyusb, didn't work. |
| 40 | + - Ran it with Wireshark USB capture to iron out the details that I counldn't |
| 41 | + infer from the DLL, like all packets start with 0x01, and are 64 byte sized. |
| 42 | + The unused data is filled with 0xCC. |
| 43 | + - running in Windows VM, I couldn't get any HID Prox cards to read, so couldn't |
| 44 | + test the read/write opcodes. |
| 45 | + - Was able to write to one of the cards provided with the reader and then read |
| 46 | + back using pysub or hidapi to connect to the device. |
| 47 | + |
| 48 | +## Protocol |
| 49 | +- All packets are 64 byte sized, input & output. Maybe larger data will require |
| 50 | +more packets, will cross the bridge when we need that. |
| 51 | +- the payload are structured like: |
| 52 | +``` |
| 53 | + 0xAA 0x55 0xWW 0xWW 0xOP 0xOP 0xPL 0xPL [payload in hex] 0xCX |
| 54 | +``` |
| 55 | +where: |
| 56 | + - `0xAA 0x55` is the header. |
| 57 | + - `0xWW 0xWW` represents some data that I always have found to be 0 in request |
| 58 | + and 0x1112 in response. |
| 59 | + - `0xOP 0xOP` represents the opcode in big endian. |
| 60 | + - `0xPL 0xPL` represents the payload length in big endian. |
| 61 | + - `[payload]` represents the payload. |
| 62 | + - `0xCX` represents the XOR of all the bytes excluding the header bytes. |
| 63 | + - Any occurrence of by `0xAA` except in header is escaped as `0xAA 0x00`. |
| 64 | + |
| 65 | +- Each packet is 64 bytes and starts with `0x01` followed by 63 bytes of payload |
| 66 | +data. Any unused bytes in the packet is filled with 0xCC. |
| 67 | +- The opcodes are as follows: |
| 68 | +``` |
| 69 | +OPCODE_SET_AUTOREAD = 0x801 # one byte payload, always found to be 0 |
| 70 | +OPCODE_SET_LED = 0x802 # one byte payload, 2 = green, anything else is red |
| 71 | +OPCODE_GET_FREQUENCY = 0x805 # no payload |
| 72 | +OPCODE_GET_MODEL = 0x806 # no payload |
| 73 | +OPCODE_GET_NUMBER = 0x808 # no payload |
| 74 | +OPCODE_READ_ID_CARD = 0x809 # no payload |
| 75 | +OPCODE_WRITE_EL4100 = 0x810 # 5 byte payload, data to be written |
| 76 | +OPCODE_WRITE_T4100 = 0x811 # 6 byte payload, first is 0 or 1, rest is data to be |
| 77 | +written. Maybe the first byte is to lock the card or not |
| 78 | +OPCODE_WRITE_E4100 = 0x812 # 6 byte payload, first is 0 or 1, rest is data to be written |
| 79 | +``` |
| 80 | + |
| 81 | +## Working with cards: |
| 82 | +- The device I had was not able to read HID cards. |
| 83 | +- The cards that came with the device were able to be written using |
| 84 | +`OPCODE_WRITE_T4100`. |
0 commit comments