Toggle menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

3DS Save File Extraction Tools: Difference between revisions

From GameBrew
No edit summary
No edit summary
 
(15 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{Infobox 3DS homebrew
{{Infobox 3DS Homebrews
| title = 3DS Save File Extraction Tools
|title=3ds-save-tool
| image = https://dlhb.gamebrew.org/3dshomebrew/save3ds-.jpg|250px
|image=3dssavetool2.png
| type = PC Utilities
|description=Tools to extract 3DS format save file.
| version = Alpha
|author=wwylele
| licence = Mixed
|lastupdated=2020/06/26
| author = wwylele
|type=File Operation
| website = https://github.com/wwylele/3ds-save-tool
|version=Alpha
| download = https://dlhb.gamebrew.org/3dshomebrew/3ds-save-tool-master.zip
|license=Mixed
| source = https://dlhb.gamebrew.org/3dshomebrew/3ds-save-tool-master.zip
|download=https://dlhb.gamebrew.org/3dshomebrews/3ds_save_tool.zip
|website=https://github.com/wwylele/3ds-save-tool
|source=https://github.com/wwylele/3ds-save-tool
}}
}}
<youtube>0L9cJ2DGiX0</youtube>
= 3DS Save File Extraction Tools =
These are tools parsing save (DISA file) and extdata (DIFF file) and extracting files from them. The tools work with decrypted files. They also support encrypted SD files if necessary keys are provided. Create file <code>secrets.py</code> from the template <code>secrets.py.template</code> to provide your keys.
These are tools parsing save (DISA file) and extdata (DIFF file) and extracting files from them. The tools work with decrypted files. They also support encrypted SD files if necessary keys are provided. Create file <code>secrets.py</code> from the template <code>secrets.py.template</code> to provide your keys.


This repo also contains some old documentations of the save data format. They were migrated to 3dbrew and the version here is outdated and unmaintained. Please refer to the pages on 3dbrew instead.
This repo also contains some old documentations of the save data format. They were migrated to 3dbrew and the version here is outdated and unmaintained. Please refer to the pages on 3dbrew instead.


Required: python 3
'''Note:''' For richer functionality, use [[Save3DS|Save3DS]].
 
==User guide==
Required: python 3.


== Usage ==
Some typical usage of the tools is listed here. These commands assume that you already have python 3 in the system PATH.
* All the file/folder paths in the examples are just a hint of where you can find them.
* "nand" is where you have the decrypted & mounted NAND. "sdmc" is where the SD card is mounted.
* "output" is where you store the extracted files.
* "0123456789abcdef0123456789abcdef" is a random ID (id0) that you will have a different one from your 3DS, and "fedcba9876543210fedcba9876543210" as well (id1).


Some typical usage of the tools is listed here. These commands assume that you already have python 3 in the system PATH. All the file/folder paths in the examples are just a hint of where you can find them. &quot;nand&quot; is where you have the decrypted &amp; mounted NAND. &quot;sdmc&quot; is where the SD card is mounted. &quot;output&quot; is where you store the extracted files. &quot;0123456789abcdef0123456789abcdef&quot; is a random ID (id0) that you will have a different one from your 3DS, and &quot;fedcba9876543210fedcba9876543210&quot; as well (id1).
The general command form is <code>python disa/diff-extract.py INPUT OUTPUT OPTIONS</code>.  


The general command form is <code>python disa/diff-extract.py INPUT OUTPUT OPTIONS</code>. In all examples below, the output path can be omitted, in which case the tool will only print the information of the input file(s) without extracting the data.
In all examples below, the output path can be omitted, in which case the tool will only print the information of the input file(s) without extracting the data.


For more advanced usage, see the output by running the scripts without arguments.
For more advanced usage, see the output by running the scripts without arguments.


=== Extracting save data ===
===Extracting save data===
<syntaxhighlight style="border: 3px dashed blue;">
./disa-extract.py \
./disa-extract.py \
    "nand/data/0123456789abcdef0123456789abcdef/sysdata/00010026/00000000" \
    "nand/data/0123456789abcdef0123456789abcdef/sysdata/00010026/00000000" \
    "output/sysdata-00010026"
    "output/sysdata-00010026"
