diff --git a/Makefile b/Makefile index 853f98c..6d632a8 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ ifeq ($(strip $(DEVKITARM)),) $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") endif -CC = $(DEVKITARM)/bin/arm-none-eabi-gcc +include $(DEVKITARM)/base_tools LD = $(DEVKITARM)/bin/arm-none-eabi-ld OBJCOPY = $(DEVKITARM)/bin/arm-none-eabi-objcopy @@ -51,9 +51,12 @@ $(dir_out)/sysmodules: $(dir_sysmod) $(dir_out)/$(name).bin: $(dir_build)/$(name).elf @mkdir -p "$(@D)" @mkdir -p "$(dir_out)/ReiNX/sysmodules" + @mkdir -p "$(dir_out)/ReiNX/sysmodules.dis" @mkdir -p "$(dir_out)/ReiNX/patches" @cp $(dir_sysmod)/loader/loader.kip $(dir_out)/ReiNX/sysmodules/ @cp $(dir_sysmod)/sm/sm.kip $(dir_out)/ReiNX/sysmodules/ + @cp $(dir_sysmod)/pm/pm.kip $(dir_out)/ReiNX/sysmodules.dis/ + @cp $(dir_sysmod)/fs_mitm/fs_mitm.kip $(dir_out)/ReiNX/sysmodules.dis/ @cp -R $(dir_data)/*.bin $(dir_out)/ReiNX/ @cp -R $(dir_data)/*.rxp $(dir_out)/ReiNX/patches $(OBJCOPY) -S -O binary $< $@ diff --git a/NX_Sysmodules b/NX_Sysmodules index 281c052..3c12add 160000 --- a/NX_Sysmodules +++ b/NX_Sysmodules @@ -1 +1 @@ -Subproject commit 281c0521dd09ec6c5af6cfef75f505602dd0888c +Subproject commit 3c12add04883b893698cfa04451c834e34bcbe66 diff --git a/README.md b/README.md index bcb4191..cf43cbf 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ To compile with Docker, `chmod +x docker-build.sh` and run the shell script `./d * FS patches on the fly (NCA verify/cmac and optional nogc) +* Kernel patches on the fly (optional debug mode) + * Exclusive ReiNX sysmodules * ES patch in RXP patch format (used with custom loader.kip) diff --git a/src/error.c b/src/error.c index 6dcd62b..e790cc6 100644 --- a/src/error.c +++ b/src/error.c @@ -30,6 +30,7 @@ void panic() { } void error(char *errStr) { + gfx_con.mute = 0; gfx_con_setcol(&gfx_con, RED, 0, 0); print("Error: %s", errStr); gfx_con_setcol(&gfx_con, DEFAULT_TEXT_COL, 0, 0); diff --git a/src/firmware.c b/src/firmware.c index 0a2eac1..fd9daff 100644 --- a/src/firmware.c +++ b/src/firmware.c @@ -25,13 +25,14 @@ static pk11_offs *pk11Offs = NULL; -void drawSplash() { +int drawSplash() { // Draw splashscreen to framebuffer. if(fopen("/ReiNX/splash.bin", "rb") != 0) { fread((void*)0xC0000000, fsize(), 1); fclose(); - usleep(3000000); + return 1; } + return 0; } pk11_offs *pkg11_offsentify(u8 *pkg1) { @@ -41,6 +42,59 @@ pk11_offs *pkg11_offsentify(u8 *pkg1) { return NULL; } +void patchFS(pkg2_kip1_info_t* ki) { + u8 kipHash[0x20]; + + print("Patching FS\n"); + + se_calc_sha256(&kipHash, ki->kip1, ki->size); + se_calc_sha256(&kipHash, ki->kip1, ki->size); + + //Create header + size_t sizeDiff = ki->kip1->sections[0].size_decomp - ki->kip1->sections[0].size_comp; + + size_t newSize = ki->size + sizeDiff; + pkg2_kip1_t *moddedKip = malloc(newSize); + memcpy(moddedKip, ki->kip1, newSize); + + u32 pos = 0; + //Get decomp .text segment + u8 *kipDecompText = blz_decompress(moddedKip->data, moddedKip->sections[0].size_comp); + + kippatchset_t *pset = kippatch_find_set(kipHash, kip_patches); + if (!pset) { + print(" could not find patchset with matching hash\n"); + } else { + int res = kippatch_apply_set(kipDecompText, moddedKip->sections[0].size_decomp, pset); + if (res) error("kippatch_apply_set() failed\n"); + } + + moddedKip->flags &= ~1; + memcpy((void*)moddedKip->data, kipDecompText, moddedKip->sections[0].size_decomp); + free(kipDecompText); + pos += moddedKip->sections[0].size_comp; + moddedKip->sections[0].size_comp = moddedKip->sections[0].size_decomp; + + for(int i = 1; i < KIP1_NUM_SECTIONS; i++) { + if(moddedKip->sections[i].offset != 0) { + memcpy((void*)moddedKip->data + pos + sizeDiff, (void*)ki->kip1->data + pos, moddedKip->sections[i].size_comp); + pos += moddedKip->sections[i].size_comp; + } + } + + free(ki->kip1); + ki->size = newSize; + ki->kip1 = moddedKip; +} + +pkg2_kip1_info_t* find_by_tid(link_t* kip_list, u64 tid) { + LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, kip_list, link) { + if(ki->kip1->tid == 0x0100000000000000) + return ki; + } + return NULL; +} + void patch(pk11_offs *pk11, pkg2_hdr_t *pkg2, link_t *kips) { //Patch Secmon if(!customSecmon){ @@ -120,69 +174,115 @@ void patch(pk11_offs *pk11, pkg2_hdr_t *pkg2, link_t *kips) { //Patch Kernel if(!customKern) { u32 crc = crc32c(pkg2->data, pkg2->sec_size[PKG2_SEC_KERNEL]); - const pkg2_kernel_id_t * id = pkg2_identify(crc); - - kernel_patch_t * kpatch = id->kernel_patchset; - if(kpatch!=NULL) { - for(int i=0; kpatch[i].id!=-1; i++) { - if(kpatch[i].id != ATM_ARR_PATCH) - *(vu32 *)(pkg2->data + kpatch[i].off) = kpatch[i].val; - else { - u32 * temp = (u32 *)kpatch[i].ptr; - for(int j=0; j< kpatch[i].val; j++) { - *(vu32*)(pkg2->data + kpatch[i].off + j*4) = temp[j]; - } - } - } - } - } - - u8 kipHash[0x20]; - - //Patch FS module (truly not my proudest code TODO cleanup) - LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, kips, link) { - //Patch FS - if(ki->kip1->tid == 0x0100000000000000) { - print("Patching FS\n"); - - se_calc_sha256(&kipHash, ki->kip1, ki->size); - se_calc_sha256(&kipHash, ki->kip1, ki->size); - - //Create header - size_t sizeDiff = ki->kip1->sections[0].size_decomp - ki->kip1->sections[0].size_comp; - size_t newSize = ki->size + sizeDiff; - pkg2_kip1_t *moddedKip = malloc(newSize); - memcpy(moddedKip, ki->kip1, newSize); - u32 pos = 0; - for(int i = 0; i < KIP1_NUM_SECTIONS; i++) { - if(!i) { - //Get decomp .text segment - u8 *kipDecompText = blz_decompress(moddedKip->data, moddedKip->sections[i].size_comp); - - kippatchset_t *pset = kippatch_find_set(kipHash, kip_patches); - if (!pset) { - print(" could not find patchset with matching hash\n"); - } else { - int res = kippatch_apply_set(kipDecompText, moddedKip->sections[i].size_decomp, pset); - if (res) error("kippatch_apply_set() failed\n"); - } - - moddedKip->flags &= ~1; - memcpy((void*)moddedKip->data, kipDecompText, moddedKip->sections[i].size_decomp); - free(kipDecompText); - pos += moddedKip->sections[i].size_comp; - moddedKip->sections[i].size_comp = moddedKip->sections[i].size_decomp; - } else { - if(moddedKip->sections[i].offset == 0) continue; - memcpy((void*)moddedKip->data + pos + sizeDiff, (void*)ki->kip1->data + pos, moddedKip->sections[i].size_comp); - pos += moddedKip->sections[i].size_comp; - } + uPtr kern = (uPtr)&pkg2->data; + uPtr sendOff, recvOff, codeRcvOff, codeSndOff, svcVerifOff, svcDebugOff, ver; + switch(crc){ + case 0x427f2647:{ //1.0.0 + svcVerifOff = 0x3764C; + svcDebugOff = 0x44074; + sendOff = 0x23CC0; + recvOff = 0x219F0; + codeSndOff = 4; + codeRcvOff = 4; + ver = 0; + break; + } + case 0xae19cf1b:{ //2.0.0 + svcVerifOff = 0x54834; + svcDebugOff = 0x6086C; + sendOff = 0x3F134; + recvOff = 0x3D1A8; + codeSndOff = 4; + codeRcvOff = 4; + ver = 1; + break; + } + case 0x73c9e274:{ //3.0.0 + svcVerifOff = 0x3BD24; + svcDebugOff = 0x483FC; + sendOff = 0x26080; + recvOff = 0x240F0; + codeSndOff = 4; + codeRcvOff = 4; + ver = 2; + break; + } + case 0xe0e8cdc4:{ //3.0.2 + svcVerifOff = 0x3BD24; + svcDebugOff = 0x48414; + sendOff = 0x26080; + recvOff = 0x240F0; + codeSndOff = 4; + codeRcvOff = 4; + ver = 3; + break; + } + case 0x485d0157:{ //4.0.0 + svcVerifOff = 0x41EB4; + svcDebugOff = 0x4EBFC; + sendOff = 0x2AF64; + recvOff = 0x28F6C; + codeSndOff = 8; + codeRcvOff = 4; + ver = 4; + break; } - - free(ki->kip1); - ki->size = newSize; - ki->kip1 = moddedKip; + case 0xf3c363f2:{ //5.0.0 + svcVerifOff = 0x45E6C; + svcDebugOff = 0x5513C; + sendOff = 0x2AD34; + recvOff = 0x28DAC; + codeSndOff = 8; + codeRcvOff = 8; + ver = 5; + break; + } + case 0x64ce1a44:{ //6.0.0 + svcVerifOff = 0x47EA0; + svcDebugOff = 0x57548; + sendOff = 0x2BB8C; + recvOff = 0x29B6C; + codeSndOff = 0x10; + codeRcvOff = 0x10; + ver = 6; + break; + } + default: + error("Kernel not supported"); + goto end; } + + //ID Send + uPtr freeSpace = getFreeSpace((void*)(kern+0x45000), 0x200, 0x20000) + 0x45000; //Find area to write payload + print("Kernel Freespace: 0x%08X\n", freeSpace); + size_t payloadSize; + u32 *sndPayload = getSndPayload(ver, &payloadSize); + *(vu32*)(kern + sendOff) = _B(sendOff, freeSpace); //write hook to payload + memcpy((void*)(kern + freeSpace), sndPayload, payloadSize); //Copy payload to free space + *(vu32*)(kern + freeSpace + payloadSize) = _B(freeSpace + payloadSize, sendOff + codeSndOff); //Jump back skipping the hook + + //ID Receive + freeSpace += (payloadSize+4); + u32 *rcvPayload = getRcvPayload(ver, &payloadSize); + *(vu32*)(kern + recvOff) = _B(recvOff, freeSpace); + memcpy((void*)(kern + freeSpace), rcvPayload, payloadSize); + *(vu32*)(kern + freeSpace + payloadSize) = _B(freeSpace + payloadSize, recvOff + codeRcvOff); + + //SVC patches + *(vu32*)(kern + svcVerifOff) = NOP; + if (fopen("/ReiNX/debug", "rb")) { + fclose(); + *(vu32*)(kern + svcDebugOff) = _MOVZX(8, 1, 0); + } + + end:; + } + + pkg2_kip1_info_t* FS_module = find_by_tid(kips, 0x0100000000000000); + if(FS_module == NULL) { + error("Could not find FS Module.\n"); + } else { + patchFS(FS_module); } } @@ -302,14 +402,14 @@ void firmware() { gfx_con_init(&gfx_con, &gfx_ctxt); gfx_con_setcol(&gfx_con, DEFAULT_TEXT_COL, 0, 0); - while (!sdMount()) { + if (!sdMount()) { error("Failed to init SD card!\n"); - print("Press POWER to power off, any other key to retry\n"); + print("Press POWER to power off, or any other key to continue without SD.\n"); if (btn_wait() & BTN_POWER) i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF); btn_wait(); } - + if(PMC(APBDEV_PMC_SCRATCH49) != 69 && fopen("/ReiNX.bin", "rb")) { fread((void*)PAYLOAD_ADDR, fsize(), 1); fclose(); @@ -321,10 +421,15 @@ void firmware() { ((void (*)())PAYLOAD_ADDR)(); } SYSREG(AHB_AHB_SPARE_REG) = (volatile vu32)0xFFFFFF9F; - PMC(APBDEV_PMC_SCRATCH49) = 0; - + PMC(APBDEV_PMC_SCRATCH49) = 0; + + if (btn_read() & BTN_VOL_DOWN) { + print("Booting verbosely\n"); + } else if (drawSplash()) { + gfx_con.mute = 1; + } + print("Welcome to ReiNX %s!\n", VERSION); loadFirm(); - drawSplash(); launch(); } diff --git a/src/hwinit/util.c b/src/hwinit/util.c index 016a7c9..375f6e2 100644 --- a/src/hwinit/util.c +++ b/src/hwinit/util.c @@ -70,7 +70,7 @@ uPtr getFreeSpace(void *start, size_t space, size_t searchSize) { if(*(u8*)(start+i) == 0) { for(int j=0;jkip_name, 2)) - nca_patch(kipdata, kipdata_len); + if(!strncmp("FS", patchset->kip_name, 2)) + nca_patch(kipdata, kipdata_len); return 0; } diff --git a/src/package.h b/src/package.h index f944970..c6f3bd0 100644 --- a/src/package.h +++ b/src/package.h @@ -25,30 +25,6 @@ #define INI1_MAGIC 0x31494E49 -#define FREE_CODE_OFF_1ST_100 0x4797C -#define FREE_CODE_OFF_1ST_200 0x6486C -#define FREE_CODE_OFF_1ST_300 0x494A4 -#define FREE_CODE_OFF_1ST_302 0x494BC -#define FREE_CODE_OFF_1ST_400 0x52890 -#define FREE_CODE_OFF_1ST_500 0x5C020 -#define FREE_CODE_OFF_1ST_600 0x5EE00 - -#define ID_SND_OFF_100 0x23CC0 -#define ID_SND_OFF_200 0x3F134 -#define ID_SND_OFF_300 0x26080 -#define ID_SND_OFF_302 0x26080 -#define ID_SND_OFF_400 0x2AF64 -#define ID_SND_OFF_500 0x2AD34 -#define ID_SND_OFF_600 0x2BB88 - -#define ID_RCV_OFF_100 0x219F0 -#define ID_RCV_OFF_200 0x3D1A8 -#define ID_RCV_OFF_300 0x240F0 -#define ID_RCV_OFF_302 0x240F0 -#define ID_RCV_OFF_400 0x28F6C -#define ID_RCV_OFF_500 0x28DAC -#define ID_RCV_OFF_600 0x29B6C - #define NOP 0xD503201F #define ADRP(r, o) 0x90000000 | ((((o) >> 12) & 0x3) << 29) | ((((o) >> 12) & 0x1FFFFC) << 3) | ((r) & 0x1F) @@ -58,303 +34,161 @@ static u8 customKern = 0; typedef struct _pkg2_hdr_t { - u8 ctr[0x10]; - u8 sec_ctr[0x40]; - u32 magic; - u32 base; - u32 pad0; - u16 version; - u16 pad1; - u32 sec_size[4]; - u32 sec_off[4]; - u8 sec_sha256[0x80]; - u8 data[]; + u8 ctr[0x10]; + u8 sec_ctr[0x40]; + u32 magic; + u32 base; + u32 pad0; + u16 version; + u16 pad1; + u32 sec_size[4]; + u32 sec_off[4]; + u8 sec_sha256[0x80]; + u8 data[]; } pkg2_hdr_t; typedef struct _pkg2_ini1_t { - u32 magic; - u32 size; - u32 num_procs; - u32 pad; + u32 magic; + u32 size; + u32 num_procs; + u32 pad; } pkg2_ini1_t; typedef struct _pkg2_kip1_sec_t { - u32 offset; - u32 size_decomp; - u32 size_comp; - u32 attrib; + u32 offset; + u32 size_decomp; + u32 size_comp; + u32 attrib; } pkg2_kip1_sec_t; #define KIP1_NUM_SECTIONS 6 typedef struct _pkg2_kip1_t { - u32 magic; - char name[12]; - u64 tid; - u32 proc_cat; - u8 main_thrd_prio; - u8 def_cpu_core; - u8 res; - u8 flags; - pkg2_kip1_sec_t sections[KIP1_NUM_SECTIONS]; - u32 caps[0x20]; - u8 data[]; + u32 magic; + char name[12]; + u64 tid; + u32 proc_cat; + u8 main_thrd_prio; + u8 def_cpu_core; + u8 res; + u8 flags; + pkg2_kip1_sec_t sections[KIP1_NUM_SECTIONS]; + u32 caps[0x20]; + u8 data[]; } pkg2_kip1_t; typedef struct _pkg2_kip1_info_t { - pkg2_kip1_t *kip1; - u32 size; - link_t link; + pkg2_kip1_t *kip1; + u32 size; + link_t link; } pkg2_kip1_info_t; typedef struct { - const char *id; - u32 kb; - u32 tsec_off; - u32 pkg11_off; - u32 sec_map[3]; - u32 secmon_base; - u32 warmboot_base; - int set_warmboot; + const char *id; + u32 kb; + u32 tsec_off; + u32 pkg11_off; + u32 sec_map[3]; + u32 secmon_base; + u32 warmboot_base; + int set_warmboot; } pk11_offs; typedef struct { - u32 magic; - u32 wb_size; - u32 wb_off; - u32 pad; - u32 ldr_size; - u32 ldr_off; - u32 sm_size; - u32 sm_off; + u32 magic; + u32 wb_size; + u32 wb_off; + u32 pad; + u32 ldr_size; + u32 ldr_off; + u32 sm_size; + u32 sm_off; } pk11_header; -enum -{ - // Generic instruction patches - SVC_VERIFY_DS = 0x10, // 0x0-0xF are RESERVED. - DEBUG_MODE_EN, - ATM_GEN_PATCH, - // >4 bytes patches. Value is a pointer of a u32 array. - ATM_ARR_PATCH, -}; - -typedef struct _kernel_patch_t -{ - u32 id; - u32 off; - u32 val; - u32 *ptr; -} kernel_patch_t; - -typedef struct _pkg2_kernel_id_t -{ - u32 crc32c_id; - kernel_patch_t *kernel_patchset; -} pkg2_kernel_id_t; - - static u32 PRC_ID_SND_100[] = { - 0xA9BF2FEA, 0x2A0E03EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B, - 0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9412948, 0xA8C12FEA + 0xA9BF2FEA, 0x2A0E03EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B, + 0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9412948, 0xA8C12FEA }; -#define FREE_CODE_OFF_2ND_100 (FREE_CODE_OFF_1ST_100 + sizeof(PRC_ID_SND_100) + 4) + static u32 PRC_ID_RCV_100[] = { - 0xA9BF2FEA, 0x2A1C03EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, - 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9412968, 0xA8C12FEA + 0xA9BF2FEA, 0x2A1C03EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, + 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9412968, 0xA8C12FEA }; static u32 PRC_ID_SND_200[] = { - 0xA9BF2FEA, 0x2A1803EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B, - 0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9413148, 0xA8C12FEA + 0xA9BF2FEA, 0x2A1803EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B, + 0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9413148, 0xA8C12FEA }; -#define FREE_CODE_OFF_2ND_200 (FREE_CODE_OFF_1ST_200 + sizeof(PRC_ID_SND_200) + 4) + static u32 PRC_ID_RCV_200[] = { - 0xA9BF2FEA, 0x2A0F03EA, 0xD37EF54A, 0xF9405FEB, 0xF86A696A, 0xF9407BEB, 0x92FFFFE9, 0x8A090148, - 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9413168, 0xA8C12FEA + 0xA9BF2FEA, 0x2A0F03EA, 0xD37EF54A, 0xF9405FEB, 0xF86A696A, 0xF9407BEB, 0x92FFFFE9, 0x8A090148, + 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9413168, 0xA8C12FEA }; static u32 PRC_ID_SND_300[] = { - 0xA9BF2FEA, 0x2A1803EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B, - 0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9415548, 0xA8C12FEA + 0xA9BF2FEA, 0x2A1803EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B, + 0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9415548, 0xA8C12FEA }; -#define FREE_CODE_OFF_2ND_300 (FREE_CODE_OFF_1ST_300 + sizeof(PRC_ID_SND_300) + 4) + static u32 PRC_ID_RCV_300[] = { - 0xA9BF2FEA, 0x2A0F03EA, 0xD37EF54A, 0xF9405FEB, 0xF86A696A, 0xF9407BEB, 0x92FFFFE9, 0x8A090148, - 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415568, 0xA8C12FEA + 0xA9BF2FEA, 0x2A0F03EA, 0xD37EF54A, 0xF9405FEB, 0xF86A696A, 0xF9407BEB, 0x92FFFFE9, 0x8A090148, + 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415568, 0xA8C12FEA }; static u32 PRC_ID_SND_302[] = { - 0xA9BF2FEA, 0x2A1803EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B, - 0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9415548, 0xA8C12FEA + 0xA9BF2FEA, 0x2A1803EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B, + 0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9415548, 0xA8C12FEA }; -#define FREE_CODE_OFF_2ND_302 (FREE_CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_302) + 4) + static u32 PRC_ID_RCV_302[] = { - 0xA9BF2FEA, 0x2A0F03EA, 0xD37EF54A, 0xF9405FEB, 0xF86A696A, 0xF9407BEB, 0x92FFFFE9, 0x8A090148, - 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415568, 0xA8C12FEA + 0xA9BF2FEA, 0x2A0F03EA, 0xD37EF54A, 0xF9405FEB, 0xF86A696A, 0xF9407BEB, 0x92FFFFE9, 0x8A090148, + 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415568, 0xA8C12FEA }; static u32 PRC_ID_SND_400[] = { - 0x2A1703EA, 0xD37EF54A, 0xF86A6B8A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, - 0xEB09015F, 0x54000060, 0xF94053EA, 0xF9415948, 0xF94053EA + 0x2A1703EA, 0xD37EF54A, 0xF86A6B8A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, + 0xEB09015F, 0x54000060, 0xF94053EA, 0xF9415948, 0xF94053EA }; -#define FREE_CODE_OFF_2ND_400 (FREE_CODE_OFF_1ST_400 + sizeof(PRC_ID_SND_400) + 4) + static u32 PRC_ID_RCV_400[] = { - 0xF9403BED, 0x2A0E03EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, - 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415B28, 0xD503201F + 0xF9403BED, 0x2A0E03EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, + 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415B28, 0xD503201F }; static u32 PRC_ID_SND_500[] = { - 0x2A1703EA, 0xD37EF54A, 0xF86A6B6A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, - 0xEB09015F, 0x54000060, 0xF94043EA, 0xF9415948, 0xF94043EA + 0x2A1703EA, 0xD37EF54A, 0xF86A6B6A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, + 0xEB09015F, 0x54000060, 0xF94043EA, 0xF9415948, 0xF94043EA }; -#define FREE_CODE_OFF_2ND_500 (FREE_CODE_OFF_1ST_500 + sizeof(PRC_ID_SND_500) + 4) + static u32 PRC_ID_RCV_500[] = { - 0xF9403BED, 0x2A1503EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, - 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415B08, 0xF9406FEA + 0xF9403BED, 0x2A1503EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, + 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415B08, 0xF9406FEA }; static u32 PRC_ID_SND_600[] = { - 0x2A1703EA, 0xD37EF54A, 0xF86A6B6A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, - 0xEB09015F, 0x54000060, 0xF94043EA, 0xF9415948, 0xF94043EA -}; -#define FREE_CODE_OFF_2ND_600 (FREE_CODE_OFF_1ST_600 + sizeof(PRC_ID_SND_600) + 4) -static u32 PRC_ID_RCV_600[] = -{ - 0xF9403BED, 0x2A1503EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, - 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415B08, 0xF9406FEA -}; - - -static kernel_patch_t kern1[] = { - { SVC_VERIFY_DS, 0x3764C, _NOP(), NULL }, // Disable SVC verifications - { DEBUG_MODE_EN, 0x44074, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch - // Atmosphère kernel patches. - { ATM_GEN_PATCH, ID_SND_OFF_100, _B(ID_SND_OFF_100, FREE_CODE_OFF_1ST_100), NULL}, // Send process id branch. - { ATM_ARR_PATCH, FREE_CODE_OFF_1ST_100, sizeof(PRC_ID_SND_100) >> 2, PRC_ID_SND_100}, // Send process id code. - { ATM_GEN_PATCH, FREE_CODE_OFF_1ST_100 + sizeof(PRC_ID_SND_100), // Branch back and skip 1 instruction. - _B(FREE_CODE_OFF_1ST_100 + sizeof(PRC_ID_SND_100), ID_SND_OFF_100 + 4), NULL}, - { ATM_GEN_PATCH, ID_RCV_OFF_100, _B(ID_RCV_OFF_100, FREE_CODE_OFF_2ND_100), NULL}, // Receive process id branch. - { ATM_ARR_PATCH, FREE_CODE_OFF_2ND_100, sizeof(PRC_ID_RCV_100) >> 2, PRC_ID_RCV_100}, // Receive process id code. - { ATM_GEN_PATCH, FREE_CODE_OFF_2ND_100 + sizeof(PRC_ID_RCV_100), // Branch back and skip 1 instruction. - _B(FREE_CODE_OFF_2ND_100 + sizeof(PRC_ID_RCV_100), ID_RCV_OFF_100 + 4), NULL}, - {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, (u32*)0xFFFFFFFF} + 0xA9BF2FEA, 0xF94037EB, 0x2A1503EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0 }; -static kernel_patch_t kern2[] = { - { SVC_VERIFY_DS, 0x54834, _NOP(), NULL }, // Disable SVC verifications - { DEBUG_MODE_EN, 0x6086C, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch - // Atmosphère kernel patches. - { ATM_GEN_PATCH, ID_SND_OFF_200, _B(ID_SND_OFF_200, FREE_CODE_OFF_1ST_200), NULL}, // Send process id branch. - { ATM_ARR_PATCH, FREE_CODE_OFF_1ST_200, sizeof(PRC_ID_SND_200) >> 2, PRC_ID_SND_200}, // Send process id code. - { ATM_GEN_PATCH, FREE_CODE_OFF_1ST_200 + sizeof(PRC_ID_SND_200), // Branch back and skip 1 instruction. - _B(FREE_CODE_OFF_1ST_200 + sizeof(PRC_ID_SND_200), ID_SND_OFF_200 + 4), NULL}, - { ATM_GEN_PATCH, ID_RCV_OFF_200, _B(ID_RCV_OFF_200, FREE_CODE_OFF_2ND_200), NULL}, // Receive process id branch. - { ATM_ARR_PATCH, FREE_CODE_OFF_2ND_200, sizeof(PRC_ID_RCV_200) >> 2, PRC_ID_RCV_200}, // Receive process id code. - { ATM_GEN_PATCH, FREE_CODE_OFF_2ND_200 + sizeof(PRC_ID_RCV_200), // Branch back and skip 1 instruction. - _B(FREE_CODE_OFF_2ND_200 + sizeof(PRC_ID_RCV_200), ID_RCV_OFF_200 + 4), NULL}, - {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, (u32*)0xFFFFFFFF} -}; -static kernel_patch_t kern3[] = { - { SVC_VERIFY_DS, 0x3BD24, _NOP(), NULL }, // Disable SVC verifications - { DEBUG_MODE_EN, 0x483FC, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch - // Atmosphère kernel patches. - { ATM_GEN_PATCH, ID_SND_OFF_300, _B(ID_SND_OFF_300, FREE_CODE_OFF_1ST_300), NULL}, // Send process id branch. - { ATM_ARR_PATCH, FREE_CODE_OFF_1ST_300, sizeof(PRC_ID_SND_300) >> 2, PRC_ID_SND_300}, // Send process id code. - { ATM_GEN_PATCH, FREE_CODE_OFF_1ST_300 + sizeof(PRC_ID_SND_300), // Branch back and skip 1 instruction. - _B(FREE_CODE_OFF_1ST_300 + sizeof(PRC_ID_SND_300), ID_SND_OFF_300 + 4), NULL}, - { ATM_GEN_PATCH, ID_RCV_OFF_300, _B(ID_RCV_OFF_300, FREE_CODE_OFF_2ND_300), NULL}, // Receive process id branch. - { ATM_ARR_PATCH, FREE_CODE_OFF_2ND_300, sizeof(PRC_ID_RCV_300) >> 2, PRC_ID_RCV_300}, // Receive process id code. - { ATM_GEN_PATCH, FREE_CODE_OFF_2ND_300 + sizeof(PRC_ID_RCV_300), // Branch back and skip 1 instruction. - _B(FREE_CODE_OFF_2ND_300 + sizeof(PRC_ID_RCV_300), ID_RCV_OFF_300 + 4), NULL}, - {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, (u32*)0xFFFFFFFF} -}; -static kernel_patch_t kern302[] = { - { SVC_VERIFY_DS, 0x3BD24, _NOP(), NULL }, // Disable SVC verifications - { DEBUG_MODE_EN, 0x48414, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch - // Atmosphère kernel patches. - { ATM_GEN_PATCH, ID_SND_OFF_302, _B(ID_SND_OFF_302, FREE_CODE_OFF_1ST_302), NULL}, // Send process id branch. - { ATM_ARR_PATCH, FREE_CODE_OFF_1ST_302, sizeof(PRC_ID_SND_302) >> 2, PRC_ID_SND_302}, // Send process id code. - { ATM_GEN_PATCH, FREE_CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_302), // Branch back and skip 1 instruction. - _B(FREE_CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_302), ID_SND_OFF_302 + 4), NULL}, - { ATM_GEN_PATCH, ID_RCV_OFF_302, _B(ID_RCV_OFF_302, FREE_CODE_OFF_2ND_302), NULL}, // Receive process id branch. - { ATM_ARR_PATCH, FREE_CODE_OFF_2ND_302, sizeof(PRC_ID_RCV_302) >> 2, PRC_ID_RCV_302}, // Receive process id code. - { ATM_GEN_PATCH, FREE_CODE_OFF_2ND_302 + sizeof(PRC_ID_RCV_302), // Branch back and skip 1 instruction. - _B(FREE_CODE_OFF_2ND_302 + sizeof(PRC_ID_RCV_302), ID_RCV_OFF_302 + 4), NULL}, - {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, (u32*)0xFFFFFFFF} -}; -static kernel_patch_t kern4[] = { - { SVC_VERIFY_DS, 0x41EB4, _NOP(), NULL }, // Disable SVC verifications - { DEBUG_MODE_EN, 0x4EBFC, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch - // Atmosphère kernel patches. - { ATM_GEN_PATCH, ID_SND_OFF_400, _B(ID_SND_OFF_400, FREE_CODE_OFF_1ST_400), NULL}, // Send process id branch. - { ATM_ARR_PATCH, FREE_CODE_OFF_1ST_400, sizeof(PRC_ID_SND_400) >> 2, PRC_ID_SND_400}, // Send process id code. - { ATM_GEN_PATCH, FREE_CODE_OFF_1ST_400 + sizeof(PRC_ID_SND_400), // Branch back and skip 2 instructions. - _B(FREE_CODE_OFF_1ST_400 + sizeof(PRC_ID_SND_400), ID_SND_OFF_400 + 8), NULL}, - { ATM_GEN_PATCH, ID_RCV_OFF_400, _B(ID_RCV_OFF_400, FREE_CODE_OFF_2ND_400), NULL}, // Receive process id branch. - { ATM_ARR_PATCH, FREE_CODE_OFF_2ND_400, sizeof(PRC_ID_RCV_400) >> 2, PRC_ID_RCV_400}, // Receive process id code. - { ATM_GEN_PATCH, FREE_CODE_OFF_2ND_400 + sizeof(PRC_ID_RCV_400), // Branch back and skip 1 instruction. - _B(FREE_CODE_OFF_2ND_400 + sizeof(PRC_ID_RCV_400), ID_RCV_OFF_400 + 4), NULL}, - {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, (u32*)0xFFFFFFFF} -}; - -static kernel_patch_t kern5[] = { - { SVC_VERIFY_DS, 0x45E6C, _NOP(), NULL }, // Disable SVC verifications - { DEBUG_MODE_EN, 0x5513C, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch - // Atmosphère kernel patches. - { ATM_GEN_PATCH, ID_SND_OFF_500, _B(ID_SND_OFF_500, FREE_CODE_OFF_1ST_500), NULL}, // Send process id branch. - { ATM_ARR_PATCH, FREE_CODE_OFF_1ST_500, sizeof(PRC_ID_SND_500) >> 2, PRC_ID_SND_500}, // Send process id code. - { ATM_GEN_PATCH, FREE_CODE_OFF_1ST_500 + sizeof(PRC_ID_SND_500), // Branch back and skip 2 instructions. - _B(FREE_CODE_OFF_1ST_500 + sizeof(PRC_ID_SND_500), ID_SND_OFF_500 + 8), NULL}, - { ATM_GEN_PATCH, ID_RCV_OFF_500, _B(ID_RCV_OFF_500, FREE_CODE_OFF_2ND_500), NULL}, // Receive process id branch. - { ATM_ARR_PATCH, FREE_CODE_OFF_2ND_500, sizeof(PRC_ID_RCV_500) >> 2, PRC_ID_RCV_500}, // Receive process id code. - { ATM_GEN_PATCH, FREE_CODE_OFF_2ND_500 + sizeof(PRC_ID_RCV_500), // Branch back and skip 2 instructions. - _B(FREE_CODE_OFF_2ND_500 + sizeof(PRC_ID_RCV_500), ID_RCV_OFF_500 + 8), NULL}, - {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, (u32*)0xFFFFFFFF} -}; - -static kernel_patch_t kern6[] = { - { SVC_VERIFY_DS, 0x47EA0, _NOP(), NULL }, // Disable SVC verifications - { DEBUG_MODE_EN, 0x57548, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch - // Atmosphère kernel patches. - /*{ ATM_GEN_PATCH, ID_SND_OFF_600, _B(ID_SND_OFF_600, FREE_CODE_OFF_1ST_600), NULL}, // Send process id branch. - { ATM_ARR_PATCH, FREE_CODE_OFF_1ST_600, sizeof(PRC_ID_SND_600) >> 2, PRC_ID_SND_600}, // Send process id code. - { ATM_GEN_PATCH, FREE_CODE_OFF_1ST_600 + sizeof(PRC_ID_SND_600), // Branch back and skip 2 instructions. - _B(FREE_CODE_OFF_1ST_600 + sizeof(PRC_ID_SND_600), ID_SND_OFF_600 + 8), NULL}, - { ATM_GEN_PATCH, ID_RCV_OFF_600, _B(ID_RCV_OFF_600, FREE_CODE_OFF_2ND_600), NULL}, // Receive process id branch. - { ATM_ARR_PATCH, FREE_CODE_OFF_2ND_600, sizeof(PRC_ID_RCV_600) >> 2, PRC_ID_RCV_600}, // Receive process id code. - { ATM_GEN_PATCH, FREE_CODE_OFF_2ND_600 + sizeof(PRC_ID_RCV_600), // Branch back and skip 2 instructions. - _B(FREE_CODE_OFF_2ND_600 + sizeof(PRC_ID_RCV_600), ID_RCV_OFF_600 + 8), NULL},*/ - {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, (u32*)0xFFFFFFFF} -}; - -static const pkg2_kernel_id_t _pkg2_kernel_ids[] = +static u32 PRC_ID_RCV_600[] = { - { 0x427f2647, kern1 }, //1.0.0 - { 0xae19cf1b, kern2 }, //2.0.0 - 2.3.0 - { 0x73c9e274, kern3 }, //3.0.0 - 3.0.1 - { 0xe0e8cdc4, kern302 }, //3.0.2 - { 0x485d0157, kern4 }, //4.0.0 - 4.1.0 - { 0xf3c363f2, kern5 }, //5.0.0 - 5.1.0 - { 0x64ce1a44, kern6 }, //6.0.0 - { 0, 0 } //End. + 0xA9BF2FEA, 0xF94043EB, 0x2A1503EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0 }; typedef struct kipdiff_s { @@ -390,4 +224,5 @@ void buildFirmwarePackage(u8 *kernel, u32 kernel_size, link_t *kips_info); size_t calcKipSize(pkg2_kip1_t *kip1); void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2); void loadKip(link_t *info, char *path); -const pkg2_kernel_id_t *pkg2_identify(u32 id); \ No newline at end of file +u32 *getSndPayload(u32 id, size_t *size); +u32 *getRcvPayload(u32 id, size_t *size); \ No newline at end of file