NintendoClients
NintendoClients copied to clipboard
[Wiki]: PIA `Monitoring Data` protocol seems to have incorrect structure and payload sizes
We've been looking at the data sent by the Wii U in SendReport, and it seems like some parts of the wiki are incorrect with how this data is encoded?
Here are all the SendReport payloads we've been working with:
MK8
0700fcff00a0ffffffffffffffffffff25a5c41168df2549adeeab05a0664a1e07c6388576c7ef6429167879d79f3ffcad10aa376e184db7c9c1b9d3938c773c3f1f73f197a18869e8737fb81f439b765b62ad82f596eada7a57d8154b57021f7c765e03e66772af3382b68e9de23e417ec5848676126e0c3b76e6e49c6a1ee1b9ea5e6c90ed25b581ecf5ec9f1a7f079d59f4d872ca0e438caab90522de52d1539c7dfaa3283018bad2bd2a6c37924d053b96e44d7f194a7924ae1967a73ddd
In this sample you can see it's using version 7, data type 0. So the Monitoring data header decodes to:
Version: 7
Data type: 0
Flags: 0xFC
Constant: 0xFF
Payload size: 0x00A0 (160 bytes)
Padding
However the payload size seems to be wrong? Following the header there is actually 176 bytes, not 160. Though including them in the payload doesn't seem to actually change anything with the crypto/decompression, so it's not clear what those bytes are? Version 7 is PIA 3.10 so it shouldn't have the authentication tag like 5.7+ does, since it's using ECB and not GCM?
Splatoon
0b00fcff010dffffffffffffffffffff1b6a99fbb9d160ecc8fcf318df07bb5c8d47bab8e60a01b54f11ed20022662e7569d5dcdfb6a88744431ded0353a5ee17cf52fe0390865bd43947c0c1de2858f73297c371b8a0e1bd14875b63d19419d9c740f3334ecd3e7606c7ba33bc3fa256f1a4de649c2cc6bb08629d38e494b3d1211a994be51143c026a92c2268f4f61ac01c35b06955e892f02d1440269b017b35f00b66ae75f8f00b456d191b1fbb6ee9bf3d9e041d122fa28489bcdbfbfcf9adea9f1eea44ae4c2a7a0e101695491a0186369197cd5ec75e32ef69789fa339ccd922895d2fdacd7e5cf430645d555346b7bf8c01e126df11a86e02e0898eea61cf615fec05270671915b34acb551641e89dd2c1675cfa23a6b7d38986689d
In this sample you can see it's using version 11, data type 0. So the Monitoring data header decodes to:
Version: 11
Data type: 0
Flags: 0xFC
Constant: 0xFF
Payload size: 0x010D (269 bytes)
Padding
However the payload size seems to be wrong? Following the header there is actually 272 bytes, not 269. If these 3 bytes are not included in the payload, then the decryption fails, making the payload size in the header rather useless?
Minecraft
1200fcff00a445b037878b6ce783c1ff3a18b65d81b244713a7b922e1fda7cf427d7a7c6e4f3593364776fd5cf2f210f17f080c0b1d90dc4a845f0576c2694d55623dc2ae3525ae79d7a1d3d6741d78c27e8505cd91ebfe44afde2eec12dba2caa62922d9d0534ea27b7f040f39370f2e2488a98876eab2139eb6a2f641bd8928f73ccf499e2f5cc79965d6ec6de686d417c38f3a531db1f1ff23f29f33e70fd62b53ff87e5f76d2a7cc7158f962404fffa42e3d176e914cca06e919990303afde59661988891c9e744f83ad76233556
In this sample you can see it's using version 18, data type 0. So the Monitoring data header decodes to:
Version: 18
Data type: 0
Flags: 0xFC
Constant: 0xFF
Payload size: 0x00A4 (164 bytes)
GCM nonce start: 0x45B037878B6CE783
GCM key ID: 0xC1 (index 1)
Constant: 0xFF
However the payload size seems to be wrong? The payload is actually 176 bytes, not 164. The GCM authentication tag is always 16 bytes at the end of the data, but using 164 bytes leaves 28 bytes as the authentication tag. This doesn't work. Using 176 bytes as the payload and the final 16 bytes as the authentication tag does work, so the payload size is again wrong
All
Additionally there seems to be some issues with the way the internal payload is documented as well. For example take this Minecraft payload:
1200ffff07aeffffffffffffffffffff050900ff00005335030a00ff000303010200400000fffe7a41ffffffffffffffffffffffffffffffffffffff49c01055c0a8000e0102000307f4003b04d85c3e4974ee28bdbb00306e0e101d9d000200080000002000000040000000200000004000000020ffffffffffffffffffffffffffffffff2710000001f4000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0020df90df90ff8ebb72a3ffffffffffffffffffffffffffffffffff000000ae0000000fffffffffffffffffffffffffffffffffffffffffffffffff0008ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffff00ffffffffffffffffffffffff0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5069614d
According to the wiki following the header there should be the PIA version stored as a uint32, but this isn't the case. The PIA version is stored as 3 (4?) separate bytes, each representing a different part of the version. In this case it's 0x050900FF which would translate to 5.9.0 (ignore FF?), but if this was treated as a uint32 the value would be 84476159 or 8447.61.59
The same is true for the NEX version, it is also stored as 3 (4?) individual bytes for each section. In this case that would be 0x030A00FF which would translate to 3.10.0 (ignore FF?), but if this was treated as a uint32 the value would be 50987263 or 5098.72.63
The SDK version is stored as a uint32 though. It's stored as 0x00005335, or 21301 which translates correctly to 2.13.1. So it seems like only some values are actually supposed to be treated as uint32's?
EDIT: I've just looked at the encoding functions for the data content in Minecraft, I do see now that it serializes these fields as uint32s despite their structure. I see where that comes from now. However it may be beneficial to change the wiki anyway to document how the data is actually stored in the uint32?