https://switchbrew.org/w/api.php?action=feedcontributions&user=The-4n&feedformat=atom
Nintendo Switch Brew - User contributions [en]
2024-03-29T01:38:09Z
User contributions
MediaWiki 1.35.8
https://switchbrew.org/w/index.php?title=NACP&diff=5437
NACP
2018-10-31T16:09:31Z
<p>The-4n: /* Structure */</p>
<hr />
<div>Roughly equivalent to non-gfx areas of 3DS SMDH. All strings for language-entries are UTF-8, unlike SMDH which uses UTF-16.<br />
<br />
Total size is 0x4000-bytes.<br />
<br />
= Structure =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x3000 (0x300*0x10)<br />
| [[#Title Entry|Title entries]]<br />
|-<br />
| 0x3000<br />
| 0x25<br />
| Isbn<br />
|-<br />
| 0x3025<br />
| 0x1<br />
| StartupUserAccount<br />
|-<br />
| 0x3026<br />
| 0x1<br />
| UserAccountSwitchLock<br />
|-<br />
| 0x3027<br />
| 0x1<br />
| AddOnContentRegistrationType<br />
|-<br />
| 0x3028<br />
| 0x4<br />
| ApplicationAttribute<br />
|-<br />
| 0x302C<br />
| 0x4<br />
| SupportedLanguages<br />
|-<br />
| 0x3030<br />
| 0x4<br />
| ParentalControl<br />
|-<br />
| 0x3034<br />
| 0x1<br />
| isScreenshotEnabled<br />
|-<br />
| 0x3035<br />
| 0x1<br />
| [[#VideoCaptureMode]]<br />
|-<br />
| 0x3036<br />
| 0x1<br />
| isDataLossConfirmationEnabled<br />
|-<br />
| 0x3037<br />
| 0x1<br />
| PlayLogPolicy<br />
|-<br />
| 0x3038<br />
| 0x8<br />
| PresenceGroupId<br />
|-<br />
| 0x3040<br />
| 0x20<br />
| RatingAge<br />
|-<br />
| 0x3060<br />
| 0x10<br />
| DisplayVersion<br />
|-<br />
| 0x3070<br />
| 0x8<br />
| AddOnContentBaseId<br />
|-<br />
| 0x3078<br />
| 0x8<br />
| SaveDataOwnerId<br />
|-<br />
| 0x3080<br />
| 0x8<br />
| UserAccountSaveDataSize<br />
|-<br />
| 0x3088<br />
| 0x8<br />
| UserAccountSaveDataJournalSize<br />
|-<br />
| 0x3090<br />
| 0x8<br />
| DeviceSaveDataSize<br />
|-<br />
| 0x3098<br />
| 0x8<br />
| DeviceSaveDataJournalSize<br />
|-<br />
| 0x30A0<br />
| 0x8<br />
| BcatDeliveryCacheStorageSize<br />
|-<br />
| 0x30A8<br />
| 0x8<br />
| ApplicationErrorCodeCategory<br />
|-<br />
| 0x30B0<br />
| 0x40 (0x8*0x8)<br />
| LocalCommunicationIds<br />
|-<br />
| 0x30F0<br />
| 0x1<br />
| LogoType<br />
|-<br />
| 0x30F1<br />
| 0x1<br />
| LogoHandling<br />
|-<br />
| 0x30F2<br />
| 0x1<br />
| isRuntimeAddOnContentInstallEnabled<br />
|-<br />
| 0x30F3<br />
| 0x3<br />
| ?<br />
|-<br />
| 0x30F6<br />
| 0x1<br />
| CrashReport<br />
|-<br />
| 0x30F7<br />
| 0x1<br />
| Hdcp<br />
|-<br />
| 0x30F8<br />
| 0x8<br />
| SeedForPseudoDeviceId<br />
|-<br />
| 0x3100<br />
| 0x41<br />
| [[BCAT_Content_Container|BcatPassphrase]], all-zero when unused.<br />
|-<br />
| 0x3141<br />
| 0x1<br />
| ?<br />
|-<br />
| 0x3142<br />
| 0x6<br />
| ReservedForUserAccountSaveDataOperation<br />
|-<br />
| 0x3148<br />
| 0x8<br />
| UserAccountSaveDataSizeMax<br />
|-<br />
| 0x3150<br />
| 0x8<br />
| UserAccountSaveDataJournalSizeMax<br />
|-<br />
| 0x3158<br />
| 0x8<br />
| DeviceSaveDataSizeMax<br />
|-<br />
| 0x3160<br />
| 0x8<br />
| DeviceSaveDataJournalSizeMax<br />
|-<br />
| 0x3168<br />
| 0x8<br />
| TemporaryStorageSize<br />
|-<br />
| 0x3170<br />
| 0x8<br />
| CacheStorageSize<br />
|-<br />
| 0x3178<br />
| 0x8<br />
| CacheStorageJournalSize<br />
|-<br />
| 0x3180<br />
| 0x8<br />
| CacheStorageDataAndJournalSizeMax<br />
|-<br />
| 0x3188<br />
| 0x8<br />
| CacheStorageIndexMax<br />
|-<br />
| 0x3190<br />
| 0x80 (0x8*0x10)<br />
| PlayLogQueryableApplicationId<br />
|-<br />
| 0x3210<br />
| 0x1<br />
| PlayLogQueryCapability<br />
|-<br />
| 0x3211<br />
| 0x1<br />
| RepairFlag<br />
|-<br />
| 0x3212<br />
| 0x1<br />
| ProgramIndex<br />
|-<br />
| 0x3213<br />
| 0x1<br />
| RequiredNetworkServiceLicenseOnLaunchFlag<br />
|-<br />
| 0x3214<br />
| 0xDEC<br />
| Reserved<br />
|}<br />
<br />
== Title Entry ==<br />
Total size is 0x300-bytes.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x200<br />
| Application name strings<br />
|-<br />
| 0x200<br />
| 0x100<br />
| Application publisher strings<br />
|}<br />
<br />
Entry index for each [[Settings_services#LanguageCode|language]]:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Entry-index || Icon [[NCA_Content_FS#FS-type3|language]] filename<br />
|-<br />
| 0 || "AmericanEnglish"<br />
|-<br />
| 1 || "BritishEnglish"<br />
|-<br />
| 2 || "Japanese"<br />
|-<br />
| 3 || "French"<br />
|-<br />
| 4 || "German"<br />
|-<br />
| 5 || "LatinAmericanSpanish"<br />
|-<br />
| 6 || "Spanish"<br />
|-<br />
| 7 || "Italian"<br />
|-<br />
| 8 || "Dutch"<br />
|-<br />
| 9 || "CanadianFrench"<br />
|-<br />
| 10 || "Portuguese"<br />
|-<br />
| 11 || "Russian"<br />
|-<br />
| 12 || "Korean"<br />
|-<br />
| 13 || "Taiwanese"<br />
|-<br />
| 14 || "Chinese"<br />
|}<br />
<br />
Official apps tend to have the title entries' strings set only to English. Some apps don't have certain title entries set at all. In addition, official apps usually (?) don't have the following title entries set: Korean, Taiwanese, and Chinese.<br />
<br />
== VideoCaptureMode ==<br />
<br />
This is the enum used to determine how gameplay recording can occur, if at all.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Enum Value || Meaning<br />
|-<br />
| 0 || Disabled<br />
|-<br />
| 1 || Enabled<br />
|-<br />
| 2 || Automatic<br />
|-<br />
|}<br />
<br />
When this value is 0, gameplay cannot be recorded. When this value is 1, the game must manually sacrifice some of its heap as transfer memory for AM's IApplicationProxy->InitializeGamePlayRecording(). When this value is 2, AM will call NS->BoostSystemMemoryResourceSize(), and allocate the required memory for recording automatically without the usermode process having to do anything.</div>
The-4n
https://switchbrew.org/w/index.php?title=NACP&diff=5436
NACP
2018-10-31T11:05:07Z
<p>The-4n: /* Structure */</p>
<hr />
<div>Roughly equivalent to non-gfx areas of 3DS SMDH. All strings for language-entries are UTF-8, unlike SMDH which uses UTF-16.<br />
<br />
Total size is 0x4000-bytes.<br />
<br />
= Structure =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x3000 (0x300*0x10)<br />
| [[#Title Entry|Title entries]]<br />
|-<br />
| 0x3000<br />
| 0x25<br />
| Isbn<br />
|-<br />
| 0x3025<br />
| 0x1<br />
| StartupUserAccount<br />
|-<br />
| 0x3026<br />
| 0x1<br />
| UserAccountSwitchLock<br />
|-<br />
| 0x3027<br />
| 0x1<br />
| AddOnContentRegistrationType<br />
|-<br />
| 0x3028<br />
| 0x4<br />
| ApplicationAttribute<br />
|-<br />
| 0x302C<br />
| 0x4<br />
| SupportedLanguages<br />
|-<br />
| 0x3030<br />
| 0x4<br />
| ParentalControl<br />
|-<br />
| 0x3034<br />
| 0x1<br />
| isScreenshotEnabled<br />
|-<br />
| 0x3035<br />
| 0x1<br />
| [[#VideoCaptureMode]]<br />
|-<br />
| 0x3036<br />
| 0x1<br />
| isDataLossConfirmationEnabled<br />
|-<br />
| 0x3037<br />
| 0x1<br />
| PlayLogPolicy<br />
|-<br />
| 0x3038<br />
| 0x8<br />
| PresenceGroupId<br />
|-<br />
| 0x3040<br />
| 0x20<br />
| RatingAge<br />
|-<br />
| 0x3060<br />
| 0x10<br />
| DisplayVersion<br />
|-<br />
| 0x3070<br />
| 0x8<br />
| AddOnContentBaseId<br />
|-<br />
| 0x3078<br />
| 0x8<br />
| SaveDataOwnerId<br />
|-<br />
| 0x3080<br />
| 0x8<br />
| UserAccountSaveDataSize<br />
|-<br />
| 0x3088<br />
| 0x8<br />
| UserAccountSaveDataJournalSize<br />
|-<br />
| 0x3090<br />
| 0x8<br />
| DeviceSaveDataSize<br />
|-<br />
| 0x3098<br />
| 0x8<br />
| DeviceSaveDataJournalSize<br />
|-<br />
| 0x30A0<br />
| 0x8<br />
| BcatDeliveryCacheStorageSize<br />
|-<br />
| 0x30A8<br />
| 0x8<br />
| ApplicationErrorCodeCategory<br />
|-<br />
| 0x30B0<br />
| 0x40 (0x8*0x8)<br />
| LocalCommunicationIds<br />
|-<br />
| 0x30F0<br />
| 0x1<br />
| LogoType<br />
|-<br />
| 0x30F1<br />
| 0x1<br />
| LogoHandling<br />
|-<br />
| 0x30F2<br />
| 0x1<br />
| isRuntimeAddOnContentInstallEnabled<br />
|-<br />
| 0x30F3<br />
| 0x3<br />
| ?<br />
|-<br />
| 0x30F6<br />
| 0x1<br />
| CrashReport<br />
|-<br />
| 0x30F7<br />
| 0x1<br />
| Hdcp<br />
|-<br />
| 0x30F8<br />
| 0x8<br />
| SeedForPseudoDeviceId<br />
|-<br />
| 0x3100<br />
| 0x41<br />
| [[BCAT_Content_Container|BcatPassphrase]], all-zero when unused.<br />
|-<br />
| 0x3141<br />
| 0x1<br />
| ?<br />
|-<br />
| 0x3142<br />
| 0x6<br />
| ReservedForUserAccountSaveDataOperation<br />
|-<br />
| 0x3148<br />
| 0x8<br />
| UserAccountSaveDataSizeMax<br />
|-<br />
| 0x3150<br />
| 0x8<br />
| UserAccountSaveDataJournalSizeMax<br />
|-<br />
| 0x3158<br />
| 0x8<br />
| DeviceSaveDataSizeMax<br />
|-<br />
| 0x3160<br />
| 0x8<br />
| DeviceSaveDataJournalSizeMax<br />
|-<br />
| 0x3168<br />
| 0x8<br />
| TemporaryStorageSize<br />
|-<br />
| 0x3170<br />
| 0x8<br />
| CacheStorageSize<br />
|-<br />
| 0x3178<br />
| 0x8<br />
| CacheStorageJournalSize<br />
|-<br />
| 0x3180<br />
| 0x8<br />
| CacheStorageDataAndJournalSizeMax<br />
|-<br />
| 0x3188<br />
| 0x8<br />
| CacheStorageIndexMax<br />
|-<br />
| 0x3190<br />
| 0x80 (0x8*0x10)<br />
| PlayLogQueryableApplicationId<br />
|-<br />
| 0x3210<br />
| 0x1<br />
| PlayLogQueryCapability<br />
|-<br />
| 0x3211<br />
| 0x1<br />
| RepairFlag<br />
|-<br />
| 0x3212<br />
| 0x1<br />
| ProgramIndex<br />
|-<br />
| 0x3213<br />
| 0x1<br />
| RequiredNetworkServiceLicenseOnLaunchFlag<br />
|-<br />
| 0x3214<br />
| 0xEC<br />
| Reserved<br />
|}<br />
<br />
== Title Entry ==<br />
Total size is 0x300-bytes.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x200<br />
| Application name strings<br />
|-<br />
| 0x200<br />
| 0x100<br />
| Application publisher strings<br />
|}<br />
<br />
Entry index for each [[Settings_services#LanguageCode|language]]:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Entry-index || Icon [[NCA_Content_FS#FS-type3|language]] filename<br />
|-<br />
| 0 || "AmericanEnglish"<br />
|-<br />
| 1 || "BritishEnglish"<br />
|-<br />
| 2 || "Japanese"<br />
|-<br />
| 3 || "French"<br />
|-<br />
| 4 || "German"<br />
|-<br />
| 5 || "LatinAmericanSpanish"<br />
|-<br />
| 6 || "Spanish"<br />
|-<br />
| 7 || "Italian"<br />
|-<br />
| 8 || "Dutch"<br />
|-<br />
| 9 || "CanadianFrench"<br />
|-<br />
| 10 || "Portuguese"<br />
|-<br />
| 11 || "Russian"<br />
|-<br />
| 12 || "Korean"<br />
|-<br />
| 13 || "Taiwanese"<br />
|-<br />
| 14 || "Chinese"<br />
|}<br />
<br />
Official apps tend to have the title entries' strings set only to English. Some apps don't have certain title entries set at all. In addition, official apps usually (?) don't have the following title entries set: Korean, Taiwanese, and Chinese.<br />
<br />
== VideoCaptureMode ==<br />
<br />
This is the enum used to determine how gameplay recording can occur, if at all.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Enum Value || Meaning<br />
|-<br />
| 0 || Disabled<br />
|-<br />
| 1 || Enabled<br />
|-<br />
| 2 || Automatic<br />
|-<br />
|}<br />
<br />
When this value is 0, gameplay cannot be recorded. When this value is 1, the game must manually sacrifice some of its heap as transfer memory for AM's IApplicationProxy->InitializeGamePlayRecording(). When this value is 2, AM will call NS->BoostSystemMemoryResourceSize(), and allocate the required memory for recording automatically without the usermode process having to do anything.</div>
The-4n
https://switchbrew.org/w/index.php?title=NACP&diff=5435
NACP
2018-10-31T11:01:37Z
<p>The-4n: /* Structure */</p>
<hr />
<div>Roughly equivalent to non-gfx areas of 3DS SMDH. All strings for language-entries are UTF-8, unlike SMDH which uses UTF-16.<br />
<br />
Total size is 0x4000-bytes.<br />
<br />
= Structure =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x3000 (0x300*0x10)<br />
| [[#Title Entry|Title entries]]<br />
|-<br />
| 0x3000<br />
| 0x25<br />
| Isbn<br />
|-<br />
| 0x3025<br />
| 0x1<br />
| StartupUserAccount<br />
|-<br />
| 0x3026<br />
| 0x1<br />
| UserAccountSwitchLock<br />
|-<br />
| 0x3027<br />
| 0x1<br />
| AddOnContentRegistrationType<br />
|-<br />
| 0x3028<br />
| 0x4<br />
| ApplicationAttribute<br />
|-<br />
| 0x302C<br />
| 0x4<br />
| SupportedLanguages<br />
|-<br />
| 0x3030<br />
| 0x4<br />
| ParentalControl<br />
|-<br />
| 0x3034<br />
| 0x1<br />
| isScreenshotEnabled<br />
|-<br />
| 0x3035<br />
| 0x1<br />
| [[#VideoCaptureMode]]<br />
|-<br />
| 0x3036<br />
| 0x1<br />
| isDataLossConfirmationEnabled<br />
|-<br />
| 0x3037<br />
| 0x1<br />
| PlayLogPolicy<br />
|-<br />
| 0x3038<br />
| 0x8<br />
| PresenceGroupId<br />
|-<br />
| 0x3040<br />
| 0x20<br />
| RatingAge<br />
|-<br />
| 0x3060<br />
| 0x10<br />
| DisplayVersion<br />
|-<br />
| 0x3070<br />
| 0x8<br />
| AddOnContentBaseId<br />
|-<br />
| 0x3078<br />
| 0x8<br />
| SaveDataOwnerId<br />
|-<br />
| 0x3080<br />
| 0x8<br />
| UserAccountSaveDataSize<br />
|-<br />
| 0x3088<br />
| 0x8<br />
| UserAccountSaveDataJournalSize<br />
|-<br />
| 0x3090<br />
| 0x8<br />
| DeviceSaveDataSize<br />
|-<br />
| 0x3098<br />
| 0x8<br />
| DeviceSaveDataJournalSize<br />
|-<br />
| 0x30A0<br />
| 0x8<br />
| BcatDeliveryCacheStorageSize<br />
|-<br />
| 0x30A8<br />
| 0x8<br />
| ApplicationErrorCodeCategory<br />
|-<br />
| 0x30B0<br />
| 0x40 (0x8*0x8)<br />
| LocalCommunicationIds<br />
|-<br />
| 0x30F0<br />
| 0x1<br />
| LogoType<br />
|-<br />
| 0x30F1<br />
| 0x1<br />
| LogoHandling<br />
|-<br />
| 0x30F2<br />
| 0x1<br />
| isRuntimeAddOnContentInstallEnabled<br />
|-<br />
| 0x30F3<br />
| 0x3<br />
| ?<br />
|-<br />
| 0x30F6<br />
| 0x1<br />
| CrashReport<br />
|-<br />
| 0x30F7<br />
| 0x1<br />
| Hdcp<br />
|-<br />
| 0x30F8<br />
| 0x8<br />
| SeedForPseudoDeviceId<br />
|-<br />
| 0x3100<br />
| 0x41<br />
| [[BCAT_Content_Container|BcatPassphrase]], all-zero when unused.<br />
|-<br />
| 0x3141<br />
| 0x1<br />
| ?<br />
|-<br />
| 0x3142<br />
| 0x6<br />
| ReservedForUserAccountSaveDataOperation<br />
|-<br />
| 0x3148<br />
| 0x8<br />
| UserAccountSaveDataSizeMax<br />
|-<br />
| 0x3150<br />
| 0x8<br />
| UserAccountSaveDataJournalSizeMax<br />
|-<br />
| 0x3158<br />
| 0x8<br />
| DeviceSaveDataSizeMax<br />
|-<br />
| 0x3160<br />
| 0x8<br />
| DeviceSaveDataJournalSizeMax<br />
|-<br />
| 0x3168<br />
| 0x8<br />
| TemporaryStorageSize<br />
|-<br />
| 0x3170<br />
| 0x8<br />
| CacheStorageSize<br />
|-<br />
| 0x3178<br />
| 0x8<br />
| CacheStorageJournalSize<br />
|-<br />
| 0x3180<br />
| 0x8<br />
| CacheStorageDataAndJournalSizeMax<br />
|-<br />
| 0x3188<br />
| 0x8<br />
| CacheStorageIndexMax<br />
|-<br />
| 0x3190<br />
| 0x80 (0x8 * 0x10)<br />
| PlayLogQueryableApplicationId<br />
|-<br />
| 0x3210<br />
| 0x1<br />
| PlayLogQueryCapability<br />
|-<br />
| 0x3211<br />
| 0x1<br />
| RepairFlag<br />
|-<br />
| 0x3212<br />
| 0x1<br />
| ProgramIndex<br />
|-<br />
| 0x3213<br />
| 0x1<br />
| RequiredNetworkServiceLicenseOnLaunchFlag<br />
|-<br />
| 0x3214<br />
| 0xEC<br />
| Reserved<br />
|}<br />
<br />
== Title Entry ==<br />
Total size is 0x300-bytes.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x200<br />
| Application name strings<br />
|-<br />
| 0x200<br />
| 0x100<br />
| Application publisher strings<br />
|}<br />
<br />
Entry index for each [[Settings_services#LanguageCode|language]]:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Entry-index || Icon [[NCA_Content_FS#FS-type3|language]] filename<br />
|-<br />
| 0 || "AmericanEnglish"<br />
|-<br />
| 1 || "BritishEnglish"<br />
|-<br />
| 2 || "Japanese"<br />
|-<br />
| 3 || "French"<br />
|-<br />
| 4 || "German"<br />
|-<br />
| 5 || "LatinAmericanSpanish"<br />
|-<br />
| 6 || "Spanish"<br />
|-<br />
| 7 || "Italian"<br />
|-<br />
| 8 || "Dutch"<br />
|-<br />
| 9 || "CanadianFrench"<br />
|-<br />
| 10 || "Portuguese"<br />
|-<br />
| 11 || "Russian"<br />
|-<br />
| 12 || "Korean"<br />
|-<br />
| 13 || "Taiwanese"<br />
|-<br />
| 14 || "Chinese"<br />
|}<br />
<br />
Official apps tend to have the title entries' strings set only to English. Some apps don't have certain title entries set at all. In addition, official apps usually (?) don't have the following title entries set: Korean, Taiwanese, and Chinese.<br />
<br />
== VideoCaptureMode ==<br />
<br />
This is the enum used to determine how gameplay recording can occur, if at all.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Enum Value || Meaning<br />
|-<br />
| 0 || Disabled<br />
|-<br />
| 1 || Enabled<br />
|-<br />
| 2 || Automatic<br />
|-<br />
|}<br />
<br />
When this value is 0, gameplay cannot be recorded. When this value is 1, the game must manually sacrifice some of its heap as transfer memory for AM's IApplicationProxy->InitializeGamePlayRecording(). When this value is 2, AM will call NS->BoostSystemMemoryResourceSize(), and allocate the required memory for recording automatically without the usermode process having to do anything.</div>
The-4n
https://switchbrew.org/w/index.php?title=NACP&diff=5434
NACP
2018-10-31T10:56:54Z
<p>The-4n: /* Structure */</p>
<hr />
<div>Roughly equivalent to non-gfx areas of 3DS SMDH. All strings for language-entries are UTF-8, unlike SMDH which uses UTF-16.<br />
<br />
Total size is 0x4000-bytes.<br />
<br />
= Structure =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x3000 (0x300*0x10)<br />
| [[#Title Entry|Title entries]]<br />
|-<br />
| 0x3000<br />
| 0x25<br />
| Isbn<br />
|-<br />
| 0x3025<br />
| 0x1<br />
| StartupUserAccount<br />
|-<br />
| 0x3026<br />
| 0x1<br />
| UserAccountSwitchLock<br />
|-<br />
| 0x3027<br />
| 0x1<br />
| AddOnContentRegistrationType<br />
|-<br />
| 0x3028<br />
| 0x4<br />
| ApplicationAttribute<br />
|-<br />
| 0x302C<br />
| 0x4<br />
| SupportedLanguages<br />
|-<br />
| 0x3030<br />
| 0x4<br />
| ParentalControl<br />
|-<br />
| 0x3034<br />
| 0x1<br />
| isScreenshotEnabled<br />
|-<br />
| 0x3035<br />
| 0x1<br />
| [[#VideoCaptureMode]]<br />
|-<br />
| 0x3036<br />
| 0x1<br />
| isDataLossConfirmationEnabled<br />
|-<br />
| 0x3037<br />
| 0x1<br />
| PlayLogPolicy<br />
|-<br />
| 0x3038<br />
| 0x8<br />
| PresenceGroupId<br />
|-<br />
| 0x3040<br />
| 0x20<br />
| RatingAge<br />
|-<br />
| 0x3060<br />
| 0x10<br />
| DisplayVersion<br />
|-<br />
| 0x3070<br />
| 0x8<br />
| AddOnContentBaseId<br />
|-<br />
| 0x3078<br />
| 0x8<br />
| SaveDataOwnerId<br />
|-<br />
| 0x3080<br />
| 0x8<br />
| UserAccountSaveDataSize<br />
|-<br />
| 0x3088<br />
| 0x8<br />
| UserAccountSaveDataJournalSize<br />
|-<br />
| 0x3090<br />
| 0x8<br />
| DeviceSaveDataSize<br />
|-<br />
| 0x3098<br />
| 0x8<br />
| DeviceSaveDataJournalSize<br />
|-<br />
| 0x30A0<br />
| 0x8<br />
| BcatDeliveryCacheStorageSize<br />
|-<br />
| 0x30A8<br />
| 0x8<br />
| ApplicationErrorCodeCategory<br />
|-<br />
| 0x30B0<br />
| 0x40 (0x8*0x8)<br />
| LocalCommunicationIds<br />
|-<br />
| 0x30F0<br />
| 0x1<br />
| LogoType<br />
|-<br />
| 0x30F1<br />
| 0x1<br />
| LogoHandling<br />
|-<br />
| 0x30F2<br />
| 0x1<br />
| isRuntimeAddOnContentInstallEnabled<br />
|-<br />
| 0x30F3<br />
| 0x3<br />
| ?<br />
|-<br />
| 0x30F6<br />
| 0x1<br />
| CrashReport<br />
|-<br />
| 0x30F7<br />
| 0x1<br />
| Hdcp<br />
|-<br />
| 0x30F8<br />
| 0x8<br />
| SeedForPseudoDeviceId<br />
|-<br />
| 0x3100<br />
| 0x41<br />
| [[BCAT_Content_Container|BcatPassphrase]], all-zero when unused.<br />
|-<br />
| 0x3141<br />
| 0x1<br />
| ?<br />
|-<br />
| 0x3142<br />
| 0x6<br />
| ReservedForUserAccountSaveDataOperation<br />
|-<br />
| 0x3148<br />
| 0x8<br />
| UserAccountSaveDataSizeMax<br />
|-<br />
| 0x3150<br />
| 0x8<br />
| UserAccountSaveDataJournalSizeMax<br />
|-<br />
| 0x3158<br />
| 0x8<br />
| DeviceSaveDataSizeMax<br />
|-<br />
| 0x3160<br />
| 0x8<br />
| DeviceSaveDataJournalSizeMax<br />
|-<br />
| 0x3168<br />
| 0x8<br />
| TemporaryStorageSize<br />
|-<br />
| 0x3170<br />
| 0x8<br />
| CacheStorageSize<br />
|-<br />
| 0x3178<br />
| 0x8<br />
| CacheStorageJournalSize<br />
|-<br />
| 0x3180<br />
| 0xE80<br />
| CacheStorageDataAndJournalSizeMax<br />
|}<br />
<br />
== Title Entry ==<br />
Total size is 0x300-bytes.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x200<br />
| Application name strings<br />
|-<br />
| 0x200<br />
| 0x100<br />
| Application publisher strings<br />
|}<br />
<br />
Entry index for each [[Settings_services#LanguageCode|language]]:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Entry-index || Icon [[NCA_Content_FS#FS-type3|language]] filename<br />
|-<br />
| 0 || "AmericanEnglish"<br />
|-<br />
| 1 || "BritishEnglish"<br />
|-<br />
| 2 || "Japanese"<br />
|-<br />
| 3 || "French"<br />
|-<br />
| 4 || "German"<br />
|-<br />
| 5 || "LatinAmericanSpanish"<br />
|-<br />
| 6 || "Spanish"<br />
|-<br />
| 7 || "Italian"<br />
|-<br />
| 8 || "Dutch"<br />
|-<br />
| 9 || "CanadianFrench"<br />
|-<br />
| 10 || "Portuguese"<br />
|-<br />
| 11 || "Russian"<br />
|-<br />
| 12 || "Korean"<br />
|-<br />
| 13 || "Taiwanese"<br />
|-<br />
| 14 || "Chinese"<br />
|}<br />
<br />
Official apps tend to have the title entries' strings set only to English. Some apps don't have certain title entries set at all. In addition, official apps usually (?) don't have the following title entries set: Korean, Taiwanese, and Chinese.<br />
<br />
== VideoCaptureMode ==<br />
<br />
This is the enum used to determine how gameplay recording can occur, if at all.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Enum Value || Meaning<br />
|-<br />
| 0 || Disabled<br />
|-<br />
| 1 || Enabled<br />
|-<br />
| 2 || Automatic<br />
|-<br />
|}<br />
<br />
When this value is 0, gameplay cannot be recorded. When this value is 1, the game must manually sacrifice some of its heap as transfer memory for AM's IApplicationProxy->InitializeGamePlayRecording(). When this value is 2, AM will call NS->BoostSystemMemoryResourceSize(), and allocate the required memory for recording automatically without the usermode process having to do anything.</div>
The-4n
https://switchbrew.org/w/index.php?title=NACP&diff=5433
NACP
2018-10-31T10:55:13Z
<p>The-4n: /* Structure */</p>
<hr />
<div>Roughly equivalent to non-gfx areas of 3DS SMDH. All strings for language-entries are UTF-8, unlike SMDH which uses UTF-16.<br />
<br />
Total size is 0x4000-bytes.<br />
<br />
= Structure =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x3000 (0x300*0x10)<br />
| [[#Title Entry|Title entries]]<br />
|-<br />
| 0x3000<br />
| 0x25<br />
| Isbn<br />
|-<br />
| 0x3025<br />
| 0x1<br />
| StartupUserAccount<br />
|-<br />
| 0x3026<br />
| 0x1<br />
| UserAccountSwitchLock<br />
|-<br />
| 0x3027<br />
| 0x1<br />
| AddOnContentRegistrationType<br />
|-<br />
| 0x3028<br />
| 0x4<br />
| ApplicationAttribute<br />
|-<br />
| 0x302C<br />
| 0x4<br />
| SupportedLanguages<br />
|-<br />
| 0x3030<br />
| 0x4<br />
| ParentalControl<br />
|-<br />
| 0x3034<br />
| 0x1<br />
| isScreenshotEnabled<br />
|-<br />
| 0x3035<br />
| 0x1<br />
| [[#VideoCaptureMode]]<br />
|-<br />
| 0x3036<br />
| 0x1<br />
| isDataLossConfirmationEnabled<br />
|-<br />
| 0x3037<br />
| 0x1<br />
| PlayLogPolicy<br />
|-<br />
| 0x3038<br />
| 0x8<br />
| PresenceGroupId<br />
|-<br />
| 0x3040<br />
| 0x20<br />
| RatingAge<br />
|-<br />
| 0x3060<br />
| 0x10<br />
| DisplayVersion<br />
|-<br />
| 0x3070<br />
| 0x8<br />
| AddOnContentBaseId<br />
|-<br />
| 0x3078<br />
| 0x8<br />
| SaveDataOwnerId<br />
|-<br />
| 0x3080<br />
| 0x8<br />
| UserAccountSaveDataSize<br />
|-<br />
| 0x3088<br />
| 0x8<br />
| UserAccountSaveDataJournalSize<br />
|-<br />
| 0x3090<br />
| 0x8<br />
| DeviceSaveDataSize<br />
|-<br />
| 0x3098<br />
| 0x8<br />
| DeviceSaveDataJournalSize<br />
|-<br />
| 0x30A0<br />
| 0x8<br />
| BcatDeliveryCacheStorageSize<br />
|-<br />
| 0x30A8<br />
| 0x8<br />
| ApplicationErrorCodeCategory<br />
|-<br />
| 0x30B0<br />
| 0x40 (0x8*0x8)<br />
| LocalCommunicationIds<br />
|-<br />
| 0x30F0<br />
| 0x1<br />
| LogoType<br />
|-<br />
| 0x30F1<br />
| 0x1<br />
| LogoHandling<br />
|-<br />
| 0x30F2<br />
| 0x1<br />
| isRuntimeAddOnContentInstallEnabled<br />
|-<br />
| 0x30F3<br />
| 0x3<br />
| ?<br />
|-<br />
| 0x30F6<br />
| 0x1<br />
| CrashReport<br />
|-<br />
| 0x30F7<br />
| 0x1<br />
| Hdcp<br />
|-<br />
| 0x30F8<br />
| 0x8<br />
| SeedForPseudoDeviceId<br />
|-<br />
| 0x3100<br />
| 0x41<br />
| [[BCAT_Content_Container|BcatPassphrase]], all-zero when unused.<br />
|-<br />
| 0x3141<br />
| 0x1<br />
| ?<br />
|-<br />
| 0x3142<br />
| 0x6<br />
| ReservedForUserAccountSaveDataOperation<br />
|-<br />
| 0x3148<br />
| 0x8<br />
| UserAccountSaveDataSizeMax<br />
|-<br />
| 0x3150<br />
| 0x8<br />
| UserAccountSaveDataJournalSizeMax<br />
|-<br />
| 0x3158<br />
| 0x8<br />
| DeviceSaveDataSizeMax<br />
|-<br />
| 0x3160<br />
| 0x8<br />
| DeviceSaveDataJournalSizeMax<br />
|-<br />
| 0x3168<br />
| 0x8<br />
| TemporaryStorageSize<br />
|-<br />
| 0x3170<br />
| 0x8<br />
| ?<br />
|-<br />
| 0x3178<br />
| 0x8<br />
| CacheStorageSize<br />
|-<br />
| 0x3180<br />
| 0xE80<br />
| ?<br />
|}<br />
<br />
== Title Entry ==<br />
Total size is 0x300-bytes.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x200<br />
| Application name strings<br />
|-<br />
| 0x200<br />
| 0x100<br />
| Application publisher strings<br />
|}<br />
<br />
Entry index for each [[Settings_services#LanguageCode|language]]:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Entry-index || Icon [[NCA_Content_FS#FS-type3|language]] filename<br />
|-<br />
| 0 || "AmericanEnglish"<br />
|-<br />
| 1 || "BritishEnglish"<br />
|-<br />
| 2 || "Japanese"<br />
|-<br />
| 3 || "French"<br />
|-<br />
| 4 || "German"<br />
|-<br />
| 5 || "LatinAmericanSpanish"<br />
|-<br />
| 6 || "Spanish"<br />
|-<br />
| 7 || "Italian"<br />
|-<br />
| 8 || "Dutch"<br />
|-<br />
| 9 || "CanadianFrench"<br />
|-<br />
| 10 || "Portuguese"<br />
|-<br />
| 11 || "Russian"<br />
|-<br />
| 12 || "Korean"<br />
|-<br />
| 13 || "Taiwanese"<br />
|-<br />
| 14 || "Chinese"<br />
|}<br />
<br />
Official apps tend to have the title entries' strings set only to English. Some apps don't have certain title entries set at all. In addition, official apps usually (?) don't have the following title entries set: Korean, Taiwanese, and Chinese.<br />
<br />
== VideoCaptureMode ==<br />
<br />
This is the enum used to determine how gameplay recording can occur, if at all.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Enum Value || Meaning<br />
|-<br />
| 0 || Disabled<br />
|-<br />
| 1 || Enabled<br />
|-<br />
| 2 || Automatic<br />
|-<br />
|}<br />
<br />
When this value is 0, gameplay cannot be recorded. When this value is 1, the game must manually sacrifice some of its heap as transfer memory for AM's IApplicationProxy->InitializeGamePlayRecording(). When this value is 2, AM will call NS->BoostSystemMemoryResourceSize(), and allocate the required memory for recording automatically without the usermode process having to do anything.</div>
The-4n
https://switchbrew.org/w/index.php?title=NACP&diff=5432
NACP
2018-10-31T10:54:32Z
<p>The-4n: </p>
<hr />
<div>Roughly equivalent to non-gfx areas of 3DS SMDH. All strings for language-entries are UTF-8, unlike SMDH which uses UTF-16.<br />
<br />
Total size is 0x4000-bytes.<br />
<br />
= Structure =<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x3000 (0x300*0x10)<br />
| [[#Title Entry|Title entries]]<br />
|-<br />
| 0x3000<br />
| 0x25<br />
| Isbn<br />
|-<br />
| 0x3025<br />
| 0x1<br />
| StartupUserAccount<br />
|-<br />
| 0x3026<br />
| 0x1<br />
| ?<br />
|-<br />
| 0x3027<br />
| 0x1<br />
| ?<br />
|-<br />
| 0x3028<br />
| 0x4<br />
| ApplicationAttribute<br />
|-<br />
| 0x302C<br />
| 0x4<br />
| SupportedLanguages<br />
|-<br />
| 0x3030<br />
| 0x4<br />
| ParentalControl<br />
|-<br />
| 0x3034<br />
| 0x1<br />
| isScreenshotEnabled<br />
|-<br />
| 0x3035<br />
| 0x1<br />
| [[#VideoCaptureMode]]<br />
|-<br />
| 0x3036<br />
| 0x1<br />
| isDataLossConfirmationEnabled<br />
|-<br />
| 0x3037<br />
| 0x1<br />
| PlayLogPolicy<br />
|-<br />
| 0x3038<br />
| 0x8<br />
| PresenceGroupId<br />
|-<br />
| 0x3040<br />
| 0x20<br />
| RatingAge<br />
|-<br />
| 0x3060<br />
| 0x10<br />
| DisplayVersion<br />
|-<br />
| 0x3070<br />
| 0x8<br />
| AddOnContentBaseId<br />
|-<br />
| 0x3078<br />
| 0x8<br />
| SaveDataOwnerId<br />
|-<br />
| 0x3080<br />
| 0x8<br />
| UserAccountSaveDataSize<br />
|-<br />
| 0x3088<br />
| 0x8<br />
| UserAccountSaveDataJournalSize<br />
|-<br />
| 0x3090<br />
| 0x8<br />
| DeviceSaveDataSize<br />
|-<br />
| 0x3098<br />
| 0x8<br />
| DeviceSaveDataJournalSize<br />
|-<br />
| 0x30A0<br />
| 0x8<br />
| BcatDeliveryCacheStorageSize<br />
|-<br />
| 0x30A8<br />
| 0x8<br />
| ApplicationErrorCodeCategory<br />
|-<br />
| 0x30B0<br />
| 0x40 (0x8*0x8)<br />
| LocalCommunicationIds<br />
|-<br />
| 0x30F0<br />
| 0x1<br />
| LogoType<br />
|-<br />
| 0x30F1<br />
| 0x1<br />
| LogoHandling<br />
|-<br />
| 0x30F2<br />
| 0x1<br />
| isRuntimeAddOnContentInstallEnabled<br />
|-<br />
| 0x30F3<br />
| 0x3<br />
| ?<br />
|-<br />
| 0x30F6<br />
| 0x1<br />
| CrashReport<br />
|-<br />
| 0x30F7<br />
| 0x1<br />
| Hdcp<br />
|-<br />
| 0x30F8<br />
| 0x8<br />
| SeedForPseudoDeviceId<br />
|-<br />
| 0x3100<br />
| 0x41<br />
| [[BCAT_Content_Container|BcatPassphrase]], all-zero when unused.<br />
|-<br />
| 0x3141<br />
| 0x1<br />
| ?<br />
|-<br />
| 0x3142<br />
| 0x6<br />
| ReservedForUserAccountSaveDataOperation<br />
|-<br />
| 0x3148<br />
| 0x8<br />
| UserAccountSaveDataSizeMax<br />
|-<br />
| 0x3150<br />
| 0x8<br />
| UserAccountSaveDataJournalSizeMax<br />
|-<br />
| 0x3158<br />
| 0x8<br />
| DeviceSaveDataSizeMax<br />
|-<br />
| 0x3160<br />
| 0x8<br />
| DeviceSaveDataJournalSizeMax<br />
|-<br />
| 0x3168<br />
| 0x8<br />
| TemporaryStorageSize<br />
|-<br />
| 0x3170<br />
| 0x8<br />
| ?<br />
|-<br />
| 0x3178<br />
| 0x8<br />
| CacheStorageSize<br />
|-<br />
| 0x3180<br />
| 0xE80<br />
| ?<br />
|}<br />
<br />
== Title Entry ==<br />
Total size is 0x300-bytes.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x200<br />
| Application name strings<br />
|-<br />
| 0x200<br />
| 0x100<br />
| Application publisher strings<br />
|}<br />
<br />
Entry index for each [[Settings_services#LanguageCode|language]]:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Entry-index || Icon [[NCA_Content_FS#FS-type3|language]] filename<br />
|-<br />
| 0 || "AmericanEnglish"<br />
|-<br />
| 1 || "BritishEnglish"<br />
|-<br />
| 2 || "Japanese"<br />
|-<br />
| 3 || "French"<br />
|-<br />
| 4 || "German"<br />
|-<br />
| 5 || "LatinAmericanSpanish"<br />
|-<br />
| 6 || "Spanish"<br />
|-<br />
| 7 || "Italian"<br />
|-<br />
| 8 || "Dutch"<br />
|-<br />
| 9 || "CanadianFrench"<br />
|-<br />
| 10 || "Portuguese"<br />
|-<br />
| 11 || "Russian"<br />
|-<br />
| 12 || "Korean"<br />
|-<br />
| 13 || "Taiwanese"<br />
|-<br />
| 14 || "Chinese"<br />
|}<br />
<br />
Official apps tend to have the title entries' strings set only to English. Some apps don't have certain title entries set at all. In addition, official apps usually (?) don't have the following title entries set: Korean, Taiwanese, and Chinese.<br />
<br />
== VideoCaptureMode ==<br />
<br />
This is the enum used to determine how gameplay recording can occur, if at all.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Enum Value || Meaning<br />
|-<br />
| 0 || Disabled<br />
|-<br />
| 1 || Enabled<br />
|-<br />
| 2 || Automatic<br />
|-<br />
|}<br />
<br />
When this value is 0, gameplay cannot be recorded. When this value is 1, the game must manually sacrifice some of its heap as transfer memory for AM's IApplicationProxy->InitializeGamePlayRecording(). When this value is 2, AM will call NS->BoostSystemMemoryResourceSize(), and allocate the required memory for recording automatically without the usermode process having to do anything.</div>
The-4n
https://switchbrew.org/w/index.php?title=CNMT&diff=5294
CNMT
2018-10-23T07:22:31Z
<p>The-4n: </p>
<hr />
<div>For the content of the NCA FS which can be [[Filesystem_services|mounted]], see [[NCA_Content_FS|here]].<br />
<br />
For the format of the actual NCA, see [[NCA_Format|here]].<br />
<br />
= Metadata file =<br />
This is the file that ends in <code>".cnmt{.nca}"</code> or <code>"meta0.ncd"</code>. This seems to replace the TMD format.<br />
<br />
There's at least 9 different filenames used for ".cnmt":<br />
* "Application_{lower-case hex titleID}.cnmt"<br />
* "Patch_{lower-case hex titleID}.cnmt"<br />
* "AddOnContent_{lower-case hex titleID}.cnmt"<br />
* "SystemUpdate_{hex titleID}.cnmt"<br />
* "SystemData_{lower-case hex titleID}.cnmt"<br />
* "SystemProgram_{lower-case hex titleID}.cnmt"<br />
* "BootImagePackage_{lower-case hex titleID}.cnmt"<br />
* "BootImagePackageSafe_{lower-case hex titleID}.cnmt"<br />
* "Delta_{lower-case hex titleID}.cnmt"<br />
<br />
It starts with a header:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 8<br />
| Title ID<br />
|-<br />
| 0x8<br />
| 4<br />
| u32 [[Title_list|title-version]]<br />
|-<br />
| 0xC<br />
| 1<br />
| Type (see [[NCM_services#Title_Types|Title Types]])<br />
|-<br />
| 0xD<br />
| 1<br />
|<br />
|-<br />
| 0xE<br />
| 2<br />
| Offset to table relative to the end of this 0x20-byte header.<br />
|-<br />
| 0x10<br />
| 2<br />
| Number of content entries<br />
|-<br />
| 0x12<br />
| 2<br />
| Number of meta entries<br />
|-<br />
| 0x14<br />
| 12<br />
|<br />
|}<br />
<br />
With SystemUpdate, the 4-bytes at offset 0xE are zero, with the entry-count field located at offset 0x12 instead(header size is the same).<br />
<br />
An optional header can follow, depending on the title type.<br />
<br />
At the end of the file following the entries is a 0x20-byte block, presumably a hash.<br />
<br />
With Patch-format, there's additional data after the end of the entries specified in the header and before the ending hash.<br />
<br />
== Application header ==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x20<br />
| 8<br />
| Patch Title ID<br />
|-<br />
| 0x28<br />
| 8<br />
| Minimum system version<br />
|}<br />
<br />
== Patch header ==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x20<br />
| 8<br />
| Original title ID<br />
|-<br />
| 0x28<br />
| 8<br />
| Minimum system version<br />
|}<br />
<br />
== Add-on content header ==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x20<br />
| 8<br />
| Application title ID<br />
|-<br />
| 0x28<br />
| 8<br />
| Minimum application version<br />
|}<br />
<br />
== Content records ==<br />
<br />
Each entry is 0x38 bytes:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 32<br />
| Hash<br />
|-<br />
| 0x20<br />
| 16<br />
| NcaId [same as first 16-bytes of hash]<br />
|-<br />
| 0x30<br />
| 6<br />
| Size, same as the output from [[Content_Manager_services#GetEntrySize]].<br />
|-<br />
| 0x36<br />
| 1<br />
| Type (0=Meta, 1=Program, 2=Data, 3=Control, 4=[[Internet_Browser|HtmlDocument]], 5=[[Internet_Browser|LegalInformation]], 6=[[NCA_Format|DeltaFragment]])<br />
|-<br />
| 0x37<br />
| 1<br />
|<br />
|}<br />
<br />
== Meta records ==<br />
<br />
Each entry is 0x10 bytes:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 8<br />
| Title ID<br />
|-<br />
| 0x8<br />
| 4<br />
| Title version<br />
|-<br />
| 0xC<br />
| 1<br />
| Type (see [[NCM_services#Title_Types|Title Types]])<br />
|-<br />
| 0xD<br />
| 1<br />
| ? bit0 set = don't install?<br />
|-<br />
| 0xE<br />
| 2<br />
| Unused?<br />
|}<br />
<br />
This is used for SystemUpdate, see here: [[Content_Manager_services#GetUpdateTitleList]].<br />
<br />
== Extended data ==<br />
<br />
Patch-type cnmt files include an extended data section. <br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 4<br />
| Number of previous cnmt entries.<br />
|-<br />
| 0x4<br />
| 4<br />
| Number of previous delta entries.<br />
|-<br />
| 0x8<br />
| 4<br />
| Number of delta info entries.<br />
|-<br />
| 0xC<br />
| 4<br />
| Number of delta application info entries.<br />
|-<br />
| 0x10<br />
| 4<br />
| Number of previous content entries.<br />
|-<br />
| 0x14<br />
| 4<br />
| Number of delta content entries.<br />
|-<br />
| 0x18<br />
| 4<br />
| Unused?<br />
|-<br />
| 0x1C<br />
| 0x38*X<br />
| Previous cnmt entries<br />
|-<br />
| <br />
| 0x28*X<br />
| Previous delta entries<br />
|-<br />
| <br />
| 0x28*X<br />
| Delta info entries<br />
|-<br />
| <br />
| 0x34*X<br />
| Delta application info entries<br />
|-<br />
| <br />
| 0x18*X<br />
| Previous content entries<br />
|-<br />
| <br />
| 0x38*X<br />
| Delta content entries. (Standard content records)<br />
|-<br />
| <br />
| 4<br />
| Unknown<br />
|-<br />
| <br />
| 4<br />
| Unknown<br />
|-<br />
| <br />
| 4<br />
| Unknown<br />
|-<br />
|}<br />
<br />
== Previous cnmt records ==<br />
<br />
Each entry is 0x38 bytes:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 8<br />
| Title ID<br />
|-<br />
| 0x8<br />
| 4<br />
| Title version<br />
|-<br />
| 0xC<br />
| 1<br />
| Type (see [[NCM_services#Title_Types|Title Types]])<br />
|-<br />
| 0xD<br />
| 3<br />
| Unused?<br />
|-<br />
| 0x10<br />
| 32<br />
| Hash<br />
|-<br />
| 0x30<br />
| 2<br />
| Unknown<br />
|-<br />
| 0x32<br />
| 2<br />
| Unused?<br />
|-<br />
| 0x34<br />
| 4<br />
| Unused?<br />
|-<br />
|}<br />
<br />
This contains information on previous metadata files.<br />
<br />
== Previous delta records ==<br />
<br />
Each entry is 0x28 bytes:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 8<br />
| Old title ID<br />
|-<br />
| 0x8<br />
| 8<br />
| New title ID<br />
|-<br />
| 0x10<br />
| 4<br />
| Old title version<br />
|-<br />
| 0x14<br />
| 4<br />
| New title version<br />
|-<br />
| 0x18<br />
| 8<br />
| Size<br />
|-<br />
| 0x20<br />
| 8<br />
| Unused?<br />
|-<br />
|}<br />
<br />
This contains information on previous delta patches.<br />
<br />
== Delta info records ==<br />
<br />
Each entry is 0x28 bytes:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 8<br />
| Old title ID<br />
|-<br />
| 0x8<br />
| 8<br />
| New title ID<br />
|-<br />
| 0x10<br />
| 4<br />
| Old title version<br />
|-<br />
| 0x14<br />
| 4<br />
| New title version<br />
|-<br />
| 0x18<br />
| 8<br />
| Some sort of index?<br />
|-<br />
| 0x20<br />
| 8<br />
| Some sort of index?<br />
|-<br />
|}<br />
<br />
This contains information on the current delta patch.<br />
<br />
== Delta application info records ==<br />
<br />
Each entry is 0x34 bytes:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 16<br />
| Old NcaId<br />
|-<br />
| 0x10<br />
| 16<br />
| New NcaId<br />
|-<br />
| 0x20<br />
| 6<br />
| Old size<br />
|-<br />
| 0x26<br />
| 2<br />
| Upper 2 bytes of the new size<br />
|-<br />
| 0x28<br />
| 4<br />
| Lower 4 bytes of the new size<br />
|-<br />
| 0x2C<br />
| 2<br />
| Unknown<br />
|-<br />
| 0x2E<br />
| 1<br />
| Type (see [[NCM_services#Title_Types|Title Types]])<br />
|-<br />
| 0x2F<br />
| 1<br />
| ? bit0 set = don't install?<br />
|-<br />
| 0x30<br />
| 4<br />
| Unused?<br />
|-<br />
|}<br />
<br />
This contains information on how to apply deltas to the previous patch.<br />
<br />
== Previous content records ==<br />
<br />
Each entry is 0x18 bytes:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 16<br />
| NcaId<br />
|-<br />
| 0x10<br />
| 6<br />
| Size<br />
|-<br />
| 0x16<br />
| 1<br />
| Type (see [[NCM_services#Title_Types|Title Types]])<br />
|-<br />
| 0x17<br />
| 1<br />
| <br />
|-<br />
|}<br />
<br />
This contains information on previous title content from earlier patches.</div>
The-4n
https://switchbrew.org/w/index.php?title=NCA&diff=5169
NCA
2018-10-08T09:53:17Z
<p>The-4n: /* Section Header Block */</p>
<hr />
<div>The entire raw NCAs are encrypted.<br />
<br />
The only known area which is not encrypted in the raw NCA is the logo section, when the NCA includes that section. Everything else documented on this page is for the plaintext version of that data.<br />
<br />
=Encryption=<br />
The first 0xC00 bytes are encrypted with AES-XTS with sector size 0x200 with a non-standard "tweak" (endianness is reversed, see [https://gist.github.com/SciresM/fe8a631d13c069bd66e9c656ab5b3f7f here]), this encrypted data is an 0x400 NCA header + an 0x200 header for each section in the section table.<br />
<br />
For pre-1.0.0 "NCA2" NCAs, the first 0x400 byte are encrypted the same way as in NCA3. However, each section header is individually encrypted as though it were sector 0, instead of the appropriate sector as in NCA3.<br />
<br />
=Header=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x100<br />
| RSA-2048 signature over the 0x200-bytes starting at offset 0x200 using fixed key.<br />
|-<br />
| 0x100<br />
| 0x100<br />
| RSA-2048 signature over the 0x200-bytes starting at offset 0x200 using key from [[NPDM]], or zeroes if not a program.<br />
|-<br />
| 0x200<br />
| 0x4<br />
| Magicnum (Normally "NCA3", "NCA2" for some pre-1.0.0 NCAs)<br />
|-<br />
| 0x204<br />
| 0x1<br />
| 0 for system NCAs. 1 for a NCA from gamecard.<br />
|-<br />
| 0x205<br />
| 0x1<br />
| Content Type (0=Program, 1=Meta, 2=Control, 3=Manual, 4=Data, 5=PublicData)<br />
|-<br />
| 0x206<br />
| 0x1<br />
| Crypto Type. Only used stating with [[3.0.0]]. Normally 0. 2 = Crypto supported starting with [[3.0.0]].<br />
|-<br />
| 0x207<br />
| 0x1<br />
| Key index, must be 0-2.<br />
|-<br />
| 0x208<br />
| 0x8<br />
| Size of the entire NCA.<br />
|-<br />
| 0x210<br />
| 0x8<br />
| titleID<br />
|-<br />
| 0x21C<br />
| 0x4<br />
| sdk_version. byte0 is normally 0? Compared with a required minimum-value(0x000B0000). Matches this string from codebin: "FS_ACCESS: { sdk_version: {byte3}.{byte2}.{byte1}, ...".<br />
|-<br />
| 0x220<br />
| 0x1<br />
| Crypto-Type2. Selects which crypto-sysver to use. 0x3 = [[3.0.1]], 0x4 = [[4.0.0]], 0x5 = [[5.0.0]].<br />
|-<br />
| 0x230<br />
| 0x10<br />
| Rights ID ([[Ticket]])<br />
|-<br />
| 0x240<br />
| 0x10*0x4(0x40)<br />
| Table for each section, see below.<br />
|-<br />
| 0x280<br />
| 0x20*0x4(0x80)<br />
| Table of SHA256 hashes, over each 0x200-byte Section Header Block.<br />
|-<br />
| 0x300<br />
| 0x10*0x4(0x40)<br />
| Key area<br />
|}<br />
<br />
<br />
The header is 0x400-bytes, at NCA+0.<br />
<br />
When the above "Crypto Type" field is 0x2 on >=v3.0, different {crypto/keydata} is used for the sections' data. With system content, this is used with every ncatype except ncatype0. The only other exception is {data-content} for the firm titles: this is required in order for older-system-versions to install it.<br />
<br />
Crypto-Type2 0x3(with the above crypto-type value) is used for all [[3.0.1]] sysmodules and the [[System_Version_Title]].<br />
<br />
With [[3.0.2]], all updated titles use the crypto from [[3.0.1]] for non-ncatype0, except for firm {data-content}.<br />
<br />
Note: in some cases various game content uses the above newer crypto as well.<br />
<br />
The keyindex passed to <key-generation-related code> is determined as follows:<br />
* Pre-[[3.0.0]]: The ncahdr keyindex field(0x207) is passed directly.<br />
* [[3.0.0]]+: It's determined using ncahdr keyindex(0x207) and "Crypto Type"(0x206). The latter field must be 0-2. In each ncahdr_keyindex block, it executes "if(ncahdr_x206>=3)<panic>", but that won't trigger due to the earlier check. The end result is basically the same as pre-[[3.0.0]], except when ncahdr_x206 == 0x2, final_index is new_base_index+ncahdr_keyindex. Actual implementation loads index from u32_array[ncahdr_crypto_type], where the address of u32_array is different for each ncahdr_keyindex.<br />
* [[3.0.1]]+: The dedicated range check for ncahdr_x206("Crypto Type") was removed, since the updated code no longer needs it. The output from a function masked with 0xFF is now used instead of ncahdr_x206(ncahdr_crypto_type). The range check for that field was changed from {ncahdr_x206 check with panic described above}, to "if(index>=4)final_index=10;"(skips accessing the array and uses 10 directly). The arrays were updated with an additional entry: final_index=v301_base_index+ncahdr_keyindex.<br />
** The keydata for the above index10 is not(?) known to be initialized.<br />
** The new function called by the code described above does:<br />
** <code>if(ncahdr_x206 < ncahdr_x220){ret = ncahdr_x220; } else { ret = ncahdr_x206; } return ret;</code><br />
<br />
==Section Table Entry==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x4<br />
| Media offset<br />
|-<br />
| 0x4<br />
| 0x4<br />
| Media end-offset<br />
|-<br />
| 0x8<br />
| 0x4<br />
| Unknown<br />
|-<br />
| 0xC<br />
| 0x4<br />
| Unknown<br />
|}<br />
<br />
Entry size is 0x10-bytes.<br />
<br />
Media offset is absoluteoffset/{mediasize}, where mediasize is hard-coded to 0x200.<br />
<br />
=Section Header Block=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x2<br />
| Version. Always 0x2<br />
|-<br />
| 0x2<br />
| 0x1<br />
| Filesystem Type. 0x0 = RomFS. 0x1 = PFS0<br />
|-<br />
| 0x3<br />
| 0x1<br />
| Hash Type. 0x2 = PFS0. 0x3 = RomFS<br />
|-<br />
| 0x4<br />
| 0x1<br />
| Crypto type. 0 and >4 are invalid. 1 = none(plaintext from raw NCA). 2 = other crypto. 3 = regular crypto. 4 = unknown.<br />
|-<br />
| 0x5<br />
| 0x1<br />
| Padding?<br />
|-<br />
| 0x8<br />
| 0xF8<br />
| FS-specific superblock.<br />
|-<br />
| 0x100<br />
| ?<br />
| Optional BKTR header. Can be used with any section, but only known to be used with game-updates RomFS.<br />
|}<br />
<br />
The Section Header Block for each section is at absoluteoffset+0x400+(sectionid*0x200), where sectionid corresponds to the index used with the entry/hash tables.<br />
<br />
The total size is 0x200-bytes.<br />
<br />
==PFS0 superblock==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x20<br />
| SHA256 hash over the hash-table at section-start+0 with the below hash-table size.<br />
|-<br />
| 0x20<br />
| 0x4<br />
| Block size in bytes.<br />
|-<br />
| 0x24<br />
| 0x4<br />
| Must be 0x2.<br />
|-<br />
| 0x28<br />
| 0x8<br />
| Offset of hash-table. Normally zero?<br />
|-<br />
| 0x30<br />
| 0x8<br />
| Size of hash-table.<br />
|-<br />
| 0x38<br />
| 0x8<br />
| Offset relative to section-start where the PFS0 header is located.<br />
|-<br />
| 0x40<br />
| 0x8<br />
| Actual byte-size of the PFS0 filesystem relative to the PFS0 header.<br />
|-<br />
| 0x48<br />
| 0xB0<br />
| Normally zeros.<br />
|}<br />
<br />
==RomFS superblock==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x8<br />
| 0xE0<br />
| IVFC header. Basically the same as [[Savegames]] IVFC except with 2 more levels and +0x0C is non-zero, see below.<br />
|}<br />
<br />
This documents the structure of Section Header Block +0 for RomFS.<br />
<br />
=== IVFC ===<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x00<br />
| 4<br />
| Magic ("IVFC")<br />
|-<br />
| 0x04<br />
| 4<br />
| Magic Number (0x20000)<br />
|-<br />
| 0x08<br />
| 4<br />
| Master hash size?<br />
|-<br />
| 0x0C<br />
| 4<br />
| Usually 7? Unknown, could be related to total number of levels maybe?<br />
|-<br />
| 0x10<br />
| 8<br />
| Level 1 offset<br />
|-<br />
| 0x18<br />
| 8<br />
| Level 1 size<br />
|-<br />
| 0x20<br />
| 4<br />
| Level 1 block size, in log2<br />
|-<br />
| 0x24<br />
| 4<br />
| Reserved<br />
|-<br />
| 0x28<br />
| 8<br />
| Level 2 offset<br />
|-<br />
| 0x30<br />
| 8<br />
| Level 2 size<br />
|-<br />
| 0x38<br />
| 4<br />
| Level 2 block size, in log2.<br />
|-<br />
| 0x3C<br />
| 4<br />
| Reserved<br />
|-<br />
| 0x40<br />
| 8<br />
| Level 3 offset<br />
|-<br />
| 0x48<br />
| 8<br />
| Level 3 size<br />
|-<br />
| 0x50<br />
| 4<br />
| Level 3 block size, in log2.<br />
|-<br />
| 0x54<br />
| 4<br />
| Reserved<br />
|-<br />
| 0x58<br />
| 8<br />
| Level 4 offset<br />
|-<br />
| 0x60<br />
| 8<br />
| Level 4 size<br />
|-<br />
| 0x68<br />
| 4<br />
| Level 4 block size, in log2.<br />
|-<br />
| 0x6C<br />
| 4<br />
| Reserved<br />
|-<br />
| 0x70<br />
| 8<br />
| Level 5 offset<br />
|-<br />
| 0x78<br />
| 8<br />
| Level 5 size<br />
|-<br />
| 0x80<br />
| 4<br />
| Level 5 block size, in log2.<br />
|-<br />
| 0x84<br />
| 4<br />
| Reserved<br />
|-<br />
| 0x88<br />
| 8<br />
| Level 6 offset<br />
|-<br />
| 0x90<br />
| 8<br />
| Level 6 size<br />
|-<br />
| 0x98<br />
| 4<br />
| Level 6 block size, in log2.<br />
|-<br />
| 0x9C<br />
| 4<br />
| Reserved<br />
|-<br />
| 0xA0<br />
| 32<br />
| Unknown, reserved?<br />
|-<br />
| 0xC0<br />
| 32<br />
| Hash<br />
|}<br />
<br />
== BKTR ==<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x8<br />
| Offset<br />
|-<br />
|-<br />
| 0x8<br />
| 0x8<br />
| Size<br />
|-<br />
| 0x10<br />
| 0x4<br />
| "BKTR"<br />
|-<br />
| 0x14<br />
| 0x4<br />
| u32, must be <=1.<br />
|-<br />
| 0x18<br />
| 0x4<br />
| s32, must be >=1.<br />
|-<br />
| 0x1C<br />
| 0x4<br />
| ?<br />
|-<br />
| 0x20<br />
| 0x20<br />
| Same as the above 0x20-bytes except with different data.<br />
|-<br />
| 0x40<br />
| 0x4?<br />
| ?<br />
|-<br />
| 0x44<br />
| 0x4?<br />
| ?<br />
|}<br />
<br />
Using this header is enabled when offset 0x8 in this header is non-zero.<br />
<br />
The above byte-offsets are relative to the start of the section-data.<br />
<br />
The two sections specified by the two BKTR entries are usually(?) at the very end of the section data(section_endoffset-{size of BKTR sections}).<br />
<br />
===RomFS Patching===<br />
<br />
The BKTR section enables combining data from an update NCA with the RomFS from a base NCA to create a single patched RomFS image. <br />
<br />
The first BKTR entry describes how to map regions of the two RomFS images to create the patched RomFS. It has the following format:<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0 || 0x4 || Padding/Unused?<br />
|-<br />
| 0x4 || 0x4 || Number of Buckets<br />
|-<br />
| 0x8 || 0x8 || Total Size of the Virtual RomFS Image<br />
|-<br />
| 0x10 || 0x3FF0 || Base Virtual Offset for each Bucket (u64s, padded with 0s until end)<br />
|-<br />
| 0x4000 || 0x4000*X || Relocation Buckets<br />
|}<br />
<br />
Where relocation buckets are as follows:<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0 || 0x4 || Padding/Unused?<br />
|-<br />
| 0x4 || 0x4 || Number of Entries<br />
|-<br />
| 0x8 || 0x8 || End offset for this Bucket<br />
|-<br />
| 0x10 || 0x3FF0 || Relocation Entries<br />
|}<br />
<br />
Where relocation entries are as follows:<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0 || 0x8 || Address in Patched RomFS<br />
|-<br />
| 0x8 || 0x8 || Address in Source RomFS<br />
|-<br />
| 0x10 || 0x4 || 1=Is from Patch RomFS, 0=Is from Base RomFS<br />
|}<br />
<br />
The second BKTR entry describes the subsections within the Patch RomFS. It has the following format:<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0 || 0x4 || Padding/Unused?<br />
|-<br />
| 0x4 || 0x4 || Number of Buckets<br />
|-<br />
| 0x8 || 0x8 || Total Size of the Physical Patch Image<br />
|-<br />
| 0x10 || 0x3FF0 || Base Physical Offset for each Bucket (u64s, padded with 0s until end)<br />
|-<br />
| 0x4000 || 0x4000*X || Subsection Buckets<br />
|}<br />
<br />
<br />
Where subsection buckets are as follows:<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0 || 0x4 || Padding/Unused?<br />
|-<br />
| 0x4 || 0x4 || Number of Entries<br />
|-<br />
| 0x8 || 0x8 || End offset for this Bucket<br />
|-<br />
| 0x10 || 0x3FF0 || Subsection Entries<br />
|}<br />
<br />
Where subsection entries are as follows:<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0 || 0x8 || Address in Patch RomFS<br />
|-<br />
| 0x8 || 0x4 || Padding/Unused?<br />
|-<br />
| 0xC || 0x4 || Value for subsection AES-CTR<br />
|}<br />
<br />
Official code assumes the relocation entries are sorted, and performs a binary search when determining where to read from. Each subsection in the Patch RomFS has its CTR calculated separately from the others based on the value in its entry (the BKTR entries use normal crypto). Thus decrypting a Patch RomFS requires decrypting and parsing the BKTR entries before anything else.<br />
<br />
=Logo section=<br />
This is a PFS0. See [[NCA_Content_FS|here]] for the mounted-FS logo contents.<br />
<br />
=ExeFS section =<br />
This is a PFS0.<br />
<br />
See [[ExeFS|here]] for mounted-FS ExeFS contents.<br />
<br />
=Game-updates=<br />
The section-data for ncatype1 RomFS section(section1) uses section-crypto-type 0x4.<br />
<br />
Game-updates also contain multiple ncatype6 content, which contain "section0_pfs0/fragment". Some of these are just NCAs, unknown for the rest(presumably NCAs with additional crypto?). The first ncatype6 content fragment file has a NDV0 header, with the NCA starting at offset 0x44.<br />
<br />
=PFS0=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| {Hash-table offset from superblock}<br />
| {Hash-table size from superblock}<br />
| Table of SHA256 hashes.<br />
|-<br />
| {Hash-table <offset+size> from superblock}<br />
| <br />
| Zeros for alignment to {alignment size}.<br />
|-<br />
| {PFS0 offset from superblock}<br />
| {PFS0 size from superblock}<br />
| The actual PFS0.<br />
|}<br />
<br />
This is the FS which has magicnum "PFS0" at header+0. This is very similar to [[Gamecard_Format|HFS0]]. A tool for extracting this FS is available [https://gist.github.com/yellows8/1a96c2b846f4ebc4bb45d7f7fa1eb7db here].<br />
<br />
The hash table is hashes for every {Block size from superblock} starting at the PFS0 header. The size used for the last hash is {PFS0 filesystem size from superblock} - offset_relativeto_header.<br />
<br />
See also the PFS0 superblock above.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x4<br />
| "PFS0" Magic<br />
|-<br />
| 0x4<br />
| 0x4<br />
| Number of files<br />
|-<br />
| 0x8<br />
| 0x4<br />
| Size of the string table<br />
|-<br />
| 0xC<br />
| 0x4<br />
| Zero/Reserved<br />
|-<br />
| 0x10<br />
| X<br />
| File Entry Table<br />
|-<br />
| 0x10 + X<br />
| Y<br />
| String Table<br />
|-<br />
| 0x10 + X + Y<br />
| Z<br />
| Raw File Data<br />
|}<br />
<br />
Where File Entry Table consists of Number of Files FileEntries:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x8<br />
| Offset of file in Data<br />
|-<br />
| 0x8<br />
| 0x8<br />
| Size of file in Data<br />
|-<br />
| 0x10<br />
| 0x4<br />
| Offset of filename in String Table<br />
|-<br />
| 0x14<br />
| 0x4<br />
| Normally zero?<br />
|}</div>
The-4n
https://switchbrew.org/w/index.php?title=CNMT&diff=5160
CNMT
2018-10-06T11:33:52Z
<p>The-4n: </p>
<hr />
<div>For the content of the NCA FS which can be [[Filesystem_services|mounted]], see [[NCA_Content_FS|here]].<br />
<br />
For the format of the actual NCA, see [[NCA_Format|here]].<br />
<br />
= Metadata file =<br />
This is the file that ends in <code>".cnmt{.nca}"</code> or <code>"meta0.ncd"</code>. This seems to replace the TMD format.<br />
<br />
There's at least 8 different filenames used for ".cnmt":<br />
* "Application_{lower-case hex titleID}.cnmt"<br />
* "Patch_{lower-case hex titleID}.cnmt"<br />
* "AddOnContent_{lower-case hex titleID}.cnmt"<br />
* "SystemUpdate_{hex titleID}.cnmt"<br />
* "SystemData_{lower-case hex titleID}.cnmt"<br />
* "SystemProgram_{lower-case hex titleID}.cnmt"<br />
* "BootImagePackage_{lower-case hex titleID}.cnmt"<br />
* "BootImagePackageSafe_{lower-case hex titleID}.cnmt"<br />
<br />
It starts with a header:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 8<br />
| Title ID<br />
|-<br />
| 0x8<br />
| 4<br />
| u32 [[Title_list|title-version]]<br />
|-<br />
| 0xC<br />
| 1<br />
| Type (see [[NCM_services#Title_Types|Title Types]])<br />
|-<br />
| 0xD<br />
| 1<br />
|<br />
|-<br />
| 0xE<br />
| 2<br />
| Offset to table relative to the end of this 0x20-byte header.<br />
|-<br />
| 0x10<br />
| 2<br />
| Number of content entries<br />
|-<br />
| 0x12<br />
| 2<br />
| Number of meta entries<br />
|-<br />
| 0x14<br />
| 12<br />
|<br />
|}<br />
<br />
With SystemUpdate, the 4-bytes at offset 0xE are zero, with the entry-count field located at offset 0x12 instead(header size is the same).<br />
<br />
An optional header can follow, depending on the title type.<br />
<br />
At the end of the file following the entries is a 0x20-byte block, presumably a hash.<br />
<br />
With Patch-format, there's additional data after the end of the entries specified in the header and before the ending hash.<br />
<br />
== Application header ==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x20<br />
| 8<br />
| Patch Title ID<br />
|-<br />
| 0x28<br />
| 8<br />
| Minimum system version<br />
|}<br />
<br />
== Patch header ==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x20<br />
| 8<br />
| Original title ID<br />
|-<br />
| 0x28<br />
| 8<br />
| Minimum system version<br />
|}<br />
<br />
== Add-on content header ==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x20<br />
| 8<br />
| Application title ID<br />
|-<br />
| 0x28<br />
| 8<br />
| Minimum application version<br />
|}<br />
<br />
== Content records ==<br />
<br />
Each entry is 0x38 bytes:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 32<br />
| Hash<br />
|-<br />
| 0x20<br />
| 16<br />
| NcaId [same as first 16-bytes of hash]<br />
|-<br />
| 0x30<br />
| 6<br />
| Size, same as the output from [[Content_Manager_services#GetEntrySize]].<br />
|-<br />
| 0x36<br />
| 1<br />
| Type (0=Meta, 1=Program, 2=Data, 3=Control, 4=[[Internet_Browser|HtmlDocument]], 5=[[Internet_Browser|LegalInformation]], 6=[[NCA_Format|DeltaFragment]])<br />
|-<br />
| 0x37<br />
| 1<br />
|<br />
|}<br />
<br />
== Meta records ==<br />
<br />
Each entry is 0x10 bytes:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 8<br />
| Title ID<br />
|-<br />
| 0x8<br />
| 4<br />
| Title version<br />
|-<br />
| 0xC<br />
| 1<br />
| Type (see [[NCM_services#Title_Types|Title Types]])<br />
|-<br />
| 0xD<br />
| 1<br />
| ? bit0 set = don't install?<br />
|-<br />
| 0xE<br />
| 2<br />
| Unused?<br />
|}<br />
<br />
This is used for SystemUpdate, see here: [[Content_Manager_services#GetUpdateTitleList]].<br />
<br />
== Extended data ==<br />
<br />
Patch-type cnmt files include an extended data section. <br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 4<br />
| Number of previous cnmt entries.<br />
|-<br />
| 0x4<br />
| 4<br />
| Number of previous delta entries.<br />
|-<br />
| 0x8<br />
| 4<br />
| Number of delta info entries.<br />
|-<br />
| 0xC<br />
| 4<br />
| Number of delta application info entries.<br />
|-<br />
| 0x10<br />
| 4<br />
| Number of previous content entries.<br />
|-<br />
| 0x14<br />
| 4<br />
| Number of delta content entries.<br />
|-<br />
| 0x18<br />
| 4<br />
| Unused?<br />
|-<br />
| 0x1C<br />
| 0x38*X<br />
| Previous cnmt entries<br />
|-<br />
| <br />
| 0x28*X<br />
| Previous delta entries<br />
|-<br />
| <br />
| 0x28*X<br />
| Delta info entries<br />
|-<br />
| <br />
| 0x34*X<br />
| Delta application info entries<br />
|-<br />
| <br />
| 0x18*X<br />
| Previous content entries<br />
|-<br />
| <br />
| 0x38*X<br />
| Delta content entries. (Standard content records)<br />
|-<br />
| <br />
| 4<br />
| Unknown<br />
|-<br />
| <br />
| 4<br />
| Unknown<br />
|-<br />
| <br />
| 4<br />
| Unknown<br />
|-<br />
|}<br />
<br />
== Previous cnmt records ==<br />
<br />
Each entry is 0x38 bytes:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 8<br />
| Title ID<br />
|-<br />
| 0x8<br />
| 4<br />
| Title version<br />
|-<br />
| 0xC<br />
| 1<br />
| Type (see [[NCM_services#Title_Types|Title Types]])<br />
|-<br />
| 0xD<br />
| 3<br />
| Unused?<br />
|-<br />
| 0x10<br />
| 32<br />
| Hash<br />
|-<br />
| 0x30<br />
| 2<br />
| Unknown<br />
|-<br />
| 0x32<br />
| 2<br />
| Unused?<br />
|-<br />
| 0x34<br />
| 4<br />
| Unused?<br />
|-<br />
|}<br />
<br />
This contains information on previous metadata files.<br />
<br />
== Previous delta records ==<br />
<br />
Each entry is 0x28 bytes:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 8<br />
| Old title ID<br />
|-<br />
| 0x8<br />
| 8<br />
| New title ID<br />
|-<br />
| 0x10<br />
| 4<br />
| Old title version<br />
|-<br />
| 0x14<br />
| 4<br />
| New title version<br />
|-<br />
| 0x18<br />
| 8<br />
| Size<br />
|-<br />
| 0x20<br />
| 8<br />
| Unused?<br />
|-<br />
|}<br />
<br />
This contains information on previous delta patches.<br />
<br />
== Delta info records ==<br />
<br />
Each entry is 0x28 bytes:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 8<br />
| Old title ID<br />
|-<br />
| 0x8<br />
| 8<br />
| New title ID<br />
|-<br />
| 0x10<br />
| 4<br />
| Old title version<br />
|-<br />
| 0x14<br />
| 4<br />
| New title version<br />
|-<br />
| 0x18<br />
| 8<br />
| Some sort of index?<br />
|-<br />
| 0x20<br />
| 8<br />
| Some sort of index?<br />
|-<br />
|}<br />
<br />
This contains information on the current delta patch.<br />
<br />
== Delta application info records ==<br />
<br />
Each entry is 0x34 bytes:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 16<br />
| Old NcaId<br />
|-<br />
| 0x10<br />
| 16<br />
| New NcaId<br />
|-<br />
| 0x20<br />
| 6<br />
| Old size<br />
|-<br />
| 0x26<br />
| 2<br />
| Upper 2 bytes of the new size<br />
|-<br />
| 0x28<br />
| 4<br />
| Lower 4 bytes of the new size<br />
|-<br />
| 0x2C<br />
| 2<br />
| Unknown<br />
|-<br />
| 0x2E<br />
| 1<br />
| Type (see [[NCM_services#Title_Types|Title Types]])<br />
|-<br />
| 0x2F<br />
| 1<br />
| ? bit0 set = don't install?<br />
|-<br />
| 0x30<br />
| 4<br />
| Unused?<br />
|-<br />
|}<br />
<br />
This contains information on how to apply deltas to the previous patch.<br />
<br />
== Previous content records ==<br />
<br />
Each entry is 0x18 bytes:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 16<br />
| NcaId<br />
|-<br />
| 0x10<br />
| 6<br />
| Size<br />
|-<br />
| 0x16<br />
| 1<br />
| Type (see [[NCM_services#Title_Types|Title Types]])<br />
|-<br />
| 0x17<br />
| 1<br />
| <br />
|-<br />
|}<br />
<br />
This contains information on previous title content from earlier patches.</div>
The-4n
https://switchbrew.org/w/index.php?title=NCA&diff=5118
NCA
2018-09-29T09:23:41Z
<p>The-4n: Undo revision 5117 by The-4n (talk)</p>
<hr />
<div>The entire raw NCAs are encrypted.<br />
<br />
The only known area which is not encrypted in the raw NCA is the logo section, when the NCA includes that section. Everything else documented on this page is for the plaintext version of that data.<br />
<br />
=Encryption=<br />
The first 0xC00 bytes are encrypted with AES-XTS with sector size 0x200 with a non-standard "tweak" (endianness is reversed, see [https://gist.github.com/SciresM/fe8a631d13c069bd66e9c656ab5b3f7f here]), this encrypted data is an 0x400 NCA header + an 0x200 header for each section in the section table.<br />
<br />
For pre-1.0.0 "NCA2" NCAs, the first 0x400 byte are encrypted the same way as in NCA3. However, each section header is individually encrypted as though it were sector 0, instead of the appropriate sector as in NCA3.<br />
<br />
=Header=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x100<br />
| RSA-2048 signature over the 0x200-bytes starting at offset 0x200 using fixed key.<br />
|-<br />
| 0x100<br />
| 0x100<br />
| RSA-2048 signature over the 0x200-bytes starting at offset 0x200 using key from [[NPDM]], or zeroes if not a program.<br />
|-<br />
| 0x200<br />
| 0x4<br />
| Magicnum (Normally "NCA3", "NCA2" for some pre-1.0.0 NCAs)<br />
|-<br />
| 0x204<br />
| 0x1<br />
| 0 for system NCAs. 1 for a NCA from gamecard.<br />
|-<br />
| 0x205<br />
| 0x1<br />
| Content Type (0=Program, 1=Meta, 2=Control, 3=Manual, 4=Data)<br />
|-<br />
| 0x206<br />
| 0x1<br />
| Crypto Type. Only used stating with [[3.0.0]]. Normally 0. 2 = Crypto supported starting with [[3.0.0]].<br />
|-<br />
| 0x207<br />
| 0x1<br />
| Key index, must be 0-2.<br />
|-<br />
| 0x208<br />
| 0x8<br />
| Size of the entire NCA.<br />
|-<br />
| 0x210<br />
| 0x8<br />
| titleID<br />
|-<br />
| 0x21C<br />
| 0x4<br />
| sdk_version. byte0 is normally 0? Compared with a required minimum-value(0x000B0000). Matches this string from codebin: "FS_ACCESS: { sdk_version: {byte3}.{byte2}.{byte1}, ...".<br />
|-<br />
| 0x220<br />
| 0x1<br />
| Crypto-Type2. Selects which crypto-sysver to use. 0x3 = [[3.0.1]], 0x4 = [[4.0.0]], 0x5 = [[5.0.0]].<br />
|-<br />
| 0x230<br />
| 0x10<br />
| Rights ID ([[Ticket]])<br />
|-<br />
| 0x240<br />
| 0x10*0x4(0x40)<br />
| Table for each section, see below.<br />
|-<br />
| 0x280<br />
| 0x20*0x4(0x80)<br />
| Table of SHA256 hashes, over each 0x200-byte Section Header Block.<br />
|-<br />
| 0x300<br />
| 0x10*0x4(0x40)<br />
| Key area<br />
|}<br />
<br />
<br />
The header is 0x400-bytes, at NCA+0.<br />
<br />
When the above "Crypto Type" field is 0x2 on >=v3.0, different {crypto/keydata} is used for the sections' data. With system content, this is used with every ncatype except ncatype0. The only other exception is {data-content} for the firm titles: this is required in order for older-system-versions to install it.<br />
<br />
Crypto-Type2 0x3(with the above crypto-type value) is used for all [[3.0.1]] sysmodules and the [[System_Version_Title]].<br />
<br />
With [[3.0.2]], all updated titles use the crypto from [[3.0.1]] for non-ncatype0, except for firm {data-content}.<br />
<br />
Note: in some cases various game content uses the above newer crypto as well.<br />
<br />
The keyindex passed to <key-generation-related code> is determined as follows:<br />
* Pre-[[3.0.0]]: The ncahdr keyindex field(0x207) is passed directly.<br />
* [[3.0.0]]+: It's determined using ncahdr keyindex(0x207) and "Crypto Type"(0x206). The latter field must be 0-2. In each ncahdr_keyindex block, it executes "if(ncahdr_x206>=3)<panic>", but that won't trigger due to the earlier check. The end result is basically the same as pre-[[3.0.0]], except when ncahdr_x206 == 0x2, final_index is new_base_index+ncahdr_keyindex. Actual implementation loads index from u32_array[ncahdr_crypto_type], where the address of u32_array is different for each ncahdr_keyindex.<br />
* [[3.0.1]]+: The dedicated range check for ncahdr_x206("Crypto Type") was removed, since the updated code no longer needs it. The output from a function masked with 0xFF is now used instead of ncahdr_x206(ncahdr_crypto_type). The range check for that field was changed from {ncahdr_x206 check with panic described above}, to "if(index>=4)final_index=10;"(skips accessing the array and uses 10 directly). The arrays were updated with an additional entry: final_index=v301_base_index+ncahdr_keyindex.<br />
** The keydata for the above index10 is not(?) known to be initialized.<br />
** The new function called by the code described above does:<br />
** <code>if(ncahdr_x206 < ncahdr_x220){ret = ncahdr_x220; } else { ret = ncahdr_x206; } return ret;</code><br />
<br />
==Section Table Entry==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x4<br />
| Media offset<br />
|-<br />
| 0x4<br />
| 0x4<br />
| Media end-offset<br />
|-<br />
| 0x8<br />
| 0x4<br />
| Unknown<br />
|-<br />
| 0xC<br />
| 0x4<br />
| Unknown<br />
|}<br />
<br />
Entry size is 0x10-bytes.<br />
<br />
Media offset is absoluteoffset/{mediasize}, where mediasize is hard-coded to 0x200.<br />
<br />
=Section Header Block=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x1<br />
| ?<br />
|-<br />
|-<br />
| 0x1<br />
| 0x1<br />
| ?<br />
|-<br />
| 0x2<br />
| 0x1<br />
| ?<br />
|-<br />
| 0x3<br />
| 0x1<br />
| Filesystem type. 0x2 = PFS0, 0x3 = RomFS, everything else is invalid.<br />
|-<br />
| 0x4<br />
| 0x1<br />
| Crypto type. 0 and >4 are invalid. 1 = none(plaintext from raw NCA). 2 = other crypto. 3 = regular crypto. 4 = unknown.<br />
|-<br />
| 0x5<br />
| 0x1<br />
| Padding?<br />
|-<br />
| 0x8<br />
| 0xF8<br />
| FS-specific superblock.<br />
|-<br />
| 0x100<br />
| ?<br />
| Optional BKTR header. Can be used with any section, but only known to be used with game-updates RomFS.<br />
|}<br />
<br />
The Section Header Block for each section is at absoluteoffset+0x400+(sectionid*0x200), where sectionid corresponds to the index used with the entry/hash tables.<br />
<br />
The total size is 0x200-bytes.<br />
<br />
==PFS0 superblock==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x20<br />
| SHA256 hash over the hash-table at section-start+0 with the below hash-table size.<br />
|-<br />
| 0x20<br />
| 0x4<br />
| Block size in bytes.<br />
|-<br />
| 0x24<br />
| 0x4<br />
| Must be 0x2.<br />
|-<br />
| 0x28<br />
| 0x8<br />
| Offset of hash-table. Normally zero?<br />
|-<br />
| 0x30<br />
| 0x8<br />
| Size of hash-table.<br />
|-<br />
| 0x38<br />
| 0x8<br />
| Offset relative to section-start where the PFS0 header is located.<br />
|-<br />
| 0x40<br />
| 0x8<br />
| Actual byte-size of the PFS0 filesystem relative to the PFS0 header.<br />
|-<br />
| 0x48<br />
| 0xB0<br />
| Normally zeros.<br />
|}<br />
<br />
==RomFS superblock==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x8<br />
| 0xE0<br />
| IVFC header. Basically the same as [[Savegames]] IVFC except with 2 more levels and +0x0C is non-zero, see below.<br />
|}<br />
<br />
This documents the structure of Section Header Block +0 for RomFS.<br />
<br />
=== IVFC ===<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x00<br />
| 4<br />
| Magic ("IVFC")<br />
|-<br />
| 0x04<br />
| 4<br />
| Magic Number (0x20000)<br />
|-<br />
| 0x08<br />
| 4<br />
| Master hash size?<br />
|-<br />
| 0x0C<br />
| 4<br />
| Usually 7? Unknown, could be related to total number of levels maybe?<br />
|-<br />
| 0x10<br />
| 8<br />
| Level 1 offset<br />
|-<br />
| 0x18<br />
| 8<br />
| Level 1 size<br />
|-<br />
| 0x20<br />
| 4<br />
| Level 1 block size, in log2<br />
|-<br />
| 0x24<br />
| 4<br />
| Reserved<br />
|-<br />
| 0x28<br />
| 8<br />
| Level 2 offset<br />
|-<br />
| 0x30<br />
| 8<br />
| Level 2 size<br />
|-<br />
| 0x38<br />
| 4<br />
| Level 2 block size, in log2.<br />
|-<br />
| 0x3C<br />
| 4<br />
| Reserved<br />
|-<br />
| 0x40<br />
| 8<br />
| Level 3 offset<br />
|-<br />
| 0x48<br />
| 8<br />
| Level 3 size<br />
|-<br />
| 0x50<br />
| 4<br />
| Level 3 block size, in log2.<br />
|-<br />
| 0x54<br />
| 4<br />
| Reserved<br />
|-<br />
| 0x58<br />
| 8<br />
| Level 4 offset<br />
|-<br />
| 0x60<br />
| 8<br />
| Level 4 size<br />
|-<br />
| 0x68<br />
| 4<br />
| Level 4 block size, in log2.<br />
|-<br />
| 0x6C<br />
| 4<br />
| Reserved<br />
|-<br />
| 0x70<br />
| 8<br />
| Level 5 offset<br />
|-<br />
| 0x78<br />
| 8<br />
| Level 5 size<br />
|-<br />
| 0x80<br />
| 4<br />
| Level 5 block size, in log2.<br />
|-<br />
| 0x84<br />
| 4<br />
| Reserved<br />
|-<br />
| 0x88<br />
| 8<br />
| Level 6 offset<br />
|-<br />
| 0x90<br />
| 8<br />
| Level 6 size<br />
|-<br />
| 0x98<br />
| 4<br />
| Level 6 block size, in log2.<br />
|-<br />
| 0x9C<br />
| 4<br />
| Reserved<br />
|-<br />
| 0xA0<br />
| 32<br />
| Unknown, reserved?<br />
|-<br />
| 0xC0<br />
| 32<br />
| Hash<br />
|}<br />
<br />
== BKTR ==<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x8<br />
| Offset<br />
|-<br />
|-<br />
| 0x8<br />
| 0x8<br />
| Size<br />
|-<br />
| 0x10<br />
| 0x4<br />
| "BKTR"<br />
|-<br />
| 0x14<br />
| 0x4<br />
| u32, must be <=1.<br />
|-<br />
| 0x18<br />
| 0x4<br />
| s32, must be >=1.<br />
|-<br />
| 0x1C<br />
| 0x4<br />
| ?<br />
|-<br />
| 0x20<br />
| 0x20<br />
| Same as the above 0x20-bytes except with different data.<br />
|-<br />
| 0x40<br />
| 0x4?<br />
| ?<br />
|-<br />
| 0x44<br />
| 0x4?<br />
| ?<br />
|}<br />
<br />
Using this header is enabled when offset 0x8 in this header is non-zero.<br />
<br />
The above byte-offsets are relative to the start of the section-data.<br />
<br />
The two sections specified by the two BKTR entries are usually(?) at the very end of the section data(section_endoffset-{size of BKTR sections}).<br />
<br />
===RomFS Patching===<br />
<br />
The BKTR section enables combining data from an update NCA with the RomFS from a base NCA to create a single patched RomFS image. <br />
<br />
The first BKTR entry describes how to map regions of the two RomFS images to create the patched RomFS. It has the following format:<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0 || 0x4 || Padding/Unused?<br />
|-<br />
| 0x4 || 0x4 || Number of Buckets<br />
|-<br />
| 0x8 || 0x8 || Total Size of the Virtual RomFS Image<br />
|-<br />
| 0x10 || 0x3FF0 || Base Virtual Offset for each Bucket (u64s, padded with 0s until end)<br />
|-<br />
| 0x4000 || 0x4000*X || Relocation Buckets<br />
|}<br />
<br />
Where relocation buckets are as follows:<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0 || 0x4 || Padding/Unused?<br />
|-<br />
| 0x4 || 0x4 || Number of Entries<br />
|-<br />
| 0x8 || 0x8 || End offset for this Bucket<br />
|-<br />
| 0x10 || 0x3FF0 || Relocation Entries<br />
|}<br />
<br />
Where relocation entries are as follows:<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0 || 0x8 || Address in Patched RomFS<br />
|-<br />
| 0x8 || 0x8 || Address in Source RomFS<br />
|-<br />
| 0x10 || 0x4 || 1=Is from Patch RomFS, 0=Is from Base RomFS<br />
|}<br />
<br />
The second BKTR entry describes the subsections within the Patch RomFS. It has the following format:<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0 || 0x4 || Padding/Unused?<br />
|-<br />
| 0x4 || 0x4 || Number of Buckets<br />
|-<br />
| 0x8 || 0x8 || Total Size of the Physical Patch Image<br />
|-<br />
| 0x10 || 0x3FF0 || Base Physical Offset for each Bucket (u64s, padded with 0s until end)<br />
|-<br />
| 0x4000 || 0x4000*X || Subsection Buckets<br />
|}<br />
<br />
<br />
Where subsection buckets are as follows:<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0 || 0x4 || Padding/Unused?<br />
|-<br />
| 0x4 || 0x4 || Number of Entries<br />
|-<br />
| 0x8 || 0x8 || End offset for this Bucket<br />
|-<br />
| 0x10 || 0x3FF0 || Subsection Entries<br />
|}<br />
<br />
Where subsection entries are as follows:<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0 || 0x8 || Address in Patch RomFS<br />
|-<br />
| 0x8 || 0x4 || Padding/Unused?<br />
|-<br />
| 0xC || 0x4 || Value for subsection AES-CTR<br />
|}<br />
<br />
Official code assumes the relocation entries are sorted, and performs a binary search when determining where to read from. Each subsection in the Patch RomFS has its CTR calculated separately from the others based on the value in its entry (the BKTR entries use normal crypto). Thus decrypting a Patch RomFS requires decrypting and parsing the BKTR entries before anything else.<br />
<br />
=Logo section=<br />
This is a PFS0. See [[NCA_Content_FS|here]] for the mounted-FS logo contents.<br />
<br />
=ExeFS section =<br />
This is a PFS0.<br />
<br />
See [[ExeFS|here]] for mounted-FS ExeFS contents.<br />
<br />
=Game-updates=<br />
The section-data for ncatype1 RomFS section(section1) uses section-crypto-type 0x4.<br />
<br />
Game-updates also contain multiple ncatype6 content, which contain "section0_pfs0/fragment". Some of these are just NCAs, unknown for the rest(presumably NCAs with additional crypto?). The first ncatype6 content fragment file has a NDV0 header, with the NCA starting at offset 0x44.<br />
<br />
=PFS0=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| {Hash-table offset from superblock}<br />
| {Hash-table size from superblock}<br />
| Table of SHA256 hashes.<br />
|-<br />
| {Hash-table <offset+size> from superblock}<br />
| <br />
| Zeros for alignment to {alignment size}.<br />
|-<br />
| {PFS0 offset from superblock}<br />
| {PFS0 size from superblock}<br />
| The actual PFS0.<br />
|}<br />
<br />
This is the FS which has magicnum "PFS0" at header+0. This is very similar to [[Gamecard_Format|HFS0]]. A tool for extracting this FS is available [https://gist.github.com/yellows8/1a96c2b846f4ebc4bb45d7f7fa1eb7db here].<br />
<br />
The hash table is hashes for every {Block size from superblock} starting at the PFS0 header. The size used for the last hash is {PFS0 filesystem size from superblock} - offset_relativeto_header.<br />
<br />
See also the PFS0 superblock above.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x4<br />
| "PFS0" Magic<br />
|-<br />
| 0x4<br />
| 0x4<br />
| Number of files<br />
|-<br />
| 0x8<br />
| 0x4<br />
| Size of the string table<br />
|-<br />
| 0xC<br />
| 0x4<br />
| Zero/Reserved<br />
|-<br />
| 0x10<br />
| X<br />
| File Entry Table<br />
|-<br />
| 0x10 + X<br />
| Y<br />
| String Table<br />
|-<br />
| 0x10 + X + Y<br />
| Z<br />
| Raw File Data<br />
|}<br />
<br />
Where File Entry Table consists of Number of Files FileEntries:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x8<br />
| Offset of file in Data<br />
|-<br />
| 0x8<br />
| 0x8<br />
| Size of file in Data<br />
|-<br />
| 0x10<br />
| 0x4<br />
| Offset of filename in String Table<br />
|-<br />
| 0x14<br />
| 0x4<br />
| Normally zero?<br />
|}</div>
The-4n
https://switchbrew.org/w/index.php?title=NCA&diff=5117
NCA
2018-09-29T08:37:07Z
<p>The-4n: </p>
<hr />
<div>The entire raw NCAs are encrypted.<br />
<br />
The only known area which is not encrypted in the raw NCA is the logo section, when the NCA includes that section. Everything else documented on this page is for the plaintext version of that data.<br />
<br />
=Encryption=<br />
The first 0xC00 bytes are encrypted with AES-XTS with sector size 0x200 with a non-standard "tweak" (endianness is reversed, see [https://gist.github.com/SciresM/fe8a631d13c069bd66e9c656ab5b3f7f here]), this encrypted data is an 0x400 NCA header + an 0x200 header for each section in the section table.<br />
<br />
For pre-1.0.0 "NCA2" NCAs, the first 0x400 byte are encrypted the same way as in NCA3. However, each section header is individually encrypted as though it were sector 0, instead of the appropriate sector as in NCA3.<br />
<br />
=Header=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x100<br />
| RSA-2048 signature over the 0x200-bytes starting at offset 0x200 using fixed key.<br />
|-<br />
| 0x100<br />
| 0x100<br />
| RSA-2048 signature over the 0x200-bytes starting at offset 0x200 using key from [[NPDM]], or zeroes if not a program.<br />
|-<br />
| 0x200<br />
| 0x4<br />
| Magicnum (Normally "NCA3", "NCA2" for some pre-1.0.0 NCAs)<br />
|-<br />
| 0x204<br />
| 0x1<br />
| 0 for system NCAs. 1 for a NCA from gamecard.<br />
|-<br />
| 0x205<br />
| 0x1<br />
| Content Type (0=Program, 1=Meta, 2=Control, 3=Manual, 4=Data, 5=PublicData)<br />
|-<br />
| 0x206<br />
| 0x1<br />
| Crypto Type. Only used stating with [[3.0.0]]. Normally 0. 2 = Crypto supported starting with [[3.0.0]].<br />
|-<br />
| 0x207<br />
| 0x1<br />
| Key index, must be 0-2.<br />
|-<br />
| 0x208<br />
| 0x8<br />
| Size of the entire NCA.<br />
|-<br />
| 0x210<br />
| 0x8<br />
| titleID<br />
|-<br />
| 0x21C<br />
| 0x4<br />
| sdk_version. byte0 is normally 0? Compared with a required minimum-value(0x000B0000). Matches this string from codebin: "FS_ACCESS: { sdk_version: {byte3}.{byte2}.{byte1}, ...".<br />
|-<br />
| 0x220<br />
| 0x1<br />
| Crypto-Type2. Selects which crypto-sysver to use. 0x3 = [[3.0.1]], 0x4 = [[4.0.0]], 0x5 = [[5.0.0]].<br />
|-<br />
| 0x230<br />
| 0x10<br />
| Rights ID ([[Ticket]])<br />
|-<br />
| 0x240<br />
| 0x10*0x4(0x40)<br />
| Table for each section, see below.<br />
|-<br />
| 0x280<br />
| 0x20*0x4(0x80)<br />
| Table of SHA256 hashes, over each 0x200-byte Section Header Block.<br />
|-<br />
| 0x300<br />
| 0x10*0x4(0x40)<br />
| Key area<br />
|}<br />
<br />
<br />
The header is 0x400-bytes, at NCA+0.<br />
<br />
When the above "Crypto Type" field is 0x2 on >=v3.0, different {crypto/keydata} is used for the sections' data. With system content, this is used with every ncatype except ncatype0. The only other exception is {data-content} for the firm titles: this is required in order for older-system-versions to install it.<br />
<br />
Crypto-Type2 0x3(with the above crypto-type value) is used for all [[3.0.1]] sysmodules and the [[System_Version_Title]].<br />
<br />
With [[3.0.2]], all updated titles use the crypto from [[3.0.1]] for non-ncatype0, except for firm {data-content}.<br />
<br />
Note: in some cases various game content uses the above newer crypto as well.<br />
<br />
The keyindex passed to <key-generation-related code> is determined as follows:<br />
* Pre-[[3.0.0]]: The ncahdr keyindex field(0x207) is passed directly.<br />
* [[3.0.0]]+: It's determined using ncahdr keyindex(0x207) and "Crypto Type"(0x206). The latter field must be 0-2. In each ncahdr_keyindex block, it executes "if(ncahdr_x206>=3)<panic>", but that won't trigger due to the earlier check. The end result is basically the same as pre-[[3.0.0]], except when ncahdr_x206 == 0x2, final_index is new_base_index+ncahdr_keyindex. Actual implementation loads index from u32_array[ncahdr_crypto_type], where the address of u32_array is different for each ncahdr_keyindex.<br />
* [[3.0.1]]+: The dedicated range check for ncahdr_x206("Crypto Type") was removed, since the updated code no longer needs it. The output from a function masked with 0xFF is now used instead of ncahdr_x206(ncahdr_crypto_type). The range check for that field was changed from {ncahdr_x206 check with panic described above}, to "if(index>=4)final_index=10;"(skips accessing the array and uses 10 directly). The arrays were updated with an additional entry: final_index=v301_base_index+ncahdr_keyindex.<br />
** The keydata for the above index10 is not(?) known to be initialized.<br />
** The new function called by the code described above does:<br />
** <code>if(ncahdr_x206 < ncahdr_x220){ret = ncahdr_x220; } else { ret = ncahdr_x206; } return ret;</code><br />
<br />
==Section Table Entry==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x4<br />
| Media offset<br />
|-<br />
| 0x4<br />
| 0x4<br />
| Media end-offset<br />
|-<br />
| 0x8<br />
| 0x4<br />
| Unknown<br />
|-<br />
| 0xC<br />
| 0x4<br />
| Unknown<br />
|}<br />
<br />
Entry size is 0x10-bytes.<br />
<br />
Media offset is absoluteoffset/{mediasize}, where mediasize is hard-coded to 0x200.<br />
<br />
=Section Header Block=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x1<br />
| ?<br />
|-<br />
|-<br />
| 0x1<br />
| 0x1<br />
| ?<br />
|-<br />
| 0x2<br />
| 0x1<br />
| ?<br />
|-<br />
| 0x3<br />
| 0x1<br />
| Filesystem type. 0x2 = PFS0, 0x3 = RomFS, everything else is invalid.<br />
|-<br />
| 0x4<br />
| 0x1<br />
| Crypto type. 0 and >4 are invalid. 1 = none(plaintext from raw NCA). 2 = other crypto. 3 = regular crypto. 4 = unknown.<br />
|-<br />
| 0x5<br />
| 0x1<br />
| Padding?<br />
|-<br />
| 0x8<br />
| 0xF8<br />
| FS-specific superblock.<br />
|-<br />
| 0x100<br />
| ?<br />
| Optional BKTR header. Can be used with any section, but only known to be used with game-updates RomFS.<br />
|}<br />
<br />
The Section Header Block for each section is at absoluteoffset+0x400+(sectionid*0x200), where sectionid corresponds to the index used with the entry/hash tables.<br />
<br />
The total size is 0x200-bytes.<br />
<br />
==PFS0 superblock==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x20<br />
| SHA256 hash over the hash-table at section-start+0 with the below hash-table size.<br />
|-<br />
| 0x20<br />
| 0x4<br />
| Block size in bytes.<br />
|-<br />
| 0x24<br />
| 0x4<br />
| Must be 0x2.<br />
|-<br />
| 0x28<br />
| 0x8<br />
| Offset of hash-table. Normally zero?<br />
|-<br />
| 0x30<br />
| 0x8<br />
| Size of hash-table.<br />
|-<br />
| 0x38<br />
| 0x8<br />
| Offset relative to section-start where the PFS0 header is located.<br />
|-<br />
| 0x40<br />
| 0x8<br />
| Actual byte-size of the PFS0 filesystem relative to the PFS0 header.<br />
|-<br />
| 0x48<br />
| 0xB0<br />
| Normally zeros.<br />
|}<br />
<br />
==RomFS superblock==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x8<br />
| 0xE0<br />
| IVFC header. Basically the same as [[Savegames]] IVFC except with 2 more levels and +0x0C is non-zero, see below.<br />
|}<br />
<br />
This documents the structure of Section Header Block +0 for RomFS.<br />
<br />
=== IVFC ===<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x00<br />
| 4<br />
| Magic ("IVFC")<br />
|-<br />
| 0x04<br />
| 4<br />
| Magic Number (0x20000)<br />
|-<br />
| 0x08<br />
| 4<br />
| Master hash size?<br />
|-<br />
| 0x0C<br />
| 4<br />
| Usually 7? Unknown, could be related to total number of levels maybe?<br />
|-<br />
| 0x10<br />
| 8<br />
| Level 1 offset<br />
|-<br />
| 0x18<br />
| 8<br />
| Level 1 size<br />
|-<br />
| 0x20<br />
| 4<br />
| Level 1 block size, in log2<br />
|-<br />
| 0x24<br />
| 4<br />
| Reserved<br />
|-<br />
| 0x28<br />
| 8<br />
| Level 2 offset<br />
|-<br />
| 0x30<br />
| 8<br />
| Level 2 size<br />
|-<br />
| 0x38<br />
| 4<br />
| Level 2 block size, in log2.<br />
|-<br />
| 0x3C<br />
| 4<br />
| Reserved<br />
|-<br />
| 0x40<br />
| 8<br />
| Level 3 offset<br />
|-<br />
| 0x48<br />
| 8<br />
| Level 3 size<br />
|-<br />
| 0x50<br />
| 4<br />
| Level 3 block size, in log2.<br />
|-<br />
| 0x54<br />
| 4<br />
| Reserved<br />
|-<br />
| 0x58<br />
| 8<br />
| Level 4 offset<br />
|-<br />
| 0x60<br />
| 8<br />
| Level 4 size<br />
|-<br />
| 0x68<br />
| 4<br />
| Level 4 block size, in log2.<br />
|-<br />
| 0x6C<br />
| 4<br />
| Reserved<br />
|-<br />
| 0x70<br />
| 8<br />
| Level 5 offset<br />
|-<br />
| 0x78<br />
| 8<br />
| Level 5 size<br />
|-<br />
| 0x80<br />
| 4<br />
| Level 5 block size, in log2.<br />
|-<br />
| 0x84<br />
| 4<br />
| Reserved<br />
|-<br />
| 0x88<br />
| 8<br />
| Level 6 offset<br />
|-<br />
| 0x90<br />
| 8<br />
| Level 6 size<br />
|-<br />
| 0x98<br />
| 4<br />
| Level 6 block size, in log2.<br />
|-<br />
| 0x9C<br />
| 4<br />
| Reserved<br />
|-<br />
| 0xA0<br />
| 32<br />
| Unknown, reserved?<br />
|-<br />
| 0xC0<br />
| 32<br />
| Hash<br />
|}<br />
<br />
== BKTR ==<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x8<br />
| Offset<br />
|-<br />
|-<br />
| 0x8<br />
| 0x8<br />
| Size<br />
|-<br />
| 0x10<br />
| 0x4<br />
| "BKTR"<br />
|-<br />
| 0x14<br />
| 0x4<br />
| u32, must be <=1.<br />
|-<br />
| 0x18<br />
| 0x4<br />
| s32, must be >=1.<br />
|-<br />
| 0x1C<br />
| 0x4<br />
| ?<br />
|-<br />
| 0x20<br />
| 0x20<br />
| Same as the above 0x20-bytes except with different data.<br />
|-<br />
| 0x40<br />
| 0x4?<br />
| ?<br />
|-<br />
| 0x44<br />
| 0x4?<br />
| ?<br />
|}<br />
<br />
Using this header is enabled when offset 0x8 in this header is non-zero.<br />
<br />
The above byte-offsets are relative to the start of the section-data.<br />
<br />
The two sections specified by the two BKTR entries are usually(?) at the very end of the section data(section_endoffset-{size of BKTR sections}).<br />
<br />
===RomFS Patching===<br />
<br />
The BKTR section enables combining data from an update NCA with the RomFS from a base NCA to create a single patched RomFS image. <br />
<br />
The first BKTR entry describes how to map regions of the two RomFS images to create the patched RomFS. It has the following format:<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0 || 0x4 || Padding/Unused?<br />
|-<br />
| 0x4 || 0x4 || Number of Buckets<br />
|-<br />
| 0x8 || 0x8 || Total Size of the Virtual RomFS Image<br />
|-<br />
| 0x10 || 0x3FF0 || Base Virtual Offset for each Bucket (u64s, padded with 0s until end)<br />
|-<br />
| 0x4000 || 0x4000*X || Relocation Buckets<br />
|}<br />
<br />
Where relocation buckets are as follows:<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0 || 0x4 || Padding/Unused?<br />
|-<br />
| 0x4 || 0x4 || Number of Entries<br />
|-<br />
| 0x8 || 0x8 || End offset for this Bucket<br />
|-<br />
| 0x10 || 0x3FF0 || Relocation Entries<br />
|}<br />
<br />
Where relocation entries are as follows:<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0 || 0x8 || Address in Patched RomFS<br />
|-<br />
| 0x8 || 0x8 || Address in Source RomFS<br />
|-<br />
| 0x10 || 0x4 || 1=Is from Patch RomFS, 0=Is from Base RomFS<br />
|}<br />
<br />
The second BKTR entry describes the subsections within the Patch RomFS. It has the following format:<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0 || 0x4 || Padding/Unused?<br />
|-<br />
| 0x4 || 0x4 || Number of Buckets<br />
|-<br />
| 0x8 || 0x8 || Total Size of the Physical Patch Image<br />
|-<br />
| 0x10 || 0x3FF0 || Base Physical Offset for each Bucket (u64s, padded with 0s until end)<br />
|-<br />
| 0x4000 || 0x4000*X || Subsection Buckets<br />
|}<br />
<br />
<br />
Where subsection buckets are as follows:<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0 || 0x4 || Padding/Unused?<br />
|-<br />
| 0x4 || 0x4 || Number of Entries<br />
|-<br />
| 0x8 || 0x8 || End offset for this Bucket<br />
|-<br />
| 0x10 || 0x3FF0 || Subsection Entries<br />
|}<br />
<br />
Where subsection entries are as follows:<br />
<br />
{| class="wikitable"<br />
|-<br />
! Start<br />
! Length<br />
! Description<br />
|-<br />
| 0x0 || 0x8 || Address in Patch RomFS<br />
|-<br />
| 0x8 || 0x4 || Padding/Unused?<br />
|-<br />
| 0xC || 0x4 || Value for subsection AES-CTR<br />
|}<br />
<br />
Official code assumes the relocation entries are sorted, and performs a binary search when determining where to read from. Each subsection in the Patch RomFS has its CTR calculated separately from the others based on the value in its entry (the BKTR entries use normal crypto). Thus decrypting a Patch RomFS requires decrypting and parsing the BKTR entries before anything else.<br />
<br />
=Logo section=<br />
This is a PFS0. See [[NCA_Content_FS|here]] for the mounted-FS logo contents.<br />
<br />
=ExeFS section =<br />
This is a PFS0.<br />
<br />
See [[ExeFS|here]] for mounted-FS ExeFS contents.<br />
<br />
=Game-updates=<br />
The section-data for ncatype1 RomFS section(section1) uses section-crypto-type 0x4.<br />
<br />
Game-updates also contain multiple ncatype6 content, which contain "section0_pfs0/fragment". Some of these are just NCAs, unknown for the rest(presumably NCAs with additional crypto?). The first ncatype6 content fragment file has a NDV0 header, with the NCA starting at offset 0x44.<br />
<br />
=PFS0=<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| {Hash-table offset from superblock}<br />
| {Hash-table size from superblock}<br />
| Table of SHA256 hashes.<br />
|-<br />
| {Hash-table <offset+size> from superblock}<br />
| <br />
| Zeros for alignment to {alignment size}.<br />
|-<br />
| {PFS0 offset from superblock}<br />
| {PFS0 size from superblock}<br />
| The actual PFS0.<br />
|}<br />
<br />
This is the FS which has magicnum "PFS0" at header+0. This is very similar to [[Gamecard_Format|HFS0]]. A tool for extracting this FS is available [https://gist.github.com/yellows8/1a96c2b846f4ebc4bb45d7f7fa1eb7db here].<br />
<br />
The hash table is hashes for every {Block size from superblock} starting at the PFS0 header. The size used for the last hash is {PFS0 filesystem size from superblock} - offset_relativeto_header.<br />
<br />
See also the PFS0 superblock above.<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x4<br />
| "PFS0" Magic<br />
|-<br />
| 0x4<br />
| 0x4<br />
| Number of files<br />
|-<br />
| 0x8<br />
| 0x4<br />
| Size of the string table<br />
|-<br />
| 0xC<br />
| 0x4<br />
| Zero/Reserved<br />
|-<br />
| 0x10<br />
| X<br />
| File Entry Table<br />
|-<br />
| 0x10 + X<br />
| Y<br />
| String Table<br />
|-<br />
| 0x10 + X + Y<br />
| Z<br />
| Raw File Data<br />
|}<br />
<br />
Where File Entry Table consists of Number of Files FileEntries:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| 0x8<br />
| Offset of file in Data<br />
|-<br />
| 0x8<br />
| 0x8<br />
| Size of file in Data<br />
|-<br />
| 0x10<br />
| 0x4<br />
| Offset of filename in String Table<br />
|-<br />
| 0x14<br />
| 0x4<br />
| Normally zero?<br />
|}</div>
The-4n