Compare commits

..

No commits in common. "master" and "v2.6.5" have entirely different histories.

16 changed files with 427 additions and 508 deletions

@ -1 +1 @@
Subproject commit 1efda4e89476d34aeb307e0acd7a8dbcd1344601
Subproject commit 9f7cea77d4db4d743e45b2e5193df76ffed0a571

@ -1 +1 @@
Subproject commit 329212a8e09d4718e304cb9d94a0e10f66d9813d
Subproject commit 5245c7b9dc232956a8578a36468f9024d8cf7001

View File

@ -4,7 +4,12 @@ ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
include $(DEVKITARM)/base_tools
include $(DEVKITARM)/3ds_rules
CC := arm-none-eabi-gcc
AS := arm-none-eabi-as
LD := arm-none-eabi-ld
OC := arm-none-eabi-objcopy
name := SafeA9LHInstaller
revision := $(shell git describe --tags --match v[0-9]* --abbrev=8 | sed 's/-[0-9]*-g/-/i')
@ -64,7 +69,7 @@ $(dir_out)/$(name)$(revision).7z: all
@7z a -mx $@ ./$(@D)/*
$(dir_build)/main.bin: $(dir_build)/main.elf
$(OBJCOPY) -S -O binary $< $@
$(OC) -S -O binary $< $@
$(dir_build)/main.elf: $(objects)
$(LINK.o) -T linker.ld $(OUTPUT_OPTION) $^
@ -79,3 +84,4 @@ $(dir_build)/%.o: $(dir_source)/%.c
$(dir_build)/%.o: $(dir_source)/%.s
@mkdir -p "$(@D)"
$(COMPILE.s) $(OUTPUT_OPTION) $<
include $(call rwildcard, $(dir_build), *.d)

View File

@ -3,7 +3,6 @@
**Usage / Features:**
*DO NOT USE THIS VERSION TO INSTALL ON NEW 3DS UNLESS YOU HAVE AN HARDMOD, CAUSES RANDOM BRICKS! UNINSTALLATION IS FINE*
For a comprehensive guide to installing A9LH and to 3DS hacking in general, refer to [Plailect's guide](https://github.com/Plailect/Guide/wiki/Get-Started).
For other details about the program, refer to the [GBATemp thread](http://gbatemp.net/threads/safea9lhinstaller.419577/).

View File

@ -1,15 +1,11 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x23F00000;
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
.data : ALIGN(4) { *(.data*); . = ALIGN(4); }
.bss : ALIGN(8) { __bss_start = .; *(.bss* COMMON); . = ALIGN(8); __bss_end = .; }
.text.start : { *(.text.start) }
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss COMMON) }
.rodata : { *(.rodata) }
. = ALIGN(4);
}

13
source/fatfs/00history.txt Normal file → Executable file
View File

@ -212,7 +212,7 @@ R0.10a (January 15, 2014)
R0.10b (May 19, 2014)
Fixed a hard error in the disk I/O layer can collapse the directory entry.
Fixed LFN entry is not deleted when delete/rename an object with lossy converted SFN. (appeared at R0.07)
Fixed LFN entry is not deleted on delete/rename an object with lossy converted SFN. (appeared at R0.07)
@ -268,7 +268,7 @@ R0.12a (July 10, 2016)
R0.12b (September 04, 2016)
Made f_rename() be able to rename objects with the same name but case.
Improved f_rename() to be able to rename objects with the same name but case.
Fixed an error in the case conversion teble of code page 866. (ff.c)
Fixed writing data is truncated at the file offset 4GiB on the exFAT volume. (appeared at R0.12)
Fixed creating a file in the root directory of exFAT volume can fail. (appeared at R0.12)
@ -277,12 +277,3 @@ R0.12b (September 04, 2016)
Fixed large file allocation/removing on the exFAT volume collapses allocation bitmap. (appeared at R0.12)
Fixed some internal errors in f_expand() and f_lseek(). (appeared at R0.12)
R0.12c (March 04, 2017)
Improved write throughput at the fragmented file on the exFAT volume.
Made memory usage for exFAT be able to be reduced as decreasing _MAX_LFN.
Fixed successive f_getfree() can return wrong count on the FAT12/16 volume. (appeared at R0.12)
Fixed configuration option _VOLUMES cannot be set 10. (appeared at R0.10c)

16
source/fatfs/00readme.txt Normal file → Executable file
View File

@ -1,21 +1,21 @@
FatFs Module Source Files R0.12c
FatFs Module Source Files R0.12a
FILES
00readme.txt This file.
00history.txt Revision history.
ff.c FatFs module.
ffconf.h Configuration file of FatFs module.
history.txt Revision history.
ffconf.h Configuration file for FatFs module.
ff.h Common include file for FatFs and application module.
ff.c FatFs module.
diskio.h Common include file for FatFs and disk I/O module.
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
integer.h Integer type definitions for FatFs.
option Optional external modules.
option Optional external functions.
Low level disk I/O module is not included in this archive because the FatFs
module is only a generic file system layer and it does not depend on any specific
storage device. You have to provide a low level disk I/O module written to
control the storage device that attached to the target system.
module is only a generic file system layer and not depend on any specific
storage device. You have to provide a low level disk I/O module that written
to control the target storage device.

665
source/fatfs/ff.c Normal file → Executable file

File diff suppressed because it is too large Load Diff

25
source/fatfs/ff.h Normal file → Executable file
View File

@ -1,8 +1,8 @@
/*----------------------------------------------------------------------------/
/ FatFs - Generic FAT file system module R0.12c /
/ FatFs - Generic FAT file system module R0.12b /
/-----------------------------------------------------------------------------/
/
/ Copyright (C) 2017, ChaN, all right reserved.
/ Copyright (C) 2016, ChaN, all right reserved.
/
/ FatFs module is an open source software. Redistribution and use of FatFs in
/ source and binary forms, with or without modification, are permitted provided
@ -19,7 +19,7 @@
#ifndef _FATFS
#define _FATFS 68300 /* Revision ID */
#define _FATFS 68020 /* Revision ID */
#ifdef __cplusplus
extern "C" {
@ -42,6 +42,13 @@ typedef struct {
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
} PARTITION;
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */
#else /* Single partition configuration */
#define LD2PD(vol) (BYTE)(vol) /* Each logical drive is bound to the same physical drive number */
#define LD2PT(vol) 0 /* Find first valid partition or in SFD */
#endif
@ -133,15 +140,14 @@ typedef struct {
FATFS* fs; /* Pointer to the owner file system object */
WORD id; /* Owner file system mount ID */
BYTE attr; /* Object attribute */
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous (no data on FAT), =3:flagmented in this session, b2:sub-directory stretched) */
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous (no data on FAT), =3:got flagmented, b2:sub-directory stretched) */
DWORD sclust; /* Object start cluster (0:no cluster or root directory) */
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
#if _FS_EXFAT
DWORD n_cont; /* Size of first fragment, clusters - 1 (valid when stat == 3) */
DWORD n_frag; /* Size of last fragment needs to be written (valid when not zero) */
DWORD n_cont; /* Size of coutiguous part, clusters - 1 (valid when stat == 3) */
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
DWORD c_ofs; /* Offset in the containing directory (valid when sclust != 0 and non-directory object) */
DWORD c_ofs; /* Offset in the containing directory (valid when sclust != 0) */
#endif
#if _FS_LOCK != 0
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
@ -157,7 +163,7 @@ typedef struct {
BYTE flag; /* File status flags */
BYTE err; /* Abort flag (error code) */
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
DWORD clust; /* Current cluster of fpter (invalid when fprt is 0) */
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
#if !_FS_READONLY
DWORD dir_sect; /* Sector number containing the directory entry */
@ -179,7 +185,7 @@ typedef struct {
_FDID obj; /* Object identifier */
DWORD dptr; /* Current read/write offset */
DWORD clust; /* Current cluster */
DWORD sect; /* Current sector (0:Read operation has terminated) */
DWORD sect; /* Current sector */
BYTE* dir; /* Pointer to the directory item in the win[] */
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
#if _USE_LFN != 0
@ -279,7 +285,6 @@ TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the fil
#define f_size(fp) ((fp)->obj.objsize)
#define f_rewind(fp) f_lseek((fp), 0)
#define f_rewinddir(dp) f_readdir((dp), 0)
#define f_rmdir(path) f_unlink(path)
#ifndef EOF
#define EOF (-1)

21
source/fatfs/ffconf.h Normal file → Executable file
View File

@ -2,7 +2,7 @@
/ FatFs - FAT file system module configuration file
/---------------------------------------------------------------------------*/
#define _FFCONF 68300 /* Revision ID */
#define _FFCONF 68020 /* Revision ID */
/*---------------------------------------------------------------------------/
/ Function Configurations
@ -73,7 +73,7 @@
/* This option specifies the OEM code page to be used on the target system.
/ Incorrect setting of the code page can cause a file open failure.
/
/ 1 - ASCII (No support of extended character. Non-LFN cfg. only)
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
/ 437 - U.S.
/ 720 - Arabic
/ 737 - Greek
@ -148,7 +148,7 @@
/---------------------------------------------------------------------------*/
#define _VOLUMES 2
/* Number of volumes (logical drives) to be used. (1-10) */
/* Number of volumes (logical drives) to be used. */
#define _STR_VOLUME_ID 0
@ -172,11 +172,11 @@
#define _MIN_SS 512
#define _MAX_SS 512
/* These options configure the range of sector size to be supported. (512, 1024,
/ 2048 or 4096) Always set both 512 for most systems, generic memory card and
/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
/ harddisk. But a larger value may be required for on-board flash memory and some
/ type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
/ to variable sector size and GET_SECTOR_SIZE command needs to be implemented to
/ the disk_ioctl() function. */
/ to variable sector size and GET_SECTOR_SIZE command must be implemented to the
/ disk_ioctl() function. */
#define _USE_TRIM 0
@ -204,7 +204,7 @@
#define _FS_TINY 0
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
/ At the tiny configuration, size of file object (FIL) is shrinked _MAX_SS bytes.
/ At the tiny configuration, size of file object (FIL) is reduced _MAX_SS bytes.
/ Instead of private sector buffer eliminated from the file object, common sector
/ buffer in the file system object (FATFS) is used for the file data transfer. */
@ -212,13 +212,13 @@
#define _FS_EXFAT 0
/* This option switches support of exFAT file system. (0:Disable or 1:Enable)
/ When enable exFAT, also LFN needs to be enabled. (_USE_LFN >= 1)
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
/ Note that enabling exFAT discards C89 compatibility. */
#define _FS_NORTC 1
#define _NORTC_MON 1
#define _NORTC_MDAY 1
#define _NORTC_YEAR 2017
#define _NORTC_YEAR 2016
/* The option _FS_NORTC switches timestamp functiton. If the system does not have
/ any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
@ -258,11 +258,10 @@
/
/ The _FS_TIMEOUT defines timeout period in unit of time tick.
/ The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
/ SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
/ included somewhere in the scope of ff.h. */
/* #include <windows.h> // O/S definitions */
/*--- End of configuration options ---*/

2
source/fatfs/integer.h Normal file → Executable file
View File

@ -30,7 +30,7 @@ typedef unsigned short WCHAR;
typedef long LONG;
typedef unsigned long DWORD;
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
/* This type MUST be 64-bit (Remove this for C89 compatibility) */
typedef unsigned long long QWORD;
#endif

0
source/fatfs/option/ccsbcs.c Normal file → Executable file
View File

View File

@ -32,6 +32,11 @@ bool mountFs(bool isSd)
return isSd ? f_mount(&fs, "0:", 1) == FR_OK : f_mount(&fs, "1:", 1) == FR_OK;
}
void unmountCtrNand(void)
{
f_mount(NULL, "1:", 1);
}
u32 fileRead(void *dest, const char *path, u32 maxSize)
{
FIL file;
@ -83,11 +88,6 @@ void fileDelete(const char *path)
f_unlink(path);
}
void fileRename(const char *oldPath, const char *newPath)
{
f_rename(oldPath, newPath);
}
u32 firmRead(void *dest)
{
const char *firmFolders[] = {"00000002", "20000002"};
@ -115,8 +115,8 @@ u32 firmRead(void *dest)
u32 tempVersion = hexAtoi(info.altname, 8);
//FIRM is newer than 11.3
if(!ISDEVUNIT && tempVersion > (ISN3DS ? 0x2D : 0x5C)) ret = 2;
//FIRM is equal or newer than 11.0
if(!ISDEVUNIT && tempVersion >= (ISN3DS ? 0x21 : 0x52)) ret = tempVersion <= (ISN3DS ? 0x28 : 0x58) ? 5 : 2;
//Found an older cxi
if(tempVersion < firmVersion) firmVersion = tempVersion;

View File

@ -25,8 +25,8 @@
#include "types.h"
bool mountFs(bool isSd);
void unmountCtrNand(void);
u32 fileRead(void *dest, const char *path, u32 maxSize);
bool fileWrite(const void *buffer, const char *path, u32 size);
void fileDelete(const char *path);
void fileRename(const char *oldPath, const char *newPath);
u32 firmRead(void *dest);

View File

@ -31,6 +31,14 @@ static const u8 sectorHashRetail[SHA_256_HASH_SIZE] = {
firm1HashRetail[SHA_256_HASH_SIZE] = {
0xD8, 0x2D, 0xB7, 0xB4, 0x38, 0x2B, 0x07, 0x88, 0x99, 0x77, 0x91, 0x0C, 0xC6, 0xEC, 0x6D, 0x87,
0x7D, 0x21, 0x79, 0x23, 0xD7, 0x60, 0xAF, 0x4E, 0x8B, 0x3A, 0xAB, 0xB2, 0x63, 0xE4, 0x21, 0xC6
},
firm104O3DSHash[SHA_256_HASH_SIZE] = {
0x5D, 0x33, 0xD9, 0xCE, 0xE3, 0x39, 0x05, 0xD5, 0xCE, 0x37, 0xFE, 0xFB, 0xB5, 0xEC, 0x73, 0x6A,
0xA0, 0x10, 0xAD, 0x87, 0xF8, 0xDC, 0x55, 0x39, 0xFD, 0xDB, 0x48, 0x69, 0xAC, 0x5F, 0x3C, 0x2B
},
firm104N3DSHash[SHA_256_HASH_SIZE] = {
0x2D, 0x6B, 0xCC, 0xCE, 0x3B, 0x81, 0xD7, 0xCA, 0x67, 0x17, 0x90, 0x33, 0x35, 0x4D, 0xFA, 0xA5,
0x70, 0xF4, 0x7A, 0x99, 0xBB, 0x60, 0x0C, 0x2F, 0x34, 0x90, 0xFF, 0x10, 0xD4, 0x4C, 0x97, 0x42
},
sectorHashDev[SHA_256_HASH_SIZE] = {
0xB2, 0x91, 0xD9, 0xB1, 0x33, 0x05, 0x79, 0x0D, 0x47, 0xC6, 0x06, 0x98, 0x4C, 0x67, 0xC3, 0x70,
@ -198,8 +206,6 @@ static inline void installer(bool isOtpless)
{
magic = 0xDEADCAFE;
fileRename("arm9loaderhax.bin", "arm9loaderhax.bak");
if(!fileWrite((void *)0x23F00000, "arm9loaderhax.bin", 0x10000))
shutdown(1, "Error: couldn't write arm9loaderhax.bin");
}
@ -267,11 +273,7 @@ static inline void installer(bool isOtpless)
drawTitle();
if(sdmmc_sdcard_init(true, false) && mountFs(true))
{
fileDelete("arm9loaderhax.bin");
fileRename("arm9loaderhax.bak", "arm9loaderhax.bin");
}
if(sdmmc_sdcard_init(true, false) && mountFs(true)) fileDelete("arm9loaderhax.bin");
else
{
posY = drawString("Couldn't remove arm9loaderhax.bin!", 10, posY + SPACING_Y, COLOR_RED);
@ -326,10 +328,32 @@ static inline void uninstaller(void)
case 1:
shutdown(1, "Error: more than one FIRM has been detected");
break;
case 5:
posY = drawString("FIRM 11.0/11.1/11.2 has been detected!", 10, posY + SPACING_Y, COLOR_RED);
posY = drawString("Press SELECT to load 10.4 FIRM from SD", 10, posY + SPACING_Y, COLOR_WHITE);
posY = drawString("Press any other button to load FIRM from CTRNAND", 10, posY, COLOR_RED);
if(waitInput() == BUTTON_SELECT)
{
u32 firm104Size = ISN3DS ? 0xF2000 : 0xEA000;
unmountCtrNand();
if(!mountFs(true)) shutdown(1, "Error: failed to mount the SD card");
if(fileRead((void *)FIRM0_OFFSET, "a9lh/firm104.bin", firm104Size) != firm104Size)
shutdown(1, "Error: firm104.bin doesn't exist or has a wrong size");
if(!verifyHash((void *)FIRM0_OFFSET, firm104Size, ISN3DS ? firm104N3DSHash : firm104O3DSHash))
shutdown(1, "Error: firm104.bin is invalid or corrupted");
firmSize = firm104Size;
break;
}
case 2:
posY = drawString("A FIRM newer than 11.3 has been detected!", 10, posY + SPACING_Y, COLOR_RED);
if(result == 2) posY = drawString("A FIRM newer than 11.2 has been detected!", 10, posY + SPACING_Y, COLOR_RED);
posY = drawString("You are about to uninstall A9LH!", 10, posY + SPACING_Y, COLOR_RED);
posY = drawString("To reinstall you'll need hardmod + NAND backup!", 10, posY, COLOR_RED);
posY = drawString("To reinstall you'll need an hardmod or a DSi dg!", 10, posY, COLOR_RED);
break;
case 3:
shutdown(1, "Error: the CTRNAND FIRM is too large");
@ -338,16 +362,23 @@ static inline void uninstaller(void)
shutdown(1, "Error: couldn't read FIRM from CTRNAND");
break;
default:
break;
}
if(firmSize != 0 || !result)
{
posY = drawString("You are about to uninstall A9LH!", 10, posY + SPACING_Y, COLOR_RED);
posY = drawString("To reinstall you'll need 9.2 or lower!", 10, posY, COLOR_RED);
break;
}
inputSequence();
//Decrypt it and get its size
if(!firmSize)
{
firmSize = decryptExeFs((Cxi *)FIRM0_OFFSET);
if(firmSize == 0) shutdown(1, "Error: couldn't decrypt the CTRNAND FIRM");
}
//writeFirm encrypts in-place, so we need two copies
memcpy((void *)FIRM1_OFFSET, (void *)FIRM0_OFFSET, firmSize);

View File

@ -91,11 +91,4 @@ start:
mov r1, #0x340
str r1, [r0]
@ Clear BSS
ldr r0, =__bss_start
mov r1, #0
ldr r2, =__bss_end
sub r2, r0
bl memset32
b main