AndBondStyle / niimprint

Python library for Niimbot label printers. Supports D11/B21/B1 via bluetooth or USB.
MIT License
200 stars 29 forks source link

B21: Hack to not waste labels during testing #34

Open etaloncop opened 1 month ago

etaloncop commented 1 month ago

EDIT: Read first. Thanks to findings by @MultiMote it appears the printer itself stores the tag serial number as well. So the methods described bellow are not working.

Been playing with my printer for quite a while and went throught quite a few labels. The printer has a Mifare ultralight tag inside every roll that is read and written with remaining count of labels after every print. The tag only appears to be written only after the print so if the tag is not inside the machine when the print is finished the machine will not reduce the amount of remaining labels. However the tag needs to be present at the time of closing the lid of the machine, otherwise it will print misaligned and defective labels.

The dirty hack

For testing purposes you can insert just a limited number of labels (or even unofficial labels) into the machine without the spool with the tag. when closing the lid place the tag with the spool underneath the machine roughly to the same position where the spool would normally sit inside. Once the machine recognizes the tags remove the spool and continue printing. This needs to be repeated after every reboot or opening of the lid.

Some other info

The tags are mifare ultralight (as already mentioned) with a every strong password of 12345678 (HEX)

here is a dump of my tag before and after printing a label, if anyone feels like reverse engineering the format UID: 1D91AF2B071080 (HEX) Before:

0000000 0000 0000 0000 0000 0000 0f00 0000 0000
0000010 0000 0000 0000 0000 0000 0000 0000 0000
*
0000030 0000 0000 0000 0000 911d abaf 072b 8010
0000040 c0bc 0000 10e1 0012 0301 0ca0 85cc 3eeb
0000050 9436 b79d 9429 8788 08b3 ea54 9b26 6ab4
0000060 44a4 317c 5b10 987d feb4 3dbc beea e8ba
0000070 3412 7856 9f48 98a1                    
0000078

After:

0000000 0000 0000 0000 0000 0000 0f00 0000 0000
0000010 0000 0000 0000 0000 0000 0000 0000 0000
*
0000030 0000 0000 0000 0000 911d abaf 072b 8010
0000040 c0bc 0000 10e1 0012 0301 0ca0 9f74 cd2b
0000050 4a40 f824 9429 8788 08b3 ea54 9b26 6ab4
0000060 44a4 317c 5b10 987d feb4 3dbc beea e8ba
0000070 3412 7856 9f48 98a1                    
0000078

after.json before.json

Enjoy

AndBondStyle commented 1 month ago

I assumed the RFID tags are read-only, and label counting is done on the app's side... Is it completely wrong then? Also linking https://github.com/kjy00302/niimprint/issues/4 as related

etaloncop commented 1 month ago

I cannot say for sure, but the tag is definitely being written after the print. I will attach some logs

This is how the communication looks like when lid is closed (no writes)

      Start |        End | Src | Data (! denotes parity error)                                           | CRC | Annotation
