mbirth / gcd-parser Goto Github PK
View Code? Open in Web Editor NEWPython parser and tools for GCD and RGN firmware files.
Python parser and tools for GCD and RGN firmware files.
--- a/grmn/updateserver.py
+++ b/grmn/updateserver.py
@@ -9,7 +9,10 @@ from . import devices
from .proto import GetAllUnitSoftwareUpdates_pb2
from xml.dom.minidom import getDOMImplementation, parseString
from urllib.parse import unquote
+import random
+import string
import requests
+import cloudscraper
PROTO_API_GETALLUNITSOFTWAREUPDATES_URL = "http://omt.garmin.com/Rce/ProtobufApi/SoftwareUpdateService/GetAllUnitSoftwareUpdates"
WEBUPDATER_SOFTWAREUPDATE_URL = "https://www.garmin.com/support/WUSoftwareUpdate.jsp"
@@ -109,7 +112,8 @@ class UpdateInfo:
class UpdateServer:
def __init__(self):
- self.device_id = "2345678910"
+ rnd_id = ''.join(random.choice(string.digits) for i in range(10))
+ self.device_id = rnd_id
self.unlock_codes = []
self.debug = False
<Model>
<PartNumber>006-B3466-00</PartNumber>
<SoftwareVersion>1440</SoftwareVersion>
<Description>Instinct Solar Tactical</Description>
</Model>
I am not sure if you guys still needed this data but here it is.
Hi,
I have found a use case of this cool parser, to downgrade the firmware of vivoactive 3 (tested with my own device). The idea is to repack a 'higher' version of the firmware from the version you want to downgrade, and fraud the device that you've put a newer firmware into it.
For example, If the current version of your device is 7.50, you want to roll back to 7.30.
get_updates.py
.gcddump.py
to dump the file.# Reset/Downgrade flag
0x000b = 0x01
# Firmware version
0x100d = 0x02f8
gcdcompile.py
to recompile the firmware.GUPDATE.gcd
and put it to /GARMIN folder.WARNING: Use at your own risk. DO NOT roll back to 6.x when your firmware is 7.x. Please don't ask me how I knew. I've bricked my device by doing this. 🤣 🤣 🤣
P.S. Does anyone know how to un-brick Vivoactive 3? It stuck at the screen of blue triangle. Plug it to the PC but nothing happens.
I used gcdstruct.py to extract the various sections of a GUPDATE.GCD file for my watch (Forerunner 245 Music). The binary for TLV Type 0x02bd is between 7MB and 8MB. Looking at the file a bit, it seems that the first 0x1fd000 bytes (including padding) are a binary that would sit in flash, which makes sense as the internal flash is 2MB. However, that leaves a question of what the structure of the rest of the file is. Running binsum.py finds a valid sha1sum near the end of the file, but that is only one small portion of what remains.
Do you know anything else about the structure of the rest of TLV Type 0x02bd? Or would I be better off following up with the Alex W. mentioned in binsum.py (I assume this is them?)
<Model>
<PartNumber>
006-B3126-00
</PartNumber>
<SoftwareVersion>
1440
</SoftwareVersion>
<Description>
Instinct
</Description>
</Model>
the dumping result doesn't have loader section
original fw can be downloaded from:
https://download.garmin.com/software/Fenix5SAPAC_GCDfile__2500.gcd
https://www8.garmin.com/support/download_details.jsp?id=4749 this is the software for the garmin fishing sonars suite. It is a little bit unusual since it contains a lot of subfiles in an update folder. The main update appears to be for all the various devices, but I found it quite hard to map any of those files to device ids.
These devices don't use the 006-B* profile but many different categories:
https://www8.garmin.com/support/ch.jsp?product=010-01864-00 for example
I'm not sure if support for those, or a way to find the mapping would be possible... but I'm open to suggestions and happy to suggest
some code for that:)
Hi!
I found a discussion about converting a 601 to 701 where you suggested to look for a translation function which checks if the desired language is installed and then locates the array of strings and selects PTR_sLanguage + stringId.
Could you tell me more on how to locate this function? I'm a little bit lost at the moment so I will appreciate any help. We can communicate via e-mail if you prefer (gerne auch in deutscher Sprache ;-).
Thank you in advance
$ ./get_updates.py -W 006-B2909-00
Device 2909 (guessed): Edge 130
Querying Garmin Express ... done.
Querying Garmin WebUpdater ...Traceback (most recent call last):
File "./get_updates.py", line 108, in <module>
results += us.query_webupdater(device_skus)
File "./gcd-parser/grmn/updateserver.py", line 145, in query_webupdater
r.fill_from_response_dom(resp)
File "./gcd-parser/grmn/updateserver.py", line 87, in fill_from_response_dom
size_bytes = float(size_kb) * 1024
ValueError: could not convert string to float: 'Unknown size'
A small contribution, thanks for sharing your great work.
The Fenix 6 series and a few other Garmin devices that use the Sony CXD5603GF chipset for GPS have an alternate SKU (your table is blank)
006-B3107-01
"GPS Software, Fenix 6 Series WW"
Note that ends in -01 and is slightly different than the listing for Forerunner 945, ending in -00 , 006-B3107-00
I believe Garmin calls it GPS Chipset Type S1 (3107) but the -00 is only up to v2.90 while -01 is up to 5.50
I am not sure what the difference is, they have international versions of these watches and APAC firmwares that have additional support for the Chinese GPS BeiDou and then the MARQ Aviator that has US WAAS GPS support while other models do not?
Also researching how to create CPE.BIN on demand for the Sony chipsets (equal to MediaTek EPO.BIN)
(old) https://www8.garmin.com/support/download_details.jsp?id=14841
./get_updates.py -W 3291
Device 3291 (guessed): fenix 6X Pro
Querying Garmin WebUpdater ...Traceback (most recent call last):
File "./get_updates.py", line 108, in <module>
results += us.query_webupdater(device_skus)
File "/usr/src/GARMIN/gcd-parser/grmn/updateserver.py", line 132, in query_webupdater
reply = self.get_webupdater_softwareupdate(requests_xml)
File "/usr/src/GARMIN/gcd-parser/grmn/updateserver.py", line 290, in get_webupdater_softwareupdate
r.raise_for_status()
File "/usr/lib/python3/dist-packages/requests/models.py", line 940, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 530 Server Error: for url: https://www.garmin.com/support/WUSoftwareUpdate.jsp
# ./gcdcompile.py v3.rcp out.gcd
Opening recipe v3.rcp
Parsing BLOCK_0
Parsing BLOCK_1
Parsing BLOCK_2
Parsing BLOCK_3
Parsing BLOCK_4
Parsing BLOCK_7
Parsing BLOCK_10
Traceback (most recent call last):
File "./gcdcompile.py", line 19, in <module>
gcd = Gcd.from_recipe(RECIPE)
File "/usr/src/GARMIN/gcd-parser/grmn/gcd.py", line 221, in from_recipe
tlv7.load_dump(params)
File "/usr/src/GARMIN/gcd-parser/grmn/tlv.py", line 357, in load_dump
numval = int(v, 0)
ValueError: invalid literal for int() with base 0: "b'\\xb7zX\\xff3*\\x89K\\x97\\xdd\\xa3T\\xa0\\xd7(E\\xc0o\\xdf\\xc8\\xe6{Jk\\xbc\\xa9\\x14\\xd2H\\x12$'"
Hello, is it what you're looking for ? :
<Model>
<PartNumber>006-B2769-00</PartNumber>
<SoftwareVersion>350</SoftwareVersion>
<Description>Foretrex 601</Description>
</Model>
Wanted to thank you for sharing this awhile back, I wrote some messy php for myself based on your code/method.
I noticed you updated the device list last month but I don't see Fenix 7 or Epix 2 in there?
Note they are also releasing the Forerunner 955 and 255 on June 1st 2022
But of course no telling when those part numbers will be searchable.
By the way I noticed they use a similar url for their software distribution, would be interesting to see update history on things like Express, etc.
"omt.garmin .com/Rce/ProtobufApi/ApplicationService/GetApplicationUpdate"
(space inserted to break domain on purpose from linking)
gcdstruct output:
`Opening .\SW_INVNTRY.GCD
#000: TLV Type 0001 at 0x8, 1 Byte - Checksum rectifier
#1: TLV Type 0002 at 0xd, 21 Bytes - Padding
#2: TLV Type 0003 at 0x26, 9 Bytes - Part number?
#3: TLV Type 0005 at 0x33, 55 Bytes - Copyright notice
#4: TLV Type 0001 at 0x6e, 1 Byte - Checksum rectifier
#5: TLV Type 0002 at 0x73, 3977 Bytes - Padding
#6: TLV Type 0001 at 0x1000, 1 Byte - Checksum rectifier
#7: TLV Type 0006 at 0x1005, 10 Bytes - Block Type 7 format definition
GCD file is attached
SW_INVNTRY.zip
Hi, do not hesitate to contact me if you want the original GarminDevice file :-)
model ..
partnumber 006-B3282-00
-
softwareversion 440
-
description Forerunner 45S
-
id3341194188
006-B4071-00
703
Instinct 2 Solar
Thailand purchased
hi, we got garmin watches, that have as name tactix delta, but SKU is same as Fenix 6X Pro
this is snip from garmindevice.xml
<Model>
<PartNumber>006-B3291-00</PartNumber>
<SoftwareVersion>2300</SoftwareVersion>
<Description>tactix Delta</Description>
</Model>
Let me share GarminDevice.xml from fenix 7S Sapphire Solar
006-B3943-10
diff --git a/grmn/devices.py b/grmn/devices.py
index c1b51fe..8c9f61c 100644
--- a/grmn/devices.py
+++ b/grmn/devices.py
@@ -1232,6 +1232,7 @@ DEVICES = {
3914: "Forerunner 245 redesign",
3927: "Approach G12",
3934: "Approach S42",
+ 3943: "EPIX (Gen 2)",
3946: "SW, LTDM20, System Code, AOER",
3949: "venu 2S ASIA",
3950: "venu 2 ASIA",
./gcdstruct.py --verbose vivosmart4_480.gcd
Opening vivosmart4_480.gcd
#000: TLV Type 0001 at 0x8, 1 Byte - Checksum rectifier
#1: TLV Type 0002 at 0xd, 21 Bytes - Padding
#2: TLV Type 0003 at 0x26, 9 Bytes - Part number?
#3: TLV Type 0005 at 0x33, 55 Bytes - Copyright notice
#4: TLV Type 0001 at 0x6e, 1 Byte - Checksum rectifier
#5: TLV Type 0002 at 0x73, 3977 Bytes - Padding
#6: TLV Type 0001 at 0x1000, 1 Byte - Checksum rectifier
#7: TLV Type 0006 at 0x1005, 14 Bytes - Block Type 7 format definition
Is any tactix able to be loaded on Fenix 5? If so, could someone help me out.
When fixing #13, I've also noticed something strange: The Vector firmware has a TLV6 and TLV7 block with no actual binary data (Field 2015 - Binary length = 0). Since the actual binary data is absent, the two blocks aren't dumped to the rcp file. The struct looks like this:
Opening Vector3_380.gcd
#000: TLV Type 0001 at 0x8, 1 Byte - Checksum rectifier
#001: TLV Type 0005 at 0xd, 55 Bytes - Copyright notice
#002: TLV Type 0001 at 0x48, 1 Byte - Checksum rectifier
#003: TLV Type 0003 at 0x4d, 2 Bytes - Part number?
#004: TLV Type 0001 at 0x53, 1 Byte - Checksum rectifier
#005: TLV Type 0006 at 0x58, 14 Bytes - Block Type 7 format definition
- Field list: 1009 100a 2015 2017 2018 2019 5003
#006: TLV Type 0007 at 0x6a, 20 Bytes - Binary descriptor
- Field 1 (1009): Device hw_id: 0x0ae3 / 2787 (Vector 3)
- Field 2 (100a): Block type: 0x07d0 / 2000
- Field 3 (2015): Binary length: 0 Bytes <---- Zero length = no binary block following?
- Field 4 (2017): Field 2017: 0x2ada0 / 175520
- Field 5 (2018): Field 2018: 0xb998 / 47512
- Field 6 (2019): Field 2019: 0x3a6d0 / 239312
~~~~~~~~~~~ BINARY BLOCK MISSING HERE ~~~~~~~~~~~~~
#007: TLV Type 0001 at 0x82, 1 Byte - Checksum rectifier
#008: TLV Type 0006 at 0x87, 28 Bytes - Block Type 7 format definition
- Field list: 4007 0020 100a 000c 100d 100e 100f 1010 1011 1012 1013 2015 201a 5003
#009: TLV Type 0007 at 0xa7, 57 Bytes - Binary descriptor
When dumping, the TLV6 and TLV7 are tied to the actual binary data. Since there is none, they're not written to the RCP file. This needs to be refactored so compiling yields the original file.
<Model>
<PartNumber>006-B3291-00</PartNumber>
<SoftwareVersion>1670</SoftwareVersion>
<Description>fenix 6X Sapphire</Description>
</Model>
<Model>
<PartNumber>006-B1613-00</PartNumber>
<SoftwareVersion>400</SoftwareVersion>
<Description>nüvi 52</Description>
</Model>
I've got a dump of the onboard 2GB eMMc flash chip ( KLM2G1HE3F-B001) if it's helpful
<Model>
<PartNumber>006-B3725-00</PartNumber>
<SoftwareVersion>320</SoftwareVersion>
<Description>GPSMAP 65s</Description>
</Model>
Thank you for your work.
$ ./get_updates.py 006-B2787-03
$ wget http://download.garmin.com/software/Vector3_380.gcd
$ ./gcddump.py Vector3_380.gcd v3
Opening Vector3_380.gcd
Dumping to v3.rcp
Traceback (most recent call last):
File "./gcddump.py", line 21, in <module>
gcd.dump_to_files(OUTBASENAME)
File "/usr/src/GARMIN/gcd-parser/grmn/gcd.py", line 174, in dump_to_files
for item in tlv.dump():
File "/usr/src/GARMIN/gcd-parser/grmn/tlv.py", line 391, in dump
valstr = "0x{:08x}".format(v)
TypeError: unsupported format string passed to bytes.__format__
diff --git a/grmn/devices.py b/grmn/devices.py
index 2f5fefe..a27cc74 100644
--- a/grmn/devices.py
+++ b/grmn/devices.py
@@ -1137,7 +1137,7 @@ DEVICES = {
3572: "vivomove 3 Style/Luxe ASIA",
3573: "vivomove 3 Sport APAC",
3576: "Fusion MS-WB670",
- 3578: "fenix 5/5 Plus/Chronos, ???",
+ 3578: "Rally 100/200",
3589: "Forerunner 745",
3590: "Forerunner 745, Sensor Hub",
3591: "Forerunner 745, BLE_BT_ANT",
Model>
PartNumber>006-B2700-00
SoftwareVersion>810
Description>vívoactive 3
/Model>
Id>3978018694
$ ./get_updates.py 006-B3943-10
$ wget http://download.garmin.com/software/EPIX_Gen2__720.gsp
$ unzip EPIX_Gen2__720.gsp
Archive: EPIX_Gen2__720.gsp
extracting: package.xml
inflating: manifest.xml
extracting: bundle.gsp
$ ./gcdstruct.py bundle.gsp
Opening bundle.gsp
Traceback (most recent call last):
File "./gcdstruct.py", line 23, in <module>
gcd = Gcd(FILE)
File "gcd-parser/grmn/gcd.py", line 33, in __init__
self.load()
File "gcd-parser/grmn/gcd.py", line 43, in load
raise ParseException(RED + "Signature mismatch ({}, should be {})!".format(repr(sig) + RESET, repr(GCD_SIG)))
grmn.gcd.ParseException: Signature mismatch (b'\x85u\xc0\x96\x99\xf6\xa5\x9c', should be b'GARMINd\x00')!
I just recently found this project and saw no other way to contact the author.
I already compiled a lot of file format info that might be helpful here: https://www.memotech.franken.de/FileFormats. Relevant is the *.GCD and *.RGN format description, and the list of SKU numbers in the Garmin firmware file (*.BIN) description.
<Model>
<PartNumber>006-B3225-00</PartNumber>
<SoftwareVersion>690</SoftwareVersion>
<Description>vívoactive 4</Description>
</Model>
<Model>
<PartNumber>006-B0827-00</PartNumber>
<SoftwareVersion>780</SoftwareVersion>
<Description>nüvi 205W</Description>
</Model>
I was trying to extract a .rgn file obtained from
http://download.garmin.com/software/fenix3_tactixBravo_quatix3_940.rgn
by ./gcddump.py fenix3_tactixBravo_quatix3_940.rgn fenix3
which gives me the error
~/src/gcd-parser:λ ./gcddump.py fenix3_tactixBravo_quatix3_940.rgn fenix3
Opening fenix3_tactixBravo_quatix3_940.rgn
Traceback (most recent call last):
File "./gcddump.py", line 19, in <module>
gcd = Gcd(FILE)
File "/home/c/src/gcd-parser/grmn/gcd.py", line 33, in __init__
self.load()
File "/home/c/src/gcd-parser/grmn/gcd.py", line 43, in load
raise ParseException(RED + "Signature mismatch ({}, should be {})!".format(repr(sig) + RESET, repr(GCD_SIG)))
grmn.gcd.ParseException: Signature mismatch (b'KpGrd\x00\x02\x00', should be b'GARMINd\x00')!
Disabling signature checking gives me another error
~/src/gcd-parser/:λ ./gcddump.py fenix3_tactixBravo_quatix3_940.rgn fenix3
Opening fenix3_tactixBravo_quatix3_940.rgn
WARNING: File truncated. End marker not reached yet. (pos=2093176)
Dumping to fenix3.rcp
Any thoughts?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.