View Single Post
Old 02-28-2026, 03:45 PM   #1
KitchenReader
Junior Member
KitchenReader began at the beginning.
 
Posts: 5
Karma: 10
Join Date: Feb 2026
Device: Pocketbook Touch HD2 (631)
Touch HD2 (631) trying to beat internal SD card lock, need some help

Hello! I'm new here, and very happy to have found this community. I have s 2018 Touch HD2, and the internal SD card is slowly dying - I've had several issues with opening books, with the device returning back to the main screen after clicking on a given book. Luckily for the moment I have managed to remedy it by running a check for errors on the micro SD card on my laptop running Linux (Incidentally, I couldn't manage to fix it on a windows machine) but definitely the days of the card are slowly numbered and I need replace it.

Now there is a wonderful thread about replacing SD cards on a 626
, which sadly does not work on the Touch HD2, the fact that both Touch HD and Touch HD2 share a model number (631) does not help either (Thanks Pocketbook). So I want to share all that I've managed to find out, and I need some help choosing a path to move forward.

First, the specs of my device:
Code:
Software version: U631.5.20.1527
device serial: NX280100109600W000X8
card serial: 0x6d019585
.freezestatus contents (hex): E9 A5 5D 50
What I've tried:
replace reading serial invocation with a file call as described in luators blog: https://luator.de/linux/2019/11/23/p...ce-memory.html

replace .freezestatus contents using the perl script as described here: https://www.mobileread.com/forums/sh...&postcount=195

sadly neither (and not both combined) worked for me for the Touch HD2, although I can confirm that my .freezestatus code is the same as the one generated by the perl script.

It seems that the internal structure is different, it has four partitions instead of 10 like in previous versions:

Code:
Command (m for help): p
Disk /dev/mmcblk0: 7.4 GiB, 7948206080 bytes, 15523840 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device         Boot   Start      End  Sectors  Size Id Type
/dev/mmcblk0p1        71680   198655   126976   62M 83 Linux
/dev/mmcblk0p2       198656  1017855   819200  400M 83 Linux
/dev/mmcblk0p3      1017856  1222655   204800  100M 83 Linux
/dev/mmcblk0p4      1222656 15523839 14301184  6.8G  c W95 FAT32 (LBA)
p2
Spoiler:
Code:
drwxr-xr-x   2 root    root        1024 Nov  7  2019 adobefonts
drwxr-xr-x   2 root    root        1024 Nov  7  2019 applications
-rw-r--r--   1 root    root         934 Nov  7  2019 applications.md5
drwxr-xr-x   2 root    root        3072 Nov  7  2019 bin
drwxr-xr-x   4 root    root        1024 Aug 16  2022 config
drwxr-xr-x   2 root    root        1024 Nov  7  2019 cramfs
-rw-r--r--   1 root    root   127524864 Nov  7  2019 cramfs.img
-rw-r--r--   1 root    root          20 Nov  7  2019 .def_id
drwxr-xr-x   3 root    root        1024 Aug 16  2022 demo
drwxr-xr-x   3 root    root        2048 Nov  7  2019 fonts
drwxr-xr-x   2 root    root        1024 Aug 16  2022 fsimage.dir
-rw-r--r--   1 root    root        4179 Nov  7  2019 fsimage.md5
-rw-r--r--   1 root    root      750882 Nov  7  2019 fsimage.tar.gz
drwxr-xr-x   4 root    root        2048 Aug 16  2022 language
drwxr-xr-x   5 root    root        8192 Nov  7  2019 lib
drwxr-xr-x   2 root    root        1024 Nov  7  2019 libexec
drwxr-xr-x   3 root    root        1024 Nov  7  2019 license
drwxr-xr-x   4 root    root        1024 Aug 16  2022 logo
drwx------   2 root    root    20971520 Nov  7  2019 lost+found
lrwxrwxrwx   1 root    root          19 Feb 25 19:32 pocketbook -> monitor.app
drwxr-xr-x  11 root    root        1024 Nov  7  2019 qml
drwxr-xr-x   2 root    root        1024 Nov  7  2019 resources
drwxr-xr-x   2 root    root        1024 Nov  7  2019 sbin
drwxr-xr-x  17 root    root        1024 Aug 16  2022 share
drwxr-xr-x   2 root    root        1024 Nov  7  2019 themes
drwxr-xr-x   3 root    root        1024 Nov  7  2019 translations
-rw-r--r--   1 root    root          14 Nov  7  2019 .version



p3
Spoiler:
-rw-r--r-- 1 root root 1923078 Nov 21 2017 bootlogo.bmp
-rw-rw-rw- 1 rtkit rtkit 3554 Jun 25 2025 device.cfg
-rw-rw-rw- 1 rtkit rtkit 3527 Jun 25 2025 device.cfg.back
-rw-rw-rw- 1 root root 32 Nov 21 2017 deviceid
drwxrwx--- 2 rtkit rtkit 3072 Aug 16 2022 dictionaries
-rw-rw-rw- 1 rtkit rtkit 32 Jun 25 2025 download_device_param.cfg
-rw-rw-rw- 1 rtkit rtkit 32 Jun 25 2025 download_device_param.cfg.back
-rw-rw-r-- 1 marius marius 4 Feb 25 20:55 .freezestatus
-rw-r--r-- 1 root root 190 Nov 21 2017 fwinfo.txt
-rw-rw-rw- 1 rtkit rtkit 16 Nov 21 2017 .hashsum_1
-rw-rw-rw- 1 rtkit rtkit 16 Nov 21 2017 .hashsum_2
drwxrwxrwx 2 rtkit rtkit 1024 Aug 16 2022 Legimi
drwxr-xr-x 2 root root 12288 Jan 1 2012 lost+found
-rw-rw-rw- 1 root root 139 Feb 24 22:10 monitorinfo
-rw-r--r-- 1 root root 66 Feb 24 21:55 netdevcache
-rw-r--r-- 1 root root 66 Feb 24 21:55 netdevcache.back
-rw-r--r-- 1 root root 433 Jun 25 2025 network.conf
drwxrwx--- 2 rtkit rtkit 1024 Jan 1 2012 pbpk
drwxr-xr-x 2 1028 users 1024 Jan 1 2012 ppbk
drwxr-xr-x 2 rtkit rtkit 1024 Jun 25 2025 runonce
-rw-rw-rw- 1 rtkit rtkit 0 Aug 16 2022 settings_pass.txt
-rwxrwx--- 1 rtkit rtkit 80 Aug 16 2022 swupdate.db


Then I tracked how does the monitor.app reads the serial code using ghidra

monitor.app

function ioc_getdserialnumber()

function iocf_request(...)

file libioc.so

blob


this is how monitor.app retrieves the device serial number

Spoiler:
Code:
bool ioc_getserialnumber(char * param_1) {
  int iVar1;
  bool bVar2;
  builtin_strncpy(param_1, "00000000000000000000", 0x15);
  bVar2 = false;
  if (DAT_000a52f4 == '\x01') {
    if ((DAT_000a52f0 & 1) == 0) {
      return false;
    }
    iVar1 = ( * iocf_request)(1, 0);
    bVar2 = iVar1 != 0;
  }
  return bVar2;
}


I tried using AI to explain what I'm seeing, but no dice. I think this is a dead-end
Spoiler:

Code:
if ( * param_3 == -0x6b8e51c9) {
    iVar2 = param_3[1];
    iVar3 = param_3[2];
    uVar6 = param_3[3] - ((iVar2 * 0x3576123c ^ 0xe77ed839 U ^ iVar2 * -0x32bc3ad1 + 0x97983467 U) & 0xfffffffc) >> 2;
    uVar5 = iVar2 * -0xe179b11 + 0xd3b03545 U ^ iVar2 * -0x4e94468d + 0xcf22f2cd U ^ iVar2 * 0x61e23b9d;
    uVar4 = iVar2 * -0xe179b11 + 0x2bcd8631 U ^ iVar2 * -0x4e94468d + 0x8b5e227 U ^ iVar2 * 0x797c436f;
    iVar7 = param_1;
    do {
    iVar1 = uVar4 + uVar5;
    uVar6 = uVar6 - 1;*(int * )(iVar7 + 0x100) = iVar1 + * (int * )((iVar7 - param_1) + (iVar3 - ((iVar2 * 0x25635427 ^ 0xb9745709 U ^ iVar2 * 0x761cea17 + 0xbdf1f023 U) & 0xfffffffc)));
    uVar4 = (uVar4 >> 9 | uVar4 << 0x17) * -0x7a15b04b + 0xd9c6780f ^ iVar1 * 0x43e4fc73 + 0x9f8ac57 U;
    uVar5 = (uVar5 >> 7 | uVar5 << 0x19) * 0x5d7e7327 + 0x9dcfa735 ^ iVar1 * 0x695fce19 + 0x81d77471 U;
    iVar7 = iVar7 + 4;
    } while (uVar6 != 0xffffff80);
    software_interrupt(0);
    ( * (code * )(param_1 + 0x100))(param_2, param_1, param_3, param_4);
} else {
    ( * (code * ) param_3[2])(param_2, param_1);
}


European pocketbook branches suggested me just buying a new device with a discount, while pocketbook.ru was indeed more helpful, offering such a service, sadly they require having a russian bank account, and even if they didn't it would be a problem conducting business with them for political reasons. but the interesting thing they mention is that they would need a screen cable photo?? (translated)
Spoiler:

Hello, Our service center charges the following repair: if you can't or don't want to contact the service center, we have a firmware generation option for remote users or those who want to save money on a service center visit. Firmware generation costs 650 rubles.

here's other relevant details:

III. For assembly, the following information is also needed:

1) The device serial number, 20 characters, uppercase Latin letters and numbers.
2) Photo of screen cable with all specified data - model, Waveform and Vcom
3) SDSN of new memory card.


And here is now, on Monday I'm going to contact one more repair shop, this time from Ukraine, they have a youtube channel, hopefully I can gather more information, but I don't know the best way to proceed for now.

1. Should I continue digging in monitor.app, looking for ways to stub the original values? Could that work?
2. Should I try getting root on the device using this method, it seems to be confirmed to work for Touch HD2 ? I use linux at work, but I'm not fluent in the deep end of it. Maybe some avenues would open up if I had root access?
3. Are there any other avenues I could try?
KitchenReader is offline   Reply With Quote