<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>samienr - Console modding</title>
    <subtitle>Electrical Nerd + Digital Artist</subtitle>
    <link rel="self" type="application/atom+xml" href="https://samienr.com/tags/console-modding/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://samienr.com"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2025-08-06T00:00:00+00:00</updated>
    <id>https://samienr.com/tags/console-modding/atom.xml</id>
    <entry xml:lang="en">
        <title>How The Nintendo 3DS Was Hacked Using a Music File</title>
        <published>2025-08-06T00:00:00+00:00</published>
        <updated>2025-08-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Samien Rahman
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://samienr.com/blog/soundhax/"/>
        <id>https://samienr.com/blog/soundhax/</id>
        
        <content type="html" xml:base="https://samienr.com/blog/soundhax/">&lt;blockquote class=&quot;note&quot;&gt;
	&lt;p class=&quot;alert-title&quot;&gt;
		&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;Note&lt;&#x2F;p&gt;
	&lt;p&gt;SoundHax was patched as of firmware version 11.4 and does not work on any Nintendo 3DS system running firmware 11.4 or higher.&lt;&#x2F;p&gt;

&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;soundhax.com&quot;&gt;SoundHax&lt;&#x2F;a&gt; was one of the most accessible exploits to get unsigned code running on the Nintendo 3DS. It worked by abusing a bug found in the &lt;em&gt;Nintendo 3DS Sound&lt;&#x2F;em&gt; application with a specially-crafted &lt;code&gt;.m4a&lt;&#x2F;code&gt; file.&lt;&#x2F;p&gt;
&lt;p&gt;The exploit was special as it was the first exploit on the 3DS that was free, offline, and worked on every version of the firmware as of when it was discovered.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;important&quot;&gt;
	&lt;p class=&quot;alert-title&quot;&gt;
		&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;Important&lt;&#x2F;p&gt;
	&lt;p&gt;To fully appreciate this brilliant symphony of hacks, a basic understanding of memory management is recommended. &lt;a href=&quot;https:&#x2F;&#x2F;samwho.dev&#x2F;memory-allocation&#x2F;&quot;&gt;This article does a good job explaining the basics&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;

