diff --git a/Makefile b/Makefile
index c8f6d19fa..7244d463f 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ endif
include $(DEVKITARM)/base_tools
-name := Luma3DS
+name := Luma3DS-Kecleon
revision := $(shell git describe --tags --match v[0-9]* --abbrev=8 | sed 's/-[0-9]*-g/-/i')
commit := $(shell git rev-parse --short=8 HEAD)
@@ -96,7 +96,7 @@ $(dir_build)/%.bin: $(dir_patches)/%.s $(dir_build)
@armips $<
$(dir_build)/memory.o $(dir_build)/strings.o: CFLAGS += -O3
-$(dir_build)/config.o: CFLAGS += -DCONFIG_TITLE="\"$(name) $(revision) configuration\""
+$(dir_build)/config.o: CFLAGS += -DCONFIG_TITLE="\"$(name) $(revision)\""
$(dir_build)/patches.o: CFLAGS += -DREVISION=\"$(revision)\" -DCOMMIT_HASH="0x$(commit)"
$(dir_build)/%.o: $(dir_source)/%.c $(bundled)
diff --git a/README.md b/README.md
index 92460ad7c..0ce2a1209 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,9 @@
+# Luma3DS - Kecleon
+
+Please read the [gbatemp thread](https://gbatemp.net/threads/release-kecleon-patch-for-luma3ds.455090/).
+
+Original Readme:
+
# Luma3DS
*Noob-proof (N)3DS "Custom Firmware"*
diff --git a/injector/source/patcher.c b/injector/source/patcher.c
index 7e7e6ae82..579a3cb6b 100644
--- a/injector/source/patcher.c
+++ b/injector/source/patcher.c
@@ -499,14 +499,15 @@ void patchCode(u64 progId, u16 progVer, u8 *code, u32 size)
{
loadCFWInfo();
- if(((progId == 0x0004003000008F02LL || //USA Home Menu
- progId == 0x0004003000008202LL || //JPN Home Menu
- progId == 0x0004003000009802LL) //EUR Home Menu
- && progVer > 4) ||
- (progId == 0x000400300000A902LL //KOR Home Menu
- && progVer > 0) ||
- progId == 0x000400300000A102LL || //CHN Home Menu
- progId == 0x000400300000B102LL) //TWN Home Menu
+ if((((progId == 0x0004003000008F02LL || //USA Home Menu
+ progId == 0x0004003000008202LL || //JPN Home Menu
+ progId == 0x0004003000009802LL) //EUR Home Menu
+ && progVer > 4) ||
+ (progId == 0x000400300000A902LL //KOR Home Menu
+ && progVer > 0) ||
+ progId == 0x000400300000A102LL || //CHN Home Menu
+ progId == 0x000400300000B102LL) //TWN Home Menu
+ && !CONFIG(KECPATCH))
{
static const u8 pattern[] = {
0x0A, 0x0C, 0x00, 0x10
@@ -591,7 +592,7 @@ void patchCode(u64 progId, u16 progVer, u8 *code, u32 size)
)) goto error;
}
- else if(progId == 0x0004013000008002LL) //NS
+ else if(progId == 0x0004013000008002LL && !CONFIG(KECPATCH)) //NS
{
if(progVer > 4)
{
@@ -731,7 +732,7 @@ void patchCode(u64 progId, u16 progVer, u8 *code, u32 size)
) != 3) goto error;
}
- else if(progId == 0x0004013000002802LL && progVer > 0) //DLP
+ else if(progId == 0x0004013000002802LL && progVer > 0 && !CONFIG(KECPATCH)) //DLP
{
static const u8 pattern[] = {
0x0C, 0xAC, 0xC0, 0xD8
diff --git a/injector/source/patcher.h b/injector/source/patcher.h
index 236a1b0a4..bc76b68b0 100644
--- a/injector/source/patcher.h
+++ b/injector/source/patcher.h
@@ -20,7 +20,6 @@ enum multiOptions
DEFAULTEMU = 0,
BRIGHTNESS,
SPLASH,
- PIN,
NEWCPU,
DEVOPTIONS
};
@@ -34,7 +33,11 @@ enum singleOptions
PATCHGAMES,
PATCHVERSTRING,
SHOWGBABOOT,
- PATCHACCESS
+ PATCHACCESS,
+ KECNAND,
+ KECPATCH,
+ KECMENU,
+ KECCOMBO
};
enum flags
@@ -43,4 +46,4 @@ enum flags
ISSAFEMODE
};
-void patchCode(u64 progId, u16 progVer, u8 *code, u32 size);
\ No newline at end of file
+void patchCode(u64 progId, u16 progVer, u8 *code, u32 size);
diff --git a/source/config.c b/source/config.c
index 5a69722d4..b9013394e 100644
--- a/source/config.c
+++ b/source/config.c
@@ -27,7 +27,6 @@
#include "screen.h"
#include "draw.h"
#include "buttons.h"
-#include "pin.h"
CfgData configData;
@@ -50,7 +49,7 @@ void writeConfig(ConfigurationStatus needConfig, u32 configTemp)
{
/* If the configuration is different from previously, overwrite it.
Just the no-forcing flag being set is not enough */
- if(needConfig != CREATE_CONFIGURATION && (configTemp & 0xFFFFFF7F) == configData.config) return;
+ if(needConfig != CREATE_CONFIGURATION && (configTemp & 0xFFFFFFFFFFFFFF7F) == configData.config) return;
if(needConfig == CREATE_CONFIGURATION)
{
@@ -60,18 +59,35 @@ void writeConfig(ConfigurationStatus needConfig, u32 configTemp)
}
//Merge the new options and new boot configuration
- configData.config = (configData.config & 0xFFFFFF00) | (configTemp & 0xFF);
+ configData.config = (configData.config & 0xFFFFFFFFFFFFFF00) | (configTemp & 0xFF);
if(!fileWrite(&configData, CONFIG_FILE, sizeof(CfgData)))
error("Error writing the configuration file");
}
-void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode)
+u32 getPAD()
+{
+ initScreens();
+
+ drawString("Set key combo with ABXY, START, SELECT & D-Pad.\n"
+ "Press R while holding down combo to finish.\n"
+ "This may take a few seconds.",
+ true, 10, 10, COLOR_WHITE);
+
+ u32 pressed;
+ do {
+ pressed = waitInput(true);
+ }
+ while(!(pressed & BUTTON_R1));
+
+ return pressed & PIN_BUTTONS;
+}
+
+void configMenu(bool isSdMode)
{
const char *multiOptionsText[] = { "Default EmuNAND: 1( ) 2( ) 3( ) 4( )",
"Screen brightness: 4( ) 3( ) 2( ) 1( )",
"Splash: Off( ) Before( ) After( ) payloads",
- "PIN lock: Off( ) 4( ) 6( ) 8( ) digits",
"New 3DS CPU: Off( ) Clock( ) L2( ) Clock+L2( )",
"Dev. features: Off( ) ErrDisp( ) UNITINFO( )"
};
@@ -84,7 +100,10 @@ void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode)
"( ) Show NAND or user string in System Settings",
"( ) Show GBA boot screen in patched AGB_FIRM",
"( ) Patch SVC/service/archive/ARM9 access",
- "( ) Hide Pin when entering"
+ "( ) Kecleon: Save config.bin in CTRNAND.",
+ "( ) Kecleon: Disable Region-Free/Flashcart\n patches",
+ "( ) Kecleon: Ignore all Button Presses on boot",
+ "( ) Kecleon: Set key-combo to remove above lock"
};
const char *optionsDescription[] = { "Select the default EmuNAND.\n\n"
@@ -101,15 +120,6 @@ void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode)
"\t* 'After payloads' displays it\n"
"afterwards.",
- "Activate a PIN lock.\n\n"
- "The PIN will be asked each time\n"
- "Luma3DS boots.\n\n"
- "4, 6 or 8 digits can be selected.\n\n"
- "The ABXY buttons and the directional\n"
- "pad buttons can be used as keys.\n\n"
- "A message can also be displayed\n"
- "(refer to the wiki for instructions).",
-
"Select the New 3DS CPU mode.\n\n"
"This won't apply to\n"
"New 3DS exclusive/enhanced games.\n\n"
@@ -191,9 +201,28 @@ void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode)
"9.3 and 10.4.\n\n"
"Only change this if you know what you\n"
"are doing!",
-
- "Hides the input when entering pin\n"
- "to unlock the 3DS"
+
+ "Save configuration file in CTRNAND\n"
+ "at '/rw/luma/config.bin'.",
+
+ "This disables patches that can give\n"
+ "away this 3DS is running CFW,\n"
+ "such as out-of-region cartridges,\n"
+ "out-of-region download play,\n"
+ "or banned flashcarts.",
+
+ "This makes Luma3DS ignore all Button\n"
+ "Presses on boot, hiding chainloading\n"
+ "and boot menus that give away this\n"
+ "3DS is running CFW.\n\n"
+ "Warning: config.bin must be deleted\n"
+ "to re-enable configuration menus\n"
+ "if Key Combo is not set.\n",
+
+ "Set a Key Combo to make this\n"
+ "configuration menu appear on\n"
+ "startup, when the above option is\n"
+ "set."
};
struct multiOption {
@@ -205,7 +234,6 @@ void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode)
{ .posXs = {19, 24, 29, 34}, .visible = isSdMode },
{ .posXs = {21, 26, 31, 36}, .visible = true },
{ .posXs = {12, 22, 31, 0}, .visible = true },
- { .posXs = {14, 19, 24, 29}, .visible = true },
{ .posXs = {17, 26, 32, 44}, .visible = ISN3DS },
{ .posXs = {19, 30, 42, 0}, .visible = true }
};
@@ -223,6 +251,9 @@ void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode)
{ .visible = true },
{ .visible = true },
{ .visible = true },
+ { .visible = true },
+ { .visible = true },
+ { .visible = true },
{ .visible = true }
};
@@ -392,11 +423,7 @@ void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode)
for(u32 i = 0; i < singleOptionsAmount; i++)
configData.config |= (singleOptions[i].enabled ? 1 : 0) << (i + 20);
- u32 newPinMode = MULTICONFIG(PIN);
-
- if(newPinMode != 0) newPin(oldPinStatus && newPinMode == oldPinMode, newPinMode);
- else if(oldPinStatus) fileDelete(PIN_FILE);
+ if (CONFIG(KECCOMBO)) configData.combo = getPAD();
- while(HID_PAD & PIN_BUTTONS);
wait(2000ULL);
}
diff --git a/source/config.h b/source/config.h
index f86f571c4..6c8f4d1b6 100644
--- a/source/config.h
+++ b/source/config.h
@@ -29,7 +29,8 @@
#define BOOTCONFIG(a, b) ((configData.config >> a) & b)
#define CONFIG_FILE "config.bin"
-#define CONFIG_VERSIONMAJOR 1
+/* Corresponds to downstream 1.8 */
+#define CONFIG_VERSIONMAJOR 24801
#define CONFIG_VERSIONMINOR 8
#define BOOTCFG_NAND BOOTCONFIG(0, 7)
@@ -42,7 +43,6 @@ enum multiOptions
DEFAULTEMU = 0,
BRIGHTNESS,
SPLASH,
- PIN,
NEWCPU,
DEVOPTIONS
};
@@ -57,7 +57,10 @@ enum singleOptions
PATCHVERSTRING,
SHOWGBABOOT,
PATCHACCESS,
- HIDEPIN
+ KECNAND,
+ KECPATCH,
+ KECMENU,
+ KECCOMBO
};
typedef enum ConfigurationStatus
@@ -69,4 +72,4 @@ typedef enum ConfigurationStatus
bool readConfig(void);
void writeConfig(ConfigurationStatus needConfig, u32 configTemp);
-void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode);
+void configMenu(bool isSdMode);
diff --git a/source/fs.c b/source/fs.c
index 831c0309c..f9ff70f65 100644
--- a/source/fs.c
+++ b/source/fs.c
@@ -35,6 +35,26 @@
static FATFS sdFs,
nandFs;
+void rmEmptyDir()
+{
+ DIR dir;
+ FILINFO fno;
+
+ if (f_chdir("/") != FR_OK) error("Filesystem Error!");
+ if (f_opendir(&dir, "luma") != FR_OK)
+ error("Directory /luma does not exist");
+ f_readdir(&dir, &fno);
+ f_closedir(&dir);
+
+ if (fno.fname[0] == 0) {
+ f_unlink("luma");
+ } else {
+ if (f_opendir(&dir, "luma") != FR_OK)
+ error("Directory /luma does not exist");
+ }
+
+}
+
static bool switchToMainDir(bool isSd)
{
const char *mainDir = isSd ? "/luma" : "/rw/luma";
@@ -51,12 +71,18 @@ static bool switchToMainDir(bool isSd)
}
}
-bool mountFs(bool isSd, bool switchToCtrNand)
+bool mountFs(bool isSdMode, bool switchToCtrNand)
{
- return isSd ? f_mount(&sdFs, "0:", 1) == FR_OK && switchToMainDir(true) :
+ return isSdMode ? f_mount(&sdFs, "0:", 1) == FR_OK && switchToMainDir(true) :
f_mount(&nandFs, "1:", 1) == FR_OK && (!switchToCtrNand || (f_chdrive("1:") == FR_OK && switchToMainDir(false)));
}
+bool changeDrive(bool switchToSd)
+{
+ return switchToSd ? f_chdrive("0:") == FR_OK && switchToMainDir(true) :
+ f_chdrive("1:") == FR_OK && switchToMainDir(false);
+}
+
u32 fileRead(void *dest, const char *path, u32 maxSize)
{
FIL file;
@@ -114,8 +140,22 @@ void fileDelete(const char *path)
f_unlink(path);
}
-void loadPayload(u32 pressed, const char *payloadPath)
+void loadPayload(u32 pressed, const char *payloadPath, bool isSdMode)
{
+ DIR dir;
+ FILINFO info;
+ char path[22] = "payloads";
+ FRESULT result;
+
+ /* Test SD for payloads. On fail, use NAND. */
+ if (isSdMode) {
+ changeDrive(true);
+ result = f_findfirst(&dir, &info, path, "*.bin");
+ if (result != FR_OK) {
+ changeDrive(false);
+ }
+ }
+
u32 *loaderAddress = (u32 *)0x24FFFE00;
u8 *payloadAddress = (u8 *)0x24F00000;
u32 payloadSize = 0,
@@ -137,11 +177,6 @@ void loadPayload(u32 pressed, const char *payloadPath)
else if(pressed & BUTTON_A) pattern = PATTERN("a");
else pattern = PATTERN("select");
- DIR dir;
- FILINFO info;
- FRESULT result;
- char path[22] = "payloads";
-
result = f_findfirst(&dir, &info, path, pattern);
if(result != FR_OK) return;
@@ -170,14 +205,25 @@ void loadPayload(u32 pressed, const char *payloadPath)
((void (*)())loaderAddress)();
}
-void payloadMenu(void)
+void payloadMenu(bool isSdMode)
{
DIR dir;
+ FILINFO info;
char path[62] = "payloads";
+ FRESULT result;
+
+ /* Test SD for payloads. On fail, use NAND. */
+ if (isSdMode) {
+ changeDrive(true);
+ result = f_findfirst(&dir, &info, path, "*.bin");
+ if (result != FR_OK) {
+ changeDrive(false);
+ }
+ }
+
if(f_opendir(&dir, path) != FR_OK) return;
- FILINFO info;
u32 payloadNum = 0;
char payloadList[20][49];
@@ -255,7 +301,7 @@ void payloadMenu(void)
concatenateStrings(path, "/");
concatenateStrings(path, payloadList[selectedPayload]);
concatenateStrings(path, ".bin");
- loadPayload(0, path);
+ loadPayload(0, path, isSdMode);
error("The payload is too large or corrupted.");
}
@@ -328,4 +374,4 @@ void findDumpFile(const char *path, char *fileName)
}
if(result == FR_OK) f_closedir(&dir);
-}
\ No newline at end of file
+}
diff --git a/source/fs.h b/source/fs.h
index 14f26c0c4..c0cfacd3f 100644
--- a/source/fs.h
+++ b/source/fs.h
@@ -26,12 +26,14 @@
#define PATTERN(a) a "_*.bin"
-bool mountFs(bool isSd, bool switchToCtrNand);
+void rmEmptyDir();
+bool mountFs(bool isSdMode, bool switchToCtrNand);
+bool changeDrive(bool switchToSd);
u32 fileRead(void *dest, const char *path, u32 maxSize);
u32 getFileSize(const char *path);
bool fileWrite(const void *buffer, const char *path, u32 size);
void fileDelete(const char *path);
-void loadPayload(u32 pressed, const char *payloadPath);
-void payloadMenu(void);
+void loadPayload(u32 pressed, const char *payloadPath, bool isSdMode);
+void payloadMenu(bool isSdMode);
u32 firmRead(void *dest, u32 firmType);
-void findDumpFile(const char *path, char *fileName);
\ No newline at end of file
+void findDumpFile(const char *path, char *fileName);
diff --git a/source/main.c b/source/main.c
index 17b6d3cf9..de61b8d9b 100644
--- a/source/main.c
+++ b/source/main.c
@@ -29,7 +29,6 @@
#include "draw.h"
#include "strings.h"
#include "buttons.h"
-#include "pin.h"
#include "crypto.h"
extern CfgData configData;
@@ -45,19 +44,25 @@ void main(void)
FirmwareSource nandType;
ConfigurationStatus needConfig;
- //Mount SD or CTRNAND
- bool isSdMode;
- if(mountFs(true, false)) isSdMode = true;
- else
- {
+ // Attempt to mount SD card.
+ bool isSdMode = mountFs(true, false);
+ if (isSdMode) {
+ // Attempt to load configuration.
+ if (readConfig()) {
+ needConfig = MODIFY_CONFIGURATION;
+ } else {
+ needConfig = CREATE_CONFIGURATION;
+ rmEmptyDir();
+ }
+ }
+ // If either of those fail, attempt to mount CTRNAND.
+ if (!isSdMode || needConfig == CREATE_CONFIGURATION) {
firmSource = FIRMWARE_SYSNAND;
if(!mountFs(false, true)) error("Failed to mount SD and CTRNAND.");
- isSdMode = false;
+ // Attempt to load configuration file.
+ needConfig = readConfig() ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION;
}
- //Attempt to read the configuration file
- needConfig = readConfig() ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION;
-
//Determine if this is a firmlaunch boot
if(ISFIRMLAUNCH)
{
@@ -92,8 +97,11 @@ void main(void)
firmType = NATIVE_FIRM;
isA9lhInstalled = ISA9LH;
- //Get pressed buttons
- u32 pressed = HID_PAD;
+ //Get pressed buttons only if chainloading/boot menus aren't disabled
+ u32 pressed = CONFIG(KECMENU) ? 0 : HID_PAD;
+
+ //Should load menu via key combo
+ bool keyComboPressed = CONFIG(KECCOMBO) && configData.combo == HID_PAD;
//Save old options and begin saving the new boot configuration
configTemp = (configData.config & 0xFFFFFF00) | ((u32)ISA9LH << 6);
@@ -127,16 +135,15 @@ void main(void)
}
}
- u32 pinMode = MULTICONFIG(PIN);
- bool hidePin = CONFIG(HIDEPIN);
- bool pinExists = pinMode != 0 && verifyPin(pinMode, hidePin);
-
//If no configuration file exists or SELECT is held, load configuration menu
- bool shouldLoadConfigMenu = needConfig == CREATE_CONFIGURATION || ((pressed & (BUTTON_SELECT | BUTTON_L1)) == BUTTON_SELECT);
+ bool shouldLoadConfigMenu =
+ needConfig == CREATE_CONFIGURATION ||
+ ((pressed & (BUTTON_SELECT | BUTTON_L1)) == BUTTON_SELECT) ||
+ keyComboPressed;
if(shouldLoadConfigMenu)
{
- configMenu(isSdMode, pinExists, pinMode);
+ configMenu(isSdMode);
//Update pressed buttons
pressed = HID_PAD;
@@ -149,13 +156,6 @@ void main(void)
isSafeMode = true;
- //If the PIN has been verified, wait to make it easier to press the SAFE_MODE combo
- if(pinExists && !shouldLoadConfigMenu)
- {
- while(HID_PAD & PIN_BUTTONS);
- wait(2000ULL);
- }
-
goto boot;
}
@@ -165,11 +165,11 @@ void main(void)
if((pressed & (BUTTON_START | BUTTON_L1)) == BUTTON_START)
{
- payloadMenu();
+ payloadMenu(isSdMode);
pressed = HID_PAD;
}
else if(((pressed & SINGLE_PAYLOAD_BUTTONS) && !(pressed & (BUTTON_L1 | BUTTON_R1 | BUTTON_A))) ||
- ((pressed & L_PAYLOAD_BUTTONS) && (pressed & BUTTON_L1))) loadPayload(pressed, NULL);
+ ((pressed & L_PAYLOAD_BUTTONS) && (pressed & BUTTON_L1))) loadPayload(pressed, NULL, isSdMode);
if(splashMode == 2) loadSplash();
@@ -238,6 +238,12 @@ void main(void)
if(!ISFIRMLAUNCH)
{
configTemp |= (u32)nandType | ((u32)firmSource << 3);
+
+ /* Change to SD card if writing config to SD card. */
+ if (isSdMode && !CONFIG(KECNAND)) {
+ if (!changeDrive(true)) error("SD card unavailible.");
+ }
+
writeConfig(needConfig, configTemp);
}
diff --git a/source/patches.c b/source/patches.c
index def865d23..3a92498f2 100644
--- a/source/patches.c
+++ b/source/patches.c
@@ -511,6 +511,8 @@ u32 patchUnitInfoValueSet(u8 *pos, u32 size)
u32 patchLgySignatureChecks(u8 *pos, u32 size)
{
+ if (CONFIG(KECPATCH)) return 0;
+
const u8 pattern[] = {0x47, 0xC1, 0x17, 0x49};
u8 *temp = memsearch(pos, pattern, size, sizeof(pattern));
@@ -527,6 +529,8 @@ u32 patchLgySignatureChecks(u8 *pos, u32 size)
u32 patchTwlInvalidSignatureChecks(u8 *pos, u32 size)
{
+ if (CONFIG(KECPATCH)) return 0;
+
const u8 pattern[] = {0x20, 0xF6, 0xE7, 0x7F};
u8 *temp = memsearch(pos, pattern, size, sizeof(pattern));
@@ -541,6 +545,8 @@ u32 patchTwlInvalidSignatureChecks(u8 *pos, u32 size)
u32 patchTwlNintendoLogoChecks(u8 *pos, u32 size)
{
+ if (CONFIG(KECPATCH)) return 0;
+
const u8 pattern[] = {0xC0, 0x30, 0x06, 0xF0};
u16 *off = (u16 *)memsearch(pos, pattern, size, sizeof(pattern));
@@ -555,6 +561,8 @@ u32 patchTwlNintendoLogoChecks(u8 *pos, u32 size)
u32 patchTwlWhitelistChecks(u8 *pos, u32 size)
{
+ if (CONFIG(KECPATCH)) return 0;
+
const u8 pattern[] = {0x22, 0x00, 0x20, 0x30};
u16 *off = (u16 *)memsearch(pos, pattern, size, sizeof(pattern));
@@ -569,6 +577,8 @@ u32 patchTwlWhitelistChecks(u8 *pos, u32 size)
u32 patchTwlFlashcartChecks(u8 *pos, u32 size, u32 firmVersion)
{
+ if (CONFIG(KECPATCH)) return 0;
+
const u8 pattern[] = {0x25, 0x20, 0x00, 0x0E};
u8 *temp = memsearch(pos, pattern, size, sizeof(pattern));
@@ -589,6 +599,8 @@ u32 patchTwlFlashcartChecks(u8 *pos, u32 size, u32 firmVersion)
u32 patchOldTwlFlashcartChecks(u8 *pos, u32 size)
{
+ if (CONFIG(KECPATCH)) return 0;
+
const u8 pattern[] = {0x06, 0xF0, 0xA0, 0xFD};
u16 *off = (u16 *)memsearch(pos, pattern, size, sizeof(pattern));
@@ -603,6 +615,8 @@ u32 patchOldTwlFlashcartChecks(u8 *pos, u32 size)
u32 patchTwlShaHashChecks(u8 *pos, u32 size)
{
+ if (CONFIG(KECPATCH)) return 0;
+
const u8 pattern[] = {0x10, 0xB5, 0x14, 0x22};
u16 *off = (u16 *)memsearch(pos, pattern, size, sizeof(pattern));
diff --git a/source/pin.c b/source/pin.c
deleted file mode 100644
index 935343cf4..000000000
--- a/source/pin.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
-* This file is part of Luma3DS
-* Copyright (C) 2016 Aurora Wright, TuxSH
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see .
-*
-* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
-* reasonable legal notices or author attributions in that material or in the Appropriate Legal
-* Notices displayed by works containing it.
-*/
-
-/*
-* Code originally by reworks
-*/
-
-#include "draw.h"
-#include "config.h"
-#include "screen.h"
-#include "utils.h"
-#include "memory.h"
-#include "buttons.h"
-#include "fs.h"
-#include "pin.h"
-#include "crypto.h"
-
-static char pinKeyToLetter(u32 pressed)
-{
- const char keys[] = "AB--RLUD--XY";
-
- u32 i;
- for(i = 31; pressed > 1; i--) pressed /= 2;
-
- return keys[31 - i];
-}
-
-void newPin(bool allowSkipping, u32 pinMode)
-{
- clearScreens(false);
-
- u8 length = 4 + 2 * (pinMode - 1);
-
- drawString("Enter a new PIN using ABXY and the DPad", true, 10, 10, COLOR_TITLE);
- drawString(allowSkipping ? "Press START to skip, SELECT to reset" : "Press SELECT to reset", true, 10, 10 + SPACING_Y, COLOR_TITLE);
-
- drawString("PIN ( digits): ", true, 10, 10 + 3 * SPACING_Y, COLOR_WHITE);
- drawCharacter('0' + length, true, 10 + 5 * SPACING_X, 10 + 3 * SPACING_Y, COLOR_WHITE);
-
- //Pad to AES block length with zeroes
- __attribute__((aligned(4))) u8 enteredPassword[AES_BLOCK_SIZE] = {0};
-
- bool reset = false;
- u8 cnt = 0;
-
- while(cnt < length)
- {
- if(reset)
- {
- for(u32 i = 0; i < cnt; i++)
- drawCharacter((char)enteredPassword[i], true, 10 + (16 + 2 * i) * SPACING_X, 10 + 3 * SPACING_Y, COLOR_BLACK);
-
- cnt = 0;
- reset = false;
- }
-
- u32 pressed;
- do
- {
- pressed = waitInput(false);
- }
- while(!(pressed & PIN_BUTTONS));
-
- pressed &= PIN_BUTTONS;
- if(!allowSkipping) pressed &= ~BUTTON_START;
-
- if(pressed & BUTTON_START) return;
-
- if(pressed & BUTTON_SELECT)
- {
- reset = true;
- continue;
- }
-
- if(!pressed) continue;
-
- //Add character to password
- enteredPassword[cnt] = (u8)pinKeyToLetter(pressed);
-
- //Visualize character on screen
- drawCharacter(enteredPassword[cnt], true, 10 + (16 + 2 * cnt) * SPACING_X, 10 + 3 * SPACING_Y, COLOR_WHITE);
-
- cnt++;
- }
-
- PinData pin;
-
- memcpy(pin.magic, "PINF", 4);
- pin.formatVersionMajor = PIN_VERSIONMAJOR;
- pin.formatVersionMinor = PIN_VERSIONMINOR;
-
- __attribute__((aligned(4))) u8 tmp[SHA_256_HASH_SIZE],
- lengthBlock[AES_BLOCK_SIZE] = {0};
- lengthBlock[0] = length;
-
- computePinHash(tmp, lengthBlock);
- memcpy(pin.lengthHash, tmp, sizeof(tmp));
-
- computePinHash(tmp, enteredPassword);
- memcpy(pin.hash, tmp, sizeof(tmp));
-
- if(!fileWrite(&pin, PIN_FILE, sizeof(PinData)))
- error("Error writing the PIN file");
-}
-
-bool verifyPin(u32 pinMode, bool hidePin)
-{
- PinData pin;
-
- if(fileRead(&pin, PIN_FILE, sizeof(PinData)) != sizeof(PinData) ||
- memcmp(pin.magic, "PINF", 4) != 0 ||
- pin.formatVersionMajor != PIN_VERSIONMAJOR ||
- pin.formatVersionMinor != PIN_VERSIONMINOR)
- return false;
-
- __attribute__((aligned(4))) u8 tmp[SHA_256_HASH_SIZE],
- lengthBlock[AES_BLOCK_SIZE] = {0};
- lengthBlock[0] = 4 + 2 * (pinMode - 1);
-
- computePinHash(tmp, lengthBlock);
-
- //Test vector verification (check if SD card has been used on another console or PIN length changed)
- if(memcmp(pin.lengthHash, tmp, sizeof(tmp)) != 0) return false;
-
- initScreens();
-
- drawString("Enter the PIN using ABXY and the DPad to proceed", true, 10, 10, COLOR_TITLE);
- drawString("Press START to shutdown, SELECT to clear", true, 10, 10 + SPACING_Y, COLOR_TITLE);
-
- drawString("PIN ( digits): ", true, 10, 10 + 3 * SPACING_Y, COLOR_WHITE);
- drawCharacter('0' + lengthBlock[0], true, 10 + 5 * SPACING_X, 10 + 3 * SPACING_Y, COLOR_WHITE);
-
- const char *messageFile = "pinmessage.txt";
- char message[801];
-
- u32 messageSize = fileRead(message, messageFile, sizeof(message) - 1);
-
- if(messageSize != 0)
- {
- message[messageSize] = 0;
- drawString(message, false, 10, 10, COLOR_WHITE);
- }
-
- //Pad to AES block length with zeroes
- __attribute__((aligned(4))) u8 enteredPassword[AES_BLOCK_SIZE] = {0};
-
- bool unlock = false,
- reset = false;
- u8 cnt = 0;
-
- while(!unlock)
- {
- if(reset)
- {
- for(u32 i = 0; i < cnt; i++)
- drawCharacter((char)enteredPassword[i], true, 10 + (16 + 2 * i) * SPACING_X, 10 + 3 * SPACING_Y, COLOR_BLACK);
-
- cnt = 0;
- reset = false;
- }
-
- u32 pressed;
- do
- {
- pressed = waitInput(false);
- }
- while(!(pressed & PIN_BUTTONS));
-
- if(pressed & BUTTON_START) mcuPowerOff();
-
- pressed &= PIN_BUTTONS;
-
- if(pressed & BUTTON_SELECT)
- {
- reset = true;
- continue;
- }
-
- if(!pressed) continue;
-
- //Add character to password
- enteredPassword[cnt] = (u8)pinKeyToLetter(pressed);
- //Visualize character on screen
- char display = hidePin ? '*' : (char)enteredPassword[cnt];
- drawCharacter(display, true, 10 + (16 + 2 * cnt) * SPACING_X, 10 + 3 * SPACING_Y, COLOR_WHITE);
-
- if(++cnt < lengthBlock[0]) continue;
-
- computePinHash(tmp, enteredPassword);
- unlock = memcmp(pin.hash, tmp, sizeof(tmp)) == 0;
-
- if(!unlock)
- {
- reset = true;
-
- drawString("Wrong PIN, try again", true, 10, 10 + 5 * SPACING_Y, COLOR_RED);
- }
- }
-
- return true;
-}
\ No newline at end of file
diff --git a/source/pin.h b/source/pin.h
deleted file mode 100644
index a6c18fcaf..000000000
--- a/source/pin.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-* This file is part of Luma3DS
-* Copyright (C) 2016 Aurora Wright, TuxSH
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see .
-*
-* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
-* reasonable legal notices or author attributions in that material or in the Appropriate Legal
-* Notices displayed by works containing it.
-*/
-
-/*
-* Code originally by reworks
-*/
-
-#pragma once
-
-#include "types.h"
-
-#define PIN_FILE "pin.bin"
-#define PIN_VERSIONMAJOR 1
-#define PIN_VERSIONMINOR 3
-
-void newPin(bool allowSkipping, u32 pinMode);
-bool verifyPin(u32 pinMode, bool hidePin);
\ No newline at end of file
diff --git a/source/types.h b/source/types.h
index 8b624d44a..7967b381f 100644
--- a/source/types.h
+++ b/source/types.h
@@ -59,7 +59,8 @@ typedef struct __attribute__((packed))
char magic[4];
u16 formatVersionMajor, formatVersionMinor;
- u32 config;
+ u64 config;
+ u32 combo;
} CfgData;
typedef struct __attribute__((packed))