[File] [PATCH] of Magdir/map for Garmin map (*.img *.vpm)
Christos Zoulas
christos at zoulas.com
Fri Dec 28 00:23:28 UTC 2018
On Dec 27, 11:48pm, joerg.jen.der.ek at gmx.net (=?UTF-8?Q?J=c3=b6rg_Jenderek?=) wrote:
-- Subject: [File] [PATCH] of Magdir/map for Garmin map (*.img *.vpm)
| This is a multi-part message in MIME format.
| --------------76E2A1FFE5BDC63CAB613494
| Content-Type: text/plain; charset=utf-8
| Content-Transfer-Encoding: 8bit
|
| Hello,
|
| some days ago i run file command version 5.35 on some Garmin map (*.img)
| and voice files (*.vpm). All such inspected examples are misidentified
| as "DOS/MBR boot sector".
|
| According to page about Garmin ".img" format on Wikipedia such examples
| are used by Garmin navigation devices use to store the maps. So i add
| that URL and magic lines to Magdir/map.
|
| >From there i found on SourceForge a PDF document imgformat-1.0.pdf with
| title "Garmin IMG File Format". So i add that URL as reference.
|
| Unfortunately the informations in that document dated about year 2005
| are incomplete or sometimes wrong, because John Mechalas gets file
| format information by reverse engineering.
|
| First i look for a signature at end of 1st block.
| 0x1FE leshort =0xAA55
| This looks similar to MBR boot sector handled by ./filesystems. That
| explains the misidentification. So at least one additional test line is
| needed. According to documentation look for valid signatures like
| DSKIMG\0 or DSDIMG\0 by line:
| >0x13 string =IMG\0
| That was sufficient for my examples. So Garmin staff is identified and
| now i call subroutine to display information about that file format by lines
| >>0 use garmin-map
| 0 name garmin-map
| >0 ubyte x Garmin
| !:mime application/x-garmin-map
|
| Display map description ( two parts, 0x20 padded) like
| "Freizeitkarte_PYRENEES (Release 18.09)" in PYRENEES_en_gmapsupp.img by
| lines
| >0x49 string x %.20s
| >0x65 string >\ \b%.31s
|
| Some field are not interesting for "normal" users. So i add lines as
| comments like for checksum:
| #>0xF ubyte x \b, Checksum 0x%x
|
| In some fields often standard values are used. So display that value
| only if unusual values are used like for 8-char signature field by line:
| >0x10 string !DSKIMG \b, signature "%.7s"
|
| According to PDF document after the information inside header the
| remaining 314 bytes should be nils. This is true for real maps, but
| wrong for gmaptz.img and all *.vpm examples according to my own
| experiments. So print non nil value by line:
| >0x84 uquad !0 \b, at 0x84 0x%llx
|
| The img format itself is a container for other data sub files. Depending
| on sub files things are different. Inspired by DOS FAT file system meta
| information about sub files is stored in a File Allocation table (FAT).
| Each FAT block is 512 bytes in length and the physical block number of
| FAT beginning is stored at offset 0x40 according to openstreetmap wiki.
| This information can be displayed by a line like:
| #>0x40 ubyte x \b, FAT at phy. block %u
| By pointer expression goto block before FAT by line
| >>(0x40.b*512) ubyte x
| Then jump relative to next block. Now we are at 1st FAT entry and
| inspect FAT entry metadata information by calling sub routine like:
| >>>&511 use garmin-fat
| It is not needed but for interest i also display the first four FAT
| entries by 3 additional lines
| >>>&1023 use garmin-fat
| >>>&1535 use garmin-fat
| >>>&2047 use garmin-fat
|
| In the FAT entry the stored information makes only sense to be displayed
| after some tests. Check if the entry is not sub part and flag for true
| sub file is set. This is done by lines:
| 0 name garmin-fat
| >0 ubyte x \b;
| >0x10 uleshort =0
| >>0 ubyte =1
| Afterwards now show sub-file name like MAKEGMAP or 12345678 by line
| >>>0x1 string x %.8s
| Next comes the sub-file typ like RGN TRE MDR LBL. This is shown by line:
| >>>0x9 string x \b.%.3s
| This is the most interesting part, because each sub-file typ carries a
| specific data. Some known file sub-types are:
| ⢠RGN. Map elements such as poly lines, polygons and points.
| ⢠LBL. Labels for map elements, city names, localities, etc.
| ⢠TRE. Map structure information that organizes the map elements into a
| data tree.
| Afterwards come the 32-bit block sequence numbers used by FAT entry.
| This can be shown by line like
| #>>>0x20 ubequad x \b, seq. 0x%16.16llx
| To store big maps a trick is used, which is known for DOS experts. The
| unit used for counting block is not the physical block size, but the
| logical block size. So with a large logical block size like 16384 in
| sample CARPATHIAN_en_gmapsupp.img it is possible to address many map
| elements with details. The logical block size is stored in the header in
| exponent fields E1 and E2. The logical block size is is calculated by
| formula:
| blocksize=2**(E1+E2)
|
| Exponent E1 appears to be always be 0x09 which gives a minimum block
| size of 512 bytes. So instead E1 and E2 show for usual block sizes the
| values by lines:
| >0x61 ubyte !0x09 \b, E1=%u
| >>0x62 ubyte x \b, E2=%u
| >0x61 ubyte =0x09 \b, blocksize
| >>0x62 ubyte 0 512
| >>0x62 ubyte 1 1024
| >>0x62 ubyte 2 2048
| >>0x62 ubyte 3 4096
| >>0x62 ubyte 4 8192
| >>0x62 ubyte 5 16384
| >>0x62 default x
| >>>0x62 ubyte x E2=%u
|
| For most garmin map file name extension ".img" is used. But some maps
| with extension ".vpm" contains garmin voice processing module (normally
| handled by Magdir/audio and further container for WAV sounds handled by
| Magdir/riff). My inspected VPM samples contain in first FAT entry the
| name "DLLINFO TXT". So look for that name. If found it is a map with
| voice part. If not then it is a normal IMG map. This is done in
| subroutine by lines like:
| 0 name garmin-map
| >0 ubyte x Garmin
| >(0x40.b*512) ubyte x
| >>&512 string =DLLINFO\ TXT map (Voice Processing)
| !:ext vpm
| >>&512 string !DLLINFO\ TXT map
| !:ext img
|
| After applying the above mentioned modifications by patch
| file-5.35-map-img.diff then all inspected examples are now described by
| Magdir/map like:
|
| CARPATHIAN_en_gmapsupp.img:
| Garmin map v0.00 Freizeitkarte_CARPATHIAN (Release 18.09)
| updated 2018-09, created 2018-09-12 19:27:44,
| blocksize 16384, at 0x74000 156 bytes "GARMIN TYP"
| ; MAKEGMAP.MPS, 13612 bytes
| ; next 0x0003
| ; MAKEGMAP.MPS, 13612 bytes
| ; 00008070.TYP, 38347 bytes
| gmaptz.img:
| Garmin map v11.02 Time Zone Map
| updated 2013-01, created 2013-01-07 9:46:41,
| blocksize 1024
| ; TIMEZONE.RGN, 573378 bytes
| ; flag 0
| ; flag 0
| ; flag 0
| , at 0x84 0x503de
| test-map.img:
| Garmin map v0.00 TEST_MAP_ ,
| updated 2018-12, created 2018-12-23 4:18:00,
| blocksize 512, at 0xc00 125 bytes "GARMIN RGN"
| ; 19088743.RGN, 512 bytes
| ; next 0x0003
| ; 19088743.RGN, 512 bytes
| ; 19088743.TRE, 241 bytes
| Deutsch__Yannick_D4481-00_0210.vpm:
| Garmin map (Voice Processing) v2.10 yannick ,
| updated 2014-09, created 2014-09-19 11:46:41,
| blocksize 1024
| ; DLLINFO .TXT, 1034 bytes
| ; flag 0
| ; flag 0
| ; flag 0
| , at 0x84 0x202de
| English_British_Serena.vpm:
| Garmin map (Voice Processing) v1.30 serena ,
| updated 2013-05, created 2013-05-30 11:14:46,
| blocksize 1024
| ; DLLINFO .TXT, 820 bytes
| ; flag 0
| ; flag 0
| ; flag 0
| , at 0x84 0x202de
|
| I hope my diff file can be applied in future version of file utility.
Added thanks!
| I tried to remove the misidentification, but i failed. In theory it
| should be possible to distinguish "DOS/MBR boot sector", "DOS executable
| (COM), boot code" and "Linux kernel x86 boot executable" by looking for
| appearance or absence of characteristic patterns like:
| >0x1FE leshort 0xAA55 \b, boot code
| in Magdir/msdos or in Magdir/linux
| 514 string HdrS Linux kernel
| or test lines
| 0x1FE leshort !0xAA55 NO x86 BOOT SIGNATURE
| 514 string !HdrS NO Linux kernel
|
| Unfortunately if size of inspected samples is low enough ( for example
| only 446 bytes) then the above lines and followers are never executed by
| file command version 5.35 and no error message is displayed. Maybe
| somebody is smart enough to fix this behavior. That would be nice.
Why would be the inspected samples short?
Thanks,
christos
More information about the File
mailing list