//-------------------------------------- //--- 010 Editor v4.0.3 Binary Template // // File: GZipTemplate.bt // Author: Tim "diff" Strazzere // Revision: 1.2 // Purpose: Quick template for parsing GZip data/files //-------------------------------------- // // Version 1.2 // - Fix processing of part numbers for continuation based gzips // - Added some notes on the encrypted header information // // Version 1.1 // - Fix small typos // - Added comments to fields // - Fix compression/flag names according to gzip 1.2.4 source // - Added uncompressed length and CRC32 // - Check for different common magic bytes, and display properly // - Minor code clean up // // Version 1.0 // - First implementation of the template // // TODO: // - Parse encrypted header information // GZip's should be Little Endian only LittleEndian(); // utility type to show the magic bytes in the value column typedef ubyte MAGIC[2] ; string MAGICRead(MAGIC magic) { string ret; string tmp; int i; for(i = 0; i<2; i++) { SPrintf(tmp, "%.2X", magic[i]); ret += tmp; } return ret; } typedef enum { // All below, except DEFLATE are reserved STORED = 0, COMPRESSED = 1, PACKED = 2, LZHED = 3, RESERVED_4 = 4, RESERVED_5 = 5, RESERVED_6 = 6, RESERVED_7 = 7, // Default (and most common) DEFLATE = 8 } COMPRESSION; // TODO : Probably some better way to do this typedef struct { // File is probably ascii text (determined by compressor) byte FLAG_ASCII_TEXT : 1; // Continuation of multi-part gzip file byte FLAG_CONTINUATION : 1; // Generic extra field present byte FLAG_EXTRA : 1; // Original filename present byte FLAG_NAME : 1; // File comment present byte FLAG_COMMENT : 1; // Is file encrypted? byte FLAG_ENCRYPTED : 1; // Reserved for future use (nothing as of gzip 1.2.4 byte FLAG_RESERVED : 1; byte FLAG_RESERVED : 1; } FLAGS; typedef enum { FAT_FILESYSTEM = 0, AMIGA = 1, VMS = 2, UNIX = 3, VM_CMS = 4, ATARI_TOS = 5, HPFS_FILESYSTEM = 6, MACINTOSH = 7, Z_SYSTEM = 8, CPM = 9, TOPS_20 = 10, NTFS_FILESYSTEM = 11, QDOS = 12, ACORN_RISCOS = 13, UNKNOWN = 255 } OS; typedef struct { MAGIC magic_bytes ; // Should be a better way to parse the magic bytes and complain to user... if(magic_bytes[0] == 0x1F) { if(magic_bytes[1] == 0x8B) { // GZIP_MAGIC Printf("Appears to be a valid GZIP compressed file, attempting to parse.\n"); } else if(magic_bytes[1] == 0x1E) { // PACK_MAGIC Printf("Appears to be a generic compressed file, attempting to parse - don't expect much though.\n"); } else if(magic_bytes[1] == 0x9E) { // OLD_GZIP_MAGIC Printf("Appears to be an old GZip compressed file, attempting to parse - don't expect much though.\n"); } else if(magic_bytes[1] == 0xA0) { // LZH_MAGIC Printf("Appears to be a LZH compressed file, attempting to parse - don't expect much though.\n"); } } else if(magic_bytes[0] == 0x50 && magic_bytes[1] == 0x4B) { Warning("Appears to be a possible ZIP file - unable to parse with this template!"); Exit(-1); } else { Warning("Does not appear to be a GZip file!"); Exit(-1); } COMPRESSION compression_method ; FLAGS flags ; // Convert to proper timestamp uint modification_time ; // Extra flags ubyte extra_flags ; // OS where compression took place OS operating_system ; // The file is marked as a continuation, so it should have a part number if(flags.FLAG_CONTINUATION == 1) { ushort part ; } // Read in extras from flags if(flags.FLAG_EXTRA == 1) { ushort extra_length ; byte extra_bytes[extra_length] ; } if(flags.FLAG_NAME == 1) { string original_file_name ; } if(flags.FLAG_COMMENT == 1) { string file_comment ; } // TODO: Parse encrypted header info // -- according to the docs this is grabbed from the zip lib (crypt.h/crypt.c) // which according to their docs is hardly used or fully supported. // It would appear you would need to compile this directly into your gzip // sources for it to properly work, even though it's considered "valid". if(flags.FLAG_ENCRYPTED == 1) { // 12 bytes of encryption header data } } gzip_header; // Structure of gzip file struct { // Header information gzip_header header ; // Everything else should just be compress bytes, less the last 8 bytes // which contain the CRC32 and uncompressed size byte compressed[FileSize() - FTell() - 8] ; uint CRC32 ; // 4 bytes uncompressed input size modulo 2^32 uint uncompressed_sized ; } gzip_file;