Minor stuff
This commit is contained in:
parent
0dc0783094
commit
653e81c48e
@ -5,6 +5,7 @@ ENTRY(_start)
|
|||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 0;
|
. = 0;
|
||||||
|
|
||||||
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
|
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
|
||||||
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
||||||
.data : ALIGN(4) { *(.data*); . = ALIGN(8); *(.bss* COMMON); . = ALIGN(8); }
|
.data : ALIGN(4) { *(.data*); . = ALIGN(8); *(.bss* COMMON); . = ALIGN(8); }
|
||||||
|
@ -5,6 +5,7 @@ ENTRY(_start)
|
|||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 0x01FF7FE0;
|
. = 0x01FF7FE0;
|
||||||
|
|
||||||
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
|
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
|
||||||
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
||||||
.data : ALIGN(4) { *(.data*); . = ALIGN(8); *(.bss* COMMON); . = ALIGN(8); }
|
.data : ALIGN(4) { *(.data*); . = ALIGN(8); *(.bss* COMMON); . = ALIGN(8); }
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
|
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
||||||
|
OUTPUT_ARCH(arm)
|
||||||
|
|
||||||
ENTRY(_start)
|
ENTRY(_start)
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 0x23F00000;
|
. = 0x23F00000;
|
||||||
.text.start : { *(.text.start) }
|
|
||||||
.text : { *(.text) }
|
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
|
||||||
.data : { *(.data) }
|
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
||||||
.bss : { *(.bss COMMON) }
|
.data : ALIGN(4) { *(.data*); . = ALIGN(8); *(.bss* COMMON); . = ALIGN(8); }
|
||||||
.rodata : { *(.rodata) }
|
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,8 @@ _start:
|
|||||||
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:" and "rom2:"
|
||||||
bne endRedir
|
cmpne r12, #0x70 ; 'p', should include "patch:"
|
||||||
|
bne endRedir
|
||||||
sub sp, sp, #0x400
|
sub sp, sp, #0x400
|
||||||
pathRedir:
|
pathRedir:
|
||||||
stmfd sp!, {r0-r3}
|
stmfd sp!, {r0-r3}
|
||||||
|
@ -289,7 +289,7 @@ static u32 findFunctionStart(u8* code, u32 pos)
|
|||||||
return 0xFFFFFFFF;
|
return 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
static 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)
|
||||||
{
|
{
|
||||||
@ -324,17 +324,19 @@ static bool findLayeredFsSymbols(u8* code, u32 size, u32 *fsMountArchive, u32 *f
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool findLayeredFsPayloadOffset(u8* code, u32 text_size, u32* payload_offset) {
|
static inline bool findLayeredFsPayloadOffset(u8* code, u32 textSize, u32 *payloadOffset)
|
||||||
// First check for sufficient padding at the end of the .text segment
|
{
|
||||||
if (((text_size + 4095) & 0xfffff000) - text_size >= romfsredir_bin_size) {
|
//First check for sufficient padding at the end of the .text segment
|
||||||
*payload_offset = text_size;
|
if(((textSize + 4095) & 0xfffff000) - textSize >= romfsredir_bin_size)
|
||||||
|
{
|
||||||
|
*payloadOffset = textSize;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
u32 svcConnectToPort = 0xFFFFFFFF;
|
u32 svcConnectToPort = 0xFFFFFFFF;
|
||||||
|
|
||||||
for(u32 addr = 4; svcConnectToPort == 0xFFFFFFFF && addr <= text_size - 4; addr += 4)
|
for(u32 addr = 4; svcConnectToPort == 0xFFFFFFFF && addr <= textSize - 4; addr += 4)
|
||||||
{
|
{
|
||||||
if(*(u32 *)(code + addr) == 0xEF00002D)
|
if(*(u32 *)(code + addr) == 0xEF00002D)
|
||||||
svcConnectToPort = addr - 4;
|
svcConnectToPort = addr - 4;
|
||||||
@ -344,18 +346,19 @@ static bool findLayeredFsPayloadOffset(u8* code, u32 text_size, u32* payload_off
|
|||||||
{
|
{
|
||||||
u32 func = 0xFFFFFFFF;
|
u32 func = 0xFFFFFFFF;
|
||||||
|
|
||||||
for(u32 i = 4; func == 0xFFFFFFFF && i <= text_size - 4; i += 4)
|
for(u32 i = 4; func == 0xFFFFFFFF && i <= textSize - 4; i += 4)
|
||||||
{
|
{
|
||||||
if(*(u32 *)(code + i) != MAKE_BRANCH_LINK(i, svcConnectToPort)) continue;
|
if(*(u32 *)(code + i) != MAKE_BRANCH_LINK(i, svcConnectToPort)) continue;
|
||||||
|
|
||||||
func = findFunctionStart(code, i);
|
func = findFunctionStart(code, i);
|
||||||
|
|
||||||
for(u32 pos = func + 4; func != 0xFFFFFFFF && pos <= text_size - 4 && *(u16 *)(code + pos + 2) != 0xE92D; pos += 4)
|
for(u32 pos = func + 4; func != 0xFFFFFFFF && pos <= textSize - 4 && *(u16 *)(code + pos + 2) != 0xE92D; pos += 4)
|
||||||
if(*(u32 *)(code + pos) == 0xE200167E) func = 0xFFFFFFFF;
|
if(*(u32 *)(code + pos) == 0xE200167E) func = 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(func != 0xFFFFFFFF) {
|
if(func != 0xFFFFFFFF)
|
||||||
*payload_offset = func;
|
{
|
||||||
|
*payloadOffset = func;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -505,7 +508,7 @@ exit:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool patchLayeredFs(u64 progId, u8* code, u32 size, u32 text_size)
|
static inline bool patchLayeredFs(u64 progId, u8* code, u32 size, u32 textSize)
|
||||||
{
|
{
|
||||||
/* 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 */
|
||||||
@ -522,14 +525,14 @@ static inline bool patchLayeredFs(u64 progId, u8* code, u32 size, u32 text_size)
|
|||||||
u32 fsMountArchive = 0xFFFFFFFF,
|
u32 fsMountArchive = 0xFFFFFFFF,
|
||||||
fsRegisterArchive = 0xFFFFFFFF,
|
fsRegisterArchive = 0xFFFFFFFF,
|
||||||
fsTryOpenFile = 0xFFFFFFFF,
|
fsTryOpenFile = 0xFFFFFFFF,
|
||||||
fsOpenFileDirectly = 0xFFFFFFFF;
|
fsOpenFileDirectly = 0xFFFFFFFF,
|
||||||
|
payloadOffset;
|
||||||
|
|
||||||
if(!findLayeredFsSymbols(code, size, &fsMountArchive, &fsRegisterArchive, &fsTryOpenFile, &fsOpenFileDirectly)) return false;
|
if(!findLayeredFsSymbols(code, size, &fsMountArchive, &fsRegisterArchive, &fsTryOpenFile, &fsOpenFileDirectly) ||
|
||||||
|
!findLayeredFsPayloadOffset(code, textSize, &payloadOffset)) return false;
|
||||||
|
|
||||||
//Setup the payload
|
//Setup the payload
|
||||||
u32 payload_offset;
|
u8 *payload = code + payloadOffset;
|
||||||
if(!findLayeredFsPayloadOffset(code, text_size, &payload_offset)) return false;
|
|
||||||
u8 *payload = code + payload_offset;
|
|
||||||
memcpy(payload, romfsredir_bin, romfsredir_bin_size);
|
memcpy(payload, romfsredir_bin, romfsredir_bin_size);
|
||||||
|
|
||||||
//Insert symbols in the payload
|
//Insert symbols in the payload
|
||||||
@ -542,13 +545,13 @@ static inline bool patchLayeredFs(u64 progId, u8* code, u32 size, u32 text_size)
|
|||||||
payload32[i] = *(u32 *)(code + fsOpenFileDirectly);
|
payload32[i] = *(u32 *)(code + fsOpenFileDirectly);
|
||||||
break;
|
break;
|
||||||
case 0xdead0001:
|
case 0xdead0001:
|
||||||
payload32[i] = MAKE_BRANCH(payload_offset + i * 4, fsOpenFileDirectly + 4);
|
payload32[i] = MAKE_BRANCH(payloadOffset + i * 4, fsOpenFileDirectly + 4);
|
||||||
break;
|
break;
|
||||||
case 0xdead0002:
|
case 0xdead0002:
|
||||||
payload32[i] = *(u32 *)(code + fsTryOpenFile);
|
payload32[i] = *(u32 *)(code + fsTryOpenFile);
|
||||||
break;
|
break;
|
||||||
case 0xdead0003:
|
case 0xdead0003:
|
||||||
payload32[i] = MAKE_BRANCH(payload_offset + 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, mount, 5);
|
||||||
@ -570,13 +573,13 @@ static inline bool patchLayeredFs(u64 progId, u8* code, u32 size, u32 text_size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Place the hooks
|
//Place the hooks
|
||||||
*(u32 *)(code + fsOpenFileDirectly) = MAKE_BRANCH(fsOpenFileDirectly, payload_offset);
|
*(u32 *)(code + fsOpenFileDirectly) = MAKE_BRANCH(fsOpenFileDirectly, payloadOffset);
|
||||||
*(u32 *)(code + fsTryOpenFile) = MAKE_BRANCH(fsTryOpenFile, payload_offset + 12);
|
*(u32 *)(code + fsTryOpenFile) = MAKE_BRANCH(fsTryOpenFile, payloadOffset + 12);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void patchCode(u64 progId, u16 progVer, u8 *code, u32 size, u32 text_size)
|
void patchCode(u64 progId, u16 progVer, u8 *code, u32 size, u32 textSize)
|
||||||
{
|
{
|
||||||
loadCFWInfo();
|
loadCFWInfo();
|
||||||
|
|
||||||
@ -838,7 +841,7 @@ void patchCode(u64 progId, u16 progVer, u8 *code, u32 size, u32 text_size)
|
|||||||
if(!loadTitleCodeSection(progId, code, size) ||
|
if(!loadTitleCodeSection(progId, code, size) ||
|
||||||
!applyCodeIpsPatch(progId, code, size) ||
|
!applyCodeIpsPatch(progId, code, size) ||
|
||||||
!loadTitleLocaleConfig(progId, ®ionId, &languageId) ||
|
!loadTitleLocaleConfig(progId, ®ionId, &languageId) ||
|
||||||
!patchLayeredFs(progId, code, size, text_size)) goto error;
|
!patchLayeredFs(progId, code, size, textSize)) goto error;
|
||||||
|
|
||||||
if(regionId != 0xFF)
|
if(regionId != 0xFF)
|
||||||
{
|
{
|
||||||
|
@ -44,4 +44,4 @@ enum flags
|
|||||||
ISSAFEMODE
|
ISSAFEMODE
|
||||||
};
|
};
|
||||||
|
|
||||||
void patchCode(u64 progId, u16 progVer, u8 *code, u32 size, u32 text_size);
|
void patchCode(u64 progId, u16 progVer, u8 *code, u32 size, u32 textSize);
|
||||||
|
@ -9,7 +9,6 @@ SECTIONS
|
|||||||
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
|
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
|
||||||
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
||||||
.data : ALIGN(4) { *(.data*); . = ALIGN(4); }
|
.data : ALIGN(4) { *(.data*); . = ALIGN(4); }
|
||||||
|
|
||||||
.bss : ALIGN(8) { __bss_start = .; *(.bss* COMMON); . = ALIGN(8); __bss_end = .; }
|
.bss : ALIGN(8) { __bss_start = .; *(.bss* COMMON); . = ALIGN(8); __bss_end = .; }
|
||||||
|
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
|
@ -5,6 +5,7 @@ ENTRY(_start)
|
|||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 0x24FFFE00;
|
. = 0x24FFFE00;
|
||||||
|
|
||||||
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
|
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
|
||||||
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
||||||
.data : ALIGN(4) { *(.data*); . = ALIGN(8); *(.bss* COMMON); . = ALIGN(8); }
|
.data : ALIGN(4) { *(.data*); . = ALIGN(8); *(.bss* COMMON); . = ALIGN(8); }
|
||||||
|
Reference in New Issue
Block a user