#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2004
    Posts
    8
    Rep Power
    0

    Extracting PNG from Binary @ 0x50


    Hi,

    Frederick Lundh himself gave me this chunk of code..and I can't get it to work. I was hoping one of you could spot the error.

    The goal is to extract a png image file from a binary simcity 4 file.
    Code:
    import struct
    
    def pngcopy(infile, outfile):
    
       # copy header
       header = infile.read(8)
       if header != "\211PNG\r\n\032\n":
           raise IOError("not a valid PNG file")
       outfile.write(header)
    
       # copy chunks, until IEND
       while 1:
           chunk = infile.read(8)
           size, cid = struct.unpack("!l4s", chunk)
           outfile.write(chunk)
           outfile.write(infile.read(size))
           outfile.write(infile.read(4)) # checksum
           if cid == "IEND":
               break
    
    infile = open("/home/flamesrock/Desktop/peachville.sc4", "rb")
    infile.seek(0x50)
    outfile = open("myimage.png", "wb")
    pngcopy(infile, outfile)
    outfile.close()
    infile.close()
    Screenshot of the hex editor in action:


    The simcity 4 binary file(for anyone who wants to try extracting):
    http://simcitysphere.com/peachville.sc4

    Any ideas on why this isn't working? It makes perfect sense to me, even as a relative newb, but it doesn't work?

    -thanks in advance
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2003
    Posts
    624
    Rep Power
    34
    Any ideas on why this isn't working?
    Yes, two;

    - 0x50 isn't the location in the file, it's the hexadecimal representation of the ASCII code for the uppercase character "P", so the seek() call wont be going to the right place...

    Code:
    >>> help(ord)
    
    >>> ord("P")
    80
    >>> hex(ord("P"))
    0x50
    Second, your screenshot shows "...PNG" (0000 8950 4E47 0D0A...), but the function is looking for "\211PNG\r\n..." (02 3131 504E47 0D0A...) which is, I think, why it immediately throws the IOException.

    As for what to do about it... I don't know.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2004
    Posts
    8
    Rep Power
    0
    Mucho gracias and sorry for the late reply.

    Shouldn't seek() goto the PNG since it contains the first P in the binary file?

    Second, your screenshot shows "...PNG" (0000 8950 4E47 0D0A...), but the function is looking for "\211PNG\r\n..." (02 3131 504E47 0D0A...) which is, I think, why it immediately throws the IOException.
    Ahhhh...good eye. I'm starting to think there might be some sort of compression...

    I'll post back as soon as I find a solution to this..if ever.

    (observations or pointers still welcome!)

    -thanks
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2003
    Posts
    624
    Rep Power
    34
    Shouldn't seek() goto the PNG since it contains the first P in the binary file?
    No - it seeks for the file position you specify, e.g. move 8 bytes backwards or move 20 bytes from the start of the file, it doesn't look at the content at all.

IMN logo majestic logo threadwatch logo seochat tools logo