Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

B21: Hack to not waste labels during testing #34

Open
etaloncop opened this issue Aug 5, 2024 · 34 comments
Open

B21: Hack to not waste labels during testing #34

etaloncop opened this issue Aug 5, 2024 · 34 comments

Comments

@etaloncop
Copy link

etaloncop commented Aug 5, 2024

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
Copy link
Owner

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 kjy00302#4 as related

@etaloncop
Copy link
Author

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
Copy link

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
Copy link

MultiMote commented Aug 7, 2024

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
Copy link
Author

etaloncop commented Aug 11, 2024

@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
Copy link
Author

@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
Copy link

MultiMote commented Aug 12, 2024

@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
Copy link

tywtyw2002 commented Aug 16, 2024

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.

@cryoz
Copy link

cryoz commented Dec 12, 2024

@etaloncop
Copy link
Author

@cryoz Wow awesome job, thanks
strings.csv
I am ataching dumped strigs from the file with addresses.
A lot of it looks like commands, maybe the device will accept them over UART, might be good to find the UART and attempt to see if there is some sort of shell.

Once I have more time i will take closer look on the binaries

@etaloncop
Copy link
Author

@cryoz
image
Is this SWD???

@MultiMote
Copy link

MultiMote commented Dec 13, 2024

@cryoz my B1 revision (HW 5.10) has pin labels, looks like it is uart in my case (in your case it looks like SWD indeed, D - DIO, C - CLK, G - GND, V - VCC).

IMG_20240624_195438

@cryoz
Copy link

cryoz commented Dec 13, 2024

yes, it's uart, but it's useless for now - only output BT_Init end, and in firmware all functions about uart receive are not called from anywhere, it seems. uart params are 256000-8-N-1

@cryoz
Copy link

cryoz commented Dec 14, 2024

well, some results from firmware:
1)rfid encrypted with TEA, from block 5 to block 34
2) tea key: <removed>
when decrypted:
3) block5 - count of printed pages?
4) block 6 = CRC32(block5) (4 bytes)
5) block 34 = CRC32(block7..block33) (108 bytes)

@cryoz
Copy link

cryoz commented Dec 14, 2024

Well, customized dump for rfid tag successfully accepted by printer. dump structure almost finished, just increase print limit number, zeroing already printed pages counter and - if you want - change serial number for this tag. cannot say if official app accept this custom tag, but i don't use these apps. printer saves print limit and printed count in SRAM followed by tag serial in blocks 7-8, not UID of tag. cannot say if sram is zeroed after battery power disconnect, but sram is not infinite.

@tywtyw2002
Copy link

tywtyw2002 commented Dec 15, 2024

#include <stdio.h>
#include <stdlib.h>

const int k0 = ??;
const int k1 = ??;
const int k2 = ??;
const int k3 = ??;

const uint32_t crc32_tab[] = {
    0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
    0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
    0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
    0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
    0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
    0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
    0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
    0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
    0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
    0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
    0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
    0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
    0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
    0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
    0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
    0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
    0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
    0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
    0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
    0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
    0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
    0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
    0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
    0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
    0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
    0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
    0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
    0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
    0xd80d2bda, 0xaf0a1b4c, 0x36034af6, ?, 0xdf60efc3, 0xa867df55,
    0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
    0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
    0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
    0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
    0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
    0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
    0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
    0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
    0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
    0xa7672661, 0xd06016f7, 0x4969474d, ?, 0xaed16a4a, 0xd9d65adc,
    0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
    0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
    0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
    0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, ?
};

uint32_t crc_check_rfid(void *buf, int size)
{
    const uint8_t *a1 = buf;
    unsigned int i; // r2

  for ( i = -1; size-- != 0; i = (i >> 8) ^ crc32_tab[((*a1++ ^ i) & 0xFF )])
    ;
  return ~i;
}


unsigned int tea_decrypt(unsigned int *a1, unsigned int *a2) {
  unsigned int v2;     // r1
  unsigned int result; // r0
  int v4;              // r2
  unsigned int i;      // r3

  v2 = *a1;
  result = a1[1];
  v4 = 0xC6EF3720;
  for (i = 0; i < 0x20; ++i) {
    result -= (16 * v2 + k2) ^ (v2 + v4) ^ ((v2 >> 5) + k3);
    v2 -= ((result >> 5) + k1) ^ (result + v4) ^ (16 * result + k0);
    v4 += 0x61C88647;
  }
  *a2 = v2;
  a2[1] = result;
  return result;
}

unsigned int tea_encrypt(unsigned int *a1, unsigned int *a2)
{
  unsigned int v2; // r1
  unsigned int result; // r0
  int v4; // r2
  unsigned int v5; // r3

  v2 = *a1;
  result = a1[1];
  v4 = 0;
  v5 = 0;
  do
  {
    ++v5;
    v4 -= 0x61C88647;
    v2 += ((result >> 5) + k1) ^ (result + v4) ^ (16 * result + k0);
    result += (16 * v2 + k2) ^ (v2 + v4) ^ ((v2 >> 5) + k3);
  }
  while ( v5 < 0x20 );
  *a2 = v2;
  a2[1] = result;
  return result;
}


