Vorwort
Im Artikel »baseline TIFF« bin ich auf den Aufbau des TIFF-Formates eingegangen. Um die Eignung von TIFF-Dateien als Bildformat für die Langzeitverfügbarkeit (bzw. Langzeitarchivierung) zu testen, habe ich das Bild aus dem Beitrag genommen, leicht geändert und mit einem Fuzzing-Tool bitweise zerstört.Als Werkzeug habe ich zzuf genutzt, welches ich angewiesen habe, 1‰ aller Bits des Original-Bildes zufällig zu verändern.
$> zzuf -c -s87423 -r0.001 <example_tiff.tiff >fuzzy-0.001.tiff
$> display fuzzy-0.001.tiff
display.im6: fuzzy-0.001.tiff: invalid TIFF directory; tags are not sorted in ascending order. `TIFFReadDirectory' @ warning/tiff.c/TIFFWarnings/768.
display.im6: fuzzy-0.001.tiff: unknown field with tag 275 (0x113) encountered. `TIFFReadDirectory' @ warning/tiff.c/TIFFWarnings/768.
display.im6: fuzzy-0.001.tiff: unknown field with tag 16663 (0x4117) encountered. `TIFFReadDirectory' @ warning/tiff.c/TIFFWarnings/768.
display.im6: fuzzy-0.001.tiff: TIFF directory is missing required "StripOffsets" field. `MissingRequired' @ error/tiff.c/TIFFErrors/508.
Versuch einer Rekonstruktion des Image File Directory (IFD)
Versuchen wir das Bild zu rekonstruieren. Zur Erinnerung hier nochmal der Aufbau eines TIFFs:
Aufbau TIFF |
Das kaputte TIFF-Bild sieht als Hexdump so aus:
00000000 49 49 2a 00 28 03 00 00 00 00 00 00 00 00 00 00 |II*.(...........|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000050 00 00 00 00 00 00 00 00 00 00 00 0c 00 00 00 0c |................|
00000060 00 00 00 0c 00 00 00 0c 00 00 00 0c 00 00 00 0c |................|
00000070 00 00 00 01 00 00 00 09 00 00 00 04 00 00 00 00 |................|
00000080 00 00 00 05 00 00 00 0c 00 00 00 0c 00 00 00 0c |................|
00000090 00 00 00 0c 00 00 00 00 00 00 00 0c 00 00 00 0c |................|
000000a0 00 00 00 0c 00 00 00 0c 00 00 00 f6 00 00 00 f6 |................|
000000b0 00 00 00 fa 00 00 00 ff 00 00 00 f6 00 00 00 f6 |................|
000000c0 00 00 00 1a 00 00 00 d5 00 00 00 54 00 00 00 00 |...........T....|
000000d0 00 00 00 75 00 00 00 ff 00 00 00 f5 00 00 00 f5 |...u............|
000000e0 00 00 00 ef 00 00 00 00 00 00 00 ff 00 00 00 f4 |................|
000000f0 00 00 00 f5 00 00 00 f5 00 00 00 00 00 00 00 00 |................|
00000100 10 00 00 28 00 00 00 e3 00 00 00 00 00 00 00 00 |...(............|
00000110 00 00 00 00 00 00 00 cb 00 00 00 51 00 00 00 00 |...........Q....|
00000120 00 00 00 70 00 00 00 af 00 00 00 01 00 00 00 01 |...p............|
00000130 00 00 00 00 00 00 00 00 00 00 00 ff 00 00 00 00 |................|
00000140 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000150 00 00 00 34 00 00 00 e4 00 00 00 00 00 00 00 00 |...4............|
00000160 00 00 00 00 00 00 00 cb 00 00 00 51 00 00 00 00 |...........Q....|
00000170 10 00 00 70 00 00 00 da 00 00 00 8b 00 00 00 8c |...p............|
00000180 00 00 00 00 00 00 00 00 00 00 00 ff 00 00 00 88 |................|
00000190 00 00 00 8b 00 00 00 3d 00 00 00 00 00 00 00 00 |.......=........|
000001a0 00 00 00 34 00 00 00 e4 00 00 00 00 00 00 00 00 |...4............|
000001b0 00 00 00 00 00 00 00 cb 00 00 00 51 00 00 00 00 |...........Q....|
000001c0 00 00 00 70 00 00 00 ce 00 00 00 63 00 00 00 63 |...p.......c...c|
000001d0 00 00 00 00 00 00 00 00 00 00 00 ff 00 00 00 5f |..............._|
000001e0 00 00 00 63 00 00 00 2b 00 00 00 00 00 00 00 00 |...c...+........|
000001f0 00 00 00 35 00 00 00 e8 00 00 00 00 00 00 00 00 |...5............|
00000200 00 00 00 00 00 00 00 cf 00 00 00 52 00 00 00 00 |...........R....|
00000210 00 00 00 72 00 00 00 af 00 00 00 00 00 00 00 00 |...r............|
00000220 00 00 00 00 00 00 01 00 20 00 00 ff 00 00 00 00 |........ .......|
00000230 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000240 00 00 00 2c 00 00 00 c2 00 00 00 00 00 00 00 00 |...,............|
00000250 00 00 00 00 00 00 00 ad 00 00 00 44 00 00 00 00 |...........D....|
00000260 00 00 00 5f 00 00 00 94 00 00 00 00 00 00 00 00 |..._............|
00000270 00 00 00 00 00 00 00 00 00 00 00 e7 00 00 00 00 |................|
00000280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000290 00 00 00 0e 00 00 00 3c 00 00 00 00 00 00 00 00 |.......<........|
000002a0 00 00 00 00 00 00 00 35 00 00 00 15 00 00 00 00 |.......5........|
000003b0 00 00 00 1d 00 00 00 2e 00 00 00 00 00 00 00 00 |................|
000002c0 00 00 00 00 00 00 00 00 00 00 00 47 00 00 00 00 |...........G....|
000002d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000310 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000320 00 00 00 00 00 00 00 00 12 00 fe 00 04 00 01 00 |................|
00000330 00 00 00 00 00 00 00 01 03 00 01 00 00 00 14 00 |................|
00000340 00 00 01 01 03 00 01 00 00 00 0a 00 00 00 02 01 |................|
00000350 03 00 04 00 00 00 06 04 00 00 03 01 03 00 01 00 |................|
00000360 00 00 01 00 00 00 06 01 03 00 01 00 00 00 02 00 |................|
00000370 00 00 0d 01 02 00 2a 00 00 00 0e 04 00 00 06 01 |......*.........|
00000380 02 00 0e 00 00 00 38 04 00 00 13 01 04 00 01 00 |......8.........|
00000390 00 00 08 00 00 00 12 01 03 00 01 00 00 00 01 00 |................|
000003a0 00 00 15 01 03 00 01 00 00 00 04 00 00 00 16 01 |................|
000003b0 03 00 01 00 00 00 40 00 00 00 17 41 04 00 01 00 |......@....A....|
000003c0 00 00 20 03 00 00 1a 01 05 00 01 00 00 00 46 04 |.. ...........F.|
000003d0 00 00 1b 01 05 00 01 00 00 00 4e 04 00 00 1c 01 |..........N.....|
000003e0 03 00 01 00 00 00 01 00 00 00 28 01 03 00 01 00 |..........(.....|
000003f0 00 00 02 00 00 00 52 01 03 00 01 00 00 00 01 00 |......R.........|
00000400 00 00 00 00 00 00 08 00 08 00 08 00 08 00 2f 68 |............../h|
00000410 6f 6d 65 2f 72 6f 6d 65 79 6b 65 2f 44 6f 6b 75 |ome/romeyke/Doku|
00000420 6d 65 6e 74 65 2f 65 78 61 6d 70 6c 65 5f 74 69 |mente/example_ti|
00000430 66 66 2e 74 69 66 66 00 54 65 73 74 62 69 6c 64 |ff.tiff.Testbild|
00000440 20 54 49 46 46 00 00 00 00 48 00 00 00 01 00 00 | TIFF....H......|
00000450 00 48 00 00 00 01 |.H....|
00000456
Schauen wir uns zu erst die 8 Bytes des Headers an. Das einzig Kritische könnte ein zerstörter Offset zum IFD sein:
00000000 49 49 2a 00 28 03 00 00 00 00 00 00 00 00 00 00 |II*.(...........|
Die ersten zwei Bytes sind in Ordnung, da sie nur zwei Werte annehmen können:
0x4949 little endian (least significant to most significant byte)
0x4d4d big endian (most significant to least significant byte)
Die nächsten zwei Bytes stellen die Zahl 42 in jeweiliger Endianess dar: 2a 00 ist also auch in Ordnung.
Die Bytes 4-7 zeigen auf das erste Image File Directory (IFD), hier die Adresse 0x0000 0328.
Kann dieser Wert stimmen?
Von IFDs wissen wir, daß diese wie folgt aufgebaut sind:
Aufbau Image File Directory (IFD) in TIFF-Datei |
An der Adresse 0x0328 stehen ff. Werte:
00000320 00 00 00 00 00 00 00 00 12 00 fe 00 04 00 01 00 |................|
00000330 00 00 00 00 00 00 00 01 03 00 01 00 00 00 14 00 |................|
00000340 00 00 01 01 03 00 01 00 00 00 0a 00 00 00 02 01 |................|
00000350 03 00 04 00 00 00 06 04 00 00 03 01 03 00 01 00 |................|
00000360 00 00 01 00 00 00 06 01 03 00 01 00 00 00 02 00 |................|
00000370 00 00 0d 01 02 00 2a 00 00 00 0e 04 00 00 06 01 |......*.........|
00000380 02 00 0e 00 00 00 38 04 00 00 13 01 04 00 01 00 |......8.........|
00000390 00 00 08 00 00 00 12 01 03 00 01 00 00 00 01 00 |................|
000003a0 00 00 15 01 03 00 01 00 00 00 04 00 00 00 16 01 |................|
000003b0 03 00 01 00 00 00 40 00 00 00 17 41 04 00 01 00 |......@....A....|
000003c0 00 00 20 03 00 00 1a 01 05 00 01 00 00 00 46 04 |.. ...........F.|
000003d0 00 00 1b 01 05 00 01 00 00 00 4e 04 00 00 1c 01 |..........N.....|
000003e0 03 00 01 00 00 00 01 00 00 00 28 01 03 00 01 00 |..........(.....|
000003f0 00 00 02 00 00 00 52 01 03 00 01 00 00 00 01 00 |......R.........|
00000400 00 00 00 00 00 00 08 00 08 00 08 00 08 00 2f 68 |............../h|
00000410 6f 6d 65 2f 72 6f 6d 65 79 6b 65 2f 44 6f 6b 75 |ome/romeyke/Doku|
00000420 6d 65 6e 74 65 2f 65 78 61 6d 70 6c 65 5f 74 69 |mente/example_ti|
00000430 66 66 2e 74 69 66 66 00 54 65 73 74 62 69 6c 64 |ff.tiff.Testbild|
00000440 20 54 49 46 46 00 00 00 00 48 00 00 00 01 00 00 | TIFF....H......|
00000450 00 48 00 00 00 01 |.H....|
00000456
Die Anzahl der Tags ergibt sich aus den Bytes 0x0328 und 0x0329 mit Wert 0x12 und 0x00, was für 18 Einträge steht. Dieser Wert klingt erstmal plausibel. Wir wissen, daß jedes Tag 12 Byte groß ist und im baseline-TIFF der nextIFD-Eintrag aus 4Bytes mit dem Wert 0x00 besteht. Schauen wir also an die Adresse 0x0328+2+12*18 = 0x402. Dort stehen 4 mal die Werte 0x00. Sieht erst einmal korrekt aus.
Wir können also annehmen, daß das IFD korrekt ist. Jeder Eintrag im IFD besteht ja aus 12 Bytes und ist wie folgt aufgebaut:
Tag-Eintrag |
- 1. 0x32a: 0xfe 0x00 -> 254
- 2. 0x336: 0x00 0x01 -> 64
- 3. 0x342: 0x01 0x01 -> 257
- 4. 0x34e: 0x02 0x01 -> 258
- 5. 0x35a: 0x03 0x01 -> 259
- 6. 0x366: 0x06 0x01 -> 262
- 7. 0x372: 0x0d 0x01 -> 269
- 8. 0x37e: 0x06 0x01 -> 262
- 9. 0x38a: 0x13 0x01 -> 275
- 10.0x396: 0x12 0x01 -> 274
- 11.0x3a2: 0x15 0x01 -> 277
- 12.0x3ae: 0x16 0x01 -> 278
- 13.0x3ba: 0x17 0x41 -> 16663
- 14.0x3c6: 0x1a 0x01 -> 282
- 15.0x3d2: 0x1b 0x01 -> 283
- 16.0x3de: 0x1c 0x01 -> 284
- 17.0x3ea: 0x28 0x01 -> 296
- 18.0x3f6: 0x52 0x01 -> 338
Ins Auge fallen die Tags 2, 6, 8, 13 u. 18. Insbesondere Tag 2 und 13 können nicht stimmen, da sie krass die Sortierung verletzten. Eventuell müssen wir die Tags 6-10 nochmal prüfen.
Der Tag 2 an Adresse 0x336 müsste einen Wert um die 250 enthalten.Sehr wahrscheinlich ist, daß er statt 0x00 0x01 die Folge 0x01 0x00 enthält, was dem Wert 256 entspräche.
Der Tag 13 an Adresse 0x3ba hat wahrscheinlich im zweiten Byte nur einen Bit-Fehler und sollte statt 0x17 0x41 die Folge 0x17 0x01 enthalten. Das ergebe dann den Wert 279.
Tragen wir die Tag-Bezeichner und die vorläufig korrigierten Tags des IFD ein:
- 1. 0x32a: 0xfe 0x00 -> 254 -> TIFFTAG_SUBFILETYPE
- 2. 0x336: 0x00 0x01 -> 256 -> TIFFTAG_IMAGEWIDTH
- 3. 0x342: 0x01 0x01 -> 257 -> TIFFTAG_IMAGELENGTH
- 4. 0x34e: 0x02 0x01 -> 258 -> TIFFTAG_BITSPERSAMPLE
- 5. 0x35a: 0x03 0x01 -> 259 -> TIFFTAG_COMPRESSION
- 6. 0x366: 0x06 0x01 -> 262 -> TIFFTAG_PHOTOMETRIC
- 7. 0x372: 0x0d 0x01 -> 269 -> TIFFTAG_DOCUMENTNAME
- 8. 0x37e: 0x06 0x01 -> 262 -> TIFFTAG_PHOTOMETRIC
- 9. 0x38a: 0x13 0x01 -> 275 -> (nicht existent)
- 10.0x396: 0x12 0x01 -> 274 -> TIFFTAG_ORIENTATION
- 11.0x3a2: 0x15 0x01 -> 277 -> TIFFTAG_SAMPLESPERPIXEL
- 12.0x3ae: 0x16 0x01 -> 278 -> TIFFTAG_ROWSPERSTRIP
- 13.0x3ba: 0x17 0x01 -> 279 -> TIFFTAG_STRIPBYTECOUNTS
- 14.0x3c6: 0x1a 0x01 -> 282 -> TIFFTAG_XRESOLUTION
- 15.0x3d2: 0x1b 0x01 -> 283 -> TIFFTAG_YRESOLUTION
- 16.0x3de: 0x1c 0x01 -> 284 -> TIFFTAG_PLANARCONFIG
- 17.0x3ea: 0x28 0x01 -> 296 -> TIFFTAG_RESOLUTIONUNIT
- 18.0x3f6: 0x52 0x01 -> 338 -> TIFFTAG_EXTRASAMPLES
Bis auf Eintrag 9 und eventuell Eintrag 18 klingen die Tags so sinnvoll, daß sie richtig sein könnten. Tag 9 muß dann zwischen 262 und 274 liegen und könnte ff. Tags enthalten:
- TIFFTAG_THRESHHOLDING 263
- TIFFTAG_CELLWIDTH 264
- TIFFTAG_CELLLENGTH 265
- TIFFTAG_FILLORDER 266
- TIFFTAG_DOCUMENTNAME 269
- TIFFTAG_IMAGEDESCRIPTION 270
- TIFFTAG_MAKE 271
- TIFFTAG_MODEL 272
- TIFFTAG_STRIPOFFSETS 273
$> tiffinfo fuzzy-0.001.tiff
TIFFReadDirectoryCheckOrder: Warning, Invalid TIFF directory; tags are not sorted in ascending order.
TIFFReadDirectory: Warning, Unknown field with tag 275 (0x113) encountered.
TIFFReadDirectory: Warning, Unknown field with tag 16663 (0x4117) encountered.
MissingRequired: TIFF directory is missing required "StripOffsets" field.
Also ist Eintrag 9 mit hoher Wahrscheinlichkeit das Tag TIFFTAG_STRIPOFFSETS mit ID 273.
Ende Teil1