Page 1 of 2

Broken Image

Posted: Thu Jan 01, 2009 2:08 am
by m!nus
my png analyzing tool (which i initially wrote for floating because it was annoying me) finally was good for something

here my solving way:

Code: Select all

Chunk #000: Chunk Type: 'IHDR' (0x49484452)

            File Offset:            8 Bytes

            Chunk Size:            13 Bytes

            CRC32:          0x86287E8C (ok)

Chunk #001: Chunk Type: 'tEXt' (0x74455874)

            File Offset:           33 Bytes

            Chunk Size:            71 Bytes

            CRC32:          0xD65A6431 (ok)

Chunk #002: Chunk Type: 'sRGB' (0x73524742)

            File Offset:          116 Bytes

            Chunk Size:             1 Bytes

            CRC32:          0xAECE1CE9 (ok)

Chunk #003: Chunk Type: 'IDAT' (0x49444154)

            File Offset:          129 Bytes

            Chunk Size:         8 192 Bytes <- 8KiB

            CRC32:          0x75A4EE8D (ok)

Chunk #004: Chunk Type: 'IDAT' (0x49444154)

            File Offset:        8 333 Bytes

            Chunk Size:         4 096 Bytes <- 4KiB

            CRC32:  0xE57B5BEA (0x280EC8A3)

Chunk #005: Chunk Type: 'ú«Áæ' (0xFAABC1E6) <- chunk type wrong, chunk length cant be the problem, previous chunklength must be wrong, 4KiB <-> 8KiB, assuming the byte/bit error here :D

            File Offset:       12 441 Bytes

            Chunk Size:  -346 184 731 Bytes

            CRC32:  0x (0x863A3A1C)

...lots of errors following...

Posted: Thu Jan 01, 2009 2:13 am
by m!nus
adum! i cant edit my post, it say topic already exists!

Posted: Fri Jan 02, 2009 4:51 pm
by theStack
I solved it with a PNG header description and a hex editor, was not that hard.
Fortunately the error was quite at the beginning so it took only a few minutes :D

And yes, I've had the "can't edit post because I started the thread"-problem too, maybe an admin can fix that bug?

Posted: Sat Feb 14, 2009 5:23 pm
by megabreit
I thought that the error would be (very probably) in the data not in the header...
That's why I wrote my png "analyser" to find out what chunk is broken.
Then I just wanted to insert the correct CRC and see.
I was very supprised that my analyser stopped working in the middle of the data :shock:
Finally a hex editor did the job for me.

Nice challenge! :lol:

Posted: Mon Sep 07, 2009 11:22 am
by ftfish
my first thought was to perform a brute force substitution, but the size of the image is too large.
so i had to checkout wiki for specifications of png format.
after knowing a bit of the structure of png, i tried to trace the Python Imaging Lib reading that png file.
when an error comes, the lib is NOT processing the checksum but chunkname
so i knew that the problem was the previous chunksize and wrote a piece of python code to fix it.
the output of my code is:

Chunkname=IHDR, Chunksize=13
Chunkname=tEXt, Chunksize=71
Chunkname=sRGB, Chunksize=1
Chunkname=IDAT, Chunksize=8192
Chunkname=IDAT, Chunksize=4096
True size should be 8192

Posted: Sun Dec 27, 2009 1:01 am
by Force4
I used the well-known 'pngckeck' tool under linux.
Thought the size of the second idat chunk was weird... So I tried to resize 0x10 -> 0x20, and it worked. I got quite lucky!

Posted: Sun Dec 27, 2009 1:54 am
by DaymItzJack
Force4 wrote:I used the well-known 'pngckeck' tool under linux.
Thought the size of the second idat chunk was weird... So I tried to resize 0x10 -> 0x20, and it worked. I got quite lucky!
I think I got even luckier because I just copied the length from the other chunk and it was thankfully the same.

Posted: Sun Sep 05, 2010 5:59 pm
by HugStuart
Well, I done it by bruteforce. I wrote a short Matlab-script, which manipulated each byte and checked, if there was a readable png. It took about 10 hours. However the picture still seemed to be broken, though the text was readable. Can somebody verify, that the position of the broken byte was at about 8336 (dez.)? Thanks!

Posted: Mon Sep 06, 2010 6:33 pm
by megabreit
Check m!nus' post! Chunk no. 004 is nearly there. Since only the chunk size was wrong you should be able to view the whole png... and yes, it displayed a broken/cut film strip.

Posted: Tue Aug 30, 2011 2:09 pm
by moose
This one took me quite long and I analyzed much more than this. I thought the size might be ok and checked many other things ... but a post in the forum got me back on the right track.

Posted: Thu Sep 22, 2011 10:15 pm
by IIMOG
I used a free PNG Analyzer (http://wolfgangfellger.de/en/product,4) and found the corrupt byte as Force4 did.

Posted: Fri Feb 03, 2012 1:37 pm
by aurora
this challenge took me quite a while to figure out, what to do -- i than wrote a little php script to test the IDAT chunks ... und fixed the byte in some hex editor. anyway -- i learned a lot interesting stuff about the png format because of this challenge ...

Posted: Mon Apr 28, 2014 7:07 am
by Hippo
I have chosen brute force, just needed to detect if the resulting muted image is valid.
... but the file was too huge and some mutations shut down the "validator".
So I had to do it propper way ... I have decided to find the broken chunk so I start with creating the list of chunks ... and broken byte appeared.

I have expected the problem to be elsewhere :(...

... made another mutation on other place and was able to correct it ... checksum calculation was several orders of magnitude faster than writing image and checking it's correctness.

Posted: Wed Apr 08, 2015 12:10 am
by Valar_Dragon
I found the broken IDAT using pngcheck, and I was convinced this had to do with a bad CRC code. I got tired of trying to change bytes manually, so I started looking at the length field and it worked!

Posted: Fri May 15, 2015 11:36 pm
by haellowyyn
Actually, brute-force works quite well, since the changed byte is at the beginning of the file. I used Python and the Pillow library which is really great for anything image-related:

Code: Select all

import io
from PIL import Image

def fixit():
    byts = open('BrokenImage.png', 'rb').read()
    for i in range(0, len(byts)):
        x = bytearray(byts)
        for c in range(256):
            x[i] = c
            f = io.BytesIO(x)
            try:
                Image.open(f).verify()
            except (SyntaxError, OSError, IndexError):
                continue
            finally:
                f.close()
            print('Done! Replaced bit {} with {:#x}.'.format(i, c))
            with open('FixedImage.png', 'wb') as f:
                f.write(x)
            return

fixit()

It finds the corrupted Byte within 7 minutes on my laptop. Searching the whole file would probably need half a day.[/url]