mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-04-02 05:27:40 -05:00
Compare commits
294 Commits
ImHex-v1.3
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5359e385ea | ||
|
|
75bcb487ee | ||
|
|
fb214600ec | ||
|
|
d95390ea42 | ||
|
|
284ca8d325 | ||
|
|
6630180276 | ||
|
|
ff68d1e23d | ||
|
|
70dd55aa6b | ||
|
|
76f850c543 | ||
|
|
74c06b74f7 | ||
|
|
f13d9d3894 | ||
|
|
c4c75a9ab2 | ||
|
|
7278a22eb2 | ||
|
|
91fd36097c | ||
|
|
afffd7eced | ||
|
|
7fd79ec9fd | ||
|
|
6b9f39cc21 | ||
|
|
9207282bcf | ||
|
|
5ed64f9f08 | ||
|
|
a75a7a5b98 | ||
|
|
60c8d93449 | ||
|
|
d3b05fd753 | ||
|
|
3b2f098b09 | ||
|
|
f4f004f0eb | ||
|
|
5c6cb9dccc | ||
|
|
44717e9b19 | ||
|
|
bc35349e0f | ||
|
|
fed5db4109 | ||
|
|
1d41392215 | ||
|
|
0b75336638 | ||
|
|
e3edbd5a6f | ||
|
|
b10a37af67 | ||
|
|
103d434cc5 | ||
|
|
7716b9d6e7 | ||
|
|
ad1e300674 | ||
|
|
e918ce52b9 | ||
|
|
db4d62aa20 | ||
|
|
d96bfbb942 | ||
|
|
2070c95f58 | ||
|
|
877895741d | ||
|
|
6b279b8375 | ||
|
|
a692b22ecc | ||
|
|
2ae0499293 | ||
|
|
bd06987e8e | ||
|
|
74e08623f1 | ||
|
|
a860c396fa | ||
|
|
da934e2045 | ||
|
|
394ef80611 | ||
|
|
2ce182b1b3 | ||
|
|
6cadad3d1f | ||
|
|
7ad9cd4f41 | ||
|
|
bcaeef31d7 | ||
|
|
ee8d2f50b7 | ||
|
|
5b8dde19a9 | ||
|
|
0b0eff0cb6 | ||
|
|
3185503be1 | ||
|
|
3a64207e58 | ||
|
|
c94d42d5c0 | ||
|
|
45c4c1d35b | ||
|
|
f93be1ea06 | ||
|
|
5ed9c0fd4d | ||
|
|
11d373319f | ||
|
|
e7d366571d | ||
|
|
b6df1742b6 | ||
|
|
0b9e83ff8a | ||
|
|
c0fc748de6 | ||
|
|
89307ba8a5 | ||
|
|
a12b5ba406 | ||
|
|
537ce67895 | ||
|
|
1771c1f077 | ||
|
|
cef20e24a7 | ||
|
|
8e7cfd9442 | ||
|
|
d0ba754dc2 | ||
|
|
9f92c38ecf | ||
|
|
0844e07056 | ||
|
|
66fc006b08 | ||
|
|
5bc66df14f | ||
|
|
7310a10214 | ||
|
|
34ee3107e2 | ||
|
|
c4378ffb14 | ||
|
|
5ad7f0c1e7 | ||
|
|
df97fc7257 | ||
|
|
3ad263783d | ||
|
|
5ccd431320 | ||
|
|
fb8e5e3f77 | ||
|
|
375145e759 | ||
|
|
71eeed981d | ||
|
|
e779b88a58 | ||
|
|
aef3d3451f | ||
|
|
c5fa53dcea | ||
|
|
9a6cbdfe28 | ||
|
|
083042632d | ||
|
|
4d172cebc3 | ||
|
|
53ff0a5d62 | ||
|
|
b3b730c6e9 | ||
|
|
8db011b6e5 | ||
|
|
b936c04d21 | ||
|
|
bf56d4ff49 | ||
|
|
fdc4a87389 | ||
|
|
1f6c701348 | ||
|
|
4092dad428 | ||
|
|
559faebec3 | ||
|
|
cde46e1f15 | ||
|
|
17c200a92e | ||
|
|
384d4c7794 | ||
|
|
37a7e59c06 | ||
|
|
e8cea09477 | ||
|
|
883433b260 | ||
|
|
2db9993cb1 | ||
|
|
01ce565c9e | ||
|
|
b7b949ea27 | ||
|
|
e026ff187e | ||
|
|
63504f59a1 | ||
|
|
6113df643d | ||
|
|
3f42dddd19 | ||
|
|
2cc8868727 | ||
|
|
7f02510762 | ||
|
|
13c4168af0 | ||
|
|
1e69cd7fb2 | ||
|
|
16a87df2ac | ||
|
|
b7598405b5 | ||
|
|
d14f8de459 | ||
|
|
4c96bfbeb3 | ||
|
|
500a3fe26e | ||
|
|
5ffc583640 | ||
|
|
b9f5f1668b | ||
|
|
4c22f28a67 | ||
|
|
6f9b05b853 | ||
|
|
c533017d0b | ||
|
|
221fa70a67 | ||
|
|
661e5b7081 | ||
|
|
7d0bbd1e24 | ||
|
|
55aca93a18 | ||
|
|
255116a587 | ||
|
|
79e25fdb73 | ||
|
|
c8d9a8deb7 | ||
|
|
1d680fbf5e | ||
|
|
bc5a55affe | ||
|
|
85f5541350 | ||
|
|
61d3e110fb | ||
|
|
af957389c2 | ||
|
|
e85645897e | ||
|
|
abc78d1644 | ||
|
|
46e41db0a8 | ||
|
|
c67dc84911 | ||
|
|
323898d083 | ||
|
|
abbd25e7f6 | ||
|
|
c8ebb3eb8a | ||
|
|
bf94cb7243 | ||
|
|
6697fc23a4 | ||
|
|
8a6bb6612b | ||
|
|
1d66949375 | ||
|
|
7c65d51986 | ||
|
|
d961271c5d | ||
|
|
26d48df7dd | ||
|
|
8f1f4911a0 | ||
|
|
1d7cc537ed | ||
|
|
62ceaae09b | ||
|
|
4a8a6cba1b | ||
|
|
c3eb9e4126 | ||
|
|
a263347414 | ||
|
|
204599a70b | ||
|
|
bf6ee6d02f | ||
|
|
0125ec2c57 | ||
|
|
c5aaac25dd | ||
|
|
196011ead9 | ||
|
|
5b15136ea4 | ||
|
|
59c954ae28 | ||
|
|
8a5cb1061b | ||
|
|
120bc84548 | ||
|
|
0e17355db0 | ||
|
|
6aee524d1a | ||
|
|
b42c571d4d | ||
|
|
71e1ad8df7 | ||
|
|
5c7d77b50f | ||
|
|
a746ecb164 | ||
|
|
569e5c4c1a | ||
|
|
0316f2b667 | ||
|
|
196695e37b | ||
|
|
bced518508 | ||
|
|
2f795fc23c | ||
|
|
5ff783d571 | ||
|
|
4299243e95 | ||
|
|
23b3c2b5d0 | ||
|
|
da1c2687e8 | ||
|
|
18f968df5b | ||
|
|
f797c711ca | ||
|
|
5380877da4 | ||
|
|
bb46276bde | ||
|
|
4242869ac1 | ||
|
|
8bdcd814a9 | ||
|
|
d7811ff5e9 | ||
|
|
4d0b3e21bc | ||
|
|
acd6903b21 | ||
|
|
8d2a39f7d4 | ||
|
|
65ef3a7783 | ||
|
|
21a0b99eac | ||
|
|
a33b68921d | ||
|
|
a0bb71be58 | ||
|
|
c7fc39ac19 | ||
|
|
b540ead0ae | ||
|
|
26878548f0 | ||
|
|
e4c9d86755 | ||
|
|
2a3de1b705 | ||
|
|
e02280f9ee | ||
|
|
bbba68cef7 | ||
|
|
28b281b403 | ||
|
|
c807959d75 | ||
|
|
3416d30f2b | ||
|
|
10bf1c76cf | ||
|
|
5b7c212029 | ||
|
|
1c2e948940 | ||
|
|
7ea34e410a | ||
|
|
56950e44d8 | ||
|
|
ed42452fc1 | ||
|
|
a68ecb8888 | ||
|
|
8d4cf59497 | ||
|
|
3c2fed22e4 | ||
|
|
ff550bd105 | ||
|
|
0ad6e3abde | ||
|
|
891968db53 | ||
|
|
5799d1d7ea | ||
|
|
9c6bfeb50f | ||
|
|
9f7cdded6a | ||
|
|
03298b0b0c | ||
|
|
5f2738872e | ||
|
|
63585e6de7 | ||
|
|
cb6caafa64 | ||
|
|
236fadee47 | ||
|
|
0549e62a14 | ||
|
|
b4bf2b946f | ||
|
|
5e82bfadac | ||
|
|
a5c9f3b18a | ||
|
|
38262e6bb9 | ||
|
|
0a37b60d70 | ||
|
|
345e264ff8 | ||
|
|
ba2c396534 | ||
|
|
439f04e19b | ||
|
|
eaeea8d093 | ||
|
|
9af8d7e693 | ||
|
|
dac2e0f786 | ||
|
|
f70b7066b9 | ||
|
|
3f44a743e8 | ||
|
|
834e5261b3 | ||
|
|
0e2966f10d | ||
|
|
b2bc248447 | ||
|
|
e6589ecba1 | ||
|
|
f75ba4b6ee | ||
|
|
cf18580960 | ||
|
|
e7d1973957 | ||
|
|
35cc68544b | ||
|
|
41d8967deb | ||
|
|
658ec20b37 | ||
|
|
fb5fcbafc1 | ||
|
|
6f7988e96e | ||
|
|
0a631f0c1f | ||
|
|
5942897c29 | ||
|
|
a7e6209791 | ||
|
|
294f69fa36 | ||
|
|
1ea12cd4bd | ||
|
|
8129504dcb | ||
|
|
22e30cfef9 | ||
|
|
9b819cf392 | ||
|
|
3277821153 | ||
|
|
f23dbbb565 | ||
|
|
52f7d9e77a | ||
|
|
99df77baf2 | ||
|
|
d7b0819ff0 | ||
|
|
70f491d2fa | ||
|
|
08680a6544 | ||
|
|
23bc36c4bd | ||
|
|
8ae778944d | ||
|
|
7e6a5d3bfa | ||
|
|
27e55d2e6d | ||
|
|
e0a602c10a | ||
|
|
8748646016 | ||
|
|
4a52ee4cf8 | ||
|
|
e517e3534b | ||
|
|
edd0aa9a2f | ||
|
|
a992d1ba92 | ||
|
|
6fbdcac556 | ||
|
|
47fce1628f | ||
|
|
9b152ae560 | ||
|
|
6b136b7fc6 | ||
|
|
93494a19a4 | ||
|
|
4fd710e23e | ||
|
|
44842dc44b | ||
|
|
056035c540 | ||
|
|
5ad8e15afc | ||
|
|
39c4d11404 | ||
|
|
815bd5f7f3 | ||
|
|
917b05a9f2 | ||
|
|
46a2cef993 | ||
|
|
bca25b1a78 |
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1,2 +1,4 @@
|
|||||||
*.pat linguist-language=Rust
|
*.pat linguist-language=Rust
|
||||||
*.hexpat linguist-language=Rust
|
*.hexpat linguist-language=Rust
|
||||||
|
|
||||||
|
tests/patterns/test_data/** binary
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
## Checklist
|
## Checklist
|
||||||
- [ ] A pattern for this format doesn't exist yet (or this PR improves the existing one)
|
- [ ] A pattern for this format doesn't exist yet (or this PR improves the existing one)
|
||||||
- [ ] The new pattern has been added to the relevant table in the Readme
|
- [ ] The new pattern has been added to the relevant table in the Readme
|
||||||
|
- [ ] The new pattern has a description pragma (`#pragma description My pattern Description here`)
|
||||||
- [ ] The pattern was associated with all relevant MIME types (using `#pragma MIME mime-type` in the source code)
|
- [ ] The pattern was associated with all relevant MIME types (using `#pragma MIME mime-type` in the source code)
|
||||||
- Make sure to never use `application/octet-stream` here as that means "Unidentifiable binary data"
|
- Make sure to never use `application/octet-stream` here as that means "Unidentifiable binary data"
|
||||||
- [ ] A test file for this pattern has been added to [/tests/patterns/test_data](/tests/patterns/test_data)
|
- [ ] A test file for this pattern has been added to [/tests/patterns/test_data](/tests/patterns/test_data)
|
||||||
|
|||||||
6
.github/workflows/dispatch.yml
vendored
6
.github/workflows/dispatch.yml
vendored
@@ -17,7 +17,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
tests:
|
tests:
|
||||||
name: 🎯 Dispatch changes
|
name: 🎯 Dispatch changes
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
env:
|
env:
|
||||||
DISPATCH_TOKEN: ${{ secrets.DISPATCH_TOKEN }}
|
DISPATCH_TOKEN: ${{ secrets.DISPATCH_TOKEN }}
|
||||||
permissions:
|
permissions:
|
||||||
@@ -27,13 +27,13 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: 🧰 Checkout
|
- name: 🧰 Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: 📄 Check changed include files
|
- name: 📄 Check changed include files
|
||||||
id: changed-includes
|
id: changed-includes
|
||||||
uses: tj-actions/changed-files@v35
|
uses: tj-actions/changed-files@v45
|
||||||
with:
|
with:
|
||||||
files: includes/**/*.pat
|
files: includes/**/*.pat
|
||||||
|
|
||||||
|
|||||||
46
.github/workflows/tests.yml
vendored
46
.github/workflows/tests.yml
vendored
@@ -7,11 +7,12 @@ on:
|
|||||||
branches: [ '*' ]
|
branches: [ '*' ]
|
||||||
repository_dispatch:
|
repository_dispatch:
|
||||||
types: [run_tests]
|
types: [run_tests]
|
||||||
|
workflow_call:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
tests:
|
tests:
|
||||||
name: 🧪 Unit Tests
|
name: 🧪 Unit Tests
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
permissions:
|
permissions:
|
||||||
actions: read
|
actions: read
|
||||||
contents: read
|
contents: read
|
||||||
@@ -19,8 +20,9 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: 🧰 Checkout
|
- name: 🧰 Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
|
repository: ${{ github.repository_owner }}/ImHex-Patterns
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: ⬇️ Install dependencies
|
- name: ⬇️ Install dependencies
|
||||||
@@ -28,12 +30,13 @@ jobs:
|
|||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install -y \
|
sudo apt install -y \
|
||||||
build-essential \
|
build-essential \
|
||||||
gcc-12 \
|
ccache \
|
||||||
g++-12 \
|
gcc-14 \
|
||||||
|
g++-14 \
|
||||||
lld \
|
lld \
|
||||||
${PKGCONF:-} \
|
${PKGCONF:-} \
|
||||||
cmake \
|
cmake \
|
||||||
make \
|
ninja-build \
|
||||||
python3 \
|
python3 \
|
||||||
python3-pip \
|
python3-pip \
|
||||||
libmagic-dev \
|
libmagic-dev \
|
||||||
@@ -41,36 +44,33 @@ jobs:
|
|||||||
|
|
||||||
sudo pip install jsonschema
|
sudo pip install jsonschema
|
||||||
|
|
||||||
|
- name: 📜 Setup ccache
|
||||||
|
uses: hendrikmuhs/ccache-action@v1
|
||||||
|
with:
|
||||||
|
key: ${{ runner.os }}-ccache-${{ github.run_id }}
|
||||||
|
restore-keys: ${{ runner.os }}-ccache
|
||||||
|
max-size: 1G
|
||||||
|
|
||||||
- name: 🛠️ Build
|
- name: 🛠️ Build
|
||||||
run: |
|
run: |
|
||||||
cd tests
|
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
cd build
|
cd build
|
||||||
CC=gcc-12 CXX=g++-12 cmake \
|
CC=gcc-14 CXX=g++-14 cmake \
|
||||||
|
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||||
|
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||||
-DCMAKE_C_FLAGS="-fuse-ld=lld --coverage" \
|
-DCMAKE_C_FLAGS="-fuse-ld=lld --coverage" \
|
||||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld --coverage" \
|
-DCMAKE_CXX_FLAGS="-fuse-ld=lld --coverage" \
|
||||||
|
-DIMHEX_PATTERNS_ENABLE_UNIT_TESTS=ON \
|
||||||
-DLIBPL_ENABLE_TESTS=OFF \
|
-DLIBPL_ENABLE_TESTS=OFF \
|
||||||
-DLIBPL_ENABLE_CLI=OFF \
|
-DLIBPL_ENABLE_CLI=OFF \
|
||||||
|
-G Ninja \
|
||||||
..
|
..
|
||||||
make -j4
|
ninja unit_tests
|
||||||
|
|
||||||
- name: 🧪 Perform Unit Tests
|
- name: 🧪 Perform Unit Tests
|
||||||
run: |
|
run: |
|
||||||
cd tests/build
|
cd build
|
||||||
ctest --output-on-failure
|
ctest --output-on-failure -j 4
|
||||||
|
|
||||||
#- name: ⚗️ Generate Coverage Report
|
|
||||||
# run: |
|
|
||||||
# cd tests/build
|
|
||||||
# lcov -d ./_deps/pattern_language-build/lib --gcov-tool /usr/bin/gcov-12 -c -o coverage.info
|
|
||||||
|
|
||||||
#- name: ⬆️ Upload Coverage Report
|
|
||||||
# uses: coverallsapp/github-action@master
|
|
||||||
# env:
|
|
||||||
# NODE_OPTIONS: --max-old-space-size=8000
|
|
||||||
# with:
|
|
||||||
# github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
# path-to-lcov: tests/build/coverage.info
|
|
||||||
|
|
||||||
- name: 📎 Validate JSON Files
|
- name: 📎 Validate JSON Files
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
10
.gitignore
vendored
10
.gitignore
vendored
@@ -1,5 +1,13 @@
|
|||||||
|
|
||||||
tests/cmake-build-debug/
|
tests/cmake*/
|
||||||
|
tests/build*/
|
||||||
|
build/
|
||||||
|
cmake-build-*/
|
||||||
|
|
||||||
|
.vscode/
|
||||||
|
.devcontainer/
|
||||||
|
.cache/
|
||||||
.idea/
|
.idea/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
compile_commands.json
|
||||||
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -2,3 +2,9 @@
|
|||||||
path = yara/official_rules
|
path = yara/official_rules
|
||||||
url = https://github.com/Yara-Rules/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
|
||||||
|
|||||||
30
CMakeLists.txt
Normal file
30
CMakeLists.txt
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
project(ImHex-Patterns)
|
||||||
|
|
||||||
|
option(IMHEX_PATTERNS_ENABLE_UNIT_TESTS "Enable building unit tests for ImHex-Patterns" OFF)
|
||||||
|
|
||||||
|
# if enabled, add a unit_test custom target for all the unit tests to be registered against
|
||||||
|
if(IMHEX_PATTERNS_ENABLE_UNIT_TESTS)
|
||||||
|
if(NOT TARGET unit_tests)
|
||||||
|
enable_testing()
|
||||||
|
add_custom_target(unit_tests)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# If this has been manually cloned into another project, libpl may already have been set up
|
||||||
|
if(NOT TARGET libpl)
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
FetchContent_Declare(
|
||||||
|
pattern_language
|
||||||
|
GIT_REPOSITORY https://github.com/WerWolv/PatternLanguage
|
||||||
|
GIT_TAG master
|
||||||
|
)
|
||||||
|
|
||||||
|
FetchContent_MakeAvailable(pattern_language)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(IMHEX_PATTERNS_ENABLE_UNIT_TESTS)
|
||||||
|
add_subdirectory(tests)
|
||||||
|
endif()
|
||||||
140
README.md
140
README.md
@@ -1,6 +1,7 @@
|
|||||||
# ImHex Database
|
# ImHex Database
|
||||||
|
|
||||||
This repository serves as a database for files to use with the [ImHex Hex Editor](https://github.com/WerWolv/ImHex). It currently contains
|
This repository serves as a database for files to use with the [ImHex Hex Editor](https://github.com/WerWolv/ImHex). It currently contains
|
||||||
|
|
||||||
- [Patterns](/patterns) - Binary Format definitions for the Pattern Language
|
- [Patterns](/patterns) - Binary Format definitions for the Pattern Language
|
||||||
- [Pattern Libraries](/includes) - Libraries that make using the Pattern Language easier
|
- [Pattern Libraries](/includes) - Libraries that make using the Pattern Language easier
|
||||||
- [Magic Files](/magic) - Custom magic file definitions for the use with libmagic
|
- [Magic Files](/magic) - Custom magic file definitions for the use with libmagic
|
||||||
@@ -24,89 +25,189 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
|
|||||||
|------|------|------|-------------|
|
|------|------|------|-------------|
|
||||||
| 3DS | | [`patterns/3ds.hexpat`](patterns/3ds.hexpat) | Autodesk 3DS Max Model file |
|
| 3DS | | [`patterns/3ds.hexpat`](patterns/3ds.hexpat) | Autodesk 3DS Max Model file |
|
||||||
| 7Z | | [`patterns/7z.hexpat`](patterns/7z.hexpat) | 7z File Format |
|
| 7Z | | [`patterns/7z.hexpat`](patterns/7z.hexpat) | 7z File Format |
|
||||||
|
| ADTFDAT | | [`patterns/adtfdat.hexpat`](patterns/adtfdat.hexpat) | [ADTFDAT files](https://digitalwerk.gitlab.io/solutions/adtf_content/adtf_base/adtf_file_library) |
|
||||||
|
| ADTS | `audio/x-hx-aac-adts` | [`patterns/adts.hexpat`](patterns/adts.hexpat) | ADTS/AAC audio files |
|
||||||
| AFE2 | | [`patterns/afe2.hexpat`](patterns/afe2.hexpat) | Nintendo Switch Atmosphère CFW Fatal Error log |
|
| AFE2 | | [`patterns/afe2.hexpat`](patterns/afe2.hexpat) | Nintendo Switch Atmosphère CFW Fatal Error log |
|
||||||
|
| ANI | `application/x-navi-animation` | [`patterns/ani.hexpat`](patterns/ani.hexpat) | Windows Animated Cursor file |
|
||||||
|
| AppleSingle | `application/applefile` | [`patterns/apple_single_double.hexpat`](patterns/apple_single_double.hexpat) | AppleSingle Dual Fork file |
|
||||||
|
| AppleDouble | `multipart/appledouble` | [`patterns/apple_single_double.hexpat`](patterns/apple_single_double.hexpat) | AppleDouble Resource Fork/Finder Metadata file |
|
||||||
| AR | `application/x-archive` | [`patterns/ar.hexpat`](patterns/ar.hexpat) | Static library archive files |
|
| AR | `application/x-archive` | [`patterns/ar.hexpat`](patterns/ar.hexpat) | Static library archive files |
|
||||||
|
| ARC | | [`patterns/arc.hexpat`](patterns/arc.hexpat) | Minecraft Legacy Console Edition ARC files |
|
||||||
|
| ARIA2 | | [`patterns/aria2.hexpat`](patterns/aria2.hexpat) | ARIA2 Download Manager Control files |
|
||||||
| ARM VTOR | | [`patterns/arm_cm_vtor.hexpat`](patterns/arm_cm_vtor.hexpat) | ARM Cortex M Vector Table Layout |
|
| ARM VTOR | | [`patterns/arm_cm_vtor.hexpat`](patterns/arm_cm_vtor.hexpat) | ARM Cortex M Vector Table Layout |
|
||||||
|
| Bastion | | [`patterns/bastion/*`](https://gitlab.com/EvelynTSMG/imhex-bastion-pats) | Various [Bastion](https://en.wikipedia.org/wiki/Bastion_(video_game)) files |
|
||||||
|
| BeyondCompare BCSS | | [`patterns/bcss.hexpat`](patterns/bcss.hexpat) | BeyondCompare Snapshot (BCSS) file |
|
||||||
| Bencode | `application/x-bittorrent` | [`patterns/bencode.hexpat`](patterns/bencode.hexpat) | Bencode encoding, used by Torrent files |
|
| Bencode | `application/x-bittorrent` | [`patterns/bencode.hexpat`](patterns/bencode.hexpat) | Bencode encoding, used by Torrent files |
|
||||||
|
| Prusa BGCODE | | [`patterns/bgcode.hexpat`](patterns/bgcode.hexpat) | PrusaSlicer Binary G-Code files |
|
||||||
|
| BLEND | | [`patterns/blend.hexpat`](patterns/blend.hexpat) | Blender Project file |
|
||||||
| BMP | `image/bmp` | [`patterns/bmp.hexpat`](patterns/bmp.hexpat) | OS2/Windows Bitmap files |
|
| BMP | `image/bmp` | [`patterns/bmp.hexpat`](patterns/bmp.hexpat) | OS2/Windows Bitmap files |
|
||||||
| BIN | | [`patterns/selinux.hexpat`](patterns/selinux.pat) | SE Linux modules |
|
| BIN | | [`patterns/selinux.hexpat`](patterns/selinux.pat) | SE Linux modules |
|
||||||
|
| BINKA | | [`patterns/binka.hexpat`](patterns/binka.pat) | RAD Game Tools Bink Audio (BINKA) files |
|
||||||
| BSON | `application/bson` | [`patterns/bson.hexpat`](patterns/bson.hexpat) | BSON (Binary JSON) format |
|
| BSON | `application/bson` | [`patterns/bson.hexpat`](patterns/bson.hexpat) | BSON (Binary JSON) format |
|
||||||
|
| bplist | `application/x-bplist` | [`patterns/bplist.hexpat`](patterns/bplist.hexpat) | Apple's binary property list format (bplist) |
|
||||||
| BSP | | [`patterns/bsp_goldsrc.hexpat`](patterns/bsp_goldsrc.hexpat) | GoldSrc engine maps format (used in Half-Life 1) |
|
| BSP | | [`patterns/bsp_goldsrc.hexpat`](patterns/bsp_goldsrc.hexpat) | GoldSrc engine maps format (used in Half-Life 1) |
|
||||||
|
| BZIP3 | | [`patterns/bzip3.hexpat`](patterns/bzip3.hexpat) | Parses BZip3 compression (file format) by Kamila Szewczyk |
|
||||||
|
| CAB | | [`patterns/cab.hexpat`](patterns/cab.hexpat) | Microsoft Cabinet (CAB) Files |
|
||||||
| CCHVA | | [`patterns/cchva.hexpat`](patterns/cchva.hexpat) | Command and Conquer Voxel Animation |
|
| CCHVA | | [`patterns/cchva.hexpat`](patterns/cchva.hexpat) | Command and Conquer Voxel Animation |
|
||||||
| CCVXL | | [`patterns/ccvxl.hexpat`](patterns/ccvxl.hexpat) | Command and Conquer Voxel Model |
|
| CCVXL | | [`patterns/ccvxl.hexpat`](patterns/ccvxl.hexpat) | Command and Conquer Voxel Model |
|
||||||
| CCPAL | | [`patterns/ccpal.hexpat`](patterns/ccpal.hexpat) | Command and Conquer Voxel Palette |
|
| CCPAL | | [`patterns/ccpal.hexpat`](patterns/ccpal.hexpat) | Command and Conquer Voxel Palette |
|
||||||
| CDA | | [`patterns/cda.hexpat`](patterns/cda.hexpat) | Compact Disc Audio track |
|
| CDA | | [`patterns/cda.hexpat`](patterns/cda.hexpat) | Compact Disc Audio track |
|
||||||
| CHM | | [`patterns/chm.hexpat`](patterns/chm.hexpat) | Windows HtmlHelp Data (ITSF / CHM) |
|
| CHD | | [`patterns/chd.hexpat`](patterns/chd.hexpat) | MAME Compressed Hunks of Data file |
|
||||||
|
| CHM | `application/vnd.ms-htmlhelp` | [`patterns/chm.hexpat`](patterns/chm.hexpat) | Windows HtmlHelp Data (ITSF / CHM) |
|
||||||
| COFF | `application/x-coff` | [`patterns/coff.hexpat`](patterns/coff.hexpat) | Common Object File Format (COFF) executable |
|
| 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 |
|
| 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 |
|
||||||
|
| CREDHIST | | [`patterns/credhist.hexpat`](patterns/credhist.hexpat) | CREDHIST Format |
|
||||||
| DDS | `image/vnd-ms.dds` | [`patterns/dds.hexpat`](patterns/dds.hexpat) | DirectDraw Surface |
|
| DDS | `image/vnd-ms.dds` | [`patterns/dds.hexpat`](patterns/dds.hexpat) | DirectDraw Surface |
|
||||||
| DEX | | [`patterns/dex.hexpat`](patterns/dex.hexpat) | Dalvik EXecutable Format |
|
| DEX | | [`patterns/dex.hexpat`](patterns/dex.hexpat) | Dalvik EXecutable Format |
|
||||||
|
| DICOM | `application/dicom` | [`patterns/dicom.hexpat`](patterns/dicom.hexpat) | DICOM image format |
|
||||||
| DMG | | [`patterns/dmg.hexpat`](patterns/dmg.hexpat) | Apple Disk Image Trailer (DMG) |
|
| 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 |
|
| DMP | | [`patterns/dmp64.hexpat`](patterns/dmp64.hexpat) | Windows Kernel Dump(DMP64) |
|
||||||
|
| DOTNET_BinaryFormatter | | [`patterns/dotnet_binaryformatter.hexpat`](patterns/dotnet_binaryformatter.hexpat) | .NET BinaryFormatter |
|
||||||
|
| DPAPI_Blob | | [`patterns/dpapblob.hexpat`](patterns/dpapiblob.hexpat) | Data protection API Blob File Format |
|
||||||
|
| DPAPI_MasterKey | | [`patterns/dpapimasterkey.hexpat`](patterns/dpapimasterkey.hexpat) | Data protection API MasterKey |
|
||||||
|
| DS_Store | | [`patterns/dsstore.hexpat`](patterns/dsstore.hexpat) | .DS_Store file format |
|
||||||
| DTA | | [`patterns/max_v104.hexpat`](patterns/max_v104.hexpat) | Mechanized Assault and Exploration v1.04 (strategy game) save file format |
|
| DTA | | [`patterns/max_v104.hexpat`](patterns/max_v104.hexpat) | Mechanized Assault and Exploration v1.04 (strategy game) save file format |
|
||||||
|
| DTED | | [`patterns/dted.hexpat`](patterns/dted.hexpat) | Digital Terrain Elevation Data (DTED) |
|
||||||
| ELF | `application/x-executable` | [`patterns/elf.hexpat`](patterns/elf.hexpat) | ELF header in elf binaries |
|
| ELF | `application/x-executable` | [`patterns/elf.hexpat`](patterns/elf.hexpat) | ELF header in elf binaries |
|
||||||
| EVTX | | [`patterns/evtx.hexpat`](patterns/evtx.hexpat) | MS Windows Vista Event Log |
|
| EVTX | `application/x-ms-evtx` | [`patterns/evtx.hexpat`](patterns/evtx.hexpat) | MS Windows Vista Event Log |
|
||||||
|
| EXFAT | | [`patterns/fs/exfat.hexpat`](patterns/fs/exfat.hexpat) | Extensible File Allocation Table (exFAT) |
|
||||||
|
| EXT4 | | [`patterns/fs/ext4.hexpat`](patterns/fs/ext4.hexpat) | Ext4 File System |
|
||||||
|
| 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 |
|
||||||
|
| FAT32 | | [`patterns/fs/fat32.hexpat`](patterns/fs/fat32.hexpat) | FAT32 File System |
|
||||||
|
| FBX | | [`patterns/fbx.hexpat`](patterns/fbx.hexpat) | Kaydara FBX Binary |
|
||||||
| FDT | | [`patterns/fdt.hexpat`](patterns/fdt.hexpat) | Flat Linux Device Tree blob |
|
| FDT | | [`patterns/fdt.hexpat`](patterns/fdt.hexpat) | Flat Linux Device Tree blob |
|
||||||
| File System | | [`patterns/fs.hexpat`](patterns/fs.hexpat) | Drive File System |
|
| FFX | | [`patterns/ffx/*`](https://gitlab.com/EvelynTSMG/imhex-ffx-pats) | Various Final Fantasy X files |
|
||||||
|
| File System | `application/x-ima` | [`patterns/fs/pattern.hexpat`](patterns/fs/pattern.hexpat) | Drive File System |
|
||||||
| FLAC | `audio/flac` | [`patterns/flac.hexpat`](patterns/flac.hexpat) | Free Lossless Audio Codec, FLAC Audio Format |
|
| 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 |
|
| FLC/FLIC | | [`patterns/flc.hexpat`](patterns/flc.hexpat) | FLC/FLIC animation file |
|
||||||
|
| FLV | | [`patterns/flv.hexpat`](patterns/flv.hexpat) | FLv animation file |
|
||||||
|
| Flipper Zero Settings | | [`patterns/flipper_settings.hexpat`](patterns/flipper_settings.hexpat) | Flipper Zero Settings Files |
|
||||||
|
| GB | `application/x-gameboy-rom` | [`patterns/gb.hexpat`](patterns/gb.hexpat) | Game Boy ROM |
|
||||||
|
| GBA | `application/x-gameboy-advance-rom` | [`patterns/gba.hexpat`](patterns/gba.hexpat) | Game Boy Advance ROM header |
|
||||||
|
| GGUF | | [`patterns/gguf.hexpat`](patterns/gguf.hexpat) | GGML Inference Models |
|
||||||
| GIF | `image/gif` | [`patterns/gif.hexpat`](patterns/gif.hexpat) | GIF image files |
|
| GIF | `image/gif` | [`patterns/gif.hexpat`](patterns/gif.hexpat) | GIF image files |
|
||||||
|
| GLTF | `model/gltf-binary` | [`patterns/gltf.hexpat`](patterns/gltf.hexpat) | GL Transmission Format binary 3D model file |
|
||||||
| GZIP | `application/gzip` | [`patterns/gzip.hexpat`](patterns/gzip.hexpat) | GZip compressed data format |
|
| GZIP | `application/gzip` | [`patterns/gzip.hexpat`](patterns/gzip.hexpat) | GZip compressed data format |
|
||||||
|
| Halo Tag || [`patterns/hinf_tag.hexpat`](patterns/hinf_tag.hexpat) | Halo Infinite Tag Files |
|
||||||
|
| Halo Module || [`patterns/hinf_module.hexpat`](patterns/hinf_module.hexpat) | Halo Infinite Module Archive Files |
|
||||||
|
| Halo HavokScript || [`patterns/hinf_luas.hexpat`](patterns/hinf_luas.hexpat) | Halo Infinite HavokScript 5.1 Bytecode |
|
||||||
|
| HPROF || [`patterns/hprof.hexpat`](patterns/hprof.hexpat) | Java HPROF Profiler Data Format |
|
||||||
|
| HSDT || [`patterns/hsdt.hexpat`](patterns/hsdt.hexpat) | HiSilicon device-tree table images |
|
||||||
| ICO | | [`patterns/ico.hexpat`](patterns/ico.hexpat) | Icon (.ico) or Cursor (.cur) files |
|
| 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 |
|
| ID3 | `audio/mpeg` | [`patterns/id3.hexpat`](patterns/id3.hexpat) | ID3 tags in MP3 files |
|
||||||
|
| IM*H || [`patterns/imah.hexpat`](patterns/imah.hexpat) | DJI Signed Firmware (IM*H) |
|
||||||
| Intel HEX | | [`patterns/intel_hex.hexpat`](patterns/intel_hex.hexpat) | [Intel hexadecimal object file format definition]("https://en.wikipedia.org/wiki/Intel_HEX") |
|
| 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 |
|
| IPS | | [`patterns/ips.hexpat`](patterns/ips.hexpat) | IPS (International Patching System) files |
|
||||||
| ISO | | [`patterns/iso.hexpat`](patterns/iso.hexpat) | ISO 9660 file system |
|
| ISO | `application/x-iso9660-image` | [`patterns/iso.hexpat`](patterns/iso.hexpat) | ISO 9660 file system |
|
||||||
| Java Class | `application/x-java-applet` | [`patterns/java_class.hexpat`](patterns/java_class.hexpat) | Java Class files |
|
| 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 |
|
| JPEG | `image/jpeg` | [`patterns/jpeg.hexpat`](patterns/jpeg.hexpat) | JPEG Image Format |
|
||||||
|
| LOC | | [`patterns/loc.hexpat`](patterns/loc.hexpat) | Minecraft Legacy Console Edition Language file |
|
||||||
|
| Lua 5.1 | | [`patterns/lua51.hexpat`](patterns/lua51.hexpat) | Lua 5.1 bytecode |
|
||||||
|
| Lua 5.2 | | [`patterns/lua52.hexpat`](patterns/lua52.hexpat) | Lua 5.2 bytecode |
|
||||||
|
| Lua 5.3 | | [`patterns/lua53.hexpat`](patterns/lua53.hexpat) | Lua 5.3 bytecode |
|
||||||
| Lua 5.4 | | [`patterns/lua54.hexpat`](patterns/lua54.hexpat) | Lua 5.4 bytecode |
|
| Lua 5.4 | | [`patterns/lua54.hexpat`](patterns/lua54.hexpat) | Lua 5.4 bytecode |
|
||||||
|
| LCE Savefile | | [`patterns/lcesave.hexpat`](patterns/lcesave.hexpat) | Minecraft Legacy Console Edition save file |
|
||||||
|
| LZNT1 | | [`patterns/lznt1.hexpat`](patterns/lznt1.hexpat) | LZNT1 compressed data format |
|
||||||
| Mach-O | `application/x-mach-binary` | [`patterns/macho.hexpat`](patterns/macho.hexpat) | Mach-O executable |
|
| 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 |
|
| 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 |
|
| MiniDump | `application/x-dmp` | [`patterns/minidump.hexpat`](patterns/minidump.hexpat) | Windows MiniDump files |
|
||||||
|
| MO | | [`patterns/mo.hexpat`](patterns/mo.hexpat) | GNU Machine Object (MO) files containing translations for gettext |
|
||||||
| mp4 | `video/mp4` | [`patterns/mp4.hexpat`](patterns/mp4.hexpat) | MPEG-4 Part 14 digital multimedia container format |
|
| 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 |
|
| msgpack | `application/x-msgpack` | [`patterns/msgpack.hexpat`](patterns/msgpack.hexpat) | MessagePack binary serialization format |
|
||||||
|
| MSSCMP | | [`patterns/msscmp.hexpat`](patterns/msscmp.hexpat) | Miles Sound System Compressed Archive |
|
||||||
| NACP | | [`patterns/nacp.hexpat`](patterns/nacp.hexpat) | Nintendo Switch NACP files |
|
| NACP | | [`patterns/nacp.hexpat`](patterns/nacp.hexpat) | Nintendo Switch NACP files |
|
||||||
| NBT | | [`patterns/nbt.hexpat`](patterns/nbt.hexpat) | Minecraft NBT format |
|
| NBT | | [`patterns/nbt.hexpat`](patterns/nbt.hexpat) | Minecraft NBT format |
|
||||||
| NE | | [`patterns/ne.hexpat`](patterns/ne.hexpat) | NE header and Standard NE fields |
|
| NDS | `application/x-nintendo-ds-rom` | [`patterns/nds.hexpat`](patterns/nds.hexpat) | DS Cartridge Header |
|
||||||
|
| NE | `application/x-ms-ne-executable` | [`patterns/ne.hexpat`](patterns/ne.hexpat) | NE header and Standard NE fields |
|
||||||
| nes | | [`patterns/nes.hexpat`](patterns/nes.hexpat) | .nes file format |
|
| nes | | [`patterns/nes.hexpat`](patterns/nes.hexpat) | .nes file format |
|
||||||
|
| NotepadCache | | [`patterns/notepad-cache.hexpat`](patterns/notepad-cache.hexpat) | Windows Notepad Cache |
|
||||||
|
| NotepadWindowState | | [`patterns/notepadwindowstate.hexpat`](patterns/notepadwindowstate.hexpat) | Windows 11 Notepad - Window State .bin file |
|
||||||
| NRO | | [`patterns/nro.hexpat`](patterns/nro.hexpat) | Nintendo Switch NRO files |
|
| 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 |
|
| NTAG | | [`patterns/ntag.hexpat`](patterns/ntag.hexpat) | NTAG213/NTAG215/NTAG216, NFC Forum Type 2 Tag compliant IC |
|
||||||
|
| NTFS | | [`patterns/fs/ntfs.hexpat`](patterns/fs/ntfs.hexpat) | NTFS (NT File System) |
|
||||||
| OGG | `audio/ogg` | [`patterns/ogg.hexpat`](patterns/ogg.hexpat) | OGG Audio format |
|
| OGG | `audio/ogg` | [`patterns/ogg.hexpat`](patterns/ogg.hexpat) | OGG Audio format |
|
||||||
|
| ORP / ORS | | [`patterns/orp.hexpat`](patterns/orp.hexpat) | OpenRGB profile format |
|
||||||
|
| PACK | | [`patterns/roblox_pack.hexpat`](patterns/roblox_pack.hexpat) | Roblox shader archive format |
|
||||||
|
| PAK | | [`patterns/xgspak.hexpat`](patterns/xgspak.hexpat) | Exient XGS Engine Pak files |
|
||||||
| PCAP | `application/vnd.tcpdump.pcap` | [`patterns/pcap.hexpat`](patterns/pcap.hexpat) | pcap header and packets |
|
| PCAP | `application/vnd.tcpdump.pcap` | [`patterns/pcap.hexpat`](patterns/pcap.hexpat) | pcap header and packets |
|
||||||
|
| PcapNG | `application/vnd.tcpdump.pcap` | [`patterns/pcapng.hexpat`](patterns/pcapng.hexpat) | pcapng header and packets |
|
||||||
|
| PCK | | [`patterns/pck.hexpat`](patterns/pck.hexpat) | Minecraft Legacy Console Edition .pck file |
|
||||||
| PCX | `application/x-pcx` | [`patterns/pcx.hexpat`](patterns/pcx.hexpat) | PCX Image format |
|
| 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 |
|
| PEF | | [`patterns/pef.hexpat`](patterns/pef.hexpat) | Preffered Executable Format executable (for Mac OS 7.1.2 - Mac OS 10.4 / BeOS) |
|
||||||
|
| PEX | | [`patterns/pex.hexpat`](patterns/pex.hexpat) | Bethesda Papyrus executable compiled script file |
|
||||||
|
| PP | | [`patterns/selinuxpp.hexpat`](patterns/selinuxpp.pat) | SE Linux package |
|
||||||
| PFS0 | | [`patterns/pfs0.hexpat`](patterns/pfs0.hexpat) | Nintendo Switch PFS0 archive (NSP files) |
|
| PFS0 | | [`patterns/pfs0.hexpat`](patterns/pfs0.hexpat) | Nintendo Switch PFS0 archive (NSP files) |
|
||||||
|
| PF | | [`patterns/pf.hexpat`](patterns/pf.hexpat) | Microsoft uncompressed prefetch files (.pf) |
|
||||||
| PIF | `image/pif` | [`patterns/pif.hexpat`](patterns/pif.hexpat) | PIF Image Format |
|
| PIF | `image/pif` | [`patterns/pif.hexpat`](patterns/pif.hexpat) | PIF Image Format |
|
||||||
|
| PKM | | [`patterns/pkm.hexpat`](patterns/pkm.hexpat) | PKM texture format |
|
||||||
| PNG | `image/png` | [`patterns/png.hexpat`](patterns/png.hexpat) | PNG image files |
|
| PNG | `image/png` | [`patterns/png.hexpat`](patterns/png.hexpat) | PNG image files |
|
||||||
| PRODINFO | | [`patterns/prodinfo.hexpat`](patterns/prodinfo.hexpat) | Nintendo Switch PRODINFO |
|
| PRODINFO | | [`patterns/prodinfo.hexpat`](patterns/prodinfo.hexpat) | Nintendo Switch PRODINFO |
|
||||||
| Protobuf | | [`patterns/protobuf.hexpat`](patterns/protobuf.hexpat) | Google Protobuf encoding |
|
| Protobuf | | [`patterns/protobuf.hexpat`](patterns/protobuf.hexpat) | Google Protobuf encoding |
|
||||||
|
| psafe3 | | [`patterns/psafe3.hexpat`](patterns/psafe3.hexpat`) | Password Safe V3 |
|
||||||
| PyInstaller | | [`patterns/pyinstaller.hexpat`](patterns/pyinstaller.hexpat) | PyInstaller binray files |
|
| PyInstaller | | [`patterns/pyinstaller.hexpat`](patterns/pyinstaller.hexpat) | PyInstaller binray files |
|
||||||
| PYC | | [`patterns/pyc.hexpat`](patterns/pyc.hexpat) | Python bytecode files |
|
| PYC | `application/x-bytecode.python` | [`patterns/pyc.hexpat`](patterns/pyc.hexpat) | Python bytecode files |
|
||||||
| QBCL | | [`patterns/qbcl.hexpat`](patterns/qbcl.hexpat) | Qubicle voxel scene project file |
|
| QBCL | | [`patterns/qbcl.hexpat`](patterns/qbcl.hexpat) | Qubicle voxel scene project file |
|
||||||
| QOI | `image/qoi` | [`patterns/qoi.hexpat`](patterns/qoi.hexpat) | QOI image files |
|
| QOI | `image/qoi` | [`patterns/qoi.hexpat`](patterns/qoi.hexpat) | QOI image files |
|
||||||
|
| Quake 3 engine demo | | [`patterns/q3demo.hexpat`](patterns/q3demo.hexpat) | Demos/replays of most Quake 3 engine games |
|
||||||
|
| quantized-mesh | | [`patterns/quantized-mesh.hexpat`](patterns/quantized-mesh.hexpat) | Cesium quantized-mesh terrain |
|
||||||
|
| RAR | `application/x-rar` | [`patterns/rar.hexpat`](patterns/rar.hexpat) | RAR archive file format |
|
||||||
|
| RAS | `image/x-sun-raster` | [`patterns/ras.hexpat`](patterns/ras.hexpat) | RAS image files |
|
||||||
|
| RCF 1.2 | | [`patterns/rcf_v1_2.hexpat`](patterns/rcf_v1_2.hexpat) | Radcore Cement Library 1.2 file header |
|
||||||
|
| ReFS | | [`patterns/refs.hexpat`](patterns/fs/refs.hexpat) | Microsoft Resilient File System |
|
||||||
|
| RGBDS | | [`patterns/rgbds.hexpat`](patterns/rgbds.hexpat) | [RGBDS](https://rgbds.gbdev.io) object file format |
|
||||||
|
| RPM | | [`patterns/rpm.hexpat`](patterns/rpm.hexpat) | [RPM](http://ftp.rpm.org/max-rpm/s1-rpm-file-format-rpm-file-format.html) package file format |
|
||||||
|
| SDB | | [`patterns/sdb.hexpat`](patterns/sdb.hexpat) | [Shim DataBase](https://learn.microsoft.com/en-us/windows/win32/devnotes/application-compatibility-database) file format |
|
||||||
| Shell Link | `application/x-ms-shortcut` | [`patterns/lnk.hexpat`](patterns/lnk.hexpat) | Windows Shell Link file format |
|
| Shell Link | `application/x-ms-shortcut` | [`patterns/lnk.hexpat`](patterns/lnk.hexpat) | Windows Shell Link file format |
|
||||||
|
| shp | | [`patterns/shp.hexpat`](patterns/shp.hexpat) | ESRI shape file |
|
||||||
|
| SHR | | [`patterns/SHR.hexpat`](patterns/SHR.hexpat) | Apple IIgs Super Hi-Res (SHR) + PaintWorks Animation (ANI) |
|
||||||
|
| shx | | [`patterns/shx.hexpat`](patterns/shx.hexpat) | ESRI index file |
|
||||||
|
| smk | | [`patterns/smk.hexpat`](patterns/smk.hexpat) | Smacker video file |
|
||||||
|
| sup | | [`patterns/sup.hexpat`](patterns/sup.hexpat) | PGS Subtitle |
|
||||||
| SPIRV | | [`patterns/spirv.hexpat`](patterns/spirv.hexpat) | SPIR-V header and instructions |
|
| SPIRV | | [`patterns/spirv.hexpat`](patterns/spirv.hexpat) | SPIR-V header and instructions |
|
||||||
|
| STDF | | [`patterns/stdfv4.hexpat`](patterns/stdfv4.hexpat) | Standard test data format for IC testers |
|
||||||
| STL | `model/stl` | [`patterns/stl.hexpat`](patterns/stl.hexpat) | STL 3D Model format |
|
| 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 |
|
| StuffItV5 | `application/x-stuffit` | [`patterns/sit5.hexpat`](patterns/sit5.hexpat) | StuffIt V5 archive |
|
||||||
|
| SQLite3 | `application/vnd.sqlite3` | [`patterns/sqlite3.hexpat`](patterns/sqlite3.hexpat) | SQLite3 Database |
|
||||||
|
| SWF | `application/x-shockwave-flash` |[`patterns/swf.hexpat`](patterns/swf.hexpat) | Shockwave Flash file format |
|
||||||
|
| TA | | [`patterns/optee_ta.hexpat`](patterns/optee_ta.hexpat) | OPTEE Trusted Application Executable |
|
||||||
| TAR | `application/x-tar` | [`patterns/tar.hexpat`](patterns/tar.hexpat) | Tar file format |
|
| TAR | `application/x-tar` | [`patterns/tar.hexpat`](patterns/tar.hexpat) | Tar file format |
|
||||||
|
| TARC | | [`patterns/tarc.hexpat`](patterns/tarc.hexpat) | KEX Engine TARC file format |
|
||||||
|
| TES | | [`patterns/wintec_tes.hexpat`](patterns/wintec_tes.hexpat) | Wintec TES GPS log |
|
||||||
|
| Thumbcache | | [`patterns/thumbcache.hexpat`](patterns/thumbcache.hexpat) | Windows thumbcache_*.db |
|
||||||
| TIFF | `image/tiff` | [`patterns/tiff.hexpat`](patterns/tiff.hexpat) | Tag Image 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 |
|
| TGA | `image/tga` | [`patterns/tga.hexpat`](patterns/tga.hexpat) | Truevision TGA/TARGA image |
|
||||||
|
| TTF | `font/ttf`, `font/otf` | [`patterns/ttf.hexpat`](patterns/ttf.hexpat) | TrueType and OpenType font format |
|
||||||
| Ubiquiti | | [`patterns/ubiquiti.hexpat`](patterns/ubiquiti.hexpat) | Ubiquiti Firmware (update) image |
|
| Ubiquiti | | [`patterns/ubiquiti.hexpat`](patterns/ubiquiti.hexpat) | Ubiquiti Firmware (update) image |
|
||||||
|
| UPK | | [`patterns/upk-ue3.hexpat`](patterns/upk-ue3.hexpat) | Unreal Engine 3 UPK file |
|
||||||
| UEFI | | [`patterns/uefi.hexpat`](patterns/uefi.hexpat)` | UEFI structs for parsing efivars |
|
| UEFI | | [`patterns/uefi.hexpat`](patterns/uefi.hexpat)` | UEFI structs for parsing efivars |
|
||||||
|
| UEFI Boot Entry | | [`patterns/uefi_boot_entry.hexpat`](patterns/uefi_boot_entry.hexpat) | UEFI Boot Entry (Load option) |
|
||||||
|
| UEFI Variable Store | | [`patterns/uefi_fv_varstore.hexpat`](patterns/uefi_fv_varstore.hexpat) | UEFI Firmware Volume Variable Store |
|
||||||
| UF2 | | [`patterns/uf2.hexpat`](patterns/uf2.hexpat) | [USB Flashing Format](https://github.com/microsoft/uf2) |
|
| UF2 | | [`patterns/uf2.hexpat`](patterns/uf2.hexpat) | [USB Flashing Format](https://github.com/microsoft/uf2) |
|
||||||
|
| Valve VPK | | [`patterns/valve_vpk.hexpat`](valve_vpk.hexpat) | Valve Package File |
|
||||||
|
| VBMeta | | [`patterns/vbmeta.hexpat`](patterns/vbmeta.hexpat) | Android VBMeta image |
|
||||||
| VDF | | [`patterns/vdf.hexpat`](patterns/vdf.hexpat) | Binary Value Data Format (.vdf) files |
|
| VDF | | [`patterns/vdf.hexpat`](patterns/vdf.hexpat) | Binary Value Data Format (.vdf) files |
|
||||||
|
| VEADO | | [`patterns/veado.hexpat`](patterns/veado.hexpat) | veadotube mini avatar file |
|
||||||
|
| VGM | | [`patterns/vgm.hexpat`](patterns/vgm.hexpat) | VGM (Video Game Music) sound log |
|
||||||
| VHDX | | [`patterns/vhdx.hexpat`](patterns/vhdx.hexpat) | Microsoft Hyper-V Virtual Hard Disk format |
|
| VHDX | | [`patterns/vhdx.hexpat`](patterns/vhdx.hexpat) | Microsoft Hyper-V Virtual Hard Disk format |
|
||||||
|
| VOX | | [`patterns/vox.hexpat`](patterns/vox.hexpat) | MagicaVoxel scene description format |
|
||||||
| WAV | `audio/x-wav` | [`patterns/wav.hexpat`](patterns/wav.hexpat) | RIFF header, WAVE header, PCM header |
|
| 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 |
|
| WAD | | [`patterns/wad.hexpat`](patterns/wad.hexpat) | DOOM WAD Archive |
|
||||||
|
| WebP | `image/webp` | [`patterns/webp.hexpat`](patterns/webp.hexpat) | Google WebP image |
|
||||||
| XBEH | `audio/x-xbox-executable` | [`patterns/xbeh.hexpat`](patterns/xbeh.hexpat) | Xbox executable |
|
| XBEH | `audio/x-xbox-executable` | [`patterns/xbeh.hexpat`](patterns/xbeh.hexpat) | Xbox executable |
|
||||||
| XCI | | [`patterns/xci.hexpat`](patterns/xci.hexpat) | Nintendo Switch XCI cardridge ROM |
|
| XCI | | [`patterns/xci.hexpat`](patterns/xci.hexpat) | Nintendo Switch XCI cartridge ROM |
|
||||||
|
| XGT | | [`patterns/xgt.hexpat`](patterns/xgstexture.hexpat) | Exient XGS Engine Texture |
|
||||||
| Xilinx BIT | | [`patterns/xilinx_bit.hexpat`](patterns/xilinx_bit.hexpat) | Xilinx FPGA Bitstreams |
|
| Xilinx BIT | | [`patterns/xilinx_bit.hexpat`](patterns/xilinx_bit.hexpat) | Xilinx FPGA Bitstreams |
|
||||||
|
| Xilinx Bootgen | `application/x-xilinx-boot-zynqmp` | [`patterns/xilinx_bootgen.hexpat`](patterns/xilinx_bootgen.hexpat) | Xilinx ZynqMP Boot Images |
|
||||||
|
| ZIM | | [`patterns/zim.hexpat`](patterns/zim.hexpat) | [ZIM](https://openzim.org) file format |
|
||||||
| ZIP | `application/zip` | [`patterns/zip.hexpat`](patterns/zip.hexpat) | End of Central Directory Header, Central Directory File Headers |
|
| 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 |
|
| 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 |
|
| ZSTD | `application/zstd` | [`patterns/zstd.hexpat`](patterns/zstd.hexpat) | Zstandard compressed data format |
|
||||||
|
| MOD | `3d-model/mod` | [`patterns/DMC3HD-Mod.hexpat`](patterns/dmc3_hd_mod.hexpat) | 3D Model files used in Devil May Cry 3 HD Collection |
|
||||||
|
| CBM BASIC | | [`commodore_basic.hexpat`](patterns/commodore_basic.hexpat) | Commodore BASIC |
|
||||||
|
|
||||||
### Scripts
|
### Scripts
|
||||||
|
|
||||||
@@ -119,9 +220,9 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
|
|||||||
|
|
||||||
| Name | Path | Description |
|
| 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 |
|
| 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
|
### Yara rules
|
||||||
|
|
||||||
@@ -156,6 +257,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 |
|
| 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 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 |
|
| 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 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 Windows | [`encodings/cyrillic_windows.tbl`](encodings/cyrillic_windows.tbl) | Cyrillic Windows encoding |
|
||||||
| Cyrillic KOI8-R | [`encodings/cyrillic_koi8_r.tbl`](encodings/cyrillic_koi8_r.tbl) | Cyrillic KOI8-R encoding (Russian Characters) |
|
| Cyrillic KOI8-R | [`encodings/cyrillic_koi8_r.tbl`](encodings/cyrillic_koi8_r.tbl) | Cyrillic KOI8-R encoding (Russian Characters) |
|
||||||
@@ -185,12 +287,14 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
|
|||||||
| Vietnamese | [`encodings/vietnamese.tbl`](encodings/vietnamese.tbl) | Vietnamese character encoding |
|
| Vietnamese | [`encodings/vietnamese.tbl`](encodings/vietnamese.tbl) | Vietnamese character encoding |
|
||||||
|
|
||||||
### Data Processor Nodes
|
### Data Processor Nodes
|
||||||
|
|
||||||
| Name | Path | Description |
|
| Name | Path | Description |
|
||||||
|------|------|-------------|
|
|------|------|-------------|
|
||||||
| Caesar Cipher | [`nodes/caesar.hexnode`](nodes/caesar.hexnode) | Simple adjustable per-byte Caecar Cipher (ROT) |
|
| Caesar Cipher | [`nodes/caesar.hexnode`](nodes/caesar.hexnode) | Simple adjustable per-byte Caecar Cipher (ROT) |
|
||||||
| XOR Cipher | [`nodes/xor.hexnode`](nodes/xor.hexnode) | XORs a input with a repeating XOR pad |
|
| XOR Cipher | [`nodes/xor.hexnode`](nodes/xor.hexnode) | XORs a input with a repeating XOR pad |
|
||||||
|
|
||||||
### Themes
|
### Themes
|
||||||
|
|
||||||
| Name | Path | Description |
|
| Name | Path | Description |
|
||||||
|------|------|-------------|
|
|------|------|-------------|
|
||||||
| Visual Studio Dark | [`themes/vs_dark.json`](themes/vs_dark.json) | Theme similar to Visual Studio's Dark theme |
|
| Visual Studio Dark | [`themes/vs_dark.json`](themes/vs_dark.json) | Theme similar to Visual Studio's Dark theme |
|
||||||
@@ -199,3 +303,11 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
|
|||||||
| Catppuccin Frappe | [`themes/catppuccin-frappe.json`](themes/catppuccin-frappe.json) | Catppuccin Frappe Flavor (Dark Theme) |
|
| Catppuccin Frappe | [`themes/catppuccin-frappe.json`](themes/catppuccin-frappe.json) | Catppuccin Frappe Flavor (Dark Theme) |
|
||||||
| Catppuccin Macchiato | [`themes/catppuccin-macchiato.json`](themes/catppuccin-macchiato.json) | Catppuccin Macchiato Flavor (Dark Theme) |
|
| Catppuccin Macchiato | [`themes/catppuccin-macchiato.json`](themes/catppuccin-macchiato.json) | Catppuccin Macchiato Flavor (Dark Theme) |
|
||||||
| Catppuccin Mocha | [`themes/catppuccin-mocha.json`](themes/catppuccin-mocha.json) | Catppuccin Mocha Flavor (Dark Theme) |
|
| Catppuccin Mocha | [`themes/catppuccin-mocha.json`](themes/catppuccin-mocha.json) | Catppuccin Mocha Flavor (Dark Theme) |
|
||||||
|
| Theme Lion | [`themes/theme_lion.json`](themes/theme_lion.json) | Semantic CLion inspired theme (Dark Theme) |
|
||||||
|
| Retina Dark | [`themes/retina_dark.json`](themes/retina_dark.json) | Semantic theme based on Dark Theme |
|
||||||
|
|
||||||
|
### Disassemblers
|
||||||
|
|
||||||
|
| Name | Path | Description |
|
||||||
|
|------|------|-------------|
|
||||||
|
| 8051 | [`disassemblers/8051.json`](disassemblers/8051.json) | Intel 8051 Architecture |
|
||||||
|
|||||||
730
disassemblers/8051.json
Normal file
730
disassemblers/8051.json
Normal file
@@ -0,0 +1,730 @@
|
|||||||
|
{
|
||||||
|
"name": "Intel 8051",
|
||||||
|
"includes": [],
|
||||||
|
"options": [],
|
||||||
|
"opcodes": [
|
||||||
|
{
|
||||||
|
"mask": "0000'0000",
|
||||||
|
"mnemonic": "NOP",
|
||||||
|
"format": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0000'0010 AAAA'AAAA AAAA'AAAA",
|
||||||
|
"mnemonic": "LJMP",
|
||||||
|
"format": "#0x{A:04X}",
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"type": "jump",
|
||||||
|
"data": {
|
||||||
|
"destination": "A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1000'0000 AAAA'AAAA",
|
||||||
|
"mnemonic": "SJMP",
|
||||||
|
"format": "#0x{A:02X}",
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"type": "jump",
|
||||||
|
"data": {
|
||||||
|
"destination": "A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0111'0011",
|
||||||
|
"mnemonic": "JMP",
|
||||||
|
"format": "@A+DPTR"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0100'0000 AAAA'AAAA",
|
||||||
|
"mnemonic": "JC",
|
||||||
|
"format": "PC + 0x{A:02X}",
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"type": "jump",
|
||||||
|
"data": {
|
||||||
|
"destination": "offset + 2 + A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0011'0000 BBBB'BBBB AAAA'AAAA",
|
||||||
|
"mnemonic": "JNB",
|
||||||
|
"format": "BIT[0x{B:02X}], PC + 0x{A:02X}",
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"type": "jump",
|
||||||
|
"data": {
|
||||||
|
"destination": "offset + 3 + A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0001'0000 BBBB'BBBB AAAA'AAAA",
|
||||||
|
"mnemonic": "JBC",
|
||||||
|
"format": "BIT[0x{B:02X}], PC + 0x{A:02X}",
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"type": "jump",
|
||||||
|
"data": {
|
||||||
|
"destination": "offset + 3 + A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0010'0000 AAAA'AAAA RRRR'RRRR",
|
||||||
|
"mnemonic": "JB",
|
||||||
|
"format": "BIT[0x{A:02X}], PC + 0x{R:02X}",
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"type": "jump",
|
||||||
|
"data": {
|
||||||
|
"destination": "offset + 3 + A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0001'0010 AAAA'AAAA AAAA'AAAA",
|
||||||
|
"mnemonic": "LCALL",
|
||||||
|
"format": "#0x{A:04X}",
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"type": "jump",
|
||||||
|
"data": {
|
||||||
|
"destination": "A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "PPP1'0001 AAAA'AAAA",
|
||||||
|
"mnemonic": "ACALL",
|
||||||
|
"format": "page{P} #0x{A:04X}",
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"type": "jump",
|
||||||
|
"data": {
|
||||||
|
"destination": "P * 256 + A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "PPP0'0001 AAAA'AAAA",
|
||||||
|
"mnemonic": "AJMP",
|
||||||
|
"format": "page{P} #0x{A:04X}",
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"type": "jump",
|
||||||
|
"data": {
|
||||||
|
"destination": "P * 256 + A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0000'0011",
|
||||||
|
"mnemonic": "RR",
|
||||||
|
"format": "A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0001'0011",
|
||||||
|
"mnemonic": "RRC",
|
||||||
|
"format": "A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0010'0011",
|
||||||
|
"mnemonic": "RL",
|
||||||
|
"format": "A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0011'0011",
|
||||||
|
"mnemonic": "RLC",
|
||||||
|
"format": "A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0000'0100",
|
||||||
|
"mnemonic": "INC",
|
||||||
|
"format": "A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0000'0101 AAAA'AAAA",
|
||||||
|
"mnemonic": "INC",
|
||||||
|
"format": "IRAM[0x{A:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0000'011R",
|
||||||
|
"mnemonic": "INC",
|
||||||
|
"format": "@R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0000'1RRR",
|
||||||
|
"mnemonic": "INC",
|
||||||
|
"format": "R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1010'0011",
|
||||||
|
"mnemonic": "INC",
|
||||||
|
"format": "DPTR"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0001'0100",
|
||||||
|
"mnemonic": "DEC",
|
||||||
|
"format": "A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0001'0101 AAAA'AAAA",
|
||||||
|
"mnemonic": "DEC",
|
||||||
|
"format": "IRAM[0x{A:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0001'0110",
|
||||||
|
"mnemonic": "DEC",
|
||||||
|
"format": "@R0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0001'0111",
|
||||||
|
"mnemonic": "DEC",
|
||||||
|
"format": "@R1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0001'1RRR",
|
||||||
|
"mnemonic": "DEC",
|
||||||
|
"format": "R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1110'0100",
|
||||||
|
"mnemonic": "CLR",
|
||||||
|
"format": "A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1100'0010 AAAA'AAAA",
|
||||||
|
"mnemonic": "CLR",
|
||||||
|
"format": "BIT[0x{A:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1100'0011",
|
||||||
|
"mnemonic": "CLR",
|
||||||
|
"format": "C"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1111'0000",
|
||||||
|
"mnemonic": "MOVX",
|
||||||
|
"format": "@DPTR, A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1110'0000",
|
||||||
|
"mnemonic": "MOVX",
|
||||||
|
"format": "A, @DPTR"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1111'001R",
|
||||||
|
"mnemonic": "MOVX",
|
||||||
|
"format": "@R{R}, A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1110'001R",
|
||||||
|
"mnemonic": "MOVX",
|
||||||
|
"format": "A, @R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0111'011R AAAA'AAAA",
|
||||||
|
"mnemonic": "MOV",
|
||||||
|
"format": "@R{R}, #0x{A:02X}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0111'1RRR AAAA'AAAA",
|
||||||
|
"mnemonic": "MOV",
|
||||||
|
"format": "R{R}, #0x{A:02X}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1111'1RRR",
|
||||||
|
"mnemonic": "MOV",
|
||||||
|
"format": "R{R}, A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1110'011R",
|
||||||
|
"mnemonic": "MOV",
|
||||||
|
"format": "A, @R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1111'011R",
|
||||||
|
"mnemonic": "MOV",
|
||||||
|
"format": "@R{R}, A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1110'1RRR",
|
||||||
|
"mnemonic": "MOV",
|
||||||
|
"format": "A, R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1001'0010 AAAA'AAAA",
|
||||||
|
"mnemonic": "MOV",
|
||||||
|
"format": "BIT[0x{A:02X}], C"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1010'0010 AAAA'AAAA",
|
||||||
|
"mnemonic": "MOV",
|
||||||
|
"format": "C, BIT[0x{A:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1001'0000 DDDD'DDDD DDDD'DDDD",
|
||||||
|
"mnemonic": "MOV",
|
||||||
|
"format": "DPTR, #0x{D:04X}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1110'0101 AAAA'AAAA",
|
||||||
|
"mnemonic": "MOV",
|
||||||
|
"format": "A, IRAM[0x{A:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1111'0101 AAAA'AAAA",
|
||||||
|
"mnemonic": "MOV",
|
||||||
|
"format": "IRAM[#0x{A:02X}], A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0111'0101 AAAA'AAAA DDDD'DDDD",
|
||||||
|
"mnemonic": "MOV",
|
||||||
|
"format": "IRAM[0x{A:02X}], #0x{D:02X}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1000'0101 AAAA'AAAA BBBB'BBBB",
|
||||||
|
"mnemonic": "MOV",
|
||||||
|
"format": "IRAM[0x{A:02X}], IRAM[0x{B:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0111'0100 DDDD'DDDD",
|
||||||
|
"mnemonic": "MOV",
|
||||||
|
"format": "A, #0x{D:02X}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1000'011R AAAA'AAAA",
|
||||||
|
"mnemonic": "MOV",
|
||||||
|
"format": "IRAM[0x{A:02X}], @R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1000'1RRR AAAA'AAAA",
|
||||||
|
"mnemonic": "MOV",
|
||||||
|
"format": "IRAM[0x{A:02X}], R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1010'011R AAAA'AAAA",
|
||||||
|
"mnemonic": "MOV",
|
||||||
|
"format": "@R{R}, IRAM[0x{A:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1010'1RRR AAAA'AAAA",
|
||||||
|
"mnemonic": "MOV",
|
||||||
|
"format": "R{R}, IRAM[0x{A:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0110'0000 AAAA'AAAA",
|
||||||
|
"mnemonic": "JZ",
|
||||||
|
"format": "PC + 0x{A:02X}",
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"type": "jump",
|
||||||
|
"data": {
|
||||||
|
"destination": "offset + 2 + A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0111'0000 AAAA'AAAA",
|
||||||
|
"mnemonic": "JNZ",
|
||||||
|
"format": "PC + 0x{A:02X}",
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"type": "jump",
|
||||||
|
"data": {
|
||||||
|
"destination": "offset + 2 + A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1001'0011",
|
||||||
|
"mnemonic": "MOVC",
|
||||||
|
"format": "A, @A+DPTR"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1000'0011",
|
||||||
|
"mnemonic": "MOVC",
|
||||||
|
"format": "A, @A+PC"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1101'011R",
|
||||||
|
"mnemonic": "XCHD",
|
||||||
|
"format": "A, @R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1100'011R",
|
||||||
|
"mnemonic": "XCH",
|
||||||
|
"format": "A, @R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1100'1RRR",
|
||||||
|
"mnemonic": "XCH",
|
||||||
|
"format": "A, R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1100'0101 AAAA'AAAA",
|
||||||
|
"mnemonic": "XCH",
|
||||||
|
"format": "A, IRAM[0x{A:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0010'0010",
|
||||||
|
"mnemonic": "RET",
|
||||||
|
"format": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0011'0010",
|
||||||
|
"mnemonic": "RETI",
|
||||||
|
"format": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1101'0010 AAAA'AAAA",
|
||||||
|
"mnemonic": "SETB",
|
||||||
|
"format": "BIT[0x{A:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1101'0011",
|
||||||
|
"mnemonic": "SETB",
|
||||||
|
"format": "C"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0101'0010 AAAA'AAAA",
|
||||||
|
"mnemonic": "ANL",
|
||||||
|
"format": "IRAM[0x{A:02X}], A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0101'0101 AAAA'AAAA",
|
||||||
|
"mnemonic": "ANL",
|
||||||
|
"format": "A, IRAM[0x{A:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0101'0011 AAAA'AAAA DDDD'DDDD",
|
||||||
|
"mnemonic": "ANL",
|
||||||
|
"format": "A, IRAM[0x{A:02X}], #0x{D:02X}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0101'0100 AAAA'AAAA",
|
||||||
|
"mnemonic": "ANL",
|
||||||
|
"format": "A, #0x{A:02X}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0101'011R",
|
||||||
|
"mnemonic": "ANL",
|
||||||
|
"format": "A, @R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0101'1RRR",
|
||||||
|
"mnemonic": "ANL",
|
||||||
|
"format": "A, R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1000'0010 AAAA'AAAA",
|
||||||
|
"mnemonic": "ANL",
|
||||||
|
"format": "C, BIT[0x{A:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1011'0000 AAAA'AAAA",
|
||||||
|
"mnemonic": "ANL",
|
||||||
|
"format": "C, /BIT[0x{A:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0100'0010 AAAA'AAAA",
|
||||||
|
"mnemonic": "ORL",
|
||||||
|
"format": "IRAM[0x{A:02X}], A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0100'0011 AAAA'AAAA DDDD'DDDD",
|
||||||
|
"mnemonic": "ORL",
|
||||||
|
"format": "IRAM[0x{A:02X}], #0x{D:02X}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0100'0100 DDDD'DDDD",
|
||||||
|
"mnemonic": "ORL",
|
||||||
|
"format": "A, #0x{D:02X}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0100'011R",
|
||||||
|
"mnemonic": "ORL",
|
||||||
|
"format": "A, @R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0100'1RRR",
|
||||||
|
"mnemonic": "ORL",
|
||||||
|
"format": "A, R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0100'0101 AAAA'AAAA",
|
||||||
|
"mnemonic": "ORL",
|
||||||
|
"format": "A, IRAM[0x{A:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0111'0010 AAAA'AAAA",
|
||||||
|
"mnemonic": "ORL",
|
||||||
|
"format": "C, BIT[0x{A:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1010'0000 AAAA'AAAA",
|
||||||
|
"mnemonic": "ORL",
|
||||||
|
"format": "C, /BIT[0x{A:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0110'0010 AAAA'AAAA",
|
||||||
|
"mnemonic": "XRL",
|
||||||
|
"format": "IRAM[0x{A:02X}], A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0110'0011 AAAA'AAAA DDDD'DDDD",
|
||||||
|
"mnemonic": "XRL",
|
||||||
|
"format": "IRAM[0x{A:02X}], #0x{D:02X}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0110'0100 DDDD'DDDD",
|
||||||
|
"mnemonic": "XRL",
|
||||||
|
"format": "A, #0x{D:02X}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0110'011R",
|
||||||
|
"mnemonic": "XRL",
|
||||||
|
"format": "A, @R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0110'1RRR",
|
||||||
|
"mnemonic": "XRL",
|
||||||
|
"format": "A, R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0110'0101 AAAA'AAAA",
|
||||||
|
"mnemonic": "XRL",
|
||||||
|
"format": "A, IRAM[0x{A:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0010'0100 DDDD'DDDD",
|
||||||
|
"mnemonic": "ADD",
|
||||||
|
"format": "A, #0x{D:02X}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0010'011R",
|
||||||
|
"mnemonic": "ADD",
|
||||||
|
"format": "A, @R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0010'0101 AAAA'AAAA",
|
||||||
|
"mnemonic": "ADD",
|
||||||
|
"format": "A, IRAM[0x{A:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0011'0100 DDDD'DDDD",
|
||||||
|
"mnemonic": "ADDC",
|
||||||
|
"format": "A, #0x{D:02X}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0011'011R",
|
||||||
|
"mnemonic": "ADDC",
|
||||||
|
"format": "A, @R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0011'0101 AAAA'AAAA",
|
||||||
|
"mnemonic": "ADDC",
|
||||||
|
"format": "A, IRAM[0x{A:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0011'1RRR",
|
||||||
|
"mnemonic": "ADDC",
|
||||||
|
"format": "A, R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1001'0100 DDDD'DDDD",
|
||||||
|
"mnemonic": "SUBB",
|
||||||
|
"format": "A, #0x{D:02X}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1001'0101 IIII'IIII",
|
||||||
|
"mnemonic": "SUBB",
|
||||||
|
"format": "A, IRAM[0x{I:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1001'011R",
|
||||||
|
"mnemonic": "SUBB",
|
||||||
|
"format": "A, @R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1001'1RRR",
|
||||||
|
"mnemonic": "SUBB",
|
||||||
|
"format": "A, R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1010'0100",
|
||||||
|
"mnemonic": "MUL",
|
||||||
|
"format": "AB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1000'0100",
|
||||||
|
"mnemonic": "DIV",
|
||||||
|
"format": "AB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0010'1RRR",
|
||||||
|
"mnemonic": "ORL",
|
||||||
|
"format": "A, R{R}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1011'0101 IIII'IIII AAAA'AAAA",
|
||||||
|
"mnemonic": "CJNE",
|
||||||
|
"format": "A, IRAM[0x{I:02X}], PC + 0x{A:02X}",
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"type": "jump",
|
||||||
|
"data": {
|
||||||
|
"destination": "offset + 3 + A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1011'0100 DDDD'DDDD AAAA'AAAA",
|
||||||
|
"mnemonic": "CJNE",
|
||||||
|
"format": "A, #0x{D:02X}, PC + 0x{A:02X}",
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"type": "jump",
|
||||||
|
"data": {
|
||||||
|
"destination": "offset + 3 + A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1011'011R DDDD'DDDD AAAA'AAAA",
|
||||||
|
"mnemonic": "CJNE",
|
||||||
|
"format": "@R{R}, #0x{D:02X}, PC + 0x{A:02X}",
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"type": "jump",
|
||||||
|
"data": {
|
||||||
|
"destination": "offset + 3 + A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1011'1RRR DDDD'DDDD AAAA'AAAA",
|
||||||
|
"mnemonic": "CJNE",
|
||||||
|
"format": "R{R}, #0x{D:02X}, PC + 0x{A:02X}",
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"type": "jump",
|
||||||
|
"data": {
|
||||||
|
"destination": "offset + 3 + A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1101'0101 IIII'IIII AAAA'AAAA",
|
||||||
|
"mnemonic": "DJNZ",
|
||||||
|
"format": "IRAM[0x{I:02X}], PC + 0x{A:02X}",
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"type": "jump",
|
||||||
|
"data": {
|
||||||
|
"destination": "offset + 3 + A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1101'1RRR AAAA'AAAA",
|
||||||
|
"mnemonic": "DJNZ",
|
||||||
|
"format": "R{R}, PC + 0x{R:02X}",
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"type": "jump",
|
||||||
|
"data": {
|
||||||
|
"destination": "offset + 2 + A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "0101'0000 AAAA'AAAA",
|
||||||
|
"mnemonic": "JNC",
|
||||||
|
"format": "PC + 0x{A:02X}",
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"type": "jump",
|
||||||
|
"data": {
|
||||||
|
"destination": "offset + 2 + A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1101'0000 AAAA'AAAA",
|
||||||
|
"mnemonic": "POP",
|
||||||
|
"format": "IRAM[0x{A:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1100'0000 AAAA'AAAA",
|
||||||
|
"mnemonic": "PUSH",
|
||||||
|
"format": "IRAM[0x{A:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1101'0100",
|
||||||
|
"mnemonic": "DA",
|
||||||
|
"format": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1100'0100",
|
||||||
|
"mnemonic": "SWAP",
|
||||||
|
"format": "A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1111'0100",
|
||||||
|
"mnemonic": "CPL",
|
||||||
|
"format": "A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1011'0011",
|
||||||
|
"mnemonic": "CPL",
|
||||||
|
"format": "C"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1011'0010 BBBB'BBBB",
|
||||||
|
"mnemonic": "CPL",
|
||||||
|
"format": "BIT[0x{B:02X}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "1010'0101",
|
||||||
|
"mnemonic": "INVALID",
|
||||||
|
"format": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mask": "XXXX'XXXX",
|
||||||
|
"mnemonic": "DB",
|
||||||
|
"format": "#0x{X:02X}",
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"type": "data",
|
||||||
|
"data": {
|
||||||
|
"value": "X"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
1045
disassemblers/jvm.json
Normal file
1045
disassemblers/jvm.json
Normal file
File diff suppressed because it is too large
Load Diff
18594
encodings/big5.tbl
Normal file
18594
encodings/big5.tbl
Normal file
File diff suppressed because it is too large
Load Diff
21921
encodings/gbk.tbl
Normal file
21921
encodings/gbk.tbl
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <hex/impl/imhex_check.pat>
|
import hex.impl.imhex_check;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Core intrinsic functions to interact with the ImHex Hex Editor
|
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
|
A type representing a selection in the hex editor
|
||||||
@@ -21,20 +21,30 @@ namespace hex::core {
|
|||||||
@return The current selection
|
@return The current selection
|
||||||
*/
|
*/
|
||||||
fn get_selection() {
|
fn get_selection() {
|
||||||
u128 result = builtin::hex::core::get_selection();
|
u128 selection = builtin::hex::core::get_selection();
|
||||||
|
|
||||||
Selection result;
|
Selection result;
|
||||||
if (result == u128(-1)) {
|
if (selection == u128(-1)) {
|
||||||
result.valid = false;
|
result.valid = false;
|
||||||
result.address = 0x00;
|
result.address = 0x00;
|
||||||
result.size = 0x00;
|
result.size = 0x00;
|
||||||
} else {
|
} else {
|
||||||
result.valid = true;
|
result.valid = true;
|
||||||
result.address = result >> 64;
|
result.address = selection >> 64;
|
||||||
result.size = result & u64(-1);
|
result.size = selection & u64(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Add a file to the Virtual Filesystem
|
||||||
|
@param path The name of the file
|
||||||
|
@param pattern The pattern associated with the file
|
||||||
|
*/
|
||||||
|
fn add_virtual_file(str path, auto pattern)
|
||||||
|
{
|
||||||
|
builtin::hex::core::add_virtual_file(path, pattern);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <hex/impl/imhex_check.pat>
|
import hex.impl.imhex_check;
|
||||||
|
|
||||||
|
import std.mem;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Library to allow decoding of more complex values
|
Library to allow decoding of more complex values
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace hex::dec {
|
namespace auto hex::dec {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Demangles a mangled name into a human readable name
|
Demangles a mangled name into a human readable name
|
||||||
@@ -17,4 +19,57 @@ namespace hex::dec {
|
|||||||
return builtin::hex::dec::demangle(mangled_name);
|
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 A value representing either the number of bytes decompressed or an error code from zlib
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Decompresses the bytes of a pattern into a section using the lz4 algorithm
|
||||||
|
@param pattern The pattern whose bytes should be decompressed
|
||||||
|
@param section The section to decompress the data into
|
||||||
|
@param frame Whether the data is framed or not
|
||||||
|
@return true if successful, false otherwise
|
||||||
|
*/
|
||||||
|
fn lz4_decompress(ref auto pattern, std::mem::Section section, bool frame = true) {
|
||||||
|
return builtin::hex::dec::lz4_decompress(pattern, section, frame);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <hex/impl/imhex_check.pat>
|
import hex.impl.imhex_check;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Library to do HTTP requests
|
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
|
Performs a HTTP GET request to the given URL and returns the response body
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <hex/impl/imhex_check.pat>
|
import hex.impl.imhex_check;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Library to interact with the currently loaded provider.
|
Library to interact with the currently loaded provider.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace hex::prv {
|
namespace auto hex::prv {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
28
includes/hex/type/encstr.pat
Normal file
28
includes/hex/type/encstr.pat
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
import hex.impl.imhex_check;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Types to work with custom encoded strings using Thiny encoding definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace auto hex::type {
|
||||||
|
|
||||||
|
/**
|
||||||
|
A string that was encoded using a custom encoding
|
||||||
|
@tparam Data Pattern whose bytes are used in the decoding process
|
||||||
|
@tparam EncodingDefinition A string containing a Thingy encoding definition as used by ImHex's custom encoding feature
|
||||||
|
*/
|
||||||
|
struct EncodedString<auto Data, auto EncodingDefinition> {
|
||||||
|
builtin::hex::dec::EncodedString<Data, EncodingDefinition> string;
|
||||||
|
} [[sealed, format("hex::type::impl::format_encoded_string")]];
|
||||||
|
|
||||||
|
namespace impl {
|
||||||
|
|
||||||
|
fn format_encoded_string(ref auto string) {
|
||||||
|
return string.string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
143
includes/hex/type/instruction.pat
Normal file
143
includes/hex/type/instruction.pat
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
import hex.impl.imhex_check;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Types to work with machine code
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace auto hex::type {
|
||||||
|
|
||||||
|
/**
|
||||||
|
A machine code instruction which will get disassembled
|
||||||
|
@tparam DisassemblerSetting A string containing the config for the disassembler in the form of "architecture; setting1, setting2, no-setting3"
|
||||||
|
@tparam SyntaxType Syntax used in the disassembly. Possible values are "intel", "at&t", "masm" and "motorola"
|
||||||
|
@tparam ImageBaseAddress Start address of the instruction region in the data
|
||||||
|
@tparam ImageLoadAddress Address where the instructions will be loaded into memory
|
||||||
|
|
||||||
|
Possible Values for DisassemblerSetting:
|
||||||
|
- Architecture, all may be suffixed with le or be to specify endianess (e.g armbe or mipsle)
|
||||||
|
- arm
|
||||||
|
- thumb
|
||||||
|
- aarch64
|
||||||
|
- arm64
|
||||||
|
- mips
|
||||||
|
- x86
|
||||||
|
- x86_64
|
||||||
|
- x64
|
||||||
|
- ppc
|
||||||
|
- powerpc
|
||||||
|
- sparc
|
||||||
|
- sysz
|
||||||
|
- xcore
|
||||||
|
- m68k
|
||||||
|
- m680x
|
||||||
|
- tms320c64x
|
||||||
|
- evm
|
||||||
|
- wasm
|
||||||
|
- riscv
|
||||||
|
- mos65xx
|
||||||
|
- bpf
|
||||||
|
- sh
|
||||||
|
- tricore
|
||||||
|
|
||||||
|
- Settings, not all settings make sense for each architecture. Prefixing settings with no- will remove them instead
|
||||||
|
- 16bit
|
||||||
|
- 32bit
|
||||||
|
- 64bit
|
||||||
|
- cortex-m
|
||||||
|
- armv8
|
||||||
|
- micromips
|
||||||
|
- mips2
|
||||||
|
- mips3
|
||||||
|
- mips32r6
|
||||||
|
- sparcv9
|
||||||
|
- qpx
|
||||||
|
- spe
|
||||||
|
- ps
|
||||||
|
- 68000
|
||||||
|
- 68010
|
||||||
|
- 68020
|
||||||
|
- 68030
|
||||||
|
- 68040
|
||||||
|
- 68060
|
||||||
|
- 6301
|
||||||
|
- 6309
|
||||||
|
- 6800
|
||||||
|
- 6801
|
||||||
|
- 6805
|
||||||
|
- 6808
|
||||||
|
- 6809
|
||||||
|
- 6811
|
||||||
|
- cpu12
|
||||||
|
- hcs08
|
||||||
|
- bpfe
|
||||||
|
- rv32g
|
||||||
|
- rv64g
|
||||||
|
- riscvc
|
||||||
|
- 6502
|
||||||
|
- 65c02
|
||||||
|
- w65c02
|
||||||
|
- 65816
|
||||||
|
- long-m
|
||||||
|
- long-x
|
||||||
|
- sh2
|
||||||
|
- sh2a
|
||||||
|
- sh3
|
||||||
|
- sh4
|
||||||
|
- sh4a
|
||||||
|
- shfpu
|
||||||
|
- shdsp
|
||||||
|
- 1.1
|
||||||
|
- 1.2
|
||||||
|
- 1.3
|
||||||
|
- 1.3.1
|
||||||
|
- 1.6
|
||||||
|
- 1.6.1
|
||||||
|
- 1.6.2
|
||||||
|
*/
|
||||||
|
struct Instruction<auto DisassemblerSetting, auto SyntaxType, auto ImageBaseAddress, auto ImageLoadAddress> {
|
||||||
|
builtin::hex::dec::Instruction<DisassemblerSetting, SyntaxType, ImageBaseAddress, ImageLoadAddress> instruction;
|
||||||
|
} [[sealed, format("hex::type::impl::format_instruction")]];
|
||||||
|
|
||||||
|
/**
|
||||||
|
A machine code instruction which will get disassembled using Intel syntax
|
||||||
|
@tparam DisassemblerSetting A string containing the config for the disassembler in the form of "architecture; setting1, setting2, no-setting3"
|
||||||
|
@tparam ImageBaseAddress Start address of the instruction region in the data
|
||||||
|
@tparam ImageLoadAddress Address where the instructions will be loaded into memory
|
||||||
|
*/
|
||||||
|
using InstructionIntel<auto DisassemblerSetting, auto ImageBaseAddress, auto ImageLoadAddress> = Instruction<DisassemblerSetting, "intel", ImageBaseAddress, ImageLoadAddress>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
A machine code instruction which will get disassembled using AT&T syntax
|
||||||
|
@tparam DisassemblerSetting A string containing the config for the disassembler in the form of "architecture; setting1, setting2, no-setting3"
|
||||||
|
@tparam ImageBaseAddress Start address of the instruction region in the data
|
||||||
|
@tparam ImageLoadAddress Address where the instructions will be loaded into memory
|
||||||
|
*/
|
||||||
|
using InstructionATNT<auto DisassemblerSetting, auto ImageBaseAddress, auto ImageLoadAddress> = Instruction<DisassemblerSetting, "at&t", ImageBaseAddress, ImageLoadAddress>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
A machine code instruction which will get disassembled using MASM syntax
|
||||||
|
@tparam DisassemblerSetting A string containing the config for the disassembler in the form of "architecture; setting1, setting2, no-setting3"
|
||||||
|
@tparam ImageBaseAddress Start address of the instruction region in the data
|
||||||
|
@tparam ImageLoadAddress Address where the instructions will be loaded into memory
|
||||||
|
*/
|
||||||
|
using InstructionMASM<auto DisassemblerSetting, auto ImageBaseAddress, auto ImageLoadAddress> = Instruction<DisassemblerSetting, "masm", ImageBaseAddress, ImageLoadAddress>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
A machine code instruction which will get disassembled using Motorola syntax
|
||||||
|
@tparam DisassemblerSetting A string containing the config for the disassembler in the form of "architecture; setting1, setting2, no-setting3"
|
||||||
|
@tparam ImageBaseAddress Start address of the instruction region in the data
|
||||||
|
@tparam ImageLoadAddress Address where the instructions will be loaded into memory
|
||||||
|
*/
|
||||||
|
using InstructionMotorola<auto DisassemblerSetting, auto ImageBaseAddress, auto ImageLoadAddress> = Instruction<DisassemblerSetting, "motorola", ImageBaseAddress, ImageLoadAddress>;
|
||||||
|
|
||||||
|
namespace impl {
|
||||||
|
|
||||||
|
fn format_instruction(ref auto instruction) {
|
||||||
|
return instruction.instruction;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
66
includes/hex/type/json.pat
Normal file
66
includes/hex/type/json.pat
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
import hex.impl.imhex_check;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Types to decode JSON and JSON-like file formats into a pattern tree
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace auto hex::type {
|
||||||
|
|
||||||
|
/**
|
||||||
|
Type representing a JSON string
|
||||||
|
@tparam Size size of the string
|
||||||
|
*/
|
||||||
|
struct Json<auto Size> {
|
||||||
|
char __data[Size] [[hidden, no_unique_address]];
|
||||||
|
builtin::hex::dec::Json<__data> json [[merge]];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Type representing Bson data
|
||||||
|
@tparam Size size of the data
|
||||||
|
*/
|
||||||
|
struct Bson<auto Size> {
|
||||||
|
u8 __data[Size] [[hidden, no_unique_address]];
|
||||||
|
builtin::hex::dec::Bson<__data> bson [[merge]];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Type representing Cbor data
|
||||||
|
@tparam Size size of the data
|
||||||
|
*/
|
||||||
|
struct Cbor<auto Size> {
|
||||||
|
u8 __data[Size] [[hidden, no_unique_address]];
|
||||||
|
builtin::hex::dec::Cbor<__data> cbor [[merge]];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Type representing Bjdata data
|
||||||
|
@tparam Size size of the data
|
||||||
|
*/
|
||||||
|
struct Bjdata<auto Size> {
|
||||||
|
u8 __data[Size] [[hidden, no_unique_address]];
|
||||||
|
builtin::hex::dec::Bjdata<__data> bjdata [[merge]];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Type representing Msgpack data
|
||||||
|
@tparam Size size of the data
|
||||||
|
*/
|
||||||
|
struct Msgpack<auto Size> {
|
||||||
|
u8 __data[Size] [[hidden, no_unique_address]];
|
||||||
|
builtin::hex::dec::Msgpack<__data> msgpack [[merge]];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Type representing Ubjson data
|
||||||
|
@tparam Size size of the data
|
||||||
|
*/
|
||||||
|
struct Ubjson<auto Size> {
|
||||||
|
u8 __data[Size] [[hidden, no_unique_address]];
|
||||||
|
builtin::hex::dec::Ubjson<__data> ubjson [[merge]];
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <std/io.pat>
|
import std.io;
|
||||||
#include <std/mem.pat>
|
import std.mem;
|
||||||
|
|
||||||
#include <hex/impl/imhex_check.pat>
|
import hex.impl.imhex_check;
|
||||||
#include <hex/dec.pat>
|
import hex.dec;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Types to automatically decode mangled names
|
Types to automatically decode mangled names
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace hex::type {
|
namespace auto hex::type {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A mangled name string that gets demangled when displayed
|
A mangled name string that gets demangled when displayed
|
||||||
|
|||||||
@@ -1,13 +1,30 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <std/sys.pat>
|
import std.sys;
|
||||||
|
import std.core;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
The array library contains a helper type to make it easier to create multi-dimensional arrays
|
The array library contains a helper type to make it easier to create multi-dimensional arrays
|
||||||
and pass arrays to functions as parameters.
|
and pass arrays to functions as parameters.
|
||||||
|
|
||||||
|
## Multi-dimensional arrays
|
||||||
|
|
||||||
|
The following example shows how to use multi-dimensional arrays with structs.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
import std.array;
|
||||||
|
|
||||||
|
struct File {
|
||||||
|
u8 width, height;
|
||||||
|
std::Array<std::Array<u8, parent.width>, height> cells;
|
||||||
|
};
|
||||||
|
|
||||||
|
File file @ 0x00;
|
||||||
|
```
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace std {
|
namespace auto std {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Simple one dimensional array wrapper
|
Simple one dimensional array wrapper
|
||||||
@@ -30,6 +47,16 @@ namespace std {
|
|||||||
std::assert($ - startAddress == NumBytes, "Not enough bytes available to fit a whole number of types");
|
std::assert($ - startAddress == NumBytes, "Not enough bytes available to fit a whole number of types");
|
||||||
} [[format("std::impl::format_array")]];
|
} [[format("std::impl::format_array")]];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
An interface type for getting the index of the currently processed element in an array. This is a nice wrapper around `std::core::array_index()`
|
||||||
|
|
||||||
|
To use it, inherit from it and use the `this.index` field to get the index of the current element
|
||||||
|
*/
|
||||||
|
struct IIndexed {
|
||||||
|
const u64 index = std::core::array_index();
|
||||||
|
};
|
||||||
|
|
||||||
namespace impl {
|
namespace impl {
|
||||||
|
|
||||||
fn format_array(ref auto array) {
|
fn format_array(ref auto array) {
|
||||||
|
|||||||
70
includes/std/attrs.pat
Normal file
70
includes/std/attrs.pat
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import std.io;
|
||||||
|
import std.core;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
The attributes library contains a set of attributes that can be used to annotate types with certain properties.
|
||||||
|
To use an attribute, simply make your custom type inherit from the attribute type you want to use.
|
||||||
|
|
||||||
|
For example, to make a type hidden, you can use the `Hidden` attribute like this:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
struct MyType : std::attr::Hidden {
|
||||||
|
// ...
|
||||||
|
};
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace auto std::attr {
|
||||||
|
|
||||||
|
/**
|
||||||
|
Attribute that marks a type as a literal type.
|
||||||
|
This means the type behaves like a built-in type in the sense that it doesn't show its internal state and its display value is determined by a format function.
|
||||||
|
It can also be transformed into a different built-in literal when used in an expression.
|
||||||
|
@tparam FormatFunction The format function to use. The return value of this function is used to display the value of the literal and also determines the value returned when the literal is used in an expression.
|
||||||
|
*/
|
||||||
|
struct Literal<auto FormatFunction> { }
|
||||||
|
[[sealed, format_read(FormatFunction), transform(FormatFunction)]];
|
||||||
|
|
||||||
|
/**
|
||||||
|
Attribute that changes the name of the variable created from a type.
|
||||||
|
@tparam Name The name of the variable created
|
||||||
|
*/
|
||||||
|
struct Named<auto Name> { }
|
||||||
|
[[name(Name)]];
|
||||||
|
|
||||||
|
/**
|
||||||
|
Attribute that adds a comment to the variable created from a type.
|
||||||
|
@tparam Comment The comment to add
|
||||||
|
*/
|
||||||
|
struct Commented<auto Comment> {}
|
||||||
|
[[comment(Comment)]];
|
||||||
|
|
||||||
|
/**
|
||||||
|
Attribute that marks a type as hidden.
|
||||||
|
This means variables of this type are not displayed in the UI.
|
||||||
|
*/
|
||||||
|
struct Hidden {}
|
||||||
|
[[hidden]];
|
||||||
|
|
||||||
|
/**
|
||||||
|
Attribute that marks a type as hidden and also hides it from the highlighter.
|
||||||
|
This means variables of this type are don't display any highlighting in the UI but are still visible.
|
||||||
|
*/
|
||||||
|
struct HighlightHidden {}
|
||||||
|
[[highlight_hidden]];
|
||||||
|
|
||||||
|
/**
|
||||||
|
Attribute that marks a type as inline.
|
||||||
|
Creating a variable of this type will not create a new layer but instead dump the contents of the type directly into the current layer.
|
||||||
|
*/
|
||||||
|
struct Inlined {}
|
||||||
|
[[inline]];
|
||||||
|
|
||||||
|
/**
|
||||||
|
Attribute that marks a type as sealed.
|
||||||
|
Sealed types don't display their internal state in the UI.
|
||||||
|
*/
|
||||||
|
struct Sealed {}
|
||||||
|
[[sealed]];
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <std/limits.pat>
|
import std.limits;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
This library contains various helper functions for common bit operations.
|
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
|
Calculates the number of 1 bits in a given number
|
||||||
@@ -14,9 +14,13 @@ namespace std::bit {
|
|||||||
@return The number of bits set to 1 in `x`
|
@return The number of bits set to 1 in `x`
|
||||||
*/
|
*/
|
||||||
fn popcount(u128 x) {
|
fn popcount(u128 x) {
|
||||||
x = (x & (std::limits::u128_max() / 3)) + ((x >> 1) & (std::limits::u128_max() / 3));
|
const u128 a = 0x55555555555555555555555555555555;
|
||||||
x = (x & (std::limits::u128_max() / 5)) + ((x >> 2) & (std::limits::u128_max() / 5));
|
const u128 b = 0x33333333333333333333333333333333;
|
||||||
x = (x & (std::limits::u128_max() / 17)) + ((x >> 4) & (std::limits::u128_max() / 17));
|
const u128 c = 0x0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F;
|
||||||
|
|
||||||
|
x = (x & a) + ((x >> 1) & a);
|
||||||
|
x = (x & b) + ((x >> 2) & b);
|
||||||
|
x = (x & c) + ((x >> 4) & c);
|
||||||
|
|
||||||
return x % 0xFF;
|
return x % 0xFF;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <std/mem.pat>
|
import std.mem;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
The core library contains intrinsics and "compiler magic" functions that
|
The core library contains intrinsics and "compiler magic" functions that
|
||||||
get extra help from the runtime to fulfill their purpose.
|
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.
|
The layout order of each field after byte-endianness has been handled.
|
||||||
@@ -38,27 +38,35 @@ 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 pattern The pattern to check
|
||||||
@param attribute The attribute's name to query
|
@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) {
|
fn get_attribute_value(ref auto pattern, str attribute) {
|
||||||
return builtin::std::core::get_attribute_value(pattern, attribute);
|
builtin::std::error("`std::core::get_attribute_value(pattern, attribute)` has been removed.\nUse `std::core::get_attribute_argument(pattern, attribute, [index])` instead.");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sets the current default endianess.
|
Sets the current default endianness.
|
||||||
Any patterns created following this attribute will be created using the set endianess.
|
Any patterns created following this attribute will be created using the set endianness.
|
||||||
@param endian The new default endianess
|
@param endian The new default endianness
|
||||||
*/
|
*/
|
||||||
fn set_endian(std::mem::Endian endian) {
|
fn set_endian(std::mem::Endian endian) {
|
||||||
builtin::std::core::set_endian(u32(endian));
|
builtin::std::core::set_endian(u32(endian));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Gets the current default endianess.
|
Gets the current default endianness.
|
||||||
@return The currently set default endianess
|
@return The currently set default endianness
|
||||||
*/
|
*/
|
||||||
fn get_endian() {
|
fn get_endian() {
|
||||||
return builtin::std::core::get_endian();
|
return builtin::std::core::get_endian();
|
||||||
@@ -146,4 +154,39 @@ namespace std::core {
|
|||||||
fn set_display_name(ref auto pattern, str name) {
|
fn set_display_name(ref auto pattern, str name) {
|
||||||
builtin::std::core::set_display_name(pattern, name);
|
builtin::std::core::set_display_name(pattern, name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Changes the comment attached to a pattern
|
||||||
|
@param pattern The pattern to modify
|
||||||
|
@param comment The new comment of the pattern
|
||||||
|
*/
|
||||||
|
fn set_pattern_comment(ref auto pattern, str comment) {
|
||||||
|
builtin::std::core::set_pattern_comment(pattern, comment);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Executes the function with the given name, passing in all given arguments
|
||||||
|
@param function_name The namespace-prefixed name of the function
|
||||||
|
@param args Arguments to pass to the function
|
||||||
|
*/
|
||||||
|
fn execute_function(str function_name, auto ... args) {
|
||||||
|
builtin::std::core::execute_function(function_name, args);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets the pattern color palette for all future created patterns
|
||||||
|
@param args RGBA8 colors as 32 bit integers (0xAABBGGRR)
|
||||||
|
*/
|
||||||
|
fn set_pattern_palette_colors(auto ... colors) {
|
||||||
|
builtin::std::core::set_pattern_palette_colors(colors);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Resets the current pattern palette progress back to zero.
|
||||||
|
This can be useful to force all instances of a type to have the same coloring for its members
|
||||||
|
*/
|
||||||
|
fn reset_pattern_palette() {
|
||||||
|
builtin::std::core::reset_pattern_palette();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
of ASCII characters.
|
of ASCII characters.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace std::ctype {
|
namespace auto std::ctype {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if the given character `c` is a digit between '0' and '9'
|
Checks if the given character `c` is a digit between '0' and '9'
|
||||||
@@ -85,7 +85,7 @@ namespace std::ctype {
|
|||||||
@return True if `c` is part of this range, false otherwise
|
@return True if `c` is part of this range, false otherwise
|
||||||
*/
|
*/
|
||||||
fn isprint(char c) {
|
fn isprint(char c) {
|
||||||
return c >= '0' && c <= '~';
|
return c >= ' ' && c <= '~';
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
**These functions are considered dangerous and require the user to manually permit them**
|
**These functions are considered dangerous and require the user to manually permit them**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace std::file {
|
namespace auto std::file {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A handle representing a file that has been opened
|
A handle representing a file that has been opened
|
||||||
@@ -97,7 +97,7 @@ namespace std::file {
|
|||||||
@param handle The handle of the file to flush
|
@param handle The handle of the file to flush
|
||||||
*/
|
*/
|
||||||
fn flush(Handle handle) {
|
fn flush(Handle handle) {
|
||||||
builtin::std::file::remove(handle);
|
builtin::std::file::flush(handle);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -109,4 +109,12 @@ namespace std::file {
|
|||||||
builtin::std::file::remove(handle);
|
builtin::std::file::remove(handle);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create all directories for the provided path
|
||||||
|
@param path The path for which all directories should be created
|
||||||
|
*/
|
||||||
|
fn create_directories(str path) {
|
||||||
|
builtin::std::file::create_directories(path);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
Library for doing arithmetic with fixed point numbers and converting them from/to floating point numbers.
|
Library for doing arithmetic with fixed point numbers and converting them from/to floating point numbers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace std::fxpt {
|
namespace auto std::fxpt {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A fixed point value
|
A fixed point value
|
||||||
|
|||||||
@@ -4,11 +4,39 @@
|
|||||||
The hash library contains various data hash functions
|
The hash library contains various data hash functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace std::hash {
|
namespace auto std::hash {
|
||||||
|
|
||||||
|
/**
|
||||||
|
Calculates the CRC8 hash of the bytes inside of a given pattern
|
||||||
|
@param pattern The pattern to calculate the CRC8 hash of
|
||||||
|
@param init The CRC8 init value
|
||||||
|
@param poly The CRC8 polynomial
|
||||||
|
@param xorout The CRC8 XOR-Out value
|
||||||
|
@param reflect_in Whether or not the input bytes should be reflected
|
||||||
|
@param reflect_out Whether or not the output should be reflected
|
||||||
|
@return Calculated CRC8 hash
|
||||||
|
*/
|
||||||
|
fn crc8(ref auto pattern, u8 init, u8 poly, u8 xorout, bool reflect_in, bool reflect_out) {
|
||||||
|
return builtin::std::hash::crc8(pattern, init, poly, xorout, reflect_in, reflect_out);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Calculates the CRC16 hash of the bytes inside of a given pattern
|
||||||
|
@param pattern The pattern to calculate the CRC16 hash of
|
||||||
|
@param init The CRC16 init value
|
||||||
|
@param poly The CRC16 polynomial
|
||||||
|
@param xorout The CRC16 XOR-Out value
|
||||||
|
@param reflect_in Whether or not the input bytes should be reflected
|
||||||
|
@param reflect_out Whether or not the output should be reflected
|
||||||
|
@return Calculated CRC16 hash
|
||||||
|
*/
|
||||||
|
fn crc16(ref auto pattern, u16 init, u16 poly, u16 xorout, bool reflect_in, bool reflect_out) {
|
||||||
|
return builtin::std::hash::crc16(pattern, init, poly, xorout, reflect_in, reflect_out);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Calculates the CRC32 hash of the bytes inside of a given pattern
|
Calculates the CRC32 hash of the bytes inside of a given pattern
|
||||||
@param pattern The pattern to calculate the crc32 hash of
|
@param pattern The pattern to calculate the CRC32 hash of
|
||||||
@param init The CRC32 init value
|
@param init The CRC32 init value
|
||||||
@param poly The CRC32 polynomial
|
@param poly The CRC32 polynomial
|
||||||
@param xorout The CRC32 XOR-Out value
|
@param xorout The CRC32 XOR-Out value
|
||||||
@@ -20,4 +48,18 @@ namespace std::hash {
|
|||||||
return builtin::std::hash::crc32(pattern, init, poly, xorout, reflect_in, reflect_out);
|
return builtin::std::hash::crc32(pattern, init, poly, xorout, reflect_in, reflect_out);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Calculates the CRC64 hash of the bytes inside of a given pattern
|
||||||
|
@param pattern The pattern to calculate the CRC64 hash of
|
||||||
|
@param init The CRC64 init value
|
||||||
|
@param poly The CRC64 polynomial
|
||||||
|
@param xorout The CRC64 XOR-Out value
|
||||||
|
@param reflect_in Whether or not the input bytes should be reflected
|
||||||
|
@param reflect_out Whether or not the output should be reflected
|
||||||
|
@return Calculated CRC64 hash
|
||||||
|
*/
|
||||||
|
fn crc64(ref auto pattern, u64 init, u64 poly, u64 xorout, bool reflect_in, bool reflect_out) {
|
||||||
|
return builtin::std::hash::crc64(pattern, init, poly, xorout, reflect_in, reflect_out);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -4,26 +4,26 @@
|
|||||||
The IO library allows formatting strings and outputting text to the console
|
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
|
Formats the given arguments using the format string and prints the result to the console
|
||||||
This function uses the C++20 `std::format` or libfmt's `fmt::format` syntax.
|
This function uses the C++20 `std::format` or libfmt's `fmt::format` syntax.
|
||||||
@param fmt Format string
|
@param fmt Format string or any other value that can be converted to a string
|
||||||
@param args Values to use in the formatting
|
@param args Values to use in the formatting
|
||||||
*/
|
*/
|
||||||
fn print(str fmt, auto ... args) {
|
fn print(auto fmt, auto ... args) {
|
||||||
builtin::std::print(fmt, args);
|
builtin::std::print(fmt, args);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Formats the given arguments using the format string and returns the result as a string
|
Formats the given arguments using the format string and returns the result as a string
|
||||||
This function uses the C++20 `std::format` or libfmt's `fmt::format` syntax.
|
This function uses the C++20 `std::format` or libfmt's `fmt::format` syntax.
|
||||||
@param fmt Format string
|
@param fmt Format string or any other value that can be converted to a string
|
||||||
@param args Values to use in the formatting
|
@param args Values to use in the formatting
|
||||||
@return The formatted string
|
@return The formatted string
|
||||||
*/
|
*/
|
||||||
fn format(str fmt, auto ... args) {
|
fn format(auto fmt, auto ... args) {
|
||||||
return builtin::std::format(fmt, args);
|
return builtin::std::format(fmt, args);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
Library to calculate the minimum and maximum values that fit into a given data type
|
Library to calculate the minimum and maximum values that fit into a given data type
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace std::limits {
|
namespace auto std::limits {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the minimum value that can be stored in a `u8`.
|
Returns the minimum value that can be stored in a `u8`.
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <std/mem.pat>
|
import std.mem;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Library containing more advanced mathematical operations.
|
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
|
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`.
|
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`
|
@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`.
|
Calculates the hyperbolic sine of `value`.
|
||||||
@@ -327,9 +328,9 @@ namespace std::math {
|
|||||||
@param start Start address
|
@param start Start address
|
||||||
@param end End address
|
@param end End address
|
||||||
@param valueSize Size of each value in bytes
|
@param valueSize Size of each value in bytes
|
||||||
@param section Section to use
|
@param [section] Section to use
|
||||||
@param operation Operation to use
|
@param [operation] Operation to use. Defaults to addition
|
||||||
@param endian Endianness to use
|
@param [endian] Endianness to use. Defaults to native
|
||||||
@return Sum of all values in the specified memory range
|
@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) {
|
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) {
|
||||||
|
|||||||
@@ -4,35 +4,17 @@
|
|||||||
Library for doing raw memory accesses and other low-level operations.
|
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
|
A Handle for a custom Section
|
||||||
*/
|
*/
|
||||||
using Section = u128;
|
using Section = u128;
|
||||||
|
const u64 SectionMain = 0;
|
||||||
|
const u64 SectionCurrent = 0xFFFF'FFFF'FFFF'FFFF;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The Endianess of a value
|
The endianness of a value
|
||||||
*/
|
*/
|
||||||
enum Endian : u8 {
|
enum Endian : u8 {
|
||||||
Native = 0,
|
Native = 0,
|
||||||
@@ -49,6 +31,15 @@ namespace std::mem {
|
|||||||
return $ >= (std::mem::base_address() + std::mem::size());
|
return $ >= (std::mem::base_address() + std::mem::size());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Function that returns true if the cursor position is at or beyond the given address
|
||||||
|
@param address The address to compare against
|
||||||
|
@return True if the cursor is at or beyond the given address
|
||||||
|
*/
|
||||||
|
fn reached(u128 address) {
|
||||||
|
return $ >= address;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Aligns the given value to the given alignment
|
Aligns the given value to the given alignment
|
||||||
@param alignment The alignment to align to
|
@param alignment The alignment to align to
|
||||||
@@ -63,33 +54,34 @@ namespace std::mem {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Gets the base address of the memory
|
Gets the base address of the data
|
||||||
@return The base address of the memory
|
@return The base address of the memory
|
||||||
*/
|
*/
|
||||||
fn base_address() {
|
fn base_address(u64 section = SectionCurrent) {
|
||||||
return builtin::std::mem::base_address();
|
return builtin::std::mem::base_address(section);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Gets the size of the memory
|
Gets the size of the data
|
||||||
@return The size of the memory
|
@return The size of the memory
|
||||||
*/
|
*/
|
||||||
fn size() {
|
fn size(u64 section = SectionCurrent) {
|
||||||
return builtin::std::mem::size();
|
return builtin::std::mem::size(section);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Finds a sequence of bytes in the memory
|
Finds a sequence of bytes in the data
|
||||||
@param occurrence_index The index of the occurrence to find
|
@param occurrence_index The index of the occurrence to find
|
||||||
@param bytes The bytes to find
|
@param bytes The bytes to find
|
||||||
@return The address of the sequence
|
@return The address of the sequence
|
||||||
*/
|
*/
|
||||||
fn find_sequence(u128 occurrence_index, auto ... bytes) {
|
fn find_sequence(u128 occurrence_index, auto ... bytes) {
|
||||||
return builtin::std::mem::find_sequence_in_range(occurrence_index, builtin::std::mem::base_address(), builtin::std::mem::size(), bytes);
|
const u128 address = std::mem::base_address();
|
||||||
|
return builtin::std::mem::find_sequence_in_range(occurrence_index, address, address + std::mem::size(), bytes);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Finds a sequence of bytes in a specific region of the memory
|
Finds a sequence of bytes in a specific region of the data
|
||||||
@param occurrence_index The index of the occurrence to find
|
@param occurrence_index The index of the occurrence to find
|
||||||
@param offsetFrom The offset from which to start searching
|
@param offsetFrom The offset from which to start searching
|
||||||
@param offsetTo The offset to which to search
|
@param offsetTo The offset to which to search
|
||||||
@@ -100,26 +92,50 @@ namespace std::mem {
|
|||||||
return builtin::std::mem::find_sequence_in_range(occurrence_index, offsetFrom, offsetTo, bytes);
|
return builtin::std::mem::find_sequence_in_range(occurrence_index, offsetFrom, offsetTo, bytes);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Finds a string in the data
|
||||||
|
@param occurrence_index The index of the occurrence to find
|
||||||
|
@param string The string to find
|
||||||
|
@return The address of the sequence
|
||||||
|
*/
|
||||||
|
fn find_string(u128 occurrence_index, str string) {
|
||||||
|
const u128 address = std::mem::base_address();
|
||||||
|
return builtin::std::mem::find_string_in_range(occurrence_index, address, address + std::mem::size(), string);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Finds a string in a specific region of the data
|
||||||
|
@param occurrence_index The index of the occurrence to find
|
||||||
|
@param offsetFrom The offset from which to start searching
|
||||||
|
@param offsetTo The offset to which to search
|
||||||
|
@param string The string to find
|
||||||
|
@return The address of the sequence
|
||||||
|
*/
|
||||||
|
fn find_string_in_range(u128 occurrence_index, u128 offsetFrom, u128 offsetTo, str string) {
|
||||||
|
return builtin::std::mem::find_string_in_range(occurrence_index, offsetFrom, offsetTo, string);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Reads a unsigned value from the memory
|
Reads a unsigned value from the memory
|
||||||
@param address The address to read from
|
@param address The address to read from
|
||||||
@param size The size of the value to read
|
@param size The size of the value to read
|
||||||
@param endian The endianess of the value to read
|
@param [endian] The endianness of the value to read. Defaults to native
|
||||||
@return The value read
|
@return The value read
|
||||||
*/
|
*/
|
||||||
fn read_unsigned(u128 address, u8 size, Endian endian = Endian::Native) {
|
fn read_unsigned(u128 address, u8 size, Endian endian = Endian::Native, Section section = SectionCurrent) {
|
||||||
return builtin::std::mem::read_unsigned(address, size, u32(endian));
|
return builtin::std::mem::read_unsigned(address, size, u32(endian), section);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Reads a signed value from the memory
|
Reads a signed value from the memory
|
||||||
@param address The address to read from
|
@param address The address to read from
|
||||||
@param size The size of the value to read
|
@param size The size of the value to read
|
||||||
@param endian The endianess of the value to read
|
@param [endian] The endianness of the value to read. Defaults to native
|
||||||
@return The value read
|
@return The value read
|
||||||
*/
|
*/
|
||||||
fn read_signed(u128 address, u8 size, Endian endian = Endian::Native) {
|
fn read_signed(u128 address, u8 size, Endian endian = Endian::Native, Section section = SectionCurrent) {
|
||||||
return builtin::std::mem::read_signed(address, size, u32(endian));
|
return builtin::std::mem::read_signed(address, size, u32(endian), section);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -128,16 +144,8 @@ namespace std::mem {
|
|||||||
@param size The size of the value to read
|
@param size The size of the value to read
|
||||||
@return The value read
|
@return The value read
|
||||||
*/
|
*/
|
||||||
fn read_string(u128 address, u8 size) {
|
fn read_string(u128 address, u128 size, Section section = SectionCurrent) {
|
||||||
return builtin::std::mem::read_string(address, size);
|
return builtin::std::mem::read_string(address, size, section);
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Gets the current bit offset within the current byte that a bitfield will read.
|
|
||||||
*/
|
|
||||||
fn current_bit_offset() {
|
|
||||||
return builtin::std::mem::current_bit_offset();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -180,6 +188,15 @@ namespace std::mem {
|
|||||||
return builtin::std::mem::get_section_size(section);
|
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
|
Copies a range of bytes from one section into another
|
||||||
@param from_section The section to copy from
|
@param from_section The section to copy from
|
||||||
@@ -202,14 +219,12 @@ namespace std::mem {
|
|||||||
builtin::std::mem::copy_value_to_section(value, to_section, to_address);
|
builtin::std::mem::copy_value_to_section(value, to_section, to_address);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Searches for a sequence of bytes and places the given type at that address
|
Returns the current bit offset when inside of a bitfield.
|
||||||
@tparam Magic The magic sequence to search for
|
@return The current bit offset between 0 and 7
|
||||||
@tparam T The type to place at the address
|
|
||||||
*/
|
*/
|
||||||
struct MagicSearch<auto Magic, T> {
|
fn current_bit_offset() {
|
||||||
std::mem::impl::MagicSearchImpl<Magic, T> impl[while(!std::mem::eof())] [[inline]];
|
return builtin::std::mem::current_bit_offset();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -218,8 +233,8 @@ namespace std::mem {
|
|||||||
@tparam To The type to reinterpret to
|
@tparam To The type to reinterpret to
|
||||||
*/
|
*/
|
||||||
union Reinterpreter<From, To> {
|
union Reinterpreter<From, To> {
|
||||||
From from;
|
From from_value;
|
||||||
To to;
|
To to_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -245,6 +260,28 @@ namespace std::mem {
|
|||||||
return "";
|
return "";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MagicSearchImpl<auto Magic, T> {
|
||||||
|
s128 address = builtin::std::mem::find_string_in_range(0, $, std::mem::size(), Magic);
|
||||||
|
if (address < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
$ = address;
|
||||||
|
try {
|
||||||
|
T data [[inline]];
|
||||||
|
} catch {
|
||||||
|
T data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Searches for a sequence of bytes and places the given type at that address
|
||||||
|
@tparam Magic The magic sequence to search for
|
||||||
|
@tparam T The type to place at the address
|
||||||
|
*/
|
||||||
|
struct MagicSearch<auto Magic, T> {
|
||||||
|
std::mem::impl::MagicSearchImpl<Magic, T> impl[while(!std::mem::eof())] [[inline]];
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <std/mem.pat>
|
import std.mem;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
The Pointer library contains helper functions to deal with pointer types.
|
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
|
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
|
Use the offset of the current pointer as start address
|
||||||
@@ -47,7 +47,7 @@ namespace std::ptr {
|
|||||||
Example:
|
Example:
|
||||||
A struct field called `p_myInfo` which is a nullable 64-bit pointer to an
|
A struct field called `p_myInfo` which is a nullable 64-bit pointer to an
|
||||||
element of type `MyInfoTy` would be written as:
|
element of type `MyInfoTy` would be written as:
|
||||||
```
|
```rust
|
||||||
struct MyStruct {
|
struct MyStruct {
|
||||||
std::ptr::NullablePtr<MyInfoTy, u64> p_myInfo;
|
std::ptr::NullablePtr<MyInfoTy, u64> p_myInfo;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <std/limits.pat>
|
import std.limits;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Library to generate random numbers. Supports various different distribution types.
|
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
|
Represents the type of distribution to use to generate a random number
|
||||||
@@ -61,8 +61,8 @@ namespace std::random {
|
|||||||
> - `Poisson(mean) -> i128`
|
> - `Poisson(mean) -> i128`
|
||||||
|
|
||||||
@param distribution Distribution to use
|
@param distribution Distribution to use
|
||||||
@param param1 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.
|
@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) {
|
fn generate_using(Distribution distribution, auto param1 = 0, auto param2 = 0) {
|
||||||
return builtin::std::random::generate(u32(distribution), param1, param2);
|
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`
|
Generates a uniformly distributed random number between `min` and `max`
|
||||||
@param min Minimum number
|
@param [min] Minimum number. Defaults to 0
|
||||||
@param max Maximum number
|
@param [max] Maximum number. Defaults to `u64_max`
|
||||||
*/
|
*/
|
||||||
fn generate(u64 min = std::limits::u64_min(), u64 max = std::limits::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);
|
return std::random::generate_using(Distribution::Uniform, min, max);
|
||||||
|
|||||||
@@ -1,22 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <std/io.pat>
|
import std.io;
|
||||||
|
import std.mem;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Libray to interact with strings.
|
Library to interact with strings.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace std::string {
|
namespace auto std::string {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Base type for sized strings. Represents a string with its size preceeding it.
|
Base type for sized strings. Represents a string with its size preceding it.
|
||||||
@tparam SizeType The type of the size field.
|
@tparam SizeType The type of the size field.
|
||||||
@tparam DataType The type of the characters.
|
@tparam DataType The type of the characters.
|
||||||
*/
|
*/
|
||||||
struct SizedStringBase<SizeType, DataType> {
|
struct SizedStringBase<SizeType, DataType> {
|
||||||
SizeType size;
|
SizeType size;
|
||||||
DataType data[size];
|
DataType data[size];
|
||||||
} [[sealed, format("std::string::impl::format_sized_string"), transform("std::string::impl::format_sized_string")]];
|
} [[sealed, format("std::string::impl::format_string"), transform("std::string::impl::format_string")]];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A ASCII string with a prefixed size.
|
A ASCII string with a prefixed size.
|
||||||
@@ -30,9 +31,28 @@ namespace std::string {
|
|||||||
*/
|
*/
|
||||||
using SizedString16<SizeType> = SizedStringBase<SizeType, char16>;
|
using SizedString16<SizeType> = SizedStringBase<SizeType, char16>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Base type for null-terminated strings. Represents a string with its size determined by the first 0x00 byte found.
|
||||||
|
@tparam DataType The type of the characters.
|
||||||
|
*/
|
||||||
|
struct NullStringBase<DataType> {
|
||||||
|
DataType data[while(std::mem::read_unsigned($, sizeof(DataType)) != 0x00)];
|
||||||
|
DataType null_terminator;
|
||||||
|
} [[sealed, format("std::string::impl::format_string"), transform("std::string::impl::format_string")]];
|
||||||
|
|
||||||
|
/**
|
||||||
|
A null-terminated ASCII string.
|
||||||
|
*/
|
||||||
|
using NullString = NullStringBase<char>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
A null-terminated UTF-16 string.
|
||||||
|
*/
|
||||||
|
using NullString16 = NullStringBase<char16>;
|
||||||
|
|
||||||
namespace impl {
|
namespace impl {
|
||||||
|
|
||||||
fn format_sized_string(ref auto string) {
|
fn format_string(ref auto string) {
|
||||||
return string.data;
|
return string.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -105,6 +125,8 @@ namespace std::string {
|
|||||||
@return True if the string starts with the substring, false otherwise.
|
@return True if the string starts with the substring, false otherwise.
|
||||||
*/
|
*/
|
||||||
fn starts_with(str string, str part) {
|
fn starts_with(str string, str part) {
|
||||||
|
if (std::string::length(string) < std::string::length(part))
|
||||||
|
return false;
|
||||||
return std::string::substr(string, 0, std::string::length(part)) == part;
|
return std::string::substr(string, 0, std::string::length(part)) == part;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -115,6 +137,8 @@ namespace std::string {
|
|||||||
@return True if the string ends with the substring, false otherwise.
|
@return True if the string ends with the substring, false otherwise.
|
||||||
*/
|
*/
|
||||||
fn ends_with(str string, str part) {
|
fn ends_with(str string, str part) {
|
||||||
|
if (std::string::length(string) < std::string::length(part))
|
||||||
|
return false;
|
||||||
return std::string::substr(string, std::string::length(string) - std::string::length(part), std::string::length(part)) == part;
|
return std::string::substr(string, std::string::length(string) - std::string::length(part), std::string::length(part)) == part;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -210,30 +234,26 @@ namespace std::string {
|
|||||||
@return The string with the replacements.
|
@return The string with the replacements.
|
||||||
*/
|
*/
|
||||||
fn replace(str string, str pattern, str replace) {
|
fn replace(str string, str pattern, str replace) {
|
||||||
u32 string_len, pattern_len, replace_len;
|
s32 string_len = std::string::length(string);
|
||||||
string_len = std::string::length(string);
|
s32 pattern_len = std::string::length(pattern);
|
||||||
pattern_len = std::string::length(pattern);
|
|
||||||
replace_len = std::string::length(replace);
|
|
||||||
|
|
||||||
if (pattern_len > string_len)
|
if (pattern_len > string_len || pattern_len * string_len == 0 )
|
||||||
return string;
|
return string;
|
||||||
|
|
||||||
str result;
|
str result;
|
||||||
u32 i;
|
s32 string_index;
|
||||||
while (i <= (string_len - pattern_len)) {
|
s32 remaining_len = string_len;
|
||||||
|
while (pattern_len <= remaining_len) {
|
||||||
if (std::string::substr(string, i, pattern_len) == pattern) {
|
if (std::string::substr(string, string_index, pattern_len) == pattern) {
|
||||||
result = result + replace;
|
result += replace;
|
||||||
i = i + pattern_len;
|
string_index += pattern_len;
|
||||||
} else {
|
} else {
|
||||||
result = result + std::string::at(string, i);
|
result += std::string::at(string, string_index);
|
||||||
i = i + 1;
|
string_index += 1;
|
||||||
}
|
}
|
||||||
|
remaining_len = string_len - string_index;
|
||||||
}
|
}
|
||||||
result = result + std::string::substr(string,string_len-pattern_len+1,pattern_len);
|
result += std::string::substr(string, string_index, remaining_len );
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <std/io.pat>
|
import std.io;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Basic helper functions
|
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
|
Asserts that a given value is true. If it's not, abort evaluation and print the given message to the console
|
||||||
@param conditoon The condition that is required to be true
|
@param condition The condition that is required to be true
|
||||||
@param message The message to print in case the assertion doesn't hold
|
@param message The message to print in case the assertion doesn't hold
|
||||||
*/
|
*/
|
||||||
fn assert(bool condition, str message) {
|
fn assert(bool condition, str message) {
|
||||||
@@ -21,7 +21,7 @@ namespace std {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
Asserts that a given value is true. If it's not, print the given message to the console as a warning
|
Asserts that a given value is true. If it's not, print the given message to the console as a warning
|
||||||
@param conditoon The condition that is required to be true
|
@param condition The condition that is required to be true
|
||||||
@param message The message to print in case the assertion doesn't hold
|
@param message The message to print in case the assertion doesn't hold
|
||||||
*/
|
*/
|
||||||
fn assert_warn(bool condition, str message) {
|
fn assert_warn(bool condition, str message) {
|
||||||
@@ -49,4 +49,11 @@ namespace std {
|
|||||||
return builtin::std::sizeof_pack(pack);
|
return builtin::std::sizeof_pack(pack);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Throws an error notifying the developer that the current code path is not implemented currently.
|
||||||
|
*/
|
||||||
|
fn unimplemented() {
|
||||||
|
std::error("Unimplemented code path reached!");
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <std/io.pat>
|
import std.io;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Library to handle time and date related operations.
|
Library to handle time and date related operations.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace std::time {
|
namespace auto std::time {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A structured representation of a time and date.
|
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.
|
A type to represent a time in seconds since the epoch.
|
||||||
*/
|
*/
|
||||||
using EpochTime = u128;
|
using EpochTime = u32;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A type to represent a time zone.
|
A type to represent a time zone.
|
||||||
@@ -91,7 +91,7 @@ namespace std::time {
|
|||||||
@return The local time.
|
@return The local time.
|
||||||
*/
|
*/
|
||||||
fn to_local(EpochTime epoch_time) {
|
fn to_local(EpochTime epoch_time) {
|
||||||
TimeConverter converter;
|
le TimeConverter converter;
|
||||||
|
|
||||||
converter.value = builtin::std::time::to_local(epoch_time);
|
converter.value = builtin::std::time::to_local(epoch_time);
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ namespace std::time {
|
|||||||
@return The UTC time.
|
@return The UTC time.
|
||||||
*/
|
*/
|
||||||
fn to_utc(EpochTime epoch_time) {
|
fn to_utc(EpochTime epoch_time) {
|
||||||
TimeConverter converter;
|
le TimeConverter converter;
|
||||||
|
|
||||||
converter.value = builtin::std::time::to_utc(epoch_time);
|
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.
|
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.
|
@return The current time in the specified time zone.
|
||||||
*/
|
*/
|
||||||
fn now(TimeZone time_zone = TimeZone::Local) {
|
fn now(TimeZone time_zone = TimeZone::Local) {
|
||||||
TimeConverter converter;
|
le TimeConverter converter;
|
||||||
|
|
||||||
if (time_zone == TimeZone::Local)
|
if (time_zone == TimeZone::Local)
|
||||||
converter.value = builtin::std::time::to_local(std::time::epoch());
|
converter.value = builtin::std::time::to_local(std::time::epoch());
|
||||||
@@ -135,7 +135,7 @@ namespace std::time {
|
|||||||
@return The DOS date.
|
@return The DOS date.
|
||||||
*/
|
*/
|
||||||
fn to_dos_date(u16 value) {
|
fn to_dos_date(u16 value) {
|
||||||
impl::DOSDateConverter converter;
|
le impl::DOSDateConverter converter;
|
||||||
|
|
||||||
converter.value = value;
|
converter.value = value;
|
||||||
|
|
||||||
@@ -148,21 +148,30 @@ namespace std::time {
|
|||||||
@return The DOS time.
|
@return The DOS time.
|
||||||
*/
|
*/
|
||||||
fn to_dos_time(u16 value) {
|
fn to_dos_time(u16 value) {
|
||||||
impl::DOSTimeConverter converter;
|
le impl::DOSTimeConverter converter;
|
||||||
|
|
||||||
converter.value = value;
|
converter.value = value;
|
||||||
|
|
||||||
return converter.time;
|
return converter.time;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Converts a FILETIME to unix time.
|
||||||
|
@param value The value to convert.
|
||||||
|
@return Timestamp formatted as unix time.
|
||||||
|
*/
|
||||||
|
fn filetime_to_unix(u64 value) {
|
||||||
|
return value / 10000000 - 11644473600;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Formats a time according to the specified format string.
|
Formats a time according to the specified format string.
|
||||||
@param time The time to format.
|
@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.
|
@return The formatted time.
|
||||||
*/
|
*/
|
||||||
fn format(Time time, str format_string = "%c") {
|
fn format(Time time, str format_string = "%c") {
|
||||||
TimeConverter converter;
|
le TimeConverter converter;
|
||||||
converter.time = time;
|
converter.time = time;
|
||||||
|
|
||||||
return builtin::std::time::format(format_string, converter.value);
|
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.
|
Formats a DOS date according to the specified format string.
|
||||||
@param date The DOS date to format.
|
@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.
|
@return The formatted DOS date.
|
||||||
*/
|
*/
|
||||||
fn format_dos_date(DOSDate date, str format_string = "{}/{}/{}") {
|
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.
|
Formats a DOS time according to the specified format string.
|
||||||
@param time The DOS time to format.
|
@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.
|
@return The formatted DOS time.
|
||||||
*/
|
*/
|
||||||
fn format_dos_time(DOSTime time, str format_string = "{:02}:{:02}:{:02}") {
|
fn format_dos_time(DOSTime time, str format_string = "{:02}:{:02}:{:02}") {
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <std/io.pat>
|
import std.io;
|
||||||
#include <std/math.pat>
|
import std.math;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Types used to change the base of the displayed integer value.
|
Types used to change the base of the displayed integer value.
|
||||||
Used like `type::Hex<u32> hexNumber;`, `type::Oct<u16> octalNumber;`
|
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.
|
Integer type representing a Hexadecimal value. Displays its value in hexadecimal format.
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
#include <std/io.pat>
|
import std.io;
|
||||||
#include <std/string.pat>
|
import std.string;
|
||||||
#include <std/mem.pat>
|
import std.mem;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Type representing a Base64 encoded string
|
Type representing a Base64 encoded string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace type {
|
namespace auto type {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Type representing a Base64 encoded string
|
Type representing a Base64 encoded string
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <std/io.pat>
|
import std.io;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Type to decode a BCD (Binary Coded Decimal) number
|
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
|
Decodes a BCD value where one byte represents a single digit
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <std/io.pat>
|
import std.io;
|
||||||
|
import std.core;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Types to display single bytes using various different representations
|
Types to display single bytes using various different representations
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace type {
|
namespace auto type {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Type visualizing the value of each individual bit
|
Type visualizing the value of each individual bit
|
||||||
@@ -20,7 +21,7 @@ namespace type {
|
|||||||
bit5 : 1;
|
bit5 : 1;
|
||||||
bit6 : 1;
|
bit6 : 1;
|
||||||
bit7 : 1;
|
bit7 : 1;
|
||||||
} [[format("type::impl::format_bits"), right_to_left]];
|
} [[format("type::impl::format_bits"), bitfield_order(std::core::BitfieldOrder::LeastToMostSignificant, 8)]];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Type visualizing the value of the two nibbles
|
Type visualizing the value of the two nibbles
|
||||||
@@ -31,7 +32,7 @@ namespace type {
|
|||||||
} [[format("type::impl::format_nibbles")]];
|
} [[format("type::impl::format_nibbles")]];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Type representing a single Byte. Decodes the byte as it's hexadeicmal value, individual bits and nibbles
|
Type representing a single Byte. Decodes the byte as it's hexadecimal value, individual bits and nibbles
|
||||||
*/
|
*/
|
||||||
union Byte {
|
union Byte {
|
||||||
u8 value;
|
u8 value;
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <std/io.pat>
|
import std.io;
|
||||||
#include <std/core.pat>
|
import std.core;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Types representing RGB or RGBA colors. The decoded color will be displayed in their color field
|
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
|
Type representing a generic RGBA color with a variable number of bits for each color
|
||||||
@@ -21,7 +21,7 @@ namespace type {
|
|||||||
g : G;
|
g : G;
|
||||||
b : B;
|
b : B;
|
||||||
if (A > 0) a : A;
|
if (A > 0) a : A;
|
||||||
} [[sealed, format("type::impl::format_color"), color(std::format("{0:02X}{1:02X}{2:02X}FF", r, g, b))]];
|
} [[sealed, format("type::impl::format_color"), color(std::format("{0:02X}{1:02X}{2:02X}", r, g, b))]];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Type representing a generic RGB color with a variable number of bits for each color
|
Type representing a generic RGB color with a variable number of bits for each color
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <std/io.pat>
|
import std.io;
|
||||||
#include <std/math.pat>
|
import std.math;
|
||||||
#include <std/mem.pat>
|
import std.mem;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Type representing a 16 bit half precision floating point number
|
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
|
Type representing a 16 bit half precision floating point number
|
||||||
@@ -50,9 +50,9 @@ namespace type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::mem::Reinterpreter<u32, float> converter;
|
std::mem::Reinterpreter<u32, float> converter;
|
||||||
converter.from = result;
|
converter.from_value = result;
|
||||||
|
|
||||||
return std::format("{}", converter.to);
|
return std::format("{}", converter.to_value);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
42
includes/type/fmt.pat
Normal file
42
includes/type/fmt.pat
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
import std.io;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Type that allows specifying its format value using a format string.
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
The following code reads a u32 from the data and formats it as an upper case hexadecimal value with
|
||||||
|
a minimum of 8 digits which is prefixed by 0x.
|
||||||
|
|
||||||
|
The format string is the same as passed to `std::format()` and follows the libfmt specification.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
type::Formatted<u32, "0x{:08X}"> hex_formatted_integer @ 0x00;
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace auto type {
|
||||||
|
|
||||||
|
/**
|
||||||
|
Arbitrarily formatted type
|
||||||
|
@tparam T Type to format
|
||||||
|
@tparam FormatString libfmt format string to format the value
|
||||||
|
*/
|
||||||
|
struct Formatted<T, auto FormatString> {
|
||||||
|
T value;
|
||||||
|
} [[sealed, format("type::impl::format_formatted"), transform("type::impl::transform_formatted")]];
|
||||||
|
|
||||||
|
namespace impl {
|
||||||
|
|
||||||
|
fn format_formatted(ref auto formatted) {
|
||||||
|
return std::format(formatted.FormatString, formatted.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn transform_formatted(ref auto formatted) {
|
||||||
|
return formatted.value;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#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
|
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
|
Type representing a GUID value
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <std/io.pat>
|
import std.io;
|
||||||
#include <std/string.pat>
|
import std.string;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Types used to decode IP addresses
|
Types used to decode IP addresses
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace type {
|
namespace auto type {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A 4 byte IPv4 Address as described in RFC 791
|
A 4 byte IPv4 Address as described in RFC 791
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <std/io.pat>
|
import std.io;
|
||||||
#include <std/mem.pat>
|
import std.mem;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Types used to decode Little Endian Base 128 numbers used to store large numbers as space efficiently as possible
|
Types used to decode Little Endian Base 128 numbers used to store large numbers as space efficiently as possible
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace type {
|
namespace auto type {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Base LEB128 type. Use `uLEB128` and `sLEB128` instead.
|
Base LEB128 type. Use `uLEB128` and `sLEB128` instead.
|
||||||
@@ -43,7 +43,7 @@ namespace type {
|
|||||||
|
|
||||||
fn transform_sleb128_array(ref auto array) {
|
fn transform_sleb128_array(ref auto array) {
|
||||||
s128 res = type::impl::transform_uleb128_array(array);
|
s128 res = type::impl::transform_uleb128_array(array);
|
||||||
if (res & 0x40 != 0) {
|
if (res & 1 << ((sizeof(array) / sizeof(u8)) * 7 - 1) != 0) {
|
||||||
res |= ~0 << (sizeof(array) / sizeof(u8)) * 7;
|
res |= ~0 << (sizeof(array) / sizeof(u8)) * 7;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <std/io.pat>
|
import std.io;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Types used to decode MAC Addresses
|
Types used to decode MAC Addresses
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace type {
|
namespace auto type {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A MAC Address as used in the Internet Protocol
|
A MAC Address as used in the Internet Protocol
|
||||||
|
|||||||
@@ -1,13 +1,33 @@
|
|||||||
#include <std/string.pat>
|
import std.string;
|
||||||
#include <std/sys.pat>
|
import std.sys;
|
||||||
#include <std/io.pat>
|
import std.io;
|
||||||
#include <std/ctype.pat>
|
import std.ctype;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Types used to parse and enforce specific magic numbers
|
Types used to parse and enforce specific magic numbers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace type {
|
namespace auto type
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
Escapes all bytes in a string to only contain printable characters. All non-printable bytes will be transformed to sequences in the \xFF form
|
||||||
|
@param value Byte array to escape
|
||||||
|
@return Escaped string
|
||||||
|
*/
|
||||||
|
fn escape_bytes(ref auto value) {
|
||||||
|
str result;
|
||||||
|
for (u32 i = 0, i < sizeof(value), i += 1)
|
||||||
|
{
|
||||||
|
char c = value[i];
|
||||||
|
|
||||||
|
if (std::ctype::isprint(c))
|
||||||
|
result += c;
|
||||||
|
else
|
||||||
|
result += std::format("\\x{:02X}", u8(c));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A Magic number. Throws an error if the magic number does not match the expected value
|
A Magic number. Throws an error if the magic number does not match the expected value
|
||||||
@@ -15,24 +35,11 @@ namespace type {
|
|||||||
*/
|
*/
|
||||||
struct Magic<auto ExpectedValue> {
|
struct Magic<auto ExpectedValue> {
|
||||||
char value[std::string::length(ExpectedValue)];
|
char value[std::string::length(ExpectedValue)];
|
||||||
std::assert(value == ExpectedValue, std::format("Invalid magic value! Expected \"{}\", got \"{}\".", ExpectedValue, value));
|
std::assert(value == ExpectedValue, std::format("Invalid magic value! Expected \"{}\", got \"{}\" at position 0x{:X}", type::escape_bytes(ExpectedValue), type::escape_bytes(value), $ - std::string::length(ExpectedValue)));
|
||||||
} [[sealed, format("type::impl::format_magic")]];
|
} [[sealed, format("type::impl::format_magic")]];
|
||||||
|
|
||||||
namespace impl {
|
namespace impl {
|
||||||
|
|
||||||
fn format_magic(ref auto magic) {
|
fn format_magic(ref auto magic) {
|
||||||
str result;
|
return std::format("\"{}\"", type::escape_bytes(magic.value));
|
||||||
for (u32 i = 0, i < sizeof(magic.value), i += 1) {
|
|
||||||
char c = magic.value[i];
|
|
||||||
|
|
||||||
if (std::ctype::isprint(c))
|
|
||||||
result += c;
|
|
||||||
else
|
|
||||||
result += std::format("\\x{:02X}", u8(c));
|
|
||||||
}
|
|
||||||
return std::format("\"{}\"", result);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
#include <std/mem.pat>
|
import std.mem;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Types dealing with various kinds of resource paths
|
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
|
Type representing a single path segment. Use the `Path` type instead of using this on its own
|
||||||
@tparam Delimeter The delimeter sequence used to separate two path segments
|
@tparam Delimiter The delimiter sequence used to separate two path segments
|
||||||
*/
|
*/
|
||||||
struct PathSegment<auto Delimeter> {
|
struct PathSegment<auto Delimiter> {
|
||||||
char string[while(std::mem::read_string($, std::string::length(Delimeter)) != Delimeter && std::mem::read_unsigned($, 1) != 0x00)];
|
char string[while(std::mem::read_string($, std::string::length(Delimiter)) != Delimiter && std::mem::read_unsigned($, 1) != 0x00)];
|
||||||
char separator [[hidden]];
|
char separator [[hidden]];
|
||||||
|
|
||||||
if (separator == 0x00) {
|
if (separator == 0x00) {
|
||||||
@@ -21,20 +21,20 @@ namespace type {
|
|||||||
} [[sealed, format("type::impl::format_path_segment")]];
|
} [[sealed, format("type::impl::format_path_segment")]];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A generic type representing a path with an arbitrary delimeter
|
A generic type representing a path with an arbitrary delimiter
|
||||||
@tparam Delimeter The delimeter sequence used to separate two path segments
|
@tparam Delimiter The delimiter sequence used to separate two path segments
|
||||||
*/
|
*/
|
||||||
struct Path<auto Delimeter> {
|
struct Path<auto Delimiter> {
|
||||||
PathSegment<Delimeter> segments[while(true)];
|
PathSegment<Delimiter> segments[while(true)];
|
||||||
} [[format("type::impl::format_path")]];
|
} [[format("type::impl::format_path")]];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A type representing a Unix path using a '/' forwardslash as delimeter
|
A type representing a Unix path using a '/' forward slash as delimiter
|
||||||
*/
|
*/
|
||||||
using UnixPath = Path<"/">;
|
using UnixPath = Path<"/">;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A type representing a DOS path using a '\' backslash as delimeter
|
A type representing a DOS path using a '\\' backslash as delimiter
|
||||||
*/
|
*/
|
||||||
using DOSPath = Path<"\\">;
|
using DOSPath = Path<"\\">;
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
#include <std/io.pat>
|
import std.io;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Types used to pretty print size values
|
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)
|
A generic size type which displays its value in Bytes (or kiB, MiB, GiB, TiB, PiB, EiB if larger)
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <std/io.pat>
|
import std.io;
|
||||||
#include <std/time.pat>
|
import std.time;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Types used to decode various different time formats
|
Types used to decode various different time formats
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace type {
|
namespace auto type {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A 32 bit Unix time value
|
A 32 bit Unix time value
|
||||||
@@ -34,6 +34,11 @@ namespace type {
|
|||||||
*/
|
*/
|
||||||
using DOSTime = u16 [[format("type::impl::format_dostime")]];
|
using DOSTime = u16 [[format("type::impl::format_dostime")]];
|
||||||
|
|
||||||
|
/**
|
||||||
|
A 64bit FILETIME value
|
||||||
|
*/
|
||||||
|
using FILETIME = u64 [[format("type::impl::format_filetime_as_unix")]];
|
||||||
|
|
||||||
namespace impl {
|
namespace impl {
|
||||||
|
|
||||||
fn format_time_t(u128 value) {
|
fn format_time_t(u128 value) {
|
||||||
@@ -48,6 +53,10 @@ namespace type {
|
|||||||
return std::time::format_dos_time(std::time::to_dos_time(value));
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Explicitly don't add these types to the `type` namespace for usability
|
// Explicitly don't add these types to the `type` namespace for usability
|
||||||
// namespace type {
|
// namespace auto type {
|
||||||
|
|
||||||
// using char = s8;
|
// using char = s8;
|
||||||
using byte = s8;
|
using byte = s8;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Explicitly don't add these types to the `type` namespace for usability
|
// Explicitly don't add these types to the `type` namespace for usability
|
||||||
// namespace type {
|
// namespace auto type {
|
||||||
|
|
||||||
using uint8_t = u8;
|
using uint8_t = u8;
|
||||||
using uint16_t = u16;
|
using uint16_t = u16;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Explicitly don't add these types to the `type` namespace for usability
|
// Explicitly don't add these types to the `type` namespace for usability
|
||||||
// namespace type {
|
// namespace auto type {
|
||||||
|
|
||||||
using le16 = le u16;
|
using le16 = le u16;
|
||||||
using be16 = be u16;
|
using be16 = be u16;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Explicitly don't add these types to the `type` namespace for usability
|
// Explicitly don't add these types to the `type` namespace for usability
|
||||||
// namespace type {
|
// namespace auto type {
|
||||||
|
|
||||||
// using u8 = u8;
|
// using u8 = u8;
|
||||||
// using u16 = u16;
|
// using u16 = u16;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Explicitly don't add these types to the `type` namespace for usability
|
// Explicitly don't add these types to the `type` namespace for usability
|
||||||
// namespace type {
|
// namespace auto type {
|
||||||
|
|
||||||
using BYTE = u8;
|
using BYTE = u8;
|
||||||
using WORD = u16;
|
using WORD = u16;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#pragma author WerWolv
|
#pragma author WerWolv
|
||||||
#pragma description Autodesk 3DS Max Model file
|
#pragma description Autodesk 3DS Max Model
|
||||||
|
|
||||||
#include <std/io.pat>
|
import std.io;
|
||||||
#include <type/base.pat>
|
import type.base;
|
||||||
|
|
||||||
#pragma MIME image/x-3ds
|
#pragma MIME image/x-3ds
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
#pragma description 7z File Format
|
#pragma description 7z Archive
|
||||||
|
#pragma MIME application/x-7z-compressed
|
||||||
|
#pragma magic [ 37 7A BC AF 27 1C ] @ 0x00
|
||||||
|
|
||||||
#include <std/io.pat>
|
import std.io;
|
||||||
#include <std/mem.pat>
|
import std.mem;
|
||||||
#include <std/math.pat>
|
import std.math;
|
||||||
|
import type.magic;
|
||||||
|
|
||||||
|
|
||||||
enum Type:u8{
|
enum Type:u8{
|
||||||
@@ -10,13 +13,9 @@ enum Type:u8{
|
|||||||
sizeStartHeader = 0x20, // Size of start Header
|
sizeStartHeader = 0x20, // Size of start Header
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TypeB:u48{
|
|
||||||
sevenZipSignature = 0x1C27AFBC7A37, // Defining 7z signature
|
|
||||||
};
|
|
||||||
|
|
||||||
struct StartHeader {
|
struct StartHeader {
|
||||||
// File signature
|
// File signature
|
||||||
u48 signature [[color("FF0000")] ];
|
type::Magic<"7z\xBC\xAF\x27\x1C"> signature [[color("FF0000")] ];
|
||||||
// Version format
|
// Version format
|
||||||
u16 formatVersion [[color("00FF00")]];
|
u16 formatVersion [[color("00FF00")]];
|
||||||
// CRC start header
|
// CRC start header
|
||||||
@@ -61,13 +60,6 @@ struct EndHeader {
|
|||||||
|
|
||||||
EndHeader endheader @ Type::sizeStartHeader;
|
EndHeader endheader @ Type::sizeStartHeader;
|
||||||
|
|
||||||
// Check 7z type
|
|
||||||
if(startheader.signature == TypeB::sevenZipSignature){
|
|
||||||
std::print("It is a 7z File Type");
|
|
||||||
}else{
|
|
||||||
std::print("The file is not 7z type");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::print("Format Version {} ",startheader.formatVersion);
|
std::print("Format Version {} ",startheader.formatVersion);
|
||||||
|
|
||||||
// Version verification
|
// Version verification
|
||||||
|
|||||||
@@ -1,20 +1,28 @@
|
|||||||
#pragma description Crash Bandicoot - Back in Time (fan game) User created flashback tapes level format
|
#pragma author AdventureT
|
||||||
|
#pragma description Crash Bandicoot - Back in Time (fan game) User created level
|
||||||
|
#pragma magic [ 43 52 41 53 48 4C 56 4C ] @ 0x00
|
||||||
|
#pragma history
|
||||||
|
#pragma 0.3 2024-05-15 Added support for version 0.95
|
||||||
|
#pragma 0.2 2023-10-29 Added support for version 0.94c
|
||||||
|
#pragma 0.1 2023-04-25 Initial support
|
||||||
|
// Supports all versions till 0.95, newer versions might be compatible!
|
||||||
|
|
||||||
#include <type/magic.pat>
|
import type.magic;
|
||||||
#include <std/string.pat>
|
import std.string;
|
||||||
#include <std/array.pat>
|
import std.array;
|
||||||
|
|
||||||
// Crash Bandicoot - Back in Time (fan game) user created tapes
|
|
||||||
// author AdventureT
|
|
||||||
|
|
||||||
struct Header {
|
struct Header {
|
||||||
type::Magic<"CRASHLVL"> magic;
|
type::Magic<"CRASHLVL"> magic;
|
||||||
u8 version;
|
u8 version;
|
||||||
|
if (version >= 4) {
|
||||||
|
std::string::SizedString<u8> gameVersion;
|
||||||
|
}
|
||||||
std::string::SizedString<u8> levelName;
|
std::string::SizedString<u8> levelName;
|
||||||
std::string::SizedString<u8> author;
|
std::string::SizedString<u8> author;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Music : u32 {
|
// Background Music
|
||||||
|
enum BGM : u32 {
|
||||||
None,
|
None,
|
||||||
BonusBGM,
|
BonusBGM,
|
||||||
CrashCreatorBGM,
|
CrashCreatorBGM,
|
||||||
@@ -30,39 +38,327 @@ enum Music : u32 {
|
|||||||
NBrioBGM
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
// v0.95
|
||||||
|
enum BGMV3 : BGMV2 {
|
||||||
|
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,
|
||||||
|
MedievalBGM,
|
||||||
|
PreHistoricBGM,
|
||||||
|
UnderWaterBGM,
|
||||||
|
BrioRevisitedBGM,
|
||||||
|
EgyptChaseBGM,
|
||||||
|
RuinsLoopBGM,
|
||||||
|
DingoSynthBGM
|
||||||
|
};
|
||||||
|
|
||||||
enum Type : u32 {
|
enum Type : u32 {
|
||||||
Unset,
|
Unset,
|
||||||
Flashback,
|
Flashback,
|
||||||
Trial
|
Trial
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Time : u32 {
|
enum TypeV2 : u32 {
|
||||||
|
Practice,
|
||||||
|
Flashback,
|
||||||
|
Trial,
|
||||||
|
Adventure
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Skybox : u32 {
|
||||||
Night,
|
Night,
|
||||||
Day,
|
Day,
|
||||||
Storm,
|
Storm,
|
||||||
Dawn
|
Dawn
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Terrain : u32 {
|
enum SkyboxV2 : u32 {
|
||||||
|
Default = 1,
|
||||||
|
Briolab,
|
||||||
|
Fort,
|
||||||
|
Moon,
|
||||||
|
Toxic,
|
||||||
|
AboutRight,
|
||||||
|
Crash1Island,
|
||||||
|
Arabia,
|
||||||
|
RoadToRuin,
|
||||||
|
Black
|
||||||
|
};
|
||||||
|
|
||||||
|
// 0.95
|
||||||
|
enum SkyboxV3 : u32 {
|
||||||
|
Default = 1,
|
||||||
|
Briolab,
|
||||||
|
Fort,
|
||||||
|
Moon,
|
||||||
|
Toxic,
|
||||||
|
AboutRight,
|
||||||
|
Crash1Island,
|
||||||
|
Arabia,
|
||||||
|
RoadToRuin,
|
||||||
|
MotorcycleDay,
|
||||||
|
MotorcycleNoon,
|
||||||
|
MotorcycleMoon,
|
||||||
|
MotorcycleNight,
|
||||||
|
Black
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Scenery : u32 {
|
||||||
None,
|
None,
|
||||||
Machines,
|
FutureTense,
|
||||||
Trees,
|
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,
|
Waterfall,
|
||||||
Snow,
|
Snow,
|
||||||
Fortress,
|
Fortress,
|
||||||
|
None2,
|
||||||
|
Lava,
|
||||||
|
TheGreatGate,
|
||||||
|
Mountain,
|
||||||
|
KoalaKong,
|
||||||
|
SunsetVista,
|
||||||
|
HangemHigh,
|
||||||
|
Sphynxinator,
|
||||||
|
Tunnel,
|
||||||
|
Pipes
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 0.95
|
||||||
|
enum SceneryV5 : u32 {
|
||||||
|
None,
|
||||||
|
FutureTense,
|
||||||
|
Forest,
|
||||||
|
Waterfall,
|
||||||
|
Snow,
|
||||||
|
Fortress,
|
||||||
|
None2,
|
||||||
|
Lava,
|
||||||
|
TheGreatGate,
|
||||||
|
Mountain,
|
||||||
|
KoalaKong,
|
||||||
|
SunsetVista,
|
||||||
|
HangemHigh,
|
||||||
|
Sphynxinator,
|
||||||
|
Tunnel,
|
||||||
|
Pipes,
|
||||||
|
Medieval,
|
||||||
|
FutureCity,
|
||||||
|
TinyArena,
|
||||||
|
HeavyMachinery,
|
||||||
|
CrystalCave,
|
||||||
|
MedievalWithHouses,
|
||||||
|
CortexBonusChamber
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Weather : u32 {
|
||||||
|
Default,
|
||||||
|
Snow,
|
||||||
|
Rain
|
||||||
|
};
|
||||||
|
|
||||||
|
// 0.95
|
||||||
|
enum WeatherV2 : u32 {
|
||||||
|
Default,
|
||||||
|
Snow,
|
||||||
|
Rain,
|
||||||
|
Night,
|
||||||
|
UnderWater
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Options {
|
struct Options {
|
||||||
|
// Type
|
||||||
|
if (header.version > 1) {
|
||||||
|
TypeV2 type;
|
||||||
|
}
|
||||||
|
else {
|
||||||
Type type;
|
Type type;
|
||||||
Time time;
|
}
|
||||||
Terrain terrain;
|
// Skybox
|
||||||
Music music;
|
if (header.version > 1) {
|
||||||
|
if (header.gameVersion == "0.95") {
|
||||||
|
SkyboxV3 skybox;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SkyboxV2 skybox;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Skybox skybox;
|
||||||
|
}
|
||||||
|
// Scenery
|
||||||
|
if (header.version == 1) {
|
||||||
|
Scenery scenery;
|
||||||
|
}
|
||||||
|
else if (header.version > 1 && header.version < 4) {
|
||||||
|
SceneryV2 scenery;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (header.gameVersion == "0.95") {
|
||||||
|
SceneryV5 skybox;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SceneryV4 skybox;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Weather
|
||||||
|
if (header.version > 2) {
|
||||||
|
if (header.gameVersion == "0.95") {
|
||||||
|
WeatherV2 weather;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Weather weather;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Background music
|
||||||
|
if (header.version > 1) {
|
||||||
|
BGMV2 bgm;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BGM bgm;
|
||||||
|
}
|
||||||
|
// Time Trial
|
||||||
|
if (type == Type::Trial) {
|
||||||
|
u32 timeTrialTicksBronze;
|
||||||
|
u32 timeTrialTicksSilver;
|
||||||
|
u32 timeTrialTicksGold;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Object {
|
struct Object {
|
||||||
std::string::SizedString<u8> objName;
|
std::string::SizedString<u8> objName;
|
||||||
|
if (header.version > 1) {
|
||||||
|
u16 x;
|
||||||
|
u16 y;
|
||||||
|
bool hasMetafields;
|
||||||
|
if (hasMetafields) {
|
||||||
|
u16 numOfMetafields;
|
||||||
|
u8 metafields[numOfMetafields];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
u32 x;
|
u32 x;
|
||||||
u32 y;
|
u32 y;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Objects{
|
struct Objects{
|
||||||
@@ -70,6 +366,6 @@ struct Objects{
|
|||||||
std::Array<Object, objCount> objArray;
|
std::Array<Object, objCount> objArray;
|
||||||
};
|
};
|
||||||
|
|
||||||
Header header @ 0x0;
|
Header header @ $;
|
||||||
Options options @ $;
|
Options options @ $;
|
||||||
Objects objects @ $;
|
Objects objects @ $;
|
||||||
189
patterns/SHR.hexpat
Normal file
189
patterns/SHR.hexpat
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
/*!
|
||||||
|
Apple IIgs Super Hi-Res (SHR) + PaintWorks Animation (ANI) — ImHex pattern
|
||||||
|
|
||||||
|
Supports:
|
||||||
|
• PIC $C1/$0000 — 32 KB uncompressed SHR screen image
|
||||||
|
• PIC $C1/$0002 — 3200-color (“Brooks”) per-scanline palettes
|
||||||
|
• ANI $C2/$0000 — PaintWorks animation:
|
||||||
|
0x0000..0x7FFF : base SHR $C1/$0000 image
|
||||||
|
0x8000.. : animation header + chunks
|
||||||
|
|
||||||
|
PaintWorks animation structure (per reversed docs):
|
||||||
|
- Base image: uncompressed SHR ($C1/$0000)
|
||||||
|
- +0x8000 u32: total animation data length after header (file_len - 0x8008)
|
||||||
|
- +0x8004 u16: global frame delay in VBLs
|
||||||
|
- +0x8006 u16: flag/? (commonly 0x00C0 or 0x00C1)
|
||||||
|
- +0x8008 ...: one or more animation chunks:
|
||||||
|
chunk:
|
||||||
|
u32 chunk_len (includes this length field)
|
||||||
|
repeated { u16 offset; u16 value; } pairs
|
||||||
|
offset==0x0000 marks End-of-Frame (value is ignored)
|
||||||
|
- Offsets may target any byte in the 32 KB SHR space (pixels, SCBs, palettes).
|
||||||
|
This enables palette-cycling and SCB effects.
|
||||||
|
|
||||||
|
References:
|
||||||
|
- CiderPress2 PaintWorks Animation notes (file structure, fields, semantics).
|
||||||
|
*/
|
||||||
|
|
||||||
|
import std.core;
|
||||||
|
import std.sys;
|
||||||
|
import std.math;
|
||||||
|
|
||||||
|
#pragma endian little
|
||||||
|
#include <std/mem.pat>
|
||||||
|
|
||||||
|
#pragma description Apple IIgs Super Hi-Res (SHR) + PaintWorks Animation (ANI)
|
||||||
|
#pragma author hasseily
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------ Constants ------------------------------
|
||||||
|
|
||||||
|
const u32 SHR_ROWS = 200;
|
||||||
|
const u32 SHR_BYTES_PER_ROW = 160;
|
||||||
|
const u32 SHR_PIXEL_DATA_SIZE = SHR_ROWS * SHR_BYTES_PER_ROW; // 32000 (0x7D00)
|
||||||
|
|
||||||
|
const u32 PIC0000_FILE_SIZE = 0x8000; // 32768
|
||||||
|
const u32 PIC0002_FILE_SIZE = 0x9600; // 38400 (32000 + 200*32)
|
||||||
|
|
||||||
|
const u32 PIC0000_OFF_PIXELS = 0x0000;
|
||||||
|
const u32 PIC0000_OFF_SCB = 0x7D00;
|
||||||
|
const u32 PIC0000_OFF_RESERVED = 0x7DC8;
|
||||||
|
const u32 PIC0000_OFF_PALETTES = 0x7E00;
|
||||||
|
|
||||||
|
const u32 PALETTE_COUNT = 16;
|
||||||
|
const u32 PALETTE_COLORS = 16;
|
||||||
|
|
||||||
|
const u32 ANI_BASE_SHR_SIZE = 0x8000; // First 32 KB is a $C1/$0000 image
|
||||||
|
const u32 ANI_HDR_OFF = 0x8000; // Animation header starts here
|
||||||
|
const u32 ANI_MIN_TOTAL_SIZE = 0x8008; // base + header (no chunks)
|
||||||
|
|
||||||
|
// ------------------------------ Types: SHR core ------------------------------
|
||||||
|
|
||||||
|
struct Row160 { u8 data[SHR_BYTES_PER_ROW]; };
|
||||||
|
|
||||||
|
// Scanline Control Byte
|
||||||
|
bitfield ShrSCB {
|
||||||
|
palette : 4; // 0..15
|
||||||
|
reserved : 1;
|
||||||
|
color_fill : 1;
|
||||||
|
interrupt : 1;
|
||||||
|
mode_640 : 1; // 0=320, 1=640
|
||||||
|
};
|
||||||
|
|
||||||
|
// helper: expand a 4-bit channel to 8-bit (0x0..0xF -> 0x00..0xFF)
|
||||||
|
fn expand4(u8 v) { return (v << 4) | v; };
|
||||||
|
|
||||||
|
bitfield Colors_gb {
|
||||||
|
blue : 4; // Blue (B3..B0)
|
||||||
|
green : 4; // Green (G3..G0)
|
||||||
|
};
|
||||||
|
|
||||||
|
bitfield Colors_r0 {
|
||||||
|
red : 4; // Red (R3..R0)
|
||||||
|
unused : 4; // Unused / reserved
|
||||||
|
};
|
||||||
|
|
||||||
|
// RGB444 stored as 0RGB
|
||||||
|
struct Rgb444_0RGB {
|
||||||
|
Colors_gb gb;
|
||||||
|
Colors_r0 r0;
|
||||||
|
} [[color(std::format("{:02X}{:02X}{:02X}", expand4(r0.red), expand4(gb.green), expand4(gb.blue)))]];
|
||||||
|
|
||||||
|
struct Palette16 { Rgb444_0RGB color[PALETTE_COLORS]; };
|
||||||
|
|
||||||
|
// $C1/$0000 raw 32 KB screen dump
|
||||||
|
struct SHR_PIC0000 {
|
||||||
|
Row160 pixels[SHR_ROWS] @ PIC0000_OFF_PIXELS;
|
||||||
|
ShrSCB scb[SHR_ROWS] @ PIC0000_OFF_SCB;
|
||||||
|
u8 reserved[56] @ PIC0000_OFF_RESERVED;
|
||||||
|
Palette16 palettes[PALETTE_COUNT] @ PIC0000_OFF_PALETTES;
|
||||||
|
};
|
||||||
|
|
||||||
|
// “Brooks” 3200-color: pixels + 200 per-line palettes (no SCBs)
|
||||||
|
struct BrooksLinePalette { Rgb444_0RGB color[PALETTE_COLORS]; };
|
||||||
|
|
||||||
|
struct SHR_PIC0002 {
|
||||||
|
Row160 pixels[SHR_ROWS] @ 0x0000;
|
||||||
|
BrooksLinePalette line_palettes[SHR_ROWS] @ SHR_PIXEL_DATA_SIZE; // 0x7D00
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------------ Types: PaintWorks ANI ($C2/$0000) ------------------------------
|
||||||
|
|
||||||
|
/* Each operation modifies 1 word at an absolute offset in the 32 KB SHR area.
|
||||||
|
End-of-frame marker: offset == 0x0000 (value is ignored). */
|
||||||
|
struct AniOp {
|
||||||
|
u16 offset [[color("0000AA")]]; // 0x0000..0x7FFE valid; 0x0000 = End-of-Frame
|
||||||
|
u16 value [[color("00AAAA")]]; // word to store at [offset]
|
||||||
|
// For convenience in the sidebar:
|
||||||
|
bool is_eof = (offset == 0x0000);
|
||||||
|
};
|
||||||
|
|
||||||
|
// A contiguous animation chunk: length + packed AniOp pairs.
|
||||||
|
// Most files have exactly one chunk that spans all frames.
|
||||||
|
struct AniChunk {
|
||||||
|
u32 chunk_len; // includes this field
|
||||||
|
|
||||||
|
// ops_count = (chunk_len - 4)/4, unless chunk_len == 4
|
||||||
|
// in which case: (__file_size - 0x8000 - 12)/4
|
||||||
|
u64 ops_count64 =
|
||||||
|
(chunk_len == 4)
|
||||||
|
? ( (__file_size > (0x8000 + 12)) ? ((__file_size - 0x8000 - 12) / 4) : 0 )
|
||||||
|
: ( (chunk_len >= 4) ? (u64(chunk_len - 4) / 4) : 0 );
|
||||||
|
|
||||||
|
u32 ops_count = u32(ops_count64);
|
||||||
|
|
||||||
|
// ops start immediately after chunk_len (offset +4)
|
||||||
|
AniOp ops[ops_count];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Header located at 0x8000 after the base 32 KB image
|
||||||
|
struct AniHeader {
|
||||||
|
u32 anim_data_len [[color("660000")]]; // total bytes of animation data after header
|
||||||
|
u16 frame_delay_vbl [[color("CC0000")]]; // global per-frame delay in VBLs (NTSC/PAL differ)
|
||||||
|
u16 flag_unknown; // usually 0x00C0 or 0x00C1
|
||||||
|
};
|
||||||
|
|
||||||
|
// Full PaintWorks animation container
|
||||||
|
struct ANI_PaintWorks {
|
||||||
|
// Base frame: a normal uncompressed SHR image
|
||||||
|
SHR_PIC0000 base @ 0x0000;
|
||||||
|
|
||||||
|
// Global animation header
|
||||||
|
AniHeader hdr @ ANI_HDR_OFF;
|
||||||
|
|
||||||
|
// One or more chunks, typically exactly one:
|
||||||
|
AniChunk chunks[ std::math::min(
|
||||||
|
u32(16), // cap to keep ImHex happy in pathological cases
|
||||||
|
u32((__file_size - (ANI_HDR_OFF + sizeof(AniHeader))) > 3 ?
|
||||||
|
1 + u32((__file_size - (ANI_HDR_OFF + sizeof(AniHeader))) / 0x10000000) :
|
||||||
|
1)
|
||||||
|
) ] @ (ANI_HDR_OFF + sizeof(AniHeader));
|
||||||
|
|
||||||
|
// Helpful computed values for inspection:
|
||||||
|
u64 file_len = __file_size;
|
||||||
|
u64 expected_anim_end = ANI_HDR_OFF + sizeof(AniHeader) + u64(hdr.anim_data_len);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------------ Dispatcher ------------------------------
|
||||||
|
|
||||||
|
u64 __file_size = std::mem::size();
|
||||||
|
|
||||||
|
if (__file_size == PIC0000_FILE_SIZE) {
|
||||||
|
// Plain SHR dump
|
||||||
|
SHR_PIC0000 pic0000 @ 0x0000;
|
||||||
|
|
||||||
|
} else if (__file_size == PIC0002_FILE_SIZE) {
|
||||||
|
// Brooks 3200-color
|
||||||
|
SHR_PIC0002 pic0002 @ 0x0000;
|
||||||
|
|
||||||
|
} else if (__file_size >= ANI_MIN_TOTAL_SIZE) {
|
||||||
|
// Heuristic: treat as PaintWorks ANI if there’s room for base+header.
|
||||||
|
// (Many PW ANI files use ProDOS type $C2/$0000.)
|
||||||
|
ANI_PaintWorks ani @ 0x0000;
|
||||||
|
|
||||||
|
} else if (__file_size >= SHR_PIXEL_DATA_SIZE) {
|
||||||
|
// Fallback: show pixels only for odd dumps
|
||||||
|
Row160 pixels_only[SHR_ROWS] @ 0x0000;
|
||||||
|
}
|
||||||
|
|
||||||
|
ANI_PaintWorks ani_paintworks_at_0 @ 0;
|
||||||
176
patterns/adtfdat.hexpat
Normal file
176
patterns/adtfdat.hexpat
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
#pragma description ADTFDAT File
|
||||||
|
|
||||||
|
#pragma magic [ 49 46 48 44 ] @ 0x00
|
||||||
|
#pragma endian little
|
||||||
|
|
||||||
|
import std.io;
|
||||||
|
import std.mem;
|
||||||
|
import type.time;
|
||||||
|
|
||||||
|
enum FileVersion : u32 {
|
||||||
|
with_history_end_offset = 0x00000301,
|
||||||
|
v500 = 0x00000500
|
||||||
|
};
|
||||||
|
|
||||||
|
bitfield ChunkFlags {
|
||||||
|
key : 1;
|
||||||
|
info : 1;
|
||||||
|
marker : 1;
|
||||||
|
type : 1;
|
||||||
|
trigger : 1;
|
||||||
|
reserved: 11;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Extension
|
||||||
|
{
|
||||||
|
char identifier[384];
|
||||||
|
u16 stream_id;
|
||||||
|
u8 reserved1[2];
|
||||||
|
u32 user_id;
|
||||||
|
u32 type_id;
|
||||||
|
u32 version_id;
|
||||||
|
u64 data_pos;
|
||||||
|
u64 data_size;
|
||||||
|
u8 reserved[96];
|
||||||
|
u8 payload[data_size] @ data_pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ChunkHeader {
|
||||||
|
u64 time_stamp [[format("format_timestamp_with_offset")]];;
|
||||||
|
u32 ref_master_table_index;
|
||||||
|
u32 offset_to_last;
|
||||||
|
u32 size;
|
||||||
|
u16 stream_id;
|
||||||
|
ChunkFlags flags;
|
||||||
|
u64 stream_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SampleInfo {
|
||||||
|
u8 memory_layout_version;
|
||||||
|
u32 size;
|
||||||
|
u8 payload[size];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Sample {
|
||||||
|
s64 timestamp [[format("format_timestamp")]];;
|
||||||
|
s32 flags;
|
||||||
|
u64 buffer_size;
|
||||||
|
u8 payload[buffer_size];
|
||||||
|
if (flags & 0x100) {
|
||||||
|
SampleInfo sample_info;
|
||||||
|
}
|
||||||
|
if (flags & 0x200) {
|
||||||
|
u32 substream_id;
|
||||||
|
} else {
|
||||||
|
u32 substream_id = 0 [[export]];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Chunk {
|
||||||
|
auto start_address = $;
|
||||||
|
|
||||||
|
ChunkHeader header;
|
||||||
|
|
||||||
|
if (header.size < 32 || start_address + header.size > std::mem::size()) {
|
||||||
|
std::warning(std::format("Invalid header size {} in chunk {} at offset 0x{:X}, last valid chunk at 0x{:X}.", header.size, chunk_index, start_address, last_valid_chunk_offset));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_valid_chunk_offset = start_address;
|
||||||
|
|
||||||
|
u8 payload[header.size - 32];
|
||||||
|
|
||||||
|
if (!skip_valid_chunks) {
|
||||||
|
if (!header.flags.info && !header.flags.marker && !header.flags.type && !header.flags.trigger) {
|
||||||
|
try {
|
||||||
|
Sample sample @ addressof(payload);
|
||||||
|
} catch {
|
||||||
|
std::warning(std::format("Invalid sample payload at chunk {} at 0x{:X}", chunk_index, start_address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk_index += 1;
|
||||||
|
|
||||||
|
// Padding with 0xEE to the next chunk header
|
||||||
|
std::mem::AlignTo<16>;
|
||||||
|
|
||||||
|
if (skip_valid_chunks) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Header {
|
||||||
|
u32 file_id;
|
||||||
|
u32 version_id;
|
||||||
|
u32 flags;
|
||||||
|
u32 extension_count;
|
||||||
|
u64 extension_offset;
|
||||||
|
u64 data_offset;
|
||||||
|
u64 data_size;
|
||||||
|
u64 chunk_count;
|
||||||
|
u64 max_chunk_size;
|
||||||
|
u64 duration;
|
||||||
|
type::time64_t filetime;
|
||||||
|
u8 header_byte_order;
|
||||||
|
u64 time_offset [[format("format_timestamp")]];
|
||||||
|
u8 patch_number;
|
||||||
|
u64 first_chunk_offset;
|
||||||
|
u64 continuous_offset;
|
||||||
|
u64 ring_buffer_end_offset;
|
||||||
|
u8 reserved[30];
|
||||||
|
char description[1912];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IndexedFile {
|
||||||
|
Header header;
|
||||||
|
Extension extensions[header.extension_count] @ header.extension_offset;
|
||||||
|
|
||||||
|
if (header.version_id >= FileVersion::with_history_end_offset &&
|
||||||
|
header.continuous_offset != header.data_offset) {
|
||||||
|
try {
|
||||||
|
Chunk ring_front[while($ < header.continuous_offset)] @ header.first_chunk_offset;
|
||||||
|
Chunk ring_back[while($ < header.ring_buffer_end_offset)] @ header.data_offset;
|
||||||
|
Chunk continueous[header.chunk_count - chunk_index] @ header.continuous_offset;
|
||||||
|
} catch {
|
||||||
|
std::warning("Too many chunks. Performing check only.");
|
||||||
|
skip_valid_chunks = true;
|
||||||
|
chunk_index = 0;
|
||||||
|
Chunk ring_front[while($ < header.continuous_offset)] @ header.first_chunk_offset;
|
||||||
|
Chunk ring_back[while($ < header.ring_buffer_end_offset)] @ header.data_offset;
|
||||||
|
Chunk continueous[while(chunk_index < header.chunk_count)] @ header.continuous_offset;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
Chunk chunks[header.chunk_count] @ header.data_offset;
|
||||||
|
} catch {
|
||||||
|
std::warning("Too many chunks. Performing check only.");
|
||||||
|
skip_valid_chunks = true;
|
||||||
|
chunk_index = 0;
|
||||||
|
Chunk chunks[while(chunk_index < header.chunk_count)] @ header.data_offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fn format_timestamp(u64 data) {
|
||||||
|
double seconds = 0;
|
||||||
|
if (file.header.version_id < FileVersion::v500) {
|
||||||
|
// microseconds
|
||||||
|
seconds = data / double(1000000);
|
||||||
|
} else {
|
||||||
|
// nanoseconds
|
||||||
|
seconds = data / double(1000000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::time::Time time64 = std::time::to_utc(seconds);
|
||||||
|
return std::time::format(time64);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn format_timestamp_with_offset(u64 data) {
|
||||||
|
return format_timestamp(data + file.header.time_offset);
|
||||||
|
};
|
||||||
|
|
||||||
|
bool skip_valid_chunks = false;
|
||||||
|
u64 last_valid_chunk_offset = 0;
|
||||||
|
u64 chunk_index = 0;
|
||||||
|
IndexedFile file @ 0x00;
|
||||||
197
patterns/adts.hexpat
Normal file
197
patterns/adts.hexpat
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
#pragma author zhoubo
|
||||||
|
#pragma description AAC ADTSn (Audio Data Transport Stream) Audio
|
||||||
|
#pragma MIME audio/x-hx-aac-adts
|
||||||
|
#pragma pattern_limit 0xFFFFFF
|
||||||
|
|
||||||
|
// History
|
||||||
|
// 0.4 2024-02-12 zhoubo: Porting from 010 Editor Templates.
|
||||||
|
// 0.3 2024-02-09 zhoubo: use BitfieldDisablePadding(Unpadded Bitfields) for odd header bytes(7,9 bytes) color, and remove FSeek.
|
||||||
|
// 0.2 2024-02-05 zhoubo: fix some comment & color.
|
||||||
|
// 0.1 2022-06-13 zhoubo: Init release. only ADTS, not support ADIF,LATM.
|
||||||
|
|
||||||
|
// More information available at:
|
||||||
|
// 1. https://wiki.multimedia.cx/index.php?title=ADTS
|
||||||
|
// 2. https://en.wikipedia.org/wiki/Advanced_Audio_Coding
|
||||||
|
// 3. https://en.wikipedia.org/wiki/AAC
|
||||||
|
// 4. https://juejin.cn/post/7032170229732442148
|
||||||
|
|
||||||
|
#pragma endian big
|
||||||
|
|
||||||
|
#include <std/sys.pat>
|
||||||
|
#include <std/core.pat>
|
||||||
|
|
||||||
|
fn GetMPEGVersionComment(auto MPEG_Version)
|
||||||
|
{
|
||||||
|
str comment = "";
|
||||||
|
match (MPEG_Version)
|
||||||
|
{
|
||||||
|
(0): comment = "MPEG-4";
|
||||||
|
(1): comment = "MPEG-2";
|
||||||
|
}
|
||||||
|
return comment;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn GetProtectionAbsentComment(auto Protection_absence)
|
||||||
|
{
|
||||||
|
str comment = "";
|
||||||
|
match (Protection_absence)
|
||||||
|
{
|
||||||
|
(0): comment = "ADTS has 9 bytes with CRC";
|
||||||
|
(1): comment = "ADTS has 7 bytes without CRC";
|
||||||
|
}
|
||||||
|
return comment;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn GetProfileComment(auto Profile)
|
||||||
|
{
|
||||||
|
str comment = "";
|
||||||
|
match (Profile)
|
||||||
|
{
|
||||||
|
(0x00): comment = "AAC Main";
|
||||||
|
(0x01): comment = "AAC LC (Low Complexity)";
|
||||||
|
(0x10): comment = "AAC SSR (Scalable Sample Rate)";
|
||||||
|
(0x11): comment = "AAC LTP (Long Term Prediction)";
|
||||||
|
}
|
||||||
|
return comment;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn GetSamplingFrequencyIndexComment(auto Sampling_frequency_index)
|
||||||
|
{
|
||||||
|
str comment = "";
|
||||||
|
match (Sampling_frequency_index)
|
||||||
|
{
|
||||||
|
(0x0): comment = "96000Hz";
|
||||||
|
(0x1): comment = "88200Hz";
|
||||||
|
(0x2): comment = "64000Hz";
|
||||||
|
(0x3): comment = "48000Hz";
|
||||||
|
(0x4): comment = "44100Hz";
|
||||||
|
(0x5): comment = "32000Hz";
|
||||||
|
(0x6): comment = "24000Hz";
|
||||||
|
(0x7): comment = "22050Hz";
|
||||||
|
(0x8): comment = "16000Hz";
|
||||||
|
(0x9): comment = "12000Hz";
|
||||||
|
(0xa): comment = "11025Hz";
|
||||||
|
(0xb): comment = "8000Hz";
|
||||||
|
(0xc): comment = "7350Hz";
|
||||||
|
(0xd): comment = "Reserved";
|
||||||
|
(0xe): comment = "Reserved";
|
||||||
|
(0xf): comment = "FORBIDDEN (malformed)";
|
||||||
|
}
|
||||||
|
return comment;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn GetChannelConfigurationComment(auto Channel_configuration)
|
||||||
|
{
|
||||||
|
str comment = "";
|
||||||
|
match (Channel_configuration)
|
||||||
|
{
|
||||||
|
(0): comment = "Defined in AOT Specifc Config";
|
||||||
|
(1): comment = "1 channel: front-center";
|
||||||
|
(2): comment = "2 channels: front-left, front-right";
|
||||||
|
(3): comment = "3 channels: front-center, front-left, front-right";
|
||||||
|
(4): comment = "4 channels: front-center, front-left, front-right, back-center";
|
||||||
|
(5): comment = "5 channels: front-center, front-left, front-right, back-left, back-right";
|
||||||
|
(6): comment = "6 channels: front-center, front-left, front-right, back-left, back-right, LFE-channel";
|
||||||
|
(7): comment = "8 channels: front-center, front-left, front-right, side-left, side-right, back-left, back-right, LFE-channel";
|
||||||
|
}
|
||||||
|
return comment;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn GetBufferFullnessComment(auto ADTS_buffer_fullness)
|
||||||
|
{
|
||||||
|
str comment = "";
|
||||||
|
match (ADTS_buffer_fullness)
|
||||||
|
{
|
||||||
|
(0x7FF): comment = "VBR (most software ignore this field)";
|
||||||
|
(_): comment = "rate..?? (most software ignore this field)";
|
||||||
|
}
|
||||||
|
return comment;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn GetRawDataBlockComment(auto Number_of_AAC_frames_minus_1)
|
||||||
|
{
|
||||||
|
str comment = "";
|
||||||
|
match (Number_of_AAC_frames_minus_1)
|
||||||
|
{
|
||||||
|
(0x0): comment = "has 1 AAC data block";
|
||||||
|
(_): comment = "data block number + 1";
|
||||||
|
}
|
||||||
|
return comment;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------
|
||||||
|
// Define structures used in AAC files
|
||||||
|
//
|
||||||
|
// [1.adts_fixed_header information]
|
||||||
|
// Syncword: 12bits, sync header, always 0xFFF。
|
||||||
|
// MPEG_Version: 1bit, 0 means MPGE-4, 1 means MPGE-2
|
||||||
|
// Layer: 2bits, alwayas ”00”
|
||||||
|
// Protection_absence: 1bit, 0 means ADTS Header 9 bytes; 1 means ADTS Header 7 bytes
|
||||||
|
// Profile: 2bit, AAC level : Main,LC,SSR,LTP
|
||||||
|
// Sampling_frequency_index: 4bits, Sampling Frequencies
|
||||||
|
// Private_bit: 1bit
|
||||||
|
// Channel_configuration: 3bits, channel number...
|
||||||
|
// Originality: 1bit
|
||||||
|
// Home: 1bit
|
||||||
|
//
|
||||||
|
// [2.adts_variable_header information]
|
||||||
|
// Copyright_id_bit: 1bit
|
||||||
|
// Copyright_id_start: 1bit
|
||||||
|
// AAC_frame_length: 13bits, AAC frame length : ADTS Header(7 or 9 bytes) + sizeof(AAC Frame)
|
||||||
|
// ADTS_buffer_fullness: 11bits, 0x7FF means VBR
|
||||||
|
// Number_of_AAC_frames_minus_1: 2bits, ADTS Frame numbers : Number_of_AAC_frames_minus_1 + 1
|
||||||
|
//
|
||||||
|
// [3.CRC information]
|
||||||
|
// CRC16: 16bits, when Protection_absence=0
|
||||||
|
|
||||||
|
bitfield ADTS_HEADER
|
||||||
|
{
|
||||||
|
// ADTS_FIXED_HEADER
|
||||||
|
Syncword : 12 [[color("00FF00"), comment("always 0xFFF")]];
|
||||||
|
MPEG_Version : 1 [[color("00FF00"), comment(GetMPEGVersionComment(this))]];
|
||||||
|
Layer : 2 [[color("00FF00"), comment("always 0")]];
|
||||||
|
Protection_absence : 1 [[color("00FF00"), comment(GetProtectionAbsentComment(this))]];
|
||||||
|
|
||||||
|
Profile : 2 [[color("0000FF"), comment(GetProfileComment(this))]];
|
||||||
|
Sampling_frequency_index : 4 [[color("0000FF"), comment(GetSamplingFrequencyIndexComment(this))]];
|
||||||
|
Private_bit : 1 [[color("0000FF")]];
|
||||||
|
Channel_configuration : 3 [[color("0000FF"), comment(GetChannelConfigurationComment(this))]];
|
||||||
|
Originality : 1 [[color("0000FF")]];
|
||||||
|
Home : 1 [[color("0000FF")]];
|
||||||
|
|
||||||
|
// ADTS_VARIABLE_HEADER
|
||||||
|
Copyright_id_bit : 1 [[color("0000FF")]];
|
||||||
|
Copyright_id_start : 1 [[color("0000FF")]];
|
||||||
|
AAC_frame_length : 13 [[color("0000FF")]];
|
||||||
|
ADTS_buffer_fullness : 11 [[color("0000FF"), comment(GetBufferFullnessComment(this))]];
|
||||||
|
Number_of_AAC_frames_minus_1 : 2 [[color("0000FF"), comment(GetRawDataBlockComment(this))]];
|
||||||
|
|
||||||
|
// ADTS_CRC_HEADER
|
||||||
|
if (0 == Protection_absence) // Header with CRC
|
||||||
|
{
|
||||||
|
u16 CRC16 [[color("FFFF00")]];
|
||||||
|
}
|
||||||
|
else // Header without CRC
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ADTS_FRAME
|
||||||
|
{
|
||||||
|
ADTS_HEADER Header;
|
||||||
|
|
||||||
|
if (0 == Header.Protection_absence) // Header with CRC 2 bytes
|
||||||
|
{
|
||||||
|
u8 Data[Header.AAC_frame_length - 9] [[color("000000")]];
|
||||||
|
}
|
||||||
|
else // Header without CRC
|
||||||
|
{
|
||||||
|
u8 Data[Header.AAC_frame_length - 7] [[color("000000")]];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//---------------------------------------------
|
||||||
|
|
||||||
|
ADTS_FRAME adtsFrame[while(!std::mem::eof())] @ 0x00;
|
||||||
@@ -1,10 +1,14 @@
|
|||||||
#pragma author WerWolv
|
#pragma author WerWolv
|
||||||
#pragma description Nintendo Switch Atmosphère CFW Fatal Error log
|
#pragma description Nintendo Switch Atmosphère CFW Fatal Error log
|
||||||
|
|
||||||
|
#pragma magic [ 41 46 45 30 ] @ 0x00
|
||||||
|
#pragma magic [ 41 46 45 31 ] @ 0x00
|
||||||
|
#pragma magic [ 41 46 45 32 ] @ 0x00
|
||||||
|
|
||||||
#pragma endian little
|
#pragma endian little
|
||||||
|
|
||||||
#include <std/io.pat>
|
import std.io;
|
||||||
#include <std/sys.pat>
|
import std.sys;
|
||||||
|
|
||||||
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC "AFE2"
|
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC "AFE2"
|
||||||
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_1 "AFE1"
|
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_1 "AFE1"
|
||||||
|
|||||||
71
patterns/ani.hexpat
Normal file
71
patterns/ani.hexpat
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
#pragma description Windows animated cursor
|
||||||
|
#pragma MIME application/x-navi-animation
|
||||||
|
#pragma endian little
|
||||||
|
|
||||||
|
import std.io;
|
||||||
|
import std.mem;
|
||||||
|
|
||||||
|
bitfield HeaderFlags {
|
||||||
|
icon : 1;
|
||||||
|
sequence : 1;
|
||||||
|
padding: 30;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct anih {
|
||||||
|
u32 struct_size;
|
||||||
|
u32 stored_frames;
|
||||||
|
u32 animation_steps;
|
||||||
|
u32 w;
|
||||||
|
u32 h;
|
||||||
|
u32 bits;
|
||||||
|
u32 planes;
|
||||||
|
u32 default_jiffies;
|
||||||
|
HeaderFlags flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rate {
|
||||||
|
u32 jiffies[parent.size / 4];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct seq {
|
||||||
|
u32 index[parent.size / 4];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RiffChunk {
|
||||||
|
char signature[4];
|
||||||
|
u32 size;
|
||||||
|
if (signature == "RIFF" || signature == "LIST") {
|
||||||
|
char type[4];
|
||||||
|
|
||||||
|
// Compatible with error size defined in ani files
|
||||||
|
u32 remain = sizeof($) - addressof(type);
|
||||||
|
u32 marked = size > remain ? remain : size;
|
||||||
|
|
||||||
|
RiffChunk chunks[while($ - addressof(type) < marked)];
|
||||||
|
} else if (signature[0] == 'I' && parent.type == "INFO") {
|
||||||
|
char info[size];
|
||||||
|
} else if (signature == "anih") {
|
||||||
|
anih anih [[inline]];
|
||||||
|
} else if (signature == "rate") {
|
||||||
|
rate rate [[inline]];
|
||||||
|
} else if (signature == "seq ") {
|
||||||
|
seq seq [[inline]];
|
||||||
|
} else {
|
||||||
|
std::mem::Bytes<size> data;
|
||||||
|
}
|
||||||
|
padding[size % 2];
|
||||||
|
} [[format_read("read_chunk")]];
|
||||||
|
|
||||||
|
fn read_chunk(RiffChunk chunk) {
|
||||||
|
if (chunk.signature == "RIFF" || chunk.signature == "LIST") {
|
||||||
|
return std::format("{}<{}> ({})", chunk.signature, chunk.type, chunk.size);
|
||||||
|
} else {
|
||||||
|
str ret = std::format("{} ({})", chunk.signature, chunk.size);
|
||||||
|
try {
|
||||||
|
ret += std::format(" \"{}\"", chunk.info);
|
||||||
|
} catch {}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
RiffChunk riff @ 0;
|
||||||
50
patterns/apple_single_double.hexpat
Normal file
50
patterns/apple_single_double.hexpat
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#pragma author Lexi Mayfield
|
||||||
|
#pragma description AppleSingle/AppleDouble file format
|
||||||
|
#pragma endian big
|
||||||
|
#pragma magic [00 05 16 0?] @ 0x00
|
||||||
|
|
||||||
|
import type.magic;
|
||||||
|
|
||||||
|
enum EntryID : u32 {
|
||||||
|
DataFork = 1,
|
||||||
|
ResourceFork = 2,
|
||||||
|
RealName = 3,
|
||||||
|
Comment = 4,
|
||||||
|
IconBW = 5,
|
||||||
|
IconColor = 6,
|
||||||
|
FileDatesInfo = 8,
|
||||||
|
FinderInfo = 9,
|
||||||
|
MacFileInfo = 10,
|
||||||
|
ProDOSFileInfo = 11,
|
||||||
|
MSDOSFileInfo = 12,
|
||||||
|
ShortName = 13,
|
||||||
|
AFPFileInfo = 14,
|
||||||
|
DirectoryID = 15,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Entry {
|
||||||
|
EntryID entryID;
|
||||||
|
u32 offset;
|
||||||
|
u32 length;
|
||||||
|
u8 data[length] @ offset [[sealed]];
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FileType : u32 {
|
||||||
|
AppleSingle = 0x00051600,
|
||||||
|
AppleDouble = 0x00051607,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Version : u32 {
|
||||||
|
V1 = 0x00010000,
|
||||||
|
V2 = 0x00020000,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AppleSingleDouble {
|
||||||
|
FileType fileType;
|
||||||
|
Version version;
|
||||||
|
char homeFileSystem[16];
|
||||||
|
u16 numEntries;
|
||||||
|
Entry entryDescs[numEntries];
|
||||||
|
};
|
||||||
|
|
||||||
|
AppleSingleDouble appleSingleDouble @ 0x00;
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
#pragma author WerWolv
|
#pragma author WerWolv
|
||||||
#pragma description Static library archive files
|
#pragma description GNU Static library archive
|
||||||
|
|
||||||
#pragma MIME application/x-archive
|
#pragma MIME application/x-archive
|
||||||
|
|
||||||
#include <std/string.pat>
|
import std.string;
|
||||||
#include <std/mem.pat>
|
import std.mem;
|
||||||
#include <std/sys.pat>
|
import std.sys;
|
||||||
|
|
||||||
struct ARFile {
|
struct ARFile {
|
||||||
char file_name[16];
|
char file_name[16];
|
||||||
@@ -23,6 +23,9 @@ struct ARFile {
|
|||||||
};
|
};
|
||||||
|
|
||||||
char signature[8] @ 0x00;
|
char signature[8] @ 0x00;
|
||||||
|
if (signature == "!<arch>\r") {
|
||||||
|
std::error("Archive file got corrupted due to CRLF line ending conversion!");
|
||||||
|
}
|
||||||
std::assert(signature == "!<arch>\n", "File is not a valid archive!");
|
std::assert(signature == "!<arch>\n", "File is not a valid archive!");
|
||||||
|
|
||||||
ARFile files[while($ < std::mem::size())] @ $;
|
ARFile files[while($ < std::mem::size())] @ $;
|
||||||
|
|||||||
26
patterns/arc.hexpat
Normal file
26
patterns/arc.hexpat
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma author DexrnZacAttack
|
||||||
|
#pragma description Minecraft LCE ARC File
|
||||||
|
#pragma endian big
|
||||||
|
|
||||||
|
import std.string;
|
||||||
|
#ifdef __IMHEX__
|
||||||
|
import hex.core;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct Table {
|
||||||
|
u16 nameSize;
|
||||||
|
char fileName[nameSize];
|
||||||
|
u32 offset;
|
||||||
|
u32 size;
|
||||||
|
u8 file[size] @ offset;
|
||||||
|
#ifdef __IMHEX__
|
||||||
|
hex::core::add_virtual_file(fileName, file);
|
||||||
|
#endif
|
||||||
|
} [[name(std::string::to_string(fileName))]];
|
||||||
|
|
||||||
|
struct ARC {
|
||||||
|
u32 count;
|
||||||
|
Table table[count];
|
||||||
|
};
|
||||||
|
|
||||||
|
ARC arc @ 0x00;
|
||||||
36
patterns/aria2.hexpat
Normal file
36
patterns/aria2.hexpat
Normal 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;
|
||||||
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
#pragma endian little
|
#pragma endian little
|
||||||
|
|
||||||
#include <std/io.pat>
|
import std.io;
|
||||||
#include <std/mem.pat>
|
import std.mem;
|
||||||
|
|
||||||
#define VTOR 0x00000000
|
#define VTOR 0x00000000
|
||||||
#define EXTERNAL_INTERRUPT_COUNT 64
|
#define EXTERNAL_INTERRUPT_COUNT 64
|
||||||
|
|||||||
1
patterns/bastion
Submodule
1
patterns/bastion
Submodule
Submodule patterns/bastion added at e6deed433c
168
patterns/bcss.hexpat
Normal file
168
patterns/bcss.hexpat
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
#pragma author ttimasdf
|
||||||
|
#pragma description BeyondCompare Snapshot (BCSS) file
|
||||||
|
|
||||||
|
#pragma magic [42 43 53 53] @ 0x00
|
||||||
|
|
||||||
|
#pragma array_limit 4294967295
|
||||||
|
#pragma pattern_limit 4294967295
|
||||||
|
|
||||||
|
|
||||||
|
import std.io;
|
||||||
|
import std.mem;
|
||||||
|
import std.array;
|
||||||
|
import std.string;
|
||||||
|
import type.magic;
|
||||||
|
|
||||||
|
#ifdef __IMHEX__
|
||||||
|
import hex.dec;
|
||||||
|
import hex.core;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
const u8 max_path_size = 1000;
|
||||||
|
str current_path[max_path_size];
|
||||||
|
u8 current_path_level = 0;
|
||||||
|
|
||||||
|
enum EntryType : u8 {
|
||||||
|
DIRECTORY = 0x01,
|
||||||
|
FILE = 0x02,
|
||||||
|
SYMLINK = 0x03,
|
||||||
|
// NULL = 0x00,
|
||||||
|
DIR_END = 0xFF,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BCSSEntry {
|
||||||
|
EntryType type;
|
||||||
|
match (type) {
|
||||||
|
(EntryType::DIRECTORY) : {
|
||||||
|
// FileName name;
|
||||||
|
std::string::SizedString<u8> name;
|
||||||
|
if (name.size != 0) {
|
||||||
|
u8 unknown[12];
|
||||||
|
on_dir_enter(name.data); // std::string::to_string(name)
|
||||||
|
} else {
|
||||||
|
// some buggy edge cases
|
||||||
|
u8 unknown[6];
|
||||||
|
std::warning(std::format("invalid empty entry current_lvl={} current_pos=0x{:02x}", current_path_level, $));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(EntryType::FILE) : {
|
||||||
|
std::string::SizedString<u8> name;
|
||||||
|
if (name.size != 0) {
|
||||||
|
u8 unknown[20];
|
||||||
|
#ifdef __IMHEX__
|
||||||
|
hex::core::add_virtual_file(get_vfs_path(name), this); // std::string::to_string(name)
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
// some buggy edge cases
|
||||||
|
u8 unknown[6];
|
||||||
|
std::warning(std::format("invalid empty entry current_lvl={} current_pos=0x{:02x}", current_path_level, $));
|
||||||
|
}
|
||||||
|
//try {
|
||||||
|
// u8 unknown[20];
|
||||||
|
//} catch {
|
||||||
|
// u8 unknown[0];
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
(EntryType::SYMLINK) : {
|
||||||
|
std::string::SizedString<u8> name;
|
||||||
|
u8 unknown[23];
|
||||||
|
std::string::SizedString<u8> target;
|
||||||
|
#ifdef __IMHEX__
|
||||||
|
hex::core::add_virtual_file(get_vfs_path(name + " [s]"), this); // std::string::to_string(name)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
(EntryType::DIR_END) : {
|
||||||
|
on_dir_exit();
|
||||||
|
}
|
||||||
|
// (EntryType::NULL) : {
|
||||||
|
// // some buggy edge cases
|
||||||
|
// u8 unknown[7];
|
||||||
|
// std::warning(std::format("invalid empty entry current_lvl={} current_pos=0x{:02x}", current_path_level, $));
|
||||||
|
// }
|
||||||
|
(_): {
|
||||||
|
std::error(std::format("unknown EntryType idx={} current_pos=0x{:02x}", std::core::array_index(), $));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}[[format_read("fmt_BCSSEntry")]];
|
||||||
|
|
||||||
|
fn on_dir_enter(str folder_name) {
|
||||||
|
// std::print("on_dir_enter folder={} current_lvl={}", folder_name, current_path_level);
|
||||||
|
if (std::string::length(folder_name) > 0) {
|
||||||
|
current_path[current_path_level] = folder_name;
|
||||||
|
current_path_level += 1;
|
||||||
|
} else {
|
||||||
|
std::warning(std::format("invalid folder name {} current_lvl={} current_pos=0x{:02x}", folder_name, current_path_level, $));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fn on_dir_exit() {
|
||||||
|
if (current_path_level > 0) {
|
||||||
|
current_path_level -= 1;
|
||||||
|
} else if (!std::mem::eof()) {
|
||||||
|
std::warning(std::format("on_dir_exit current_lvl already == 0 current_pos=0x{:02x}", $));
|
||||||
|
}
|
||||||
|
// std::print("on_dir_exit current_lvl={}", current_path_level);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn get_vfs_path(str file_name) {
|
||||||
|
str vfs_path = "";
|
||||||
|
if (current_path_level > 0) {
|
||||||
|
vfs_path = current_path[0];
|
||||||
|
for(u8 i = 1, i < current_path_level, i += 1) {
|
||||||
|
//hash_hex = hash_hex + std::format("{:02X}",bytes[i]);
|
||||||
|
vfs_path = vfs_path + "/" + current_path[i];
|
||||||
|
}
|
||||||
|
return vfs_path + "/" + file_name;
|
||||||
|
} else {
|
||||||
|
return file_name;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
fn fmt_BCSSEntry(BCSSEntry e) {
|
||||||
|
try {
|
||||||
|
match (e.type) {
|
||||||
|
(EntryType::DIRECTORY | EntryType::FILE) : {
|
||||||
|
return std::format("{}: {}", (e.type == EntryType::DIRECTORY ? "Dir" : "File"), e.name.data);
|
||||||
|
}
|
||||||
|
(EntryType::SYMLINK) : {
|
||||||
|
return std::format("Symlink: {} -> {}", e.name.data, e.target.data);
|
||||||
|
}
|
||||||
|
(EntryType::DIR_END) : {
|
||||||
|
return "Directory End";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
return "[FmtErr]";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BCSSFile {
|
||||||
|
if (std::mem::read_unsigned(0, 4) == 0x53534342) {
|
||||||
|
type::Magic<"BCSS"> magic;
|
||||||
|
u8 unknown[14];
|
||||||
|
std::string::SizedString<u16> root_path;
|
||||||
|
|
||||||
|
u8 zlib_content[std::mem::size()-$];
|
||||||
|
|
||||||
|
// manually add zlib header which is essential for hex::dec::zlib_decompress
|
||||||
|
const str zlib_header = "\x78\x9c";
|
||||||
|
std::mem::Section zlib_compressed = std::mem::create_section("zlib_compressed");
|
||||||
|
std::mem::copy_value_to_section(zlib_header, zlib_compressed, 0);
|
||||||
|
std::mem::copy_value_to_section(zlib_content, zlib_compressed, 2);
|
||||||
|
u8 zlib[std::mem::get_section_size(zlib_compressed)] @ 0x00 in zlib_compressed;
|
||||||
|
|
||||||
|
#ifdef __IMHEX__
|
||||||
|
std::mem::Section zlib_decompressed = std::mem::create_section("zlib_decompressed");
|
||||||
|
hex::dec::zlib_decompress(zlib, zlib_decompressed, 15);
|
||||||
|
u8 decompressed_content[std::mem::get_section_size(zlib_decompressed)] @ 0x00 in zlib_decompressed;
|
||||||
|
hex::core::add_virtual_file("bcss_content", decompressed_content);
|
||||||
|
std::warning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n! BCSS file content is compressed !\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\nopen `bcss_content` file from the Virtual Filesystem tab and run this pattern on it.");
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
BCSSEntry entries[while(!std::mem::eof())];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BCSSFile bcss_file @ 0x00;
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
#pragma author WerWolv
|
#pragma author WerWolv
|
||||||
#pragma description Bencode encoding, used by Torrent files
|
#pragma description Torrent data (Bencode)
|
||||||
|
|
||||||
#pragma MIME application/x-bittorrent
|
#pragma MIME application/x-bittorrent
|
||||||
|
|
||||||
#include <std/ctype.pat>
|
import std.ctype;
|
||||||
#include <std/mem.pat>
|
import std.mem;
|
||||||
#include <std/string.pat>
|
import std.string;
|
||||||
|
|
||||||
namespace bencode {
|
namespace bencode {
|
||||||
|
|
||||||
@@ -38,10 +38,15 @@ namespace bencode {
|
|||||||
ASCIIDecimal length;
|
ASCIIDecimal length;
|
||||||
char separator [[hidden]];
|
char separator [[hidden]];
|
||||||
char value[length];
|
char value[length];
|
||||||
} [[sealed, format("bencode::format_string"), transform("bencode::format_string")]];
|
} [[sealed, format("bencode::format_string")]];
|
||||||
|
|
||||||
fn format_string(String string) {
|
fn format_string(String string) {
|
||||||
return string.value;
|
for (u64 i = 0, i < string.length, i = i + 1) {
|
||||||
|
if (!std::ctype::isprint(string.value[i])) {
|
||||||
|
return "Contains non-printable characters";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::format("\"{}\"", string.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
using Bencode;
|
using Bencode;
|
||||||
@@ -57,6 +62,10 @@ namespace bencode {
|
|||||||
|
|
||||||
if (type == Type::Dictionary) {
|
if (type == Type::Dictionary) {
|
||||||
DictionaryEntry entry[while(std::mem::read_unsigned($, 1) != 'e')];
|
DictionaryEntry entry[while(std::mem::read_unsigned($, 1) != 'e')];
|
||||||
|
char end;
|
||||||
|
} else if (type == Type::List) {
|
||||||
|
Value entry[while(std::mem::read_unsigned($, 1) != 'e')];
|
||||||
|
char end;
|
||||||
} else if (type == Type::Integer) {
|
} else if (type == Type::Integer) {
|
||||||
ASCIIDecimal value;
|
ASCIIDecimal value;
|
||||||
char end;
|
char end;
|
||||||
|
|||||||
101
patterns/bgcode.hexpat
Normal file
101
patterns/bgcode.hexpat
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
#pragma author Shadlock0133 (aka Aurora) / WerWolv
|
||||||
|
#pragma description Prusa Binary G-Code
|
||||||
|
#pragma magic [ 47 43 44 45 ] @ 0x00
|
||||||
|
|
||||||
|
import type.magic;
|
||||||
|
import std.mem;
|
||||||
|
|
||||||
|
enum ChecksumType : u16 {
|
||||||
|
None = 0,
|
||||||
|
CRC32 = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BlockType : u16 {
|
||||||
|
FileMetadata = 0,
|
||||||
|
GCode = 1,
|
||||||
|
SlicerMetadata = 2,
|
||||||
|
PrinterMetadata = 3,
|
||||||
|
PrintMetadata = 4,
|
||||||
|
Thumbnail = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CompressionType : u16 {
|
||||||
|
NoCompression = 0,
|
||||||
|
Deflate = 1,
|
||||||
|
HeatshrinkWindowSize11 = 2,
|
||||||
|
HeatshrinkWindowSize12 = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BlockHeader {
|
||||||
|
BlockType type;
|
||||||
|
CompressionType compressionType;
|
||||||
|
u32 uncompressedSize;
|
||||||
|
|
||||||
|
if (compressionType != CompressionType::NoCompression) {
|
||||||
|
u32 compressedSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 dataSize = compressionType == CompressionType::NoCompression ? uncompressedSize : compressedSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Encoding : u16 {
|
||||||
|
INI = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Metadata {
|
||||||
|
Encoding encoding;
|
||||||
|
char data[parent.header.dataSize];
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ImageFormat : u16 {
|
||||||
|
PNG = 0,
|
||||||
|
JPG = 1,
|
||||||
|
QOI = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Thumbnail {
|
||||||
|
ImageFormat format;
|
||||||
|
u16 width, height;
|
||||||
|
std::mem::Bytes<parent.header.dataSize> imageData;
|
||||||
|
} [[hex::visualize("image", imageData)]];
|
||||||
|
|
||||||
|
enum GCodeEncoding : u16 {
|
||||||
|
NoEncoding = 0,
|
||||||
|
MeatPack = 1,
|
||||||
|
MeatPackWithComments = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GCode {
|
||||||
|
GCodeEncoding encoding;
|
||||||
|
|
||||||
|
std::mem::Bytes<parent.header.dataSize> gcode;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Block {
|
||||||
|
BlockHeader header;
|
||||||
|
|
||||||
|
match (header.type) {
|
||||||
|
(BlockType::FileMetadata): Metadata fileMetadata;
|
||||||
|
(BlockType::PrinterMetadata): Metadata printerMetadata;
|
||||||
|
(BlockType::Thumbnail): Thumbnail thumbnail;
|
||||||
|
(BlockType::PrintMetadata): Metadata printMetadata;
|
||||||
|
(BlockType::SlicerMetadata): Metadata slicerMetadata;
|
||||||
|
(BlockType::GCode): GCode gcode;
|
||||||
|
(_): std::error("Invalid Block type!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent.checksumType != ChecksumType::None)
|
||||||
|
u32 checksum;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BGCode {
|
||||||
|
type::Magic<"GCDE"> magic;
|
||||||
|
u32 version;
|
||||||
|
std::assert(version == 1, "Only Version 1 is supported");
|
||||||
|
|
||||||
|
ChecksumType checksumType;
|
||||||
|
|
||||||
|
Block blocks[while(!std::mem::eof())];
|
||||||
|
};
|
||||||
|
|
||||||
|
BGCode bgcode @ 0x00;
|
||||||
24
patterns/binka.hexpat
Normal file
24
patterns/binka.hexpat
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#pragma author DexrnZacAttack
|
||||||
|
#pragma description RAD Game Tools BINKA (Bink Audio)
|
||||||
|
#pragma magic [31 46 43 42] @ 0x00
|
||||||
|
|
||||||
|
import std.string;
|
||||||
|
import std.math;
|
||||||
|
import type.magic;
|
||||||
|
|
||||||
|
fn getDuration(u32 duration_ts, u32 sample_rate) {
|
||||||
|
return float(duration_ts) / float(sample_rate);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Binka {
|
||||||
|
type::Magic<"1FCB"> magic;
|
||||||
|
u8; // can't get this to change anything when using ffprobe
|
||||||
|
u8 channel_count [[name(std::format("Channel Count: {}", this))]];
|
||||||
|
u16 sample_rate [[name(std::format("Sample Rate: {}", this))]];
|
||||||
|
u32 duration_ts [[name(std::format("Duration: {}s", std::math::floor(getDuration(this, sample_rate))))]];
|
||||||
|
u32;
|
||||||
|
u32 size [[name(std::format("File Size: {} bytes", this))]];
|
||||||
|
u8 data[size - 20];
|
||||||
|
};
|
||||||
|
|
||||||
|
Binka binka @ 0x00;
|
||||||
196
patterns/blend.hexpat
Normal file
196
patterns/blend.hexpat
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
#pragma description Blender file
|
||||||
|
#pragma magic [42 4C 45 4E 44 45 52] @ 0x00
|
||||||
|
|
||||||
|
/*
|
||||||
|
* References:
|
||||||
|
* https://projects.blender.org/blender/blender
|
||||||
|
* https://github.com/facebook/zstd/blob/master/contrib/seekable_format/zstd_seekable_compression_format.md
|
||||||
|
*
|
||||||
|
* Refer to the following files/structs:
|
||||||
|
* source/blender/blenloader/intern/writefile.cc
|
||||||
|
* source/blender/blenkernel/BKE_main.hh BlendThumbnail
|
||||||
|
* source/blender/makesdna/DNA_sdna_types.h BHead
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Increased the pattern limit to be able to evaluate all pixels of the embedded thumbnail.
|
||||||
|
#pragma pattern_limit 1000000
|
||||||
|
|
||||||
|
#ifdef __IMHEX__
|
||||||
|
import hex.dec;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
import std.core;
|
||||||
|
import std.io;
|
||||||
|
import std.mem;
|
||||||
|
import std.string;
|
||||||
|
import std.sys;
|
||||||
|
import type.color;
|
||||||
|
import type.magic;
|
||||||
|
|
||||||
|
// Useful for extracting the thumbnail if the rest of the blend file is corrupted or truncated.
|
||||||
|
bool quitAfterThumbnailIsParsed in;
|
||||||
|
// Allow the pattern evaluator to skip the thumbnail e.g. if evaluation takes too long.
|
||||||
|
bool skipThumbnail in;
|
||||||
|
|
||||||
|
struct BHead<Ptr> {
|
||||||
|
char code[4];
|
||||||
|
s32 len;
|
||||||
|
Ptr old;
|
||||||
|
s32 SDNAnr;
|
||||||
|
s32 nr;
|
||||||
|
|
||||||
|
// ENDB marks the last data block in the file.
|
||||||
|
if (code == "ENDB") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ThumbnailLine<auto width> {
|
||||||
|
type::RGBA8 pixels[width];
|
||||||
|
};
|
||||||
|
|
||||||
|
fn copyThumbnail(u32 height, ref auto lines, std::mem::Section target) {
|
||||||
|
for (s64 l = (height - 1), l >= 0, l = l - 1) {
|
||||||
|
u64 currentSectionSize = std::mem::get_section_size(target);
|
||||||
|
// Append the current line to section.
|
||||||
|
std::mem::copy_value_to_section(lines[l], target, currentSectionSize);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Thumbnail {
|
||||||
|
u32 width;
|
||||||
|
u32 height;
|
||||||
|
u128 size = width * height;
|
||||||
|
ThumbnailLine<width> lines[height];
|
||||||
|
|
||||||
|
// Generate the thumbnail section.
|
||||||
|
std::mem::Section thumbnailFlipped = std::mem::create_section("thumbnail");
|
||||||
|
copyThumbnail(height, lines, thumbnailFlipped);
|
||||||
|
type::RGBA8 image[size] @ 0x00 in thumbnailFlipped;
|
||||||
|
}
|
||||||
|
#ifdef __IMHEX__
|
||||||
|
[[hex::visualize("bitmap", image, width, height)]]
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
struct DataBlock<Ptr> {
|
||||||
|
BHead<Ptr> bHead;
|
||||||
|
|
||||||
|
if (bHead.SDNAnr == 0 && bHead.code == "TEST") {
|
||||||
|
if (skipThumbnail) {
|
||||||
|
u8 thumbnail[bHead.len]; // Interpret as raw binary data.
|
||||||
|
} else {
|
||||||
|
Thumbnail thumbnail;
|
||||||
|
auto thumbnailSize = sizeof(thumbnail);
|
||||||
|
std::assert(thumbnailSize == bHead.len,
|
||||||
|
std::format("The thumbnail (size={:#x}) does not fit exactly into its DataBlock (len={:#x})!",
|
||||||
|
thumbnailSize, bHead.len));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (quitAfterThumbnailIsParsed) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
u8 data[bHead.len]; // Unknown. Interpret as raw binary data.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PointerSize : char {
|
||||||
|
POINTER_4BYTE = '_',
|
||||||
|
POINTER_8BYTE = '-'
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Endianness : char {
|
||||||
|
BIG_ENDIAN = 'V',
|
||||||
|
LITTLE_ENDIAN = 'v'
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Blend<auto inputSize> {
|
||||||
|
type::Magic<"BLENDER"> magic;
|
||||||
|
PointerSize pointerSize;
|
||||||
|
Endianness endianness;
|
||||||
|
char version[3];
|
||||||
|
|
||||||
|
match (endianness) {
|
||||||
|
(Endianness::LITTLE_ENDIAN): std::core::set_endian(std::mem::Endian::Little);
|
||||||
|
(Endianness::BIG_ENDIAN): std::core::set_endian(std::mem::Endian::Big);
|
||||||
|
(_): std::error("Invalid value for endianness!");
|
||||||
|
}
|
||||||
|
|
||||||
|
match (pointerSize) {
|
||||||
|
(PointerSize::POINTER_4BYTE): DataBlock<u32> dataBlock[while($ < inputSize)];
|
||||||
|
(PointerSize::POINTER_8BYTE): DataBlock<u64> dataBlock[while($ < inputSize)];
|
||||||
|
(_): std::error("Invalid pointer size!");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BlendWrapper {
|
||||||
|
u128 currentPos = $;
|
||||||
|
char magic[4] @ currentPos [[hidden]];
|
||||||
|
|
||||||
|
if (magic != "\x28\xB5\x2F\xFD") { // ZSTD magic
|
||||||
|
// Assume the blend file is uncompressed.
|
||||||
|
Blend<sizeof($)> blend @ currentPos;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} [[inline]];
|
||||||
|
|
||||||
|
BlendWrapper blendWrapper @ 0x00;
|
||||||
|
|
||||||
|
// Assume the blend file is ZSTD compressed.
|
||||||
|
|
||||||
|
struct SeekTableFooter {
|
||||||
|
u32 numFrames;
|
||||||
|
char flag;
|
||||||
|
type::Magic<"\xB1\xEA\x92\x8F"> footerMagic;
|
||||||
|
};
|
||||||
|
|
||||||
|
u128 seekTableFooterSize = 9;
|
||||||
|
SeekTableFooter seekTableFooter @ (sizeof($) - seekTableFooterSize);
|
||||||
|
|
||||||
|
struct SeekTableEntry {
|
||||||
|
u32 compressedSize;
|
||||||
|
u32 uncompressedSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
u128 seekTableEntrySize = 8;
|
||||||
|
SeekTableEntry seekTableEntries[seekTableFooter.numFrames]
|
||||||
|
@ (addressof(seekTableFooter) - seekTableFooter.numFrames * seekTableEntrySize);
|
||||||
|
|
||||||
|
struct SeekTableHeader {
|
||||||
|
type::Magic<"\x5E\x2A\x4D\x18"> magic;
|
||||||
|
u32 frameSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
u128 seekTableHeaderSize = 8;
|
||||||
|
std::assert(seekTableFooter.numFrames > 0, "The seek table must contain entries!");
|
||||||
|
SeekTableHeader seekTableHeader @ (addressof(seekTableEntries[0]) - seekTableHeaderSize);
|
||||||
|
|
||||||
|
u32 frameIndex = 0;
|
||||||
|
|
||||||
|
struct ZSTDFrame {
|
||||||
|
u8 data[seekTableEntries[frameIndex].compressedSize];
|
||||||
|
frameIndex = frameIndex + 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
ZSTDFrame zstdFrames[seekTableFooter.numFrames] @ 0x00;
|
||||||
|
|
||||||
|
#ifdef __IMHEX__
|
||||||
|
std::mem::Section decompressedSection = std::mem::create_section("decompressedBlend");
|
||||||
|
u128 previousSectionSize = 0;
|
||||||
|
|
||||||
|
for (u32 i = 0, i < seekTableFooter.numFrames, i = i + 1) {
|
||||||
|
std::assert(hex::dec::zstd_decompress(zstdFrames[i].data, decompressedSection),
|
||||||
|
"Decompression failed!");
|
||||||
|
u32 uncompressedSize = seekTableEntries[i].uncompressedSize;
|
||||||
|
u128 currentSectionSize = std::mem::get_section_size(decompressedSection)
|
||||||
|
- previousSectionSize;
|
||||||
|
std::assert_warn(uncompressedSize == currentSectionSize,
|
||||||
|
std::format("The uncompressedSize {} for ZSTDFrame #{} "
|
||||||
|
+ "must be equal to its actual decompressed size{}!",
|
||||||
|
uncompressedSize, i, currentSectionSize));
|
||||||
|
previousSectionSize += currentSectionSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
Blend<previousSectionSize> blend @ 0x00 in decompressedSection;
|
||||||
|
#endif
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
#pragma description OS2/Windows Bitmap files
|
#pragma description OS2/Windows Bitmap
|
||||||
|
|
||||||
#pragma MIME image/bmp
|
#pragma MIME image/bmp
|
||||||
#pragma endian little
|
#pragma endian little
|
||||||
#include <std/mem.pat>
|
import std.mem;
|
||||||
|
|
||||||
struct BitmapFileHeader {
|
struct BitmapFileHeader {
|
||||||
u8 bfType[2];
|
u8 bfType[2];
|
||||||
|
|||||||
274
patterns/bplist.hexpat
Normal file
274
patterns/bplist.hexpat
Normal file
@@ -0,0 +1,274 @@
|
|||||||
|
#pragma description Apple binary property list
|
||||||
|
#pragma MIME application/x-bplist
|
||||||
|
|
||||||
|
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;
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
#pragma author WerWolv
|
#pragma author WerWolv
|
||||||
#pragma description BSON (Binary JSON) format
|
#pragma description BSON (Binary JSON)
|
||||||
|
|
||||||
#pragma MIME application/bson
|
#pragma MIME application/bson
|
||||||
|
|
||||||
#include <std/mem.pat>
|
import std.mem;
|
||||||
#include <type/time.pat>
|
import type.time;
|
||||||
|
|
||||||
enum Type : u8 {
|
enum Type : u8 {
|
||||||
Double = 0x01,
|
Double = 0x01,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#pragma description GoldSrc engine maps format (used in Half-Life 1)
|
#pragma description GoldSrc engine map (Half-Life 1)
|
||||||
|
|
||||||
#include <std/ptr.pat>
|
import std.ptr;
|
||||||
#include <std/mem.pat>
|
import std.mem;
|
||||||
#include <std/sys.pat>
|
import std.sys;
|
||||||
|
|
||||||
#pragma endian little
|
#pragma endian little
|
||||||
|
|
||||||
|
|||||||
64
patterns/bzip3.hexpat
Normal file
64
patterns/bzip3.hexpat
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#pragma author Sewer56
|
||||||
|
#pragma description Parses BZip3 compression (file format) by Kamila Szewczyk
|
||||||
|
#pragma MIME application/x-bzip3
|
||||||
|
#pragma endian little
|
||||||
|
#pragma magic [42 5A 33 76 31] @ 0x00
|
||||||
|
import std.mem;
|
||||||
|
|
||||||
|
// Helper function for bit counting
|
||||||
|
fn popcount(u8 b) {
|
||||||
|
u32 count = 0;
|
||||||
|
while (b != 0) {
|
||||||
|
count = count + (b & 1);
|
||||||
|
b = b >> 1;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Frame header structure
|
||||||
|
struct FrameHeader {
|
||||||
|
char magic[5]; // "BZ3v1"
|
||||||
|
u32 blockSize; // Maximum block size
|
||||||
|
};
|
||||||
|
|
||||||
|
// Small block header (for blocks < 64 bytes)
|
||||||
|
struct SmallBlock {
|
||||||
|
u32 crc32; // CRC32 checksum
|
||||||
|
u32 literal; // Always 0xFFFFFFFF for small blocks
|
||||||
|
u8 data[parent.compressedSize - 8]; // Uncompressed data
|
||||||
|
};
|
||||||
|
|
||||||
|
// Regular block (blocks > 64 bytes)
|
||||||
|
struct Block {
|
||||||
|
u32 crc32; // CRC32 checksum of uncompressed data
|
||||||
|
u32 bwtIndex; // Burrows-Wheeler transform index
|
||||||
|
u8 model; // Compression model flags
|
||||||
|
|
||||||
|
if ((model & 0x02) != 0)
|
||||||
|
u32 lzpSize; // Size after LZP compression
|
||||||
|
if ((model & 0x04) != 0)
|
||||||
|
u32 rleSize; // Size after RLE compression
|
||||||
|
|
||||||
|
u8 data[parent.compressedSize - (popcount(model) * 4 + 9)];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Main block structure
|
||||||
|
struct Chunk {
|
||||||
|
u32 compressedSize; // Size of compressed block
|
||||||
|
u32 origSize; // Original uncompressed size
|
||||||
|
|
||||||
|
if (origSize < 64) {
|
||||||
|
SmallBlock block;
|
||||||
|
} else {
|
||||||
|
Block block;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Main parsing structure
|
||||||
|
struct BZip3File {
|
||||||
|
FrameHeader header;
|
||||||
|
// Read blocks until end of file
|
||||||
|
Chunk chunks[while(!std::mem::eof())];
|
||||||
|
};
|
||||||
|
|
||||||
|
BZip3File file @ 0x0;
|
||||||
110
patterns/cab.hexpat
Normal file
110
patterns/cab.hexpat
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
#pragma author The Wandering Trader
|
||||||
|
#pragma description Microsoft Cabinet (CAB) Files
|
||||||
|
#pragma magic [4D 53 43 46] @ 0x00
|
||||||
|
|
||||||
|
import type.time;
|
||||||
|
import type.magic;
|
||||||
|
import type.size;
|
||||||
|
|
||||||
|
fn format_string(auto string) {
|
||||||
|
return std::format("{}",string);
|
||||||
|
};
|
||||||
|
|
||||||
|
bitfield flags {
|
||||||
|
bool cfhdrPREV_CABINET : 1;
|
||||||
|
bool cfhdrNEXT_CABINET : 1;
|
||||||
|
bool cfhdrRESERVE_PRESENT : 1;
|
||||||
|
padding : 13;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CFHEADER {
|
||||||
|
type::Magic<"MSCF"> signature;
|
||||||
|
u32 reserved1;
|
||||||
|
type::Size32 cbCabinet;
|
||||||
|
u32 reserved2;
|
||||||
|
u32 coffFiles;
|
||||||
|
u32 reserved3;
|
||||||
|
u8 versionMajor;
|
||||||
|
u8 versionMinor;
|
||||||
|
u16 cFolders;
|
||||||
|
u16 cFiles;
|
||||||
|
flags flags;
|
||||||
|
u16 setID;
|
||||||
|
u16 iCabinet;
|
||||||
|
if (flags.cfhdrRESERVE_PRESENT) {
|
||||||
|
type::Size16 cbCFHeader;
|
||||||
|
type::Size8 cbCFFolder;
|
||||||
|
type::Size8 cbCFData;
|
||||||
|
u8 abReserve[cbCFHeader];
|
||||||
|
}
|
||||||
|
if (flags.cfhdrPREV_CABINET) {
|
||||||
|
char szCabinetPrev[] [[format("format_string")]];
|
||||||
|
char szDiskPrev[] [[format("format_string")]];
|
||||||
|
}
|
||||||
|
if (flags.cfhdrNEXT_CABINET) {
|
||||||
|
char szCabinetNext[] [[format("format_string")]];
|
||||||
|
char szDiskNext[] [[format("format_string")]];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum typeCompress : u8{
|
||||||
|
tcompMASK_TYPE = 0x000F,
|
||||||
|
tcompTYPE_NONE = 0x0000,
|
||||||
|
tcompTYPE_MSZIP = 0x0001,
|
||||||
|
tcompTYPE_QUANTUM = 0x0002,
|
||||||
|
tcompTYPE_LZX = 0x0003,
|
||||||
|
};
|
||||||
|
|
||||||
|
using CFDATA;
|
||||||
|
|
||||||
|
struct CFFOLDER {
|
||||||
|
u32 coffCabStart;
|
||||||
|
u16 cCfData;
|
||||||
|
typeCompress typeCompress;
|
||||||
|
u8 compressionLevel;
|
||||||
|
if (CFHEADER.flags.cfhdrRESERVE_PRESENT) {
|
||||||
|
u8 abReserve[CFHEADER.cbCFFolder];
|
||||||
|
}
|
||||||
|
CFDATA CFDATA[cCfData] @ coffCabStart;
|
||||||
|
};
|
||||||
|
|
||||||
|
bitfield attribs {
|
||||||
|
bool _A_RDONLY : 1;
|
||||||
|
bool _A_HIDDEN : 1;
|
||||||
|
bool _A_SYSTEM : 1;
|
||||||
|
padding : 2;
|
||||||
|
bool _A_ARCH : 1;
|
||||||
|
bool _A_EXEC : 1;
|
||||||
|
bool _A_NAME_IS_UTF : 1;
|
||||||
|
padding : 8;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CFFILE {
|
||||||
|
type::Size32 cbFile;
|
||||||
|
u32 uoffFolderStart;
|
||||||
|
u16 iFolder;
|
||||||
|
type::DOSDate date;
|
||||||
|
type::DOSTime time;
|
||||||
|
attribs attribs;
|
||||||
|
if (attribs._A_NAME_IS_UTF) {
|
||||||
|
char16 szName[];
|
||||||
|
} else {
|
||||||
|
char szName[] [[format("format_string")]];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CFDATA {
|
||||||
|
u32 csum;
|
||||||
|
type::Size16 cbData;
|
||||||
|
type::Size16 cbUncomp;
|
||||||
|
if (CFHEADER.flags.cfhdrRESERVE_PRESENT) {
|
||||||
|
u8 abReserve[CFHEADER.cbCFData];
|
||||||
|
}
|
||||||
|
u8 ab[cbData];
|
||||||
|
};
|
||||||
|
|
||||||
|
CFHEADER CFHEADER @ 0;
|
||||||
|
CFFOLDER CFFOLDER[CFHEADER.cFolders] @ $;
|
||||||
|
CFFILE CFFILE[CFHEADER.cFiles] @ $;
|
||||||
@@ -1,29 +1,29 @@
|
|||||||
#pragma description Compact Disc Audio track
|
#pragma description Compact Disc Audio track
|
||||||
|
#pragma magic [ 52 49 46 46 ] @ 0x00
|
||||||
|
|
||||||
struct Header {
|
struct Header {
|
||||||
u32 RIFF;
|
u32 RIFF;
|
||||||
s32 size;
|
s32 size;
|
||||||
u32 CDDA;
|
u32 CDDA;
|
||||||
u32 fmt;
|
u32 fmt;
|
||||||
u32 lenghtofthechunck;
|
u32 lenghtofthechunck;
|
||||||
u16 versionofcdformat;
|
u16 versionofcdformat;
|
||||||
u16 numberofrange;
|
u16 numberofrange;
|
||||||
u32 identifier;
|
u32 identifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct DataInfo {
|
struct DataInfo {
|
||||||
|
u32 range;
|
||||||
u32 range;
|
u32 duration;
|
||||||
u32 duration;
|
u8 rangepositionframes;
|
||||||
u8 rangepositionframes;
|
u8 rangepositionseconds;
|
||||||
u8 rangepositionseconds;
|
u8 rangepositionminutes;
|
||||||
u8 rangepositionminutes;
|
u8 nullbyte;
|
||||||
u8 nullbyte;
|
u8 durationtrackframes;
|
||||||
u8 durationtrackframes;
|
u8 durationtrackseconds;
|
||||||
u8 durationtrackseconds;
|
u8 durationtrackminutes;
|
||||||
u8 durationtrackminutes;
|
u8 nullbytee;
|
||||||
u8 nullbytee;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
105
patterns/chd.hexpat
Normal file
105
patterns/chd.hexpat
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
#pragma author Lexi Mayfield
|
||||||
|
#pragma description MAME Compressed Hunks of Data
|
||||||
|
#pragma endian big
|
||||||
|
|
||||||
|
fn CHD_MAKE_TAG(char a, char b, char c, char d) {
|
||||||
|
return (u32(u8(a)) << 24) |
|
||||||
|
u32(u8((b)) << 16) |
|
||||||
|
u32(u8((c)) << 8) |
|
||||||
|
u32(u8(d));
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CHDv5_CODEC : u32 {
|
||||||
|
NONE = 0,
|
||||||
|
ZLIB = CHD_MAKE_TAG('z','l','i','b'),
|
||||||
|
ZSTD = CHD_MAKE_TAG('z','s','t','d'),
|
||||||
|
LZMA = CHD_MAKE_TAG('l','z','m','a'),
|
||||||
|
HUFFMAN = CHD_MAKE_TAG('h','u','f','f'),
|
||||||
|
FLAC = CHD_MAKE_TAG('f','l','a','c'),
|
||||||
|
CD_ZLIB = CHD_MAKE_TAG('c','d','z','l'),
|
||||||
|
CD_ZSTD = CHD_MAKE_TAG('c','d','z','s'),
|
||||||
|
CD_LZMA = CHD_MAKE_TAG('c','d','l','z'),
|
||||||
|
CD_FLAC = CHD_MAKE_TAG('c','d','f','l'),
|
||||||
|
AVHUFF = CHD_MAKE_TAG('a','v','h','u'),
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CHDv5_METADATA_TAG : u32 {
|
||||||
|
CHDMETATAG_WILDCARD = 0,
|
||||||
|
HARD_DISK_METADATA_TAG = CHD_MAKE_TAG('G','D','D','D'),
|
||||||
|
HARD_DISK_IDENT_METADATA_TAG = CHD_MAKE_TAG('I','D','N','T'),
|
||||||
|
HARD_DISK_KEY_METADATA_TAG = CHD_MAKE_TAG('K','E','Y',' '),
|
||||||
|
PCMCIA_CIS_METADATA_TAG = CHD_MAKE_TAG('C','I','S',' '),
|
||||||
|
CDROM_OLD_METADATA_TAG = CHD_MAKE_TAG('C','H','C','D'),
|
||||||
|
CDROM_TRACK_METADATA_TAG = CHD_MAKE_TAG('C','H','T','R'),
|
||||||
|
CDROM_TRACK_METADATA2_TAG = CHD_MAKE_TAG('C','H','T','2'),
|
||||||
|
GDROM_OLD_METADATA_TAG = CHD_MAKE_TAG('C','H','G','T'),
|
||||||
|
GDROM_TRACK_METADATA_TAG = CHD_MAKE_TAG('C','H','G','D'),
|
||||||
|
DVD_METADATA_TAG = CHD_MAKE_TAG('D','V','D',' '),
|
||||||
|
AV_METADATA_TAG = CHD_MAKE_TAG('A','V','A','V'),
|
||||||
|
AV_LD_METADATA_TAG = CHD_MAKE_TAG('A','V','L','D'),
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CHDv5UncompressedMap {
|
||||||
|
u32 offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CHDv5CompressedMapEntry {
|
||||||
|
u8 compression;
|
||||||
|
u24 complength;
|
||||||
|
u48 offset;
|
||||||
|
u16 crc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CHDv5CompressedMap {
|
||||||
|
u32 length;
|
||||||
|
u48 datastart;
|
||||||
|
u16 crc;
|
||||||
|
u8 lengthbits;
|
||||||
|
u8 hunkbits;
|
||||||
|
u8 parentunitbits;
|
||||||
|
u8 reserved;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CHDv5MetadataEntry {
|
||||||
|
CHDv5_METADATA_TAG metatag;
|
||||||
|
u8 flags;
|
||||||
|
u24 length;
|
||||||
|
u64 next;
|
||||||
|
char entry[length];
|
||||||
|
|
||||||
|
if (next != 0) {
|
||||||
|
CHDv5MetadataEntry nextMeta @ next;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CHDv5 {
|
||||||
|
CHDv5_CODEC compressors[4];
|
||||||
|
u64 logicalbytes;
|
||||||
|
u64 mapoffset;
|
||||||
|
u64 metaoffset;
|
||||||
|
u32 hunkbytes;
|
||||||
|
u32 unitbytes;
|
||||||
|
u8 rawsha1[20];
|
||||||
|
u8 sha1[20];
|
||||||
|
u8 parentsha1[20];
|
||||||
|
|
||||||
|
if (compressors[0] == CHDv5_CODEC::NONE) {
|
||||||
|
CHDv5UncompressedMap map @ mapoffset;
|
||||||
|
} else {
|
||||||
|
CHDv5CompressedMap map @ mapoffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHDv5MetadataEntry meta @ metaoffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CHD {
|
||||||
|
char tag[8];
|
||||||
|
u32 length;
|
||||||
|
u32 version;
|
||||||
|
|
||||||
|
if (version == 5) {
|
||||||
|
CHDv5 chd;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CHD chd @ 0x00;
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
#pragma author WerWolv
|
#pragma author WerWolv
|
||||||
#pragma description Windows HtmlHelp Data (ITSF / CHM)
|
#pragma description Windows HtmlHelp Data (ITSF / CHM)
|
||||||
|
#pragma MIME application/vnd.ms-htmlhelp
|
||||||
|
|
||||||
#include <type/magic.pat>
|
import type.magic;
|
||||||
#include <type/size.pat>
|
import type.size;
|
||||||
#include <type/guid.pat>
|
import type.guid;
|
||||||
#include <type/leb128.pat>
|
import type.leb128;
|
||||||
#include <std/sys.pat>
|
import std.sys;
|
||||||
|
|
||||||
enum WindowsLanguageId : u32 {
|
enum WindowsLanguageId : u32 {
|
||||||
Arabic_SaudiArabia = 0x401,
|
Arabic_SaudiArabia = 0x401,
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
#pragma MIME application/x-coff
|
#pragma MIME application/x-coff
|
||||||
|
|
||||||
#include <type/time.pat>
|
import type.time;
|
||||||
#include <type/size.pat>
|
import type.size;
|
||||||
|
|
||||||
enum Machine : u16 {
|
enum Machine : u16 {
|
||||||
Unknown = 0x0000,
|
Unknown = 0x0000,
|
||||||
@@ -164,7 +164,10 @@ bitfield SectionFlags {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fn format_alignment(u8 alignment) {
|
fn format_alignment(u8 alignment) {
|
||||||
return 1 << alignment;
|
if(alignment > 0) {
|
||||||
|
return 1 << (alignment - 1);
|
||||||
|
}
|
||||||
|
return alignment;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Relocations {
|
struct Relocations {
|
||||||
|
|||||||
158
patterns/commodore_basic.hexpat
Normal file
158
patterns/commodore_basic.hexpat
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
#pragma description Commodore BASIC
|
||||||
|
#pragma author Stephen Hewitt
|
||||||
|
|
||||||
|
import std.io;
|
||||||
|
import std.mem;
|
||||||
|
|
||||||
|
bool in_quotes = false;
|
||||||
|
|
||||||
|
le u16 LoadAddress @0 [[color("ff0000")]];
|
||||||
|
|
||||||
|
fn formatll(u16 offset) {
|
||||||
|
if (offset&0xff00 == 0)
|
||||||
|
return "No next line";
|
||||||
|
u16 fo = offset-LoadAddress+2;
|
||||||
|
return std::format("Next line: ${:04X} (offset ${:04X})", offset, fo);
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Token : u8 {
|
||||||
|
END = 0x80,
|
||||||
|
FOR = 0x81,
|
||||||
|
NEXT = 0x82,
|
||||||
|
DATA = 0x83,
|
||||||
|
INPUT_ = 0x84,
|
||||||
|
INPUT = 0x85,
|
||||||
|
DIM = 0x86,
|
||||||
|
READ = 0x87,
|
||||||
|
LET = 0x88,
|
||||||
|
GOTO = 0x89,
|
||||||
|
RUN = 0x8a,
|
||||||
|
IF = 0x8b,
|
||||||
|
RESTORE = 0x8c,
|
||||||
|
GOSUB = 0x8d,
|
||||||
|
RETURN = 0x8e,
|
||||||
|
REM = 0x8f,
|
||||||
|
STOP = 0x90,
|
||||||
|
ON = 0x91,
|
||||||
|
WAIT = 0x92,
|
||||||
|
LOAD = 0x93,
|
||||||
|
SAVE = 0x94,
|
||||||
|
VERIFY = 0x95,
|
||||||
|
DEF = 0x96,
|
||||||
|
POKE = 0x97,
|
||||||
|
PRINT_ = 0x98,
|
||||||
|
PRINT = 0x99,
|
||||||
|
CONT = 0x9a,
|
||||||
|
LIST = 0x9b,
|
||||||
|
CLR = 0x9c,
|
||||||
|
CMD = 0x9d,
|
||||||
|
SYS = 0x9e,
|
||||||
|
OPEN = 0x9f,
|
||||||
|
CLOSE = 0xa0,
|
||||||
|
GET = 0xa1,
|
||||||
|
NEW = 0xa2,
|
||||||
|
TAB_ = 0xa3,
|
||||||
|
TO = 0xa4,
|
||||||
|
FN = 0xa5,
|
||||||
|
SPC_ = 0xa6,
|
||||||
|
THEN = 0xa7,
|
||||||
|
NOT = 0xa8,
|
||||||
|
STEP = 0xa9,
|
||||||
|
PLUS_ = 0xaa,
|
||||||
|
MINUS_ = 0xab,
|
||||||
|
TIMES_ = 0xac,
|
||||||
|
DIVIDE_ = 0xad,
|
||||||
|
POW_ = 0xae,
|
||||||
|
AND = 0xaf,
|
||||||
|
OR = 0xb0,
|
||||||
|
GT_ = 0xb1,
|
||||||
|
EQ_ = 0xb2,
|
||||||
|
LT_ = 0xb3,
|
||||||
|
SGN = 0xb4,
|
||||||
|
INT = 0xb5,
|
||||||
|
ABS = 0xb6,
|
||||||
|
USR = 0xb7,
|
||||||
|
FRE = 0xb7,
|
||||||
|
POS = 0xb9,
|
||||||
|
SQR = 0xba,
|
||||||
|
RND = 0xbb,
|
||||||
|
LOG = 0xbc,
|
||||||
|
EXP = 0xbd,
|
||||||
|
COS = 0xbe,
|
||||||
|
SIN = 0xbf,
|
||||||
|
TAN = 0xc0,
|
||||||
|
ATN = 0xc1,
|
||||||
|
PEEK = 0xc2,
|
||||||
|
LEN = 0xc3,
|
||||||
|
STR_ = 0xc4,
|
||||||
|
VAL = 0xc5,
|
||||||
|
ASC = 0xc6,
|
||||||
|
CHR_ = 0xc7,
|
||||||
|
LEFT_ = 0xc8,
|
||||||
|
RIGHT_ = 0xc9,
|
||||||
|
MID_ = 0xca,
|
||||||
|
PI_ = 0xff
|
||||||
|
} [[format("formate")]];
|
||||||
|
|
||||||
|
// Can't seem to put attributes on enum members. Hack around it.
|
||||||
|
fn formate(Token t) {
|
||||||
|
match (t) {
|
||||||
|
(Token::INPUT_): return "INPUT#"; // $84
|
||||||
|
(Token::PRINT_): return "PRINT#"; // $98
|
||||||
|
(Token::TAB_): return "TAB("; // $a3
|
||||||
|
(Token::SPC_): return "SPC("; // $a6
|
||||||
|
(Token::PLUS_): return "+"; // $aa
|
||||||
|
(Token::MINUS_): return "-"; // $ab
|
||||||
|
(Token::TIMES_): return "*"; // $ac
|
||||||
|
(Token::DIVIDE_): return "/"; // $ad
|
||||||
|
//(Token::POW_): return "↑"; // $ae
|
||||||
|
(Token::GT_): return ">"; // $b1
|
||||||
|
(Token::EQ_): return "="; // $b2
|
||||||
|
(Token::LT_): return "<"; // $b3
|
||||||
|
(Token::STR_): return "STR$"; // $c4
|
||||||
|
(Token::CHR_): return "CHR$"; // $c7
|
||||||
|
(Token::LEFT_): return "LEFT$"; // $c8
|
||||||
|
(Token::RIGHT_): return "RIGHT$"; // $c9
|
||||||
|
(Token::MID_): return "MID$"; // $ca
|
||||||
|
//(Token::PI_): return "π"; // $ff
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn NotZero() {
|
||||||
|
u8 b = std::mem::read_unsigned($, 1);
|
||||||
|
return b!=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn IsToken() {
|
||||||
|
u8 b = std::mem::read_unsigned($, 1);
|
||||||
|
return b&0x80!=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn IsPETSCII() {
|
||||||
|
u8 b = std::mem::read_unsigned($, 1);
|
||||||
|
if (b == '"')
|
||||||
|
in_quotes = !in_quotes;
|
||||||
|
return (b!=0) && (in_quotes || (b&0x80)==0);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LineSegment
|
||||||
|
{
|
||||||
|
Token tokens[while(IsToken())] [[color("a040a0")]];
|
||||||
|
char petscii[while(IsPETSCII())] [[color("a0a0a0")]];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Line
|
||||||
|
{
|
||||||
|
in_quotes = false;
|
||||||
|
|
||||||
|
u16 next [[color("8080ff"), format("formatll")]];
|
||||||
|
if (next&0xff00 == 0)
|
||||||
|
break;
|
||||||
|
le u16 line_number [[color("00FF00")]];
|
||||||
|
LineSegment contents[while(NotZero())];
|
||||||
|
u8 eol [[color("00ffff")]];
|
||||||
|
};
|
||||||
|
|
||||||
|
Line Lines[while(!std::mem::eof())] @ 2;
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
#pragma author WerWolv
|
#pragma author WerWolv
|
||||||
#pragma description Old Binary CPIO Format
|
#pragma description Old Binary CPIO
|
||||||
|
|
||||||
#include <type/base.pat>
|
import type.base;
|
||||||
|
|
||||||
#include <std/time.pat>
|
import std.time;
|
||||||
#include <std/core.pat>
|
import std.core;
|
||||||
#include <std/sys.pat>
|
import std.sys;
|
||||||
#include <std/mem.pat>
|
import std.mem;
|
||||||
|
|
||||||
#pragma MIME application/x-cpio
|
#pragma MIME application/x-cpio
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ namespace old_binary {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fn format_time(u32 value) {
|
fn format_time(u32 value) {
|
||||||
return std::time::format(std::time::to_utc(swap_32bit(value)));
|
return std::time::format(std::time::to_utc(old_binary::swap_32bit(value)));
|
||||||
};
|
};
|
||||||
|
|
||||||
using SwappedU32 = u32 [[transform("old_binary::swap_32bit"), format("old_binary::swap_32bit")]];
|
using SwappedU32 = u32 [[transform("old_binary::swap_32bit"), format("old_binary::swap_32bit")]];
|
||||||
|
|||||||
99
patterns/credhist.hexpat
Normal file
99
patterns/credhist.hexpat
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
#pragma description "CREDHIST"
|
||||||
|
|
||||||
|
/*
|
||||||
|
FilePath: C:\Users\<USER>\AppData\Roaming\Microsoft\Protect\
|
||||||
|
The files/folders are hidden.
|
||||||
|
|
||||||
|
To unhide it
|
||||||
|
1. Open Command Prompt (cmd.exe).
|
||||||
|
2. Run the following command:
|
||||||
|
=> attrib -h -s
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type.guid;
|
||||||
|
import std.mem;
|
||||||
|
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/seccrypto/alg-id
|
||||||
|
enum ALG_ID : u32 {
|
||||||
|
CALG_DH_EPHEM = 0x0000aa02, // Diffie-Hellman ephemeral key exchange algorithm.
|
||||||
|
CALG_DH_SF = 0x0000aa01, // Diffie-Hellman store and forward key exchange algorithm.
|
||||||
|
CALG_DSS_SIGN = 0x00002200, // DSA public key signature algorithm.
|
||||||
|
CALG_ECDH = 0x0000aa05, // Elliptic curve Diffie-Hellman key exchange algorithm.
|
||||||
|
CALG_ECDH_EPHEM = 0x0000ae06, // Ephemeral elliptic curve Diffie-Hellman key exchange algorithm.
|
||||||
|
CALG_ECDSA = 0x00002203, // Elliptic curve digital signature algorithm.
|
||||||
|
CALG_ECMQV = 0x0000a001, // Elliptic curve Menezes, Qu, and Vanstone (MQV) key exchange algorithm.
|
||||||
|
CALG_HASH_REPLACE_OWF = 0x0000800b, // One way function hashing algorithm.
|
||||||
|
CALG_HUGHES_MD5 = 0x0000a003, // Hughes MD5 hashing algorithm.
|
||||||
|
CALG_HMAC = 0x00008009, // HMAC keyed hash algorithm.
|
||||||
|
CALG_KEA_KEYX = 0x0000aa04, // KEA key exchange algorithm (FORTEZZA).
|
||||||
|
CALG_MAC = 0x00008005, // MAC keyed hash algorithm.
|
||||||
|
CALG_MD2 = 0x00008001, // MD2 hashing algorithm.
|
||||||
|
CALG_MD4 = 0x00008002, // MD4 hashing algorithm.
|
||||||
|
CALG_MD5 = 0x00008003, // MD5 hashing algorithm.
|
||||||
|
CALG_NO_SIGN = 0x00002000, // No signature algorithm.
|
||||||
|
CALG_OID_INFO_CNG_ONLY = 0xffffffff, // Algorithm is only implemented in CNG.
|
||||||
|
CALG_OID_INFO_PARAMETERS = 0xfffffffe, // Algorithm is defined in the encoded parameters.
|
||||||
|
CALG_PCT1_MASTER = 0x00004c04, // Used by the Schannel.dll operations system.
|
||||||
|
CALG_RC2 = 0x00006602, // RC2 block encryption algorithm.
|
||||||
|
CALG_RC4 = 0x00006801, // RC4 stream encryption algorithm.
|
||||||
|
CALG_RC5 = 0x0000660d, // RC5 block encryption algorithm.
|
||||||
|
CALG_RSA_KEYX = 0x0000a400, // RSA public key exchange algorithm.
|
||||||
|
CALG_RSA_SIGN = 0x00002400, // RSA public key signature algorithm.
|
||||||
|
CALG_SCHANNEL_ENC_KEY = 0x00004c07, // Used by the Schannel.dll operations system.
|
||||||
|
CALG_SCHANNEL_MAC_KEY = 0x00004c03, // Used by the Schannel.dll operations system.
|
||||||
|
CALG_SCHANNEL_MASTER_HASH = 0x00004c02, // Used by the Schannel.dll operations system.
|
||||||
|
CALG_SEAL = 0x00006802, // SEAL encryption algorithm.
|
||||||
|
CALG_SHA = 0x00008004, // SHA hashing algorithm.
|
||||||
|
CALG_SHA1 = 0x00008004, // Same as CALG_SHA.
|
||||||
|
CALG_SHA_256 = 0x0000800c, // 256-bit SHA hashing algorithm.
|
||||||
|
CALG_SHA_384 = 0x0000800d, // 384-bit SHA hashing algorithm.
|
||||||
|
CALG_SHA_512 = 0x0000800e, // 512-bit SHA hashing algorithm.
|
||||||
|
CALG_SKIPJACK = 0x0000660a, // Skipjack block encryption algorithm (FORTEZZA).
|
||||||
|
CALG_SSL2_MASTER = 0x00004c05, // Used by the Schannel.dll operations system.
|
||||||
|
CALG_SSL3_MASTER = 0x00004c01, // Used by the Schannel.dll operations system.
|
||||||
|
CALG_SSL3_SHAMD5 = 0x00008008, // Used by the Schannel.dll operations system.
|
||||||
|
CALG_TEK = 0x0000660b, // TEK (FORTEZZA).
|
||||||
|
CALG_TLS1_MASTER = 0x00004c06, // Used by the Schannel.dll operations system.
|
||||||
|
CALG_TLS1PRF = 0x0000800a // Used by the Schannel.dll operations system.
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://devblogs.microsoft.com/oldnewthing/20040315-00/?p=40253
|
||||||
|
struct SID {
|
||||||
|
u8 revisionlvl[[name("RevisionLevel"), comment("SID_REVISION")]];
|
||||||
|
u8 dashes[[name("NoOfDashes"), comment("number of dashes minus two")]]; // dashes = actualdashes - 0x2
|
||||||
|
char ntauth[0x6][[name("NtAuthority"), comment("SECURITY_NT_AUTHORITY")]];
|
||||||
|
u32 subatuh1[[name("SubAuthority1"), comment("SECURITY_NT_NON_UNIQUE")]];
|
||||||
|
u32 subatuh2[[name("SubAuthority2"), comment("these identify the machine that issued the SID")]];
|
||||||
|
u32 subatuh3[[name("SubAuthority3"), comment("these identify the machine that issued the SID")]];
|
||||||
|
u32 subatuh4[[name("SubAuthority4"), comment("these identify the machine that issued the SID")]];
|
||||||
|
u32 rid[[name("RID"), comment("unique user id on the machine")]];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct CREDHIST_HEADER{
|
||||||
|
u32 version[[name("Version")]];
|
||||||
|
type::GUID guid[[name("GUID")]];
|
||||||
|
u32 nextlen[[name("NextCredSize")]];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CREDHIST {
|
||||||
|
CREDHIST_HEADER credheader[[name("CredHistHeader")]];
|
||||||
|
if (std::mem::eof()){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
u32 flgas [[name("Flags")]];
|
||||||
|
ALG_ID alghashid[[name("AlgorithmHashId")]];
|
||||||
|
u32 rounds [[name("Rounds")]];
|
||||||
|
u32 sidlen [[name("SIDLen")]];
|
||||||
|
ALG_ID algcryptid[[name("AlgorithmCryptId")]];
|
||||||
|
u32 sha1len[[name("SHA1Len")]];
|
||||||
|
u32 md4len[[name("ntlmlen")]];
|
||||||
|
char salt[0x10][[name("Salt")]];
|
||||||
|
SID sid[[name("SID")]];
|
||||||
|
char sha1hash[sha1len][[name("SHA1Hash")]];
|
||||||
|
char md4hash[md4len][[name("NTLMHash")]];
|
||||||
|
u64 unk1[[name("Unknown")]];
|
||||||
|
};
|
||||||
|
|
||||||
|
CREDHIST credhist [while(!std::mem::eof())] @ 0x0[[name("CredHist")]];
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma description DirectDraw Surface
|
#pragma description DirectDraw Surface
|
||||||
|
|
||||||
#pragma MIME image/vnd-ms.dds
|
#pragma MIME image/vnd-ms.dds
|
||||||
|
#pragma MIME image/x-dds
|
||||||
#pragma endian little
|
#pragma endian little
|
||||||
|
|
||||||
enum DXGI_FORMAT : u32 {
|
enum DXGI_FORMAT : u32 {
|
||||||
@@ -167,16 +168,26 @@ bitfield Caps2Flags {
|
|||||||
};
|
};
|
||||||
|
|
||||||
bitfield PixelFormatFlags {
|
bitfield PixelFormatFlags {
|
||||||
alphaPixels : 1;
|
alphaPixels : 1; // DDPF_ALPHAPIXELS
|
||||||
alpha : 1;
|
alpha : 1; // DDPF_ALPHA
|
||||||
fourCC : 1;
|
fourCC : 1; // DDPF_FOURCC
|
||||||
padding : 3;
|
paletteIndexed4 : 1; // DDPF_PALETTEINDEXED4
|
||||||
rgb : 1; // 0x40
|
paletteIndexedTo8 : 1; // DDPF_PALETTEINDEXEDTO8
|
||||||
padding : 2;
|
paletteIndexed8 : 1; // DDPF_PALETTEINDEXED8
|
||||||
yuv : 1; // 0x200
|
rgb : 1; // DDPF_RGB
|
||||||
padding : 3;
|
compressed : 1; // DDPF_COMPRESSED
|
||||||
luminance : 1; // 0x20000
|
rgbToYuv : 1; // DDPF_RGBTOYUV
|
||||||
padding : 17;
|
yuv : 1; // DDPF_YUV
|
||||||
|
zBuffer : 1; // DDPF_ZBUFFER
|
||||||
|
paletteIndexed1 : 1; // DDPF_PALETTEINDEXED1
|
||||||
|
paletteIndexed2 : 1; // DDPF_PALETTEINDEXED2
|
||||||
|
zPixels : 1; // DDPF_ZPIXELS
|
||||||
|
stencilBuffer : 1; // DDPF_STENCILBUFFER
|
||||||
|
alphaResult : 1; // DDPF_ALPHARESULT
|
||||||
|
luminance : 1; // DDPF_LUMINANCE
|
||||||
|
bumpLuminance : 1; // DDPF_BUMPLUMINANCE
|
||||||
|
bumpDudv : 1; // DDPF_BUMPDUDV
|
||||||
|
padding : 13; // Padding bits to complete 32-bit structure
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DX10ResourceDimension : u32 {
|
enum DX10ResourceDimension : u32 {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma description Dalvik EXecutable Format
|
#pragma description Dalvik EXecutable
|
||||||
|
#pragma magic [ 64 65 78 0A ?? ?? ?? 00 ]
|
||||||
|
|
||||||
#include <type/leb128.pat>
|
import type.leb128;
|
||||||
|
|
||||||
struct header_item {
|
struct header_item {
|
||||||
u8 magic[8];
|
u8 magic[8];
|
||||||
|
|||||||
5594
patterns/dicom.hexpat
Normal file
5594
patterns/dicom.hexpat
Normal file
File diff suppressed because it is too large
Load Diff
165
patterns/dmc3_hd_mod.hexpat
Normal file
165
patterns/dmc3_hd_mod.hexpat
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
#pragma description Devil May Cry 3 HD .mod 3D model file
|
||||||
|
#pragma MIME 3d-model/capcom.dmc3-hd-mod
|
||||||
|
|
||||||
|
// author = haru233, many thanks to AxCut
|
||||||
|
// ImHex Hex Pattern File for Capcom's Devil May Cry 3 HD .mod files
|
||||||
|
|
||||||
|
|
||||||
|
import std.core;
|
||||||
|
|
||||||
|
|
||||||
|
struct ModelHeader {
|
||||||
|
char ID[4];
|
||||||
|
float Version;
|
||||||
|
padding[8];
|
||||||
|
u8 objectCount;
|
||||||
|
u8 boneCount;
|
||||||
|
u8 numberTextures;
|
||||||
|
u8;
|
||||||
|
u32;
|
||||||
|
u64;
|
||||||
|
u64 skeletonOffset;
|
||||||
|
padding[24];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ObjectInfo {
|
||||||
|
u8 meshCount;
|
||||||
|
u8;
|
||||||
|
u16 numberVertices;
|
||||||
|
padding[4];
|
||||||
|
u64 meshOffset;
|
||||||
|
u32 flags;
|
||||||
|
padding[28];
|
||||||
|
float X, Y, Z;
|
||||||
|
float radius;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Positions {
|
||||||
|
float positions[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct Normals {
|
||||||
|
float normal[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct UVs {
|
||||||
|
s16 uv[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BoneIndices {
|
||||||
|
u8 boneindex[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Weights {
|
||||||
|
u16 weight[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MeshSCM {
|
||||||
|
u16 numberVertices;
|
||||||
|
u16 textureIndex;
|
||||||
|
padding[12];
|
||||||
|
u64 VerticesPositionsOffset;
|
||||||
|
u64 NormalsPositionsOffset;
|
||||||
|
u64 UVsPositionsOffset;
|
||||||
|
|
||||||
|
padding[16];
|
||||||
|
u64 unknownOffset;
|
||||||
|
|
||||||
|
u64;
|
||||||
|
padding[8];
|
||||||
|
|
||||||
|
Positions positions[numberVertices] @VerticesPositionsOffset;
|
||||||
|
Normals normals[numberVertices] @NormalsPositionsOffset;
|
||||||
|
UVs uvs[numberVertices] @UVsPositionsOffset;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Mesh {
|
||||||
|
u16 numberVertices;
|
||||||
|
u16 textureIndex;
|
||||||
|
padding[12];
|
||||||
|
u64 VerticesPositionsOffset;
|
||||||
|
u64 NormalsPositionsOffset;
|
||||||
|
u64 UVsPositionsOffset;
|
||||||
|
|
||||||
|
u64 BoneIndicesOffset;
|
||||||
|
u64 WeightsOffset;
|
||||||
|
padding[8];
|
||||||
|
|
||||||
|
u64;
|
||||||
|
padding[8];
|
||||||
|
|
||||||
|
Positions positions[numberVertices] @VerticesPositionsOffset;
|
||||||
|
Normals normals[numberVertices] @NormalsPositionsOffset;
|
||||||
|
UVs uvs[numberVertices] @UVsPositionsOffset;
|
||||||
|
|
||||||
|
BoneIndices b_index[numberVertices] @BoneIndicesOffset;
|
||||||
|
Weights weights[numberVertices] @WeightsOffset;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct Hierarchy {
|
||||||
|
u8 hierarchy;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HierarchyOrder {
|
||||||
|
u8 hierarchyorder;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Unknown {
|
||||||
|
u8;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Transform {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
float length; // sqrt(x*x + y*y + z*z)
|
||||||
|
padding[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Skeleton{
|
||||||
|
u32 hierarchyOffset;
|
||||||
|
u32 hierarchyOrderOffset;
|
||||||
|
u32 unknownOffset;
|
||||||
|
u32 transformsOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ModelHeader modelheader @ 0x00;
|
||||||
|
ObjectInfo objects_info[modelheader.objectCount] @ 0x40;
|
||||||
|
|
||||||
|
u32 objectOffset;
|
||||||
|
|
||||||
|
struct Object {
|
||||||
|
u64 i = std::core::array_index();
|
||||||
|
if (modelheader.ID == "SCM ") {
|
||||||
|
objectOffset = objects_info[0].meshOffset;
|
||||||
|
MeshSCM meshscm[objects_info[i].meshCount] @ objects_info[i].meshOffset;
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
objectOffset = objects_info[0].meshOffset;
|
||||||
|
Mesh mesh[objects_info[i].meshCount] @ objects_info[i].meshOffset;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Object objects[modelheader.objectCount] @objectOffset;
|
||||||
|
|
||||||
|
Skeleton skeleton @modelheader.skeletonOffset;
|
||||||
|
|
||||||
|
Hierarchy hierarchy[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.hierarchyOffset);
|
||||||
|
|
||||||
|
HierarchyOrder hierarchyorder[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.hierarchyOrderOffset);
|
||||||
|
|
||||||
|
Unknown unknown[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.unknownOffset);
|
||||||
|
|
||||||
|
Transform transform[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.transformsOffset);
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
#pragma description Apple Disk Image Trailer (DMG)
|
#pragma description Apple Disk Image Trailer (DMG)
|
||||||
|
#pragma magic [ 6B 6F 6C 79 ] @ -512
|
||||||
|
|
||||||
#pragma endian big
|
#pragma endian big
|
||||||
|
|
||||||
#include <type/magic.pat>
|
import type.magic;
|
||||||
#include <type/size.pat>
|
import type.size;
|
||||||
#include <type/guid.pat>
|
import type.guid;
|
||||||
#include <std/mem.pat>
|
import std.mem;
|
||||||
|
|
||||||
// Parse DMG Structure per http://newosxbook.com/DMG.html
|
// Parse DMG Structure per http://newosxbook.com/DMG.html
|
||||||
//
|
//
|
||||||
@@ -22,12 +23,12 @@ struct UDIFResourceFile {
|
|||||||
type::Size<u64> RsrcForkLength; // Resource fork length, if any
|
type::Size<u64> RsrcForkLength; // Resource fork length, if any
|
||||||
u32 SegmentNumber; // Usually 1, may be 0
|
u32 SegmentNumber; // Usually 1, may be 0
|
||||||
u32 SegmentCount; // Usually 1, may be 0
|
u32 SegmentCount; // Usually 1, may be 0
|
||||||
type::GUID SegmentID; // 128-bit GUID identifier of segment (if SegmentNumber !=0)
|
|
||||||
|
|
||||||
|
type::GUID SegmentID; // 128-bit GUID identifier of segment (if SegmentNumber !=0)
|
||||||
|
|
||||||
u32 DataChecksumType; // Data fork
|
u32 DataChecksumType; // Data fork
|
||||||
type::Size<u32> DataChecksumSize; // Checksum Information
|
type::Size<u32> DataChecksumSize; // Checksum Information
|
||||||
u32 DataChecksum[DataChecksumSize]; // Up to 128-bytes (32 x 4) of checksum
|
u32 DataChecksum[32]; // Up to 128-bytes (32 x 4) of checksum
|
||||||
|
|
||||||
u64 XMLOffset; // Offset of property list in DMG, from beginning
|
u64 XMLOffset; // Offset of property list in DMG, from beginning
|
||||||
type::Size<u64> XMLLength; // Length of property list
|
type::Size<u64> XMLLength; // Length of property list
|
||||||
@@ -35,7 +36,7 @@ struct UDIFResourceFile {
|
|||||||
|
|
||||||
u32 ChecksumType; // Master
|
u32 ChecksumType; // Master
|
||||||
type::Size<u32> ChecksumSize; // Checksum information
|
type::Size<u32> ChecksumSize; // Checksum information
|
||||||
u32 Checksum[ChecksumSize]; // Up to 128-bytes (32 x 4) of checksum
|
u32 Checksum[32]; // Up to 128-bytes (32 x 4) of checksum
|
||||||
|
|
||||||
u32 ImageVariant; // Commonly 1
|
u32 ImageVariant; // Commonly 1
|
||||||
u64 SectorCount; // Size of DMG when expanded, in sectors
|
u64 SectorCount; // Size of DMG when expanded, in sectors
|
||||||
|
|||||||
102
patterns/dmp64.hexpat
Normal file
102
patterns/dmp64.hexpat
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
#pragma magic [ 50 41 47 45 ] @ 0x00 // PAGE
|
||||||
|
#pragma author "5h4rrK"
|
||||||
|
#pragma description "KERNEL DUMP"
|
||||||
|
|
||||||
|
import std.core;
|
||||||
|
import std.io;
|
||||||
|
import std.array;
|
||||||
|
|
||||||
|
#define COMMENT_SIZE 0x80
|
||||||
|
|
||||||
|
fn format_values(auto val){
|
||||||
|
return std::format("{:#x}", val);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn format_size_values(auto val){
|
||||||
|
return std::format(
|
||||||
|
"{:#x} ({}) ",
|
||||||
|
val,
|
||||||
|
std::format("{:#x}",val * 0x1000)
|
||||||
|
);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
union DUMP_FILE_ATTRIBUTES {
|
||||||
|
u32 bitfields[[name("BitFields")]];
|
||||||
|
u32 attributes[[name("Attributes")]];
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DUMP_TYPE : u32 {
|
||||||
|
FULL_DUMP = 0x01,
|
||||||
|
BITMAP_DUMP = 0x05
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EXCEPTION_RECORD64
|
||||||
|
{
|
||||||
|
u32 exception_code[[name("ExceptionCode"), format("format_values")]];
|
||||||
|
u32 exception_flags[[name("ExceptionFlags"), format("format_values")]];
|
||||||
|
u64 exception_record[[name("ExceptionRecord"), format("format_values")]];
|
||||||
|
u64 exception_address[[name("ExceptionAddress"), format("format_values")]];
|
||||||
|
u32 number_parameters[[name("NumberParameters"), format("format_values")]];
|
||||||
|
u32 unused_alignment[[name("Alignment"), format("format_values")]];
|
||||||
|
u64 exception_information[15][[name("ExceptionInformation")]];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PHYSICAL_MEMORY_RUN64 {
|
||||||
|
u64 base_page [[ name("BasePage"), format("format_size_values"), comment("StartOffset = BasePage * PageSize")]];
|
||||||
|
u64 page_count[[ name("PageCount"),format("format_size_values"), comment("Length = PageCount * PageSize")]];
|
||||||
|
}[[name("PHYSICAL_MEMORY_RUN_ENTRY")]];
|
||||||
|
|
||||||
|
struct PHYSICAL_MEMORY_DESCRIPTOR64 {
|
||||||
|
u32 no_of_runs [[name("NumberOfRuns")]];
|
||||||
|
char description[4][[name("Description")]];
|
||||||
|
u64 no_of_pages[[name("NumberOfPages"),format("format_values")]];
|
||||||
|
// PHYSICAL_MEMORY_RUN64 pmr64[no_of_runs] [[name("PHYSICAL_MEMORY_RUN64")]];
|
||||||
|
std::Array<PHYSICAL_MEMORY_RUN64, no_of_runs> pmrObjs[[name("PHYSICAL_MEMORY_RUN64")]];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DUMP_HEADER64 {
|
||||||
|
char signature[4][[name("Signature")]];
|
||||||
|
char validdump[4][[name("ValidDump")]];
|
||||||
|
u32 major_version[[name("MajorVersion")]];
|
||||||
|
u32 minor_version[[name("MinorVersion")]];
|
||||||
|
u64 dtb [[name("DirectoryBaseTable"),format("format_values")]];
|
||||||
|
u64 pfn [[name("PfnDataBase"), format("format_values")]];
|
||||||
|
u64 ploadedmodulelist [[name("PsLoadedModuleList"), format("format_values")]];
|
||||||
|
u64 pactiveprocesshead [[name("PsActiveProcessHead"), format("format_values")]];
|
||||||
|
u32 machine_type [[name("MachineImageType"), format("format_values")]];
|
||||||
|
u32 processor_counts [[name("ProcessorsCount")]];
|
||||||
|
u32 bug_check [[name("BugCheckCode"), format("format_values")]];
|
||||||
|
u32 bug_check_code_desc[[name("BugCheckCodeDescription"), format("format_values")]];
|
||||||
|
u64 bug_check_param1[[name("BugCheckCodeParameter1"), format("format_values")]];
|
||||||
|
u64 bug_check_param2[[name("BugCheckCodeParameter2"), format("format_values")]];
|
||||||
|
u64 bug_check_param3[[name("BugCheckCodeParameter3"), format("format_values")]];
|
||||||
|
u64 bug_check_param4[[name("BugCheckCodeParameter4"), format("format_values")]];
|
||||||
|
char version_user[0x20][[name("VersionUser")]];
|
||||||
|
u64 kdbg[[name("KdDebuggerDataBlock"), format("format_values")]];
|
||||||
|
PHYSICAL_MEMORY_DESCRIPTOR64 phys_mem_desc[[name("PHYSICAL_MEMORY_DESCRIPTOR64")]];
|
||||||
|
char mem_block_buffer[0x260][[name("PhysicalMemoryBlockBuffer")]];
|
||||||
|
char context_record[0xbb8][[name("ContextRecord")]];
|
||||||
|
EXCEPTION_RECORD64 excr[[name("EXCEPTION_RECORD64")]];
|
||||||
|
DUMP_TYPE dmp_type[[name("DumpType")]];
|
||||||
|
char desc1[4][[name("Description")]];
|
||||||
|
u64 req_dump_space[[name("RequiredDumpSpace"), format("format_values")]];
|
||||||
|
u64 sys_time[[name("SystemTime"), format("format_values")]];
|
||||||
|
char comment[COMMENT_SIZE][[name("Comment")]];
|
||||||
|
u64 sys_up_time[[name("SystemUpTime"), format("format_values")]];
|
||||||
|
u32 min_dmp_fields[[name("MiniDumpFields"), format("format_values")]];
|
||||||
|
u32 sec_data_state[[name("SecondaryDataState"), format("format_values")]];
|
||||||
|
u32 product_type[[name("ProductType"), format("format_values")]];
|
||||||
|
u32 suite_mask[[name("SuiteMask"), format("format_values")]];
|
||||||
|
u32 writer_status[[name("WriterStatus"), format("format_values")]];
|
||||||
|
char unused1[[name("Unused1")]];
|
||||||
|
char secondary_version[[name("KdSecondaryVersion")]];
|
||||||
|
char unused2[2][[name("Unused2")]];
|
||||||
|
DUMP_FILE_ATTRIBUTES dfa[[name("DUMP_FILE_ATTRIBUTES")]];
|
||||||
|
u32 boot_id[[name("BootId")]];
|
||||||
|
char reserved[0xfa8][[name("Reserved")]];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
DUMP_HEADER64 dmp @ 0x00 [[name("DumpHeader")]];
|
||||||
921
patterns/dotnet_binaryformatter.hexpat
Normal file
921
patterns/dotnet_binaryformatter.hexpat
Normal file
@@ -0,0 +1,921 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
References:
|
||||||
|
.NET BinaryFormatter Specification "MS-NRBF":
|
||||||
|
https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nrbf/75b9fe09-be15-475f-85b8-ae7b7558cfe5
|
||||||
|
.NET runtime:
|
||||||
|
https://github.com/dotnet/runtime/blob/v8.0.17/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryParser.cs
|
||||||
|
.NET Library for Parsing MS-NRBF streams:
|
||||||
|
https://github.com/bbowyersmyth/BinaryFormatDataStructure
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma author ODeux
|
||||||
|
#pragma description .NET BinaryFormatter (System.Runtime.Serialization.Formatters.Binary, obsolete)
|
||||||
|
|
||||||
|
#pragma endian little
|
||||||
|
|
||||||
|
import std.core;
|
||||||
|
import std.sys;
|
||||||
|
import std.mem;
|
||||||
|
import std.ptr;
|
||||||
|
|
||||||
|
fn offsetOf(ref auto value, ref auto value_field){
|
||||||
|
return addressof(value_field) - addressof(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NullableArrayPtr<T, pointerSize, auto size>{
|
||||||
|
pointerSize pointerValue [[no_unique_address, hidden]];
|
||||||
|
if(pointerValue != 0)
|
||||||
|
T *data[size]: pointerSize;
|
||||||
|
else
|
||||||
|
padding[sizeof(pointerSize)];
|
||||||
|
};
|
||||||
|
|
||||||
|
using _Ptr<T, PointerSize> = std::ptr::NullablePtr<T, PointerSize>;
|
||||||
|
using _ArrayPtr<T, PointerSize, auto size> = NullableArrayPtr<T, PointerSize, size>;
|
||||||
|
|
||||||
|
fn append_value_to_section(ref auto value, std::mem::Section section){
|
||||||
|
u128 old_section_size = std::mem::get_section_size(section);
|
||||||
|
std::mem::copy_value_to_section(value, section, old_section_size);
|
||||||
|
return old_section_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn todo(auto message){
|
||||||
|
std::error(std::format("@0x{:08X} TODO: " + message, $));
|
||||||
|
};
|
||||||
|
|
||||||
|
using _Trackers;
|
||||||
|
std::mem::Section _TrackersSection = std::mem::create_section("_TrackersSection");
|
||||||
|
_Trackers _trackers @ 0x0 in _TrackersSection;
|
||||||
|
bool NeedUpdateTrackers = false;
|
||||||
|
bool IsUpdatingTrackers = false;
|
||||||
|
|
||||||
|
enum _ObjEnum: u64{
|
||||||
|
Empty = 0,
|
||||||
|
SerializedStreamHeader = 1,
|
||||||
|
ClassWithId = 2, Object = _ObjEnum::ClassWithId,
|
||||||
|
SystemClassWithMembers = 3, ObjectWithMap = _ObjEnum::SystemClassWithMembers,
|
||||||
|
ClassWithMembers = 4, ObjectWithMapAssemId = _ObjEnum::ClassWithMembers,
|
||||||
|
SystemClassWithMembersAndTypes = 5, ObjectWithMapTyped = _ObjEnum::SystemClassWithMembersAndTypes,
|
||||||
|
ClassWithMembersAndTypes = 6, ObjectWithMapTypedAssemId = _ObjEnum::ClassWithMembersAndTypes,
|
||||||
|
BinaryObjectString = 7, ObjectString = _ObjEnum::BinaryObjectString,
|
||||||
|
BinaryArray = 8, Array = _ObjEnum::BinaryArray,
|
||||||
|
MemberPrimitiveTyped = 9,
|
||||||
|
MemberReference = 10,
|
||||||
|
BinaryLibrary = 11, Assembly = _ObjEnum::BinaryLibrary,
|
||||||
|
ObjectNullMultiple256 = 12,
|
||||||
|
ObjectNullMultiple = 13,
|
||||||
|
ArraySinglePrimitive = 14,
|
||||||
|
ArraySingleObject = 15,
|
||||||
|
ArraySingleString = 16,
|
||||||
|
CrossAppDomainMap = 17,
|
||||||
|
CrossAppDomainString = 18,
|
||||||
|
CrossAppDomainAssembly = 19,
|
||||||
|
MethodCall = 20,
|
||||||
|
MethodReturn = 21
|
||||||
|
};
|
||||||
|
|
||||||
|
fn zeroedCurrObjTrackers(){
|
||||||
|
_trackers.currentObj.TypeName.pointerValue = 0;
|
||||||
|
_trackers.currentObj.AssemblyName.pointerValue = 0;
|
||||||
|
_trackers.currentObj.objEnum = _ObjEnum::Empty;
|
||||||
|
_trackers.currentObj.RawPtr = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn copyCurrObjAtIdTrackers(auto id){
|
||||||
|
NeedUpdateTrackers = true;
|
||||||
|
_trackers.objs[id].TypeName.pointerValue = _trackers.currentObj.TypeName.pointerValue;
|
||||||
|
_trackers.objs[id].AssemblyName.pointerValue = _trackers.currentObj.AssemblyName.pointerValue;
|
||||||
|
/* ! Enum does not get copied if we don't use a cast here for some reason ! */
|
||||||
|
_trackers.objs[id].objEnum = u64(_trackers.currentObj.objEnum);
|
||||||
|
_trackers.objs[id].RawPtr = _trackers.currentObj.RawPtr;
|
||||||
|
};
|
||||||
|
|
||||||
|
using BitfieldOrder = std::core::BitfieldOrder;
|
||||||
|
|
||||||
|
using TimeSpan = s64;
|
||||||
|
|
||||||
|
enum PrimitiveTypeEnum: u8{
|
||||||
|
Invalid = 0,
|
||||||
|
Boolean = 1,
|
||||||
|
Byte = 2,
|
||||||
|
Char = 3,
|
||||||
|
Currency = 4, /* Not Used in this protocol */
|
||||||
|
Decimal = 5,
|
||||||
|
Double = 6,
|
||||||
|
Int16 = 7,
|
||||||
|
Int32 = 8,
|
||||||
|
Int64 = 9,
|
||||||
|
SByte = 10,
|
||||||
|
Single = 11,
|
||||||
|
TimeSpan = 12,
|
||||||
|
DateTime = 13,
|
||||||
|
UInt16 = 14,
|
||||||
|
UInt32 = 15,
|
||||||
|
UInt64 = 16,
|
||||||
|
Null = 17,
|
||||||
|
String = 18
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PrimitiveTypeEnumT<auto _primitiveTypeEnumT>{
|
||||||
|
PrimitiveTypeEnum primitiveTypeEnumT = _primitiveTypeEnumT;
|
||||||
|
PrimitiveTypeEnum primitiveTypeEnum;
|
||||||
|
if(_primitiveTypeEnumT > 0)
|
||||||
|
std::assert(primitiveTypeEnum == primitiveTypeEnumT, std::format("Expected {} but got {}", primitiveTypeEnumT, primitiveTypeEnum));
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BinaryTypeEnum: u8{
|
||||||
|
Primitive = 0,
|
||||||
|
String = 1,
|
||||||
|
Object = 2,
|
||||||
|
SystemClass = 3, ObjectUrt = BinaryTypeEnum::SystemClass,
|
||||||
|
Class = 4, ObjectUser = BinaryTypeEnum::Class,
|
||||||
|
ObjectArray = 5,
|
||||||
|
StringArray = 6,
|
||||||
|
PrimitiveArray = 7
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BinaryArrayTypeEnum: u8{
|
||||||
|
Single = 0,
|
||||||
|
Jagged = 1,
|
||||||
|
Rectangular = 2,
|
||||||
|
SingleOffset = 3,
|
||||||
|
JaggedOffset = 4,
|
||||||
|
RectangularOffset = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RecordTypeEnum: u8{
|
||||||
|
SerializedStreamHeader = 0,
|
||||||
|
ClassWithId = 1, Object = RecordTypeEnum::ClassWithId,
|
||||||
|
SystemClassWithMembers = 2, ObjectWithMap = RecordTypeEnum::SystemClassWithMembers,
|
||||||
|
ClassWithMembers = 3, ObjectWithMapAssemId = RecordTypeEnum::ClassWithMembers,
|
||||||
|
SystemClassWithMembersAndTypes = 4, ObjectWithMapTyped = RecordTypeEnum::SystemClassWithMembersAndTypes,
|
||||||
|
ClassWithMembersAndTypes = 5, ObjectWithMapTypedAssemId = RecordTypeEnum::ClassWithMembersAndTypes,
|
||||||
|
BinaryObjectString = 6, ObjectString = RecordTypeEnum::BinaryObjectString,
|
||||||
|
BinaryArray = 7, Array = RecordTypeEnum::BinaryArray,
|
||||||
|
MemberPrimitiveTyped = 8,
|
||||||
|
MemberReference = 9,
|
||||||
|
ObjectNull = 10,
|
||||||
|
MessageEnd = 11,
|
||||||
|
BinaryLibrary = 12, Assembly = RecordTypeEnum::BinaryLibrary,
|
||||||
|
ObjectNullMultiple256 = 13,
|
||||||
|
ObjectNullMultiple = 14,
|
||||||
|
ArraySinglePrimitive = 15,
|
||||||
|
ArraySingleObject = 16,
|
||||||
|
ArraySingleString = 17,
|
||||||
|
CrossAppDomainMap = 18,
|
||||||
|
CrossAppDomainString = 19,
|
||||||
|
CrossAppDomainAssembly = 20,
|
||||||
|
MethodCall = 21,
|
||||||
|
MethodReturn = 22
|
||||||
|
};
|
||||||
|
using BinaryHeaderEnum = RecordTypeEnum;
|
||||||
|
|
||||||
|
struct RecordTypeEnumT<auto _recordTypeEnumT>{
|
||||||
|
RecordTypeEnum recordTypeEnumT = _recordTypeEnumT;
|
||||||
|
RecordTypeEnum recordTypeEnum;
|
||||||
|
if(_recordTypeEnumT > 0)
|
||||||
|
std::assert(recordTypeEnum == recordTypeEnumT, std::format("Expected {} but got {}", recordTypeEnumT, recordTypeEnum));
|
||||||
|
};
|
||||||
|
|
||||||
|
bitfield MessageFlags{
|
||||||
|
bool NoArgs: 1; /* Arg Category */
|
||||||
|
bool ArgsInline: 1; /* Arg Category */
|
||||||
|
bool ArgsIsArray: 1; /* Arg Category */
|
||||||
|
bool ArgsInArray: 1; /* Arg Category */
|
||||||
|
bool NoContext: 1; /* Context Category */
|
||||||
|
bool ContextInline: 1; /* Context Category */
|
||||||
|
bool ContextInArray: 1; /* Context Category */
|
||||||
|
bool MethodSignatureInArray: 1; /* Signature Category */
|
||||||
|
bool PropertiesInArray: 1; /* Property Category */
|
||||||
|
bool NoReturnValue: 1; /* Return Category */
|
||||||
|
bool ReturnValueVoid: 1; /* Return Category */
|
||||||
|
bool ReturnValueInline: 1; /* Return Category */
|
||||||
|
bool ReturnValueInArray: 1; /* Return Category */
|
||||||
|
bool ExceptionInArray: 1; /* Exception Category */
|
||||||
|
bool GenericMethod: 1; /* Generic Category */
|
||||||
|
unsigned unused: 17;
|
||||||
|
} [[bitfield_order(BitfieldOrder::LeastToMostSignificant, 32)]];
|
||||||
|
|
||||||
|
fn validate_MessageFlags(MessageFlags flags){
|
||||||
|
u8 arg_cnt = flags.NoArgs + flags.ArgsInline + flags.ArgsIsArray + flags.ArgsInArray;
|
||||||
|
u8 ctx_cnt = flags.NoContext + flags.ContextInline + flags.ContextInArray;
|
||||||
|
u8 sig_cnt = flags.MethodSignatureInArray;
|
||||||
|
u8 ret_cnt = flags.NoReturnValue + flags.ReturnValueVoid + flags.ReturnValueInline + flags.ReturnValueInArray;
|
||||||
|
u8 excep_cnt = flags.ExceptionInArray;
|
||||||
|
u8 prop_cnt = flags.PropertiesInArray;
|
||||||
|
u8 gen_cnt = flags.GenericMethod;
|
||||||
|
if(arg_cnt > 1 || ctx_cnt > 1 || sig_cnt > 1 || ret_cnt > 1 || excep_cnt > 1 || prop_cnt > 1 || gen_cnt > 1)
|
||||||
|
return -1;
|
||||||
|
if(arg_cnt != 0 && excep_cnt != 0) return -1;
|
||||||
|
if(ret_cnt != 0 && excep_cnt != 0) return -1;
|
||||||
|
if(ret_cnt != 0 && sig_cnt != 0) return -1;
|
||||||
|
if(excep_cnt != 0 && sig_cnt != 0) return -1;
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DateTimeKind: u8{
|
||||||
|
NOT_SPECIFIED = 0,
|
||||||
|
UTC = 1,
|
||||||
|
Local = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
bitfield DateTime{
|
||||||
|
s64 Ticks: 62;
|
||||||
|
DateTimeKind kind: 2;
|
||||||
|
} [[bitfield_order(BitfieldOrder::LeastToMostSignificant, 64)]];
|
||||||
|
|
||||||
|
struct vLength{
|
||||||
|
/*
|
||||||
|
Can't use that, it breaks when struct get re-parsed in _TrackersSection
|
||||||
|
u8 data[while(std::mem::read_unsigned($, 1) & 0x80)];
|
||||||
|
u8 last;
|
||||||
|
*/
|
||||||
|
u64 bytes [[no_unique_address, hidden]];
|
||||||
|
u8 cnt = 0;
|
||||||
|
if(bytes & 0x80){
|
||||||
|
if(bytes & 0x8000){
|
||||||
|
if(bytes & 0x800000){
|
||||||
|
if(bytes & 0x80000000){
|
||||||
|
if(bytes & 0x8000000000){
|
||||||
|
/* exceeding vLength 5 bytes, caller should crash */
|
||||||
|
cnt = 5;
|
||||||
|
}else cnt = 4;
|
||||||
|
}else cnt = 3;
|
||||||
|
}else cnt = 2;
|
||||||
|
}else cnt = 1;
|
||||||
|
}else cnt = 0;
|
||||||
|
u8 data[cnt];
|
||||||
|
u8 last;
|
||||||
|
} [[sealed, transform("LPS_Length_decode"), format("LPS_Length_decode")]];
|
||||||
|
|
||||||
|
fn LPS_Length_decode(auto Length){
|
||||||
|
u64 length = 0;
|
||||||
|
u8 i = 0;
|
||||||
|
for(i = 0, i < sizeof(Length.data), i += 1)
|
||||||
|
length |= u64(Length.data[i] & 0x7F) << i * 7;
|
||||||
|
length |= u64(Length.last) << i * 7;
|
||||||
|
return length;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LengthPrefixedString{
|
||||||
|
vLength Length;
|
||||||
|
std::assert(sizeof(Length) <= 5, "LengthPrefixedString.Length must be at most 5 bytes long");
|
||||||
|
char String[Length];
|
||||||
|
};
|
||||||
|
|
||||||
|
using Decimal = LengthPrefixedString;
|
||||||
|
|
||||||
|
struct ClassTypeInfo{
|
||||||
|
LengthPrefixedString TypeName;
|
||||||
|
s32 LibraryId;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ValueWithCode{
|
||||||
|
PrimitiveTypeEnum PrimitiveType;
|
||||||
|
match(PrimitiveType){
|
||||||
|
(PrimitiveTypeEnum::Boolean): bool Value;
|
||||||
|
(PrimitiveTypeEnum::Byte): u8 Value;
|
||||||
|
(PrimitiveTypeEnum::Char): char Value;
|
||||||
|
(PrimitiveTypeEnum::Currency): std::error("Primitive currency not used in this protocol");
|
||||||
|
(PrimitiveTypeEnum::Decimal): Decimal Value;
|
||||||
|
(PrimitiveTypeEnum::Double): double Value;
|
||||||
|
(PrimitiveTypeEnum::Int16): s16 Value;
|
||||||
|
(PrimitiveTypeEnum::Int32): s32 Value;
|
||||||
|
(PrimitiveTypeEnum::Int64): s64 Value;
|
||||||
|
(PrimitiveTypeEnum::SByte): s8 Value;
|
||||||
|
(PrimitiveTypeEnum::Single): float Value;
|
||||||
|
(PrimitiveTypeEnum::TimeSpan): TimeSpan Value;
|
||||||
|
(PrimitiveTypeEnum::DateTime): DateTime Value;
|
||||||
|
(PrimitiveTypeEnum::UInt16): u16 Value;
|
||||||
|
(PrimitiveTypeEnum::UInt32): u32 Value;
|
||||||
|
(PrimitiveTypeEnum::UInt64): u64 Value;
|
||||||
|
(PrimitiveTypeEnum::Null): {}
|
||||||
|
(PrimitiveTypeEnum::String): LengthPrefixedString Value;
|
||||||
|
(_): std::error(std::format("Unexpected {}", PrimitiveType));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StringValueWithCode: PrimitiveTypeEnumT<PrimitiveTypeEnum::String>{
|
||||||
|
LengthPrefixedString StringValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ArrayOfValueWithCode{
|
||||||
|
s32 Length;
|
||||||
|
ValueWithCode ListOfValueWithCode[Length];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ArrayInfo{
|
||||||
|
s32 ObjectId;
|
||||||
|
s32 Length;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ClassInfo{
|
||||||
|
s32 ObjectId;
|
||||||
|
LengthPrefixedString Name;
|
||||||
|
s32 MemberCount;
|
||||||
|
LengthPrefixedString MemberNames[MemberCount];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AdditionalInfo<auto _binaryTypeEnum>{
|
||||||
|
BinaryTypeEnum binaryTypeEnum = _binaryTypeEnum;
|
||||||
|
match(binaryTypeEnum){
|
||||||
|
(BinaryTypeEnum::SystemClass): /* ObjectUrt */
|
||||||
|
LengthPrefixedString String;
|
||||||
|
(BinaryTypeEnum::Class): /* ObjectUser */
|
||||||
|
ClassTypeInfo classTypeInfo;
|
||||||
|
(BinaryTypeEnum::Primitive | BinaryTypeEnum::PrimitiveArray): {
|
||||||
|
PrimitiveTypeEnum primitiveType;
|
||||||
|
std::assert(primitiveType != PrimitiveTypeEnum::Null &&
|
||||||
|
primitiveType != PrimitiveTypeEnum::String, "Must not be Null or String");
|
||||||
|
}
|
||||||
|
(BinaryTypeEnum::String | BinaryTypeEnum::Object |
|
||||||
|
BinaryTypeEnum::ObjectArray | BinaryTypeEnum::StringArray):
|
||||||
|
{/* not using continue here, need to keep array index matching */}
|
||||||
|
(_): std::error(std::format("Unrecognized {}", binaryTypeEnum));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MemberTypeInfo<auto MemberCount>{
|
||||||
|
BinaryTypeEnum binaryTypeEnums[MemberCount];
|
||||||
|
AdditionalInfo<binaryTypeEnums[std::core::array_index()]> additionalInfo[MemberCount];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UntypedMember<auto _className, auto classInfo>{
|
||||||
|
str className = _className;
|
||||||
|
u64 MemberCount = classInfo.MemberCount;
|
||||||
|
if(className == "System.Guid" && MemberCount == 11){
|
||||||
|
match(std::core::array_index()){
|
||||||
|
(0): s32 _a;
|
||||||
|
(1): s16 _b;
|
||||||
|
(2): s16 _c;
|
||||||
|
(3): u8 _d;
|
||||||
|
(4): u8 _e;
|
||||||
|
(5): u8 _f;
|
||||||
|
(6): u8 _g;
|
||||||
|
(7): u8 _h;
|
||||||
|
(8): u8 _i;
|
||||||
|
(9): u8 _j;
|
||||||
|
(10): u8 _k;
|
||||||
|
(_): std::error("unreachable");
|
||||||
|
}
|
||||||
|
}else if(MemberCount == 1 && classInfo.MemberNames[0].String == "value__"){
|
||||||
|
str Name = classInfo.MemberNames[0].String;
|
||||||
|
s32 member [name(Name)];
|
||||||
|
}else
|
||||||
|
std::error(std::format("Unsupported untyped member: {}", className));
|
||||||
|
};
|
||||||
|
|
||||||
|
using Record;
|
||||||
|
|
||||||
|
struct Members<auto _Name, auto memberTypeInfo>{
|
||||||
|
u64 i = std::core::array_index();
|
||||||
|
str Name = _Name;
|
||||||
|
BinaryTypeEnum binaryTypeEnum = memberTypeInfo.binaryTypeEnums[i];
|
||||||
|
if(binaryTypeEnum == BinaryTypeEnum::Primitive){
|
||||||
|
PrimitiveTypeEnum primitiveTypeEnum = memberTypeInfo.additionalInfo[i].primitiveType;
|
||||||
|
match(primitiveTypeEnum){
|
||||||
|
(PrimitiveTypeEnum::Boolean): bool Value [[name(Name)]];
|
||||||
|
(PrimitiveTypeEnum::Byte): u8 Value [[name(Name)]];
|
||||||
|
(PrimitiveTypeEnum::Char): char Value [[name(Name)]];
|
||||||
|
(PrimitiveTypeEnum::Currency): std::error("Primitive currency not used in this protocol");
|
||||||
|
(PrimitiveTypeEnum::Decimal): Decimal Value [[name(Name)]];
|
||||||
|
(PrimitiveTypeEnum::Double): double Value [[name(Name)]];
|
||||||
|
(PrimitiveTypeEnum::Int16): s16 Value [[name(Name)]];
|
||||||
|
(PrimitiveTypeEnum::Int32): s32 Value [[name(Name)]];
|
||||||
|
(PrimitiveTypeEnum::Int64): s64 Value [[name(Name)]];
|
||||||
|
(PrimitiveTypeEnum::SByte): s8 Value [[name(Name)]];
|
||||||
|
(PrimitiveTypeEnum::Single): float Value [[name(Name)]];
|
||||||
|
(PrimitiveTypeEnum::TimeSpan): TimeSpan Value [[name(Name)]];
|
||||||
|
(PrimitiveTypeEnum::DateTime): DateTime Value [[name(Name)]];
|
||||||
|
(PrimitiveTypeEnum::UInt16): u16 Value [[name(Name)]];
|
||||||
|
(PrimitiveTypeEnum::UInt32): u32 Value [[name(Name)]];
|
||||||
|
(PrimitiveTypeEnum::UInt64): u64 Value [[name(Name)]];
|
||||||
|
(PrimitiveTypeEnum::Null): {}
|
||||||
|
(PrimitiveTypeEnum::String): LengthPrefixedString Value [[name(Name)]];
|
||||||
|
(_): std::error(std::format("Unexpected {}", primitiveTypeEnum));
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
Record record [[name(Name)]];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ClassWithMembersAndTypes: RecordTypeEnumT<RecordTypeEnum::ClassWithMembersAndTypes>{
|
||||||
|
ClassInfo classInfo;
|
||||||
|
MemberTypeInfo<classInfo.MemberCount> memberTypeInfo;
|
||||||
|
s32 LibraryId;
|
||||||
|
Members<classInfo.MemberNames[std::core::array_index()].String, memberTypeInfo> members[classInfo.MemberCount];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ClassWithMembers: RecordTypeEnumT<RecordTypeEnum::ClassWithMembers>{
|
||||||
|
ClassInfo classInfo;
|
||||||
|
s32 LibraryId;
|
||||||
|
UntypedMember<classInfo.Name.String, classInfo> members[classInfo.MemberCount];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SystemClassWithMembersAndTypes: RecordTypeEnumT<RecordTypeEnum::SystemClassWithMembersAndTypes>{
|
||||||
|
ClassInfo classInfo;
|
||||||
|
MemberTypeInfo<classInfo.MemberCount> memberTypeInfo;
|
||||||
|
Members<classInfo.MemberNames[std::core::array_index()].String, memberTypeInfo> members[classInfo.MemberCount];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SystemClassWithMembers: RecordTypeEnumT<RecordTypeEnum::SystemClassWithMembers>{
|
||||||
|
ClassInfo classInfo;
|
||||||
|
UntypedMember<classInfo.Name.String, classInfo> members[classInfo.MemberCount];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ClassWithId: RecordTypeEnumT<RecordTypeEnum::ClassWithId>{
|
||||||
|
s32 ObjectId;
|
||||||
|
s32 MetadataId;
|
||||||
|
if(!IsUpdatingTrackers && NeedUpdateTrackers){
|
||||||
|
IsUpdatingTrackers = true;
|
||||||
|
_Trackers _trackers @ 0x0 in _TrackersSection;
|
||||||
|
IsUpdatingTrackers = false;
|
||||||
|
NeedUpdateTrackers = false;
|
||||||
|
}
|
||||||
|
match(_trackers.objs[MetadataId].objEnum){
|
||||||
|
(_ObjEnum::ClassWithMembersAndTypes): {
|
||||||
|
u32 MemberCount = _trackers.objs[MetadataId].classWithMembersAndTypes.data.classInfo.MemberCount;
|
||||||
|
Members<_trackers.objs[MetadataId].classWithMembersAndTypes.data.classInfo.MemberNames[std::core::array_index()].String, _trackers.objs[MetadataId].classWithMembersAndTypes.data.memberTypeInfo> members[MemberCount];
|
||||||
|
}
|
||||||
|
(_ObjEnum::SystemClassWithMembersAndTypes): {
|
||||||
|
u32 MemberCount = _trackers.objs[MetadataId].systemClassWithMemberAndTypes.data.classInfo.MemberCount;
|
||||||
|
Members<_trackers.objs[MetadataId].systemClassWithMemberAndTypes.data.classInfo.MemberNames[std::core::array_index()].String, _trackers.objs[MetadataId].systemClassWithMemberAndTypes.data.memberTypeInfo> members[MemberCount];
|
||||||
|
}
|
||||||
|
(_ObjEnum::SystemClassWithMembers): {
|
||||||
|
str className = _trackers.objs[MetadataId].TypeName.data.String;
|
||||||
|
u32 MemberCount = _trackers.objs[MetadataId].systemClassWithMembers.data.classInfo.MemberCount;
|
||||||
|
UntypedMember<className, _trackers.objs[MetadataId].systemClassWithMembers.data.classInfo> members[MemberCount];
|
||||||
|
}
|
||||||
|
(_ObjEnum::ClassWithMembers): {
|
||||||
|
str className = _trackers.objs[MetadataId].TypeName.data.String;
|
||||||
|
u32 MemberCount = _trackers.objs[MetadataId].classWithMembers.data.classInfo.MemberCount;
|
||||||
|
UntypedMember<className, _trackers.objs[MetadataId].classWithMembers.data.classInfo> members[MemberCount];
|
||||||
|
}
|
||||||
|
(_): std::error(std::format("Unexpected {}", _trackers.objs[MetadataId].objEnum));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BinaryArray: RecordTypeEnumT<RecordTypeEnum::BinaryArray>{
|
||||||
|
s32 ObjectId;
|
||||||
|
BinaryArrayTypeEnum binaryArrayTypeEnum;
|
||||||
|
s32 Rank;
|
||||||
|
s32 Length[Rank];
|
||||||
|
if(binaryArrayTypeEnum == BinaryArrayTypeEnum::SingleOffset ||
|
||||||
|
binaryArrayTypeEnum == BinaryArrayTypeEnum::JaggedOffset ||
|
||||||
|
binaryArrayTypeEnum == BinaryArrayTypeEnum::RectangularOffset)
|
||||||
|
s32 LowerBounds[Rank];
|
||||||
|
BinaryTypeEnum TypeEnum;
|
||||||
|
AdditionalInfo<TypeEnum> additionalInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ArraySinglePrimitive: RecordTypeEnumT<RecordTypeEnum::ArraySinglePrimitive>{
|
||||||
|
ArrayInfo arrayInfo;
|
||||||
|
PrimitiveTypeEnum primitiveTypeEnum;
|
||||||
|
std::assert(primitiveTypeEnum != PrimitiveTypeEnum::Null &&
|
||||||
|
primitiveTypeEnum != PrimitiveTypeEnum::String, "Can't be one of those");
|
||||||
|
match(primitiveTypeEnum){
|
||||||
|
(PrimitiveTypeEnum::Boolean): bool Values[arrayInfo.Length];
|
||||||
|
(PrimitiveTypeEnum::Byte): u8 Value[arrayInfo.Length];
|
||||||
|
(PrimitiveTypeEnum::Char): char Value[arrayInfo.Length];
|
||||||
|
(PrimitiveTypeEnum::Currency): std::error("Primitive currency not used in this protocol");
|
||||||
|
(PrimitiveTypeEnum::Decimal): Decimal Value[arrayInfo.Length];
|
||||||
|
(PrimitiveTypeEnum::Double): double Value[arrayInfo.Length];
|
||||||
|
(PrimitiveTypeEnum::Int16): s16 Value[arrayInfo.Length];
|
||||||
|
(PrimitiveTypeEnum::Int32): s32 Value[arrayInfo.Length];
|
||||||
|
(PrimitiveTypeEnum::Int64): s64 Value[arrayInfo.Length];
|
||||||
|
(PrimitiveTypeEnum::SByte): s8 Value[arrayInfo.Length];
|
||||||
|
(PrimitiveTypeEnum::Single): float Value[arrayInfo.Length];
|
||||||
|
(PrimitiveTypeEnum::TimeSpan): TimeSpan Value[arrayInfo.Length];
|
||||||
|
(PrimitiveTypeEnum::DateTime): DateTime Value[arrayInfo.Length];
|
||||||
|
(PrimitiveTypeEnum::UInt16): u16 Value[arrayInfo.Length];
|
||||||
|
(PrimitiveTypeEnum::UInt32): u32 Value[arrayInfo.Length];
|
||||||
|
(PrimitiveTypeEnum::UInt64): u64 Value[arrayInfo.Length];
|
||||||
|
(PrimitiveTypeEnum::Null): {}
|
||||||
|
(PrimitiveTypeEnum::String): LengthPrefixedString Value[arrayInfo.Length];
|
||||||
|
(_): std::error(std::format("Unexpected {}", primitiveTypeEnum));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
u64 ArraySinglElementSkipCount = 0;
|
||||||
|
struct ArraySingleElement<auto _recordTypeEnum>{
|
||||||
|
RecordTypeEnum recordTypeEnum = _recordTypeEnum;
|
||||||
|
if(ArraySinglElementSkipCount > 0)
|
||||||
|
ArraySinglElementSkipCount -= 1;
|
||||||
|
else{
|
||||||
|
if(recordTypeEnum == RecordTypeEnum::ArraySingleString){
|
||||||
|
Record record [[inline]];
|
||||||
|
match(record.recordTypeEnum){
|
||||||
|
(RecordTypeEnum::ObjectNullMultiple):
|
||||||
|
ArraySinglElementSkipCount = record.objectNullMultiple.NullCount;
|
||||||
|
(RecordTypeEnum::ObjectNullMultiple256):
|
||||||
|
ArraySinglElementSkipCount = record.objectNullMultiple256.NullCount;
|
||||||
|
(_): {}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
Record record [[inline]];
|
||||||
|
if(record.recordTypeEnum == RecordTypeEnum::BinaryLibrary){
|
||||||
|
Record record2 [[inline]];
|
||||||
|
match(record2.recordTypeEnum){
|
||||||
|
(RecordTypeEnum::ObjectNullMultiple):
|
||||||
|
ArraySinglElementSkipCount = record2.objectNullMultiple.NullCount;
|
||||||
|
(RecordTypeEnum::ObjectNullMultiple256):
|
||||||
|
ArraySinglElementSkipCount = record2.objectNullMultiple256.NullCount;
|
||||||
|
(_): {}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
match(record.recordTypeEnum){
|
||||||
|
(RecordTypeEnum::ObjectNullMultiple):
|
||||||
|
ArraySinglElementSkipCount = record.objectNullMultiple.NullCount;
|
||||||
|
(RecordTypeEnum::ObjectNullMultiple256):
|
||||||
|
ArraySinglElementSkipCount = record.objectNullMultiple256.NullCount;
|
||||||
|
(_): {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ArraySingleObject: RecordTypeEnumT<RecordTypeEnum::ArraySingleObject>{
|
||||||
|
ArrayInfo arrayInfo;
|
||||||
|
ArraySinglElementSkipCount = 0;
|
||||||
|
ArraySingleElement<RecordTypeEnum::ArraySingleObject> records[arrayInfo.Length];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ArraySingleString: RecordTypeEnumT<RecordTypeEnum::ArraySingleString>{
|
||||||
|
ArrayInfo arrayInfo;
|
||||||
|
ArraySinglElementSkipCount = 0;
|
||||||
|
ArraySingleElement<RecordTypeEnum::ArraySingleString> records[arrayInfo.Length];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MethodReturnCallArray{
|
||||||
|
if(parent.MessageEnum.ReturnValueInArray)
|
||||||
|
ArraySingleObject ReturnValue;
|
||||||
|
if(parent.MessageEnum.ArgsInArray)
|
||||||
|
ArraySingleObject OutputArguments;
|
||||||
|
if(parent.MessageEnum.ExceptionInArray)
|
||||||
|
ArraySingleObject Exception;
|
||||||
|
if(parent.MessageEnum.ContextInArray)
|
||||||
|
ArraySingleObject CallContext;
|
||||||
|
if(parent.MessageEnum.PropertiesInArray)
|
||||||
|
ArraySingleObject MessageProperties;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MethodCallArray{
|
||||||
|
if(parent.MessageEnum.ArgsInArray)
|
||||||
|
ArraySingleObject InputArguments;
|
||||||
|
if(parent.MessageEnum.GenericMethod)
|
||||||
|
ArraySingleObject GenericTypeArguments;
|
||||||
|
if(parent.MessageEnum.MethodSignatureInArray)
|
||||||
|
ArraySingleObject MethodSignature;
|
||||||
|
if(parent.MessageEnum.ContextInArray)
|
||||||
|
ArraySingleObject CallContext;
|
||||||
|
if(parent.MessageEnum.PropertiesInArray)
|
||||||
|
ArraySingleObject MessageProperties;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BinaryMethodReturn: RecordTypeEnumT<RecordTypeEnum::MethodReturn>{
|
||||||
|
MessageFlags MessageEnum;
|
||||||
|
std::assert(validate_MessageFlags(MessageEnum) >= 0, "Validation Failed");
|
||||||
|
std::assert(!MessageEnum.MethodSignatureInArray && !MessageEnum.GenericMethod, "Can't be one of those");
|
||||||
|
if(MessageEnum.ReturnValueInline)
|
||||||
|
ValueWithCode ReturnValue;
|
||||||
|
if(MessageEnum.ContextInline)
|
||||||
|
StringValueWithCode CallContext;
|
||||||
|
if(MessageEnum.ArgsInline)
|
||||||
|
ArrayOfValueWithCode Args;
|
||||||
|
MethodReturnCallArray ReturnCallArray;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BinaryMethodCall: RecordTypeEnumT<RecordTypeEnum::MethodCall>{
|
||||||
|
MessageFlags MessageEnum;
|
||||||
|
std::assert(validate_MessageFlags(MessageEnum) >= 0, "Validation Failed");
|
||||||
|
std::assert(!MessageEnum.NoReturnValue && !MessageEnum.ReturnValueVoid &&
|
||||||
|
!MessageEnum.ReturnValueInline && !MessageEnum.ReturnValueInArray &&
|
||||||
|
!MessageEnum.ExceptionInArray, "Can't be one of those");
|
||||||
|
StringValueWithCode MethodName;
|
||||||
|
StringValueWithCode TypeName;
|
||||||
|
if(MessageEnum.ContextInline)
|
||||||
|
StringValueWithCode CallContext;
|
||||||
|
if(MessageEnum.ArgsInline)
|
||||||
|
ArrayOfValueWithCode Args;
|
||||||
|
MethodCallArray CallArray;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MemberPrimitiveTyped: RecordTypeEnumT<RecordTypeEnum::MemberPrimitiveTyped>{
|
||||||
|
PrimitiveTypeEnum primitiveTypeEnum;
|
||||||
|
std::assert(primitiveTypeEnum != PrimitiveTypeEnum::Null &&
|
||||||
|
primitiveTypeEnum != PrimitiveTypeEnum::String, "Can't be one of those");
|
||||||
|
match(primitiveTypeEnum){
|
||||||
|
(PrimitiveTypeEnum::Boolean): bool Value;
|
||||||
|
(PrimitiveTypeEnum::Byte): u8 Value;
|
||||||
|
(PrimitiveTypeEnum::Char): char Value;
|
||||||
|
(PrimitiveTypeEnum::Currency): std::error("Primitive currency not used in this protocol");
|
||||||
|
(PrimitiveTypeEnum::Decimal): Decimal Value;
|
||||||
|
(PrimitiveTypeEnum::Double): double Value;
|
||||||
|
(PrimitiveTypeEnum::Int16): s16 Value;
|
||||||
|
(PrimitiveTypeEnum::Int32): s32 Value;
|
||||||
|
(PrimitiveTypeEnum::Int64): s64 Value;
|
||||||
|
(PrimitiveTypeEnum::SByte): s8 Value;
|
||||||
|
(PrimitiveTypeEnum::Single): float Value;
|
||||||
|
(PrimitiveTypeEnum::TimeSpan): TimeSpan Value;
|
||||||
|
(PrimitiveTypeEnum::DateTime): DateTime Value;
|
||||||
|
(PrimitiveTypeEnum::UInt16): u16 Value;
|
||||||
|
(PrimitiveTypeEnum::UInt32): u32 Value;
|
||||||
|
(PrimitiveTypeEnum::UInt64): u64 Value;
|
||||||
|
(_): std::error(std::format("Unexpected {}", primitiveTypeEnum));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MemberPrimitiveUnTyped<auto PrimitiveType>{
|
||||||
|
match(PrimitiveType){
|
||||||
|
(PrimitiveTypeEnum::Boolean): bool Value;
|
||||||
|
(PrimitiveTypeEnum::Byte): u8 Value;
|
||||||
|
(PrimitiveTypeEnum::Char): char Value;
|
||||||
|
(PrimitiveTypeEnum::Currency): std::error("Primitive currency not used in this protocol");
|
||||||
|
(PrimitiveTypeEnum::Decimal): Decimal Value;
|
||||||
|
(PrimitiveTypeEnum::Double): double Value;
|
||||||
|
(PrimitiveTypeEnum::Int16): s16 Value;
|
||||||
|
(PrimitiveTypeEnum::Int32): s32 Value;
|
||||||
|
(PrimitiveTypeEnum::Int64): s64 Value;
|
||||||
|
(PrimitiveTypeEnum::SByte): s8 Value;
|
||||||
|
(PrimitiveTypeEnum::Single): float Value;
|
||||||
|
(PrimitiveTypeEnum::TimeSpan): TimeSpan Value;
|
||||||
|
(PrimitiveTypeEnum::DateTime): DateTime Value;
|
||||||
|
(PrimitiveTypeEnum::UInt16): u16 Value;
|
||||||
|
(PrimitiveTypeEnum::UInt32): u32 Value;
|
||||||
|
(PrimitiveTypeEnum::UInt64): u64 Value;
|
||||||
|
(PrimitiveTypeEnum::Null): {}
|
||||||
|
(PrimitiveTypeEnum::String):std::error("Can't be String");
|
||||||
|
(_): std::error(std::format("Unexpected {}", PrimitiveType));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MemberReference: RecordTypeEnumT<RecordTypeEnum::MemberReference>{
|
||||||
|
s32 IdRef;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ObjectNull: RecordTypeEnumT<RecordTypeEnum::ObjectNull>{
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ObjectNullMultiple: RecordTypeEnumT<RecordTypeEnum::ObjectNullMultiple>{
|
||||||
|
s32 NullCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ObjectNullMultiple256: RecordTypeEnumT<RecordTypeEnum::ObjectNullMultiple256>{
|
||||||
|
u8 NullCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BinaryObjectString: RecordTypeEnumT<RecordTypeEnum::BinaryObjectString>{
|
||||||
|
s32 ObjectId;
|
||||||
|
LengthPrefixedString Value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SerializationHeaderRecord: RecordTypeEnumT<RecordTypeEnum::SerializedStreamHeader>{
|
||||||
|
s32 RootId;
|
||||||
|
s32 HeaderId;
|
||||||
|
s32 MajorVersion;
|
||||||
|
std::assert_warn(MajorVersion == 1, "MajorVersion should be 1");
|
||||||
|
s32 MinorVersion;
|
||||||
|
std::assert_warn(MinorVersion == 0, "MinorVersion should be 0");
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BinaryLibrary: RecordTypeEnumT<RecordTypeEnum::BinaryLibrary>{
|
||||||
|
s32 LibraryId;
|
||||||
|
LengthPrefixedString LibraryName;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MessageEnd: RecordTypeEnumT<RecordTypeEnum::MessageEnd>{
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CrossAppDomainMap: RecordTypeEnumT<RecordTypeEnum::CrossAppDomainMap>{
|
||||||
|
s32 crossAppDomainArrayIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CrossAppDomainString: RecordTypeEnumT<RecordTypeEnum::CrossAppDomainString>{
|
||||||
|
s32 ObjectId;
|
||||||
|
s32 Value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CrossAppDomainAssembly: RecordTypeEnumT<RecordTypeEnum::CrossAppDomainAssembly>{
|
||||||
|
s32 LibraryId;
|
||||||
|
s32 LibraryIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Record{
|
||||||
|
RecordTypeEnum recordTypeEnum [[no_unique_address, hidden]];
|
||||||
|
match(recordTypeEnum){
|
||||||
|
(RecordTypeEnum::SerializedStreamHeader):
|
||||||
|
std::error("SerializationStreamHeader can only appear at the top of the document");
|
||||||
|
(RecordTypeEnum::ClassWithId): { /* RecordTypeEnum::Object */
|
||||||
|
ClassWithId classWithId;
|
||||||
|
if(!IsUpdatingTrackers){
|
||||||
|
zeroedCurrObjTrackers();
|
||||||
|
_trackers.currentObj.objEnum = _ObjEnum::ClassWithId;
|
||||||
|
_trackers.currentObj.RawPtr = append_value_to_section(classWithId, _TrackersSection);
|
||||||
|
_trackers.currentObj.TypeName.pointerValue = _trackers.objs[classWithId.MetadataId].TypeName.pointerValue;
|
||||||
|
_trackers.currentObj.AssemblyName.pointerValue =_trackers.objs[classWithId.MetadataId].AssemblyName.pointerValue ;
|
||||||
|
if(classWithId.ObjectId != 0)
|
||||||
|
copyCurrObjAtIdTrackers(classWithId.ObjectId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(RecordTypeEnum::SystemClassWithMembers): { /* RecordTypeEnum::ObjectWithMap */
|
||||||
|
SystemClassWithMembers systemClassWithMembers;
|
||||||
|
if(!IsUpdatingTrackers){
|
||||||
|
zeroedCurrObjTrackers();
|
||||||
|
_trackers.currentObj.objEnum = _ObjEnum::SystemClassWithMembers;
|
||||||
|
_trackers.currentObj.RawPtr = append_value_to_section(systemClassWithMembers, _TrackersSection);
|
||||||
|
_trackers.currentObj.TypeName.pointerValue = _trackers.currentObj.RawPtr + offsetOf(systemClassWithMembers, systemClassWithMembers.classInfo.Name);
|
||||||
|
if(systemClassWithMembers.classInfo.ObjectId != 0)
|
||||||
|
copyCurrObjAtIdTrackers(systemClassWithMembers.classInfo.ObjectId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(RecordTypeEnum::ClassWithMembers): { /* RecordTypeEnum::ObjectWithMapAssemId */
|
||||||
|
ClassWithMembers classWithMembers;
|
||||||
|
if(!IsUpdatingTrackers){
|
||||||
|
zeroedCurrObjTrackers();
|
||||||
|
_trackers.currentObj.objEnum = _ObjEnum::ClassWithMembers;
|
||||||
|
_trackers.currentObj.RawPtr = append_value_to_section(classWithMembers, _TrackersSection);
|
||||||
|
_trackers.currentObj.TypeName.pointerValue = _trackers.currentObj.RawPtr + offsetOf(classWithMembers, classWithMembers.classInfo.Name);
|
||||||
|
_trackers.currentObj.AssemblyName.pointerValue = _trackers.libs[classWithMembers.LibraryId].pointerValue;
|
||||||
|
if(classWithMembers.classInfo.ObjectId != 0)
|
||||||
|
copyCurrObjAtIdTrackers(classWithMembers.classInfo.ObjectId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(RecordTypeEnum::SystemClassWithMembersAndTypes): { /* RecordTypeEnum::ObjectWithMapTyped */
|
||||||
|
SystemClassWithMembersAndTypes systemClassWithMembersAndTypes;
|
||||||
|
if(!IsUpdatingTrackers){
|
||||||
|
zeroedCurrObjTrackers();
|
||||||
|
_trackers.currentObj.objEnum = _ObjEnum::SystemClassWithMembersAndTypes;
|
||||||
|
_trackers.currentObj.RawPtr = append_value_to_section(systemClassWithMembersAndTypes, _TrackersSection);
|
||||||
|
_trackers.currentObj.TypeName.pointerValue = _trackers.currentObj.RawPtr + offsetOf(systemClassWithMembersAndTypes, systemClassWithMembersAndTypes.classInfo.Name);
|
||||||
|
if(systemClassWithMembersAndTypes.classInfo.ObjectId != 0)
|
||||||
|
copyCurrObjAtIdTrackers(systemClassWithMembersAndTypes.classInfo.ObjectId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(RecordTypeEnum::ClassWithMembersAndTypes): { /* RecordTypeEnum::ObjectWithMapTypedAssemId */
|
||||||
|
ClassWithMembersAndTypes classWithMembersAndTypes;
|
||||||
|
if(!IsUpdatingTrackers){
|
||||||
|
zeroedCurrObjTrackers();
|
||||||
|
_trackers.currentObj.objEnum = _ObjEnum::ClassWithMembersAndTypes;
|
||||||
|
_trackers.currentObj.RawPtr = append_value_to_section(classWithMembersAndTypes, _TrackersSection);
|
||||||
|
_trackers.currentObj.TypeName.pointerValue = _trackers.currentObj.RawPtr + offsetOf(classWithMembersAndTypes, classWithMembersAndTypes.classInfo.Name);
|
||||||
|
_trackers.currentObj.AssemblyName.pointerValue = _trackers.libs[classWithMembersAndTypes.LibraryId].pointerValue;
|
||||||
|
if(classWithMembersAndTypes.classInfo.ObjectId != 0)
|
||||||
|
copyCurrObjAtIdTrackers(classWithMembersAndTypes.classInfo.ObjectId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(RecordTypeEnum::BinaryObjectString): { /* RecordTypeEnum::ObjectString */
|
||||||
|
BinaryObjectString binaryObjectString;
|
||||||
|
if(!IsUpdatingTrackers){
|
||||||
|
zeroedCurrObjTrackers();
|
||||||
|
_trackers.currentObj.objEnum = _ObjEnum::BinaryObjectString;
|
||||||
|
_trackers.currentObj.RawPtr = append_value_to_section(binaryObjectString, _TrackersSection);
|
||||||
|
if(binaryObjectString.ObjectId != 0)
|
||||||
|
copyCurrObjAtIdTrackers(binaryObjectString.ObjectId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(RecordTypeEnum::BinaryArray): { /* RecordTypeEnum::Array */
|
||||||
|
BinaryArray binaryArray;
|
||||||
|
if(!IsUpdatingTrackers){
|
||||||
|
zeroedCurrObjTrackers();
|
||||||
|
_trackers.currentObj.objEnum = _ObjEnum::BinaryArray;
|
||||||
|
_trackers.currentObj.RawPtr = append_value_to_section(binaryArray, _TrackersSection);
|
||||||
|
if(binaryArray.ObjectId != 0)
|
||||||
|
copyCurrObjAtIdTrackers(binaryArray.ObjectId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(RecordTypeEnum::MemberPrimitiveTyped): {
|
||||||
|
MemberPrimitiveTyped memberPrimitiveTyped;
|
||||||
|
}
|
||||||
|
(RecordTypeEnum::MemberReference): {
|
||||||
|
MemberReference memberReference;
|
||||||
|
}
|
||||||
|
(RecordTypeEnum::ObjectNull): {}
|
||||||
|
(RecordTypeEnum::MessageEnd): break;
|
||||||
|
(RecordTypeEnum::BinaryLibrary): { /* RecordTypeEnum::Assembly */
|
||||||
|
BinaryLibrary library;
|
||||||
|
if(!IsUpdatingTrackers)
|
||||||
|
_trackers.libs[library.LibraryId].pointerValue = append_value_to_section(library.LibraryName, _TrackersSection);
|
||||||
|
}
|
||||||
|
(RecordTypeEnum::ObjectNullMultiple256): {
|
||||||
|
ObjectNullMultiple256 objectNullMultiple256;
|
||||||
|
}
|
||||||
|
(RecordTypeEnum::ObjectNullMultiple): {
|
||||||
|
ObjectNullMultiple objectNullMultiple;
|
||||||
|
}
|
||||||
|
(RecordTypeEnum::ArraySinglePrimitive): {
|
||||||
|
ArraySinglePrimitive arraySinglePrimitive;
|
||||||
|
if(!IsUpdatingTrackers){
|
||||||
|
zeroedCurrObjTrackers();
|
||||||
|
_trackers.currentObj.objEnum = _ObjEnum::ArraySinglePrimitive;
|
||||||
|
_trackers.currentObj.RawPtr = append_value_to_section(arraySinglePrimitive, _TrackersSection);
|
||||||
|
if(arraySinglePrimitive.arrayInfo.ObjectId != 0)
|
||||||
|
copyCurrObjAtIdTrackers(arraySinglePrimitive.arrayInfo.ObjectId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(RecordTypeEnum::ArraySingleObject): {
|
||||||
|
ArraySingleObject arraySingleObject;
|
||||||
|
}
|
||||||
|
(RecordTypeEnum::ArraySingleString): {
|
||||||
|
ArraySingleString arraySingleString;
|
||||||
|
}
|
||||||
|
(RecordTypeEnum::CrossAppDomainMap):
|
||||||
|
CrossAppDomainMap crossAppDomainMap;
|
||||||
|
(RecordTypeEnum::CrossAppDomainString):
|
||||||
|
CrossAppDomainString crossAppDomainString;
|
||||||
|
(RecordTypeEnum::CrossAppDomainAssembly):
|
||||||
|
CrossAppDomainAssembly crossAppDomainAssembly;
|
||||||
|
(RecordTypeEnum::MethodCall): {
|
||||||
|
BinaryMethodCall binaryMethodCall;
|
||||||
|
}
|
||||||
|
(RecordTypeEnum::MethodReturn): {
|
||||||
|
BinaryMethodReturn binaryMethodReturn;
|
||||||
|
}
|
||||||
|
(_): std::error(std::format("Unrecognized {}", recordTypeEnum));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DotNetBinnaryFormatter{
|
||||||
|
SerializationHeaderRecord Header;
|
||||||
|
Record records[while(std::mem::read_unsigned($, 1) != RecordTypeEnum::MessageEnd)];
|
||||||
|
MessageEnd End;
|
||||||
|
if(!IsUpdatingTrackers && NeedUpdateTrackers){
|
||||||
|
IsUpdatingTrackers = true;
|
||||||
|
_Trackers _trackers @ 0x0 in _TrackersSection;
|
||||||
|
IsUpdatingTrackers = false;
|
||||||
|
NeedUpdateTrackers = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _ObjTracker{
|
||||||
|
_Ptr<LengthPrefixedString, u64> TypeName;
|
||||||
|
_Ptr<LengthPrefixedString, u64> AssemblyName;
|
||||||
|
_ObjEnum objEnum;
|
||||||
|
u64 RawPtr [[no_unique_address]];
|
||||||
|
/* Only enable the one we actually use to avoid significant slow down */
|
||||||
|
match(objEnum){
|
||||||
|
(_ObjEnum::Empty):
|
||||||
|
u64 ptr;
|
||||||
|
/*
|
||||||
|
(_ObjEnum::ClassWithId): // _ObjEnum::Object
|
||||||
|
_Ptr<ClassWithId, u64> classWithId;
|
||||||
|
*/
|
||||||
|
(_ObjEnum::SystemClassWithMembers): // _ObjEnum::ObjectWithMap
|
||||||
|
_Ptr<SystemClassWithMembers, u64> systemClassWithMembers;
|
||||||
|
(_ObjEnum::ClassWithMembers): // _ObjEnum::ObjectWithMapAssemId
|
||||||
|
_Ptr<ClassWithMembers, u64> classWithMembers;
|
||||||
|
(_ObjEnum::SystemClassWithMembersAndTypes): // _ObjEnum::ObjectWithMapTyped
|
||||||
|
_Ptr<SystemClassWithMembersAndTypes, u64> systemClassWithMemberAndTypes;
|
||||||
|
(_ObjEnum::ClassWithMembersAndTypes): // _ObjEnum::ObjectWithMapTypedAssemId
|
||||||
|
_Ptr<ClassWithMembersAndTypes, u64> classWithMembersAndTypes;
|
||||||
|
/*
|
||||||
|
(_ObjEnum::BinaryObjectString): // _ObjEnum::ObjectString
|
||||||
|
_Ptr<BinaryObjectString, u64> binaryObjectString;
|
||||||
|
(_ObjEnum::BinaryArray): // _ObjEnum::Array
|
||||||
|
_Ptr<BinaryArray, u64> binaryArray;
|
||||||
|
(_ObjEnum::MemberPrimitiveTyped):
|
||||||
|
_Ptr<MemberPrimitiveTyped, u64> memberPrimitiveTyped;
|
||||||
|
(_ObjEnum::MemberReference):
|
||||||
|
_Ptr<MemberReference, u64> memberReference;
|
||||||
|
(_ObjEnum::BinaryLibrary): // _ObjEnum::Assembly
|
||||||
|
_Ptr<BinaryLibrary, u64> library;
|
||||||
|
(_ObjEnum::ObjectNullMultiple256):
|
||||||
|
_Ptr<ObjectNullMultiple256, u64> objectNullMultiple256;
|
||||||
|
(_ObjEnum::ObjectNullMultiple):
|
||||||
|
_Ptr<ObjectNullMultiple, u64> objectNullMultiple;
|
||||||
|
(_ObjEnum::ArraySinglePrimitive):
|
||||||
|
_Ptr<ArraySinglePrimitive, u64> arraySinglePrimitive;
|
||||||
|
(_ObjEnum::ArraySingleObject):
|
||||||
|
_Ptr<ArraySingleObject, u64> arraySingleObject;
|
||||||
|
(_ObjEnum::ArraySingleString):
|
||||||
|
_Ptr<ArraySingleString, u64> arraySingleString;
|
||||||
|
(_ObjEnum::CrossAppDomainMap):
|
||||||
|
_Ptr<CrossAppDomainMap, u64> crossAppDomainMap;
|
||||||
|
(_ObjEnum::CrossAppDomainString):
|
||||||
|
_Ptr<CrossAppDomainString, u64> crossAppDomainString;
|
||||||
|
(_ObjEnum::CrossAppDomainAssembly):
|
||||||
|
_Ptr<CrossAppDomainAssembly, u64> crossAppDomainAssembly;
|
||||||
|
(_ObjEnum::MethodCall):
|
||||||
|
_Ptr<BinaryMethodCall, u64> binaryMethodCall;
|
||||||
|
(_ObjEnum::MethodReturn):
|
||||||
|
_Ptr<BinaryMethodReturn, u64> binaryMethodReturn;
|
||||||
|
*/
|
||||||
|
(_): u64 ptr; //std::error(std::format("Unexpected {}", objEnum));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Should be an In variable with default non zero value in the future until we use a hash map */
|
||||||
|
#define _OBJECTS_TRACKER_CNT 232
|
||||||
|
#define _LIBRARIES_CNT 8
|
||||||
|
|
||||||
|
struct _Trackers{
|
||||||
|
_ObjTracker currentObj;
|
||||||
|
/* TODO: this should really be an hash map, the algorithm that generated is unspecified */
|
||||||
|
_ObjTracker objs[_OBJECTS_TRACKER_CNT];
|
||||||
|
_Ptr<LengthPrefixedString, u64> libs[_LIBRARIES_CNT];
|
||||||
|
};
|
||||||
|
|
||||||
|
std::mem::set_section_size(_TrackersSection, sizeof(_trackers));
|
||||||
|
|
||||||
|
DotNetBinnaryFormatter dotNetBinnaryFormatter @ 0x0;
|
||||||
73
patterns/dpapiblob.hexpat
Normal file
73
patterns/dpapiblob.hexpat
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#pragma description "DPAPI Blob"
|
||||||
|
|
||||||
|
import type.guid;
|
||||||
|
import std.mem;
|
||||||
|
|
||||||
|
enum ALG_ID : u32 {
|
||||||
|
CALG_DH_EPHEM = 0x0000aa02,
|
||||||
|
CALG_DH_SF = 0x0000aa01,
|
||||||
|
CALG_DSS_SIGN = 0x00002200,
|
||||||
|
CALG_ECDH = 0x0000aa05,
|
||||||
|
CALG_ECDH_EPHEM = 0x0000ae06,
|
||||||
|
CALG_ECDSA = 0x00002203,
|
||||||
|
CALG_ECMQV = 0x0000a001,
|
||||||
|
CALG_HASH_REPLACE_OWF = 0x0000800b,
|
||||||
|
CALG_HUGHES_MD5 = 0x0000a003,
|
||||||
|
CALG_HMAC = 0x00008009,
|
||||||
|
CALG_KEA_KEYX = 0x0000aa04,
|
||||||
|
CALG_MAC = 0x00008005,
|
||||||
|
CALG_MD2 = 0x00008001,
|
||||||
|
CALG_MD4 = 0x00008002,
|
||||||
|
CALG_MD5 = 0x00008003,
|
||||||
|
CALG_NO_SIGN = 0x00002000,
|
||||||
|
CALG_OID_INFO_CNG_ONLY = 0xffffffff,
|
||||||
|
CALG_OID_INFO_PARAMETERS = 0xfffffffe,
|
||||||
|
CALG_PCT1_MASTER = 0x00004c04,
|
||||||
|
CALG_RC2 = 0x00006602,
|
||||||
|
CALG_RC4 = 0x00006801,
|
||||||
|
CALG_RC5 = 0x0000660d,
|
||||||
|
CALG_RSA_KEYX = 0x0000a400,
|
||||||
|
CALG_RSA_SIGN = 0x00002400,
|
||||||
|
CALG_SCHANNEL_ENC_KEY = 0x00004c07,
|
||||||
|
CALG_SCHANNEL_MAC_KEY = 0x00004c03,
|
||||||
|
CALG_SCHANNEL_MASTER_HASH = 0x00004c02,
|
||||||
|
CALG_SEAL = 0x00006802,
|
||||||
|
CALG_SHA = 0x00008004,
|
||||||
|
CALG_SHA1 = 0x00008004,
|
||||||
|
CALG_SHA_256 = 0x0000800c,
|
||||||
|
CALG_SHA_384 = 0x0000800d,
|
||||||
|
CALG_SHA_512 = 0x0000800e,
|
||||||
|
CALG_SKIPJACK = 0x0000660a,
|
||||||
|
CALG_SSL2_MASTER = 0x00004c05,
|
||||||
|
CALG_SSL3_MASTER = 0x00004c01,
|
||||||
|
CALG_SSL3_SHAMD5 = 0x00008008,
|
||||||
|
CALG_TEK = 0x0000660b,
|
||||||
|
CALG_TLS1_MASTER = 0x00004c06,
|
||||||
|
CALG_TLS1PRF = 0x0000800a
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DPAPI_BLOB{
|
||||||
|
u32 version[[name("Version")]];
|
||||||
|
type::GUID providerguid[[name("ProviderGUID")]];
|
||||||
|
u32 masterguid[[name("MasterKeyVersion")]];
|
||||||
|
type::GUID guid[[name("MasterKeyGUID")]];
|
||||||
|
u32 flags[[name("Flags")]];
|
||||||
|
u32 desclen [[name("DescriptionLen")]];
|
||||||
|
char16 desc[desclen / 0x02 ] [[name("Description")]];
|
||||||
|
ALG_ID cryptid [[name("AlgCryptId")]];
|
||||||
|
u32 algcryptlen[[name("AlgCryptLen")]];
|
||||||
|
u32 saltlen [[name("SaltLen")]];
|
||||||
|
char salt[saltlen][[name("Salt")]];
|
||||||
|
u32 hmackeylen[[name("HMACKeyLen")]];
|
||||||
|
char hmackey[hmackeylen][[name("HMACKey")]];
|
||||||
|
ALG_ID algid[[name("AlgHashId")]];
|
||||||
|
u32 alghashkeylen[[name("AlgHashKeyLen")]];
|
||||||
|
u32 hmac2keylen[[name("HMAC2keylen")]];
|
||||||
|
char hmac2[hmac2keylen][[name("HMAC2Key")]];
|
||||||
|
u32 datalen[[name("DataLen")]];
|
||||||
|
char data[datalen][[name("Data")]];
|
||||||
|
u32 signlen[[name("signlen")]];
|
||||||
|
char signhash[signlen][[name("SignHash")]];
|
||||||
|
};
|
||||||
|
|
||||||
|
DPAPI_BLOB dpapiblob @0x00 [[name("DPAPIBlob")]];
|
||||||
124
patterns/dpapimasterkey.hexpat
Normal file
124
patterns/dpapimasterkey.hexpat
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
#pragma description "DPAPIMasterKey"
|
||||||
|
|
||||||
|
/*
|
||||||
|
FilePath: C:\Users\<USER>\AppData\Roaming\Microsoft\Protect\<SID>
|
||||||
|
This files are hidden.
|
||||||
|
To unhide it,
|
||||||
|
1. Open Command Prompt (cmd.exe).
|
||||||
|
2. Run the following command:
|
||||||
|
- attrib -h -s
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type.guid;
|
||||||
|
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/seccrypto/alg-id
|
||||||
|
enum ALG_ID : u32 {
|
||||||
|
CALG_DH_EPHEM = 0x0000aa02,
|
||||||
|
CALG_DH_SF = 0x0000aa01,
|
||||||
|
CALG_DSS_SIGN = 0x00002200,
|
||||||
|
CALG_ECDH = 0x0000aa05,
|
||||||
|
CALG_ECDH_EPHEM = 0x0000ae06,
|
||||||
|
CALG_ECDSA = 0x00002203,
|
||||||
|
CALG_ECMQV = 0x0000a001,
|
||||||
|
CALG_HASH_REPLACE_OWF = 0x0000800b,
|
||||||
|
CALG_HUGHES_MD5 = 0x0000a003,
|
||||||
|
CALG_HMAC = 0x00008009,
|
||||||
|
CALG_KEA_KEYX = 0x0000aa04,
|
||||||
|
CALG_MAC = 0x00008005,
|
||||||
|
CALG_MD2 = 0x00008001,
|
||||||
|
CALG_MD4 = 0x00008002,
|
||||||
|
CALG_MD5 = 0x00008003,
|
||||||
|
CALG_NO_SIGN = 0x00002000,
|
||||||
|
CALG_OID_INFO_CNG_ONLY = 0xffffffff,
|
||||||
|
CALG_OID_INFO_PARAMETERS = 0xfffffffe,
|
||||||
|
CALG_PCT1_MASTER = 0x00004c04,
|
||||||
|
CALG_RC2 = 0x00006602,
|
||||||
|
CALG_RC4 = 0x00006801,
|
||||||
|
CALG_RC5 = 0x0000660d,
|
||||||
|
CALG_RSA_KEYX = 0x0000a400,
|
||||||
|
CALG_RSA_SIGN = 0x00002400,
|
||||||
|
CALG_SCHANNEL_ENC_KEY = 0x00004c07,
|
||||||
|
CALG_SCHANNEL_MAC_KEY = 0x00004c03,
|
||||||
|
CALG_SCHANNEL_MASTER_HASH = 0x00004c02,
|
||||||
|
CALG_SEAL = 0x00006802,
|
||||||
|
CALG_SHA = 0x00008004,
|
||||||
|
CALG_SHA1 = 0x00008004,
|
||||||
|
CALG_SHA_256 = 0x0000800c,
|
||||||
|
CALG_SHA_384 = 0x0000800d,
|
||||||
|
CALG_SHA_512 = 0x0000800e,
|
||||||
|
CALG_SKIPJACK = 0x0000660a,
|
||||||
|
CALG_SSL2_MASTER = 0x00004c05,
|
||||||
|
CALG_SSL3_MASTER = 0x00004c01,
|
||||||
|
CALG_SSL3_SHAMD5 = 0x00008008,
|
||||||
|
CALG_TEK = 0x0000660b,
|
||||||
|
CALG_TLS1_MASTER = 0x00004c06,
|
||||||
|
CALG_TLS1PRF = 0x0000800a
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct CREDHIST_MASTERKEY {
|
||||||
|
u32 version[[name("Version")]];
|
||||||
|
type::GUID guid[[name("GUID")]];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DOMAINKEY_MASTERKEY {
|
||||||
|
u32 version[[name("Version")]];
|
||||||
|
u32 seclen[[name("SecretLen")]];
|
||||||
|
u32 accesschklen[[name("AccessCheckLen")]];
|
||||||
|
type::GUID backupguid_[[name("BackupKeyGUID")]];
|
||||||
|
char blob[seclen][[name("Secret")]];
|
||||||
|
char accesschk[accesschklen][[name("AccessCheck")]];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BACKUP_MASTERKEY {
|
||||||
|
u32 start = $;
|
||||||
|
u32 version[[name("Version")]];
|
||||||
|
char salt[16][[name("Salt")]];
|
||||||
|
u32 rounds [[name("PBKDF2IterationCount")]];
|
||||||
|
ALG_ID alghashid[[name("HMACAlgId")]];
|
||||||
|
ALG_ID algcryptid[[name("CryptAlgId")]];
|
||||||
|
u32 meta = $ - start;
|
||||||
|
char key[parent.backupkeylen - meta][[name("Key")]];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PASSWORD_MASTERKEY {
|
||||||
|
u32 start = $;
|
||||||
|
u32 version[[name("Version")]];
|
||||||
|
char salt[16][[name("Salt")]];
|
||||||
|
u32 rounds [[name("PBKDF2IterationCount")]];
|
||||||
|
ALG_ID alghashid[[name("HMACAlgId")]];
|
||||||
|
ALG_ID algcryptid[[name("CryptAlgId")]];
|
||||||
|
u32 meta = $ - start;
|
||||||
|
char key[parent.masterkeylen - meta][[name("Key")]];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DPAPIMasterKey {
|
||||||
|
u32 version[[name("Version")]];
|
||||||
|
u32 unk1[[name("Unknown1")]];
|
||||||
|
u32 unk2[[name("Unknown2")]];
|
||||||
|
char16 guid[0x24][[name("GUID"), comment("This GUID is the fileName itself")]];
|
||||||
|
u32 unk3[[name("Unknown3")]];
|
||||||
|
u32 unk4[[name("Unknown4")]];
|
||||||
|
u32 policy[[name("Policy")]];
|
||||||
|
u64 masterkeylen [[name("MasterKeyLen")]];
|
||||||
|
u64 backupkeylen [[name("BackupKeyLen")]];
|
||||||
|
u64 credhistlen [[name("CredHistoryLen")]];
|
||||||
|
u64 domainkeylen [[name("DomainKeyLen")]];
|
||||||
|
if (masterkeylen > 0){
|
||||||
|
PASSWORD_MASTERKEY masterkey[[name("MasterKey")]];
|
||||||
|
}
|
||||||
|
if (backupkeylen > 0){
|
||||||
|
BACKUP_MASTERKEY backupkey[[name("BackupKey")]];
|
||||||
|
}
|
||||||
|
if (credhistlen > 0){
|
||||||
|
CREDHIST_MASTERKEY credhistkey[[name("CredHistoryKey")]];
|
||||||
|
}
|
||||||
|
if (domainkeylen > 0){
|
||||||
|
DOMAINKEY_MASTERKEY domainkey[[name("DomainKey")]];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DPAPIMasterKey masterkey @0x00[[name("DPAPIMasterKey")]];
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
#pragma description .DS_Store file format
|
#pragma description macOS .DS_Store
|
||||||
|
#pragma magic [ 42 75 64 31 ] @ 0x04
|
||||||
|
|
||||||
// Apple macOS .DS_Store format
|
// Apple macOS .DS_Store format
|
||||||
#pragma endian big
|
#pragma endian big
|
||||||
#include <std/io.pat>
|
import std.io;
|
||||||
|
|
||||||
struct RecordEntry {
|
struct RecordEntry {
|
||||||
u32 length;
|
u32 length;
|
||||||
|
|||||||
119
patterns/dted.hexpat
Normal file
119
patterns/dted.hexpat
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
#pragma description Digital Terrain Elevation Data
|
||||||
|
#pragma endian big
|
||||||
|
|
||||||
|
#pragma magic [ 4C 48 55 ] @ 0x00
|
||||||
|
|
||||||
|
import std.core;
|
||||||
|
import std.io;
|
||||||
|
import std.mem;
|
||||||
|
import std.string;
|
||||||
|
|
||||||
|
|
||||||
|
enum Magic:u24 {
|
||||||
|
UHL = 0x55484C,
|
||||||
|
DSI = 0x445349,
|
||||||
|
ACC = 0x414343,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UHL {
|
||||||
|
Magic magic;
|
||||||
|
char one;
|
||||||
|
char lon[8];
|
||||||
|
char lat[8];
|
||||||
|
char lon_data_interval[4];
|
||||||
|
char lat_data_interval[4];
|
||||||
|
char accuracy[4];
|
||||||
|
char security_code[3];
|
||||||
|
char uniq_ref[12];
|
||||||
|
char lon_lines[4];
|
||||||
|
char lat_points[4];
|
||||||
|
char multi_accuracy;
|
||||||
|
char reserved[24];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DSI {
|
||||||
|
Magic magic;
|
||||||
|
char classification;
|
||||||
|
char stuff1[29];
|
||||||
|
char stuff2[26];
|
||||||
|
char product_level[5];
|
||||||
|
char uniq_ref[15];
|
||||||
|
char reserved[8];
|
||||||
|
char data_edition[2];
|
||||||
|
char match_version;
|
||||||
|
char maint_date[4];
|
||||||
|
char match_date[4];
|
||||||
|
char main_desc_code[4];
|
||||||
|
char producer_code[8];
|
||||||
|
char reserved2[16];
|
||||||
|
char product_spec[9];
|
||||||
|
char numbers[2];
|
||||||
|
char product_spec_date[4];
|
||||||
|
char vertical_datum[3];
|
||||||
|
char horizontal_datum[5];
|
||||||
|
char digitizing_system[10];
|
||||||
|
char compilation_date[4];
|
||||||
|
char reserved3[22];
|
||||||
|
char lat_origin[9];
|
||||||
|
char lon_origin[10];
|
||||||
|
char lat_sw_corner[7];
|
||||||
|
char lon_sw_corner[8];
|
||||||
|
char lat_nw_corner[7];
|
||||||
|
char lon_nw_corner[8];
|
||||||
|
char lat_ne_corner[7];
|
||||||
|
char lon_ne_corner[8];
|
||||||
|
char lat_se_corner[7];
|
||||||
|
char lon_se_corner[8];
|
||||||
|
char clockwise_orientation[9];
|
||||||
|
char lat_interval[4];
|
||||||
|
char lon_interval[4];
|
||||||
|
char lat_lines[4];
|
||||||
|
char lon_lines[4];
|
||||||
|
char partial_cell[2];
|
||||||
|
char reserved4[101];
|
||||||
|
char reserved5[100];
|
||||||
|
char reserved6[156];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ACCSub {
|
||||||
|
char abs_vertical_accuracy[4];
|
||||||
|
char abs_horizontal_accuracy[4];
|
||||||
|
char rel_vertical_accuracy[4];
|
||||||
|
char rel_horizontal_accuracy[4];
|
||||||
|
char num_coords[2];
|
||||||
|
char pairs[19*14];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ACC {
|
||||||
|
Magic magic;
|
||||||
|
char abs_horizontal_accuracy[4];
|
||||||
|
char abs_vertical_accuracy[4];
|
||||||
|
char rel_horizontal_accuracy[4];
|
||||||
|
char rel_vertical_accuracy[4];
|
||||||
|
char reserved1[4];
|
||||||
|
char reserved2[1];
|
||||||
|
char reserved3[31];
|
||||||
|
char multi_accuracy_outline[2]; // determines sub regions
|
||||||
|
ACCSub subs[9];
|
||||||
|
char reserved4[18];
|
||||||
|
char reserved5[69];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DataRecords {
|
||||||
|
char magic;
|
||||||
|
s24 data_block_count;
|
||||||
|
s16 lon_count;
|
||||||
|
s16 lat_count;
|
||||||
|
s16 elevation[std::string::parse_int(parent.dsi.lat_lines, 10)];
|
||||||
|
u32 checksum;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DTED {
|
||||||
|
UHL uhl;
|
||||||
|
DSI dsi;
|
||||||
|
ACC acc;
|
||||||
|
DataRecords records[std::string::parse_int(this.dsi.lon_lines, 10)];
|
||||||
|
};
|
||||||
|
|
||||||
|
DTED dted @ 0x00;
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user