Playing Pokémon Go before it’s released in your country

Jonathan Lima
5 min readJul 18, 2016

--

Pokémon Go is one of the most anticipated games ever. Within only 10 days after the initial release in Australia and New Zealand, Nintendo stocks jumped over 90%.

Note: If you just want to play Pokémon Go, go the “My Public Server” section below and follow the instructions.

Despite its tremendous success, the game isn’t available yet on half of the planet, including Japan, Russia and Brazil.

In this article I’ll show you how to play Pokémon Go even if it hasn’t been released yet in your country.

You can find my implementation here: https://github.com/greenboxal/pgo-teleport

Other Approaches

I saw some approaches over the Internet, but I didn’t like them for some reasons:

  • Changes the street map to the target location
  • Freezes your location
  • The need to use a virtual keyboard to walk

Those approaches kill the most important experience of the game: walking around to catch Pokémon.

Intercepting network traffic

I used a simple setup to intercept network packets. Using mitmproxy as a HTTP proxy, I could sniff all requests the game sent to the server.

Decoding the game packets with mitmproxy and a custom script

Understanding the Protocol

The game leverages HTTP/2 where available as its transport, falling back to HTTP 1.1. The protocol itself is based on Google’s protobuf which is posted over HTTP.

All messages are enveloped in a RPC structure as follows:

RPC Envelope using protobuf syntax

Authentication is made via JWT, and, in every request, your current latitude and longitude is sent.

Multiple calls can be sent on the same request using the calls array. The result comes in results array.

Teleporting you somewhere cool

Niantic blocked Pokémon from spawning in areas where the game wasn’t released. In order to get Pokémon, you need to teleport yourself somewhere.

I chose to replace my house with the Central Park, in New York. To do so, I took my address coordinates and calculated difference from my target.

Local Lat = -23.5505
Local Lng = -46.6333
Target Lat = 40.7829
Target Lng = -73.9654
Delta Lat = (Local Lat - Target Lat) = 64.3334
Delta Lng = (Local Lng - Target Lng) = -27.3321

Now when I need to translate any coordinate from my location to the target, I just need to sum my delta to it.

As mitmproxy allows me to use a Python script to modify the requests before they’re sent to the server, I quickly created a script that sums the delta to all requests.

The GetMapObjects function

Even though I was sending my altered location to the server, no objects appeared on my map. I needed to dig deeper.

Every second, the game sends a request to the server called GetMapObjects, which requests Pokémon, PokeStops, gyms and any other object that would appear on the map.

The game sends an array of numbers in the CellId field. That field was intriguing me. Reading some posts over the internet, I found that Ingress — another game from Niantic, which is similar to Pokémon Go — uses Google’s library s2-geometry.

Parsing those IDs with s2-geometry I found exactly what I was looking for: they were coordinates for some 100m² areas around my location.

I won’t explain the exact mechanics of this library but, basically, it indexes latitudinal and longitudinal data of a sphere using a 64bit integer. Some databases including MongoDB use this structure to index 2D data.

Given that, I just need to decode those CellIDs back to geographic coordinates, add my location delta, then encode them back to CellIDs.

Pokémon and PokeStops only appears when connected through the proxy

You can find a more complete explanation about s2-geometry here.

The packet-frenzy

Aside from GetMapObjects, there are about 20 other packets and sub-packets that transport some kind of coordinate. Gotta translate ‘em all. (sorry for this, I couldn’t resist)

Those packets are:

  • GetMapObjects
  • PlayerUpdate
  • FortSearch
  • FortDetails
  • GetGymDetails
  • Encounter
  • GetIncensePokemon
  • FortDeployPokemon
  • FortRecallPokemon
  • AddFortModifier
  • TradeSearch
  • UseItemGym
  • DiskEncounter
  • IncenseEncounter

After patching all those packets, the entire game seemed to work pretty well.

Making it work on iOS

I live in a game of love and hate with Apple.

You can’t enable a global HTTP proxy unless you’re connected to a wifi network. This would make my proxy useless as you need to walk on the streets in order to play — the last place you will find wifi here in Brazil.

The best solution I found was to create a VPN server that would hijack the traffic to Pokémon Go servers and send it to my proxy.

I used SoftEther to create a L2TP/IPSec connection on a Ubuntu box in AWS. As I didn’t want my entire phone traffic to be sent to this server, I redirect the traffic using a DNS server and split tunneling.

I also tried to push static routes over the connection but my phone seemed to ignore them.

My Public Server

As this setup was pretty complicated, I’ve made my VPN with my proxy public. You can connect to it and play the game as if it were released in your country.

I won’t cover any method on downloading the game (like downloading the APK or connecting to the US App Store). You can find a lot of references for that over the Internet.

Disclaimer: NEVER forward your entire traffic to an unknown VPN, you could compromise your data and passwords.

That being said, the certificate you need to install only covers *.nianticlabs.com, Pokémon Go’s endpoint.

VPN Details:

Protocol: L2TP/IPSec
Address: pgo-vpn.greenboxal.com
IPSec Pre Shared Key: pokemongo
Username: pokemongo
Password: pokemongo
Static routes (if needed): 10.66.0.0/16
DNS server (if needed): 10.66.0.1
Redirect all traffic: NO

You shouldn’t redirect your entire phone traffic to this server as it can only route Pokémon Go servers.

Please check this link for always up-to-date information: http://pgo.greenboxal.com/

iOS Instructions

iOS Profile: http://pgo.greenboxal.com/PokemonGo.mobileconfig (copy and paste on Safari, won’t work on Medium reader)

  1. Accept the installation instruction when you click the download link
  2. A VPN item should appear on the Settings app
  3. Click to enable it
  4. Profit

Remember to turn the VPN off when not playing.

Android Instructions

Install Certificate: Download link

Accept inputs and select VPN and Apps usage.

Add the VPN profile:

  1. Go to Settings > Wireless & Network > More > VPN
  2. Click the + button
  3. Input values as the box above
  4. Profit

Note that username and password inputs are available after saving the profile and tapping it to connect.

Donations

If you like my work, or if you use my public VPN, please consider making me a donation in order fund the VPN server.

PayPal: Donate here

Bitcoin: 3Ez8ZYR91dGFhANKCDGieo8bAZtmzeX5id

References

You can always check for up-to-date information about the VPN here: http://greenboxal.github.io/pgo-teleport

mitmproxy: https://mitmproxy.org

Base protobuf messages: https://github.com/bettse/mitmdump_decoder

Reverse engineering Pokémon Go API: http://joshhunt.is/reverse-engineering-pokemon-go-api/

S2 Geometry Explanation: http://blog.christianperone.com/2015/08/googles-s2-geometry-on-the-sphere-cells-and-hilbert-curve/

--

--