Do the same for romfs redit => get rid of armips; update README.md
This commit is contained in:
parent
0c9365bcb7
commit
6bd7070d38
11
README.md
11
README.md
@ -13,12 +13,11 @@ Since Luma3DS v8.0, Luma3DS has its own in-game menu, triggerable by `L+Down+Sel
|
||||
|
||||
## Compiling
|
||||
|
||||
First you need to clone the repository with: `git clone https://github.com/AuroraWright/Luma3DS.git`
|
||||
To compile, you'll need [armips](https://github.com/Kingcom/armips) and a build of a recent commit of [makerom](https://github.com/profi200/Project_CTR) added to your PATH. You'll also need to install [firmtool](https://github.com/TuxSH/firmtool), its README contains installation instructions.
|
||||
You'll also need to update your [libctru](https://github.com/smealum/ctrulib) install, building from the latest commit.
|
||||
Here are [Windows](https://buildbot.orphis.net/armips/) and [Linux](https://ev1l0rd.s-ul.eu/mEIk4atQ) builds of armips (thanks to who compiled them!).
|
||||
Run `make` and everything should work!
|
||||
You can find the compiled files in the `out` folder.
|
||||
First you need to clone the repository with: `git clone https://github.com/AuroraWright/Luma3DS.git`
|
||||
To compile, you'll need a recent commit of [makerom](https://github.com/profi200/Project_CTR) added to your PATH. You'll also need to install [firmtool](https://github.com/TuxSH/firmtool), its README contains installation instructions.
|
||||
You'll also need to update your libctru and devkitARM installation to their latest releases.
|
||||
Then, run `make`.
|
||||
The produced file is called `boot.firm` and is meant to be copied to the root of your SD card, for usage with boot9strap.
|
||||
|
||||
---
|
||||
|
||||
|
@ -9,7 +9,6 @@ include $(DEVKITARM)/3ds_rules
|
||||
name := $(shell basename $(CURDIR))
|
||||
|
||||
dir_source := source
|
||||
dir_patches := patches
|
||||
dir_build := build
|
||||
dir_out := ../../$(dir_build)
|
||||
|
||||
@ -26,12 +25,6 @@ LDFLAGS := -specs=3dsx.specs $(ASFLAGS) -Wl,--section-start,.text=0x14000000
|
||||
objects = $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
|
||||
$(call rwildcard, $(dir_source), *.s *.c))
|
||||
|
||||
bundled = $(dir_build)/romfsredir.bin.o
|
||||
|
||||
define bin2o
|
||||
bin2s $< | $(AS) -o $(@)
|
||||
endef
|
||||
|
||||
.PHONY: all
|
||||
all: $(dir_out)/$(name).cxi
|
||||
|
||||
@ -47,22 +40,9 @@ $(dir_out)/$(name).cxi: $(dir_build)/$(name).elf
|
||||
$(dir_build)/$(name).elf: $(bundled) $(objects)
|
||||
$(LINK.o) $(OUTPUT_OPTION) $^ $(LIBPATHS) $(LIBS)
|
||||
|
||||
$(dir_build)/%.bin.o: $(dir_build)/%.bin
|
||||
@$(bin2o)
|
||||
|
||||
$(dir_build)/%.bin: $(dir_patches)/%.s
|
||||
@mkdir -p "$(@D)"
|
||||
@armips $<
|
||||
|
||||
$(dir_build)/memory.o $(dir_build)/strings.o: CFLAGS += -O3
|
||||
|
||||
$(dir_build)/bundled.h: $(bundled)
|
||||
@$(foreach f, $(bundled),\
|
||||
echo "extern const u8" `(echo $(basename $(notdir $(f))) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> $@;\
|
||||
echo "extern const u32" `(echo $(basename $(notdir $(f)))| sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> $@;\
|
||||
)
|
||||
|
||||
$(dir_build)/%.o: $(dir_source)/%.c $(dir_build)/bundled.h
|
||||
$(dir_build)/%.o: $(dir_source)/%.c
|
||||
@mkdir -p "$(@D)"
|
||||
$(COMPILE.c) $(OUTPUT_OPTION) $<
|
||||
|
||||
|
@ -1,117 +0,0 @@
|
||||
.arm.little
|
||||
.create "build/romfsredir.bin", 0
|
||||
|
||||
.macro addr, reg, func
|
||||
add reg, pc, #func-.-8
|
||||
.endmacro
|
||||
.macro load, reg, func
|
||||
ldr reg, [pc, #func-.-8]
|
||||
.endmacro
|
||||
|
||||
; Patch by delebile
|
||||
|
||||
.arm
|
||||
_start:
|
||||
|
||||
; Jumps here before the fsOpenFileDirectly call
|
||||
_mountArchive:
|
||||
b mountArchive
|
||||
.word 0xdead0000 ; Substituted opcode
|
||||
.word 0xdead0001 ; Branch to hooked function
|
||||
|
||||
; Jumps here before every iFileOpen call
|
||||
_fsRedir:
|
||||
b fsRedir
|
||||
.word 0xdead0002 ; Substituted opcode
|
||||
.word 0xdead0003 ; Branch to hooked function
|
||||
|
||||
; Mounts the archive and registers it as 'lf:'
|
||||
mountArchive:
|
||||
cmp r3, #3
|
||||
bne _mountArchive + 4
|
||||
stmfd sp!, {r0-r4, lr}
|
||||
sub sp, sp, #4
|
||||
load r1, archiveId
|
||||
mov r0, sp
|
||||
load r4, fsMountArchive
|
||||
blx r4
|
||||
mov r3, #0
|
||||
mov r2, #0
|
||||
ldr r1, [sp]
|
||||
addr r0, archiveName
|
||||
load r4, fsRegisterArchive
|
||||
blx r4
|
||||
add sp, sp, #4
|
||||
ldmfd sp!, {r0-r4, lr}
|
||||
b _mountArchive + 4
|
||||
|
||||
; Check the path passed to iFileOpen.
|
||||
; If it is trying to access a RomFS file, we try to
|
||||
; open it from the LayeredFS folder.
|
||||
; If the file cannot be opened, we just open
|
||||
; it from its original archive like nothing happened
|
||||
fsRedir:
|
||||
stmfd sp!, {r0-r12, lr}
|
||||
addr r3, romFsMount
|
||||
bl compare
|
||||
addne r3, pc, #updateRomFsMount-.-8
|
||||
blne compare
|
||||
bne endRedir
|
||||
sub sp, sp, #0x400
|
||||
pathRedir:
|
||||
stmfd sp!, {r0-r3}
|
||||
add r0, sp, #0x10
|
||||
load r3, customPath
|
||||
pathRedir_1:
|
||||
ldrb r2, [r3], #1
|
||||
cmp r2, #0
|
||||
strneh r2, [r0], #2
|
||||
bne pathRedir_1
|
||||
pathRedir_2:
|
||||
ldrh r2, [r1], #2
|
||||
cmp r2, #0x3A ; ':'
|
||||
bne pathRedir_2
|
||||
; Skip a slash if there are two after the mountpoint,
|
||||
; as some games mistakenly have those
|
||||
ldrh r3, [r1, #2]
|
||||
cmp r3, #0x2F ; '/'
|
||||
pathRedir_3:
|
||||
ldrh r2, [r1], #2
|
||||
strneh r2, [r0], #2
|
||||
cmp r2, #0
|
||||
bne pathRedir_3
|
||||
ldmfd sp!, {r0-r3}
|
||||
mov r1, sp
|
||||
bl _fsRedir + 4
|
||||
add sp, sp, #0x400
|
||||
cmp r0, #0
|
||||
|
||||
endRedir:
|
||||
ldmfd sp!, {r0-r12, lr}
|
||||
moveq r0, #0
|
||||
bxeq lr
|
||||
b _fsRedir + 4
|
||||
|
||||
compare:
|
||||
mov r9, r1
|
||||
add r10, r3, #4
|
||||
loop:
|
||||
ldrb r12, [r3], #1
|
||||
ldrb r11, [r9], #2
|
||||
cmp r11, r12
|
||||
bxne lr
|
||||
cmp r10, r3
|
||||
bne loop
|
||||
bx lr
|
||||
|
||||
.pool
|
||||
.align 4
|
||||
archiveName : .dcb "lf:", 0
|
||||
fsMountArchive : .word 0xdead0005
|
||||
fsRegisterArchive : .word 0xdead0006
|
||||
archiveId : .word 0xdead0007
|
||||
romFsMount : .dcb "rom:"
|
||||
updateRomFsMount : .word 0xdead0008
|
||||
customPath : .word 0xdead0004
|
||||
|
||||
.close
|
@ -3,7 +3,7 @@
|
||||
#include "memory.h"
|
||||
#include "strings.h"
|
||||
#include "fsldr.h"
|
||||
#include "../build/bundled.h"
|
||||
#include "romfsredir.h"
|
||||
|
||||
static u32 patchMemory(u8 *start, u32 size, const void *pattern, u32 patSize, s32 offset, const void *replace, u32 repSize, u32 count)
|
||||
{
|
||||
@ -204,7 +204,7 @@ static inline bool findLayeredFsPayloadOffset(u8 *code, u32 size, u32 roSize, u3
|
||||
roundedDataSize = ((dataSize + 4095) & 0xFFFFF000);
|
||||
|
||||
//First check for sufficient padding at the end of the .text segment
|
||||
if(roundedTextSize - size >= romfsredir_bin_size) *payloadOffset = size;
|
||||
if(roundedTextSize - size >= romfsRedirPatchSize) *payloadOffset = size;
|
||||
else
|
||||
{
|
||||
//If there isn't enough padding look for the "throwFatalError" function to replace
|
||||
@ -528,43 +528,18 @@ static inline bool patchLayeredFs(u64 progId, u8 *code, u32 size, u32 textSize,
|
||||
|
||||
//Setup the payload
|
||||
u8 *payload = code + payloadOffset;
|
||||
memcpy(payload, romfsredir_bin, romfsredir_bin_size);
|
||||
|
||||
//Insert symbols in the payload
|
||||
u32 *payload32 = (u32 *)payload;
|
||||
for(u32 i = 0; i < romfsredir_bin_size / 4; i++)
|
||||
{
|
||||
switch(payload32[i])
|
||||
{
|
||||
case 0xdead0000:
|
||||
payload32[i] = *(u32 *)(code + fsOpenFileDirectly);
|
||||
break;
|
||||
case 0xdead0001:
|
||||
payload32[i] = MAKE_BRANCH(payloadOffset + i * 4, fsOpenFileDirectly + 4);
|
||||
break;
|
||||
case 0xdead0002:
|
||||
payload32[i] = *(u32 *)(code + fsTryOpenFile);
|
||||
break;
|
||||
case 0xdead0003:
|
||||
payload32[i] = MAKE_BRANCH(payloadOffset + i * 4, fsTryOpenFile + 4);
|
||||
break;
|
||||
case 0xdead0004:
|
||||
payload32[i] = pathAddress;
|
||||
break;
|
||||
case 0xdead0005:
|
||||
payload32[i] = 0x100000 + fsMountArchive;
|
||||
break;
|
||||
case 0xdead0006:
|
||||
payload32[i] = 0x100000 + fsRegisterArchive;
|
||||
break;
|
||||
case 0xdead0007:
|
||||
payload32[i] = archiveId;
|
||||
break;
|
||||
case 0xdead0008:
|
||||
memcpy(payload32 + i, updateRomFsMounts[updateRomFsIndex], 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
romfsRedirPatchSubstituted1 = *(u32 *)(code + fsOpenFileDirectly);
|
||||
romfsRedirPatchHook1 = MAKE_BRANCH(payloadOffset + (u32)&romfsRedirPatchHook1 - (u32)romfsRedirPatch, fsOpenFileDirectly + 4);
|
||||
romfsRedirPatchSubstituted1 = *(u32 *)(code + fsTryOpenFile);
|
||||
romfsRedirPatchHook2 = MAKE_BRANCH(payloadOffset + (u32)&romfsRedirPatchHook2 - (u32)romfsRedirPatch, fsTryOpenFile + 4);
|
||||
romfsRedirPatchCustomPath = pathAddress;
|
||||
romfsRedirPatchFsMountArchive = 0x100000 + fsMountArchive;
|
||||
romfsRedirPatchFsRegisterArchive = 0x100000 + fsRegisterArchive;
|
||||
romfsRedirPatchArchiveId = archiveId;
|
||||
memcpy(&romfsRedirPatchRomFsMount, updateRomFsMounts[updateRomFsIndex], 4);
|
||||
|
||||
memcpy(payload, romfsRedirPatch, romfsRedirPatchSize);
|
||||
|
||||
memcpy(code + pathOffset, "lf:", 3);
|
||||
memcpy(code + pathOffset + 3, path, sizeof(path));
|
||||
|
17
sysmodules/loader/source/romfsredir.h
Normal file
17
sysmodules/loader/source/romfsredir.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <3ds/types.h>
|
||||
|
||||
extern const u8 romfsRedirPatch[];
|
||||
extern const u32 romfsRedirPatchSize;
|
||||
|
||||
extern u32 romfsRedirPatchSubstituted1, romfsRedirPatchHook1;
|
||||
extern u32 romfsRedirPatchSubstituted2, romfsRedirPatchHook2;
|
||||
|
||||
extern u32 romfsRedirPatchArchiveName;
|
||||
extern u32 romfsRedirPatchFsMountArchive;
|
||||
extern u32 romfsRedirPatchFsRegisterArchive;
|
||||
extern u32 romfsRedirPatchArchiveId;
|
||||
extern u32 romfsRedirPatchRomFsMount;
|
||||
extern u32 romfsRedirPatchUpdateRomFsMount;
|
||||
extern u32 romfsRedirPatchCustomPath;
|
130
sysmodules/loader/source/romfsredir.s
Normal file
130
sysmodules/loader/source/romfsredir.s
Normal file
@ -0,0 +1,130 @@
|
||||
@ Patch by delebile
|
||||
|
||||
.section .data.romfsRedirPatch, "aw", %progbits
|
||||
.align 4
|
||||
|
||||
.global romfsRedirPatch
|
||||
romfsRedirPatch:
|
||||
@ Jumps here before the fsOpenFileDirectly call
|
||||
_mountArchive:
|
||||
b mountArchive
|
||||
.global romfsRedirPatchSubstituted1
|
||||
romfsRedirPatchSubstituted1:
|
||||
.word 0xdead0000 @ Substituted opcode
|
||||
.global romfsRedirPatchHook1
|
||||
romfsRedirPatchHook1:
|
||||
.word 0xdead0001 @ Branch to hooked function
|
||||
|
||||
@ Jumps here before every iFileOpen call
|
||||
_fsRedir:
|
||||
b fsRedir
|
||||
.global romfsRedirPatchSubstituted2
|
||||
romfsRedirPatchSubstituted2:
|
||||
.word 0xdead0002 @ Substituted opcode
|
||||
.global romfsRedirPatchHook2
|
||||
romfsRedirPatchHook2:
|
||||
.word 0xdead0002 @ Branch to hooked function
|
||||
|
||||
@ Mounts the archive and registers it as 'lf:'
|
||||
mountArchive:
|
||||
cmp r3, #3
|
||||
bne romfsRedirPatchSubstituted1
|
||||
stmfd sp!, {r0-r4, lr}
|
||||
sub sp, sp, #4
|
||||
adr r1, romfsRedirPatchArchiveId
|
||||
mov r0, sp
|
||||
ldr r4, romfsRedirPatchFsMountArchive
|
||||
blx r4
|
||||
mov r3, #0
|
||||
mov r2, #0
|
||||
ldr r1, [sp]
|
||||
adr r0, romfsRedirPatchArchiveName
|
||||
ldr r4, romfsRedirPatchFsRegisterArchive
|
||||
blx r4
|
||||
add sp, sp, #4
|
||||
ldmfd sp!, {r0-r4, lr}
|
||||
b romfsRedirPatchSubstituted1
|
||||
|
||||
@ Check the path passed to iFileOpen.
|
||||
@ If it is trying to access a RomFS file, we try to
|
||||
@ open it from the LayeredFS folder.
|
||||
@ If the file cannot be opened, we just open
|
||||
@ it from its original archive like nothing happened
|
||||
fsRedir:
|
||||
stmfd sp!, {r0-r12, lr}
|
||||
adr r3, romfsRedirPatchRomFsMount
|
||||
bl compare
|
||||
adrne r3, romfsRedirPatchUpdateRomFsMount
|
||||
blne compare
|
||||
bne endRedir
|
||||
sub sp, sp, #0x400
|
||||
pathRedir:
|
||||
stmfd sp!, {r0-r3}
|
||||
add r0, sp, #0x10
|
||||
ldr r3, romfsRedirPatchCustomPath
|
||||
pathRedir_1:
|
||||
ldrb r2, [r3], #1
|
||||
cmp r2, #0
|
||||
strneh r2, [r0], #2
|
||||
bne pathRedir_1
|
||||
pathRedir_2:
|
||||
ldrh r2, [r1], #2
|
||||
cmp r2, #0x3A @ ':'
|
||||
bne pathRedir_2
|
||||
@ Skip a slash if there are two after the mountpoint,
|
||||
@ as some games mistakenly have those
|
||||
ldrh r3, [r1, #2]
|
||||
cmp r3, #0x2F @ '/'
|
||||
pathRedir_3:
|
||||
ldrh r2, [r1], #2
|
||||
strneh r2, [r0], #2
|
||||
cmp r2, #0
|
||||
bne pathRedir_3
|
||||
ldmfd sp!, {r0-r3}
|
||||
mov r1, sp
|
||||
bl romfsRedirPatchSubstituted2
|
||||
add sp, sp, #0x400
|
||||
cmp r0, #0
|
||||
|
||||
endRedir:
|
||||
ldmfd sp!, {r0-r12, lr}
|
||||
moveq r0, #0
|
||||
bxeq lr
|
||||
b romfsRedirPatchSubstituted2
|
||||
|
||||
compare:
|
||||
mov r9, r1
|
||||
add r10, r3, #4
|
||||
loop:
|
||||
ldrb r12, [r3], #1
|
||||
ldrb r11, [r9], #2
|
||||
cmp r11, r12
|
||||
bxne lr
|
||||
cmp r10, r3
|
||||
bne loop
|
||||
bx lr
|
||||
|
||||
.pool
|
||||
.balign 4
|
||||
|
||||
.global romfsRedirPatchArchiveName
|
||||
.global romfsRedirPatchFsMountArchive
|
||||
.global romfsRedirPatchFsRegisterArchive
|
||||
.global romfsRedirPatchArchiveId
|
||||
.global romfsRedirPatchRomFsMount
|
||||
.global romfsRedirPatchUpdateRomFsMount
|
||||
.global romfsRedirPatchCustomPath
|
||||
|
||||
romfsRedirPatchArchiveName : .ascii "lf:\0"
|
||||
romfsRedirPatchFsMountArchive : .word 0xdead0005
|
||||
romfsRedirPatchFsRegisterArchive : .word 0xdead0006
|
||||
romfsRedirPatchArchiveId : .word 0xdead0007
|
||||
romfsRedirPatchRomFsMount : .ascii "rom:"
|
||||
romfsRedirPatchUpdateRomFsMount : .word 0xdead0008
|
||||
romfsRedirPatchCustomPath : .word 0xdead0004
|
||||
|
||||
_romfsRedirPatchEnd:
|
||||
|
||||
.global romfsRedirPatchSize
|
||||
romfsRedirPatchSize:
|
||||
.word _romfsRedirPatchEnd - romfsRedirPatch
|
Reference in New Issue
Block a user