Improved unit type detection code

This commit is contained in:
d0k3 2017-02-26 13:35:37 +01:00
parent cbcdea231a
commit 81e7b1fbb6
12 changed files with 40 additions and 55 deletions

View File

@ -1,15 +0,0 @@
#include "common.h"
#include "platform.h"
#define CONFIG_PLATFORM_REG ((volatile u32*)0x10140FFC)
Platform GetUnitPlatform()
{
switch (*CONFIG_PLATFORM_REG) {
case 7:
return PLATFORM_N3DS;
case 1:
default:
return PLATFORM_3DS;
}
}

View File

@ -1,8 +0,0 @@
#pragma once
typedef enum {
PLATFORM_3DS,
PLATFORM_N3DS,
} Platform;
Platform GetUnitPlatform();

13
source/common/unittype.h Normal file
View File

@ -0,0 +1,13 @@
#pragma once
#include "common.h"
// see: https://3dbrew.org/wiki/CONFIG11_Registers
#define IS_O3DS ((*(vu32*) 0x10140FFC) != 0x7)
// see: https://www.3dbrew.org/wiki/Memory_layout#ARM9_ITCM
// see: https://www.3dbrew.org/wiki/OTP_Registers#Plaintext_OTP
#define IS_DEVKIT ((*(vu8*) (0x01FFB800+0x19)) != 0x0)
// see: https://3dbrew.org/wiki/CONFIG11_Registers
#define IS_A9LH ((*(vu32*) 0x101401C0) == 0)

View File

@ -1,5 +1,5 @@
#include "ramdrive.h"
#include "platform.h"
#include "unittype.h"
static u8* ramdrv_buffer = NULL;
static u32 ramdrv_size = 0;
@ -26,7 +26,7 @@ u64 GetRamDriveSize(void) {
}
void InitRamDrive(void) {
if (GetUnitPlatform() == PLATFORM_3DS) {
if (IS_O3DS) {
ramdrv_buffer = RAMDRV_BUFFER_O3DS;
ramdrv_size = RAMDRV_SIZE_O3DS;
} else {

View File

@ -2,7 +2,7 @@
#include "fsdrive.h"
#include "virtual.h"
#include "image.h"
#include "nand.h"
#include "unittype.h"
#include "ui.h"
#define PATH_SYS_LVL1 "S:/twln.bin", "S:/twlp.bin"
@ -41,7 +41,7 @@ bool CheckWritePermissions(const char* path) {
for (u32 i = 0; (i < sizeof(path_lvl1) / sizeof(char*)) && (lvl < 1); i++)
if (strncmp(path, path_lvl1[i], 256) == 0) lvl = 1;
}
if (!CheckA9lh()) { // changed SysNAND permission levels on non-A9LH
if (!IS_A9LH) { // changed SysNAND permission levels on non-A9LH
if ((drvtype & DRV_CTRNAND) || (lvl == 2)) lvl = 3;
}
perm = perms[lvl];
@ -172,7 +172,7 @@ bool SetWritePermissions(u32 perm, bool add_perm) {
return false;
break;
case PERM_SYS_LVL3:
if (!ShowUnlockSequence(5, "!THIS IS YOUR ONLY WARNING!\n \nYou want to enable SysNAND\nlvl3 writing permissions.\n \nThis enables you to OVERWRITE\n%s", CheckA9lh() ? "your A9LH installation and/or\nBRICK your console!" : "essential system files and/or\nBRICK your console!"))
if (!ShowUnlockSequence(5, "!THIS IS YOUR ONLY WARNING!\n \nYou want to enable SysNAND\nlvl3 writing permissions.\n \nThis enables you to OVERWRITE\n%s", IS_A9LH ? "your A9LH installation and/or\nBRICK your console!" : "essential system files and/or\nBRICK your console!"))
return false;
break;
case PERM_ALL: // maybe get rid of this (???)

View File

@ -3,7 +3,7 @@
#include "ui.h"
#include "fsperm.h"
#include "filetype.h"
#include "platform.h"
#include "unittype.h"
#include "aes.h"
#include "sha.h"
#include "vff.h"
@ -1427,7 +1427,7 @@ u32 InjectHealthAndSafety(const char* path, const char* destdrv) {
continue;
region = secinfo[0x100];
if (region >= sizeof(tidlow_hs_o3ds) / sizeof(u32)) continue;
tidlow_hs = (GetUnitPlatform() == PLATFORM_3DS) ?
tidlow_hs = (IS_O3DS) ?
tidlow_hs_o3ds[region] : tidlow_hs_n3ds[region];
break;
}

View File

@ -8,7 +8,7 @@
#include "gameutil.h"
#include "nandutil.h"
#include "filetype.h"
#include "platform.h"
#include "unittype.h"
#include "nand.h"
#include "virtual.h"
#include "vcart.h"
@ -239,7 +239,7 @@ u32 SdFormatMenu(void) {
return 1;
}
if (CheckA9lh()) {
if (IS_A9LH) {
InitSDCardFS(); // on A9LH: copy the payload from mem to SD root
FileSetData("0:/arm9loaderhax.bin", (u8*) 0x23F00000, 0x40000, 0, true);
DeinitSDCardFS();
@ -616,7 +616,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
bool buildable = (FTYPE_BUILDABLE(filetype));
bool buildable_legit = (FTYPE_BUILDABLE_L(filetype));
bool hsinjectable = (FTYPE_HSINJECTABLE(filetype));
bool restorable = (FTYPE_RESTORABLE(filetype) && CheckA9lh() && !(drvtype & DRV_SYSNAND));
bool restorable = (FTYPE_RESTORABLE(filetype) && IS_A9LH && !(drvtype & DRV_SYSNAND));
bool ebackupable = (FTYPE_EBACKUP(filetype));
bool xorpadable = (FTYPE_XORPAD(filetype));
bool launchable = ((FTYPE_PAYLOAD(filetype)) && (drvtype & DRV_FAT));
@ -1069,7 +1069,7 @@ u32 GodMode() {
InitExtFS();
// could also check for a9lh via this: ((*(vu32*) 0x101401C0) == 0)
if ((GetUnitPlatform() == PLATFORM_N3DS) && !CheckSlot0x05Crypto()) {
if ((!IS_O3DS) && !CheckSlot0x05Crypto()) {
if (!ShowPrompt(true, "Warning: slot0x05 crypto fail!\nCould not set up slot0x05keyY.\nContinue?")) {
DeinitExtFS();
DeinitSDCardFS();

View File

@ -1,14 +1,14 @@
#include "nand.h"
#include "fsdrive.h"
#include "fsutil.h"
#include "platform.h"
#include "unittype.h"
#include "keydb.h"
#include "aes.h"
#include "sha.h"
#include "sdmmc.h"
#include "image.h"
#define NAND_MIN_SECTORS ((GetUnitPlatform() == PLATFORM_N3DS) ? NAND_MIN_SECTORS_N3DS : NAND_MIN_SECTORS_O3DS)
#define NAND_MIN_SECTORS ((!IS_O3DS) ? NAND_MIN_SECTORS_N3DS : NAND_MIN_SECTORS_O3DS)
static u8 slot0x05KeyY[0x10] = { 0x00 }; // need to load this from FIRM0 / external file
static const u8 slot0x05KeyY_sha256[0x20] = { // hash for slot0x05KeyY (16 byte)
@ -67,7 +67,7 @@ u32 LoadKeyYFromP9(u8* key, const u8* keyhash, u32 offset, u32 keyslot)
u8 header[0x200];
// check arm9loaderhax
if (!CheckA9lh() || (offset < (offsetA9l + 0x0800))) return 1;
if (!IS_A9LH || (offset < (offsetA9l + 0x0800))) return 1;
// section 2 (arm9loader) header of FIRM
// this is @0x066A00 in FIRM90 & FIRM81
@ -98,7 +98,7 @@ bool InitNandCrypto(void)
{
// part #0: KeyX / KeyY for secret sector 0x96
// on a9lh this MUST be run before accessing the SHA register in any other way
if (CheckA9lh()) { // for a9lh
if (IS_A9LH) { // for a9lh
// store the current SHA256 from register
memcpy(OtpSha256, (void*) REG_SHAHASH, 32);
} else {
@ -128,7 +128,7 @@ bool InitNandCrypto(void)
// part #2: TWL KEY
// see: https://www.3dbrew.org/wiki/Memory_layout#ARM9_ITCM
if (CheckA9lh()) { // only for a9lh
if (IS_A9LH) { // only for a9lh
u32* TwlCustId = (u32*) (0x01FFB808);
u8 TwlKeyX[16] __attribute__((aligned(32)));
u8 TwlKeyY[16] __attribute__((aligned(32)));
@ -196,11 +196,6 @@ bool CheckSector0x96Crypto(void)
return (sha_cmp(slot0x11Key95_sha256, buffer, 16, SHA256_MODE) == 0);
}
bool CheckA9lh(void)
{
return ((*(vu32*) 0x101401C0) == 0);
}
void CryptNand(u8* buffer, u32 sector, u32 count, u32 keyslot)
{
u32 mode = (sector >= SECTOR_TWL + SIZE_TWL) ? AES_CNT_CTRNAND_MODE : AES_CNT_TWLNAND_MODE;
@ -368,7 +363,7 @@ u32 CheckNandHeader(u8* header)
// header type check
if (memcmp(header + 0x100, nand_magic_n3ds, sizeof(nand_magic_n3ds) == 0) == 0)
return (GetUnitPlatform() == PLATFORM_3DS) ? 0 : NAND_TYPE_N3DS;
return (IS_O3DS) ? 0 : NAND_TYPE_N3DS;
else if (memcmp(header + 0x100, nand_magic_o3ds, sizeof(nand_magic_o3ds) == 0) == 0)
return NAND_TYPE_O3DS;
@ -379,13 +374,13 @@ u32 CheckNandType(u32 nand_src)
{
if (ReadNandSectors(NAND_BUFFER, 0, 1, 0xFF, nand_src) != 0)
return 0;
if (memcmp(NAND_BUFFER + 0x100, nand_magic_n3ds, 0x60) == 0) {
return (GetUnitPlatform() == PLATFORM_3DS) ? 0 : NAND_TYPE_N3DS;
} else if (memcmp(NAND_BUFFER + 0x100, nand_magic_o3ds, 0x60) == 0) {
if (memcmp(NAND_BUFFER + 0x100, nand_magic_n3ds, sizeof(nand_magic_n3ds)) == 0) {
return (IS_O3DS) ? 0 : NAND_TYPE_N3DS;
} else if (memcmp(NAND_BUFFER + 0x100, nand_magic_o3ds, sizeof(nand_magic_o3ds)) == 0) {
u8 magic[8] = {0xE9, 0x00, 0x00, 0x43, 0x54, 0x52, 0x20, 0x20};
if (ReadNandSectors(NAND_BUFFER, 0x5CAE5, 1, 0x04, nand_src) != 0)
return 0;
return ((GetUnitPlatform() == PLATFORM_3DS) || (memcmp(magic, NAND_BUFFER, 8) == 0)) ?
return ((IS_O3DS) || (memcmp(magic, NAND_BUFFER, 8) == 0)) ?
NAND_TYPE_O3DS : NAND_TYPE_NO3DS;
}

View File

@ -37,7 +37,6 @@
bool InitNandCrypto(void);
bool CheckSlot0x05Crypto(void);
bool CheckSector0x96Crypto(void);
bool CheckA9lh(void);
void CryptNand(u8* buffer, u32 sector, u32 count, u32 keyslot);
void CryptSector0x96(u8* buffer, bool encrypt);

View File

@ -6,6 +6,7 @@
#include "image.h"
#include "fsinit.h"
#include "fsperm.h"
#include "unittype.h"
#include "sha.h"
#include "ui.h"
#include "vff.h"
@ -194,7 +195,7 @@ u32 SafeRestoreNandDump(const char* path) {
if ((ValidateNandDump(path) != 0) && // NAND dump validation
!ShowPrompt(true, "NAND dump corrupt or not from console.\nStill continue?"))
return 1;
if (!CheckA9lh()) {
if (!IS_A9LH) {
ShowPrompt(false, "Error: A9LH not detected.");
return 1;
}

View File

@ -1,5 +1,5 @@
#include "vmem.h"
#include "platform.h"
#include "unittype.h"
#define VFLAG_N3DS_ONLY (1UL<<31)
@ -29,7 +29,7 @@ bool ReadVMemDir(VirtualFile* vfile, VirtualDir* vdir) { // uses a generic vdir
memcpy(vfile, templates + vdir->index, sizeof(VirtualFile));
// process special flag
if ((vfile->flags & VFLAG_N3DS_ONLY) && (GetUnitPlatform() != PLATFORM_N3DS))
if ((vfile->flags & VFLAG_N3DS_ONLY) && (IS_O3DS))
continue; // this is not on O3DS consoles
// found if arriving here

View File

@ -2,7 +2,7 @@
#include "nand.h"
#include "agbsave.h"
#include "essentials.h"
#include "platform.h"
#include "unittype.h"
#define VFLAG_ON_O3DS NAND_TYPE_O3DS
#define VFLAG_ON_N3DS NAND_TYPE_N3DS
@ -52,7 +52,7 @@ bool ReadVNandDir(VirtualFile* vfile, VirtualDir* vdir) { // uses a generic vdir
while (++vdir->index < n_templates) {
// get NAND type (O3DS/N3DS/NO3DS), workaround for empty EmuNAND
u32 nand_type = CheckNandType(nand_src);
if (!nand_type) nand_type = (GetUnitPlatform() == PLATFORM_3DS) ? NAND_TYPE_O3DS : NAND_TYPE_N3DS;
if (!nand_type) nand_type = (IS_O3DS) ? NAND_TYPE_O3DS : NAND_TYPE_N3DS;
// copy current template to vfile
memcpy(vfile, templates + vdir->index, sizeof(VirtualFile));