# CTF Forensics - 3D Printing / CAD File Forensics ## Table of Contents - [PrusaSlicer Binary G-code (.g / .bgcode)](#prusaslicer-binary-g-code-g-bgcode) - [QOIF (Quite OK Image Format)](#qoif-quite-ok-image-format) - [G-code Analysis Tips](#g-code-analysis-tips) - [G-code Side View Visualization (0xFun 2026)](#g-code-side-view-visualization-0xfun-2026) - [Uncommon File Magic Bytes](#uncommon-file-magic-bytes) --- ## PrusaSlicer Binary G-code (.g / .bgcode) **File magic:** `GCDE` (4 bytes) The `.g` extension is PrusaSlicer's binary G-code format (bgcode). It stores G-code in a block-based structure with compression. **File structure:** ```text Header: "GCDE"(4) + version(4) + checksum_type(2) Blocks: [type(2) + compression(2) + uncompressed_size(4) + compressed_size(4) if compressed + type-specific fields + data + CRC32(4)] ``` **Block types:** - 0 = FileMetadata (has encoding field, 2 bytes) - 1 = GCode (has encoding field, 2 bytes) - 2 = SlicerMetadata (has encoding field, 2 bytes) - 3 = PrinterMetadata (has encoding field, 2 bytes) - 4 = PrintMetadata (has encoding field, 2 bytes) - 5 = Thumbnail (has format(2) + width(2) + height(2)) **Compression types:** 0=None, 1=Deflate, 2=Heatshrink(11,4), 3=Heatshrink(12,4) **Thumbnail formats:** 0=PNG, 1=JPEG, 2=QOI (Quite OK Image) **Parsing and extracting G-code:** ```python import struct, zlib import heatshrink2 # pip install heatshrink2 with open('file.g', 'rb') as f: data = f.read() pos = 10 # After header while pos < len(data) - 8: block_type = struct.unpack('