Understanding and Manipulating PNG Files

Published by Berkan K. on March 26

book 5 min read

In digital forensics, understanding “magic headers” is essential. These byte patterns at the beginning of files identify their type and are crucial for investigators analyzing file formats to gather evidence. This blog post dives into the importance of magic headers, particularly highlighting their role in adjusting the dimensions of a PNG file within the world of digital forensics.

What are Magic Headers?

Magic headers, also known as file signatures, are unique sequences of bytes placed at the beginning of files to signify their formats. These headers enable operating systems and applications to recognize file types without relying on file extensions, which can be easily renamed or altered. Magic headers are crucial in digital forensics for identifying and verifying file types, especially in data recovery and when dealing with files that have had their extensions changed to hide their true nature.

The ‘Magic’ of PNG Files

The Portable Network Graphics (PNG) format is widely used for its lossless compression and ability to handle transparency. A PNG file starts with a specific magic header, identifiable by the first eight bytes: 89 50 4E 47 0D 0A 1A 0A. This signature is critical for applications to recognize the file as a PNG.

Beyond the magic header, PNG files contain chunks that hold different types of data, such as the image’s actual pixel data, color information, and metadata. Of particular interest are the IHDR chunk, which contains the image’s dimensions, and how manipulating it can change the image’s size.

Structure of a Very Simple PNG File

PNG signature           | Image Header  | Image Data | Image End 
89 50 4E 47 0D 0A 1A 0A | IHDR          | IDAT       | IEND      

Contents of a minimal PNG file representing one red pixel

Hex	                                         As characters
89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 .PNG........IHDR
00 00 00 01 00 00 00 01 08 02 00 00 00 90 77 53 ..............wS
DE 00 00 00 0C 49 44 41 54 08 D7 63 F8 CF C0 00 .....IDAT..c....
00 03 01 01 00 18 DD 8D B0 00 00 00 00 49 45 4E .............IEN
44 AE 42 60 82                                  D.B`.

Let’s break down the structure of this minimal PNG file:

  • PNG Signature: The first eight bytes 89 50 4E 47 0D 0A 1A 0A represent the PNG magic header.
  • IHDR Chunk: The IHDR chunk contains the image’s width, height, bit depth, color type, compression method, filter method, and interlace method.
  • IDAT Chunk: The IDAT chunk holds the actual image data compressed using the DEFLATE algorithm.
  • IEND Chunk: The IEND chunk marks the end of the PNG file.

IHDR Chunk

  • Width: 00 00 00 01 (1 pixel)
  • Height: 00 00 00 01 (1 pixel)
  • Bit depth: 08 (8 bits per channel)
  • Color type: 02 (Truecolor with alpha)
  • Compression method: 00 (Deflate/inflate with a sliding window of at most 32768 bytes)
  • Filter method: 00 (Adaptive filtering with five basic filter types)
  • Interlace method: 00 (No interlace)

The IDAT chuck is out of the scope of this example, but it would contain the compressed pixel data for the red pixel. Read more about it here.

Changing PNG Dimensions by Modifying Width and Height in the IHDR Chunk

The IHDR chunk is the first chunk after the PNG file’s magic header and contains, among other things, the image’s width and height as previously mentioned. These dimensions are stored as four-byte integers, representing the width and height in pixels. By altering these bytes, you can change the perceived dimensions of the image without affecting the actual image data.

Example: Manipulating Image Size

Imagine a PNG image with dimensions 800x600 pixels. The width (800) and height (600) are encoded in the IHDR chunk in hexadecimal representation. The width 800 in hexadecimal is 0x0320, and the height 600 in hexadecimal is 0x0258.

To change the image size, you would:

  1. Locate the IHDR chunk, which follows the initial eight-byte magic header.
  2. Find the position of the width and height fields within the IHDR chunk.
  3. Modify the bytes representing width and height to the desired values using a hex editor or a similar tool.

For instance, to change the image dimensions to 1024x768 pixels:

  • 1024 in hexadecimal is 0x0400, and 768 is 0x0300.
  • You would replace the bytes representing the original width and height with the bytes for 0x0400 and 0x0300, respectively.
    • The first four bytes represent the width (800 pixels).
    • The next four bytes represent the height (600 pixels).
Original IHDR chunk:
00 00 03 20 00 00 02 58 08 02 00 00 00

Modified IHDR chunk:
00 00 04 00 00 00 03 00 08 02 00 00 00

And just like that, we’ve changed the image’s dimensions from 800x600 pixels to 1024x768 pixels by modifying the IHDR chunk.

Caution and Considerations

Modifying the IHDR chunk requires precision:

  • Incorrectly editing the file can corrupt it, making it unreadable.
  • The CRC (Cyclic Redundancy Check) for the chunk must also be recalculated and updated to reflect the changes, as it ensures the integrity of the data within the chunk.
Hello, I'm a 23-year-old Software Engineer based in Denmark, specializing in Cybersecurity and
Fullstack Development.

Beyond programming, I enjoy sharing my journey and insights through writing, aiming to contribute to the tech community and inspire like-minded professionals.

Post Details Category