Home Manual Recovery of Location Data From JPG
Post
Cancel

Manual Recovery of Location Data From JPG

img-1

This post is a walkthrough of how to manually recover location data from an image using a hex editor (HxD). I will provide two methods for doing this.

I will be using an intentionally corrupted image that I created. If you’d like to try it yourself, you can open this image in a new tab and download it, then open it in a hex editor. Corrupted Image

Most of the image data has been overwritten with null values, which is why the image doesn’t display anything when its opened. This is meant to simulate what might happen if the image file were deleted and partially overwritten, but without the complicated overwritten data and just null values instead. There is just enough data remaining from the original image for it to be identified as a valid image and the important EXIF data still remains in the file! All of this data can be viewed using a Hex Editor such as HxD.

EXIF Tool (Simple Method)

You might try taking the jpg file and using an online EXIF tool to view the location data.

Exif Tool

Unfortunately, this won’t return any of the useful EXIF information. This has to do with the TIFF Header Structure of this corrupted image. TIFF stands for Tag Image File Format and its used to represent raster graphics(2-D Images as a grid of pixels) and store image information (like location data or created date).

HxD

When looking at a JPG in a hex editor, the first few offsets of the file contain some important information for the EXIF tool to identify the image and the metadata it has.

FF D8 is at offset 0 and 1, and identifies the start of a JFIF, JPE, JPEG, or JPG. These offsets are crucial for the EXIF tool. If these offsets were missing, the EXIF tool would not recognize this file as a JPG.

There is also a trailer FF D9 which identifies the end of the file.

The next few offsets can optionally contain an EXIF Tool tag name or an SPIFF tag name. This data has been tampered with, DE AD BE EF spells DEADBEEF and doesn’t provide any useful information other than that the files data has been tampered with. These offsets aren’t important for the EXIF tool in finding the metadata anyways.

Offset 12 is where the fun begins and leads towards the first solution of this challenge.

The start of the TIFF Header Structure can begin with either 4D 4D (MM in ascii) or 49 49 (II in ascii). Here, there is a 4D for an M, but only just one. If you are clever and realize there should be two M’s, you might change the null value at offset 13 to 4D, save the change and reupload the image to an EXIF Tool.

Changed

Exif

Exif

With this simple change the exiftool has everything it needs to identify all the IFD entries, including the location data.

Well Done

BUT…if you are an intellectually starving nerd like myself, you might push on to understand where this data actually lives in the file. Why? Because why not? You can’t just leave knowledge on the table.

Image File Directory (IDF) Searching for GPS Data

Byte Order and IFD Offset

The TIFF Header Structure is 8 bytes long.

/assets/img/Corrupted Image/8-byte-tiff.png

BytesHex ValuesMeaning
0 to 74D 4D 00 2A 00 00 00 088-Bytes
0 to 14D 4DByte Order
2 to 300 2ATIFF File
4 to 700 00 00 08Offset of the first IFD

Image File Directory

This is where the image data pointers and metadata are stored. This directory could come before or after the actual image data itself.

In this case, the IFD0 is located at offset 8. This is heavily confusing because we just looked at offsets 12 to 19 to see the 8 byte TIFF Header Structure. What this offset 8 byte value actually means is to start from the beginning of the TIFF File. The TIFF file began at offset 12 with a value of 4D. We need to add 8 bytes starting from offset 12 and look at the next bytes to see the first IFD entry.

To put it another way, we can add 12 bytes from the very beginning of the file.

IFD0

IFD0

BytesHex ValueMeaning
+ 0200 0D13 Directory Entries
+ 1201 00 00 03 00 00 00 01 0F C0 00 00Entry 0
+ 1201 01 00 03 00 00 00 01 0B D0 00 00Entry 1
+ 1201 0F 00 02 00 00 00 08 00 00 00 AAEntry 2
+ 1201 10 00 02 00 00 00 09 00 00 00 B2Entry 3
+ 1201 12 00 03 00 00 00 01 00 01 00 00Entry 4
+ 1201 1A 00 05 00 00 00 01 00 00 00 BCEntry 5
+ 1201 1B 00 05 00 00 00 01 00 00 00 C4Entry 6
+ 1201 28 00 03 00 00 00 01 00 02 00 00Entry 7
+ 1201 31 00 02 00 00 00 0E 00 00 00 CCEntry 8
+ 1201 32 00 02 00 00 00 14 00 00 00 DAEntry 9
+ 1202 13 00 03 00 00 00 01 00 01 00 00Entry 10
+ 1287 69 00 04 00 00 00 01 00 00 00 EEEntry 11
+ 1288 25 00 04 00 00 00 01 00 00 03 1EEntry 12
+ 0400 00 00 00Offset to next IDF (None)

The first 2 bytes tell us that there are 13 12-byte entries that follow. Then the next IFD is pointed to at the end.

12-Byte Field Entry 0 Breakdown

