From f40943c8cd5b799357e86d93736a23784bef3100 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Fri, 8 Jul 2022 12:31:54 +0200 Subject: [PATCH] patterns: Added UF2 pattern --- README.md | 1 + patterns/uf2.hexpat | 98 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 patterns/uf2.hexpat diff --git a/README.md b/README.md index 6826d27..acec7b0 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ Hex patterns, include patterns and magic files for the use with the ImHex Hex Ed | ISO | | `patterns/iso.hexpat` | ISO 9660 file system | | VDF | | `patterns/vdf.hexpat` | Binary Value Data Format (.vdf) files | | IP | | `patterns/ip.hexpat` | Ethernet II Frames (IP Packets) | +| UF2 | | `patterns/uf2.hexpat` | [USB Flashing Format](https://github.com/microsoft/uf2) | ### Scripts diff --git a/patterns/uf2.hexpat b/patterns/uf2.hexpat new file mode 100644 index 0000000..4c3faf8 --- /dev/null +++ b/patterns/uf2.hexpat @@ -0,0 +1,98 @@ +#include +#include + +#pragma MIME application/microformats+json +#pragma MIME application/microformats2+json +#pragma MIME application/mf2+json +#pragma MIME application/uf2+json + +#pragma pattern_limit 100000 + +bitfield UF2_Flags { + NotMainFlash : 1; + padding : 11; + FileContainer : 1; + FamilyIDPresent : 1; + MD5ChecksumPresent : 1; + ExtensionTagsPresent : 1; + padding : 16; +}; + +struct UF2_Hash { + u32 startAddress; + u32 size; + u8 md5Checksum[16]; +} [[static]]; + +struct UF2_TagType { + u8 bytes[3]; +} [[format("formatTagType")]]; + +enum UF2_TagTypeEnum : u32 { + FirmwareFileVersion = 0x9FC7BC, + DeviceDescription = 0x650D9D, + TargetPageSize = 0x0BE9F7, + SHA1Checksum = 0xB46DB0, + DeviceTypeIdentifier = 0xC8A729 +}; + +fn formatTagType(UF2_TagType type) { + u32 value = (type.bytes[0] << 16) | (type.bytes[1] << 8) | (type.bytes[2]); + + if (value == UF2_TagTypeEnum::FirmwareFileVersion) + return "Firmware File Version"; + else if (value == UF2_TagTypeEnum::DeviceDescription) + return "Device Description"; + else if (value == UF2_TagTypeEnum::TargetPageSize) + return "Target Page Size"; + else if (value == UF2_TagTypeEnum::SHA1Checksum) + return "SHA1 Checksum"; + else if (value == UF2_TagTypeEnum::DeviceTypeIdentifier) + return "Device Type Identifier"; + else + return "Custom Type"; +}; + +struct UF2_ExtensionTag { + u8 size; + UF2_TagType type; + u8 data[size - 4]; + + if (size == 0 && type.bytes[0] == 0x00 && type.bytes[1] == 0x00 && type.bytes[2] == 0x00) + break; +}; + +struct UF2_Block { + char magicStart0[4]; + u32 magicStart1; + UF2_Flags flags; + u32 targetAddr; + u32 payloadSize; + u32 blockNo; + u32 numBlocks; + + if (flags.FamilyIDPresent) + u32 familyId; + else + u32 fileSize; + + if (flags.MD5ChecksumPresent) { + u8 data[452]; + UF2_Hash hash; + } + else { + u8 data[476]; + } + + if (flags.ExtensionTagsPresent) { + UF2_ExtensionTag extensionTags[0xFF]; + } + + u32 magicEnd; + + std::assert(magicStart0 == "UF2\n", "Invalid magicStart0 value!"); + std::assert(magicStart1 == 0x9E5D5157, "Invalid magicStart1 value!"); + std::assert(magicEnd == 0x0AB16F30, "Invalid magicEnd value!"); +}; + +UF2_Block block[while(!std::mem::eof())] @ 0; \ No newline at end of file