Decoding Android Google Maps : gmm_myplaces.db

After reading the blog post from Josh Hickman Finding Phones With Google Maps Part 1 (Android), I got interested in the Google Maps Android app to see what information reside on the phone. So I looked to Aleapp to see what was decoded for Google Maps, and surprisingly, there was no plugin for the gmm_myplaces.db database, which holds the saved Labels from the Google Maps app. So, I found myself doing some testing for this DB to understand it well.

So, first, I created some test data in the ‘Labeled’ category within the ‘Saved’ section of the android app, which should be saved to gmm_myplaces.db.

I configured the Home and Work locations and added a custom label for the Airport. Additionally, I included a contact in the label section. To add the address for the home of the ‘Mickey Mouse’ contact, I searched for Magic Kingdom in Orlando and saved it from there. However, it seems like it saved as coordinates instead of an address. Perhaps I should test that a bit more later.

Now, let’s open the gmm_myplaces.db in DB Browser for SQLITE.

twitter:image

I have four saved labels on Google Maps, but only three in the database. So let’s dig in that a bit. According to Josh Hickman’s blog post, the key_string ‘0:0’ corresponds to home, and ‘1:0’ is for work. We have the timestamps of the label, the latitude, longitude information and the sync_item blob is in protobuf format.

Now, let’s examine the sync_item data for home 0:0 in Mushy. (I know, if you’ve read his blog, this information isn’t new for now.)

In examining it, we can observe the address, the latitude, the timestamp and the Google Maps URL. One difference from Josh Hickman’s findings is that I don’t have the longitude in it. The work label protobuf blob is similar to the home one so let’s skip this one.

Now, let’s inspect the protobuf data for the row 3 with the key_string 3:7243743950465490508.

So now, we can say that this corresponds to the custom label I created with ‘Airport’ as its label name. It’s containing the same info type as the Home and Work label but as we can see, the red box is a new key that we didn’t have in the home or work label and represent the custom label name we assigned when we created it.

Now that we have more information about what is saved to the database, I need to investigate why I didn’t get the longitude as Josh Hickman did in Mushy. To explore another approach, I saved the sync_item blob data to a file and used blackboxprotobuf with Python to see if I could obtain the same information as Mushy. To learn a bit more how to use blackboxprotobuf in python, I looked to the youtube video DFIR parsing of protobuf data in Python by Alexis Brignoni

Here’s the small python code I used to read the file :

import blackboxprotobuf

with open("proto", 'rb') as f:
	pb = f.read()
	print(blackboxprotobuf.decode_message(pb))

Here’s the print of the output:

```
({'2': b'3:7243743950465490508', '6': {'1': {'1': 3, '2': 7243743950465490508}, '2': b'Montr\xc3\xa9al-Pierre Elliott Trudeau International Airport (YUL), Bd Rom\xc3\xa9o Vachon Nord (Arriv\xc3\xa9es), Dorval, QC H4Y 1H1', '3': b'0x4cc93d7753d8c92b:0x1e30a8791014678d', '4': {'1': 45465685, '2': -73745481}, '5': 1701876724017, '7': b'Airport', '6': b'http://maps.google.com/?q=Montr%C3%A9al-Pierre+Elliott+Trudeau+International+Airport+(YUL),+Bd+Rom%C3%A9o+Vachon+Nord+(Arriv%C3%A9es),+Dorval,+QC+H4Y+1H1&ftid=0x4cc93d7753d8c92b:0x1e30a8791014678d'}}, {'2': {'type': 'bytes', 'name': ''}, '6': {'type': 'message', 'message_typedef': {'1': {'type': 'message', 'message_typedef': {'1': {'type': 'int', 'name': ''}, '2': {'type': 'int', 'name': ''}}, 'name': ''}, '2': {'type': 'bytes', 'name': ''}, '3': {'type': 'bytes', 'name': ''}, '4': {'type': 'message', 'message_typedef': {'1': {'type': 'int', 'name': ''}, '2': {'type': 'int', 'name': ''}}, 'name': ''}, '5': {'type': 'int', 'name': ''}, '7': {'type': 'bytes', 'name': ''}, '6': {'type': 'bytes', 'name': ''}}, 'name': ''}})
```

If we examiner the value for '4': {'1': 45465685, '2': -73745481}, it appears to represent the longitude. It seems that Mushy might have an issue with the value, or perhaps there was an problem on my end with my config … That’s why we always need to test and validate our tools and our finding.

After conducting these tests, I made modifications to the googleMapsGMM artifact parser in ALEAPP to include the Label location information from the gmm_myplace.db file. Here’s the result with Aleapp:

To continue testing the database, let’s update the work label to a new location and remove the Airport label since we can’t modify a custom label. Now, let’s examine the database :

The timestamp and location were updated and the custom label “Airport” is deleted. Now, let’s run Aleapp again to observe to the last data:

It appears that the timestamp for the home and work labels is updated with the last modification date, while the custom label reflects the creation date since it cannot be modified.

This covers the information we can extract from the gmm_myplaces.db database and its usage. Moving forward, I plan to conduct further tests and research to pinpoint the storage location of the ‘Mickey Mouse’ contact within the Labels since it’s not with the other labels. Additionally, I aim to contribute more to community projects like ALEAPP.

Leave a Comment