The first 12 bytes are broken down as follows:

BytesHex ValueMeaningInformation
0 to 1101 00 00 03 00 00 00 01 0F C0 00 00IFD Entry 012-Bytes
0 to 101 00Field Identifying Tag256 = Exif.Image.ImageWidth
2 to 300 03Field TypeSHORT (2 byte unsigned integer)
4 to 700 00 00 01Count of the Type1 count
8 to 110F C0 00 00The Value Offset0FC0 = 4032

Bytes 8 to 11 don’t actually point to an IFD value offset. Rather, the value of the image width is recorded here instead since it fits in 4 bytes or less. The value is the first 4 bytes starting from the left. 0F C0 means the width is 4032 and this is confirmed by looking back at the EXIF tool results:

Exif

The 12 byte field entries contain the metadata we want to view. In this first directory entry we looked at the Exif.Image.ImageWidth data. Using an Exif tags table as a reference, we can look for the directory entry that has GPS Info.

GPS Info Tag

The GPS info tag has the hex value of 8825 and can be searched for within the 13 12-byte entries.

GPS-info-tag

Looking back at the table above, the 13th directory entry contains an Exif Tag for GPS info.

12-byte breakdown of IFD Entry 13

ByteHexMeaingInformation
0 to 1188 25 00 04 00 00 00 01 00 00 03 1EIFD Entry 1312-Bytes
0 to 188 25Field Identifying TagGPSTag
2 to 300 04Field TypeLONG (4 byte unsigned integer)
4 to 700 00 00 01Count of the Type1 count
8 to 1100 00 03 1EThe Value OffsetOffset 798

Starting from the beginning of the TIFF File, the GPS IFD should start at offset 798 and what follows is a new IFD with its own number of 12-byte entries and values.

GPS-Info-IFD

Following the same IFD structure of 2-byte number of entries and then x number of 12-byte entries, we can determine what this IFD has in it.

GPS Info IFD Breakdown

BytesHexMeaning
0 to 100 099 Directory Entries
 00 01 00 02 00 00 00 02 4E 00 00 00Entry 0
 00 02 00 05 00 00 00 03 00 00 03 90Entry 1
 00 03 00 02 00 00 00 02 57 00 00 00Entry 2
 00 04 00 05 00 00 00 03 00 00 03 A8Entry 3
 00 05 00 01 00 00 00 01 00 00 00 00Entry 4
 00 06 00 05 00 00 00 01 00 00 03 C0Entry 5
 00 07 00 05 00 00 00 03 00 00 03 C8Entry 6
 00 1B 00 07 00 00 00 0C 00 00 03 E0Entry 7
 00 1D 00 02 00 00 00 0B 00 00 03 ECEntry 8
 00 00 00 00 00Offset to Next IFD (None)

There are 9 directory entries in this GPS Info IFD. A GPS Info Tag reference can be used to identify the field tags.

Entry #Field TagField TypeCountValue
0GPSLatitudeRefASCII2N
1GPSLatitudeRATIONAL3Value at offset 0390 = 42 58 13.1555
2GPSLongitudeRefASCII2W
3GPSLongitudeRATIONAL3Value at offset 03A8 = 85 40 13.7531
4GPSAltitudeRefBYTE10 = Above Sea Level
5GPSAltitudeRATIONAL1Value at offset 03C0 = 180.552
6GPSTimeStampRATIONAL3Value at offset 03C8 = 23:28:24 UTC
7GPSProcessingMethodUNDEFINED12Skip
8GPSDateStampASCII11Value at offset 03EC = 2023:09:27

Each RATIONAL Field Type consists of 2 LONGs. The first LONG is the numerator and the second LONG is the denominator. I converted the hex values to their decimal value and divided.

As an example, Entry 1 contains 3 RATIONAL values.

The first value is a LONG at offset 0390 is 00 00 00 2A (42) followed by the second LONG 00 00 00 01 (1) The second value is 00 00 00 3A (58), followed by the second LONG 00 00 00 01 (1) The third value is a LONG 00 02 01 E3 (131555) and the second LONG 00 00 27 10 (10000) After dividing 131555 by 10000 you have 13.1555.

The 3 RATIONAL values are in a Degrees, Minutes, Seconds format. 42° 58' 13.155"

The Final Coordinates are: 42° 58' 13.155" N 85° 40' 13.7531" W

Exif

Ta-Da

Ta-Da

These coordinates are for this address:

1
2
3
United States District Court for the Western District of Michigan
110 Michigan Street Northwest, Grand Rapids, MI 49503 
United States of America

The original, uncorrupted image: Original

References:

https://www.garykessler.net/library/file_sigs.html https://www.cipa.jp/std/documents/e/DC-008-2012_E.pdf https://exiv2.org/tags.html https://docs.fileformat.com/image/exif/ https://exiftool.org/TagNames/GPS.html

This post is licensed under CC BY 4.0 by the author.