</syntaxhighlight>
 
This extracts system save data 00010026 (CECD data) from NAND to folder <code>output/sysdata-00010026</code>.
This extracts system save data 00010026 (CECD data) from NAND to folder <code>output/sysdata-00010026</code>.
-----
-----
<syntaxhighlight style="border: 3px dashed blue;">
./disa-extract.py \
./disa-extract.py \
    "sdmc/gm9out/00000001.sav" \
    "sdmc/gm9out/00000001.sav" \
    "output/savedata"
    "output/savedata"
</syntaxhighlight>
 
This extracts game save data that has been decrypted using GodMode9 (or any other tools) to folder <code>output/savedata</code>.
This extracts game save data that has been decrypted using GodMode9 (or any other tools) to folder <code>output/savedata</code>.
-----
-----
<syntaxhighlight style="border: 3px dashed blue;">
./disa-extract.py \
./disa-extract.py \
    "sdmc/Nintendo 3DS/0123456789abcdef0123456789abcdef/fedcba9876543210fedcba9876543210/title/00040000/00164800/data/00000001.sav" \
    "sdmc/Nintendo 3DS/0123456789abcdef0123456789abcdef/fedcba9876543210fedcba9876543210/title/00040000/00164800/data/00000001.sav" \
    "output/pokemon-sun-save" \
    "output/pokemon-sun-save" \
    -sd \
    -sd \
    -decrypt \
    -decrypt \
    -id 0004000000164800
    -id 0004000000164800
</syntaxhighlight>
 
This extracts encrypted save data of Pokemon Sun from SD card to folder <code>output/pokemon-sun-save</code>. Some requirement and notes of this command:
This extracts encrypted save data of Pokemon Sun from SD card to folder <code>output/pokemon-sun-save</code>. Some requirement and notes of this command:
* You need to create <code>secrets.py</code> from <code>secrets.py.template</code> and fill in the keys.
* You need to create <code>secrets.py</code> from <code>secrets.py.template</code> and fill in the keys.
* The parameter <code>-id XXXXXXXXXXXXXXXX</code> is the game title ID in 16-digit hex and must match the game.
* The parameter <code>-id XXXXXXXXXXXXXXXX</code> is the game title ID in 16-digit hex and must match the game.
* An additional library <code>Cryptodome</code> is needed.
* An additional library <code>Cryptodome</code> is needed.
* If the script outputs &quot;Error: CMAC mismatch.&quot;, it means that some of the keys or the title ID is incorrect.
* If the script outputs "Error: CMAC mismatch.", it means that some of the keys or the title ID is incorrect.
-----
 
=== Extracting extdata ===
<syntaxhighlight style="border: 3px dashed blue;">
./diff-extract.py \
    "nand/data/0123456789abcdef0123456789abcdef/extdata/00048000/f000000b" \
    "output/sysextdata-f000000b"
</syntaxhighlight>


===Extracting extdata===
./diff-extract.py \
    "nand/data/0123456789abcdef0123456789abcdef/extdata/00048000/f000000b" \
    "output/sysextdata-f000000b"
This extracts system extdata 00048000f000000b (contains coins info etc.) from NAND to folder <code>output/sysextdata-f000000b</code>.
This extracts system extdata 00048000f000000b (contains coins info etc.) from NAND to folder <code>output/sysextdata-f000000b</code>.


Note?do '''NOT''' enter the <code>00000000</code> folder inside <code>f000000b</code>.
'''Note:''' Do not enter the <code>00000000</code> folder inside <code>f000000b</code>.
-----
-----
<syntaxhighlight style="border: 3px dashed blue;">
./diff-extract.py \
./diff-extract.py \
    "sdmc/gm9out/12345678" \
    "sdmc/gm9out/12345678" \
    "output/extdata"
    "output/extdata"
This extracts extdata that has been decrypted using GodMode9 (or any other tools) to folder <code>output/extdata</code>. When using GodMode9, please copy the entire folder <code>sdmc/Nintendo 3DS/<id0>/<id1>/extdata/00000000/<id>/</code> (and do not enter the inner folder <code>00000000</code>) to somewhere else in SD card (<code>gm9out/</code> for example).
</syntaxhighlight>
 
