Skip to content
Permalink
Browse files

Add INI1 relocation on 8.0, fix kernel hash being different between e…

…xFAT and FAT32 firmware of 8.0
  • Loading branch information...
EliseZeroTwo committed Apr 21, 2019
1 parent 9186c4b commit afb7cabcf6480bcc4d26364c2b845c385926ef92
Showing with 82 additions and 15 deletions.
  1. +1 −0 septchainloader/src/hwinit/sdmmc_driver.c
  2. +33 −1 src/firmware.c
  3. +3 −1 src/package.c
  4. +32 −12 src/package.h
  5. +13 −1 src/patches.c
@@ -1027,6 +1027,7 @@ void sdmmc_end(sdmmc_t *sdmmc)
{
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);
musleep(1); // To power cycle min 1ms without power is needed.
max77620_regulator_enable(REGULATOR_LDO2, 0);
}

_sdmmc_get_clkcon(sdmmc);
@@ -126,12 +126,44 @@ u8 loadFirm() {

//Read package2
size_t pkg2_size = 0;
u8 *pkg2 = ReadPackage2(&storage);
u8 *pkg2 = ReadPackage2(&storage, &pkg2_size);

// Unpack Package2.
print("Unpacking package2...\n");

pkg2_hdr_t *dec_pkg2 = unpackFirmwarePackage(pkg2);
//If firmware is 8.0, remake package2 by moving ini1 into its section from kernel
//TODO: find better way to differentiate the firmware version that isn't TSEC firmware offset
if (pk11Offs->tsec_off == 0xE00 && pk11Offs->kb == KB_FIRMWARE_VERSION_800) {
pkg2_ini1_t *old_ini1 = (pkg2_ini1_t *)(dec_pkg2->data + 0x95000);
*((vu64 *)((uPtr)dec_pkg2->data + 0x168)) = (u64)dec_pkg2->sec_size[0];

dec_pkg2->sec_off[PKG2_SEC_INI1] = dec_pkg2->sec_off[PKG2_SEC_KERNEL] + dec_pkg2->sec_size[PKG2_SEC_KERNEL];
size_t rebuilt_package2_size = sizeof(pkg2_hdr_t) + dec_pkg2->sec_size[0] + ALIGN(old_ini1->size, 4);

pkg2_hdr_t *new_pkg2 = (pkg2_hdr_t *)malloc(rebuilt_package2_size);

memcpy(new_pkg2, dec_pkg2, sizeof(pkg2_hdr_t));
memcpy(new_pkg2->data, dec_pkg2->data, dec_pkg2->sec_size[0]);
memcpy(new_pkg2->data + dec_pkg2->sec_size[0], old_ini1, old_ini1->size);
new_pkg2->sec_size[1] = ALIGN(old_ini1->size, 4);

uint8_t *data = new_pkg2->data;

for (unsigned int section = 0; section < 3; section++) {
size_t sz = (size_t)new_pkg2->sec_size[section];
if(!sz)
continue;

se_calc_sha256(&(new_pkg2->sec_sha256[section * 0x20]), data, sz);
data += sz;
}

u32 *ctrs = (u32 *)(new_pkg2->ctr);
uint32_t package_size = ctrs[0] ^ ctrs[2] ^ ctrs[3];
ctrs[3] ^= (package_size ^ rebuilt_package2_size);
dec_pkg2 = new_pkg2;
}
print("Parsing kips\n");
LIST_INIT(kip1_info);
pkg2_parse_kips(&kip1_info, dec_pkg2);
@@ -36,7 +36,7 @@ u8 *ReadPackage1Ldr(sdmmc_storage_t *storage) {
return pk11;
}

u8 *ReadPackage2(sdmmc_storage_t *storage) {
u8 *ReadPackage2(sdmmc_storage_t *storage, size_t *out_size) {
// Read GPT partition.
LIST_INIT(gpt);
sdmmc_storage_set_mmc_partition(storage, 0);
@@ -55,6 +55,7 @@ u8 *ReadPackage2(sdmmc_storage_t *storage) {
nx_emmc_part_read(storage, pkg2_part, 0x4000 / NX_EMMC_BLOCKSIZE, 1, tmp);
u32 *hdr = (u32 *)(tmp + 0x100);
u32 pkg2_size = hdr[0] ^ hdr[2] ^ hdr[3];
*out_size = pkg2_size;
free(tmp);
u8 *pkg2 = malloc(ALIGN(pkg2_size, NX_EMMC_BLOCKSIZE));
print("Reading Package2...\n");
@@ -252,6 +253,7 @@ void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2) {
pkg2_kip1_info_t *ki = (pkg2_kip1_info_t *)malloc(sizeof(pkg2_kip1_info_t));
ki->kip1 = kip1;
ki->size = calcKipSize(kip1);
print("Found kip %s of size 0x%x\n", kip1->name, ki->size);
list_append(info, &ki->link);
ptr += ki->size;
}
@@ -238,6 +238,8 @@ typedef struct {
u32 GenericOff;
u8 CodeSndOff;
u8 CodeRcvOff;
size_t hash_offset;
size_t hash_size;
} KernelMeta;

static const KernelMeta kernelInfo[] = {
@@ -250,7 +252,9 @@ static const KernelMeta kernelInfo[] = {
0x219F0,
0,
4,
4
4,
0,
0
},
{ //2.0.0
{0x64, 0x0B, 0x51, 0xFF, 0x28, 0x01, 0xB8, 0x30, 0xA7, 0xA3, 0x60, 0x47, 0x86, 0x0D, 0x68, 0xAA,
@@ -261,7 +265,9 @@ static const KernelMeta kernelInfo[] = {
0x3D1A8,
0,
4,
4
4,
0,
0
},
{ //3.0.0
{0x50, 0x84, 0x23, 0xAC, 0x6F, 0xA1, 0x5D, 0x3B, 0x56, 0xC2, 0xFC, 0x95, 0x22, 0xCC, 0xD5, 0xA8,
@@ -272,7 +278,9 @@ static const KernelMeta kernelInfo[] = {
0x240F0,
0,
4,
4
4,
0,
0
},
{ //3.0.2
{0x81, 0x9D, 0x08, 0xBE, 0xE4, 0x5E, 0x1F, 0xBB, 0x45, 0x5A, 0x6D, 0x70, 0x4B, 0xB2, 0x17, 0xA6,
@@ -283,7 +291,9 @@ static const KernelMeta kernelInfo[] = {
0x240F0,
0,
4,
4
4,
0,
0
},
{ //4.0.0
{0xE6, 0xC0, 0xB7, 0xE3, 0x2F, 0xF9, 0x44, 0x51, 0xEC, 0xD5, 0x95, 0x79, 0xE3, 0x46, 0xB1, 0xDA,
@@ -294,7 +304,9 @@ static const KernelMeta kernelInfo[] = {
0x28F6C,
0,
8,
4
4,
0,
0
},
{ //5.0.0
{0xB2, 0x38, 0x61, 0xA8, 0xE1, 0xE2, 0xE4, 0xE4, 0x17, 0x28, 0xED, 0xA9, 0xF6, 0xF6, 0xBD, 0xD2,
@@ -305,7 +317,9 @@ static const KernelMeta kernelInfo[] = {
0x28DAC,
0x38C2C,
8,
8
8,
0,
0
},
{ //6.0.0
{0x85, 0x97, 0x40, 0xF6, 0xC0, 0x3E, 0x3D, 0x44, 0xDE, 0xA4, 0xA0, 0x35, 0xFD, 0x12, 0x9C, 0xD4,
@@ -316,7 +330,9 @@ static const KernelMeta kernelInfo[] = {
0x29B6C,
0x3A8CC,
0x10,
0x10
0x10,
0,
0
},
{ //7.0.0
{0xA2, 0x5E, 0x47, 0x0C, 0x8E, 0x6D, 0x2F, 0xD7, 0x5D, 0xAD, 0x24, 0xD7, 0xD8, 0x24, 0x34, 0xFB,
@@ -327,24 +343,28 @@ static const KernelMeta kernelInfo[] = {
0x2B23C,
0x3C6E0,
0x10,
0x10
0x10,
0,
0
},
{ //8.0.0
{0x24, 0x2A, 0x50, 0x42, 0xFC, 0x6C, 0x0A, 0x64, 0xE7, 0xC2, 0x16, 0x0F, 0xD8, 0x53, 0x1E, 0xFC,
0x5C, 0x25, 0xCA, 0xC0, 0x5A, 0xED, 0x01, 0xA7, 0xE3, 0x11, 0x78, 0x6C, 0x07, 0x10, 0x32, 0xA1},
{0xA6, 0xAD, 0x5D, 0x7F, 0xCF, 0x25, 0x80, 0xAE, 0xE6, 0x57, 0x9F, 0x6F, 0xC5, 0xC5, 0xF6, 0x13,
0x77, 0x23, 0xAC, 0x88, 0x79, 0x76, 0xF7, 0x25, 0x06, 0x16, 0x35, 0x3B, 0x3F, 0xA7, 0x59, 0x49},
0x4D15C,
0x5BFAC,
0x2F1FC,
0x2D424,
0x3FAD0,
0x10,
0x10
0x10,
0x1A8,
0x95000 - 0x1A8
},
};

u8 *ReadBoot0(sdmmc_storage_t *storage);
u8 *ReadPackage1Ldr(sdmmc_storage_t *storage);
u8 *ReadPackage2(sdmmc_storage_t *storage);
u8 *ReadPackage2(sdmmc_storage_t *storage, size_t *out_size);
int kippatch_apply(u8 *kipdata, u64 kipdata_len, kippatch_t *patch);
int kippatch_apply_set(u8 *kipdata, u64 kipdata_len, kippatchset_t *patchset);
kippatchset_t *kippatch_find_set(u8 *kiphash, kippatchset_t *patchsets);
@@ -226,7 +226,19 @@ void patchKernel(pkg2_hdr_t *pkg2){
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;
if(memcmp(hash, kernelInfo[i].Hash, 0x20)) {
//Due to ini1 being embedded in kernel in firmware 8.0, we cannot hash the entire kernel as the ini1 changes between exFAT firmware versions and FAT32 firmware versions
u8 tmp_hash[0x20];
if ((kernelInfo[i].hash_offset != 0 && kernelInfo[i].hash_size != 0)) {
se_calc_sha256(tmp_hash, pkg2->data + kernelInfo[i].hash_offset, kernelInfo[i].hash_size);
if (!memcmp(tmp_hash, kernelInfo[i].Hash, 0x20))
memcpy(hash, tmp_hash, 0x20);
else
continue;
} else
continue;

}
print("Patching kernel %d\n", i);

//ID Send

0 comments on commit afb7cab

Please sign in to comment.
You can’t perform that action at this time.