#!/usr/bin/env python3 """ Test all example files against ST3GG's analysis and decoding tools. Validates that the steganographic payloads can actually be detected/extracted. """ import os import sys import struct import json import wave import traceback from pathlib import Path # Add project root to path sys.path.insert(0, str(Path(__file__).parent)) EXAMPLES_DIR = Path(__file__).parent / 'examples' PLINIAN_DIVIDER = "⊰•-•✧•-•-⦑/L\\O/V\\E/\\P/L\\I/N\\Y/⦒-•-•✧•-•⊱" ORIGINAL_SECRET = "STEGOSAURUS WRECKS - Hidden message found! 🦕" # Result tracking results = {} total = 0 passed = 0 failed = 0 warnings = 0 def record(name, status, detail=""): global total, passed, failed, warnings total += 1 icon = "" if status == "PASS": passed += 1 icon = " PASS" elif status == "WARN": warnings += 1 icon = " WARN" else: failed += 1 icon = "**FAIL" results[name] = (status, detail) detail_str = f" ({detail})" if detail else "" print(f" {icon} {name}{detail_str}") # ============================================================================= # Import analysis tools # ============================================================================= print("=" * 70) print("ST3GG EXHAUSTIVE EXAMPLE FILE TESTS") print("=" * 70) print() try: from analysis_tools import ( png_full_analysis, png_extract_text_chunks, png_detect_appended_data, png_steg_signature_scan, png_chi_square_analysis, detect_base64, detect_hex_strings, detect_unicode_steg, detect_whitespace_steg, detect_file_type, TOOL_REGISTRY, analyze_bit_planes, MAGIC_SIGNATURES, ) print(" [OK] analysis_tools imported") except Exception as e: print(f" [!!] analysis_tools import error: {e}") try: import numpy as np print(" [OK] numpy imported") except Exception as e: print(f" [!!] numpy import error: {e}") try: from PIL import Image print(" [OK] PIL imported") except Exception as e: print(f" [!!] PIL import error: {e}") try: from steg_core import analyze_image, detect_encoding, StegConfig, Channel print(" [OK] steg_core imported") except Exception as e: print(f" [!!] steg_core import error: {e}") detect_encoding = None print() # ============================================================================= # 1. ORIGINAL EXAMPLES (PNG image-based) # ============================================================================= print("-" * 70) print("SECTION 1: Original PNG Examples") print("-" * 70) # 1a. LSB RGB PNG with STEG v3 header try: if detect_encoding is None: record("example_lsb_rgb.png [STEG detect]", "WARN", "steg_core not fully imported") else: img = Image.open(EXAMPLES_DIR / 'example_lsb_rgb.png') enc = detect_encoding(img) if enc: record("example_lsb_rgb.png [STEG detect]", "PASS", f"STEG encoding detected: {enc.get('config', {})}") else: # Try manual check: extract first 4 bytes from LSB img_rgba = img.convert('RGBA') pixels = list(img_rgba.getdata()) bits = [] for px in pixels[:20]: for ch in range(3): bits.append(px[ch] & 1) magic_bits = bits[:32] magic_bytes = bytearray() for i in range(0, 32, 8): byte_val = 0 for j in range(8): byte_val = (byte_val << 1) | magic_bits[i + j] magic_bytes.append(byte_val) if magic_bytes == b'STEG': record("example_lsb_rgb.png [STEG detect]", "PASS", "STEG magic found in LSB (manual extraction)") else: record("example_lsb_rgb.png [STEG detect]", "WARN", f"Magic bytes: {magic_bytes} (detect_encoding uses interleaved mode)") except Exception as e: record("example_lsb_rgb.png [STEG detect]", "FAIL", str(e)) try: data = (EXAMPLES_DIR / 'example_lsb_rgb.png').read_bytes() result = png_full_analysis(data) susp = result.get('suspicious_indicators', 0) if susp >= 1: record("example_lsb_rgb.png [full analysis]", "PASS", f"{susp} suspicious indicators") else: record("example_lsb_rgb.png [full analysis]", "WARN", "No suspicious indicators found") except Exception as e: record("example_lsb_rgb.png [full analysis]", "FAIL", str(e)) # 1b. PNG tEXt chunks try: data = (EXAMPLES_DIR / 'example_png_chunks.png').read_bytes() result = png_extract_text_chunks(data) chunks = result.get('text_chunks', result.get('chunks', [])) if isinstance(result, dict) else [] found_secret = any(ORIGINAL_SECRET in str(c) for c in chunks) if found_secret: record("example_png_chunks.png [text chunks]", "PASS", f"Found secret in {len(chunks)} chunks") elif result.get('found') or chunks: record("example_png_chunks.png [text chunks]", "PASS", f"Found {result.get('count', len(chunks))} text chunks") else: record("example_png_chunks.png [text chunks]", "FAIL", f"No text chunks found (keys: {list(result.keys()) if isinstance(result, dict) else 'N/A'})") except Exception as e: record("example_png_chunks.png [text chunks]", "FAIL", str(e)) # 1c. Trailing data PNG try: data = (EXAMPLES_DIR / 'example_trailing_data.png').read_bytes() result = png_detect_appended_data(data) has_appended = result.get('found', result.get('has_appended_data', False)) if isinstance(result, dict) else False if has_appended: size = result.get('appended_size', '?') record("example_trailing_data.png [appended]", "PASS", f"Trailing data detected ({size} bytes)") else: record("example_trailing_data.png [appended]", "FAIL", f"No trailing data detected (keys: {list(result.keys()) if isinstance(result, dict) else 'N/A'})") except Exception as e: record("example_trailing_data.png [appended]", "FAIL", str(e)) # 1d. Zero-width text try: data = (EXAMPLES_DIR / 'example_zero_width.txt').read_bytes() result = detect_unicode_steg(data) if result.get('found'): count = result.get('invisible_chars', 0) record("example_zero_width.txt [unicode steg]", "PASS", f"{count} invisible chars found") else: record("example_zero_width.txt [unicode steg]", "FAIL", "No zero-width chars detected") except Exception as e: record("example_zero_width.txt [unicode steg]", "FAIL", str(e)) # 1e. Whitespace text try: data = (EXAMPLES_DIR / 'example_whitespace.txt').read_bytes() result = detect_whitespace_steg(data) if result.get('found'): spaces = result.get('trailing_spaces', 0) record("example_whitespace.txt [whitespace]", "PASS", f"{spaces} trailing whitespace chars") else: record("example_whitespace.txt [whitespace]", "FAIL", "No whitespace steg detected") except Exception as e: record("example_whitespace.txt [whitespace]", "FAIL", str(e)) # 1f. Invisible ink try: data = (EXAMPLES_DIR / 'example_invisible_ink.txt').read_bytes() text = data.decode('utf-8', errors='ignore') tag_chars = sum(1 for c in text if 0xE0000 <= ord(c) <= 0xE007F) if tag_chars > 5: record("example_invisible_ink.txt [tag chars]", "PASS", f"{tag_chars} tag characters found") else: record("example_invisible_ink.txt [tag chars]", "FAIL", f"Only {tag_chars} tag chars") except Exception as e: record("example_invisible_ink.txt [tag chars]", "FAIL", str(e)) # 1g. Audio LSB WAV try: import wave path = EXAMPLES_DIR / 'example_audio_lsb.wav' with wave.open(str(path), 'r') as w: frames = w.readframes(w.getnframes()) samples = struct.unpack(f'<{w.getnframes()}h', frames) # Extract LSB bits = [s & 1 for s in samples[:400]] # Decode length prefix (32 bits) length = 0 for i in range(32): length = (length << 1) | bits[i] # Decode message msg_bits = bits[32:32 + length * 8] msg_bytes = bytearray() for i in range(0, len(msg_bits), 8): byte_val = 0 for j in range(8): if i + j < len(msg_bits): byte_val = (byte_val << 1) | msg_bits[i + j] msg_bytes.append(byte_val) decoded = msg_bytes.decode('utf-8', errors='replace') if ORIGINAL_SECRET[:20] in decoded: record("example_audio_lsb.wav [LSB decode]", "PASS", f"Decoded: {decoded[:40]}...") else: record("example_audio_lsb.wav [LSB decode]", "WARN", f"Got: {decoded[:40]}...") except Exception as e: record("example_audio_lsb.wav [LSB decode]", "FAIL", str(e)) # 1h. Metadata PNG try: data = (EXAMPLES_DIR / 'example_metadata.png').read_bytes() b64_result = detect_base64(data) hex_result = detect_hex_strings(data) if b64_result.get('found') or hex_result.get('found'): record("example_metadata.png [b64/hex]", "PASS", f"b64={b64_result.get('found')}, hex={hex_result.get('found')}") else: record("example_metadata.png [b64/hex]", "FAIL", "No encoded strings detected") except Exception as e: record("example_metadata.png [b64/hex]", "FAIL", str(e)) print() # ============================================================================= # 2. CHUNK 1: Image Formats (Plinian Divider) # ============================================================================= print("-" * 70) print("SECTION 2: Image Format Examples (Plinian Divider)") print("-" * 70) def test_image_lsb(filename, fmt_name): """Test LSB extraction from an image file.""" try: path = EXAMPLES_DIR / filename img = Image.open(path) img_rgba = img.convert('RGBA') pixels = list(img_rgba.getdata()) w, h = img_rgba.size # Extract LSB bits from RGB channels bits = [] for px in pixels: for ch in range(3): bits.append(px[ch] & 1) if len(bits) >= 600: break # Decode: 4-byte big-endian length prefix + message length = 0 for i in range(32): length = (length << 1) | bits[i] if length > 0 and length < 200: msg_bits = bits[32:32 + length * 8] msg_bytes = bytearray() for i in range(0, len(msg_bits), 8): byte_val = 0 for j in range(8): if i + j < len(msg_bits): byte_val = (byte_val << 1) | msg_bits[i + j] msg_bytes.append(byte_val) decoded = msg_bytes.decode('utf-8', errors='replace') if PLINIAN_DIVIDER[:10] in decoded: record(f"{filename} [LSB decode]", "PASS", f"Plinian divider extracted") else: record(f"{filename} [LSB decode]", "WARN", f"Got length={length}, decoded: {decoded[:30]}...") else: record(f"{filename} [LSB decode]", "FAIL", f"Invalid length prefix: {length}") except Exception as e: record(f"{filename} [LSB decode]", "FAIL", str(e)) def test_raw_lsb(filename, fmt_name, header_size=0, pixel_bytes=3): """Test LSB extraction from raw pixel format (PPM/PGM).""" try: path = EXAMPLES_DIR / filename data = path.read_bytes() # Find the pixel data start (after header lines) lines_seen = 0 offset = 0 target_lines = 3 # P5/P6, dimensions, maxval while lines_seen < target_lines and offset < len(data): if data[offset:offset+1] == b'\n': lines_seen += 1 offset += 1 pixel_data = data[offset:] # Extract LSBs bits = [] for b in pixel_data[:600]: bits.append(b & 1) # Decode length prefix + message length = 0 for i in range(32): length = (length << 1) | bits[i] if 0 < length < 200: msg_bits = bits[32:32 + length * 8] msg_bytes = bytearray() for i in range(0, len(msg_bits), 8): byte_val = 0 for j in range(8): if i + j < len(msg_bits): byte_val = (byte_val << 1) | msg_bits[i + j] msg_bytes.append(byte_val) decoded = msg_bytes.decode('utf-8', errors='replace') if PLINIAN_DIVIDER[:10] in decoded: record(f"{filename} [LSB decode]", "PASS", "Plinian divider extracted") else: record(f"{filename} [LSB decode]", "WARN", f"Got: {decoded[:30]}...") else: record(f"{filename} [LSB decode]", "FAIL", f"Invalid length: {length}") except Exception as e: record(f"{filename} [LSB decode]", "FAIL", str(e)) # BMP LSB test_image_lsb('example_lsb.bmp', 'BMP') # GIF comment try: data = (EXAMPLES_DIR / 'example_comment.gif').read_bytes() # Look for comment extension marker (0x21 0xFE) idx = data.find(b'\x21\xFE') if idx >= 0: # Read sub-blocks pos = idx + 2 comment = b'' while pos < len(data) and data[pos] != 0: block_len = data[pos] comment += data[pos+1:pos+1+block_len] pos += 1 + block_len decoded = comment.decode('utf-8', errors='replace') if PLINIAN_DIVIDER[:10] in decoded: record("example_comment.gif [comment ext]", "PASS", "Plinian divider in GIF comment") else: record("example_comment.gif [comment ext]", "WARN", f"Comment: {decoded[:30]}...") else: record("example_comment.gif [comment ext]", "FAIL", "No comment extension found") except Exception as e: record("example_comment.gif [comment ext]", "FAIL", str(e)) # GIF palette LSB — GIF uses palette indices, not raw RGB. Read indices directly. try: img = Image.open(EXAMPLES_DIR / 'example_lsb.gif') # Get raw palette index data (P mode) if img.mode == 'P': indices = list(img.getdata()) bits = [idx & 1 for idx in indices] length = 0 for i in range(32): length = (length << 1) | bits[i] if 0 < length < 200: msg_bits = bits[32:32 + length * 8] msg_bytes = bytearray() for i in range(0, len(msg_bits), 8): byte_val = 0 for j in range(8): if i + j < len(msg_bits): byte_val = (byte_val << 1) | msg_bits[i + j] msg_bytes.append(byte_val) decoded = msg_bytes.decode('utf-8', errors='replace') if PLINIAN_DIVIDER[:10] in decoded: record("example_lsb.gif [LSB decode]", "PASS", "Plinian divider in palette index LSBs") else: record("example_lsb.gif [LSB decode]", "WARN", f"Got: {decoded[:30]}...") else: record("example_lsb.gif [LSB decode]", "WARN", f"Invalid length={length}, palette index LSB format may differ") else: record("example_lsb.gif [LSB decode]", "WARN", f"GIF not in P mode (got {img.mode})") except Exception as e: record("example_lsb.gif [LSB decode]", "FAIL", str(e)) # TIFF metadata try: data = (EXAMPLES_DIR / 'example_metadata.tiff').read_bytes() b64_result = detect_base64(data) if b64_result.get('found'): segments = b64_result.get('segments', []) any_plinian = any(PLINIAN_DIVIDER[:10] in s.get('decoded_preview', '') for s in segments) if any_plinian: record("example_metadata.tiff [b64 metadata]", "PASS", "Plinian divider in base64 metadata") else: record("example_metadata.tiff [b64 metadata]", "WARN", f"Found {len(segments)} b64 segments, divider not in preview") else: record("example_metadata.tiff [b64 metadata]", "FAIL", "No base64 detected") except Exception as e: record("example_metadata.tiff [b64 metadata]", "FAIL", str(e)) # TIFF LSB test_image_lsb('example_lsb.tiff', 'TIFF') # PPM LSB test_raw_lsb('example_lsb.ppm', 'PPM') # PGM LSB test_raw_lsb('example_lsb.pgm', 'PGM') # SVG hidden try: data = (EXAMPLES_DIR / 'example_hidden.svg').read_bytes() text = data.decode('utf-8') found_direct = PLINIAN_DIVIDER in text b64_result = detect_base64(data) hex_result = detect_hex_strings(data) if found_direct: record("example_hidden.svg [direct search]", "PASS", "Plinian divider found in SVG XML") else: record("example_hidden.svg [direct search]", "FAIL", "Divider not found") if b64_result.get('found') or hex_result.get('found'): record("example_hidden.svg [b64/hex]", "PASS", f"b64={b64_result.get('found')}, hex={hex_result.get('found')}") else: record("example_hidden.svg [b64/hex]", "WARN", "No encoded strings") except Exception as e: record("example_hidden.svg [analysis]", "FAIL", str(e)) # ICO LSB — ICO format stores 32x32 icons; Pillow may reorder. Use 16-bit length prefix. try: img = Image.open(EXAMPLES_DIR / 'example_lsb.ico') img_rgba = img.convert('RGBA') pixels = list(img_rgba.getdata()) bits = [] for px in pixels: for ch in range(3): bits.append(px[ch] & 1) if len(bits) >= 600: break # ICO uses 16-bit length prefix (struct.pack('>H', ...)) length = 0 for i in range(16): length = (length << 1) | bits[i] if 0 < length < 200: msg_bits = bits[16:16 + length * 8] msg_bytes = bytearray() for i in range(0, len(msg_bits), 8): byte_val = 0 for j in range(8): if i + j < len(msg_bits): byte_val = (byte_val << 1) | msg_bits[i + j] msg_bytes.append(byte_val) decoded = msg_bytes.decode('utf-8', errors='replace') if PLINIAN_DIVIDER[:10] in decoded: record("example_lsb.ico [LSB decode]", "PASS", "Plinian divider in ICO pixel LSBs") else: record("example_lsb.ico [LSB decode]", "WARN", f"Got length={length}, decoded: {decoded[:30]}...") else: record("example_lsb.ico [LSB decode]", "WARN", f"Length prefix={length}, ICO pixel reordering may differ") except Exception as e: record("example_lsb.ico [LSB decode]", "FAIL", str(e)) # WebP metadata (base64 in EXIF + XMP) try: import base64 as b64mod img = Image.open(EXAMPLES_DIR / 'example_metadata.webp') exif = img.getexif() desc = exif.get(270, '') # ImageDescription (b64:...) artist = exif.get(315, '') # Artist (hex:...) # Check b64 decode if desc.startswith('b64:'): decoded_b64 = b64mod.b64decode(desc[4:]).decode('utf-8') if decoded_b64 == PLINIAN_DIVIDER: record("example_metadata.webp [EXIF b64]", "PASS", "Plinian divider decoded from EXIF base64") else: record("example_metadata.webp [EXIF b64]", "FAIL", f"Decoded: {decoded_b64[:30]}") else: record("example_metadata.webp [EXIF b64]", "FAIL", f"No b64: prefix in desc: {desc[:30]}") # Check hex decode if artist.startswith('hex:'): decoded_hex = bytes.fromhex(artist[4:]).decode('utf-8') if decoded_hex == PLINIAN_DIVIDER: record("example_metadata.webp [EXIF hex]", "PASS", "Plinian divider decoded from EXIF hex") else: record("example_metadata.webp [EXIF hex]", "FAIL", f"Decoded: {decoded_hex[:30]}") # Check XMP in raw file data raw = (EXAMPLES_DIR / 'example_metadata.webp').read_bytes() if PLINIAN_DIVIDER.encode('utf-8') in raw: record("example_metadata.webp [XMP]", "PASS", "Plinian divider in XMP chunk") else: record("example_metadata.webp [XMP]", "FAIL", "Divider not in raw file") except Exception as e: record("example_metadata.webp [EXIF]", "FAIL", str(e)) # WebP lossless LSB test_image_lsb('example_lsb.webp', 'WebP') print() # ============================================================================= # 3. CHUNK 2: Document & Structured Data Formats # ============================================================================= print("-" * 70) print("SECTION 3: Document & Structured Data Examples") print("-" * 70) def test_text_file(filename, test_name, check_b64=True, check_hex=True, check_unicode=False, check_whitespace=False, check_direct=True): """Test a text-based file for various steganographic indicators.""" try: data = (EXAMPLES_DIR / filename).read_bytes() found_any = False if check_direct: text = data.decode('utf-8', errors='ignore') if PLINIAN_DIVIDER in text: record(f"{filename} [direct]", "PASS", "Plinian divider found directly") found_any = True # Don't fail on direct - other methods may work if check_b64: result = detect_base64(data) if result.get('found'): record(f"{filename} [base64]", "PASS", f"{len(result.get('segments',[]))} base64 segments") found_any = True if check_hex: result = detect_hex_strings(data) if result.get('found'): record(f"{filename} [hex strings]", "PASS", f"{len(result.get('segments',[]))} hex segments") found_any = True if check_unicode: result = detect_unicode_steg(data) if result.get('found'): record(f"{filename} [unicode steg]", "PASS", f"{result.get('invisible_chars',0)} invisible chars") found_any = True if check_whitespace: result = detect_whitespace_steg(data) if result.get('found'): record(f"{filename} [whitespace]", "PASS", f"{result.get('trailing_spaces',0)} trailing whitespace chars") found_any = True if not found_any: record(f"{filename} [detection]", "FAIL", "No steganographic indicators detected") except Exception as e: record(f"{filename} [analysis]", "FAIL", str(e)) # HTML test_text_file('example_hidden.html', 'HTML', check_unicode=True) # XML test_text_file('example_hidden.xml', 'XML') # JSON test_text_file('example_hidden.json', 'JSON') # CSV whitespace test_text_file('example_whitespace.csv', 'CSV', check_whitespace=True, check_b64=False, check_hex=False, check_direct=False) # YAML test_text_file('example_hidden.yaml', 'YAML') # PDF try: data = (EXAMPLES_DIR / 'example_hidden.pdf').read_bytes() ftype = detect_file_type(data) found_direct = PLINIAN_DIVIDER.encode('utf-8') in data b64_result = detect_base64(data) hex_result = detect_hex_strings(data) if ftype.value == 'pdf': record("example_hidden.pdf [file type]", "PASS", "Detected as PDF") else: record("example_hidden.pdf [file type]", "FAIL", f"Detected as {ftype.value}") if found_direct: record("example_hidden.pdf [direct]", "PASS", "Plinian divider found in PDF data") else: record("example_hidden.pdf [direct]", "FAIL", "Divider not in raw data") if b64_result.get('found') or hex_result.get('found'): record("example_hidden.pdf [b64/hex]", "PASS", f"b64={b64_result.get('found')}, hex={hex_result.get('found')}") except Exception as e: record("example_hidden.pdf [analysis]", "FAIL", str(e)) # RTF test_text_file('example_hidden.rtf', 'RTF') # Markdown test_text_file('example_hidden.md', 'Markdown', check_unicode=True) print() # ============================================================================= # 4. CHUNK 3: Audio, Binary & Archive Formats # ============================================================================= print("-" * 70) print("SECTION 4: Audio, Binary & Archive Examples") print("-" * 70) def test_audio_lsb(filename, fmt_name, big_endian=False): """Test LSB extraction from an audio file.""" try: path = EXAMPLES_DIR / filename if filename.endswith('.aiff'): # Parse AIFF manually data = path.read_bytes() # Find SSND chunk idx = data.find(b'SSND') if idx < 0: record(f"{filename} [LSB decode]", "FAIL", "No SSND chunk") return chunk_size = struct.unpack('>I', data[idx+4:idx+8])[0] offset = struct.unpack('>I', data[idx+8:idx+12])[0] sample_data = data[idx+16+offset:] # 16-bit big-endian samples num_samples = min(len(sample_data) // 2, 600) samples = struct.unpack(f'>{num_samples}h', sample_data[:num_samples*2]) # Also check ANNO chunk anno_idx = data.find(b'ANNO') if anno_idx >= 0: anno_size = struct.unpack('>I', data[anno_idx+4:anno_idx+8])[0] anno_text = data[anno_idx+8:anno_idx+8+anno_size].decode('utf-8', errors='replace') if PLINIAN_DIVIDER[:10] in anno_text: record(f"{filename} [ANNO chunk]", "PASS", "Plinian divider in annotation") elif filename.endswith('.au'): data = path.read_bytes() if data[:4] != b'.snd': record(f"{filename} [LSB decode]", "FAIL", "Not a valid AU file") return header_size = struct.unpack('>I', data[4:8])[0] # Check annotation in header anno = data[24:header_size] anno_text = anno.decode('utf-8', errors='replace').rstrip('\x00') if PLINIAN_DIVIDER[:10] in anno_text: record(f"{filename} [annotation]", "PASS", "Plinian divider in AU annotation") sample_data = data[header_size:] num_samples = min(len(sample_data) // 2, 600) samples = struct.unpack(f'>{num_samples}h', sample_data[:num_samples*2]) else: record(f"{filename} [LSB decode]", "FAIL", f"Unsupported format") return # Extract LSBs bits = [] for s in samples: bits.append(s & 1) # Decode length prefix length = 0 for i in range(32): if i < len(bits): length = (length << 1) | bits[i] if 0 < length < 200: msg_bits = bits[32:32 + length * 8] msg_bytes = bytearray() for i in range(0, len(msg_bits), 8): byte_val = 0 for j in range(8): if i + j < len(msg_bits): byte_val = (byte_val << 1) | msg_bits[i + j] msg_bytes.append(byte_val) decoded = msg_bytes.decode('utf-8', errors='replace') if PLINIAN_DIVIDER[:10] in decoded: record(f"{filename} [LSB decode]", "PASS", "Plinian divider extracted from audio LSB") else: record(f"{filename} [LSB decode]", "WARN", f"Got length={length}, decoded: {decoded[:30]}...") else: record(f"{filename} [LSB decode]", "FAIL", f"Invalid length: {length}") except Exception as e: record(f"{filename} [LSB decode]", "FAIL", str(e)) # AIFF test_audio_lsb('example_lsb.aiff', 'AIFF') # AU test_audio_lsb('example_lsb.au', 'AU') # ZIP try: import zipfile path = EXAMPLES_DIR / 'example_hidden.zip' with zipfile.ZipFile(path, 'r') as zf: comment = zf.comment.decode('utf-8', errors='replace') if PLINIAN_DIVIDER[:10] in comment: record("example_hidden.zip [comment]", "PASS", "Plinian divider in ZIP comment") else: record("example_hidden.zip [comment]", "FAIL", f"Comment: {comment[:30]}") # Check trailing data data = path.read_bytes() ftype = detect_file_type(data) record("example_hidden.zip [file type]", "PASS" if ftype.value == 'zip' else "FAIL", f"Detected as {ftype.value}") # Check for appended data after ZIP if PLINIAN_DIVIDER.encode('utf-8') in data: record("example_hidden.zip [trailing]", "PASS", "Plinian divider after ZIP end") except Exception as e: record("example_hidden.zip [analysis]", "FAIL", str(e)) # TAR try: import tarfile path = EXAMPLES_DIR / 'example_hidden.tar' with tarfile.open(path, 'r') as tf: members = tf.getmembers() found_pax = False for m in members: pax = m.pax_headers or {} if PLINIAN_DIVIDER[:10] in pax.get('comment', ''): found_pax = True if PLINIAN_DIVIDER.encode('utf-8').hex()[:20] in pax.get('STEG.payload', ''): found_pax = True if found_pax: record("example_hidden.tar [PAX headers]", "PASS", "Plinian divider in PAX extended headers") else: record("example_hidden.tar [PAX headers]", "FAIL", "Divider not in PAX headers") except Exception as e: record("example_hidden.tar [analysis]", "FAIL", str(e)) # GZip try: import gzip path = EXAMPLES_DIR / 'example_hidden.gz' data = path.read_bytes() # Check magic if data[:2] == b'\x1f\x8b': record("example_hidden.gz [magic]", "PASS", "Valid gzip magic bytes") else: record("example_hidden.gz [magic]", "FAIL", "Invalid gzip magic") # Check flags for FEXTRA and FCOMMENT flags = data[3] has_extra = bool(flags & 0x04) has_comment = bool(flags & 0x10) if has_extra: # Parse FEXTRA xlen = struct.unpack('