mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-03-31 13:25:58 -05:00
Compare commits
116 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 | ||
|
|
5481c2ff6a | ||
|
|
efa9957935 | ||
|
|
073768fec3 | ||
|
|
ceb322019c | ||
|
|
befd05f8dd | ||
|
|
6a1abd8fec | ||
|
|
b2ebbc6d66 | ||
|
|
24c003b333 | ||
|
|
caea4544ef | ||
|
|
36b107f0ca | ||
|
|
6367f434ab | ||
|
|
2cfd3c43a7 | ||
|
|
4bda291de1 | ||
|
|
ce542887c4 | ||
|
|
44216762fd | ||
|
|
3621144815 | ||
|
|
244dd88098 | ||
|
|
93c53f2d2e | ||
|
|
ccd163b981 | ||
|
|
cfc6a442de | ||
|
|
62b1eb927e | ||
|
|
2baae9c5f6 | ||
|
|
6ccb3bf465 | ||
|
|
fc997133a1 | ||
|
|
966c4e15b0 | ||
|
|
935a26e9f9 | ||
|
|
529c419ca8 | ||
|
|
befd6ef448 | ||
|
|
45da27275d | ||
|
|
60c5f795a0 | ||
|
|
72acac1082 | ||
|
|
a9d6c882ac | ||
|
|
7ecfcd446d | ||
|
|
b094757b03 | ||
|
|
1d0b11372f | ||
|
|
f01ddec350 | ||
|
|
64136ba16c | ||
|
|
1e45938887 | ||
|
|
f32b162647 | ||
|
|
d2685aabf5 | ||
|
|
8027cda032 | ||
|
|
a178509b3c | ||
|
|
56411ae067 | ||
|
|
7ee489237d | ||
|
|
4d97e79097 | ||
|
|
9fec10000a | ||
|
|
b0d8b81861 | ||
|
|
c7fbb661ae | ||
|
|
7e19b4cb10 | ||
|
|
ff2726ce8a | ||
|
|
ed47fa65f1 | ||
|
|
f0963603bf | ||
|
|
15548b92e2 | ||
|
|
87efc6cf54 | ||
|
|
5e48adcb9d |
10
.github/PULL_REQUEST_TEMPLATE/pattern_template.md
vendored
Normal file
10
.github/PULL_REQUEST_TEMPLATE/pattern_template.md
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# Pattern
|
||||
|
||||
[Information about your pattern]
|
||||
|
||||
## Checklist
|
||||
- [ ] A pattern for this format doesn't exist yet (or this PR improves the existing one)
|
||||
- [ ] The new pattern has been added to the relevant table in the Readme
|
||||
- [ ] The pattern was associated with all relevant MIME types (using `#pragma MIME mime-type` in the source code)
|
||||
- [ ] A test file for this pattern has been added to [/tests/patterns/test_data](/tests/patterns/test_data)
|
||||
- Try to keep this file below ~ 1 MB
|
||||
26
.github/workflows/tests.yml
vendored
26
.github/workflows/tests.yml
vendored
@@ -5,6 +5,8 @@ on:
|
||||
branches: [ '*' ]
|
||||
pull_request:
|
||||
branches: [ '*' ]
|
||||
repository_dispatch:
|
||||
types: [run_tests]
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
@@ -34,7 +36,8 @@ jobs:
|
||||
make \
|
||||
python3 \
|
||||
python3-pip \
|
||||
libmagic-dev
|
||||
libmagic-dev \
|
||||
lcov
|
||||
|
||||
sudo pip install jsonschema
|
||||
|
||||
@@ -43,10 +46,11 @@ jobs:
|
||||
cd tests
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
||||
-DLIBPL_ENABLE_TESTS=OFF \
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld --coverage" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld --coverage" \
|
||||
-DLIBPL_ENABLE_TESTS=OFF \
|
||||
-DLIBPL_ENABLE_CLI=OFF \
|
||||
..
|
||||
make -j4
|
||||
|
||||
@@ -54,6 +58,18 @@ jobs:
|
||||
run: |
|
||||
cd tests/build
|
||||
ctest --output-on-failure
|
||||
|
||||
- name: ⚗️ Generate Coverage Report
|
||||
run: |
|
||||
cd tests/build
|
||||
lcov -d ./_deps/pattern_language-build/lib --gcov-tool /usr/bin/gcov-12 -c -o coverage.info
|
||||
|
||||
- name: ⬆️ Upload Coverage Report
|
||||
uses: coverallsapp/github-action@master
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
path-to-lcov: tests/build/coverage.info
|
||||
|
||||
- name: 📎 Validate JSON Files
|
||||
run: |
|
||||
cd constants
|
||||
|
||||
169
README.md
169
README.md
@@ -8,108 +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`, `application/x-sharedlib` | `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 |
|
||||
| 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 |
|
||||
| cstdint | `includes/cstdint.pat` | C integer types |
|
||||
| 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 |
|
||||
| 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 :)
|
||||
|
||||
256
encodings/cyrillic_cp866.tbl
Normal file
256
encodings/cyrillic_cp866.tbl
Normal file
@@ -0,0 +1,256 @@
|
||||
00=NUL
|
||||
01=☺
|
||||
02=☻
|
||||
03=♥
|
||||
04=♦
|
||||
05=♣
|
||||
06=♠
|
||||
07=•
|
||||
08=◘
|
||||
09=○
|
||||
0A=◙
|
||||
0B=♂
|
||||
0C=♀
|
||||
0D=♪
|
||||
0E=♫
|
||||
0F=☼
|
||||
10=►
|
||||
11=◄
|
||||
12=↕
|
||||
13=‼
|
||||
14=¶
|
||||
15=§
|
||||
16=▬
|
||||
17=↨
|
||||
18=↑
|
||||
19=↓
|
||||
1A=→
|
||||
1B=←
|
||||
1C=∟
|
||||
1D=↔
|
||||
1E=▲
|
||||
1F=▼
|
||||
20=
|
||||
21=!
|
||||
22="
|
||||
23=#
|
||||
24=$
|
||||
25=%
|
||||
26=&
|
||||
27='
|
||||
28=(
|
||||
29=)
|
||||
2A=*
|
||||
2B=+
|
||||
2C=,
|
||||
2D=-
|
||||
2E=.
|
||||
2F=/
|
||||
30=0
|
||||
31=1
|
||||
32=2
|
||||
33=3
|
||||
34=4
|
||||
35=5
|
||||
36=6
|
||||
37=7
|
||||
38=8
|
||||
39=9
|
||||
3A=:
|
||||
3B=;
|
||||
3C=<
|
||||
3D==
|
||||
3E=>
|
||||
3F=?
|
||||
40=@
|
||||
41=A
|
||||
42=B
|
||||
43=C
|
||||
44=D
|
||||
45=E
|
||||
46=F
|
||||
47=G
|
||||
48=H
|
||||
49=I
|
||||
4A=J
|
||||
4B=K
|
||||
4C=L
|
||||
4D=M
|
||||
4E=N
|
||||
4F=O
|
||||
50=P
|
||||
51=Q
|
||||
52=R
|
||||
53=S
|
||||
54=T
|
||||
55=U
|
||||
56=V
|
||||
57=W
|
||||
58=X
|
||||
59=Y
|
||||
5A=Z
|
||||
5B=[
|
||||
5C=\
|
||||
5D=]
|
||||
5E=^
|
||||
5F=_
|
||||
60=`
|
||||
61=a
|
||||
62=b
|
||||
63=c
|
||||
64=d
|
||||
65=e
|
||||
66=f
|
||||
67=g
|
||||
68=h
|
||||
69=i
|
||||
6A=j
|
||||
6B=k
|
||||
6C=l
|
||||
6D=m
|
||||
6E=n
|
||||
6F=o
|
||||
70=p
|
||||
71=q
|
||||
72=r
|
||||
73=s
|
||||
74=t
|
||||
75=u
|
||||
76=v
|
||||
77=w
|
||||
78=x
|
||||
79=y
|
||||
7A=z
|
||||
7B={
|
||||
7C=|
|
||||
7D=}
|
||||
7E=~
|
||||
7F=⌂
|
||||
80=А
|
||||
81=Б
|
||||
82=В
|
||||
83=Г
|
||||
84=Д
|
||||
85=Е
|
||||
86=Ж
|
||||
87=З
|
||||
88=И
|
||||
89=Й
|
||||
8A=К
|
||||
8B=Л
|
||||
8C=М
|
||||
8D=Н
|
||||
8E=О
|
||||
8F=П
|
||||
90=Р
|
||||
91=С
|
||||
92=Т
|
||||
93=У
|
||||
94=Ф
|
||||
95=Х
|
||||
96=Ц
|
||||
97=Ч
|
||||
98=Ш
|
||||
99=Щ
|
||||
9A=Ъ
|
||||
9B=Ы
|
||||
9C=Ь
|
||||
9D=Э
|
||||
9E=Ю
|
||||
9F=Я
|
||||
A0=а
|
||||
A1=б
|
||||
A2=в
|
||||
A3=г
|
||||
A4=д
|
||||
A5=е
|
||||
A6=ж
|
||||
A7=з
|
||||
A8=и
|
||||
A9=й
|
||||
AA=к
|
||||
AB=л
|
||||
AC=м
|
||||
AD=н
|
||||
AE=о
|
||||
AF=п
|
||||
B0=░
|
||||
B1=▒
|
||||
B2=▓
|
||||
B3=│
|
||||
B4=┤
|
||||
B5=╡
|
||||
B6=╢
|
||||
B7=╖
|
||||
B8=╕
|
||||
B9=╣
|
||||
BA=║
|
||||
BB=╗
|
||||
BC=╝
|
||||
BD=╜
|
||||
BE=╛
|
||||
BF=┐
|
||||
C0=└
|
||||
C1=┴
|
||||
C2=┬
|
||||
C3=├
|
||||
C4=─
|
||||
C5=┼
|
||||
C6=╞
|
||||
C7=╟
|
||||
C8=╚
|
||||
C9=╔
|
||||
CA=╩
|
||||
CB=╦
|
||||
CC=╠
|
||||
CD=═
|
||||
CE=╬
|
||||
CF=╧
|
||||
D0=╨
|
||||
D1=╤
|
||||
D2=╥
|
||||
D3=╙
|
||||
D4=╘
|
||||
D5=╒
|
||||
D6=╓
|
||||
D7=╫
|
||||
D8=╪
|
||||
D9=┘
|
||||
DA=┌
|
||||
DB=█
|
||||
DC=▄
|
||||
DD=▌
|
||||
DE=▐
|
||||
DF=▀
|
||||
E0=р
|
||||
E1=с
|
||||
E2=т
|
||||
E3=у
|
||||
E4=ф
|
||||
E5=х
|
||||
E6=ц
|
||||
E7=ч
|
||||
E8=ш
|
||||
E9=щ
|
||||
EA=ъ
|
||||
EB=ы
|
||||
EC=ь
|
||||
ED=э
|
||||
EE=ю
|
||||
EF=я
|
||||
F0=Ё
|
||||
F1=ё
|
||||
F2=Є
|
||||
F3=є
|
||||
F4=Ї
|
||||
F5=ї
|
||||
F6=Ў
|
||||
F7=ў
|
||||
F8=°
|
||||
F9=∙
|
||||
FA=·
|
||||
FB=√
|
||||
FC=№
|
||||
FD=¤
|
||||
FE=■
|
||||
FF=
|
||||
16674
encodings/euc_kr.tbl
Normal file
16674
encodings/euc_kr.tbl
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,9 @@
|
||||
00=
|
||||
090D=(R)
|
||||
0A=(BR)
|
||||
08=␈
|
||||
09=␉
|
||||
0A=␊
|
||||
0B=␋
|
||||
0C=␌
|
||||
0D=␍
|
||||
20=
|
||||
21=!
|
||||
22="
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
using uint8_t = u8;
|
||||
using uint16_t = u16;
|
||||
using uint32_t = u32;
|
||||
using uint64_t = u64;
|
||||
using uint128_t = u128;
|
||||
|
||||
using int8_t = s8;
|
||||
using int16_t = s16;
|
||||
using int32_t = s32;
|
||||
using int64_t = s64;
|
||||
using int128_t = s128;
|
||||
|
||||
using size_t = u32;
|
||||
using ssize_t = s32;
|
||||
29
includes/hex/core.pat
Normal file
29
includes/hex/core.pat
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/impl/imhex_check.pat>
|
||||
|
||||
namespace hex::core {
|
||||
|
||||
struct Selection {
|
||||
bool valid;
|
||||
u64 address, size;
|
||||
};
|
||||
|
||||
fn get_selection() {
|
||||
u128 result = builtin::hex::core::get_selection();
|
||||
|
||||
Selection result;
|
||||
if (result == u128(-1)) {
|
||||
result.valid = false;
|
||||
result.address = 0x00;
|
||||
result.size = 0x00;
|
||||
} else {
|
||||
result.valid = true;
|
||||
result.address = result >> 64;
|
||||
result.size = result & u64(-1);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
}
|
||||
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);
|
||||
};
|
||||
|
||||
}
|
||||
11
includes/hex/http.pat
Normal file
11
includes/hex/http.pat
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/impl/imhex_check.pat>
|
||||
|
||||
namespace hex::http {
|
||||
|
||||
fn get(str url) {
|
||||
return builtin::hex::http::get(url);
|
||||
};
|
||||
|
||||
}
|
||||
7
includes/hex/impl/imhex_check.pat
Normal file
7
includes/hex/impl/imhex_check.pat
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef __PL_UNIT_TESTS__
|
||||
#ifndef __IMHEX__
|
||||
|
||||
#error This library is only available in the ImHex Hex editor
|
||||
|
||||
#endif
|
||||
#endif
|
||||
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]];
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace std {
|
||||
|
||||
using uint8_t = u8;
|
||||
using uint16_t = u16;
|
||||
using uint32_t = u32;
|
||||
using uint64_t = u64;
|
||||
using uint128_t = u128;
|
||||
|
||||
using int8_t = s8;
|
||||
using int16_t = s16;
|
||||
using int32_t = s32;
|
||||
using int64_t = s64;
|
||||
using int128_t = s128;
|
||||
|
||||
using float32_t = float;
|
||||
using float64_t = double;
|
||||
|
||||
using size_t = u64;
|
||||
using ssize_t = s64;
|
||||
|
||||
}
|
||||
60
includes/std/core.pat
Normal file
60
includes/std/core.pat
Normal file
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include <std/mem.pat>
|
||||
|
||||
namespace std::core {
|
||||
|
||||
enum BitfieldOrder : u8 {
|
||||
LeftToRight = 0,
|
||||
RightToLeft = 1
|
||||
};
|
||||
|
||||
|
||||
fn has_attribute(ref auto pattern, str attribute) {
|
||||
return builtin::std::core::has_attribute(pattern, attribute);
|
||||
};
|
||||
|
||||
|
||||
fn get_attribute_value(ref auto pattern, str attribute) {
|
||||
return builtin::std::core::get_attribute_value(pattern, attribute);
|
||||
};
|
||||
|
||||
|
||||
fn set_endian(std::mem::Endian endian) {
|
||||
builtin::std::core::set_endian(u32(endian));
|
||||
};
|
||||
|
||||
fn get_endian() {
|
||||
return builtin::std::core::get_endian();
|
||||
};
|
||||
|
||||
|
||||
fn set_bitfield_order(BitfieldOrder order) {
|
||||
builtin::std::core::set_bitfield_order(u32(order));
|
||||
};
|
||||
|
||||
fn get_bitfield_order() {
|
||||
return builtin::std::core::get_bitfield_order();
|
||||
};
|
||||
|
||||
|
||||
fn array_index() {
|
||||
return builtin::std::core::array_index();
|
||||
};
|
||||
|
||||
fn member_count(ref auto pattern) {
|
||||
return builtin::std::core::member_count(pattern);
|
||||
};
|
||||
|
||||
fn has_member(ref auto pattern, str name) {
|
||||
return builtin::std::core::has_member(pattern, name);
|
||||
};
|
||||
|
||||
fn formatted_value(ref auto pattern) {
|
||||
return builtin::std::core::formatted_value(pattern);
|
||||
};
|
||||
|
||||
fn is_valid_enum(ref auto pattern) {
|
||||
return builtin::std::core::is_valid_enum(pattern);
|
||||
};
|
||||
}
|
||||
@@ -12,7 +12,7 @@ namespace std::file {
|
||||
|
||||
|
||||
fn open(str path, Mode mode) {
|
||||
return builtin::std::file::open(path, mode);
|
||||
return builtin::std::file::open(path, u32(mode));
|
||||
};
|
||||
|
||||
fn close(Handle handle) {
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace std::http {
|
||||
|
||||
fn get(str url) {
|
||||
return builtin::std::http::get(url);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -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,14 @@
|
||||
|
||||
namespace std::mem {
|
||||
|
||||
using Section = u128;
|
||||
|
||||
enum Endian : u8 {
|
||||
Native = 0,
|
||||
Big = 1,
|
||||
Little = 2
|
||||
};
|
||||
|
||||
fn eof() {
|
||||
return $ >= std::mem::size();
|
||||
};
|
||||
@@ -29,16 +37,64 @@ namespace std::mem {
|
||||
return builtin::std::mem::find_sequence_in_range(occurrence_index, offsetFrom, offsetTo, bytes);
|
||||
};
|
||||
|
||||
fn read_unsigned(u128 address, u8 size) {
|
||||
return builtin::std::mem::read_unsigned(address, size);
|
||||
fn read_unsigned(u128 address, u8 size, Endian endian = Endian::Native) {
|
||||
return builtin::std::mem::read_unsigned(address, size, u32(endian));
|
||||
};
|
||||
|
||||
fn read_signed(u128 address, u8 size) {
|
||||
return builtin::std::mem::read_signed(address, size);
|
||||
fn read_signed(u128 address, u8 size, Endian endian = Endian::Native) {
|
||||
return builtin::std::mem::read_signed(address, size, u32(endian));
|
||||
};
|
||||
|
||||
fn read_string(u128 address, u8 size) {
|
||||
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]];
|
||||
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace std {
|
||||
|
||||
using i8 = s8;
|
||||
using i16 = s16;
|
||||
using i32 = s32;
|
||||
using i64 = s64;
|
||||
using i128 = s128;
|
||||
|
||||
using f32 = float;
|
||||
using f64 = double;
|
||||
|
||||
using usize = u64;
|
||||
using isize = s64;
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
};
|
||||
@@ -39,15 +55,12 @@ namespace std::string {
|
||||
};
|
||||
|
||||
fn contains(str a, str b) {
|
||||
s32 a_len, b_len;
|
||||
a_len = std::string::length(a);
|
||||
b_len = std::string::length(b);
|
||||
s32 a_len = std::string::length(a);
|
||||
s32 b_len = std::string::length(b);
|
||||
|
||||
s32 i;
|
||||
while (i < a_len - b_len) {
|
||||
for (s32 i = 0, i <= (a_len - b_len), i += 1) {
|
||||
if (std::string::substr(a, i, b_len) == b)
|
||||
return true;
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
32
includes/type/path.pat
Normal file
32
includes/type/path.pat
Normal file
@@ -0,0 +1,32 @@
|
||||
#include <std/mem.pat>
|
||||
|
||||
namespace type {
|
||||
|
||||
struct UnixPathSegment {
|
||||
char string[while(std::mem::read_unsigned($, 1) != '/' && std::mem::read_unsigned($, 1) != 0x00)];
|
||||
char separator [[hidden]];
|
||||
|
||||
if (separator == 0x00) {
|
||||
$ -= 1;
|
||||
break;
|
||||
}
|
||||
} [[sealed, format("type::impl::format_unix_path_segment")]];
|
||||
|
||||
struct UnixPath {
|
||||
UnixPathSegment segments[while(true)];
|
||||
} [[format("type::impl::format_unix_path")]];
|
||||
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_unix_path_segment(UnixPathSegment segment) {
|
||||
return segment.string;
|
||||
};
|
||||
|
||||
fn format_unix_path(UnixPath path) {
|
||||
return std::mem::read_string($, sizeof(path));
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
49
includes/type/size.pat
Normal file
49
includes/type/size.pat
Normal file
@@ -0,0 +1,49 @@
|
||||
#include <std/io.pat>
|
||||
|
||||
namespace type {
|
||||
|
||||
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 {
|
||||
|
||||
fn size_formatter(u128 size) {
|
||||
double sizeFloat = size;
|
||||
|
||||
u32 i = 0;
|
||||
while (sizeFloat >= 1024 && i <= 6) {
|
||||
i += 1;
|
||||
sizeFloat /= 1024;
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
if (size == 1)
|
||||
return std::format("{} Byte", size);
|
||||
else
|
||||
return std::format("{} Bytes", size);
|
||||
} else {
|
||||
str result = std::format("{:.3f} ", sizeFloat);
|
||||
|
||||
if (i == 1)
|
||||
return result + "kiB";
|
||||
else if (i == 2)
|
||||
return result + "MiB";
|
||||
else if (i == 3)
|
||||
return result + "GiB";
|
||||
else if (i == 4)
|
||||
return result + "TiB";
|
||||
else if (i == 5)
|
||||
return result + "PiB";
|
||||
else
|
||||
return result + "EiB";
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,15 +4,26 @@
|
||||
#include <std/time.pat>
|
||||
|
||||
namespace type {
|
||||
|
||||
using time_t = u16 [[format("type::impl::format_time_t")]];
|
||||
|
||||
namespace impl {
|
||||
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")]];
|
||||
|
||||
fn format_time_t(time_t value) {
|
||||
namespace impl {
|
||||
|
||||
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));
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
62
includes/type/types/010.pat
Normal file
62
includes/type/types/010.pat
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
// Explicitly don't add these types to the `type` namespace for usability
|
||||
// namespace type {
|
||||
|
||||
// using char = s8;
|
||||
using byte = s8;
|
||||
using CHAR = s8;
|
||||
using BYTE = s8;
|
||||
|
||||
using uchar = u8;
|
||||
using ubyte = u8;
|
||||
using UCHAR = u8;
|
||||
using UBYTE = u8;
|
||||
|
||||
|
||||
using short = s16;
|
||||
using int16 = s16;
|
||||
using SHORT = s16;
|
||||
using INT16 = s16;
|
||||
|
||||
using ushort = u16;
|
||||
using uint16 = u16;
|
||||
using USHORT = u16;
|
||||
using UINT16 = u16;
|
||||
using WORD = u16;
|
||||
|
||||
using int = s32;
|
||||
using int32 = s32;
|
||||
using long = s32;
|
||||
using INT = s32;
|
||||
using INT32 = s32;
|
||||
using LONG = s32;
|
||||
|
||||
using uint = u32;
|
||||
using uint32 = u32;
|
||||
using ulong = u32;
|
||||
using UINT = u32;
|
||||
using UINT32 = u32;
|
||||
using ULONG = u32;
|
||||
using DWORD = u32;
|
||||
|
||||
using int64 = s64;
|
||||
using quad = s64;
|
||||
using QUAD = s64;
|
||||
using INT64 = s64;
|
||||
using __int64 = s64;
|
||||
|
||||
using uint64 = u64;
|
||||
using uquad = u64;
|
||||
using UQUAD = u64;
|
||||
using UINT64 = u64;
|
||||
using QWORD = u64;
|
||||
using __uint64 = u64;
|
||||
|
||||
// using float = float;
|
||||
using FLOAT = float;
|
||||
|
||||
// using double = double;
|
||||
using DOUBLE = double;
|
||||
|
||||
// }
|
||||
39
includes/type/types/c.pat
Normal file
39
includes/type/types/c.pat
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
// Explicitly don't add these types to the `type` namespace for usability
|
||||
// namespace type {
|
||||
|
||||
using uint8_t = u8;
|
||||
using uint16_t = u16;
|
||||
using uint32_t = u32;
|
||||
using uint64_t = u64;
|
||||
using __uint64_t = u64;
|
||||
using uint128_t = u128;
|
||||
using __uint128_t = u128;
|
||||
|
||||
using int8_t = s8;
|
||||
using int16_t = s16;
|
||||
using int32_t = s32;
|
||||
using int64_t = s64;
|
||||
using __int64_t = s64;
|
||||
using int128_t = s128;
|
||||
using __int128_t = s128;
|
||||
|
||||
using size_t = u64;
|
||||
using ssize_t = s64;
|
||||
|
||||
using uintptr_t = u64;
|
||||
using intptr_t = s64;
|
||||
using ptrdiff_t = s64;
|
||||
|
||||
// using char = char;
|
||||
using wchar_t = char16;
|
||||
using char8_t = char;
|
||||
using char16_t = char16;
|
||||
using char32_t = u32;
|
||||
|
||||
using short = s16;
|
||||
using int = s32;
|
||||
using long = s32;
|
||||
|
||||
// }
|
||||
13
includes/type/types/linux.pat
Normal file
13
includes/type/types/linux.pat
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
// Explicitly don't add these types to the `type` namespace for usability
|
||||
// namespace type {
|
||||
|
||||
using le16 = le u16;
|
||||
using be16 = be u16;
|
||||
using le32 = le u32;
|
||||
using be32 = be u32;
|
||||
using le64 = le u64;
|
||||
using be64 = be u64;
|
||||
|
||||
// }
|
||||
24
includes/type/types/rust.pat
Normal file
24
includes/type/types/rust.pat
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
// Explicitly don't add these types to the `type` namespace for usability
|
||||
// namespace type {
|
||||
|
||||
// using u8 = u8;
|
||||
// using u16 = u16;
|
||||
// using u32 = u32;
|
||||
// using u64 = u64;
|
||||
// using u128 = u128;
|
||||
|
||||
using i8 = s8;
|
||||
using i16 = s16;
|
||||
using i32 = s32;
|
||||
using i64 = s64;
|
||||
using i128 = s128;
|
||||
|
||||
using f32 = float;
|
||||
using f64 = double;
|
||||
|
||||
using usize = u64;
|
||||
using isize = i64;
|
||||
|
||||
// }
|
||||
53
includes/type/types/win32.pat
Normal file
53
includes/type/types/win32.pat
Normal file
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
// Explicitly don't add these types to the `type` namespace for usability
|
||||
// namespace type {
|
||||
|
||||
using BYTE = u8;
|
||||
using WORD = u16;
|
||||
using DWORD = u32;
|
||||
using QWORD = u64;
|
||||
using DWORDLONG = u64;
|
||||
using DWORD32 = u32;
|
||||
using DWORD64 = u64;
|
||||
|
||||
using INT = s32;
|
||||
using UINT = u32;
|
||||
using FLOAT = float;
|
||||
using SHORT = s16;
|
||||
using USHORT = u16;
|
||||
using BOOL = bool;
|
||||
using BOOLEAN = bool;
|
||||
|
||||
using INT8 = s8;
|
||||
using INT16 = s16;
|
||||
using INT32 = s32;
|
||||
using INT64 = s64;
|
||||
using UINT8 = u8;
|
||||
using UINT16 = u16;
|
||||
using UINT32 = u32;
|
||||
using UINT64 = u64;
|
||||
|
||||
using LONG = s32;
|
||||
using ULONG = u32;
|
||||
using LONG32 = s32;
|
||||
using ULONG32 = u32;
|
||||
using LONG64 = s64;
|
||||
using ULONG64 = u64;
|
||||
using LONGLONG = s64;
|
||||
using ULONGLONG = u64;
|
||||
|
||||
using SIZE_T = u64;
|
||||
using SSIZE_T = s64;
|
||||
|
||||
using UCHAR = u8;
|
||||
using CHAR = char;
|
||||
using CCHAR = char;
|
||||
|
||||
using ATOM = WORD;
|
||||
using PVOID = SIZE_T;
|
||||
using HANDLE = PVOID;
|
||||
using HINSTANCE = HANDLE;
|
||||
using HRESULT = LONG;
|
||||
|
||||
// }
|
||||
73
patterns/bencode.hexpat
Normal file
73
patterns/bencode.hexpat
Normal file
@@ -0,0 +1,73 @@
|
||||
#pragma MIME application/x-bittorrent
|
||||
|
||||
#include <std/ctype.pat>
|
||||
#include <std/mem.pat>
|
||||
#include <std/string.pat>
|
||||
|
||||
namespace bencode {
|
||||
|
||||
struct ASCIIDecimal {
|
||||
char value[while(std::ctype::isdigit(std::mem::read_unsigned($, 1)))];
|
||||
} [[sealed, format("bencode::format_ascii_decimal"), transform("bencode::format_ascii_decimal")]];
|
||||
|
||||
fn format_ascii_decimal(ASCIIDecimal adsasd) {
|
||||
return std::string::parse_int(adsasd.value, 10);
|
||||
};
|
||||
|
||||
enum Type : u8 {
|
||||
Integer = 'i',
|
||||
Dictionary = 'd',
|
||||
List = 'l',
|
||||
|
||||
String0 = '0',
|
||||
String1 = '1',
|
||||
String2 = '2',
|
||||
String3 = '3',
|
||||
String4 = '4',
|
||||
String5 = '5',
|
||||
String6 = '6',
|
||||
String7 = '7',
|
||||
String8 = '8',
|
||||
String9 = '9'
|
||||
};
|
||||
|
||||
struct String {
|
||||
ASCIIDecimal length;
|
||||
char separator [[hidden]];
|
||||
char value[length];
|
||||
} [[sealed, format("bencode::format_string"), transform("bencode::format_string")]];
|
||||
|
||||
fn format_string(String string) {
|
||||
return string.value;
|
||||
};
|
||||
|
||||
using Bencode;
|
||||
using Value;
|
||||
|
||||
struct DictionaryEntry {
|
||||
String key;
|
||||
Value value;
|
||||
};
|
||||
|
||||
struct Value {
|
||||
Type type;
|
||||
|
||||
if (type == Type::Dictionary) {
|
||||
DictionaryEntry entry[while(std::mem::read_unsigned($, 1) != 'e')];
|
||||
} else if (type == Type::Integer) {
|
||||
ASCIIDecimal value;
|
||||
char end;
|
||||
} else {
|
||||
$ -= 1;
|
||||
String value;
|
||||
}
|
||||
};
|
||||
|
||||
struct Bencode {
|
||||
Value value[while(!std::mem::eof())] [[inline]];
|
||||
char end;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
bencode::Bencode bencode @ 0x00;
|
||||
128
patterns/bson.hexpat
Normal file
128
patterns/bson.hexpat
Normal file
@@ -0,0 +1,128 @@
|
||||
#pragma MIME application/bson
|
||||
|
||||
#include <type/time.pat>
|
||||
|
||||
enum Type : u8 {
|
||||
Double = 0x01,
|
||||
String = 0x02,
|
||||
EmbeddedDocument = 0x03,
|
||||
Array = 0x04,
|
||||
Binary = 0x05,
|
||||
Undefined = 0x06,
|
||||
ObjectId = 0x07,
|
||||
Boolean = 0x08,
|
||||
UTCDatetime = 0x09,
|
||||
Null = 0x0A,
|
||||
Regex = 0x0B,
|
||||
DBPointer = 0x0C,
|
||||
JavaScript = 0x0D,
|
||||
Symbol = 0x0E,
|
||||
JavaScriptWithScope = 0x0F,
|
||||
Int32 = 0x10,
|
||||
Timestamp = 0x11,
|
||||
Int64 = 0x12,
|
||||
Decimal128 = 0x13,
|
||||
|
||||
MinKey = 0xFF,
|
||||
MaxKey = 0x7F
|
||||
};
|
||||
|
||||
enum Subtype : u8 {
|
||||
GenericBinarySubtype = 0x00,
|
||||
Function = 0x01,
|
||||
BinaryOld = 0x02,
|
||||
UUIDOld = 0x03,
|
||||
UUID = 0x04,
|
||||
MD5 = 0x05,
|
||||
EncryptedBSONValue = 0x06,
|
||||
CompressedBSONColumn = 0x07,
|
||||
UserDefined = 0x80
|
||||
};
|
||||
|
||||
struct Binary {
|
||||
s32 length;
|
||||
Subtype subtype;
|
||||
u8 data[length];
|
||||
};
|
||||
|
||||
struct String {
|
||||
u32 length [[hidden]];
|
||||
char value[length];
|
||||
} [[sealed, format("format_string")]];
|
||||
|
||||
struct CString {
|
||||
char value[];
|
||||
} [[sealed, format("format_string")]];
|
||||
|
||||
fn format_string(auto string) {
|
||||
return string.value;
|
||||
};
|
||||
|
||||
struct ObjectId {
|
||||
type::time32_t timestamp;
|
||||
u8 randomValue[5];
|
||||
u24 counter;
|
||||
};
|
||||
|
||||
struct DBPointer {
|
||||
String name;
|
||||
ObjectId value;
|
||||
};
|
||||
|
||||
|
||||
using Document;
|
||||
|
||||
struct Element {
|
||||
Type type;
|
||||
|
||||
CString name;
|
||||
|
||||
if (type == Type::Double) {
|
||||
double value;
|
||||
} else if (type == Type::String) {
|
||||
String value;
|
||||
} else if (type == Type::EmbeddedDocument) {
|
||||
Document value;
|
||||
} else if (type == Type::Array) {
|
||||
Document value;
|
||||
} else if (type == Type::Binary) {
|
||||
Binary value;
|
||||
} else if (type == Type::Undefined) {
|
||||
/* undefined */
|
||||
} else if (type == Type::ObjectId) {
|
||||
ObjectId value;
|
||||
} else if (type == Type::Boolean) {
|
||||
bool value;
|
||||
} else if (type == Type::UTCDatetime) {
|
||||
type::time64_t value;
|
||||
} else if (type == Type::Null) {
|
||||
/* null */
|
||||
} else if (type == Type::Regex) {
|
||||
CString regexPattern;
|
||||
CString regexOptions;
|
||||
} else if (type == Type::DBPointer) {
|
||||
DBPointer value;
|
||||
} else if (type == Type::JavaScript) {
|
||||
String value;
|
||||
} else if (type == Type::Symbol) {
|
||||
String value;
|
||||
} else if (type == Type::JavaScriptWithScope) {
|
||||
String value;
|
||||
} else if (type == Type::Int32) {
|
||||
s32 value;
|
||||
} else if (type == Type::Timestamp) {
|
||||
u64 value;
|
||||
} else if (type == Type::Int64) {
|
||||
s64 value;
|
||||
} else if (type == Type::Decimal128) {
|
||||
u128 value;
|
||||
}
|
||||
};
|
||||
|
||||
struct Document {
|
||||
s32 listLength;
|
||||
Element elements[while($ < ((addressof(this) + listLength) - 1))];
|
||||
padding[1];
|
||||
};
|
||||
|
||||
Document document @ 0x00;
|
||||
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;
|
||||
@@ -1,261 +1,744 @@
|
||||
#pragma MIME application/x-executable
|
||||
#pragma MIME application/x-elf
|
||||
#pragma MIME application/x-coredump
|
||||
#pragma MIME application/x-object
|
||||
#pragma MIME application/x-sharedlib
|
||||
|
||||
namespace elf {
|
||||
#include <std/core.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
enum Class : u8 {
|
||||
_32Bit = 1,
|
||||
_64Bit = 2
|
||||
};
|
||||
|
||||
enum Endian : u8 {
|
||||
Little = 1,
|
||||
Big = 2
|
||||
};
|
||||
|
||||
enum OSABI : u8 {
|
||||
SystemV = 0x00,
|
||||
HP_UX = 0x01,
|
||||
NetBSD = 0x02,
|
||||
Linux = 0x03,
|
||||
GNU_Hurd = 0x04,
|
||||
Solaris = 0x06,
|
||||
AIX = 0x07,
|
||||
IRIX = 0x08,
|
||||
FreeBSD = 0x09,
|
||||
Tru64 = 0x0A,
|
||||
NovellModesto = 0x0B,
|
||||
OpenBSD = 0x0C,
|
||||
OpenVMS = 0x0D,
|
||||
NonStop_Kernel = 0x0E,
|
||||
AROS = 0x0F,
|
||||
FenixOS = 0x10,
|
||||
CloudABI = 0x11,
|
||||
Stratus_Technologies_OpenVOS = 0x12
|
||||
};
|
||||
|
||||
enum Type : u16 {
|
||||
using EI_ABIVERSION = u8;
|
||||
using Elf32_Addr = u32;
|
||||
using Elf32_BaseAddr = u32;
|
||||
using Elf32_BaseOff = u32;
|
||||
using Elf32_Half = u16;
|
||||
using Elf32_Off = u32;
|
||||
using Elf32_Sword = s32;
|
||||
using Elf32_VAddr = u32;
|
||||
using Elf32_Word = u32;
|
||||
using Elf64_Addr = u64;
|
||||
using Elf64_BaseAddr = u64;
|
||||
using Elf64_BaseOff = u64;
|
||||
using Elf64_Half = u16;
|
||||
using Elf64_Off = u64;
|
||||
using Elf64_Sword = s32;
|
||||
using Elf64_Sxword = s64;
|
||||
using Elf64_VAddr = u64;
|
||||
using Elf64_Word = u32;
|
||||
using Elf64_Xword = u64;
|
||||
using E_VERSION = u32;
|
||||
|
||||
enum EI_CLASS : u8 {
|
||||
ELFCLASSNONE = 0x00,
|
||||
ELFCLASS32 = 0x01,
|
||||
ELFCLASS64 = 0x02,
|
||||
};
|
||||
|
||||
enum EI_DATA : u8 {
|
||||
ELFDATANONE = 0x00,
|
||||
ELFDATA2LSB = 0x01,
|
||||
ELFDATA2MSB = 0x02,
|
||||
};
|
||||
|
||||
enum EI_OSABI : u8 {
|
||||
SYSV = 0x00,
|
||||
HPUX = 0x01,
|
||||
NetBSD = 0x02,
|
||||
Linux = 0x03,
|
||||
GNUHurd = 0x04,
|
||||
Solaris = 0x06,
|
||||
AIX = 0x07,
|
||||
IRIX = 0x08,
|
||||
FreeBSD = 0x09,
|
||||
Tru64 = 0x0A,
|
||||
NovellModesto = 0x0B,
|
||||
OpenBSD = 0x0C,
|
||||
OpenVMS = 0x0D,
|
||||
NonStopKernel = 0x0E,
|
||||
AROS = 0x0F,
|
||||
FenixOS = 0x10,
|
||||
CloudABI = 0x11,
|
||||
OpenVOS = 0x12,
|
||||
ARM_EABI = 0x40,
|
||||
STANDALONE = 0xFF,
|
||||
};
|
||||
|
||||
enum EI_VERSION : u8 {
|
||||
NONE = 0x00,
|
||||
REL = 0x01,
|
||||
EXEC = 0x02,
|
||||
DYN = 0x03,
|
||||
CORE = 0x04,
|
||||
LOOS = 0xFE00,
|
||||
HIOS = 0xFEFF,
|
||||
LOPROC = 0xFF00,
|
||||
HIPROC = 0xFFFF
|
||||
};
|
||||
|
||||
enum Machine : u16 {
|
||||
Undefined = 0x00,
|
||||
ATNT_WE_32100 = 0x01,
|
||||
SPARC = 0x02,
|
||||
x86 = 0x03,
|
||||
Motorola_68000 = 0x04,
|
||||
Motorola_88000 = 0x05,
|
||||
IntelMCU = 0x06,
|
||||
Intel_80860 = 0x07,
|
||||
MIPS = 0x08,
|
||||
IBM_System370 = 0x09,
|
||||
MIPS_RS300_LE = 0x0A,
|
||||
/* 0x0B - 0x0D: Reserved */
|
||||
HP_PA_RISC = 0x0E,
|
||||
/* 0x0F: Reserved */
|
||||
Intel_80960 = 0x13,
|
||||
PowerPC = 0x14,
|
||||
PowerPC_64 = 0x15,
|
||||
S390 = 0x16,
|
||||
IBM_SPU_SPC = 0x17,
|
||||
/* 0x18 - 0x23: Reserved */
|
||||
NEC_V800 = 0x24,
|
||||
Fujitsu_FR20 = 0x25,
|
||||
TRW_RH_32 = 0x26,
|
||||
Motorola_RCE = 0x27,
|
||||
ARM32 = 0x28,
|
||||
Digital_Alpha = 0x29,
|
||||
SuperH = 0x2A,
|
||||
SPARCv9 = 0x2B,
|
||||
Siemens_TriCore = 0x2C,
|
||||
Argonaut_RISC_Core = 0x2D,
|
||||
Hitachi_H8_300 = 0x2E,
|
||||
Hitachi_H8_300H = 0x2F,
|
||||
Hitachi_H8S = 0x30,
|
||||
Hitachi_H8_500 = 0x31,
|
||||
IA_64 = 0x32,
|
||||
Standford_MIPS_X = 0x33,
|
||||
Motorola_ColdFire = 0x34,
|
||||
Motorola_M68HC12 = 0x35,
|
||||
Fujitsu_MMA = 0x36,
|
||||
Siemens_PCP = 0x37,
|
||||
Sony_nCPU = 0x38,
|
||||
Denso_NDR1 = 0x39,
|
||||
Motorola_StarCore = 0x3A,
|
||||
Toyota_ME16 = 0x3B,
|
||||
STMicroelectronics_ST100 = 0x3C,
|
||||
Advanced_Logic_Corp_TinyJ = 0x3D,
|
||||
AMD_x86_64 = 0x3E,
|
||||
TMS320C6000 = 0x8C,
|
||||
MCST_Elbrus_e2k = 0xAF,
|
||||
ARM64 = 0xB7,
|
||||
RISC_V = 0xF3,
|
||||
Berkeley_Packet_Filter = 0xF7,
|
||||
WDC_65C816 = 0x101
|
||||
};
|
||||
|
||||
struct Identity {
|
||||
char magic[4];
|
||||
Class class;
|
||||
Endian endian;
|
||||
u8 version;
|
||||
OSABI os_abi;
|
||||
|
||||
if (os_abi == elf::OSABI::Linux)
|
||||
u8 dynamic_linker_version;
|
||||
else
|
||||
u8 abi_version;
|
||||
};
|
||||
CURRENT = 0x01,
|
||||
};
|
||||
|
||||
struct Header {
|
||||
Identity identity;
|
||||
enum EM : u16 {
|
||||
EM_NONE = 0x0000,
|
||||
EM_M32 = 0x0001,
|
||||
EM_SPARC = 0x0002,
|
||||
EM_386 = 0x0003,
|
||||
EM_68K = 0x0004,
|
||||
EM_88K = 0x0005,
|
||||
EM_IAMCU = 0x0006,
|
||||
EM_860 = 0x0007,
|
||||
EM_MIPS = 0x0008,
|
||||
EM_S370 = 0x0009,
|
||||
EM_MIPS_RS4_BE = 0x000a,
|
||||
EM_PARISC = 0x000f,
|
||||
EM_VPP500 = 0x0011,
|
||||
EM_SPARC32PLUS = 0x0012,
|
||||
EM_960 = 0x0013,
|
||||
EM_PPC = 0x0014,
|
||||
EM_PPC64 = 0x0015,
|
||||
EM_S390 = 0x0016,
|
||||
EM_SPU = 0x0017,
|
||||
EM_V800 = 0x0024,
|
||||
EM_FR20 = 0x0025,
|
||||
EM_RH32 = 0x0026,
|
||||
EM_RCE = 0x0027,
|
||||
EM_ARM = 0x0028,
|
||||
EM_ALPHA = 0x0029,
|
||||
EM_SH = 0x002A,
|
||||
EM_SPARCV9 = 0x002B,
|
||||
EM_TRICORE = 0x002C,
|
||||
EM_ARC = 0x002D,
|
||||
EM_H8_300 = 0x002E,
|
||||
EM_H8_300H = 0x002F,
|
||||
EM_H8S = 0x0030,
|
||||
EM_H8_500 = 0x0031,
|
||||
EM_IA_64 = 0x0032,
|
||||
EM_MIPS_X = 0x0033,
|
||||
EM_COLDFIRE = 0x0034,
|
||||
EM_68HC12 = 0x0035,
|
||||
EM_MMA = 0x0036,
|
||||
EM_PCP = 0x0037,
|
||||
EM_NCPU = 0x0038,
|
||||
EM_NDR1 = 0x0039,
|
||||
EM_STARCORE = 0x003A,
|
||||
EM_ME16 = 0x003B,
|
||||
EM_ST100 = 0x003C,
|
||||
EM_TINYJ = 0x003D,
|
||||
EM_X86_64 = 0x003E,
|
||||
EM_PDSP = 0x003F,
|
||||
EM_PDP10 = 0x0040,
|
||||
EM_PDP11 = 0x0041,
|
||||
EM_FX66 = 0x0042,
|
||||
EM_ST9PLUS = 0x0043,
|
||||
EM_ST7 = 0x0044,
|
||||
EM_68HC16 = 0x0045,
|
||||
EM_68HC11 = 0x0046,
|
||||
EM_68HC08 = 0x0047,
|
||||
EM_68HC05 = 0x0048,
|
||||
EM_SVX = 0x0049,
|
||||
EM_ST19 = 0x004A,
|
||||
EM_VAX = 0x004B,
|
||||
EM_CRIS = 0x004C,
|
||||
EM_JAVELIN = 0x004D,
|
||||
EM_FIREPATH = 0x004E,
|
||||
EM_ZSP = 0x004F,
|
||||
EM_MMIX = 0x0050,
|
||||
EM_HUANY = 0x0051,
|
||||
EM_PRISM = 0x0052,
|
||||
EM_AVR = 0x0053,
|
||||
EM_FR30 = 0x0054,
|
||||
EM_D10V = 0x0055,
|
||||
EM_D30V = 0x0056,
|
||||
EM_V850 = 0x0057,
|
||||
EM_M32R = 0x0058,
|
||||
EM_MN10300 = 0x0059,
|
||||
EM_MN10200 = 0x005A,
|
||||
EM_PJ = 0x005B,
|
||||
EM_OPENRISC = 0x005C,
|
||||
EM_ARC_COMPACT = 0x005D,
|
||||
EM_XTENSA = 0x005E,
|
||||
EM_VIDEOCORE = 0x005F,
|
||||
EM_TMM_GPP = 0x0060,
|
||||
EM_NS32K = 0x0061,
|
||||
EM_TPC = 0x0062,
|
||||
EM_SNP1K = 0x0063,
|
||||
EM_ST200 = 0x0064,
|
||||
EM_IP2K = 0x0065,
|
||||
EM_MAX = 0x0066,
|
||||
EM_CR = 0x0067,
|
||||
EM_F2MC16 = 0x0068,
|
||||
EM_MSP430 = 0x0069,
|
||||
EM_BLACKFIN = 0x006A,
|
||||
EM_SE_C33 = 0x006B,
|
||||
EM_SEP = 0x006C,
|
||||
EM_ARCA = 0x006D,
|
||||
EM_UNICORE = 0x006E,
|
||||
EM_EXCESS = 0x006F,
|
||||
EM_DXP = 0x0070,
|
||||
EM_ALTERA_NIOS2 = 0x0071,
|
||||
EM_CRX = 0x0072,
|
||||
EM_XGATE = 0x0073,
|
||||
EM_C166 = 0x0074,
|
||||
EM_M16C = 0x0075,
|
||||
EM_DSPIC30F = 0x0076,
|
||||
EM_CE = 0x0077,
|
||||
EM_M32C = 0x0078,
|
||||
EM_TSK3000 = 0x0083,
|
||||
EM_RS08 = 0x0084,
|
||||
EM_SHARC = 0x0085,
|
||||
EM_ECOG2 = 0x0086,
|
||||
EM_SCORE7 = 0x0087,
|
||||
EM_DSP24 = 0x0088,
|
||||
EM_VIDEOCORE3 = 0x0089,
|
||||
EM_LATTICEMICO32 = 0x008A,
|
||||
EM_SE_C17 = 0x008B,
|
||||
EM_TI_C6000 = 0x008C,
|
||||
EM_TI_C2000 = 0x008D,
|
||||
EM_TI_C5500 = 0x008E,
|
||||
EM_TI_ARP32 = 0x008F,
|
||||
EM_TI_PRU = 0x0090,
|
||||
EM_MMDSP_PLUS = 0x00A0,
|
||||
EM_CYPRESS_M8C = 0x00A1,
|
||||
EM_R32C = 0x00A2,
|
||||
EM_TRIMEDIA = 0x00A3,
|
||||
EM_QDSP6 = 0x00A4,
|
||||
EM_8051 = 0x00A5,
|
||||
EM_STXP7X = 0x00A6,
|
||||
EM_NDS32 = 0x00A7,
|
||||
EM_ECOG1 = 0x00A8,
|
||||
EM_ECOG1X = 0x00A8,
|
||||
EM_MAXQ30 = 0x00A9,
|
||||
EM_XIMO16 = 0x00AA,
|
||||
EM_MANIK = 0x00AB,
|
||||
EM_CRAYNV2 = 0x00AC,
|
||||
EM_RX = 0x00AD,
|
||||
EM_METAG = 0x00AE,
|
||||
EM_MCST_ELBRUS = 0x00AF,
|
||||
EM_ECOG16 = 0x00B0,
|
||||
EM_CR16 = 0x00B1,
|
||||
EM_ETPU = 0x00B2,
|
||||
EM_SLE9X = 0x00B3,
|
||||
EM_L10M = 0x00B4,
|
||||
EM_K10M = 0x00B5,
|
||||
EM_AARCH64 = 0x00B7,
|
||||
EM_AVR32 = 0x00B9,
|
||||
EM_STM8 = 0x00BA,
|
||||
EM_TILE64 = 0x00BB,
|
||||
EM_TILEPRO = 0x00BC,
|
||||
EM_MICROBLAZE = 0x00BD,
|
||||
EM_CUDA = 0x00BE,
|
||||
EM_TILEGX = 0x00BF,
|
||||
EM_CLOUDSHIELD = 0x00C0,
|
||||
EM_COREA_1ST = 0x00C1,
|
||||
EM_COREA_2ND = 0x00C2,
|
||||
EM_ARC_COMPACT2 = 0x00C3,
|
||||
EM_OPEN8 = 0x00C4,
|
||||
EM_RL78 = 0x00C5,
|
||||
EM_VIDEOCORE5 = 0x00C6,
|
||||
EM_78KOR = 0x00C7,
|
||||
EM_56800EX = 0x00C8,
|
||||
EM_BA1 = 0x00C9,
|
||||
EM_BA2 = 0x00CA,
|
||||
EM_XCORE = 0x00CB,
|
||||
EM_MCHP_PIC = 0x00CC,
|
||||
EM_INTEL205 = 0x00CD,
|
||||
EM_INTEL206 = 0x00CE,
|
||||
EM_INTEL207 = 0x00CF,
|
||||
EM_INTEL208 = 0x00D0,
|
||||
EM_INTEL209 = 0x00D1,
|
||||
EM_KM32 = 0x00D2,
|
||||
EM_KMX32 = 0x00D3,
|
||||
EM_KMX16 = 0x00D4,
|
||||
EM_KMX8 = 0x00D5,
|
||||
EM_KVARC = 0x00D6,
|
||||
EM_CDP = 0x00D7,
|
||||
EM_COGE = 0x00D8,
|
||||
EM_COOL = 0x00D9,
|
||||
EM_NORC = 0x00DA,
|
||||
EM_CSR_KALIMBA = 0x00DB,
|
||||
EM_Z80 = 0x00DC,
|
||||
EM_VISIUM = 0x00DD,
|
||||
EM_FT32 = 0x00DE,
|
||||
EM_MOXIE = 0x00DF,
|
||||
EM_AMDGPU = 0x00E0,
|
||||
EM_RISCV = 0x00F3,
|
||||
};
|
||||
|
||||
enum ET : u16 {
|
||||
NONE = 0x0000,
|
||||
REL = 0x0001,
|
||||
EXEC = 0x0002,
|
||||
DYN = 0x0003,
|
||||
CORE = 0x0004,
|
||||
};
|
||||
|
||||
enum DT : u32 {
|
||||
DT_NULL = 0x0,
|
||||
DT_NEEDED = 0x1,
|
||||
DT_PLTRELSZ = 0x2,
|
||||
DT_PLTGOT = 0x3,
|
||||
DT_HASH = 0x4,
|
||||
DT_STRTAB = 0x5,
|
||||
DT_SYMTAB = 0x6,
|
||||
DT_RELA = 0x7,
|
||||
DT_RELASZ = 0x8,
|
||||
DT_RELAENT = 0x9,
|
||||
DT_STRSZ = 0xA,
|
||||
DT_SYMENT = 0xB,
|
||||
DT_INIT = 0xC,
|
||||
DT_FINI = 0xD,
|
||||
DT_SONAME = 0xE,
|
||||
DT_RPATH = 0xF,
|
||||
DT_SYMBOLIC = 0x10,
|
||||
DT_REL = 0x11,
|
||||
DT_RELSZ = 0x12,
|
||||
DT_RELENT = 0x13,
|
||||
DT_PLTREL = 0x14,
|
||||
DT_DEBUG = 0x15,
|
||||
DT_TEXTREL = 0x16,
|
||||
DT_JMPREL = 0x17,
|
||||
DT_BIND_NOW = 0x18,
|
||||
DT_INIT_ARRAY = 0x19,
|
||||
DT_FINI_ARRAY = 0x1A,
|
||||
DT_INIT_ARRAYSZ = 0x1B,
|
||||
DT_FINI_ARRAYSZ = 0x1C,
|
||||
DT_RUNPATH = 0x1D,
|
||||
DT_FLAGS = 0x1E,
|
||||
DT_PREINIT_ARRAY = 0x20,
|
||||
DT_PREINIT_ARRAYSZ = 0x21,
|
||||
DT_MAXPOSTAGS = 0x22,
|
||||
DT_NUM = 0x23,
|
||||
DT_GNU_PRELINKED = 0x6FFFFDF5,
|
||||
DT_GNU_CONFLICTSZ = 0x6FFFFDF6,
|
||||
DT_GNU_LIBLISTSZ = 0x6FFFFDF7,
|
||||
DT_CHECKSUM = 0x6FFFFDF8,
|
||||
DT_PLTPADSZ = 0x6FFFFDF9,
|
||||
DT_MOVEENT = 0x6FFFFDFA,
|
||||
DT_MOVESZ = 0x6FFFFDFB,
|
||||
DT_FEATURE_1 = 0x6FFFFDFC,
|
||||
DT_POSFLAG_1 = 0x6FFFFDFD,
|
||||
DT_SYMINSZ = 0x6FFFFDFE,
|
||||
DT_SYMINENT = 0x6FFFFDFF,
|
||||
DT_GNU_HASH = 0x6FFFFEF5,
|
||||
DT_TLSDESC_PLT = 0x6FFFFEF6,
|
||||
DT_TLSDESC_GOT = 0x6FFFFEF7,
|
||||
DT_GNU_CONFLICT = 0x6FFFFEF8,
|
||||
DT_GNU_LIBLIST = 0x6FFFFEF9,
|
||||
DT_CONFIG = 0x6FFFFEFA,
|
||||
DT_DEPAUDIT = 0x6FFFFEFB,
|
||||
DT_AUDIT = 0x6FFFFEFC,
|
||||
DT_PLTPAD = 0x6FFFFEFD,
|
||||
DT_MOVETAB = 0x6FFFFEFE,
|
||||
DT_SYMINFO = 0x6FFFFEFF,
|
||||
DT_VERSYM = 0x6FFFFFF0,
|
||||
DT_RELACOUNT = 0x6FFFFFF9,
|
||||
DT_RELCOUNT = 0x6FFFFFFA,
|
||||
DT_FLAGS_1 = 0x6FFFFFFB,
|
||||
DT_VERDEF = 0x6FFFFFFC,
|
||||
DT_VERDEFNUM = 0x6FFFFFFD,
|
||||
DT_VERNEED = 0x6FFFFFFE,
|
||||
DT_VERNEEDNUM = 0x6FFFFFFF,
|
||||
DT_AUXILIARY = 0x7FFFFFFD,
|
||||
DT_USED = 0x7FFFFFFE,
|
||||
DT_FILTER = 0x7FFFFFFF,
|
||||
DT_DEPRECATED_SPARC_REGISTER = 0x7000001,
|
||||
DT_SUNW_AUXILIARY = 0x6000000D,
|
||||
DT_SUNW_RTLDINF = 0x6000000E,
|
||||
DT_SUNW_FILTER = 0x6000000F,
|
||||
DT_SUNW_CAP = 0x60000010,
|
||||
DT_SUNW_SYMTAB = 0x60000011,
|
||||
DT_SUNW_SYMSZ = 0x60000012,
|
||||
DT_SUNW_SORTENT = 0x60000013,
|
||||
DT_SUNW_SYMSORT = 0x60000014,
|
||||
DT_SUNW_SYMSORTSZ = 0x60000015,
|
||||
DT_SUNW_TLSSORT = 0x60000016,
|
||||
DT_SUNW_TLSSORTSZ = 0x60000017,
|
||||
DT_SUNW_STRPAD = 0x60000019,
|
||||
DT_SUNW_LDMACH = 0x6000001B,
|
||||
};
|
||||
|
||||
enum RT : Elf32_Word {
|
||||
CONSISTENT = 0x00,
|
||||
ADD = 0x01,
|
||||
DELETE = 0x02,
|
||||
};
|
||||
|
||||
enum PT : Elf32_Word {
|
||||
NULL = 0x00,
|
||||
LOAD = 0x01,
|
||||
DYNAMIC = 0x02,
|
||||
INTERP = 0x03,
|
||||
NOTE = 0x04,
|
||||
SHLIB = 0x05,
|
||||
PHDR = 0x06,
|
||||
TLS = 0x07,
|
||||
LOOS = 0x60000000,
|
||||
HIOS = 0x6FFFFFFF,
|
||||
GNU_EH_FRAME = PT::LOOS + 0x474E550,
|
||||
GNU_STACK = PT::LOOS + 0x474E551,
|
||||
GNU_RELRO = PT::LOOS + 0x474E552,
|
||||
GNU_PROPERTY = PT::LOOS + 0x474E553,
|
||||
SUNWBSS = 0x6FFFFFFA,
|
||||
SUNWSTACK = 0x6FFFFFFB,
|
||||
ARM_ARCHEXT = 0x70000000,
|
||||
ARM_UNWIND = 0x70000001,
|
||||
};
|
||||
|
||||
enum ELFCOMPRESS : u8 {
|
||||
ZLIB = 0x01,
|
||||
};
|
||||
|
||||
enum SHN : u16 {
|
||||
UNDEF = 0x00,
|
||||
BEFORE = 0xFF00,
|
||||
AFTER = 0xFF01,
|
||||
ABS = 0xFFF1,
|
||||
COMMON = 0xFFF2,
|
||||
XINDEX = 0xFFFF,
|
||||
};
|
||||
|
||||
enum SHT : Elf32_Word {
|
||||
NULL = 0x00,
|
||||
PROGBITS = 0x01,
|
||||
SYMTAB = 0x02,
|
||||
STRTAB = 0x03,
|
||||
RELA = 0x04,
|
||||
HASH = 0x05,
|
||||
DYNAMIC = 0x06,
|
||||
NOTE = 0x07,
|
||||
NOBITS = 0x08,
|
||||
REL = 0x09,
|
||||
SHLIB = 0x0A,
|
||||
DYNSYM = 0x0B,
|
||||
UNKNOWN12 = 0x0C,
|
||||
UNKNOWN13 = 0x0D,
|
||||
INIT_ARRAY = 0x0E,
|
||||
FINI_ARRAY = 0x0F,
|
||||
PREINIT_ARRAY = 0x10,
|
||||
GROUP = 0x11,
|
||||
SYMTAB_SHNDX = 0x12,
|
||||
GNU_INCREMENTAL_INPUTS = 0x6FFF4700,
|
||||
GNU_ATTRIBUTES = 0x6FFFFFF5,
|
||||
GNU_HASH = 0x6FFFFFF6,
|
||||
GNU_LIBLIST = 0x6FFFFFF7,
|
||||
CHECKSUM = 0x6FFFFFF8,
|
||||
SUNW_move = 0x6FFFFFFA,
|
||||
SUNW_COMDAT = 0x6FFFFFFB,
|
||||
SUNW_syminfo = 0x6FFFFFFC,
|
||||
GNU_verdef = 0x6FFFFFFD,
|
||||
GNU_verneed = 0x6FFFFFFE,
|
||||
GNU_versym = 0x6FFFFFFF,
|
||||
ARM_EXIDX = 0x70000001,
|
||||
ARM_PREEMPTMAP = 0x70000002,
|
||||
ARM_ATTRIBUTES = 0x70000003,
|
||||
ARM_DEBUGOVERLAY = 0x70000004,
|
||||
ARM_OVERLAYSECTION = 0x70000005,
|
||||
};
|
||||
|
||||
enum STV : u8 {
|
||||
DEFAULT = 0x00,
|
||||
INTERNAL = 0x01,
|
||||
HIDDEN = 0x02,
|
||||
PROTECTED = 0x03,
|
||||
};
|
||||
|
||||
enum SYMINFO_BT : Elf32_Half {
|
||||
SELF = 0xFFFF,
|
||||
PARENT = 0xFFFE,
|
||||
NONE = 0xFFFD,
|
||||
};
|
||||
|
||||
enum VER_DEF : Elf32_Half {
|
||||
NON = 0x00,
|
||||
CURRENT = 0x01,
|
||||
NUM = 0x02,
|
||||
};
|
||||
|
||||
enum VER_NDX : Elf32_Half {
|
||||
LOCAL = 0x00,
|
||||
GLOBAL = 0x01,
|
||||
ELIMINATE = 0xFF01,
|
||||
};
|
||||
|
||||
enum VER_NEED : Elf32_Half {
|
||||
NONE = 0x00,
|
||||
CURRENT = 0x01,
|
||||
NUM = 0x02,
|
||||
};
|
||||
|
||||
bitfield SYMINFO_FLG {
|
||||
padding : 10;
|
||||
NOEXTDIRECT : 1;
|
||||
DIRECTBIND : 1;
|
||||
LAZYLOAD : 1;
|
||||
COPY : 1;
|
||||
RESERVED : 1;
|
||||
DIRECT : 1;
|
||||
} [[left_to_right]];
|
||||
|
||||
bitfield ST {
|
||||
ST_BIND : 4;
|
||||
ST_TYPE : 4;
|
||||
} [[left_to_right]];
|
||||
|
||||
bitfield SHF {
|
||||
MASKPROC : 4;
|
||||
MASKOS : 8;
|
||||
UNKNOWN : 8;
|
||||
COMPRESSED : 1;
|
||||
TLS : 1;
|
||||
GROUP : 1;
|
||||
OS_NONCONFORMING : 1;
|
||||
LINK_ORDER : 1;
|
||||
INFO_LINK : 1;
|
||||
STRINGS : 1;
|
||||
MERGE : 1;
|
||||
padding : 1;
|
||||
EXECINSTR : 1;
|
||||
ALLOC : 1;
|
||||
WRITE : 1;
|
||||
} [[left_to_right]];
|
||||
|
||||
bitfield ELF32_R_INFO {
|
||||
SYM : 8;
|
||||
TYPE : 8;
|
||||
} [[left_to_right]];
|
||||
|
||||
bitfield ELF64_R_INFO {
|
||||
SYM : 32;
|
||||
TYPE : 32;
|
||||
} [[left_to_right]];
|
||||
|
||||
bitfield PF {
|
||||
MASKPROC : 4;
|
||||
MASKOS : 4;
|
||||
padding : 17;
|
||||
R : 1;
|
||||
W : 1;
|
||||
X : 1;
|
||||
} [[left_to_right]];
|
||||
|
||||
struct E_IDENT {
|
||||
char EI_MAG[4];
|
||||
EI_CLASS EI_CLASS;
|
||||
EI_DATA EI_DATA;
|
||||
EI_VERSION EI_VERSION;
|
||||
EI_OSABI EI_OSABI;
|
||||
EI_ABIVERSION EI_ABIVERSION;
|
||||
padding[7];
|
||||
Type type;
|
||||
Machine machine;
|
||||
u32 version;
|
||||
};
|
||||
|
||||
struct Elf32_Ehdr {
|
||||
ET e_type;
|
||||
EM e_machine;
|
||||
E_VERSION e_version;
|
||||
Elf32_VAddr e_entry;
|
||||
Elf32_Off e_phoff;
|
||||
Elf32_Off e_shoff;
|
||||
Elf32_Word e_flags;
|
||||
Elf32_Half e_ehsize;
|
||||
Elf32_Half e_phentsize;
|
||||
Elf32_Half e_phnum;
|
||||
Elf32_Half e_shentsize;
|
||||
Elf32_Half e_shnum;
|
||||
Elf32_Half e_shstrndx;
|
||||
};
|
||||
|
||||
struct Elf64_Ehdr {
|
||||
ET e_type;
|
||||
EM e_machine;
|
||||
E_VERSION e_version;
|
||||
Elf64_VAddr e_entry;
|
||||
Elf64_Off e_phoff;
|
||||
Elf64_Off e_shoff;
|
||||
Elf64_Word e_flags;
|
||||
Elf64_Half e_ehsize;
|
||||
Elf64_Half e_phentsize;
|
||||
Elf64_Half e_phnum;
|
||||
Elf64_Half e_shentsize;
|
||||
Elf64_Half e_shnum;
|
||||
Elf64_Half e_shstrndx;
|
||||
};
|
||||
|
||||
struct Elf32_Phdr {
|
||||
PT p_type;
|
||||
Elf32_Off p_offset;
|
||||
Elf32_Addr p_vaddr;
|
||||
Elf32_Addr p_paddr;
|
||||
Elf32_Word p_filesz;
|
||||
Elf32_Word p_memsz;
|
||||
PF p_flags;
|
||||
Elf32_Word p_align;
|
||||
|
||||
if (identity.class == elf::Class::_32Bit) {
|
||||
u32 entry_point;
|
||||
u32 program_header_offset;
|
||||
u32 section_header_offset;
|
||||
} else {
|
||||
u64 entry_point;
|
||||
u64 program_header_offset;
|
||||
u64 section_header_offset;
|
||||
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;
|
||||
};
|
||||
|
||||
struct Elf64_Phdr {
|
||||
PT p_type;
|
||||
PF p_flags;
|
||||
Elf64_Off p_offset;
|
||||
Elf64_Addr p_vaddr;
|
||||
Elf64_Addr p_paddr;
|
||||
Elf64_Xword p_filesz;
|
||||
Elf64_Xword p_memsz;
|
||||
Elf64_Xword p_align;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
struct Elf32_Chdr {
|
||||
u32 ch_type;
|
||||
Elf32_Word ch_size;
|
||||
Elf32_Word ch_addralign;
|
||||
};
|
||||
|
||||
struct Elf32_Rel {
|
||||
Elf32_Off r_offset;
|
||||
ELF32_R_INFO r_info;
|
||||
};
|
||||
|
||||
struct Elf32_Rela {
|
||||
Elf32_Off r_offset;
|
||||
ELF32_R_INFO r_info;
|
||||
Elf32_Sword r_addend;
|
||||
};
|
||||
|
||||
struct Elf32_Sym {
|
||||
u32 st_name;
|
||||
Elf32_VAddr st_value;
|
||||
Elf32_Word st_size;
|
||||
ST st_info;
|
||||
STV st_other;
|
||||
u16 st_shndx;
|
||||
};
|
||||
|
||||
struct Elf32_Syminfo {
|
||||
u16 si_boundto;
|
||||
SYMINFO_FLG si_flags;
|
||||
};
|
||||
|
||||
s64 stringTableIndex;
|
||||
|
||||
struct String {
|
||||
char value[];
|
||||
} [[sealed, format("format_string")]];
|
||||
|
||||
fn format_string(String string) {
|
||||
return string.value;
|
||||
};
|
||||
|
||||
struct Elf32_Shdr {
|
||||
u32 sh_name;
|
||||
SHT sh_type;
|
||||
SHF sh_flags;
|
||||
u32 sh_addr;
|
||||
u32 sh_offset;
|
||||
Elf32_Word sh_size;
|
||||
Elf32_Word sh_link;
|
||||
Elf32_Word sh_info;
|
||||
Elf32_Word sh_addralign;
|
||||
Elf32_Word sh_entsize;
|
||||
|
||||
if (sh_size > 0 && sh_offset + sh_size < std::mem::size()) {
|
||||
if (sh_type == SHT::NOBITS || sh_type == SHT::NULL) {
|
||||
// Section has no data
|
||||
} else if (sh_type == SHT::STRTAB) {
|
||||
String stringTable[while($ < (sh_offset + sh_size))] @ sh_offset;
|
||||
stringTableIndex = std::core::array_index();
|
||||
} else if (sh_type == SHT::DYNSYM) {
|
||||
Elf32_Sym symbolTable[sh_size / sh_entsize] @ sh_offset;
|
||||
} else if (sh_type == SHT::INIT_ARRAY || sh_type == SHT::FINI_ARRAY) {
|
||||
u32 pointer[while($ < (sh_offset + sh_size))] @ sh_offset;
|
||||
} else {
|
||||
u8 data[sh_size] @ sh_offset;
|
||||
}
|
||||
}
|
||||
} [[format("format_section_header")]];;
|
||||
|
||||
struct Elf64_Chdr {
|
||||
u32 ch_type;
|
||||
Elf64_Word ch_size;
|
||||
Elf64_Word ch_addralign;
|
||||
};
|
||||
|
||||
struct Elf64_Rel {
|
||||
Elf64_Off r_offset;
|
||||
ELF64_R_INFO r_info;
|
||||
};
|
||||
|
||||
struct Elf64_Rela {
|
||||
Elf64_Off r_offset;
|
||||
ELF64_R_INFO r_info;
|
||||
Elf64_Sxword r_addend;
|
||||
};
|
||||
|
||||
struct Elf64_Sym {
|
||||
u32 st_name;
|
||||
ST st_info;
|
||||
STV st_other;
|
||||
u16 st_shndx;
|
||||
Elf64_VAddr st_value;
|
||||
Elf64_Xword st_size;
|
||||
};
|
||||
|
||||
struct Elf64_Syminfo {
|
||||
u16 si_boundto;
|
||||
SYMINFO_FLG si_flags;
|
||||
};
|
||||
|
||||
struct Elf64_Shdr {
|
||||
u32 sh_name;
|
||||
SHT sh_type;
|
||||
SHF sh_flags;
|
||||
padding[4];
|
||||
u64 sh_addr;
|
||||
u64 sh_offset;
|
||||
Elf64_Xword sh_size;
|
||||
Elf64_Word sh_link;
|
||||
Elf64_Word sh_info;
|
||||
Elf64_Xword sh_addralign;
|
||||
Elf64_Xword sh_entsize;
|
||||
|
||||
u32 flags;
|
||||
|
||||
u16 elf_header_size;
|
||||
u16 program_header_entry_size;
|
||||
u16 program_header_entry_count;
|
||||
u16 section_header_entry_size;
|
||||
u16 section_header_entry_count;
|
||||
u16 section_name_entry_id;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace program {
|
||||
|
||||
enum Type : u32 {
|
||||
NULL = 0x00,
|
||||
LOAD = 0x01,
|
||||
DYNAMIC = 0x02,
|
||||
INTERP = 0x03,
|
||||
NOTE = 0x04,
|
||||
SHLIB = 0x05,
|
||||
PHDR = 0x06,
|
||||
TLS = 0x07,
|
||||
LOOS = 0x60000000,
|
||||
HIOS = 0x6FFFFFFF,
|
||||
LOPROC = 0x70000000,
|
||||
HIPROC = 0x7FFFFFFF
|
||||
};
|
||||
|
||||
struct Header {
|
||||
Type type;
|
||||
|
||||
if (parent.header.identity.class == elf::Class::_32Bit) {
|
||||
u32 offset;
|
||||
u32 virtual_address;
|
||||
u32 physical_address;
|
||||
u32 file_size;
|
||||
u32 memory_size;
|
||||
u32 flags;
|
||||
u32 alignment;
|
||||
} else {
|
||||
u32 flags;
|
||||
u64 offset;
|
||||
u64 virtual_address;
|
||||
u64 physical_address;
|
||||
u64 file_size;
|
||||
u64 memory_size;
|
||||
u64 alignment;
|
||||
if (sh_size > 0 && sh_offset + sh_size < std::mem::size()) {
|
||||
if (sh_type == SHT::NOBITS || sh_type == SHT::NULL) {
|
||||
// Section has no data
|
||||
} else if (sh_type == SHT::STRTAB) {
|
||||
String stringTable[while($ < (sh_offset + sh_size))] @ sh_offset;
|
||||
stringTableIndex = std::core::array_index();
|
||||
} else if (sh_type == SHT::DYNSYM) {
|
||||
Elf64_Sym symbolTable[sh_size / sh_entsize] @ sh_offset;
|
||||
} else if (sh_type == SHT::INIT_ARRAY || sh_type == SHT::FINI_ARRAY) {
|
||||
u32 pointer[while($ < (sh_offset + sh_size))] @ sh_offset;
|
||||
} else {
|
||||
u8 data[sh_size] @ sh_offset;
|
||||
}
|
||||
}
|
||||
};
|
||||
} [[format("format_section_header")]];
|
||||
|
||||
}
|
||||
fn format_section_header(auto shdr) {
|
||||
u32 i = 0;
|
||||
|
||||
u32 nameAddress = addressof(elf.shdr[stringTableIndex].stringTable) + shdr.sh_name;
|
||||
while (i < std::core::member_count(elf.shdr[stringTableIndex].stringTable)) {
|
||||
if (nameAddress >= addressof(elf.shdr[stringTableIndex].stringTable[i]) && nameAddress < (addressof(elf.shdr[stringTableIndex].stringTable[i]) + sizeof(elf.shdr[stringTableIndex].stringTable[i])))
|
||||
break;
|
||||
|
||||
i += 1;
|
||||
}
|
||||
|
||||
namespace section {
|
||||
|
||||
struct String {
|
||||
char characters[];
|
||||
};
|
||||
|
||||
enum Type : u32 {
|
||||
NULL = 0x00,
|
||||
PROGBITS = 0x01,
|
||||
SYMTAB = 0x02,
|
||||
STRTAB = 0x03,
|
||||
RELA = 0x04,
|
||||
HASH = 0x05,
|
||||
DYNAMIC = 0x06,
|
||||
NOTE = 0x07,
|
||||
NOBITS = 0x08,
|
||||
REL = 0x09,
|
||||
SHLIB = 0x0A,
|
||||
DYNSYM = 0x0B,
|
||||
INIT_ARRAY = 0x0E,
|
||||
FINI_ARRAY = 0x0F,
|
||||
PREINIT_ARRAY = 0x10,
|
||||
GROUP = 0x11,
|
||||
SYMTAB_SHNDX = 0x12,
|
||||
NUM = 0x13,
|
||||
LOOS = 0x60000000
|
||||
};
|
||||
|
||||
bitfield Flags {
|
||||
WRITE : 1;
|
||||
ALLOC : 1;
|
||||
EXECINSTR : 1;
|
||||
pad1 : 1;
|
||||
MERGE : 1;
|
||||
STRINGS : 1;
|
||||
INFO_LINK : 1;
|
||||
LINK_ORDER : 1;
|
||||
OS_NONCONFORMING : 1;
|
||||
GROUP : 1;
|
||||
TLS : 1;
|
||||
};
|
||||
|
||||
struct Header {
|
||||
u32 name_offset;
|
||||
section::Type type;
|
||||
Flags flags;
|
||||
padding[2];
|
||||
|
||||
if (parent.header.identity.class == elf::Class::_32Bit) {
|
||||
u32 address;
|
||||
u32 offset;
|
||||
u32 size;
|
||||
u32 link;
|
||||
u32 info;
|
||||
u32 address_alignment;
|
||||
u32 entry_size;
|
||||
} else {
|
||||
padding[4];
|
||||
u64 address;
|
||||
u64 offset;
|
||||
u64 size;
|
||||
u32 link;
|
||||
u32 info;
|
||||
u64 address_alignment;
|
||||
u64 entry_size;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
return elf.shdr[stringTableIndex].stringTable[i].value;
|
||||
};
|
||||
|
||||
|
||||
elf::Header header @ 0x00;
|
||||
program::Header program_headers[header.program_header_entry_count] @ header.program_header_offset;
|
||||
section::Header section_headers[header.section_header_entry_count] @ header.section_header_offset;
|
||||
struct ELF {
|
||||
E_IDENT e_ident;
|
||||
|
||||
if (e_ident.EI_DATA == EI_DATA::ELFDATA2LSB)
|
||||
std::core::set_endian(std::mem::Endian::Little);
|
||||
else
|
||||
std::core::set_endian(std::mem::Endian::Big);
|
||||
|
||||
if (e_ident.EI_CLASS == EI_CLASS::ELFCLASS32) {
|
||||
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;
|
||||
Elf64_Shdr shdr[ehdr.e_shnum] @ ehdr.e_shoff;
|
||||
}
|
||||
};
|
||||
|
||||
ELF elf @ 0x00;
|
||||
|
||||
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;
|
||||
321
patterns/flac.hexpat
Normal file
321
patterns/flac.hexpat
Normal file
@@ -0,0 +1,321 @@
|
||||
#include <std/sys.pat>
|
||||
#include <std/core.pat>
|
||||
#include <std/io.pat>
|
||||
|
||||
#pragma endian big
|
||||
|
||||
u32 sampleSize;
|
||||
u32 bitsPerSample;
|
||||
|
||||
// METADATA
|
||||
|
||||
enum BLOCK_TYPE : u8 {
|
||||
STREAMINFO = 0,
|
||||
PADDING = 1,
|
||||
APPLICATION = 2,
|
||||
SEEKTABLE = 3,
|
||||
VORBIS_COMMENT = 4,
|
||||
CUESHEET = 5,
|
||||
PICTURE = 6,
|
||||
|
||||
INVALID = 127
|
||||
};
|
||||
|
||||
bitfield METADATA_BLOCK_HEADER {
|
||||
lastMetadataBlock : 1;
|
||||
blockType : 7;
|
||||
length : 24;
|
||||
} [[left_to_right]];
|
||||
|
||||
bitfield STREAMINFO_FLAGS {
|
||||
sampleRate : 20;
|
||||
numChannels : 3 [[format("format_channels")]];
|
||||
bitsPerSample : 5;
|
||||
numSamplesInStream : 36;
|
||||
} [[inline, left_to_right]];
|
||||
|
||||
fn format_channels(u8 value) {
|
||||
return value + 1;
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_STREAMINFO {
|
||||
u16 minBlockSize, maxBlockSize;
|
||||
u24 minFrameSize, maxFrameSize;
|
||||
STREAMINFO_FLAGS flags;
|
||||
u128 md5Signature;
|
||||
|
||||
bitsPerSample = flags.bitsPerSample;
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_PADDING {
|
||||
padding[parent.header.length];
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_APPLICATION {
|
||||
char applicationID[4];
|
||||
u8 applicationData[parent.header.length - sizeof(applicationID)];
|
||||
};
|
||||
|
||||
struct SEEKPOINT {
|
||||
u64 sampleNumber;
|
||||
u64 byteOffset;
|
||||
u16 numSamples;
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_SEEKTABLE {
|
||||
SEEKPOINT seekPoints[parent.header.length / 18];
|
||||
};
|
||||
|
||||
struct VORBIS_USER_COMMENT {
|
||||
le u32 length;
|
||||
char comment[length];
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_VORBIS_COMMENT {
|
||||
le u32 vendorLength;
|
||||
u8 vendor[vendorLength];
|
||||
|
||||
le u32 userCommentListLength;
|
||||
VORBIS_USER_COMMENT userCommentList[userCommentListLength];
|
||||
};
|
||||
|
||||
bitfield TRACK_FLAGS {
|
||||
audioTrack : 1;
|
||||
preEmphasis : 1;
|
||||
padding : 6;
|
||||
} [[inline]];
|
||||
|
||||
struct CUESHEET_TRACK_INDEX {
|
||||
u64 sampleOffset;
|
||||
u8 indexPointNumber;
|
||||
padding[3];
|
||||
};
|
||||
|
||||
struct CUESHEET_TRACK {
|
||||
u64 trackOffset;
|
||||
u8 trackNumber;
|
||||
char trackISRC[12];
|
||||
TRACK_FLAGS flags;
|
||||
padding[13];
|
||||
u8 numTrackIndexPoints;
|
||||
CUESHEET_TRACK_INDEX indexes[numTrackIndexPoints];
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_CUESHEET {
|
||||
char mediaCatalogNumber[128];
|
||||
u64 numLeadInSamples;
|
||||
bool isCD;
|
||||
padding[258];
|
||||
u8 numTracks;
|
||||
CUESHEET_TRACK tracks[numTracks];
|
||||
};
|
||||
|
||||
enum PICTURE_TYPE : u32 {
|
||||
Other = 0,
|
||||
FileIcon = 1,
|
||||
OtherFileIcon = 2,
|
||||
CoverFront = 3,
|
||||
CoverBack = 4,
|
||||
LeafletPage = 5,
|
||||
Media = 6,
|
||||
LeadArtist = 7,
|
||||
Artist = 8,
|
||||
Conductor = 9,
|
||||
Band = 10,
|
||||
Composer = 11,
|
||||
Lyricist = 12,
|
||||
RecordingLocation = 13,
|
||||
DuringRecording = 14,
|
||||
DuringPerformance = 15,
|
||||
MovieScreenCapture = 16,
|
||||
ABrightColoredFish = 17,
|
||||
Illustration = 18,
|
||||
BandLogoType = 19,
|
||||
PublisherLogoType = 20
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_PICTURE {
|
||||
PICTURE_TYPE pictureType;
|
||||
u32 mimeTypeLength;
|
||||
char mimeType[mineTypeLength];
|
||||
u32 descriptionLength;
|
||||
char description[descriptionLength];
|
||||
u32 width, height;
|
||||
u32 colorDepth;
|
||||
u32 colorCount;
|
||||
u32 pictureDataLength;
|
||||
u8 pictureData[pictureDataLength];
|
||||
};
|
||||
|
||||
|
||||
|
||||
// FRAME DATA
|
||||
// TODO: THIS IS INCOMPLETE / NOT WORKING CURRENTLY
|
||||
|
||||
bitfield FRAME_HEADER_FLAGS {
|
||||
syncCode : 14;
|
||||
padding : 1;
|
||||
blockingStrategy : 1;
|
||||
blockSize : 4;
|
||||
sampleRate : 4;
|
||||
channelAssignment : 4;
|
||||
sampleSize : 3;
|
||||
padding : 1;
|
||||
} [[inline]];
|
||||
|
||||
struct FRAME_HEADER {
|
||||
FRAME_HEADER_FLAGS flags;
|
||||
|
||||
sampleSize = flags.sampleSize;
|
||||
|
||||
if (flags.blockingStrategy)
|
||||
char16 sampleNumber[7];
|
||||
else
|
||||
char16 frameNumber[6];
|
||||
|
||||
if (flags.blockSize == 0b0110)
|
||||
u8 blockSize;
|
||||
else if (flags.blockSize == 0b0111)
|
||||
u16 blockSize;
|
||||
|
||||
if (flags.sampleRate == 0b1100)
|
||||
u8 sampleRate;
|
||||
else if (flags.sampleRate == 0b1101 || flags.sampleRate == 0b1110)
|
||||
u16 sampleRate;
|
||||
|
||||
u8 crc8;
|
||||
};
|
||||
|
||||
struct FRAME_FOOTER {
|
||||
u16 crc16;
|
||||
};
|
||||
|
||||
bitfield SUBFRAME_HEADER {
|
||||
padding : 1;
|
||||
type : 6;
|
||||
wastedBits : 1;
|
||||
};
|
||||
|
||||
fn getBitsPerSample() {
|
||||
if (sampleSize == 0b000)
|
||||
return bitsPerSample;
|
||||
else if (sampleSize == 0b001)
|
||||
return 8;
|
||||
else if (sampleSize == 0b010)
|
||||
return 12;
|
||||
else if (sampleSize == 0b100)
|
||||
return 16;
|
||||
else if (sampleSize == 0b101)
|
||||
return 20;
|
||||
else if (sampleSize == 0b110)
|
||||
return 24;
|
||||
};
|
||||
|
||||
bitfield SUBFRAME_CONSTANT {
|
||||
value : getBitsPerSample();
|
||||
};
|
||||
|
||||
bitfield SUBFRAME_VERBATIM {
|
||||
value : getBitsPerSample() * parent.parent.header.flags.blockSize;
|
||||
};
|
||||
|
||||
bitfield SUBFRAME_FIXED_VALUE {
|
||||
value : getBitsPerSample() * (parent.parent.header.type & 0b111);
|
||||
codingMethod : 2;
|
||||
} [[inline]];
|
||||
|
||||
bitfield RESIDUAL_CODING_METHOD_PARTITIONED_RICE {
|
||||
partitionOrder : 4;
|
||||
riceParameter : 4;
|
||||
if (riceParameter == 0b1111)
|
||||
bitsPerSample : 5;
|
||||
} [[right_to_left]];
|
||||
|
||||
bitfield RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 {
|
||||
partitionOrder : 4;
|
||||
riceParameter : 5;
|
||||
if (riceParameter == 0b11111)
|
||||
bitsPerSample : 5;
|
||||
} [[right_to_left]];
|
||||
|
||||
struct RESIDUAL {
|
||||
if (parent.value.codingMethod == 0b00)
|
||||
RESIDUAL_CODING_METHOD_PARTITIONED_RICE rice;
|
||||
else if (parent.value.codingMethod == 0b01)
|
||||
RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 rice;
|
||||
|
||||
|
||||
if ((parent.parent.header.type & 0b111) == 0b000)
|
||||
u8 samples[(getBitsPerSample() * (parent.parent.parent.header.flags.blockSize - (parent.parent.header.type & 0b111))) / 8];
|
||||
else if (std::core::array_index() != 0)
|
||||
u8 samples[(getBitsPerSample() * (parent.parent.parent.header.flags.blockSize / (1 << rice.partitionOrder))) / 8];
|
||||
else
|
||||
u8 samples[(getBitsPerSample() * ((parent.parent.parent.header.flags.blockSize / (1 << rice.partitionOrder)) - (parent.parent.header.type & 0b111))) / 8];
|
||||
};
|
||||
|
||||
struct SUBFRAME_FIXED {
|
||||
SUBFRAME_FIXED_VALUE value;
|
||||
RESIDUAL residual;
|
||||
};
|
||||
|
||||
bitfield SUBFRAME_LPC_VALUE {
|
||||
warmUpSamples : getBitsPerSample() * ((parent.header.type & 0b011111) + 1);
|
||||
quantizedLinearPredictorCoefficient : 4;
|
||||
quantizedLinearPredictorCoefficientShift : 5;
|
||||
predictorCoefficients : quantizedLinearPredictorCoefficient * ((parent.header.type & 0b011111) + 1);
|
||||
} [[inline]];
|
||||
|
||||
struct SUBFRAME_LPC {
|
||||
SUBFRAME_LPC_VALUE value;
|
||||
RESIDUAL residual;
|
||||
};
|
||||
|
||||
|
||||
struct SUBFRAME {
|
||||
SUBFRAME_HEADER header;
|
||||
|
||||
if (header.type == 0b00000)
|
||||
SUBFRAME_CONSTANT constant;
|
||||
else if (header.type == 0b000001)
|
||||
SUBFRAME_VERBATIM verbatim;
|
||||
else if ((header.type >> 3) == 0b001 && (header.type & 0b111) <= 4)
|
||||
SUBFRAME_FIXED fixed;
|
||||
else if (header.type == 0b100000)
|
||||
SUBFRAME_LPC lpc;
|
||||
};
|
||||
|
||||
struct FRAME {
|
||||
FRAME_HEADER header;
|
||||
SUBFRAME subframes[parent.metadata[0].data.flags.numChannels + 1];
|
||||
FRAME_FOOTER footer;
|
||||
};
|
||||
|
||||
|
||||
struct METADATA_BLOCK {
|
||||
METADATA_BLOCK_HEADER header;
|
||||
if (header.lastMetadataBlock)
|
||||
break;
|
||||
|
||||
if (header.blockType == BLOCK_TYPE::STREAMINFO)
|
||||
METADATA_BLOCK_STREAMINFO data;
|
||||
else if (header.blockType == BLOCK_TYPE::PADDING)
|
||||
METADATA_BLOCK_PADDING data;
|
||||
else if (header.blockType == BLOCK_TYPE::APPLICATION)
|
||||
METADATA_BLOCK_APPLICATION data;
|
||||
else if (header.blockType == BLOCK_TYPE::VORBIS_COMMENT)
|
||||
METADATA_BLOCK_VORBIS_COMMENT data;
|
||||
else if (header.blockType == BLOCK_TYPE::CUESHEET)
|
||||
METADATA_BLOCK_CUESHEET data;
|
||||
else if (header.blockType == BLOCK_TYPE::PICTURE)
|
||||
METADATA_BLOCK_PICTURE data;
|
||||
else
|
||||
std::error("Invalid metadata block type!");
|
||||
};
|
||||
|
||||
struct STREAM {
|
||||
char magic[4];
|
||||
METADATA_BLOCK metadata[while(true)];
|
||||
//FRAME frames[while(!std::mem::eof())];
|
||||
};
|
||||
|
||||
STREAM stream @ 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:");
|
||||
|
||||
459
patterns/lnk.hexpat
Normal file
459
patterns/lnk.hexpat
Normal file
@@ -0,0 +1,459 @@
|
||||
#pragma MIME application/x-ms-shortcut
|
||||
|
||||
#include <type/guid.pat>
|
||||
#include <type/size.pat>
|
||||
|
||||
bitfield LinkFlags {
|
||||
HasLinkTargetIDList : 1;
|
||||
HasLinkInfo : 1;
|
||||
HasName : 1;
|
||||
HasRelativePath : 1;
|
||||
HasWorkingDir : 1;
|
||||
HasArguments : 1;
|
||||
HasIconLocation : 1;
|
||||
IsUnicode : 1;
|
||||
ForceNoLinkInfo : 1;
|
||||
HasExpString : 1;
|
||||
RunInSeparateProcess : 1;
|
||||
padding : 1;
|
||||
HasDarwinID : 1;
|
||||
RunAsUser : 1;
|
||||
HasExpIcon : 1;
|
||||
NoPidlAlias : 1;
|
||||
padding : 1;
|
||||
RunWithShimLayer : 1;
|
||||
ForceNoLinkTrack : 1;
|
||||
EnableTargetMetadata : 1;
|
||||
DisableLinkPathTracking : 1;
|
||||
DisableKnownFolderTracking : 1;
|
||||
DisableKnownFolderAlias : 1;
|
||||
AllowLinkToLink : 1;
|
||||
UnaliasOnSave : 1;
|
||||
PreferEnvironmentPath : 1;
|
||||
KeepLocalIDListForUNCTarget : 1;
|
||||
padding : 5;
|
||||
} [[right_to_left]];
|
||||
|
||||
bitfield FileAttributesFlags {
|
||||
FILE_ATTRIBUTE_READONLY : 1;
|
||||
FILE_ATTRIBUTE_HIDDEN : 1;
|
||||
FILE_ATTRIBUTE_SYSTEM : 1;
|
||||
padding : 1;
|
||||
FILE_ATTRIBUTE_DIRECTORY : 1;
|
||||
FILE_ATTRIBUTE_ARCHIVE : 1;
|
||||
padding : 1;
|
||||
FILE_ATTRIBUTE_NORMAL : 1;
|
||||
FILE_ATTRIBUTE_TEMPORARY : 1;
|
||||
FILE_ATTRIBUTE_SPARSE_FILE : 1;
|
||||
FILE_ATTRIBUTE_REPARSE_POINT : 1;
|
||||
FILE_ATTRIBUTE_COMPRESSED : 1;
|
||||
FILE_ATTRIBUTE_OFFLINE : 1;
|
||||
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED : 1;
|
||||
FILE_ATTRIBUTE_ENCRYPTED : 1;
|
||||
padding : 17;
|
||||
} [[right_to_left]];
|
||||
|
||||
bitfield ModifierKeys {
|
||||
HOTKEYF_SHIFT : 1;
|
||||
HOTKEYF_CONTROL : 1;
|
||||
HOTKEYF_ALT : 1;
|
||||
padding : 5;
|
||||
} [[right_to_left]];
|
||||
|
||||
enum Keys : u8 {
|
||||
KEY_NONE = 0x00,
|
||||
KEY_0 = 0x30,
|
||||
KEY_1 = 0x31,
|
||||
KEY_2 = 0x32,
|
||||
KEY_3 = 0x33,
|
||||
KEY_4 = 0x34,
|
||||
KEY_5 = 0x35,
|
||||
KEY_6 = 0x36,
|
||||
KEY_7 = 0x37,
|
||||
KEY_8 = 0x38,
|
||||
KEY_9 = 0x39,
|
||||
KEY_A = 0x41,
|
||||
KEY_B = 0x42,
|
||||
KEY_C = 0x43,
|
||||
KEY_D = 0x44,
|
||||
KEY_E = 0x45,
|
||||
KEY_F = 0x46,
|
||||
KEY_G = 0x47,
|
||||
KEY_H = 0x48,
|
||||
KEY_I = 0x49,
|
||||
KEY_J = 0x4A,
|
||||
KEY_K = 0x4B,
|
||||
KEY_L = 0x4C,
|
||||
KEY_M = 0x4D,
|
||||
KEY_N = 0x4E,
|
||||
KEY_O = 0x4F,
|
||||
KEY_P = 0x50,
|
||||
KEY_Q = 0x51,
|
||||
KEY_R = 0x52,
|
||||
KEY_S = 0x53,
|
||||
KEY_T = 0x54,
|
||||
KEY_U = 0x55,
|
||||
KEY_V = 0x56,
|
||||
KEY_W = 0x57,
|
||||
KEY_X = 0x58,
|
||||
KEY_Y = 0x59,
|
||||
KEY_Z = 0x5A,
|
||||
|
||||
VK_F1 = 0x70,
|
||||
VK_F2 = 0x71,
|
||||
VK_F3 = 0x72,
|
||||
VK_F4 = 0x73,
|
||||
VK_F5 = 0x74,
|
||||
VK_F6 = 0x75,
|
||||
VK_F7 = 0x76,
|
||||
VK_F8 = 0x77,
|
||||
VK_F9 = 0x78,
|
||||
VK_F10 = 0x79,
|
||||
VK_F11 = 0x7A,
|
||||
VK_F12 = 0x7B,
|
||||
VK_F13 = 0x7C,
|
||||
VK_F14 = 0x7D,
|
||||
VK_F15 = 0x7E,
|
||||
VK_F16 = 0x7F,
|
||||
VK_F17 = 0x80,
|
||||
VK_F18 = 0x81,
|
||||
VK_F19 = 0x82,
|
||||
VK_F20 = 0x83,
|
||||
VK_F21 = 0x84,
|
||||
VK_F22 = 0x85,
|
||||
VK_F23 = 0x86,
|
||||
VK_F24 = 0x87,
|
||||
VK_NUMLOCK = 0x90,
|
||||
VK_SCROLL = 0x91,
|
||||
};
|
||||
|
||||
struct HotKeyFlags {
|
||||
Keys Key;
|
||||
ModifierKeys ModifierKeys;
|
||||
};
|
||||
|
||||
struct FILETIME {
|
||||
u32 dwLowDateTime;
|
||||
u32 dwHighDateTime;
|
||||
};
|
||||
|
||||
enum SHOWWINDOW_FLAGS : u32 {
|
||||
SW_SHOWNORMAL = 0x00000001,
|
||||
SW_SHOWMAXIMIZED = 0x00000003,
|
||||
SW_SHOWMINNOACTIVE = 0x00000007
|
||||
};
|
||||
|
||||
struct ShellLinkHeader {
|
||||
type::Size32 HeaderSize;
|
||||
type::GUID LinkCLSID;
|
||||
LinkFlags LinkFlags;
|
||||
FileAttributesFlags FileAttributes;
|
||||
FILETIME CreationTime, AccessTime, WriteTime;
|
||||
type::Size32 FileSize;
|
||||
u32 IconIndex;
|
||||
SHOWWINDOW_FLAGS ShowCommand;
|
||||
HotKeyFlags HotKey;
|
||||
padding[2];
|
||||
padding[4];
|
||||
padding[4];
|
||||
};
|
||||
|
||||
struct ItemID {
|
||||
type::Size16 ItemIDSize;
|
||||
|
||||
if (ItemIDSize == 0x00)
|
||||
break;
|
||||
else
|
||||
u8 Data[ItemIDSize - sizeof(ItemIDSize)];
|
||||
};
|
||||
|
||||
struct IDList {
|
||||
ItemID ItemIDList[while(true)];
|
||||
};
|
||||
|
||||
struct LinkTargetIDList {
|
||||
type::Size16 IDListSize;
|
||||
IDList IDList[while($ < (addressof(IDListSize) + IDListSize))];
|
||||
};
|
||||
|
||||
bitfield LinkInfoFlags {
|
||||
VolumeIDAndLocalBasePath : 1;
|
||||
CommonNetworkRelativeLinkAndPathSuffix : 1;
|
||||
padding : 30;
|
||||
};
|
||||
|
||||
enum DriveType : u32 {
|
||||
DRIVE_UNKNOWN = 0x00000000,
|
||||
DRIVE_NO_ROOT_DIR = 0x00000001,
|
||||
DRIVE_REMOVABLE = 0x00000002,
|
||||
DRIVE_FIXED = 0x00000003,
|
||||
DRIVE_REMOTE = 0x00000004,
|
||||
DRIVE_CDROM = 0x00000005,
|
||||
DRIVE_RAMDISK = 0x00000006
|
||||
};
|
||||
|
||||
struct VolumeID {
|
||||
type::Size32 VolumeIDSize;
|
||||
DriveType DriveType;
|
||||
u32 DriveSerialNumber;
|
||||
u32 VolumeLabelOffset;
|
||||
if (VolumeLabelOffset == 0x14)
|
||||
u32 VolumeLabelOffsetUnicode;
|
||||
char Data[VolumeIDSize - ($ - addressof(this))];
|
||||
};
|
||||
|
||||
bitfield CommonNetworkRelativeLinkFlags {
|
||||
ValidDevice : 1;
|
||||
ValidNetType : 1;
|
||||
padding : 30;
|
||||
} [[right_to_left]];
|
||||
|
||||
enum NetworkProviderType : u32 {
|
||||
WNNC_NET_AVID = 0x001A0000,
|
||||
WNNC_NET_DOCUSPACE = 0x001B0000,
|
||||
WNNC_NET_MANGOSOFT = 0x001C0000,
|
||||
WNNC_NET_SERNET = 0x001D0000,
|
||||
WNNC_NET_RIVERFRONT1 = 0x001E0000,
|
||||
WNNC_NET_RIVERFRONT2 = 0x001F0000,
|
||||
WNNC_NET_DECORB = 0x00200000,
|
||||
WNNC_NET_PROTSTOR = 0x00210000,
|
||||
WNNC_NET_FJ_REDIR = 0x00220000,
|
||||
WNNC_NET_DISTINCT = 0x00230000,
|
||||
WNNC_NET_TWINS = 0x00240000,
|
||||
WNNC_NET_RDR2SAMPLE = 0x00250000,
|
||||
WNNC_NET_CSC = 0x00260000,
|
||||
WNNC_NET_3IN1 = 0x00270000,
|
||||
WNNC_NET_EXTENDNET = 0x00290000,
|
||||
WNNC_NET_STAC = 0x002A0000,
|
||||
WNNC_NET_FOXBAT = 0x002B0000,
|
||||
WNNC_NET_YAHOO = 0x002C0000,
|
||||
WNNC_NET_EXIFS = 0x002D0000,
|
||||
WNNC_NET_DAV = 0x002E0000,
|
||||
WNNC_NET_KNOWARE = 0x002F0000,
|
||||
WNNC_NET_OBJECT_DIRE = 0x00300000,
|
||||
WNNC_NET_MASFAX = 0x00310000,
|
||||
WNNC_NET_HOB_NFS = 0x00320000,
|
||||
WNNC_NET_SHIVA = 0x00330000,
|
||||
WNNC_NET_IBMAL = 0x00340000,
|
||||
WNNC_NET_LOCK = 0x00350000,
|
||||
WNNC_NET_TERMSRV = 0x00360000,
|
||||
WNNC_NET_SRT = 0x00370000,
|
||||
WNNC_NET_QUINCY = 0x00380000,
|
||||
WNNC_NET_OPENAFS = 0x00390000,
|
||||
WNNC_NET_AVID1 = 0x003A0000,
|
||||
WNNC_NET_DFS = 0x003B0000,
|
||||
WNNC_NET_KWNP = 0x003C0000,
|
||||
WNNC_NET_ZENWORKS = 0x003D0000,
|
||||
WNNC_NET_DRIVEONWEB = 0x003E0000,
|
||||
WNNC_NET_VMWARE = 0x003F0000,
|
||||
WNNC_NET_RSFX = 0x00400000,
|
||||
WNNC_NET_MFILES = 0x00410000,
|
||||
WNNC_NET_MS_NFS = 0x00420000,
|
||||
WNNC_NET_GOOGLE = 0x00430000
|
||||
};
|
||||
|
||||
struct CommonNetworkRelativeLink {
|
||||
type::Size32 CommonNetworkRelativeLinkSize;
|
||||
CommonNetworkRelativeLinkFlags CommonNetworkRelativeLinkFlags;
|
||||
u32 NetNameOffset;
|
||||
u32 DeviceNameOffset;
|
||||
NetworkProviderType NetworkProviderType;
|
||||
|
||||
if (NetNameOffset > 0x14) {
|
||||
u32 NetNameOffsetUnicode;
|
||||
u32 DeviceNameOffsetUnicode;
|
||||
}
|
||||
|
||||
char NetName[];
|
||||
char DeviceName[];
|
||||
|
||||
if (NetNameOffset > 0x14) {
|
||||
char16 NetNameUnicode[];
|
||||
char16 DeviceNameUnicode[];
|
||||
}
|
||||
};
|
||||
|
||||
struct LinkInfo {
|
||||
type::Size32 LinkInfoSize;
|
||||
type::Size32 LinkInfoHeaderSize;
|
||||
LinkInfoFlags LinkInfoFlags;
|
||||
u32 VolumeIDOffset;
|
||||
u32 LocalBasePathOffset;
|
||||
u32 CommonNetworkRelativeLinkOffset;
|
||||
u32 CommonPathSuffixOffset;
|
||||
|
||||
if (LinkInfoHeaderSize >= 0x24) {
|
||||
u32 LocalBasePathOffsetUnicode;
|
||||
u32 CommonPathSuffixOffsetUnicode;
|
||||
}
|
||||
|
||||
if (LinkInfoFlags.VolumeIDAndLocalBasePath) {
|
||||
VolumeID VolumeID;
|
||||
char LocalBasePath[];
|
||||
}
|
||||
|
||||
if (LinkInfoFlags.CommonNetworkRelativeLinkAndPathSuffix)
|
||||
CommonNetworkRelativeLink CommonNetworkRelativeLink;
|
||||
|
||||
char CommonPathSuffix[];
|
||||
|
||||
if (LinkInfoHeaderSize >= 0x24) {
|
||||
if (LinkInfoFlags.VolumeIDAndLocalBasePath)
|
||||
char16 LocalBasePathUnicode[];
|
||||
char16 CommonPathSuffixUnicode[];
|
||||
}
|
||||
};
|
||||
|
||||
struct String {
|
||||
u16 CountCharacters;
|
||||
char16 String[CountCharacters];
|
||||
};
|
||||
|
||||
struct StringData {
|
||||
if (parent.ShellLinkHeader.LinkFlags.HasName)
|
||||
String NAME_STRING;
|
||||
if (parent.ShellLinkHeader.LinkFlags.HasRelativePath)
|
||||
String RELATIVE_PATH;
|
||||
if (parent.ShellLinkHeader.LinkFlags.HasWorkingDir)
|
||||
String WORKING_DIR;
|
||||
if (parent.ShellLinkHeader.LinkFlags.HasArguments)
|
||||
String COMMAND_LINE_ARGUMENTS;
|
||||
if (parent.ShellLinkHeader.LinkFlags.HasIconLocation)
|
||||
String ICON_LOCATION;
|
||||
};
|
||||
|
||||
bitfield FillAttributes {
|
||||
FOREGROUND_BLUE : 1;
|
||||
FOREGROUND_GREEN : 1;
|
||||
FOREGROUND_RED : 1;
|
||||
FOREGROUND_INTENSITY : 1;
|
||||
|
||||
BACKGROUND_BLUE : 1;
|
||||
BACKGROUND_GREEN : 1;
|
||||
BACKGROUND_RED : 1;
|
||||
BACKGROUND_INTENSITY : 1;
|
||||
|
||||
padding : 8;
|
||||
} [[right_to_left]];
|
||||
|
||||
struct ConsoleDataBlock {
|
||||
FillAttributes FillAttributes;
|
||||
FillAttributes PopupFillAttributes;
|
||||
u16 ScreenBufferSizeX, ScreenBufferSizeY;
|
||||
u16 WindowSizeX, WindowSizeY;
|
||||
u16 WindowOriginX, WindowOriginY;
|
||||
padding[4];
|
||||
padding[4];
|
||||
u32 FontSize;
|
||||
u32 FontFamily;
|
||||
u32 FontWeight;
|
||||
char16 FaceName[32];
|
||||
u32 CursorSize;
|
||||
u32 FullScreen;
|
||||
u32 QuickEdit;
|
||||
u32 InsertMode;
|
||||
u32 AutoPosition;
|
||||
u32 HistoryBufferSize;
|
||||
u32 NumberOfHistoryBuffers;
|
||||
u32 HistoryNoDup;
|
||||
u32 ColorTable[16];
|
||||
};
|
||||
|
||||
struct ConsoleFEDataBlock {
|
||||
u32 CodePage;
|
||||
};
|
||||
|
||||
struct DarwinDataBlock {
|
||||
char DarwinDataAnsi[260];
|
||||
char16 DarwinDataUnicode[260];
|
||||
};
|
||||
|
||||
struct EnvironmentVariableDataBlock {
|
||||
char TargetAnsi[260];
|
||||
char16 TargetUnicode[260];
|
||||
};
|
||||
|
||||
struct IconEnvironmentDataBlock {
|
||||
char TargetAnsi[260];
|
||||
char16 TargetUnicode[260];
|
||||
};
|
||||
|
||||
struct KnownFolderDataBlock {
|
||||
type::GUID KnownFolderID;
|
||||
u32 Offset;
|
||||
};
|
||||
|
||||
struct PropertyStoreDataBlock {
|
||||
u8 Bytes[parent.BlockSize - sizeof(parent.BlockSize) - sizeof(parent.BlockSignature)];
|
||||
std::warning("PropertyStoreDataBlock is not yet implemented!");
|
||||
};
|
||||
|
||||
struct ShimDataBlock {
|
||||
char16 LayerName[(parent.BlockSize - sizeof(parent.BlockSize) - sizeof(parent.BlockSignature)) / sizeof(char16)];
|
||||
};
|
||||
|
||||
struct SpecialFolderDataBlock {
|
||||
u32 SpecialFolderID;
|
||||
u32 Offset;
|
||||
};
|
||||
|
||||
struct TrackerDataBlock {
|
||||
type::Size32 Length;
|
||||
u32 Version;
|
||||
char MachineID[16];
|
||||
type::GUID Droid[2];
|
||||
type::GUID DroidBirth[2];
|
||||
};
|
||||
|
||||
struct VistaAndAboveIDListDataBlock {
|
||||
IDList IDList;
|
||||
};
|
||||
|
||||
struct ExtraDataBlock {
|
||||
type::Size32 BlockSize;
|
||||
|
||||
if (BlockSize < 0x04)
|
||||
break;
|
||||
else {
|
||||
u32 BlockSignature;
|
||||
|
||||
if (BlockSignature == 0xA000'0002)
|
||||
ConsoleDataBlock CONSOLE_PROPS;
|
||||
else if (BlockSignature == 0xA000'0004)
|
||||
ConsoleFEDataBlock CONSOLE_FE_PROPS;
|
||||
else if (BlockSignature == 0xA000'0006)
|
||||
DarwinDataBlock DARWIN_PROPS;
|
||||
else if (BlockSignature == 0xA000'0001)
|
||||
EnvironmentVariableDataBlock ENVIRONMENT_PROPS;
|
||||
else if (BlockSignature == 0xA000'0007)
|
||||
IconEnvironmentDataBlock ICON_ENVIRONMENT_PROPS;
|
||||
else if (BlockSignature == 0xA000'000B)
|
||||
KnownFolderDataBlock KNOWN_FOLDER_PROPS;
|
||||
else if (BlockSignature == 0xA000'0009)
|
||||
PropertyStoreDataBlock PROPERTY_STORE_PROPS;
|
||||
else if (BlockSignature == 0xA000'0008)
|
||||
ShimDataBlock SHIM_PROPS;
|
||||
else if (BlockSignature == 0xA000'0005)
|
||||
SpecialFolderDataBlock SPECIAL_FOLDER_PROPS;
|
||||
else if (BlockSignature == 0xA000'0003)
|
||||
TrackerDataBlock TRACKER_PROPS;
|
||||
else if (BlockSignature == 0xA000'000C)
|
||||
VistaAndAboveIDListDataBlock VISTA_AND_ABOVE_IDLIST_PROPS;
|
||||
}
|
||||
};
|
||||
|
||||
struct ExtraData {
|
||||
ExtraDataBlock ExtraDataBlock[while(true)];
|
||||
};
|
||||
|
||||
struct LNK {
|
||||
ShellLinkHeader ShellLinkHeader;
|
||||
if (ShellLinkHeader.LinkFlags.HasLinkTargetIDList)
|
||||
LinkTargetIDList LinkTargetIDList;
|
||||
if (ShellLinkHeader.LinkFlags.HasLinkInfo)
|
||||
LinkInfo LinkInfo;
|
||||
StringData StringData;
|
||||
ExtraData ExtraData;
|
||||
};
|
||||
|
||||
LNK lnk @ 0x00;
|
||||
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;
|
||||
423
patterns/minidump.hexpat
Normal file
423
patterns/minidump.hexpat
Normal file
@@ -0,0 +1,423 @@
|
||||
#pragma MIME application/x-dmp
|
||||
|
||||
#include <type/time.pat>
|
||||
#include <type/types/win32.pat>
|
||||
#include <type/size.pat>
|
||||
|
||||
using RVA = ULONG32;
|
||||
using RVA64 = ULONG64;
|
||||
|
||||
enum MINIDUMP_STREAM_TYPE : ULONG32 {
|
||||
UnusedStream = 0,
|
||||
ReservedStream0 = 1,
|
||||
ReservedStream1 = 2,
|
||||
ThreadListStream = 3,
|
||||
ModuleListStream = 4,
|
||||
MemoryListStream = 5,
|
||||
ExceptionStream = 6,
|
||||
SystemInfoStream = 7,
|
||||
ThreadExListStream = 8,
|
||||
Memory64ListStream = 9,
|
||||
CommentStreamA = 10,
|
||||
CommentStreamW = 11,
|
||||
HandleDataStream = 12,
|
||||
FunctionTableStream = 13,
|
||||
UnloadedModuleListStream = 14,
|
||||
MiscInfoStream = 15,
|
||||
MemoryInfoListStream = 16,
|
||||
ThreadInfoListStream = 17,
|
||||
HandleOperationListStream = 18,
|
||||
TokenStream = 19,
|
||||
JavaScriptDataStream = 20,
|
||||
SystemMemoryInfoStream = 21,
|
||||
ProcessVmCountersStream = 22,
|
||||
IptTraceStream = 23,
|
||||
ThreadNamesStream = 24,
|
||||
ceStreamNull = 0x8000,
|
||||
ceStreamSystemInfo = 0x8001,
|
||||
ceStreamException = 0x8002,
|
||||
ceStreamModuleList = 0x8003,
|
||||
ceStreamProcessList = 0x8004,
|
||||
ceStreamThreadList = 0x8005,
|
||||
ceStreamThreadContextList = 0x8006,
|
||||
ceStreamThreadCallStackList = 0x8007,
|
||||
ceStreamMemoryVirtualList = 0x8008,
|
||||
ceStreamMemoryPhysicalList = 0x8009,
|
||||
ceStreamBucketParameters = 0x800A,
|
||||
ceStreamProcessModuleMap = 0x800B,
|
||||
ceStreamDiagnosisList = 0x800C,
|
||||
LastReservedStream = 0xFFFF
|
||||
};
|
||||
|
||||
struct MINIDUMP_LOCATION_DESCRIPTOR {
|
||||
type::Size32 DataSize;
|
||||
RVA Rva;
|
||||
};
|
||||
|
||||
struct MINIDUMP_MEMORY_DESCRIPTOR {
|
||||
ULONG64 StartOfMemoryRange;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR Memory;
|
||||
};
|
||||
|
||||
struct MINIDUMP_THREAD {
|
||||
ULONG32 ThreadId;
|
||||
ULONG32 SuspendCount;
|
||||
ULONG32 PriorityClass;
|
||||
ULONG32 Priority;
|
||||
ULONG64 Teb;
|
||||
MINIDUMP_MEMORY_DESCRIPTOR Stack;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
|
||||
};
|
||||
|
||||
struct MINIDUMP_THREAD_LIST {
|
||||
ULONG32 NumberOfThreads;
|
||||
MINIDUMP_THREAD Threads[NumberOfThreads];
|
||||
};
|
||||
|
||||
struct VS_FIXEDFILEINFO {
|
||||
DWORD dwSignature;
|
||||
DWORD dwStrucVersion;
|
||||
DWORD dwFileVersionMS;
|
||||
DWORD dwFileVersionLS;
|
||||
DWORD dwProductVersionMS;
|
||||
DWORD dwProductVersionLS;
|
||||
DWORD dwFileFlagsMask;
|
||||
DWORD dwFileFlags;
|
||||
DWORD dwFileOS;
|
||||
DWORD dwFileType;
|
||||
DWORD dwFileSubtype;
|
||||
DWORD dwFileDateMS;
|
||||
DWORD dwFileDateLS;
|
||||
};
|
||||
|
||||
struct MINIDUMP_MODULE {
|
||||
ULONG64 BaseOfImage;
|
||||
type::Size32 SizeOfImage;
|
||||
ULONG32 CheckSum;
|
||||
type::time32_t TimeDateStamp;
|
||||
RVA ModuleNameRva;
|
||||
VS_FIXEDFILEINFO VersionInfo;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR CvRecord;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR MiscRecord;
|
||||
ULONG64 Reserved0;
|
||||
ULONG64 Reserved1;
|
||||
|
||||
char16 ModuleName[] @ ModuleNameRva + 4 [[hidden]];
|
||||
} [[format("format_module")]];
|
||||
|
||||
fn format_module(ref MINIDUMP_MODULE module) {
|
||||
return module.ModuleName;
|
||||
};
|
||||
|
||||
struct MINIDUMP_MODULE_LIST {
|
||||
ULONG32 NumberOfModules;
|
||||
MINIDUMP_MODULE Modules[NumberOfModules];
|
||||
};
|
||||
|
||||
struct MINIDUMP_MEMORY_LIST {
|
||||
ULONG32 NumberOfMemoryRanges;
|
||||
MINIDUMP_MEMORY_DESCRIPTOR MemoryRanges[NumberOfMemoryRanges];
|
||||
};
|
||||
|
||||
struct MINIDUMP_EXCEPTION {
|
||||
ULONG32 ExceptionCode;
|
||||
ULONG32 ExceptionFlags;
|
||||
ULONG64 ExceptionRecord;
|
||||
ULONG64 ExceptionAddress;
|
||||
ULONG32 NumberParameters;
|
||||
padding[4];
|
||||
ULONG64 ExceptionInformation[15];
|
||||
};
|
||||
|
||||
struct MINIDUMP_EXCEPTION_STREAM {
|
||||
ULONG32 ThreadId;
|
||||
padding[4];
|
||||
MINIDUMP_EXCEPTION ExceptionRecord;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
|
||||
};
|
||||
|
||||
struct CPU_INFORMATION {
|
||||
ULONG32 VendorId[3];
|
||||
ULONG32 VersionInformation;
|
||||
ULONG32 FeatureInformation;
|
||||
ULONG32 AMDExtendedCpuFeatures;
|
||||
};
|
||||
|
||||
struct MINIDUMP_SYSTEM_INFO {
|
||||
USHORT ProcessorArchitecture;
|
||||
USHORT ProcessorLevel;
|
||||
USHORT ProcessorRevision;
|
||||
UCHAR NumberOfProcessors;
|
||||
UCHAR ProductType;
|
||||
ULONG32 MajorVersion;
|
||||
ULONG32 MinorVersion;
|
||||
ULONG32 BuildNumber;
|
||||
ULONG32 PlatformId;
|
||||
RVA CSDVersionRva;
|
||||
USHORT SuiteMask;
|
||||
USHORT Reserved;
|
||||
CPU_INFORMATION Cpu;
|
||||
};
|
||||
|
||||
struct MINIDUMP_THREAD_EX {
|
||||
ULONG32 ThreadId;
|
||||
ULONG32 SuspendCount;
|
||||
ULONG32 PriorityClass;
|
||||
ULONG32 Priority;
|
||||
ULONG64 Teb;
|
||||
MINIDUMP_MEMORY_DESCRIPTOR Stack;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
|
||||
MINIDUMP_MEMORY_DESCRIPTOR BackingStore;
|
||||
};
|
||||
|
||||
struct MINIDUMP_THREAD_EX_LIST {
|
||||
ULONG32 NumberOfThreads;
|
||||
MINIDUMP_THREAD_EX Threads[NumberOfThreads];
|
||||
};
|
||||
|
||||
struct MINIDUMP_MEMORY_DESCRIPTOR64 {
|
||||
ULONG64 StartOfMemoryRange;
|
||||
type::Size64 DataSize;
|
||||
};
|
||||
|
||||
struct MINIDUMP_MEMORY64_LIST {
|
||||
ULONG64 NumberOfMemoryRanges;
|
||||
RVA64 BaseRva;
|
||||
MINIDUMP_MEMORY_DESCRIPTOR64 MemoryRanges[NumberOfMemoryRanges];
|
||||
};
|
||||
|
||||
struct MINIDUMP_HANDLE_DESCRIPTOR {
|
||||
ULONG64 Handle;
|
||||
RVA TypeNameRva;
|
||||
RVA ObjectNameRva;
|
||||
ULONG32 Attributes;
|
||||
ULONG32 GrantedAccess;
|
||||
ULONG32 HandleCount;
|
||||
ULONG32 PointerCount;
|
||||
};
|
||||
|
||||
struct MINIDUMP_HANDLE_DESCRIPTOR_2 {
|
||||
ULONG64 Handle;
|
||||
RVA TypeNameRva;
|
||||
RVA ObjectNameRva;
|
||||
ULONG32 Attributes;
|
||||
ULONG32 GrantedAccess;
|
||||
ULONG32 HandleCount;
|
||||
ULONG32 PointerCount;
|
||||
RVA ObjectInfoRva;
|
||||
ULONG32 Reserved0;
|
||||
};
|
||||
|
||||
struct MINIDUMP_HANDLE_DATA_STREAM {
|
||||
ULONG32 SizeOfHeader;
|
||||
ULONG32 SizeOfDescriptor;
|
||||
ULONG32 NumberOfDescriptors;
|
||||
ULONG32 Reserved;
|
||||
|
||||
if (SizeOfDescriptor == 32)
|
||||
MINIDUMP_HANDLE_DESCRIPTOR HandleDescriptors[NumberOfDescriptors];
|
||||
else if (SizeOfDescriptor == 40)
|
||||
MINIDUMP_HANDLE_DESCRIPTOR_2 HandleDescriptors[NumberOfDescriptors];
|
||||
};
|
||||
|
||||
struct MINIDUMP_FUNCTION_TABLE_DESCRIPTOR {
|
||||
ULONG64 MinimumAddress;
|
||||
ULONG64 MaximumAddress;
|
||||
ULONG64 BaseAddress;
|
||||
ULONG32 EntryCount;
|
||||
type::Size32 SizeOfAlignPad;
|
||||
};
|
||||
|
||||
struct MINIDUMP_FUNCTION_TABLE_STREAM {
|
||||
type::Size32 SizeOfHeader;
|
||||
type::Size32 SizeOfDescriptor;
|
||||
type::Size32 SizeOfNativeDescriptor;
|
||||
type::Size32 SizeOfFunctionEntry;
|
||||
ULONG32 NumberOfDescriptors;
|
||||
ULONG32 SizeOfAlignPad;
|
||||
|
||||
MINIDUMP_FUNCTION_TABLE_DESCRIPTOR FunctionDescriptors[NumberOfDescriptors];
|
||||
};
|
||||
|
||||
struct MINIDUMP_UNLOADED_MODULE {
|
||||
ULONG64 BaseOfImage;
|
||||
type::Size32 SizeOfImage;
|
||||
ULONG32 CheckSum;
|
||||
ULONG32 TimeDateStamp;
|
||||
RVA ModuleNameRva;
|
||||
|
||||
char16 ModuleName[] @ ModuleNameRva + 4 [[hidden]];
|
||||
} [[format("format_unloaded_module")]];
|
||||
|
||||
fn format_unloaded_module(ref MINIDUMP_UNLOADED_MODULE module) {
|
||||
return module.ModuleName;
|
||||
};
|
||||
|
||||
struct MINIDUMP_UNLOADED_MODULE_LIST {
|
||||
ULONG32 SizeOfHeader;
|
||||
ULONG32 SizeOfEntry;
|
||||
ULONG32 NumberOfEntries;
|
||||
|
||||
if (SizeOfHeader > 12)
|
||||
padding[header.SizeOfHeader - 12];
|
||||
|
||||
MINIDUMP_UNLOADED_MODULE Modules[NumberOfEntries];
|
||||
};
|
||||
|
||||
struct MINIDUMP_MISC_INFO {
|
||||
ULONG32 SizeOfInfo;
|
||||
ULONG32 Flags1;
|
||||
ULONG32 ProcessId;
|
||||
ULONG32 ProcessCreateTime;
|
||||
ULONG32 ProcessUserTime;
|
||||
ULONG32 ProcessKernelTime;
|
||||
|
||||
if (SizeOfInfo > 24) {
|
||||
ULONG32 ProcessorMaxMhz;
|
||||
ULONG32 ProcessorCurrentMhz;
|
||||
ULONG32 ProcessorMhzLimit;
|
||||
ULONG32 ProcessorMaxIdleState;
|
||||
ULONG32 ProcessorCurrentIdleState;
|
||||
}
|
||||
};
|
||||
|
||||
struct MINIDUMP_MEMORY_INFO {
|
||||
ULONG64 BaseAddress;
|
||||
ULONG64 AllocationBase;
|
||||
ULONG32 AllocationProtect;
|
||||
padding[4];
|
||||
type::Size64 RegionSize;
|
||||
ULONG32 State;
|
||||
ULONG32 Protect;
|
||||
ULONG32 Type;
|
||||
padding[4];
|
||||
};
|
||||
|
||||
struct MINIDUMP_MEMORY_INFO_LIST {
|
||||
ULONG SizeOfHeader;
|
||||
ULONG SizeOfEntry;
|
||||
ULONG64 NumberOfEntries;
|
||||
|
||||
if (SizeOfHeader > 16)
|
||||
padding[SizeOfHeader - 16];
|
||||
|
||||
MINIDUMP_MEMORY_INFO Info[NumberOfEntries];
|
||||
};
|
||||
|
||||
struct MINIDUMP_THREAD_INFO {
|
||||
ULONG32 ThreadId;
|
||||
ULONG32 DumpFlags;
|
||||
ULONG32 DumpError;
|
||||
ULONG32 ExitStatus;
|
||||
ULONG64 CreateTime;
|
||||
ULONG64 ExitTime;
|
||||
ULONG64 KernelTime;
|
||||
ULONG64 UserTime;
|
||||
ULONG64 StartAddress;
|
||||
ULONG64 Affinity;
|
||||
};
|
||||
|
||||
struct MINIDUMP_THREAD_INFO_LIST {
|
||||
ULONG SizeOfHeader;
|
||||
ULONG SizeOfEntry;
|
||||
ULONG NumberOfEntries;
|
||||
|
||||
if (SizeOfHeader > 12)
|
||||
padding[SizeOfHeader - 12];
|
||||
|
||||
MINIDUMP_THREAD_INFO Info[NumberOfEntries];
|
||||
};
|
||||
|
||||
struct MINIDUMP_HANDLE_OPERATION_LIST {
|
||||
ULONG32 SizeOfHeader;
|
||||
ULONG32 SizeOfEntry;
|
||||
ULONG32 NumberOfEntries;
|
||||
ULONG32 Reserved;
|
||||
};
|
||||
|
||||
struct MINIDUMP_DIRECTORY {
|
||||
MINIDUMP_STREAM_TYPE StreamType;
|
||||
MINIDUMP_LOCATION_DESCRIPTOR Location;
|
||||
|
||||
if (StreamType == MINIDUMP_STREAM_TYPE::ThreadListStream)
|
||||
MINIDUMP_THREAD_LIST ThreadList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::ModuleListStream)
|
||||
MINIDUMP_MODULE_LIST ModuleList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::MemoryListStream)
|
||||
MINIDUMP_MEMORY_LIST MemoryList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::ExceptionStream)
|
||||
MINIDUMP_EXCEPTION_STREAM ExceptionInfo @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::SystemInfoStream)
|
||||
MINIDUMP_SYSTEM_INFO SystemInfo @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::ThreadExListStream)
|
||||
MINIDUMP_THREAD_EX_LIST ThreadExList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::Memory64ListStream)
|
||||
MINIDUMP_MEMORY64_LIST Mem64List @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::CommentStreamA)
|
||||
char Comment[] @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::CommentStreamW)
|
||||
char16 Comment[] @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::HandleDataStream)
|
||||
MINIDUMP_HANDLE_DATA_STREAM HandleData @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::FunctionTableStream)
|
||||
MINIDUMP_FUNCTION_TABLE_STREAM FunctionTable @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::UnloadedModuleListStream)
|
||||
MINIDUMP_UNLOADED_MODULE_LIST UnloadModuleList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::MiscInfoStream)
|
||||
MINIDUMP_MISC_INFO MiscInfo @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::MemoryInfoListStream)
|
||||
MINIDUMP_MEMORY_INFO_LIST MemInfoList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::ThreadInfoListStream)
|
||||
MINIDUMP_THREAD_INFO_LIST ThreadInfoList @ Location.Rva;
|
||||
else if (StreamType == MINIDUMP_STREAM_TYPE::HandleOperationListStream)
|
||||
MINIDUMP_HANDLE_OPERATION_LIST HandleOperList @ Location.Rva;
|
||||
};
|
||||
|
||||
bitfield MINIDUMP_TYPE {
|
||||
MiniDumpWithDataSegs : 1;
|
||||
MiniDumpWithFullMemory : 1;
|
||||
MiniDumpWithHandleData : 1;
|
||||
MiniDumpFilterMemory : 1;
|
||||
MiniDumpScanMemory : 1;
|
||||
MiniDumpWithUnloadedModules : 1;
|
||||
MiniDumpWithIndirectlyReferencedMemory : 1;
|
||||
MiniDumpFilterModulePaths : 1;
|
||||
MiniDumpWithProcessThreadData : 1;
|
||||
MiniDumpWithPrivateReadWriteMemory : 1;
|
||||
MiniDumpWithoutOptionalData : 1;
|
||||
MiniDumpWithFullMemoryInfo : 1;
|
||||
MiniDumpWithThreadInfo : 1;
|
||||
MiniDumpWithCodeSegs : 1;
|
||||
MiniDumpWithoutAuxiliaryState : 1;
|
||||
MiniDumpWithFullAuxiliaryState : 1;
|
||||
MiniDumpWithPrivateWriteCopyMemory : 1;
|
||||
MiniDumpIgnoreInaccessibleMemory : 1;
|
||||
MiniDumpWithTokenInformation : 1;
|
||||
MiniDumpWithModuleHeaders : 1;
|
||||
MiniDumpFilterTriage : 1;
|
||||
MiniDumpWithAvxXStateContext : 1;
|
||||
MiniDumpWithIptTrace : 1;
|
||||
MiniDumpScanInaccessiblePartialPages : 1;
|
||||
padding : 40;
|
||||
} [[right_to_left]];
|
||||
|
||||
struct MINIDUMP_HEADER {
|
||||
char Signature[4];
|
||||
ULONG32 Version;
|
||||
ULONG32 NumberOfStreams;
|
||||
RVA StreamDirectoryRva;
|
||||
ULONG32 Checksum;
|
||||
type::time32_t TimeDateStamp;
|
||||
MINIDUMP_TYPE Flags;
|
||||
};
|
||||
|
||||
struct MINIDUMP {
|
||||
MINIDUMP_HEADER Header;
|
||||
MINIDUMP_DIRECTORY Streams[Header.NumberOfStreams] [[format_entries("format_stream")]];
|
||||
};
|
||||
|
||||
fn format_stream(ref MINIDUMP_DIRECTORY stream) {
|
||||
return stream.StreamType;
|
||||
};
|
||||
|
||||
MINIDUMP MiniDump @ 0x00;
|
||||
154
patterns/msgpack.hexpat
Normal file
154
patterns/msgpack.hexpat
Normal file
@@ -0,0 +1,154 @@
|
||||
#pragma MIME application/x-msgpack
|
||||
|
||||
enum Type : u8 {
|
||||
PositiveFixInt = 0x00 ... 0x7F,
|
||||
FixMap = 0x80 ... 0x8F,
|
||||
FixArray = 0x90 ... 0x9F,
|
||||
FixStr = 0xA0 ... 0xBF,
|
||||
Nil = 0xC0,
|
||||
Unused = 0xC1,
|
||||
False = 0xC2,
|
||||
True = 0xC3,
|
||||
Bin8 = 0xC4,
|
||||
Bin16 = 0xC5,
|
||||
Bin32 = 0xC6,
|
||||
Ext8 = 0xC7,
|
||||
Ext16 = 0xC8,
|
||||
Ext32 = 0xC9,
|
||||
Float32 = 0xCA,
|
||||
Float64 = 0xCB,
|
||||
Uint8 = 0xCC,
|
||||
Uint16 = 0xCD,
|
||||
Uint32 = 0xCE,
|
||||
Uint64 = 0xCF,
|
||||
Int8 = 0xD0,
|
||||
Int16 = 0xD1,
|
||||
Int32 = 0xD2,
|
||||
Int64 = 0xD3,
|
||||
FixExt1 = 0xD4,
|
||||
FixExt2 = 0xD5,
|
||||
FixExt4 = 0xD6,
|
||||
FixExt8 = 0xD7,
|
||||
FixExt16 = 0xD8,
|
||||
Str8 = 0xD9,
|
||||
Str16 = 0xDA,
|
||||
Str32 = 0xDB,
|
||||
Array16 = 0xDC,
|
||||
Array32 = 0xDD,
|
||||
Map16 = 0xDE,
|
||||
Map32 = 0xDF,
|
||||
NegativeFixInt = 0xE0 ... 0xFF
|
||||
};
|
||||
|
||||
fn format_positive_fixint(u8 value) {
|
||||
return value & 0b0111'1111;
|
||||
};
|
||||
|
||||
fn format_negative_fixint(u8 value) {
|
||||
return -(value & 0b0001'1111);
|
||||
};
|
||||
|
||||
using MessagePack;
|
||||
|
||||
struct MapEntry {
|
||||
MessagePack key, value;
|
||||
};
|
||||
|
||||
struct MessagePack {
|
||||
Type type;
|
||||
|
||||
if (u8(type) <= 0x7F) {
|
||||
$ -= 1;
|
||||
u8 value [[format("format_positive_fixint")]];
|
||||
} else if (u8(type) >= Type::NegativeFixInt) {
|
||||
$ -= 1;
|
||||
u8 value [[format("format_negative_fixint")]];
|
||||
} else if (type == Type::Uint8)
|
||||
be u8 value;
|
||||
else if (type == Type::Uint16)
|
||||
be u16 value;
|
||||
else if (type == Type::Uint32)
|
||||
be u32 value;
|
||||
else if (type == Type::Uint64)
|
||||
be u64 value;
|
||||
else if (type == Type::Int8)
|
||||
be s8 value;
|
||||
else if (type == Type::Int16)
|
||||
be s16 value;
|
||||
else if (type == Type::Int32)
|
||||
be s32 value;
|
||||
else if (type == Type::Int64)
|
||||
be s64 value;
|
||||
else if (type == Type::Float32)
|
||||
be float value;
|
||||
else if (type == Type::Float64)
|
||||
be double value;
|
||||
else if ((u8(type) & 0b1110'0000) == Type::FixStr)
|
||||
char value[u8(type) & 0b0001'1111];
|
||||
else if (type == Type::Str8) {
|
||||
be u8 length;
|
||||
char value[length];
|
||||
} else if (type == Type::Str16) {
|
||||
be u16 length;
|
||||
char value[length];
|
||||
} else if (type == Type::Str32) {
|
||||
be u32 length;
|
||||
char value[length];
|
||||
} else if (type == Type::Bin8) {
|
||||
be u8 length;
|
||||
u8 value[length];
|
||||
} else if (type == Type::Bin16) {
|
||||
be u16 length;
|
||||
u8 value[length];
|
||||
} else if (type == Type::Bin32) {
|
||||
be u32 length;
|
||||
u8 value[length];
|
||||
} else if ((u8(type) & 0b1111'0000) == Type::FixArray)
|
||||
MessagePack value[u8(type) & 0b0000'1111];
|
||||
else if (type == Type::Array16) {
|
||||
be u16 length;
|
||||
MessagePack value[length];
|
||||
} else if (type == Type::Array32) {
|
||||
be u32 length;
|
||||
MessagePack value[length];
|
||||
} else if ((u8(type) & 0b1111'0000) == Type::FixMap)
|
||||
MapEntry value[u8(type) & 0b0000'1111];
|
||||
else if (type == Type::Map16) {
|
||||
be u16 length;
|
||||
MapEntry value[length];
|
||||
} else if (type == Type::Map32) {
|
||||
be u32 length;
|
||||
MapEntry value[length];
|
||||
} else if (type == Type::FixExt1) {
|
||||
s8 type;
|
||||
u8 data;
|
||||
} else if (type == Type::FixExt2) {
|
||||
s8 type;
|
||||
u16 data;
|
||||
} else if (type == Type::FixExt4) {
|
||||
s8 type;
|
||||
u32 data;
|
||||
} else if (type == Type::FixExt8) {
|
||||
s8 type;
|
||||
u64 data;
|
||||
} else if (type == Type::FixExt16) {
|
||||
s8 type;
|
||||
u128 data;
|
||||
} else if (type == Type::Ext8) {
|
||||
u8 length;
|
||||
s8 type;
|
||||
u8 data[length];
|
||||
} else if (type == Type::Ext16) {
|
||||
u16 length;
|
||||
s8 type;
|
||||
u8 data[length];
|
||||
} else if (type == Type::Ext32) {
|
||||
u32 length;
|
||||
s8 type;
|
||||
u8 data[length];
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
MessagePack pack @ 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;
|
||||
161
patterns/ntag.hexpat
Normal file
161
patterns/ntag.hexpat
Normal file
@@ -0,0 +1,161 @@
|
||||
bitfield AccessCapability {
|
||||
Read : 4;
|
||||
Write : 4;
|
||||
} [[left_to_right]];
|
||||
|
||||
struct CapabilityContainer {
|
||||
u8 magic;
|
||||
u8 version;
|
||||
u8 memorySize;
|
||||
AccessCapability accessCapability;
|
||||
};
|
||||
|
||||
bitfield NDEFFlags {
|
||||
MB : 1;
|
||||
ME : 1;
|
||||
CF : 1;
|
||||
SR : 1;
|
||||
IL : 1;
|
||||
TNF : 3;
|
||||
} [[left_to_right]];
|
||||
|
||||
enum TNFType : u8 {
|
||||
Empty = 0x00,
|
||||
NFCForumWellKnownType = 0x01,
|
||||
MediaType = 0x02,
|
||||
AbsoluteURI = 0x03,
|
||||
NFCForumExternalType = 0x04,
|
||||
Unknown = 0x05,
|
||||
Unchanged = 0x06,
|
||||
Reserved = 0x07
|
||||
};
|
||||
|
||||
struct NDEF {
|
||||
NDEFFlags flags;
|
||||
u8 typeLength;
|
||||
|
||||
if (flags.SR)
|
||||
u8 payloadLength;
|
||||
else
|
||||
u32 payloadLength;
|
||||
|
||||
if (flags.IL)
|
||||
u8 idLength;
|
||||
|
||||
char type[typeLength];
|
||||
|
||||
if (flags.IL)
|
||||
u8 id[idLength];
|
||||
|
||||
u8 payload[payloadLength];
|
||||
|
||||
if (flags.ME)
|
||||
break;
|
||||
};
|
||||
|
||||
struct LockControl {
|
||||
u8 dynamicLockByteOffset;
|
||||
u8 numBits;
|
||||
u8 pageControlInfo;
|
||||
};
|
||||
|
||||
struct MemoryControl {
|
||||
u8 reservedBytesOffset;
|
||||
u8 numBytes;
|
||||
u8 pageSize;
|
||||
};
|
||||
|
||||
struct Length {
|
||||
u8 byte [[hidden, no_unique_address]];
|
||||
if (byte == 0xFF)
|
||||
u24 length;
|
||||
else
|
||||
u8 length;
|
||||
} [[sealed, transform("transform_length"), format("transform_length")]];
|
||||
|
||||
fn transform_length(Length length) {
|
||||
return length.length;
|
||||
};
|
||||
|
||||
enum Tag : u8 {
|
||||
NULL = 0x00,
|
||||
LockControl = 0x01,
|
||||
MemoryControl = 0x02,
|
||||
NDEFMessage = 0x03,
|
||||
Proprietary = 0xFD,
|
||||
TerminatorTLV = 0xFE
|
||||
};
|
||||
|
||||
struct TLV {
|
||||
Tag tag;
|
||||
if (tag == Tag::TerminatorTLV) {
|
||||
break;
|
||||
} else if (tag == Tag::NULL) {
|
||||
// Empty
|
||||
} else {
|
||||
Length length;
|
||||
|
||||
if (length > 0) {
|
||||
if (tag == Tag::LockControl) {
|
||||
LockControl lockControl;
|
||||
} else if (tag == Tag::MemoryControl) {
|
||||
LockControl lockControl;
|
||||
} else if (tag == Tag::NDEFMessage) {
|
||||
NDEF ndef[while(true)];
|
||||
} else {
|
||||
u8 value[length];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct ManufacturerData {
|
||||
u8 serial1[3];
|
||||
u8 checkByte0;
|
||||
u8 serial2[4];
|
||||
u8 checkByte1;
|
||||
u8 internal;
|
||||
u16 lockBytes;
|
||||
};
|
||||
|
||||
struct DynamicLockBytes {
|
||||
u8 bytes[3];
|
||||
padding[1];
|
||||
};
|
||||
|
||||
bitfield MIRROR {
|
||||
MIRROR_CONF : 2;
|
||||
MIRROR_BYTE : 2;
|
||||
padding : 1;
|
||||
STRG_MOD_EN : 1;
|
||||
padding : 2;
|
||||
} [[left_to_right]];
|
||||
|
||||
bitfield ACCESS {
|
||||
PROT : 1;
|
||||
CFGLCK : 1;
|
||||
padding : 1;
|
||||
NFC_CNT_EN : 1;
|
||||
NFC_CNT_PWD_PROT : 1;
|
||||
AUTHLIM : 3;
|
||||
};
|
||||
|
||||
struct Config {
|
||||
MIRROR MIRROR;
|
||||
u8 MIRROR_PAGE;
|
||||
u8 AUTH0;
|
||||
ACCESS ACCESS;
|
||||
u32 PWD;
|
||||
u16 PACK;
|
||||
};
|
||||
|
||||
struct NTAG {
|
||||
ManufacturerData manufacturerData;
|
||||
CapabilityContainer cc;
|
||||
TLV tlv[while(true)];
|
||||
padding[addressof(tlv) + cc.memorySize * 8 - sizeof(tlv)];
|
||||
DynamicLockBytes dynamicLockBytes;
|
||||
Config config;
|
||||
};
|
||||
|
||||
NTAG ntag @ 0x00;
|
||||
29
patterns/ogg.hexpat
Normal file
29
patterns/ogg.hexpat
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma MIME audio/ogg
|
||||
|
||||
#include <std/core.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
bitfield HeaderType {
|
||||
Continuation : 1;
|
||||
BeginOfStream : 1;
|
||||
EndOfStream : 1;
|
||||
};
|
||||
|
||||
struct SegmentData {
|
||||
u8 data[parent.segmentTable[std::core::array_index()]];
|
||||
};
|
||||
|
||||
struct Ogg {
|
||||
char capturePattern[4];
|
||||
u8 version;
|
||||
HeaderType headerType;
|
||||
u64 granulePosition;
|
||||
u32 bitstreamSerialNumber;
|
||||
u32 pageSequenceNumber;
|
||||
u32 checksum;
|
||||
u8 pageSegments;
|
||||
u8 segmentTable[pageSegments];
|
||||
SegmentData data[pageSegments];
|
||||
};
|
||||
|
||||
Ogg ogg[while(!std::mem::eof())] @ 0x00;
|
||||
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;
|
||||
1258
patterns/pe.hexpat
1258
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")]];
|
||||
66
patterns/protobuf.hexpat
Normal file
66
patterns/protobuf.hexpat
Normal file
@@ -0,0 +1,66 @@
|
||||
#include <std/mem.pat>
|
||||
|
||||
#include <type/leb128.pat>
|
||||
|
||||
struct ZigZag32 {
|
||||
u32 value;
|
||||
} [[sealed, format("format_zigzag32")]];
|
||||
|
||||
fn format_zigzag32(ZigZag32 zigzag) {
|
||||
return s32((s32(zigzag.value) << 1) ^ (s32(zigzag.value) >> 31));
|
||||
};
|
||||
|
||||
struct ZigZag64 {
|
||||
u64 value;
|
||||
} [[sealed, format("format_zigzag64")]];
|
||||
|
||||
fn format_zigzag64(ZigZag64 zigzag) {
|
||||
return s64((s64(zigzag.value) << 1) ^ (s64(zigzag.value) >> 63));
|
||||
};
|
||||
|
||||
enum WireType : u8 {
|
||||
Varint = 0,
|
||||
_64Bit = 1,
|
||||
LengthDelimited = 2,
|
||||
StartGroup = 3,
|
||||
EndGroup = 4,
|
||||
_32Bit = 5
|
||||
};
|
||||
|
||||
bitfield Key {
|
||||
field_number : 5;
|
||||
wire_type : 3;
|
||||
} [[left_to_right]];
|
||||
|
||||
union _64Bit {
|
||||
u64 fixed64;
|
||||
ZigZag64 sfixed64;
|
||||
double dbl;
|
||||
};
|
||||
|
||||
union _32Bit {
|
||||
u32 fixed32;
|
||||
ZigZag32 sfixed32;
|
||||
float flt;
|
||||
};
|
||||
|
||||
struct LengthDelimited {
|
||||
type::LEB128 length;
|
||||
char data[length];
|
||||
};
|
||||
|
||||
|
||||
struct Entry {
|
||||
Key key;
|
||||
|
||||
if (key.wire_type == WireType::Varint)
|
||||
type::LEB128 value;
|
||||
else if (key.wire_type == WireType::_64Bit)
|
||||
_64Bit value;
|
||||
else if (key.wire_type == WireType::LengthDelimited)
|
||||
LengthDelimited value;
|
||||
else if (key.wire_type == WireType::_32Bit)
|
||||
_32Bit value;
|
||||
};
|
||||
|
||||
Entry entries[while(!std::mem::eof())] @ 0x00;
|
||||
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;
|
||||
38
patterns/stl.hexpat
Normal file
38
patterns/stl.hexpat
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma MIME model/stl
|
||||
#pragma MIME model/x.stl-binary
|
||||
#pragma MIME model/x.stl-ascii
|
||||
#pragma MIME application/sla
|
||||
|
||||
#include <std/sys.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
struct Vector3f {
|
||||
float x, y, z;
|
||||
} [[static, format("format_vector3f")]];
|
||||
|
||||
fn format_vector3f(Vector3f vec) {
|
||||
return std::format("[ {}, {}, {} ]", vec.x, vec.y, vec.z);
|
||||
};
|
||||
|
||||
struct Triangle {
|
||||
Vector3f normal;
|
||||
Vector3f points[3];
|
||||
u16 flags;
|
||||
} [[static]];
|
||||
|
||||
struct BinarySTLHeader {
|
||||
char caption[];
|
||||
padding[80 - sizeof(caption)];
|
||||
u32 triangleCount;
|
||||
};
|
||||
|
||||
struct STL {
|
||||
if (std::mem::read_string(0, 6) == "solid ")
|
||||
std::warning("ASCII STL file!");
|
||||
else {
|
||||
BinarySTLHeader header;
|
||||
Triangle triangles[header.triangleCount];
|
||||
}
|
||||
};
|
||||
|
||||
STL stl @ 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;
|
||||
193
patterns/vhdx.hexpat
Normal file
193
patterns/vhdx.hexpat
Normal file
@@ -0,0 +1,193 @@
|
||||
#include <std/io.pat>
|
||||
#include <std/ptr.pat>
|
||||
#include <std/core.pat>
|
||||
|
||||
#include <type/guid.pat>
|
||||
#include <type/size.pat>
|
||||
|
||||
struct FileTypeIdentifier {
|
||||
char signature[8];
|
||||
char16 creator[256];
|
||||
padding[0x1'0000 - sizeof(signature) - sizeof(creator)];
|
||||
};
|
||||
|
||||
struct DataSector {
|
||||
u32 sequenceHigh;
|
||||
u8 data[4084];
|
||||
u32 sequenceLow;
|
||||
} [[static]];
|
||||
|
||||
struct ZeroDescriptor {
|
||||
padding[4];
|
||||
u64 zeroLength;
|
||||
DataSector *dataSector : u64;
|
||||
u64 sequenceNumber;
|
||||
} [[static]];
|
||||
|
||||
struct DataDescriptor {
|
||||
u32 trailingBytes;
|
||||
u64 leadingBytes;
|
||||
DataSector *dataSector : u64;
|
||||
u64 sequenceNumber;
|
||||
} [[static]];
|
||||
|
||||
struct LogDescriptor {
|
||||
char signature[4];
|
||||
|
||||
if (signature == "zero")
|
||||
ZeroDescriptor descriptor [[inline]];
|
||||
else if (signature == "desc")
|
||||
DataDescriptor descriptor [[inline]];
|
||||
};
|
||||
|
||||
struct LogEntry {
|
||||
char signature[4];
|
||||
u32 checksum;
|
||||
type::Size32 entryLength;
|
||||
u32 tail;
|
||||
u64 sequenceNumber;
|
||||
u32 descriptorCount;
|
||||
padding[4];
|
||||
type::GUID logGuid;
|
||||
u64 flushedFileOffset;
|
||||
u64 lastFileOffset;
|
||||
} [[static]];
|
||||
|
||||
bitfield BAT {
|
||||
State : 3;
|
||||
padding : 17;
|
||||
FileOffsetMB : 44;
|
||||
} [[right_to_left]];
|
||||
|
||||
bitfield MetadataEntryFlags {
|
||||
IsUser : 1;
|
||||
IsVirtualDisk : 1;
|
||||
IsRequired : 1;
|
||||
padding : 29;
|
||||
};
|
||||
|
||||
bitfield FileParameterFlags {
|
||||
LeaveBlockAllocated : 1;
|
||||
HasParent : 1;
|
||||
padding : 30;
|
||||
};
|
||||
|
||||
struct MetadataFileParameters {
|
||||
type::Size32 blockSize;
|
||||
FileParameterFlags flags;
|
||||
};
|
||||
|
||||
struct MetadataVirtualDiskSize {
|
||||
type::Size64 virtualDiskSize;
|
||||
};
|
||||
|
||||
struct MetadataVirtualDiskID {
|
||||
type::GUID virtualDiskID;
|
||||
};
|
||||
|
||||
struct MetadataLogicalSectorSize {
|
||||
type::Size32 logicalSectorSize;
|
||||
};
|
||||
|
||||
struct MetadataPhysicalSectorSize {
|
||||
type::Size32 physicalSectorSize;
|
||||
};
|
||||
|
||||
struct ParentLocatorEntry {
|
||||
u32 keyOffset;
|
||||
u32 valueOffset;
|
||||
u16 keyLength;
|
||||
u16 valueLength;
|
||||
|
||||
char key[keyLength] @ addressof(parent) + keyOffset;
|
||||
char value[valueLength] @ addressof(parent) + valueOffset;
|
||||
};
|
||||
|
||||
struct MetadataParentLocator {
|
||||
type::GUID locatorType;
|
||||
padding[2];
|
||||
u16 keyValueCount;
|
||||
ParentLocatorEntry entries[keyValueCount];
|
||||
};
|
||||
|
||||
fn metadata_relative(u128 offset) {
|
||||
return addressof(parent.parent);
|
||||
};
|
||||
|
||||
struct MetadataTableEntry {
|
||||
type::GUID itemID;
|
||||
|
||||
if (std::core::formatted_value(itemID) == "{CAA16737-FA36-4D43-B3B6-33F0AA44E76B}")
|
||||
MetadataFileParameters *data : u32 [[pointer_base("metadata_relative")]];
|
||||
else if (std::core::formatted_value(itemID) == "{2FA54224-CD1B-4876-B211-5DBED83BF4B8}")
|
||||
MetadataVirtualDiskSize *data : u32 [[pointer_base("metadata_relative")]];
|
||||
else if (std::core::formatted_value(itemID) == "{BECA12AB-B2E6-4523-93EF-C309E000C746}")
|
||||
MetadataVirtualDiskID *data : u32 [[pointer_base("metadata_relative")]];
|
||||
else if (std::core::formatted_value(itemID) == "{8141BF1D-A96F-4709-BA47-F233A8FAAB5F}")
|
||||
MetadataLogicalSectorSize *data : u32 [[pointer_base("metadata_relative")]];
|
||||
else if (std::core::formatted_value(itemID) == "{CDA348C7-445D-4471-9CC9-E9885251C556}")
|
||||
MetadataPhysicalSectorSize *data : u32 [[pointer_base("metadata_relative")]];
|
||||
else if (std::core::formatted_value(itemID) == "{A8D35F2D-B30B-454D-ABF7-D3D84834AB0C}")
|
||||
MetadataParentLocator *data : u32 [[pointer_base("metadata_relative")]];
|
||||
else
|
||||
u32 dataOffset;
|
||||
|
||||
type::Size32 length;
|
||||
MetadataEntryFlags flags;
|
||||
padding[4];
|
||||
};
|
||||
|
||||
struct MetadataRegion {
|
||||
char signature[8];
|
||||
padding[2];
|
||||
u16 entryCount;
|
||||
padding[20];
|
||||
MetadataTableEntry entries[entryCount];
|
||||
};
|
||||
|
||||
struct RegionTableEntry {
|
||||
type::GUID guid;
|
||||
|
||||
if (std::core::formatted_value(guid) == "{2DC27766-F623-4200-9D64-115E9BFD4A08}")
|
||||
BAT *bat : u64;
|
||||
else if (std::core::formatted_value(guid) == "{8B7CA206-4790-4B9A-B8FE-575F050F886E}")
|
||||
MetadataRegion *metadata : u64;
|
||||
else
|
||||
u64 fileOffset;
|
||||
|
||||
type::Size32 length;
|
||||
u32 required;
|
||||
};
|
||||
|
||||
struct RegionTable {
|
||||
char signature[4];
|
||||
u32 checksum;
|
||||
u32 entryCount;
|
||||
padding[4];
|
||||
|
||||
RegionTableEntry entries[entryCount];
|
||||
};
|
||||
|
||||
struct Header {
|
||||
char signature[4];
|
||||
u32 checksum;
|
||||
u64 sequenceNumber;
|
||||
type::GUID fileWriteGuid, dataWriteGuid, logGuid;
|
||||
u16 logVersion;
|
||||
u16 version;
|
||||
type::Size32 logLength;
|
||||
LogEntry *log : u64;
|
||||
padding[4016];
|
||||
};
|
||||
|
||||
struct VHDX {
|
||||
FileTypeIdentifier fileTypeIdentifier;
|
||||
|
||||
Header header @ 0x1'0000;
|
||||
Header headerBackup @ 0x2'0000;
|
||||
|
||||
RegionTable regionTable @ 0x3'0000;
|
||||
RegionTable regionTableBackup @ 0x4'0000;
|
||||
};
|
||||
|
||||
VHDX vhdx @ 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;
|
||||
@@ -17,6 +17,7 @@ enum WaveFormatType : u16 {
|
||||
Unknown,
|
||||
PCM,
|
||||
MS_ADPCM,
|
||||
IEEEFloatingPoint,
|
||||
ALAW = 6,
|
||||
MULAW,
|
||||
IMA_ADPCM = 0x11,
|
||||
@@ -83,6 +84,10 @@ bitfield WaveMPEGFlags {
|
||||
padding : 11;
|
||||
};
|
||||
|
||||
struct WaveFormatIEEEFloatingPoint : WaveFormatPCM {
|
||||
|
||||
};
|
||||
|
||||
struct WaveFormatMPEG : WaveFormatEx {
|
||||
WaveMPEGLayer headLayersUsed;
|
||||
u32 headBitrate;
|
||||
@@ -169,7 +174,7 @@ struct WaveListItem : WaveChunk {
|
||||
} else if (chunkId == "note") {
|
||||
WaveNote note;
|
||||
} else {
|
||||
padding[chunkSize];
|
||||
padding[(chunkSize + 1) >> 1 << 1];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -181,38 +186,53 @@ struct WaveList {
|
||||
WaveListItem item[while ($ < listEnd)];
|
||||
};
|
||||
|
||||
u32 paddedChunkSize;
|
||||
|
||||
struct WavData {
|
||||
WaveChunk chunk;
|
||||
paddedChunkSize = (chunk.chunkSize + 1) >> 1 << 1;
|
||||
|
||||
if (chunk.chunkId == "fmt ") {
|
||||
WaveFormat fmt;
|
||||
|
||||
if (fmt.formatTag == WaveFormatType::PCM) {
|
||||
WaveFormatPCM pcmExtraData;
|
||||
padding[paddedChunkSize - sizeof(fmt) - sizeof(pcmExtraData)];
|
||||
} else if (fmt.formatTag == WaveFormatType::MS_ADPCM) {
|
||||
WaveFormatMSADPCM msAdpcmExtraData;
|
||||
padding[paddedChunkSize - sizeof(fmt) - sizeof(msAdpcmExtraData)];
|
||||
} else if (fmt.formatTag == WaveFormatType::MPEG) {
|
||||
WaveFormatMPEG mpegExtraData;
|
||||
padding[paddedChunkSize - sizeof(fmt) - sizeof(mpegExtraData)];
|
||||
} else if (fmt.formatTag == WaveFormatType::MPEGLAYER3) {
|
||||
WaveFormatMPEGLayer3 mpegLayer3ExtraData;
|
||||
padding[paddedChunkSize - sizeof(fmt) - sizeof(mpegLayer3ExtraData)];
|
||||
} else if (fmt.formatTag == WaveFormatType::IEEEFloatingPoint) {
|
||||
WaveFormatIEEEFloatingPoint ieeFloatingPointExtraData;
|
||||
padding[paddedChunkSize - sizeof(fmt) - sizeof(ieeFloatingPointExtraData)];
|
||||
} else {
|
||||
WaveFormatExDummy unknown;
|
||||
padding[paddedChunkSize - sizeof(fmt) - sizeof(unknown)];
|
||||
}
|
||||
} else if (chunk.chunkId == "data") {
|
||||
padding[chunk.chunkSize];
|
||||
padding[paddedChunkSize];
|
||||
} else if (chunk.chunkId == "fact") {
|
||||
WaveFact fact;
|
||||
padding[paddedChunkSize - sizeof(fact)];
|
||||
} else if (chunk.chunkId == "smpl") {
|
||||
WaveSample smpl;
|
||||
padding[paddedChunkSize - sizeof(smpl)];
|
||||
} else if (chunk.chunkId == "cue ") {
|
||||
WaveCue cue;
|
||||
padding[paddedChunkSize - sizeof(cue)];
|
||||
} else if (chunk.chunkId == "LIST") {
|
||||
listEnd = $ + chunk.chunkSize;
|
||||
WaveList list;
|
||||
padding[paddedChunkSize % 1];
|
||||
} else {
|
||||
padding[chunk.chunkSize];
|
||||
padding[paddedChunkSize];
|
||||
}
|
||||
};
|
||||
|
||||
RiffHeader header @0x00;
|
||||
WavData data[while (!std::mem::eof())] @$;
|
||||
WavData data[while (!std::mem::eof())] @ $;
|
||||
|
||||
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;
|
||||
52
patterns/xilinx_bit.hexpat
Normal file
52
patterns/xilinx_bit.hexpat
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <std/mem.pat>
|
||||
#include <std/io.pat>
|
||||
|
||||
struct Flags {
|
||||
be u16 length;
|
||||
u8 value[length];
|
||||
};
|
||||
|
||||
struct TLV {
|
||||
char tag[parent.keySize];
|
||||
be u16 length;
|
||||
char value[length];
|
||||
};
|
||||
|
||||
struct Command {
|
||||
be u32 value;
|
||||
} [[static, sealed, format("format_command")]];
|
||||
|
||||
fn format_command(Command command) {
|
||||
u32 x = command.value;
|
||||
|
||||
if (x == 0x20000000) return "NOP";
|
||||
if (x == 0xAA995566) return "SYNC";
|
||||
if (x == 0x000000BB) return "Bus Width Sync";
|
||||
if (x == 0x11220044) return "Bus Width Detect";
|
||||
if (x == 0x30002001) return "Write to FAR";
|
||||
if (x == 0x28006000) return "Write to FDRO";
|
||||
if (x == 0x30000001) return "Write to CRC";
|
||||
if (x == 0x30018001) return "Write to IDCODE";
|
||||
if (x == 0x30004000) return "Write to FDRI";
|
||||
if (x == 0x30008001) return "Write to CMD";
|
||||
|
||||
if ((x & 0xF0000000) == 0x30000000)
|
||||
return std::format("Write to Register {}", (x & 0x0003E000) >> 13);
|
||||
|
||||
return std::format("0x{:08X}", x);
|
||||
};
|
||||
|
||||
struct Commands {
|
||||
char tag[parent.keySize];
|
||||
be u32 length;
|
||||
Command commands[length / 4];
|
||||
};
|
||||
|
||||
struct Header {
|
||||
Flags flags;
|
||||
be u16 keySize;
|
||||
TLV tlv[4];
|
||||
Commands data;
|
||||
};
|
||||
|
||||
Header header @ 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;
|
||||
@@ -4,7 +4,7 @@ from pathlib import Path
|
||||
|
||||
def extractData(projectName, jsonData, objectName, extension):
|
||||
if objectName in jsonData:
|
||||
with open(f"./{projectName}.{extension}", "w") as output:
|
||||
with open(f"./{projectName}.{extension}", mode="w", encoding="utf-8") as output:
|
||||
output.write(jsonData[objectName])
|
||||
|
||||
def main():
|
||||
@@ -13,7 +13,7 @@ def main():
|
||||
exit(1)
|
||||
|
||||
projectPath = sys.argv[1]
|
||||
with open(projectPath, "r") as file:
|
||||
with open(projectPath, mode="r", encoding="utf-8") as file:
|
||||
jsonData = json.loads(file.read())
|
||||
|
||||
projectName = Path(projectPath).stem
|
||||
@@ -22,7 +22,7 @@ def main():
|
||||
extractData(projectName, jsonData, "pattern", "hexpat")
|
||||
|
||||
if "bookmarks" in jsonData:
|
||||
with open(f"./{projectName}.hexbm", "w") as output:
|
||||
with open(f"./{projectName}.hexbm", mode="w", encoding="utf-8") as output:
|
||||
jsonOutput = {}
|
||||
jsonOutput["bookmarks"] = jsonData["bookmarks"]
|
||||
|
||||
@@ -32,4 +32,4 @@ def main():
|
||||
print(f"Project file used file {jsonData['filePath']}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main()
|
||||
|
||||
@@ -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 });
|
||||
|
||||
@@ -46,6 +48,8 @@ int main(int argc, char **argv) {
|
||||
runtime.addPragma("eval_depth", DummyPragmaHandler);
|
||||
runtime.addPragma("array_limit", DummyPragmaHandler);
|
||||
runtime.addPragma("pattern_limit", DummyPragmaHandler);
|
||||
|
||||
runtime.addDefine("__PL_UNIT_TESTS__");
|
||||
}
|
||||
|
||||
// Execute pattern
|
||||
@@ -71,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,13 +41,16 @@ 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);
|
||||
runtime.addDefine("__PL_UNIT_TESTS__");
|
||||
}
|
||||
|
||||
// Execute pattern
|
||||
@@ -73,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/bson.hexpat.bin
Normal file
BIN
tests/patterns/test_data/bson.hexpat.bin
Normal file
Binary file not shown.
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/elf.hexpat.elf
Normal file
BIN
tests/patterns/test_data/elf.hexpat.elf
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/lnk.hexpat.lnk
Normal file
BIN
tests/patterns/test_data/lnk.hexpat.lnk
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/msgpack.hexpat.bin
Normal file
BIN
tests/patterns/test_data/msgpack.hexpat.bin
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/ntag.hexpat.bin
Normal file
BIN
tests/patterns/test_data/ntag.hexpat.bin
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.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user