This commit is contained in:
wheremyfoodat 2023-08-13 18:20:46 +03:00
parent 2dd9933621
commit ca0b5755c0

View file

@ -2,83 +2,84 @@
#include <array> #include <array>
#include <optional> #include <optional>
#include <vector> #include <vector>
#include "io_file.hpp"
#include "helpers.hpp"
#include "crypto/aes_engine.hpp" #include "crypto/aes_engine.hpp"
#include "helpers.hpp"
#include "io_file.hpp"
#include "services/region_codes.hpp" #include "services/region_codes.hpp"
struct NCCH { struct NCCH {
struct EncryptionInfo { struct EncryptionInfo {
Crypto::AESKey normalKey; Crypto::AESKey normalKey;
Crypto::AESKey initialCounter; Crypto::AESKey initialCounter;
}; };
struct FSInfo { // Info on the ExeFS/RomFS struct FSInfo { // Info on the ExeFS/RomFS
u64 offset = 0; u64 offset = 0;
u64 size = 0; u64 size = 0;
u64 hashRegionSize = 0; u64 hashRegionSize = 0;
std::optional<EncryptionInfo> encryptionInfo; std::optional<EncryptionInfo> encryptionInfo;
}; };
// Descriptions for .text, .data and .rodata sections // Descriptions for .text, .data and .rodata sections
struct CodeSetInfo { struct CodeSetInfo {
u32 address = 0; u32 address = 0;
u32 pageCount = 0; u32 pageCount = 0;
u32 size = 0; u32 size = 0;
// Extract the code set info from the relevant header data // Extract the code set info from the relevant header data
void extract(const u8* headerEntry) { void extract(const u8 *headerEntry) {
address = *(u32*)&headerEntry[0]; address = *(u32 *)&headerEntry[0];
pageCount = *(u32*)&headerEntry[4]; pageCount = *(u32 *)&headerEntry[4];
size = *(u32*)&headerEntry[8]; size = *(u32 *)&headerEntry[8];
} }
}; };
u64 partitionIndex = 0; u64 partitionIndex = 0;
u64 fileOffset = 0; u64 fileOffset = 0;
bool isNew3DS = false; bool isNew3DS = false;
bool initialized = false; bool initialized = false;
bool compressCode = false; // Shows whether the .code file in the ExeFS is compressed bool compressCode = false; // Shows whether the .code file in the ExeFS is compressed
bool mountRomFS = false; bool mountRomFS = false;
bool encrypted = false; bool encrypted = false;
bool fixedCryptoKey = false; bool fixedCryptoKey = false;
bool seedCrypto = false; bool seedCrypto = false;
u8 secondaryKeySlot = 0; u8 secondaryKeySlot = 0;
static constexpr u64 mediaUnit = 0x200; static constexpr u64 mediaUnit = 0x200;
u64 size = 0; // Size of NCCH converted to bytes u64 size = 0; // Size of NCCH converted to bytes
u32 stackSize = 0; u32 stackSize = 0;
u32 bssSize = 0; u32 bssSize = 0;
u32 exheaderSize = 0; u32 exheaderSize = 0;
FSInfo exheaderInfo; FSInfo exheaderInfo;
FSInfo exeFS; FSInfo exeFS;
FSInfo romFS; FSInfo romFS;
CodeSetInfo text, data, rodata; CodeSetInfo text, data, rodata;
// Contents of the .code file in the ExeFS // Contents of the .code file in the ExeFS
std::vector<u8> codeFile; std::vector<u8> codeFile;
// Contains of the cart's save data // Contains of the cart's save data
std::vector<u8> saveData; std::vector<u8> saveData;
// The cart region. Only the CXI's region matters to us. Necessary to get past region locking // The cart region. Only the CXI's region matters to us. Necessary to get past region locking
std::optional<Regions> region = std::nullopt; std::optional<Regions> region = std::nullopt;
// Returns true on success, false on failure // Returns true on success, false on failure
// Partition index/offset/size must have been set before this // Partition index/offset/size must have been set before this
bool loadFromHeader(Crypto::AESEngine &aesEngine, IOFile& file, const FSInfo &info); bool loadFromHeader(Crypto::AESEngine &aesEngine, IOFile &file, const FSInfo &info);
bool hasExtendedHeader() { return exheaderSize != 0; } bool hasExtendedHeader() { return exheaderSize != 0; }
bool hasExeFS() { return exeFS.size != 0; } bool hasExeFS() { return exeFS.size != 0; }
bool hasRomFS() { return romFS.size != 0; } bool hasRomFS() { return romFS.size != 0; }
bool hasCode() { return codeFile.size() != 0; } bool hasCode() { return codeFile.size() != 0; }
bool hasSaveData() { return saveData.size() != 0; } bool hasSaveData() { return saveData.size() != 0; }
// Parse SMDH for region info and such. Returns false on failure, true on success // Parse SMDH for region info and such. Returns false on failure, true on success
bool parseSMDH(const std::vector<u8>& smdh); bool parseSMDH(const std::vector<u8> &smdh);
std::pair<bool, Crypto::AESKey> getPrimaryKey(Crypto::AESEngine &aesEngine, const Crypto::AESKey &keyY); std::pair<bool, Crypto::AESKey> getPrimaryKey(Crypto::AESEngine &aesEngine, const Crypto::AESKey &keyY);
std::pair<bool, Crypto::AESKey> getSecondaryKey(Crypto::AESEngine &aesEngine, const Crypto::AESKey &keyY); std::pair<bool, Crypto::AESKey> getSecondaryKey(Crypto::AESEngine &aesEngine, const Crypto::AESKey &keyY);
std::pair<bool, std::size_t> readFromFile(IOFile& file, const FSInfo &info, u8 *dst, std::size_t offset, std::size_t size); std::pair<bool, std::size_t> readFromFile(IOFile &file, const FSInfo &info, u8 *dst, std::size_t offset, std::size_t size);
}; };