Extracting VFS3 from Ni no Kuni II: Revenant Kingdom PRINCE'S EDITION (Nintendo Switch)

Extraction and unpacking of game archives and compression, encryption, obfuscation, decoding of unknown files
masagrator
Posts: 82
Joined: Sat Dec 22, 2018 10:03 am

Extracting VFS3 from Ni no Kuni II: Revenant Kingdom PRINCE'S EDITION (Nintendo Switch)

Post by masagrator »

It seems they updated VFS3 format without changing header, so script for Killer7 is returning reading error.

Image

I have only figured out that something was added at 0x8 which is not taken into account in script.

0x0 - VFS3
0x4 - VER (isn't this (also) header size?)
0xC - folder count

And so on. Maybe there is already tool somewhere that can extract it? Best would be open source.

Archive
https://drive.google.com/file/d/1Ao_0bn ... sp=sharing

Edit: It seems to be similar to file from this thread:
https://zenhax.com/viewtopic.php?t=15413#p66367
Last edited by masagrator on Mon Nov 01, 2021 9:36 pm, edited 2 times in total.
masagrator
Posts: 82
Joined: Sat Dec 22, 2018 10:03 am

Re: Extracting VFS3 from Ni no Kuni II: Revenant Kingdom PRINCE'S EDITION (Nintendo Switch)

Post by masagrator »

So after checking out whole file, I think I know now how this works, but I am lost how to decompress stuff.

Main issue is that VFS contains 10 compression dicts that needs to be used for decompression of files.
which dict to use is probably stored at the file table (there is one 16-bit value that has number between -1 and 9).
I am lost what to use to apply dicts to zstd compressed data without frame header.

Currently written script you can find here:
https://github.com/masagrator/NXGameScr ... npacker.py
spiritovod
Posts: 719
Joined: Sat Sep 28, 2019 7:00 pm

Re: Extracting VFS3 from Ni no Kuni II: Revenant Kingdom PRINCE'S EDITION (Nintendo Switch)

Post by spiritovod »

@masagrator: If you mean quickbms, dictionary is supported like this "comtype zstd dict dict_size" where dict is binary data - which is implementation of default ZSTD_decompress_usingDict function from api, I think. You can check such implementation in Frostbite script, for example.
masagrator
Posts: 82
Joined: Sat Dec 22, 2018 10:03 am

Re: Extracting VFS3 from Ni no Kuni II: Revenant Kingdom PRINCE'S EDITION (Nintendo Switch)

Post by masagrator »

spiritovod wrote:@masagrator: If you mean quickbms, dictionary is supported like this "comtype zstd dict dict_size" where dict is binary data - which is implementation of default ZSTD_decompress_usingDict function from api, I think. You can check such implementation in Frostbite script, for example.

Thanks for tip. Sadly it doesn't work for me. (error -10 while uncompressing)

By looking at files i am assuming that if file has -1 in DEC_DICT then that means compression dict is not in use.
Even by looking at data it seems to be a correct stance.

Image

But even that fails. I guess it may be related to that it doesn't have frame header (although dicts have them).

I have uploaded script that has hardcoded first dictionary and tries to unpack two files from archive in first post:
first has DEC_DICT = -1 (so I'm assuming that it doesn't use DICT at all)
second has DEC_DICT = 0 (thus why first dict)

EDIT: When adding manually header 28 b5 2f fd I'm getting error -72 instead of -10
spiritovod
Posts: 719
Joined: Sat Sep 28, 2019 7:00 pm

Re: Extracting VFS3 from Ni no Kuni II: Revenant Kingdom PRINCE'S EDITION (Nintendo Switch)

Post by spiritovod »

@masagrator: I never seen usage of headerless zstd blocks - you can probably strip magic from it, but not the rest, otherwise you'll need to modify library like, a lot. And data from the picture looks more like lz family stream (most of them can use dictionaries as well). Did you try to look for some string references of used compression in binary?
Also, your archive in the first post is not available for public, in case if someone else will decide to look into the matter.

P.S. List of zstd error codes for better understanding: link
masagrator
Posts: 82
Joined: Sat Dec 22, 2018 10:03 am

Re: Extracting VFS3 from Ni no Kuni II: Revenant Kingdom PRINCE'S EDITION (Nintendo Switch)

Post by masagrator »

spiritovod wrote:@masagrator: I never seen usage of headerless zstd blocks - you can probably strip magic from it, but not the rest, otherwise you'll need to modify library like, a lot. And data from the picture looks more like lz family stream (most of them can use dictionaries as well). Did you try to look for some string references of used compression in binary?
Also, your archive in the first post is not available for public, in case if someone else will decide to look into the matter.

P.S. List of zstd error codes for better understanding: link

oops, fixed.
Still dictionaries have correct magic for zstd dictionaries. So at least files using them must be zstd.

Executable is also mentioning lz4 and zlib. It's not zlib obviuously.
Tried lz4 and also doesn't work.

I'm assuming all files are zstd because filename has "zstd" :D
masagrator
Posts: 82
Joined: Sat Dec 22, 2018 10:03 am

Re: Extracting VFS3 from Ni no Kuni II: Revenant Kingdom PRINCE'S EDITION (Nintendo Switch)

Post by masagrator »

So for now figured out that files not using DICTs can use standard frame_header, but I need manually update it with compressed size in binary form.

Edit: All files not using dictionaries with only 1 frame decompressed successfully. It's using stanard zstd frame_header with --no-check.
masagrator
Posts: 82
Joined: Sat Dec 22, 2018 10:03 am

Re: Extracting VFS3 from Ni no Kuni II: Revenant Kingdom PRINCE'S EDITION (Nintendo Switch)

Post by masagrator »

Figured out how to decompress files with chunks not using dictionary.
Now time to take dictionary attack.
masagrator
Posts: 82
Joined: Sat Dec 22, 2018 10:03 am

Re: Extracting VFS3 from Ni no Kuni II: Revenant Kingdom PRINCE'S EDITION (Nintendo Switch)

Post by masagrator »

Ok, I have now 100% success rate in extracting and decompressing files in all VFS3 archives for Ni no Kuni 2 Switch version.

Python script can be found here:
https://github.com/masagrator/NXGameScr ... npacker.py

It requires Python 3 and installed libraries: zstandard, numpy