------------+------------+-----+-------------------------------------------------------------------------+-----+--------------------
          0 |        992 | Rdr |52(7)                                                                    |     | WUPA
       2260 |       4628 | Tag |44  00                                                                   |     | 
       7408 |       9872 | Rdr |93  20                                                                   |     | ANTICOLL
      11076 |      16964 | Tag |88  1d  91  af  ab                                                       |     | 
      20592 |      31056 | Rdr |93  70  88  1d  91  af  ab  8c  a5                                       |  ok | SELECT_UID
      32324 |      35844 | Tag |04  da  17                                                               |     | 
      38624 |      41088 | Rdr |95  20                                                                   |     | ANTICOLL-2
      42548 |      48180 | Tag |ca  01  04  20  2f                                                       |     | 
      51680 |      62144 | Rdr |95  70  2b  07  10  80  bc  b3  87                                       |  ok | SELECT_UID-2
      63412 |      66996 | Tag |00  fe  51                                                               |     | 
      69840 |      78064 | Rdr |1b  12  34  56  78  0a  94                                               |  ok | PWD-AUTH KEY: 0x12345678
     101796 |     106404 | Tag |aa  aa  63! 5b                                                           |     | 
     109136 |     113904 | Rdr |30  07  bd  dc                                                           |  ok | READBLOCK(7)
     115108 |     135908 | Tag |29  94  88  87  b3  08  54  ea  26  9b  b4  6a  a4  44  7c  31  08  6a   |  ok | 
     139968 |     144736 | Rdr |30  0b  d1  16                                                           |  ok | READBLOCK(11)
     145940 |     166804 | Tag |10  5b  7d  98  b4  fe  bc  3d  ea  be  ba  e8  bb  22  eb  c9  cb  98   |  ok | 
     170816 |     175520 | Rdr |30  0f  f5  50                                                           |  ok | READBLOCK(15)
     176788 |     197652 | Tag |48  9f  a1  98  2a  30  fe  ba  ea  be  ba  e8  bb  22  eb  c9  bd  f8   |  ok | 
     201648 |     206416 | Rdr |30  13  18  8a                                                           |  ok | READBLOCK(19)
     207620 |     228420 | Tag |94  80  3b  74  3a  8b  64  88  18  5d  7f  ac  33  d3  3d  88  99  06   |  ok | 
     232496 |     237200 | Rdr |30  17  3c  cc                                                           |  ok | READBLOCK(23)
     238468 |     259332 | Tag |55  2f  a7  e6  4a  39  5c  4d  ea  be  ba  e8  bb  22  eb  c9  1c  cd   |  ok | 
     263328 |     268032 | Rdr |30  1b  50  06                                                           |  ok | READBLOCK(27)
     269300 |     290164 | Tag |6d  15  2f  2a  21  a4  eb  e3  db  4b  27  9b  e1  d8  d6  83  a0  97   |  ok | 
     294176 |     298944 | Rdr |30  1f  74  40                                                           |  ok | READBLOCK(31)
     300148 |     320948 | Tag |34  c9  9f  77  44  a0  ec  ac  38  30  fd  9c  f1  0b  98  31  81  a5   |  ok | 
     325136 |     329840 | Rdr |30  05  af  ff                                                           |  ok | READBLOCK(5)
     331108 |     351972 | Tag |e3  09  1a  22  c6  49  6b  96  29  94  88  87  b3  08  54  ea  31  4a   |  ok | 

and this is when printing is completed:

      Start |        End | Src | Data (! denotes parity error)                                           | CRC | Annotation
------------+------------+-----+-------------------------------------------------------------------------+-----+--------------------
          0 |        992 | Rdr |52(7)                                                                    |     | WUPA
       2244 |       4612 | Tag |44  00                                                                   |     | 
       7408 |       9872 | Rdr |93  20                                                                   |     | ANTICOLL
      11060 |      16948 | Tag |88  1d  91  af  ab                                                       |     | 
      20576 |      31040 | Rdr |93  70  88  1d  91  af  ab  8c  a5                                       |  ok | SELECT_UID
      32308 |      35828 | Tag |04  da  17                                                               |     | 
      38624 |      41088 | Rdr |95  20                                                                   |     | ANTICOLL-2
      42276 |      48164 | Tag |2b  07  10  80  bc                                                       |     | 
      51792 |      62256 | Rdr |95  70  2b  07  10  80  bc  b3  87                                       |  ok | SELECT_UID-2
      63508 |      67092 | Tag |00  fe  51                                                               |     | 
      70080 |      78304 | Rdr |1b  12  34  56  78  0a  94                                               |  ok | PWD-AUTH KEY: 0x12345678
     101892 |     106628 | Tag |55  55  c7  b6                                                           |     | 
    2549296 |    2550288 | Rdr |52(7)                                                                    |     | WUPA
    2551540 |    2553908 | Tag |44  00                                                                   |     | 
    2556704 |    2559168 | Rdr |93  20                                                                   |     | ANTICOLL
    2560356 |    2566244 | Tag |88  1d  91  af  ab                                                       |     | 
    2569760 |    2580224 | Rdr |93  70  88  1d  91  af  ab  8c  a5                                       |  ok | SELECT_UID
    2581476 |    2584996 | Tag |04  da  17                                                               |     | 
    2587664 |    2590128 | Rdr |95  20                                                                   |     | ANTICOLL-2
    2591316 |    2597204 | Tag |2b  07  10  80  bc                                                       |     | 
    2600704 |    2611168 | Rdr |95  70  2b  07  10  80  bc  b3  87                                       |  ok | SELECT_UID-2
    2612420 |    2616004 | Tag |00  fe  51                                                               |     | 
    2618864 |    2627088 | Rdr |1b  12  34  56  78  0a  94                                               |  ok | PWD-AUTH KEY: 0x12345678
    2650676 |    2655412 | Tag |55  55  c7  b6                                                           |     | 
    2658544 |    2667920 | Rdr |a2  05  cc  85  eb  3e  03  d5                                           |  ok | WRITEBLOCK(5)
    2713524 |    2714100 | Tag |0a(3)                                                                    |     | 
    2717152 |    2726528 | Rdr |a2  06  36  94  9d  b7  de  01                                           |  ok | WRITEBLOCK(6)
    2772132 |    2772708 | Tag |0a(3)                                                                    |     | 
    2775376 |    2780080 | Rdr |30  05  af  ff                                                           |  ok | READBLOCK(5)
    2781332 |    2802132 | Tag |cc  85  eb  3e  36  94  9d  b7  29  94  88  87  b3  08  54  ea  b7  8d   |  ok | 

