QNX6 Superblock CRC calculation

Hi guys,

I am trying to modify a QNX6 FS superblock.
However, it seems there is a CRC checksum in the superblock and now I am trying to find out how that checksum is calculated.
Maybe there is someone around that could bring me on the right track?




There is definitely a checksum (see the documentation on superblocks).

You’ll probably have to contact QNX directly (Foundry 27) for how it’s calculated.

The question is why are you trying to modify it?


I got a slightly properitary QNX6 FS device where I am trying to increase the FS on one partition.
Well, I already reverse engineered a lot. (directory nodes, inodes, bitmap nodes, file chains etc.)
One of the next things will be to modify both superblocks to reflect more free blocks, more space (+ relocate the second superblock).

Of course I will also have to increase the bitmap nodes for more space … that’s clear.

That specific device has no terminal, does not mount any other filesystems (ext2, vfat etc. tried), does not accept a fresh QNX6 FS (superblocks on different position, slightly different superblock structure), does not re-initialize it’s storage if given an empty partition etc. etc :frowning:


If it’s slightly proprietary it may not work even if you do manage to rewrite the super blocks. Who knows what was built into it to prevent the kinds of mods you are trying to do.

You don’t mention whether the device has a CF card or is using pure flash memory. If it has a removable card, you could try putting the card in another machine, copying all the files off, reformatting to your hearts content and then copying the files back. But if it’s just got pure flash that’s obviously out of the question.

I’m also not sure what you mean by ‘does not re-initialize it’s storage if given an empty partition’. The dinit command is used to initialize an empty partition to a QNX filesystem.


Hi Tim,

first, thanks for your replies …
The device has an internal 2.5" harddrive (IDE) which I can take out and put in an external USB enclosure.
Due to the “modifications” QNX Neutrino - at least the latest version - refuses to mount the fs.
Tried dinit but the appliance refused to accept a freshly created - again, created with the latest QNX version - filesystem.
So I can not copy the content and create a fresh, bigger fs.

“does not re-initialize it’s storage” meant that the device does not automatically detect if you give it an empty device (partition) and create a fresh fs on it. (which would make it easy … the files are not important)


The superblock/filesystem actually seems to be quite similar to the original qnx6-fs. However, if I try to chkqnx6fs the filesystem, I am getting a “wrong superblock signature” error.

Hey it sounds like it was protected against tempering for a reason… :slight_smile:

Of course it was, but I’m not sure if it was protected for the reason to prevent me changing the superblock.
My impression is that it was just “protected” for a safe fs-error detection to do a proper rollback.
If I wanted to really protect something I’d use AES and not a sort of crc ;)


The chkqnx6fs command is only for QNX 6.4 or later versions. Before you you use chkfsys. Not sure whether that will solve your problem or not because you didn’t mention what version of the O/S the appliance is using.

It’s obvious the boot image isn’t on the HD itself since you can format the drive and it still doesn’t work. So yeah, it’s likely they’ve customized some kind of copy protection in which case you’ll have to manually puzzle it out by trial and error (assuming chkfsys doesn’t help).


Well, I assumed that qnx6fs is qnx6fs. It could well be true that the appliance is using an older version.
So over the time there were changes to the qnx6fs that could cause newer qnx version to refuse a fs-check?

No problem to weap up my keyboard - you know. So over time that thing will lose anyways …
However, I thought that at least for a clean, freshly created qnx6fs (using the latest qnx version) I thought there shall be a way to modify the superblock. At least I had the hope the required knowledge could be somewhere out here.
But maybe really no-one else already came that far - at least in the context of qnx6fs :frowning:


Actually until fairly recently (a year or so ago) most of QNX was open source and could be downloaded from a repository on Foundry 27. Some stuff is still available there. No idea if that includes the entire file system but it might include the chkfsys utility.

My point is that the maker of the device could have gotten hold of the source code and made a mod to the CRC polynomial to ‘customize’ their device. If they have done that then brute force is the only way you are going to achive what you want.


Yes, I already found some links to sourcecode. However, it seems that all those links got invalidated due to either a content move or policy change. (not sure which reason is true)
I also already had the idea that even a simple fs utility source could be sufficient for my needs.
Sorry to say, as for the qnx sources the same seems to be true for all fs utilities :frowning:

Ok, I know that byte 5-8 in the superblock are the only candidates for the checksum.
(all the other changes to the superblock I can explain if I copy a new file to the fs)

Further, no crc32 (as we are talking about 4 bytes just crc32 algorithms came into focus) run over any potion of the superblock (implemented a program that tries out all “sliding window” byte lengths) resulted in a match.
So tomorrow I will extend the test by including a “brute-force” 2^32 “pre-initialization” of those 4 bytes and compare the crc32 outcome to that specific superblock crc32.
Yes, of course, I will end up with a match. But I have plenty superblocks on the shelve ;) (easy to create a new one by just copying or deleting a file)
Let’s see if I will come to a match across multiple superblocks …

Next idea is that maybe an xor is applied after crc32 calculation. (that would make it easy for appliance creators to do a “slight” modification at that step)
So I will also write a piece of source code to check 2^32 combinations of potential xor candidates. In that case I am perfectly sure that I >have< get a match. (otherwise I’ve got a different problem with my source code…)
Again, If that xor value will match for different superblocks it will be a winner ;)

So … let’s see how good the actual “protection” is …