void decrypt() {
    printf("decrypt");
    uint32_t data[30];
    uint32_t result[30];

    FILE *fp;
    fp = fopen("label_raw.bin", "r");
    fread(data, sizeof(data), 1, fp);
    fclose(fp);

    for (int i = 0; i < 30; i=i+2) {
        tea_decrypt(&data[i], &result[i]);
    }

    fp = fopen("label_data.bin", "w");
    fwrite(result, sizeof(result), 1, fp);
    fclose(fp);
}

void encrypt() {
    printf("Encrypt.");
    uint32_t data[30];
    uint32_t result[30];

    FILE *fp;
    fp = fopen("label_data.bin", "r");
    fread(data, sizeof(data), 1, fp);
    fclose(fp);

    // crc for cnt
    data[1] = crc_check_rfid(&data, 4);
    data[29] = crc_check_rfid(&data[2], 108);

    for (int i = 0; i < 30; i=i+2) {
        tea_encrypt(&data[i], &result[i]);
    }

    fp = fopen("label_raw.bin", "w");
    fwrite(result, sizeof(result), 1, fp);
    fclose(fp);
}


void main() {
    // encrypt();
    decrypt();
}

Good luck guys.

If u not use the app, just random generate a tag data and write them to a NTAG215 tag then everything fine.

@tywtyw2002
Copy link

tywtyw2002 commented Dec 15, 2024

well, some results from firmware: 1)rfid encrypted with TEA, from block 5 to block 34 2) tea key: ????? when decrypted: 3) block5 - count of printed pages? 4) block 6 = CRC32(block5) (4 bytes) 5) block 34 = CRC32(block7..block33) (108 bytes)

I did this long time ago, some detailed information already forgot...

block 5 is printed label cnt.
block 7-8 uuid
block 9-12 serial ASCII
block 15-16 barcode
block 21 first 2bytes is print limited cnt (2bytes short)

@MultiMote
Copy link

Be careful guys. I'm not sure it's a good idea to keep it in the public domain.
Sometimes the printer manufacturer watches the GitHub, if they find any hacks they will fix it in the next release to block it. Or some profiteer will sell this stuff for profit.

@cryoz
Copy link

cryoz commented Dec 15, 2024

FW for D11 (12.21) - https://niimbot-bison.oss-cn-hangzhou.aliyuncs.com/public_resources/font/6cb97e175a1ad1728756e2b8b40c344b.bin
In addition for blocks map:
block 27: paper height (frst byte), paper width (second byte)
P.S. i've removed keys from my comment, thanks @MultiMote

@etaloncop
Copy link
Author

Be careful guys. I'm not sure it's a good idea to keep it in the public domain. Sometimes the printer manufacturer watches the GitHub, if they find any hacks they will fix it in the next release to block it. Or some profiteer will sell this stuff for profit.

There is only so much the manufacturer could do, his hands are tied, afterall they need to keep backwards compatibility. Its better if community has resources on how to defeat the measures.

@cryoz
Copy link

cryoz commented Dec 15, 2024

There is only so much the manufacturer could do, his hands are tied, afterall they need to keep backwards compatibility. Its better if community has resources on how to defeat the measures.

i think, manufacturer is not main problem. Profiteers are real problem - selling universal tags for example.
And for community - problem for wasting labels is not solved with these keys. Firmware hack - yes, but 1) not all firmwares for all printers are available, 2) we cannot dump current fw 3) we need method for upload hacked fw to device without official app.
Uploading fw to device - sniffing official app bluetooth when updating fw, maybe.
Hacking FW is trivial, but for my B1 (HW 3.01) i cannot find fw, physical dumping not possible for now.

@etaloncop
Copy link
Author

I will look into the swd interface then, if it is there and enabled. It could be used for precisely that.

@cryoz
Copy link

cryoz commented Dec 15, 2024

I will look into the swd interface then, if it is there and enabled. It could be used for precisely that.

b1 and d11 don't have ARTERY CPU and based only on YC3121 CPU, sdk and datasheet are very hard to find, only datasheet i found is here (chinese): https://www.ycble.cn/apks/yc_file/YC3121%EF%BC%88BT%EF%BC%89%E8%8A%AF%E7%89%87%E6%95%B0%E6%8D%AE%E6%89%8B%E5%86%8CV2.0.pdf
in theory, they have SWD, but is it enabled or not i cannot say

@tywtyw2002
Copy link

tywtyw2002 commented Dec 16, 2024

