Ghost0159 / saveShop

Let's save the 3DS and Wii U eShop!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

saveShop

The eShop for the 3DS and Wii U is closing down on 27 March 2023. Let's save it!

saveShop is a PC tool that scrapes the eShop for metadata and media files (screenshots/videos). A web-based game list is included to explore the scraped data.

Demo screenshot

Why?

The data presented on the eShop provides historical context to games that you wouldn't find by just playing them, such as game descriptions, trailers, user-ratings, and more.

These things present interesting background to a game's release:

  • What features were considered innovative at the time? What catch-phrases did the developers highlight?
  • What screenshots and trailers were released alongside the game release to show off the game's strengths?
  • Did the gaming community welcome or reject the title at the time? How widely was it played?

Sadly, for one reason or another, many preservation communities don't bother archiving this historical context. It would be a shame to lose it just because its significance wasn't widely understood at the time. With saveShop, your own personal archive is in close reach!

Legal disclaimer

This tool cannot be used to download games. The authors of this tool do not host public archives.

Use of this tool may be subject to legislation in your country and/or the country the accessed servers reside in. Terms of service may apply. Text and data mining may be considered legal for the purposes of pattern and trend analysis, but speak to your lawyer if in doubt about your legal situation.

Build & Usage

The Rust package manager Cargo is required to build saveShop. Run the following for usage instructions:

cargo run -- --help

For most subcommands, the server region(s) to fetch data from must be specified using --regions.

For full metadata access, you will need to provide the 3DS client certificate (see below). If video data is dumped (fetch-media --fetch-videos), saveShop can auto-convert moflex videos to mp4 using the convert-media subcommand (requires FFmpeg to be installed).

Incomplete runs can be resumed, but the initial rescan will take some time.

Extract 3DS client certificate

The 3DS client certificate ("ClCertA") is required to access metadata from Ninja servers. The certificate can be dumped in either of three ways. In all cases, the certificate must be converted to PEM format after dumping.

Option 1: Dump fully decrypted certificate from a 3DS using ccrypt

The most convenient option to dump the certificate is to run ccrypt on a 3DS.

Option 2: Dump certificate from a 3DS

Using GodMode9, navigate to CTRNAND/title/0004001b/00010002/content/00000000.app, select NCCH image options and then Mount image to drive. Enter the romfs directory in the mounted image. You should see two files, ctr-common-1-cert.bin and ctr-common-1-key.bin. Copy each file to the SD card and transfer it to a PC.

These files are AES encrypted using 3DS key slot 0xd. This is the same key you'd put into the slot0x0DKeyN line of an aes_keys.txt file used by Citra. To decrypt the data on PC, run these commands (where <aeskey_0x0d> must be replaced with the 32-hex-digit AES key):

dd if=ctr-common-1-cert.bin of=ctr-common-1-cert.bin.iv bs=1 count=16
dd if=ctr-common-1-cert.bin of=ctr-common-1-cert.bin.contents bs=1 skip=16
dd if=ctr-common-1-key.bin of=ctr-common-1-key.bin.iv bs=1 count=16
dd if=ctr-common-1-key.bin of=ctr-common-1-key.bin.contents bs=1 skip=16
openssl enc -aes-128-cbc -nosalt -d -in ctr-common-1-cert.bin.contents -K <aeskey_0x0d> -iv `xxd -p ctr-common-1-cert.bin.iv` > ctr-common-1-cert.dec
openssl enc -aes-128-cbc -nosalt -d -in ctr-common-1-key.bin.contents -K <aeskey_0x0d> -iv `xxd -p ctr-common-1-key.bin.iv` > ctr-common-1-key.dec

Option 3: Dump certificate from NUS

It's assumed you know what you're doing here. Don't forget to decrypt the data using the CLCertA's title key. Like in Option 2, this data must additionally be decrypted with AES key 0xd.

After dumping the certificate: Converting to PEM format

First, ensure the dumping process was successful using:

curl --cert-type DER --key-type DER --cert ctr-common-1-cert.dec --key ctr-common-1-key.dec --insecure https://ninja.ctr.shop.nintendo.net/ninja/ws/country/US

Then, combine the two decrypted files into a single PEM file:

openssl x509 -in ctr-common-1-cert.dec -inform DER -out ctr-common-1-cert.pem -outform PEM
openssl rsa -in ctr-common-1-key.dec -inform DER -out ctr-common-1-key.pem -outform PEM
cat ctr-common-1-cert.pem ctr-common-1-key.pem > ctr-common-1.pem
rm ctr-common-1-cert.pem ctr-common-1-key.pem

Again verify everything went smoothly using:

curl --cert ctr-common-1.pem --insecure https://ninja.ctr.shop.nintendo.net/ninja/ws/country/US

You can now pass this certificate to saveShop using the --cert option.

Viewing results

A web-app is included to explore scraped contents. Copy index.html to the directory you ran saveShop in and open a local HTTP server (e.g. by running python3 -m http.server). You should then be able to view the data by navigating to localhost:8000 in your web browser.

TODO

  • Improve Wii U eShop scraping

About

Let's save the 3DS and Wii U eShop!


Languages

Language:Rust 75.1%Language:HTML 24.9%