Compare commits

...

154 Commits

Author SHA1 Message Date
paxcut
375145e759 include/std: std::ptr::relative_to_base_section not working anymore (#349)
Fixes #348 

In issue #348 it is stated that the pattern fails to find the variable baseAddress in the parent of the parent of the attribute function. One parent is required to access the variables on the pattern that is using the attribute.

That pattern is used in the pattern that contains baseAddress as a pointer to an array of the children pattern and that seems to require an extra parent level to be added in order to access baseAddress without errors. The fix was tested on an xbe file extracted from an xbox cd rom and while it failed without the fix as stated in issue 348 with the fix it ran to completion without issues.
2025-02-16 12:52:01 +01:00
paxcut
71eeed981d patterns/protobuf: Remove global variables
In issue #346 it is noted that the format functions return the same value repeatidly and erroneously. This is due to the use of global variables which result on only their last value being used in format functions due to their delayed evaluation. Fixed by using local variables instead. Also remove tabs from the file and an unused tags variable.
2025-01-30 20:24:11 +01:00
Fabian Neundorf
e779b88a58 patterns/iso: Fix incorrect condition (#344) 2025-01-23 21:44:44 +01:00
Fabian Neundorf
aef3d3451f patterns/iso: Add some improvements to the ISO pattern matching (#343)
* patterns: Load all ISO volume descriptors

* patterns: Parse supplementary volume descriptors

* patterns: Add system use in directory records for iso
2025-01-23 19:23:11 +01:00
Nik
c5fa53dcea includes/type: Make type::Formatted actually work as documented 2025-01-19 18:13:48 +01:00
The Wandering Trader
9a6cbdfe28 patterns: Add CAB pattern (#342)
* Add files via upload

* Add files via upload

* Update README.md
2025-01-19 00:13:04 +01:00
Nik
083042632d includes/hex: Hide implementation data of json types 2025-01-16 19:15:10 +01:00
Nik
4d172cebc3 patterns: Removed invalid zip test file 2025-01-14 20:07:03 +01:00
Nik
53ff0a5d62 patterns/afe2: Fixed misspelled of pragma 2025-01-14 20:06:39 +01:00
WerWolv
b3b730c6e9 patterns: Fixed various test binaries 2025-01-14 20:01:51 +01:00
Nik
8db011b6e5 patterns: Added MIME types and magic numbers to all patterns that have them 2025-01-14 20:01:36 +01:00
Nik
b936c04d21 patterns/gguf: Added #pragma magic to allow auto-loading the pattern 2025-01-14 18:21:16 +01:00
bake
bf56d4ff49 patterns: Add veado pattern (#339)
* Add veado pattern

* Add veado to README

* Add veado example file
2025-01-13 21:21:05 +01:00
Known Rabbit
fdc4a87389 patterns: Add bcss (BeyondCompare SnapShot) file (#338)
* patterns: add bcss (BeyondCompare SnapShot) file

* Add entry to readme

* Change table entries in alphabetical order

* Support both bcss file and uncompressed content

* Remove misleading cases, add warning message

* Add test cases to bcss.hexpat

* ifdef out ImHex-only functionality

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2025-01-13 21:20:36 +01:00
Mia
1f6c701348 patterns: Added sup pattern file (#337)
* Add sup pattern file

* Add files via upload

* Update README.md
2025-01-09 20:01:14 +01:00
JTurtle
4092dad428 includes/type: Fix error in float16 format function (#336) 2025-01-05 09:46:09 +01:00
Nik
559faebec3 patterns: Added simple SQLite3 database pattern 2024-12-28 19:57:48 +01:00
Nik
cde46e1f15 patterns/bgcode: Improve bgcode pattern 2024-12-28 18:51:34 +01:00
Nik
17c200a92e disassemblers/jvm: Added remaining instructions besides lookupswitch and tableswitch 2024-12-27 13:41:46 +01:00
Nik
384d4c7794 disassemblers: Added half of the JVM instructions 2024-12-27 01:07:36 +01:00
Nik
37a7e59c06 disassemblers: Added Intel 8051 architecture 2024-12-26 20:08:42 +01:00
Nik
e8cea09477 include/hex: Added definitions for new built-in types 2024-12-24 12:39:28 +01:00
Andrey Andreyevich Bienkowski
883433b260 includes/type: Fix parsing of signed leb128 (#333) 2024-12-18 21:49:16 +01:00
Nik
2db9993cb1 git: Fixed ninja package name 2024-12-18 21:45:45 +01:00
Nik
01ce565c9e git: Install ninja 2024-12-18 21:35:34 +01:00
Nik
b7b949ea27 git: Updated action runners 2024-12-18 20:53:54 +01:00
BobSmun
e026ff187e build: Improve build system (#327)
* *Add top level CMakeLists.txt, to make it easier to use both independently and from within other projects
* Add a unit_test target, to attach all unit tests to

* * Fix unit tests for windows
* Silence cmake warning regarding missing top project
* update .gitignore for vscode

---------

Co-authored-by: BobSmun <6492115+BobSmun@users.noreply.github.com>
2024-12-16 20:37:38 +01:00
Nik
63504f59a1 tests: Fixed fucked up include 2024-12-14 22:31:12 +01:00
Josef Šimánek
6113df643d git: Fix typo in readme (#332) 2024-12-14 16:35:25 +01:00
WerWolv
3f42dddd19 tests: Improve unit tests for includes and patterns 2024-12-14 16:34:27 +01:00
Luca Corbatto
2cc8868727 patterns: Added rar file pattern as requested in #258 (#324)
* Add rar file pattern as requested in #258

* Fix rar pattern

Removed some experimental (and apperantly broken) code.

* Break on EndOfArchive header instead of EOF

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-12-14 13:48:06 +01:00
Sabhya
7f02510762 patterns: Added dmp64.hexpat and test files (#331)
* [+] Added dmp64.hexpat && test files

* Fix encoding of pattern file

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-12-14 13:40:22 +01:00
Sewer.
13c4168af0 patterns/bzip3: Fixed Incorrect field on branch (#330) 2024-12-13 10:21:47 +01:00
Sewer.
1e69cd7fb2 patterns: Added BZip3 File Header Pattern (#329)
* Added: BZip3 Compression

* Fixed: Bound the SmallBlock data by parent's size

* Improved: Now uses the name 'Chunk' for block wrappers, such that the name 'block' matches with what the BZ3 API does

* Improved: Import rather than Include std::mem

* Added: Missing 'description' field in pragma
2024-12-12 21:56:13 +01:00
Sabhya
16a87df2ac patterns: Added DPAPI Blob, DPAPI MasterKey, CREDHIST patterns (#328)
* [+]Added DPAPI MasterKey & Updated README.md

* [+]Added DPAPI Blob Pattern & Updated README.md

* [+] Added CREDHIST Pattern &  Updated README.md

* [+] Test Files added for dpapimasterkey, dpapiblob & CREDHIST
2024-12-05 21:26:43 +01:00
kbugstar
b7598405b5 encodings: Added Chinese GBK encoding (#308)
Chinese Gbk encoding file
2024-12-01 17:19:14 +01:00
WerWolv
d14f8de459 includes/std: Added new palette control functions 2024-12-01 17:15:24 +01:00
WerWolv
4c96bfbeb3 patterns/fs: Fixed pattern and uploaded test data 2024-11-28 21:35:25 +01:00
Geky
500a3fe26e patterns: Added GBA ROM pattern (#323)
* add support for cartridge size type $54

Added support for cartridge size type $54, corresponding to 1.5 MiB (96 banks).

* add missing license

* Add GBA Cartridge Header

* Update README.md

Added GBA information to README.md and corrected a typo.
2024-11-28 17:59:45 +01:00
WerWolv
5ffc583640 pattern/tiff: Fixed function parameter types 2024-11-27 20:44:56 +01:00
Nik
b9f5f1668b includes/type: Fixed use of Reinterpreter type 2024-11-24 14:53:30 +01:00
Nik
4c22f28a67 pattern/rgbds: Fixed bad include 2024-11-24 14:53:02 +01:00
Bananchiki
6f9b05b853 themes: Added One Dark theme (#322)
* Added One Dark theme

* theme: fixed spacing
2024-11-24 14:51:06 +01:00
Mrmaxmeier
c533017d0b git: Various style fixes everywhere, removing whitespaces (#321)
* repo-wide: trim trailing spaces

Note: This doesn't touch the .tbl files in encodings/ since they include
meaningful trailing spaces (`20= `)

* patterns: clean up duplicate semicolons

* ELF: add header magic check

* glTF: use type::Magic for magic value

* glTF: check that the file size in the header matches

* xgstexture: fix generics syntax for magic value

* JPEG: define hex enum with 0x00 instead of 0X00

* CI: update deprecated actions

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-11-24 11:41:26 +01:00
Dexrn ZacAttack
221fa70a67 patterns: Added Miles Sound System Compressed Archive (MSSCMP) (#320)
* MSSCMP readme

* Add files via upload
2024-11-24 11:39:43 +01:00
Dexrn ZacAttack
661e5b7081 patterns: Added RAD Game Tools BINKA hexpat (#319)
* Binka readme

* Binka hexpat
2024-11-24 11:39:22 +01:00
Geky
7d0bbd1e24 patterns/GameBoy: Add support for cartridge size type $54 and missing licenses (#318)
* add support for cartridge size type $54

Added support for cartridge size type $54, corresponding to 1.5 MiB (96 banks).

* add missing license
2024-11-24 11:38:54 +01:00
Maxim Savenko
55aca93a18 patterns/mp4: Add 'stsz' box definition to MP4 pattern (#317) 2024-11-24 11:38:31 +01:00
otakuxtom
255116a587 patterns/pe: Fix error when ordinalTableRVA is zero (#315)
ordinalTableRVA is not always has value. it might be zero.
Whien this happened, it will failed.

Signed-off-by: Chunhao Hung <chunhao.hung@insyde.com>
Co-authored-by: Chunhao Hung <chunhao.hung@insyde.com>
2024-11-17 14:00:43 +01:00
Luca Corbatto
79e25fdb73 patterns/zip: Added parsing of general purpose bit flag (#314)
* Add parsing of general purpose bit flag

Add "GeneralPurposeBitFlags" bitfield definition. The names are based on
the official ZIP format specification although I chose to name the
fields closer to their purpose rather than their official name. This is
intended to make reading the pattern and its output easier. Example:
official name "Language encoding flag (EFS)" my name
"filenameAndCommentAreUtf8" because this immediately explains what it
does.

I chose not to implement the specifics of the "compressionOptions" as
their meanings are specific to the compression method used and it would
make the pattern much more complicated for (in my opinion) little gain.

I also chose to unify the names of the general purpose bit filed in the
LocalFileHeader and the CentralDirectoryFileHeader. Previously, they had
different names, suggesting they might have different meaning. According
to the official docs though, these fields have the exact same meaning.

Official docs: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT

* Fix typo and remove redundant type declaration
2024-11-17 14:00:16 +01:00
Dexrn ZacAttack
c8d9a8deb7 patterns: Added Minecraft LCE LOC file pattern (#311)
* create LOC hexpat

* loc to list
2024-11-17 13:59:44 +01:00
Miku-666
1d680fbf5e patterns: Added Minecraft LCE .pck format pattern (#310) 2024-11-17 13:59:20 +01:00
Dexrn ZacAttack
bc5a55affe patterns/lcesave: Use Virtual Filesystem + ZLib support + auto endian detection (#309)
* use Virtual Filesystem + ZLib support + auto endian detection

* fix builtin

* smh how am I only noticing that I just duplicated a function for no reason

* ifdefs to fix actions moment
2024-11-17 13:58:56 +01:00
Dexrn ZacAttack
85f5541350 patterns: Added Minecraft LCE ARC file format (#307)
* Create arc.hexpat

* add test file

* mention arc

* abide by contributing.md

* use virtual filesystem

* brainfart

* ifdefs to fix github actions moment #2
2024-11-17 13:58:02 +01:00
bbbbbr
61d3e110fb patterns/gb: Add 16K and 32K arrays for ROM Banks (#305)
Having arrays for dividing the GB ROM up into ROM Banks makes it much easier to jump to and inspect data at the start and end of banks.

- 16K Banks are the typical standard
- 32K banks aren't very common but are used in a couple unlicensed Games such as those using the Wisdom Tree MBC controller
2024-11-17 13:57:45 +01:00
Hikodroid
af957389c2 patterns: Added pattern for LZNT1 compressed data (#304) 2024-11-17 13:57:23 +01:00
Hikodroid
e85645897e patterns: Added pattern for Blender project files (#303)
* patterns: Added pattern for Blender project files

* patterns/blend: Added pattern file and test data

* patterns/blend: Fix the thumbnail bugs by passing the source data by reference

* patterns/blend: Added ZSTD support and test data
2024-11-17 13:56:59 +01:00
Hikodroid
abc78d1644 patterns/fbx: Improved the FBX pattern (#302)
* patterns/fbx: Improved the FBX pattern
-Added pragma magic
-Fixed sizing of compressed contents array
-Added references
-Cleaned up whitespace

* Added missing ] bracket in README.md
2024-11-17 13:56:40 +01:00
Valentin Lenhart
46e41db0a8 patterns/pe: Use appropriate pointer for first section placement (#300) 2024-11-17 13:56:01 +01:00
Valentin Lenhart
c67dc84911 patterns/pe: Fixed off by one error in coff pattern (#299) 2024-11-17 13:55:30 +01:00
Guest257351
323898d083 patterns/lua5.1: Fixed a bug in the Lua 5.1 bytecode pattern (#298)
* Fixed a bug in the Lua 5.1 bytecode pattern

Lua 5.1 bytecode upvalue fields were incorrectly defined as a `Vector<u32>` instead of `Vector<LuaString>`.

* Fixed another bug in the lua 5.1 bytecode pattern

Lua 5.1 bytecode string sizes were incorrectly parsed as a 64-bit integer, instead of a 32-bit integer.

* Updated the Lua 5.1 bytecode pattern for 32-bit compilers.

Updated the pattern to allow for 32-bit and 64-bit integers for the size of the string length field.
2024-11-17 13:55:00 +01:00
Seth Hall
abbd25e7f6 patterns: Added Windows Notepad cache file pattern (#297)
* Added Windows Notepad Cache file parser.

* Fixed Notepad windowstate link in readme

* Added a test file for notepad-cache.hexpat
2024-11-17 13:54:29 +01:00
Martín Montané
c8ebb3eb8a includes/std: Added checks to ends_with and starts_with to prevent failure (#295)
Fixing cases where part is longer than string, this cases should both return false instead of failing.

Co-authored-by: Nik <werwolv98@gmail.com>
2024-11-17 13:54:03 +01:00
applecuckoo
bf94cb7243 patterns: Added new WebP and VGM patterns (#294)
* README: fix square bracket

* patterns: add WebP pattern

* patterns/dds: add x-dds mimetype

* patterns: add vgm pattern

* patterns/vgm: remove old pointer

* patterns/protobuf: fix field number handling

* patterns/protobuf: add .pb file extension

* patterns/uf2: updating the family IDs again

* patterns/png: add cHRM and tIME chunks

* patterns/png: whoops, old description snuck back in

* new quantized-mesh pattern

* add quantized-mesh to README, implement oct16 decoding
2024-11-17 13:53:18 +01:00
paxcut
6697fc23a4 themes: Updated the custom themes to the new text editor color palettes (#255)
* Updated the custom themes to the new text editor color palettes designed for full syntax highlighting, but the existing themes should look just like they did before.

* impr: renamed pattern-placed-variable to calculated-pointer and added view
fix: pe pattern could read past the end of file if symbol search option was turned on and input file had no symbols. In that case a StringTable array that has 1 element would be created and place at offset 0 where the size variable was set to a large number creating the error. The fix is to set the size of the array using numberOfSymbols>0

* Fix: that was a bad choice for the size of the stringTable array because  even if findSymbols is not on the file can contain symbols. This was causing the pe unit test to fail. To get the right array size use sizeof(symbolTable)>0 which will be 1 only if findSymbols is true and the file actually contains symbols
2024-11-17 13:52:30 +01:00
Nik
8a6bb6612b includes/std: Fixed standard library errors with latest nightly 2024-11-17 13:51:51 +01:00
endes0
1d66949375 patterns: Added ext4 filesystem pattern (#293)
* patterns: add ext4 volume layout pattern

* patterns: improve ext4 pattern

* patterns: remove debug pragma from ext4

* patterns: fix ext4 magic and padding

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-08-20 21:56:05 +02:00
SpaceManiac
7c65d51986 patterns/msgpack: Fixed endianess of lengths and fixint definition (#291)
* Fix endianness of msgpack ext datum lengths

* Fix formatting of negative fixints
2024-08-20 20:41:12 +02:00
BobSmun
d961271c5d includes/std: Fixed std::core::set_pattern_comment (#289) 2024-08-20 20:33:18 +02:00
applecuckoo
26d48df7dd patterns/uf2: Add new RP2xxx-related family IDs (#288)
* patterns/uf2: add family ID enum

* patterns/uf2: Fix enum spacing

* patterns: add missing description pragmas and README entries, etc.

* patterns/uf2: add reference for Family ID enum

* patterns/uf2: add new RP2xxx family IDs

* patterns/uf2: whoops (comma fix)
2024-08-09 12:39:28 +02:00
Nik
8f1f4911a0 includes/std: Fixed value display error with std::string::NullString 2024-08-07 22:12:25 +02:00
Eldred Habert
1d7cc537ed patterns: Added RGBDS object file format (#287) 2024-08-07 22:11:29 +02:00
qux-bbb
62ceaae09b patterns/lua54: Add a Lua 5.4 test file (#286) 2024-08-04 21:54:24 +02:00
Nik
4a8a6cba1b patterns/flipper_settings: Removed #pragma magic as they would give too many false positives 2024-08-03 20:14:27 +02:00
Nik
c3eb9e4126 patterns: Improved pattern descriptions 2024-08-03 17:44:37 +02:00
WerWolv
a263347414 tests: Added StuffIt5 archive 2024-08-03 15:16:48 +02:00
qux-bbb
204599a70b patterns: Added Lua 5.3 bytecode pattern (#285) 2024-08-03 14:47:07 +02:00
Jan Wiesemann
bf6ee6d02f patterns: Added pattern for Flipper Zero settings (#281)
* Added pattern for Flipper Zero settings

* Added readme entry

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-08-03 14:11:02 +02:00
qux-bbb
0125ec2c57 patterns: Added Lua 5.2 bytecode pattern (#284) 2024-08-03 14:07:50 +02:00
applecuckoo
c5aaac25dd patterns/uf2: Added Family ID enum to uf2.hexpat, Added missing description pragmas and other minor fixes (#282)
* patterns/uf2: add family ID enum

* patterns/uf2: Fix enum spacing

* patterns: add missing description pragmas and README entries, etc.

* patterns/uf2: add reference for Family ID enum
2024-08-03 10:47:40 +02:00
qux-bbb
196011ead9 patterns: Added Lua 5.1 bytecode pattern (#283) 2024-08-03 10:46:25 +02:00
xtex
5b15136ea4 patterns: Add HSDT pattern (#280)
Co-authored-by: Nik <werwolv98@gmail.com>
2024-07-27 08:38:44 +02:00
qux-bbb
59c954ae28 patterns/lua54: Removed empty line (#278)
Remove an empty line.
2024-07-26 19:52:24 +02:00
Hikodroid
8a5cb1061b patterns/fbx: Simplified the fbx hexpat (#277) 2024-07-26 19:52:01 +02:00
Hikodroid
120bc84548 patterns/fbx: Fixed the fbx hexpat (#276)
* patterns: FBX - revised hexpat for fbx files but still broken

* patterns: FBX - implemented a workaround for the previously broken hexpat

* Disable ImHex-specific functions outside of ImHex

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-07-25 00:00:11 +02:00
WerWolv
0e17355db0 tests: Added more test files 2024-07-23 21:03:17 +02:00
WerWolv
6aee524d1a patterns: Fix various patterns, added more test files 2024-07-23 20:31:43 +02:00
WerWolv
b42c571d4d patterns: Fixed run problems with some patterns 2024-07-23 18:39:05 +02:00
xndcn
71e1ad8df7 patterns/jpeg: Simplify EOI marker search (#272)
Co-authored-by: Nik <werwolv98@gmail.com>
2024-07-23 18:37:03 +02:00
WerWolv
5c7d77b50f patterns: Added Kaydara FBX Binary format
Credit to @Hikodroid
2024-07-23 18:29:02 +02:00
WerWolv
a746ecb164 tests: Moved/Renamed some test files 2024-07-23 18:24:05 +02:00
Dexrn ZacAttack
569e5c4c1a patterns: Added Minecraft LCE save format (#256)
* Add Minecraft LCE save format

* Add files to the pattern

took forever lol cuz weird syntax

* NBT parsing n stuff

* Minecraft Xbox 360 Edition saves, read description

TU033 is a pre-release version, which has a slightly different file format that I documented myself [here](https://github.com/Team-Lodestone/Documentation/blob/main/LCE/Pre-Release%20Save%20Format.md)

TU5 is a release version which uses the same file format used all the way up to latest TU (aka the last version released)

All of these saves have been decompressed from XMemCompress (iirc modified LZX)
Chunk data however is still compressed, because it's not meant to be uncompressed in the scope of reading the save.

https://github.com/Team-Lodestone/Documentation/blob/main/LCE/LCE%20File%20Versions.md

* Support Pre-Release files, JANKY file type detection, min and cur version.

* fix top comment

* LCE saves to readme
2024-07-23 18:17:02 +02:00
applecuckoo
0316f2b667 patterns: Add PKM pattern + add BCC checksum verification to ntag pattern (#274)
* patterns/ntag: add BCC checksum verification

* patterns: add PKM file pattern

* Add entry to README

* Added missing import

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-07-23 08:30:05 +02:00
WerWolv
196695e37b includes/std: Allow std::print() and std::format() to take any value as format argument again 2024-07-12 21:19:43 +02:00
WerWolv
bced518508 includes/std: Added std::mem::reached() for use with while-sized arrays 2024-07-10 21:32:55 +02:00
WerWolv
2f795fc23c includes/std: Added attrs library 2024-07-10 21:32:35 +02:00
C3pa
5ff783d571 includes: Fix various spelling errors (#270)
docs: fix some spelling errors

Related issue:
https://github.com/WerWolv/ImHex/issues/1139
2024-07-10 21:09:15 +02:00
WerWolv
4299243e95 includes/std: Added hex::dec::lz4_decompress() 2024-07-07 15:51:40 +02:00
Surasia
23b3c2b5d0 git: Fix hinf_tag and hinf_module links in readme (#268) 2024-07-07 13:44:04 +02:00
Surasia
da1c2687e8 patterns/hinf_*: Add Halo Infinite tag and module file patterns (#267)
* patterns/hinf: Add Halo Infinite Tag and Module patterns

* patterns/hinf_bitmap: remove pattern
2024-07-06 17:33:03 +02:00
WerWolv
18f968df5b includes/std: Drastically improved std::mem::MagicSearch, added find_string and find_string_in_range 2024-07-04 20:47:39 +02:00
WerWolv
f797c711ca includes/std: Optimize std::bit::popcount 2024-07-04 17:58:12 +02:00
WerWolv
5380877da4 tests: Added error message when no description is used 2024-07-04 08:28:20 +02:00
Marc Butler
bb46276bde patterns: Added Password Safe Version 3 pattern (#266)
* Add password safe V3

* Added description pragma

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-07-04 08:27:51 +02:00
Nik
4242869ac1 patterns/zlib: Cast bitfield enums to integers before doing math with them 2024-07-03 22:48:15 +02:00
WerWolv
8bdcd814a9 includes/std: Added std::unimplemented() 2024-07-02 18:00:52 +02:00
WerWolv
d7811ff5e9 patterns: Replaced old bitfield order attributes with new ones
Fixes #265
2024-07-02 18:00:41 +02:00
WerWolv
4d0b3e21bc includes/std: Added better documentation to std::mem::current_bit_offset() 2024-07-02 18:00:05 +02:00
WerWolv
acd6903b21 includes/std: Added crc8, crc16 and crc64 functions
Fixes #226
2024-07-02 17:59:40 +02:00
WerWolv
8d2a39f7d4 git: Added build folders to gitignore 2024-07-02 17:58:47 +02:00
Nik
65ef3a7783 includes/std: Removed cyclic dependency between std.mem and std.string 2024-07-01 23:47:09 +02:00
Nik
21a0b99eac includes/std: Added missing string include to std::mem 2024-06-29 23:25:58 +02:00
Rebuild
a33b68921d patterns: Added ttf/otf format (#263)
* Add ttf/otf format

* ttf: Put cff to preprocessing
2024-06-29 22:52:21 +02:00
Nik
a0bb71be58 includes/std: Added std::core::execute_function() 2024-06-29 11:53:43 +02:00
WerWolv
c7fc39ac19 git: Make sure test data is always treated as binaries 2024-06-26 20:59:41 +02:00
WerWolv
b540ead0ae includes/std: Added std::IIndexed as a nicer wrapper around std::core::array_index() 2024-06-25 22:52:57 +02:00
Nik
26878548f0 includes/std: Fixed NullString not including null terminator and not checking for string end correctly 2024-06-23 18:45:13 +02:00
C3pa
e4c9d86755 includes/std: Add some fixes from the WerWolv/Documentation repo (#262)
* Escape backslash in DOSPath docs

* Spelling correction for std\sys.pat

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-06-22 10:59:36 +02:00
WerWolv
2a3de1b705 includes: Tabs -> Spaces 2024-06-22 10:46:30 +02:00
WerWolv
e02280f9ee includes/type: Added arbitrarily formattable type 2024-06-20 21:21:42 +02:00
WerWolv
bbba68cef7 includes/std: Added null-terminated strings to the strings library 2024-06-20 21:21:30 +02:00
Joachim Schiele
28b281b403 patterns/pe: Added .didata section support (#257) 2024-06-16 15:23:01 +02:00
Kirill Gladkikh
c807959d75 patterns/jpeg: Support EOF in the middle of JPEG (#240)
* Support EOF in the middle of file

* Changed to eoi marker searching
2024-06-16 15:16:01 +02:00
Francisco J. Solis
3416d30f2b pattern/dds: Fix bitfield PixelFormatFlags (#259)
* Fix bitfield PixelFormatFlags

The padding names should not repeat
Comments should be added to each field for clarification
Padding should be corrected for luminance.

* Re-work of PixelFormatFlags

Add more information considering current GIMP repository structure
https://gitlab.gnome.org/GNOME/gimp/-/blame/master/plug-ins/file-dds/dds.h\#L145
2024-06-09 22:15:05 +02:00
iTrooz
10bf1c76cf chore: mention description pragma in PR template 2024-05-20 01:05:48 +02:00
iTrooz
5b7c212029 git: use ccache (#253) 2024-05-20 01:01:59 +02:00
iTrooz
1c2e948940 test: Make description pragma mandatory (#251) 2024-05-20 00:35:24 +02:00
iTrooz
7ea34e410a fix: add missing ; to core.pat 2024-05-20 00:13:52 +02:00
iTrooz
56950e44d8 fix: use renamed PatternRuntime::getEvalError() (#252) 2024-05-20 00:10:34 +02:00
iTrooz
ed42452fc1 chore: remove old coverage code 2024-05-20 00:01:36 +02:00
iTrooz
a68ecb8888 fix: run tests concurrently 2024-05-20 00:01:00 +02:00
WerWolv
8d4cf59497 patterns/ffx: Updated submodule 2024-05-19 17:05:56 +02:00
Benjamin Gilbert
3c2fed22e4 patterns: Add Windows animated cursor (#242)
* patterns: Add Windows animated cursor

* Added readme entry

* Added mime type to readme

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2024-05-19 16:58:03 +02:00
Christoph Koehler
ff550bd105 patterns: Add Digital Terrain Elevation Data (DTED) pattern file (#243)
Tested on DTED0 and DTED2, will likely work with DTED1 as well.
2024-05-19 16:55:30 +02:00
Rebuild
0ad6e3abde patterns/mp4: Use FixedPoint32 instead of u32 for width and height (#248)
Update mp4.hexpat

* Use FixedPoint32 instead of u32 for width and height
* Add formatting for displaying fixed point 16.16 and 8.8 numbers
2024-05-19 16:55:04 +02:00
Marijn Kneppers
891968db53 includes/std: Add create_directories to std (#250) 2024-05-19 16:46:05 +02:00
Marijn Kneppers
5799d1d7ea includes/std: Make std::file::flush not delete files (#246) 2024-05-12 23:39:49 +02:00
Marijn Kneppers
9c6bfeb50f includes/hex: Added hex::core::add_virtual_file (#247) 2024-05-12 23:38:57 +02:00
AdventureT
9f7cdded6a Crashlvl: Added support for version 0.95 (#245)
* Working on new Version

* Needs testing

* Updated CrashLvl script to support version 0.94c

* Update README.md

* Added TestData and author to script

* Delete tests/patterns/test_data/CrashLvl.hexpat.bin

* CrashLvl.hexpat: Added support for version 0.95
2024-05-12 23:38:25 +02:00
Claudius Coenen
03298b0b0c patterns: Added Wintec TES file pattern (#238) 2024-04-21 12:33:19 +02:00
LolHacksRule
5f2738872e patterns: Added XGSPak and XGSTexture patterns (#237)
* Add XGSPak and XGSTexture patterns

* Whoops forgot proper pointers

* Fix typo

* Whoops

* Proper start

* Update xgstexture.hexpat
2024-04-21 12:32:26 +02:00
nazDridoy
63585e6de7 patterns/7z: Added MIME type (#241) 2024-04-21 12:25:00 +02:00
Sabhya Raj Mehta
cb6caafa64 patterns/refs: Added Structure for MinStoreB+ node, missing GlobalRootNode Names & parses all Superblocks (#236)
[+] Added Structure for MinStoreB+ node, Missing GlobalRootNode Names
2024-03-29 11:55:01 +01:00
Leon Jacobs
236fadee47 patterns: Added gguf pattern (#235)
* (feat) add gguf parser

* (chore) cleanup empty struct

* (tests) add sample gguf for tests and update readme

* (feat) update type enum
2024-03-28 21:55:18 +01:00
GlorifiedPig
0549e62a14 patterns/tar: Fixed minor typo (#230)
changes "if" to "id"
2024-03-21 22:16:37 +01:00
Sabhya Raj Mehta
b4bf2b946f patterns/refs: Added filesystem Checking, comments, Renamed REFS_HEADER, and Fixed typo. (#231)
Added FileSystem Checking and comments && renamed struct ReFSHeader to VolumeBootRecord && Fixed Typo
2024-03-21 22:16:15 +01:00
Zwip-Zwap Zapony
5e82bfadac includes/std: Replace get_attribute_value with get_attribute_argument (#233)
Update get_attribute_argument/get_attribute_value

Replace std::core::get_attribute_value with std::core::get_attribute_argument
Mark optional arguments with square brackets in the documentation comments, and list their default values
2024-03-21 21:48:53 +01:00
Sabhya
a5c9f3b18a patterns: Added ReFS filesystem pattern (#229)
Added Pattern File For Parsing ReFS filesystem Header, SuperBlock and CheckPoint && updated README.md
2024-03-17 10:19:18 +01:00
Nik
38262e6bb9 tests/patterns: Moved xilinx bootgen test file to correct folder 2024-03-16 10:24:09 +01:00
Nik
0a37b60d70 git: Mark all test files as binary 2024-03-16 10:22:51 +01:00
Shadlock0133
345e264ff8 patterns: Add .bgcode file (#222)
Support for binary G-code files, used by 3d printers
2024-03-15 21:54:58 +01:00
syuuha
ba2c396534 patterns: Added pattern for ADTS files (#223) 2024-03-15 21:54:41 +01:00
paxcut
439f04e19b includes/std: Fixed "unknown function fm" error was shown in pattern data. (#225) 2024-03-15 21:54:03 +01:00
ogmini
eaeea8d093 patterns: Added pattern for Windows 11 Notepad Window State bin file (#228)
* Add files via upload

* Update README.md

* Update README.md

* Add files via upload

* Update Notepad-WindowState.hexpat

* Update and rename Notepad-WindowState.hexpat to notepadwindowstate.hexpat

* Rename Notepad-WindowState.hexpat.bin to notepad-windowstate.hexpat.bin

* Update README.md
2024-03-15 21:53:40 +01:00
265 changed files with 34763 additions and 2849 deletions

2
.gitattributes vendored
View File

@@ -1,2 +1,4 @@
*.pat linguist-language=Rust
*.hexpat linguist-language=Rust
tests/patterns/test_data/** binary

View File

@@ -5,7 +5,8 @@
## 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 new pattern has a description pragma (`#pragma description My pattern Description here`)
- [ ] The pattern was associated with all relevant MIME types (using `#pragma MIME mime-type` in the source code)
- Make sure to never use `application/octet-stream` here as that means "Unidentifiable binary data"
- [ ] A test file for this pattern has been added to [/tests/patterns/test_data](/tests/patterns/test_data)
- Try to keep this file below ~ 1 MB
- Try to keep this file below ~ 1 MB

View File

@@ -8,7 +8,7 @@ on:
repository_dispatch:
types: [run_tests]
workflow_dispatch:
inputs:
inputs:
generate_docs:
description: "Regenerate docs"
required: false
@@ -17,7 +17,7 @@ on:
jobs:
tests:
name: 🎯 Dispatch changes
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
env:
DISPATCH_TOKEN: ${{ secrets.DISPATCH_TOKEN }}
permissions:
@@ -27,13 +27,13 @@ jobs:
steps:
- name: 🧰 Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
submodules: recursive
- name: 📄 Check changed include files
id: changed-includes
uses: tj-actions/changed-files@v35
uses: tj-actions/changed-files@v45
with:
files: includes/**/*.pat
@@ -45,7 +45,7 @@ jobs:
repo: Documentation
owner: WerWolv
event_type: update_pl_docs
- name: ✉️ Update PatternLanguage Website
if: ${{ env.DISPATCH_TOKEN != '' }}
uses: mvasigh/dispatch-action@main

View File

@@ -11,7 +11,7 @@ on:
jobs:
tests:
name: 🧪 Unit Tests
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
permissions:
actions: read
contents: read
@@ -19,7 +19,7 @@ jobs:
steps:
- name: 🧰 Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
submodules: recursive
@@ -28,56 +28,54 @@ jobs:
sudo apt update
sudo apt install -y \
build-essential \
gcc-12 \
g++-12 \
ccache \
gcc-14 \
g++-14 \
lld \
${PKGCONF:-} \
cmake \
make \
ninja-build \
python3 \
python3-pip \
libmagic-dev \
lcov
sudo pip install jsonschema
- name: 📜 Setup ccache
uses: hendrikmuhs/ccache-action@v1
with:
key: ${{ runner.os }}-ccache-${{ github.run_id }}
restore-keys: ${{ runner.os }}-ccache
max-size: 1G
- name: 🛠️ Build
run: |
cd tests
mkdir -p build
cd build
CC=gcc-12 CXX=g++-12 cmake \
CC=gcc-14 CXX=g++-14 cmake \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_C_FLAGS="-fuse-ld=lld --coverage" \
-DCMAKE_CXX_FLAGS="-fuse-ld=lld --coverage" \
-DIMHEX_PATTERNS_ENABLE_UNIT_TESTS=ON \
-DLIBPL_ENABLE_TESTS=OFF \
-DLIBPL_ENABLE_CLI=OFF \
-G Ninja \
..
make -j4
ninja unit_tests
- name: 🧪 Perform Unit Tests
run: |
cd tests/build
ctest --output-on-failure
#- name: ⚗️ Generate Coverage Report
# run: |
# cd tests/build
# lcov -d ./_deps/pattern_language-build/lib --gcov-tool /usr/bin/gcov-12 -c -o coverage.info
#- name: ⬆️ Upload Coverage Report
# uses: coverallsapp/github-action@master
# env:
# NODE_OPTIONS: --max-old-space-size=8000
# with:
# github-token: ${{ secrets.GITHUB_TOKEN }}
# path-to-lcov: tests/build/coverage.info
cd build
ctest --output-on-failure -j 4
- name: 📎 Validate JSON Files
run: |
cd constants
for file in ./[!_schema.json]*; do jsonschema -i $file _schema.json; done
cd ..
cd tips
for file in ./[!_schema.json]*; do jsonschema -i $file _schema.json; done
cd ..

11
.gitignore vendored
View File

@@ -1,5 +1,12 @@
tests/cmake-build-debug/
tests/cmake*/
tests/build*/
build/
.vscode/
.devcontainer/
.cache/
.idea/
.DS_Store
.DS_Store
compile_commands.json

30
CMakeLists.txt Normal file
View File

@@ -0,0 +1,30 @@
cmake_minimum_required(VERSION 3.16)
project(ImHex-Patterns)
option(IMHEX_PATTERNS_ENABLE_UNIT_TESTS "Enable building unit tests for ImHex-Patterns" OFF)
# if enabled, add a unit_test custom target for all the unit tests to be registered against
if(IMHEX_PATTERNS_ENABLE_UNIT_TESTS)
if(NOT TARGET unit_tests)
enable_testing()
add_custom_target(unit_tests)
endif()
endif()
# If this has been manually cloned into another project, libpl may already have been set up
if(NOT TARGET libpl)
include(FetchContent)
FetchContent_Declare(
pattern_language
GIT_REPOSITORY https://github.com/WerWolv/PatternLanguage
GIT_TAG master
)
FetchContent_MakeAvailable(pattern_language)
endif()
if(IMHEX_PATTERNS_ENABLE_UNIT_TESTS)
add_subdirectory(tests)
endif()

View File

@@ -8,5 +8,5 @@ Thanks a lot for any additions or improvements :)
## Adding new Patterns
When adding new patterns, if possible, please also add a test file named `<pattern_name>.hexpat.<extension>` to the `/tests/patterns/test_data` directory. This allows our Unit Tests to be run against your code so we can make sure it stays up-to-date and doesn't break when changes are made to the PatternLanguage.
Please try to keep these files as small as possible (~100kiB at most) so cloning stays fast.
Please try to keep these files as small as possible (~100kiB at most) so cloning stays fast.
Please also make sure to not submit any test files that are under copyright such as game files, ROMs or files extracted from other programs. We don't want a DMCA takedown on this repo.

101
README.md
View File

@@ -1,6 +1,7 @@
# ImHex Database
This repository serves as a database for files to use with the [ImHex Hex Editor](https://github.com/WerWolv/ImHex). It currently contains
- [Patterns](/patterns) - Binary Format definitions for the Pattern Language
- [Pattern Libraries](/includes) - Libraries that make using the Pattern Language easier
- [Magic Files](/magic) - Custom magic file definitions for the use with libmagic
@@ -24,100 +25,149 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
|------|------|------|-------------|
| 3DS | | [`patterns/3ds.hexpat`](patterns/3ds.hexpat) | Autodesk 3DS Max Model file |
| 7Z | | [`patterns/7z.hexpat`](patterns/7z.hexpat) | 7z File Format |
| ADTS | `audio/x-hx-aac-adts` | [`patterns/adts.hexpat`](patterns/adts.hexpat) | ADTS/AAC audio files |
| AFE2 | | [`patterns/afe2.hexpat`](patterns/afe2.hexpat) | Nintendo Switch Atmosphère CFW Fatal Error log |
| ANI | `application/x-navi-animation` | [`patterns/ani.hexpat`](patterns/ani.hexpat) | Windows Animated Cursor file |
| AR | `application/x-archive` | [`patterns/ar.hexpat`](patterns/ar.hexpat) | Static library archive files |
| ARC | | [`patterns/arc.hexpat`](patterns/arc.hexpat) | Minecraft Legacy Console Edition ARC files |
| ARIA2 | | [`patterns/aria2.hexpat`](patterns/aria2.hexpat) | ARIA2 Download Manager Control files |
| ARM VTOR | | [`patterns/arm_cm_vtor.hexpat`](patterns/arm_cm_vtor.hexpat) | ARM Cortex M Vector Table Layout |
| Bastion | | [`patterns/bastion/*`](https://gitlab.com/EvelynTSMG/imhex-bastion-pats) | Various [Bastion](https://en.wikipedia.org/wiki/Bastion_(video_game)) files |
| BeyondCompare BCSS | | [`patterns/bcss.hexpat`](patterns/bcss.hexpat) | BeyondCompare Snapshot (BCSS) file |
| Bencode | `application/x-bittorrent` | [`patterns/bencode.hexpat`](patterns/bencode.hexpat) | Bencode encoding, used by Torrent files |
| Prusa BGCODE | | [`patterns/bgcode.hexpat`](patterns/bgcode.hexpat) | PrusaSlicer Binary G-Code files |
| BLEND | | [`patterns/blend.hexpat`](patterns/blend.hexpat) | Blender Project file |
| BMP | `image/bmp` | [`patterns/bmp.hexpat`](patterns/bmp.hexpat) | OS2/Windows Bitmap files |
| BIN | | [`patterns/selinux.hexpat`](patterns/selinux.pat) | SE Linux modules |
| BINKA | | [`patterns/binka.hexpat`](patterns/binka.pat) | RAD Game Tools Bink Audio (BINKA) files |
| BSON | `application/bson` | [`patterns/bson.hexpat`](patterns/bson.hexpat) | BSON (Binary JSON) format |
| bplist | | [`patterns/bplist.hexpat`](patterns/bplist.hexpat) | Apple's binary property list format (bplist) |
| bplist | `application/x-bplist` | [`patterns/bplist.hexpat`](patterns/bplist.hexpat) | Apple's binary property list format (bplist) |
| BSP | | [`patterns/bsp_goldsrc.hexpat`](patterns/bsp_goldsrc.hexpat) | GoldSrc engine maps format (used in Half-Life 1) |
| BZIP3 | | [`patterns/bzip3.hexpat`](patterns/bzip3.hexpat) | GoldSrc engine maps format (used in Half-Life 1) |
| CAB | | [`patterns/cab.hexpat`](patterns/cab.hexpat) | Microsoft Cabinet (CAB) Files |
| CCHVA | | [`patterns/cchva.hexpat`](patterns/cchva.hexpat) | Command and Conquer Voxel Animation |
| CCVXL | | [`patterns/ccvxl.hexpat`](patterns/ccvxl.hexpat) | Command and Conquer Voxel Model |
| CCPAL | | [`patterns/ccpal.hexpat`](patterns/ccpal.hexpat) | Command and Conquer Voxel Palette |
| CDA | | [`patterns/cda.hexpat`](patterns/cda.hexpat) | Compact Disc Audio track |
| CHM | | [`patterns/chm.hexpat`](patterns/chm.hexpat) | Windows HtmlHelp Data (ITSF / CHM) |
| CHM | `application/vnd.ms-htmlhelp` | [`patterns/chm.hexpat`](patterns/chm.hexpat) | Windows HtmlHelp Data (ITSF / CHM) |
| COFF | `application/x-coff` | [`patterns/coff.hexpat`](patterns/coff.hexpat) | Common Object File Format (COFF) executable |
| CPIO | `application/x-cpio` | [`patterns/cpio.hexpat`](patterns/cpio.hexpat) | Old Binary CPIO Format |
| CrashLvl | | [`patterns/Crashlvl.hexpat`](patterns/Crashlvl.hexpat) | Crash Bandicoot - Back in Time (fan game) User created level format |
| CREDHIST | | [`patterns/credhist.hexpat`](patterns/credhist.hexpat) | CREDHIST Format |
| DDS | `image/vnd-ms.dds` | [`patterns/dds.hexpat`](patterns/dds.hexpat) | DirectDraw Surface |
| DEX | | [`patterns/dex.hexpat`](patterns/dex.hexpat) | Dalvik EXecutable Format |
| DICOM | `application/dicom` | [`patterns/dicom.hexpat`](patterns/dicom.hexpat) | DICOM image format |
| DMG | | [`patterns/dmg.hexpat`](patterns/dmg.hexpat) | Apple Disk Image Trailer (DMG) |
| DMP | | [`patterns/dmp64.hexpat`](patterns/dmp64.hexpat) | Windows Kernel Dump(DMP64) |
| DPAPI_Blob | | [`patterns/dpapblob.hexpat`](patterns/dpapiblob.hexpat) | Data protection API Blob File Format |
| DPAPI_MasterKey | | [`patterns/dpapimasterkey.hexpat`](patterns/dpapimasterkey.hexpat) | Data protection API MasterKey |
| DS_Store | | [`patterns/dsstore.hexpat`](patterns/dsstore.hexpat) | .DS_Store file format |
| DTA | | [`patterns/max_v104.hexpat`](patterns/max_v104.hexpat) | Mechanized Assault and Exploration v1.04 (strategy game) save file format |
| DTED | | [`patterns/dted.hexpat`](patterns/dted.hexpat) | Digital Terrain Elevation Data (DTED) |
| ELF | `application/x-executable` | [`patterns/elf.hexpat`](patterns/elf.hexpat) | ELF header in elf binaries |
| EVTX | | [`patterns/evtx.hexpat`](patterns/evtx.hexpat) | MS Windows Vista Event Log |
| EVTX | `application/x-ms-evtx` | [`patterns/evtx.hexpat`](patterns/evtx.hexpat) | MS Windows Vista Event Log |
| EXT4 | | [`patterns/ext4.hexpat`](patterns/ext4.hexpat) | Ext4 filesystem |
| FAS | | [`patterns/fas_oskasoftware.hexpat`](patterns/fas_oskasoftware.hexpat) [`patterns/fas_oskasoftware_old.hexpat`](patterns/fas_oskasoftware_old.hexpat) (Old versions of Oska DeskMate) | Oska Software DeskMates FAS (Frames and Sequences) file |
| FBX | | [`patterns/fbx.hexpat`](patterns/fbx.hexpat) | Kaydara FBX Binary |
| FDT | | [`patterns/fdt.hexpat`](patterns/fdt.hexpat) | Flat Linux Device Tree blob |
| FFX | | [`patterns/ffx/*`](https://gitlab.com/EvelynTSMG/imhex-ffx-pats) | Various Final Fantasy X files |
| File System | | [`patterns/fs.hexpat`](patterns/fs.hexpat) | Drive File System |
| File System | `application/x-ima` | [`patterns/fs.hexpat`](patterns/fs.hexpat) | Drive File System |
| FLAC | `audio/flac` | [`patterns/flac.hexpat`](patterns/flac.hexpat) | Free Lossless Audio Codec, FLAC Audio Format |
| GB | `application/x-gameboy-rom` | [`patterns/gb.hexpat`](patterns/gb.hexpat) | Gameboy ROM |
| Flipper Zero Settings | | [`patterns/flipper_settings.hexpat`](patterns/flipper_settings.hexpat) | Flipper Zero Settings Files |
| GB | `application/x-gameboy-rom` | [`patterns/gb.hexpat`](patterns/gb.hexpat) | Game Boy ROM |
| GBA | `application/x-gameboy-advance-rom` | [`patterns/gba.hexpat`](patterns/gba.hexpat) | Game Boy Advance ROM header |
| GGUF | | [`patterns/gguf.hexpat`](patterns/gguf.hexpat) | GGML Inference Models |
| GIF | `image/gif` | [`patterns/gif.hexpat`](patterns/gif.hexpat) | GIF image files |
| GLTF | `model/gltf-binary` | [`patterns/gltf.hexpat`](patterns/gltf.hexpat) | GL Transmission Format binary 3D model file |
| GZIP | `application/gzip` | [`patterns/gzip.hexpat`](patterns/gzip.hexpat) | GZip compressed data format |
| Halo Bitmap || [`patterns/hinf_bitmap.hexpat`](patterns/hinf_bitmap.hexpat) | Halo Infinite Bitmap tag files |
| Halo Tag || [`patterns/hinf_tag.hexpat`](patterns/hinf_tag.hexpat) | Halo Infinite Tag Files |
| Halo Module || [`patterns/hinf_module.hexpat`](patterns/hinf_module.hexpat) | Halo Infinite Module Archive Files |
| Halo HavokScript || [`patterns/hinf_luas.hexpat`](patterns/hinf_luas.hexpat) | Halo Infinite HavokScript 5.1 Bytecode |
| HSDT || [`patterns/hsdt.hexpat`](patterns/hsdt.hexpat) | HiSilicon device-tree table images |
| ICO | | [`patterns/ico.hexpat`](patterns/ico.hexpat) | Icon (.ico) or Cursor (.cur) files |
| ID3 | `audio/mpeg` | [`patterns/id3.hexpat`](patterns/id3.hexpat) | ID3 tags in MP3 files |
| Intel HEX | | [`patterns/intel_hex.hexpat`](patterns/intel_hex.hexpat) | [Intel hexadecimal object file format definition]("https://en.wikipedia.org/wiki/Intel_HEX") |
| IP | | [`patterns/ip.hexpat`](patterns/ip.hexpat) | Ethernet II Frames (IP Packets) |
| IPS | | [`patterns/ips.hexpat`](patterns/ips.hexpat) | IPS (International Patching System) files |
| ISO | | [`patterns/iso.hexpat`](patterns/iso.hexpat) | ISO 9660 file system |
| ISO | `application/x-iso9660-image` | [`patterns/iso.hexpat`](patterns/iso.hexpat) | ISO 9660 file system |
| Java Class | `application/x-java-applet` | [`patterns/java_class.hexpat`](patterns/java_class.hexpat) | Java Class files |
| JPEG | `image/jpeg` | [`patterns/jpeg.hexpat`](patterns/jpeg.hexpat) | JPEG Image Format |
| LOC | | [`patterns/loc.hexpat`](patterns/loc.hexpat) | Minecraft Legacy Console Edition Language file |
| Lua 5.1 | | [`patterns/lua51.hexpat`](patterns/lua51.hexpat) | Lua 5.1 bytecode |
| Lua 5.2 | | [`patterns/lua52.hexpat`](patterns/lua52.hexpat) | Lua 5.2 bytecode |
| Lua 5.3 | | [`patterns/lua53.hexpat`](patterns/lua53.hexpat) | Lua 5.3 bytecode |
| Lua 5.4 | | [`patterns/lua54.hexpat`](patterns/lua54.hexpat) | Lua 5.4 bytecode |
| LCE Savefile | | [`patterns/lcesave.hexpat`](patterns/lcesave.hexpat) | Minecraft Legacy Console Edition save file |
| LZNT1 | | [`patterns/lznt1.hexpat`](patterns/lznt1.hexpat) | LZNT1 compressed data format |
| Mach-O | `application/x-mach-binary` | [`patterns/macho.hexpat`](patterns/macho.hexpat) | Mach-O executable |
| MIDI | `audio/midi` | [`patterns/midi.hexpat`](patterns/midi.hexpat) | MIDI header, event fields provided |
| MiniDump | `application/x-dmp` | [`patterns/minidump.hexpat`](patterns/minidump.hexpat) | Windows MiniDump files |
| mp4 | `video/mp4` | [`patterns/mp4.hexpat`](patterns/mp4.hexpat) | MPEG-4 Part 14 digital multimedia container format |
| msgpack | `application/x-msgpack` | [`patterns/msgpack.hexpat`](patterns/msgpack.hexpat) | MessagePack binary serialization format |
| MSSCMP | | [`patterns/msscmp.hexpat`](patterns/msscmp.hexpat) | Miles Sound System Compressed Archive |
| NACP | | [`patterns/nacp.hexpat`](patterns/nacp.hexpat) | Nintendo Switch NACP files |
| NBT | | [`patterns/nbt.hexpat`](patterns/nbt.hexpat) | Minecraft NBT format |
| NE | | [`patterns/ne.hexpat`](patterns/ne.hexpat) | NE header and Standard NE fields |
| nes | | [`patterns/nes.hexpat`](patterns/nes.hexpat) | .nes file format |
| NE | `application/x-ms-ne-executable` | [`patterns/ne.hexpat`](patterns/ne.hexpat) | NE header and Standard NE fields |
| nes | | [`patterns/nes.hexpat`](patterns/nes.hexpat) | .nes file format |
| NotepadCache | | [`patterns/notepad-cache.hexpat`](patterns/notepad-cache.hexpat) | Windows Notepad Cache |
| NotepadWindowState | | [`patterns/notepadwindowstate.hexpat`](patterns/notepadwindowstate.hexpat) | Windows 11 Notepad - Window State .bin file |
| NRO | | [`patterns/nro.hexpat`](patterns/nro.hexpat) | Nintendo Switch NRO files |
| NTAG | | [`patterns/ntag.hexpat`](patterns/ntag.hexpat) | NTAG213/NTAG215/NTAG216, NFC Forum Type 2 Tag compliant IC |
| OGG | `audio/ogg` | [`patterns/ogg.hexpat`](patterns/ogg.hexpat) | OGG Audio format |
| PAK | | [`patterns/xgspak.hexpat`](patterns/xgspak.hexpat) | Exient XGS Engine Pak files |
| PCAP | `application/vnd.tcpdump.pcap` | [`patterns/pcap.hexpat`](patterns/pcap.hexpat) | pcap header and packets |
| PCK | | [`patterns/pck.hexpat`](patterns/pck.hexpat) | Minecraft Legacy Console Edition .pck file |
| PCX | `application/x-pcx` | [`patterns/pcx.hexpat`](patterns/pcx.hexpat) | PCX Image format |
| PE | `application/x-dosexec` `application/x-msdownload` | [`patterns/pe.hexpat`](patterns/pe.hexpat) | PE header, COFF header, Standard COFF fields and Windows Specific fields |
| PP | | [`patterns/selinuxpp.hexpat`](patterns/selinuxpp.pat) | SE Linux package |
| PE | `application/x-dosexec` `application/x-msdownload` | [`patterns/pe.hexpat`](patterns/pe.hexpat) | PE header, COFF header, Standard COFF fields and Windows Specific fields |
| PP | | [`patterns/selinuxpp.hexpat`](patterns/selinuxpp.pat) | SE Linux package |
| PFS0 | | [`patterns/pfs0.hexpat`](patterns/pfs0.hexpat) | Nintendo Switch PFS0 archive (NSP files) |
| PIF | `image/pif` | [`patterns/pif.hexpat`](patterns/pif.hexpat) | PIF Image Format |
| PNG | `image/png` | [`patterns/png.hexpat`](patterns/png.hexpat) | PNG image files |
| PRODINFO | | [`patterns/prodinfo.hexpat`](patterns/prodinfo.hexpat) | Nintendo Switch PRODINFO |
| Protobuf | | [`patterns/protobuf.hexpat`](patterns/protobuf.hexpat) | Google Protobuf encoding |
| PyInstaller | | [`patterns/pyinstaller.hexpat`](patterns/pyinstaller.hexpat) | PyInstaller binray files |
| PYC | | [`patterns/pyc.hexpat`](patterns/pyc.hexpat) | Python bytecode files |
| PKM | | [`patterns/pkm.hexpat`](patterns/pkm.hexpat) | PKM texture format |
| PNG | `image/png` | [`patterns/png.hexpat`](patterns/png.hexpat) | PNG image files |
| PRODINFO | | [`patterns/prodinfo.hexpat`](patterns/prodinfo.hexpat) | Nintendo Switch PRODINFO |
| Protobuf | | [`patterns/protobuf.hexpat`](patterns/protobuf.hexpat) | Google Protobuf encoding |
| psafe3 | | [`patterns/psafe3.hexpat`](patterns/psafe3.hexpat`) | Password Safe V3 |
| PyInstaller | | [`patterns/pyinstaller.hexpat`](patterns/pyinstaller.hexpat) | PyInstaller binray files |
| PYC | `application/x-bytecode.python` | [`patterns/pyc.hexpat`](patterns/pyc.hexpat) | Python bytecode files |
| QBCL | | [`patterns/qbcl.hexpat`](patterns/qbcl.hexpat) | Qubicle voxel scene project file |
| QOI | `image/qoi` | [`patterns/qoi.hexpat`](patterns/qoi.hexpat) | QOI image files |
| RAS | `image/x-sun-raster` | [`patterns/ras.hexpat`](patterns/ras.hexpat) | RAS image files |
| QOI | `image/qoi` | [`patterns/qoi.hexpat`](patterns/qoi.hexpat) | QOI image files |
| quantized-mesh | | [`patterns/quantized-mesh.hexpat`](patterns/quantized-mesh.hexpat) | Cesium quantized-mesh terrain |
| RAR | `application/x-rar` | [`patterns/rar.hexpat`](patterns/rar.hexpat) | RAR archive file format |
| RAS | `image/x-sun-raster` | [`patterns/ras.hexpat`](patterns/ras.hexpat) | RAS image files |
| ReFS | | [`patterns/refs.hexpat`](patterns/refs.hexpat) | Microsoft Resilient File System |
| RGBDS | | [`patterns/rgbds.hexpat`](patterns/rgbds.hexpat) | [RGBDS](https://rgbds.gbdev.io) object file format |
| Shell Link | `application/x-ms-shortcut` | [`patterns/lnk.hexpat`](patterns/lnk.hexpat) | Windows Shell Link file format |
| shp | | [`patterns/shp.hexpat`](patterns/shp.hexpat) | ESRI shape file |
| shx | | [`patterns/shx.hexpat`](patterns/shx.hexpat) | ESRI index file |
| sup | | [`patterns/sup.hexpat`](patterns/sup.hexpat) | PGS Subtitle |
| SPIRV | | [`patterns/spirv.hexpat`](patterns/spirv.hexpat) | SPIR-V header and instructions |
| STL | `model/stl` | [`patterns/stl.hexpat`](patterns/stl.hexpat) | STL 3D Model format |
| StuffItV5 | `application/x-stuffit` | [`patterns/sit5.hexpat`](patterns/sit5.hexpat) | StuffIt V5 archive |
| SWF | |[`patterns/swf.hexpat`](patterns/swf.hexpat) | Shockwave Flash file format |
| SQLite3 | `application/vnd.sqlite3` | [`patterns/sqlite3.hexpat`](patterns/sqlite3.hexpat) | SQLite3 Database |
| SWF | `application/x-shockwave-flash` |[`patterns/swf.hexpat`](patterns/swf.hexpat) | Shockwave Flash file format |
| TAR | `application/x-tar` | [`patterns/tar.hexpat`](patterns/tar.hexpat) | Tar file format |
| TES | | [`patterns/wintec_tes.hexpat`](patterns/wintec_tes.hexpat) | Wintec TES GPS log |
| TIFF | `image/tiff` | [`patterns/tiff.hexpat`](patterns/tiff.hexpat) | Tag Image File Format |
| TGA | `image/tga` | [`patterns/tga.hexpat`](patterns/tga.hexpat) | Truevision TGA/TARGA image |
| TTF | `font/ttf`, `font/otf` | [`patterns/ttf.hexpat`](patterns/ttf.hexpat) | TrueType and OpenType font format |
| Ubiquiti | | [`patterns/ubiquiti.hexpat`](patterns/ubiquiti.hexpat) | Ubiquiti Firmware (update) image |
| UEFI | | [`patterns/uefi.hexpat`](patterns/uefi.hexpat)` | UEFI structs for parsing efivars |
| UEFI Boot Entry | | [`patterns/uefi_boot_entry.hexpat`](patterns/uefi_boot_entry.hexpat) | UEFI Boot Entry (Load option) |
| UF2 | | [`patterns/uf2.hexpat`](patterns/uf2.hexpat) | [USB Flashing Format](https://github.com/microsoft/uf2) |
| VBMeta | | [`patterns/vbmeta.hexpat`](patterns/vbmeta.hexpat) | Android VBMeta image |
| VDF | | [`patterns/vdf.hexpat`](patterns/vdf.hexpat) | Binary Value Data Format (.vdf) files |
| VEADO | | [`patterns/veado.hexpat`](patterns/veado.hexpat) | veadotube mini avatar file |
| VGM | | [`patterns/vgm.hexpat`](patterns/vgm.hexpat) | VGM (Video Game Music) sound log |
| VHDX | | [`patterns/vhdx.hexpat`](patterns/vhdx.hexpat) | Microsoft Hyper-V Virtual Hard Disk format |
| WAV | `audio/x-wav` | [`patterns/wav.hexpat`](patterns/wav.hexpat) | RIFF header, WAVE header, PCM header |
| WAS | | [`patterns\was_oskasoftware.hexpat`](patterns\was_oskasoftware.hexpat) | Oska Software DeskMates WAS/WA3 (WAVE/MP3 Set) file
| WAD | | [`patterns/wad.hexpat`](patterns/wad.hexpat) | DOOM WAD Archive |
| WebP | `image/webp` | [`patterns/webp.hexpat`](patterns/webp.hexpat) | Google WebP image |
| XBEH | `audio/x-xbox-executable` | [`patterns/xbeh.hexpat`](patterns/xbeh.hexpat) | Xbox executable |
| XCI | | [`patterns/xci.hexpat`](patterns/xci.hexpat) | Nintendo Switch XCI cardridge ROM |
| XCI | | [`patterns/xci.hexpat`](patterns/xci.hexpat) | Nintendo Switch XCI cartridge ROM |
| XGT | | [`patterns/xgt.hexpat`](patterns/xgstexture.hexpat) | Exient XGS Engine Texture |
| Xilinx BIT | | [`patterns/xilinx_bit.hexpat`](patterns/xilinx_bit.hexpat) | Xilinx FPGA Bitstreams |
| Xilinx Bootgen | | [`patterns/xilinx_bootgen.hexpat`](patterns/xilinx_bootgen.hexpat) | Xilinx ZynqMP Boot Images |
| Xilinx Bootgen | `application/x-xilinx-boot-zynqmp` | [`patterns/xilinx_bootgen.hexpat`](patterns/xilinx_bootgen.hexpat) | Xilinx ZynqMP Boot Images |
| ZIP | `application/zip` | [`patterns/zip.hexpat`](patterns/zip.hexpat) | End of Central Directory Header, Central Directory File Headers |
| ZLIB | `application/zlib` | [`patterns/zlib.hexpat`](patterns/zlib.hexpat) | ZLIB compressed data format |
| ZSTD | `application/zstd` | [`patterns/zstd.hexpat`](patterns/zstd.hexpat) | Zstandard compressed data format |
@@ -198,15 +248,16 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
| 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 |
> import custom encoding from File -> Import... -> Custome Encoding File
### Data Processor Nodes
| Name | Path | Description |
|------|------|-------------|
| Caesar Cipher | [`nodes/caesar.hexnode`](nodes/caesar.hexnode) | Simple adjustable per-byte Caecar Cipher (ROT) |
| XOR Cipher | [`nodes/xor.hexnode`](nodes/xor.hexnode) | XORs a input with a repeating XOR pad |
### Themes
| Name | Path | Description |
|------|------|-------------|
| Visual Studio Dark | [`themes/vs_dark.json`](themes/vs_dark.json) | Theme similar to Visual Studio's Dark theme |
@@ -215,3 +266,9 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
| Catppuccin Frappe | [`themes/catppuccin-frappe.json`](themes/catppuccin-frappe.json) | Catppuccin Frappe Flavor (Dark Theme) |
| Catppuccin Macchiato | [`themes/catppuccin-macchiato.json`](themes/catppuccin-macchiato.json) | Catppuccin Macchiato Flavor (Dark Theme) |
| Catppuccin Mocha | [`themes/catppuccin-mocha.json`](themes/catppuccin-mocha.json) | Catppuccin Mocha Flavor (Dark Theme) |
### Disassemblers
| Name | Path | Description |
|------|------|-------------|
| 8051 | [`disassemblers/8051.json`](disassemblers/8051.json) | Intel 8051 Architecture |

View File

@@ -775,6 +775,6 @@
"name": "ENOTRECOVERABLE",
"desc": "State not recoverable"
}
]
}

730
disassemblers/8051.json Normal file
View File

@@ -0,0 +1,730 @@
{
"name": "Intel 8051",
"includes": [],
"options": [],
"opcodes": [
{
"mask": "0000'0000",
"mnemonic": "NOP",
"format": ""
},
{
"mask": "0000'0010 AAAA'AAAA AAAA'AAAA",
"mnemonic": "LJMP",
"format": "#0x{A:04X}",
"metadata": [
{
"type": "jump",
"data": {
"destination": "A"
}
}
]
},
{
"mask": "1000'0000 AAAA'AAAA",
"mnemonic": "SJMP",
"format": "#0x{A:02X}",
"metadata": [
{
"type": "jump",
"data": {
"destination": "A"
}
}
]
},
{
"mask": "0111'0011",
"mnemonic": "JMP",
"format": "@A+DPTR"
},
{
"mask": "0100'0000 AAAA'AAAA",
"mnemonic": "JC",
"format": "PC + 0x{A:02X}",
"metadata": [
{
"type": "jump",
"data": {
"destination": "offset + 2 + A"
}
}
]
},
{
"mask": "0011'0000 BBBB'BBBB AAAA'AAAA",
"mnemonic": "JNB",
"format": "BIT[0x{B:02X}], PC + 0x{A:02X}",
"metadata": [
{
"type": "jump",
"data": {
"destination": "offset + 3 + A"
}
}
]
},
{
"mask": "0001'0000 BBBB'BBBB AAAA'AAAA",
"mnemonic": "JBC",
"format": "BIT[0x{B:02X}], PC + 0x{A:02X}",
"metadata": [
{
"type": "jump",
"data": {
"destination": "offset + 3 + A"
}
}
]
},
{
"mask": "0010'0000 AAAA'AAAA RRRR'RRRR",
"mnemonic": "JB",
"format": "BIT[0x{A:02X}], PC + 0x{R:02X}",
"metadata": [
{
"type": "jump",
"data": {
"destination": "offset + 3 + A"
}
}
]
},
{
"mask": "0001'0010 AAAA'AAAA AAAA'AAAA",
"mnemonic": "LCALL",
"format": "#0x{A:04X}",
"metadata": [
{
"type": "jump",
"data": {
"destination": "A"
}
}
]
},
{
"mask": "PPP1'0001 AAAA'AAAA",
"mnemonic": "ACALL",
"format": "page{P} #0x{A:04X}",
"metadata": [
{
"type": "jump",
"data": {
"destination": "P * 256 + A"
}
}
]
},
{
"mask": "PPP0'0001 AAAA'AAAA",
"mnemonic": "AJMP",
"format": "page{P} #0x{A:04X}",
"metadata": [
{
"type": "jump",
"data": {
"destination": "P * 256 + A"
}
}
]
},
{
"mask": "0000'0011",
"mnemonic": "RR",
"format": "A"
},
{
"mask": "0001'0011",
"mnemonic": "RRC",
"format": "A"
},
{
"mask": "0010'0011",
"mnemonic": "RL",
"format": "A"
},
{
"mask": "0011'0011",
"mnemonic": "RLC",
"format": "A"
},
{
"mask": "0000'0100",
"mnemonic": "INC",
"format": "A"
},
{
"mask": "0000'0101 AAAA'AAAA",
"mnemonic": "INC",
"format": "IRAM[0x{A:02X}]"
},
{
"mask": "0000'011R",
"mnemonic": "INC",
"format": "@R{R}"
},
{
"mask": "0000'1RRR",
"mnemonic": "INC",
"format": "R{R}"
},
{
"mask": "1010'0011",
"mnemonic": "INC",
"format": "DPTR"
},
{
"mask": "0001'0100",
"mnemonic": "DEC",
"format": "A"
},
{
"mask": "0001'0101 AAAA'AAAA",
"mnemonic": "DEC",
"format": "IRAM[0x{A:02X}]"
},
{
"mask": "0001'0110",
"mnemonic": "DEC",
"format": "@R0"
},
{
"mask": "0001'0111",
"mnemonic": "DEC",
"format": "@R1"
},
{
"mask": "0001'1RRR",
"mnemonic": "DEC",
"format": "R{R}"
},
{
"mask": "1110'0100",
"mnemonic": "CLR",
"format": "A"
},
{
"mask": "1100'0010 AAAA'AAAA",
"mnemonic": "CLR",
"format": "BIT[0x{A:02X}]"
},
{
"mask": "1100'0011",
"mnemonic": "CLR",
"format": "C"
},
{
"mask": "1111'0000",
"mnemonic": "MOVX",
"format": "@DPTR, A"
},
{
"mask": "1110'0000",
"mnemonic": "MOVX",
"format": "A, @DPTR"
},
{
"mask": "1111'001R",
"mnemonic": "MOVX",
"format": "@R{R}, A"
},
{
"mask": "1110'001R",
"mnemonic": "MOVX",
"format": "A, @R{R}"
},
{
"mask": "0111'011R AAAA'AAAA",
"mnemonic": "MOV",
"format": "@R{R}, #0x{A:02X}"
},
{
"mask": "0111'1RRR AAAA'AAAA",
"mnemonic": "MOV",
"format": "R{R}, #0x{A:02X}"
},
{
"mask": "1111'1RRR",
"mnemonic": "MOV",
"format": "R{R}, A"
},
{
"mask": "1110'011R",
"mnemonic": "MOV",
"format": "A, @R{R}"
},
{
"mask": "1111'011R",
"mnemonic": "MOV",
"format": "@R{R}, A"
},
{
"mask": "1110'1RRR",
"mnemonic": "MOV",
"format": "A, R{R}"
},
{
"mask": "1001'0010 AAAA'AAAA",
"mnemonic": "MOV",
"format": "BIT[0x{A:02X}], C"
},
{
"mask": "1010'0010 AAAA'AAAA",
"mnemonic": "MOV",
"format": "C, BIT[0x{A:02X}]"
},
{
"mask": "1001'0000 DDDD'DDDD DDDD'DDDD",
"mnemonic": "MOV",
"format": "DPTR, #0x{D:04X}"
},
{
"mask": "1110'0101 AAAA'AAAA",
"mnemonic": "MOV",
"format": "A, IRAM[0x{A:02X}]"
},
{
"mask": "1111'0101 AAAA'AAAA",
"mnemonic": "MOV",
"format": "IRAM[#0x{A:02X}], A"
},
{
"mask": "0111'0101 AAAA'AAAA DDDD'DDDD",
"mnemonic": "MOV",
"format": "IRAM[0x{A:02X}], #0x{D:02X}"
},
{
"mask": "1000'0101 AAAA'AAAA BBBB'BBBB",
"mnemonic": "MOV",
"format": "IRAM[0x{A:02X}], IRAM[0x{B:02X}]"
},
{
"mask": "0111'0100 DDDD'DDDD",
"mnemonic": "MOV",
"format": "A, #0x{D:02X}"
},
{
"mask": "1000'011R AAAA'AAAA",
"mnemonic": "MOV",
"format": "IRAM[0x{A:02X}], @R{R}"
},
{
"mask": "1000'1RRR AAAA'AAAA",
"mnemonic": "MOV",
"format": "IRAM[0x{A:02X}], R{R}"
},
{
"mask": "1010'011R AAAA'AAAA",
"mnemonic": "MOV",
"format": "@R{R}, IRAM[0x{A:02X}]"
},
{
"mask": "1010'1RRR AAAA'AAAA",
"mnemonic": "MOV",
"format": "R{R}, IRAM[0x{A:02X}]"
},
{
"mask": "0110'0000 AAAA'AAAA",
"mnemonic": "JZ",
"format": "PC + 0x{A:02X}",
"metadata": [
{
"type": "jump",
"data": {
"destination": "offset + 2 + A"
}
}
]
},
{
"mask": "0111'0000 AAAA'AAAA",
"mnemonic": "JNZ",
"format": "PC + 0x{A:02X}",
"metadata": [
{
"type": "jump",
"data": {
"destination": "offset + 2 + A"
}
}
]
},
{
"mask": "1001'0011",
"mnemonic": "MOVC",
"format": "A, @A+DPTR"
},
{
"mask": "1000'0011",
"mnemonic": "MOVC",
"format": "A, @A+PC"
},
{
"mask": "1101'011R",
"mnemonic": "XCHD",
"format": "A, @R{R}"
},
{
"mask": "1100'011R",
"mnemonic": "XCH",
"format": "A, @R{R}"
},
{
"mask": "1100'1RRR",
"mnemonic": "XCH",
"format": "A, R{R}"
},
{
"mask": "1100'0101 AAAA'AAAA",
"mnemonic": "XCH",
"format": "A, IRAM[0x{A:02X}]"
},
{
"mask": "0010'0010",
"mnemonic": "RET",
"format": ""
},
{
"mask": "0011'0010",
"mnemonic": "RETI",
"format": ""
},
{
"mask": "1101'0010 AAAA'AAAA",
"mnemonic": "SETB",
"format": "BIT[0x{A:02X}]"
},
{
"mask": "1101'0011",
"mnemonic": "SETB",
"format": "C"
},
{
"mask": "0101'0010 AAAA'AAAA",
"mnemonic": "ANL",
"format": "IRAM[0x{A:02X}], A"
},
{
"mask": "0101'0101 AAAA'AAAA",
"mnemonic": "ANL",
"format": "A, IRAM[0x{A:02X}]"
},
{
"mask": "0101'0011 AAAA'AAAA DDDD'DDDD",
"mnemonic": "ANL",
"format": "A, IRAM[0x{A:02X}], #0x{D:02X}"
},
{
"mask": "0101'0100 AAAA'AAAA",
"mnemonic": "ANL",
"format": "A, #0x{A:02X}"
},
{
"mask": "0101'011R",
"mnemonic": "ANL",
"format": "A, @R{R}"
},
{
"mask": "0101'1RRR",
"mnemonic": "ANL",
"format": "A, R{R}"
},
{
"mask": "1000'0010 AAAA'AAAA",
"mnemonic": "ANL",
"format": "C, BIT[0x{A:02X}]"
},
{
"mask": "1011'0000 AAAA'AAAA",
"mnemonic": "ANL",
"format": "C, /BIT[0x{A:02X}]"
},
{
"mask": "0100'0010 AAAA'AAAA",
"mnemonic": "ORL",
"format": "IRAM[0x{A:02X}], A"
},
{
"mask": "0100'0011 AAAA'AAAA DDDD'DDDD",
"mnemonic": "ORL",
"format": "IRAM[0x{A:02X}], #0x{D:02X}"
},
{
"mask": "0100'0100 DDDD'DDDD",
"mnemonic": "ORL",
"format": "A, #0x{D:02X}"
},
{
"mask": "0100'011R",
"mnemonic": "ORL",
"format": "A, @R{R}"
},
{
"mask": "0100'1RRR",
"mnemonic": "ORL",
"format": "A, R{R}"
},
{
"mask": "0100'0101 AAAA'AAAA",
"mnemonic": "ORL",
"format": "A, IRAM[0x{A:02X}]"
},
{
"mask": "0111'0010 AAAA'AAAA",
"mnemonic": "ORL",
"format": "C, BIT[0x{A:02X}]"
},
{
"mask": "1010'0000 AAAA'AAAA",
"mnemonic": "ORL",
"format": "C, /BIT[0x{A:02X}]"
},
{
"mask": "0110'0010 AAAA'AAAA",
"mnemonic": "XRL",
"format": "IRAM[0x{A:02X}], A"
},
{
"mask": "0110'0011 AAAA'AAAA DDDD'DDDD",
"mnemonic": "XRL",
"format": "IRAM[0x{A:02X}], #0x{D:02X}"
},
{
"mask": "0110'0100 DDDD'DDDD",
"mnemonic": "XRL",
"format": "A, #0x{D:02X}"
},
{
"mask": "0110'011R",
"mnemonic": "XRL",
"format": "A, @R{R}"
},
{
"mask": "0110'1RRR",
"mnemonic": "XRL",
"format": "A, R{R}"
},
{
"mask": "0110'0101 AAAA'AAAA",
"mnemonic": "XRL",
"format": "A, IRAM[0x{A:02X}]"
},
{
"mask": "0010'0100 DDDD'DDDD",
"mnemonic": "ADD",
"format": "A, #0x{D:02X}"
},
{
"mask": "0010'011R",
"mnemonic": "ADD",
"format": "A, @R{R}"
},
{
"mask": "0010'0101 AAAA'AAAA",
"mnemonic": "ADD",
"format": "A, IRAM[0x{A:02X}]"
},
{
"mask": "0011'0100 DDDD'DDDD",
"mnemonic": "ADDC",
"format": "A, #0x{D:02X}"
},
{
"mask": "0011'011R",
"mnemonic": "ADDC",
"format": "A, @R{R}"
},
{
"mask": "0011'0101 AAAA'AAAA",
"mnemonic": "ADDC",
"format": "A, IRAM[0x{A:02X}]"
},
{
"mask": "0011'1RRR",
"mnemonic": "ADDC",
"format": "A, R{R}"
},
{
"mask": "1001'0100 DDDD'DDDD",
"mnemonic": "SUBB",
"format": "A, #0x{D:02X}"
},
{
"mask": "1001'0101 IIII'IIII",
"mnemonic": "SUBB",
"format": "A, IRAM[0x{I:02X}]"
},
{
"mask": "1001'011R",
"mnemonic": "SUBB",
"format": "A, @R{R}"
},
{
"mask": "1001'1RRR",
"mnemonic": "SUBB",
"format": "A, R{R}"
},
{
"mask": "1010'0100",
"mnemonic": "MUL",
"format": "AB"
},
{
"mask": "1000'0100",
"mnemonic": "DIV",
"format": "AB"
},
{
"mask": "0010'1RRR",
"mnemonic": "ORL",
"format": "A, R{R}"
},
{
"mask": "1011'0101 IIII'IIII AAAA'AAAA",
"mnemonic": "CJNE",
"format": "A, IRAM[0x{I:02X}], PC + 0x{A:02X}",
"metadata": [
{
"type": "jump",
"data": {
"destination": "offset + 3 + A"
}
}
]
},
{
"mask": "1011'0100 DDDD'DDDD AAAA'AAAA",
"mnemonic": "CJNE",
"format": "A, #0x{D:02X}, PC + 0x{A:02X}",
"metadata": [
{
"type": "jump",
"data": {
"destination": "offset + 3 + A"
}
}
]
},
{
"mask": "1011'011R DDDD'DDDD AAAA'AAAA",
"mnemonic": "CJNE",
"format": "@R{R}, #0x{D:02X}, PC + 0x{A:02X}",
"metadata": [
{
"type": "jump",
"data": {
"destination": "offset + 3 + A"
}
}
]
},
{
"mask": "1011'1RRR DDDD'DDDD AAAA'AAAA",
"mnemonic": "CJNE",
"format": "R{R}, #0x{D:02X}, PC + 0x{A:02X}",
"metadata": [
{
"type": "jump",
"data": {
"destination": "offset + 3 + A"
}
}
]
},
{
"mask": "1101'0101 IIII'IIII AAAA'AAAA",
"mnemonic": "DJNZ",
"format": "IRAM[0x{I:02X}], PC + 0x{A:02X}",
"metadata": [
{
"type": "jump",
"data": {
"destination": "offset + 3 + A"
}
}
]
},
{
"mask": "1101'1RRR AAAA'AAAA",
"mnemonic": "DJNZ",
"format": "R{R}, PC + 0x{R:02X}",
"metadata": [
{
"type": "jump",
"data": {
"destination": "offset + 2 + A"
}
}
]
},
{
"mask": "0101'0000 AAAA'AAAA",
"mnemonic": "JNC",
"format": "PC + 0x{A:02X}",
"metadata": [
{
"type": "jump",
"data": {
"destination": "offset + 2 + A"
}
}
]
},
{
"mask": "1101'0000 AAAA'AAAA",
"mnemonic": "POP",
"format": "IRAM[0x{A:02X}]"
},
{
"mask": "1100'0000 AAAA'AAAA",
"mnemonic": "PUSH",
"format": "IRAM[0x{A:02X}]"
},
{
"mask": "1101'0100",
"mnemonic": "DA",
"format": ""
},
{
"mask": "1100'0100",
"mnemonic": "SWAP",
"format": "A"
},
{
"mask": "1111'0100",
"mnemonic": "CPL",
"format": "A"
},
{
"mask": "1011'0011",
"mnemonic": "CPL",
"format": "C"
},
{
"mask": "1011'0010 BBBB'BBBB",
"mnemonic": "CPL",
"format": "BIT[0x{B:02X}]"
},
{
"mask": "1010'0101",
"mnemonic": "INVALID",
"format": ""
},
{
"mask": "XXXX'XXXX",
"mnemonic": "DB",
"format": "#0x{X:02X}",
"metadata": [
{
"type": "data",
"data": {
"value": "X"
}
}
]
}
]
}

1045
disassemblers/jvm.json Normal file

File diff suppressed because it is too large Load Diff

21921
encodings/gbk.tbl Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -37,4 +37,14 @@ namespace auto hex::core {
return result;
};
/**
Add a file to the Virtual Filesystem
@param path The name of the file
@param pattern The pattern associated with the file
*/
fn add_virtual_file(str path, auto pattern)
{
builtin::hex::core::add_virtual_file(path, pattern);
};
}

View File

@@ -60,5 +60,16 @@ namespace auto hex::dec {
fn zstd_decompress(ref auto pattern, std::mem::Section section) {
return builtin::hex::dec::zstd_decompress(pattern, section);
};
/**
Decompresses the bytes of a pattern into a section using the lz4 algorithm
@param pattern The pattern whose bytes should be decompressed
@param section The section to decompress the data into
@param frame Whether the data is framed or not
@return true if successful, false otherwise
*/
fn lz4_decompress(ref auto pattern, std::mem::Section section, bool frame = true) {
return builtin::hex::dec::lz4_decompress(pattern, section, frame);
};
}

View File

@@ -7,11 +7,11 @@ import hex.impl.imhex_check;
*/
namespace auto hex::prv {
/**
Queries information from the currently loaded provider. The kind of information that's available depends on the provider that's loaded
> **Available information**
> - File Provider
> - `file_path() -> str`
@@ -32,12 +32,12 @@ namespace auto hex::prv {
> - `region_size(regionName) -> u64`
> - `process_id() -> u32`
> - `process_name() -> str`
@param category Information category
@param argument Extra argument to pass along
*/
fn get_information(str category, str argument = "") {
return builtin::hex::prv::get_information(category, argument);
};
}

View File

@@ -0,0 +1,28 @@
#pragma once
import hex.impl.imhex_check;
/*!
Types to work with custom encoded strings using Thiny encoding definitions
*/
namespace auto hex::type {
/**
A string that was encoded using a custom encoding
@tparam Data Pattern whose bytes are used in the decoding process
@tparam EncodingDefinition A string containing a Thingy encoding definition as used by ImHex's custom encoding feature
*/
struct EncodedString<auto Data, auto EncodingDefinition> {
builtin::hex::dec::EncodedString<Data, EncodingDefinition> string;
} [[sealed, format("hex::type::impl::format_encoded_string")]];
namespace impl {
fn format_encoded_string(ref auto string) {
return string.string;
};
}
}

View File

@@ -0,0 +1,143 @@
#pragma once
import hex.impl.imhex_check;
/*!
Types to work with machine code
*/
namespace auto hex::type {
/**
A machine code instruction which will get disassembled
@tparam DisassemblerSetting A string containing the config for the disassembler in the form of "architecture; setting1, setting2, no-setting3"
@tparam SyntaxType Syntax used in the disassembly. Possible values are "intel", "at&t", "masm" and "motorola"
@tparam ImageBaseAddress Start address of the instruction region in the data
@tparam ImageLoadAddress Address where the instructions will be loaded into memory
Possible Values for DisassemblerSetting:
- Architecture, all may be suffixed with le or be to specify endianess (e.g armbe or mipsle)
- arm
- thumb
- aarch64
- arm64
- mips
- x86
- x86_64
- x64
- ppc
- powerpc
- sparc
- sysz
- xcore
- m68k
- m680x
- tms320c64x
- evm
- wasm
- riscv
- mos65xx
- bpf
- sh
- tricore
- Settings, not all settings make sense for each architecture. Prefixing settings with no- will remove them instead
- 16bit
- 32bit
- 64bit
- cortex-m
- armv8
- micromips
- mips2
- mips3
- mips32r6
- sparcv9
- qpx
- spe
- ps
- 68000
- 68010
- 68020
- 68030
- 68040
- 68060
- 6301
- 6309
- 6800
- 6801
- 6805
- 6808
- 6809
- 6811
- cpu12
- hcs08
- bpfe
- rv32g
- rv64g
- riscvc
- 6502
- 65c02
- w65c02
- 65816
- long-m
- long-x
- sh2
- sh2a
- sh3
- sh4
- sh4a
- shfpu
- shdsp
- 1.1
- 1.2
- 1.3
- 1.3.1
- 1.6
- 1.6.1
- 1.6.2
*/
struct Instruction<auto DisassemblerSetting, auto SyntaxType, auto ImageBaseAddress, auto ImageLoadAddress> {
builtin::hex::dec::Instruction<DisassemblerSetting, SyntaxType, ImageBaseAddress, ImageLoadAddress> instruction;
} [[sealed, format("hex::type::impl::format_instruction")]];
/**
A machine code instruction which will get disassembled using Intel syntax
@tparam DisassemblerSetting A string containing the config for the disassembler in the form of "architecture; setting1, setting2, no-setting3"
@tparam ImageBaseAddress Start address of the instruction region in the data
@tparam ImageLoadAddress Address where the instructions will be loaded into memory
*/
using InstructionIntel<auto DisassemblerSetting, auto ImageBaseAddress, auto ImageLoadAddress> = Instruction<DisassemblerSetting, "intel", ImageBaseAddress, ImageLoadAddress>;
/**
A machine code instruction which will get disassembled using AT&T syntax
@tparam DisassemblerSetting A string containing the config for the disassembler in the form of "architecture; setting1, setting2, no-setting3"
@tparam ImageBaseAddress Start address of the instruction region in the data
@tparam ImageLoadAddress Address where the instructions will be loaded into memory
*/
using InstructionATNT<auto DisassemblerSetting, auto ImageBaseAddress, auto ImageLoadAddress> = Instruction<DisassemblerSetting, "at&t", ImageBaseAddress, ImageLoadAddress>;
/**
A machine code instruction which will get disassembled using MASM syntax
@tparam DisassemblerSetting A string containing the config for the disassembler in the form of "architecture; setting1, setting2, no-setting3"
@tparam ImageBaseAddress Start address of the instruction region in the data
@tparam ImageLoadAddress Address where the instructions will be loaded into memory
*/
using InstructionMASM<auto DisassemblerSetting, auto ImageBaseAddress, auto ImageLoadAddress> = Instruction<DisassemblerSetting, "masm", ImageBaseAddress, ImageLoadAddress>;
/**
A machine code instruction which will get disassembled using Motorola syntax
@tparam DisassemblerSetting A string containing the config for the disassembler in the form of "architecture; setting1, setting2, no-setting3"
@tparam ImageBaseAddress Start address of the instruction region in the data
@tparam ImageLoadAddress Address where the instructions will be loaded into memory
*/
using InstructionMotorola<auto DisassemblerSetting, auto ImageBaseAddress, auto ImageLoadAddress> = Instruction<DisassemblerSetting, "motorola", ImageBaseAddress, ImageLoadAddress>;
namespace impl {
fn format_instruction(ref auto instruction) {
return instruction.instruction;
};
}
}

View File

@@ -0,0 +1,66 @@
#pragma once
import hex.impl.imhex_check;
/*!
Types to decode JSON and JSON-like file formats into a pattern tree
*/
namespace auto hex::type {
/**
Type representing a JSON string
@tparam Size size of the string
*/
struct Json<auto Size> {
char __data[Size] [[hidden]];
builtin::hex::dec::Json<__data> json [[merge]];
};
/**
Type representing Bson data
@tparam Size size of the data
*/
struct Bson<auto Size> {
u8 __data[Size] [[hidden]];
builtin::hex::dec::Bson<__data> bson [[merge]];
};
/**
Type representing Cbor data
@tparam Size size of the data
*/
struct Cbor<auto Size> {
u8 __data[Size] [[hidden]];
builtin::hex::dec::Cbor<__data> cbor [[merge]];
};
/**
Type representing Bjdata data
@tparam Size size of the data
*/
struct Bjdata<auto Size> {
u8 __data[Size] [[hidden]];
builtin::hex::dec::Bjdata<__data> bjdata [[merge]];
};
/**
Type representing Msgpack data
@tparam Size size of the data
*/
struct Msgpack<auto Size> {
u8 __data[Size] [[hidden]];
builtin::hex::dec::Msgpack<__data> msgpack [[merge]];
};
/**
Type representing Ubjson data
@tparam Size size of the data
*/
struct Ubjson<auto Size> {
u8 __data[Size] [[hidden]];
builtin::hex::dec::Ubjson<__data> ubjson [[merge]];
};
}

View File

@@ -11,20 +11,20 @@ import hex.dec;
*/
namespace auto hex::type {
/**
A mangled name string that gets demangled when displayed
*/
struct MangledName {
char value[];
} [[sealed, format("hex::type::impl::format_mangled_name")]];
namespace impl {
fn format_mangled_name(ref MangledName name) {
return hex::dec::demangle(name.value);
};
}
}

View File

@@ -1,6 +1,7 @@
#pragma once
import std.sys;
import std.core;
/*!
The array library contains a helper type to make it easier to create multi-dimensional arrays
@@ -30,6 +31,16 @@ namespace auto std {
std::assert($ - startAddress == NumBytes, "Not enough bytes available to fit a whole number of types");
} [[format("std::impl::format_array")]];
/**
An interface type for getting the index of the currently processed element in an array. This is a nice wrapper around `std::core::array_index()`
To use it, inherit from it and use the `this.index` field to get the index of the current element
*/
struct IIndexed {
const u64 index = std::core::array_index();
};
namespace impl {
fn format_array(ref auto array) {

70
includes/std/attrs.pat Normal file
View File

@@ -0,0 +1,70 @@
import std.io;
import std.core;
/*!
The attributes library contains a set of attributes that can be used to annotate types with certain properties.
To use an attribute, simply make your custom type inherit from the attribute type you want to use.
For example, to make a type hidden, you can use the `Hidden` attribute like this:
```rust
struct MyType : std::attr::Hidden {
// ...
};
```
*/
namespace auto std::attr {
/**
Attribute that marks a type as a literal type.
This means the type behaves like a built-in type in the sense that it doesn't show its internal state and its display value is determined by a format function.
It can also be transformed into a different built-in literal when used in an expression.
@tparam FormatFunction The format function to use. The return value of this function is used to display the value of the literal and also determines the value returned when the literal is used in an expression.
*/
struct Literal<auto FormatFunction> { }
[[sealed, format_read(FormatFunction), transform(FormatFunction)]];
/**
Attribute that changes the name of the variable created from a type.
@tparam Name The name of the variable created
*/
struct Named<auto Name> { }
[[name(Name)]];
/**
Attribute that adds a comment to the variable created from a type.
@tparam Comment The comment to add
*/
struct Commented<auto Comment> {}
[[comment(Comment)]];
/**
Attribute that marks a type as hidden.
This means variables of this type are not displayed in the UI.
*/
struct Hidden {}
[[hidden]];
/**
Attribute that marks a type as hidden and also hides it from the highlighter.
This means variables of this type are don't display any highlighting in the UI but are still visible.
*/
struct HighlightHidden {}
[[highlight_hidden]];
/**
Attribute that marks a type as inline.
Creating a variable of this type will not create a new layer but instead dump the contents of the type directly into the current layer.
*/
struct Inlined {}
[[inline]];
/**
Attribute that marks a type as sealed.
Sealed types don't display their internal state in the UI.
*/
struct Sealed {}
[[sealed]];
}

View File

@@ -3,61 +3,65 @@
import std.limits;
/*!
This library contains various helper functions for common bit operations.
This library contains various helper functions for common bit operations.
*/
namespace auto std::bit {
/**
Calculates the number of 1 bits in a given number
@param x The number
@return The number of bits set to 1 in `x`
*/
fn popcount(u128 x) {
x = (x & (std::limits::u128_max() / 3)) + ((x >> 1) & (std::limits::u128_max() / 3));
x = (x & (std::limits::u128_max() / 5)) + ((x >> 2) & (std::limits::u128_max() / 5));
x = (x & (std::limits::u128_max() / 17)) + ((x >> 4) & (std::limits::u128_max() / 17));
return x % 0xFF;
};
/**
Calculates the number of 1 bits in a given number
@param x The number
@return The number of bits set to 1 in `x`
*/
fn popcount(u128 x) {
const u128 a = 0x55555555555555555555555555555555;
const u128 b = 0x33333333333333333333333333333333;
const u128 c = 0x0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F;
/**
Checks if only a single bit is set to 1 in a given number
@param x The number
@return True if there's a single bit set to 1 in `x`, false otherwise
*/
fn has_single_bit(u128 x) {
return x != 0 && (x & (x - 1)) == 0;
};
/**
Rounds the given number up to the next bigger power of two
@param x The number
@return Next bigger power of two that can fit `x`
*/
fn bit_ceil(u128 x) {
if (x == 0) return 0;
u8 i;
while ((1 << i) < x)
i = i + 1;
return 1 << i;
};
x = (x & a) + ((x >> 1) & a);
x = (x & b) + ((x >> 2) & b);
x = (x & c) + ((x >> 4) & c);
/**
Rounds the given number down to the next bigger power of two
@param x The number
@return Next smaller power of two
*/
fn bit_floor(u128 x) {
if (x == 0) return 0;
u8 i;
while ((x >> i) > 0)
i = i + 1;
return 1 << (i - 1);
};
return x % 0xFF;
};
/**
Checks if only a single bit is set to 1 in a given number
@param x The number
@return True if there's a single bit set to 1 in `x`, false otherwise
*/
fn has_single_bit(u128 x) {
return x != 0 && (x & (x - 1)) == 0;
};
/**
Rounds the given number up to the next bigger power of two
@param x The number
@return Next bigger power of two that can fit `x`
*/
fn bit_ceil(u128 x) {
if (x == 0) return 0;
u8 i;
while ((1 << i) < x)
i = i + 1;
return 1 << i;
};
/**
Rounds the given number down to the next bigger power of two
@param x The number
@return Next smaller power of two
*/
fn bit_floor(u128 x) {
if (x == 0) return 0;
u8 i;
while ((x >> i) > 0)
i = i + 1;
return 1 << (i - 1);
};
}

View File

@@ -38,27 +38,35 @@ namespace auto std::core {
};
/**
Returns the first parameter of the attribute of a pattern if it has one
Returns the nth parameter of the attribute of a pattern if it has one
@param pattern The pattern to check
@param attribute The attribute's name to query
@param [index] The parameter index of the attribute to return. Defaults to 0
*/
fn get_attribute_argument(ref auto pattern, str attribute, u32 index = 0) {
return builtin::std::core::get_attribute_argument(pattern, attribute, index);
};
/**
@warning Removed in 1.27.0
*/
fn get_attribute_value(ref auto pattern, str attribute) {
return builtin::std::core::get_attribute_value(pattern, attribute);
builtin::std::error("`std::core::get_attribute_value(pattern, attribute)` has been removed.\nUse `std::core::get_attribute_argument(pattern, attribute, [index])` instead.");
};
/**
Sets the current default endianess.
Any patterns created following this attribute will be created using the set endianess.
@param endian The new default endianess
Sets the current default endianness.
Any patterns created following this attribute will be created using the set endianness.
@param endian The new default endianness
*/
fn set_endian(std::mem::Endian endian) {
builtin::std::core::set_endian(u32(endian));
};
/**
Gets the current default endianess.
@return The currently set default endianess
Gets the current default endianness.
@return The currently set default endianness
*/
fn get_endian() {
return builtin::std::core::get_endian();
@@ -151,9 +159,34 @@ namespace auto std::core {
/**
Changes the comment attached to a pattern
@param pattern The pattern to modify
@param name The new comment of the pattern
@param comment The new comment of the pattern
*/
fn set_pattern_comment(ref auto pattern, str comment) {
builtin::std::core::set_pattern_comment(pattern, name);
builtin::std::core::set_pattern_comment(pattern, comment);
};
/**
Executes the function with the given name, passing in all given arguments
@param function_name The namespace-prefixed name of the function
@param args Arguments to pass to the function
*/
fn execute_function(str function_name, auto ... args) {
builtin::std::core::execute_function(function_name, args);
};
/**
Sets the pattern color palette for all future created patterns
@param args RGBA8 colors as 32 bit integers (0xAABBGGRR)
*/
fn set_pattern_palette_colors(auto ... colors) {
builtin::std::core::set_pattern_palette_colors(colors);
};
/**
Resets the current pattern palette progress back to zero.
This can be useful to force all instances of a type to have the same coloring for its members
*/
fn reset_pattern_palette() {
builtin::std::core::reset_pattern_palette();
};
}

View File

@@ -1,112 +1,120 @@
#pragma once
/*!
The File library allows reading and writing from/to external files using
a C-like File IO API.
The File library allows reading and writing from/to external files using
a C-like File IO API.
**These functions are considered dangerous and require the user to manually permit them**
**These functions are considered dangerous and require the user to manually permit them**
*/
namespace auto std::file {
/**
/**
A handle representing a file that has been opened
*/
using Handle = s32;
/**
using Handle = s32;
/**
The mode to open a file in.
Read opens the file in read-only mode
Write opens the file in read and write mode
Create creates a new file if it doesn't exist and overwrites an existing file
Read opens the file in read-only mode
Write opens the file in read and write mode
Create creates a new file if it doesn't exist and overwrites an existing file
*/
enum Mode : u8 {
Read = 1,
Write = 2,
Create = 3
};
enum Mode : u8 {
Read = 1,
Write = 2,
Create = 3
};
/**
/**
Opens a file
@param path The path to the file to open
@param mode File open mode
@return Handle to the newly opened file
@param path The path to the file to open
@param mode File open mode
@return Handle to the newly opened file
*/
fn open(str path, Mode mode) {
return builtin::std::file::open(path, u32(mode));
};
fn open(str path, Mode mode) {
return builtin::std::file::open(path, u32(mode));
};
/**
/**
Closes a file handle that has been opened previously
@param handle The handle to close
@param handle The handle to close
*/
fn close(Handle handle) {
builtin::std::file::close(handle);
};
fn close(Handle handle) {
builtin::std::file::close(handle);
};
/**
/**
Reads the content of a file into a string
@param handle The file handle to read from
@param size Number of bytes to read
@return String containing the read data
@param handle The file handle to read from
@param size Number of bytes to read
@return String containing the read data
*/
fn read(Handle handle, u64 size) {
return builtin::std::file::read(handle, size);
};
fn read(Handle handle, u64 size) {
return builtin::std::file::read(handle, size);
};
/**
/**
Writes the content of a string into a file
@param handle The file handle to write to
@param data String or Pattern to write to the file
@param handle The file handle to write to
@param data String or Pattern to write to the file
*/
fn write(Handle handle, auto data) {
builtin::std::file::write(handle, data);
};
fn write(Handle handle, auto data) {
builtin::std::file::write(handle, data);
};
/**
/**
Sets the current cursor position in the given file handle
@param handle The file handle to set the cursor position in
@param offset The offset to move the cursor to
@param handle The file handle to set the cursor position in
@param offset The offset to move the cursor to
*/
fn seek(Handle handle, u64 offset) {
builtin::std::file::seek(handle, offset);
};
fn seek(Handle handle, u64 offset) {
builtin::std::file::seek(handle, offset);
};
/**
Queries the size of a file
@param handle The handle of the file to get the size of
@return The file's size
*/
fn size(Handle handle) {
return builtin::std::file::size(handle);
};
/**
Queries the size of a file
@param handle The handle of the file to get the size of
@return The file's size
*/
fn size(Handle handle) {
return builtin::std::file::size(handle);
};
/**
Resizes a file
@param handle The handle of the file to resize
*/
fn resize(Handle handle, u64 size) {
builtin::std::file::resize(handle, size);
};
/**
Resizes a file
@param handle The handle of the file to resize
*/
fn resize(Handle handle, u64 size) {
builtin::std::file::resize(handle, size);
};
/**
Flushes changes made to a file to disk
@param handle The handle of the file to flush
*/
fn flush(Handle handle) {
builtin::std::file::remove(handle);
};
/**
Flushes changes made to a file to disk
@param handle The handle of the file to flush
*/
fn flush(Handle handle) {
builtin::std::file::flush(handle);
};
/**
Deletes a file from disk. This will also automatically close this file
@param handle The handle of the file to delete
*/
fn remove(Handle handle) {
builtin::std::file::remove(handle);
};
/**
Deletes a file from disk. This will also automatically close this file
@param handle The handle of the file to delete
*/
fn remove(Handle handle) {
builtin::std::file::remove(handle);
};
/**
Create all directories for the provided path
@param path The path for which all directories should be created
*/
fn create_directories(str path) {
builtin::std::file::create_directories(path);
};
}

View File

@@ -1,89 +1,89 @@
#pragma once
/*!
Library for doing arithmetic with fixed point numbers and converting them from/to floating point numbers.
Library for doing arithmetic with fixed point numbers and converting them from/to floating point numbers.
*/
namespace auto std::fxpt {
/**
A fixed point value
*/
using fixed = s128;
/**
A fixed point value
*/
using fixed = s128;
/**
Converts a fixed point value into a floating point value
@param fxt The fixed point value to convert
@param precision The bits of precision the new value should have
@return The floating point representation of fxt
*/
fn to_float(fixed fxt, u32 precision) {
return double(fxt) / double((1 << precision));
};
/**
Converts a floating point value into a fixed point value
@param flt The floating point value to convert
@param precision The bits of precision the new value should have
@return The fixed point representation of flt
*/
fn to_fixed(double flt, u32 precision) {
return s128((flt * (1 << precision)));
};
/**
Converts a fixed point value into a floating point value
@param fxt The fixed point value to convert
@param precision The bits of precision the new value should have
@return The floating point representation of fxt
*/
fn to_float(fixed fxt, u32 precision) {
return double(fxt) / double((1 << precision));
};
/**
Changes the number of bits used to represent the decimal part of the given fixed point number
@param value The fixed point value to convert
@param start_precision The current number of bits used
@param end_precision The new number of bits used
@return `value` as a new fixed point number with `end_precision` bits of precision
*/
fn change_precision(fixed value, u32 start_precision, u32 end_precision) {
return std::fxpt::to_fixed(std::fxpt::to_float(value, start_precision), end_precision);
};
/**
Adds two fixed point numbers with a given precision together
@param a First fixed point number
@param b Second fixed point number
@param precision The precision of `a` and `b`
@return Result of the addition of `a` and `b`
*/
fn add(fixed a, fixed b, u32 precision) {
return a + b;
};
/**
Subtracts two fixed point numbers with a given precision together
@param a First fixed point number
@param b Second fixed point number
@param precision The precision of `a` and `b`
@return Result of the subtraction of `a` and `b`
*/
fn subtract(fixed a, fixed b, u32 precision) {
return a - b;
};
/**
Multiplies two fixed point numbers with a given precision together
@param a First fixed point number
@param b Second fixed point number
@param precision The precision of `a` and `b`
@return Result of the multiplication of `a` and `b`
*/
fn multiply(fixed a, fixed b, u32 precision) {
return (a * b) / (1 << precision);
};
/**
Divides two fixed point numbers with a given precision together
@param a First fixed point number
@param b Second fixed point number
@param precision The precision of `a` and `b`
@return Result of the division of `a` and `b`
*/
fn divide(fixed a, fixed b, u32 precision) {
return (a << precision) / b;
};
/**
Converts a floating point value into a fixed point value
@param flt The floating point value to convert
@param precision The bits of precision the new value should have
@return The fixed point representation of flt
*/
fn to_fixed(double flt, u32 precision) {
return s128((flt * (1 << precision)));
};
/**
Changes the number of bits used to represent the decimal part of the given fixed point number
@param value The fixed point value to convert
@param start_precision The current number of bits used
@param end_precision The new number of bits used
@return `value` as a new fixed point number with `end_precision` bits of precision
*/
fn change_precision(fixed value, u32 start_precision, u32 end_precision) {
return std::fxpt::to_fixed(std::fxpt::to_float(value, start_precision), end_precision);
};
/**
Adds two fixed point numbers with a given precision together
@param a First fixed point number
@param b Second fixed point number
@param precision The precision of `a` and `b`
@return Result of the addition of `a` and `b`
*/
fn add(fixed a, fixed b, u32 precision) {
return a + b;
};
/**
Subtracts two fixed point numbers with a given precision together
@param a First fixed point number
@param b Second fixed point number
@param precision The precision of `a` and `b`
@return Result of the subtraction of `a` and `b`
*/
fn subtract(fixed a, fixed b, u32 precision) {
return a - b;
};
/**
Multiplies two fixed point numbers with a given precision together
@param a First fixed point number
@param b Second fixed point number
@param precision The precision of `a` and `b`
@return Result of the multiplication of `a` and `b`
*/
fn multiply(fixed a, fixed b, u32 precision) {
return (a * b) / (1 << precision);
};
/**
Divides two fixed point numbers with a given precision together
@param a First fixed point number
@param b Second fixed point number
@param precision The precision of `a` and `b`
@return Result of the division of `a` and `b`
*/
fn divide(fixed a, fixed b, u32 precision) {
return (a << precision) / b;
};
}

View File

@@ -6,18 +6,60 @@
namespace auto std::hash {
/**
Calculates the CRC8 hash of the bytes inside of a given pattern
@param pattern The pattern to calculate the CRC8 hash of
@param init The CRC8 init value
@param poly The CRC8 polynomial
@param xorout The CRC8 XOR-Out value
@param reflect_in Whether or not the input bytes should be reflected
@param reflect_out Whether or not the output should be reflected
@return Calculated CRC8 hash
*/
fn crc8(ref auto pattern, u8 init, u8 poly, u8 xorout, bool reflect_in, bool reflect_out) {
return builtin::std::hash::crc8(pattern, init, poly, xorout, reflect_in, reflect_out);
};
/**
Calculates the CRC16 hash of the bytes inside of a given pattern
@param pattern The pattern to calculate the CRC16 hash of
@param init The CRC16 init value
@param poly The CRC16 polynomial
@param xorout The CRC16 XOR-Out value
@param reflect_in Whether or not the input bytes should be reflected
@param reflect_out Whether or not the output should be reflected
@return Calculated CRC16 hash
*/
fn crc16(ref auto pattern, u16 init, u16 poly, u16 xorout, bool reflect_in, bool reflect_out) {
return builtin::std::hash::crc16(pattern, init, poly, xorout, reflect_in, reflect_out);
};
/**
Calculates the CRC32 hash of the bytes inside of a given pattern
@param pattern The pattern to calculate the crc32 hash of
@param pattern The pattern to calculate the CRC32 hash of
@param init The CRC32 init value
@param poly The CRC32 polynomial
@param xorout The CRC32 XOR-Out value
@param reflect_in Whether or not the input bytes should be reflected
@param reflect_out Whether or not the output should be reflected
@return Calculated CRC32 hash
@return Calculated CRC32 hash
*/
fn crc32(ref auto pattern, u32 init, u32 poly, u32 xorout, bool reflect_in, bool reflect_out) {
return builtin::std::hash::crc32(pattern, init, poly, xorout, reflect_in, reflect_out);
};
/**
Calculates the CRC64 hash of the bytes inside of a given pattern
@param pattern The pattern to calculate the CRC64 hash of
@param init The CRC64 init value
@param poly The CRC64 polynomial
@param xorout The CRC64 XOR-Out value
@param reflect_in Whether or not the input bytes should be reflected
@param reflect_out Whether or not the output should be reflected
@return Calculated CRC64 hash
*/
fn crc64(ref auto pattern, u64 init, u64 poly, u64 xorout, bool reflect_in, bool reflect_out) {
return builtin::std::hash::crc64(pattern, init, poly, xorout, reflect_in, reflect_out);
};
}

View File

@@ -9,21 +9,21 @@ namespace auto std {
/**
Formats the given arguments using the format string and prints the result to the console
This function uses the C++20 `std::format` or libfmt's `fmt::format` syntax.
@param fmt Format string
@param fmt Format string or any other value that can be converted to a string
@param args Values to use in the formatting
*/
fn print(str fmt, auto ... args) {
fn print(auto fmt, auto ... args) {
builtin::std::print(fmt, args);
};
/**
Formats the given arguments using the format string and returns the result as a string
This function uses the C++20 `std::format` or libfmt's `fmt::format` syntax.
@param fmt Format string
@param fmt Format string or any other value that can be converted to a string
@param args Values to use in the formatting
@return The formatted string
*/
fn format(str fmt, auto ... args) {
fn format(auto fmt, auto ... args) {
return builtin::std::format(fmt, args);
};

View File

@@ -1,169 +1,169 @@
#pragma once
/*!
Library to calculate the minimum and maximum values that fit into a given data type
Library to calculate the minimum and maximum values that fit into a given data type
*/
namespace auto std::limits {
/**
Returns the minimum value that can be stored in a `u8`.
@return Minimum value
*/
fn u8_min() {
return u8(0);
};
/**
Returns the maximum value that can be stored in a `u8`.
@return Maximum value
*/
fn u8_max() {
return u8(-1);
};
/**
Returns the minimum value that can be stored in a `s8`.
@return Minimum value
*/
/**
Returns the minimum value that can be stored in a `u8`.
@return Minimum value
*/
fn u8_min() {
return u8(0);
};
/**
Returns the maximum value that can be stored in a `u8`.
@return Maximum value
*/
fn u8_max() {
return u8(-1);
};
/**
Returns the minimum value that can be stored in a `s8`.
@return Minimum value
*/
fn s8_min() {
return -s8((std::limits::u8_max() / 2)) - 1;
};
/**
Returns the maximum value that can be stored in a `s8`.
@return Maximum value
*/
fn s8_max() {
return s8((std::limits::u8_max() / 2));
};
return -s8((std::limits::u8_max() / 2)) - 1;
};
/**
Returns the maximum value that can be stored in a `s8`.
@return Maximum value
*/
fn s8_max() {
return s8((std::limits::u8_max() / 2));
};
/**
Returns the minimum value that can be stored in a `u16`.
@return Minimum value
*/
fn u16_min() {
return u16(0);
};
/**
Returns the maximum value that can be stored in a `u16`.
@return Maximum value
*/
fn u16_max() {
return u16(-1);
};
/**
Returns the minimum value that can be stored in a `s16`.
@return Minimum value
*/
fn s16_min() {
return -s16((std::limits::u16_max() / 2)) - 1;
};
/**
Returns the maximum value that can be stored in a `s16`.
@return Maximum value
*/
fn s16_max() {
return s16((std::limits::u16_max() / 2));
};
/**
Returns the minimum value that can be stored in a `u32`.
@return Minimum value
*/
fn u32_min() {
return u32(0);
};
/**
Returns the maximum value that can be stored in a `u32`.
@return Maximum value
*/
fn u32_max() {
return u32(-1);
};
/**
Returns the minimum value that can be stored in a `s32`.
@return Minimum value
*/
fn s32_min() {
return -s32((std::limits::u32_max() / 2)) - 1;
};
/**
Returns the maximum value that can be stored in a `s32`.
@return Maximum value
*/
fn s32_max() {
return s32((std::limits::u32_max() / 2));
};
/**
Returns the minimum value that can be stored in a `u64`.
@return Minimum value
*/
fn u64_min() {
return u64(0);
};
/**
Returns the maximum value that can be stored in a `u64`.
@return Maximum value
*/
fn u64_max() {
return u64(-1);
};
/**
Returns the minimum value that can be stored in a `s64`.
@return Minimum value
*/
fn s64_min() {
return -s64((std::limits::u64_max() / 2)) - 1;
};
/**
Returns the maximum value that can be stored in a `s64`.
@return Maximum value
*/
fn s64_max() {
return s64((std::limits::u64_max() / 2));
};
/**
Returns the minimum value that can be stored in a `u128`.
@return Minimum value
*/
fn u128_min() {
return u128(0);
};
/**
Returns the maximum value that can be stored in a `u128`.
@return Maximum value
*/
fn u128_max() {
return u128(-1);
};
/**
Returns the minimum value that can be stored in a `s128`.
@return Minimum value
*/
fn s128_min() {
return -s128((std::limits::u128_max() / 2)) - 1;
};
/**
Returns the maximum value that can be stored in a `s128`.
@return Maximum value
*/
fn s128_max() {
return s128((std::limits::u128_max() / 2));
};
/**
Returns the minimum value that can be stored in a `u16`.
@return Minimum value
*/
fn u16_min() {
return u16(0);
};
/**
Returns the maximum value that can be stored in a `u16`.
@return Maximum value
*/
fn u16_max() {
return u16(-1);
};
/**
Returns the minimum value that can be stored in a `s16`.
@return Minimum value
*/
fn s16_min() {
return -s16((std::limits::u16_max() / 2)) - 1;
};
/**
Returns the maximum value that can be stored in a `s16`.
@return Maximum value
*/
fn s16_max() {
return s16((std::limits::u16_max() / 2));
};
/**
Returns the minimum value that can be stored in a `u32`.
@return Minimum value
*/
fn u32_min() {
return u32(0);
};
/**
Returns the maximum value that can be stored in a `u32`.
@return Maximum value
*/
fn u32_max() {
return u32(-1);
};
/**
Returns the minimum value that can be stored in a `s32`.
@return Minimum value
*/
fn s32_min() {
return -s32((std::limits::u32_max() / 2)) - 1;
};
/**
Returns the maximum value that can be stored in a `s32`.
@return Maximum value
*/
fn s32_max() {
return s32((std::limits::u32_max() / 2));
};
/**
Returns the minimum value that can be stored in a `u64`.
@return Minimum value
*/
fn u64_min() {
return u64(0);
};
/**
Returns the maximum value that can be stored in a `u64`.
@return Maximum value
*/
fn u64_max() {
return u64(-1);
};
/**
Returns the minimum value that can be stored in a `s64`.
@return Minimum value
*/
fn s64_min() {
return -s64((std::limits::u64_max() / 2)) - 1;
};
/**
Returns the maximum value that can be stored in a `s64`.
@return Maximum value
*/
fn s64_max() {
return s64((std::limits::u64_max() / 2));
};
/**
Returns the minimum value that can be stored in a `u128`.
@return Minimum value
*/
fn u128_min() {
return u128(0);
};
/**
Returns the maximum value that can be stored in a `u128`.
@return Maximum value
*/
fn u128_max() {
return u128(-1);
};
/**
Returns the minimum value that can be stored in a `s128`.
@return Minimum value
*/
fn s128_min() {
return -s128((std::limits::u128_max() / 2)) - 1;
};
/**
Returns the maximum value that can be stored in a `s128`.
@return Maximum value
*/
fn s128_max() {
return s128((std::limits::u128_max() / 2));
};
}

View File

@@ -3,338 +3,338 @@
import std.mem;
/*!
Library containing more advanced mathematical operations.
Library containing more advanced mathematical operations.
*/
namespace auto std::math {
/**
Compares the values `a` and `b` with each other and returns the smaller of the two
@param a First value
@param b Second value
@return `a` if `a` is smaller than `b`, otherwise `b`
*/
fn min(auto a, auto b) {
if (a < b)
return a;
else
return b;
};
/**
Compares the values `a` and `b` with each other and returns the bigger of the two
@param a First value
@param b Second value
@return `a` if `a` is bigger than `b`, otherwise `b`
*/
fn max(auto a, auto b) {
if (a > b)
return a;
else
return b;
};
/**
Clamps the value of `x` between `min` and `max`.
@param x Value
@param min Minimum value
@param max Maximum value
@return `min` if `x` is smaller than `min`, `max` if `x` is bigger than `max`, `x` otherwise
*/
fn clamp(auto x, auto min, auto max) {
if (x < min)
return min;
else if (x > max)
return max;
else
return x;
};
/**
Returns the absolute value of `x`.
@param x Value
@return `x` if `x` is positive, `-x` otherwise
*/
fn abs(auto x) {
if (x < 0)
return -x;
else
return x;
};
/**
Returns the sign of `x`.
@param x Value
@return `1` if `x` is positive, `-1` if `x` is negative, `0` if `x` is zero
*/
fn sign(auto x) {
if (x > 0)
return 1;
else if (x < 0)
return -1;
else
return 0;
};
/**
Copies the sign of `y` to `x`.
@param x Value
@param y Value
@return `x` if `y` is positive, `-x` if `y` is negative
*/
fn copy_sign(auto x, auto y) {
if (y >= 0)
return std::math::abs(x);
else
return -std::math::abs(x);
};
/**
Calculates the factorial of `x`.
@param x Value
@return Factorial of `x`
*/
fn factorial(u128 x) {
u128 result;
result = x;
while (x > 1) {
x = x - 1;
result = result * x;
}
return result;
};
/**
Calculates the binomial coefficient of `n` and `k`.
@param n Value
@param k Value
@return Binomial coefficient of `n` and `k`
*/
fn comb(u128 n, u128 k) {
if (k > n)
return 0;
else
return std::math::factorial(n) / (std::math::factorial(k) * std::math::factorial(n - k));
};
/**
Calculates the permutation of `n` and `k`.
@param n Value
@param k Value
@return Permutation of `n` and `k`
*/
fn perm(u128 n, u128 k) {
if (k > n)
return 0;
else
return std::math::factorial(n) / std::math::factorial(n - k);
};
/**
Floors the value of `value`.
@param value Value
@return `value` floored
*/
fn floor(auto value) { return builtin::std::math::floor(value); };
/**
Ceils the value of `value`.
@param value Value
@return `value` ceiled
*/
fn ceil(auto value) { return builtin::std::math::ceil(value); };
/**
Rounds the value of `value`.
@param value Value
@return `value` rounded
*/
fn round(auto value) { return builtin::std::math::round(value); };
/**
Truncates the value of `value`.
@param value Value
@return `value` truncated
*/
fn trunc(auto value) { return builtin::std::math::trunc(value); };
/**
Calculates the logarithm of `value` with base 10.
@param value Value
@return Logarithm of `value` with base 10
*/
fn log10(auto value) { return builtin::std::math::log10(value); };
/**
Calculates the logarithm of `value` with base 2.
@param value Value
@return Logarithm of `value` with base 2
*/
fn log2(auto value) { return builtin::std::math::log2(value); };
/**
Calculates the natural logarithm of `value`.
@param value Value
@return Logarithm of `value` with base `e`
*/
fn ln(auto value) { return builtin::std::math::ln(value); };
/**
Calculates the floating point modulus of `value`.
@param value Value
@return Floating point modulus of `value`
*/
fn fmod(auto value) { return builtin::std::math::fmod(value); };
/**
Calculates the value of `base` raised to the power of `exp`.
@param base Base
@param exp Exponent
@return `base` raised to the power of `exp`
*/
fn pow(auto base, auto exp) { return builtin::std::math::pow(base, exp); };
/**
Compares the values `a` and `b` with each other and returns the smaller of the two
@param a First value
@param b Second value
@return `a` if `a` is smaller than `b`, otherwise `b`
*/
fn min(auto a, auto b) {
if (a < b)
return a;
else
return b;
};
/**
Calculates the value of the natural number `e` raised to the power of `value`.
@param value Exponent
@return `e` raised to the power of `value`
*/
Compares the values `a` and `b` with each other and returns the bigger of the two
@param a First value
@param b Second value
@return `a` if `a` is bigger than `b`, otherwise `b`
*/
fn max(auto a, auto b) {
if (a > b)
return a;
else
return b;
};
/**
Clamps the value of `x` between `min` and `max`.
@param x Value
@param min Minimum value
@param max Maximum value
@return `min` if `x` is smaller than `min`, `max` if `x` is bigger than `max`, `x` otherwise
*/
fn clamp(auto x, auto min, auto max) {
if (x < min)
return min;
else if (x > max)
return max;
else
return x;
};
/**
Returns the absolute value of `x`.
@param x Value
@return `x` if `x` is positive, `-x` otherwise
*/
fn abs(auto x) {
if (x < 0)
return -x;
else
return x;
};
/**
Returns the sign of `x`.
@param x Value
@return `1` if `x` is positive, `-1` if `x` is negative, `0` if `x` is zero
*/
fn sign(auto x) {
if (x > 0)
return 1;
else if (x < 0)
return -1;
else
return 0;
};
/**
Copies the sign of `y` to `x`.
@param x Value
@param y Value
@return `x` if `y` is positive, `-x` if `y` is negative
*/
fn copy_sign(auto x, auto y) {
if (y >= 0)
return std::math::abs(x);
else
return -std::math::abs(x);
};
/**
Calculates the factorial of `x`.
@param x Value
@return Factorial of `x`
*/
fn factorial(u128 x) {
u128 result;
result = x;
while (x > 1) {
x = x - 1;
result = result * x;
}
return result;
};
/**
Calculates the binomial coefficient of `n` and `k`.
@param n Value
@param k Value
@return Binomial coefficient of `n` and `k`
*/
fn comb(u128 n, u128 k) {
if (k > n)
return 0;
else
return std::math::factorial(n) / (std::math::factorial(k) * std::math::factorial(n - k));
};
/**
Calculates the permutation of `n` and `k`.
@param n Value
@param k Value
@return Permutation of `n` and `k`
*/
fn perm(u128 n, u128 k) {
if (k > n)
return 0;
else
return std::math::factorial(n) / std::math::factorial(n - k);
};
/**
Floors the value of `value`.
@param value Value
@return `value` floored
*/
fn floor(auto value) { return builtin::std::math::floor(value); };
/**
Ceils the value of `value`.
@param value Value
@return `value` ceiled
*/
fn ceil(auto value) { return builtin::std::math::ceil(value); };
/**
Rounds the value of `value`.
@param value Value
@return `value` rounded
*/
fn round(auto value) { return builtin::std::math::round(value); };
/**
Truncates the value of `value`.
@param value Value
@return `value` truncated
*/
fn trunc(auto value) { return builtin::std::math::trunc(value); };
/**
Calculates the logarithm of `value` with base 10.
@param value Value
@return Logarithm of `value` with base 10
*/
fn log10(auto value) { return builtin::std::math::log10(value); };
/**
Calculates the logarithm of `value` with base 2.
@param value Value
@return Logarithm of `value` with base 2
*/
fn log2(auto value) { return builtin::std::math::log2(value); };
/**
Calculates the natural logarithm of `value`.
@param value Value
@return Logarithm of `value` with base `e`
*/
fn ln(auto value) { return builtin::std::math::ln(value); };
/**
Calculates the floating point modulus of `value`.
@param value Value
@return Floating point modulus of `value`
*/
fn fmod(auto value) { return builtin::std::math::fmod(value); };
/**
Calculates the value of `base` raised to the power of `exp`.
@param base Base
@param exp Exponent
@return `base` raised to the power of `exp`
*/
fn pow(auto base, auto exp) { return builtin::std::math::pow(base, exp); };
/**
Calculates the value of the natural number `e` raised to the power of `value`.
@param value Exponent
@return `e` raised to the power of `value`
*/
fn exp(auto value) { return builtin::std::math::exp(value); };
/**
Calculates the square root of `value`.
@param value Value
@return Square root of `value`
*/
fn sqrt(auto value) { return builtin::std::math::sqrt(value); };
/**
Calculates the square root of `value`.
@param value Value
@return Square root of `value`
*/
fn sqrt(auto value) { return builtin::std::math::sqrt(value); };
/**
Calculates the cubic root of `value`.
@param value Value
@return Cubic root of `value`
*/
fn cbrt(auto value) { return builtin::std::math::cbrt(value); };
/**
Calculates the cubic root of `value`.
@param value Value
@return Cubic root of `value`
*/
fn cbrt(auto value) { return builtin::std::math::cbrt(value); };
/**
Calculates the sine of `value`.
@param value Angle value in radians
@return Sine of `value`
*/
fn sin(auto value) { return builtin::std::math::sin(value); };
/**
Calculates the sine of `value`.
@param value Angle value in radians
@return Sine of `value`
*/
fn sin(auto value) { return builtin::std::math::sin(value); };
/**
Calculates the cosine of `value`.
@param value Angle value in radians
@return Cosine of `value`
*/
fn cos(auto value) { return builtin::std::math::cos(value); };
/**
Calculates the cosine of `value`.
@param value Angle value in radians
@return Cosine of `value`
*/
fn cos(auto value) { return builtin::std::math::cos(value); };
/**
Calculates the tangent of `value`.
@param value Angle value in radians
@return Tangent of `value`
*/
fn tan(auto value) { return builtin::std::math::tan(value); };
/**
Calculates the tangent of `value`.
@param value Angle value in radians
@return Tangent of `value`
*/
fn tan(auto value) { return builtin::std::math::tan(value); };
/**
Calculates the arc sine of `value`.
@param value Angle value in radians
@return Arc sine of `value`
*/
fn asin(auto value) { return builtin::std::math::asin(value); };
/**
Calculates the arc sine of `value`.
@param value Angle value in radians
@return Arc sine of `value`
*/
fn asin(auto value) { return builtin::std::math::asin(value); };
/**
Calculates the arc cosine of `value`.
@param value Value
@return Arc cosine of `value` in radians
*/
fn acos(auto value) { return builtin::std::math::acos(value); };
/**
Calculates the arc cosine of `value`.
@param value Value
@return Arc cosine of `value` in radians
*/
fn acos(auto value) { return builtin::std::math::acos(value); };
/**
Calculates the arc tangent of `value`.
@param value Value
@return Arc tangent of `value` in radians between `-pi/2` and `pi/2`
*/
fn atan(auto value) { return builtin::std::math::atan(value); };
/**
Calculates the arc tangent of `value`.
@param value Value
@return Arc tangent of `value` in radians between `-pi/2` and `pi/2`
*/
fn atan(auto value) { return builtin::std::math::atan(value); };
/**
Calculates the arc tangent of `value`.
@param y Value representing the proportion of the y-coordinate
@param x Value representing the proportion of the x-coordinate.
@return Arc tangent of `value` in radians between `-pi` and `pi`
*/
fn atan2(auto y, auto x) { return builtin::std::math::atan2(y, x); };
/**
Calculates the arc tangent of `value`.
@param y Value representing the proportion of the y-coordinate
@param x Value representing the proportion of the x-coordinate.
@return Arc tangent of `value` in radians between `-pi` and `pi`
*/
fn atan2(auto y, auto x) { return builtin::std::math::atan2(y, x); };
/**
Calculates the hyperbolic sine of `value`.
@param value Angle value in radians
@return Hyperbolic sine of `value`
*/
fn sinh(auto value) { return builtin::std::math::sinh(value); };
/**
Calculates the hyperbolic sine of `value`.
@param value Angle value in radians
@return Hyperbolic sine of `value`
*/
fn sinh(auto value) { return builtin::std::math::sinh(value); };
/**
Calculates the hyperbolic cosine of `value`.
@param value Angle value in radians
@return Hyperbolic cosine of `value`
*/
fn cosh(auto value) { return builtin::std::math::cosh(value); };
/**
Calculates the hyperbolic cosine of `value`.
@param value Angle value in radians
@return Hyperbolic cosine of `value`
*/
fn cosh(auto value) { return builtin::std::math::cosh(value); };
/**
Calculates the hyperbolic tangent of `value`.
@param value Angle value in radians
@return Hyperbolic tangent of `value`
*/
fn tanh(auto value) { return builtin::std::math::tanh(value); };
/**
Calculates the hyperbolic tangent of `value`.
@param value Angle value in radians
@return Hyperbolic tangent of `value`
*/
fn tanh(auto value) { return builtin::std::math::tanh(value); };
/**
Calculates the arc hyperbolic sine of `value`.
@param value Value
@return Arc hyperbolic sine of `value`
*/
fn asinh(auto value) { return builtin::std::math::asinh(value); };
/**
Calculates the arc hyperbolic sine of `value`.
@param value Value
@return Arc hyperbolic sine of `value`
*/
fn asinh(auto value) { return builtin::std::math::asinh(value); };
/**
Calculates the arc hyperbolic cosine of `value`.
@param value Value
@return Arc hyperbolic cosine of `value`
*/
fn acosh(auto value) { return builtin::std::math::acosh(value); };
/**
Calculates the arc hyperbolic cosine of `value`.
@param value Value
@return Arc hyperbolic cosine of `value`
*/
fn acosh(auto value) { return builtin::std::math::acosh(value); };
/**
Calculates the arc hyperbolic tangent of `value`.
@param value Value
@return Arc hyperbolic tangent of `value`
*/
fn atanh(auto value) { return builtin::std::math::atanh(value); };
/**
Calculates the arc hyperbolic tangent of `value`.
@param value Value
@return Arc hyperbolic tangent of `value`
*/
fn atanh(auto value) { return builtin::std::math::atanh(value); };
/**
Options to use with the `std::math::accumulate` function.
*/
enum AccumulateOperation : u8 {
Add = 0,
Multiply = 1,
Modulo = 2,
Min = 3,
Max = 4
};
/**
Options to use with the `std::math::accumulate` function.
*/
enum AccumulateOperation : u8 {
Add = 0,
Multiply = 1,
Modulo = 2,
Min = 3,
Max = 4
};
/**
Calculates the sum of all values in the specified memory range.
@param start Start address
@param end End address
@param valueSize Size of each value in bytes
@param [section] Section to use
@param [operation] Operation to use. Defaults to addition
@param [endian] Endianness to use. Defaults to native
@return Sum of all values in the specified memory range
*/
fn accumulate(u128 start, u128 end, u128 valueSize, std::mem::Section section = 0, AccumulateOperation operation = AccumulateOperation::Add, std::mem::Endian endian = std::mem::Endian::Native) {
return builtin::std::math::accumulate(start, end, valueSize, section, u128(operation), u128(endian));
};
/**
Calculates the sum of all values in the specified memory range.
@param start Start address
@param end End address
@param valueSize Size of each value in bytes
@param section Section to use
@param operation Operation to use
@param endian Endianness to use
@return Sum of all values in the specified memory range
*/
fn accumulate(u128 start, u128 end, u128 valueSize, std::mem::Section section = 0, AccumulateOperation operation = AccumulateOperation::Add, std::mem::Endian endian = std::mem::Endian::Native) {
return builtin::std::math::accumulate(start, end, valueSize, section, u128(operation), u128(endian));
};
}

View File

@@ -9,18 +9,15 @@ namespace auto std::mem {
namespace impl {
struct MagicSearchImpl<auto Magic, T> {
if ($ < (std::mem::base_address() + 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;
s128 address = builtin::std::mem::find_string_in_range(0, $, builtin::std::mem::size(), Magic);
if (address < 0)
break;
$ = address;
try {
T data [[inline]];
} catch {
T data;
}
};
@@ -32,7 +29,7 @@ namespace auto std::mem {
using Section = u128;
/**
The Endianess of a value
The endianness of a value
*/
enum Endian : u8 {
Native = 0,
@@ -49,6 +46,15 @@ namespace auto std::mem {
return $ >= (std::mem::base_address() + std::mem::size());
};
/**
Function that returns true if the cursor position is at or beyond the given address
@param address The address to compare against
@return True if the cursor is at or beyond the given address
*/
fn reached(u128 address) {
return $ >= address;
};
/**
Aligns the given value to the given alignment
@param alignment The alignment to align to
@@ -60,10 +66,10 @@ namespace auto std::mem {
return remainder != 0 ? value + (alignment - remainder) : value;
};
/**
Gets the base address of the memory
Gets the base address of the data
@return The base address of the memory
*/
fn base_address() {
@@ -71,7 +77,7 @@ namespace auto std::mem {
};
/**
Gets the size of the memory
Gets the size of the data
@return The size of the memory
*/
fn size() {
@@ -79,17 +85,18 @@ namespace auto std::mem {
};
/**
Finds a sequence of bytes in the memory
Finds a sequence of bytes in the data
@param occurrence_index The index of the occurrence to find
@param bytes The bytes to find
@return The address of the sequence
*/
fn find_sequence(u128 occurrence_index, auto ... bytes) {
return builtin::std::mem::find_sequence_in_range(occurrence_index, builtin::std::mem::base_address(), builtin::std::mem::size(), bytes);
const u128 address = builtin::std::mem::base_address();
return builtin::std::mem::find_sequence_in_range(occurrence_index, address, address + builtin::std::mem::size(), bytes);
};
/**
Finds a sequence of bytes in a specific region of the memory
Finds a sequence of bytes in a specific region of the data
@param occurrence_index The index of the occurrence to find
@param offsetFrom The offset from which to start searching
@param offsetTo The offset to which to search
@@ -100,11 +107,35 @@ namespace auto std::mem {
return builtin::std::mem::find_sequence_in_range(occurrence_index, offsetFrom, offsetTo, bytes);
};
/**
Finds a string in the data
@param occurrence_index The index of the occurrence to find
@param string The string to find
@return The address of the sequence
*/
fn find_string(u128 occurrence_index, str string) {
const u128 address = builtin::std::mem::base_address();
return builtin::std::mem::find_string_in_range(occurrence_index, address, address + builtin::std::mem::size(), string);
};
/**
Finds a string in a specific region of the data
@param occurrence_index The index of the occurrence to find
@param offsetFrom The offset from which to start searching
@param offsetTo The offset to which to search
@param string The string to find
@return The address of the sequence
*/
fn find_string_in_range(u128 occurrence_index, u128 offsetFrom, u128 offsetTo, str string) {
return builtin::std::mem::find_string_in_range(occurrence_index, offsetFrom, offsetTo, string);
};
/**
Reads a unsigned value from the memory
@param address The address to read from
@param size The size of the value to read
@param endian The endianess of the value to read
@param [endian] The endianness of the value to read. Defaults to native
@return The value read
*/
fn read_unsigned(u128 address, u8 size, Endian endian = Endian::Native) {
@@ -115,7 +146,7 @@ namespace auto std::mem {
Reads a signed value from the memory
@param address The address to read from
@param size The size of the value to read
@param endian The endianess of the value to read
@param [endian] The endianness of the value to read. Defaults to native
@return The value read
*/
fn read_signed(u128 address, u8 size, Endian endian = Endian::Native) {
@@ -132,14 +163,6 @@ namespace auto std::mem {
return builtin::std::mem::read_string(address, size);
};
/**
Gets the current bit offset within the current byte that a bitfield will read.
*/
fn current_bit_offset() {
return builtin::std::mem::current_bit_offset();
};
/**
Reads a number of bits from the specified bit offset within the specified byte
@param byteOffset The byte offset within the data
@@ -211,6 +234,14 @@ namespace auto std::mem {
builtin::std::mem::copy_value_to_section(value, to_section, to_address);
};
/**
Returns the current bit offset when inside of a bitfield.
@return The current bit offset between 0 and 7
*/
fn current_bit_offset() {
return builtin::std::mem::current_bit_offset();
};
/**
Searches for a sequence of bytes and places the given type at that address
@@ -227,10 +258,10 @@ namespace auto std::mem {
@tparam To The type to reinterpret to
*/
union Reinterpreter<From, To> {
From from;
To to;
From from_value;
To to_value;
};
/**
Aligns the cursor to the given alignment
@@ -249,11 +280,11 @@ namespace auto std::mem {
} [[sealed, format("std::mem::impl::format_bytes")]];
namespace impl {
fn format_bytes(auto bytes) {
return "";
};
}
}

View File

@@ -57,7 +57,7 @@ namespace auto std::ptr {
// `pointerValue` is `no_unique_address` because we don't want to advance
// the current memory location after reading the value of the pointer itself;
// we want to examine the value at this address to determine what should be
// displayed. It's also `hidden` so the editor only displays either thee
// displayed. It's also `hidden` so the editor only displays either thee
// padding or the populated pointer/pointee field.
PointerTy pointerValue [[no_unique_address, hidden]];
if (pointerValue == 0x0) {

View File

@@ -7,7 +7,7 @@ import std.limits;
*/
namespace auto std::random {
/**
Represents the type of distribution to use to generate a random number
*/
@@ -61,21 +61,21 @@ namespace auto std::random {
> - `Poisson(mean) -> i128`
@param distribution Distribution to use
@param param1 This parameter depends on the type of distribution used.
@param param2 This parameter depends on the type of distribution used.
@param [param1] This parameter depends on the type of distribution used. Defaults to 0
@param [param2] This parameter depends on the type of distribution used. Defaults to 0
*/
fn generate_using(Distribution distribution, auto param1 = 0, auto param2 = 0) {
return builtin::std::random::generate(u32(distribution), param1, param2);
};
/**
Generates a uniformly distributed random number between `min` and `max`
@param min Minimum number
@param max Maximum number
@param [min] Minimum number. Defaults to 0
@param [max] Maximum number. Defaults to `u64_max`
*/
fn generate(u64 min = std::limits::u64_min(), u64 max = std::limits::u64_max()) {
return std::random::generate_using(Distribution::Uniform, min, max);
};
}

View File

@@ -1,129 +1,153 @@
#pragma once
import std.io;
import std.mem;
/*!
Libray to interact with strings.
Library to interact with strings.
*/
namespace auto std::string {
/**
Base type for sized strings. Represents a string with its size preceeding it.
@tparam SizeType The type of the size field.
@tparam DataType The type of the characters.
*/
struct SizedStringBase<SizeType, DataType> {
SizeType size;
DataType data[size];
} [[sealed, format("std::string::impl::format_sized_string"), transform("std::string::impl::format_sized_string")]];
/**
Base type for sized strings. Represents a string with its size preceding it.
@tparam SizeType The type of the size field.
@tparam DataType The type of the characters.
*/
struct SizedStringBase<SizeType, DataType> {
SizeType size;
DataType data[size];
} [[sealed, format("std::string::impl::format_string"), transform("std::string::impl::format_string")]];
/**
A ASCII string with a prefixed size.
@tparam SizeType The type of the size field.
*/
using SizedString<SizeType> = SizedStringBase<SizeType, char>;
/**
A ASCII string with a prefixed size.
@tparam SizeType The type of the size field.
*/
using SizedString<SizeType> = SizedStringBase<SizeType, char>;
/**
A UTF-16 string with a prefixed size.
@tparam SizeType The type of the size field.
*/
using SizedString16<SizeType> = SizedStringBase<SizeType, char16>;
/**
A UTF-16 string with a prefixed size.
@tparam SizeType The type of the size field.
*/
using SizedString16<SizeType> = SizedStringBase<SizeType, char16>;
namespace impl {
/**
Base type for null-terminated strings. Represents a string with its size determined by the first 0x00 byte found.
@tparam DataType The type of the characters.
*/
struct NullStringBase<DataType> {
DataType data[while(std::mem::read_unsigned($, sizeof(DataType)) != 0x00)];
DataType null_terminator;
} [[sealed, format("std::string::impl::format_string"), transform("std::string::impl::format_string")]];
fn format_sized_string(ref auto string) {
return string.data;
};
/**
A null-terminated ASCII string.
*/
using NullString = NullStringBase<char>;
}
/**
A null-terminated UTF-16 string.
*/
using NullString16 = NullStringBase<char16>;
/**
Gets the length of a string.
@param string The string to get the length of.
@return The length of the string.
*/
fn length(str string) {
return builtin::std::string::length(string);
};
namespace impl {
/**
Gets the character at a given index.
@param string The string to get the character from.
@param index The index of the character to get.
@return The character at the given index.
*/
fn at(str string, u32 index) {
return builtin::std::string::at(string, index);
};
fn format_string(ref auto string) {
return string.data;
};
/**
Gets a substring of a string.
@param string The string to get the substring from.
@param pos The position of the first character of the substring.
@param count The number of characters to get.
@return The substring.
*/
fn substr(str string, u32 pos, u32 count) {
return builtin::std::string::substr(string, pos, count);
};
}
/**
Gets the length of a string.
@param string The string to get the length of.
@return The length of the string.
*/
fn length(str string) {
return builtin::std::string::length(string);
};
/**
Gets the character at a given index.
@param string The string to get the character from.
@param index The index of the character to get.
@return The character at the given index.
*/
fn at(str string, u32 index) {
return builtin::std::string::at(string, index);
};
/**
Gets a substring of a string.
@param string The string to get the substring from.
@param pos The position of the first character of the substring.
@param count The number of characters to get.
@return The substring.
*/
fn substr(str string, u32 pos, u32 count) {
return builtin::std::string::substr(string, pos, count);
};
/**
Converts a string to an integer.
@param string The string to convert.
@param base The base of the number.
@return The integer.
*/
fn parse_int(str string, u8 base) {
return builtin::std::string::parse_int(string, base);
};
/**
Converts a string to an integer.
@param string The string to convert.
@param base The base of the number.
@return The integer.
*/
fn parse_int(str string, u8 base) {
return builtin::std::string::parse_int(string, base);
};
/**
Converts a string to a float.
@param string The string to convert.
@return The float.
*/
fn parse_float(str string) {
return builtin::std::string::parse_float(string);
};
/**
Converts a string to a float.
@param string The string to convert.
@return The float.
*/
fn parse_float(str string) {
return builtin::std::string::parse_float(string);
};
/**
Converts any type to a string.
@param x The value to convert.
@return The string.
*/
/**
Converts any type to a string.
@param x The value to convert.
@return The string.
*/
fn to_string(auto x) {
return std::format("{}", x);
};
/**
Checks if a string starts with a given substring.
@param string The string to check.
@param part The substring to check for.
@return True if the string starts with the substring, false otherwise.
*/
/**
Checks if a string starts with a given substring.
@param string The string to check.
@param part The substring to check for.
@return True if the string starts with the substring, false otherwise.
*/
fn starts_with(str string, str part) {
if (std::string::length(string) < std::string::length(part))
return false;
return std::string::substr(string, 0, std::string::length(part)) == part;
};
/**
Checks if a string ends with a given substring.
@param string The string to check.
@param part The substring to check for.
@return True if the string ends with the substring, false otherwise.
*/
/**
Checks if a string ends with a given substring.
@param string The string to check.
@param part The substring to check for.
@return True if the string ends with the substring, false otherwise.
*/
fn ends_with(str string, str part) {
if (std::string::length(string) < std::string::length(part))
return false;
return std::string::substr(string, std::string::length(string) - std::string::length(part), std::string::length(part)) == part;
};
/**
Checks if a string contains a given substring.
@param string The string to check.
@param part The substring to check for.
@return True if the string contains the substring, false otherwise.
*/
/**
Checks if a string contains a given substring.
@param string The string to check.
@param part The substring to check for.
@return True if the string contains the substring, false otherwise.
*/
fn contains(str string, str part) {
s32 string_len = std::string::length(string);
s32 part_len = std::string::length(part);
@@ -136,100 +160,100 @@ namespace auto std::string {
return false;
};
/**
Reverses a string.
@param string The string to reverse.
@return The reversed string.
*/
fn reverse(str string) {
/**
Reverses a string.
@param string The string to reverse.
@return The reversed string.
*/
fn reverse(str string) {
str result;
s32 i;
i = std::string::length(string);
while (i > 0) {
i = i - 1;
result = result + std::string::at(string, i);
}
return result;
};
/**
Converts a string to upper case.
@param string The string to convert.
@return The converted string.
*/
/**
Converts a string to upper case.
@param string The string to convert.
@return The converted string.
*/
fn to_upper(str string) {
str result;
u32 i;
char c;
while (i < std::string::length(string)) {
c = std::string::at(string, i);
if (c >= 'a' && c <= 'z')
result = result + char(c - 0x20);
else
result = result + c;
i = i + 1;
}
return result;
};
/**
Converts a string to lower case.
@param string The string to convert.
@return The converted string.
*/
fn to_lower(str string) {
str result;
u32 i;
char c;
while (i < std::string::length(string)) {
c = std::string::at(string, i);
if (c >= 'A' && c <= 'Z')
result = result + char(c + 0x20);
else
result = result + c;
i = i + 1;
}
return result;
};
str result;
/**
Replaces all occurrences of a substring with another substring.
@param string The string to replace in.
@param pattern The substring to replace.
@param replace The substring to replace with.
@return The string with the replacements.
*/
fn replace(str string, str pattern, str replace) {
s32 string_len = std::string::length(string);
s32 pattern_len = std::string::length(pattern);
u32 i;
char c;
while (i < std::string::length(string)) {
c = std::string::at(string, i);
if (pattern_len > string_len || pattern_len * string_len == 0 )
return string;
if (c >= 'a' && c <= 'z')
result = result + char(c - 0x20);
else
result = result + c;
str result;
s32 string_index;
s32 remaining_len = string_len;
while (pattern_len <= remaining_len) {
if (std::string::substr(string, string_index, pattern_len) == pattern) {
result += replace;
string_index += pattern_len;
} else {
result += std::string::at(string, string_index);
string_index += 1;
}
remaining_len = string_len - string_index;
}
result += std::string::substr(string, string_index, remaining_len );
return result;
};
i = i + 1;
}
return result;
};
/**
Converts a string to lower case.
@param string The string to convert.
@return The converted string.
*/
fn to_lower(str string) {
str result;
u32 i;
char c;
while (i < std::string::length(string)) {
c = std::string::at(string, i);
if (c >= 'A' && c <= 'Z')
result = result + char(c + 0x20);
else
result = result + c;
i = i + 1;
}
return result;
};
/**
Replaces all occurrences of a substring with another substring.
@param string The string to replace in.
@param pattern The substring to replace.
@param replace The substring to replace with.
@return The string with the replacements.
*/
fn replace(str string, str pattern, str replace) {
s32 string_len = std::string::length(string);
s32 pattern_len = std::string::length(pattern);
if (pattern_len > string_len || pattern_len * string_len == 0 )
return string;
str result;
s32 string_index;
s32 remaining_len = string_len;
while (pattern_len <= remaining_len) {
if (std::string::substr(string, string_index, pattern_len) == pattern) {
result += replace;
string_index += pattern_len;
} else {
result += std::string::at(string, string_index);
string_index += 1;
}
remaining_len = string_len - string_index;
}
result += std::string::substr(string, string_index, remaining_len );
return result;
};
}

View File

@@ -10,7 +10,7 @@ namespace auto std {
/**
Asserts that a given value is true. If it's not, abort evaluation and print the given message to the console
@param conditoon The condition that is required to be true
@param condition The condition that is required to be true
@param message The message to print in case the assertion doesn't hold
*/
fn assert(bool condition, str message) {
@@ -21,7 +21,7 @@ namespace auto std {
/**
Asserts that a given value is true. If it's not, print the given message to the console as a warning
@param conditoon The condition that is required to be true
@param condition The condition that is required to be true
@param message The message to print in case the assertion doesn't hold
*/
fn assert_warn(bool condition, str message) {
@@ -49,4 +49,11 @@ namespace auto std {
return builtin::std::sizeof_pack(pack);
};
/**
Throws an error notifying the developer that the current code path is not implemented currently.
*/
fn unimplemented() {
std::error("Unimplemented code path reached!");
};
}

View File

@@ -3,198 +3,198 @@
import std.io;
/*!
Library to handle time and date related operations.
Library to handle time and date related operations.
*/
namespace auto std::time {
/**
A structured representation of a time and date.
*/
struct Time {
u8 sec;
u8 min;
u8 hour;
u8 mday;
u8 mon;
u16 year;
u8 wday;
u16 yday;
bool isdst;
} [[sealed]];
/**
A structured representation of a time and date.
*/
struct Time {
u8 sec;
u8 min;
u8 hour;
u8 mday;
u8 mon;
u16 year;
u8 wday;
u16 yday;
bool isdst;
} [[sealed]];
/**
A helper type to convert between Time and u128.
*/
union TimeConverter {
Time time;
u128 value;
};
/**
A helper type to convert between Time and u128.
*/
union TimeConverter {
Time time;
u128 value;
};
/**
A type to represent a time in seconds since the epoch.
*/
using EpochTime = u32;
/**
A type to represent a time in seconds since the epoch.
*/
using EpochTime = u32;
/**
A type to represent a time zone.
*/
enum TimeZone : u8 {
Local,
UTC
};
/**
A type to represent a time zone.
*/
enum TimeZone : u8 {
Local,
UTC
};
/**
A type to represent a DOS date.
*/
bitfield DOSDate {
day: 5;
month: 4;
year: 7;
} [[sealed]];
/**
A type to represent a DOS date.
*/
bitfield DOSDate {
day: 5;
month: 4;
year: 7;
} [[sealed]];
/**
A type to represent a DOS time.
*/
bitfield DOSTime {
seconds: 5;
minutes: 6;
hours: 5;
} [[sealed]];
/**
A type to represent a DOS time.
*/
bitfield DOSTime {
seconds: 5;
minutes: 6;
hours: 5;
} [[sealed]];
namespace impl {
namespace impl {
union DOSDateConverter {
DOSDate date;
u16 value;
};
union DOSDateConverter {
DOSDate date;
u16 value;
};
union DOSTimeConverter {
DOSTime time;
u16 value;
};
union DOSTimeConverter {
DOSTime time;
u16 value;
};
}
}
/**
Returns the current time in seconds since the epoch.
@return The current time in seconds since the epoch.
*/
fn epoch() {
return builtin::std::time::epoch();
};
/**
Returns the current time in seconds since the epoch.
@return The current time in seconds since the epoch.
*/
fn epoch() {
return builtin::std::time::epoch();
};
/**
Converts a time in seconds since the epoch to a local time.
@param epoch_time The time in seconds since the epoch.
@return The local time.
*/
fn to_local(EpochTime epoch_time) {
le TimeConverter converter;
/**
Converts a time in seconds since the epoch to a local time.
@param epoch_time The time in seconds since the epoch.
@return The local time.
*/
fn to_local(EpochTime epoch_time) {
le TimeConverter converter;
converter.value = builtin::std::time::to_local(epoch_time);
converter.value = builtin::std::time::to_local(epoch_time);
return converter.time;
};
return converter.time;
};
/**
Converts a time in seconds since the epoch to a UTC time.
@param epoch_time The time in seconds since the epoch.
@return The UTC time.
*/
fn to_utc(EpochTime epoch_time) {
le TimeConverter converter;
/**
Converts a time in seconds since the epoch to a UTC time.
@param epoch_time The time in seconds since the epoch.
@return The UTC time.
*/
fn to_utc(EpochTime epoch_time) {
le TimeConverter converter;
converter.value = builtin::std::time::to_utc(epoch_time);
converter.value = builtin::std::time::to_utc(epoch_time);
return converter.time;
};
return converter.time;
};
/**
Queries the current time in the specified time zone.
@param time_zone The time zone to query.
@return The current time in the specified time zone.
*/
fn now(TimeZone time_zone = TimeZone::Local) {
le TimeConverter converter;
/**
Queries the current time in the specified time zone.
@param [time_zone] The time zone to query. Defaults to local.
@return The current time in the specified time zone.
*/
fn now(TimeZone time_zone = TimeZone::Local) {
le 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;
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;
};
return converter.time;
};
/**
Converts a value to a DOS date.
@param value The value to convert.
@return The DOS date.
*/
fn to_dos_date(u16 value) {
le impl::DOSDateConverter converter;
/**
Converts a value to a DOS date.
@param value The value to convert.
@return The DOS date.
*/
fn to_dos_date(u16 value) {
le impl::DOSDateConverter converter;
converter.value = value;
converter.value = value;
return converter.date;
};
return converter.date;
};
/**
Converts a value to a DOS time.
@param value The value to convert.
@return The DOS time.
*/
fn to_dos_time(u16 value) {
le impl::DOSTimeConverter converter;
/**
Converts a value to a DOS time.
@param value The value to convert.
@return The DOS time.
*/
fn to_dos_time(u16 value) {
le impl::DOSTimeConverter converter;
converter.value = value;
converter.value = value;
return converter.time;
};
return converter.time;
};
/**
Converts a FILETIME to unix time.
@param value The value to convert.
@return Timestamp formatted as unix time.
*/
fn filetime_to_unix(u64 value) {
return value / 10000000 - 11644473600;
};
/**
Converts a FILETIME to unix time.
@param value The value to convert.
@return Timestamp formatted as unix time.
*/
fn filetime_to_unix(u64 value) {
return value / 10000000 - 11644473600;
};
/**
Formats a time according to the specified format string.
@param time The time to format.
@param format_string The format string to use.
@return The formatted time.
*/
fn format(Time time, str format_string = "%c") {
le TimeConverter converter;
converter.time = time;
/**
Formats a time according to the specified format string.
@param time The time to format.
@param [format_string] The format string to use. Defaults to "%c".
@return The formatted time.
*/
fn format(Time time, str format_string = "%c") {
le TimeConverter converter;
converter.time = time;
return builtin::std::time::format(format_string, converter.value);
};
return builtin::std::time::format(format_string, converter.value);
};
/**
Formats a DOS date according to the specified format string.
@param date The DOS date to format.
@param format_string The format string to use.
@return The formatted DOS date.
*/
fn format_dos_date(DOSDate date, str format_string = "{}/{}/{}") {
return std::format(format_string, date.day, date.month, date.year + 1980);
};
/**
Formats a DOS date according to the specified format string.
@param date The DOS date to format.
@param [format_string] The format string to use. Defaults to "{}/{}/{}".
@return The formatted DOS date.
*/
fn format_dos_date(DOSDate date, str format_string = "{}/{}/{}") {
return std::format(format_string, date.day, date.month, date.year + 1980);
};
/**
Formats a DOS time according to the specified format string.
@param time The DOS time to format.
@param format_string The format string to use.
@return The formatted DOS time.
*/
fn format_dos_time(DOSTime time, str format_string = "{:02}:{:02}:{:02}") {
return std::format(format_string, time.hours, time.minutes, time.seconds * 2);
};
/**
Formats a DOS time according to the specified format string.
@param time The DOS time to format.
@param [format_string] The format string to use. Defaults to "{:02}:{:02}:{:02}".
@return The formatted DOS time.
*/
fn format_dos_time(DOSTime time, str format_string = "{:02}:{:02}:{:02}") {
return std::format(format_string, time.hours, time.minutes, time.seconds * 2);
};
}

View File

@@ -34,7 +34,7 @@ namespace auto type {
*/
using Bin<T> = T [[format("type::impl::format_bin")]];
namespace impl {
namespace impl {
fn format_number(auto value, str fmt) {
bool negative = value < 0;
@@ -50,6 +50,6 @@ namespace auto type {
fn format_dec(auto value) { return type::impl::format_number(value, "{}"); };
fn format_bin(auto value) { return type::impl::format_number(value, "0b{:08b}"); };
}
}
}

View File

@@ -1,13 +1,14 @@
#pragma once
import std.io;
import std.core;
/*!
Types to display single bytes using various different representations
*/
namespace auto type {
/**
Type visualizing the value of each individual bit
*/
@@ -20,8 +21,8 @@ namespace auto type {
bit5 : 1;
bit6 : 1;
bit7 : 1;
} [[format("type::impl::format_bits"), right_to_left]];
} [[format("type::impl::format_bits"), bitfield_order(std::core::BitfieldOrder::LeastToMostSignificant, 8)]];
/**
Type visualizing the value of the two nibbles
*/
@@ -29,9 +30,9 @@ namespace auto type {
low : 4;
high : 4;
} [[format("type::impl::format_nibbles")]];
/**
Type representing a single Byte. Decodes the byte as it's hexadeicmal value, individual bits and nibbles
Type representing a single Byte. Decodes the byte as it's hexadecimal value, individual bits and nibbles
*/
union Byte {
u8 value;
@@ -40,7 +41,7 @@ namespace auto type {
} [[format("type::impl::format_byte"), single_color]];
namespace impl {
namespace impl {
fn format_byte(Byte byte) {
return std::format("0x{0:02X} (0b{1:08b}) LSB:{2}, MSB:{3}",
@@ -49,9 +50,9 @@ namespace auto type {
byte.bits.bit0,
byte.bits.bit7);
};
fn format_bits(Bits bits) {
return std::format("0b{}{}{}{}{}{}{}{}",
return std::format("0b{}{}{}{}{}{}{}{}",
bits.bit7,
bits.bit6,
bits.bit5,
@@ -61,11 +62,11 @@ namespace auto type {
bits.bit1,
bits.bit0);
};
fn format_nibbles(Nibbles nibbles) {
return std::format("{{ {0:0X}, {1:0X} }}", nibbles.high, nibbles.low);
};
}
}
}

View File

@@ -14,7 +14,7 @@ namespace auto type {
@tparam R Number of bits used for the red component
@tparam G Number of bits used for the green component
@tparam B Number of bits used for the blue component
@tparam A Number of bits used for the alpha component
@tparam A Number of bits used for the alpha component
*/
bitfield RGBA<auto R, auto G, auto B, auto A> {
r : R;
@@ -22,7 +22,7 @@ namespace auto type {
b : B;
if (A > 0) a : A;
} [[sealed, format("type::impl::format_color"), color(std::format("{0:02X}{1:02X}{2:02X}FF", r, g, b))]];
/**
Type representing a generic RGB color with a variable number of bits for each color
@tparam R Number of bits used for the red component
@@ -30,7 +30,7 @@ namespace auto type {
@tparam B Number of bits used for the blue component
*/
using RGB<auto R, auto G, auto B> = RGBA<R,G,B,0>;
/**
Type representing a RGBA color with 8 bits for the red component, 8 bits for green, 8 bits for blue and 8 bits for alpha
@@ -56,7 +56,7 @@ namespace auto type {
Type representing a RGBA color with 5 bits for the red component, 5 bits for green, 5 bits for blue and 1 bits for alpha
*/
using RGBA5551 = RGBA<5,5,5,1>;
namespace impl {
@@ -76,5 +76,5 @@ namespace auto type {
};
}
}

View File

@@ -9,37 +9,37 @@ import std.mem;
*/
namespace auto type {
/**
Type representing a 16 bit half precision floating point number
*/
using float16 = u16 [[format("type::impl::format_float16")]];
namespace impl {
union U32ToFloatConverter {
u32 intValue;
float floatValue;
};
fn format_float16(float16 value) {
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);
}
@@ -48,11 +48,11 @@ namespace auto type {
} else {
result = (sign << 31) | ((exponent + (0x7F - 15)) << 23) | (mantissa << 13);
}
std::mem::Reinterpreter<u32, float> converter;
converter.from = result;
return std::format("{}", converter.to);
converter.from_value = result;
return std::format("{}", converter.to_value);
};
}

42
includes/type/fmt.pat Normal file
View File

@@ -0,0 +1,42 @@
#pragma once
import std.io;
/*!
Type that allows specifying its format value using a format string.
## Usage
The following code reads a u32 from the data and formats it as an upper case hexadecimal value with
a minimum of 8 digits which is prefixed by 0x.
The format string is the same as passed to `std::format()` and follows the libfmt specification.
```rust
type::Formatted<u32, "0x{:08X}"> hex_formatted_integer @ 0x00;
```
*/
namespace auto type {
/**
Arbitrarily formatted type
@tparam T Type to format
@tparam FormatString libfmt format string to format the value
*/
struct Formatted<T, auto FormatString> {
T value;
} [[sealed, format("type::impl::format_formatted"), transform("type::impl::transform_formatted")]];
namespace impl {
fn format_formatted(ref auto formatted) {
return std::format(formatted.FormatString, formatted.value);
};
fn transform_formatted(ref auto formatted) {
return formatted.value;
};
}
}

View File

@@ -3,15 +3,15 @@
import std.io;
/*!
Types to deal with UUIDs (Universally Unique Identifiers) / GUIDs (Globally Unique Identifiers) as described in RFC 4122
Types to deal with UUIDs (Universally Unique Identifiers) / GUIDs (Globally Unique Identifiers) as described in RFC 4122
*/
namespace auto type {
/**
Type representing a GUID value
*/
struct GUID {
/**
Type representing a GUID value
*/
struct GUID {
u32 time_low;
u16 time_mid;
u16 time_high_and_version;
@@ -20,31 +20,31 @@ namespace auto type {
u8 node[6];
} [[sealed, format("type::impl::format_guid")]];
/**
Alias name for GUID
*/
using UUID = GUID;
/**
Alias name for GUID
*/
using UUID = GUID;
namespace impl {
namespace impl {
fn format_guid(GUID guid) {
bool valid = ((le u16(guid.time_high_and_version) >> 12) <= 5) && (((guid.clock_seq_and_reserved >> 4) >= 8) || ((guid.clock_seq_and_reserved >> 4) == 0));
return std::format("{}{{{:08X}-{:04X}-{:04X}-{:02X}{:02X}-{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}}}",
valid ? "" : "Invalid ",
le u32(guid.time_low),
le u16(guid.time_mid),
le u16(guid.time_high_and_version),
guid.clock_seq_and_reserved,
guid.clock_seq_low,
guid.node[0],
guid.node[1],
guid.node[2],
guid.node[3],
guid.node[4],
guid.node[5]);
};
fn format_guid(GUID guid) {
bool valid = ((le u16(guid.time_high_and_version) >> 12) <= 5) && (((guid.clock_seq_and_reserved >> 4) >= 8) || ((guid.clock_seq_and_reserved >> 4) == 0));
}
return std::format("{}{{{:08X}-{:04X}-{:04X}-{:02X}{:02X}-{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}}}",
valid ? "" : "Invalid ",
le u32(guid.time_low),
le u16(guid.time_mid),
le u16(guid.time_high_and_version),
guid.clock_seq_and_reserved,
guid.clock_seq_low,
guid.node[0],
guid.node[1],
guid.node[2],
guid.node[3],
guid.node[4],
guid.node[5]);
};
}
}

View File

@@ -4,69 +4,69 @@ import std.io;
import std.mem;
/*!
Types used to decode Little Endian Base 128 numbers used to store large numbers as space efficiently as possible
Types used to decode Little Endian Base 128 numbers used to store large numbers as space efficiently as possible
*/
namespace auto type {
/**
Base LEB128 type. Use `uLEB128` and `sLEB128` instead.
*/
struct LEB128Base {
u8 array[while($ == addressof(this) || std::mem::read_unsigned($-1, 1) & 0x80 != 0)] [[hidden]];
} [[sealed]];
/**
A unsigned variant of a LEB128 number
*/
using uLEB128 = LEB128Base [[format("type::impl::format_uleb128"), transform("type::impl::transform_uleb128")]];
/**
Base LEB128 type. Use `uLEB128` and `sLEB128` instead.
*/
struct LEB128Base {
u8 array[while($ == addressof(this) || std::mem::read_unsigned($-1, 1) & 0x80 != 0)] [[hidden]];
} [[sealed]];
/**
A signed variant of a LEB128 number
*/
using sLEB128 = LEB128Base [[format("type::impl::format_sleb128"), transform("type::impl::transform_sleb128")]];
/**
A unsigned variant of a LEB128 number
*/
using uLEB128 = LEB128Base [[format("type::impl::format_uleb128"), transform("type::impl::transform_uleb128")]];
/**
Legacy alias for uLEB128
*/
using LEB128 = uLEB128;
namespace impl {
fn transform_uleb128_array(ref auto array) {
u128 res = array[0] & 0x7f;
for(u8 i = 1, array[i-1] & 0x80 != 0, i+=1) {
res |= u128(array[i] & 0x7f) << 7 * i;
}
return res;
};
/**
A signed variant of a LEB128 number
*/
using sLEB128 = LEB128Base [[format("type::impl::format_sleb128"), transform("type::impl::transform_sleb128")]];
fn transform_sleb128_array(ref auto array) {
s128 res = type::impl::transform_uleb128_array(array);
if (res & 0x40 != 0) {
res |= ~0 << (sizeof(array) / sizeof(u8)) * 7;
}
return res;
};
fn format_uleb128(ref auto leb128) {
u128 res = type::impl::transform_uleb128_array(leb128.array);
return std::format("{} ({:#x})", res, res);
};
fn transform_uleb128(ref auto leb128) {
return type::impl::transform_uleb128_array(leb128.array);
};
/**
Legacy alias for uLEB128
*/
using LEB128 = uLEB128;
fn format_sleb128(ref auto leb128) {
s128 res = type::impl::transform_sleb128_array(leb128.array);
return std::format("{} ({:#x})", res, res);
};
fn transform_sleb128(ref auto leb128) {
return type::impl::transform_sleb128_array(leb128.array);
};
namespace impl {
fn transform_uleb128_array(ref auto array) {
u128 res = array[0] & 0x7f;
for(u8 i = 1, array[i-1] & 0x80 != 0, i+=1) {
res |= u128(array[i] & 0x7f) << 7 * i;
}
return res;
};
fn transform_sleb128_array(ref auto array) {
s128 res = type::impl::transform_uleb128_array(array);
if (res & 1 << ((sizeof(array) / sizeof(u8)) * 7 - 1) != 0) {
res |= ~0 << (sizeof(array) / sizeof(u8)) * 7;
}
return res;
};
fn format_uleb128(ref auto leb128) {
u128 res = type::impl::transform_uleb128_array(leb128.array);
return std::format("{} ({:#x})", res, res);
};
fn transform_uleb128(ref auto leb128) {
return type::impl::transform_uleb128_array(leb128.array);
};
fn format_sleb128(ref auto leb128) {
s128 res = type::impl::transform_sleb128_array(leb128.array);
return std::format("{} ({:#x})", res, res);
};
fn transform_sleb128(ref auto leb128) {
return type::impl::transform_sleb128_array(leb128.array);
};
}
}
}

View File

@@ -3,30 +3,30 @@
import std.io;
/*!
Types used to decode MAC Addresses
Types used to decode MAC Addresses
*/
namespace auto type {
/**
A MAC Address as used in the Internet Protocol
*/
struct MACAddress {
u8 bytes[6];
} [[sealed, format("type::impl::format_mac_address")]];
/**
A MAC Address as used in the Internet Protocol
*/
struct MACAddress {
u8 bytes[6];
} [[sealed, format("type::impl::format_mac_address")]];
namespace impl {
namespace impl {
fn format_mac_address(MACAddress address) {
return std::format("{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
address.bytes[0],
address.bytes[1],
address.bytes[2],
address.bytes[3],
address.bytes[4],
address.bytes[5]);
};
return std::format("{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
address.bytes[0],
address.bytes[1],
address.bytes[2],
address.bytes[3],
address.bytes[4],
address.bytes[5]);
};
}
}
}

View File

@@ -9,8 +9,13 @@ import std.ctype;
namespace auto type
{
fn fm(ref auto value)
{
/**
Escapes all bytes in a string to only contain printable characters. All non-printable bytes will be transformed to sequences in the form form \xFF
@param value Byte array to escape
@return Escaped string
*/
fn escape_bytes(ref auto value) {
str result;
for (u32 i = 0, i < sizeof(value), i += 1)
{
@@ -21,23 +26,20 @@ namespace auto type
else
result += std::format("\\x{:02X}", u8(c));
}
return std::format("\"{}\"", result);
return result;
};
/**
A Magic number. Throws an error if the magic number does not match the expected value
@tparam ExpectedValue A string representing the expected value
*/
struct Magic<auto ExpectedValue>
{
struct Magic<auto ExpectedValue> {
char value[std::string::length(ExpectedValue)];
std::assert_warn(value == ExpectedValue, std::format("Invalid magic value! Expected {}, got {} at position 0x{:X}", type::fm(ExpectedValue), type::fm(value), $ - std::string::length(ExpectedValue)));
std::assert(value == ExpectedValue, std::format("Invalid magic value! Expected \"{}\", got \"{}\" at position 0x{:X}", type::escape_bytes(ExpectedValue), type::escape_bytes(value), $ - std::string::length(ExpectedValue)));
} [[sealed, format("type::impl::format_magic")]];
namespace impl
{
fn format_magic(ref auto magic)
{
return fm(magic.value);
namespace impl {
fn format_magic(ref auto magic) {
return std::format("\"{}\"", type::escape_bytes(magic.value));
};
}
}

View File

@@ -1,53 +1,53 @@
import std.mem;
/*!
Types dealing with various kinds of resource paths
Types dealing with various kinds of resource paths
*/
namespace auto type {
/**
Type representing a single path segment. Use the `Path` type instead of using this on its own
@tparam Delimeter The delimeter sequence used to separate two path segments
*/
struct PathSegment<auto Delimeter> {
char string[while(std::mem::read_string($, std::string::length(Delimeter)) != Delimeter && std::mem::read_unsigned($, 1) != 0x00)];
char separator [[hidden]];
if (separator == 0x00) {
$ -= 1;
break;
}
} [[sealed, format("type::impl::format_path_segment")]];
/**
A generic type representing a path with an arbitrary delimeter
@tparam Delimeter The delimeter sequence used to separate two path segments
*/
struct Path<auto Delimeter> {
PathSegment<Delimeter> segments[while(true)];
} [[format("type::impl::format_path")]];
/**
A type representing a Unix path using a '/' forwardslash as delimeter
*/
using UnixPath = Path<"/">;
/**
Type representing a single path segment. Use the `Path` type instead of using this on its own
@tparam Delimiter The delimiter sequence used to separate two path segments
*/
struct PathSegment<auto Delimiter> {
char string[while(std::mem::read_string($, std::string::length(Delimiter)) != Delimiter && std::mem::read_unsigned($, 1) != 0x00)];
char separator [[hidden]];
if (separator == 0x00) {
$ -= 1;
break;
}
} [[sealed, format("type::impl::format_path_segment")]];
/**
A generic type representing a path with an arbitrary delimiter
@tparam Delimiter The delimiter sequence used to separate two path segments
*/
struct Path<auto Delimiter> {
PathSegment<Delimiter> segments[while(true)];
} [[format("type::impl::format_path")]];
/**
A type representing a Unix path using a '/' forward slash as delimiter
*/
using UnixPath = Path<"/">;
/**
A type representing a DOS path using a '\' backslash as delimeter
*/
using DOSPath = Path<"\\">;
namespace impl {
fn format_path_segment(ref auto segment) {
return segment.string;
};
fn format_path(ref auto path) {
return std::mem::read_string($, sizeof(path));
};
}
/**
A type representing a DOS path using a '\\' backslash as delimiter
*/
using DOSPath = Path<"\\">;
namespace impl {
fn format_path_segment(ref auto segment) {
return segment.string;
};
fn format_path(ref auto path) {
return std::mem::read_string($, sizeof(path));
};
}
}

View File

@@ -13,9 +13,9 @@ namespace auto type {
A 32 bit Unix time value
*/
using time32_t = u32 [[format("type::impl::format_time_t")]];
/**
Alias name for `time32_t`
Alias name for `time32_t`
*/
using time_t = time32_t;

View File

@@ -1,5 +1,5 @@
#pragma author WerWolv
#pragma description Autodesk 3DS Max Model file
#pragma description Autodesk 3DS Max Model
import std.io;
import type.base;
@@ -7,7 +7,7 @@ import type.base;
#pragma MIME image/x-3ds
// Heavily based off of ZiZi's 010 Editor 3DS Template
enum ChunkIdentifier : u16 {
enum ChunkIdentifier : u16 {
NULL_CHUNK = 0x0000,
ChunkType = 0x0995,
ChunkUnique = 0x0996,
@@ -40,10 +40,10 @@ enum ChunkIdentifier : u16 {
COLOR_24 = 0x0011, // r,g,b: Byte
LIN_COLOR_24 = 0x0012, // r,g,b: Byte (gamma corrected)
LIN_COLOR_F = 0x0013, // r,g,b: Single precision float (gamma corrected)
INT_PERCENTAGE = 0x0030, // u16 integer
FLOAT_PERCENTAGE = 0x0031, // Single precision float
M3DMAGIC = 0x4D4D,
SMAGIC = 0x2D2D,
LMAGIC = 0x2D3D,
@@ -72,7 +72,7 @@ enum ChunkIdentifier : u16 {
RAY_BIAS = 0x1460,
USE_RAYTRACE = 0x1470,
O_CONSTS = 0x1500,
AMBIENT_LIGHT = 0x2100,
FOG = 0x2200,
@@ -82,7 +82,7 @@ enum ChunkIdentifier : u16 {
USE_DISTANCE_CUE = 0x2301,
WORLD_LAYERED_FOG = 0x2302,
WORLD_USE_LAYERED_FOG = 0x2303,
DEFAULT_VIEW = 0x3000,
VIEW_TOP = 0x3010,
VIEW_BOTTOM = 0x3020,
@@ -93,7 +93,7 @@ enum ChunkIdentifier : u16 {
VIEW_USER = 0x3070,
VIEW_CAMERA = 0x3080,
VIEW_WINDOW = 0x3090,
NAMED_OBJECT = 0x4000,
OBJ_HIDDEN = 0x4010,
OBJ_VIS_LOFTER = 0x4011,
@@ -103,7 +103,7 @@ enum ChunkIdentifier : u16 {
OBJ_PROCEDURAL = 0x4015,
OBJ_FROZEN = 0x4016,
OBJ_DONT_RCVSHADOW = 0x4017,
N_TRI_OBJECT = 0x4100,
POINT_ARRAY = 0x4110,
POINT_FLAG_ARRAY = 0x4111,
@@ -134,7 +134,7 @@ enum ChunkIdentifier : u16 {
DL_SPOT_OVERSHOOT = 0x4652,
DL_SPOT_PROJECTOR = 0x4653,
DL_EXCLUDE = 0x4654,
DL_RANGE = 0x4655, /* Not used in R3 */
DL_RANGE = 0x4655, /* Not used in R3 */
DL_SPOT_ROLL = 0x4656,
DL_SPOT_ASPECT = 0x4657,
DL_RAY_BIAS = 0x4658,
@@ -143,22 +143,22 @@ enum ChunkIdentifier : u16 {
DL_INNER_RANGE = 0x4659,
DL_OUTER_RANGE = 0x465A,
DL_MULTIPLIER = 0x465B,
N_AMBIENT_LIGHT = 0x4680,
N_CAMERA = 0x4700,
CAM_SEE_CONE = 0x4710,
CAM_RANGES = 0x4720,
HIERARCHY = 0x4F00,
PARENT_OBJECT = 0x4F10,
PIVOT_OBJECT = 0x4F20,
PIVOT_LIMITS = 0x4F30,
PIVOT_ORDER = 0x4F40,
XLATE_RANGE = 0x4F50,
POLY_2D = 0x5000,
/* Flags in shaper file that tell whether polys make up an ok shape */
SHAPE_OK = 0x5010,
SHAPE_NOT_OK = 0x5011,
@@ -177,8 +177,8 @@ enum ChunkIdentifier : u16 {
YZ_CURVE = 0x6080,
INTERPCT = 0x6090,
DEFORM_LIMIT = 0x60A0,
/* Flags for Modeler options */
/* Flags for Modeler options */
USE_CONTOUR = 0x6100,
USE_TWEEN = 0x6110,
USE_SCALE = 0x6120,
@@ -187,7 +187,7 @@ enum ChunkIdentifier : u16 {
USE_FIT = 0x6150,
USE_BEVEL = 0x6160,
/* Viewport description chunks */
/* Viewport description chunks */
VIEWPORT_LAYOUT_OLD = 0x7000,
VIEWPORT_DATA_OLD = 0x7010,
VIEWPORT_LAYOUT = 0x7001,
@@ -196,7 +196,7 @@ enum ChunkIdentifier : u16 {
VIEWPORT_SIZE = 0x7020,
NETWORK_VIEW = 0x7030,
/* External Application Data */
/* External Application Data */
XDATA_SECTION = 0x8000,
XDATA_ENTRY = 0x8001,
XDATA_APPNAME = 0x8002,
@@ -215,8 +215,8 @@ enum ChunkIdentifier : u16 {
XDATA_RFU1 = 0x800F,
PARENT_NAME = 0x80F0,
/* Material Chunk IDs */
/* Material Chunk IDs */
MAT_ENTRY = 0xAFFF,
MAT_NAME = 0xA000,
MAT_AMBIENT = 0xA010,
@@ -228,7 +228,7 @@ enum ChunkIdentifier : u16 {
MAT_TRANSPARENCY = 0xA050,
MAT_XPFALL = 0xA052,
MAT_REFBLUR = 0xA053,
MAT_SELF_ILLUM = 0xA080,
MAT_TWO_SIDE = 0xA081,
MAT_DECAL = 0xA082,
@@ -241,13 +241,13 @@ enum ChunkIdentifier : u16 {
MAT_XPFALLIN = 0xA08A,
MAT_PHONGSOFT = 0xA08C,
MAT_WIREABS = 0xA08E,
MAT_SHADING = 0xA100,
MAT_TEXMAP = 0xA200,
MAT_MAPNAME = 0xA300,
MAT_ACUBIC = 0xA310,
MAT_MAP_TILINGOLD = 0xA350,
MAT_MAP_TILING = 0xA351,
MAT_MAP_TEXBLUR_OLD = 0xA352,
@@ -262,14 +262,14 @@ enum ChunkIdentifier : u16 {
MAT_MAP_RCOL = 0xA364,
MAT_MAP_GCOL = 0xA366,
MAT_MAP_BCOL = 0xA368,
MAT_SPECMAP = 0xA204,
MAT_OPACMAP = 0xA210,
MAT_REFLMAP = 0xA220,
MAT_BUMPMAP = 0xA230,
MAT_USE_REFBLUR = 0xA250,
MAT_BUMP_PERCENT = 0xA252,
MAT_SXP_TEXT_DATA = 0xA320,
MAT_SXP_TEXT2_DATA = 0xA321,
MAT_SXP_OPAC_DATA = 0xA322,
@@ -285,7 +285,7 @@ enum ChunkIdentifier : u16 {
MAT_SXP_SHIN_MASKDATA = 0xA334,
MAT_SXP_SELFI_MASKDATA = 0xA336,
MAT_SXP_REFL_MASKDATA = 0xA338,
MAT_TEX2MAP = 0xA33A,
MAT_SHINMAP = 0xA33C,
MAT_SELFIMAP = 0xA33D,
@@ -297,8 +297,8 @@ enum ChunkIdentifier : u16 {
MAT_SPECMASK = 0xA348,
MAT_SELFIMASK = 0xA34A,
MAT_REFLMASK = 0xA34C,
/* Keyframe Chunk IDs */
/* Keyframe Chunk IDs */
KFDATA = 0xB000,
KFHDR = 0xB00A,
AMBIENT_NODE_TAG = 0xB001,
@@ -308,13 +308,13 @@ enum ChunkIdentifier : u16 {
LIGHT_NODE_TAG = 0xB005,
L_TARGET_NODE_TAG = 0xB006,
SPOTLIGHT_NODE_TAG = 0xB007,
KFSEG = 0xB008,
KFCURTIME = 0xB009,
NODE_HDR = 0xB010,
INSTANCE_NAME = 0xB011,
PRESCALE = 0xB012,
PRESCALE = 0xB012,
PIVOT = 0xB013,
BOUNDBOX = 0xB014,
MORPH_SMOOTH = 0xB015,
@@ -329,10 +329,10 @@ enum ChunkIdentifier : u16 {
FALL_TRACK_TAG = 0xB028,
HIDE_TRACK_TAG = 0xB029,
NODE_ID = 0xB030,
CMAGIC = 0xC23D,
C_MDRAWER = 0xC010,
C_TDRAWER = 0xC020,
C_SHPDRAWER = 0xC030,
@@ -395,7 +395,7 @@ enum ChunkIdentifier : u16 {
C_BITMAP_DRAWER = 0xC25B,
C_RGB_FILE = 0xC260,
C_RGB_OVASPECT = 0xC270,
C_RGB_ANIMTYPE = 0xC271,
C_RENDER_ALL = 0xC272,
C_REND_FROM = 0xC273,
@@ -513,16 +513,16 @@ enum ChunkIdentifier : u16 {
C_VTR_IN = 0xC775,
C_VTR_PK = 0xC780,
C_VTR_SH = 0xC785,
/* Material chunks */
C_WORK_MTLS = 0xC790, /* Old-style -- now ignored */
C_WORK_MTLS_2 = 0xC792, /* Old-style -- now ignored */
C_WORK_MTLS_3 = 0xC793, /* Old-style -- now ignored */
C_WORK_MTLS_4 = 0xC794, /* Old-style -- now ignored */
C_WORK_MTLS_5 = 0xCB00, /* Old-style -- now ignored */
C_WORK_MTLS_6 = 0xCB01, /* Old-style -- now ignored */
C_WORK_MTLS_7 = 0xCB02, /* Old-style -- now ignored */
C_WORK_MTLS_8 = 0xCB03, /* Old-style -- now ignored */
/* Material chunks */
C_WORK_MTLS = 0xC790, /* Old-style -- now ignored */
C_WORK_MTLS_2 = 0xC792, /* Old-style -- now ignored */
C_WORK_MTLS_3 = 0xC793, /* Old-style -- now ignored */
C_WORK_MTLS_4 = 0xC794, /* Old-style -- now ignored */
C_WORK_MTLS_5 = 0xCB00, /* Old-style -- now ignored */
C_WORK_MTLS_6 = 0xCB01, /* Old-style -- now ignored */
C_WORK_MTLS_7 = 0xCB02, /* Old-style -- now ignored */
C_WORK_MTLS_8 = 0xCB03, /* Old-style -- now ignored */
C_WORKMTL = 0xCB04,
C_SXP_TEXT_DATA = 0xCB10,
C_SXP_TEXT2_DATA = 0xCB20,
@@ -542,15 +542,15 @@ enum ChunkIdentifier : u16 {
C_BGTYPE = 0xC7A1,
C_MEDTILE = 0xC7B0,
/* Contrast */
C_LO_CONTRAST = 0xC7D0,
C_HI_CONTRAST = 0xC7D1,
/* 3d frozen display */
/* 3d frozen display */
C_FROZ_DISPLAY = 0xC7E0,
/* Booleans */
/* Booleans */
C_BOOLWELD = 0xc7f0,
C_BOOLTYPE = 0xc7f1,
@@ -569,8 +569,8 @@ enum ChunkIdentifier : u16 {
C_MAPDRAWER8 = 0xCA08,
C_MAPDRAWER9 = 0xCA09,
C_MAPDRAWER_ENTRY = 0xCA10,
/* System Options */
/* System Options */
C_BACKUP_FILE = 0xCA20,
C_DITHER_256 = 0xCA21,
C_SAVE_LAST = 0xCA22,
@@ -596,8 +596,8 @@ enum ChunkIdentifier : u16 {
C_AUTO_SMOOTH = 0xCA80,
C_DXF_SMOOTH_ANG = 0xCA90,
C_SMOOTH_ANG = 0xCAA0,
/* Special network-use chunks */
/* Special network-use chunks */
C_NET_USE_VPOST = 0xCC00,
C_NET_USE_GAMMA = 0xCC10,
C_NET_FIELD_ORDER = 0xCC20,
@@ -628,8 +628,8 @@ enum ChunkIdentifier : u16 {
C_VIEW_PRES_RATIO = 0xCE50,
C_BGND_PRES_RATIO = 0xCE60,
C_NTH_SERIAL_NUM = 0xCE70,
/* Video Post */
/* Video Post */
VPDATA = 0xd000,
P_QUEUE_ENTRY = 0xd100,
@@ -648,7 +648,7 @@ enum ChunkIdentifier : u16 {
P_QUEUE_ALIGN = 0xd190,
P_CUSTOM_SIZE = 0xd1a0,
P_ALPH_NONE = 0xd210,
P_ALPH_PSEUDO = 0xd220, /* Old chunk */
P_ALPH_OP_PSEUDO = 0xd221, /* Old chunk */
@@ -732,7 +732,7 @@ bitfield Spline {
Use_Bias : 1;
Use_Ease_To : 1;
Use_Ease_From : 1;
padding : 3;
if (Use_Tension == 1)
@@ -745,7 +745,7 @@ bitfield Spline {
float Ease_To;
if (Use_Ease_From == 1)
float Ease_From;
padding : 8;
};
@@ -795,7 +795,7 @@ struct Keys<auto identifier> {
) : {
RotationKey data[count];
}
(
ChunkIdentifier::FOV_TRACK_TAG |
ChunkIdentifier::ROLL_TRACK_TAG |
@@ -804,13 +804,13 @@ struct Keys<auto identifier> {
) : {
AngleKey data[count];
}
(
ChunkIdentifier::MORPH_TRACK_TAG
) : {
MorphKey data[count];
}
(
ChunkIdentifier::HIDE_TRACK_TAG
) : {
@@ -842,7 +842,7 @@ struct Chunk {
u32 chunkSize;
u32 dataLength = chunkSize - 6 [[export]];
u32 chunkEnd = $ + dataLength;
if (chunkSize > 0) {
std::print("{}", identifier);
match (identifier) {
@@ -894,14 +894,14 @@ struct Chunk {
): {
Chunk chunks[while($ < chunkEnd)];
}
(
ChunkIdentifier::M3D_VERSION |
ChunkIdentifier::MESH_VERSION
): {
u32 version;
}
(
ChunkIdentifier::LO_SHADOW_BIAS |
ChunkIdentifier::HI_SHADOW_BIAS |
@@ -921,41 +921,41 @@ struct Chunk {
): {
float value;
}
(
ChunkIdentifier::V_GRADIENT
) : {
float position;
Chunk chunks[while($ < chunkEnd)];
}
(
ChunkIdentifier::NAMED_OBJECT
) : {
char name[];
Chunk chunks[while($ < chunkEnd)];
}
(
ChunkIdentifier::POINT_ARRAY
) : {
u16 count;
Vector3f vectices[count] [[hex::visualize("3d", this, null)]];
}
(
ChunkIdentifier::TEX_VERTS
) : {
u16 count;
Vector2f coords[count];
}
(
ChunkIdentifier::MESH_MATRIX
) : {
Vector3f x, y, z, w;
}
(
ChunkIdentifier::FACE_ARRAY
) : {
@@ -963,26 +963,26 @@ struct Chunk {
Face faces[count];
Chunk chunks[while($ < chunkEnd)];
}
(
ChunkIdentifier::POINT_FLAG_ARRAY
) : {
u16 count;
VertexFlags flags[count];
}
(
ChunkIdentifier::SMOOTH_GROUP
) : {
u32 groups[dataLength / sizeof(u32)];
}
(
ChunkIdentifier::MESH_COLOR
) : {
u8 value;
}
(
ChunkIdentifier::MSH_MAT_GROUP
) : {
@@ -990,7 +990,7 @@ struct Chunk {
u16 count;
u16 groups[count];
}
(
ChunkIdentifier::KFHDR
) : {
@@ -998,25 +998,25 @@ struct Chunk {
char name[];
u32 animationLength;
}
(
ChunkIdentifier::KFSEG
) : {
u32 start, end;
}
(
ChunkIdentifier::KFCURTIME
) : {
u32 frameIndex;
}
(
ChunkIdentifier::NODE_ID
) : {
type::Hex<u16> id;
}
(
ChunkIdentifier::NODE_HDR
) : {
@@ -1026,47 +1026,47 @@ struct Chunk {
KeyFlags2 flags2;
type::Hex<u16> parentId;
}
(
ChunkIdentifier::PIVOT
) : {
Vector3f value;
}
(
ChunkIdentifier::BOUNDBOX
) : {
Vector3f min, max;
}
(
ChunkIdentifier::COLOR_24 |
ChunkIdentifier::LIN_COLOR_24
) : {
RGB<u8> color;
}
(
ChunkIdentifier::COLOR_F |
ChunkIdentifier::LIN_COLOR_F
) : {
RGB<float> color;
}
(
ChunkIdentifier::INT_PERCENTAGE |
ChunkIdentifier::MAT_BUMP_PERCENT
) : {
u16 value;
}
(
ChunkIdentifier::SHADOW_MAP_SIZE |
ChunkIdentifier::MAT_SHADING
) : {
u16 value;
}
(
ChunkIdentifier::POS_TRACK_TAG |
ChunkIdentifier::ROT_TRACK_TAG |
@@ -1077,13 +1077,13 @@ struct Chunk {
ChunkIdentifier::MORPH_TRACK_TAG |
ChunkIdentifier::HOT_TRACK_TAG |
ChunkIdentifier::FALL_TRACK_TAG |
ChunkIdentifier::HIDE_TRACK_TAG
ChunkIdentifier::HIDE_TRACK_TAG
) : {
TrackFlags flags;
u8 unknown[8];
Keys<identifier> keys;
}
(
ChunkIdentifier::INSTANCE_NAME |
ChunkIdentifier::BIT_MAP |
@@ -1093,26 +1093,26 @@ struct Chunk {
) : {
char name[];
}
(
ChunkIdentifier::MAT_MAP_TILING
) : {
u16 tiling;
}
(
ChunkIdentifier::WORLD_VIEWPORT_SIZE
) : {
u16 x, y, w, h;
}
(
ChunkIdentifier::N_DIRECT_LIGHT
) : {
Vector3f position;
Chunk chunks[while($ < chunkEnd)];
}
(
ChunkIdentifier::DL_SPOTLIGHT
) : {
@@ -1120,16 +1120,16 @@ struct Chunk {
float hotspot, falloff;
Chunk chunks[while($ < chunkEnd)];
}
(
ChunkIdentifier::N_CAMERA
) : {
Vector3f position, target;
float roll, fov;
}
(_) : {
std::warning(std::format("Unhandled Chunk ID: {}, Skipping 0x{:04X} bytes", identifier, dataLength));
$ += dataLength;

View File

@@ -1,101 +1,102 @@
#pragma description 7z File Format
#pragma description 7z Archive
#pragma MIME application/x-7z-compressed
import std.io;
import std.mem;
import std.math;
import std.io;
import std.mem;
import std.math;
enum Type:u8{
startPosition = 0x00, // Start position
sizeStartHeader = 0x20, // Size of start Header
};
enum Type:u8{
startPosition = 0x00, // Start position
sizeStartHeader = 0x20, // Size of start Header
};
enum TypeB:u48{
sevenZipSignature = 0x1C27AFBC7A37, // Defining 7z signature
};
enum TypeB:u48{
sevenZipSignature = 0x1C27AFBC7A37, // Defining 7z signature
};
struct StartHeader {
// File signature
u48 signature [[color("FF0000")] ];
// Version format
u16 formatVersion [[color("00FF00")]];
// CRC start header
u32 crcOfTheFollowing20Bytes [[color("0000FF")]];
// Relative offset of End Header
u64 relativeOffsetEndHeader [[color("FFFF00")]];
// Length of End Header
u64 theLengthOfEndHeader [[color("00FFFF")]];
// CRC of End Ender
u32 crcOftheEndHeader [[color("FF00FF")]];
// File size calculation
u64 fileSize = relativeOffsetEndHeader + theLengthOfEndHeader + Type::sizeStartHeader;
// Absolute offset calculation End Header
u64 startEndHeader = relativeOffsetEndHeader + Type::sizeStartHeader;
};
struct StartHeader {
// File signature
u48 signature [[color("FF0000")] ];
// Version format
u16 formatVersion [[color("00FF00")]];
// CRC start header
u32 crcOfTheFollowing20Bytes [[color("0000FF")]];
// Relative offset of End Header
u64 relativeOffsetEndHeader [[color("FFFF00")]];
// Length of End Header
u64 theLengthOfEndHeader [[color("00FFFF")]];
// CRC of End Ender
u32 crcOftheEndHeader [[color("FF00FF")]];
// File size calculation
u64 fileSize = relativeOffsetEndHeader + theLengthOfEndHeader + Type::sizeStartHeader;
// Absolute offset calculation End Header
u64 startEndHeader = relativeOffsetEndHeader + Type::sizeStartHeader;
};
StartHeader startheader @ Type::startPosition;
struct CompressedData {
// Start of compressed data
u8 startOfCompressedData[4] [[color("C0C0C0")]];
};
StartHeader startheader @ Type::startPosition;
CompressedData compresseddata @ Type::sizeStartHeader;
struct CompressedData {
// Start of compressed data
u8 startOfCompressedData[4] [[color("C0C0C0")]];
};
struct EndHeader {
// Set padding to place End Header in right position
padding[startheader.relativeOffsetEndHeader];
// Mark link to meta block
u8 linkToMetaBlock [[color("FF0000")]];
// Mark all End Header
char fullEndHeader[startheader.theLengthOfEndHeader] [[color("63954A")]];
// Detect LZMA signature
u64 lzmaSignaturePosition = std::mem::find_sequence_in_range(0, addressof(fullEndHeader), addressof(fullEndHeader) + sizeof(fullEndHeader), 0x23, 0x03, 0x01, 0x01, 0x05, 0x5D);
// Mark positions if LZMA signature was detected
if(lzmaSignaturePosition != 0xFFFFFFFFFFFFFFFF){
u48 lzmaSignature @ lzmaSignaturePosition [[color("0000FF")]];
}
};
CompressedData compresseddata @ Type::sizeStartHeader;
EndHeader endheader @ Type::sizeStartHeader;
// Check 7z type
if(startheader.signature == TypeB::sevenZipSignature){
std::print("It is a 7z File Type");
}else{
std::print("The file is not 7z type");
}
std::print("Format Version {} ",startheader.formatVersion);
struct EndHeader {
// Set padding to place End Header in right position
padding[startheader.relativeOffsetEndHeader];
// Mark link to meta block
u8 linkToMetaBlock [[color("FF0000")]];
// Mark all End Header
char fullEndHeader[startheader.theLengthOfEndHeader] [[color("63954A")]];
// Detect LZMA signature
u64 lzmaSignaturePosition = std::mem::find_sequence_in_range(0, addressof(fullEndHeader), addressof(fullEndHeader) + sizeof(fullEndHeader), 0x23, 0x03, 0x01, 0x01, 0x05, 0x5D);
// Version verification
if(startheader.formatVersion == 0x0400){
std::print("Major Version 0x00 || 0 - Minor Version 0x04 || 4");
}
// Mark positions if LZMA signature was detected
if(lzmaSignaturePosition != 0xFFFFFFFFFFFFFFFF){
u48 lzmaSignature @ lzmaSignaturePosition [[color("0000FF")]];
}
};
// Verification of the compressed method is LZMA, Bzip2 or LZMA2
if(compresseddata.startOfCompressedData[0] == Type::startPosition){
std::print("Compressed Method LZMA");
}else if(compresseddata.startOfCompressedData[0] == 0x42){
std::print("Compressed Method Bzip2");
}else{
std::print("Compressed Method LZMA2");
}
EndHeader endheader @ Type::sizeStartHeader;
// Check 7z type
if(startheader.signature == TypeB::sevenZipSignature){
std::print("It is a 7z File Type");
}else{
std::print("The file is not 7z type");
}
std::print("CRC Start Header 0x{:X}",startheader.crcOfTheFollowing20Bytes);
std::print("Format Version {} ",startheader.formatVersion);
std::print("CRC End Header 0x{:X} ", startheader.crcOftheEndHeader);
// Version verification
if(startheader.formatVersion == 0x0400){
std::print("Major Version 0x00 || 0 - Minor Version 0x04 || 4");
}
std::print("CompressedData length 0x{:X} || {} bytes ",startheader.relativeOffsetEndHeader, startheader.relativeOffsetEndHeader);
// Verification of the compressed method is LZMA, Bzip2 or LZMA2
if(compresseddata.startOfCompressedData[0] == Type::startPosition){
std::print("Compressed Method LZMA");
}else if(compresseddata.startOfCompressedData[0] == 0x42){
std::print("Compressed Method Bzip2");
}else{
std::print("Compressed Method LZMA2");
}
std::print("Relative Offset of End Header 0x{:X} || {} bytes",startheader.relativeOffsetEndHeader, startheader.relativeOffsetEndHeader);
std::print("Offset to start End Header 0x{:X} || {} bytes",startheader.startEndHeader,startheader.startEndHeader);
std::print("End Header length 0x{:X} || {} bytes",startheader.theLengthOfEndHeader,startheader.theLengthOfEndHeader);
std::print("CRC Start Header 0x{:X}",startheader.crcOfTheFollowing20Bytes);
std::print("File size 0x{:X} || {} bytes",startheader.fileSize, startheader.fileSize);
std::print("CRC End Header 0x{:X} ", startheader.crcOftheEndHeader);
std::print("CompressedData length 0x{:X} || {} bytes ",startheader.relativeOffsetEndHeader, startheader.relativeOffsetEndHeader);
std::print("Relative Offset of End Header 0x{:X} || {} bytes",startheader.relativeOffsetEndHeader, startheader.relativeOffsetEndHeader);
std::print("Offset to start End Header 0x{:X} || {} bytes",startheader.startEndHeader,startheader.startEndHeader);
std::print("End Header length 0x{:X} || {} bytes",startheader.theLengthOfEndHeader,startheader.theLengthOfEndHeader);
std::print("File size 0x{:X} || {} bytes",startheader.fileSize, startheader.fileSize);

View File

@@ -1,12 +1,16 @@
#pragma author AdventureT
#pragma description Crash Bandicoot - Back in Time (fan game) User created level format
// Supports all versions till 0.94c, newer versions might be compatible!
#pragma description Crash Bandicoot - Back in Time (fan game) User created level
#pragma magic [ 43 52 41 53 48 4C 56 4C ] @ 0x00
#pragma history
#pragma 0.3 2024-05-15 Added support for version 0.95
#pragma 0.2 2023-10-29 Added support for version 0.94c
#pragma 0.1 2023-04-25 Initial support
// Supports all versions till 0.95, newer versions might be compatible!
import type.magic;
import std.string;
import std.array;
struct Header {
type::Magic<"CRASHLVL"> magic;
u8 version;
@@ -17,8 +21,6 @@ struct Header {
std::string::SizedString<u8> author;
};
Header header @ 0x0;
// Background Music
enum BGM : u32 {
None,
@@ -37,6 +39,56 @@ enum BGM : u32 {
};
enum BGMV2 : u32 {
None,
N_TropyBGM,
CrashCreatorBGM,
MainMenuBGM,
WarpRoomBGM,
Jungle01BGM,
SnowBGM,
RiverBGM,
FutureBGM,
LabBGM,
SewerBGM,
EgyptBGM,
NBrioBGM,
AdventureBGM,
SpyBGM,
ChaseBGM,
TrialsBGM,
SpaceBGM,
Jungle02BGM,
RipperBGM,
TheGreatWallBGM,
RoadToSomewhereBGM,
LavaKoalaBGM,
CortexBGM,
CyberCortexBGM,
ArabicBGM,
N_Tropy2BGM,
JazzBGM,
Space2BGM,
TawnaBonusBGM,
CortexPowerBGM,
ArabicBonusBGM,
EgyptBonusBGM,
FutureBonusBGM,
LostCityBGM,
PolarBGM,
RiverBonusBGM,
RuinsBonusBGM,
SewerBonusBGM,
SnowBonusBGM,
RoadToRuinBGM,
NGinBGM,
Arabia01BGM,
Arabia02BGM,
BashBGM,
Cortex02BGM
};
// v0.95
enum BGMV3 : BGMV2 {
None,
N_TropyBGM,
CrashCreatorBGM,
@@ -83,12 +135,19 @@ enum BGMV2 : u32 {
Arabia02BGM,
BashBGM,
Cortex02BGM,
MedievalBGM,
PreHistoricBGM,
UnderWaterBGM,
BrioRevisitedBGM,
EgyptChaseBGM,
RuinsLoopBGM,
DingoSynthBGM
};
enum Type : u32 {
Unset,
Flashback,
Trial,
Trial
};
enum TypeV2 : u32 {
@@ -118,13 +177,31 @@ enum SkyboxV2 : u32 {
Black
};
// 0.95
enum SkyboxV3 : u32 {
Default = 1,
Briolab,
Fort,
Moon,
Toxic,
AboutRight,
Crash1Island,
Arabia,
RoadToRuin,
MotorcycleDay,
MotorcycleNoon,
MotorcycleMoon,
MotorcycleNight,
Black
};
enum Scenery : u32 {
None,
FutureTense,
Forest,
Waterfall,
Snow,
Fortress,
Fortress
};
enum SceneryV2 : u32 {
@@ -165,44 +242,102 @@ enum SceneryV4 : u32 {
Pipes
};
// 0.95
enum SceneryV5 : u32 {
None,
FutureTense,
Forest,
Waterfall,
Snow,
Fortress,
None2,
Lava,
TheGreatGate,
Mountain,
KoalaKong,
SunsetVista,
HangemHigh,
Sphynxinator,
Tunnel,
Pipes,
Medieval,
FutureCity,
TinyArena,
HeavyMachinery,
CrystalCave,
MedievalWithHouses,
CortexBonusChamber
};
enum Weather : u32 {
Default,
Snow,
Rain
};
// 0.95
enum WeatherV2 : u32 {
Default,
Snow,
Rain,
Night,
UnderWater
};
struct Options {
if (header.version > 1)
// Type
if (header.version > 1) {
TypeV2 type;
else
Type type;
if (header.version > 1)
SkyboxV2 skybox;
else
Skybox skybox;
if (header.version == 1)
Scenery scenery;
else if (header.version > 1 && header.version < 4)
SceneryV2 scenery;
else
SceneryV4 scenery;
if (header.version > 2)
{
Weather weather;
}
if (header.version > 1)
else {
Type type;
}
// Skybox
if (header.version > 1) {
if (header.gameVersion == "0.95") {
SkyboxV3 skybox;
}
else {
SkyboxV2 skybox;
}
}
else {
Skybox skybox;
}
// Scenery
if (header.version == 1) {
Scenery scenery;
}
else if (header.version > 1 && header.version < 4) {
SceneryV2 scenery;
}
else {
if (header.gameVersion == "0.95") {
SceneryV5 skybox;
}
else {
SceneryV4 skybox;
}
}
// Weather
if (header.version > 2) {
if (header.gameVersion == "0.95") {
WeatherV2 weather;
}
else {
Weather weather;
}
}
// Background music
if (header.version > 1) {
BGMV2 bgm;
else
}
else {
BGM bgm;
if (type == Type::Trial)
{
}
// Time Trial
if (type == Type::Trial) {
u32 timeTrialTicksBronze;
u32 timeTrialTicksSilver;
u32 timeTrialTicksGold;
@@ -210,22 +345,17 @@ struct Options {
};
struct Object {
std::string::SizedString<u8> objName;
if (header.version > 1)
{
if (header.version > 1) {
u16 x;
u16 y;
bool hasMetafields;
if (hasMetafields)
{
if (hasMetafields) {
u16 numOfMetafields;
u8 metafields[numOfMetafields];
}
}
else
{
else {
u32 x;
u32 y;
}
@@ -236,9 +366,6 @@ struct Objects{
std::Array<Object, objCount> objArray;
};
Header header @ $;
Options options @ $;
Objects objects @ $;
Objects objects @ $;

197
patterns/adts.hexpat Normal file
View File

@@ -0,0 +1,197 @@
#pragma author zhoubo
#pragma description AAC ADTSn (Audio Data Transport Stream) Audio
#pragma MIME audio/x-hx-aac-adts
#pragma pattern_limit 0xFFFFFF
// History
// 0.4 2024-02-12 zhoubo: Porting from 010 Editor Templates.
// 0.3 2024-02-09 zhoubo: use BitfieldDisablePadding(Unpadded Bitfields) for odd header bytes(7,9 bytes) color, and remove FSeek.
// 0.2 2024-02-05 zhoubo: fix some comment & color.
// 0.1 2022-06-13 zhoubo: Init release. only ADTS, not support ADIF,LATM.
// More information available at:
// 1. https://wiki.multimedia.cx/index.php?title=ADTS
// 2. https://en.wikipedia.org/wiki/Advanced_Audio_Coding
// 3. https://en.wikipedia.org/wiki/AAC
// 4. https://juejin.cn/post/7032170229732442148
#pragma endian big
#include <std/sys.pat>
#include <std/core.pat>
fn GetMPEGVersionComment(auto MPEG_Version)
{
str comment = "";
match (MPEG_Version)
{
(0): comment = "MPEG-4";
(1): comment = "MPEG-2";
}
return comment;
};
fn GetProtectionAbsentComment(auto Protection_absence)
{
str comment = "";
match (Protection_absence)
{
(0): comment = "ADTS has 9 bytes with CRC";
(1): comment = "ADTS has 7 bytes without CRC";
}
return comment;
};
fn GetProfileComment(auto Profile)
{
str comment = "";
match (Profile)
{
(0x00): comment = "AAC Main";
(0x01): comment = "AAC LC (Low Complexity)";
(0x10): comment = "AAC SSR (Scalable Sample Rate)";
(0x11): comment = "AAC LTP (Long Term Prediction)";
}
return comment;
};
fn GetSamplingFrequencyIndexComment(auto Sampling_frequency_index)
{
str comment = "";
match (Sampling_frequency_index)
{
(0x0): comment = "96000Hz";
(0x1): comment = "88200Hz";
(0x2): comment = "64000Hz";
(0x3): comment = "48000Hz";
(0x4): comment = "44100Hz";
(0x5): comment = "32000Hz";
(0x6): comment = "24000Hz";
(0x7): comment = "22050Hz";
(0x8): comment = "16000Hz";
(0x9): comment = "12000Hz";
(0xa): comment = "11025Hz";
(0xb): comment = "8000Hz";
(0xc): comment = "7350Hz";
(0xd): comment = "Reserved";
(0xe): comment = "Reserved";
(0xf): comment = "FORBIDDEN (malformed)";
}
return comment;
};
fn GetChannelConfigurationComment(auto Channel_configuration)
{
str comment = "";
match (Channel_configuration)
{
(0): comment = "Defined in AOT Specifc Config";
(1): comment = "1 channel: front-center";
(2): comment = "2 channels: front-left, front-right";
(3): comment = "3 channels: front-center, front-left, front-right";
(4): comment = "4 channels: front-center, front-left, front-right, back-center";
(5): comment = "5 channels: front-center, front-left, front-right, back-left, back-right";
(6): comment = "6 channels: front-center, front-left, front-right, back-left, back-right, LFE-channel";
(7): comment = "8 channels: front-center, front-left, front-right, side-left, side-right, back-left, back-right, LFE-channel";
}
return comment;
};
fn GetBufferFullnessComment(auto ADTS_buffer_fullness)
{
str comment = "";
match (ADTS_buffer_fullness)
{
(0x7FF): comment = "VBR (most software ignore this field)";
(_): comment = "rate..?? (most software ignore this field)";
}
return comment;
};
fn GetRawDataBlockComment(auto Number_of_AAC_frames_minus_1)
{
str comment = "";
match (Number_of_AAC_frames_minus_1)
{
(0x0): comment = "has 1 AAC data block";
(_): comment = "data block number + 1";
}
return comment;
};
//-----------------------------------
// Define structures used in AAC files
//
// [1.adts_fixed_header information]
// Syncword: 12bits, sync header, always 0xFFF。
// MPEG_Version: 1bit, 0 means MPGE-4, 1 means MPGE-2
// Layer: 2bits, alwayas ”00”
// Protection_absence: 1bit, 0 means ADTS Header 9 bytes; 1 means ADTS Header 7 bytes
// Profile: 2bit, AAC level : Main,LC,SSR,LTP
// Sampling_frequency_index: 4bits, Sampling Frequencies
// Private_bit: 1bit
// Channel_configuration: 3bits, channel number...
// Originality: 1bit
// Home: 1bit
//
// [2.adts_variable_header information]
// Copyright_id_bit: 1bit
// Copyright_id_start: 1bit
// AAC_frame_length: 13bits, AAC frame length : ADTS Header(7 or 9 bytes) + sizeof(AAC Frame)
// ADTS_buffer_fullness: 11bits, 0x7FF means VBR
// Number_of_AAC_frames_minus_1: 2bits, ADTS Frame numbers : Number_of_AAC_frames_minus_1 + 1
//
// [3.CRC information]
// CRC16: 16bits, when Protection_absence=0
bitfield ADTS_HEADER
{
// ADTS_FIXED_HEADER
Syncword : 12 [[color("00FF00"), comment("always 0xFFF")]];
MPEG_Version : 1 [[color("00FF00"), comment(GetMPEGVersionComment(this))]];
Layer : 2 [[color("00FF00"), comment("always 0")]];
Protection_absence : 1 [[color("00FF00"), comment(GetProtectionAbsentComment(this))]];
Profile : 2 [[color("0000FF"), comment(GetProfileComment(this))]];
Sampling_frequency_index : 4 [[color("0000FF"), comment(GetSamplingFrequencyIndexComment(this))]];
Private_bit : 1 [[color("0000FF")]];
Channel_configuration : 3 [[color("0000FF"), comment(GetChannelConfigurationComment(this))]];
Originality : 1 [[color("0000FF")]];
Home : 1 [[color("0000FF")]];
// ADTS_VARIABLE_HEADER
Copyright_id_bit : 1 [[color("0000FF")]];
Copyright_id_start : 1 [[color("0000FF")]];
AAC_frame_length : 13 [[color("0000FF")]];
ADTS_buffer_fullness : 11 [[color("0000FF"), comment(GetBufferFullnessComment(this))]];
Number_of_AAC_frames_minus_1 : 2 [[color("0000FF"), comment(GetRawDataBlockComment(this))]];
// ADTS_CRC_HEADER
if (0 == Protection_absence) // Header with CRC
{
u16 CRC16 [[color("FFFF00")]];
}
else // Header without CRC
{
}
};
struct ADTS_FRAME
{
ADTS_HEADER Header;
if (0 == Header.Protection_absence) // Header with CRC 2 bytes
{
u8 Data[Header.AAC_frame_length - 9] [[color("000000")]];
}
else // Header without CRC
{
u8 Data[Header.AAC_frame_length - 7] [[color("000000")]];
}
};
//---------------------------------------------
ADTS_FRAME adtsFrame[while(!std::mem::eof())] @ 0x00;

View File

@@ -1,6 +1,10 @@
#pragma author WerWolv
#pragma description Nintendo Switch Atmosphère CFW Fatal Error log
#pragma magic [ 41 46 45 30 ] @ 0x00
#pragma magic [ 41 46 45 31 ] @ 0x00
#pragma magic [ 41 46 45 32 ] @ 0x00
#pragma endian little
import std.io;
@@ -52,8 +56,8 @@ std::assert(ctx.magic == ATMOSPHERE_REBOOT_TO_FATAL_MAGIC ||
ctx.magic == ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_1 ||
ctx.magic == ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_0,
"File is not a valid Atmosphere fatal error binary!");
std::assert_warn(ctx.magic == ATMOSPHERE_REBOOT_TO_FATAL_MAGIC,
std::assert_warn(ctx.magic == ATMOSPHERE_REBOOT_TO_FATAL_MAGIC,
"Atmosphere fatal error binary is for an older version!");

66
patterns/ani.hexpat Normal file
View File

@@ -0,0 +1,66 @@
#pragma description Windows animated cursor
#pragma MIME application/x-navi-animation
#pragma endian little
import std.io;
import std.mem;
bitfield HeaderFlags {
icon : 1;
sequence : 1;
padding: 30;
};
struct anih {
u32 struct_size;
u32 stored_frames;
u32 animation_steps;
u32 w;
u32 h;
u32 bits;
u32 planes;
u32 default_jiffies;
HeaderFlags flags;
};
struct rate {
u32 jiffies[parent.size / 4];
};
struct seq {
u32 index[parent.size / 4];
};
struct RiffChunk {
char signature[4];
u32 size;
if (signature == "RIFF" || signature == "LIST") {
char type[4];
RiffChunk chunks[while($ - addressof(type) < size)];
} else if (signature[0] == 'I' && parent.type == "INFO") {
char info[size];
} else if (signature == "anih") {
anih anih [[inline]];
} else if (signature == "rate") {
rate rate [[inline]];
} else if (signature == "seq ") {
seq seq [[inline]];
} else {
std::mem::Bytes<size> data;
}
padding[size % 2];
} [[format_read("read_chunk")]];
fn read_chunk(RiffChunk chunk) {
if (chunk.signature == "RIFF" || chunk.signature == "LIST") {
return std::format("{}<{}> ({})", chunk.signature, chunk.type, chunk.size);
} else {
str ret = std::format("{} ({})", chunk.signature, chunk.size);
try {
ret += std::format(" \"{}\"", chunk.info);
} catch {}
return ret;
}
};
RiffChunk riff @ 0;

View File

@@ -1,5 +1,5 @@
#pragma author WerWolv
#pragma description Static library archive files
#pragma description GNU Static library archive
#pragma MIME application/x-archive
@@ -15,7 +15,7 @@ struct ARFile {
char file_mode[8];
char file_size[10];
u16 end_marker;
if (end_marker == 0x0A60) {
u8 data[std::string::parse_int(this.file_size, 10)];
padding[sizeof(data) & 1];
@@ -23,6 +23,9 @@ struct ARFile {
};
char signature[8] @ 0x00;
if (signature == "!<arch>\r") {
std::error("Archive file got corrupted due to CRLF line ending conversion!");
}
std::assert(signature == "!<arch>\n", "File is not a valid archive!");
ARFile files[while($ < std::mem::size())] @ $;

26
patterns/arc.hexpat Normal file
View File

@@ -0,0 +1,26 @@
#pragma author DexrnZacAttack
#pragma description Minecraft LCE ARC File
#pragma endian big
import std.string;
#ifdef __IMHEX__
import hex.core;
#endif
struct Table {
u16 nameSize;
char fileName[nameSize];
u32 offset;
u32 size;
u8 file[size] @ offset;
#ifdef __IMHEX__
hex::core::add_virtual_file(fileName, file);
#endif
} [[name(std::string::to_string(fileName))]];
struct ARC {
u32 count;
Table table[count];
};
ARC arc @ 0x00;

View File

@@ -40,21 +40,21 @@ VectorTable vector_table @ VTOR;
fn main() {
u32 table_size = sizeof(vector_table);
u32 default_handler_address = 0x00;
for (u32 i = 4, i < table_size, i = i + 4) {
u32 occurrences = 0;
for (u32 j = 4, j < table_size, j = j + 4) {
if (std::mem::read_unsigned(i, 4) == std::mem::read_unsigned(j, 4)) {
occurrences = occurrences + 1;
if (occurrences > 1)
default_handler_address = std::mem::read_unsigned(i, 4);
}
}
}
if (default_handler_address != 0x00)
std::print("Default Handler implementation at 0x{:08X}", default_handler_address);
};

168
patterns/bcss.hexpat Normal file
View File

@@ -0,0 +1,168 @@
#pragma author ttimasdf
#pragma description BeyondCompare Snapshot (BCSS) file
#pragma magic [42 43 53 53] @ 0x00
#pragma array_limit 4294967295
#pragma pattern_limit 4294967295
import std.io;
import std.mem;
import std.array;
import std.string;
import type.magic;
#ifdef __IMHEX__
import hex.dec;
import hex.core;
#endif
const u8 max_path_size = 1000;
str current_path[max_path_size];
u8 current_path_level = 0;
enum EntryType : u8 {
DIRECTORY = 0x01,
FILE = 0x02,
SYMLINK = 0x03,
// NULL = 0x00,
DIR_END = 0xFF,
};
struct BCSSEntry {
EntryType type;
match (type) {
(EntryType::DIRECTORY) : {
// FileName name;
std::string::SizedString<u8> name;
if (name.size != 0) {
u8 unknown[12];
on_dir_enter(name.data); // std::string::to_string(name)
} else {
// some buggy edge cases
u8 unknown[6];
std::warning(std::format("invalid empty entry current_lvl={} current_pos=0x{:02x}", current_path_level, $));
}
}
(EntryType::FILE) : {
std::string::SizedString<u8> name;
if (name.size != 0) {
u8 unknown[20];
#ifdef __IMHEX__
hex::core::add_virtual_file(get_vfs_path(name), this); // std::string::to_string(name)
#endif
} else {
// some buggy edge cases
u8 unknown[6];
std::warning(std::format("invalid empty entry current_lvl={} current_pos=0x{:02x}", current_path_level, $));
}
//try {
// u8 unknown[20];
//} catch {
// u8 unknown[0];
//}
}
(EntryType::SYMLINK) : {
std::string::SizedString<u8> name;
u8 unknown[23];
std::string::SizedString<u8> target;
#ifdef __IMHEX__
hex::core::add_virtual_file(get_vfs_path(name + " [s]"), this); // std::string::to_string(name)
#endif
}
(EntryType::DIR_END) : {
on_dir_exit();
}
// (EntryType::NULL) : {
// // some buggy edge cases
// u8 unknown[7];
// std::warning(std::format("invalid empty entry current_lvl={} current_pos=0x{:02x}", current_path_level, $));
// }
(_): {
std::error(std::format("unknown EntryType idx={} current_pos=0x{:02x}", std::core::array_index(), $));
}
}
}[[format_read("fmt_BCSSEntry")]];
fn on_dir_enter(str folder_name) {
// std::print("on_dir_enter folder={} current_lvl={}", folder_name, current_path_level);
if (std::string::length(folder_name) > 0) {
current_path[current_path_level] = folder_name;
current_path_level += 1;
} else {
std::warning(std::format("invalid folder name {} current_lvl={} current_pos=0x{:02x}", folder_name, current_path_level, $));
}
};
fn on_dir_exit() {
if (current_path_level > 0) {
current_path_level -= 1;
} else if (!std::mem::eof()) {
std::warning(std::format("on_dir_exit current_lvl already == 0 current_pos=0x{:02x}", $));
}
// std::print("on_dir_exit current_lvl={}", current_path_level);
};
fn get_vfs_path(str file_name) {
str vfs_path = "";
if (current_path_level > 0) {
vfs_path = current_path[0];
for(u8 i = 1, i < current_path_level, i += 1) {
//hash_hex = hash_hex + std::format("{:02X}",bytes[i]);
vfs_path = vfs_path + "/" + current_path[i];
}
return vfs_path + "/" + file_name;
} else {
return file_name;
}
};
fn fmt_BCSSEntry(BCSSEntry e) {
try {
match (e.type) {
(EntryType::DIRECTORY | EntryType::FILE) : {
return std::format("{}: {}", (e.type == EntryType::DIRECTORY ? "Dir" : "File"), e.name.data);
}
(EntryType::SYMLINK) : {
return std::format("Symlink: {} -> {}", e.name.data, e.target.data);
}
(EntryType::DIR_END) : {
return "Directory End";
}
}
} catch {
return "[FmtErr]";
}
};
struct BCSSFile {
if (std::mem::read_unsigned(0, 4) == 0x53534342) {
type::Magic<"BCSS"> magic;
u8 unknown[14];
std::string::SizedString<u16> root_path;
u8 zlib_content[std::mem::size()-$];
// manually add zlib header which is essential for hex::dec::zlib_decompress
const str zlib_header = "\x78\x9c";
std::mem::Section zlib_compressed = std::mem::create_section("zlib_compressed");
std::mem::copy_value_to_section(zlib_header, zlib_compressed, 0);
std::mem::copy_value_to_section(zlib_content, zlib_compressed, 2);
u8 zlib[std::mem::get_section_size(zlib_compressed)] @ 0x00 in zlib_compressed;
#ifdef __IMHEX__
std::mem::Section zlib_decompressed = std::mem::create_section("zlib_decompressed");
hex::dec::zlib_decompress(zlib, zlib_decompressed, 15);
u8 decompressed_content[std::mem::get_section_size(zlib_decompressed)] @ 0x00 in zlib_decompressed;
hex::core::add_virtual_file("bcss_content", decompressed_content);
std::warning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n! BCSS file content is compressed !\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\nopen `bcss_content` file from the Virtual Filesystem tab and run this pattern on it.");
#endif
} else {
BCSSEntry entries[while(!std::mem::eof())];
}
};
BCSSFile bcss_file @ 0x00;

View File

@@ -1,5 +1,5 @@
#pragma author WerWolv
#pragma description Bencode encoding, used by Torrent files
#pragma description Torrent data (Bencode)
#pragma MIME application/x-bittorrent
@@ -8,20 +8,20 @@ import std.mem;
import std.string;
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',
@@ -33,30 +33,30 @@ namespace bencode {
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;
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')];
DictionaryEntry entry[while(std::mem::read_unsigned($, 1) != 'e')];
} else if (type == Type::Integer) {
ASCIIDecimal value;
char end;
@@ -65,12 +65,12 @@ namespace bencode {
String value;
}
};
struct Bencode {
Value value[while(!std::mem::eof())] [[inline]];
Value value[while(!std::mem::eof())] [[inline]];
char end;
};
}
bencode::Bencode bencode @ 0x00;

101
patterns/bgcode.hexpat Normal file
View File

@@ -0,0 +1,101 @@
#pragma author Shadlock0133 (aka Aurora) / WerWolv
#pragma description Prusa Binary G-Code
#pragma magic [ 47 43 44 45 ] @ 0x00
import type.magic;
import std.mem;
enum ChecksumType : u16 {
None = 0,
CRC32 = 1
};
enum BlockType : u16 {
FileMetadata = 0,
GCode = 1,
SlicerMetadata = 2,
PrinterMetadata = 3,
PrintMetadata = 4,
Thumbnail = 5
};
enum CompressionType : u16 {
NoCompression = 0,
Deflate = 1,
HeatshrinkWindowSize11 = 2,
HeatshrinkWindowSize12 = 3
};
struct BlockHeader {
BlockType type;
CompressionType compressionType;
u32 uncompressedSize;
if (compressionType != CompressionType::NoCompression) {
u32 compressedSize;
}
u32 dataSize = compressionType == CompressionType::NoCompression ? uncompressedSize : compressedSize;
};
enum Encoding : u16 {
INI = 0
};
struct Metadata {
Encoding encoding;
char data[parent.header.dataSize];
};
enum ImageFormat : u16 {
PNG = 0,
JPG = 1,
QOI = 2
};
struct Thumbnail {
ImageFormat format;
u16 width, height;
std::mem::Bytes<parent.header.dataSize> imageData;
} [[hex::visualize("image", imageData)]];
enum GCodeEncoding : u16 {
NoEncoding = 0,
MeatPack = 1,
MeatPackWithComments = 2
};
struct GCode {
GCodeEncoding encoding;
std::mem::Bytes<parent.header.dataSize> gcode;
};
struct Block {
BlockHeader header;
match (header.type) {
(BlockType::FileMetadata): Metadata fileMetadata;
(BlockType::PrinterMetadata): Metadata printerMetadata;
(BlockType::Thumbnail): Thumbnail thumbnail;
(BlockType::PrintMetadata): Metadata printMetadata;
(BlockType::SlicerMetadata): Metadata slicerMetadata;
(BlockType::GCode): GCode gcode;
(_): std::error("Invalid Block type!");
}
if (parent.checksumType != ChecksumType::None)
u32 checksum;
};
struct BGCode {
type::Magic<"GCDE"> magic;
u32 version;
std::assert(version == 1, "Only Version 1 is supported");
ChecksumType checksumType;
Block blocks[while(!std::mem::eof())];
};
BGCode bgcode @ 0x00;

24
patterns/binka.hexpat Normal file
View File

@@ -0,0 +1,24 @@
#pragma author DexrnZacAttack
#pragma description RAD Game Tools BINKA (Bink Audio)
#pragma magic [31 46 43 42] @ 0x00
import std.string;
import std.math;
import type.magic;
fn getDuration(u32 duration_ts, u32 sample_rate) {
return float(duration_ts) / float(sample_rate);
};
struct Binka {
type::Magic<"1FCB"> magic;
u8; // can't get this to change anything when using ffprobe
u8 channel_count [[name(std::format("Channel Count: {}", this))]];
u16 sample_rate [[name(std::format("Sample Rate: {}", this))]];
u32 duration_ts [[name(std::format("Duration: {}s", std::math::floor(getDuration(this, sample_rate))))]];
u32;
u32 size [[name(std::format("File Size: {} bytes", this))]];
u8 data[size - 20];
};
Binka binka @ 0x00;

196
patterns/blend.hexpat Normal file
View File

@@ -0,0 +1,196 @@
#pragma description Blender file
#pragma magic [42 4C 45 4E 44 45 52] @ 0x00
/*
* References:
* https://projects.blender.org/blender/blender
* https://github.com/facebook/zstd/blob/master/contrib/seekable_format/zstd_seekable_compression_format.md
*
* Refer to the following files/structs:
* source/blender/blenloader/intern/writefile.cc
* source/blender/blenkernel/BKE_main.hh BlendThumbnail
* source/blender/makesdna/DNA_sdna_types.h BHead
*/
// Increased the pattern limit to be able to evaluate all pixels of the embedded thumbnail.
#pragma pattern_limit 1000000
#ifdef __IMHEX__
import hex.dec;
#endif
import std.core;
import std.io;
import std.mem;
import std.string;
import std.sys;
import type.color;
import type.magic;
// Useful for extracting the thumbnail if the rest of the blend file is corrupted or truncated.
bool quitAfterThumbnailIsParsed in;
// Allow the pattern evaluator to skip the thumbnail e.g. if evaluation takes too long.
bool skipThumbnail in;
struct BHead<Ptr> {
char code[4];
s32 len;
Ptr old;
s32 SDNAnr;
s32 nr;
// ENDB marks the last data block in the file.
if (code == "ENDB") {
break;
}
};
struct ThumbnailLine<auto width> {
type::RGBA8 pixels[width];
};
fn copyThumbnail(u32 height, ref auto lines, std::mem::Section target) {
for (s64 l = (height - 1), l >= 0, l = l - 1) {
u64 currentSectionSize = std::mem::get_section_size(target);
// Append the current line to section.
std::mem::copy_value_to_section(lines[l], target, currentSectionSize);
}
};
struct Thumbnail {
u32 width;
u32 height;
u128 size = width * height;
ThumbnailLine<width> lines[height];
// Generate the thumbnail section.
std::mem::Section thumbnailFlipped = std::mem::create_section("thumbnail");
copyThumbnail(height, lines, thumbnailFlipped);
type::RGBA8 image[size] @ 0x00 in thumbnailFlipped;
}
#ifdef __IMHEX__
[[hex::visualize("bitmap", image, width, height)]]
#endif
;
struct DataBlock<Ptr> {
BHead<Ptr> bHead;
if (bHead.SDNAnr == 0 && bHead.code == "TEST") {
if (skipThumbnail) {
u8 thumbnail[bHead.len]; // Interpret as raw binary data.
} else {
Thumbnail thumbnail;
auto thumbnailSize = sizeof(thumbnail);
std::assert(thumbnailSize == bHead.len,
std::format("The thumbnail (size={:#x}) does not fit exactly into its DataBlock (len={:#x})!",
thumbnailSize, bHead.len));
}
if (quitAfterThumbnailIsParsed) {
break;
}
} else {
u8 data[bHead.len]; // Unknown. Interpret as raw binary data.
}
};
enum PointerSize : char {
POINTER_4BYTE = '_',
POINTER_8BYTE = '-'
};
enum Endianness : char {
BIG_ENDIAN = 'V',
LITTLE_ENDIAN = 'v'
};
struct Blend<auto inputSize> {
type::Magic<"BLENDER"> magic;
PointerSize pointerSize;
Endianness endianness;
char version[3];
match (endianness) {
(Endianness::LITTLE_ENDIAN): std::core::set_endian(std::mem::Endian::Little);
(Endianness::BIG_ENDIAN): std::core::set_endian(std::mem::Endian::Big);
(_): std::error("Invalid value for endianness!");
}
match (pointerSize) {
(PointerSize::POINTER_4BYTE): DataBlock<u32> dataBlock[while($ < inputSize)];
(PointerSize::POINTER_8BYTE): DataBlock<u64> dataBlock[while($ < inputSize)];
(_): std::error("Invalid pointer size!");
}
};
struct BlendWrapper {
u128 currentPos = $;
char magic[4] @ currentPos [[hidden]];
if (magic != "\x28\xB5\x2F\xFD") { // ZSTD magic
// Assume the blend file is uncompressed.
Blend<sizeof($)> blend @ currentPos;
return;
}
} [[inline]];
BlendWrapper blendWrapper @ 0x00;
// Assume the blend file is ZSTD compressed.
struct SeekTableFooter {
u32 numFrames;
char flag;
type::Magic<"\xB1\xEA\x92\x8F"> footerMagic;
};
u128 seekTableFooterSize = 9;
SeekTableFooter seekTableFooter @ (sizeof($) - seekTableFooterSize);
struct SeekTableEntry {
u32 compressedSize;
u32 uncompressedSize;
};
u128 seekTableEntrySize = 8;
SeekTableEntry seekTableEntries[seekTableFooter.numFrames]
@ (addressof(seekTableFooter) - seekTableFooter.numFrames * seekTableEntrySize);
struct SeekTableHeader {
type::Magic<"\x5E\x2A\x4D\x18"> magic;
u32 frameSize;
};
u128 seekTableHeaderSize = 8;
std::assert(seekTableFooter.numFrames > 0, "The seek table must contain entries!");
SeekTableHeader seekTableHeader @ (addressof(seekTableEntries[0]) - seekTableHeaderSize);
u32 frameIndex = 0;
struct ZSTDFrame {
u8 data[seekTableEntries[frameIndex].compressedSize];
frameIndex = frameIndex + 1;
};
ZSTDFrame zstdFrames[seekTableFooter.numFrames] @ 0x00;
#ifdef __IMHEX__
std::mem::Section decompressedSection = std::mem::create_section("decompressedBlend");
u128 previousSectionSize = 0;
for (u32 i = 0, i < seekTableFooter.numFrames, i = i + 1) {
std::assert(hex::dec::zstd_decompress(zstdFrames[i].data, decompressedSection),
"Decompression failed!");
u32 uncompressedSize = seekTableEntries[i].uncompressedSize;
u128 currentSectionSize = std::mem::get_section_size(decompressedSection)
- previousSectionSize;
std::assert_warn(uncompressedSize == currentSectionSize,
std::format("The uncompressedSize {} for ZSTDFrame #{} "
+ "must be equal to its actual decompressed size{}!",
uncompressedSize, i, currentSectionSize));
previousSectionSize += currentSectionSize;
};
Blend<previousSectionSize> blend @ 0x00 in decompressedSection;
#endif

View File

@@ -1,4 +1,4 @@
#pragma description OS2/Windows Bitmap files
#pragma description OS2/Windows Bitmap
#pragma MIME image/bmp
#pragma endian little
@@ -97,7 +97,7 @@ struct Bitmap {
(_): BitmapInfoHeaderV1 bmih;
}
padding[bmih.biSize - sizeof(bmih)];
if (bmih.biBitCount <= 8)
{
if (bmih.biClrUsed > 0 )
@@ -105,7 +105,7 @@ struct Bitmap {
else
Colors rgbq[1 << bmih.biBitCount];
}
if (bmih.biSizeImage > 0 )
u8 lineData[bmih.biSizeImage];
else

View File

@@ -1,3 +1,6 @@
#pragma description Apple binary property list
#pragma MIME application/x-bplist
import std.math;
import std.core;
import type.magic;
@@ -27,14 +30,14 @@ enum Marker : u8 {
UNK_0xF0 = 0xF0
};
fn get_marker_name(u8 marker) {
fn get_marker_name(u8 marker) {
if (marker == Marker::Null){// null 0000 0000
return "Null ";
}else if (marker == Marker::False){ //bool 0000 1000 // false
return "False";
}else if (marker == Marker::True){//bool 0000 1001 // true
return "True";
}else if (marker == Marker::Fill){ //fill 0000 1111 // fill byte
}else if (marker == Marker::Fill){ //fill 0000 1111 // fill byte
return "Fill";
}else if (marker & 0xF0 == Marker::Int){ //int 0001 nnnn ... // # of bytes is 2^nnnn, big-endian bytes
return "Int";
@@ -43,10 +46,10 @@ fn get_marker_name(u8 marker) {
}else if (marker == Marker::Date){ //date 0011 0011 ... // 8 byte float follows, big-endian bytes
return "Date";
}else if (marker & 0xF0 == Marker::Data){ //data 0100 nnnn [int] ... // nnnn is number of bytes unless 1111 then int count follows, followed by bytes
return "Data";
return "Data";
}else if (marker & 0xF0 == Marker::ASCIIString){ //string 0101 nnnn [int] ... // ASCII string, nnnn is # of chars, else 1111 then int count, then bytes
return "ASCIIString";
}else if (marker & 0xF0 == Marker::Unicode16String){ //string 0110 nnnn [int] ... // Unicode string, nnnn is # of chars, else 1111 then int count, then big-endian 2-byte
}else if (marker & 0xF0 == Marker::Unicode16String){ //string 0110 nnnn [int] ... // Unicode string, nnnn is # of chars, else 1111 then int count, then big-endian 2-byte
return "Unicode16String";
}else if (marker & 0xF0 == Marker::UNK_0x70){ //0111 xxxx // unused
return "UNK_0x70";
@@ -54,19 +57,19 @@ fn get_marker_name(u8 marker) {
return "UID";
}else if (marker & 0xF0 == Marker::UNK_0x90){ // 1001 xxxx // unused
return "UNK_0x90";
}else if (marker & 0xF0 == Marker::Array){ //array 1010 nnnn [int] objref* // nnnn is count, unless '1111', then int count follows
}else if (marker & 0xF0 == Marker::Array){ //array 1010 nnnn [int] objref* // nnnn is count, unless '1111', then int count follows
return "Array";
}else if (marker & 0xF0 == Marker::UNK_0xB0){ //1011 xxxx // unused
return "UNK_0xB0";
}else if (marker & 0xF0 == Marker::Set){ //set 1100 nnnn [int] objref* // nnnn is count, unless '1111', then int count follows
return "Set";
}else if (marker & 0xF0 == Marker::Dict){ //dict 1101 nnnn [int] keyref* objref* // nnnn is count, unless '1111', then int count follows
}else if (marker & 0xF0 == Marker::Dict){ //dict 1101 nnnn [int] keyref* objref* // nnnn is count, unless '1111', then int count follows
return "Dict";
}else if (marker & 0xF0 == Marker::UNK_0xE0){ // 1110 xxxx // unused
return "UNK_0xE0";
}else if (marker & 0xF0 == Marker::UNK_0xF0){ //1111 xxxx // unused
return "UNK_0xF0";
}
}
};
fn format_tag(u8 marker) {
@@ -77,12 +80,12 @@ fn coredata_to_date (double val){
return type::impl::format_time_t(978307200 + val);
};
struct DictElement {
struct DictElement {
CFBinaryPlistObject key @ offsetTable[parent.objReference.key_refs[std::core::array_index()]].offset;
CFBinaryPlistObject value @ offsetTable[parent.objReference.value_refs[std::core::array_index()]].offset;
};
struct ArrayElement {
struct ArrayElement {
CFBinaryPlistObject value @ offsetTable[parent.objReference.value_refs[std::core::array_index()]].offset;
};
@@ -140,23 +143,23 @@ struct CFBinaryPlistOffset{
struct CFBinaryPlistObject{
u8 marker [[format("get_marker_name")]];
u8 marker_msb = marker & 0xF0;
u8 marker_lsb = marker & 0x0F;
match (marker_msb){
match (marker_msb){
(0x0): {
match (marker_lsb){
(Marker::Null): {
u8 value = 0x00 [[export]];
}
(Marker::False): {
(Marker::False): {
bool value = false [[export]];
}
(Marker::True): {
bool value = true [[export]];
}
(Marker::Fill): {
(Marker::Fill): {
//I think the correct implementation is to do nothing here. The marker will be used as padding (Fill) ???
}
(_): {
@@ -165,7 +168,7 @@ struct CFBinaryPlistObject{
}
}
(Marker::Int): {
be u8 size = std::math::pow(2, marker_lsb);
be u8 size = std::math::pow(2, marker_lsb);
// in format version '00', 1, 2, and 4-byte integers have to be interpreted as unsigned,
// whereas 8-byte integers are signed (and 16-byte when available)
// negative 1, 2, 4-byte integers are always emitted as 8 bytes in format '00'
@@ -179,10 +182,10 @@ struct CFBinaryPlistObject{
(8): be s64 value;
(16): be s128 value;
(_): std::error(std::format("Invalid size detected for 'Int' marker. Got size: {}.", size));
}
}
}
(Marker::Real): {
be u8 size = std::math::pow(2, marker_lsb);
be u8 size = std::math::pow(2, marker_lsb);
match (size){
(4): be float value;
(8): be double value;
@@ -194,7 +197,7 @@ struct CFBinaryPlistObject{
}
(Marker::Data): {
ObjectLen ObjectLen;
u8 value[ObjectLen.size];
u8 value[ObjectLen.size];
}
(Marker::ASCIIString): {
ObjectLen ObjectLen;
@@ -214,7 +217,7 @@ struct CFBinaryPlistObject{
(8): be u64 value;
(16): be u128 value;
(_): std::error(std::format("Invalid size detected for 'UID' marker. Got size: {}.", size));
}
}
}
(Marker::Set | Marker::Array): {
ObjectLen ObjectLen;
@@ -224,7 +227,7 @@ struct CFBinaryPlistObject{
}
(Marker::Dict): {
ObjectLen ObjectLen;
ObjectReference objReference;
DictElement value[ObjectLen.size];
}
@@ -233,7 +236,7 @@ struct CFBinaryPlistObject{
}
(_): {
std::error(std::format("Got unknown marker 0x{:x}", marker));
}
}
}
};
@@ -247,13 +250,13 @@ struct CFBinaryPlistHeader{
struct CFBinaryPlistTrailer {
u8 unused[5];
u8 sortVersion;
u8 sortVersion;
be u8 offsetIntSize;
match (offsetIntSize){
(1|2|4|8): {}
(_): {std::error("Invalid offsetIntSize.");}
}
be u8 objectRefSize;
be u8 objectRefSize;
match (objectRefSize){
(1|2|4|8): {}
(_): {std::error("Invalid objectRefSize.");}

View File

@@ -1,5 +1,5 @@
#pragma author WerWolv
#pragma description BSON (Binary JSON) format
#pragma description BSON (Binary JSON)
#pragma MIME application/bson
@@ -26,8 +26,8 @@ enum Type : u8 {
Timestamp = 0x11,
Int64 = 0x12,
Decimal128 = 0x13,
MinKey = 0xFF,
MinKey = 0xFF,
MaxKey = 0x7F
};
@@ -78,9 +78,9 @@ using Document;
struct Element {
Type type;
CString name;
if (type == Type::Double) {
double value;
} else if (type == Type::String) {
@@ -93,9 +93,9 @@ struct Element {
Binary value;
} else if (type == Type::Undefined) {
/* undefined */
} else if (type == Type::ObjectId) {
} else if (type == Type::ObjectId) {
ObjectId value;
} else if (type == Type::Boolean) {
} else if (type == Type::Boolean) {
bool value;
} else if (type == Type::UTCDatetime) {
type::time64_t value;

View File

@@ -1,4 +1,4 @@
#pragma description GoldSrc engine maps format (used in Half-Life 1)
#pragma description GoldSrc engine map (Half-Life 1)
import std.ptr;
import std.mem;
@@ -163,7 +163,7 @@ struct dmiptexlump_t
MiptexPointer dataofs[nummiptex];
};
struct VisibilityData
struct VisibilityData
{
u8 data[file_header.lumps[LumpIndex::Visibility].filelen];
u8 pad[std::mem::align_to(4, sizeof(this)) - sizeof(this)];

64
patterns/bzip3.hexpat Normal file
View File

@@ -0,0 +1,64 @@
#pragma author Sewer56
#pragma description Parses BZip3 compression (file format) by Kamila Szewczyk
#pragma MIME application/x-bzip3
#pragma endian little
#pragma magic [42 5A 33 76 31] @ 0x00
import std.mem;
// Helper function for bit counting
fn popcount(u8 b) {
u32 count = 0;
while (b != 0) {
count = count + (b & 1);
b = b >> 1;
}
return count;
};
// Frame header structure
struct FrameHeader {
char magic[5]; // "BZ3v1"
u32 blockSize; // Maximum block size
};
// Small block header (for blocks < 64 bytes)
struct SmallBlock {
u32 crc32; // CRC32 checksum
u32 literal; // Always 0xFFFFFFFF for small blocks
u8 data[parent.compressedSize - 8]; // Uncompressed data
};
// Regular block (blocks > 64 bytes)
struct Block {
u32 crc32; // CRC32 checksum of uncompressed data
u32 bwtIndex; // Burrows-Wheeler transform index
u8 model; // Compression model flags
if ((model & 0x02) != 0)
u32 lzpSize; // Size after LZP compression
if ((model & 0x04) != 0)
u32 rleSize; // Size after RLE compression
u8 data[parent.compressedSize - (popcount(model) * 4 + 9)];
};
// Main block structure
struct Chunk {
u32 compressedSize; // Size of compressed block
u32 origSize; // Original uncompressed size
if (origSize < 64) {
SmallBlock block;
} else {
Block block;
}
};
// Main parsing structure
struct BZip3File {
FrameHeader header;
// Read blocks until end of file
Chunk chunks[while(!std::mem::eof())];
};
BZip3File file @ 0x0;

110
patterns/cab.hexpat Normal file
View File

@@ -0,0 +1,110 @@
#pragma author The Wandering Trader
#pragma description Microsoft Cabinet (CAB) Files
#pragma magic [4D 53 43 46] @ 0x00
import type.time;
import type.magic;
import type.size;
fn format_string(auto string) {
return std::format("{}",string);
};
bitfield flags {
bool cfhdrPREV_CABINET : 1;
bool cfhdrNEXT_CABINET : 1;
bool cfhdrRESERVE_PRESENT : 1;
padding : 13;
};
struct CFHEADER {
type::Magic<"MSCF"> signature;
u32 reserved1;
type::Size32 cbCabinet;
u32 reserved2;
u32 coffFiles;
u32 reserved3;
u8 versionMajor;
u8 versionMinor;
u16 cFolders;
u16 cFiles;
flags flags;
u16 setID;
u16 iCabinet;
if (flags.cfhdrRESERVE_PRESENT) {
type::Size16 cbCFHeader;
type::Size8 cbCFFolder;
type::Size8 cbCFData;
u8 abReserve[cbCFHeader];
}
if (flags.cfhdrPREV_CABINET) {
char szCabinetPrev[] [[format("format_string")]];
char szDiskPrev[] [[format("format_string")]];
}
if (flags.cfhdrNEXT_CABINET) {
char szCabinetNext[] [[format("format_string")]];
char szDiskNext[] [[format("format_string")]];
}
};
enum typeCompress : u8{
tcompMASK_TYPE = 0x000F,
tcompTYPE_NONE = 0x0000,
tcompTYPE_MSZIP = 0x0001,
tcompTYPE_QUANTUM = 0x0002,
tcompTYPE_LZX = 0x0003,
};
using CFDATA;
struct CFFOLDER {
u32 coffCabStart;
u16 cCfData;
typeCompress typeCompress;
u8 compressionLevel;
if (CFHEADER.flags.cfhdrRESERVE_PRESENT) {
u8 abReserve[CFHEADER.cbCFFolder];
}
CFDATA CFDATA[cCfData] @ coffCabStart;
};
bitfield attribs {
bool _A_RDONLY : 1;
bool _A_HIDDEN : 1;
bool _A_SYSTEM : 1;
padding : 2;
bool _A_ARCH : 1;
bool _A_EXEC : 1;
bool _A_NAME_IS_UTF : 1;
padding : 8;
};
struct CFFILE {
type::Size32 cbFile;
u32 uoffFolderStart;
u16 iFolder;
type::DOSDate date;
type::DOSTime time;
attribs attribs;
if (attribs._A_NAME_IS_UTF) {
char16 szName[];
} else {
char szName[] [[format("format_string")]];
}
};
struct CFDATA {
u32 csum;
type::Size16 cbData;
type::Size16 cbUncomp;
if (CFHEADER.flags.cfhdrRESERVE_PRESENT) {
u8 abReserve[CFHEADER.cbCFData];
}
u8 ab[cbData];
};
CFHEADER CFHEADER @ 0;
CFFOLDER CFFOLDER[CFHEADER.cFolders] @ $;
CFFILE CFFILE[CFHEADER.cFiles] @ $;

View File

@@ -1,29 +1,29 @@
#pragma description Compact Disc Audio track
#pragma magic [ 52 49 46 46 ] @ 0x00
struct Header {
u32 RIFF;
s32 size;
u32 CDDA;
u32 fmt;
u32 lenghtofthechunck;
u16 versionofcdformat;
u16 numberofrange;
u32 identifier;
u32 RIFF;
s32 size;
u32 CDDA;
u32 fmt;
u32 lenghtofthechunck;
u16 versionofcdformat;
u16 numberofrange;
u32 identifier;
};
struct DataInfo {
u32 range;
u32 duration;
u8 rangepositionframes;
u8 rangepositionseconds;
u8 rangepositionminutes;
u8 nullbyte;
u8 durationtrackframes;
u8 durationtrackseconds;
u8 durationtrackminutes;
u8 nullbytee;
u32 range;
u32 duration;
u8 rangepositionframes;
u8 rangepositionseconds;
u8 rangepositionminutes;
u8 nullbyte;
u8 durationtrackframes;
u8 durationtrackseconds;
u8 durationtrackminutes;
u8 nullbytee;
};

View File

@@ -1,5 +1,6 @@
#pragma author WerWolv
#pragma description Windows HtmlHelp Data (ITSF / CHM)
#pragma MIME application/vnd.ms-htmlhelp
import type.magic;
import type.size;
@@ -285,26 +286,26 @@ struct DirectoryIndexEntry {
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!");
@@ -313,7 +314,7 @@ struct ListingChunk {
struct HeaderSection {
char magic[4];
if (magic == "\xFE\x01\x00\x00") {
u32;
type::Size<u64> fileSize;
@@ -337,7 +338,7 @@ struct HeaderSection {
u32;
u32;
u32;
ListingChunk chunk[directoryChunkCount];
} else {
std::error("Invalid header section magic!");
@@ -347,22 +348,22 @@ struct HeaderSection {
struct HeaderSectionTableEntry {
u64 offset;
type::Size<u64> size;
HeaderSection headerSection @ offset;
};
struct NameListEntry {
type::Size<u16> nameLength;
char16 name[nameLength];
char16 name[nameLength];
padding[2];
};
struct NameListFile {
u16 fileLengthWords;
u16 entriesInFile;
NameListEntry nameList[entriesInFile];
padding[0x2E];
};
@@ -376,7 +377,7 @@ struct SectionData {
u32;
};
struct Content {
struct Content {
NameListFile nameListFile;
SectionData sectionData;
};
@@ -389,9 +390,9 @@ struct CHM {
be u32 timeStamp;
WindowsLanguageId languageId;
type::GUID guids[2];
HeaderSectionTableEntry headerSectionTable[2];
Content *dataOffset : u64;
};

View File

@@ -116,11 +116,11 @@ struct SymbolTable {
Type type;
StorageClass storageClass;
u8 numberOfAuxSymbols;
countedSymbols += 1 + numberOfAuxSymbols;
AuxSymbol auxSymbols[numberOfAuxSymbols];
if (countedSymbols >= parent.header.numberOfSymbols)
break;
};
@@ -164,7 +164,10 @@ bitfield SectionFlags {
};
fn format_alignment(u8 alignment) {
return 1 << alignment;
if(alignment > 0) {
return 1 << (alignment - 1);
}
return alignment;
};
struct Relocations {
@@ -184,7 +187,7 @@ struct Section {
u16 numberOfRelocations;
u16 numberOfLineNumbers;
SectionFlags characteristics;
u8 rawData[sizeOfRawData] @ pointerToRawData [[sealed]];
Relocations relocations[numberOfRelocations] @ pointerToRelocations;
};
@@ -202,9 +205,9 @@ struct Header {
struct COFF {
Header header;
Section sectionTable[header.numberOfSections];
SymbolTable symbolTable[header.numberOfSymbols] @ header.pointerToSymbolTable;
StringTable stringTable @ addressof(symbolTable) + sizeof(symbolTable);
};

View File

@@ -1,5 +1,5 @@
#pragma author WerWolv
#pragma description Old Binary CPIO Format
#pragma description Old Binary CPIO
import type.base;
@@ -42,7 +42,7 @@ namespace old_binary {
std::core::set_endian(std::mem::Endian::Little);
else
std::error("Invalid CPIO Magic!");
u16 dev;
u16 ino;
Mode mode;
@@ -59,7 +59,7 @@ namespace old_binary {
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;
};

99
patterns/credhist.hexpat Normal file
View File

@@ -0,0 +1,99 @@
#pragma description "CREDHIST"
/*
FilePath: C:\Users\<USER>\AppData\Roaming\Microsoft\Protect\
The files/folders are hidden.
To unhide it
1. Open Command Prompt (cmd.exe).
2. Run the following command:
=> attrib -h -s
*/
import type.guid;
import std.mem;
// https://learn.microsoft.com/en-us/windows/win32/seccrypto/alg-id
enum ALG_ID : u32 {
CALG_DH_EPHEM = 0x0000aa02, // Diffie-Hellman ephemeral key exchange algorithm.
CALG_DH_SF = 0x0000aa01, // Diffie-Hellman store and forward key exchange algorithm.
CALG_DSS_SIGN = 0x00002200, // DSA public key signature algorithm.
CALG_ECDH = 0x0000aa05, // Elliptic curve Diffie-Hellman key exchange algorithm.
CALG_ECDH_EPHEM = 0x0000ae06, // Ephemeral elliptic curve Diffie-Hellman key exchange algorithm.
CALG_ECDSA = 0x00002203, // Elliptic curve digital signature algorithm.
CALG_ECMQV = 0x0000a001, // Elliptic curve Menezes, Qu, and Vanstone (MQV) key exchange algorithm.
CALG_HASH_REPLACE_OWF = 0x0000800b, // One way function hashing algorithm.
CALG_HUGHES_MD5 = 0x0000a003, // Hughes MD5 hashing algorithm.
CALG_HMAC = 0x00008009, // HMAC keyed hash algorithm.
CALG_KEA_KEYX = 0x0000aa04, // KEA key exchange algorithm (FORTEZZA).
CALG_MAC = 0x00008005, // MAC keyed hash algorithm.
CALG_MD2 = 0x00008001, // MD2 hashing algorithm.
CALG_MD4 = 0x00008002, // MD4 hashing algorithm.
CALG_MD5 = 0x00008003, // MD5 hashing algorithm.
CALG_NO_SIGN = 0x00002000, // No signature algorithm.
CALG_OID_INFO_CNG_ONLY = 0xffffffff, // Algorithm is only implemented in CNG.
CALG_OID_INFO_PARAMETERS = 0xfffffffe, // Algorithm is defined in the encoded parameters.
CALG_PCT1_MASTER = 0x00004c04, // Used by the Schannel.dll operations system.
CALG_RC2 = 0x00006602, // RC2 block encryption algorithm.
CALG_RC4 = 0x00006801, // RC4 stream encryption algorithm.
CALG_RC5 = 0x0000660d, // RC5 block encryption algorithm.
CALG_RSA_KEYX = 0x0000a400, // RSA public key exchange algorithm.
CALG_RSA_SIGN = 0x00002400, // RSA public key signature algorithm.
CALG_SCHANNEL_ENC_KEY = 0x00004c07, // Used by the Schannel.dll operations system.
CALG_SCHANNEL_MAC_KEY = 0x00004c03, // Used by the Schannel.dll operations system.
CALG_SCHANNEL_MASTER_HASH = 0x00004c02, // Used by the Schannel.dll operations system.
CALG_SEAL = 0x00006802, // SEAL encryption algorithm.
CALG_SHA = 0x00008004, // SHA hashing algorithm.
CALG_SHA1 = 0x00008004, // Same as CALG_SHA.
CALG_SHA_256 = 0x0000800c, // 256-bit SHA hashing algorithm.
CALG_SHA_384 = 0x0000800d, // 384-bit SHA hashing algorithm.
CALG_SHA_512 = 0x0000800e, // 512-bit SHA hashing algorithm.
CALG_SKIPJACK = 0x0000660a, // Skipjack block encryption algorithm (FORTEZZA).
CALG_SSL2_MASTER = 0x00004c05, // Used by the Schannel.dll operations system.
CALG_SSL3_MASTER = 0x00004c01, // Used by the Schannel.dll operations system.
CALG_SSL3_SHAMD5 = 0x00008008, // Used by the Schannel.dll operations system.
CALG_TEK = 0x0000660b, // TEK (FORTEZZA).
CALG_TLS1_MASTER = 0x00004c06, // Used by the Schannel.dll operations system.
CALG_TLS1PRF = 0x0000800a // Used by the Schannel.dll operations system.
};
// https://devblogs.microsoft.com/oldnewthing/20040315-00/?p=40253
struct SID {
u8 revisionlvl[[name("RevisionLevel"), comment("SID_REVISION")]];
u8 dashes[[name("NoOfDashes"), comment("number of dashes minus two")]]; // dashes = actualdashes - 0x2
char ntauth[0x6][[name("NtAuthority"), comment("SECURITY_NT_AUTHORITY")]];
u32 subatuh1[[name("SubAuthority1"), comment("SECURITY_NT_NON_UNIQUE")]];
u32 subatuh2[[name("SubAuthority2"), comment("these identify the machine that issued the SID")]];
u32 subatuh3[[name("SubAuthority3"), comment("these identify the machine that issued the SID")]];
u32 subatuh4[[name("SubAuthority4"), comment("these identify the machine that issued the SID")]];
u32 rid[[name("RID"), comment("unique user id on the machine")]];
};
struct CREDHIST_HEADER{
u32 version[[name("Version")]];
type::GUID guid[[name("GUID")]];
u32 nextlen[[name("NextCredSize")]];
};
struct CREDHIST {
CREDHIST_HEADER credheader[[name("CredHistHeader")]];
if (std::mem::eof()){
break;
}
u32 flgas [[name("Flags")]];
ALG_ID alghashid[[name("AlgorithmHashId")]];
u32 rounds [[name("Rounds")]];
u32 sidlen [[name("SIDLen")]];
ALG_ID algcryptid[[name("AlgorithmCryptId")]];
u32 sha1len[[name("SHA1Len")]];
u32 md4len[[name("ntlmlen")]];
char salt[0x10][[name("Salt")]];
SID sid[[name("SID")]];
char sha1hash[sha1len][[name("SHA1Hash")]];
char md4hash[md4len][[name("NTLMHash")]];
u64 unk1[[name("Unknown")]];
};
CREDHIST credhist [while(!std::mem::eof())] @ 0x0[[name("CredHist")]];

View File

@@ -1,6 +1,7 @@
#pragma description DirectDraw Surface
#pragma MIME image/vnd-ms.dds
#pragma MIME image/x-dds
#pragma endian little
enum DXGI_FORMAT : u32 {
@@ -167,16 +168,26 @@ bitfield Caps2Flags {
};
bitfield PixelFormatFlags {
alphaPixels : 1;
alpha : 1;
fourCC : 1;
padding : 3;
rgb : 1; // 0x40
padding : 2;
yuv : 1; // 0x200
padding : 3;
luminance : 1; // 0x20000
padding : 17;
alphaPixels : 1; // DDPF_ALPHAPIXELS
alpha : 1; // DDPF_ALPHA
fourCC : 1; // DDPF_FOURCC
paletteIndexed4 : 1; // DDPF_PALETTEINDEXED4
paletteIndexedTo8 : 1; // DDPF_PALETTEINDEXEDTO8
paletteIndexed8 : 1; // DDPF_PALETTEINDEXED8
rgb : 1; // DDPF_RGB
compressed : 1; // DDPF_COMPRESSED
rgbToYuv : 1; // DDPF_RGBTOYUV
yuv : 1; // DDPF_YUV
zBuffer : 1; // DDPF_ZBUFFER
paletteIndexed1 : 1; // DDPF_PALETTEINDEXED1
paletteIndexed2 : 1; // DDPF_PALETTEINDEXED2
zPixels : 1; // DDPF_ZPIXELS
stencilBuffer : 1; // DDPF_STENCILBUFFER
alphaResult : 1; // DDPF_ALPHARESULT
luminance : 1; // DDPF_LUMINANCE
bumpLuminance : 1; // DDPF_BUMPLUMINANCE
bumpDudv : 1; // DDPF_BUMPDUDV
padding : 13; // Padding bits to complete 32-bit structure
};
enum DX10ResourceDimension : u32 {
@@ -192,7 +203,7 @@ enum DX10AlphaMode : u32 {
Straight,
PreMultiplied,
Opaque,
Custom,
Custom,
};
bitfield DX10MiscFlags {

View File

@@ -1,4 +1,5 @@
#pragma description Dalvik EXecutable Format
#pragma description Dalvik EXecutable
#pragma magic [ 64 65 78 0A ?? ?? ?? 00 ]
import type.leb128;
@@ -99,7 +100,7 @@ enum access_flag : type::uLEB128{
static = 0x8,
final = 0x10,
synchronized = 0x20,
volatile = 0x40
volatile = 0x40
};
struct encoded_field {
@@ -134,7 +135,7 @@ struct class_def_item {
u32 class_data_off;
//class_data_item *class_data_off:u32;
u32 static_values_off;
char class_name[] @ addressof(parent.type_ids[class_idx].type_name);
char class_name[] @ addressof(parent.type_ids[class_idx].type_name);
}[[name(class_name)]];
struct type_item {

View File

@@ -1,4 +1,4 @@
#pragma description DICOM file
#pragma description DICOM Digital Imaging and Communications in Medicine
#pragma MIME application/dicom
#pragma endian little

View File

@@ -1,4 +1,5 @@
#pragma description Apple Disk Image Trailer (DMG)
#pragma magic [ 6B 6F 6C 79 ] @ -512
#pragma endian big
@@ -11,41 +12,41 @@ import std.mem;
//
// UDIFResourceFile starts at size(file) - 512
struct UDIFResourceFile {
type::Magic<"koly"> Signature; // Magic ('koly')
u32 Version; // Current version is 4
type::Size<u32> HeaderSize; // sizeof(this), always 512
type::Magic<"koly"> Signature; // Magic ('koly')
u32 Version; // Current version is 4
type::Size<u32> HeaderSize; // sizeof(this), always 512
u32 Flags;
u64 RunningDataForkOffset; //
u64 DataForkOffset; // Data fork offset (usually 0, beginning of file)
type::Size<u64> DataForkLength; // Size of data fork (usually up to the XMLOffset, below)
u64 RsrcForkOffset; // Resource fork offset, if any
type::Size<u64> RsrcForkLength; // Resource fork length, if any
u32 SegmentNumber; // Usually 1, may be 0
u32 SegmentCount; // Usually 1, may be 0
type::GUID SegmentID; // 128-bit GUID identifier of segment (if SegmentNumber !=0)
u64 RunningDataForkOffset; //
u64 DataForkOffset; // Data fork offset (usually 0, beginning of file)
type::Size<u64> DataForkLength; // Size of data fork (usually up to the XMLOffset, below)
u64 RsrcForkOffset; // Resource fork offset, if any
type::Size<u64> RsrcForkLength; // Resource fork length, if any
u32 SegmentNumber; // Usually 1, may be 0
u32 SegmentCount; // Usually 1, may be 0
u32 DataChecksumType; // Data fork
type::GUID SegmentID; // 128-bit GUID identifier of segment (if SegmentNumber !=0)
u32 DataChecksumType; // Data fork
type::Size<u32> DataChecksumSize; // Checksum Information
u32 DataChecksum[DataChecksumSize]; // Up to 128-bytes (32 x 4) of checksum
u32 DataChecksum[32]; // Up to 128-bytes (32 x 4) of checksum
u64 XMLOffset; // Offset of property list in DMG, from beginning
type::Size<u64> XMLLength; // Length of property list
u8 Reserved1[120]; // 120 reserved bytes - zeroed
u64 XMLOffset; // Offset of property list in DMG, from beginning
type::Size<u64> XMLLength; // Length of property list
u8 Reserved1[120]; // 120 reserved bytes - zeroed
u32 ChecksumType; // Master
type::Size<u32> ChecksumSize; // Checksum information
u32 Checksum[ChecksumSize]; // Up to 128-bytes (32 x 4) of checksum
u32 ChecksumType; // Master
type::Size<u32> ChecksumSize; // Checksum information
u32 Checksum[32]; // Up to 128-bytes (32 x 4) of checksum
u32 ImageVariant; // Commonly 1
u64 SectorCount; // Size of DMG when expanded, in sectors
u32 ImageVariant; // Commonly 1
u64 SectorCount; // Size of DMG when expanded, in sectors
u32 reserved2; // 0
u32 reserved3; // 0
u32 reserved4; // 0
u32 reserved2; // 0
u32 reserved3; // 0
u32 reserved4; // 0
};
UDIFResourceFile trailer @ std::mem::size() - 512;
char metadata_plist[trailer.XMLLength] @ trailer.XMLOffset;
char metadata_plist[trailer.XMLLength] @ trailer.XMLOffset;

102
patterns/dmp64.hexpat Normal file
View File

@@ -0,0 +1,102 @@
#pragma magic [ 50 41 47 45 ] @ 0x00 // PAGE
#pragma author "5h4rrK"
#pragma description "KERNEL DUMP"
import std.core;
import std.io;
import std.array;
#define COMMENT_SIZE 0x80
fn format_values(auto val){
return std::format("{:#x}", val);
};
fn format_size_values(auto val){
return std::format(
"{:#x} ({}) ",
val,
std::format("{:#x}",val * 0x1000)
);
};
union DUMP_FILE_ATTRIBUTES {
u32 bitfields[[name("BitFields")]];
u32 attributes[[name("Attributes")]];
};
enum DUMP_TYPE : u32 {
FULL_DUMP = 0x01,
BITMAP_DUMP = 0x05
};
struct EXCEPTION_RECORD64
{
u32 exception_code[[name("ExceptionCode"), format("format_values")]];
u32 exception_flags[[name("ExceptionFlags"), format("format_values")]];
u64 exception_record[[name("ExceptionRecord"), format("format_values")]];
u64 exception_address[[name("ExceptionAddress"), format("format_values")]];
u32 number_parameters[[name("NumberParameters"), format("format_values")]];
u32 unused_alignment[[name("Alignment"), format("format_values")]];
u64 exception_information[15][[name("ExceptionInformation")]];
};
struct PHYSICAL_MEMORY_RUN64 {
u64 base_page [[ name("BasePage"), format("format_size_values"), comment("StartOffset = BasePage * PageSize")]];
u64 page_count[[ name("PageCount"),format("format_size_values"), comment("Length = PageCount * PageSize")]];
}[[name("PHYSICAL_MEMORY_RUN_ENTRY")]];
struct PHYSICAL_MEMORY_DESCRIPTOR64 {
u32 no_of_runs [[name("NumberOfRuns")]];
char description[4][[name("Description")]];
u64 no_of_pages[[name("NumberOfPages"),format("format_values")]];
// PHYSICAL_MEMORY_RUN64 pmr64[no_of_runs] [[name("PHYSICAL_MEMORY_RUN64")]];
std::Array<PHYSICAL_MEMORY_RUN64, no_of_runs> pmrObjs[[name("PHYSICAL_MEMORY_RUN64")]];
};
struct DUMP_HEADER64 {
char signature[4][[name("Signature")]];
char validdump[4][[name("ValidDump")]];
u32 major_version[[name("MajorVersion")]];
u32 minor_version[[name("MinorVersion")]];
u64 dtb [[name("DirectoryBaseTable"),format("format_values")]];
u64 pfn [[name("PfnDataBase"), format("format_values")]];
u64 ploadedmodulelist [[name("PsLoadedModuleList"), format("format_values")]];
u64 pactiveprocesshead [[name("PsActiveProcessHead"), format("format_values")]];
u32 machine_type [[name("MachineImageType"), format("format_values")]];
u32 processor_counts [[name("ProcessorsCount")]];
u32 bug_check [[name("BugCheckCode"), format("format_values")]];
u32 bug_check_code_desc[[name("BugCheckCodeDescription"), format("format_values")]];
u64 bug_check_param1[[name("BugCheckCodeParameter1"), format("format_values")]];
u64 bug_check_param2[[name("BugCheckCodeParameter2"), format("format_values")]];
u64 bug_check_param3[[name("BugCheckCodeParameter3"), format("format_values")]];
u64 bug_check_param4[[name("BugCheckCodeParameter4"), format("format_values")]];
char version_user[0x20][[name("VersionUser")]];
u64 kdbg[[name("KdDebuggerDataBlock"), format("format_values")]];
PHYSICAL_MEMORY_DESCRIPTOR64 phys_mem_desc[[name("PHYSICAL_MEMORY_DESCRIPTOR64")]];
char mem_block_buffer[0x260][[name("PhysicalMemoryBlockBuffer")]];
char context_record[0xbb8][[name("ContextRecord")]];
EXCEPTION_RECORD64 excr[[name("EXCEPTION_RECORD64")]];
DUMP_TYPE dmp_type[[name("DumpType")]];
char desc1[4][[name("Description")]];
u64 req_dump_space[[name("RequiredDumpSpace"), format("format_values")]];
u64 sys_time[[name("SystemTime"), format("format_values")]];
char comment[COMMENT_SIZE][[name("Comment")]];
u64 sys_up_time[[name("SystemUpTime"), format("format_values")]];
u32 min_dmp_fields[[name("MiniDumpFields"), format("format_values")]];
u32 sec_data_state[[name("SecondaryDataState"), format("format_values")]];
u32 product_type[[name("ProductType"), format("format_values")]];
u32 suite_mask[[name("SuiteMask"), format("format_values")]];
u32 writer_status[[name("WriterStatus"), format("format_values")]];
char unused1[[name("Unused1")]];
char secondary_version[[name("KdSecondaryVersion")]];
char unused2[2][[name("Unused2")]];
DUMP_FILE_ATTRIBUTES dfa[[name("DUMP_FILE_ATTRIBUTES")]];
u32 boot_id[[name("BootId")]];
char reserved[0xfa8][[name("Reserved")]];
};
DUMP_HEADER64 dmp @ 0x00 [[name("DumpHeader")]];

73
patterns/dpapiblob.hexpat Normal file
View File

@@ -0,0 +1,73 @@
#pragma description "DPAPI Blob"
import type.guid;
import std.mem;
enum ALG_ID : u32 {
CALG_DH_EPHEM = 0x0000aa02,
CALG_DH_SF = 0x0000aa01,
CALG_DSS_SIGN = 0x00002200,
CALG_ECDH = 0x0000aa05,
CALG_ECDH_EPHEM = 0x0000ae06,
CALG_ECDSA = 0x00002203,
CALG_ECMQV = 0x0000a001,
CALG_HASH_REPLACE_OWF = 0x0000800b,
CALG_HUGHES_MD5 = 0x0000a003,
CALG_HMAC = 0x00008009,
CALG_KEA_KEYX = 0x0000aa04,
CALG_MAC = 0x00008005,
CALG_MD2 = 0x00008001,
CALG_MD4 = 0x00008002,
CALG_MD5 = 0x00008003,
CALG_NO_SIGN = 0x00002000,
CALG_OID_INFO_CNG_ONLY = 0xffffffff,
CALG_OID_INFO_PARAMETERS = 0xfffffffe,
CALG_PCT1_MASTER = 0x00004c04,
CALG_RC2 = 0x00006602,
CALG_RC4 = 0x00006801,
CALG_RC5 = 0x0000660d,
CALG_RSA_KEYX = 0x0000a400,
CALG_RSA_SIGN = 0x00002400,
CALG_SCHANNEL_ENC_KEY = 0x00004c07,
CALG_SCHANNEL_MAC_KEY = 0x00004c03,
CALG_SCHANNEL_MASTER_HASH = 0x00004c02,
CALG_SEAL = 0x00006802,
CALG_SHA = 0x00008004,
CALG_SHA1 = 0x00008004,
CALG_SHA_256 = 0x0000800c,
CALG_SHA_384 = 0x0000800d,
CALG_SHA_512 = 0x0000800e,
CALG_SKIPJACK = 0x0000660a,
CALG_SSL2_MASTER = 0x00004c05,
CALG_SSL3_MASTER = 0x00004c01,
CALG_SSL3_SHAMD5 = 0x00008008,
CALG_TEK = 0x0000660b,
CALG_TLS1_MASTER = 0x00004c06,
CALG_TLS1PRF = 0x0000800a
};
struct DPAPI_BLOB{
u32 version[[name("Version")]];
type::GUID providerguid[[name("ProviderGUID")]];
u32 masterguid[[name("MasterKeyVersion")]];
type::GUID guid[[name("MasterKeyGUID")]];
u32 flags[[name("Flags")]];
u32 desclen [[name("DescriptionLen")]];
char16 desc[desclen / 0x02 ] [[name("Description")]];
ALG_ID cryptid [[name("AlgCryptId")]];
u32 algcryptlen[[name("AlgCryptLen")]];
u32 saltlen [[name("SaltLen")]];
char salt[saltlen][[name("Salt")]];
u32 hmackeylen[[name("HMACKeyLen")]];
char hmackey[hmackeylen][[name("HMACKey")]];
ALG_ID algid[[name("AlgHashId")]];
u32 alghashkeylen[[name("AlgHashKeyLen")]];
u32 hmac2keylen[[name("HMAC2keylen")]];
char hmac2[hmac2keylen][[name("HMAC2Key")]];
u32 datalen[[name("DataLen")]];
char data[datalen][[name("Data")]];
u32 signlen[[name("signlen")]];
char signhash[signlen][[name("SignHash")]];
};
DPAPI_BLOB dpapiblob @0x00 [[name("DPAPIBlob")]];

View File

@@ -0,0 +1,124 @@
#pragma description "DPAPIMasterKey"
/*
FilePath: C:\Users\<USER>\AppData\Roaming\Microsoft\Protect\<SID>
This files are hidden.
To unhide it,
1. Open Command Prompt (cmd.exe).
2. Run the following command:
- attrib -h -s
*/
import type.guid;
// https://learn.microsoft.com/en-us/windows/win32/seccrypto/alg-id
enum ALG_ID : u32 {
CALG_DH_EPHEM = 0x0000aa02,
CALG_DH_SF = 0x0000aa01,
CALG_DSS_SIGN = 0x00002200,
CALG_ECDH = 0x0000aa05,
CALG_ECDH_EPHEM = 0x0000ae06,
CALG_ECDSA = 0x00002203,
CALG_ECMQV = 0x0000a001,
CALG_HASH_REPLACE_OWF = 0x0000800b,
CALG_HUGHES_MD5 = 0x0000a003,
CALG_HMAC = 0x00008009,
CALG_KEA_KEYX = 0x0000aa04,
CALG_MAC = 0x00008005,
CALG_MD2 = 0x00008001,
CALG_MD4 = 0x00008002,
CALG_MD5 = 0x00008003,
CALG_NO_SIGN = 0x00002000,
CALG_OID_INFO_CNG_ONLY = 0xffffffff,
CALG_OID_INFO_PARAMETERS = 0xfffffffe,
CALG_PCT1_MASTER = 0x00004c04,
CALG_RC2 = 0x00006602,
CALG_RC4 = 0x00006801,
CALG_RC5 = 0x0000660d,
CALG_RSA_KEYX = 0x0000a400,
CALG_RSA_SIGN = 0x00002400,
CALG_SCHANNEL_ENC_KEY = 0x00004c07,
CALG_SCHANNEL_MAC_KEY = 0x00004c03,
CALG_SCHANNEL_MASTER_HASH = 0x00004c02,
CALG_SEAL = 0x00006802,
CALG_SHA = 0x00008004,
CALG_SHA1 = 0x00008004,
CALG_SHA_256 = 0x0000800c,
CALG_SHA_384 = 0x0000800d,
CALG_SHA_512 = 0x0000800e,
CALG_SKIPJACK = 0x0000660a,
CALG_SSL2_MASTER = 0x00004c05,
CALG_SSL3_MASTER = 0x00004c01,
CALG_SSL3_SHAMD5 = 0x00008008,
CALG_TEK = 0x0000660b,
CALG_TLS1_MASTER = 0x00004c06,
CALG_TLS1PRF = 0x0000800a
};
struct CREDHIST_MASTERKEY {
u32 version[[name("Version")]];
type::GUID guid[[name("GUID")]];
};
struct DOMAINKEY_MASTERKEY {
u32 version[[name("Version")]];
u32 seclen[[name("SecretLen")]];
u32 accesschklen[[name("AccessCheckLen")]];
type::GUID backupguid_[[name("BackupKeyGUID")]];
char blob[seclen][[name("Secret")]];
char accesschk[accesschklen][[name("AccessCheck")]];
};
struct BACKUP_MASTERKEY {
u32 start = $;
u32 version[[name("Version")]];
char salt[16][[name("Salt")]];
u32 rounds [[name("PBKDF2IterationCount")]];
ALG_ID alghashid[[name("HMACAlgId")]];
ALG_ID algcryptid[[name("CryptAlgId")]];
u32 meta = $ - start;
char key[parent.backupkeylen - meta][[name("Key")]];
};
struct PASSWORD_MASTERKEY {
u32 start = $;
u32 version[[name("Version")]];
char salt[16][[name("Salt")]];
u32 rounds [[name("PBKDF2IterationCount")]];
ALG_ID alghashid[[name("HMACAlgId")]];
ALG_ID algcryptid[[name("CryptAlgId")]];
u32 meta = $ - start;
char key[parent.masterkeylen - meta][[name("Key")]];
};
struct DPAPIMasterKey {
u32 version[[name("Version")]];
u32 unk1[[name("Unknown1")]];
u32 unk2[[name("Unknown2")]];
char16 guid[0x24][[name("GUID"), comment("This GUID is the fileName itself")]];
u32 unk3[[name("Unknown3")]];
u32 unk4[[name("Unknown4")]];
u32 policy[[name("Policy")]];
u64 masterkeylen [[name("MasterKeyLen")]];
u64 backupkeylen [[name("BackupKeyLen")]];
u64 credhistlen [[name("CredHistoryLen")]];
u64 domainkeylen [[name("DomainKeyLen")]];
if (masterkeylen > 0){
PASSWORD_MASTERKEY masterkey[[name("MasterKey")]];
}
if (backupkeylen > 0){
BACKUP_MASTERKEY backupkey[[name("BackupKey")]];
}
if (credhistlen > 0){
CREDHIST_MASTERKEY credhistkey[[name("CredHistoryKey")]];
}
if (domainkeylen > 0){
DOMAINKEY_MASTERKEY domainkey[[name("DomainKey")]];
}
};
DPAPIMasterKey masterkey @0x00[[name("DPAPIMasterKey")]];

View File

@@ -1,4 +1,5 @@
#pragma description .DS_Store file format
#pragma description macOS .DS_Store
#pragma magic [ 42 75 64 31 ] @ 0x04
// Apple macOS .DS_Store format
#pragma endian big
@@ -7,11 +8,11 @@ import std.io;
struct RecordEntry {
u32 length;
char16 filename[length];
char id[4];
// either blob or length
char type[4];
if (type == "blob") {
u32 blobCount;
u8 blobData[blobCount];
@@ -67,15 +68,15 @@ struct BuddyBlock {
u8 reserved[4];
// padding for next multiple of 256 entries (1024 bytes)
u32 addresses[blockCount];
// u8 padding[paddingCount];
u32 directoryCount;
// directory entries
u8 count;
u8 name[count];
u32 blockNumber;
// free lists
// 32 free lists
BuddyRootBlockOffsets off[32];
@@ -96,7 +97,7 @@ struct BuddyAllocator {
u32 offsetBookkeeping2;
u32 offsetData;
u8 reserved[12];
BuddyRootBlock root @ offsetBookkeeping + 4;
std::print("TOC {} address 0x{:08x}",
@@ -104,7 +105,7 @@ struct BuddyAllocator {
root.offsets.addresses[root.toc.toc[0].value] >> 0x5 << 0x5);
BlocksList blocks @ (root.offsets.addresses[root.toc.toc[0].value] >> 0x5 << 0x5) + 4;
std::print("Blocks start at address 0x{:08x}, size 0x{:04x}",
root.offsets.addresses[blocks.blockId] >> 0x5 << 0x5,
1 << (root.offsets.addresses[blocks.blockId] & 0x1f));

119
patterns/dted.hexpat Normal file
View File

@@ -0,0 +1,119 @@
#pragma description Digital Terrain Elevation Data
#pragma endian big
#pragma magic [ 4C 48 55 ] @ 0x00
import std.core;
import std.io;
import std.mem;
import std.string;
enum Magic:u24 {
UHL = 0x55484C,
DSI = 0x445349,
ACC = 0x414343,
};
struct UHL {
Magic magic;
char one;
char lon[8];
char lat[8];
char lon_data_interval[4];
char lat_data_interval[4];
char accuracy[4];
char security_code[3];
char uniq_ref[12];
char lon_lines[4];
char lat_points[4];
char multi_accuracy;
char reserved[24];
};
struct DSI {
Magic magic;
char classification;
char stuff1[29];
char stuff2[26];
char product_level[5];
char uniq_ref[15];
char reserved[8];
char data_edition[2];
char match_version;
char maint_date[4];
char match_date[4];
char main_desc_code[4];
char producer_code[8];
char reserved2[16];
char product_spec[9];
char numbers[2];
char product_spec_date[4];
char vertical_datum[3];
char horizontal_datum[5];
char digitizing_system[10];
char compilation_date[4];
char reserved3[22];
char lat_origin[9];
char lon_origin[10];
char lat_sw_corner[7];
char lon_sw_corner[8];
char lat_nw_corner[7];
char lon_nw_corner[8];
char lat_ne_corner[7];
char lon_ne_corner[8];
char lat_se_corner[7];
char lon_se_corner[8];
char clockwise_orientation[9];
char lat_interval[4];
char lon_interval[4];
char lat_lines[4];
char lon_lines[4];
char partial_cell[2];
char reserved4[101];
char reserved5[100];
char reserved6[156];
};
struct ACCSub {
char abs_vertical_accuracy[4];
char abs_horizontal_accuracy[4];
char rel_vertical_accuracy[4];
char rel_horizontal_accuracy[4];
char num_coords[2];
char pairs[19*14];
};
struct ACC {
Magic magic;
char abs_horizontal_accuracy[4];
char abs_vertical_accuracy[4];
char rel_horizontal_accuracy[4];
char rel_vertical_accuracy[4];
char reserved1[4];
char reserved2[1];
char reserved3[31];
char multi_accuracy_outline[2]; // determines sub regions
ACCSub subs[9];
char reserved4[18];
char reserved5[69];
};
struct DataRecords {
char magic;
s24 data_block_count;
s16 lon_count;
s16 lat_count;
s16 elevation[std::string::parse_int(parent.dsi.lat_lines, 10)];
u32 checksum;
};
struct DTED {
UHL uhl;
DSI dsi;
ACC acc;
DataRecords records[std::string::parse_int(this.dsi.lon_lines, 10)];
};
DTED dted @ 0x00;

View File

@@ -1,5 +1,5 @@
#pragma author WerWolv
#pragma description ELF header in elf binaries
#pragma description Executable and Linkable Format executable (ELF)
#pragma MIME application/x-executable
#pragma MIME application/x-elf
@@ -10,6 +10,7 @@
import std.core;
import std.io;
import std.mem;
import type.magic;
using BitfieldOrder = std::core::BitfieldOrder;
@@ -498,12 +499,12 @@ bitfield SHF {
bitfield ELF32_R_INFO {
SYM : 8;
TYPE : 8;
} [[left_to_right]];
} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 16)]];
bitfield ELF64_R_INFO {
SYM : 32;
TYPE : 32;
} [[left_to_right]];
} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 64)]];
bitfield PF {
X : 1;
@@ -515,7 +516,7 @@ bitfield PF {
};
struct E_IDENT {
char EI_MAG[4];
type::Magic<"\x7fELF"> EI_MAG;
EI_CLASS EI_CLASS;
EI_DATA EI_DATA;
EI_VERSION EI_VERSION;
@@ -565,7 +566,7 @@ struct Elf32_Phdr {
Elf32_Word p_memsz;
PF p_flags;
Elf32_Word 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 [[sealed]];
};
@@ -579,7 +580,7 @@ struct Elf64_Phdr {
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 [[sealed]];
};
@@ -636,13 +637,13 @@ struct Elf32_Shdr {
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();
stringTableIndex = std::core::array_index();
} else if (sh_type == SHT::SYMTAB || sh_type == SHT::DYNSYM) {
Elf32_Sym symbolTable[sh_size / sh_entsize] @ sh_offset;
} else if (sh_type == SHT::INIT_ARRAY || sh_type == SHT::FINI_ARRAY) {
@@ -651,7 +652,7 @@ struct Elf32_Shdr {
u8 data[sh_size] @ sh_offset [[sealed]];
}
}
} [[format("format_section_header")]];;
} [[format("format_section_header")]];
struct Elf64_Chdr {
u32 ch_type;
@@ -696,13 +697,13 @@ struct Elf64_Shdr {
Elf64_Word sh_info;
Elf64_Xword sh_addralign;
Elf64_Xword 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();
stringTableIndex = std::core::array_index();
} else if (sh_type == SHT::SYMTAB || sh_type == SHT::DYNSYM) {
Elf64_Sym symbolTable[sh_size / sh_entsize] @ sh_offset;
} else if (sh_type == SHT::INIT_ARRAY || sh_type == SHT::FINI_ARRAY) {
@@ -715,7 +716,7 @@ struct Elf64_Shdr {
fn format_section_header(auto shdr) {
u32 i = 0;
u32 nameAddress = addressof(elf.shdr[stringTableIndex].stringTable) + shdr.sh_name;
String string @ nameAddress;
@@ -725,12 +726,12 @@ fn format_section_header(auto shdr) {
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;

View File

@@ -1,5 +1,5 @@
#pragma description MS Windows Vista Event Log
#pragma MIME application/x-ms-evtx
#pragma endian little
struct Header {

543
patterns/ext4.hexpat Normal file
View File

@@ -0,0 +1,543 @@
#pragma author endes
#pragma description ext4 volume layout parser (until inodes)
// Decodes the ext4 superblock, group descriptors and inodes.
// Does not decode the directory entries, inode data, jornal or superblock backups.
// Heavily based on the linux kernel documentation:
// https://www.kernel.org/doc/html/latest/filesystems/ext4/
#pragma endian little
#pragma magic [53 EF] @ 0x438
#pragma pattern_limit 0x90000
import type.time;
import type.size;
import type.magic;
import std.core;
import std.mem;
import std.math;
enum ext4_super_state : u16 {
Cleanlyumounted = 0x01,
Errorsdetected = 0x02,
Orphansbeingrecovered = 0x03
};
enum ext4_super_errors : u16 {
Continue = 0x01,
RemountReadOnly = 0x02,
Panic = 0x03
};
enum ext4_super_creator : u32 {
Linux = 0x00,
Hurd = 0x01,
Masix = 0x02,
FreeBSD = 0x03,
Lites = 0x04
};
enum ext4_super_revision : u32 {
ORIGINAL = 0x00,
V2_DYNAMIC_REV = 0x01
};
bitfield ext4_super_compat {
COMPAT_DIR_PREALLOC : 1 [[comment("Directory preallocation.")]];
COMPAT_IMAGIC_INODES : 1 [[comment("“imagic inodes”. Not clear from the code what this does.")]];
COMPAT_HAS_JOURNAL : 1 [[comment("Has a journal.")]];
COMPAT_EXT_ATTR : 1 [[comment("Supports extended attributes.")]];
COMPAT_RESIZE_INODE : 1 [[comment("Has reserved GDT blocks for filesystem expansion.")]];
COMPAT_DIR_INDEX : 1 [[comment("Has directory indices.")]];
COMPAT_LAZY_BG : 1 [[comment("“Lazy BG”. Not in Linux kernel, seems to have been for uninitialized block groups?.")]];
COMPAT_EXCLUDE_INODE : 1 [[comment("“Exclude inode”. Not used.")]];
COMPAT_EXCLUDE_BITMAP : 1 [[comment("“Exclude bitmap”. Seems to be used to indicate the presence of snapshot-related exclude bitmaps? Not defined in linux kernel or used in e2fsprogs.")]];
COMPAT_SPARSE_SUPER2 : 1 [[comment("Sparse Super Block, v2. If this flag is set, the SB field s_backup_bgs points to the two block groups that contain backup superblocks.")]];
COMPAT_FAST_COMMIT : 1 [[comment("Journal fast commits supported.")]];
padding : 1;
RO_COMPAT_ORPHAN_PRESENT : 1 [[comment("Orphan file allocated. This is the special file for more efficient tracking of unlinked but still open inodes.")]];
};
bitfield ext4_super_incompat {
INCOMPAT_COMPRESSION : 1;
INCOMPAT_FILETYPE : 1 [[comment("Directory entries record the file type.")]];
INCOMPAT_RECOVER : 1 [[comment("Filesystem needs recovery.")]];
INCOMPAT_JOURNAL_DEV : 1 [[comment("Filesystem has a separate journal device.")]];
INCOMPAT_META_BG : 1 [[comment("Meta block groups.")]];
padding : 1;
INCOMPAT_EXTENTS : 1 [[comment("Files in this filesystem use extents.")]];
INCOMPAT_64BIT : 1 [[comment("Enable a filesystem size of 2^64 blocks.")]];
INCOMPAT_MMP : 1 [[comment("Multiple mount protection.")]];
INCOMPAT_FLEX_BG : 1 [[comment("Flexible block groups.")]];
INCOMPAT_EA_INODE : 1 [[comment("Inodes can be used to store large extended attribute values.")]];
padding : 1 [[comment("Data in directory entry.")]];
INCOMPAT_DIRDATA : 1;
INCOMPAT_CSUM_SEED : 1 [[comment("Metadata checksum seed is stored in the superblock.")]];
INCOMPAT_LARGEDIR : 1 [[comment("Large directory >2GB or 3-level htree.")]];
INCOMPAT_INLINE_DATA : 1 [[comment("Data in inode.")]];
INCOMPAT_ENCRYPT : 1 [[comment("Encrypted inodes are present on the filesystem.")]];
};
bitfield ext4_super_compat_ro {
RO_COMPAT_SPARSE_SUPER : 1 [[comment("Sparse superblocks.")]];
RO_COMPAT_LARGE_FILE : 1 [[comment("This filesystem has been used to store a file greater than 2GiB.")]];
RO_COMPAT_BTREE_DIR : 1 [[comment("Not used in linux kernel or e2fsprogs.")]];
RO_COMPAT_HUGE_FILE : 1 [[comment("This filesystem has files whose sizes are represented in units of logical blocks, not 512-byte sectors. This implies a very large file indeed!.")]];
RO_COMPAT_GDT_CSUM : 1 [[comment("Group descriptors have checksums.")]];
RO_COMPAT_DIR_NLINK : 1 [[comment("Indicates that the old ext3 32,000 subdirectory limit no longer applies.")]];
RO_COMPAT_EXTRA_ISIZE : 1 [[comment("Indicates that large inodes exist on this filesystem.")]];
RO_COMPAT_HAS_SNAPSHOT : 1 [[comment("This filesystem has a snapshot.")]];
RO_COMPAT_QUOTA : 1;
RO_COMPAT_BIGALLOC : 1 [[comment("This filesystem supports “bigalloc”, which means that file extents are tracked in units of clusters (of blocks) instead of blocks.")]];
RO_COMPAT_METADATA_CSUM : 1 [[comment("This filesystem supports metadata checksumming.")]];
RO_COMPAT_REPLICA : 1 [[comment("Filesystem supports replicas. This feature is neither in the kernel nor e2fsprogs.")]];
RO_COMPAT_READONLY : 1 [[comment("Read-only filesystem image.")]];
RO_COMPAT_PROJECT : 1 [[comment("Filesystem tracks project quotas.")]];
padding : 1;
RO_COMPAT_VERITY : 1 [[comment("Verity inodes may be present on the filesystem.")]];
RO_COMPAT_ORPHAN_PRESENT : 1 [[comment("Indicates orphan file may have valid orphan entries and thus we need to clean them up when mounting the filesystem.")]];
};
enum ext4_super_def_hash : u8 {
LEGACY = 0x00,
HALF_MD4 = 0x01,
TEA = 0x02,
LEGACY_UNSIGNED = 0x03,
HALF_MD4_UNSIGNED = 0x04,
TEA_UNSIGNED = 0x05
};
bitfield ext4_super_mountopts {
EXT4_DEFM_DEBUG : 1 [[comment("Print debugging info upon (re)mount.")]];
EXT4_DEFM_BSDGROUPS : 1 [[comment("New files take the gid of the containing directory (instead of the fsgid of the current process).")]];
EXT4_DEFM_XATTR_USER : 1 [[comment("Support userspace-provided extended attributes.")]];
EXT4_DEFM_ACL : 1 [[comment("Support POSIX access control lists (ACLs).")]];
EXT4_DEFM_UID16 : 1 [[comment("Do not support 32-bit UIDs.")]];
EXT4_DEFM_JMODE_DATA : 1 [[comment("All data and metadata are committed to the journal.")]];
EXT4_DEFM_JMODE_ORDER : 1 [[comment("All data are flushed to the disk before metadata are committed to the journal.")]];
padding : 1;
EXT4_DEFM_NOBARRIER : 1 [[comment("Disable write flushes.")]];
EXT4_DEFM_BLOCK_VALIDITY : 1 [[comment("Track which blocks in a filesystem are metadata and therefore should not be used as data blocks.")]];
EXT4_DEFM_DISCARD : 1 [[comment("Enable DISCARD support, where the storage device is told about blocks becoming unused.")]];
EXT4_DEFM_NODELALLOC : 1 [[comment("Disable delayed allocation.")]];
};
bitfield ext4_super_flags {
SIGNED_HASH_DIRECTORY : 1;
UNSIGNED_HASH_DIRECTORY : 1;
TEST_DEV_CODE : 1;
};
enum ext4_super_encrypt_algos : u8 {
ENCRYPTION_MODE_INVALID = 0x00,
ENCRYPTION_MODE_AES_256_XTS = 0x01,
ENCRYPTION_MODE_AES_256_GCM = 0x02,
ENCRYPTION_MODE_AES_256_CBC = 0x03,
};
struct ext4_super_block {
u32 s_inodes_count [[comment("Total inode count.")]];
u32 s_blocks_count_lo [[comment("Total block count.")]];
u32 s_r_blocks_count_lo [[comment("This number of blocks can only be allocated by the super-user.")]];
u32 s_free_blocks_count_lo [[comment("Free block count.")]];
u32 s_free_inodes_count [[comment("Free inode count.")]];
u32 s_first_data_block [[comment("First data block. This must be at least 1 for 1k-block filesystems and is typically 0 for all other block sizes.")]];
u32 s_log_block_size;
u32 s_log_cluster_size;
u64 block_size = std::math::pow(2, 10+s_log_block_size);
u64 cluster_size = std::math::pow(2, 10+s_log_cluster_size);
u32 s_blocks_per_group [[comment("Blocks per group.")]];
u32 s_clusters_per_group [[comment("Clusters per group, if bigalloc is enabled. Otherwise s_clusters_per_group must equal s_blocks_per_group.")]];
u32 s_inodes_per_group [[comment("Inodes per group.")]];
type::time32_t s_mtime [[comment("Last mount time, in seconds since the epoch.")]];
type::time32_t s_wtime [[comment("Last write time, in seconds since the epoch.")]];
u16 s_mnt_count [[comment("Number of mounts since the last fsck.")]];
u16 s_max_mnt_count [[comment("Number of mounts beyond which a fsck is needed.")]];
type::Magic<"\x53\xEF"> s_magic;
ext4_super_state s_state [[comment("File system state.")]];
ext4_super_errors s_errors [[comment("Behaviour when detecting errors.")]];
u16 s_minor_rev_level [[comment("Minor revision level.")]];
type::time32_t s_lastcheck [[comment("Time of last check, in seconds since the epoch.")]];
u32 s_checkinterval [[comment("Maximum time between checks, in seconds.")]];
ext4_super_creator s_creator_os [[comment("Creator OS.")]];
ext4_super_revision s_rev_level [[comment("Revision level.")]];
u16 s_def_resuid [[comment("Default uid for reserved blocks.")]];
u16 s_def_resgid [[comment("Default gid for reserved blocks.")]];
// EXT2_DYNAMIC_REV superblock
if (s_rev_level >= ext4_super_revision::V2_DYNAMIC_REV) {
u32 s_first_ino [[comment("First non-reserved inode.")]];
u16 s_inode_size [[comment("Size of inode structure, in bytes.")]];
u16 s_block_group_nr [[comment("Block group number of this superblock.")]];
ext4_super_compat s_feature_compat [[comment("Compatible feature set flags. Kernel can still read/write this fs even if it doesnt understand a flag; fsck should not do that.")]];
padding[2];
ext4_super_incompat s_feature_incompat [[comment("Incompatible feature set. If the kernel or fsck doesnt understand one of these bits, it should stop.")]];
padding[1];
ext4_super_compat_ro s_feature_ro_compat [[comment("Readonly-compatible feature set. If the kernel doesnt understand one of these bits, it can still mount read-only.")]];
padding[1];
u8 s_uuid[16] [[comment("128-bit UUID for volume.")]];
char s_volume_name[16] [[comment("Volume label.")]];
char s_last_mounted[64] [[comment("Directory where filesystem was last mounted.")]];
if (s_feature_incompat.INCOMPAT_COMPRESSION) {
u32 s_algorithm_usage_bitmap;
} else {
padding[4];
}
// Performance hints
if (s_feature_compat.COMPAT_DIR_PREALLOC) {
u8 s_prealloc_blocks [[comment("Number of blocks to try to preallocate for ... files? (Not used in e2fsprogs/Linux).")]];
u8 s_prealloc_dir_blocks [[comment("Number of blocks to preallocate for directories. (Not used in e2fsprogs/Linux).")]];
} else {
padding[2];
}
u16 s_reserved_gdt_blocks [[comment("Number of reserved GDT entries for future filesystem expansion.")]];
// Journaling support
if (s_feature_compat.COMPAT_HAS_JOURNAL) {
u8 s_journal_uuid[16] [[comment("UUID of journal superblock.")]];
u32 s_journal_inum [[comment("Inode number of journal file.")]];
if (s_feature_incompat.INCOMPAT_JOURNAL_DEV) {
u32 s_journal_dev [[comment("Device number of journal file.")]];
} else {
padding[4];
}
} else {
padding[24];
}
u32 s_last_orphan [[comment("Inode start of list of orphaned inodes to delete.")]];
u32 s_hash_seed[4] [[comment("HTREE hash seed.")]];
ext4_super_def_hash s_def_hash_version [[comment("Default hash algorithm to use for directory hashes.")]];
u8 s_jnl_backup_type [[comment("If this value is 0 or EXT3_JNL_BACKUP_BLOCKS (1), then the s_jnl_blocks field contains a duplicate copy of the inodes i_block[] array and i_size.")]];
if (s_feature_incompat.INCOMPAT_64BIT) {
u16 s_desc_size [[comment("Size of group descriptors, in bytes, if the 64bit incompat feature flag is set.")]];
} else {
padding[2];
}
ext4_super_mountopts s_default_mount_opts [[comment("Default mount options.")]];
padding[2];
if (s_feature_incompat.INCOMPAT_META_BG) {
u32 s_first_meta_bg [[comment("First metablock block group, if the meta_bg feature is enabled.")]];
} else {
padding[4];
}
type::time32_t s_mkfs_time [[comment("When the filesystem was created, in seconds since the epoch.")]];
u32 s_jnl_blocks[17] [[comment("Backup copy of the journal inodes i_block[] array in the first 15 elements and i_size_high and i_size in the 16th and 17th elements, respectively.")]];
if (s_feature_incompat.INCOMPAT_64BIT) {
u32 s_blocks_count_hi [[comment("High 32-bits of the block count.")]];
u32 s_r_blocks_count_hi [[comment("High 32-bits of the reserved block count.")]];
u32 s_free_blocks_count_hi [[comment("High 32-bits of the free block count.")]];
u64 s_blocks_count = (u64(s_blocks_count_hi) << 32) + s_blocks_count_lo;
u64 s_r_blocks_count = (u64(s_r_blocks_count_hi) << 32) + s_r_blocks_count_lo;
u64 s_free_blocks_count = (u64(s_free_blocks_count_hi) << 32) + s_free_blocks_count_lo;
u64 groups_count = std::math::ceil(s_blocks_count/float(s_blocks_per_group));
} else {
padding[12];
u64 s_blocks_count = s_blocks_count_lo;
u64 s_r_blocks_count = s_r_blocks_count_lo;
u64 s_free_blocks_count = s_free_blocks_count_lo;
u64 groups_count = std::math::ceil(s_blocks_count/float(s_blocks_per_group));
}
if (s_feature_ro_compat.RO_COMPAT_EXTRA_ISIZE) {
u16 s_min_extra_isize [[comment("All inodes have at least # bytes.")]];
u16 s_want_extra_isize [[comment("New inodes should reserve # bytes.")]];
} else {
padding[4];
}
ext4_super_flags s_flags [[comment("Miscellaneous flags.")]];
padding[3];
u16 s_raid_stride [[comment("RAID stride. This is the number of logical blocks read from or written to the disk before moving to the next disk. This affects the placement of filesystem metadata.")]];
if (s_feature_incompat.INCOMPAT_MMP) {
u16 s_mmp_interval [[comment("Number of seconds to wait in multi-mount prevention (MMP) checking.")]];
u64 s_mmp_block [[comment("Block number for multi-mount protection data.")]];
} else {
padding[10];
}
u32 s_raid_stripe_width [[comment("RAID stripe width. This is the number of logical blocks read from or written to the disk before coming back to the current disk.")]];
if (s_feature_incompat.INCOMPAT_FLEX_BG) {
u8 s_log_groups_per_flex;
u64 groups_per_flex = std::math::pow(2, s_log_groups_per_flex);
} else {
padding[1];
}
if (s_feature_ro_compat.RO_COMPAT_METADATA_CSUM) {
u8 s_checksum_type [[comment("Metadata checksum algorithm type.")]];
} else {
padding[1];
}
padding[2];
u64 s_kbytes_written [[comment("Number of KiB written to this filesystem over its lifetime.")]];
if (s_feature_ro_compat.RO_COMPAT_HAS_SNAPSHOT) {
u32 s_snapshot_inum [[comment("inode number of active snapshot. (Not used in e2fsprogs/Linux.)")]];
u32 s_snapshot_id [[comment("Sequential ID of active snapshot. (Not used in e2fsprogs/Linux.)")]];
u64 s_snapshot_r_blocks_count [[comment("Number of blocks reserved for active snapshots future use. (Not used in e2fsprogs/Linux.)")]];
u32 s_snapshot_list [[comment("inode number of the head of the on-disk snapshot list. (Not used in e2fsprogs/Linux.)")]];
} else {
padding[20];
}
u32 s_error_count [[comment("Number of errors seen.")]];
if (s_error_count > 0) {
type::time32_t s_first_error_time [[comment("First time an error happened.")]];
u32 s_first_error_ino [[comment("inode involved in first error.")]];
u64 s_first_error_block [[comment("Number of block involved of first error.")]];
char s_first_error_func[32] [[comment("Name of function where the error happened.")]];
u32 s_first_error_line [[comment("Line number where error happened.")]];
type::time32_t s_last_error_time [[comment("Last time an error happened.")]];
u32 s_last_error_ino [[comment("inode involved in most recent error.")]];
u32 s_last_error_line [[comment("Line number where most recent error happened.")]];
u64 s_last_error_block [[comment("Number of block involved in most recent error.")]];
char s_last_error_func[32] [[comment("Name of function where the most recent error happened.")]];
} else {
padding[104];
}
char s_mount_opts[64] [[comment("ASCIIZ string of mount options.")]];
if (s_feature_ro_compat.RO_COMPAT_QUOTA) {
u32 s_usr_quota_inum [[comment("Inode number of user quota file.")]];
u32 s_grp_quota_inum [[comment("Inode number of group quota file.")]];
} else {
padding[8];
}
u32 s_overhead_blocks [[comment("Overhead blocks/clusters in fs. (Huh? This field is always zero, which means that the linux kernel calculates it dynamically.)")]];
if (s_feature_compat.COMPAT_SPARSE_SUPER2) {
u32 s_backup_bgs[2] [[comment("Block groups containing superblock backups.")]];
} else {
padding[8];
}
if (s_feature_incompat.INCOMPAT_ENCRYPT) {
ext4_super_encrypt_algos s_encrypt_algos[4] [[comment("Encryption algorithms in use. There can be up to four algorithms in use at any time.")]];
u8 s_encrypt_pw_salt[16] [[comment("Salt for the string2key algorithm for encryption.")]];
} else {
padding[20];
}
u32 s_lpf_ino [[comment("Inode number of lost+found.")]];
if (s_feature_ro_compat.RO_COMPAT_PROJECT) {
u32 s_prj_quota_inum [[comment("Inode that tracks project quotas.")]];
} else {
padding[4];
}
if (s_feature_ro_compat.RO_COMPAT_METADATA_CSUM) {
u32 s_checksum_seed [[comment("Checksum seed used for metadata_csum calculations. This value is crc32c(~0, $orig_fs_uuid).")]];
} else {
padding[4];
}
u8 s_wtime_hi [[comment("Upper 8 bits of the s_wtime field.")]];
u8 s_mtime_hi [[comment("Upper 8 bits of the s_mtime field.")]];
u8 s_mkfs_time_hi [[comment("Upper 8 bits of the s_mkfs_time field.")]];
u8 s_lastcheck_hi [[comment("Upper 8 bits of the s_lastcheck field.")]];
u8 s_first_error_time_hi [[comment("Upper 8 bits of the s_first_error_time field.")]];
u8 s_last_error_time_hi [[comment("Upper 8 bits of the s_last_error_time field.")]];
padding[2];
u16 s_encoding [[comment("Filename charset encoding.")]];
u16 s_encoding_flags [[comment("Filename charset encoding flags.")]];
if (s_feature_compat.RO_COMPAT_ORPHAN_PRESENT) {
u32 s_orphan_file_inum [[comment("Orphan file inode number.")]];
} else {
padding[4];
}
padding[376];
if (s_feature_ro_compat.RO_COMPAT_METADATA_CSUM) {
u32 s_checksum [[comment("Superblock checksum.")]];
} else {
padding[4];
}
}
};
ext4_super_block super_block @ 0x400;
fn block_to_address(u32 block) {
return super_block.block_size * block;
};
fn block_pointer_to_address(u32 block) {
return block_to_address(block) - block;
};
struct ext4_bitmap {
u8 data[super_block.block_size];
};
bitfield ext4_i_mode {
S_IXOTH : 1 [[comment("Others may execute.")]];
S_IWOTH : 1 [[comment("Others may write.")]];
S_IROTH : 1 [[comment("Others may read.")]];
S_IXGRP : 1 [[comment("Group members may execute.")]];
S_IWGRP : 1 [[comment("Group members may write.")]];
S_IRGRP : 1 [[comment("Group members may read.")]];
S_IXUSR : 1 [[comment("Owner may execute.")]];
S_IWUSR : 1 [[comment("Owner may write.")]];
S_IRUSR : 1 [[comment("Owner may read.")]];
S_ISVTX : 1 [[comment("Sticky bit.")]];
S_ISGID : 1 [[comment("Set GID.")]];
S_ISUID : 1 [[comment("Set UID.")]];
S_IFIFO : 1 [[comment("FIFO.")]];
S_IFCHR : 1 [[comment("Character device.")]];
S_IFDIR : 1 [[comment("Directory.")]];
S_IFREG : 1 [[comment("Regular file.")]];
};
bitfield ext4_i_flags {
EXT4_SECRM_FL : 1 [[comment("This file requires secure deletion.")]];
EXT4_UNRM_FL : 1 [[comment("This file should be preserved, should undeletion be desired.")]];
EXT4_COMPR_FL : 1 [[comment("File is compressed.")]];
EXT4_SYNC_FL : 1 [[comment("All writes to the file must be synchronous.")]];
EXT4_IMMUTABLE_FL : 1 [[comment("File is immutable.")]];
EXT4_APPEND_FL : 1 [[comment("File can only be appended.")]];
EXT4_NODUMP_FL : 1 [[comment("The dump utility should not dump this file.")]];
EXT4_NOATIME_FL : 1 [[comment("Do not update access time.")]];
EXT4_DIRTY_FL : 1 [[comment("Dirty compressed file.")]];
EXT4_COMPRBLK_FL : 1 [[comment("File has one or more compressed clusters.")]];
EXT4_NOCOMPR_FL : 1 [[comment("Do not compress file.")]];
EXT4_ENCRYPT_FL : 1 [[comment("Encrypted inode.")]];
EXT4_INDEX_FL : 1 [[comment("Directory has hashed indexes.")]];
EXT4_IMAGIC_FL : 1 [[comment("AFS magic directory.")]];
EXT4_JOURNAL_DATA_FL : 1 [[comment("File data must always be written through the journal.")]];
EXT4_NOTAIL_FL : 1 [[comment("File tail should not be merged.")]];
EXT4_DIRSYNC_FL : 1 [[comment("All directory entry data should be written synchronously.")]];
EXT4_TOPDIR_FL : 1 [[comment("Top of directory hierarchy.")]];
EXT4_HUGE_FILE_FL : 1 [[comment("This is a huge file.")]];
EXT4_EXTENTS_FL : 1 [[comment("Inode uses extents.")]];
EXT4_VERITY_FL : 1 [[comment("Verity protected file.")]];
EXT4_EA_INODE_FL : 1 [[comment("Inode stores a large extended attribute value in its data blocks.")]];
EXT4_EOFBLOCKS_FL : 1 [[comment("This file has blocks allocated past EOF.")]];
padding : 1;
EXT4_SNAPFILE_FL : 1 [[comment("Inode is a snapshot.")]];
padding : 1;
EXT4_SNAPFILE_DELETED_FL : 1 [[comment("Snapshot is being deleted.")]];
EXT4_SNAPFILE_SHRUNK_FL : 1 [[comment("Snapshot shrink has completed.")]];
EXT4_INLINE_DATA_FL : 1 [[comment("Inode has inline data.")]];
EXT4_PROJINHERIT_FL : 1 [[comment("Create children with the same project ID.")]];
padding : 1;
EXT4_RESERVED_FL : 1 [[comment("Reserved for ext4 library.")]];
};
struct ext4_inode {
ext4_i_mode i_mode [[comment("File mode.")]];
u16 i_uid [[comment("Lower 16-bits of Owner UID.")]];
u32 i_size [[comment("Lower 32-bits of size in bytes.")]];
type::time32_t i_atime [[comment("Last access time.")]];
type::time32_t i_ctime [[comment("Last inode change time.")]];
type::time32_t i_mtime [[comment("Last data modification time.")]];
type::time32_t i_dtime [[comment("Deletion Time.")]];
u16 i_gid [[comment("Lower 16-bits of GID.")]];
u16 i_links_count [[comment("Hard link count.")]];
u32 i_blocks_lo [[comment("Lower 32-bits of “block” count.")]];
ext4_i_flags i_flags [[comment("Inode flags.")]];
u32 i_osd1 [[comment("Depends of the OS.")]];
u32 i_block[15] [[comment("Block map or extent tree.")]];
u32 i_generation [[comment("File version (for NFS).")]];
u32 i_file_acl [[comment("Lower 32-bits of extended attribute block.")]];
u32 i_dir_acl [[comment("Upper 32-bits of file/directory size.")]];
u32 i_faddr [[comment("Fragment address.")]];
u8 i_osd2[12] [[comment("Depends of the OS.")]];
if (super_block.s_rev_level >= ext4_super_revision::V2_DYNAMIC_REV && super_block.s_inode_size > 0x80) {
u16 i_extra_isize [[comment("Size of this inode - 128.")]];
u16 i_checksum_hi [[comment("Upper 16-bits of the inode checksum.")]];
if (super_block.s_inode_size > 0x84) {
u32 i_ctime_extra [[comment("Extra change time bits.")]];
u32 i_mtime_extra [[comment("Extra modification time bits.")]];
u32 i_atime_extra [[comment("Extra access time bits.")]];
u32 i_crtime [[comment("File creation time.")]];
u32 i_crtime_extra [[comment("Extra file creation time bits.")]];
if (super_block.s_inode_size > 0x98) {
u32 i_version_hi [[comment("Upper 32-bits for version number.")]];
if (super_block.s_inode_size > 0x9C) {
u32 i_projid [[comment("Project ID.")]];
if (super_block.s_inode_size > 0xA0) {
padding[super_block.s_inode_size - 0xA0];
}
}
}
}
}
};
bitfield ext4_bg_flags {
EXT4_BG_INODE_UNINIT : 1 [[comment("Inode table and bitmap are not initialized.")]];
EXT4_BG_BLOCK_UNINIT : 1 [[comment("Block bitmap is not initialized.")]];
EXT4_BG_INODE_ZEROED : 1 [[comment("Inode table is zeroed.")]];
};
struct ext4_group_desc {
ext4_bitmap *bg_block_bitmap : u32 [[pointer_base("block_pointer_to_address"), comment("Lower 32-bits of location of block bitmap.")]];
ext4_bitmap *bg_inode_bitmap : u32 [[pointer_base("block_pointer_to_address"), comment("Lower 32-bits of location of inode bitmap.")]];
ext4_inode *bg_inode_table[super_block.s_inodes_per_group] : u32 [[pointer_base("block_pointer_to_address"), comment("Lower 32-bits of location of inode table.")]];
u16 bg_free_blocks_count [[comment("Lower 16-bits of free block count.")]];
u16 bg_free_inodes_count [[comment("Lower 16-bits of free inode count.")]];
u16 bg_used_dirs_count [[comment("Lower 16-bits of directory count.")]];
ext4_bg_flags bg_flags [[comment("Block group flags.")]];
padding[1];
u32 bg_exclude_bitmap_lo [[comment("Lower 32-bits of location of snapshot exclusion bitmap.")]];
u16 bg_block_bitmap_csum_lo [[comment("Lower 16-bits of the block bitmap checksum.")]];
u16 bg_inode_bitmap_csum_lo [[comment("Lower 16-bits of the inode bitmap checksum.")]];
u16 bg_itable_unused_lo [[comment("Lower 16-bits of unused inode count.")]];
u16 bg_checksum [[comment("Group descriptor checksum.")]];
};
struct ext4_group_desc_64_bit : ext4_group_desc {
u32 bg_block_bitmap_hi [[comment("Upper 32-bits of location of block bitmap.")]];
u32 bg_inode_bitmap_hi [[comment("Upper 32-bits of location of inodes bitmap.")]];
u32 bg_inode_table_hi [[comment("Upper 32-bits of location of inodes table.")]];
u16 bg_free_blocks_count_hi [[comment("Upper 16-bits of free block count.")]];
u16 bg_free_inodes_count_hi [[comment("Upper 16-bits of free inode count.")]];
u16 bg_used_dirs_count_hi [[comment("Upper 16-bits of directory count.")]];
u16 bg_itable_unused_hi [[comment("Upper 16-bits of unused inode count.")]];
u32 bg_exclude_bitmap_hi [[comment("Upper 32-bits of location of snapshot exclusion bitmap.")]];
u16 bg_block_bitmap_csum_hi [[comment("Upper 16-bits of the block bitmap checksum.")]];
u16 bg_inode_bitmap_csum_hi [[comment("Upper 16-bits of the inode bitmap checksum.")]];
padding[4];
};
struct ext4_group_descriptors {
if (super_block.s_rev_level >= ext4_super_revision::V2_DYNAMIC_REV && super_block.s_feature_incompat.INCOMPAT_64BIT) {
ext4_group_desc_64_bit group_desc[super_block.groups_count];
} else {
ext4_group_desc group_desc[super_block.groups_count];
}
};
ext4_group_descriptors group_descs @ block_to_address(2);

193
patterns/fbx.hexpat Normal file
View File

@@ -0,0 +1,193 @@
#pragma description Kaydara FBX Binary
#pragma magic [4B 61 79 64 61 72 61 20 46 42 58 20 42 69 6E 61 72 79 20 20 00 1A 00] @ 0x00
/*
* Based on Blenders implementation of FBX import/export, see:
* (incomplete) https://code.blender.org/2013/08/fbx-binary-file-format-specification/
* https://projects.blender.org/blender/blender/src/branch/main/scripts/addons_core/io_scene_fbx/parse_fbx.py
* https://projects.blender.org/blender/blender/src/branch/main/scripts/addons_core/io_scene_fbx/encode_bin.py
*/
#pragma endian little
#ifdef __IMHEX__
import hex.dec;
#endif
import std.mem;
import std.string;
import std.sys;
import type.magic;
struct Array<E> {
u32 arrayLength;
u32 encoding;
u32 compressedLength;
std::assert(encoding < 2, "Invalid array encoding!");
if (encoding == 0) {
// Uncompressed
E contents[arrayLength];
} else {
// Compressed (zlib)
u128 pos = $;
u8 compressedContents[compressedLength];
#ifdef __IMHEX__
std::mem::Section contentsSection = std::mem::create_section(std::format("contentsSection @ {:#x}", pos));
hex::dec::zlib_decompress(compressedContents, contentsSection, 15);
auto contentsSectionSize = std::mem::get_section_size(contentsSection);
auto contentsElementSize = sizeof(E);
std::assert_warn((contentsSectionSize % contentsElementSize) == 0,
"The size of the contentsSection must be an integer multiple of sizeof(E) !");
E contents[contentsSectionSize / contentsElementSize] @ 0x00 in contentsSection;
#endif
}
};
enum PropertyTypeCode : char {
BYTE = 'Z',
SHORT = 'Y',
BOOL = 'B',
CHAR = 'C',
INT = 'I',
FLOAT = 'F',
DOUBLE = 'D',
LONG = 'L',
BINARY = 'R',
STRING = 'S',
ARRAY_BOOL = 'b',
ARRAY_UBYTE = 'c',
ARRAY_INT = 'i',
ARRAY_LONG = 'l',
ARRAY_FLOAT = 'f',
ARRAY_DOUBLE = 'd'
};
struct PropertyRecord {
PropertyTypeCode typeCode;
match (typeCode) {
(PropertyTypeCode::BYTE): s8 data;
(PropertyTypeCode::SHORT): s16 data;
(PropertyTypeCode::BOOL): bool data;
(PropertyTypeCode::CHAR): char data;
(PropertyTypeCode::INT): s32 data;
(PropertyTypeCode::FLOAT): float data;
(PropertyTypeCode::DOUBLE): double data;
(PropertyTypeCode::LONG): s64 data;
(PropertyTypeCode::BINARY): {
u32 dataLength;
u8 data[dataLength];
}
(PropertyTypeCode::STRING): {
u32 stringLength;
char string[stringLength];
}
(PropertyTypeCode::ARRAY_BOOL): Array<bool> data;
(PropertyTypeCode::ARRAY_UBYTE): Array<u8> data;
(PropertyTypeCode::ARRAY_INT): Array<s32> data;
(PropertyTypeCode::ARRAY_LONG): Array<s64> data;
(PropertyTypeCode::ARRAY_FLOAT): Array<float> data;
(PropertyTypeCode::ARRAY_DOUBLE): Array<double> data;
(_): std::error("Invalid property type code!");
}
};
struct NodeRecord32 {
u32 endOffset;
u32 numProperties;
u32 propertyListLen;
u8 nameLen;
// Detect sentinel record which marks the end of a list of node records
if (endOffset == 0
&& numProperties == 0
&& propertyListLen == 0
&& nameLen == 0) {
break;
}
char name[nameLen];
auto posBeforePropertyRecords = $;
auto posAfterPropertyRecords = posBeforePropertyRecords + propertyListLen;
PropertyRecord propertyRecords[numProperties];
std::assert($ == posAfterPropertyRecords, std::format("Invalid size of propertyRecords @ {:#x} !", posBeforePropertyRecords));
NodeRecord32 nestedList[while($ < endOffset)];
std::assert($ == endOffset, std::format("Invalid size of nestedList @ {:#x} !", posAfterPropertyRecords));
};
struct NodeRecord64 {
u64 endOffset;
u64 numProperties;
u64 propertyListLen;
u8 nameLen;
// Detect sentinel record which marks the end of a list of node records
if (endOffset == 0
&& numProperties == 0
&& propertyListLen == 0
&& nameLen == 0) {
break;
}
char name[nameLen];
auto posBeforePropertyRecords = $;
auto posAfterPropertyRecords = posBeforePropertyRecords + propertyListLen;
PropertyRecord propertyRecords[numProperties];
std::assert($ == posAfterPropertyRecords, std::format("Invalid size of propertyRecords @ {:#x} !", posBeforePropertyRecords));
NodeRecord64 nestedList[while($ < endOffset)];
std::assert($ == endOffset, std::format("Invalid size of nestedList @ {:#x} !", posAfterPropertyRecords));
};
fn assertZero (auto array, u128 size, auto message) {
bool nonzeroPadding = false;
for (u8 i = 0, i < size, i = i + 1) {
if (array[i] != 0) {
nonzeroPadding = true;
}
}
std::assert_warn(!nonzeroPadding, message);
};
struct Footer {
type::Magic<"\xFA\xBC\xAB\x09\xD0\xC8\xD4\x66\xB1\x76\xFB\x83\x1C\xF7\x26\x7E"> footerId;
char zeroes[4];
assertZero(zeroes, 4, "Found non-zero values in footer after footerId!");
u128 ofs = $;
u8 alignmentPaddingSize = ((ofs + 15) & ~15) - ofs;
if (alignmentPaddingSize == 0) {
alignmentPaddingSize = 16;
}
char alignmentPadding[alignmentPaddingSize];
assertZero(alignmentPadding, alignmentPaddingSize, "Found non-zero bytes in alignmentPadding!");
u32 version;
char staticPadding[120];
assertZero(staticPadding, 120, "Found non-zero bytes in staticPadding!");
type::Magic<"\xF8\x5A\x8C\x6A\xDE\xF5\xD9\x7E\xEC\xE9\x0C\xE3\x75\x8F\x29\x0B"> footerMagic;
};
struct Header {
type::Magic<"Kaydara FBX Binary \x00\x1A\x00"> magic;
u32 version;
};
struct FBX {
Header header;
if (header.version < 7500) {
NodeRecord32 rootRecords[while(true)];
} else {
NodeRecord64 rootRecords[while(true)];
}
Footer footer;
std::assert_warn(header.version == footer.version, "Version numbers in header and footer do not match!");
};
FBX fbx @ 0x00;

View File

@@ -1,5 +1,6 @@
#pragma author WerWolv
#pragma description Flat Linux Device Tree blob
#pragma magic [ D0 0D FE ED ] @ 0x00
#pragma endian big

View File

@@ -1,5 +1,6 @@
#pragma author WerWolv
#pragma description Free Lossless Audio Codec, FLAC Audio Format
#pragma MIME audio/flac
import std.sys;
import std.core;
@@ -22,7 +23,7 @@ enum BLOCK_TYPE : u8 {
VORBIS_COMMENT = 4,
CUESHEET = 5,
PICTURE = 6,
INVALID = 127
};
@@ -48,7 +49,7 @@ struct METADATA_BLOCK_STREAMINFO {
u24 minFrameSize, maxFrameSize;
STREAMINFO_FLAGS flags;
u128 md5Signature;
bitsPerSample = flags.bitsPerSample;
};
@@ -79,7 +80,7 @@ struct VORBIS_USER_COMMENT {
struct METADATA_BLOCK_VORBIS_COMMENT {
le u32 vendorLength;
u8 vendor[vendorLength];
le u32 userCommentListLength;
VORBIS_USER_COMMENT userCommentList[userCommentListLength];
};
@@ -168,24 +169,24 @@ bitfield FRAME_HEADER_FLAGS {
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;
};
@@ -248,8 +249,8 @@ struct RESIDUAL {
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)
@@ -278,7 +279,7 @@ struct SUBFRAME_LPC {
struct SUBFRAME {
SUBFRAME_HEADER header;
if (header.type == 0b00000)
SUBFRAME_CONSTANT constant;
else if (header.type == 0b000001)
@@ -300,7 +301,7 @@ 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)

View File

@@ -0,0 +1,258 @@
/*!
This pattern can be used to parse Flipper Zero settings.
It supports SavedStructure based settings and Notification settings.
*/
#pragma author Jan Wiesemann
#pragma description Flipper Zero Settings
/**
Infrared
@source https://github.com/flipperdevices/flipperzero-firmware/blob/a403e5f543a5423e39ac1700ae4711e9e489445e/applications/main/infrared/infrared_app.c#L17
*/
#define MAGIC_IR 0x1F
/**
Expansion/UART
@source https://github.com/flipperdevices/flipperzero-firmware/blob/a403e5f543a5423e39ac1700ae4711e9e489445e/applications/services/expansion/expansion_settings.c#L10
*/
#define MAGIC_UART 0xEA
/**
Bluetooth
@source https://github.com/flipperdevices/flipperzero-firmware/blob/a403e5f543a5423e39ac1700ae4711e9e489445e/applications/services/bt/bt_settings.c#L9
*/
#define MAGIC_BT 0x19
/**
Dolphin
@source https://github.com/DarkFlippers/unleashed-firmware/blob/b2305ce5c7a6ab36babc30243a589eccfa9edcb6/applications/services/dolphin/helpers/dolphin_state.c#L14
*/
#define MAGIC_DOLPHIN 0xD0
/**
Desktop
@source https://github.com/flipperdevices/flipperzero-firmware/blob/a403e5f543a5423e39ac1700ae4711e9e489445e/applications/services/desktop/desktop_settings.h#L14
*/
#define MAGIC_DEKTOP 0x17
/* ======= Common structures =======
Flipper datatype aliases
They are added for easyer translatiom from the Flipper soruce into ImHex
*/
using int8_t = u8;
using uint8_t = u8;
using int16_t = u16;
using uint16_t = u16;
using int32_t = s32;
using uint32_t = u32;
using int64_t = s64;
using uint64_t = u64;
/* ======= Common structures ======= */
/**
Header for a saved structure file
@source https://github.com/flipperdevices/flipperzero-firmware/blob/a403e5f543a5423e39ac1700ae4711e9e489445e/lib/toolbox/saved_struct.c#L14
*/
struct SavedStructHeader {
uint8_t magic;
uint8_t version;
uint8_t checksum; //Sum of data-bytes
uint8_t flags; //Not used always 0
uint32_t timestamp; //Not used alwas 0
};
/* ======= Infrared settings '.infrared.settings' ======= */
/*
Lists all avalible outputs for the Infrared appication
@source https://github.com/flipperdevices/flipperzero-firmware/blob/a403e5f543a5423e39ac1700ae4711e9e489445e/targets/furi_hal_include/furi_hal_infrared.h#L23
*/
enum FuriHalInfraredTxPin : uint8_t {
FuriHalInfraredTxPinInternal,
FuriHalInfraredTxPinExtPA7,
FuriHalInfraredTxPinMax
};
/*
Infrared Settings
@source https://github.com/flipperdevices/flipperzero-firmware/blob/a403e5f543a5423e39ac1700ae4711e9e489445e/applications/main/infrared/infrared_app.c#L22
*/
struct InfraredSettings {
FuriHalInfraredTxPin tx_pin;
bool otg_enabled;
};
/* ======= Expansion settings '.expansion.settings' ======= */
/**
???
@source https://github.com/flipperdevices/flipperzero-firmware/blob/a403e5f543a5423e39ac1700ae4711e9e489445e/applications/services/expansion/expansion_settings.h#L23
*/
struct ExpansionSettings {
uint8_t uart_index;
};
/* ======= Bluetooth settings '.bt.settings' ======= */
/**
Bluetooth Settings
@source https://github.com/flipperdevices/flipperzero-firmware/blob/a403e5f543a5423e39ac1700ae4711e9e489445e/applications/services/bt/bt_settings.h#L14
*/
struct BtSettings {
bool enabled;
};
/* ======= Dolphin state '.dolphin.state' ======= */
/**
Lists all avalible Apps, that grand you points
@source https://github.com/flipperdevices/flipperzero-firmware/blob/a403e5f543a5423e39ac1700ae4711e9e489445e/applications/services/dolphin/helpers/dolphin_deed.h#L18
*/
enum DolphinApp : uint16_t {
DolphinAppSubGhz,
DolphinAppRfid,
DolphinAppNfc,
DolphinAppIr,
DolphinAppIbutton,
DolphinAppBadusb,
DolphinAppPlugin,
DolphinAppMAX
};
/**
States for the Dolphin
@source https://github.com/flipperdevices/flipperzero-firmware/blob/a403e5f543a5423e39ac1700ae4711e9e489445e/applications/services/dolphin/helpers/dolphin_state.h#L17
*/
struct DolphinStoreData{
uint8_t icounter_daily_limit[DolphinApp::DolphinAppMAX];
uint8_t butthurt_daily_limit;
uint32_t flags; // Not used always 0
uint32_t icounter;
int32_t butthurt;
uint64_t timestamp;
padding[4];
};
/* ======= Desktop settings '.dektop.settings' ======= */
#define MAX_PIN_SIZE 10
#define MIN_PIN_SIZE 4
#define MAX_APP_LENGTH 128
/**
Represents a Input Key
@source https://github.com/flipperdevices/flipperzero-firmware/blob/a403e5f543a5423e39ac1700ae4711e9e489445e/targets/f7/furi_hal/furi_hal_resources.h#L22
*/
enum InputKey : uint8_t{
InputKeyUp,
InputKeyDown,
InputKeyRight,
InputKeyLeft,
InputKeyOk,
InputKeyBack,
InputKeyMAX, /**< Special value */
};
/**
Stores the Pin-Code
@source https://github.com/flipperdevices/flipperzero-firmware/blob/a403e5f543a5423e39ac1700ae4711e9e489445e/applications/services/desktop/desktop_settings.h#L58
*/
struct PinCode{
InputKey data[MAX_PIN_SIZE];
uint8_t length;
};
/**
Possible buttons for the Shortcut menu
@source https://github.com/flipperdevices/flipperzero-firmware/blob/a403e5f543a5423e39ac1700ae4711e9e489445e/applications/services/desktop/desktop_settings.h#L45
*/
enum FavoriteAppShortcut : uint32_t {
FavoriteAppLeftShort,
FavoriteAppLeftLong,
FavoriteAppRightShort,
FavoriteAppRightLong,
FavoriteAppNumber
};
/**
Possible buttons for the Shortcut menu while using the dummy mode
@source https://github.com/flipperdevices/flipperzero-firmware/blob/a403e5f543a5423e39ac1700ae4711e9e489445e/applications/services/desktop/desktop_settings.h#L53
*/
enum DummyAppShortcut : uint32_t{
DummyAppLeft = 0,
DummyAppRight,
DummyAppDown,
DummyAppOk,
DummyAppNumber,
};
/**
Path or Appname for a Shortcut
@source https://github.com/flipperdevices/flipperzero-firmware/blob/a403e5f543a5423e39ac1700ae4711e9e489445e/applications/services/desktop/desktop_settings.h#L62
*/
struct FavoriteApp {
char name_or_path[MAX_APP_LENGTH];
};
/**
Settings for the Desktop
@source https://github.com/flipperdevices/flipperzero-firmware/blob/a403e5f543a5423e39ac1700ae4711e9e489445e/applications/services/desktop/desktop_settings.h#L71
*/
struct DesktopSettings {
PinCode pin_code;
padding[1];
uint32_t auto_lock_delay_ms;
uint8_t dummy_mode;
uint8_t display_clock;
FavoriteApp favorite_apps[FavoriteAppShortcut::FavoriteAppNumber];
FavoriteApp dummy_apps[DummyAppShortcut::DummyAppNumber];
padding[2];
};
/* ======= Helper======= */
/**
Container for SavedStruct based settings
*/
struct SavedStructure {
SavedStructHeader header;
match(header.magic, sizeof($) - sizeof(SavedStructHeader)) {
(MAGIC_IR, sizeof(InfraredSettings)): InfraredSettings infraredSettings;
(MAGIC_UART, sizeof(ExpansionSettings)): ExpansionSettings expansionSettings;
(MAGIC_BT, sizeof(BtSettings)): BtSettings btSettings;
(MAGIC_DOLPHIN, sizeof(DolphinStoreData)): DolphinStoreData dolphinStoreData;
(MAGIC_DEKTOP, sizeof(DesktopSettings)): DesktopSettings desktopSettings;
}
};
/**
Settings for the LCD and Notifications
@source https://github.com/flipperdevices/flipperzero-firmware/blob/a403e5f543a5423e39ac1700ae4711e9e489445e/applications/services/notification/notification_app.h#L46
*/
struct NotificationSettings {
uint8_t version;
padding[3];
float display_brightness;
float led_brightness;
float speaker_volume;
uint32_t display_off_delay_ms;
int8_t contrast;
bool vibro_on;
padding[2];
};
/**
Wrapper for SavedStructure or Notificaition settings
*/
struct FlipperSettings {
if(sizeof($) == sizeof(NotificationSettings))
NotificationSettings notificationSettings;
else
SavedStructure savedStructure;
};
FlipperSettings flipperSettings @ 0x00;

View File

@@ -1,7 +1,9 @@
#pragma author WerWolv
#pragma description Drive File System
#pragma MIME application/x-ima
import std.io;
import std.core;
struct DiskTimeStamp {
u8 seconds, minutes, hours;
@@ -46,25 +48,25 @@ namespace fat32 {
padding[12];
u32 trailSignature;
};
bitfield SequenceNumber {
padding : 1;
lastLogical : 1;
padding : 1;
number : 5;
} [[left_to_right]];
} [[bitfield_order(std::core::BitfieldOrder::MostToLeastSignificant, 8)]];
enum EntryStatus : u8 {
Regular = 0x00,
DotEntry = 0x2E,
DeletedEntry = 0xE5
};
union EntryStatusOrSequenceNumber {
EntryStatus entryStatus;
SequenceNumber sequenceNumber;
};
bitfield Attributes {
readOnly : 1;
hidden : 1;
@@ -73,8 +75,8 @@ namespace fat32 {
subdirectory : 1;
archive : 1;
padding : 2;
} [[right_to_left]];
} [[bitfield_order(std::core::BitfieldOrder::LeastToMostSignificant, 8)]];
struct DirEntry {
char fileName[8];
char extension[3];
@@ -83,10 +85,10 @@ namespace fat32 {
u16 time, date;
u16 startingCluster;
u32 fileSize;
u8 data[fileSize] @ startingCluster * bytesPerCluster;
};
struct VFATDirEntry {
EntryStatusOrSequenceNumber entryStatusOrSequenceNumber;
char16 name1[5];
@@ -96,7 +98,7 @@ namespace fat32 {
char16 name2[6];
u16 startingCluster;
char16 name3[2];
if (entryStatusOrSequenceNumber.sequenceNumber.number > 1)
VFATDirEntry nextLogicalEntry;
else
@@ -133,9 +135,9 @@ namespace fat32 {
char fsType[8];
u8 bootstrapCode[420];
u16 signature;
bytesPerCluster = (sectorsPerCluster * 1024) * bytesPerSector;
FSInfo fsInfo @ addressof(this) + fsInfoSector * bytesPerSector;
VFATDirEntry rootDirEntry @ addressof(this) + rootCluster * bytesPerCluster;
};
@@ -143,13 +145,13 @@ namespace fat32 {
}
struct PartitionEntry {
PartitionStatus status;
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)

View File

@@ -7,6 +7,9 @@ import type.size;
import std.string;
import std.mem;
const u16 ROMBANKSIZE_16K = 0x4000;
const u16 ROMBANKSIZE_32K = 0x8000;
bool uppercaseROMFeatures in;
bool brandedROMFeatures in;
@@ -30,9 +33,13 @@ namespace format {
romSize = 1258291;
romBanks = 80;
}
if (cartSizeType == 0x54) {
romSize = 1572864;
romBanks = 96;
}
return std::format("size: {}, banks: {}", type::impl::size_formatter(romSize), romBanks);
};
fn ram_type(u8 ramType) {
u16 ramSize;
u16 ramBanks;
@@ -54,7 +61,7 @@ namespace format {
}
return std::format("size: {}, banks: {}", type::impl::size_formatter(ramSize), ramBanks);
};
fn rom_features(u8 type) {
str result = "( ";
if (brandedROMFeatures) match(type) {
@@ -64,37 +71,37 @@ namespace format {
match(type) {
(0x00): result += "no_mbc";
(0x01): result += "mbc1";
(0x02): result += "mbc1 | ram";
(0x02): result += "mbc1 | ram";
(0x03): result += "mbc1 | ram | battery";
(0x05): result += "mbc2";
(0x05): result += "mbc2";
(0x06): result += "mbc2 | battery";
(0x08): result += "no_mbc | ram";
(0x08): result += "no_mbc | ram";
(0x09): result += "no_mbc | ram | battery";
(0x0B): result += "mmm01";
(0x0B): result += "mmm01";
(0x0C): result += "mmm01 | ram";
(0x0D): result += "mmm01 | ram | battery";
(0x0D): result += "mmm01 | ram | battery";
(0x0F): result += "mbc3 | timer | battery";
(0x10): result += "mbc3 | timer | ram | battery";
(0x10): result += "mbc3 | timer | ram | battery";
(0x11): result += "mbc3";
(0x12): result += "mbc3 | ram";
(0x12): result += "mbc3 | ram";
(0x13): result += "mbc3 | ram | battery";
(0x19): result += "mbc5";
(0x19): result += "mbc5";
(0x1A): result += "mbc5 | ram";
(0x1B): result += "mbc5 | ram | battery";
(0x1B): result += "mbc5 | ram | battery";
(0x1C): result += "mbc5 | rumble";
(0x1D): result += "mbc5 | rumble | ram";
(0x1D): result += "mbc5 | rumble | ram";
(0x1E): result += "mbc5 | rumble | ram | battery";
(0x20): result += "mbc6";
(0x20): result += "mbc6";
(0x22): result += "mbc7 | sensor | rumble";
(0xFC): result += "camera";
(0xFC): result += "camera";
(0xFD): result += "tama5";
(0xFE): result += "huc3";
(0xFE): result += "huc3";
(0xFF): result += "huc1 | ram | battery";
}
if (uppercaseROMFeatures) result = std::string::to_upper(result);
return result + " )";
return result + " )";
};
fn licensee_code(u8 code) {
match(code) {
(0x00): return "None";
@@ -128,6 +135,7 @@ namespace format {
(0x46 | 0xCF): return "Angel";
(0x47): return "Spectrum Holoby";
(0x49): return "Irem";
(0x4F): return "U.S. Gold";
(0x50): return "Absolute";
(0x51 | 0xB0): return "Acclaim";
(0x52): return "Activision";
@@ -196,7 +204,7 @@ namespace format {
(0xCA): return "Ultra";
(0xCB): return "Vap";
(0xCC): return "Use Corporation";
(0xCD): return "Meldac";
(0xCD): return "Meldac";
(0xD1): return "Sofel";
(0xD2): return "Quest";
(0xD3): return "Sigma Enterprises";
@@ -214,6 +222,7 @@ namespace format {
(0xE8): return "Asmik";
(0xE9): return "Natsume";
(0xEA): return "King Records";
(0xEC): return "Epic/Sony Records";
(0xEE): return "IGS";
(0xF0): return "A Wave";
(0xF3): return "Extreme Entertainment";
@@ -221,7 +230,7 @@ namespace format {
return "Unknown Licensee";
};
fn new_licensee_code(str a) {
fn new_licensee_code(str a) {
if (std::mem::read_unsigned(0x14B, 1) != 0x33) return "See old licensee code";
match(a) {
("00"): return "None";
@@ -284,13 +293,16 @@ namespace format {
("96"): return "Yonezawa/spal";
("97"): return "Kaneko";
("99"): return "Pack in soft";
("9H"): return "Bottom Up";
("A4"): return "Konami (Yu-Gi-Oh!)";
("BL"): return "MTO";
("DK"): return "Kodansha";
}
return "Unknown";
};
using CGB;
fn null_cgb_flags(CGB flags) {
return "NO_CGB";
};
@@ -357,5 +369,15 @@ struct JumpVectors {
u8 int5[8] [[comment("joypad")]];
};
struct romBank16K {
u8 Bank[ROMBANKSIZE_16K];
};
struct romBank32K {
u8 Bank[ROMBANKSIZE_32K];
};
romBank16K romBanks16K[std::mem::size() / ROMBANKSIZE_16K] @ 0x00;
romBank32K romBanks32K[std::mem::size() / ROMBANKSIZE_32K] @ 0x00;
JumpVectors jumpVectors @ 0x00 [[comment("Instructions called on interrupts or RST instructions")]];
CartridgeStart cartridgeStart @ 0x100;

175
patterns/gba.hexpat Normal file
View File

@@ -0,0 +1,175 @@
#pragma author GekySan
#pragma description Game Boy Advance ROM Header
#pragma MIME application/x-gameboy-advance-rom
#pragma MIME application/x-agb-rom
#pragma MIME application/x-gba-rom
import std.string;
import std.mem;
import std.sys;
// In gb.hexpat
namespace format {
fn licensee_code(str code) {
match(code) {
("00"): return "None";
("01" | "31"): return "Nintendo";
("08" | "38"): return "Capcom";
("09"): return "Hot-B";
("0A" | "E0"): return "Jaleco";
("0B"): return "Coconuts Japan";
("0C" | "6E"): return "Elite Systems";
("13" | "69"): return "EA (Electronic Arts)";
("18"): return "Hudsonsoft";
("19"): return "ITC Entertainment";
("1A"): return "Yanoman";
("1D"): return "Japan Clary";
("1F" | "4A" | "61"): return "Virgin Interactive";
("24"): return "PCM Complete";
("25"): return "San-X";
("28"): return "Kotobuki Systems";
("29"): return "Seta";
("30" | "70"): return "Infogrames";
("32" | "A2" | "B2" | "C4"): return "Bandai";
("33"): return "See new licensee code";
("34" | "A4"): return "Konami";
("35"): return "HectorSoft";
("39" | "9D"): return "Banpresto";
("3C"): return ".Entertainment i";
("3E"): return "Gremlin";
("41"): return "Ubisoft";
("42" | "EB"): return "Atlus";
("44" | "4D"): return "Malibu";
("46" | "CF"): return "Angel";
("47"): return "Spectrum Holoby";
("49"): return "Irem";
("4F"): return "U.S. Gold";
("50"): return "Absolute";
("51" | "B0"): return "Acclaim";
("52"): return "Activision";
("53"): return "American Sammy";
("54"): return "GameTek";
("55"): return "Park Place";
("56" | "DB" | "FF"): return "LJN";
("57"): return "Matchbox";
("59"): return "Milton Bradley";
("5A"): return "Mindscape";
("5B"): return "Romstar";
("5C" | "D6"): return "Naxat Soft";
("5D"): return "Tradewest";
("60"): return "Titus";
("67"): return "Ocean Interactive";
("6F"): return "Electro Brain";
("71"): return "Interplay";
("72" | "AA"): return "Broderbund";
("73"): return "Sculptered Soft";
("75"): return "The Sales Curve";
("78"): return "t.hq";
("79"): return "Accolade";
("7A"): return "Triffix Entertainment";
("7C"): return "Microprose";
("7F" | "C2"): return "Kemco";
("80"): return "Misawa Entertainment";
("83"): return "Lozc";
("86" | "C4"): return "Tokuma Shoten Intermedia";
("8B"): return "Bullet-Proof Software";
("8C"): return "Vic Tokai";
("8E"): return "Ape";
("8F"): return "I'Max";
("91"): return "Chunksoft Co.";
("92"): return "Video System";
("93"): return "Tsubaraya Productions Co.";
("95"): return "Varie Corporation";
("96"): return "Yonezawa/SPal";
("97"): return "Kaneko";
("99"): return "Arc";
("9A"): return "Nihon Bussan";
("9B"): return "Tecmo";
("9C"): return "Imagineer";
("9F"): return "Nova";
("A1"): return "Hori Electric";
("A6"): return "Kawada";
("A7"): return "Takara";
("A9"): return "Technos Japan";
("AC"): return "Toei Animation";
("AD"): return "Toho";
("AF"): return "Namco";
("B1"): return "ASCII or Nexsoft";
("B4"): return "Square Enix";
("B6"): return "HAL Laboratory";
("B7"): return "SNK";
("B9" | "CE"): return "Pony Canyon";
("BA"): return "Culture Brain";
("BB"): return "Sunsoft";
("BD"): return "Sony Imagesoft";
("BF"): return "Sammy";
("C0" | "D0"): return "Taito";
("C3"): return "Squaresoft";
("C5"): return "Data East";
("C6"): return "Tonkinhouse";
("C8"): return "Koei";
("C9"): return "UFL";
("CA"): return "Ultra";
("CB"): return "Vap";
("CC"): return "Use Corporation";
("CD"): return "Meldac";
("D1"): return "Sofel";
("D2"): return "Quest";
("D3"): return "Sigma Enterprises";
("D4"): return "ASK Kodansha Co.";
("D7"): return "Copya System";
("DA"): return "Tomy";
("DD"): return "NCS";
("DE"): return "Human";
("DF"): return "Altron";
("E1"): return "Towa Chiki";
("E2"): return "Yutaka";
("E3"): return "Varie";
("E5"): return "Epoch";
("E7"): return "Athena";
("E8"): return "Asmik";
("E9"): return "Natsume";
("EA"): return "King Records";
("EC"): return "Epic/Sony Records";
("EE"): return "IGS";
("F0"): return "A Wave";
("F3"): return "Extreme Entertainment";
}
return "Unknown Licensee";
};
}
fn calcChecksum() {
u8 sum = 0;
u8 offset = 0xA0;
while (offset <= 0xBC) {
sum += std::mem::read_unsigned(offset, 1);
offset += 1;
}
return ((-((0x19 + sum) & 0xFF)) & 0xFF) == std::mem::read_unsigned(0xBD, 1);
};
struct GBAHeader {
u8 entryPoint[4] [[comment("ARM entry point code, typically a 'B rom_start' instruction")]];
u8 nintendoLogo[156] [[comment("Nintendo logo")]];
char gameTitle[12] [[comment("Game title, uppercase ASCII, max 12 characters")]];
char gameCode[4] [[comment("Game code, uppercase ASCII, 4 characters")]];
char makerCode[2] [[format("format::licensee_code"), comment("Maker code, uppercase ASCII, 2 characters")]];
u8 fixedValue [[comment("Fixed value, must be 0x96")]];
u8 unitCode [[comment("Main unit code, identifies required hardware (00h for GBA)")]];
u8 deviceType [[comment("Device type, usually 00h. Bit 7 relates to DACS/debug features")]];
u8 reserved1[7] [[comment("Reserved area, must be zero-filled")]];
u8 softwareVersion [[comment("Software version number, usually 00h")]];
u8 complementCheck [[comment("Header checksum, required for validation")]];
u8 reserved2[2] [[comment("Reserved area, must be zero-filled")]];
};
if (!calcChecksum()) {
std::error("Checksum validation failed: Calculated value does not match the expected checksum in the header.");
}
GBAHeader gbaHeader @ 0x0000;

216
patterns/gguf.hexpat Normal file
View File

@@ -0,0 +1,216 @@
// https://github.com/ggerganov/ggml/blob/master/docs/gguf.md
// https://github.com/openxla/iree/blob/main/runtime/src/iree/io/formats/gguf/gguf_parser.c
#pragma description ggml GGUF v3
#pragma authors @leonjza, jessie @ imhex discord
#pragma magic [ 47 47 55 46 ] @ 0x00
#pragma pattern_limit 300000
enum ggml_type: u32 {
GGML_TYPE_F32 = 0,
GGML_TYPE_F16 = 1,
GGML_TYPE_Q4_0 = 2,
GGML_TYPE_Q4_1 = 3,
// GGML_TYPE_Q4_2 = 4, support has been removed
// GGML_TYPE_Q4_3 = 5, support has been removed
GGML_TYPE_Q5_0 = 6,
GGML_TYPE_Q5_1 = 7,
GGML_TYPE_Q8_0 = 8,
GGML_TYPE_Q8_1 = 9,
GGML_TYPE_Q2_K = 10,
GGML_TYPE_Q3_K = 11,
GGML_TYPE_Q4_K = 12,
GGML_TYPE_Q5_K = 13,
GGML_TYPE_Q6_K = 14,
GGML_TYPE_Q8_K = 15,
GGML_TYPE_IQ2_XXS = 16,
GGML_TYPE_IQ2_XS = 17,
GGML_TYPE_IQ3_XXS = 18,
GGML_TYPE_IQ1_S = 19,
GGML_TYPE_IQ4_NL = 20,
GGML_TYPE_IQ3_S = 21,
GGML_TYPE_IQ2_S = 22,
GGML_TYPE_IQ4_XS = 23,
GGML_TYPE_I8 = 24,
GGML_TYPE_I16 = 25,
GGML_TYPE_I32 = 26,
GGML_TYPE_I64 = 27,
GGML_TYPE_F64 = 28,
GGML_TYPE_IQ1_M = 29,
GGML_TYPE_COUNT,
};
enum gguf_metadata_value_type: u32 {
// The value is a 8-bit unsigned integer.
GGUF_METADATA_VALUE_TYPE_UINT8 = 0,
// The value is a 8-bit signed integer.
GGUF_METADATA_VALUE_TYPE_INT8 = 1,
// The value is a 16-bit unsigned little-endian integer.
GGUF_METADATA_VALUE_TYPE_UINT16 = 2,
// The value is a 16-bit signed little-endian integer.
GGUF_METADATA_VALUE_TYPE_INT16 = 3,
// The value is a 32-bit unsigned little-endian integer.
GGUF_METADATA_VALUE_TYPE_UINT32 = 4,
// The value is a 32-bit signed little-endian integer.
GGUF_METADATA_VALUE_TYPE_INT32 = 5,
// The value is a 32-bit IEEE754 floating point number.
GGUF_METADATA_VALUE_TYPE_FLOAT32 = 6,
// The value is a boolean.
// 1-byte value where 0 is false and 1 is true.
// Anything else is invalid, and should be treated as either the model being invalid or the reader being buggy.
GGUF_METADATA_VALUE_TYPE_BOOL = 7,
// The value is a UTF-8 non-null-terminated string, with length prepended.
GGUF_METADATA_VALUE_TYPE_STRING = 8,
// The value is an array of other values, with the length and type prepended.
///
// Arrays can be nested, and the length of the array is the number of elements in the array, not the number of bytes.
GGUF_METADATA_VALUE_TYPE_ARRAY = 9,
// The value is a 64-bit unsigned little-endian integer.
GGUF_METADATA_VALUE_TYPE_UINT64 = 10,
// The value is a 64-bit signed little-endian integer.
GGUF_METADATA_VALUE_TYPE_INT64 = 11,
// The value is a 64-bit IEEE754 floating point number.
GGUF_METADATA_VALUE_TYPE_FLOAT64 = 12,
};
// A string in GGUF.
struct gguf_string_t {
// The length of the string, in bytes.
u64 len;
// The string as a UTF-8 non-null-terminated string.
char string[len];
};
struct gguf_metadata_value_t {
gguf_metadata_value_type type;
u64 length;
match(type) {
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_UINT8): u8 value[length];
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_INT8): s8 value[length];
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_UINT16): u16 value[length];
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_INT16): s16 value[length];
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_UINT32): u32 value[length];
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_INT32): s32 value[length];
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_FLOAT32): float value[length];
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_BOOL): bool value[length];
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_STRING): gguf_string_t value[length];
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_UINT64): u64 value[length];
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_FLOAT64): double value[length];
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_ARRAY): double value[length];
}
};
struct gguf_metadata_value {
gguf_metadata_value_type type;
match(type) {
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_UINT8): u8 value;
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_INT8): s8 value;
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_UINT16): u16 value;
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_INT16): s16 value;
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_UINT32): u32 value;
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_INT32): s32 value;
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_FLOAT32): float value;
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_BOOL): bool value;
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_STRING): gguf_string_t value;
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_UINT64): u64 value;
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_FLOAT64): double value;
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_ARRAY): gguf_metadata_value_t value;
}
};
struct gguf_metadata_kv_t {
// The key of the metadata. It is a standard GGUF string, with the following caveats:
// - It must be a valid ASCII string.
// - It must be a hierarchical key, where each segment is `lower_snake_case` and separated by a `.`.
// - It must be at most 2^16-1/65535 bytes long.
// Any keys that do not follow these rules are invalid.
gguf_string_t key;
// The type of the value.
// Must be one of the `gguf_metadata_value_type` values.
// gguf_metadata_value_type value_type;
// The value.
gguf_metadata_value value;
};
struct gguf_header_t {
// Magic number to announce that this is a GGUF file.
// Must be `GGUF` at the byte level: `0x47` `0x47` `0x55` `0x46`.
// Your executor might do little-endian byte order, so it might be
// check for 0x46554747 and letting the endianness cancel out.
// Consider being *very* explicit about the byte order here.
u32 magic;
// The version of the format implemented.
// Must be `3` for version described in this spec, which introduces big-endian support.
//
// This version should only be increased for structural changes to the format.
// Changes that do not affect the structure of the file should instead update the metadata
// to signify the change.
u32 version;
// The number of tensors in the file.
// This is explicit, instead of being included in the metadata, to ensure it is always present
// for loading the tensors.
u64 tensor_count;
// The number of metadata key-value pairs.
u64 metadata_kv_count;
// The metadata key-value pairs.
gguf_metadata_kv_t metadata_kv[metadata_kv_count];
};
struct gguf_tensor_info_t {
// The name of the tensor. It is a standard GGUF string, with the caveat that
// it must be at most 64 bytes long.
gguf_string_t name;
// The number of dimensions in the tensor.
// Currently at most 4, but this may change in the future.
u32 n_dimensions;
// The dimensions of the tensor.
u64 dimensions[n_dimensions];
// The type of the tensor.
ggml_type type;
// The offset of the tensor's data in this file in bytes.
//
// This offset is relative to `tensor_data`, not to the start
// of the file, to make it easier for writers to write the file.
// Readers should consider exposing this offset relative to the
// file to make it easier to read the data.
//
// Must be a multiple of `ALIGNMENT`. That is, `align_offset(offset) == offset`.
u64 offset;
};
struct gguf_file_t {
// The header of the file.
gguf_header_t header;
// Tensor infos, which can be used to locate the tensor data.
gguf_tensor_info_t tensor_infos[header.tensor_count];
// Padding to the nearest multiple of `ALIGNMENT`.
//
// That is, if `sizeof(header) + sizeof(tensor_infos)` is not a multiple of `ALIGNMENT`,
// this padding is added to make it so.
//
// This can be calculated as `align_offset(position) - position`, where `position` is
// the position of the end of `tensor_infos` (i.e. `sizeof(header) + sizeof(tensor_infos)`).
u8 _padding[];
// Tensor data.
//
// This is arbitrary binary data corresponding to the weights of the model. This data should be close
// or identical to the data in the original model file, but may be different due to quantization or
// other optimizations for inference. Any such deviations should be recorded in the metadata or as
// part of the architecture definition.
//
// Each tensor's data must be stored within this array, and located through its `tensor_infos` entry.
// The offset of each tensor's data must be a multiple of `ALIGNMENT`, and the space between tensors
// should be padded to `ALIGNMENT` bytes.
u8 tensor_data[];
};
gguf_file_t GGUF @ 0x00;

View File

@@ -1,4 +1,4 @@
#pragma description GIF image files
#pragma description GIF image
#pragma MIME image/gif
@@ -27,7 +27,7 @@ bitfield GCT_Flags {
colorRes : 3 [[comment("Indicates the richness of the original pallet")]];
enabled : 1;
};
bitfield ImageDescriptorFlags {
lctSize: 3;
reserved: 2;
@@ -35,7 +35,7 @@ bitfield ImageDescriptorFlags {
interlaceFlag: 1;
lctEnable: 1;
};
bitfield GCE_Flags {
transparent : 1;
userInput : 1;
@@ -109,7 +109,7 @@ struct PlainTextExtension {
u8 textForegroundColorIndex;
u8 textBackgroundColorIndex;
DataSubBlocks plainTextData;
};
struct GraphicControlExtension {
@@ -141,9 +141,9 @@ namespace format {
if(value == 0x00) return "Do nothing";
if(value == 0x01) return "Do not remove pixels";
if(value == 0x02) return "Restore background pixels";
if(value == 0x03) return "Restore previous pixels";
if(value == 0x03) return "Restore previous pixels";
};
fn extension_name(u8 label) {
if(label == LABEL_GC) return "Graphical Control Extension";
if(label == LABEL_COMMENT) return "Comment Extension";

View File

@@ -1,6 +1,6 @@
/**
* @file <gltf.pat> ImHex Pattern for glTF binary files.
*
* @file <gltf.hexpat> ImHex Pattern for glTF binary files.
*
* Copyright (c) 2023 H. Utku Maden <utkumaden@hotmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -22,14 +22,19 @@
* SOFTWARE.
*/
#pragma author H. Utku Maden
#pragma description GL Transmission Format binary 3D model (.glb)
#pragma MIME model/gltf-binary
import std.mem;
import std.io;
import type.magic;
/**
* @brief The glTF magic section.
*/
struct gltf_magic_t {
char magic[4]; /**< The magic value. Must be "glTF" */
type::Magic<"glTF"> magic; /**< The magic value. Must be "glTF" */
u32 version; /**< The version. Must be 2 for glTF 2.0. */
u32 length; /**< Length of the file in bytes, including magic section. */
};
@@ -55,12 +60,11 @@ fn gltf_format(gltf_chunk_type_t x)
{
if (x == gltf_chunk_type_t::JSON) return "JSON";
else if (x == gltf_chunk_type_t::BIN) return "BIN";
return "";
};
gltf_magic_t magic @ 0x00;
gltf_chunk_t chunks[while(!std::mem::eof())] @ $;
if (magic.magic != "glTF")
std::error("This file might not be a glTF file, expected \"glTF\", got %s", magic.magic);
std::assert_warn(std::mem::size() == magic.length, "file size mismatch");

View File

@@ -1,5 +1,5 @@
#pragma author WerWolv
#pragma description GZip compressed data format
#pragma description GZip compressed data
#pragma MIME application/gzip
@@ -55,26 +55,26 @@ struct GZip {
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;
};

View File

@@ -1,536 +0,0 @@
import std.mem;
import std.io;
import std.string;
struct Header {
u32 magic;
u32 version;
u64 RootStructAltGUID;
u64 AssetChecksum;
u32 DependencyCount;
s32 DataBlockCount;
s32 TagStructCount;
s32 DataReferenceCount;
s32 TagReferenceCount;
u32 StringTableSize;
u32 ZoneSetDataSize;
u32 Unk_0x34;
u32 HeaderSize;
u32 DataSize;
u32 ResourceDataSize;
u32 ActualResoureDataSize;
u8 HeaderAlignment;
u8 TagDataAlignment;
u8 ResourceDataAlignment;
u8 ActualResourceDataAlignment;
s32 IsResource;
};
enum curve_mode : u8 {
choose_best = 0x00,
force_FAST = 0x01,
force_PRETTY = 0x02,
};
enum BitmapForcedFormat : u16 {
Use_Default = 0x00,
Best_Compressed_Color_Format = 0x01,
Best_Uncompressed_Color_Format = 0x02,
Best_Compressed_Bump_Format = 0x03,
Best_Uncompressed_Bump_Format = 0x04,
Best_Compressed_Monochrome_Format = 0x05,
Best_Uncompressed_Monochrome_Format = 0x06,
Best_Compressed_Monochrome_Format_Without_Alpha = 0x07,
unused2 = 0x08,
unused3 = 0x09,
unused4 = 0x0A,
unused5 = 0x0B,
unused6 = 0x0C,
Color_And_Alpha_Formats = 0x0D,
bc1_unorm_DXT1_Compressed_Color_Key_Alpha = 0x0E,
bc2_unorm_DXT3_Compressed_Color_4bit_Alpha = 0x0F,
bc3_unorm_DXT5_Compressed_Color_Compressed_8bit_Alpha = 0x10,
Color_24bit_Alpha_8bit = 0x11,
Monochrome_8bit_Alpha_8bit = 0x12,
Channel_Mask_3bit_Color_1bit_Alpha = 0x13,
Color_30bit_Alpha_2bit = 0x14,
Color_48bit_Alpha_16bit = 0x15,
HALF_Color_Alpha = 0x16,
FLOAT_Color_Alpha = 0x17,
r8_unorm_8bit_Intensity_RGBA = 0x18,
DEPRECATED_DXT3A_4bit_Intensity_ARGB = 0x19,
bc4_unorm_rrrr_DXT5A_Compressed_Intensity_ARGB = 0x1A,
Compressed_Monochrome_Alpha = 0x1B,
b4g4r4a4_12bit_Color_4bit_Alpha = 0x1C,
Color_Only_Formats = 0x1D,
Monochrome_8bit = 0x1E,
Compressed_Color_24bit = 0x1F,
Color_32bit_R11G11B10 = 0x20,
Monochrome_16bit = 0x21,
Red_Green_Only_16bit = 0x22,
Signed_RGBA_16bit = 0x23,
HALF_Red_Only = 0x24,
FLOAT_Red_Only = 0x25,
HALF_Red_Green_Only = 0x26,
FLOAT_Red_Green_Only = 0x27,
HALF_Monochrome = 0x28,
DEPRECATED_Compressed_Monochrome_4bit = 0x29,
Compressed_Interpolated_Monochrome = 0x2A,
bc6h_uf16_HDR_RGB_Unsigned_Half_Float = 0x2B,
bc6h_sf16_HDR_RGB_Signed_Half_Float = 0x2C,
bc7_unorm_High_Quality_bc3 = 0x2D,
Alpha_Only_Formats = 0x2E,
DEPRECATED_DXT3A_4bit_Alpha = 0x2F,
bc4_unorm_000r_DXT5A_8bit_Compressed_Alpha = 0x30,
Alpha_8bit = 0x31,
unused28 = 0x32,
unused29 = 0x33,
unused30 = 0x34,
Normal_Map_Formats = 0x35,
bc5_snorm_DXN_Compressed_Normals_Better = 0x36,
DEPRECATED_CTX1_Compressed_Normals_Smaller = 0x37,
Normals_16bit = 0x38,
Normals_32bit = 0x39,
Vector_8bit_4_Channel = 0x3A,
};
enum BitmapDownsampleFilter : u8 {
point_sampled = 0x01,
box_filter = 0x02,
blackman_filter = 0x03,
lanczos_filter = 0x04,
nuttall_filter = 0x05,
blackman_harris_filter = 0x06,
blackman_nuttall_filter = 0x07,
flat_top_filter = 0x08,
extreme_filter = 0x09,
min_filter = 0x0A
};
enum BitmapType : u8 {
_2D_Texture = 0x00,
_3D_Texture = 0x01,
CubeMap = 0x02,
Array = 0x03,
};
enum BitmapColorSpace : u8 {
Automatic = 0x00,
Rec709 = 0x01,
DCI_P3 = 0x02,
Rec2020 = 0x03,
};
enum SignedDistanceFieldMethod : u8 {
Neighbors_Multithreaded = 0x00,
Neighbors = 0x01,
Cached_Euclidean_Multithreaded = 0x02,
Cached_Euclidean = 0x03,
SSEDT = 0x04,
};
enum BitmapFormat : u16 {
a8_unorm = 0x00,
r8_unorm_rrr1 = 0x01,
r8_unorm_rrrr = 0x02,
r8g8_unorm_rrrg = 0x03,
unused1 = 0x04,
unused2 = 0x05,
b5g6r5_unorm = 0x06,
unused3 = 0x07,
b5g6r5a1_unorm = 0x08,
b4g4r4a4_unorm = 0x09,
b8g8r8x8_unorm = 0x0A,
b8g8r8a8_unorm = 0x0B,
unused4 = 0x0C,
DEPRECATED_dxt5_bias_alpha = 0x0D,
bc1_unorm_dxt1 = 0x0E,
bc2_unorm_dxt3 = 0x0F,
bc3_unorm_dxt5 = 0x10,
DEPRECATED_a4r4g4b4_font = 0x11,
unused7 = 0x12,
unused8 = 0x13,
DEPRECATED_SOFTWARE_rgbfp32 = 0x14,
unused9 = 0x15,
r8g8_snorm_v8u8 = 0x16,
DEPRECATED_g8b8 = 0x17,
r32g32b32a32_float_abgrfp32 = 0x18,
r16g16b16a16_float_abgrfp16 = 0x19,
r16_float_rrr1_16f_mono = 0x1A,
r16_float_r000_16f_red = 0x1B,
r8g8b8a8_snorm_q8w8v8u8 = 0x1C,
r10g10b10a2_unorm_a2r10g10b10 = 0x1D,
r16g16b16a16_unorm_a16b16g16r16 = 0x1E,
r16g16_snorm_v16u16 = 0x1F,
r16_unorm_rrr0_L16 = 0x20,
r16g16_unorm_r16g16 = 0x21,
r16g16b16a16_snorm_signedr16g16b16a16 = 0x22,
DEPRECATED_dxt3a = 0x23,
bc4_unorm_rrrr_dxt5a = 0x24,
bc4_snorm_rrrr = 0x25,
DEPRECATED_dxt3a_1111 = 0x26,
bc5_snorm_dxn = 0x27,
DEPRECATED_ctx1 = 0x28,
DEPRECATED_dxt3a_alpha_only = 0x29,
DEPRECATED_dxt3a_monochrome_only = 0x2A,
bc4_unorm_000r_dxt5a_alpha = 0x2B,
bc4_unorm_rrr1_dxt5a_mono = 0x2C,
bc5_unorm_rrrg_dxn_mono_alpha = 0x2D,
bc5_snorm_rrrg_dxn_mono_alpha_signed = 0x2E,
bc6h_uf16 = 0x2F,
bc6h_sf16 = 0x30,
bc7_unorm = 0x31,
d24_unorm_s8_uint_depth_24 = 0x32,
r11g11b10_float = 0x33,
r16g16_float = 0x34,
};
enum BitmapCurve : u8 {
unknown = 0x00,
xRGB = 0x01,
gamma_2 = 0x02,
linear = 0x03,
offset_log = 0x04,
sRGB = 0x05,
Rec709 = 0x06,
};
enum BitmapUsageFlag : u8 {
ignore_curve_override = 0x00,
do_not_allow_size_optimization = 0x01,
swap_axes = 0x02,
pre_filter_cubemaps = 0x03,
};
enum BitmapSlicer : u8 {
automatically_determine_slicer = 0x00,
no_slicing = 0x01,
color_plate_slicer = 0x02,
cube_map_slicer = 0x03,
color_grading_slicer = 0x04,
};
enum BitmapPacker : u8 {
no_packing = 0x00,
sprite_packing = 0x01,
sprite_packing_if_needed = 0x02,
_3d_pack = 0x03,
};
enum BitmapSmallestMip : u8 {
_1_pixel = 0x00,
_2_pixel = 0x01,
_4_pixel = 0x02,
_8_pixel = 0x03,
_16_pixel = 0x04,
_32_pixel = 0x05,
_64_pixel = 0x06,
_128_pixel = 0x07,
_256_pixel = 0x08,
_512_pixel = 0x09,
_1024_pixel = 0x0A,
};
enum Swizzle : u8 {
default = 0x00,
source_red_channel = 0x01,
source_green_channel = 0x02,
source_blue_channel = 0x03,
source_alpha_channel = 0x04,
set_to_1 = 0x05,
set_to_0 = 0x06,
set_to_0_5 = 0x07,
Random = 0x08,
one_minus_source_red_channel = 0x09,
one_minus_source_green_channel = 0x0A,
one_minus_source_blue_channel = 0x0B,
one_minus_source_alpha_channel = 0x0C,
negative_source_red_channel = 0x0D,
negative_source_green_channel = 0x0E,
negative_source_blue_channel = 0x0F,
negative_source_alpha_channel = 0x10,
};
bitfield BitmapDicerFlag {
convert_plate_color_key_to_alpha_channel : 1;
rotate_cube_map_to_match_directX_format : 1;
sprites_shrink_elements_to_smallest_non_zero_alpha_region : 1;
sprites_shrink_elements_to_smallest_non_zero_color_and_alpha_region : 1;
unsigned_signed_scale_and_bias : 1;
color_grading_sRGB_correction : 1;
color_grading_Rec709_correction : 1;
};
bitfield BitmapDownsampleFlag {
sprites : 1;
pre_multiply_alpha : 1;
post_divide_alpha : 1;
height_map : 1;
detail_map : 1;
_signed : 1;
illum_map : 1;
zbump_map : 1;
cubemap : 1;
calculate_spec_power : 1;
downsample_bumps_in_angular_space : 1;
standard_orientation_of_normals_in_angular_space_and_renormalize : 1;
generate_rgb_luminance_into_alpha_channel : 1;
};
bitfield BitmapPackerFlag {
shrink_sprite_texture_pages_tightly_to_content : 1;
};
bitfield BitmapDataResourceFlags {
Contains_3D_Texture : 1;
CPU_Gameplay_Required : 1;
Single_Mip_Texture : 1;
UI_Texture : 1;
};
bitfield BitmapGroupFlags {
bitmap_is_tiled : 1;
use_less_blurry_bump_map : 1;
dither_when_compressing : 1;
generate_random_sprites : 1;
ignore_alpha_channel : 1;
alpha_channel_stores_transparency : 1;
preserve_alpha_channel_in_mipmaps : 1;
only_use_on_demand : 1;
apply_max_resolution_after_slicing :1;
pre_filter_cubemaps : 1;
has_valid_min_and_max_values : 1;
SDF_Only_Store_Inside_values : 1;
SDF_Store_Direction : 1;
SDF_Store_Initial_Values_In_Alpha_Channel : 1;
Has_CUstom_Mipmaps : 1;
Validate_Has_Custom_Mipmaps : 1;
Is_Light_Probes : 1;
pad1 : 1;
pad2 : 1;
pad3 : 1;
pad4 : 1;
pad5 : 1;
pad6 : 1;
pad7 : 1;
pad8 : 1;
};
bitfield BitmapFlags {
power_of_two_dimension : 1;
compressed : 1;
swap_axes : 1;
mutable_at_runtime : 1;
pad1 : 1;
pad2 : 1;
pad3 : 1;
pad4 : 1;
pad5 : 1;
};
struct Data_Block {
u32 Size;
u16 Padding;
u16 Section;
u64 Offset;
};
struct Tag_Def_Structure {
s64 GUID_1;
s64 GUID_2;
u16 Type;
u16 Unk_0x12;
s32 TargetIndex;
s32 FieldBlock;
u32 FieldOffset;
};
struct Tag_Dependency {
char GroupTag[4] [[format("std::string::reverse")]];
u32 NameOffset;
u64 AssetID;
u32 GlobalID;
u32 Unk_0x14;
};
struct Data_Reference {
s32 ParentStructIndex;
s32 Unk_0x04;
s32 TargetIndex;
s32 FieldBlock;
u32 FieldOffset;
};
struct TagReference {
s64 GlobalHandle;
s32 ref_id_int;
s32 ref_id_sub;
s32 ref_id_center_int;
char TagGroupRev[4] [[format("std::string::reverse")]];
s32 local_handle;
};
struct Tag_Fixup_Reference {
s32 FieldBlock;
u32 FieldOffset;
u32 NameOffset;
s32 DependencyIndex;
TagReference tagreference @ header.HeaderSize + datablocks[FieldBlock].Offset + FieldOffset;
};
struct RealARgbColor {
float A;
float R;
float G;
float B;
};
struct RealRgbColor {
float R;
float G;
float B;
};
struct Bitmap_Resource_Handle {
s32 pixels[6]; // sum of these equals pixel count.
u32 hardware_format;
s8 tileMode;
s8 format;
BitmapDataResourceFlags bitmap_data_resource_flags;
s8 Alignment_Bits;
u8 highResMipCountAndFlags;
u8 mipCountPerArraySlice;
char generated_padff1b[6];
s64 runtime_data;
char streamingData[20];
s32 generated_padb266;
};
struct BitmapBlock {
u16 width;
u16 height;
u16 depth;
BitmapType Bitmap_Type;
u8 generated_paddca;
BitmapFormat bitmap_format;
BitmapFlags bitmap_flags;
s8 mipmap_count;
BitmapCurve bitmap_curve;
u16 generated_pad8fee;
float streaming_scale;
s16 source_width;
s16 source_height;
char bitmap_resource_handle_size[12];
s32 bitmap_resource_handle_count;
Bitmap_Resource_Handle bitmap_resource_handle[bitmap_resource_handle_count];
};
struct BitmapUsage {
s32 name;
s32 editor_group;
u32 source_gamma;
BitmapCurve bitmap_curve;
BitmapUsageFlag bitmap_usage_flag;
BitmapSlicer bitmap_slicer;
BitmapDicerFlag bitmap_dicer;
BitmapPacker bitmap_packer;
BitmapPackerFlag bitmap_packer_flags;
BitmapType bitmap_type;
s8 mipmap_limit;
BitmapSmallestMip bitmap_smallest_mip;
BitmapDownsampleFilter bitmap_downsample_filter;
s8 filter_radius_bias;
char generated_pad122e[1];
BitmapDownsampleFlag bitmap_downsample_flag;
char generated_pad5ee3[2];
RealRgbColor sprite_background_color;
Swizzle swizzle_red;
Swizzle swizzle_green;
Swizzle swizzle_blue;
Swizzle swizzle_alpha;
BitmapFormat bitmap_formats;
BitmapColorSpace source_color_space;
BitmapColorSpace target_color_space;
};
struct BitmapGroupSprite {
u32 bitmap_index;
char generated_pad2095[2];
s32 left;
s32 right;
s32 top;
s32 bottom;
s64 real_point_2D;
};
struct BitmapGroupSequence {
char name[32];
u32 first_bitmap_index;
u32 bitmap_count;
char sprites[16];
s32 sprite_count;
BitmapGroupSprite Sprites[sprite_count];
};
struct Bitm {
u32 Usage;
s32 UsageID;
s32 Package;
s32 texture_group;
BitmapGroupFlags flags;
u16 sprite_spacing;
u16 mip_sample_count;
float bump_map_height;
float blur_factor;
u32 blur;
u32 mipmap_blur;
curve_mode curvemode;
s8 max_mipmap_level;
u16 max_resolution;
BitmapForcedFormat force_bitmap_format;
SignedDistanceFieldMethod sdfgeneration;
s8 target_platform;
u16 spread_factor;
u16 generated_pad8ed2;
char usage_override[16];
s32 usage_override_count;
BitmapUsage bitmap_usage[usage_override_count];
char manual_sequence[16];
s32 manual_sequences_count;
BitmapGroupSequence manual_sequences[manual_sequences_count];
char source_data[24];
char source_path[20];
u64 source_checksum;
RealARgbColor min_color;
RealARgbColor max_color;
char sequence[16];
s32 sequences_count;
BitmapGroupSequence sequences[sequences_count];
char bitmapstart[16];
s32 bitmap_block_count;
BitmapBlock bitmap_block[bitmap_block_count];
char RawDDSData[header.ActualResoureDataSize];
};
struct InternalStruct {
s64 vtablespace;
u32 global_tag_id;
char local_tag_handle[4];
};
// TAG LAYOUT
Header header @ 0x00;
Tag_Dependency Dependencies[header.DependencyCount] @ 0x50;
Data_Block datablocks[header.DataBlockCount] @ header.DependencyCount * 0x18 + 0x50;
Tag_Def_Structure tagdefstructure[header.TagStructCount] @ header.DependencyCount * 0x18 + 0x50 + header.DataBlockCount * 0x10;
Data_Reference Data_References[header.DataReferenceCount] @ header.DependencyCount * 0x18 + 0x50 + header.DataBlockCount * 0x10 + header.TagStructCount * 0x20;
Tag_Fixup_Reference tagfixupreference[header.TagReferenceCount] @ header.DependencyCount * 0x18 + 0x50 + header.DataBlockCount * 0x10 + header.TagStructCount * 0x20 + header.DataReferenceCount * 0x14;
char ZoneSet[header.ZoneSetDataSize] @ header.HeaderSize - header.ZoneSetDataSize; // zonesets kinda make no sense
InternalStruct internalstruct @ header.HeaderSize;
Bitm bitmap @ header.HeaderSize + 16;

View File

@@ -1,5 +1,6 @@
#pragma author Surasia
#pragma description Halo Infinite HavokScript 5.1 "luas" file
#pragma description Halo Infinite HavokScript 5.1 "luas"
#pragma magic [ 75 63 73 68 ] @ 0x00
import std.io;
import std.mem;
@@ -26,7 +27,7 @@ enum lua_endian : u8 {
little_endian = 1,
big_endian = 0,
};
enum lua_numbertype : u8 {
_float = 0,
_int32 = 1,
@@ -136,7 +137,7 @@ enum HksOpCode : s8 {
GETSLOT_D,
GETGLOBAL_MEM,
};
enum HksType : u8
{
TNIL,
@@ -212,10 +213,10 @@ struct LuaConstant {
}
else if (type == HksType::TLIGHTUSERDATA) {
s64 userdata;
}
}
else {
s64 data;
}
}
};
struct HksLocal {
@@ -226,7 +227,7 @@ struct HksLocal {
struct LuaFunction {
s32 upvaluecount;
s32 paramcount;
s8 isVarArg;
@@ -238,7 +239,7 @@ struct LuaFunction {
}
LuaInstruction instructions[instruction_count];
s32 constantCount;
LuaConstant constants[constantCount];;
LuaConstant constants[constantCount];
s32 HasDebugInfo;
if (HasDebugInfo != 0) {
u32 LineCount;
@@ -422,7 +423,7 @@ struct LuaScriptTagDefinition {
LuaHeader lua_header;
try {
char pad[14];
LuaReferencedTagContainer referencedTags[referencedTags_count.count];
LuaReferencedTagContainer referencedTags[referencedTags_count.count];
} catch {
std::print("This file does not support referenced Tags.");
}
@@ -438,4 +439,4 @@ Data_Reference Data_References[header.DataReferenceCount] @ header.DependencyCou
Tag_Fixup_Reference tagfixupreference[header.TagReferenceCount] @ header.DependencyCount * 0x18 + 0x50 + header.DataBlockCount * 0x10 + header.TagStructCount * 0x20 + header.DataReferenceCount * 0x14;
char ZoneSet[header.ZoneSetDataSize] @ header.HeaderSize - header.ZoneSetDataSize;
InternalStruct internalstruct @ header.HeaderSize;
LuaScriptTagDefinition lua_script @ header.HeaderSize + 16;
LuaScriptTagDefinition lua_script @ header.HeaderSize + 16;

View File

@@ -0,0 +1,78 @@
#pragma author Surasia
#pragma description Halo Infinite Module
#pragma array_limit 0
#pragma pattern_limit 0
#pragma magic [ 6D 6F 68 64 ] @ 0x00
import std.string;
struct ModuleHeader
{
char magic[4];
s32 version;
s64 moduleId;
u32 fileCount;
s32 manifest0Count;
s32 manifest1Count;
s32 manifest2Count;
s32 resourceIndex;
u32 stringSize;
u32 resourceCount;
u32 blockCount;
u64 buildVersion;
s64 hd1Delta;
u64 dataSize;
};
struct ModuleFile
{
u32 resourceCount;
s32 parentIndex;
s16 pad;
u16 blockCount;
s32 blockIndex;
s32 resourceIndex;
char class[4] [[format("std::string::reverse")]];
u64 dataOffsetBytes;
u64 dataOffset = dataOffsetBytes & 0x0000FFFFFFFFFFFF [[export]];
u16 dataOffsetFlags = dataOffsetBytes >> 48 [[export]];
u32 totalCompressedSize;
u32 totalUncompressedSize;
u32 globalTagId;
u32 uncompressedHeaderSize;
u32 uncompressedTagDataSize;
u32 uncompressedResourceDataSize;
u32 uncompressedActualResourceDataSize;
u32 resourceBlockCount;
u32 nameOffset;
s32 parentResource;
u64 assetChecksum;
u64 assetId;
};
struct ModuleBlock
{
u32 compressedOffset;
u32 compressedSize;
u32 decompressedOffset;
u32 decompressedSize;
bool compressed;
s24 pad;
};
struct Module
{
ModuleHeader module_header;
ModuleFile files[module_header.fileCount];
$ = $ + 8;
s32 resources[module_header.resourceCount];
ModuleBlock blocks[module_header.blockCount];
padding[while($[$] == 0)];
std::print("Compressed Tag Data starts at: {}", $);
};
Module module_root @ 0x00;

169
patterns/hinf_tag.hexpat Normal file
View File

@@ -0,0 +1,169 @@
#pragma author Surasia
#pragma description Halo Infinite Tag
#pragma magic [ 75 63 73 68 ] @ 0x00
import std.string;
import type.guid;
u32 fileStart = 0;
enum TagSectionType : u16
{
header,
tagData,
resourceData
};
enum TagStructType : u16
{
mainStruct,
tagBlock,
resource,
custom,
literal
};
struct TagHeader
{
char magic[4];
s32 version;
u64 hash;
u64 checksum;
u32 dependencyCount;
u32 dataBlockCount;
u32 tagStructCount;
u32 dataReferenceCount;
u32 tagReferenceCount;
u32 stringTableSize;
u32 zoneSetDataSize;
u32 unknown0;
u32 headerSize;
fileStart = headerSize;
u32 dataSize;
u32 resourceDataSize;
u32 actualResourceDataSize;
u8 headerAlignment;
u8 tagDataAlignment;
u8 resourceDataAlignment;
u8 actualResourceAlignment;
u32 unknown1;
};
struct TagDependency
{
char tagGroup[4] [[format("std::string::reverse")]];
u32 nameOffset;
u64 assetId;
u32 globalId;
u32 parentTag;
};
struct TagDataBlock
{
u32 entrySize;
u16 pad;
TagSectionType section;
u64 offset;
if (section == TagSectionType::tagData)
{
char dataBlock[entrySize] @ fileStart + offset;
}
};
struct TagStruct
{
type::GUID guid;
TagStructType type;
u16 unknown0;
s32 targetIndex;
s32 fieldBlockIndex;
u32 fieldOffset;
};
struct TagDataReference
{
s32 parentStructIndex;
s32 unknown0;
s32 targetIndex;
s32 fieldBlockIndex;
u32 fieldOffset;
};
struct TagReference
{
s32 fieldBlockIndex;
u32 fieldOffset;
u32 nameOffset;
s32 dependencyIndex;
};
struct TagZonesetHeader
{
s32 version;
u32 zonesetCount;
u32 footerCount;
s32 parentCount;
};
struct TagZonesetInstanceHeader
{
s32 stringId;
u32 tagCount;
u32 parentCount;
u32 footerCount;
};
struct TagZonesetTag
{
u32 globalId;
s32 stringId;
};
struct TagZonesetInstance
{
TagZonesetInstanceHeader header;
TagZonesetTag tags[header.tagCount];
TagZonesetTag footers[header.footerCount];
s32 parents[header.parentCount];
};
struct TagZoneset
{
TagZonesetHeader zoneset_header;
TagZonesetInstance instances[zoneset_header.zonesetCount];
};
struct Tag
{
TagHeader header;
TagDependency dependencies[header.dependencyCount];
TagDataBlock data_blocks[header.dataBlockCount];
TagStruct tag_structs[header.tagStructCount];
TagDataReference data_references[header.dataReferenceCount];
TagReference tag_references[header.tagReferenceCount];
TagZoneset zonesets;
if (header.headerSize != $)
{
std::print("Header size is wrong, additional data in tag");
$ = header.headerSize;
std::print("Data offset now at: {}", $);
}
};
Tag tag_root @ 0x00;

69
patterns/hsdt.hexpat Normal file
View File

@@ -0,0 +1,69 @@
// Analyzed and reverse engineered by xtex
#pragma author xtex
#pragma description HiSilicon HSDT device-tree table
#pragma endian little
#pragma magic [ 48 53 44 54 ] @ 0x00
import std.sys;
import std.mem;
u32 dt_hdr_offset;
if (std::mem::read_unsigned(4096, 4, std::mem::Endian::Little) == 0x54445348) {
// for DTS dumped from UPDATE.APP
// everything is offseted 4096 bytes
dt_hdr_offset = 0x1000;
} else {
// for DTS dumped from Huawei device
// /dev/block/bootdevice/by-name/dts
dt_hdr_offset = 0;
}
struct dt_table_t {
u32 magic [[comment("should always be 0x54445348")]];
std::assert(magic == 0x54445348, "bad dt_table_t magic");
u32 version [[comment("should always be 1")]];
u32 num_entries;
};
struct dt_entry_t { // 0x28 bytes
u8 board_id[4] [[sealed, format("format_board_id")]];
// in my reverse project, undefined0 is always zero
// and is not used by the fastboot
u32 undefined0 [[sealed]];
std::assert_warn(undefined0 == 0, "undefined0 is not zero");
u32 dtb_len;
// VRL is for verifying the DTB
// set VRL to 0 to skip verifying
u32 vrl_len;
u32 dtb_offset;
u32 vrl_offset;
u8 undefined1[16] [[sealed]];
// the real GZIPped DTB should start at dtb_offset + 4096
u8 dtb[dtb_len] @ (dtb_offset + 4096 + dt_hdr_offset) [[sealed]];
if (vrl_len != 0)
u8 vrl[vrl_len] @ (vrl_offset + dt_hdr_offset) [[sealed]];
} [[format("format_dt_entry")]];
fn format_dt_entry(auto dt_entry) {
if (dt_entry.vrl_len != 0) {
return std::format(
"{}, with VRL",
format_board_id(dt_entry.board_id)
);
} else {
return format_board_id(dt_entry.board_id);
}
};
fn format_board_id(auto board_id) {
return std::format(
"<0x{:02x} 0x{:02x} 0x{:02x} 0x{:02x}>",
board_id[0], board_id[1],
board_id[2], board_id[3]
);
};
dt_table_t dt_hdr @ (dt_hdr_offset + 0x0);
dt_entry_t dt_entries[dt_hdr.num_entries] @ (dt_hdr_offset + 0xc);

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