Fix and refactor stuff
This commit is contained in:
parent
2fab0be5e8
commit
bafba1197e
3
Makefile
3
Makefile
@ -106,7 +106,6 @@ $(dir_build)/loader.h: $(dir_loader)/Makefile
|
|||||||
|
|
||||||
$(dir_build)/arm9_exceptions.h: $(dir_arm9_exceptions)/Makefile
|
$(dir_build)/arm9_exceptions.h: $(dir_arm9_exceptions)/Makefile
|
||||||
@$(MAKE) -C $(dir_arm9_exceptions)
|
@$(MAKE) -C $(dir_arm9_exceptions)
|
||||||
@mv $(dir_arm9_exceptions)/arm9_exceptions.bin $(@D)
|
|
||||||
@bin2c -o $@ -n arm9_exceptions $(@D)/arm9_exceptions.bin
|
@bin2c -o $@ -n arm9_exceptions $(@D)/arm9_exceptions.bin
|
||||||
|
|
||||||
$(dir_build)/screeninit.h: $(dir_screeninit)/Makefile
|
$(dir_build)/screeninit.h: $(dir_screeninit)/Makefile
|
||||||
@ -114,7 +113,7 @@ $(dir_build)/screeninit.h: $(dir_screeninit)/Makefile
|
|||||||
@bin2c -o $@ -n screeninit $(@D)/screeninit.bin
|
@bin2c -o $@ -n screeninit $(@D)/screeninit.bin
|
||||||
|
|
||||||
$(dir_build)/memory.o: CFLAGS += -O3
|
$(dir_build)/memory.o: CFLAGS += -O3
|
||||||
$(dir_build)/config.o: CFLAGS += -DCONFIG_TITLE="\"$(name) $(revision) configuration\""
|
$(dir_build)/config.o: CFLAGS += -DCONFIG_TITLE="\"$(name) $(revision) (dev) configuration\""
|
||||||
|
|
||||||
$(dir_build)/%.o: $(dir_source)/%.c $(bundled)
|
$(dir_build)/%.o: $(dir_source)/%.c $(bundled)
|
||||||
@mkdir -p "$(@D)"
|
@mkdir -p "$(@D)"
|
||||||
|
@ -25,13 +25,13 @@ objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
|
|||||||
$(call rwildcard, $(dir_source), *.s *.c)))
|
$(call rwildcard, $(dir_source), *.s *.c)))
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: $(name).bin
|
all: ../../$(dir_build)/$(name).bin
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
@rm -rf $(dir_build)
|
@rm -rf $(dir_build)
|
||||||
|
|
||||||
$(name).bin: $(dir_build)/$(name).elf
|
../../$(dir_build)/$(name).bin: $(dir_build)/$(name).elf
|
||||||
$(OC) -S -O binary $< $@
|
$(OC) -S -O binary $< $@
|
||||||
|
|
||||||
$(dir_build)/$(name).elf: $(objects)
|
$(dir_build)/$(name).elf: $(objects)
|
||||||
|
@ -24,41 +24,6 @@ u32 config,
|
|||||||
firmSource,
|
firmSource,
|
||||||
emuOffset;
|
emuOffset;
|
||||||
|
|
||||||
static inline void patchExceptionHandlersInstall(u8 *arm9Section)
|
|
||||||
{
|
|
||||||
static const u8 pattern[] = {
|
|
||||||
0x18, 0x10, 0x80, 0xE5,
|
|
||||||
0x10, 0x10, 0x80, 0xE5,
|
|
||||||
0x20, 0x10, 0x80, 0xE5,
|
|
||||||
0x28, 0x10, 0x80, 0xE5,
|
|
||||||
}; //i.e when it stores ldr pc, [pc, #-4]
|
|
||||||
|
|
||||||
u32* off = (u32 *)(memsearch(arm9Section, pattern, section[2].size, sizeof(pattern)));
|
|
||||||
if(off == NULL) return;
|
|
||||||
off += sizeof(pattern)/4;
|
|
||||||
|
|
||||||
u32 r0 = 0x08000000;
|
|
||||||
|
|
||||||
for(; *off != 0xE3A01040; off++) //until mov r1, #0x40
|
|
||||||
{
|
|
||||||
if((*off >> 26) != 0x39 || ((*off >> 16) & 0xf) != 0 || ((*off >> 25) & 1) != 0 || ((*off >> 20) & 5) != 0)
|
|
||||||
continue; //discard everything that's not str rX, [r0, #imm](!)
|
|
||||||
|
|
||||||
int rD = (*off >> 12) & 0xf;
|
|
||||||
int offset = (*off & 0xfff) * ((((*off >> 23) & 1) == 0) ? -1 : 1);
|
|
||||||
int writeback = (*off >> 21) & 1, pre = (*off >> 24) & 1;
|
|
||||||
|
|
||||||
u32 addr = r0 + ((pre || !writeback) ? offset : 0);
|
|
||||||
if(addr != 0x08000014 && addr != 0x08000004)
|
|
||||||
*off = 0xE1A00000; //nop
|
|
||||||
else
|
|
||||||
*off = 0xE5800000 | (rD << 12) | (addr & 0xfff); //preserve IRQ and svc handlers
|
|
||||||
|
|
||||||
if(!pre) addr += offset;
|
|
||||||
if(writeback) r0 = addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
u32 bootType,
|
u32 bootType,
|
||||||
@ -247,7 +212,7 @@ void main(void)
|
|||||||
|
|
||||||
loadFirm(firmType, !firmType && updatedSys == !firmSource);
|
loadFirm(firmType, !firmType && updatedSys == !firmSource);
|
||||||
|
|
||||||
patchExceptionHandlersInstall((u8 *)firm + section[2].offset);
|
patchExceptionHandlersInstall((u8 *)firm + section[2].offset, section[2].size);
|
||||||
|
|
||||||
switch(firmType)
|
switch(firmType)
|
||||||
{
|
{
|
||||||
@ -293,21 +258,6 @@ static inline void loadFirm(u32 firmType, u32 externalFirm)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void patchKernelFCRAMAndVRAMMappingPermissions(void)
|
|
||||||
{
|
|
||||||
static const u8 MMUConfigPattern[] = {
|
|
||||||
0xC4, 0xDD, 0xFA, 0x1F,
|
|
||||||
0x16, 0x64, 0x01, 0x00,
|
|
||||||
0xBC, 0xDD, 0xFA, 0x1F,
|
|
||||||
0x00, 0x50, 0xFF, 0x1F
|
|
||||||
};
|
|
||||||
|
|
||||||
u8 *arm11Section1 = (u8 *)firm + section[1].offset;
|
|
||||||
|
|
||||||
u32* off = (u32 *)memsearch(arm11Section1, MMUConfigPattern, section[1].size, sizeof(MMUConfigPattern));
|
|
||||||
if(off != NULL) off[1] &= ~(1 << 4); //clear XN bit
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void patchNativeFirm(u32 nandType, u32 emuHeader, u32 a9lhMode)
|
static inline void patchNativeFirm(u32 nandType, u32 emuHeader, u32 a9lhMode)
|
||||||
{
|
{
|
||||||
u8 *arm9Section = (u8 *)firm + section[2].offset;
|
u8 *arm9Section = (u8 *)firm + section[2].offset;
|
||||||
@ -367,16 +317,14 @@ static inline void patchNativeFirm(u32 nandType, u32 emuHeader, u32 a9lhMode)
|
|||||||
|
|
||||||
//Does nothing if svcBackdoor is still there
|
//Does nothing if svcBackdoor is still there
|
||||||
if(nativeFirmType == 1) reimplementSvcBackdoor((u8 *)firm + section[1].offset, section[1].size);
|
if(nativeFirmType == 1) reimplementSvcBackdoor((u8 *)firm + section[1].offset, section[1].size);
|
||||||
if(nativeFirmType == 1) reimplementSvcBackdoor();
|
|
||||||
|
|
||||||
if(DEVMODE)
|
if(DEVMODE)
|
||||||
{
|
{
|
||||||
//Apply UNITINFO patch
|
//Apply UNITINFO patch
|
||||||
u8 *unitInfoOffset = getUnitInfoValueSet(arm9Section, section[2].size);
|
patchUnitInfoValueSet(arm9Section, section[2].size);
|
||||||
*unitInfoOffset = unitInfoPatch;
|
|
||||||
|
|
||||||
//Make FCRAM (and VRAM as a side effect) globally executable from arm11 kernel
|
//Make FCRAM (and VRAM as a side effect) globally executable from arm11 kernel
|
||||||
patchKernelFCRAMAndVRAMMappingPermissions();
|
patchKernelFCRAMAndVRAMMappingPermissions(arm9Section, section[2].size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@ typedef struct firmHeader {
|
|||||||
} firmHeader;
|
} firmHeader;
|
||||||
|
|
||||||
static inline void loadFirm(u32 firmType, u32 externalFirm);
|
static inline void loadFirm(u32 firmType, u32 externalFirm);
|
||||||
static inline void patchKernelFCRAMAndVRAMMappingPermissions(void);
|
|
||||||
static inline void patchNativeFirm(u32 nandType, u32 emuHeader, u32 a9lhMode);
|
static inline void patchNativeFirm(u32 nandType, u32 emuHeader, u32 a9lhMode);
|
||||||
static inline void patchLegacyFirm(u32 firmType);
|
static inline void patchLegacyFirm(u32 firmType);
|
||||||
static inline void patchSafeFirm(void);
|
static inline void patchSafeFirm(void);
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "../build/rebootpatch.h"
|
#include "../build/rebootpatch.h"
|
||||||
|
|
||||||
const u8 unitInfoPatch = 0xE3;
|
|
||||||
|
|
||||||
u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
|
u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
|
||||||
{
|
{
|
||||||
u8 *off = memsearch(pos, "ess9", size, 4);
|
u8 *off = memsearch(pos, "ess9", size, 4);
|
||||||
@ -90,12 +88,61 @@ void patchFirmWriteSafe(u8 *pos, u32 size)
|
|||||||
off[1] = writeBlockSafe[1];
|
off[1] = writeBlockSafe[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 *getUnitInfoValueSet(u8 *pos, u32 size)
|
void patchExceptionHandlersInstall(u8 *pos, u32 size)
|
||||||
|
{
|
||||||
|
static const u8 pattern[] = {
|
||||||
|
0x18, 0x10, 0x80, 0xE5,
|
||||||
|
0x10, 0x10, 0x80, 0xE5,
|
||||||
|
0x20, 0x10, 0x80, 0xE5,
|
||||||
|
0x28, 0x10, 0x80, 0xE5,
|
||||||
|
}; //i.e when it stores ldr pc, [pc, #-4]
|
||||||
|
|
||||||
|
u32* off = (u32 *)(memsearch(pos, pattern, size, sizeof(pattern)));
|
||||||
|
if(off == NULL) return;
|
||||||
|
off += sizeof(pattern)/4;
|
||||||
|
|
||||||
|
u32 r0 = 0x08000000;
|
||||||
|
|
||||||
|
for(; *off != 0xE3A01040; off++) //until mov r1, #0x40
|
||||||
|
{
|
||||||
|
if((*off >> 26) != 0x39 || ((*off >> 16) & 0xf) != 0 || ((*off >> 25) & 1) != 0 || ((*off >> 20) & 5) != 0)
|
||||||
|
continue; //discard everything that's not str rX, [r0, #imm](!)
|
||||||
|
|
||||||
|
int rD = (*off >> 12) & 0xf;
|
||||||
|
int offset = (*off & 0xfff) * ((((*off >> 23) & 1) == 0) ? -1 : 1);
|
||||||
|
int writeback = (*off >> 21) & 1, pre = (*off >> 24) & 1;
|
||||||
|
|
||||||
|
u32 addr = r0 + ((pre || !writeback) ? offset : 0);
|
||||||
|
if(addr != 0x08000014 && addr != 0x08000004)
|
||||||
|
*off = 0xE1A00000; //nop
|
||||||
|
else
|
||||||
|
*off = 0xE5800000 | (rD << 12) | (addr & 0xfff); //preserve IRQ and svc handlers
|
||||||
|
|
||||||
|
if(!pre) addr += offset;
|
||||||
|
if(writeback) r0 = addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void patchUnitInfoValueSet(u8 *pos, u32 size)
|
||||||
{
|
{
|
||||||
//Look for UNITINFO value being set
|
//Look for UNITINFO value being set
|
||||||
const u8 pattern[] = {0x01, 0x10, 0xA0, 0x13};
|
const u8 pattern[] = {0x01, 0x10, 0xA0, 0x13};
|
||||||
|
|
||||||
return memsearch(pos, pattern, size, 4) + 3;
|
u8 *off = memsearch(pos, pattern, size, 4);
|
||||||
|
if(off != NULL) off[3] = 0xE3;
|
||||||
|
}
|
||||||
|
|
||||||
|
void patchKernelFCRAMAndVRAMMappingPermissions(u8 *pos, u32 size)
|
||||||
|
{
|
||||||
|
static const u8 MMUConfigPattern[] = {
|
||||||
|
0xC4, 0xDD, 0xFA, 0x1F,
|
||||||
|
0x16, 0x64, 0x01, 0x00,
|
||||||
|
0xBC, 0xDD, 0xFA, 0x1F,
|
||||||
|
0x00, 0x50, 0xFF, 0x1F
|
||||||
|
};
|
||||||
|
|
||||||
|
u32* off = (u32 *)memsearch(pos, MMUConfigPattern, size, sizeof(MMUConfigPattern));
|
||||||
|
if(off != NULL) off[1] &= ~(1 << 4); //clear XN bit
|
||||||
}
|
}
|
||||||
|
|
||||||
void reimplementSvcBackdoor(u8 *pos, u32 size)
|
void reimplementSvcBackdoor(u8 *pos, u32 size)
|
||||||
|
@ -14,13 +14,17 @@ typedef struct patchData {
|
|||||||
} patch;
|
} patch;
|
||||||
u32 type;
|
u32 type;
|
||||||
} patchData;
|
} patchData;
|
||||||
const u8 unitInfoPatch;
|
|
||||||
u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr);
|
u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr);
|
||||||
void patchSignatureChecks(u8 *pos, u32 size);
|
void patchSignatureChecks(u8 *pos, u32 size);
|
||||||
void patchTitleInstallMinVersionCheck(u8 *pos, u32 size);
|
void patchTitleInstallMinVersionCheck(u8 *pos, u32 size);
|
||||||
void patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr);
|
void patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr);
|
||||||
void patchFirmWrites(u8 *pos, u32 size);
|
void patchFirmWrites(u8 *pos, u32 size);
|
||||||
void patchFirmWriteSafe(u8 *pos, u32 size);
|
void patchFirmWriteSafe(u8 *pos, u32 size);
|
||||||
|
void patchExceptionHandlersInstall(u8 *pos, u32 size);
|
||||||
|
void patchUnitInfoValueSet(u8 *pos, u32 size);
|
||||||
|
void patchKernelFCRAMAndVRAMMappingPermissions(u8 *pos, u32 size);
|
||||||
void reimplementSvcBackdoor(u8 *pos, u32 size);
|
void reimplementSvcBackdoor(u8 *pos, u32 size);
|
||||||
void applyLegacyFirmPatches(u8 *pos, u32 firmType, u32 console);
|
void applyLegacyFirmPatches(u8 *pos, u32 firmType, u32 console);
|
||||||
|
u32 getLoader(u8 *pos, u32 *loaderSize);
|
||||||
u8 *getUnitInfoValueSet(u8 *pos, u32 size);
|
u8 *getUnitInfoValueSet(u8 *pos, u32 size);
|
Reference in New Issue
Block a user