> For the complete documentation index, see [llms.txt](https://sarpers-organization.gitbook.io/ctftricks/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sarpers-organization.gitbook.io/ctftricks/_chapter-intro-5/file-format/forensics-file-format-chunk-analysis.md).

# Chunk Analysis

## PNG Chunk Size Calculation

When a PNG chunk's length field is corrupted but the start of the *next* chunk is known (e.g., found using `binwalk`), you can calculate the correct data size. The process involves analyzing the file structure, calculating the correct length, and writing the corrected length back into the file.

A PNG chunk consists of a 4-byte length field, a 4-byte chunk type, the data payload, and a 4-byte CRC. The total size of a chunk is its data length plus 12 bytes (4 for length, 4 for type, 4 for CRC). If the start offset of a corrupted chunk (`current_chunk_offset`) and the start offset of the *next* chunk (`next_chunk_offset`) are known, the correct data length can be calculated. The `next_chunk_offset` is equal to `current_chunk_offset + data_length + 12`. Therefore, the `data_length` is `next_chunk_offset - current_chunk_offset - 12`.

For example, if a chunk starts at offset `0x57` and the next chunk starts at `0x10008`:

* The current chunk starts at `0x57`.
* The next chunk starts at `0x10008`.
* The calculation using the formula `next_chunk_offset - current_chunk_offset - 12` becomes: `0x10008 - 0x57 - 12` = `0x10008 - 0x63` = `0xFFA5`.

The calculated size `0xFFA5` (or `65445` decimal) represents the size of the data section. This value needs to be written back into the 4-byte length field *before* the chunk type, in big-endian format (`00 00 FF A5`).

`binwalk` is a tool commonly used to find the start of embedded files and structures within a file, which can help identify the offsets of PNG chunks. Once the offsets are determined, a script can be used to modify the file. The correct length can be calculated and packed into a 4-byte big-endian integer before being written back to the file at the start of the corrupted chunk.

Here is a Python example demonstrating this process:

```python
import struct

# Assume these offsets are found using binwalk or similar tools
corrupted_chunk_offset = 0x57
next_chunk_offset = 0x10008
file_path = "corrupt.png" # Replace with your file path

# Calculate the correct data length
# Length = Offset of next chunk - Offset of current chunk start - 12 (4 bytes type + 4 bytes CRC + 4 bytes length field itself)
correct_length = next_chunk_offset - corrupted_chunk_offset - 12

# Pack the new length as a big-endian 4-byte integer (>I)
packed_length = struct.pack(">I", correct_length)

# Write the new length back into the file
try:
    with open(file_path, "r+b") as f:
        # Seek to the beginning of the corrupted chunk's length field
        f.seek(corrupted_chunk_offset)
        # Write the packed length
        f.write(packed_length)
    print(f"Corrected length {correct_length} (0x{correct_length:X}) written to offset 0x{corrupted_chunk_offset:X}")
except FileNotFoundError:
    print(f"Error: File not found at {file_path}")
except Exception as e:
    print(f"An error occurred: {e}")

```

This script calculates the correct length based on the known offsets and the PNG chunk structure, then uses the `struct` module to format the length as a big-endian 4-byte integer, and finally writes it back into the file at the appropriate offset.

***

## PNG Chunk Structure Analysis

Analyze the sequence and boundaries of chunks within a PNG file to understand its layout and identify anomalies. Beyond the initial header, files like PNGs are composed of distinct chunks. Analyzing the structure of these chunks, including their start positions, lengths, and types, helps understand the file's composition. A PNG file consists of a PNG signature followed by a series of chunks. A chunk consists of four parts: Length, Chunk type, Chunk data, and CRC.

Use `xxd` to create a hexadecimal dump of a file, which allows focused examination of specific regions, useful for looking past known fixed sections or at potential chunk boundaries. The left column in `xxd` output indicates the byte offset.

```bash
xxd <file>
```

Options like `-g` can group bytes differently (e.g., `-g 1` for single bytes).

```bash
xxd -g 1 -s 0x53 <file> | head
```

Specific sections can be examined using offset and length parameters. The `-s` option allows specifying a starting offset, and `-l` specifies the length of data to dump. For instance, to view 0x20 bytes starting from offset 0x50, with 16 bytes per line using the `-c` option:

```bash
xxd -c 16 -s 0x50 -l 0x20 file
```

`xxd -p` can produce a raw plain hexdump output without offsets or ASCII representation, which is useful for piping into other commands or for converting back to binary using `xxd -r -p`.

```bash
xxd -p <file>
xxd -r -p <hex_data>
```

Use `binwalk`, a firmware analysis tool, to scan for known chunk signatures and map their locations, even if preceding structure is incorrect. This is effective for finding occurrences of specific chunk types and their offsets within the file.

```bash
binwalk -R "<chunk_type>" <file>
# Example:
binwalk -R "IDAT" <file>
```

A general scan can reveal various structures within the file:

```bash
binwalk <file>
```

`binwalk` can also be used to automatically extract embedded files or data streams it identifies using the `-e` flag.

```bash
binwalk -e <file>
```

Identifying consecutive chunks using these methods is key for subsequent size calculations or data extraction. Data within specific chunks, such as the IDAT chunk which contains image pixel data, is often compressed, typically using zlib. Tools like `zlib-flate` can be used to decompress such data streams.

```bash
zlib-flate -uncompress < <compressed_data>
```

Alternatively, decompression can be performed using scripting languages like Python:

```python
import zlib
# Assume 'compressed_data' contains the raw zlib compressed bytes from a chunk
decompressed_data = zlib.decompress(compressed_data)
```

Analyzing the decompressed data is crucial for understanding the actual image content or identifying hidden information within the pixel data streams. PNG files store 16-bit depth data in big-endian byte order (most significant bytes first).
