diff --git a/includes/std/core.pat b/includes/std/core.pat index a579f1a..052ba05 100644 --- a/includes/std/core.pat +++ b/includes/std/core.pat @@ -10,11 +10,21 @@ namespace std::core { /** - The default ordering of bitfield members + The layout order of each field after byte-endianness has been handled. + + `LeftToRight` and `RightToLeft` are deprecated in favor of the clearer `MostToLeastSignificant` and `LeastToMostSignificant` names. */ enum BitfieldOrder : u8 { + /** + @warning deprecated + */ LeftToRight = 0, - RightToLeft = 1 + /** + @warning deprecated + */ + RightToLeft = 1, + MostToLeastSignificant = 0, + LeastToMostSignificant = 1 }; @@ -56,19 +66,17 @@ namespace std::core { /** - Sets the default bitfield order. - @param order The new default bitfield order + @warning Removed in 1.28.0 */ fn set_bitfield_order(BitfieldOrder order) { - builtin::std::core::set_bitfield_order(u32(order)); + builtin::std::error("Runtime default bitfield order is no longer supported.\nConsider using `be` or `le` on your bitfield variables,\nor attach attribute `bitfield_order` to the bitfield."); }; /** - Gets thee current default bitfield order - @return The currently set default bitfield order + @warning Removed in 1.28.0 */ fn get_bitfield_order() { - return builtin::std::core::get_bitfield_order(); + builtin::std::error("Runtime default bitfield order is no longer supported.\nConsider using `be` or `le` on your bitfield variables,\nor attach attribute `bitfield_order` to the bitfield."); }; diff --git a/includes/std/mem.pat b/includes/std/mem.pat index 9abbac7..ec8112e 100644 --- a/includes/std/mem.pat +++ b/includes/std/mem.pat @@ -113,6 +113,27 @@ namespace std::mem { }; + /** + Gets the current bit offset within the current byte that a bitfield will read. + */ + fn current_bit_offset() { + return builtin::std::mem::current_bit_offset(); + }; + + /** + Reads a number of bits from the specified bit offset within the specified byte + @param byteOffset The byte offset within the data + @param bitOffset The bit offset to start the read at within the current byte + @param bitSize The total number of bits to read + @return A u128 containing the value read + */ + fn read_bits(u128 byteOffset, u128 bitOffset, u64 bitSize) { + byteOffset += bitOffset >> 3; + bitOffset = bitOffset & 0x7; + return builtin::std::mem::read_bits(byteOffset, bitOffset, bitSize); + }; + + /** Creates a new custom section with the given name @param name The name of the section diff --git a/patterns/coff.hexpat b/patterns/coff.hexpat index ac4a534..4c9bad5 100644 --- a/patterns/coff.hexpat +++ b/patterns/coff.hexpat @@ -1,209 +1,209 @@ -#pragma MIME application/x-coff - -#include -#include - -enum Machine : u16 { - Unknown = 0x0000, - AM33 = 0x01D3, - AMD64 = 0x8664, - ARM = 0x01C0, - ARM64 = 0xAA64, - ARMNT = 0x01C4, - EBC = 0x0EBC, - I386 = 0x014C, - IA64 = 0x0200, - LOONGARCH32 = 0x6232, - LOONGARCH64 = 0x6264, - M32R = 0x9041, - MIPS16 = 0x0226, - MIPSFPU = 0x0366, - MIPSFPU16 = 0x0466, - POWERPC = 0x01F0, - POWERPCFP = 0x01F0, - R4000 = 0x0166, - RISCV32 = 0x5032, - RISCV64 = 0x5064, - RISCV128 = 0x5128, - SH3 = 0x01A2, - SH3DSP = 0x01A3, - SH4 = 0x01A6, - SH5 = 0x01A8, - THUMB = 0x01C2, - WCEMIPSV2 = 0x0169 -}; - -bitfield Characteristics { - relocsStripped : 1; - executableImage : 1; - lineNumsStripped : 1; - localSymsStripped : 1; - aggressiveWsTrim : 1; - largeAddressAware : 1; - padding : 1; - bytesReversedLo : 1; - _32BitMachine : 1; - debugStripped : 1; - removableRunFromSwap : 1; - netRunFromSwap : 1; - system : 1; - dll : 1; - upSystemOnly : 1; - bytesReversedHi : 1; -} [[right_to_left]]; - -enum Type : u16 { - Null = 0, - Void = 1, - Char = 2, - Short = 3, - Int = 4, - Long = 5, - Float = 6, - Double = 7, - Struct = 8, - Union = 9, - Enum = 10, - MOE = 11, - Byte = 12, - Word = 13, - UInt = 14, - DWord = 15 -}; - -enum StorageClass : u8 { - EndOfFunction = 0xFF, - Null = 0, - Automatic = 1, - External = 2, - Static = 3, - Register = 4, - ExternalDef = 5, - Label = 6, - UndefinedLabel = 7, - MemberOfStruct = 8, - Argument = 9, - StructTag = 10, - MemberOfUnion = 11, - UnionTag = 12, - TypeDefinition = 13, - UndefinedStatic = 14, - EnumTag = 15, - MemberOfEnum = 16, - RegisterParam = 17, - BitField = 18, - Block = 100, - Function = 101, - EndOfStruct = 102, - File = 103, - Section = 104, - WeakExternal = 105, - CLRToken = 107 -}; - -struct AuxSymbol { - u8 data[18]; -}; - -u32 countedSymbols = 0; -struct SymbolTable { - char name[8]; - u32 value; - u16 sectionNumber; - Type type; - StorageClass storageClass; - u8 numberOfAuxSymbols; - - countedSymbols += 1 + numberOfAuxSymbols; - - AuxSymbol auxSymbols[numberOfAuxSymbols]; - - if (countedSymbols >= parent.header.numberOfSymbols) - break; -}; - -struct String { - char value[]; -}; - -struct StringTable { - u32 size; - String strings[while($ < addressof(size) + size)]; -}; - -bitfield SectionFlags { - padding : 3; - typeNoPad : 1; - padding : 1; - cntCode : 1; - initializedData : 1; - uninitializedData : 1; - lnkOther : 1; - lnkInfo : 1; - padding : 1; - lnkRemove : 1; - lnkCOMDAT : 1; - padding : 2; - gprel : 1; - padding : 1; - memPurgeable : 1; - memLocked : 1; - memPreload : 1; - alignment : 4 [[format("format_alignment")]]; - lnkNrelocOvfl : 1; - memDiscardable : 1; - memNotCached : 1; - memNotPaged : 1; - memShared : 1; - memExecute : 1; - memRead : 1; - memWrite : 1; -} [[right_to_left]]; - -fn format_alignment(u8 alignment) { - return 1 << alignment; -}; - -struct Relocations { - u32 virtualAddress; - u32 symbolTableIndex; - Type type; -}; - -struct Section { - char name[8]; - type::Size virtualSize; - u32 virtualAddress; - type::Size sizeOfRawData; - u32 pointerToRawData; - u32 pointerToRelocations; - u32 pointerToLineNumbers; - u16 numberOfRelocations; - u16 numberOfLineNumbers; - SectionFlags characteristics; - - u8 rawData[sizeOfRawData] @ pointerToRawData [[sealed]]; - Relocations relocations[numberOfRelocations] @ pointerToRelocations; -}; - -struct Header { - Machine machine; - u16 numberOfSections; - type::time32_t timeDateStamp; - u32 pointerToSymbolTable; - u32 numberOfSymbols; - u16 sizeOfOptionalHeader; - Characteristics characteristics; -}; - - -struct COFF { - Header header; - - Section sectionTable[header.numberOfSections]; - - SymbolTable symbolTable[header.numberOfSymbols] @ header.pointerToSymbolTable; - StringTable stringTable @ addressof(symbolTable) + sizeof(symbolTable); -}; - -COFF coff @ 0x00; +#pragma MIME application/x-coff + +#include +#include + +enum Machine : u16 { + Unknown = 0x0000, + AM33 = 0x01D3, + AMD64 = 0x8664, + ARM = 0x01C0, + ARM64 = 0xAA64, + ARMNT = 0x01C4, + EBC = 0x0EBC, + I386 = 0x014C, + IA64 = 0x0200, + LOONGARCH32 = 0x6232, + LOONGARCH64 = 0x6264, + M32R = 0x9041, + MIPS16 = 0x0226, + MIPSFPU = 0x0366, + MIPSFPU16 = 0x0466, + POWERPC = 0x01F0, + POWERPCFP = 0x01F0, + R4000 = 0x0166, + RISCV32 = 0x5032, + RISCV64 = 0x5064, + RISCV128 = 0x5128, + SH3 = 0x01A2, + SH3DSP = 0x01A3, + SH4 = 0x01A6, + SH5 = 0x01A8, + THUMB = 0x01C2, + WCEMIPSV2 = 0x0169 +}; + +bitfield Characteristics { + relocsStripped : 1; + executableImage : 1; + lineNumsStripped : 1; + localSymsStripped : 1; + aggressiveWsTrim : 1; + largeAddressAware : 1; + padding : 1; + bytesReversedLo : 1; + _32BitMachine : 1; + debugStripped : 1; + removableRunFromSwap : 1; + netRunFromSwap : 1; + system : 1; + dll : 1; + upSystemOnly : 1; + bytesReversedHi : 1; +}; + +enum Type : u16 { + Null = 0, + Void = 1, + Char = 2, + Short = 3, + Int = 4, + Long = 5, + Float = 6, + Double = 7, + Struct = 8, + Union = 9, + Enum = 10, + MOE = 11, + Byte = 12, + Word = 13, + UInt = 14, + DWord = 15 +}; + +enum StorageClass : u8 { + EndOfFunction = 0xFF, + Null = 0, + Automatic = 1, + External = 2, + Static = 3, + Register = 4, + ExternalDef = 5, + Label = 6, + UndefinedLabel = 7, + MemberOfStruct = 8, + Argument = 9, + StructTag = 10, + MemberOfUnion = 11, + UnionTag = 12, + TypeDefinition = 13, + UndefinedStatic = 14, + EnumTag = 15, + MemberOfEnum = 16, + RegisterParam = 17, + BitField = 18, + Block = 100, + Function = 101, + EndOfStruct = 102, + File = 103, + Section = 104, + WeakExternal = 105, + CLRToken = 107 +}; + +struct AuxSymbol { + u8 data[18]; +}; + +u32 countedSymbols = 0; +struct SymbolTable { + char name[8]; + u32 value; + u16 sectionNumber; + Type type; + StorageClass storageClass; + u8 numberOfAuxSymbols; + + countedSymbols += 1 + numberOfAuxSymbols; + + AuxSymbol auxSymbols[numberOfAuxSymbols]; + + if (countedSymbols >= parent.header.numberOfSymbols) + break; +}; + +struct String { + char value[]; +}; + +struct StringTable { + u32 size; + String strings[while($ < addressof(size) + size)]; +}; + +bitfield SectionFlags { + padding : 3; + typeNoPad : 1; + padding : 1; + cntCode : 1; + initializedData : 1; + uninitializedData : 1; + lnkOther : 1; + lnkInfo : 1; + padding : 1; + lnkRemove : 1; + lnkCOMDAT : 1; + padding : 2; + gprel : 1; + padding : 1; + memPurgeable : 1; + memLocked : 1; + memPreload : 1; + alignment : 4 [[format("format_alignment")]]; + lnkNrelocOvfl : 1; + memDiscardable : 1; + memNotCached : 1; + memNotPaged : 1; + memShared : 1; + memExecute : 1; + memRead : 1; + memWrite : 1; +}; + +fn format_alignment(u8 alignment) { + return 1 << alignment; +}; + +struct Relocations { + u32 virtualAddress; + u32 symbolTableIndex; + Type type; +}; + +struct Section { + char name[8]; + type::Size virtualSize; + u32 virtualAddress; + type::Size sizeOfRawData; + u32 pointerToRawData; + u32 pointerToRelocations; + u32 pointerToLineNumbers; + u16 numberOfRelocations; + u16 numberOfLineNumbers; + SectionFlags characteristics; + + u8 rawData[sizeOfRawData] @ pointerToRawData [[sealed]]; + Relocations relocations[numberOfRelocations] @ pointerToRelocations; +}; + +struct Header { + Machine machine; + u16 numberOfSections; + type::time32_t timeDateStamp; + u32 pointerToSymbolTable; + u32 numberOfSymbols; + u16 sizeOfOptionalHeader; + Characteristics characteristics; +}; + + +struct COFF { + Header header; + + Section sectionTable[header.numberOfSections]; + + SymbolTable symbolTable[header.numberOfSymbols] @ header.pointerToSymbolTable; + StringTable stringTable @ addressof(symbolTable) + sizeof(symbolTable); +}; + +COFF coff @ 0x00; diff --git a/patterns/cpio.pat b/patterns/cpio.pat index e33085d..cba0888 100644 --- a/patterns/cpio.pat +++ b/patterns/cpio.pat @@ -22,14 +22,14 @@ namespace old_binary { using SwappedU32 = u32 [[transform("old_binary::swap_32bit"), format("old_binary::swap_32bit")]]; bitfield Mode { - file_type : 4; - suid : 1; - sgid : 1; - sticky : 1; - r : 3; - w : 3; x : 3; - } [[left_to_right]]; + w : 3; + r : 3; + sticky : 1; + sgid : 1; + suid : 1; + file_type : 4; + }; struct CpioHeader { type::Oct magic; diff --git a/patterns/elf.hexpat b/patterns/elf.hexpat index 88298e1..90c19a2 100644 --- a/patterns/elf.hexpat +++ b/patterns/elf.hexpat @@ -4,10 +4,12 @@ #pragma MIME application/x-object #pragma MIME application/x-sharedlib -#include #include +#include #include +using BitfieldOrder = std::core::BitfieldOrder; + using EI_ABIVERSION = u8; using Elf32_Addr = u32; using Elf32_BaseAddr = u32; @@ -458,37 +460,37 @@ enum VER_NEED : Elf32_Half { }; bitfield SYMINFO_FLG { - padding : 10; - NOEXTDIRECT : 1; - DIRECTBIND : 1; - LAZYLOAD : 1; - COPY : 1; - RESERVED : 1; DIRECT : 1; -} [[left_to_right]]; + RESERVED : 1; + COPY : 1; + LAZYLOAD : 1; + DIRECTBIND : 1; + NOEXTDIRECT : 1; + padding : 10; +}; bitfield ST { ST_BIND : 4; ST_TYPE : 4; -} [[left_to_right]]; +} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 8)]]; bitfield SHF { - MASKPROC : 4; - MASKOS : 8; - UNKNOWN : 8; - COMPRESSED : 1; - TLS : 1; - GROUP : 1; - OS_NONCONFORMING : 1; - LINK_ORDER : 1; - INFO_LINK : 1; - STRINGS : 1; - MERGE : 1; - padding : 1; - EXECINSTR : 1; - ALLOC : 1; WRITE : 1; -} [[left_to_right]]; + ALLOC : 1; + EXECINSTR : 1; + padding : 1; + MERGE : 1; + STRINGS : 1; + INFO_LINK : 1; + LINK_ORDER : 1; + OS_NONCONFORMING : 1; + GROUP : 1; + TLS : 1; + COMPRESSED : 1; + UNKNOWN : 8; + MASKOS : 8; + MASKPROC : 4; +}; bitfield ELF32_R_INFO { SYM : 8; @@ -501,13 +503,13 @@ bitfield ELF64_R_INFO { } [[left_to_right]]; bitfield PF { - MASKPROC : 4; - MASKOS : 4; - padding : 17; - R : 1; - W : 1; X : 1; -} [[left_to_right]]; + W : 1; + R : 1; + padding : 17; + MASKOS : 4; + MASKPROC : 4; +}; struct E_IDENT { char EI_MAG[4]; diff --git a/patterns/flac.hexpat b/patterns/flac.hexpat index 9a7cac8..f88476c 100644 --- a/patterns/flac.hexpat +++ b/patterns/flac.hexpat @@ -1,321 +1,323 @@ -#include -#include -#include - -#pragma endian big - -u32 sampleSize; -u32 bitsPerSample; - -// METADATA - -enum BLOCK_TYPE : u8 { - STREAMINFO = 0, - PADDING = 1, - APPLICATION = 2, - SEEKTABLE = 3, - VORBIS_COMMENT = 4, - CUESHEET = 5, - PICTURE = 6, - - INVALID = 127 -}; - -bitfield METADATA_BLOCK_HEADER { - lastMetadataBlock : 1; - blockType : 7; - length : 24; -} [[left_to_right]]; - -bitfield STREAMINFO_FLAGS { - sampleRate : 20; - numChannels : 3 [[format("format_channels")]]; - bitsPerSample : 5; - numSamplesInStream : 36; -} [[inline, left_to_right]]; - -fn format_channels(u8 value) { - return value + 1; -}; - -struct METADATA_BLOCK_STREAMINFO { - u16 minBlockSize, maxBlockSize; - u24 minFrameSize, maxFrameSize; - STREAMINFO_FLAGS flags; - u128 md5Signature; - - bitsPerSample = flags.bitsPerSample; -}; - -struct METADATA_BLOCK_PADDING { - padding[parent.header.length]; -}; - -struct METADATA_BLOCK_APPLICATION { - char applicationID[4]; - u8 applicationData[parent.header.length - sizeof(applicationID)]; -}; - -struct SEEKPOINT { - u64 sampleNumber; - u64 byteOffset; - u16 numSamples; -}; - -struct METADATA_BLOCK_SEEKTABLE { - SEEKPOINT seekPoints[parent.header.length / 18]; -}; - -struct VORBIS_USER_COMMENT { - le u32 length; - char comment[length]; -}; - -struct METADATA_BLOCK_VORBIS_COMMENT { - le u32 vendorLength; - u8 vendor[vendorLength]; - - le u32 userCommentListLength; - VORBIS_USER_COMMENT userCommentList[userCommentListLength]; -}; - -bitfield TRACK_FLAGS { - audioTrack : 1; - preEmphasis : 1; - padding : 6; -} [[inline]]; - -struct CUESHEET_TRACK_INDEX { - u64 sampleOffset; - u8 indexPointNumber; - padding[3]; -}; - -struct CUESHEET_TRACK { - u64 trackOffset; - u8 trackNumber; - char trackISRC[12]; - TRACK_FLAGS flags; - padding[13]; - u8 numTrackIndexPoints; - CUESHEET_TRACK_INDEX indexes[numTrackIndexPoints]; -}; - -struct METADATA_BLOCK_CUESHEET { - char mediaCatalogNumber[128]; - u64 numLeadInSamples; - bool isCD; - padding[258]; - u8 numTracks; - CUESHEET_TRACK tracks[numTracks]; -}; - -enum PICTURE_TYPE : u32 { - Other = 0, - FileIcon = 1, - OtherFileIcon = 2, - CoverFront = 3, - CoverBack = 4, - LeafletPage = 5, - Media = 6, - LeadArtist = 7, - Artist = 8, - Conductor = 9, - Band = 10, - Composer = 11, - Lyricist = 12, - RecordingLocation = 13, - DuringRecording = 14, - DuringPerformance = 15, - MovieScreenCapture = 16, - ABrightColoredFish = 17, - Illustration = 18, - BandLogoType = 19, - PublisherLogoType = 20 -}; - -struct METADATA_BLOCK_PICTURE { - PICTURE_TYPE pictureType; - u32 mimeTypeLength; - char mimeType[mineTypeLength]; - u32 descriptionLength; - char description[descriptionLength]; - u32 width, height; - u32 colorDepth; - u32 colorCount; - u32 pictureDataLength; - u8 pictureData[pictureDataLength]; -}; - - - -// FRAME DATA -// TODO: THIS IS INCOMPLETE / NOT WORKING CURRENTLY - -bitfield FRAME_HEADER_FLAGS { - syncCode : 14; - padding : 1; - blockingStrategy : 1; - blockSize : 4; - sampleRate : 4; - channelAssignment : 4; - sampleSize : 3; - padding : 1; -} [[inline]]; - -struct FRAME_HEADER { - FRAME_HEADER_FLAGS flags; - - sampleSize = flags.sampleSize; - - if (flags.blockingStrategy) - char16 sampleNumber[7]; - else - char16 frameNumber[6]; - - if (flags.blockSize == 0b0110) - u8 blockSize; - else if (flags.blockSize == 0b0111) - u16 blockSize; - - if (flags.sampleRate == 0b1100) - u8 sampleRate; - else if (flags.sampleRate == 0b1101 || flags.sampleRate == 0b1110) - u16 sampleRate; - - u8 crc8; -}; - -struct FRAME_FOOTER { - u16 crc16; -}; - -bitfield SUBFRAME_HEADER { - padding : 1; - type : 6; - wastedBits : 1; -}; - -fn getBitsPerSample() { - if (sampleSize == 0b000) - return bitsPerSample; - else if (sampleSize == 0b001) - return 8; - else if (sampleSize == 0b010) - return 12; - else if (sampleSize == 0b100) - return 16; - else if (sampleSize == 0b101) - return 20; - else if (sampleSize == 0b110) - return 24; -}; - -bitfield SUBFRAME_CONSTANT { - value : getBitsPerSample(); -}; - -bitfield SUBFRAME_VERBATIM { - value : getBitsPerSample() * parent.parent.header.flags.blockSize; -}; - -bitfield SUBFRAME_FIXED_VALUE { - value : getBitsPerSample() * (parent.parent.header.type & 0b111); - codingMethod : 2; -} [[inline]]; - -bitfield RESIDUAL_CODING_METHOD_PARTITIONED_RICE { - partitionOrder : 4; - riceParameter : 4; - if (riceParameter == 0b1111) - bitsPerSample : 5; -} [[right_to_left]]; - -bitfield RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 { - partitionOrder : 4; - riceParameter : 5; - if (riceParameter == 0b11111) - bitsPerSample : 5; -} [[right_to_left]]; - -struct RESIDUAL { - if (parent.value.codingMethod == 0b00) - RESIDUAL_CODING_METHOD_PARTITIONED_RICE rice; - else if (parent.value.codingMethod == 0b01) - RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 rice; - - - if ((parent.parent.header.type & 0b111) == 0b000) - u8 samples[(getBitsPerSample() * (parent.parent.parent.header.flags.blockSize - (parent.parent.header.type & 0b111))) / 8]; - else if (std::core::array_index() != 0) - u8 samples[(getBitsPerSample() * (parent.parent.parent.header.flags.blockSize / (1 << rice.partitionOrder))) / 8]; - else - u8 samples[(getBitsPerSample() * ((parent.parent.parent.header.flags.blockSize / (1 << rice.partitionOrder)) - (parent.parent.header.type & 0b111))) / 8]; -}; - -struct SUBFRAME_FIXED { - SUBFRAME_FIXED_VALUE value; - RESIDUAL residual; -}; - -bitfield SUBFRAME_LPC_VALUE { - warmUpSamples : getBitsPerSample() * ((parent.header.type & 0b011111) + 1); - quantizedLinearPredictorCoefficient : 4; - quantizedLinearPredictorCoefficientShift : 5; - predictorCoefficients : quantizedLinearPredictorCoefficient * ((parent.header.type & 0b011111) + 1); -} [[inline]]; - -struct SUBFRAME_LPC { - SUBFRAME_LPC_VALUE value; - RESIDUAL residual; -}; - - -struct SUBFRAME { - SUBFRAME_HEADER header; - - if (header.type == 0b00000) - SUBFRAME_CONSTANT constant; - else if (header.type == 0b000001) - SUBFRAME_VERBATIM verbatim; - else if ((header.type >> 3) == 0b001 && (header.type & 0b111) <= 4) - SUBFRAME_FIXED fixed; - else if (header.type == 0b100000) - SUBFRAME_LPC lpc; -}; - -struct FRAME { - FRAME_HEADER header; - SUBFRAME subframes[parent.metadata[0].data.flags.numChannels + 1]; - FRAME_FOOTER footer; -}; - - -struct METADATA_BLOCK { - METADATA_BLOCK_HEADER header; - if (header.lastMetadataBlock) - break; - - if (header.blockType == BLOCK_TYPE::STREAMINFO) - METADATA_BLOCK_STREAMINFO data; - else if (header.blockType == BLOCK_TYPE::PADDING) - METADATA_BLOCK_PADDING data; - else if (header.blockType == BLOCK_TYPE::APPLICATION) - METADATA_BLOCK_APPLICATION data; - else if (header.blockType == BLOCK_TYPE::VORBIS_COMMENT) - METADATA_BLOCK_VORBIS_COMMENT data; - else if (header.blockType == BLOCK_TYPE::CUESHEET) - METADATA_BLOCK_CUESHEET data; - else if (header.blockType == BLOCK_TYPE::PICTURE) - METADATA_BLOCK_PICTURE data; - else - std::error("Invalid metadata block type!"); -}; - -struct STREAM { - char magic[4]; - METADATA_BLOCK metadata[while(true)]; - //FRAME frames[while(!std::mem::eof())]; -}; - +#include +#include +#include + +#pragma endian big + +using BitfieldOrder = std::core::BitfieldOrder; + +u32 sampleSize; +u32 bitsPerSample; + +// METADATA + +enum BLOCK_TYPE : u8 { + STREAMINFO = 0, + PADDING = 1, + APPLICATION = 2, + SEEKTABLE = 3, + VORBIS_COMMENT = 4, + CUESHEET = 5, + PICTURE = 6, + + INVALID = 127 +}; + +bitfield METADATA_BLOCK_HEADER { + lastMetadataBlock : 1; + blockType : 7; + length : 24; +}; + +bitfield STREAMINFO_FLAGS { + sampleRate : 20; + numChannels : 3 [[format("format_channels")]]; + bitsPerSample : 5; + numSamplesInStream : 36; +} [[inline]]; + +fn format_channels(u8 value) { + return value + 1; +}; + +struct METADATA_BLOCK_STREAMINFO { + u16 minBlockSize, maxBlockSize; + u24 minFrameSize, maxFrameSize; + STREAMINFO_FLAGS flags; + u128 md5Signature; + + bitsPerSample = flags.bitsPerSample; +}; + +struct METADATA_BLOCK_PADDING { + padding[parent.header.length]; +}; + +struct METADATA_BLOCK_APPLICATION { + char applicationID[4]; + u8 applicationData[parent.header.length - sizeof(applicationID)]; +}; + +struct SEEKPOINT { + u64 sampleNumber; + u64 byteOffset; + u16 numSamples; +}; + +struct METADATA_BLOCK_SEEKTABLE { + SEEKPOINT seekPoints[parent.header.length / 18]; +}; + +struct VORBIS_USER_COMMENT { + le u32 length; + char comment[length]; +}; + +struct METADATA_BLOCK_VORBIS_COMMENT { + le u32 vendorLength; + u8 vendor[vendorLength]; + + le u32 userCommentListLength; + VORBIS_USER_COMMENT userCommentList[userCommentListLength]; +}; + +bitfield TRACK_FLAGS { + audioTrack : 1; + preEmphasis : 1; +} [[inline,bitfield_order(BitfieldOrder::LeastToMostSignificant, 8)]]; + +struct CUESHEET_TRACK_INDEX { + u64 sampleOffset; + u8 indexPointNumber; + padding[3]; +}; + +struct CUESHEET_TRACK { + u64 trackOffset; + u8 trackNumber; + char trackISRC[12]; + TRACK_FLAGS flags; + padding[13]; + u8 numTrackIndexPoints; + CUESHEET_TRACK_INDEX indexes[numTrackIndexPoints]; +}; + +struct METADATA_BLOCK_CUESHEET { + char mediaCatalogNumber[128]; + u64 numLeadInSamples; + bool isCD; + padding[258]; + u8 numTracks; + CUESHEET_TRACK tracks[numTracks]; +}; + +enum PICTURE_TYPE : u32 { + Other = 0, + FileIcon = 1, + OtherFileIcon = 2, + CoverFront = 3, + CoverBack = 4, + LeafletPage = 5, + Media = 6, + LeadArtist = 7, + Artist = 8, + Conductor = 9, + Band = 10, + Composer = 11, + Lyricist = 12, + RecordingLocation = 13, + DuringRecording = 14, + DuringPerformance = 15, + MovieScreenCapture = 16, + ABrightColoredFish = 17, + Illustration = 18, + BandLogoType = 19, + PublisherLogoType = 20 +}; + +struct METADATA_BLOCK_PICTURE { + PICTURE_TYPE pictureType; + u32 mimeTypeLength; + char mimeType[mineTypeLength]; + u32 descriptionLength; + char description[descriptionLength]; + u32 width, height; + u32 colorDepth; + u32 colorCount; + u32 pictureDataLength; + u8 pictureData[pictureDataLength]; +}; + + + +// FRAME DATA +// TODO: THIS IS INCOMPLETE / NOT WORKING CURRENTLY + +bitfield FRAME_HEADER_FLAGS { + syncCode : 14; + padding : 1; + blockingStrategy : 1; + blockSize : 4; + sampleRate : 4; + channelAssignment : 4; + sampleSize : 3; +} [[inline,bitfield_order(BitfieldOrder::LeastToMostSignificant, 32)]]; + +struct FRAME_HEADER { + FRAME_HEADER_FLAGS flags; + + sampleSize = flags.sampleSize; + + if (flags.blockingStrategy) + char16 sampleNumber[7]; + else + char16 frameNumber[6]; + + if (flags.blockSize == 0b0110) + u8 blockSize; + else if (flags.blockSize == 0b0111) + u16 blockSize; + + if (flags.sampleRate == 0b1100) + u8 sampleRate; + else if (flags.sampleRate == 0b1101 || flags.sampleRate == 0b1110) + u16 sampleRate; + + u8 crc8; +}; + +struct FRAME_FOOTER { + u16 crc16; +}; + +bitfield SUBFRAME_HEADER { + padding : 1; + type : 6; + wastedBits : 1; +}; + +fn getBitsPerSample() { + if (sampleSize == 0b000) + return bitsPerSample; + else if (sampleSize == 0b001) + return 8; + else if (sampleSize == 0b010) + return 12; + else if (sampleSize == 0b100) + return 16; + else if (sampleSize == 0b101) + return 20; + else if (sampleSize == 0b110) + return 24; + else + std::error(std::format("Invalid sample size {}.", sampleSize)); +}; + +bitfield SUBFRAME_CONSTANT { + value : getBitsPerSample(); +}; + +bitfield SUBFRAME_VERBATIM { + value : getBitsPerSample() * parent.parent.header.flags.blockSize; +}; + +bitfield SUBFRAME_FIXED_VALUE { + value : getBitsPerSample() * (parent.parent.header.type & 0b111); + codingMethod : 2; +} [[inline]]; + +bitfield RESIDUAL_CODING_METHOD_PARTITIONED_RICE { + partitionOrder : 4; + riceParameter : 4; + if (riceParameter == 0b1111) + bitsPerSample : 5; +}; + +bitfield RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 { + partitionOrder : 4; + riceParameter : 5; + if (riceParameter == 0b11111) + bitsPerSample : 5; +}; + +struct RESIDUAL { + if (parent.value.codingMethod == 0b00) + RESIDUAL_CODING_METHOD_PARTITIONED_RICE rice; + else if (parent.value.codingMethod == 0b01) + RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 rice; + + + if ((parent.parent.header.type & 0b111) == 0b000) + u8 samples[(getBitsPerSample() * (parent.parent.parent.header.flags.blockSize - (parent.parent.header.type & 0b111))) / 8]; + else if (std::core::array_index() != 0) + u8 samples[(getBitsPerSample() * (parent.parent.parent.header.flags.blockSize / (1 << rice.partitionOrder))) / 8]; + else + u8 samples[(getBitsPerSample() * ((parent.parent.parent.header.flags.blockSize / (1 << rice.partitionOrder)) - (parent.parent.header.type & 0b111))) / 8]; +}; + +struct SUBFRAME_FIXED { + SUBFRAME_FIXED_VALUE value; + RESIDUAL residual; +}; + +bitfield SUBFRAME_LPC_VALUE { + warmUpSamples : getBitsPerSample() * ((parent.header.type & 0b011111) + 1); + quantizedLinearPredictorCoefficient : 4; + quantizedLinearPredictorCoefficientShift : 5; + predictorCoefficients : quantizedLinearPredictorCoefficient * ((parent.header.type & 0b011111) + 1); +} [[inline]]; + +struct SUBFRAME_LPC { + SUBFRAME_LPC_VALUE value; + RESIDUAL residual; +}; + + +struct SUBFRAME { + SUBFRAME_HEADER header; + + if (header.type == 0b00000) + SUBFRAME_CONSTANT constant; + else if (header.type == 0b000001) + SUBFRAME_VERBATIM verbatim; + else if ((header.type >> 3) == 0b001 && (header.type & 0b111) <= 4) + SUBFRAME_FIXED fixed; + else if (header.type == 0b100000) + SUBFRAME_LPC lpc; +}; + +struct FRAME { + FRAME_HEADER header; + SUBFRAME subframes[parent.metadata[0].data.flags.numChannels + 1]; + FRAME_FOOTER footer; +}; + + +struct METADATA_BLOCK { + METADATA_BLOCK_HEADER header; + if (header.lastMetadataBlock) + break; + + if (header.blockType == BLOCK_TYPE::STREAMINFO) + METADATA_BLOCK_STREAMINFO data; + else if (header.blockType == BLOCK_TYPE::PADDING) + METADATA_BLOCK_PADDING data; + else if (header.blockType == BLOCK_TYPE::APPLICATION) + METADATA_BLOCK_APPLICATION data; + else if (header.blockType == BLOCK_TYPE::VORBIS_COMMENT) + METADATA_BLOCK_VORBIS_COMMENT data; + else if (header.blockType == BLOCK_TYPE::CUESHEET) + METADATA_BLOCK_CUESHEET data; + else if (header.blockType == BLOCK_TYPE::PICTURE) + METADATA_BLOCK_PICTURE data; + else + std::error("Invalid metadata block type!"); +}; + +struct STREAM { + char magic[4]; + METADATA_BLOCK metadata[while(true)]; + //FRAME frames[while(!std::mem::eof())]; +}; + STREAM stream @ 0x00; \ No newline at end of file diff --git a/patterns/fs.hexpat b/patterns/fs.hexpat index c29e452..85431ce 100644 --- a/patterns/fs.hexpat +++ b/patterns/fs.hexpat @@ -13,7 +13,7 @@ bitfield CHS { h : 8; s : 6; c : 10; -} [[right_to_left, format("chs_formatter")]]; +} [[format("chs_formatter")]]; fn chs_formatter(CHS chs) { return std::format("({:X}, {:X}, {:X}) | 0x{:X}", chs.c, chs.h, chs.s, (chs.c * 16 + chs.h) * 63 + (chs.s - 1)); diff --git a/patterns/gzip.hexpat b/patterns/gzip.hexpat index fc9fcf5..569755e 100644 --- a/patterns/gzip.hexpat +++ b/patterns/gzip.hexpat @@ -1,77 +1,79 @@ -#pragma MIME application/gzip - -#include -#include -#include - -bitfield Flags { - FTEXT : 1; - FHCRC : 1; - FEXTRA : 1; - FNAME : 1; - FCOMMENT : 1; - padding : 3; -} [[right_to_left]]; - -bitfield ExtraFlags { - padding : 1; - maximumCompression : 1; - fastestCompression : 1; - padding : 5; -}; - -enum CompressionMethod : u8 { - Reserved = 0 ... 7, - Deflate = 8 -}; - -enum OperatingSystemID : u8 { - FATFileSystem = 0x00, - Amiga = 0x01, - VMS = 0x02, - Unix = 0x03, - VM_CMS = 0x04, - AtariTOS = 0x05, - HPFSFileSystem = 0x06, - Macintosh = 0x07, - ZSystem = 0x08, - CP_M = 0x09, - TOPS_20 = 0x0A, - NTFSFileSystem = 0x0B, - QDOS = 0x0C, - AcordRISCOS = 0x0D, - Unknown = 0xFF -}; - -struct GZip { - u16 signature; - CompressionMethod compressionMethod; - Flags flags; - type::time32_t modificationTime; - ExtraFlags extraFlags; - OperatingSystemID operatingSystemId; - - if (flags.FEXTRA) { - u16 extraLength; - u8 extraField[extraLength]; - } - - if (flags.FNAME) { - char originalFileName[]; - } - - if (flags.FCOMMENT) { - char comment[]; - } - - if (flags.FHCRC) { - u16 crc16; - } - - u8 data[while($ < std::mem::size() - 8)] [[sealed]]; - - u32 crc32; - type::Size isize; -}; - +#pragma MIME application/gzip + +#include +#include +#include +#include + +using BitfieldOrder = std::core::BitfieldOrder; + +bitfield Flags { + FTEXT : 1; + FHCRC : 1; + FEXTRA : 1; + FNAME : 1; + FCOMMENT : 1; +} [[bitfield_order(BitfieldOrder::LeastToMostSignificant, 8)]]; + +bitfield ExtraFlags { + padding : 1; + maximumCompression : 1; + fastestCompression : 1; + padding : 5; +}; + +enum CompressionMethod : u8 { + Reserved = 0 ... 7, + Deflate = 8 +}; + +enum OperatingSystemID : u8 { + FATFileSystem = 0x00, + Amiga = 0x01, + VMS = 0x02, + Unix = 0x03, + VM_CMS = 0x04, + AtariTOS = 0x05, + HPFSFileSystem = 0x06, + Macintosh = 0x07, + ZSystem = 0x08, + CP_M = 0x09, + TOPS_20 = 0x0A, + NTFSFileSystem = 0x0B, + QDOS = 0x0C, + AcordRISCOS = 0x0D, + Unknown = 0xFF +}; + +struct GZip { + u16 signature; + CompressionMethod compressionMethod; + Flags flags; + type::time32_t modificationTime; + ExtraFlags extraFlags; + OperatingSystemID operatingSystemId; + + if (flags.FEXTRA) { + u16 extraLength; + u8 extraField[extraLength]; + } + + if (flags.FNAME) { + char originalFileName[]; + } + + if (flags.FCOMMENT) { + char comment[]; + } + + if (flags.FHCRC) { + u16 crc16; + } + + u8 data[while($ < std::mem::size() - 8)] [[sealed]]; + + u32 crc32; + type::Size isize; +}; + GZip gzip @ 0x00; \ No newline at end of file diff --git a/patterns/ip.hexpat b/patterns/ip.hexpat index 9d9b158..49277dd 100644 --- a/patterns/ip.hexpat +++ b/patterns/ip.hexpat @@ -1,5 +1,4 @@ #pragma endian big - #pragma bitfield_order left_to_right #include #include diff --git a/patterns/java_class.hexpat b/patterns/java_class.hexpat index f2abf8b..2a696e6 100644 --- a/patterns/java_class.hexpat +++ b/patterns/java_class.hexpat @@ -1,9 +1,12 @@ #pragma endian big #pragma MIME application/x-java-applet +#include #include #include +using BitfieldOrder = std::core::BitfieldOrder; + // The Java documentations use the number of bytes instead of the number of bits for its type names using u1 = u8; using u2 = u16; @@ -206,7 +209,7 @@ bitfield access_flags_method { padding : 1; // 0x2000 padding : 1; // 0x4000 padding : 1; // 0x8000 -}; +} [[bitfield_order(BitfieldOrder::LeastToMostSignificant, 16)]]; bitfield access_flags_field { ACC_PUBLIC : 1; // 0x0001 @@ -225,7 +228,7 @@ bitfield access_flags_field { padding : 1; // 0x2000 ACC_ENUM : 1; // 0x4000 padding : 1; // 0x8000 -}; +} [[bitfield_order(BitfieldOrder::LeastToMostSignificant, 16)]]; bitfield access_flags_class { ACC_PUBLIC : 1; // 0x0001 @@ -244,7 +247,7 @@ bitfield access_flags_class { ACC_ANNOTATION : 1; // 0x2000 ACC_ENUM : 1; // 0x4000 ACC_MODULE : 1; // 0x8000 -}; +} [[bitfield_order(BitfieldOrder::LeastToMostSignificant, 16)]]; struct attribute_info { u2 attribute_name_info; diff --git a/patterns/lnk.hexpat b/patterns/lnk.hexpat index ea1d6b5..a556d44 100644 --- a/patterns/lnk.hexpat +++ b/patterns/lnk.hexpat @@ -1,459 +1,462 @@ -#pragma MIME application/x-ms-shortcut - -#include -#include - -bitfield LinkFlags { - HasLinkTargetIDList : 1; - HasLinkInfo : 1; - HasName : 1; - HasRelativePath : 1; - HasWorkingDir : 1; - HasArguments : 1; - HasIconLocation : 1; - IsUnicode : 1; - ForceNoLinkInfo : 1; - HasExpString : 1; - RunInSeparateProcess : 1; - padding : 1; - HasDarwinID : 1; - RunAsUser : 1; - HasExpIcon : 1; - NoPidlAlias : 1; - padding : 1; - RunWithShimLayer : 1; - ForceNoLinkTrack : 1; - EnableTargetMetadata : 1; - DisableLinkPathTracking : 1; - DisableKnownFolderTracking : 1; - DisableKnownFolderAlias : 1; - AllowLinkToLink : 1; - UnaliasOnSave : 1; - PreferEnvironmentPath : 1; - KeepLocalIDListForUNCTarget : 1; - padding : 5; -} [[right_to_left]]; - -bitfield FileAttributesFlags { - FILE_ATTRIBUTE_READONLY : 1; - FILE_ATTRIBUTE_HIDDEN : 1; - FILE_ATTRIBUTE_SYSTEM : 1; - padding : 1; - FILE_ATTRIBUTE_DIRECTORY : 1; - FILE_ATTRIBUTE_ARCHIVE : 1; - padding : 1; - FILE_ATTRIBUTE_NORMAL : 1; - FILE_ATTRIBUTE_TEMPORARY : 1; - FILE_ATTRIBUTE_SPARSE_FILE : 1; - FILE_ATTRIBUTE_REPARSE_POINT : 1; - FILE_ATTRIBUTE_COMPRESSED : 1; - FILE_ATTRIBUTE_OFFLINE : 1; - FILE_ATTRIBUTE_NOT_CONTENT_INDEXED : 1; - FILE_ATTRIBUTE_ENCRYPTED : 1; - padding : 17; -} [[right_to_left]]; - -bitfield ModifierKeys { - HOTKEYF_SHIFT : 1; - HOTKEYF_CONTROL : 1; - HOTKEYF_ALT : 1; - padding : 5; -} [[right_to_left]]; - -enum Keys : u8 { - KEY_NONE = 0x00, - KEY_0 = 0x30, - KEY_1 = 0x31, - KEY_2 = 0x32, - KEY_3 = 0x33, - KEY_4 = 0x34, - KEY_5 = 0x35, - KEY_6 = 0x36, - KEY_7 = 0x37, - KEY_8 = 0x38, - KEY_9 = 0x39, - KEY_A = 0x41, - KEY_B = 0x42, - KEY_C = 0x43, - KEY_D = 0x44, - KEY_E = 0x45, - KEY_F = 0x46, - KEY_G = 0x47, - KEY_H = 0x48, - KEY_I = 0x49, - KEY_J = 0x4A, - KEY_K = 0x4B, - KEY_L = 0x4C, - KEY_M = 0x4D, - KEY_N = 0x4E, - KEY_O = 0x4F, - KEY_P = 0x50, - KEY_Q = 0x51, - KEY_R = 0x52, - KEY_S = 0x53, - KEY_T = 0x54, - KEY_U = 0x55, - KEY_V = 0x56, - KEY_W = 0x57, - KEY_X = 0x58, - KEY_Y = 0x59, - KEY_Z = 0x5A, - - VK_F1 = 0x70, - VK_F2 = 0x71, - VK_F3 = 0x72, - VK_F4 = 0x73, - VK_F5 = 0x74, - VK_F6 = 0x75, - VK_F7 = 0x76, - VK_F8 = 0x77, - VK_F9 = 0x78, - VK_F10 = 0x79, - VK_F11 = 0x7A, - VK_F12 = 0x7B, - VK_F13 = 0x7C, - VK_F14 = 0x7D, - VK_F15 = 0x7E, - VK_F16 = 0x7F, - VK_F17 = 0x80, - VK_F18 = 0x81, - VK_F19 = 0x82, - VK_F20 = 0x83, - VK_F21 = 0x84, - VK_F22 = 0x85, - VK_F23 = 0x86, - VK_F24 = 0x87, - VK_NUMLOCK = 0x90, - VK_SCROLL = 0x91, -}; - -struct HotKeyFlags { - Keys Key; - ModifierKeys ModifierKeys; -}; - -struct FILETIME { - u32 dwLowDateTime; - u32 dwHighDateTime; -}; - -enum SHOWWINDOW_FLAGS : u32 { - SW_SHOWNORMAL = 0x00000001, - SW_SHOWMAXIMIZED = 0x00000003, - SW_SHOWMINNOACTIVE = 0x00000007 -}; - -struct ShellLinkHeader { - type::Size32 HeaderSize; - type::GUID LinkCLSID; - LinkFlags LinkFlags; - FileAttributesFlags FileAttributes; - FILETIME CreationTime, AccessTime, WriteTime; - type::Size32 FileSize; - u32 IconIndex; - SHOWWINDOW_FLAGS ShowCommand; - HotKeyFlags HotKey; - padding[2]; - padding[4]; - padding[4]; -}; - -struct ItemID { - type::Size16 ItemIDSize; - - if (ItemIDSize == 0x00) - break; - else - u8 Data[ItemIDSize - sizeof(ItemIDSize)]; -}; - -struct IDList { - ItemID ItemIDList[while(true)]; -}; - -struct LinkTargetIDList { - type::Size16 IDListSize; - IDList IDList[while($ < (addressof(IDListSize) + IDListSize))]; -}; - -bitfield LinkInfoFlags { - VolumeIDAndLocalBasePath : 1; - CommonNetworkRelativeLinkAndPathSuffix : 1; - padding : 30; -}; - -enum DriveType : u32 { - DRIVE_UNKNOWN = 0x00000000, - DRIVE_NO_ROOT_DIR = 0x00000001, - DRIVE_REMOVABLE = 0x00000002, - DRIVE_FIXED = 0x00000003, - DRIVE_REMOTE = 0x00000004, - DRIVE_CDROM = 0x00000005, - DRIVE_RAMDISK = 0x00000006 -}; - -struct VolumeID { - type::Size32 VolumeIDSize; - DriveType DriveType; - u32 DriveSerialNumber; - u32 VolumeLabelOffset; - if (VolumeLabelOffset == 0x14) - u32 VolumeLabelOffsetUnicode; - char Data[VolumeIDSize - ($ - addressof(this))]; -}; - -bitfield CommonNetworkRelativeLinkFlags { - ValidDevice : 1; - ValidNetType : 1; - padding : 30; -} [[right_to_left]]; - -enum NetworkProviderType : u32 { - WNNC_NET_AVID = 0x001A0000, - WNNC_NET_DOCUSPACE = 0x001B0000, - WNNC_NET_MANGOSOFT = 0x001C0000, - WNNC_NET_SERNET = 0x001D0000, - WNNC_NET_RIVERFRONT1 = 0x001E0000, - WNNC_NET_RIVERFRONT2 = 0x001F0000, - WNNC_NET_DECORB = 0x00200000, - WNNC_NET_PROTSTOR = 0x00210000, - WNNC_NET_FJ_REDIR = 0x00220000, - WNNC_NET_DISTINCT = 0x00230000, - WNNC_NET_TWINS = 0x00240000, - WNNC_NET_RDR2SAMPLE = 0x00250000, - WNNC_NET_CSC = 0x00260000, - WNNC_NET_3IN1 = 0x00270000, - WNNC_NET_EXTENDNET = 0x00290000, - WNNC_NET_STAC = 0x002A0000, - WNNC_NET_FOXBAT = 0x002B0000, - WNNC_NET_YAHOO = 0x002C0000, - WNNC_NET_EXIFS = 0x002D0000, - WNNC_NET_DAV = 0x002E0000, - WNNC_NET_KNOWARE = 0x002F0000, - WNNC_NET_OBJECT_DIRE = 0x00300000, - WNNC_NET_MASFAX = 0x00310000, - WNNC_NET_HOB_NFS = 0x00320000, - WNNC_NET_SHIVA = 0x00330000, - WNNC_NET_IBMAL = 0x00340000, - WNNC_NET_LOCK = 0x00350000, - WNNC_NET_TERMSRV = 0x00360000, - WNNC_NET_SRT = 0x00370000, - WNNC_NET_QUINCY = 0x00380000, - WNNC_NET_OPENAFS = 0x00390000, - WNNC_NET_AVID1 = 0x003A0000, - WNNC_NET_DFS = 0x003B0000, - WNNC_NET_KWNP = 0x003C0000, - WNNC_NET_ZENWORKS = 0x003D0000, - WNNC_NET_DRIVEONWEB = 0x003E0000, - WNNC_NET_VMWARE = 0x003F0000, - WNNC_NET_RSFX = 0x00400000, - WNNC_NET_MFILES = 0x00410000, - WNNC_NET_MS_NFS = 0x00420000, - WNNC_NET_GOOGLE = 0x00430000 -}; - -struct CommonNetworkRelativeLink { - type::Size32 CommonNetworkRelativeLinkSize; - CommonNetworkRelativeLinkFlags CommonNetworkRelativeLinkFlags; - u32 NetNameOffset; - u32 DeviceNameOffset; - NetworkProviderType NetworkProviderType; - - if (NetNameOffset > 0x14) { - u32 NetNameOffsetUnicode; - u32 DeviceNameOffsetUnicode; - } - - char NetName[]; - char DeviceName[]; - - if (NetNameOffset > 0x14) { - char16 NetNameUnicode[]; - char16 DeviceNameUnicode[]; - } -}; - -struct LinkInfo { - type::Size32 LinkInfoSize; - type::Size32 LinkInfoHeaderSize; - LinkInfoFlags LinkInfoFlags; - u32 VolumeIDOffset; - u32 LocalBasePathOffset; - u32 CommonNetworkRelativeLinkOffset; - u32 CommonPathSuffixOffset; - - if (LinkInfoHeaderSize >= 0x24) { - u32 LocalBasePathOffsetUnicode; - u32 CommonPathSuffixOffsetUnicode; - } - - if (LinkInfoFlags.VolumeIDAndLocalBasePath) { - VolumeID VolumeID; - char LocalBasePath[]; - } - - if (LinkInfoFlags.CommonNetworkRelativeLinkAndPathSuffix) - CommonNetworkRelativeLink CommonNetworkRelativeLink; - - char CommonPathSuffix[]; - - if (LinkInfoHeaderSize >= 0x24) { - if (LinkInfoFlags.VolumeIDAndLocalBasePath) - char16 LocalBasePathUnicode[]; - char16 CommonPathSuffixUnicode[]; - } -}; - -struct String { - u16 CountCharacters; - char16 String[CountCharacters]; -}; - -struct StringData { - if (parent.ShellLinkHeader.LinkFlags.HasName) - String NAME_STRING; - if (parent.ShellLinkHeader.LinkFlags.HasRelativePath) - String RELATIVE_PATH; - if (parent.ShellLinkHeader.LinkFlags.HasWorkingDir) - String WORKING_DIR; - if (parent.ShellLinkHeader.LinkFlags.HasArguments) - String COMMAND_LINE_ARGUMENTS; - if (parent.ShellLinkHeader.LinkFlags.HasIconLocation) - String ICON_LOCATION; -}; - -bitfield FillAttributes { - FOREGROUND_BLUE : 1; - FOREGROUND_GREEN : 1; - FOREGROUND_RED : 1; - FOREGROUND_INTENSITY : 1; - - BACKGROUND_BLUE : 1; - BACKGROUND_GREEN : 1; - BACKGROUND_RED : 1; - BACKGROUND_INTENSITY : 1; - - padding : 8; -} [[right_to_left]]; - -struct ConsoleDataBlock { - FillAttributes FillAttributes; - FillAttributes PopupFillAttributes; - u16 ScreenBufferSizeX, ScreenBufferSizeY; - u16 WindowSizeX, WindowSizeY; - u16 WindowOriginX, WindowOriginY; - padding[4]; - padding[4]; - u32 FontSize; - u32 FontFamily; - u32 FontWeight; - char16 FaceName[32]; - u32 CursorSize; - u32 FullScreen; - u32 QuickEdit; - u32 InsertMode; - u32 AutoPosition; - u32 HistoryBufferSize; - u32 NumberOfHistoryBuffers; - u32 HistoryNoDup; - u32 ColorTable[16]; -}; - -struct ConsoleFEDataBlock { - u32 CodePage; -}; - -struct DarwinDataBlock { - char DarwinDataAnsi[260]; - char16 DarwinDataUnicode[260]; -}; - -struct EnvironmentVariableDataBlock { - char TargetAnsi[260]; - char16 TargetUnicode[260]; -}; - -struct IconEnvironmentDataBlock { - char TargetAnsi[260]; - char16 TargetUnicode[260]; -}; - -struct KnownFolderDataBlock { - type::GUID KnownFolderID; - u32 Offset; -}; - -struct PropertyStoreDataBlock { - u8 Bytes[parent.BlockSize - sizeof(parent.BlockSize) - sizeof(parent.BlockSignature)]; - std::warning("PropertyStoreDataBlock is not yet implemented!"); -}; - -struct ShimDataBlock { - char16 LayerName[(parent.BlockSize - sizeof(parent.BlockSize) - sizeof(parent.BlockSignature)) / sizeof(char16)]; -}; - -struct SpecialFolderDataBlock { - u32 SpecialFolderID; - u32 Offset; -}; - -struct TrackerDataBlock { - type::Size32 Length; - u32 Version; - char MachineID[16]; - type::GUID Droid[2]; - type::GUID DroidBirth[2]; -}; - -struct VistaAndAboveIDListDataBlock { - IDList IDList; -}; - -struct ExtraDataBlock { - type::Size32 BlockSize; - - if (BlockSize < 0x04) - break; - else { - u32 BlockSignature; - - if (BlockSignature == 0xA000'0002) - ConsoleDataBlock CONSOLE_PROPS; - else if (BlockSignature == 0xA000'0004) - ConsoleFEDataBlock CONSOLE_FE_PROPS; - else if (BlockSignature == 0xA000'0006) - DarwinDataBlock DARWIN_PROPS; - else if (BlockSignature == 0xA000'0001) - EnvironmentVariableDataBlock ENVIRONMENT_PROPS; - else if (BlockSignature == 0xA000'0007) - IconEnvironmentDataBlock ICON_ENVIRONMENT_PROPS; - else if (BlockSignature == 0xA000'000B) - KnownFolderDataBlock KNOWN_FOLDER_PROPS; - else if (BlockSignature == 0xA000'0009) - PropertyStoreDataBlock PROPERTY_STORE_PROPS; - else if (BlockSignature == 0xA000'0008) - ShimDataBlock SHIM_PROPS; - else if (BlockSignature == 0xA000'0005) - SpecialFolderDataBlock SPECIAL_FOLDER_PROPS; - else if (BlockSignature == 0xA000'0003) - TrackerDataBlock TRACKER_PROPS; - else if (BlockSignature == 0xA000'000C) - VistaAndAboveIDListDataBlock VISTA_AND_ABOVE_IDLIST_PROPS; - } -}; - -struct ExtraData { - ExtraDataBlock ExtraDataBlock[while(true)]; -}; - -struct LNK { - ShellLinkHeader ShellLinkHeader; - if (ShellLinkHeader.LinkFlags.HasLinkTargetIDList) - LinkTargetIDList LinkTargetIDList; - if (ShellLinkHeader.LinkFlags.HasLinkInfo) - LinkInfo LinkInfo; - StringData StringData; - ExtraData ExtraData; -}; - -LNK lnk @ 0x00; +#pragma MIME application/x-ms-shortcut + +#include +#include +#include + +using BitfieldOrder = std::core::BitfieldOrder; + +bitfield LinkFlags { + HasLinkTargetIDList : 1; + HasLinkInfo : 1; + HasName : 1; + HasRelativePath : 1; + HasWorkingDir : 1; + HasArguments : 1; + HasIconLocation : 1; + IsUnicode : 1; + ForceNoLinkInfo : 1; + HasExpString : 1; + RunInSeparateProcess : 1; + padding : 1; + HasDarwinID : 1; + RunAsUser : 1; + HasExpIcon : 1; + NoPidlAlias : 1; + padding : 1; + RunWithShimLayer : 1; + ForceNoLinkTrack : 1; + EnableTargetMetadata : 1; + DisableLinkPathTracking : 1; + DisableKnownFolderTracking : 1; + DisableKnownFolderAlias : 1; + AllowLinkToLink : 1; + UnaliasOnSave : 1; + PreferEnvironmentPath : 1; + KeepLocalIDListForUNCTarget : 1; + padding : 5; +}; + +bitfield FileAttributesFlags { + FILE_ATTRIBUTE_READONLY : 1; + FILE_ATTRIBUTE_HIDDEN : 1; + FILE_ATTRIBUTE_SYSTEM : 1; + padding : 1; + FILE_ATTRIBUTE_DIRECTORY : 1; + FILE_ATTRIBUTE_ARCHIVE : 1; + padding : 1; + FILE_ATTRIBUTE_NORMAL : 1; + FILE_ATTRIBUTE_TEMPORARY : 1; + FILE_ATTRIBUTE_SPARSE_FILE : 1; + FILE_ATTRIBUTE_REPARSE_POINT : 1; + FILE_ATTRIBUTE_COMPRESSED : 1; + FILE_ATTRIBUTE_OFFLINE : 1; + FILE_ATTRIBUTE_NOT_CONTENT_INDEXED : 1; + FILE_ATTRIBUTE_ENCRYPTED : 1; + padding : 17; +}; + +bitfield ModifierKeys { + HOTKEYF_SHIFT : 1; + HOTKEYF_CONTROL : 1; + HOTKEYF_ALT : 1; + padding : 5; +}; + +enum Keys : u8 { + KEY_NONE = 0x00, + KEY_0 = 0x30, + KEY_1 = 0x31, + KEY_2 = 0x32, + KEY_3 = 0x33, + KEY_4 = 0x34, + KEY_5 = 0x35, + KEY_6 = 0x36, + KEY_7 = 0x37, + KEY_8 = 0x38, + KEY_9 = 0x39, + KEY_A = 0x41, + KEY_B = 0x42, + KEY_C = 0x43, + KEY_D = 0x44, + KEY_E = 0x45, + KEY_F = 0x46, + KEY_G = 0x47, + KEY_H = 0x48, + KEY_I = 0x49, + KEY_J = 0x4A, + KEY_K = 0x4B, + KEY_L = 0x4C, + KEY_M = 0x4D, + KEY_N = 0x4E, + KEY_O = 0x4F, + KEY_P = 0x50, + KEY_Q = 0x51, + KEY_R = 0x52, + KEY_S = 0x53, + KEY_T = 0x54, + KEY_U = 0x55, + KEY_V = 0x56, + KEY_W = 0x57, + KEY_X = 0x58, + KEY_Y = 0x59, + KEY_Z = 0x5A, + + VK_F1 = 0x70, + VK_F2 = 0x71, + VK_F3 = 0x72, + VK_F4 = 0x73, + VK_F5 = 0x74, + VK_F6 = 0x75, + VK_F7 = 0x76, + VK_F8 = 0x77, + VK_F9 = 0x78, + VK_F10 = 0x79, + VK_F11 = 0x7A, + VK_F12 = 0x7B, + VK_F13 = 0x7C, + VK_F14 = 0x7D, + VK_F15 = 0x7E, + VK_F16 = 0x7F, + VK_F17 = 0x80, + VK_F18 = 0x81, + VK_F19 = 0x82, + VK_F20 = 0x83, + VK_F21 = 0x84, + VK_F22 = 0x85, + VK_F23 = 0x86, + VK_F24 = 0x87, + VK_NUMLOCK = 0x90, + VK_SCROLL = 0x91, +}; + +struct HotKeyFlags { + Keys Key; + ModifierKeys ModifierKeys; +}; + +struct FILETIME { + u32 dwLowDateTime; + u32 dwHighDateTime; +}; + +enum SHOWWINDOW_FLAGS : u32 { + SW_SHOWNORMAL = 0x00000001, + SW_SHOWMAXIMIZED = 0x00000003, + SW_SHOWMINNOACTIVE = 0x00000007 +}; + +struct ShellLinkHeader { + type::Size32 HeaderSize; + type::GUID LinkCLSID; + LinkFlags LinkFlags; + FileAttributesFlags FileAttributes; + FILETIME CreationTime, AccessTime, WriteTime; + type::Size32 FileSize; + u32 IconIndex; + SHOWWINDOW_FLAGS ShowCommand; + HotKeyFlags HotKey; + padding[2]; + padding[4]; + padding[4]; +}; + +struct ItemID { + type::Size16 ItemIDSize; + + if (ItemIDSize == 0x00) + break; + else + u8 Data[ItemIDSize - sizeof(ItemIDSize)]; +}; + +struct IDList { + ItemID ItemIDList[while(true)]; +}; + +struct LinkTargetIDList { + type::Size16 IDListSize; + IDList IDList[while($ < (addressof(IDListSize) + IDListSize))]; +}; + +bitfield LinkInfoFlags { + VolumeIDAndLocalBasePath : 1; + CommonNetworkRelativeLinkAndPathSuffix : 1; + padding : 30; +}; + +enum DriveType : u32 { + DRIVE_UNKNOWN = 0x00000000, + DRIVE_NO_ROOT_DIR = 0x00000001, + DRIVE_REMOVABLE = 0x00000002, + DRIVE_FIXED = 0x00000003, + DRIVE_REMOTE = 0x00000004, + DRIVE_CDROM = 0x00000005, + DRIVE_RAMDISK = 0x00000006 +}; + +struct VolumeID { + type::Size32 VolumeIDSize; + DriveType DriveType; + u32 DriveSerialNumber; + u32 VolumeLabelOffset; + if (VolumeLabelOffset == 0x14) + u32 VolumeLabelOffsetUnicode; + char Data[VolumeIDSize - ($ - addressof(this))]; +}; + +bitfield CommonNetworkRelativeLinkFlags { + ValidDevice : 1; + ValidNetType : 1; + padding : 30; +}; + +enum NetworkProviderType : u32 { + WNNC_NET_AVID = 0x001A0000, + WNNC_NET_DOCUSPACE = 0x001B0000, + WNNC_NET_MANGOSOFT = 0x001C0000, + WNNC_NET_SERNET = 0x001D0000, + WNNC_NET_RIVERFRONT1 = 0x001E0000, + WNNC_NET_RIVERFRONT2 = 0x001F0000, + WNNC_NET_DECORB = 0x00200000, + WNNC_NET_PROTSTOR = 0x00210000, + WNNC_NET_FJ_REDIR = 0x00220000, + WNNC_NET_DISTINCT = 0x00230000, + WNNC_NET_TWINS = 0x00240000, + WNNC_NET_RDR2SAMPLE = 0x00250000, + WNNC_NET_CSC = 0x00260000, + WNNC_NET_3IN1 = 0x00270000, + WNNC_NET_EXTENDNET = 0x00290000, + WNNC_NET_STAC = 0x002A0000, + WNNC_NET_FOXBAT = 0x002B0000, + WNNC_NET_YAHOO = 0x002C0000, + WNNC_NET_EXIFS = 0x002D0000, + WNNC_NET_DAV = 0x002E0000, + WNNC_NET_KNOWARE = 0x002F0000, + WNNC_NET_OBJECT_DIRE = 0x00300000, + WNNC_NET_MASFAX = 0x00310000, + WNNC_NET_HOB_NFS = 0x00320000, + WNNC_NET_SHIVA = 0x00330000, + WNNC_NET_IBMAL = 0x00340000, + WNNC_NET_LOCK = 0x00350000, + WNNC_NET_TERMSRV = 0x00360000, + WNNC_NET_SRT = 0x00370000, + WNNC_NET_QUINCY = 0x00380000, + WNNC_NET_OPENAFS = 0x00390000, + WNNC_NET_AVID1 = 0x003A0000, + WNNC_NET_DFS = 0x003B0000, + WNNC_NET_KWNP = 0x003C0000, + WNNC_NET_ZENWORKS = 0x003D0000, + WNNC_NET_DRIVEONWEB = 0x003E0000, + WNNC_NET_VMWARE = 0x003F0000, + WNNC_NET_RSFX = 0x00400000, + WNNC_NET_MFILES = 0x00410000, + WNNC_NET_MS_NFS = 0x00420000, + WNNC_NET_GOOGLE = 0x00430000 +}; + +struct CommonNetworkRelativeLink { + type::Size32 CommonNetworkRelativeLinkSize; + CommonNetworkRelativeLinkFlags CommonNetworkRelativeLinkFlags; + u32 NetNameOffset; + u32 DeviceNameOffset; + NetworkProviderType NetworkProviderType; + + if (NetNameOffset > 0x14) { + u32 NetNameOffsetUnicode; + u32 DeviceNameOffsetUnicode; + } + + char NetName[]; + char DeviceName[]; + + if (NetNameOffset > 0x14) { + char16 NetNameUnicode[]; + char16 DeviceNameUnicode[]; + } +}; + +struct LinkInfo { + type::Size32 LinkInfoSize; + type::Size32 LinkInfoHeaderSize; + LinkInfoFlags LinkInfoFlags; + u32 VolumeIDOffset; + u32 LocalBasePathOffset; + u32 CommonNetworkRelativeLinkOffset; + u32 CommonPathSuffixOffset; + + if (LinkInfoHeaderSize >= 0x24) { + u32 LocalBasePathOffsetUnicode; + u32 CommonPathSuffixOffsetUnicode; + } + + if (LinkInfoFlags.VolumeIDAndLocalBasePath) { + VolumeID VolumeID; + char LocalBasePath[]; + } + + if (LinkInfoFlags.CommonNetworkRelativeLinkAndPathSuffix) + CommonNetworkRelativeLink CommonNetworkRelativeLink; + + char CommonPathSuffix[]; + + if (LinkInfoHeaderSize >= 0x24) { + if (LinkInfoFlags.VolumeIDAndLocalBasePath) + char16 LocalBasePathUnicode[]; + char16 CommonPathSuffixUnicode[]; + } +}; + +struct String { + u16 CountCharacters; + char16 String[CountCharacters]; +}; + +struct StringData { + if (parent.ShellLinkHeader.LinkFlags.HasName) + String NAME_STRING; + if (parent.ShellLinkHeader.LinkFlags.HasRelativePath) + String RELATIVE_PATH; + if (parent.ShellLinkHeader.LinkFlags.HasWorkingDir) + String WORKING_DIR; + if (parent.ShellLinkHeader.LinkFlags.HasArguments) + String COMMAND_LINE_ARGUMENTS; + if (parent.ShellLinkHeader.LinkFlags.HasIconLocation) + String ICON_LOCATION; +}; + +bitfield FillAttributes { + FOREGROUND_BLUE : 1; + FOREGROUND_GREEN : 1; + FOREGROUND_RED : 1; + FOREGROUND_INTENSITY : 1; + + BACKGROUND_BLUE : 1; + BACKGROUND_GREEN : 1; + BACKGROUND_RED : 1; + BACKGROUND_INTENSITY : 1; + + padding : 8; +}; + +struct ConsoleDataBlock { + FillAttributes FillAttributes; + FillAttributes PopupFillAttributes; + u16 ScreenBufferSizeX, ScreenBufferSizeY; + u16 WindowSizeX, WindowSizeY; + u16 WindowOriginX, WindowOriginY; + padding[4]; + padding[4]; + u32 FontSize; + u32 FontFamily; + u32 FontWeight; + char16 FaceName[32]; + u32 CursorSize; + u32 FullScreen; + u32 QuickEdit; + u32 InsertMode; + u32 AutoPosition; + u32 HistoryBufferSize; + u32 NumberOfHistoryBuffers; + u32 HistoryNoDup; + u32 ColorTable[16]; +}; + +struct ConsoleFEDataBlock { + u32 CodePage; +}; + +struct DarwinDataBlock { + char DarwinDataAnsi[260]; + char16 DarwinDataUnicode[260]; +}; + +struct EnvironmentVariableDataBlock { + char TargetAnsi[260]; + char16 TargetUnicode[260]; +}; + +struct IconEnvironmentDataBlock { + char TargetAnsi[260]; + char16 TargetUnicode[260]; +}; + +struct KnownFolderDataBlock { + type::GUID KnownFolderID; + u32 Offset; +}; + +struct PropertyStoreDataBlock { + u8 Bytes[parent.BlockSize - sizeof(parent.BlockSize) - sizeof(parent.BlockSignature)]; + std::warning("PropertyStoreDataBlock is not yet implemented!"); +}; + +struct ShimDataBlock { + char16 LayerName[(parent.BlockSize - sizeof(parent.BlockSize) - sizeof(parent.BlockSignature)) / sizeof(char16)]; +}; + +struct SpecialFolderDataBlock { + u32 SpecialFolderID; + u32 Offset; +}; + +struct TrackerDataBlock { + type::Size32 Length; + u32 Version; + char MachineID[16]; + type::GUID Droid[2]; + type::GUID DroidBirth[2]; +}; + +struct VistaAndAboveIDListDataBlock { + IDList IDList; +}; + +struct ExtraDataBlock { + type::Size32 BlockSize; + + if (BlockSize < 0x04) + break; + else { + u32 BlockSignature; + + if (BlockSignature == 0xA000'0002) + ConsoleDataBlock CONSOLE_PROPS; + else if (BlockSignature == 0xA000'0004) + ConsoleFEDataBlock CONSOLE_FE_PROPS; + else if (BlockSignature == 0xA000'0006) + DarwinDataBlock DARWIN_PROPS; + else if (BlockSignature == 0xA000'0001) + EnvironmentVariableDataBlock ENVIRONMENT_PROPS; + else if (BlockSignature == 0xA000'0007) + IconEnvironmentDataBlock ICON_ENVIRONMENT_PROPS; + else if (BlockSignature == 0xA000'000B) + KnownFolderDataBlock KNOWN_FOLDER_PROPS; + else if (BlockSignature == 0xA000'0009) + PropertyStoreDataBlock PROPERTY_STORE_PROPS; + else if (BlockSignature == 0xA000'0008) + ShimDataBlock SHIM_PROPS; + else if (BlockSignature == 0xA000'0005) + SpecialFolderDataBlock SPECIAL_FOLDER_PROPS; + else if (BlockSignature == 0xA000'0003) + TrackerDataBlock TRACKER_PROPS; + else if (BlockSignature == 0xA000'000C) + VistaAndAboveIDListDataBlock VISTA_AND_ABOVE_IDLIST_PROPS; + } +}; + +struct ExtraData { + ExtraDataBlock ExtraDataBlock[while(true)]; +}; + +struct LNK { + ShellLinkHeader ShellLinkHeader; + if (ShellLinkHeader.LinkFlags.HasLinkTargetIDList) + LinkTargetIDList LinkTargetIDList; + if (ShellLinkHeader.LinkFlags.HasLinkInfo) + LinkInfo LinkInfo; + StringData StringData; + ExtraData ExtraData; +}; + +LNK lnk @ 0x00; diff --git a/patterns/macho.hexpat b/patterns/macho.hexpat index 8616be1..32862bc 100644 --- a/patterns/macho.hexpat +++ b/patterns/macho.hexpat @@ -1,383 +1,383 @@ -#pragma MIME application/x-mach-binary - -#include - -enum Magic : u32 { - _32BitMagic = 0xFEEDFACE, - _64BitMagic = 0xFEEDFACF -}; - -enum CpuType : u32 { - VAX = 1, - ROMP = 2, - BS32032 = 4, - BS32332 = 5, - MC680x0 = 6, - I386 = 7, - X86_64 = CpuType::I386 | 0x100'0000, - MIPS = 8, - NS32532 = 9, - HPPA = 11, - ARM = 12, - MC88000 = 13, - SPARC = 14, - I860 = be u32(15), - I860_LITTLE = 16, - RS6000 = 17, - MC980000 = 18, - POWERPC = 18, - POWERPC64 = CpuType::POWERPC | 0x100'0000, - VEO = 255 -}; - -enum SubCpuTypeVAX : u24 { - ALL = 0, - VAX780 = 1, - VAX785 = 2, - VAX750 = 3, - VAX730 = 4, - UVAXI = 5, - UVAXII = 6, - VAX8200 = 7, - VAX8500 = 8, - VAX8600 = 9, - VAX8650 = 10, - VAX8800 = 11, - UVAXIII = 12 -}; - -enum SubCpuTypeROMP : u24 { - ALL = 0, - PC = 1, - APC = 2, - _135 = 3 -}; - -enum SubCpuType32XXX : u24 { - ALL = 0, - MMAX_DPC = 1, - SQT = 2, - MMAX_APC_FPU = 3, - MMAX_APC_FPA = 4, - MMAX_XPC = 5 -}; - -enum SubCpuTypeI386 : u24 { - _386 = 3, - _486 = 4, - _486SX = SubCpuTypeI386::_486 + 128, - _586 = 5, - IntelPentium = 5 + (0 << 4), - IntelPentiumPro = 6 + (1 << 4), - IntelPentiumIIM3 = 6 + (3 << 4), - IntelPentiumIIM5 = 6 + (5 << 4), - IntelPentium4 = 10 + (0 << 4), -}; - -enum SubCpuTypeMips : u24 { - ALL = 0, - R2300 = 1, - R2600 = 2, - R2800 = 3, - R2000a = 4 -}; - -enum SubCpuType680x0 : u24 { - ALL = 1, - MC68030 = 1, - MC68040 = 2, - MC68030_Only = 3 -}; - -enum SubCpuTypeHPPA : u24 { - ALL = 0, - _7100 = 0, - _7100LC = 1 -}; - -enum SubCpuTypeARM : u24 { - ALL = 0, - A500_ARCH = 1, - A500 = 2, - A440 = 3, - M4 = 4, - V4T = 5, - V6 = 6, - V5TEJ = 7, - XSCALE = 8, - V7 = 9, - V7F = 10, /* Cortex A9 */ - V7S = 11, /* Swift */ - V7K = 12 /* Kirkwood40 */ -}; - -enum SubCpuTypeMC88000 : u24 { - ALL = 0, - MMAX_JPC = 1, - MC88100 = 1, - MC88110 = 2 -}; - -enum SubCpuTypeMC98000 : u24 { - ALL = 0, - MC98601 = 1 -}; - -enum SubCpuTypeI860 : u24 { - ALL = 0, - _860 = 1 -}; - -enum SubCpuTypeI860Little : u24 { - ALL = 0 ... 1 -}; - -enum SubCpuTypeRS6000 : u24 { - ALL = 0 ... 1 -}; - -enum SubCpuTypeSparc : u24 { - ALL = 0, - _260 = 1, - _110 = 2 -}; - -enum SubCpuTypePowerPC : u24 { - ALL = 0, - _601 = 1, - _602 = 2, - _603 = 3, - _603e = 4, - _603ev = 5, - _604 = 6, - _604e = 7, - _620 = 8, - _750 = 9, - _7400 = 10, - _7450 = 11, - _970 = 100 -}; - -enum SubCpuTypeVEO : u24 { - _1 = 1, - _2 = 2, - _3 = 3, - _4 = 4, - ALL = SubCpuTypeVEO::_2 -}; - -bitfield Capabilities { - padding : 7; - lib64 : 1; -} [[right_to_left]]; - -enum FileType : u32 { - Object = 1, - Execute = 2, - FVMLib = 3, - Core = 4, - Preload = 5, - DyLib = 6, - DyLinker = 7, - Bundle = 8, - DyLibStub = 9, - DSym = 10, - KExtBundle = 11, -}; - -bitfield Flags { - noUndefs : 1; - incrLink : 1; - dyldLink : 1; - binDatLoad : 1; - prebound : 1; - splitSegs : 1; - lazyInit : 1; - twoLevel : 1; - forceFlat : 1; - noMultiDefs : 1; - noFixPrebinding : 1; - prebindable : 1; - allModsBound : 1; - subSectionsViaSymbols : 1; - canonical : 1; - weakDefines : 1; - bindsToWeak : 1; - allowStackExecution : 1; - rootSafe : 1; - setuidSafe : 1; - noReexportedDylibs : 1; - pie : 1; - deadStrippableDylib : 1; - hasTlvDescriptors : 1; - noHeapExecution : 1; - appExtensionSafe : 1; - nlistOutOfSyncWithDyldinof : 1; - simSupport : 1; -} [[right_to_left]]; - -struct Header { - Magic magic; - CpuType cpuType; - if (cpuType == CpuType::VAX) SubCpuTypeVAX subCpuType; - else if (cpuType == CpuType::ROMP) SubCpuTypeROMP subCpuType; - else if (cpuType == CpuType::BS32032 || cpuType == CpuType::BS32332 || cpuType == CpuType::NS32532) SubCpuType32XXX subCpuType; - else if (cpuType == CpuType::I386 || cpuType == CpuType::X86_64) SubCpuTypeI386 subCpuType; - else if (cpuType == CpuType::MIPS) SubCpuTypeMips subCpuType; - else if (cpuType == CpuType::HPPA) SubCpuTypeHPPA subCpuType; - else if (cpuType == CpuType::ARM) SubCpuTypeARM subCpuType; - else if (cpuType == CpuType::MC88000) SubCpuTypeMC88000 subCpuType; - else if (cpuType == CpuType::MC98000) SubCpuTypeMC98000 subCpuType; - else if (cpuType == CpuType::I860 || cpuType == CpuType::I860_LITTLE) SubCpuTypeI860 subCpuType; - else if (cpuType == CpuType::SPARC) SubCpuTypeSparc subCpuType; - else if (cpuType == CpuType::POWERPC || cpuType == CpuType::POWERPC64) SubCpuTypePowerPC subCpuType; - else if (cpuType == CpuType::VEO) SubCpuTypeVEO subCpuType; - else u24 subCpuType; - Capabilities capabilities; - FileType fileType; - u32 numCommands; - type::Size sizeOfCommands; - Flags flags; - - if (magic == Magic::_64BitMagic) padding[sizeof(u32)]; -}; - -enum Command : u32 { - ReqDyLd = 0x8000'0000, - - Segment = 0x01, - SymTab = 0x02, - SymSeg = 0x03, - Thread = 0x04, - UnixThread = 0x05, - LoadFVMLib = 0x06, - IdFVMLib = 0x07, - Ident = 0x08, - FVMFile = 0x09, - PrePage = 0x0A, - DySymTab = 0x0B, - LoadDyLib = 0x0C, - IdDyLib = 0x0D, - LoadDyLinker = 0x0E, - IdDyLinker = 0x0F, - PreboundDyLib = 0x10, - Routines = 0x11, - SubFramework = 0x12, - SubUmbrella = 0x13, - SubClient = 0x14, - SubLibrary = 0x15, - TwoLevelHints = 0x16, - PrebindCksum = 0x17, - LoadWeakDyLib = 0x18 | Command::ReqDyLd, - Segment64 = 0x19, - Routines64 = 0x1A, - UUID = 0x1B, - RPath = 0x1C | 0x8000'0000, - CodeSignature = 0x1D, - SegmentSplitInfo = 0x1E, - ReExportDyLib = 0x1F | Command::ReqDyLd, - LazyLoadDyLib = 0x20, - EncryptionInfo = 0x21, - DyLdInfo = 0x22, - DyLdInfoOnly = 0x22 | Command::ReqDyLd, - LoadUpwardDyLib = 0x23 | Command::ReqDyLd, - VersionMinMacOSX = 0x24, - VersionMinIPhoneOS = 0x25, - FunctionStarts = 0x26, - DyLdEnvironment = 0x27, - Main = 0x28 | Command::ReqDyLd, - DataInCode = 0x29, - SourceVersion = 0x2A, - DyLibCodeSignDRS = 0x2B -}; - -struct CommandUUID { - u128 uuid; -}; - -struct Section { - char sectionName[16]; - char segmentName[16]; - u32 address; - type::Size size; - u32 offset; - u32 align; - u32 reloff; - u32 numRelocs; - u32 flags; - padding[8]; - - if (offset > 0) - u8 data[size] @ offset [[sealed]]; -}; - -struct CommandSegment { - char segmentName[16]; - u32 vmAddress; - type::Size vmSize; - u32 fileOffset; - type::Size fileSize; - u32 maxProtection; - u32 initProtection; - u32 numSections; - u32 flags; - - Section sections[numSections]; - - if (fileOffset > 0) - u8 data[fileSize] @ fileOffset [[sealed]]; -}; - -struct Section64 { - char sectionName[16]; - char segmentName[16]; - u64 address; - type::Size size; - u32 offset; - u32 align; - u32 reloff; - u32 numRelocs; - u32 flags; - padding[12]; - - if (offset > 0) - u8 data[size] @ offset [[sealed]]; -}; - -struct CommandSegment64 { - char segmentName[16]; - u64 vmAddress; - type::Size vmSize; - u64 fileOffset; - type::Size fileSize; - u32 maxProtection; - u32 initProtection; - u32 numSections; - u32 flags; - - Section64 sections[numSections]; - - if (fileOffset > 0) - u8 data[fileSize] @ fileOffset [[sealed]]; -}; - -struct LoadCommand { - Command command; - type::Size commandSize; - - if (command == Command::UUID) - CommandUUID data; - else if (command == Command::Segment) - CommandSegment data; - else if (command == Command::Segment64) - CommandSegment64 data; - else - u8 data[commandSize - 8] [[sealed]]; -}; - -struct MachO { - Header header; - LoadCommand loadCommands[header.numCommands]; -}; - +#pragma MIME application/x-mach-binary + +#include + +enum Magic : u32 { + _32BitMagic = 0xFEEDFACE, + _64BitMagic = 0xFEEDFACF +}; + +enum CpuType : u32 { + VAX = 1, + ROMP = 2, + BS32032 = 4, + BS32332 = 5, + MC680x0 = 6, + I386 = 7, + X86_64 = CpuType::I386 | 0x100'0000, + MIPS = 8, + NS32532 = 9, + HPPA = 11, + ARM = 12, + MC88000 = 13, + SPARC = 14, + I860 = be u32(15), + I860_LITTLE = 16, + RS6000 = 17, + MC980000 = 18, + POWERPC = 18, + POWERPC64 = CpuType::POWERPC | 0x100'0000, + VEO = 255 +}; + +enum SubCpuTypeVAX : u24 { + ALL = 0, + VAX780 = 1, + VAX785 = 2, + VAX750 = 3, + VAX730 = 4, + UVAXI = 5, + UVAXII = 6, + VAX8200 = 7, + VAX8500 = 8, + VAX8600 = 9, + VAX8650 = 10, + VAX8800 = 11, + UVAXIII = 12 +}; + +enum SubCpuTypeROMP : u24 { + ALL = 0, + PC = 1, + APC = 2, + _135 = 3 +}; + +enum SubCpuType32XXX : u24 { + ALL = 0, + MMAX_DPC = 1, + SQT = 2, + MMAX_APC_FPU = 3, + MMAX_APC_FPA = 4, + MMAX_XPC = 5 +}; + +enum SubCpuTypeI386 : u24 { + _386 = 3, + _486 = 4, + _486SX = SubCpuTypeI386::_486 + 128, + _586 = 5, + IntelPentium = 5 + (0 << 4), + IntelPentiumPro = 6 + (1 << 4), + IntelPentiumIIM3 = 6 + (3 << 4), + IntelPentiumIIM5 = 6 + (5 << 4), + IntelPentium4 = 10 + (0 << 4), +}; + +enum SubCpuTypeMips : u24 { + ALL = 0, + R2300 = 1, + R2600 = 2, + R2800 = 3, + R2000a = 4 +}; + +enum SubCpuType680x0 : u24 { + ALL = 1, + MC68030 = 1, + MC68040 = 2, + MC68030_Only = 3 +}; + +enum SubCpuTypeHPPA : u24 { + ALL = 0, + _7100 = 0, + _7100LC = 1 +}; + +enum SubCpuTypeARM : u24 { + ALL = 0, + A500_ARCH = 1, + A500 = 2, + A440 = 3, + M4 = 4, + V4T = 5, + V6 = 6, + V5TEJ = 7, + XSCALE = 8, + V7 = 9, + V7F = 10, /* Cortex A9 */ + V7S = 11, /* Swift */ + V7K = 12 /* Kirkwood40 */ +}; + +enum SubCpuTypeMC88000 : u24 { + ALL = 0, + MMAX_JPC = 1, + MC88100 = 1, + MC88110 = 2 +}; + +enum SubCpuTypeMC98000 : u24 { + ALL = 0, + MC98601 = 1 +}; + +enum SubCpuTypeI860 : u24 { + ALL = 0, + _860 = 1 +}; + +enum SubCpuTypeI860Little : u24 { + ALL = 0 ... 1 +}; + +enum SubCpuTypeRS6000 : u24 { + ALL = 0 ... 1 +}; + +enum SubCpuTypeSparc : u24 { + ALL = 0, + _260 = 1, + _110 = 2 +}; + +enum SubCpuTypePowerPC : u24 { + ALL = 0, + _601 = 1, + _602 = 2, + _603 = 3, + _603e = 4, + _603ev = 5, + _604 = 6, + _604e = 7, + _620 = 8, + _750 = 9, + _7400 = 10, + _7450 = 11, + _970 = 100 +}; + +enum SubCpuTypeVEO : u24 { + _1 = 1, + _2 = 2, + _3 = 3, + _4 = 4, + ALL = SubCpuTypeVEO::_2 +}; + +bitfield Capabilities { + padding : 7; + lib64 : 1; +}; + +enum FileType : u32 { + Object = 1, + Execute = 2, + FVMLib = 3, + Core = 4, + Preload = 5, + DyLib = 6, + DyLinker = 7, + Bundle = 8, + DyLibStub = 9, + DSym = 10, + KExtBundle = 11, +}; + +bitfield Flags { + noUndefs : 1; + incrLink : 1; + dyldLink : 1; + binDatLoad : 1; + prebound : 1; + splitSegs : 1; + lazyInit : 1; + twoLevel : 1; + forceFlat : 1; + noMultiDefs : 1; + noFixPrebinding : 1; + prebindable : 1; + allModsBound : 1; + subSectionsViaSymbols : 1; + canonical : 1; + weakDefines : 1; + bindsToWeak : 1; + allowStackExecution : 1; + rootSafe : 1; + setuidSafe : 1; + noReexportedDylibs : 1; + pie : 1; + deadStrippableDylib : 1; + hasTlvDescriptors : 1; + noHeapExecution : 1; + appExtensionSafe : 1; + nlistOutOfSyncWithDyldinof : 1; + simSupport : 1; +}; + +struct Header { + Magic magic; + CpuType cpuType; + if (cpuType == CpuType::VAX) SubCpuTypeVAX subCpuType; + else if (cpuType == CpuType::ROMP) SubCpuTypeROMP subCpuType; + else if (cpuType == CpuType::BS32032 || cpuType == CpuType::BS32332 || cpuType == CpuType::NS32532) SubCpuType32XXX subCpuType; + else if (cpuType == CpuType::I386 || cpuType == CpuType::X86_64) SubCpuTypeI386 subCpuType; + else if (cpuType == CpuType::MIPS) SubCpuTypeMips subCpuType; + else if (cpuType == CpuType::HPPA) SubCpuTypeHPPA subCpuType; + else if (cpuType == CpuType::ARM) SubCpuTypeARM subCpuType; + else if (cpuType == CpuType::MC88000) SubCpuTypeMC88000 subCpuType; + else if (cpuType == CpuType::MC98000) SubCpuTypeMC98000 subCpuType; + else if (cpuType == CpuType::I860 || cpuType == CpuType::I860_LITTLE) SubCpuTypeI860 subCpuType; + else if (cpuType == CpuType::SPARC) SubCpuTypeSparc subCpuType; + else if (cpuType == CpuType::POWERPC || cpuType == CpuType::POWERPC64) SubCpuTypePowerPC subCpuType; + else if (cpuType == CpuType::VEO) SubCpuTypeVEO subCpuType; + else u24 subCpuType; + Capabilities capabilities; + FileType fileType; + u32 numCommands; + type::Size sizeOfCommands; + Flags flags; + + if (magic == Magic::_64BitMagic) padding[sizeof(u32)]; +}; + +enum Command : u32 { + ReqDyLd = 0x8000'0000, + + Segment = 0x01, + SymTab = 0x02, + SymSeg = 0x03, + Thread = 0x04, + UnixThread = 0x05, + LoadFVMLib = 0x06, + IdFVMLib = 0x07, + Ident = 0x08, + FVMFile = 0x09, + PrePage = 0x0A, + DySymTab = 0x0B, + LoadDyLib = 0x0C, + IdDyLib = 0x0D, + LoadDyLinker = 0x0E, + IdDyLinker = 0x0F, + PreboundDyLib = 0x10, + Routines = 0x11, + SubFramework = 0x12, + SubUmbrella = 0x13, + SubClient = 0x14, + SubLibrary = 0x15, + TwoLevelHints = 0x16, + PrebindCksum = 0x17, + LoadWeakDyLib = 0x18 | Command::ReqDyLd, + Segment64 = 0x19, + Routines64 = 0x1A, + UUID = 0x1B, + RPath = 0x1C | 0x8000'0000, + CodeSignature = 0x1D, + SegmentSplitInfo = 0x1E, + ReExportDyLib = 0x1F | Command::ReqDyLd, + LazyLoadDyLib = 0x20, + EncryptionInfo = 0x21, + DyLdInfo = 0x22, + DyLdInfoOnly = 0x22 | Command::ReqDyLd, + LoadUpwardDyLib = 0x23 | Command::ReqDyLd, + VersionMinMacOSX = 0x24, + VersionMinIPhoneOS = 0x25, + FunctionStarts = 0x26, + DyLdEnvironment = 0x27, + Main = 0x28 | Command::ReqDyLd, + DataInCode = 0x29, + SourceVersion = 0x2A, + DyLibCodeSignDRS = 0x2B +}; + +struct CommandUUID { + u128 uuid; +}; + +struct Section { + char sectionName[16]; + char segmentName[16]; + u32 address; + type::Size size; + u32 offset; + u32 align; + u32 reloff; + u32 numRelocs; + u32 flags; + padding[8]; + + if (offset > 0) + u8 data[size] @ offset [[sealed]]; +}; + +struct CommandSegment { + char segmentName[16]; + u32 vmAddress; + type::Size vmSize; + u32 fileOffset; + type::Size fileSize; + u32 maxProtection; + u32 initProtection; + u32 numSections; + u32 flags; + + Section sections[numSections]; + + if (fileOffset > 0) + u8 data[fileSize] @ fileOffset [[sealed]]; +}; + +struct Section64 { + char sectionName[16]; + char segmentName[16]; + u64 address; + type::Size size; + u32 offset; + u32 align; + u32 reloff; + u32 numRelocs; + u32 flags; + padding[12]; + + if (offset > 0) + u8 data[size] @ offset [[sealed]]; +}; + +struct CommandSegment64 { + char segmentName[16]; + u64 vmAddress; + type::Size vmSize; + u64 fileOffset; + type::Size fileSize; + u32 maxProtection; + u32 initProtection; + u32 numSections; + u32 flags; + + Section64 sections[numSections]; + + if (fileOffset > 0) + u8 data[fileSize] @ fileOffset [[sealed]]; +}; + +struct LoadCommand { + Command command; + type::Size commandSize; + + if (command == Command::UUID) + CommandUUID data; + else if (command == Command::Segment) + CommandSegment data; + else if (command == Command::Segment64) + CommandSegment64 data; + else + u8 data[commandSize - 8] [[sealed]]; +}; + +struct MachO { + Header header; + LoadCommand loadCommands[header.numCommands]; +}; + MachO macho @ 0x00; \ No newline at end of file diff --git a/patterns/minidump.hexpat b/patterns/minidump.hexpat index 042187a..9535b0a 100644 --- a/patterns/minidump.hexpat +++ b/patterns/minidump.hexpat @@ -1,423 +1,423 @@ -#pragma MIME application/x-dmp - -#include -#include -#include - -using RVA = ULONG32; -using RVA64 = ULONG64; - -enum MINIDUMP_STREAM_TYPE : ULONG32 { - UnusedStream = 0, - ReservedStream0 = 1, - ReservedStream1 = 2, - ThreadListStream = 3, - ModuleListStream = 4, - MemoryListStream = 5, - ExceptionStream = 6, - SystemInfoStream = 7, - ThreadExListStream = 8, - Memory64ListStream = 9, - CommentStreamA = 10, - CommentStreamW = 11, - HandleDataStream = 12, - FunctionTableStream = 13, - UnloadedModuleListStream = 14, - MiscInfoStream = 15, - MemoryInfoListStream = 16, - ThreadInfoListStream = 17, - HandleOperationListStream = 18, - TokenStream = 19, - JavaScriptDataStream = 20, - SystemMemoryInfoStream = 21, - ProcessVmCountersStream = 22, - IptTraceStream = 23, - ThreadNamesStream = 24, - ceStreamNull = 0x8000, - ceStreamSystemInfo = 0x8001, - ceStreamException = 0x8002, - ceStreamModuleList = 0x8003, - ceStreamProcessList = 0x8004, - ceStreamThreadList = 0x8005, - ceStreamThreadContextList = 0x8006, - ceStreamThreadCallStackList = 0x8007, - ceStreamMemoryVirtualList = 0x8008, - ceStreamMemoryPhysicalList = 0x8009, - ceStreamBucketParameters = 0x800A, - ceStreamProcessModuleMap = 0x800B, - ceStreamDiagnosisList = 0x800C, - LastReservedStream = 0xFFFF -}; - -struct MINIDUMP_LOCATION_DESCRIPTOR { - type::Size32 DataSize; - RVA Rva; -}; - -struct MINIDUMP_MEMORY_DESCRIPTOR { - ULONG64 StartOfMemoryRange; - MINIDUMP_LOCATION_DESCRIPTOR Memory; -}; - -struct MINIDUMP_THREAD { - ULONG32 ThreadId; - ULONG32 SuspendCount; - ULONG32 PriorityClass; - ULONG32 Priority; - ULONG64 Teb; - MINIDUMP_MEMORY_DESCRIPTOR Stack; - MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; -}; - -struct MINIDUMP_THREAD_LIST { - ULONG32 NumberOfThreads; - MINIDUMP_THREAD Threads[NumberOfThreads]; -}; - -struct VS_FIXEDFILEINFO { - DWORD dwSignature; - DWORD dwStrucVersion; - DWORD dwFileVersionMS; - DWORD dwFileVersionLS; - DWORD dwProductVersionMS; - DWORD dwProductVersionLS; - DWORD dwFileFlagsMask; - DWORD dwFileFlags; - DWORD dwFileOS; - DWORD dwFileType; - DWORD dwFileSubtype; - DWORD dwFileDateMS; - DWORD dwFileDateLS; -}; - -struct MINIDUMP_MODULE { - ULONG64 BaseOfImage; - type::Size32 SizeOfImage; - ULONG32 CheckSum; - type::time32_t TimeDateStamp; - RVA ModuleNameRva; - VS_FIXEDFILEINFO VersionInfo; - MINIDUMP_LOCATION_DESCRIPTOR CvRecord; - MINIDUMP_LOCATION_DESCRIPTOR MiscRecord; - ULONG64 Reserved0; - ULONG64 Reserved1; - - char16 ModuleName[] @ ModuleNameRva + 4 [[hidden]]; -} [[format("format_module")]]; - -fn format_module(ref MINIDUMP_MODULE module) { - return module.ModuleName; -}; - -struct MINIDUMP_MODULE_LIST { - ULONG32 NumberOfModules; - MINIDUMP_MODULE Modules[NumberOfModules]; -}; - -struct MINIDUMP_MEMORY_LIST { - ULONG32 NumberOfMemoryRanges; - MINIDUMP_MEMORY_DESCRIPTOR MemoryRanges[NumberOfMemoryRanges]; -}; - -struct MINIDUMP_EXCEPTION { - ULONG32 ExceptionCode; - ULONG32 ExceptionFlags; - ULONG64 ExceptionRecord; - ULONG64 ExceptionAddress; - ULONG32 NumberParameters; - padding[4]; - ULONG64 ExceptionInformation[15]; -}; - -struct MINIDUMP_EXCEPTION_STREAM { - ULONG32 ThreadId; - padding[4]; - MINIDUMP_EXCEPTION ExceptionRecord; - MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; -}; - -struct CPU_INFORMATION { - ULONG32 VendorId[3]; - ULONG32 VersionInformation; - ULONG32 FeatureInformation; - ULONG32 AMDExtendedCpuFeatures; -}; - -struct MINIDUMP_SYSTEM_INFO { - USHORT ProcessorArchitecture; - USHORT ProcessorLevel; - USHORT ProcessorRevision; - UCHAR NumberOfProcessors; - UCHAR ProductType; - ULONG32 MajorVersion; - ULONG32 MinorVersion; - ULONG32 BuildNumber; - ULONG32 PlatformId; - RVA CSDVersionRva; - USHORT SuiteMask; - USHORT Reserved; - CPU_INFORMATION Cpu; -}; - -struct MINIDUMP_THREAD_EX { - ULONG32 ThreadId; - ULONG32 SuspendCount; - ULONG32 PriorityClass; - ULONG32 Priority; - ULONG64 Teb; - MINIDUMP_MEMORY_DESCRIPTOR Stack; - MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; - MINIDUMP_MEMORY_DESCRIPTOR BackingStore; -}; - -struct MINIDUMP_THREAD_EX_LIST { - ULONG32 NumberOfThreads; - MINIDUMP_THREAD_EX Threads[NumberOfThreads]; -}; - -struct MINIDUMP_MEMORY_DESCRIPTOR64 { - ULONG64 StartOfMemoryRange; - type::Size64 DataSize; -}; - -struct MINIDUMP_MEMORY64_LIST { - ULONG64 NumberOfMemoryRanges; - RVA64 BaseRva; - MINIDUMP_MEMORY_DESCRIPTOR64 MemoryRanges[NumberOfMemoryRanges]; -}; - -struct MINIDUMP_HANDLE_DESCRIPTOR { - ULONG64 Handle; - RVA TypeNameRva; - RVA ObjectNameRva; - ULONG32 Attributes; - ULONG32 GrantedAccess; - ULONG32 HandleCount; - ULONG32 PointerCount; -}; - -struct MINIDUMP_HANDLE_DESCRIPTOR_2 { - ULONG64 Handle; - RVA TypeNameRva; - RVA ObjectNameRva; - ULONG32 Attributes; - ULONG32 GrantedAccess; - ULONG32 HandleCount; - ULONG32 PointerCount; - RVA ObjectInfoRva; - ULONG32 Reserved0; -}; - -struct MINIDUMP_HANDLE_DATA_STREAM { - ULONG32 SizeOfHeader; - ULONG32 SizeOfDescriptor; - ULONG32 NumberOfDescriptors; - ULONG32 Reserved; - - if (SizeOfDescriptor == 32) - MINIDUMP_HANDLE_DESCRIPTOR HandleDescriptors[NumberOfDescriptors]; - else if (SizeOfDescriptor == 40) - MINIDUMP_HANDLE_DESCRIPTOR_2 HandleDescriptors[NumberOfDescriptors]; -}; - -struct MINIDUMP_FUNCTION_TABLE_DESCRIPTOR { - ULONG64 MinimumAddress; - ULONG64 MaximumAddress; - ULONG64 BaseAddress; - ULONG32 EntryCount; - type::Size32 SizeOfAlignPad; -}; - -struct MINIDUMP_FUNCTION_TABLE_STREAM { - type::Size32 SizeOfHeader; - type::Size32 SizeOfDescriptor; - type::Size32 SizeOfNativeDescriptor; - type::Size32 SizeOfFunctionEntry; - ULONG32 NumberOfDescriptors; - ULONG32 SizeOfAlignPad; - - MINIDUMP_FUNCTION_TABLE_DESCRIPTOR FunctionDescriptors[NumberOfDescriptors]; -}; - -struct MINIDUMP_UNLOADED_MODULE { - ULONG64 BaseOfImage; - type::Size32 SizeOfImage; - ULONG32 CheckSum; - ULONG32 TimeDateStamp; - RVA ModuleNameRva; - - char16 ModuleName[] @ ModuleNameRva + 4 [[hidden]]; -} [[format("format_unloaded_module")]]; - -fn format_unloaded_module(ref MINIDUMP_UNLOADED_MODULE module) { - return module.ModuleName; -}; - -struct MINIDUMP_UNLOADED_MODULE_LIST { - ULONG32 SizeOfHeader; - ULONG32 SizeOfEntry; - ULONG32 NumberOfEntries; - - if (SizeOfHeader > 12) - padding[header.SizeOfHeader - 12]; - - MINIDUMP_UNLOADED_MODULE Modules[NumberOfEntries]; -}; - -struct MINIDUMP_MISC_INFO { - ULONG32 SizeOfInfo; - ULONG32 Flags1; - ULONG32 ProcessId; - ULONG32 ProcessCreateTime; - ULONG32 ProcessUserTime; - ULONG32 ProcessKernelTime; - - if (SizeOfInfo > 24) { - ULONG32 ProcessorMaxMhz; - ULONG32 ProcessorCurrentMhz; - ULONG32 ProcessorMhzLimit; - ULONG32 ProcessorMaxIdleState; - ULONG32 ProcessorCurrentIdleState; - } -}; - -struct MINIDUMP_MEMORY_INFO { - ULONG64 BaseAddress; - ULONG64 AllocationBase; - ULONG32 AllocationProtect; - padding[4]; - type::Size64 RegionSize; - ULONG32 State; - ULONG32 Protect; - ULONG32 Type; - padding[4]; -}; - -struct MINIDUMP_MEMORY_INFO_LIST { - ULONG SizeOfHeader; - ULONG SizeOfEntry; - ULONG64 NumberOfEntries; - - if (SizeOfHeader > 16) - padding[SizeOfHeader - 16]; - - MINIDUMP_MEMORY_INFO Info[NumberOfEntries]; -}; - -struct MINIDUMP_THREAD_INFO { - ULONG32 ThreadId; - ULONG32 DumpFlags; - ULONG32 DumpError; - ULONG32 ExitStatus; - ULONG64 CreateTime; - ULONG64 ExitTime; - ULONG64 KernelTime; - ULONG64 UserTime; - ULONG64 StartAddress; - ULONG64 Affinity; -}; - -struct MINIDUMP_THREAD_INFO_LIST { - ULONG SizeOfHeader; - ULONG SizeOfEntry; - ULONG NumberOfEntries; - - if (SizeOfHeader > 12) - padding[SizeOfHeader - 12]; - - MINIDUMP_THREAD_INFO Info[NumberOfEntries]; -}; - -struct MINIDUMP_HANDLE_OPERATION_LIST { - ULONG32 SizeOfHeader; - ULONG32 SizeOfEntry; - ULONG32 NumberOfEntries; - ULONG32 Reserved; -}; - -struct MINIDUMP_DIRECTORY { - MINIDUMP_STREAM_TYPE StreamType; - MINIDUMP_LOCATION_DESCRIPTOR Location; - - if (StreamType == MINIDUMP_STREAM_TYPE::ThreadListStream) - MINIDUMP_THREAD_LIST ThreadList @ Location.Rva; - else if (StreamType == MINIDUMP_STREAM_TYPE::ModuleListStream) - MINIDUMP_MODULE_LIST ModuleList @ Location.Rva; - else if (StreamType == MINIDUMP_STREAM_TYPE::MemoryListStream) - MINIDUMP_MEMORY_LIST MemoryList @ Location.Rva; - else if (StreamType == MINIDUMP_STREAM_TYPE::ExceptionStream) - MINIDUMP_EXCEPTION_STREAM ExceptionInfo @ Location.Rva; - else if (StreamType == MINIDUMP_STREAM_TYPE::SystemInfoStream) - MINIDUMP_SYSTEM_INFO SystemInfo @ Location.Rva; - else if (StreamType == MINIDUMP_STREAM_TYPE::ThreadExListStream) - MINIDUMP_THREAD_EX_LIST ThreadExList @ Location.Rva; - else if (StreamType == MINIDUMP_STREAM_TYPE::Memory64ListStream) - MINIDUMP_MEMORY64_LIST Mem64List @ Location.Rva; - else if (StreamType == MINIDUMP_STREAM_TYPE::CommentStreamA) - char Comment[] @ Location.Rva; - else if (StreamType == MINIDUMP_STREAM_TYPE::CommentStreamW) - char16 Comment[] @ Location.Rva; - else if (StreamType == MINIDUMP_STREAM_TYPE::HandleDataStream) - MINIDUMP_HANDLE_DATA_STREAM HandleData @ Location.Rva; - else if (StreamType == MINIDUMP_STREAM_TYPE::FunctionTableStream) - MINIDUMP_FUNCTION_TABLE_STREAM FunctionTable @ Location.Rva; - else if (StreamType == MINIDUMP_STREAM_TYPE::UnloadedModuleListStream) - MINIDUMP_UNLOADED_MODULE_LIST UnloadModuleList @ Location.Rva; - else if (StreamType == MINIDUMP_STREAM_TYPE::MiscInfoStream) - MINIDUMP_MISC_INFO MiscInfo @ Location.Rva; - else if (StreamType == MINIDUMP_STREAM_TYPE::MemoryInfoListStream) - MINIDUMP_MEMORY_INFO_LIST MemInfoList @ Location.Rva; - else if (StreamType == MINIDUMP_STREAM_TYPE::ThreadInfoListStream) - MINIDUMP_THREAD_INFO_LIST ThreadInfoList @ Location.Rva; - else if (StreamType == MINIDUMP_STREAM_TYPE::HandleOperationListStream) - MINIDUMP_HANDLE_OPERATION_LIST HandleOperList @ Location.Rva; -}; - -bitfield MINIDUMP_TYPE { - MiniDumpWithDataSegs : 1; - MiniDumpWithFullMemory : 1; - MiniDumpWithHandleData : 1; - MiniDumpFilterMemory : 1; - MiniDumpScanMemory : 1; - MiniDumpWithUnloadedModules : 1; - MiniDumpWithIndirectlyReferencedMemory : 1; - MiniDumpFilterModulePaths : 1; - MiniDumpWithProcessThreadData : 1; - MiniDumpWithPrivateReadWriteMemory : 1; - MiniDumpWithoutOptionalData : 1; - MiniDumpWithFullMemoryInfo : 1; - MiniDumpWithThreadInfo : 1; - MiniDumpWithCodeSegs : 1; - MiniDumpWithoutAuxiliaryState : 1; - MiniDumpWithFullAuxiliaryState : 1; - MiniDumpWithPrivateWriteCopyMemory : 1; - MiniDumpIgnoreInaccessibleMemory : 1; - MiniDumpWithTokenInformation : 1; - MiniDumpWithModuleHeaders : 1; - MiniDumpFilterTriage : 1; - MiniDumpWithAvxXStateContext : 1; - MiniDumpWithIptTrace : 1; - MiniDumpScanInaccessiblePartialPages : 1; - padding : 40; -} [[right_to_left]]; - -struct MINIDUMP_HEADER { - char Signature[4]; - ULONG32 Version; - ULONG32 NumberOfStreams; - RVA StreamDirectoryRva; - ULONG32 Checksum; - type::time32_t TimeDateStamp; - MINIDUMP_TYPE Flags; -}; - -struct MINIDUMP { - MINIDUMP_HEADER Header; - MINIDUMP_DIRECTORY Streams[Header.NumberOfStreams] [[format_entries("format_stream")]]; -}; - -fn format_stream(ref MINIDUMP_DIRECTORY stream) { - return stream.StreamType; -}; - -MINIDUMP MiniDump @ 0x00; +#pragma MIME application/x-dmp + +#include +#include +#include + +using RVA = ULONG32; +using RVA64 = ULONG64; + +enum MINIDUMP_STREAM_TYPE : ULONG32 { + UnusedStream = 0, + ReservedStream0 = 1, + ReservedStream1 = 2, + ThreadListStream = 3, + ModuleListStream = 4, + MemoryListStream = 5, + ExceptionStream = 6, + SystemInfoStream = 7, + ThreadExListStream = 8, + Memory64ListStream = 9, + CommentStreamA = 10, + CommentStreamW = 11, + HandleDataStream = 12, + FunctionTableStream = 13, + UnloadedModuleListStream = 14, + MiscInfoStream = 15, + MemoryInfoListStream = 16, + ThreadInfoListStream = 17, + HandleOperationListStream = 18, + TokenStream = 19, + JavaScriptDataStream = 20, + SystemMemoryInfoStream = 21, + ProcessVmCountersStream = 22, + IptTraceStream = 23, + ThreadNamesStream = 24, + ceStreamNull = 0x8000, + ceStreamSystemInfo = 0x8001, + ceStreamException = 0x8002, + ceStreamModuleList = 0x8003, + ceStreamProcessList = 0x8004, + ceStreamThreadList = 0x8005, + ceStreamThreadContextList = 0x8006, + ceStreamThreadCallStackList = 0x8007, + ceStreamMemoryVirtualList = 0x8008, + ceStreamMemoryPhysicalList = 0x8009, + ceStreamBucketParameters = 0x800A, + ceStreamProcessModuleMap = 0x800B, + ceStreamDiagnosisList = 0x800C, + LastReservedStream = 0xFFFF +}; + +struct MINIDUMP_LOCATION_DESCRIPTOR { + type::Size32 DataSize; + RVA Rva; +}; + +struct MINIDUMP_MEMORY_DESCRIPTOR { + ULONG64 StartOfMemoryRange; + MINIDUMP_LOCATION_DESCRIPTOR Memory; +}; + +struct MINIDUMP_THREAD { + ULONG32 ThreadId; + ULONG32 SuspendCount; + ULONG32 PriorityClass; + ULONG32 Priority; + ULONG64 Teb; + MINIDUMP_MEMORY_DESCRIPTOR Stack; + MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; +}; + +struct MINIDUMP_THREAD_LIST { + ULONG32 NumberOfThreads; + MINIDUMP_THREAD Threads[NumberOfThreads]; +}; + +struct VS_FIXEDFILEINFO { + DWORD dwSignature; + DWORD dwStrucVersion; + DWORD dwFileVersionMS; + DWORD dwFileVersionLS; + DWORD dwProductVersionMS; + DWORD dwProductVersionLS; + DWORD dwFileFlagsMask; + DWORD dwFileFlags; + DWORD dwFileOS; + DWORD dwFileType; + DWORD dwFileSubtype; + DWORD dwFileDateMS; + DWORD dwFileDateLS; +}; + +struct MINIDUMP_MODULE { + ULONG64 BaseOfImage; + type::Size32 SizeOfImage; + ULONG32 CheckSum; + type::time32_t TimeDateStamp; + RVA ModuleNameRva; + VS_FIXEDFILEINFO VersionInfo; + MINIDUMP_LOCATION_DESCRIPTOR CvRecord; + MINIDUMP_LOCATION_DESCRIPTOR MiscRecord; + ULONG64 Reserved0; + ULONG64 Reserved1; + + char16 ModuleName[] @ ModuleNameRva + 4 [[hidden]]; +} [[format("format_module")]]; + +fn format_module(ref MINIDUMP_MODULE module) { + return module.ModuleName; +}; + +struct MINIDUMP_MODULE_LIST { + ULONG32 NumberOfModules; + MINIDUMP_MODULE Modules[NumberOfModules]; +}; + +struct MINIDUMP_MEMORY_LIST { + ULONG32 NumberOfMemoryRanges; + MINIDUMP_MEMORY_DESCRIPTOR MemoryRanges[NumberOfMemoryRanges]; +}; + +struct MINIDUMP_EXCEPTION { + ULONG32 ExceptionCode; + ULONG32 ExceptionFlags; + ULONG64 ExceptionRecord; + ULONG64 ExceptionAddress; + ULONG32 NumberParameters; + padding[4]; + ULONG64 ExceptionInformation[15]; +}; + +struct MINIDUMP_EXCEPTION_STREAM { + ULONG32 ThreadId; + padding[4]; + MINIDUMP_EXCEPTION ExceptionRecord; + MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; +}; + +struct CPU_INFORMATION { + ULONG32 VendorId[3]; + ULONG32 VersionInformation; + ULONG32 FeatureInformation; + ULONG32 AMDExtendedCpuFeatures; +}; + +struct MINIDUMP_SYSTEM_INFO { + USHORT ProcessorArchitecture; + USHORT ProcessorLevel; + USHORT ProcessorRevision; + UCHAR NumberOfProcessors; + UCHAR ProductType; + ULONG32 MajorVersion; + ULONG32 MinorVersion; + ULONG32 BuildNumber; + ULONG32 PlatformId; + RVA CSDVersionRva; + USHORT SuiteMask; + USHORT Reserved; + CPU_INFORMATION Cpu; +}; + +struct MINIDUMP_THREAD_EX { + ULONG32 ThreadId; + ULONG32 SuspendCount; + ULONG32 PriorityClass; + ULONG32 Priority; + ULONG64 Teb; + MINIDUMP_MEMORY_DESCRIPTOR Stack; + MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; + MINIDUMP_MEMORY_DESCRIPTOR BackingStore; +}; + +struct MINIDUMP_THREAD_EX_LIST { + ULONG32 NumberOfThreads; + MINIDUMP_THREAD_EX Threads[NumberOfThreads]; +}; + +struct MINIDUMP_MEMORY_DESCRIPTOR64 { + ULONG64 StartOfMemoryRange; + type::Size64 DataSize; +}; + +struct MINIDUMP_MEMORY64_LIST { + ULONG64 NumberOfMemoryRanges; + RVA64 BaseRva; + MINIDUMP_MEMORY_DESCRIPTOR64 MemoryRanges[NumberOfMemoryRanges]; +}; + +struct MINIDUMP_HANDLE_DESCRIPTOR { + ULONG64 Handle; + RVA TypeNameRva; + RVA ObjectNameRva; + ULONG32 Attributes; + ULONG32 GrantedAccess; + ULONG32 HandleCount; + ULONG32 PointerCount; +}; + +struct MINIDUMP_HANDLE_DESCRIPTOR_2 { + ULONG64 Handle; + RVA TypeNameRva; + RVA ObjectNameRva; + ULONG32 Attributes; + ULONG32 GrantedAccess; + ULONG32 HandleCount; + ULONG32 PointerCount; + RVA ObjectInfoRva; + ULONG32 Reserved0; +}; + +struct MINIDUMP_HANDLE_DATA_STREAM { + ULONG32 SizeOfHeader; + ULONG32 SizeOfDescriptor; + ULONG32 NumberOfDescriptors; + ULONG32 Reserved; + + if (SizeOfDescriptor == 32) + MINIDUMP_HANDLE_DESCRIPTOR HandleDescriptors[NumberOfDescriptors]; + else if (SizeOfDescriptor == 40) + MINIDUMP_HANDLE_DESCRIPTOR_2 HandleDescriptors[NumberOfDescriptors]; +}; + +struct MINIDUMP_FUNCTION_TABLE_DESCRIPTOR { + ULONG64 MinimumAddress; + ULONG64 MaximumAddress; + ULONG64 BaseAddress; + ULONG32 EntryCount; + type::Size32 SizeOfAlignPad; +}; + +struct MINIDUMP_FUNCTION_TABLE_STREAM { + type::Size32 SizeOfHeader; + type::Size32 SizeOfDescriptor; + type::Size32 SizeOfNativeDescriptor; + type::Size32 SizeOfFunctionEntry; + ULONG32 NumberOfDescriptors; + ULONG32 SizeOfAlignPad; + + MINIDUMP_FUNCTION_TABLE_DESCRIPTOR FunctionDescriptors[NumberOfDescriptors]; +}; + +struct MINIDUMP_UNLOADED_MODULE { + ULONG64 BaseOfImage; + type::Size32 SizeOfImage; + ULONG32 CheckSum; + ULONG32 TimeDateStamp; + RVA ModuleNameRva; + + char16 ModuleName[] @ ModuleNameRva + 4 [[hidden]]; +} [[format("format_unloaded_module")]]; + +fn format_unloaded_module(ref MINIDUMP_UNLOADED_MODULE module) { + return module.ModuleName; +}; + +struct MINIDUMP_UNLOADED_MODULE_LIST { + ULONG32 SizeOfHeader; + ULONG32 SizeOfEntry; + ULONG32 NumberOfEntries; + + if (SizeOfHeader > 12) + padding[header.SizeOfHeader - 12]; + + MINIDUMP_UNLOADED_MODULE Modules[NumberOfEntries]; +}; + +struct MINIDUMP_MISC_INFO { + ULONG32 SizeOfInfo; + ULONG32 Flags1; + ULONG32 ProcessId; + ULONG32 ProcessCreateTime; + ULONG32 ProcessUserTime; + ULONG32 ProcessKernelTime; + + if (SizeOfInfo > 24) { + ULONG32 ProcessorMaxMhz; + ULONG32 ProcessorCurrentMhz; + ULONG32 ProcessorMhzLimit; + ULONG32 ProcessorMaxIdleState; + ULONG32 ProcessorCurrentIdleState; + } +}; + +struct MINIDUMP_MEMORY_INFO { + ULONG64 BaseAddress; + ULONG64 AllocationBase; + ULONG32 AllocationProtect; + padding[4]; + type::Size64 RegionSize; + ULONG32 State; + ULONG32 Protect; + ULONG32 Type; + padding[4]; +}; + +struct MINIDUMP_MEMORY_INFO_LIST { + ULONG SizeOfHeader; + ULONG SizeOfEntry; + ULONG64 NumberOfEntries; + + if (SizeOfHeader > 16) + padding[SizeOfHeader - 16]; + + MINIDUMP_MEMORY_INFO Info[NumberOfEntries]; +}; + +struct MINIDUMP_THREAD_INFO { + ULONG32 ThreadId; + ULONG32 DumpFlags; + ULONG32 DumpError; + ULONG32 ExitStatus; + ULONG64 CreateTime; + ULONG64 ExitTime; + ULONG64 KernelTime; + ULONG64 UserTime; + ULONG64 StartAddress; + ULONG64 Affinity; +}; + +struct MINIDUMP_THREAD_INFO_LIST { + ULONG SizeOfHeader; + ULONG SizeOfEntry; + ULONG NumberOfEntries; + + if (SizeOfHeader > 12) + padding[SizeOfHeader - 12]; + + MINIDUMP_THREAD_INFO Info[NumberOfEntries]; +}; + +struct MINIDUMP_HANDLE_OPERATION_LIST { + ULONG32 SizeOfHeader; + ULONG32 SizeOfEntry; + ULONG32 NumberOfEntries; + ULONG32 Reserved; +}; + +struct MINIDUMP_DIRECTORY { + MINIDUMP_STREAM_TYPE StreamType; + MINIDUMP_LOCATION_DESCRIPTOR Location; + + if (StreamType == MINIDUMP_STREAM_TYPE::ThreadListStream) + MINIDUMP_THREAD_LIST ThreadList @ Location.Rva; + else if (StreamType == MINIDUMP_STREAM_TYPE::ModuleListStream) + MINIDUMP_MODULE_LIST ModuleList @ Location.Rva; + else if (StreamType == MINIDUMP_STREAM_TYPE::MemoryListStream) + MINIDUMP_MEMORY_LIST MemoryList @ Location.Rva; + else if (StreamType == MINIDUMP_STREAM_TYPE::ExceptionStream) + MINIDUMP_EXCEPTION_STREAM ExceptionInfo @ Location.Rva; + else if (StreamType == MINIDUMP_STREAM_TYPE::SystemInfoStream) + MINIDUMP_SYSTEM_INFO SystemInfo @ Location.Rva; + else if (StreamType == MINIDUMP_STREAM_TYPE::ThreadExListStream) + MINIDUMP_THREAD_EX_LIST ThreadExList @ Location.Rva; + else if (StreamType == MINIDUMP_STREAM_TYPE::Memory64ListStream) + MINIDUMP_MEMORY64_LIST Mem64List @ Location.Rva; + else if (StreamType == MINIDUMP_STREAM_TYPE::CommentStreamA) + char Comment[] @ Location.Rva; + else if (StreamType == MINIDUMP_STREAM_TYPE::CommentStreamW) + char16 Comment[] @ Location.Rva; + else if (StreamType == MINIDUMP_STREAM_TYPE::HandleDataStream) + MINIDUMP_HANDLE_DATA_STREAM HandleData @ Location.Rva; + else if (StreamType == MINIDUMP_STREAM_TYPE::FunctionTableStream) + MINIDUMP_FUNCTION_TABLE_STREAM FunctionTable @ Location.Rva; + else if (StreamType == MINIDUMP_STREAM_TYPE::UnloadedModuleListStream) + MINIDUMP_UNLOADED_MODULE_LIST UnloadModuleList @ Location.Rva; + else if (StreamType == MINIDUMP_STREAM_TYPE::MiscInfoStream) + MINIDUMP_MISC_INFO MiscInfo @ Location.Rva; + else if (StreamType == MINIDUMP_STREAM_TYPE::MemoryInfoListStream) + MINIDUMP_MEMORY_INFO_LIST MemInfoList @ Location.Rva; + else if (StreamType == MINIDUMP_STREAM_TYPE::ThreadInfoListStream) + MINIDUMP_THREAD_INFO_LIST ThreadInfoList @ Location.Rva; + else if (StreamType == MINIDUMP_STREAM_TYPE::HandleOperationListStream) + MINIDUMP_HANDLE_OPERATION_LIST HandleOperList @ Location.Rva; +}; + +bitfield MINIDUMP_TYPE { + MiniDumpWithDataSegs : 1; + MiniDumpWithFullMemory : 1; + MiniDumpWithHandleData : 1; + MiniDumpFilterMemory : 1; + MiniDumpScanMemory : 1; + MiniDumpWithUnloadedModules : 1; + MiniDumpWithIndirectlyReferencedMemory : 1; + MiniDumpFilterModulePaths : 1; + MiniDumpWithProcessThreadData : 1; + MiniDumpWithPrivateReadWriteMemory : 1; + MiniDumpWithoutOptionalData : 1; + MiniDumpWithFullMemoryInfo : 1; + MiniDumpWithThreadInfo : 1; + MiniDumpWithCodeSegs : 1; + MiniDumpWithoutAuxiliaryState : 1; + MiniDumpWithFullAuxiliaryState : 1; + MiniDumpWithPrivateWriteCopyMemory : 1; + MiniDumpIgnoreInaccessibleMemory : 1; + MiniDumpWithTokenInformation : 1; + MiniDumpWithModuleHeaders : 1; + MiniDumpFilterTriage : 1; + MiniDumpWithAvxXStateContext : 1; + MiniDumpWithIptTrace : 1; + MiniDumpScanInaccessiblePartialPages : 1; + padding : 40; +}; + +struct MINIDUMP_HEADER { + char Signature[4]; + ULONG32 Version; + ULONG32 NumberOfStreams; + RVA StreamDirectoryRva; + ULONG32 Checksum; + type::time32_t TimeDateStamp; + MINIDUMP_TYPE Flags; +}; + +struct MINIDUMP { + MINIDUMP_HEADER Header; + MINIDUMP_DIRECTORY Streams[Header.NumberOfStreams] [[format_entries("format_stream")]]; +}; + +fn format_stream(ref MINIDUMP_DIRECTORY stream) { + return stream.StreamType; +}; + +MINIDUMP MiniDump @ 0x00; diff --git a/patterns/ne.hexpat b/patterns/ne.hexpat index 53ce444..6af270e 100644 --- a/patterns/ne.hexpat +++ b/patterns/ne.hexpat @@ -1,7 +1,5 @@ #include -#pragma bitfield_order right_to_left - struct DOSHeader { char signature[2]; u16 lastPageSize; @@ -186,7 +184,7 @@ bitfield SegmentTableFlags { containsRelocationInfo : 1; padding : 1; discardPriority : 4; -} [[right_to_left]]; +}; struct SegmentTable { u16 segmentDataPointer; diff --git a/patterns/ntag.hexpat b/patterns/ntag.hexpat index fef84ec..e69cca7 100644 --- a/patterns/ntag.hexpat +++ b/patterns/ntag.hexpat @@ -1,161 +1,165 @@ -bitfield AccessCapability { - Read : 4; - Write : 4; -} [[left_to_right]]; - -struct CapabilityContainer { - u8 magic; - u8 version; - u8 memorySize; - AccessCapability accessCapability; -}; - -bitfield NDEFFlags { - MB : 1; - ME : 1; - CF : 1; - SR : 1; - IL : 1; - TNF : 3; -} [[left_to_right]]; - -enum TNFType : u8 { - Empty = 0x00, - NFCForumWellKnownType = 0x01, - MediaType = 0x02, - AbsoluteURI = 0x03, - NFCForumExternalType = 0x04, - Unknown = 0x05, - Unchanged = 0x06, - Reserved = 0x07 -}; - -struct NDEF { - NDEFFlags flags; - u8 typeLength; - - if (flags.SR) - u8 payloadLength; - else - u32 payloadLength; - - if (flags.IL) - u8 idLength; - - char type[typeLength]; - - if (flags.IL) - u8 id[idLength]; - - u8 payload[payloadLength]; - - if (flags.ME) - break; -}; - -struct LockControl { - u8 dynamicLockByteOffset; - u8 numBits; - u8 pageControlInfo; -}; - -struct MemoryControl { - u8 reservedBytesOffset; - u8 numBytes; - u8 pageSize; -}; - -struct Length { - u8 byte [[hidden, no_unique_address]]; - if (byte == 0xFF) - u24 length; - else - u8 length; -} [[sealed, transform("transform_length"), format("transform_length")]]; - -fn transform_length(Length length) { - return length.length; -}; - -enum Tag : u8 { - NULL = 0x00, - LockControl = 0x01, - MemoryControl = 0x02, - NDEFMessage = 0x03, - Proprietary = 0xFD, - TerminatorTLV = 0xFE -}; - -struct TLV { - Tag tag; - if (tag == Tag::TerminatorTLV) { - break; - } else if (tag == Tag::NULL) { - // Empty - } else { - Length length; - - if (length > 0) { - if (tag == Tag::LockControl) { - LockControl lockControl; - } else if (tag == Tag::MemoryControl) { - LockControl lockControl; - } else if (tag == Tag::NDEFMessage) { - NDEF ndef[while(true)]; - } else { - u8 value[length]; - } - } - } -}; - -struct ManufacturerData { - u8 serial1[3]; - u8 checkByte0; - u8 serial2[4]; - u8 checkByte1; - u8 internal; - u16 lockBytes; -}; - -struct DynamicLockBytes { - u8 bytes[3]; - padding[1]; -}; - -bitfield MIRROR { - MIRROR_CONF : 2; - MIRROR_BYTE : 2; - padding : 1; - STRG_MOD_EN : 1; - padding : 2; -} [[left_to_right]]; - -bitfield ACCESS { - PROT : 1; - CFGLCK : 1; - padding : 1; - NFC_CNT_EN : 1; - NFC_CNT_PWD_PROT : 1; - AUTHLIM : 3; -}; - -struct Config { - MIRROR MIRROR; - u8 MIRROR_PAGE; - u8 AUTH0; - ACCESS ACCESS; - u32 PWD; - u16 PACK; -}; - -struct NTAG { - ManufacturerData manufacturerData; - CapabilityContainer cc; - TLV tlv[while(true)]; - padding[addressof(tlv) + cc.memorySize * 8 - sizeof(tlv)]; - DynamicLockBytes dynamicLockBytes; - Config config; -}; - -NTAG ntag @ 0x00; +#include + +using BitfieldOrder = std::core::BitfieldOrder; + +bitfield AccessCapability { + Read : 4; + Write : 4; +} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 8)]]; + +struct CapabilityContainer { + u8 magic; + u8 version; + u8 memorySize; + be AccessCapability accessCapability; +}; + +bitfield NDEFFlags { + MB : 1; + ME : 1; + CF : 1; + SR : 1; + IL : 1; + TNF : 3; +} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 8)]]; + +enum TNFType : u8 { + Empty = 0x00, + NFCForumWellKnownType = 0x01, + MediaType = 0x02, + AbsoluteURI = 0x03, + NFCForumExternalType = 0x04, + Unknown = 0x05, + Unchanged = 0x06, + Reserved = 0x07 +}; + +struct NDEF { + NDEFFlags flags; + u8 typeLength; + + if (flags.SR) + u8 payloadLength; + else + u32 payloadLength; + + if (flags.IL) + u8 idLength; + + char type[typeLength]; + + if (flags.IL) + u8 id[idLength]; + + u8 payload[payloadLength]; + + if (flags.ME) + break; +}; + +struct LockControl { + u8 dynamicLockByteOffset; + u8 numBits; + u8 pageControlInfo; +}; + +struct MemoryControl { + u8 reservedBytesOffset; + u8 numBytes; + u8 pageSize; +}; + +struct Length { + u8 byte [[hidden, no_unique_address]]; + if (byte == 0xFF) + u24 length; + else + u8 length; +} [[sealed, transform("transform_length"), format("transform_length")]]; + +fn transform_length(Length length) { + return length.length; +}; + +enum Tag : u8 { + NULL = 0x00, + LockControl = 0x01, + MemoryControl = 0x02, + NDEFMessage = 0x03, + Proprietary = 0xFD, + TerminatorTLV = 0xFE +}; + +struct TLV { + Tag tag; + if (tag == Tag::TerminatorTLV) { + break; + } else if (tag == Tag::NULL) { + // Empty + } else { + Length length; + + if (length > 0) { + if (tag == Tag::LockControl) { + LockControl lockControl; + } else if (tag == Tag::MemoryControl) { + LockControl lockControl; + } else if (tag == Tag::NDEFMessage) { + NDEF ndef[while(true)]; + } else { + u8 value[length]; + } + } + } +}; + +struct ManufacturerData { + u8 serial1[3]; + u8 checkByte0; + u8 serial2[4]; + u8 checkByte1; + u8 internal; + u16 lockBytes; +}; + +struct DynamicLockBytes { + u8 bytes[3]; + padding[1]; +}; + +bitfield MIRROR { + MIRROR_CONF : 2; + MIRROR_BYTE : 2; + padding : 1; + STRG_MOD_EN : 1; + padding : 2; +} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 8)]]; + +bitfield ACCESS { + PROT : 1; + CFGLCK : 1; + padding : 1; + NFC_CNT_EN : 1; + NFC_CNT_PWD_PROT : 1; + AUTHLIM : 3; +}; + +struct Config { + MIRROR MIRROR; + u8 MIRROR_PAGE; + u8 AUTH0; + ACCESS ACCESS; + u32 PWD; + u16 PACK; +}; + +struct NTAG { + ManufacturerData manufacturerData; + CapabilityContainer cc; + TLV tlv[while(true)]; + padding[addressof(tlv) + cc.memorySize * 8 - sizeof(tlv)]; + DynamicLockBytes dynamicLockBytes; + Config config; +}; + +NTAG ntag @ 0x00; diff --git a/patterns/pe.hexpat b/patterns/pe.hexpat index cdb9660..7e0edb5 100644 --- a/patterns/pe.hexpat +++ b/patterns/pe.hexpat @@ -1,6 +1,5 @@ #pragma MIME application/x-dosexec #pragma MIME application/x-msdownload -#pragma bitfield_order right_to_left #pragma pattern_limit 0x400000 #include @@ -378,7 +377,7 @@ fn architecture() { bitfield OrdinalFlagByte { flag : 1; padding : 7; -} [[left_to_right]]; +}; struct NameTableEntry { u16 hint; @@ -1278,4 +1277,4 @@ struct StringTable { StringTableString strings[while($ < addressof(this) + size)]; } [[inline]]; -StringTable stringTable[checkForDebugInformation] @ addressof(symbolTable) + sizeof(symbolTable); +StringTable stringTable[checkForDebugInformation] @ addressof(symbolTable) + sizeof(symbolTable); \ No newline at end of file diff --git a/patterns/protobuf.hexpat b/patterns/protobuf.hexpat index 492e530..b1292ae 100644 --- a/patterns/protobuf.hexpat +++ b/patterns/protobuf.hexpat @@ -1,66 +1,67 @@ -#include - -#include - -struct ZigZag32 { - u32 value; -} [[sealed, format("format_zigzag32")]]; - -fn format_zigzag32(ZigZag32 zigzag) { - return s32((s32(zigzag.value) << 1) ^ (s32(zigzag.value) >> 31)); -}; - -struct ZigZag64 { - u64 value; -} [[sealed, format("format_zigzag64")]]; - -fn format_zigzag64(ZigZag64 zigzag) { - return s64((s64(zigzag.value) << 1) ^ (s64(zigzag.value) >> 63)); -}; - -enum WireType : u8 { - Varint = 0, - _64Bit = 1, - LengthDelimited = 2, - StartGroup = 3, - EndGroup = 4, - _32Bit = 5 -}; - -bitfield Key { - field_number : 5; - wire_type : 3; -} [[left_to_right]]; - -union _64Bit { - u64 fixed64; - ZigZag64 sfixed64; - double dbl; -}; - -union _32Bit { - u32 fixed32; - ZigZag32 sfixed32; - float flt; -}; - -struct LengthDelimited { - type::LEB128 length; - char data[length]; -}; - - -struct Entry { - Key key; - - if (key.wire_type == WireType::Varint) - type::LEB128 value; - else if (key.wire_type == WireType::_64Bit) - _64Bit value; - else if (key.wire_type == WireType::LengthDelimited) - LengthDelimited value; - else if (key.wire_type == WireType::_32Bit) - _32Bit value; -}; - -Entry entries[while(!std::mem::eof())] @ 0x00; +#include +#include + +#include + +struct ZigZag32 { + u32 value; +} [[sealed, format("format_zigzag32")]]; + +fn format_zigzag32(ZigZag32 zigzag) { + return s32((s32(zigzag.value) << 1) ^ (s32(zigzag.value) >> 31)); +}; + +struct ZigZag64 { + u64 value; +} [[sealed, format("format_zigzag64")]]; + +fn format_zigzag64(ZigZag64 zigzag) { + return s64((s64(zigzag.value) << 1) ^ (s64(zigzag.value) >> 63)); +}; + +enum WireType : u8 { + Varint = 0, + _64Bit = 1, + LengthDelimited = 2, + StartGroup = 3, + EndGroup = 4, + _32Bit = 5 +}; + +bitfield Key { + field_number : 5; + wire_type : 3; +} [[bitfield_order(std::core::BitfieldOrder::MostToLeastSignificant, 8)]]; + +union _64Bit { + u64 fixed64; + ZigZag64 sfixed64; + double dbl; +}; + +union _32Bit { + u32 fixed32; + ZigZag32 sfixed32; + float flt; +}; + +struct LengthDelimited { + type::LEB128 length; + char data[length]; +}; + + +struct Entry { + Key key; + + if (key.wire_type == WireType::Varint) + type::LEB128 value; + else if (key.wire_type == WireType::_64Bit) + _64Bit value; + else if (key.wire_type == WireType::LengthDelimited) + LengthDelimited value; + else if (key.wire_type == WireType::_32Bit) + _32Bit value; +}; + +Entry entries[while(!std::mem::eof())] @ 0x00; diff --git a/patterns/qoi.hexpat b/patterns/qoi.hexpat index deb58ac..377ba31 100644 --- a/patterns/qoi.hexpat +++ b/patterns/qoi.hexpat @@ -1,6 +1,5 @@ #pragma MIME image/qoi #pragma endian big -#pragma bitfield_order left_to_right #include diff --git a/patterns/sit5.hexpat b/patterns/sit5.hexpat index b79216d..5c1b7e2 100644 --- a/patterns/sit5.hexpat +++ b/patterns/sit5.hexpat @@ -13,13 +13,13 @@ namespace v5 { folder : 1; encrypted : 1; padding : 5; - } [[left_to_right]]; + }; bitfield Flags2 { padding : 7; resource_fork : 1; padding : 8; - } [[left_to_right]]; + }; using MacOSHFSPlusDate = u32 [[format("v5::format_macos_date")]]; diff --git a/patterns/spirv.hexpat b/patterns/spirv.hexpat index 76d7221..909ecdc 100644 --- a/patterns/spirv.hexpat +++ b/patterns/spirv.hexpat @@ -1,3 +1,5 @@ +#include + enum GeneratorID : u16 { Khronos = 0, LunarG = 1, @@ -642,4 +644,4 @@ struct Instruction { Header header @ 0x00; // SPIR-V does not have any footer, increase number of instructions manually if you encounter a bigger shader -Instruction instructions[1024] @ 0x14; \ No newline at end of file +Instruction instructions[while (!std::mem::eof())] @ 0x14; \ No newline at end of file diff --git a/patterns/usb.hexpat b/patterns/usb.hexpat index e7f0bfd..8e45a88 100644 --- a/patterns/usb.hexpat +++ b/patterns/usb.hexpat @@ -1,269 +1,272 @@ -#include -#include -#include - -enum DescriptorType : u8 { - DeviceDescriptor = 0x01, - ConfigDescriptor = 0x02, - StringDescriptor = 0x03, - InterfaceDescriptor = 0x04, - EndpointDescriptor = 0x05, - DeviceQualifierDescriptor = 0x06, - OtherSpeedConfigurationDescriptor = 0x07, - InterfacePowerDescriptor = 0x08, - OTGDescriptor = 0x09, - DebugDescriptor = 0x0A, - InterfaceAssociationDescriptor = 0x0B, - - HIDDescriptor = 0x21, - ReportDescriptor = 0x22, - PhysicalDescriptor = 0x23 -}; - -enum InterfaceClass : u8 { - UseClassInformationInInterfaceDescriptors = 0x00, - Audio = 0x01, - CommunicationAndCDCControl = 0x02, - HID = 0x03, - Physical = 0x05, - Image = 0x06, - Printer = 0x07, - MassStorage = 0x08, - Hub = 0x09, - CDCData = 0x0A, - SmartCard = 0x0B, - ContentSecurity = 0x0C, - Video = 0x0E, - PersonalHealthcare = 0x0F, - AudioVideoDevice = 0x10, - BillboardDevice = 0x11, - USBTypeCBridge = 0x12, - I3CDevice = 0x3C, - DiagnosticDevice = 0xDC, - WirelessController = 0xE0, - Miscellaneous = 0xEF, - ApplicationSpecific = 0xFE, - VendorSpecific = 0xFF -}; - -enum CountryCode : u8 { - NotSupported = 0, - Arabic = 1, - Belgian = 2, - CanadianBilingual = 3, - CanadianFrench = 4, - CzechRepublic = 5, - Danish = 6, - Finnish = 7, - French = 8, - German = 9, - Greek = 10, - Hebrew = 11, - Hungary = 12, - International = 13, - Italian = 14, - JapanKatakana = 15, - Korean = 16, - LatinAmerican = 17, - Dutch = 18, - Norwegian = 19, - PersianFarsi = 20, - Polish = 21, - Portuguese = 22, - Russian = 23, - Slovakian = 24, - Spanish = 25, - Swedish = 26, - SwissFrench = 27, - SwissGerman = 28, - Switzerland = 29, - Taiwan = 30, - TurkishQ = 31, - EnglishUK = 32, - EnglishUS = 33, - Yugoslavian = 34, - TurkishF = 35, - Reserved = 36 ... 255 -}; - -enum HubInterfaceSubClass : u8 { - Hub = 0x00 -}; - -enum AudioVideoDeviceSubClass : u8 { - AVControlInterface = 0x01, - AVDataVideoStreamingInterface = 0x02, - AVDataAudioStreamingInterface = 0x03 -}; - -enum HubInterfaceProtocol : u8 { - FullSpeedHub = 0x00, - HiSpeedHubWithSingleTT = 0x01, - HiSpeedHubWithMultipleTTs = 0x02 -}; - -struct Ampere { - u8 amps; -} [[sealed, format("format_ampere")]]; - -fn format_ampere(Ampere ampere) { - return std::format("{} mA", ampere.amps * 2); -}; - -bitfield ConfigAttributes { - padding : 1; - SelfPowered : 1; - RemoteWakeup : 1; - padding : 5; -} [[left_to_right]]; - -struct BCD { - u8 bytes[Size]; -} [[sealed, format("format_bcd")]]; - -fn format_bcd(ref auto bcd) { - str result; - for (s8 i = sizeof(bcd.bytes) - 1, i >= 0, i -= 1) - result += std::format("{:X}.", bcd.bytes[i]); - - return std::string::substr(result, 0, std::string::length(result) - 1); -}; - -struct DeviceDescriptor { - BCD<2> bcdUSB; - InterfaceClass bDeviceClass; - if (bDeviceClass == InterfaceClass::Hub) { - HubInterfaceSubClass bDeviceSubClass; - if (bDeviceSubClass == HubInterfaceSubClass::Hub) - HubInterfaceProtocol bDeviceSubClass; - else - u8 bDeviceSubClass; - } else if (bDeviceClass == InterfaceClass::AudioVideoDevice) { - AudioVideoDeviceSubClass bDeviceSubClass; - u8 bDeviceSubClass; - } else { - u8 bDeviceSubClass; - } -}; - -struct ConfigDescriptor { - u16 wTotalLength; - u8 bNumInterfaces; - u8 bConfigurationValue; - u8 iConfiguration; - ConfigAttributes bmAttributes; - Ampere bMaxPower; -}; - -struct StringDescriptor { - char bString[parent.bLength - 2]; -}; - -struct InterfaceDescriptor { - u8 bInterfaceNumber; - u8 bAlternateSetting; - u8 bNumEndpoints; - - InterfaceClass bInterfaceClass; - if (bInterfaceClass == InterfaceClass::Hub) { - HubInterfaceSubClass bInterfaceSubClass; - if (bInterfaceSubClass == HubInterfaceSubClass::Hub) - HubInterfaceProtocol bInterfaceProtocol; - else - u8 bInterfaceProtocol; - } else if (bInterfaceClass == InterfaceClass::AudioVideoDevice) { - AudioVideoDeviceSubClass bInterfaceSubClass; - u8 bInterfaceProtocol; - } else { - u8 bInterfaceSubClass; - u8 bInterfaceProtocol; - } - - u8 iInterface; -}; - -enum EndpointDirection : u8 { - OUT = 0, - IN = 1 -}; - -fn format_direction(u8 value) { - EndpointDirection direction; - direction = value; - return direction; -}; - -bitfield EndpointAddress { - Direction : 1 [[format("format_direction")]]; - padding : 3; - EndpointNumber : 4; -} [[left_to_right]]; - -bitfield EndpointAttributes { - TransferType : 2; - SynchronizationType : 2; - UsageType : 2; -} [[right_to_left]]; - -struct EndpointDescriptor { - EndpointAddress bEndPointAddress; - EndpointAttributes bmAttributes; - u16 wMaxPacketSize; - u8 bInterval; -}; - -struct OtherSpeedConfigurationDescriptor { - ConfigDescriptor content [[inline]]; -}; - -struct DeviceQualifierDescriptor { - DeviceDescriptor deviceDescriptor [[inline]]; - u8 bMaxPacketSize0; - u8 bNumConfigurations; - padding[1]; -}; - -bitfield OTGAttributes { - SRPSupport : 1; - HNPSupport : 1; -} [[right_to_left]]; - -struct OTGDescriptor { - OTGAttributes bmAttributes; -}; - -struct HIDDescriptor { - BCD<2> bcdVersion; - CountryCode bCountryCode; - u8 bNumDescriptors; - DescriptorType bDescriptorType; - u16 wDescriptorLength; -}; - -struct USBDescriptor { - u8 bLength; - DescriptorType bDescriptorType; - - if (bDescriptorType == DescriptorType::DeviceDescriptor) - DeviceDescriptor deviceDescriptor [[inline]]; - else if (bDescriptorType == DescriptorType::ConfigDescriptor) - ConfigDescriptor configDescriptor [[inline]]; - else if (bDescriptorType == DescriptorType::StringDescriptor) - StringDescriptor stringDescriptor [[inline]]; - else if (bDescriptorType == DescriptorType::InterfaceDescriptor) - InterfaceDescriptor interfaceDescriptor [[inline]]; - else if (bDescriptorType == DescriptorType::EndpointDescriptor) - EndpointDescriptor endpointDescriptor [[inline]]; - else if (bDescriptorType == DescriptorType::OtherSpeedConfigurationDescriptor) - OtherSpeedConfigurationDescriptor otherSpeedConfigurationDescriptor [[inline]]; - else if (bDescriptorType == DescriptorType::DeviceQualifierDescriptor) - DeviceQualifierDescriptor deviceQualifierDescriptor [[inline]]; - else if (bDescriptorType == DescriptorType::OTGDescriptor) - OTGDescriptor otgDescriptor [[inline]]; - else if (bDescriptorType == DescriptorType::HIDDescriptor) - HIDDescriptor hidDescriptor [[inline]]; - - padding[bLength - ($ - addressof(this))]; -}; - +#include +#include +#include +#include + +using BitfieldOrder = std::core::BitfieldOrder; + +enum DescriptorType : u8 { + DeviceDescriptor = 0x01, + ConfigDescriptor = 0x02, + StringDescriptor = 0x03, + InterfaceDescriptor = 0x04, + EndpointDescriptor = 0x05, + DeviceQualifierDescriptor = 0x06, + OtherSpeedConfigurationDescriptor = 0x07, + InterfacePowerDescriptor = 0x08, + OTGDescriptor = 0x09, + DebugDescriptor = 0x0A, + InterfaceAssociationDescriptor = 0x0B, + + HIDDescriptor = 0x21, + ReportDescriptor = 0x22, + PhysicalDescriptor = 0x23 +}; + +enum InterfaceClass : u8 { + UseClassInformationInInterfaceDescriptors = 0x00, + Audio = 0x01, + CommunicationAndCDCControl = 0x02, + HID = 0x03, + Physical = 0x05, + Image = 0x06, + Printer = 0x07, + MassStorage = 0x08, + Hub = 0x09, + CDCData = 0x0A, + SmartCard = 0x0B, + ContentSecurity = 0x0C, + Video = 0x0E, + PersonalHealthcare = 0x0F, + AudioVideoDevice = 0x10, + BillboardDevice = 0x11, + USBTypeCBridge = 0x12, + I3CDevice = 0x3C, + DiagnosticDevice = 0xDC, + WirelessController = 0xE0, + Miscellaneous = 0xEF, + ApplicationSpecific = 0xFE, + VendorSpecific = 0xFF +}; + +enum CountryCode : u8 { + NotSupported = 0, + Arabic = 1, + Belgian = 2, + CanadianBilingual = 3, + CanadianFrench = 4, + CzechRepublic = 5, + Danish = 6, + Finnish = 7, + French = 8, + German = 9, + Greek = 10, + Hebrew = 11, + Hungary = 12, + International = 13, + Italian = 14, + JapanKatakana = 15, + Korean = 16, + LatinAmerican = 17, + Dutch = 18, + Norwegian = 19, + PersianFarsi = 20, + Polish = 21, + Portuguese = 22, + Russian = 23, + Slovakian = 24, + Spanish = 25, + Swedish = 26, + SwissFrench = 27, + SwissGerman = 28, + Switzerland = 29, + Taiwan = 30, + TurkishQ = 31, + EnglishUK = 32, + EnglishUS = 33, + Yugoslavian = 34, + TurkishF = 35, + Reserved = 36 ... 255 +}; + +enum HubInterfaceSubClass : u8 { + Hub = 0x00 +}; + +enum AudioVideoDeviceSubClass : u8 { + AVControlInterface = 0x01, + AVDataVideoStreamingInterface = 0x02, + AVDataAudioStreamingInterface = 0x03 +}; + +enum HubInterfaceProtocol : u8 { + FullSpeedHub = 0x00, + HiSpeedHubWithSingleTT = 0x01, + HiSpeedHubWithMultipleTTs = 0x02 +}; + +struct Ampere { + u8 amps; +} [[sealed, format("format_ampere")]]; + +fn format_ampere(Ampere ampere) { + return std::format("{} mA", ampere.amps * 2); +}; + +bitfield ConfigAttributes { + padding : 1; + SelfPowered : 1; + RemoteWakeup : 1; + padding : 5; +} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 8)]]; + +struct BCD { + u8 bytes[Size]; +} [[sealed, format("format_bcd")]]; + +fn format_bcd(ref auto bcd) { + str result; + for (s8 i = sizeof(bcd.bytes) - 1, i >= 0, i -= 1) + result += std::format("{:X}.", bcd.bytes[i]); + + return std::string::substr(result, 0, std::string::length(result) - 1); +}; + +struct DeviceDescriptor { + BCD<2> bcdUSB; + InterfaceClass bDeviceClass; + if (bDeviceClass == InterfaceClass::Hub) { + HubInterfaceSubClass bDeviceSubClass; + if (bDeviceSubClass == HubInterfaceSubClass::Hub) + HubInterfaceProtocol bDeviceSubClass; + else + u8 bDeviceSubClass; + } else if (bDeviceClass == InterfaceClass::AudioVideoDevice) { + AudioVideoDeviceSubClass bDeviceSubClass; + u8 bDeviceSubClass; + } else { + u8 bDeviceSubClass; + } +}; + +struct ConfigDescriptor { + u16 wTotalLength; + u8 bNumInterfaces; + u8 bConfigurationValue; + u8 iConfiguration; + ConfigAttributes bmAttributes; + Ampere bMaxPower; +}; + +struct StringDescriptor { + char bString[parent.bLength - 2]; +}; + +struct InterfaceDescriptor { + u8 bInterfaceNumber; + u8 bAlternateSetting; + u8 bNumEndpoints; + + InterfaceClass bInterfaceClass; + if (bInterfaceClass == InterfaceClass::Hub) { + HubInterfaceSubClass bInterfaceSubClass; + if (bInterfaceSubClass == HubInterfaceSubClass::Hub) + HubInterfaceProtocol bInterfaceProtocol; + else + u8 bInterfaceProtocol; + } else if (bInterfaceClass == InterfaceClass::AudioVideoDevice) { + AudioVideoDeviceSubClass bInterfaceSubClass; + u8 bInterfaceProtocol; + } else { + u8 bInterfaceSubClass; + u8 bInterfaceProtocol; + } + + u8 iInterface; +}; + +enum EndpointDirection : u8 { + OUT = 0, + IN = 1 +}; + +fn format_direction(u8 value) { + EndpointDirection direction; + direction = value; + return direction; +}; + +bitfield EndpointAddress { + EndpointNumber : 4; + padding : 3; + Direction : 1 [[format("format_direction")]]; +}; + +bitfield EndpointAttributes { + TransferType : 2; + SynchronizationType : 2; + UsageType : 2; +}; + +struct EndpointDescriptor { + EndpointAddress bEndPointAddress; + EndpointAttributes bmAttributes; + u16 wMaxPacketSize; + u8 bInterval; +}; + +struct OtherSpeedConfigurationDescriptor { + ConfigDescriptor content [[inline]]; +}; + +struct DeviceQualifierDescriptor { + DeviceDescriptor deviceDescriptor [[inline]]; + u8 bMaxPacketSize0; + u8 bNumConfigurations; + padding[1]; +}; + +bitfield OTGAttributes { + SRPSupport : 1; + HNPSupport : 1; +} [[right_to_left]]; + +struct OTGDescriptor { + OTGAttributes bmAttributes; +}; + +struct HIDDescriptor { + BCD<2> bcdVersion; + CountryCode bCountryCode; + u8 bNumDescriptors; + DescriptorType bDescriptorType; + u16 wDescriptorLength; +}; + +struct USBDescriptor { + u8 bLength; + DescriptorType bDescriptorType; + + if (bDescriptorType == DescriptorType::DeviceDescriptor) + DeviceDescriptor deviceDescriptor [[inline]]; + else if (bDescriptorType == DescriptorType::ConfigDescriptor) + ConfigDescriptor configDescriptor [[inline]]; + else if (bDescriptorType == DescriptorType::StringDescriptor) + StringDescriptor stringDescriptor [[inline]]; + else if (bDescriptorType == DescriptorType::InterfaceDescriptor) + InterfaceDescriptor interfaceDescriptor [[inline]]; + else if (bDescriptorType == DescriptorType::EndpointDescriptor) + EndpointDescriptor endpointDescriptor [[inline]]; + else if (bDescriptorType == DescriptorType::OtherSpeedConfigurationDescriptor) + OtherSpeedConfigurationDescriptor otherSpeedConfigurationDescriptor [[inline]]; + else if (bDescriptorType == DescriptorType::DeviceQualifierDescriptor) + DeviceQualifierDescriptor deviceQualifierDescriptor [[inline]]; + else if (bDescriptorType == DescriptorType::OTGDescriptor) + OTGDescriptor otgDescriptor [[inline]]; + else if (bDescriptorType == DescriptorType::HIDDescriptor) + HIDDescriptor hidDescriptor [[inline]]; + + padding[bLength - ($ - addressof(this))]; +}; + USBDescriptor descriptors[while(!std::mem::eof())] @ 0x00; \ No newline at end of file diff --git a/patterns/xbeh.hexpat b/patterns/xbeh.hexpat index a53b6e7..818d996 100644 --- a/patterns/xbeh.hexpat +++ b/patterns/xbeh.hexpat @@ -22,7 +22,7 @@ bitfield AllowedMedia { padding : 20; NonSecureHardDisk : 1; NonSecureMode : 1; -} [[right_to_left]]; +}; bitfield GameRegion { NorthAmerica : 1; @@ -30,7 +30,7 @@ bitfield GameRegion { RestOfTheWorld : 1; padding : 28; Manufacturing : 1; -} [[right_to_left]]; +}; struct Certificate { type::Size certificateSize; @@ -52,7 +52,7 @@ bitfield InitializationFlags { Limit64Megabytes : 1; DontSetuptHarddisk : 1; padding : 28; -} [[right_to_left]]; +}; union EntryPoint { u32 betaAddress [[format("format_beta_entrypoint")]]; @@ -333,7 +333,7 @@ bitfield LibraryFlags { QFEVersion : 13; Approved : 2; DebugBuild : 1; -} [[right_to_left]]; +}; struct LibraryVersion { char libraryName[8]; @@ -349,7 +349,7 @@ bitfield SectionFlags { HeadPageReadOnly : 1; TailPageReadOnly : 1; padding : 26; -} [[right_to_left]]; +}; struct SectionHeader { SectionFlags sectionFlags; diff --git a/patterns/zstd.hexpat b/patterns/zstd.hexpat index 2934e02..eb9abe5 100644 --- a/patterns/zstd.hexpat +++ b/patterns/zstd.hexpat @@ -1,11 +1,14 @@ // https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md #pragma MIME application/zstd - + +#include #include #include #include +using BitfieldOrder = std::core::BitfieldOrder; + #define ZSTD_MAGIC_NUMBER 0xFD2FB528 bitfield frame_header_descriptor_t { @@ -15,12 +18,12 @@ bitfield frame_header_descriptor_t { reserved_bit : 1; content_checksum_flag : 1; dictionary_id_flag : 2; -} [[left_to_right]]; +} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 8)]]; bitfield window_descriptor_t { exponent : 5; mantissa : 3; -} [[left_to_right]]; +} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 8)]]; fn window_size(window_descriptor_t window_descriptor) { u64 window_log = 10 + window_descriptor.exponent; @@ -67,7 +70,7 @@ bitfield block_header_t { last_block : 1; block_type : 2; block_size : 21; -} [[right_to_left]]; +}; enum block_type : u8 { raw_block = 0,