[PKG1] Add kernel patching

Add Disable Svc Verification and Debug mode.
Can be enabled via the hekate .ini

https://gist.github.com/roblabla/440f3ceaa0b2d3ca530c2a43fe258420
This commit is contained in:
Kostas Missos 2018-06-01 19:22:11 +03:00 committed by nwert
parent dac8cd83ec
commit e2a8b36750
3 changed files with 123 additions and 18 deletions

View file

@ -4,13 +4,49 @@
Nintendo Switch bootloader, firmware patcher, and more. Nintendo Switch bootloader, firmware patcher, and more.
## ipl config ## ipl config
The ipl can be configured via 'hekate_ipl.ini' (if it is present on the SD card). Each ini section represents a boot entry, except for the special section 'config' that controls the global configuration. The ipl can be configured via 'hekate_ipl.ini' (if it is present on the SD card). Each ini section represents a boot entry, except for the special section 'config' that controls the global configuration.
Possible key/value combinations: ### Possible key/value combinations:
- warmboot={SD path} | Config option | Description |
- secmon={SD path} | ------------------ | ---------------------------------------------------------- |
- kernel={SD path} | warmboot={SD path} | Replaces the warmboot binary |
- kip1={SD path} | secmon={SD path} | Replaces the security monitor binary |
| kernel={SD path} | Replaces the kernel binary |
| kip1={SD path} | Replaces/Adds kernel initial process. Multiple can be set. |
| fullsvcperm=1 | Disables SVC verification |
| debugmode=1 | Enables Debug mode |
```
hekate (C) 2018 naehrwert, st4rk.
Thanks to: derrek, nedwill, plutoo, shuffle2, smea, thexyz, yellows8.
Greetings to: fincs, hexkyz, SciresM, Shiny Quagsire, WinterMute.
Open source and free packages used:
- FatFs R0.13a, Copyright (C) 2017, ChaN
- bcl-1.2.0, Copyright (C) 2003-2006, Marcus Geelnard
___
.-' `'.
/ \
| ;
| | ___.--,
_.._ |0) = (0) | _.---'`__.-( (_.
__.--'`_.. '.__.\ '--. \_.-' ,.--'` `""`
( ,.--'` ',__ /./; ;, '.__.'` __
_`) ) .---.__.' / | |\ \__..--"" """--.,_
`---' .'.''-._.-'`_./ /\ '. \ _.--''````'''--._`-.__.'
| | .' _.-' | | \ \ '. `----`
\ \/ .' \ \ '. '-._)
\/ / \ \ `=.__`'-.
/ /\ `) ) / / `"".`\
, _.-'.'\ \ / / ( ( / /
`--'` ) ) .-'.' '.'. | (
(/` ( (` ) ) '-; [switchbrew]
```

View file

@ -190,6 +190,9 @@ typedef struct _launch_ctxt_t
void *kernel; void *kernel;
u32 kernel_size; u32 kernel_size;
link_t kip1_list; link_t kip1_list;
u8 *svcperm;
u8 *debugmode;
} launch_ctxt_t; } launch_ctxt_t;
typedef struct _merge_kip_t typedef struct _merge_kip_t
@ -321,6 +324,26 @@ static int _config_kip1(launch_ctxt_t *ctxt, const char *value)
return 1; return 1;
} }
static int _config_svcperm(launch_ctxt_t *ctxt, const char *value)
{
if (*(u8 *)value == '1')
{
DPRINTF("Disabled SVC verification\n");
ctxt->svcperm = malloc(1);
}
return 1;
}
static int _config_debugmode(launch_ctxt_t *ctxt, const char *value)
{
if (*(u8 *)value == '1')
{
DPRINTF("Enabled Debug mode\n");
ctxt->debugmode = malloc(1);
}
}
typedef struct _cfg_handler_t typedef struct _cfg_handler_t
{ {
const char *key; const char *key;
@ -332,6 +355,8 @@ static const cfg_handler_t _config_handlers[] = {
{ "secmon", _config_secmon }, { "secmon", _config_secmon },
{ "kernel", _config_kernel }, { "kernel", _config_kernel },
{ "kip1", _config_kip1 }, { "kip1", _config_kip1 },
{ "fullsvcperm", _config_svcperm },
{ "debugmode", _config_debugmode },
{ NULL, NULL }, { NULL, NULL },
}; };
@ -384,12 +409,18 @@ int hos_launch(ini_sec_t *cfg)
{ {
//Else we patch it to allow for an unsigned package2. //Else we patch it to allow for an unsigned package2.
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) { if (secmon_patchset != NULL || (kernel_patchset != NULL && (ctxt.svcperm || ctxt.debugmode))) {
for (u32 i = 0; secmon_patchset[i].off != 0xFFFFFFFF; i++) if (secmon_patchset != NULL)
*(vu32 *)(ctxt.pkg1_id->secmon_base + secmon_patchset[i].off) = secmon_patchset[i].val; {
gfx_printf(&gfx_con, "%kPatching Security Monitor%k\n", 0xFF00BAFF, 0xFFCCCCCC);
for (u32 i = 0; secmon_patchset[i].off != 0xFFFFFFFF; i++)
*(vu32 *)(ctxt.pkg1_id->secmon_base + secmon_patchset[i].off) = secmon_patchset[i].val;
}
DPRINTF("loaded warmboot.bin and secmon\n"); gfx_printf(&gfx_con, "Loaded warmboot.bin and secmon\n");
//Read package2. //Read package2.
if (!_read_emmc_pkg2(&ctxt)) if (!_read_emmc_pkg2(&ctxt))
@ -409,9 +440,19 @@ 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))
{
gfx_printf(&gfx_con, "%kPatching kernel%k\n", 0xFF00BAFF, 0xFFCCCCCC);
if (ctxt.svcperm && kernel_patchset[0].off != 0xFFFFFFFF)
*(vu32 *)(ctxt.kernel + kernel_patchset[0].off) = kernel_patchset[0].val;
if (ctxt.debugmode && kernel_patchset[1].off != 0xFFFFFFFF)
*(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);
LIST_FOREACH_ENTRY(merge_kip_t, mki, &ctxt.kip1_list, link) LIST_FOREACH_ENTRY(merge_kip_t, mki, &ctxt.kip1_list, link)
pkg2_merge_kip(&kip1_info, (pkg2_kip1_t *)mki->kip1); pkg2_merge_kip(&kip1_info, (pkg2_kip1_t *)mki->kip1);
@ -428,6 +469,8 @@ int hos_launch(ini_sec_t *cfg)
} }
} }
gfx_printf(&gfx_con, "\n%kBooting...%k\n", 0xFF00FF96, 0xFFCCCCCC);
se_aes_key_clear(0x8); se_aes_key_clear(0x8);
se_aes_key_clear(0xB); se_aes_key_clear(0xB);

View file

@ -48,15 +48,15 @@ PATCHSET_DEF(_secmon_3_patchset,
{ 0xAC8 + 0xADC, _NOP() } //Sections SHA2. { 0xAC8 + 0xADC, _NOP() } //Sections SHA2.
); );
PATCHSET_DEF(_secmon_5_patchset, PATCHSET_DEF(_secmon_4_patchset,
//Patch package2 decryption and signature/hash checks. //Patch package2 decryption and signature/hash checks.
{ 0x1218 + 0x6E68, _NOP() }, //Header signature. { 0x1218 + 0x6E68, _NOP() }, //Header signature.
{ 0x1218 + 0x6E74, _NOP() }, //Version. { 0x1218 + 0x6E74, _NOP() }, //Version.
{ 0x1218 + 0x6FE4, _NOP() }, //Sections SHA2. { 0x1218 + 0x6FE4, _NOP() }, //Sections SHA2.
{ 0x1218 + 0x2DC, _NOP() } //Unknown. { 0x1218 + 0x2DC, _NOP() } //Unknown.
); );
PATCHSET_DEF(_secmon_6_patchset, PATCHSET_DEF(_secmon_5_patchset,
//Patch package2 decryption and signature/hash checks. //Patch package2 decryption and signature/hash checks.
{ 0x12b0 + 0x4d0, _NOP() }, { 0x12b0 + 0x4d0, _NOP() },
{ 0x12b0 + 0x4dc, _NOP() }, { 0x12b0 + 0x4dc, _NOP() },
@ -65,6 +65,32 @@ PATCHSET_DEF(_secmon_6_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,
{ 0xFFFFFFFF, 0xFFFFFFFF }, // TODO: MISSING
{ 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:
@ -77,12 +103,12 @@ PATCHSET_DEF(_secmon_6_patchset,
*/ */
static const pkg1_id_t _pkg1_ids[] = { static const pkg1_id_t _pkg1_ids[] = {
{ "20161121183008", 0, 0x1900, 0x3FE0, { 2, 1, 0 }, 0x40014020, _secmon_1_patchset }, //1.0.0 { "20161121183008", 0, 0x1900, 0x3FE0, { 2, 1, 0 }, 0x40014020, _secmon_1_patchset, _kernel_1_patchset }, //1.0.0
{ "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, _secmon_2_patchset }, //2.0.0 { "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, _secmon_2_patchset, _kernel_2_patchset }, //2.0.0 - 2.3.0
{ "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, _secmon_3_patchset }, //3.0.0 { "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, _secmon_3_patchset, _kernel_3_patchset }, //3.0.0
{ "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, _secmon_3_patchset }, //3.0.1 { "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, _secmon_3_patchset, _kernel_3_patchset }, //3.0.1 - 3.0.2
{ "20170921172629", 3, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, _secmon_5_patchset }, //4.0.0 { "20170921172629", 3, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, _secmon_4_patchset, _kernel_4_patchset }, //4.0.0 - 4.1.0
{ "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, _secmon_6_patchset }, //5.0.0 { "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, _secmon_5_patchset, _kernel_5_patchset }, //5.0.0 - 5.0.2
{ NULL, 0, 0, 0, 0 } //End. { NULL, 0, 0, 0, 0 } //End.
}; };