Skip to content
This repository has been archived by the owner on Oct 3, 2018. It is now read-only.

Commit

Permalink
Merge upstream into master
Browse files Browse the repository at this point in the history
Upstream features added:
-Better PIN management (deleted on deactivation, actually protects settings)
-Can now run 1.x and 2.x sysnands (kernel write protection patch only)
-Speed enhancements
  • Loading branch information
rboninsegna committed Sep 1, 2016
2 parents b54d50d + c0f042b commit 55807de
Show file tree
Hide file tree
Showing 35 changed files with 501 additions and 372 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
$(call rwildcard, $(dir_source), *.s *.c)))

bundled = $(dir_build)/rebootpatch.h $(dir_build)/emunandpatch.h $(dir_build)/svcGetCFWInfopatch.h $(dir_build)/twl_k11modulespatch.h \
$(dir_build)/injector.h $(dir_build)/loader.h
$(dir_build)/injector.h $(dir_build)/loader.h

.PHONY: all
all: a9lh
Expand Down Expand Up @@ -92,7 +92,7 @@ $(dir_build)/loader.h: $(dir_loader)/Makefile
@$(MAKE) -C $(dir_loader)
@bin2c -o $@ -n loader $(@D)/loader.bin

$(dir_build)/memory.o: CFLAGS += -O3
$(dir_build)/memory.o $(dir_build)/strings.o: CFLAGS += -O3
$(dir_build)/config.o: CFLAGS += -DCONFIG_TITLE="\"$(name) $(revision) configuration\""
$(dir_build)/patches.o: CFLAGS += -DREVISION=\"$(revision)\" -DCOMMIT_HASH="0x$(commit)"

Expand Down
12 changes: 8 additions & 4 deletions injector/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)

INCLUDE := $(foreach dir,$(LIBDIRS),-I$(dir)/include)

ARCH := -mcpu=mpcore -mfloat-abi=hard -mtp=soft
CFLAGS := -Wall -Wextra -MMD -MP -marm $(ARCH) -fno-builtin -std=c11 -O2 -flto -ffast-math -mword-relocations \
ASFLAGS := -mcpu=mpcore -mfloat-abi=hard -mtp=soft
CFLAGS := -Wall -Wextra -MMD -MP -marm $(ASFLAGS) -fno-builtin -std=c11 -O2 -flto -ffast-math -mword-relocations \
-ffunction-sections -fdata-sections $(INCLUDE) -DARM11 -D_3DS
LDFLAGS := -Xlinker --defsym="__start__=0x14000000" -specs=3dsx.specs $(ARCH)
LDFLAGS := -Xlinker --defsym="__start__=0x14000000" -specs=3dsx.specs $(ASFLAGS)

objects = $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
$(call rwildcard, $(dir_source), *.c))
$(call rwildcard, $(dir_source), *.s *.c))

.PHONY: all
all: ../$(dir_build)/$(name).cxi
Expand All @@ -48,4 +48,8 @@ $(dir_build)/memory.o : CFLAGS += -O3
$(dir_build)/%.o: $(dir_source)/%.c
@mkdir -p "$(@D)"
$(COMPILE.c) $(OUTPUT_OPTION) $<

$(dir_build)/%.o: $(dir_source)/%.s
@mkdir -p "$(@D)"
$(COMPILE.s) $(OUTPUT_OPTION) $<
include $(call rwildcard, $(dir_build), *.d)
19 changes: 19 additions & 0 deletions injector/source/CFWInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include <3ds/types.h>

typedef struct __attribute__((packed))
{
char magic[4];

u8 versionMajor;
u8 versionMinor;
u8 versionBuild;
u8 flags; /* bit 0: dev branch; bit 1: is release */

u32 commitHash;

u32 config;
} CFWInfo;

int svcGetCFWInfo(CFWInfo *info);
9 changes: 9 additions & 0 deletions injector/source/CFWInfo.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.text
.arm
.align 4

.global svcGetCFWInfo
.type svcGetCFWInfo, %function
svcGetCFWInfo:
svc 0x2e
bx lr
11 changes: 3 additions & 8 deletions injector/source/patcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
#include "memory.h"
#include "patcher.h"
#include "ifile.h"
#include "CFWInfo.h"

static CFWInfo info = {0};
static CFWInfo info;

static int memcmp(const void *buf1, const void *buf2, u32 size)
{
Expand Down Expand Up @@ -85,23 +86,17 @@ static int fileOpen(IFile *file, FS_ArchiveID archiveId, const char *path, int f
return IFile_Open(file, archiveId, archivePath, filePath, flags);
}

int __attribute__((naked)) svcGetCFWInfo(CFWInfo __attribute__((unused)) *out)
{
__asm__ volatile("svc 0x2E; bx lr");
}

static void loadCFWInfo(void)
{
static bool infoLoaded = false;

if(!infoLoaded)
{
svcGetCFWInfo(&info);

IFile file;
if(BOOTCONFIG(5, 1) && R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, "/", FS_OPEN_READ))) //Init SD card if SAFE_MODE is being booted
{
IFile_Close(&file);
}

infoLoaded = true;
}
Expand Down
15 changes: 0 additions & 15 deletions injector/source/patcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,4 @@
#define OPTION_ERRDISP 12
#define OPTION_TESTMENU 13


typedef struct __attribute__((packed))
{
char magic[4];

u8 versionMajor;
u8 versionMinor;
u8 versionBuild;
u8 flags; /* bit 0: dev branch; bit 1: is release */

u32 commitHash;

u32 config;
} CFWInfo;

void patchCode(u64 progId, u8 *code, u32 size);
2 changes: 1 addition & 1 deletion loader/source/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#include "memory.h"
#include "cache.h"

extern u32 payloadSize; //defined in start.s
extern u32 payloadSize; //Defined in start.s

void main(void)
{
Expand Down
2 changes: 1 addition & 1 deletion patches/emunand.s
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ nand_sd:
sdmmc: .ascii "SDMC"
nand_offset: .ascii "NAND" ; for rednand this should be 1
ncsd_header_offset: .ascii "NCSD" ; depends on nand manufacturer + emunand type (GW/RED)
.close
.close
21 changes: 12 additions & 9 deletions patches/reboot.s
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ payload_maxsize equ 0x10000 ; Maximum size for the payload (maximum that CakeB

.create "build/reboot.bin", 0
.arm
; Interesting registers and locations to keep in mind, set before this code is ran:
; - sp + 0x3A8 - 0x70: FIRM path in exefs.
; - r7 (which is sp + 0x3A8 - 0x198): Reserved space for file handle
; - *(sp + 0x3A8 - 0x198) + 0x28: fread function.
; Interesting registers and locations to keep in mind, set just before this code is ran:
; - r1: FIRM path in exefs.
; - r7: pointer to file object
; - *r7: vtable
; - *(vtable + 0x28): fread function
; - *(r7 + 8): file handle

mov r8, r1

pxi_wait_recv:
ldr r2, =0x44846
Expand Down Expand Up @@ -47,16 +51,15 @@ payload_maxsize equ 0x10000 ; Maximum size for the payload (maximum that CakeB
cmp r4, #0
movne r3, #0x12000 ; Skip the first 0x12000 bytes.
moveq r3, payload_maxsize
ldr r6, [sp, #0x3A8-0x198]
ldr r6, [r7]
ldr r6, [r6, #0x28]
blx r6
cmp r4, #0
movne r4, #0
bne read_payload ; Go read the real payload.

; Copy the low TID (in UTF-16) of the wanted firm to the 5th byte of the payload
add r0, sp, #0x3A8 - 0x70
add r0, 0x1A
add r0, r8, 0x1A
add r1, r0, #0x10
ldr r2, =payload_addr + 4
copy_TID_low:
Expand All @@ -75,7 +78,7 @@ payload_maxsize equ 0x10000 ; Maximum size for the payload (maximum that CakeB
goto_reboot:
; Jump to reboot code
ldr r0, =(kernelcode_start - goto_reboot - 12)
add r0, pc
add r0, pc ; pc is two instructions ahead of the instruction being executed (12 = 2*4 + 4)
swi 0x7B

die:
Expand Down Expand Up @@ -122,4 +125,4 @@ dat_fname: .dcw "sdmc:/Luma3DS.dat"
bx r0

.pool
.close
.close
6 changes: 4 additions & 2 deletions patches/twl_k11modules.s
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ patch:
cmp r7, r6
bne end

ldr r7, =#0xabcdabcd ; offset of the dev launcher (will be replaced later)
ldr r7, [launcher] ; offset of the dev launcher (will be replaced later)
add r7, r9

adr r5, patchesStart
Expand Down Expand Up @@ -81,7 +81,9 @@ patch:

end:

pop {r0-r11, pc}
pop {r0-r11, pc}

launcher: .ascii "LAUN"

.align 2
.thumb
Expand Down
62 changes: 52 additions & 10 deletions source/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,50 @@
*/

#include "config.h"
#include "memory.h"
#include "fs.h"
#include "utils.h"
#include "screen.h"
#include "draw.h"
#include "buttons.h"
#include "pin.h"

void configureCFW(void)
bool readConfig(const char *configPath)
{
if(fileRead(&configData, configPath) != sizeof(cfgData) ||
memcmp(configData.magic, "CONF", 4) != 0 ||
configData.formatVersionMajor != CONFIG_VERSIONMAJOR ||
configData.formatVersionMinor != CONFIG_VERSIONMINOR)
{
configData.config = 0;
return false;
}

return true;
}

void writeConfig(const char *configPath, u32 configTemp, ConfigurationStatus needConfig)
{
/* If the configuration is different from previously, overwrite it.
Just the no-forcing flag being set is not enough */
if(needConfig == CREATE_CONFIGURATION || (configTemp & 0xFFFFFFEF) != configData.config)
{
if(needConfig == CREATE_CONFIGURATION)
{
memcpy(configData.magic, "CONF", 4);
configData.formatVersionMajor = CONFIG_VERSIONMAJOR;
configData.formatVersionMinor = CONFIG_VERSIONMINOR;
}

//Merge the new options and new boot configuration
configData.config = (configData.config & 0xFFFFFFC0) | (configTemp & 0x3F);

if(!fileWrite(&configData, configPath, sizeof(cfgData)))
error("Error writing the configuration file");
}
}

void configMenu(bool oldPinStatus)
{
initScreens();

Expand All @@ -41,16 +79,15 @@ void configureCFW(void)
"( ) Use second EmuNAND as default", //2
"( ) Enable region/language emu. and ext. .code", //3
"( ) Show current NAND/kernel in System Settings", //4
"( ) Show GBA boot screen in patched AGB_FIRM", //5
"( ) Display splash screen before payloads", //6
"( ) Use a PIN", //7
"( ) Enable experimental TwlBg patches", //8
"( ) Enable experimental TwlBg patches",//5
"( ) Show GBA boot screen in patched AGB_FIRM", //6
"( ) Display splash screen before payloads", //7
"( ) Use a PIN", //8
"( ) Region free", //9
"( ) Try to block mandatory updates", //10
"( ) SecureInfo: sigpatch + use _C if available", //11
"( ) Verbose errors (ErrDisp)", //12
"( ) Force TestMenu as home screen" }; //13

struct multiOption {
int posXs[4];
int posY;
Expand Down Expand Up @@ -190,14 +227,19 @@ void configureCFW(void)
}

//Preserve the last-used boot options (last 12 bits)
config &= 0x3F;
configData.config &= 0x3F;

//Parse and write the new configuration
for(u32 i = 0; i < multiOptionsAmount; i++)
config |= multiOptions[i].enabled << (i * 2 + 6);
configData.config |= multiOptions[i].enabled << (i * 2 + 6);
for(u32 i = 0; i < singleOptionsAmount; i++)
config |= (singleOptions[i].enabled ? 1 : 0) << (i + 16);
configData.config |= (singleOptions[i].enabled ? 1 : 0) << (i + 16);

if(CONFIG(8)) newPin(oldPinStatus);
else if(oldPinStatus) fileDelete(PIN_LOCATION);

//Wait for the pressed buttons to change
while(HID_PAD == BUTTON_START);
while(HID_PAD & PIN_BUTTONS);

chrono(2);
}
30 changes: 25 additions & 5 deletions source/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,30 @@

#include "types.h"

#define CONFIG(a) (((config >> (a + 16)) & 1) != 0)
#define MULTICONFIG(a) ((config >> (a * 2 + 6)) & 3)
#define BOOTCONFIG(a, b) ((config >> a) & b)
#define CONFIG(a) (((configData.config >> (a + 16)) & 1) != 0)
#define MULTICONFIG(a) ((configData.config >> (a * 2 + 6)) & 3)
#define BOOTCONFIG(a, b) ((configData.config >> a) & b)

extern u32 config;
#define CONFIG_VERSIONMAJOR 1
#define CONFIG_VERSIONMINOR 0

void configureCFW(void);
typedef struct __attribute__((packed))
{
char magic[4];
u16 formatVersionMajor, formatVersionMinor;

u32 config;
} cfgData;

typedef enum ConfigurationStatus
{
DONT_CONFIGURE = 0,
MODIFY_CONFIGURATION = 1,
CREATE_CONFIGURATION = 2
} ConfigurationStatus;

extern cfgData configData;

bool readConfig(const char *configPath);
void writeConfig(const char *configPath, u32 configTemp, ConfigurationStatus needConfig);
void configMenu(bool oldPinStatus);
4 changes: 2 additions & 2 deletions source/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,13 +457,13 @@ void arm9Loader(u8 *arm9Section)
}
}

void computePINHash(u8 out[32], u8 *in, u32 blockCount)
void computePinHash(u8 *out, u8 *in, u32 blockCount)
{
u8 __attribute__((aligned(4))) cid[0x10];
u8 __attribute__((aligned(4))) cipherText[0x10];
sdmmc_get_cid(1, (u32 *)cid);

aes_use_keyslot(4); // console-unique keyslot which keys are set by the Arm9 bootROM
aes_use_keyslot(4); //Console-unique keyslot whose keys are set by the ARM9 bootROM
aes(cipherText, in, blockCount, cid, AES_CBC_ENCRYPT_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);

sha(out, cipherText, 0x10, SHA_256_MODE);
Expand Down
6 changes: 2 additions & 4 deletions source/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,12 @@
#define SHA_1_HASH_SIZE (160 / 8)

extern u32 emuOffset;
extern bool isN3DS;
extern bool isDevUnit;
extern bool isN3DS, isDevUnit;
extern FirmwareSource firmSource;

void ctrNandInit(void);
u32 ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf);
void setRSAMod0DerivedKeys(void);
void decryptExeFs(u8 *inbuf);
void arm9Loader(u8 *arm9Section);

void computePINHash(u8 out[32], u8 *in, u32 blockCount);
void computePinHash(u8 *out, u8 *in, u32 blockCount);
Loading

0 comments on commit 55807de

Please sign in to comment.