Adding a language to a Garmin watch

Sometimes a Christmas miracle is needed to save the holidays. Sometimes it comes only thanks to some abundant free time and proclivity towards messing around with stuff. After buying a smart watch (Garmin Vivomove HR) for a relative, I found out, that it does not have the Slovak language available, even though it should according to the reviews. So I decided to somehow make it work.

Filesystem exploration

The best place to start is by connecting the watch to the PC with a USB cable. With the Garmin Express software installed, the watch allows its filesystem to be mounted and it can be browsed. I looked around and while there were many interesting folders, I first looked into the TEXT folder. It contained several .LNG files, one for each language, but none for Slovak.

Watch filesystem
OSCP Badge

The files had a relatively simple structure. Without looking into it too much I could easily identify some sort of ID in the first half of the file because it stood out from the surrounding binary mess. Further into the file are null byte delimited strings of the translated messages. If all else fails, it would be possible to translate every string, rewrite them and hope that the binary mess does not contain some kind of checksum or array of string lengths.

Finnish language

I took this as a sign to look for a Slovak language file on the internet. After some Google dorking I came across a somewhat obscure site, which seemed to list exactly the file I needed, but not without some weirdness. First of all, links were pointing to the legitimate Garmin website, and secondly, the Slovak language file was an exe file, not lng as one would expect. Obscure site

I followed the link to the official Garmin download page. However, it did not list any download links to the file. Curious to see how the obscure site got the download link, I checked the webpage source and saw a very interesting comment. Legitimate website comment

Great news! I had the link and knew how to load the file. The downloaded exe file looked structurally identical to the other lng files, so I took it just as a quirk of the website and did not pursue it further.

Loading the language into the watch

Both manufacturer-intended ways did not work. Using Garmin Express (as the non-commented section recommended) did not turn out fruitful, since there were no obvious ways to make it install the file. It did have a menu for “Language “, but according to some help websites it seems to find the languages on its own. And it did not find any it in this case. Garmin Express

Next, I tried the “commented way” using WebUpdater. Passing the language as an argument did not seem to change anything in its behavior. It did not seem to do anything with the file and certainly did not have the desired effect of adding the language. I also tried to disconnect it from the internet in various stages of the process so it could be forced to consider local files, but to no avail.

Garmin WebUpdater

In hindsight, these step-by-step solutions could be written for older versions and this functionality could be not supported in current ones. That being said, let’s try hacky solutions!

1st try – Just paste it into the folder

First I tried the most obvious thing possible – I just put the lng file into the TEXT folder and hoped the watch will pick it up. I tried both SLOVAK.LNG and SLOVAKIAN.LNG filenames because while Slovak is more typical to use, the Garmin website called its files “Slovakian”.

Unsurprisingly, that did not work. The watch probably does not read the contents of the folder, just follows some configuration file with a list of filenames. To find it I identified what could be an ID in a language file (Swedish one in this case) and did a Powershell equivalent of grep -r, which recursively goes through all of the files and looks for the string. Grepping to find ID

Turns out, there was an XML config Garmin\GarminDevice.xml, that specifies the languages.

2nd try – Edit the config

The GarminDevice.xml configuration file was an XML document, which specified many extensions and options for the watch. Most importantly, there was a section concerning the languages. Each line contained an ID found in the file as well as a path to the language file. Further in the XML file, there was also a section with LanguageSelectionList tag which contained some integers. However, these did not correspond to anything I could find, so I hoped they are not important. I only added a new line for the Slovak language with a correct ID and version number guessed from the official website, restarted the watched, waited, and hoped for the best.

GarminDevice.xml file

After the restart, there was no new language in the menu, so it did not work. The watch even went one step further and overwrote the new config file. Just to test if the new file did not pass some smell test I tried switching places of two XML elements and restarting the watch and it was overwritten again. So I pushed this way further down the list of things to try.

3rd try – rewriting another language

Finally, I tried a way simpler approach – to rewrite an already existing language. All of the configs could stay in place as they were, but the strings will be different. That being said, there could be many other checks the new file still needs to pass.

I decided to replace the Finnish language. I took the downloaded Slovak file, edited its ID to match the Finnish one, and replaced file FINNISH.LNG with this new one on the watch’s filesystem.

Edited Slovak language

After booting up the watch and choosing “FI” in the menu – success! The watch told me to set the time and the date in Slovak and the new translation worked flawlessly.

OSCP Badge
OSCP Badge
OSCP Badge

Sometimes doing a manufacturer-intended thing can become a CTF of its own.