mirror of
https://wiilab.wiimart.org/wiimart/WiiMart-Patcher
synced 2025-09-04 04:21:19 +02:00
Add base domain patch
This commit is contained in:
parent
e4c4758290
commit
59dbc66f1d
@ -5,4 +5,5 @@ Contents:
|
|||||||
- [`opcacrt6.yml`](opcacrt6.yml): A [Kaitai](https://kaitai.io) structure describing a very basic `opcacrt6.dat`.
|
- [`opcacrt6.yml`](opcacrt6.yml): A [Kaitai](https://kaitai.io) structure describing a very basic `opcacrt6.dat`.
|
||||||
It does not attempt to handle things such as client certificates or user passwords.
|
It does not attempt to handle things such as client certificates or user passwords.
|
||||||
- [`patch_overwrite_ios.md`](patch_overwrite_ios.md): An explanation over why and how IOS is patched for operation of the Wii Shop Channel.
|
- [`patch_overwrite_ios.md`](patch_overwrite_ios.md): An explanation over why and how IOS is patched for operation of the Wii Shop Channel.
|
||||||
- [`patch_custom_ca_ios.md`](patch_custom_ca_ios.md): The logistics of inserting our custom CA into IOS as well for EC usage.
|
- [`patch_custom_ca_ios.md`](patch_custom_ca_ios.md): The logistics of inserting our custom CA into IOS as well for EC usage.
|
||||||
|
- [`patch_base_domain.md`](patch_base_domain.md): Information about what URLs are present within the main DOL and information about patching them.
|
29
docs/patch_base_domain.md
Normal file
29
docs/patch_base_domain.md
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Patch: Change Base Domain
|
||||||
|
|
||||||
|
## Motivation
|
||||||
|
Ranging from HTML/JS/etc loaded from the browser portion of the shop channel to ES underneath, traffic points to Nintendo's servers without other modifications.
|
||||||
|
|
||||||
|
We need to have all traffic directed to our controlled servers.
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
With Opera's `myfilter.ini`, we simply insert our custom URL to the allowed domains on the filter list.
|
||||||
|
|
||||||
|
Unfortunately, we cannot simply `s/shop.wii.com/$USER_BASE_DOMAIN/` in the main DOL, no matter how appealing as that sounds. Most prominently, we need to handle padding for domain names shorter than `shop.wii.com`.
|
||||||
|
|
||||||
|
Thankfully, for all types present, we can replace the domain name replaced and add padding to match if necessary.
|
||||||
|
|
||||||
|
We can identify five types of URLs within the main DOL to patch:
|
||||||
|
- `https://oss-auth.shop.wii.com/startup?initpage=showManual&titleId=`
|
||||||
|
- For an unknown reason, this specific URL (alongside several others) is present 9 times within the main DOL. It is only referenced once. The other 8 occurrences appear to be directly after the data segment for other JS plugins.
|
||||||
|
- `https://oss-auth.shop.wii.com/oss/getLog`
|
||||||
|
- It is unclear on what this is for, as it is never requested whatsoever or accessed during normal runtime. Perhaps an earlier version of the Wii Shop Channel posted `ec.getLog()` to it.
|
||||||
|
- It appears directly after the data for `wiiShop`'s JS plugin, implying it goes unused. The similarly-named `getLogUrl` Setter within `wiiShop` appears to be stubbed out.
|
||||||
|
- `.shop.wii.com`
|
||||||
|
- This suffix is compared on all pages. If the loaded page's domain does not match, most EC functionality is disabled.
|
||||||
|
- `https://oss-auth.shop.wii.com`
|
||||||
|
- Similar to the first, this appears 9 times and is only referenced once.
|
||||||
|
- `https://ecs.a.taur.cloud/ecs/services/ECommerceSOAP`
|
||||||
|
- Appears to be present for `GetECConfig`, which is most likely not called within the Wii Shop channel. Instead, `ECommerceInterface#setWebSvcUrls` is preferred.
|
||||||
|
|
||||||
|
## Execution
|
||||||
|
We simply iterate through these 5 types of URLs, replace the domain, and pad if appropiate. Doing so allows us to not fragment the rest of the URL with null bytes should padding be added.
|
@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/logrusorgru/aurora/v3"
|
"github.com/logrusorgru/aurora/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -20,6 +21,9 @@ type Patch struct {
|
|||||||
Name string
|
Name string
|
||||||
|
|
||||||
// AtOffset is the offset within the file this patch should be applied at.
|
// AtOffset is the offset within the file this patch should be applied at.
|
||||||
|
// If not present, the patch will be recursively applied across the entire file.
|
||||||
|
// Relying on this behavior is highly discouraged, as it may damage other parts of the binary
|
||||||
|
// if gone unchecked.
|
||||||
AtOffset int
|
AtOffset int
|
||||||
|
|
||||||
// Before is an array of the bytes to find for, i.e. present within the original file.
|
// Before is an array of the bytes to find for, i.e. present within the original file.
|
||||||
@ -43,21 +47,28 @@ func applyPatch(patch Patch) error {
|
|||||||
if len(patch.Before) != len(patch.After) {
|
if len(patch.Before) != len(patch.After) {
|
||||||
return ErrInconsistentPatch
|
return ErrInconsistentPatch
|
||||||
}
|
}
|
||||||
if patch.AtOffset > len(mainDol) {
|
if patch.AtOffset != 0 && patch.AtOffset > len(mainDol) {
|
||||||
return ErrPatchOutOfRange
|
return ErrPatchOutOfRange
|
||||||
}
|
}
|
||||||
|
|
||||||
// Either Before or After should return the same length.
|
// Either Before or After should return the same length.
|
||||||
patchLen := len(patch.Before)
|
patchLen := len(patch.Before)
|
||||||
|
|
||||||
// Ensure original bytes are present
|
// Determine our patching behavior.
|
||||||
originalBytes := mainDol[patch.AtOffset : patch.AtOffset+patchLen]
|
if patch.AtOffset != 0 {
|
||||||
if !bytes.Equal(originalBytes, patch.Before) {
|
// Ensure original bytes are present
|
||||||
return ErrInvalidPatch
|
originalBytes := mainDol[patch.AtOffset : patch.AtOffset+patchLen]
|
||||||
}
|
if !bytes.Equal(originalBytes, patch.Before) {
|
||||||
|
return ErrInvalidPatch
|
||||||
|
}
|
||||||
|
|
||||||
// Apply patch
|
// Apply patch at the specified offset
|
||||||
copy(mainDol[patch.AtOffset:], patch.After)
|
copy(mainDol[patch.AtOffset:], patch.After)
|
||||||
|
} else {
|
||||||
|
// Recursively apply this patch.
|
||||||
|
// We cannot verify if the original contents are present via this.
|
||||||
|
mainDol = bytes.ReplaceAll(mainDol, patch.Before, patch.After)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -80,5 +91,6 @@ func emptyBytes(length int) []byte {
|
|||||||
// applyDefaultPatches iterates through a list of default patches.
|
// applyDefaultPatches iterates through a list of default patches.
|
||||||
func applyDefaultPatches() {
|
func applyDefaultPatches() {
|
||||||
applyPatchSet("Overwrite IOS Syscall for ES", OverwriteIOSPatch)
|
applyPatchSet("Overwrite IOS Syscall for ES", OverwriteIOSPatch)
|
||||||
applyPatchSet("Load Custom CA within IOS", LoadCustomCA(rootCertificate))
|
applyPatchSet("Load Custom CA within IOS", LoadCustomCA())
|
||||||
|
applyPatchSet("Change Base Domain", PatchBaseDomain())
|
||||||
}
|
}
|
||||||
|
64
patch_base_domain.go
Normal file
64
patch_base_domain.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
const (
|
||||||
|
NintendoBaseDomain = "shop.wii.com"
|
||||||
|
ShowManualURL = "https://oss-auth.shop.wii.com/startup?initpage=showManual&titleId="
|
||||||
|
GetLogURL = "https://oss-auth.shop.wii.com/oss/getLog"
|
||||||
|
TrustedDomain = ".shop.wii.com"
|
||||||
|
ECommerceBaseURL = "https://ecs.shop.wii.com/ecs/services/ECommerceSOAP"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PatchBaseDomain replaces all Nintendo domains to be the user's
|
||||||
|
// specified base domain.
|
||||||
|
// See docs/patch_base_domain.md for more information.
|
||||||
|
func PatchBaseDomain() PatchSet {
|
||||||
|
return PatchSet{
|
||||||
|
Patch{
|
||||||
|
Name: "Modify /startup domain",
|
||||||
|
|
||||||
|
Before: []byte(ShowManualURL),
|
||||||
|
After: padReplace(ShowManualURL),
|
||||||
|
},
|
||||||
|
Patch{
|
||||||
|
Name: "Modify oss-auth URL",
|
||||||
|
AtOffset: 3180692,
|
||||||
|
|
||||||
|
Before: []byte(GetLogURL),
|
||||||
|
After: padReplace(GetLogURL),
|
||||||
|
},
|
||||||
|
Patch{
|
||||||
|
Name: "Modify trusted base domain prefix",
|
||||||
|
AtOffset: 3323432,
|
||||||
|
|
||||||
|
Before: []byte(TrustedDomain),
|
||||||
|
After: padReplace(TrustedDomain),
|
||||||
|
},
|
||||||
|
Patch{
|
||||||
|
Name: "Modify ECS SOAP endpoint URL",
|
||||||
|
AtOffset: 3268896,
|
||||||
|
|
||||||
|
Before: []byte(ECommerceBaseURL),
|
||||||
|
After: padReplace(ECommerceBaseURL),
|
||||||
|
},
|
||||||
|
Patch{
|
||||||
|
Name: "Wildcard replace other instances",
|
||||||
|
|
||||||
|
Before: []byte(NintendoBaseDomain),
|
||||||
|
After: padReplace(baseDomain),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func padReplace(url string) []byte {
|
||||||
|
replaced := strings.ReplaceAll(url, NintendoBaseDomain, baseDomain)
|
||||||
|
|
||||||
|
// See if we truly need to pad.
|
||||||
|
if len(url) == len(replaced) {
|
||||||
|
return []byte(replaced)
|
||||||
|
}
|
||||||
|
|
||||||
|
padding := len(url) - len(replaced)
|
||||||
|
return append([]byte(replaced), emptyBytes(padding)...)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user