&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;small&gt;Before proceeding, I&#x27;d also highly suggest reading the writeup on &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nedwill&#x2F;soundhax?tab=readme-ov-file#writeup&quot;&gt;Nedwill&#x27;s GitHub page&lt;&#x2F;a&gt;&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h1 id=&quot;the-vulnerability&quot;&gt;The Vulnerability&lt;&#x2F;h1&gt;
&lt;p&gt;For context, the M4A format uses the MP4 file format. At its core, SoundHax exploits a bug in how the &lt;em&gt;Nintendo 3DS Sound&lt;&#x2F;em&gt; application handles MP4 atom tags.&lt;&#x2F;p&gt;
&lt;p&gt;That is, when loading in an M4A file, a 256-byte buffer is allocated on the heap for song names (the max size according to the MP4 spec).
The song name is then copied from the file into the buffer using one of two functions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;For ASCII strings, &lt;code&gt;strncpy(dst, src, 256)&lt;&#x2F;code&gt; is used, which is safe.&lt;&#x2F;li&gt;
&lt;li&gt;For Unicode strings, &lt;code&gt;memcpy()&lt;&#x2F;code&gt; is used, which &lt;strong&gt;takes a user-provided size&lt;&#x2F;strong&gt; instead of 256 &lt;small&gt;(not safe!)&lt;&#x2F;small&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Unicode strings likely didn&#x27;t use &lt;code&gt;strncpy()&lt;&#x2F;code&gt; because it stops at the first null terminating byte &lt;small&gt;(which is used for marking the end of an ASCII string)&lt;&#x2F;small&gt;. Unicode can have null bytes as parts of characters, which means that &lt;code&gt;strncpy()&lt;&#x2F;code&gt; wouldn&#x27;t work well.&lt;&#x2F;p&gt;
&lt;p&gt;Instead, song names are simply gathered by copying over as many bytes as the file specifies, &lt;strong&gt;even if the number is greater than 256.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This means that the program code is vulnerable to a &lt;colorize&gt;&lt;strong&gt;buffer overflow attack.&lt;&#x2F;strong&gt;&lt;&#x2F;colorize&gt;
By providing a carefully crafted Unicode title longer than 256 bytes, an attacker can write data &lt;strong&gt;beyond the allocated buffer and into other parts of console memory.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;the-exploit&quot;&gt;The Exploit&lt;&#x2F;h1&gt;
&lt;p&gt;Taking advantage of this bug, we can get arbitrary code execution on the 3DS using the following steps:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Creating an M4A file with an oversized Unicode title&lt;&#x2F;li&gt;
&lt;li&gt;Causing a Buffer Overflow in the Heap&lt;&#x2F;li&gt;
&lt;li&gt;Corrupting the Heap Metadata&lt;&#x2F;li&gt;
&lt;li&gt;Unlink Exploitation&lt;&#x2F;li&gt;
&lt;li&gt;Heap Feng Shui&lt;&#x2F;li&gt;
&lt;li&gt;Constructing and Executing a ROP Chain&lt;&#x2F;li&gt;
&lt;li&gt;Abusing the GPU (&#x27;gspwn&#x27;)&lt;&#x2F;li&gt;
&lt;li&gt;Unlimited Power!!!&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Anyways, here&#x27;s how it works.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;1-crafting-the-malicious-file&quot;&gt;1. Crafting the malicious File&lt;&#x2F;h2&gt;
&lt;p&gt;The exploit begins with the construction of a M4A file containing a specially crafted Unicode title that&#x27;s intentionally oversized. Nedwill used a Python script to do this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#212733;color:#ccc9c2;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;font-style:italic;color:#5c6773;&quot;&gt;# Start with some text for the song title: &amp;quot;3 nedwill 2016&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;title &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bae67e;&quot;&gt;&amp;quot;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#95e6cb;&quot;&gt;\x00&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bae67e;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color:#95e6cb;&quot;&gt;\x00 \x00&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bae67e;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#95e6cb;&quot;&gt;\x00&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bae67e;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color:#95e6cb;&quot;&gt;\x00&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bae67e;&quot;&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color:#95e6cb;&quot;&gt;\x00&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bae67e;&quot;&gt;w&lt;&#x2F;span&gt;&lt;span style=&quot;color:#95e6cb;&quot;&gt;\x00&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bae67e;&quot;&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color:#95e6cb;&quot;&gt;\x00&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bae67e;&quot;&gt;l&lt;&#x2F;span&gt;&lt;span style=&quot;color:#95e6cb;&quot;&gt;\x00&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bae67e;&quot;&gt;l&lt;&#x2F;span&gt;&lt;span style=&quot;color:#95e6cb;&quot;&gt;\x00&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bae67e;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5c6773;&quot;&gt;# Add a bunch of zeros to make the title 772 bytes long
&lt;&#x2F;span&gt;&lt;span&gt;title &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;+= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bae67e;&quot;&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95e6cb;&quot;&gt;\x00&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bae67e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;772&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f28779;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;(title)) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5c6773;&quot;&gt;# Much larger than 256 bytes!
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This creates a 772 byte string for the title. But this alone isn&#x27;t enough.&lt;&#x2F;p&gt;
&lt;p&gt;The MP4 file format needs each piece of data to be labeled with its exact size which means we also need the file metadata to tell the 3DS how long this title is. When the rest of this Python script builds the final M4A file, it calculates the length of our oversized title and embeds it as binary data into the file header, like any other MP4 file is structured.&lt;&#x2F;p&gt;
&lt;p&gt;The file isn&#x27;t lying about anything, it genuinely contains 772 bytes of title data, properly labeled and all. It&#x27;s just that 772 bytes is &lt;em&gt;way too many&lt;&#x2F;em&gt; bytes for a title, and it goes well over the allocated space of 256 bytes. This means that the rest of the 516 bytes end up writing over other regions of memory.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;2-triggering-the-heap-overflow&quot;&gt;2. Triggering the Heap Overflow&lt;&#x2F;h2&gt;
&lt;p&gt;When the &lt;em&gt;Nintendo 3DS Sound&lt;&#x2F;em&gt; application encounters our special file, it will read the size field in the file metadata, sees &quot;772 bytes of title data,&quot; and trustingly pass this value to the &lt;code&gt;memcpy()&lt;&#x2F;code&gt; function without questioning whether 772 bytes is a reasonable length for a song title.&lt;&#x2F;p&gt;
&lt;p&gt;When this happens, the 3DS:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;allocates the standard 256-byte buffer.&lt;&#x2F;li&gt;
&lt;li&gt;uses &lt;code&gt;memcpy()&lt;&#x2F;code&gt; with our provided length.&lt;&#x2F;li&gt;
&lt;li&gt;copies our oversized title, writing beyond the buffer&#x27;s boundaries&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;3-heap-manipulation-and-unlink-exploitation&quot;&gt;3. Heap Manipulation and Unlink Exploitation&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;heap-manipulation&quot;&gt;Heap Manipulation&lt;&#x2F;h3&gt;
&lt;p&gt;The heap overflow allows us to manipulate the heap&#x27;s metadata structures. Modern heap implementations maintain information about memory chunks, including:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Chunk sizes&lt;&#x2F;li&gt;
&lt;li&gt;Usage status&lt;&#x2F;li&gt;
&lt;li&gt;Forward&#x2F;backward pointers&lt;&#x2F;li&gt;
&lt;li&gt;Boundary tags&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;By overflowing into these structures, we can override some of this metadata and fool the heap manager into operating using this fake data. If you&#x27;re a little confused, &lt;a href=&quot;https:&#x2F;&#x2F;samienr.com&#x2F;blog&#x2F;soundhax&#x2F;memory#heap-overflow&quot;&gt;take a look at this&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;unlink-exploitation&quot;&gt;Unlink Exploitation&lt;&#x2F;h3&gt;
&lt;p&gt;When the heap manager needs to free a chunk, it performs an &quot;unlink&quot; operation to remove the chunk from its internal data structures and possibly also merge it with adjacent free chunks.&lt;&#x2F;p&gt;
&lt;p&gt;Part of this operation involves updating the forward and backward pointers of a chunk. This process assumes that the chunk metadata is trustworthy. Our fake chunk exploits this trust to achieve arbitrary memory writes.&lt;&#x2F;p&gt;
&lt;p&gt;This typically looks something like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;C&quot; style=&quot;background-color:#212733;color:#ccc9c2;&quot; class=&quot;language-C &quot;&gt;&lt;code class=&quot;language-C&quot; data-lang=&quot;C&quot;&gt;&lt;span&gt;chunk&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;fd&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;bk &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; chunk&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;bk&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;chunk&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;bk&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;fd &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; chunk&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;fd&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The allocator pretty much goes &quot;if this chunk says its next chunk is at address X, then I&#x27;ll update the chunk at address X to point back to the previous chunk.&quot; Except we are in control of those addresses. That is to say, we choose what address X is, and we control what the previous chunk&#x27;s address is, so we can make the allocator write an arbitrary value to an arbitrary location, A.K.A. an arbitrary write primitive.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;4-stack-manipulation-heap-feng-shui&quot;&gt;4. Stack Manipulation | &quot;Heap Feng Shui&quot;&lt;&#x2F;h2&gt;
&lt;p&gt;With control over the unlink operation, we can write to any memory location. However, this power must be wielded strategically. The SoundHax exploit uses a technique known as &lt;em&gt;heap feng shui&lt;&#x2F;em&gt; to gain control over the program&#x27;s execution stack.&lt;&#x2F;p&gt;
&lt;p&gt;The goal is to trick the heap allocator into returning a stack address when the program next requests a memory allocation. As for what this stack address is, Nedwill had to painstakingly find a particular address that&#x27;s contents look like a valid heap chunk with seemingly proper heap chunk metadata values&lt;&#x2F;p&gt;
&lt;p&gt;We use our arbitrary write primitive to overwrite the heap&#x27;s free list header with this stack address (via the unlink exploitation). At the same time, we manipulate the size field of the chunk being freed to make it appear very small, preventing it from being a viable option the next time the allocator looks for a free chunk. This sets up our fake stack &quot;chunk&quot; as the primary candidate for the next allocation.&lt;&#x2F;p&gt;
&lt;p&gt;When the program makes its next &lt;code&gt;malloc()&lt;&#x2F;code&gt; call, the heap allocator searches through the free list looking for a suitable block. It finds our fake chunk on the stack, validates that it has enough space and proper metadata, and then returns the stack address as if it were heap memory.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;5-rop-chain-construction-and-execution&quot;&gt;5. ROP Chain Construction and Execution&lt;&#x2F;h2&gt;
&lt;p&gt;With step 4, the application writes data to what it thinks is allocated heap memory, but it&#x27;s actually writing to the program&#x27;s execution stack. Since the stack contains values such return addresses and the local variables of functions, we now have access to control the program&#x27;s execution flow.&lt;&#x2F;p&gt;
&lt;p&gt;Unfortunately for us, however, we can&#x27;t go ahead and just write in instructions (A.K.A. shellcode) just yet. Modern systems, such as the one on the 3DS, have some protections to prevent executing code on the stack or heap. However, we can work around this by using a technique known as Return-Oriented Programming (ROP), which chains together small pieces of existing code to perform our desired operations.&lt;&#x2F;p&gt;
&lt;p&gt;Think of ROP as something like the cut-up technique, where an artist cuts scraps out of a book or magazine, then rearranges these scraps to create a new text the author never intended.

	&lt;img class=&quot;
			
			
			
			
                        
		&quot;
		alt=&quot;An example of the cut-up technique&quot;
		src=&quot;Cut_up_text.webp&quot; &#x2F;&gt;
	
	&lt;figcaption&gt;Imagine each one of these scraps is a piece of code.&lt;&#x2F;figcaption&gt;
	

&lt;&#x2F;p&gt;
&lt;p&gt;Each piece of code, or &quot;gadget,&quot; in our ROP chain is a small fragment of actual program code that performs a simple operation, like loading a register or calling a function, then returns control to the next gadget in the sequence.&lt;&#x2F;p&gt;
&lt;p&gt;The SoundHax ROP chain performs a handful of operations. First, it copies our second-stage payload from the stack to heap memory. Next, it sets up parameters for some GPU operations. Then it actually calls these GPU functions to perform memory copying operations that would normally be forbidden (more on this in the next section). Finally, it transfers control to our newly-positioned code.&lt;&#x2F;p&gt;
&lt;p&gt;Each step of this process uses code that already exists in the application&#x27;s memory space, making it extremely difficult for most prevention mechanisms to detect our attack.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;6-gpu-assisted-code-injection-gspwn&quot;&gt;6. GPU-Assisted Code Injection (gspwn)&lt;&#x2F;h2&gt;
&lt;p&gt;I briefly mentioned GPU functions. Now let&#x27;s actually talk about why we&#x27;re using graphics calls and how genius this move is.&lt;&#x2F;p&gt;
&lt;p&gt;When gaining code execution through the ROP chain, we were still constrained by the system&#x27;s memory protection mechanisms, meaning that we weren&#x27;t yet able to overwrite any of the application&#x27;s code segment from userland. This usually isn&#x27;t allowed as that would violate a bunch of security boundaries-- user applications &lt;em&gt;should&lt;&#x2F;em&gt; be kept separate from system code.&lt;&#x2F;p&gt;
&lt;p&gt;Nedwill&#x27;s solution to get around this was pretty creative: Abusing the 3DS&#x27;s GPU. The GPU has special privileges to perform direct memory access (DMA) transfers between memory regions. This means that while almost nothing should be able to copy data from heap memory into the executable text segment of running applications, the GPU &lt;em&gt;can.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This technique, known as &#x27;gspwn&#x27; in the 3DS homebrew community, effectively bypasses the system&#x27;s code signing and memory protection by using the GPU as an unwitting accomplice in our attack. The GPU doesn&#x27;t know or care that we&#x27;re abusing its power, it simply performs whatever operation is requested.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;7-full-code-execution&quot;&gt;7. Full Code Execution&lt;&#x2F;h2&gt;
&lt;p&gt;With our payload now residing in executable memory, the final step is to transfer control to it. Our ROP chain concludes by jumping to the newly-written code, which implements a second-stage loader that performs the final steps of the compromise.&lt;&#x2F;p&gt;
&lt;p&gt;The stage-2 payload disables potentially problematic system threads that might interfere with homebrew execution. It then opens and reads the &lt;code&gt;otherapp.bin&lt;&#x2F;code&gt; file from the SD card, which contains the &lt;colorize&gt;homebrew launcher.&lt;&#x2F;colorize&gt; For the uninitiated, the homebrew launcher is the gateway to running homebrew applications &lt;small&gt;(a.k.a. unsigned code that can be written by anyone without Nintendo&#x27;s approval)&lt;&#x2F;small&gt;. The ROP chain uses the GPU one more time to copy this payload into memory and transfer control to it.&lt;&#x2F;p&gt;
&lt;p&gt;At this point, the system is fully compromised and running arbitrary unsigned code with the same privileges as the original Sound application. The user will now see the homebrew launcher appear on screen.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h1&gt;
&lt;p&gt;Unlike many other exploits for various game consoles, SoundHax required no internet connection, specific games, hardware modifications, or any complex setup procedures. Users could simply download the appropriate M4A file for their region and firmware version, copy it to their SD card, and play it through that built-in &lt;em&gt;Nintendo 3DS Sound&lt;&#x2F;em&gt; application.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
