[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