Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c5369a5cad | ||
|
|
b5eba765a5 | ||
|
|
a5ddc38477 | ||
|
|
8d102256a2 | ||
|
|
2e561f7ea9 | ||
|
|
9656fe1b6f | ||
|
|
48c23f2a43 |
@@ -14,8 +14,8 @@
|
|||||||
_start:
|
_start:
|
||||||
|
|
||||||
; Jumps here before the fsOpenFileDirectly call
|
; Jumps here before the fsOpenFileDirectly call
|
||||||
_mountSd:
|
_mountArchive:
|
||||||
b mountSd
|
b mountArchive
|
||||||
.word 0xdead0000 ; Substituted opcode
|
.word 0xdead0000 ; Substituted opcode
|
||||||
.word 0xdead0001 ; Branch to hooked function
|
.word 0xdead0001 ; Branch to hooked function
|
||||||
|
|
||||||
@@ -25,42 +25,43 @@ _start:
|
|||||||
.word 0xdead0002 ; Substituted opcode
|
.word 0xdead0002 ; Substituted opcode
|
||||||
.word 0xdead0003 ; Branch to hooked function
|
.word 0xdead0003 ; Branch to hooked function
|
||||||
|
|
||||||
; Mounts SDMC and registers the archive as 'sdmc:'
|
; Mounts the archive and registers it as 'lf:'
|
||||||
mountSd:
|
mountArchive:
|
||||||
cmp r3, #3
|
cmp r3, #3
|
||||||
bne _mountSd+4
|
bne _mountArchive + 4
|
||||||
stmfd sp!, {r0-r4, lr}
|
stmfd sp!, {r0-r4, lr}
|
||||||
sub sp, sp, #4
|
sub sp, sp, #4
|
||||||
load r1, archive
|
load r1, archiveId
|
||||||
mov r0, sp
|
mov r0, sp
|
||||||
load r4, fsMountArchive
|
load r4, fsMountArchive
|
||||||
blx r4
|
blx r4
|
||||||
mov r3, #0
|
mov r3, #0
|
||||||
mov r2, #0
|
mov r2, #0
|
||||||
ldr r1, [sp]
|
ldr r1, [sp]
|
||||||
addr r0, sdmcArchiveName
|
addr r0, archiveName
|
||||||
load r4, fsRegisterArchive
|
load r4, fsRegisterArchive
|
||||||
blx r4
|
blx r4
|
||||||
add sp, sp, #4
|
add sp, sp, #4
|
||||||
ldmfd sp!, {r0-r4, lr}
|
ldmfd sp!, {r0-r4, lr}
|
||||||
b _mountSd+4
|
b _mountArchive + 4
|
||||||
|
|
||||||
; Check the path passed to iFileOpen.
|
; Check the path passed to iFileOpen.
|
||||||
; If it is trying to access a RomFS file, we try to
|
; If it is trying to access a RomFS file, we try to
|
||||||
; open it from the title folder on the sdcard.
|
; open it from the LayeredFS folder.
|
||||||
; If the file cannot be opened from the sdcard, we just open
|
; If the file cannot be opened, we just open
|
||||||
; it from its original archive like nothing happened
|
; it from its original archive like nothing happened
|
||||||
fsRedir:
|
fsRedir:
|
||||||
stmfd sp!, {r0-r12, lr}
|
stmfd sp!, {r0-r12, lr}
|
||||||
ldrb r12, [r1]
|
ldrb r12, [r1]
|
||||||
cmp r12, #0x72 ; 'r', should include "rom:" and "rom2:"
|
cmp r12, #0x72 ; 'r', should include "rom:", "rom2:" and "rex:"
|
||||||
cmpne r12, #0x70 ; 'p', should include "patch:"
|
cmpne r12, #0x70 ; 'p', should include "patch:"
|
||||||
|
cmpne r12, #0x65 ; 'e', should include "ext:"
|
||||||
bne endRedir
|
bne endRedir
|
||||||
sub sp, sp, #0x400
|
sub sp, sp, #0x400
|
||||||
pathRedir:
|
pathRedir:
|
||||||
stmfd sp!, {r0-r3}
|
stmfd sp!, {r0-r3}
|
||||||
add r0, sp, #0x10
|
add r0, sp, #0x10
|
||||||
addr r3, sdmcCustomPath
|
addr r3, customPath
|
||||||
pathRedir_1:
|
pathRedir_1:
|
||||||
ldrb r2, [r3], #1
|
ldrb r2, [r3], #1
|
||||||
strh r2, [r0], #2
|
strh r2, [r0], #2
|
||||||
@@ -78,7 +79,7 @@ _start:
|
|||||||
bne pathRedir_3
|
bne pathRedir_3
|
||||||
ldmfd sp!, {r0-r3}
|
ldmfd sp!, {r0-r3}
|
||||||
mov r1, sp
|
mov r1, sp
|
||||||
bl _fsRedir+4
|
bl _fsRedir + 4
|
||||||
add sp, sp, #0x400
|
add sp, sp, #0x400
|
||||||
cmp r0, #0
|
cmp r0, #0
|
||||||
|
|
||||||
@@ -86,16 +87,14 @@ _start:
|
|||||||
ldmfd sp!, {r0-r12, lr}
|
ldmfd sp!, {r0-r12, lr}
|
||||||
moveq r0, #0
|
moveq r0, #0
|
||||||
bxeq lr
|
bxeq lr
|
||||||
b _fsRedir+4
|
b _fsRedir + 4
|
||||||
|
|
||||||
.pool
|
.pool
|
||||||
.align 4
|
.align 4
|
||||||
sdmcArchiveName : .word 0xdead0007
|
archiveName : .dcb "lf:", 0
|
||||||
.dcb ":", 0
|
|
||||||
.align 4
|
|
||||||
fsMountArchive : .word 0xdead0005
|
fsMountArchive : .word 0xdead0005
|
||||||
fsRegisterArchive : .word 0xdead0006
|
fsRegisterArchive : .word 0xdead0006
|
||||||
archive : .word 0xdead0008
|
archiveId : .word 0xdead0007
|
||||||
sdmcCustomPath : .word 0xdead0004
|
customPath : .word 0xdead0004
|
||||||
|
|
||||||
.close
|
.close
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ static inline void patchCfgGetRegion(u8 *code, u32 size, u8 regionId, u32 CFGUHa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 findFunctionStart(u8* code, u32 pos)
|
static u32 findFunctionStart(u8 *code, u32 pos)
|
||||||
{
|
{
|
||||||
while(pos >= 4)
|
while(pos >= 4)
|
||||||
{
|
{
|
||||||
@@ -289,7 +289,7 @@ static u32 findFunctionStart(u8* code, u32 pos)
|
|||||||
return 0xFFFFFFFF;
|
return 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool findLayeredFsSymbols(u8* code, u32 size, u32 *fsMountArchive, u32 *fsRegisterArchive, u32 *fsTryOpenFile, u32 *fsOpenFileDirectly)
|
static inline bool findLayeredFsSymbols(u8 *code, u32 size, u32 *fsMountArchive, u32 *fsRegisterArchive, u32 *fsTryOpenFile, u32 *fsOpenFileDirectly)
|
||||||
{
|
{
|
||||||
for(u32 addr = 0; addr <= size - 4; addr += 4)
|
for(u32 addr = 0; addr <= size - 4; addr += 4)
|
||||||
{
|
{
|
||||||
@@ -307,12 +307,12 @@ static inline bool findLayeredFsSymbols(u8* code, u32 size, u32 *fsMountArchive,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(addr <= size - 12 && *fsRegisterArchive == 0xFFFFFFFF && *(u32 *)(code + addr) == 0xE3500008 && (*(u32 *)(code + addr + 4) & 0xFFF00FF0) == 0xE1800400 && (*(u32 *)(code + addr + 8) & 0xFFF00FF0) == 0xE1800FC0)
|
if(addr <= size - 12 && *fsRegisterArchive == 0xFFFFFFFF && *(u32 *)(code + addr) == 0xE3500008 &&
|
||||||
|
(*(u32 *)(code + addr + 4) & 0xFFF00FF0) == 0xE1800400 && (*(u32 *)(code + addr + 8) & 0xFFF00FF0) == 0xE1800FC0)
|
||||||
*fsRegisterArchive = findFunctionStart(code, addr);
|
*fsRegisterArchive = findFunctionStart(code, addr);
|
||||||
|
|
||||||
if(addr <= size - 16 && *fsTryOpenFile == 0xFFFFFFFF && *(u32 *)(code + addr + 0xC) == 0xE12FFF3C &&
|
if(addr <= size - 0x40 && *fsTryOpenFile == 0xFFFFFFFF && *(u32 *)(code + addr + 4) == 0x1AFFFFFC && *(u32 *)(code + addr) == 0xE351003A &&
|
||||||
((*(u32 *)(code + addr) == 0xE1A0100D) || (*(u32 *)(code + addr) == 0xE28D1010)) && (*(u32 *)(code + addr + 4) == 0xE590C000) &&
|
*(u32 *)(code + addr + 0x34) == 0xE590C000 && *(u32 *)(code + addr + 0x3C) == 0xE12FFF3C)
|
||||||
((*(u32 *)(code + addr + 8) == 0xE1A00004) || (*(u32 *)(code + addr + 8) == 0xE1A00005)))
|
|
||||||
*fsTryOpenFile = findFunctionStart(code, addr);
|
*fsTryOpenFile = findFunctionStart(code, addr);
|
||||||
|
|
||||||
if(*fsOpenFileDirectly == 0xFFFFFFFF && *(u32 *)(code + addr) == 0x08030204)
|
if(*fsOpenFileDirectly == 0xFFFFFFFF && *(u32 *)(code + addr) == 0x08030204)
|
||||||
@@ -324,12 +324,13 @@ static inline bool findLayeredFsSymbols(u8* code, u32 size, u32 *fsMountArchive,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool findLayeredFsPayloadOffset(u8* code, u32 size, u32 *payloadOffset)
|
static inline bool findLayeredFsPayloadOffset(u8 *code, u32 size, u32 *payloadOffset)
|
||||||
{
|
{
|
||||||
//First check for sufficient padding at the end of the .text segment
|
//First check for sufficient padding at the end of the .text segment
|
||||||
if(((size + 4095) & 0xfffff000) - size >= romfsredir_bin_size)
|
if(((size + 4095) & 0xFFFFF000) - size >= romfsredir_bin_size)
|
||||||
{
|
{
|
||||||
*payloadOffset = size;
|
*payloadOffset = size;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,6 +360,7 @@ static inline bool findLayeredFsPayloadOffset(u8* code, u32 size, u32 *payloadOf
|
|||||||
if(func != 0xFFFFFFFF)
|
if(func != 0xFFFFFFFF)
|
||||||
{
|
{
|
||||||
*payloadOffset = func;
|
*payloadOffset = func;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -508,7 +510,7 @@ exit:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool patchLayeredFs(u64 progId, u8* code, u32 size)
|
static inline bool patchLayeredFs(u64 progId, u8 *code, u32 size)
|
||||||
{
|
{
|
||||||
/* Here we look for "/luma/titles/[u64 titleID in hex, uppercase]/romfs"
|
/* Here we look for "/luma/titles/[u64 titleID in hex, uppercase]/romfs"
|
||||||
If it exists it should be a folder containing ROMFS files */
|
If it exists it should be a folder containing ROMFS files */
|
||||||
@@ -516,11 +518,11 @@ static inline bool patchLayeredFs(u64 progId, u8* code, u32 size)
|
|||||||
char path[] = "/luma/titles/0000000000000000/romfs";
|
char path[] = "/luma/titles/0000000000000000/romfs";
|
||||||
progIdToStr(path + 28, progId);
|
progIdToStr(path + 28, progId);
|
||||||
|
|
||||||
u32 archive = checkLumaDir(path);
|
u32 archiveId = checkLumaDir(path);
|
||||||
|
|
||||||
if(!archive) return true;
|
if(!archiveId) return true;
|
||||||
|
|
||||||
const char *mount = archive == ARCHIVE_SDMC ? "sdmc:" : "nand:";
|
static const char *archiveName = "lf:";
|
||||||
|
|
||||||
u32 fsMountArchive = 0xFFFFFFFF,
|
u32 fsMountArchive = 0xFFFFFFFF,
|
||||||
fsRegisterArchive = 0xFFFFFFFF,
|
fsRegisterArchive = 0xFFFFFFFF,
|
||||||
@@ -554,8 +556,8 @@ static inline bool patchLayeredFs(u64 progId, u8* code, u32 size)
|
|||||||
payload32[i] = MAKE_BRANCH(payloadOffset + i * 4, fsTryOpenFile + 4);
|
payload32[i] = MAKE_BRANCH(payloadOffset + i * 4, fsTryOpenFile + 4);
|
||||||
break;
|
break;
|
||||||
case 0xdead0004:
|
case 0xdead0004:
|
||||||
memcpy(payload32 + i, mount, 5);
|
memcpy(payload32 + i, archiveName, 3);
|
||||||
memcpy((u8 *)(payload32 + i) + 5, path, sizeof(path));
|
memcpy((u8 *)(payload32 + i) + 3, path, sizeof(path));
|
||||||
break;
|
break;
|
||||||
case 0xdead0005:
|
case 0xdead0005:
|
||||||
payload32[i] = 0x100000 + fsMountArchive;
|
payload32[i] = 0x100000 + fsMountArchive;
|
||||||
@@ -564,10 +566,7 @@ static inline bool patchLayeredFs(u64 progId, u8* code, u32 size)
|
|||||||
payload32[i] = 0x100000 + fsRegisterArchive;
|
payload32[i] = 0x100000 + fsRegisterArchive;
|
||||||
break;
|
break;
|
||||||
case 0xdead0007:
|
case 0xdead0007:
|
||||||
memcpy(payload32 + i, mount, 4);
|
payload32[i] = archiveId;
|
||||||
break;
|
|
||||||
case 0xdead0008:
|
|
||||||
payload32[i] = archive;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -240,7 +240,8 @@ boot:
|
|||||||
bool loadFromStorage = CONFIG(LOADEXTFIRMSANDMODULES);
|
bool loadFromStorage = CONFIG(LOADEXTFIRMSANDMODULES);
|
||||||
u32 firmVersion = loadFirm(&firmType, firmSource, loadFromStorage, isSafeMode);
|
u32 firmVersion = loadFirm(&firmType, firmSource, loadFromStorage, isSafeMode);
|
||||||
|
|
||||||
bool doUnitinfoPatch = CONFIG(PATCHUNITINFO), enableExceptionHandlers = CONFIG(ENABLEEXCEPTIONHANDLERS);
|
bool doUnitinfoPatch = CONFIG(PATCHUNITINFO),
|
||||||
|
enableExceptionHandlers = CONFIG(ENABLEEXCEPTIONHANDLERS);
|
||||||
u32 res;
|
u32 res;
|
||||||
switch(firmType)
|
switch(firmType)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user