Playing around with Mystery Gifts in Pokémon DPPt
The Mystery Gift feature in the Pokémon Diamond/Pearl/Platinum games is an oddball.
Unlike previous generations, where the feature was either relatively speaking, random (Generation II) or required an extra peripheral (Generation III), the Generation IV games had this functionality baked into the console, and they used it fairly prolifically. In these games, there are a couple ways to receive the gifts, all wirelessly:
- Nintendo Wi-Fi Connection (now defunct)
- DS Wireless Connection
- from a Friend*
And individually, these all have their fair share of problems:
- Nintendo WFC is, as just mentioned, fully defunct
- The last Gen IV wireless event was in 2011
- Who has a friend with a functioning DS and a still-valid mystery gift?
This feature then, is pretty much dead - it had a good lifespan, but it doesn't look like we'll be able to play around with it any time soon.
Unless... what if we could emulate it?
- Emulating Nintendo WFC is out of the question - there are projects out there that tackle this massive problem space, but they're mostly closed source.
- We can't really emulate friends, either. We'd need two functioning DSes with valid mystery gifts, so ultimately, that means no new gifts can be created.
- What about Wireless Distributions? Well, no harm in trying.
Scoping it out
When I first started working on this project, I looked around for prior art, and couldn't really find any*, nor did I find much interest in this. With Action Replay and co. making it pretty easy to modify inventories, Pokémon boxes, etc. it seems like the relative interest in this long-dead feature has waned significantly. Nevertheless, I wondered if it was possible.
To start with, let's analyze how Nintendo did it. Some might labour under the misapprehension that these distributions used specialized hardware. However:
So, yes - although it was likely Nintendo did not use direct off-the-shelf DS units for their distributions, they did use the same DS hardware somewhere within their chain in order to speak the same "language" as the game itself.
Since people have dumped these ROMs too (no links provided, and I do not condone downloading any copyrighted materials), we are able to actually run the very same code. We can take a look at what this looks like here:
When we follow the instructions, the screen flashes and (presumably) begins distributing:
When we open up another DS with the proper game installed, we see that, yes - Manaphy is properly distributed.
That's it then! Most of these cartridges are already dumped, and it looks like this solves our problem, right?
Well...
It's never that simple
In my mind this approach fails on three fronts:
- Downloading ROMs is legally dubious at best, even for a long-dead system like the DS.
- Even more dubious is the act of purchasing these cartridges, which are clearly marked as Nintendo's property, and to boot, are absolutely insanely priced due to their rarity.
- It still requires two DS systems!
All of this, and we cannot create new distributions (without modification of the ROM file).
However, these ROMs do act as a great jumping off point for exploration.
The Nintendo DS, by all measures, only uses Wi-Fi* for its wireless communications. It possesses no hardware for Bluetooth or any other communication protocols. It's all Wi-Fi*, all the time.
Now, the asterisk in the last paragraph is because this isn't really Wi-Fi - it's instead a heavily modified (and proprietary version of) the IEEE 802.11 standard, which Wi-Fi is built on. This isn't a very useful distinction right now, but it will help us understand some surprises later. But for all intents and purposes, we'll begin by approaching this as Wi-Fi.
Now, we don't really know what we're dealing with, besides the fact that it's Wi-Fi. Not knowing any of the nitty-gritty, we should take a look at the whole enchilada. Because we don't know anything about the underlying details, we need to use a Wi-Fi adapter in promiscuous mode to "sniff" the raw IEEE 802.11 frames. Normal Wireshark operation won't cut it here, but there are tools such as Airtool 2 for macOS that can turn an ordinary MacBook Pro into a Wi-Fi sniffing machine, and from there, we can use Wireshark to take a look at the dumps.
Airtool 2 in particular will let us capture a particular 2.4GHz Wi-Fi "channel" and inspect all the traffic the MacBook can "see" on that channel. In the screenshot above, the channel listing was "1", so we can safely bet this is likely speaking of Channel 1 on the 2.4GHz spectrum. We can reload the distribution, sniff on the channel, and...
We see a bunch of frames, with various amounts of data. If you load up another DS, and obtain the distribution, you'll find that the receiver never echoes back any data to the transmitting cartridge. Huh?
Cleverly, the transmitter utilizes "beacon" frames, which are the IEEE 802.11 frame types used for advertising a connection. They are "broadcasted" - that is, explicitly sent to any device that will hear them. Unlike a typical Wi-Fi advertisement, however, these beacon frames contain no SSID, and aren't advertising a true connection, per-se. Instead, they contain a "vendor tag" with a whole load of shifting data. This immediately stands out as most likely candidate for the data we're interested in.
Diving in deeper
We should probably start by going over what a beacon frame generally looks like. In Wireshark, IEEE 802.11 are prefixed with a "pseudo-header" of data retreived from the physical circumstances surrounding the frame capture. This is the "radiotap" header, and it is not data that was sent over the air - it is data generated by the capturing library when recording the frame to disk.
The next bit of data is the start of the actual data sent over the air. This includes the MAC addresses of the "receiver", "destination", and "transmitter" - terms that vary in meaning, but aren't too important right now. The type of frame is also in this section, which is how we know it's a Beacon frame.
After this, we get to the "management" section, as a Beacon is a "management" frame. This
is divided for our purposes into two parts: the "fixed" parameters (timestamp, capability)
and the "tagged" parameters. We can ignore most of the tagged parameters for now, but there's
a special one we definitely want to pay attention to - a tagged parameter with an ID
DDh.
This tag means the data is "vendor-specific", and after the length of the tag is an
"organizationally
unique identifier". In the packets we received, that's 00:09:BF, which Wireshark
helpfully
tells us belongs to "Nintendo Co., Ltd.". That seems very interesting. What is in this tagged
parameter, though?
The GBATek documentation, an absolute beast of a project, contains some information about the way the DS advertises connections. This documentation is primarily focused on the use of these beacons for things like Pictochat or Multiboot, but some of the basic header information here helps to disambiguate the tag's data.
0000 00 0a 00 00 00 01 00 01 00 18 03 40 00 00 00 70
0010 00 28 00 0c 00 44 19 ff ff a8 03 00 00 2e 01 4d
0020 01 45 01 51 01 53 01 52 01 48 01 de 01 45 01 52
0030 01 48 01 de 01 3a 01 49 01 45 01 56 01 50 01 de
0040 01 37 01 2b 01 38 01 2b 01 3a 01 32 01 43 01 de
0050 01 2f 01 5a 01 49 01 52 01 58 01 ff ff ff ff ff
0060 ff ff ff ff ff 00 0c 00 00 01 00 0d 00 00 00 00
0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0080 00 00 00 00 00
Using GBATek as a legend for the dump above, we can see the following:
00 OUI (cut off in Wireshark)
0a 00 Stepping Offset (matches)
00 00 LCD Sync Rate (ignore)
01 00 01 00 Fixed ID (ignore)
18 03 40 00 Game ID (ignore)
00 00 Stream Code (ignore)
70 Bytes left (70h, the max)
00 Beacon Type (a 0 here we'll note)
28 00 CMD data size (we'll note)
0c 00 Reply Data Size (we'll note)
Rest Of The Data:
44 19 ff ff a8 03 00 00 2e 01 4d 01 45 01 51 01 53 01
52 01 48 01 de 01 45 01 52 01 48 01 de 01 3a 01 49 01
45 01 56 01 50 01 de 01 37 01 2b 01 38 01 2b 01 3a 01
32 01 43 01 de 01 2f 01 5a 01 49 01 52 01 58 01 ff ff
ff ff ff ff ff ff ff ff 00 0c 00 00 01 00 0d 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00
The initial haul here is pretty disappointing, but it at least gives us an idea of the standard header data we should expect to see, and what it means (even if it's largely unused)
Exploring the dumps further, we begin to see that the first eight bytes of the remaining data are
stable
in every frame excepting bytes two and three (FFFFh in the above dump). These
particular
bytes
actually seem to increment (the above oddball frame notwithstanding) and these range from
0000h
to 0008h. We can make a rudimentary guess that, given the ID is ascending through a set
range,
these bytes are relative ordering of some kind. We'll leave aside the oddball FFFFh for
now.
With this, we can begin to treat the rest of the data as one big body, listed below:
00000000 7F D3 80 BE B9 09 0D 16 94 A4 E3 BB 03 A9 37 8C
00000010 6C CE 61 ED 25 92 90 74 48 AB FF E8 5C 7E 4C 5C
00000020 FB 26 11 A5 1B CC 25 4A 17 38 32 53 39 B1 73 DE
00000030 D9 E7 1C 11 99 54 E9 6F 2D C0 2C CA D3 8B 43 3E
00000040 D8 0B DA 6C 0E 22 C4 11 08 FF 8F C1 C1 64 C8 AD
00000050 A9 62 BA C5 0B E4 E2 09 24 21 8A 98 35 F1 15 00
00000060 9B 2E 78 56 D0 81 13 E6 80 A9 B0 92 D9 90 FD A4
00000070 D4 54 99 00 84 7B A3 3B ED D1 29 61 5D 78 52 8E
00000080 EB 4D 64 EE 0A 8C 44 9E 93 70 CE 89 73 A4 2E 1C
00000090 A6 59 22 F1 78 E6 77 90 BE E4 06 F9 5E D5 71 48
000000A0 71 E6 3A DD 47 1E 7C 9C D4 7C EA 04 B6 28 7B 37
000000B0 3D 98 8E 63 5A 9E 19 01 CD 22 91 B8 FC 73 E2 16
000000C0 38 8D BA BC 12 6B BD 0C C0 C7 DD 4D 9F C7 F8 C8
000000D0 41 8A 77 BC 97 1B 5F 2A 87 50 F8 AB C4 27 49 C1
000000E0 76 C7 3A DB 9A F4 B7 FA 02 88 7A 21 EF 68 72 1F
000000F0 28 6E 00 5F 3C 40 98 C3 68 DE 32 ED F3 F4 1F 86
00000100 CE FA 87 AF 96 29 73 10 DF EF 54 A2 7C C3 12 D6
00000110 6A AE 9D 38 8C 49 78 EA 54 21 93 73 76 35 70 48
00000120 16 70 D4 3B 56 14 92 AB C5 75 59 AA AE B2 6D C1
00000130 07 80 E8 D0 44 2D D7 7A A8 0D 87 84 E1 81 8E DC
00000140 65 D8 57 69 5C 16 92 9D D3 61 6A 54 20 65 FA 14
00000150 8C 7B 42 1A F5 B9 68 EF 7D A6 95 F7 76 65 B1 58
00000160 E8 8E CA C4 F9 F2 66 54 48 B5 29 A4 76 0E 93 0E
00000170 35 26 97 A6 21 BB 02 BA 16 76 77 20 5C 07 A4 FB
00000180 A3 41 C7 92 EA EB F6 10 64 0C 8C 79 F4 1C DA AD
00000190 D0 A2 76 3B 5D 7E B3 0D 2F 08 AD 03 61 C3 A4 04
000001A0 77 BB FE 89 66 E2 18 40 AA 1F 4E CB D9 7A ED 60
000001B0 91 99 8B C6 7B 69 F2 76 D4 49 D4 31 5B 5F 55 87
000001C0 9A B8 09 A6 3B EB C1 F9 CB CC 34 C0 1E 63 31 16
000001D0 47 47 0D 31 A3 8D F0 15 58 62 2D CB 61 50 A6 0E
000001E0 9E 8F F6 22 68 9B 08 BC DF 81 80 12 9D 93 2E 1D
000001F0 41 D3 26 7E 35 11 42 D5 8F C3 D5 F5 7C B5 29 E5
00000200 65 ED 72 F2 1D 9F A7 04 13 69 26 2C AF 90 F0 D8
00000210 70 BF 9C CB 24 C6 EA AC 87 B8 60 A8 D0 7D A5 5F
00000220 94 6D 44 22 26 66 23 6A 85 7F 73 5F 0F C3 E1 4A
00000230 90 D6 C7 88 0E A5 4C 73 B8 9C 54 56 D7 F0 B8 B9
00000240 A0 35 FF F6 B3 D4 85 55 30 9C 32 FA F7 9E 2D D1
00000250 23 21 AA 81 67 86 E5 0F 7E 30 E1 03 AA 9C BD B8
00000260 9F 59 BC B2 EC 43 E2 34 75 87 67 97 7D 32 26 D4
00000270 B6 06 B8 E0 11 A6 45 62 21 8F F6 35 B2 55 6D EB
00000280 CB 0F DF 49 DC 7C B1 4F FF 2F 07 DF 20 91 CB B3
00000290 1A 25 0B 07 7B BD EF F1 39 A5 AA 4E A6 9A 54 89
000002A0 ED 44 0E 1C 38 DF 4B 6C 74 FA 8B 5B 09 17 07 C1
000002B0 05 F5 4A 30 3F CF 39 CB 2F 90 C5 7D F3 B0 19 62
000002C0 F8 27 7B B2 74 52 84 96 3C 06 FE 30 B7 F8 25 F6
000002D0 C3 CE 3D E1 F7 09 A4 FD 06 F9 B4 5E 25 92 D7 D7
000002E0 CC 5E AC 82 AF AF E6 09 F6 40 BC F0 71 98 95 31
000002F0 40 21 A5 B7 F9 A1 6F 02 C4 F0 D7 D8 FE 59 26 4D
00000300 F6 E2 88 8D B1 25 6A A6 C2 E5 D4 A3 27 D2 33 3D
00000310 64 C4 E0 75 2D 81 E9 5E 6E EA 11 38 9F 29 2C 1B
00000320 A1 86 47 AC 3F 86 7C CC 39 7C 79 68 E6 B8 EC 95
00000330 9F 73 30 B9 FE 4C FB 76 96 9F CF 1F 57 9E 7F 65
00000340 A8 44 C9 32 B5 CC 66 C2 4F 53 D9 46 2E 63 B5 C9
00000350 3F 8F 2F 39 6E E1 D3 16 81 3E BA AC 2E 1B F0 9A
00000360 7F C3 14 8F D3 E6 76 20 AB 00 57 5A 88 D6 5D F4
00000370 94 84 79 C5 A7 7D B3 CB C7 D7 2D 20 5C 73 6F 5F
00000380 24 5C 69 55 37 98 95 9D 67 02 F6 CC 4A C6 00 DD
00000390 9F BD 72 5D FF EF 42 EE 0C E5 3C 08 06 1D 1D 0D
000003A0 CA 04 41 4F C2 EF 04 C7
This data has super high entropy, which implies it's either encrypted or compressed (or both). We end up with (104*9)=936 Bytes of total (presumably encrypted) data.
Breaking the code
From here, (and after a lot more searching), we do lean on a singular piece of prior art able to be found - a 2017 GBATemp post from user Yuuto, who kindly investigated some of the details with a debugger. From this, we gather the following:
- The body is encrypted with RC4, an older, now far out-of-date encryption method.
- The key is a combination of a proprietary key (
3FA2h), the MAC Address of the transmitting device, and a checksum. - All of the other details we've figured out up until now seem intact, too.
With this knowledge, we can whip up a script that does the hard work in decoding this data. Using
the
MAC
address of our device (a secret, sorry) and the checksum for the data (1944h), we get a
properly decrypted output:
00000000 2E 01 4D 01 45 01 51 01 53 01 52 01 48 01 DE 01
00000010 45 01 52 01 48 01 DE 01 3A 01 49 01 45 01 56 01
00000020 50 01 DE 01 37 01 2B 01 38 01 2B 01 3A 01 32 01
00000030 43 01 DE 01 2F 01 5A 01 49 01 52 01 58 01 FF FF
00000040 FF FF FF FF FF FF FF FF 00 0C 00 00 01 00 0D 00
00000050 01 00 00 00 01 00 00 00 01 00 00 00 00 00 18 40
00000060 D8 BF 53 CE 39 E9 9E C9 2A 95 71 D5 C0 CC 70 5E
00000070 67 FF 78 71 33 80 9E 5B 98 49 99 00 97 12 23 DB
00000080 D8 05 DF 58 ED FF 60 7F 83 1D 86 7C 0D EE 22 79
00000090 29 44 93 BC BB C5 A6 56 AE 9F FB 34 7B C1 9B AE
000000A0 1E D5 0B D1 03 C9 B7 49 C7 A2 9E 5E 6B B7 9E A8
000000B0 69 A1 2A 3F 56 72 AD A2 8F BC DF A8 8F C3 69 EF
000000C0 C3 69 D8 B4 B5 1B EE 73 F8 33 28 38 22 3E B0 88
000000D0 BC EA C5 E5 55 AB D8 32 20 70 5E 23 C4 4C CF E4
000000E0 C6 41 21 AC DC D2 17 1F 43 79 DB B6 A4 4A D0 37
000000F0 44 0C 20 DE 36 57 F9 92 37 78 31 22 C1 59 E4 D4
00000100 98 3E 41 82 94 B1 91 FF 27 D0 D5 3C AB D2 E7 02
00000110 7D 10 5E A0 69 44 43 D5 67 31 2B 74 28 A7 57 A8
00000120 CE 2B 8B 13 F6 AB D8 26 D6 73 56 97 EB 33 B3 C1
00000130 49 2D 37 D8 D5 03 23 06 A5 FD B0 EE B3 A8 B9 0A
00000140 45 99 4E 47 00 00 00 00 00 40 00 00 00 00 00 00
00000150 00 00 00 00 2E 01 4D 01 45 01 51 01 53 01 52 01
00000160 48 01 DE 01 45 01 52 01 48 01 DE 01 3A 01 49 01
00000170 45 01 56 01 50 01 DE 01 37 01 2B 01 38 01 2B 01
00000180 3A 01 32 01 43 01 DE 01 2F 01 5A 01 49 01 52 01
00000190 58 01 FF FF FF FF FF FF FF FF FF FF 00 0C 00 00
000001A0 01 00 0D 00 3E 01 4C 01 4D 01 57 01 DE 01 37 01
000001B0 2B 01 38 01 2B 01 3A 01 32 01 43 01 DE 01 4D 01
000001C0 57 01 DE 01 45 01 DE 01 4B 01 4D 01 4A 01 58 01
000001D0 DE 01 58 01 53 01 DE 01 5D 01 53 01 59 01 DE 01
000001E0 4D 01 52 01 DE 01 00 E0 47 01 49 01 50 01 49 01
000001F0 46 01 56 01 45 01 58 01 4D 01 53 01 52 01 DE 01
00000200 53 01 4A 01 DE 01 58 01 4C 01 49 01 DE 01 51 01
00000210 53 01 5A 01 4D 01 49 01 DE 01 3A 01 53 01 4F 01
00000220 88 01 51 01 53 01 52 01 DE 01 00 E0 3C 01 45 01
00000230 52 01 4B 01 49 01 56 01 DE 01 45 01 52 01 48 01
00000240 DE 01 58 01 4C 01 49 01 DE 01 3E 01 49 01 51 01
00000250 54 01 50 01 49 01 DE 01 53 01 4A 01 DE 01 58 01
00000260 4C 01 49 01 DE 01 3D 01 49 01 45 01 AE 01 FF FF
00000270 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000280 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000290 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000002A0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000002B0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000002C0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000002D0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000002E0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000002F0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000300 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000310 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000320 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000330 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000340 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000350 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000360 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000370 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000380 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000390 FF FF FF FF FF FF FF FF 00 00 00 00 EA 01 00 00
000003A0 00 00 00 00 00 00 00 00
Success!
What do we have?
Yuuto's post, as invaluable as it is, is light on info about the actual payload itself. For that, we can utilize the work already done by the community.
The payload, as described in Yutto's post, is in the "PCD" format. I cannot, for the life of me, find a thorough description of this format, anywhere. So, I'll document it here as I go along.
The PCD format
A quick note before we start - again, most of this format is not documented anywhere. For my analysis, I'm using both intuition as well as the very helpful decoder implementation provided by the venerable PkHeX program.
With that said, let's start by stripping the first copy of the header from the data. Now, with the remaining data, let's analyze part one: the gift itself:
00000000 01 00 00 00 01 00 00 00 01 00 00 00 00 00 18 40
00000010 D8 BF 53 CE 39 E9 9E C9 2A 95 71 D5 C0 CC 70 5E
00000020 67 FF 78 71 33 80 9E 5B 98 49 99 00 97 12 23 DB
00000030 D8 05 DF 58 ED FF 60 7F 83 1D 86 7C 0D EE 22 79
00000040 29 44 93 BC BB C5 A6 56 AE 9F FB 34 7B C1 9B AE
00000050 1E D5 0B D1 03 C9 B7 49 C7 A2 9E 5E 6B B7 9E A8
00000060 69 A1 2A 3F 56 72 AD A2 8F BC DF A8 8F C3 69 EF
00000070 C3 69 D8 B4 B5 1B EE 73 F8 33 28 38 22 3E B0 88
00000080 BC EA C5 E5 55 AB D8 32 20 70 5E 23 C4 4C CF E4
00000090 C6 41 21 AC DC D2 17 1F 43 79 DB B6 A4 4A D0 37
000000A0 44 0C 20 DE 36 57 F9 92 37 78 31 22 C1 59 E4 D4
000000B0 98 3E 41 82 94 B1 91 FF 27 D0 D5 3C AB D2 E7 02
000000C0 7D 10 5E A0 69 44 43 D5 67 31 2B 74 28 A7 57 A8
000000D0 CE 2B 8B 13 F6 AB D8 26 D6 73 56 97 EB 33 B3 C1
000000E0 49 2D 37 D8 D5 03 23 06 A5 FD B0 EE B3 A8 B9 0A
000000F0 45 99 4E 47 00 00 00 00 00 40 00 00 00 00 00 00
00000100 00 00 00 00
The format is entirely dependent on the first 2 bytes - this is the type of the gift.
The following table lists the type of gifts:
| ID | Name |
|---|---|
| 0 | Empty |
| 1 | Pokémon |
| 2 | Pokémon Egg |
| 3 | Item |
| 4 | Battle Ruleset |
| 5 | Underground Good |
| 6 | Accessory |
| 7 | Manaphy Egg (Pokémon Ranger) |
| 8 | Member's Card |
| 9 | Oak's Letter |
| 10 | Azure Flute |
| 11 | Pokétch App |
Every single gift data object is 256 bytes, plus the 4 bytes of the tag and associated 2 bytes (of unknown purpose), for a total of 260 bytes in this section.
For gifts in the Item, Goods, Event Item, or Pokétch App categories, the first 4 bytes are a little-endian integer specifying the ID of the received gift. The rest of the data is unused.
For gifts in the Manaphy Egg category, the entire data is unused.
For gifts in the accessory category, the first 4 bytes are the category of accessory, and the second 4 bytes are the ID within this category.
For gifts in the Pokémon or Pokémon Egg category, the first 4 bytes determine whether or not the received Pokémon takes your name as the Original Trainer name or not. The next 236 bytes are a PKM payload, encrypted according to the usual Generation IV save encoding standards. The remaining 16 bytes are unknown or filler.
For gifts in the Battle Ruleset category, the data is a Ruleset object.
Next, we'll analyze the "header" section.
00000100 2E 01 4D 01 45 01 51 01 53 01 52 01
00000110 48 01 DE 01 45 01 52 01 48 01 DE 01 3A 01 49 01
00000120 45 01 56 01 50 01 DE 01 37 01 2B 01 38 01 2B 01
00000130 3A 01 32 01 43 01 DE 01 2F 01 5A 01 49 01 52 01
00000140 58 01 FF FF FF FF FF FF FF FF FF FF 00 0C 00 00
00000150 01 00 0D 00
The first 72 bytes are a Generation IV encoded string that encodes the
title of the event, in this case, "Diamond and Pearl MANAPHY Event".
The remaining bytes are our "compatibility code" (00000C00h),
and the card number (0001h). The second to last byte is a bitflag,
described below.
| Name | Bit | Description |
|---|---|---|
| Unique | 0 | Whether or not the gift can only be received once |
| (ignore) | 1 | |
| Has Card | 2 | Whether or not the gift contains Wonder Card data |
| Delivered | 3 | Whether or not this gift is received by talking to the delivery man in a Pokemart |
| Shareable | 4 | Whether or not this gift can be "regifted" to others |
| Regifted | 5 | Whether or not this gift is a regift of a regift |
| (ignore) | 6 | |
| (ignore) | 7 |
The last byte is likely padding.
Finally, our wonder card data:
00000150 3E 01 4C 01 4D 01 57 01 DE 01 37 01
00000160 2B 01 38 01 2B 01 3A 01 32 01 43 01 DE 01 4D 01
00000170 57 01 DE 01 45 01 DE 01 4B 01 4D 01 4A 01 58 01
00000180 DE 01 58 01 53 01 DE 01 5D 01 53 01 59 01 DE 01
00000190 4D 01 52 01 DE 01 00 E0 47 01 49 01 50 01 49 01
000001A0 46 01 56 01 45 01 58 01 4D 01 53 01 52 01 DE 01
000001B0 53 01 4A 01 DE 01 58 01 4C 01 49 01 DE 01 51 01
000001C0 53 01 5A 01 4D 01 49 01 DE 01 3A 01 53 01 4F 01
000001D0 88 01 51 01 53 01 52 01 DE 01 00 E0 3C 01 45 01
000001E0 52 01 4B 01 49 01 56 01 DE 01 45 01 52 01 48 01
000001F0 DE 01 58 01 4C 01 49 01 DE 01 3E 01 49 01 51 01
00000200 54 01 50 01 49 01 DE 01 53 01 4A 01 DE 01 58 01
00000210 4C 01 49 01 DE 01 3D 01 49 01 45 01 AE 01 FF FF
00000220 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000230 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000240 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000250 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000260 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000270 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000280 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000290 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000002A0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000002B0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000002C0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000002D0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000002E0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000002F0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000300 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000310 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000320 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000330 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000340 FF FF FF FF FF FF FF FF 00 00 00 00 EA 01 00 00
00000350 00 00 00 00 00 00 00 00
The first 500 bytes are the card's text, once again encoded in the standard Generation IV format. Decoding this time reads:
This MANAPHY is a gift to you in
celebration of the movie Pokémon
Ranger and the Temple of the Sea.
The next byte is the number of remaining "regifts". A FFh for
this value means it can be regifted indefinitely. The byte
after this is padding.
The next three shorts are the Pokémon IDs for the wonder card's Pokémon display. In this case, the display is one Manpahy in the middle position.
The remaining 8 bytes are seemingly padding.
Where from here?
We've done now a full decoding of the beacon data, and the format therein. This is a great start - we now know just enough to be able to create our own distributions in the PCD format, wrap them up, and encrypt them in order to send them out. But how do we send them out? The next blog post in this series will go through my experiments with the ESP32 chipset, and successful distribution of custom mystery gift payloads.