mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-17 19:21:30 +12:00
[NCCH/NCSD] Pain
This commit is contained in:
parent
29241b41ce
commit
6b6cc7ca2f
3 changed files with 40 additions and 6 deletions
|
@ -1,4 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <array>
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
|
|
||||||
struct NCCH {
|
struct NCCH {
|
||||||
|
@ -7,13 +8,20 @@ struct NCCH {
|
||||||
bool compressExeFS = false;
|
bool compressExeFS = false;
|
||||||
bool mountRomFS = false;
|
bool mountRomFS = false;
|
||||||
bool encrypted = false;
|
bool encrypted = false;
|
||||||
|
bool fixedCryptoKey = false;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
// Header: 0x200 + 0x800 byte NCCH header + exheadr
|
// Header: 0x200 + 0x800 byte NCCH header + exheadr
|
||||||
// Returns true on success, false on failure
|
// Returns true on success, false on failure
|
||||||
bool loadFromHeader(u8* header);
|
bool loadFromHeader(u8* header);
|
||||||
|
bool hasExtendedHeader() { return exheaderSize != 0; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::array<u8, 16> primaryKey = {}; // For exheader, ExeFS header and icons
|
||||||
|
std::array<u8, 16> secondaryKey = {}; // For RomFS and some files in ExeFS
|
||||||
};
|
};
|
|
@ -3,23 +3,44 @@
|
||||||
#include "memory.hpp"
|
#include "memory.hpp"
|
||||||
|
|
||||||
bool NCCH::loadFromHeader(u8* header) {
|
bool NCCH::loadFromHeader(u8* header) {
|
||||||
const u8* exheader = &header[0x200]; // Extended NCCH header
|
|
||||||
|
|
||||||
if (header[0x100] != 'N' || header[0x101] != 'C' || header[0x102] != 'C' || header[0x103] != 'H') {
|
if (header[0x100] != 'N' || header[0x101] != 'C' || header[0x102] != 'C' || header[0x103] != 'H') {
|
||||||
printf("Invalid header on NCCH\n");
|
printf("Invalid header on NCCH\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = u64(*(u32*)&header[0x104]) * mediaUnit; // TODO: Maybe don't type pun because big endian will break
|
size = u64(*(u32*)&header[0x104]) * mediaUnit; // TODO: Maybe don't type pun because big endian will break
|
||||||
|
exheaderSize = *(u32*)&header[0x180];
|
||||||
|
|
||||||
|
const u64 programID = *(u64*)&header[0x118];
|
||||||
|
|
||||||
// Read NCCH flags
|
// Read NCCH flags
|
||||||
isNew3DS = header[0x188 + 4] == 2;
|
isNew3DS = header[0x188 + 4] == 2;
|
||||||
mountRomFS = (header[0x188 + 7] & 0x1) != 0x1;
|
fixedCryptoKey = (header[0x188 + 7] & 0x1) == 0x1;
|
||||||
|
mountRomFS = (header[0x188 + 7] & 0x2) != 0x2;
|
||||||
encrypted = (header[0x188 + 7] & 0x4) != 0x4;
|
encrypted = (header[0x188 + 7] & 0x4) != 0x4;
|
||||||
|
|
||||||
|
bool encryptedExheader = encrypted;
|
||||||
|
|
||||||
|
if (fixedCryptoKey) {
|
||||||
|
Helpers::panic("Fixed crypto keys for NCCH");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exheaderSize != 0) {
|
||||||
|
const u8* exheader = &header[0x200]; // Extended NCCH header
|
||||||
|
const u64 jumpID = *(u64*)&exheader[0x1C0 + 0x8];
|
||||||
|
|
||||||
|
// TODO: How does this even work
|
||||||
|
if (u32(programID) == u32(jumpID) && encryptedExheader) {
|
||||||
|
printf("Exheader is supposedly ecrypted but not actually encrypted\n");
|
||||||
|
encryptedExheader = false;
|
||||||
|
} else if (encryptedExheader) {
|
||||||
|
Helpers::panic("Encrypted exheader");
|
||||||
|
}
|
||||||
|
|
||||||
compressExeFS = (exheader[0xD] & 1) != 0;
|
compressExeFS = (exheader[0xD] & 1) != 0;
|
||||||
stackSize = *(u32*)&exheader[0x1C];
|
stackSize = *(u32*)&exheader[0x1C];
|
||||||
bssSize = *(u32*)&exheader[0x3C];
|
bssSize = *(u32*)&exheader[0x3C];
|
||||||
|
}
|
||||||
|
|
||||||
printf("Stack size: %08X\nBSS size: %08X\n", stackSize, bssSize);
|
printf("Stack size: %08X\nBSS size: %08X\n", stackSize, bssSize);
|
||||||
|
|
||||||
|
|
|
@ -64,5 +64,10 @@ std::optional<NCSD> Memory::loadNCSD(const std::filesystem::path& path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ncsd.partitions[0].ncch.hasExtendedHeader()) {
|
||||||
|
printf("NCSD's CXI doesn't have exheader?\n");
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
return ncsd;
|
return ncsd;
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue