mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-03-31 05:15:54 -05:00
Compare commits
129 Commits
ImHex-v1.2
...
ImHex-v1.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1cd7f92a5d | ||
|
|
d42b87d9e6 | ||
|
|
035de359d7 | ||
|
|
fe59788783 | ||
|
|
ef198cf24f | ||
|
|
b73b69a8cc | ||
|
|
5d72494019 | ||
|
|
afbce642fb | ||
|
|
a72058eb65 | ||
|
|
ab2ed98dab | ||
|
|
3edc6ea172 | ||
|
|
a9a7f0b186 | ||
|
|
5f352e26d1 | ||
|
|
3e2a6aabaa | ||
|
|
56d6f0187f | ||
|
|
adf7256c39 | ||
|
|
a25a8a3615 | ||
|
|
6ae8b30488 | ||
|
|
125ba38d72 | ||
|
|
ba55feb200 | ||
|
|
a301a4bfeb | ||
|
|
531be04739 | ||
|
|
87e05bec48 | ||
|
|
a31d290005 | ||
|
|
f3de35a320 | ||
|
|
d9de2f7058 | ||
|
|
790f837e4f | ||
|
|
d8a291977a | ||
|
|
62a83b53aa | ||
|
|
53ea45ffa6 | ||
|
|
c0a1bbd218 | ||
|
|
27f4e20638 | ||
|
|
bbb2107d5f | ||
|
|
8601a6665e | ||
|
|
c6f2b57384 | ||
|
|
dd190f7c8a | ||
|
|
55e3fec3bc | ||
|
|
8e78f371f5 | ||
|
|
2758ec8d36 | ||
|
|
82ca79c166 | ||
|
|
146273b1b3 | ||
|
|
ab4bff9f42 | ||
|
|
000f0eb730 | ||
|
|
2d45d5d086 | ||
|
|
2d4b4add82 | ||
|
|
e635c3a5bf | ||
|
|
15234a284d | ||
|
|
0673673b99 | ||
|
|
3786f7e265 | ||
|
|
ea4dda001a | ||
|
|
324b0894d3 | ||
|
|
e89e85e10c | ||
|
|
b93e957e46 | ||
|
|
e7eba44ae0 | ||
|
|
41d801a114 | ||
|
|
25f73ca721 | ||
|
|
facbe59163 | ||
|
|
55023ce4ea | ||
|
|
32158edb3a | ||
|
|
862d4d1c28 | ||
|
|
d4045b76c3 | ||
|
|
8ab2ff4ab1 | ||
|
|
5ea7141cb7 | ||
|
|
9b13113682 | ||
|
|
0748fa135e | ||
|
|
a4a14309be | ||
|
|
7c179b3b41 | ||
|
|
c204696209 | ||
|
|
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 |
@@ -6,5 +6,6 @@
|
||||
- [ ] 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)
|
||||
- Make sure to never use `application/octet-stream` here as that means "Unidentifiable binary data"
|
||||
- [ ] 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
|
||||
|
||||
47
.github/workflows/dispatch.yml
vendored
Normal file
47
.github/workflows/dispatch.yml
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
name: "Dispatch"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ '*' ]
|
||||
pull_request:
|
||||
branches: [ '*' ]
|
||||
repository_dispatch:
|
||||
types: [run_tests]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
generate_docs:
|
||||
description: "Regenerate docs"
|
||||
required: false
|
||||
type: boolean
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
name: 🎯 Dispatch changes
|
||||
runs-on: ubuntu-22.04
|
||||
env:
|
||||
DISPATCH_TOKEN: ${{ secrets.DISPATCH_TOKEN }}
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: 📄 Check changed include files
|
||||
id: changed-includes
|
||||
uses: tj-actions/changed-files@v35
|
||||
with:
|
||||
files: includes/**/*.pat
|
||||
|
||||
- name: ✉️ Run Documentation generator
|
||||
if: ${{ env.DISPATCH_TOKEN != '' && (steps.changed-includes.outputs.any_changed == 'true' || inputs.generate_docs || github.event_name == 'repository_dispatch' ) }}
|
||||
uses: mvasigh/dispatch-action@main
|
||||
with:
|
||||
token: ${{ secrets.DISPATCH_TOKEN }}
|
||||
repo: Documentation
|
||||
owner: WerWolv
|
||||
event_type: update_pl_docs
|
||||
1
.github/workflows/tests.yml
vendored
1
.github/workflows/tests.yml
vendored
@@ -50,6 +50,7 @@ jobs:
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld --coverage" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld --coverage" \
|
||||
-DLIBPL_ENABLE_TESTS=OFF \
|
||||
-DLIBPL_ENABLE_CLI=OFF \
|
||||
..
|
||||
make -j4
|
||||
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,3 +2,4 @@
|
||||
tests/cmake-build-debug/
|
||||
|
||||
.idea/
|
||||
.DS_Store
|
||||
12
CONTRIBUTING.md
Normal file
12
CONTRIBUTING.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Contributing
|
||||
|
||||
Contributing to the Database is very simple. Fork this repository, add your new files (or changes to existing files) to the right folders and create a PR.
|
||||
When adding new files, please make sure to also add a link to them to the Table of Contents in the README.md file. That way the files can be discovered by others more easily.
|
||||
|
||||
Thanks a lot for any additions or improvements :)
|
||||
|
||||
## Adding new Patterns
|
||||
|
||||
When adding new patterns, if possible, please also add a test file named `<pattern_name>.hexpat.<extension>` to the `/tests/patterns/test_data` directory. This allows our Unit Tests to be run against your code so we can make sure it stays up-to-date and doesn't break when changes are made to the PatternLanguage.
|
||||
Please try to keep these files as small as possible (~100kiB at most) so cloning stays fast.
|
||||
Please also make sure to not submit any test files that are under copyright such as game files, ROMs or files extracted from other programs. We don't want a DMCA takedown on this repo.
|
||||
230
README.md
230
README.md
@@ -1,6 +1,20 @@
|
||||
# ImHex-Patterns
|
||||
# ImHex Database
|
||||
|
||||
Hex patterns, include patterns and magic files for the use with the ImHex Hex Editor
|
||||
This repository serves as a database for files to use with the [ImHex Hex Editor](https://github.com/WerWolv/ImHex). It currently contains
|
||||
- [Patterns](/patterns) - Binary Format definitions for the Pattern Language
|
||||
- [Pattern Libraries](/includes) - Libraries that make using the Pattern Language easier
|
||||
- [Magic Files](/magic) - Custom magic file definitions for the use with libmagic
|
||||
- [Encodings](/encodings) - Custom encodings in the .tbl format
|
||||
- [Data Processor Nodes](/nodes) - Custom nodes made for ImHex's Data Processor
|
||||
- [Themes](/themes) - Custom themes for ImHex
|
||||
- [Constants](/constants) - Constants definition files
|
||||
- [Scripts](/scripts) - Various scripts to generate code or automate some tasks
|
||||
- [Yara](/yara) - Custom Yara rules
|
||||
|
||||
## Submissions
|
||||
|
||||
Most files in this repository have been submitted by the community. Please feel free to open a PR on your own and add files to it!
|
||||
Everything will immediately show up in ImHex's Content Store and gets bundled with the next release of ImHex.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
@@ -8,122 +22,160 @@ Hex patterns, include patterns and magic files for the use with the ImHex Hex Ed
|
||||
|
||||
| Name | MIME | Path | Description |
|
||||
|------|------|------|-------------|
|
||||
| BMP | `image/bmp` | `patterns/bmp.hexpat` | OS2/Windows Bitmap files |
|
||||
| ELF | `application/x-executable` | `patterns/elf.hexpat` | ELF header in elf binaries |
|
||||
| PE | `application/x-dosexec` | `patterns/pe.hexpat` | PE header, COFF header, Standard COFF fields and Windows Specific fields |
|
||||
| Intel HEX | | `patterns/intel_hex.hexpat` | [Intel hexadecimal object file format definition]("https://en.wikipedia.org/wiki/Intel_HEX") |
|
||||
| MIDI | `audio/midi` | `patterns/midi.hexpat` | MIDI header, event fields provided |
|
||||
| WAV | `audio/wav` | `patterns/wav.hexpat` | RIFF header, WAVE header, PCM header |
|
||||
| ZIP | `application/zip` | `patterns/zip.hexpat` | End of Central Directory Header, Central Directory File Headers |
|
||||
| PCAP | `application/vnd.tcpdump.pcap` | `patterns/pcap.hexpat` | pcap header and packets |
|
||||
| SPIRV | | `patterns/spirv.hexpat` | SPIR-V header and instructions |
|
||||
| AFE2 | | `patterns/afe2.hexpat` | Nintendo Switch Atmosphère CFW Fatal Error log |
|
||||
| AR | `application/x-archive` | `patterns/ar.hexpat` | Static library archive files |
|
||||
| NACP | | `patterns/nacp.hexpat` | Nintendo Switch NACP files |
|
||||
| NRO | | `patterns/nro.hexpat` | Nintendo Switch NRO files |
|
||||
| PRODINFO | | `patterns/prodinfo.hexpat` | Nintendo Switch PRODINFO |
|
||||
| Java Class | `application/x-java-applet` | `patterns/java_class.hexpat` | Java Class files |
|
||||
| ARM VTOR | | `patterns/arm_cm_vtor.hexpat` | ARM Cortex M Vector Table Layout |
|
||||
| ICO | | `patterns/ico.hexpat` | Icon (.ico) or Cursor (.cur) files |
|
||||
| PNG | `image/png` | `patterns/png.hexpat` | PNG image files |
|
||||
| DDS | `image/vnd-ms.dds` | `patterns/dds.hexpat` | DirectDraw Surface |
|
||||
| TGA | `image/tga` | `patterns/tga.hexpat` | Truevision TGA/TARGA image |
|
||||
| ISO | | `patterns/iso.hexpat` | ISO 9660 file system |
|
||||
| VDF | | `patterns/vdf.hexpat` | Binary Value Data Format (.vdf) files |
|
||||
| IP | | `patterns/ip.hexpat` | Ethernet II Frames (IP Packets) |
|
||||
| UF2 | | `patterns/uf2.hexpat` | [USB Flashing Format](https://github.com/microsoft/uf2) |
|
||||
| File System | | `patterns/fs.hexpat` | Drive File System |
|
||||
| Bencode | `application/x-bittorrent` | `patterns/bencode.hexpat` | Bencode encoding, used by Torrent files |
|
||||
| Protobuf | | `patterns/protobuf.hexpat` | Google Protobuf encoding |
|
||||
| OGG | `audio/ogg` | `patterns/ogg.hexpat` | OGG Audio format |
|
||||
| STL | `model/stl` | `patterns/stl.hexpat` | STL 3D Model format |
|
||||
| VHDX | | `patterns/vhdx.hexpat` | Microsoft Hyper-V Virtual Hard Disk format |
|
||||
| NTAG | | `patterns/ntag.hexpat` | NTAG213/NTAG215/NTAG216, NFC Forum Type 2 Tag compliant IC |
|
||||
| Shell Link | `application/x-ms-shortcut` | `patterns/lnk.hexpat` | Windows Shell Link file format |
|
||||
| Xilinx BIT | | `patterns/xilinx_bit.hexpat` | Xilinx FPGA Bitstreams |
|
||||
| FLAC | `audio/flac` | `patterns/flac.hexpat` | Free Lossless Audio Codec, FLAC Audio Format |
|
||||
| BSON | `application/bson` | `patterns/bson.hexpat` | BSON (Binary JSON) format |
|
||||
| msgpack | `application/x-msgpack` | `patterns/msgpack.hexpat` | MessagePack binary serialization format |
|
||||
| MiniDump | `application/x-dmp` | `patterns/minidump.hexpat` | Windows MiniDump files |
|
||||
| BMP | `image/bmp` | [`patterns/bmp.hexpat`](patterns/bmp.hexpat) | OS2/Windows Bitmap files |
|
||||
| ELF | `application/x-executable` | [`patterns/elf.hexpat`](patterns/elf.hexpat) | ELF header in elf binaries |
|
||||
| PE | `application/x-dosexec` | [`patterns/pe.hexpat`](patterns/pe.hexpat) | PE header, COFF header, Standard COFF fields and Windows Specific fields |
|
||||
| NE | | [`patterns/ne.hexpat`](patterns/ne.hexpat) | NE header and Standard NE fields |
|
||||
| Intel HEX | | [`patterns/intel_hex.hexpat`](patterns/intel_hex.hexpat) | [Intel hexadecimal object file format definition]("https://en.wikipedia.org/wiki/Intel_HEX") |
|
||||
| MIDI | `audio/midi` | [`patterns/midi.hexpat`](patterns/midi.hexpat) | MIDI header, event fields provided |
|
||||
| WAV | `audio/wav` | [`patterns/wav.hexpat`](patterns/wav.hexpat) | RIFF header, WAVE header, PCM header |
|
||||
| ZIP | `application/zip` | [`patterns/zip.hexpat`](patterns/zip.hexpat) | End of Central Directory Header, Central Directory File Headers |
|
||||
| PCAP | `application/vnd.tcpdump.pcap` | [`patterns/pcap.hexpat`](patterns/pcap.hexpat) | pcap header and packets |
|
||||
| SPIRV | | [`patterns/spirv.hexpat`](patterns/spirv.hexpat) | SPIR-V header and instructions |
|
||||
| AFE2 | | [`patterns/afe2.hexpat`](patterns/afe2.hexpat) | Nintendo Switch Atmosphère CFW Fatal Error log |
|
||||
| AR | `application/x-archive` | [`patterns/ar.hexpat`](patterns/ar.hexpat) | Static library archive files |
|
||||
| NACP | | [`patterns/nacp.hexpat`](patterns/nacp.hexpat) | Nintendo Switch NACP files |
|
||||
| NRO | | [`patterns/nro.hexpat`](patterns/nro.hexpat) | Nintendo Switch NRO files |
|
||||
| PRODINFO | | [`patterns/prodinfo.hexpat`](patterns/prodinfo.hexpat) | Nintendo Switch PRODINFO |
|
||||
| Java Class | `application/x-java-applet` | [`patterns/java_class.hexpat`](patterns/java_class.hexpat) | Java Class files |
|
||||
| ARM VTOR | | [`patterns/arm_cm_vtor.hexpat`](patterns/arm_cm_vtor.hexpat) | ARM Cortex M Vector Table Layout |
|
||||
| ICO | | [`patterns/ico.hexpat`](patterns/ico.hexpat) | Icon (.ico) or Cursor (.cur) files |
|
||||
| PNG | `image/png` | [`patterns/png.hexpat`](patterns/png.hexpat) | PNG image files |
|
||||
| QOI | `image/qoi` | [`patterns/qoi.hexpat`](patterns/qoi.hexpat) | QOI 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/id3.hexpat`](patterns/id3.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) |
|
||||
| DMG | | [`patterns/dmg.hexpat`](patterns/dmg.hexpat) | Apple Disk Image Trailer (DMG) |
|
||||
| XBEH | `audio/x-xbox-executable` | [`patterns/xbeh.hexpat`](patterns/xbeh.hexpat) | Xbox executable |
|
||||
| QBCL | | [`patterns/qbcl.hexpat`](patterns/qbcl.hexpat) | Qubicle voxel scene project file |
|
||||
| CCHVA | | [`patterns/cchva.hexpat`](patterns/cchva.hexpat) | Command and Conquer Voxel Animation |
|
||||
| CCVXL | | [`patterns/ccvxl.hexpat`](patterns/ccvxl.hexpat) | Command and Conquer Voxel Model |
|
||||
| CCPAL | | [`patterns/ccpal.hexpat`](patterns/ccpal.hexpat) | Command and Conquer Voxel Palette |
|
||||
| PIF | `image/pif` | [`patterns/pif.hexpat`](patterns/pif.hexpat) | PIF Image Format |
|
||||
| JPEG | `image/jpeg` | [`patterns/jpeg.hexpat`](patterns/jpeg.hexpat) | JPEG Image Format |
|
||||
| Lua 5.4 | | [`patterns/lua54.hexpat`](patterns/lua54.hexpat) | Lua 5.4 bytecode |
|
||||
| DEX | | [`patterns/dex.hexpat`](patterns/dex.hexpat) | Dalvik EXecutable Format |
|
||||
| DS_Store | `application/octet-stream` | [`patterns/dsstore.hexpat`](patterns/dsstore.hexpat) | .DS_Store file format |
|
||||
| UEFI | | [`patterns/uefi.hexpat`](patterns/uefi.hexpat)` | UEFI structs for parsing efivars |
|
||||
| EVTX | | [`patterns/evtx.hexpat`](patterns/evtx.hexpat) | MS Windows Vista Event Log |
|
||||
| BSP | | [`patterns/bsp_goldsrc.hexpat`](patterns/bsp_goldsrc.hexpat) | GoldSrc engine maps format (used in Half-Life 1) |
|
||||
|
||||
### Scripts
|
||||
|
||||
| Name | Path | Description |
|
||||
|------|------|-------------|
|
||||
| svd2pat | `scripts/svd2pat.py` | Converts a ARM .svd register MMIO definition file into a pattern |
|
||||
| csv2tbl | `scripts/csv2tbl.py` | Converts a 010 editor CSV encoding file into a table file |
|
||||
| svd2pat | [`scripts/svd2pat.py`](scripts/svd2pat.py) | Converts a ARM .svd register MMIO definition file into a pattern |
|
||||
| csv2tbl | [`scripts/csv2tbl.py`](scripts/csv2tbl.py) | Converts a 010 editor CSV encoding file into a table file |
|
||||
|
||||
### Pattern Libraries
|
||||
|
||||
| Name | Path | Description |
|
||||
|------|------|-------------|
|
||||
| libstd | `includes/std/*` | Pattern Language Standard Libaray |
|
||||
| libtype | `includes/type/*` | Various custom types with special formatters |
|
||||
| libhex | `includes/hex/*` | Functions to interact with ImHex |
|
||||
| libstd | [`includes/std/*`](includes/std) | Pattern Language Standard Libaray |
|
||||
| libtype | [`includes/type/*`](includes/type) | Various custom types with special formatters |
|
||||
| libhex | [`includes/hex/*`](includes/hex) | Functions to interact with ImHex |
|
||||
|
||||
### Yara rules
|
||||
|
||||
| Name | Path | Description |
|
||||
|------|------|-------------|
|
||||
| Official Rules | `yara/official_rules/*` | Official Yara rules repository |
|
||||
| Official Rules | [`yara/official_rules/*`](yara/official_rules) | Official Yara rules repository |
|
||||
|
||||
### Magic files
|
||||
|
||||
| Name | Path | Description |
|
||||
|------|------|-------------|
|
||||
| Nintendo Switch | `magic/nintendo_switch_magic` | Identifies common file types used on the Nintendo Switch |
|
||||
| Portable Executable | `magic/portable_executable_magic` | Identifies PE files used on Windows
|
||||
| Nintendo Switch | [`magic/nintendo_switch_magic`](magic/nintendo_switch_magic) | Identifies common file types used on the Nintendo Switch |
|
||||
| Portable Executable | [`magic/portable_executable_magic`](magic/portable_executable_magic) | Identifies PE files used on Windows
|
||||
|
||||
### Constants files
|
||||
|
||||
| Name | Path | Description |
|
||||
|------|------|-------------|
|
||||
| CRC-16 | `constants/crc16.json` | Constants associated with CRC-16 operations |
|
||||
| CRC-32 | `constants/crc32.json` | Constants associated with CRC-32 operations |
|
||||
| HTTP-Codes | `constants/http_status.json` | HTTP Status code values |
|
||||
| Linux Error Codes | `constants/linux_errors.json` | Values of Linux error results |
|
||||
| CRC-16 | [`constants/crc16.json`](constants/crc16.json) | Constants associated with CRC-16 operations |
|
||||
| CRC-32 | [`constants/crc32.json`](constants/crc32.json) | Constants associated with CRC-32 operations |
|
||||
| HTTP-Codes | [`constants/http_status.json`](constants/http_status.json) | HTTP Status code values |
|
||||
| Linux Error Codes | [`constants/linux_errors.json`](constants/linux_errors.json) | Values of Linux error results |
|
||||
|
||||
### Encoding files
|
||||
|
||||
| Name | Path | Description |
|
||||
|------|------|-------------|
|
||||
| Arabic ISO | `encodings/arabic_iso.tbl` | Arabic ISO encoding |
|
||||
| Arabic Windows | `encodings/arabic_windows.tbl` | Arabic Windows encoding |
|
||||
| ASCII | `encodings/ascii.tbl` | Regular ASCII encoding |
|
||||
| ASCII+ANSI | `encodings/ascii_ansi.tbl` | Extended ASCII encoding |
|
||||
| ASCII+OEM | `encodings/ascii_oem.tbl` | ASCII encoding with Windows OEM characters |
|
||||
| Baltic ISO | `encodings/baltic_iso.tbl` | Baltic ISO encoding |
|
||||
| Baltic Windows | `encodings/baltic_windows.tbl` | Baltic Windows encoding |
|
||||
| Cyrillic ISO | `encodings/cyrillic_iso.tbl` | Cyrillic ISO encoding |
|
||||
| Cyrillic Windows | `encodings/cyrillic_windows.tbl` | Cyrillic Windows encoding |
|
||||
| Cyrillic KOI8-R | `encodings/cyrillic_koi8_r.tbl` | Cyrillic KOI8-R encoding (Russian Characters) |
|
||||
| Cyrillic KOI8-U | `encodings/cyrillic_koi8_u.tbl` | Cyrillic KOI8-U encoding (Ukranian Characters) |
|
||||
| Eastern Europe ISO | `encodings/eastern_europe_iso.tbl` | Eastern Europe ISO encoding |
|
||||
| Eastern Europe Windows | `encodings/eastern_europe_windows.tbl` | Eastern Europe Windows encoding |
|
||||
| EBCDIC | `encodings/ebcdic.tbl` | Extended Binary Coded Decimal Interchange Code, developed by IBM for their Main Frames |
|
||||
| EUC-JP | `encodings/euc_jp.tbl` | EUC-JP encoding with NEC special and IBM extended characters |
|
||||
| EUC-KR | `encodings/euc_kr.tbl` | EUC-KR encoding |
|
||||
| Greek ISO | `encodings/greek_iso.tbl` | Greek ISO encoding |
|
||||
| Greek Windows | `encodings/greek_windows.tbl` | Greek Windows encoding |
|
||||
| Hebrew ISO | `encodings/hebrew_iso.tbl` | Hebrew ISO encoding |
|
||||
| Hebrew Windows | `encodings/hebrew_windows.tbl` | Hebrew Windows encoding |
|
||||
| ISO/IEC 646 | `encodings/iso_646.tbl` | ISO/IEC 646 encoding, an older version of ASCII |
|
||||
| ISO/IEC 6937 | `encodings/iso_6937.tbl` | ISO/IEC 6937 encoding, an extension of ASCII containing additional character |
|
||||
| JIS 0201 | `encodings/jis_x_0201.tbl` | JIS X 0201 encoding in UTF-8 |
|
||||
| JIS X 0211 | `encodings/jis_x_0211.tbl` | JIS X 0211 encoding in UTF-8 |
|
||||
| JIS 0213 | `encodings/jis_x_0213.tbl` | JIS X 0213 encoding in UTF-8 |
|
||||
| Macintosh | `encodings/macintosh.tbl` | Macintosh character encoding used by the Kermit protocol |
|
||||
| Pokémon (English, Generation 1) | `encodings/pokegen1_en.tbl` | Character encoding used by the English generation 1 Pokémon games |
|
||||
| Shift-JIS UTF-8 | `encodings/shiftjis.tbl` | Shift-JIS encoding in UTF-8 |
|
||||
| Thai | `encodings/thai.tbl` | Thai character encoding |
|
||||
| Turkish ISO | `encodings/turkish_iso.tbl` | Turkish ISO encoding |
|
||||
| Turkish Windows | `encodings/turkish_windows.tbl` | Turkish Windows encoding |
|
||||
| UTF-8 | `encodings/utf8.tbl` | UTF-8 encoding |
|
||||
| Vietnamese | `encodings/vietnamese.tbl` | Vietnamese character encoding |
|
||||
| Arabic ISO | [`encodings/arabic_iso.tbl`](encodings/arabic_iso.tbl) | Arabic ISO encoding |
|
||||
| Arabic Windows | [`encodings/arabic_windows.tbl`](encodings/arabic_windows.tbl) | Arabic Windows encoding |
|
||||
| ASCII | [`encodings/ascii.tbl`](encodings/ascii.tbl) | Regular ASCII encoding |
|
||||
| ASCII+ANSI | [`encodings/ascii_ansi.tbl`](encodings/ascii_ansi.tbl) | Extended ASCII encoding |
|
||||
| ASCII+OEM | [`encodings/ascii_oem.tbl`](encodings/ascii_oem.tbl) | ASCII encoding with Windows OEM characters |
|
||||
| Baltic ISO | [`encodings/baltic_iso.tbl`](encodings/baltic_iso.tbl) | Baltic ISO encoding |
|
||||
| Baltic Windows | [`encodings/baltic_windows.tbl`](encodings/baltic_windows.tbl) | Baltic Windows encoding |
|
||||
| Cyrillic ISO | [`encodings/cyrillic_iso.tbl`](encodings/cyrillic_iso.tbl) | Cyrillic ISO encoding |
|
||||
| Cyrillic Windows | [`encodings/cyrillic_windows.tbl`](encodings/cyrillic_windows.tbl) | Cyrillic Windows encoding |
|
||||
| Cyrillic KOI8-R | [`encodings/cyrillic_koi8_r.tbl`](encodings/cyrillic_koi8_r.tbl) | Cyrillic KOI8-R encoding (Russian Characters) |
|
||||
| Cyrillic KOI8-U | [`encodings/cyrillic_koi8_u.tbl`](encodings/cyrillic_koi8_u.tbl) | Cyrillic KOI8-U encoding (Ukranian Characters) |
|
||||
| Eastern Europe ISO | [`encodings/eastern_europe_iso.tbl`](encodings/eastern_europe_iso.tbl) | Eastern Europe ISO encoding |
|
||||
| Eastern Europe Windows | [`encodings/eastern_europe_windows.tbl`](encodings/eastern_europe_windows.tbl) | Eastern Europe Windows encoding |
|
||||
| EBCDIC | [`encodings/ebcdic.tbl`](encodings/ebcdic.tbl) | Extended Binary Coded Decimal Interchange Code, developed by IBM for their Main Frames |
|
||||
| EUC-JP | [`encodings/euc_jp.tbl`](encodings/euc_jp.tbl) | EUC-JP encoding with NEC special and IBM extended characters |
|
||||
| EUC-KR | [`encodings/euc_kr.tbl`](encodings/euc_kr.tbl) | EUC-KR encoding |
|
||||
| Greek ISO | [`encodings/greek_iso.tbl`](encodings/greek_iso.tbl) | Greek ISO encoding |
|
||||
| Greek Windows | [`encodings/greek_windows.tbl`](encodings/greek_windows.tbl) | Greek Windows encoding |
|
||||
| Hebrew ISO | [`encodings/hebrew_iso.tbl`](encodings/hebrew_iso.tbl) | Hebrew ISO encoding |
|
||||
| Hebrew Windows | [`encodings/hebrew_windows.tbl`](encodings/hebrew_windows.tbl) | Hebrew Windows encoding |
|
||||
| ISO/IEC 646 | [`encodings/iso_646.tbl`](encodings/iso_646.tbl) | ISO/IEC 646 encoding, an older version of ASCII |
|
||||
| ISO/IEC 6937 | [`encodings/iso_6937.tbl`](encodings/iso_6937.tbl) | ISO/IEC 6937 encoding, an extension of ASCII containing additional character |
|
||||
| JIS 0201 | [`encodings/jis_x_0201.tbl`](encodings/jis_x_0201.tbl) | JIS X 0201 encoding in UTF-8 |
|
||||
| JIS X 0211 | [`encodings/jis_x_0211.tbl`](encodings/jis_x_0211.tbl) | JIS X 0211 encoding in UTF-8 |
|
||||
| JIS 0213 | [`encodings/jis_x_0213.tbl`](encodings/jis_x_0213.tbl) | JIS X 0213 encoding in UTF-8 |
|
||||
| Macintosh | [`encodings/macintosh.tbl`](encodings/macintosh.tbl) | Macintosh character encoding used by the Kermit protocol |
|
||||
| Pokémon (English, Generation 1) | [`encodings/pokegen1_en.tbl`](encodings/pokegen1_en.tbl) | Character encoding used by the English generation 1 Pokémon games |
|
||||
| Pokémon (English, Generation 3) | [`encodings/pokegen3_en.tbl`](encodings/pokegen3_en.tbl) | Character encoding used by the English generation 3 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
|
||||
### Data Processor Nodes
|
||||
| Name | Path | Description |
|
||||
|------|------|-------------|
|
||||
| Caesar Cipher | [`nodes/caesar.hexnode`](nodes/caesar.hexnode) | Simple adjustable per-byte Caecar Cipher (ROT) |
|
||||
| XOR Cipher | [`nodes/xor.hexnode`](nodes/xor.hexnode) | XORs a input with a repeating XOR pad |
|
||||
|
||||
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 :)
|
||||
### Themes
|
||||
| Name | Path | Description |
|
||||
|------|------|-------------|
|
||||
| Visual Studio Dark | [`themes/vs_dark.json`](themes/vs_dark.json) | Theme similar to Visual Studio's Dark theme |
|
||||
| Solarized Dark | [`themes/solarized_dark.json`](themes/solarized_dark.json) | Solarized Dark Theme |
|
||||
|
||||
7120
encodings/ms932.tbl
Normal file
7120
encodings/ms932.tbl
Normal file
File diff suppressed because it is too large
Load Diff
256
encodings/pokegen3_en.tbl
Normal file
256
encodings/pokegen3_en.tbl
Normal file
@@ -0,0 +1,256 @@
|
||||
00
|
||||
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
|
||||
31
|
||||
32
|
||||
33
|
||||
34
|
||||
35==
|
||||
36
|
||||
37
|
||||
38
|
||||
39
|
||||
3a
|
||||
3b
|
||||
3c
|
||||
3d
|
||||
3e
|
||||
3f
|
||||
40
|
||||
41
|
||||
42
|
||||
43
|
||||
44
|
||||
45
|
||||
46
|
||||
47
|
||||
48
|
||||
49
|
||||
4a
|
||||
4b
|
||||
4c
|
||||
4d
|
||||
4e
|
||||
4f
|
||||
50
|
||||
51=¿
|
||||
52=¡
|
||||
53=Pk
|
||||
54=Mn
|
||||
55=Po
|
||||
56=Ké
|
||||
57
|
||||
58
|
||||
59
|
||||
5a=Í
|
||||
5b=%
|
||||
5c=(
|
||||
5d=)
|
||||
5e
|
||||
5f
|
||||
60
|
||||
61
|
||||
62
|
||||
63
|
||||
64
|
||||
65
|
||||
66
|
||||
67
|
||||
68=â
|
||||
69
|
||||
6a
|
||||
6b
|
||||
6c
|
||||
6d
|
||||
6e
|
||||
6f=í
|
||||
70
|
||||
71
|
||||
72
|
||||
73
|
||||
74
|
||||
75
|
||||
76
|
||||
77
|
||||
78
|
||||
79=⬆
|
||||
7a=⬇
|
||||
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=0
|
||||
a2=1
|
||||
a3=2
|
||||
a4=3
|
||||
a5=4
|
||||
a6=5
|
||||
a7=6
|
||||
a8=7
|
||||
a9=8
|
||||
aa=9
|
||||
ab=!
|
||||
ac=?
|
||||
ad=.
|
||||
ae=-
|
||||
af=・
|
||||
b0
|
||||
b1=“
|
||||
b2=”
|
||||
b3=‘
|
||||
b4=’
|
||||
b5=♂
|
||||
b6=♀
|
||||
b7
|
||||
b8=,
|
||||
b9=×
|
||||
ba=/
|
||||
bb=A
|
||||
bc=B
|
||||
bd=C
|
||||
be=D
|
||||
bf=E
|
||||
c0=F
|
||||
c1=G
|
||||
c2=H
|
||||
c3=I
|
||||
c4=J
|
||||
c5=K
|
||||
c6=L
|
||||
c7=M
|
||||
c8=N
|
||||
c9=O
|
||||
ca=P
|
||||
cb=Q
|
||||
cc=R
|
||||
cd=S
|
||||
ce=T
|
||||
cf=U
|
||||
d0=V
|
||||
d1=W
|
||||
d2=X
|
||||
d3=Y
|
||||
d4=Z
|
||||
d5=a
|
||||
d6=b
|
||||
d7=c
|
||||
d8=d
|
||||
d9=e
|
||||
da=f
|
||||
db=g
|
||||
dc=h
|
||||
dd=i
|
||||
de=j
|
||||
df=k
|
||||
e0=l
|
||||
e1=m
|
||||
e2=n
|
||||
e3=o
|
||||
e4=p
|
||||
e5=q
|
||||
e6=r
|
||||
e7=s
|
||||
e8=t
|
||||
e9=u
|
||||
ea=v
|
||||
eb=w
|
||||
ec=x
|
||||
ed=y
|
||||
ee=z
|
||||
ef=▶
|
||||
f0=:
|
||||
f1=Ä
|
||||
f2=Ö
|
||||
f3=Ü
|
||||
f4=ä
|
||||
f5=ö
|
||||
f6=ü
|
||||
f7
|
||||
f8
|
||||
f9
|
||||
fa
|
||||
fb
|
||||
fc
|
||||
fd
|
||||
fe
|
||||
ff
|
||||
@@ -1,10 +1,3 @@
|
||||
00=
|
||||
08=\b
|
||||
09=\t
|
||||
0A=\n
|
||||
0B=\v
|
||||
0C=\f
|
||||
0D=\r
|
||||
20=
|
||||
21=!
|
||||
22="
|
||||
@@ -128,12 +121,12 @@
|
||||
8159=〆
|
||||
815A=〇
|
||||
815B=ー
|
||||
815C=―
|
||||
815C=—
|
||||
815D=‐
|
||||
815E=/
|
||||
815F=\
|
||||
8160=~
|
||||
8161=∥
|
||||
8160=〜
|
||||
8161=‖
|
||||
8162=|
|
||||
8163=…
|
||||
8164=‥
|
||||
@@ -160,7 +153,7 @@
|
||||
8179=【
|
||||
817A=】
|
||||
817B=+
|
||||
817C=-
|
||||
817C=−
|
||||
817D=±
|
||||
817E=×
|
||||
8180=÷
|
||||
@@ -180,8 +173,8 @@
|
||||
818E=℃
|
||||
818F=¥
|
||||
8190=$
|
||||
8191=¢
|
||||
8192=£
|
||||
8191=¢
|
||||
8192=£
|
||||
8193=%
|
||||
8194=#
|
||||
8195=&
|
||||
@@ -194,6 +187,7 @@
|
||||
819C=●
|
||||
819D=◎
|
||||
819E=◇
|
||||
819F=◆
|
||||
81A0=□
|
||||
81A1=■
|
||||
81A2=△
|
||||
@@ -217,7 +211,7 @@
|
||||
81BF=∩
|
||||
81C8=∧
|
||||
81C9=∨
|
||||
81CA=¬
|
||||
81CA=¬
|
||||
81CB=⇒
|
||||
81CC=⇔
|
||||
81CD=∀
|
||||
@@ -623,89 +617,6 @@
|
||||
84BC=┥
|
||||
84BD=┸
|
||||
84BE=╂
|
||||
8740=①
|
||||
8741=②
|
||||
8742=③
|
||||
8743=④
|
||||
8744=⑤
|
||||
8745=⑥
|
||||
8746=⑦
|
||||
8747=⑧
|
||||
8748=⑨
|
||||
8749=⑩
|
||||
874A=⑪
|
||||
874B=⑫
|
||||
874C=⑬
|
||||
874D=⑭
|
||||
874E=⑮
|
||||
874F=⑯
|
||||
8750=⑰
|
||||
8751=⑱
|
||||
8752=⑲
|
||||
8753=⑳
|
||||
8754=Ⅰ
|
||||
8755=Ⅱ
|
||||
8756=Ⅲ
|
||||
8757=Ⅳ
|
||||
8758=Ⅴ
|
||||
8759=Ⅵ
|
||||
875A=Ⅶ
|
||||
875B=Ⅷ
|
||||
875C=Ⅸ
|
||||
875D=Ⅹ
|
||||
875F=㍉
|
||||
8760=㌔
|
||||
8761=㌢
|
||||
8762=㍍
|
||||
8763=㌘
|
||||
8764=㌧
|
||||
8765=㌃
|
||||
8766=㌶
|
||||
8767=㍑
|
||||
8768=㍗
|
||||
8769=㌍
|
||||
876A=㌦
|
||||
876B=㌣
|
||||
876C=㌫
|
||||
876D=㍊
|
||||
876E=㌻
|
||||
876F=㎜
|
||||
8770=㎝
|
||||
8771=㎞
|
||||
8772=㎎
|
||||
8773=㎏
|
||||
8774=㏄
|
||||
8775=㎡
|
||||
877E=㍻
|
||||
8780=〝
|
||||
8781=〟
|
||||
8782=№
|
||||
8783=㏍
|
||||
8784=℡
|
||||
8785=㊤
|
||||
8786=㊥
|
||||
8787=㊦
|
||||
8788=㊧
|
||||
8789=㊨
|
||||
878A=㈱
|
||||
878B=㈲
|
||||
878C=㈹
|
||||
878D=㍾
|
||||
878E=㍽
|
||||
878F=㍼
|
||||
8790=≒
|
||||
8791=≡
|
||||
8792=∫
|
||||
8793=∮
|
||||
8794=∑
|
||||
8795=√
|
||||
8796=⊥
|
||||
8797=∠
|
||||
8798=∟
|
||||
8799=⊿
|
||||
879A=∵
|
||||
879B=∩
|
||||
879C=∪
|
||||
889F=亜
|
||||
88A0=唖
|
||||
88A1=娃
|
||||
@@ -7124,4 +7035,3 @@ EAA1=遙
|
||||
EAA2=瑤
|
||||
EAA3=凜
|
||||
EAA4=熙
|
||||
FA5B=∵
|
||||
|
||||
1257568
encodings/utf8.tbl
1257568
encodings/utf8.tbl
File diff suppressed because it is too large
Load Diff
@@ -2,13 +2,24 @@
|
||||
|
||||
#include <hex/impl/imhex_check.pat>
|
||||
|
||||
/*!
|
||||
Core intrinsic functions to interact with the ImHex Hex Editor
|
||||
*/
|
||||
|
||||
namespace hex::core {
|
||||
|
||||
/**
|
||||
A type representing a selection in the hex editor
|
||||
*/
|
||||
struct Selection {
|
||||
bool valid;
|
||||
u64 address, size;
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the current selection in the hex editor
|
||||
@return The current selection
|
||||
*/
|
||||
fn get_selection() {
|
||||
u128 result = builtin::hex::core::get_selection();
|
||||
|
||||
|
||||
20
includes/hex/dec.pat
Normal file
20
includes/hex/dec.pat
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/impl/imhex_check.pat>
|
||||
|
||||
/*!
|
||||
Library to allow decoding of more complex values
|
||||
*/
|
||||
|
||||
namespace hex::dec {
|
||||
|
||||
/**
|
||||
Demangles a mangled name into a human readable name
|
||||
@param mangled_name The mangled name
|
||||
@return The demangled name
|
||||
*/
|
||||
fn demangle(str mangled_name) {
|
||||
return builtin::hex::dec::demangle(mangled_name);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -2,8 +2,17 @@
|
||||
|
||||
#include <hex/impl/imhex_check.pat>
|
||||
|
||||
/*!
|
||||
Library to do HTTP requests
|
||||
*/
|
||||
|
||||
namespace hex::http {
|
||||
|
||||
/**
|
||||
Performs a HTTP GET request to the given URL and returns the response body
|
||||
@param url URL to perform the request to
|
||||
@return Response body
|
||||
*/
|
||||
fn get(str url) {
|
||||
return builtin::hex::http::get(url);
|
||||
};
|
||||
|
||||
43
includes/hex/provider.pat
Normal file
43
includes/hex/provider.pat
Normal file
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/impl/imhex_check.pat>
|
||||
|
||||
/*!
|
||||
Library to interact with the currently loaded provider.
|
||||
*/
|
||||
|
||||
namespace hex::prv {
|
||||
|
||||
|
||||
/**
|
||||
Queries information from the currently loaded provider. The kind of information that's available depends on the provider that's loaded
|
||||
|
||||
> **Available information**
|
||||
> - File Provider
|
||||
> - `file_path() -> str`
|
||||
> - `file_name() -> str`
|
||||
> - `file_extension() -> str`
|
||||
> - `creation_time() -> time_t`
|
||||
> - `access_time() -> time_t`
|
||||
> - `modification_time() -> time_t`
|
||||
> - `permissions() -> u16`
|
||||
> - Disk Provider
|
||||
> - `file_path() -> str`
|
||||
> - `sector_size() -> u128`
|
||||
> - GDB Provider
|
||||
> - `ip() -> str`
|
||||
> - `port() -> u16`
|
||||
> - Process Memory Provider
|
||||
> - `region_address(regionName) -> u64`
|
||||
> - `region_size(regionName) -> u64`
|
||||
> - `process_id() -> u32`
|
||||
> - `process_name() -> str`
|
||||
|
||||
@param category Information category
|
||||
@param argument Extra argument to pass along
|
||||
*/
|
||||
fn get_information(str category, str argument = "") {
|
||||
return builtin::hex::prv::get_information(category, argument);
|
||||
};
|
||||
|
||||
}
|
||||
30
includes/hex/type/mangled.pat
Normal file
30
includes/hex/type/mangled.pat
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <std/io.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
#include <hex/impl/imhex_check.pat>
|
||||
#include <hex/dec.pat>
|
||||
|
||||
/*!
|
||||
Types to automatically decode mangled names
|
||||
*/
|
||||
|
||||
namespace hex::type {
|
||||
|
||||
/**
|
||||
A mangled name string that gets demangled when displayed
|
||||
*/
|
||||
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);
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
19
includes/std/array.pat
Normal file
19
includes/std/array.pat
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
The array library contains various helper functions and types to make
|
||||
it easier to work with Arrays.
|
||||
*/
|
||||
|
||||
namespace std {
|
||||
|
||||
/**
|
||||
Simple one dimensional array wrapper
|
||||
@tparam T The array types
|
||||
@tparam Size Size of the array
|
||||
*/
|
||||
struct Array<T, auto Size> {
|
||||
T data[Size] [[inline]];
|
||||
};
|
||||
|
||||
}
|
||||
@@ -2,8 +2,17 @@
|
||||
|
||||
#include <std/limits.pat>
|
||||
|
||||
/*!
|
||||
This library contains various helper functions for common bit operations.
|
||||
*/
|
||||
|
||||
namespace std::bit {
|
||||
|
||||
/**
|
||||
Calculates the number of 1 bits in a given number
|
||||
@param x The number
|
||||
@return The number of bits set to 1 in `x`
|
||||
*/
|
||||
fn popcount(u128 x) {
|
||||
x = (x & (std::limits::u128_max() / 3)) + ((x >> 1) & (std::limits::u128_max() / 3));
|
||||
x = (x & (std::limits::u128_max() / 5)) + ((x >> 2) & (std::limits::u128_max() / 5));
|
||||
@@ -12,10 +21,20 @@ namespace std::bit {
|
||||
return x % 0xFF;
|
||||
};
|
||||
|
||||
/**
|
||||
Checks if only a single bit is set to 1 in a given number
|
||||
@param x The number
|
||||
@return True if there's a single bit set to 1 in `x`, false otherwise
|
||||
*/
|
||||
fn has_single_bit(u128 x) {
|
||||
return x != 0 && (x & (x - 1)) == 0;
|
||||
};
|
||||
|
||||
/**
|
||||
Rounds the given number up to the next bigger power of two
|
||||
@param x The number
|
||||
@return Next bigger power of two that can fit `x`
|
||||
*/
|
||||
fn bit_ceil(u128 x) {
|
||||
if (x == 0) return 0;
|
||||
|
||||
@@ -25,7 +44,12 @@ namespace std::bit {
|
||||
|
||||
return 1 << i;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Rounds the given number down to the next bigger power of two
|
||||
@param x The number
|
||||
@return Next smaller power of two
|
||||
*/
|
||||
fn bit_floor(u128 x) {
|
||||
if (x == 0) return 0;
|
||||
|
||||
|
||||
@@ -2,56 +2,148 @@
|
||||
|
||||
#include <std/mem.pat>
|
||||
|
||||
/*!
|
||||
The core library contains intrinsics and "compiler magic" functions that
|
||||
get extra help from the runtime to fulfill their purpose.
|
||||
*/
|
||||
|
||||
namespace std::core {
|
||||
|
||||
/**
|
||||
The layout order of each field after byte-endianness has been handled.
|
||||
|
||||
`LeftToRight` and `RightToLeft` are deprecated in favor of the clearer `MostToLeastSignificant` and `LeastToMostSignificant` names.
|
||||
*/
|
||||
enum BitfieldOrder : u8 {
|
||||
/**
|
||||
@warning deprecated
|
||||
*/
|
||||
LeftToRight = 0,
|
||||
RightToLeft = 1
|
||||
/**
|
||||
@warning deprecated
|
||||
*/
|
||||
RightToLeft = 1,
|
||||
MostToLeastSignificant = 0,
|
||||
LeastToMostSignificant = 1
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Checks if a pattern has a specific attribute assigned to it
|
||||
@param pattern The pattern to check
|
||||
@param attribute The attribute's name to check for
|
||||
*/
|
||||
fn has_attribute(ref auto pattern, str attribute) {
|
||||
return builtin::std::core::has_attribute(pattern, attribute);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Returns the first parameter of the attribute of a pattern if it has one
|
||||
@param pattern The pattern to check
|
||||
@param attribute The attribute's name to query
|
||||
*/
|
||||
fn get_attribute_value(ref auto pattern, str attribute) {
|
||||
return builtin::std::core::get_attribute_value(pattern, attribute);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Sets the current default endianess.
|
||||
Any patterns created following this attribute will be created using the set endianess.
|
||||
@param endian The new default endianess
|
||||
*/
|
||||
fn set_endian(std::mem::Endian endian) {
|
||||
builtin::std::core::set_endian(u32(endian));
|
||||
};
|
||||
|
||||
/**
|
||||
Gets the current default endianess.
|
||||
@return The currently set default endianess
|
||||
*/
|
||||
fn get_endian() {
|
||||
return builtin::std::core::get_endian();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@warning Removed in 1.28.0
|
||||
*/
|
||||
fn set_bitfield_order(BitfieldOrder order) {
|
||||
builtin::std::core::set_bitfield_order(order);
|
||||
builtin::std::error("Runtime default bitfield order is no longer supported.\nConsider using `be` or `le` on your bitfield variables,\nor attach attribute `bitfield_order` to the bitfield.");
|
||||
};
|
||||
|
||||
/**
|
||||
@warning Removed in 1.28.0
|
||||
*/
|
||||
fn get_bitfield_order() {
|
||||
return builtin::std::core::get_bitfield_order();
|
||||
builtin::std::error("Runtime default bitfield order is no longer supported.\nConsider using `be` or `le` on your bitfield variables,\nor attach attribute `bitfield_order` to the bitfield.");
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
When used inside of a pattern that's being created using a pattern,
|
||||
returns the current array index that's being processed.
|
||||
If used outside of an array, always yields 0.
|
||||
@return The current array index
|
||||
*/
|
||||
fn array_index() {
|
||||
return builtin::std::core::array_index();
|
||||
};
|
||||
|
||||
/**
|
||||
Queries the number of members of a struct, union or bitfield or the number of entries in an array
|
||||
@param pattern The pattern to check
|
||||
@return The number of members in `pattern`
|
||||
*/
|
||||
fn member_count(ref auto pattern) {
|
||||
return builtin::std::core::member_count(pattern);
|
||||
};
|
||||
|
||||
/**
|
||||
Checks whether or not a given pattern has a member with a given name
|
||||
@param pattern The pattern to check
|
||||
@param name The name of the member to look for
|
||||
@return True if a member called `name` exists, false otherwise
|
||||
*/
|
||||
fn has_member(ref auto pattern, str name) {
|
||||
return builtin::std::core::has_member(pattern, name);
|
||||
};
|
||||
|
||||
/**
|
||||
Formats a pattern using it's default formatter or its custom formatter function set through
|
||||
the `[[format]]` or `[[format_read]]` attribute
|
||||
@param pattern The pattern to format
|
||||
@return Formatted string representation of `pattern`
|
||||
*/
|
||||
fn formatted_value(ref auto pattern) {
|
||||
return builtin::std::core::formatted_value(pattern);
|
||||
};
|
||||
|
||||
/**
|
||||
Checks if the given enum value corresponds has a corresponding constant
|
||||
@param pattern The enum value to check
|
||||
@return True if pattern has a valid enum representation, false if not
|
||||
*/
|
||||
fn is_valid_enum(ref auto pattern) {
|
||||
return builtin::std::core::is_valid_enum(pattern);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Changes the color of the given pattern to a new color
|
||||
@param pattern The pattern to modify
|
||||
@param color The RGBA8 color
|
||||
*/
|
||||
fn set_pattern_color(ref auto pattern, u32 color) {
|
||||
builtin::std::core::set_pattern_color(pattern, color);
|
||||
};
|
||||
|
||||
/**
|
||||
Changes the display name of a given pattern
|
||||
@param pattern The pattern to modify
|
||||
@param name The new display name of the pattern
|
||||
*/
|
||||
fn set_display_name(ref auto pattern, str name) {
|
||||
builtin::std::core::set_display_name(pattern, name);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,51 +1,116 @@
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
The ctype library has functions to check if a character is part of a specific category
|
||||
of ASCII characters.
|
||||
*/
|
||||
|
||||
namespace std::ctype {
|
||||
|
||||
/**
|
||||
Checks if the given character `c` is a digit between '0' and '9'
|
||||
@param c The character to check
|
||||
@return True if `c` is part of this range, false otherwise
|
||||
*/
|
||||
fn isdigit(char c) {
|
||||
return c >= '0' && c <= '9';
|
||||
};
|
||||
|
||||
/**
|
||||
Checks if the given character `c` is a hexadecimal digit between '0' and '9', `A` and `F` or `a` and `f`
|
||||
@param c The character to check
|
||||
@return True if `c` is part of this range, false otherwise
|
||||
*/
|
||||
fn isxdigit(char c) {
|
||||
return std::ctype::isdigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
|
||||
};
|
||||
|
||||
/**
|
||||
Checks if the given character `c` is a upper case letter between 'A' and 'Z'
|
||||
@param c The character to check
|
||||
@return True if `c` is part of this range, false otherwise
|
||||
*/
|
||||
fn isupper(char c) {
|
||||
return c >= 'A' && c <= 'Z';
|
||||
};
|
||||
|
||||
/**
|
||||
Checks if the given character `c` is a lower case letter between 'a' and 'z'
|
||||
@param c The character to check
|
||||
@return True if `c` is part of this range, false otherwise
|
||||
*/
|
||||
fn islower(char c) {
|
||||
return c >= 'a' && c <= 'z';
|
||||
};
|
||||
|
||||
/**
|
||||
Checks if the given character `c` is either a upper or lower case letter between 'A' and 'Z' or 'a' and 'z'
|
||||
@param c The character to check
|
||||
@return True if `c` is part of this range, false otherwise
|
||||
*/
|
||||
fn isalpha(char c) {
|
||||
return std::ctype::isupper(c) || std::ctype::islower(c);
|
||||
};
|
||||
|
||||
/**
|
||||
Checks if the given character `c` is a upper or lower case letter or a number
|
||||
@param c The character to check
|
||||
@return True if `c` is part of this range, false otherwise
|
||||
*/
|
||||
fn isalnum(char c) {
|
||||
return std::ctype::isalpha(c) || std::ctype::isdigit(c);
|
||||
};
|
||||
|
||||
/**
|
||||
Checks if the given character `c` is a space character
|
||||
@param c The character to check
|
||||
@return True if `c` is part of this range, false otherwise
|
||||
*/
|
||||
fn isspace(char c) {
|
||||
return (c >= 0x09 && c <= 0x0D) || c == 0x20;
|
||||
};
|
||||
|
||||
/**
|
||||
Checks if the given character `c` is a invisible character
|
||||
@param c The character to check
|
||||
@return True if `c` is part of this range, false otherwise
|
||||
*/
|
||||
fn isblank(char c) {
|
||||
return c == 0x09 || c == ' ';
|
||||
};
|
||||
|
||||
/**
|
||||
Checks if the given character `c` has a printable glyph
|
||||
@param c The character to check
|
||||
@return True if `c` is part of this range, false otherwise
|
||||
*/
|
||||
fn isprint(char c) {
|
||||
return c >= '0' && c <= '~';
|
||||
};
|
||||
|
||||
/**
|
||||
Checks if the given character `c` is a control code
|
||||
@param c The character to check
|
||||
@return True if `c` is part of this range, false otherwise
|
||||
*/
|
||||
fn iscntrl(char c) {
|
||||
return !std::ctype::isprint(c);
|
||||
};
|
||||
|
||||
/**
|
||||
Checks if the given character `c` has a visible glyph
|
||||
@param c The character to check
|
||||
@return True if `c` is part of this range, false otherwise
|
||||
*/
|
||||
fn isgraph(char c) {
|
||||
return std::ctype::isprint(c) && !std::ctype::isspace(c);
|
||||
};
|
||||
|
||||
/**
|
||||
Checks if the given character `c` is a punctuation character
|
||||
@param c The character to check
|
||||
@return True if `c` is part of this range, false otherwise
|
||||
*/
|
||||
fn ispunct(char c) {
|
||||
return std::ctype::isgraph(c) && !std::ctype::isalnum(c);
|
||||
};
|
||||
|
||||
@@ -1,9 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
The File library allows reading and writing from/to external files using
|
||||
a C-like File IO API.
|
||||
|
||||
**These functions are considered dangerous and require the user to manually permit them**
|
||||
*/
|
||||
|
||||
namespace std::file {
|
||||
|
||||
/**
|
||||
A handle representing a file that has been opened
|
||||
*/
|
||||
using Handle = s32;
|
||||
|
||||
/**
|
||||
The mode to open a file in.
|
||||
Read opens the file in read-only mode
|
||||
Write opens the file in read and write mode
|
||||
Create creates a new file if it doesn't exist and overwrites an existing file
|
||||
*/
|
||||
enum Mode : u8 {
|
||||
Read = 1,
|
||||
Write = 2,
|
||||
@@ -11,37 +27,84 @@ namespace std::file {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Opens a file
|
||||
@param path The path to the file to open
|
||||
@param mode File open mode
|
||||
@return Handle to the newly opened file
|
||||
*/
|
||||
fn open(str path, Mode mode) {
|
||||
return builtin::std::file::open(path, u32(mode));
|
||||
};
|
||||
|
||||
/**
|
||||
Closes a file handle that has been opened previously
|
||||
@param handle The handle to close
|
||||
*/
|
||||
fn close(Handle handle) {
|
||||
builtin::std::file::close(handle);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Reads the content of a file into a string
|
||||
@param handle The file handle to read from
|
||||
@param size Number of bytes to read
|
||||
@return String containing the read data
|
||||
*/
|
||||
fn read(Handle handle, u64 size) {
|
||||
return builtin::std::file::read(handle, size);
|
||||
};
|
||||
|
||||
/**
|
||||
Writes the content of a string into a file
|
||||
@param handle The file handle to write to
|
||||
@param data String to write to the file
|
||||
*/
|
||||
fn write(Handle handle, str data) {
|
||||
return builtin::std::file::write(handle, data);
|
||||
builtin::std::file::write(handle, data);
|
||||
};
|
||||
|
||||
/**
|
||||
Sets the current cursor position in the given file handle
|
||||
@param handle The file handle to set the cursor position in
|
||||
@param offset The offset to move the cursor to
|
||||
*/
|
||||
fn seek(Handle handle, u64 offset) {
|
||||
builtin::std::file::seek(handle, offset);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Queries the size of a file
|
||||
@param handle The handle of the file to get the size of
|
||||
@return The file's size
|
||||
*/
|
||||
fn size(Handle handle) {
|
||||
return builtin::std::file::size(handle);
|
||||
};
|
||||
|
||||
/**
|
||||
Resizes a file
|
||||
@param handle The handle of the file to resize
|
||||
*/
|
||||
fn resize(Handle handle, u64 size) {
|
||||
builtin::std::file::resize(handle, size);
|
||||
};
|
||||
|
||||
/**
|
||||
Flushes changes made to a file to disk
|
||||
@param handle The handle of the file to flush
|
||||
*/
|
||||
fn flush(Handle handle) {
|
||||
builtin::std::file::remove(handle);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Deletes a file from disk. This will also automatically close this file
|
||||
@param handle The handle of the file to delete
|
||||
*/
|
||||
fn remove(Handle handle) {
|
||||
builtin::std::file::remove(handle);
|
||||
};
|
||||
|
||||
@@ -1,33 +1,87 @@
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
Library for doing arithmetic with fixed point numbers and converting them from/to floating point numbers.
|
||||
*/
|
||||
|
||||
namespace std::fxpt {
|
||||
|
||||
/**
|
||||
A fixed point value
|
||||
*/
|
||||
using fixed = s128;
|
||||
|
||||
/**
|
||||
Converts a fixed point value into a floating point value
|
||||
@param fxt The fixed point value to convert
|
||||
@param precision The bits of precision the new value should have
|
||||
@return The floating point representation of fxt
|
||||
*/
|
||||
fn to_float(fixed fxt, u32 precision) {
|
||||
return double(fxt) / double((1 << precision));
|
||||
};
|
||||
|
||||
/**
|
||||
Converts a floating point value into a fixed point value
|
||||
@param flt The floating point value to convert
|
||||
@param precision The bits of precision the new value should have
|
||||
@return The fixed point representation of flt
|
||||
*/
|
||||
fn to_fixed(double flt, u32 precision) {
|
||||
return fixed((flt * (1 << precision)));
|
||||
};
|
||||
|
||||
/**
|
||||
Changes the number of bits used to represent the decimal part of the given fixed point number
|
||||
@param value The fixed point value to convert
|
||||
@param start_precision The current number of bits used
|
||||
@param end_precision The new number of bits used
|
||||
@return `value` as a new fixed point number with `end_precision` bits of precision
|
||||
*/
|
||||
fn change_precision(fixed value, u32 start_precision, u32 end_precision) {
|
||||
return std::fxpt::to_fixed(std::fxpt::to_float(value, start_precision), end_precision);
|
||||
};
|
||||
|
||||
/**
|
||||
Adds two fixed point numbers with a given precision together
|
||||
@param a First fixed point number
|
||||
@param b Second fixed point number
|
||||
@param precision The precision of `a` and `b`
|
||||
@return Result of the addition of `a` and `b`
|
||||
*/
|
||||
fn add(fixed a, fixed b, u32 precision) {
|
||||
return a + b;
|
||||
};
|
||||
|
||||
/**
|
||||
Subtracts two fixed point numbers with a given precision together
|
||||
@param a First fixed point number
|
||||
@param b Second fixed point number
|
||||
@param precision The precision of `a` and `b`
|
||||
@return Result of the subtraction of `a` and `b`
|
||||
*/
|
||||
fn subtract(fixed a, fixed b, u32 precision) {
|
||||
return a - b;
|
||||
};
|
||||
|
||||
/**
|
||||
Multiplies two fixed point numbers with a given precision together
|
||||
@param a First fixed point number
|
||||
@param b Second fixed point number
|
||||
@param precision The precision of `a` and `b`
|
||||
@return Result of the multiplication of `a` and `b`
|
||||
*/
|
||||
fn multiply(fixed a, fixed b, u32 precision) {
|
||||
return (a * b) / (1 << precision);
|
||||
};
|
||||
|
||||
/**
|
||||
Divides two fixed point numbers with a given precision together
|
||||
@param a First fixed point number
|
||||
@param b Second fixed point number
|
||||
@param precision The precision of `a` and `b`
|
||||
@return Result of the division of `a` and `b`
|
||||
*/
|
||||
fn divide(fixed a, fixed b, u32 precision) {
|
||||
return (a << precision) / b;
|
||||
};
|
||||
|
||||
@@ -1,29 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
The hash library contains various data hash functions
|
||||
*/
|
||||
|
||||
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);
|
||||
/**
|
||||
Calculates the CRC32 hash of the bytes inside of a given pattern
|
||||
@param pattern The pattern to calculate the crc32 hash of
|
||||
@param init The CRC32 init value
|
||||
@param poly The CRC32 polynomial
|
||||
@param xorout The CRC32 XOR-Out value
|
||||
@param reflect_in Whether or not the input bytes should be reflected
|
||||
@param reflect_out Whether or not the output should be reflected
|
||||
@return Calculated CRC32 hash
|
||||
*/
|
||||
fn crc32(ref auto pattern, u32 init, u32 poly, u32 xorout, bool reflect_in, bool reflect_out) {
|
||||
return builtin::std::hash::crc32(pattern, init, poly, xorout, reflect_in, reflect_out);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,20 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
The IO library allows formatting strings and outputting text to the console
|
||||
*/
|
||||
|
||||
namespace std {
|
||||
|
||||
/**
|
||||
Formats the given arguments using the format string and prints the result to the console
|
||||
This function uses the C++20 `std::format` or libfmt's `fmt::format` syntax.
|
||||
@param fmt Format string
|
||||
@param args Values to use in the formatting
|
||||
*/
|
||||
fn print(str fmt, auto ... args) {
|
||||
builtin::std::print(fmt, args);
|
||||
};
|
||||
|
||||
/**
|
||||
Formats the given arguments using the format string and returns the result as a string
|
||||
This function uses the C++20 `std::format` or libfmt's `fmt::format` syntax.
|
||||
@param fmt Format string
|
||||
@param args Values to use in the formatting
|
||||
@return The formatted string
|
||||
*/
|
||||
fn format(str fmt, auto ... args) {
|
||||
return builtin::std::format(fmt, args);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Aborts evaluation of the code immediately and prints a error message to the console
|
||||
@param message The message to print
|
||||
*/
|
||||
fn error(str message) {
|
||||
builtin::std::error(message);
|
||||
};
|
||||
|
||||
/**
|
||||
Prints a warning message to the console
|
||||
@param message The message to print
|
||||
*/
|
||||
fn warning(str message) {
|
||||
builtin::std::warning(message);
|
||||
};
|
||||
|
||||
@@ -1,85 +1,169 @@
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
Library to calculate the minimum and maximum values that fit into a given data type
|
||||
*/
|
||||
|
||||
namespace std::limits {
|
||||
|
||||
/**
|
||||
Returns the minimum value that can be stored in a `u8`.
|
||||
@return Minimum value
|
||||
*/
|
||||
fn u8_min() {
|
||||
return u8(0);
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the maximum value that can be stored in a `u8`.
|
||||
@return Maximum value
|
||||
*/
|
||||
fn u8_max() {
|
||||
return u8(-1);
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the minimum value that can be stored in a `s8`.
|
||||
@return Minimum value
|
||||
*/
|
||||
fn s8_min() {
|
||||
return -s8((std::limits::u8_max() / 2)) - 1;
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the maximum value that can be stored in a `s8`.
|
||||
@return Maximum value
|
||||
*/
|
||||
fn s8_max() {
|
||||
return s8((u8_max() / 2));
|
||||
return s8((std::limits::u8_max() / 2));
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the minimum value that can be stored in a `u16`.
|
||||
@return Minimum value
|
||||
*/
|
||||
fn u16_min() {
|
||||
return u16(0);
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the maximum value that can be stored in a `u16`.
|
||||
@return Maximum value
|
||||
*/
|
||||
fn u16_max() {
|
||||
return u16(-1);
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the minimum value that can be stored in a `s16`.
|
||||
@return Minimum value
|
||||
*/
|
||||
fn s16_min() {
|
||||
return -s16((std::limits::u16_max() / 2)) - 1;
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the maximum value that can be stored in a `s16`.
|
||||
@return Maximum value
|
||||
*/
|
||||
fn s16_max() {
|
||||
return s16((u16_max() / 2));
|
||||
return s16((std::limits::u16_max() / 2));
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the minimum value that can be stored in a `u32`.
|
||||
@return Minimum value
|
||||
*/
|
||||
fn u32_min() {
|
||||
return u32(0);
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the maximum value that can be stored in a `u32`.
|
||||
@return Maximum value
|
||||
*/
|
||||
fn u32_max() {
|
||||
return u32(-1);
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the minimum value that can be stored in a `s32`.
|
||||
@return Minimum value
|
||||
*/
|
||||
fn s32_min() {
|
||||
return -s32((std::limits::u32_max() / 2)) - 1;
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the maximum value that can be stored in a `s32`.
|
||||
@return Maximum value
|
||||
*/
|
||||
fn s32_max() {
|
||||
return s32((u32_max() / 2));
|
||||
return s32((std::limits::u32_max() / 2));
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the minimum value that can be stored in a `u64`.
|
||||
@return Minimum value
|
||||
*/
|
||||
fn u64_min() {
|
||||
return u64(0);
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the maximum value that can be stored in a `u64`.
|
||||
@return Maximum value
|
||||
*/
|
||||
fn u64_max() {
|
||||
return u64(-1);
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the minimum value that can be stored in a `s64`.
|
||||
@return Minimum value
|
||||
*/
|
||||
fn s64_min() {
|
||||
return -s64((std::limits::u64_max() / 2)) - 1;
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the maximum value that can be stored in a `s64`.
|
||||
@return Maximum value
|
||||
*/
|
||||
fn s64_max() {
|
||||
return s64((u64_max() / 2));
|
||||
return s64((std::limits::u64_max() / 2));
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the minimum value that can be stored in a `u128`.
|
||||
@return Minimum value
|
||||
*/
|
||||
fn u128_min() {
|
||||
return u128(0);
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the maximum value that can be stored in a `u128`.
|
||||
@return Maximum value
|
||||
*/
|
||||
fn u128_max() {
|
||||
return u128(-1);
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the minimum value that can be stored in a `s128`.
|
||||
@return Minimum value
|
||||
*/
|
||||
fn s128_min() {
|
||||
return -s128((std::limits::u128_max() / 2)) - 1;
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the maximum value that can be stored in a `s128`.
|
||||
@return Maximum value
|
||||
*/
|
||||
fn s128_max() {
|
||||
return s128((u128_max() / 2));
|
||||
return s128((std::limits::u128_max() / 2));
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <std/mem.pat>
|
||||
|
||||
/*!
|
||||
Library containing more advanced mathematical operations.
|
||||
*/
|
||||
|
||||
namespace std::math {
|
||||
|
||||
/**
|
||||
Compares the values `a` and `b` with each other and returns the smaller of the two
|
||||
@param a First value
|
||||
@param b Second value
|
||||
@return `a` if `a` is smaller than `b`, otherwise `b`
|
||||
*/
|
||||
fn min(auto a, auto b) {
|
||||
if (a < b)
|
||||
return a;
|
||||
@@ -9,6 +21,12 @@ namespace std::math {
|
||||
return b;
|
||||
};
|
||||
|
||||
/**
|
||||
Compares the values `a` and `b` with each other and returns the bigger of the two
|
||||
@param a First value
|
||||
@param b Second value
|
||||
@return `a` if `a` is bigger than `b`, otherwise `b`
|
||||
*/
|
||||
fn max(auto a, auto b) {
|
||||
if (a > b)
|
||||
return a;
|
||||
@@ -16,6 +34,13 @@ namespace std::math {
|
||||
return b;
|
||||
};
|
||||
|
||||
/**
|
||||
Clamps the value of `x` between `min` and `max`.
|
||||
@param x Value
|
||||
@param min Minimum value
|
||||
@param max Maximum value
|
||||
@return `min` if `x` is smaller than `min`, `max` if `x` is bigger than `max`, `x` otherwise
|
||||
*/
|
||||
fn clamp(auto x, auto min, auto max) {
|
||||
if (x < min)
|
||||
return min;
|
||||
@@ -25,6 +50,11 @@ namespace std::math {
|
||||
return x;
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the absolute value of `x`.
|
||||
@param x Value
|
||||
@return `x` if `x` is positive, `-x` otherwise
|
||||
*/
|
||||
fn abs(auto x) {
|
||||
if (x < 0)
|
||||
return -x;
|
||||
@@ -32,6 +62,11 @@ namespace std::math {
|
||||
return x;
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the sign of `x`.
|
||||
@param x Value
|
||||
@return `1` if `x` is positive, `-1` if `x` is negative, `0` if `x` is zero
|
||||
*/
|
||||
fn sign(auto x) {
|
||||
if (x > 0)
|
||||
return 1;
|
||||
@@ -41,6 +76,12 @@ namespace std::math {
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
Copies the sign of `y` to `x`.
|
||||
@param x Value
|
||||
@param y Value
|
||||
@return `x` if `y` is positive, `-x` if `y` is negative
|
||||
*/
|
||||
fn copy_sign(auto x, auto y) {
|
||||
if (y >= 0)
|
||||
return std::math::abs(x);
|
||||
@@ -48,6 +89,11 @@ namespace std::math {
|
||||
return -std::math::abs(x);
|
||||
};
|
||||
|
||||
/**
|
||||
Calculates the factorial of `x`.
|
||||
@param x Value
|
||||
@return Factorial of `x`
|
||||
*/
|
||||
fn factorial(u128 x) {
|
||||
u128 result;
|
||||
|
||||
@@ -60,6 +106,12 @@ namespace std::math {
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
Calculates the binomial coefficient of `n` and `k`.
|
||||
@param n Value
|
||||
@param k Value
|
||||
@return Binomial coefficient of `n` and `k`
|
||||
*/
|
||||
fn comb(u128 n, u128 k) {
|
||||
if (k > n)
|
||||
return 0;
|
||||
@@ -67,6 +119,12 @@ namespace std::math {
|
||||
return std::math::factorial(n) / (std::math::factorial(k) * std::math::factorial(n - k));
|
||||
};
|
||||
|
||||
/**
|
||||
Calculates the permutation of `n` and `k`.
|
||||
@param n Value
|
||||
@param k Value
|
||||
@return Permutation of `n` and `k`
|
||||
*/
|
||||
fn perm(u128 n, u128 k) {
|
||||
if (k > n)
|
||||
return 0;
|
||||
@@ -74,36 +132,202 @@ namespace std::math {
|
||||
return std::math::factorial(n) / std::math::factorial(n - k);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Floors the value of `value`.
|
||||
@param value Value
|
||||
@return `value` floored
|
||||
*/
|
||||
fn floor(auto value) { return builtin::std::math::floor(value); };
|
||||
|
||||
/**
|
||||
Ceils the value of `value`.
|
||||
@param value Value
|
||||
@return `value` ceiled
|
||||
*/
|
||||
fn ceil(auto value) { return builtin::std::math::ceil(value); };
|
||||
|
||||
/**
|
||||
Rounds the value of `value`.
|
||||
@param value Value
|
||||
@return `value` rounded
|
||||
*/
|
||||
fn round(auto value) { return builtin::std::math::round(value); };
|
||||
|
||||
/**
|
||||
Truncates the value of `value`.
|
||||
@param value Value
|
||||
@return `value` truncated
|
||||
*/
|
||||
fn trunc(auto value) { return builtin::std::math::trunc(value); };
|
||||
|
||||
|
||||
/**
|
||||
Calculates the logarithm of `value` with base 10.
|
||||
@param value Value
|
||||
@return Logarithm of `value` with base 10
|
||||
*/
|
||||
fn log10(auto value) { return builtin::std::math::log10(value); };
|
||||
|
||||
/**
|
||||
Calculates the logarithm of `value` with base 2.
|
||||
@param value Value
|
||||
@return Logarithm of `value` with base 2
|
||||
*/
|
||||
fn log2(auto value) { return builtin::std::math::log2(value); };
|
||||
|
||||
/**
|
||||
Calculates the natural logarithm of `value`.
|
||||
@param value Value
|
||||
@param base Base
|
||||
@return Logarithm of `value` with base `e`
|
||||
*/
|
||||
fn ln(auto value) { return builtin::std::math::ln(value); };
|
||||
|
||||
/**
|
||||
Calculates the floating point modulus of `value`.
|
||||
@param value Value
|
||||
@return Floating point modulus of `value`
|
||||
*/
|
||||
fn fmod(auto value) { return builtin::std::math::fmod(value); };
|
||||
|
||||
/**
|
||||
Calculates the value of `base` raised to the power of `exp`.
|
||||
@param base Base
|
||||
@param exp Exponent
|
||||
@return `base` raised to the power of `exp`
|
||||
*/
|
||||
fn pow(auto base, auto exp) { return builtin::std::math::pow(base, exp); };
|
||||
|
||||
/**
|
||||
Calculates the square root of `value`.
|
||||
@param value Value
|
||||
@return Square root of `value`
|
||||
*/
|
||||
fn sqrt(auto value) { return builtin::std::math::sqrt(value); };
|
||||
|
||||
/**
|
||||
Calculates the cubic root of `value`.
|
||||
@param value Value
|
||||
@return Cubic root of `value`
|
||||
*/
|
||||
fn cbrt(auto value) { return builtin::std::math::cbrt(value); };
|
||||
|
||||
/**
|
||||
Calculates the sine of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Sine of `value`
|
||||
*/
|
||||
fn sin(auto value) { return builtin::std::math::sin(value); };
|
||||
|
||||
/**
|
||||
Calculates the cosine of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Cosine of `value`
|
||||
*/
|
||||
fn cos(auto value) { return builtin::std::math::cos(value); };
|
||||
|
||||
/**
|
||||
Calculates the tangent of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Tangent of `value`
|
||||
*/
|
||||
fn tan(auto value) { return builtin::std::math::tan(value); };
|
||||
|
||||
/**
|
||||
Calculates the arc sine of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Arc sine of `value`
|
||||
*/
|
||||
fn asin(auto value) { return builtin::std::math::asin(value); };
|
||||
|
||||
/**
|
||||
Calculates the arc cosine of `value`.
|
||||
@param value Value
|
||||
@return Arc cosine of `value` in radians
|
||||
*/
|
||||
fn acos(auto value) { return builtin::std::math::acos(value); };
|
||||
|
||||
/**
|
||||
Calculates the arc tangent of `value`.
|
||||
@param value Value
|
||||
@return Arc tangent of `value` in radians between `-pi/2` and `pi/2`
|
||||
*/
|
||||
fn atan(auto value) { return builtin::std::math::atan(value); };
|
||||
|
||||
/**
|
||||
Calculates the arc tangent of `value`.
|
||||
@param value Value
|
||||
@return Arc tangent of `value` in radians between `-pi` and `pi`
|
||||
*/
|
||||
fn atan2(auto value) { return builtin::std::math::atan2(value); };
|
||||
|
||||
/**
|
||||
Calculates the hyperbolic sine of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Hyperbolic sine of `value`
|
||||
*/
|
||||
fn sinh(auto value) { return builtin::std::math::sinh(value); };
|
||||
|
||||
/**
|
||||
Calculates the hyperbolic cosine of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Hyperbolic cosine of `value`
|
||||
*/
|
||||
fn cosh(auto value) { return builtin::std::math::cosh(value); };
|
||||
|
||||
/**
|
||||
Calculates the hyperbolic tangent of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Hyperbolic tangent of `value`
|
||||
*/
|
||||
fn tanh(auto value) { return builtin::std::math::tanh(value); };
|
||||
|
||||
|
||||
/**
|
||||
Calculates the arc hyperbolic sine of `value`.
|
||||
@param value Value
|
||||
@return Arc hyperbolic sine of `value`
|
||||
*/
|
||||
fn asinh(auto value) { return builtin::std::math::asinh(value); };
|
||||
|
||||
/**
|
||||
Calculates the arc hyperbolic cosine of `value`.
|
||||
@param value Value
|
||||
@return Arc hyperbolic cosine of `value`
|
||||
*/
|
||||
fn acosh(auto value) { return builtin::std::math::acosh(value); };
|
||||
|
||||
/**
|
||||
Calculates the arc hyperbolic tangent of `value`.
|
||||
@param value Value
|
||||
@return Arc hyperbolic tangent of `value`
|
||||
*/
|
||||
fn atanh(auto value) { return builtin::std::math::atanh(value); };
|
||||
|
||||
|
||||
/**
|
||||
Options to use with the `std::math::accumulate` function.
|
||||
*/
|
||||
enum AccumulateOperation : u8 {
|
||||
Add = 0,
|
||||
Multiply = 1,
|
||||
Modulo = 2,
|
||||
Min = 3,
|
||||
Max = 4
|
||||
};
|
||||
|
||||
/**
|
||||
Calculates the sum of all values in the specified memory range.
|
||||
@param start Start address
|
||||
@param end End address
|
||||
@param valueSize Size of each value in bytes
|
||||
@param section Section to use
|
||||
@param operation Operation to use
|
||||
@param endian Endianness to use
|
||||
@return Sum of all values in the specified memory range
|
||||
*/
|
||||
fn accumulate(u128 start, u128 end, u128 valueSize, std::mem::Section section = 0, AccumulateOperation operation = AccumulateOperation::Add, std::mem::Endian endian = std::mem::Endian::Native) {
|
||||
return builtin::std::math::accumulate(start, end, valueSize, section, u128(operation), u128(endian));
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,17 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
Library for doing raw memory accesses and other low-level operations.
|
||||
*/
|
||||
|
||||
namespace std::mem {
|
||||
|
||||
/**
|
||||
A Handle for a custom Section
|
||||
*/
|
||||
using Section = u128;
|
||||
|
||||
/**
|
||||
The Endianess of a value
|
||||
*/
|
||||
enum Endian : u8 {
|
||||
Native = 0,
|
||||
Big = 1,
|
||||
Little = 2
|
||||
};
|
||||
|
||||
/**
|
||||
Function that returns true if the cursor position is at the end of the memory
|
||||
This is usually used in while-sized arrays in the form of `u8 array[while(!std::mem::eof())]`
|
||||
@return True if the cursor is at the end of the memory
|
||||
*/
|
||||
fn eof() {
|
||||
return $ >= std::mem::size();
|
||||
};
|
||||
|
||||
/**
|
||||
Aligns the given value to the given alignment
|
||||
@param alignment The alignment to align to
|
||||
@param value The value to align
|
||||
@return The aligned value
|
||||
*/
|
||||
fn align_to(u128 alignment, u128 value) {
|
||||
u128 remainder = value % alignment;
|
||||
|
||||
@@ -19,32 +42,202 @@ namespace std::mem {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Gets the base address of the memory
|
||||
@return The base address of the memory
|
||||
*/
|
||||
fn base_address() {
|
||||
return builtin::std::mem::base_address();
|
||||
};
|
||||
|
||||
/**
|
||||
Gets the size of the memory
|
||||
@return The size of the memory
|
||||
*/
|
||||
fn size() {
|
||||
return builtin::std::mem::size();
|
||||
};
|
||||
|
||||
/**
|
||||
Finds a sequence of bytes in the memory
|
||||
@param occurrence_index The index of the occurrence to find
|
||||
@param bytes The bytes to find
|
||||
@return The address of the sequence
|
||||
*/
|
||||
fn find_sequence(u128 occurrence_index, auto ... bytes) {
|
||||
return builtin::std::mem::find_sequence_in_range(occurrence_index, builtin::std::mem::base_address(), builtin::std::mem::size(), bytes);
|
||||
};
|
||||
|
||||
/**
|
||||
Finds a sequence of bytes in a specific region of the memory
|
||||
@param occurrence_index The index of the occurrence to find
|
||||
@param offsetFrom The offset from which to start searching
|
||||
@param offsetTo The offset to which to search
|
||||
@param bytes The bytes to find
|
||||
@return The address of the sequence
|
||||
*/
|
||||
fn find_sequence_in_range(u128 occurrence_index, u128 offsetFrom, u128 offsetTo, auto ... bytes) {
|
||||
return builtin::std::mem::find_sequence_in_range(occurrence_index, offsetFrom, offsetTo, bytes);
|
||||
};
|
||||
|
||||
/**
|
||||
Reads a unsigned value from the memory
|
||||
@param address The address to read from
|
||||
@param size The size of the value to read
|
||||
@param endian The endianess of the value to read
|
||||
@return The value read
|
||||
*/
|
||||
fn read_unsigned(u128 address, u8 size, Endian endian = Endian::Native) {
|
||||
return builtin::std::mem::read_unsigned(address, size, u32(endian));
|
||||
};
|
||||
|
||||
/**
|
||||
Reads a signed value from the memory
|
||||
@param address The address to read from
|
||||
@param size The size of the value to read
|
||||
@param endian The endianess of the value to read
|
||||
@return The value read
|
||||
*/
|
||||
fn read_signed(u128 address, u8 size, Endian endian = Endian::Native) {
|
||||
return builtin::std::mem::read_signed(address, size, u32(endian));
|
||||
};
|
||||
|
||||
/**
|
||||
Reads a string value from the memory
|
||||
@param address The address to read from
|
||||
@param size The size of the value to read
|
||||
@return The value read
|
||||
*/
|
||||
fn read_string(u128 address, u8 size) {
|
||||
return builtin::std::mem::read_string(address, size);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Gets the current bit offset within the current byte that a bitfield will read.
|
||||
*/
|
||||
fn current_bit_offset() {
|
||||
return builtin::std::mem::current_bit_offset();
|
||||
};
|
||||
|
||||
/**
|
||||
Reads a number of bits from the specified bit offset within the specified byte
|
||||
@param byteOffset The byte offset within the data
|
||||
@param bitOffset The bit offset to start the read at within the current byte
|
||||
@param bitSize The total number of bits to read
|
||||
@return A u128 containing the value read
|
||||
*/
|
||||
fn read_bits(u128 byteOffset, u128 bitOffset, u64 bitSize) {
|
||||
byteOffset += bitOffset >> 3;
|
||||
bitOffset = bitOffset & 0x7;
|
||||
return builtin::std::mem::read_bits(byteOffset, bitOffset, bitSize);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Creates a new custom section with the given name
|
||||
@param name The name of the section
|
||||
@return The handle to the section
|
||||
*/
|
||||
fn create_section(str name) {
|
||||
return builtin::std::mem::create_section(name);
|
||||
};
|
||||
|
||||
/**
|
||||
Deletes a custom section
|
||||
@param section The handle to the section
|
||||
*/
|
||||
fn delete_section(Section section) {
|
||||
builtin::std::mem::delete_section(section);
|
||||
};
|
||||
|
||||
/**
|
||||
Gets the size of a custom section
|
||||
@param section The handle to the section
|
||||
@return The size of the section
|
||||
*/
|
||||
fn get_section_size(Section section) {
|
||||
return builtin::std::mem::get_section_size(section);
|
||||
};
|
||||
|
||||
/**
|
||||
Copies a range of bytes from one section into another
|
||||
@param from_section The section to copy from
|
||||
@param from_address The address to copy from
|
||||
@param to_section The section to copy to
|
||||
@param to_address The address to copy to
|
||||
@param size The size of the range to copy
|
||||
*/
|
||||
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);
|
||||
};
|
||||
|
||||
/**
|
||||
Copies a range of bytes from the main section into a custom section
|
||||
@param from_section The section to copy from
|
||||
@param from_address The address to copy from
|
||||
@param to_address The address to copy to
|
||||
@param size The size of the range to copy
|
||||
*/
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Searches for a sequence of bytes and places the given type at that address
|
||||
@tparam Magic The magic sequence to search for
|
||||
@tparam T The type to place at the 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;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
Reinterprets a value as a different one
|
||||
@tparam From The type to reinterpret from
|
||||
@tparam To The type to reinterpret to
|
||||
*/
|
||||
union Reinterpreter<From, To> {
|
||||
From from;
|
||||
To to;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Aligns the cursor to the given alignment
|
||||
@tparam alignment The alignment to align to
|
||||
*/
|
||||
struct AlignTo<auto Alignment> {
|
||||
padding[Alignment - ((($ - 1) % Alignment) + 1)];
|
||||
} [[hidden, sealed]];
|
||||
|
||||
/**
|
||||
A type representing a sequence of bytes without any specific meaning
|
||||
@tparam Size The size of the sequence
|
||||
*/
|
||||
struct Bytes<auto Size> {
|
||||
u8 bytes[Size];
|
||||
} [[sealed, format("std::mem::impl::format_bytes")]];
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_bytes(auto bytes) {
|
||||
return "";
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,17 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
The Pointer library contains helper functions to deal with pointer types.
|
||||
The `relative_to` functions are meant to be used with the `[[pointer_base]]` attribute
|
||||
*/
|
||||
|
||||
namespace std::ptr {
|
||||
|
||||
/**
|
||||
Use the offset of the current pointer as start address
|
||||
@param offset The pointer's value
|
||||
@return The new pointer base
|
||||
*/
|
||||
fn relative_to_pointer(u128 offset) {
|
||||
return $;
|
||||
};
|
||||
|
||||
/**
|
||||
Use the offset of the pointer's parent as start address
|
||||
@param offset The pointer's value
|
||||
@return The new pointer base
|
||||
*/
|
||||
fn relative_to_parent(u128 offset) {
|
||||
return addressof(parent);
|
||||
};
|
||||
|
||||
/**
|
||||
Use the end of the file as pointer base address and use its value as offset backwards from there
|
||||
@param offset The pointer's value
|
||||
@return The new pointer base
|
||||
*/
|
||||
fn relative_to_end(u128 offset) {
|
||||
return std::mem::size() - offset * 2;
|
||||
};
|
||||
|
||||
/**
|
||||
A nullable pointer, generic over both the pointee type and pointer type.
|
||||
|
||||
By nullable, we mean that if the pointer's value is zero (`0x0`), then the
|
||||
value will appear as padding rather than a pointer to something, but
|
||||
if the pointer's value is non-zero, that non-zero value will be treated as
|
||||
a pointer of type `PointerTy` which points to an element of type `PointeeTy`.
|
||||
|
||||
Example:
|
||||
A struct field called `p_myInfo` which is a nullable 64-bit pointer to an
|
||||
element of type `MyInfoTy` would be written as:
|
||||
```
|
||||
struct MyStruct {
|
||||
std::ptr::NullablePtr<MyInfoTy, u64> p_myInfo;
|
||||
}
|
||||
```
|
||||
*/
|
||||
struct NullablePtr<PointeeTy, PointerTy> {
|
||||
// `pointerValue` is `no_unique_address` because we don't want to advance
|
||||
// the current memory location after reading the value of the pointer itself;
|
||||
// we want to examine the value at this address to determine what should be
|
||||
// displayed. It's also `hidden` so the editor only displays either thee
|
||||
// padding or the populated pointer/pointee field.
|
||||
PointerTy pointerValue [[no_unique_address, hidden]];
|
||||
if (pointerValue == 0x0) {
|
||||
padding[sizeof(PointerTy)];
|
||||
} else {
|
||||
PointeeTy *data : PointerTy;
|
||||
}
|
||||
};
|
||||
}
|
||||
81
includes/std/random.pat
Normal file
81
includes/std/random.pat
Normal file
@@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
|
||||
#include <std/limits.pat>
|
||||
|
||||
/*!
|
||||
Library to generate random numbers. Supports various different distribution types.
|
||||
*/
|
||||
|
||||
namespace std::random {
|
||||
|
||||
/**
|
||||
Represents the type of distribution to use to generate a random number
|
||||
*/
|
||||
enum Distribution : u8 {
|
||||
Uniform = 0,
|
||||
Normal = 1,
|
||||
Exponential = 2,
|
||||
Gamma = 3,
|
||||
Weibull = 4,
|
||||
ExtremeValue = 5,
|
||||
ChiSquared = 6,
|
||||
Cauchy = 7,
|
||||
FisherF = 8,
|
||||
StudentT = 9,
|
||||
LogNormal = 10,
|
||||
Bernoulli = 11,
|
||||
Binomial = 12,
|
||||
NegativeBinomial = 13,
|
||||
Geometric = 14,
|
||||
Poisson = 15
|
||||
};
|
||||
|
||||
/**
|
||||
Sets the seed of the random number generator
|
||||
@param seed Seed to use
|
||||
*/
|
||||
fn set_seed(u64 seed) {
|
||||
builtin::std::random::set_seed(seed);
|
||||
};
|
||||
|
||||
/**
|
||||
Generates a random number using the given distribution with the given parameters.
|
||||
The random number generator used internally is C++'s std::mt19937_64 Mersenne Twister implementation.
|
||||
|
||||
> **Distributions**
|
||||
> - `Uniform(min, max) -> i128`
|
||||
> - `Normal(mean, stddev) -> double`
|
||||
> - `Exponential(lambda) -> double`
|
||||
> - `Gamma(alpha, beta) -> double`
|
||||
> - `Weibull(a, b) -> double`
|
||||
> - `ExtremeValue(a, b) -> double`
|
||||
> - `ChiSquared(n) -> double`
|
||||
> - `Cauchy(a, b) -> double`
|
||||
> - `FisherF(m, n) -> double`
|
||||
> - `StudentT(n) -> double`
|
||||
> - `LogNormal(m, s) -> double`
|
||||
> - `Bernoulli(p) -> bool`
|
||||
> - `Binomial(t, p) -> i128`
|
||||
> - `NegativeBinomial(k, p) -> i128`
|
||||
> - `Geometric(p) -> i128`
|
||||
> - `Poisson(mean) -> i128`
|
||||
|
||||
@param distribution Distribution to use
|
||||
@param param1 This parameter depends on the type of distribution used.
|
||||
@param param2 This parameter depends on the type of distribution used.
|
||||
*/
|
||||
fn generate_using(Distribution distribution, auto param1 = 0, auto param2 = 0) {
|
||||
return builtin::std::random::generate(u32(distribution), param1, param2);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Generates a uniformly distributed random number between `min` and `max`
|
||||
@param min Minimum number
|
||||
@param max Maximum number
|
||||
*/
|
||||
fn generate(u64 min = std::limits::u64_min(), u64 max = std::limits::u64_max()) {
|
||||
return std::random::generate_using(Distribution::Uniform, min, max);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -2,54 +2,145 @@
|
||||
|
||||
#include <std/io.pat>
|
||||
|
||||
/*!
|
||||
Libray to interact with strings.
|
||||
*/
|
||||
|
||||
namespace std::string {
|
||||
|
||||
/**
|
||||
Base type for sized strings. Represents a string with its size preceeding it.
|
||||
@tparam SizeType The type of the size field.
|
||||
@tparam DataType The type of the characters.
|
||||
*/
|
||||
struct SizedStringBase<SizeType, DataType> {
|
||||
SizeType size;
|
||||
DataType data[size];
|
||||
} [[sealed, format("std::string::impl::format_sized_string"), transform("std::string::impl::format_sized_string")]];
|
||||
|
||||
/**
|
||||
A ASCII string with a prefixed size.
|
||||
@tparam SizeType The type of the size field.
|
||||
*/
|
||||
using SizedString<SizeType> = SizedStringBase<SizeType, char>;
|
||||
|
||||
/**
|
||||
A UTF-16 string with a prefixed size.
|
||||
@tparam SizeType The type of the size field.
|
||||
*/
|
||||
using SizedString16<SizeType> = SizedStringBase<SizeType, char16>;
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_sized_string(ref auto string) {
|
||||
return string.data;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Gets the length of a string.
|
||||
@param string The string to get the length of.
|
||||
@return The length of the string.
|
||||
*/
|
||||
fn length(str string) {
|
||||
return builtin::std::string::length(string);
|
||||
};
|
||||
|
||||
/**
|
||||
Gets the character at a given index.
|
||||
@param string The string to get the character from.
|
||||
@param index The index of the character to get.
|
||||
@return The character at the given index.
|
||||
*/
|
||||
fn at(str string, u32 index) {
|
||||
return builtin::std::string::at(string, index);
|
||||
};
|
||||
|
||||
/**
|
||||
Gets a substring of a string.
|
||||
@param string The string to get the substring from.
|
||||
@param pos The position of the first character of the substring.
|
||||
@param count The number of characters to get.
|
||||
@return The substring.
|
||||
*/
|
||||
fn substr(str string, u32 pos, u32 count) {
|
||||
return builtin::std::string::substr(string, pos, count);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Converts a string to an integer.
|
||||
@param string The string to convert.
|
||||
@param base The base of the number.
|
||||
@return The integer.
|
||||
*/
|
||||
fn parse_int(str string, u8 base) {
|
||||
return builtin::std::string::parse_int(string, base);
|
||||
};
|
||||
|
||||
/**
|
||||
Converts a string to a float.
|
||||
@param string The string to convert.
|
||||
@return The float.
|
||||
*/
|
||||
fn parse_float(str string) {
|
||||
return builtin::std::string::parse_float(string);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Converts any type to a string.
|
||||
@param x The value to convert.
|
||||
@return The string.
|
||||
*/
|
||||
fn to_string(auto x) {
|
||||
return std::format("{}", x);
|
||||
};
|
||||
|
||||
/**
|
||||
Checks if a string starts with a given substring.
|
||||
@param string The string to check.
|
||||
@param part The substring to check for.
|
||||
@return True if the string starts with the substring, false otherwise.
|
||||
*/
|
||||
fn starts_with(str string, str part) {
|
||||
return std::string::substr(string, 0, std::string::length(part)) == part;
|
||||
};
|
||||
|
||||
/**
|
||||
Checks if a string ends with a given substring.
|
||||
@param string The string to check.
|
||||
@param part The substring to check for.
|
||||
@return True if the string ends with the substring, false otherwise.
|
||||
*/
|
||||
fn ends_with(str string, str part) {
|
||||
return std::string::substr(string, std::string::length(string) - std::string::length(part), std::string::length(part)) == part;
|
||||
};
|
||||
|
||||
fn contains(str a, str b) {
|
||||
s32 a_len = std::string::length(a);
|
||||
s32 b_len = std::string::length(b);
|
||||
/**
|
||||
Checks if a string contains a given substring.
|
||||
@param string The string to check.
|
||||
@param part The substring to check for.
|
||||
@return True if the string contains the substring, false otherwise.
|
||||
*/
|
||||
fn contains(str string, str part) {
|
||||
s32 string_len = std::string::length(string);
|
||||
s32 part_len = std::string::length(part);
|
||||
|
||||
for (s32 i = 0, i <= (a_len - b_len), i += 1) {
|
||||
if (std::string::substr(a, i, b_len) == b)
|
||||
for (s32 i = 0, i <= (string_len - part_len), i += 1) {
|
||||
if (std::string::substr(string, i, part_len) == part)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
Reverses a string.
|
||||
@param string The string to reverse.
|
||||
@return The reversed string.
|
||||
*/
|
||||
fn reverse(str string) {
|
||||
str result;
|
||||
|
||||
@@ -63,6 +154,11 @@ namespace std::string {
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
Converts a string to upper case.
|
||||
@param string The string to convert.
|
||||
@return The converted string.
|
||||
*/
|
||||
fn to_upper(str string) {
|
||||
str result;
|
||||
|
||||
@@ -82,6 +178,11 @@ namespace std::string {
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
Converts a string to lower case.
|
||||
@param string The string to convert.
|
||||
@return The converted string.
|
||||
*/
|
||||
fn to_lower(str string) {
|
||||
str result;
|
||||
|
||||
@@ -101,6 +202,13 @@ namespace std::string {
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
Replaces all occurrences of a substring with another substring.
|
||||
@param string The string to replace in.
|
||||
@param pattern The substring to replace.
|
||||
@param replace The substring to replace with.
|
||||
@return The string with the replacements.
|
||||
*/
|
||||
fn replace(str string, str pattern, str replace) {
|
||||
u32 string_len, pattern_len, replace_len;
|
||||
string_len = std::string::length(string);
|
||||
|
||||
@@ -2,14 +2,28 @@
|
||||
|
||||
#include <std/io.pat>
|
||||
|
||||
/*!
|
||||
Basic helper functions
|
||||
*/
|
||||
|
||||
namespace std {
|
||||
|
||||
/**
|
||||
Asserts that a given value is true. If it's not, abort evaluation and print the given message to the console
|
||||
@param conditoon The condition that is required to be true
|
||||
@param message The message to print in case the assertion doesn't hold
|
||||
*/
|
||||
fn assert(bool condition, str message) {
|
||||
if (!condition) {
|
||||
std::error(std::format("assertion failed '{0}'", message));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
Asserts that a given value is true. If it's not, print the given message to the console as a warning
|
||||
@param conditoon The condition that is required to be true
|
||||
@param message The message to print in case the assertion doesn't hold
|
||||
*/
|
||||
fn assert_warn(bool condition, str message) {
|
||||
if (!condition) {
|
||||
std::warning(std::format("assertion failed '{0}'", message));
|
||||
@@ -17,10 +31,20 @@ namespace std {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Queries the value of a set environment variable given it's name
|
||||
@param name The name of the env variable
|
||||
@return The value of that variable
|
||||
*/
|
||||
fn env(str name) {
|
||||
return builtin::std::env(name);
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the number of parameters in a parameter pack.
|
||||
@param pack The pack to check
|
||||
@return Number of parameters in `pack`
|
||||
*/
|
||||
fn sizeof_pack(auto ... pack) {
|
||||
return builtin::std::sizeof_pack(pack);
|
||||
};
|
||||
|
||||
@@ -2,8 +2,15 @@
|
||||
|
||||
#include <std/io.pat>
|
||||
|
||||
/*!
|
||||
Library to handle time and date related operations.
|
||||
*/
|
||||
|
||||
namespace std::time {
|
||||
|
||||
/**
|
||||
A structured representation of a time and date.
|
||||
*/
|
||||
struct Time {
|
||||
u8 sec;
|
||||
u8 min;
|
||||
@@ -15,57 +22,170 @@ namespace std::time {
|
||||
u16 yday;
|
||||
bool isdst;
|
||||
} [[sealed]];
|
||||
|
||||
|
||||
/**
|
||||
A helper type to convert between Time and u128.
|
||||
*/
|
||||
union TimeConverter {
|
||||
Time time;
|
||||
u128 value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
A type to represent a time in seconds since the epoch.
|
||||
*/
|
||||
using EpochTime = u128;
|
||||
|
||||
/**
|
||||
A type to represent a time zone.
|
||||
*/
|
||||
enum TimeZone : u8 {
|
||||
Local,
|
||||
UTC
|
||||
};
|
||||
|
||||
/**
|
||||
A type to represent a DOS date.
|
||||
*/
|
||||
bitfield DOSDate {
|
||||
day: 5;
|
||||
month: 4;
|
||||
year: 7;
|
||||
} [[sealed]];
|
||||
|
||||
/**
|
||||
A type to represent a DOS time.
|
||||
*/
|
||||
bitfield DOSTime {
|
||||
seconds: 5;
|
||||
minutes: 6;
|
||||
hours: 5;
|
||||
} [[sealed]];
|
||||
|
||||
namespace impl {
|
||||
|
||||
union DOSDateConverter {
|
||||
DOSDate date;
|
||||
u16 value;
|
||||
};
|
||||
|
||||
union DOSTimeConverter {
|
||||
DOSTime time;
|
||||
u16 value;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Returns the current time in seconds since the epoch.
|
||||
@return The current time in seconds since the epoch.
|
||||
*/
|
||||
fn epoch() {
|
||||
return builtin::std::time::epoch();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Converts a time in seconds since the epoch to a local time.
|
||||
@param epoch_time The time in seconds since the epoch.
|
||||
@return The local time.
|
||||
*/
|
||||
fn to_local(EpochTime epoch_time) {
|
||||
TimeConverter converter;
|
||||
|
||||
|
||||
converter.value = builtin::std::time::to_local(epoch_time);
|
||||
|
||||
|
||||
return converter.time;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Converts a time in seconds since the epoch to a UTC time.
|
||||
@param epoch_time The time in seconds since the epoch.
|
||||
@return The UTC time.
|
||||
*/
|
||||
fn to_utc(EpochTime epoch_time) {
|
||||
TimeConverter converter;
|
||||
|
||||
|
||||
converter.value = builtin::std::time::to_utc(epoch_time);
|
||||
|
||||
|
||||
return converter.time;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Queries the current time in the specified time zone.
|
||||
@param time_zone The time zone to query.
|
||||
@return The current time in the specified time zone.
|
||||
*/
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Converts a value to a DOS date.
|
||||
@param value The value to convert.
|
||||
@return The DOS date.
|
||||
*/
|
||||
fn to_dos_date(u16 value) {
|
||||
impl::DOSDateConverter converter;
|
||||
|
||||
converter.value = value;
|
||||
|
||||
return converter.date;
|
||||
};
|
||||
|
||||
/**
|
||||
Converts a value to a DOS time.
|
||||
@param value The value to convert.
|
||||
@return The DOS time.
|
||||
*/
|
||||
fn to_dos_time(u16 value) {
|
||||
impl::DOSTimeConverter converter;
|
||||
|
||||
converter.value = value;
|
||||
|
||||
return converter.time;
|
||||
};
|
||||
|
||||
/**
|
||||
Formats a time according to the specified format string.
|
||||
@param time The time to format.
|
||||
@param format_string The format string to use.
|
||||
@return The formatted time.
|
||||
*/
|
||||
fn format(Time time, str format_string = "%c") {
|
||||
TimeConverter converter;
|
||||
converter.time = time;
|
||||
|
||||
|
||||
return builtin::std::time::format(format_string, converter.value);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
Formats a DOS date according to the specified format string.
|
||||
@param date The DOS date to format.
|
||||
@param format_string The format string to use.
|
||||
@return The formatted DOS date.
|
||||
*/
|
||||
fn format_dos_date(DOSDate date, str format_string = "{}/{}/{}") {
|
||||
return std::format(format_string, date.day, date.month, date.year + 1980);
|
||||
};
|
||||
|
||||
/**
|
||||
Formats a DOS time according to the specified format string.
|
||||
@param time The DOS time to format.
|
||||
@param format_string The format string to use.
|
||||
@return The formatted DOS time.
|
||||
*/
|
||||
fn format_dos_time(DOSTime time, str format_string = "{:02}:{:02}:{:02}") {
|
||||
return std::format(format_string, time.hours, time.minutes, time.seconds * 2);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
55
includes/type/base.pat
Normal file
55
includes/type/base.pat
Normal file
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <std/io.pat>
|
||||
#include <std/math.pat>
|
||||
|
||||
/*!
|
||||
Types used to change the base of the displayed integer value.
|
||||
Used like `type::Hex<u32> hexNumber;`, `type::Oct<u16> octalNumber;`
|
||||
*/
|
||||
|
||||
namespace type {
|
||||
|
||||
/**
|
||||
Integer type representing a Hexadecimal value. Displays its value in hexadecimal format.
|
||||
@tparam T Integer type to use
|
||||
*/
|
||||
using Hex<T> = T [[format("type::impl::format_hex")]];
|
||||
|
||||
/**
|
||||
Integer type representing a Octal value. Displays its value in octal format.
|
||||
@tparam T Integer type to use
|
||||
*/
|
||||
using Oct<T> = T [[format("type::impl::format_oct")]];
|
||||
|
||||
/**
|
||||
Integer type representing a Decimal value. Displays its value in decimal format.
|
||||
@tparam T Integer type to use
|
||||
*/
|
||||
using Dec<T> = T [[format("type::impl::format_dec")]];
|
||||
|
||||
/**
|
||||
Integer type representing a Binary value. Displays its value in binary format.
|
||||
@tparam T Integer type to use
|
||||
*/
|
||||
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}"); };
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
37
includes/type/bcd.pat
Normal file
37
includes/type/bcd.pat
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <std/io.pat>
|
||||
|
||||
/*!
|
||||
Type to decode a BCD (Binary Coded Decimal) number
|
||||
*/
|
||||
|
||||
namespace type {
|
||||
|
||||
/**
|
||||
Decodes a BCD value where one byte represents a single digit
|
||||
@tparam Digits Number of digits
|
||||
*/
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,8 +2,15 @@
|
||||
|
||||
#include <std/io.pat>
|
||||
|
||||
/*!
|
||||
Types to display single bytes using various different representations
|
||||
*/
|
||||
|
||||
namespace type {
|
||||
|
||||
/**
|
||||
Type visualizing the value of each individual bit
|
||||
*/
|
||||
bitfield Bits {
|
||||
bit0 : 1;
|
||||
bit1 : 1;
|
||||
@@ -15,11 +22,17 @@ namespace type {
|
||||
bit7 : 1;
|
||||
} [[format("type::impl::format_bits"), right_to_left]];
|
||||
|
||||
/**
|
||||
Type visualizing the value of the two nibbles
|
||||
*/
|
||||
bitfield Nibbles {
|
||||
low : 4;
|
||||
high : 4;
|
||||
} [[format("type::impl::format_nibbles")]];
|
||||
|
||||
/**
|
||||
Type representing a single Byte. Decodes the byte as it's hexadeicmal value, individual bits and nibbles
|
||||
*/
|
||||
union Byte {
|
||||
u8 value;
|
||||
Bits bits;
|
||||
|
||||
80
includes/type/color.pat
Normal file
80
includes/type/color.pat
Normal file
@@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
|
||||
#include <std/io.pat>
|
||||
#include <std/core.pat>
|
||||
|
||||
/*!
|
||||
Types representing RGB or RGBA colors. The decoded color will be displayed in their color field
|
||||
*/
|
||||
|
||||
namespace type {
|
||||
|
||||
/**
|
||||
Type representing a generic RGBA color with a variable number of bits for each color
|
||||
@tparam R Number of bits used for the red component
|
||||
@tparam G Number of bits used for the green component
|
||||
@tparam B Number of bits used for the blue component
|
||||
@tparam A Number of bits used for the alpha component
|
||||
*/
|
||||
bitfield RGBA<auto R, auto G, auto B, auto A> {
|
||||
r : R;
|
||||
g : G;
|
||||
b : B;
|
||||
if (A > 0) a : A;
|
||||
} [[sealed, format("type::impl::format_color"), color(std::format("{0:02X}{1:02X}{2:02X}FF", r, g, b))]];
|
||||
|
||||
/**
|
||||
Type representing a generic RGB color with a variable number of bits for each color
|
||||
@tparam R Number of bits used for the red component
|
||||
@tparam G Number of bits used for the green component
|
||||
@tparam B Number of bits used for the blue component
|
||||
*/
|
||||
using RGB<auto R, auto G, auto B> = RGBA<R,G,B,0>;
|
||||
|
||||
|
||||
/**
|
||||
Type representing a RGBA color with 8 bits for the red component, 8 bits for green, 8 bits for blue and 8 bits for alpha
|
||||
*/
|
||||
using RGBA8 = RGBA<8,8,8,8>;
|
||||
|
||||
/**
|
||||
Type representing a RGB color with 8 bits for the red component, 8 bits for green and 8 bits for blue
|
||||
*/
|
||||
using RGB8 = RGB<8,8,8>;
|
||||
|
||||
/**
|
||||
Type representing a RGB color with 5 bits for the red component, 6 bits for green and 5 bits for blue
|
||||
*/
|
||||
using RGB565 = RGB<5,6,5>;
|
||||
|
||||
/**
|
||||
Type representing a RGBA color with 4 bits for the red component, 4 bits for green, 4 bits for blue and 4 bits for alpha
|
||||
*/
|
||||
using RGB4444 = RGBA<4,4,4,4>;
|
||||
|
||||
/**
|
||||
Type representing a RGBA color with 5 bits for the red component, 5 bits for green, 5 bits for blue and 1 bits for alpha
|
||||
*/
|
||||
using RGBA5551 = RGBA<5,5,5,1>;
|
||||
|
||||
|
||||
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,59 @@
|
||||
|
||||
#include <std/io.pat>
|
||||
#include <std/math.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
/*!
|
||||
Type representing a 16 bit half precision floating point number
|
||||
*/
|
||||
|
||||
namespace type {
|
||||
|
||||
/**
|
||||
Type representing a 16 bit half precision floating point number
|
||||
*/
|
||||
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);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,8 +2,15 @@
|
||||
|
||||
#include <std/io.pat>
|
||||
|
||||
/*!
|
||||
Types to deal with UUIDs (Universally Unique Identifiers) / GUIDs (Globally Unique Identifiers) as described in RFC 4122
|
||||
*/
|
||||
|
||||
namespace type {
|
||||
|
||||
/**
|
||||
Type representing a GUID value
|
||||
*/
|
||||
struct GUID {
|
||||
u32 time_low;
|
||||
u16 time_mid;
|
||||
@@ -13,6 +20,11 @@ namespace type {
|
||||
u8 node[6];
|
||||
} [[sealed, format("type::impl::format_guid")]];
|
||||
|
||||
/**
|
||||
Alias name for GUID
|
||||
*/
|
||||
using UUID = GUID;
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_guid(GUID guid) {
|
||||
|
||||
@@ -1,39 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#include <std/io.pat>
|
||||
#include <std/string.pat>
|
||||
|
||||
/*!
|
||||
Types used to decode IP addresses
|
||||
*/
|
||||
|
||||
namespace type {
|
||||
|
||||
struct IPv4Address {
|
||||
u8 bytes[4];
|
||||
} [[sealed, format("type::impl::format_ipv4_address")]];
|
||||
/**
|
||||
A 4 byte IPv4 Address as described in RFC 791
|
||||
*/
|
||||
struct IPv4Address {
|
||||
u8 bytes[4];
|
||||
} [[sealed, format("type::impl::format_ipv4_address")]];
|
||||
|
||||
/**
|
||||
A 16 byte IPv6 Address as described in RFC 8200
|
||||
*/
|
||||
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]);
|
||||
};
|
||||
be 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("{:X}", address.words[i]);
|
||||
}
|
||||
|
||||
result += ":";
|
||||
}
|
||||
|
||||
return std::string::substr(result, 0, std::string::length(result) - 1);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,31 +3,70 @@
|
||||
#include <std/io.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
/*!
|
||||
Types used to decode Little Endian Base 128 numbers used to store large numbers as space efficiently as possible
|
||||
*/
|
||||
|
||||
namespace type {
|
||||
|
||||
struct LEB128 {
|
||||
/**
|
||||
Base LEB128 type. Use `uLEB128` and `sLEB128` instead.
|
||||
*/
|
||||
struct LEB128Base {
|
||||
u8 array[while($ == addressof(this) || std::mem::read_unsigned($-1, 1) & 0x80 != 0)] [[hidden]];
|
||||
} [[sealed, format("type::impl::format_leb128"), transform("type::impl::transform_leb128")]];
|
||||
} [[sealed]];
|
||||
|
||||
/**
|
||||
A unsigned variant of a LEB128 number
|
||||
*/
|
||||
using uLEB128 = LEB128Base [[format("type::impl::format_uleb128"), transform("type::impl::transform_uleb128")]];
|
||||
|
||||
/**
|
||||
A signed variant of a LEB128 number
|
||||
*/
|
||||
using sLEB128 = LEB128Base [[format("type::impl::format_sleb128"), transform("type::impl::transform_sleb128")]];
|
||||
|
||||
/**
|
||||
Legacy alias for uLEB128
|
||||
*/
|
||||
using LEB128 = uLEB128;
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn transform_leb128_array(auto array) {
|
||||
fn transform_uleb128_array(auto array) {
|
||||
u128 res = array[0] & 0x7f;
|
||||
for(u8 i = 1, array[i-1] & 0x80 != 0, i+=1) {
|
||||
res |= u64(array[i] & 0x7f) << 7 * i;
|
||||
res |= u128(array[i] & 0x7f) << 7 * i;
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
fn transform_sleb128_array(auto array) {
|
||||
s128 res = type::impl::transform_uleb128_array(array);
|
||||
if (res & 0x40 != 0) {
|
||||
res |= ~0 << (sizeof(array) / sizeof(u8)) * 7;
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
fn format_leb128(auto leb128) {
|
||||
u128 res = type::impl::transform_leb128_array(leb128.array);
|
||||
fn format_uleb128(auto leb128) {
|
||||
u128 res = type::impl::transform_uleb128_array(leb128.array);
|
||||
return std::format("{} ({:#x})", res, res);
|
||||
};
|
||||
|
||||
fn transform_leb128(auto leb128) {
|
||||
return type::impl::transform_leb128_array(leb128.array);
|
||||
fn transform_uleb128(auto leb128) {
|
||||
return type::impl::transform_uleb128_array(leb128.array);
|
||||
};
|
||||
|
||||
fn format_sleb128(auto leb128) {
|
||||
s128 res = type::impl::transform_sleb128_array(leb128.array);
|
||||
return std::format("{} ({:#x})", res, res);
|
||||
};
|
||||
|
||||
fn transform_sleb128(auto leb128) {
|
||||
return type::impl::transform_sleb128_array(leb128.array);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,15 @@
|
||||
|
||||
#include <std/io.pat>
|
||||
|
||||
/*!
|
||||
Types used to decode MAC Addresses
|
||||
*/
|
||||
|
||||
namespace type {
|
||||
|
||||
/**
|
||||
A MAC Address as used in the Internet Protocol
|
||||
*/
|
||||
struct MACAddress {
|
||||
u8 bytes[6];
|
||||
} [[sealed, format("type::impl::format_mac_address")]];
|
||||
|
||||
38
includes/type/magic.pat
Normal file
38
includes/type/magic.pat
Normal file
@@ -0,0 +1,38 @@
|
||||
#include <std/string.pat>
|
||||
#include <std/sys.pat>
|
||||
#include <std/io.pat>
|
||||
#include <std/ctype.pat>
|
||||
|
||||
/*!
|
||||
Types used to parse and enforce specific magic numbers
|
||||
*/
|
||||
|
||||
namespace type {
|
||||
|
||||
/**
|
||||
A Magic number. Throws an error if the magic number does not match the expected value
|
||||
@tparam ExpectedValue A string representing the expected value
|
||||
*/
|
||||
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) {
|
||||
str result;
|
||||
for (u32 i = 0, i < sizeof(magic.value), i += 1) {
|
||||
char c = magic.value[i];
|
||||
|
||||
if (std::ctype::isprint(c))
|
||||
result += c;
|
||||
else
|
||||
result += std::format("\\x{:02X}", u8(c));
|
||||
}
|
||||
return std::format("\"{}\"", result);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,32 +1,53 @@
|
||||
#include <std/mem.pat>
|
||||
|
||||
/*!
|
||||
Types dealing with various kinds of resource paths
|
||||
*/
|
||||
|
||||
namespace type {
|
||||
|
||||
struct UnixPathSegment {
|
||||
char string[while(std::mem::read_unsigned($, 1) != '/' && std::mem::read_unsigned($, 1) != 0x00)];
|
||||
/**
|
||||
Type representing a single path segment. Use the `Path` type instead of using this on its own
|
||||
@tparam Delimeter The delimeter sequence used to separate two path segments
|
||||
*/
|
||||
struct PathSegment<auto Delimeter> {
|
||||
char string[while(std::mem::read_string($, std::string::length(Delimeter)) != Delimeter && std::mem::read_unsigned($, 1) != 0x00)];
|
||||
char separator [[hidden]];
|
||||
|
||||
if (separator == 0x00) {
|
||||
$ -= 1;
|
||||
break;
|
||||
}
|
||||
} [[sealed, format("type::impl::format_unix_path_segment")]];
|
||||
} [[sealed, format("type::impl::format_path_segment")]];
|
||||
|
||||
struct UnixPath {
|
||||
UnixPathSegment segments[while(true)];
|
||||
} [[format("type::impl::format_unix_path")]];
|
||||
/**
|
||||
A generic type representing a path with an arbitrary delimeter
|
||||
@tparam Delimeter The delimeter sequence used to separate two path segments
|
||||
*/
|
||||
struct Path<auto Delimeter> {
|
||||
PathSegment<Delimeter> segments[while(true)];
|
||||
} [[format("type::impl::format_path")]];
|
||||
|
||||
/**
|
||||
A type representing a Unix path using a '/' forwardslash as delimeter
|
||||
*/
|
||||
using UnixPath = Path<"/">;
|
||||
|
||||
/**
|
||||
A type representing a DOS path using a '\' backslash as delimeter
|
||||
*/
|
||||
using DOSPath = Path<"\\">;
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_unix_path_segment(UnixPathSegment segment) {
|
||||
fn format_path_segment(ref auto segment) {
|
||||
return segment.string;
|
||||
};
|
||||
|
||||
fn format_unix_path(UnixPath path) {
|
||||
fn format_path(ref auto path) {
|
||||
return std::mem::read_string($, sizeof(path));
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,37 @@
|
||||
#include <std/io.pat>
|
||||
|
||||
/*!
|
||||
Types used to pretty print size values
|
||||
*/
|
||||
|
||||
namespace type {
|
||||
|
||||
using Size8 = u8 [[format("type::impl::size_formatter")]];
|
||||
using Size16 = u16 [[format("type::impl::size_formatter")]];
|
||||
using Size32 = u32 [[format("type::impl::size_formatter")]];
|
||||
using Size64 = u64 [[format("type::impl::size_formatter")]];
|
||||
using Size128 = u128 [[format("type::impl::size_formatter")]];
|
||||
/**
|
||||
A generic size type which displays its value in Bytes (or kiB, MiB, GiB, TiB, PiB, EiB if larger)
|
||||
@tparam T Underlying type
|
||||
*/
|
||||
using Size<T> = T [[format("type::impl::size_formatter")]];
|
||||
|
||||
/**
|
||||
A 8 bit size type
|
||||
*/
|
||||
using Size8 = Size<u8>;
|
||||
/**
|
||||
A 16 bit size type
|
||||
*/
|
||||
using Size16 = Size<u16>;
|
||||
/**
|
||||
A 32 bit size type
|
||||
*/
|
||||
using Size32 = Size<u32>;
|
||||
/**
|
||||
A 64 bit size type
|
||||
*/
|
||||
using Size64 = Size<u64>;
|
||||
/**
|
||||
A 128 bit size type
|
||||
*/
|
||||
using Size128 = Size<u128>;
|
||||
|
||||
namespace impl {
|
||||
|
||||
@@ -42,4 +69,4 @@ namespace type {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -3,17 +3,51 @@
|
||||
#include <std/io.pat>
|
||||
#include <std/time.pat>
|
||||
|
||||
/*!
|
||||
Types used to decode various different time formats
|
||||
*/
|
||||
|
||||
namespace type {
|
||||
|
||||
|
||||
/**
|
||||
A 32 bit Unix time value
|
||||
*/
|
||||
using time32_t = u32 [[format("type::impl::format_time_t")]];
|
||||
|
||||
/**
|
||||
Alias name for `time32_t`
|
||||
*/
|
||||
using time_t = time32_t;
|
||||
|
||||
/**
|
||||
A 64 bit Unix time value
|
||||
*/
|
||||
using time64_t = u64 [[format("type::impl::format_time_t")]];
|
||||
|
||||
/**
|
||||
A DOS Date value
|
||||
*/
|
||||
using DOSDate = u16 [[format("type::impl::format_dosdate")]];
|
||||
|
||||
/**
|
||||
A DOS Time value
|
||||
*/
|
||||
using DOSTime = u16 [[format("type::impl::format_dostime")]];
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_time_t(u128 value) {
|
||||
fn format_time_t(u128 value) {
|
||||
return std::time::format(std::time::to_utc(value));
|
||||
};
|
||||
|
||||
fn format_dosdate(u16 value) {
|
||||
return std::time::format_dos_date(std::time::to_dos_date(value));
|
||||
};
|
||||
|
||||
fn format_dostime(u16 value) {
|
||||
return std::time::format_dos_time(std::time::to_dos_time(value));
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
Alias types to make it easier to move template definitions over from 010 Editor to ImHex
|
||||
*/
|
||||
|
||||
// Explicitly don't add these types to the `type` namespace for usability
|
||||
// namespace type {
|
||||
|
||||
@@ -11,7 +15,7 @@
|
||||
using uchar = u8;
|
||||
using ubyte = u8;
|
||||
using UCHAR = u8;
|
||||
using ubyte = u8;
|
||||
using UBYTE = u8;
|
||||
|
||||
|
||||
using short = s16;
|
||||
@@ -59,4 +63,4 @@
|
||||
// using double = double;
|
||||
using DOUBLE = double;
|
||||
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
Alias definitions for all C stdint and regular data types
|
||||
*/
|
||||
|
||||
// Explicitly don't add these types to the `type` namespace for usability
|
||||
// namespace type {
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
Various data types used in the Linux Kernel
|
||||
*/
|
||||
|
||||
// Explicitly don't add these types to the `type` namespace for usability
|
||||
// namespace type {
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
Alias definitions for Rust's data types
|
||||
*/
|
||||
|
||||
// Explicitly don't add these types to the `type` namespace for usability
|
||||
// namespace type {
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
Alias definitions for various type names used in Windows applications
|
||||
*/
|
||||
|
||||
// Explicitly don't add these types to the `type` namespace for usability
|
||||
// namespace type {
|
||||
|
||||
|
||||
219
nodes/caesar.hexnode
Normal file
219
nodes/caesar.hexnode
Normal file
@@ -0,0 +1,219 @@
|
||||
{
|
||||
"attrs": [
|
||||
76,
|
||||
77,
|
||||
78
|
||||
],
|
||||
"data": {
|
||||
"nodes": {
|
||||
"links": {
|
||||
"31": {
|
||||
"from": 54,
|
||||
"id": 31,
|
||||
"to": 55
|
||||
},
|
||||
"33": {
|
||||
"from": 59,
|
||||
"id": 33,
|
||||
"to": 56
|
||||
},
|
||||
"34": {
|
||||
"from": 60,
|
||||
"id": 34,
|
||||
"to": 57
|
||||
},
|
||||
"40": {
|
||||
"from": 68,
|
||||
"id": 40,
|
||||
"to": 53
|
||||
},
|
||||
"41": {
|
||||
"from": 66,
|
||||
"id": 41,
|
||||
"to": 69
|
||||
},
|
||||
"42": {
|
||||
"from": 66,
|
||||
"id": 42,
|
||||
"to": 63
|
||||
},
|
||||
"43": {
|
||||
"from": 58,
|
||||
"id": 43,
|
||||
"to": 71
|
||||
},
|
||||
"44": {
|
||||
"from": 70,
|
||||
"id": 44,
|
||||
"to": 72
|
||||
},
|
||||
"45": {
|
||||
"from": 73,
|
||||
"id": 45,
|
||||
"to": 64
|
||||
},
|
||||
"46": {
|
||||
"from": 65,
|
||||
"id": 46,
|
||||
"to": 75
|
||||
}
|
||||
},
|
||||
"nodes": {
|
||||
"19": {
|
||||
"attrs": [
|
||||
66
|
||||
],
|
||||
"data": {
|
||||
"name": "Input",
|
||||
"type": 2
|
||||
},
|
||||
"id": 19,
|
||||
"name": "Input",
|
||||
"pos": {
|
||||
"x": 48.0,
|
||||
"y": 151.0
|
||||
},
|
||||
"type": "hex.builtin.nodes.custom.input"
|
||||
},
|
||||
"20": {
|
||||
"attrs": [
|
||||
68
|
||||
],
|
||||
"data": {
|
||||
"name": "Count",
|
||||
"type": 0
|
||||
},
|
||||
"id": 20,
|
||||
"name": "Count",
|
||||
"pos": {
|
||||
"x": 50.0,
|
||||
"y": 264.0
|
||||
},
|
||||
"type": "hex.builtin.nodes.custom.input"
|
||||
},
|
||||
"21": {
|
||||
"attrs": [
|
||||
53,
|
||||
54
|
||||
],
|
||||
"data": null,
|
||||
"id": 21,
|
||||
"name": "hex.builtin.nodes.casting.int_to_buffer.header",
|
||||
"pos": {
|
||||
"x": 212.0,
|
||||
"y": 315.0
|
||||
},
|
||||
"type": "hex.builtin.nodes.casting.int_to_buffer"
|
||||
},
|
||||
"22": {
|
||||
"attrs": [
|
||||
55,
|
||||
56,
|
||||
57,
|
||||
58
|
||||
],
|
||||
"data": null,
|
||||
"id": 22,
|
||||
"name": "hex.builtin.nodes.buffer.slice.header",
|
||||
"pos": {
|
||||
"x": 384.0,
|
||||
"y": 375.0
|
||||
},
|
||||
"type": "hex.builtin.nodes.buffer.slice"
|
||||
},
|
||||
"23": {
|
||||
"attrs": [
|
||||
59
|
||||
],
|
||||
"data": {
|
||||
"data": 0
|
||||
},
|
||||
"id": 23,
|
||||
"name": "hex.builtin.nodes.constants.int.header",
|
||||
"pos": {
|
||||
"x": 122.0,
|
||||
"y": 423.0
|
||||
},
|
||||
"type": "hex.builtin.nodes.constants.int"
|
||||
},
|
||||
"24": {
|
||||
"attrs": [
|
||||
60
|
||||
],
|
||||
"data": {
|
||||
"data": 1
|
||||
},
|
||||
"id": 24,
|
||||
"name": "hex.builtin.nodes.constants.int.header",
|
||||
"pos": {
|
||||
"x": 120.0,
|
||||
"y": 510.0
|
||||
},
|
||||
"type": "hex.builtin.nodes.constants.int"
|
||||
},
|
||||
"25": {
|
||||
"attrs": [
|
||||
63,
|
||||
64,
|
||||
65
|
||||
],
|
||||
"data": null,
|
||||
"id": 25,
|
||||
"name": "hex.builtin.nodes.bitwise.add.header",
|
||||
"pos": {
|
||||
"x": 720.0,
|
||||
"y": 183.0
|
||||
},
|
||||
"type": "hex.builtin.nodes.bitwise.add"
|
||||
},
|
||||
"26": {
|
||||
"attrs": [
|
||||
69,
|
||||
70
|
||||
],
|
||||
"data": null,
|
||||
"id": 26,
|
||||
"name": "hex.builtin.nodes.buffer.size.header",
|
||||
"pos": {
|
||||
"x": 383.0,
|
||||
"y": 274.0
|
||||
},
|
||||
"type": "hex.builtin.nodes.buffer.size"
|
||||
},
|
||||
"27": {
|
||||
"attrs": [
|
||||
71,
|
||||
72,
|
||||
73
|
||||
],
|
||||
"data": null,
|
||||
"id": 27,
|
||||
"name": "hex.builtin.nodes.buffer.repeat.header",
|
||||
"pos": {
|
||||
"x": 595.0,
|
||||
"y": 445.0
|
||||
},
|
||||
"type": "hex.builtin.nodes.buffer.repeat"
|
||||
},
|
||||
"28": {
|
||||
"attrs": [
|
||||
75
|
||||
],
|
||||
"data": {
|
||||
"name": "Output",
|
||||
"type": 2
|
||||
},
|
||||
"id": 28,
|
||||
"name": "Output",
|
||||
"pos": {
|
||||
"x": 864.0,
|
||||
"y": 330.0
|
||||
},
|
||||
"type": "hex.builtin.nodes.custom.output"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Caesar Cipher",
|
||||
"type": "hex.builtin.nodes.custom.custom"
|
||||
}
|
||||
223
nodes/xor.hexnode
Normal file
223
nodes/xor.hexnode
Normal file
@@ -0,0 +1,223 @@
|
||||
{
|
||||
"attrs": [
|
||||
36,
|
||||
37,
|
||||
38
|
||||
],
|
||||
"data": {
|
||||
"nodes": {
|
||||
"links": {
|
||||
"11": {
|
||||
"from": 20,
|
||||
"id": 11,
|
||||
"to": 22
|
||||
},
|
||||
"13": {
|
||||
"from": 23,
|
||||
"id": 13,
|
||||
"to": 32
|
||||
},
|
||||
"14": {
|
||||
"from": 17,
|
||||
"id": 14,
|
||||
"to": 19
|
||||
},
|
||||
"15": {
|
||||
"from": 14,
|
||||
"id": 15,
|
||||
"to": 15
|
||||
},
|
||||
"16": {
|
||||
"from": 12,
|
||||
"id": 16,
|
||||
"to": 16
|
||||
},
|
||||
"17": {
|
||||
"from": 9,
|
||||
"id": 17,
|
||||
"to": 11
|
||||
},
|
||||
"18": {
|
||||
"from": 7,
|
||||
"id": 18,
|
||||
"to": 10
|
||||
},
|
||||
"19": {
|
||||
"from": 31,
|
||||
"id": 19,
|
||||
"to": 8
|
||||
},
|
||||
"20": {
|
||||
"from": 30,
|
||||
"id": 20,
|
||||
"to": 6
|
||||
},
|
||||
"22": {
|
||||
"from": 31,
|
||||
"id": 22,
|
||||
"to": 18
|
||||
},
|
||||
"23": {
|
||||
"from": 30,
|
||||
"id": 23,
|
||||
"to": 21
|
||||
}
|
||||
},
|
||||
"nodes": {
|
||||
"10": {
|
||||
"attrs": [
|
||||
14
|
||||
],
|
||||
"data": {
|
||||
"data": 1
|
||||
},
|
||||
"id": 10,
|
||||
"name": "hex.builtin.nodes.constants.int.header",
|
||||
"pos": {
|
||||
"x": 430.0,
|
||||
"y": 364.0
|
||||
},
|
||||
"type": "hex.builtin.nodes.constants.int"
|
||||
},
|
||||
"11": {
|
||||
"attrs": [
|
||||
15,
|
||||
16,
|
||||
17
|
||||
],
|
||||
"data": null,
|
||||
"id": 11,
|
||||
"name": "hex.builtin.nodes.arithmetic.add.header",
|
||||
"pos": {
|
||||
"x": 579.0,
|
||||
"y": 421.0
|
||||
},
|
||||
"type": "hex.builtin.nodes.arithmetic.add"
|
||||
},
|
||||
"12": {
|
||||
"attrs": [
|
||||
18,
|
||||
19,
|
||||
20
|
||||
],
|
||||
"data": null,
|
||||
"id": 12,
|
||||
"name": "hex.builtin.nodes.buffer.repeat.header",
|
||||
"pos": {
|
||||
"x": 661.0,
|
||||
"y": 241.0
|
||||
},
|
||||
"type": "hex.builtin.nodes.buffer.repeat"
|
||||
},
|
||||
"13": {
|
||||
"attrs": [
|
||||
21,
|
||||
22,
|
||||
23
|
||||
],
|
||||
"data": null,
|
||||
"id": 13,
|
||||
"name": "hex.builtin.nodes.bitwise.xor.header",
|
||||
"pos": {
|
||||
"x": 818.0,
|
||||
"y": 163.0
|
||||
},
|
||||
"type": "hex.builtin.nodes.bitwise.xor"
|
||||
},
|
||||
"14": {
|
||||
"attrs": [
|
||||
32
|
||||
],
|
||||
"data": {
|
||||
"name": "Output",
|
||||
"type": 2
|
||||
},
|
||||
"id": 14,
|
||||
"name": "Output",
|
||||
"pos": {
|
||||
"x": 1000.0,
|
||||
"y": 432.0
|
||||
},
|
||||
"type": "hex.builtin.nodes.custom.output"
|
||||
},
|
||||
"4": {
|
||||
"attrs": [
|
||||
30
|
||||
],
|
||||
"data": {
|
||||
"name": "Input",
|
||||
"type": 2
|
||||
},
|
||||
"id": 4,
|
||||
"name": "Input",
|
||||
"pos": {
|
||||
"x": 82.0,
|
||||
"y": 139.0
|
||||
},
|
||||
"type": "hex.builtin.nodes.custom.input"
|
||||
},
|
||||
"5": {
|
||||
"attrs": [
|
||||
31
|
||||
],
|
||||
"data": {
|
||||
"name": "XOR Pad",
|
||||
"type": 2
|
||||
},
|
||||
"id": 5,
|
||||
"name": "XOR Pad",
|
||||
"pos": {
|
||||
"x": 89.0,
|
||||
"y": 328.0
|
||||
},
|
||||
"type": "hex.builtin.nodes.custom.input"
|
||||
},
|
||||
"6": {
|
||||
"attrs": [
|
||||
6,
|
||||
7
|
||||
],
|
||||
"data": null,
|
||||
"id": 6,
|
||||
"name": "hex.builtin.nodes.buffer.size.header",
|
||||
"pos": {
|
||||
"x": 269.0,
|
||||
"y": 403.0
|
||||
},
|
||||
"type": "hex.builtin.nodes.buffer.size"
|
||||
},
|
||||
"7": {
|
||||
"attrs": [
|
||||
8,
|
||||
9
|
||||
],
|
||||
"data": null,
|
||||
"id": 7,
|
||||
"name": "hex.builtin.nodes.buffer.size.header",
|
||||
"pos": {
|
||||
"x": 267.0,
|
||||
"y": 486.0
|
||||
},
|
||||
"type": "hex.builtin.nodes.buffer.size"
|
||||
},
|
||||
"8": {
|
||||
"attrs": [
|
||||
10,
|
||||
11,
|
||||
12
|
||||
],
|
||||
"data": null,
|
||||
"id": 8,
|
||||
"name": "hex.builtin.nodes.arithmetic.div.header",
|
||||
"pos": {
|
||||
"x": 409.0,
|
||||
"y": 465.0
|
||||
},
|
||||
"type": "hex.builtin.nodes.arithmetic.div"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "XOR Pad",
|
||||
"type": "hex.builtin.nodes.custom.custom"
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma endian little
|
||||
|
||||
#include <std/io.pat>
|
||||
#include <std/sys.pat>
|
||||
|
||||
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC "AFE2"
|
||||
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_1 "AFE1"
|
||||
@@ -54,4 +55,4 @@ std::assert_warn(ctx.magic == ATMOSPHERE_REBOOT_TO_FATAL_MAGIC,
|
||||
|
||||
|
||||
std::print("Error Description: 0x{:04X}", ctx.error_desc);
|
||||
std::print("Program ID: {:016X}", ctx.program_id);
|
||||
std::print("Program ID: {:016X}", ctx.program_id);
|
||||
|
||||
208
patterns/bsp_goldsrc.hexpat
Normal file
208
patterns/bsp_goldsrc.hexpat
Normal file
@@ -0,0 +1,208 @@
|
||||
#include <std/ptr.pat>
|
||||
#include <std/mem.pat>
|
||||
#include <std/sys.pat>
|
||||
|
||||
#pragma endian little
|
||||
|
||||
#define HEADER_LUMPS 15
|
||||
#define MAX_MAP_HULLS 4
|
||||
#define NUM_AMBIENTS 4
|
||||
#define MAXLIGHTMAPS 4
|
||||
|
||||
enum LumpIndex : u32 {
|
||||
Entities,
|
||||
Planes,
|
||||
Textures,
|
||||
Vertexes,
|
||||
Visibility,
|
||||
Nodes,
|
||||
Texinfo,
|
||||
Faces,
|
||||
Lighting,
|
||||
Clipnodes,
|
||||
Leafs,
|
||||
Marksurfaces,
|
||||
Edges,
|
||||
Surfedges,
|
||||
Models,
|
||||
};
|
||||
|
||||
struct vec3f
|
||||
{
|
||||
float x, y, z;
|
||||
};
|
||||
|
||||
struct dlump_t
|
||||
{
|
||||
s32 fileofs;
|
||||
s32 filelen;
|
||||
};
|
||||
|
||||
struct dheader_t
|
||||
{
|
||||
s32 version;
|
||||
dlump_t lumps[HEADER_LUMPS];
|
||||
std::assert(version == 30, "This version of BSP format is unsupported.");
|
||||
};
|
||||
|
||||
struct dmodel_t
|
||||
{
|
||||
vec3f mins;
|
||||
vec3f maxs;
|
||||
vec3f origin; // for sounds or lights
|
||||
s32 headnode[MAX_MAP_HULLS];
|
||||
s32 visleafs; // not including the solid leaf 0
|
||||
s32 firstface;
|
||||
s32 numfaces;
|
||||
};
|
||||
|
||||
struct dplane_t
|
||||
{
|
||||
vec3f normal;
|
||||
float dist;
|
||||
s32 type;
|
||||
};
|
||||
|
||||
struct dtexinfo_t
|
||||
{
|
||||
float vecs[8]; // texmatrix [s/t][xyz offset]
|
||||
s32 miptex;
|
||||
s16 flags;
|
||||
s16 faceinfo; // -1 no face info otherwise dfaceinfo_t
|
||||
};
|
||||
|
||||
struct dleaf_t
|
||||
{
|
||||
s32 contents;
|
||||
s32 visofs; // -1 = no visibility info
|
||||
s16 mins[3];
|
||||
s16 maxs[3];
|
||||
u16 firstmarksurface;
|
||||
u16 nummarksurfaces;
|
||||
u8 ambient_level[NUM_AMBIENTS];
|
||||
};
|
||||
|
||||
struct dnode_t
|
||||
{
|
||||
s32 planenum;
|
||||
s16 children[2]; // negative numbers are -(leafs + 1), not nodes
|
||||
s16 mins[3];
|
||||
s16 maxs[3];
|
||||
u16 firstface;
|
||||
u16 numfaces; // counting both sides
|
||||
};
|
||||
|
||||
struct dface_t
|
||||
{
|
||||
u16 planenum;
|
||||
s16 side;
|
||||
s32 firstedge;
|
||||
s16 numedges;
|
||||
s16 texinfo;
|
||||
u8 styles[MAXLIGHTMAPS];
|
||||
s32 lightofs; // start of [numstyles*surfsize] samples
|
||||
};
|
||||
|
||||
struct dedge_t
|
||||
{
|
||||
u16 v[2]; // indices of vertexes
|
||||
};
|
||||
|
||||
struct dclipnode_t
|
||||
{
|
||||
s32 planenum;
|
||||
s16 children[2];
|
||||
};
|
||||
|
||||
using dmarkface_t = u16;
|
||||
using dsurfedge_t = s32;
|
||||
using dvertex_t = vec3f;
|
||||
|
||||
fn get_miptex_pixeldata_size(auto width, auto height, auto offset) {
|
||||
if (offset != 0) {
|
||||
return std::mem::align_to(4, width * height * 85 / 64 + sizeof(u16) + 768);
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct miptex_t
|
||||
{
|
||||
char name[16];
|
||||
u32 width;
|
||||
u32 height;
|
||||
u32 offsets[4]; // four mip maps stored
|
||||
u8 pixeldata[get_miptex_pixeldata_size(width, height, offsets[0])];
|
||||
};
|
||||
|
||||
dheader_t file_header @ 0x00;
|
||||
|
||||
fn get_lump_element_count(auto index, auto elem_size) {
|
||||
return file_header.lumps[index].filelen / elem_size;
|
||||
};
|
||||
|
||||
fn get_lump_address(auto index) {
|
||||
return file_header.lumps[index].fileofs;
|
||||
};
|
||||
|
||||
fn get_miptex_ptr_base(auto offset) {
|
||||
return file_header.lumps[LumpIndex::Textures].fileofs;
|
||||
};
|
||||
|
||||
struct MiptexPointer
|
||||
{
|
||||
miptex_t *data: u32 [[pointer_base("get_miptex_ptr_base"), inline]];
|
||||
};
|
||||
|
||||
struct dmiptexlump_t
|
||||
{
|
||||
s32 nummiptex;
|
||||
MiptexPointer dataofs[nummiptex];
|
||||
};
|
||||
|
||||
struct VisibilityData
|
||||
{
|
||||
u8 data[file_header.lumps[LumpIndex::Visibility].filelen];
|
||||
u8 pad[std::mem::align_to(4, sizeof(this)) - sizeof(this)];
|
||||
};
|
||||
|
||||
struct LightmapData
|
||||
{
|
||||
u8 data[file_header.lumps[LumpIndex::Lighting].filelen];
|
||||
u8 pad[std::mem::align_to(4, sizeof(this)) - sizeof(this)];
|
||||
};
|
||||
|
||||
struct EntityData
|
||||
{
|
||||
char text[];
|
||||
u8 pad[std::mem::align_to(4, sizeof(this)) - sizeof(this)];
|
||||
};
|
||||
|
||||
s32 models_count = get_lump_element_count(LumpIndex::Models, sizeof(dmodel_t));
|
||||
s32 vertexes_count = get_lump_element_count(LumpIndex::Vertexes, sizeof(vec3f));
|
||||
s32 planes_count = get_lump_element_count(LumpIndex::Planes, sizeof(dplane_t));
|
||||
s32 leafs_count = get_lump_element_count(LumpIndex::Leafs, sizeof(dleaf_t));
|
||||
s32 nodes_count = get_lump_element_count(LumpIndex::Nodes, sizeof(dnode_t));
|
||||
s32 faces_count = get_lump_element_count(LumpIndex::Faces, sizeof(dface_t));
|
||||
s32 markfaces_count = get_lump_element_count(LumpIndex::Marksurfaces, sizeof(dmarkface_t));
|
||||
s32 surfedges_count = get_lump_element_count(LumpIndex::Surfedges, sizeof(dsurfedge_t));
|
||||
s32 edges_count = get_lump_element_count(LumpIndex::Edges, sizeof(dedge_t));
|
||||
s32 clipnodes_count = get_lump_element_count(LumpIndex::Clipnodes, sizeof(dclipnode_t));
|
||||
s32 texinfo_count = get_lump_element_count(LumpIndex::Texinfo, sizeof(dtexinfo_t));
|
||||
|
||||
dmodel_t models_lump[models_count] @ get_lump_address(LumpIndex::Models);
|
||||
dvertex_t vertexes_lump[vertexes_count] @ get_lump_address(LumpIndex::Vertexes);
|
||||
dplane_t planes_lump[planes_count] @ get_lump_address(LumpIndex::Planes);
|
||||
dleaf_t leafs_lump[leafs_count] @ get_lump_address(LumpIndex::Leafs);
|
||||
dnode_t nodes_lump[nodes_count] @ get_lump_address(LumpIndex::Nodes);
|
||||
dface_t faces_lump[faces_count] @ get_lump_address(LumpIndex::Faces);
|
||||
dmarkface_t markfaces_lump[markfaces_count] @ get_lump_address(LumpIndex::Marksurfaces);
|
||||
dsurfedge_t surfedges_lump[surfedges_count] @ get_lump_address(LumpIndex::Surfedges);
|
||||
dedge_t edges_lump[edges_count] @ get_lump_address(LumpIndex::Edges);
|
||||
dclipnode_t clipnodes_lump[clipnodes_count] @ get_lump_address(LumpIndex::Clipnodes);
|
||||
dtexinfo_t texinfo_lump[texinfo_count] @ get_lump_address(LumpIndex::Texinfo);
|
||||
dmiptexlump_t textures_lump @ get_lump_address(LumpIndex::Textures);
|
||||
VisibilityData visdata_lump @ get_lump_address(LumpIndex::Visibility);
|
||||
LightmapData lightdata_lump @ get_lump_address(LumpIndex::Lighting);
|
||||
EntityData entdata_lump @ get_lump_address(LumpIndex::Entities);
|
||||
30
patterns/cchva.hexpat
Normal file
30
patterns/cchva.hexpat
Normal file
@@ -0,0 +1,30 @@
|
||||
// Command and conquer voxel animation format
|
||||
|
||||
struct vec4_s {
|
||||
float x [[color("FF0000")]];
|
||||
float y [[color("00FF00")]];
|
||||
float z [[color("0000FF")]];
|
||||
float w [[color("FFFF00")]];
|
||||
};
|
||||
|
||||
struct mat3x4_s {
|
||||
vec4_s row[3];
|
||||
};
|
||||
|
||||
struct name_s {
|
||||
char buffer[16] [[color("EECCCC")]];
|
||||
};
|
||||
|
||||
struct hva_s {
|
||||
name_s name;
|
||||
u32 numFrames;
|
||||
u32 numNodes;
|
||||
name_s nodeNames[numNodes];
|
||||
};
|
||||
|
||||
struct frame_s {
|
||||
mat3x4_s mat[hva.numNodes];
|
||||
};
|
||||
|
||||
hva_s hva @0x00;
|
||||
frame_s frames[hva.numFrames] @sizeof(hva);
|
||||
13
patterns/ccpal.hexpat
Normal file
13
patterns/ccpal.hexpat
Normal file
@@ -0,0 +1,13 @@
|
||||
// Command and conquer palette format
|
||||
|
||||
struct Color {
|
||||
u8 r;
|
||||
u8 g;
|
||||
u8 b;
|
||||
};
|
||||
|
||||
struct Palette {
|
||||
Color colors[256];
|
||||
};
|
||||
|
||||
Palette pal @0x00;
|
||||
69
patterns/ccvxl.hexpat
Normal file
69
patterns/ccvxl.hexpat
Normal file
@@ -0,0 +1,69 @@
|
||||
// Command and Conquer voxel model format
|
||||
|
||||
struct vec4_s {
|
||||
float x [[color("FF0000")]];
|
||||
float y [[color("00FF00")]];
|
||||
float z [[color("0000FF")]];
|
||||
float w [[color("FFFF00")]];
|
||||
};
|
||||
|
||||
struct vec3_s {
|
||||
float x [[color("FF0000")]];
|
||||
float y [[color("00FF00")]];
|
||||
float z [[color("0000FF")]];
|
||||
};
|
||||
|
||||
struct mat3x4_s {
|
||||
vec4_s row[3];
|
||||
};
|
||||
|
||||
struct name_s {
|
||||
char buffer[16] [[color("EECCCC")]];
|
||||
};
|
||||
|
||||
struct color_s {
|
||||
u8 r;
|
||||
u8 g;
|
||||
u8 b;
|
||||
};
|
||||
|
||||
struct vxl_limb_header_s {
|
||||
name_s name;
|
||||
s32 limb_number;
|
||||
u32 _reserved1;
|
||||
u32 _reserved2;
|
||||
};
|
||||
|
||||
struct vxl_limb_tailer_s {
|
||||
u32 span_start_offset;
|
||||
u32 span_end_offset;
|
||||
u32 span_data_offset;
|
||||
float scale;
|
||||
mat3x4_s matrix;
|
||||
vec3_s min_bounds;
|
||||
vec3_s max_bounds;
|
||||
u8 xsize;
|
||||
u8 ysize;
|
||||
u8 zsize;
|
||||
u8 normal_type;
|
||||
};
|
||||
|
||||
struct vxl_s {
|
||||
name_s name;
|
||||
u32 palette_count;
|
||||
u32 limb_count;
|
||||
u32 tailer_count;
|
||||
u32 body_size;
|
||||
u8 remap_start_index;
|
||||
u8 remap_end_index;
|
||||
color_s internal_palette[256];
|
||||
vxl_limb_header_s _headers[limb_count];
|
||||
u8 body[body_size];
|
||||
vxl_limb_tailer_s _tailers[limb_count];
|
||||
};
|
||||
|
||||
struct frame_s {
|
||||
mat3x4_s mat[hva.numNodes];
|
||||
};
|
||||
|
||||
vxl_s vxl @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;
|
||||
};
|
||||
|
||||
enum Type : u16 {
|
||||
Null = 0,
|
||||
Void = 1,
|
||||
Char = 2,
|
||||
Short = 3,
|
||||
Int = 4,
|
||||
Long = 5,
|
||||
Float = 6,
|
||||
Double = 7,
|
||||
Struct = 8,
|
||||
Union = 9,
|
||||
Enum = 10,
|
||||
MOE = 11,
|
||||
Byte = 12,
|
||||
Word = 13,
|
||||
UInt = 14,
|
||||
DWord = 15
|
||||
};
|
||||
|
||||
enum StorageClass : u8 {
|
||||
EndOfFunction = 0xFF,
|
||||
Null = 0,
|
||||
Automatic = 1,
|
||||
External = 2,
|
||||
Static = 3,
|
||||
Register = 4,
|
||||
ExternalDef = 5,
|
||||
Label = 6,
|
||||
UndefinedLabel = 7,
|
||||
MemberOfStruct = 8,
|
||||
Argument = 9,
|
||||
StructTag = 10,
|
||||
MemberOfUnion = 11,
|
||||
UnionTag = 12,
|
||||
TypeDefinition = 13,
|
||||
UndefinedStatic = 14,
|
||||
EnumTag = 15,
|
||||
MemberOfEnum = 16,
|
||||
RegisterParam = 17,
|
||||
BitField = 18,
|
||||
Block = 100,
|
||||
Function = 101,
|
||||
EndOfStruct = 102,
|
||||
File = 103,
|
||||
Section = 104,
|
||||
WeakExternal = 105,
|
||||
CLRToken = 107
|
||||
};
|
||||
|
||||
struct AuxSymbol {
|
||||
u8 data[18];
|
||||
};
|
||||
|
||||
u32 countedSymbols = 0;
|
||||
struct SymbolTable {
|
||||
char name[8];
|
||||
u32 value;
|
||||
u16 sectionNumber;
|
||||
Type type;
|
||||
StorageClass storageClass;
|
||||
u8 numberOfAuxSymbols;
|
||||
|
||||
countedSymbols += 1 + numberOfAuxSymbols;
|
||||
|
||||
AuxSymbol auxSymbols[numberOfAuxSymbols];
|
||||
|
||||
if (countedSymbols >= parent.header.numberOfSymbols)
|
||||
break;
|
||||
};
|
||||
|
||||
struct String {
|
||||
char value[];
|
||||
};
|
||||
|
||||
struct StringTable {
|
||||
u32 size;
|
||||
String strings[while($ < addressof(size) + size)];
|
||||
};
|
||||
|
||||
bitfield SectionFlags {
|
||||
padding : 3;
|
||||
typeNoPad : 1;
|
||||
padding : 1;
|
||||
cntCode : 1;
|
||||
initializedData : 1;
|
||||
uninitializedData : 1;
|
||||
lnkOther : 1;
|
||||
lnkInfo : 1;
|
||||
padding : 1;
|
||||
lnkRemove : 1;
|
||||
lnkCOMDAT : 1;
|
||||
padding : 2;
|
||||
gprel : 1;
|
||||
padding : 1;
|
||||
memPurgeable : 1;
|
||||
memLocked : 1;
|
||||
memPreload : 1;
|
||||
alignment : 4 [[format("format_alignment")]];
|
||||
lnkNrelocOvfl : 1;
|
||||
memDiscardable : 1;
|
||||
memNotCached : 1;
|
||||
memNotPaged : 1;
|
||||
memShared : 1;
|
||||
memExecute : 1;
|
||||
memRead : 1;
|
||||
memWrite : 1;
|
||||
};
|
||||
|
||||
fn format_alignment(u8 alignment) {
|
||||
return 1 << alignment;
|
||||
};
|
||||
|
||||
struct Relocations {
|
||||
u32 virtualAddress;
|
||||
u32 symbolTableIndex;
|
||||
Type type;
|
||||
};
|
||||
|
||||
struct Section {
|
||||
char name[8];
|
||||
type::Size<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 {
|
||||
x : 3;
|
||||
w : 3;
|
||||
r : 3;
|
||||
sticky : 1;
|
||||
sgid : 1;
|
||||
suid : 1;
|
||||
file_type : 4;
|
||||
};
|
||||
|
||||
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;
|
||||
174
patterns/dex.hexpat
Normal file
174
patterns/dex.hexpat
Normal file
@@ -0,0 +1,174 @@
|
||||
#include <type/leb128.pat>
|
||||
|
||||
struct header_item {
|
||||
u8 magic[8];
|
||||
u32 checksum;
|
||||
u8 signature[20];
|
||||
u32 file_size;
|
||||
u32 header_size;
|
||||
u32 endian_tag;
|
||||
u32 link_size;
|
||||
u32 link_off;
|
||||
u32 map_off;
|
||||
u32 string_ids_size;
|
||||
u32 string_ids_off;
|
||||
u32 type_ids_size;
|
||||
u32 type_ids_off;
|
||||
u32 proto_ids_size;
|
||||
u32 proto_ids_off;
|
||||
u32 field_ids_size;
|
||||
u32 field_ids_off;
|
||||
u32 method_ids_size;
|
||||
u32 method_ids_off;
|
||||
u32 class_defs_size;
|
||||
u32 class_defs_off;
|
||||
u32 data_size;
|
||||
u32 data_off;
|
||||
};
|
||||
|
||||
struct map_item {
|
||||
u16 type;
|
||||
u16 unused;
|
||||
u32 size;
|
||||
u32 offset;
|
||||
};
|
||||
|
||||
struct map_list {
|
||||
u32 size;
|
||||
map_item list[size];
|
||||
};
|
||||
|
||||
struct string_data_item {
|
||||
type::uLEB128 utf16_size[[hidden]];
|
||||
char string[utf16_size];
|
||||
}[[inline]];
|
||||
|
||||
struct string_id_item {
|
||||
string_data_item* string_data: u32;
|
||||
}[[name(string_data.string)]];
|
||||
|
||||
|
||||
struct type_id_item {
|
||||
u32 descriptor_idx;
|
||||
char type_name[] @ addressof(parent.string_ids[descriptor_idx].string_data.string);
|
||||
}[[name(type_name)]];
|
||||
|
||||
struct proto_id_item {
|
||||
u32 shorty_idx;
|
||||
u32 return_type_idx;
|
||||
u32 parameters_off;
|
||||
char shorty_dec[] @ addressof(parent.string_ids[shorty_idx].string_data.string);
|
||||
char return_type[] @ addressof(parent.type_ids[return_type_idx].type_name);
|
||||
}[[name(shorty_dec)]];
|
||||
|
||||
struct field_id_item {
|
||||
u16 class_idx;
|
||||
u16 type_idx;
|
||||
u32 name_idx;
|
||||
char class_name[] @ addressof(parent.type_ids[class_idx].type_name);
|
||||
char type_name[] @ addressof(parent.type_ids[type_idx].type_name);
|
||||
char field_name[] @ addressof(parent.string_ids[name_idx].string_data.string);
|
||||
}[[name(field_name)]];
|
||||
|
||||
struct method_id_item {
|
||||
u16 class_idx;
|
||||
u16 proto_idx;
|
||||
u32 name_idx;
|
||||
char class_name[] @ addressof(parent.type_ids[class_idx].type_name);
|
||||
char proto_desc[] @ addressof(parent.proto_ids[proto_idx].shorty_dec);
|
||||
char method_name[] @ addressof(parent.string_ids[name_idx].string_data.string);
|
||||
|
||||
}[[name(class_name+method_name)]];
|
||||
|
||||
struct class_site_id_item {
|
||||
u32 call_site_off;
|
||||
};
|
||||
|
||||
struct method_handle_item {
|
||||
u16 method_handle_type;
|
||||
u16 unused;
|
||||
u16 field_or_method_id;
|
||||
u16 unused2;
|
||||
};
|
||||
enum access_flag : type::uLEB128{
|
||||
public = 0x1,
|
||||
private = 0x2,
|
||||
protected = 0x4,
|
||||
static = 0x8,
|
||||
final = 0x10,
|
||||
synchronized = 0x20,
|
||||
volatile = 0x40
|
||||
};
|
||||
|
||||
struct encoded_field {
|
||||
type::uLEB128 field_idx_diff;
|
||||
access_flag access_flags;
|
||||
};
|
||||
|
||||
struct encoded_method {
|
||||
type::uLEB128 method_idx_diff;
|
||||
type::uLEB128 access_flags;
|
||||
type::uLEB128 code_off;
|
||||
};
|
||||
|
||||
struct class_data_item {
|
||||
type::uLEB128 static_fields_size;
|
||||
type::uLEB128 instance_fields_size;
|
||||
type::uLEB128 direct_methods_size;
|
||||
type::uLEB128 virtual_methods_size;
|
||||
encoded_field static_fields[static_fields_size];
|
||||
encoded_field instance_fields[instance_fields_size];
|
||||
encoded_method direct_methods[direct_methods_size];
|
||||
encoded_method virtual_methods[virtual_methods_size];
|
||||
};
|
||||
|
||||
struct class_def_item {
|
||||
u32 class_idx;
|
||||
u32 access_flags;
|
||||
u32 superclass_idx;
|
||||
u32 interfaces_off;
|
||||
u32 source_file_idx;
|
||||
u32 annotations_off;
|
||||
u32 class_data_off;
|
||||
//class_data_item *class_data_off:u32;
|
||||
u32 static_values_off;
|
||||
char class_name[] @ addressof(parent.type_ids[class_idx].type_name);
|
||||
}[[name(class_name)]];
|
||||
|
||||
struct type_item {
|
||||
u16 type_idx;
|
||||
};
|
||||
|
||||
struct type_list {
|
||||
u32 size;
|
||||
type_item list[size];
|
||||
};
|
||||
|
||||
struct code_item {
|
||||
u16 registers_size;
|
||||
u16 ins_size;
|
||||
u16 outs_size;
|
||||
u16 tries_size;
|
||||
u32 debug_info_off;
|
||||
u32 insns_size;
|
||||
u16 insns[insns_size];
|
||||
};
|
||||
|
||||
struct try_item {
|
||||
u32 start_addr;
|
||||
u16 insn_count;
|
||||
u16 handler_off;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct Dex {
|
||||
header_item header;
|
||||
string_id_item string_ids[header.string_ids_size] @ header.string_ids_off;
|
||||
type_id_item type_ids[header.type_ids_size] @ header.type_ids_off;
|
||||
proto_id_item proto_ids[header.proto_ids_size] @ header.proto_ids_off;
|
||||
field_id_item field_ids[header.field_ids_size] @ header.field_ids_off;
|
||||
method_id_item method_ids[header.method_ids_size] @ header.method_ids_off;
|
||||
class_def_item class_defs[header.class_defs_size] @ header.class_defs_off;
|
||||
};
|
||||
Dex dex @ 0x00;
|
||||
49
patterns/dmg.hexpat
Normal file
49
patterns/dmg.hexpat
Normal file
@@ -0,0 +1,49 @@
|
||||
#pragma endian big
|
||||
|
||||
#include <type/magic.pat>
|
||||
#include <type/size.pat>
|
||||
#include <type/guid.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
// Parse DMG Structure per http://newosxbook.com/DMG.html
|
||||
//
|
||||
// UDIFResourceFile starts at size(file) - 512
|
||||
struct UDIFResourceFile {
|
||||
type::Magic<"koly"> Signature; // Magic ('koly')
|
||||
u32 Version; // Current version is 4
|
||||
type::Size<u32> HeaderSize; // sizeof(this), always 512
|
||||
u32 Flags;
|
||||
u64 RunningDataForkOffset; //
|
||||
u64 DataForkOffset; // Data fork offset (usually 0, beginning of file)
|
||||
type::Size<u64> DataForkLength; // Size of data fork (usually up to the XMLOffset, below)
|
||||
u64 RsrcForkOffset; // Resource fork offset, if any
|
||||
type::Size<u64> RsrcForkLength; // Resource fork length, if any
|
||||
u32 SegmentNumber; // Usually 1, may be 0
|
||||
u32 SegmentCount; // Usually 1, may be 0
|
||||
type::GUID SegmentID; // 128-bit GUID identifier of segment (if SegmentNumber !=0)
|
||||
|
||||
|
||||
u32 DataChecksumType; // Data fork
|
||||
type::Size<u32> DataChecksumSize; // Checksum Information
|
||||
u32 DataChecksum[DataChecksumSize]; // Up to 128-bytes (32 x 4) of checksum
|
||||
|
||||
u64 XMLOffset; // Offset of property list in DMG, from beginning
|
||||
type::Size<u64> XMLLength; // Length of property list
|
||||
u8 Reserved1[120]; // 120 reserved bytes - zeroed
|
||||
|
||||
u32 ChecksumType; // Master
|
||||
type::Size<u32> ChecksumSize; // Checksum information
|
||||
u32 Checksum[ChecksumSize]; // Up to 128-bytes (32 x 4) of checksum
|
||||
|
||||
u32 ImageVariant; // Commonly 1
|
||||
u64 SectorCount; // Size of DMG when expanded, in sectors
|
||||
|
||||
u32 reserved2; // 0
|
||||
u32 reserved3; // 0
|
||||
u32 reserved4; // 0
|
||||
};
|
||||
|
||||
|
||||
UDIFResourceFile trailer @ std::mem::size() - 512;
|
||||
|
||||
char metadata_plist[trailer.XMLLength] @ trailer.XMLOffset;
|
||||
113
patterns/dsstore.hexpat
Normal file
113
patterns/dsstore.hexpat
Normal file
@@ -0,0 +1,113 @@
|
||||
// Apple macOS .DS_Store format
|
||||
#pragma endian big
|
||||
#include <std/io.pat>
|
||||
|
||||
struct RecordEntry {
|
||||
u32 length;
|
||||
char16 filename[length];
|
||||
|
||||
char id[4];
|
||||
// either blob or length
|
||||
char type[4];
|
||||
|
||||
if (type == "blob") {
|
||||
u32 blobCount;
|
||||
u8 blobData[blobCount];
|
||||
}
|
||||
else if (type == "long") {
|
||||
u32 value;
|
||||
}
|
||||
else if (type == "shor") {
|
||||
u32 value;
|
||||
}
|
||||
else if (type == "bool") {
|
||||
u8 value;
|
||||
}
|
||||
};
|
||||
|
||||
struct TreeBlock {
|
||||
u32 mode;
|
||||
u32 count;
|
||||
RecordEntry entries[count];
|
||||
};
|
||||
|
||||
struct BuddyRootBlockOffsets {
|
||||
u32 count;
|
||||
u8 reserved[4];
|
||||
u32 addresses[count];
|
||||
padding[(1024 - (count * 4))];
|
||||
};
|
||||
|
||||
struct BuddyTableOfContentEntry {
|
||||
u8 count;
|
||||
char name[count];
|
||||
u32 value;
|
||||
};
|
||||
|
||||
struct BuddyTableOfContents {
|
||||
u32 count;
|
||||
BuddyTableOfContentEntry toc[count];
|
||||
};
|
||||
|
||||
struct BuddyFreeList {
|
||||
u32 count;
|
||||
u32 offsets[count];
|
||||
};
|
||||
|
||||
struct BuddyRootBlock {
|
||||
BuddyRootBlockOffsets offsets;
|
||||
BuddyTableOfContents toc;
|
||||
BuddyFreeList freelists[32];
|
||||
};
|
||||
|
||||
struct BuddyBlock {
|
||||
u32 blockCount;
|
||||
u8 reserved[4];
|
||||
// padding for next multiple of 256 entries (1024 bytes)
|
||||
u32 addresses[blockCount];
|
||||
|
||||
// u8 padding[paddingCount];
|
||||
u32 directoryCount;
|
||||
|
||||
// directory entries
|
||||
u8 count;
|
||||
u8 name[count];
|
||||
u32 blockNumber;
|
||||
|
||||
// free lists
|
||||
// 32 free lists
|
||||
BuddyRootBlockOffsets off[32];
|
||||
};
|
||||
|
||||
struct BlocksList {
|
||||
u32 blockId [[color("E57373")]];
|
||||
u32 internalBlocks [[color("80CBC4")]];
|
||||
u32 countRecords [[color("ffeb3b")]];
|
||||
u32 countBlocks [[color("64b5f6")]];
|
||||
u32 reserved [[color("a1887f")]];
|
||||
};
|
||||
|
||||
struct BuddyAllocator {
|
||||
char header[4];
|
||||
u32 offsetBookkeeping;
|
||||
u32 sizeBookkeeping;
|
||||
u32 offsetBookkeeping2;
|
||||
u32 offsetData;
|
||||
u8 reserved[12];
|
||||
|
||||
BuddyRootBlock root @ offsetBookkeeping + 4;
|
||||
|
||||
std::print("TOC {} address 0x{:08x}",
|
||||
root.toc.toc[0].value,
|
||||
root.offsets.addresses[root.toc.toc[0].value] >> 0x5 << 0x5);
|
||||
|
||||
BlocksList blocks @ (root.offsets.addresses[root.toc.toc[0].value] >> 0x5 << 0x5) + 4;
|
||||
|
||||
std::print("Blocks start at address 0x{:08x}, size 0x{:04x}",
|
||||
root.offsets.addresses[blocks.blockId] >> 0x5 << 0x5,
|
||||
1 << (root.offsets.addresses[blocks.blockId] & 0x1f));
|
||||
|
||||
TreeBlock entries @ (root.offsets.addresses[blocks.blockId] >> 0x5 << 0x5) + 4;
|
||||
};
|
||||
|
||||
BuddyAllocator buddy @0x04;
|
||||
@@ -5,8 +5,11 @@
|
||||
#pragma MIME application/x-sharedlib
|
||||
|
||||
#include <std/core.pat>
|
||||
#include <std/io.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
using BitfieldOrder = std::core::BitfieldOrder;
|
||||
|
||||
using EI_ABIVERSION = u8;
|
||||
using Elf32_Addr = u32;
|
||||
using Elf32_BaseAddr = u32;
|
||||
@@ -457,37 +460,37 @@ enum VER_NEED : Elf32_Half {
|
||||
};
|
||||
|
||||
bitfield SYMINFO_FLG {
|
||||
padding : 10;
|
||||
NOEXTDIRECT : 1;
|
||||
DIRECTBIND : 1;
|
||||
LAZYLOAD : 1;
|
||||
COPY : 1;
|
||||
RESERVED : 1;
|
||||
DIRECT : 1;
|
||||
} [[left_to_right]];
|
||||
RESERVED : 1;
|
||||
COPY : 1;
|
||||
LAZYLOAD : 1;
|
||||
DIRECTBIND : 1;
|
||||
NOEXTDIRECT : 1;
|
||||
padding : 10;
|
||||
};
|
||||
|
||||
bitfield ST {
|
||||
ST_BIND : 4;
|
||||
ST_TYPE : 4;
|
||||
} [[left_to_right]];
|
||||
} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 8)]];
|
||||
|
||||
bitfield SHF {
|
||||
MASKPROC : 4;
|
||||
MASKOS : 8;
|
||||
UNKNOWN : 8;
|
||||
COMPRESSED : 1;
|
||||
TLS : 1;
|
||||
GROUP : 1;
|
||||
OS_NONCONFORMING : 1;
|
||||
LINK_ORDER : 1;
|
||||
INFO_LINK : 1;
|
||||
STRINGS : 1;
|
||||
MERGE : 1;
|
||||
padding : 1;
|
||||
EXECINSTR : 1;
|
||||
ALLOC : 1;
|
||||
WRITE : 1;
|
||||
} [[left_to_right]];
|
||||
ALLOC : 1;
|
||||
EXECINSTR : 1;
|
||||
padding : 1;
|
||||
MERGE : 1;
|
||||
STRINGS : 1;
|
||||
INFO_LINK : 1;
|
||||
LINK_ORDER : 1;
|
||||
OS_NONCONFORMING : 1;
|
||||
GROUP : 1;
|
||||
TLS : 1;
|
||||
COMPRESSED : 1;
|
||||
UNKNOWN : 8;
|
||||
MASKOS : 8;
|
||||
MASKPROC : 4;
|
||||
};
|
||||
|
||||
bitfield ELF32_R_INFO {
|
||||
SYM : 8;
|
||||
@@ -500,13 +503,13 @@ bitfield ELF64_R_INFO {
|
||||
} [[left_to_right]];
|
||||
|
||||
bitfield PF {
|
||||
MASKPROC : 4;
|
||||
MASKOS : 4;
|
||||
padding : 17;
|
||||
R : 1;
|
||||
W : 1;
|
||||
X : 1;
|
||||
} [[left_to_right]];
|
||||
W : 1;
|
||||
R : 1;
|
||||
padding : 17;
|
||||
MASKOS : 4;
|
||||
MASKPROC : 4;
|
||||
};
|
||||
|
||||
struct E_IDENT {
|
||||
char EI_MAG[4];
|
||||
@@ -560,8 +563,8 @@ struct Elf32_Phdr {
|
||||
PF p_flags;
|
||||
Elf32_Word p_align;
|
||||
|
||||
if (p_offset > 0 && p_filesz > 0 && (p_offset + p_filesz) < std::mem::data_size() && p_filesz < std::mem::data_size())
|
||||
u8 p_data[p_filesz] @ p_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 [[sealed]];
|
||||
};
|
||||
|
||||
struct Elf64_Phdr {
|
||||
@@ -575,7 +578,7 @@ struct Elf64_Phdr {
|
||||
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;
|
||||
u8 p_data[p_filesz] @ p_offset [[sealed]];
|
||||
};
|
||||
|
||||
struct Elf32_Chdr {
|
||||
@@ -637,12 +640,12 @@ struct Elf32_Shdr {
|
||||
} 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) {
|
||||
} else if (sh_type == SHT::SYMTAB || 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;
|
||||
u8 data[sh_size] @ sh_offset [[sealed]];
|
||||
}
|
||||
}
|
||||
} [[format("format_section_header")]];;
|
||||
@@ -697,12 +700,12 @@ struct Elf64_Shdr {
|
||||
} 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) {
|
||||
} else if (sh_type == SHT::SYMTAB || 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;
|
||||
u8 data[sh_size] @ sh_offset [[sealed]];
|
||||
}
|
||||
}
|
||||
} [[format("format_section_header")]];
|
||||
@@ -731,7 +734,9 @@ struct ELF {
|
||||
std::core::set_endian(std::mem::Endian::Big);
|
||||
|
||||
if (e_ident.EI_CLASS == EI_CLASS::ELFCLASS32) {
|
||||
Elf32_Ehdr header;
|
||||
Elf32_Ehdr ehdr;
|
||||
Elf32_Phdr phdr[ehdr.e_phnum] @ ehdr.e_phoff;
|
||||
Elf32_Shdr shdr[ehdr.e_shnum] @ ehdr.e_shoff;
|
||||
} else if (e_ident.EI_CLASS == EI_CLASS::ELFCLASS64) {
|
||||
Elf64_Ehdr ehdr;
|
||||
Elf64_Phdr phdr[ehdr.e_phnum] @ ehdr.e_phoff;
|
||||
@@ -740,3 +745,78 @@ struct ELF {
|
||||
};
|
||||
|
||||
ELF elf @ 0x00;
|
||||
|
||||
|
||||
fn gen_shdr_disp_name(ref auto pattern, str member_name, u8 member_index) {
|
||||
return std::format(
|
||||
"{}@shdr[{}]({})",
|
||||
member_name,
|
||||
member_index,
|
||||
format_section_header(pattern)
|
||||
);
|
||||
};
|
||||
|
||||
fn gen_shdr_sub_disp_name(ref auto pattern, str member_name, u8 member_index, u64 submember_index) {
|
||||
return std::format(
|
||||
"{}[{}]@shdr[{}]({})",
|
||||
member_name,
|
||||
submember_index,
|
||||
member_index,
|
||||
format_section_header(pattern)
|
||||
);
|
||||
};
|
||||
|
||||
fn gen_phdr_disp_name(ref auto pattern, str member_name, u8 member_index) {
|
||||
return std::format(
|
||||
"{}@phdr[{}]({})",
|
||||
member_name,
|
||||
member_index,
|
||||
pattern.p_type
|
||||
);
|
||||
};
|
||||
|
||||
bool displaySectionNames in;
|
||||
|
||||
fn main() {
|
||||
if (!displaySectionNames)
|
||||
return;
|
||||
|
||||
for (u32 i = 0, i < std::core::member_count(elf.shdr), i += 1) {
|
||||
if (std::core::has_member(elf.shdr[i], "stringTable")) {
|
||||
std::core::set_display_name(
|
||||
elf.shdr[i].stringTable,
|
||||
gen_shdr_disp_name(elf.shdr[i], "stringTable", i)
|
||||
);
|
||||
for (u64 j = 0, j < std::core::member_count(elf.shdr[i].stringTable), j += 1) {
|
||||
std::core::set_display_name(
|
||||
elf.shdr[i].stringTable[j],
|
||||
gen_shdr_sub_disp_name(elf.shdr[i], "String", i, j)
|
||||
);
|
||||
}
|
||||
} else if (std::core::has_member(elf.shdr[i], "symbolTable")) {
|
||||
std::core::set_display_name(
|
||||
elf.shdr[i].symbolTable,
|
||||
gen_shdr_disp_name(elf.shdr[i], "symbolTable", i)
|
||||
);
|
||||
} else if (std::core::has_member(elf.shdr[i], "pointer")) {
|
||||
std::core::set_display_name(
|
||||
elf.shdr[i].pointer,
|
||||
gen_shdr_disp_name(elf.shdr[i], "pointer", i)
|
||||
);
|
||||
} else if (std::core::has_member(elf.shdr[i], "data")) {
|
||||
std::core::set_display_name(
|
||||
elf.shdr[i].data,
|
||||
gen_shdr_disp_name(elf.shdr[i], "data", i)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 i = 0, i < std::core::member_count(elf.phdr), i += 1) {
|
||||
if (std::core::has_member(elf.phdr[i], "p_data")) {
|
||||
std::core::set_display_name(
|
||||
elf.phdr[i].p_data,
|
||||
gen_phdr_disp_name(elf.phdr[i], "p_data", i)
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
57
patterns/evtx.hexpat
Normal file
57
patterns/evtx.hexpat
Normal file
@@ -0,0 +1,57 @@
|
||||
#pragma endian little
|
||||
|
||||
struct Header {
|
||||
char signature[0x8];
|
||||
u64 first_chunk_number;
|
||||
u64 last_chunk_number;
|
||||
u64 next_record_identifier;
|
||||
u32 header_size;
|
||||
u16 minor_format_version;
|
||||
u16 major_format_version;
|
||||
u16 header_block_size;
|
||||
u16 number_of_chunks;
|
||||
u8 unknown[0x4C];
|
||||
u32 file_Flag;
|
||||
u32 checkSum;
|
||||
u8 unknown2[3968];
|
||||
};
|
||||
|
||||
struct BinaryXML{
|
||||
u8 fragment_header_token;
|
||||
u8 major_version;
|
||||
u8 minor_version;
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
struct Event_Record{
|
||||
u32 signature;
|
||||
u32 size;
|
||||
u64 event_record_identifier;
|
||||
u64 written_data_amd_time;
|
||||
BinaryXML binaryxml;
|
||||
};
|
||||
|
||||
struct Chunk{
|
||||
char signature[0x8];
|
||||
u64 first_event_record_number;
|
||||
u64 last_event_record_number;
|
||||
u64 first_event_record_identifier;
|
||||
u64 last_event_record_identifier;
|
||||
u32 header_size;
|
||||
u32 last_event_record_data_offset;
|
||||
u32 free_space_offset;
|
||||
u32 event_records_checksum;
|
||||
u8 unknown[64];
|
||||
u32 unknown2;
|
||||
u32 checksum;
|
||||
u8 common_string_offset_array[256];
|
||||
u8 templatePtr[128];
|
||||
Event_Record event_record;
|
||||
};
|
||||
|
||||
struct Evtx {
|
||||
Header header;
|
||||
Chunk chunk;
|
||||
};
|
||||
|
||||
Evtx evtx @ 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;
|
||||
@@ -1,321 +1,323 @@
|
||||
#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())];
|
||||
};
|
||||
|
||||
#include <std/sys.pat>
|
||||
#include <std/core.pat>
|
||||
#include <std/io.pat>
|
||||
|
||||
#pragma endian big
|
||||
|
||||
using BitfieldOrder = std::core::BitfieldOrder;
|
||||
|
||||
u32 sampleSize;
|
||||
u32 bitsPerSample;
|
||||
|
||||
// METADATA
|
||||
|
||||
enum BLOCK_TYPE : u8 {
|
||||
STREAMINFO = 0,
|
||||
PADDING = 1,
|
||||
APPLICATION = 2,
|
||||
SEEKTABLE = 3,
|
||||
VORBIS_COMMENT = 4,
|
||||
CUESHEET = 5,
|
||||
PICTURE = 6,
|
||||
|
||||
INVALID = 127
|
||||
};
|
||||
|
||||
bitfield METADATA_BLOCK_HEADER {
|
||||
lastMetadataBlock : 1;
|
||||
blockType : 7;
|
||||
length : 24;
|
||||
};
|
||||
|
||||
bitfield STREAMINFO_FLAGS {
|
||||
sampleRate : 20;
|
||||
numChannels : 3 [[format("format_channels")]];
|
||||
bitsPerSample : 5;
|
||||
numSamplesInStream : 36;
|
||||
} [[inline]];
|
||||
|
||||
fn format_channels(u8 value) {
|
||||
return value + 1;
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_STREAMINFO {
|
||||
u16 minBlockSize, maxBlockSize;
|
||||
u24 minFrameSize, maxFrameSize;
|
||||
STREAMINFO_FLAGS flags;
|
||||
u128 md5Signature;
|
||||
|
||||
bitsPerSample = flags.bitsPerSample;
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_PADDING {
|
||||
padding[parent.header.length];
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_APPLICATION {
|
||||
char applicationID[4];
|
||||
u8 applicationData[parent.header.length - sizeof(applicationID)];
|
||||
};
|
||||
|
||||
struct SEEKPOINT {
|
||||
u64 sampleNumber;
|
||||
u64 byteOffset;
|
||||
u16 numSamples;
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_SEEKTABLE {
|
||||
SEEKPOINT seekPoints[parent.header.length / 18];
|
||||
};
|
||||
|
||||
struct VORBIS_USER_COMMENT {
|
||||
le u32 length;
|
||||
char comment[length];
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_VORBIS_COMMENT {
|
||||
le u32 vendorLength;
|
||||
u8 vendor[vendorLength];
|
||||
|
||||
le u32 userCommentListLength;
|
||||
VORBIS_USER_COMMENT userCommentList[userCommentListLength];
|
||||
};
|
||||
|
||||
bitfield TRACK_FLAGS {
|
||||
audioTrack : 1;
|
||||
preEmphasis : 1;
|
||||
} [[inline,bitfield_order(BitfieldOrder::LeastToMostSignificant, 8)]];
|
||||
|
||||
struct CUESHEET_TRACK_INDEX {
|
||||
u64 sampleOffset;
|
||||
u8 indexPointNumber;
|
||||
padding[3];
|
||||
};
|
||||
|
||||
struct CUESHEET_TRACK {
|
||||
u64 trackOffset;
|
||||
u8 trackNumber;
|
||||
char trackISRC[12];
|
||||
TRACK_FLAGS flags;
|
||||
padding[13];
|
||||
u8 numTrackIndexPoints;
|
||||
CUESHEET_TRACK_INDEX indexes[numTrackIndexPoints];
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_CUESHEET {
|
||||
char mediaCatalogNumber[128];
|
||||
u64 numLeadInSamples;
|
||||
bool isCD;
|
||||
padding[258];
|
||||
u8 numTracks;
|
||||
CUESHEET_TRACK tracks[numTracks];
|
||||
};
|
||||
|
||||
enum PICTURE_TYPE : u32 {
|
||||
Other = 0,
|
||||
FileIcon = 1,
|
||||
OtherFileIcon = 2,
|
||||
CoverFront = 3,
|
||||
CoverBack = 4,
|
||||
LeafletPage = 5,
|
||||
Media = 6,
|
||||
LeadArtist = 7,
|
||||
Artist = 8,
|
||||
Conductor = 9,
|
||||
Band = 10,
|
||||
Composer = 11,
|
||||
Lyricist = 12,
|
||||
RecordingLocation = 13,
|
||||
DuringRecording = 14,
|
||||
DuringPerformance = 15,
|
||||
MovieScreenCapture = 16,
|
||||
ABrightColoredFish = 17,
|
||||
Illustration = 18,
|
||||
BandLogoType = 19,
|
||||
PublisherLogoType = 20
|
||||
};
|
||||
|
||||
struct METADATA_BLOCK_PICTURE {
|
||||
PICTURE_TYPE pictureType;
|
||||
u32 mimeTypeLength;
|
||||
char mimeType[mineTypeLength];
|
||||
u32 descriptionLength;
|
||||
char description[descriptionLength];
|
||||
u32 width, height;
|
||||
u32 colorDepth;
|
||||
u32 colorCount;
|
||||
u32 pictureDataLength;
|
||||
u8 pictureData[pictureDataLength];
|
||||
};
|
||||
|
||||
|
||||
|
||||
// FRAME DATA
|
||||
// TODO: THIS IS INCOMPLETE / NOT WORKING CURRENTLY
|
||||
|
||||
bitfield FRAME_HEADER_FLAGS {
|
||||
syncCode : 14;
|
||||
padding : 1;
|
||||
blockingStrategy : 1;
|
||||
blockSize : 4;
|
||||
sampleRate : 4;
|
||||
channelAssignment : 4;
|
||||
sampleSize : 3;
|
||||
} [[inline,bitfield_order(BitfieldOrder::LeastToMostSignificant, 32)]];
|
||||
|
||||
struct FRAME_HEADER {
|
||||
FRAME_HEADER_FLAGS flags;
|
||||
|
||||
sampleSize = flags.sampleSize;
|
||||
|
||||
if (flags.blockingStrategy)
|
||||
char16 sampleNumber[7];
|
||||
else
|
||||
char16 frameNumber[6];
|
||||
|
||||
if (flags.blockSize == 0b0110)
|
||||
u8 blockSize;
|
||||
else if (flags.blockSize == 0b0111)
|
||||
u16 blockSize;
|
||||
|
||||
if (flags.sampleRate == 0b1100)
|
||||
u8 sampleRate;
|
||||
else if (flags.sampleRate == 0b1101 || flags.sampleRate == 0b1110)
|
||||
u16 sampleRate;
|
||||
|
||||
u8 crc8;
|
||||
};
|
||||
|
||||
struct FRAME_FOOTER {
|
||||
u16 crc16;
|
||||
};
|
||||
|
||||
bitfield SUBFRAME_HEADER {
|
||||
padding : 1;
|
||||
type : 6;
|
||||
wastedBits : 1;
|
||||
};
|
||||
|
||||
fn getBitsPerSample() {
|
||||
if (sampleSize == 0b000)
|
||||
return bitsPerSample;
|
||||
else if (sampleSize == 0b001)
|
||||
return 8;
|
||||
else if (sampleSize == 0b010)
|
||||
return 12;
|
||||
else if (sampleSize == 0b100)
|
||||
return 16;
|
||||
else if (sampleSize == 0b101)
|
||||
return 20;
|
||||
else if (sampleSize == 0b110)
|
||||
return 24;
|
||||
else
|
||||
std::error(std::format("Invalid sample size {}.", sampleSize));
|
||||
};
|
||||
|
||||
bitfield SUBFRAME_CONSTANT {
|
||||
value : getBitsPerSample();
|
||||
};
|
||||
|
||||
bitfield SUBFRAME_VERBATIM {
|
||||
value : getBitsPerSample() * parent.parent.header.flags.blockSize;
|
||||
};
|
||||
|
||||
bitfield SUBFRAME_FIXED_VALUE {
|
||||
value : getBitsPerSample() * (parent.parent.header.type & 0b111);
|
||||
codingMethod : 2;
|
||||
} [[inline]];
|
||||
|
||||
bitfield RESIDUAL_CODING_METHOD_PARTITIONED_RICE {
|
||||
partitionOrder : 4;
|
||||
riceParameter : 4;
|
||||
if (riceParameter == 0b1111)
|
||||
bitsPerSample : 5;
|
||||
};
|
||||
|
||||
bitfield RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 {
|
||||
partitionOrder : 4;
|
||||
riceParameter : 5;
|
||||
if (riceParameter == 0b11111)
|
||||
bitsPerSample : 5;
|
||||
};
|
||||
|
||||
struct RESIDUAL {
|
||||
if (parent.value.codingMethod == 0b00)
|
||||
RESIDUAL_CODING_METHOD_PARTITIONED_RICE rice;
|
||||
else if (parent.value.codingMethod == 0b01)
|
||||
RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 rice;
|
||||
|
||||
|
||||
if ((parent.parent.header.type & 0b111) == 0b000)
|
||||
u8 samples[(getBitsPerSample() * (parent.parent.parent.header.flags.blockSize - (parent.parent.header.type & 0b111))) / 8];
|
||||
else if (std::core::array_index() != 0)
|
||||
u8 samples[(getBitsPerSample() * (parent.parent.parent.header.flags.blockSize / (1 << rice.partitionOrder))) / 8];
|
||||
else
|
||||
u8 samples[(getBitsPerSample() * ((parent.parent.parent.header.flags.blockSize / (1 << rice.partitionOrder)) - (parent.parent.header.type & 0b111))) / 8];
|
||||
};
|
||||
|
||||
struct SUBFRAME_FIXED {
|
||||
SUBFRAME_FIXED_VALUE value;
|
||||
RESIDUAL residual;
|
||||
};
|
||||
|
||||
bitfield SUBFRAME_LPC_VALUE {
|
||||
warmUpSamples : getBitsPerSample() * ((parent.header.type & 0b011111) + 1);
|
||||
quantizedLinearPredictorCoefficient : 4;
|
||||
quantizedLinearPredictorCoefficientShift : 5;
|
||||
predictorCoefficients : quantizedLinearPredictorCoefficient * ((parent.header.type & 0b011111) + 1);
|
||||
} [[inline]];
|
||||
|
||||
struct SUBFRAME_LPC {
|
||||
SUBFRAME_LPC_VALUE value;
|
||||
RESIDUAL residual;
|
||||
};
|
||||
|
||||
|
||||
struct SUBFRAME {
|
||||
SUBFRAME_HEADER header;
|
||||
|
||||
if (header.type == 0b00000)
|
||||
SUBFRAME_CONSTANT constant;
|
||||
else if (header.type == 0b000001)
|
||||
SUBFRAME_VERBATIM verbatim;
|
||||
else if ((header.type >> 3) == 0b001 && (header.type & 0b111) <= 4)
|
||||
SUBFRAME_FIXED fixed;
|
||||
else if (header.type == 0b100000)
|
||||
SUBFRAME_LPC lpc;
|
||||
};
|
||||
|
||||
struct FRAME {
|
||||
FRAME_HEADER header;
|
||||
SUBFRAME subframes[parent.metadata[0].data.flags.numChannels + 1];
|
||||
FRAME_FOOTER footer;
|
||||
};
|
||||
|
||||
|
||||
struct METADATA_BLOCK {
|
||||
METADATA_BLOCK_HEADER header;
|
||||
if (header.lastMetadataBlock)
|
||||
break;
|
||||
|
||||
if (header.blockType == BLOCK_TYPE::STREAMINFO)
|
||||
METADATA_BLOCK_STREAMINFO data;
|
||||
else if (header.blockType == BLOCK_TYPE::PADDING)
|
||||
METADATA_BLOCK_PADDING data;
|
||||
else if (header.blockType == BLOCK_TYPE::APPLICATION)
|
||||
METADATA_BLOCK_APPLICATION data;
|
||||
else if (header.blockType == BLOCK_TYPE::VORBIS_COMMENT)
|
||||
METADATA_BLOCK_VORBIS_COMMENT data;
|
||||
else if (header.blockType == BLOCK_TYPE::CUESHEET)
|
||||
METADATA_BLOCK_CUESHEET data;
|
||||
else if (header.blockType == BLOCK_TYPE::PICTURE)
|
||||
METADATA_BLOCK_PICTURE data;
|
||||
else
|
||||
std::error("Invalid metadata block type!");
|
||||
};
|
||||
|
||||
struct STREAM {
|
||||
char magic[4];
|
||||
METADATA_BLOCK metadata[while(true)];
|
||||
//FRAME frames[while(!std::mem::eof())];
|
||||
};
|
||||
|
||||
STREAM stream @ 0x00;
|
||||
@@ -13,7 +13,7 @@ bitfield CHS {
|
||||
h : 8;
|
||||
s : 6;
|
||||
c : 10;
|
||||
} [[right_to_left, format("chs_formatter")]];
|
||||
} [[format("chs_formatter")]];
|
||||
|
||||
fn chs_formatter(CHS chs) {
|
||||
return std::format("({:X}, {:X}, {:X}) | 0x{:X}", chs.c, chs.h, chs.s, (chs.c * 16 + chs.h) * 63 + (chs.s - 1));
|
||||
|
||||
181
patterns/gif.hexpat
Normal file
181
patterns/gif.hexpat
Normal file
@@ -0,0 +1,181 @@
|
||||
#define LABEL_GC 0xF9
|
||||
#define LABEL_COMMENT 0xFE
|
||||
#define LABEL_APPLICATION 0xFF
|
||||
#define LABEL_PLAINTEXT 0x01
|
||||
#define LABEL_APPLICATION_NETSCAPE "NETSCAPE"
|
||||
#define CODE_FRAME 0x2C
|
||||
#define CODE_EXTENSION 0x21
|
||||
#define CODE_TRAILER 0x3B
|
||||
#define MAX_BLOCKS 4096
|
||||
#define GCT_ACCESS parent.parent.parent.parent.header.gct
|
||||
|
||||
#include <std/io.pat>
|
||||
#include <std/core.pat>
|
||||
#include <std/mem.pat>
|
||||
#include <std/string.pat>
|
||||
|
||||
#pragma MIME image/gif
|
||||
|
||||
bitfield GCT_Flags {
|
||||
size : 3 [[comment("physical size = 2^(flags.size + 1)")]];
|
||||
sort : 1 [[comment("Indicates if the table is sorted by importance")]];
|
||||
colorRes : 3 [[comment("Indicates the richness of the original pallet")]];
|
||||
enabled : 1;
|
||||
};
|
||||
|
||||
bitfield LCT_Flags {
|
||||
size : 3 [[comment("physical size = 2^(flags.size + 1)")]];
|
||||
padding : 2;
|
||||
sort : 1 [[comment("Indicates if the table is sorted by importance")]];
|
||||
interlace : 1;
|
||||
enable : 1;
|
||||
};
|
||||
|
||||
bitfield GC_Flags {
|
||||
transparent : 1;
|
||||
userInput : 1;
|
||||
disposalMode : 3 [[format("format::dispose_enum")]];
|
||||
reserved : 3;
|
||||
};
|
||||
|
||||
struct color {
|
||||
u8 r, g, b;
|
||||
} [[color(std::format("{:02X}{:02X}{:02X}", r, g, b))]];
|
||||
|
||||
struct subblock {
|
||||
u8 size;
|
||||
if(size == 0) break;
|
||||
u8 data[size];
|
||||
};
|
||||
|
||||
struct block {
|
||||
subblock blocks[MAX_BLOCKS];
|
||||
};
|
||||
|
||||
fn exp2(auto n) {
|
||||
return 1 << n;
|
||||
};
|
||||
|
||||
struct Header {
|
||||
char magic[3];
|
||||
char version[3];
|
||||
u16 width;
|
||||
u16 height;
|
||||
GCT_Flags gctFlags;
|
||||
u8 bgColorIndex;
|
||||
u8 pixelAscpet;
|
||||
if (gctFlags.enabled) {
|
||||
color gct[(exp2(gctFlags.size + 1))];
|
||||
color bgColor = gct[bgColorIndex];
|
||||
}
|
||||
};
|
||||
|
||||
struct frame {
|
||||
u16 x;
|
||||
u16 y;
|
||||
u16 width;
|
||||
u16 height;
|
||||
LCT_Flags lctFlags;
|
||||
if(lctFlags.enable) {
|
||||
color lct[(exp2(lctFlags.size + 1))];
|
||||
}
|
||||
u8 lzwMinCode [[comment("This byte determines the initial number of bits used for LZW codes in the image data")]];
|
||||
block lzwCompressedData [[comment("Data is pallet indecies either into current LDC or GCT and is compressed using LZW")]];
|
||||
};
|
||||
|
||||
struct comment {
|
||||
block data [[hidden]];
|
||||
char comment[] @ addressof(data.blocks) + 1; // TODO : need to find a better way of doing this
|
||||
};
|
||||
|
||||
struct application {
|
||||
u8 blockSize [[hidden]];
|
||||
char identifier[8] [[comment("Only known are: NETSCAPE")]];
|
||||
char version[3] [[comment("Only known for NETSCAPE: '2.0'")]];
|
||||
block b [[hidden]];
|
||||
if(identifier == LABEL_APPLICATION_NETSCAPE) {
|
||||
u16 loopcount @ addressof(b.blocks[0].data) + 1 [[comment("0, = Forever")]];
|
||||
}
|
||||
};
|
||||
|
||||
struct plaintext {
|
||||
u8 blockSize [[hidden]];
|
||||
u16 gridLeftPos;
|
||||
u16 gridTopPos;
|
||||
u16 gridWidth;
|
||||
u16 gridHeight;
|
||||
u8 cellWidth;
|
||||
u8 cellHeight;
|
||||
u8 textForegroundColorIndex [[hidden]];
|
||||
u8 textBackgroundColorIndex [[hidden]];
|
||||
color textForegroundColor @ addressof(GCT_ACCESS[textForegroundColorIndex]);
|
||||
color textBackgroundColor @ addressof(GCT_ACCESS[textBackgroundColorIndex]);
|
||||
block data [[hidden]];
|
||||
char text[] @ addressof(data.blocks) + 1;
|
||||
//char text[data.blocks[std::core::array_index()].size] @ addressof(data.blocks[std::core::array_index()].data);
|
||||
};
|
||||
|
||||
struct graphical_control {
|
||||
u8 blockSize [[hidden]];
|
||||
GC_Flags flags;
|
||||
u16 delay [[format("format::delay")]];
|
||||
u8 transparentColorIndex;
|
||||
block b [[hidden]];
|
||||
};
|
||||
|
||||
namespace format {
|
||||
fn dispose_enum(u8 value) {
|
||||
if(value == 0x00) return "Do nothing";
|
||||
if(value == 0x01) return "Do not remove pixels";
|
||||
if(value == 0x02) return "Restore background pixels";
|
||||
if(value == 0x03) return "Restore previous pixels";
|
||||
};
|
||||
|
||||
fn extension_name(u8 label) {
|
||||
if(label == LABEL_GC) return "Graphical Control Extension";
|
||||
if(label == LABEL_COMMENT) return "Comment Extension";
|
||||
if(label == LABEL_APPLICATION) return "Application Extension";
|
||||
if(label == LABEL_PLAINTEXT) return "Plaintext Extension";
|
||||
return "Unknown Extension";
|
||||
};
|
||||
|
||||
fn content_name(ref frame f) {
|
||||
if(f.code == CODE_FRAME) return "Frame";
|
||||
if(f.code == CODE_EXTENSION) return "Extension";
|
||||
if(f.code == CODE_TRAILER) return "End";
|
||||
return "Unknown Content";
|
||||
};
|
||||
|
||||
fn delay(u16 delay) {
|
||||
if(delay == -1) return "forever";
|
||||
else if(delay < 2) return "100ms";
|
||||
else return std::string::to_string(delay * 10) + "ms";
|
||||
return "notime";
|
||||
};
|
||||
}
|
||||
|
||||
struct extension {
|
||||
u8 label [[format("format::extension_name")]];
|
||||
if(label == LABEL_GC) graphical_control gc [[inline]];
|
||||
if(label == LABEL_COMMENT) comment c [[inline]];
|
||||
if(label == LABEL_APPLICATION) application a [[inline]];
|
||||
if(label == LABEL_PLAINTEXT) plaintext [[inline]];
|
||||
};
|
||||
|
||||
struct content {
|
||||
u8 code [[hidden]];
|
||||
if(code == CODE_FRAME) frame f [[inline]];
|
||||
if(code == CODE_EXTENSION) extension e [[inline]];
|
||||
if(code == CODE_TRAILER) break;
|
||||
} [[format("format::content_name")]];
|
||||
|
||||
struct Data {
|
||||
content contents[while(!std::mem::eof())] [[inline]];
|
||||
};
|
||||
|
||||
struct Gif {
|
||||
Header header;
|
||||
Data data;
|
||||
};
|
||||
|
||||
Gif gif @ 0x00;
|
||||
79
patterns/gzip.hexpat
Normal file
79
patterns/gzip.hexpat
Normal file
@@ -0,0 +1,79 @@
|
||||
#pragma MIME application/gzip
|
||||
|
||||
#include <type/time.pat>
|
||||
#include <type/size.pat>
|
||||
#include <std/core.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
using BitfieldOrder = std::core::BitfieldOrder;
|
||||
|
||||
bitfield Flags {
|
||||
FTEXT : 1;
|
||||
FHCRC : 1;
|
||||
FEXTRA : 1;
|
||||
FNAME : 1;
|
||||
FCOMMENT : 1;
|
||||
} [[bitfield_order(BitfieldOrder::LeastToMostSignificant, 8)]];
|
||||
|
||||
bitfield ExtraFlags {
|
||||
padding : 1;
|
||||
maximumCompression : 1;
|
||||
fastestCompression : 1;
|
||||
padding : 5;
|
||||
};
|
||||
|
||||
enum CompressionMethod : u8 {
|
||||
Reserved = 0 ... 7,
|
||||
Deflate = 8
|
||||
};
|
||||
|
||||
enum OperatingSystemID : u8 {
|
||||
FATFileSystem = 0x00,
|
||||
Amiga = 0x01,
|
||||
VMS = 0x02,
|
||||
Unix = 0x03,
|
||||
VM_CMS = 0x04,
|
||||
AtariTOS = 0x05,
|
||||
HPFSFileSystem = 0x06,
|
||||
Macintosh = 0x07,
|
||||
ZSystem = 0x08,
|
||||
CP_M = 0x09,
|
||||
TOPS_20 = 0x0A,
|
||||
NTFSFileSystem = 0x0B,
|
||||
QDOS = 0x0C,
|
||||
AcordRISCOS = 0x0D,
|
||||
Unknown = 0xFF
|
||||
};
|
||||
|
||||
struct GZip {
|
||||
u16 signature;
|
||||
CompressionMethod compressionMethod;
|
||||
Flags flags;
|
||||
type::time32_t modificationTime;
|
||||
ExtraFlags extraFlags;
|
||||
OperatingSystemID operatingSystemId;
|
||||
|
||||
if (flags.FEXTRA) {
|
||||
u16 extraLength;
|
||||
u8 extraField[extraLength];
|
||||
}
|
||||
|
||||
if (flags.FNAME) {
|
||||
char originalFileName[];
|
||||
}
|
||||
|
||||
if (flags.FCOMMENT) {
|
||||
char comment[];
|
||||
}
|
||||
|
||||
if (flags.FHCRC) {
|
||||
u16 crc16;
|
||||
}
|
||||
|
||||
u8 data[while($ < std::mem::size() - 8)] [[sealed]];
|
||||
|
||||
u32 crc32;
|
||||
type::Size<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;
|
||||
@@ -1,5 +1,4 @@
|
||||
#pragma endian big
|
||||
#pragma bitfield_order left_to_right
|
||||
|
||||
#include <std/sys.pat>
|
||||
#include <std/io.pat>
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
#pragma endian big
|
||||
#pragma MIME application/x-java-applet
|
||||
|
||||
#include <std/core.pat>
|
||||
#include <std/io.pat>
|
||||
#include <std/sys.pat>
|
||||
|
||||
using BitfieldOrder = std::core::BitfieldOrder;
|
||||
|
||||
// The Java documentations use the number of bytes instead of the number of bits for its type names
|
||||
using u1 = u8;
|
||||
using u2 = u16;
|
||||
@@ -26,7 +29,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 +41,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 +134,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 {
|
||||
@@ -179,7 +209,7 @@ bitfield access_flags_method {
|
||||
padding : 1; // 0x2000
|
||||
padding : 1; // 0x4000
|
||||
padding : 1; // 0x8000
|
||||
};
|
||||
} [[bitfield_order(BitfieldOrder::LeastToMostSignificant, 16)]];
|
||||
|
||||
bitfield access_flags_field {
|
||||
ACC_PUBLIC : 1; // 0x0001
|
||||
@@ -198,7 +228,7 @@ bitfield access_flags_field {
|
||||
padding : 1; // 0x2000
|
||||
ACC_ENUM : 1; // 0x4000
|
||||
padding : 1; // 0x8000
|
||||
};
|
||||
} [[bitfield_order(BitfieldOrder::LeastToMostSignificant, 16)]];
|
||||
|
||||
bitfield access_flags_class {
|
||||
ACC_PUBLIC : 1; // 0x0001
|
||||
@@ -216,8 +246,8 @@ bitfield access_flags_class {
|
||||
ACC_SYNTHETIC : 1; // 0x1000
|
||||
ACC_ANNOTATION : 1; // 0x2000
|
||||
ACC_ENUM : 1; // 0x4000
|
||||
padding : 1; // 0x8000
|
||||
};
|
||||
ACC_MODULE : 1; // 0x8000
|
||||
} [[bitfield_order(BitfieldOrder::LeastToMostSignificant, 16)]];
|
||||
|
||||
struct attribute_info {
|
||||
u2 attribute_name_info;
|
||||
@@ -279,31 +309,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:");
|
||||
|
||||
122
patterns/jpeg.hexpat
Normal file
122
patterns/jpeg.hexpat
Normal file
@@ -0,0 +1,122 @@
|
||||
#include <std/mem.pat>
|
||||
#pragma endian big
|
||||
|
||||
#pragma MIME image/jpeg
|
||||
|
||||
enum Marker : u8 {
|
||||
TEM = 0x01,
|
||||
SOF0 = 0xC0,
|
||||
SOF1 = 0xC1,
|
||||
SOF2 = 0xC2,
|
||||
SOF3 = 0xC3,
|
||||
DHT = 0xC4,
|
||||
SOF5 = 0xC5,
|
||||
SOF6 = 0xC6,
|
||||
SOF7 = 0xC7,
|
||||
SOI = 0xD8,
|
||||
EOI = 0xD9,
|
||||
SOS = 0xDA,
|
||||
DQT = 0xDB,
|
||||
DNL = 0xDC,
|
||||
DRI = 0xDD,
|
||||
DHP = 0xDE,
|
||||
APP0 = 0xE0,
|
||||
APP1 = 0xE1,
|
||||
APP2 = 0xE2,
|
||||
APP3 = 0xE3,
|
||||
APP4 = 0xE4,
|
||||
APP5 = 0xE5,
|
||||
APP6 = 0xE6,
|
||||
APP7 = 0xE7,
|
||||
APP8 = 0xE8,
|
||||
APP9 = 0xE9,
|
||||
APP10 = 0xEA,
|
||||
APP11 = 0xEB,
|
||||
APP12 = 0xEC,
|
||||
APP13 = 0xED,
|
||||
APP14 = 0xEE,
|
||||
APP15 = 0xEF,
|
||||
COM = 0xFE
|
||||
};
|
||||
|
||||
enum DensityUnit : u8 {
|
||||
NoUnit = 0x00,
|
||||
PixelsPerInch = 0x01,
|
||||
PixelsPerCm = 0x02
|
||||
};
|
||||
|
||||
struct Pixel {
|
||||
u8 r, g, b;
|
||||
} [[sealed, transform("transform_pixel")]];
|
||||
|
||||
fn transform_pixel(Pixel pixel) {
|
||||
return (0xFF << 24) | (pixel.b << 16) | (pixel.g << 8) | (pixel.r << 0);
|
||||
};
|
||||
|
||||
|
||||
struct APP0 {
|
||||
char magic[5];
|
||||
u8 versionMajor, versionMinor;
|
||||
DensityUnit densityUnit;
|
||||
u16 densityX, densityY;
|
||||
u8 thumbnailX, thumbnailY;
|
||||
Pixel thumbnail[thumbnailX * thumbnailY] [[sealed]];
|
||||
};
|
||||
|
||||
enum ComponentId : u8 {
|
||||
Y = 1,
|
||||
CB = 2,
|
||||
CR = 3,
|
||||
I = 4,
|
||||
Q = 5
|
||||
};
|
||||
|
||||
struct SOF0Component {
|
||||
ComponentId componentId;
|
||||
u8 samplingFactors;
|
||||
u8 quantizationTableId;
|
||||
};
|
||||
|
||||
struct SOF0 {
|
||||
u8 bitsPerSample;
|
||||
u16 imageHeight, imageWidth;
|
||||
u8 numComponents;
|
||||
SOF0Component components[numComponents];
|
||||
};
|
||||
|
||||
struct SOSComponent {
|
||||
ComponentId componentId;
|
||||
u8 huffmanTable;
|
||||
};
|
||||
|
||||
struct SOS {
|
||||
u8 numComponents;
|
||||
SOSComponent components[numComponents];
|
||||
u8 startSpectralSelection;
|
||||
u8 endSpectral;
|
||||
u8 apprBitPos;
|
||||
|
||||
u8 image_data[while(!std::mem::eof())] [[sealed]];
|
||||
};
|
||||
|
||||
struct Segment {
|
||||
u8 magic;
|
||||
Marker marker;
|
||||
|
||||
if (marker == Marker::SOI || marker == Marker::EOI) {
|
||||
|
||||
} else {
|
||||
u16 length;
|
||||
if (marker == Marker::APP0) {
|
||||
APP0 data;
|
||||
} else if (marker == Marker::SOF0) {
|
||||
SOF0 data;
|
||||
} else if (marker == Marker::SOS) {
|
||||
SOS data;
|
||||
} else {
|
||||
u8 data[length - sizeof(length)] [[sealed]];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Segment segments[while(!std::mem::eof())] @ 0x00;
|
||||
@@ -1,459 +1,462 @@
|
||||
#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;
|
||||
#pragma MIME application/x-ms-shortcut
|
||||
|
||||
#include <std/core.pat>
|
||||
#include <type/guid.pat>
|
||||
#include <type/size.pat>
|
||||
|
||||
using BitfieldOrder = std::core::BitfieldOrder;
|
||||
|
||||
bitfield LinkFlags {
|
||||
HasLinkTargetIDList : 1;
|
||||
HasLinkInfo : 1;
|
||||
HasName : 1;
|
||||
HasRelativePath : 1;
|
||||
HasWorkingDir : 1;
|
||||
HasArguments : 1;
|
||||
HasIconLocation : 1;
|
||||
IsUnicode : 1;
|
||||
ForceNoLinkInfo : 1;
|
||||
HasExpString : 1;
|
||||
RunInSeparateProcess : 1;
|
||||
padding : 1;
|
||||
HasDarwinID : 1;
|
||||
RunAsUser : 1;
|
||||
HasExpIcon : 1;
|
||||
NoPidlAlias : 1;
|
||||
padding : 1;
|
||||
RunWithShimLayer : 1;
|
||||
ForceNoLinkTrack : 1;
|
||||
EnableTargetMetadata : 1;
|
||||
DisableLinkPathTracking : 1;
|
||||
DisableKnownFolderTracking : 1;
|
||||
DisableKnownFolderAlias : 1;
|
||||
AllowLinkToLink : 1;
|
||||
UnaliasOnSave : 1;
|
||||
PreferEnvironmentPath : 1;
|
||||
KeepLocalIDListForUNCTarget : 1;
|
||||
padding : 5;
|
||||
};
|
||||
|
||||
bitfield FileAttributesFlags {
|
||||
FILE_ATTRIBUTE_READONLY : 1;
|
||||
FILE_ATTRIBUTE_HIDDEN : 1;
|
||||
FILE_ATTRIBUTE_SYSTEM : 1;
|
||||
padding : 1;
|
||||
FILE_ATTRIBUTE_DIRECTORY : 1;
|
||||
FILE_ATTRIBUTE_ARCHIVE : 1;
|
||||
padding : 1;
|
||||
FILE_ATTRIBUTE_NORMAL : 1;
|
||||
FILE_ATTRIBUTE_TEMPORARY : 1;
|
||||
FILE_ATTRIBUTE_SPARSE_FILE : 1;
|
||||
FILE_ATTRIBUTE_REPARSE_POINT : 1;
|
||||
FILE_ATTRIBUTE_COMPRESSED : 1;
|
||||
FILE_ATTRIBUTE_OFFLINE : 1;
|
||||
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED : 1;
|
||||
FILE_ATTRIBUTE_ENCRYPTED : 1;
|
||||
padding : 17;
|
||||
};
|
||||
|
||||
bitfield ModifierKeys {
|
||||
HOTKEYF_SHIFT : 1;
|
||||
HOTKEYF_CONTROL : 1;
|
||||
HOTKEYF_ALT : 1;
|
||||
padding : 5;
|
||||
};
|
||||
|
||||
enum Keys : u8 {
|
||||
KEY_NONE = 0x00,
|
||||
KEY_0 = 0x30,
|
||||
KEY_1 = 0x31,
|
||||
KEY_2 = 0x32,
|
||||
KEY_3 = 0x33,
|
||||
KEY_4 = 0x34,
|
||||
KEY_5 = 0x35,
|
||||
KEY_6 = 0x36,
|
||||
KEY_7 = 0x37,
|
||||
KEY_8 = 0x38,
|
||||
KEY_9 = 0x39,
|
||||
KEY_A = 0x41,
|
||||
KEY_B = 0x42,
|
||||
KEY_C = 0x43,
|
||||
KEY_D = 0x44,
|
||||
KEY_E = 0x45,
|
||||
KEY_F = 0x46,
|
||||
KEY_G = 0x47,
|
||||
KEY_H = 0x48,
|
||||
KEY_I = 0x49,
|
||||
KEY_J = 0x4A,
|
||||
KEY_K = 0x4B,
|
||||
KEY_L = 0x4C,
|
||||
KEY_M = 0x4D,
|
||||
KEY_N = 0x4E,
|
||||
KEY_O = 0x4F,
|
||||
KEY_P = 0x50,
|
||||
KEY_Q = 0x51,
|
||||
KEY_R = 0x52,
|
||||
KEY_S = 0x53,
|
||||
KEY_T = 0x54,
|
||||
KEY_U = 0x55,
|
||||
KEY_V = 0x56,
|
||||
KEY_W = 0x57,
|
||||
KEY_X = 0x58,
|
||||
KEY_Y = 0x59,
|
||||
KEY_Z = 0x5A,
|
||||
|
||||
VK_F1 = 0x70,
|
||||
VK_F2 = 0x71,
|
||||
VK_F3 = 0x72,
|
||||
VK_F4 = 0x73,
|
||||
VK_F5 = 0x74,
|
||||
VK_F6 = 0x75,
|
||||
VK_F7 = 0x76,
|
||||
VK_F8 = 0x77,
|
||||
VK_F9 = 0x78,
|
||||
VK_F10 = 0x79,
|
||||
VK_F11 = 0x7A,
|
||||
VK_F12 = 0x7B,
|
||||
VK_F13 = 0x7C,
|
||||
VK_F14 = 0x7D,
|
||||
VK_F15 = 0x7E,
|
||||
VK_F16 = 0x7F,
|
||||
VK_F17 = 0x80,
|
||||
VK_F18 = 0x81,
|
||||
VK_F19 = 0x82,
|
||||
VK_F20 = 0x83,
|
||||
VK_F21 = 0x84,
|
||||
VK_F22 = 0x85,
|
||||
VK_F23 = 0x86,
|
||||
VK_F24 = 0x87,
|
||||
VK_NUMLOCK = 0x90,
|
||||
VK_SCROLL = 0x91,
|
||||
};
|
||||
|
||||
struct HotKeyFlags {
|
||||
Keys Key;
|
||||
ModifierKeys ModifierKeys;
|
||||
};
|
||||
|
||||
struct FILETIME {
|
||||
u32 dwLowDateTime;
|
||||
u32 dwHighDateTime;
|
||||
};
|
||||
|
||||
enum SHOWWINDOW_FLAGS : u32 {
|
||||
SW_SHOWNORMAL = 0x00000001,
|
||||
SW_SHOWMAXIMIZED = 0x00000003,
|
||||
SW_SHOWMINNOACTIVE = 0x00000007
|
||||
};
|
||||
|
||||
struct ShellLinkHeader {
|
||||
type::Size32 HeaderSize;
|
||||
type::GUID LinkCLSID;
|
||||
LinkFlags LinkFlags;
|
||||
FileAttributesFlags FileAttributes;
|
||||
FILETIME CreationTime, AccessTime, WriteTime;
|
||||
type::Size32 FileSize;
|
||||
u32 IconIndex;
|
||||
SHOWWINDOW_FLAGS ShowCommand;
|
||||
HotKeyFlags HotKey;
|
||||
padding[2];
|
||||
padding[4];
|
||||
padding[4];
|
||||
};
|
||||
|
||||
struct ItemID {
|
||||
type::Size16 ItemIDSize;
|
||||
|
||||
if (ItemIDSize == 0x00)
|
||||
break;
|
||||
else
|
||||
u8 Data[ItemIDSize - sizeof(ItemIDSize)];
|
||||
};
|
||||
|
||||
struct IDList {
|
||||
ItemID ItemIDList[while(true)];
|
||||
};
|
||||
|
||||
struct LinkTargetIDList {
|
||||
type::Size16 IDListSize;
|
||||
IDList IDList[while($ < (addressof(IDListSize) + IDListSize))];
|
||||
};
|
||||
|
||||
bitfield LinkInfoFlags {
|
||||
VolumeIDAndLocalBasePath : 1;
|
||||
CommonNetworkRelativeLinkAndPathSuffix : 1;
|
||||
padding : 30;
|
||||
};
|
||||
|
||||
enum DriveType : u32 {
|
||||
DRIVE_UNKNOWN = 0x00000000,
|
||||
DRIVE_NO_ROOT_DIR = 0x00000001,
|
||||
DRIVE_REMOVABLE = 0x00000002,
|
||||
DRIVE_FIXED = 0x00000003,
|
||||
DRIVE_REMOTE = 0x00000004,
|
||||
DRIVE_CDROM = 0x00000005,
|
||||
DRIVE_RAMDISK = 0x00000006
|
||||
};
|
||||
|
||||
struct VolumeID {
|
||||
type::Size32 VolumeIDSize;
|
||||
DriveType DriveType;
|
||||
u32 DriveSerialNumber;
|
||||
u32 VolumeLabelOffset;
|
||||
if (VolumeLabelOffset == 0x14)
|
||||
u32 VolumeLabelOffsetUnicode;
|
||||
char Data[VolumeIDSize - ($ - addressof(this))];
|
||||
};
|
||||
|
||||
bitfield CommonNetworkRelativeLinkFlags {
|
||||
ValidDevice : 1;
|
||||
ValidNetType : 1;
|
||||
padding : 30;
|
||||
};
|
||||
|
||||
enum NetworkProviderType : u32 {
|
||||
WNNC_NET_AVID = 0x001A0000,
|
||||
WNNC_NET_DOCUSPACE = 0x001B0000,
|
||||
WNNC_NET_MANGOSOFT = 0x001C0000,
|
||||
WNNC_NET_SERNET = 0x001D0000,
|
||||
WNNC_NET_RIVERFRONT1 = 0x001E0000,
|
||||
WNNC_NET_RIVERFRONT2 = 0x001F0000,
|
||||
WNNC_NET_DECORB = 0x00200000,
|
||||
WNNC_NET_PROTSTOR = 0x00210000,
|
||||
WNNC_NET_FJ_REDIR = 0x00220000,
|
||||
WNNC_NET_DISTINCT = 0x00230000,
|
||||
WNNC_NET_TWINS = 0x00240000,
|
||||
WNNC_NET_RDR2SAMPLE = 0x00250000,
|
||||
WNNC_NET_CSC = 0x00260000,
|
||||
WNNC_NET_3IN1 = 0x00270000,
|
||||
WNNC_NET_EXTENDNET = 0x00290000,
|
||||
WNNC_NET_STAC = 0x002A0000,
|
||||
WNNC_NET_FOXBAT = 0x002B0000,
|
||||
WNNC_NET_YAHOO = 0x002C0000,
|
||||
WNNC_NET_EXIFS = 0x002D0000,
|
||||
WNNC_NET_DAV = 0x002E0000,
|
||||
WNNC_NET_KNOWARE = 0x002F0000,
|
||||
WNNC_NET_OBJECT_DIRE = 0x00300000,
|
||||
WNNC_NET_MASFAX = 0x00310000,
|
||||
WNNC_NET_HOB_NFS = 0x00320000,
|
||||
WNNC_NET_SHIVA = 0x00330000,
|
||||
WNNC_NET_IBMAL = 0x00340000,
|
||||
WNNC_NET_LOCK = 0x00350000,
|
||||
WNNC_NET_TERMSRV = 0x00360000,
|
||||
WNNC_NET_SRT = 0x00370000,
|
||||
WNNC_NET_QUINCY = 0x00380000,
|
||||
WNNC_NET_OPENAFS = 0x00390000,
|
||||
WNNC_NET_AVID1 = 0x003A0000,
|
||||
WNNC_NET_DFS = 0x003B0000,
|
||||
WNNC_NET_KWNP = 0x003C0000,
|
||||
WNNC_NET_ZENWORKS = 0x003D0000,
|
||||
WNNC_NET_DRIVEONWEB = 0x003E0000,
|
||||
WNNC_NET_VMWARE = 0x003F0000,
|
||||
WNNC_NET_RSFX = 0x00400000,
|
||||
WNNC_NET_MFILES = 0x00410000,
|
||||
WNNC_NET_MS_NFS = 0x00420000,
|
||||
WNNC_NET_GOOGLE = 0x00430000
|
||||
};
|
||||
|
||||
struct CommonNetworkRelativeLink {
|
||||
type::Size32 CommonNetworkRelativeLinkSize;
|
||||
CommonNetworkRelativeLinkFlags CommonNetworkRelativeLinkFlags;
|
||||
u32 NetNameOffset;
|
||||
u32 DeviceNameOffset;
|
||||
NetworkProviderType NetworkProviderType;
|
||||
|
||||
if (NetNameOffset > 0x14) {
|
||||
u32 NetNameOffsetUnicode;
|
||||
u32 DeviceNameOffsetUnicode;
|
||||
}
|
||||
|
||||
char NetName[];
|
||||
char DeviceName[];
|
||||
|
||||
if (NetNameOffset > 0x14) {
|
||||
char16 NetNameUnicode[];
|
||||
char16 DeviceNameUnicode[];
|
||||
}
|
||||
};
|
||||
|
||||
struct LinkInfo {
|
||||
type::Size32 LinkInfoSize;
|
||||
type::Size32 LinkInfoHeaderSize;
|
||||
LinkInfoFlags LinkInfoFlags;
|
||||
u32 VolumeIDOffset;
|
||||
u32 LocalBasePathOffset;
|
||||
u32 CommonNetworkRelativeLinkOffset;
|
||||
u32 CommonPathSuffixOffset;
|
||||
|
||||
if (LinkInfoHeaderSize >= 0x24) {
|
||||
u32 LocalBasePathOffsetUnicode;
|
||||
u32 CommonPathSuffixOffsetUnicode;
|
||||
}
|
||||
|
||||
if (LinkInfoFlags.VolumeIDAndLocalBasePath) {
|
||||
VolumeID VolumeID;
|
||||
char LocalBasePath[];
|
||||
}
|
||||
|
||||
if (LinkInfoFlags.CommonNetworkRelativeLinkAndPathSuffix)
|
||||
CommonNetworkRelativeLink CommonNetworkRelativeLink;
|
||||
|
||||
char CommonPathSuffix[];
|
||||
|
||||
if (LinkInfoHeaderSize >= 0x24) {
|
||||
if (LinkInfoFlags.VolumeIDAndLocalBasePath)
|
||||
char16 LocalBasePathUnicode[];
|
||||
char16 CommonPathSuffixUnicode[];
|
||||
}
|
||||
};
|
||||
|
||||
struct String {
|
||||
u16 CountCharacters;
|
||||
char16 String[CountCharacters];
|
||||
};
|
||||
|
||||
struct StringData {
|
||||
if (parent.ShellLinkHeader.LinkFlags.HasName)
|
||||
String NAME_STRING;
|
||||
if (parent.ShellLinkHeader.LinkFlags.HasRelativePath)
|
||||
String RELATIVE_PATH;
|
||||
if (parent.ShellLinkHeader.LinkFlags.HasWorkingDir)
|
||||
String WORKING_DIR;
|
||||
if (parent.ShellLinkHeader.LinkFlags.HasArguments)
|
||||
String COMMAND_LINE_ARGUMENTS;
|
||||
if (parent.ShellLinkHeader.LinkFlags.HasIconLocation)
|
||||
String ICON_LOCATION;
|
||||
};
|
||||
|
||||
bitfield FillAttributes {
|
||||
FOREGROUND_BLUE : 1;
|
||||
FOREGROUND_GREEN : 1;
|
||||
FOREGROUND_RED : 1;
|
||||
FOREGROUND_INTENSITY : 1;
|
||||
|
||||
BACKGROUND_BLUE : 1;
|
||||
BACKGROUND_GREEN : 1;
|
||||
BACKGROUND_RED : 1;
|
||||
BACKGROUND_INTENSITY : 1;
|
||||
|
||||
padding : 8;
|
||||
};
|
||||
|
||||
struct ConsoleDataBlock {
|
||||
FillAttributes FillAttributes;
|
||||
FillAttributes PopupFillAttributes;
|
||||
u16 ScreenBufferSizeX, ScreenBufferSizeY;
|
||||
u16 WindowSizeX, WindowSizeY;
|
||||
u16 WindowOriginX, WindowOriginY;
|
||||
padding[4];
|
||||
padding[4];
|
||||
u32 FontSize;
|
||||
u32 FontFamily;
|
||||
u32 FontWeight;
|
||||
char16 FaceName[32];
|
||||
u32 CursorSize;
|
||||
u32 FullScreen;
|
||||
u32 QuickEdit;
|
||||
u32 InsertMode;
|
||||
u32 AutoPosition;
|
||||
u32 HistoryBufferSize;
|
||||
u32 NumberOfHistoryBuffers;
|
||||
u32 HistoryNoDup;
|
||||
u32 ColorTable[16];
|
||||
};
|
||||
|
||||
struct ConsoleFEDataBlock {
|
||||
u32 CodePage;
|
||||
};
|
||||
|
||||
struct DarwinDataBlock {
|
||||
char DarwinDataAnsi[260];
|
||||
char16 DarwinDataUnicode[260];
|
||||
};
|
||||
|
||||
struct EnvironmentVariableDataBlock {
|
||||
char TargetAnsi[260];
|
||||
char16 TargetUnicode[260];
|
||||
};
|
||||
|
||||
struct IconEnvironmentDataBlock {
|
||||
char TargetAnsi[260];
|
||||
char16 TargetUnicode[260];
|
||||
};
|
||||
|
||||
struct KnownFolderDataBlock {
|
||||
type::GUID KnownFolderID;
|
||||
u32 Offset;
|
||||
};
|
||||
|
||||
struct PropertyStoreDataBlock {
|
||||
u8 Bytes[parent.BlockSize - sizeof(parent.BlockSize) - sizeof(parent.BlockSignature)];
|
||||
std::warning("PropertyStoreDataBlock is not yet implemented!");
|
||||
};
|
||||
|
||||
struct ShimDataBlock {
|
||||
char16 LayerName[(parent.BlockSize - sizeof(parent.BlockSize) - sizeof(parent.BlockSignature)) / sizeof(char16)];
|
||||
};
|
||||
|
||||
struct SpecialFolderDataBlock {
|
||||
u32 SpecialFolderID;
|
||||
u32 Offset;
|
||||
};
|
||||
|
||||
struct TrackerDataBlock {
|
||||
type::Size32 Length;
|
||||
u32 Version;
|
||||
char MachineID[16];
|
||||
type::GUID Droid[2];
|
||||
type::GUID DroidBirth[2];
|
||||
};
|
||||
|
||||
struct VistaAndAboveIDListDataBlock {
|
||||
IDList IDList;
|
||||
};
|
||||
|
||||
struct ExtraDataBlock {
|
||||
type::Size32 BlockSize;
|
||||
|
||||
if (BlockSize < 0x04)
|
||||
break;
|
||||
else {
|
||||
u32 BlockSignature;
|
||||
|
||||
if (BlockSignature == 0xA000'0002)
|
||||
ConsoleDataBlock CONSOLE_PROPS;
|
||||
else if (BlockSignature == 0xA000'0004)
|
||||
ConsoleFEDataBlock CONSOLE_FE_PROPS;
|
||||
else if (BlockSignature == 0xA000'0006)
|
||||
DarwinDataBlock DARWIN_PROPS;
|
||||
else if (BlockSignature == 0xA000'0001)
|
||||
EnvironmentVariableDataBlock ENVIRONMENT_PROPS;
|
||||
else if (BlockSignature == 0xA000'0007)
|
||||
IconEnvironmentDataBlock ICON_ENVIRONMENT_PROPS;
|
||||
else if (BlockSignature == 0xA000'000B)
|
||||
KnownFolderDataBlock KNOWN_FOLDER_PROPS;
|
||||
else if (BlockSignature == 0xA000'0009)
|
||||
PropertyStoreDataBlock PROPERTY_STORE_PROPS;
|
||||
else if (BlockSignature == 0xA000'0008)
|
||||
ShimDataBlock SHIM_PROPS;
|
||||
else if (BlockSignature == 0xA000'0005)
|
||||
SpecialFolderDataBlock SPECIAL_FOLDER_PROPS;
|
||||
else if (BlockSignature == 0xA000'0003)
|
||||
TrackerDataBlock TRACKER_PROPS;
|
||||
else if (BlockSignature == 0xA000'000C)
|
||||
VistaAndAboveIDListDataBlock VISTA_AND_ABOVE_IDLIST_PROPS;
|
||||
}
|
||||
};
|
||||
|
||||
struct ExtraData {
|
||||
ExtraDataBlock ExtraDataBlock[while(true)];
|
||||
};
|
||||
|
||||
struct LNK {
|
||||
ShellLinkHeader ShellLinkHeader;
|
||||
if (ShellLinkHeader.LinkFlags.HasLinkTargetIDList)
|
||||
LinkTargetIDList LinkTargetIDList;
|
||||
if (ShellLinkHeader.LinkFlags.HasLinkInfo)
|
||||
LinkInfo LinkInfo;
|
||||
StringData StringData;
|
||||
ExtraData ExtraData;
|
||||
};
|
||||
|
||||
LNK lnk @ 0x00;
|
||||
|
||||
135
patterns/lua54.hexpat
Normal file
135
patterns/lua54.hexpat
Normal file
@@ -0,0 +1,135 @@
|
||||
#include <std/io.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn transform_Size_array(auto array) {
|
||||
u128 res = 0;
|
||||
for(u8 i = 0, (array[i] & 0x80 == 0) && (i < 9), i+=1) {
|
||||
res <<= 7;
|
||||
res |= array[i] & 0x7f;
|
||||
}
|
||||
res <<= 7;
|
||||
res |= array[sizeof(array)-1] & 0x7f;
|
||||
return res;
|
||||
};
|
||||
|
||||
fn format_Size(auto leb128) {
|
||||
u128 res = impl::transform_Size_array(leb128.array);
|
||||
return std::format("{} ({:#x})", res, res);
|
||||
};
|
||||
|
||||
fn transform_Size(auto leb128) {
|
||||
return impl::transform_Size_array(leb128.array);
|
||||
};
|
||||
|
||||
fn format_LuaString(auto string) {
|
||||
if (string.size == 0) {
|
||||
return "None";
|
||||
}
|
||||
return std::format("\"{}\"", string.data);
|
||||
};
|
||||
|
||||
fn format_Constant(auto const) {
|
||||
return const.data;
|
||||
};
|
||||
|
||||
fn format_Version(auto ver) {
|
||||
return std::format("Ver. {}.{}", ver.major, ver.minor);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
using LuaFunction;
|
||||
|
||||
struct Size {
|
||||
u8 array[while(addressof(this) == $ || ((addressof(this)-$ < 9) && (std::mem::read_unsigned($-1, 1) & 0x80 == 0)))] [[hidden]];
|
||||
} [[sealed, format("impl::format_Size"), transform("impl::transform_Size")]];
|
||||
|
||||
|
||||
bitfield Version {
|
||||
minor : 4;
|
||||
major : 4;
|
||||
} [[format("impl::format_Version")]];
|
||||
|
||||
struct LuaBinaryHeader {
|
||||
u32 magic;
|
||||
Version version_number;
|
||||
u8 format_version;
|
||||
u8 error_detection_data[6];
|
||||
u8 size_of_int;
|
||||
u8 size_of_size_t;
|
||||
u8 size_of_number;
|
||||
u64 luac_int;
|
||||
double luac_num;
|
||||
};
|
||||
struct LuaString {
|
||||
Size size;
|
||||
if (size > 0) {
|
||||
char data[size-1];
|
||||
}
|
||||
}[[format("impl::format_LuaString")]];
|
||||
|
||||
struct LuaConstant {
|
||||
u8 type;
|
||||
if (type == 3) {
|
||||
u64 data;
|
||||
} else if (type == 0x13) {
|
||||
double data;
|
||||
} else if (type == 0x4 || type == 0x14) {
|
||||
LuaString data;
|
||||
}
|
||||
}[[format("impl::format_Constant")]];
|
||||
|
||||
struct LuaUpvalue {
|
||||
u8 instack;
|
||||
u8 idx;
|
||||
u8 kind;
|
||||
};
|
||||
|
||||
struct Vector<T> {
|
||||
Size size;
|
||||
T values[size];
|
||||
};
|
||||
|
||||
|
||||
struct AbsLineInfo {
|
||||
Size pc;
|
||||
Size line;
|
||||
};
|
||||
|
||||
struct LocalVar {
|
||||
LuaString varname;
|
||||
Size startpc;
|
||||
Size endpc;
|
||||
};
|
||||
|
||||
struct LuaDebugInfo {
|
||||
Vector<s8> lineInfo;
|
||||
Vector<AbsLineInfo> abslineinfo;
|
||||
Vector<LocalVar> local_vars;
|
||||
Vector<LuaString> upvalues;
|
||||
};
|
||||
|
||||
struct LuaFunction {
|
||||
LuaString source;
|
||||
Size line_defined;
|
||||
Size last_line_defined;
|
||||
u8 number_of_parameters;
|
||||
u8 is_vararg;
|
||||
u8 maxstacksize;
|
||||
Vector<u32> code;
|
||||
Vector<LuaConstant> constants;
|
||||
Vector<LuaUpvalue> upvalues;
|
||||
Vector<LuaFunction> protos;
|
||||
LuaDebugInfo debugInfo;
|
||||
|
||||
};
|
||||
|
||||
struct LuaFile {
|
||||
LuaBinaryHeader header;
|
||||
u8 size_of_upvalues;
|
||||
LuaFunction func;
|
||||
};
|
||||
|
||||
LuaFile file @ 0;
|
||||
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;
|
||||
};
|
||||
|
||||
enum FileType : u32 {
|
||||
Object = 1,
|
||||
Execute = 2,
|
||||
FVMLib = 3,
|
||||
Core = 4,
|
||||
Preload = 5,
|
||||
DyLib = 6,
|
||||
DyLinker = 7,
|
||||
Bundle = 8,
|
||||
DyLibStub = 9,
|
||||
DSym = 10,
|
||||
KExtBundle = 11,
|
||||
};
|
||||
|
||||
bitfield Flags {
|
||||
noUndefs : 1;
|
||||
incrLink : 1;
|
||||
dyldLink : 1;
|
||||
binDatLoad : 1;
|
||||
prebound : 1;
|
||||
splitSegs : 1;
|
||||
lazyInit : 1;
|
||||
twoLevel : 1;
|
||||
forceFlat : 1;
|
||||
noMultiDefs : 1;
|
||||
noFixPrebinding : 1;
|
||||
prebindable : 1;
|
||||
allModsBound : 1;
|
||||
subSectionsViaSymbols : 1;
|
||||
canonical : 1;
|
||||
weakDefines : 1;
|
||||
bindsToWeak : 1;
|
||||
allowStackExecution : 1;
|
||||
rootSafe : 1;
|
||||
setuidSafe : 1;
|
||||
noReexportedDylibs : 1;
|
||||
pie : 1;
|
||||
deadStrippableDylib : 1;
|
||||
hasTlvDescriptors : 1;
|
||||
noHeapExecution : 1;
|
||||
appExtensionSafe : 1;
|
||||
nlistOutOfSyncWithDyldinof : 1;
|
||||
simSupport : 1;
|
||||
};
|
||||
|
||||
struct Header {
|
||||
Magic magic;
|
||||
CpuType cpuType;
|
||||
if (cpuType == CpuType::VAX) SubCpuTypeVAX subCpuType;
|
||||
else if (cpuType == CpuType::ROMP) SubCpuTypeROMP subCpuType;
|
||||
else if (cpuType == CpuType::BS32032 || cpuType == CpuType::BS32332 || cpuType == CpuType::NS32532) SubCpuType32XXX subCpuType;
|
||||
else if (cpuType == CpuType::I386 || cpuType == CpuType::X86_64) SubCpuTypeI386 subCpuType;
|
||||
else if (cpuType == CpuType::MIPS) SubCpuTypeMips subCpuType;
|
||||
else if (cpuType == CpuType::HPPA) SubCpuTypeHPPA subCpuType;
|
||||
else if (cpuType == CpuType::ARM) SubCpuTypeARM subCpuType;
|
||||
else if (cpuType == CpuType::MC88000) SubCpuTypeMC88000 subCpuType;
|
||||
else if (cpuType == CpuType::MC98000) SubCpuTypeMC98000 subCpuType;
|
||||
else if (cpuType == CpuType::I860 || cpuType == CpuType::I860_LITTLE) SubCpuTypeI860 subCpuType;
|
||||
else if (cpuType == CpuType::SPARC) SubCpuTypeSparc subCpuType;
|
||||
else if (cpuType == CpuType::POWERPC || cpuType == CpuType::POWERPC64) SubCpuTypePowerPC subCpuType;
|
||||
else if (cpuType == CpuType::VEO) SubCpuTypeVEO subCpuType;
|
||||
else u24 subCpuType;
|
||||
Capabilities capabilities;
|
||||
FileType fileType;
|
||||
u32 numCommands;
|
||||
type::Size<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;
|
||||
@@ -1,423 +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;
|
||||
#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;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
76
patterns/nbt.hexpat
Normal file
76
patterns/nbt.hexpat
Normal file
@@ -0,0 +1,76 @@
|
||||
#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 if (parent.tag == Tag::IntArray){
|
||||
s32 arrayLength;
|
||||
s32 value[arrayLength] [[sealed]];
|
||||
} else if (parent.tag == Tag::LongArray) {
|
||||
s32 arrayLength;
|
||||
s64 value[arrayLength] [[sealed]];
|
||||
} 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;
|
||||
262
patterns/ne.hexpat
Normal file
262
patterns/ne.hexpat
Normal file
@@ -0,0 +1,262 @@
|
||||
#include <std/mem.pat>
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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;
|
||||
@@ -1,161 +1,165 @@
|
||||
bitfield AccessCapability {
|
||||
Read : 4;
|
||||
Write : 4;
|
||||
} [[left_to_right]];
|
||||
|
||||
struct CapabilityContainer {
|
||||
u8 magic;
|
||||
u8 version;
|
||||
u8 memorySize;
|
||||
AccessCapability accessCapability;
|
||||
};
|
||||
|
||||
bitfield NDEFFlags {
|
||||
MB : 1;
|
||||
ME : 1;
|
||||
CF : 1;
|
||||
SR : 1;
|
||||
IL : 1;
|
||||
TNF : 3;
|
||||
} [[left_to_right]];
|
||||
|
||||
enum TNFType : u8 {
|
||||
Empty = 0x00,
|
||||
NFCForumWellKnownType = 0x01,
|
||||
MediaType = 0x02,
|
||||
AbsoluteURI = 0x03,
|
||||
NFCForumExternalType = 0x04,
|
||||
Unknown = 0x05,
|
||||
Unchanged = 0x06,
|
||||
Reserved = 0x07
|
||||
};
|
||||
|
||||
struct NDEF {
|
||||
NDEFFlags flags;
|
||||
u8 typeLength;
|
||||
|
||||
if (flags.SR)
|
||||
u8 payloadLength;
|
||||
else
|
||||
u32 payloadLength;
|
||||
|
||||
if (flags.IL)
|
||||
u8 idLength;
|
||||
|
||||
char type[typeLength];
|
||||
|
||||
if (flags.IL)
|
||||
u8 id[idLength];
|
||||
|
||||
u8 payload[payloadLength];
|
||||
|
||||
if (flags.ME)
|
||||
break;
|
||||
};
|
||||
|
||||
struct LockControl {
|
||||
u8 dynamicLockByteOffset;
|
||||
u8 numBits;
|
||||
u8 pageControlInfo;
|
||||
};
|
||||
|
||||
struct MemoryControl {
|
||||
u8 reservedBytesOffset;
|
||||
u8 numBytes;
|
||||
u8 pageSize;
|
||||
};
|
||||
|
||||
struct Length {
|
||||
u8 byte [[hidden, no_unique_address]];
|
||||
if (byte == 0xFF)
|
||||
u24 length;
|
||||
else
|
||||
u8 length;
|
||||
} [[sealed, transform("transform_length"), format("transform_length")]];
|
||||
|
||||
fn transform_length(Length length) {
|
||||
return length.length;
|
||||
};
|
||||
|
||||
enum Tag : u8 {
|
||||
NULL = 0x00,
|
||||
LockControl = 0x01,
|
||||
MemoryControl = 0x02,
|
||||
NDEFMessage = 0x03,
|
||||
Proprietary = 0xFD,
|
||||
TerminatorTLV = 0xFE
|
||||
};
|
||||
|
||||
struct TLV {
|
||||
Tag tag;
|
||||
if (tag == Tag::TerminatorTLV) {
|
||||
break;
|
||||
} else if (tag == Tag::NULL) {
|
||||
// Empty
|
||||
} else {
|
||||
Length length;
|
||||
|
||||
if (length > 0) {
|
||||
if (tag == Tag::LockControl) {
|
||||
LockControl lockControl;
|
||||
} else if (tag == Tag::MemoryControl) {
|
||||
LockControl lockControl;
|
||||
} else if (tag == Tag::NDEFMessage) {
|
||||
NDEF ndef[while(true)];
|
||||
} else {
|
||||
u8 value[length];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct ManufacturerData {
|
||||
u8 serial1[3];
|
||||
u8 checkByte0;
|
||||
u8 serial2[4];
|
||||
u8 checkByte1;
|
||||
u8 internal;
|
||||
u16 lockBytes;
|
||||
};
|
||||
|
||||
struct DynamicLockBytes {
|
||||
u8 bytes[3];
|
||||
u8 RFUI;
|
||||
};
|
||||
|
||||
bitfield MIRROR {
|
||||
MIRROR_CONF : 2;
|
||||
MIRROR_BYTE : 2;
|
||||
RFUI : 1;
|
||||
STRG_MOD_EN : 1;
|
||||
RFUI : 2;
|
||||
} [[left_to_right]];
|
||||
|
||||
bitfield ACCESS {
|
||||
PROT : 1;
|
||||
CFGLCK : 1;
|
||||
RFUI : 1;
|
||||
NFC_CNT_EN : 1;
|
||||
NFC_CNT_PWD_PROT : 1;
|
||||
AUTHLIM : 3;
|
||||
};
|
||||
|
||||
struct Config {
|
||||
MIRROR MIRROR;
|
||||
u8 MIRROR_PAGE;
|
||||
u8 AUTH0;
|
||||
ACCESS ACCESS;
|
||||
u32 PWD;
|
||||
u16 PACK;
|
||||
};
|
||||
|
||||
struct NTAG {
|
||||
ManufacturerData manufacturerData;
|
||||
CapabilityContainer cc;
|
||||
TLV tlv[while(true)];
|
||||
padding[addressof(tlv) + cc.memorySize * 8 - sizeof(tlv)];
|
||||
DynamicLockBytes dynamicLockBytes;
|
||||
Config config;
|
||||
};
|
||||
|
||||
NTAG ntag @ 0x00;
|
||||
#include <std/core.pat>
|
||||
|
||||
using BitfieldOrder = std::core::BitfieldOrder;
|
||||
|
||||
bitfield AccessCapability {
|
||||
Read : 4;
|
||||
Write : 4;
|
||||
} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 8)]];
|
||||
|
||||
struct CapabilityContainer {
|
||||
u8 magic;
|
||||
u8 version;
|
||||
u8 memorySize;
|
||||
be AccessCapability accessCapability;
|
||||
};
|
||||
|
||||
bitfield NDEFFlags {
|
||||
MB : 1;
|
||||
ME : 1;
|
||||
CF : 1;
|
||||
SR : 1;
|
||||
IL : 1;
|
||||
TNF : 3;
|
||||
} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 8)]];
|
||||
|
||||
enum TNFType : u8 {
|
||||
Empty = 0x00,
|
||||
NFCForumWellKnownType = 0x01,
|
||||
MediaType = 0x02,
|
||||
AbsoluteURI = 0x03,
|
||||
NFCForumExternalType = 0x04,
|
||||
Unknown = 0x05,
|
||||
Unchanged = 0x06,
|
||||
Reserved = 0x07
|
||||
};
|
||||
|
||||
struct NDEF {
|
||||
NDEFFlags flags;
|
||||
u8 typeLength;
|
||||
|
||||
if (flags.SR)
|
||||
u8 payloadLength;
|
||||
else
|
||||
u32 payloadLength;
|
||||
|
||||
if (flags.IL)
|
||||
u8 idLength;
|
||||
|
||||
char type[typeLength];
|
||||
|
||||
if (flags.IL)
|
||||
u8 id[idLength];
|
||||
|
||||
u8 payload[payloadLength];
|
||||
|
||||
if (flags.ME)
|
||||
break;
|
||||
};
|
||||
|
||||
struct LockControl {
|
||||
u8 dynamicLockByteOffset;
|
||||
u8 numBits;
|
||||
u8 pageControlInfo;
|
||||
};
|
||||
|
||||
struct MemoryControl {
|
||||
u8 reservedBytesOffset;
|
||||
u8 numBytes;
|
||||
u8 pageSize;
|
||||
};
|
||||
|
||||
struct Length {
|
||||
u8 byte [[hidden, no_unique_address]];
|
||||
if (byte == 0xFF)
|
||||
u24 length;
|
||||
else
|
||||
u8 length;
|
||||
} [[sealed, transform("transform_length"), format("transform_length")]];
|
||||
|
||||
fn transform_length(Length length) {
|
||||
return length.length;
|
||||
};
|
||||
|
||||
enum Tag : u8 {
|
||||
NULL = 0x00,
|
||||
LockControl = 0x01,
|
||||
MemoryControl = 0x02,
|
||||
NDEFMessage = 0x03,
|
||||
Proprietary = 0xFD,
|
||||
TerminatorTLV = 0xFE
|
||||
};
|
||||
|
||||
struct TLV {
|
||||
Tag tag;
|
||||
if (tag == Tag::TerminatorTLV) {
|
||||
break;
|
||||
} else if (tag == Tag::NULL) {
|
||||
// Empty
|
||||
} else {
|
||||
Length length;
|
||||
|
||||
if (length > 0) {
|
||||
if (tag == Tag::LockControl) {
|
||||
LockControl lockControl;
|
||||
} else if (tag == Tag::MemoryControl) {
|
||||
LockControl lockControl;
|
||||
} else if (tag == Tag::NDEFMessage) {
|
||||
NDEF ndef[while(true)];
|
||||
} else {
|
||||
u8 value[length];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct ManufacturerData {
|
||||
u8 serial1[3];
|
||||
u8 checkByte0;
|
||||
u8 serial2[4];
|
||||
u8 checkByte1;
|
||||
u8 internal;
|
||||
u16 lockBytes;
|
||||
};
|
||||
|
||||
struct DynamicLockBytes {
|
||||
u8 bytes[3];
|
||||
padding[1];
|
||||
};
|
||||
|
||||
bitfield MIRROR {
|
||||
MIRROR_CONF : 2;
|
||||
MIRROR_BYTE : 2;
|
||||
padding : 1;
|
||||
STRG_MOD_EN : 1;
|
||||
padding : 2;
|
||||
} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 8)]];
|
||||
|
||||
bitfield ACCESS {
|
||||
PROT : 1;
|
||||
CFGLCK : 1;
|
||||
padding : 1;
|
||||
NFC_CNT_EN : 1;
|
||||
NFC_CNT_PWD_PROT : 1;
|
||||
AUTHLIM : 3;
|
||||
};
|
||||
|
||||
struct Config {
|
||||
MIRROR MIRROR;
|
||||
u8 MIRROR_PAGE;
|
||||
u8 AUTH0;
|
||||
ACCESS ACCESS;
|
||||
u32 PWD;
|
||||
u16 PACK;
|
||||
};
|
||||
|
||||
struct NTAG {
|
||||
ManufacturerData manufacturerData;
|
||||
CapabilityContainer cc;
|
||||
TLV tlv[while(true)];
|
||||
padding[addressof(tlv) + cc.memorySize * 8 - sizeof(tlv)];
|
||||
DynamicLockBytes dynamicLockBytes;
|
||||
Config config;
|
||||
};
|
||||
|
||||
NTAG ntag @ 0x00;
|
||||
|
||||
40
patterns/pbz.hexpat
Normal file
40
patterns/pbz.hexpat
Normal file
@@ -0,0 +1,40 @@
|
||||
// Apple pbz compressed file
|
||||
// Used by Apple on .xip files and OTA updates,
|
||||
// and can be created with macOS compression_tool.
|
||||
//
|
||||
// Copyright (c) 2023 Nicolás Alvarez <nicolas.alvarez@gmail.com>
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <std/mem.pat>
|
||||
#include <type/magic.pat>
|
||||
|
||||
#pragma endian big
|
||||
|
||||
#define SHOW_DATA 0
|
||||
|
||||
enum CompressionType: char {
|
||||
ZLIB = 'z',
|
||||
LZMA = 'x',
|
||||
LZ4 = '4',
|
||||
LZFSE = 'e'
|
||||
};
|
||||
|
||||
struct Chunk {
|
||||
u64 uncompressed_size;
|
||||
u64 compressed_size;
|
||||
if (SHOW_DATA) {
|
||||
u8 data[compressed_size] [[sealed]];
|
||||
} else {
|
||||
padding[compressed_size];
|
||||
}
|
||||
};
|
||||
|
||||
struct PBZ {
|
||||
type::Magic<"pbz"> magic;
|
||||
CompressionType compression;
|
||||
u64 chunk_size;
|
||||
Chunk chunks[while(!std::mem::eof())];
|
||||
};
|
||||
|
||||
PBZ pbz @ 0;
|
||||
@@ -1,140 +1,155 @@
|
||||
#include <std/mem.pat>
|
||||
#pragma MIME application/vnd.tcpdump.pcap
|
||||
#pragma endian little
|
||||
|
||||
enum network_type : u32 {
|
||||
LINKTYPE_NULL = 0,
|
||||
LINKTYPE_ETHERNET = 1,
|
||||
LINKTYPE_AX25 = 3,
|
||||
LINKTYPE_IEEE802_5 = 6,
|
||||
LINKTYPE_ARCNET_BSD = 7,
|
||||
LINKTYPE_SLIP = 8,
|
||||
LINKTYPE_PPP = 9,
|
||||
LINKTYPE_FDDI = 10,
|
||||
LINKTYPE_PPP_HDLC = 50,
|
||||
LINKTYPE_PPP_ETHER = 51,
|
||||
LINKTYPE_ATM_RFC1483 = 100,
|
||||
LINKTYPE_RAW = 101,
|
||||
LINKTYPE_C_HDLC = 104,
|
||||
LINKTYPE_IEEE802_11 = 105,
|
||||
LINKTYPE_FRELAY = 107,
|
||||
LINKTYPE_LOOP = 108,
|
||||
LINKTYPE_LINUX_SLL = 113,
|
||||
LINKTYPE_LTALK = 114,
|
||||
LINKTYPE_PFLOG = 117,
|
||||
LINKTYPE_IEEE802_11_PRISM = 119,
|
||||
LINKTYPE_IP_OVER_FC = 122,
|
||||
LINKTYPE_SUNATM = 123,
|
||||
LINKTYPE_IEEE802_11_RADIOTAP = 127,
|
||||
LINKTYPE_ARCNET_LINUX = 129,
|
||||
LINKTYPE_APPLE_IP_OVER_IEEE1394 = 138,
|
||||
LINKTYPE_MTP2_WITH_PHDR = 139,
|
||||
LINKTYPE_MTP2 = 140,
|
||||
LINKTYPE_MTP3 = 141,
|
||||
LINKTYPE_SCCP = 142,
|
||||
LINKTYPE_DOCSIS = 143,
|
||||
LINKTYPE_LINUX_IRDA = 144,
|
||||
LINKTYPE_IEEE802_11_AVS = 163,
|
||||
LINKTYPE_BACNET_MS_TP = 165,
|
||||
LINKTYPE_PPP_PPPD = 166,
|
||||
LINKTYPE_GPRS_LLC = 169,
|
||||
LINKTYPE_GPF_T = 170,
|
||||
LINKTYPE_GPF_F = 171,
|
||||
LINKTYPE_LINUX_LAPD = 177,
|
||||
LINKTYPE_MFR = 182,
|
||||
LINKTYPE_BLUETOOTH_HCI_H4 = 187,
|
||||
LINKTYPE_USB_LINUX = 189,
|
||||
LINKTYPE_PPI = 192,
|
||||
LINKTYPE_IEEE802_15_4_WITHFCS = 195,
|
||||
LINKTYPE_SITA = 196,
|
||||
LINKTYPE_ERF = 197,
|
||||
LINKTYPE_BLUETOOTH_HCI_H4_WITH_PHDR = 201,
|
||||
LINKTYPE_AX25_KISS = 202,
|
||||
LINKTYPE_LAPD = 203,
|
||||
LINKTYPE_PPP_WITH_DIR = 204,
|
||||
LINKTYPE_C_HDLC_WITH_DIR = 205,
|
||||
LINKTYPE_FRELAY_WITH_DIR = 206,
|
||||
LINKTYPE_LAPB_WITH_DIR = 207,
|
||||
LINKTYPE_IPMB_LINUX = 209,
|
||||
LINKTYPE_FLEXRAY = 210,
|
||||
LINKTYPE_IEEE802_15_4_NONASK_PHY = 215,
|
||||
LINKTYPE_USB_LINUX_MMAPPED = 220,
|
||||
LINKTYPE_FC_2 = 224,
|
||||
LINKTYPE_FC_2_WITH_FRAME_DELIMS = 225,
|
||||
LINKTYPE_IPNET = 226,
|
||||
LINKTYPE_CAN_SOCKETCAN = 227,
|
||||
LINKTYPE_IPV4 = 228,
|
||||
LINKTYPE_IPV6 = 229,
|
||||
LINKTYPE_IEEE802_15_4_NOFCS = 230,
|
||||
LINKTYPE_DBUS = 231,
|
||||
LINKTYPE_DVB_CI = 235,
|
||||
LINKTYPE_MUX27010 = 236,
|
||||
LINKTYPE_STANAG_5066_D_PDU = 237,
|
||||
LINKTYPE_NFLOG = 239,
|
||||
LINKTYPE_NETANALYZER = 240,
|
||||
LINKTYPE_NETANALYZER_TRANSPARENT = 241,
|
||||
LINKTYPE_IPOIB = 242,
|
||||
LINKTYPE_MPEG_2_TS = 243,
|
||||
LINKTYPE_NG40 = 244,
|
||||
LINKTYPE_NFC_LLCP = 245,
|
||||
LINKTYPE_INFINIBAND = 247,
|
||||
LINKTYPE_SCTP = 248,
|
||||
LINKTYPE_USBPCAP = 249,
|
||||
LINKTYPE_RTAC_SERIAL = 250,
|
||||
LINKTYPE_BLUETOOTH_LE_LL = 251,
|
||||
LINKTYPE_NETLINK = 253,
|
||||
LINKTYPE_BLUETOOTH_LINUX_MONITOR = 254,
|
||||
LINKTYPE_BLUETOOTH_BREDR_BB = 255,
|
||||
LINKTYPE_BLUETOOTH_LE_LL_WITH_PHDR = 256,
|
||||
LINKTYPE_PROFIBUS_DL = 257,
|
||||
LINKTYPE_PKTAP = 258,
|
||||
LINKTYPE_EPON = 259,
|
||||
LINKTYPE_IPMI_HPM_2 = 260,
|
||||
LINKTYPE_ZWAVE_R1_R2 = 261,
|
||||
LINKTYPE_ZWAVE_R3 = 262,
|
||||
LINKTYPE_WATTSTOPPER_DLM = 263,
|
||||
LINKTYPE_ISO_14443 = 264,
|
||||
LINKTYPE_RDS = 265,
|
||||
LINKTYPE_USB_DARWIN = 266,
|
||||
LINKTYPE_SDLC = 268,
|
||||
LINKTYPE_LORATAP = 270,
|
||||
LINKTYPE_VSOCK = 271,
|
||||
LINKTYPE_NORDIC_BLE = 272,
|
||||
LINKTYPE_DOCSIS31_XRA31 = 273,
|
||||
LINKTYPE_ETHERNET_MPACKET = 274,
|
||||
LINKTYPE_DISPLAYPORT_AUX = 275,
|
||||
LINKTYPE_LINUX_SLL2 = 276,
|
||||
LINKTYPE_OPENVIZSLA = 278,
|
||||
LINKTYPE_EBHSCR = 279,
|
||||
LINKTYPE_VPP_DISPATCH = 280,
|
||||
LINKTYPE_DSA_TAG_BRCM = 281,
|
||||
LINKTYPE_DSA_TAG_BRCM_PREPEND = 282,
|
||||
LINKTYPE_IEEE802_15_4_TAP = 283,
|
||||
LINKTYPE_DSA_TAG_DSA = 284,
|
||||
LINKTYPE_DSA_TAG_EDSA = 285,
|
||||
LINKTYPE_ELEE = 286,
|
||||
LINKTYPE_Z_WAVE_SERIAL = 287,
|
||||
LINKTYPE_USB_2_0 = 288,
|
||||
LINKTYPE_ATSC_ALP = 289,
|
||||
LINKTYPE_ETW = 290
|
||||
LINKTYPE_NULL = 0,
|
||||
LINKTYPE_ETHERNET = 1,
|
||||
LINKTYPE_AX25 = 3,
|
||||
LINKTYPE_IEEE802_5 = 6,
|
||||
LINKTYPE_ARCNET_BSD = 7,
|
||||
LINKTYPE_SLIP = 8,
|
||||
LINKTYPE_PPP = 9,
|
||||
LINKTYPE_FDDI = 10,
|
||||
LINKTYPE_PPP_HDLC = 50,
|
||||
LINKTYPE_PPP_ETHER = 51,
|
||||
LINKTYPE_ATM_RFC1483 = 100,
|
||||
LINKTYPE_RAW = 101,
|
||||
LINKTYPE_C_HDLC = 104,
|
||||
LINKTYPE_IEEE802_11 = 105,
|
||||
LINKTYPE_FRELAY = 107,
|
||||
LINKTYPE_LOOP = 108,
|
||||
LINKTYPE_LINUX_SLL = 113,
|
||||
LINKTYPE_LTALK = 114,
|
||||
LINKTYPE_PFLOG = 117,
|
||||
LINKTYPE_IEEE802_11_PRISM = 119,
|
||||
LINKTYPE_IP_OVER_FC = 122,
|
||||
LINKTYPE_SUNATM = 123,
|
||||
LINKTYPE_IEEE802_11_RADIOTAP = 127,
|
||||
LINKTYPE_ARCNET_LINUX = 129,
|
||||
LINKTYPE_APPLE_IP_OVER_IEEE1394 = 138,
|
||||
LINKTYPE_MTP2_WITH_PHDR = 139,
|
||||
LINKTYPE_MTP2 = 140,
|
||||
LINKTYPE_MTP3 = 141,
|
||||
LINKTYPE_SCCP = 142,
|
||||
LINKTYPE_DOCSIS = 143,
|
||||
LINKTYPE_LINUX_IRDA = 144,
|
||||
LINKTYPE_IEEE802_11_AVS = 163,
|
||||
LINKTYPE_BACNET_MS_TP = 165,
|
||||
LINKTYPE_PPP_PPPD = 166,
|
||||
LINKTYPE_GPRS_LLC = 169,
|
||||
LINKTYPE_GPF_T = 170,
|
||||
LINKTYPE_GPF_F = 171,
|
||||
LINKTYPE_LINUX_LAPD = 177,
|
||||
LINKTYPE_MFR = 182,
|
||||
LINKTYPE_BLUETOOTH_HCI_H4 = 187,
|
||||
LINKTYPE_USB_LINUX = 189,
|
||||
LINKTYPE_PPI = 192,
|
||||
LINKTYPE_IEEE802_15_4_WITHFCS = 195,
|
||||
LINKTYPE_SITA = 196,
|
||||
LINKTYPE_ERF = 197,
|
||||
LINKTYPE_BLUETOOTH_HCI_H4_WITH_PHDR = 201,
|
||||
LINKTYPE_AX25_KISS = 202,
|
||||
LINKTYPE_LAPD = 203,
|
||||
LINKTYPE_PPP_WITH_DIR = 204,
|
||||
LINKTYPE_C_HDLC_WITH_DIR = 205,
|
||||
LINKTYPE_FRELAY_WITH_DIR = 206,
|
||||
LINKTYPE_LAPB_WITH_DIR = 207,
|
||||
LINKTYPE_IPMB_LINUX = 209,
|
||||
LINKTYPE_FLEXRAY = 210,
|
||||
LINKTYPE_IEEE802_15_4_NONASK_PHY = 215,
|
||||
LINKTYPE_USB_LINUX_MMAPPED = 220,
|
||||
LINKTYPE_FC_2 = 224,
|
||||
LINKTYPE_FC_2_WITH_FRAME_DELIMS = 225,
|
||||
LINKTYPE_IPNET = 226,
|
||||
LINKTYPE_CAN_SOCKETCAN = 227,
|
||||
LINKTYPE_IPV4 = 228,
|
||||
LINKTYPE_IPV6 = 229,
|
||||
LINKTYPE_IEEE802_15_4_NOFCS = 230,
|
||||
LINKTYPE_DBUS = 231,
|
||||
LINKTYPE_DVB_CI = 235,
|
||||
LINKTYPE_MUX27010 = 236,
|
||||
LINKTYPE_STANAG_5066_D_PDU = 237,
|
||||
LINKTYPE_NFLOG = 239,
|
||||
LINKTYPE_NETANALYZER = 240,
|
||||
LINKTYPE_NETANALYZER_TRANSPARENT = 241,
|
||||
LINKTYPE_IPOIB = 242,
|
||||
LINKTYPE_MPEG_2_TS = 243,
|
||||
LINKTYPE_NG40 = 244,
|
||||
LINKTYPE_NFC_LLCP = 245,
|
||||
LINKTYPE_INFINIBAND = 247,
|
||||
LINKTYPE_SCTP = 248,
|
||||
LINKTYPE_USBPCAP = 249,
|
||||
LINKTYPE_RTAC_SERIAL = 250,
|
||||
LINKTYPE_BLUETOOTH_LE_LL = 251,
|
||||
LINKTYPE_NETLINK = 253,
|
||||
LINKTYPE_BLUETOOTH_LINUX_MONITOR = 254,
|
||||
LINKTYPE_BLUETOOTH_BREDR_BB = 255,
|
||||
LINKTYPE_BLUETOOTH_LE_LL_WITH_PHDR = 256,
|
||||
LINKTYPE_PROFIBUS_DL = 257,
|
||||
LINKTYPE_PKTAP = 258,
|
||||
LINKTYPE_EPON = 259,
|
||||
LINKTYPE_IPMI_HPM_2 = 260,
|
||||
LINKTYPE_ZWAVE_R1_R2 = 261,
|
||||
LINKTYPE_ZWAVE_R3 = 262,
|
||||
LINKTYPE_WATTSTOPPER_DLM = 263,
|
||||
LINKTYPE_ISO_14443 = 264,
|
||||
LINKTYPE_RDS = 265,
|
||||
LINKTYPE_USB_DARWIN = 266,
|
||||
LINKTYPE_SDLC = 268,
|
||||
LINKTYPE_LORATAP = 270,
|
||||
LINKTYPE_VSOCK = 271,
|
||||
LINKTYPE_NORDIC_BLE = 272,
|
||||
LINKTYPE_DOCSIS31_XRA31 = 273,
|
||||
LINKTYPE_ETHERNET_MPACKET = 274,
|
||||
LINKTYPE_DISPLAYPORT_AUX = 275,
|
||||
LINKTYPE_LINUX_SLL2 = 276,
|
||||
LINKTYPE_OPENVIZSLA = 278,
|
||||
LINKTYPE_EBHSCR = 279,
|
||||
LINKTYPE_VPP_DISPATCH = 280,
|
||||
LINKTYPE_DSA_TAG_BRCM = 281,
|
||||
LINKTYPE_DSA_TAG_BRCM_PREPEND = 282,
|
||||
LINKTYPE_IEEE802_15_4_TAP = 283,
|
||||
LINKTYPE_DSA_TAG_DSA = 284,
|
||||
LINKTYPE_DSA_TAG_EDSA = 285,
|
||||
LINKTYPE_ELEE = 286,
|
||||
LINKTYPE_Z_WAVE_SERIAL = 287,
|
||||
LINKTYPE_USB_2_0 = 288,
|
||||
LINKTYPE_ATSC_ALP = 289,
|
||||
LINKTYPE_ETW = 290
|
||||
};
|
||||
|
||||
struct pcaprec_hdr_t {
|
||||
u32 ts_sec; /* timestamp seconds */
|
||||
u32 ts_usec; /* timestamp microseconds */
|
||||
u32 incl_len; /* number of octets of packet saved in file */
|
||||
u32 orig_len; /* actual length of packet */
|
||||
u8 data[incl_len];
|
||||
enum magic : u32 {
|
||||
BE = 0xA1B2C3D4,
|
||||
LE = 0xD4C3B2A1
|
||||
};
|
||||
|
||||
struct pcap_hdr_t {
|
||||
u32 magic_number; /* magic number */
|
||||
u16 version_major; /* major version number */
|
||||
u16 version_minor; /* minor version number */
|
||||
s32 thiszone; /* GMT to local correction */
|
||||
u32 sigfigs; /* accuracy of timestamps */
|
||||
u32 snaplen; /* max length of captured packets, in octets */
|
||||
network_type network; /* data link type */
|
||||
pcaprec_hdr_t packet[1000];
|
||||
|
||||
struct pcap_record_t {
|
||||
u32 ts_sec; /* timestamp seconds */
|
||||
u32 ts_usec; /* timestamp microseconds */
|
||||
u32 incl_len; /* number of octets of packet saved in file */
|
||||
u32 orig_len; /* actual length of packet */
|
||||
u8 data[incl_len];
|
||||
};
|
||||
|
||||
pcap_hdr_t pcap @ 0x00;
|
||||
struct pcap_header_t {
|
||||
u16 version_major; /* major version number */
|
||||
u16 version_minor; /* minor version number */
|
||||
s32 thiszone; /* GMT to local correction */
|
||||
u32 sigfigs; /* accuracy of timestamps */
|
||||
u32 snaplen; /* max length of captured packets, in octets */
|
||||
network_type network; /* data link type */
|
||||
};
|
||||
|
||||
struct pcap {
|
||||
be magic magic_number;
|
||||
if (magic_number == magic::BE) {
|
||||
be pcap_header_t header;
|
||||
be pcap_record_t packet[while(!std::mem::eof())];
|
||||
} else {
|
||||
le pcap_header_t header;
|
||||
le pcap_record_t packet[while(!std::mem::eof())];
|
||||
}
|
||||
};
|
||||
|
||||
pcap pcap @ 0x00;
|
||||
|
||||
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;
|
||||
76
patterns/pif.hexpat
Normal file
76
patterns/pif.hexpat
Normal file
@@ -0,0 +1,76 @@
|
||||
/* PIF - Portable Image Format
|
||||
*
|
||||
* Basic decoder for the PIF file structure
|
||||
* https://github.com/gfcwfzkm/PIF-Image-Format
|
||||
*/
|
||||
|
||||
#pragma MIME image/pif
|
||||
#pragma endian little
|
||||
|
||||
enum imageType_t : u16 {
|
||||
RGB888 = 0x433C,
|
||||
RGB565 = 0xE5C5,
|
||||
RGB332 = 0x1E53,
|
||||
RGB16C = 0xB895,
|
||||
BLWH = 0x7DAA,
|
||||
IND24 = 0x4952,
|
||||
IND16 = 0x4947,
|
||||
IND8 = 0x4942
|
||||
};
|
||||
|
||||
enum compression_t : u16 {
|
||||
NO_COMPRESSION = 0,
|
||||
RLE_COMPRESSION = 0x7DDE
|
||||
};
|
||||
|
||||
struct PIFFileHeader {
|
||||
char Signature[4];
|
||||
u32 FileSize;
|
||||
u32 ImageOffset;
|
||||
};
|
||||
|
||||
struct PIFInfoHeader {
|
||||
imageType_t ImageType;
|
||||
u16 BitsPerPixel;
|
||||
u16 ImageWidth;
|
||||
u16 ImageHeight;
|
||||
u32 ImageSize;
|
||||
u16 ColorTableSize;
|
||||
compression_t Compression;
|
||||
};
|
||||
|
||||
struct PIF {
|
||||
PIFFileHeader PIF_FileHeader;
|
||||
PIFInfoHeader PIF_ImageHeader;
|
||||
|
||||
if (PIF_ImageHeader.ImageType == imageType_t::IND24)
|
||||
{
|
||||
u24 ColorTable[PIF_ImageHeader.ColorTableSize/3];
|
||||
}
|
||||
else if (PIF_ImageHeader.ImageType == imageType_t::IND16)
|
||||
{
|
||||
u16 ColorTable[PIF_ImageHeader.ColorTableSize/2];
|
||||
}
|
||||
else if (PIF_ImageHeader.ImageType == imageType_t::IND8)
|
||||
{
|
||||
u8 ColorTable[PIF_ImageHeader.ColorTableSize];
|
||||
}
|
||||
|
||||
if ((PIF_ImageHeader.ImageType == imageType_t::RGB888) ||
|
||||
(PIF_ImageHeader.ImageType == imageType_t::IND24))
|
||||
{
|
||||
u24 ImageData[(PIF_FileHeader.FileSize - PIF_FileHeader.ImageOffset)/3];
|
||||
}
|
||||
else if ((PIF_ImageHeader.ImageType == imageType_t::RGB565) ||
|
||||
(PIF_ImageHeader.ImageType == imageType_t::IND16))
|
||||
{
|
||||
u16 ImageData[(PIF_FileHeader.FileSize - PIF_FileHeader.ImageOffset)/2];
|
||||
}
|
||||
else if ((PIF_ImageHeader.ImageType == imageType_t::RGB332) ||
|
||||
(PIF_ImageHeader.ImageType == imageType_t::IND8))
|
||||
{
|
||||
u8 ImageData[(PIF_FileHeader.FileSize - PIF_FileHeader.ImageOffset)/1];
|
||||
}
|
||||
};
|
||||
|
||||
PIF pif @ 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")]];
|
||||
@@ -1,66 +1,67 @@
|
||||
#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;
|
||||
#include <std/core.pat>
|
||||
#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;
|
||||
} [[bitfield_order(std::core::BitfieldOrder::MostToLeastSignificant, 8)]];
|
||||
|
||||
union _64Bit {
|
||||
u64 fixed64;
|
||||
ZigZag64 sfixed64;
|
||||
double dbl;
|
||||
};
|
||||
|
||||
union _32Bit {
|
||||
u32 fixed32;
|
||||
ZigZag32 sfixed32;
|
||||
float flt;
|
||||
};
|
||||
|
||||
struct LengthDelimited {
|
||||
type::LEB128 length;
|
||||
char data[length];
|
||||
};
|
||||
|
||||
|
||||
struct Entry {
|
||||
Key key;
|
||||
|
||||
if (key.wire_type == WireType::Varint)
|
||||
type::LEB128 value;
|
||||
else if (key.wire_type == WireType::_64Bit)
|
||||
_64Bit value;
|
||||
else if (key.wire_type == WireType::LengthDelimited)
|
||||
LengthDelimited value;
|
||||
else if (key.wire_type == WireType::_32Bit)
|
||||
_32Bit value;
|
||||
};
|
||||
|
||||
Entry entries[while(!std::mem::eof())] @ 0x00;
|
||||
|
||||
80
patterns/qbcl.hexpat
Normal file
80
patterns/qbcl.hexpat
Normal file
@@ -0,0 +1,80 @@
|
||||
// Qubicle QBCL format
|
||||
|
||||
struct String {
|
||||
u32 len;
|
||||
char string[len];
|
||||
};
|
||||
|
||||
struct Matrix {
|
||||
u32 sizex;
|
||||
u32 sizey;
|
||||
u32 sizez;
|
||||
s32 tx;
|
||||
s32 ty;
|
||||
s32 tz;
|
||||
float pivotx;
|
||||
float pivoty;
|
||||
float pivotz;
|
||||
u32 compressedDataSize;
|
||||
u8 zip[compressedDataSize];
|
||||
};
|
||||
|
||||
// Rotation matrix according to wikipedia
|
||||
// https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
|
||||
struct Matrices {
|
||||
float row1[3];
|
||||
float row2[3];
|
||||
float row3[3];
|
||||
};
|
||||
|
||||
using Node;
|
||||
|
||||
struct Model {
|
||||
Matrices rotation;
|
||||
u32 childCount;
|
||||
Node nodes[childCount];
|
||||
};
|
||||
|
||||
struct Compound {
|
||||
Matrix matrix;
|
||||
u32 childCount;
|
||||
Node nodes[childCount];
|
||||
};
|
||||
|
||||
struct Node {
|
||||
u32 type;
|
||||
u32 unknown;
|
||||
String name;
|
||||
u8 visible;
|
||||
u8 unknown2;
|
||||
u8 locked;
|
||||
if (type == 0) {
|
||||
Matrix matrix;
|
||||
} else if (type == 1) {
|
||||
Model model;
|
||||
} else if (type == 2) {
|
||||
Compound compound;
|
||||
}
|
||||
};
|
||||
|
||||
struct Header {
|
||||
u32 magic;
|
||||
u32 version;
|
||||
u32 fileversion;
|
||||
u32 thumbwidth;
|
||||
u32 thumbheight;
|
||||
char bgra[thumbwidth * thumbheight * 4];
|
||||
String title;
|
||||
String desc;
|
||||
String metadata;
|
||||
String author;
|
||||
String company;
|
||||
String website;
|
||||
String copyright;
|
||||
// Maybe change and creation time?
|
||||
double time1;
|
||||
double time2;
|
||||
Node node;
|
||||
};
|
||||
|
||||
Header hdr @0x00;
|
||||
98
patterns/qoi.hexpat
Normal file
98
patterns/qoi.hexpat
Normal file
@@ -0,0 +1,98 @@
|
||||
#pragma MIME image/qoi
|
||||
#pragma endian big
|
||||
|
||||
#include <std/mem.pat>
|
||||
|
||||
namespace qoi {
|
||||
|
||||
enum channels_t : u8 {
|
||||
RGB = 3,
|
||||
RGBA = 4
|
||||
};
|
||||
|
||||
enum color_space_t : u8 {
|
||||
sRGB = 0,
|
||||
linear = 1
|
||||
};
|
||||
|
||||
struct header_t {
|
||||
char magic[4];
|
||||
u32 width;
|
||||
u32 height;
|
||||
channels_t channels;
|
||||
color_space_t color_space;
|
||||
};
|
||||
|
||||
enum tags_t : u8 {
|
||||
index = 0b00000000 ... 0b00111111,
|
||||
diff = 0b01000000 ... 0b01111111,
|
||||
luma = 0b10000000 ... 0b10111111,
|
||||
run = 0b11000000 ... 0b11111101,
|
||||
rgb = 0b11111110,
|
||||
rgba = 0b11111111,
|
||||
};
|
||||
|
||||
bitfield op_index {
|
||||
tag: 2;
|
||||
index: 6;
|
||||
} [[color("0000FF")]];
|
||||
|
||||
bitfield op_diff {
|
||||
tag: 2;
|
||||
dr: 2;
|
||||
dg: 2;
|
||||
db: 2;
|
||||
} [[color("FFFFFF")]];
|
||||
|
||||
bitfield op_luma {
|
||||
tag: 2;
|
||||
diff_green: 6;
|
||||
dr_dg: 4;
|
||||
db_dg: 4;
|
||||
} [[color("FFFF00")]];
|
||||
|
||||
bitfield op_run {
|
||||
tag: 2;
|
||||
run_length: 6;
|
||||
} [[color("00FF00")]];
|
||||
|
||||
struct op_rgb {
|
||||
u8 tag;
|
||||
u8 red;
|
||||
u8 green;
|
||||
u8 blue;
|
||||
} [[color("FF7700")]];
|
||||
|
||||
struct op_rgba {
|
||||
u8 tag;
|
||||
u8 red;
|
||||
u8 green;
|
||||
u8 blue;
|
||||
u8 alpha;
|
||||
} [[color("FF0000")]];
|
||||
|
||||
u8 op_type;
|
||||
fn get_op_type() {
|
||||
op_type = std::mem::read_unsigned($, 1);
|
||||
if (op_type < tags_t::rgb)
|
||||
op_type &= 0b11000000;
|
||||
};
|
||||
|
||||
struct op_t {
|
||||
qoi::get_op_type();
|
||||
if (op_type == tags_t::index) op_index;
|
||||
else if (op_type == tags_t::diff) op_diff;
|
||||
else if (op_type == tags_t::luma) op_luma;
|
||||
else if (op_type == tags_t::run) op_run;
|
||||
else if (op_type == tags_t::rgb) op_rgb;
|
||||
else if (op_type == tags_t::rgba) op_rgba;
|
||||
};
|
||||
|
||||
struct file_t {
|
||||
header_t header;
|
||||
op_t data[while(!std::mem::eof())];
|
||||
};
|
||||
|
||||
} // namespace qoi
|
||||
|
||||
qoi::file_t qoi_picture @ 0x0;
|
||||
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;
|
||||
};
|
||||
|
||||
bitfield Flags2 {
|
||||
padding : 7;
|
||||
resource_fork : 1;
|
||||
padding : 8;
|
||||
};
|
||||
|
||||
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;
|
||||
@@ -1,3 +1,5 @@
|
||||
#include <std/mem.pat>
|
||||
|
||||
enum GeneratorID : u16 {
|
||||
Khronos = 0,
|
||||
LunarG = 1,
|
||||
@@ -642,4 +644,4 @@ struct Instruction {
|
||||
Header header @ 0x00;
|
||||
|
||||
// SPIR-V does not have any footer, increase number of instructions manually if you encounter a bigger shader
|
||||
Instruction instructions[1024] @ 0x14;
|
||||
Instruction instructions[while (!std::mem::eof())] @ 0x14;
|
||||
@@ -5,34 +5,47 @@
|
||||
|
||||
#include <std/sys.pat>
|
||||
#include <std/mem.pat>
|
||||
#include <std/core.pat>
|
||||
|
||||
struct Vector3f {
|
||||
float x, y, z;
|
||||
float x, y, z;
|
||||
} [[static, format("format_vector3f")]];
|
||||
|
||||
fn format_vector3f(Vector3f vec) {
|
||||
return std::format("[ {}, {}, {} ]", vec.x, vec.y, vec.z);
|
||||
return std::format("[ {}, {}, {} ]", vec.x, vec.y, vec.z);
|
||||
};
|
||||
|
||||
struct Triangle {
|
||||
Vector3f normal;
|
||||
Vector3f points[3];
|
||||
u16 flags;
|
||||
Vector3f normal;
|
||||
Vector3f points[3];
|
||||
u16 flags;
|
||||
} [[static]];
|
||||
|
||||
struct BinarySTLHeader {
|
||||
char caption[];
|
||||
padding[80 - sizeof(caption)];
|
||||
u32 triangleCount;
|
||||
char caption[while($[$] != 0x00 && $ - addressof(this) < 80)];
|
||||
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];
|
||||
}
|
||||
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;
|
||||
STL stl @ 0x00;
|
||||
|
||||
/* Visualize the 3D Model */
|
||||
|
||||
struct Vertex {
|
||||
Vector3f points[3] @ addressof(stl.triangles[std::core::array_index()].points);
|
||||
};
|
||||
|
||||
struct Model {
|
||||
Vertex vertices[stl.header.triangleCount];
|
||||
} [[highlight_hidden, sealed, hex::visualize("3d", vertices, null)]];
|
||||
|
||||
Model model @ 0x00;
|
||||
|
||||
89
patterns/tar.hexpat
Normal file
89
patterns/tar.hexpat
Normal file
@@ -0,0 +1,89 @@
|
||||
#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 GNU_HEADER "ustar "
|
||||
#define PAX_HEADER "ustar\x00"
|
||||
#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 == PAX_HEADER || magic == GNU_HEADER, "Magic bytes are not correct! Perhaps wrong file?");
|
||||
|
||||
tar tar[while(!std::mem::eof())] @ 0x000;
|
||||
@@ -72,7 +72,7 @@ struct Footer {
|
||||
u32 developerDirectoryOffset;
|
||||
char signature[0x10];
|
||||
char dot;
|
||||
char null;
|
||||
char zero;
|
||||
};
|
||||
|
||||
Header header @ 0x0;
|
||||
|
||||
67
patterns/uefi.hexpat
Normal file
67
patterns/uefi.hexpat
Normal file
@@ -0,0 +1,67 @@
|
||||
#pragma MIME data
|
||||
|
||||
#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002
|
||||
#define WIN_CERT_TYPE_EFI_PKCS115 0x0EF0
|
||||
#define WIN_CERT_TYPE_EFI_GUID 0x0EF1
|
||||
|
||||
struct EFI_TIME {
|
||||
u16 Year; // 1900 – 9999
|
||||
u8 Month; // 1 – 12
|
||||
u8 Day; // 1 – 31
|
||||
u8 Hour; // 0 – 23
|
||||
u8 Minute; // 0 – 59
|
||||
u8 Second; // 0 – 59
|
||||
u8 Pad1;
|
||||
u32 Nanosecond; // 0 – 999,999,999
|
||||
s16 TimeZone; // -1440 to 1440 or 2047
|
||||
u8 Daylight;
|
||||
u8 Pad2;
|
||||
};
|
||||
|
||||
struct EFI_GUID {
|
||||
u32 Data1;
|
||||
u16 Data2;
|
||||
u16 Data3;
|
||||
u8 Data4[8];
|
||||
};
|
||||
|
||||
struct WIN_CERTIFICATE {
|
||||
u32 Length;
|
||||
u16 Revision;
|
||||
u16 CertificateType;
|
||||
//u8 Certificate[];
|
||||
};
|
||||
|
||||
struct WIN_CERTIFICATE_UEFI_GUID {
|
||||
WIN_CERTIFICATE Hdr;
|
||||
EFI_GUID CertType;
|
||||
u8 CertData[Hdr.Length-SizeofWIN_CERTIFICATE_UEFI_GUID];
|
||||
};
|
||||
#define SizeofWIN_CERTIFICATE_UEFI_GUID 24
|
||||
|
||||
struct EFI_VARIABLE_AUTHENTICATION_2 {
|
||||
EFI_TIME TimeStamp;
|
||||
WIN_CERTIFICATE_UEFI_GUID AuthInfo;
|
||||
};
|
||||
|
||||
struct EFI_SIGNATURE_DATA {
|
||||
EFI_GUID SignatureOwner;
|
||||
u8 SignatureData[1076];
|
||||
};
|
||||
|
||||
struct EFI_SIGNATURE_LIST {
|
||||
EFI_GUID SignatureType;
|
||||
u32 SignatureListSize;
|
||||
u32 SignatureHeaderSize;
|
||||
u32 SignatureSize;
|
||||
u8 SignatureHeader[SignatureHeaderSize];
|
||||
EFI_SIGNATURE_DATA Signatures;
|
||||
};
|
||||
|
||||
|
||||
struct dbx_esl {
|
||||
EFI_VARIABLE_AUTHENTICATION_2 Auth;
|
||||
EFI_SIGNATURE_LIST x509_1;
|
||||
};
|
||||
|
||||
dbx_esl header @ 0x00;
|
||||
272
patterns/usb.hexpat
Normal file
272
patterns/usb.hexpat
Normal file
@@ -0,0 +1,272 @@
|
||||
#include <std/core.pat>
|
||||
#include <std/io.pat>
|
||||
#include <std/mem.pat>
|
||||
#include <std/string.pat>
|
||||
|
||||
using BitfieldOrder = std::core::BitfieldOrder;
|
||||
|
||||
enum DescriptorType : u8 {
|
||||
DeviceDescriptor = 0x01,
|
||||
ConfigDescriptor = 0x02,
|
||||
StringDescriptor = 0x03,
|
||||
InterfaceDescriptor = 0x04,
|
||||
EndpointDescriptor = 0x05,
|
||||
DeviceQualifierDescriptor = 0x06,
|
||||
OtherSpeedConfigurationDescriptor = 0x07,
|
||||
InterfacePowerDescriptor = 0x08,
|
||||
OTGDescriptor = 0x09,
|
||||
DebugDescriptor = 0x0A,
|
||||
InterfaceAssociationDescriptor = 0x0B,
|
||||
|
||||
HIDDescriptor = 0x21,
|
||||
ReportDescriptor = 0x22,
|
||||
PhysicalDescriptor = 0x23
|
||||
};
|
||||
|
||||
enum InterfaceClass : u8 {
|
||||
UseClassInformationInInterfaceDescriptors = 0x00,
|
||||
Audio = 0x01,
|
||||
CommunicationAndCDCControl = 0x02,
|
||||
HID = 0x03,
|
||||
Physical = 0x05,
|
||||
Image = 0x06,
|
||||
Printer = 0x07,
|
||||
MassStorage = 0x08,
|
||||
Hub = 0x09,
|
||||
CDCData = 0x0A,
|
||||
SmartCard = 0x0B,
|
||||
ContentSecurity = 0x0C,
|
||||
Video = 0x0E,
|
||||
PersonalHealthcare = 0x0F,
|
||||
AudioVideoDevice = 0x10,
|
||||
BillboardDevice = 0x11,
|
||||
USBTypeCBridge = 0x12,
|
||||
I3CDevice = 0x3C,
|
||||
DiagnosticDevice = 0xDC,
|
||||
WirelessController = 0xE0,
|
||||
Miscellaneous = 0xEF,
|
||||
ApplicationSpecific = 0xFE,
|
||||
VendorSpecific = 0xFF
|
||||
};
|
||||
|
||||
enum CountryCode : u8 {
|
||||
NotSupported = 0,
|
||||
Arabic = 1,
|
||||
Belgian = 2,
|
||||
CanadianBilingual = 3,
|
||||
CanadianFrench = 4,
|
||||
CzechRepublic = 5,
|
||||
Danish = 6,
|
||||
Finnish = 7,
|
||||
French = 8,
|
||||
German = 9,
|
||||
Greek = 10,
|
||||
Hebrew = 11,
|
||||
Hungary = 12,
|
||||
International = 13,
|
||||
Italian = 14,
|
||||
JapanKatakana = 15,
|
||||
Korean = 16,
|
||||
LatinAmerican = 17,
|
||||
Dutch = 18,
|
||||
Norwegian = 19,
|
||||
PersianFarsi = 20,
|
||||
Polish = 21,
|
||||
Portuguese = 22,
|
||||
Russian = 23,
|
||||
Slovakian = 24,
|
||||
Spanish = 25,
|
||||
Swedish = 26,
|
||||
SwissFrench = 27,
|
||||
SwissGerman = 28,
|
||||
Switzerland = 29,
|
||||
Taiwan = 30,
|
||||
TurkishQ = 31,
|
||||
EnglishUK = 32,
|
||||
EnglishUS = 33,
|
||||
Yugoslavian = 34,
|
||||
TurkishF = 35,
|
||||
Reserved = 36 ... 255
|
||||
};
|
||||
|
||||
enum HubInterfaceSubClass : u8 {
|
||||
Hub = 0x00
|
||||
};
|
||||
|
||||
enum AudioVideoDeviceSubClass : u8 {
|
||||
AVControlInterface = 0x01,
|
||||
AVDataVideoStreamingInterface = 0x02,
|
||||
AVDataAudioStreamingInterface = 0x03
|
||||
};
|
||||
|
||||
enum HubInterfaceProtocol : u8 {
|
||||
FullSpeedHub = 0x00,
|
||||
HiSpeedHubWithSingleTT = 0x01,
|
||||
HiSpeedHubWithMultipleTTs = 0x02
|
||||
};
|
||||
|
||||
struct Ampere {
|
||||
u8 amps;
|
||||
} [[sealed, format("format_ampere")]];
|
||||
|
||||
fn format_ampere(Ampere ampere) {
|
||||
return std::format("{} mA", ampere.amps * 2);
|
||||
};
|
||||
|
||||
bitfield ConfigAttributes {
|
||||
padding : 1;
|
||||
SelfPowered : 1;
|
||||
RemoteWakeup : 1;
|
||||
padding : 5;
|
||||
} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 8)]];
|
||||
|
||||
struct BCD<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;
|
||||
}
|
||||
};
|
||||
|
||||
struct ConfigDescriptor {
|
||||
u16 wTotalLength;
|
||||
u8 bNumInterfaces;
|
||||
u8 bConfigurationValue;
|
||||
u8 iConfiguration;
|
||||
ConfigAttributes bmAttributes;
|
||||
Ampere bMaxPower;
|
||||
};
|
||||
|
||||
struct StringDescriptor {
|
||||
char bString[parent.bLength - 2];
|
||||
};
|
||||
|
||||
struct InterfaceDescriptor {
|
||||
u8 bInterfaceNumber;
|
||||
u8 bAlternateSetting;
|
||||
u8 bNumEndpoints;
|
||||
|
||||
InterfaceClass bInterfaceClass;
|
||||
if (bInterfaceClass == InterfaceClass::Hub) {
|
||||
HubInterfaceSubClass bInterfaceSubClass;
|
||||
if (bInterfaceSubClass == HubInterfaceSubClass::Hub)
|
||||
HubInterfaceProtocol bInterfaceProtocol;
|
||||
else
|
||||
u8 bInterfaceProtocol;
|
||||
} else if (bInterfaceClass == InterfaceClass::AudioVideoDevice) {
|
||||
AudioVideoDeviceSubClass bInterfaceSubClass;
|
||||
u8 bInterfaceProtocol;
|
||||
} else {
|
||||
u8 bInterfaceSubClass;
|
||||
u8 bInterfaceProtocol;
|
||||
}
|
||||
|
||||
u8 iInterface;
|
||||
};
|
||||
|
||||
enum EndpointDirection : u8 {
|
||||
OUT = 0,
|
||||
IN = 1
|
||||
};
|
||||
|
||||
fn format_direction(u8 value) {
|
||||
EndpointDirection direction;
|
||||
direction = value;
|
||||
return direction;
|
||||
};
|
||||
|
||||
bitfield EndpointAddress {
|
||||
EndpointNumber : 4;
|
||||
padding : 3;
|
||||
Direction : 1 [[format("format_direction")]];
|
||||
};
|
||||
|
||||
bitfield EndpointAttributes {
|
||||
TransferType : 2;
|
||||
SynchronizationType : 2;
|
||||
UsageType : 2;
|
||||
};
|
||||
|
||||
struct EndpointDescriptor {
|
||||
EndpointAddress bEndPointAddress;
|
||||
EndpointAttributes bmAttributes;
|
||||
u16 wMaxPacketSize;
|
||||
u8 bInterval;
|
||||
};
|
||||
|
||||
struct OtherSpeedConfigurationDescriptor {
|
||||
ConfigDescriptor content [[inline]];
|
||||
};
|
||||
|
||||
struct DeviceQualifierDescriptor {
|
||||
DeviceDescriptor deviceDescriptor [[inline]];
|
||||
u8 bMaxPacketSize0;
|
||||
u8 bNumConfigurations;
|
||||
padding[1];
|
||||
};
|
||||
|
||||
bitfield OTGAttributes {
|
||||
SRPSupport : 1;
|
||||
HNPSupport : 1;
|
||||
} [[right_to_left]];
|
||||
|
||||
struct OTGDescriptor {
|
||||
OTGAttributes bmAttributes;
|
||||
};
|
||||
|
||||
struct HIDDescriptor {
|
||||
BCD<2> bcdVersion;
|
||||
CountryCode bCountryCode;
|
||||
u8 bNumDescriptors;
|
||||
DescriptorType bDescriptorType;
|
||||
u16 wDescriptorLength;
|
||||
};
|
||||
|
||||
struct USBDescriptor {
|
||||
u8 bLength;
|
||||
DescriptorType bDescriptorType;
|
||||
|
||||
if (bDescriptorType == DescriptorType::DeviceDescriptor)
|
||||
DeviceDescriptor deviceDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::ConfigDescriptor)
|
||||
ConfigDescriptor configDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::StringDescriptor)
|
||||
StringDescriptor stringDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::InterfaceDescriptor)
|
||||
InterfaceDescriptor interfaceDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::EndpointDescriptor)
|
||||
EndpointDescriptor endpointDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::OtherSpeedConfigurationDescriptor)
|
||||
OtherSpeedConfigurationDescriptor otherSpeedConfigurationDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::DeviceQualifierDescriptor)
|
||||
DeviceQualifierDescriptor deviceQualifierDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::OTGDescriptor)
|
||||
OTGDescriptor otgDescriptor [[inline]];
|
||||
else if (bDescriptorType == DescriptorType::HIDDescriptor)
|
||||
HIDDescriptor hidDescriptor [[inline]];
|
||||
|
||||
padding[bLength - ($ - addressof(this))];
|
||||
};
|
||||
|
||||
USBDescriptor descriptors[while(!std::mem::eof())] @ 0x00;
|
||||
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;
|
||||
403
patterns/xbeh.hexpat
Normal file
403
patterns/xbeh.hexpat
Normal file
@@ -0,0 +1,403 @@
|
||||
#pragma MIME audio/x-xbox-executable
|
||||
|
||||
#include <type/magic.pat>
|
||||
#include <type/size.pat>
|
||||
#include <type/time.pat>
|
||||
|
||||
#include <std/io.pat>
|
||||
#include <std/mem.pat>
|
||||
|
||||
|
||||
bitfield AllowedMedia {
|
||||
HardDisk : 1;
|
||||
DVD_X2 : 1;
|
||||
DVD_CD : 1;
|
||||
CD : 1;
|
||||
DVD_5_RO : 1;
|
||||
DVD_9_RO : 1;
|
||||
DVD_5_RW : 1;
|
||||
DVD_9_RW : 1;
|
||||
Dongle : 1;
|
||||
MediaBoard : 1;
|
||||
padding : 20;
|
||||
NonSecureHardDisk : 1;
|
||||
NonSecureMode : 1;
|
||||
};
|
||||
|
||||
bitfield GameRegion {
|
||||
NorthAmerica : 1;
|
||||
Japan : 1;
|
||||
RestOfTheWorld : 1;
|
||||
padding : 28;
|
||||
Manufacturing : 1;
|
||||
};
|
||||
|
||||
struct Certificate {
|
||||
type::Size<u32> certificateSize;
|
||||
type::time32_t timeDate;
|
||||
u32 titleId;
|
||||
char16 titleName[0x50 / 2];
|
||||
u32 alternateTitleIds[16];
|
||||
AllowedMedia allowedMedia;
|
||||
GameRegion gameRegion;
|
||||
u32 gameRatings;
|
||||
u128 lanKey;
|
||||
u128 signatureKey;
|
||||
u128 alternateSignatureKeys[16];
|
||||
};
|
||||
|
||||
bitfield InitializationFlags {
|
||||
MountUtilityDrive : 1;
|
||||
FormatUtilityDrive : 1;
|
||||
Limit64Megabytes : 1;
|
||||
DontSetuptHarddisk : 1;
|
||||
padding : 28;
|
||||
};
|
||||
|
||||
union EntryPoint {
|
||||
u32 betaAddress [[format("format_beta_entrypoint")]];
|
||||
u32 debugAddress [[format("format_debug_entrypoint")]];
|
||||
u32 retailAddress [[format("format_retail_entrypoint")]];
|
||||
|
||||
if ((betaAddress ^ 0xE682F45B) - parent.baseAddress < std::mem::size())
|
||||
u8 beta @ (betaAddress ^ 0xE682F45B) - parent.baseAddress;;
|
||||
if ((debugAddress ^ 0x94859D4B) - parent.baseAddress < std::mem::size())
|
||||
u8 debug @ (debugAddress ^ 0x94859D4B) - parent.baseAddress;;
|
||||
if ((retailAddress ^ 0xA8FC57AB) - parent.baseAddress < std::mem::size())
|
||||
u8 retail @ (retailAddress ^ 0xA8FC57AB) - parent.baseAddress;
|
||||
};
|
||||
|
||||
fn format_beta_entrypoint(u32 value) {
|
||||
return std::format("0x{:08X}", value ^ 0xE682F45B);
|
||||
};
|
||||
|
||||
fn format_debug_entrypoint(u32 value) {
|
||||
return std::format("0x{:08X}", value ^ 0x94859D4B);
|
||||
};
|
||||
|
||||
fn format_retail_entrypoint(u32 value) {
|
||||
return std::format("0x{:08X}", value ^ 0xA8FC57AB);
|
||||
};
|
||||
|
||||
#define KERNEL_BASE 0x8000'0000
|
||||
enum KernelImageFunction : u32 {
|
||||
AvGetSavedDataAddress = 1 + KERNEL_BASE,
|
||||
AvSendTVEncoderOption = 2 + KERNEL_BASE,
|
||||
AvSetDisplayMode = 3 + KERNEL_BASE,
|
||||
AvSetSavedDataAddress = 4 + KERNEL_BASE,
|
||||
DbgBreakPoint = 5 + KERNEL_BASE,
|
||||
DbgBreakPointWithStatus = 6 + KERNEL_BASE,
|
||||
DbgLoadImageSymbols = 7 + KERNEL_BASE,
|
||||
DbgPrint = 8 + KERNEL_BASE,
|
||||
HalReadSMCTrayState = 9 + KERNEL_BASE,
|
||||
DbgPrompt = 10 + KERNEL_BASE,
|
||||
DbgUnLoadImageSymbols = 11 + KERNEL_BASE,
|
||||
ExAcquireReadWriteLockExclusive = 12 + KERNEL_BASE,
|
||||
ExAcquireReadWriteLockShared = 13 + KERNEL_BASE,
|
||||
ExAllocatePool = 14 + KERNEL_BASE,
|
||||
ExAllocatePoolWithTag = 15 + KERNEL_BASE,
|
||||
ExEventObjectType = 16 + KERNEL_BASE,
|
||||
ExFreePool = 17 + KERNEL_BASE,
|
||||
ExInitializeReadWriteLock = 18 + KERNEL_BASE,
|
||||
ExInterlockedAddLargeInteger = 19 + KERNEL_BASE,
|
||||
ExInterlockedAddLargeStatistic = 20 + KERNEL_BASE,
|
||||
ExInterlockedCompareExchange64 = 21 + KERNEL_BASE,
|
||||
ExMutantObjectType = 22 + KERNEL_BASE,
|
||||
ExQueryPoolBlockSize = 23 + KERNEL_BASE,
|
||||
ExQueryNonVolatileSetting = 24 + KERNEL_BASE,
|
||||
ExReadWriteRefurbInfo = 25 + KERNEL_BASE,
|
||||
ExRaiseException = 26 + KERNEL_BASE,
|
||||
ExRaiseStatus = 27 + KERNEL_BASE,
|
||||
ExReleaseReadWriteLock = 28 + KERNEL_BASE,
|
||||
ExSaveNonVolatileSetting = 29 + KERNEL_BASE,
|
||||
ExSemaphoreObjectType = 30 + KERNEL_BASE,
|
||||
ExTimerObjectType = 31 + KERNEL_BASE,
|
||||
ExfInterlockedInsertHeadList = 32 + KERNEL_BASE,
|
||||
ExfInterlockedInsertTailList = 33 + KERNEL_BASE,
|
||||
ExfInterlockedRemoveHeadList = 34 + KERNEL_BASE,
|
||||
FscGetCacheSize = 35 + KERNEL_BASE,
|
||||
FscInvalidateIdleBlocks = 36 + KERNEL_BASE,
|
||||
FscSetCacheSize = 37 + KERNEL_BASE,
|
||||
HalClearSoftwareInterrupt = 38 + KERNEL_BASE,
|
||||
HalDisableSystemInterrupt = 39 + KERNEL_BASE,
|
||||
HalDiskCachePartitionCount = 40 + KERNEL_BASE,
|
||||
HalDiskModelNumber = 41 + KERNEL_BASE,
|
||||
HalDiskSerialNumber = 42 + KERNEL_BASE,
|
||||
HalEnableSystemInterrupt = 43 + KERNEL_BASE,
|
||||
HalGetInterruptVector = 44 + KERNEL_BASE,
|
||||
HalReadSMBusValue = 45 + KERNEL_BASE,
|
||||
HalReadWritePCISpace = 46 + KERNEL_BASE,
|
||||
HalRegisterShutdownNotification = 47 + KERNEL_BASE,
|
||||
HalRequestSoftwareInterrupt = 48 + KERNEL_BASE,
|
||||
HalReturnToFirmware = 49 + KERNEL_BASE,
|
||||
HalWriteSMBusValue = 50 + KERNEL_BASE,
|
||||
InterlockedCompareExchange = 51 + KERNEL_BASE,
|
||||
InterlockedDecrement = 52 + KERNEL_BASE,
|
||||
InterlockedIncrement = 53 + KERNEL_BASE,
|
||||
InterlockedExchange = 54 + KERNEL_BASE,
|
||||
InterlockedExchangeAdd = 55 + KERNEL_BASE,
|
||||
InterlockedFlushSList = 56 + KERNEL_BASE,
|
||||
InterlockedPopEntrySList = 57 + KERNEL_BASE,
|
||||
InterlockedPushEntrySList = 58 + KERNEL_BASE,
|
||||
IoAllocateIrp = 59 + KERNEL_BASE,
|
||||
IoBuildAsynchronousFsdRequest = 60 + KERNEL_BASE,
|
||||
IoBuildDeviceIoControlRequest = 61 + KERNEL_BASE,
|
||||
IoBuildSynchronousFsdRequest = 62 + KERNEL_BASE,
|
||||
IoCheckShareAccess = 63 + KERNEL_BASE,
|
||||
IoCompletionObjectType = 64 + KERNEL_BASE,
|
||||
IoCreateDevice = 65 + KERNEL_BASE,
|
||||
IoCreateFile = 66 + KERNEL_BASE,
|
||||
IoCreateSymbolicLink = 67 + KERNEL_BASE,
|
||||
IoDeleteDevice = 68 + KERNEL_BASE,
|
||||
IoDeleteSymbolicLink = 69 + KERNEL_BASE,
|
||||
IoDeviceObjectType = 70 + KERNEL_BASE,
|
||||
IoFileObjectType = 71 + KERNEL_BASE,
|
||||
IoFreeIrp = 72 + KERNEL_BASE,
|
||||
IoInitializeIrp = 73 + KERNEL_BASE,
|
||||
IoInvalidDeviceRequest = 74 + KERNEL_BASE,
|
||||
IoQueryFileInformation = 75 + KERNEL_BASE,
|
||||
IoQueryVolumeInformation = 76 + KERNEL_BASE,
|
||||
IoQueueThreadIrp = 77 + KERNEL_BASE,
|
||||
IoRemoveShareAccess = 78 + KERNEL_BASE,
|
||||
IoSetIoCompletion = 79 + KERNEL_BASE,
|
||||
IoSetShareAccess = 80 + KERNEL_BASE,
|
||||
IoStartNextPacket = 81 + KERNEL_BASE,
|
||||
IoStartNextPacketByKey = 82 + KERNEL_BASE,
|
||||
IoStartPacket = 83 + KERNEL_BASE,
|
||||
IoSynchronousDeviceIoControlRequest = 84 + KERNEL_BASE,
|
||||
IoSynchronousFsdRequest = 85 + KERNEL_BASE,
|
||||
IofCallDriver = 86 + KERNEL_BASE,
|
||||
IofCompleteRequest = 87 + KERNEL_BASE,
|
||||
KdDebuggerEnabled = 88 + KERNEL_BASE,
|
||||
KdDebuggerNotPresent = 89 + KERNEL_BASE,
|
||||
IoDismountVolume = 90 + KERNEL_BASE,
|
||||
IoDismountVolumeByName = 91 + KERNEL_BASE,
|
||||
KeAlertResumeThread = 92 + KERNEL_BASE,
|
||||
KeAlertThread = 93 + KERNEL_BASE,
|
||||
KeBoostPriorityThread = 94 + KERNEL_BASE,
|
||||
KeBugCheck = 95 + KERNEL_BASE,
|
||||
KeBugCheckEx = 96 + KERNEL_BASE,
|
||||
KeCancelTimer = 97 + KERNEL_BASE,
|
||||
KeConnectInterrupt = 98 + KERNEL_BASE,
|
||||
KeDelayExecutionThread = 99 + KERNEL_BASE,
|
||||
KeDisconnectInterrupt = 100 + KERNEL_BASE,
|
||||
KeEnterCriticalRegion = 101 + KERNEL_BASE,
|
||||
MmGlobalData = 102 + KERNEL_BASE,
|
||||
KeGetCurrentIrql = 103 + KERNEL_BASE,
|
||||
KeGetCurrentThread = 104 + KERNEL_BASE,
|
||||
KeInitializeApc = 105 + KERNEL_BASE,
|
||||
KeInitializeDeviceQueue = 106 + KERNEL_BASE,
|
||||
KeInitializeDpc = 107 + KERNEL_BASE,
|
||||
KeInitializeEvent = 108 + KERNEL_BASE,
|
||||
KeInitializeInterrupt = 109 + KERNEL_BASE,
|
||||
KeInitializeMutant = 110 + KERNEL_BASE,
|
||||
KeInitializeQueue = 111 + KERNEL_BASE,
|
||||
KeInitializeSemaphore = 112 + KERNEL_BASE,
|
||||
KeInitializeTimerEx = 113 + KERNEL_BASE,
|
||||
KeInsertByKeyDeviceQueue = 114 + KERNEL_BASE,
|
||||
KeInsertDeviceQueue = 115 + KERNEL_BASE,
|
||||
KeInsertHeadQueue = 116 + KERNEL_BASE,
|
||||
KeInsertQueue = 117 + KERNEL_BASE,
|
||||
KeInsertQueueApc = 118 + KERNEL_BASE,
|
||||
KeInsertQueueDpc = 119 + KERNEL_BASE,
|
||||
KeInterruptTime = 120 + KERNEL_BASE,
|
||||
KeIsExecutingDpc = 121 + KERNEL_BASE,
|
||||
KeLeaveCriticalRegion = 122 + KERNEL_BASE,
|
||||
KePulseEvent = 123 + KERNEL_BASE,
|
||||
KeQueryBasePriorityThread = 124 + KERNEL_BASE,
|
||||
KeQueryInterruptTime = 125 + KERNEL_BASE,
|
||||
KeQueryPerformanceCounter = 126 + KERNEL_BASE,
|
||||
KeQueryPerformanceFrequency = 127 + KERNEL_BASE,
|
||||
KeQuerySystemTime = 128 + KERNEL_BASE,
|
||||
KeRaiseIrqlToDpcLevel = 129 + KERNEL_BASE,
|
||||
KeRaiseIrqlToSynchLevel = 130 + KERNEL_BASE,
|
||||
KeReleaseMutant = 131 + KERNEL_BASE,
|
||||
KeReleaseSemaphore = 132 + KERNEL_BASE,
|
||||
KeRemoveByKeyDeviceQueue = 133 + KERNEL_BASE,
|
||||
KeRemoveDeviceQueue = 134 + KERNEL_BASE,
|
||||
KeRemoveEntryDeviceQueue = 135 + KERNEL_BASE,
|
||||
KeRemoveQueue = 136 + KERNEL_BASE,
|
||||
KeRemoveQueueDpc = 137 + KERNEL_BASE,
|
||||
KeResetEvent = 138 + KERNEL_BASE,
|
||||
KeRestoreFloatingPointState = 139 + KERNEL_BASE,
|
||||
KeResumeThread = 140 + KERNEL_BASE,
|
||||
KeRundownQueue = 141 + KERNEL_BASE,
|
||||
KeSaveFloatingPointState = 142 + KERNEL_BASE,
|
||||
KeSetBasePriorityThread = 143 + KERNEL_BASE,
|
||||
KeSetDisableBoostThread = 144 + KERNEL_BASE,
|
||||
KeSetEvent = 145 + KERNEL_BASE,
|
||||
KeSetEventBoostPriority = 146 + KERNEL_BASE,
|
||||
KeSetPriorityProcess = 147 + KERNEL_BASE,
|
||||
KeSetPriorityThread = 148 + KERNEL_BASE,
|
||||
KeSetTimer = 149 + KERNEL_BASE,
|
||||
KeSetTimerEx = 150 + KERNEL_BASE,
|
||||
KeStallExecutionProcessor = 151 + KERNEL_BASE,
|
||||
KeSuspendThread = 152 + KERNEL_BASE,
|
||||
KeSynchronizeExecution = 153 + KERNEL_BASE,
|
||||
KeSystemTime = 154 + KERNEL_BASE,
|
||||
KeTestAlertThread = 155 + KERNEL_BASE,
|
||||
KeTickCount = 156 + KERNEL_BASE,
|
||||
KeTimeIncrement = 157 + KERNEL_BASE,
|
||||
KeWaitForMultipleObjects = 158 + KERNEL_BASE,
|
||||
KeWaitForSingleObject = 159 + KERNEL_BASE,
|
||||
KfRaiseIrql = 160 + KERNEL_BASE,
|
||||
KfLowerIrql = 161 + KERNEL_BASE,
|
||||
KiBugCheckData = 162 + KERNEL_BASE,
|
||||
KiUnlockDispatcherDatabase = 163 + KERNEL_BASE,
|
||||
LaunchDataPage = 164 + KERNEL_BASE,
|
||||
MmAllocateContiguousMemory = 165 + KERNEL_BASE,
|
||||
MmAllocateContiguousMemoryEx = 166 + KERNEL_BASE,
|
||||
MmAllocateSystemMemory = 167 + KERNEL_BASE,
|
||||
MmClaimGpuInstanceMemory = 168 + KERNEL_BASE,
|
||||
MmCreateKernelStack = 169 + KERNEL_BASE,
|
||||
MmDeleteKernelStack = 170 + KERNEL_BASE,
|
||||
MmFreeContiguousMemory = 171 + KERNEL_BASE,
|
||||
MmFreeSystemMemory = 172 + KERNEL_BASE,
|
||||
MmGetPhysicalAddress = 173 + KERNEL_BASE,
|
||||
MmIsAddressValid = 174 + KERNEL_BASE,
|
||||
MmLockUnlockBufferPages = 175 + KERNEL_BASE,
|
||||
MmLockUnlockPhysicalPage = 176 + KERNEL_BASE,
|
||||
MmMapIoSpace = 177 + KERNEL_BASE,
|
||||
MmPersistContiguousMemory = 178 + KERNEL_BASE,
|
||||
MmQueryAddressProtect = 179 + KERNEL_BASE,
|
||||
MmQueryAllocationSize = 180 + KERNEL_BASE,
|
||||
MmQueryStatistics = 181 + KERNEL_BASE,
|
||||
MmSetAddressProtect = 182 + KERNEL_BASE,
|
||||
MmUnmapIoSpace = 183 + KERNEL_BASE,
|
||||
NtAllocateVirtualMemory = 184 + KERNEL_BASE,
|
||||
NtCancelTimer = 185 + KERNEL_BASE,
|
||||
NtClearEvent = 186 + KERNEL_BASE,
|
||||
NtClose = 187 + KERNEL_BASE,
|
||||
NtCreateDirectoryObject = 188 + KERNEL_BASE,
|
||||
NtCreateEvent = 189 + KERNEL_BASE,
|
||||
NtCreateFile = 190 + KERNEL_BASE,
|
||||
NtCreateIoCompletion = 191 + KERNEL_BASE,
|
||||
NtCreateMutant = 192 + KERNEL_BASE,
|
||||
NtCreateSemaphore = 193 + KERNEL_BASE,
|
||||
NtCreateTimer = 194 + KERNEL_BASE,
|
||||
NtDeleteFile = 195 + KERNEL_BASE,
|
||||
NtDeviceIoControlFile = 196 + KERNEL_BASE,
|
||||
NtDuplicateObject = 197 + KERNEL_BASE,
|
||||
NtFlushBuffersFile = 198 + KERNEL_BASE,
|
||||
NtFreeVirtualMemory = 199 + KERNEL_BASE,
|
||||
NtFsControlFile = 200 + KERNEL_BASE,
|
||||
NtOpenDirectoryObject = 201 + KERNEL_BASE,
|
||||
NtOpenFile = 202 + KERNEL_BASE,
|
||||
NtOpenSymbolicLinkObject = 203 + KERNEL_BASE,
|
||||
NtProtectVirtualMemory = 204 + KERNEL_BASE,
|
||||
NtPulseEvent = 205 + KERNEL_BASE,
|
||||
NtQueueApcThread = 206 + KERNEL_BASE,
|
||||
NtQueryDirectoryFile = 207 + KERNEL_BASE
|
||||
};
|
||||
|
||||
struct KernelImageThunk {
|
||||
KernelImageFunction addresses[while(std::mem::read_unsigned($, 4) != 0x00)];
|
||||
padding[4];
|
||||
};
|
||||
|
||||
union KernelImageThunkAddress {
|
||||
u32 debugAddress [[format("format_debug_kernel_image_thunk_address")]];
|
||||
u32 retailAddress [[format("format_retail_kernel_image_thunk_address")]];
|
||||
|
||||
if ((debugAddress ^ 0xEFB1F152) - parent.baseAddress < std::mem::size())
|
||||
KernelImageThunk debug @ (debugAddress ^ 0xEFB1F152) - parent.baseAddress;;
|
||||
if ((retailAddress ^ 0x5B6D40B6) - parent.baseAddress < std::mem::size())
|
||||
KernelImageThunk retail @ (retailAddress ^ 0x5B6D40B6) - parent.baseAddress;
|
||||
};
|
||||
|
||||
fn format_debug_kernel_image_thunk_address(u32 value) {
|
||||
return std::format("0x{:08X}", value ^ 0xEFB1F152);
|
||||
};
|
||||
|
||||
fn format_retail_kernel_image_thunk_address(u32 value) {
|
||||
return std::format("0x{:08X}", value ^ 0x5B6D40B6);
|
||||
};
|
||||
|
||||
struct TLS {
|
||||
u32 rawDataStart, rawDataEnd;
|
||||
u32 indexAddress;
|
||||
u32 callbacksAddress;
|
||||
type::Size<u32> zeroFillSize;
|
||||
u32 characteristics;
|
||||
};
|
||||
|
||||
fn relative_to_base(auto pointer) {
|
||||
return -parent.baseAddress;
|
||||
};
|
||||
|
||||
fn relative_to_base_section(auto pointer) {
|
||||
return -parent.parent.baseAddress;
|
||||
};
|
||||
|
||||
bitfield LibraryFlags {
|
||||
QFEVersion : 13;
|
||||
Approved : 2;
|
||||
DebugBuild : 1;
|
||||
};
|
||||
|
||||
struct LibraryVersion {
|
||||
char libraryName[8];
|
||||
u16 major, minor, build;
|
||||
LibraryFlags flags;
|
||||
};
|
||||
|
||||
bitfield SectionFlags {
|
||||
Writable : 1;
|
||||
Preload : 1;
|
||||
Executable : 1;
|
||||
InsertedFile : 1;
|
||||
HeadPageReadOnly : 1;
|
||||
TailPageReadOnly : 1;
|
||||
padding : 26;
|
||||
};
|
||||
|
||||
struct SectionHeader {
|
||||
SectionFlags sectionFlags;
|
||||
u32 virtualAddress;
|
||||
type::Size<u32> virtualSize;
|
||||
u32 rawAddress;
|
||||
type::Size<u32> rawSize;
|
||||
char *sectionName[] : u32 [[pointer_base("relative_to_base_section")]];
|
||||
u32 *sectionNameRefrenceCount : u32 [[pointer_base("relative_to_base_section")]];
|
||||
u16 *headSharedPageReferenceCount : u32 [[pointer_base("relative_to_base_section")]];
|
||||
u16 *tailSharedPageReferenceCount : u32 [[pointer_base("relative_to_base_section")]];
|
||||
u8 sectionDigest[20];
|
||||
|
||||
u8 data[rawSize] @ rawAddress [[sealed]];
|
||||
};
|
||||
|
||||
struct XBEH {
|
||||
type::Magic<"XBEH"> magic;
|
||||
u8 signature[0x100] [[sealed]];
|
||||
u32 baseAddress;
|
||||
type::Size<u32> headerSize, imageSize, imageHeaderSize;
|
||||
type::time32_t timeDate;
|
||||
Certificate *certificate : u32 [[pointer_base("relative_to_base")]];
|
||||
u32 numSections;
|
||||
SectionHeader *sectionHeader[numSections] : u32 [[pointer_base("relative_to_base")]];
|
||||
InitializationFlags initializationFlags;
|
||||
EntryPoint entrypoint;
|
||||
TLS *tls : u32 [[pointer_base("relative_to_base")]];
|
||||
|
||||
type::Size<u32> stackSize;
|
||||
u32 peHeapReserve, peHeapCommit, peBaseAddress;
|
||||
type::Size<u32> peImageSize;
|
||||
u32 peChecksum;
|
||||
type::time32_t peTimeDate;
|
||||
char *debugPathNameAddress[] : u32 [[pointer_base("relative_to_base")]];
|
||||
char *debugFileNameAddress[] : u32 [[pointer_base("relative_to_base")]];
|
||||
char16 *utf16DebugFileNameAddress[] : u32 [[pointer_base("relative_to_base")]];
|
||||
KernelImageThunkAddress kernelImageThunkAddress;
|
||||
u32 nonKernelImportDirectoryAddress;
|
||||
u32 numLibraryVersions;
|
||||
LibraryVersion *libraryVersonTable[numLibraryVersions] : u32 [[pointer_base("relative_to_base")]];
|
||||
LibraryVersion *kernelLibraryVersion : u32 [[pointer_base("relative_to_base")]];
|
||||
LibraryVersion *xapiLibraryVersion : u32 [[pointer_base("relative_to_base")]];
|
||||
u32 logoBitMapAddress, logoBitmapSize;
|
||||
u64 unknown1;
|
||||
u32 unknown2;
|
||||
|
||||
u8 logoBitmap[logoBitmapSize] @ logoBitMapAddress - baseAddress;
|
||||
};
|
||||
|
||||
XBEH xbeh @ 0x00;
|
||||
97
patterns/xci.hexpat
Normal file
97
patterns/xci.hexpat
Normal file
@@ -0,0 +1,97 @@
|
||||
#include <std/core.pat>
|
||||
|
||||
#include <type/magic.pat>
|
||||
#include <type/size.pat>
|
||||
|
||||
#define PAGE_SIZE 0x200
|
||||
|
||||
enum RomSize : u8 {
|
||||
_1GB = 0xFA,
|
||||
_2GB = 0xF8,
|
||||
_4GB = 0xF0,
|
||||
_8GB = 0xE0,
|
||||
_16GB = 0xE1,
|
||||
_32GB = 0xE2
|
||||
};
|
||||
|
||||
bitfield Index {
|
||||
titleKeyDecIndex : 4;
|
||||
kekIndex : 4;
|
||||
};
|
||||
|
||||
bitfield Flags {
|
||||
autoBoot : 1;
|
||||
historyErase : 1;
|
||||
repairTool : 1;
|
||||
differentRegionCupToTerraDevice : 1;
|
||||
differentRegionCupToGlobalDevice : 1;
|
||||
padding : 2;
|
||||
hasNewCardHeader : 1;
|
||||
};
|
||||
|
||||
struct SelSec {
|
||||
u16 t1, t2;
|
||||
};
|
||||
|
||||
struct CardHeader {
|
||||
u8 headerSignature[0x100];
|
||||
type::Magic<"HEAD"> magic;
|
||||
u32 romAreaStartPageAddress;
|
||||
u32 backupAreaStartPageAddress;
|
||||
Index index [[inline]];
|
||||
RomSize romSize;
|
||||
u8 cardHeaderVersion;
|
||||
Flags flags;
|
||||
u64 packageId;
|
||||
u32 validDataEndAddress;
|
||||
padding[4];
|
||||
u8 iv[0x10];
|
||||
u64 partitionFsHeaderAddress;
|
||||
type::Size<u64> partitionFsHeaderSize;
|
||||
u8 partitionFsHeaderHash[0x20];
|
||||
u8 initialDataHash[0x20];
|
||||
SelSec selSec;
|
||||
u32 selT1Key;
|
||||
u32 selKey;
|
||||
u32 limArea;
|
||||
|
||||
u8 cardHeaderEncryptedData[0x70];
|
||||
};
|
||||
|
||||
struct FileEntry {
|
||||
u64 dataOffset;
|
||||
type::Size<u64> dataSize;
|
||||
u32 fileNameOffset;
|
||||
type::Size<u32> hashedRegionSize;
|
||||
padding[8];
|
||||
u8 hash[0x20];
|
||||
};
|
||||
|
||||
struct String {
|
||||
char string[];
|
||||
};
|
||||
|
||||
struct File {
|
||||
String fileName @ addressof(parent.stringTable) + parent.fileEntryTable[std::core::array_index()].fileNameOffset;
|
||||
u8 data[parent.fileEntryTable[std::core::array_index()].dataSize] @ addressof(parent.stringTable) + sizeof(parent.stringTable) + parent.fileEntryTable[std::core::array_index()].dataOffset [[sealed]];
|
||||
};
|
||||
|
||||
struct PartitionFs {
|
||||
type::Magic<"HFS0"> magic;
|
||||
u32 fileCount;
|
||||
type::Size<u32> stringTableSize;
|
||||
padding[4];
|
||||
FileEntry fileEntryTable[fileCount];
|
||||
String stringTable[while($ < (addressof(fileEntryTable) + sizeof(fileEntryTable) + stringTableSize))];
|
||||
|
||||
File files[fileCount];
|
||||
};
|
||||
|
||||
struct XCI {
|
||||
CardHeader header;
|
||||
|
||||
PartitionFs x @ header.romAreaStartPageAddress * PAGE_SIZE;
|
||||
|
||||
};
|
||||
|
||||
XCI xci @ 0x00;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user