mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-03-31 05:15:54 -05:00
Compare commits
61 Commits
ImHex-v1.2
...
ImHex-v1.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f53be98204 | ||
|
|
ee95990225 | ||
|
|
ac28d9d029 | ||
|
|
372a0e5bba | ||
|
|
544cadbcca | ||
|
|
1471b02abd | ||
|
|
73cde21254 | ||
|
|
f730d8b0cc | ||
|
|
13183769f8 | ||
|
|
5eda5a15bf | ||
|
|
8e6248aa2d | ||
|
|
75fd40442b | ||
|
|
5a3036149c | ||
|
|
b160e99b63 | ||
|
|
f32db1745f | ||
|
|
7842c974df | ||
|
|
e2c191b7c9 | ||
|
|
71ee41fe2c | ||
|
|
69feadfc09 | ||
|
|
e79d512b2b | ||
|
|
e876270a08 | ||
|
|
8f39ecd879 | ||
|
|
ba36826e2d | ||
|
|
ac0b77540d | ||
|
|
683e78d9c3 | ||
|
|
110b498d7b | ||
|
|
9887da7af5 | ||
|
|
01a1bd0d9f | ||
|
|
fbb6a84323 | ||
|
|
4cdf3c11cf | ||
|
|
a9ada89bd0 | ||
|
|
de0e089165 | ||
|
|
e7ea6fd77f | ||
|
|
ff3c796de8 | ||
|
|
0c83764f24 | ||
|
|
d87f95dbfa | ||
|
|
51dad63779 | ||
|
|
764b86acc9 | ||
|
|
10fdf94899 | ||
|
|
9ba998e618 | ||
|
|
aceeb2b7b3 | ||
|
|
3b1b7cc379 | ||
|
|
49be43e0e1 | ||
|
|
8e70a5524d | ||
|
|
9c0bf1433c | ||
|
|
43afbfa120 | ||
|
|
f75703fd2b | ||
|
|
16eebea2fb | ||
|
|
6cb208d975 | ||
|
|
665c50b914 | ||
|
|
04ef9d6085 | ||
|
|
dc5b219d24 | ||
|
|
e6c800b71c | ||
|
|
5c9a7b1ac0 | ||
|
|
22390d0adf | ||
|
|
dfc9b17067 | ||
|
|
d33fdfafb8 | ||
|
|
58d63d1d4a | ||
|
|
86f38ca545 | ||
|
|
27d98d4552 | ||
|
|
dba93afe06 |
1
.github/workflows/tests.yml
vendored
1
.github/workflows/tests.yml
vendored
@@ -50,6 +50,7 @@ jobs:
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld --coverage" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld --coverage" \
|
||||
-DLIBPL_ENABLE_TESTS=OFF \
|
||||
-DLIBPL_ENABLE_CLI=OFF \
|
||||
..
|
||||
make -j4
|
||||
|
||||
|
||||
183
README.md
183
README.md
@@ -8,122 +8,139 @@ Hex patterns, include patterns and magic files for the use with the ImHex Hex Ed
|
||||
|
||||
| Name | MIME | Path | Description |
|
||||
|------|------|------|-------------|
|
||||
| BMP | `image/bmp` | `patterns/bmp.hexpat` | OS2/Windows Bitmap files |
|
||||
| ELF | `application/x-executable` | `patterns/elf.hexpat` | ELF header in elf binaries |
|
||||
| PE | `application/x-dosexec` | `patterns/pe.hexpat` | PE header, COFF header, Standard COFF fields and Windows Specific fields |
|
||||
| Intel HEX | | `patterns/intel_hex.hexpat` | [Intel hexadecimal object file format definition]("https://en.wikipedia.org/wiki/Intel_HEX") |
|
||||
| MIDI | `audio/midi` | `patterns/midi.hexpat` | MIDI header, event fields provided |
|
||||
| WAV | `audio/wav` | `patterns/wav.hexpat` | RIFF header, WAVE header, PCM header |
|
||||
| ZIP | `application/zip` | `patterns/zip.hexpat` | End of Central Directory Header, Central Directory File Headers |
|
||||
| PCAP | `application/vnd.tcpdump.pcap` | `patterns/pcap.hexpat` | pcap header and packets |
|
||||
| SPIRV | | `patterns/spirv.hexpat` | SPIR-V header and instructions |
|
||||
| AFE2 | | `patterns/afe2.hexpat` | Nintendo Switch Atmosphère CFW Fatal Error log |
|
||||
| AR | `application/x-archive` | `patterns/ar.hexpat` | Static library archive files |
|
||||
| NACP | | `patterns/nacp.hexpat` | Nintendo Switch NACP files |
|
||||
| NRO | | `patterns/nro.hexpat` | Nintendo Switch NRO files |
|
||||
| PRODINFO | | `patterns/prodinfo.hexpat` | Nintendo Switch PRODINFO |
|
||||
| Java Class | `application/x-java-applet` | `patterns/java_class.hexpat` | Java Class files |
|
||||
| ARM VTOR | | `patterns/arm_cm_vtor.hexpat` | ARM Cortex M Vector Table Layout |
|
||||
| ICO | | `patterns/ico.hexpat` | Icon (.ico) or Cursor (.cur) files |
|
||||
| PNG | `image/png` | `patterns/png.hexpat` | PNG image files |
|
||||
| DDS | `image/vnd-ms.dds` | `patterns/dds.hexpat` | DirectDraw Surface |
|
||||
| TGA | `image/tga` | `patterns/tga.hexpat` | Truevision TGA/TARGA image |
|
||||
| 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) |
|
||||
| File System | | `patterns/fs.hexpat` | Drive File System |
|
||||
| Bencode | `application/x-bittorrent` | `patterns/bencode.hexpat` | Bencode encoding, used by Torrent files |
|
||||
| Protobuf | | `patterns/protobuf.hexpat` | Google Protobuf encoding |
|
||||
| OGG | `audio/ogg` | `patterns/ogg.hexpat` | OGG Audio format |
|
||||
| STL | `model/stl` | `patterns/stl.hexpat` | STL 3D Model format |
|
||||
| VHDX | | `patterns/vhdx.hexpat` | Microsoft Hyper-V Virtual Hard Disk format |
|
||||
| NTAG | | `patterns/ntag.hexpat` | NTAG213/NTAG215/NTAG216, NFC Forum Type 2 Tag compliant IC |
|
||||
| Shell Link | `application/x-ms-shortcut` | `patterns/lnk.hexpat` | Windows Shell Link file format |
|
||||
| Xilinx BIT | | `patterns/xilinx_bit.hexpat` | Xilinx FPGA Bitstreams |
|
||||
| FLAC | `audio/flac` | `patterns/flac.hexpat` | Free Lossless Audio Codec, FLAC Audio Format |
|
||||
| BSON | `application/bson` | `patterns/bson.hexpat` | BSON (Binary JSON) format |
|
||||
| msgpack | `application/x-msgpack` | `patterns/msgpack.hexpat` | MessagePack binary serialization format |
|
||||
| MiniDump | `application/x-dmp` | `patterns/minidump.hexpat` | Windows MiniDump files |
|
||||
| BMP | `image/bmp` | [`patterns/bmp.hexpat`](patterns/bmp.hexpat) | OS2/Windows Bitmap files |
|
||||
| ELF | `application/x-executable` | [`patterns/elf.hexpat`](patterns/elf.hexpat) | ELF header in elf binaries |
|
||||
| PE | `application/x-dosexec` | [`patterns/pe.hexpat`](patterns/pe.hexpat) | PE header, COFF header, Standard COFF fields and Windows Specific fields |
|
||||
| NE | | [`patterns/ne.hexpat`](patterns/ne.hexpat) | NE header and Standard NE fields |
|
||||
| Intel HEX | | [`patterns/intel_hex.hexpat`](patterns/intel_hex.hexpat) | [Intel hexadecimal object file format definition]("https://en.wikipedia.org/wiki/Intel_HEX") |
|
||||
| MIDI | `audio/midi` | [`patterns/midi.hexpat`](patterns/midi.hexpat) | MIDI header, event fields provided |
|
||||
| WAV | `audio/wav` | [`patterns/wav.hexpat`](patterns/wav.hexpat) | RIFF header, WAVE header, PCM header |
|
||||
| ZIP | `application/zip` | [`patterns/zip.hexpat`](patterns/zip.hexpat) | End of Central Directory Header, Central Directory File Headers |
|
||||
| PCAP | `application/vnd.tcpdump.pcap` | [`patterns/pcap.hexpat`](patterns/pcap.hexpat) | pcap header and packets |
|
||||
| SPIRV | | [`patterns/spirv.hexpat`](patterns/spirv.hexpat) | SPIR-V header and instructions |
|
||||
| AFE2 | | [`patterns/afe2.hexpat`](patterns/afe2.hexpat) | Nintendo Switch Atmosphère CFW Fatal Error log |
|
||||
| AR | `application/x-archive` | [`patterns/ar.hexpat`](patterns/ar.hexpat) | Static library archive files |
|
||||
| NACP | | [`patterns/nacp.hexpat`](patterns/nacp.hexpat) | Nintendo Switch NACP files |
|
||||
| NRO | | [`patterns/nro.hexpat`](patterns/nro.hexpat) | Nintendo Switch NRO files |
|
||||
| PRODINFO | | [`patterns/prodinfo.hexpat`](patterns/prodinfo.hexpat) | Nintendo Switch PRODINFO |
|
||||
| Java Class | `application/x-java-applet` | [`patterns/java_class.hexpat`](patterns/java_class.hexpat) | Java Class files |
|
||||
| ARM VTOR | | [`patterns/arm_cm_vtor.hexpat`](patterns/arm_cm_vtor.hexpat) | ARM Cortex M Vector Table Layout |
|
||||
| ICO | | [`patterns/ico.hexpat`](patterns/ico.hexpat) | Icon (.ico) or Cursor (.cur) files |
|
||||
| PNG | `image/png` | [`patterns/png.hexpat`](patterns/png.hexpat) | PNG image files |
|
||||
| DDS | `image/vnd-ms.dds` | [`patterns/dds.hexpat`](patterns/dds.hexpat) | DirectDraw Surface |
|
||||
| TGA | `image/tga` | [`patterns/tga.hexpat`](patterns/tga.hexpat) | Truevision TGA/TARGA image |
|
||||
| ISO | | [`patterns/iso.hexpat`](patterns/iso.hexpat) | ISO 9660 file system |
|
||||
| VDF | | [`patterns/vdf.hexpat`](patterns/vdf.hexpat) | Binary Value Data Format (.vdf) files |
|
||||
| IP | | [`patterns/ip.hexpat`](patterns/ip.hexpat) | Ethernet II Frames (IP Packets) |
|
||||
| UF2 | | [`patterns/uf2.hexpat`](patterns/uf2.hexpat) | [USB Flashing Format](https://github.com/microsoft/uf2) |
|
||||
| File System | | [`patterns/fs.hexpat`](patterns/fs.hexpat) | Drive File System |
|
||||
| Bencode | `application/x-bittorrent` | [`patterns/bencode.hexpat`](patterns/bencode.hexpat) | Bencode encoding, used by Torrent files |
|
||||
| Protobuf | | [`patterns/protobuf.hexpat`](patterns/protobuf.hexpat) | Google Protobuf encoding |
|
||||
| OGG | `audio/ogg` | [`patterns/ogg.hexpat`](patterns/ogg.hexpat) | OGG Audio format |
|
||||
| STL | `model/stl` | [`patterns/stl.hexpat`](patterns/stl.hexpat) | STL 3D Model format |
|
||||
| VHDX | | [`patterns/vhdx.hexpat`](patterns/vhdx.hexpat) | Microsoft Hyper-V Virtual Hard Disk format |
|
||||
| NTAG | | [`patterns/ntag.hexpat`](patterns/ntag.hexpat) | NTAG213/NTAG215/NTAG216, NFC Forum Type 2 Tag compliant IC |
|
||||
| Shell Link | `application/x-ms-shortcut` | [`patterns/lnk.hexpat`](patterns/lnk.hexpat) | Windows Shell Link file format |
|
||||
| Xilinx BIT | | [`patterns/xilinx_bit.hexpat`](patterns/xilinx_bit.hexpat) | Xilinx FPGA Bitstreams |
|
||||
| FLAC | `audio/flac` | [`patterns/flac.hexpat`](patterns/flac.hexpat) | Free Lossless Audio Codec, FLAC Audio Format |
|
||||
| BSON | `application/bson` | [`patterns/bson.hexpat`](patterns/bson.hexpat) | BSON (Binary JSON) format |
|
||||
| msgpack | `application/x-msgpack` | [`patterns/msgpack.hexpat`](patterns/msgpack.hexpat) | MessagePack binary serialization format |
|
||||
| MiniDump | `application/x-dmp` | [`patterns/minidump.hexpat`](patterns/minidump.hexpat) | Windows MiniDump files |
|
||||
| ID3 | `audio/mpeg` | [`patterns/id3tag.hexpat`](patterns/id3tag.hexpat) | ID3 tags in MP3 files |
|
||||
| TAR | `application/x-tar` | [`patterns/tar.hexpat`](patterns/tar.hexpat) | Tar file format |
|
||||
| CPIO | `application/x-cpio` | [`patterns/cpio.hexpat`](patterns/cpio.hexpat) | Old Binary CPIO Format |
|
||||
| FDT | | [`patterns/fdt.hexpat`](patterns/fdt.hexpat) | Flat Linux Device Tree blob |
|
||||
| StuffItV5 | `application/x-stuffit` | [`patterns/sit5.hexpat`](patterns/sit5.hexpat) | StuffIt V5 archive |
|
||||
| NBT | | [`patterns/nbt.hexpat`](patterns/nbt.hexpat) | Minecraft NBT format |
|
||||
| PCX | `application/x-pcx` | [`patterns/pcx.hexpat`](patterns/pcx.hexpat) | PCX Image format |
|
||||
| GZIP | `application/gzip` | [`patterns/gzip.hexpat`](patterns/gzip.hexpat) | GZip compressed data format |
|
||||
| PFS0 | | [`patterns/pfs0.hexpat`](patterns/pfs0.hexpat) | Nintendo Switch PFS0 archive (NSP files) |
|
||||
| XCI | | [`patterns/xci.hexpat`](patterns/xci.hexpat) | Nintendo Switch XCI cardridge ROM |
|
||||
| WAD | | [`patterns/wad.hexpat`](patterns/wad.hexpat) | DOOM WAD Archive |
|
||||
| GIF | `image/gif` | [`patterns/gif.hexpat`](patterns/gif.hexpat) | GIF image files |
|
||||
| ZSTD | `application/zstd` | [`patterns/zstd.hexpat`](patterns/zstd.hexpat) | Zstandard compressed data format |
|
||||
| COFF | `application/x-coff` | [`patterns/coff.hexpat`](patterns/coff.hexpat) | Common Object File Format (COFF) executable |
|
||||
| Mach-O | `application/x-mach-binary` | [`patterns/macho.hexpat`](patterns/macho.hexpat) | Mach-O executable |
|
||||
| CHM | | [`patterns/chm.hexpat`](patterns/chm.hexpat) | Windows HtmlHelp Data (ITSF / CHM) |
|
||||
|
||||
### Scripts
|
||||
|
||||
| Name | Path | Description |
|
||||
|------|------|-------------|
|
||||
| svd2pat | `scripts/svd2pat.py` | Converts a ARM .svd register MMIO definition file into a pattern |
|
||||
| csv2tbl | `scripts/csv2tbl.py` | Converts a 010 editor CSV encoding file into a table file |
|
||||
| svd2pat | [`scripts/svd2pat.py`](scripts/svd2pat.py) | Converts a ARM .svd register MMIO definition file into a pattern |
|
||||
| csv2tbl | [`scripts/csv2tbl.py`](scripts/csv2tbl.py) | Converts a 010 editor CSV encoding file into a table file |
|
||||
|
||||
### Pattern Libraries
|
||||
|
||||
| Name | Path | Description |
|
||||
|------|------|-------------|
|
||||
| libstd | `includes/std/*` | Pattern Language Standard Libaray |
|
||||
| libtype | `includes/type/*` | Various custom types with special formatters |
|
||||
| libhex | `includes/hex/*` | Functions to interact with ImHex |
|
||||
| libstd | [`includes/std/*`](includes/std) | Pattern Language Standard Libaray |
|
||||
| libtype | [`includes/type/*`](includes/type) | Various custom types with special formatters |
|
||||
| libhex | [`includes/hex/*`](includes/hex) | Functions to interact with ImHex |
|
||||
|
||||
### Yara rules
|
||||
|
||||
| Name | Path | Description |
|
||||
|------|------|-------------|
|
||||
| Official Rules | `yara/official_rules/*` | Official Yara rules repository |
|
||||
| Official Rules | [`yara/official_rules/*`](yara/official_rules) | Official Yara rules repository |
|
||||
|
||||
### Magic files
|
||||
|
||||
| Name | Path | Description |
|
||||
|------|------|-------------|
|
||||
| Nintendo Switch | `magic/nintendo_switch_magic` | Identifies common file types used on the Nintendo Switch |
|
||||
| Portable Executable | `magic/portable_executable_magic` | Identifies PE files used on Windows
|
||||
| Nintendo Switch | [`magic/nintendo_switch_magic`](magic/nintendo_switch_magic) | Identifies common file types used on the Nintendo Switch |
|
||||
| Portable Executable | [`magic/portable_executable_magic`](magic/portable_executable_magic) | Identifies PE files used on Windows
|
||||
|
||||
### Constants files
|
||||
|
||||
| Name | Path | Description |
|
||||
|------|------|-------------|
|
||||
| CRC-16 | `constants/crc16.json` | Constants associated with CRC-16 operations |
|
||||
| CRC-32 | `constants/crc32.json` | Constants associated with CRC-32 operations |
|
||||
| HTTP-Codes | `constants/http_status.json` | HTTP Status code values |
|
||||
| Linux Error Codes | `constants/linux_errors.json` | Values of Linux error results |
|
||||
| CRC-16 | [`constants/crc16.json`](constants/crc16.json) | Constants associated with CRC-16 operations |
|
||||
| CRC-32 | [`constants/crc32.json`](constants/crc32.json) | Constants associated with CRC-32 operations |
|
||||
| HTTP-Codes | [`constants/http_status.json`](constants/http_status.json) | HTTP Status code values |
|
||||
| Linux Error Codes | [`constants/linux_errors.json`](constants/linux_errors.json) | Values of Linux error results |
|
||||
|
||||
### Encoding files
|
||||
|
||||
| Name | Path | Description |
|
||||
|------|------|-------------|
|
||||
| Arabic ISO | `encodings/arabic_iso.tbl` | Arabic ISO encoding |
|
||||
| Arabic Windows | `encodings/arabic_windows.tbl` | Arabic Windows encoding |
|
||||
| ASCII | `encodings/ascii.tbl` | Regular ASCII encoding |
|
||||
| ASCII+ANSI | `encodings/ascii_ansi.tbl` | Extended ASCII encoding |
|
||||
| ASCII+OEM | `encodings/ascii_oem.tbl` | ASCII encoding with Windows OEM characters |
|
||||
| Baltic ISO | `encodings/baltic_iso.tbl` | Baltic ISO encoding |
|
||||
| Baltic Windows | `encodings/baltic_windows.tbl` | Baltic Windows encoding |
|
||||
| Cyrillic ISO | `encodings/cyrillic_iso.tbl` | Cyrillic ISO encoding |
|
||||
| Cyrillic Windows | `encodings/cyrillic_windows.tbl` | Cyrillic Windows encoding |
|
||||
| Cyrillic KOI8-R | `encodings/cyrillic_koi8_r.tbl` | Cyrillic KOI8-R encoding (Russian Characters) |
|
||||
| Cyrillic KOI8-U | `encodings/cyrillic_koi8_u.tbl` | Cyrillic KOI8-U encoding (Ukranian Characters) |
|
||||
| Eastern Europe ISO | `encodings/eastern_europe_iso.tbl` | Eastern Europe ISO encoding |
|
||||
| Eastern Europe Windows | `encodings/eastern_europe_windows.tbl` | Eastern Europe Windows encoding |
|
||||
| EBCDIC | `encodings/ebcdic.tbl` | Extended Binary Coded Decimal Interchange Code, developed by IBM for their Main Frames |
|
||||
| EUC-JP | `encodings/euc_jp.tbl` | EUC-JP encoding with NEC special and IBM extended characters |
|
||||
| EUC-KR | `encodings/euc_kr.tbl` | EUC-KR encoding |
|
||||
| Greek ISO | `encodings/greek_iso.tbl` | Greek ISO encoding |
|
||||
| Greek Windows | `encodings/greek_windows.tbl` | Greek Windows encoding |
|
||||
| Hebrew ISO | `encodings/hebrew_iso.tbl` | Hebrew ISO encoding |
|
||||
| Hebrew Windows | `encodings/hebrew_windows.tbl` | Hebrew Windows encoding |
|
||||
| ISO/IEC 646 | `encodings/iso_646.tbl` | ISO/IEC 646 encoding, an older version of ASCII |
|
||||
| ISO/IEC 6937 | `encodings/iso_6937.tbl` | ISO/IEC 6937 encoding, an extension of ASCII containing additional character |
|
||||
| JIS 0201 | `encodings/jis_x_0201.tbl` | JIS X 0201 encoding in UTF-8 |
|
||||
| JIS X 0211 | `encodings/jis_x_0211.tbl` | JIS X 0211 encoding in UTF-8 |
|
||||
| JIS 0213 | `encodings/jis_x_0213.tbl` | JIS X 0213 encoding in UTF-8 |
|
||||
| Macintosh | `encodings/macintosh.tbl` | Macintosh character encoding used by the Kermit protocol |
|
||||
| Pokémon (English, Generation 1) | `encodings/pokegen1_en.tbl` | Character encoding used by the English generation 1 Pokémon games |
|
||||
| Shift-JIS UTF-8 | `encodings/shiftjis.tbl` | Shift-JIS encoding in UTF-8 |
|
||||
| Thai | `encodings/thai.tbl` | Thai character encoding |
|
||||
| Turkish ISO | `encodings/turkish_iso.tbl` | Turkish ISO encoding |
|
||||
| Turkish Windows | `encodings/turkish_windows.tbl` | Turkish Windows encoding |
|
||||
| UTF-8 | `encodings/utf8.tbl` | UTF-8 encoding |
|
||||
| Vietnamese | `encodings/vietnamese.tbl` | Vietnamese character encoding |
|
||||
| Arabic ISO | [`encodings/arabic_iso.tbl`](encodings/arabic_iso.tbl) | Arabic ISO encoding |
|
||||
| Arabic Windows | [`encodings/arabic_windows.tbl`](encodings/arabic_windows.tbl) | Arabic Windows encoding |
|
||||
| ASCII | [`encodings/ascii.tbl`](encodings/ascii.tbl) | Regular ASCII encoding |
|
||||
| ASCII+ANSI | [`encodings/ascii_ansi.tbl`](encodings/ascii_ansi.tbl) | Extended ASCII encoding |
|
||||
| ASCII+OEM | [`encodings/ascii_oem.tbl`](encodings/ascii_oem.tbl) | ASCII encoding with Windows OEM characters |
|
||||
| Baltic ISO | [`encodings/baltic_iso.tbl`](encodings/baltic_iso.tbl) | Baltic ISO encoding |
|
||||
| Baltic Windows | [`encodings/baltic_windows.tbl`](encodings/baltic_windows.tbl) | Baltic Windows encoding |
|
||||
| Cyrillic ISO | [`encodings/cyrillic_iso.tbl`](encodings/cyrillic_iso.tbl) | Cyrillic ISO encoding |
|
||||
| Cyrillic Windows | [`encodings/cyrillic_windows.tbl`](encodings/cyrillic_windows.tbl) | Cyrillic Windows encoding |
|
||||
| Cyrillic KOI8-R | [`encodings/cyrillic_koi8_r.tbl`](encodings/cyrillic_koi8_r.tbl) | Cyrillic KOI8-R encoding (Russian Characters) |
|
||||
| Cyrillic KOI8-U | [`encodings/cyrillic_koi8_u.tbl`](encodings/cyrillic_koi8_u.tbl) | Cyrillic KOI8-U encoding (Ukranian Characters) |
|
||||
| Eastern Europe ISO | [`encodings/eastern_europe_iso.tbl`](encodings/eastern_europe_iso.tbl) | Eastern Europe ISO encoding |
|
||||
| Eastern Europe Windows | [`encodings/eastern_europe_windows.tbl`](encodings/eastern_europe_windows.tbl) | Eastern Europe Windows encoding |
|
||||
| EBCDIC | [`encodings/ebcdic.tbl`](encodings/ebcdic.tbl) | Extended Binary Coded Decimal Interchange Code, developed by IBM for their Main Frames |
|
||||
| EUC-JP | [`encodings/euc_jp.tbl`](encodings/euc_jp.tbl) | EUC-JP encoding with NEC special and IBM extended characters |
|
||||
| EUC-KR | [`encodings/euc_kr.tbl`](encodings/euc_kr.tbl) | EUC-KR encoding |
|
||||
| Greek ISO | [`encodings/greek_iso.tbl`](encodings/greek_iso.tbl) | Greek ISO encoding |
|
||||
| Greek Windows | [`encodings/greek_windows.tbl`](encodings/greek_windows.tbl) | Greek Windows encoding |
|
||||
| Hebrew ISO | [`encodings/hebrew_iso.tbl`](encodings/hebrew_iso.tbl) | Hebrew ISO encoding |
|
||||
| Hebrew Windows | [`encodings/hebrew_windows.tbl`](encodings/hebrew_windows.tbl) | Hebrew Windows encoding |
|
||||
| ISO/IEC 646 | [`encodings/iso_646.tbl`](encodings/iso_646.tbl) | ISO/IEC 646 encoding, an older version of ASCII |
|
||||
| ISO/IEC 6937 | [`encodings/iso_6937.tbl`](encodings/iso_6937.tbl) | ISO/IEC 6937 encoding, an extension of ASCII containing additional character |
|
||||
| JIS 0201 | [`encodings/jis_x_0201.tbl`](encodings/jis_x_0201.tbl) | JIS X 0201 encoding in UTF-8 |
|
||||
| JIS X 0211 | [`encodings/jis_x_0211.tbl`](encodings/jis_x_0211.tbl) | JIS X 0211 encoding in UTF-8 |
|
||||
| JIS 0213 | [`encodings/jis_x_0213.tbl`](encodings/jis_x_0213.tbl) | JIS X 0213 encoding in UTF-8 |
|
||||
| Macintosh | [`encodings/macintosh.tbl`](encodings/macintosh.tbl) | Macintosh character encoding used by the Kermit protocol |
|
||||
| Pokémon (English, Generation 1) | [`encodings/pokegen1_en.tbl`](encodings/pokegen1_en.tbl) | Character encoding used by the English generation 1 Pokémon games |
|
||||
| Shift-JIS UTF-8 | [`encodings/shiftjis.tbl`](encodings/shiftjis.tbl) | Shift-JIS encoding in UTF-8 |
|
||||
| Thai | [`encodings/thai.tbl`](encodings/thai.tbl) | Thai character encoding |
|
||||
| Turkish ISO | [`encodings/turkish_iso.tbl`](encodings/turkish_iso.tbl) | Turkish ISO encoding |
|
||||
| Turkish Windows | [`encodings/turkish_windows.tbl`](encodings/turkish_windows.tbl) | Turkish Windows encoding |
|
||||
| UTF-8 | [`encodings/utf8.tbl`](encodings/utf8.tbl) | UTF-8 encoding |
|
||||
| Vietnamese | [`encodings/vietnamese.tbl`](encodings/vietnamese.tbl) | Vietnamese character encoding |
|
||||
|
||||
## Contributing
|
||||
|
||||
If you want to contribute a file to the database, please make a PR which adds it to the right folder and adds a new entry to the table in this readme.
|
||||
To take advantage of the automatic pattern testing, please consider adding a test file named `<pattern_name>.hexpat.<extension>` to the `/tests/patterns/test_data` directory. Try to keep this file as small as possible so the repository doesn't become excessively large
|
||||
|
||||
Thanks a lot :)
|
||||
Thanks a lot :)
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
00=
|
||||
08=\b
|
||||
09=\t
|
||||
0A=\n
|
||||
0B=\v
|
||||
0C=\f
|
||||
0D=\r
|
||||
08=␈
|
||||
09=␉
|
||||
0A=␊
|
||||
0B=␋
|
||||
0C=␌
|
||||
0D=␍
|
||||
20=
|
||||
21=!
|
||||
22="
|
||||
|
||||
11
includes/hex/dec.pat
Normal file
11
includes/hex/dec.pat
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/impl/imhex_check.pat>
|
||||
|
||||
namespace hex::dec {
|
||||
|
||||
fn demangle(str mangled_name) {
|
||||
return builtin::hex::dec::demangle(mangled_name);
|
||||
};
|
||||
|
||||
}
|
||||
23
includes/hex/type/mangled.pat
Normal file
23
includes/hex/type/mangled.pat
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <std/io.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
#include <hex/impl/imhex_check.pat>
|
||||
#include <hex/dec.pat>
|
||||
|
||||
namespace hex::type {
|
||||
|
||||
struct MangledName {
|
||||
char value[];
|
||||
} [[sealed, format("hex::type::impl::format_mangled_name")]];
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_mangled_name(ref MangledName name) {
|
||||
return hex::dec::demangle(name.value);
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
9
includes/std/array.pat
Normal file
9
includes/std/array.pat
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
namespace std {
|
||||
|
||||
struct Array<T, auto Size> {
|
||||
T data[Size] [[inline]];
|
||||
};
|
||||
|
||||
}
|
||||
@@ -30,7 +30,7 @@ namespace std::core {
|
||||
|
||||
|
||||
fn set_bitfield_order(BitfieldOrder order) {
|
||||
builtin::std::core::set_bitfield_order(order);
|
||||
builtin::std::core::set_bitfield_order(u32(order));
|
||||
};
|
||||
|
||||
fn get_bitfield_order() {
|
||||
@@ -54,4 +54,7 @@ namespace std::core {
|
||||
return builtin::std::core::formatted_value(pattern);
|
||||
};
|
||||
|
||||
fn is_valid_enum(ref auto pattern) {
|
||||
return builtin::std::core::is_valid_enum(pattern);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,28 +2,8 @@
|
||||
|
||||
namespace std::hash {
|
||||
|
||||
fn crc32(u128 address, u64 size, u32 init, u32 poly) {
|
||||
u8 byte;
|
||||
u32 crc, mask;
|
||||
|
||||
crc = init;
|
||||
|
||||
u64 i;
|
||||
while (i < size) {
|
||||
byte = std::mem::read_unsigned(address + i, 1);
|
||||
crc = crc ^ byte;
|
||||
|
||||
u8 j;
|
||||
while (j < 8) {
|
||||
mask = u32(-(crc & 1));
|
||||
crc = (crc >> 1) ^ (poly & mask);
|
||||
j = j + 1;
|
||||
}
|
||||
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
return u32(~crc);
|
||||
fn crc32(ref auto pattern, u32 init, u32 poly) {
|
||||
return builtin::std::hash::crc32(pattern, init, poly);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -15,7 +15,7 @@ namespace std::limits {
|
||||
};
|
||||
|
||||
fn s8_max() {
|
||||
return s8((u8_max() / 2));
|
||||
return s8((std::limits::u8_max() / 2));
|
||||
};
|
||||
|
||||
fn u16_min() {
|
||||
@@ -31,7 +31,7 @@ namespace std::limits {
|
||||
};
|
||||
|
||||
fn s16_max() {
|
||||
return s16((u16_max() / 2));
|
||||
return s16((std::limits::u16_max() / 2));
|
||||
};
|
||||
|
||||
fn u32_min() {
|
||||
@@ -47,7 +47,7 @@ namespace std::limits {
|
||||
};
|
||||
|
||||
fn s32_max() {
|
||||
return s32((u32_max() / 2));
|
||||
return s32((std::limits::u32_max() / 2));
|
||||
};
|
||||
|
||||
fn u64_min() {
|
||||
@@ -63,7 +63,7 @@ namespace std::limits {
|
||||
};
|
||||
|
||||
fn s64_max() {
|
||||
return s64((u64_max() / 2));
|
||||
return s64((std::limits::u64_max() / 2));
|
||||
};
|
||||
|
||||
fn u128_min() {
|
||||
@@ -79,7 +79,7 @@ namespace std::limits {
|
||||
};
|
||||
|
||||
fn s128_max() {
|
||||
return s128((u128_max() / 2));
|
||||
return s128((std::limits::u128_max() / 2));
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace std::mem {
|
||||
|
||||
using Section = u128;
|
||||
|
||||
enum Endian : u8 {
|
||||
Native = 0,
|
||||
Big = 1,
|
||||
@@ -47,4 +49,52 @@ namespace std::mem {
|
||||
return builtin::std::mem::read_string(address, size);
|
||||
};
|
||||
|
||||
|
||||
fn create_section(str name) {
|
||||
return builtin::std::mem::create_section(name);
|
||||
};
|
||||
|
||||
fn delete_section(Section section) {
|
||||
builtin::std::mem::delete_section(section);
|
||||
};
|
||||
|
||||
fn get_section_size(Section section) {
|
||||
return builtin::std::mem::get_section_size(section);
|
||||
};
|
||||
|
||||
fn copy_section_to_section(Section from_section, u64 from_address, Section to_section, u64 to_address, u64 size) {
|
||||
builtin::std::mem::copy_to_section(from_section, from_address, to_section, to_address, size);
|
||||
};
|
||||
|
||||
fn copy_value_to_section(ref auto value, Section to_section, u64 to_address) {
|
||||
builtin::std::mem::copy_value_to_section(value, to_section, to_address);
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct MagicSearch<auto Magic, T> {
|
||||
if ($ < (std::mem::size() - std::string::length(Magic) - 1)) {
|
||||
char __potentialMagic__[std::string::length(Magic)] [[hidden, no_unique_address]];
|
||||
|
||||
if (__potentialMagic__ == Magic) {
|
||||
T data [[inline]];
|
||||
} else {
|
||||
padding[1];
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
padding[1];
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
union Reinterpreter<From, To> {
|
||||
From from;
|
||||
To to;
|
||||
};
|
||||
|
||||
struct AlignTo<auto Alignment> {
|
||||
padding[Alignment - ((($ - 1) % Alignment) + 1)];
|
||||
} [[hidden, sealed]];
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,22 @@
|
||||
|
||||
namespace std::string {
|
||||
|
||||
struct SizedStringBase<SizeType, DataType> {
|
||||
SizeType size;
|
||||
DataType data[size];
|
||||
} [[sealed, format("std::string::impl::format_sized_string"), transform("std::string::impl::format_sized_string")]];
|
||||
|
||||
using SizedString<SizeType> = SizedStringBase<SizeType, char>;
|
||||
using SizedString16<SizeType> = SizedStringBase<SizeType, char16>;
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_sized_string(ref auto string) {
|
||||
return string.data;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
fn length(str string) {
|
||||
return builtin::std::string::length(string);
|
||||
};
|
||||
|
||||
@@ -15,12 +15,12 @@ namespace std::time {
|
||||
u16 yday;
|
||||
bool isdst;
|
||||
} [[sealed]];
|
||||
|
||||
|
||||
union TimeConverter {
|
||||
Time time;
|
||||
u128 value;
|
||||
};
|
||||
|
||||
|
||||
using EpochTime = u128;
|
||||
|
||||
enum TimeZone : u8 {
|
||||
@@ -28,44 +28,94 @@ namespace std::time {
|
||||
UTC
|
||||
};
|
||||
|
||||
bitfield DOSDate {
|
||||
day: 5;
|
||||
month: 4;
|
||||
year: 7;
|
||||
} [[sealed]];
|
||||
|
||||
bitfield DOSTime {
|
||||
seconds: 5;
|
||||
minutes: 6;
|
||||
hours: 5;
|
||||
} [[sealed]];
|
||||
|
||||
namespace impl {
|
||||
|
||||
union DOSDateConverter {
|
||||
DOSDate date;
|
||||
u16 value;
|
||||
};
|
||||
|
||||
union DOSTimeConverter {
|
||||
DOSTime time;
|
||||
u16 value;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
fn epoch() {
|
||||
return builtin::std::time::epoch();
|
||||
};
|
||||
|
||||
|
||||
fn to_local(EpochTime epoch_time) {
|
||||
TimeConverter converter;
|
||||
|
||||
|
||||
converter.value = builtin::std::time::to_local(epoch_time);
|
||||
|
||||
return converter.time;
|
||||
};
|
||||
|
||||
fn to_utc(EpochTime epoch_time) {
|
||||
TimeConverter converter;
|
||||
|
||||
converter.value = builtin::std::time::to_utc(epoch_time);
|
||||
|
||||
|
||||
return converter.time;
|
||||
};
|
||||
|
||||
fn to_utc(EpochTime epoch_time) {
|
||||
TimeConverter converter;
|
||||
|
||||
converter.value = builtin::std::time::to_utc(epoch_time);
|
||||
|
||||
return converter.time;
|
||||
};
|
||||
|
||||
fn now(TimeZone time_zone = TimeZone::Local) {
|
||||
TimeConverter converter;
|
||||
|
||||
|
||||
if (time_zone == TimeZone::Local)
|
||||
converter.value = builtin::std::time::to_local(std::time::epoch());
|
||||
else if (time_zone == TimeZone::UTC)
|
||||
converter.value = builtin::std::time::to_utc(std::time::epoch());
|
||||
else
|
||||
converter.value = 0x00;
|
||||
|
||||
|
||||
return converter.time;
|
||||
};
|
||||
|
||||
|
||||
fn to_dos_date(u16 value) {
|
||||
impl::DOSDateConverter converter;
|
||||
|
||||
converter.value = value;
|
||||
|
||||
return converter.date;
|
||||
};
|
||||
|
||||
fn to_dos_time(u16 value) {
|
||||
impl::DOSTimeConverter converter;
|
||||
|
||||
converter.value = value;
|
||||
|
||||
return converter.time;
|
||||
};
|
||||
|
||||
fn format(Time time, str format_string = "%c") {
|
||||
TimeConverter converter;
|
||||
converter.time = time;
|
||||
|
||||
|
||||
return builtin::std::time::format(format_string, converter.value);
|
||||
};
|
||||
}
|
||||
|
||||
fn format_dos_date(DOSDate date, str format_string = "{}/{}/{}") {
|
||||
return std::format(format_string, date.day, date.month, date.year + 1980);
|
||||
};
|
||||
|
||||
fn format_dos_time(DOSTime time, str format_string = "{:02}:{:02}:{:02}") {
|
||||
return std::format(format_string, time.hours, time.minutes, time.seconds * 2);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
31
includes/type/base.pat
Normal file
31
includes/type/base.pat
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <std/io.pat>
|
||||
#include <std/math.pat>
|
||||
|
||||
namespace type {
|
||||
|
||||
using Hex<T> = T [[format("type::impl::format_hex")]];
|
||||
using Oct<T> = T [[format("type::impl::format_oct")]];
|
||||
using Dec<T> = T [[format("type::impl::format_dec")]];
|
||||
using Bin<T> = T [[format("type::impl::format_bin")]];
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_number(auto value, str fmt) {
|
||||
bool negative = value < 0;
|
||||
|
||||
if (negative)
|
||||
return std::format("-" + fmt, std::math::abs(value));
|
||||
else
|
||||
return std::format(fmt, value);
|
||||
};
|
||||
|
||||
fn format_hex(auto value) { return type::impl::format_number(value, "0x{:02X}"); };
|
||||
fn format_oct(auto value) { return type::impl::format_number(value, "0o{:03o}"); };
|
||||
fn format_dec(auto value) { return type::impl::format_number(value, "{}"); };
|
||||
fn format_bin(auto value) { return type::impl::format_number(value, "0b{:08b}"); };
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
29
includes/type/bcd.pat
Normal file
29
includes/type/bcd.pat
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <std/io.pat>
|
||||
|
||||
namespace type {
|
||||
|
||||
struct BCD<auto Digits> {
|
||||
u8 bytes[Digits];
|
||||
} [[sealed, format_read("type::impl::format_bcd")]];
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_bcd(ref auto bcd) {
|
||||
str result;
|
||||
|
||||
for (u32 i = 0, i < sizeof(bcd.bytes), i += 1) {
|
||||
u8 byte = bcd.bytes[i];
|
||||
if (byte >= 10)
|
||||
return "Invalid";
|
||||
|
||||
result += std::format("{}", byte);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
48
includes/type/color.pat
Normal file
48
includes/type/color.pat
Normal file
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <std/io.pat>
|
||||
#include <std/core.pat>
|
||||
|
||||
namespace type {
|
||||
|
||||
struct RGB8 {
|
||||
u8 r, g, b;
|
||||
} [[sealed, format("type::impl::format_color")]];
|
||||
|
||||
struct RGBA8 {
|
||||
u8 r, g, b, a;
|
||||
} [[sealed, format("type::impl::format_color")]];
|
||||
|
||||
bitfield RGB565 {
|
||||
r : 5;
|
||||
g : 6;
|
||||
b : 5;
|
||||
} [[sealed, format("type::impl::format_color")]];
|
||||
|
||||
bitfield RGBA4 {
|
||||
r : 4;
|
||||
g : 4;
|
||||
b : 4;
|
||||
a : 4;
|
||||
} [[sealed, format("type::impl::format_color")]];
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_color(ref auto color) {
|
||||
if (!std::core::has_member(color, "a")) {
|
||||
return std::format("#{0:02X}{1:02X}{2:02X} | rgb({0}, {1}, {2})",
|
||||
color.r,
|
||||
color.g,
|
||||
color.b);
|
||||
} else {
|
||||
return std::format("#{0:02X}{1:02X}{2:02X}{3:02X} | rgba({0}, {1}, {2}, {3})",
|
||||
color.r,
|
||||
color.g,
|
||||
color.b,
|
||||
color.a);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,28 +2,52 @@
|
||||
|
||||
#include <std/io.pat>
|
||||
#include <std/math.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
namespace type {
|
||||
|
||||
using float16 = u16 [[format("type::impl::format_float16")]];
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_float16(float16 value) {
|
||||
float sign = (value >> 15) == 0b01 ? -1.0 : 1.0;
|
||||
float exponent = std::math::pow(2.0, float((value >> 10) & 0x1F) - 14);
|
||||
u16 mantissa = value & 0x3FF;
|
||||
|
||||
float fraction = 0;
|
||||
for (s8 i = 9, i >= 0, i -= 1) {
|
||||
if ((mantissa & (1 << i)) != 0) {
|
||||
fraction += 1.0 / std::math::pow(2.0, (10.0 - i));
|
||||
}
|
||||
}
|
||||
|
||||
return std::format("{:f}", sign * exponent * fraction);
|
||||
namespace impl {
|
||||
|
||||
union U32ToFloatConverter {
|
||||
u32 intValue;
|
||||
float floatValue;
|
||||
};
|
||||
|
||||
}
|
||||
fn format_float16(float16 value) {
|
||||
u32 sign = value >> 15;
|
||||
u32 exponent = (value >> 10) & 0x1F;
|
||||
u32 mantissa = value & 0x3FF;
|
||||
|
||||
u32 result = 0x00;
|
||||
|
||||
if (exponent == 0) {
|
||||
if (mantissa == 0) {
|
||||
result = sign << 31;
|
||||
} else {
|
||||
exponent = 0x7F - 14;
|
||||
|
||||
while ((mantissa & (1 << 10)) == 0) {
|
||||
exponent -= 1;
|
||||
mantissa <<= 1;
|
||||
}
|
||||
|
||||
mantissa &= 0x3FF;
|
||||
result = (sign << 31) | (exponent << 23) | (mantissa << 13);
|
||||
}
|
||||
} else if (exponent == 0x1F) {
|
||||
result = (sign << 31) | (0xFF << 23) | (mantissa << 13);
|
||||
} else {
|
||||
result = (sign << 31) | ((exponent + (0x7F - 15)) << 23) | (mantissa << 13);
|
||||
}
|
||||
|
||||
std::mem::Reinterpreter<u32, float> converter;
|
||||
converter.from = result;
|
||||
|
||||
return std::format("{}", converter.to);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,36 +4,53 @@
|
||||
|
||||
namespace type {
|
||||
|
||||
struct IPv4Address {
|
||||
u8 bytes[4];
|
||||
} [[sealed, format("type::impl::format_ipv4_address")]];
|
||||
struct IPv4Address {
|
||||
u8 bytes[4];
|
||||
} [[sealed, format("type::impl::format_ipv4_address")]];
|
||||
|
||||
struct IPv6Address {
|
||||
u16 words[8];
|
||||
} [[sealed, format("type::impl::format_ipv6_address")]];
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_ipv4_address(IPv4Address address) {
|
||||
return std::format("{}.{}.{}.{}",
|
||||
address.bytes[0],
|
||||
address.bytes[1],
|
||||
address.bytes[2],
|
||||
address.bytes[3]);
|
||||
};
|
||||
u16 words[8];
|
||||
} [[sealed, format("type::impl::format_ipv6_address")]];
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_ipv4_address(IPv4Address address) {
|
||||
return std::format("{}.{}.{}.{}",
|
||||
address.bytes[0],
|
||||
address.bytes[1],
|
||||
address.bytes[2],
|
||||
address.bytes[3]);
|
||||
};
|
||||
|
||||
fn format_ipv6_address(IPv6Address address) {
|
||||
return std::format("{:04X}:{:04X}:{:04X}:{:04X}:{:04X}:{:04X}:{:04X}:{:04X}",
|
||||
address.words[0],
|
||||
address.words[1],
|
||||
address.words[2],
|
||||
address.words[3],
|
||||
address.words[4],
|
||||
address.words[5],
|
||||
address.words[6],
|
||||
address.words[7]);
|
||||
};
|
||||
|
||||
}
|
||||
str result;
|
||||
|
||||
bool hadZeros = false;
|
||||
s8 startIndex = -1;
|
||||
|
||||
for (u8 i = 0, i < 8, i += 1) {
|
||||
if (address.words[i] == 0x00 && !hadZeros) {
|
||||
hadZeros = true;
|
||||
startIndex = i;
|
||||
|
||||
while (i < 7) {
|
||||
if (address.words[i + 1] != 0x00)
|
||||
break;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
if (startIndex == 0 || i == 7)
|
||||
result += ":";
|
||||
} else {
|
||||
result += std::format("{:04X}", address.words[i]);
|
||||
}
|
||||
|
||||
result += ":";
|
||||
}
|
||||
|
||||
return std::string::substr(result, 0, std::string::length(result) - 1);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
19
includes/type/magic.pat
Normal file
19
includes/type/magic.pat
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <std/string.pat>
|
||||
#include <std/sys.pat>
|
||||
|
||||
namespace type {
|
||||
|
||||
struct Magic<auto ExpectedValue> {
|
||||
char value[std::string::length(ExpectedValue)];
|
||||
std::assert(value == ExpectedValue, std::format("Invalid magic value! Expected \"{}\", got \"{}\".", ExpectedValue, value));
|
||||
} [[sealed, format("type::impl::format_magic")]];
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_magic(ref auto magic) {
|
||||
return magic.value;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
#include <std/io.pat>
|
||||
|
||||
namespace type {
|
||||
|
||||
using Size8 = u8 [[format("type::impl::size_formatter")]];
|
||||
using Size16 = u16 [[format("type::impl::size_formatter")]];
|
||||
using Size32 = u32 [[format("type::impl::size_formatter")]];
|
||||
using Size64 = u64 [[format("type::impl::size_formatter")]];
|
||||
using Size128 = u128 [[format("type::impl::size_formatter")]];
|
||||
using Size<T> = T [[format("type::impl::size_formatter")]];
|
||||
|
||||
using Size8 = Size<u8>;
|
||||
using Size16 = Size<u16>;
|
||||
using Size32 = Size<u32>;
|
||||
using Size64 = Size<u64>;
|
||||
using Size128 = Size<u128>;
|
||||
|
||||
namespace impl {
|
||||
|
||||
@@ -42,4 +46,4 @@ namespace type {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -4,16 +4,26 @@
|
||||
#include <std/time.pat>
|
||||
|
||||
namespace type {
|
||||
|
||||
|
||||
using time32_t = u32 [[format("type::impl::format_time_t")]];
|
||||
using time64_t = u64 [[format("type::impl::format_time_t")]];
|
||||
using dosdate16_t = u16 [[format("type::impl::format_dosdate16_t")]];
|
||||
using dostime16_t = u16 [[format("type::impl::format_dostime16_t")]];
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_time_t(u128 value) {
|
||||
fn format_time_t(u128 value) {
|
||||
return std::time::format(std::time::to_utc(value));
|
||||
};
|
||||
|
||||
fn format_dosdate16_t(u16 value) {
|
||||
return std::time::format_dos_date(std::time::to_dos_date(value));
|
||||
};
|
||||
|
||||
fn format_dostime16_t(u16 value) {
|
||||
return std::time::format_dos_time(std::time::to_dos_time(value));
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
using uchar = u8;
|
||||
using ubyte = u8;
|
||||
using UCHAR = u8;
|
||||
using ubyte = u8;
|
||||
using UBYTE = u8;
|
||||
|
||||
|
||||
using short = s16;
|
||||
@@ -59,4 +59,4 @@
|
||||
// using double = double;
|
||||
using DOUBLE = double;
|
||||
|
||||
// }
|
||||
// }
|
||||
|
||||
395
patterns/chm.hexpat
Normal file
395
patterns/chm.hexpat
Normal file
@@ -0,0 +1,395 @@
|
||||
#include <type/magic.pat>
|
||||
#include <type/size.pat>
|
||||
#include <type/guid.pat>
|
||||
#include <type/leb128.pat>
|
||||
#include <std/sys.pat>
|
||||
|
||||
enum WindowsLanguageId : u32 {
|
||||
Arabic_SaudiArabia = 0x401,
|
||||
Arabic_Iraq = 0x801,
|
||||
Arabic_Egypt = 0xc01,
|
||||
Arabic_Libya = 0x1001,
|
||||
Arabic_Algeria = 0x1401,
|
||||
Arabic_Morocco = 0x1801,
|
||||
Arabic_Tunisia = 0x1c01,
|
||||
Arabic_Oman = 0x2001,
|
||||
Arabic_Yemen = 0x2401,
|
||||
Arabic_Syria = 0x2801,
|
||||
Arabic_Jordan = 0x2c01,
|
||||
Arabic_Lebanon = 0x3001,
|
||||
Arabic_Kuwait = 0x3401,
|
||||
Arabic_UAE = 0x3801,
|
||||
Arabic_Bahrain = 0x3c01,
|
||||
Arabic_Qatar = 0x4001,
|
||||
Bulgarian = 0x402,
|
||||
Catalan = 0x403,
|
||||
Valencian = 0x803,
|
||||
Chinese_Taiwan = 0x404,
|
||||
Chinese_PRC = 0x804,
|
||||
Chinese_HongKongSAR = 0xc04,
|
||||
Chinese_Singapore = 0x1004,
|
||||
Chinese_MacaoSAR = 0x1404,
|
||||
Czech = 0x405,
|
||||
Danish = 0x406,
|
||||
German_Germany = 0x407,
|
||||
German_Switzerland = 0x807,
|
||||
German_Austria = 0xc07,
|
||||
German_Luxembourg = 0x1007,
|
||||
German_Liechtenstein = 0x1407,
|
||||
Greek = 0x408,
|
||||
English_UnitedStates = 0x409,
|
||||
English_UnitedKingdom = 0x809,
|
||||
English_Australia = 0xc09,
|
||||
English_Canada = 0x1009,
|
||||
English_NewZealand = 0x1409,
|
||||
English_Ireland = 0x1809,
|
||||
English_SouthAfrica = 0x1c09,
|
||||
English_Jamaica = 0x2009,
|
||||
English_Caribbean = 0x2409,
|
||||
English_Belize = 0x2809,
|
||||
English_TrinidadandTobago = 0x2c09,
|
||||
English_Zimbabwe = 0x3009,
|
||||
English_Philippines = 0x3409,
|
||||
English_Indonesia = 0x3809,
|
||||
English_HongKongSAR = 0x3c09,
|
||||
English_India = 0x4009,
|
||||
English_Malaysia = 0x4409,
|
||||
English_Singapore = 0x4809,
|
||||
Spanish_SpainTraditionalSort = 0x40a,
|
||||
Spanish_Mexico = 0x80a,
|
||||
Spanish_Spain = 0xc0a,
|
||||
Spanish_Guatemala = 0x100a,
|
||||
Spanish_CostaRica = 0x140a,
|
||||
Spanish_Panama = 0x180a,
|
||||
Spanish_DominicanRepublic = 0x1c0a,
|
||||
Spanish_Venezuela = 0x200a,
|
||||
Spanish_Colombia = 0x240a,
|
||||
Spanish_Peru = 0x280a,
|
||||
Spanish_Argentina = 0x2c0a,
|
||||
Spanish_Ecuador = 0x300a,
|
||||
Spanish_Chile = 0x340a,
|
||||
Spanish_Uruguay = 0x380a,
|
||||
Spanish_Paraguay = 0x3c0a,
|
||||
Spanish_Bolivia = 0x400a,
|
||||
Spanish_ElSalvador = 0x440a,
|
||||
Spanish_Honduras = 0x480a,
|
||||
Spanish_Nicaragua = 0x4c0a,
|
||||
Spanish_PuertoRico = 0x500a,
|
||||
Spanish_UnitedStates = 0x540a,
|
||||
Spanish_LatinAmerica = 0x580a,
|
||||
Finnish = 0x40b,
|
||||
French_France = 0x40c,
|
||||
French_Belgium = 0x80c,
|
||||
French_Canada = 0xc0c,
|
||||
French_Switzerland = 0x100c,
|
||||
French_Luxembourg = 0x140c,
|
||||
French_Monaco = 0x180c,
|
||||
French_Caribbean = 0x1c0c,
|
||||
French_Reunion = 0x200c,
|
||||
French_CongoDRC = 0x240c,
|
||||
French_Senegal = 0x280c,
|
||||
French_Cameroon = 0x2c0c,
|
||||
French_CoteDIvoire = 0x300c,
|
||||
French_Mali = 0x340c,
|
||||
French_Morocco = 0x380c,
|
||||
French_Haiti = 0x3c0c,
|
||||
Hebrew = 0x40d,
|
||||
Hungarian = 0x40e,
|
||||
Icelandic = 0x40f,
|
||||
Italian_Italy = 0x410,
|
||||
Italian_Switzerland = 0x810,
|
||||
Japanese = 0x411,
|
||||
Korean = 0x412,
|
||||
Dutch_Netherlands = 0x413,
|
||||
Dutch_Belgium = 0x813,
|
||||
Norwegian_Bokmal = 0x414,
|
||||
Norwegian_Nynorsk = 0x814,
|
||||
Polish = 0x415,
|
||||
Portuguese_Brazil = 0x416,
|
||||
Portuguese_Portugal = 0x816,
|
||||
Romansh = 0x417,
|
||||
Romanian = 0x418,
|
||||
Romanian_Moldova = 0x818,
|
||||
Russian = 0x419,
|
||||
Russian_Moldova = 0x819,
|
||||
Croatian_Croatia = 0x41a,
|
||||
Serbian_LatinSerbiaandMontenegroFormer = 0x81a,
|
||||
Serbian_CyrillicSerbiaAndMontenegroFormer = 0xc1a,
|
||||
Croatian_BosniaAndHerzegovina = 0x101a,
|
||||
Bosnian_Latin = 0x141a,
|
||||
Serbian_LatinBosniaAndHerzegovina = 0x181a,
|
||||
Serbian_CyrillicBosniaAndHerzegovina = 0x1c1a,
|
||||
Bosnian_Cyrillic = 0x201a,
|
||||
Serbian_LatinSerbia = 0x241a,
|
||||
Serbian_CyrillicSerbia = 0x281a,
|
||||
Serbian_LatinMontenegro = 0x2c1a,
|
||||
Serbian_CyrillicMontenegro = 0x301a,
|
||||
Slovak = 0x41b,
|
||||
Albanian = 0x41c,
|
||||
Swedish_Sweden = 0x41d,
|
||||
Swedish_Finland = 0x81d,
|
||||
Thai = 0x41e,
|
||||
Turkish = 0x41f,
|
||||
Urdu_Pakistan = 0x420,
|
||||
Urdu_India = 0x820,
|
||||
Indonesian = 0x421,
|
||||
Ukrainian = 0x422,
|
||||
Belarusian = 0x423,
|
||||
Slovenian = 0x424,
|
||||
Estonian = 0x425,
|
||||
Latvian = 0x426,
|
||||
Lithuanian = 0x427,
|
||||
Tajik = 0x428,
|
||||
Persian = 0x429,
|
||||
Vietnamese = 0x42a,
|
||||
Armenian = 0x42b,
|
||||
Azerbaijani_Latin = 0x42c,
|
||||
Azerbaijani_Cyrillic = 0x82c,
|
||||
Basque = 0x42d,
|
||||
UpperSorbian = 0x42e,
|
||||
LowerSorbian = 0x82e,
|
||||
Macedonian = 0x42f,
|
||||
Sesotho_SouthAfrica = 0x430,
|
||||
Xitsonga = 0x431,
|
||||
Setswana_SouthAfrica = 0x432,
|
||||
Setswana_Botswana = 0x832,
|
||||
Venda = 0x433,
|
||||
isiXhosa = 0x434,
|
||||
isiZulu = 0x435,
|
||||
Afrikaans = 0x436,
|
||||
Georgian = 0x437,
|
||||
Faroese = 0x438,
|
||||
Hindi = 0x439,
|
||||
Maltese = 0x43a,
|
||||
NorthernSami_Norway = 0x43b,
|
||||
NorthernSami_Sweden = 0x83b,
|
||||
NorthernSami_Finland = 0xc3b,
|
||||
LuleSami_Norway = 0x103b,
|
||||
LuleSami_Sweden = 0x143b,
|
||||
SouthernSami_Norway = 0x183b,
|
||||
SouthernSami_Sweden = 0x1c3b,
|
||||
SkoltSami_Finland = 0x203b,
|
||||
InariSami_Finland = 0x243b,
|
||||
Irish = 0x83c,
|
||||
Yiddish = 0x43d,
|
||||
Malay_Malaysia = 0x43e,
|
||||
Malay_BruneiDarussalam = 0x83e,
|
||||
Kazakh = 0x43f,
|
||||
Kyrgyz = 0x440,
|
||||
Kiswahili = 0x441,
|
||||
Turkmen = 0x442,
|
||||
Uzbek_Latin = 0x443,
|
||||
Uzbek_Cyrillic = 0x843,
|
||||
Tatar = 0x444,
|
||||
Bangla_India = 0x445,
|
||||
Bangla_Bangladesh = 0x845,
|
||||
Punjabi_India = 0x446,
|
||||
Punjabi_Pakistan = 0x846,
|
||||
Gujarati = 0x447,
|
||||
Odia = 0x448,
|
||||
Tamil_India = 0x449,
|
||||
Tamil_SriLanka = 0x849,
|
||||
Telugu = 0x44a,
|
||||
Kannada = 0x44b,
|
||||
Malayalam = 0x44c,
|
||||
Assamese = 0x44d,
|
||||
Marathi = 0x44e,
|
||||
Sanskrit = 0x44f,
|
||||
Mongolian_Cyrillic = 0x450,
|
||||
Mongolian_TraditionalMongolianPRC = 0x850,
|
||||
Mongolian_TraditionalMongolianMongolia = 0xc50,
|
||||
Tibetan_PRC = 0x451,
|
||||
Welsh = 0x452,
|
||||
Khmer = 0x453,
|
||||
Lao = 0x454,
|
||||
Burmese = 0x455,
|
||||
Galician = 0x456,
|
||||
Konkani = 0x457,
|
||||
Manipuri = 0x458,
|
||||
Sindhi_Devanagari = 0x459,
|
||||
Sindhi_Arabic = 0x859,
|
||||
Syriac = 0x45a,
|
||||
Sinhala = 0x45b,
|
||||
Cherokee_Cherokee = 0x45c,
|
||||
Inuktitut_Syllabics = 0x45d,
|
||||
Inuktitut_Latin = 0x85d,
|
||||
Amharic = 0x45e,
|
||||
Tamazight_ArabicMorocco = 0x45f,
|
||||
Tamazight_LatinAlgeria = 0x85f,
|
||||
Tamazight_TifinaghMorocco = 0x105f,
|
||||
Kashmiri_Arabic = 0x460,
|
||||
Kashmiri = 0x860,
|
||||
Nepali = 0x461,
|
||||
Nepali_India = 0x861,
|
||||
Frisian = 0x462,
|
||||
Pashto = 0x463,
|
||||
Filipino = 0x464,
|
||||
Divehi = 0x465,
|
||||
Edo = 0x466,
|
||||
Fulah_Nigeria = 0x467,
|
||||
Fulah_LatinSenegal = 0x867,
|
||||
Hausa = 0x468,
|
||||
Ibibio_Nigeria = 0x469,
|
||||
Yoruba = 0x46a,
|
||||
Quechua_Bolivia = 0x46b,
|
||||
Quechua_Ecuador = 0x86b,
|
||||
Quechua_Peru = 0xc6b,
|
||||
SesothoSaLeboa = 0x46c,
|
||||
Bashkir = 0x46d,
|
||||
Luxembourgish = 0x46e,
|
||||
Greenlandic = 0x46f,
|
||||
Igbo = 0x470,
|
||||
Kanuri = 0x471,
|
||||
Oromo = 0x472,
|
||||
Tigrinya_Ethiopia = 0x473,
|
||||
Tigrinya_Eritrea = 0x873,
|
||||
Guarani = 0x474,
|
||||
Hawaiian = 0x475,
|
||||
Latin = 0x476,
|
||||
Somali = 0x477,
|
||||
Yi_PRC = 0x478,
|
||||
Papiamentu = 0x479,
|
||||
Mapudungun = 0x47a,
|
||||
Mohawk = 0x47c,
|
||||
Breton = 0x47e,
|
||||
Uyghur_PRC = 0x480,
|
||||
Maori = 0x481,
|
||||
Occitan = 0x482,
|
||||
Corsican = 0x483,
|
||||
Alsatian = 0x484,
|
||||
Sakha = 0x485,
|
||||
Kiche = 0x486,
|
||||
Kinyarwanda = 0x487,
|
||||
Wolof = 0x488,
|
||||
Dari = 0x48c,
|
||||
ScottishGaelic_UnitedKingdom = 0x491,
|
||||
CentralKurdish_Iraq = 0x492
|
||||
};
|
||||
|
||||
struct DirectoryListingEntry {
|
||||
type::LEB128 nameLength;
|
||||
char name[nameLength];
|
||||
type::LEB128 contentSection;
|
||||
type::LEB128 offset;
|
||||
type::LEB128 length;
|
||||
};
|
||||
|
||||
struct DirectoryIndexEntry {
|
||||
type::LEB128 nameLength;
|
||||
char name[nameLength];
|
||||
type::LEB128 directoryListingChunk;
|
||||
};
|
||||
|
||||
struct ListingChunk {
|
||||
char magic[4];
|
||||
|
||||
if (magic == "PMGL") {
|
||||
type::Size<u32> freeSpaceLength;
|
||||
u32;
|
||||
u32 prevChunkNumber, nextChunkNumber;
|
||||
|
||||
u16 directoryListingEntryCount @ addressof(this) + parent.directoryChunkSize - 2;
|
||||
u16 offsets[(freeSpaceLength - 2) / 2] @ addressof(directoryListingEntryCount) - (freeSpaceLength - 2);
|
||||
|
||||
DirectoryListingEntry directories[directoryListingEntryCount];
|
||||
|
||||
$ = addressof(directoryListingEntryCount) + sizeof(directoryListingEntryCount);
|
||||
} else if (magic == "PMGI") {
|
||||
type::Size<u32> freeSpaceLength;
|
||||
|
||||
u16 directoryIndexEntryCount @ addressof(this) + parent.directoryChunkSize - 2;
|
||||
u16 offsets[(freeSpaceLength - 2) / 2] @ addressof(directoryIndexEntryCount) - (freeSpaceLength - 2);
|
||||
|
||||
DirectoryIndexEntry indexes[directoryIndexEntryCount];
|
||||
|
||||
$ = addressof(directoryIndexEntryCount) + sizeof(directoryIndexEntryCount);
|
||||
} else {
|
||||
std::error("Invalid chunk magic!");
|
||||
}
|
||||
};
|
||||
|
||||
struct HeaderSection {
|
||||
char magic[4];
|
||||
|
||||
if (magic == "\xFE\x01\x00\x00") {
|
||||
u32;
|
||||
type::Size<u64> fileSize;
|
||||
u32;
|
||||
u32;
|
||||
} else if (magic == "ITSP") {
|
||||
u32 version;
|
||||
type::Size<u32> directoryHeaderLength1;
|
||||
u32;
|
||||
u32 directoryChunkSize;
|
||||
u32 quickRefSectionDensity;
|
||||
u32 indexTreeDepth;
|
||||
u32 rootIndexChunkNumber;
|
||||
u32 firstPMGLChunkNumber;
|
||||
u32 lastPMGLChunkNumber;
|
||||
u32;
|
||||
u32 directoryChunkCount;
|
||||
WindowsLanguageId languageId;
|
||||
type::GUID guid;
|
||||
type::Size<u32> directoryHeaderLength2;
|
||||
u32;
|
||||
u32;
|
||||
u32;
|
||||
|
||||
ListingChunk chunk[directoryChunkCount];
|
||||
} else {
|
||||
std::error("Invalid header section magic!");
|
||||
}
|
||||
};
|
||||
|
||||
struct HeaderSectionTableEntry {
|
||||
u64 offset;
|
||||
type::Size<u64> size;
|
||||
|
||||
HeaderSection headerSection @ offset;
|
||||
};
|
||||
|
||||
struct NameListEntry {
|
||||
type::Size<u16> nameLength;
|
||||
char16 name[nameLength];
|
||||
padding[2];
|
||||
};
|
||||
|
||||
struct NameListFile {
|
||||
u16 fileLengthWords;
|
||||
u16 entriesInFile;
|
||||
|
||||
NameListEntry nameList[entriesInFile];
|
||||
|
||||
padding[0x2E];
|
||||
};
|
||||
|
||||
struct SectionData {
|
||||
u32 fileLengthWords;
|
||||
type::Magic<"LZXC"> magic;
|
||||
u32 version;
|
||||
u32 lzxResetInterval;
|
||||
type::Size<u32> windowSize;
|
||||
type::Size<u32> cacheSize;
|
||||
u32;
|
||||
};
|
||||
|
||||
struct Content {
|
||||
NameListFile nameListFile;
|
||||
SectionData sectionData;
|
||||
};
|
||||
|
||||
struct CHM {
|
||||
type::Magic<"ITSF"> magic;
|
||||
u32 version;
|
||||
type::Size<u32> headerSize;
|
||||
u32;
|
||||
be u32 timeStamp;
|
||||
WindowsLanguageId languageId;
|
||||
type::GUID guids[2];
|
||||
|
||||
HeaderSectionTableEntry headerSectionTable[2];
|
||||
|
||||
Content *dataOffset : u64;
|
||||
};
|
||||
|
||||
CHM chm @ 0x00;
|
||||
209
patterns/coff.hexpat
Normal file
209
patterns/coff.hexpat
Normal file
@@ -0,0 +1,209 @@
|
||||
#pragma MIME application/x-coff
|
||||
|
||||
#include <type/time.pat>
|
||||
#include <type/size.pat>
|
||||
|
||||
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<u32> virtualSize;
|
||||
u32 virtualAddress;
|
||||
type::Size<u32> 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;
|
||||
66
patterns/cpio.pat
Normal file
66
patterns/cpio.pat
Normal file
@@ -0,0 +1,66 @@
|
||||
#include <type/base.pat>
|
||||
|
||||
#include <std/time.pat>
|
||||
#include <std/core.pat>
|
||||
#include <std/sys.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
#pragma MIME application/x-cpio
|
||||
|
||||
namespace old_binary {
|
||||
|
||||
using Time = u32 [[format("old_binary::format_time")]];
|
||||
|
||||
fn swap_32bit(u32 value) {
|
||||
return ((value >> 16) & 0xFFFF) | ((value & 0xFFFF) << 16);
|
||||
};
|
||||
|
||||
fn format_time(u32 value) {
|
||||
return std::time::format(std::time::to_utc(swap_32bit(value)));
|
||||
};
|
||||
|
||||
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]];
|
||||
|
||||
struct CpioHeader {
|
||||
type::Oct<u16> magic;
|
||||
if (magic == be u16(0o070707))
|
||||
std::core::set_endian(std::mem::Endian::Big);
|
||||
else if (magic == le u16(0o070707))
|
||||
std::core::set_endian(std::mem::Endian::Little);
|
||||
else
|
||||
std::error("Invalid CPIO Magic!");
|
||||
|
||||
u16 dev;
|
||||
u16 ino;
|
||||
Mode mode;
|
||||
u16 uid;
|
||||
u16 gid;
|
||||
u16 nlink;
|
||||
u16 rdev;
|
||||
Time mtime;
|
||||
u16 namesize;
|
||||
SwappedU32 filesize;
|
||||
};
|
||||
|
||||
struct Cpio {
|
||||
CpioHeader header;
|
||||
char pathname[header.namesize % 2 == 0 ? header.namesize : header.namesize + 1];
|
||||
u8 data[header.filesize % 2 == 0 ? header.filesize : header.filesize + 1];
|
||||
|
||||
if (pathname == "TRAILER!!!\x00\x00")
|
||||
break;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
old_binary::Cpio cpio[while(true)] @ 0x00;
|
||||
@@ -560,7 +560,7 @@ struct Elf32_Phdr {
|
||||
PF p_flags;
|
||||
Elf32_Word p_align;
|
||||
|
||||
if (p_offset > 0 && p_filesz > 0 && (p_offset + p_filesz) < std::mem::data_size() && p_filesz < std::mem::data_size())
|
||||
if (p_offset > 0 && p_filesz > 0 && (p_offset + p_filesz) < std::mem::size() && p_filesz < std::mem::size())
|
||||
u8 p_data[p_filesz] @ p_offset;
|
||||
};
|
||||
|
||||
@@ -731,7 +731,9 @@ struct ELF {
|
||||
std::core::set_endian(std::mem::Endian::Big);
|
||||
|
||||
if (e_ident.EI_CLASS == EI_CLASS::ELFCLASS32) {
|
||||
Elf32_Ehdr header;
|
||||
Elf32_Ehdr ehdr;
|
||||
Elf32_Phdr phdr[ehdr.e_phnum] @ ehdr.e_phoff;
|
||||
Elf32_Shdr shdr[ehdr.e_shnum] @ ehdr.e_shoff;
|
||||
} else if (e_ident.EI_CLASS == EI_CLASS::ELFCLASS64) {
|
||||
Elf64_Ehdr ehdr;
|
||||
Elf64_Phdr phdr[ehdr.e_phnum] @ ehdr.e_phoff;
|
||||
|
||||
70
patterns/fdt.pat
Normal file
70
patterns/fdt.pat
Normal file
@@ -0,0 +1,70 @@
|
||||
#pragma endian big
|
||||
|
||||
#include <std/sys.pat>
|
||||
#include <std/io.pat>
|
||||
|
||||
#include <type/magic.pat>
|
||||
#include <type/size.pat>
|
||||
|
||||
struct FDTHeader {
|
||||
type::Magic<"\xD0\x0D\xFE\xED"> magic;
|
||||
u32 totalsize;
|
||||
u32 off_dt_struct;
|
||||
u32 off_dt_strings;
|
||||
u32 off_mem_rsvmap;
|
||||
u32 version;
|
||||
u32 last_comp_version;
|
||||
u32 boot_cpuid_phys;
|
||||
u32 size_dt_strings;
|
||||
u32 size_dt_struct;
|
||||
};
|
||||
|
||||
struct AlignTo<auto Alignment> {
|
||||
padding[Alignment- ((($ - 1) % Alignment) + 1)];
|
||||
};
|
||||
|
||||
struct FDTReserveEntry {
|
||||
u64 address;
|
||||
type::Size<u64> size;
|
||||
|
||||
if (address == 0x00 && size == 0x00)
|
||||
break;
|
||||
};
|
||||
|
||||
enum FDTToken : u32 {
|
||||
FDT_BEGIN_NODE = 0x00000001,
|
||||
FDT_END_NODE = 0x00000002,
|
||||
FDT_PROP = 0x00000003,
|
||||
FDT_NOP = 0x00000004,
|
||||
FDT_END = 0x00000009
|
||||
};
|
||||
|
||||
struct FDTStructureBlock {
|
||||
FDTToken token;
|
||||
if (token == FDTToken::FDT_BEGIN_NODE) {
|
||||
char nodeName[];
|
||||
AlignTo<4>;
|
||||
} else if (token == FDTToken::FDT_END) {
|
||||
break;
|
||||
} else if (token == FDTToken::FDT_PROP) {
|
||||
u32 len;
|
||||
u32 nameoff;
|
||||
char value[len];
|
||||
AlignTo<4>;
|
||||
char name[] @ parent.header.off_dt_strings + nameoff;
|
||||
} else if (token == FDTToken::FDT_NOP || token == FDTToken::FDT_END_NODE) {
|
||||
// Nothing to do
|
||||
} else {
|
||||
std::error(std::format("Invalid token at address 0x{:02X}", addressof(token)));
|
||||
}
|
||||
};
|
||||
|
||||
struct FDT {
|
||||
FDTHeader header;
|
||||
std::assert(header.version == 17, "Unsupported format version");
|
||||
|
||||
FDTStructureBlock structureBlocks[while(true)] @ header.off_dt_struct;
|
||||
FDTReserveEntry reserveEntries[while(true)] @ header.off_mem_rsvmap;
|
||||
};
|
||||
|
||||
FDT fdt @ 0x00;
|
||||
153
patterns/gif.hexpat
Normal file
153
patterns/gif.hexpat
Normal file
@@ -0,0 +1,153 @@
|
||||
#include <std/mem.pat>
|
||||
|
||||
#pragma MIME image/gif
|
||||
|
||||
#pragma bitfield_order left_to_right
|
||||
|
||||
// gif89a
|
||||
|
||||
struct data_subblock_t {
|
||||
u8 block_size;
|
||||
u8 data_values[block_size];
|
||||
};
|
||||
|
||||
struct data_subblocks_t {
|
||||
data_subblock_t data[while (std::mem::read_unsigned($, 1) != 0x00)];
|
||||
u8 block_terminator; // 0x00
|
||||
} [[inline]];
|
||||
|
||||
struct header_t {
|
||||
char header[3];
|
||||
char version[3];
|
||||
};
|
||||
|
||||
bitfield lsd_fields_t {
|
||||
global_color_table_flag : 1;
|
||||
color_resolution : 3;
|
||||
sort_flag : 1;
|
||||
size_of_global_color_table : 3;
|
||||
} [[inline]];
|
||||
|
||||
struct logical_screen_descriptor_t {
|
||||
u16 width;
|
||||
u16 height;
|
||||
lsd_fields_t fields;
|
||||
u8 background_color_index;
|
||||
u8 pixel_aspect_ratio;
|
||||
};
|
||||
|
||||
struct color_table_entry_t {
|
||||
u8 red;
|
||||
u8 green;
|
||||
u8 blue;
|
||||
};
|
||||
|
||||
bitfield gce_fields_t {
|
||||
padding : 3;
|
||||
disposal_method : 3;
|
||||
user_input_flag : 1;
|
||||
transparent_color_flag : 1;
|
||||
} [[inline]];
|
||||
|
||||
struct graphic_coltrol_extension_t {
|
||||
u8 extension_introducer; // 0x21
|
||||
u8 graphic_control_label; // 0xf9
|
||||
u8 block_size;
|
||||
gce_fields_t fields;
|
||||
u16 delay_time;
|
||||
u8 transparent_color_index;
|
||||
u8 block_terminator;
|
||||
};
|
||||
|
||||
struct comment_extension_t {
|
||||
u8 extension_introducer; // 0x21
|
||||
u8 comment_label; // 0xfe
|
||||
data_subblocks_t comment_data;
|
||||
};
|
||||
|
||||
struct plaintext_extension_t {
|
||||
u8 extension_introducer; // 0x21
|
||||
u8 plain_text_label; // 0x01
|
||||
|
||||
u8 block_size; // 12
|
||||
u16 text_grid_left_position;
|
||||
u16 text_grid_top_position;
|
||||
u16 text_grid_width;
|
||||
u16 text_grid_height;
|
||||
u8 character_cell_width;
|
||||
u8 character_cell_height;
|
||||
u8 text_foreground_color_index;
|
||||
u8 text_background_color_index;
|
||||
data_subblocks_t plain_text_data;
|
||||
};
|
||||
|
||||
struct application_extension_t {
|
||||
u8 extension_introducer; // 0x21
|
||||
u8 extension_label; // 0xff
|
||||
|
||||
u8 block_size; // 11
|
||||
u8 application_identifier[8];
|
||||
u8 application_authentication_code[3];
|
||||
|
||||
data_subblocks_t data;
|
||||
};
|
||||
|
||||
bitfield id_fields_t {
|
||||
local_color_table : 1;
|
||||
interlace_flag : 1;
|
||||
sort_fla : 1;
|
||||
padding : 2;
|
||||
size_of_local_color_table : 3;
|
||||
} [[inline]];
|
||||
|
||||
struct image_descriptor_t {
|
||||
u8 image_separator; // 0x2c
|
||||
u16 image_left_position;
|
||||
u16 image_top_position;
|
||||
u16 image_width;
|
||||
u16 image_height;
|
||||
id_fields_t fields;
|
||||
};
|
||||
|
||||
struct table_based_image_t {
|
||||
u8 lzw_minimum_code_size;
|
||||
data_subblocks_t data;
|
||||
};
|
||||
|
||||
struct gif_block_t {
|
||||
if (std::mem::read_unsigned($, 1) == 0x21) {
|
||||
if (std::mem::read_unsigned($+1, 1) == 0x01) {
|
||||
plaintext_extension_t plaintext_extension;
|
||||
}
|
||||
else if (std::mem::read_unsigned($+1, 1) == 0xf9) {
|
||||
graphic_coltrol_extension_t graphic_coltrol_extension;
|
||||
}
|
||||
else if (std::mem::read_unsigned($+1, 1) == 0xfe) {
|
||||
comment_extension_t comment;
|
||||
} else {
|
||||
application_extension_t application_extension;
|
||||
}
|
||||
}
|
||||
else if (std::mem::read_unsigned($, 1) == 0x2c) {
|
||||
image_descriptor_t image_descriptor;
|
||||
if (image_descriptor.fields.local_color_table) {
|
||||
color_table_entry_t local_color_table[1<<(image_descriptor.fields.size_of_local_color_table + 1)];
|
||||
}
|
||||
table_based_image_t image;
|
||||
}
|
||||
} [[inline]];
|
||||
|
||||
struct gif_t {
|
||||
header_t header;
|
||||
logical_screen_descriptor_t logical_screen_descriptor;
|
||||
if (logical_screen_descriptor.fields.global_color_table_flag) {
|
||||
color_table_entry_t global_color_table[1<<(logical_screen_descriptor.fields.size_of_global_color_table + 1)];
|
||||
}
|
||||
|
||||
gif_block_t blocks[while (std::mem::read_unsigned($, 1) != 0x3b)];
|
||||
|
||||
u8 trailer; // 0x3b
|
||||
};
|
||||
|
||||
gif_t gif @ 0x00;
|
||||
|
||||
77
patterns/gzip.hexpat
Normal file
77
patterns/gzip.hexpat
Normal file
@@ -0,0 +1,77 @@
|
||||
#pragma MIME application/gzip
|
||||
|
||||
#include <type/time.pat>
|
||||
#include <type/size.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
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<u32> isize;
|
||||
};
|
||||
|
||||
GZip gzip @ 0x00;
|
||||
156
patterns/id3.hexpat
Normal file
156
patterns/id3.hexpat
Normal file
@@ -0,0 +1,156 @@
|
||||
#pragma MIME audio/mpeg
|
||||
|
||||
#include <std/mem.pat>
|
||||
|
||||
namespace v1 {
|
||||
|
||||
struct Tag {
|
||||
char header[3];
|
||||
char title[30];
|
||||
char artist[30];
|
||||
char album[30];
|
||||
char year[4];
|
||||
char comment[30];
|
||||
u8 zero;
|
||||
u8 track;
|
||||
u8 genre;
|
||||
} [[static]];
|
||||
|
||||
}
|
||||
|
||||
namespace v2 {
|
||||
|
||||
struct SyncSafeInt {
|
||||
u8 bytes[4];
|
||||
} [[sealed, static, format("v2::ssi_value"), transform("v2::ssi_value")]];
|
||||
|
||||
fn ssi_value(ref SyncSafeInt n) {
|
||||
u32 result = 0;
|
||||
for (u8 i = 0, i < 4, i = i + 1) {
|
||||
u8 byteval = n.bytes[i] & 0x7F;
|
||||
u8 shift = 7 * (4 - i - 1);
|
||||
result = result | (byteval << shift);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
struct TagVersion {
|
||||
u8 major;
|
||||
u8 revision;
|
||||
};
|
||||
|
||||
bitfield TagHeaderFlags {
|
||||
unsynchronized : 1;
|
||||
extended : 1;
|
||||
experimental : 1;
|
||||
footer : 1;
|
||||
padding : 4;
|
||||
};
|
||||
|
||||
struct TagHeader {
|
||||
char identifier[3];
|
||||
TagVersion version;
|
||||
TagHeaderFlags flags;
|
||||
SyncSafeInt size;
|
||||
} [[static]];
|
||||
|
||||
bitfield ExtendedFlag {
|
||||
padding : 1;
|
||||
update : 1;
|
||||
crcpresent : 1;
|
||||
restrictions : 1;
|
||||
padding : 4;
|
||||
};
|
||||
|
||||
struct TagExtendedHeader {
|
||||
SyncSafeInt size;
|
||||
u8 nflagbytes;
|
||||
ExtendedFlag flags[nflagbytes];
|
||||
u8 data[size];
|
||||
};
|
||||
|
||||
struct TagFooter {
|
||||
char identifier[3];
|
||||
TagVersion version;
|
||||
TagHeaderFlags flags;
|
||||
SyncSafeInt size;
|
||||
} [[static]];
|
||||
|
||||
bitfield FrameFlags {
|
||||
padding : 1;
|
||||
tagalterpreservation : 1;
|
||||
filealterpreservation : 1;
|
||||
readonly : 1;
|
||||
padding : 5;
|
||||
groupid : 1;
|
||||
padding : 2;
|
||||
compressed : 1;
|
||||
encrypted : 1;
|
||||
unzynchronized : 1;
|
||||
datalengthindicator : 1;
|
||||
};
|
||||
|
||||
enum TextEncoding : u8 {
|
||||
ISO88591 = 0x00,
|
||||
UTF16BOM = 0x01,
|
||||
UTF16BE = 0x02,
|
||||
UTF8 = 0x03,
|
||||
};
|
||||
|
||||
struct StringData {
|
||||
TextEncoding encoding;
|
||||
if (encoding == TextEncoding::UTF16BOM) {
|
||||
u16 bom;
|
||||
char16 data[(parent.size - 3) / 2];
|
||||
} else if (encoding == TextEncoding::UTF16BE)
|
||||
be char16 data[(parent.size - 1) / 2];
|
||||
else
|
||||
char data[parent.size - 1];
|
||||
};
|
||||
|
||||
// Hack to work around the fact, that chars may not be compared
|
||||
union FrameId {
|
||||
char cdata[4];
|
||||
u8 ndata[4];
|
||||
} [[sealed, static, format("v2::impl::format_frame_id")]];
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_frame_id(ref FrameId id) {
|
||||
return id.cdata;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
struct Frame {
|
||||
FrameId id;
|
||||
SyncSafeInt size;
|
||||
FrameFlags flags;
|
||||
if (id.ndata[0] == 'T')
|
||||
StringData data;
|
||||
else
|
||||
u8 data[size];
|
||||
};
|
||||
|
||||
fn has_next_frame(u32 size) {
|
||||
bool hasnext = $ < size;
|
||||
if (hasnext) {
|
||||
hasnext = std::mem::read_unsigned($, 1) != 0;
|
||||
$ = $ - 1;
|
||||
}
|
||||
return hasnext;
|
||||
};
|
||||
|
||||
struct Tag {
|
||||
TagHeader header;
|
||||
if (header.flags.extended)
|
||||
TagExtendedHeader extendedheader;
|
||||
Frame frames[while(v2::has_next_frame(header.size))];
|
||||
if (header.flags.footer)
|
||||
TagFooter footer;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
v2::Tag tag @ 0;
|
||||
v1::Tag oldtag @ std::mem::size() - 128;
|
||||
@@ -26,7 +26,9 @@ enum cp_tag : u8 {
|
||||
CONSTANT_NameAndType = 12,
|
||||
CONSTANT_MethodHandle = 15,
|
||||
CONSTANT_MethodType = 16,
|
||||
CONSTANT_InvokeDynamic = 18
|
||||
CONSTANT_InvokeDynamic = 18,
|
||||
CONSTANT_Module = 19,
|
||||
CONSTANT_Package = 20
|
||||
};
|
||||
|
||||
enum major_version : u2 {
|
||||
@@ -36,7 +38,7 @@ enum major_version : u2 {
|
||||
JDK_1_4 = 48,
|
||||
|
||||
Java_SE_5_0 = 49,
|
||||
Java_SE_6_0 = 50,
|
||||
Java_SE_6 = 50,
|
||||
Java_SE_7 = 51,
|
||||
Java_SE_8 = 52,
|
||||
Java_SE_9 = 53,
|
||||
@@ -129,37 +131,62 @@ struct CONSTANT_InvokeDynamic_info {
|
||||
u2 name_and_type_index;
|
||||
};
|
||||
|
||||
struct cp_info {
|
||||
cp_tag tag;
|
||||
// Tag == CONSTANT_Module
|
||||
struct CONSTANT_Module_info {
|
||||
u2 name_index;
|
||||
};
|
||||
|
||||
if (tag == cp_tag::CONSTANT_Utf8)
|
||||
CONSTANT_Utf8_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Integer)
|
||||
CONSTANT_Integer_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Float)
|
||||
CONSTANT_Float_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Long)
|
||||
CONSTANT_Long_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Double)
|
||||
CONSTANT_Double_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Class)
|
||||
CONSTANT_Class_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_String)
|
||||
CONSTANT_String_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Fieldref)
|
||||
CONSTANT_Fieldref_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Methodref)
|
||||
CONSTANT_Methodref_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_InterfaceMethodref)
|
||||
CONSTANT_InterfaceMethodref_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_NameAndType)
|
||||
CONSTANT_NameAndType_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_MethodHandle)
|
||||
CONSTANT_MethodHandle_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_MethodType)
|
||||
CONSTANT_MethodType_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_InvokeDynamic)
|
||||
CONSTANT_InvokeDynamic_info info [[inline]];
|
||||
// Tag == CONSTANT_Package
|
||||
struct CONSTANT_Package_info {
|
||||
u2 name_index;
|
||||
};
|
||||
|
||||
// All 8-byte constants take up two entries in the constant_pool table of the class file
|
||||
u1 padding_entry_flag = 0;
|
||||
|
||||
struct cp_info {
|
||||
if (padding_entry_flag == 0) {
|
||||
cp_tag tag;
|
||||
|
||||
if (tag == cp_tag::CONSTANT_Utf8)
|
||||
CONSTANT_Utf8_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Integer)
|
||||
CONSTANT_Integer_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Float)
|
||||
CONSTANT_Float_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Long) {
|
||||
CONSTANT_Long_info info [[inline]];
|
||||
padding_entry_flag = 1;
|
||||
}
|
||||
else if (tag == cp_tag::CONSTANT_Double) {
|
||||
CONSTANT_Double_info info [[inline]];
|
||||
padding_entry_flag = 1;
|
||||
}
|
||||
else if (tag == cp_tag::CONSTANT_Class)
|
||||
CONSTANT_Class_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_String)
|
||||
CONSTANT_String_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Fieldref)
|
||||
CONSTANT_Fieldref_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Methodref)
|
||||
CONSTANT_Methodref_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_InterfaceMethodref)
|
||||
CONSTANT_InterfaceMethodref_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_NameAndType)
|
||||
CONSTANT_NameAndType_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_MethodHandle)
|
||||
CONSTANT_MethodHandle_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_MethodType)
|
||||
CONSTANT_MethodType_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_InvokeDynamic)
|
||||
CONSTANT_InvokeDynamic_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Module)
|
||||
CONSTANT_Module_info info [[inline]];
|
||||
else if (tag == cp_tag::CONSTANT_Package)
|
||||
CONSTANT_Package_info info [[inline]];
|
||||
} else {
|
||||
padding_entry_flag = 0;
|
||||
}
|
||||
};
|
||||
|
||||
bitfield access_flags_method {
|
||||
@@ -216,7 +243,7 @@ bitfield access_flags_class {
|
||||
ACC_SYNTHETIC : 1; // 0x1000
|
||||
ACC_ANNOTATION : 1; // 0x2000
|
||||
ACC_ENUM : 1; // 0x4000
|
||||
padding : 1; // 0x8000
|
||||
ACC_MODULE : 1; // 0x8000
|
||||
};
|
||||
|
||||
struct attribute_info {
|
||||
@@ -279,31 +306,29 @@ fn main() {
|
||||
|
||||
std::print("Fields:");
|
||||
for (le u16 i = 0, i < class_file.fields_count, i = i + 1) {
|
||||
str method_string = " ";
|
||||
str field_string = " ";
|
||||
|
||||
if (class_file.fields[i].access_flags.ACC_PUBLIC)
|
||||
method_string = method_string + "public ";
|
||||
field_string = field_string + "public ";
|
||||
if (class_file.fields[i].access_flags.ACC_PRIVATE)
|
||||
method_string = method_string + "private ";
|
||||
field_string = field_string + "private ";
|
||||
if (class_file.fields[i].access_flags.ACC_PROTECTED)
|
||||
method_string = method_string + "protected ";
|
||||
field_string = field_string + "protected ";
|
||||
if (class_file.fields[i].access_flags.ACC_STATIC)
|
||||
method_string = method_string + "static ";
|
||||
field_string = field_string + "static ";
|
||||
if (class_file.fields[i].access_flags.ACC_FINAL)
|
||||
method_string = method_string + "final ";
|
||||
field_string = field_string + "final ";
|
||||
if (class_file.fields[i].access_flags.ACC_VOLATILE)
|
||||
method_string = method_string + "volatile ";
|
||||
if (class_file.fields[i].access_flags.ACC_NATIVE)
|
||||
method_string = method_string + "native ";
|
||||
field_string = field_string + "volatile ";
|
||||
if (class_file.fields[i].access_flags.ACC_TRANSIENT)
|
||||
method_string = method_string + "transient ";
|
||||
field_string = field_string + "transient ";
|
||||
if (class_file.fields[i].access_flags.ACC_ENUM)
|
||||
method_string = method_string + "enum ";
|
||||
field_string = field_string + "enum ";
|
||||
|
||||
method_string = method_string + class_file.constant_pool[class_file.fields[i].name_index - 1].info.bytes;
|
||||
method_string = method_string + " [ " + class_file.constant_pool[class_file.fields[i].descriptor_index - 1].info.bytes + " ]";
|
||||
field_string = field_string + class_file.constant_pool[class_file.fields[i].name_index - 1].info.bytes;
|
||||
field_string = field_string + " [ " + class_file.constant_pool[class_file.fields[i].descriptor_index - 1].info.bytes + " ]";
|
||||
|
||||
std::print("{}", method_string);
|
||||
std::print("{}", field_string);
|
||||
}
|
||||
|
||||
std::print("Methods:");
|
||||
|
||||
383
patterns/macho.hexpat
Normal file
383
patterns/macho.hexpat
Normal file
@@ -0,0 +1,383 @@
|
||||
#pragma MIME application/x-mach-binary
|
||||
|
||||
#include <type/size.pat>
|
||||
|
||||
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<u32> 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<u32> 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<u32> vmSize;
|
||||
u32 fileOffset;
|
||||
type::Size<u32> 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<u64> 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<u64> vmSize;
|
||||
u64 fileOffset;
|
||||
type::Size<u64> 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<u32> 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;
|
||||
@@ -8,50 +8,50 @@ 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
|
||||
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;
|
||||
type::Size32 DataSize;
|
||||
RVA Rva;
|
||||
};
|
||||
|
||||
struct MINIDUMP_MEMORY_DESCRIPTOR {
|
||||
@@ -70,24 +70,24 @@ struct MINIDUMP_THREAD {
|
||||
};
|
||||
|
||||
struct MINIDUMP_THREAD_LIST {
|
||||
ULONG32 NumberOfThreads;
|
||||
MINIDUMP_THREAD Threads[NumberOfThreads];
|
||||
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;
|
||||
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 {
|
||||
@@ -101,12 +101,12 @@ struct MINIDUMP_MODULE {
|
||||
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;
|
||||
return module.ModuleName;
|
||||
};
|
||||
|
||||
struct MINIDUMP_MODULE_LIST {
|
||||
@@ -137,10 +137,10 @@ struct MINIDUMP_EXCEPTION_STREAM {
|
||||
};
|
||||
|
||||
struct CPU_INFORMATION {
|
||||
ULONG32 VendorId[3];
|
||||
ULONG32 VersionInformation;
|
||||
ULONG32 FeatureInformation;
|
||||
ULONG32 AMDExtendedCpuFeatures;
|
||||
ULONG32 VendorId[3];
|
||||
ULONG32 VersionInformation;
|
||||
ULONG32 FeatureInformation;
|
||||
ULONG32 AMDExtendedCpuFeatures;
|
||||
};
|
||||
|
||||
struct MINIDUMP_SYSTEM_INFO {
|
||||
@@ -235,7 +235,7 @@ struct MINIDUMP_FUNCTION_TABLE_STREAM {
|
||||
type::Size32 SizeOfFunctionEntry;
|
||||
ULONG32 NumberOfDescriptors;
|
||||
ULONG32 SizeOfAlignPad;
|
||||
|
||||
|
||||
MINIDUMP_FUNCTION_TABLE_DESCRIPTOR FunctionDescriptors[NumberOfDescriptors];
|
||||
};
|
||||
|
||||
@@ -245,19 +245,19 @@ struct MINIDUMP_UNLOADED_MODULE {
|
||||
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;
|
||||
return module.ModuleName;
|
||||
};
|
||||
|
||||
struct MINIDUMP_UNLOADED_MODULE_LIST {
|
||||
ULONG32 SizeOfHeader;
|
||||
ULONG32 SizeOfEntry;
|
||||
ULONG32 NumberOfEntries;
|
||||
|
||||
|
||||
if (SizeOfHeader > 12)
|
||||
padding[header.SizeOfHeader - 12];
|
||||
|
||||
@@ -271,7 +271,7 @@ struct MINIDUMP_MISC_INFO {
|
||||
ULONG32 ProcessCreateTime;
|
||||
ULONG32 ProcessUserTime;
|
||||
ULONG32 ProcessKernelTime;
|
||||
|
||||
|
||||
if (SizeOfInfo > 24) {
|
||||
ULONG32 ProcessorMaxMhz;
|
||||
ULONG32 ProcessorCurrentMhz;
|
||||
@@ -297,7 +297,7 @@ struct MINIDUMP_MEMORY_INFO_LIST {
|
||||
ULONG SizeOfHeader;
|
||||
ULONG SizeOfEntry;
|
||||
ULONG64 NumberOfEntries;
|
||||
|
||||
|
||||
if (SizeOfHeader > 16)
|
||||
padding[SizeOfHeader - 16];
|
||||
|
||||
@@ -321,7 +321,7 @@ struct MINIDUMP_THREAD_INFO_LIST {
|
||||
ULONG SizeOfHeader;
|
||||
ULONG SizeOfEntry;
|
||||
ULONG NumberOfEntries;
|
||||
|
||||
|
||||
if (SizeOfHeader > 12)
|
||||
padding[SizeOfHeader - 12];
|
||||
|
||||
@@ -336,88 +336,88 @@ struct MINIDUMP_HANDLE_OPERATION_LIST {
|
||||
};
|
||||
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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")]];
|
||||
MINIDUMP_HEADER Header;
|
||||
MINIDUMP_DIRECTORY Streams[Header.NumberOfStreams] [[format_entries("format_stream")]];
|
||||
};
|
||||
|
||||
fn format_stream(ref MINIDUMP_DIRECTORY stream) {
|
||||
return stream.StreamType;
|
||||
return stream.StreamType;
|
||||
};
|
||||
|
||||
MINIDUMP MiniDump @ 0x00;
|
||||
MINIDUMP MiniDump @ 0x00;
|
||||
|
||||
70
patterns/nbt.hexpat
Normal file
70
patterns/nbt.hexpat
Normal file
@@ -0,0 +1,70 @@
|
||||
#include <std/sys.pat>
|
||||
|
||||
#pragma endian big
|
||||
|
||||
enum Tag : u8 {
|
||||
End = 0,
|
||||
Byte = 1,
|
||||
Short = 2,
|
||||
Int = 3,
|
||||
Long = 4,
|
||||
Float = 5,
|
||||
Double = 6,
|
||||
ByteArray = 7,
|
||||
String = 8,
|
||||
List = 9,
|
||||
Compound = 10,
|
||||
IntArray = 11,
|
||||
LongArray = 12
|
||||
};
|
||||
|
||||
using Element;
|
||||
|
||||
struct Value {
|
||||
if (parent.tag == Tag::Byte)
|
||||
s8 value;
|
||||
else if (parent.tag == Tag::Short)
|
||||
s16 value;
|
||||
else if (parent.tag == Tag::Int)
|
||||
s32 value;
|
||||
else if (parent.tag == Tag::Long)
|
||||
s64 value;
|
||||
else if (parent.tag == Tag::Float)
|
||||
float value;
|
||||
else if (parent.tag == Tag::Double)
|
||||
double value;
|
||||
else if (parent.tag == Tag::ByteArray) {
|
||||
s32 arrayLength;
|
||||
s8 value[arrayLength] [[sealed]];
|
||||
} else if (parent.tag == Tag::String) {
|
||||
u16 stringLength;
|
||||
char value[stringLength];
|
||||
} else if (parent.tag == Tag::List) {
|
||||
Tag tag;
|
||||
s32 listLength;
|
||||
Value values[listLength] [[static]];
|
||||
} else if (parent.tag == Tag::Compound) {
|
||||
Element values[while(true)];
|
||||
} else {
|
||||
std::error(std::format("Invalid tag {:02X}", TypeTag));
|
||||
}
|
||||
} [[inline]];
|
||||
|
||||
struct Element {
|
||||
Tag tag;
|
||||
if (tag == Tag::End)
|
||||
break;
|
||||
else {
|
||||
|
||||
u16 nameLength;
|
||||
char name[nameLength];
|
||||
|
||||
Value value;
|
||||
}
|
||||
};
|
||||
|
||||
struct NBT {
|
||||
Element element[while(true)] [[inline]];
|
||||
};
|
||||
|
||||
NBT nbt @ 0x00;
|
||||
264
patterns/ne.hexpat
Normal file
264
patterns/ne.hexpat
Normal file
@@ -0,0 +1,264 @@
|
||||
#include <std/mem.pat>
|
||||
|
||||
#pragma bitfield_order right_to_left
|
||||
|
||||
struct DOSHeader {
|
||||
char signature[2];
|
||||
u16 lastPageSize;
|
||||
u16 numberOfPages;
|
||||
u16 relocations;
|
||||
u16 headerSizeInParagraphs;
|
||||
u16 minimumAllocatedParagraphs;
|
||||
u16 maximumAllocatedParagraphs;
|
||||
u16 initialSSValue;
|
||||
u16 initialRelativeSPValue;
|
||||
u16 checksum;
|
||||
u16 initialRelativeIPValue;
|
||||
u16 initialCSValue;
|
||||
u16 relocationsTablePointer;
|
||||
u16 overlayNumber;
|
||||
u8 overlayInformation[0x20];
|
||||
u32 neHeaderPointer;
|
||||
};
|
||||
|
||||
u16 dosMessageOffset;
|
||||
u16 pointedCodeOffset;
|
||||
|
||||
fn finddosmessage() {
|
||||
for (u8 i = 0, $+i < std::mem::read_unsigned(0x3C, 4), i = i + 1) {
|
||||
if (std::mem::read_unsigned($+i, 1) == 0xBA) { // MOV instruction
|
||||
dosMessageOffset = std::mem::read_unsigned($+i+1, 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
fn findpointingcode() {
|
||||
for (u8 i = 0, $+i < std::mem::read_unsigned(0x3C, 4), i = i + 1) {
|
||||
if (std::mem::read_unsigned($+i, 1) == 0xE8) { // CALL instruction
|
||||
pointedCodeOffset = std::mem::read_unsigned($+i+1, 2);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
fn isdosdata(char c) {
|
||||
return c == 0x0D || c == '$';
|
||||
};
|
||||
|
||||
struct DOSStub {
|
||||
if (findpointingcode()) {
|
||||
u8 pointingCode[3];
|
||||
u8 code[while(std::mem::read_unsigned($, 1) != 0x00)] @ addressof(this) + pointedCodeOffset + 3;
|
||||
char message[while(!isdosdata(std::mem::read_unsigned($, 1)))];
|
||||
char data[while(std::mem::read_string($-1, 1) != "$")];
|
||||
}
|
||||
else {
|
||||
finddosmessage();
|
||||
if (dosMessageOffset > 0) {
|
||||
u8 code[while($ != addressof(this) + dosMessageOffset)];
|
||||
char message[while(!isdosdata(std::mem::read_unsigned($, 1)))];
|
||||
char data[while(std::mem::read_string($-1, 1) != "$")];
|
||||
}
|
||||
else {
|
||||
char code[while(std::mem::read_unsigned($, 1) != 0x00)];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct FileHeader {
|
||||
DOSHeader dosHeader;
|
||||
DOSStub dosStub @ dosHeader.headerSizeInParagraphs * 16;
|
||||
};
|
||||
|
||||
FileHeader fileHeader @ 0x00;
|
||||
|
||||
enum DGroupType : u8 {
|
||||
NoAutoData,
|
||||
SingleData,
|
||||
MultipleData,
|
||||
Null
|
||||
};
|
||||
|
||||
fn formatDGroupType(u8 value) {
|
||||
DGroupType dgroup = value;
|
||||
|
||||
return dgroup;
|
||||
};
|
||||
|
||||
enum AppType : u8 {
|
||||
None,
|
||||
Fullscreen,
|
||||
WinPMCompatible,
|
||||
UsesWinPM
|
||||
};
|
||||
|
||||
fn formatAppType(u8 value) {
|
||||
AppType app = value;
|
||||
|
||||
return app;
|
||||
};
|
||||
|
||||
bitfield ProgramFlags {
|
||||
dGroupType : 2 [[format("formatDGroupType")]];
|
||||
globalInitialization : 1;
|
||||
protectedModeOnly : 1;
|
||||
instructions86 : 1;
|
||||
instructions286 : 1;
|
||||
instructions386 : 1;
|
||||
instructionsX87 : 1;
|
||||
};
|
||||
|
||||
bitfield ApplicationFlags {
|
||||
applicationType : 2 [[format("formatAppType")]];
|
||||
padding : 1;
|
||||
os2Application : 1;
|
||||
reserved : 1;
|
||||
imageError : 1;
|
||||
nonConforming : 1;
|
||||
dll : 1;
|
||||
};
|
||||
|
||||
enum OSType : u8 {
|
||||
Unknown = 0x00,
|
||||
OS2 = 0x01,
|
||||
Win16 = 0x02,
|
||||
DOS4 = 0x03,
|
||||
Win32 = 0x04,
|
||||
BorlandOSServices = 0x05,
|
||||
PharlapDOSExtenderOS2 = 0x81,
|
||||
PharlapDOSExtenderWindows = 0x82
|
||||
};
|
||||
|
||||
bitfield OS2EXEFlags {
|
||||
longFilename : 1;
|
||||
protectedMode : 1;
|
||||
proportionalFonts : 1;
|
||||
gangloadArea : 1;
|
||||
};
|
||||
|
||||
struct NEHeader {
|
||||
char signature[2];
|
||||
u8 majorLinkerVersion;
|
||||
u8 minorLinkerVersion;
|
||||
u16 entryTableOffset;
|
||||
u16 entryTableLength;
|
||||
u32 fileCRC;
|
||||
ProgramFlags programFlags;
|
||||
ApplicationFlags appFlags;
|
||||
u16 autoDataSegmentIndex;
|
||||
u16 initHeapSize;
|
||||
u16 initStackSize;
|
||||
u32 entryPoint;
|
||||
u32 initialStackPointer;
|
||||
u16 segmentCount;
|
||||
u16 moduleReferenceCount;
|
||||
u16 nonResidentNamesTableSize;
|
||||
u16 segmentTableOffset;
|
||||
u16 resourceTableOffset;
|
||||
u16 residentNamesTableOffset;
|
||||
u16 moduleReferenceTableOffset;
|
||||
u16 importedNamesTableOffset;
|
||||
u8 *nonResidentNamesTablePointer[nonResidentNamesTableSize] : u32;
|
||||
u16 moveableEntryCount;
|
||||
u16 fileAlignmentSizeShiftCount;
|
||||
u16 resourceCount;
|
||||
OSType targetOS;
|
||||
OS2EXEFlags os2ExeFlags;
|
||||
u16 thunksReturnOffset;
|
||||
u16 segmentReferenceThunksOffset;
|
||||
u16 minimumCodeSwapAreaSize;
|
||||
u8 expectedMinorWindowsVersion;
|
||||
u8 expectedMajorWindowsVersion;
|
||||
};
|
||||
|
||||
NEHeader neHeader @ fileHeader.dosHeader.neHeaderPointer;
|
||||
|
||||
bitfield SegmentTableFlags {
|
||||
dataSegment : 1;
|
||||
typeMask : 2;
|
||||
padding : 1;
|
||||
moveable : 1;
|
||||
padding : 1;
|
||||
preloaded : 1;
|
||||
padding : 1;
|
||||
containsRelocationInfo : 1;
|
||||
padding : 1;
|
||||
discardPriority : 4;
|
||||
} [[right_to_left]];
|
||||
|
||||
struct SegmentTable {
|
||||
u16 segmentDataPointer;
|
||||
u16 segmentLength;
|
||||
SegmentTableFlags segmentTableFlags;
|
||||
u16 minimumAllocationSize;
|
||||
};
|
||||
|
||||
SegmentTable segmentTable[neHeader.segmentCount] @ addressof(neHeader) + neHeader.segmentTableOffset;
|
||||
|
||||
bitfield BlockFlags {
|
||||
padding : 4;
|
||||
moveable : 1;
|
||||
shared : 1;
|
||||
preload : 1;
|
||||
padding : 9;
|
||||
};
|
||||
|
||||
struct ResourceTypeInformationBlock {
|
||||
u8 *resourcePointer : u16;
|
||||
u16 resourceLength;
|
||||
BlockFlags flags;
|
||||
u16 resourceID;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct ResourceRecord {
|
||||
u16 typeID;
|
||||
u16 numberOfResources;
|
||||
u32 reserved;
|
||||
ResourceTypeInformationBlock blocks[numberOfResources];
|
||||
};
|
||||
|
||||
struct ResourceTable {
|
||||
u16 alignmentShiftCount;
|
||||
ResourceRecord records[neHeader.resourceTableEntryCount];
|
||||
u8 stringLength;
|
||||
char string[stringLength];
|
||||
};
|
||||
|
||||
ResourceTable resourceTable[neHeader.resourceCount] @ addressof(neHeader) + neHeader.resourceTableOffset;
|
||||
|
||||
struct ResidentName {
|
||||
u8 stringLength;
|
||||
char string[stringLength];
|
||||
u16 ordinalNumber;
|
||||
};
|
||||
|
||||
ResidentName residentNameTable[while($+1 < addressof(neHeader) + neHeader.moduleReferenceTableOffset)] @ addressof(neHeader) + neHeader.residentNamesTableOffset;
|
||||
|
||||
struct ModuleReference {
|
||||
u16 moduleNameOffset;
|
||||
};
|
||||
|
||||
ModuleReference moduleReferenceTable[neHeader.moduleReferenceCount] @ addressof(neHeader) + neHeader.moduleReferenceTableOffset;
|
||||
|
||||
struct ImportedNameTable {
|
||||
u8 stringLength;
|
||||
char string[stringLength];
|
||||
};
|
||||
|
||||
ImportedNameTable importedNameTable[while($ < addressof(neHeader) + neHeader.entryTableOffset)] @ addressof(neHeader) + neHeader.importedNamesTableOffset;
|
||||
|
||||
enum EntryDataType : u8 {
|
||||
Unused,
|
||||
Fixed = 0x01 ... 0xFE,
|
||||
Moveable
|
||||
};
|
||||
|
||||
struct EntryTable {
|
||||
u8 entryCount;
|
||||
EntryDataType segmentIndicator;
|
||||
};
|
||||
|
||||
EntryTable entryTable[neHeader.entryTableLength/2] @ addressof(neHeader) + neHeader.entryTableOffset;
|
||||
@@ -120,21 +120,21 @@ struct ManufacturerData {
|
||||
|
||||
struct DynamicLockBytes {
|
||||
u8 bytes[3];
|
||||
u8 RFUI;
|
||||
padding[1];
|
||||
};
|
||||
|
||||
bitfield MIRROR {
|
||||
MIRROR_CONF : 2;
|
||||
MIRROR_BYTE : 2;
|
||||
RFUI : 1;
|
||||
padding : 1;
|
||||
STRG_MOD_EN : 1;
|
||||
RFUI : 2;
|
||||
padding : 2;
|
||||
} [[left_to_right]];
|
||||
|
||||
bitfield ACCESS {
|
||||
PROT : 1;
|
||||
CFGLCK : 1;
|
||||
RFUI : 1;
|
||||
padding : 1;
|
||||
NFC_CNT_EN : 1;
|
||||
NFC_CNT_PWD_PROT : 1;
|
||||
AUTHLIM : 3;
|
||||
|
||||
30
patterns/pbzx.hexpat
Normal file
30
patterns/pbzx.hexpat
Normal file
@@ -0,0 +1,30 @@
|
||||
// pbzx compression stream
|
||||
// Used by Apple on .xip files and OTA updates.
|
||||
//
|
||||
// Copyright (c) 2022 Nicolás Alvarez <nicolas.alvarez@gmail.com>
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <std/mem.pat>
|
||||
|
||||
#pragma endian big
|
||||
|
||||
#define SHOW_DATA 0
|
||||
|
||||
struct Chunk {
|
||||
u64 uncompressed_size;
|
||||
u64 compressed_size;
|
||||
if (SHOW_DATA) {
|
||||
u8 data[compressed_size] [[sealed]];
|
||||
} else {
|
||||
padding[compressed_size];
|
||||
}
|
||||
};
|
||||
|
||||
struct PBZX {
|
||||
char magic[4];
|
||||
u64 chunk_size;
|
||||
Chunk chunks[while(!std::mem::eof())];
|
||||
};
|
||||
|
||||
PBZX pbzx @ 0;
|
||||
52
patterns/pcx.hexpat
Normal file
52
patterns/pcx.hexpat
Normal file
@@ -0,0 +1,52 @@
|
||||
#pragma MIME application/x-pcx
|
||||
|
||||
#include <std/io.pat>
|
||||
|
||||
enum Encoding : u8 {
|
||||
NoEncoding = 0x00,
|
||||
RunLengthEncoding = 0x01
|
||||
};
|
||||
|
||||
enum PaletteType : u16 {
|
||||
MonochromeOrColorInformation = 0x01,
|
||||
GrayscaleInformation = 0x02
|
||||
};
|
||||
|
||||
enum Version : u8 {
|
||||
V2_5 = 0x00,
|
||||
V2_8WithPalette = 0x02,
|
||||
V2_8_WithoutPalette = 0x03,
|
||||
PaintbrushForWindows = 0x04,
|
||||
V3_0 = 0x05
|
||||
};
|
||||
|
||||
struct Header {
|
||||
u8 magic;
|
||||
Version version;
|
||||
Encoding encoding;
|
||||
u8 bitsPerPixel;
|
||||
u16 xMin, yMin;
|
||||
u16 xMax, yMax;
|
||||
u16 hdpi, vdpi;
|
||||
};
|
||||
|
||||
struct RGB8 {
|
||||
u8 r, g, b;
|
||||
} [[sealed, color(std::format("{:02X}{:02X}{:02X}", this.r, this.g, this.b))]];
|
||||
|
||||
struct Palette {
|
||||
RGB8 color[16];
|
||||
};
|
||||
|
||||
struct PCX {
|
||||
Header header;
|
||||
Palette palette;
|
||||
padding[1];
|
||||
u8 numPlanes;
|
||||
u16 bytesPerLine;
|
||||
PaletteType paletteType;
|
||||
u16 hres, vres;
|
||||
padding[54];
|
||||
};
|
||||
|
||||
PCX pcx @ 0x00;
|
||||
1259
patterns/pe.hexpat
1259
patterns/pe.hexpat
File diff suppressed because it is too large
Load Diff
38
patterns/pfs0.hexpat
Normal file
38
patterns/pfs0.hexpat
Normal file
@@ -0,0 +1,38 @@
|
||||
#include <type/magic.pat>
|
||||
#include <type/size.pat>
|
||||
|
||||
#include <std/core.pat>
|
||||
|
||||
struct FileEntry {
|
||||
u64 dataOffset;
|
||||
type::Size<u64> dataSize;
|
||||
u32 nameOffset;
|
||||
padding[4];
|
||||
};
|
||||
|
||||
struct String {
|
||||
char value[];
|
||||
};
|
||||
|
||||
struct Header {
|
||||
type::Magic<"PFS0"> magic;
|
||||
u32 numFiles;
|
||||
type::Size<u32> stringTableSize;
|
||||
padding[4];
|
||||
|
||||
FileEntry fileEntryTable[numFiles];
|
||||
String strings[numFiles];
|
||||
};
|
||||
|
||||
struct File {
|
||||
char name[] @ addressof(parent.header.strings) + parent.header.fileEntryTable[std::core::array_index()].nameOffset;
|
||||
u8 data[parent.header.fileEntryTable[std::core::array_index()].dataSize] @ parent.header.fileEntryTable[std::core::array_index()].dataOffset [[sealed]];
|
||||
};
|
||||
|
||||
struct PFS0 {
|
||||
Header header;
|
||||
|
||||
File files[header.numFiles];
|
||||
};
|
||||
|
||||
PFS0 pfs0 @ 0x00;
|
||||
@@ -1,36 +1,90 @@
|
||||
#pragma MIME image/png
|
||||
#pragma endian big
|
||||
|
||||
struct header_t
|
||||
{
|
||||
struct header_t {
|
||||
u8 highBitByte;
|
||||
char signature[3];
|
||||
char dosLineEnding[2];
|
||||
char dosEOF;
|
||||
char unixLineEnding;
|
||||
char signature[3];
|
||||
char dosLineEnding[2];
|
||||
char dosEOF;
|
||||
char unixLineEnding;
|
||||
};
|
||||
|
||||
struct ihdr_t
|
||||
{
|
||||
struct actl_t {
|
||||
u32 frames [[comment("Total № of frames in animation")]];
|
||||
u32 plays [[comment("№ of times animation will loop")]];
|
||||
} [[comment("Animation control chunk"), name("acTL")]];
|
||||
|
||||
enum ColorType: u8 {
|
||||
Grayscale = 0x0,
|
||||
RGBTriple = 0x2,
|
||||
Palette,
|
||||
GrayscaleAlpha,
|
||||
RGBA = 0x6
|
||||
};
|
||||
|
||||
enum Interlacing: u8 {
|
||||
None,
|
||||
Adam7
|
||||
};
|
||||
|
||||
struct ihdr_t {
|
||||
u32 width [[comment("Image width")]];
|
||||
u32 height [[comment("Image height")]];
|
||||
u8 bit_depth;
|
||||
u8 color_type [[comment("PNG Image Type\n0: greyscale\n2: truecolour\n3: indexed-color\n4: greyscale with alpha\n6: truecolour with alpha")]];
|
||||
u8 compression_method;
|
||||
u8 filter_method;
|
||||
u8 interlace_method [[comment("values 0 \"no interlace\" or 1 \"Adam7 interlace\"")]];
|
||||
ColorType color_type [[comment("PNG Image Type")]];
|
||||
u8 compression_method [[comment("Only 0x0 = zlib supported by most")]];
|
||||
u8 filter_method [[comment("Only 0x0 = adaptive supported by most")]];
|
||||
Interlacing interlacing;
|
||||
};
|
||||
|
||||
struct palette_entry_t {
|
||||
u8 r;
|
||||
u8 g;
|
||||
u8 b;
|
||||
enum sRGB: u8 {
|
||||
Perceptual = 0x0,
|
||||
RelativeColorimetric,
|
||||
Saturation,
|
||||
AbsoluteColorimetric
|
||||
};
|
||||
|
||||
enum Unit: u8 {
|
||||
Unknown,
|
||||
Meter
|
||||
};
|
||||
|
||||
struct phys_t {
|
||||
u32 ppu_x [[comment("Pixels per unit, X axis")]];
|
||||
u32 ppu_y [[comment("Pixels per unit, Y axis")]];
|
||||
u8 unit [[comment("Unit Specifier\n0: unit is unknown\n1: unit is the metre")]];
|
||||
Unit unit;
|
||||
};
|
||||
|
||||
enum BlendOp: u8 {
|
||||
Source = 0x0,
|
||||
Over
|
||||
};
|
||||
|
||||
enum DisposeOp: u8 {
|
||||
None = 0x0,
|
||||
Background,
|
||||
Previous
|
||||
};
|
||||
|
||||
struct fctl_t {
|
||||
u32 sequence_no [[comment("Sequence №")]];
|
||||
u32 width [[comment("Frame width")]];
|
||||
u32 height;
|
||||
u32 xoff;
|
||||
u32 yoff;
|
||||
u16 delay_num;
|
||||
u16 delay_den;
|
||||
DisposeOp dispose_op;
|
||||
BlendOp blend_op;
|
||||
};
|
||||
|
||||
struct fdat_t {
|
||||
u32 sequence_no;
|
||||
};
|
||||
|
||||
fn text_len() {
|
||||
u64 len = parent.parent.length - ($ - addressof(parent.keyword));
|
||||
return len;
|
||||
};
|
||||
|
||||
struct itxt_t {
|
||||
@@ -39,48 +93,92 @@ struct itxt_t {
|
||||
u8 compression_method;
|
||||
char language_tag[];
|
||||
char translated_keyword[];
|
||||
char text[parent.length - ($ - addressof(keyword))];
|
||||
char text[text_len()];
|
||||
};
|
||||
|
||||
struct ztxt_t {
|
||||
char keyword[];
|
||||
u8 compression_method;
|
||||
char text[text_len()];
|
||||
};
|
||||
|
||||
struct text_t {
|
||||
char keyword[];
|
||||
char text[text_len()];
|
||||
};
|
||||
|
||||
struct iccp_t {
|
||||
char profile [];
|
||||
u8 compression_method;
|
||||
u8 compressed_profile[parent.length - ($ - addressof(profile))];
|
||||
char keyword[];
|
||||
u8 compression_method;
|
||||
u8 compressed_profile[text_len()];
|
||||
};
|
||||
|
||||
struct palette_entry_t {
|
||||
u24 color;
|
||||
} [[inline]];
|
||||
|
||||
struct chunk_t {
|
||||
u32 length [[color("17BECF")]];
|
||||
char type[4];
|
||||
char name[4];
|
||||
|
||||
#define IHDR_k "IHDR"
|
||||
#define PLTE_k "PLTE"
|
||||
#define sRGB_k "sRGB"
|
||||
#define pHYs_k "pHYs"
|
||||
#define iTXt_k "iTXt"
|
||||
#define tEXt_k "tEXt"
|
||||
#define zTXt_k "zTXt"
|
||||
#define IDAT_k "IDAT"
|
||||
#define IEND_k "IEND"
|
||||
#define gAMA_k "gAMA"
|
||||
#define iCCP_k "iCCP"
|
||||
#define acTL_k "acTL"
|
||||
#define fdAT_k "fdAT"
|
||||
#define fcTL_k "fcTL"
|
||||
|
||||
if (type == IHDR_k) {
|
||||
if (name == IHDR_k) {
|
||||
ihdr_t ihdr [[comment("Image Header chunk"), name("IHDR")]];
|
||||
} else if (type == PLTE_k) {
|
||||
} else if (name == PLTE_k) {
|
||||
palette_entry_t entries[length / 3];
|
||||
} else if (type == pHYs_k) {
|
||||
} else if (name == sRGB_k) {
|
||||
sRGB srgb;
|
||||
} else if (name == pHYs_k) {
|
||||
phys_t phys;
|
||||
} else if (type == iTXt_k) {
|
||||
} else if (name == acTL_k) {
|
||||
actl_t actl [[comment("Animation control chunk")]];
|
||||
} else if (name == fcTL_k) {
|
||||
fctl_t fctl [[comment("Frame control chunk")]];
|
||||
} else if (name == iTXt_k) {
|
||||
itxt_t text;
|
||||
} else if (type == gAMA_k) {
|
||||
} else if (name == gAMA_k) {
|
||||
u32 gamma [[name("image gamma"), comment("4 byte unsigned integer representing gamma times 100000")]];
|
||||
} else if (type == iCCP_k) {
|
||||
} else if (name == iCCP_k) {
|
||||
iccp_t iccp;
|
||||
} else if (name == tEXt_k) {
|
||||
text_t text;
|
||||
} else if (name == zTXt_k) {
|
||||
ztxt_t text;
|
||||
} else if (name == iCCP_k) {
|
||||
iccp_t iccp;
|
||||
} else if (name == fdAT_k) {
|
||||
fdat_t fdat [[comment("Frame data chunk")]];
|
||||
u8 data[length-sizeof(u32)];
|
||||
} else {
|
||||
u8 data[length];
|
||||
}
|
||||
|
||||
u32 crc;
|
||||
} [[format("chunkValueName")]];
|
||||
|
||||
fn chunkValueName(ref chunk_t chunk) {
|
||||
return chunk.name;
|
||||
};
|
||||
|
||||
struct chunk_set {
|
||||
chunk_t chunks[while(builtin::std::mem::read_string($ + 4, 4) != "IEND")] [[inline]];
|
||||
} [[inline]];
|
||||
|
||||
header_t header @ 0x00 [[comment("PNG file signature"), name("Signature")]];
|
||||
chunk_t ihdr_chunk @ 0x08 [[comment("PNG Header chunk"), name("IHDR")]];
|
||||
chunk_t chunk_set[while(builtin::std::mem::read_string($ + 4, 4) != "IEND")] @ $ [[comment("PNG file chunks"), name("Chunks"), inline]];
|
||||
chunk_t iend_chunk @ $ [[name("IEND"), comment("Image End Chunk")]];
|
||||
chunk_set set @ $ [[comment("PNG Chunks"), name("Chunks"), inline]];
|
||||
chunk_t iend_chunk @ $ [[comment("Image End Chunk"), name("IEND")]];
|
||||
115
patterns/sit5.hexpat
Normal file
115
patterns/sit5.hexpat
Normal file
@@ -0,0 +1,115 @@
|
||||
// Based on https://github.com/mietek/theunarchiver/wiki/StuffIt5Format and https://github.com/ParksProjets/Maconv/blob/master/docs/stuffit/Stuffit_v5.md
|
||||
|
||||
#pragma endian big
|
||||
#pragma MIME application/x-stuffit
|
||||
|
||||
#include <std/io.pat>
|
||||
#include <std/time.pat>
|
||||
|
||||
namespace v5 {
|
||||
|
||||
bitfield Flags1 {
|
||||
padding : 1;
|
||||
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")]];
|
||||
|
||||
fn format_macos_date(MacOSHFSPlusDate date) {
|
||||
return std::time::format(std::time::to_utc(date - 2082844800));
|
||||
};
|
||||
|
||||
struct Header {
|
||||
char magic[0x50];
|
||||
u32 unknown1;
|
||||
u32 archiveSize;
|
||||
u32 entriesOffset;
|
||||
u32 unknown2;
|
||||
};
|
||||
|
||||
struct EntryHeader {
|
||||
u32 magic;
|
||||
u8 version;
|
||||
u8 unknown1;
|
||||
u16 headerSize;
|
||||
u8 unknown2;
|
||||
Flags1 flags;
|
||||
MacOSHFSPlusDate creationDate, modificationDate;
|
||||
u32 prevEntryOffset, nextEntryOffset, parentEntryOffset;
|
||||
u16 nameSize;
|
||||
u16 headerChecksum;
|
||||
|
||||
u32 dataForkUncompressedLength, dataForkCompressedLength;
|
||||
u16 dataForkChecksum;
|
||||
u16 unknown3;
|
||||
};
|
||||
|
||||
enum CompressionMethod : u8 {
|
||||
None = 0x00, // No compression
|
||||
Rle90 = 0x01, // Run length encoding
|
||||
Compress = 0x02, // Compress LZW algorithm, 14 bit max code length, block mode
|
||||
StuffIt3 = 0x03, // Simple Huffman encoding for individual bytes
|
||||
StuffIt5 = 0x05, // LZAH
|
||||
StuffIt8 = 0x08, // Miller-Wegman
|
||||
StuffIt13 = 0x0D, // LZSS and Huffman
|
||||
Stuffit14 = 0x0E, // Unknown
|
||||
StuffItArsenic = 0x0F // BWT and arithmetic coding
|
||||
};
|
||||
|
||||
struct Entry {
|
||||
EntryHeader header;
|
||||
if (header.flags.folder) {
|
||||
u16 numFiles;
|
||||
|
||||
if (header.dataForkUncompressedLength)
|
||||
std::print("Folder entry {} is special!", std::core::array_index());
|
||||
} else {
|
||||
CompressionMethod compressionMethod;
|
||||
}
|
||||
|
||||
u8 passwordDataLength;
|
||||
u8 passwordInformation[passwordDataLength];
|
||||
char fileName[header.nameSize];
|
||||
u16 commentSize;
|
||||
u16 unknown2;
|
||||
char comment[commentSize];
|
||||
|
||||
if (!header.flags.folder) {
|
||||
Flags2 flags;
|
||||
u16 unknown3;
|
||||
char fileType[4];
|
||||
u32 fileCreator;
|
||||
u16 macOSFinderFlags;
|
||||
u32 unknown4;
|
||||
u32 unknown5;
|
||||
u8 unknown6[6];
|
||||
|
||||
if (header.version == 1)
|
||||
u32 unknown7;
|
||||
|
||||
u8 compressedData[header.dataForkCompressedLength] [[sealed]];
|
||||
|
||||
if (header.nextEntryOffset == 0x00)
|
||||
break;
|
||||
else
|
||||
$ = header.nextEntryOffset;
|
||||
}
|
||||
};
|
||||
|
||||
struct StuffIt {
|
||||
Header header;
|
||||
|
||||
Entry entries[while(true)] @ header.entriesOffset;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
v5::StuffIt stuffIt @ 0x00;
|
||||
88
patterns/tar.hexpat
Normal file
88
patterns/tar.hexpat
Normal file
@@ -0,0 +1,88 @@
|
||||
#pragma MIME application/tar
|
||||
#pragma MIME application/x-tar
|
||||
|
||||
#pragma endian little
|
||||
|
||||
#include <std/string.pat>
|
||||
#include <std/time.pat>
|
||||
#include <std/mem.pat>
|
||||
#include <std/sys.pat>
|
||||
|
||||
|
||||
#define HEADER "ustar "
|
||||
#define NULL "\x00"
|
||||
|
||||
fn octal_to_decimal(str value) {
|
||||
return std::string::parse_int(value, 8);
|
||||
};
|
||||
|
||||
fn get_time(str time) {
|
||||
std::time::EpochTime epochtime = octal_to_decimal(time);
|
||||
std::time::Time localtime = std::time::to_local(epochtime);
|
||||
return std::time::format(localtime, "%c");
|
||||
};
|
||||
|
||||
enum typeflagenum : char {
|
||||
regular = '0',
|
||||
also_regular = '\x00',
|
||||
link_to_another_file_already_archived = '1',
|
||||
symbolic_link = '2',
|
||||
character_special_device = '3',
|
||||
block_special_device = '4',
|
||||
directory = '5',
|
||||
fifo_special_file = '6',
|
||||
reserved = '7'
|
||||
};
|
||||
|
||||
struct posix_header {
|
||||
char name[100] [[name("file name")]];
|
||||
char mode[8] [[name("file mode")]];
|
||||
char uid[8] [[name("user id of the file")]];
|
||||
char gid[8] [[name("group if of the file")]];
|
||||
char size[12] [[name("size of the file in octal")]];
|
||||
char mtime[12] [[name("modified time of file in epoch time")]];
|
||||
char chksum[8] [[name("checksum")]];
|
||||
typeflagenum typeflag [[name("type of file")]];
|
||||
char linkname[100] [[name("name of link")]];
|
||||
char magic[6] [[name("magic bytes that identifies the 'file version'")]];
|
||||
char version[2] [[name("version (also used with magic bytes)")]];
|
||||
char uname[32] [[name("username of the owner of the file")]];
|
||||
char gname[32] [[name("group name of the owner of the file")]];
|
||||
char devmajor[8] [[name("major device numbers")]];
|
||||
char devminor[8] [[name("minor device numbers")]];
|
||||
char prefix[155] [[name("filename prefix")]];
|
||||
char reserved[12] [[name("reserved")]];
|
||||
};
|
||||
|
||||
|
||||
struct tar {
|
||||
posix_header header_raw;
|
||||
char file[octal_to_decimal(header_raw.size)];
|
||||
|
||||
std::print("-" * 50);
|
||||
std::print("File Name: {}", header_raw.name);
|
||||
std::print("File Permissions: {}" , header_raw.mode);
|
||||
std::print("UID: {}", header_raw.uid);
|
||||
std::print("GUID: {}", header_raw.gid);
|
||||
std::print("Size: {} bytes", octal_to_decimal(header_raw.size));
|
||||
std::print("Modified Time: {}", get_time(header_raw.mtime));
|
||||
std::print("Checksum: {}", header_raw.chksum);
|
||||
std::print("Type of File: {}", header_raw.typeflag);
|
||||
std::print("Magic Bytes: {}", header_raw.magic);
|
||||
std::print("Version: {}", header_raw.version);
|
||||
std::print("uname: {}", header_raw.uname);
|
||||
std::print("gname: {}", header_raw.gname);
|
||||
std::print("devmajor: {}", header_raw.devmajor);
|
||||
std::print("devminor: {}", header_raw.devminor);
|
||||
std::print("prefix: {}", header_raw.prefix);
|
||||
|
||||
char empty[while (std::mem::read_string($, 1) == NULL && !std::mem::eof())];
|
||||
if (std::mem::eof()) {
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
char magic[6] @ 0x00000101 [[hidden]];
|
||||
std::assert(magic == HEADER, "Magic bytes are not correct! Perhaps wrong file?");
|
||||
|
||||
tar tar[while(!std::mem::eof())] @ 0x000;
|
||||
270
patterns/usb.hexpat
Normal file
270
patterns/usb.hexpat
Normal file
@@ -0,0 +1,270 @@
|
||||
#include <std/io.pat>
|
||||
#include <std/mem.pat>
|
||||
#include <std/string.pat>
|
||||
|
||||
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<auto Size> {
|
||||
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;
|
||||
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))];
|
||||
};
|
||||
|
||||
USBDescriptor descriptors[while(!std::mem::eof())] @ 0x00;
|
||||
24
patterns/wad.hexpat
Normal file
24
patterns/wad.hexpat
Normal file
@@ -0,0 +1,24 @@
|
||||
#include <type/magic.pat>
|
||||
#include <type/size.pat>
|
||||
|
||||
enum WADType : char {
|
||||
Internal = 'I',
|
||||
Patch = 'P'
|
||||
};
|
||||
|
||||
struct FileLump {
|
||||
u32 filePos;
|
||||
type::Size<u32> size;
|
||||
char name[8];
|
||||
|
||||
u8 data[size] @ filePos [[sealed]];
|
||||
};
|
||||
|
||||
struct WAD {
|
||||
WADType type;
|
||||
type::Magic<"WAD"> identification;
|
||||
u32 numLumps;
|
||||
FileLump *infoTable[numLumps] : u32;
|
||||
};
|
||||
|
||||
WAD wad @ 0x00;
|
||||
97
patterns/xci.hexpat
Normal file
97
patterns/xci.hexpat
Normal file
@@ -0,0 +1,97 @@
|
||||
#include <std/core.pat>
|
||||
|
||||
#include <type/magic.pat>
|
||||
#include <type/size.pat>
|
||||
|
||||
#define PAGE_SIZE 0x200
|
||||
|
||||
enum RomSize : u8 {
|
||||
_1GB = 0xFA,
|
||||
_2GB = 0xF8,
|
||||
_4GB = 0xF0,
|
||||
_8GB = 0xE0,
|
||||
_16GB = 0xE1,
|
||||
_32GB = 0xE2
|
||||
};
|
||||
|
||||
bitfield Index {
|
||||
titleKeyDecIndex : 4;
|
||||
kekIndex : 4;
|
||||
};
|
||||
|
||||
bitfield Flags {
|
||||
autoBoot : 1;
|
||||
historyErase : 1;
|
||||
repairTool : 1;
|
||||
differentRegionCupToTerraDevice : 1;
|
||||
differentRegionCupToGlobalDevice : 1;
|
||||
padding : 2;
|
||||
hasNewCardHeader : 1;
|
||||
};
|
||||
|
||||
struct SelSec {
|
||||
u16 t1, t2;
|
||||
};
|
||||
|
||||
struct CardHeader {
|
||||
u8 headerSignature[0x100];
|
||||
type::Magic<"HEAD"> magic;
|
||||
u32 romAreaStartPageAddress;
|
||||
u32 backupAreaStartPageAddress;
|
||||
Index index [[inline]];
|
||||
RomSize romSize;
|
||||
u8 cardHeaderVersion;
|
||||
Flags flags;
|
||||
u64 packageId;
|
||||
u32 validDataEndAddress;
|
||||
padding[4];
|
||||
u8 iv[0x10];
|
||||
u64 partitionFsHeaderAddress;
|
||||
type::Size<u64> partitionFsHeaderSize;
|
||||
u8 partitionFsHeaderHash[0x20];
|
||||
u8 initialDataHash[0x20];
|
||||
SelSec selSec;
|
||||
u32 selT1Key;
|
||||
u32 selKey;
|
||||
u32 limArea;
|
||||
|
||||
u8 cardHeaderEncryptedData[0x70];
|
||||
};
|
||||
|
||||
struct FileEntry {
|
||||
u64 dataOffset;
|
||||
type::Size<u64> dataSize;
|
||||
u32 fileNameOffset;
|
||||
type::Size<u32> hashedRegionSize;
|
||||
padding[8];
|
||||
u8 hash[0x20];
|
||||
};
|
||||
|
||||
struct String {
|
||||
char string[];
|
||||
};
|
||||
|
||||
struct File {
|
||||
String fileName @ addressof(parent.stringTable) + parent.fileEntryTable[std::core::array_index()].fileNameOffset;
|
||||
u8 data[parent.fileEntryTable[std::core::array_index()].dataSize] @ addressof(parent.stringTable) + sizeof(parent.stringTable) + parent.fileEntryTable[std::core::array_index()].dataOffset [[sealed]];
|
||||
};
|
||||
|
||||
struct PartitionFs {
|
||||
type::Magic<"HFS0"> magic;
|
||||
u32 fileCount;
|
||||
type::Size<u32> stringTableSize;
|
||||
padding[4];
|
||||
FileEntry fileEntryTable[fileCount];
|
||||
String stringTable[while($ < (addressof(fileEntryTable) + sizeof(fileEntryTable) + stringTableSize))];
|
||||
|
||||
File files[fileCount];
|
||||
};
|
||||
|
||||
struct XCI {
|
||||
CardHeader header;
|
||||
|
||||
PartitionFs x @ header.romAreaStartPageAddress * PAGE_SIZE;
|
||||
|
||||
};
|
||||
|
||||
XCI xci @ 0x00;
|
||||
@@ -1,46 +1,60 @@
|
||||
#pragma MIME application/zip
|
||||
|
||||
#include <std/mem.pat>
|
||||
#include <std/math.pat>
|
||||
|
||||
struct EndOfCentralDirectory{
|
||||
u32 headerSignature [[color("00000000")]];
|
||||
u16 diskNum [[comment("Number of this disk "), name("Disk Number")]];
|
||||
u16 diskStart [[comment("Disk where central directory starts "), name("Central Directory Disk Number")]];
|
||||
u16 CDRCount [[comment("Number of central directory records on this disk"), name("Central Directory Entries")]];
|
||||
u16 CentralDirectoryRecordCount [[comment("Total number of entries in the central directory"), name("Total Central Directory Entries")]];
|
||||
u32 CDSize [[comment("Size of central directory (bytes)"), name("Central Directory Size")]];
|
||||
u32 CDOffset [[comment("Offset of start of central directory, relative to start of archive"), name("Central Directory Offset")]];
|
||||
u16 commentLength [[color("00000000")]];
|
||||
char coment[commentLength] [[name("Comment")]];
|
||||
struct EndOfCentralDirectory {
|
||||
u32 headerSignature [[color("00000000")]];
|
||||
u16 diskNum [[comment("Number of this disk "), name("Disk Number")]];
|
||||
u16 diskStart [[comment("Disk where central directory starts "), name("Central Directory Disk Number")]];
|
||||
u16 CDRCount [[comment("Number of central directory records on this disk"), name("Central Directory Entries")]];
|
||||
u16 CentralDirectoryRecordCount [[comment("Total number of entries in the central directory"), name("Total Central Directory Entries")]];
|
||||
u32 CDSize [[comment("Size of central directory (bytes)"), name("Central Directory Size")]];
|
||||
u32 CDOffset [[comment("Offset of start of central directory, relative to start of archive"), name("Central Directory Offset")]];
|
||||
u16 commentLength [[color("00000000")]];
|
||||
char coment[commentLength] [[name("Comment")]];
|
||||
};
|
||||
|
||||
EndOfCentralDirectory fileInfo @ std::mem::find_sequence(0,0x50,0x4B,0x05,0x06) [[name("End of Central Directory Record")]];
|
||||
|
||||
struct CentralDirectoryEntry{
|
||||
|
||||
fn find_eocd() {
|
||||
// If there is no zip comment, which is the common case,
|
||||
// the end-of-central-directory record will be 22 bytes long
|
||||
// at the end of the file; check if size-22 has the signature.
|
||||
if (std::mem::read_unsigned(std::mem::size()-22, 4, std::mem::Endian::Little) == 0x06054B50) {
|
||||
return std::mem::size()-22;
|
||||
} else {
|
||||
// If it's not there, then there's probably a zip comment;
|
||||
// search the last 64KB of the file for the signature.
|
||||
// This is not entirely reliable, since the signature could
|
||||
// randomly appear in compressed data before the actual EOCD,
|
||||
// but it should be good enough...
|
||||
u128 last64k = std::math::max(0, std::mem::size()-65536-22);
|
||||
return std::mem::find_sequence_in_range(0, last64k, std::mem::size(), 0x50,0x4B,0x05,0x06);
|
||||
}
|
||||
};
|
||||
|
||||
struct CentralDirectoryFileHeader{
|
||||
u32 headerSignature [[color("00000000")]];
|
||||
u16 versionMade [[comment("Version file made by")]];
|
||||
u16 versionExtract [[comment("Minimum version needed to extract")]];
|
||||
u16 generalFlag [[comment("General purpose bit flag"), color("00000000")]];
|
||||
u16 compressionMethod;
|
||||
u16 fileLastModifyTime [[comment("File last modification time")]];
|
||||
u16 fileLastModifyDate [[comment("File last modification date")]];
|
||||
u32 crc32 [[comment("CRC-32 of uncompressed data"), color("00000000")]];
|
||||
u32 compressedSize;
|
||||
u32 uncompressedSize;
|
||||
u16 fileNameLength [[color("00000000")]];
|
||||
u16 extraFieldLength [[color("00000000")]];
|
||||
u16 fileCommentLength [[color("00000000")]];
|
||||
u16 diskNumber [[comment("Disk number where file starts ")]];
|
||||
u16 internalFileAttributes;
|
||||
u32 externalFileAttributes;
|
||||
u32 fileOffset [[comment("Relative offset of local file header. This is the number of bytes between the start of the first disk on which the file occurs, and the start of the local file header. This allows software reading the central directory to locate the position of the file inside the ZIP file.")]];
|
||||
char fileName[fileNameLength];
|
||||
u8 extraField[extraFieldLength];
|
||||
char comment[fileCommentLength];
|
||||
EndOfCentralDirectory fileInfo @ find_eocd() [[name("End of Central Directory Record")]];
|
||||
|
||||
struct CentralDirectoryFileHeader {
|
||||
u32 headerSignature [[color("00000000")]];
|
||||
u16 versionMade [[comment("Version file made by")]];
|
||||
u16 versionExtract [[comment("Minimum version needed to extract")]];
|
||||
u16 generalFlag [[comment("General purpose bit flag"), color("00000000")]];
|
||||
u16 compressionMethod;
|
||||
u16 fileLastModifyTime [[comment("File last modification time")]];
|
||||
u16 fileLastModifyDate [[comment("File last modification date")]];
|
||||
u32 crc32 [[comment("CRC-32 of uncompressed data"), color("00000000")]];
|
||||
u32 compressedSize;
|
||||
u32 uncompressedSize;
|
||||
u16 fileNameLength [[color("00000000")]];
|
||||
u16 extraFieldLength [[color("00000000")]];
|
||||
u16 fileCommentLength [[color("00000000")]];
|
||||
u16 diskNumber [[comment("Disk number where file starts")]];
|
||||
u16 internalFileAttributes;
|
||||
u32 externalFileAttributes;
|
||||
u32 fileOffset [[comment("Offset of local file header, relative to the start of the first disk on which the file occurs.")]];
|
||||
char fileName[fileNameLength];
|
||||
u8 extraField[extraFieldLength];
|
||||
char comment[fileCommentLength];
|
||||
};
|
||||
|
||||
CentralDirectoryFileHeader centralDirHeaders[fileInfo.CDRCount] @ (fileInfo.CDOffset) [[name("Files")]];
|
||||
|
||||
115
patterns/zstd.hexpat
Normal file
115
patterns/zstd.hexpat
Normal file
@@ -0,0 +1,115 @@
|
||||
// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md
|
||||
|
||||
#pragma MIME application/zstd
|
||||
|
||||
#include <std/io.pat>
|
||||
#include <std/mem.pat>
|
||||
#include <std/sys.pat>
|
||||
|
||||
#define ZSTD_MAGIC_NUMBER 0xFD2FB528
|
||||
|
||||
bitfield frame_header_descriptor_t {
|
||||
frame_content_size_flag : 2;
|
||||
single_segment_flag : 1;
|
||||
unused_bit : 1;
|
||||
reserved_bit : 1;
|
||||
content_checksum_flag : 1;
|
||||
dictionary_id_flag : 2;
|
||||
} [[left_to_right]];
|
||||
|
||||
bitfield window_descriptor_t {
|
||||
exponent : 5;
|
||||
mantissa : 3;
|
||||
} [[left_to_right]];
|
||||
|
||||
fn window_size(window_descriptor_t window_descriptor) {
|
||||
u64 window_log = 10 + window_descriptor.exponent;
|
||||
u64 window_base = 1 << window_log;
|
||||
u64 window_add = (window_base / 8) * window_descriptor.mantissa;
|
||||
u64 window_size = window_base + window_add;
|
||||
return window_size;
|
||||
};
|
||||
|
||||
struct frame_header_t {
|
||||
frame_header_descriptor_t frame_header_descriptor;
|
||||
|
||||
if (!frame_header_descriptor.single_segment_flag){
|
||||
window_descriptor_t window_descriptor;
|
||||
}
|
||||
|
||||
if (frame_header_descriptor.dictionary_id_flag == 1) {
|
||||
le u8 dictionary_id;
|
||||
}
|
||||
else if (frame_header_descriptor.dictionary_id_flag == 2) {
|
||||
le u16 dictionary_id;
|
||||
}
|
||||
else if (frame_header_descriptor.dictionary_id_flag == 3) {
|
||||
le u32 dictionary_id;
|
||||
}
|
||||
|
||||
if (frame_header_descriptor.frame_content_size_flag == 0) { // 0
|
||||
if (frame_header_descriptor.single_segment_flag) {
|
||||
le u8 content_size;
|
||||
}
|
||||
}
|
||||
else if (frame_header_descriptor.frame_content_size_flag == 1) {
|
||||
le u16 content_size;
|
||||
}
|
||||
else if (frame_header_descriptor.frame_content_size_flag == 2) {
|
||||
le u32 content_size;
|
||||
}
|
||||
else {
|
||||
le u64 content_size;
|
||||
}
|
||||
};
|
||||
|
||||
bitfield block_header_t {
|
||||
block_size : 21;
|
||||
block_type : 2;
|
||||
last_block : 1;
|
||||
} [[left_to_right]];
|
||||
|
||||
enum block_type : u8 {
|
||||
raw_block = 0,
|
||||
rle_block = 1,
|
||||
compressed_block = 2,
|
||||
reserved = 3
|
||||
};
|
||||
|
||||
struct data_block_t {
|
||||
block_header_t block_header;
|
||||
|
||||
if (block_header.last_block) {
|
||||
last_block_flag = true;
|
||||
}
|
||||
|
||||
if (block_header.block_type == block_type::raw_block) {
|
||||
le u8 block_content[block_header.block_size];
|
||||
}
|
||||
else if (block_header.block_type == block_type::rle_block) {
|
||||
le u8 block_content[1];
|
||||
}
|
||||
else if (block_header.block_type == block_type::compressed_block) {
|
||||
le u8 block_content[block_header.block_size];
|
||||
}
|
||||
else {
|
||||
std::error("The data block seems to be corrupted!");
|
||||
}
|
||||
};
|
||||
|
||||
struct content_checksum_t {
|
||||
le u32 xxh64_hash;
|
||||
};
|
||||
|
||||
struct zstd_frame_t {
|
||||
le u32 magic_number;
|
||||
std::assert(magic_number == ZSTD_MAGIC_NUMBER, "Invalid magic number!");
|
||||
frame_header_t frame_header;
|
||||
data_block_t data_block[while(!last_block_flag)];
|
||||
if (frame_header.frame_header_descriptor.content_checksum_flag) {
|
||||
content_checksum_t content_checksum;
|
||||
}
|
||||
};
|
||||
|
||||
bool last_block_flag = false;
|
||||
zstd_frame_t zstd_frame @ 0x00;
|
||||
@@ -15,7 +15,7 @@ add_executable(includes_test
|
||||
)
|
||||
|
||||
target_include_directories(includes_test PRIVATE include)
|
||||
target_link_libraries(includes_test libpl)
|
||||
target_link_libraries(includes_test PRIVATE libpl fmt)
|
||||
|
||||
set_target_properties(includes_test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
|
||||
@@ -34,9 +34,11 @@ int main(int argc, char **argv) {
|
||||
return false;
|
||||
};
|
||||
|
||||
runtime.setDataSource([&](pl::u64 address, pl::u8 *data, size_t size) {
|
||||
pl::core::err::E0011.throwError("Include files should never read from memory directly!");
|
||||
}, 0x00, 0x100000);
|
||||
runtime.setDataSource(0x00, 0x100000,
|
||||
[&](pl::u64 address, pl::u8 *data, size_t size) {
|
||||
pl::core::err::E0011.throwError("Include files should never read from memory directly!");
|
||||
}
|
||||
);
|
||||
runtime.setDangerousFunctionCallHandler([]{ return true; });
|
||||
runtime.setIncludePaths({ includePath });
|
||||
|
||||
@@ -73,4 +75,4 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ find_package(PkgConfig REQUIRED)
|
||||
pkg_search_module(MAGIC libmagic>=5.39)
|
||||
|
||||
target_include_directories(magic_test PRIVATE include)
|
||||
target_link_libraries(magic_test libpl magic)
|
||||
target_link_libraries(magic_test PRIVATE libpl magic fmt)
|
||||
|
||||
set_target_properties(magic_test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ add_executable(patterns_tests
|
||||
)
|
||||
|
||||
target_include_directories(patterns_tests PRIVATE include)
|
||||
target_link_libraries(patterns_tests libpl)
|
||||
target_link_libraries(patterns_tests PRIVATE libpl fmt)
|
||||
|
||||
set_target_properties(patterns_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
|
||||
@@ -41,10 +41,12 @@ int main(int argc, char **argv) {
|
||||
{
|
||||
constexpr auto DummyPragmaHandler = [](const auto&, const auto&){ return true; };
|
||||
|
||||
runtime.setDataSource([&](pl::u64 address, pl::u8 *data, size_t size) {
|
||||
testFile.seek(address);
|
||||
testFile.readBuffer(data, size);
|
||||
}, 0x00, testFile.getSize());
|
||||
runtime.setDataSource(0x00, testFile.getSize(),
|
||||
[&](pl::u64 address, pl::u8 *data, size_t size) {
|
||||
testFile.seek(address);
|
||||
testFile.readBuffer(data, size);
|
||||
}
|
||||
);
|
||||
runtime.setDangerousFunctionCallHandler([]{ return true; });
|
||||
runtime.setIncludePaths({ includePath });
|
||||
runtime.addPragma("MIME", DummyPragmaHandler);
|
||||
@@ -74,4 +76,4 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
BIN
tests/patterns/test_data/ar.hexpat.ar
Normal file
BIN
tests/patterns/test_data/ar.hexpat.ar
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/bmp.hexpat.bmp
Normal file
BIN
tests/patterns/test_data/bmp.hexpat.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
BIN
tests/patterns/test_data/chm.hexpat.chm
Normal file
BIN
tests/patterns/test_data/chm.hexpat.chm
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/coff.hexpat.obj
Normal file
BIN
tests/patterns/test_data/coff.hexpat.obj
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/cpio.hexpat.cpio
Normal file
BIN
tests/patterns/test_data/cpio.hexpat.cpio
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/fdt.hexpat.dtb
Normal file
BIN
tests/patterns/test_data/fdt.hexpat.dtb
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/flac.hexpat.flac
Normal file
BIN
tests/patterns/test_data/flac.hexpat.flac
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/gif.hexpat.gif
Normal file
BIN
tests/patterns/test_data/gif.hexpat.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.7 KiB |
BIN
tests/patterns/test_data/gzip.hexpat.gz
Normal file
BIN
tests/patterns/test_data/gzip.hexpat.gz
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/java_class.hexpat.class
Normal file
BIN
tests/patterns/test_data/java_class.hexpat.class
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/macho.hexpat.o
Normal file
BIN
tests/patterns/test_data/macho.hexpat.o
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/nbt.hexpat.nbt
Normal file
BIN
tests/patterns/test_data/nbt.hexpat.nbt
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/ne.hexpat.exe
Normal file
BIN
tests/patterns/test_data/ne.hexpat.exe
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/nro.hexpat.nro
Normal file
BIN
tests/patterns/test_data/nro.hexpat.nro
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/ogg.hexpat.ogg
Normal file
BIN
tests/patterns/test_data/ogg.hexpat.ogg
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/pcx.hexpat.pcx
Normal file
BIN
tests/patterns/test_data/pcx.hexpat.pcx
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/png.hexpat.png
Normal file
BIN
tests/patterns/test_data/png.hexpat.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.8 KiB |
BIN
tests/patterns/test_data/protobuf.hexpat.bin
Normal file
BIN
tests/patterns/test_data/protobuf.hexpat.bin
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/stl.hexpat.stl
Normal file
BIN
tests/patterns/test_data/stl.hexpat.stl
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/tar.hexpat.tar
Normal file
BIN
tests/patterns/test_data/tar.hexpat.tar
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/tga.hexpat.tga
Normal file
BIN
tests/patterns/test_data/tga.hexpat.tga
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/usb.hexpat.bin
Normal file
BIN
tests/patterns/test_data/usb.hexpat.bin
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/wav.hexpat.wav
Normal file
BIN
tests/patterns/test_data/wav.hexpat.wav
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/zip.hexpat.zip
Normal file
BIN
tests/patterns/test_data/zip.hexpat.zip
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/zstd.hexpat.zst
Normal file
BIN
tests/patterns/test_data/zstd.hexpat.zst
Normal file
Binary file not shown.
Reference in New Issue
Block a user