# [3DS][SSL] Use of uninitialized class member leads to RCE in eShop movie player

eShop movie player leaves audio decoder pointer uninitialized for pcm16 codec; heap massaging via crafted JPEG screenshots yields arbitrary jump and RCE.

- Payout: hidden
- Severity: none
- Program: Nintendo
- Found by: mrnbayoh
- Disclosed: 2020-12-18
- Write-up quality: 8/10
- Original: https://hackerone.com/reports/895769
- Library page: https://bugbountylibrary.com/r/h1%3A895769
- Tags: area:os domain:desktop impact:rce kind:bounty platform:hackerone tech:payment technique:chained technique:source-review vuln:memory-corruption vuln:rce

**Target:** eShop movie player audio decoder initialization
**Root cause:** create_audio_decoder reads *out_decoder without initializing it for the pcm16 codec, then calls decoder->init() on the attacker-influenced value.
**Steps:**
1. Craft binary files served as title screenshots so freed JPEG heap chunks contain controlled values.
2. Trigger eShop title info page load so screenshots are freed just before player allocation.
3. Heap-massage so the Player object's uninitialized decoder field lands on controlled data.
4. Play a video using the pcm16 codec to reach create_audio_decoder with uninitialized *out_decoder.
5. decoder->init() performs an arbitrary virtual call to attacker-controlled address.
**How found:** Code review of create_audio_decoder revealed the pcm16 branch reads *out_decoder without assignment, unlike fastaudio/imadpcm which overwrite it; noted JPEG screenshots are freed just before player allocation, suggesting heap massaging.
**Exploitation:** Attacker controls screenshot content (via SSL flaw #894922) to place controlled bytes in freed JPEG heap chunks; when the movie player is allocated over them, the uninitialized decoder pointer is attacker-controlled, and decoder->init() gives an arbitrary jump leading to usermode RCE in eShop.
**Escalation:** Chained with SSL flaw #894922 to inject crafted screenshot files; alternatively hypothesized via eShop catalog submission.
**Insight:** When a codec/format branch skips allocation but still dereferences the out-pointer, check whether the caller zero-initializes it; and look for free-then-allocate ordering (freed screenshots before player alloc) as a heap-massaging primitive.

