The nbl format is an archive format that supports encryption, compression and endianness. It is separated in two parts with the first one mandatory and the second optional. The first part stores most files while the second part apparently only stores textures.
Two file format identifiers have been identified so far.
The file format identifier is available in the first 4 bytes of the nbl files.
On low-endian architectures like the PC and the PSP, the files are stored in low-endian with a file format identifier NMLL
.
On big-endian architectures like the XBOX 360, the files are stored in big-endian with a file format identifier NMLB
.
Not much is known so far about the NMLB
format and whether it has an impact on the algorithms. Similarly, the PS2 files have not been studied at all. Note that there is one NMLB
file on the AOTI disc, probably put there by mistake.
Additionally, textures are stored further in the file and have a similar identifier for their chunk: TMLL
. It isn't known yet whether there is a TMLB
chunk for big-endian files.
The identifiers can be tentatively recognized:
NMLL
: N M L Low-endianNMLB
: N M L Big-endianTMLL
: Textures M L Low-endian
The headers have a size of 0x30
with the first 0x20
reserved for the NMLL
part of the archive and the last 0x10
for the TMLL
part. The TMLL
information is repeated later in the file in the TMLL
headers though.
The two missing values are unrelated to the availability of a TMLL
chunk. They also don't seem to be used for decompression nor decryption. They're often equal to 0, which implies they are probably not checksum- nor padding-related. They most certainly represent some sort of count or size, though, because of their distribution.
Position | Size | Type | Description |
---|---|---|---|
0x00 | 4 | char[4] | File format identifier |
0x04 | 2 | ushort | File format version (so far only 0x0002 ) |
0x06 | 2 | ? | Unknown |
0x08 | 4 | uint | Headers size (including the files list) |
0x0C | 4 | uint | Number of files |
0x10 | 4 | uint | Uncompressed data size, for all files |
0x14 | 4 | uint | Compressed data size, for all files; 0 if they aren't compressed |
0x18 | 4 | ? | Unknown |
0x1C | 4 | uint | Decryption key seed |
0x20 | 4 | uint | Size of the TMLL header; 0 if there isn't any |
0x24 | 4 | uint | Uncompressed TMLL data size |
0x28 | 4 | uint | Compressed TMLL data size |
0x2C | 4 | uint | Number of files in the TMLL chunk |
The files list starts at 0x30
in the file. It is basically many chunks of (usual) size 0x60
appended one after another, one for each file. The number of files can be found in the headers.
Note that while most nbl files have these chunks of size 0x60
, it is apparently possible to have different sizes for them because the chunk size can be defined inside it.
When the file is encrypted, only part of the file chunk is encrypted, starting at position 0x10
with a size of 0x30
. Once decrypted it can be read without any additional work.
The positions in the following table are from the beginning of the current file information chunk.
Position | Size | Type | Description |
---|---|---|---|
0x00 | 4 | char[4] | Chunk identifier |
0x04 | 4 | uint | Chunk size (usually 0x60 ) |
0x08 | 4 | ? | Unknown |
0x0C | 4 | ? | Unknown |
0x10 | 0x20 | char[0x20] | Filename |
0x30 | 4 | uint | Position in the uncompressed data (0 = data start position) |
0x34 | 4 | uint | Size of the file in the uncompressed data |
0x38 | 4 | ? | Unknown |
0x3C | 4 | ? | Unknown |
0x40 | 4 | ? | Unknown |
0x44 | 4 | ? | Unknown |
0x48 | 4 | ? | Unknown |
0x4C | 4 | ? | Unknown |
0x50 | 4 | ? | Unknown |
0x54 | 4 | ? | Unknown |
0x58 | 4 | ? | Unknown |
0x5C | 4 | ? | Unknown |
As far as is currently known, the data position isn't clearly indicated in the headers.
One can deduce it by calculating it with the knowledge of the headers size (found in the headers) and the padding size (which can be deduced by looking at the file). The padding size has been found to be of 0x800
bytes for the PC files, and many PSP2 files. However it appears that some PSP2 files use a padding of 0x40
. Whether this padding size can be deduced automatically is currently unknown.
All files are appended right after another, then optionally compressed, then optionally encrypted. One must thus first decrypt the whole data, then decompress the result before being able to access the files.
Later in the file can be found a TMLL
chunk. The calculation to reach the TMLL
chunk is unfortunately unknown so far. It can be found by searching through the file at all positions multiple of the padding size.
Not all files contain a TMLL
chunk. The NMLL
headers contain information allowing us to know whether a file contains a TMLL
chunk without having to search for it.
Note that just before the TMLL
chunk there is some sort of data table available. This table seems to have a size dependent on the number of files in the chunk. Its use isn't known so far.
The headers have a size of 0x20
.
Some values are just repeated from the NMLL
headers. The TMLL
headers can in fact be completely ignored for reading because they don't tell more than has been said by the NMLL
headers. The values are probably repeated only for convenience.
All TMLL
chunks appear to be compressed. It is not known whether the game is capable of loading an uncompressed TMLL
chunk.
Position | Size | Type | Description |
---|---|---|---|
0x00 | 4 | char[4] | Chunk identifier (TMLL ) |
0x04 | 2 | ushort | File format version (so far only 0x0002 ) |
0x06 | 2 | ushort | Nothing (so far only 0x0000 ) |
0x08 | 4 | uint | Headers size (including the files list) |
0x0C | 4 | uint | Number of files |
0x10 | 4 | uint | Uncompressed data size, for all files |
0x14 | 4 | uint | Compressed data size, for all files |
0x18 | 4 | uint | Nothing (so far only 0x00000000 ) |
0x1C | 4 | uint | Nothing (so far only 0x00000000 ) |
According to current knowledge, the files list works like the NMLL files list except they start at position 0x20
from the start of the TMLL
chunk.
Of course, since not everything is known about either, there might be some small differences. But many things including size, positions and decryption are the same.
The TMLL
data uses a different compression than the NMLL
data. Not much is known on that yet and no files have been extracted so far.