From 3dbrew
Jump to navigation Jump to search

The Old3DS+New3DS 10.4.0-29 system update was released on January 18, 2016. This Old3DS update was released for the following regions: USA, EUR, JPN, CHN, KOR, and TWN. This New3DS update was released for the following regions: USA, EUR, JPN, CHN, and KOR.

Security flaws fixed: yes, see below.

Old3DS/New3DS browserhax and menuhax were not fixed(the Old3DS browser wasn't even updated).


Official USA change-log:

  • Further improvements to overall system stability and other minor adjustments have been made to enhance the user experience

System Titles[edit]


memchunkhax2 was partially fixed by reading the MemoryBlockHeader next pointer before it is mapped to userland, but it can still be exploited using GPU. Only one function was changed in arm11kernel.

The only updated FIRM sysmodules were fs and loader, for fs only a version-field in .code was updated used with a debug NOP-instruction.


The loader process .text was previously 0x331C-bytes, it's now 0x36F0-bytes.

All code changes:

  • Some code using svcGetSystemTick was added. This is used by L_14002670.
  • L_140022b8(L_14002234 in previous loader version): This is the function which calls L_140025f0. Code was added between the code which loads the memregion value from exheader, and the func call for mapping it(L_140025f0). This new code determines what to pass for the L_140025f0 insp4 flag. By default the value passed for that flag is 0.
    • When the process memregion is APPLICATION, the programID is for a CTR title, and the uniqueid matches the eShop system-application(all regions including CHN), the flag is set to 1.
    • When the process memregion is SYSTEM, the flag is set to 1 when the reslimit_category is not LIB_APPLET.
  • L_140025f0(L_140024e4 in previous loader version) now calls another function(L_14002670) instead of svcControlMemory directly, for mapping the codebin memory. The insp4 flag from the L_140025f0 input is passed to L_14002670 as sp0.
  • L_14002670: New function used for mapping the codebin. When the insp0 flag is zero, this does the normal memory-mapping, otherwise a special memory-mapping codepath is used. This codepath still uses the same memregion specified in the exheader.

The special memory-mapping codepath is basically a method of mapping the codebin with svcControlMemory using up to 8 chunks, each with a random size. Each chunk is done in a random order. Since the allocation order is random, this also means the order of each .text chunk in physmem is random too. When the total size of the randomized page-count is less than the required amount, an 8th chunk is used to pad the total size to the exact required size. It appears the total combined size used with svcControlMemory is always exactly the same as what's required for the codebin.

Regarding chunk size calculation:

  • s32 maxval = (codebin_totalrequiredpages - pagepos) >> 4;
  • The above maxval field is set to 15 if it's >=15.
  • pagecount = L_14001730(maxval);
  • pagecount = (pagecount+1) << 4;
  • chunksize = pagecount << 12;

This is an attempt at randomizing the layout of physmem .text, due to gspwn.


There were no New3DS-only changes in Process9, the arm9loader wasn't changed either.

There were exactly 4 updated functions in Process9, all of these involve NTRCARD:

  • The first two functions had code added which clears a certain state field to 0 around the beginning of the function.
  • The third function now passes value 0x1000 as inr2 when calling the fourth function.
  • The fourth and last function, this is the function used for reading the card header. A buffer-overflow check was added in the NTRCARD reading loop: "if(out_bufpos >= inr2)<skip over copying the word to output>".


NS added a new APT command used by Home Menu which now checks whether IronFall is on the latest version before launching; if it is on an exploitable version and the function is called to launch IronFall the system will refuse to launch the title(it's unknown what exactly caused a "reboot" here). This check is done again before launching the title, throwing an error if it fails.

All NS code changes:

  • L_103e6c(prev ver at L_103e6c): APT cmd-handler, this was updated for the command mentioned above.
  • L_1086f4: New function, this is called by the above cmd-handler. This basically just calls L_10b1cc.
  • L_10b1cc: New function, this is the actual APT:IsTitleAllowed implementation. Returns 0 for blocked, 1 for allowed.
    • The beginning of this function is the same as L_10d598, without the u16 check right away.
    • This initializes amu, then uses AM:GetTitleInfo with the input programID(mediatype is hard-coded to SD). If the latter returns an error, this will exit with retval0.
    • If u16 entry+4 is < (titleversion>>10), this then exits with retval1.
    • Then the AM:GetTitleInfo + versioncheck code is repeated using the update-data title.
    • This lastly exits, with retval1 if the update-data titlever is newer than the entry one.
  • L_10d598: New function, only called by L_10df40. This is the internal-NS-only version of the APT:IsTitleAllowed code. Returns 0 for blocked, 1 for allowed.
    • This immediately returns 1 when the mediatype isn't SD, or when the title isn't a CTR title.
    • Then it loads the uniqueid from the input struct, for determining which entry to use from a table in .rodata. The uniqueid is compared with hard-coded constants in the function code itself, even though the table contains the uniqueids too. The code looks like: "if(uniqueid == constant0) {entryptr = addr0} else if ...". When no entry is found, this immediately returns 1.
    • Lastly, if input_version_value is <= u16 entry+4, this returns 0, otherwise 1 is returned.
  • L_10df40(prev ver at L_10ddd4): This appears to be the main function used by NS for launching titles in general(minus NSS:LaunchTitle used by the *hax payloads). Code was added for calling L_10d598() in two locations. The version value passed to L_10d598 here is the title NCCH remaster-version. When that function returns <blocked>, this code returns error 0xC8A0CC04.

See here regarding the contents of that table.

Home Menu[edit]

The code changes for Home Menu appear to be just title/AM related / GUI.

Code was implemented for using APT:IsTitleAllowed mentioned above. This is only done after VersionList handling(for example when one tries to launch the app without updating), prior to doing the actual application launch. When that returns 0, Home Menu will display a message using the following text from new message-strings:

You need to update this 
software before you can
launch it.

SpotPass sysmodule[edit]

Only one function was changed in the BOSS/SpotPass sysmodule, the changes in this function seem to be minor.

Internet Browser[edit]

Only the New3DS Internet Browser was updated, see here for that.

eShop system-application[edit]

Some ratings-related strings were added to the main codebin("ratPEGI_U_02" and "detailPEGI_D_01").

The message files were updated:

diff --git a/v19465/tiger.msbt.lz.decom.wstrs b/v20482/tiger.msbt.lz.decom.wstrs
index 2a3a24e..55358d0 100644
--- a/v19465/tiger.msbt.lz.decom.wstrs
+++ b/v20482/tiger.msbt.lz.decom.wstrs
@@ -258,6 +258,7 @@ Charts
 Search Results: 
 Price: TBD
 Offers in-game purchases
 This software is currently unavailable.
 Go to Page


Only the main codebin was updated, nothing changed with strings in that codebin(besides a string containing a version which gets updated for each mint update).


The USA 0004009B00012302 CFA(and the equivalent titleIDs for the other regions) was updated, the following message was added to 20000_msbt_LZ.bin:

An error has occurred.
Please check if there is corrupted data
in Data Management 
 Nintendo 3DS
in the System Settings.
If the problem persists, please
make a note of the error code
and visit support.nintendo.com.

See Also[edit]

System update report(s):