Title Database: Difference between revisions
TimmSkiller (talk | contribs) Correct information about pre-headers |
TimmSkiller (talk | contribs) Restructure a bit to have a proper ToC |
||
| (2 intermediate revisions by the same user not shown) | |||
| Line 134: | Line 134: | ||
This is a variant of [[Inner FAT|FAT filesystem]]. It consists one "root" directory and multiple "files". Each "file" is one title info entry described below. | This is a variant of [[Inner FAT|FAT filesystem]]. It consists one "root" directory and multiple "files". Each "file" is one title info entry described below. | ||
== Title Info Entry == | === Title Info Entry === | ||
An entry contains information taken from both the application NCCH file(s) and TMD. | An entry contains information taken from both the application NCCH file(s) and TMD. | ||
| Line 140: | Line 140: | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Start | ! Start !! Length !! Description | ||
! Length | |- | ||
! Description | | 0x0 || 0x8 || u64, Title Size | ||
|- | |||
| 0x8 || 0x4 || u32, Title Type from TMD (usually 0x40) | |||
|- | |||
| 0xC || 0x2 || u16, Title Version | |||
|- | |||
| 0xE || 0x2 || u16, Content index for Download Play Child content | |||
|- | |||
| 0x10 || 0x2 || u16, Content index for Instruction Manual content | |||
|- | |||
| 0x12 || 0x2 || u16, Content index for Old3DS update partition (even though this is unused because digital titles don't have update partitions) | |||
|- | |||
| 0x14 || 0x4 || TMD file ID (the ID part in <code>{ID}.tmd</code> inside the title folder) | |||
|- | |||
| 0x18 || 0x4 || CMD file ID (the ID part in <code>{ID}.cmd</code> inside the title folder) | |||
|- | |||
| 0x1C || 0x4 || save file ID (the ID part in <code>{ID}.sav</code> inside the title/data folder) | |||
|- | |||
| 0x20 || 0x8 || u64, extdata ID (zero if title does not use extdata) | |||
|- | |||
| 0x28 || 0x1 || bool, has public.sav (DSiWare only) | |||
|- | |||
| 0x29 || 0x1 || bool, has private.sav (DSiWare only) | |||
|- | |- | ||
| | | 0x2A || 0x1 || bool, has banner.sav (DSiWare only) | ||
| | |||
| | |||
|- | |- | ||
| | | 0x2B || 0x1 || bool, requires moving public/private/banner.new to public/private/banner.sav (DSiWare only) (see [[AMPXI:WriteTWLSavedata]]) | ||
| | |||
| | |||
|- | |- | ||
| | | 0x2C || 0x1 || u8, CMD format version (see [[Titles#Data_Structure|Title Data Structure]]) | ||
| | |||
| Title | |||
|- | |- | ||
| | | 0x2D || 0x1 || bool, is user DSiWare title (as in, does not have system title bit set, see [[Title_list#TWL_(DSi)_Titles|TWL (DSi) Titles]] for more information) | ||
| | |||
| | |||
|- | |- | ||
| | | 0x2E || 0x2 || u16, New3DS update partition content index (even though this is unused because digital titles don't have update partitions) | ||
| | |||
| | |||
|- | |- | ||
| | | 0x30 || 0x10 || Product code (first 12 bytes of raw .nds for DSiWare, which is the game title) | ||
| | |||
| | |||
|- | |- | ||
| | | 0x40 || 0x8 || u64, ordering number. Used in some code paths to find the "latest" added entry, but this value is never written and always 0. | ||
| | |||
| | |||
|- | |- | ||
| | | 0x48 || 0x1 || bool, is temporary (true for DLP child titles added into tmp_i/tmp_t.db) | ||
| | |||
| | |||
|- | |- | ||
| | | 0x49 || 0x1 || u8, [[Application_Manager_Services#ImportTitleContextState|ImportTitleContextState]] | ||
| | |||
| | |||
|- | |- | ||
| | | 0x4A || 0x1 || bool, overwrite (set when reinstalling an existing title) | ||
| | |||
| | |||
|- | |- | ||
| | | 0x4B || 0x1 || Reserved | ||
| | |||
| | |||
|- | |- | ||
| | | 0x4C || 0x4 || Content ID for content index 0, 0xFFFFFFFF if not applicable | ||
| | |||
| | |||
|- | |- | ||
| 0x50 | | 0x50 || 0x4 || u32, random value generated during title installation (See [[CTXT]]) | ||
| 0x4 | |||
| | |||
|- | |- | ||
| 0x54 | | 0x54 || 0x2C || Reserved | ||
| | |||
| Reserved | |||
|} | |} | ||
For ticket.db | === Ticket Info Entry === | ||
For ticket.db entries, there is a header indicates ticket count (as a Title ID can have more than one ticket installed). Then each entry contains the size, followed by the actual ticket data. | |||
{| class="wikitable" | {| class="wikitable" | ||
|+ Header | |+ Header | ||
| Line 231: | Line 227: | ||
| X | | X | ||
| [[Ticket|Ticket]] data | | [[Ticket|Ticket]] data | ||
|} | |} | ||
Latest revision as of 19:27, 27 May 2026
These files contain data relating to install/usage/management of installed 3DS titles. The database files are located at:
- nand/dbs
- sdmc/Nintendo 3DS/<ID0>/<ID1>/dbs
ID0 is the first 0x10-bytes from a SHA256 hash. The installation of SD Card titles was introduced in the 2.0.0-2 update and the SD dbs files are encrypted by the general SD filesystem encryption rule. These files are DIFF containers. These DIFF files do not use external IVFC level 4, so all database data is duplicated in the container. In this page only the inner content of the container is described.
These files are only created on SD (via AM) if they don't exist when the eShop application is starting up, during network init etc (prior to showing the "system update required" dialog).
These files are stored under this directory:
| Stored on SD card | Stored in CTR-NAND | Filename | CTR-9DB0 ID | Description |
|---|---|---|---|---|
| No | Yes | ticket.db | 0x0 | This contains the installed tickets (NAND and SD). |
| No | Yes | certs.db | 0x1 | This contains the certificate chain used to verify TMDs and other certificates. |
| Yes | Yes | title.db | 0x2 | Title database, this contains entries for all installed titles (TWL & CTR) on the 3DS (Each database is responsible for titles installed on its medium). |
| Yes | Yes | import.db | 0x3 | This is an Import Database, it contains entries for titles (or versions of titles) not yet installed, ready for transferring to the title.db. (Automatic Update uses this, so completing the update takes seconds.) |
| No | Yes | tmp_t.db | 0x4 | This is the temporary Title database containing one entry for the currently installed Download Play Child. |
| No | Yes | tmp_i.db | 0x5 | Similar to import.db, except it's used in conjunction with tmp_t.db, for installing Download Play Children. |
The inner content of the container consists of a pre-header with size of 0x80 identifying the Database Type, followed by a BDRI container. The offsets in the BDRI header are usually relative to the offset to the start of the BDRI header (0x80 in the file)
Pre Header
| Start | Length | Description |
|---|---|---|
| 0x00 | 8 | Database Type "Magic" (see below) |
| 0x08 | 0x4 | Version (always 0) |
| 0xC | 0x74 | Reserved |
For ticket.db, a different pre-header is used:
| Start | Length | Description |
|---|---|---|
| 0x00 | 4 | Database Type "Magic" (see below) |
| 0x04 | 0x04 | Version (always 1) |
| 0x08 | 0x08 | Reserved |
Database Magic
| Database Type | Magic |
|---|---|
| CTR-NAND ticket.db | TICK |
| CTR-NAND import.db | NANDIDB |
| CTR-NAND title.db | NANDTDB |
| CTR-NAND tmp_i.db | TEMPIDB |
| CTR-NAND tmp_t.db | TEMPIDB |
| SD Card import.db | TEMPTDB |
| SD Card title.db | TEMPTDB |
| (unused, likely supposed to be SD card import.db) | SDMCIDB |
BDRI
This is a variant of FAT filesystem. It consists one "root" directory and multiple "files". Each "file" is one title info entry described below.
Title Info Entry
An entry contains information taken from both the application NCCH file(s) and TMD.
| Start | Length | Description |
|---|---|---|
| 0x0 | 0x8 | u64, Title Size |
| 0x8 | 0x4 | u32, Title Type from TMD (usually 0x40) |
| 0xC | 0x2 | u16, Title Version |
| 0xE | 0x2 | u16, Content index for Download Play Child content |
| 0x10 | 0x2 | u16, Content index for Instruction Manual content |
| 0x12 | 0x2 | u16, Content index for Old3DS update partition (even though this is unused because digital titles don't have update partitions) |
| 0x14 | 0x4 | TMD file ID (the ID part in {ID}.tmd inside the title folder)
|
| 0x18 | 0x4 | CMD file ID (the ID part in {ID}.cmd inside the title folder)
|
| 0x1C | 0x4 | save file ID (the ID part in {ID}.sav inside the title/data folder)
|
| 0x20 | 0x8 | u64, extdata ID (zero if title does not use extdata) |
| 0x28 | 0x1 | bool, has public.sav (DSiWare only) |
| 0x29 | 0x1 | bool, has private.sav (DSiWare only) |
| 0x2A | 0x1 | bool, has banner.sav (DSiWare only) |
| 0x2B | 0x1 | bool, requires moving public/private/banner.new to public/private/banner.sav (DSiWare only) (see AMPXI:WriteTWLSavedata) |
| 0x2C | 0x1 | u8, CMD format version (see Title Data Structure) |
| 0x2D | 0x1 | bool, is user DSiWare title (as in, does not have system title bit set, see TWL (DSi) Titles for more information) |
| 0x2E | 0x2 | u16, New3DS update partition content index (even though this is unused because digital titles don't have update partitions) |
| 0x30 | 0x10 | Product code (first 12 bytes of raw .nds for DSiWare, which is the game title) |
| 0x40 | 0x8 | u64, ordering number. Used in some code paths to find the "latest" added entry, but this value is never written and always 0. |
| 0x48 | 0x1 | bool, is temporary (true for DLP child titles added into tmp_i/tmp_t.db) |
| 0x49 | 0x1 | u8, ImportTitleContextState |
| 0x4A | 0x1 | bool, overwrite (set when reinstalling an existing title) |
| 0x4B | 0x1 | Reserved |
| 0x4C | 0x4 | Content ID for content index 0, 0xFFFFFFFF if not applicable |
| 0x50 | 0x4 | u32, random value generated during title installation (See CTXT) |
| 0x54 | 0x2C | Reserved |
Ticket Info Entry
For ticket.db entries, there is a header indicates ticket count (as a Title ID can have more than one ticket installed). Then each entry contains the size, followed by the actual ticket data.
| Start | Length | Description |
|---|---|---|
| 0x0 | 4 | Amount of tickets X |
| 0x4 | X * (size of tickets + 4) | Ticket entries |
| Start | Length | Description |
|---|---|---|
| 0x0 | 4 | Ticket data size X (often 0x350 but some DLC tickets may be larger) |
| 0x4 | X | Ticket data |
NOTES:
It is important to note the database doesn't contain a hash of the .cmd. So if a user has more than one valid set of application data for a given .cmd Content ID they can be manually interchanged without issue. Though renaming a .cmd file to match the Content ID which the title.db is expecting will result in an error, as the CTR for the per-console encryption layer changes depending on the file path, and the MAC of the .cmd is probably generated with the .cmd Content ID in mind.
These NAND/SD /dbs images seem to be loaded by the ARM9 while NATIVE_FIRM is booting.
Removing ticket.db from a New-3DS with signature checks disabled will not result in an unbootable system, however all icons except Slot-1 will disappear from Home. Applets can however still be used. Recovery can be accomplished via hardmod or arm9loaderhax plus a known good backup of the file (or the whole partition or disk); Gamecard exploits were not tested, and Browserhax did not work.