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:

And individually, these all have their fair share of problems:

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?

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:



Figure 1: A mystery distribution cart, taken from an eBay listing.

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:



Figure 2: The landing screen for the 2007 Manaphy distribution cartridge.

When we follow the instructions, the screen flashes and (presumably) begins distributing:



Figure 3: The distribution active screen for the 2007 Manaphy distribution cartridge.

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:

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...



Figure 4: Success!

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                                 
        
Figure 5: Information from the vendor-specific tag on one frame of our dump.

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                                               
        
Figure 6: Slightly annotated information from the above.

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                         
        
Figure 7: The whole body of all the ascending packets, in order.

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:

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                         
        
Figure 7: The decrypted body of our payload.

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                                     
        
Figure 8: The "gift" section of our payload.

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                                     
        
Figure 9: The header section of our payload.

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                         
        
Figure 10: The wonder card section of our payload.

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.