Compare commits

..

126 Commits

Author SHA1 Message Date
Nik
f53be98204 patterns/chm: Added Windows HtmlHelp file pattern 2023-01-03 12:11:56 +01:00
Nik
ee95990225 patterns/macho: Added Mach-O pattern 2023-01-02 13:15:51 +01:00
Nik
ac28d9d029 patterns/coff: Added COFF pattern 2023-01-01 23:51:12 +01:00
123456abcdef
372a0e5bba tests/patterns: Added various pattern test files (#69)
Co-authored-by: Nik <werwolv98@gmail.com>
2022-12-31 22:45:46 +01:00
WerWolv
544cadbcca build: Fixed rest of unit tests 2022-12-31 22:38:40 +01:00
WerWolv
1471b02abd build: Fixed building unit tests 2022-12-31 10:13:29 +01:00
123456abcdef
73cde21254 patterns/zstd: Added ZSTD pattern (#68) 2022-12-30 22:05:21 +01:00
Minei3oat
f730d8b0cc patterns/gif: Added GIF pattern (#67)
patterns/gif: Added GIF pattern
2022-12-28 10:47:11 +01:00
123456abcdef
13183769f8 includes/std: Fix namespacing for std::limits::s*_max() (#66)
fix namespacing for std::limit::s*_max()
2022-12-27 11:04:47 +01:00
Nik
5eda5a15bf patterns: Added XCI and WAD pattern 2022-12-27 10:35:07 +01:00
Nik
8e6248aa2d patterns: Added PCX, GZip and PFS0 pattern 2022-12-27 00:56:24 +01:00
Nik
75fd40442b includes/type: Added BCD type 2022-12-24 15:10:23 +01:00
Nik
5a3036149c patterns/nbt: Added NBT pattern 2022-12-21 19:57:04 +01:00
Nik
b160e99b63 patterns/sit5: Added StuffItV5 archive pattern 2022-12-21 11:27:58 +01:00
Nik
f32db1745f tests/patterns: Added various pattern test files 2022-12-21 07:28:20 +01:00
Nik
7842c974df git: Fixed wrong pattern entry in readme table 2022-12-20 21:41:40 +01:00
Nik
e2c191b7c9 includes/std: Added std::mem::AlignTo type 2022-12-20 21:34:51 +01:00
Nik
71ee41fe2c patterns/fdt: Added flat device tree blob pattern 2022-12-20 17:14:23 +01:00
Nik
69feadfc09 patterns/cpio: Added new CPIO pattern 2022-12-20 16:08:10 +01:00
Nik
e79d512b2b includes/type: Fixed base types 2022-12-20 15:29:00 +01:00
gmestanley
e876270a08 encodings/shiftjis: Make control characters easier to read (#65)
* Update pe.hexpat

Implementing a number of things and fixing others

* Update pe.hexpat

Adding the readonlyData pattern

* Update pe.hexpat

Testing putting the number of tabs on Github to 4 instead of 8 (so that comments on the code for the Sections don't break)

* Update pe.hexpat

Reverting change that turned out to be needless

* Update pe.hexpat

Actually sending the `products[while($ != richHeaderEndPosition)]` to `products[while($ < richHeaderEndPosition)]` change

* Add files via upload

Adding NE test file

* Add files via upload

Adding NE pattern file

* Update ne.hexpat

Fixing the error with the entry table assignment

* Update README.md

Added the NE pattern file to the list of patterns

* Update shiftjis.tbl

Deleted the very first character and changed the other first ones' values
2022-12-19 16:21:06 +01:00
Nicolás Alvarez
8f39ecd879 patterns: Added pattern file for Apple PBZX compressed streams (#63)
This is used by Apple for Xcode .xip files (cpio in pbzx in xar), OTA
updates of iOS, and other files.
2022-12-18 00:36:41 +01:00
João Oliveira
ba36826e2d patterns: Added Tar Pattern (#64)
* patterns: add tar support

* readme: add tar entry

* patterns: update tar file

Co-authored-by: favaioos <120850826+favaioos@users.noreply.github.com>
2022-12-18 00:36:16 +01:00
Nik
ac0b77540d tests: Fixed more tests 2022-12-17 22:35:03 +01:00
Nik
683e78d9c3 tests: Fixed building of unit tests 2022-12-17 22:28:52 +01:00
Nik
110b498d7b includes/type: Added magic number assertion type 2022-11-29 14:43:27 +01:00
gmestanley
9887da7af5 patterns/ne: Adding pattern file for NE executables (#58)
* Update pe.hexpat

Implementing a number of things and fixing others

* Update pe.hexpat

Adding the readonlyData pattern

* Update pe.hexpat

Testing putting the number of tabs on Github to 4 instead of 8 (so that comments on the code for the Sections don't break)

* Update pe.hexpat

Reverting change that turned out to be needless

* Update pe.hexpat

Actually sending the `products[while($ != richHeaderEndPosition)]` to `products[while($ < richHeaderEndPosition)]` change

* Add files via upload

Adding NE test file

* Add files via upload

Adding NE pattern file

* Update ne.hexpat

Fixing the error with the entry table assignment

* Update README.md

Added the NE pattern file to the list of patterns
2022-11-19 19:25:02 +01:00
Nicolás Alvarez
01a1bd0d9f patterns/zip: Change how the end of central directory record is found (#60)
Previously, the zip pattern was searching for the end-of-central-directory
header signature (50 4B 05 06) by searching the entire file for it. This is
*very* slow for large files, and risks false positives since those bytes
could randomly appear in compressed data. I had this happen on the first
large (>2GB) zip file I tried.

I'm now checking for the EOCD signature at exactly 22 bytes from the end of
the file (in the common case there is no zip comment), and if that fails
I search for it in the last 64KB of the file (in case there *is* a comment
at the end of the EOCD, which can't be larger than 64KB). This is much
faster, and fixes loading my zip file where it was spuriously finding the
signature in the wrong place.

This still has a low risk of false positives (what if the comment has the
50 4B 05 06 bytes? what if there is a short comment but the signature
appears in the last 64KB of compressed data?), but I don't know what's the
"right" way to find the EOCD, or how proper zip-reading tools handle the
ambiguity...
2022-11-19 18:05:26 +01:00
finict
fbb6a84323 patterns: Fixed PNG pattern #61 (#62)
Closes #61
2022-11-19 18:04:51 +01:00
Nik
4cdf3c11cf includes/std: Fixed copy_section_to_section copy-paste error 2022-11-19 18:02:04 +01:00
Nicolás Alvarez
a9ada89bd0 patterns: Minor cleanup to zip pattern (#59)
* Use spaces instead of tabs in zip.hexpat

* patterns: minor cleanup to ZIP pattern

- Remove empty and unused CentralDirectoryEntry struct.
- Shorten the comment of CentralDirectoryFileHeader.fileOffset. It was so
  long that the tooltip overflowed my screen, and didn't really add much
  information.
- Small whitespace changes.
2022-11-14 22:46:28 +01:00
Merlyn Morgan-Graham
de0e089165 includes/std+type: Add DOS datetime types (#57)
Add type::dosdate16_t and type::dostime16_t in pattern library
2022-11-14 10:08:00 +01:00
Fredrick Brennan
e7ea6fd77f patterns: Added APNG support to PNG pattern (#53) 2022-11-10 10:36:46 +01:00
Fredrick Brennan
ff3c796de8 patterns: Added sRGB, zTXt, tEXt support to PNG pattern (#55)
* patterns: png.hexpat: APNG support

* patterns: png.hexpat: +sRGB, zTXt, tEXt
2022-11-10 10:23:42 +01:00
lieyanqzu
0c83764f24 patterns: Fix java class pattern and update to javase17 format (#56)
fix java class pattern and update to javase17 format
2022-11-10 10:23:06 +01:00
Fredrick Brennan
d87f95dbfa includes/type: Add RGB8 to color.pat (#54) 2022-11-10 10:22:17 +01:00
Nik
51dad63779 includes/std: Removed invalid returns 2022-11-09 21:56:06 +01:00
Nik
764b86acc9 includes/std: Added section functions 2022-11-09 21:53:31 +01:00
Nik
10fdf94899 includes/std: Fixed syntax error 2022-11-09 21:25:01 +01:00
Nik
9ba998e618 includes/std: Added new functions 2022-11-09 21:21:59 +01:00
WerWolv
aceeb2b7b3 git: Don't build plcli tool in tests 2022-11-06 18:40:39 +01:00
fr0ntlin3
3b1b7cc379 patterns: Fixed ELF pattern for 32-bit files (#51)
Co-authored-by: z <z>
2022-11-06 18:36:37 +01:00
gmestanley
49be43e0e1 patterns: Making pe.hexpat even better (#52)
* Update pe.hexpat

Implementing a number of things and fixing others

* Update pe.hexpat

Adding the readonlyData pattern

* Update pe.hexpat

Testing putting the number of tabs on Github to 4 instead of 8 (so that comments on the code for the Sections don't break)

* Update pe.hexpat

Reverting change that turned out to be needless

* Update pe.hexpat

Actually sending the `products[while($ != richHeaderEndPosition)]` to `products[while($ < richHeaderEndPosition)]` change
2022-10-30 12:07:54 +01:00
Nik
8e70a5524d includes/type: Added templates for number types with specific base 2022-10-10 22:36:46 +02:00
Nik
9c0bf1433c includes/std: Added new Array and SizedString type 2022-10-10 22:36:09 +02:00
Nik
43afbfa120 includes/type: Made size and float16 types more generic 2022-10-09 17:38:05 +02:00
Nik
f75703fd2b includes/std: Added MagicSearch and Reinterpreter helper type 2022-10-09 17:37:37 +02:00
Nik
16eebea2fb patterns: Added USB Descriptor pattern 2022-10-09 12:46:29 +02:00
Florian Limberger
6cb208d975 patterns: Added pattern for ID3 tags (#48)
* Add naive first implementation of ID3 patterns

* Refine string handling a bit

* Optimize structs using the static keyword

* Add MIME type pragma and update README
2022-10-09 12:26:34 +02:00
Nik
665c50b914 patterns: Fixed minidump pattern formatting 2022-10-08 11:20:46 +02:00
Nik
04ef9d6085 includes/type: Fixed copy-paste error in float16 type 2022-10-03 14:14:35 +02:00
Nik
dc5b219d24 includes/type: Fixed duplicate type definition in 010 types library 2022-10-03 10:51:43 +02:00
Nik
e6c800b71c includes/type: Fixed missing preprocessor instructions in size type library 2022-10-03 08:37:05 +02:00
Nik
5c9a7b1ac0 includes/type: Display space optimized version of IPv6 addresses 2022-10-02 23:25:10 +02:00
Nik
22390d0adf includes/type: Fixed broken float16 type 2022-10-02 22:57:46 +02:00
Nik
dfc9b17067 includes/type: Fixed missing include in color include 2022-10-02 21:55:48 +02:00
Nik
d33fdfafb8 git: Added links to all the files mentioned in the readme 2022-10-02 18:36:46 +02:00
Nik
58d63d1d4a includes/hex: Fixed mangled name format function 2022-10-01 21:53:41 +02:00
Nik
86f38ca545 includes/type: Added new color types 2022-09-30 14:52:30 +02:00
Nik
27d98d4552 includes/hex: Added support for new demangle function 2022-09-30 14:52:21 +02:00
Nik
dba93afe06 patterns: Fixed duplicate variable names 2022-09-21 16:34:23 +02:00
Nik
5481c2ff6a includes/std: Made relevant std::core functions take patterns as reference 2022-09-15 14:30:01 +02:00
Nik
efa9957935 git: Disable ci sanitizers again for now 2022-09-15 14:29:37 +02:00
Nik
073768fec3 includes/std: Fix passing std::file::Mode enum to builtin function 2022-09-15 11:39:17 +02:00
WerWolv
ceb322019c git: Fix CI command line 2022-09-14 15:12:59 +02:00
WerWolv
befd05f8dd tests: Enable sanitizers on unit tests 2022-09-14 15:11:17 +02:00
Nik
6a1abd8fec git: Look for coverage information in correct folder 2022-09-14 15:01:44 +02:00
Nik
b2ebbc6d66 git: Added coverage checking to tests 2022-09-14 14:56:52 +02:00
Nik
24c003b333 tests: Disable imhex checks in unit tests 2022-09-14 14:29:12 +02:00
Nik
caea4544ef includes/hex: Added library files 2022-09-14 14:01:54 +02:00
Nik
36b107f0ca includes/hex: Added imhex support library 2022-09-14 14:01:28 +02:00
Nik
6367f434ab includes: Removed old types library files 2022-09-14 14:01:15 +02:00
Nik
2cfd3c43a7 patterns: Added x-dosexec MIME type to PE pattern 2022-09-13 15:57:34 +02:00
Nik
4bda291de1 patterns: Added minidump pattern 2022-09-13 13:26:50 +02:00
Nik
ce542887c4 includes/type: Added aliases for builtin types 2022-09-11 21:53:18 +02:00
Nik
44216762fd patterns: Added msgpack pattern 2022-09-08 13:29:55 +02:00
Nik
3621144815 patterns: Added BSON pattern 2022-09-07 14:42:38 +02:00
Nik
244dd88098 includes/type: Fixed time_t format function 2022-09-07 14:21:53 +02:00
Nik
93c53f2d2e includes/type: Fixed time_t type and added time32_t and time64_t 2022-09-07 14:21:05 +02:00
Nik
ccd163b981 git: Added repository dispatch event to CI 2022-09-07 11:51:09 +02:00
Nik
cfc6a442de patterns: Added basic FLAC metadata pattern 2022-09-07 09:42:51 +02:00
Nik
62b1eb927e patterns: Added Xilinx bitstream pattern 2022-09-05 22:09:23 +02:00
Nik
2baae9c5f6 patterns: Added MIME types to ELF pattern 2022-09-04 23:01:31 +02:00
Nik
6ccb3bf465 includes/std: Add endian parameter to std::mem::read_unsigned and std::mem::read_signed 2022-09-04 20:37:19 +02:00
Nik
fc997133a1 patterns: Fix use of std::core::Endian 2022-09-04 20:26:46 +02:00
Nik
966c4e15b0 includes/std: Moved Endian enum to std::mem 2022-09-04 20:26:05 +02:00
Nik
935a26e9f9 patterns: Fixed parsing of WAV files generated by AudaCity
Thanks to @rikogeln
2022-09-04 17:45:39 +02:00
Nik
529c419ca8 git: Added pattern pull request template 2022-09-04 15:57:51 +02:00
Nik
befd6ef448 includes/std: Cast endian to integer before passing it to evaluator 2022-09-04 14:31:26 +02:00
Nik
45da27275d tests: Added elf test data 2022-09-04 14:17:04 +02:00
Nik
60c5f795a0 patterns: Greatly improve ELF pattern 2022-09-04 14:15:41 +02:00
Nik
72acac1082 tests: Added lnk test data 2022-09-02 23:45:11 +02:00
Nik
a9d6c882ac patterns: Replaced tabs with spaces in lnk pattern 2022-09-02 23:21:40 +02:00
Nik
7ecfcd446d patterns: Added Microsoft Shell Link pattern 2022-09-02 23:13:43 +02:00
Nik
b094757b03 includes/type: Display size type bytes without decimal points 2022-09-02 22:49:35 +02:00
Nik
1d0b11372f includes/type: Fixed size type visualizer 2022-09-02 22:45:20 +02:00
mirusu400
f01ddec350 encodings: Add euc_kr table (#46)
* Add euc_kr table

* Fix euc_kr to numberic order, Add README to euc_kr table
2022-09-02 18:34:49 +02:00
Nik
64136ba16c tests: Added correct ntag test file 2022-09-02 17:22:40 +02:00
Nik
1e45938887 patterns: Added NTAG pattern 2022-09-02 17:14:23 +02:00
Nik
f32b162647 patterns: Added VHDX pattern 2022-08-31 15:08:32 +02:00
Nik
d2685aabf5 lib/type: Added size type 2022-08-31 15:05:10 +02:00
Nik
8027cda032 lib/std: Added std::core::formatted_value function 2022-08-31 15:02:47 +02:00
WerWolv
a178509b3c patterns: Added stl pattern 2022-08-29 15:23:43 +02:00
WerWolv
56411ae067 patterns: Added MIME type for ogg pattern 2022-08-29 15:02:42 +02:00
WerWolv
7ee489237d patterns: Added Ogg pattern 2022-08-29 15:02:08 +02:00
WerWolv
4d97e79097 lib/std: Added std::core::member_count and std::core::has_member functions 2022-08-28 22:41:43 +02:00
WerWolv
9fec10000a patterns: Fixed ZigZag encoding in protobuf pattern 2022-08-28 19:07:30 +02:00
WerWolv
b0d8b81861 patterns: Added protobuf pattern 2022-08-28 13:51:58 +02:00
ThePixelCoder
c7fbb661ae patterns: Add GNU program types to ELF (#35) 2022-08-27 12:51:45 +02:00
jz5
7e19b4cb10 patterns: Fixed chunk size issues in WAV pattern. (#44) 2022-08-27 12:50:53 +02:00
Berylskid
ff2726ce8a encodings: Added control characters to shiftjis encoding(#43)
Fixed and added control character encoding.
2022-08-27 12:43:50 +02:00
Alexander Kozlov
ed47fa65f1 encodings: Add cyrillyc cp866 encoding (#45) 2022-08-27 12:42:44 +02:00
WerWolv
f0963603bf patterns: Added bencode pattern 2022-08-27 12:41:59 +02:00
WerWolv
15548b92e2 includes/std: Added core library functions 2022-08-19 00:00:30 +02:00
WerWolv
87efc6cf54 includes/std: Fixed std::string::contains function not checking last character 2022-08-16 09:48:42 +02:00
WerWolv
5e48adcb9d scripts: Properly open legacy hexproj files as UTF-8 2022-08-16 09:27:05 +02:00
Lucy
f548643933 encodings: Add English Pokémon generation 1 character encoding (#42)
* encodings: Add English Pokémon generation 1 character encoding

Source: https://bulbapedia.bulbagarden.net/wiki/Character_encoding_(Generation_I)#English

* readme: Add `pokegen1_en.tbl`
2022-08-14 17:46:40 +02:00
WerWolv
575e4d5381 scripts: Added helper scripts to extract old project files 2022-08-14 14:47:28 +02:00
WerWolv
6b0fad199e git: Remove LR line ending requirements 2022-08-10 19:22:35 +02:00
gmestanley
ece86f1124 patterns: Added enhancements for PE pattern (#41)
The current pattern file for the PE format doesn't have a lot of the format's quirks, so I decided to code them in after I noticed that it doesn't cover the structure known as Rich Header. (Forgive the garbage code for its ProductType enum, it was the only way I found to make the values appear.)
Here are my sources for the improvements included here:

How the MZ header works and some of its variables' names: [How to determine the size of an PE executable file from headers and or footers](https://stackoverflow.com/questions/34684660/how-to-determine-the-size-of-an-pe-executable-file-from-headers-and-or-footers)
The function of some of the MZ header variables: [https://github.com/corkami/pics/blob/master/binary/pe102.png](PE102 by Corkami)
The existence of sections: [https://github.com/corkami/pics/blob/master/binary/pe101/pe101.png](PE101 by Corkami)
The Machine values for LoongArch processors, the architecture enum and how it's used in the Optional Header, Subsystem types, DLL & Section characteristics, how sections, their line numbers and relocations work: [PE Format](https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#the-rsrc-section)
The Machine values for DECAlphaAXP and i860: [Peering Inside the PE: A Tour of the Win32 Portable Executable File Format](https://docs.microsoft.com/en-us/previous-versions/ms809762(v=msdn.10)#the-pe-header)
How the Rich Header works: [https://www.virusbulletin.com/virusbulletin/2020/01/vb2019-paper-rich-headers-leveraging-mysterious-artifact-pe-format/](VB2019 paper: Rich Headers: leveraging this mysterious artifact of the PE format)
Values of products in the Rich Header: [https://securelist.com/the-devils-in-the-rich-header/84348/](The devil’s in the Rich header)
Every other value not found in the above source: Ghidra
2022-08-10 15:06:10 +02:00
WerWolv
ce2b4d60ca patterns: Added very basic MBR and FAT32 filesystem pattern 2022-08-10 14:36:06 +02:00
WerWolv
7c88439681 git: Output errors when ctest fails 2022-08-09 16:10:27 +02:00
WerWolv
8d3c94be8f tests: Make tests compile with latest PatternLanguage update 2022-08-07 22:55:00 +02:00
WerWolv
0b15299980 patterns: Remove [[static]] attribute from non-static struct in elf pattern 2022-08-07 21:40:54 +02:00
WerWolv
eda13b2518 includes/type: Added [[sealed]] attribute to LEB128 type 2022-08-05 13:49:26 +02:00
Oded Shapira
aa6c90fa5b includes/type: Added LEB128 type (#40)
* Implement VarInt type

* VarInts are little endian, make result u128

* Rename VarInt to LEB128

* It didn't remove the varint file
2022-08-05 13:45:34 +02:00
115 changed files with 25366 additions and 728 deletions

8
.gitattributes vendored
View File

@@ -1,10 +1,2 @@
*.pat linguist-language=Rust
*.hexpat linguist-language=Rust
constants/* text eol=lf
encodings/* text eol=lf
includes/* text eol=lf
magic/* text eol=lf
patterns/* text eol=lf
structs/* text eol=lf
tips/* text eol=lf
yara/* text eol=lf

View File

@@ -0,0 +1,10 @@
# Pattern
[Information about your pattern]
## Checklist
- [ ] A pattern for this format doesn't exist yet (or this PR improves the existing one)
- [ ] The new pattern has been added to the relevant table in the Readme
- [ ] The pattern was associated with all relevant MIME types (using `#pragma MIME mime-type` in the source code)
- [ ] A test file for this pattern has been added to [/tests/patterns/test_data](/tests/patterns/test_data)
- Try to keep this file below ~ 1 MB

View File

@@ -5,6 +5,8 @@ on:
branches: [ '*' ]
pull_request:
branches: [ '*' ]
repository_dispatch:
types: [run_tests]
jobs:
tests:
@@ -34,7 +36,8 @@ jobs:
make \
python3 \
python3-pip \
libmagic-dev
libmagic-dev \
lcov
sudo pip install jsonschema
@@ -43,17 +46,30 @@ jobs:
cd tests
mkdir -p build
cd build
CC=gcc-12 CXX=g++-12 cmake \
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
-DLIBPL_ENABLE_TESTS=OFF \
CC=gcc-12 CXX=g++-12 cmake \
-DCMAKE_C_FLAGS="-fuse-ld=lld --coverage" \
-DCMAKE_CXX_FLAGS="-fuse-ld=lld --coverage" \
-DLIBPL_ENABLE_TESTS=OFF \
-DLIBPL_ENABLE_CLI=OFF \
..
make -j4
- name: 🧪 Perform Unit Tests
run: |
cd tests/build
ctest
ctest --output-on-failure
- name: ⚗️ Generate Coverage Report
run: |
cd tests/build
lcov -d ./_deps/pattern_language-build/lib --gcov-tool /usr/bin/gcov-12 -c -o coverage.info
- name: ⬆️ Upload Coverage Report
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: tests/build/coverage.info
- name: 📎 Validate JSON Files
run: |
cd constants

167
README.md
View File

@@ -8,106 +8,139 @@ Hex patterns, include patterns and magic files for the use with the ImHex Hex Ed
| Name | MIME | Path | Description |
|------|------|------|-------------|
| BMP | `image/bmp` | `patterns/bmp.hexpat` | OS2/Windows Bitmap files |
| ELF | `application/x-executable`, `application/x-sharedlib` | `patterns/elf.hexpat` | ELF header in elf binaries |
| PE | `application/x-dosexec` | `patterns/pe.hexpat` | PE header, COFF header, Standard COFF fields and Windows Specific fields |
| Intel HEX | | `patterns/intel_hex.hexpat` | [Intel hexadecimal object file format definition]("https://en.wikipedia.org/wiki/Intel_HEX") |
| MIDI | `audio/midi` | `patterns/midi.hexpat` | MIDI header, event fields provided |
| WAV | `audio/wav` | `patterns/wav.hexpat` | RIFF header, WAVE header, PCM header |
| ZIP | `application/zip` | `patterns/zip.hexpat` | End of Central Directory Header, Central Directory File Headers |
| PCAP | `application/vnd.tcpdump.pcap` | `patterns/pcap.hexpat` | pcap header and packets |
| SPIRV | | `patterns/spirv.hexpat` | SPIR-V header and instructions |
| AFE2 | | `patterns/afe2.hexpat` | Nintendo Switch Atmosphère CFW Fatal Error log |
| AR | `application/x-archive` | `patterns/ar.hexpat` | Static library archive files |
| NACP | | `patterns/nacp.hexpat` | Nintendo Switch NACP files |
| NRO | | `patterns/nro.hexpat` | Nintendo Switch NRO files |
| PRODINFO | | `patterns/prodinfo.hexpat` | Nintendo Switch PRODINFO |
| Java Class | `application/x-java-applet` | `patterns/java_class.hexpat` | Java Class files |
| ARM VTOR | | `patterns/arm_cm_vtor.hexpat` | ARM Cortex M Vector Table Layout |
| ICO | | `patterns/ico.hexpat` | Icon (.ico) or Cursor (.cur) files |
| PNG | `image/png` | `patterns/png.hexpat` | PNG image files |
| DDS | `image/vnd-ms.dds` | `patterns/dds.hexpat` | DirectDraw Surface |
| TGA | `image/tga` | `patterns/tga.hexpat` | Truevision TGA/TARGA image |
| ISO | | `patterns/iso.hexpat` | ISO 9660 file system |
| VDF | | `patterns/vdf.hexpat` | Binary Value Data Format (.vdf) files |
| IP | | `patterns/ip.hexpat` | Ethernet II Frames (IP Packets) |
| UF2 | | `patterns/uf2.hexpat` | [USB Flashing Format](https://github.com/microsoft/uf2) |
| BMP | `image/bmp` | [`patterns/bmp.hexpat`](patterns/bmp.hexpat) | OS2/Windows Bitmap files |
| ELF | `application/x-executable` | [`patterns/elf.hexpat`](patterns/elf.hexpat) | ELF header in elf binaries |
| PE | `application/x-dosexec` | [`patterns/pe.hexpat`](patterns/pe.hexpat) | PE header, COFF header, Standard COFF fields and Windows Specific fields |
| NE | | [`patterns/ne.hexpat`](patterns/ne.hexpat) | NE header and Standard NE fields |
| Intel HEX | | [`patterns/intel_hex.hexpat`](patterns/intel_hex.hexpat) | [Intel hexadecimal object file format definition]("https://en.wikipedia.org/wiki/Intel_HEX") |
| MIDI | `audio/midi` | [`patterns/midi.hexpat`](patterns/midi.hexpat) | MIDI header, event fields provided |
| WAV | `audio/wav` | [`patterns/wav.hexpat`](patterns/wav.hexpat) | RIFF header, WAVE header, PCM header |
| ZIP | `application/zip` | [`patterns/zip.hexpat`](patterns/zip.hexpat) | End of Central Directory Header, Central Directory File Headers |
| PCAP | `application/vnd.tcpdump.pcap` | [`patterns/pcap.hexpat`](patterns/pcap.hexpat) | pcap header and packets |
| SPIRV | | [`patterns/spirv.hexpat`](patterns/spirv.hexpat) | SPIR-V header and instructions |
| AFE2 | | [`patterns/afe2.hexpat`](patterns/afe2.hexpat) | Nintendo Switch Atmosphère CFW Fatal Error log |
| AR | `application/x-archive` | [`patterns/ar.hexpat`](patterns/ar.hexpat) | Static library archive files |
| NACP | | [`patterns/nacp.hexpat`](patterns/nacp.hexpat) | Nintendo Switch NACP files |
| NRO | | [`patterns/nro.hexpat`](patterns/nro.hexpat) | Nintendo Switch NRO files |
| PRODINFO | | [`patterns/prodinfo.hexpat`](patterns/prodinfo.hexpat) | Nintendo Switch PRODINFO |
| Java Class | `application/x-java-applet` | [`patterns/java_class.hexpat`](patterns/java_class.hexpat) | Java Class files |
| ARM VTOR | | [`patterns/arm_cm_vtor.hexpat`](patterns/arm_cm_vtor.hexpat) | ARM Cortex M Vector Table Layout |
| ICO | | [`patterns/ico.hexpat`](patterns/ico.hexpat) | Icon (.ico) or Cursor (.cur) files |
| PNG | `image/png` | [`patterns/png.hexpat`](patterns/png.hexpat) | PNG image files |
| DDS | `image/vnd-ms.dds` | [`patterns/dds.hexpat`](patterns/dds.hexpat) | DirectDraw Surface |
| TGA | `image/tga` | [`patterns/tga.hexpat`](patterns/tga.hexpat) | Truevision TGA/TARGA image |
| ISO | | [`patterns/iso.hexpat`](patterns/iso.hexpat) | ISO 9660 file system |
| VDF | | [`patterns/vdf.hexpat`](patterns/vdf.hexpat) | Binary Value Data Format (.vdf) files |
| IP | | [`patterns/ip.hexpat`](patterns/ip.hexpat) | Ethernet II Frames (IP Packets) |
| UF2 | | [`patterns/uf2.hexpat`](patterns/uf2.hexpat) | [USB Flashing Format](https://github.com/microsoft/uf2) |
| File System | | [`patterns/fs.hexpat`](patterns/fs.hexpat) | Drive File System |
| Bencode | `application/x-bittorrent` | [`patterns/bencode.hexpat`](patterns/bencode.hexpat) | Bencode encoding, used by Torrent files |
| Protobuf | | [`patterns/protobuf.hexpat`](patterns/protobuf.hexpat) | Google Protobuf encoding |
| OGG | `audio/ogg` | [`patterns/ogg.hexpat`](patterns/ogg.hexpat) | OGG Audio format |
| STL | `model/stl` | [`patterns/stl.hexpat`](patterns/stl.hexpat) | STL 3D Model format |
| VHDX | | [`patterns/vhdx.hexpat`](patterns/vhdx.hexpat) | Microsoft Hyper-V Virtual Hard Disk format |
| NTAG | | [`patterns/ntag.hexpat`](patterns/ntag.hexpat) | NTAG213/NTAG215/NTAG216, NFC Forum Type 2 Tag compliant IC |
| Shell Link | `application/x-ms-shortcut` | [`patterns/lnk.hexpat`](patterns/lnk.hexpat) | Windows Shell Link file format |
| Xilinx BIT | | [`patterns/xilinx_bit.hexpat`](patterns/xilinx_bit.hexpat) | Xilinx FPGA Bitstreams |
| FLAC | `audio/flac` | [`patterns/flac.hexpat`](patterns/flac.hexpat) | Free Lossless Audio Codec, FLAC Audio Format |
| BSON | `application/bson` | [`patterns/bson.hexpat`](patterns/bson.hexpat) | BSON (Binary JSON) format |
| msgpack | `application/x-msgpack` | [`patterns/msgpack.hexpat`](patterns/msgpack.hexpat) | MessagePack binary serialization format |
| MiniDump | `application/x-dmp` | [`patterns/minidump.hexpat`](patterns/minidump.hexpat) | Windows MiniDump files |
| ID3 | `audio/mpeg` | [`patterns/id3tag.hexpat`](patterns/id3tag.hexpat) | ID3 tags in MP3 files |
| TAR | `application/x-tar` | [`patterns/tar.hexpat`](patterns/tar.hexpat) | Tar file format |
| CPIO | `application/x-cpio` | [`patterns/cpio.hexpat`](patterns/cpio.hexpat) | Old Binary CPIO Format |
| FDT | | [`patterns/fdt.hexpat`](patterns/fdt.hexpat) | Flat Linux Device Tree blob |
| StuffItV5 | `application/x-stuffit` | [`patterns/sit5.hexpat`](patterns/sit5.hexpat) | StuffIt V5 archive |
| NBT | | [`patterns/nbt.hexpat`](patterns/nbt.hexpat) | Minecraft NBT format |
| PCX | `application/x-pcx` | [`patterns/pcx.hexpat`](patterns/pcx.hexpat) | PCX Image format |
| GZIP | `application/gzip` | [`patterns/gzip.hexpat`](patterns/gzip.hexpat) | GZip compressed data format |
| PFS0 | | [`patterns/pfs0.hexpat`](patterns/pfs0.hexpat) | Nintendo Switch PFS0 archive (NSP files) |
| XCI | | [`patterns/xci.hexpat`](patterns/xci.hexpat) | Nintendo Switch XCI cardridge ROM |
| WAD | | [`patterns/wad.hexpat`](patterns/wad.hexpat) | DOOM WAD Archive |
| GIF | `image/gif` | [`patterns/gif.hexpat`](patterns/gif.hexpat) | GIF image files |
| ZSTD | `application/zstd` | [`patterns/zstd.hexpat`](patterns/zstd.hexpat) | Zstandard compressed data format |
| COFF | `application/x-coff` | [`patterns/coff.hexpat`](patterns/coff.hexpat) | Common Object File Format (COFF) executable |
| Mach-O | `application/x-mach-binary` | [`patterns/macho.hexpat`](patterns/macho.hexpat) | Mach-O executable |
| CHM | | [`patterns/chm.hexpat`](patterns/chm.hexpat) | Windows HtmlHelp Data (ITSF / CHM) |
### Scripts
| Name | Path | Description |
|------|------|-------------|
| svd2pat | `scripts/svd2pat.py` | Converts a ARM .svd register MMIO definition file into a pattern |
| csv2tbl | `scripts/csv2tbl.py` | Converts a 010 editor CSV encoding file into a table file |
| svd2pat | [`scripts/svd2pat.py`](scripts/svd2pat.py) | Converts a ARM .svd register MMIO definition file into a pattern |
| csv2tbl | [`scripts/csv2tbl.py`](scripts/csv2tbl.py) | Converts a 010 editor CSV encoding file into a table file |
### Pattern Libraries
| Name | Path | Description |
|------|------|-------------|
| libstd | `includes/std/*` | Pattern Language Standard Libaray |
| cstdint | `includes/cstdint.pat` | C integer types |
| libstd | [`includes/std/*`](includes/std) | Pattern Language Standard Libaray |
| libtype | [`includes/type/*`](includes/type) | Various custom types with special formatters |
| libhex | [`includes/hex/*`](includes/hex) | Functions to interact with ImHex |
### Yara rules
| Name | Path | Description |
|------|------|-------------|
| Official Rules | `yara/official_rules/*` | Official Yara rules repository |
| Official Rules | [`yara/official_rules/*`](yara/official_rules) | Official Yara rules repository |
### Magic files
| Name | Path | Description |
|------|------|-------------|
| Nintendo Switch | `magic/nintendo_switch_magic` | Identifies common file types used on the Nintendo Switch |
| Portable Executable | `magic/portable_executable_magic` | Identifies PE files used on Windows
| Nintendo Switch | [`magic/nintendo_switch_magic`](magic/nintendo_switch_magic) | Identifies common file types used on the Nintendo Switch |
| Portable Executable | [`magic/portable_executable_magic`](magic/portable_executable_magic) | Identifies PE files used on Windows
### Constants files
| Name | Path | Description |
|------|------|-------------|
| CRC-16 | `constants/crc16.json` | Constants associated with CRC-16 operations |
| CRC-32 | `constants/crc32.json` | Constants associated with CRC-32 operations |
| HTTP-Codes | `constants/http_status.json` | HTTP Status code values |
| Linux Error Codes | `constants/linux_errors.json` | Values of Linux error results |
| CRC-16 | [`constants/crc16.json`](constants/crc16.json) | Constants associated with CRC-16 operations |
| CRC-32 | [`constants/crc32.json`](constants/crc32.json) | Constants associated with CRC-32 operations |
| HTTP-Codes | [`constants/http_status.json`](constants/http_status.json) | HTTP Status code values |
| Linux Error Codes | [`constants/linux_errors.json`](constants/linux_errors.json) | Values of Linux error results |
### Encoding files
| Name | Path | Description |
|------|------|-------------|
| Arabic ISO | `encodings/arabic_iso.tbl` | Arabic ISO encoding |
| Arabic Windows | `encodings/arabic_windows.tbl` | Arabic Windows encoding |
| ASCII | `encodings/ascii.tbl` | Regular ASCII encoding |
| ASCII+ANSI | `encodings/ascii_ansi.tbl` | Extended ASCII encoding |
| ASCII+OEM | `encodings/ascii_oem.tbl` | ASCII encoding with Windows OEM characters |
| Baltic ISO | `encodings/baltic_iso.tbl` | Baltic ISO encoding |
| Baltic Windows | `encodings/baltic_windows.tbl` | Baltic Windows encoding |
| Cyrillic ISO | `encodings/cyrillic_iso.tbl` | Cyrillic ISO encoding |
| Cyrillic Windows | `encodings/cyrillic_windows.tbl` | Cyrillic Windows encoding |
| Cyrillic KOI8-R | `encodings/cyrillic_koi8_r.tbl` | Cyrillic KOI8-R encoding (Russian Characters) |
| Cyrillic KOI8-U | `encodings/cyrillic_koi8_u.tbl` | Cyrillic KOI8-U encoding (Ukranian Characters) |
| Eastern Europe ISO | `encodings/eastern_europe_iso.tbl` | Eastern Europe ISO encoding |
| Eastern Europe Windows | `encodings/eastern_europe_windows.tbl` | Eastern Europe Windows encoding |
| EBCDIC | `encodings/ebcdic.tbl` | Extended Binary Coded Decimal Interchange Code, developed by IBM for their Main Frames |
| EUC-JP | `encodings/euc_jp.tbl` | EUC-JP encoding with NEC special and IBM extended characters |
| Greek ISO | `encodings/greek_iso.tbl` | Greek ISO encoding |
| Greek Windows | `encodings/greek_windows.tbl` | Greek Windows encoding |
| Hebrew ISO | `encodings/hebrew_iso.tbl` | Hebrew ISO encoding |
| Hebrew Windows | `encodings/hebrew_windows.tbl` | Hebrew Windows encoding |
| ISO/IEC 646 | `encodings/iso_646.tbl` | ISO/IEC 646 encoding, an older version of ASCII |
| ISO/IEC 6937 | `encodings/iso_6937.tbl` | ISO/IEC 6937 encoding, an extension of ASCII containing additional character |
| JIS 0201 | `encodings/jis_x_0201.tbl` | JIS X 0201 encoding in UTF-8 |
| JIS X 0211 | `encodings/jis_x_0211.tbl` | JIS X 0211 encoding in UTF-8 |
| JIS 0213 | `encodings/jis_x_0213.tbl` | JIS X 0213 encoding in UTF-8 |
| Macintosh | `encodings/macintosh.tbl` | Macintosh character encoding used by the Kermit protocol |
| Shift-JIS UTF-8 | `encodings/shiftjis.tbl` | Shift-JIS encoding in UTF-8 |
| Thai | `encodings/thai.tbl` | Thai character encoding |
| Turkish ISO | `encodings/turkish_iso.tbl` | Turkish ISO encoding |
| Turkish Windows | `encodings/turkish_windows.tbl` | Turkish Windows encoding |
| UTF-8 | `encodings/utf8.tbl` | UTF-8 encoding |
| Vietnamese | `encodings/vietnamese.tbl` | Vietnamese character encoding |
| Arabic ISO | [`encodings/arabic_iso.tbl`](encodings/arabic_iso.tbl) | Arabic ISO encoding |
| Arabic Windows | [`encodings/arabic_windows.tbl`](encodings/arabic_windows.tbl) | Arabic Windows encoding |
| ASCII | [`encodings/ascii.tbl`](encodings/ascii.tbl) | Regular ASCII encoding |
| ASCII+ANSI | [`encodings/ascii_ansi.tbl`](encodings/ascii_ansi.tbl) | Extended ASCII encoding |
| ASCII+OEM | [`encodings/ascii_oem.tbl`](encodings/ascii_oem.tbl) | ASCII encoding with Windows OEM characters |
| Baltic ISO | [`encodings/baltic_iso.tbl`](encodings/baltic_iso.tbl) | Baltic ISO encoding |
| Baltic Windows | [`encodings/baltic_windows.tbl`](encodings/baltic_windows.tbl) | Baltic Windows encoding |
| Cyrillic ISO | [`encodings/cyrillic_iso.tbl`](encodings/cyrillic_iso.tbl) | Cyrillic ISO encoding |
| Cyrillic Windows | [`encodings/cyrillic_windows.tbl`](encodings/cyrillic_windows.tbl) | Cyrillic Windows encoding |
| Cyrillic KOI8-R | [`encodings/cyrillic_koi8_r.tbl`](encodings/cyrillic_koi8_r.tbl) | Cyrillic KOI8-R encoding (Russian Characters) |
| Cyrillic KOI8-U | [`encodings/cyrillic_koi8_u.tbl`](encodings/cyrillic_koi8_u.tbl) | Cyrillic KOI8-U encoding (Ukranian Characters) |
| Eastern Europe ISO | [`encodings/eastern_europe_iso.tbl`](encodings/eastern_europe_iso.tbl) | Eastern Europe ISO encoding |
| Eastern Europe Windows | [`encodings/eastern_europe_windows.tbl`](encodings/eastern_europe_windows.tbl) | Eastern Europe Windows encoding |
| EBCDIC | [`encodings/ebcdic.tbl`](encodings/ebcdic.tbl) | Extended Binary Coded Decimal Interchange Code, developed by IBM for their Main Frames |
| EUC-JP | [`encodings/euc_jp.tbl`](encodings/euc_jp.tbl) | EUC-JP encoding with NEC special and IBM extended characters |
| EUC-KR | [`encodings/euc_kr.tbl`](encodings/euc_kr.tbl) | EUC-KR encoding |
| Greek ISO | [`encodings/greek_iso.tbl`](encodings/greek_iso.tbl) | Greek ISO encoding |
| Greek Windows | [`encodings/greek_windows.tbl`](encodings/greek_windows.tbl) | Greek Windows encoding |
| Hebrew ISO | [`encodings/hebrew_iso.tbl`](encodings/hebrew_iso.tbl) | Hebrew ISO encoding |
| Hebrew Windows | [`encodings/hebrew_windows.tbl`](encodings/hebrew_windows.tbl) | Hebrew Windows encoding |
| ISO/IEC 646 | [`encodings/iso_646.tbl`](encodings/iso_646.tbl) | ISO/IEC 646 encoding, an older version of ASCII |
| ISO/IEC 6937 | [`encodings/iso_6937.tbl`](encodings/iso_6937.tbl) | ISO/IEC 6937 encoding, an extension of ASCII containing additional character |
| JIS 0201 | [`encodings/jis_x_0201.tbl`](encodings/jis_x_0201.tbl) | JIS X 0201 encoding in UTF-8 |
| JIS X 0211 | [`encodings/jis_x_0211.tbl`](encodings/jis_x_0211.tbl) | JIS X 0211 encoding in UTF-8 |
| JIS 0213 | [`encodings/jis_x_0213.tbl`](encodings/jis_x_0213.tbl) | JIS X 0213 encoding in UTF-8 |
| Macintosh | [`encodings/macintosh.tbl`](encodings/macintosh.tbl) | Macintosh character encoding used by the Kermit protocol |
| Pokémon (English, Generation 1) | [`encodings/pokegen1_en.tbl`](encodings/pokegen1_en.tbl) | Character encoding used by the English generation 1 Pokémon games |
| Shift-JIS UTF-8 | [`encodings/shiftjis.tbl`](encodings/shiftjis.tbl) | Shift-JIS encoding in UTF-8 |
| Thai | [`encodings/thai.tbl`](encodings/thai.tbl) | Thai character encoding |
| Turkish ISO | [`encodings/turkish_iso.tbl`](encodings/turkish_iso.tbl) | Turkish ISO encoding |
| Turkish Windows | [`encodings/turkish_windows.tbl`](encodings/turkish_windows.tbl) | Turkish Windows encoding |
| UTF-8 | [`encodings/utf8.tbl`](encodings/utf8.tbl) | UTF-8 encoding |
| Vietnamese | [`encodings/vietnamese.tbl`](encodings/vietnamese.tbl) | Vietnamese character encoding |
## Contributing
If you want to contribute a file to the database, please make a PR which adds it to the right folder and adds a new entry to the table in this readme.
To take advantage of the automatic pattern testing, please consider adding a test file named `<pattern_name>.hexpat.<extension>` to the `/tests/patterns/test_data` directory. Try to keep this file as small as possible so the repository doesn't become excessively large
Thanks a lot :)
Thanks a lot :)

View File

@@ -0,0 +1,256 @@
00=NUL
01=☺
02=☻
03=♥
04=♦
05=♣
06=♠
07=•
08=◘
09=○
0A=◙
0B=♂
0C=♀
0D=♪
0E=♫
0F=☼
10=►
11=◄
12=↕
13=‼
14=¶
15=§
16=▬
17=↨
18=↑
19=↓
1A=→
1B=←
1C=∟
1D=↔
1E=▲
1F=▼
20=
21=!
22="
23=#
24=$
25=%
26=&
27='
28=(
29=)
2A=*
2B=+
2C=,
2D=-
2E=.
2F=/
30=0
31=1
32=2
33=3
34=4
35=5
36=6
37=7
38=8
39=9
3A=:
3B=;
3C=<
3D==
3E=>
3F=?
40=@
41=A
42=B
43=C
44=D
45=E
46=F
47=G
48=H
49=I
4A=J
4B=K
4C=L
4D=M
4E=N
4F=O
50=P
51=Q
52=R
53=S
54=T
55=U
56=V
57=W
58=X
59=Y
5A=Z
5B=[
5C=\
5D=]
5E=^
5F=_
60=`
61=a
62=b
63=c
64=d
65=e
66=f
67=g
68=h
69=i
6A=j
6B=k
6C=l
6D=m
6E=n
6F=o
70=p
71=q
72=r
73=s
74=t
75=u
76=v
77=w
78=x
79=y
7A=z
7B={
7C=|
7D=}
7E=~
7F=⌂
80=А
81=Б
82=В
83=Г
84=Д
85=Е
86=Ж
87=З
88=И
89=Й
8A=К
8B=Л
8C=М
8D=Н
8E=О
8F=П
90=Р
91=С
92=Т
93=У
94=Ф
95=Х
96=Ц
97=Ч
98=Ш
99=Щ
9A=Ъ
9B=Ы
9C=Ь
9D=Э
9E=Ю
9F=Я
A0=а
A1=б
A2=в
A3=г
A4=д
A5=е
A6=ж
A7=з
A8=и
A9=й
AA=к
AB=л
AC=м
AD=н
AE=о
AF=п
B0=░
B1=▒
B2=▓
B3=│
B4=┤
B5=╡
B6=╢
B7=╖
B8=╕
B9=╣
BA=║
BB=╗
BC=╝
BD=╜
BE=╛
BF=┐
C0=└
C1=┴
C2=┬
C3=├
C4=─
C5=┼
C6=╞
C7=╟
C8=╚
C9=╔
CA=╩
CB=╦
CC=╠
CD=═
CE=╬
CF=╧
D0=╨
D1=╤
D2=╥
D3=╙
D4=╘
D5=╒
D6=╓
D7=╫
D8=╪
D9=┘
DA=┌
DB=█
DC=▄
DD=▌
DE=▐
DF=▀
E0=р
E1=с
E2=т
E3=у
E4=ф
E5=х
E6=ц
E7=ч
E8=ш
E9=щ
EA=ъ
EB=ы
EC=ь
ED=э
EE=ю
EF=я
F0=Ё
F1=ё
F2=Є
F3=є
F4=Ї
F5=ї
F6=Ў
F7=ў
F8=°
F9=∙
FA=·
FB=√
FC=№
FD=¤
FE=■
FF= 

16674
encodings/euc_kr.tbl Normal file

File diff suppressed because it is too large Load Diff

255
encodings/pokegen1_en.tbl Normal file
View File

@@ -0,0 +1,255 @@
00=NUL
01
02
03
04
05
06
07
08
09
0A
0B
0C
0D
0E
0F
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=page
4A=PkMn
4B=_cont
4C=autocont
4D
4E=next line
4F=bottom line
50=end
51=paragraph
52=player name
53=rival name
54=Poké
55=cont
56=......
57=done
58=prompt
59=target
5A=user
5B=PC
5C=TM
5D=TRAINER
5E=ROCKET
5F=dex
60=A
61=B
62=C
63=D
64=E
65=F
66=G
67=H
68=I
69=V
6A=S
6B=L
6C=M
6D=:
6E=ぃ
6F=ぅ
70=
71=
72=“
73=”
74=・
75=⋯
76=ぁ
77=ぇ
78=ぉ
79
7A
7B
7C
7D
7E
7F
80=A
81=B
82=C
83=D
84=E
85=F
86=G
87=H
88=I
89=J
8A=K
8B=L
8C=M
8D=N
8E=O
8F=P
90=Q
91=R
92=S
93=T
94=U
95=V
96=W
97=X
98=Y
99=Z
9A=(
9B=)
9C=
9D=;
9E=[
9F=]
A0=a
A1=b
A2=c
A3=d
A4=e
A5=f
A6=g
A7=h
A8=i
A9=j
AA=k
AB=l
AC=m
AD=n
AE=o
AF=p
B0=q
B1=r
B2=s
B3=t
B4=u
B5=v
B6=w
B7=x
B8=y
B9=z
BA=é
BB='d
BC='l
BD='s
BE='t
BF='v
C0
C1
C2
C3
C4
C5
C6
C7
C8
C9
CA
CB
CC
CD
CE
CF
D0
D1
D2
D3
D4
D5
D6
D7
D8
D9
DA
DB
DC
DD
DE
DF
E0='
E1=Pk
E2=Mn
E3=-
E4='r
E5='m
E6=?
E7=!
E8=.
E9=ァ
EA=ゥ
EB=ェ
EC=▷
ED=▶
EE=▼
EF=♂
F0=$
F1=×
F2=.
F3=/
F4=,
F5=♀
F6=0
F7=1
F8=2
F9=3
FA=4
FB=5
FC=6
FD=7
FE=8
FF=9

View File

@@ -1,6 +1,9 @@
00=
090D=(R)
0A=(BR)
08=␈
09=␉
0A=
0B=␋
0C=␌
0D=␍
20=
21=!
22="

View File

@@ -1,16 +0,0 @@
#pragma once
using uint8_t = u8;
using uint16_t = u16;
using uint32_t = u32;
using uint64_t = u64;
using uint128_t = u128;
using int8_t = s8;
using int16_t = s16;
using int32_t = s32;
using int64_t = s64;
using int128_t = s128;
using size_t = u32;
using ssize_t = s32;

29
includes/hex/core.pat Normal file
View File

@@ -0,0 +1,29 @@
#pragma once
#include <hex/impl/imhex_check.pat>
namespace hex::core {
struct Selection {
bool valid;
u64 address, size;
};
fn get_selection() {
u128 result = builtin::hex::core::get_selection();
Selection result;
if (result == u128(-1)) {
result.valid = false;
result.address = 0x00;
result.size = 0x00;
} else {
result.valid = true;
result.address = result >> 64;
result.size = result & u64(-1);
}
return result;
};
}

11
includes/hex/dec.pat Normal file
View File

@@ -0,0 +1,11 @@
#pragma once
#include <hex/impl/imhex_check.pat>
namespace hex::dec {
fn demangle(str mangled_name) {
return builtin::hex::dec::demangle(mangled_name);
};
}

11
includes/hex/http.pat Normal file
View File

@@ -0,0 +1,11 @@
#pragma once
#include <hex/impl/imhex_check.pat>
namespace hex::http {
fn get(str url) {
return builtin::hex::http::get(url);
};
}

View File

@@ -0,0 +1,7 @@
#ifndef __PL_UNIT_TESTS__
#ifndef __IMHEX__
#error This library is only available in the ImHex Hex editor
#endif
#endif

View File

@@ -0,0 +1,23 @@
#pragma once
#include <std/io.pat>
#include <std/mem.pat>
#include <hex/impl/imhex_check.pat>
#include <hex/dec.pat>
namespace hex::type {
struct MangledName {
char value[];
} [[sealed, format("hex::type::impl::format_mangled_name")]];
namespace impl {
fn format_mangled_name(ref MangledName name) {
return hex::dec::demangle(name.value);
};
}
}

9
includes/std/array.pat Normal file
View File

@@ -0,0 +1,9 @@
#pragma once
namespace std {
struct Array<T, auto Size> {
T data[Size] [[inline]];
};
}

View File

@@ -1,23 +0,0 @@
#pragma once
namespace std {
using uint8_t = u8;
using uint16_t = u16;
using uint32_t = u32;
using uint64_t = u64;
using uint128_t = u128;
using int8_t = s8;
using int16_t = s16;
using int32_t = s32;
using int64_t = s64;
using int128_t = s128;
using float32_t = float;
using float64_t = double;
using size_t = u64;
using ssize_t = s64;
}

60
includes/std/core.pat Normal file
View File

@@ -0,0 +1,60 @@
#pragma once
#include <std/mem.pat>
namespace std::core {
enum BitfieldOrder : u8 {
LeftToRight = 0,
RightToLeft = 1
};
fn has_attribute(ref auto pattern, str attribute) {
return builtin::std::core::has_attribute(pattern, attribute);
};
fn get_attribute_value(ref auto pattern, str attribute) {
return builtin::std::core::get_attribute_value(pattern, attribute);
};
fn set_endian(std::mem::Endian endian) {
builtin::std::core::set_endian(u32(endian));
};
fn get_endian() {
return builtin::std::core::get_endian();
};
fn set_bitfield_order(BitfieldOrder order) {
builtin::std::core::set_bitfield_order(u32(order));
};
fn get_bitfield_order() {
return builtin::std::core::get_bitfield_order();
};
fn array_index() {
return builtin::std::core::array_index();
};
fn member_count(ref auto pattern) {
return builtin::std::core::member_count(pattern);
};
fn has_member(ref auto pattern, str name) {
return builtin::std::core::has_member(pattern, name);
};
fn formatted_value(ref auto pattern) {
return builtin::std::core::formatted_value(pattern);
};
fn is_valid_enum(ref auto pattern) {
return builtin::std::core::is_valid_enum(pattern);
};
}

View File

@@ -12,7 +12,7 @@ namespace std::file {
fn open(str path, Mode mode) {
return builtin::std::file::open(path, mode);
return builtin::std::file::open(path, u32(mode));
};
fn close(Handle handle) {

View File

@@ -2,28 +2,8 @@
namespace std::hash {
fn crc32(u128 address, u64 size, u32 init, u32 poly) {
u8 byte;
u32 crc, mask;
crc = init;
u64 i;
while (i < size) {
byte = std::mem::read_unsigned(address + i, 1);
crc = crc ^ byte;
u8 j;
while (j < 8) {
mask = u32(-(crc & 1));
crc = (crc >> 1) ^ (poly & mask);
j = j + 1;
}
i = i + 1;
}
return u32(~crc);
fn crc32(ref auto pattern, u32 init, u32 poly) {
return builtin::std::hash::crc32(pattern, init, poly);
};
}

View File

@@ -1,9 +0,0 @@
#pragma once
namespace std::http {
fn get(str url) {
return builtin::std::http::get(url);
};
}

View File

@@ -15,7 +15,7 @@ namespace std::limits {
};
fn s8_max() {
return s8((u8_max() / 2));
return s8((std::limits::u8_max() / 2));
};
fn u16_min() {
@@ -31,7 +31,7 @@ namespace std::limits {
};
fn s16_max() {
return s16((u16_max() / 2));
return s16((std::limits::u16_max() / 2));
};
fn u32_min() {
@@ -47,7 +47,7 @@ namespace std::limits {
};
fn s32_max() {
return s32((u32_max() / 2));
return s32((std::limits::u32_max() / 2));
};
fn u64_min() {
@@ -63,7 +63,7 @@ namespace std::limits {
};
fn s64_max() {
return s64((u64_max() / 2));
return s64((std::limits::u64_max() / 2));
};
fn u128_min() {
@@ -79,7 +79,7 @@ namespace std::limits {
};
fn s128_max() {
return s128((u128_max() / 2));
return s128((std::limits::u128_max() / 2));
};
}
}

View File

@@ -2,6 +2,14 @@
namespace std::mem {
using Section = u128;
enum Endian : u8 {
Native = 0,
Big = 1,
Little = 2
};
fn eof() {
return $ >= std::mem::size();
};
@@ -29,16 +37,64 @@ namespace std::mem {
return builtin::std::mem::find_sequence_in_range(occurrence_index, offsetFrom, offsetTo, bytes);
};
fn read_unsigned(u128 address, u8 size) {
return builtin::std::mem::read_unsigned(address, size);
fn read_unsigned(u128 address, u8 size, Endian endian = Endian::Native) {
return builtin::std::mem::read_unsigned(address, size, u32(endian));
};
fn read_signed(u128 address, u8 size) {
return builtin::std::mem::read_signed(address, size);
fn read_signed(u128 address, u8 size, Endian endian = Endian::Native) {
return builtin::std::mem::read_signed(address, size, u32(endian));
};
fn read_string(u128 address, u8 size) {
return builtin::std::mem::read_string(address, size);
};
fn create_section(str name) {
return builtin::std::mem::create_section(name);
};
fn delete_section(Section section) {
builtin::std::mem::delete_section(section);
};
fn get_section_size(Section section) {
return builtin::std::mem::get_section_size(section);
};
fn copy_section_to_section(Section from_section, u64 from_address, Section to_section, u64 to_address, u64 size) {
builtin::std::mem::copy_to_section(from_section, from_address, to_section, to_address, size);
};
fn copy_value_to_section(ref auto value, Section to_section, u64 to_address) {
builtin::std::mem::copy_value_to_section(value, to_section, to_address);
};
struct MagicSearch<auto Magic, T> {
if ($ < (std::mem::size() - std::string::length(Magic) - 1)) {
char __potentialMagic__[std::string::length(Magic)] [[hidden, no_unique_address]];
if (__potentialMagic__ == Magic) {
T data [[inline]];
} else {
padding[1];
continue;
}
} else {
padding[1];
continue;
}
};
union Reinterpreter<From, To> {
From from;
To to;
};
struct AlignTo<auto Alignment> {
padding[Alignment - ((($ - 1) % Alignment) + 1)];
} [[hidden, sealed]];
}

View File

@@ -1,17 +0,0 @@
#pragma once
namespace std {
using i8 = s8;
using i16 = s16;
using i32 = s32;
using i64 = s64;
using i128 = s128;
using f32 = float;
using f64 = double;
using usize = u64;
using isize = s64;
}

View File

@@ -4,6 +4,22 @@
namespace std::string {
struct SizedStringBase<SizeType, DataType> {
SizeType size;
DataType data[size];
} [[sealed, format("std::string::impl::format_sized_string"), transform("std::string::impl::format_sized_string")]];
using SizedString<SizeType> = SizedStringBase<SizeType, char>;
using SizedString16<SizeType> = SizedStringBase<SizeType, char16>;
namespace impl {
fn format_sized_string(ref auto string) {
return string.data;
};
}
fn length(str string) {
return builtin::std::string::length(string);
};
@@ -39,15 +55,12 @@ namespace std::string {
};
fn contains(str a, str b) {
s32 a_len, b_len;
a_len = std::string::length(a);
b_len = std::string::length(b);
s32 a_len = std::string::length(a);
s32 b_len = std::string::length(b);
s32 i;
while (i < a_len - b_len) {
for (s32 i = 0, i <= (a_len - b_len), i += 1) {
if (std::string::substr(a, i, b_len) == b)
return true;
i = i + 1;
}
return false;

View File

@@ -15,12 +15,12 @@ namespace std::time {
u16 yday;
bool isdst;
} [[sealed]];
union TimeConverter {
Time time;
u128 value;
};
using EpochTime = u128;
enum TimeZone : u8 {
@@ -28,44 +28,94 @@ namespace std::time {
UTC
};
bitfield DOSDate {
day: 5;
month: 4;
year: 7;
} [[sealed]];
bitfield DOSTime {
seconds: 5;
minutes: 6;
hours: 5;
} [[sealed]];
namespace impl {
union DOSDateConverter {
DOSDate date;
u16 value;
};
union DOSTimeConverter {
DOSTime time;
u16 value;
};
}
fn epoch() {
return builtin::std::time::epoch();
};
fn to_local(EpochTime epoch_time) {
TimeConverter converter;
converter.value = builtin::std::time::to_local(epoch_time);
return converter.time;
};
fn to_utc(EpochTime epoch_time) {
TimeConverter converter;
converter.value = builtin::std::time::to_utc(epoch_time);
return converter.time;
};
fn to_utc(EpochTime epoch_time) {
TimeConverter converter;
converter.value = builtin::std::time::to_utc(epoch_time);
return converter.time;
};
fn now(TimeZone time_zone = TimeZone::Local) {
TimeConverter converter;
if (time_zone == TimeZone::Local)
converter.value = builtin::std::time::to_local(std::time::epoch());
else if (time_zone == TimeZone::UTC)
converter.value = builtin::std::time::to_utc(std::time::epoch());
else
converter.value = 0x00;
return converter.time;
};
fn to_dos_date(u16 value) {
impl::DOSDateConverter converter;
converter.value = value;
return converter.date;
};
fn to_dos_time(u16 value) {
impl::DOSTimeConverter converter;
converter.value = value;
return converter.time;
};
fn format(Time time, str format_string = "%c") {
TimeConverter converter;
converter.time = time;
return builtin::std::time::format(format_string, converter.value);
};
}
fn format_dos_date(DOSDate date, str format_string = "{}/{}/{}") {
return std::format(format_string, date.day, date.month, date.year + 1980);
};
fn format_dos_time(DOSTime time, str format_string = "{:02}:{:02}:{:02}") {
return std::format(format_string, time.hours, time.minutes, time.seconds * 2);
};
}

31
includes/type/base.pat Normal file
View File

@@ -0,0 +1,31 @@
#pragma once
#include <std/io.pat>
#include <std/math.pat>
namespace type {
using Hex<T> = T [[format("type::impl::format_hex")]];
using Oct<T> = T [[format("type::impl::format_oct")]];
using Dec<T> = T [[format("type::impl::format_dec")]];
using Bin<T> = T [[format("type::impl::format_bin")]];
namespace impl {
fn format_number(auto value, str fmt) {
bool negative = value < 0;
if (negative)
return std::format("-" + fmt, std::math::abs(value));
else
return std::format(fmt, value);
};
fn format_hex(auto value) { return type::impl::format_number(value, "0x{:02X}"); };
fn format_oct(auto value) { return type::impl::format_number(value, "0o{:03o}"); };
fn format_dec(auto value) { return type::impl::format_number(value, "{}"); };
fn format_bin(auto value) { return type::impl::format_number(value, "0b{:08b}"); };
}
}

29
includes/type/bcd.pat Normal file
View File

@@ -0,0 +1,29 @@
#pragma once
#include <std/io.pat>
namespace type {
struct BCD<auto Digits> {
u8 bytes[Digits];
} [[sealed, format_read("type::impl::format_bcd")]];
namespace impl {
fn format_bcd(ref auto bcd) {
str result;
for (u32 i = 0, i < sizeof(bcd.bytes), i += 1) {
u8 byte = bcd.bytes[i];
if (byte >= 10)
return "Invalid";
result += std::format("{}", byte);
}
return result;
};
}
}

48
includes/type/color.pat Normal file
View File

@@ -0,0 +1,48 @@
#pragma once
#include <std/io.pat>
#include <std/core.pat>
namespace type {
struct RGB8 {
u8 r, g, b;
} [[sealed, format("type::impl::format_color")]];
struct RGBA8 {
u8 r, g, b, a;
} [[sealed, format("type::impl::format_color")]];
bitfield RGB565 {
r : 5;
g : 6;
b : 5;
} [[sealed, format("type::impl::format_color")]];
bitfield RGBA4 {
r : 4;
g : 4;
b : 4;
a : 4;
} [[sealed, format("type::impl::format_color")]];
namespace impl {
fn format_color(ref auto color) {
if (!std::core::has_member(color, "a")) {
return std::format("#{0:02X}{1:02X}{2:02X} | rgb({0}, {1}, {2})",
color.r,
color.g,
color.b);
} else {
return std::format("#{0:02X}{1:02X}{2:02X}{3:02X} | rgba({0}, {1}, {2}, {3})",
color.r,
color.g,
color.b,
color.a);
}
};
}
}

View File

@@ -2,28 +2,52 @@
#include <std/io.pat>
#include <std/math.pat>
#include <std/mem.pat>
namespace type {
using float16 = u16 [[format("type::impl::format_float16")]];
namespace impl {
fn format_float16(float16 value) {
float sign = (value >> 15) == 0b01 ? -1.0 : 1.0;
float exponent = std::math::pow(2.0, float((value >> 10) & 0x1F) - 14);
u16 mantissa = value & 0x3FF;
float fraction = 0;
for (s8 i = 9, i >= 0, i -= 1) {
if ((mantissa & (1 << i)) != 0) {
fraction += 1.0 / std::math::pow(2.0, (10.0 - i));
}
}
return std::format("{:f}", sign * exponent * fraction);
namespace impl {
union U32ToFloatConverter {
u32 intValue;
float floatValue;
};
}
fn format_float16(float16 value) {
u32 sign = value >> 15;
u32 exponent = (value >> 10) & 0x1F;
u32 mantissa = value & 0x3FF;
u32 result = 0x00;
if (exponent == 0) {
if (mantissa == 0) {
result = sign << 31;
} else {
exponent = 0x7F - 14;
while ((mantissa & (1 << 10)) == 0) {
exponent -= 1;
mantissa <<= 1;
}
mantissa &= 0x3FF;
result = (sign << 31) | (exponent << 23) | (mantissa << 13);
}
} else if (exponent == 0x1F) {
result = (sign << 31) | (0xFF << 23) | (mantissa << 13);
} else {
result = (sign << 31) | ((exponent + (0x7F - 15)) << 23) | (mantissa << 13);
}
std::mem::Reinterpreter<u32, float> converter;
converter.from = result;
return std::format("{}", converter.to);
};
}
}
}

View File

@@ -4,36 +4,53 @@
namespace type {
struct IPv4Address {
u8 bytes[4];
} [[sealed, format("type::impl::format_ipv4_address")]];
struct IPv4Address {
u8 bytes[4];
} [[sealed, format("type::impl::format_ipv4_address")]];
struct IPv6Address {
u16 words[8];
} [[sealed, format("type::impl::format_ipv6_address")]];
namespace impl {
fn format_ipv4_address(IPv4Address address) {
return std::format("{}.{}.{}.{}",
address.bytes[0],
address.bytes[1],
address.bytes[2],
address.bytes[3]);
};
u16 words[8];
} [[sealed, format("type::impl::format_ipv6_address")]];
namespace impl {
fn format_ipv4_address(IPv4Address address) {
return std::format("{}.{}.{}.{}",
address.bytes[0],
address.bytes[1],
address.bytes[2],
address.bytes[3]);
};
fn format_ipv6_address(IPv6Address address) {
return std::format("{:04X}:{:04X}:{:04X}:{:04X}:{:04X}:{:04X}:{:04X}:{:04X}",
address.words[0],
address.words[1],
address.words[2],
address.words[3],
address.words[4],
address.words[5],
address.words[6],
address.words[7]);
};
}
str result;
bool hadZeros = false;
s8 startIndex = -1;
for (u8 i = 0, i < 8, i += 1) {
if (address.words[i] == 0x00 && !hadZeros) {
hadZeros = true;
startIndex = i;
while (i < 7) {
if (address.words[i + 1] != 0x00)
break;
i += 1;
}
if (startIndex == 0 || i == 7)
result += ":";
} else {
result += std::format("{:04X}", address.words[i]);
}
result += ":";
}
return std::string::substr(result, 0, std::string::length(result) - 1);
};
}
}
}

33
includes/type/leb128.pat Normal file
View File

@@ -0,0 +1,33 @@
#pragma once
#include <std/io.pat>
#include <std/mem.pat>
namespace type {
struct LEB128 {
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")]];
namespace impl {
fn transform_leb128_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;
}
return res;
};
fn format_leb128(auto leb128) {
u128 res = type::impl::transform_leb128_array(leb128.array);
return std::format("{} ({:#x})", res, res);
};
fn transform_leb128(auto leb128) {
return type::impl::transform_leb128_array(leb128.array);
};
}
}

19
includes/type/magic.pat Normal file
View File

@@ -0,0 +1,19 @@
#include <std/string.pat>
#include <std/sys.pat>
namespace type {
struct Magic<auto ExpectedValue> {
char value[std::string::length(ExpectedValue)];
std::assert(value == ExpectedValue, std::format("Invalid magic value! Expected \"{}\", got \"{}\".", ExpectedValue, value));
} [[sealed, format("type::impl::format_magic")]];
namespace impl {
fn format_magic(ref auto magic) {
return magic.value;
};
}
}

32
includes/type/path.pat Normal file
View File

@@ -0,0 +1,32 @@
#include <std/mem.pat>
namespace type {
struct UnixPathSegment {
char string[while(std::mem::read_unsigned($, 1) != '/' && std::mem::read_unsigned($, 1) != 0x00)];
char separator [[hidden]];
if (separator == 0x00) {
$ -= 1;
break;
}
} [[sealed, format("type::impl::format_unix_path_segment")]];
struct UnixPath {
UnixPathSegment segments[while(true)];
} [[format("type::impl::format_unix_path")]];
namespace impl {
fn format_unix_path_segment(UnixPathSegment segment) {
return segment.string;
};
fn format_unix_path(UnixPath path) {
return std::mem::read_string($, sizeof(path));
};
}
}

49
includes/type/size.pat Normal file
View File

@@ -0,0 +1,49 @@
#include <std/io.pat>
namespace type {
using Size<T> = T [[format("type::impl::size_formatter")]];
using Size8 = Size<u8>;
using Size16 = Size<u16>;
using Size32 = Size<u32>;
using Size64 = Size<u64>;
using Size128 = Size<u128>;
namespace impl {
fn size_formatter(u128 size) {
double sizeFloat = size;
u32 i = 0;
while (sizeFloat >= 1024 && i <= 6) {
i += 1;
sizeFloat /= 1024;
}
if (i == 0) {
if (size == 1)
return std::format("{} Byte", size);
else
return std::format("{} Bytes", size);
} else {
str result = std::format("{:.3f} ", sizeFloat);
if (i == 1)
return result + "kiB";
else if (i == 2)
return result + "MiB";
else if (i == 3)
return result + "GiB";
else if (i == 4)
return result + "TiB";
else if (i == 5)
return result + "PiB";
else
return result + "EiB";
}
};
}
}

View File

@@ -4,15 +4,26 @@
#include <std/time.pat>
namespace type {
using time_t = u16 [[format("type::impl::format_time_t")]];
namespace impl {
using time32_t = u32 [[format("type::impl::format_time_t")]];
using time64_t = u64 [[format("type::impl::format_time_t")]];
using dosdate16_t = u16 [[format("type::impl::format_dosdate16_t")]];
using dostime16_t = u16 [[format("type::impl::format_dostime16_t")]];
fn format_time_t(time_t value) {
namespace impl {
fn format_time_t(u128 value) {
return std::time::format(std::time::to_utc(value));
};
}
fn format_dosdate16_t(u16 value) {
return std::time::format_dos_date(std::time::to_dos_date(value));
};
}
fn format_dostime16_t(u16 value) {
return std::time::format_dos_time(std::time::to_dos_time(value));
};
}
}

View File

@@ -0,0 +1,62 @@
#pragma once
// Explicitly don't add these types to the `type` namespace for usability
// namespace type {
// using char = s8;
using byte = s8;
using CHAR = s8;
using BYTE = s8;
using uchar = u8;
using ubyte = u8;
using UCHAR = u8;
using UBYTE = u8;
using short = s16;
using int16 = s16;
using SHORT = s16;
using INT16 = s16;
using ushort = u16;
using uint16 = u16;
using USHORT = u16;
using UINT16 = u16;
using WORD = u16;
using int = s32;
using int32 = s32;
using long = s32;
using INT = s32;
using INT32 = s32;
using LONG = s32;
using uint = u32;
using uint32 = u32;
using ulong = u32;
using UINT = u32;
using UINT32 = u32;
using ULONG = u32;
using DWORD = u32;
using int64 = s64;
using quad = s64;
using QUAD = s64;
using INT64 = s64;
using __int64 = s64;
using uint64 = u64;
using uquad = u64;
using UQUAD = u64;
using UINT64 = u64;
using QWORD = u64;
using __uint64 = u64;
// using float = float;
using FLOAT = float;
// using double = double;
using DOUBLE = double;
// }

39
includes/type/types/c.pat Normal file
View File

@@ -0,0 +1,39 @@
#pragma once
// Explicitly don't add these types to the `type` namespace for usability
// namespace type {
using uint8_t = u8;
using uint16_t = u16;
using uint32_t = u32;
using uint64_t = u64;
using __uint64_t = u64;
using uint128_t = u128;
using __uint128_t = u128;
using int8_t = s8;
using int16_t = s16;
using int32_t = s32;
using int64_t = s64;
using __int64_t = s64;
using int128_t = s128;
using __int128_t = s128;
using size_t = u64;
using ssize_t = s64;
using uintptr_t = u64;
using intptr_t = s64;
using ptrdiff_t = s64;
// using char = char;
using wchar_t = char16;
using char8_t = char;
using char16_t = char16;
using char32_t = u32;
using short = s16;
using int = s32;
using long = s32;
// }

View File

@@ -0,0 +1,13 @@
#pragma once
// Explicitly don't add these types to the `type` namespace for usability
// namespace type {
using le16 = le u16;
using be16 = be u16;
using le32 = le u32;
using be32 = be u32;
using le64 = le u64;
using be64 = be u64;
// }

View File

@@ -0,0 +1,24 @@
#pragma once
// Explicitly don't add these types to the `type` namespace for usability
// namespace type {
// using u8 = u8;
// using u16 = u16;
// using u32 = u32;
// using u64 = u64;
// using u128 = u128;
using i8 = s8;
using i16 = s16;
using i32 = s32;
using i64 = s64;
using i128 = s128;
using f32 = float;
using f64 = double;
using usize = u64;
using isize = i64;
// }

View File

@@ -0,0 +1,53 @@
#pragma once
// Explicitly don't add these types to the `type` namespace for usability
// namespace type {
using BYTE = u8;
using WORD = u16;
using DWORD = u32;
using QWORD = u64;
using DWORDLONG = u64;
using DWORD32 = u32;
using DWORD64 = u64;
using INT = s32;
using UINT = u32;
using FLOAT = float;
using SHORT = s16;
using USHORT = u16;
using BOOL = bool;
using BOOLEAN = bool;
using INT8 = s8;
using INT16 = s16;
using INT32 = s32;
using INT64 = s64;
using UINT8 = u8;
using UINT16 = u16;
using UINT32 = u32;
using UINT64 = u64;
using LONG = s32;
using ULONG = u32;
using LONG32 = s32;
using ULONG32 = u32;
using LONG64 = s64;
using ULONG64 = u64;
using LONGLONG = s64;
using ULONGLONG = u64;
using SIZE_T = u64;
using SSIZE_T = s64;
using UCHAR = u8;
using CHAR = char;
using CCHAR = char;
using ATOM = WORD;
using PVOID = SIZE_T;
using HANDLE = PVOID;
using HINSTANCE = HANDLE;
using HRESULT = LONG;
// }

73
patterns/bencode.hexpat Normal file
View File

@@ -0,0 +1,73 @@
#pragma MIME application/x-bittorrent
#include <std/ctype.pat>
#include <std/mem.pat>
#include <std/string.pat>
namespace bencode {
struct ASCIIDecimal {
char value[while(std::ctype::isdigit(std::mem::read_unsigned($, 1)))];
} [[sealed, format("bencode::format_ascii_decimal"), transform("bencode::format_ascii_decimal")]];
fn format_ascii_decimal(ASCIIDecimal adsasd) {
return std::string::parse_int(adsasd.value, 10);
};
enum Type : u8 {
Integer = 'i',
Dictionary = 'd',
List = 'l',
String0 = '0',
String1 = '1',
String2 = '2',
String3 = '3',
String4 = '4',
String5 = '5',
String6 = '6',
String7 = '7',
String8 = '8',
String9 = '9'
};
struct String {
ASCIIDecimal length;
char separator [[hidden]];
char value[length];
} [[sealed, format("bencode::format_string"), transform("bencode::format_string")]];
fn format_string(String string) {
return string.value;
};
using Bencode;
using Value;
struct DictionaryEntry {
String key;
Value value;
};
struct Value {
Type type;
if (type == Type::Dictionary) {
DictionaryEntry entry[while(std::mem::read_unsigned($, 1) != 'e')];
} else if (type == Type::Integer) {
ASCIIDecimal value;
char end;
} else {
$ -= 1;
String value;
}
};
struct Bencode {
Value value[while(!std::mem::eof())] [[inline]];
char end;
};
}
bencode::Bencode bencode @ 0x00;

128
patterns/bson.hexpat Normal file
View File

@@ -0,0 +1,128 @@
#pragma MIME application/bson
#include <type/time.pat>
enum Type : u8 {
Double = 0x01,
String = 0x02,
EmbeddedDocument = 0x03,
Array = 0x04,
Binary = 0x05,
Undefined = 0x06,
ObjectId = 0x07,
Boolean = 0x08,
UTCDatetime = 0x09,
Null = 0x0A,
Regex = 0x0B,
DBPointer = 0x0C,
JavaScript = 0x0D,
Symbol = 0x0E,
JavaScriptWithScope = 0x0F,
Int32 = 0x10,
Timestamp = 0x11,
Int64 = 0x12,
Decimal128 = 0x13,
MinKey = 0xFF,
MaxKey = 0x7F
};
enum Subtype : u8 {
GenericBinarySubtype = 0x00,
Function = 0x01,
BinaryOld = 0x02,
UUIDOld = 0x03,
UUID = 0x04,
MD5 = 0x05,
EncryptedBSONValue = 0x06,
CompressedBSONColumn = 0x07,
UserDefined = 0x80
};
struct Binary {
s32 length;
Subtype subtype;
u8 data[length];
};
struct String {
u32 length [[hidden]];
char value[length];
} [[sealed, format("format_string")]];
struct CString {
char value[];
} [[sealed, format("format_string")]];
fn format_string(auto string) {
return string.value;
};
struct ObjectId {
type::time32_t timestamp;
u8 randomValue[5];
u24 counter;
};
struct DBPointer {
String name;
ObjectId value;
};
using Document;
struct Element {
Type type;
CString name;
if (type == Type::Double) {
double value;
} else if (type == Type::String) {
String value;
} else if (type == Type::EmbeddedDocument) {
Document value;
} else if (type == Type::Array) {
Document value;
} else if (type == Type::Binary) {
Binary value;
} else if (type == Type::Undefined) {
/* undefined */
} else if (type == Type::ObjectId) {
ObjectId value;
} else if (type == Type::Boolean) {
bool value;
} else if (type == Type::UTCDatetime) {
type::time64_t value;
} else if (type == Type::Null) {
/* null */
} else if (type == Type::Regex) {
CString regexPattern;
CString regexOptions;
} else if (type == Type::DBPointer) {
DBPointer value;
} else if (type == Type::JavaScript) {
String value;
} else if (type == Type::Symbol) {
String value;
} else if (type == Type::JavaScriptWithScope) {
String value;
} else if (type == Type::Int32) {
s32 value;
} else if (type == Type::Timestamp) {
u64 value;
} else if (type == Type::Int64) {
s64 value;
} else if (type == Type::Decimal128) {
u128 value;
}
};
struct Document {
s32 listLength;
Element elements[while($ < ((addressof(this) + listLength) - 1))];
padding[1];
};
Document document @ 0x00;

395
patterns/chm.hexpat Normal file
View 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
View File

@@ -0,0 +1,209 @@
#pragma MIME application/x-coff
#include <type/time.pat>
#include <type/size.pat>
enum Machine : u16 {
Unknown = 0x0000,
AM33 = 0x01D3,
AMD64 = 0x8664,
ARM = 0x01C0,
ARM64 = 0xAA64,
ARMNT = 0x01C4,
EBC = 0x0EBC,
I386 = 0x014C,
IA64 = 0x0200,
LOONGARCH32 = 0x6232,
LOONGARCH64 = 0x6264,
M32R = 0x9041,
MIPS16 = 0x0226,
MIPSFPU = 0x0366,
MIPSFPU16 = 0x0466,
POWERPC = 0x01F0,
POWERPCFP = 0x01F0,
R4000 = 0x0166,
RISCV32 = 0x5032,
RISCV64 = 0x5064,
RISCV128 = 0x5128,
SH3 = 0x01A2,
SH3DSP = 0x01A3,
SH4 = 0x01A6,
SH5 = 0x01A8,
THUMB = 0x01C2,
WCEMIPSV2 = 0x0169
};
bitfield Characteristics {
relocsStripped : 1;
executableImage : 1;
lineNumsStripped : 1;
localSymsStripped : 1;
aggressiveWsTrim : 1;
largeAddressAware : 1;
padding : 1;
bytesReversedLo : 1;
_32BitMachine : 1;
debugStripped : 1;
removableRunFromSwap : 1;
netRunFromSwap : 1;
system : 1;
dll : 1;
upSystemOnly : 1;
bytesReversedHi : 1;
} [[right_to_left]];
enum Type : u16 {
Null = 0,
Void = 1,
Char = 2,
Short = 3,
Int = 4,
Long = 5,
Float = 6,
Double = 7,
Struct = 8,
Union = 9,
Enum = 10,
MOE = 11,
Byte = 12,
Word = 13,
UInt = 14,
DWord = 15
};
enum StorageClass : u8 {
EndOfFunction = 0xFF,
Null = 0,
Automatic = 1,
External = 2,
Static = 3,
Register = 4,
ExternalDef = 5,
Label = 6,
UndefinedLabel = 7,
MemberOfStruct = 8,
Argument = 9,
StructTag = 10,
MemberOfUnion = 11,
UnionTag = 12,
TypeDefinition = 13,
UndefinedStatic = 14,
EnumTag = 15,
MemberOfEnum = 16,
RegisterParam = 17,
BitField = 18,
Block = 100,
Function = 101,
EndOfStruct = 102,
File = 103,
Section = 104,
WeakExternal = 105,
CLRToken = 107
};
struct AuxSymbol {
u8 data[18];
};
u32 countedSymbols = 0;
struct SymbolTable {
char name[8];
u32 value;
u16 sectionNumber;
Type type;
StorageClass storageClass;
u8 numberOfAuxSymbols;
countedSymbols += 1 + numberOfAuxSymbols;
AuxSymbol auxSymbols[numberOfAuxSymbols];
if (countedSymbols >= parent.header.numberOfSymbols)
break;
};
struct String {
char value[];
};
struct StringTable {
u32 size;
String strings[while($ < addressof(size) + size)];
};
bitfield SectionFlags {
padding : 3;
typeNoPad : 1;
padding : 1;
cntCode : 1;
initializedData : 1;
uninitializedData : 1;
lnkOther : 1;
lnkInfo : 1;
padding : 1;
lnkRemove : 1;
lnkCOMDAT : 1;
padding : 2;
gprel : 1;
padding : 1;
memPurgeable : 1;
memLocked : 1;
memPreload : 1;
alignment : 4 [[format("format_alignment")]];
lnkNrelocOvfl : 1;
memDiscardable : 1;
memNotCached : 1;
memNotPaged : 1;
memShared : 1;
memExecute : 1;
memRead : 1;
memWrite : 1;
} [[right_to_left]];
fn format_alignment(u8 alignment) {
return 1 << alignment;
};
struct Relocations {
u32 virtualAddress;
u32 symbolTableIndex;
Type type;
};
struct Section {
char name[8];
type::Size<u32> virtualSize;
u32 virtualAddress;
type::Size<u32> sizeOfRawData;
u32 pointerToRawData;
u32 pointerToRelocations;
u32 pointerToLineNumbers;
u16 numberOfRelocations;
u16 numberOfLineNumbers;
SectionFlags characteristics;
u8 rawData[sizeOfRawData] @ pointerToRawData [[sealed]];
Relocations relocations[numberOfRelocations] @ pointerToRelocations;
};
struct Header {
Machine machine;
u16 numberOfSections;
type::time32_t timeDateStamp;
u32 pointerToSymbolTable;
u32 numberOfSymbols;
u16 sizeOfOptionalHeader;
Characteristics characteristics;
};
struct COFF {
Header header;
Section sectionTable[header.numberOfSections];
SymbolTable symbolTable[header.numberOfSymbols] @ header.pointerToSymbolTable;
StringTable stringTable @ addressof(symbolTable) + sizeof(symbolTable);
};
COFF coff @ 0x00;

66
patterns/cpio.pat Normal file
View File

@@ -0,0 +1,66 @@
#include <type/base.pat>
#include <std/time.pat>
#include <std/core.pat>
#include <std/sys.pat>
#include <std/mem.pat>
#pragma MIME application/x-cpio
namespace old_binary {
using Time = u32 [[format("old_binary::format_time")]];
fn swap_32bit(u32 value) {
return ((value >> 16) & 0xFFFF) | ((value & 0xFFFF) << 16);
};
fn format_time(u32 value) {
return std::time::format(std::time::to_utc(swap_32bit(value)));
};
using SwappedU32 = u32 [[transform("old_binary::swap_32bit"), format("old_binary::swap_32bit")]];
bitfield Mode {
file_type : 4;
suid : 1;
sgid : 1;
sticky : 1;
r : 3;
w : 3;
x : 3;
} [[left_to_right]];
struct CpioHeader {
type::Oct<u16> magic;
if (magic == be u16(0o070707))
std::core::set_endian(std::mem::Endian::Big);
else if (magic == le u16(0o070707))
std::core::set_endian(std::mem::Endian::Little);
else
std::error("Invalid CPIO Magic!");
u16 dev;
u16 ino;
Mode mode;
u16 uid;
u16 gid;
u16 nlink;
u16 rdev;
Time mtime;
u16 namesize;
SwappedU32 filesize;
};
struct Cpio {
CpioHeader header;
char pathname[header.namesize % 2 == 0 ? header.namesize : header.namesize + 1];
u8 data[header.filesize % 2 == 0 ? header.filesize : header.filesize + 1];
if (pathname == "TRAILER!!!\x00\x00")
break;
};
}
old_binary::Cpio cpio[while(true)] @ 0x00;

View File

@@ -1,261 +1,744 @@
#pragma MIME application/x-executable
#pragma MIME application/x-elf
#pragma MIME application/x-coredump
#pragma MIME application/x-object
#pragma MIME application/x-sharedlib
namespace elf {
#include <std/core.pat>
#include <std/mem.pat>
enum Class : u8 {
_32Bit = 1,
_64Bit = 2
};
enum Endian : u8 {
Little = 1,
Big = 2
};
enum OSABI : u8 {
SystemV = 0x00,
HP_UX = 0x01,
NetBSD = 0x02,
Linux = 0x03,
GNU_Hurd = 0x04,
Solaris = 0x06,
AIX = 0x07,
IRIX = 0x08,
FreeBSD = 0x09,
Tru64 = 0x0A,
NovellModesto = 0x0B,
OpenBSD = 0x0C,
OpenVMS = 0x0D,
NonStop_Kernel = 0x0E,
AROS = 0x0F,
FenixOS = 0x10,
CloudABI = 0x11,
Stratus_Technologies_OpenVOS = 0x12
};
enum Type : u16 {
using EI_ABIVERSION = u8;
using Elf32_Addr = u32;
using Elf32_BaseAddr = u32;
using Elf32_BaseOff = u32;
using Elf32_Half = u16;
using Elf32_Off = u32;
using Elf32_Sword = s32;
using Elf32_VAddr = u32;
using Elf32_Word = u32;
using Elf64_Addr = u64;
using Elf64_BaseAddr = u64;
using Elf64_BaseOff = u64;
using Elf64_Half = u16;
using Elf64_Off = u64;
using Elf64_Sword = s32;
using Elf64_Sxword = s64;
using Elf64_VAddr = u64;
using Elf64_Word = u32;
using Elf64_Xword = u64;
using E_VERSION = u32;
enum EI_CLASS : u8 {
ELFCLASSNONE = 0x00,
ELFCLASS32 = 0x01,
ELFCLASS64 = 0x02,
};
enum EI_DATA : u8 {
ELFDATANONE = 0x00,
ELFDATA2LSB = 0x01,
ELFDATA2MSB = 0x02,
};
enum EI_OSABI : u8 {
SYSV = 0x00,
HPUX = 0x01,
NetBSD = 0x02,
Linux = 0x03,
GNUHurd = 0x04,
Solaris = 0x06,
AIX = 0x07,
IRIX = 0x08,
FreeBSD = 0x09,
Tru64 = 0x0A,
NovellModesto = 0x0B,
OpenBSD = 0x0C,
OpenVMS = 0x0D,
NonStopKernel = 0x0E,
AROS = 0x0F,
FenixOS = 0x10,
CloudABI = 0x11,
OpenVOS = 0x12,
ARM_EABI = 0x40,
STANDALONE = 0xFF,
};
enum EI_VERSION : u8 {
NONE = 0x00,
REL = 0x01,
EXEC = 0x02,
DYN = 0x03,
CORE = 0x04,
LOOS = 0xFE00,
HIOS = 0xFEFF,
LOPROC = 0xFF00,
HIPROC = 0xFFFF
};
enum Machine : u16 {
Undefined = 0x00,
ATNT_WE_32100 = 0x01,
SPARC = 0x02,
x86 = 0x03,
Motorola_68000 = 0x04,
Motorola_88000 = 0x05,
IntelMCU = 0x06,
Intel_80860 = 0x07,
MIPS = 0x08,
IBM_System370 = 0x09,
MIPS_RS300_LE = 0x0A,
/* 0x0B - 0x0D: Reserved */
HP_PA_RISC = 0x0E,
/* 0x0F: Reserved */
Intel_80960 = 0x13,
PowerPC = 0x14,
PowerPC_64 = 0x15,
S390 = 0x16,
IBM_SPU_SPC = 0x17,
/* 0x18 - 0x23: Reserved */
NEC_V800 = 0x24,
Fujitsu_FR20 = 0x25,
TRW_RH_32 = 0x26,
Motorola_RCE = 0x27,
ARM32 = 0x28,
Digital_Alpha = 0x29,
SuperH = 0x2A,
SPARCv9 = 0x2B,
Siemens_TriCore = 0x2C,
Argonaut_RISC_Core = 0x2D,
Hitachi_H8_300 = 0x2E,
Hitachi_H8_300H = 0x2F,
Hitachi_H8S = 0x30,
Hitachi_H8_500 = 0x31,
IA_64 = 0x32,
Standford_MIPS_X = 0x33,
Motorola_ColdFire = 0x34,
Motorola_M68HC12 = 0x35,
Fujitsu_MMA = 0x36,
Siemens_PCP = 0x37,
Sony_nCPU = 0x38,
Denso_NDR1 = 0x39,
Motorola_StarCore = 0x3A,
Toyota_ME16 = 0x3B,
STMicroelectronics_ST100 = 0x3C,
Advanced_Logic_Corp_TinyJ = 0x3D,
AMD_x86_64 = 0x3E,
TMS320C6000 = 0x8C,
MCST_Elbrus_e2k = 0xAF,
ARM64 = 0xB7,
RISC_V = 0xF3,
Berkeley_Packet_Filter = 0xF7,
WDC_65C816 = 0x101
};
struct Identity {
char magic[4];
Class class;
Endian endian;
u8 version;
OSABI os_abi;
if (os_abi == elf::OSABI::Linux)
u8 dynamic_linker_version;
else
u8 abi_version;
};
CURRENT = 0x01,
};
struct Header {
Identity identity;
enum EM : u16 {
EM_NONE = 0x0000,
EM_M32 = 0x0001,
EM_SPARC = 0x0002,
EM_386 = 0x0003,
EM_68K = 0x0004,
EM_88K = 0x0005,
EM_IAMCU = 0x0006,
EM_860 = 0x0007,
EM_MIPS = 0x0008,
EM_S370 = 0x0009,
EM_MIPS_RS4_BE = 0x000a,
EM_PARISC = 0x000f,
EM_VPP500 = 0x0011,
EM_SPARC32PLUS = 0x0012,
EM_960 = 0x0013,
EM_PPC = 0x0014,
EM_PPC64 = 0x0015,
EM_S390 = 0x0016,
EM_SPU = 0x0017,
EM_V800 = 0x0024,
EM_FR20 = 0x0025,
EM_RH32 = 0x0026,
EM_RCE = 0x0027,
EM_ARM = 0x0028,
EM_ALPHA = 0x0029,
EM_SH = 0x002A,
EM_SPARCV9 = 0x002B,
EM_TRICORE = 0x002C,
EM_ARC = 0x002D,
EM_H8_300 = 0x002E,
EM_H8_300H = 0x002F,
EM_H8S = 0x0030,
EM_H8_500 = 0x0031,
EM_IA_64 = 0x0032,
EM_MIPS_X = 0x0033,
EM_COLDFIRE = 0x0034,
EM_68HC12 = 0x0035,
EM_MMA = 0x0036,
EM_PCP = 0x0037,
EM_NCPU = 0x0038,
EM_NDR1 = 0x0039,
EM_STARCORE = 0x003A,
EM_ME16 = 0x003B,
EM_ST100 = 0x003C,
EM_TINYJ = 0x003D,
EM_X86_64 = 0x003E,
EM_PDSP = 0x003F,
EM_PDP10 = 0x0040,
EM_PDP11 = 0x0041,
EM_FX66 = 0x0042,
EM_ST9PLUS = 0x0043,
EM_ST7 = 0x0044,
EM_68HC16 = 0x0045,
EM_68HC11 = 0x0046,
EM_68HC08 = 0x0047,
EM_68HC05 = 0x0048,
EM_SVX = 0x0049,
EM_ST19 = 0x004A,
EM_VAX = 0x004B,
EM_CRIS = 0x004C,
EM_JAVELIN = 0x004D,
EM_FIREPATH = 0x004E,
EM_ZSP = 0x004F,
EM_MMIX = 0x0050,
EM_HUANY = 0x0051,
EM_PRISM = 0x0052,
EM_AVR = 0x0053,
EM_FR30 = 0x0054,
EM_D10V = 0x0055,
EM_D30V = 0x0056,
EM_V850 = 0x0057,
EM_M32R = 0x0058,
EM_MN10300 = 0x0059,
EM_MN10200 = 0x005A,
EM_PJ = 0x005B,
EM_OPENRISC = 0x005C,
EM_ARC_COMPACT = 0x005D,
EM_XTENSA = 0x005E,
EM_VIDEOCORE = 0x005F,
EM_TMM_GPP = 0x0060,
EM_NS32K = 0x0061,
EM_TPC = 0x0062,
EM_SNP1K = 0x0063,
EM_ST200 = 0x0064,
EM_IP2K = 0x0065,
EM_MAX = 0x0066,
EM_CR = 0x0067,
EM_F2MC16 = 0x0068,
EM_MSP430 = 0x0069,
EM_BLACKFIN = 0x006A,
EM_SE_C33 = 0x006B,
EM_SEP = 0x006C,
EM_ARCA = 0x006D,
EM_UNICORE = 0x006E,
EM_EXCESS = 0x006F,
EM_DXP = 0x0070,
EM_ALTERA_NIOS2 = 0x0071,
EM_CRX = 0x0072,
EM_XGATE = 0x0073,
EM_C166 = 0x0074,
EM_M16C = 0x0075,
EM_DSPIC30F = 0x0076,
EM_CE = 0x0077,
EM_M32C = 0x0078,
EM_TSK3000 = 0x0083,
EM_RS08 = 0x0084,
EM_SHARC = 0x0085,
EM_ECOG2 = 0x0086,
EM_SCORE7 = 0x0087,
EM_DSP24 = 0x0088,
EM_VIDEOCORE3 = 0x0089,
EM_LATTICEMICO32 = 0x008A,
EM_SE_C17 = 0x008B,
EM_TI_C6000 = 0x008C,
EM_TI_C2000 = 0x008D,
EM_TI_C5500 = 0x008E,
EM_TI_ARP32 = 0x008F,
EM_TI_PRU = 0x0090,
EM_MMDSP_PLUS = 0x00A0,
EM_CYPRESS_M8C = 0x00A1,
EM_R32C = 0x00A2,
EM_TRIMEDIA = 0x00A3,
EM_QDSP6 = 0x00A4,
EM_8051 = 0x00A5,
EM_STXP7X = 0x00A6,
EM_NDS32 = 0x00A7,
EM_ECOG1 = 0x00A8,
EM_ECOG1X = 0x00A8,
EM_MAXQ30 = 0x00A9,
EM_XIMO16 = 0x00AA,
EM_MANIK = 0x00AB,
EM_CRAYNV2 = 0x00AC,
EM_RX = 0x00AD,
EM_METAG = 0x00AE,
EM_MCST_ELBRUS = 0x00AF,
EM_ECOG16 = 0x00B0,
EM_CR16 = 0x00B1,
EM_ETPU = 0x00B2,
EM_SLE9X = 0x00B3,
EM_L10M = 0x00B4,
EM_K10M = 0x00B5,
EM_AARCH64 = 0x00B7,
EM_AVR32 = 0x00B9,
EM_STM8 = 0x00BA,
EM_TILE64 = 0x00BB,
EM_TILEPRO = 0x00BC,
EM_MICROBLAZE = 0x00BD,
EM_CUDA = 0x00BE,
EM_TILEGX = 0x00BF,
EM_CLOUDSHIELD = 0x00C0,
EM_COREA_1ST = 0x00C1,
EM_COREA_2ND = 0x00C2,
EM_ARC_COMPACT2 = 0x00C3,
EM_OPEN8 = 0x00C4,
EM_RL78 = 0x00C5,
EM_VIDEOCORE5 = 0x00C6,
EM_78KOR = 0x00C7,
EM_56800EX = 0x00C8,
EM_BA1 = 0x00C9,
EM_BA2 = 0x00CA,
EM_XCORE = 0x00CB,
EM_MCHP_PIC = 0x00CC,
EM_INTEL205 = 0x00CD,
EM_INTEL206 = 0x00CE,
EM_INTEL207 = 0x00CF,
EM_INTEL208 = 0x00D0,
EM_INTEL209 = 0x00D1,
EM_KM32 = 0x00D2,
EM_KMX32 = 0x00D3,
EM_KMX16 = 0x00D4,
EM_KMX8 = 0x00D5,
EM_KVARC = 0x00D6,
EM_CDP = 0x00D7,
EM_COGE = 0x00D8,
EM_COOL = 0x00D9,
EM_NORC = 0x00DA,
EM_CSR_KALIMBA = 0x00DB,
EM_Z80 = 0x00DC,
EM_VISIUM = 0x00DD,
EM_FT32 = 0x00DE,
EM_MOXIE = 0x00DF,
EM_AMDGPU = 0x00E0,
EM_RISCV = 0x00F3,
};
enum ET : u16 {
NONE = 0x0000,
REL = 0x0001,
EXEC = 0x0002,
DYN = 0x0003,
CORE = 0x0004,
};
enum DT : u32 {
DT_NULL = 0x0,
DT_NEEDED = 0x1,
DT_PLTRELSZ = 0x2,
DT_PLTGOT = 0x3,
DT_HASH = 0x4,
DT_STRTAB = 0x5,
DT_SYMTAB = 0x6,
DT_RELA = 0x7,
DT_RELASZ = 0x8,
DT_RELAENT = 0x9,
DT_STRSZ = 0xA,
DT_SYMENT = 0xB,
DT_INIT = 0xC,
DT_FINI = 0xD,
DT_SONAME = 0xE,
DT_RPATH = 0xF,
DT_SYMBOLIC = 0x10,
DT_REL = 0x11,
DT_RELSZ = 0x12,
DT_RELENT = 0x13,
DT_PLTREL = 0x14,
DT_DEBUG = 0x15,
DT_TEXTREL = 0x16,
DT_JMPREL = 0x17,
DT_BIND_NOW = 0x18,
DT_INIT_ARRAY = 0x19,
DT_FINI_ARRAY = 0x1A,
DT_INIT_ARRAYSZ = 0x1B,
DT_FINI_ARRAYSZ = 0x1C,
DT_RUNPATH = 0x1D,
DT_FLAGS = 0x1E,
DT_PREINIT_ARRAY = 0x20,
DT_PREINIT_ARRAYSZ = 0x21,
DT_MAXPOSTAGS = 0x22,
DT_NUM = 0x23,
DT_GNU_PRELINKED = 0x6FFFFDF5,
DT_GNU_CONFLICTSZ = 0x6FFFFDF6,
DT_GNU_LIBLISTSZ = 0x6FFFFDF7,
DT_CHECKSUM = 0x6FFFFDF8,
DT_PLTPADSZ = 0x6FFFFDF9,
DT_MOVEENT = 0x6FFFFDFA,
DT_MOVESZ = 0x6FFFFDFB,
DT_FEATURE_1 = 0x6FFFFDFC,
DT_POSFLAG_1 = 0x6FFFFDFD,
DT_SYMINSZ = 0x6FFFFDFE,
DT_SYMINENT = 0x6FFFFDFF,
DT_GNU_HASH = 0x6FFFFEF5,
DT_TLSDESC_PLT = 0x6FFFFEF6,
DT_TLSDESC_GOT = 0x6FFFFEF7,
DT_GNU_CONFLICT = 0x6FFFFEF8,
DT_GNU_LIBLIST = 0x6FFFFEF9,
DT_CONFIG = 0x6FFFFEFA,
DT_DEPAUDIT = 0x6FFFFEFB,
DT_AUDIT = 0x6FFFFEFC,
DT_PLTPAD = 0x6FFFFEFD,
DT_MOVETAB = 0x6FFFFEFE,
DT_SYMINFO = 0x6FFFFEFF,
DT_VERSYM = 0x6FFFFFF0,
DT_RELACOUNT = 0x6FFFFFF9,
DT_RELCOUNT = 0x6FFFFFFA,
DT_FLAGS_1 = 0x6FFFFFFB,
DT_VERDEF = 0x6FFFFFFC,
DT_VERDEFNUM = 0x6FFFFFFD,
DT_VERNEED = 0x6FFFFFFE,
DT_VERNEEDNUM = 0x6FFFFFFF,
DT_AUXILIARY = 0x7FFFFFFD,
DT_USED = 0x7FFFFFFE,
DT_FILTER = 0x7FFFFFFF,
DT_DEPRECATED_SPARC_REGISTER = 0x7000001,
DT_SUNW_AUXILIARY = 0x6000000D,
DT_SUNW_RTLDINF = 0x6000000E,
DT_SUNW_FILTER = 0x6000000F,
DT_SUNW_CAP = 0x60000010,
DT_SUNW_SYMTAB = 0x60000011,
DT_SUNW_SYMSZ = 0x60000012,
DT_SUNW_SORTENT = 0x60000013,
DT_SUNW_SYMSORT = 0x60000014,
DT_SUNW_SYMSORTSZ = 0x60000015,
DT_SUNW_TLSSORT = 0x60000016,
DT_SUNW_TLSSORTSZ = 0x60000017,
DT_SUNW_STRPAD = 0x60000019,
DT_SUNW_LDMACH = 0x6000001B,
};
enum RT : Elf32_Word {
CONSISTENT = 0x00,
ADD = 0x01,
DELETE = 0x02,
};
enum PT : Elf32_Word {
NULL = 0x00,
LOAD = 0x01,
DYNAMIC = 0x02,
INTERP = 0x03,
NOTE = 0x04,
SHLIB = 0x05,
PHDR = 0x06,
TLS = 0x07,
LOOS = 0x60000000,
HIOS = 0x6FFFFFFF,
GNU_EH_FRAME = PT::LOOS + 0x474E550,
GNU_STACK = PT::LOOS + 0x474E551,
GNU_RELRO = PT::LOOS + 0x474E552,
GNU_PROPERTY = PT::LOOS + 0x474E553,
SUNWBSS = 0x6FFFFFFA,
SUNWSTACK = 0x6FFFFFFB,
ARM_ARCHEXT = 0x70000000,
ARM_UNWIND = 0x70000001,
};
enum ELFCOMPRESS : u8 {
ZLIB = 0x01,
};
enum SHN : u16 {
UNDEF = 0x00,
BEFORE = 0xFF00,
AFTER = 0xFF01,
ABS = 0xFFF1,
COMMON = 0xFFF2,
XINDEX = 0xFFFF,
};
enum SHT : Elf32_Word {
NULL = 0x00,
PROGBITS = 0x01,
SYMTAB = 0x02,
STRTAB = 0x03,
RELA = 0x04,
HASH = 0x05,
DYNAMIC = 0x06,
NOTE = 0x07,
NOBITS = 0x08,
REL = 0x09,
SHLIB = 0x0A,
DYNSYM = 0x0B,
UNKNOWN12 = 0x0C,
UNKNOWN13 = 0x0D,
INIT_ARRAY = 0x0E,
FINI_ARRAY = 0x0F,
PREINIT_ARRAY = 0x10,
GROUP = 0x11,
SYMTAB_SHNDX = 0x12,
GNU_INCREMENTAL_INPUTS = 0x6FFF4700,
GNU_ATTRIBUTES = 0x6FFFFFF5,
GNU_HASH = 0x6FFFFFF6,
GNU_LIBLIST = 0x6FFFFFF7,
CHECKSUM = 0x6FFFFFF8,
SUNW_move = 0x6FFFFFFA,
SUNW_COMDAT = 0x6FFFFFFB,
SUNW_syminfo = 0x6FFFFFFC,
GNU_verdef = 0x6FFFFFFD,
GNU_verneed = 0x6FFFFFFE,
GNU_versym = 0x6FFFFFFF,
ARM_EXIDX = 0x70000001,
ARM_PREEMPTMAP = 0x70000002,
ARM_ATTRIBUTES = 0x70000003,
ARM_DEBUGOVERLAY = 0x70000004,
ARM_OVERLAYSECTION = 0x70000005,
};
enum STV : u8 {
DEFAULT = 0x00,
INTERNAL = 0x01,
HIDDEN = 0x02,
PROTECTED = 0x03,
};
enum SYMINFO_BT : Elf32_Half {
SELF = 0xFFFF,
PARENT = 0xFFFE,
NONE = 0xFFFD,
};
enum VER_DEF : Elf32_Half {
NON = 0x00,
CURRENT = 0x01,
NUM = 0x02,
};
enum VER_NDX : Elf32_Half {
LOCAL = 0x00,
GLOBAL = 0x01,
ELIMINATE = 0xFF01,
};
enum VER_NEED : Elf32_Half {
NONE = 0x00,
CURRENT = 0x01,
NUM = 0x02,
};
bitfield SYMINFO_FLG {
padding : 10;
NOEXTDIRECT : 1;
DIRECTBIND : 1;
LAZYLOAD : 1;
COPY : 1;
RESERVED : 1;
DIRECT : 1;
} [[left_to_right]];
bitfield ST {
ST_BIND : 4;
ST_TYPE : 4;
} [[left_to_right]];
bitfield SHF {
MASKPROC : 4;
MASKOS : 8;
UNKNOWN : 8;
COMPRESSED : 1;
TLS : 1;
GROUP : 1;
OS_NONCONFORMING : 1;
LINK_ORDER : 1;
INFO_LINK : 1;
STRINGS : 1;
MERGE : 1;
padding : 1;
EXECINSTR : 1;
ALLOC : 1;
WRITE : 1;
} [[left_to_right]];
bitfield ELF32_R_INFO {
SYM : 8;
TYPE : 8;
} [[left_to_right]];
bitfield ELF64_R_INFO {
SYM : 32;
TYPE : 32;
} [[left_to_right]];
bitfield PF {
MASKPROC : 4;
MASKOS : 4;
padding : 17;
R : 1;
W : 1;
X : 1;
} [[left_to_right]];
struct E_IDENT {
char EI_MAG[4];
EI_CLASS EI_CLASS;
EI_DATA EI_DATA;
EI_VERSION EI_VERSION;
EI_OSABI EI_OSABI;
EI_ABIVERSION EI_ABIVERSION;
padding[7];
Type type;
Machine machine;
u32 version;
};
struct Elf32_Ehdr {
ET e_type;
EM e_machine;
E_VERSION e_version;
Elf32_VAddr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
};
struct Elf64_Ehdr {
ET e_type;
EM e_machine;
E_VERSION e_version;
Elf64_VAddr e_entry;
Elf64_Off e_phoff;
Elf64_Off e_shoff;
Elf64_Word e_flags;
Elf64_Half e_ehsize;
Elf64_Half e_phentsize;
Elf64_Half e_phnum;
Elf64_Half e_shentsize;
Elf64_Half e_shnum;
Elf64_Half e_shstrndx;
};
struct Elf32_Phdr {
PT p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
PF p_flags;
Elf32_Word p_align;
if (identity.class == elf::Class::_32Bit) {
u32 entry_point;
u32 program_header_offset;
u32 section_header_offset;
} else {
u64 entry_point;
u64 program_header_offset;
u64 section_header_offset;
if (p_offset > 0 && p_filesz > 0 && (p_offset + p_filesz) < std::mem::size() && p_filesz < std::mem::size())
u8 p_data[p_filesz] @ p_offset;
};
struct Elf64_Phdr {
PT p_type;
PF p_flags;
Elf64_Off p_offset;
Elf64_Addr p_vaddr;
Elf64_Addr p_paddr;
Elf64_Xword p_filesz;
Elf64_Xword p_memsz;
Elf64_Xword p_align;
if (p_offset > 0 && p_filesz > 0 && (p_offset + p_filesz) < std::mem::size() && p_filesz < std::mem::size())
u8 p_data[p_filesz] @ p_offset;
};
struct Elf32_Chdr {
u32 ch_type;
Elf32_Word ch_size;
Elf32_Word ch_addralign;
};
struct Elf32_Rel {
Elf32_Off r_offset;
ELF32_R_INFO r_info;
};
struct Elf32_Rela {
Elf32_Off r_offset;
ELF32_R_INFO r_info;
Elf32_Sword r_addend;
};
struct Elf32_Sym {
u32 st_name;
Elf32_VAddr st_value;
Elf32_Word st_size;
ST st_info;
STV st_other;
u16 st_shndx;
};
struct Elf32_Syminfo {
u16 si_boundto;
SYMINFO_FLG si_flags;
};
s64 stringTableIndex;
struct String {
char value[];
} [[sealed, format("format_string")]];
fn format_string(String string) {
return string.value;
};
struct Elf32_Shdr {
u32 sh_name;
SHT sh_type;
SHF sh_flags;
u32 sh_addr;
u32 sh_offset;
Elf32_Word sh_size;
Elf32_Word sh_link;
Elf32_Word sh_info;
Elf32_Word sh_addralign;
Elf32_Word sh_entsize;
if (sh_size > 0 && sh_offset + sh_size < std::mem::size()) {
if (sh_type == SHT::NOBITS || sh_type == SHT::NULL) {
// Section has no data
} else if (sh_type == SHT::STRTAB) {
String stringTable[while($ < (sh_offset + sh_size))] @ sh_offset;
stringTableIndex = std::core::array_index();
} else if (sh_type == SHT::DYNSYM) {
Elf32_Sym symbolTable[sh_size / sh_entsize] @ sh_offset;
} else if (sh_type == SHT::INIT_ARRAY || sh_type == SHT::FINI_ARRAY) {
u32 pointer[while($ < (sh_offset + sh_size))] @ sh_offset;
} else {
u8 data[sh_size] @ sh_offset;
}
}
} [[format("format_section_header")]];;
struct Elf64_Chdr {
u32 ch_type;
Elf64_Word ch_size;
Elf64_Word ch_addralign;
};
struct Elf64_Rel {
Elf64_Off r_offset;
ELF64_R_INFO r_info;
};
struct Elf64_Rela {
Elf64_Off r_offset;
ELF64_R_INFO r_info;
Elf64_Sxword r_addend;
};
struct Elf64_Sym {
u32 st_name;
ST st_info;
STV st_other;
u16 st_shndx;
Elf64_VAddr st_value;
Elf64_Xword st_size;
};
struct Elf64_Syminfo {
u16 si_boundto;
SYMINFO_FLG si_flags;
};
struct Elf64_Shdr {
u32 sh_name;
SHT sh_type;
SHF sh_flags;
padding[4];
u64 sh_addr;
u64 sh_offset;
Elf64_Xword sh_size;
Elf64_Word sh_link;
Elf64_Word sh_info;
Elf64_Xword sh_addralign;
Elf64_Xword sh_entsize;
u32 flags;
u16 elf_header_size;
u16 program_header_entry_size;
u16 program_header_entry_count;
u16 section_header_entry_size;
u16 section_header_entry_count;
u16 section_name_entry_id;
};
}
namespace program {
enum Type : u32 {
NULL = 0x00,
LOAD = 0x01,
DYNAMIC = 0x02,
INTERP = 0x03,
NOTE = 0x04,
SHLIB = 0x05,
PHDR = 0x06,
TLS = 0x07,
LOOS = 0x60000000,
HIOS = 0x6FFFFFFF,
LOPROC = 0x70000000,
HIPROC = 0x7FFFFFFF
};
struct Header {
Type type;
if (parent.header.identity.class == elf::Class::_32Bit) {
u32 offset;
u32 virtual_address;
u32 physical_address;
u32 file_size;
u32 memory_size;
u32 flags;
u32 alignment;
} else {
u32 flags;
u64 offset;
u64 virtual_address;
u64 physical_address;
u64 file_size;
u64 memory_size;
u64 alignment;
if (sh_size > 0 && sh_offset + sh_size < std::mem::size()) {
if (sh_type == SHT::NOBITS || sh_type == SHT::NULL) {
// Section has no data
} else if (sh_type == SHT::STRTAB) {
String stringTable[while($ < (sh_offset + sh_size))] @ sh_offset;
stringTableIndex = std::core::array_index();
} else if (sh_type == SHT::DYNSYM) {
Elf64_Sym symbolTable[sh_size / sh_entsize] @ sh_offset;
} else if (sh_type == SHT::INIT_ARRAY || sh_type == SHT::FINI_ARRAY) {
u32 pointer[while($ < (sh_offset + sh_size))] @ sh_offset;
} else {
u8 data[sh_size] @ sh_offset;
}
}
} [[static]];
} [[format("format_section_header")]];
}
fn format_section_header(auto shdr) {
u32 i = 0;
u32 nameAddress = addressof(elf.shdr[stringTableIndex].stringTable) + shdr.sh_name;
while (i < std::core::member_count(elf.shdr[stringTableIndex].stringTable)) {
if (nameAddress >= addressof(elf.shdr[stringTableIndex].stringTable[i]) && nameAddress < (addressof(elf.shdr[stringTableIndex].stringTable[i]) + sizeof(elf.shdr[stringTableIndex].stringTable[i])))
break;
i += 1;
}
namespace section {
struct String {
char characters[];
};
enum Type : u32 {
NULL = 0x00,
PROGBITS = 0x01,
SYMTAB = 0x02,
STRTAB = 0x03,
RELA = 0x04,
HASH = 0x05,
DYNAMIC = 0x06,
NOTE = 0x07,
NOBITS = 0x08,
REL = 0x09,
SHLIB = 0x0A,
DYNSYM = 0x0B,
INIT_ARRAY = 0x0E,
FINI_ARRAY = 0x0F,
PREINIT_ARRAY = 0x10,
GROUP = 0x11,
SYMTAB_SHNDX = 0x12,
NUM = 0x13,
LOOS = 0x60000000
};
bitfield Flags {
WRITE : 1;
ALLOC : 1;
EXECINSTR : 1;
pad1 : 1;
MERGE : 1;
STRINGS : 1;
INFO_LINK : 1;
LINK_ORDER : 1;
OS_NONCONFORMING : 1;
GROUP : 1;
TLS : 1;
};
struct Header {
u32 name_offset;
section::Type type;
Flags flags;
padding[2];
if (parent.header.identity.class == elf::Class::_32Bit) {
u32 address;
u32 offset;
u32 size;
u32 link;
u32 info;
u32 address_alignment;
u32 entry_size;
} else {
padding[4];
u64 address;
u64 offset;
u64 size;
u32 link;
u32 info;
u64 address_alignment;
u64 entry_size;
}
} [[static]];
}
return elf.shdr[stringTableIndex].stringTable[i].value;
};
elf::Header header @ 0x00;
program::Header program_headers[header.program_header_entry_count] @ header.program_header_offset;
section::Header section_headers[header.section_header_entry_count] @ header.section_header_offset;
struct ELF {
E_IDENT e_ident;
if (e_ident.EI_DATA == EI_DATA::ELFDATA2LSB)
std::core::set_endian(std::mem::Endian::Little);
else
std::core::set_endian(std::mem::Endian::Big);
if (e_ident.EI_CLASS == EI_CLASS::ELFCLASS32) {
Elf32_Ehdr ehdr;
Elf32_Phdr phdr[ehdr.e_phnum] @ ehdr.e_phoff;
Elf32_Shdr shdr[ehdr.e_shnum] @ ehdr.e_shoff;
} else if (e_ident.EI_CLASS == EI_CLASS::ELFCLASS64) {
Elf64_Ehdr ehdr;
Elf64_Phdr phdr[ehdr.e_phnum] @ ehdr.e_phoff;
Elf64_Shdr shdr[ehdr.e_shnum] @ ehdr.e_shoff;
}
};
ELF elf @ 0x00;

70
patterns/fdt.pat Normal file
View File

@@ -0,0 +1,70 @@
#pragma endian big
#include <std/sys.pat>
#include <std/io.pat>
#include <type/magic.pat>
#include <type/size.pat>
struct FDTHeader {
type::Magic<"\xD0\x0D\xFE\xED"> magic;
u32 totalsize;
u32 off_dt_struct;
u32 off_dt_strings;
u32 off_mem_rsvmap;
u32 version;
u32 last_comp_version;
u32 boot_cpuid_phys;
u32 size_dt_strings;
u32 size_dt_struct;
};
struct AlignTo<auto Alignment> {
padding[Alignment- ((($ - 1) % Alignment) + 1)];
};
struct FDTReserveEntry {
u64 address;
type::Size<u64> size;
if (address == 0x00 && size == 0x00)
break;
};
enum FDTToken : u32 {
FDT_BEGIN_NODE = 0x00000001,
FDT_END_NODE = 0x00000002,
FDT_PROP = 0x00000003,
FDT_NOP = 0x00000004,
FDT_END = 0x00000009
};
struct FDTStructureBlock {
FDTToken token;
if (token == FDTToken::FDT_BEGIN_NODE) {
char nodeName[];
AlignTo<4>;
} else if (token == FDTToken::FDT_END) {
break;
} else if (token == FDTToken::FDT_PROP) {
u32 len;
u32 nameoff;
char value[len];
AlignTo<4>;
char name[] @ parent.header.off_dt_strings + nameoff;
} else if (token == FDTToken::FDT_NOP || token == FDTToken::FDT_END_NODE) {
// Nothing to do
} else {
std::error(std::format("Invalid token at address 0x{:02X}", addressof(token)));
}
};
struct FDT {
FDTHeader header;
std::assert(header.version == 17, "Unsupported format version");
FDTStructureBlock structureBlocks[while(true)] @ header.off_dt_struct;
FDTReserveEntry reserveEntries[while(true)] @ header.off_mem_rsvmap;
};
FDT fdt @ 0x00;

321
patterns/flac.hexpat Normal file
View File

@@ -0,0 +1,321 @@
#include <std/sys.pat>
#include <std/core.pat>
#include <std/io.pat>
#pragma endian big
u32 sampleSize;
u32 bitsPerSample;
// METADATA
enum BLOCK_TYPE : u8 {
STREAMINFO = 0,
PADDING = 1,
APPLICATION = 2,
SEEKTABLE = 3,
VORBIS_COMMENT = 4,
CUESHEET = 5,
PICTURE = 6,
INVALID = 127
};
bitfield METADATA_BLOCK_HEADER {
lastMetadataBlock : 1;
blockType : 7;
length : 24;
} [[left_to_right]];
bitfield STREAMINFO_FLAGS {
sampleRate : 20;
numChannels : 3 [[format("format_channels")]];
bitsPerSample : 5;
numSamplesInStream : 36;
} [[inline, left_to_right]];
fn format_channels(u8 value) {
return value + 1;
};
struct METADATA_BLOCK_STREAMINFO {
u16 minBlockSize, maxBlockSize;
u24 minFrameSize, maxFrameSize;
STREAMINFO_FLAGS flags;
u128 md5Signature;
bitsPerSample = flags.bitsPerSample;
};
struct METADATA_BLOCK_PADDING {
padding[parent.header.length];
};
struct METADATA_BLOCK_APPLICATION {
char applicationID[4];
u8 applicationData[parent.header.length - sizeof(applicationID)];
};
struct SEEKPOINT {
u64 sampleNumber;
u64 byteOffset;
u16 numSamples;
};
struct METADATA_BLOCK_SEEKTABLE {
SEEKPOINT seekPoints[parent.header.length / 18];
};
struct VORBIS_USER_COMMENT {
le u32 length;
char comment[length];
};
struct METADATA_BLOCK_VORBIS_COMMENT {
le u32 vendorLength;
u8 vendor[vendorLength];
le u32 userCommentListLength;
VORBIS_USER_COMMENT userCommentList[userCommentListLength];
};
bitfield TRACK_FLAGS {
audioTrack : 1;
preEmphasis : 1;
padding : 6;
} [[inline]];
struct CUESHEET_TRACK_INDEX {
u64 sampleOffset;
u8 indexPointNumber;
padding[3];
};
struct CUESHEET_TRACK {
u64 trackOffset;
u8 trackNumber;
char trackISRC[12];
TRACK_FLAGS flags;
padding[13];
u8 numTrackIndexPoints;
CUESHEET_TRACK_INDEX indexes[numTrackIndexPoints];
};
struct METADATA_BLOCK_CUESHEET {
char mediaCatalogNumber[128];
u64 numLeadInSamples;
bool isCD;
padding[258];
u8 numTracks;
CUESHEET_TRACK tracks[numTracks];
};
enum PICTURE_TYPE : u32 {
Other = 0,
FileIcon = 1,
OtherFileIcon = 2,
CoverFront = 3,
CoverBack = 4,
LeafletPage = 5,
Media = 6,
LeadArtist = 7,
Artist = 8,
Conductor = 9,
Band = 10,
Composer = 11,
Lyricist = 12,
RecordingLocation = 13,
DuringRecording = 14,
DuringPerformance = 15,
MovieScreenCapture = 16,
ABrightColoredFish = 17,
Illustration = 18,
BandLogoType = 19,
PublisherLogoType = 20
};
struct METADATA_BLOCK_PICTURE {
PICTURE_TYPE pictureType;
u32 mimeTypeLength;
char mimeType[mineTypeLength];
u32 descriptionLength;
char description[descriptionLength];
u32 width, height;
u32 colorDepth;
u32 colorCount;
u32 pictureDataLength;
u8 pictureData[pictureDataLength];
};
// FRAME DATA
// TODO: THIS IS INCOMPLETE / NOT WORKING CURRENTLY
bitfield FRAME_HEADER_FLAGS {
syncCode : 14;
padding : 1;
blockingStrategy : 1;
blockSize : 4;
sampleRate : 4;
channelAssignment : 4;
sampleSize : 3;
padding : 1;
} [[inline]];
struct FRAME_HEADER {
FRAME_HEADER_FLAGS flags;
sampleSize = flags.sampleSize;
if (flags.blockingStrategy)
char16 sampleNumber[7];
else
char16 frameNumber[6];
if (flags.blockSize == 0b0110)
u8 blockSize;
else if (flags.blockSize == 0b0111)
u16 blockSize;
if (flags.sampleRate == 0b1100)
u8 sampleRate;
else if (flags.sampleRate == 0b1101 || flags.sampleRate == 0b1110)
u16 sampleRate;
u8 crc8;
};
struct FRAME_FOOTER {
u16 crc16;
};
bitfield SUBFRAME_HEADER {
padding : 1;
type : 6;
wastedBits : 1;
};
fn getBitsPerSample() {
if (sampleSize == 0b000)
return bitsPerSample;
else if (sampleSize == 0b001)
return 8;
else if (sampleSize == 0b010)
return 12;
else if (sampleSize == 0b100)
return 16;
else if (sampleSize == 0b101)
return 20;
else if (sampleSize == 0b110)
return 24;
};
bitfield SUBFRAME_CONSTANT {
value : getBitsPerSample();
};
bitfield SUBFRAME_VERBATIM {
value : getBitsPerSample() * parent.parent.header.flags.blockSize;
};
bitfield SUBFRAME_FIXED_VALUE {
value : getBitsPerSample() * (parent.parent.header.type & 0b111);
codingMethod : 2;
} [[inline]];
bitfield RESIDUAL_CODING_METHOD_PARTITIONED_RICE {
partitionOrder : 4;
riceParameter : 4;
if (riceParameter == 0b1111)
bitsPerSample : 5;
} [[right_to_left]];
bitfield RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 {
partitionOrder : 4;
riceParameter : 5;
if (riceParameter == 0b11111)
bitsPerSample : 5;
} [[right_to_left]];
struct RESIDUAL {
if (parent.value.codingMethod == 0b00)
RESIDUAL_CODING_METHOD_PARTITIONED_RICE rice;
else if (parent.value.codingMethod == 0b01)
RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 rice;
if ((parent.parent.header.type & 0b111) == 0b000)
u8 samples[(getBitsPerSample() * (parent.parent.parent.header.flags.blockSize - (parent.parent.header.type & 0b111))) / 8];
else if (std::core::array_index() != 0)
u8 samples[(getBitsPerSample() * (parent.parent.parent.header.flags.blockSize / (1 << rice.partitionOrder))) / 8];
else
u8 samples[(getBitsPerSample() * ((parent.parent.parent.header.flags.blockSize / (1 << rice.partitionOrder)) - (parent.parent.header.type & 0b111))) / 8];
};
struct SUBFRAME_FIXED {
SUBFRAME_FIXED_VALUE value;
RESIDUAL residual;
};
bitfield SUBFRAME_LPC_VALUE {
warmUpSamples : getBitsPerSample() * ((parent.header.type & 0b011111) + 1);
quantizedLinearPredictorCoefficient : 4;
quantizedLinearPredictorCoefficientShift : 5;
predictorCoefficients : quantizedLinearPredictorCoefficient * ((parent.header.type & 0b011111) + 1);
} [[inline]];
struct SUBFRAME_LPC {
SUBFRAME_LPC_VALUE value;
RESIDUAL residual;
};
struct SUBFRAME {
SUBFRAME_HEADER header;
if (header.type == 0b00000)
SUBFRAME_CONSTANT constant;
else if (header.type == 0b000001)
SUBFRAME_VERBATIM verbatim;
else if ((header.type >> 3) == 0b001 && (header.type & 0b111) <= 4)
SUBFRAME_FIXED fixed;
else if (header.type == 0b100000)
SUBFRAME_LPC lpc;
};
struct FRAME {
FRAME_HEADER header;
SUBFRAME subframes[parent.metadata[0].data.flags.numChannels + 1];
FRAME_FOOTER footer;
};
struct METADATA_BLOCK {
METADATA_BLOCK_HEADER header;
if (header.lastMetadataBlock)
break;
if (header.blockType == BLOCK_TYPE::STREAMINFO)
METADATA_BLOCK_STREAMINFO data;
else if (header.blockType == BLOCK_TYPE::PADDING)
METADATA_BLOCK_PADDING data;
else if (header.blockType == BLOCK_TYPE::APPLICATION)
METADATA_BLOCK_APPLICATION data;
else if (header.blockType == BLOCK_TYPE::VORBIS_COMMENT)
METADATA_BLOCK_VORBIS_COMMENT data;
else if (header.blockType == BLOCK_TYPE::CUESHEET)
METADATA_BLOCK_CUESHEET data;
else if (header.blockType == BLOCK_TYPE::PICTURE)
METADATA_BLOCK_PICTURE data;
else
std::error("Invalid metadata block type!");
};
struct STREAM {
char magic[4];
METADATA_BLOCK metadata[while(true)];
//FRAME frames[while(!std::mem::eof())];
};
STREAM stream @ 0x00;

168
patterns/fs.hexpat Normal file
View File

@@ -0,0 +1,168 @@
#include <std/io.pat>
struct DiskTimeStamp {
u8 seconds, minutes, hours;
};
enum DiskProtection : u16 {
None = 0x0000,
CopyProtected = 0x5A5A
};
bitfield CHS {
h : 8;
s : 6;
c : 10;
} [[right_to_left, 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));
};
enum PartitionStatus : u8 {
None = 0x00,
Active = 0x80
};
enum PartitionType : u8 {
EmptyPartitionEntry = 0x00,
FAT32_CHS = 0x0B,
FAT32_LBA = 0x0C
};
namespace fat32 {
u64 bytesPerCluster;
struct FSInfo {
u32 leadSignature;
padding[480];
u32 structSignature;
u32 freeClusterCount;
u32 nextFreeCluster;
padding[12];
u32 trailSignature;
};
bitfield SequenceNumber {
padding : 1;
lastLogical : 1;
padding : 1;
number : 5;
} [[left_to_right]];
enum EntryStatus : u8 {
Regular = 0x00,
DotEntry = 0x2E,
DeletedEntry = 0xE5
};
union EntryStatusOrSequenceNumber {
EntryStatus entryStatus;
SequenceNumber sequenceNumber;
};
bitfield Attributes {
readOnly : 1;
hidden : 1;
systemFile : 1;
volumeLabel : 1;
subdirectory : 1;
archive : 1;
padding : 2;
} [[right_to_left]];
struct DirEntry {
char fileName[8];
char extension[3];
Attributes attributes;
u8 reserved[10];
u16 time, date;
u16 startingCluster;
u32 fileSize;
u8 data[fileSize] @ startingCluster * bytesPerCluster;
};
struct VFATDirEntry {
EntryStatusOrSequenceNumber entryStatusOrSequenceNumber;
char16 name1[5];
Attributes attributes;
u8 type;
u8 nameChecksum;
char16 name2[6];
u16 startingCluster;
char16 name3[2];
if (entryStatusOrSequenceNumber.sequenceNumber.number > 1)
VFATDirEntry nextLogicalEntry;
else
DirEntry physicalEntry;
};
struct Partition {
u8 jmpCode[3];
char oemName[8];
u16 bytesPerSector;
u8 sectorsPerCluster;
u16 reservedAreaSize;
u8 numFats;
u16 rootEntryCount;
u16 numSectors;
u8 mediaType;
u16 fatSize;
u16 sectorsPerTrack;
u16 numHeads;
u32 numHiddenSectors;
u32 numFsSectors;
u32 numFatSectors;
u16 extFlags;
u16 fsVersion;
u32 rootCluster;
u16 fsInfoSector;
u16 backupBootSector;
padding[12];
u8 driveNumber;
padding[1];
u8 bootSignature;
u32 volumeID;
char volumeLabel[11];
char fsType[8];
u8 bootstrapCode[420];
u16 signature;
bytesPerCluster = (sectorsPerCluster * 1024) * bytesPerSector;
FSInfo fsInfo @ addressof(this) + fsInfoSector * bytesPerSector;
VFATDirEntry rootDirEntry @ addressof(this) + rootCluster * bytesPerCluster;
};
}
struct PartitionEntry {
PartitionStatus status;
CHS chsFirstSectorAddress;
PartitionType type;
CHS chsLastSectorAddress;
u32 lbaFirstSectorAddress;
u32 numSectors;
if (type == PartitionType::EmptyPartitionEntry)
continue;
else if (type == PartitionType::FAT32_CHS || type == PartitionType::FAT32_LBA)
fat32::Partition partition @ lbaFirstSectorAddress * 512;
};
struct MasterBootRecord {
u8 bootstrapCodeArea1[218];
padding[2];
u8 originalPhysicalDrive;
DiskTimeStamp diskTimeStamp;
u8 bootstrapCodeArea2[216];
u32 diskSignature;
DiskProtection diskProtection;
PartitionEntry partitionEntries[4];
u16 bootSignature;
};
MasterBootRecord mbr @ 0x00;

153
patterns/gif.hexpat Normal file
View File

@@ -0,0 +1,153 @@
#include <std/mem.pat>
#pragma MIME image/gif
#pragma bitfield_order left_to_right
// gif89a
struct data_subblock_t {
u8 block_size;
u8 data_values[block_size];
};
struct data_subblocks_t {
data_subblock_t data[while (std::mem::read_unsigned($, 1) != 0x00)];
u8 block_terminator; // 0x00
} [[inline]];
struct header_t {
char header[3];
char version[3];
};
bitfield lsd_fields_t {
global_color_table_flag : 1;
color_resolution : 3;
sort_flag : 1;
size_of_global_color_table : 3;
} [[inline]];
struct logical_screen_descriptor_t {
u16 width;
u16 height;
lsd_fields_t fields;
u8 background_color_index;
u8 pixel_aspect_ratio;
};
struct color_table_entry_t {
u8 red;
u8 green;
u8 blue;
};
bitfield gce_fields_t {
padding : 3;
disposal_method : 3;
user_input_flag : 1;
transparent_color_flag : 1;
} [[inline]];
struct graphic_coltrol_extension_t {
u8 extension_introducer; // 0x21
u8 graphic_control_label; // 0xf9
u8 block_size;
gce_fields_t fields;
u16 delay_time;
u8 transparent_color_index;
u8 block_terminator;
};
struct comment_extension_t {
u8 extension_introducer; // 0x21
u8 comment_label; // 0xfe
data_subblocks_t comment_data;
};
struct plaintext_extension_t {
u8 extension_introducer; // 0x21
u8 plain_text_label; // 0x01
u8 block_size; // 12
u16 text_grid_left_position;
u16 text_grid_top_position;
u16 text_grid_width;
u16 text_grid_height;
u8 character_cell_width;
u8 character_cell_height;
u8 text_foreground_color_index;
u8 text_background_color_index;
data_subblocks_t plain_text_data;
};
struct application_extension_t {
u8 extension_introducer; // 0x21
u8 extension_label; // 0xff
u8 block_size; // 11
u8 application_identifier[8];
u8 application_authentication_code[3];
data_subblocks_t data;
};
bitfield id_fields_t {
local_color_table : 1;
interlace_flag : 1;
sort_fla : 1;
padding : 2;
size_of_local_color_table : 3;
} [[inline]];
struct image_descriptor_t {
u8 image_separator; // 0x2c
u16 image_left_position;
u16 image_top_position;
u16 image_width;
u16 image_height;
id_fields_t fields;
};
struct table_based_image_t {
u8 lzw_minimum_code_size;
data_subblocks_t data;
};
struct gif_block_t {
if (std::mem::read_unsigned($, 1) == 0x21) {
if (std::mem::read_unsigned($+1, 1) == 0x01) {
plaintext_extension_t plaintext_extension;
}
else if (std::mem::read_unsigned($+1, 1) == 0xf9) {
graphic_coltrol_extension_t graphic_coltrol_extension;
}
else if (std::mem::read_unsigned($+1, 1) == 0xfe) {
comment_extension_t comment;
} else {
application_extension_t application_extension;
}
}
else if (std::mem::read_unsigned($, 1) == 0x2c) {
image_descriptor_t image_descriptor;
if (image_descriptor.fields.local_color_table) {
color_table_entry_t local_color_table[1<<(image_descriptor.fields.size_of_local_color_table + 1)];
}
table_based_image_t image;
}
} [[inline]];
struct gif_t {
header_t header;
logical_screen_descriptor_t logical_screen_descriptor;
if (logical_screen_descriptor.fields.global_color_table_flag) {
color_table_entry_t global_color_table[1<<(logical_screen_descriptor.fields.size_of_global_color_table + 1)];
}
gif_block_t blocks[while (std::mem::read_unsigned($, 1) != 0x3b)];
u8 trailer; // 0x3b
};
gif_t gif @ 0x00;

77
patterns/gzip.hexpat Normal file
View File

@@ -0,0 +1,77 @@
#pragma MIME application/gzip
#include <type/time.pat>
#include <type/size.pat>
#include <std/mem.pat>
bitfield Flags {
FTEXT : 1;
FHCRC : 1;
FEXTRA : 1;
FNAME : 1;
FCOMMENT : 1;
padding : 3;
} [[right_to_left]];
bitfield ExtraFlags {
padding : 1;
maximumCompression : 1;
fastestCompression : 1;
padding : 5;
};
enum CompressionMethod : u8 {
Reserved = 0 ... 7,
Deflate = 8
};
enum OperatingSystemID : u8 {
FATFileSystem = 0x00,
Amiga = 0x01,
VMS = 0x02,
Unix = 0x03,
VM_CMS = 0x04,
AtariTOS = 0x05,
HPFSFileSystem = 0x06,
Macintosh = 0x07,
ZSystem = 0x08,
CP_M = 0x09,
TOPS_20 = 0x0A,
NTFSFileSystem = 0x0B,
QDOS = 0x0C,
AcordRISCOS = 0x0D,
Unknown = 0xFF
};
struct GZip {
u16 signature;
CompressionMethod compressionMethod;
Flags flags;
type::time32_t modificationTime;
ExtraFlags extraFlags;
OperatingSystemID operatingSystemId;
if (flags.FEXTRA) {
u16 extraLength;
u8 extraField[extraLength];
}
if (flags.FNAME) {
char originalFileName[];
}
if (flags.FCOMMENT) {
char comment[];
}
if (flags.FHCRC) {
u16 crc16;
}
u8 data[while($ < std::mem::size() - 8)] [[sealed]];
u32 crc32;
type::Size<u32> isize;
};
GZip gzip @ 0x00;

156
patterns/id3.hexpat Normal file
View 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;

View File

@@ -26,7 +26,9 @@ enum cp_tag : u8 {
CONSTANT_NameAndType = 12,
CONSTANT_MethodHandle = 15,
CONSTANT_MethodType = 16,
CONSTANT_InvokeDynamic = 18
CONSTANT_InvokeDynamic = 18,
CONSTANT_Module = 19,
CONSTANT_Package = 20
};
enum major_version : u2 {
@@ -36,7 +38,7 @@ enum major_version : u2 {
JDK_1_4 = 48,
Java_SE_5_0 = 49,
Java_SE_6_0 = 50,
Java_SE_6 = 50,
Java_SE_7 = 51,
Java_SE_8 = 52,
Java_SE_9 = 53,
@@ -129,37 +131,62 @@ struct CONSTANT_InvokeDynamic_info {
u2 name_and_type_index;
};
struct cp_info {
cp_tag tag;
// Tag == CONSTANT_Module
struct CONSTANT_Module_info {
u2 name_index;
};
if (tag == cp_tag::CONSTANT_Utf8)
CONSTANT_Utf8_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Integer)
CONSTANT_Integer_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Float)
CONSTANT_Float_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Long)
CONSTANT_Long_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Double)
CONSTANT_Double_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Class)
CONSTANT_Class_info info [[inline]];
else if (tag == cp_tag::CONSTANT_String)
CONSTANT_String_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Fieldref)
CONSTANT_Fieldref_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Methodref)
CONSTANT_Methodref_info info [[inline]];
else if (tag == cp_tag::CONSTANT_InterfaceMethodref)
CONSTANT_InterfaceMethodref_info info [[inline]];
else if (tag == cp_tag::CONSTANT_NameAndType)
CONSTANT_NameAndType_info info [[inline]];
else if (tag == cp_tag::CONSTANT_MethodHandle)
CONSTANT_MethodHandle_info info [[inline]];
else if (tag == cp_tag::CONSTANT_MethodType)
CONSTANT_MethodType_info info [[inline]];
else if (tag == cp_tag::CONSTANT_InvokeDynamic)
CONSTANT_InvokeDynamic_info info [[inline]];
// Tag == CONSTANT_Package
struct CONSTANT_Package_info {
u2 name_index;
};
// All 8-byte constants take up two entries in the constant_pool table of the class file
u1 padding_entry_flag = 0;
struct cp_info {
if (padding_entry_flag == 0) {
cp_tag tag;
if (tag == cp_tag::CONSTANT_Utf8)
CONSTANT_Utf8_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Integer)
CONSTANT_Integer_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Float)
CONSTANT_Float_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Long) {
CONSTANT_Long_info info [[inline]];
padding_entry_flag = 1;
}
else if (tag == cp_tag::CONSTANT_Double) {
CONSTANT_Double_info info [[inline]];
padding_entry_flag = 1;
}
else if (tag == cp_tag::CONSTANT_Class)
CONSTANT_Class_info info [[inline]];
else if (tag == cp_tag::CONSTANT_String)
CONSTANT_String_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Fieldref)
CONSTANT_Fieldref_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Methodref)
CONSTANT_Methodref_info info [[inline]];
else if (tag == cp_tag::CONSTANT_InterfaceMethodref)
CONSTANT_InterfaceMethodref_info info [[inline]];
else if (tag == cp_tag::CONSTANT_NameAndType)
CONSTANT_NameAndType_info info [[inline]];
else if (tag == cp_tag::CONSTANT_MethodHandle)
CONSTANT_MethodHandle_info info [[inline]];
else if (tag == cp_tag::CONSTANT_MethodType)
CONSTANT_MethodType_info info [[inline]];
else if (tag == cp_tag::CONSTANT_InvokeDynamic)
CONSTANT_InvokeDynamic_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Module)
CONSTANT_Module_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Package)
CONSTANT_Package_info info [[inline]];
} else {
padding_entry_flag = 0;
}
};
bitfield access_flags_method {
@@ -216,7 +243,7 @@ bitfield access_flags_class {
ACC_SYNTHETIC : 1; // 0x1000
ACC_ANNOTATION : 1; // 0x2000
ACC_ENUM : 1; // 0x4000
padding : 1; // 0x8000
ACC_MODULE : 1; // 0x8000
};
struct attribute_info {
@@ -279,31 +306,29 @@ fn main() {
std::print("Fields:");
for (le u16 i = 0, i < class_file.fields_count, i = i + 1) {
str method_string = " ";
str field_string = " ";
if (class_file.fields[i].access_flags.ACC_PUBLIC)
method_string = method_string + "public ";
field_string = field_string + "public ";
if (class_file.fields[i].access_flags.ACC_PRIVATE)
method_string = method_string + "private ";
field_string = field_string + "private ";
if (class_file.fields[i].access_flags.ACC_PROTECTED)
method_string = method_string + "protected ";
field_string = field_string + "protected ";
if (class_file.fields[i].access_flags.ACC_STATIC)
method_string = method_string + "static ";
field_string = field_string + "static ";
if (class_file.fields[i].access_flags.ACC_FINAL)
method_string = method_string + "final ";
field_string = field_string + "final ";
if (class_file.fields[i].access_flags.ACC_VOLATILE)
method_string = method_string + "volatile ";
if (class_file.fields[i].access_flags.ACC_NATIVE)
method_string = method_string + "native ";
field_string = field_string + "volatile ";
if (class_file.fields[i].access_flags.ACC_TRANSIENT)
method_string = method_string + "transient ";
field_string = field_string + "transient ";
if (class_file.fields[i].access_flags.ACC_ENUM)
method_string = method_string + "enum ";
field_string = field_string + "enum ";
method_string = method_string + class_file.constant_pool[class_file.fields[i].name_index - 1].info.bytes;
method_string = method_string + " [ " + class_file.constant_pool[class_file.fields[i].descriptor_index - 1].info.bytes + " ]";
field_string = field_string + class_file.constant_pool[class_file.fields[i].name_index - 1].info.bytes;
field_string = field_string + " [ " + class_file.constant_pool[class_file.fields[i].descriptor_index - 1].info.bytes + " ]";
std::print("{}", method_string);
std::print("{}", field_string);
}
std::print("Methods:");

459
patterns/lnk.hexpat Normal file
View File

@@ -0,0 +1,459 @@
#pragma MIME application/x-ms-shortcut
#include <type/guid.pat>
#include <type/size.pat>
bitfield LinkFlags {
HasLinkTargetIDList : 1;
HasLinkInfo : 1;
HasName : 1;
HasRelativePath : 1;
HasWorkingDir : 1;
HasArguments : 1;
HasIconLocation : 1;
IsUnicode : 1;
ForceNoLinkInfo : 1;
HasExpString : 1;
RunInSeparateProcess : 1;
padding : 1;
HasDarwinID : 1;
RunAsUser : 1;
HasExpIcon : 1;
NoPidlAlias : 1;
padding : 1;
RunWithShimLayer : 1;
ForceNoLinkTrack : 1;
EnableTargetMetadata : 1;
DisableLinkPathTracking : 1;
DisableKnownFolderTracking : 1;
DisableKnownFolderAlias : 1;
AllowLinkToLink : 1;
UnaliasOnSave : 1;
PreferEnvironmentPath : 1;
KeepLocalIDListForUNCTarget : 1;
padding : 5;
} [[right_to_left]];
bitfield FileAttributesFlags {
FILE_ATTRIBUTE_READONLY : 1;
FILE_ATTRIBUTE_HIDDEN : 1;
FILE_ATTRIBUTE_SYSTEM : 1;
padding : 1;
FILE_ATTRIBUTE_DIRECTORY : 1;
FILE_ATTRIBUTE_ARCHIVE : 1;
padding : 1;
FILE_ATTRIBUTE_NORMAL : 1;
FILE_ATTRIBUTE_TEMPORARY : 1;
FILE_ATTRIBUTE_SPARSE_FILE : 1;
FILE_ATTRIBUTE_REPARSE_POINT : 1;
FILE_ATTRIBUTE_COMPRESSED : 1;
FILE_ATTRIBUTE_OFFLINE : 1;
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED : 1;
FILE_ATTRIBUTE_ENCRYPTED : 1;
padding : 17;
} [[right_to_left]];
bitfield ModifierKeys {
HOTKEYF_SHIFT : 1;
HOTKEYF_CONTROL : 1;
HOTKEYF_ALT : 1;
padding : 5;
} [[right_to_left]];
enum Keys : u8 {
KEY_NONE = 0x00,
KEY_0 = 0x30,
KEY_1 = 0x31,
KEY_2 = 0x32,
KEY_3 = 0x33,
KEY_4 = 0x34,
KEY_5 = 0x35,
KEY_6 = 0x36,
KEY_7 = 0x37,
KEY_8 = 0x38,
KEY_9 = 0x39,
KEY_A = 0x41,
KEY_B = 0x42,
KEY_C = 0x43,
KEY_D = 0x44,
KEY_E = 0x45,
KEY_F = 0x46,
KEY_G = 0x47,
KEY_H = 0x48,
KEY_I = 0x49,
KEY_J = 0x4A,
KEY_K = 0x4B,
KEY_L = 0x4C,
KEY_M = 0x4D,
KEY_N = 0x4E,
KEY_O = 0x4F,
KEY_P = 0x50,
KEY_Q = 0x51,
KEY_R = 0x52,
KEY_S = 0x53,
KEY_T = 0x54,
KEY_U = 0x55,
KEY_V = 0x56,
KEY_W = 0x57,
KEY_X = 0x58,
KEY_Y = 0x59,
KEY_Z = 0x5A,
VK_F1 = 0x70,
VK_F2 = 0x71,
VK_F3 = 0x72,
VK_F4 = 0x73,
VK_F5 = 0x74,
VK_F6 = 0x75,
VK_F7 = 0x76,
VK_F8 = 0x77,
VK_F9 = 0x78,
VK_F10 = 0x79,
VK_F11 = 0x7A,
VK_F12 = 0x7B,
VK_F13 = 0x7C,
VK_F14 = 0x7D,
VK_F15 = 0x7E,
VK_F16 = 0x7F,
VK_F17 = 0x80,
VK_F18 = 0x81,
VK_F19 = 0x82,
VK_F20 = 0x83,
VK_F21 = 0x84,
VK_F22 = 0x85,
VK_F23 = 0x86,
VK_F24 = 0x87,
VK_NUMLOCK = 0x90,
VK_SCROLL = 0x91,
};
struct HotKeyFlags {
Keys Key;
ModifierKeys ModifierKeys;
};
struct FILETIME {
u32 dwLowDateTime;
u32 dwHighDateTime;
};
enum SHOWWINDOW_FLAGS : u32 {
SW_SHOWNORMAL = 0x00000001,
SW_SHOWMAXIMIZED = 0x00000003,
SW_SHOWMINNOACTIVE = 0x00000007
};
struct ShellLinkHeader {
type::Size32 HeaderSize;
type::GUID LinkCLSID;
LinkFlags LinkFlags;
FileAttributesFlags FileAttributes;
FILETIME CreationTime, AccessTime, WriteTime;
type::Size32 FileSize;
u32 IconIndex;
SHOWWINDOW_FLAGS ShowCommand;
HotKeyFlags HotKey;
padding[2];
padding[4];
padding[4];
};
struct ItemID {
type::Size16 ItemIDSize;
if (ItemIDSize == 0x00)
break;
else
u8 Data[ItemIDSize - sizeof(ItemIDSize)];
};
struct IDList {
ItemID ItemIDList[while(true)];
};
struct LinkTargetIDList {
type::Size16 IDListSize;
IDList IDList[while($ < (addressof(IDListSize) + IDListSize))];
};
bitfield LinkInfoFlags {
VolumeIDAndLocalBasePath : 1;
CommonNetworkRelativeLinkAndPathSuffix : 1;
padding : 30;
};
enum DriveType : u32 {
DRIVE_UNKNOWN = 0x00000000,
DRIVE_NO_ROOT_DIR = 0x00000001,
DRIVE_REMOVABLE = 0x00000002,
DRIVE_FIXED = 0x00000003,
DRIVE_REMOTE = 0x00000004,
DRIVE_CDROM = 0x00000005,
DRIVE_RAMDISK = 0x00000006
};
struct VolumeID {
type::Size32 VolumeIDSize;
DriveType DriveType;
u32 DriveSerialNumber;
u32 VolumeLabelOffset;
if (VolumeLabelOffset == 0x14)
u32 VolumeLabelOffsetUnicode;
char Data[VolumeIDSize - ($ - addressof(this))];
};
bitfield CommonNetworkRelativeLinkFlags {
ValidDevice : 1;
ValidNetType : 1;
padding : 30;
} [[right_to_left]];
enum NetworkProviderType : u32 {
WNNC_NET_AVID = 0x001A0000,
WNNC_NET_DOCUSPACE = 0x001B0000,
WNNC_NET_MANGOSOFT = 0x001C0000,
WNNC_NET_SERNET = 0x001D0000,
WNNC_NET_RIVERFRONT1 = 0x001E0000,
WNNC_NET_RIVERFRONT2 = 0x001F0000,
WNNC_NET_DECORB = 0x00200000,
WNNC_NET_PROTSTOR = 0x00210000,
WNNC_NET_FJ_REDIR = 0x00220000,
WNNC_NET_DISTINCT = 0x00230000,
WNNC_NET_TWINS = 0x00240000,
WNNC_NET_RDR2SAMPLE = 0x00250000,
WNNC_NET_CSC = 0x00260000,
WNNC_NET_3IN1 = 0x00270000,
WNNC_NET_EXTENDNET = 0x00290000,
WNNC_NET_STAC = 0x002A0000,
WNNC_NET_FOXBAT = 0x002B0000,
WNNC_NET_YAHOO = 0x002C0000,
WNNC_NET_EXIFS = 0x002D0000,
WNNC_NET_DAV = 0x002E0000,
WNNC_NET_KNOWARE = 0x002F0000,
WNNC_NET_OBJECT_DIRE = 0x00300000,
WNNC_NET_MASFAX = 0x00310000,
WNNC_NET_HOB_NFS = 0x00320000,
WNNC_NET_SHIVA = 0x00330000,
WNNC_NET_IBMAL = 0x00340000,
WNNC_NET_LOCK = 0x00350000,
WNNC_NET_TERMSRV = 0x00360000,
WNNC_NET_SRT = 0x00370000,
WNNC_NET_QUINCY = 0x00380000,
WNNC_NET_OPENAFS = 0x00390000,
WNNC_NET_AVID1 = 0x003A0000,
WNNC_NET_DFS = 0x003B0000,
WNNC_NET_KWNP = 0x003C0000,
WNNC_NET_ZENWORKS = 0x003D0000,
WNNC_NET_DRIVEONWEB = 0x003E0000,
WNNC_NET_VMWARE = 0x003F0000,
WNNC_NET_RSFX = 0x00400000,
WNNC_NET_MFILES = 0x00410000,
WNNC_NET_MS_NFS = 0x00420000,
WNNC_NET_GOOGLE = 0x00430000
};
struct CommonNetworkRelativeLink {
type::Size32 CommonNetworkRelativeLinkSize;
CommonNetworkRelativeLinkFlags CommonNetworkRelativeLinkFlags;
u32 NetNameOffset;
u32 DeviceNameOffset;
NetworkProviderType NetworkProviderType;
if (NetNameOffset > 0x14) {
u32 NetNameOffsetUnicode;
u32 DeviceNameOffsetUnicode;
}
char NetName[];
char DeviceName[];
if (NetNameOffset > 0x14) {
char16 NetNameUnicode[];
char16 DeviceNameUnicode[];
}
};
struct LinkInfo {
type::Size32 LinkInfoSize;
type::Size32 LinkInfoHeaderSize;
LinkInfoFlags LinkInfoFlags;
u32 VolumeIDOffset;
u32 LocalBasePathOffset;
u32 CommonNetworkRelativeLinkOffset;
u32 CommonPathSuffixOffset;
if (LinkInfoHeaderSize >= 0x24) {
u32 LocalBasePathOffsetUnicode;
u32 CommonPathSuffixOffsetUnicode;
}
if (LinkInfoFlags.VolumeIDAndLocalBasePath) {
VolumeID VolumeID;
char LocalBasePath[];
}
if (LinkInfoFlags.CommonNetworkRelativeLinkAndPathSuffix)
CommonNetworkRelativeLink CommonNetworkRelativeLink;
char CommonPathSuffix[];
if (LinkInfoHeaderSize >= 0x24) {
if (LinkInfoFlags.VolumeIDAndLocalBasePath)
char16 LocalBasePathUnicode[];
char16 CommonPathSuffixUnicode[];
}
};
struct String {
u16 CountCharacters;
char16 String[CountCharacters];
};
struct StringData {
if (parent.ShellLinkHeader.LinkFlags.HasName)
String NAME_STRING;
if (parent.ShellLinkHeader.LinkFlags.HasRelativePath)
String RELATIVE_PATH;
if (parent.ShellLinkHeader.LinkFlags.HasWorkingDir)
String WORKING_DIR;
if (parent.ShellLinkHeader.LinkFlags.HasArguments)
String COMMAND_LINE_ARGUMENTS;
if (parent.ShellLinkHeader.LinkFlags.HasIconLocation)
String ICON_LOCATION;
};
bitfield FillAttributes {
FOREGROUND_BLUE : 1;
FOREGROUND_GREEN : 1;
FOREGROUND_RED : 1;
FOREGROUND_INTENSITY : 1;
BACKGROUND_BLUE : 1;
BACKGROUND_GREEN : 1;
BACKGROUND_RED : 1;
BACKGROUND_INTENSITY : 1;
padding : 8;
} [[right_to_left]];
struct ConsoleDataBlock {
FillAttributes FillAttributes;
FillAttributes PopupFillAttributes;
u16 ScreenBufferSizeX, ScreenBufferSizeY;
u16 WindowSizeX, WindowSizeY;
u16 WindowOriginX, WindowOriginY;
padding[4];
padding[4];
u32 FontSize;
u32 FontFamily;
u32 FontWeight;
char16 FaceName[32];
u32 CursorSize;
u32 FullScreen;
u32 QuickEdit;
u32 InsertMode;
u32 AutoPosition;
u32 HistoryBufferSize;
u32 NumberOfHistoryBuffers;
u32 HistoryNoDup;
u32 ColorTable[16];
};
struct ConsoleFEDataBlock {
u32 CodePage;
};
struct DarwinDataBlock {
char DarwinDataAnsi[260];
char16 DarwinDataUnicode[260];
};
struct EnvironmentVariableDataBlock {
char TargetAnsi[260];
char16 TargetUnicode[260];
};
struct IconEnvironmentDataBlock {
char TargetAnsi[260];
char16 TargetUnicode[260];
};
struct KnownFolderDataBlock {
type::GUID KnownFolderID;
u32 Offset;
};
struct PropertyStoreDataBlock {
u8 Bytes[parent.BlockSize - sizeof(parent.BlockSize) - sizeof(parent.BlockSignature)];
std::warning("PropertyStoreDataBlock is not yet implemented!");
};
struct ShimDataBlock {
char16 LayerName[(parent.BlockSize - sizeof(parent.BlockSize) - sizeof(parent.BlockSignature)) / sizeof(char16)];
};
struct SpecialFolderDataBlock {
u32 SpecialFolderID;
u32 Offset;
};
struct TrackerDataBlock {
type::Size32 Length;
u32 Version;
char MachineID[16];
type::GUID Droid[2];
type::GUID DroidBirth[2];
};
struct VistaAndAboveIDListDataBlock {
IDList IDList;
};
struct ExtraDataBlock {
type::Size32 BlockSize;
if (BlockSize < 0x04)
break;
else {
u32 BlockSignature;
if (BlockSignature == 0xA000'0002)
ConsoleDataBlock CONSOLE_PROPS;
else if (BlockSignature == 0xA000'0004)
ConsoleFEDataBlock CONSOLE_FE_PROPS;
else if (BlockSignature == 0xA000'0006)
DarwinDataBlock DARWIN_PROPS;
else if (BlockSignature == 0xA000'0001)
EnvironmentVariableDataBlock ENVIRONMENT_PROPS;
else if (BlockSignature == 0xA000'0007)
IconEnvironmentDataBlock ICON_ENVIRONMENT_PROPS;
else if (BlockSignature == 0xA000'000B)
KnownFolderDataBlock KNOWN_FOLDER_PROPS;
else if (BlockSignature == 0xA000'0009)
PropertyStoreDataBlock PROPERTY_STORE_PROPS;
else if (BlockSignature == 0xA000'0008)
ShimDataBlock SHIM_PROPS;
else if (BlockSignature == 0xA000'0005)
SpecialFolderDataBlock SPECIAL_FOLDER_PROPS;
else if (BlockSignature == 0xA000'0003)
TrackerDataBlock TRACKER_PROPS;
else if (BlockSignature == 0xA000'000C)
VistaAndAboveIDListDataBlock VISTA_AND_ABOVE_IDLIST_PROPS;
}
};
struct ExtraData {
ExtraDataBlock ExtraDataBlock[while(true)];
};
struct LNK {
ShellLinkHeader ShellLinkHeader;
if (ShellLinkHeader.LinkFlags.HasLinkTargetIDList)
LinkTargetIDList LinkTargetIDList;
if (ShellLinkHeader.LinkFlags.HasLinkInfo)
LinkInfo LinkInfo;
StringData StringData;
ExtraData ExtraData;
};
LNK lnk @ 0x00;

383
patterns/macho.hexpat Normal file
View File

@@ -0,0 +1,383 @@
#pragma MIME application/x-mach-binary
#include <type/size.pat>
enum Magic : u32 {
_32BitMagic = 0xFEEDFACE,
_64BitMagic = 0xFEEDFACF
};
enum CpuType : u32 {
VAX = 1,
ROMP = 2,
BS32032 = 4,
BS32332 = 5,
MC680x0 = 6,
I386 = 7,
X86_64 = CpuType::I386 | 0x100'0000,
MIPS = 8,
NS32532 = 9,
HPPA = 11,
ARM = 12,
MC88000 = 13,
SPARC = 14,
I860 = be u32(15),
I860_LITTLE = 16,
RS6000 = 17,
MC980000 = 18,
POWERPC = 18,
POWERPC64 = CpuType::POWERPC | 0x100'0000,
VEO = 255
};
enum SubCpuTypeVAX : u24 {
ALL = 0,
VAX780 = 1,
VAX785 = 2,
VAX750 = 3,
VAX730 = 4,
UVAXI = 5,
UVAXII = 6,
VAX8200 = 7,
VAX8500 = 8,
VAX8600 = 9,
VAX8650 = 10,
VAX8800 = 11,
UVAXIII = 12
};
enum SubCpuTypeROMP : u24 {
ALL = 0,
PC = 1,
APC = 2,
_135 = 3
};
enum SubCpuType32XXX : u24 {
ALL = 0,
MMAX_DPC = 1,
SQT = 2,
MMAX_APC_FPU = 3,
MMAX_APC_FPA = 4,
MMAX_XPC = 5
};
enum SubCpuTypeI386 : u24 {
_386 = 3,
_486 = 4,
_486SX = SubCpuTypeI386::_486 + 128,
_586 = 5,
IntelPentium = 5 + (0 << 4),
IntelPentiumPro = 6 + (1 << 4),
IntelPentiumIIM3 = 6 + (3 << 4),
IntelPentiumIIM5 = 6 + (5 << 4),
IntelPentium4 = 10 + (0 << 4),
};
enum SubCpuTypeMips : u24 {
ALL = 0,
R2300 = 1,
R2600 = 2,
R2800 = 3,
R2000a = 4
};
enum SubCpuType680x0 : u24 {
ALL = 1,
MC68030 = 1,
MC68040 = 2,
MC68030_Only = 3
};
enum SubCpuTypeHPPA : u24 {
ALL = 0,
_7100 = 0,
_7100LC = 1
};
enum SubCpuTypeARM : u24 {
ALL = 0,
A500_ARCH = 1,
A500 = 2,
A440 = 3,
M4 = 4,
V4T = 5,
V6 = 6,
V5TEJ = 7,
XSCALE = 8,
V7 = 9,
V7F = 10, /* Cortex A9 */
V7S = 11, /* Swift */
V7K = 12 /* Kirkwood40 */
};
enum SubCpuTypeMC88000 : u24 {
ALL = 0,
MMAX_JPC = 1,
MC88100 = 1,
MC88110 = 2
};
enum SubCpuTypeMC98000 : u24 {
ALL = 0,
MC98601 = 1
};
enum SubCpuTypeI860 : u24 {
ALL = 0,
_860 = 1
};
enum SubCpuTypeI860Little : u24 {
ALL = 0 ... 1
};
enum SubCpuTypeRS6000 : u24 {
ALL = 0 ... 1
};
enum SubCpuTypeSparc : u24 {
ALL = 0,
_260 = 1,
_110 = 2
};
enum SubCpuTypePowerPC : u24 {
ALL = 0,
_601 = 1,
_602 = 2,
_603 = 3,
_603e = 4,
_603ev = 5,
_604 = 6,
_604e = 7,
_620 = 8,
_750 = 9,
_7400 = 10,
_7450 = 11,
_970 = 100
};
enum SubCpuTypeVEO : u24 {
_1 = 1,
_2 = 2,
_3 = 3,
_4 = 4,
ALL = SubCpuTypeVEO::_2
};
bitfield Capabilities {
padding : 7;
lib64 : 1;
} [[right_to_left]];
enum FileType : u32 {
Object = 1,
Execute = 2,
FVMLib = 3,
Core = 4,
Preload = 5,
DyLib = 6,
DyLinker = 7,
Bundle = 8,
DyLibStub = 9,
DSym = 10,
KExtBundle = 11,
};
bitfield Flags {
noUndefs : 1;
incrLink : 1;
dyldLink : 1;
binDatLoad : 1;
prebound : 1;
splitSegs : 1;
lazyInit : 1;
twoLevel : 1;
forceFlat : 1;
noMultiDefs : 1;
noFixPrebinding : 1;
prebindable : 1;
allModsBound : 1;
subSectionsViaSymbols : 1;
canonical : 1;
weakDefines : 1;
bindsToWeak : 1;
allowStackExecution : 1;
rootSafe : 1;
setuidSafe : 1;
noReexportedDylibs : 1;
pie : 1;
deadStrippableDylib : 1;
hasTlvDescriptors : 1;
noHeapExecution : 1;
appExtensionSafe : 1;
nlistOutOfSyncWithDyldinof : 1;
simSupport : 1;
} [[right_to_left]];
struct Header {
Magic magic;
CpuType cpuType;
if (cpuType == CpuType::VAX) SubCpuTypeVAX subCpuType;
else if (cpuType == CpuType::ROMP) SubCpuTypeROMP subCpuType;
else if (cpuType == CpuType::BS32032 || cpuType == CpuType::BS32332 || cpuType == CpuType::NS32532) SubCpuType32XXX subCpuType;
else if (cpuType == CpuType::I386 || cpuType == CpuType::X86_64) SubCpuTypeI386 subCpuType;
else if (cpuType == CpuType::MIPS) SubCpuTypeMips subCpuType;
else if (cpuType == CpuType::HPPA) SubCpuTypeHPPA subCpuType;
else if (cpuType == CpuType::ARM) SubCpuTypeARM subCpuType;
else if (cpuType == CpuType::MC88000) SubCpuTypeMC88000 subCpuType;
else if (cpuType == CpuType::MC98000) SubCpuTypeMC98000 subCpuType;
else if (cpuType == CpuType::I860 || cpuType == CpuType::I860_LITTLE) SubCpuTypeI860 subCpuType;
else if (cpuType == CpuType::SPARC) SubCpuTypeSparc subCpuType;
else if (cpuType == CpuType::POWERPC || cpuType == CpuType::POWERPC64) SubCpuTypePowerPC subCpuType;
else if (cpuType == CpuType::VEO) SubCpuTypeVEO subCpuType;
else u24 subCpuType;
Capabilities capabilities;
FileType fileType;
u32 numCommands;
type::Size<u32> sizeOfCommands;
Flags flags;
if (magic == Magic::_64BitMagic) padding[sizeof(u32)];
};
enum Command : u32 {
ReqDyLd = 0x8000'0000,
Segment = 0x01,
SymTab = 0x02,
SymSeg = 0x03,
Thread = 0x04,
UnixThread = 0x05,
LoadFVMLib = 0x06,
IdFVMLib = 0x07,
Ident = 0x08,
FVMFile = 0x09,
PrePage = 0x0A,
DySymTab = 0x0B,
LoadDyLib = 0x0C,
IdDyLib = 0x0D,
LoadDyLinker = 0x0E,
IdDyLinker = 0x0F,
PreboundDyLib = 0x10,
Routines = 0x11,
SubFramework = 0x12,
SubUmbrella = 0x13,
SubClient = 0x14,
SubLibrary = 0x15,
TwoLevelHints = 0x16,
PrebindCksum = 0x17,
LoadWeakDyLib = 0x18 | Command::ReqDyLd,
Segment64 = 0x19,
Routines64 = 0x1A,
UUID = 0x1B,
RPath = 0x1C | 0x8000'0000,
CodeSignature = 0x1D,
SegmentSplitInfo = 0x1E,
ReExportDyLib = 0x1F | Command::ReqDyLd,
LazyLoadDyLib = 0x20,
EncryptionInfo = 0x21,
DyLdInfo = 0x22,
DyLdInfoOnly = 0x22 | Command::ReqDyLd,
LoadUpwardDyLib = 0x23 | Command::ReqDyLd,
VersionMinMacOSX = 0x24,
VersionMinIPhoneOS = 0x25,
FunctionStarts = 0x26,
DyLdEnvironment = 0x27,
Main = 0x28 | Command::ReqDyLd,
DataInCode = 0x29,
SourceVersion = 0x2A,
DyLibCodeSignDRS = 0x2B
};
struct CommandUUID {
u128 uuid;
};
struct Section {
char sectionName[16];
char segmentName[16];
u32 address;
type::Size<u32> size;
u32 offset;
u32 align;
u32 reloff;
u32 numRelocs;
u32 flags;
padding[8];
if (offset > 0)
u8 data[size] @ offset [[sealed]];
};
struct CommandSegment {
char segmentName[16];
u32 vmAddress;
type::Size<u32> vmSize;
u32 fileOffset;
type::Size<u32> fileSize;
u32 maxProtection;
u32 initProtection;
u32 numSections;
u32 flags;
Section sections[numSections];
if (fileOffset > 0)
u8 data[fileSize] @ fileOffset [[sealed]];
};
struct Section64 {
char sectionName[16];
char segmentName[16];
u64 address;
type::Size<u64> size;
u32 offset;
u32 align;
u32 reloff;
u32 numRelocs;
u32 flags;
padding[12];
if (offset > 0)
u8 data[size] @ offset [[sealed]];
};
struct CommandSegment64 {
char segmentName[16];
u64 vmAddress;
type::Size<u64> vmSize;
u64 fileOffset;
type::Size<u64> fileSize;
u32 maxProtection;
u32 initProtection;
u32 numSections;
u32 flags;
Section64 sections[numSections];
if (fileOffset > 0)
u8 data[fileSize] @ fileOffset [[sealed]];
};
struct LoadCommand {
Command command;
type::Size<u32> commandSize;
if (command == Command::UUID)
CommandUUID data;
else if (command == Command::Segment)
CommandSegment data;
else if (command == Command::Segment64)
CommandSegment64 data;
else
u8 data[commandSize - 8] [[sealed]];
};
struct MachO {
Header header;
LoadCommand loadCommands[header.numCommands];
};
MachO macho @ 0x00;

423
patterns/minidump.hexpat Normal file
View File

@@ -0,0 +1,423 @@
#pragma MIME application/x-dmp
#include <type/time.pat>
#include <type/types/win32.pat>
#include <type/size.pat>
using RVA = ULONG32;
using RVA64 = ULONG64;
enum MINIDUMP_STREAM_TYPE : ULONG32 {
UnusedStream = 0,
ReservedStream0 = 1,
ReservedStream1 = 2,
ThreadListStream = 3,
ModuleListStream = 4,
MemoryListStream = 5,
ExceptionStream = 6,
SystemInfoStream = 7,
ThreadExListStream = 8,
Memory64ListStream = 9,
CommentStreamA = 10,
CommentStreamW = 11,
HandleDataStream = 12,
FunctionTableStream = 13,
UnloadedModuleListStream = 14,
MiscInfoStream = 15,
MemoryInfoListStream = 16,
ThreadInfoListStream = 17,
HandleOperationListStream = 18,
TokenStream = 19,
JavaScriptDataStream = 20,
SystemMemoryInfoStream = 21,
ProcessVmCountersStream = 22,
IptTraceStream = 23,
ThreadNamesStream = 24,
ceStreamNull = 0x8000,
ceStreamSystemInfo = 0x8001,
ceStreamException = 0x8002,
ceStreamModuleList = 0x8003,
ceStreamProcessList = 0x8004,
ceStreamThreadList = 0x8005,
ceStreamThreadContextList = 0x8006,
ceStreamThreadCallStackList = 0x8007,
ceStreamMemoryVirtualList = 0x8008,
ceStreamMemoryPhysicalList = 0x8009,
ceStreamBucketParameters = 0x800A,
ceStreamProcessModuleMap = 0x800B,
ceStreamDiagnosisList = 0x800C,
LastReservedStream = 0xFFFF
};
struct MINIDUMP_LOCATION_DESCRIPTOR {
type::Size32 DataSize;
RVA Rva;
};
struct MINIDUMP_MEMORY_DESCRIPTOR {
ULONG64 StartOfMemoryRange;
MINIDUMP_LOCATION_DESCRIPTOR Memory;
};
struct MINIDUMP_THREAD {
ULONG32 ThreadId;
ULONG32 SuspendCount;
ULONG32 PriorityClass;
ULONG32 Priority;
ULONG64 Teb;
MINIDUMP_MEMORY_DESCRIPTOR Stack;
MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
};
struct MINIDUMP_THREAD_LIST {
ULONG32 NumberOfThreads;
MINIDUMP_THREAD Threads[NumberOfThreads];
};
struct VS_FIXEDFILEINFO {
DWORD dwSignature;
DWORD dwStrucVersion;
DWORD dwFileVersionMS;
DWORD dwFileVersionLS;
DWORD dwProductVersionMS;
DWORD dwProductVersionLS;
DWORD dwFileFlagsMask;
DWORD dwFileFlags;
DWORD dwFileOS;
DWORD dwFileType;
DWORD dwFileSubtype;
DWORD dwFileDateMS;
DWORD dwFileDateLS;
};
struct MINIDUMP_MODULE {
ULONG64 BaseOfImage;
type::Size32 SizeOfImage;
ULONG32 CheckSum;
type::time32_t TimeDateStamp;
RVA ModuleNameRva;
VS_FIXEDFILEINFO VersionInfo;
MINIDUMP_LOCATION_DESCRIPTOR CvRecord;
MINIDUMP_LOCATION_DESCRIPTOR MiscRecord;
ULONG64 Reserved0;
ULONG64 Reserved1;
char16 ModuleName[] @ ModuleNameRva + 4 [[hidden]];
} [[format("format_module")]];
fn format_module(ref MINIDUMP_MODULE module) {
return module.ModuleName;
};
struct MINIDUMP_MODULE_LIST {
ULONG32 NumberOfModules;
MINIDUMP_MODULE Modules[NumberOfModules];
};
struct MINIDUMP_MEMORY_LIST {
ULONG32 NumberOfMemoryRanges;
MINIDUMP_MEMORY_DESCRIPTOR MemoryRanges[NumberOfMemoryRanges];
};
struct MINIDUMP_EXCEPTION {
ULONG32 ExceptionCode;
ULONG32 ExceptionFlags;
ULONG64 ExceptionRecord;
ULONG64 ExceptionAddress;
ULONG32 NumberParameters;
padding[4];
ULONG64 ExceptionInformation[15];
};
struct MINIDUMP_EXCEPTION_STREAM {
ULONG32 ThreadId;
padding[4];
MINIDUMP_EXCEPTION ExceptionRecord;
MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
};
struct CPU_INFORMATION {
ULONG32 VendorId[3];
ULONG32 VersionInformation;
ULONG32 FeatureInformation;
ULONG32 AMDExtendedCpuFeatures;
};
struct MINIDUMP_SYSTEM_INFO {
USHORT ProcessorArchitecture;
USHORT ProcessorLevel;
USHORT ProcessorRevision;
UCHAR NumberOfProcessors;
UCHAR ProductType;
ULONG32 MajorVersion;
ULONG32 MinorVersion;
ULONG32 BuildNumber;
ULONG32 PlatformId;
RVA CSDVersionRva;
USHORT SuiteMask;
USHORT Reserved;
CPU_INFORMATION Cpu;
};
struct MINIDUMP_THREAD_EX {
ULONG32 ThreadId;
ULONG32 SuspendCount;
ULONG32 PriorityClass;
ULONG32 Priority;
ULONG64 Teb;
MINIDUMP_MEMORY_DESCRIPTOR Stack;
MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
MINIDUMP_MEMORY_DESCRIPTOR BackingStore;
};
struct MINIDUMP_THREAD_EX_LIST {
ULONG32 NumberOfThreads;
MINIDUMP_THREAD_EX Threads[NumberOfThreads];
};
struct MINIDUMP_MEMORY_DESCRIPTOR64 {
ULONG64 StartOfMemoryRange;
type::Size64 DataSize;
};
struct MINIDUMP_MEMORY64_LIST {
ULONG64 NumberOfMemoryRanges;
RVA64 BaseRva;
MINIDUMP_MEMORY_DESCRIPTOR64 MemoryRanges[NumberOfMemoryRanges];
};
struct MINIDUMP_HANDLE_DESCRIPTOR {
ULONG64 Handle;
RVA TypeNameRva;
RVA ObjectNameRva;
ULONG32 Attributes;
ULONG32 GrantedAccess;
ULONG32 HandleCount;
ULONG32 PointerCount;
};
struct MINIDUMP_HANDLE_DESCRIPTOR_2 {
ULONG64 Handle;
RVA TypeNameRva;
RVA ObjectNameRva;
ULONG32 Attributes;
ULONG32 GrantedAccess;
ULONG32 HandleCount;
ULONG32 PointerCount;
RVA ObjectInfoRva;
ULONG32 Reserved0;
};
struct MINIDUMP_HANDLE_DATA_STREAM {
ULONG32 SizeOfHeader;
ULONG32 SizeOfDescriptor;
ULONG32 NumberOfDescriptors;
ULONG32 Reserved;
if (SizeOfDescriptor == 32)
MINIDUMP_HANDLE_DESCRIPTOR HandleDescriptors[NumberOfDescriptors];
else if (SizeOfDescriptor == 40)
MINIDUMP_HANDLE_DESCRIPTOR_2 HandleDescriptors[NumberOfDescriptors];
};
struct MINIDUMP_FUNCTION_TABLE_DESCRIPTOR {
ULONG64 MinimumAddress;
ULONG64 MaximumAddress;
ULONG64 BaseAddress;
ULONG32 EntryCount;
type::Size32 SizeOfAlignPad;
};
struct MINIDUMP_FUNCTION_TABLE_STREAM {
type::Size32 SizeOfHeader;
type::Size32 SizeOfDescriptor;
type::Size32 SizeOfNativeDescriptor;
type::Size32 SizeOfFunctionEntry;
ULONG32 NumberOfDescriptors;
ULONG32 SizeOfAlignPad;
MINIDUMP_FUNCTION_TABLE_DESCRIPTOR FunctionDescriptors[NumberOfDescriptors];
};
struct MINIDUMP_UNLOADED_MODULE {
ULONG64 BaseOfImage;
type::Size32 SizeOfImage;
ULONG32 CheckSum;
ULONG32 TimeDateStamp;
RVA ModuleNameRva;
char16 ModuleName[] @ ModuleNameRva + 4 [[hidden]];
} [[format("format_unloaded_module")]];
fn format_unloaded_module(ref MINIDUMP_UNLOADED_MODULE module) {
return module.ModuleName;
};
struct MINIDUMP_UNLOADED_MODULE_LIST {
ULONG32 SizeOfHeader;
ULONG32 SizeOfEntry;
ULONG32 NumberOfEntries;
if (SizeOfHeader > 12)
padding[header.SizeOfHeader - 12];
MINIDUMP_UNLOADED_MODULE Modules[NumberOfEntries];
};
struct MINIDUMP_MISC_INFO {
ULONG32 SizeOfInfo;
ULONG32 Flags1;
ULONG32 ProcessId;
ULONG32 ProcessCreateTime;
ULONG32 ProcessUserTime;
ULONG32 ProcessKernelTime;
if (SizeOfInfo > 24) {
ULONG32 ProcessorMaxMhz;
ULONG32 ProcessorCurrentMhz;
ULONG32 ProcessorMhzLimit;
ULONG32 ProcessorMaxIdleState;
ULONG32 ProcessorCurrentIdleState;
}
};
struct MINIDUMP_MEMORY_INFO {
ULONG64 BaseAddress;
ULONG64 AllocationBase;
ULONG32 AllocationProtect;
padding[4];
type::Size64 RegionSize;
ULONG32 State;
ULONG32 Protect;
ULONG32 Type;
padding[4];
};
struct MINIDUMP_MEMORY_INFO_LIST {
ULONG SizeOfHeader;
ULONG SizeOfEntry;
ULONG64 NumberOfEntries;
if (SizeOfHeader > 16)
padding[SizeOfHeader - 16];
MINIDUMP_MEMORY_INFO Info[NumberOfEntries];
};
struct MINIDUMP_THREAD_INFO {
ULONG32 ThreadId;
ULONG32 DumpFlags;
ULONG32 DumpError;
ULONG32 ExitStatus;
ULONG64 CreateTime;
ULONG64 ExitTime;
ULONG64 KernelTime;
ULONG64 UserTime;
ULONG64 StartAddress;
ULONG64 Affinity;
};
struct MINIDUMP_THREAD_INFO_LIST {
ULONG SizeOfHeader;
ULONG SizeOfEntry;
ULONG NumberOfEntries;
if (SizeOfHeader > 12)
padding[SizeOfHeader - 12];
MINIDUMP_THREAD_INFO Info[NumberOfEntries];
};
struct MINIDUMP_HANDLE_OPERATION_LIST {
ULONG32 SizeOfHeader;
ULONG32 SizeOfEntry;
ULONG32 NumberOfEntries;
ULONG32 Reserved;
};
struct MINIDUMP_DIRECTORY {
MINIDUMP_STREAM_TYPE StreamType;
MINIDUMP_LOCATION_DESCRIPTOR Location;
if (StreamType == MINIDUMP_STREAM_TYPE::ThreadListStream)
MINIDUMP_THREAD_LIST ThreadList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::ModuleListStream)
MINIDUMP_MODULE_LIST ModuleList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::MemoryListStream)
MINIDUMP_MEMORY_LIST MemoryList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::ExceptionStream)
MINIDUMP_EXCEPTION_STREAM ExceptionInfo @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::SystemInfoStream)
MINIDUMP_SYSTEM_INFO SystemInfo @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::ThreadExListStream)
MINIDUMP_THREAD_EX_LIST ThreadExList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::Memory64ListStream)
MINIDUMP_MEMORY64_LIST Mem64List @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::CommentStreamA)
char Comment[] @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::CommentStreamW)
char16 Comment[] @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::HandleDataStream)
MINIDUMP_HANDLE_DATA_STREAM HandleData @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::FunctionTableStream)
MINIDUMP_FUNCTION_TABLE_STREAM FunctionTable @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::UnloadedModuleListStream)
MINIDUMP_UNLOADED_MODULE_LIST UnloadModuleList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::MiscInfoStream)
MINIDUMP_MISC_INFO MiscInfo @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::MemoryInfoListStream)
MINIDUMP_MEMORY_INFO_LIST MemInfoList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::ThreadInfoListStream)
MINIDUMP_THREAD_INFO_LIST ThreadInfoList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::HandleOperationListStream)
MINIDUMP_HANDLE_OPERATION_LIST HandleOperList @ Location.Rva;
};
bitfield MINIDUMP_TYPE {
MiniDumpWithDataSegs : 1;
MiniDumpWithFullMemory : 1;
MiniDumpWithHandleData : 1;
MiniDumpFilterMemory : 1;
MiniDumpScanMemory : 1;
MiniDumpWithUnloadedModules : 1;
MiniDumpWithIndirectlyReferencedMemory : 1;
MiniDumpFilterModulePaths : 1;
MiniDumpWithProcessThreadData : 1;
MiniDumpWithPrivateReadWriteMemory : 1;
MiniDumpWithoutOptionalData : 1;
MiniDumpWithFullMemoryInfo : 1;
MiniDumpWithThreadInfo : 1;
MiniDumpWithCodeSegs : 1;
MiniDumpWithoutAuxiliaryState : 1;
MiniDumpWithFullAuxiliaryState : 1;
MiniDumpWithPrivateWriteCopyMemory : 1;
MiniDumpIgnoreInaccessibleMemory : 1;
MiniDumpWithTokenInformation : 1;
MiniDumpWithModuleHeaders : 1;
MiniDumpFilterTriage : 1;
MiniDumpWithAvxXStateContext : 1;
MiniDumpWithIptTrace : 1;
MiniDumpScanInaccessiblePartialPages : 1;
padding : 40;
} [[right_to_left]];
struct MINIDUMP_HEADER {
char Signature[4];
ULONG32 Version;
ULONG32 NumberOfStreams;
RVA StreamDirectoryRva;
ULONG32 Checksum;
type::time32_t TimeDateStamp;
MINIDUMP_TYPE Flags;
};
struct MINIDUMP {
MINIDUMP_HEADER Header;
MINIDUMP_DIRECTORY Streams[Header.NumberOfStreams] [[format_entries("format_stream")]];
};
fn format_stream(ref MINIDUMP_DIRECTORY stream) {
return stream.StreamType;
};
MINIDUMP MiniDump @ 0x00;

154
patterns/msgpack.hexpat Normal file
View File

@@ -0,0 +1,154 @@
#pragma MIME application/x-msgpack
enum Type : u8 {
PositiveFixInt = 0x00 ... 0x7F,
FixMap = 0x80 ... 0x8F,
FixArray = 0x90 ... 0x9F,
FixStr = 0xA0 ... 0xBF,
Nil = 0xC0,
Unused = 0xC1,
False = 0xC2,
True = 0xC3,
Bin8 = 0xC4,
Bin16 = 0xC5,
Bin32 = 0xC6,
Ext8 = 0xC7,
Ext16 = 0xC8,
Ext32 = 0xC9,
Float32 = 0xCA,
Float64 = 0xCB,
Uint8 = 0xCC,
Uint16 = 0xCD,
Uint32 = 0xCE,
Uint64 = 0xCF,
Int8 = 0xD0,
Int16 = 0xD1,
Int32 = 0xD2,
Int64 = 0xD3,
FixExt1 = 0xD4,
FixExt2 = 0xD5,
FixExt4 = 0xD6,
FixExt8 = 0xD7,
FixExt16 = 0xD8,
Str8 = 0xD9,
Str16 = 0xDA,
Str32 = 0xDB,
Array16 = 0xDC,
Array32 = 0xDD,
Map16 = 0xDE,
Map32 = 0xDF,
NegativeFixInt = 0xE0 ... 0xFF
};
fn format_positive_fixint(u8 value) {
return value & 0b0111'1111;
};
fn format_negative_fixint(u8 value) {
return -(value & 0b0001'1111);
};
using MessagePack;
struct MapEntry {
MessagePack key, value;
};
struct MessagePack {
Type type;
if (u8(type) <= 0x7F) {
$ -= 1;
u8 value [[format("format_positive_fixint")]];
} else if (u8(type) >= Type::NegativeFixInt) {
$ -= 1;
u8 value [[format("format_negative_fixint")]];
} else if (type == Type::Uint8)
be u8 value;
else if (type == Type::Uint16)
be u16 value;
else if (type == Type::Uint32)
be u32 value;
else if (type == Type::Uint64)
be u64 value;
else if (type == Type::Int8)
be s8 value;
else if (type == Type::Int16)
be s16 value;
else if (type == Type::Int32)
be s32 value;
else if (type == Type::Int64)
be s64 value;
else if (type == Type::Float32)
be float value;
else if (type == Type::Float64)
be double value;
else if ((u8(type) & 0b1110'0000) == Type::FixStr)
char value[u8(type) & 0b0001'1111];
else if (type == Type::Str8) {
be u8 length;
char value[length];
} else if (type == Type::Str16) {
be u16 length;
char value[length];
} else if (type == Type::Str32) {
be u32 length;
char value[length];
} else if (type == Type::Bin8) {
be u8 length;
u8 value[length];
} else if (type == Type::Bin16) {
be u16 length;
u8 value[length];
} else if (type == Type::Bin32) {
be u32 length;
u8 value[length];
} else if ((u8(type) & 0b1111'0000) == Type::FixArray)
MessagePack value[u8(type) & 0b0000'1111];
else if (type == Type::Array16) {
be u16 length;
MessagePack value[length];
} else if (type == Type::Array32) {
be u32 length;
MessagePack value[length];
} else if ((u8(type) & 0b1111'0000) == Type::FixMap)
MapEntry value[u8(type) & 0b0000'1111];
else if (type == Type::Map16) {
be u16 length;
MapEntry value[length];
} else if (type == Type::Map32) {
be u32 length;
MapEntry value[length];
} else if (type == Type::FixExt1) {
s8 type;
u8 data;
} else if (type == Type::FixExt2) {
s8 type;
u16 data;
} else if (type == Type::FixExt4) {
s8 type;
u32 data;
} else if (type == Type::FixExt8) {
s8 type;
u64 data;
} else if (type == Type::FixExt16) {
s8 type;
u128 data;
} else if (type == Type::Ext8) {
u8 length;
s8 type;
u8 data[length];
} else if (type == Type::Ext16) {
u16 length;
s8 type;
u8 data[length];
} else if (type == Type::Ext32) {
u32 length;
s8 type;
u8 data[length];
}
};
MessagePack pack @ 0x00;

70
patterns/nbt.hexpat Normal file
View File

@@ -0,0 +1,70 @@
#include <std/sys.pat>
#pragma endian big
enum Tag : u8 {
End = 0,
Byte = 1,
Short = 2,
Int = 3,
Long = 4,
Float = 5,
Double = 6,
ByteArray = 7,
String = 8,
List = 9,
Compound = 10,
IntArray = 11,
LongArray = 12
};
using Element;
struct Value {
if (parent.tag == Tag::Byte)
s8 value;
else if (parent.tag == Tag::Short)
s16 value;
else if (parent.tag == Tag::Int)
s32 value;
else if (parent.tag == Tag::Long)
s64 value;
else if (parent.tag == Tag::Float)
float value;
else if (parent.tag == Tag::Double)
double value;
else if (parent.tag == Tag::ByteArray) {
s32 arrayLength;
s8 value[arrayLength] [[sealed]];
} else if (parent.tag == Tag::String) {
u16 stringLength;
char value[stringLength];
} else if (parent.tag == Tag::List) {
Tag tag;
s32 listLength;
Value values[listLength] [[static]];
} else if (parent.tag == Tag::Compound) {
Element values[while(true)];
} else {
std::error(std::format("Invalid tag {:02X}", TypeTag));
}
} [[inline]];
struct Element {
Tag tag;
if (tag == Tag::End)
break;
else {
u16 nameLength;
char name[nameLength];
Value value;
}
};
struct NBT {
Element element[while(true)] [[inline]];
};
NBT nbt @ 0x00;

264
patterns/ne.hexpat Normal file
View File

@@ -0,0 +1,264 @@
#include <std/mem.pat>
#pragma bitfield_order right_to_left
struct DOSHeader {
char signature[2];
u16 lastPageSize;
u16 numberOfPages;
u16 relocations;
u16 headerSizeInParagraphs;
u16 minimumAllocatedParagraphs;
u16 maximumAllocatedParagraphs;
u16 initialSSValue;
u16 initialRelativeSPValue;
u16 checksum;
u16 initialRelativeIPValue;
u16 initialCSValue;
u16 relocationsTablePointer;
u16 overlayNumber;
u8 overlayInformation[0x20];
u32 neHeaderPointer;
};
u16 dosMessageOffset;
u16 pointedCodeOffset;
fn finddosmessage() {
for (u8 i = 0, $+i < std::mem::read_unsigned(0x3C, 4), i = i + 1) {
if (std::mem::read_unsigned($+i, 1) == 0xBA) { // MOV instruction
dosMessageOffset = std::mem::read_unsigned($+i+1, 2);
break;
}
}
};
fn findpointingcode() {
for (u8 i = 0, $+i < std::mem::read_unsigned(0x3C, 4), i = i + 1) {
if (std::mem::read_unsigned($+i, 1) == 0xE8) { // CALL instruction
pointedCodeOffset = std::mem::read_unsigned($+i+1, 2);
return true;
}
}
return false;
};
fn isdosdata(char c) {
return c == 0x0D || c == '$';
};
struct DOSStub {
if (findpointingcode()) {
u8 pointingCode[3];
u8 code[while(std::mem::read_unsigned($, 1) != 0x00)] @ addressof(this) + pointedCodeOffset + 3;
char message[while(!isdosdata(std::mem::read_unsigned($, 1)))];
char data[while(std::mem::read_string($-1, 1) != "$")];
}
else {
finddosmessage();
if (dosMessageOffset > 0) {
u8 code[while($ != addressof(this) + dosMessageOffset)];
char message[while(!isdosdata(std::mem::read_unsigned($, 1)))];
char data[while(std::mem::read_string($-1, 1) != "$")];
}
else {
char code[while(std::mem::read_unsigned($, 1) != 0x00)];
}
}
};
struct FileHeader {
DOSHeader dosHeader;
DOSStub dosStub @ dosHeader.headerSizeInParagraphs * 16;
};
FileHeader fileHeader @ 0x00;
enum DGroupType : u8 {
NoAutoData,
SingleData,
MultipleData,
Null
};
fn formatDGroupType(u8 value) {
DGroupType dgroup = value;
return dgroup;
};
enum AppType : u8 {
None,
Fullscreen,
WinPMCompatible,
UsesWinPM
};
fn formatAppType(u8 value) {
AppType app = value;
return app;
};
bitfield ProgramFlags {
dGroupType : 2 [[format("formatDGroupType")]];
globalInitialization : 1;
protectedModeOnly : 1;
instructions86 : 1;
instructions286 : 1;
instructions386 : 1;
instructionsX87 : 1;
};
bitfield ApplicationFlags {
applicationType : 2 [[format("formatAppType")]];
padding : 1;
os2Application : 1;
reserved : 1;
imageError : 1;
nonConforming : 1;
dll : 1;
};
enum OSType : u8 {
Unknown = 0x00,
OS2 = 0x01,
Win16 = 0x02,
DOS4 = 0x03,
Win32 = 0x04,
BorlandOSServices = 0x05,
PharlapDOSExtenderOS2 = 0x81,
PharlapDOSExtenderWindows = 0x82
};
bitfield OS2EXEFlags {
longFilename : 1;
protectedMode : 1;
proportionalFonts : 1;
gangloadArea : 1;
};
struct NEHeader {
char signature[2];
u8 majorLinkerVersion;
u8 minorLinkerVersion;
u16 entryTableOffset;
u16 entryTableLength;
u32 fileCRC;
ProgramFlags programFlags;
ApplicationFlags appFlags;
u16 autoDataSegmentIndex;
u16 initHeapSize;
u16 initStackSize;
u32 entryPoint;
u32 initialStackPointer;
u16 segmentCount;
u16 moduleReferenceCount;
u16 nonResidentNamesTableSize;
u16 segmentTableOffset;
u16 resourceTableOffset;
u16 residentNamesTableOffset;
u16 moduleReferenceTableOffset;
u16 importedNamesTableOffset;
u8 *nonResidentNamesTablePointer[nonResidentNamesTableSize] : u32;
u16 moveableEntryCount;
u16 fileAlignmentSizeShiftCount;
u16 resourceCount;
OSType targetOS;
OS2EXEFlags os2ExeFlags;
u16 thunksReturnOffset;
u16 segmentReferenceThunksOffset;
u16 minimumCodeSwapAreaSize;
u8 expectedMinorWindowsVersion;
u8 expectedMajorWindowsVersion;
};
NEHeader neHeader @ fileHeader.dosHeader.neHeaderPointer;
bitfield SegmentTableFlags {
dataSegment : 1;
typeMask : 2;
padding : 1;
moveable : 1;
padding : 1;
preloaded : 1;
padding : 1;
containsRelocationInfo : 1;
padding : 1;
discardPriority : 4;
} [[right_to_left]];
struct SegmentTable {
u16 segmentDataPointer;
u16 segmentLength;
SegmentTableFlags segmentTableFlags;
u16 minimumAllocationSize;
};
SegmentTable segmentTable[neHeader.segmentCount] @ addressof(neHeader) + neHeader.segmentTableOffset;
bitfield BlockFlags {
padding : 4;
moveable : 1;
shared : 1;
preload : 1;
padding : 9;
};
struct ResourceTypeInformationBlock {
u8 *resourcePointer : u16;
u16 resourceLength;
BlockFlags flags;
u16 resourceID;
u32 reserved;
};
struct ResourceRecord {
u16 typeID;
u16 numberOfResources;
u32 reserved;
ResourceTypeInformationBlock blocks[numberOfResources];
};
struct ResourceTable {
u16 alignmentShiftCount;
ResourceRecord records[neHeader.resourceTableEntryCount];
u8 stringLength;
char string[stringLength];
};
ResourceTable resourceTable[neHeader.resourceCount] @ addressof(neHeader) + neHeader.resourceTableOffset;
struct ResidentName {
u8 stringLength;
char string[stringLength];
u16 ordinalNumber;
};
ResidentName residentNameTable[while($+1 < addressof(neHeader) + neHeader.moduleReferenceTableOffset)] @ addressof(neHeader) + neHeader.residentNamesTableOffset;
struct ModuleReference {
u16 moduleNameOffset;
};
ModuleReference moduleReferenceTable[neHeader.moduleReferenceCount] @ addressof(neHeader) + neHeader.moduleReferenceTableOffset;
struct ImportedNameTable {
u8 stringLength;
char string[stringLength];
};
ImportedNameTable importedNameTable[while($ < addressof(neHeader) + neHeader.entryTableOffset)] @ addressof(neHeader) + neHeader.importedNamesTableOffset;
enum EntryDataType : u8 {
Unused,
Fixed = 0x01 ... 0xFE,
Moveable
};
struct EntryTable {
u8 entryCount;
EntryDataType segmentIndicator;
};
EntryTable entryTable[neHeader.entryTableLength/2] @ addressof(neHeader) + neHeader.entryTableOffset;

161
patterns/ntag.hexpat Normal file
View File

@@ -0,0 +1,161 @@
bitfield AccessCapability {
Read : 4;
Write : 4;
} [[left_to_right]];
struct CapabilityContainer {
u8 magic;
u8 version;
u8 memorySize;
AccessCapability accessCapability;
};
bitfield NDEFFlags {
MB : 1;
ME : 1;
CF : 1;
SR : 1;
IL : 1;
TNF : 3;
} [[left_to_right]];
enum TNFType : u8 {
Empty = 0x00,
NFCForumWellKnownType = 0x01,
MediaType = 0x02,
AbsoluteURI = 0x03,
NFCForumExternalType = 0x04,
Unknown = 0x05,
Unchanged = 0x06,
Reserved = 0x07
};
struct NDEF {
NDEFFlags flags;
u8 typeLength;
if (flags.SR)
u8 payloadLength;
else
u32 payloadLength;
if (flags.IL)
u8 idLength;
char type[typeLength];
if (flags.IL)
u8 id[idLength];
u8 payload[payloadLength];
if (flags.ME)
break;
};
struct LockControl {
u8 dynamicLockByteOffset;
u8 numBits;
u8 pageControlInfo;
};
struct MemoryControl {
u8 reservedBytesOffset;
u8 numBytes;
u8 pageSize;
};
struct Length {
u8 byte [[hidden, no_unique_address]];
if (byte == 0xFF)
u24 length;
else
u8 length;
} [[sealed, transform("transform_length"), format("transform_length")]];
fn transform_length(Length length) {
return length.length;
};
enum Tag : u8 {
NULL = 0x00,
LockControl = 0x01,
MemoryControl = 0x02,
NDEFMessage = 0x03,
Proprietary = 0xFD,
TerminatorTLV = 0xFE
};
struct TLV {
Tag tag;
if (tag == Tag::TerminatorTLV) {
break;
} else if (tag == Tag::NULL) {
// Empty
} else {
Length length;
if (length > 0) {
if (tag == Tag::LockControl) {
LockControl lockControl;
} else if (tag == Tag::MemoryControl) {
LockControl lockControl;
} else if (tag == Tag::NDEFMessage) {
NDEF ndef[while(true)];
} else {
u8 value[length];
}
}
}
};
struct ManufacturerData {
u8 serial1[3];
u8 checkByte0;
u8 serial2[4];
u8 checkByte1;
u8 internal;
u16 lockBytes;
};
struct DynamicLockBytes {
u8 bytes[3];
padding[1];
};
bitfield MIRROR {
MIRROR_CONF : 2;
MIRROR_BYTE : 2;
padding : 1;
STRG_MOD_EN : 1;
padding : 2;
} [[left_to_right]];
bitfield ACCESS {
PROT : 1;
CFGLCK : 1;
padding : 1;
NFC_CNT_EN : 1;
NFC_CNT_PWD_PROT : 1;
AUTHLIM : 3;
};
struct Config {
MIRROR MIRROR;
u8 MIRROR_PAGE;
u8 AUTH0;
ACCESS ACCESS;
u32 PWD;
u16 PACK;
};
struct NTAG {
ManufacturerData manufacturerData;
CapabilityContainer cc;
TLV tlv[while(true)];
padding[addressof(tlv) + cc.memorySize * 8 - sizeof(tlv)];
DynamicLockBytes dynamicLockBytes;
Config config;
};
NTAG ntag @ 0x00;

29
patterns/ogg.hexpat Normal file
View File

@@ -0,0 +1,29 @@
#pragma MIME audio/ogg
#include <std/core.pat>
#include <std/mem.pat>
bitfield HeaderType {
Continuation : 1;
BeginOfStream : 1;
EndOfStream : 1;
};
struct SegmentData {
u8 data[parent.segmentTable[std::core::array_index()]];
};
struct Ogg {
char capturePattern[4];
u8 version;
HeaderType headerType;
u64 granulePosition;
u32 bitstreamSerialNumber;
u32 pageSequenceNumber;
u32 checksum;
u8 pageSegments;
u8 segmentTable[pageSegments];
SegmentData data[pageSegments];
};
Ogg ogg[while(!std::mem::eof())] @ 0x00;

30
patterns/pbzx.hexpat Normal file
View File

@@ -0,0 +1,30 @@
// pbzx compression stream
// Used by Apple on .xip files and OTA updates.
//
// Copyright (c) 2022 Nicolás Alvarez <nicolas.alvarez@gmail.com>
//
// SPDX-License-Identifier: GPL-2.0-or-later
#include <std/mem.pat>
#pragma endian big
#define SHOW_DATA 0
struct Chunk {
u64 uncompressed_size;
u64 compressed_size;
if (SHOW_DATA) {
u8 data[compressed_size] [[sealed]];
} else {
padding[compressed_size];
}
};
struct PBZX {
char magic[4];
u64 chunk_size;
Chunk chunks[while(!std::mem::eof())];
};
PBZX pbzx @ 0;

52
patterns/pcx.hexpat Normal file
View 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;

File diff suppressed because it is too large Load Diff

38
patterns/pfs0.hexpat Normal file
View 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;

View File

@@ -1,36 +1,90 @@
#pragma MIME image/png
#pragma endian big
struct header_t
{
struct header_t {
u8 highBitByte;
char signature[3];
char dosLineEnding[2];
char dosEOF;
char unixLineEnding;
char signature[3];
char dosLineEnding[2];
char dosEOF;
char unixLineEnding;
};
struct ihdr_t
{
struct actl_t {
u32 frames [[comment("Total № of frames in animation")]];
u32 plays [[comment("№ of times animation will loop")]];
} [[comment("Animation control chunk"), name("acTL")]];
enum ColorType: u8 {
Grayscale = 0x0,
RGBTriple = 0x2,
Palette,
GrayscaleAlpha,
RGBA = 0x6
};
enum Interlacing: u8 {
None,
Adam7
};
struct ihdr_t {
u32 width [[comment("Image width")]];
u32 height [[comment("Image height")]];
u8 bit_depth;
u8 color_type [[comment("PNG Image Type\n0: greyscale\n2: truecolour\n3: indexed-color\n4: greyscale with alpha\n6: truecolour with alpha")]];
u8 compression_method;
u8 filter_method;
u8 interlace_method [[comment("values 0 \"no interlace\" or 1 \"Adam7 interlace\"")]];
ColorType color_type [[comment("PNG Image Type")]];
u8 compression_method [[comment("Only 0x0 = zlib supported by most")]];
u8 filter_method [[comment("Only 0x0 = adaptive supported by most")]];
Interlacing interlacing;
};
struct palette_entry_t {
u8 r;
u8 g;
u8 b;
enum sRGB: u8 {
Perceptual = 0x0,
RelativeColorimetric,
Saturation,
AbsoluteColorimetric
};
enum Unit: u8 {
Unknown,
Meter
};
struct phys_t {
u32 ppu_x [[comment("Pixels per unit, X axis")]];
u32 ppu_y [[comment("Pixels per unit, Y axis")]];
u8 unit [[comment("Unit Specifier\n0: unit is unknown\n1: unit is the metre")]];
Unit unit;
};
enum BlendOp: u8 {
Source = 0x0,
Over
};
enum DisposeOp: u8 {
None = 0x0,
Background,
Previous
};
struct fctl_t {
u32 sequence_no [[comment("Sequence №")]];
u32 width [[comment("Frame width")]];
u32 height;
u32 xoff;
u32 yoff;
u16 delay_num;
u16 delay_den;
DisposeOp dispose_op;
BlendOp blend_op;
};
struct fdat_t {
u32 sequence_no;
};
fn text_len() {
u64 len = parent.parent.length - ($ - addressof(parent.keyword));
return len;
};
struct itxt_t {
@@ -39,48 +93,92 @@ struct itxt_t {
u8 compression_method;
char language_tag[];
char translated_keyword[];
char text[parent.length - ($ - addressof(keyword))];
char text[text_len()];
};
struct ztxt_t {
char keyword[];
u8 compression_method;
char text[text_len()];
};
struct text_t {
char keyword[];
char text[text_len()];
};
struct iccp_t {
char profile [];
u8 compression_method;
u8 compressed_profile[parent.length - ($ - addressof(profile))];
char keyword[];
u8 compression_method;
u8 compressed_profile[text_len()];
};
struct palette_entry_t {
u24 color;
} [[inline]];
struct chunk_t {
u32 length [[color("17BECF")]];
char type[4];
char name[4];
#define IHDR_k "IHDR"
#define PLTE_k "PLTE"
#define sRGB_k "sRGB"
#define pHYs_k "pHYs"
#define iTXt_k "iTXt"
#define tEXt_k "tEXt"
#define zTXt_k "zTXt"
#define IDAT_k "IDAT"
#define IEND_k "IEND"
#define gAMA_k "gAMA"
#define iCCP_k "iCCP"
#define acTL_k "acTL"
#define fdAT_k "fdAT"
#define fcTL_k "fcTL"
if (type == IHDR_k) {
if (name == IHDR_k) {
ihdr_t ihdr [[comment("Image Header chunk"), name("IHDR")]];
} else if (type == PLTE_k) {
} else if (name == PLTE_k) {
palette_entry_t entries[length / 3];
} else if (type == pHYs_k) {
} else if (name == sRGB_k) {
sRGB srgb;
} else if (name == pHYs_k) {
phys_t phys;
} else if (type == iTXt_k) {
} else if (name == acTL_k) {
actl_t actl [[comment("Animation control chunk")]];
} else if (name == fcTL_k) {
fctl_t fctl [[comment("Frame control chunk")]];
} else if (name == iTXt_k) {
itxt_t text;
} else if (type == gAMA_k) {
} else if (name == gAMA_k) {
u32 gamma [[name("image gamma"), comment("4 byte unsigned integer representing gamma times 100000")]];
} else if (type == iCCP_k) {
} else if (name == iCCP_k) {
iccp_t iccp;
} else if (name == tEXt_k) {
text_t text;
} else if (name == zTXt_k) {
ztxt_t text;
} else if (name == iCCP_k) {
iccp_t iccp;
} else if (name == fdAT_k) {
fdat_t fdat [[comment("Frame data chunk")]];
u8 data[length-sizeof(u32)];
} else {
u8 data[length];
}
u32 crc;
} [[format("chunkValueName")]];
fn chunkValueName(ref chunk_t chunk) {
return chunk.name;
};
struct chunk_set {
chunk_t chunks[while(builtin::std::mem::read_string($ + 4, 4) != "IEND")] [[inline]];
} [[inline]];
header_t header @ 0x00 [[comment("PNG file signature"), name("Signature")]];
chunk_t ihdr_chunk @ 0x08 [[comment("PNG Header chunk"), name("IHDR")]];
chunk_t chunk_set[while(builtin::std::mem::read_string($ + 4, 4) != "IEND")] @ $ [[comment("PNG file chunks"), name("Chunks"), inline]];
chunk_t iend_chunk @ $ [[name("IEND"), comment("Image End Chunk")]];
chunk_set set @ $ [[comment("PNG Chunks"), name("Chunks"), inline]];
chunk_t iend_chunk @ $ [[comment("Image End Chunk"), name("IEND")]];

66
patterns/protobuf.hexpat Normal file
View File

@@ -0,0 +1,66 @@
#include <std/mem.pat>
#include <type/leb128.pat>
struct ZigZag32 {
u32 value;
} [[sealed, format("format_zigzag32")]];
fn format_zigzag32(ZigZag32 zigzag) {
return s32((s32(zigzag.value) << 1) ^ (s32(zigzag.value) >> 31));
};
struct ZigZag64 {
u64 value;
} [[sealed, format("format_zigzag64")]];
fn format_zigzag64(ZigZag64 zigzag) {
return s64((s64(zigzag.value) << 1) ^ (s64(zigzag.value) >> 63));
};
enum WireType : u8 {
Varint = 0,
_64Bit = 1,
LengthDelimited = 2,
StartGroup = 3,
EndGroup = 4,
_32Bit = 5
};
bitfield Key {
field_number : 5;
wire_type : 3;
} [[left_to_right]];
union _64Bit {
u64 fixed64;
ZigZag64 sfixed64;
double dbl;
};
union _32Bit {
u32 fixed32;
ZigZag32 sfixed32;
float flt;
};
struct LengthDelimited {
type::LEB128 length;
char data[length];
};
struct Entry {
Key key;
if (key.wire_type == WireType::Varint)
type::LEB128 value;
else if (key.wire_type == WireType::_64Bit)
_64Bit value;
else if (key.wire_type == WireType::LengthDelimited)
LengthDelimited value;
else if (key.wire_type == WireType::_32Bit)
_32Bit value;
};
Entry entries[while(!std::mem::eof())] @ 0x00;

115
patterns/sit5.hexpat Normal file
View File

@@ -0,0 +1,115 @@
// Based on https://github.com/mietek/theunarchiver/wiki/StuffIt5Format and https://github.com/ParksProjets/Maconv/blob/master/docs/stuffit/Stuffit_v5.md
#pragma endian big
#pragma MIME application/x-stuffit
#include <std/io.pat>
#include <std/time.pat>
namespace v5 {
bitfield Flags1 {
padding : 1;
folder : 1;
encrypted : 1;
padding : 5;
} [[left_to_right]];
bitfield Flags2 {
padding : 7;
resource_fork : 1;
padding : 8;
} [[left_to_right]];
using MacOSHFSPlusDate = u32 [[format("v5::format_macos_date")]];
fn format_macos_date(MacOSHFSPlusDate date) {
return std::time::format(std::time::to_utc(date - 2082844800));
};
struct Header {
char magic[0x50];
u32 unknown1;
u32 archiveSize;
u32 entriesOffset;
u32 unknown2;
};
struct EntryHeader {
u32 magic;
u8 version;
u8 unknown1;
u16 headerSize;
u8 unknown2;
Flags1 flags;
MacOSHFSPlusDate creationDate, modificationDate;
u32 prevEntryOffset, nextEntryOffset, parentEntryOffset;
u16 nameSize;
u16 headerChecksum;
u32 dataForkUncompressedLength, dataForkCompressedLength;
u16 dataForkChecksum;
u16 unknown3;
};
enum CompressionMethod : u8 {
None = 0x00, // No compression
Rle90 = 0x01, // Run length encoding
Compress = 0x02, // Compress LZW algorithm, 14 bit max code length, block mode
StuffIt3 = 0x03, // Simple Huffman encoding for individual bytes
StuffIt5 = 0x05, // LZAH
StuffIt8 = 0x08, // Miller-Wegman
StuffIt13 = 0x0D, // LZSS and Huffman
Stuffit14 = 0x0E, // Unknown
StuffItArsenic = 0x0F // BWT and arithmetic coding
};
struct Entry {
EntryHeader header;
if (header.flags.folder) {
u16 numFiles;
if (header.dataForkUncompressedLength)
std::print("Folder entry {} is special!", std::core::array_index());
} else {
CompressionMethod compressionMethod;
}
u8 passwordDataLength;
u8 passwordInformation[passwordDataLength];
char fileName[header.nameSize];
u16 commentSize;
u16 unknown2;
char comment[commentSize];
if (!header.flags.folder) {
Flags2 flags;
u16 unknown3;
char fileType[4];
u32 fileCreator;
u16 macOSFinderFlags;
u32 unknown4;
u32 unknown5;
u8 unknown6[6];
if (header.version == 1)
u32 unknown7;
u8 compressedData[header.dataForkCompressedLength] [[sealed]];
if (header.nextEntryOffset == 0x00)
break;
else
$ = header.nextEntryOffset;
}
};
struct StuffIt {
Header header;
Entry entries[while(true)] @ header.entriesOffset;
};
}
v5::StuffIt stuffIt @ 0x00;

38
patterns/stl.hexpat Normal file
View File

@@ -0,0 +1,38 @@
#pragma MIME model/stl
#pragma MIME model/x.stl-binary
#pragma MIME model/x.stl-ascii
#pragma MIME application/sla
#include <std/sys.pat>
#include <std/mem.pat>
struct Vector3f {
float x, y, z;
} [[static, format("format_vector3f")]];
fn format_vector3f(Vector3f vec) {
return std::format("[ {}, {}, {} ]", vec.x, vec.y, vec.z);
};
struct Triangle {
Vector3f normal;
Vector3f points[3];
u16 flags;
} [[static]];
struct BinarySTLHeader {
char caption[];
padding[80 - sizeof(caption)];
u32 triangleCount;
};
struct STL {
if (std::mem::read_string(0, 6) == "solid ")
std::warning("ASCII STL file!");
else {
BinarySTLHeader header;
Triangle triangles[header.triangleCount];
}
};
STL stl @ 0x00;

88
patterns/tar.hexpat Normal file
View File

@@ -0,0 +1,88 @@
#pragma MIME application/tar
#pragma MIME application/x-tar
#pragma endian little
#include <std/string.pat>
#include <std/time.pat>
#include <std/mem.pat>
#include <std/sys.pat>
#define HEADER "ustar "
#define NULL "\x00"
fn octal_to_decimal(str value) {
return std::string::parse_int(value, 8);
};
fn get_time(str time) {
std::time::EpochTime epochtime = octal_to_decimal(time);
std::time::Time localtime = std::time::to_local(epochtime);
return std::time::format(localtime, "%c");
};
enum typeflagenum : char {
regular = '0',
also_regular = '\x00',
link_to_another_file_already_archived = '1',
symbolic_link = '2',
character_special_device = '3',
block_special_device = '4',
directory = '5',
fifo_special_file = '6',
reserved = '7'
};
struct posix_header {
char name[100] [[name("file name")]];
char mode[8] [[name("file mode")]];
char uid[8] [[name("user id of the file")]];
char gid[8] [[name("group if of the file")]];
char size[12] [[name("size of the file in octal")]];
char mtime[12] [[name("modified time of file in epoch time")]];
char chksum[8] [[name("checksum")]];
typeflagenum typeflag [[name("type of file")]];
char linkname[100] [[name("name of link")]];
char magic[6] [[name("magic bytes that identifies the 'file version'")]];
char version[2] [[name("version (also used with magic bytes)")]];
char uname[32] [[name("username of the owner of the file")]];
char gname[32] [[name("group name of the owner of the file")]];
char devmajor[8] [[name("major device numbers")]];
char devminor[8] [[name("minor device numbers")]];
char prefix[155] [[name("filename prefix")]];
char reserved[12] [[name("reserved")]];
};
struct tar {
posix_header header_raw;
char file[octal_to_decimal(header_raw.size)];
std::print("-" * 50);
std::print("File Name: {}", header_raw.name);
std::print("File Permissions: {}" , header_raw.mode);
std::print("UID: {}", header_raw.uid);
std::print("GUID: {}", header_raw.gid);
std::print("Size: {} bytes", octal_to_decimal(header_raw.size));
std::print("Modified Time: {}", get_time(header_raw.mtime));
std::print("Checksum: {}", header_raw.chksum);
std::print("Type of File: {}", header_raw.typeflag);
std::print("Magic Bytes: {}", header_raw.magic);
std::print("Version: {}", header_raw.version);
std::print("uname: {}", header_raw.uname);
std::print("gname: {}", header_raw.gname);
std::print("devmajor: {}", header_raw.devmajor);
std::print("devminor: {}", header_raw.devminor);
std::print("prefix: {}", header_raw.prefix);
char empty[while (std::mem::read_string($, 1) == NULL && !std::mem::eof())];
if (std::mem::eof()) {
break;
}
};
char magic[6] @ 0x00000101 [[hidden]];
std::assert(magic == HEADER, "Magic bytes are not correct! Perhaps wrong file?");
tar tar[while(!std::mem::eof())] @ 0x000;

270
patterns/usb.hexpat Normal file
View File

@@ -0,0 +1,270 @@
#include <std/io.pat>
#include <std/mem.pat>
#include <std/string.pat>
enum DescriptorType : u8 {
DeviceDescriptor = 0x01,
ConfigDescriptor = 0x02,
StringDescriptor = 0x03,
InterfaceDescriptor = 0x04,
EndpointDescriptor = 0x05,
DeviceQualifierDescriptor = 0x06,
OtherSpeedConfigurationDescriptor = 0x07,
InterfacePowerDescriptor = 0x08,
OTGDescriptor = 0x09,
DebugDescriptor = 0x0A,
InterfaceAssociationDescriptor = 0x0B,
HIDDescriptor = 0x21,
ReportDescriptor = 0x22,
PhysicalDescriptor = 0x23
};
enum InterfaceClass : u8 {
UseClassInformationInInterfaceDescriptors = 0x00,
Audio = 0x01,
CommunicationAndCDCControl = 0x02,
HID = 0x03,
Physical = 0x05,
Image = 0x06,
Printer = 0x07,
MassStorage = 0x08,
Hub = 0x09,
CDCData = 0x0A,
SmartCard = 0x0B,
ContentSecurity = 0x0C,
Video = 0x0E,
PersonalHealthcare = 0x0F,
AudioVideoDevice = 0x10,
BillboardDevice = 0x11,
USBTypeCBridge = 0x12,
I3CDevice = 0x3C,
DiagnosticDevice = 0xDC,
WirelessController = 0xE0,
Miscellaneous = 0xEF,
ApplicationSpecific = 0xFE,
VendorSpecific = 0xFF
};
enum CountryCode : u8 {
NotSupported = 0,
Arabic = 1,
Belgian = 2,
CanadianBilingual = 3,
CanadianFrench = 4,
CzechRepublic = 5,
Danish = 6,
Finnish = 7,
French = 8,
German = 9,
Greek = 10,
Hebrew = 11,
Hungary = 12,
International = 13,
Italian = 14,
JapanKatakana = 15,
Korean = 16,
LatinAmerican = 17,
Dutch = 18,
Norwegian = 19,
PersianFarsi = 20,
Polish = 21,
Portuguese = 22,
Russian = 23,
Slovakian = 24,
Spanish = 25,
Swedish = 26,
SwissFrench = 27,
SwissGerman = 28,
Switzerland = 29,
Taiwan = 30,
TurkishQ = 31,
EnglishUK = 32,
EnglishUS = 33,
Yugoslavian = 34,
TurkishF = 35,
Reserved = 36 ... 255
};
enum HubInterfaceSubClass : u8 {
Hub = 0x00
};
enum AudioVideoDeviceSubClass : u8 {
AVControlInterface = 0x01,
AVDataVideoStreamingInterface = 0x02,
AVDataAudioStreamingInterface = 0x03
};
enum HubInterfaceProtocol : u8 {
FullSpeedHub = 0x00,
HiSpeedHubWithSingleTT = 0x01,
HiSpeedHubWithMultipleTTs = 0x02
};
struct Ampere {
u8 amps;
} [[sealed, format("format_ampere")]];
fn format_ampere(Ampere ampere) {
return std::format("{} mA", ampere.amps * 2);
};
bitfield ConfigAttributes {
padding : 1;
SelfPowered : 1;
RemoteWakeup : 1;
padding : 5;
} [[left_to_right]];
struct BCD<auto Size> {
u8 bytes[Size];
} [[sealed, format("format_bcd")]];
fn format_bcd(ref auto bcd) {
str result;
for (s8 i = sizeof(bcd.bytes) - 1, i >= 0, i -= 1)
result += std::format("{:X}.", bcd.bytes[i]);
return std::string::substr(result, 0, std::string::length(result) - 1);
};
struct DeviceDescriptor {
BCD<2> bcdUSB;
InterfaceClass bDeviceClass;
if (bDeviceClass == InterfaceClass::Hub) {
HubInterfaceSubClass bDeviceSubClass;
if (bDeviceSubClass == HubInterfaceSubClass::Hub)
HubInterfaceProtocol bDeviceSubClass;
else
u8 bDeviceSubClass;
} else if (bDeviceClass == InterfaceClass::AudioVideoDevice) {
AudioVideoDeviceSubClass bDeviceSubClass;
u8 bDeviceSubClass;
} else {
u8 bDeviceSubClass;
u8 bDeviceSubClass;
}
};
struct ConfigDescriptor {
u16 wTotalLength;
u8 bNumInterfaces;
u8 bConfigurationValue;
u8 iConfiguration;
ConfigAttributes bmAttributes;
Ampere bMaxPower;
};
struct StringDescriptor {
char bString[parent.bLength - 2];
};
struct InterfaceDescriptor {
u8 bInterfaceNumber;
u8 bAlternateSetting;
u8 bNumEndpoints;
InterfaceClass bInterfaceClass;
if (bInterfaceClass == InterfaceClass::Hub) {
HubInterfaceSubClass bInterfaceSubClass;
if (bInterfaceSubClass == HubInterfaceSubClass::Hub)
HubInterfaceProtocol bInterfaceProtocol;
else
u8 bInterfaceProtocol;
} else if (bInterfaceClass == InterfaceClass::AudioVideoDevice) {
AudioVideoDeviceSubClass bInterfaceSubClass;
u8 bInterfaceProtocol;
} else {
u8 bInterfaceSubClass;
u8 bInterfaceProtocol;
}
u8 iInterface;
};
enum EndpointDirection : u8 {
OUT = 0,
IN = 1
};
fn format_direction(u8 value) {
EndpointDirection direction;
direction = value;
return direction;
};
bitfield EndpointAddress {
Direction : 1 [[format("format_direction")]];
padding : 3;
EndpointNumber : 4;
} [[left_to_right]];
bitfield EndpointAttributes {
TransferType : 2;
SynchronizationType : 2;
UsageType : 2;
} [[right_to_left]];
struct EndpointDescriptor {
EndpointAddress bEndPointAddress;
EndpointAttributes bmAttributes;
u16 wMaxPacketSize;
u8 bInterval;
};
struct OtherSpeedConfigurationDescriptor {
ConfigDescriptor content [[inline]];
};
struct DeviceQualifierDescriptor {
DeviceDescriptor deviceDescriptor [[inline]];
u8 bMaxPacketSize0;
u8 bNumConfigurations;
padding[1];
};
bitfield OTGAttributes {
SRPSupport : 1;
HNPSupport : 1;
} [[right_to_left]];
struct OTGDescriptor {
OTGAttributes bmAttributes;
};
struct HIDDescriptor {
BCD<2> bcdVersion;
CountryCode bCountryCode;
u8 bNumDescriptors;
DescriptorType bDescriptorType;
u16 wDescriptorLength;
};
struct USBDescriptor {
u8 bLength;
DescriptorType bDescriptorType;
if (bDescriptorType == DescriptorType::DeviceDescriptor)
DeviceDescriptor deviceDescriptor [[inline]];
else if (bDescriptorType == DescriptorType::ConfigDescriptor)
ConfigDescriptor configDescriptor [[inline]];
else if (bDescriptorType == DescriptorType::StringDescriptor)
StringDescriptor stringDescriptor [[inline]];
else if (bDescriptorType == DescriptorType::InterfaceDescriptor)
InterfaceDescriptor interfaceDescriptor [[inline]];
else if (bDescriptorType == DescriptorType::EndpointDescriptor)
EndpointDescriptor endpointDescriptor [[inline]];
else if (bDescriptorType == DescriptorType::OtherSpeedConfigurationDescriptor)
OtherSpeedConfigurationDescriptor otherSpeedConfigurationDescriptor [[inline]];
else if (bDescriptorType == DescriptorType::DeviceQualifierDescriptor)
DeviceQualifierDescriptor deviceQualifierDescriptor [[inline]];
else if (bDescriptorType == DescriptorType::OTGDescriptor)
OTGDescriptor otgDescriptor [[inline]];
else if (bDescriptorType == DescriptorType::HIDDescriptor)
HIDDescriptor hidDescriptor [[inline]];
padding[bLength - ($ - addressof(this))];
};
USBDescriptor descriptors[while(!std::mem::eof())] @ 0x00;

193
patterns/vhdx.hexpat Normal file
View File

@@ -0,0 +1,193 @@
#include <std/io.pat>
#include <std/ptr.pat>
#include <std/core.pat>
#include <type/guid.pat>
#include <type/size.pat>
struct FileTypeIdentifier {
char signature[8];
char16 creator[256];
padding[0x1'0000 - sizeof(signature) - sizeof(creator)];
};
struct DataSector {
u32 sequenceHigh;
u8 data[4084];
u32 sequenceLow;
} [[static]];
struct ZeroDescriptor {
padding[4];
u64 zeroLength;
DataSector *dataSector : u64;
u64 sequenceNumber;
} [[static]];
struct DataDescriptor {
u32 trailingBytes;
u64 leadingBytes;
DataSector *dataSector : u64;
u64 sequenceNumber;
} [[static]];
struct LogDescriptor {
char signature[4];
if (signature == "zero")
ZeroDescriptor descriptor [[inline]];
else if (signature == "desc")
DataDescriptor descriptor [[inline]];
};
struct LogEntry {
char signature[4];
u32 checksum;
type::Size32 entryLength;
u32 tail;
u64 sequenceNumber;
u32 descriptorCount;
padding[4];
type::GUID logGuid;
u64 flushedFileOffset;
u64 lastFileOffset;
} [[static]];
bitfield BAT {
State : 3;
padding : 17;
FileOffsetMB : 44;
} [[right_to_left]];
bitfield MetadataEntryFlags {
IsUser : 1;
IsVirtualDisk : 1;
IsRequired : 1;
padding : 29;
};
bitfield FileParameterFlags {
LeaveBlockAllocated : 1;
HasParent : 1;
padding : 30;
};
struct MetadataFileParameters {
type::Size32 blockSize;
FileParameterFlags flags;
};
struct MetadataVirtualDiskSize {
type::Size64 virtualDiskSize;
};
struct MetadataVirtualDiskID {
type::GUID virtualDiskID;
};
struct MetadataLogicalSectorSize {
type::Size32 logicalSectorSize;
};
struct MetadataPhysicalSectorSize {
type::Size32 physicalSectorSize;
};
struct ParentLocatorEntry {
u32 keyOffset;
u32 valueOffset;
u16 keyLength;
u16 valueLength;
char key[keyLength] @ addressof(parent) + keyOffset;
char value[valueLength] @ addressof(parent) + valueOffset;
};
struct MetadataParentLocator {
type::GUID locatorType;
padding[2];
u16 keyValueCount;
ParentLocatorEntry entries[keyValueCount];
};
fn metadata_relative(u128 offset) {
return addressof(parent.parent);
};
struct MetadataTableEntry {
type::GUID itemID;
if (std::core::formatted_value(itemID) == "{CAA16737-FA36-4D43-B3B6-33F0AA44E76B}")
MetadataFileParameters *data : u32 [[pointer_base("metadata_relative")]];
else if (std::core::formatted_value(itemID) == "{2FA54224-CD1B-4876-B211-5DBED83BF4B8}")
MetadataVirtualDiskSize *data : u32 [[pointer_base("metadata_relative")]];
else if (std::core::formatted_value(itemID) == "{BECA12AB-B2E6-4523-93EF-C309E000C746}")
MetadataVirtualDiskID *data : u32 [[pointer_base("metadata_relative")]];
else if (std::core::formatted_value(itemID) == "{8141BF1D-A96F-4709-BA47-F233A8FAAB5F}")
MetadataLogicalSectorSize *data : u32 [[pointer_base("metadata_relative")]];
else if (std::core::formatted_value(itemID) == "{CDA348C7-445D-4471-9CC9-E9885251C556}")
MetadataPhysicalSectorSize *data : u32 [[pointer_base("metadata_relative")]];
else if (std::core::formatted_value(itemID) == "{A8D35F2D-B30B-454D-ABF7-D3D84834AB0C}")
MetadataParentLocator *data : u32 [[pointer_base("metadata_relative")]];
else
u32 dataOffset;
type::Size32 length;
MetadataEntryFlags flags;
padding[4];
};
struct MetadataRegion {
char signature[8];
padding[2];
u16 entryCount;
padding[20];
MetadataTableEntry entries[entryCount];
};
struct RegionTableEntry {
type::GUID guid;
if (std::core::formatted_value(guid) == "{2DC27766-F623-4200-9D64-115E9BFD4A08}")
BAT *bat : u64;
else if (std::core::formatted_value(guid) == "{8B7CA206-4790-4B9A-B8FE-575F050F886E}")
MetadataRegion *metadata : u64;
else
u64 fileOffset;
type::Size32 length;
u32 required;
};
struct RegionTable {
char signature[4];
u32 checksum;
u32 entryCount;
padding[4];
RegionTableEntry entries[entryCount];
};
struct Header {
char signature[4];
u32 checksum;
u64 sequenceNumber;
type::GUID fileWriteGuid, dataWriteGuid, logGuid;
u16 logVersion;
u16 version;
type::Size32 logLength;
LogEntry *log : u64;
padding[4016];
};
struct VHDX {
FileTypeIdentifier fileTypeIdentifier;
Header header @ 0x1'0000;
Header headerBackup @ 0x2'0000;
RegionTable regionTable @ 0x3'0000;
RegionTable regionTableBackup @ 0x4'0000;
};
VHDX vhdx @ 0x00;

24
patterns/wad.hexpat Normal file
View 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;

View File

@@ -17,6 +17,7 @@ enum WaveFormatType : u16 {
Unknown,
PCM,
MS_ADPCM,
IEEEFloatingPoint,
ALAW = 6,
MULAW,
IMA_ADPCM = 0x11,
@@ -83,6 +84,10 @@ bitfield WaveMPEGFlags {
padding : 11;
};
struct WaveFormatIEEEFloatingPoint : WaveFormatPCM {
};
struct WaveFormatMPEG : WaveFormatEx {
WaveMPEGLayer headLayersUsed;
u32 headBitrate;
@@ -169,7 +174,7 @@ struct WaveListItem : WaveChunk {
} else if (chunkId == "note") {
WaveNote note;
} else {
padding[chunkSize];
padding[(chunkSize + 1) >> 1 << 1];
}
};
@@ -181,38 +186,53 @@ struct WaveList {
WaveListItem item[while ($ < listEnd)];
};
u32 paddedChunkSize;
struct WavData {
WaveChunk chunk;
paddedChunkSize = (chunk.chunkSize + 1) >> 1 << 1;
if (chunk.chunkId == "fmt ") {
WaveFormat fmt;
if (fmt.formatTag == WaveFormatType::PCM) {
WaveFormatPCM pcmExtraData;
padding[paddedChunkSize - sizeof(fmt) - sizeof(pcmExtraData)];
} else if (fmt.formatTag == WaveFormatType::MS_ADPCM) {
WaveFormatMSADPCM msAdpcmExtraData;
padding[paddedChunkSize - sizeof(fmt) - sizeof(msAdpcmExtraData)];
} else if (fmt.formatTag == WaveFormatType::MPEG) {
WaveFormatMPEG mpegExtraData;
padding[paddedChunkSize - sizeof(fmt) - sizeof(mpegExtraData)];
} else if (fmt.formatTag == WaveFormatType::MPEGLAYER3) {
WaveFormatMPEGLayer3 mpegLayer3ExtraData;
padding[paddedChunkSize - sizeof(fmt) - sizeof(mpegLayer3ExtraData)];
} else if (fmt.formatTag == WaveFormatType::IEEEFloatingPoint) {
WaveFormatIEEEFloatingPoint ieeFloatingPointExtraData;
padding[paddedChunkSize - sizeof(fmt) - sizeof(ieeFloatingPointExtraData)];
} else {
WaveFormatExDummy unknown;
padding[paddedChunkSize - sizeof(fmt) - sizeof(unknown)];
}
} else if (chunk.chunkId == "data") {
padding[chunk.chunkSize];
padding[paddedChunkSize];
} else if (chunk.chunkId == "fact") {
WaveFact fact;
padding[paddedChunkSize - sizeof(fact)];
} else if (chunk.chunkId == "smpl") {
WaveSample smpl;
padding[paddedChunkSize - sizeof(smpl)];
} else if (chunk.chunkId == "cue ") {
WaveCue cue;
padding[paddedChunkSize - sizeof(cue)];
} else if (chunk.chunkId == "LIST") {
listEnd = $ + chunk.chunkSize;
WaveList list;
padding[paddedChunkSize % 1];
} else {
padding[chunk.chunkSize];
padding[paddedChunkSize];
}
};
RiffHeader header @0x00;
WavData data[while (!std::mem::eof())] @$;
WavData data[while (!std::mem::eof())] @ $;

97
patterns/xci.hexpat Normal file
View 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;

View File

@@ -0,0 +1,52 @@
#include <std/mem.pat>
#include <std/io.pat>
struct Flags {
be u16 length;
u8 value[length];
};
struct TLV {
char tag[parent.keySize];
be u16 length;
char value[length];
};
struct Command {
be u32 value;
} [[static, sealed, format("format_command")]];
fn format_command(Command command) {
u32 x = command.value;
if (x == 0x20000000) return "NOP";
if (x == 0xAA995566) return "SYNC";
if (x == 0x000000BB) return "Bus Width Sync";
if (x == 0x11220044) return "Bus Width Detect";
if (x == 0x30002001) return "Write to FAR";
if (x == 0x28006000) return "Write to FDRO";
if (x == 0x30000001) return "Write to CRC";
if (x == 0x30018001) return "Write to IDCODE";
if (x == 0x30004000) return "Write to FDRI";
if (x == 0x30008001) return "Write to CMD";
if ((x & 0xF0000000) == 0x30000000)
return std::format("Write to Register {}", (x & 0x0003E000) >> 13);
return std::format("0x{:08X}", x);
};
struct Commands {
char tag[parent.keySize];
be u32 length;
Command commands[length / 4];
};
struct Header {
Flags flags;
be u16 keySize;
TLV tlv[4];
Commands data;
};
Header header @ 0x00;

View File

@@ -1,46 +1,60 @@
#pragma MIME application/zip
#include <std/mem.pat>
#include <std/math.pat>
struct EndOfCentralDirectory{
u32 headerSignature [[color("00000000")]];
u16 diskNum [[comment("Number of this disk "), name("Disk Number")]];
u16 diskStart [[comment("Disk where central directory starts "), name("Central Directory Disk Number")]];
u16 CDRCount [[comment("Number of central directory records on this disk"), name("Central Directory Entries")]];
u16 CentralDirectoryRecordCount [[comment("Total number of entries in the central directory"), name("Total Central Directory Entries")]];
u32 CDSize [[comment("Size of central directory (bytes)"), name("Central Directory Size")]];
u32 CDOffset [[comment("Offset of start of central directory, relative to start of archive"), name("Central Directory Offset")]];
u16 commentLength [[color("00000000")]];
char coment[commentLength] [[name("Comment")]];
struct EndOfCentralDirectory {
u32 headerSignature [[color("00000000")]];
u16 diskNum [[comment("Number of this disk "), name("Disk Number")]];
u16 diskStart [[comment("Disk where central directory starts "), name("Central Directory Disk Number")]];
u16 CDRCount [[comment("Number of central directory records on this disk"), name("Central Directory Entries")]];
u16 CentralDirectoryRecordCount [[comment("Total number of entries in the central directory"), name("Total Central Directory Entries")]];
u32 CDSize [[comment("Size of central directory (bytes)"), name("Central Directory Size")]];
u32 CDOffset [[comment("Offset of start of central directory, relative to start of archive"), name("Central Directory Offset")]];
u16 commentLength [[color("00000000")]];
char coment[commentLength] [[name("Comment")]];
};
EndOfCentralDirectory fileInfo @ std::mem::find_sequence(0,0x50,0x4B,0x05,0x06) [[name("End of Central Directory Record")]];
struct CentralDirectoryEntry{
fn find_eocd() {
// If there is no zip comment, which is the common case,
// the end-of-central-directory record will be 22 bytes long
// at the end of the file; check if size-22 has the signature.
if (std::mem::read_unsigned(std::mem::size()-22, 4, std::mem::Endian::Little) == 0x06054B50) {
return std::mem::size()-22;
} else {
// If it's not there, then there's probably a zip comment;
// search the last 64KB of the file for the signature.
// This is not entirely reliable, since the signature could
// randomly appear in compressed data before the actual EOCD,
// but it should be good enough...
u128 last64k = std::math::max(0, std::mem::size()-65536-22);
return std::mem::find_sequence_in_range(0, last64k, std::mem::size(), 0x50,0x4B,0x05,0x06);
}
};
struct CentralDirectoryFileHeader{
u32 headerSignature [[color("00000000")]];
u16 versionMade [[comment("Version file made by")]];
u16 versionExtract [[comment("Minimum version needed to extract")]];
u16 generalFlag [[comment("General purpose bit flag"), color("00000000")]];
u16 compressionMethod;
u16 fileLastModifyTime [[comment("File last modification time")]];
u16 fileLastModifyDate [[comment("File last modification date")]];
u32 crc32 [[comment("CRC-32 of uncompressed data"), color("00000000")]];
u32 compressedSize;
u32 uncompressedSize;
u16 fileNameLength [[color("00000000")]];
u16 extraFieldLength [[color("00000000")]];
u16 fileCommentLength [[color("00000000")]];
u16 diskNumber [[comment("Disk number where file starts ")]];
u16 internalFileAttributes;
u32 externalFileAttributes;
u32 fileOffset [[comment("Relative offset of local file header. This is the number of bytes between the start of the first disk on which the file occurs, and the start of the local file header. This allows software reading the central directory to locate the position of the file inside the ZIP file.")]];
char fileName[fileNameLength];
u8 extraField[extraFieldLength];
char comment[fileCommentLength];
EndOfCentralDirectory fileInfo @ find_eocd() [[name("End of Central Directory Record")]];
struct CentralDirectoryFileHeader {
u32 headerSignature [[color("00000000")]];
u16 versionMade [[comment("Version file made by")]];
u16 versionExtract [[comment("Minimum version needed to extract")]];
u16 generalFlag [[comment("General purpose bit flag"), color("00000000")]];
u16 compressionMethod;
u16 fileLastModifyTime [[comment("File last modification time")]];
u16 fileLastModifyDate [[comment("File last modification date")]];
u32 crc32 [[comment("CRC-32 of uncompressed data"), color("00000000")]];
u32 compressedSize;
u32 uncompressedSize;
u16 fileNameLength [[color("00000000")]];
u16 extraFieldLength [[color("00000000")]];
u16 fileCommentLength [[color("00000000")]];
u16 diskNumber [[comment("Disk number where file starts")]];
u16 internalFileAttributes;
u32 externalFileAttributes;
u32 fileOffset [[comment("Offset of local file header, relative to the start of the first disk on which the file occurs.")]];
char fileName[fileNameLength];
u8 extraField[extraFieldLength];
char comment[fileCommentLength];
};
CentralDirectoryFileHeader centralDirHeaders[fileInfo.CDRCount] @ (fileInfo.CDOffset) [[name("Files")]];

115
patterns/zstd.hexpat Normal file
View File

@@ -0,0 +1,115 @@
// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md
#pragma MIME application/zstd
#include <std/io.pat>
#include <std/mem.pat>
#include <std/sys.pat>
#define ZSTD_MAGIC_NUMBER 0xFD2FB528
bitfield frame_header_descriptor_t {
frame_content_size_flag : 2;
single_segment_flag : 1;
unused_bit : 1;
reserved_bit : 1;
content_checksum_flag : 1;
dictionary_id_flag : 2;
} [[left_to_right]];
bitfield window_descriptor_t {
exponent : 5;
mantissa : 3;
} [[left_to_right]];
fn window_size(window_descriptor_t window_descriptor) {
u64 window_log = 10 + window_descriptor.exponent;
u64 window_base = 1 << window_log;
u64 window_add = (window_base / 8) * window_descriptor.mantissa;
u64 window_size = window_base + window_add;
return window_size;
};
struct frame_header_t {
frame_header_descriptor_t frame_header_descriptor;
if (!frame_header_descriptor.single_segment_flag){
window_descriptor_t window_descriptor;
}
if (frame_header_descriptor.dictionary_id_flag == 1) {
le u8 dictionary_id;
}
else if (frame_header_descriptor.dictionary_id_flag == 2) {
le u16 dictionary_id;
}
else if (frame_header_descriptor.dictionary_id_flag == 3) {
le u32 dictionary_id;
}
if (frame_header_descriptor.frame_content_size_flag == 0) { // 0
if (frame_header_descriptor.single_segment_flag) {
le u8 content_size;
}
}
else if (frame_header_descriptor.frame_content_size_flag == 1) {
le u16 content_size;
}
else if (frame_header_descriptor.frame_content_size_flag == 2) {
le u32 content_size;
}
else {
le u64 content_size;
}
};
bitfield block_header_t {
block_size : 21;
block_type : 2;
last_block : 1;
} [[left_to_right]];
enum block_type : u8 {
raw_block = 0,
rle_block = 1,
compressed_block = 2,
reserved = 3
};
struct data_block_t {
block_header_t block_header;
if (block_header.last_block) {
last_block_flag = true;
}
if (block_header.block_type == block_type::raw_block) {
le u8 block_content[block_header.block_size];
}
else if (block_header.block_type == block_type::rle_block) {
le u8 block_content[1];
}
else if (block_header.block_type == block_type::compressed_block) {
le u8 block_content[block_header.block_size];
}
else {
std::error("The data block seems to be corrupted!");
}
};
struct content_checksum_t {
le u32 xxh64_hash;
};
struct zstd_frame_t {
le u32 magic_number;
std::assert(magic_number == ZSTD_MAGIC_NUMBER, "Invalid magic number!");
frame_header_t frame_header;
data_block_t data_block[while(!last_block_flag)];
if (frame_header.frame_header_descriptor.content_checksum_flag) {
content_checksum_t content_checksum;
}
};
bool last_block_flag = false;
zstd_frame_t zstd_frame @ 0x00;

View File

@@ -0,0 +1,35 @@
import json
import sys
from pathlib import Path
def extractData(projectName, jsonData, objectName, extension):
if objectName in jsonData:
with open(f"./{projectName}.{extension}", mode="w", encoding="utf-8") as output:
output.write(jsonData[objectName])
def main():
if len(sys.argv) != 2 or not str(sys.argv[1]).endswith(".hexproj"):
print(f"Usage: {sys.argv[0]} <filename.hexproj>")
exit(1)
projectPath = sys.argv[1]
with open(projectPath, mode="r", encoding="utf-8") as file:
jsonData = json.loads(file.read())
projectName = Path(projectPath).stem
extractData(projectName, jsonData, "dataProcessor", "hexnode")
extractData(projectName, jsonData, "pattern", "hexpat")
if "bookmarks" in jsonData:
with open(f"./{projectName}.hexbm", mode="w", encoding="utf-8") as output:
jsonOutput = {}
jsonOutput["bookmarks"] = jsonData["bookmarks"]
output.write(json.dumps(jsonOutput, indent=4))
if "filePath" in jsonData:
print(f"Project file used file {jsonData['filePath']}")
if __name__ == "__main__":
main()

View File

@@ -15,7 +15,7 @@ add_executable(includes_test
)
target_include_directories(includes_test PRIVATE include)
target_link_libraries(includes_test libpl)
target_link_libraries(includes_test PRIVATE libpl fmt)
set_target_properties(includes_test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})

View File

@@ -1,5 +1,8 @@
#include <pl.hpp>
#include <helpers/file.hpp>
#include <pl/helpers/file.hpp>
#include <pl/core/errors/preprocessor_errors.hpp>
#include <pl/core/errors/evaluator_errors.hpp>
#include <fmt/format.h>
#include <cstdlib>
@@ -19,18 +22,23 @@ int main(int argc, char **argv) {
fmt::print("Running test {} on test file {}\n", includeName, includeFilePath.filename().string());
// Open pattern file
pl::fs::File patternFile(includeFilePath, pl::fs::File::Mode::Read);
pl::hlp::fs::File patternFile(includeFilePath, pl::hlp::fs::File::Mode::Read);
if (!patternFile.isValid())
return EXIT_FAILURE;
// Setup Pattern Language Runtime
pl::PatternLanguage runtime;
{
constexpr auto DummyPragmaHandler = [](const auto&, const auto&){ pl::LogConsole::abortEvaluation("Include files should never use this pragma!"); return true; };
constexpr auto DummyPragmaHandler = [](const auto&, const auto&){
pl::core::err::M0006.throwError("Include files should never use this pragma!");
return false;
};
runtime.setDataSource([&](pl::u64 address, pl::u8 *data, size_t size) {
pl::LogConsole::abortEvaluation("Include files should never read from memory directly!");
}, 0x00, 0x100000);
runtime.setDataSource(0x00, 0x100000,
[&](pl::u64 address, pl::u8 *data, size_t size) {
pl::core::err::E0011.throwError("Include files should never read from memory directly!");
}
);
runtime.setDangerousFunctionCallHandler([]{ return true; });
runtime.setIncludePaths({ includePath });
@@ -40,6 +48,8 @@ int main(int argc, char **argv) {
runtime.addPragma("eval_depth", DummyPragmaHandler);
runtime.addPragma("array_limit", DummyPragmaHandler);
runtime.addPragma("pattern_limit", DummyPragmaHandler);
runtime.addDefine("__PL_UNIT_TESTS__");
}
// Execute pattern
@@ -47,14 +57,15 @@ int main(int argc, char **argv) {
fmt::print("Error during execution!\n");
if (const auto &hardError = runtime.getError(); hardError.has_value())
fmt::print("Hard error: {}\n\n", hardError.value().what());
fmt::print("Hard error: {}:{} - {}\n\n", hardError->line, hardError->column, hardError->message);
for (const auto &[level, message] : runtime.getConsoleLog()) {
switch (level) {
case pl::LogConsole::Level::Debug: fmt::print(" [DEBUG] "); break;
case pl::LogConsole::Level::Info: fmt::print(" [INFO] "); break;
case pl::LogConsole::Level::Warning: fmt::print(" [WARN] "); break;
case pl::LogConsole::Level::Error: fmt::print(" [ERROR] "); break;
using enum pl::core::LogConsole::Level;
case Debug: fmt::print(" [DEBUG] "); break;
case Info: fmt::print(" [INFO] "); break;
case Warning: fmt::print(" [WARN] "); break;
case Error: fmt::print(" [ERROR] "); break;
}
fmt::print("{}\n", message);
@@ -64,4 +75,4 @@ int main(int argc, char **argv) {
}
return EXIT_SUCCESS;
}
}

View File

@@ -17,7 +17,7 @@ find_package(PkgConfig REQUIRED)
pkg_search_module(MAGIC libmagic>=5.39)
target_include_directories(magic_test PRIVATE include)
target_link_libraries(magic_test libpl magic)
target_link_libraries(magic_test PRIVATE libpl magic fmt)
set_target_properties(magic_test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})

View File

@@ -1,5 +1,5 @@
#include <helpers/file.hpp>
#include <helpers/guards.hpp>
#include <pl/helpers/file.hpp>
#include <pl/helpers/guards.hpp>
#include <fmt/format.h>
#include <cstdlib>

View File

@@ -15,7 +15,7 @@ add_executable(patterns_tests
)
target_include_directories(patterns_tests PRIVATE include)
target_link_libraries(patterns_tests libpl)
target_link_libraries(patterns_tests PRIVATE libpl fmt)
set_target_properties(patterns_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})

View File

@@ -1,5 +1,5 @@
#include <pl.hpp>
#include <helpers/file.hpp>
#include <pl/helpers/file.hpp>
#include <fmt/format.h>
#include <cstdlib>
@@ -27,12 +27,12 @@ int main(int argc, char **argv) {
fmt::print("Running test {} on test file {}\n", patternName, testFilePath.stem().string());
// Open pattern file
pl::fs::File patternFile(patternFilePath, pl::fs::File::Mode::Read);
pl::hlp::fs::File patternFile(patternFilePath, pl::hlp::fs::File::Mode::Read);
if (!patternFile.isValid())
return EXIT_FAILURE;
// Open test file
pl::fs::File testFile(testFilePath, pl::fs::File::Mode::Read);
pl::hlp::fs::File testFile(testFilePath, pl::hlp::fs::File::Mode::Read);
if (!testFile.isValid())
return EXIT_FAILURE;
@@ -41,13 +41,16 @@ int main(int argc, char **argv) {
{
constexpr auto DummyPragmaHandler = [](const auto&, const auto&){ return true; };
runtime.setDataSource([&](pl::u64 address, pl::u8 *data, size_t size) {
testFile.seek(address);
testFile.readBuffer(data, size);
}, 0x00, testFile.getSize());
runtime.setDataSource(0x00, testFile.getSize(),
[&](pl::u64 address, pl::u8 *data, size_t size) {
testFile.seek(address);
testFile.readBuffer(data, size);
}
);
runtime.setDangerousFunctionCallHandler([]{ return true; });
runtime.setIncludePaths({ includePath });
runtime.addPragma("MIME", DummyPragmaHandler);
runtime.addDefine("__PL_UNIT_TESTS__");
}
// Execute pattern
@@ -55,14 +58,15 @@ int main(int argc, char **argv) {
fmt::print("Error during execution!\n");
if (const auto &hardError = runtime.getError(); hardError.has_value())
fmt::print("Hard error: {}\n\n", hardError.value().what());
fmt::print("Hard error: {}:{} - {}\n\n", hardError->line, hardError->column, hardError->message);
for (const auto &[level, message] : runtime.getConsoleLog()) {
switch (level) {
case pl::LogConsole::Level::Debug: fmt::print(" [DEBUG] "); break;
case pl::LogConsole::Level::Info: fmt::print(" [INFO] "); break;
case pl::LogConsole::Level::Warning: fmt::print(" [WARN] "); break;
case pl::LogConsole::Level::Error: fmt::print(" [ERROR] "); break;
using enum pl::core::LogConsole::Level;
case Debug: fmt::print(" [DEBUG] "); break;
case Info: fmt::print(" [INFO] "); break;
case Warning: fmt::print(" [WARN] "); break;
case Error: fmt::print(" [ERROR] "); break;
}
fmt::print("{}\n", message);
@@ -72,4 +76,4 @@ int main(int argc, char **argv) {
}
return EXIT_SUCCESS;
}
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More