Compare commits

..

107 Commits

Author SHA1 Message Date
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
Nik
9af8d7e693 includes/std: Added back #pragma once to mem library 2024-02-27 20:28:02 +01:00
WerWolv
dac2e0f786 patterns: Fixed a few errors 2024-02-25 22:59:32 +01:00
Nik
f70b7066b9 includes: Switch over to import statements (#224)
* Update includes and patterns to new import system

* Update namespaces to new syntax
2024-02-25 22:04:41 +01:00
WerWolv
3f44a743e8 yara: Added advanced analysis rules 2024-02-25 11:29:59 +01:00
WerWolv
834e5261b3 tests: Fixed tests not building 2024-02-18 13:07:04 +01:00
Nik
0e2966f10d includes/std: Added missing std::core::set_pattern_comment function 2024-02-09 13:23:51 +01:00
Nik
b2bc248447 includes/hex: SectionId -> Section 2024-01-31 08:24:03 +01:00
Nik
e6589ecba1 includes/std: Make std::mem::read_string take in a larger size 2024-01-31 08:22:25 +01:00
apewo
f75ba4b6ee patterns/pe: Add extra MIME Type (#220)
add pe mime

Co-authored-by: John Doe <bla@bla.bla>
2024-01-29 18:36:21 +01:00
Nik
cf18580960 includes/hex: Added decompress functions 2024-01-27 17:05:08 +01:00
lucia c
e7d1973957 patterns: Added SWF header pattern (#219)
* patterns: Added pattern for SWF files.

* Added test file for SWF header.

* Update README with SWF file type.
2024-01-27 15:53:16 +01:00
t1hq
35cc68544b encodings: Add custom encoding file for Big5 (#218)
* add big5 encoding table

* add notes for big5 encoding, and how to import custom encoding file
2024-01-27 11:18:47 +01:00
Nik
41d8967deb patterns/pyc: Remove unused function 2024-01-20 22:14:47 +01:00
pew
658ec20b37 patterns: Add .ras pattern (#216)
* Add simple .ras file pattern

* Update ras.hexpat

* Update README.md

* Add .ras test file

* Update ras.hexpat

* Update ras.hexpat

* Update ras.hexpat

* Update ras.hexpat
2024-01-10 00:38:18 +01:00
paxcut
fb5fcbafc1 includes/type: Changes to magic type to include address of failed asserts. (#217) 2024-01-10 00:36:17 +01:00
Brandon Maier
6f7988e96e patterns: Added Xilinx boot images (#210)
* Adds pattern for Xilinx's Zynq UltraScale+ Boot Image format.
* Boot images are generated by Xilinx's `bootgen` tool.
* Spec: Xilinx UG1283 https://docs.xilinx.com/r/en-US/ug1283-bootgen-user-guide/Zynq-UltraScale-MPSoC-Boot-and-Configuration
* Add test file generated as follows
  - Build bootgen tool from https://github.com/Xilinx/bootgen
  - Create dummy data with `dd if=/dev/zero of=image.bin count=1`
  - Create bif with `echo "img: {image.bin}" >image.bif`
  - Create test bin with
    `./bootgen -arch zynqmp -image image.bif -o xilinx_bootgen.hexpat.bin`
2023-12-28 18:32:13 +01:00
g4ngli0s
0a631f0c1f patterns/pe: Fix BaseRelocationBlock count inside BaseRelocationTable (#212) 2023-12-28 18:31:53 +01:00
EvelynTSMG
5942897c29 patterns/ffx: Pull in latest updates (#209)
* Add Final Fantasy X patterns

* Update README

* Fix: github dum

* Add Bastion patterns

* git: update submodules

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2023-12-22 14:02:37 +01:00
utkumaden
a7e6209791 patterns: Added gITF pattern(#205)
* Create gltf.hexpat

Added glTF binary file pattern.

* Add a test file for the glTF pattern.

* Renamed the test file to fit the pattern file name.

* Fixed typo in documentation.
2023-12-07 17:09:25 +01:00
EvelynTSMG
294f69fa36 patterns: Add Bastion patterns (#207)
* Add Final Fantasy X patterns

* Update README

* Fix: github dum

* Add Bastion patterns

---------

Co-authored-by: Nik <werwolv98@gmail.com>
2023-12-07 16:38:32 +01:00
gmestanley
1ea12cd4bd patterns/pe: Bringing over the massively improved version of pe.hexpat (#204)
* Add files via upload

* Update README.md

Added nes.hexpat to list of hex patterns

* Fix indenting of hex patterns list

Moved nes.hexpat below NE.hexpat

* Update README.md

Fixed indenting of PP pattern file's description being wrong

* Added x-msdownload MIME type to PE description

* Made indenting & code of ips.hexpat better

* Improvements to gb.hexpat

* Urgent fix to ips.hexpat

* Urgent fix to gb.hexpat

* Massive pe.hexpat improvement

* Replaced virtualDifference with relativeVirtualDifference

* Fixing unnecessary pattern_limit
2023-12-07 16:36:50 +01:00
Surasia
8129504dcb patterns/hinf_luas: Added pattern for reading HavokScript 5.1 Bytecode from Halo Infinite (#203)
* patterns/hinf_luas: Added pattern for reading HavokScript 5.1 Bytecode from Halo Infinite

* Parses Header and Structures of the parent tag
* Reads Bytecode types and arguments
* Reads Constants and Debug Info
* Reads Referenced Tags in the File

* readme: fix relative link
2023-12-07 16:36:27 +01:00
klirktag
22e30cfef9 patterns/mp4: Add STBL-box children (#202)
add STBL-box children
2023-12-07 16:36:07 +01:00
EvelynTSMG
9b819cf392 patterns: Add Final Fantasy X patterns (#197)
* Add Final Fantasy X patterns

* Update README

* Fix: github dum
2023-11-20 11:54:56 +01:00
klirktag
3277821153 patterns/mp4: Support mp4a and avc1 codec boxes (#195)
add support for mp4a and avc1 codec boxes, and sample-time-to-sample box
2023-11-15 22:26:10 +01:00
paxcut
f23dbbb565 includes/std: Fixed std::string::replace not replacing sequences correctly (#198)
fix:  [Bug] std::string::replace("aa", "aa", "") returns "a" #1408
2023-11-15 22:25:34 +01:00
Surasia
52f7d9e77a patterns/hinf_bitmap: Added pattern for parsing Halo Infinite bitmap files (#194)
* patterns/hinf_bitmap: Added pattern for parsing Halo Infinite bitmap files

* Parses the header of all Halo Infinite files which includes related "dependencies", datablocks, structure references
* Read bitmap sequence data, including bitmap index, complete index, sprite info
* Find the width/height and DDS Format of the raw texture, which can then be parsed into usable DDS textures
* Locates raw DDS block info

* Nulled out the DDS section of the bitmap
2023-11-14 00:20:32 +01:00
klirktag
99df77baf2 patterns/mp4: Add childbox support for STBL boxes (#192)
* find childboxes in stbl

* add implementation for SampleDescriptionBox
2023-11-14 00:06:50 +01:00
klirktag
d7b0819ff0 patterns/mp4: Make handler_type into a char[4], which reflects how it is used (#193)
make handler_type into a char[4], which reflects how it is used
2023-11-14 00:06:31 +01:00
Nik
70f491d2fa includes/type: Fixed formatting of time_t values in big endian patterns 2023-11-12 22:18:46 +01:00
Hugo
08680a6544 patterns/bplist: Added pattern file for Apple’s binary property list format (bplist) (#190)
* Added pattern file for Apple’s binary property list format (bplist)

* renamed some stuff and improved error messages

* added error handling for object size special case (0x0F)
2023-11-12 01:02:50 +01:00
Ange Albertini
23bc36c4bd patterns/selinux: Detailed SELinux config bitfield (#188) 2023-11-06 16:30:53 +01:00
Ange Albertini
8ae778944d patterns/se: Increased array limit (#187)
Increased array limit
2023-11-01 20:19:10 +01:00
klirktag
7e6a5d3bfa patterns/mp4: Added stbl box (#185) 2023-10-29 19:54:23 +01:00
Hugo
27e55d2e6d patterns/zip: Added parsing of extra field (#182)
* zip pattern: Improved fallback method for finding eocd. Added test data to cover this edge case

* zip pattern: added parsing of extra field
2023-10-29 19:47:11 +01:00
Benjamin Gilbert
e0a602c10a patterns/jpeg: Small improvements (#184)
* patterns/jpeg: exclude EOI marker from SOS image data

* patterns/jpeg: use type::Magic for magic numbers

* patterns/jpeg: add RGB component IDs

* patterns/jpeg: add struct for APP14 marker

* patterns/jpeg: add definition for COM marker

* patterns/jpeg: add some format_read() for better legibility
2023-10-29 19:46:51 +01:00
AdventureT
8748646016 patterns/CrashLvl: Update Crash Back in Time level format (#186)
* 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
2023-10-29 19:46:28 +01:00
iTrooz
4a52ee4cf8 patterns: add UEFI Boot Entry pattern (#183)
add uefi_boot_entry pattern
2023-10-24 23:04:49 +02:00
iTrooz
e517e3534b patterns: fix description pragmas (#181) 2023-10-24 17:25:43 +02:00
DmitriLeon2000
edd0aa9a2f patterns: Add .fas and .was pattern files (Oska DeskMates) (#176)
* Add .fas and .was pattern files (Oska DeskMates)

* Update .was pattern file

* Update .was/.wa3 pattern file

* Update README.md

* Update README.md

* Update .fas & .was pattern files

* Update README.md

* Update fas_oskasoftware_old.hexpat

* Added WAS test file

* Update WAS test file

* Update was_oskasoftware.hexpat
2023-10-24 07:35:38 +02:00
Hugo
a992d1ba92 patterns/zip: Improved fallback method for finding eocd (#177)
zip pattern: Improved fallback method for finding eocd. Added test data to cover this edge case
2023-10-24 07:35:02 +02:00
leen
6fbdcac556 patterns/ip: Fix payload size when ip header or tcp header has options in ip.hexpat (#178) 2023-10-24 07:34:35 +02:00
itsmeow
47fce1628f patterns: Add ARIA2 Control format (#179) 2023-10-24 07:33:56 +02:00
Nik
9b152ae560 includes/std: Fixed doc comment of std::math::atan2 2023-10-22 21:25:14 +02:00
Nik
6b136b7fc6 includes/std: Fixed std::math::atan2 not taking correct arguments 2023-10-22 21:23:51 +02:00
gmestanley
93494a19a4 patterns: Better code + credit given for ips.hexpat & better readme (#174)
* Add files via upload

* Update README.md

Added nes.hexpat to list of hex patterns

* Fix indenting of hex patterns list

Moved nes.hexpat below NE.hexpat

* Update README.md

Fixed indenting of PP pattern file's description being wrong

* Added x-msdownload MIME type to PE description

* Made indenting & code of ips.hexpat better

* Improvements to gb.hexpat

* Urgent fix to ips.hexpat

* Urgent fix to gb.hexpat
2023-10-15 21:21:19 +02:00
H0L0
4fd710e23e patterns/flac: Fix SEEKTABLE metadata block (#173)
Add SEEKTABLE to blocktype check
2023-10-15 21:19:34 +02:00
Nik
44842dc44b includes/std: Added std::mem::set_section_size (#175) 2023-10-15 21:15:12 +02:00
HalfInner
056035c540 patterns/zip: Add parsing local file header with minor adjustment (#172)
patterns/zip: add parsing local file header, and another adjustmenst

Add missing parsing for local file headers
Add compression method
Minor adjustments: removed black colors, marked magic ids
2023-10-06 12:20:30 +02:00
Diego
5ad8e15afc patterns/shp: Added ESRI patterns (#170)
* add .shp and .shx patterns

* add tests
2023-10-06 12:20:11 +02:00
Nik
39c4d11404 patterns/uefi: Remove invalid MIME pragma 2023-10-05 08:54:59 +02:00
Benjamin Gilbert
815bd5f7f3 git: Minor readme fixes (#168) 2023-09-26 16:51:31 +02:00
Benjamin Gilbert
917b05a9f2 patterns: Add DICOM (#162)
DICOM files specify a "transfer syntax" which defines the image
compression format, the encoding rules for the entire file, and any
special-case encoding rules for particular fields.  Many transfer syntaxes
have common design features, but a transfer syntax is allowed to use
completely custom encoding rules, and need not be publicly documented.

Explicitly reject transfer syntaxes we know we don't support: implicit VR
(uncommon), explicit VR big-endian (deprecated), deflate-compressed.
In all other cases, follow some general rules and hope it works out.

The large lookup functions were generated by a script, but I haven't
included the code here, since its input is hand-massaged data copied from
HTML tables.

Add a JPEG WSI test case from the WG26 2021 hackathon (CC0 license) and a
synthetic LE Explicit VLP case produced with img2dcm.
2023-09-26 16:51:02 +02:00
brliron
46a2cef993 patterns: Added Android VBMeta image pattern (#169) 2023-09-26 14:03:24 +02:00
Nik
bca25b1a78 includes/hex: Fixed duplicate variable name in hex::core::get_selection() function
Fixes #167
2023-09-25 07:22:06 +02:00
Benjamin Gilbert
7ecd6d87dd patterns/tiff: Support BigTIFF and tiled TIFF; bugfixes and cleanups (#159)
* patterns/tiff: show TIFF tag name/number in DirectoryEntry array

Don't require unfolding the array entry to see what tag it contains.

* patterns/tiff: show IFD number in IFD list

* patterns/tiff: add JPEGTables tag; correct name of ICC Profile tag

* patterns/tiff: add TIFFRational type

Rationals, uniquely, are primitives with two fields.  Add a struct to
represent this, rather than inlining them.

* patterns/tiff: use correct types for fields smaller than 4 bytes

Small fields are always left-aligned in the 4-byte Value Offset.  On
little-endian TIFFs we currently cheat this by declaring a 32-bit value
and letting little-endianness handle the semantics.  However, this adds
some extra conditionals, and misrepresents the resulting field as 32 bits.
Drop the cheat.

* patterns/tiff: add ValueOffset abstraction

We were using the field type to make assumptions about whether the Value
Offset is a Value or an Offset, which is incorrect.  If the Count
multiplied by the field size is larger than 4, the field is an Offset;
otherwise it's a Value.

Add display sugar for single-element arrays to avoid extra nesting.

* patterns/tiff: drop dead code

get_ifds_offsets() and BIG/LITTLE aren't used at all.  get_total_IFDs()
is only used for declaring the length of TIFFFile.IFDs, and isn't needed
because IFDs are structured as a linked list.

* patterns/tiff: drop set_endian()

The call in TIFFFile is redundant.  Drop both calls and open-code the
check at the top level, before executing any code.  The BigTIFF check
will eventually be added alongside this one.

Fail if we don't recognize the magic number.

* patterns/tiff: minor cleanups

* patterns/tiff: drop strip offset/byte count arrays from struct IFD

They're redundant with the fields in the DirectoryEntry array.  Also
they're buggy: they assume the field Value Offsets are always offsets,
which isn't true for single-strip IFDs, and they ignore a partial last
strip in multiple-strip IFDs.

* patterns/tiff: rewrite strip array generation

We're making extra work for ourselves by avoiding the type system.  Also,
by calculating the number of strips we expect rather than the number of
strips we actually have, we're miscounting and omitting any partial last
strip.

Instead, read the strip offsets and byte counts directly from the
IFDEntry array.

* patterns/tiff: add ImageData array for tiled IFDs

* patterns/tiff: increase variable widths for BigTIFF

Use 64-bit temporary variables for values that can be 64 bits in BigTIFF.

* patterns/tiff: support BigTIFF

* tests/patterns/test_data: add more TIFF tests
2023-09-24 20:04:20 +02:00
dn-ln
bf0d96db5f patterns/id3: Fix the error No variable named 'n' found. (#160) 2023-09-24 20:03:49 +02:00
paxcut
705900d38b includes/std: Fixed std::string::replace (#163)
The submitted fix may have been a work in progress version instead of the tested solution I intended to submit. Hopefully this time I'll get it right.
2023-09-24 19:58:04 +02:00
gmestanley
734afdf500 patterns: Added .nes pattern file (#166)
* Add files via upload

* Update README.md

Added nes.hexpat to list of hex patterns

* Fix indenting of hex patterns list

Moved nes.hexpat below NE.hexpat
2023-09-24 19:57:20 +02:00
Benjamin Gilbert
c0c117ac19 tests/patterns: support multiple test files for a pattern (#161)
Allow either a single test file in tests/patterns/${pattern}.hexpat.${ext},
as we do now, or multiple files in tests/patterns/${pattern}.hexpat/*.

Closes #158.
2023-09-10 09:56:25 +02:00
paxcut
7fba66a444 includes/std: Fixed std::string::replace truncating output incorrectly (#157) 2023-09-10 09:40:29 +02:00
Yury Ershov
8eed75d783 patterns/bson: Support for multiple documents per file (#156)
* BSON support multiple documents per file

BSON files can contain consecutive documents glued one after another. An example of these is MongoDB FTDC metrics export.

[`bsondump`](https://github.com/mongodb/mongo-tools/blob/master/bsondump/bsondump.go) can unpack this type of BSON documents.

* Add accidentally deleted lines
2023-09-10 09:39:32 +02:00
Kenichi Saita
81f4978656 patterns/vhdx: Various improvements (#154)
* Replaced right_to_left to bitfield_order

* Fixed type of ParentLocatorEntry (char -> char16)

* Fixed item address of MetadataTableEntry

* Improved RegionTableEntry# Please enter the commit message for your changes. Lines starting
2023-09-10 09:39:04 +02:00
iTrooz
b6e0557a1d patterns: put author and description inside each pattern (#155) 2023-08-28 12:32:23 +02:00
gmestanley
ba14dd0cb2 patterns: Adding IPS pattern and fixed PE magic file (#153)
* Update pe.hexpat

New improvement

* Add ips.hexpat via upload

* Add ips.hexpat.ips via upload

* Added IPS to README

* Mentioned Windows in portable_executable_magic
2023-08-27 00:38:30 +02:00
MatrixEditor
86f93dfdaf patterns: Added Ubiquiti firmware pattern (#145)
* Ubiquiti firmware pattern

* Added padding and crc32 fields

* Added unit test file

+ Renamed fields in partition struct
2023-08-16 23:28:01 +02:00
Justus Garbe
001900e3c2 patterns/pyc: Add a pattern for pyc files
Change name
2023-08-15 09:30:19 +02:00
Nik
6baae92553 includes/std: Added missing mem library include in ptr libary 2023-08-04 22:56:03 +02:00
Jason Shirk
520f9bcb22 patterns/pe: Fix DebugDirectory version field types (#146) 2023-08-04 01:14:49 +02:00
vikke1234
44b0392b78 patterns/fdt: Unflatten FDT (#144)
In order to have a better time viewing FDTs in the visualizer
scanner will now unflatten the FDT.

It could still be improved slightly by modifying FDTProps to
make their values be `u32`s and possibly detect whether they
should be u64s.
2023-08-04 01:11:20 +02:00
Nik
df2bd4e3f9 git: Run PatternLanguage webpage CI 2023-07-29 12:12:33 +02:00
Nik
7723cf55c6 patterns: Fixed wrong extensions for some patterns 2023-07-24 16:14:37 +02:00
Nik
caa2b6aaa6 patterns/fdt: Improved visualizing of data 2023-07-24 16:13:34 +02:00
lopqto
7344df7ff6 patterns/pyinstaller: Added PyInstaller pattern (#142) 2023-07-16 20:21:59 +02:00
Nik
df649d2e62 patterns/elf: Speed up section name querying 2023-07-14 21:52:47 +02:00
Nik
8710b9e66f scripts: Added basic Kaitai to ImHex Pattern converter 2023-07-14 17:08:49 +02:00
vikke1234
665c942329 patterns/fdt: Fixed typo (#141) 2023-07-14 12:18:27 +02:00
vikke1234
50f93d14ff patterns/fdt: Fix flattened device tree parsing (#140)
* Fix flattened device tree parsing

Fix parsing to support multiple FDTs in a file and
non-zero base addresses.

* Fix string parsing

Parent offset wasn't being taken into account
when looking for prop names.
2023-07-13 14:38:52 +02:00
Nik
ab43516517 includes/std: Allow std::mem::MagicSearch to work with non-zero base addresses 2023-07-13 12:10:54 +02:00
Nik
4587b465d4 includes/std: Fixed std::mem::eof() not working correctly with non-zero base addresses 2023-07-13 12:08:25 +02:00
Nik
75b2c7be7e includes/std: Fixed MagicSearch type 2023-07-13 12:06:02 +02:00
Ange Albertini
19dd39e7c0 patterns: Added SE Linux binary format pattern (#139)
* SE Linux policy binary

module, base, kernel and packages

* Updated README with SELinux patterns

* SELinux test files
2023-07-12 20:25:47 +02:00
Nik
ecd34d35b2 patterns/elf: Fixed p_data definition in Phdr structs 2023-07-12 14:10:01 +02:00
Nik
06366839aa includes/std: Added std::ByteSizedArray 2023-07-12 00:13:02 +02:00
Nik
e3c387d0cf patterns/3ds: Added 3DS Max pattern 2023-07-10 16:36:49 +02:00
brliron
5a7077412c patterns/bmp: Various improvements (#138)
- Add various version of the BitmapInfoHeader struct, and autodetect
  the correct one.
- Fix palette detection.
- Use BitmapInfoHeader::biSize to find the position of the palette / data.
2023-07-10 11:31:07 +02:00
WerWolv
d8a37b0579 tests: Added WAD test file 2023-07-09 10:05:47 +02:00
WerWolv
1f1b2b9c5b tests: Fixed name of afe2 test file 2023-07-09 10:05:40 +02:00
Nik
d1645d2dc2 patterns:/intel_hex: Allow Intel Hex pattern to support files with linux line endings 2023-07-09 00:39:23 +02:00
WerWolv
61ef68b12a tests: Added more test files 2023-07-09 00:31:48 +02:00
WerWolv
c52e5b959b patterns: Fixed intel hex pattern 2023-07-09 00:14:58 +02:00
WerWolv
4a62892411 tests: Added various new test files 2023-07-09 00:14:49 +02:00
Nemoumbra
fc9b4cdbc2 tests: Added ico test file (#137) 2023-07-08 23:33:20 +02:00
Nik
daa556db31 tests: Fixed name of jpeg test pattern 2023-07-08 23:15:42 +02:00
Nik
e01a832fab patterns/lua54: Fixed parameter named const 2023-07-08 23:07:05 +02:00
Nik
759708d446 patterns/png: Automatically name PNG chunks 2023-07-03 22:06:48 +02:00
Trevor Gross
82560e6d9d patterns: Add a pattern for zlib compression (#135)
Add a pattern for RFC 1950 zlib compression
2023-07-02 18:58:19 +02:00
209 changed files with 34772 additions and 3756 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

@@ -45,3 +45,12 @@ jobs:
repo: Documentation
owner: WerWolv
event_type: update_pl_docs
- name: ✉️ Update PatternLanguage Website
if: ${{ env.DISPATCH_TOKEN != '' }}
uses: mvasigh/dispatch-action@main
with:
token: ${{ secrets.DISPATCH_TOKEN }}
repo: PatternLanguageWeb
owner: WerWolv
event_type: rebuild_wasm

8
.gitmodules vendored
View File

@@ -1,4 +1,10 @@
[submodule "rules"]
path = yara/official_rules
url = https://github.com/Yara-Rules/rules
branch = master
branch = master
[submodule "patterns/ffx"]
path = patterns/ffx
url = https://gitlab.com/EvelynTSMG/imhex-ffx-pats.git
[submodule "patterns/bastion"]
path = patterns/bastion
url = https://gitlab.com/EvelynTSMG/imhex-bastion-pats.git

View File

@@ -22,13 +22,18 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
| Name | MIME | Path | Description |
|------|------|------|-------------|
| 7Z | | [`patterns/7z.hexpat`](patterns/7z.hexpat) | 7z File Format |
| AFE2 | | [`patterns/afe2.hexpat`](patterns/afe2.hexpat) | Nintendo Switch Atmosphère CFW Fatal Error log |
| AR | `application/x-archive` | [`patterns/ar.hexpat`](patterns/ar.hexpat) | Static library archive files |
| ARM VTOR | | [`patterns/arm_cm_vtor.hexpat`](patterns/arm_cm_vtor.hexpat) | ARM Cortex M Vector Table Layout |
| Bencode | `application/x-bittorrent` | [`patterns/bencode.hexpat`](patterns/bencode.hexpat) | Bencode encoding, used by Torrent files |
| 3DS | | [`patterns/3ds.hexpat`](patterns/3ds.hexpat) | Autodesk 3DS Max Model file |
| 7Z | | [`patterns/7z.hexpat`](patterns/7z.hexpat) | 7z File Format |
| AFE2 | | [`patterns/afe2.hexpat`](patterns/afe2.hexpat) | Nintendo Switch Atmosphère CFW Fatal Error log |
| AR | `application/x-archive` | [`patterns/ar.hexpat`](patterns/ar.hexpat) | Static library archive files |
| 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 |
| Bencode | `application/x-bittorrent` | [`patterns/bencode.hexpat`](patterns/bencode.hexpat) | Bencode encoding, used by Torrent files |
| BMP | `image/bmp` | [`patterns/bmp.hexpat`](patterns/bmp.hexpat) | OS2/Windows Bitmap files |
| BSON | `application/bson` | [`patterns/bson.hexpat`](patterns/bson.hexpat) | BSON (Binary JSON) format |
| BIN | | [`patterns/selinux.hexpat`](patterns/selinux.pat) | SE Linux modules |
| 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) |
| BSP | | [`patterns/bsp_goldsrc.hexpat`](patterns/bsp_goldsrc.hexpat) | GoldSrc engine maps format (used in Half-Life 1) |
| CCHVA | | [`patterns/cchva.hexpat`](patterns/cchva.hexpat) | Command and Conquer Voxel Animation |
| CCVXL | | [`patterns/ccvxl.hexpat`](patterns/ccvxl.hexpat) | Command and Conquer Voxel Model |
@@ -37,66 +42,86 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
| CHM | | [`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 flashback tapes level format |
| CrashLvl | | [`patterns/Crashlvl.hexpat`](patterns/Crashlvl.hexpat) | Crash Bandicoot - Back in Time (fan game) User created level format |
| DDS | `image/vnd-ms.dds` | [`patterns/dds.hexpat`](patterns/dds.hexpat) | DirectDraw Surface |
| DEX | | [`patterns/dex.hexpat`](patterns/dex.hexpat) | Dalvik EXecutable Format |
| DMG | | [`patterns/dmg.hexpat`](patterns/dmg.hexpat) | Apple Disk Image Trailer (DMG) |
| DS_Store | `application/octet-stream` | [`patterns/dsstore.hexpat`](patterns/dsstore.hexpat) | .DS_Store file format |
| 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 |
| 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 |
| 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 |
| FDT | | [`patterns/fdt.hexpat`](patterns/fdt.hexpat) | Flat Linux Device Tree blob |
| File System | | [`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 |
| 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 |
| 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 |
| GIF | `image/gif` | [`patterns/gif.hexpat`](patterns/gif.hexpat) | GIF image files |
| GZIP | `application/gzip` | [`patterns/gzip.hexpat`](patterns/gzip.hexpat) | GZip compressed data format |
| ICO | | [`patterns/ico.hexpat`](patterns/ico.hexpat) | Icon (.ico) or Cursor (.cur) files |
| Halo Bitmap || [`patterns/hinf_bitmap.hexpat`](patterns/hinf_bitmap.hexpat) | Halo Infinite Bitmap tag files |
| Halo HavokScript || [`patterns/hinf_luas.hexpat`](patterns/hinf_luas.hexpat) | Halo Infinite HavokScript 5.1 Bytecode |
| 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) |
| 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 |
| Java Class | `application/x-java-applet` | [`patterns/java_class.hexpat`](patterns/java_class.hexpat) | Java Class files |
| 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 |
| Lua 5.4 | | [`patterns/lua54.hexpat`](patterns/lua54.hexpat) | Lua 5.4 bytecode |
| 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 |
| NACP | | [`patterns/nacp.hexpat`](patterns/nacp.hexpat) | Nintendo Switch NACP files |
| 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 |
| 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 |
| 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 |
| PCAP | `application/vnd.tcpdump.pcap` | [`patterns/pcap.hexpat`](patterns/pcap.hexpat) | pcap header and packets |
| nes | | [`patterns/nes.hexpat`](patterns/nes.hexpat) | .nes file format |
| NotepadWindowState | | [`patterns/notepad-windowstate.hexpat`](patterns/notepad-windowstate.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 |
| PCAP | `application/vnd.tcpdump.pcap` | [`patterns/pcap.hexpat`](patterns/pcap.hexpat) | pcap header and packets |
| PCX | `application/x-pcx` | [`patterns/pcx.hexpat`](patterns/pcx.hexpat) | PCX Image format |
| PE | `application/x-dosexec` | [`patterns/pe.hexpat`](patterns/pe.hexpat) | PE header, COFF header, Standard COFF fields and Windows Specific fields |
| 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 |
| QBCL | | [`patterns/qbcl.hexpat`](patterns/qbcl.hexpat) | Qubicle voxel scene project file |
| QOI | `image/qoi` | [`patterns/qoi.hexpat`](patterns/qoi.hexpat) | QOI image files |
| Shell Link | `application/x-ms-shortcut` | [`patterns/lnk.hexpat`](patterns/lnk.hexpat) | Windows Shell Link file format |
| 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 |
| 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 |
| ReFS | | [`patterns/refs.hexpat`](patterns/refs.hexpat) | Microsoft Resilient File System |
| 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 |
| 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 |
| TAR | `application/x-tar` | [`patterns/tar.hexpat`](patterns/tar.hexpat) | Tar file format |
| 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 |
| Ubiquiti | | [`patterns/ubiquiti.hexpat`](patterns/ubiquiti.hexpat) | Ubiquiti Firmware (update) image |
| UEFI | | [`patterns/uefi.hexpat`](patterns/uefi.hexpat)` | UEFI structs for parsing efivars |
| UF2 | | [`patterns/uf2.hexpat`](patterns/uf2.hexpat) | [USB Flashing Format](https://github.com/microsoft/uf2) |
| VDF | | [`patterns/vdf.hexpat`](patterns/vdf.hexpat) | Binary Value Data Format (.vdf) files |
| VHDX | | [`patterns/vhdx.hexpat`](patterns/vhdx.hexpat) | Microsoft Hyper-V Virtual Hard Disk format |
| 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 |
| 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 |
| 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 |
| Xilinx BIT | | [`patterns/xilinx_bit.hexpat`](patterns/xilinx_bit.hexpat) | Xilinx FPGA Bitstreams |
| 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 |
| 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 |
### Scripts
@@ -110,9 +135,9 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
| Name | Path | Description |
|------|------|-------------|
| libstd | [`includes/std/*`](includes/std) | Pattern Language Standard Libaray |
| libtype | [`includes/type/*`](includes/type) | Various custom types with special formatters |
| libhex | [`includes/hex/*`](includes/hex) | Functions to interact with ImHex |
| libstd | [`includes/std/*`](includes/std) | Pattern Language Standard Library |
| libtype | [`includes/type/*`](includes/type) | Various custom types with special formatters |
### Yara rules
@@ -147,6 +172,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
| ASCII+OEM | [`encodings/ascii_oem.tbl`](encodings/ascii_oem.tbl) | ASCII encoding with Windows OEM characters |
| Baltic ISO | [`encodings/baltic_iso.tbl`](encodings/baltic_iso.tbl) | Baltic ISO encoding |
| Baltic Windows | [`encodings/baltic_windows.tbl`](encodings/baltic_windows.tbl) | Baltic Windows encoding |
| Big5 (Traditional Chinese) | [`encodings/big5.tbl`](encodings/big5.tbl) | Big5 encoding for Traditional Chinese |
| Cyrillic ISO | [`encodings/cyrillic_iso.tbl`](encodings/cyrillic_iso.tbl) | Cyrillic ISO encoding |
| Cyrillic Windows | [`encodings/cyrillic_windows.tbl`](encodings/cyrillic_windows.tbl) | Cyrillic Windows encoding |
| Cyrillic KOI8-R | [`encodings/cyrillic_koi8_r.tbl`](encodings/cyrillic_koi8_r.tbl) | Cyrillic KOI8-R encoding (Russian Characters) |
@@ -174,6 +200,7 @@ 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 |

18594
encodings/big5.tbl Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,12 @@
#pragma once
#include <hex/impl/imhex_check.pat>
import hex.impl.imhex_check;
/*!
Core intrinsic functions to interact with the ImHex Hex Editor
*/
namespace hex::core {
namespace auto hex::core {
/**
A type representing a selection in the hex editor
@@ -21,20 +21,20 @@ namespace hex::core {
@return The current selection
*/
fn get_selection() {
u128 result = builtin::hex::core::get_selection();
u128 selection = builtin::hex::core::get_selection();
Selection result;
if (result == u128(-1)) {
if (selection == u128(-1)) {
result.valid = false;
result.address = 0x00;
result.size = 0x00;
} else {
result.valid = true;
result.address = result >> 64;
result.size = result & u64(-1);
result.address = selection >> 64;
result.size = selection & u64(-1);
}
return result;
};
}
}

View File

@@ -1,12 +1,14 @@
#pragma once
#include <hex/impl/imhex_check.pat>
import hex.impl.imhex_check;
import std.mem;
/*!
Library to allow decoding of more complex values
*/
namespace hex::dec {
namespace auto hex::dec {
/**
Demangles a mangled name into a human readable name
@@ -17,4 +19,46 @@ namespace hex::dec {
return builtin::hex::dec::demangle(mangled_name);
};
/**
Decompresses the bytes of a pattern into a section using the zlib algorithm
@param pattern The pattern whose bytes should be decompressed
@param section The section to decompress the data into
@param window_size The window size passed to zlib
@return true if successful, false otherwise
*/
fn zlib_decompress(ref auto pattern, std::mem::Section section, u64 window_size = 0) {
return builtin::hex::dec::zlib_decompress(pattern, section, window_size);
};
/**
Decompresses the bytes of a pattern into a section using the bzip algorithm
@param pattern The pattern whose bytes should be decompressed
@param section The section to decompress the data into
@return true if successful, false otherwise
*/
fn bzip_decompress(ref auto pattern, std::mem::Section section) {
return builtin::hex::dec::bzip_decompress(pattern, section);
};
/**
Decompresses the bytes of a pattern into a section using the LZMA algorithm
@param pattern The pattern whose bytes should be decompressed
@param section The section to decompress the data into
@return true if successful, false otherwise
*/
fn lzma_decompress(ref auto pattern, std::mem::Section section) {
return builtin::hex::dec::lzma_decompress(pattern, section);
};
/**
Decompresses the bytes of a pattern into a section using the zstd algorithm
@param pattern The pattern whose bytes should be decompressed
@param section The section to decompress the data into
@return true if successful, false otherwise
*/
fn zstd_decompress(ref auto pattern, std::mem::Section section) {
return builtin::hex::dec::zstd_decompress(pattern, section);
};
}

View File

@@ -1,12 +1,12 @@
#pragma once
#include <hex/impl/imhex_check.pat>
import hex.impl.imhex_check;
/*!
Library to do HTTP requests
*/
namespace hex::http {
namespace auto hex::http {
/**
Performs a HTTP GET request to the given URL and returns the response body

View File

@@ -1,12 +1,12 @@
#pragma once
#include <hex/impl/imhex_check.pat>
import hex.impl.imhex_check;
/*!
Library to interact with the currently loaded provider.
*/
namespace hex::prv {
namespace auto hex::prv {
/**

View File

@@ -1,16 +1,16 @@
#pragma once
#include <std/io.pat>
#include <std/mem.pat>
import std.io;
import std.mem;
#include <hex/impl/imhex_check.pat>
#include <hex/dec.pat>
import hex.impl.imhex_check;
import hex.dec;
/*!
Types to automatically decode mangled names
*/
namespace hex::type {
namespace auto hex::type {
/**
A mangled name string that gets demangled when displayed

View File

@@ -1,19 +1,41 @@
#pragma once
import std.sys;
/*!
The array library contains a helper type to make it easier to create multi-dimensional arrays
and pass arrays to functions as parameters.
*/
namespace std {
namespace auto std {
/**
Simple one dimensional array wrapper
@tparam T The array types
@tparam Size Size of the array
@tparam Size Number of entries in the array
*/
struct Array<T, auto Size> {
T data[Size] [[inline]];
};
} [[format("std::impl::format_array")]];
/**
Simple array wrapper for an array with a size in bytes
@tparam T The array types
@tparam NumBytes Number of bytes the array contains
*/
struct ByteSizedArray<T, auto NumBytes> {
u64 startAddress = $;
T array[while($ - startAddress < NumBytes)] [[inline]];
std::assert($ - startAddress == NumBytes, "Not enough bytes available to fit a whole number of types");
} [[format("std::impl::format_array")]];
namespace impl {
fn format_array(ref auto array) {
return "[ ... ]";
};
}
}

View File

@@ -1,12 +1,12 @@
#pragma once
#include <std/limits.pat>
import std.limits;
/*!
This library contains various helper functions for common bit operations.
*/
namespace std::bit {
namespace auto std::bit {
/**
Calculates the number of 1 bits in a given number

View File

@@ -1,13 +1,13 @@
#pragma once
#include <std/mem.pat>
import std.mem;
/*!
The core library contains intrinsics and "compiler magic" functions that
get extra help from the runtime to fulfill their purpose.
*/
namespace std::core {
namespace auto std::core {
/**
The layout order of each field after byte-endianness has been handled.
@@ -38,12 +38,20 @@ namespace 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.");
};
@@ -146,4 +154,14 @@ namespace std::core {
fn set_display_name(ref auto pattern, str name) {
builtin::std::core::set_display_name(pattern, name);
};
/**
Changes the comment attached to a pattern
@param pattern The pattern to modify
@param name The new comment of the pattern
*/
fn set_pattern_comment(ref auto pattern, str comment) {
builtin::std::core::set_pattern_comment(pattern, name);
};
}

View File

@@ -5,7 +5,7 @@
of ASCII characters.
*/
namespace std::ctype {
namespace auto std::ctype {
/**
Checks if the given character `c` is a digit between '0' and '9'

View File

@@ -7,7 +7,7 @@
**These functions are considered dangerous and require the user to manually permit them**
*/
namespace std::file {
namespace auto std::file {
/**
A handle representing a file that has been opened

View File

@@ -4,7 +4,7 @@
Library for doing arithmetic with fixed point numbers and converting them from/to floating point numbers.
*/
namespace std::fxpt {
namespace auto std::fxpt {
/**
A fixed point value

View File

@@ -4,7 +4,7 @@
The hash library contains various data hash functions
*/
namespace std::hash {
namespace auto std::hash {
/**
Calculates the CRC32 hash of the bytes inside of a given pattern

View File

@@ -4,7 +4,7 @@
The IO library allows formatting strings and outputting text to the console
*/
namespace std {
namespace auto std {
/**
Formats the given arguments using the format string and prints the result to the console

View File

@@ -4,7 +4,7 @@
Library to calculate the minimum and maximum values that fit into a given data type
*/
namespace std::limits {
namespace auto std::limits {
/**
Returns the minimum value that can be stored in a `u8`.

View File

@@ -1,12 +1,12 @@
#pragma once
#include <std/mem.pat>
import std.mem;
/*!
Library containing more advanced mathematical operations.
*/
namespace std::math {
namespace auto std::math {
/**
Compares the values `a` and `b` with each other and returns the smaller of the two
@@ -262,10 +262,11 @@ namespace std::math {
/**
Calculates the arc tangent of `value`.
@param value 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 value) { return builtin::std::math::atan2(value); };
fn atan2(auto y, auto x) { return builtin::std::math::atan2(y, x); };
/**
Calculates the hyperbolic sine of `value`.
@@ -327,9 +328,9 @@ namespace std::math {
@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
@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) {

View File

@@ -4,8 +4,28 @@
Library for doing raw memory accesses and other low-level operations.
*/
namespace std::mem {
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;
}
};
}
/**
A Handle for a custom Section
*/
@@ -26,7 +46,7 @@ namespace std::mem {
@return True if the cursor is at the end of the memory
*/
fn eof() {
return $ >= std::mem::size();
return $ >= (std::mem::base_address() + std::mem::size());
};
/**
@@ -84,7 +104,7 @@ namespace std::mem {
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 endianess of the value to read. Defaults to native
@return The value read
*/
fn read_unsigned(u128 address, u8 size, Endian endian = Endian::Native) {
@@ -95,7 +115,7 @@ namespace 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 endianess of the value to read. Defaults to native
@return The value read
*/
fn read_signed(u128 address, u8 size, Endian endian = Endian::Native) {
@@ -108,7 +128,7 @@ namespace std::mem {
@param size The size of the value to read
@return The value read
*/
fn read_string(u128 address, u8 size) {
fn read_string(u128 address, u128 size) {
return builtin::std::mem::read_string(address, size);
};
@@ -160,6 +180,15 @@ namespace std::mem {
return builtin::std::mem::get_section_size(section);
};
/**
Changes the size of a custom section
@param section The handle to the section
@param size The new size of the section
*/
fn set_section_size(Section section, u128 size) {
builtin::std::mem::set_section_size(section, size);
};
/**
Copies a range of bytes from one section into another
@param from_section The section to copy from
@@ -189,19 +218,7 @@ namespace std::mem {
@tparam T The type to place at the address
*/
struct MagicSearch<auto Magic, T> {
if ($ < (std::mem::size() - std::string::length(Magic) - 1)) {
char __potentialMagic__[std::string::length(Magic)] [[hidden, no_unique_address]];
if (__potentialMagic__ == Magic) {
T data [[inline]];
} else {
padding[1];
continue;
}
} else {
padding[1];
continue;
}
std::mem::impl::MagicSearchImpl<Magic, T> impl[while(!std::mem::eof())] [[inline]];
};
/**

View File

@@ -1,11 +1,13 @@
#pragma once
import std.mem;
/*!
The Pointer library contains helper functions to deal with pointer types.
The `relative_to` functions are meant to be used with the `[[pointer_base]]` attribute
*/
namespace std::ptr {
namespace auto std::ptr {
/**
Use the offset of the current pointer as start address
@@ -64,4 +66,4 @@ namespace std::ptr {
PointeeTy *data : PointerTy;
}
};
}
}

View File

@@ -1,12 +1,12 @@
#pragma once
#include <std/limits.pat>
import std.limits;
/*!
Library to generate random numbers. Supports various different distribution types.
*/
namespace std::random {
namespace auto std::random {
/**
Represents the type of distribution to use to generate a random number
@@ -61,8 +61,8 @@ namespace 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);
@@ -71,8 +71,8 @@ namespace std::random {
/**
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,12 +1,12 @@
#pragma once
#include <std/io.pat>
import std.io;
/*!
Libray to interact with strings.
*/
namespace std::string {
namespace auto std::string {
/**
Base type for sized strings. Represents a string with its size preceeding it.
@@ -209,30 +209,27 @@ namespace std::string {
@param replace The substring to replace with.
@return The string with the replacements.
*/
fn replace(str string, str pattern, str replace) {
u32 string_len, pattern_len, replace_len;
string_len = std::string::length(string);
pattern_len = std::string::length(pattern);
replace_len = std::string::length(replace);
if (pattern_len > string_len)
return string;
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;
u32 i;
while (i <= (string_len - pattern_len)) {
if (std::string::substr(string, i, pattern_len) == pattern) {
result = result + replace;
i = i + pattern_len;
} else {
result = result + std::string::at(string, i);
i = i + 1;
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

@@ -1,12 +1,12 @@
#pragma once
#include <std/io.pat>
import std.io;
/*!
Basic helper functions
*/
namespace std {
namespace auto std {
/**
Asserts that a given value is true. If it's not, abort evaluation and print the given message to the console

View File

@@ -1,12 +1,12 @@
#pragma once
#include <std/io.pat>
import std.io;
/*!
Library to handle time and date related operations.
*/
namespace std::time {
namespace auto std::time {
/**
A structured representation of a time and date.
@@ -34,7 +34,7 @@ namespace std::time {
/**
A type to represent a time in seconds since the epoch.
*/
using EpochTime = u128;
using EpochTime = u32;
/**
A type to represent a time zone.
@@ -91,7 +91,7 @@ namespace std::time {
@return The local time.
*/
fn to_local(EpochTime epoch_time) {
TimeConverter converter;
le TimeConverter converter;
converter.value = builtin::std::time::to_local(epoch_time);
@@ -104,7 +104,7 @@ namespace std::time {
@return The UTC time.
*/
fn to_utc(EpochTime epoch_time) {
TimeConverter converter;
le TimeConverter converter;
converter.value = builtin::std::time::to_utc(epoch_time);
@@ -113,11 +113,11 @@ namespace std::time {
/**
Queries the current time in the specified time zone.
@param time_zone The time zone to query.
@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) {
TimeConverter converter;
le TimeConverter converter;
if (time_zone == TimeZone::Local)
converter.value = builtin::std::time::to_local(std::time::epoch());
@@ -135,7 +135,7 @@ namespace std::time {
@return The DOS date.
*/
fn to_dos_date(u16 value) {
impl::DOSDateConverter converter;
le impl::DOSDateConverter converter;
converter.value = value;
@@ -148,21 +148,30 @@ namespace std::time {
@return The DOS time.
*/
fn to_dos_time(u16 value) {
impl::DOSTimeConverter converter;
le impl::DOSTimeConverter converter;
converter.value = value;
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;
};
/**
Formats a time according to the specified format string.
@param time The time to format.
@param format_string The format string to use.
@param [format_string] The format string to use. Defaults to "%c".
@return The formatted time.
*/
fn format(Time time, str format_string = "%c") {
TimeConverter converter;
le TimeConverter converter;
converter.time = time;
return builtin::std::time::format(format_string, converter.value);
@@ -171,7 +180,7 @@ namespace std::time {
/**
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.
@param [format_string] The format string to use. Defaults to "{}/{}/{}".
@return The formatted DOS date.
*/
fn format_dos_date(DOSDate date, str format_string = "{}/{}/{}") {
@@ -181,7 +190,7 @@ namespace std::time {
/**
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.
@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}") {

View File

@@ -1,14 +1,14 @@
#pragma once
#include <std/io.pat>
#include <std/math.pat>
import std.io;
import std.math;
/*!
Types used to change the base of the displayed integer value.
Used like `type::Hex<u32> hexNumber;`, `type::Oct<u16> octalNumber;`
*/
namespace type {
namespace auto type {
/**
Integer type representing a Hexadecimal value. Displays its value in hexadecimal format.

View File

@@ -1,12 +1,12 @@
#include <std/io.pat>
#include <std/string.pat>
#include <std/mem.pat>
import std.io;
import std.string;
import std.mem;
/*!
Type representing a Base64 encoded string
*/
namespace type {
namespace auto type {
/**
Type representing a Base64 encoded string

View File

@@ -1,12 +1,12 @@
#pragma once
#include <std/io.pat>
import std.io;
/*!
Type to decode a BCD (Binary Coded Decimal) number
*/
namespace type {
namespace auto type {
/**
Decodes a BCD value where one byte represents a single digit

View File

@@ -1,12 +1,12 @@
#pragma once
#include <std/io.pat>
import std.io;
/*!
Types to display single bytes using various different representations
*/
namespace type {
namespace auto type {
/**
Type visualizing the value of each individual bit

View File

@@ -1,13 +1,13 @@
#pragma once
#include <std/io.pat>
#include <std/core.pat>
import std.io;
import std.core;
/*!
Types representing RGB or RGBA colors. The decoded color will be displayed in their color field
*/
namespace type {
namespace auto type {
/**
Type representing a generic RGBA color with a variable number of bits for each color

View File

@@ -1,14 +1,14 @@
#pragma once
#include <std/io.pat>
#include <std/math.pat>
#include <std/mem.pat>
import std.io;
import std.math;
import std.mem;
/*!
Type representing a 16 bit half precision floating point number
*/
namespace type {
namespace auto type {
/**
Type representing a 16 bit half precision floating point number

View File

@@ -1,12 +1,12 @@
#pragma once
#include <std/io.pat>
import std.io;
/*!
Types to deal with UUIDs (Universally Unique Identifiers) / GUIDs (Globally Unique Identifiers) as described in RFC 4122
*/
namespace type {
namespace auto type {
/**
Type representing a GUID value

View File

@@ -1,13 +1,13 @@
#pragma once
#include <std/io.pat>
#include <std/string.pat>
import std.io;
import std.string;
/*!
Types used to decode IP addresses
*/
namespace type {
namespace auto type {
/**
A 4 byte IPv4 Address as described in RFC 791

View File

@@ -1,13 +1,13 @@
#pragma once
#include <std/io.pat>
#include <std/mem.pat>
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
*/
namespace type {
namespace auto type {
/**
Base LEB128 type. Use `uLEB128` and `sLEB128` instead.

View File

@@ -1,12 +1,12 @@
#pragma once
#include <std/io.pat>
import std.io;
/*!
Types used to decode MAC Addresses
*/
namespace type {
namespace auto type {
/**
A MAC Address as used in the Internet Protocol

View File

@@ -1,38 +1,43 @@
#include <std/string.pat>
#include <std/sys.pat>
#include <std/io.pat>
#include <std/ctype.pat>
import std.string;
import std.sys;
import std.io;
import std.ctype;
/*!
Types used to parse and enforce specific magic numbers
*/
namespace type {
namespace auto type
{
fn fm(ref auto value)
{
str result;
for (u32 i = 0, i < sizeof(value), i += 1)
{
char c = value[i];
if (std::ctype::isprint(c))
result += c;
else
result += std::format("\\x{:02X}", u8(c));
}
return std::format("\"{}\"", 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(value == ExpectedValue, std::format("Invalid magic value! Expected \"{}\", got \"{}\".", ExpectedValue, value));
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)));
} [[sealed, format("type::impl::format_magic")]];
namespace impl {
fn format_magic(ref auto magic) {
str result;
for (u32 i = 0, i < sizeof(magic.value), i += 1) {
char c = magic.value[i];
if (std::ctype::isprint(c))
result += c;
else
result += std::format("\\x{:02X}", u8(c));
}
return std::format("\"{}\"", result);
namespace impl
{
fn format_magic(ref auto magic)
{
return type::fm(magic.value);
};
}
}

View File

@@ -1,10 +1,10 @@
#include <std/mem.pat>
import std.mem;
/*!
Types dealing with various kinds of resource paths
*/
namespace type {
namespace auto type {
/**
Type representing a single path segment. Use the `Path` type instead of using this on its own

View File

@@ -1,10 +1,10 @@
#include <std/io.pat>
import std.io;
/*!
Types used to pretty print size values
*/
namespace type {
namespace auto type {
/**
A generic size type which displays its value in Bytes (or kiB, MiB, GiB, TiB, PiB, EiB if larger)

View File

@@ -1,13 +1,13 @@
#pragma once
#include <std/io.pat>
#include <std/time.pat>
import std.io;
import std.time;
/*!
Types used to decode various different time formats
*/
namespace type {
namespace auto type {
/**
A 32 bit Unix time value
@@ -34,6 +34,11 @@ namespace type {
*/
using DOSTime = u16 [[format("type::impl::format_dostime")]];
/**
A 64bit FILETIME value
*/
using FILETIME = u64 [[format("type::impl::format_filetime_as_unix")]];
namespace impl {
fn format_time_t(u128 value) {
@@ -48,6 +53,10 @@ namespace type {
return std::time::format_dos_time(std::time::to_dos_time(value));
};
fn format_filetime_as_unix(u64 value) {
return std::time::filetime_to_unix(value);
};
}
}

View File

@@ -5,7 +5,7 @@
*/
// Explicitly don't add these types to the `type` namespace for usability
// namespace type {
// namespace auto type {
// using char = s8;
using byte = s8;

View File

@@ -5,7 +5,7 @@
*/
// Explicitly don't add these types to the `type` namespace for usability
// namespace type {
// namespace auto type {
using uint8_t = u8;
using uint16_t = u16;

View File

@@ -5,7 +5,7 @@
*/
// Explicitly don't add these types to the `type` namespace for usability
// namespace type {
// namespace auto type {
using le16 = le u16;
using be16 = be u16;

View File

@@ -5,7 +5,7 @@
*/
// Explicitly don't add these types to the `type` namespace for usability
// namespace type {
// namespace auto type {
// using u8 = u8;
// using u16 = u16;

View File

@@ -5,7 +5,7 @@
*/
// Explicitly don't add these types to the `type` namespace for usability
// namespace type {
// namespace auto type {
using BYTE = u8;
using WORD = u16;

View File

@@ -1,4 +1,4 @@
# A libmagic database containing definition for PE files used by MS-DOS based systems
# A libmagic database containing definition for PE files used by MS-DOS/Windows based systems
# MS-DOS Portable Executable
0x0 string/b MZ MS-DOS Binary

1141
patterns/3ds.hexpat Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,8 @@
#include <std/io.pat>
#include <std/mem.pat>
#include <std/math.pat>
#pragma description 7z File Format
import std.io;
import std.mem;
import std.math;
enum Type:u8{

View File

@@ -1,18 +1,26 @@
#include <type/magic.pat>
#include <std/string.pat>
#include <std/array.pat>
#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!
import type.magic;
import std.string;
import std.array;
// Crash Bandicoot - Back in Time (fan game) user created tapes
// author AdventureT
struct Header {
type::Magic<"CRASHLVL"> magic;
u8 version;
if (version >= 4) {
std::string::SizedString<u8> gameVersion;
}
std::string::SizedString<u8> levelName;
std::string::SizedString<u8> author;
};
enum Music : u32 {
Header header @ 0x0;
// Background Music
enum BGM : u32 {
None,
BonusBGM,
CrashCreatorBGM,
@@ -28,39 +36,199 @@ enum Music : u32 {
NBrioBGM
};
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,
};
enum Type : u32 {
Unset,
Flashback,
Trial
Trial,
};
enum Time : u32 {
enum TypeV2 : u32 {
Practice,
Flashback,
Trial,
Adventure
};
enum Skybox : u32 {
Night,
Day,
Storm,
Dawn
};
enum Terrain : u32 {
enum SkyboxV2 : u32 {
Default = 1,
Briolab,
Fort,
Moon,
Toxic,
AboutRight,
Crash1Island,
Arabia,
RoadToRuin,
Black
};
enum Scenery : u32 {
None,
Machines,
Trees,
FutureTense,
Forest,
Waterfall,
Snow,
Fortress,
};
enum SceneryV2 : u32 {
None,
FutureTense,
Forest,
Waterfall,
None2,
Fortress,
None3,
Lava,
TheGreatGate,
Mountain,
KoalaKong,
SunsetVista,
HangemHigh,
Sphynxinator,
Tunnel,
Pipes
};
enum SceneryV4 : u32 {
None,
FutureTense,
Forest,
Waterfall,
Snow,
Fortress,
None2,
Lava,
TheGreatGate,
Mountain,
KoalaKong,
SunsetVista,
HangemHigh,
Sphynxinator,
Tunnel,
Pipes
};
enum Weather : u32 {
Default,
Snow,
Rain
};
struct Options {
Type type;
Time time;
Terrain terrain;
Music music;
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)
BGMV2 bgm;
else
BGM bgm;
if (type == Type::Trial)
{
u32 timeTrialTicksBronze;
u32 timeTrialTicksSilver;
u32 timeTrialTicksGold;
}
};
struct Object {
std::string::SizedString<u8> objName;
u32 x;
u32 y;
if (header.version > 1)
{
u16 x;
u16 y;
bool hasMetafields;
if (hasMetafields)
{
u16 numOfMetafields;
u8 metafields[numOfMetafields];
}
}
else
{
u32 x;
u32 y;
}
};
struct Objects{
@@ -68,6 +236,9 @@ struct Objects{
std::Array<Object, objCount> objArray;
};
Header header @ 0x0;
Options options @ $;
Objects objects @ $;
Objects objects @ $;

198
patterns/adts.hexpat Normal file
View File

@@ -0,0 +1,198 @@
#pragma authors: zhoubo
#pragma version: 0.4
#pragma description: Parse AAC's ADTS(Audio Data Transport Stream) audio files.
#pragma category: Audio
#pragma filemask: *.aac
#pragma IDBytes: FF F //ADTS Syncword
#pragma history:
#pragma 0.4 2024-02-12 zhoubo: Porting from 010 Editor Templates.
#pragma 0.3 2024-02-09 zhoubo: use BitfieldDisablePadding(Unpadded Bitfields) for odd header bytes(7,9 bytes) color, and remove FSeek.
#pragma 0.2 2024-02-05 zhoubo: fix some comment & color.
#pragma 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,7 +1,10 @@
#pragma author WerWolv
#pragma description Nintendo Switch Atmosphère CFW Fatal Error log
#pragma endian little
#include <std/io.pat>
#include <std/sys.pat>
import std.io;
import std.sys;
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC "AFE2"
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_1 "AFE1"

View File

@@ -1,8 +1,11 @@
#pragma author WerWolv
#pragma description Static library archive files
#pragma MIME application/x-archive
#include <std/string.pat>
#include <std/mem.pat>
#include <std/sys.pat>
import std.string;
import std.mem;
import std.sys;
struct ARFile {
char file_name[16];

36
patterns/aria2.hexpat Normal file
View File

@@ -0,0 +1,36 @@
#pragma author itsmeow
#pragma description aria2 Control File
#pragma endian big
/*
Format sourced from:
https://aria2.github.io/manual/en/html/technical-notes.html#control-file-aria2-format
Version 0 files are not supported by default
However parsing one is as simple as changing to #pragma endian ittle
and resolving any errors resulting from that by adding be prefixes to struct fields.
*/
struct AriaInFlight {
u32 index;
u32 length;
u32 bitfield_piece_length;
u8 bitfield_p[bitfield_piece_length];
};
struct AriaHeader {
u16 version;
u32 extension;
u32 infohash_length;
u8 infohash[infohash_length];
u32 piece_length;
u64 total_length;
u64 upload_length;
u32 bitfield_length;
u8 bitfield_d[bitfield_length];
u32 inflight_count;
AriaInFlight inflights[inflight_count];
};
AriaHeader aria_header @ 0x00;

View File

@@ -1,7 +1,10 @@
#pragma author WerWolv
#pragma description ARM Cortex M Vector Table Layout
#pragma endian little
#include <std/io.pat>
#include <std/mem.pat>
import std.io;
import std.mem;
#define VTOR 0x00000000
#define EXTERNAL_INTERRUPT_COUNT 64

1
patterns/bastion Submodule

Submodule patterns/bastion added at e6deed433c

View File

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

80
patterns/bgcode.hexpat Normal file
View File

@@ -0,0 +1,80 @@
#pragma author Shadlock0133 (aka Aurora)
#pragma description Binary G-Code from Prusa
#include <type/magic.pat>
#include <std/mem.pat>
enum ChecksumType : u16 {
None,
CRC32,
};
enum BlockType : u16 {
FileMetadata,
GCode,
SlicerMetadata,
PrinterMetadata,
PrintMetadata,
Thumbnail,
};
enum Compression : u16 {
None,
Deflate,
Heatshrink11_4,
Heatshrink12_4,
};
enum Encoding : u16 {
Ini,
};
enum ImageFormat : u16 {
Png,
Jpg,
Qoi,
};
struct Header {
type::Magic<"GCDE"> magic;
u32 version;
ChecksumType checksum_type;
};
Header header @ 0;
std::assert(header.version == 1, "only version 1 supported");
struct Block {
BlockType type;
Compression compression;
u32 uncompressed_size;
auto size = uncompressed_size;
if (compression != Compression::None) {
u32 compressed_size;
size = compressed_size;
}
match (type) {
(BlockType::FileMetadata
| BlockType::PrinterMetadata
| BlockType::PrintMetadata
| BlockType::SlicerMetadata): {
Encoding encoding;
}
(BlockType::Thumbnail): {
ImageFormat image_format;
u16 width;
u16 height;
}
(BlockType::GCode): {
u16;
}
(_): { std::assert(false, "unknown type"); }
}
u8 data[size];
match (header.checksum_type) {
(ChecksumType::None): {}
(ChecksumType::CRC32): { u32 checksum; }
}
};
Block blocks[while(!std::mem::eof())] @ $;

View File

@@ -1,6 +1,8 @@
#pragma description OS2/Windows Bitmap files
#pragma MIME image/bmp
#pragma endian little
#include <std/mem.pat>
import std.mem;
struct BitmapFileHeader {
u8 bfType[2];
@@ -10,13 +12,38 @@ struct BitmapFileHeader {
u32 bfOffBits;
};
struct BitmapInfoHeader {
enum Compression : u32 {
BI_RGB,
BI_RLE8,
BI_RLE4,
BI_BITFIELDS,
BI_JPEG,
BI_PNG,
BI_ALPHABITFIELDS,
BI_CMYK,
BI_CMYKRLE8,
BI_CMYKRLE4,
};
struct CIEXYZ {
u32 ciexyzX;
u32 ciexyzY;
u32 ciexyzZ;
};
struct CIEXYZTRIPLE {
CIEXYZ ciexyzRed;
CIEXYZ ciexyzGreen;
CIEXYZ ciexyzBlue;
};
struct BitmapInfoHeaderV1 {
u32 biSize;
s32 biWidth;
s32 biHeight;
u16 biPlanes;
u16 biBitCount;
u32 biCompression;
Compression biCompression;
u32 biSizeImage;
s32 biXPelsPerMeter;
s32 biYPelsPerMeter;
@@ -24,6 +51,31 @@ struct BitmapInfoHeader {
u32 biClrImportant;
};
struct BitmapInfoHeaderV2 : BitmapInfoHeaderV1 {
u32 biRedMask;
u32 biGreenMask;
u32 biBlueMask;
};
struct BitmapInfoHeaderV3 : BitmapInfoHeaderV2 {
u32 biAlphaMask;
};
struct BitmapInfoHeaderV4 : BitmapInfoHeaderV3 {
u32 biCSType;
CIEXYZTRIPLE biEndpoints;
u32 biGammaRed;
u32 biGammaGreen;
u32 biGammaBlue;
};
struct BitmapInfoHeaderV5 : BitmapInfoHeaderV4 {
u32 biIntent;
u32 biProfileData;
u32 biProfileSize;
u32 biReserved;
};
struct Colors {
u8 blue;
u8 green;
@@ -32,11 +84,21 @@ struct Colors {
};
struct Bitmap {
u8 data[std::mem::size()] [[no_unique_address, hidden]];
u8 data[std::mem::size()] [[no_unique_address, hidden]];
BitmapFileHeader bmfh;
BitmapInfoHeader bmih;
// Deduce the header version from its size
u32 bmInfoHeaderSize [[hidden, no_unique_address]];
match (bmInfoHeaderSize) {
(40): BitmapInfoHeaderV1 bmih;
(52): BitmapInfoHeaderV2 bmih;
(56): BitmapInfoHeaderV3 bmih;
(108): BitmapInfoHeaderV4 bmih;
(124): BitmapInfoHeaderV5 bmih;
(_): BitmapInfoHeaderV1 bmih;
}
padding[bmih.biSize - sizeof(bmih)];
if ((bmih.biBitCount != 24) && (bmih.biBitCount != 32))
if (bmih.biBitCount <= 8)
{
if (bmih.biClrUsed > 0 )
Colors rgbq[bmih.biClrUsed];

271
patterns/bplist.hexpat Normal file
View File

@@ -0,0 +1,271 @@
import std.math;
import std.core;
import type.magic;
import type.time;
using CFBinaryPlistObject;
enum Marker : u8 {
Null = 0x00,
False = 0x08,
True = 0x09,
Fill = 0x0F,
Int = 0x10,
Real = 0x20,
Date = 0x30,
Data = 0x40,
ASCIIString = 0x50,
Unicode16String = 0x60,
UNK_0x70 = 0x70,
UID = 0x80,
UNK_0x90 = 0x90,
Array = 0xA0,
UNK_0xB0 = 0xB0,
Set = 0xC0,
Dict = 0xD0,
UNK_0xE0 = 0xE0,
UNK_0xF0 = 0xF0
};
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
return "Fill";
}else if (marker & 0xF0 == Marker::Int){ //int 0001 nnnn ... // # of bytes is 2^nnnn, big-endian bytes
return "Int";
}else if (marker & 0xF0 == Marker:: Real){ //real 0010 nnnn ... // # of bytes is 2^nnnn, big-endian bytes
return "Real";
}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";
}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
return "Unicode16String";
}else if (marker & 0xF0 == Marker::UNK_0x70){ //0111 xxxx // unused
return "UNK_0x70";
}else if (marker & 0xF0 == Marker::UID){ //uid 1000 nnnn ... // nnnn+1 is # of bytes
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
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
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) {
return std::format("{}", get_marker(marker));
};
fn coredata_to_date (double val){
return type::impl::format_time_t(978307200 + val);
};
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 {
CFBinaryPlistObject value @ offsetTable[parent.objReference.value_refs[std::core::array_index()]].offset;
};
struct ObjectReference{
match(trailer.objectRefSize){
(1): {
be u8 key_refs[parent.ObjectLen.size];
be u8 value_refs[parent.ObjectLen.size];
}
(2): {
be u16 key_refs[parent.ObjectLen.size];
be u16 value_refs[parent.ObjectLen.size];
}
(4): {
be u32 key_refs[parent.ObjectLen.size];
be u32 value_refs[parent.ObjectLen.size];
}
(8): {
be u64 key_refs[parent.ObjectLen.size];
be u64 value_refs[parent.ObjectLen.size];
}
}
};
struct ObjectReferenceArray{
match(trailer.objectRefSize){
(1): be u8 value_refs[parent.ObjectLen.size];
(2): be u16 value_refs[parent.ObjectLen.size];
(4): be u32 value_refs[parent.ObjectLen.size];
(8): be u64 value_refs[parent.ObjectLen.size];
}
};
struct ObjectLen{
if (parent.marker_lsb != 0x0F){
u8 size = parent.marker_lsb [[export]];
}else{
CFBinaryPlistObject obj;
if (obj.marker & 0xF0 != Marker::Int){
std::error(std::format("Expects a 'Int' marker. Got 0x{:x} marker, with value {}", obj.marker, obj.value));
}
u128 size = obj.value [[export]];
}
};
struct CFBinaryPlistOffset{
match (trailer.offsetIntSize){
(1): be u8 offset;
(2): be u16 offset;
(4): be u32 offset;
(8): be u64 offset;
}
};
struct CFBinaryPlistObject{
u8 marker [[format("get_marker_name")]];
u8 marker_msb = marker & 0xF0;
u8 marker_lsb = marker & 0x0F;
match (marker_msb){
(0x0): {
match (marker_lsb){
(Marker::Null): {
u8 value = 0x00 [[export]];
}
(Marker::False): {
bool value = false [[export]];
}
(Marker::True): {
bool value = true [[export]];
}
(Marker::Fill): {
//I think the correct implementation is to do nothing here. The marker will be used as padding (Fill) ???
}
(_): {
std::error("Detected unknown marker {}.", marker_msb);
}
}
}
(Marker::Int): {
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'
// integers are not required to be in the most compact possible representation, but only the last 64 bits are significant currently
// Source: https://opensource.apple.com/source/CF/CF-550/CFBinaryPList.c
match (size) {
(1): be u8 value;
(2): be u16 value;
(4): be u32 value;
(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);
match (size){
(4): be float value;
(8): be double value;
(_): std::error(std::format("Invalid size detected for 'Real' marker. Got size: {}.", size));
}
}
(Marker::Date): {
be double value [[format("coredata_to_date")]];
}
(Marker::Data): {
ObjectLen ObjectLen;
u8 value[ObjectLen.size];
}
(Marker::ASCIIString): {
ObjectLen ObjectLen;
char value[ObjectLen.size];
}
(Marker::Unicode16String): {
ObjectLen ObjectLen;
be char16 value[ObjectLen.size];
}
(Marker::UID): {
//Not 100% sure if this is correct for UID. Need more testing
u8 size = marker_lsb+1;
match (size) {
(1): be u8 value;
(2): be u16 value;
(4): be u32 value;
(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;
ObjectReferenceArray objReference;
ArrayElement value[ObjectLen.size];
}
(Marker::Dict): {
ObjectLen ObjectLen;
ObjectReference objReference;
DictElement value[ObjectLen.size];
}
(Marker::UNK_0x70 | Marker::UNK_0x90 | Marker::UNK_0xB0 | Marker::UNK_0xE0 | Marker::UNK_0xF0): {
std::error(std::format("Got unused marker 0x{:x}", marker));
}
(_): {
std::error(std::format("Got unknown marker 0x{:x}", marker));
}
}
};
struct CFBinaryPlistHeader{
type::Magic<"bplist"> magic;
u16 version;
if (version != 0x3030){
std::error("Unsupported version detected. Only version 00 is supported (bplist00).");
}
};
struct CFBinaryPlistTrailer {
u8 unused[5];
u8 sortVersion;
be u8 offsetIntSize;
match (offsetIntSize){
(1|2|4|8): {}
(_): {std::error("Invalid offsetIntSize.");}
}
be u8 objectRefSize;
match (objectRefSize){
(1|2|4|8): {}
(_): {std::error("Invalid objectRefSize.");}
}
be u64 numObjects;
be u64 topObject;
be u64 offsetTableOffset;
};
CFBinaryPlistHeader header @ 0x00;
CFBinaryPlistTrailer trailer @ std::mem::size()-32;
CFBinaryPlistOffset offsetTable[trailer.numObjects] @ trailer.offsetTableOffset;
CFBinaryPlistObject objectTable @ offsetTable[trailer.topObject].offset;

View File

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

View File

@@ -1,6 +1,8 @@
#include <std/ptr.pat>
#include <std/mem.pat>
#include <std/sys.pat>
#pragma description GoldSrc engine maps format (used in Half-Life 1)
import std.ptr;
import std.mem;
import std.sys;
#pragma endian little

View File

@@ -1,3 +1,5 @@
#pragma description Command and Conquer Voxel Animation
// Command and conquer voxel animation format
struct vec4_s {

View File

@@ -1,3 +1,5 @@
#pragma description Command and Conquer Voxel Palette
// Command and conquer palette format
struct Color {

View File

@@ -1,3 +1,5 @@
#pragma description Command and Conquer Voxel Model
// Command and Conquer voxel model format
struct vec4_s {

View File

@@ -1,3 +1,5 @@
#pragma description Compact Disc Audio track
struct Header {
u32 RIFF;
s32 size;

View File

@@ -1,395 +1,398 @@
#include <type/magic.pat>
#include <type/size.pat>
#include <type/guid.pat>
#include <type/leb128.pat>
#include <std/sys.pat>
enum WindowsLanguageId : u32 {
Arabic_SaudiArabia = 0x401,
Arabic_Iraq = 0x801,
Arabic_Egypt = 0xc01,
Arabic_Libya = 0x1001,
Arabic_Algeria = 0x1401,
Arabic_Morocco = 0x1801,
Arabic_Tunisia = 0x1c01,
Arabic_Oman = 0x2001,
Arabic_Yemen = 0x2401,
Arabic_Syria = 0x2801,
Arabic_Jordan = 0x2c01,
Arabic_Lebanon = 0x3001,
Arabic_Kuwait = 0x3401,
Arabic_UAE = 0x3801,
Arabic_Bahrain = 0x3c01,
Arabic_Qatar = 0x4001,
Bulgarian = 0x402,
Catalan = 0x403,
Valencian = 0x803,
Chinese_Taiwan = 0x404,
Chinese_PRC = 0x804,
Chinese_HongKongSAR = 0xc04,
Chinese_Singapore = 0x1004,
Chinese_MacaoSAR = 0x1404,
Czech = 0x405,
Danish = 0x406,
German_Germany = 0x407,
German_Switzerland = 0x807,
German_Austria = 0xc07,
German_Luxembourg = 0x1007,
German_Liechtenstein = 0x1407,
Greek = 0x408,
English_UnitedStates = 0x409,
English_UnitedKingdom = 0x809,
English_Australia = 0xc09,
English_Canada = 0x1009,
English_NewZealand = 0x1409,
English_Ireland = 0x1809,
English_SouthAfrica = 0x1c09,
English_Jamaica = 0x2009,
English_Caribbean = 0x2409,
English_Belize = 0x2809,
English_TrinidadandTobago = 0x2c09,
English_Zimbabwe = 0x3009,
English_Philippines = 0x3409,
English_Indonesia = 0x3809,
English_HongKongSAR = 0x3c09,
English_India = 0x4009,
English_Malaysia = 0x4409,
English_Singapore = 0x4809,
Spanish_SpainTraditionalSort = 0x40a,
Spanish_Mexico = 0x80a,
Spanish_Spain = 0xc0a,
Spanish_Guatemala = 0x100a,
Spanish_CostaRica = 0x140a,
Spanish_Panama = 0x180a,
Spanish_DominicanRepublic = 0x1c0a,
Spanish_Venezuela = 0x200a,
Spanish_Colombia = 0x240a,
Spanish_Peru = 0x280a,
Spanish_Argentina = 0x2c0a,
Spanish_Ecuador = 0x300a,
Spanish_Chile = 0x340a,
Spanish_Uruguay = 0x380a,
Spanish_Paraguay = 0x3c0a,
Spanish_Bolivia = 0x400a,
Spanish_ElSalvador = 0x440a,
Spanish_Honduras = 0x480a,
Spanish_Nicaragua = 0x4c0a,
Spanish_PuertoRico = 0x500a,
Spanish_UnitedStates = 0x540a,
Spanish_LatinAmerica = 0x580a,
Finnish = 0x40b,
French_France = 0x40c,
French_Belgium = 0x80c,
French_Canada = 0xc0c,
French_Switzerland = 0x100c,
French_Luxembourg = 0x140c,
French_Monaco = 0x180c,
French_Caribbean = 0x1c0c,
French_Reunion = 0x200c,
French_CongoDRC = 0x240c,
French_Senegal = 0x280c,
French_Cameroon = 0x2c0c,
French_CoteDIvoire = 0x300c,
French_Mali = 0x340c,
French_Morocco = 0x380c,
French_Haiti = 0x3c0c,
Hebrew = 0x40d,
Hungarian = 0x40e,
Icelandic = 0x40f,
Italian_Italy = 0x410,
Italian_Switzerland = 0x810,
Japanese = 0x411,
Korean = 0x412,
Dutch_Netherlands = 0x413,
Dutch_Belgium = 0x813,
Norwegian_Bokmal = 0x414,
Norwegian_Nynorsk = 0x814,
Polish = 0x415,
Portuguese_Brazil = 0x416,
Portuguese_Portugal = 0x816,
Romansh = 0x417,
Romanian = 0x418,
Romanian_Moldova = 0x818,
Russian = 0x419,
Russian_Moldova = 0x819,
Croatian_Croatia = 0x41a,
Serbian_LatinSerbiaandMontenegroFormer = 0x81a,
Serbian_CyrillicSerbiaAndMontenegroFormer = 0xc1a,
Croatian_BosniaAndHerzegovina = 0x101a,
Bosnian_Latin = 0x141a,
Serbian_LatinBosniaAndHerzegovina = 0x181a,
Serbian_CyrillicBosniaAndHerzegovina = 0x1c1a,
Bosnian_Cyrillic = 0x201a,
Serbian_LatinSerbia = 0x241a,
Serbian_CyrillicSerbia = 0x281a,
Serbian_LatinMontenegro = 0x2c1a,
Serbian_CyrillicMontenegro = 0x301a,
Slovak = 0x41b,
Albanian = 0x41c,
Swedish_Sweden = 0x41d,
Swedish_Finland = 0x81d,
Thai = 0x41e,
Turkish = 0x41f,
Urdu_Pakistan = 0x420,
Urdu_India = 0x820,
Indonesian = 0x421,
Ukrainian = 0x422,
Belarusian = 0x423,
Slovenian = 0x424,
Estonian = 0x425,
Latvian = 0x426,
Lithuanian = 0x427,
Tajik = 0x428,
Persian = 0x429,
Vietnamese = 0x42a,
Armenian = 0x42b,
Azerbaijani_Latin = 0x42c,
Azerbaijani_Cyrillic = 0x82c,
Basque = 0x42d,
UpperSorbian = 0x42e,
LowerSorbian = 0x82e,
Macedonian = 0x42f,
Sesotho_SouthAfrica = 0x430,
Xitsonga = 0x431,
Setswana_SouthAfrica = 0x432,
Setswana_Botswana = 0x832,
Venda = 0x433,
isiXhosa = 0x434,
isiZulu = 0x435,
Afrikaans = 0x436,
Georgian = 0x437,
Faroese = 0x438,
Hindi = 0x439,
Maltese = 0x43a,
NorthernSami_Norway = 0x43b,
NorthernSami_Sweden = 0x83b,
NorthernSami_Finland = 0xc3b,
LuleSami_Norway = 0x103b,
LuleSami_Sweden = 0x143b,
SouthernSami_Norway = 0x183b,
SouthernSami_Sweden = 0x1c3b,
SkoltSami_Finland = 0x203b,
InariSami_Finland = 0x243b,
Irish = 0x83c,
Yiddish = 0x43d,
Malay_Malaysia = 0x43e,
Malay_BruneiDarussalam = 0x83e,
Kazakh = 0x43f,
Kyrgyz = 0x440,
Kiswahili = 0x441,
Turkmen = 0x442,
Uzbek_Latin = 0x443,
Uzbek_Cyrillic = 0x843,
Tatar = 0x444,
Bangla_India = 0x445,
Bangla_Bangladesh = 0x845,
Punjabi_India = 0x446,
Punjabi_Pakistan = 0x846,
Gujarati = 0x447,
Odia = 0x448,
Tamil_India = 0x449,
Tamil_SriLanka = 0x849,
Telugu = 0x44a,
Kannada = 0x44b,
Malayalam = 0x44c,
Assamese = 0x44d,
Marathi = 0x44e,
Sanskrit = 0x44f,
Mongolian_Cyrillic = 0x450,
Mongolian_TraditionalMongolianPRC = 0x850,
Mongolian_TraditionalMongolianMongolia = 0xc50,
Tibetan_PRC = 0x451,
Welsh = 0x452,
Khmer = 0x453,
Lao = 0x454,
Burmese = 0x455,
Galician = 0x456,
Konkani = 0x457,
Manipuri = 0x458,
Sindhi_Devanagari = 0x459,
Sindhi_Arabic = 0x859,
Syriac = 0x45a,
Sinhala = 0x45b,
Cherokee_Cherokee = 0x45c,
Inuktitut_Syllabics = 0x45d,
Inuktitut_Latin = 0x85d,
Amharic = 0x45e,
Tamazight_ArabicMorocco = 0x45f,
Tamazight_LatinAlgeria = 0x85f,
Tamazight_TifinaghMorocco = 0x105f,
Kashmiri_Arabic = 0x460,
Kashmiri = 0x860,
Nepali = 0x461,
Nepali_India = 0x861,
Frisian = 0x462,
Pashto = 0x463,
Filipino = 0x464,
Divehi = 0x465,
Edo = 0x466,
Fulah_Nigeria = 0x467,
Fulah_LatinSenegal = 0x867,
Hausa = 0x468,
Ibibio_Nigeria = 0x469,
Yoruba = 0x46a,
Quechua_Bolivia = 0x46b,
Quechua_Ecuador = 0x86b,
Quechua_Peru = 0xc6b,
SesothoSaLeboa = 0x46c,
Bashkir = 0x46d,
Luxembourgish = 0x46e,
Greenlandic = 0x46f,
Igbo = 0x470,
Kanuri = 0x471,
Oromo = 0x472,
Tigrinya_Ethiopia = 0x473,
Tigrinya_Eritrea = 0x873,
Guarani = 0x474,
Hawaiian = 0x475,
Latin = 0x476,
Somali = 0x477,
Yi_PRC = 0x478,
Papiamentu = 0x479,
Mapudungun = 0x47a,
Mohawk = 0x47c,
Breton = 0x47e,
Uyghur_PRC = 0x480,
Maori = 0x481,
Occitan = 0x482,
Corsican = 0x483,
Alsatian = 0x484,
Sakha = 0x485,
Kiche = 0x486,
Kinyarwanda = 0x487,
Wolof = 0x488,
Dari = 0x48c,
ScottishGaelic_UnitedKingdom = 0x491,
CentralKurdish_Iraq = 0x492
};
struct DirectoryListingEntry {
type::LEB128 nameLength;
char name[nameLength];
type::LEB128 contentSection;
type::LEB128 offset;
type::LEB128 length;
};
struct DirectoryIndexEntry {
type::LEB128 nameLength;
char name[nameLength];
type::LEB128 directoryListingChunk;
};
struct ListingChunk {
char magic[4];
if (magic == "PMGL") {
type::Size<u32> freeSpaceLength;
u32;
u32 prevChunkNumber, nextChunkNumber;
u16 directoryListingEntryCount @ addressof(this) + parent.directoryChunkSize - 2;
u16 offsets[(freeSpaceLength - 2) / 2] @ addressof(directoryListingEntryCount) - (freeSpaceLength - 2);
DirectoryListingEntry directories[directoryListingEntryCount];
$ = addressof(directoryListingEntryCount) + sizeof(directoryListingEntryCount);
} else if (magic == "PMGI") {
type::Size<u32> freeSpaceLength;
u16 directoryIndexEntryCount @ addressof(this) + parent.directoryChunkSize - 2;
u16 offsets[(freeSpaceLength - 2) / 2] @ addressof(directoryIndexEntryCount) - (freeSpaceLength - 2);
DirectoryIndexEntry indexes[directoryIndexEntryCount];
$ = addressof(directoryIndexEntryCount) + sizeof(directoryIndexEntryCount);
} else {
std::error("Invalid chunk magic!");
}
};
struct HeaderSection {
char magic[4];
if (magic == "\xFE\x01\x00\x00") {
u32;
type::Size<u64> fileSize;
u32;
u32;
} else if (magic == "ITSP") {
u32 version;
type::Size<u32> directoryHeaderLength1;
u32;
u32 directoryChunkSize;
u32 quickRefSectionDensity;
u32 indexTreeDepth;
u32 rootIndexChunkNumber;
u32 firstPMGLChunkNumber;
u32 lastPMGLChunkNumber;
u32;
u32 directoryChunkCount;
WindowsLanguageId languageId;
type::GUID guid;
type::Size<u32> directoryHeaderLength2;
u32;
u32;
u32;
ListingChunk chunk[directoryChunkCount];
} else {
std::error("Invalid header section magic!");
}
};
struct HeaderSectionTableEntry {
u64 offset;
type::Size<u64> size;
HeaderSection headerSection @ offset;
};
struct NameListEntry {
type::Size<u16> nameLength;
char16 name[nameLength];
padding[2];
};
struct NameListFile {
u16 fileLengthWords;
u16 entriesInFile;
NameListEntry nameList[entriesInFile];
padding[0x2E];
};
struct SectionData {
u32 fileLengthWords;
type::Magic<"LZXC"> magic;
u32 version;
u32 lzxResetInterval;
type::Size<u32> windowSize;
type::Size<u32> cacheSize;
u32;
};
struct Content {
NameListFile nameListFile;
SectionData sectionData;
};
struct CHM {
type::Magic<"ITSF"> magic;
u32 version;
type::Size<u32> headerSize;
u32;
be u32 timeStamp;
WindowsLanguageId languageId;
type::GUID guids[2];
HeaderSectionTableEntry headerSectionTable[2];
Content *dataOffset : u64;
};
CHM chm @ 0x00;
#pragma author WerWolv
#pragma description Windows HtmlHelp Data (ITSF / CHM)
import type.magic;
import type.size;
import type.guid;
import type.leb128;
import std.sys;
enum WindowsLanguageId : u32 {
Arabic_SaudiArabia = 0x401,
Arabic_Iraq = 0x801,
Arabic_Egypt = 0xc01,
Arabic_Libya = 0x1001,
Arabic_Algeria = 0x1401,
Arabic_Morocco = 0x1801,
Arabic_Tunisia = 0x1c01,
Arabic_Oman = 0x2001,
Arabic_Yemen = 0x2401,
Arabic_Syria = 0x2801,
Arabic_Jordan = 0x2c01,
Arabic_Lebanon = 0x3001,
Arabic_Kuwait = 0x3401,
Arabic_UAE = 0x3801,
Arabic_Bahrain = 0x3c01,
Arabic_Qatar = 0x4001,
Bulgarian = 0x402,
Catalan = 0x403,
Valencian = 0x803,
Chinese_Taiwan = 0x404,
Chinese_PRC = 0x804,
Chinese_HongKongSAR = 0xc04,
Chinese_Singapore = 0x1004,
Chinese_MacaoSAR = 0x1404,
Czech = 0x405,
Danish = 0x406,
German_Germany = 0x407,
German_Switzerland = 0x807,
German_Austria = 0xc07,
German_Luxembourg = 0x1007,
German_Liechtenstein = 0x1407,
Greek = 0x408,
English_UnitedStates = 0x409,
English_UnitedKingdom = 0x809,
English_Australia = 0xc09,
English_Canada = 0x1009,
English_NewZealand = 0x1409,
English_Ireland = 0x1809,
English_SouthAfrica = 0x1c09,
English_Jamaica = 0x2009,
English_Caribbean = 0x2409,
English_Belize = 0x2809,
English_TrinidadandTobago = 0x2c09,
English_Zimbabwe = 0x3009,
English_Philippines = 0x3409,
English_Indonesia = 0x3809,
English_HongKongSAR = 0x3c09,
English_India = 0x4009,
English_Malaysia = 0x4409,
English_Singapore = 0x4809,
Spanish_SpainTraditionalSort = 0x40a,
Spanish_Mexico = 0x80a,
Spanish_Spain = 0xc0a,
Spanish_Guatemala = 0x100a,
Spanish_CostaRica = 0x140a,
Spanish_Panama = 0x180a,
Spanish_DominicanRepublic = 0x1c0a,
Spanish_Venezuela = 0x200a,
Spanish_Colombia = 0x240a,
Spanish_Peru = 0x280a,
Spanish_Argentina = 0x2c0a,
Spanish_Ecuador = 0x300a,
Spanish_Chile = 0x340a,
Spanish_Uruguay = 0x380a,
Spanish_Paraguay = 0x3c0a,
Spanish_Bolivia = 0x400a,
Spanish_ElSalvador = 0x440a,
Spanish_Honduras = 0x480a,
Spanish_Nicaragua = 0x4c0a,
Spanish_PuertoRico = 0x500a,
Spanish_UnitedStates = 0x540a,
Spanish_LatinAmerica = 0x580a,
Finnish = 0x40b,
French_France = 0x40c,
French_Belgium = 0x80c,
French_Canada = 0xc0c,
French_Switzerland = 0x100c,
French_Luxembourg = 0x140c,
French_Monaco = 0x180c,
French_Caribbean = 0x1c0c,
French_Reunion = 0x200c,
French_CongoDRC = 0x240c,
French_Senegal = 0x280c,
French_Cameroon = 0x2c0c,
French_CoteDIvoire = 0x300c,
French_Mali = 0x340c,
French_Morocco = 0x380c,
French_Haiti = 0x3c0c,
Hebrew = 0x40d,
Hungarian = 0x40e,
Icelandic = 0x40f,
Italian_Italy = 0x410,
Italian_Switzerland = 0x810,
Japanese = 0x411,
Korean = 0x412,
Dutch_Netherlands = 0x413,
Dutch_Belgium = 0x813,
Norwegian_Bokmal = 0x414,
Norwegian_Nynorsk = 0x814,
Polish = 0x415,
Portuguese_Brazil = 0x416,
Portuguese_Portugal = 0x816,
Romansh = 0x417,
Romanian = 0x418,
Romanian_Moldova = 0x818,
Russian = 0x419,
Russian_Moldova = 0x819,
Croatian_Croatia = 0x41a,
Serbian_LatinSerbiaandMontenegroFormer = 0x81a,
Serbian_CyrillicSerbiaAndMontenegroFormer = 0xc1a,
Croatian_BosniaAndHerzegovina = 0x101a,
Bosnian_Latin = 0x141a,
Serbian_LatinBosniaAndHerzegovina = 0x181a,
Serbian_CyrillicBosniaAndHerzegovina = 0x1c1a,
Bosnian_Cyrillic = 0x201a,
Serbian_LatinSerbia = 0x241a,
Serbian_CyrillicSerbia = 0x281a,
Serbian_LatinMontenegro = 0x2c1a,
Serbian_CyrillicMontenegro = 0x301a,
Slovak = 0x41b,
Albanian = 0x41c,
Swedish_Sweden = 0x41d,
Swedish_Finland = 0x81d,
Thai = 0x41e,
Turkish = 0x41f,
Urdu_Pakistan = 0x420,
Urdu_India = 0x820,
Indonesian = 0x421,
Ukrainian = 0x422,
Belarusian = 0x423,
Slovenian = 0x424,
Estonian = 0x425,
Latvian = 0x426,
Lithuanian = 0x427,
Tajik = 0x428,
Persian = 0x429,
Vietnamese = 0x42a,
Armenian = 0x42b,
Azerbaijani_Latin = 0x42c,
Azerbaijani_Cyrillic = 0x82c,
Basque = 0x42d,
UpperSorbian = 0x42e,
LowerSorbian = 0x82e,
Macedonian = 0x42f,
Sesotho_SouthAfrica = 0x430,
Xitsonga = 0x431,
Setswana_SouthAfrica = 0x432,
Setswana_Botswana = 0x832,
Venda = 0x433,
isiXhosa = 0x434,
isiZulu = 0x435,
Afrikaans = 0x436,
Georgian = 0x437,
Faroese = 0x438,
Hindi = 0x439,
Maltese = 0x43a,
NorthernSami_Norway = 0x43b,
NorthernSami_Sweden = 0x83b,
NorthernSami_Finland = 0xc3b,
LuleSami_Norway = 0x103b,
LuleSami_Sweden = 0x143b,
SouthernSami_Norway = 0x183b,
SouthernSami_Sweden = 0x1c3b,
SkoltSami_Finland = 0x203b,
InariSami_Finland = 0x243b,
Irish = 0x83c,
Yiddish = 0x43d,
Malay_Malaysia = 0x43e,
Malay_BruneiDarussalam = 0x83e,
Kazakh = 0x43f,
Kyrgyz = 0x440,
Kiswahili = 0x441,
Turkmen = 0x442,
Uzbek_Latin = 0x443,
Uzbek_Cyrillic = 0x843,
Tatar = 0x444,
Bangla_India = 0x445,
Bangla_Bangladesh = 0x845,
Punjabi_India = 0x446,
Punjabi_Pakistan = 0x846,
Gujarati = 0x447,
Odia = 0x448,
Tamil_India = 0x449,
Tamil_SriLanka = 0x849,
Telugu = 0x44a,
Kannada = 0x44b,
Malayalam = 0x44c,
Assamese = 0x44d,
Marathi = 0x44e,
Sanskrit = 0x44f,
Mongolian_Cyrillic = 0x450,
Mongolian_TraditionalMongolianPRC = 0x850,
Mongolian_TraditionalMongolianMongolia = 0xc50,
Tibetan_PRC = 0x451,
Welsh = 0x452,
Khmer = 0x453,
Lao = 0x454,
Burmese = 0x455,
Galician = 0x456,
Konkani = 0x457,
Manipuri = 0x458,
Sindhi_Devanagari = 0x459,
Sindhi_Arabic = 0x859,
Syriac = 0x45a,
Sinhala = 0x45b,
Cherokee_Cherokee = 0x45c,
Inuktitut_Syllabics = 0x45d,
Inuktitut_Latin = 0x85d,
Amharic = 0x45e,
Tamazight_ArabicMorocco = 0x45f,
Tamazight_LatinAlgeria = 0x85f,
Tamazight_TifinaghMorocco = 0x105f,
Kashmiri_Arabic = 0x460,
Kashmiri = 0x860,
Nepali = 0x461,
Nepali_India = 0x861,
Frisian = 0x462,
Pashto = 0x463,
Filipino = 0x464,
Divehi = 0x465,
Edo = 0x466,
Fulah_Nigeria = 0x467,
Fulah_LatinSenegal = 0x867,
Hausa = 0x468,
Ibibio_Nigeria = 0x469,
Yoruba = 0x46a,
Quechua_Bolivia = 0x46b,
Quechua_Ecuador = 0x86b,
Quechua_Peru = 0xc6b,
SesothoSaLeboa = 0x46c,
Bashkir = 0x46d,
Luxembourgish = 0x46e,
Greenlandic = 0x46f,
Igbo = 0x470,
Kanuri = 0x471,
Oromo = 0x472,
Tigrinya_Ethiopia = 0x473,
Tigrinya_Eritrea = 0x873,
Guarani = 0x474,
Hawaiian = 0x475,
Latin = 0x476,
Somali = 0x477,
Yi_PRC = 0x478,
Papiamentu = 0x479,
Mapudungun = 0x47a,
Mohawk = 0x47c,
Breton = 0x47e,
Uyghur_PRC = 0x480,
Maori = 0x481,
Occitan = 0x482,
Corsican = 0x483,
Alsatian = 0x484,
Sakha = 0x485,
Kiche = 0x486,
Kinyarwanda = 0x487,
Wolof = 0x488,
Dari = 0x48c,
ScottishGaelic_UnitedKingdom = 0x491,
CentralKurdish_Iraq = 0x492
};
struct DirectoryListingEntry {
type::LEB128 nameLength;
char name[nameLength];
type::LEB128 contentSection;
type::LEB128 offset;
type::LEB128 length;
};
struct DirectoryIndexEntry {
type::LEB128 nameLength;
char name[nameLength];
type::LEB128 directoryListingChunk;
};
struct ListingChunk {
char magic[4];
if (magic == "PMGL") {
type::Size<u32> freeSpaceLength;
u32;
u32 prevChunkNumber, nextChunkNumber;
u16 directoryListingEntryCount @ addressof(this) + parent.directoryChunkSize - 2;
u16 offsets[(freeSpaceLength - 2) / 2] @ addressof(directoryListingEntryCount) - (freeSpaceLength - 2);
DirectoryListingEntry directories[directoryListingEntryCount];
$ = addressof(directoryListingEntryCount) + sizeof(directoryListingEntryCount);
} else if (magic == "PMGI") {
type::Size<u32> freeSpaceLength;
u16 directoryIndexEntryCount @ addressof(this) + parent.directoryChunkSize - 2;
u16 offsets[(freeSpaceLength - 2) / 2] @ addressof(directoryIndexEntryCount) - (freeSpaceLength - 2);
DirectoryIndexEntry indexes[directoryIndexEntryCount];
$ = addressof(directoryIndexEntryCount) + sizeof(directoryIndexEntryCount);
} else {
std::error("Invalid chunk magic!");
}
};
struct HeaderSection {
char magic[4];
if (magic == "\xFE\x01\x00\x00") {
u32;
type::Size<u64> fileSize;
u32;
u32;
} else if (magic == "ITSP") {
u32 version;
type::Size<u32> directoryHeaderLength1;
u32;
u32 directoryChunkSize;
u32 quickRefSectionDensity;
u32 indexTreeDepth;
u32 rootIndexChunkNumber;
u32 firstPMGLChunkNumber;
u32 lastPMGLChunkNumber;
u32;
u32 directoryChunkCount;
WindowsLanguageId languageId;
type::GUID guid;
type::Size<u32> directoryHeaderLength2;
u32;
u32;
u32;
ListingChunk chunk[directoryChunkCount];
} else {
std::error("Invalid header section magic!");
}
};
struct HeaderSectionTableEntry {
u64 offset;
type::Size<u64> size;
HeaderSection headerSection @ offset;
};
struct NameListEntry {
type::Size<u16> nameLength;
char16 name[nameLength];
padding[2];
};
struct NameListFile {
u16 fileLengthWords;
u16 entriesInFile;
NameListEntry nameList[entriesInFile];
padding[0x2E];
};
struct SectionData {
u32 fileLengthWords;
type::Magic<"LZXC"> magic;
u32 version;
u32 lzxResetInterval;
type::Size<u32> windowSize;
type::Size<u32> cacheSize;
u32;
};
struct Content {
NameListFile nameListFile;
SectionData sectionData;
};
struct CHM {
type::Magic<"ITSF"> magic;
u32 version;
type::Size<u32> headerSize;
u32;
be u32 timeStamp;
WindowsLanguageId languageId;
type::GUID guids[2];
HeaderSectionTableEntry headerSectionTable[2];
Content *dataOffset : u64;
};
CHM chm @ 0x00;

View File

@@ -1,7 +1,10 @@
#pragma author WerWolv
#pragma description Common Object File Format (COFF) executable
#pragma MIME application/x-coff
#include <type/time.pat>
#include <type/size.pat>
import type.time;
import type.size;
enum Machine : u16 {
Unknown = 0x0000,

View File

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

View File

@@ -1,3 +1,5 @@
#pragma description DirectDraw Surface
#pragma MIME image/vnd-ms.dds
#pragma endian little

View File

@@ -1,4 +1,6 @@
#include <type/leb128.pat>
#pragma description Dalvik EXecutable Format
import type.leb128;
struct header_item {
u8 magic[8];

5594
patterns/dicom.hexpat Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,11 @@
#pragma description Apple Disk Image Trailer (DMG)
#pragma endian big
#include <type/magic.pat>
#include <type/size.pat>
#include <type/guid.pat>
#include <std/mem.pat>
import type.magic;
import type.size;
import type.guid;
import std.mem;
// Parse DMG Structure per http://newosxbook.com/DMG.html
//

View File

@@ -1,6 +1,8 @@
#pragma description .DS_Store file format
// Apple macOS .DS_Store format
#pragma endian big
#include <std/io.pat>
import std.io;
struct RecordEntry {
u32 length;

View File

@@ -1,12 +1,15 @@
#pragma author WerWolv
#pragma description ELF header in elf binaries
#pragma MIME application/x-executable
#pragma MIME application/x-elf
#pragma MIME application/x-coredump
#pragma MIME application/x-object
#pragma MIME application/x-sharedlib
#include <std/core.pat>
#include <std/io.pat>
#include <std/mem.pat>
import std.core;
import std.io;
import std.mem;
using BitfieldOrder = std::core::BitfieldOrder;
@@ -563,7 +566,7 @@ struct Elf32_Phdr {
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())
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]];
};
@@ -577,7 +580,7 @@ struct Elf64_Phdr {
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())
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]];
};
@@ -714,14 +717,9 @@ fn format_section_header(auto shdr) {
u32 i = 0;
u32 nameAddress = addressof(elf.shdr[stringTableIndex].stringTable) + shdr.sh_name;
while (i < std::core::member_count(elf.shdr[stringTableIndex].stringTable)) {
if (nameAddress >= addressof(elf.shdr[stringTableIndex].stringTable[i]) && nameAddress < (addressof(elf.shdr[stringTableIndex].stringTable[i]) + sizeof(elf.shdr[stringTableIndex].stringTable[i])))
break;
i += 1;
}
String string @ nameAddress;
return elf.shdr[stringTableIndex].stringTable[i].value;
return string;
};
@@ -819,4 +817,4 @@ fn main() {
);
}
}
};
};

View File

@@ -1,3 +1,5 @@
#pragma description MS Windows Vista Event Log
#pragma endian little
struct Header {

View File

@@ -0,0 +1,111 @@
#pragma author DmitriLeon2000
#pragma description Oska Software DeskMates FAS (Frames and Sequences) file
#pragma endian little
enum Compression : u32 {
BI_RGB,
BI_RLE8,
BI_RLE4,
BI_BITFIELDS,
BI_JPEG,
BI_PNG,
BI_ALPHABITFIELDS,
BI_CMYK,
BI_CMYKRLE8,
BI_CMYKRLE4,
};
struct Colors {
u8 blue;
u8 green;
u8 red;
u8 reserved;
};
struct FASHeader {
char name[50]; // name of the pack, may include garbage data
u16 version; // Format version number
s16 frameIDFirst; // assigned ID of the first frame
s16 frameIDLast; // assigned ID of the last frame
s32 width; // width of the animation (in pixels)
s32 height; // height of the animation (in pixels)
u16 frameSize; // size of the animation ((frameWidth * BPP + 31) // 32 * 4 * frameHeight)
u16 DblHeaderCount; // amount of BitmapInfoHeader pairs (one for color, one for masking)
};
struct BitmapInfoHeader { // bog-standard BitmapInfoHeaderV1
u32 biSize;
s32 biWidth;
s32 biHeight;
u16 biPlanes;
u16 biBitCount;
Compression compression;
u32 biSizeImage;
s32 biXPelsPerMeter;
s32 biYPelsPerMeter;
u32 biClrUsed;
u32 biClrImportant;
};
struct BitmapInfo {
BitmapInfoHeader header;
Colors colorMap[header.biClrUsed == 0 ?
1 << header.biBitCount : header.biClrUsed];
};
struct ExtraSprite {
char name[];
};
struct AnimSequence {
char name[];
char sequence[];
};
struct SeqHeader {
le u32 size;
le u32 count;
le u32 strPointers[count*2];
};
struct Bitmap {
u8 byte[fas.fasHeader.version >= 3 ? fas.fasHeader.frameSize + (fas.frameSizeHigh << 16) : fas.fasHeader.frameSize];
};
struct FramesHeader {
le u32 count;
le s16 frameID[count];
u8 frameDblHdrID[count];
};
struct FAS {
FASHeader fasHeader;
BitmapInfo dibHeaders[fasHeader.DblHeaderCount * 2];
if (fasHeader.version >= 1)
u8 charID;
if (fasHeader.version >= 2)
{
u32 extraEndOffset;
u16 extraSpritesCount;
if (extraSpritesCount)
// char extraSpriteList[touchOffset - 6];
ExtraSprite extraSprites[extraSpritesCount];
}
if (fasHeader.version >= 3)
le u16 frameSizeHigh;
le u16 touchColors;
if (touchColors)
{
u32 touchColorMap[touchColors];
u16 touchWidth;
u8 touchBitmap[this.touchWidth * fasHeader.height];
}
SeqHeader seqHeader;
if (fasHeader.version >= 1)
u8 filenameChecksum; // a checksum for a filename in ASCII
AnimSequence sequences[seqHeader.count];
FramesHeader framesHeader;
};
FAS fas @ 0x00;
Bitmap framesBitmap[fas.framesHeader.count] @ $;

View File

@@ -0,0 +1,87 @@
#pragma author DmitriLeon2000
#pragma description Oska Software DeskMates FAS (Frames and Sequences) file (Oska DeskMate versions 1.3 and 2.06)
#pragma endian little
enum Compression : u32 {
BI_RGB,
BI_RLE8,
BI_RLE4,
BI_BITFIELDS,
BI_JPEG,
BI_PNG,
BI_ALPHABITFIELDS,
BI_CMYK,
BI_CMYKRLE8,
BI_CMYKRLE4,
};
struct Colors {
u8 blue;
u8 green;
u8 red;
u8 reserved;
};
struct FASHeader {
s32 width; // width of the animation (in pixels)
s32 height; // height of the animation (in pixels)
u16 reserved1;
u16 reserved2;
u16 frameSizeCombined; // a sum of frameSizeColor and frameSizeMask
u16 frameSizeColor; // size of the animation ((frameWidth * 4 + 31) // 32 * 4 * frameHeight)
u16 frameSizeMask; // size of the animation's mask ((frameWidth * 1 + 31) // 32 * 4 * frameHeight)
u16 headerCount; // amount of DIB headers
};
struct BitmapInfoHeader { // bog-standard BitmapInfoHeaderV1
u32 biSize;
s32 biWidth;
s32 biHeight;
u16 biPlanes;
u16 biBitCount;
Compression compression;
u32 biSizeImage;
s32 biXPelsPerMeter;
s32 biYPelsPerMeter;
u32 biClrUsed;
u32 biClrImportant;
};
struct BitmapInfo {
BitmapInfoHeader header;
le u32 colorMap[header.biClrUsed == 0 ?
1 << header.biBitCount : header.biClrUsed];
};
struct AnimSequence {
char name[];
char sequence[];
};
struct SeqHeader {
le u32 size;
le u32 count;
le u32 strPointers[count*2];
};
struct Frame {
u8 colorBitmap[fas.fasHeader.frameSizeColor];
u8 maskBitmap[fas.fasHeader.frameSizeMask];
};
struct FramesHeader {
le u32 count;
le s16 frameID[count];
};
struct FAS {
FASHeader fasHeader;
BitmapInfo dibHeaders[fasHeader.headerCount];
SeqHeader seqHeader;
AnimSequence sequences[seqHeader.count];
FramesHeader framesHeader;
};
FAS fas @ 0x00;
Frame frames[fas.framesHeader.count] @ $;

125
patterns/fdt.hexpat Normal file
View File

@@ -0,0 +1,125 @@
#pragma author WerWolv
#pragma description Flat Linux Device Tree blob
#pragma endian big
import std.sys;
import std.io;
import std.core;
import type.magic;
import type.size;
// These are used in order for the children to be able to find strings
u64 fdt_addr;
u64 str_offset;
struct FDTHeader {
type::Magic<"\xD0\x0D\xFE\xED"> magic;
u32 totalsize;
u32 off_dt_struct;
u32 off_dt_strings;
u32 off_mem_rsvmap;
u32 version;
u32 last_comp_version;
u32 boot_cpuid_phys;
u32 size_dt_strings;
u32 size_dt_struct;
};
struct AlignTo<auto Alignment> {
padding[Alignment- ((($ - 1) % Alignment) + 1)];
} [[hidden]];
struct FDTReserveEntry {
u64 address;
type::Size<u64> size;
if (address == 0x00 && size == 0x00)
break;
};
enum FDTToken : u32 {
FDT_BEGIN_NODE = 0x00000001,
FDT_END_NODE = 0x00000002,
FDT_PROP = 0x00000003,
FDT_NOP = 0x00000004,
FDT_END = 0x00000009
};
union FDTPropValue<auto len> {
u32 prop_array[len / sizeof(u32)];
char string[len];
};
struct FDTProp {
FDTToken tok[[hidden]];
u32 len [[hidden]];
u32 nameoff [[hidden]];
if (len > 0) {
// if len is zero, value is absent and no need to include it
FDTPropValue<len> value;
}
AlignTo<4>;
char name[] @ fdt_addr + str_offset + nameoff;
std::core::set_display_name(this, name);
std::print(std::format("{:x} token {} len {} {}",
$, tok, len,nameoff));
FDTToken token = std::mem::read_unsigned($, 4, std::mem::Endian::Big);
if (token != FDTToken::FDT_PROP) {
break;
}
};
struct FDTNode {
FDTToken token = std::mem::read_unsigned($, 4, std::mem::Endian::Big);
if (token == FDTToken::FDT_BEGIN_NODE) {
FDTToken tok[[hidden]];
char name[];
AlignTo<4>;
std::core::set_display_name(this, name[0] ? name : "/");
token = std::mem::read_unsigned($, 4, std::mem::Endian::Big);
if(token == FDTToken::FDT_PROP) {
FDTProp props[while(true)];
}
token = std::mem::read_unsigned($, 4, std::mem::Endian::Big);
if(token == FDTToken::FDT_END_NODE) {
FDTToken[[hidden]];
break;
}
FDTNode children[while(true)][[inline]];
} else if(token == FDTToken::FDT_NOP) {
// TODO this may break the pattern, I've so far not encountered it
}
// ew duplication
token = std::mem::read_unsigned($, 4, std::mem::Endian::Big);
if(token == FDTToken::FDT_END_NODE) {
FDTToken[[hidden]];
break;
}
};
struct FDTStructureBlock {
FDTNode;
};
struct FDT {
FDTHeader header;
std::assert(header.version == 17, "Unsupported format version");
fdt_addr = addressof(this);
str_offset = header.off_dt_strings;
FDTStructureBlock structureBlocks @ fdt_addr + header.off_dt_struct;
FDTReserveEntry reserveEntries[while(true)] @ fdt_addr + header.off_mem_rsvmap;
};
std::mem::MagicSearch<"\xD0\x0D\xFE\xED", FDT> fdt @ std::mem::base_address();

View File

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

1
patterns/ffx Submodule

Submodule patterns/ffx added at ad18b0259f

View File

@@ -1,6 +1,9 @@
#include <std/sys.pat>
#include <std/core.pat>
#include <std/io.pat>
#pragma author WerWolv
#pragma description Free Lossless Audio Codec, FLAC Audio Format
import std.sys;
import std.core;
import std.io;
#pragma endian big
@@ -304,6 +307,8 @@ struct METADATA_BLOCK {
METADATA_BLOCK_PADDING data;
else if (header.blockType == BLOCK_TYPE::APPLICATION)
METADATA_BLOCK_APPLICATION data;
else if (header.blockType == BLOCK_TYPE::SEEKTABLE)
METADATA_BLOCK_SEEKTABLE data;
else if (header.blockType == BLOCK_TYPE::VORBIS_COMMENT)
METADATA_BLOCK_VORBIS_COMMENT data;
else if (header.blockType == BLOCK_TYPE::CUESHEET)
@@ -320,4 +325,4 @@ struct STREAM {
//FRAME frames[while(!std::mem::eof())];
};
STREAM stream @ 0x00;
STREAM stream @ 0x00;

View File

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

View File

@@ -1,337 +1,361 @@
#include <type/size.pat>
#include <std/io.pat>
#include <std/string.pat>
#pragma author WerWolv
#pragma description Gameboy ROM
#pragma MIME application/x-gameboy-rom
import type.size;
import std.string;
import std.mem;
bool uppercaseROMFeatures in;
bool brandedROMFeatures in;
bitfield CGB {
padding : 2;
PGB_MODE : 2;
padding : 2;
CGB_ONLY : 1 [[comment("gbcOnly")]];
CGB_SUPPORT : 1 [[comment("supportsGBC")]];
} [[comment("GBCFlags")]];
namespace format {
fn rom_type(u8 romType) {
u32 romSize = 32768 * (1 << romType);
u16 romBanks = 2 * (1 << romType);
if(romType == 0x52) {
romSize = 1153434;
romBanks = 72;
}
if(romType == 0x53) {
romSize = 1258291;
romBanks = 80;
}
return std::format("size: {}, banks: {}", type::impl::size_formatter(romSize), romBanks);
};
fn ram_type(u8 ramType) {
u16 ramSize;
u16 ramBanks;
if(ramType == 2) {
ramSize = 8192;
ramBanks = 1;
}
if(ramType == 3) {
ramSize = 32768;
ramBanks = 4;
}
if(ramType == 4) {
ramSize = 131072;
ramBanks = 16;
}
if(ramType == 5) {
ramSize = 65536;
ramBanks = 8;
}
return std::format("size: {}, banks: {}", type::impl::size_formatter(ramSize), ramBanks);
};
fn rom_features(u8 type) {
str result = "( ";
match(type) {
(0x00): result += "no_mbc ";
(0x01): result += "mbc1 ";
(0x02): result += "mbc1 | ram ";
(0x03): result += "mbc1 | ram | battery ";
(0x05): result += "mbc2 ";
(0x06): result += "mbc2 | battery ";
(0x08): result += "no_mbc | ram ";
(0x09): result += "no_mbc | ram | battery ";
(0x0B): result += "mmm01 ";
(0x0C): result += "mmm01 | ram ";
(0x0D): result += "mmm01 | ram | battery ";
(0x0F): result += "mbc3 | timer | battery ";
(0x10): result += "mbc3 | timer | ram | battery ";
(0x11): result += "mbc3 ";
(0x12): result += "mbc3 | ram ";
(0x13): result += "mbc3 | ram | battery ";
(0x19): result += "mbc5 ";
(0x1A): result += "mbc5 | ram ";
(0x1B): result += "mbc5 | ram | battery ";
(0x1C): result += "mbc5 | rumble ";
(0x1D): result += "mbc5 | rumble | ram ";
(0x1E): result += "mbc5 | rumble | ram | battery ";
(0x20): result += "mbc6 ";
(0x22): result += "mbc7 | sensor | rumble ";
(0xFC): result += "camera ";
(0xFD): result += "tama5 ";
(0xFE): result += "huc3 ";
(0xFF): result += "huc1 | ram | battery ";
}
return result + ")";
};
fn licensee_code(u8 code) {
match(code) {
(0x00): return "None";
(0x01 | 0x31): return "Nintendo";
(0x08 | 0x38): return "Capcom";
(0x09): return "Hot-B";
(0x0A | 0xE0): return "Jaleco";
(0x0B): return "Coconuts Japan";
(0x0C | 0x6E): return "Elite Systems";
(0x13 | 0x69): return "EA (Electronic Arts)";
(0x18): return "Hudsonsoft";
(0x19): return "ITC Entertainment";
(0x1A): return "Yanoman";
(0x1D): return "Japan Clary";
(0x1F | 0x4A | 0x61): return "Virgin Interactive";
(0x24): return "PCM Complete";
(0x25): return "San-X";
(0x28): return "Kotobuki Systems";
(0x29): return "Seta";
(0x30 | 0x70): return "Infogrames";
(0x32 | 0xA2 | 0xB2 | 0xC4): return "Bandai";
(0x33): return "See new licensee";
(0x34 | 0xA4): return "Konami";
(0x35): return "HectorSoft";
(0x39 | 0x9D): return "Banpresto";
(0x3C): return ".Entertainment i";
(0x3E): return "Gremlin";
(0x41): return "Ubisoft";
(0x42 | 0xEB): return "Atlus";
(0x44 | 0x4D): return "Malibu";
(0x46 | 0xCF): return "Angel";
(0x47): return "Spectrum Holoby";
(0x49): return "Irem";
(0x50): return "Absolute";
(0x51 | 0xB0): return "Acclaim";
(0x52): return "Activision";
(0x53): return "American Sammy";
(0x54): return "GameTek";
(0x55): return "Park Place";
(0x56 | 0xDB | 0xFF): return "LJN";
(0x57): return "Matchbox";
(0x59): return "Milton Bradley";
(0x5A): return "Mindscape";
(0x5B): return "Romstar";
(0x5C | 0xD6): return "Naxat Soft";
(0x5D): return "Tradewest";
(0x60): return "Titus";
(0x67): return "Ocean Interactive";
(0x6F): return "Electro Brain";
(0x71): return "Interplay";
(0x72 | 0xAA): return "Broderbund";
(0x73): return "Sculptered Soft";
(0x75): return "The Sales Curve";
(0x78): return "t.hq";
(0x79): return "Accolade";
(0x7A): return "Triffix Entertainment";
(0x7C): return "Microprose";
(0x7F | 0xC2): return "Kemco";
(0x80): return "Misawa Entertainment";
(0x83): return "Lozc";
(0x86 | 0xC4): return "Tokuma Shoten Intermedia";
(0x8B): return "Bullet-Proof Software";
(0x8C): return "Vic Tokai";
(0x8E): return "Ape";
(0x8F): return "I'Max";
(0x91): return "Chunksoft Co.";
(0x92): return "Video System";
(0x93): return "Tsubaraya Productions Co.";
(0x95): return "Varie Corporation";
(0x96): return "Yonezawa/SPal";
(0x97): return "Kaneko";
(0x99): return "Arc";
(0x9A): return "Nihon Bussan";
(0x9B): return "Tecmo";
(0x9C): return "Imagineer";
(0x9F): return "Nova";
(0xA1): return "Hori Electric";
(0xA6): return "Kawada";
(0xA7): return "Takara";
(0xA9): return "Technos Japan";
(0xAC): return "Toei Animation";
(0xAD): return "Toho";
(0xAF): return "Namco";
(0xB1): return "ASCII or Nexsoft";
(0xB4): return "Square Enix";
(0xB6): return "HAL Laboratory";
(0xB7): return "SNK";
(0xB9 | 0xCE): return "Pony Canyon";
(0xBA): return "Culture Brain";
(0xBB): return "Sunsoft";
(0xBD): return "Sony Imagesoft";
(0xBF): return "Sammy";
(0xC0 | 0xD0): return "Taito";
(0xC3): return "Squaresoft";
(0xC5): return "Data East";
(0xC6): return "Tonkinhouse";
(0xC8): return "Koei";
(0xC9): return "UFL";
(0xCA): return "Ultra";
(0xCB): return "Vap";
(0xCC): return "Use Corporation";
(0xCD): return "Meldac";
(0xD1): return "Sofel";
(0xD2): return "Quest";
(0xD3): return "Sigma Enterprises";
(0xD4): return "ASK Kodansha Co.";
(0xD7): return "Copya System";
(0xDA): return "Tomy";
(0xDD): return "NCS";
(0xDE): return "Human";
(0xDF): return "Altron";
(0xE1): return "Towa Chiki";
(0xE2): return "Yutaka";
(0xE3): return "Varie";
(0xE5): return "Epoch";
(0xE7): return "Athena";
(0xE8): return "Asmik";
(0xE9): return "Natsume";
(0xEA): return "King Records";
(0xEE): return "IGS";
(0xF0): return "A Wave";
(0xF3): return "Extreme Entertainment";
}
return "Unknown Licensee";
};
fn new_licensee_code(str a) {
if(a[0] == 0 && a[1] == 0) return "See old licensee";
match(a) {
("00"): return "None";
("01"): return "Nintendo R&D1";
("08"): return "Capcom";
("13"): return "Electronic Arts";
("18"): return "Hudson Soft";
("19"): return "b-ai";
("20"): return "kss";
("22"): return "pow";
("24"): return "PCM Complete";
("25"): return "san-x";
("28"): return "Kemco Japan";
("29"): return "seta";
("30"): return "Viacom";
("31"): return "Nintendo";
("32"): return "Bandai";
("33"): return "Ocean/Acclaim";
("34"): return "Konami";
("35"): return "Hector";
("37"): return "Taito";
("38"): return "Hudson";
("39"): return "Banpresto";
("41"): return "Ubi Soft";
("42"): return "Atlus";
("44"): return "Malibu";
("46"): return "angel";
("47"): return "Bullet-Proof";
("49"): return "irem";
("50"): return "Absolute";
("51"): return "Acclaim";
("52"): return "Activision";
("53"): return "American sammy";
("54"): return "Konami";
("55"): return "Hi tech entertainment";
("56"): return "LJN";
("57"): return "Matchbox";
("58"): return "Mattel";
("59"): return "Milton Bradley";
("60"): return "Titus";
("61"): return "Virgin";
("64"): return "LucasArts";
("67"): return "Ocean";
("69"): return "Electronic Arts";
("70"): return "Infogrames";
("71"): return "Interplay";
("72"): return "Broderbund";
("73"): return "sculptured";
("75"): return "sci";
("78"): return "THQ";
("79"): return "Accolade";
("80"): return "misawa";
("83"): return "lozc";
("86"): return "Tokuma Shoten Intermedia";
("87"): return "Tsukuda Original";
("91"): return "Chunksoft";
("92"): return "Video system";
("93"): return "Ocean/Acclaim";
("95"): return "Varie";
("96"): return "Yonezawa/spal";
("97"): return "Kaneko";
("99"): return "Pack in soft";
("A4"): return "Konami (Yu-Gi-Oh!)";
}
return "Unknown";
};
fn cart_size(u8 cartSizeType) {
u32 romSize = 32768 * (1 << cartSizeType);
u16 romBanks = 2 * (1 << cartSizeType);
if (cartSizeType == 0x52) {
romSize = 1153434;
romBanks = 72;
}
if (cartSizeType == 0x53) {
romSize = 1258291;
romBanks = 80;
}
return std::format("size: {}, banks: {}", type::impl::size_formatter(romSize), romBanks);
};
fn ram_type(u8 ramType) {
u16 ramSize;
u16 ramBanks;
if(ramType == 2) {
ramSize = 8192;
ramBanks = 1;
}
if(ramType == 3) {
ramSize = 32768;
ramBanks = 4;
}
if(ramType == 4) {
ramSize = 131072;
ramBanks = 16;
}
if(ramType == 5) {
ramSize = 65536;
ramBanks = 8;
}
return std::format("size: {}, banks: {}", type::impl::size_formatter(ramSize), ramBanks);
};
fn rom_features(u8 type) {
str result = "( ";
if (brandedROMFeatures) match(type) {
(0xFC): result += "pocket ";
(0xFD): result += "bandai ";
}
match(type) {
(0x00): result += "no_mbc";
(0x01): result += "mbc1";
(0x02): result += "mbc1 | ram";
(0x03): result += "mbc1 | ram | battery";
(0x05): result += "mbc2";
(0x06): result += "mbc2 | battery";
(0x08): result += "no_mbc | ram";
(0x09): result += "no_mbc | ram | battery";
(0x0B): result += "mmm01";
(0x0C): result += "mmm01 | ram";
(0x0D): result += "mmm01 | ram | battery";
(0x0F): result += "mbc3 | timer | battery";
(0x10): result += "mbc3 | timer | ram | battery";
(0x11): result += "mbc3";
(0x12): result += "mbc3 | ram";
(0x13): result += "mbc3 | ram | battery";
(0x19): result += "mbc5";
(0x1A): result += "mbc5 | ram";
(0x1B): result += "mbc5 | ram | battery";
(0x1C): result += "mbc5 | rumble";
(0x1D): result += "mbc5 | rumble | ram";
(0x1E): result += "mbc5 | rumble | ram | battery";
(0x20): result += "mbc6";
(0x22): result += "mbc7 | sensor | rumble";
(0xFC): result += "camera";
(0xFD): result += "tama5";
(0xFE): result += "huc3";
(0xFF): result += "huc1 | ram | battery";
}
if (uppercaseROMFeatures) result = std::string::to_upper(result);
return result + " )";
};
fn licensee_code(u8 code) {
match(code) {
(0x00): return "None";
(0x01 | 0x31): return "Nintendo";
(0x08 | 0x38): return "Capcom";
(0x09): return "Hot-B";
(0x0A | 0xE0): return "Jaleco";
(0x0B): return "Coconuts Japan";
(0x0C | 0x6E): return "Elite Systems";
(0x13 | 0x69): return "EA (Electronic Arts)";
(0x18): return "Hudsonsoft";
(0x19): return "ITC Entertainment";
(0x1A): return "Yanoman";
(0x1D): return "Japan Clary";
(0x1F | 0x4A | 0x61): return "Virgin Interactive";
(0x24): return "PCM Complete";
(0x25): return "San-X";
(0x28): return "Kotobuki Systems";
(0x29): return "Seta";
(0x30 | 0x70): return "Infogrames";
(0x32 | 0xA2 | 0xB2 | 0xC4): return "Bandai";
(0x33): return "See new licensee code";
(0x34 | 0xA4): return "Konami";
(0x35): return "HectorSoft";
(0x39 | 0x9D): return "Banpresto";
(0x3C): return ".Entertainment i";
(0x3E): return "Gremlin";
(0x41): return "Ubisoft";
(0x42 | 0xEB): return "Atlus";
(0x44 | 0x4D): return "Malibu";
(0x46 | 0xCF): return "Angel";
(0x47): return "Spectrum Holoby";
(0x49): return "Irem";
(0x50): return "Absolute";
(0x51 | 0xB0): return "Acclaim";
(0x52): return "Activision";
(0x53): return "American Sammy";
(0x54): return "GameTek";
(0x55): return "Park Place";
(0x56 | 0xDB | 0xFF): return "LJN";
(0x57): return "Matchbox";
(0x59): return "Milton Bradley";
(0x5A): return "Mindscape";
(0x5B): return "Romstar";
(0x5C | 0xD6): return "Naxat Soft";
(0x5D): return "Tradewest";
(0x60): return "Titus";
(0x67): return "Ocean Interactive";
(0x6F): return "Electro Brain";
(0x71): return "Interplay";
(0x72 | 0xAA): return "Broderbund";
(0x73): return "Sculptered Soft";
(0x75): return "The Sales Curve";
(0x78): return "t.hq";
(0x79): return "Accolade";
(0x7A): return "Triffix Entertainment";
(0x7C): return "Microprose";
(0x7F | 0xC2): return "Kemco";
(0x80): return "Misawa Entertainment";
(0x83): return "Lozc";
(0x86 | 0xC4): return "Tokuma Shoten Intermedia";
(0x8B): return "Bullet-Proof Software";
(0x8C): return "Vic Tokai";
(0x8E): return "Ape";
(0x8F): return "I'Max";
(0x91): return "Chunksoft Co.";
(0x92): return "Video System";
(0x93): return "Tsubaraya Productions Co.";
(0x95): return "Varie Corporation";
(0x96): return "Yonezawa/SPal";
(0x97): return "Kaneko";
(0x99): return "Arc";
(0x9A): return "Nihon Bussan";
(0x9B): return "Tecmo";
(0x9C): return "Imagineer";
(0x9F): return "Nova";
(0xA1): return "Hori Electric";
(0xA6): return "Kawada";
(0xA7): return "Takara";
(0xA9): return "Technos Japan";
(0xAC): return "Toei Animation";
(0xAD): return "Toho";
(0xAF): return "Namco";
(0xB1): return "ASCII or Nexsoft";
(0xB4): return "Square Enix";
(0xB6): return "HAL Laboratory";
(0xB7): return "SNK";
(0xB9 | 0xCE): return "Pony Canyon";
(0xBA): return "Culture Brain";
(0xBB): return "Sunsoft";
(0xBD): return "Sony Imagesoft";
(0xBF): return "Sammy";
(0xC0 | 0xD0): return "Taito";
(0xC3): return "Squaresoft";
(0xC5): return "Data East";
(0xC6): return "Tonkinhouse";
(0xC8): return "Koei";
(0xC9): return "UFL";
(0xCA): return "Ultra";
(0xCB): return "Vap";
(0xCC): return "Use Corporation";
(0xCD): return "Meldac";
(0xD1): return "Sofel";
(0xD2): return "Quest";
(0xD3): return "Sigma Enterprises";
(0xD4): return "ASK Kodansha Co.";
(0xD7): return "Copya System";
(0xDA): return "Tomy";
(0xDD): return "NCS";
(0xDE): return "Human";
(0xDF): return "Altron";
(0xE1): return "Towa Chiki";
(0xE2): return "Yutaka";
(0xE3): return "Varie";
(0xE5): return "Epoch";
(0xE7): return "Athena";
(0xE8): return "Asmik";
(0xE9): return "Natsume";
(0xEA): return "King Records";
(0xEE): return "IGS";
(0xF0): return "A Wave";
(0xF3): return "Extreme Entertainment";
}
return "Unknown Licensee";
};
fn new_licensee_code(str a) {
if (std::mem::read_unsigned(0x14B, 1) != 0x33) return "See old licensee code";
match(a) {
("00"): return "None";
("01"): return "Nintendo R&D1";
("08"): return "Capcom";
("13"): return "Electronic Arts";
("18"): return "Hudson Soft";
("19"): return "b-ai";
("20"): return "KSS";
("22"): return "pow";
("24"): return "PCM Complete";
("25"): return "san-x";
("28"): return "Kemco Japan";
("29"): return "seta";
("30"): return "Viacom";
("31"): return "Nintendo";
("32"): return "Bandai";
("33"): return "Ocean/Acclaim";
("34"): return "Konami";
("35"): return "Hector";
("37"): return "Taito";
("38"): return "Hudson";
("39"): return "Banpresto";
("41"): return "Ubi Soft";
("42"): return "Atlus";
("44"): return "Malibu";
("46"): return "Angel";
("47"): return "Bullet-Proof Software";
("49"): return "irem";
("50"): return "Absolute";
("51"): return "Acclaim";
("52"): return "Activision";
("53"): return "American Sammy";
("54"): return "Konami";
("55"): return "Hi tech entertainment";
("56"): return "LJN";
("57"): return "Matchbox";
("58"): return "Mattel";
("59"): return "Milton Bradley";
("60"): return "Titus";
("61"): return "Virgin";
("64"): return "LucasArts";
("67"): return "Ocean";
("69"): return "Electronic Arts";
("70"): return "Infogrames";
("71"): return "Interplay";
("72"): return "Broderbund";
("73"): return "sculptured";
("75"): return "sci";
("78"): return "THQ";
("79"): return "Accolade";
("80"): return "misawa";
("83"): return "lozc";
("86"): return "Tokuma Shoten Intermedia";
("87"): return "Tsukuda Original";
("91"): return "Chunksoft";
("92"): return "Video system";
("93"): return "Ocean/Acclaim";
("95"): return "Varie";
("96"): return "Yonezawa/spal";
("97"): return "Kaneko";
("99"): return "Pack in soft";
("A4"): return "Konami (Yu-Gi-Oh!)";
}
return "Unknown";
};
using CGB;
fn null_cgb_flags(CGB flags) {
return "NO_CGB";
};
}
enum DestinationType : u8 {
Japanese,
NonJapanese
};
enum SGBFlagType : u8 {
NoSGBFunctionality,
SGBFunctionality = 0x03
};
struct Header {
char title[16-(std::mem::read_unsigned(addressof(this)+15, 1) >= 0x80)];
if (std::mem::read_unsigned(addressof(this)+15, 1) == 0)
CGB gbcFlags @ $-1 [[format("format::null_cgb_flags")]];
else if (std::mem::read_unsigned(addressof(this)+15, 1) >= 0x80)
CGB gbcFlags;
char newLicenseeCode[2] [[format("format::new_licensee_code")]];
SGBFlagType sgbFlag;
u8 romType [[format("format::rom_features")]];
u8 cartSize [[format("format::cart_size")]];
u8 ramType [[format("format::ram_type")]];
DestinationType destination;
u8 licenseeCode [[format("format::licensee_code")]];
u8 maskROMVersionNumber;
u8 headerChecksum [[comment("Checksum for: $134-$14C")]];
u16 globalChecksum [[comment("Checksum for entire range")]];
};
bitfield pixel_packed {
p1 : 1;
p2 : 1;
p3 : 1;
p4 : 1;
p5 : 1;
p6 : 1;
p7 : 1;
p8 : 1;
p1 : 1;
p2 : 1;
p3 : 1;
p4 : 1;
p5 : 1;
p6 : 1;
p7 : 1;
p8 : 1;
};
enum CGB : u8 {
NO_CGB = 0x00 ... 0x7F,
BACKWARDS_COMPATIBLE = 0x80,
CGB_ONLY = 0xC0
};
struct Logo {
pixel_packed rawData[0x30];
struct CartridgeStart {
u8 entryCode[4];
pixel_packed logo[0x30];
Header header;
};
struct JumpVectors {
u8 rst1[8] [[comment("rst $1")]];
u8 rst2[8] [[comment("rst $2")]];
u8 rst3[8] [[comment("rst $3")]];
u8 rst4[8] [[comment("rst $4")]];
u8 rst5[8] [[comment("rst $5")]];;
u8 rst6[8] [[comment("rst $6")]];
u8 rst7[8] [[comment("rst $7")]];
u8 rst8[8] [[comment("rst $8")]];
u8 int1[8] [[comment("vblank")]];
u8 int2[8] [[comment("lcd stat")]];
u8 int3[8] [[comment("timer")]];
u8 int4[8] [[comment("serial")]];
u8 int5[8] [[comment("joypad")]];
};
struct Header {
u32 jmpInstruction;
Logo logo;
char title[0xF];
CGB cgb;
char newLicenseeCode[2] [[format("format::new_licensee_code")]];
bool sgbFlag;
u8 type [[format("format::rom_features")]];
u8 romType [[format("format::rom_type")]];
u8 ramType [[format("format::ram_type")]];
bool japanOnly;
u8 licenseeCode [[format("format::licensee_code")]];
u8 version;
u8 checksum [[comment("Checksum for: $134-$14C")]];
u16 gloalChecksum [[comment("Checksum for entire range")]];
u8 rst1[8] [[comment("rst $1")]];
u8 rst2[8] [[comment("rst $2")]];
u8 rst3[8] [[comment("rst $3")]];
u8 rst4[8] [[comment("rst $4")]];
u8 rst5[8] [[comment("rst $5")]];
u8 rst6[8] [[comment("rst $6")]];
u8 rst7[8] [[comment("rst $7")]];
u8 rst8[8] [[comment("rst $8")]];
u8 int1[8] [[comment("vblank")]];
u8 int2[8] [[comment("lcd stat")]];
u8 int3[8] [[comment("timer")]];
u8 int4[8] [[comment("serial")]];
u8 int5[8] [[comment("joypad")]];
};
struct Cartrige {
JumpVectors jumpVectors [[comment("Instructions called on interupts or rst instructions")]];
padding[0x100 - sizeof(JumpVectors)];
Header header;
};
Cartrige cart @ 0x00;
JumpVectors jumpVectors @ 0x00 [[comment("Instructions called on interrupts or RST instructions")]];
CartridgeStart cartridgeStart @ 0x100;

View File

@@ -1,3 +1,5 @@
#pragma description GIF image files
#pragma MIME image/gif
// Extension Labels
@@ -11,13 +13,13 @@
#define EXTENSION_INTRODUCER_MAGIC 0x21
#define GIF_TRAILER_MAGIC 0x3B
#include <std/io.pat>
#include <std/core.pat>
#include <std/mem.pat>
#include <std/string.pat>
#include <std/math.pat>
import std.io;
import std.core;
import std.mem;
import std.string;
import std.math;
#include <type/magic.pat>
import type.magic;
bitfield GCT_Flags {
size : 3 [[comment("physical size = 2^(flags.size + 1)")]];

66
patterns/gltf.hexpat Normal file
View File

@@ -0,0 +1,66 @@
/**
* @file <gltf.pat> 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
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import std.mem;
import std.io;
/**
* @brief The glTF magic section.
*/
struct gltf_magic_t {
char magic[4]; /**< 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. */
};
/**
* @brief Enumeration of well defined glTF chunks.
*/
enum gltf_chunk_type_t : u32 {
JSON = 1313821514 /* "JSON" */, /**< JSON chunk. */
BIN = 5130562 /* "BIN\0" */, /**< Binary data chunk. Could be an image or model data. */
};
/**
* @brief A glTF chunk.
*/
struct gltf_chunk_t {
u32 length; /**< Length of this chunk. */
gltf_chunk_type_t type [[format("gltf_format")]]; /**< Type of the chunk. JSON or BIN expected. */
u8 string[length]; /**< The chunk data. */
};
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);

View File

@@ -1,9 +1,12 @@
#pragma author WerWolv
#pragma description GZip compressed data format
#pragma MIME application/gzip
#include <type/time.pat>
#include <type/size.pat>
#include <std/core.pat>
#include <std/mem.pat>
import type.time;
import type.size;
import std.core;
import std.mem;
using BitfieldOrder = std::core::BitfieldOrder;

536
patterns/hinf_bitmap.hexpat Normal file
View File

@@ -0,0 +1,536 @@
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;

441
patterns/hinf_luas.hexpat Normal file
View File

@@ -0,0 +1,441 @@
#pragma author Surasia
#pragma description Halo Infinite HavokScript 5.1 "luas" file
import std.io;
import std.mem;
import std.core;
import std.string;
struct String32 {
s32 length;
if (length != 0) {
char s[length - 1];
u8 endbyte;
}
};
struct String64 {
s64 length;
if (length != 0) {
char s[length - 1];
u8 endbyte;
}
};
enum lua_endian : u8 {
little_endian = 1,
big_endian = 0,
};
enum lua_numbertype : u8 {
_float = 0,
_int32 = 1,
};
struct lua_enum {
s32 value;
String32 string;
};
struct LuaEnum {
s32 count;
lua_enum entries[count];
};
enum HksOpCode : s8 {
GETFIELD,
TEST,
CALL_I,
CALL_C,
EQ,
EQ_BK,
GETGLOBAL,
MOVE,
SELF,
RETURN,
GETTABLE_S,
GETTABLE_N,
GETTABLE,
LOADBOOL,
TFORLOOP,
SETFIELD,
SETTABLE_S,
SETTABLE_S_BK,
SETTABLE_N,
SETTABLE_N_BK,
SETTABLE,
SETTABLE_BK,
TAILCALL_I,
TAILCALL_C,
TAILCALL_M,
LOADK,
LOADNIL,
SETGLOBAL,
JMP,
CALL_M,
CALL,
INTRINSIC_INDEX,
INTRINSIC_NEWINDEX,
INTRINSIC_SELF,
INTRINSIC_LITERAL,
INTRINSIC_NEWINDEX_LITERAL,
INTRINSIC_SELF_LITERAL,
TAILCALL,
GETUPVAL,
SETUPVAL,
ADD,
ADD_BK,
SUB,
SUB_BK,
MUL,
MUL_BK,
DIV,
DIV_BK,
MOD,
MOD_BK,
POW,
POW_BK,
NEWTABLE,
UNM,
NOT,
LEN,
LT,
LT_BK,
LE,
LE_BK,
CONCAT,
TESTSET,
FORPREP,
FORLOOP,
SETLIST,
CLOSE,
CLOSURE,
VARARG,
TAILCALL_I_R1,
CALL_I_R1,
SETUPVAL_R1,
TEST_R1,
NOT_R1,
GETFIELD_R1,
SETFIELD_R1,
NEWSTRUCT,
DATA,
SETSLOTN,
SETSLOTI,
SETSLOT,
SETSLOTS,
SETSLOTMT,
CHECKTYPE,
CHECKTYPES,
GETSLOT,
GETSLOTMT,
SELFSLOT,
SELFSLOTMT,
GETFIELD_MM,
CHECKTYPE_D,
GETSLOT_D,
GETGLOBAL_MEM,
};
enum HksType : u8
{
TNIL,
TBOOLEAN,
TLIGHTUSERDATA,
TNUMBER,
TSTRING,
TTABLE,
TFUNCTION,
TUSERDATA,
TTHREAD,
TIFUNCTION,
TCFUNCTION,
TUI64,
TSTRUCT
};
bitfield REG_CONST_UNUSED {
argB : 17 & 0x1ffff;
argA : 8 & 0xff;
};
bitfield REG_NUM_NUM {
argC : 9 & 0x1ff;
argB : 8 & 0xff;
argA : 8 & 0xff;
};
bitfield REG_NUM_UNUSED {
argB : 8 & 0xff;
argA : 8 & 0xff;
argC : 9 & 0x1ff;
};
bitfield UNUSED_OFFSET_UNUSED {
argA : 8 & 0xff;
argB : 9 & 0x1ff;
argC : 8 & 0xff;
};
bitfield LuaBitfield {
HksOpCode OpCode : 7;
//Arguments : 25; // read on how to process them at https://raw.githubusercontent.com/soupstream/havok-script-tools/main/HavokScriptToolsCommon/HksOpCodes.cs
match(OpCode) {
(HksOpCode::LOADK) : REG_CONST_UNUSED arguments;
(HksOpCode::SETGLOBAL) : REG_CONST_UNUSED arguments;
(HksOpCode::NEWTABLE) : REG_NUM_NUM arguments;
(HksOpCode::CLOSURE) : REG_CONST_UNUSED arguments;
(HksOpCode::RETURN) : REG_NUM_UNUSED arguments;
(HksOpCode::NEWSTRUCT) : REG_NUM_NUM arguments;
(HksOpCode::DATA) : UNUSED_OFFSET_UNUSED arguments;
(_): arguments : 25;
}
};
struct LuaInstruction {
LuaBitfield OpCode;
};
struct LuaConstant {
HksType type;
if (type == HksType::TNIL) {
}
else if (type == HksType::TSTRING) {
String64 string;
}
else if (type == HksType::TNUMBER) {
float number;
}
else if (type == HksType::TBOOLEAN) {
bool boolean;
}
else if (type == HksType::TLIGHTUSERDATA) {
s64 userdata;
}
else {
s64 data;
}
};
struct HksLocal {
String64 string;
u32 start;
u32 end;
};
struct LuaFunction {
s32 upvaluecount;
s32 paramcount;
s8 isVarArg;
s32 slotCount;
s32 unk;
s32 instruction_count;
if ($ % 4 != 0) {
$ += (4 - ($ % 4));
}
LuaInstruction instructions[instruction_count];
s32 constantCount;
LuaConstant constants[constantCount];;
s32 HasDebugInfo;
if (HasDebugInfo != 0) {
u32 LineCount;
u32 LocalsCount;
u32 UpValueCount;
u32 LineBegin;
u32 LineEnd;
String64 path;
String64 functionName;
s32 Lines[LineCount];
HksLocal Locals[LocalsCount];
String64 UpValues[UpValueCount];
}
s32 function_count;
LuaFunction children[function_count];
};
struct LuaStructHeader {
String64 name;
s32 structID;
s32 pad;
s24 unk1;
HksType type;
s32 unk2;
};
struct LuaStructMember {
s32 pad;
LuaStructHeader header;
s32 index;
};
struct LuaStruct {
try {
u32 unk;
LuaStructHeader ExtendedStructHeader;
s64 ExtendedStructMemberCount;
LuaStructMember ExtendedStructMembers[ExtendedStructMemberCount];
u32 unk2;
} catch {
std::print("WARNING: this file does not support structs.");
}
try {
LuaStructHeader StructHeader;
s64 StructMemberCount;
LuaStructMember StructMembers[StructMemberCount];
} catch {
std::print("WARNING: this file does not support multiple structs.");
}
};
struct LuaHeader {
char luaheader[4];
u8 version;
u8 format;
lua_endian Endianness;
if (Endianness == lua_endian::big_endian) {
std::core::set_endian(std::mem::Endian::Big);
} else {
std::core::set_endian(std::mem::Endian::Little);
}
u8 intSize;
u8 size_tSize;
u8 instruction_size;
u8 number_size;
lua_numbertype numberType;
u8 flags;
u8 unknown;
LuaEnum enums;
LuaFunction LuaFunctions;
LuaStruct LuaStructures;
};
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;
};
struct _s_tagblock {
char tagblock[16];
s32 count;
};
struct _s_resource {
char resource[12];
s32 count;
};
struct _s_data {
char data[24];
};
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 _s_tagref {
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;
_s_tagref tagreference @ header.HeaderSize + datablocks[FieldBlock].Offset + FieldOffset;
};
struct InternalStruct {
s64 vtablespace;
u32 global_tag_id;
char local_tag_handle[4];
};
struct LuaReferencedTagContainer {
_s_tagref tagReference;
};
struct LuaScriptTagDefinition {
u32 luaFileName;
_s_data luaFileData;
char luaFileNameString[256];
_s_tagblock referencedTags_count;
LuaHeader lua_header;
try {
char pad[14];
LuaReferencedTagContainer referencedTags[referencedTags_count.count];
} catch {
std::print("This file does not support referenced Tags.");
}
};
// 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;
InternalStruct internalstruct @ header.HeaderSize;
LuaScriptTagDefinition lua_script @ header.HeaderSize + 16;

View File

@@ -1,6 +1,9 @@
#pragma author WerWolv
#pragma description Icon (.ico) or Cursor (.cur) files
#pragma endian little
#include <std/sys.pat>
import std.sys;
#pragma MIME image/vnd.microsoft.icon
#pragma MIME image/x-icon

View File

@@ -1,6 +1,8 @@
#pragma description ID3 tags in MP3 files
#pragma MIME audio/mpeg
#include <std/mem.pat>
import std.mem;
namespace v1 {
@@ -24,10 +26,10 @@ namespace v2 {
u8 bytes[4];
} [[sealed, static, format("v2::ssi_value"), transform("v2::ssi_value")]];
fn ssi_value(ref SyncSafeInt n) {
fn ssi_value(ref SyncSafeInt size) {
u32 result = 0;
for (u8 i = 0, i < 4, i = i + 1) {
u8 byteval = n.bytes[i] & 0x7F;
u8 byteval = size.bytes[i] & 0x7F;
u8 shift = 7 * (4 - i - 1);
result = result | (byteval << shift);
}

View File

@@ -1,3 +1,5 @@
#pragma description Intel hexadecimal object file format definition
/* If you have no delimiters between data records then remove
* the null_bytes field in the data_packet struct.
* Set the array at the bottom to the highest index + 1 in the Pattern Data view
@@ -6,6 +8,8 @@
*/
#pragma endian big
import std.mem;
enum FileType: u16 {
Data = 0x3030,
EOF = 0x3031,
@@ -45,7 +49,9 @@ struct data_packet {
}
u16 checksum [[color("0045F0DF")]];
u16 null_bytes [[color("005E565A")]];
u8 line_ending_1 [[color("005E565A")]];
if (line_ending_1 == '\r')
u8 line_ending_2 [[color("005E565A")]];
};
data_packet data[1418] @ 0x00;
data_packet data[while(!std::mem::eof())] @ 0x00;

View File

@@ -1,7 +1,10 @@
#pragma author WerWolv
#pragma description Ethernet II Frames (IP Packets)
#pragma endian big
#include <std/sys.pat>
#include <std/io.pat>
import std.sys;
import std.io;
struct MAC {
u8 octets[6];
@@ -129,7 +132,7 @@ namespace ip {
if (flags.data_offset > 5)
u8 options[(flags.data_offset - 5) * sizeof(u32)];
u8 data[parent.parent.header.total_length - 40];
u8 data[parent.parent.header.total_length - parent.parent.header.ihl * 4 - flags.data_offset * 4];
};
}

28
patterns/ips.hexpat Normal file
View File

@@ -0,0 +1,28 @@
#pragma author gmestanley
#pragma description IPS (International Patching System) files
#pragma endian big
import std.mem;
import std.string;
struct Hunk {
u24 offset;
u16 length;
if (!length) {
u16 runCount;
u8 payload;
}
else {
u8 payload[length];
}
};
struct IPS {
char signature[5];
Hunk hunks[while($ < std::mem::size() - (3 + 3 * (std::mem::read_string(std::mem::size()-3, 3) != "EOF")))];
char eof[3];
u24 truncatedSize[3+(std::mem::read_string(std::mem::size()-3, 3) != "EOF")>3];
};
IPS ips @ 0x00;

View File

@@ -1,6 +1,8 @@
#pragma description ISO 9660 file system
#pragma endian little
#include <std/io.pat>
import std.io;
enum VolumeDescriptorTypes : u8 {
BootRecord,

View File

@@ -1,12 +1,15 @@
#pragma author WerWolv
#pragma description Java Class files
#pragma endian big
#pragma pattern_limit 100000000
#pragma MIME application/x-java-applet
#include <std/string.pat>
#include <std/math.pat>
#include <std/core.pat>
#include <std/io.pat>
#include <std/sys.pat>
import std.string;
import std.math;
import std.core;
import std.io;
import std.sys;
using BitfieldOrder = std::core::BitfieldOrder;

View File

@@ -1,122 +1,156 @@
#include <std/mem.pat>
#pragma endian big
#pragma MIME image/jpeg
enum Marker : u8 {
TEM = 0x01,
SOF0 = 0xC0,
SOF1 = 0xC1,
SOF2 = 0xC2,
SOF3 = 0xC3,
DHT = 0xC4,
SOF5 = 0xC5,
SOF6 = 0xC6,
SOF7 = 0xC7,
SOI = 0xD8,
EOI = 0xD9,
SOS = 0xDA,
DQT = 0xDB,
DNL = 0xDC,
DRI = 0xDD,
DHP = 0xDE,
APP0 = 0xE0,
APP1 = 0xE1,
APP2 = 0xE2,
APP3 = 0xE3,
APP4 = 0xE4,
APP5 = 0xE5,
APP6 = 0xE6,
APP7 = 0xE7,
APP8 = 0xE8,
APP9 = 0xE9,
APP10 = 0xEA,
APP11 = 0xEB,
APP12 = 0xEC,
APP13 = 0xED,
APP14 = 0xEE,
APP15 = 0xEF,
COM = 0xFE
};
enum DensityUnit : u8 {
NoUnit = 0x00,
PixelsPerInch = 0x01,
PixelsPerCm = 0x02
};
struct Pixel {
u8 r, g, b;
} [[sealed, transform("transform_pixel")]];
fn transform_pixel(Pixel pixel) {
return (0xFF << 24) | (pixel.b << 16) | (pixel.g << 8) | (pixel.r << 0);
};
struct APP0 {
char magic[5];
u8 versionMajor, versionMinor;
DensityUnit densityUnit;
u16 densityX, densityY;
u8 thumbnailX, thumbnailY;
Pixel thumbnail[thumbnailX * thumbnailY] [[sealed]];
};
enum ComponentId : u8 {
Y = 1,
CB = 2,
CR = 3,
I = 4,
Q = 5
};
struct SOF0Component {
ComponentId componentId;
u8 samplingFactors;
u8 quantizationTableId;
};
struct SOF0 {
u8 bitsPerSample;
u16 imageHeight, imageWidth;
u8 numComponents;
SOF0Component components[numComponents];
};
struct SOSComponent {
ComponentId componentId;
u8 huffmanTable;
};
struct SOS {
u8 numComponents;
SOSComponent components[numComponents];
u8 startSpectralSelection;
u8 endSpectral;
u8 apprBitPos;
u8 image_data[while(!std::mem::eof())] [[sealed]];
};
struct Segment {
u8 magic;
Marker marker;
if (marker == Marker::SOI || marker == Marker::EOI) {
} else {
u16 length;
if (marker == Marker::APP0) {
APP0 data;
} else if (marker == Marker::SOF0) {
SOF0 data;
} else if (marker == Marker::SOS) {
SOS data;
} else {
u8 data[length - sizeof(length)] [[sealed]];
}
}
};
#pragma author WerWolv
#pragma description JPEG Image Format
import std.io;
import std.mem;
import type.magic;
#pragma endian big
#pragma MIME image/jpeg
enum Marker : u8 {
TEM = 0x01,
SOF0 = 0xC0,
SOF1 = 0xC1,
SOF2 = 0xC2,
SOF3 = 0xC3,
DHT = 0xC4,
SOF5 = 0xC5,
SOF6 = 0xC6,
SOF7 = 0xC7,
SOI = 0xD8,
EOI = 0xD9,
SOS = 0xDA,
DQT = 0xDB,
DNL = 0xDC,
DRI = 0xDD,
DHP = 0xDE,
APP0 = 0xE0,
APP1 = 0xE1,
APP2 = 0xE2,
APP3 = 0xE3,
APP4 = 0xE4,
APP5 = 0xE5,
APP6 = 0xE6,
APP7 = 0xE7,
APP8 = 0xE8,
APP9 = 0xE9,
APP10 = 0xEA,
APP11 = 0xEB,
APP12 = 0xEC,
APP13 = 0xED,
APP14 = 0xEE,
APP15 = 0xEF,
COM = 0xFE
};
enum DensityUnit : u8 {
NoUnit = 0x00,
PixelsPerInch = 0x01,
PixelsPerCm = 0x02
};
enum ColorTransform : u8 {
Unknown = 0x00,
YCbCr = 0x01,
YCCK = 0x02
};
struct Pixel {
u8 r, g, b;
} [[sealed, transform("transform_pixel")]];
fn transform_pixel(Pixel pixel) {
return (0xFF << 24) | (pixel.b << 16) | (pixel.g << 8) | (pixel.r << 0);
};
struct APP0 {
type::Magic<"JFIF\x00"> magic;
u8 versionMajor, versionMinor;
DensityUnit densityUnit;
u16 densityX, densityY;
u8 thumbnailX, thumbnailY;
Pixel thumbnail[thumbnailX * thumbnailY] [[sealed]];
};
struct APP14 {
type::Magic<"Adobe"> magic;
u16 version;
u16 flags0;
u16 flags1;
ColorTransform transform;
};
enum ComponentId : u8 {
Y = 1,
CB = 2,
CR = 3,
I = 4,
Q = 5,
B = 66,
G = 71,
R = 82
};
struct SOF0Component {
ComponentId componentId;
u8 samplingFactors;
u8 quantizationTableId;
} [[format_read("sof0_component_read")]];
fn sof0_component_read(SOF0Component c) {
return std::format("({}, {}, {})", c.componentId, c.samplingFactors, c.quantizationTableId);
};
struct SOF0 {
u8 bitsPerSample;
u16 imageHeight, imageWidth;
u8 numComponents;
SOF0Component components[numComponents];
};
struct SOSComponent {
ComponentId componentId;
u8 huffmanTable;
};
struct SOS {
u8 numComponents;
SOSComponent components[numComponents];
u8 startSpectralSelection;
u8 endSpectral;
u8 apprBitPos;
u8 image_data[std::mem::size() - $ - 2] [[sealed]];
};
struct Segment {
type::Magic<"\xff"> magic;
Marker marker;
if (marker == Marker::SOI || marker == Marker::EOI) {
} else {
u16 length;
if (marker == Marker::APP0) {
APP0 data;
} else if (marker == Marker::APP14) {
APP14 data;
} else if (marker == Marker::COM) {
char data[length - sizeof(length)];
} else if (marker == Marker::SOF0) {
SOF0 data;
} else if (marker == Marker::SOS) {
SOS data;
} else {
u8 data[length - sizeof(length)] [[sealed]];
}
}
} [[format_read("segment_read")]];
fn segment_read(Segment s) {
return std::format("{}", s.marker);
};
Segment segments[while(!std::mem::eof())] @ 0x00 [[hex::visualize("image", this)]];

View File

@@ -1,8 +1,11 @@
#pragma author WerWolv
#pragma description Windows Shell Link file format
#pragma MIME application/x-ms-shortcut
#include <std/core.pat>
#include <type/guid.pat>
#include <type/size.pat>
import std.core;
import type.guid;
import type.size;
using BitfieldOrder = std::core::BitfieldOrder;

View File

@@ -1,5 +1,7 @@
#include <std/io.pat>
#include <std/mem.pat>
#pragma description Lua 5.4 bytecode
import std.io;
import std.mem;
namespace impl {
@@ -30,8 +32,8 @@ namespace impl {
return std::format("\"{}\"", string.data);
};
fn format_Constant(auto const) {
return const.data;
fn format_Constant(auto constant) {
return constant.data;
};
fn format_Version(auto ver) {
@@ -132,4 +134,4 @@ struct LuaFile {
LuaFunction func;
};
LuaFile file @ 0;
LuaFile file @ 0;

View File

@@ -1,6 +1,9 @@
#pragma author WerWolv
#pragma description Mach-O executable
#pragma MIME application/x-mach-binary
#include <type/size.pat>
import type.size;
enum Magic : u32 {
_32BitMagic = 0xFEEDFACE,

View File

@@ -1,5 +1,7 @@
#include <std/sys.pat>
#include <std/mem.pat>
#pragma description Mechanized Assault and Exploration v1.04 (strategy game) save file format
import std.sys;
import std.mem;
#pragma array_limit 12544
#pragma pattern_limit 2000000

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