Hacking [GUIDE] Upgrading 8.1.0-0J to 9.2.0-20J

yifan_lu

@yifanlu
OP
Member
Joined
Apr 28, 2007
Messages
663
Trophies
0
XP
1,671
Country
United States
This method no longer works as-is because Nintendo removed the update files from their servers. You now need to host the files on your own server and modify the GetAccountStatus request to point to it. See here for the cached 9.1J/9.2U update files.

I posted this http://yifan.lu/2015/03/23/nintendo-3ds-system-updater/ but I thought some people here may be interested. Please note this should only be attempted by those who understand what they're doing (aka, this is not noob friendly). Hopefully someone may make a more noob friendly solution based on this information (like a NTR plugin with a hosted SOAP server). Also, this procedure can be used to upgrade any version to any other version (maybe even downgrade provided you are already <= 9.2) in any other region but that's an exercise left to the reader.

(Oh yeah, for those who have to ask. The reason for this is because ninjhax isn't supported on 8.1.0-0J)

Prerequisites

  • Cubic Ninja
  • NTR CFW 2.0 and NTR Debugger
  • A web server with support for some kind of scripting language (PHP for example)
  • Clear any pending update by entering recovery mode and exiting (I don’t think this is needed but better safe than sorry)
Steps

  1. Host the SOAP response for the version you want to update to on your web server. You can find all the raw SOAP responses from yellows8’s update report site. For example, here is the one for 9.1.0-20J. According to yellows8, there was a bug and his bot did not capture 9.2.0-20J. However, since there was only two titles changed in that update, I just manually crafted a 9.2.0-20J response.
  2. Host the SOAP response for the update title hash. Here is the template. You need to change the value of the TitleHash to match the TitleHash at the end of your update response from step 1.
  3. Create a script that responds with one of the two SOAP responses above depending if the request header is for “urn:nus.wsapi.broadon.com/GetSystemUpdate” or “SOAPAction: urn:nus.wsapi.broadon.com/GetSystemTitleHash”. I made a two lined PHP script called “update.php” that does this.
  4. Host the SOAP response for getting the server URLs. The template for this is here. You only need to change the value of NusURL to point to your NUS responder script created in step 3. (In my case, it would be http://myhost.com/update.php)
  5. Boot your 3DS into NTR CFW 2.0 and connect the debugger
  6. Use listprocess() to get the PID for “nim”. On 8.1.0-0J, it should be 0x25.
  7. Patch NIM to use your server for NetUpdateSOAP (this offset is for 8.1.0-0J): write(0x15E424, tuple(map(ord, “http://myhost.com/update.php\0″)), pid=0x25)
  8. Patch NIM to use your server for ECommerceSOAP. Since you’re only responding to GetAccountStatus, it is okay to hard code this: write(0x15E0EC, tuple(map(ord, “http://myhost.com/GetAccountStatus_response.xml\0″)), pid=0x25)
  9. Do the same for another reference to ECommerceSOAP: write(0x15E463, tuple(map(ord, “http://myhost.com/GetAccountStatus_response.xml\0″)), pid=0x25)
  10. Go into system settings, and perform an update (do NOT exit system settings as you will lose your patches and will have to perform them again after restarting).
  11. Once the update is done, you will be prompted to restart, however because you are in NTR mode, the screen will just go black. You need to hold the power button and manually restart.
EDIT: Bonus, here's a complete crafted 9.2.0U N3DS response: https://gist.github.com/yifanlu/a589c9655e05acbd30dc I say complete because the normal update response is missing a couple of titles that have never been updated (for example activity log). Region swapping requires you to install the complete set of titles.

EDIT 2: Oishikatta was kind enough to host the files, so you don't need to have a web server http://gbatemp.net/threads/guide-upgrading-8-1-0-0j-to-9-2-0-20j.384960/page-6#post-5420331 be warned that when you do this, you're sending your account id, serial number, and device token to someone else! (They can for example use this information to transfer your eshop account to their 3DS.)
 
Last edited by yifan_lu,

Link'sSpiritualAwakening

Well-Known Member
Newcomer
Joined
Mar 21, 2015
Messages
69
Trophies
0
Age
37
XP
101
Country
United States
That's really excellent. Hopefully someone makes a noobified version that will allow me to go from 8.1j to 9.2 US. Or someone makes a user friendly video for it. Only thing is I guess I'd lose access to my japan Cubic Ninja and OOT carts (not getting gateway.)
 
  • Like
Reactions: niño de cobre

Oishikatta

Well-Known Member
Member
Joined
Oct 30, 2014
Messages
971
Trophies
0
XP
603
Country
United States
That's really excellent. Hopefully someone makes a noobified version that will allow me to go from 8.1j to 9.2 US. Or someone makes a user friendly video for it. Only thing is I guess I'd lose access to my japan Cubic Ninja and OOT carts (not getting gateway.)


That's never going to happen. This is only for updating within the same region.
 
  • Like
Reactions: Margen67

Tokiopop

Caffeine fiend
Member
Joined
Apr 14, 2009
Messages
1,833
Trophies
0
Age
29
Location
UK
XP
446
Country
very nice :) thanks for this hard work! we are lucky you got an 8.1 3ds otherwise i doubt we would have seen this figured out haha.

-- and wow, how easy to remove the update nag for people bothered by it, nice link, funny we have not seen it before http://3dbrew.org/wiki/Recovery_Mode

I've seen the recovery mode thing mentioned a few times, guess it should be put in one of the stickies or something if it already isn't.

But this is great, being on 8.1J kinda sucked!
 

michyprima

Well-Known Member
Member
Joined
Feb 19, 2014
Messages
219
Trophies
0
Age
30
XP
201
Country
Italy
PHP:
<?php
 
header('Content-Type: text/xml');
 
$headers = apache_request_headers();
$myfile = fopen("log3ds.txt","a");
 
foreach ($headers as $header => $value) {
 
fwrite($myfile, $header);
fwrite($myfile, ": ");
fwrite($myfile, $value);
fwrite($myfile, "\n");
 
if($header == "SOAPAction") {
if($value == "urn:nus.wsapi.broadon.com/GetSystemUpdate") {
fwrite($myfile, "GetSystemUpdate detected\n");
echo file_get_contents("titleversion.xml");
} elseif ($value == "urn:nus.wsapi.broadon.com/GetSystemTitleHash") {
fwrite($myfile, "GetSystemTitleHash detected\n");
echo file_get_contents("titlehash.xml");
}
}
 
}
fwrite($myfile, "\n");
fclose($myfile);
die();
 
?>

any reason this isn't working?

It's the first time I try to use PHP, I'm not a web developer :)

Edit: investigating, my n3ds is also requesting GetSystemCommonETicket and since my php script isn't handling that, the update fails. :/ any clue?

Code:
Host: 192.168.43.97
User-Agent: CTR NUP 040600 Mar 14 2012 13:33:20
Connection: Keep-Alive
Accept-Charset: UTF-8
Content-type: text/xml; charset=utf-8
SOAPAction: urn:nus.wsapi.broadon.com/GetSystemTitleHash
GetSystemTitleHash detected
com.broadon.RequesterName: unitTest
com.broadon.RequesterHash: xxx
com.broadon.RequesterTimestamp: xxx
Transfer-Encoding: chunked
 
Host: 192.168.43.97
User-Agent: CTR NUP 040600 Mar 14 2012 13:33:20
Connection: Keep-Alive
Accept-Charset: UTF-8
Content-type: text/xml; charset=utf-8
SOAPAction: urn:nus.wsapi.broadon.com/GetSystemUpdate
GetSystemUpdate detected
com.broadon.RequesterName: unitTest
com.broadon.RequesterHash: xxx
com.broadon.RequesterTimestamp: xxx
Transfer-Encoding: chunked
 
Host: 192.168.43.97
User-Agent: CTR NUP 040600 Mar 14 2012 13:33:20
Connection: Keep-Alive
Accept-Charset: UTF-8
Content-type: text/xml; charset=utf-8
SOAPAction: urn:nus.wsapi.broadon.com/GetSystemCommonETicket
com.broadon.RequesterName: unitTest
com.broadon.RequesterHash: xxx
com.broadon.RequesterTimestamp: xxx
Transfer-Encoding: chunked
 

yifan_lu

@yifanlu
OP
Member
Joined
Apr 28, 2007
Messages
663
Trophies
0
XP
1,671
Country
United States
PHP:
<?php
 
header('Content-Type: text/xml');
 
$headers = apache_request_headers();
$myfile = fopen("log3ds.txt","a");
 
foreach ($headers as $header => $value) {
 
fwrite($myfile, $header);
fwrite($myfile, ": ");
fwrite($myfile, $value);
fwrite($myfile, "\n");
 
if($header == "SOAPAction") {
if($value == "urn:nus.wsapi.broadon.com/GetSystemUpdate") {
fwrite($myfile, "GetSystemUpdate detected\n");
echo file_get_contents("titleversion.xml");
} elseif ($value == "urn:nus.wsapi.broadon.com/GetSystemTitleHash") {
fwrite($myfile, "GetSystemTitleHash detected\n");
echo file_get_contents("titlehash.xml");
}
}
 
}
fwrite($myfile, "\n");
fclose($myfile);
die();
 
?>

any reason this isn't working?

It's the first time I try to use PHP, I'm not a web developer :)

Edit: investigating, my n3ds is also requesting GetSystemCommonETicket and since my php script isn't handling that, the update fails. :/ any clue?

Code:
Host: 192.168.43.97
User-Agent: CTR NUP 040600 Mar 14 2012 13:33:20
Connection: Keep-Alive
Accept-Charset: UTF-8
Content-type: text/xml; charset=utf-8
SOAPAction: urn:nus.wsapi.broadon.com/GetSystemTitleHash
GetSystemTitleHash detected
com.broadon.RequesterName: unitTest
com.broadon.RequesterHash: xxx
com.broadon.RequesterTimestamp: xxx
Transfer-Encoding: chunked
 
Host: 192.168.43.97
User-Agent: CTR NUP 040600 Mar 14 2012 13:33:20
Connection: Keep-Alive
Accept-Charset: UTF-8
Content-type: text/xml; charset=utf-8
SOAPAction: urn:nus.wsapi.broadon.com/GetSystemUpdate
GetSystemUpdate detected
com.broadon.RequesterName: unitTest
com.broadon.RequesterHash: xxx
com.broadon.RequesterTimestamp: xxx
Transfer-Encoding: chunked
 
Host: 192.168.43.97
User-Agent: CTR NUP 040600 Mar 14 2012 13:33:20
Connection: Keep-Alive
Accept-Charset: UTF-8
Content-type: text/xml; charset=utf-8
SOAPAction: urn:nus.wsapi.broadon.com/GetSystemCommonETicket
com.broadon.RequesterName: unitTest
com.broadon.RequesterHash: xxx
com.broadon.RequesterTimestamp: xxx
Transfer-Encoding: chunked

I've only seen it request GetSystemCommonETicket when trying to install update from a different region. Is that what you're trying to do? If so, be careful! If you screw up, you may brick your console. The process is a bit more tricky. You need to capture the common ticket request and proxy that too. What I did was get the private certs out of the 3DS and used a modified ninupdate script to proxy that request. However, since you can download cetk manually from nintendo's cdn, you can pretty much compose your own responses from the template I've provided and base64-encoding the cetk for the titles you need.
 

michyprima

Well-Known Member
Member
Joined
Feb 19, 2014
Messages
219
Trophies
0
Age
30
XP
201
Country
Italy
I've only seen it request GetSystemCommonETicket when trying to install update from a different region. Is that what you're trying to do? If so, be careful! If you screw up, you may brick your console. The process is a bit more tricky. You need to capture the common ticket request and proxy that too. What I did was get the private certs out of the 3DS and used a modified ninupdate script to proxy that request. However, since you can download cetk manually from nintendo's cdn, you can pretty much compose your own responses from the template I've provided and base64-encoding the cetk for the titles you need.
Yeah I read your article very carefully and no I'm not trying to switch between regions. I'm trying to upgrade from 8.1J to 9.2J. My guess is that the 3DS is requesting the ticket for the browser since this unit does not have one. Would you mind to provide a ticket response for it?
I would really appreciate your help sir.
Thanks for your time sharing your knowledge!
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    NinStar @ NinStar: It will actually make it worse