It appears that the blocks 5 and 6 are being updated and it seems to be more complex than just a simple counter however i do not expect any difficult cryptography (judging from tag being protected with password 12345678)

Additionally I do not know if the tag serial is not being stored in the persistent memory of the printer with a secondary counter. So it could be that the tags will expire even if the tag does not get written, but it should be at least be possible to use it in different printer.

MultiMote commented 1 month ago

It would be interesting to check how the printer behaves when the label limit of rfid tag is exceeded (density will drop or not). If the printer is going to work as usual, we could just stick a tag on the case and print on any thermal paper.

MultiMote commented 1 month ago

I cannot say for sure, but the tag is definitely being written after the print

I can confirm it. I have two printers.

  1. Checked printed labels count with both printers (put RFID tag on the case an closed the lid, sent RfidInfo packet). Printed labels = 55.
  2. Put RFID tag to printer 1. Printed two labels. Sent RfidInfo packet. Printed labels = 57.
  3. Put RFID tag to printer 2. Sent RfidInfo packet. Printed labels = 57.

Also official niimbot apps send label quota to the server: https://print.niimbot.com/api/rfid/getRfid/v2?serialNumbers%5B%5D=881dab43d38c0000 881dab43d38c0000 - your label serial number (you can get it with RfidInfo packet)

Upd: Tried to rewrite RFID tag contents to previous values (thanks to @etaloncop password) with rc522 module. Write is successful, but it seems like the printer is storing tag data inside internal memory and rewrites the tag if printer pages count is less than previous.

etaloncop commented 1 month ago

@MultiMote Thank you so much for your research. Based on your findings i conclude that there is no way to easily overcome the label counting in the printers internal memory. I might attempt to dump the printer firmware and reverse engineer the firmware, but since this is very labor and time intensive I dont see myself doing it any time soon. I will however at least attach some photos of the internals. This is the RFID IC image The main board with the MCU image

Edit: Would be good idea to check if the SWD is unlocked. If that is the case dumping the firmware should be walk in the park

etaloncop commented 1 month ago

@MultiMote One more idea, in theory it should be possible to lock the tag so its read only. I wonder if that might make it last forever. If the safety mechanism is implemented correctly it will not make a difference, however there is a chance that it might work.

MultiMote commented 1 month ago

@etaloncop tried to lock pages 5 and 6 (lock bits are 3 and 4 byte of page 2).

  0   1D AB 43 7D
  1   D3 8C 00 00
  2   5F A3 80 FF ->  5F A3 E0 FF

The printer is no longer able to write data to these pages (tested with reader). Unfortunately, counter is still incrementing (also tried to reboot and lid open-close).

tywtyw2002 commented 3 weeks ago

RFID BLK 5, 6 are printed count. blk 5/6 seems like one is the real count data, another is the CRC.

BLK 7-34 are fixed label data.

The label RFID DATA are encrypted by TEA or DES. Because the BLOCK size is 16 bytes.

I did some test on the B1. It seems the only way to stop count increase is to remove rfid from label roll, and put the rfid under the printer and close the lid.(Usually, I try for 3 times, the printer is not 100% detected RFID when RFID under the printer.) If the printer detected RFID, you can remove the rfid and print staffs, the printer will not tracker the count at this condition.

For APP side. The url https://print.niimbot.com/api/rfid/getRfid/v2?serialNumbers%5B%5D=881dab43d38c0000 is to get the label count in their cloud. If the cloud print count large than limit count, the app refuse send data to printer. U can bypass it by deny the app request with some proxy software or fake a resp.

After each print. The app send log data to niimbot-pro.cn-hangzhou.log.aliyuncs.com, the backend process the data and increase the print cnt.

Another host is bpa.niimbot.com, the app also send some data.

Block these two hosts should make APP work or just use 3-rd client to print.