From 81e7b1fbb6e8f096220a335499622042b97e4ea4 Mon Sep 17 00:00:00 2001 From: d0k3 Date: Sun, 26 Feb 2017 13:35:37 +0100 Subject: [PATCH] Improved unit type detection code --- source/common/platform.c | 15 --------------- source/common/platform.h | 8 -------- source/common/unittype.h | 13 +++++++++++++ source/fatfs/ramdrive.c | 4 ++-- source/fs/fsperm.c | 6 +++--- source/game/gameutil.c | 4 ++-- source/godmode.c | 8 ++++---- source/nand/nand.c | 25 ++++++++++--------------- source/nand/nand.h | 1 - source/nand/nandutil.c | 3 ++- source/virtual/vmem.c | 4 ++-- source/virtual/vnand.c | 4 ++-- 12 files changed, 40 insertions(+), 55 deletions(-) delete mode 100644 source/common/platform.c delete mode 100644 source/common/platform.h create mode 100644 source/common/unittype.h diff --git a/source/common/platform.c b/source/common/platform.c deleted file mode 100644 index b56ef46..0000000 --- a/source/common/platform.c +++ /dev/null @@ -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; - } -} diff --git a/source/common/platform.h b/source/common/platform.h deleted file mode 100644 index ce04df1..0000000 --- a/source/common/platform.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -typedef enum { - PLATFORM_3DS, - PLATFORM_N3DS, -} Platform; - -Platform GetUnitPlatform(); diff --git a/source/common/unittype.h b/source/common/unittype.h new file mode 100644 index 0000000..98dfa7f --- /dev/null +++ b/source/common/unittype.h @@ -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) diff --git a/source/fatfs/ramdrive.c b/source/fatfs/ramdrive.c index 9b84004..c9c38e1 100644 --- a/source/fatfs/ramdrive.c +++ b/source/fatfs/ramdrive.c @@ -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 { diff --git a/source/fs/fsperm.c b/source/fs/fsperm.c index 0ed30ec..5227f0a 100644 --- a/source/fs/fsperm.c +++ b/source/fs/fsperm.c @@ -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 (???) diff --git a/source/game/gameutil.c b/source/game/gameutil.c index ecb0852..020d526 100644 --- a/source/game/gameutil.c +++ b/source/game/gameutil.c @@ -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; } diff --git a/source/godmode.c b/source/godmode.c index 2815a36..3457055 100644 --- a/source/godmode.c +++ b/source/godmode.c @@ -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(); diff --git a/source/nand/nand.c b/source/nand/nand.c index f01983f..133dc75 100644 --- a/source/nand/nand.c +++ b/source/nand/nand.c @@ -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; } diff --git a/source/nand/nand.h b/source/nand/nand.h index faa08ca..3b59103 100644 --- a/source/nand/nand.h +++ b/source/nand/nand.h @@ -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); diff --git a/source/nand/nandutil.c b/source/nand/nandutil.c index 9098268..dba8c27 100644 --- a/source/nand/nandutil.c +++ b/source/nand/nandutil.c @@ -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; } diff --git a/source/virtual/vmem.c b/source/virtual/vmem.c index 5a2b6d3..e79a5ff 100644 --- a/source/virtual/vmem.c +++ b/source/virtual/vmem.c @@ -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 diff --git a/source/virtual/vnand.c b/source/virtual/vnand.c index bf8b191..592de3d 100644 --- a/source/virtual/vnand.c +++ b/source/virtual/vnand.c @@ -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));