This extracts extdata that has been decrypted using GodMode9 (or any other tools) to folder <code>output/extdata</code>. When using GodMode9, please copy the '''entire''' folder <code>sdmc/Nintendo 3DS/&lt;id0&gt;/&lt;id1&gt;/extdata/00000000/&lt;id&gt;/</code> (and do '''NOT''' enter the inner folder <code>00000000</code>!) to somewhere else in SD card (<code>gm9out/</code> for example).
-----
-----
 
./diff-extract.py \
<syntaxhighlight style="border: 3px dashed blue;">
    "sdmc/Nintendo 3DS/0123456789abcdef0123456789abcdef/fedcba9876543210fedcba9876543210/extdata/00000000/00001554" \
./diff-extract.py \
    "output/mhx-save" \
    "sdmc/Nintendo 3DS/0123456789abcdef0123456789abcdef/fedcba9876543210fedcba9876543210/extdata/00000000/00001554" \
    -decrypt \
    "output/mhx-save" \
    -id 00001554
    -decrypt \
    -id 00001554
</syntaxhighlight>
 
This extracts encrypted game extdata of Monster Hunter X from SD card to folder <code>output/mhx-save</code>. Some requirement and notes of this command:
This extracts encrypted game extdata of Monster Hunter X from SD card to folder <code>output/mhx-save</code>. Some requirement and notes of this command:
* You need to create <code>secrets.py</code> from <code>secrets.py.template</code> and fill in the keys.
* You need to create <code>secrets.py</code> from <code>secrets.py.template</code> and fill in the keys.
* The parameter <code>-id XXXXXXXX</code> is the extdata ID in 8-digit hex and must match the game. It is usually similar to the game title ID.
* The parameter <code>-id XXXXXXXX</code> is the extdata ID in 8-digit hex and must match the game. Usually similar to the game title ID.
* An additional library <code>Cryptodome</code> is needed.
* An additional library <code>Cryptodome</code> is needed.
* If the script outputs &quot;Error: CMAC mismatch.&quot;, it means that some of the keys or the extdata ID is incorrect.
* If the script outputs "Error: CMAC mismatch.", it means that some of the keys or the extdata ID is incorrect.
-----
 
=== Extracting single DIFF file (titledb file, extdata subfile etc.) ===
 
<syntaxhighlight style="border: 3px dashed blue;">
./diff-extract.py \
    "nand/dbs/ticket.db" \
    "output/ticket"
</syntaxhighlight>


===Extracting single DIFF file (titledb file, extdata subfile etc.)===
./diff-extract.py \
    "nand/dbs/ticket.db" \
    "output/ticket"
This extracts the ticket database file from NAND to folder <code>output/ticket</code>.
This extracts the ticket database file from NAND to folder <code>output/ticket</code>.
-----
-----
 
./diff-extract.py \
<syntaxhighlight style="border: 3px dashed blue;">
    "sdmc/gm9out/title.db" \
./diff-extract.py \
    "output/title"
    "sdmc/gm9out/title.db" \
    "output/title"
</syntaxhighlight>
 
This extracts the title database file that has been decrypted using GodMode9 (or any other tools) from SD to folder <code>output/title</code>.
This extracts the title database file that has been decrypted using GodMode9 (or any other tools) from SD to folder <code>output/title</code>.
-----
-----
 
./diff-extract.py \
<syntaxhighlight style="border: 3px dashed blue;">
    "sdmc/Nintendo 3DS/0123456789abcdef0123456789abcdef/fedcba9876543210fedcba9876543210/dbs/title.db" \
./diff-extract.py \
    "output/title" \
    "sdmc/Nintendo 3DS/0123456789abcdef0123456789abcdef/fedcba9876543210fedcba9876543210/dbs/title.db" \
    -titledb \
    "output/title" \
    -decrypt \
    -titledb \
    -id 2
    -decrypt \
    -id 2
</syntaxhighlight>
 
This extracts the encrypted title database file from SD to folder <code>output/title</code>. Some requirement and notes of this command:
This extracts the encrypted title database file from SD to folder <code>output/title</code>. Some requirement and notes of this command:
* You need to create <code>secrets.py</code> from <code>secrets.py.template</code> and fill in the keys.
* You need to create <code>secrets.py</code> from <code>secrets.py.template</code> and fill in the keys.
* The parameter <code>-id X</code> is title database ID: 2 for title.db and 3 for import.db.
* The parameter <code>-id X</code> is title database ID: 2 for title.db and 3 for import.db.
* An additional library <code>Cryptodome</code> is needed.
* An additional library <code>Cryptodome</code> is needed.
* If the script outputs &quot;Error: CMAC mismatch.&quot;, it means that some of the keys or the ID is incorrect.
* If the script outputs "Error: CMAC mismatch.", it means that some of the keys or the ID is incorrect.


=== Extracting Title databse (<code>*.db</code> files, except for <code>certs.db</code>) ===
===Extracting Title databse (<code>*.db</code> files, except for <code>certs.db</code>)===
./db-extract.py \
    "output/ticket" \
    "output/tickets"
This extracts all ticket subfiles from file <code>output/ticket</code> to <code>output/tickets</code>. The input file of this command is this output file of the <code>./diff-extract.py</code> command shown above.


<syntaxhighlight style="border: 3px dashed blue;">
A bash file that pipes the two commands is also provided. It takes the original <code>ticket.db</code> file as input.
./db-extract.py \
./db-fast.sh \
    "output/ticket" \
    "nand/dbs/ticket.db" \
    "output/tickets"
    "output/tickets"
</syntaxhighlight>


This extracts all ticket subfiles from file <code>output/ticket</code> to <code>output/tickets</code>. The input file of this command is ''this output file of the <code>./diff-extract.py</code> command'' shown above.
==Screenshots==
https://dlhb.gamebrew.org/3dshomebrews/3dssavetool3.png


A bash file that pipes the two commands is also provided. It takes ''the original <code>ticket.db</code> file'' as input.
https://dlhb.gamebrew.org/3dshomebrews/3dssavetool4.png


<syntaxhighlight style="border: 3px dashed blue;">
==External links==
./db-fast.sh \
* GitHub - https://github.com/wwylele/3ds-save-tool
    "nand/dbs/ticket.db" \
    "output/tickets"
</syntaxhighlight>

Latest revision as of 10:32, 22 Haziran 2024

3ds-save-tool
3dssavetool2.png
General
Authorwwylele
TypeFile Operation
VersionAlpha
LicenseMixed
Last Updated2020/06/26
Links
Download
Website
Source

These are tools parsing save (DISA file) and extdata (DIFF file) and extracting files from them. The tools work with decrypted files. They also support encrypted SD files if necessary keys are provided. Create file secrets.py from the template secrets.py.template to provide your keys.

This repo also contains some old documentations of the save data format. They were migrated to 3dbrew and the version here is outdated and unmaintained. Please refer to the pages on 3dbrew instead.

Note: For richer functionality, use Save3DS.

User guide

Required: python 3.

Some typical usage of the tools is listed here. These commands assume that you already have python 3 in the system PATH.

  • All the file/folder paths in the examples are just a hint of where you can find them.
  • "nand" is where you have the decrypted & mounted NAND. "sdmc" is where the SD card is mounted.
  • "output" is where you store the extracted files.
  • "0123456789abcdef0123456789abcdef" is a random ID (id0) that you will have a different one from your 3DS, and "fedcba9876543210fedcba9876543210" as well (id1).

The general command form is python disa/diff-extract.py INPUT OUTPUT OPTIONS.

In all examples below, the output path can be omitted, in which case the tool will only print the information of the input file(s) without extracting the data.

For more advanced usage, see the output by running the scripts without arguments.

Extracting save data

./disa-extract.py \
    "nand/data/0123456789abcdef0123456789abcdef/sysdata/00010026/00000000" \
    "output/sysdata-00010026"

