mirror of
https://github.com/CTCaer/hekate
synced 2024-11-20 02:49:25 +00:00
[PKG2] Switch kernel patching to crc32c based kernel id
This provides support for the 3.0.2 kernel, where pkg1 has the same id with 3.0.1. Thanks @roblabla for noticing and providing the Debug mode kernel patch.
This commit is contained in:
parent
fb9e91ed0c
commit
b299cb40c7
7 changed files with 116 additions and 57 deletions
33
ipl/hos.c
33
ipl/hos.c
|
@ -74,6 +74,21 @@ static const u8 master_keyseed_4xx[0x10] =
|
||||||
static const u8 console_keyseed_4xx[0x10] =
|
static const u8 console_keyseed_4xx[0x10] =
|
||||||
{ 0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28 };
|
{ 0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28 };
|
||||||
|
|
||||||
|
#define CRC32C_POLY 0x82f63b78
|
||||||
|
|
||||||
|
u32 crc32c(const u8 *buf, u32 len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
u32 crc = 0;
|
||||||
|
|
||||||
|
crc = ~crc;
|
||||||
|
while (len--) {
|
||||||
|
crc ^= *buf++;
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
crc = crc & 1 ? (crc >> 1) ^ CRC32C_POLY : crc >> 1;
|
||||||
|
}
|
||||||
|
return ~crc;
|
||||||
|
}
|
||||||
|
|
||||||
static void _se_lock()
|
static void _se_lock()
|
||||||
{
|
{
|
||||||
|
@ -178,6 +193,7 @@ typedef struct _launch_ctxt_t
|
||||||
|
|
||||||
void *pkg1;
|
void *pkg1;
|
||||||
const pkg1_id_t *pkg1_id;
|
const pkg1_id_t *pkg1_id;
|
||||||
|
const pkg2_kernel_id_t *pkg2_kernel_id;
|
||||||
|
|
||||||
void *warmboot;
|
void *warmboot;
|
||||||
u32 warmboot_size;
|
u32 warmboot_size;
|
||||||
|
@ -413,18 +429,14 @@ int hos_launch(ini_sec_t *cfg)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Else we patch it to allow for an unsigned package2.
|
//Else we patch it to allow for an unsigned package2 and patched kernel.
|
||||||
patch_t *secmon_patchset = ctxt.pkg1_id->secmon_patchset;
|
patch_t *secmon_patchset = ctxt.pkg1_id->secmon_patchset;
|
||||||
//In case a kernel patch option is set. Allows to disable Svc Verififcation or/and enable Debug mode
|
|
||||||
patch_t *kernel_patchset = ctxt.pkg1_id->kernel_patchset;
|
|
||||||
|
|
||||||
if (secmon_patchset != NULL || (kernel_patchset != NULL && (ctxt.svcperm || ctxt.debugmode))) {
|
|
||||||
if (secmon_patchset != NULL)
|
if (secmon_patchset != NULL)
|
||||||
{
|
{
|
||||||
gfx_printf(&gfx_con, "%kPatching Security Monitor%k\n", 0xFF00BAFF, 0xFFCCCCCC);
|
gfx_printf(&gfx_con, "%kPatching Security Monitor%k\n", 0xFF00BAFF, 0xFFCCCCCC);
|
||||||
for (u32 i = 0; secmon_patchset[i].off != 0xFFFFFFFF; i++)
|
for (u32 i = 0; secmon_patchset[i].off != 0xFFFFFFFF; i++)
|
||||||
*(vu32 *)(ctxt.pkg1_id->secmon_base + secmon_patchset[i].off) = secmon_patchset[i].val;
|
*(vu32 *)(ctxt.pkg1_id->secmon_base + secmon_patchset[i].off) = secmon_patchset[i].val;
|
||||||
}
|
|
||||||
|
|
||||||
gfx_printf(&gfx_con, "Loaded warmboot.bin and secmon\n");
|
gfx_printf(&gfx_con, "Loaded warmboot.bin and secmon\n");
|
||||||
|
|
||||||
|
@ -447,7 +459,15 @@ int hos_launch(ini_sec_t *cfg)
|
||||||
ctxt.kernel = pkg2_hdr->data;
|
ctxt.kernel = pkg2_hdr->data;
|
||||||
ctxt.kernel_size = pkg2_hdr->sec_size[PKG2_SEC_KERNEL];
|
ctxt.kernel_size = pkg2_hdr->sec_size[PKG2_SEC_KERNEL];
|
||||||
|
|
||||||
if (kernel_patchset != NULL && (ctxt.svcperm || ctxt.debugmode))
|
if (ctxt.svcperm || ctxt.debugmode)
|
||||||
|
{
|
||||||
|
u32 kernel_crc32 = crc32c((u8 *)ctxt.kernel, ctxt.kernel_size);
|
||||||
|
ctxt.pkg2_kernel_id = pkg2_identify(kernel_crc32);
|
||||||
|
|
||||||
|
//In case a kernel patch option is set. Allows to disable Svc Verififcation or/and enable Debug mode
|
||||||
|
patch_t *kernel_patchset = ctxt.pkg2_kernel_id->kernel_patchset;
|
||||||
|
|
||||||
|
if (kernel_patchset != NULL)
|
||||||
{
|
{
|
||||||
gfx_printf(&gfx_con, "%kPatching kernel%k\n", 0xFF00BAFF, 0xFFCCCCCC);
|
gfx_printf(&gfx_con, "%kPatching kernel%k\n", 0xFF00BAFF, 0xFFCCCCCC);
|
||||||
if (ctxt.svcperm && kernel_patchset[0].off != 0xFFFFFFFF)
|
if (ctxt.svcperm && kernel_patchset[0].off != 0xFFFFFFFF)
|
||||||
|
@ -456,6 +476,7 @@ int hos_launch(ini_sec_t *cfg)
|
||||||
*(vu32 *)(ctxt.kernel + kernel_patchset[1].off) = kernel_patchset[1].val;
|
*(vu32 *)(ctxt.kernel + kernel_patchset[1].off) = kernel_patchset[1].val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Merge extra KIP1s into loaded ones.
|
//Merge extra KIP1s into loaded ones.
|
||||||
gfx_printf(&gfx_con, "%kPatching kernel initial processes%k\n", 0xFF00BAFF, 0xFFCCCCCC);
|
gfx_printf(&gfx_con, "%kPatching kernel initial processes%k\n", 0xFF00BAFF, 0xFFCCCCCC);
|
||||||
|
|
|
@ -792,7 +792,7 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
|
||||||
|
|
||||||
if (!maxSplitParts)
|
if (!maxSplitParts)
|
||||||
{
|
{
|
||||||
EPRINTF("Not enough free space for partial dumping.");
|
EPRINTF("Not enough free space for Partial Backup.");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
38
ipl/pkg1.c
38
ipl/pkg1.c
|
@ -68,32 +68,6 @@ PATCHSET_DEF(_secmon_5_patchset,
|
||||||
//{ 0x12b0 + 0xa18 , _NOP() } // BootConfig Retail Check
|
//{ 0x12b0 + 0xa18 , _NOP() } // BootConfig Retail Check
|
||||||
);
|
);
|
||||||
|
|
||||||
// Include kernel patches here, so we can utilize pkg1 id
|
|
||||||
PATCHSET_DEF(_kernel_1_patchset,
|
|
||||||
{ 0x3764C, _NOP() }, // Disable SVC verifications
|
|
||||||
{ 0x44074, _MOVZX(8, 1, 0) } // Enable Debug Patch
|
|
||||||
);
|
|
||||||
|
|
||||||
PATCHSET_DEF(_kernel_2_patchset,
|
|
||||||
{ 0x54834, _NOP() }, // Disable SVC verifications
|
|
||||||
{ 0x6086C, _MOVZX(8, 1, 0) } // Enable Debug Patch
|
|
||||||
);
|
|
||||||
|
|
||||||
PATCHSET_DEF(_kernel_3_patchset,
|
|
||||||
{ 0x3BD24, _NOP() }, // Disable SVC verifications
|
|
||||||
{ 0x483FC, _MOVZX(8, 1, 0) } // Enable Debug Patch
|
|
||||||
);
|
|
||||||
|
|
||||||
PATCHSET_DEF(_kernel_4_patchset,
|
|
||||||
{ 0x41EB4, _NOP() }, // Disable SVC verifications
|
|
||||||
{ 0x4EBFC, _MOVZX(8, 1, 0) } // Enable Debug Patch
|
|
||||||
);
|
|
||||||
|
|
||||||
PATCHSET_DEF(_kernel_5_patchset,
|
|
||||||
{ 0x45E6C, _NOP() }, // Disable SVC verifications
|
|
||||||
{ 0x5513C, _MOVZX(8, 1, 0) } // Enable Debug Patch
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* package1.1 header: <wb, ldr, sm>
|
* package1.1 header: <wb, ldr, sm>
|
||||||
* package1.1 layout:
|
* package1.1 layout:
|
||||||
|
@ -106,12 +80,12 @@ PATCHSET_DEF(_kernel_5_patchset,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const pkg1_id_t _pkg1_ids[] = {
|
static const pkg1_id_t _pkg1_ids[] = {
|
||||||
{ "20161121183008", 0, 0x1900, 0x3FE0, { 2, 1, 0 }, SM_100_ADR, 0x8000D000, 1, _secmon_1_patchset, _kernel_1_patchset }, //1.0.0 (Patched relocator)
|
{ "20161121183008", 0, 0x1900, 0x3FE0, { 2, 1, 0 }, SM_100_ADR, 0x8000D000, 1, _secmon_1_patchset }, //1.0.0 (Patched relocator)
|
||||||
{ "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, 1, _secmon_2_patchset, _kernel_2_patchset }, //2.0.0 - 2.3.0
|
{ "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, 1, _secmon_2_patchset }, //2.0.0 - 2.3.0
|
||||||
{ "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, 1, _secmon_3_patchset, _kernel_3_patchset }, //3.0.0
|
{ "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, 1, _secmon_3_patchset }, //3.0.0
|
||||||
{ "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, 1, _secmon_3_patchset, _kernel_3_patchset }, //3.0.1 - 3.0.2
|
{ "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, 1, _secmon_3_patchset }, //3.0.1 - 3.0.2
|
||||||
{ "20170921172629", 3, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, 0, _secmon_4_patchset, _kernel_4_patchset }, //4.0.0 - 4.1.0
|
{ "20170921172629", 3, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, 0, _secmon_4_patchset }, //4.0.0 - 4.1.0
|
||||||
{ "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, 0, _secmon_5_patchset, _kernel_5_patchset }, //5.0.0 - 5.0.2
|
{ "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, 0, _secmon_5_patchset }, //5.0.0 - 5.1.0
|
||||||
{ NULL, 0, 0, 0, 0 } //End.
|
{ NULL, 0, 0, 0, 0 } //End.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,12 +25,6 @@
|
||||||
{ 0xFFFFFFFF, 0xFFFFFFFF } \
|
{ 0xFFFFFFFF, 0xFFFFFFFF } \
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct _patch_t
|
|
||||||
{
|
|
||||||
u32 off;
|
|
||||||
u32 val;
|
|
||||||
} patch_t;
|
|
||||||
|
|
||||||
typedef struct _pkg1_id_t
|
typedef struct _pkg1_id_t
|
||||||
{
|
{
|
||||||
const char *id;
|
const char *id;
|
||||||
|
@ -42,7 +36,6 @@ typedef struct _pkg1_id_t
|
||||||
u32 warmboot_base;
|
u32 warmboot_base;
|
||||||
int set_warmboot;
|
int set_warmboot;
|
||||||
patch_t *secmon_patchset;
|
patch_t *secmon_patchset;
|
||||||
patch_t *kernel_patchset;
|
|
||||||
} pkg1_id_t;
|
} pkg1_id_t;
|
||||||
|
|
||||||
typedef struct _pk11_hdr_t
|
typedef struct _pk11_hdr_t
|
||||||
|
|
52
ipl/pkg2.c
52
ipl/pkg2.c
|
@ -25,6 +25,58 @@ extern gfx_con_t gfx_con;
|
||||||
#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)*/
|
#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)*/
|
||||||
#define DPRINTF(...)
|
#define DPRINTF(...)
|
||||||
|
|
||||||
|
#define _MOVZX(r, i, s) 0xD2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)
|
||||||
|
#define _NOP() 0xD503201F
|
||||||
|
|
||||||
|
// Include kernel patches here, so we can utilize pkg1 id
|
||||||
|
PATCHSET_DEF(_kernel_1_patchset,
|
||||||
|
{ 0x3764C, _NOP() }, // Disable SVC verifications
|
||||||
|
{ 0x44074, _MOVZX(8, 1, 0) } // Enable Debug Patch
|
||||||
|
);
|
||||||
|
|
||||||
|
PATCHSET_DEF(_kernel_2_patchset,
|
||||||
|
{ 0x54834, _NOP() }, // Disable SVC verifications
|
||||||
|
{ 0x6086C, _MOVZX(8, 1, 0) } // Enable Debug Patch
|
||||||
|
);
|
||||||
|
|
||||||
|
PATCHSET_DEF(_kernel_3_patchset,
|
||||||
|
{ 0x3BD24, _NOP() }, // Disable SVC verifications
|
||||||
|
{ 0x483FC, _MOVZX(8, 1, 0) } // Enable Debug Patch
|
||||||
|
);
|
||||||
|
|
||||||
|
PATCHSET_DEF(_kernel_302_patchset,
|
||||||
|
{ 0x3BD24, _NOP() }, // Disable SVC verifications
|
||||||
|
{ 0x48414, _MOVZX(8, 1, 0) } // Enable Debug Patch
|
||||||
|
);
|
||||||
|
|
||||||
|
PATCHSET_DEF(_kernel_4_patchset,
|
||||||
|
{ 0x41EB4, _NOP() }, // Disable SVC verifications
|
||||||
|
{ 0x4EBFC, _MOVZX(8, 1, 0) } // Enable Debug Patch
|
||||||
|
);
|
||||||
|
|
||||||
|
PATCHSET_DEF(_kernel_5_patchset,
|
||||||
|
{ 0x45E6C, _NOP() }, // Disable SVC verifications
|
||||||
|
{ 0x5513C, _MOVZX(8, 1, 0) } // Enable Debug Patch
|
||||||
|
);
|
||||||
|
|
||||||
|
static const pkg2_kernel_id_t _pkg2_kernel_ids[] = {
|
||||||
|
{ 0x427f2647, _kernel_1_patchset }, //1.0.0
|
||||||
|
{ 0xae19cf1b, _kernel_2_patchset }, //2.0.0 - 2.3.0
|
||||||
|
{ 0x73c9e274, _kernel_3_patchset }, //3.0.0 - 3.0.1
|
||||||
|
{ 0xe0e8cdc4, _kernel_302_patchset }, //3.0.2
|
||||||
|
{ 0x485d0157, _kernel_4_patchset }, //4.0.0 - 4.1.0
|
||||||
|
{ 0xf3c363f2, _kernel_5_patchset }, //5.0.0 - 5.1.0
|
||||||
|
{ 0, 0 } //End.
|
||||||
|
};
|
||||||
|
|
||||||
|
const pkg2_kernel_id_t *pkg2_identify(u32 id)
|
||||||
|
{
|
||||||
|
for (u32 i = 0; _pkg2_kernel_ids[i].crc32c_id; i++)
|
||||||
|
if (id == _pkg2_kernel_ids[i].crc32c_id)
|
||||||
|
return &_pkg2_kernel_ids[i];
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static u32 _pkg2_calc_kip1_size(pkg2_kip1_t *kip1)
|
static u32 _pkg2_calc_kip1_size(pkg2_kip1_t *kip1)
|
||||||
{
|
{
|
||||||
u32 size = sizeof(pkg2_kip1_t);
|
u32 size = sizeof(pkg2_kip1_t);
|
||||||
|
|
13
ipl/pkg2.h
13
ipl/pkg2.h
|
@ -27,6 +27,12 @@
|
||||||
|
|
||||||
#define INI1_MAGIC 0x31494E49
|
#define INI1_MAGIC 0x31494E49
|
||||||
|
|
||||||
|
#define PATCHSET_DEF(name, ...) \
|
||||||
|
patch_t name[] = { \
|
||||||
|
__VA_ARGS__, \
|
||||||
|
{ 0xFFFFFFFF, 0xFFFFFFFF } \
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct _pkg2_hdr_t
|
typedef struct _pkg2_hdr_t
|
||||||
{
|
{
|
||||||
u8 ctr[0x10];
|
u8 ctr[0x10];
|
||||||
|
@ -82,12 +88,19 @@ typedef struct _pkg2_kip1_info_t
|
||||||
link_t link;
|
link_t link;
|
||||||
} pkg2_kip1_info_t;
|
} pkg2_kip1_info_t;
|
||||||
|
|
||||||
|
typedef struct _pkg2_kernel_id_t
|
||||||
|
{
|
||||||
|
u32 crc32c_id;
|
||||||
|
patch_t *kernel_patchset;
|
||||||
|
} pkg2_kernel_id_t;
|
||||||
|
|
||||||
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2);
|
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2);
|
||||||
int pkg2_has_kip(link_t *info, u64 tid);
|
int pkg2_has_kip(link_t *info, u64 tid);
|
||||||
void pkg2_replace_kip(link_t *info, u64 tid, pkg2_kip1_t *kip1);
|
void pkg2_replace_kip(link_t *info, u64 tid, pkg2_kip1_t *kip1);
|
||||||
void pkg2_add_kip(link_t *info, pkg2_kip1_t *kip1);
|
void pkg2_add_kip(link_t *info, pkg2_kip1_t *kip1);
|
||||||
void pkg2_merge_kip(link_t *info, pkg2_kip1_t *kip1);
|
void pkg2_merge_kip(link_t *info, pkg2_kip1_t *kip1);
|
||||||
|
|
||||||
|
const pkg2_kernel_id_t *pkg2_identify(u32 id);
|
||||||
pkg2_hdr_t *pkg2_decrypt(void *data);
|
pkg2_hdr_t *pkg2_decrypt(void *data);
|
||||||
void pkg2_build_encrypt(void *dst, void *kernel, u32 kernel_size, link_t *kips_info);
|
void pkg2_build_encrypt(void *dst, void *kernel, u32 kernel_size, link_t *kips_info);
|
||||||
|
|
||||||
|
|
|
@ -34,4 +34,10 @@ typedef volatile unsigned char vu8;
|
||||||
typedef volatile unsigned short vu16;
|
typedef volatile unsigned short vu16;
|
||||||
typedef volatile unsigned int vu32;
|
typedef volatile unsigned int vu32;
|
||||||
|
|
||||||
|
typedef struct _patch_t
|
||||||
|
{
|
||||||
|
u32 off;
|
||||||
|
u32 val;
|
||||||
|
} patch_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue