mirror of https://github.com/x64dbg/btparser
667 lines
22 KiB
Plaintext
667 lines
22 KiB
Plaintext
|
//-----------------------------------
|
||
|
//--- 010 Editor v2.0 Binary Template
|
||
|
//
|
||
|
// File: ZIPTemplateAdv.bt
|
||
|
// Author: SweetScape Software
|
||
|
// Revision: 2.4
|
||
|
// Purpose: Defines a template for
|
||
|
// parsing ZIP files. Handles more
|
||
|
// complex ZIP data such as ZIP64
|
||
|
// that the base ZIPTemplate.bt cannot
|
||
|
// read. These changes may be merged into
|
||
|
// the main ZIPTemplate.bt file.
|
||
|
//
|
||
|
// Changes:
|
||
|
// 2.1 (SweetScape):
|
||
|
// - Added write function for ZIPFILERECORD structure.
|
||
|
// 2.2 (S.Gibson, KPMG LLP):
|
||
|
// - Fix for entry comment field
|
||
|
// - Fix for parsing data descriptors
|
||
|
// 2.3 (DCeres):
|
||
|
// - Added write function for VERECORD structure.
|
||
|
// - Added write function for ZIP64ENDLOCATORRECORD structure.
|
||
|
// - Added write function for ZIP64ENDLOCATOR structure.
|
||
|
// - Added write function for EXTRAFIELD structure.
|
||
|
// 2.4 (George Woods):
|
||
|
// - Handle zero compressed size in header with ZIPDATADESCR header
|
||
|
// after compressed data.
|
||
|
//-----------------------------------
|
||
|
|
||
|
// Define structures used in ZIP files
|
||
|
|
||
|
typedef enum <uint> {
|
||
|
S_ZIPFILERECORD = 0x04034b50,
|
||
|
S_ZIPDATADESCR = 0x08074b50,
|
||
|
S_ZIPDIRENTRY = 0x02014b50,
|
||
|
S_ZIPDIGITALSIG = 0x05054b50,
|
||
|
S_ZIP64ENDLOCATORRECORD = 0x06064b50,
|
||
|
S_ZIP64ENDLOCATOR = 0x07064b50,
|
||
|
S_ZIPENDLOCATOR = 0x06054b50
|
||
|
} SignatureTYPE <format=hex>;
|
||
|
|
||
|
typedef enum <byte> {
|
||
|
OS_FAT = 0,
|
||
|
OS_AMIGA = 1,
|
||
|
OS_VMS = 2, // VAX/VMS
|
||
|
OS_Unix = 3,
|
||
|
OS_VM_CMS = 4,
|
||
|
OS_Atari = 5, // what if it's a minix filesystem? [cjh]
|
||
|
OS_HPFS = 6, // filesystem used by OS/2 (and NT 3.x)
|
||
|
OS_Mac = 7,
|
||
|
OS_Z_System = 8,
|
||
|
OS_CPM = 9,
|
||
|
OS_TOPS20 = 10, // pkzip 2.50 NTFS
|
||
|
OS_NTFS = 11, // filesystem used by Windows NT
|
||
|
OS_QDOS = 12, // SMS/QDOS
|
||
|
OS_Acorn = 13, // Archimedes Acorn RISC OS
|
||
|
OS_VFAT = 14, // filesystem used by Windows 95, NT
|
||
|
OS_MVS = 15,
|
||
|
OS_BeOS = 16, // hybrid POSIX/database filesystem
|
||
|
OS_Tandem = 17,
|
||
|
OS_OS400 = 18,
|
||
|
OS_OSX = 19
|
||
|
} HOSTOSTYPE;
|
||
|
|
||
|
typedef byte VERSIONTYPE <read=read_VERSIONTYPE>;
|
||
|
|
||
|
string read_VERSIONTYPE (local VERSIONTYPE &af) {
|
||
|
local string s = "";
|
||
|
SPrintf (s, "%1.1f", (float)af / 10);
|
||
|
return s;
|
||
|
}
|
||
|
|
||
|
typedef struct{
|
||
|
VERSIONTYPE Version;
|
||
|
HOSTOSTYPE HostOS;
|
||
|
} VERECORD <read=read_VERECORD>;
|
||
|
|
||
|
string read_VERECORD (local VERECORD &af) {
|
||
|
local string s = "";
|
||
|
SPrintf (s, "Ver %1.1f, ", (float)af.Version / 10);
|
||
|
s += EnumToString( af.HostOS);
|
||
|
return s;
|
||
|
}
|
||
|
|
||
|
//enum used for compression format
|
||
|
typedef enum <short> {
|
||
|
COMP_STORED = 0,
|
||
|
COMP_SHRUNK = 1,
|
||
|
COMP_REDUCED1 = 2,
|
||
|
COMP_REDUCED2 = 3,
|
||
|
COMP_REDUCED3 = 4,
|
||
|
COMP_REDUCED4 = 5,
|
||
|
COMP_IMPLODED = 6,
|
||
|
COMP_TOKEN = 7,
|
||
|
COMP_DEFLATE = 8, // Deflate - standard ZIP codec, used from the start, also found in regular ZIP files
|
||
|
COMP_DEFLATE64 = 9,
|
||
|
COMP_PKImploding = 10,
|
||
|
|
||
|
COMP_BZip2 = 12, // BZIP2 - Newer than deflate, with better compression and slightly slower speed.
|
||
|
COMP_LZMA = 14, // LZMA - advanced ZIPX codec, taken from open source 7-zip format
|
||
|
COMP_Terse = 18,
|
||
|
COMP_Lz77 = 19,
|
||
|
|
||
|
COMP_Jpeg = 0x60, // Jpeg - Codec added by WinZip for specific support of jpeg images ( http://www.winzip.com/wz_jpg_comp.pdf )
|
||
|
COMP_WavPack = 0x61, // WavPack - Codec for compressing specifically wav files. ( http://www.wavpack.com )
|
||
|
COMP_PPMd = 0x62, // PPMd - context modeling based codec, also featured in new ZIP standard. We use it in our Optimized method for text file compression. ( http://www.compression.ru/ds/ )
|
||
|
COMP_WzAES = 0x63 // WZAES encryption methods
|
||
|
} COMPTYPE;
|
||
|
|
||
|
typedef enum <ushort>{
|
||
|
FLAG_Encrypted = 0x0001, //Bit 0: If set, indicates that the file is encrypted.
|
||
|
FLAG_CompressionFlagBit1 = 0x0002,
|
||
|
FLAG_CompressionFlagBit2 = 0x0004,
|
||
|
FLAG_DescriptorUsedMask = 0x0008,
|
||
|
FLAG_Reserved1 = 0x0010,
|
||
|
FLAG_Reserved2 = 0x0020,
|
||
|
FLAG_StrongEncrypted = 0x0040, //Bit 6: Strong encryption
|
||
|
FLAG_CurrentlyUnused1 = 0x0080,
|
||
|
FLAG_CurrentlyUnused2 = 0x0100,
|
||
|
FLAG_CurrentlyUnused3 = 0x0200,
|
||
|
FLAG_CurrentlyUnused4 = 0x0400,
|
||
|
FLAG_Utf8 = 0x0800, // Bit 11: filename and comment encoded using UTF-8
|
||
|
FLAG_ReservedPKWARE1 = 0x1000,
|
||
|
FLAG_CDEncrypted = 0x2000, // Bit 13: Used when encrypting the Central Directory to indicate selected data values in the Local Header are masked to hide their actual values.
|
||
|
FLAG_ReservedPKWARE2 = 0x4000,
|
||
|
FLAG_ReservedPKWARE3 = 0x8000,
|
||
|
|
||
|
} FLAGTYPE <read=read_FLAGTYPE>;
|
||
|
|
||
|
string read_FLAGTYPE (local FLAGTYPE &af) {
|
||
|
local string s = "";
|
||
|
local int commaNeeded = 0;
|
||
|
local FLAGTYPE i = 1;
|
||
|
|
||
|
SPrintf (s, "%d: ", af);
|
||
|
while (i < FLAG_ReservedPKWARE3)
|
||
|
{
|
||
|
if (af & i)
|
||
|
{
|
||
|
if (commaNeeded)
|
||
|
{ s += ", "; }
|
||
|
s += EnumToString(i);
|
||
|
commaNeeded = 1;
|
||
|
}
|
||
|
i = i << 1;
|
||
|
}
|
||
|
return s;
|
||
|
}
|
||
|
|
||
|
typedef enum <ushort>{
|
||
|
EH_Zip64 = 0x0001, //Zip64 extended information extra field
|
||
|
EH_AVInfo = 0x0007, //AV Info
|
||
|
EH_ExtLanguage = 0x0008, //Reserved for extended language encoding data (PFS)
|
||
|
EH_OS2 = 0x0009, //OS/2
|
||
|
EH_NTFS = 0x000a, //NTFS
|
||
|
EH_OpenVMS = 0x000c, //OpenVMS
|
||
|
EH_UNIX = 0x000d, //UNIX
|
||
|
EH_fileStream = 0x000e, //Reserved for file stream and fork descriptors
|
||
|
EH_PatchDescriptor = 0x000f, //Patch Descriptor
|
||
|
EH_PKCS7X509 = 0x0014, //PKCS#7 Store for X.509 Certificates
|
||
|
EH_X509IDSignature = 0x0015, //X.509 Certificate ID and Signature for individual file
|
||
|
EH_X509IDCD = 0x0016, //X.509 Certificate ID for Central Directory
|
||
|
EH_StrongEncryption = 0x0017, //Strong Encryption Header
|
||
|
EH_RecordManagement = 0x0018, //Record Management Controls
|
||
|
EH_PKCS7List = 0x0019, //PKCS#7 Encryption Recipient Certificate List
|
||
|
EH_Attributes = 0x0065, //IBM S/390 (Z390), AS/400 (I400) attributes uncompressed
|
||
|
EH_ReservedAttributes = 0x0066, //Reserved for IBM S/390 (Z390), AS/400 (I400) attributes - compressed
|
||
|
EH_POSZIP4690 = 0x4690, //POSZIP 4690 (reserved)
|
||
|
EH_Mac = 0x07c8, //Macintosh
|
||
|
EH_ZipItMac1 = 0x2605, //ZipIt Macintosh
|
||
|
EH_ZipItMac2 = 0x2705, //ZipIt Macintosh 1.3.5+
|
||
|
EH_ZipItMac3 = 0x2805, //ZipIt Macintosh 1.3.5+
|
||
|
EH_InfoZIPMac = 0x334d, //Info-ZIP Macintosh
|
||
|
EH_Acorn = 0x4341, //Acorn/SparkFS
|
||
|
EH_WinNTSecurity = 0x4453, //Windows NT security descriptor (binary ACL)
|
||
|
EH_VM_CMS = 0x4704, //VM/CMS
|
||
|
EH_MVS = 0x470f, //MVS
|
||
|
EH_FWKCS = 0x4b46, //FWKCS MD5 (see below)
|
||
|
EH_OS2AccessList = 0x4c41, //OS/2 access control list (text ACL)
|
||
|
EH_InfoZIPOpenVMS = 0x4d49, //Info-ZIP OpenVMS
|
||
|
EH_Xceed = 0x4f4c, //Xceed original location extra field
|
||
|
EH_AOSVS = 0x5356, //AOS/VS (ACL)
|
||
|
EH_extTimestamp = 0x5455, //extended timestamp
|
||
|
EH_XceedUnicode = 0x554e, //Xceed unicode extra field
|
||
|
EH_InfoZIPUNIX = 0x5855, //Info-ZIP UNIX (original, also OS/2, NT, etc)
|
||
|
EH_InfoZIPUnicodeComment = 0x6375, //Info-ZIP Unicode Comment Extra Field
|
||
|
EH_BeOS = 0x6542, //BeOS/BeBox
|
||
|
EH_InfoZIPUnicodePath = 0x7075, //Info-ZIP Unicode Path Extra Field
|
||
|
EH_ASiUNIX = 0x756e, //ASi UNIX
|
||
|
EH_InfoZIPUNIXNew = 0x7855, //Info-ZIP UNIX (16-bit UID/GID info)
|
||
|
EH_InfoZIPUNIXNew3rd = 0x7875, //Info-ZIP UNIX 3rd generation (generic UID/GID, ...)
|
||
|
EH_WinGrowth = 0xa220, //Microsoft Open Packaging Growth Hint
|
||
|
EH_SMSQDOS = 0xfd4a, //SMS/QDOS
|
||
|
EH_WzAES = 0x9901, //
|
||
|
} HEADERFLAG;
|
||
|
|
||
|
typedef enum <ushort>{
|
||
|
AlgID_DES = 0x6601, //- DES
|
||
|
AlgID_RC2OLD = 0x6602, //- RC2 (version needed to extract < 5.2)
|
||
|
AlgID_3DES168 = 0x6603, //- 3DES 168
|
||
|
AlgID_3DES112 = 0x6609, //- 3DES 112
|
||
|
AlgID_AES128 = 0x660E, //- AES 128
|
||
|
AlgID_AES192 = 0x660F, //- AES 192
|
||
|
AlgID_AES256 = 0x6610, //- AES 256
|
||
|
AlgID_RC2 = 0x6702, //- RC2 (version needed to extract >= 5.2)
|
||
|
AlgID_Blowfish = 0x6720, //- Blowfish
|
||
|
AlgID_Twofish = 0x6721, //- Twofish
|
||
|
AlgID_RC4 = 0x6801, //- RC4
|
||
|
AlgID_Unknown = 0xFFFF, //- Unknown algorithm
|
||
|
} ALGFLAG;
|
||
|
|
||
|
typedef enum <byte>{
|
||
|
AES128 = 0x01, //128-bit encryption key
|
||
|
AES192 = 0x02, //192-bit encryption key
|
||
|
AES256 = 0x03, //256-bit encryption key
|
||
|
} AESMODE;
|
||
|
|
||
|
typedef enum <ushort>{
|
||
|
pfPassword = 0x0001, //- Password is required to decrypt
|
||
|
pfCertificates = 0x0002, //- Certificates only
|
||
|
pfPasswordCertificates = 0x0003, //- Password or certificate required to decrypt
|
||
|
} PRCFLAG;
|
||
|
|
||
|
typedef struct {
|
||
|
HEADERFLAG efHeaderID;
|
||
|
ushort efDataSize;
|
||
|
|
||
|
Printf("%d", efHeaderID);
|
||
|
switch (efHeaderID)
|
||
|
{
|
||
|
case EH_Zip64:
|
||
|
uint64 efOriginalSize;
|
||
|
uint64 efCompressedSize;
|
||
|
//uint64 efHeaderOffset;
|
||
|
//uint efDiskNumberStart;
|
||
|
break;
|
||
|
case EH_InfoZIPUnicodePath:
|
||
|
byte efVersion;
|
||
|
uint efNameCRC32;
|
||
|
if(efDataSize > 0 )
|
||
|
char efUnicodeName[efDataSize - 5];
|
||
|
break;
|
||
|
case EH_NTFS:
|
||
|
int Reserved; //4 bytes Reserved for future use
|
||
|
local int len = efDataSize - 4;
|
||
|
while (len > 0)
|
||
|
{
|
||
|
ushort Tag; //2 bytes NTFS attribute tag value #1
|
||
|
ushort Size; //2 bytes Size of attribute #1, in bytes
|
||
|
if (Tag == 0x001)
|
||
|
{
|
||
|
FILETIME Mtime; //8 bytes File last modification time
|
||
|
FILETIME Atime; //8 bytes File last access time
|
||
|
FILETIME Ctime; //8 bytes File creation time
|
||
|
}
|
||
|
else
|
||
|
byte Data[Size]; //(var.) Size1 Attribute #1 data
|
||
|
len -= Size + 4;
|
||
|
}
|
||
|
break;
|
||
|
case EH_StrongEncryption:
|
||
|
ushort Format; //2 bytes Format definition for this record
|
||
|
ALGFLAG AlgID; //2 bytes Encryption algorithm identifier
|
||
|
ushort Bitlen; //2 bytes Bit length of encryption key
|
||
|
PRCFLAG Flags; //2 bytes Processing flags
|
||
|
if (efDataSize > 8)
|
||
|
byte CertData[efDataSize - 8]; //TSize-8 Certificate decryption extra field data
|
||
|
break;
|
||
|
case EH_WzAES:
|
||
|
ushort version; //2 bytes Integer version number specific to the zip vendor
|
||
|
char VendorID[2]; //2 bytes 2-character vendor ID
|
||
|
AESMODE Strength; //1 bytes Integer mode value indicating AES encryption strength
|
||
|
COMPTYPE deCompression; //2 bytes The actual compression method used to compress the file
|
||
|
break;
|
||
|
default:
|
||
|
if(efDataSize > 0 )
|
||
|
char efData[ efDataSize ];
|
||
|
break;
|
||
|
}
|
||
|
} EXTRAFIELD <read=read_EXTRAFIELD>;
|
||
|
|
||
|
string read_EXTRAFIELD (local EXTRAFIELD &af)
|
||
|
{
|
||
|
return EnumToString(af.efHeaderID);
|
||
|
}
|
||
|
|
||
|
typedef struct {
|
||
|
HEADERFLAG efHeaderID;
|
||
|
uint efDataSize;
|
||
|
|
||
|
Printf("%d", efHeaderID);
|
||
|
switch (efHeaderID)
|
||
|
{
|
||
|
case EH_Zip64:
|
||
|
uint64 efOriginalSize;
|
||
|
uint64 efCompressedSize;
|
||
|
//uint64 efHeaderOffset;
|
||
|
//uint efDiskNumberStart;
|
||
|
break;
|
||
|
case EH_InfoZIPUnicodePath:
|
||
|
byte efVersion;
|
||
|
uint efNameCRC32;
|
||
|
if(efDataSize > 0 )
|
||
|
char efUnicodeName[efDataSize - 5];
|
||
|
break;
|
||
|
default:
|
||
|
if(efDataSize > 0 )
|
||
|
char efData[ efDataSize ];
|
||
|
break;
|
||
|
}
|
||
|
} EXTRA64FIELD;
|
||
|
|
||
|
typedef enum <uint>{
|
||
|
FA_READONLY = 0x00000001,
|
||
|
FA_HIDDEN = 0x00000002,
|
||
|
FA_SYSTEM = 0x00000004,
|
||
|
FA_DIRECTORY = 0x00000010,
|
||
|
FA_ARCHIVE = 0x00000020,
|
||
|
FA_DEVICE = 0x00000040,
|
||
|
FA_NORMAL = 0x00000080,
|
||
|
FA_TEMPORARY = 0x00000100,
|
||
|
FA_SPARSE_FILE = 0x00000200,
|
||
|
FA_REPARSE_POINT = 0x00000400,
|
||
|
FA_COMPRESSED = 0x00000800,
|
||
|
FA_OFFLINE = 0x00001000,
|
||
|
FA_NOT_CONTENT_INDEXED = 0x00002000,
|
||
|
FA_ENCRYPTED = 0x00004000,
|
||
|
FA_VIRTUAL = 0x00010000,
|
||
|
|
||
|
kIFMT = 0170000 << 16, /* Unix file type mask */
|
||
|
|
||
|
kIFDIR = 0040000 << 16, /* Unix directory */
|
||
|
kIFREG = 0100000 << 16, /* Unix regular file */
|
||
|
kIFSOCK = 0140000 << 16, /* Unix socket (BSD, not SysV or Amiga) */
|
||
|
kIFLNK = 0120000 << 16, /* Unix symbolic link (not SysV, Amiga) */
|
||
|
kIFBLK = 0060000 << 16, /* Unix block special (not Amiga) */
|
||
|
kIFCHR = 0020000 << 16, /* Unix character special (not Amiga) */
|
||
|
kIFIFO = 0010000 << 16, /* Unix fifo (BCC, not MSC or Amiga) */
|
||
|
|
||
|
kISUID = 04000 << 16, /* Unix set user id on execution */
|
||
|
kISGID = 02000 << 16, /* Unix set group id on execution */
|
||
|
kISVTX = 01000 << 16, /* Unix directory permissions control */
|
||
|
kIRWXU = 00700 << 16, /* Unix read, write, execute: owner */
|
||
|
kIRUSR = 00400 << 16, /* Unix read permission: owner */
|
||
|
kIWUSR = 00200 << 16, /* Unix write permission: owner */
|
||
|
kIXUSR = 00100 << 16, /* Unix execute permission: owner */
|
||
|
kIRWXG = 00070 << 16, /* Unix read, write, execute: group */
|
||
|
kIRGRP = 00040 << 16, /* Unix read permission: group */
|
||
|
kIWGRP = 00020 << 16, /* Unix write permission: group */
|
||
|
kIXGRP = 00010 << 16, /* Unix execute permission: group */
|
||
|
kIRWXO = 00007 << 16, /* Unix read, write, execute: other */
|
||
|
kIROTH = 00004 << 16, /* Unix read permission: other */
|
||
|
kIWOTH = 00002 << 16, /* Unix write permission: other */
|
||
|
kIXOTH = 00001 << 16 /* Unix execute permission: other */
|
||
|
} FILEATTRIBUTE <read=read_FILEATTRIBUTE>;
|
||
|
|
||
|
string read_FILEATTRIBUTE (local FILEATTRIBUTE &af) {
|
||
|
local string s = "";
|
||
|
local int commaNeeded = 0;
|
||
|
local FILEATTRIBUTE i = 1;
|
||
|
|
||
|
SPrintf (s, "0x%X: ", af);
|
||
|
while (i < 0xFFFFFF - 2)
|
||
|
{
|
||
|
if (af & i)
|
||
|
{
|
||
|
if (commaNeeded)
|
||
|
{
|
||
|
s += ", ";
|
||
|
}
|
||
|
s += EnumToString(i);
|
||
|
commaNeeded = 1;
|
||
|
}
|
||
|
i = i << 1;
|
||
|
}
|
||
|
return s;
|
||
|
}
|
||
|
|
||
|
// Defintes the Data descriptor
|
||
|
typedef struct {
|
||
|
SignatureTYPE ddSignature; //0x08074b50
|
||
|
uint ddCRC <format=hex>;
|
||
|
uint ddCompressedSize;
|
||
|
uint ddUncompressedSize;
|
||
|
} ZIPDATADESCR;
|
||
|
|
||
|
// Defines a file record
|
||
|
typedef struct {
|
||
|
// Header for the file
|
||
|
SignatureTYPE frSignature; //0x04034b50
|
||
|
VERECORD frVersion;
|
||
|
FLAGTYPE frFlags;
|
||
|
COMPTYPE frCompression;
|
||
|
DOSTIME frFileTime;
|
||
|
DOSDATE frFileDate;
|
||
|
uint frCrc <format=hex>;
|
||
|
uint frCompressedSize;
|
||
|
uint frUncompressedSize;
|
||
|
ushort frFileNameLength;
|
||
|
ushort frExtraFieldLength;
|
||
|
if( frFileNameLength > 0 )
|
||
|
char frFileName[ frFileNameLength ];
|
||
|
|
||
|
local int len = frExtraFieldLength;
|
||
|
while (len > 0)
|
||
|
{
|
||
|
EXTRAFIELD frExtraField;
|
||
|
len -= frExtraField.efDataSize + 4;
|
||
|
}
|
||
|
// Compressed data
|
||
|
SetBackColor( cNone );
|
||
|
|
||
|
if ((frFlags & FLAG_Encrypted) && ( frFlags & FLAG_StrongEncrypted))
|
||
|
{
|
||
|
struct
|
||
|
{
|
||
|
ushort IVSize;
|
||
|
byte IVData[IVSize];
|
||
|
uint Size;
|
||
|
ushort Format;
|
||
|
ALGFLAG AlgID;
|
||
|
ushort BitLen;
|
||
|
ushort Flags;
|
||
|
ushort ErdSize;
|
||
|
byte ErdData[ErdSize];
|
||
|
uint Reserved;
|
||
|
ushort VSize;
|
||
|
byte VData[VSize - 4];
|
||
|
uint VCRC32;
|
||
|
} StrongEncryptedHeader;
|
||
|
char frData[ frCompressedSize - StrongEncryptedHeader.IVSize - StrongEncryptedHeader.Size - 6];
|
||
|
}
|
||
|
else if ((frFlags & FLAG_Encrypted) && ( frCompression == COMP_WzAES ))
|
||
|
{
|
||
|
local int lenSalt = 0;
|
||
|
if (frExtraField.efHeaderID == EH_WzAES)
|
||
|
{
|
||
|
switch (frExtraField.Strength)
|
||
|
{
|
||
|
case AES128:
|
||
|
lenSalt = 8;
|
||
|
break;
|
||
|
case AES192:
|
||
|
lenSalt = 12;
|
||
|
break;
|
||
|
case AES256:
|
||
|
lenSalt = 16;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
uchar SaltValue[lenSalt];
|
||
|
ushort PassVerification;
|
||
|
uchar frData[ frCompressedSize - 12 - lenSalt];
|
||
|
uchar AuthenticationCode[ 10];
|
||
|
}
|
||
|
else if( (frCompressedSize > 0) && (frCompressedSize < 0xFFFFFFFF))
|
||
|
{
|
||
|
uchar frData[ frCompressedSize ];
|
||
|
}
|
||
|
else if (frCompressedSize == 0 && (frFlags & FLAG_DescriptorUsedMask))
|
||
|
{
|
||
|
// If bit 3 (0x08) of the flags field is set, then the CRC-32 and file sizes were not known when the header was written.
|
||
|
// Instead there is an additional header ZIPDATADESCR appended after the compressed data.
|
||
|
// We look for the next signature of the appended header here.
|
||
|
local int64 posCurrent = FTell();
|
||
|
local int64 posNext = FindFirst(S_ZIPDATADESCR,true,false,false,0.0,1,posCurrent);
|
||
|
if (posNext >= posCurrent)
|
||
|
{
|
||
|
uchar frData[posNext - posCurrent];
|
||
|
|
||
|
SetBackColor( cLtGreen );
|
||
|
ZIPDATADESCR dataDescr;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} ZIPFILERECORD <read=ReadZIPFILERECORD, write=WriteZIPFILERECORD>;
|
||
|
|
||
|
// Defines an entry in the directory table
|
||
|
typedef struct {
|
||
|
SignatureTYPE deSignature; //0x02014b50
|
||
|
VERECORD deVersionMadeBy;
|
||
|
VERECORD deVersionToExtract;
|
||
|
FLAGTYPE deFlags;
|
||
|
COMPTYPE deCompression;
|
||
|
DOSTIME deFileTime;
|
||
|
DOSDATE deFileDate;
|
||
|
uint deCrc <format=hex>;
|
||
|
uint deCompressedSize;
|
||
|
uint deUncompressedSize;
|
||
|
ushort deFileNameLength;
|
||
|
ushort deExtraFieldLength;
|
||
|
ushort deFileCommentLength;
|
||
|
ushort deDiskNumberStart;
|
||
|
ushort deInternalAttributes;
|
||
|
FILEATTRIBUTE deExternalAttributes;
|
||
|
uint deHeaderOffset;
|
||
|
if( deFileNameLength > 0 )
|
||
|
char deFileName[ deFileNameLength ];
|
||
|
local int len = deExtraFieldLength;
|
||
|
while (len > 0)
|
||
|
{
|
||
|
EXTRAFIELD deExtraField;
|
||
|
len -= deExtraField.efDataSize + 4;
|
||
|
}
|
||
|
if( deFileCommentLength > 0 )
|
||
|
uchar deFileComment[ deFileCommentLength ];
|
||
|
} ZIPDIRENTRY <read=ReadZIPDIRENTRY>;
|
||
|
|
||
|
// Defines the digital signature
|
||
|
typedef struct {
|
||
|
SignatureTYPE dsSignature; //0x05054b50
|
||
|
ushort dsDataLength;
|
||
|
if( dsDataLength > 0 )
|
||
|
uchar dsData[ dsDataLength ];
|
||
|
} ZIPDIGITALSIG;
|
||
|
|
||
|
// Zip64 end of central directory record
|
||
|
typedef struct {
|
||
|
SignatureTYPE elr64Signature; //0x06064b50
|
||
|
int64 elr64DirectoryRecordSize;
|
||
|
if (elr64DirectoryRecordSize > 1)
|
||
|
VERECORD elr64VersionMadeBy;
|
||
|
if (elr64DirectoryRecordSize > 2)
|
||
|
VERECORD elr64VersionToExtract;
|
||
|
if (elr64DirectoryRecordSize > 4)
|
||
|
uint el64DiskNumber;
|
||
|
if (elr64DirectoryRecordSize > 8)
|
||
|
uint el64StartDiskNumber;
|
||
|
if (elr64DirectoryRecordSize > 12)
|
||
|
int64 el64EntriesOnDisk;
|
||
|
if (elr64DirectoryRecordSize > 20)
|
||
|
int64 el64EntriesInDirectory;
|
||
|
if (elr64DirectoryRecordSize > 28)
|
||
|
int64 el64DirectorySize;
|
||
|
if (elr64DirectoryRecordSize > 36)
|
||
|
int64 el64DirectoryOffset;
|
||
|
if (elr64DirectoryRecordSize > 44)
|
||
|
{
|
||
|
char DataSect [elr64DirectoryRecordSize - 44];
|
||
|
// local int len = elr64DirectoryRecordSize - 44;
|
||
|
// while (len > 0)
|
||
|
// {
|
||
|
// EXTRA64FIELD frExtraField;
|
||
|
// len -= frExtraField.efDataSize + 4;
|
||
|
// }
|
||
|
|
||
|
}
|
||
|
} ZIP64ENDLOCATORRECORD;
|
||
|
|
||
|
//Zip64 end of central directory locator
|
||
|
typedef struct {
|
||
|
SignatureTYPE elSignature; //0x07064b50
|
||
|
uint elStartDiskNumber;
|
||
|
int64 elDirectoryOffset;
|
||
|
uint elEntriesInDirectory;
|
||
|
} ZIP64ENDLOCATOR;
|
||
|
|
||
|
// Defines the end of central directory locator
|
||
|
typedef struct {
|
||
|
SignatureTYPE elSignature; //0x06054b50
|
||
|
ushort elDiskNumber;
|
||
|
ushort elStartDiskNumber;
|
||
|
ushort elEntriesOnDisk;
|
||
|
ushort elEntriesInDirectory;
|
||
|
uint elDirectorySize;
|
||
|
uint elDirectoryOffset;
|
||
|
ushort elCommentLength;
|
||
|
if( elCommentLength > 0 )
|
||
|
char elComment[ elCommentLength ];
|
||
|
} ZIPENDLOCATOR;
|
||
|
|
||
|
//--------------------------------------------
|
||
|
|
||
|
// Custom read functions that allows the name of the
|
||
|
// of the file to appear in the Template Results.
|
||
|
|
||
|
string ReadZIPFILERECORD( ZIPFILERECORD &file )
|
||
|
{
|
||
|
if( exists( file.frFileName ) )
|
||
|
return file.frFileName;
|
||
|
else
|
||
|
return "";
|
||
|
}
|
||
|
|
||
|
string ReadZIPDIRENTRY( ZIPDIRENTRY &entry )
|
||
|
{
|
||
|
if( exists( entry.deFileName ) )
|
||
|
return entry.deFileName;
|
||
|
else
|
||
|
return "";
|
||
|
}
|
||
|
|
||
|
// Custom write function that allows changing
|
||
|
// the name of the file - note that the file
|
||
|
// name size cannot be increased
|
||
|
|
||
|
void WriteZIPFILERECORD( ZIPFILERECORD &file, string s )
|
||
|
{
|
||
|
local int len = Strlen( s );
|
||
|
if( exists( file.frFileName ) )
|
||
|
{
|
||
|
Strncpy( file.frFileName, s, file.frFileNameLength );
|
||
|
if( len < file.frFileNameLength )
|
||
|
file.frFileName[len] = 0; //null terminate
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------
|
||
|
|
||
|
// Define the file
|
||
|
local uint tag;
|
||
|
LittleEndian();
|
||
|
while( !FEof() )
|
||
|
{
|
||
|
// Read a tag
|
||
|
tag = ReadUInt( FTell() );
|
||
|
|
||
|
// Read data depending upon tag - should start with 'PK'.
|
||
|
// Note that when duplicate variables are defined, they
|
||
|
// are made into an array (see 'Using Templates and Structs'
|
||
|
// in the help file).
|
||
|
if( tag == S_ZIPFILERECORD )
|
||
|
{
|
||
|
SetBackColor( cLtGray );
|
||
|
ZIPFILERECORD record;
|
||
|
if (record.frExtraFieldLength > 0 && record.frExtraField.efHeaderID == EH_Zip64)
|
||
|
{
|
||
|
//Printf("%Lu", record.frExtraField.efCompressedSize);
|
||
|
FSkip(record.frExtraField.efCompressedSize);
|
||
|
}
|
||
|
}
|
||
|
else if( tag == S_ZIPDATADESCR )
|
||
|
{
|
||
|
SetBackColor( cLtGreen );
|
||
|
ZIPDATADESCR dataDescr;
|
||
|
}
|
||
|
else if( tag == S_ZIPDIRENTRY )
|
||
|
{
|
||
|
SetBackColor( cLtPurple );
|
||
|
ZIPDIRENTRY dirEntry;
|
||
|
}
|
||
|
else if( tag == S_ZIPDIGITALSIG )
|
||
|
{
|
||
|
SetBackColor( cLtBlue );
|
||
|
ZIPDIGITALSIG digitalSig;
|
||
|
}
|
||
|
else if( tag == S_ZIP64ENDLOCATORRECORD )
|
||
|
{
|
||
|
SetBackColor( cYellow );
|
||
|
ZIP64ENDLOCATORRECORD end64Locator;
|
||
|
}
|
||
|
else if( tag == S_ZIP64ENDLOCATOR )
|
||
|
{
|
||
|
SetBackColor( cDkYellow );
|
||
|
ZIP64ENDLOCATOR end64Locator;
|
||
|
}
|
||
|
else if( tag == S_ZIPENDLOCATOR )
|
||
|
{
|
||
|
SetBackColor( cLtYellow );
|
||
|
ZIPENDLOCATOR endLocator;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Warning( "Unknown ZIP tag encountered. Template stopped." );
|
||
|
return -1;
|
||
|
}
|
||
|
}
|