mirror of
https://github.com/CTCaer/hekate
synced 2024-12-22 19:31:12 +00:00
[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:
parent
dac8cd83ec
commit
e2a8b36750
3 changed files with 123 additions and 18 deletions
46
README.md
46
README.md
|
@ -4,13 +4,49 @@
|
|||
|
||||
Nintendo Switch bootloader, firmware patcher, and more.
|
||||
|
||||
|
||||
## 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.
|
||||
|
||||
Possible key/value combinations:
|
||||
### Possible key/value combinations:
|
||||
|
||||
- warmboot={SD path}
|
||||
- secmon={SD path}
|
||||
- kernel={SD path}
|
||||
- kip1={SD path}
|
||||
| Config option | Description |
|
||||
| ------------------ | ---------------------------------------------------------- |
|
||||
| warmboot={SD path} | Replaces the warmboot binary |
|
||||
| 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]
|
||||
```
|
51
ipl/hos.c
51
ipl/hos.c
|
@ -190,6 +190,9 @@ typedef struct _launch_ctxt_t
|
|||
void *kernel;
|
||||
u32 kernel_size;
|
||||
link_t kip1_list;
|
||||
|
||||
u8 *svcperm;
|
||||
u8 *debugmode;
|
||||
} launch_ctxt_t;
|
||||
|
||||
typedef struct _merge_kip_t
|
||||
|
@ -321,6 +324,26 @@ static int _config_kip1(launch_ctxt_t *ctxt, const char *value)
|
|||
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
|
||||
{
|
||||
const char *key;
|
||||
|
@ -332,6 +355,8 @@ static const cfg_handler_t _config_handlers[] = {
|
|||
{ "secmon", _config_secmon },
|
||||
{ "kernel", _config_kernel },
|
||||
{ "kip1", _config_kip1 },
|
||||
{ "fullsvcperm", _config_svcperm },
|
||||
{ "debugmode", _config_debugmode },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
|
@ -384,12 +409,18 @@ int hos_launch(ini_sec_t *cfg)
|
|||
{
|
||||
//Else we patch it to allow for an unsigned package2.
|
||||
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) {
|
||||
for (u32 i = 0; secmon_patchset[i].off != 0xFFFFFFFF; i++)
|
||||
*(vu32 *)(ctxt.pkg1_id->secmon_base + secmon_patchset[i].off) = secmon_patchset[i].val;
|
||||
if (secmon_patchset != NULL || (kernel_patchset != NULL && (ctxt.svcperm || ctxt.debugmode))) {
|
||||
if (secmon_patchset != NULL)
|
||||
{
|
||||
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.
|
||||
if (!_read_emmc_pkg2(&ctxt))
|
||||
|
@ -409,9 +440,19 @@ int hos_launch(ini_sec_t *cfg)
|
|||
{
|
||||
ctxt.kernel = pkg2_hdr->data;
|
||||
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.
|
||||
gfx_printf(&gfx_con, "%kPatching kernel initial processes%k\n", 0xFF00BAFF, 0xFFCCCCCC);
|
||||
LIST_FOREACH_ENTRY(merge_kip_t, mki, &ctxt.kip1_list, link)
|
||||
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(0xB);
|
||||
|
||||
|
|
44
ipl/pkg1.c
44
ipl/pkg1.c
|
@ -48,15 +48,15 @@ PATCHSET_DEF(_secmon_3_patchset,
|
|||
{ 0xAC8 + 0xADC, _NOP() } //Sections SHA2.
|
||||
);
|
||||
|
||||
PATCHSET_DEF(_secmon_5_patchset,
|
||||
PATCHSET_DEF(_secmon_4_patchset,
|
||||
//Patch package2 decryption and signature/hash checks.
|
||||
{ 0x1218 + 0x6E68, _NOP() }, //Header signature.
|
||||
{ 0x1218 + 0x6E74, _NOP() }, //Version.
|
||||
{ 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.
|
||||
{ 0x12b0 + 0x4d0, _NOP() },
|
||||
{ 0x12b0 + 0x4dc, _NOP() },
|
||||
|
@ -65,6 +65,32 @@ PATCHSET_DEF(_secmon_6_patchset,
|
|||
//{ 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 layout:
|
||||
|
@ -77,12 +103,12 @@ PATCHSET_DEF(_secmon_6_patchset,
|
|||
*/
|
||||
|
||||
static const pkg1_id_t _pkg1_ids[] = {
|
||||
{ "20161121183008", 0, 0x1900, 0x3FE0, { 2, 1, 0 }, 0x40014020, _secmon_1_patchset }, //1.0.0
|
||||
{ "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, _secmon_2_patchset }, //2.0.0
|
||||
{ "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, _secmon_3_patchset }, //3.0.0
|
||||
{ "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, _secmon_3_patchset }, //3.0.1
|
||||
{ "20170921172629", 3, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, _secmon_5_patchset }, //4.0.0
|
||||
{ "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, _secmon_6_patchset }, //5.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, _kernel_2_patchset }, //2.0.0 - 2.3.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, _kernel_3_patchset }, //3.0.1 - 3.0.2
|
||||
{ "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_5_patchset, _kernel_5_patchset }, //5.0.0 - 5.0.2
|
||||
{ NULL, 0, 0, 0, 0 } //End.
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue