Difference between revisions of "Capture services"

From Nintendo Switch Brew
Jump to navigation Jump to search
(memcmp size)
(19 intermediate revisions by 4 users not shown)
Line 1: Line 1:
 
= caps:a =
 
= caps:a =
 +
This is "nn::capsrv::sf::IAlbumAccessorService".
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || GetAlbumFileCount
 +
|-
 +
| 1 || GetAlbumFileList
 +
|-
 +
| 2 || LoadAlbumFile
 +
|-
 +
| 3 || DeleteAlbumFile
 +
|-
 +
| 4 || StorageCopyAlbumFile
 +
|-
 +
| 5 || IsAlbumMounted
 +
|-
 +
| 6 || GetAlbumUsage
 +
|-
 +
| 7 || GetAlbumFileSize
 +
|-
 +
| 8 || LoadAlbumFileThumbnail
 +
|-
 +
| 9 || [2.0.0+] LoadAlbumScreenShotImage
 +
|-
 +
| 10 || [2.0.0+] LoadAlbumScreenShotThumbnailImage
 +
|-
 +
| 11 || [2.0.0+] GetAlbumEntryFromApplicationAlbumEntry
 +
|-
 +
| 12 || [3.0.0+]
 +
|-
 +
| 13 || [3.0.0+]
 +
|-
 +
| 14 || [3.0.0+]
 +
|-
 +
| 15 || [4.0.0+]
 +
|-
 +
| 16 || [4.0.0+]
 +
|-
 +
| 17 || [4.0.0+]
 +
|-
 +
| 18 || [6.0.0+]
 +
|-
 +
| 100 || [5.0.0+]
 +
|-
 +
| 101 || [5.0.0+]
 +
|-
 +
| 202 || [1.0.0-2.3.0] SaveEditedScreenShot
 +
|-
 +
| 301 || GetLastThumbnail
 +
|-
 +
| 302 || [4.0.0+]
 +
|-
 +
| 401 || GetAutoSavingStorage
 +
|-
 +
| 501 || GetRequiredStorageSpaceSizeToCopyAll
 +
|-
 +
| 1001 || [3.0.0+]
 +
|-
 +
| 1002 || [3.0.0+]
 +
|-
 +
| 1003 || [4.0.0+]
 +
|-
 +
| 8001 || ForceAlbumUnmounted
 +
|-
 +
| 8002 || ResetAlbumMountStatus
 +
|-
 +
| 8011 || RefreshAlbumCache
 +
|-
 +
| 8012 || GetAlbumCache
 +
|-
 +
| 8013 || [4.0.0+]
 +
|-
 +
| 8021 || [2.0.0+] GetAlbumEntryFromApplicationAlbumEntryAruid
 +
|-
 +
| 10011 || SetInternalErrorConversionEnabled
 +
|-
 +
| 50000 || [6.0.0+]
 +
|-
 +
| 60002 || [4.0.0+]
 +
|}
 +
 +
Cmd1002: Takes a total of 0x38-bytes of input, two type-0x5 input buffers, and returns 0x20-bytes of output. [4.0.0+] No longer returns output, and now takes the following buffers instead: type-0x16, type-0x46, and type-0x6.
 +
 +
Cmd60002: Takes a total of 8-bytes of input, a PID, and returns an [[#IAlbumAccessorSession]].
 +
 +
== IAlbumAccessorSession ==
 +
This is "nn::capsrv::sf::IAlbumAccessorSession".
 +
 +
This was added with [4.0.0+].
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 2001 ||
 +
|-
 +
| 2002 ||
 +
|-
 +
| 2003 ||
 +
|-
 +
| 2004 ||
 +
|-
 +
| 2005 ||
 +
|-
 +
| 2006 ||
 +
|-
 +
| 2007 ||
 +
|-
 +
| 2008 ||
 +
|}
  
 
= caps:c =
 
= caps:c =
 +
This is "nn::capsrv::sf::IAlbumControlService", previously "nn::capsrv::sf::ICaptureControllerService" with [1.0.0].
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name || Notes
 +
|-
 +
| [1.0.0] 1 || ||
 +
|-
 +
| [1.0.0] 2 || ||
 +
|-
 +
| 33 || [7.0.0+] || Takes a total of 0x10-bytes of input, no output.
 +
|-
 +
| [1.0.0] 1001 || ||
 +
|-
 +
| [1.0.0] 1002 || ||
 +
|-
 +
| [1.0.0] 1011 || ||
 +
|-
 +
| 2001 || ||
 +
|-
 +
| 2002 || ||
 +
|-
 +
| 2011 || [2.0.0+] ||
 +
|-
 +
| 2012 || [2.0.0+] ||
 +
|-
 +
| 2013 || [2.0.0+] ||
 +
|-
 +
| 2014 || [2.0.0+] ||
 +
|-
 +
| 2101 || [2.0.0+] || Takes an input u8 and u64, returns a 0x18-byte struct.
 +
|-
 +
| 2102 || [2.0.0+] ||
 +
|-
 +
| [2.0.0-3.0.2] 2201 || ||
 +
|-
 +
| 2202 || [4.0.0+] ||
 +
|-
 +
| 2301 || [2.0.0+] ||
 +
|-
 +
| 2302 || [4.0.0+] ||
 +
|-
 +
| 60001 || [4.0.0+] || Takes a total of 8-bytes of input and a PID, returns an [[#IAlbumControlSession]].
 +
|}
 +
 +
== IAlbumControlSession ==
 +
This is "nn::capsrv::sf::IAlbumControlSession".
 +
 +
This was added with [4.0.0+].
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name || Notes
 +
|-
 +
| 2001 || ||
 +
|-
 +
| 2002 || ||
 +
|-
 +
| 2003 || ||
 +
|-
 +
| 2004 || ||
 +
|-
 +
| 2005 || ||
 +
|-
 +
| 2006 || ||
 +
|-
 +
| 2007 || ||
 +
|-
 +
| 2008 || ||
 +
|-
 +
| 2401 || ||
 +
|-
 +
| 2402 || ||
 +
|-
 +
| 2403 || ||
 +
|-
 +
| 2404 || ||
 +
|-
 +
| 2405 || ||
 +
|-
 +
| 2406 || [7.0.0+] ||
 +
|-
 +
| 2411 || ||
 +
|-
 +
| 2412 || ||
 +
|-
 +
| 2413 || ||
 +
|-
 +
| 2414 || ||
 +
|-
 +
| 2421 || ||
 +
|-
 +
| 2422 || ||
 +
|-
 +
| 2424 || ||
 +
|-
 +
| 2431 || ||
 +
|-
 +
| 2433 || ||
 +
|-
 +
| 2434 || ||
 +
|}
 +
 +
= caps:u =
 +
This is "nn::capsrv::sf::IAlbumApplicationService".
 +
 +
This was added with [5.0.0+].
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 32 || [7.0.0+] [[#SetShimLibraryVersion]]
 +
|-
 +
| 102 || GetAlbumFileList0AafeAruidDeprecated
 +
|-
 +
| 103 || DeleteAlbumFileByAruid
 +
|-
 +
| 104 || GetAlbumFileSizeByAruid
 +
|-
 +
| 105 || DeleteAlbumFileByAruidForDebug
 +
|-
 +
| 110 || LoadAlbumScreenShotImageByAruid
 +
|-
 +
| 120 || LoadAlbumScreenShotThumbnailImageByAruid
 +
|-
 +
| 130 || PrecheckToCreateContentsByAruid
 +
|-
 +
| 140 || [6.0.0+] GetAlbumFileList1AafeAruidDeprecated
 +
|-
 +
| 141 || [6.0.0+] GetAlbumFileList2AafeUidAruidDeprecated
 +
|-
 +
| 142 || [7.0.0+] GetAlbumFileList3AaeAruid
 +
|-
 +
| 143 || [7.0.0+] GetAlbumFileList4AaeUidAruid
 +
|-
 +
| 60002 || OpenAccessorSessionForApplication
 +
|}
 +
 +
== SetShimLibraryVersion ==
 +
Takes a total of 0x10-bytes of input and a PID, no output.
 +
 +
== IAlbumAccessorApplicationSession ==
 +
This is "nn::capsrv::sf::IAlbumAccessorApplicationSession".
 +
 +
This was added with [5.0.0+].
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 2001 || OpenAlbumMovieReadStream
 +
|-
 +
| 2002 || CloseAlbumMovieReadStream
 +
|-
 +
| 2003 || GetAlbumMovieReadStreamMovieDataSize
 +
|-
 +
| 2004 || ReadMovieDataFromAlbumMovieReadStream
 +
|-
 +
| 2005 || GetAlbumMovieReadStreamBrokenReason
 +
|}
 +
 +
= AlbumEntry =
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x8 || Unknown
 +
|-
 +
| 0x8 || 0x8 || titleID
 +
|-
 +
| 0x10 || 0x2 || Year
 +
|-
 +
| 0x12 || 0x1 || Month
 +
|-
 +
| 0x13 || 0x1 || Day
 +
|-
 +
| 0x14 || 0x1 || Hour
 +
|-
 +
| 0x15 || 0x1 || Minute
 +
|-
 +
| 0x16 || 0x1 || Second
 +
|-
 +
| 0x17 || 0x1 || Unknown
 +
|-
 +
| 0x18 || 0x1 || Unknown
 +
|-
 +
| 0x19 || 0x1 || Unknown
 +
|-
 +
| 0x1A || 0x6 || Padding?
 +
|}
 +
 +
This is "nn::capsrv::AlbumEntry". This is a 0x20-byte struct.
  
 +
The data at offset 0x10 size 0x8 corresponds to each field in the Album entry filename, prior to the "-".
  
 
= Notes =
 
= Notes =
 
 
capsrv is responsible for validating the MACs for screenshots stored on the SD card, if the setting capsrv!enable_album_screenshot_filedata_verification is non-zero.  
 
capsrv is responsible for validating the MACs for screenshots stored on the SD card, if the setting capsrv!enable_album_screenshot_filedata_verification is non-zero.  
  
 
Screenshots are validated as follows: The JPEG's MAC is extracted from the EXIF maker note, and stored. A timestamp string is generated by calling snprintf(&str, 20, "%04d:%02d:%02d %02d:%02d:%02d", ...); with stored timestamp values. If this doesn't match the timestamp string stored in EXIF, then an error 0xA34CE is returned. Otherwise, the entire JPEG is loaded into memory, and the stored EXIF maker note is cleared to zeroes. Then, an HMAC-SHA256 is computed over the entire JPEG using a hardcoded secret key. if (memcmp(calculated_hmac, stored_hmac, 0x10) == 0), the screenshot is valid, else 0xA3ACE is returned.
 
Screenshots are validated as follows: The JPEG's MAC is extracted from the EXIF maker note, and stored. A timestamp string is generated by calling snprintf(&str, 20, "%04d:%02d:%02d %02d:%02d:%02d", ...); with stored timestamp values. If this doesn't match the timestamp string stored in EXIF, then an error 0xA34CE is returned. Otherwise, the entire JPEG is loaded into memory, and the stored EXIF maker note is cleared to zeroes. Then, an HMAC-SHA256 is computed over the entire JPEG using a hardcoded secret key. if (memcmp(calculated_hmac, stored_hmac, 0x10) == 0), the screenshot is valid, else 0xA3ACE is returned.
 +
 +
In [[3.0.0]], MAC calculation was changed: now, instead of calculating an HMAC, a plain SHA256 hash is calculated. capsrv basically does screenshot_kek = spl::GenerateAesKek(<hardcoded screenshot_kek_source>); spl::LoadAesKey(screenshot_kek, <hardcoded screenshot_key_source>); MAC = spl::ComputeCmac(hash);
 +
 +
== Videos ==
 +
[[4.0.0]] includes video playback etc support in Album via mp4. These include a JPEG thumbnail, which is used for video "validation". The EXIF is also much larger: the MakerNote is 0x498-bytes, with encrypted data starting at offset +0x8. This encryption uses AES-CTR with hardcoded key/ctr. MAC calculation works the same way as the [[3.0.0]]+ JPEG MAC calculation, except with a different movie_kek_source/movie_key_source.
 +
 +
Note: the Album process itself uses libstagefright for video playback.
 +
 +
[[Category:Services]]

Revision as of 23:34, 22 August 2019

caps:a

This is "nn::capsrv::sf::IAlbumAccessorService".

Cmd Name
0 GetAlbumFileCount
1 GetAlbumFileList
2 LoadAlbumFile
3 DeleteAlbumFile
4 StorageCopyAlbumFile
5 IsAlbumMounted
6 GetAlbumUsage
7 GetAlbumFileSize
8 LoadAlbumFileThumbnail
9 [2.0.0+] LoadAlbumScreenShotImage
10 [2.0.0+] LoadAlbumScreenShotThumbnailImage
11 [2.0.0+] GetAlbumEntryFromApplicationAlbumEntry
12 [3.0.0+]
13 [3.0.0+]
14 [3.0.0+]
15 [4.0.0+]
16 [4.0.0+]
17 [4.0.0+]
18 [6.0.0+]
100 [5.0.0+]
101 [5.0.0+]
202 [1.0.0-2.3.0] SaveEditedScreenShot
301 GetLastThumbnail
302 [4.0.0+]
401 GetAutoSavingStorage
501 GetRequiredStorageSpaceSizeToCopyAll
1001 [3.0.0+]
1002 [3.0.0+]
1003 [4.0.0+]
8001 ForceAlbumUnmounted
8002 ResetAlbumMountStatus
8011 RefreshAlbumCache
8012 GetAlbumCache
8013 [4.0.0+]
8021 [2.0.0+] GetAlbumEntryFromApplicationAlbumEntryAruid
10011 SetInternalErrorConversionEnabled
50000 [6.0.0+]
60002 [4.0.0+]

Cmd1002: Takes a total of 0x38-bytes of input, two type-0x5 input buffers, and returns 0x20-bytes of output. [4.0.0+] No longer returns output, and now takes the following buffers instead: type-0x16, type-0x46, and type-0x6.

Cmd60002: Takes a total of 8-bytes of input, a PID, and returns an #IAlbumAccessorSession.

IAlbumAccessorSession

This is "nn::capsrv::sf::IAlbumAccessorSession".

This was added with [4.0.0+].

Cmd Name
2001
2002
2003
2004
2005
2006
2007
2008

caps:c

This is "nn::capsrv::sf::IAlbumControlService", previously "nn::capsrv::sf::ICaptureControllerService" with [1.0.0].

Cmd Name Notes
[1.0.0] 1
[1.0.0] 2
33 [7.0.0+] Takes a total of 0x10-bytes of input, no output.
[1.0.0] 1001
[1.0.0] 1002
[1.0.0] 1011
2001
2002
2011 [2.0.0+]
2012 [2.0.0+]
2013 [2.0.0+]
2014 [2.0.0+]
2101 [2.0.0+] Takes an input u8 and u64, returns a 0x18-byte struct.
2102 [2.0.0+]
[2.0.0-3.0.2] 2201
2202 [4.0.0+]
2301 [2.0.0+]
2302 [4.0.0+]
60001 [4.0.0+] Takes a total of 8-bytes of input and a PID, returns an #IAlbumControlSession.

IAlbumControlSession

This is "nn::capsrv::sf::IAlbumControlSession".

This was added with [4.0.0+].

Cmd Name Notes
2001
2002
2003
2004
2005
2006
2007
2008
2401
2402
2403
2404
2405
2406 [7.0.0+]
2411
2412
2413
2414
2421
2422
2424
2431
2433
2434

caps:u

This is "nn::capsrv::sf::IAlbumApplicationService".

This was added with [5.0.0+].

Cmd Name
32 [7.0.0+] #SetShimLibraryVersion
102 GetAlbumFileList0AafeAruidDeprecated
103 DeleteAlbumFileByAruid
104 GetAlbumFileSizeByAruid
105 DeleteAlbumFileByAruidForDebug
110 LoadAlbumScreenShotImageByAruid
120 LoadAlbumScreenShotThumbnailImageByAruid
130 PrecheckToCreateContentsByAruid
140 [6.0.0+] GetAlbumFileList1AafeAruidDeprecated
141 [6.0.0+] GetAlbumFileList2AafeUidAruidDeprecated
142 [7.0.0+] GetAlbumFileList3AaeAruid
143 [7.0.0+] GetAlbumFileList4AaeUidAruid
60002 OpenAccessorSessionForApplication

SetShimLibraryVersion

Takes a total of 0x10-bytes of input and a PID, no output.

IAlbumAccessorApplicationSession

This is "nn::capsrv::sf::IAlbumAccessorApplicationSession".

This was added with [5.0.0+].

Cmd Name
2001 OpenAlbumMovieReadStream
2002 CloseAlbumMovieReadStream
2003 GetAlbumMovieReadStreamMovieDataSize
2004 ReadMovieDataFromAlbumMovieReadStream
2005 GetAlbumMovieReadStreamBrokenReason

AlbumEntry

Offset Size Description
0x0 0x8 Unknown
0x8 0x8 titleID
0x10 0x2 Year
0x12 0x1 Month
0x13 0x1 Day
0x14 0x1 Hour
0x15 0x1 Minute
0x16 0x1 Second
0x17 0x1 Unknown
0x18 0x1 Unknown
0x19 0x1 Unknown
0x1A 0x6 Padding?

This is "nn::capsrv::AlbumEntry". This is a 0x20-byte struct.

The data at offset 0x10 size 0x8 corresponds to each field in the Album entry filename, prior to the "-".

Notes

capsrv is responsible for validating the MACs for screenshots stored on the SD card, if the setting capsrv!enable_album_screenshot_filedata_verification is non-zero.

Screenshots are validated as follows: The JPEG's MAC is extracted from the EXIF maker note, and stored. A timestamp string is generated by calling snprintf(&str, 20, "%04d:%02d:%02d %02d:%02d:%02d", ...); with stored timestamp values. If this doesn't match the timestamp string stored in EXIF, then an error 0xA34CE is returned. Otherwise, the entire JPEG is loaded into memory, and the stored EXIF maker note is cleared to zeroes. Then, an HMAC-SHA256 is computed over the entire JPEG using a hardcoded secret key. if (memcmp(calculated_hmac, stored_hmac, 0x10) == 0), the screenshot is valid, else 0xA3ACE is returned.

In 3.0.0, MAC calculation was changed: now, instead of calculating an HMAC, a plain SHA256 hash is calculated. capsrv basically does screenshot_kek = spl::GenerateAesKek(<hardcoded screenshot_kek_source>); spl::LoadAesKey(screenshot_kek, <hardcoded screenshot_key_source>); MAC = spl::ComputeCmac(hash);

Videos

4.0.0 includes video playback etc support in Album via mp4. These include a JPEG thumbnail, which is used for video "validation". The EXIF is also much larger: the MakerNote is 0x498-bytes, with encrypted data starting at offset +0x8. This encryption uses AES-CTR with hardcoded key/ctr. MAC calculation works the same way as the 3.0.0+ JPEG MAC calculation, except with a different movie_kek_source/movie_key_source.

Note: the Album process itself uses libstagefright for video playback.