Pubblicato un nuovo aggiornamento per LibHac, la libreria .NET reimplementa alcune parti del sistema operativo della console Nintendo Switch, noto anche come Horizon OS.
La maggior parte dei contenuti viene importata ed esportata utilizzando un’interfaccia IStorage standard. Ciò significa che la lettura di tipi di file nidificati e le cifrature possono essere facilmente eseguite collegando diversi lettori di file tra loro.
Ad esempio, i file di un titolo archiviato sulla scheda SD esterna possono essere letti o estratti in questo modo: NAX0 Reader
-> NCA Reader
-> RomFS Reader
-> Individual Files
.
LibHac utilizza diverse interfacce per leggere e scrivere dati e file, basandosi sulle interfacce del sistema operativo Horizon:
IStorage
IStorage è un’interfaccia utilizzata da LibHac per leggere e scrivere dati, simile a .NET Stream, ma a differenza di un Stream, un oggetto IStorage non tiene traccia della propria posizione, è necessario specificare un offset ad ogni operazione di lettura.
IStorage usa intervalli di byte (span) per leggere e scrivere dati, e la lunghezza dei dati letti o scritti è uguale alla lunghezza dello span fornito.
IFile
IFile è simile a IStorage, ma con alcune differenze significative:
- IFile può crescere automaticamente se i dati vengono scritti oltre la fine del file, mentre IStorage non cresce automaticamente.
- Quando si richiedono più byte di quelli disponibili, IFile leggerà quanti più byte possibile e restituirà il numero di byte letti, mentre IStorage genererà un’eccezione.
IFileSystem
Questa è un’interfaccia che rappresenta un file system standard e fornisce funzionalità per leggere file, navigare nel file system, creare file, ecc..
Utilizzo di LibHac
Caricamento delle chiavi
La maggior parte delle funzionalità di LibHac richiede un oggetto Keyset che contiene le chiavi di crittografia necessarie per leggere il contenuto.
Questo può essere fatto caricando le chiavi da un file di testo esterno o creando un nuovo oggetto Keyset
e copiando le chiavi al suo interno.
Keyset keyset = ExternalKeys.ReadKeyFile("common_key_file", "title_key_file", "console_key_file");
I file di testo devono seguire il formato specificato in questo documento.
Lettura di un file NCA
Per aprire un file NCA e ottenere un IStorage
dei file decrittografati:
using (IStorage inFile = new LocalStorage("filename.nca", FileAccess.Read))
{
var nca = new Nca(keyset, inFile);
IStorage decryptedNca = nca.OpenDecryptedNca();
}
Per aprire la sezione del codice di un file NCA:
using (IStorage inFile = new LocalStorage("filename.nca", FileAccess.Read))
{
var nca = new Nca(keyset, inFile);
IStorage section = nca.OpenStorage(NcaSectionType.Code, IntegrityCheckLevel.ErrorOnInvalid);
}
Per aprire la sezione dati di un file NCA come file IFileSystem
:
using (IStorage inFile = new LocalStorage("filename.nca", FileAccess.Read))
{
var nca = new Nca(keyset, inFile);
IFileSystem fileSystem = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None);
}
SVengono forniti metodi di estensione per operazioni comuni sulle interfacce LibHac.
IFileSystem.CopyFileSystem
copia completamente il contenuto di un IFileSystem
in un altro.
using (IStorage inFile = new LocalStorage("filename.nca", FileAccess.Read))
{
var nca = new Nca(keyset, inFile);
var outFileSystem = new LocalFileSystem("extracted_path");
IFileSystem fileSystem = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
fileSystem.CopyFileSystem(outFileSystem);
}
Per aprire un file NCA con una patch:
using (IStorage baseFile = new LocalStorage("base.nca", FileAccess.Read))
using (IStorage patchFile = new LocalStorage("base.nca", FileAccess.Read))
{
var baseNca = new Nca(keyset, baseFile);
var patchNca = new Nca(keyset, patchFile);
IFileSystem fileSystem = baseNca.OpenFileSystemWithPatch(patchNca, NcaSectionType.Data,
IntegrityCheckLevel.ErrorOnInvalid);
}
Operazioni su IFileSystem
Per aprire un file e leggere i primi 0x4000 byte:
using (IStorage inFile = new LocalStorage("filename.nca", FileAccess.Read))
{
var nca = new Nca(keyset, inFile);
IFileSystem fileSystem = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
var buffer = new byte[0x4000];
IFile myFile = fileSystem.OpenFile("/my/file/path.ext", OpenMode.Read);
int bytesRead = myFile.Read(buffer, 0);
}
Si può utilizzare IDirectory
per enumerare le voci del file system in una directory.
hactoolnet
hactoolnet è un programma di esempio che utilizza LibHac. Viene utilizzato in modo simile a hactool.
Utilizzo
Usage: hactoolnet.exe [options...] <path>
Options:
-r, --raw Keep raw data, don't unpack.
-y, --verify Verify all hashes in the input file.
-h, --enablehash Enable hash checks when reading the input file.
-d, --dev Decrypt with development keys instead of retail.
-k, --keyset Load keys from an external file.
-t, --intype=type Specify input file type [nca, xci, romfs, pfs0, pk11, pk21, ini1, kip1, switchfs, save, ndv0, keygen, romfsbuild, pfsbuild]
--titlekeys <file> Load title keys from an external file.
--accesslog <file> Specify the access log file path.
--disablekeywarns Disables warning output when loading external keys.
--version Display version information and exit.
--help Display this help and exit.
NCA options:
--plaintext <file> Specify file path for saving a decrypted copy of the NCA.
--ciphertext <file> Specify file path for saving an encrypted copy of the NCA.
--header <file> Specify Header file path.
--section0 <file> Specify Section 0 file path.
--section1 <file> Specify Section 1 file path.
--section2 <file> Specify Section 2 file path.
--section3 <file> Specify Section 3 file path.
--section0dir <dir> Specify Section 0 directory path.
--section1dir <dir> Specify Section 1 directory path.
--section2dir <dir> Specify Section 2 directory path.
--section3dir <dir> Specify Section 3 directory path.
--exefs <file> Specify ExeFS file path.
--exefsdir <dir> Specify ExeFS directory path.
--romfs <file> Specify RomFS file path.
--romfsdir <dir> Specify RomFS directory path.
--listromfs List files in RomFS.
--basenca Set Base NCA to use with update partitions.
KIP1 options:
--uncompressed <f> Specify file path for saving uncompressed KIP1.
RomFS options:
--romfsdir <dir> Specify RomFS directory path.
--listromfs List files in RomFS.
RomFS creation options:
Input path must be a directory
--outfile <file> Specify created RomFS file path.
Partition FS options:
--outdir <dir> Specify extracted FS directory path.
Partition FS creation options:
Input path must be a directory
--outfile <file> Specify created Partition FS file path.
--hashedfs Create a hashed Partition FS (HFS0).
XCI options:
--rootdir <dir> Specify root XCI directory path.
--updatedir <dir> Specify update XCI directory path.
--normaldir <dir> Specify normal XCI directory path.
--securedir <dir> Specify secure XCI directory path.
--logodir <dir> Specify logo XCI directory path.
--outdir <dir> Specify XCI directory path.
--nspout <file> Specify file for the created NSP.
Partition FS and XCI options:
--exefs <file> Specify main ExeFS file path.
--exefsdir <dir> Specify main ExeFS directory path.
--romfs <file> Specify main RomFS file path.
--romfsdir <dir> Specify main RomFS directory path.
--listapps List application info.
--listtitles List title info for all titles.
--listncas List info for all NCAs.
--title <title id> Specify title ID to use.
Package1 options:
--outdir <dir> Specify Package1 directory path.
Package2 options:
--outdir <dir> Specify Package2 directory path.
--extractini1 Enable INI1 extraction to default directory (redundant with --ini1dir set).
--ini1dir <dir> Specify INI1 directory path. Overrides default path, if present.
INI1 options:
--outdir <dir> Specify INI1 directory path.
Switch FS options:
--sdseed <seed> Set console unique seed for SD card NAX0 encryption.
--listapps List application info.
--listtitles List title info for all titles.
--listncas List info for all NCAs.
--title <title id> Specify title ID to use.
--outdir <dir> Specify directory path to save title NCAs to. (--title must be specified)
--exefs <file> Specify ExeFS directory path. (--title must be specified)
--exefsdir <dir> Specify ExeFS directory path. (--title must be specified)
--romfs <file> Specify RomFS directory path. (--title must be specified)
--romfsdir <dir> Specify RomFS directory path. (--title must be specified)
--savedir <dir> Specify save file directory path.
-y, --verify Verify all titles, or verify a single title if --title is set.
Save data options:
--outdir <dir> Specify directory path to save contents to.
--debugoutdir <dir> Specify directory path to save intermediate data to for debugging.
--sign Sign the save file. (Requires device_key in key file)
--trim Trim garbage data in the save file. (Requires device_key in key file)
--listfiles List files in save file.
--repack <dir> Replaces the contents of the save data with the specified directory.
--replacefile <filename in save> <file> Replaces a file in the save data
NAX0 options:
--sdseed <seed> Set console unique seed for SD card NAX0 encryption.
--sdpath <path> Set relative path for NAX0 key derivation (ex: /registered/000000FF/cafebabecafebabecafebabecafebabe.nca).
--plaintext Specify file path to save decrypted contents.
NDV0 (Delta) options:
Input delta patch can be a delta NCA file or a delta fragment file.
--basefile <file> Specify base file path.
--outfile Specify patched file path.
Keygen options:
--outdir <dir> Specify directory path to save key files to.
Esempi
Elenca le applicazioni su una scheda SD o NAND Switch:
hactoolnet -t switchfs --sdseed <sd_seed> --listapps <sd_root_path>
Estrai un titolo da una scheda SD o NAND come file NCA:
hactoolnet -t switchfs --sdseed <sd_seed> --title <title_id> --outdir output <sd_root_path>
Estrai il RomFS da un titolo da una scheda SD o NAND:
hactoolnet -t switchfs --sdseed <sd_seed> --title <title_id> --romfsdir romfs <sd_root_path>
Chiavi esterne
Per ulteriori informazioni dettagliate sui file delle chiavi, consultare il link KEYS.md.
Le chiavi possono essere caricate da un file di testo specificando un nome file con l’argomento -k
. Il file dovrebbe seguire lo stesso formato letto da hactool: “I file delle chiavi sono file di testo contenenti una chiave per riga, nel formato “nome_chiave = CHIAVE_ESAGONALE”. Il maiuscolo/minuscolo non dovrebbe avere importanza, così come gli spazi bianchi.”
Le chiavi uniche della console possono essere caricate da un file di testo specificando un nome file con l’argomento --consolekeys
. Il formato del file è lo stesso del file principale delle chiavi.
Le chiavi dei titoli possono essere caricate da un file di testo specificando un nome file con l’argomento --titlekeys
. Il file dovrebbe contenere una chiave per riga nel formato rights_id, CHIAVE_ESAGONALE
.
Se un file di chiavi non è impostato dalla riga di comando, hactoolnet cercherà e caricherà i file di chiavi in $HOME/.switch/prod.keys
, $HOME/.switch/console.keys
e $HOME/.switch/title.keys
.
Download: hactoolnet v0.19.0 (Linux)
Download: hactoolnet v0.19.0 (netcore)
Download: hactoolnet v0.19.0 (Windows)
Download: hactoolnet v0.19.0 (nupkg)
Download: Source code hactoolnet v0.19.0
Fonte: github.com