diff --git a/docs/patch_ec_title_check.md b/docs/patch_ec_title_check.md index 8c6bb4f..e8e6f1f 100644 --- a/docs/patch_ec_title_check.md +++ b/docs/patch_ec_title_check.md @@ -13,13 +13,24 @@ Within this, four conditions are checked: - Is the channel a game channel? This checks two types: - `00010000`, typically used for discs - `00010004`. - - Is the channel a "service title"? (`00010100`) - - Name taken from `ec::isServiceTitle`. + - Is the channel a service title? (`00010100`) If any of these are true, installation of the title is permitted. Otherwise, installation is forbidden. -## Execution -This behavior is not ideal. `ec::allowDownloadByApp` is patched to immediately return `1`, or true. +Two other functions perform these four conditionals as well: `ec::isManagedTitle`, and `ec::isManagedTicket`. They are invoked when retrieving title information and when deleting titles. -In the future, `ec::isManagedTitle` and `ec::isManagedTicket` may wish to be patched as well due to similar reasons. \ No newline at end of file +It was identified that upon unregistration, a function named `ec::removeAllTitles` is called. This function loops through all installed titles, checking whether they are managed titles. If the title is managed, its ticket is removed and its title contents are deleted. + +Simply returning that all titles are managed exposes a large risk of deletion. Several options were discussed on how to approach this: + - Have all titles and tickets be managed, and ensure that the user is never unregistered + - While possible, not worth the risk. + - Possibly add hidden titles as managed (since we'll have the installation stub there) + - While far more safe than the first bullet point, we will still delete all NAND channels upon unregistration. + - Nullify the deletion function on unregister and hope that nothing else is like this + - This approach was chosen. This patch set will be refined if other mass-deletion functions are identified. + +## Execution +This behavior is not ideal. Four patches are applied: + - `ec::allowDownloadByApp`, `ec::isManagedTitle`, and `ec::isManagedTicket` are all patched to immediately return `1`, or true. + - `ec::removeAllTitles` immediately returns `0`, preventing all damage. Its return value is seemingly the amount of titles remaining. \ No newline at end of file diff --git a/patch_ec_title_check.go b/patch_ec_title_check.go index 892a430..08a245b 100644 --- a/patch_ec_title_check.go +++ b/patch_ec_title_check.go @@ -2,7 +2,7 @@ package main var NegateECTitle = PatchSet{ Patch{ - Name: "Allow all titles", + Name: "Permit downloading all titles", AtOffset: 619648, // Generic function prolog @@ -17,4 +17,41 @@ var NegateECTitle = PatchSet{ BLR(), }.toBytes(), }, + Patch{ + Name: "Mark all titles as managed", + AtOffset: 620656, + + Before: Instructions{ + STWU(R1, R1, 0xfff0), + MFSPR(), + }.toBytes(), + After: Instructions{ + LI(R3, 1), + BLR(), + }.toBytes(), + }, + Patch{ + Name: "Mark all tickets as managed", + AtOffset: 619904, + Before: Instructions{ + STWU(R1, R1, 0xfff0), + MFSPR(), + }.toBytes(), + After: Instructions{ + LI(R3, 1), + BLR(), + }.toBytes(), + }, + Patch{ + Name: "Nullify ec::removeAllTitles", + AtOffset: 588368, + Before: Instructions{ + STWU(R1, R1, 0xffc0), + MFSPR(), + }.toBytes(), + After: Instructions{ + LI(R3, 0), + BLR(), + }.toBytes(), + }, }