Permalink
Browse files

Partial 7.0 support

  • Loading branch information...
Reisyukaku committed Feb 3, 2019
1 parent e3c5c63 commit 80095f252597d4006d15f09c6866fd9efe0ef893
Showing with 162 additions and 117 deletions.
  1. +1 −1 NX_Sysmodules
  2. +2 −1 src/bootloader.c
  3. +9 −8 src/bootloader.h
  4. +45 −105 src/firmware.c
  5. +2 −1 src/hwinit/types.h
  6. +103 −1 src/package.h
@@ -305,8 +305,9 @@ void setup() {
sdram_lp0_save_params(sdram_get_params());

// Check if power off from HOS and shutdown
if (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_IRQTOP) & MAX77620_IRQ_TOP_RTC_MASK)
if (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_IRQTOP) & MAX77620_IRQ_TOP_RTC_MASK) {
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF);
}

}

@@ -19,14 +19,15 @@

// TODO: Maybe find these with memsearch
static const pk11_offs _pk11_offs[] = {
{ KB_FIRMWARE_VERSION_100, 0x1900, 0x3FE0, { 2, 1, 0 }, 0x40014020, 0x8000D000, 1 }, //1.0.0
{ KB_FIRMWARE_VERSION_200, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, 1 }, //2.0.0 - 2.3.0
{ KB_FIRMWARE_VERSION_300, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, 1 }, //3.0.0
{ KB_FIRMWARE_VERSION_301, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, 1 }, //3.0.1 - 3.0.2
{ KB_FIRMWARE_VERSION_400, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, 0 }, //4.0.0 - 4.1.0
{ KB_FIRMWARE_VERSION_500, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, 0 }, //5.0.0 - 5.0.2
{ KB_FIRMWARE_VERSION_600, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, 0 }, //6.0.0
{ KB_FIRMWARE_VERSION_620, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, 0 }, //6.2.0
{ KB_FIRMWARE_VERSION_100, 0x1900, 0x3FE0, { 2, 1, 0 }, 0x40014020, 0x8000D000 }, //1.0.0
{ KB_FIRMWARE_VERSION_200, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000 }, //2.0.0 - 2.3.0
{ KB_FIRMWARE_VERSION_300, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000 }, //3.0.0
{ KB_FIRMWARE_VERSION_301, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000 }, //3.0.1 - 3.0.2
{ KB_FIRMWARE_VERSION_400, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000 }, //4.0.0 - 4.1.0
{ KB_FIRMWARE_VERSION_500, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000 }, //5.0.0 - 5.0.2
{ KB_FIRMWARE_VERSION_600, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800 }, //6.0.0
{ KB_FIRMWARE_VERSION_620, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800 }, //6.2.0
{ KB_FIRMWARE_VERSION_700, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x4002B000, 0x4003E000 }, //7.0.0
{ NULL } // End.
};

@@ -102,6 +102,8 @@ void patchWarmboot(u32 warmbootBase) {
*fuseCheck = NOP_v7;
if(segmentID != NULL)
*segmentID = NOP_v7;
}else{
print("Using custom warmboot.\n");
}
}

@@ -235,116 +237,51 @@ void patchSecmon(u32 secmonBase, u32 fw){
*ver_ptr = NOP_v8;
*hdrsig_ptr = NOP_v8;
*sha2_ptr = NOP_v8;
}else{
print("Using custom secmon.\n");
}
}

void patchKernel(pkg2_hdr_t *pkg2){
print("Patching Kernel...\n");
//Patch Kernel
if(!customKern) {
u32 crc = crc32c(pkg2->data, pkg2->sec_size[PKG2_SEC_KERNEL]);
u8 hash[0x20];
se_calc_sha256(hash, pkg2->data, pkg2->sec_size[PKG2_SEC_KERNEL]);
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;
}
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;
uPtr sendOff, recvOff, codeRcvOff, codeSndOff, svcVerifOff, svcDebugOff;

int i; for(i = 0; i < sizeof(kernelInfo)/sizeof(KernelMeta); i++) {
if(memcmp(hash, kernelInfo[i].Hash, 0x20)) continue;
print("Patching kernel %d\n", i);

//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(i, &payloadSize);
*(vu32*)(kern + kernelInfo[i].SendOff) = _B(kernelInfo[i].SendOff, freeSpace); //write hook to payload
memcpy((void*)(kern + freeSpace), sndPayload, payloadSize); //Copy payload to free space
*(vu32*)(kern + freeSpace + payloadSize) = _B(freeSpace + payloadSize, kernelInfo[i].SendOff + kernelInfo[i].CodeSndOff); //Jump back skipping the hook

//ID Receive
freeSpace += (payloadSize+4);
u32 *rcvPayload = getRcvPayload(i, &payloadSize);
*(vu32*)(kern + kernelInfo[i].RcvOff) = _B(kernelInfo[i].RcvOff, freeSpace);
memcpy((void*)(kern + freeSpace), rcvPayload, payloadSize);
*(vu32*)(kern + freeSpace + payloadSize) = _B(freeSpace + payloadSize, kernelInfo[i].RcvOff + kernelInfo[i].CodeRcvOff);

//SVC patches
*(vu32*)(kern + kernelInfo[i].SvcVerify) = NOP_v8;
if (fopen("/ReiNX/debug", "rb")) {
fclose();
*(vu32*)(kern + kernelInfo[i].SvcDebug) = _MOVZX(8, 1, 0);
}
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_v8;
if (fopen("/ReiNX/debug", "rb")) {
fclose();
*(vu32*)(kern + svcDebugOff) = _MOVZX(8, 1, 0);

break;
}

end:;
}else{
print("Using custom kernel.\n");
}
}

@@ -369,6 +306,7 @@ void patchKernelExtensions(link_t *kips){
}

u8 loadFirm() {
print("%k\nSetting up HOS:\n%k", WHITE, DEFAULT_TEXT_COL);
sdmmc_storage_t storage;
sdmmc_t sdmmc;

@@ -400,11 +338,11 @@ u8 loadFirm() {
u8 *keyblob = (u8 *)malloc(NX_EMMC_BLOCKSIZE);
sdmmc_storage_read(&storage, 0x180000 / NX_EMMC_BLOCKSIZE + pk11Offs->kb, 1, keyblob);
if(!keygen(keyblob, pk11Offs->kb, pkg1ldr, pk11Offs))
print("Failed to keygen...\n");
print("Failed to keygen...\n");
free(keyblob);
//Decrypt if needed
if(pk11Offs->kb < KB_FIRMWARE_VERSION_620)
se_aes_crypt_ctr(11, pkg11 + 0x20, pkg11_size, pkg11 + 0x20, pkg11_size, pkg11 + 0x10);
se_aes_crypt_ctr(11, pkg11 + 0x20, pkg11_size, pkg11 + 0x20, pkg11_size, pkg11 + 0x10);

print("Unpacking pkg1\n");
pkg1_unpack(pk11Offs, (u32)pkg11);
@@ -421,6 +359,7 @@ u8 loadFirm() {
pkg2_parse_kips(&kip1_info, dec_pkg2);

// Patch firmware.
print("%k\nPatching HOS:\n%k", WHITE, DEFAULT_TEXT_COL);
patchWarmboot(pk11Offs->warmboot_base);
patchSecmon(pk11Offs->secmon_base, pk11Offs->kb);
patchKernel(dec_pkg2);
@@ -448,6 +387,8 @@ static void SE_lock() {
}

void launch() {
print("%k\nLaunching HOS!\n%k", GREEN, DEFAULT_TEXT_COL);

se_aes_key_clear(0x8);
se_aes_key_clear(0xB);

@@ -563,12 +504,11 @@ void firmware() {
}

if (btn_read() & BTN_VOL_DOWN) {
print("Booting verbosely\n");
print("%kWelcome to ReiNX %s!\n%k", WHITE, VERSION, DEFAULT_TEXT_COL);
} else if (drawSplash()) {
gfx_con.mute = 1;
}

print("Welcome to ReiNX %s!\n", VERSION);
loadFirm();
launch();
}
}
@@ -55,7 +55,8 @@ enum KB_FIRMWARE_VERSION {
KB_FIRMWARE_VERSION_400 = 3,
KB_FIRMWARE_VERSION_500 = 4,
KB_FIRMWARE_VERSION_600 = 5,
KB_FIRMWARE_VERSION_620 = 6
KB_FIRMWARE_VERSION_620 = 6,
KB_FIRMWARE_VERSION_700 = 7
};

#endif
@@ -94,7 +94,6 @@ typedef struct {
u32 sec_map[3];
u32 secmon_base;
u32 warmboot_base;
int set_warmboot;
} pk11_offs;

typedef struct {
@@ -211,8 +210,111 @@ static u32 PRC_ID_RCV_600[] =
0xA9BF2FEA, 0xF94043EB, 0x2A1503EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};

static u32 PRC_ID_SND_700[] =
{
0xA9BF2FEA, 0xF9403BEB, 0x2A1903EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002A8, 0xF9401D08, 0xAA1503E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};

static u32 PRC_ID_RCV_700[] =
{
0xA9BF2FEA, 0xF9404FEB, 0x2A1603EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400368, 0xF9401D08, 0xAA1B03E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};

extern kippatchset_t kip_patches[];

typedef struct {
u8 Hash[0x20];
u32 SvcVerify;
u32 SvcDebug;
u32 SendOff;
u32 RcvOff;
u8 CodeSndOff;
u8 CodeRcvOff;
} KernelMeta;

static const KernelMeta kernelInfo[] = {
{ //1.0.0
{0xB8, 0xC5, 0x0C, 0x68, 0x25, 0xA9, 0xB9, 0x5B, 0xD2, 0x4D, 0x2C, 0x7C, 0x81, 0x7F, 0xE6, 0x96,
0xF2, 0x42, 0x4E, 0x1D, 0x78, 0xDF, 0x3B, 0xCA, 0x3D, 0x6B, 0x68, 0x12, 0xDD, 0xA9, 0xCB, 0x9C},
0x3764C,
0x44074,
0x23CC0,
0x219F0,
4,
4
},
{ //2.0.0
{0x64, 0x0B, 0x51, 0xFF, 0x28, 0x01, 0xB8, 0x30, 0xA7, 0xA3, 0x60, 0x47, 0x86, 0x0D, 0x68, 0xAA,
0x9A, 0x92, 0x10, 0x0D, 0xB9, 0xCC, 0xEC, 0x8B, 0x05, 0x80, 0x73, 0xBD, 0x33, 0xB4, 0x2C, 0x6C},
0x54834,
0x6086C,
0x3F134,
0x3D1A8,
4,
4
},
{ //3.0.0
{0x50, 0x84, 0x23, 0xAC, 0x6F, 0xA1, 0x5D, 0x3B, 0x56, 0xC2, 0xFC, 0x95, 0x22, 0xCC, 0xD5, 0xA8,
0x15, 0xD3, 0xB4, 0x6B, 0xA1, 0x2C, 0xF2, 0x93, 0xD3, 0x02, 0x05, 0xAB, 0x52, 0xEF, 0x73, 0xC5},
0x3BD24,
0x483FC,
0x26080,
0x240F0,
4,
4
},
{ //3.0.2
{0x81, 0x9D, 0x08, 0xBE, 0xE4, 0x5E, 0x1F, 0xBB, 0x45, 0x5A, 0x6D, 0x70, 0x4B, 0xB2, 0x17, 0xA6,
0x12, 0x69, 0xF8, 0xB8, 0x75, 0x1C, 0x71, 0x16, 0xF0, 0xE9, 0x79, 0x7F, 0xB0, 0xD1, 0x78, 0xB2},
0x3BD24,
0x48414,
0x26080,
0x240F0,
4,
4
},
{ //4.0.0
{0xE6, 0xC0, 0xB7, 0xE3, 0x2F, 0xF9, 0x44, 0x51, 0xEC, 0xD5, 0x95, 0x79, 0xE3, 0x46, 0xB1, 0xDA,
0x2E, 0xD9, 0x28, 0xC6, 0xF2, 0x31, 0x4F, 0x95, 0xD8, 0xC7, 0xD5, 0xBD, 0x15, 0xD5, 0xE2, 0x5A},
0x41EB4,
0x4EBFC,
0x2AF64,
0x28F6C,
8,
4
},
{ //5.0.0
{0xB2, 0x38, 0x61, 0xA8, 0xE1, 0xE2, 0xE4, 0xE4, 0x17, 0x28, 0xED, 0xA9, 0xF6, 0xF6, 0xBD, 0xD2,
0x59, 0xDB, 0x1F, 0xEF, 0x4A, 0x8B, 0x2F, 0x1C, 0x64, 0x46, 0x06, 0x40, 0xF5, 0x05, 0x9C, 0x43},
0x45E6C,
0x5513C,
0x2AD34,
0x28DAC,
8,
8
},
{ //6.0.0
{0x85, 0x97, 0x40, 0xF6, 0xC0, 0x3E, 0x3D, 0x44, 0xDE, 0xA4, 0xA0, 0x35, 0xFD, 0x12, 0x9C, 0xD4,
0x4F, 0x9C, 0x36, 0x53, 0x74, 0x54, 0x2C, 0x9C, 0x55, 0x47, 0xC4, 0x25, 0xF1, 0x42, 0xFB, 0x97},
0x47EA0,
0x57548,
0x2BB8C,
0x29B6C,
0x10,
0x10
},
{ //7.0.0
{0xA2, 0x5E, 0x47, 0x0C, 0x8E, 0x6D, 0x2F, 0xD7, 0x5D, 0xAD, 0x24, 0xD7, 0xD8, 0x24, 0x34, 0xFB,
0xCD, 0x77, 0xBB, 0xE6, 0x66, 0x03, 0xCB, 0xAF, 0xAB, 0x85, 0x45, 0xA0, 0x91, 0xAF, 0x34, 0x25},
0,
0,
0,
0,
0x10,
0x10
},
};

u8 *ReadBoot0(sdmmc_storage_t *storage);
u8 *ReadPackage1Ldr(sdmmc_storage_t *storage);
u8 *ReadPackage2(sdmmc_storage_t *storage);

0 comments on commit 80095f2

Please sign in to comment.