This extracts system save data 00010026 (CECD data) from NAND to folder output/sysdata-00010026.


./disa-extract.py \
    "sdmc/gm9out/00000001.sav" \
    "output/savedata"

This extracts game save data that has been decrypted using GodMode9 (or any other tools) to folder output/savedata.


./disa-extract.py \
    "sdmc/Nintendo 3DS/0123456789abcdef0123456789abcdef/fedcba9876543210fedcba9876543210/title/00040000/00164800/data/00000001.sav" \
    "output/pokemon-sun-save" \
    -sd \
    -decrypt \
    -id 0004000000164800

This extracts encrypted save data of Pokemon Sun from SD card to folder output/pokemon-sun-save. Some requirement and notes of this command:

  • You need to create secrets.py from secrets.py.template and fill in the keys.
  • The parameter -id XXXXXXXXXXXXXXXX is the game title ID in 16-digit hex and must match the game.
  • An additional library Cryptodome is needed.
  • If the script outputs "Error: CMAC mismatch.", it means that some of the keys or the title ID is incorrect.

Extracting extdata

./diff-extract.py \
    "nand/data/0123456789abcdef0123456789abcdef/extdata/00048000/f000000b" \
    "output/sysextdata-f000000b"

This extracts system extdata 00048000f000000b (contains coins info etc.) from NAND to folder output/sysextdata-f000000b.

Note: Do not enter the 00000000 folder inside f000000b.


./diff-extract.py \
    "sdmc/gm9out/12345678" \
    "output/extdata"

This extracts extdata that has been decrypted using GodMode9 (or any other tools) to folder output/extdata. When using GodMode9, please copy the entire folder sdmc/Nintendo 3DS/<id0>/<id1>/extdata/00000000/<id>/ (and do not enter the inner folder 00000000) to somewhere else in SD card (gm9out/ for example).


./diff-extract.py \
    "sdmc/Nintendo 3DS/0123456789abcdef0123456789abcdef/fedcba9876543210fedcba9876543210/extdata/00000000/00001554" \
    "output/mhx-save" \
    -decrypt \
    -id 00001554

This extracts encrypted game extdata of Monster Hunter X from SD card to folder output/mhx-save. Some requirement and notes of this command:

  • You need to create secrets.py from secrets.py.template and fill in the keys.
  • The parameter -id XXXXXXXX is the extdata ID in 8-digit hex and must match the game. Usually similar to the game title ID.
  • An additional library Cryptodome is needed.
  • If the script outputs "Error: CMAC mismatch.", it means that some of the keys or the extdata ID is incorrect.

Extracting single DIFF file (titledb file, extdata subfile etc.)

./diff-extract.py \
    "nand/dbs/ticket.db" \
    "output/ticket"

This extracts the ticket database file from NAND to folder output/ticket.


./diff-extract.py \
    "sdmc/gm9out/title.db" \
    "output/title"

This extracts the title database file that has been decrypted using GodMode9 (or any other tools) from SD to folder output/title.


./diff-extract.py \
    "sdmc/Nintendo 3DS/0123456789abcdef0123456789abcdef/fedcba9876543210fedcba9876543210/dbs/title.db" \
    "output/title" \
    -titledb \
    -decrypt \
    -id 2

This extracts the encrypted title database file from SD to folder output/title. Some requirement and notes of this command:

  • You need to create secrets.py from secrets.py.template and fill in the keys.
  • The parameter -id X is title database ID: 2 for title.db and 3 for import.db.
  • An additional library Cryptodome is needed.
  • If the script outputs "Error: CMAC mismatch.", it means that some of the keys or the ID is incorrect.

Extracting Title databse (*.db files, except for certs.db)

./db-extract.py \
    "output/ticket" \
    "output/tickets"

This extracts all ticket subfiles from file output/ticket to output/tickets. The input file of this command is this output file of the ./diff-extract.py command shown above.

A bash file that pipes the two commands is also provided. It takes the original ticket.db file as input.

./db-fast.sh \
    "nand/dbs/ticket.db" \
    "output/tickets"

Screenshots

3dssavetool3.png

3dssavetool4.png

External links

Advertising: