Do the same for romfs redit => get rid of armips; update README.md

This commit is contained in:
TuxSH 2018-05-23 01:50:25 +02:00
parent 0c9365bcb7
commit 6bd7070d38
6 changed files with 166 additions and 182 deletions

View File

@ -13,12 +13,11 @@ Since Luma3DS v8.0, Luma3DS has its own in-game menu, triggerable by `L+Down+Sel
## Compiling ## Compiling
First you need to clone the repository with: `git clone https://github.com/AuroraWright/Luma3DS.git` 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. 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](https://github.com/smealum/ctrulib) install, building from the latest commit. You'll also need to update your libctru and devkitARM installation to their latest releases.
Here are [Windows](https://buildbot.orphis.net/armips/) and [Linux](https://ev1l0rd.s-ul.eu/mEIk4atQ) builds of armips (thanks to who compiled them!). Then, run `make`.
Run `make` and everything should work! The produced file is called `boot.firm` and is meant to be copied to the root of your SD card, for usage with boot9strap.
You can find the compiled files in the `out` folder.
--- ---

View File

@ -9,7 +9,6 @@ include $(DEVKITARM)/3ds_rules
name := $(shell basename $(CURDIR)) name := $(shell basename $(CURDIR))
dir_source := source dir_source := source
dir_patches := patches
dir_build := build dir_build := build
dir_out := ../../$(dir_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, \ objects = $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
$(call rwildcard, $(dir_source), *.s *.c)) $(call rwildcard, $(dir_source), *.s *.c))
bundled = $(dir_build)/romfsredir.bin.o
define bin2o
bin2s $< | $(AS) -o $(@)
endef
.PHONY: all .PHONY: all
all: $(dir_out)/$(name).cxi all: $(dir_out)/$(name).cxi
@ -47,22 +40,9 @@ $(dir_out)/$(name).cxi: $(dir_build)/$(name).elf
$(dir_build)/$(name).elf: $(bundled) $(objects) $(dir_build)/$(name).elf: $(bundled) $(objects)
$(LINK.o) $(OUTPUT_OPTION) $^ $(LIBPATHS) $(LIBS) $(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)/memory.o $(dir_build)/strings.o: CFLAGS += -O3
$(dir_build)/bundled.h: $(bundled) $(dir_build)/%.o: $(dir_source)/%.c
@$(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
@mkdir -p "$(@D)" @mkdir -p "$(@D)"
$(COMPILE.c) $(OUTPUT_OPTION) $< $(COMPILE.c) $(OUTPUT_OPTION) $<

View File

@ -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

View File

@ -3,7 +3,7 @@
#include "memory.h" #include "memory.h"
#include "strings.h" #include "strings.h"
#include "fsldr.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) 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); roundedDataSize = ((dataSize + 4095) & 0xFFFFF000);
//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(roundedTextSize - size >= romfsredir_bin_size) *payloadOffset = size; if(roundedTextSize - size >= romfsRedirPatchSize) *payloadOffset = size;
else else
{ {
//If there isn't enough padding look for the "throwFatalError" function to replace //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 //Setup the payload
u8 *payload = code + payloadOffset; u8 *payload = code + payloadOffset;
memcpy(payload, romfsredir_bin, romfsredir_bin_size);
//Insert symbols in the payload romfsRedirPatchSubstituted1 = *(u32 *)(code + fsOpenFileDirectly);
u32 *payload32 = (u32 *)payload; romfsRedirPatchHook1 = MAKE_BRANCH(payloadOffset + (u32)&romfsRedirPatchHook1 - (u32)romfsRedirPatch, fsOpenFileDirectly + 4);
for(u32 i = 0; i < romfsredir_bin_size / 4; i++) romfsRedirPatchSubstituted1 = *(u32 *)(code + fsTryOpenFile);
{ romfsRedirPatchHook2 = MAKE_BRANCH(payloadOffset + (u32)&romfsRedirPatchHook2 - (u32)romfsRedirPatch, fsTryOpenFile + 4);
switch(payload32[i]) romfsRedirPatchCustomPath = pathAddress;
{ romfsRedirPatchFsMountArchive = 0x100000 + fsMountArchive;
case 0xdead0000: romfsRedirPatchFsRegisterArchive = 0x100000 + fsRegisterArchive;
payload32[i] = *(u32 *)(code + fsOpenFileDirectly); romfsRedirPatchArchiveId = archiveId;
break; memcpy(&romfsRedirPatchRomFsMount, updateRomFsMounts[updateRomFsIndex], 4);
case 0xdead0001:
payload32[i] = MAKE_BRANCH(payloadOffset + i * 4, fsOpenFileDirectly + 4); memcpy(payload, romfsRedirPatch, romfsRedirPatchSize);
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;
}
}
memcpy(code + pathOffset, "lf:", 3); memcpy(code + pathOffset, "lf:", 3);
memcpy(code + pathOffset + 3, path, sizeof(path)); memcpy(code + pathOffset + 3, path, sizeof(path));

View 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;

View 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