FW for D11 (12.21) - niimbot-bison.oss-cn-hangzhou.aliyuncs.com/public_resources/font/6cb97e175a1ad1728756e2b8b40c344b.bin In addition for blocks map: block 27: paper height (frst byte), paper width (second byte) P.S. i've removed keys from my comment, thanks @MultiMote

you also need to remove editing history.

Screenshot 2024-12-16 at 00 06 22

@tywtyw2002
Copy link

If we can figure out how to reflash the firmware. Just need to mask few instructions then the rfid is no longer necessary and will not affect the print quality.

In the disassembly code, the printer force lower the printing density if the rfid result false.

@cryoz
Copy link

cryoz commented Dec 22, 2024

we can reflash firmware. WIndows app includes printer server and electron webapp. webapp communicating with printer via printserver by simple websocket protocol.
you can unpack setup file of official windows application, find file jcPrinterSdk.exe and unpack it too. After just run jcprinter.exe, turn on printer, connect it by usb and you can communicate with printer via websocket, for example:

import websocket
import json

websocket_url = 'ws://localhost:37989'

ws = websocket.WebSocket()
ws.connect(websocket_url)

# receiving info about connected printers

rq = {'apiName': 'getAllPrinters'}
ws.send(json.dumps(rq))
connectData = {}
message = json.loads(ws.recv())
if message.get('resultAck', None):
    if message['resultAck'].get('info', None):
        info = json.loads(message['resultAck']['info'])
        connectData['printerName'] = [*info][0]
        connectData['port'] = int(info[connectData['printerName']])

# Connect Printer

# {"apiName":"selectPrinter","parameter":{"printerName":"f227060347","port":6}}
rq['apiName'] = 'selectPrinter'
rq['parameter'] = connectData
ws.send(json.dumps(rq))
message = ws.recv()
print(json.loads(message))

# Enable detailed logging to console

rq = {'apiName': 'enableConsoleAllLog'}
rq['parameter'] = {'isEnable':1}
ws.send(json.dumps(rq))
while True:
    message = json.loads(ws.recv())
    if message.get('apiName', None) == rq['apiName']:
        break
print(message)

# Run some commands

rq = {'apiName': 'getPrinterTagID'}
ws.send(json.dumps(rq))
while True:
    message = json.loads(ws.recv())
    if message.get('apiName', None) == rq['apiName']:
        break
print(message)

# Update firmware

# rq = {'apiName': 'updateFirmware'}
# # SAMPLE data for firmware
# fwdata = {'fileName': r"d:\\niimbot\\fw\\B1_3.04_mod.bin", 'strSwVersion': '3.04', 'strCrc': '12345678'}
# rq['parameter'] = fwdata
# ws.send(json.dumps(rq))
# while True:
#     message = json.loads(ws.recv())
#     if message.get('apiName', None) == rq['apiName']:
#         print(message)
#         resAck = message.get('resultAck', None)
#         if resAck:
#             if resAck.get('result',None) == 0:
#                 break

# close the websocket connection
ws.close()

@cryoz
Copy link

cryoz commented Jan 3, 2025

I found fw for my printer version (B1 HW 3.01), patched and flashed it by (updated) script above. All is perfect now, printer worked like intended :)

@MultiMote
Copy link

MultiMote commented Jan 6, 2025

@cryoz how strCrc is calculated? For dec and hex (reverse order too) representation of crc32 I am getting {"errorCode":4,"info":"crc checkout error!","result":-1}

@cryoz
Copy link

cryoz commented Jan 6, 2025

@MultiMote CRC32 of whole fw file. Here simple script:

import sys
from zlib import crc32

if len(sys.argv) < 2:
    print('Usage: fw_crc.py fw.bin')
    exit(0)

with open(sys.argv[1], 'rb') as f:
    fw = f.read()
crc = crc32(fw)
print(f'Firmware CRC: {crc:08X}')

Insert that 8-digit hex number into strCrc parameter as is.
P.S. D11_H have modern cpu and slight more complex crc checks inside firmware

@MultiMote
Copy link

MultiMote commented Jan 6, 2025

Trying to flash firmware from this comment #34 (comment)

image

@cryoz
Copy link

cryoz commented Jan 6, 2025

you shoud use full path of firmware file for filename parameter, jcPrint server cannot find file in his current directory without full path :)

@MultiMote
Copy link

Oh, my really stupid error 😂
Now it works, thanks.

@cryoz
Copy link

cryoz commented Jan 6, 2025

i can patch fw 5.14 for b1 and upload patched firmwares for B1 HW 3.01 or D11_H HW 4.01, but i don't think github is right place for that.

@tywtyw2002
Copy link

i can patch fw 5.14 for b1 and upload patched firmwares for B1 HW 3.01 or D11_H HW 4.01, but i don't think github is right place for that.

use telegram to upload the file and paste link here, should be fine. Or someone could create a telegram group.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants