Difference between revisions of "Internet Browser"
(166 intermediate revisions by 16 users not shown) | |||
Line 1: | Line 1: | ||
− | + | Nintendo Switch does not have a normal Internet Browser for user usage. However, there is multiple browser applets. It is the [https://web.archive.org/web/20170304075230/https://gl.access-company.com/news_event/archives/2017/170303/ NetFront NX] browser, which is based on Webkit. | |
− | + | ||
+ | When linking the Nintendo Account with Facebook, the Facebook Auth website will open, offering a search box that can be used to browse the Internet ("LoginApplet"). Alternatively, it can be accessed with custom DNS settings which simulate a Wi-Fi login page ([[#WifiWebAuthApplet|WifiWebAuthApplet]] for captive-portal). | ||
== Known User Agent Strings == | == Known User Agent Strings == | ||
{| class='wikitable' | {| class='wikitable' | ||
− | ! | + | ! System Version |
− | |||
! UA String | ! UA String | ||
|- | |- | ||
− | | | + | | [[1.0.0]] |
− | | | + | | Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.4.25 NintendoBrowser/5.1.0.11682 |
− | | Mozilla/5.0 (Nintendo Switch; | + | |- |
+ | | [[2.0.0]] | ||
+ | | Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.5.9 NintendoBrowser/5.1.0.13341 | ||
+ | |- | ||
+ | | [[2.1.0]]-[[2.3.0]] | ||
+ | | Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.5.10 NintendoBrowser/5.1.0.13343 | ||
+ | |- | ||
+ | | [[3.0.0]] | ||
+ | | Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.6.9 NintendoBrowser/5.1.0.14936 | ||
+ | |- | ||
+ | | [[4.0.0]] | ||
+ | | Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.7.9 NintendoBrowser/5.1.0.15785 | ||
+ | |- | ||
+ | | [[5.0.0]] | ||
+ | | Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.8.9 NintendoBrowser/5.1.0.16739 | ||
+ | |- | ||
+ | | [[5.1.0]] | ||
+ | | Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.9.3 NintendoBrowser/5.1.0.16958 | ||
+ | |- | ||
+ | | [[6.0.0]] | ||
+ | | Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.10.13 NintendoBrowser/5.1.0.17805 | ||
+ | |- | ||
+ | | [[6.1.0]] | ||
+ | | Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.10.14 NintendoBrowser/5.1.0.17806 | ||
+ | |- | ||
+ | | [[10.0.0]] | ||
+ | | Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/606.4 (KHTML, like Gecko) NF/6.0.1.15.4 NintendoBrowser/5.1.0.20389 | ||
+ | |} | ||
+ | |||
+ | The UA is generated with: "Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/<webkitver> (KHTML, like Gecko) NF/<nfver0>.<nfver1>.<nfver2> NintendoBrowser/5.<ninver0>.<ninver1>.<ninver2>" | ||
+ | |||
+ | == Browser Applets == | ||
+ | {| class='wikitable' | ||
+ | ! appletname (From UA) | ||
+ | ! Usage | ||
+ | ! Invalid TLS cert handling | ||
+ | ! Uses whitelist | ||
+ | ! Title ID | ||
+ | ! Notes | ||
+ | |- | ||
+ | | WebApplet | ||
+ | | General web-applet for use by applications(online manuals, ...). | ||
+ | | Displays an error dialog without an option to ignore it. | ||
+ | | Yes | ||
+ | | 010000000000100A | ||
+ | | | ||
+ | |- | ||
+ | | ShopN | ||
+ | | Actual eShop client | ||
+ | | Just displays an error-code. | ||
+ | | Yes | ||
+ | | 010000000000100B | ||
+ | | | ||
+ | |- | ||
+ | | WebApplet | ||
+ | | Offline HTML display | ||
+ | | | ||
+ | | | ||
+ | | 010000000000100F | ||
+ | | | ||
+ | |- | ||
+ | | LoginApplet | ||
+ | | Nintendo Account linking, and for linking Facebook and Twitter to suggest friends | ||
+ | | Just displays an error-code. | ||
+ | | Yes | ||
+ | | 0100000000001010 | ||
+ | | | ||
+ | |- | ||
+ | | ShareApplet | ||
+ | | Posting screenshots to social media, and (optionally) linking social media accounts | ||
+ | | Just displays an error-code. | ||
+ | | Yes | ||
+ | | 0100000000001010 | ||
+ | | | ||
+ | |- | ||
+ | | LobbyApplet | ||
+ | | "Nintendo Switch Online Lounge" | ||
+ | | Just displays an error-code. | ||
+ | | Yes | ||
+ | | 0100000000001010 | ||
+ | | | ||
+ | |- | ||
+ | | NsoApplet | ||
+ | | Nintendo Switch Online menu | ||
+ | | | ||
+ | | | ||
+ | | 0100000000001010 | ||
+ | | | ||
+ | |- | ||
+ | | WifiWebAuthApplet | ||
+ | | Captive-portal | ||
+ | | Displays an error dialog with an option to ignore it. | ||
+ | | No | ||
+ | | 0100000000001011 | ||
+ | | | ||
+ | |} | ||
+ | |||
+ | When whitelisting is enabled, you can only load page domains included in the whitelist, otherwise an error is displayed. This only applies to page navigation. Videos via the <video> tag are not affected, likewise with network requests with JS. | ||
+ | |||
+ | No known applets can directly access the SD card via mounting it. This includes ShareApplet (which posts screenshots from SD to social media). | ||
+ | |||
+ | == OSS == | ||
+ | The NROs for the OSS are stored under a separate [[Title_list|title]]. All of the web-applets use the same OSS NROs via this title. | ||
+ | |||
+ | String from v2.0 in oss_wkc.nro: "libcurl/7.50.1". | ||
+ | |||
+ | == Video Playback == | ||
+ | WifiWebAuthApplet does not fully support playing videos. It will [[Error_codes|assert]] with normal videos. The assert triggers before it even starts MP4 parsing?(For example, selecting a video from a video-tag will assert even though it doesn't send any network request for it) However, in some cases with certain MP4s using vulns it will display an error dialog instead. | ||
+ | |||
+ | With v3.0 WifiWebAuthApplet video-playback was disabled, it now throws the following error when attempting to play a video: "Support Code: 2809-1212" "This feature is not available." On past system-versions it would just trigger a fatal-error(see above). Video playback still works on the whitelisted applets following v3.0.0, which allows video playback through Facebook and embedded into Google Sites. | ||
+ | |||
+ | == Trusted RootCAs == | ||
+ | While the rootCA(s) for Let's Encrypt isn't included, Let's Encrypt is indirectly trusted via "Digital Signature Trust Co.". This seems to be only(?) the case for WifiWebAuthApplet, hence non-WifiWebAuthApplet seems to have a different set of trusted rootCAs. | ||
+ | |||
+ | == WifiWebAuthApplet == | ||
+ | When doing a connection-test in system-settings, it will detect that the captive-portal is required and display an error for it when the response for "http://conntest.nintendowifi.net/" doesn't include the "X-Organization: Nintendo" HTTP header. The web-applet will not load until something else attempts a conntest, for example when launching eShop and prior to LoginApplet launching. The initial page loaded by this applet is the above conntest URL. | ||
+ | |||
+ | This is only available starting with [[2.0.0]]. | ||
+ | |||
+ | Prior to version [[3.0.0]], this applet was launched when attempting a system update from recovery mode if needed. This was changed to display a "This feature is not available." popup instead. | ||
+ | |||
+ | The conntest URL from [[#WebWifiPageArg]] is used to poll whether the connection is usable, with the SDK [[libcurl]]. | ||
+ | |||
+ | ==Whitelisted Applets== | ||
+ | The v2.1 main-codebin page-aligned .text size is 0x1000-bytes larger than ShopN. | ||
+ | |||
+ | The file at "data:/whitelist/WhitelistLns.txt" for LoginApplet/ShareApplet/LobbyApplet, which doesn't exist in WifiWebAuthApplet, contains the following: | ||
+ | |||
+ | <nowiki>^https://([0-9A-Za-z\-]+\.)*nintendo\.net(/|$) | ||
+ | ^https?://([0-9A-Za-z\-]+\.)*nintendo\.(co\.jp|com|eu|co\.uk|es|pt|ch|at|de|nl|be|ch|ru|fr|it|co\.za|co\.kr|tw|com\.hk|com\.au|ca|co\.nz)(/|$) | ||
+ | ^https?://([0-9A-Za-z\-]+\.)*nintendo-europe\.com(/|$) | ||
+ | ^https?://([0-9A-Za-z\-]+\.)*nintendoservicecentre\.co\.uk(/|$) | ||
+ | ^https?://([0-9A-Za-z\-]+\.)*google\.(com|ad|ae|com\.af|com\.ag|com\.ai|al|am|co\.ao|com\.ar|as|at|com\.au|az|ba|com\.bd|be|bf|bg|com\.bh|bi|bj|com\.bn|com\.bo|com\.br|bs|bt|co\.bw|by|com\.bz|ca|cd|cf|cg|ch|ci|co\.ck|cl|cm|cn|com\.co|co\.cr|com\.cu|cv|com\.cy|cz|de|dj|dk|dm|com\.do|dz|com\.ec|ee|com\.eg|es|com\.et|fi|com\.fj|fm|fr|ga|ge|gg|com\.gh|com\.gi|gl|gm|gp|gr|com\.gt|gy|com\.hk|hn|hr|ht|hu|co\.id|ie|co\.il|im|co\.in|iq|is|it|je|com\.jm|jo|co\.jp|co\.ke|com\.kh|ki|kg|co\.kr|com\.kw|kz|la|com\.lb|li|lk|co\.ls|lt|lu|lv|com\.ly|co\.ma|md|me|mg|mk|ml|com\.mm|mn|ms|com\.mt|mu|mv|mw|com\.mx|com\.my|co\.mz|com\.na|com\.nf|com\.ng|com\.ni|ne|nl|no|com\.np|nr|nu|co\.nz|com\.om|com\.pa|com\.pe|com\.pg|com\.ph|com\.pk|pl|pn|com\.pr|ps|pt|com\.py|com\.qa|ro|ru|rw|com\.sa|com\.sb|sc|se|com\.sg|sh|si|sk|com\.sl|sn|so|sm|sr|st|com\.sv|td|tg|co\.th|com\.tj|tk|tl|tm|tn|to|com\.tr|tt|com\.tw|co\.tz|com\.ua|co\.ug|co\.uk|com\.uy|co\.uz|com\.vc|co\.ve|vg|co\.vi|com\.vn|vu|ws|rs|co\.za|co\.zm|co\.zw|cat)(/|$) | ||
+ | ^https://([0-9A-Za-z\-]+\.)*facebook\.com(/|$) | ||
+ | ^https://([0-9A-Za-z\-]+\.)*twitter\.com(/|$)</nowiki> | ||
+ | |||
+ | [3.0.0+]: The "google\.(com" line now starts with "^https://" instead of "https?://", hence plain HTTP is no longer allowed. The following line was added right after the original google line: "---- ^https?://([0-9A-Za-z\-]+\.)*google(\.[A-Za-z]+)*/(search|translate)\?" | ||
+ | |||
+ | [4.0.0+]: Lines 2-4 ("...nintendo\.(co...", "nintendo-europe", and "nintendoservicecentre") now starts with "^https://" instead of "https?://". Hence, plain HTTP for these are no longer allowed. | ||
+ | |||
+ | ===ShareApplet=== | ||
+ | The initial page loaded by this applet is controlled by the [[#ShareStartPage]] TLV. | ||
+ | |||
+ | The "web-lp1.share.srv.nintendo.net" site will return a HTTP 302 redirect to <nowiki>"https://nintendo.com/"</nowiki> when the specified User-Agent isn't the one for ShareApplet. | ||
+ | |||
+ | ===LobbyApplet=== | ||
+ | Support for Lobby was added with [2.0.0+]. This applet is for "Nintendo Switch Online Lounge" | ||
+ | |||
+ | The initial page loaded by this applet is: <nowiki>"https://web-lp1.znc.srv.nintendo.net/lobby/"</nowiki>. | ||
+ | |||
+ | The content of the above URL refers to "rooms", "NxView_Img_Google_Play_Icon", etc. | ||
+ | |||
+ | And also: | ||
+ | Your room has been created. | ||
+ | |||
+ | You can invite friends to the room via | ||
+ | the Nintendo Switch Online Lounge app. | ||
+ | |||
+ | === NsoApplet === | ||
+ | [11.0.0+] This applet handles the new Nintendo Switch Online menu, which is launched from qlaunch. | ||
+ | |||
+ | The initial page loaded by this applet is: <nowiki>"https://%.nso.nintendo.net/</nowiki>{string from [[#TLVs|TLV]] 0x2}" | ||
+ | |||
+ | == ShopN == | ||
+ | The initial page loaded by ShopN is: <nowiki>"https://bugyo.hac.lp1.eshop.nintendo.net/ashigaru/"</nowiki>. | ||
+ | This can be accessed via computer possesed the certificate ShopN. | ||
+ | |||
+ | The file at "data:/whitelist/WhitelistEc.txt", which doesn't exist in WifiWebAuthApplet, contains the following: | ||
+ | |||
+ | <nowiki>^https://([0-9A-Za-z\-]+\.)*eshop\.nintendo\.net($|/) | ||
+ | ^https?://([0-9A-Za-z\-]+\.)*nintendo\.(co\.jp|com|de)($|/)</nowiki> | ||
+ | |||
+ | == WebApplet == | ||
+ | ===010000000000100A=== | ||
+ | The initial page loaded by this applet is specified by the title which launched this applet. Plain HTTP is allowed. | ||
+ | |||
+ | The files under "data:/" are identical to WifiWebAuthApplet except that the content of each file differs. | ||
+ | |||
+ | This applet uses a whitelist, but it doesn't come from "data:/" like whitelisted-applet. | ||
+ | |||
+ | ==== WebApplet launch with Tetris ==== | ||
+ | The Tetris game/demo can be used to launch the online-WebApplet. This ''only'' applies to the JPN region of the game/demo: "ぷよぷよ™テトリス®S"(aka "Puyo Puyo Tetris"). Note that the gamecard for this can be used to launch the online-WebApplet on system-version >=1.0.0. | ||
+ | |||
+ | First, launch the offline-WebApplet for the manual: | ||
+ | * Game: Main-menu -> press A with the already selected top menu button -> press the R button. | ||
+ | * Demo: Main-menu -> select menu button on the right side -> press A. | ||
+ | |||
+ | Then in the manual: | ||
+ | * Press A -> select the bottom menu entry in the list. | ||
+ | * Select the SEGA icon -> press A. | ||
+ | |||
+ | The offline-WebApplet will then launch the online-WebApplet with the plain-http <nowiki>"http://sega.jp/"</nowiki> URL. Non-JPN regions of Tetris don't have any external link in the manual. For example, with your own DNS-server setup to return your own server address for this domain, you can load your own content for use with online-WebApplet. | ||
+ | |||
+ | As of 12/01/2017 this still works on the latest update for Tetris (version 1.1.2). | ||
+ | |||
+ | === Offline Applet === | ||
+ | Minus TIDs, the [[NPDM]] is the same as 010000000000100A except 010000000000100A has access to more/other services. | ||
+ | |||
+ | == Service/FS Access == | ||
+ | All browser applets have access to the following services: acc:u1, appletAE, audin:u, audren:u, audout:u, bsd:u, fatal:u, fsp-srv, hid, hid:sys, irs, ldn:m, ldr:ro, lm, erpt:c, nifm:s, ns:am, nsd:u, nvdrv:a, mm:u, pl:u, prepo:s, set, set:sys, sfdnsres, ssl, time:u, vi:s | ||
+ | |||
+ | LoginApplet/ShareApplet/LobbyApplet have access to the above + caps:a. | ||
+ | |||
+ | ShopN has access to the above + nim:shp. | ||
+ | |||
+ | Unlike the applets listed above, WebApplet TID 010000000000100A has access to the [[Filesystem_services|FS]] MountContent* commands. This is so that it can load the whitelist from "/accessible-urls/accessible-urls.txt" in the mounted FS, from [[NCA]]-type4 where titleID={application which launched this applet}. | ||
+ | |||
+ | == Heap == | ||
+ | The size used for [[SVC|svcSetHeapSize]] by the web-applets is 0x15600000. Under ShopN, the largest size that can be passed to this without an error being returned, is 0x1B400000. | ||
+ | |||
+ | The size used by title 010000000000100A (on 10.0.0 at least) is 0x14200000. | ||
+ | |||
+ | The heap for the main-codebin (<code>malloc</code>/<code>operator new</code>) uses nn::lmem::*ExpHeap. [8.0.0+] <code>malloc</code>/<code>operator new</code> now checks the return-addr (addr located in a relevant NRO), with wkc_malloc_crashonfailure being called for the allocation if the check passes, otherwise a normal allocation is done (the code which runs for this will Abort if allocation fails). | ||
+ | |||
+ | <code>malloc</code> passes the input size directly to the called func. <code>operator new</code> when handling normal non-wkc allocations passes the following to the called func: <code>sxtw x1, {inw0}</code> (for wkc allocations the size is passed directly). [12.1.0+] The size is now passed directly (64bit) without using sxtw. | ||
+ | |||
+ | [11.0.0+] There's now optional code for using [[SVC|svcMapPhysicalMemoryUnsafe]] etc, however it's unknown what sets the flag for this. An Abort string used this is: "{path}/TransferredMemoryManager.cpp" | ||
+ | |||
+ | == Applet Launching == | ||
+ | The web-applets are launched using a storage containing the input arg data, on exit the output storage contains the "*ReturnValue" reply data. | ||
+ | |||
+ | Input/output storage size for TLV data is 0x2000-bytes. | ||
+ | |||
+ | === Library Applet Versions === | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! System Version || Value | ||
+ | |- | ||
+ | | [1.0.0+] || 0x20000 | ||
+ | |- | ||
+ | | [3.0.0+] || 0x30000 | ||
+ | |- | ||
+ | | [5.0.0+] || 0x50000 | ||
+ | |- | ||
+ | | [6.0.0+] || 0x60000 | ||
+ | |- | ||
+ | | [8.0.0+] || 0x80000 | ||
+ | |} | ||
+ | |||
+ | The above only (?) applies to non-WebWifi. WebWifi uses version 0x0. | ||
+ | |||
+ | === ShimKind === | ||
+ | This enum is "nn::web::common::ShimKind". | ||
+ | |||
+ | This indicates the type of web-applet. | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Value | ||
+ | ! Name | ||
+ | |- | ||
+ | | 1 | ||
+ | | Shop | ||
+ | |- | ||
+ | | 2 | ||
+ | | Login | ||
+ | |- | ||
+ | | 3 | ||
+ | | Offline | ||
+ | |- | ||
+ | | 4 | ||
+ | | Share | ||
+ | |- | ||
+ | | 5 | ||
+ | | Web | ||
+ | |- | ||
+ | | 6 | ||
+ | | Wifi | ||
+ | |- | ||
+ | | 7 | ||
+ | | Lobby | ||
+ | |- | ||
+ | | 8 | ||
+ | | [[#NsoApplet|Lhub]] | ||
+ | |} | ||
+ | |||
+ | === WebSession === | ||
+ | With [5.0.0+] sdk-nso added <code>nn::web::Session::</code>. With [6.0.0+] this was removed, however it was reintroduced with [7.0.0+] as <code>nn::web::*WebSession</code> (for ShimKind Offline and Web). | ||
+ | |||
+ | This is for sending/receiving [[#SessionMessage]]s via applet Interactive storage. | ||
+ | |||
+ | During state init, max_messages is set to 0xA ([7.0.0+] 0x10), with message_count=0 and cur_size=0. [5.0.0-5.1.0] max_size is set to 0x5000. [7.0.0+] Two queues are used for message_count/cur_size: first one is for BrowserEngineContent (max_size 0x8000 is used), the second one is for non-BrowserEngineContent (max_size 0x1000 is used). | ||
+ | |||
+ | When sending messages, there has to be an available message slot available (<code>max_messages!=message_count</code>), and there has to be enough space available (<code>msghdr_contentsize+0x10 + cur_size <= max_size</code>). After pushing the storage, message_count is incremented and cur_size is increased by <code>msghdr_contentsize+0x10</code>. | ||
+ | |||
+ | When receiving messages, it will repeatedly pop Interactive output storage until no more are available. Non-Ack messages are Acked. | ||
+ | * Ack: Verifies that message_count is not already 0, then decrements it. Then cur_size is decreased by the u32 loaded from msgcontent+0. | ||
+ | * 0x0: Does some validation. Reads the message content into the user buffer, when contentsize is non-zero. The original contentsize is written to an user output param. The last byte in the user buffer (contentsize clamped to the user max-buf-size, -1) is set to 0 for NUL-termination. | ||
+ | |||
+ | Next info was tested in 9.0.0 | ||
+ | |||
+ | In the js side (which is only available when enabled via the JsExtensionEnabled TLV), there is a method called <code>window.nx.sendMessage(arg)</code> that sends data to the native side, this method returns a boolean indicating if sending was successful and accepts a string as an argument. The string is encoded like a C null terminated string in the message content. For receive messages from native part, there is a dom event called <code>message</code> which is dispatched when a message arrives. The event can be listened using <code>window.nx.addEventListener("message", callback)</code> being callback a function which first parameter is like a dom event arg and contains a member called <code>data</code> which contains the string decoded from the arrived message. | ||
+ | |||
+ | If messages aren't acked by the native part, js side will not longer receive messages. Ack to web applet '''must''' have 4 bytes after the message content or the applet will Abort. | ||
+ | |||
+ | ==== SessionMessage ==== | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Offset | ||
+ | ! Size | ||
+ | ! Description | ||
+ | |- | ||
+ | | 0x0 | ||
+ | | 0x10 | ||
+ | | [[#SessionMessageHeader]] | ||
+ | |- | ||
+ | | 0x10 | ||
+ | | Size from header | ||
+ | | Message content | ||
+ | |- | ||
+ | | After message content | ||
+ | | 0x4 if message is ack, 0x0 otherwise | ||
+ | | Padding | ||
|} | |} | ||
+ | |||
+ | ==== SessionMessageHeader ==== | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Offset | ||
+ | ! Size | ||
+ | ! Description | ||
+ | |- | ||
+ | | 0x0 | ||
+ | | 0x4 | ||
+ | | Message Kind ([[#WebSessionSendMessageKind]] / [[#WebSessionReceiveMessageKind]]) | ||
+ | |- | ||
+ | | 0x4 | ||
+ | | 0x4 | ||
+ | | Data size following the header. | ||
+ | |- | ||
+ | | 0x8 | ||
+ | | 0x8 | ||
+ | | Unused | ||
+ | |} | ||
+ | |||
+ | ==== WebSessionSendMessageKind ==== | ||
+ | This is "nn::web::detail::WebSessionSendMessageKind". | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! ID | ||
+ | ! Content size | ||
+ | ! Description | ||
+ | |- | ||
+ | | 0x0 | ||
+ | | Arbitrary | ||
+ | | BrowserEngine Content, NUL-terminated string. Used to communicate with the applet via JsExtensions used by the Js being run by the applet on the current page. | ||
+ | |- | ||
+ | | 0x100 | ||
+ | | 0x0 | ||
+ | | SystemMessage Appear. Requests the applet to Appear, this is only needed with [[#WebSessionBootMode]] AllForegroundInitiallyHidden. | ||
+ | |- | ||
+ | | 0x1000 | ||
+ | | 0xC | ||
+ | | Ack. Content: first u32 is the entire storage size of the message being acked, the rest is not used. | ||
+ | |} | ||
+ | |||
+ | ==== WebSessionReceiveMessageKind ==== | ||
+ | This is "nn::web::detail::WebSessionReceiveMessageKind". | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! ID | ||
+ | ! Content size | ||
+ | ! Description | ||
+ | |- | ||
+ | | 0x0 | ||
+ | | Arbitrary | ||
+ | | BrowserEngine Content, see [[#WebSessionSendMessageKind]]. | ||
+ | |- | ||
+ | | 0x1000 | ||
+ | | 0xC | ||
+ | | Ack BrowserEngine | ||
+ | |- | ||
+ | | 0x1001 | ||
+ | | 0xC | ||
+ | | Ack SystemMessage | ||
+ | |} | ||
+ | |||
+ | === WebWifiPageArg === | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Offset | ||
+ | ! Size | ||
+ | ! Description | ||
+ | |- | ||
+ | | 0x0 || 0x4 || Official sw sets this to 0 with appletStorageWrite, separately from the rest of the config struct. | ||
+ | |- | ||
+ | | 0x4 || 0x100 || URL used for the connection-test requests. | ||
+ | |- | ||
+ | | 0x104 || 0x400 || Initial URL navigated to by the applet. | ||
+ | |- | ||
+ | | 0x504 || 0x10 || NIFM Network UUID. Can be value zero. Only used by the applet when conntest_url is set. | ||
+ | |- | ||
+ | | 0x514 || 0x4 || Input value for nifm cmd SetRequirementByRevision. Can be value zero. Only used by the applet when conntest_url is set. | ||
+ | |} | ||
+ | |||
+ | This is the input struct for WifiWebAuthApplet. This is a total of 0x518-bytes. | ||
+ | |||
+ | When the conntest_url is empty, the applet will test the connection with nifm and throw an error on failure. | ||
+ | |||
+ | === WebWifiReturnValue === | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Offset | ||
+ | ! Size | ||
+ | ! Description | ||
+ | |- | ||
+ | | 0x0 || 0x4 || ? | ||
+ | |- | ||
+ | | 0x4 || 0x8 || Result | ||
+ | |} | ||
+ | |||
+ | This is the output struct for WifiWebAuthApplet. This is a total of 0x8-bytes. | ||
+ | |||
+ | === WebCommonReturnValue === | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Offset | ||
+ | ! Size | ||
+ | ! Description | ||
+ | |- | ||
+ | | 0x0 || 0x4 || u32 exitReason | ||
+ | |- | ||
+ | | 0x4 || 0x4 || Padding | ||
+ | |- | ||
+ | | 0x8 || 0x1000 || lastUrl string | ||
+ | |- | ||
+ | | 0x1008 || 0x8 || lastUrlSize | ||
+ | |} | ||
+ | |||
+ | This is the 0x1010-byte output storage used by all non-WebWifi applets - except for Share which returns a TLV storage on [3.0.0+], and Web on [8.0.0+]. | ||
+ | |||
+ | === WebArgHeader === | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Offset | ||
+ | ! Size | ||
+ | ! Description | ||
+ | |- | ||
+ | | 0x0 || 0x2 || Total [[#WebArgTLV]] entries following this struct. | ||
+ | |- | ||
+ | | 0x2 || 0x2 || Padding | ||
+ | |- | ||
+ | | 0x4 || 0x4 || [[#ShimKind]] | ||
+ | |} | ||
+ | |||
+ | This is the header struct at offset 0 in the input web Arg storage for non-WebWifi. This is a total of 0x8-bytes. The total storage size used for input/output TLVs is 0x2000. | ||
+ | |||
+ | === WebArgTLV === | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Offset | ||
+ | ! Size | ||
+ | ! Description | ||
+ | |- | ||
+ | | 0x0 || 0x2 || Type of this arg. | ||
+ | |- | ||
+ | | 0x2 || 0x2 || Size of the arg data following this struct. | ||
+ | |- | ||
+ | | 0x4 || 0x4 || Padding | ||
+ | |} | ||
+ | |||
+ | Web TLV used in the input web Arg storage, after [[#WebArgHeader]]. This is a total of 0x8-bytes. | ||
+ | |||
+ | === WebBootFooterButtonEntry === | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Offset | ||
+ | ! Size | ||
+ | ! Description | ||
+ | |- | ||
+ | | 0x0 || 0x4 || [[#FooterButtonId]] | ||
+ | |- | ||
+ | | 0x4 || 0x1 || u8 bool visible flag | ||
+ | |- | ||
+ | | 0x5 || 0x2 || ? | ||
+ | |- | ||
+ | | 0x7 || 0x1 || ? | ||
+ | |} | ||
+ | |||
+ | === TLVs === | ||
+ | All strings are NUL-terminated. | ||
+ | |||
+ | ==== Input TLVs ==== | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! System Version | ||
+ | ! Applets | ||
+ | ! Type | ||
+ | ! Size | ||
+ | ! Value | ||
+ | ! Description | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | | ||
+ | | 0x1 | ||
+ | | 0xC00 | ||
+ | | string | ||
+ | | Initial URL | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | | ||
+ | | 0x3 | ||
+ | | 0x400 | ||
+ | | string | ||
+ | | CallbackUrl | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | | ||
+ | | 0x4 | ||
+ | | 0x400 | ||
+ | | string | ||
+ | | CallbackableUrl | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | Offline | ||
+ | | 0x5 | ||
+ | | 0x8 | ||
+ | | u64 titleID | ||
+ | | ApplicationId, for DocumentKind_OfflineHtmlPage/DocumentKind_ApplicationLegalInformation. Should be zero for DocumentKind_OfflineHtmlPage since it's ignored. | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | Offline | ||
+ | | 0x6 | ||
+ | | 0xC00 | ||
+ | | string | ||
+ | | DocumentPath | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | Offline | ||
+ | | 0x7 | ||
+ | | 0x4 | ||
+ | | u32 enum OfflineDocumentKind | ||
+ | | [[#DocumentKind]] | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | Offline | ||
+ | | 0x8 | ||
+ | | 0x8 | ||
+ | | u64 titleID | ||
+ | | SystemDataId, for DocumentKind_SystemDataPage. | ||
+ | |- | ||
+ | | | ||
+ | | Share | ||
+ | | 0x9 | ||
+ | | 0x4 | ||
+ | | u32 enum [[#ShareStartPage]] | ||
+ | | ShareStartPage | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | | ||
+ | | 0xA | ||
+ | | 0x1000 | ||
+ | | string | ||
+ | | Whitelist. If not formatted properly, the applet will exit briefly after the applet is launched. Each line is a regex for each whitelisted URL. | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | | ||
+ | | 0xB | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | News flag. When set the domain from the input URL is automatically whitelisted, in addition to any already loaded whitelist. | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | | ||
+ | | 0xE | ||
+ | | 0x10 | ||
+ | | userID | ||
+ | | userID, controls which user-specific savedata to mount. | ||
+ | |- | ||
+ | | | ||
+ | | Share | ||
+ | | 0xF | ||
+ | | 0x20 | ||
+ | | [[Capture_services|AlbumEntry]] | ||
+ | | AlbumEntry0 | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | | ||
+ | | 0x10 | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | ScreenShotEnabled. Controls whether screen-shot capture is allowed. | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | | ||
+ | | 0x11 | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | EcClientCertEnabled | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | | ||
+ | | 0x12 | ||
+ | | 0x1 | ||
+ | | u8 | ||
+ | | ? | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | Offline | ||
+ | | 0x13 | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | PlayReportEnabled | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | | ||
+ | | 0x14 | ||
+ | | 0x1 | ||
+ | | u8 | ||
+ | | ? | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | | ||
+ | | 0x15 | ||
+ | | 0x1 | ||
+ | | u8 | ||
+ | | ? | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | | ||
+ | | 0x17 | ||
+ | | 0x4 | ||
+ | | u32 enum [[#BootDisplayKind]] | ||
+ | | BootDisplayKind | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | | ||
+ | | 0x18 | ||
+ | | 0x4 | ||
+ | | u32 enum [[#BackgroundKind]] | ||
+ | | BackgroundKind | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | | ||
+ | | 0x19 | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | FooterEnabled. Controls whether the UI footer is enabled. | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | | ||
+ | | 0x1A | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | PointerEnabled | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | | ||
+ | | 0x1B | ||
+ | | 0x4 | ||
+ | | u32 enum [[#LeftStickMode]] | ||
+ | | LeftStickMode | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | | ||
+ | | 0x1C | ||
+ | | 0x4 | ||
+ | | s32 | ||
+ | | KeyRepeatFrame, first param | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | | ||
+ | | 0x1D | ||
+ | | 0x4 | ||
+ | | s32 | ||
+ | | KeyRepeatFrame, second param | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | | ||
+ | | 0x1E | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | Set after BootAsMediaPlayer with the value inverted. | ||
+ | |- | ||
+ | | [1.0.0+] | ||
+ | | | ||
+ | | 0x1F | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | DisplayUrlKind (<code>value = (input_enumval==0x1)</code>) | ||
+ | |- | ||
+ | | [2.0.0+] | ||
+ | | | ||
+ | | 0x21 | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | BootAsMediaPlayer | ||
+ | |- | ||
+ | | [2.0.0+] | ||
+ | | | ||
+ | | 0x22 | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | ShopJumpEnabled | ||
+ | |- | ||
+ | | [2.0.0+] | ||
+ | | | ||
+ | | 0x23 | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | [6.0.0+] MediaAutoPlayEnabled ([2.0.0-5.1.0] MediaPlayerUserGestureRestrictionEnabled) | ||
+ | |- | ||
+ | | [2.0.0+] | ||
+ | | | ||
+ | | 0x24 | ||
+ | | 0x100 | ||
+ | | string | ||
+ | | LobbyParameter | ||
+ | |- | ||
+ | | [3.0.0+] | ||
+ | | Share | ||
+ | | 0x26 | ||
+ | | 0x20 | ||
+ | | [[Capture_services|ApplicationAlbumEntry]] | ||
+ | | ApplicationAlbumEntry | ||
+ | |- | ||
+ | | [3.0.0+] | ||
+ | | | ||
+ | | 0x27 | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | JsExtensionEnabled | ||
+ | |- | ||
+ | | [4.0.0+] | ||
+ | | Share | ||
+ | | 0x28 | ||
+ | | 0x100 | ||
+ | | string | ||
+ | | AdditionalCommentText | ||
+ | |- | ||
+ | | [4.0.0+] | ||
+ | | | ||
+ | | 0x29 | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | TouchEnabledOnContents | ||
+ | |- | ||
+ | | [4.0.0+] | ||
+ | | | ||
+ | | 0x2A | ||
+ | | 0x80 | ||
+ | | string | ||
+ | | UserAgentAdditionalString. " " followed by this string are appended to the normal User-Agent string. | ||
+ | |- | ||
+ | | [4.0.0+] | ||
+ | | Share | ||
+ | | 0x2B | ||
+ | | 0x10 | ||
+ | | u8 array | ||
+ | | AdditionalMediaData0 (If the user-input size is less than 0x10, the remaining tmp data used for the TLV is cleared) | ||
+ | |- | ||
+ | | [4.0.0+] | ||
+ | | | ||
+ | | 0x2C | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | MediaPlayerAutoCloseEnabled | ||
+ | |- | ||
+ | | [4.0.0+] | ||
+ | | | ||
+ | | 0x2D | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | PageCacheEnabled | ||
+ | |- | ||
+ | | [4.0.0+] | ||
+ | | | ||
+ | | 0x2E | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | WebAudioEnabled | ||
+ | |- | ||
+ | | [5.0.0+] | ||
+ | | | ||
+ | | 0x2F | ||
+ | | 0x1 | ||
+ | | u8 | ||
+ | | ? | ||
+ | |- | ||
+ | | [5.0.0+] | ||
+ | | | ||
+ | | 0x31 | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | When set, indicates the whitelist for YouTubeVideo should be used (loaded from web-applet RomFS). | ||
+ | |- | ||
+ | | [5.0.0+] | ||
+ | | | ||
+ | | 0x32 | ||
+ | | 0x4 | ||
+ | | u32 enum *WebFooterFixedKind | ||
+ | | FooterFixedKind | ||
+ | |- | ||
+ | | [5.0.0+] | ||
+ | | | ||
+ | | 0x33 | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | PageFadeEnabled | ||
+ | |- | ||
+ | | [5.0.0+] | ||
+ | | Share | ||
+ | | 0x34 | ||
+ | | 0x20 | ||
+ | | s8 data[32] | ||
+ | | MediaCreatorApplicationRatingAge | ||
+ | |- | ||
+ | | [5.0.0+] | ||
+ | | | ||
+ | | 0x35 | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | BootLoadingIconEnabled | ||
+ | |- | ||
+ | | [5.0.0+] | ||
+ | | | ||
+ | | 0x36 | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | PageScrollIndicatorEnabled | ||
+ | |- | ||
+ | | [6.0.0+] | ||
+ | | | ||
+ | | 0x37 | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | MediaPlayerSpeedControlEnabled | ||
+ | |- | ||
+ | | [6.0.0+] | ||
+ | | Share | ||
+ | | 0x38 | ||
+ | | 0x20 | ||
+ | | [[Capture_services|AlbumEntry]] | ||
+ | | AlbumEntry1 | ||
+ | |- | ||
+ | | [6.0.0+] | ||
+ | | Share | ||
+ | | 0x39 | ||
+ | | 0x20 | ||
+ | | [[Capture_services|AlbumEntry]] | ||
+ | | AlbumEntry2 | ||
+ | |- | ||
+ | | [6.0.0+] | ||
+ | | Share | ||
+ | | 0x3A | ||
+ | | 0x20 | ||
+ | | [[Capture_services|AlbumEntry]] | ||
+ | | AlbumEntry3 | ||
+ | |- | ||
+ | | [6.0.0+] | ||
+ | | Share | ||
+ | | 0x3B | ||
+ | | 0x10 | ||
+ | | u8 array | ||
+ | | AdditionalMediaData1 | ||
+ | |- | ||
+ | | [6.0.0+] | ||
+ | | Share | ||
+ | | 0x3C | ||
+ | | 0x10 | ||
+ | | u8 array | ||
+ | | AdditionalMediaData2 | ||
+ | |- | ||
+ | | [6.0.0+] | ||
+ | | Share | ||
+ | | 0x3D | ||
+ | | 0x10 | ||
+ | | u8 array | ||
+ | | AdditionalMediaData3 | ||
+ | |- | ||
+ | | [6.0.0+] | ||
+ | | BootFooterButton | ||
+ | | 0x3E | ||
+ | | 0x80 | ||
+ | | Array of [[#WebBootFooterButtonEntry]] with 0x10 entries. | ||
+ | | BootFooterButton | ||
+ | |- | ||
+ | | [6.0.0+] | ||
+ | | | ||
+ | | 0x3F | ||
+ | | 0x4 | ||
+ | | float | ||
+ | | OverrideWebAudioVolume | ||
+ | |- | ||
+ | | [6.0.0+] | ||
+ | | | ||
+ | | 0x40 | ||
+ | | 0x4 | ||
+ | | float | ||
+ | | OverrideMediaAudioVolume | ||
+ | |- | ||
+ | | [7.0.0+] | ||
+ | | | ||
+ | | 0x41 | ||
+ | | 0x4 | ||
+ | | u32 enum [[#WebSessionBootMode]] | ||
+ | | BootMode | ||
+ | |- | ||
+ | | [7.0.0+] | ||
+ | | | ||
+ | | 0x42 | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | Enables using [[#WebSession]] when set. | ||
+ | |- | ||
+ | | [8.0.0+] | ||
+ | | Offline | ||
+ | | 0x43 | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | MediaPlayerUiEnabled | ||
+ | |- | ||
+ | | [11.0.0+] | ||
+ | | | ||
+ | | 0x44 | ||
+ | | 0x1 | ||
+ | | bool | ||
+ | | TransferMemoryEnabled | ||
+ | |} | ||
+ | |||
+ | Offline: title to load the content from is controlled by ApplicationId/SystemDataId. With DocumentKind_OfflineHtmlPage, it will ignore this and only load from the user-process title. | ||
+ | |||
+ | Offline DocumentPath: Initial document path in RomFS, without the leading '/'. For DocumentKind_OfflineHtmlPage, this is relative to "html-document/" in RomFS. For the other DocumentKind values, this is relative to "/" in RomFS. This path must contain ".htdocs/". | ||
+ | |||
+ | Share/Lobby: if a non-zero userID isn't set, the applet will launch the profile-selector applet to select an account. | ||
+ | |||
+ | Share: An error will be displayed if neither AlbumEntry or ApplicationAlbumEntry are set, with [[#ShareStartPage|ShareStartPage_Default]]. | ||
+ | |||
+ | [6.0.0+] <code>AddAlbumEntryAndMediaData</code> was added: | ||
+ | * Looks for AlbumEntry{N} TLVs, when a TLV is not found it is written, then the associated AdditionalMediaData{N} TLV is written the same way as AdditionalMediaData0. If all AlbumEntry{N} TLVs already exist, this returns without writing anything. | ||
+ | |||
+ | TransferMemoryEnabled: sdknso only exposes this for the Web applet. The sdknso func uses <code>nn::os::QueryMemoryInfo</code> at the start of the func, however the output is unused. The applet doesn't seem to parse this TLV. | ||
+ | |||
+ | ==== Output TLVs ==== | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! System Version | ||
+ | ! Applets | ||
+ | ! Type | ||
+ | ! Size | ||
+ | ! Value | ||
+ | ! Description | ||
+ | |- | ||
+ | | [3.0.0+] | ||
+ | | Share, Web | ||
+ | | 0x1 | ||
+ | | 0x4 | ||
+ | | u32 | ||
+ | | ShareExitReason | ||
+ | |- | ||
+ | | [3.0.0+] | ||
+ | | Share, Web | ||
+ | | 0x2 | ||
+ | | | ||
+ | | string | ||
+ | | LastUrl | ||
+ | |- | ||
+ | | [3.0.0+] | ||
+ | | Share, Web | ||
+ | | 0x3 | ||
+ | | 0x8 | ||
+ | | u64 | ||
+ | | LastUrlSize | ||
+ | |- | ||
+ | | [3.0.0+] | ||
+ | | Share | ||
+ | | 0x4 | ||
+ | | 0x4 | ||
+ | | u32 | ||
+ | | SharePostResult | ||
+ | |- | ||
+ | | [3.0.0+] | ||
+ | | Share | ||
+ | | 0x5 | ||
+ | | | ||
+ | | string | ||
+ | | PostServiceName | ||
+ | |- | ||
+ | | [3.0.0+] | ||
+ | | Share | ||
+ | | 0x6 | ||
+ | | 0x8 | ||
+ | | u64 | ||
+ | | PostServiceNameSize | ||
+ | |- | ||
+ | | [3.0.0+] | ||
+ | | Share | ||
+ | | 0x7 | ||
+ | | | ||
+ | | string | ||
+ | | PostId | ||
+ | |- | ||
+ | | [3.0.0+] | ||
+ | | Share | ||
+ | | 0x8 | ||
+ | | 0x8 | ||
+ | | u64 | ||
+ | | PostIdSize | ||
+ | |- | ||
+ | | [8.0.0+] | ||
+ | | Web | ||
+ | | 0x9 | ||
+ | | 0x1 | ||
+ | | u8 bool | ||
+ | | MediaPlayerAutoClosedByCompletion | ||
+ | |} | ||
+ | |||
+ | These are used for Share-applet on [3.0.0+], and with Web on [8.0.0+]. Official user-processes doesn't check the TLV size for any of these. | ||
+ | |||
+ | ==== DocumentKind ==== | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Value | ||
+ | ! Name | ||
+ | ! Description | ||
+ | |- | ||
+ | | 0x1 | ||
+ | | DocumentKind_OfflineHtmlPage | ||
+ | | Use the HtmlDocument NCA content from the application. | ||
+ | |- | ||
+ | | 0x2 | ||
+ | | DocumentKind_ApplicationLegalInformation | ||
+ | | Use the LegalInformation NCA content from the application. | ||
+ | |- | ||
+ | | 0x3 | ||
+ | | DocumentKind_SystemDataPage | ||
+ | | Use the Data NCA content from the specified title, see also: [[Title_list#System_Data_Archives]] | ||
+ | |} | ||
+ | |||
+ | This controls the kind of content to mount with Offline-applet. | ||
+ | |||
+ | ==== ShareStartPage ==== | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Value | ||
+ | ! Name | ||
+ | ! URL | ||
+ | |- | ||
+ | | 0 | ||
+ | | ShareStartPage_Default | ||
+ | | [[Network|"https://web-%.share.srv.nintendo.net/"]] | ||
+ | |- | ||
+ | | 1 | ||
+ | | ShareStartPage_Settings | ||
+ | | [[Network|"https://web-%.share.srv.nintendo.net/settings/"]] | ||
+ | |} | ||
+ | |||
+ | This enum controls the initial page for ShareApplet. | ||
+ | |||
+ | ==== BootDisplayKind ==== | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Value | ||
+ | ! Name | ||
+ | ! Description | ||
+ | |- | ||
+ | | 0 | ||
+ | | BootDisplayKind_White | ||
+ | | Default white background. | ||
+ | |- | ||
+ | | 1 | ||
+ | | | ||
+ | | Unknown. Used by Offline default Arg initialization for DocumentKind_ApplicationLegalInformation/DocumentKind_SystemDataPage. | ||
+ | |- | ||
+ | | 2 | ||
+ | | BootDisplayKind_Black | ||
+ | | Black background. | ||
+ | |- | ||
+ | | 3 | ||
+ | | | ||
+ | | Unknown. Used by Share default Arg initialization. | ||
+ | |- | ||
+ | | 4 | ||
+ | | | ||
+ | | Unknown. Used by Lobby default default Arg initialization. | ||
+ | |} | ||
+ | |||
+ | Kind values for BootDisplayKind. Controls the background color while displaying the loading screen during applet boot. Also controls the BackgroundKind when value is non-zero. | ||
+ | |||
+ | The applet converts this to internal values. | ||
+ | * BootDisplayKind 0: | ||
+ | ** If launched by an Application: | ||
+ | *** If [[#BackgroundKind]] is 2..1, return 3..2. When 0, run the below, otherwise assert. | ||
+ | ** return TLV value from BootAsMediaPlayer | ||
+ | * BootDisplayKind 1..4: return 0..3. | ||
+ | |||
+ | ==== BackgroundKind ==== | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Value | ||
+ | ! Name | ||
+ | ! Description | ||
+ | |- | ||
+ | | 0 | ||
+ | | | ||
+ | | Unknown. Used by Offline default Arg initialization for DocumentKind_ApplicationLegalInformation/DocumentKind_SystemDataPage. | ||
+ | |- | ||
+ | | 1 | ||
+ | | | ||
+ | | Same as [[#BootDisplayKind]] value 3. | ||
+ | |- | ||
+ | | 2 | ||
+ | | | ||
+ | | Same as [[#BootDisplayKind]] value 4. Used by Lobby default Arg initialization. | ||
+ | |} | ||
+ | |||
+ | Kind values for BackgroundKind. Only used when [[#BootDisplayKind]] is 0. | ||
+ | |||
+ | ==== LeftStickMode ==== | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Value | ||
+ | ! Name | ||
+ | ! Description | ||
+ | |- | ||
+ | | 0 | ||
+ | | LeftStickMode_Pointer | ||
+ | | The user can directly control the pointer via the left-stick. | ||
+ | |- | ||
+ | | 1 | ||
+ | | LeftStickMode_Cursor | ||
+ | | The user can only select elements on the page via the left-stick. | ||
+ | |} | ||
+ | |||
+ | Controls the initial mode, this can be toggled by the user via the pressing the left-stick button. If the Pointer flag is set to false, only LeftStickMode_Cursor will be used and mode toggle by the user is disabled (input value ignored). | ||
+ | |||
+ | ==== FooterButtonId ==== | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Value | ||
+ | ! Name | ||
+ | ! Description | ||
+ | |- | ||
+ | | 0 | ||
+ | | None | ||
+ | | None, for empty [[#WebBootFooterButtonEntry]]. Invalid for use as an input Id. | ||
+ | |- | ||
+ | | 1 | ||
+ | | | ||
+ | | | ||
+ | |- | ||
+ | | 2 | ||
+ | | | ||
+ | | | ||
+ | |- | ||
+ | | 3 | ||
+ | | | ||
+ | | | ||
+ | |- | ||
+ | | 4 | ||
+ | | | ||
+ | | | ||
+ | |- | ||
+ | | 5 | ||
+ | | | ||
+ | | | ||
+ | |- | ||
+ | | 6 | ||
+ | | | ||
+ | | | ||
+ | |- | ||
+ | | 7 | ||
+ | | | ||
+ | | Values starting with this are invalid. | ||
+ | |- | ||
+ | |} | ||
+ | |||
+ | ==== WebSessionBootMode ==== | ||
+ | This is "nn::web::WebSessionBootMode". | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Value | ||
+ | ! Name | ||
+ | ! Description | ||
+ | |- | ||
+ | | 0 | ||
+ | | | ||
+ | | Normal/default (AllForeground) | ||
+ | |- | ||
+ | | 1 | ||
+ | | | ||
+ | | AllForegroundInitiallyHidden | ||
+ | |} | ||
+ | |||
+ | This controls which [[Applet_Manager_services|LibraryAppletMode]] the applet will be launched with, by the user-process. The TLV for this seems to be ignored by the applet. | ||
+ | |||
+ | ==== LastUrl ==== | ||
+ | When the applet loads a page where the beginning of the URL matches the URL from CallbackUrl, the applet will exit and set LastUrl to that URL (exit doesn't occur when CallbackableUrl is set). With Offline-applet for CallbackUrl handling, it compares the domain with "localhost" instead of using the CallbackUrl TLV. | ||
+ | |||
+ | == Versions == | ||
+ | |||
+ | === [[1.0.0]] === | ||
+ | "shareddata:/buildinfo/buildinfo.dat" content: | ||
+ | r:11682 | ||
+ | p:NX64 | ||
+ | v:Pilot | ||
+ | d:2016-11-25 23:30 | ||
+ | n:0.4.25 | ||
+ | |||
+ | === [[2.0.0]] === | ||
+ | |||
+ | "shareddata:/buildinfo/buildinfo.dat" content: | ||
+ | r:13341 | ||
+ | p:NX64 | ||
+ | v:Release | ||
+ | d:2017-02-13 22:57 | ||
+ | n:0.5.9 | ||
+ | |||
+ | |||
+ | === [[2.1.0]] === | ||
+ | See [[Switch_Userland_Flaws|here]] for vuln-related changes. | ||
+ | |||
+ | The WebKit NRO was updated. For the WebKit NRO, the page-aligned size for the R-X, R--, and RW- pages are the same as v2.0. | ||
+ | * The actual code in the NRO starts differing starting at offset 0xE780. In v2.0 the offset following the last code instruction is text_lastpage+0x3F8(text_end-0xC08), while for v2.1 it's text_lastpage+0xE60(text_end-0x1A0). Compared to the previous version, there's a val0 u32(padding) inserted where the code for the import stubs begin, near the end of .text. Relative to that end offset going backwards, .text differs starting at v2.0 textbase+0xD56530 / v2.1 textbase+0xD56F94. | ||
+ | * The R-- section was updated. Besides the large table(?) which was updated(nothing was added/removed there), the strings containing "D:/for_cruiser/release_182/nx/webkit/" were updated: "182" was changed to "189". 0x10-bytes at offset 0x57292C were removed. 0x8-bytes were inserted at offset 0x14B2B5C in the v2.1 section. 0x8-bytes were inserted at offset 0x14B5C10 in the v2.1 section. ... | ||
+ | * The RW- section was updated, mainly for different addrs. Nothing was added/removed. Most(?)/all(?) main-codebin func import-addrs relative to main-codebin-base are the same as v2.0. | ||
+ | |||
+ | Main-codebin region(titleID 010000000000100B): | ||
+ | * rtld is same as before basically, minus addrs. Likewise for the "nnSdkEmpty" binary following the main-codebin. | ||
+ | * Various byte values were changed in the main .text. | ||
+ | * In the main R-- section: | ||
+ | ** The length of a string used with the user-agent changed, due to being changed from "{...}.9" to "{...}.10". | ||
+ | ** The version in the following string was changed from "1.2.2" to "1.2.3": "FS_ACCESS: { sdk_versio n: 1.2.3, spec: NX }" | ||
+ | ** The datetime strings following "b/23876444" was changed from "Feb 10 2017" "02:24:47" to "Mar 9 201 7" "21:41:27". | ||
+ | ** A 0x10-byte block prior to SDK library tag strings was updated. The version in those strings was changed from "1_2_2" to "1_2_3". | ||
+ | * The main RW- section appears to be basically the same minus addrs. | ||
+ | |||
+ | All of the other NROs were updated in FS with only the following changes: | ||
+ | * The R-X section is identical to the previous version except for the 0x10-byte block in the NRO header. | ||
+ | * The R-- section only had version values in "/release_{ver}/" strings updated, see the for_cruiser path mentioned for WebKit NRO above. The only other change was that a 0x10-byte block following a "GNU" string was updated. | ||
+ | |||
+ | ==== FS ==== | ||
+ | The content of "blacklist:/" and "oceanShared:/" haven't changed. Only the content of "shareddata:/" and "data:/" changed. | ||
+ | |||
+ | ===== "shareddata:/" ===== | ||
+ | The following files were updated here(nothing added/removed): | ||
+ | |||
+ | * /buildinfo/buildinfo.dat | ||
+ | * /dll/cairo_wkc.nro | ||
+ | * /dll/libfont.nro | ||
+ | * /dll/oss_wkc.nro | ||
+ | * /dll/peer_wkc.nro | ||
+ | * /dll/webkit_wkc.nro | ||
+ | |||
+ | That is, every .nro under the above directory was updated. | ||
+ | |||
+ | "shareddata:/buildinfo/buildinfo.dat" content: | ||
+ | r:13343 | ||
+ | p::NX64 | ||
+ | v:Release | ||
+ | d:2017-03-14 21:08 | ||
+ | n:0.5.10 | ||
+ | |||
+ | ===== "data:/" ===== | ||
+ | The following files were updated here(nothing added/removed): | ||
+ | |||
+ | * /.nrr/netfront.nrr | ||
+ | * /buildinfo/buildinfo.dat | ||
+ | |||
+ | === [[3.0.1]] === | ||
+ | While main-codebin .text was updated, no actual code was changed. | ||
+ | |||
+ | The .nss path string in main-codebin was changed from "Q:\work\LibraryApplet\..." to "Q:\work\nup\LibraryApplet\...". | ||
+ | |||
+ | See [[3.0.1|here]] regarding "shareddata:/" buildinfo. | ||
+ | |||
+ | === [[5.0.0]] === | ||
+ | Support for YouTubeVideo was added, and new [[#TLVs]] etc. | ||
+ | |||
+ | In RomFS "/whitelist/WhitelistYouTubePlayer.txt" was added for the YouTubeVideo whitelist, which contains the following: <nowiki>"^https://www\.youtube\.com/embed/"</nowiki>. This file has the same content on 7.0.x. | ||
+ | |||
+ | [[Category:Library Applets]] |
Latest revision as of 19:37, 11 June 2024
Nintendo Switch does not have a normal Internet Browser for user usage. However, there is multiple browser applets. It is the NetFront NX browser, which is based on Webkit.
When linking the Nintendo Account with Facebook, the Facebook Auth website will open, offering a search box that can be used to browse the Internet ("LoginApplet"). Alternatively, it can be accessed with custom DNS settings which simulate a Wi-Fi login page (WifiWebAuthApplet for captive-portal).
Known User Agent Strings
System Version | UA String |
---|---|
1.0.0 | Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.4.25 NintendoBrowser/5.1.0.11682 |
2.0.0 | Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.5.9 NintendoBrowser/5.1.0.13341 |
2.1.0-2.3.0 | Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.5.10 NintendoBrowser/5.1.0.13343 |
3.0.0 | Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.6.9 NintendoBrowser/5.1.0.14936 |
4.0.0 | Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.7.9 NintendoBrowser/5.1.0.15785 |
5.0.0 | Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.8.9 NintendoBrowser/5.1.0.16739 |
5.1.0 | Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.9.3 NintendoBrowser/5.1.0.16958 |
6.0.0 | Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.10.13 NintendoBrowser/5.1.0.17805 |
6.1.0 | Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.10.14 NintendoBrowser/5.1.0.17806 |
10.0.0 | Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/606.4 (KHTML, like Gecko) NF/6.0.1.15.4 NintendoBrowser/5.1.0.20389 |
The UA is generated with: "Mozilla/5.0 (Nintendo Switch; <appletname>) AppleWebKit/<webkitver> (KHTML, like Gecko) NF/<nfver0>.<nfver1>.<nfver2> NintendoBrowser/5.<ninver0>.<ninver1>.<ninver2>"
Browser Applets
appletname (From UA) | Usage | Invalid TLS cert handling | Uses whitelist | Title ID | Notes |
---|---|---|---|---|---|
WebApplet | General web-applet for use by applications(online manuals, ...). | Displays an error dialog without an option to ignore it. | Yes | 010000000000100A | |
ShopN | Actual eShop client | Just displays an error-code. | Yes | 010000000000100B | |
WebApplet | Offline HTML display | 010000000000100F | |||
LoginApplet | Nintendo Account linking, and for linking Facebook and Twitter to suggest friends | Just displays an error-code. | Yes | 0100000000001010 | |
ShareApplet | Posting screenshots to social media, and (optionally) linking social media accounts | Just displays an error-code. | Yes | 0100000000001010 | |
LobbyApplet | "Nintendo Switch Online Lounge" | Just displays an error-code. | Yes | 0100000000001010 | |
NsoApplet | Nintendo Switch Online menu | 0100000000001010 | |||
WifiWebAuthApplet | Captive-portal | Displays an error dialog with an option to ignore it. | No | 0100000000001011 |
When whitelisting is enabled, you can only load page domains included in the whitelist, otherwise an error is displayed. This only applies to page navigation. Videos via the <video> tag are not affected, likewise with network requests with JS.
No known applets can directly access the SD card via mounting it. This includes ShareApplet (which posts screenshots from SD to social media).
OSS
The NROs for the OSS are stored under a separate title. All of the web-applets use the same OSS NROs via this title.
String from v2.0 in oss_wkc.nro: "libcurl/7.50.1".
Video Playback
WifiWebAuthApplet does not fully support playing videos. It will assert with normal videos. The assert triggers before it even starts MP4 parsing?(For example, selecting a video from a video-tag will assert even though it doesn't send any network request for it) However, in some cases with certain MP4s using vulns it will display an error dialog instead.
With v3.0 WifiWebAuthApplet video-playback was disabled, it now throws the following error when attempting to play a video: "Support Code: 2809-1212" "This feature is not available." On past system-versions it would just trigger a fatal-error(see above). Video playback still works on the whitelisted applets following v3.0.0, which allows video playback through Facebook and embedded into Google Sites.
Trusted RootCAs
While the rootCA(s) for Let's Encrypt isn't included, Let's Encrypt is indirectly trusted via "Digital Signature Trust Co.". This seems to be only(?) the case for WifiWebAuthApplet, hence non-WifiWebAuthApplet seems to have a different set of trusted rootCAs.
WifiWebAuthApplet
When doing a connection-test in system-settings, it will detect that the captive-portal is required and display an error for it when the response for "http://conntest.nintendowifi.net/" doesn't include the "X-Organization: Nintendo" HTTP header. The web-applet will not load until something else attempts a conntest, for example when launching eShop and prior to LoginApplet launching. The initial page loaded by this applet is the above conntest URL.
This is only available starting with 2.0.0.
Prior to version 3.0.0, this applet was launched when attempting a system update from recovery mode if needed. This was changed to display a "This feature is not available." popup instead.
The conntest URL from #WebWifiPageArg is used to poll whether the connection is usable, with the SDK libcurl.
Whitelisted Applets
The v2.1 main-codebin page-aligned .text size is 0x1000-bytes larger than ShopN.
The file at "data:/whitelist/WhitelistLns.txt" for LoginApplet/ShareApplet/LobbyApplet, which doesn't exist in WifiWebAuthApplet, contains the following:
^https://([0-9A-Za-z\-]+\.)*nintendo\.net(/|$) ^https?://([0-9A-Za-z\-]+\.)*nintendo\.(co\.jp|com|eu|co\.uk|es|pt|ch|at|de|nl|be|ch|ru|fr|it|co\.za|co\.kr|tw|com\.hk|com\.au|ca|co\.nz)(/|$) ^https?://([0-9A-Za-z\-]+\.)*nintendo-europe\.com(/|$) ^https?://([0-9A-Za-z\-]+\.)*nintendoservicecentre\.co\.uk(/|$) ^https?://([0-9A-Za-z\-]+\.)*google\.(com|ad|ae|com\.af|com\.ag|com\.ai|al|am|co\.ao|com\.ar|as|at|com\.au|az|ba|com\.bd|be|bf|bg|com\.bh|bi|bj|com\.bn|com\.bo|com\.br|bs|bt|co\.bw|by|com\.bz|ca|cd|cf|cg|ch|ci|co\.ck|cl|cm|cn|com\.co|co\.cr|com\.cu|cv|com\.cy|cz|de|dj|dk|dm|com\.do|dz|com\.ec|ee|com\.eg|es|com\.et|fi|com\.fj|fm|fr|ga|ge|gg|com\.gh|com\.gi|gl|gm|gp|gr|com\.gt|gy|com\.hk|hn|hr|ht|hu|co\.id|ie|co\.il|im|co\.in|iq|is|it|je|com\.jm|jo|co\.jp|co\.ke|com\.kh|ki|kg|co\.kr|com\.kw|kz|la|com\.lb|li|lk|co\.ls|lt|lu|lv|com\.ly|co\.ma|md|me|mg|mk|ml|com\.mm|mn|ms|com\.mt|mu|mv|mw|com\.mx|com\.my|co\.mz|com\.na|com\.nf|com\.ng|com\.ni|ne|nl|no|com\.np|nr|nu|co\.nz|com\.om|com\.pa|com\.pe|com\.pg|com\.ph|com\.pk|pl|pn|com\.pr|ps|pt|com\.py|com\.qa|ro|ru|rw|com\.sa|com\.sb|sc|se|com\.sg|sh|si|sk|com\.sl|sn|so|sm|sr|st|com\.sv|td|tg|co\.th|com\.tj|tk|tl|tm|tn|to|com\.tr|tt|com\.tw|co\.tz|com\.ua|co\.ug|co\.uk|com\.uy|co\.uz|com\.vc|co\.ve|vg|co\.vi|com\.vn|vu|ws|rs|co\.za|co\.zm|co\.zw|cat)(/|$) ^https://([0-9A-Za-z\-]+\.)*facebook\.com(/|$) ^https://([0-9A-Za-z\-]+\.)*twitter\.com(/|$)
[3.0.0+]: The "google\.(com" line now starts with "^https://" instead of "https?://", hence plain HTTP is no longer allowed. The following line was added right after the original google line: "---- ^https?://([0-9A-Za-z\-]+\.)*google(\.[A-Za-z]+)*/(search|translate)\?"
[4.0.0+]: Lines 2-4 ("...nintendo\.(co...", "nintendo-europe", and "nintendoservicecentre") now starts with "^https://" instead of "https?://". Hence, plain HTTP for these are no longer allowed.
The initial page loaded by this applet is controlled by the #ShareStartPage TLV.
The "web-lp1.share.srv.nintendo.net" site will return a HTTP 302 redirect to "https://nintendo.com/" when the specified User-Agent isn't the one for ShareApplet.
LobbyApplet
Support for Lobby was added with [2.0.0+]. This applet is for "Nintendo Switch Online Lounge"
The initial page loaded by this applet is: "https://web-lp1.znc.srv.nintendo.net/lobby/".
The content of the above URL refers to "rooms", "NxView_Img_Google_Play_Icon", etc.
And also:
Your room has been created. You can invite friends to the room via the Nintendo Switch Online Lounge app.
NsoApplet
[11.0.0+] This applet handles the new Nintendo Switch Online menu, which is launched from qlaunch.
The initial page loaded by this applet is: "https://%.nso.nintendo.net/{string from TLV 0x2}"
ShopN
The initial page loaded by ShopN is: "https://bugyo.hac.lp1.eshop.nintendo.net/ashigaru/". This can be accessed via computer possesed the certificate ShopN.
The file at "data:/whitelist/WhitelistEc.txt", which doesn't exist in WifiWebAuthApplet, contains the following:
^https://([0-9A-Za-z\-]+\.)*eshop\.nintendo\.net($|/) ^https?://([0-9A-Za-z\-]+\.)*nintendo\.(co\.jp|com|de)($|/)
WebApplet
010000000000100A
The initial page loaded by this applet is specified by the title which launched this applet. Plain HTTP is allowed.
The files under "data:/" are identical to WifiWebAuthApplet except that the content of each file differs.
This applet uses a whitelist, but it doesn't come from "data:/" like whitelisted-applet.
WebApplet launch with Tetris
The Tetris game/demo can be used to launch the online-WebApplet. This only applies to the JPN region of the game/demo: "ぷよぷよ™テトリス®S"(aka "Puyo Puyo Tetris"). Note that the gamecard for this can be used to launch the online-WebApplet on system-version >=1.0.0.
First, launch the offline-WebApplet for the manual:
- Game: Main-menu -> press A with the already selected top menu button -> press the R button.
- Demo: Main-menu -> select menu button on the right side -> press A.
Then in the manual:
- Press A -> select the bottom menu entry in the list.
- Select the SEGA icon -> press A.
The offline-WebApplet will then launch the online-WebApplet with the plain-http "http://sega.jp/" URL. Non-JPN regions of Tetris don't have any external link in the manual. For example, with your own DNS-server setup to return your own server address for this domain, you can load your own content for use with online-WebApplet.
As of 12/01/2017 this still works on the latest update for Tetris (version 1.1.2).
Offline Applet
Minus TIDs, the NPDM is the same as 010000000000100A except 010000000000100A has access to more/other services.
Service/FS Access
All browser applets have access to the following services: acc:u1, appletAE, audin:u, audren:u, audout:u, bsd:u, fatal:u, fsp-srv, hid, hid:sys, irs, ldn:m, ldr:ro, lm, erpt:c, nifm:s, ns:am, nsd:u, nvdrv:a, mm:u, pl:u, prepo:s, set, set:sys, sfdnsres, ssl, time:u, vi:s
LoginApplet/ShareApplet/LobbyApplet have access to the above + caps:a.
ShopN has access to the above + nim:shp.
Unlike the applets listed above, WebApplet TID 010000000000100A has access to the FS MountContent* commands. This is so that it can load the whitelist from "/accessible-urls/accessible-urls.txt" in the mounted FS, from NCA-type4 where titleID={application which launched this applet}.
Heap
The size used for svcSetHeapSize by the web-applets is 0x15600000. Under ShopN, the largest size that can be passed to this without an error being returned, is 0x1B400000.
The size used by title 010000000000100A (on 10.0.0 at least) is 0x14200000.
The heap for the main-codebin (malloc
/operator new
) uses nn::lmem::*ExpHeap. [8.0.0+] malloc
/operator new
now checks the return-addr (addr located in a relevant NRO), with wkc_malloc_crashonfailure being called for the allocation if the check passes, otherwise a normal allocation is done (the code which runs for this will Abort if allocation fails).
malloc
passes the input size directly to the called func. operator new
when handling normal non-wkc allocations passes the following to the called func: sxtw x1, {inw0}
(for wkc allocations the size is passed directly). [12.1.0+] The size is now passed directly (64bit) without using sxtw.
[11.0.0+] There's now optional code for using svcMapPhysicalMemoryUnsafe etc, however it's unknown what sets the flag for this. An Abort string used this is: "{path}/TransferredMemoryManager.cpp"
Applet Launching
The web-applets are launched using a storage containing the input arg data, on exit the output storage contains the "*ReturnValue" reply data.
Input/output storage size for TLV data is 0x2000-bytes.
Library Applet Versions
System Version | Value |
---|---|
[1.0.0+] | 0x20000 |
[3.0.0+] | 0x30000 |
[5.0.0+] | 0x50000 |
[6.0.0+] | 0x60000 |
[8.0.0+] | 0x80000 |
The above only (?) applies to non-WebWifi. WebWifi uses version 0x0.
ShimKind
This enum is "nn::web::common::ShimKind".
This indicates the type of web-applet.
Value | Name |
---|---|
1 | Shop |
2 | Login |
3 | Offline |
4 | Share |
5 | Web |
6 | Wifi |
7 | Lobby |
8 | Lhub |
WebSession
With [5.0.0+] sdk-nso added nn::web::Session::
. With [6.0.0+] this was removed, however it was reintroduced with [7.0.0+] as nn::web::*WebSession
(for ShimKind Offline and Web).
This is for sending/receiving #SessionMessages via applet Interactive storage.
During state init, max_messages is set to 0xA ([7.0.0+] 0x10), with message_count=0 and cur_size=0. [5.0.0-5.1.0] max_size is set to 0x5000. [7.0.0+] Two queues are used for message_count/cur_size: first one is for BrowserEngineContent (max_size 0x8000 is used), the second one is for non-BrowserEngineContent (max_size 0x1000 is used).
When sending messages, there has to be an available message slot available (max_messages!=message_count
), and there has to be enough space available (msghdr_contentsize+0x10 + cur_size <= max_size
). After pushing the storage, message_count is incremented and cur_size is increased by msghdr_contentsize+0x10
.
When receiving messages, it will repeatedly pop Interactive output storage until no more are available. Non-Ack messages are Acked.
- Ack: Verifies that message_count is not already 0, then decrements it. Then cur_size is decreased by the u32 loaded from msgcontent+0.
- 0x0: Does some validation. Reads the message content into the user buffer, when contentsize is non-zero. The original contentsize is written to an user output param. The last byte in the user buffer (contentsize clamped to the user max-buf-size, -1) is set to 0 for NUL-termination.
Next info was tested in 9.0.0
In the js side (which is only available when enabled via the JsExtensionEnabled TLV), there is a method called window.nx.sendMessage(arg)
that sends data to the native side, this method returns a boolean indicating if sending was successful and accepts a string as an argument. The string is encoded like a C null terminated string in the message content. For receive messages from native part, there is a dom event called message
which is dispatched when a message arrives. The event can be listened using window.nx.addEventListener("message", callback)
being callback a function which first parameter is like a dom event arg and contains a member called data
which contains the string decoded from the arrived message.
If messages aren't acked by the native part, js side will not longer receive messages. Ack to web applet must have 4 bytes after the message content or the applet will Abort.
SessionMessage
Offset | Size | Description |
---|---|---|
0x0 | 0x10 | #SessionMessageHeader |
0x10 | Size from header | Message content |
After message content | 0x4 if message is ack, 0x0 otherwise | Padding |
SessionMessageHeader
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | Message Kind (#WebSessionSendMessageKind / #WebSessionReceiveMessageKind) |
0x4 | 0x4 | Data size following the header. |
0x8 | 0x8 | Unused |
WebSessionSendMessageKind
This is "nn::web::detail::WebSessionSendMessageKind".
ID | Content size | Description |
---|---|---|
0x0 | Arbitrary | BrowserEngine Content, NUL-terminated string. Used to communicate with the applet via JsExtensions used by the Js being run by the applet on the current page. |
0x100 | 0x0 | SystemMessage Appear. Requests the applet to Appear, this is only needed with #WebSessionBootMode AllForegroundInitiallyHidden. |
0x1000 | 0xC | Ack. Content: first u32 is the entire storage size of the message being acked, the rest is not used. |
WebSessionReceiveMessageKind
This is "nn::web::detail::WebSessionReceiveMessageKind".
ID | Content size | Description |
---|---|---|
0x0 | Arbitrary | BrowserEngine Content, see #WebSessionSendMessageKind. |
0x1000 | 0xC | Ack BrowserEngine |
0x1001 | 0xC | Ack SystemMessage |
WebWifiPageArg
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | Official sw sets this to 0 with appletStorageWrite, separately from the rest of the config struct. |
0x4 | 0x100 | URL used for the connection-test requests. |
0x104 | 0x400 | Initial URL navigated to by the applet. |
0x504 | 0x10 | NIFM Network UUID. Can be value zero. Only used by the applet when conntest_url is set. |
0x514 | 0x4 | Input value for nifm cmd SetRequirementByRevision. Can be value zero. Only used by the applet when conntest_url is set. |
This is the input struct for WifiWebAuthApplet. This is a total of 0x518-bytes.
When the conntest_url is empty, the applet will test the connection with nifm and throw an error on failure.
WebWifiReturnValue
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | ? |
0x4 | 0x8 | Result |
This is the output struct for WifiWebAuthApplet. This is a total of 0x8-bytes.
WebCommonReturnValue
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | u32 exitReason |
0x4 | 0x4 | Padding |
0x8 | 0x1000 | lastUrl string |
0x1008 | 0x8 | lastUrlSize |
This is the 0x1010-byte output storage used by all non-WebWifi applets - except for Share which returns a TLV storage on [3.0.0+], and Web on [8.0.0+].
WebArgHeader
Offset | Size | Description |
---|---|---|
0x0 | 0x2 | Total #WebArgTLV entries following this struct. |
0x2 | 0x2 | Padding |
0x4 | 0x4 | #ShimKind |
This is the header struct at offset 0 in the input web Arg storage for non-WebWifi. This is a total of 0x8-bytes. The total storage size used for input/output TLVs is 0x2000.
WebArgTLV
Offset | Size | Description |
---|---|---|
0x0 | 0x2 | Type of this arg. |
0x2 | 0x2 | Size of the arg data following this struct. |
0x4 | 0x4 | Padding |
Web TLV used in the input web Arg storage, after #WebArgHeader. This is a total of 0x8-bytes.
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | #FooterButtonId |
0x4 | 0x1 | u8 bool visible flag |
0x5 | 0x2 | ? |
0x7 | 0x1 | ? |
TLVs
All strings are NUL-terminated.
Input TLVs
System Version | Applets | Type | Size | Value | Description |
---|---|---|---|---|---|
[1.0.0+] | 0x1 | 0xC00 | string | Initial URL | |
[1.0.0+] | 0x3 | 0x400 | string | CallbackUrl | |
[1.0.0+] | 0x4 | 0x400 | string | CallbackableUrl | |
[1.0.0+] | Offline | 0x5 | 0x8 | u64 titleID | ApplicationId, for DocumentKind_OfflineHtmlPage/DocumentKind_ApplicationLegalInformation. Should be zero for DocumentKind_OfflineHtmlPage since it's ignored. |
[1.0.0+] | Offline | 0x6 | 0xC00 | string | DocumentPath |
[1.0.0+] | Offline | 0x7 | 0x4 | u32 enum OfflineDocumentKind | #DocumentKind |
[1.0.0+] | Offline | 0x8 | 0x8 | u64 titleID | SystemDataId, for DocumentKind_SystemDataPage. |
Share | 0x9 | 0x4 | u32 enum #ShareStartPage | ShareStartPage | |
[1.0.0+] | 0xA | 0x1000 | string | Whitelist. If not formatted properly, the applet will exit briefly after the applet is launched. Each line is a regex for each whitelisted URL. | |
[1.0.0+] | 0xB | 0x1 | u8 bool | News flag. When set the domain from the input URL is automatically whitelisted, in addition to any already loaded whitelist. | |
[1.0.0+] | 0xE | 0x10 | userID | userID, controls which user-specific savedata to mount. | |
Share | 0xF | 0x20 | AlbumEntry | AlbumEntry0 | |
[1.0.0+] | 0x10 | 0x1 | u8 bool | ScreenShotEnabled. Controls whether screen-shot capture is allowed. | |
[1.0.0+] | 0x11 | 0x1 | u8 bool | EcClientCertEnabled | |
[1.0.0+] | 0x12 | 0x1 | u8 | ? | |
[1.0.0+] | Offline | 0x13 | 0x1 | u8 bool | PlayReportEnabled |
[1.0.0+] | 0x14 | 0x1 | u8 | ? | |
[1.0.0+] | 0x15 | 0x1 | u8 | ? | |
[1.0.0+] | 0x17 | 0x4 | u32 enum #BootDisplayKind | BootDisplayKind | |
[1.0.0+] | 0x18 | 0x4 | u32 enum #BackgroundKind | BackgroundKind | |
[1.0.0+] | 0x19 | 0x1 | u8 bool | FooterEnabled. Controls whether the UI footer is enabled. | |
[1.0.0+] | 0x1A | 0x1 | u8 bool | PointerEnabled | |
[1.0.0+] | 0x1B | 0x4 | u32 enum #LeftStickMode | LeftStickMode | |
[1.0.0+] | 0x1C | 0x4 | s32 | KeyRepeatFrame, first param | |
[1.0.0+] | 0x1D | 0x4 | s32 | KeyRepeatFrame, second param | |
[1.0.0+] | 0x1E | 0x1 | u8 bool | Set after BootAsMediaPlayer with the value inverted. | |
[1.0.0+] | 0x1F | 0x1 | u8 bool | DisplayUrlKind (value = (input_enumval==0x1) )
| |
[2.0.0+] | 0x21 | 0x1 | u8 bool | BootAsMediaPlayer | |
[2.0.0+] | 0x22 | 0x1 | u8 bool | ShopJumpEnabled | |
[2.0.0+] | 0x23 | 0x1 | u8 bool | [6.0.0+] MediaAutoPlayEnabled ([2.0.0-5.1.0] MediaPlayerUserGestureRestrictionEnabled) | |
[2.0.0+] | 0x24 | 0x100 | string | LobbyParameter | |
[3.0.0+] | Share | 0x26 | 0x20 | ApplicationAlbumEntry | ApplicationAlbumEntry |
[3.0.0+] | 0x27 | 0x1 | u8 bool | JsExtensionEnabled | |
[4.0.0+] | Share | 0x28 | 0x100 | string | AdditionalCommentText |
[4.0.0+] | 0x29 | 0x1 | u8 bool | TouchEnabledOnContents | |
[4.0.0+] | 0x2A | 0x80 | string | UserAgentAdditionalString. " " followed by this string are appended to the normal User-Agent string. | |
[4.0.0+] | Share | 0x2B | 0x10 | u8 array | AdditionalMediaData0 (If the user-input size is less than 0x10, the remaining tmp data used for the TLV is cleared) |
[4.0.0+] | 0x2C | 0x1 | u8 bool | MediaPlayerAutoCloseEnabled | |
[4.0.0+] | 0x2D | 0x1 | u8 bool | PageCacheEnabled | |
[4.0.0+] | 0x2E | 0x1 | u8 bool | WebAudioEnabled | |
[5.0.0+] | 0x2F | 0x1 | u8 | ? | |
[5.0.0+] | 0x31 | 0x1 | u8 bool | When set, indicates the whitelist for YouTubeVideo should be used (loaded from web-applet RomFS). | |
[5.0.0+] | 0x32 | 0x4 | u32 enum *WebFooterFixedKind | FooterFixedKind | |
[5.0.0+] | 0x33 | 0x1 | u8 bool | PageFadeEnabled | |
[5.0.0+] | Share | 0x34 | 0x20 | s8 data[32] | MediaCreatorApplicationRatingAge |
[5.0.0+] | 0x35 | 0x1 | u8 bool | BootLoadingIconEnabled | |
[5.0.0+] | 0x36 | 0x1 | u8 bool | PageScrollIndicatorEnabled | |
[6.0.0+] | 0x37 | 0x1 | u8 bool | MediaPlayerSpeedControlEnabled | |
[6.0.0+] | Share | 0x38 | 0x20 | AlbumEntry | AlbumEntry1 |
[6.0.0+] | Share | 0x39 | 0x20 | AlbumEntry | AlbumEntry2 |
[6.0.0+] | Share | 0x3A | 0x20 | AlbumEntry | AlbumEntry3 |
[6.0.0+] | Share | 0x3B | 0x10 | u8 array | AdditionalMediaData1 |
[6.0.0+] | Share | 0x3C | 0x10 | u8 array | AdditionalMediaData2 |
[6.0.0+] | Share | 0x3D | 0x10 | u8 array | AdditionalMediaData3 |
[6.0.0+] | BootFooterButton | 0x3E | 0x80 | Array of #WebBootFooterButtonEntry with 0x10 entries. | BootFooterButton |
[6.0.0+] | 0x3F | 0x4 | float | OverrideWebAudioVolume | |
[6.0.0+] | 0x40 | 0x4 | float | OverrideMediaAudioVolume | |
[7.0.0+] | 0x41 | 0x4 | u32 enum #WebSessionBootMode | BootMode | |
[7.0.0+] | 0x42 | 0x1 | u8 bool | Enables using #WebSession when set. | |
[8.0.0+] | Offline | 0x43 | 0x1 | u8 bool | MediaPlayerUiEnabled |
[11.0.0+] | 0x44 | 0x1 | bool | TransferMemoryEnabled |
Offline: title to load the content from is controlled by ApplicationId/SystemDataId. With DocumentKind_OfflineHtmlPage, it will ignore this and only load from the user-process title.
Offline DocumentPath: Initial document path in RomFS, without the leading '/'. For DocumentKind_OfflineHtmlPage, this is relative to "html-document/" in RomFS. For the other DocumentKind values, this is relative to "/" in RomFS. This path must contain ".htdocs/".
Share/Lobby: if a non-zero userID isn't set, the applet will launch the profile-selector applet to select an account.
Share: An error will be displayed if neither AlbumEntry or ApplicationAlbumEntry are set, with ShareStartPage_Default.
[6.0.0+] AddAlbumEntryAndMediaData
was added:
- Looks for AlbumEntry{N} TLVs, when a TLV is not found it is written, then the associated AdditionalMediaData{N} TLV is written the same way as AdditionalMediaData0. If all AlbumEntry{N} TLVs already exist, this returns without writing anything.
TransferMemoryEnabled: sdknso only exposes this for the Web applet. The sdknso func uses nn::os::QueryMemoryInfo
at the start of the func, however the output is unused. The applet doesn't seem to parse this TLV.
Output TLVs
System Version | Applets | Type | Size | Value | Description |
---|---|---|---|---|---|
[3.0.0+] | Share, Web | 0x1 | 0x4 | u32 | ShareExitReason |
[3.0.0+] | Share, Web | 0x2 | string | LastUrl | |
[3.0.0+] | Share, Web | 0x3 | 0x8 | u64 | LastUrlSize |
[3.0.0+] | Share | 0x4 | 0x4 | u32 | SharePostResult |
[3.0.0+] | Share | 0x5 | string | PostServiceName | |
[3.0.0+] | Share | 0x6 | 0x8 | u64 | PostServiceNameSize |
[3.0.0+] | Share | 0x7 | string | PostId | |
[3.0.0+] | Share | 0x8 | 0x8 | u64 | PostIdSize |
[8.0.0+] | Web | 0x9 | 0x1 | u8 bool | MediaPlayerAutoClosedByCompletion |
These are used for Share-applet on [3.0.0+], and with Web on [8.0.0+]. Official user-processes doesn't check the TLV size for any of these.
DocumentKind
Value | Name | Description |
---|---|---|
0x1 | DocumentKind_OfflineHtmlPage | Use the HtmlDocument NCA content from the application. |
0x2 | DocumentKind_ApplicationLegalInformation | Use the LegalInformation NCA content from the application. |
0x3 | DocumentKind_SystemDataPage | Use the Data NCA content from the specified title, see also: Title_list#System_Data_Archives |
This controls the kind of content to mount with Offline-applet.
Value | Name | URL |
---|---|---|
0 | ShareStartPage_Default | "https://web-%.share.srv.nintendo.net/" |
1 | ShareStartPage_Settings | "https://web-%.share.srv.nintendo.net/settings/" |
This enum controls the initial page for ShareApplet.
BootDisplayKind
Value | Name | Description |
---|---|---|
0 | BootDisplayKind_White | Default white background. |
1 | Unknown. Used by Offline default Arg initialization for DocumentKind_ApplicationLegalInformation/DocumentKind_SystemDataPage. | |
2 | BootDisplayKind_Black | Black background. |
3 | Unknown. Used by Share default Arg initialization. | |
4 | Unknown. Used by Lobby default default Arg initialization. |
Kind values for BootDisplayKind. Controls the background color while displaying the loading screen during applet boot. Also controls the BackgroundKind when value is non-zero.
The applet converts this to internal values.
- BootDisplayKind 0:
- If launched by an Application:
- If #BackgroundKind is 2..1, return 3..2. When 0, run the below, otherwise assert.
- return TLV value from BootAsMediaPlayer
- If launched by an Application:
- BootDisplayKind 1..4: return 0..3.
BackgroundKind
Value | Name | Description |
---|---|---|
0 | Unknown. Used by Offline default Arg initialization for DocumentKind_ApplicationLegalInformation/DocumentKind_SystemDataPage. | |
1 | Same as #BootDisplayKind value 3. | |
2 | Same as #BootDisplayKind value 4. Used by Lobby default Arg initialization. |
Kind values for BackgroundKind. Only used when #BootDisplayKind is 0.
LeftStickMode
Value | Name | Description |
---|---|---|
0 | LeftStickMode_Pointer | The user can directly control the pointer via the left-stick. |
1 | LeftStickMode_Cursor | The user can only select elements on the page via the left-stick. |
Controls the initial mode, this can be toggled by the user via the pressing the left-stick button. If the Pointer flag is set to false, only LeftStickMode_Cursor will be used and mode toggle by the user is disabled (input value ignored).
Value | Name | Description |
---|---|---|
0 | None | None, for empty #WebBootFooterButtonEntry. Invalid for use as an input Id. |
1 | ||
2 | ||
3 | ||
4 | ||
5 | ||
6 | ||
7 | Values starting with this are invalid. |
WebSessionBootMode
This is "nn::web::WebSessionBootMode".
Value | Name | Description |
---|---|---|
0 | Normal/default (AllForeground) | |
1 | AllForegroundInitiallyHidden |
This controls which LibraryAppletMode the applet will be launched with, by the user-process. The TLV for this seems to be ignored by the applet.
LastUrl
When the applet loads a page where the beginning of the URL matches the URL from CallbackUrl, the applet will exit and set LastUrl to that URL (exit doesn't occur when CallbackableUrl is set). With Offline-applet for CallbackUrl handling, it compares the domain with "localhost" instead of using the CallbackUrl TLV.
Versions
1.0.0
"shareddata:/buildinfo/buildinfo.dat" content:
r:11682 p:NX64 v:Pilot d:2016-11-25 23:30 n:0.4.25
2.0.0
"shareddata:/buildinfo/buildinfo.dat" content:
r:13341 p:NX64 v:Release d:2017-02-13 22:57 n:0.5.9
2.1.0
See here for vuln-related changes.
The WebKit NRO was updated. For the WebKit NRO, the page-aligned size for the R-X, R--, and RW- pages are the same as v2.0.
- The actual code in the NRO starts differing starting at offset 0xE780. In v2.0 the offset following the last code instruction is text_lastpage+0x3F8(text_end-0xC08), while for v2.1 it's text_lastpage+0xE60(text_end-0x1A0). Compared to the previous version, there's a val0 u32(padding) inserted where the code for the import stubs begin, near the end of .text. Relative to that end offset going backwards, .text differs starting at v2.0 textbase+0xD56530 / v2.1 textbase+0xD56F94.
- The R-- section was updated. Besides the large table(?) which was updated(nothing was added/removed there), the strings containing "D:/for_cruiser/release_182/nx/webkit/" were updated: "182" was changed to "189". 0x10-bytes at offset 0x57292C were removed. 0x8-bytes were inserted at offset 0x14B2B5C in the v2.1 section. 0x8-bytes were inserted at offset 0x14B5C10 in the v2.1 section. ...
- The RW- section was updated, mainly for different addrs. Nothing was added/removed. Most(?)/all(?) main-codebin func import-addrs relative to main-codebin-base are the same as v2.0.
Main-codebin region(titleID 010000000000100B):
- rtld is same as before basically, minus addrs. Likewise for the "nnSdkEmpty" binary following the main-codebin.
- Various byte values were changed in the main .text.
- In the main R-- section:
- The length of a string used with the user-agent changed, due to being changed from "{...}.9" to "{...}.10".
- The version in the following string was changed from "1.2.2" to "1.2.3": "FS_ACCESS: { sdk_versio n: 1.2.3, spec: NX }"
- The datetime strings following "b/23876444" was changed from "Feb 10 2017" "02:24:47" to "Mar 9 201 7" "21:41:27".
- A 0x10-byte block prior to SDK library tag strings was updated. The version in those strings was changed from "1_2_2" to "1_2_3".
- The main RW- section appears to be basically the same minus addrs.
All of the other NROs were updated in FS with only the following changes:
- The R-X section is identical to the previous version except for the 0x10-byte block in the NRO header.
- The R-- section only had version values in "/release_{ver}/" strings updated, see the for_cruiser path mentioned for WebKit NRO above. The only other change was that a 0x10-byte block following a "GNU" string was updated.
FS
The content of "blacklist:/" and "oceanShared:/" haven't changed. Only the content of "shareddata:/" and "data:/" changed.
The following files were updated here(nothing added/removed):
- /buildinfo/buildinfo.dat
- /dll/cairo_wkc.nro
- /dll/libfont.nro
- /dll/oss_wkc.nro
- /dll/peer_wkc.nro
- /dll/webkit_wkc.nro
That is, every .nro under the above directory was updated.
"shareddata:/buildinfo/buildinfo.dat" content:
r:13343 p::NX64 v:Release d:2017-03-14 21:08 n:0.5.10
"data:/"
The following files were updated here(nothing added/removed):
- /.nrr/netfront.nrr
- /buildinfo/buildinfo.dat
3.0.1
While main-codebin .text was updated, no actual code was changed.
The .nss path string in main-codebin was changed from "Q:\work\LibraryApplet\..." to "Q:\work\nup\LibraryApplet\...".
See here regarding "shareddata:/" buildinfo.
5.0.0
Support for YouTubeVideo was added, and new #TLVs etc.
In RomFS "/whitelist/WhitelistYouTubePlayer.txt" was added for the YouTubeVideo whitelist, which contains the following: "^https://www\.youtube\.com/embed/". This file has the same content on 7.0.x.