Compare commits

..

142 Commits

Author SHA1 Message Date
WerWolv
fd7beb642f build: Bumped version to 1.23.2 2022-09-17 15:49:19 +02:00
WerWolv
b766cf0807 patterns: Updated pattern language 2022-09-17 15:48:12 +02:00
Nik
6c9469961b git: Added flatpak link to install guide 2022-09-17 13:35:54 +02:00
WerWolv
d8844236d0 git: Added install guide file, cleaned up readme 2022-09-17 10:38:02 +02:00
WerWolv
60eb59c605 build: Bumped version to 1.23.1 2022-09-17 09:00:39 +02:00
WerWolv
6a7bbb8752 fix: Crash on some Linux systems when opening files 2022-09-17 08:55:18 +02:00
WerWolv
e4431749e1 patterns: Updated pattern language 2022-09-16 15:12:12 +02:00
WerWolv
c587b357eb patterns: Updated pattern language 2022-09-16 10:52:49 +02:00
WerWolv
7357c26d54 ux: Pre-fill remove popup size value with current selection size 2022-09-16 08:33:18 +02:00
WerWolv
73ca45ad3d git: Updated winget-create to the latest release 2022-09-16 08:30:42 +02:00
WerWolv
bf00503d1f fix: BufferedReader messing up the second to last byte 2022-09-16 08:30:28 +02:00
WerWolv
44a90f5c7d build: Bumped version to 1.23.0 2022-09-15 14:40:14 +02:00
WerWolv
5c3ee9f499 fix: Dangerous function call popup keep appearing 2022-09-15 11:38:22 +02:00
WerWolv
03f357efd1 patterns: Updated pattern language 2022-09-15 11:31:13 +02:00
WerWolv
5462575f5c sys: Allow multiple files to be opened through the command line 2022-09-15 09:48:02 +02:00
WerWolv
120e2bc300 sys: Fix opening files in existing instance not working on Intel GPUs 2022-09-15 09:47:47 +02:00
WerWolv
c3137df83c patterns: Updated pattern language 2022-09-15 09:46:38 +02:00
WerWolv
737155a226 patterns: Added hex::core::get_selection function 2022-09-15 09:34:59 +02:00
WerWolv
66d64cf020 patterns: Refactor creation of default runtime 2022-09-15 09:34:40 +02:00
WerWolv
42f5c0f484 fix: Tasks being interrupted even if they already finished 2022-09-14 13:51:48 +02:00
WerWolv
75047e26e2 feat: Added various new Copy as... options 2022-09-13 23:48:47 +02:00
Colin Kinloch
9fa6d82775 build: Install Database files from subdirectory in offline builds (#737)
Signed-off-by: Colin Kinloch <colin.kinloch@collabora.com>

Signed-off-by: Colin Kinloch <colin.kinloch@collabora.com>
Co-authored-by: Colin Kinloch <colin.kinloch@collabora.com>
2022-09-13 22:34:33 +02:00
WerWolv
d1468984e7 fix: Copy as... -> ASCII Art inserting too much whitespace 2022-09-13 22:02:57 +02:00
WerWolv
20a2331504 feat: Allow task stop button to abort pattern evaluation 2022-09-13 16:05:41 +02:00
WerWolv
5b00c8ee08 feat: Added find view reset button 2022-09-13 14:22:18 +02:00
WerWolv
bda4aadc54 fix: Sequence escape codes 2022-09-13 14:10:52 +02:00
WerWolv
9d7e2eccac feat: Added "Require full match" toggle to regex string search 2022-09-13 14:06:19 +02:00
WerWolv
8c219b981c fix: Searching for invalid binary sequence causing too many matches 2022-09-13 14:05:48 +02:00
WerWolv
7d87c8bb98 patterns: Added references 2022-09-13 13:14:36 +02:00
WerWolv
13afd96806 fix: Build issues due to invalid capture 2022-09-12 23:45:37 +02:00
WerWolv
4fb74a1769 patterns: Updated pattern language 2022-09-12 21:28:29 +02:00
WerWolv
aa658b7dbc sys: Make sure constexpr variables don't get copied onto the stack 2022-09-12 21:28:02 +02:00
xtexChooser
7e3601989a lang: Update Chinese(Simplified) translation (#739) 2022-09-11 21:56:55 +02:00
WerWolv
3a1c0f8d66 fix: Disk provider slowing down loading of ImHex 2022-09-11 21:06:15 +02:00
WerWolv
91160b4311 fix: Copy as... function sometimes producing invalid results
Fixes #738
2022-09-09 20:13:49 +02:00
WerWolv
83f4093796 fix: Rendering of pattern array entries not working correctly 2022-09-08 23:03:58 +02:00
iTrooz_
f219395b25 build: Added AppImage zsync and updated metadata (#733)
* added update information

* upload zsync

* set version of appimage

* release: do not execute steps which needs a token when not provided

* set the appimage output name directly in the recipe file

* add metainfo file in every Linux package

* update metainfo file

* set categories in the metainfo file

* add both .metainfo.xml and .appdata.xml files because it is the old standard still wanted by some things

* actually use WerWolv's repository for AppImage updates

* rename metainfo files

* Typo : appdata and not appinfo

* split screenshots
2022-09-08 09:31:49 +02:00
iTrooz_
ae6a7ad8e5 build: Change Ubuntu package name, updated README (#734)
* rename Ubuntu 22.04 deb

* fix typo in readme

* says explicitely that AppImage is available for all distributions
2022-09-08 09:30:56 +02:00
WerWolv
d990ee102a sys: More cleanup 2022-09-07 23:11:24 +02:00
WerWolv
cfde9939b4 sys: Refactor and cleanup pattern drawer 2022-09-07 23:11:13 +02:00
iTrooz_
a22725bb67 build: Cleanup PKGBUILD (#732)
* [From Morten Linderud] update PKGBUILD

* quote strings in PKGBUILD

* do not use ls to

* do not hardcode version
2022-09-07 22:23:56 +02:00
WerWolv
7a4040f6ec ui: Fixed indentation of sealed patterns in pattern data view 2022-09-07 22:21:44 +02:00
WerWolv
2fbb351314 patterns: Updated pattern language 2022-09-07 11:32:47 +02:00
WerWolv
96e85c0685 ui: Removed unused space in hex editor footer 2022-09-07 11:32:33 +02:00
WerWolv
50577c9ea0 patterns: Updated pattern language 2022-09-07 00:14:05 +02:00
WerWolv
073323b517 ui: Fix invalid indentation with inlined patterns 2022-09-06 20:04:55 +02:00
WerWolv
37cc8f3aae patterns: Updated pattern language 2022-09-06 10:50:26 +02:00
WerWolv
6367152650 ux: Fixed welcome screen settings button not always working 2022-09-06 10:50:17 +02:00
WerWolv
ffbaef3872 build: Make sure cmake gets reconfigured when version file changes 2022-09-06 10:43:43 +02:00
WerWolv
a0b2473bf4 ui: Improved pattern color visualization 2022-09-05 23:34:20 +02:00
WerWolv
95a3104a56 sys: Only display FPS in debug builds 2022-09-05 22:37:28 +02:00
WerWolv
2d5f77730b patterns: Updated pattern language 2022-09-05 22:09:44 +02:00
WerWolv
033a0dfbb9 patterns: Updated pattern language 2022-09-05 14:16:44 +02:00
WerWolv
cb682b6e21 ui: Fixed graphics artifacts on welcome screen 2022-09-05 14:16:31 +02:00
WerWolv
7312908d4d resources: Invert colors of logo 2022-09-04 21:36:00 +02:00
WerWolv
b44f6035b3 resources: Added dark mode for logo text 2022-09-04 21:18:09 +02:00
WerWolv
b6bc8abf83 git: Added better logo to readme 2022-09-04 20:51:07 +02:00
WerWolv
c60c1154b9 patterns: Updated pattern language
Fixes #276
2022-09-04 20:37:40 +02:00
Jonathan Wright
219afb6244 build: Change appdata metadata file license to CC0 (#727) 2022-09-04 20:24:04 +02:00
WerWolv
22b6bdb5cf feat: Added Copy as -> Address option to Edit menu
Closes #725
2022-09-04 14:23:09 +02:00
WerWolv
d9a47fe815 fix: Crashes when resizing file
Fixes #721
2022-09-04 11:16:24 +02:00
Nik
45e987b413 git: Fixed Arch Linux package name in readme 2022-09-04 01:23:51 +02:00
Kainoa Kanter
a920696d03 git: Update AUR instructions (#722)
`yay install` is not a proper verb
2022-09-04 00:50:47 +02:00
WerWolv
f72b153fe0 build: Bumped version to 1.22.0 2022-09-04 00:05:27 +02:00
WerWolv
d240b4ed49 fix: Build errors 2022-09-04 00:04:27 +02:00
WerWolv
1a21627cdb ui: Added error popup when an exception is thrown in a task 2022-09-03 23:56:57 +02:00
WerWolv
0a115a3c03 fix: Filtering search occurrences in Find view with multiple files being broken
Fixes #685
2022-09-03 23:15:30 +02:00
WerWolv
7ef11f566b fix: Crash when resizing a non-writable provider
Fixes #704
2022-09-03 23:08:40 +02:00
WerWolv
7f6aa9f9a6 fix: Backwards searching being broken
Fixes #713
2022-09-03 23:02:46 +02:00
WerWolv
4df1496a0f patterns: Properly set current base address in pattern language runtime
Fixes #714
2022-09-03 22:04:41 +02:00
WerWolv
b68eb0bb5e patterns: Fixed accessing global variables inside [[format]] functions
Fixes #720
2022-09-03 21:34:54 +02:00
WerWolv
7c0fb7c4f2 patterns: Updated pattern language 2022-09-03 17:15:42 +02:00
Nik
ede8048680 build: Added missing language files to cmake script 2022-09-02 16:27:31 +02:00
iTrooz_
b10ba8fea0 build: Add NoGPU (Software Rendering) version for Windows (#716)
* add NoGPU (Software Rendering) version for Windows

* rename the NoGPU artifact

* add emoji to a step
2022-09-02 16:12:02 +02:00
iTrooz_
3eb2cca286 build: Add text to the PORTABLE file (#718) 2022-09-02 16:11:19 +02:00
mirusu400
721ac837e0 lang: Add Korean Translation (#719)
* Add ko-KR translation

* Remove Fallbackentry
2022-09-02 16:10:54 +02:00
Jonathan Wright
f6fef35d3d docs: Add install instructions for Linux distros (#691)
Co-authored-by: iTrooz_ <itrooz@protonmail.com>
2022-09-01 20:32:50 +02:00
iTrooz_
0569770239 git: Added NoGPU dmg for MacOS (#708) 2022-08-30 09:47:39 +02:00
WerWolv
6689b8ebfa patterns: Updated pattern language 2022-08-29 16:33:40 +02:00
WerWolv
3cb6c4f775 fix: Buffered reader returning zeros if provider size is below 16MiB
Fixes #707
2022-08-29 16:32:32 +02:00
WerWolv
b687eb88f9 fix: Pattern source code not being loaded correctly from project files 2022-08-29 13:15:17 +02:00
WerWolv
33a375910a sys: Added "New File..." menu item and shortcut 2022-08-28 20:55:48 +02:00
WerWolv
a620400e4e patterns: Fixed unions 2022-08-28 17:53:47 +02:00
WerWolv
cc7dc3597b patterns: Fixed base_address pragma not working correctly 2022-08-28 17:53:33 +02:00
WerWolv
60b5842e94 fix: Signed data inspector rows displaying invalid values
Fixes #706
2022-08-28 12:55:26 +02:00
WerWolv
2b9c6ec447 patterns: Updated pattern language 2022-08-28 12:35:36 +02:00
WerWolv
742a4e53b5 patterns: Updated pattern language 2022-08-27 14:29:04 +02:00
WerWolv
0cd10b6b70 patterns: Updated pattern language 2022-08-27 13:20:28 +02:00
WerWolv
aabf718e60 patterns: Updated pattern language 2022-08-27 12:55:11 +02:00
WerWolv
03116c4ab8 patterns: Updated pattern language 2022-08-27 11:43:43 +02:00
iTrooz_
38162c0129 build: Use the bundled CA cert in AppImage (#694)
* Added option to bundle CA

* use bundled CA for AppImage

* Fix bundled CA not working on Linux

* revert change to add null terminated string

* set IMHEX_USE_BUNDLED_CA to ON on Windows
2022-08-26 00:21:17 +02:00
WerWolv
f62edea450 build: Fix various clang build issues 2022-08-26 00:18:08 +02:00
WerWolv
940f1e30c5 patterns: Updated pattern language 2022-08-25 21:14:20 +02:00
WerWolv
af32d68c3f git: Update macOS minimal requirements 2022-08-25 19:32:26 +02:00
WerWolv
eb874ac810 patterns: Updated pattern language 2022-08-25 19:31:06 +02:00
WerWolv
a79bf4c3ec patterns: Updated pattern language 2022-08-25 13:53:21 +02:00
WerWolv
90adacab9f fix: Build issues 2022-08-24 14:55:11 +02:00
WerWolv
e86ca29b8c sys: Improved searching behaviour 2022-08-24 00:31:34 +02:00
WerWolv
4f1f9a718c fix: Not all recent providers showing up correctly 2022-08-24 00:18:10 +02:00
WerWolv
cc09014e6e patterns: Updated pattern language 2022-08-24 00:17:31 +02:00
WerWolv
de98b40c93 fix: Build failing on macOS 2022-08-22 11:12:50 +02:00
WerWolv
a6eaa34f6d fix: Diff view crash when closing provider that's being diffed 2022-08-22 11:04:32 +02:00
WerWolv
dacb64ae66 fix: Window header always displaying (Read Only) after opening a provider 2022-08-22 11:00:31 +02:00
WerWolv
c0a5e2012f patterns: Updated pattern language 2022-08-21 23:34:02 +02:00
WerWolv
389e53a8a0 fix: Net request json parser throwing exceptions 2022-08-21 23:33:08 +02:00
WerWolv
928fbe235a ui: Automatically sort pattern data table by address 2022-08-21 23:32:18 +02:00
WerWolv
7d85a8b6fc fix: Providers not being closed correctly
Fixes #692
2022-08-20 14:04:12 +02:00
WerWolv
d004962e3a patterns: Updated pattern language 2022-08-20 13:58:58 +02:00
WerWolv
1462a4689d fix: ImHex crashing on exit
Fixes #698
2022-08-20 13:43:26 +02:00
WerWolv
93be4c8ed1 fix: Resource embedding not working correctly on Linux and macOS 2022-08-20 13:38:56 +02:00
Lukas Cone
536c6df438 fix: Race condition when evaluating patterns (#696) 2022-08-19 23:01:57 +02:00
WerWolv
f8a089a61f build: Added appdata metainfo file to AppImage 2022-08-19 12:05:47 +02:00
WerWolv
491ee6aa2f patterns: Updated pattern language 2022-08-18 23:51:50 +02:00
iTrooz_
6a88c7cbaa git: Make sure Linux CI doesn't build ImHex twice (#689)
* install deb package in a different folder than AppImage

* added comment for Ubuntu cmake build

* fixed typos

* separate cmake build for deb and appimage
2022-08-18 23:03:31 +02:00
Jonathan Wright
be82ee15b7 build: Lower curl version requirement (#684)
to allow building against RHEL 9's system curl
2022-08-18 01:13:38 +02:00
WerWolv
1ddd3ea2b9 fix: Custom pattern include paths not working correctly 2022-08-18 00:30:02 +02:00
WerWolv
a56a8c1d6c fix: Some clang issues 2022-08-18 00:24:29 +02:00
WerWolv
9c4e314bb6 git: Fixed release CI 2022-08-17 23:25:52 +02:00
WerWolv
ea26722a18 build: Bumped version to 1.21.2 2022-08-17 22:51:18 +02:00
WerWolv
5aee359700 git: Send workflow dispatch request to Plugin template repo on release 2022-08-17 22:32:55 +02:00
Vladyslav
5d11fc960e build: Updated minimum required cmake version to 3.20 (#677)
As per cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD.html,
`set(CMAKE_CXX_STANDARD 23)` requires minimum cmake version bump to 3.20
2022-08-17 18:39:49 +02:00
Berylskid
707fec0e2a lang: Updated Japanese translation (#679)
- Added as many translations as possible for the "Find" function.
- Added and corrected some other translations.
2022-08-17 18:37:44 +02:00
WerWolv
55b877d5e0 fix: Region validity check not working correctly with non-zero base address
Fixes #683
2022-08-17 16:28:44 +02:00
WerWolv
e779285be4 feat: Added basic ability to interrupt long running tasks 2022-08-17 16:15:36 +02:00
WerWolv
cf6ae52889 git: Automatically update winget package on release 2022-08-17 15:50:29 +02:00
Berylskid
caad705975 lang: Updated Japanese translation (#676)
Added two translations about import/export bookmarks
2022-08-16 11:54:26 +02:00
WerWolv
0c3fc6f858 ui: Moved welcome screen close button further to the left 2022-08-16 11:49:56 +02:00
WerWolv
0529155faa fix: Import/Export bookmarks menu items being disabled when they shouldn't be 2022-08-16 11:49:40 +02:00
WerWolv
aa01d58b33 ui: Increase window size when a bigger font is being used 2022-08-16 11:49:07 +02:00
WerWolv
0c0caf6942 fix: Restarting ImHex not working correctly 2022-08-16 11:48:37 +02:00
WerWolv
7e01ff451f patterns: Fixed return statements inside of loops acting like breaks
Fixes #675
2022-08-16 09:49:29 +02:00
WerWolv
e0e4b0a5a9 fix: Learn Pattern Language welcome screen button pointing to wrong URL 2022-08-16 09:29:50 +02:00
WerWolv
0e2c1f1355 fix: Syntax errors 2022-08-16 00:39:56 +02:00
WerWolv
0ed7341f71 patterns: Updated pattern language 2022-08-16 00:35:24 +02:00
WerWolv
29e970fd81 fix: Out of bounds strlen read 2022-08-16 00:29:53 +02:00
WerWolv
43ab72dcb8 fix: Undefined behaviour in helper functions 2022-08-16 00:12:28 +02:00
WerWolv
07dc77f13d git: Build Unit tests with debug symbols 2022-08-15 23:49:42 +02:00
WerWolv
9b2ee998de git: Enabled address, leak and UB sanitizers in unit tests CI 2022-08-15 23:33:04 +02:00
WerWolv
e1c5cd1e86 patterns: Updated pattern language 2022-08-15 22:35:24 +02:00
WerWolv
0d0301f4f6 patterns: Updated pattern language 2022-08-15 22:22:05 +02:00
WerWolv
29adeae6a3 fix: Undefined behaviour in frame wait time calculation 2022-08-15 22:21:53 +02:00
WerWolv
6b62a1963e fix: Some occurrences of undefined behaviour 2022-08-15 21:08:09 +02:00
103 changed files with 2695 additions and 1047 deletions

View File

@@ -99,14 +99,7 @@ jobs:
..
mingw32-make -j4 install
cpack
touch $PWD/install/PORTABLE
- name: ⬆️ Upload Portable ZIP
uses: actions/upload-artifact@v3
with:
name: Windows Portable
path: |
build/install/*
echo "ImHex checks for the existence of this file to determine if it is running in portable mode. You should not delete this file" > $PWD/install/PORTABLE
- name: ⬆️ Upload Windows Installer
uses: actions/upload-artifact@v3
@@ -115,23 +108,59 @@ jobs:
path: |
build/*.msi
- name: ⬆️ Upload Portable ZIP
uses: actions/upload-artifact@v3
with:
name: Windows Portable
path: |
build/install/*
- name: ⬇️ Download Mesa3D for NoGPU version
shell: bash
run: |
echo "NoGPU version Powered by Mesa 3D : https://fdossena.com/?p=mesa%2Findex.frag" > build/install/MESA.md
curl https://downloads.fdossena.com/geth.php?r=mesa64-latest -L -o mesa.7z
7z e mesa.7z
mv opengl32.dll build/install
- name: ⬆️ Upload NoGPU Portable ZIP
uses: actions/upload-artifact@v3
with:
name: Windows Portable NoGPU
path: |
build/install/*
# MacOS build
macos:
runs-on: macos-11
name: 🍎 macOS 11.0
steps:
strategy:
matrix:
include:
- suffix: "-NoGPU"
custom_glfw: true
- suffix: ""
custom_glfw: false
name: 🍎 macOS 11.0${{matrix.suffix}}
steps:
- name: 🧰 Checkout
uses: actions/checkout@v3
with:
submodules: recursive
- name: 📜 Set version variable
run: |
echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_ENV
- name: 📜 Restore ccache
uses: actions/cache@v3
with:
path: |
~/Library/Caches/ccache
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
key: ${{ runner.os }}-${{ matrix.suffix }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build
@@ -140,12 +169,43 @@ jobs:
with:
path: |
build/CMakeCache.txt
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
key: ${{ runner.os }}-${{ matrix.suffix }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
- name: ⬇️ Install dependencies
run: |
brew bundle --no-lock --file dist/Brewfile
- name: ⬇️ Install classic glfw
if: ${{! matrix.custom_glfw}}
run: |
brew install glfw
- name: 🧰 Checkout glfw
if: ${{matrix.custom_glfw}}
uses: actions/checkout@v3
with:
repository: glfw/glfw
path: glfw
- name: ⬇️ Patch and install custom glfw
if: ${{matrix.custom_glfw}}
run: |
cd glfw
git apply ../dist/macOS/0001-glfw-SW.patch
mkdir build
cd build
cmake \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
..
make -j 4 install
# MacOS cmake build
- name: 🛠️ Build
run: |
@@ -167,13 +227,14 @@ jobs:
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
-DIMHEX_PATTERNS_PULL_MASTER=ON \
-DCMAKE_OSX_DEPLOYMENT_TARGET="10.10" \
-DCPACK_PACKAGE_FILE_NAME="imhex-${{env.IMHEX_VERSION}}-macOS${{matrix.suffix}}" \
..
make -j4 package
- name: ⬆️ Upload DMG
uses: actions/upload-artifact@v3
with:
name: macOS DMG
name: macOS DMG${{matrix.suffix}}
path: build/*.dmg
# Ubuntu build
@@ -187,7 +248,7 @@ jobs:
with:
submodules: recursive
- name: 📜 Restore cache
- name: 📜 Restore ccache
uses: actions/cache@v3
with:
path: |
@@ -200,6 +261,7 @@ jobs:
with:
path: |
build/CMakeCache.txt
build-appimage/CMakeCache.txt
.flatpak-builder
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
@@ -225,13 +287,14 @@ jobs:
$HOME/.cargo/bin/rustup target add x86_64-unknown-linux-gnu
$HOME/.cargo/bin/rustup default nightly
# Ubuntu cmake build
- name: 🛠️ Build
run: |
mkdir -p build
cd build
CC=gcc-12 CXX=g++-12 cmake \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
-DCMAKE_INSTALL_PREFIX="/usr" \
-DCMAKE_INSTALL_PREFIX="/usr" \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
@@ -239,7 +302,7 @@ jobs:
-DRUST_PATH="$HOME/.cargo/bin/" \
-DIMHEX_PATTERNS_PULL_MASTER=ON \
..
make -j 4 install DESTDIR=AppDir
make -j 4 install DESTDIR=DebDir
- name: 📜 Set version variable
run: |
@@ -256,29 +319,34 @@ jobs:
- name: 📦 Bundle DEB
run: |
cp -r build/DEBIAN build/AppDir
dpkg-deb -Zgzip --build build/AppDir
mv build/AppDir.deb imhex-${{env.IMHEX_VERSION}}.deb
rm -rf build/AppDir/DEBIAN
cp -r build/DEBIAN build/DebDir
dpkg-deb -Zgzip --build build/DebDir
mv build/DebDir.deb imhex-${{env.IMHEX_VERSION}}-Ubuntu-22.04.deb
# AppImage cmake build
- name: 🛠️ Reconfigure build for AppImage
run: |
# Reconfigure CMake to include a flag needed for AppImage
# Other flags are kept from old configuration
cd build
cmake \
-DIMHEX_PLUGINS_IN_SHARE=ON \
..
rm -rf AppDir
mkdir -p build-appimage
cd build-appimage
CC=gcc-12 CXX=g++-12 cmake \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
-DCMAKE_INSTALL_PREFIX="/usr" \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
-DRUST_PATH="$HOME/.cargo/bin/" \
-DIMHEX_PATTERNS_PULL_MASTER=ON \
-DIMHEX_PLUGINS_IN_SHARE=ON \
-DIMHEX_USE_BUNDLED_CA=ON \
..
make -j 4 install DESTDIR=AppDir
- name: 📦 Bundle AppImage
run: |
cd build
cd build-appimage
export VERSION=${{env.IMHEX_VERSION}}
appimage-builder --recipe ../dist/AppImageBuilder.yml
mv ImHex-AppImage-x86_64.AppImage ../imhex-${{env.IMHEX_VERSION}}.AppImage
cd ..
#- name: ⬆️ Upload Flatpak
@@ -291,14 +359,20 @@ jobs:
- name: ⬆️ Upload DEB
uses: actions/upload-artifact@v3
with:
name: Linux DEB (Ubuntu 22.04)
name: Ubuntu 22.04 DEB
path: '*.deb'
- name: ⬆️ Upload AppImage
uses: actions/upload-artifact@v3
with:
name: Linux AppImage
path: '*.AppImage'
path: 'build-appimage/*.AppImage'
- name: ⬆️ Upload AppImage zsync
uses: actions/upload-artifact@v3
with:
name: Linux AppImage zsync
path: 'build-appimage/*.AppImage.zsync'
# ArchLinux build
archlinux-build:

View File

@@ -6,11 +6,12 @@ name: Release
on:
release:
types: [published]
workflow_dispatch:
jobs:
release:
release-common:
runs-on: ubuntu-latest
name: Release
name: Release Common
steps:
- name: 🧰 Checkout
@@ -57,8 +58,10 @@ jobs:
fi
done
- name: 🟩 Rename Windows Portable Zip
run: mv "Windows Portable.zip" imhex-${{env.IMHEX_VERSION}}-Windows-Portable.zip
- name: 🟩 Rename artifacts when needed
run: |
mv "Windows Portable.zip" imhex-${{env.IMHEX_VERSION}}-Windows-Portable.zip
mv "Windows Portable NoGPU.zip" imhex-${{env.IMHEX_VERSION}}-Windows-Portable-NoGPU.zip
- name: ⬆️ Upload everything to release
uses: softprops/action-gh-release@v1
@@ -110,3 +113,37 @@ jobs:
tag: ImHex-v${{env.IMHEX_VERSION}}
repo: ImHex-Patterns
token: ${{ secrets.RELEASE_TOKEN }}
- name: ✉️ Update C++ Plugin Template
uses: mvasigh/dispatch-action@main
env:
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
if: "${{ env.RELEASE_TOKEN != '' }}"
with:
token: ${{ secrets.RELEASE_TOKEN }}
repo: ImHex-Cpp-Plugin-Template
owner: WerWolv
event_type: update_submodule
release-windows:
name: Release Windows
needs: release-common
runs-on: windows-2022
steps:
- name: ⬇️ Download dependencies
shell: pwsh
run: |
iwr https://github.com/microsoft/winget-create/releases/download/v1.1.2.0/wingetcreate.exe -OutFile wingetcreate.exe
- name: ⬆️ Update winget manifest
shell: pwsh
env:
WINGET_GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
if: "${{ env.WINGET_GITHUB_TOKEN != '' }}"
run: |
$tagname = $env:GITHUB_REF.Replace("refs/tags/", "")
$version = $tagname.Replace("v", "")
$url = "https://github.com/WerWolv/ImHex/releases/download/${tagname}/imhex-${version}-win64.msi"
.\wingetcreate.exe update WerWolv.ImHex -u $url --version $version
if ($version -notmatch "-") {
.\wingetcreate.exe submit .\manifests\w\WerWolv\ImHex\${version}\ --token $env:WINGET_GITHUB_TOKEN
}

View File

@@ -47,18 +47,18 @@ jobs:
run: |
mkdir -p build
cd build
CC=gcc-12 CXX=g++-12 cmake \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
-DIMHEX_PATTERNS_PULL_MASTER=ON \
CC=gcc-12 CXX=g++-12 cmake \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_C_FLAGS="-fuse-ld=lld -fsanitize=address,leak,undefined -fno-sanitize-recover=all" \
-DCMAKE_CXX_FLAGS="-fuse-ld=lld -fsanitize=address,leak,undefined -fno-sanitize-recover=all" \
-DIMHEX_OFFLINE_BUILD=ON \
..
make -j4 unit_tests install
- name: 🧪 Perform Unit Tests
run: |
cd build
ctest --output-on-failure
ctest --output-on-failure

1
.idea/vcs.xml generated
View File

@@ -8,6 +8,7 @@
<mapping directory="$PROJECT_DIR$/lib/external/libromfs" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/external/nativefiledialog" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/external/pattern_language" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/external/pattern_language/external/cli11" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/external/pattern_language/external/fmt" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/external/xdgpp" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/external/yara/yara" vcs="Git" />

View File

@@ -1,10 +1,11 @@
cmake_minimum_required(VERSION 3.16)
cmake_minimum_required(VERSION 3.20)
# Options
option(IMHEX_USE_BUNDLED_CA "Use the CA bundle in romfs instead of the system one" OFF)
option(IMHEX_PLUGINS_IN_SHARE "Put the plugins in share/imhex/plugins instead of lib[..]/imhex/plugins" OFF)
option(IMHEX_STRIP_RELEASE "Strip the release builds" ON)
option(IMHEX_OFFLINE_BUILD "Enable offline build" OFF)
option(IMHEX_IGNORE_BAD_CLONE "Disabled the bad clone prevention checks" OFF)
option(IMHEX_IGNORE_BAD_CLONE "Disable the bad clone prevention checks" OFF)
option(IMHEX_PATTERNS_PULL_MASTER "Download latest files from master branch of the ImHex-Patterns repo" OFF)
option(IMHEX_IGNORE_BAD_COMPILER "Allow compiling with an unsupported compiler" OFF)
@@ -46,4 +47,4 @@ enable_testing()
add_subdirectory(tests EXCLUDE_FROM_ALL)
# Configure packaging
createPackage()
createPackage()

52
INSTALL.md Normal file
View File

@@ -0,0 +1,52 @@
# Installing ImHex
## Official Releases
The easiest way to install ImHex is to download the latest release from the [GitHub releases page](github.com/WerWolv/ImHex/releases/latest).
There's also a NoGPU version available for users who don't have a GPU or want to run ImHex in a VM without GPU passthrough.
## Nighly Builds
The GitHub Actions CI builds a new release package on every commit made to repository. These builds are available on the [GitHub Actions page](https://github.com/WerWolv/ImHex/actions?query=workflow%3A%22Build%22).
These builds are not guaranteed to be stable and may contain bugs, however they also contain new features that are not yet available in the official releases.
## Building from source
Build instructions for Windows, Linux and macOS can be found under `/dist/compiling`:
- Windows: [Link](dist/compiling/windows.md)
- macOS: [Link](dist/compiling/macos.md)
- Linux: [Link](dist/compiling/linux.md)
## Package managers
ImHex is also available on various package managers. The officially supported ones are listed here:
### Windows
- **Cocolatey**
- [imhex](https://community.chocolatey.org/packages/imhex) (Thanks to @Jarcho)
- `choco install imhex`
- **winget**
- [WerWolv.ImHex](https://github.com/microsoft/winget-pkgs/tree/master/manifests/w/WerWolv/ImHex)
- `winget install WerWolv.ImHex`
### Linux
- **Arch Linux AUR**
- [imhex-bin](https://aur.archlinux.org/packages/imhex-bin/) (Thanks to @iTrooz)
- `yay -S imhex-bin`
- [imhex](https://aur.archlinux.org/packages/imhex/) (Thanks to @KokaKiwi)
- `yay -S imhex`
- **Fedora**
- [imhex](https://src.fedoraproject.org/rpms/imhex/) (Thanks to @jonathanspw)
- `dnf install imhex`
- **Flatpak**
- [net.werwolv.Imhex](https://flathub.org/apps/details/net.werwolv.ImHex) (Thanks to @Mailaender)
- `flatpak install flathub net.werwolv.ImHex`
### Available on other package managers
Packages that aren't explicitly mentioned above are not officially supported but they will most likely still work.
Contact the maintainer of the package if you have any issues.
[![Packaging status](https://repology.org/badge/vertical-allrepos/imhex.svg)](https://repology.org/project/imhex/versions)

View File

@@ -1,4 +1,4 @@
<a href="https://imhex.werwolv.net"><h1 align="center" >:mag: ImHex</h1></a>
<a href="https://imhex.werwolv.net"><h1 align="center" ><img height="100px" src="resources/projects/logo_text.svg"></h1></a>
<p align="center">A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.</p>
@@ -104,7 +104,11 @@ If you like my work, please consider supporting me on GitHub Sponsors, Patreon o
## Pattern Language
The custom C-like Pattern Language developed and used by ImHex is easy to read, understand and learn. A guide with all features of the language can be found [on the docs page](http://imhex.werwolv.net/docs).
The Pattern Language is the completely custom programming language developed for ImHex.
It allows you to define structures and data types in a C-like syntax and then use them to parse and highlight a file's content.
- Source Code: [Link](https://github.com/WerWolv/PatternLanguage/)
- Documentation: [Link](https://imhex.werwolv.net/docs/)
## Database
@@ -116,40 +120,15 @@ For format patterns, libraries, magic and constant files, check out the [ImHex-P
To use ImHex, the following minimal system requirements need to be met:
- **OS**: Windows 7 or higher, macOS 10.10 (Yosemite) or higher, "Modern" Linux (Ubuntu 22.04+, Fedora Stable/Rawhide and Arch Linux are officially supported)
- **OS**: Windows 7 or higher, macOS 10.15 (Catalina) or higher, "Modern" Linux (Ubuntu 22.04, Fedora Stable/Rawhide, and Arch Linux have official packages, other distributions can use the AppImage)
- **CPU**: x86_64 (64 Bit)
- **GPU**: OpenGL 3.0 or higher (preferable a dedicated GPU and not Intel HD Graphics)
- **RAM**: 512MB, more may be required for more complicated analysis
- **Storage**: 100MB
## Plugin development
## Installing
To develop plugins for ImHex, use one of the following two templates projects to get started. You then have access to the entirety of libimhex as well as the ImHex API and the Content Registry to interact with ImHex or to add new content.
- [C++ Plugin Template](https://github.com/WerWolv/ImHex-Cpp-Plugin-Template)
- [Rust Plugin Template](https://github.com/WerWolv/ImHex-Rust-Plugin-Template)
## Nightly builds
Nightlies are available via GitHub Actions [here](https://github.com/WerWolv/ImHex/actions?query=workflow%3ABuild).
- Windows • __x86_64__
- [Installer](https://nightly.link/WerWolv/ImHex/workflows/build/master/Windows%20Installer.zip)
- [Portable](https://nightly.link/WerWolv/ImHex/workflows/build/master/Windows%20Portable.zip)
- MacOS • __x86_64__
- [DMG](https://nightly.link/WerWolv/ImHex/workflows/build/master/macOS%20DMG.zip)
- Linux • __x86_64__
- [Ubuntu DEB](https://nightly.link/WerWolv/ImHex/workflows/build/master/Linux%20DEB%20%28Ubuntu%2022.04%29.zip)
- [AppImage](https://nightly.link/WerWolv/ImHex/workflows/build/master/Linux%20AppImage.zip)
- [Arch Package](https://nightly.link/WerWolv/ImHex/workflows/build/master/ArchLinux%20.pkg.tar.zst.zip)
- [Fedora Rawhide RPM](https://nightly.link/WerWolv/ImHex/workflows/build/master/Fedora%20Rawhide%20RPM.zip)
- [Fedora Stable RPM](https://nightly.link/WerWolv/ImHex/workflows/build/master/Fedora%20Latest%20RPM.zip)
## Third party repositories
ImHex is available in various third party repositories.
[![Packaging status](https://repology.org/badge/vertical-allrepos/imhex.svg)](https://repology.org/project/imhex/versions)
Information on how to install ImHex can be found in the [Install](/INSTALL.md) guide
## Compiling
@@ -160,6 +139,15 @@ All releases are being built using latest available GCC.
Many dependencies are bundled into the repository using submodules so make sure to clone it using the `--recurse-submodules` option.
All dependencies that aren't bundled, can be installed using the dependency installer scripts found in the `/dist` folder.
For more information, check out the [Compiling](/dist/compiling) guide.
## Plugin development
To develop plugins for ImHex, use one of the following two templates projects to get started. You then have access to the entirety of libimhex as well as the ImHex API and the Content Registry to interact with ImHex or to add new content.
- [C++ Plugin Template](https://github.com/WerWolv/ImHex-Cpp-Plugin-Template)
- [Rust Plugin Template](https://github.com/WerWolv/ImHex-Rust-Plugin-Template)
## Credits
### Contributors

View File

@@ -1 +1 @@
1.21.1
1.23.2

View File

@@ -84,6 +84,8 @@ macro(detectOS)
set(CMAKE_INSTALL_BINDIR ".")
set(CMAKE_INSTALL_LIBDIR ".")
set(PLUGINS_INSTALL_LOCATION "plugins")
SET(IMHEX_USE_BUNDLED_CA ON)
elseif (APPLE)
add_compile_definitions(OS_MACOS)
set(CMAKE_INSTALL_BINDIR ".")
@@ -102,10 +104,15 @@ macro(detectOS)
# Warning : Do not work with portable versions such as appimage (because the path is hardcoded)
add_compile_definitions(SYSTEM_PLUGINS_LOCATION="${CMAKE_INSTALL_FULL_LIBDIR}/imhex") # "plugins" will be appended from the app
endif()
else ()
message(FATAL_ERROR "Unknown / unsupported system!")
endif()
if(IMHEX_USE_BUNDLED_CA)
add_compile_definitions(IMHEX_USE_BUNDLED_CA)
endif()
endmacro()
# Detect 32 vs. 64 bit system
@@ -133,7 +140,7 @@ macro(configurePackingResources)
if (CREATE_PACKAGE)
set(CPACK_GENERATOR "WIX")
set(CPACK_PACKAGE_NAME "ImHex")
set(CPACK_PACKAGE_NAME "imhex")
set(CPACK_PACKAGE_VENDOR "WerWolv")
set(CPACK_WIX_UPGRADE_GUID "05000E99-9659-42FD-A1CF-05C554B39285")
set(CPACK_WIX_PRODUCT_ICON "${PROJECT_SOURCE_DIR}/resources/dist/windows/icon.ico")
@@ -258,6 +265,14 @@ macro(createPackage)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/icon.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pixmaps RENAME imhex.png)
install(FILES "$<TARGET_FILE:libimhex>" DESTINATION "${CMAKE_INSTALL_LIBDIR}" PERMISSIONS ${LIBRARY_PERMISSIONS})
downloadImHexPatternsFiles("./share/imhex")
# install AppStream file
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dist/net.werwolv.imhex.metainfo.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo)
# install symlink for the old standard name
file(CREATE_LINK net.werwolv.imhex.metainfo.xml ${CMAKE_CURRENT_BINARY_DIR}/net.werwolv.imhex.appdata.xml SYMBOLIC)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/net.werwolv.imhex.appdata.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo)
endif()
if (CREATE_BUNDLE)
@@ -316,7 +331,9 @@ macro(setDefaultBuiltTypeIfUnset)
endmacro()
function(loadVersion version)
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" read_version)
set(VERSION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/VERSION")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${VERSION_FILE})
file(READ "${VERSION_FILE}" read_version)
set(${version} ${read_version} PARENT_SCOPE)
endfunction()
@@ -344,7 +361,7 @@ function(verifyCompiler)
message(FATAL_ERROR "ImHex requires GCC 12.0.0 or newer. Please use the latest GCC version.")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "14.0.0")
message(FATAL_ERROR "ImHex requires Clang 14.0.0 or newer. Please use the latest Clang version.")
elseif (NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
elseif (NOT (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
message(FATAL_ERROR "ImHex can only be compiled with GCC or Clang. ${CMAKE_CXX_COMPILER_ID} is not supported.")
endif()
endfunction()
@@ -375,6 +392,12 @@ function(downloadImHexPatternsFiles dest)
FetchContent_Populate(imhex_patterns)
else ()
# Maybe patterns are cloned to a subdirectory
set(imhex_patterns_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ImHex-Patterns")
endif ()
if (EXISTS ${imhex_patterns_SOURCE_DIR})
set(PATTERNS_FOLDERS_TO_INSTALL constants encodings includes patterns magic)
foreach (FOLDER ${PATTERNS_FOLDERS_TO_INSTALL})
install(DIRECTORY "${imhex_patterns_SOURCE_DIR}/${FOLDER}" DESTINATION ${dest})

View File

@@ -6,7 +6,7 @@ AppDir:
id: imhex
name: ImHex
icon: imhex
version: AppImage
version: "{{VERSION}}"
exec: usr/bin/imhex
exec_args: $@
apt:
@@ -136,4 +136,5 @@ AppDir:
- usr/share/doc/*/TODO.*
AppImage:
arch: x86_64
update-information: guess
update-information: gh-releases-zsync|WerWolv|ImHex|latest|imhex-*.AppImage.zsync
file_name: imhex-{{VERSION}}.AppImage

33
dist/Arch/PKGBUILD vendored
View File

@@ -1,40 +1,29 @@
# Maintainer: iTrooz_ <itrooz at protonmail dot com>
# Contributor: Morten Linderud <foxboron@archlinux.org>
pkgname=imhex-bin
pkgver=%version%
pkgrel=1
pkgdesc="A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM. "
arch=("x86_64")
url="https://github.com/WerWolv/ImHex"
repo=$url
license=('GPL 2.0')
groups=()
license=('GPL2')
depends=(glfw mbedtls python freetype2 libglvnd dbus xdg-desktop-portal curl fmt yara nlohmann-json)
makedepends=(git)
checkdepends=()
optdepends=()
provides=(imhex)
conflicts=(imhex)
replaces=()
backup=()
options=()
source=($repo"/releases/download/v$pkgver/imhex-$pkgver-ArchLinux.pkg.tar.zst")
noextract=()
source=("$url/releases/download/v$pkgver/imhex-$pkgver-ArchLinux.pkg.tar.zst")
md5sums=(SKIP)
validpgpkeys=()
package() {
tar -xf imhex-$pkgver-ArchLinux.pkg.tar.zst
install -Dm755 "$srcdir/usr/bin/imhex" "$pkgdir/usr/bin/imhex"
install -Dm644 "$srcdir/usr/lib/libimhex.so.$pkgver" "$pkgdir/usr/lib/libimhex.so.$pkgver"
install -DT $srcdir/usr/bin/imhex $pkgdir/usr/bin/imhex
install -DT $srcdir/usr/lib/libimhex.so.$pkgver $pkgdir/usr/lib/libimhex.so.$pkgver
for plugin in $srcdir/usr/lib/imhex/plugins/*.hexplug;
do
install -DT $plugin $pkgdir/usr/lib/imhex/plugins/`basename $plugin`
for plugin in "$srcdir/usr/lib/imhex/plugins/"*.hexplug; do
install -Dm644 "$plugin" "$pkgdir/usr/lib/imhex/plugins/${plugin##*/}"
done
mkdir -p $pkgdir/usr/share/imhex
cp -r $srcdir/usr/share/imhex/{constants,encodings,includes,magic,patterns} $pkgdir/usr/share/imhex
cp -r $srcdir/usr/share/{applications,licenses} $pkgdir/usr/share
install -d $pkgdir/usr/share
install -d "$pkgdir/usr/share/imhex"
cp -r "$srcdir/usr/share/imhex/"{constants,encodings,includes,magic,patterns} "$pkgdir/usr/share/imhex"
cp -r "$srcdir/usr/share/"{applications,licenses} "$pkgdir/usr/share"
}

1
dist/Brewfile vendored
View File

@@ -1,4 +1,3 @@
brew "glfw"
brew "mbedtls"
brew "nlohmann-json"
brew "cmake"

25
dist/macOS/0001-glfw-SW.patch vendored Normal file
View File

@@ -0,0 +1,25 @@
From 9c8665af4c2e2ce66555c15c05c72027bfdf0cb6 Mon Sep 17 00:00:00 2001
From: iTrooz <itrooz@protonmail.com>
Date: Mon, 29 Aug 2022 17:29:38 +0200
Subject: [PATCH] Use software rendering on MacOS
---
src/nsgl_context.m | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/nsgl_context.m b/src/nsgl_context.m
index fc1f7521..e5906575 100644
--- a/src/nsgl_context.m
+++ b/src/nsgl_context.m
@@ -198,7 +198,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
NSOpenGLPixelFormatAttribute attribs[40];
int index = 0;
- ADD_ATTRIB(NSOpenGLPFAAccelerated);
+ ADD_ATTRIB(NSOpenGLPFARendererID);ADD_ATTRIB(kCGLRendererGenericFloatID);
ADD_ATTRIB(NSOpenGLPFAClosestPolicy);
if (ctxconfig->nsgl.offline)
--
2.37.2

34
dist/net.werwolv.imhex.metainfo.xml vendored Normal file
View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>imhex</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-2.0</project_license>
<name>ImHex</name>
<developer_name>WerWolv</developer_name>
<update_contact>hey@werwolv.net</update_contact>
<summary>A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM</summary>
<description>
<p>ImHex is a feature-rich Hex Editor aimed towards Reverse Engineers working with foreign data formats, malware, executables and raw memory.
Besides all the features a common Hex Editor has, ImHex also features a custom scripting language used to declare and dissect data structures, support for running YARA rules, a node-based graphical data pre-processor and support for various data sources such as files, raw disks or GDB Servers.</p>
</description>
<launchable type="desktop-id">imhex.desktop</launchable>
<url type="homepage">https://imhex.werwolv.net</url>
<screenshots>
<screenshot type="default">
<image>https://user-images.githubusercontent.com/10835354/139717326-8044769d-527b-4d88-8adf-2d4ecafdca1f.png</image>
</screenshot>
<screenshot>
<image>https://user-images.githubusercontent.com/10835354/139717323-1f8c9d52-f7eb-4f43-9f11-097ac728ed6c.png</image>
</screenshot>
</screenshots>
<provides>
<id>imhex.desktop</id>
</provides>
<categories>
<category>Development</category>
</categories>
</component>

2
dist/rpm/imhex.spec vendored
View File

@@ -84,5 +84,7 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/imhex.desktop
%{_datadir}/applications/imhex.desktop
%{_prefix}/lib64/libimhex.so.%{_version}
%{_prefix}/lib64/imhex/plugins/*
%{_metainfodir}/net.werwolv.imhex.metainfo.xml
%{_metainfodir}/net.werwolv.imhex.appdata.xml
%changelog

View File

@@ -99,7 +99,7 @@
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
//#define ImDrawIdx unsigned int
#define ImDrawIdx unsigned int
//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
//struct ImDrawList;

View File

@@ -58,7 +58,7 @@ if(NOT USE_SYSTEM_CURL)
set(LIBCURL_LIBRARIES libcurl)
else()
find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBCURL REQUIRED IMPORTED_TARGET libcurl>=7.78.0)
pkg_check_modules(LIBCURL REQUIRED IMPORTED_TARGET libcurl>=7.76.1)
endif()
if (NOT USE_SYSTEM_LLVM)

View File

@@ -136,7 +136,7 @@ namespace hex {
}
std::unique_ptr<pl::PatternLanguage> createDefaultRuntime(prv::Provider *provider);
void configureRuntime(pl::PatternLanguage &runtime, prv::Provider *provider);
void addPragma(const std::string &name, const pl::api::PragmaHandler &handler);

View File

@@ -126,6 +126,7 @@ namespace hex {
EVENT_DEF(RequestSetPatternLanguageCode, std::string);
EVENT_DEF(RequestChangeWindowTitle, std::string);
EVENT_DEF(RequestCloseImHex, bool);
EVENT_DEF(RequestRestartImHex);
EVENT_DEF(RequestOpenFile, std::fs::path);
EVENT_DEF(RequestChangeTheme, u32);
EVENT_DEF(RequestOpenPopup, std::string);

View File

@@ -150,15 +150,6 @@ namespace hex {
}
namespace Tasks {
Task createTask(const std::string &unlocalizedName, u64 maxValue);
void doLater(const std::function<void()> &function);
std::vector<std::function<void()>> &getDeferredCalls();
}
namespace System {
namespace impl {
@@ -210,6 +201,7 @@ namespace hex {
std::map<std::string, std::string> &getInitArguments();
constexpr static float DefaultFontSize = 13.0;
const std::fs::path &getCustomFontPath();
float getFontSize();

View File

@@ -179,10 +179,10 @@ namespace hex {
return result;
}
static constexpr auto CTRL = Key(static_cast<Keys>(0x1000'0000));
static constexpr auto ALT = Key(static_cast<Keys>(0x2000'0000));
static constexpr auto SHIFT = Key(static_cast<Keys>(0x4000'0000));
static constexpr auto SUPER = Key(static_cast<Keys>(0x8000'0000));
constexpr static auto CTRL = Key(static_cast<Keys>(0x1000'0000));
constexpr static auto ALT = Key(static_cast<Keys>(0x2000'0000));
constexpr static auto SHIFT = Key(static_cast<Keys>(0x4000'0000));
constexpr static auto SUPER = Key(static_cast<Keys>(0x8000'0000));
class ShortcutManager {
public:

View File

@@ -2,40 +2,105 @@
#include <hex.hpp>
#include <list>
#include <cstdio>
#include <thread>
#include <functional>
#include <cstdint>
#include <mutex>
#include <string>
#include <chrono>
#include <memory>
#include <list>
namespace hex {
class TaskHolder;
class TaskManager;
class Task {
public:
Task() = default;
Task(const std::string &unlocalizedName, u64 maxValue);
Task(std::string unlocalizedName, u64 maxValue, std::function<void(Task &)> function);
Task(const Task&) = delete;
Task(Task &&other) noexcept;
~Task();
Task(Task &&other) noexcept;
void update(u64 value = 0);
void setMaxValue(u64 value);
void setMaxValue(u64 maxValue);
void update(u64 currValue);
void finish();
[[nodiscard]] bool isFinished() const;
[[nodiscard]] bool hadException() const;
[[nodiscard]] bool wasInterrupted() const;
void clearException();
[[nodiscard]] std::string getExceptionMessage() const;
[[nodiscard]] double getProgress() const;
[[nodiscard]] const std::string &getUnlocalizedName();
[[nodiscard]] u64 getValue() const;
[[nodiscard]] u64 getMaxValue() const;
[[nodiscard]] const std::string &getName() const;
void interrupt();
[[nodiscard]] bool isPending() const;
static size_t getRunningTaskCount();
static std::list<Task *> &getRunningTasks() { return Task::s_runningTasks; }
static std::mutex &getTaskMutex() { return Task::s_taskMutex; }
void setInterruptCallback(std::function<void()> callback);
private:
std::string m_name;
u64 m_maxValue = 0, m_currValue = 0;
void finish();
void interruption();
void exception(const char *message);
static std::list<Task *> s_runningTasks;
static std::mutex s_taskMutex;
private:
mutable std::mutex m_mutex;
std::string m_unlocalizedName;
u64 m_currValue, m_maxValue;
std::thread m_thread;
std::function<void()> m_interruptCallback;
bool m_shouldInterrupt = false;
bool m_interrupted = false;
bool m_finished = false;
bool m_hadException = false;
std::string m_exceptionMessage;
struct TaskInterruptor { virtual ~TaskInterruptor() = default; };
friend class TaskHolder;
friend class TaskManager;
};
class TaskHolder {
public:
TaskHolder() = default;
explicit TaskHolder(std::weak_ptr<Task> task) : m_task(std::move(task)) { }
[[nodiscard]] bool isRunning() const;
[[nodiscard]] bool hadException() const;
[[nodiscard]] bool wasInterrupted() const;
void interrupt();
private:
std::weak_ptr<Task> m_task;
};
class TaskManager {
public:
TaskManager() = delete;
constexpr static auto NoProgress = 0;
static TaskHolder createTask(std::string name, u64 maxValue, std::function<void(Task &)> function);
static void collectGarbage();
static size_t getRunningTaskCount();
static std::list<std::shared_ptr<Task>> &getRunningTasks();
static void doLater(const std::function<void()> &function);
static void runDeferredCalls();
private:
static std::mutex s_deferredCallsMutex;
static std::list<std::shared_ptr<Task>> s_tasks;
static std::list<std::function<void()>> s_deferredCalls;
};
}

View File

@@ -90,7 +90,7 @@ namespace hex::dp {
protected:
[[noreturn]] void throwNodeError(const std::string &message) {
throw NodeError(this, message);
throw NodeError { this, message };
}
std::vector<u8> getBufferOnInput(u32 index);

View File

@@ -31,7 +31,7 @@ namespace hex {
class Disassembler {
public:
static constexpr cs_arch toCapstoneArchitecture(Architecture architecture) {
constexpr static cs_arch toCapstoneArchitecture(Architecture architecture) {
return static_cast<cs_arch>(architecture);
}

View File

@@ -35,7 +35,7 @@ namespace hex {
Net();
~Net();
static constexpr u32 DefaultTimeout = 2'000;
constexpr static u32 DefaultTimeout = 2'000;
std::future<Response<std::string>> getString(const std::string &url, u32 timeout = DefaultTimeout);
std::future<Response<nlohmann::json>> getJson(const std::string &url, u32 timeout = DefaultTimeout);

View File

@@ -31,6 +31,16 @@ namespace hex {
long double operator""_scaled(unsigned long long value);
ImVec2 scaled(const ImVec2 &vector);
template<typename T>
std::vector<T> operator|(const std::vector<T> &lhs, const std::vector<T> &rhs) {
std::vector<T> result;
std::copy(lhs.begin(), lhs.end(), std::back_inserter(result));
std::copy(rhs.begin(), rhs.end(), std::back_inserter(result));
return result;
}
std::string to_string(u128 value);
std::string to_string(i128 value);
@@ -68,7 +78,7 @@ namespace hex {
}
constexpr inline i128 signExtend(size_t numBits, i128 value) {
i128 mask = 1U << (numBits - 1);
i128 mask = 1ULL << (numBits - 1);
return (value ^ mask) - mask;
}
@@ -84,6 +94,13 @@ namespace hex {
return result;
}
constexpr inline size_t strnlen(const char *s, size_t n) {
size_t i = 0;
while (i < n && s[i] != '\x00') i++;
return i;
}
template<class... Ts>
struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts>

View File

@@ -4,14 +4,17 @@
#include <vector>
#include <hex/providers/provider.hpp>
#include <hex/helpers/literals.hpp>
namespace hex::prv {
using namespace hex::literals;
class BufferedReader {
public:
explicit BufferedReader(Provider *provider, size_t bufferSize = 0xFF'FFFF)
explicit BufferedReader(Provider *provider, size_t bufferSize = 16_MiB)
: m_provider(provider), m_bufferAddress(provider->getBaseAddress()), m_maxBufferSize(bufferSize),
m_startAddress(0x00), m_endAddress(provider->getActualSize()),
m_startAddress(0x00), m_endAddress(provider->getActualSize() - 1),
m_buffer(bufferSize) {
}
@@ -21,6 +24,9 @@ namespace hex::prv {
}
void setEndAddress(u64 address) {
if (address >= this->m_provider->getActualSize())
address = this->m_provider->getActualSize() - 1;
this->m_endAddress = address;
}
@@ -215,7 +221,7 @@ namespace hex::prv {
}
value_type operator[](i64 offset) const {
auto result = this->m_reader->readReverse(this->m_address + offset, 1);
auto result = this->m_reader->readReverse(this->m_address - offset, 1);
if (result.empty())
return 0x00;
@@ -247,7 +253,7 @@ namespace hex::prv {
}
ReverseIterator rend() {
return { this, std::numeric_limits<u64>::max() };
return { this, 0 };
}
private:
@@ -256,6 +262,8 @@ namespace hex::prv {
const auto remainingBytes = (this->m_endAddress - address) + 1;
if (remainingBytes < this->m_maxBufferSize)
this->m_buffer.resize(remainingBytes);
else
this->m_buffer.resize(this->m_maxBufferSize);
this->m_provider->read(address, this->m_buffer.data(), this->m_buffer.size());
this->m_bufferAddress = address;

View File

@@ -14,10 +14,6 @@
#include <nlohmann/json.hpp>
namespace pl {
class PatternLanguage;
}
namespace hex::prv {
class Provider {
@@ -70,8 +66,8 @@ namespace hex::prv {
[[nodiscard]] virtual std::string getName() const = 0;
[[nodiscard]] virtual std::vector<std::pair<std::string, std::string>> getDataInformation() const = 0;
[[nodiscard]] virtual bool open();
virtual void close();
[[nodiscard]] virtual bool open() = 0;
virtual void close() = 0;
void addPatch(u64 offset, const void *buffer, size_t size, bool createUndo = false);
void createUndoPoint();

View File

@@ -241,29 +241,30 @@ namespace hex {
return functionName;
}
std::unique_ptr<pl::PatternLanguage> createDefaultRuntime(prv::Provider *provider) {
auto runtime = std::make_unique<pl::PatternLanguage>();
void configureRuntime(pl::PatternLanguage &runtime, prv::Provider *provider) {
runtime.reset();
if (provider != nullptr) {
runtime->setDataSource([provider](u64 offset, u8 *buffer, size_t size) {
runtime.setDataSource([provider](u64 offset, u8 *buffer, size_t size) {
provider->read(offset, buffer, size);
}, provider->getBaseAddress(), provider->getActualSize());
}
runtime->setIncludePaths(fs::getDefaultPaths(fs::ImHexPath::PatternsInclude));
runtime.setIncludePaths(fs::getDefaultPaths(fs::ImHexPath::PatternsInclude) | fs::getDefaultPaths(fs::ImHexPath::Patterns));
for (const auto &func : getFunctions()) {
if (func.dangerous)
runtime->addDangerousFunction(func.ns, func.name, func.parameterCount, func.callback);
runtime.addDangerousFunction(func.ns, func.name, func.parameterCount, func.callback);
else
runtime->addFunction(func.ns, func.name, func.parameterCount, func.callback);
runtime.addFunction(func.ns, func.name, func.parameterCount, func.callback);
}
for (const auto &[name, callback] : getPragmas()) {
runtime->addPragma(name, callback);
runtime.addPragma(name, callback);
}
return runtime;
runtime.addDefine("__IMHEX__");
runtime.addDefine("__IMHEX_VERSION__", IMHEX_VERSION);
}
void addPragma(const std::string &name, const pl::api::PragmaHandler &handler) {

View File

@@ -20,11 +20,8 @@ namespace hex {
}
void restartImHex() {
EventManager::post<RequestRestartImHex>();
EventManager::post<RequestCloseImHex>(false);
std::atexit([] {
auto &programArgs = ImHexApi::System::getProgramArguments();
execve(programArgs.argv[0], programArgs.argv, programArgs.envp);
});
}
}
@@ -211,7 +208,7 @@ namespace hex {
namespace ImHexApi::Provider {
static u32 s_currentProvider = std::numeric_limits<u32>::max();
static i64 s_currentProvider = -1;
static std::vector<prv::Provider *> s_providers;
namespace impl {
@@ -239,7 +236,7 @@ namespace hex {
}
void setCurrentProvider(u32 index) {
if (Task::getRunningTaskCount() > 0)
if (TaskManager::getRunningTaskCount() > 0)
return;
if (index < s_providers.size() && s_currentProvider != index) {
@@ -250,7 +247,7 @@ namespace hex {
}
bool isValid() {
return !s_providers.empty() && s_currentProvider < s_providers.size();
return !s_providers.empty() && s_currentProvider >= 0 && s_currentProvider < i64(s_providers.size());
}
void markDirty() {
@@ -269,7 +266,7 @@ namespace hex {
}
void add(prv::Provider *provider, bool skipLoadInterface) {
if (Task::getRunningTaskCount() > 0)
if (TaskManager::getRunningTaskCount() > 0)
return;
if (skipLoadInterface)
@@ -285,7 +282,7 @@ namespace hex {
if (provider == nullptr)
return;
if (Task::getRunningTaskCount() > 0)
if (TaskManager::getRunningTaskCount() > 0)
return;
if (!noQuestions) {
@@ -310,6 +307,9 @@ namespace hex {
else if (it - s_providers.begin() == s_currentProvider)
setCurrentProvider(0);
provider->close();
EventManager::post<EventProviderClosed>(provider);
delete provider;
}
@@ -322,29 +322,6 @@ namespace hex {
}
namespace ImHexApi::Tasks {
Task createTask(const std::string &unlocalizedName, u64 maxValue) {
return { unlocalizedName, maxValue };
}
void doLater(const std::function<void()> &function) {
static std::mutex tasksMutex;
std::scoped_lock lock(tasksMutex);
getDeferredCalls().push_back(function);
}
std::vector<std::function<void()>> &getDeferredCalls() {
static std::vector<std::function<void()>> deferredCalls;
return deferredCalls;
}
}
namespace ImHexApi::System {
namespace impl {
@@ -393,7 +370,7 @@ namespace hex {
s_customFontPath = path;
}
static float s_fontSize = 13.0;
static float s_fontSize = DefaultFontSize;
void setFontSize(float size) {
s_fontSize = size;
}

View File

@@ -101,6 +101,8 @@ namespace hex {
tar.write(MetadataPath, metadataContent);
}
ImHexApi::Provider::resetDirty();
return result;
}

View File

@@ -1,71 +1,200 @@
#include <hex/api/task.hpp>
#include <hex/api/localization.hpp>
#include <hex/helpers/logger.hpp>
#include <algorithm>
namespace hex {
std::list<Task *> Task::s_runningTasks;
std::mutex Task::s_taskMutex;
std::mutex TaskManager::s_deferredCallsMutex;
Task::Task(const std::string &unlocalizedName, u64 maxValue) : m_name(LangEntry(unlocalizedName)), m_maxValue(maxValue), m_currValue(0) {
std::scoped_lock lock(Task::s_taskMutex);
std::list<std::shared_ptr<Task>> TaskManager::s_tasks;
std::list<std::function<void()>> TaskManager::s_deferredCalls;
Task::s_runningTasks.push_back(this);
}
Task::Task(std::string unlocalizedName, u64 maxValue, std::function<void(Task &)> function)
: m_unlocalizedName(std::move(unlocalizedName)), m_currValue(0), m_maxValue(maxValue) {
this->m_thread = std::thread([this, func = std::move(function)] {
try {
func(*this);
} catch (const TaskInterruptor &) {
this->interruption();
} catch (const std::exception &e) {
log::error("Exception in task {}: {}", this->m_unlocalizedName, e.what());
this->exception(e.what());
} catch (...) {
log::error("Exception in task {}", this->m_unlocalizedName);
this->exception("Unknown Exception");
}
Task::~Task() {
this->finish();
this->finish();
});
}
Task::Task(hex::Task &&other) noexcept {
std::scoped_lock lock(Task::s_taskMutex);
std::scoped_lock thisLock(this->m_mutex);
std::scoped_lock otherLock(other.m_mutex);
this->m_thread = std::move(other.m_thread);
this->m_unlocalizedName = std::move(other.m_unlocalizedName);
this->m_name = other.m_name;
this->m_maxValue = other.m_maxValue;
this->m_currValue = other.m_currValue;
auto it = std::find(Task::s_runningTasks.begin(), Task::s_runningTasks.end(), &other);
if (it != Task::s_runningTasks.end()) {
*it = this;
}
this->m_finished = other.m_finished;
this->m_hadException = other.m_hadException;
this->m_interrupted = other.m_interrupted;
this->m_shouldInterrupt = other.m_shouldInterrupt;
}
Task::~Task() {
if (!this->isFinished())
this->interrupt();
this->m_thread.join();
}
void Task::update(u64 value) {
std::scoped_lock lock(this->m_mutex);
this->m_currValue = value;
if (this->m_shouldInterrupt)
throw TaskInterruptor();
}
void Task::setMaxValue(u64 value) {
std::scoped_lock lock(this->m_mutex);
this->m_maxValue = value;
}
void Task::interrupt() {
std::scoped_lock lock(this->m_mutex);
this->m_shouldInterrupt = true;
if (this->m_interruptCallback)
this->m_interruptCallback();
}
void Task::setInterruptCallback(std::function<void()> callback) {
this->m_interruptCallback = std::move(callback);
}
bool Task::isFinished() const {
std::scoped_lock lock(this->m_mutex);
return this->m_finished;
}
bool Task::hadException() const {
std::scoped_lock lock(this->m_mutex);
return this->m_hadException;
}
bool Task::wasInterrupted() const {
std::scoped_lock lock(this->m_mutex);
return this->m_interrupted;
}
void Task::clearException() {
std::scoped_lock lock(this->m_mutex);
this->m_hadException = false;
}
std::string Task::getExceptionMessage() const {
std::scoped_lock lock(this->m_mutex);
return this->m_exceptionMessage;
}
const std::string &Task::getUnlocalizedName() {
return this->m_unlocalizedName;
}
u64 Task::getValue() const {
return this->m_currValue;
}
u64 Task::getMaxValue() const {
return this->m_maxValue;
}
void Task::finish() {
std::scoped_lock lock(Task::s_taskMutex);
std::scoped_lock lock(this->m_mutex);
Task::s_runningTasks.remove(this);
this->m_finished = true;
}
void Task::setMaxValue(u64 maxValue) {
this->m_maxValue = maxValue;
void Task::interruption() {
std::scoped_lock lock(this->m_mutex);
this->m_interrupted = true;
}
void Task::update(u64 currValue) {
if (this->m_currValue < this->m_maxValue)
this->m_currValue = currValue;
void Task::exception(const char *message) {
std::scoped_lock lock(this->m_mutex);
this->m_exceptionMessage = message;
this->m_hadException = true;
}
double Task::getProgress() const {
if (this->m_maxValue == 0)
return 100;
return static_cast<double>(this->m_currValue) / static_cast<double>(this->m_maxValue);
bool TaskHolder::isRunning() const {
return !m_task.expired() && !m_task.lock()->isFinished();
}
bool Task::isPending() const {
return this->m_maxValue == 0;
bool TaskHolder::hadException() const {
return m_task.expired() || m_task.lock()->hadException();
}
const std::string &Task::getName() const {
return this->m_name;
bool TaskHolder::wasInterrupted() const {
return m_task.expired() || m_task.lock()->wasInterrupted();
}
size_t Task::getRunningTaskCount() {
std::scoped_lock lock(Task::s_taskMutex);
void TaskHolder::interrupt() {
if (!this->m_task.expired())
this->m_task.lock()->interrupt();
}
return Task::s_runningTasks.size();
TaskHolder TaskManager::createTask(std::string name, u64 maxValue, std::function<void(Task &)> function) {
s_tasks.emplace_back(std::make_shared<Task>(std::move(name), maxValue, std::move(function)));
return TaskHolder(s_tasks.back());
}
void TaskManager::collectGarbage() {
std::erase_if(s_tasks, [](const auto &task) { return task->isFinished() && !task->hadException(); });
}
std::list<std::shared_ptr<Task>> &TaskManager::getRunningTasks() {
return s_tasks;
}
size_t TaskManager::getRunningTaskCount() {
return s_tasks.size();
}
void TaskManager::doLater(const std::function<void()> &function) {
std::scoped_lock lock(s_deferredCallsMutex);
s_deferredCalls.push_back(function);
}
void TaskManager::runDeferredCalls() {
std::scoped_lock lock(s_deferredCallsMutex);
for (const auto &call : s_deferredCalls)
call();
s_deferredCalls.clear();
}
}

View File

@@ -1,7 +1,8 @@
#include <hex/helpers/file.hpp>
#include <hex/helpers/utils.hpp>
#include <unistd.h>
#include <cstring>
namespace hex::fs {
@@ -90,7 +91,7 @@ namespace hex::fs {
return "";
auto cString = reinterpret_cast<const char *>(bytes.data());
return { cString, std::min(bytes.size(), std::strlen(cString)) };
return { cString, hex::strnlen(cString, bytes.size()) };
}
std::u8string File::readU8String(size_t numBytes) {
@@ -104,7 +105,7 @@ namespace hex::fs {
return u8"";
auto cString = reinterpret_cast<const char8_t *>(bytes.data());
return { cString, std::min(bytes.size(), std::strlen(reinterpret_cast<const char*>(bytes.data()))) };
return { cString, hex::strnlen(reinterpret_cast<const char*>(bytes.data()), bytes.size()) };
}
void File::write(const u8 *buffer, size_t size) {

View File

@@ -109,7 +109,7 @@ namespace hex {
curl_easy_setopt(this->m_ctx, CURLOPT_NOSIGNAL, 1L);
curl_easy_setopt(this->m_ctx, CURLOPT_NOPROGRESS, 0L);
#if defined(OS_WINDOWS)
#if defined(IMHEX_USE_BUNDLED_CA)
curl_easy_setopt(this->m_ctx, CURLOPT_CAINFO, nullptr);
curl_easy_setopt(this->m_ctx, CURLOPT_CAPATH, nullptr);
curl_easy_setopt(this->m_ctx, CURLOPT_SSLCERTTYPE, "PEM");
@@ -124,7 +124,7 @@ namespace hex {
if (result != CURLE_OK)
log::error("Net request failed with error {0}: '{1}'", u32(result), curl_easy_strerror(result));
i32 responseCode = 0;
long responseCode = 0;
curl_easy_getinfo(this->m_ctx, CURLINFO_RESPONSE_CODE, &responseCode);
curl_slist_free_all(this->m_headers);
@@ -135,7 +135,7 @@ namespace hex {
if (result != CURLE_OK)
return std::nullopt;
else
return responseCode;
return i32(responseCode);
}
std::future<Response<std::string>> Net::getString(const std::string &url, u32 timeout) {
@@ -167,8 +167,10 @@ namespace hex {
setCommonSettings(response, url, timeout);
auto responseCode = execute();
return Response<nlohmann::json> { responseCode.value_or(0), nlohmann::json::parse(response) };
if (!responseCode.has_value())
return Response<nlohmann::json> { 0, { } };
else
return Response<nlohmann::json> { responseCode.value_or(0), nlohmann::json::parse(response, nullptr, false, true) };
});
}
@@ -188,15 +190,26 @@ namespace hex {
curl_mimepart *part = curl_mime_addpart(mime);
auto fileName = filePath.filename().string();
curl_mime_data_cb(
part, file.getSize(), [](char *buffer, size_t size, size_t nitems, void *arg) -> size_t {
curl_mime_data_cb(part, file.getSize(),
[](char *buffer, size_t size, size_t nitems, void *arg) -> size_t {
auto file = static_cast<FILE*>(arg);
return fread(buffer, size, nitems, file); }, [](void *arg, curl_off_t offset, int origin) -> int {
return fread(buffer, size, nitems, file);
},
[](void *arg, curl_off_t offset, int origin) -> int {
auto file = static_cast<FILE*>(arg);
fseek(file, offset, origin);
return CURL_SEEKFUNC_OK; }, [](void *arg) {
if (fseek(file, offset, origin) != 0)
return CURL_SEEKFUNC_CANTSEEK;
else
return CURL_SEEKFUNC_OK;
},
[](void *arg) {
auto file = static_cast<FILE*>(arg);
fclose(file); }, file.getHandle());
fclose(file);
},
file.getHandle());
curl_mime_filename(part, fileName.c_str());
curl_mime_name(part, "file");

View File

@@ -233,7 +233,7 @@ namespace hex {
}
std::string toEngineeringString(double value) {
constexpr std::array Suffixes = { "a", "f", "p", "n", "u", "m", "", "k", "M", "G", "T", "P", "E" };
constexpr static std::array Suffixes = { "a", "f", "p", "n", "u", "m", "", "k", "M", "G", "T", "P", "E" };
int8_t suffixIndex = 6;
@@ -339,7 +339,7 @@ namespace hex {
auto c = [&] { return string[offset]; };
if (c() == '\\') {
if ((offset + 2) >= string.length()) return {};
if ((offset + 2) > string.length()) return {};
offset++;

View File

@@ -19,7 +19,6 @@ namespace hex::prv {
Provider::~Provider() {
for (auto &overlay : this->m_overlays)
this->deleteOverlay(overlay);
this->close();
}
void Provider::read(u64 offset, void *buffer, size_t size, bool overlays) {
@@ -171,14 +170,6 @@ namespace hex::prv {
return page;
}
bool Provider::open() {
EventManager::post<EventProviderOpened>(this);
return true;
}
void Provider::close() {
EventManager::post<EventProviderClosed>(this);
}
void Provider::addPatch(u64 offset, const void *buffer, size_t size, bool createUndo) {
if (this->m_patchTreeOffset > 0) {
auto iter = this->m_patches.end();
@@ -266,7 +257,7 @@ namespace hex::prv {
}
std::pair<Region, bool> Provider::getRegionValidity(u64 address) const {
if (address > this->getActualSize())
if ((address - this->getBaseAddress()) > this->getActualSize())
return { Region::Invalid(), false };
bool insideValidRegion = false;

View File

@@ -13,6 +13,8 @@
#include <imgui_impl_opengl3_loader.h>
#include <hex/api/imhex_api.hpp>
namespace ImGui {
int UpdateStringSizeCallback(ImGuiInputTextCallbackData *data) {
@@ -536,7 +538,7 @@ namespace ImGui {
const ImGuiStyle &style = g.Style;
ImVec2 pos = window->DC.CursorPos + ImVec2(0, yOffset);
ImVec2 size = CalcItemSize(ImVec2(100, 5), 100, g.FontSize + style.FramePadding.y * 2.0f);
ImVec2 size = CalcItemSize(ImVec2(100, 5) * hex::ImHexApi::System::getGlobalScale(), 100, g.FontSize + style.FramePadding.y * 2.0f);
ImRect bb(pos, pos + size);
ItemSize(size, 0);
if (!ItemAdd(bb, 0))

View File

@@ -49,7 +49,7 @@ namespace hex {
}
ImVec2 View::getMinSize() const {
return scaled(ImVec2(480, 720));
return scaled(ImVec2(10, 10));
}
ImVec2 View::getMaxSize() const {

View File

@@ -4,6 +4,7 @@
#include <imgui_freetype.h>
#include <hex/api/content_registry.hpp>
#include <hex/api/project_file_manager.hpp>
#include <hex/ui/view.hpp>
#include <hex/helpers/net.hpp>
#include <hex/helpers/fs.hpp>
@@ -173,7 +174,6 @@ namespace hex::init {
ContentRegistry::Provider::getEntries().clear();
ImHexApi::System::getInitArguments().clear();
ImHexApi::Tasks::getDeferredCalls().clear();
ImHexApi::HexEditor::impl::getBackgroundHighlights().clear();
ImHexApi::HexEditor::impl::getForegroundHighlights().clear();
ImHexApi::HexEditor::impl::getBackgroundHighlightingFunctions().clear();
@@ -215,12 +215,13 @@ namespace hex::init {
ShortcutManager::clearShortcuts();
hex::Task::getRunningTasks().clear();
TaskManager::getRunningTasks().clear();
ContentRegistry::DataProcessorNode::getEntries().clear();
ContentRegistry::DataFormatter::getEntries().clear();
ContentRegistry::FileHandler::getEntries().clear();
ContentRegistry::Hashes::impl::getHashes().clear();
{
auto &visualizers = ContentRegistry::HexEditor::impl::getVisualizers();
@@ -229,6 +230,9 @@ namespace hex::init {
visualizers.clear();
}
ProjectFile::getHandlers().clear();
ProjectFile::getProviderHandlers().clear();
return true;
}

View File

@@ -18,42 +18,49 @@ int main(int argc, char **argv, char **envp) {
ImHexApi::System::impl::setBorderlessWindowMode(true);
#endif
// Initialization
{
Window::initNative();
bool shouldRestart = false;
hex::log::info("Welcome to ImHex!");
EventManager::subscribe<RequestRestartImHex>([&]{ shouldRestart = true; });
init::WindowSplash splashWindow;
do {
shouldRestart = false;
for (const auto &[name, task] : init::getInitTasks())
splashWindow.addStartupTask(name, task);
// Initialization
{
Window::initNative();
if (!splashWindow.loop())
ImHexApi::System::getInitArguments().insert({ "tasks-failed", {} });
}
hex::log::info("Welcome to ImHex!");
// Clean up
ON_SCOPE_EXIT {
for (const auto &[name, task] : init::getExitTasks())
task();
};
init::WindowSplash splashWindow;
// Main window
{
Window window;
for (const auto &[name, task] : init::getInitTasks())
splashWindow.addStartupTask(name, task);
if (argc == 1)
; // No arguments provided
else if (argc == 2)
EventManager::post<RequestOpenFile>(argv[1]);
else {
hex::log::fatal("Usage: {} [<file_name>]", argv[0]);
return EXIT_FAILURE;
if (!splashWindow.loop())
ImHexApi::System::getInitArguments().insert({ "tasks-failed", {} });
}
window.loop();
}
// Clean up
ON_SCOPE_EXIT {
for (const auto &[name, task] : init::getExitTasks())
task();
};
// Main window
{
Window window;
if (argc == 1)
; // No arguments provided
else if (argc >= 2) {
for (auto i = 1; i < argc; i++)
EventManager::post<RequestOpenFile>(argv[i]);
}
window.loop();
}
} while (shouldRestart);
return EXIT_SUCCESS;
}

View File

@@ -32,7 +32,39 @@ namespace hex {
static float g_titleBarHeight;
static ImGuiMouseCursor g_mouseCursorIcon;
static LRESULT windowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
static LRESULT commonWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_COPYDATA:
{
auto message = reinterpret_cast<COPYDATASTRUCT *>(lParam);
if (message == nullptr) break;
auto data = reinterpret_cast<const char8_t *>(message->lpData);
if (data == nullptr) break;
std::fs::path path = data;
log::info("Opening file in existing instance: {}", path.string());
EventManager::post<RequestOpenFile>(path);
break;
}
case WM_SETTINGCHANGE:
{
if (lParam == 0) break;
if (LPCTSTR(lParam) == std::string_view("ImmersiveColorSet")) {
EventManager::post<EventOSThemeChanged>();
}
break;
}
default:
break;
}
return CallWindowProc((WNDPROC)g_oldWndProc, hwnd, uMsg, wParam, lParam);
}
static LRESULT borderlessWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_NCACTIVATE:
case WM_NCPAINT:
@@ -106,11 +138,11 @@ namespace hex {
return HTNOWHERE;
}
constexpr auto RegionClient = 0b0000;
constexpr auto RegionLeft = 0b0001;
constexpr auto RegionRight = 0b0010;
constexpr auto RegionTop = 0b0100;
constexpr auto RegionBottom = 0b1000;
constexpr static auto RegionClient = 0b0000;
constexpr static auto RegionLeft = 0b0001;
constexpr static auto RegionRight = 0b0010;
constexpr static auto RegionTop = 0b0100;
constexpr static auto RegionBottom = 0b1000;
const auto result =
RegionLeft * (cursor.x < (window.left + border.x)) |
@@ -146,35 +178,11 @@ namespace hex {
}
break;
}
case WM_SETTINGCHANGE:
{
if (lParam == 0) break;
if (LPCTSTR(lParam) == std::string_view("ImmersiveColorSet")) {
EventManager::post<EventOSThemeChanged>();
}
break;
}
case WM_COPYDATA:
{
auto message = reinterpret_cast<COPYDATASTRUCT *>(lParam);
if (message == nullptr) break;
auto data = reinterpret_cast<const char8_t *>(message->lpData);
if (data == nullptr) break;
std::fs::path path = data;
log::info("Opening file in existing instance: {}", path.string());
EventManager::post<RequestOpenFile>(path);
break;
}
default:
break;
}
return CallWindowProc((WNDPROC)g_oldWndProc, hwnd, uMsg, wParam, lParam);
return commonWindowProc(hwnd, uMsg, wParam, lParam);
}
@@ -255,7 +263,7 @@ namespace hex {
if (borderlessWindowMode) {
g_oldWndProc = ::SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)windowProc);
g_oldWndProc = ::SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)borderlessWindowProc);
MARGINS borderless = { 1, 1, 1, 1 };
::DwmExtendFrameIntoClientArea(hwnd, &borderless);
@@ -265,6 +273,8 @@ namespace hex {
::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE);
::SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_OVERLAPPEDWINDOW);
} else {
g_oldWndProc = ::SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)commonWindowProc);
}
// Catch heap corruption

View File

@@ -86,11 +86,11 @@ namespace hex {
{
for (const auto &[argument, value] : ImHexApi::System::getInitArguments()) {
if (argument == "no-plugins") {
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("No Plugins"); });
TaskManager::doLater([] { ImGui::OpenPopup("No Plugins"); });
} else if (argument == "no-builtin-plugin") {
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("No Builtin Plugin"); });
TaskManager::doLater([] { ImGui::OpenPopup("No Builtin Plugin"); });
} else if (argument == "multiple-builtin-plugins") {
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("Multiple Builtin Plugins"); });
TaskManager::doLater([] { ImGui::OpenPopup("Multiple Builtin Plugins"); });
}
}
}
@@ -114,23 +114,24 @@ namespace hex {
if (ImHexApi::Provider::isValid()) {
auto provider = ImHexApi::Provider::get();
if (!windowTitle.empty())
if (!windowTitle.empty() && provider != nullptr) {
title += " - " + windowTitle;
if (provider->isDirty())
title += " (*)";
if (provider->isDirty())
title += " (*)";
if (!provider->isWritable())
title += " (Read Only)";
if (!provider->isWritable())
title += " (Read Only)";
}
}
this->m_windowTitle = title;
glfwSetWindowTitle(this->m_window, title.c_str());
});
constexpr auto CrashBackupFileName = "crash_backup.hexproj";
constexpr static auto CrashBackupFileName = "crash_backup.hexproj";
EventManager::subscribe<EventAbnormalTermination>(this, [this, CrashBackupFileName](int) {
EventManager::subscribe<EventAbnormalTermination>(this, [this](int) {
ImGui::SaveIniSettingsToDisk(this->m_imguiSettingsPath.string().c_str());
if (!ImHexApi::Provider::isDirty())
@@ -179,7 +180,7 @@ namespace hex {
} else {
glfwPollEvents();
bool frameRateUnlocked = ImGui::IsPopupOpen(ImGuiID(0), ImGuiPopupFlags_AnyPopupId) || Task::getRunningTaskCount() > 0 || this->m_mouseButtonDown || this->m_hadEvent || !this->m_pressedKeys.empty();
bool frameRateUnlocked = ImGui::IsPopupOpen(ImGuiID(0), ImGuiPopupFlags_AnyPopupId) || TaskManager::getRunningTaskCount() > 0 || this->m_mouseButtonDown || this->m_hadEvent || !this->m_pressedKeys.empty();
const double timeout = std::max(0.0, (1.0 / 5.0) - (glfwGetTime() - this->m_lastFrameTime));
if ((this->m_lastFrameTime - this->m_frameRateUnlockTime) > 5 && this->m_frameRateTemporarilyUnlocked && !frameRateUnlocked) {
@@ -202,8 +203,11 @@ namespace hex {
this->frameEnd();
const auto targetFps = ImHexApi::System::getTargetFPS();
if (targetFps <= 200)
std::this_thread::sleep_for(std::chrono::milliseconds(u64((this->m_lastFrameTime + 1 / targetFps - glfwGetTime()) * 1000)));
if (targetFps <= 200) {
auto leftoverFrameTime = i64((this->m_lastFrameTime + 1 / targetFps - glfwGetTime()) * 1000);
if (leftoverFrameTime > 0)
std::this_thread::sleep_for(std::chrono::milliseconds(leftoverFrameTime));
}
this->m_lastFrameTime = glfwGetTime();
@@ -421,7 +425,6 @@ namespace hex {
}
}
this->m_popupsToOpen.remove_if([](const auto &name) {
if (ImGui::IsPopupOpen(name.c_str()))
return true;
@@ -431,17 +434,12 @@ namespace hex {
return false;
});
TaskManager::runDeferredCalls();
EventManager::post<EventFrameBegin>();
}
void Window::frame() {
{
auto &calls = ImHexApi::Tasks::getDeferredCalls();
for (const auto &callback : calls)
callback();
calls.clear();
}
auto &io = ImGui::GetIO();
for (auto &[name, view] : ContentRegistry::Views::getEntries()) {
ImGui::GetCurrentContext()->NextWindowData.ClearFlags();
@@ -452,7 +450,8 @@ namespace hex {
continue;
if (view->isAvailable()) {
ImGui::SetNextWindowSizeConstraints(scaled(view->getMinSize()), scaled(view->getMaxSize()));
float fontScaling = std::max(1.0F, ImHexApi::System::getFontSize() / ImHexApi::System::DefaultFontSize);
ImGui::SetNextWindowSizeConstraints(view->getMinSize() * fontScaling, view->getMaxSize() * fontScaling);
view->drawContent();
}
@@ -485,6 +484,8 @@ namespace hex {
void Window::frameEnd() {
EventManager::post<EventFrameEnd>();
TaskManager::collectGarbage();
this->endNativeWindowFrame();
ImGui::Render();

View File

@@ -52,16 +52,16 @@ add_library(${PROJECT_NAME} SHARED
source/content/views/view_provider_settings.cpp
source/content/views/view_find.cpp
source/content/helpers/math_evaluator.cpp
source/content/helpers/pattern_drawer.cpp
source/math_evaluator.cpp
source/pattern_drawer.cpp
source/lang/en_US.cpp
source/lang/de_DE.cpp
source/lang/en_US.cpp
source/lang/it_IT.cpp
source/lang/zh_CN.cpp
source/lang/ja_JP.cpp
source/lang/ko_KR.cpp
source/lang/pt_BR.cpp
source/lang/zh_CN.cpp
source/lang/zh_TW.cpp
)
@@ -69,7 +69,7 @@ add_library(${PROJECT_NAME} SHARED
target_include_directories(${PROJECT_NAME} PRIVATE include)
# Add additional libraries here #
target_link_libraries(${PROJECT_NAME} PRIVATE libimhex LLVMDemangle)
target_link_libraries(${PROJECT_NAME} PRIVATE libimhex)
# ---- No need to change anything from here downwards unless you know what you're doing ---- #

View File

@@ -98,7 +98,7 @@ namespace hex {
};
static i16 comparePrecedence(const Operator &a, const Operator &b);
static bool isLeftAssociative(const Operator op);
static bool isLeftAssociative(const Operator &op);
static std::pair<Operator, size_t> toOperator(const std::string &input);
private:

View File

@@ -34,12 +34,6 @@ namespace hex {
void visit(pl::ptrn::PatternWideString& pattern) override;
private:
void createDefaultEntry(const pl::ptrn::Pattern &pattern, const std::string &value, pl::core::Token::Literal &&literal) const;
void createLeafNode(const pl::ptrn::Pattern& pattern) const;
bool createTreeNode(const pl::ptrn::Pattern& pattern) const;
void makeSelectable(const pl::ptrn::Pattern &pattern) const;
void draw(pl::ptrn::Pattern& pattern);
template<ArrayPattern T>
@@ -53,19 +47,12 @@ namespace hex {
});
}
this->drawArrayEnd(pattern, opened);
this->drawArrayEnd(pattern, opened, pattern.isInlined());
}
bool drawArrayRoot(pl::ptrn::Pattern& pattern, size_t entryCount, bool isInlined);
void drawArrayNode(u64 idx, u64& displayEnd, pl::ptrn::Pattern& pattern);
void drawArrayEnd(pl::ptrn::Pattern& pattern, bool opened);
void drawCommentTooltip(const pl::ptrn::Pattern &pattern) const;
void drawTypenameColumn(const pl::ptrn::Pattern& pattern, const std::string& pattern_name) const;
void drawNameColumn(const pl::ptrn::Pattern& pattern) const;
void drawColorColumn(const pl::ptrn::Pattern& pattern) const;
void drawOffsetColumn(const pl::ptrn::Pattern& pattern) const;
void drawSizeColumn(const pl::ptrn::Pattern& pattern) const;
void drawArrayEnd(pl::ptrn::Pattern& pattern, bool opened, bool inlined);
u64& getDisplayEnd(const pl::ptrn::Pattern& pattern);

View File

@@ -17,6 +17,8 @@ namespace hex::plugin::builtin::prv {
[[nodiscard]] bool isResizable() const override { return false; }
[[nodiscard]] bool isSavable() const override { return false; }
void setBaseAddress(u64 address) override;
void readRaw(u64 offset, void *buffer, size_t size) override;
void writeRaw(u64 offset, const void *buffer, size_t size) override;
[[nodiscard]] size_t getActualSize() const override;

View File

@@ -15,6 +15,9 @@ namespace hex::plugin::builtin::prv {
[[nodiscard]] bool isResizable() const override { return false; }
[[nodiscard]] bool isSavable() const override { return false; }
[[nodiscard]] bool open() override { return true; }
void close() override { }
void readRaw(u64 offset, void *buffer, size_t size) override { hex::unused(offset, buffer, size); }
void writeRaw(u64 offset, const void *buffer, size_t size) override { hex::unused(offset, buffer, size); }
[[nodiscard]] size_t getActualSize() const override { return 0x00; }

View File

@@ -28,7 +28,7 @@ namespace hex::plugin::builtin {
void drawContent() override;
private:
bool m_disassembling = false;
TaskHolder m_disassemblerTask;
u64 m_baseAddress = 0;
ui::SelectedRegion m_range = ui::SelectedRegion::EntireData;

View File

@@ -61,6 +61,7 @@ namespace hex::plugin::builtin {
struct Regex {
std::string pattern;
bool fullMatch = true;
} regex;
struct BinaryPattern {
@@ -73,11 +74,11 @@ namespace hex::plugin::builtin {
std::map<prv::Provider*, std::vector<Occurrence>> m_foundOccurrences, m_sortedOccurrences;
std::map<prv::Provider*, OccurrenceTree> m_occurrenceTree;
std::map<prv::Provider*, std::string> m_currFilter;
std::atomic<bool> m_searchRunning;
TaskHolder m_searchTask;
bool m_settingsValid = false;
std::string m_currFilter;
private:
static std::vector<Occurrence> searchStrings(Task &task, prv::Provider *provider, Region searchRegion, SearchSettings::Strings settings);
static std::vector<Occurrence> searchSequence(Task &task, prv::Provider *provider, Region searchRegion, SearchSettings::Bytes settings);

View File

@@ -1,6 +1,7 @@
#pragma once
#include <hex/ui/view.hpp>
#include <hex/api/task.hpp>
#include <array>
#include <atomic>
@@ -27,7 +28,7 @@ namespace hex::plugin::builtin {
double m_entropyHandlePosition;
std::array<ImU64, 256> m_valueCounts = { 0 };
bool m_analyzing = false;
TaskHolder m_analyzerTask;
Region m_analyzedRegion = { 0, 0 };

View File

@@ -1,15 +1,12 @@
#pragma once
#include "pattern_drawer.hpp"
#include <hex.hpp>
#include <imgui.h>
#include <hex/ui/view.hpp>
#include <content/helpers/pattern_drawer.hpp>
#include <vector>
#include <tuple>
#include <cstdio>
namespace hex::plugin::builtin {

View File

@@ -5,6 +5,8 @@
#include <imgui.h>
#include <hex/ui/view.hpp>
#include <hex/api/task.hpp>
namespace hex::plugin::builtin {
class ViewYara : public View {
@@ -29,7 +31,7 @@ namespace hex::plugin::builtin {
std::vector<std::pair<std::fs::path, std::fs::path>> m_rules;
std::vector<YaraMatch> m_matches;
u32 m_selectedRule = 0;
bool m_matching = false;
TaskHolder m_matcherTask;
std::vector<std::string> m_consoleMessages;

View File

@@ -5,7 +5,7 @@
#include <hex/helpers/utils.hpp>
#include <hex/helpers/fmt.hpp>
#include "math_evaluator.hpp"
#include <content/helpers/math_evaluator.hpp>
namespace hex::plugin::builtin {

View File

@@ -1,34 +1,42 @@
#include <hex/api/content_registry.hpp>
#include <hex/providers/provider.hpp>
#include <hex/providers/buffered_reader.hpp>
#include <hex/helpers/fmt.hpp>
#include <hex/helpers/crypto.hpp>
namespace hex::plugin::builtin {
static std::string formatLanguageArray(prv::Provider *provider, u64 offset, size_t size, const std::string &start, const std::string &byteFormat, const std::string &end) {
constexpr auto NewLineIndent = "\n ";
constexpr static auto NewLineIndent = "\n ";
constexpr static auto LineLength = 16;
std::string result = start;
std::string result;
result.reserve(start.size() + hex::format(byteFormat, 0x00).size() * size + + std::string(NewLineIndent).size() / LineLength + end.size());
std::vector<u8> buffer(0x1'0000, 0x00);
for (u64 i = 0; i < size; i += buffer.size()) {
size_t readSize = std::min<u64>(buffer.size(), size - i);
provider->read(offset, buffer.data(), readSize);
result += start;
for (u32 j = 0; j < readSize; j++) {
if (j % 0x10 == 0)
result += NewLineIndent;
auto reader = prv::BufferedReader(provider);
reader.seek(offset);
reader.setEndAddress(offset + size - 1);
result += hex::format(byteFormat, buffer[j]);
}
u64 index = 0x00;
for (u8 byte : reader) {
if ((index % LineLength) == 0x00)
result += NewLineIndent;
// Remove trailing comma
result += hex::format(byteFormat, byte);
index++;
}
// Remove trailing comma
if (provider->getActualSize() > 0) {
result.pop_back();
result.pop_back();
}
result += "\n";
result += end;
result += "\n" + end;
return result;
}
@@ -63,45 +71,78 @@ namespace hex::plugin::builtin {
return formatLanguageArray(provider, offset, size, "const data = new Uint8Array([", "0x{0:02X}, ", "]);");
});
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.lua", [](prv::Provider *provider, u64 offset, size_t size) {
return formatLanguageArray(provider, offset, size, "data = {", "0x{0:02X}, ", "}");
});
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.go", [](prv::Provider *provider, u64 offset, size_t size) {
return formatLanguageArray(provider, offset, size, "data := [...]byte {", "0x{0:02X}, ", "}");
});
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.crystal", [](prv::Provider *provider, u64 offset, size_t size) {
return formatLanguageArray(provider, offset, size, "data = [", "0x{0:02X}, ", "] of UInt8");
});
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.swift", [](prv::Provider *provider, u64 offset, size_t size) {
return formatLanguageArray(provider, offset, size, "let data: [Uint8] = [", "0x{0:02X}, ", "]");
});
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.pascal", [](prv::Provider *provider, u64 offset, size_t size) {
return formatLanguageArray(provider, offset, size, hex::format("data: array[0..{0}] of Byte = (", size - 1), "${0:02X}, ", ")");
});
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.base64", [](prv::Provider *provider, u64 offset, size_t size) {
std::vector<u8> data(size, 0x00);
provider->read(offset, data.data(), size);
auto result = crypt::encode64(data);
return std::string(result.begin(), result.end());
});
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.ascii", [](prv::Provider *provider, u64 offset, size_t size) {
std::string result = "Hex View 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n\n";
constexpr static auto HeaderLine = "Hex View 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n";
std::string result;
result.reserve(std::string(HeaderLine).size() * size / 0x10);
std::vector<u8> buffer(0x1'0000, 0x00);
for (u64 byte = 0; byte < size; byte += buffer.size()) {
size_t readSize = std::min<u64>(buffer.size(), size - byte);
provider->read(offset, buffer.data(), readSize);
result += HeaderLine;
const auto end = (offset + readSize) - 1;
auto reader = prv::BufferedReader(provider);
reader.seek(offset);
reader.setEndAddress((offset + size) - 1);
for (u32 col = offset >> 4; col <= (end >> 4); col++) {
result += hex::format("{0:08X} ", col << 4);
for (u64 i = 0; i < 16; i++) {
u64 address = offset & ~u64(0x0F);
std::string asciiRow;
for (u8 byte : reader) {
if ((address % 0x10) == 0) {
result += hex::format(" {}", asciiRow);
result += hex::format("\n{0:08X} ", address);
if ((col == (offset >> 4) && i < (offset & 0xF)) || (col == (end >> 4) && i > (end & 0xF)))
asciiRow.clear();
if (address == (offset & ~u64(0x0F))) {
for (u64 i = 0; i < (offset - address); i++) {
result += " ";
else
result += hex::format("{0:02X} ", buffer[((col << 4) - offset) + i]);
if ((i & 0xF) == 0x7)
result += " ";
asciiRow += " ";
}
address = offset;
}
}
result += hex::format("{0:02X} ", byte);
asciiRow += std::isprint(byte) ? char(byte) : '.';
if ((address % 0x10) == 0x07)
result += " ";
for (u64 i = 0; i < 16; i++) {
if ((col == (offset >> 4) && i < (offset & 0xF)) || (col == (end >> 4) && i > (end & 0xF)))
result += " ";
else {
u8 c = buffer[((col << 4) - offset) + i];
char displayChar = (c < 32 || c >= 128) ? '.' : c;
result += hex::format("{0}", displayChar);
}
}
result += "\n";
}
address++;
}
if ((address % 0x10) != 0x00)
for (u32 i = 0; i < (0x10 - (address % 0x10)); i++)
result += " ";
result += hex::format(" {}", asciiRow);
return result;
});
@@ -115,48 +156,46 @@ namespace hex::plugin::builtin {
" .textcolumn { color:#000000 }\n"
" </style>\n\n"
" <code>\n"
" <span class=\"offsetheader\">Hex View&nbsp&nbsp00 01 02 03 04 05 06 07&nbsp 08 09 0A 0B 0C 0D 0E 0F</span><br>\n";
" <span class=\"offsetheader\">Hex View&nbsp&nbsp00 01 02 03 04 05 06 07&nbsp 08 09 0A 0B 0C 0D 0E 0F</span>";
auto reader = prv::BufferedReader(provider);
reader.seek(offset);
reader.setEndAddress((offset + size) - 1);
std::vector<u8> buffer(0x1'0000, 0x00);
for (u64 byte = 0; byte < size; byte += buffer.size()) {
size_t readSize = std::min<u64>(buffer.size(), size - byte);
provider->read(offset, buffer.data(), readSize);
u64 address = offset & ~u64(0x0F);
std::string asciiRow;
for (u8 byte : reader) {
if ((address % 0x10) == 0) {
result += hex::format(" {}", asciiRow);
result += hex::format("<br>\n <span class=\"offsetcolumn\">{0:08X}</span>&nbsp&nbsp<span class=\"hexcolumn\">", address);
const auto end = (offset + readSize) - 1;
asciiRow.clear();
for (u32 col = offset >> 4; col <= (end >> 4); col++) {
result += hex::format(" <span class=\"offsetcolumn\">{0:08X}</span>&nbsp&nbsp<span class=\"hexcolumn\">", col << 4);
for (u64 i = 0; i < 16; i++) {
if ((col == (offset >> 4) && i < (offset & 0xF)) || (col == (end >> 4) && i > (end & 0xF)))
result += "&nbsp&nbsp ";
else
result += hex::format("{0:02X} ", buffer[((col << 4) - offset) + i]);
if ((i & 0xF) == 0x7)
result += "&nbsp";
}
result += "</span>&nbsp&nbsp<span class=\"textcolumn\">";
for (u64 i = 0; i < 16; i++) {
if ((col == (offset >> 4) && i < (offset & 0xF)) || (col == (end >> 4) && i > (end & 0xF)))
result += "&nbsp";
else {
u8 c = buffer[((col << 4) - offset) + i];
char displayChar = (c < 32 || c >= 128) ? '.' : c;
result += hex::format("{0}", displayChar);
if (address == (offset & ~u64(0x0F))) {
for (u64 i = 0; i < (offset - address); i++) {
result += "&nbsp&nbsp&nbsp";
asciiRow += "&nbsp";
}
address = offset;
}
result += "</span><br>\n";
result += "</span>";
}
result += hex::format("{0:02X} ", byte);
asciiRow += std::isprint(byte) ? char(byte) : '.';
if ((address % 0x10) == 0x07)
result += "&nbsp";
address++;
}
for (u32 i = 0; i < (0x10 - (address % 0x10)); i++)
result += "&nbsp&nbsp&nbsp";
result += asciiRow;
result +=
" </code>\n"
"\n </code>\n"
"</div>\n";
return result;

View File

@@ -86,7 +86,7 @@ namespace hex::plugin::builtin {
auto format = (style == Style::Decimal) ? "{0:d}" : ((style == Style::Hexadecimal) ? hex::format("0x{{0:0{}X}}", Size * 2) : hex::format("0o{{0:0{}o}}", Size * 3));
T value = 0x00;
std::memcpy(&value, buffer.data(), Size);
std::memcpy(&value, buffer.data(), std::min(sizeof(T), Size));
return hex::format(format, hex::changeEndianess(value, Size, endian));
}
@@ -98,8 +98,11 @@ namespace hex::plugin::builtin {
auto format = (style == Style::Decimal) ? "{0}{1:d}" : ((style == Style::Hexadecimal) ? hex::format("{{0}}0x{{1:0{}X}}", Size * 2) : hex::format("{{0}}0o{{1:0{}o}}", Size * 3));
T value = 0x00;
std::memcpy(&value, buffer.data(), Size);
auto number = hex::signExtend(Size * 8, hex::changeEndianess(value, Size, endian));
std::memcpy(&value, buffer.data(), std::min(sizeof(T), Size));
auto number = hex::changeEndianess(value, Size, endian);
if (Size != sizeof(T))
number = hex::signExtend(Size * 8, number);
bool negative = number < 0;
return hex::format(format, negative ? "-" : "", std::abs(number));
@@ -118,7 +121,7 @@ namespace hex::plugin::builtin {
template<typename T>
static hex::ContentRegistry::DataInspector::impl::GeneratorFunction drawString(T func) {
return [func](const std::vector<u8> &buffer, std::endian endian, Style style) {
return [value = func(buffer, endian, style)] -> std::string { ImGui::TextUnformatted(value.c_str()); return value; };
return [value = func(buffer, endian, style)]() -> std::string { ImGui::TextUnformatted(value.c_str()); return value; };
};
}

View File

@@ -32,7 +32,7 @@ namespace hex::plugin::builtin {
NodeBuffer() : Node("hex.builtin.nodes.constants.buffer.header", { dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "") }) { }
void drawNode() override {
constexpr int StepSize = 1, FastStepSize = 10;
constexpr static int StepSize = 1, FastStepSize = 10;
ImGui::PushItemWidth(100);
ImGui::InputScalar("hex.builtin.nodes.constants.buffer.size"_lang, ImGuiDataType_U32, &this->m_size, &StepSize, &FastStepSize);

View File

@@ -21,7 +21,8 @@ namespace hex::plugin::builtin {
auto provider = ImHexApi::Provider::createProvider("hex.builtin.provider.file", true);
if (auto *fileProvider = dynamic_cast<prv::FileProvider*>(provider); fileProvider != nullptr) {
fileProvider->setPath(path);
(void)fileProvider->open();
if (fileProvider->open())
EventManager::post<EventProviderOpened>(fileProvider);
}
}
@@ -30,27 +31,32 @@ namespace hex::plugin::builtin {
EventManager::subscribe<EventWindowClosing>([](GLFWwindow *window) {
if (ImHexApi::Provider::isDirty()) {
glfwSetWindowShouldClose(window, GLFW_FALSE);
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.popup.exit_application.title"_lang); });
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.popup.exit_application.title"_lang); });
}
});
EventManager::subscribe<EventProviderClosing>([](hex::prv::Provider *provider, bool *shouldClose) {
if (provider->isDirty()) {
*shouldClose = false;
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.popup.close_provider.title"_lang); });
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.popup.close_provider.title"_lang); });
}
});
EventManager::subscribe<EventProviderChanged>([](hex::prv::Provider *oldProvider, hex::prv::Provider *newProvider) {
hex::unused(oldProvider);
if (newProvider != nullptr) {
if (newProvider != nullptr && newProvider->isAvailable()) {
EventManager::post<RequestChangeWindowTitle>(newProvider->getName());
} else {
EventManager::post<RequestChangeWindowTitle>("");
}
});
EventManager::subscribe<EventProviderOpened>([](hex::prv::Provider *provider) {
if (provider != nullptr && ImHexApi::Provider::get() == provider)
EventManager::post<RequestChangeWindowTitle>(provider->getName());
});
EventManager::subscribe<RequestOpenFile>(openFile);
EventManager::subscribe<RequestOpenWindow>([](const std::string &name) {
@@ -87,22 +93,27 @@ namespace hex::plugin::builtin {
if (provider->hasFilePicker()) {
if (!provider->handleFilePicker()) {
ImHexApi::Tasks::doLater([provider] { ImHexApi::Provider::remove(provider); });
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); });
return;
}
if (!provider->open()) {
View::showErrorPopup("hex.builtin.popup.error.open"_lang);
ImHexApi::Tasks::doLater([provider] { ImHexApi::Provider::remove(provider); });
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); });
return;
}
EventManager::post<EventProviderOpened>(provider);
}
else if (provider->hasLoadInterface())
EventManager::post<RequestOpenPopup>(View::toWindowName("hex.builtin.view.provider_settings.load_popup"));
else {
if (!provider->open() || !provider->isAvailable()) {
View::showErrorPopup("hex.builtin.popup.error.open"_lang);
ImHexApi::Tasks::doLater([provider] { ImHexApi::Provider::remove(provider); });
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); });
return;
}
EventManager::post<EventProviderOpened>(provider);
}
});

View File

@@ -1,4 +1,4 @@
#include "math_evaluator.hpp"
#include <content/helpers/math_evaluator.hpp>
#include <hex/helpers/utils.hpp>
#include <hex/helpers/concepts.hpp>
@@ -6,7 +6,6 @@
#include <string>
#include <queue>
#include <stack>
#include <stdexcept>
#include <cmath>
#include <cstdint>
#include <optional>
@@ -19,7 +18,7 @@ namespace hex {
}
template<typename T>
bool MathEvaluator<T>::isLeftAssociative(const Operator op) {
bool MathEvaluator<T>::isLeftAssociative(const Operator &op) {
return (static_cast<u32>(op) & 0xF00) == 0;
}

View File

@@ -1,4 +1,4 @@
#include "pattern_drawer.hpp"
#include <content/helpers/pattern_drawer.hpp>
#include <pl/patterns/pattern_array_dynamic.hpp>
#include <pl/patterns/pattern_array_static.hpp>
@@ -25,15 +25,100 @@
#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
namespace {
constexpr static auto DisplayEndDefault = 50u;
constexpr static auto DisplayEndStep = 50u;
using namespace ::std::literals::string_literals;
};
namespace hex {
namespace {
constexpr auto DisplayEndDefault = 50U;
constexpr auto DisplayEndStep = 50U;
using namespace ::std::literals::string_literals;
void createLeafNode(const pl::ptrn::Pattern& pattern) {
ImGui::TreeNodeEx(pattern.getDisplayName().c_str(), ImGuiTreeNodeFlags_Leaf |
ImGuiTreeNodeFlags_NoTreePushOnOpen |
ImGuiTreeNodeFlags_SpanFullWidth |
ImGuiTreeNodeFlags_AllowItemOverlap);
}
bool createTreeNode(const pl::ptrn::Pattern& pattern) {
if (pattern.isSealed()) {
ImGui::Indent();
ImGui::TextUnformatted(pattern.getDisplayName().c_str());
ImGui::Unindent();
return false;
}
else
return ImGui::TreeNodeEx(pattern.getDisplayName().c_str(), ImGuiTreeNodeFlags_SpanFullWidth);
}
void drawTypenameColumn(const pl::ptrn::Pattern& pattern, const std::string& pattern_name) {
ImGui::TextFormattedColored(ImColor(0xFFD69C56), pattern_name);
ImGui::SameLine();
ImGui::TextUnformatted(pattern.getTypeName().c_str());
ImGui::TableNextColumn();
}
void drawNameColumn(const pl::ptrn::Pattern& pattern) {
ImGui::TextUnformatted(pattern.getDisplayName().c_str());
ImGui::TableNextColumn();
}
void drawColorColumn(const pl::ptrn::Pattern& pattern) {
ImGui::ColorButton("color", ImColor(pattern.getColor()), ImGuiColorEditFlags_NoTooltip, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
ImGui::TableNextColumn();
}
void drawOffsetColumn(const pl::ptrn::Pattern& pattern) {
ImGui::TextFormatted("0x{0:08X} : 0x{1:08X}", pattern.getOffset(), pattern.getOffset() + pattern.getSize() - (pattern.getSize() == 0 ? 0 : 1));
ImGui::TableNextColumn();
}
void drawSizeColumn(const pl::ptrn::Pattern& pattern) {
ImGui::TextFormatted("0x{0:04X}", pattern.getSize());
ImGui::TableNextColumn();
}
void drawCommentTooltip(const pl::ptrn::Pattern &pattern) {
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) && pattern.getComment() != nullptr) {
ImGui::BeginTooltip();
ImGui::TextUnformatted(pattern.getComment()->c_str());
ImGui::EndTooltip();
}
}
void makeSelectable(const pl::ptrn::Pattern &pattern) {
ImGui::PushID(static_cast<int>(pattern.getOffset()));
ImGui::PushID(pattern.getVariableName().c_str());
if (ImGui::Selectable("##PatternLine", false, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap)) {
ImHexApi::HexEditor::setSelection(pattern.getOffset(), pattern.getSize());
}
ImGui::SameLine(0, 0);
ImGui::PopID();
ImGui::PopID();
}
void createDefaultEntry(pl::ptrn::Pattern &pattern) {
ImGui::TableNextRow();
createLeafNode(pattern);
ImGui::TableNextColumn();
makeSelectable(pattern);
drawCommentTooltip(pattern);
ImGui::SameLine();
drawNameColumn(pattern);
drawColorColumn(pattern);
drawOffsetColumn(pattern);
drawSizeColumn(pattern);
ImGui::TextFormattedColored(ImColor(0xFF9BC64D), "{}", pattern.getFormattedName().empty() ? pattern.getTypeName() : pattern.getFormattedName());
ImGui::TableNextColumn();
ImGui::TextFormatted("{}", pattern.getFormattedValue());
}
}
void PatternDrawer::visit(pl::ptrn::PatternArrayDynamic& pattern) {
this->drawArray(pattern);
}
@@ -81,15 +166,12 @@ namespace hex {
ImGui::TableNextColumn();
makeSelectable(pattern);
drawCommentTooltip(pattern);
ImGui::TableNextColumn();
drawColorColumn(pattern);
drawOffsetColumn(pattern);
drawSizeColumn(pattern);
drawTypenameColumn(pattern, "bitfield");
ImGui::TextFormatted("{}", pattern.getFormattedValue());
} else {
ImGui::SameLine();
ImGui::TreeNodeEx("", ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf);
}
if (open) {
@@ -97,16 +179,17 @@ namespace hex {
this->draw(field);
});
ImGui::TreePop();
if (!pattern.isInlined())
ImGui::TreePop();
}
}
void PatternDrawer::visit(pl::ptrn::PatternBoolean& pattern) {
this->createDefaultEntry(pattern, pattern.getFormattedValue(), static_cast<bool>(pattern.getValue()));
createDefaultEntry(pattern);
}
void PatternDrawer::visit(pl::ptrn::PatternCharacter& pattern) {
this->createDefaultEntry(pattern, pattern.getFormattedValue(), pattern.getValue());
createDefaultEntry(pattern);
}
void PatternDrawer::visit(pl::ptrn::PatternEnum& pattern) {
@@ -125,11 +208,7 @@ namespace hex {
}
void PatternDrawer::visit(pl::ptrn::PatternFloat& pattern) {
if (pattern.getSize() == 4) {
this->createDefaultEntry(pattern, pattern.getFormattedValue(), static_cast<float>(pattern.getValue()));
} else if (pattern.getSize() == 8) {
this->createDefaultEntry(pattern, pattern.getFormattedValue(), static_cast<double>(pattern.getValue()));
}
createDefaultEntry(pattern);
}
void PatternDrawer::visit(pl::ptrn::PatternPadding& pattern) {
@@ -147,32 +226,29 @@ namespace hex {
ImGui::TableNextColumn();
makeSelectable(pattern);
drawCommentTooltip(pattern);
ImGui::SameLine(0, 0);
drawColorColumn(pattern);
drawOffsetColumn(pattern);
drawSizeColumn(pattern);
ImGui::TextFormattedColored(ImColor(0xFF9BC64D), "{}", pattern.getFormattedName());
ImGui::TableNextColumn();
ImGui::TextFormatted("{}", pattern.getFormattedValue());
} else {
ImGui::SameLine();
ImGui::TreeNodeEx("", ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf);
}
if (open) {
pattern.getPointedAtPattern()->accept(*this);
ImGui::TreePop();
if (!pattern.isInlined())
ImGui::TreePop();
}
}
void PatternDrawer::visit(pl::ptrn::PatternSigned& pattern) {
this->createDefaultEntry(pattern, pattern.getFormattedValue(), pattern.getValue());
createDefaultEntry(pattern);
}
void PatternDrawer::visit(pl::ptrn::PatternString& pattern) {
if (pattern.getSize() > 0)
this->createDefaultEntry(pattern, pattern.getFormattedValue(), pattern.getValue());
createDefaultEntry(pattern);
}
void PatternDrawer::visit(pl::ptrn::PatternStruct& pattern) {
@@ -185,14 +261,14 @@ namespace hex {
ImGui::TableNextColumn();
makeSelectable(pattern);
drawCommentTooltip(pattern);
ImGui::TableNextColumn();
if (pattern.isSealed())
drawColorColumn(pattern);
else
ImGui::TableNextColumn();
drawOffsetColumn(pattern);
drawSizeColumn(pattern);
drawTypenameColumn(pattern, "struct");
ImGui::TextFormatted("{}", pattern.getFormattedValue());
} else {
ImGui::SameLine();
ImGui::TreeNodeEx("", ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf);
}
if (open) {
@@ -200,7 +276,8 @@ namespace hex {
this->draw(member);
});
ImGui::TreePop();
if (!pattern.isInlined())
ImGui::TreePop();
}
}
@@ -214,14 +291,14 @@ namespace hex {
ImGui::TableNextColumn();
makeSelectable(pattern);
drawCommentTooltip(pattern);
ImGui::TableNextColumn();
if (pattern.isSealed())
drawColorColumn(pattern);
else
ImGui::TableNextColumn();
drawOffsetColumn(pattern);
drawSizeColumn(pattern);
drawTypenameColumn(pattern, "union");
ImGui::TextFormatted("{}", pattern.getFormattedValue());
} else {
ImGui::SameLine();
ImGui::TreeNodeEx("", ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf);
}
if (open) {
@@ -229,59 +306,22 @@ namespace hex {
this->draw(member);
});
ImGui::TreePop();
if (!pattern.isInlined())
ImGui::TreePop();
}
}
void PatternDrawer::visit(pl::ptrn::PatternUnsigned& pattern) {
this->createDefaultEntry(pattern, pattern.getFormattedValue(), pattern.getValue());
createDefaultEntry(pattern);
}
void PatternDrawer::visit(pl::ptrn::PatternWideCharacter& pattern) {
this->createDefaultEntry(pattern, pattern.getFormattedValue(), u128(pattern.getValue()));
createDefaultEntry(pattern);
}
void PatternDrawer::visit(pl::ptrn::PatternWideString& pattern) {
if (pattern.getSize() > 0)
this->createDefaultEntry(pattern, pattern.getFormattedValue(), pattern.getValue());
}
void PatternDrawer::createDefaultEntry(const pl::ptrn::Pattern &pattern, const std::string &value, pl::core::Token::Literal &&literal) const {
ImGui::TableNextRow();
createLeafNode(pattern);
ImGui::TableNextColumn();
makeSelectable(pattern);
drawCommentTooltip(pattern);
ImGui::SameLine();
drawNameColumn(pattern);
drawColorColumn(pattern);
drawOffsetColumn(pattern);
drawSizeColumn(pattern);
ImGui::TextFormattedColored(ImColor(0xFF9BC64D), "{}", pattern.getFormattedName().empty() ? pattern.getTypeName() : pattern.getFormattedName());
ImGui::TableNextColumn();
ImGui::TextFormatted("{}", pattern.formatDisplayValue(value, literal));
}
void PatternDrawer::makeSelectable(const pl::ptrn::Pattern &pattern) const {
ImGui::PushID(static_cast<int>(pattern.getOffset()));
ImGui::PushID(pattern.getVariableName().c_str());
if (ImGui::Selectable("##PatternLine", false, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap)) {
ImHexApi::HexEditor::setSelection(pattern.getOffset(), pattern.getSize());
}
ImGui::SameLine();
ImGui::PopID();
ImGui::PopID();
}
void PatternDrawer::drawCommentTooltip(const pl::ptrn::Pattern &pattern) const {
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) && pattern.getComment().has_value()) {
ImGui::BeginTooltip();
ImGui::TextUnformatted(pattern.getComment()->c_str());
ImGui::EndTooltip();
}
createDefaultEntry(pattern);
}
void PatternDrawer::draw(pl::ptrn::Pattern& pattern) {
@@ -303,7 +343,10 @@ namespace hex {
ImGui::TableNextColumn();
makeSelectable(pattern);
drawCommentTooltip(pattern);
ImGui::TableNextColumn();
if (pattern.isSealed())
drawColorColumn(pattern);
else
ImGui::TableNextColumn();
drawOffsetColumn(pattern);
drawSizeColumn(pattern);
ImGui::TextFormattedColored(ImColor(0xFF9BC64D), "{0}", pattern.getTypeName());
@@ -317,9 +360,6 @@ namespace hex {
ImGui::TableNextColumn();
ImGui::TextFormatted("{}", pattern.getFormattedValue());
} else {
ImGui::SameLine();
ImGui::TreeNodeEx("", ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf);
}
return open;
@@ -328,7 +368,7 @@ namespace hex {
void PatternDrawer::drawArrayNode(u64 idx, u64& displayEnd, pl::ptrn::Pattern& pattern) {
u64 lastVisible = displayEnd - 1;
ImGui::PushID(pattern.getOffset());
ImGui::PushID(reinterpret_cast<void*>(pattern.getOffset()));
if (idx < lastVisible) {
this->draw(pattern);
@@ -344,65 +384,23 @@ namespace hex {
ImGui::PopID();
}
void PatternDrawer::drawArrayEnd(pl::ptrn::Pattern& pattern, bool opened) {
void PatternDrawer::drawArrayEnd(pl::ptrn::Pattern& pattern, bool opened, bool inlined) {
if (opened) {
ImGui::TreePop();
if (!inlined)
ImGui::TreePop();
} else {
auto& displayEnd = this->getDisplayEnd(pattern);
displayEnd = DisplayEndDefault;
}
}
void PatternDrawer::createLeafNode(const pl::ptrn::Pattern& pattern) const {
ImGui::TreeNodeEx(pattern.getDisplayName().c_str(), ImGuiTreeNodeFlags_Leaf |
ImGuiTreeNodeFlags_NoTreePushOnOpen |
ImGuiTreeNodeFlags_SpanFullWidth |
ImGuiTreeNodeFlags_AllowItemOverlap);
}
bool PatternDrawer::createTreeNode(const pl::ptrn::Pattern& pattern) const {
if (pattern.isSealed()) {
ImGui::Selectable(pattern.getDisplayName().c_str(), false, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap);
return false;
}
else
return ImGui::TreeNodeEx(pattern.getDisplayName().c_str(), ImGuiTreeNodeFlags_SpanFullWidth);
}
void PatternDrawer::drawTypenameColumn(const pl::ptrn::Pattern& pattern, const std::string& pattern_name) const {
ImGui::TextFormattedColored(ImColor(0xFFD69C56), pattern_name);
ImGui::SameLine();
ImGui::TextUnformatted(pattern.getTypeName().c_str());
ImGui::TableNextColumn();
}
void PatternDrawer::drawNameColumn(const pl::ptrn::Pattern& pattern) const {
ImGui::TextUnformatted(pattern.getDisplayName().c_str());
ImGui::TableNextColumn();
}
void PatternDrawer::drawColorColumn(const pl::ptrn::Pattern& pattern) const {
ImGui::ColorButton("color", ImColor(pattern.getColor()), ImGuiColorEditFlags_NoTooltip, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
ImGui::TableNextColumn();
}
void PatternDrawer::drawOffsetColumn(const pl::ptrn::Pattern& pattern) const {
ImGui::TextFormatted("0x{0:08X} : 0x{1:08X}", pattern.getOffset(), pattern.getOffset() + pattern.getSize() - (pattern.getSize() == 0 ? 0 : 1));
ImGui::TableNextColumn();
}
void PatternDrawer::drawSizeColumn(const pl::ptrn::Pattern& pattern) const {
ImGui::TextFormatted("0x{0:04X}", pattern.getSize());
ImGui::TableNextColumn();
}
u64& PatternDrawer::getDisplayEnd(const pl::ptrn::Pattern& pattern) {
auto it = m_displayEnd.find(&pattern);
if (it != m_displayEnd.end()) {
auto it = this->m_displayEnd.find(&pattern);
if (it != this->m_displayEnd.end()) {
return it->second;
}
auto [inserted, success] = m_displayEnd.emplace(&pattern, DisplayEndDefault);
return inserted->second;
auto [value, success] = this->m_displayEnd.emplace(&pattern, DisplayEndDefault);
return value->second;
}
};

View File

@@ -9,8 +9,6 @@
#include <hex/helpers/crypto.hpp>
#include <hex/helpers/patches.hpp>
#include <thread>
namespace hex::plugin::builtin {
static bool g_demoWindowOpen = false;
@@ -20,13 +18,14 @@ namespace hex::plugin::builtin {
ContentRegistry::Interface::registerMainMenuItem("hex.builtin.menu.file", 1000);
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1050, [&] {
bool taskRunning = Task::getRunningTaskCount() > 0;
bool taskRunning = TaskManager::getRunningTaskCount() > 0;
if (ImGui::MenuItem("hex.builtin.menu.file.create_file"_lang, "CTRL + N", false, !taskRunning)) {
EventManager::post<RequestOpenWindow>("Create File");
}
if (ImGui::MenuItem("hex.builtin.menu.file.open_file"_lang, "CTRL + O", false, !taskRunning)) {
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
EventManager::post<RequestOpenFile>(path);
});
EventManager::post<RequestOpenWindow>("Open File");
}
if (ImGui::BeginMenu("hex.builtin.menu.file.open_other"_lang, !taskRunning)) {
@@ -44,7 +43,7 @@ namespace hex::plugin::builtin {
/* File open, quit imhex */
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1150, [&] {
bool providerValid = ImHexApi::Provider::isValid();
bool taskRunning = Task::getRunningTaskCount() > 0;
bool taskRunning = TaskManager::getRunningTaskCount() > 0;
if (ImGui::MenuItem("hex.builtin.menu.file.close"_lang, "CTRL + W", false, providerValid && !taskRunning)) {
ImHexApi::Provider::remove(ImHexApi::Provider::get());
@@ -59,7 +58,7 @@ namespace hex::plugin::builtin {
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1250, [&] {
auto provider = ImHexApi::Provider::get();
bool providerValid = ImHexApi::Provider::isValid();
bool taskRunning = Task::getRunningTaskCount() > 0;
bool taskRunning = TaskManager::getRunningTaskCount() > 0;
if (ImGui::MenuItem("hex.builtin.menu.file.open_project"_lang, "", false, !taskRunning)) {
fs::openFileBrowser(fs::DialogMode::Open, { {"Project File", "hexproj"}
@@ -85,7 +84,7 @@ namespace hex::plugin::builtin {
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1300, [&] {
auto provider = ImHexApi::Provider::get();
bool providerValid = ImHexApi::Provider::isValid();
bool taskRunning = Task::getRunningTaskCount() > 0;
bool taskRunning = TaskManager::getRunningTaskCount() > 0;
/* Import */
if (ImGui::BeginMenu("hex.builtin.menu.file.import"_lang, !taskRunning)) {
@@ -126,9 +125,7 @@ namespace hex::plugin::builtin {
if (ImGui::MenuItem("hex.builtin.menu.file.import.ips"_lang, nullptr, false)) {
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
std::thread([path] {
auto task = ImHexApi::Tasks::createTask("hex.builtin.common.processing", 0);
TaskManager::createTask("hex.builtin.common.processing", TaskManager::NoProgress, [path](auto &task) {
auto patchData = fs::File(path, fs::File::Mode::Read).readBytes();
auto patch = hex::loadIPSPatch(patchData);
@@ -144,15 +141,13 @@ namespace hex::plugin::builtin {
}
provider->createUndoPoint();
}).detach();
});
});
}
if (ImGui::MenuItem("hex.builtin.menu.file.import.ips32"_lang, nullptr, false)) {
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
std::thread([path] {
auto task = ImHexApi::Tasks::createTask("hex.builtin.common.processing", 0);
TaskManager::createTask("hex.builtin.common.processing", TaskManager::NoProgress, [path](auto &task) {
auto patchData = fs::File(path, fs::File::Mode::Read).readBytes();
auto patch = hex::loadIPS32Patch(patchData);
@@ -168,7 +163,7 @@ namespace hex::plugin::builtin {
}
provider->createUndoPoint();
}).detach();
});
});
}
@@ -186,12 +181,10 @@ namespace hex::plugin::builtin {
patches[0x00454F45] = value;
}
std::thread([patches] {
auto task = ImHexApi::Tasks::createTask("hex.builtin.common.processing", 0);
TaskManager::createTask("hex.builtin.common.processing", TaskManager::NoProgress, [patches](auto &) {
auto data = generateIPSPatch(patches);
ImHexApi::Tasks::doLater([data] {
TaskManager::doLater([data] {
fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const auto &path) {
auto file = fs::File(path, fs::File::Mode::Create);
if (!file.isValid()) {
@@ -202,7 +195,7 @@ namespace hex::plugin::builtin {
file.write(data);
});
});
}).detach();
});
}
if (ImGui::MenuItem("hex.builtin.menu.file.export.ips32"_lang, nullptr, false)) {
@@ -213,23 +206,21 @@ namespace hex::plugin::builtin {
patches[0x45454F45] = value;
}
std::thread([patches] {
auto task = ImHexApi::Tasks::createTask("hex.builtin.common.processing", 0);
TaskManager::createTask("hex.builtin.common.processing", TaskManager::NoProgress, [patches](auto &) {
auto data = generateIPS32Patch(patches);
ImHexApi::Tasks::doLater([data] {
TaskManager::doLater([data] {
fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const auto &path) {
auto file = fs::File(path, fs::File::Mode::Create);
if (!file.isValid()) {
View::showErrorPopup("hex.builtin.menu.file.export.popup.create"_lang);
View::showErrorPopup("hex.builtin.menu.file.export.base64.popup.export_error"_lang);
return;
}
file.write(data);
});
});
}).detach();
});
}
ImGui::EndMenu();

View File

@@ -13,10 +13,23 @@ namespace hex::plugin::builtin {
using namespace pl::core;
using FunctionParameterCount = pl::api::FunctionParameterCount;
pl::api::Namespace nsStdHttp = { "builtin", "std", "http" };
pl::api::Namespace nsHexCore = { "builtin", "hex", "core" };
{
/* get_selection() */
ContentRegistry::PatternLanguage::addDangerousFunction(nsHexCore, "get_selection", FunctionParameterCount::none(), [](Evaluator *, auto) -> std::optional<Token::Literal> {
if (!ImHexApi::HexEditor::isSelectionValid())
return std::numeric_limits<u128>::max();
auto selection = ImHexApi::HexEditor::getSelection();
return u128(u128(selection->getStartAddress()) << 64 | u128(selection->getSize()));
});
}
pl::api::Namespace nsHexHttp = { "builtin", "hex", "http" };
{
/* get(url) */
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdHttp, "get", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addDangerousFunction(nsHexHttp, "get", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
const auto url = Token::literalToString(params[0], false);
hex::Net net;

View File

@@ -13,6 +13,8 @@ namespace hex::plugin::builtin {
auto baseAddress = strtoull(value.c_str(), nullptr, 0);
ImHexApi::Provider::get()->setBaseAddress(baseAddress);
runtime.setDataBaseAddress(baseAddress);
return true;
});

View File

@@ -41,6 +41,8 @@ namespace hex::plugin::builtin {
provider->loadSettings(providerSettings["settings"]);
if (!provider->open())
success = false;
else
EventManager::post<EventProviderOpened>(provider);
}
return success;

View File

@@ -32,7 +32,7 @@
namespace hex::plugin::builtin::prv {
DiskProvider::DiskProvider() : Provider() {
this->reloadDrives();
}
bool DiskProvider::isAvailable() const {
@@ -137,7 +137,7 @@ namespace hex::plugin::builtin::prv {
#endif
return Provider::open();
return true;
}
void DiskProvider::close() {
@@ -156,8 +156,6 @@ namespace hex::plugin::builtin::prv {
this->m_diskHandle = -1;
#endif
Provider::close();
}
void DiskProvider::readRaw(u64 offset, void *buffer, size_t size) {
@@ -320,6 +318,9 @@ namespace hex::plugin::builtin::prv {
void DiskProvider::drawLoadInterface() {
#if defined(OS_WINDOWS)
if (this->m_availableDrives.empty())
this->reloadDrives();
if (ImGui::BeginListBox("hex.builtin.provider.disk.selected_disk"_lang)) {
for (const auto &drive : this->m_availableDrives) {
@@ -358,8 +359,10 @@ namespace hex::plugin::builtin::prv {
}
std::pair<Region, bool> DiskProvider::getRegionValidity(u64 address) const {
address -= this->getBaseAddress();
if (address < this->getActualSize())
return { Region { address, this->getActualSize() - address }, true };
return { Region { this->getBaseAddress() + address, this->getActualSize() - address }, true };
else
return { Region::Invalid(), false };
}

View File

@@ -29,7 +29,7 @@ namespace hex::plugin::builtin::prv {
}
bool FileProvider::isResizable() const {
return true;
return isAvailable() && isWritable();
}
bool FileProvider::isSavable() const {
@@ -300,7 +300,7 @@ namespace hex::plugin::builtin::prv {
#endif
return Provider::open();
return true;
}
void FileProvider::close() {
@@ -319,8 +319,6 @@ namespace hex::plugin::builtin::prv {
::close(this->m_file);
#endif
Provider::close();
}
void FileProvider::loadSettings(const nlohmann::json &settings) {
@@ -336,8 +334,10 @@ namespace hex::plugin::builtin::prv {
}
std::pair<Region, bool> FileProvider::getRegionValidity(u64 address) const {
address -= this->getBaseAddress();
if (address < this->getActualSize())
return { Region { address, this->getActualSize() - address }, true };
return { Region { this->getBaseAddress() + address, this->getActualSize() - address }, true };
else
return { Region::Invalid(), false };
}

View File

@@ -273,7 +273,7 @@ namespace hex::plugin::builtin::prv {
}
});
return Provider::open();
return true;
} else {
return false;
}
@@ -285,8 +285,6 @@ namespace hex::plugin::builtin::prv {
if (this->m_cacheUpdateThread.joinable()) {
this->m_cacheUpdateThread.join();
}
Provider::close();
}
bool GDBProvider::isConnected() const {
@@ -325,8 +323,10 @@ namespace hex::plugin::builtin::prv {
}
std::pair<Region, bool> GDBProvider::getRegionValidity(u64 address) const {
address -= this->getBaseAddress();
if (address < this->getActualSize())
return { Region { address, this->getActualSize() - address }, true };
return { Region { this->getBaseAddress() + address, this->getActualSize() - address }, true };
else
return { Region::Invalid(), false };
}

View File

@@ -153,6 +153,21 @@ namespace hex::plugin::builtin::prv {
}
void IntelHexProvider::setBaseAddress(u64 address) {
auto oldBase = this->getBaseAddress();
auto intervals = this->m_data.findOverlapping(oldBase, oldBase + this->getActualSize());
for (auto &interval : intervals) {
interval.start = (interval.start - oldBase) + address;
interval.stop = (interval.stop - oldBase) + address;
}
this->m_data = std::move(intervals);
Provider::setBaseAddress(address);
}
void IntelHexProvider::readRaw(u64 offset, void *buffer, size_t size) {
auto intervals = this->m_data.findOverlapping(offset, (offset + size) - 1);
@@ -195,12 +210,11 @@ namespace hex::plugin::builtin::prv {
this->m_dataSize = maxAddress + 1;
this->m_dataValid = true;
return Provider::open();
return true;
}
void IntelHexProvider::close() {
Provider::close();
}
[[nodiscard]] std::string IntelHexProvider::getName() const {

View File

@@ -190,11 +190,11 @@ namespace hex::plugin::builtin::prv {
this->m_dataSize = maxAddress + 1;
this->m_dataValid = true;
return Provider::open();
return true;
}
void MotorolaSRECProvider::close() {
Provider::close();
}
[[nodiscard]] std::string MotorolaSRECProvider::getName() const {

View File

@@ -484,7 +484,7 @@ namespace hex::plugin::builtin {
}
// If a custom font has been loaded now, also load the font size
float fontSize = 13.0F * ImHexApi::System::getGlobalScale();
float fontSize = ImHexApi::System::DefaultFontSize * ImHexApi::System::getGlobalScale();
if (!fontFile.empty()) {
ImHexApi::System::impl::setCustomFontPath(fontFile);

View File

@@ -4,11 +4,14 @@
namespace hex::plugin::builtin {
void registerShortcuts() {
// New file
ShortcutManager::addGlobalShortcut(CTRL + Keys::N, [] {
EventManager::post<RequestOpenWindow>("Create File");
});
// Open file
ShortcutManager::addGlobalShortcut(CTRL + Keys::O, [] {
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
EventManager::post<RequestOpenFile>(path);
});
EventManager::post<RequestOpenWindow>("Open File");
});
// Close file

View File

@@ -19,7 +19,7 @@
#include <limits>
#include <llvm/Demangle/Demangle.h>
#include "math_evaluator.hpp"
#include <content/helpers/math_evaluator.hpp>
#include <imgui.h>
#define IMGUI_DEFINE_MATH_OPERATORS
@@ -745,15 +745,15 @@ namespace hex::plugin::builtin {
void drawFileToolShredder() {
static bool shredding = false;
static std::u8string selectedFile;
static bool fastMode = false;
static TaskHolder shredderTask;
ImGui::TextUnformatted("hex.builtin.tools.file_tools.shredder.warning"_lang);
ImGui::NewLine();
if (ImGui::BeginChild("settings", { 0, ImGui::GetTextLineHeightWithSpacing() * 4 }, true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) {
ImGui::BeginDisabled(shredding);
ImGui::BeginDisabled(shredderTask.isRunning());
{
ImGui::TextUnformatted("hex.builtin.tools.file_tools.shredder.input"_lang);
ImGui::SameLine();
@@ -771,17 +771,14 @@ namespace hex::plugin::builtin {
}
ImGui::EndChild();
if (shredding)
if (shredderTask.isRunning())
ImGui::TextSpinner("hex.builtin.tools.file_tools.shredder.shredding"_lang);
else {
ImGui::BeginDisabled(selectedFile.empty());
{
if (ImGui::Button("hex.builtin.tools.file_tools.shredder.shred"_lang)) {
shredding = true;
std::thread([] {
shredderTask = TaskManager::createTask("hex.builtin.tools.file_tools.shredder.shredding", 0, [](auto &task) {
ON_SCOPE_EXIT {
shredding = false;
selectedFile.clear();
};
fs::File file(selectedFile, fs::File::Mode::Write);
@@ -791,6 +788,8 @@ namespace hex::plugin::builtin {
return;
}
task.setMaxValue(file.getSize());
std::vector<std::array<u8, 3>> overwritePattern;
if (fastMode) {
/* Should be sufficient for modern disks */
@@ -803,40 +802,40 @@ namespace hex::plugin::builtin {
/* Fill fixed patterns */
overwritePattern = {
{ },
{ },
{},
{},
{ 0x55, 0x55, 0x55 },
{ 0xAA, 0xAA, 0xAA },
{ 0x92, 0x49, 0x24 },
{ 0x49, 0x24, 0x92 },
{ 0x24, 0x92, 0x49 },
{ 0x00, 0x00, 0x00 },
{ 0x11, 0x11, 0x11 },
{ 0x22, 0x22, 0x22 },
{ 0x33, 0x33, 0x44 },
{ 0x55, 0x55, 0x55 },
{ 0x66, 0x66, 0x66 },
{ 0x77, 0x77, 0x77 },
{ 0x88, 0x88, 0x88 },
{ 0x99, 0x99, 0x99 },
{ 0xAA, 0xAA, 0xAA },
{ 0xBB, 0xBB, 0xBB },
{ 0xCC, 0xCC, 0xCC },
{ 0xDD, 0xDD, 0xDD },
{ 0xEE, 0xEE, 0xEE },
{ 0xFF, 0xFF, 0xFF },
{ 0x92, 0x49, 0x24 },
{ 0x49, 0x24, 0x92 },
{ 0x24, 0x92, 0x49 },
{ 0x6D, 0xB6, 0xDB },
{ 0xB6, 0xDB, 0x6D },
{ 0xBD, 0x6D, 0xB6 },
{},
{},
{},
{}
{ },
{ },
{},
{},
{ 0x55, 0x55, 0x55 },
{ 0xAA, 0xAA, 0xAA },
{ 0x92, 0x49, 0x24 },
{ 0x49, 0x24, 0x92 },
{ 0x24, 0x92, 0x49 },
{ 0x00, 0x00, 0x00 },
{ 0x11, 0x11, 0x11 },
{ 0x22, 0x22, 0x22 },
{ 0x33, 0x33, 0x44 },
{ 0x55, 0x55, 0x55 },
{ 0x66, 0x66, 0x66 },
{ 0x77, 0x77, 0x77 },
{ 0x88, 0x88, 0x88 },
{ 0x99, 0x99, 0x99 },
{ 0xAA, 0xAA, 0xAA },
{ 0xBB, 0xBB, 0xBB },
{ 0xCC, 0xCC, 0xCC },
{ 0xDD, 0xDD, 0xDD },
{ 0xEE, 0xEE, 0xEE },
{ 0xFF, 0xFF, 0xFF },
{ 0x92, 0x49, 0x24 },
{ 0x49, 0x24, 0x92 },
{ 0x24, 0x92, 0x49 },
{ 0x6D, 0xB6, 0xDB },
{ 0xB6, 0xDB, 0x6D },
{ 0xBD, 0x6D, 0xB6 },
{},
{},
{},
{}
};
/* Fill random patterns */
@@ -848,7 +847,6 @@ namespace hex::plugin::builtin {
size_t fileSize = file.getSize();
auto task = ImHexApi::Tasks::createTask("hex.builtin.tools.file_tools.shredder.shredding", fileSize);
for (const auto &pattern : overwritePattern) {
for (u64 offset = 0; offset < fileSize; offset += 3) {
file.write(pattern.data(), std::min<u64>(pattern.size(), fileSize - offset));
@@ -861,7 +859,7 @@ namespace hex::plugin::builtin {
file.remove();
View::showInfoPopup("hex.builtin.tools.file_tools.shredder.success"_lang);
}).detach();
});
}
}
ImGui::EndDisabled();
@@ -890,14 +888,14 @@ namespace hex::plugin::builtin {
1
};
static bool splitting = false;
static std::u8string selectedFile;
static std::u8string baseOutputPath;
static u64 splitSize = sizes[0];
static int selectedItem = 0;
static TaskHolder splitterTask;
if (ImGui::BeginChild("split_settings", { 0, ImGui::GetTextLineHeightWithSpacing() * 7 }, true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) {
ImGui::BeginDisabled(splitting);
ImGui::BeginDisabled(splitterTask.isRunning());
{
ImGui::InputText("##path", selectedFile);
ImGui::SameLine();
@@ -926,7 +924,7 @@ namespace hex::plugin::builtin {
}
}
ImGui::EndDisabled();
ImGui::BeginDisabled(splitting || selectedItem != sizes.size() - 1);
ImGui::BeginDisabled(splitterTask.isRunning() || selectedItem != sizes.size() - 1);
{
ImGui::InputScalar("###custom_size", ImGuiDataType_U64, &splitSize);
ImGui::SameLine();
@@ -938,15 +936,13 @@ namespace hex::plugin::builtin {
ImGui::BeginDisabled(selectedFile.empty() || baseOutputPath.empty() || splitSize == 0);
{
if (splitting)
if (splitterTask.isRunning())
ImGui::TextSpinner("hex.builtin.tools.file_tools.splitter.splitting"_lang);
else {
if (ImGui::Button("hex.builtin.tools.file_tools.splitter.split"_lang)) {
splitting = true;
std::thread([] {
splitterTask = TaskManager::createTask("hex.builtin.tools.file_tools.splitter.splitting", 0, [](auto &task) {
ON_SCOPE_EXIT {
splitting = false;
selectedFile.clear();
baseOutputPath.clear();
};
@@ -962,7 +958,8 @@ namespace hex::plugin::builtin {
return;
}
auto task = ImHexApi::Tasks::createTask("hex.builtin.tools.file_tools.splitter.splitting", file.getSize());
task.setMaxValue(file.getSize());
u32 index = 1;
for (u64 offset = 0; offset < file.getSize(); offset += splitSize) {
task.update(offset);
@@ -977,7 +974,7 @@ namespace hex::plugin::builtin {
return;
}
constexpr auto BufferSize = 0xFF'FFFF;
constexpr static auto BufferSize = 0xFF'FFFF;
for (u64 partOffset = 0; partOffset < splitSize; partOffset += BufferSize) {
partFile.write(file.readBytes(std::min<u64>(BufferSize, splitSize - partOffset)));
partFile.flush();
@@ -987,7 +984,7 @@ namespace hex::plugin::builtin {
}
View::showInfoPopup("hex.builtin.tools.file_tools.splitter.success"_lang);
}).detach();
});
}
}
}
@@ -995,10 +992,10 @@ namespace hex::plugin::builtin {
}
void drawFileToolCombiner() {
static bool combining = false;
static std::vector<std::fs::path> files;
static std::u8string outputPath;
static u32 selectedIndex;
static TaskHolder combinerTask;
if (ImGui::BeginTable("files_table", 2, ImGuiTableFlags_SizingStretchProp)) {
ImGui::TableSetupColumn("file list", ImGuiTableColumnFlags_NoHeaderLabel, 10);
@@ -1041,7 +1038,7 @@ namespace hex::plugin::builtin {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::BeginDisabled(combining);
ImGui::BeginDisabled(combinerTask.isRunning());
{
if (ImGui::Button("hex.builtin.tools.file_tools.combiner.add"_lang)) {
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
@@ -1063,7 +1060,7 @@ namespace hex::plugin::builtin {
ImGui::EndTable();
}
ImGui::BeginDisabled(combining);
ImGui::BeginDisabled(combinerTask.isRunning());
{
ImGui::InputText("##output_path", outputPath);
ImGui::SameLine();
@@ -1079,14 +1076,12 @@ namespace hex::plugin::builtin {
ImGui::BeginDisabled(files.empty() || outputPath.empty());
{
if (combining)
if (combinerTask.isRunning())
ImGui::TextSpinner("hex.builtin.tools.file_tools.combiner.combining"_lang);
else {
if (ImGui::Button("hex.builtin.tools.file_tools.combiner.combine"_lang)) {
combining = true;
std::thread([] {
ON_SCOPE_EXIT { combining = false; };
combinerTask = TaskManager::createTask("hex.builtin.tools.file_tools.combiner.combining", 0, [](auto &task) {
fs::File output(outputPath, fs::File::Mode::Create);
@@ -1095,7 +1090,7 @@ namespace hex::plugin::builtin {
return;
}
auto task = ImHexApi::Tasks::createTask("hex.builtin.tools.file_tools.combiner.combining", files.size());
task.setMaxValue(files.size());
u64 fileIndex = 0;
for (const auto &file : files) {
@@ -1108,7 +1103,7 @@ namespace hex::plugin::builtin {
return;
}
constexpr auto BufferSize = 0xFF'FFFF;
constexpr static auto BufferSize = 0xFF'FFFF;
auto inputSize = input.getSize();
for (u64 inputOffset = 0; inputOffset < inputSize; inputOffset += BufferSize) {
output.write(input.readBytes(std::min<u64>(BufferSize, inputSize - inputOffset)));
@@ -1121,7 +1116,7 @@ namespace hex::plugin::builtin {
outputPath.clear();
View::showInfoPopup("hex.builtin.tools.file_tools.combiner.success"_lang);
}).detach();
});
}
}
}

View File

@@ -153,6 +153,15 @@ namespace hex::plugin::builtin {
ImGui::EndPopup();
}
// Task exception popup
for (const auto &task : TaskManager::getRunningTasks()) {
if (task->hadException()) {
EventManager::post<RequestShowErrorPopup>(hex::format("hex.builtin.popup.error.task_exception"_lang, LangEntry(task->getUnlocalizedName()), task->getExceptionMessage()));
task->clearException();
break;
}
}
}
void addGlobalUIItems() {
@@ -161,19 +170,19 @@ namespace hex::plugin::builtin {
EventManager::subscribe<RequestShowInfoPopup>([](const std::string &message) {
s_popupMessage = message;
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.common.info"_lang); });
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.info"_lang); });
});
EventManager::subscribe<RequestShowErrorPopup>([](const std::string &message) {
s_popupMessage = message;
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.common.error"_lang); });
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.error"_lang); });
});
EventManager::subscribe<RequestShowFatalErrorPopup>([](const std::string &message) {
s_popupMessage = message;
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.common.fatal"_lang); });
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.fatal"_lang); });
});
EventManager::subscribe<RequestShowYesNoQuestionPopup>([](const std::string &message, const std::function<void()> &yesCallback, const std::function<void()> &noCallback) {
@@ -182,7 +191,7 @@ namespace hex::plugin::builtin {
s_yesCallback = yesCallback;
s_noCallback = noCallback;
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.common.question"_lang); });
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.question"_lang); });
});
EventManager::subscribe<RequestShowFileChooserPopup>([](const std::vector<std::fs::path> &paths, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(std::fs::path)> &callback) {
@@ -191,7 +200,7 @@ namespace hex::plugin::builtin {
s_selectableFilesValidExtensions = validExtensions;
s_selectableFileOpenCallback = callback;
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.common.choose_file"_lang); });
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.choose_file"_lang); });
});
}
@@ -203,38 +212,63 @@ namespace hex::plugin::builtin {
});
}
ContentRegistry::Interface::addFooterItem([] {
static float framerate = 0;
if (ImGui::HasSecondPassed()) {
framerate = 1.0F / ImGui::GetIO().DeltaTime;
}
ImGui::TextFormatted("FPS {0:2}.{1:02}", u32(framerate), u32(framerate * 100) % 100);
});
ContentRegistry::Interface::addFooterItem([] {
size_t taskCount = 0;
double taskProgress = 0.0;
std::string taskName;
{
std::scoped_lock lock(Task::getTaskMutex());
taskCount = Task::getRunningTasks().size();
if (taskCount > 0) {
auto frontTask = Task::getRunningTasks().front();
taskProgress = frontTask->getProgress();
taskName = frontTask->getName();
#if defined(DEBUG)
ContentRegistry::Interface::addFooterItem([] {
static float framerate = 0;
if (ImGui::HasSecondPassed()) {
framerate = 1.0F / ImGui::GetIO().DeltaTime;
}
}
ImGui::TextFormatted("FPS {0:2}.{1:02}", u32(framerate), u32(framerate * 100) % 100);
});
#endif
ContentRegistry::Interface::addFooterItem([] {
auto taskCount = TaskManager::getRunningTaskCount();
if (taskCount > 0) {
auto &tasks = TaskManager::getRunningTasks();
auto frontTask = tasks.front();
auto widgetStart = ImGui::GetCursorPos();
ImGui::TextSpinner(hex::format("({})", taskCount).c_str());
ImGui::SameLine();
ImGui::SmallProgressBar(frontTask->getMaxValue() == 0 ? 1 : (float(frontTask->getValue()) / frontTask->getMaxValue()), (ImGui::GetCurrentWindow()->MenuBarHeight() - 10_scaled) / 2.0);
ImGui::SameLine();
auto widgetEnd = ImGui::GetCursorPos();
ImGui::SetCursorPos(widgetStart);
ImGui::InvisibleButton("FrontTask", ImVec2(widgetEnd.x - widgetStart.x, ImGui::GetCurrentWindow()->MenuBarHeight()));
ImGui::SetCursorPos(widgetEnd);
ImGui::InfoTooltip(LangEntry(frontTask->getUnlocalizedName()).get().c_str());
if (ImGui::BeginPopupContextItem("FrontTask", ImGuiPopupFlags_MouseButtonLeft)) {
for (const auto &task : tasks) {
ImGui::PushID(&task);
ImGui::TextFormatted("{}", LangEntry(task->getUnlocalizedName()));
ImGui::SameLine();
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
ImGui::SameLine();
ImGui::SmallProgressBar(frontTask->getMaxValue() == 0 ? 1 : (float(frontTask->getValue()) / frontTask->getMaxValue()), (ImGui::GetTextLineHeightWithSpacing() - 5_scaled) / 2);
ImGui::SameLine();
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
if (ImGui::ToolBarButton(ICON_VS_DEBUG_STOP, ImGui::GetStyleColorVec4(ImGuiCol_Text)))
task->interrupt();
ImGui::PopStyleVar();
ImGui::PopID();
}
ImGui::EndPopup();
}
ImGui::SameLine();
ImGui::SmallProgressBar(taskProgress, (ImGui::GetCurrentWindow()->MenuBarHeight() - 10_scaled) / 2.0);
ImGui::InfoTooltip(taskName.c_str());
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, scaled(ImVec2(1, 2)));
if (ImGui::ToolBarButton(ICON_VS_DEBUG_STOP, ImGui::GetStyleColorVec4(ImGuiCol_Text)))
frontTask->interrupt();
ImGui::PopStyleVar();
}
});
}
@@ -243,7 +277,7 @@ namespace hex::plugin::builtin {
ContentRegistry::Interface::addToolbarItem([] {
auto provider = ImHexApi::Provider::get();
bool providerValid = provider != nullptr;
bool tasksRunning = Task::getRunningTaskCount() > 0;
bool tasksRunning = TaskManager::getRunningTaskCount() > 0;
// Undo
ImGui::BeginDisabled(!providerValid || !provider->canUndo());

View File

@@ -14,7 +14,7 @@ namespace hex::plugin::builtin {
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.help", 1000, [&, this] {
if (ImGui::MenuItem("hex.builtin.view.help.about.name"_lang, "")) {
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.help.about.name").c_str()); });
TaskManager::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.help.about.name").c_str()); });
this->m_aboutWindowOpen = true;
this->getWindowOpenState() = true;
}
@@ -147,7 +147,7 @@ namespace hex::plugin::builtin {
ImGui::TableSetupColumn("Type");
ImGui::TableSetupColumn("Paths");
constexpr std::array<std::pair<const char *, fs::ImHexPath>, 8> PathTypes = {
constexpr static std::array<std::pair<const char *, fs::ImHexPath>, 8> PathTypes = {
{{ "Resources", fs::ImHexPath::Resources },
{ "Config", fs::ImHexPath::Config },
{ "Magic", fs::ImHexPath::Magic },

View File

@@ -325,16 +325,15 @@ namespace hex::plugin::builtin {
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 4000, [&] {
bool providerValid = ImHexApi::Provider::isValid();
auto selection = ImHexApi::HexEditor::getSelection();
if (ImGui::MenuItem("hex.builtin.menu.file.bookmark.import"_lang, nullptr, false, selection.has_value() && providerValid)) {
if (ImGui::MenuItem("hex.builtin.menu.file.bookmark.import"_lang, nullptr, false, providerValid)) {
fs::openFileBrowser(fs::DialogMode::Open, { { "Bookmarks File", "hexbm"} }, [&](const std::fs::path &path) {
try {
importBookmarks(ImHexApi::Provider::get(), nlohmann::json::parse(fs::File(path, fs::File::Mode::Read).readString()));
} catch (...) { }
});
}
if (ImGui::MenuItem("hex.builtin.menu.file.bookmark.export"_lang, nullptr, false, selection.has_value() && providerValid)) {
if (ImGui::MenuItem("hex.builtin.menu.file.bookmark.export"_lang, nullptr, false, providerValid && !ProviderExtraData::getCurrent().bookmarks.empty())) {
fs::openFileBrowser(fs::DialogMode::Save, { { "Bookmarks File", "hexbm"} }, [&](const std::fs::path &path) {
nlohmann::json json;
exportBookmarks(ImHexApi::Provider::get(), json);

View File

@@ -75,7 +75,7 @@ namespace hex::plugin::builtin {
}
std::vector<ViewCommandPalette::CommandResult> ViewCommandPalette::getCommandResults(const std::string &input) {
constexpr auto MatchCommand = [](const std::string &currCommand, const std::string &commandToMatch) -> std::pair<MatchType, std::string_view> {
constexpr static auto MatchCommand = [](const std::string &currCommand, const std::string &commandToMatch) -> std::pair<MatchType, std::string_view> {
if (currCommand.empty()) {
return { MatchType::InfoMatch, "" };
} else if (currCommand.size() <= commandToMatch.size()) {

View File

@@ -34,10 +34,16 @@ namespace hex::plugin::builtin {
this->m_upperCaseHex = static_cast<int>(upperCaseHex);
}
});
EventManager::subscribe<EventProviderClosed>(this, [this](prv::Provider *) {
this->m_providerA = -1;
this->m_providerB = -1;
});
}
ViewDiff::~ViewDiff() {
EventManager::unsubscribe<EventSettingsChanged>(this);
EventManager::unsubscribe<EventProviderClosed>(this);
}
static void drawProviderSelector(int &provider) {

View File

@@ -24,9 +24,8 @@ namespace hex::plugin::builtin {
void ViewDisassembler::disassemble() {
this->m_disassembly.clear();
this->m_disassembling = true;
std::thread([this] {
this->m_disassemblerTask = TaskManager::createTask("hex.builtin.view.disassembler.disassembling", this->m_codeRegion.getSize(), [this](auto &task) {
csh capstoneHandle;
cs_insn *instructions = nullptr;
@@ -40,7 +39,6 @@ namespace hex::plugin::builtin {
std::vector<u8> buffer(2048, 0x00);
size_t size = this->m_codeRegion.getSize();
auto task = ImHexApi::Tasks::createTask("hex.builtin.view.disassembler.disassembling", size);
for (u64 address = 0; address < size; address += 2048) {
task.update(address);
@@ -80,9 +78,7 @@ namespace hex::plugin::builtin {
cs_close(&capstoneHandle);
}
this->m_disassembling = false;
}).detach();
});
}
void ViewDisassembler::drawContent() {
@@ -321,14 +317,14 @@ namespace hex::plugin::builtin {
}
ImGui::EndChild();
ImGui::BeginDisabled(this->m_disassembling);
ImGui::BeginDisabled(this->m_disassemblerTask.isRunning());
{
if (ImGui::Button("hex.builtin.view.disassembler.disassemble"_lang))
this->disassemble();
}
ImGui::EndDisabled();
if (this->m_disassembling) {
if (this->m_disassemblerTask.isRunning()) {
ImGui::SameLine();
ImGui::TextSpinner("hex.builtin.view.disassembler.disassembling"_lang);
}
@@ -345,7 +341,7 @@ namespace hex::plugin::builtin {
ImGui::TableSetupColumn("hex.builtin.view.disassembler.disassembly.bytes"_lang);
ImGui::TableSetupColumn("hex.builtin.view.disassembler.disassembly.title"_lang);
if (!this->m_disassembling) {
if (!this->m_disassemblerTask.isRunning()) {
ImGuiListClipper clipper;
clipper.Begin(this->m_disassembly.size());

View File

@@ -6,7 +6,6 @@
#include <array>
#include <regex>
#include <string>
#include <thread>
#include <utility>
#include <llvm/Demangle/Demangle.h>
@@ -235,6 +234,9 @@ namespace hex::plugin::builtin {
reader.setEndAddress(searchRegion.getEndAddress());
auto sequence = hex::decodeByteString(settings.sequence);
if (sequence.empty())
return { };
auto occurrence = reader.begin();
while (true) {
occurrence = std::search(reader.begin(), reader.end(), std::boyer_moore_horspool_searcher(sequence.begin(), sequence.end()));
@@ -269,8 +271,13 @@ namespace hex::plugin::builtin {
std::string string(occurrence.region.getSize(), '\x00');
provider->read(occurrence.region.getStartAddress(), string.data(), occurrence.region.getSize());
if (std::regex_match(string, regex))
result.push_back(occurrence);
if (settings.fullMatch) {
if (std::regex_match(string, regex))
result.push_back(occurrence);
} else {
if (std::regex_search(string, regex))
result.push_back(occurrence);
}
}
return result;
@@ -319,9 +326,7 @@ namespace hex::plugin::builtin {
}
}();
this->m_searchRunning = true;
std::thread([this, settings = this->m_searchSettings, searchRegion]{
auto task = ImHexApi::Tasks::createTask("hex.builtin.view.find.searching", searchRegion.getSize());
this->m_searchTask = TaskManager::createTask("hex.builtin.view.find.searching", searchRegion.getSize(), [this, settings = this->m_searchSettings, searchRegion](auto &task) {
auto provider = ImHexApi::Provider::get();
switch (settings.mode) {
@@ -338,7 +343,7 @@ namespace hex::plugin::builtin {
case BinaryPattern:
this->m_foundOccurrences[provider] = searchBinaryPattern(task, provider, searchRegion, settings.binaryPattern);
break;
}
}
this->m_sortedOccurrences[provider] = this->m_foundOccurrences[provider];
@@ -346,9 +351,7 @@ namespace hex::plugin::builtin {
for (const auto &occurrence : this->m_foundOccurrences[provider])
intervals.push_back(OccurrenceTree::interval(occurrence.region.getStartAddress(), occurrence.region.getEndAddress(), occurrence));
this->m_occurrenceTree[provider] = std::move(intervals);
this->m_searchRunning = false;
}).detach();
});
}
std::string ViewFind::decodeValue(prv::Provider *provider, Occurrence occurrence) const {
@@ -408,7 +411,7 @@ namespace hex::plugin::builtin {
if (ImGui::Begin(View::toWindowName("hex.builtin.view.find.name").c_str(), &this->getWindowOpenState())) {
auto provider = ImHexApi::Provider::get();
ImGui::BeginDisabled(this->m_searchRunning);
ImGui::BeginDisabled(this->m_searchTask.isRunning());
{
ui::regionSelectionPicker(&this->m_searchSettings.range, true, true);
@@ -466,7 +469,7 @@ namespace hex::plugin::builtin {
ImGui::InputText("hex.builtin.common.value"_lang, settings.sequence);
this->m_settingsValid = !settings.sequence.empty();
this->m_settingsValid = !settings.sequence.empty() && !hex::decodeByteString(settings.sequence).empty();
ImGui::EndTabItem();
}
@@ -475,7 +478,7 @@ namespace hex::plugin::builtin {
mode = SearchSettings::Mode::Regex;
ImGui::InputText("hex.builtin.view.find.regex"_lang, settings.pattern);
ImGui::InputText("hex.builtin.view.find.regex.pattern"_lang, settings.pattern);
try {
std::regex regex(settings.pattern);
@@ -487,6 +490,8 @@ namespace hex::plugin::builtin {
if (settings.pattern.empty())
this->m_settingsValid = false;
ImGui::Checkbox("hex.builtin.view.find.regex.full_match"_lang, &settings.fullMatch);
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.view.find.binary_pattern"_lang)) {
@@ -519,6 +524,16 @@ namespace hex::plugin::builtin {
ImGui::SameLine();
ImGui::TextFormatted("hex.builtin.view.find.search.entries"_lang, this->m_foundOccurrences[provider].size());
ImGui::BeginDisabled(this->m_foundOccurrences[provider].empty());
{
if (ImGui::Button("hex.builtin.view.find.search.reset"_lang)) {
this->m_foundOccurrences[provider].clear();
this->m_sortedOccurrences[provider].clear();
this->m_occurrenceTree[provider].clear();
}
}
ImGui::EndDisabled();
}
ImGui::EndDisabled();
@@ -529,11 +544,11 @@ namespace hex::plugin::builtin {
auto &currOccurrences = this->m_sortedOccurrences[provider];
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputTextWithHint("##filter", "hex.builtin.common.filter"_lang, this->m_currFilter)) {
this->m_sortedOccurrences = this->m_foundOccurrences;
if (ImGui::InputTextWithHint("##filter", "hex.builtin.common.filter"_lang, this->m_currFilter[provider])) {
this->m_sortedOccurrences[provider] = this->m_foundOccurrences[provider];
currOccurrences.erase(std::remove_if(currOccurrences.begin(), currOccurrences.end(), [this, provider](const auto &region) {
return !this->decodeValue(provider, region).contains(this->m_currFilter);
return !this->decodeValue(provider, region).contains(this->m_currFilter[provider]);
}), currOccurrences.end());
}
ImGui::PopItemWidth();

View File

@@ -5,7 +5,7 @@
#include <hex/providers/buffered_reader.hpp>
#include <hex/helpers/crypto.hpp>
#include "math_evaluator.hpp"
#include <content/helpers/math_evaluator.hpp>
#include <imgui_internal.h>
#include <nlohmann/json.hpp>
@@ -143,6 +143,17 @@ namespace hex::plugin::builtin {
class PopupFind : public ViewHexEditor::Popup {
public:
PopupFind() {
EventManager::subscribe<EventRegionSelected>(this, [this](Region region) {
this->m_searchPosition = this->m_nextSearchPosition.value_or(region.getStartAddress());
this->m_nextSearchPosition.reset();
});
}
~PopupFind() override {
EventManager::unsubscribe<EventRegionSelected>(this);
}
void draw(ViewHexEditor *editor) override {
std::vector<u8> searchSequence;
@@ -189,22 +200,34 @@ namespace hex::plugin::builtin {
ImGui::EndTabBar();
}
if (!this->m_searchRunning && !searchSequence.empty() && this->m_shouldSearch) {
this->m_searchRunning = true;
std::thread([this, searchSequence, editor]{
auto task = ImHexApi::Tasks::createTask("Searching", ImHexApi::Provider::get()->getSize());
if (!this->m_searchTask.isRunning() && !searchSequence.empty() && this->m_shouldSearch) {
this->m_searchTask = TaskManager::createTask("hex.builtin.common.processing", ImHexApi::Provider::get()->getActualSize(), [this, editor, searchSequence](auto &) {
for (u8 retry = 0; retry < 2; retry++) {
auto region = this->findSequence(searchSequence, this->m_backwards);
if (auto region = this->findSequence(editor, searchSequence, this->m_backwards); region.has_value()) {
ImHexApi::Tasks::doLater([editor, region]{
editor->setSelection(region->getStartAddress(), region->getEndAddress());
editor->jumpToSelection();
});
if (region.has_value()) {
if (editor->getSelection() == region) {
if (this->m_nextSearchPosition.has_value())
this->m_searchPosition = this->m_nextSearchPosition.value();
this->m_nextSearchPosition.reset();
continue;
} else {
TaskManager::doLater([editor, region]{
editor->setSelection(region->getStartAddress(), region->getEndAddress());
editor->jumpToSelection();
});
break;
}
} else {
this->m_reachedEnd = true;
}
}
this->m_shouldSearch = false;
this->m_requestFocus = true;
this->m_searchRunning = false;
}).detach();
});
}
}
@@ -218,26 +241,40 @@ namespace hex::plugin::builtin {
this->m_requestFocus = false;
}
ImGui::BeginDisabled(this->m_searchRunning);
ImGui::BeginDisabled(this->m_searchTask.isRunning());
{
ImGui::SameLine();
if (ImGui::IconButton(ICON_VS_SEARCH "##search", ButtonColor, ButtonSize)) {
this->m_shouldSearch = true;
this->m_backwards = false;
this->m_reachedEnd = false;
this->m_searchPosition.reset();
this->m_nextSearchPosition.reset();
}
ImGui::BeginDisabled(!this->m_searchPosition.has_value());
{
if (ImGui::IconButton(ICON_VS_ARROW_UP "##up", ButtonColor, ButtonSize)) {
this->m_shouldSearch = true;
this->m_backwards = true;
ImGui::BeginDisabled(this->m_reachedEnd && this->m_backwards);
{
if (ImGui::IconButton(ICON_VS_ARROW_UP "##up", ButtonColor, ButtonSize)) {
this->m_shouldSearch = true;
this->m_backwards = true;
this->m_reachedEnd = false;
}
}
ImGui::EndDisabled();
ImGui::SameLine();
if (ImGui::IconButton(ICON_VS_ARROW_DOWN "##down", ButtonColor, ButtonSize)) {
this->m_shouldSearch = true;
this->m_backwards = false;
ImGui::BeginDisabled(this->m_reachedEnd && !this->m_backwards);
{
if (ImGui::IconButton(ICON_VS_ARROW_DOWN "##down", ButtonColor, ButtonSize)) {
this->m_shouldSearch = true;
this->m_backwards = false;
this->m_reachedEnd = false;
}
}
ImGui::EndDisabled();
}
ImGui::EndDisabled();
@@ -245,13 +282,10 @@ namespace hex::plugin::builtin {
ImGui::EndDisabled();
}
std::optional<Region> findSequence(ViewHexEditor *editor, const std::vector<u8> &sequence, bool backwards) {
std::optional<Region> findSequence(const std::vector<u8> &sequence, bool backwards) {
hex::prv::BufferedReader reader(ImHexApi::Provider::get());
if (!editor->isSelectionValid())
reader.seek(this->m_searchPosition.value_or(0x00));
else
reader.seek(this->m_searchPosition.value_or(editor->getSelection().getStartAddress()));
reader.seek(this->m_searchPosition.value_or(0x00));
constexpr static auto searchFunction = [](const auto &haystackBegin, const auto &haystackEnd, const auto &needleBegin, const auto &needleEnd) {
return std::search(haystackBegin, haystackEnd, std::boyer_moore_horspool_searcher(needleBegin, needleEnd));
@@ -260,18 +294,18 @@ namespace hex::plugin::builtin {
if (!backwards) {
auto occurrence = searchFunction(reader.begin(), reader.end(), sequence.begin(), sequence.end());
if (occurrence != reader.end()) {
this->m_searchPosition = occurrence.getAddress() + sequence.size();
this->m_nextSearchPosition = occurrence.getAddress() + sequence.size();
return Region { occurrence.getAddress(), sequence.size() };
}
} else {
auto occurrence = searchFunction(reader.rbegin(), reader.rend(), sequence.begin(), sequence.end());
auto occurrence = searchFunction(reader.rbegin(), reader.rend(), sequence.rbegin(), sequence.rend());
if (occurrence != reader.rend()) {
if (occurrence.getAddress() < sequence.size())
this->m_searchPosition = 0x00;
this->m_nextSearchPosition = 0x00;
else
this->m_searchPosition = occurrence.getAddress() - sequence.size();
this->m_nextSearchPosition = occurrence.getAddress() - sequence.size();
return Region { occurrence.getAddress(), sequence.size() };
return Region { occurrence.getAddress() - (sequence.size() - 1), sequence.size() };
}
}
@@ -279,13 +313,14 @@ namespace hex::plugin::builtin {
}
std::string m_input;
std::optional<u64> m_searchPosition;
std::optional<u64> m_searchPosition, m_nextSearchPosition;
bool m_requestFocus = true;
std::atomic<bool> m_shouldSearch = false;
std::atomic<bool> m_backwards = false;
std::atomic<bool> m_reachedEnd = false;
std::atomic<bool> m_searchRunning = false;
TaskHolder m_searchTask;
};
class PopupBaseAddress : public ViewHexEditor::Popup {
@@ -967,14 +1002,14 @@ namespace hex::plugin::builtin {
if ((ImGui::IsMouseDown(ImGuiMouseButton_Left) && this->m_selectionStart != this->m_selectionEnd)) {
auto fractionPerLine = 1.0 / (this->m_visibleRowCount + 1);
if (y == u64(clipper.DisplayStart + 2)) {
if (i128(this->m_selectionEnd - provider->getBaseAddress() - provider->getCurrentPageAddress()) <= (i64(clipper.DisplayStart + 2) * this->m_bytesPerRow)) {
if (y == u64(clipper.DisplayStart + 3)) {
if (i128(this->m_selectionEnd - provider->getBaseAddress() - provider->getCurrentPageAddress()) <= (i64(clipper.DisplayStart + 3) * this->m_bytesPerRow)) {
this->m_shouldScrollToSelection = false;
ImGui::SetScrollHereY(fractionPerLine * 4);
ImGui::SetScrollHereY(fractionPerLine * 5);
}
} else if (y == u64(clipper.DisplayEnd - 2)) {
if (i128(this->m_selectionEnd - provider->getBaseAddress() - provider->getCurrentPageAddress()) >= (i64(clipper.DisplayEnd - 2) * this->m_bytesPerRow)) {
} else if (y == u64(clipper.DisplayEnd - 3)) {
if (i128(this->m_selectionEnd - provider->getBaseAddress() - provider->getCurrentPageAddress()) >= (i64(clipper.DisplayEnd - 3) * this->m_bytesPerRow)) {
this->m_shouldScrollToSelection = false;
ImGui::SetScrollHereY(fractionPerLine * (this->m_visibleRowCount - 1));
}
@@ -1117,7 +1152,7 @@ namespace hex::plugin::builtin {
void ViewHexEditor::drawContent() {
if (ImGui::Begin(View::toWindowName(this->getUnlocalizedName()).c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) {
const auto FooterSize = ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetTextLineHeightWithSpacing() * 3);
const auto FooterSize = ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetTextLineHeightWithSpacing() * 2.3);
const auto TableSize = ImGui::GetContentRegionAvail() - ImVec2(0, FooterSize.y);
this->drawPopup();
@@ -1140,17 +1175,22 @@ namespace hex::plugin::builtin {
}
static void copyBytes(const Region &selection) {
constexpr static auto Format = "{0:02X} ";
auto provider = ImHexApi::Provider::get();
std::vector<u8> buffer(selection.size, 0x00);
provider->read(selection.getStartAddress() + provider->getBaseAddress() + provider->getCurrentPageAddress(), buffer.data(), buffer.size());
auto reader = prv::BufferedReader(provider);
reader.seek(selection.getStartAddress() + provider->getBaseAddress() + provider->getCurrentPageAddress());
reader.setEndAddress(selection.getEndAddress() + provider->getBaseAddress() + provider->getCurrentPageAddress());
std::string str;
for (const auto &byte : buffer)
str += hex::format("{0:02X} ", byte);
str.pop_back();
std::string result;
result.reserve(fmt::format(Format, 0x00).size() * selection.getSize());
ImGui::SetClipboardText(str.c_str());
for (const auto &byte : reader)
result += fmt::format(Format, byte);
result.pop_back();
ImGui::SetClipboardText(result.c_str());
}
static void pasteBytes(const Region &selection) {
@@ -1349,6 +1389,12 @@ namespace hex::plugin::builtin {
});
EventManager::subscribe<RequestSelectionChange>(this, [this](Region region) {
if (region == Region::Invalid()) {
this->m_selectionStart = InvalidSelection;
this->m_selectionEnd = InvalidSelection;
return;
}
auto provider = ImHexApi::Provider::get();
auto page = provider->getPageOfAddress(region.getStartAddress());
@@ -1485,6 +1531,8 @@ namespace hex::plugin::builtin {
if (ImGui::BeginMenu("hex.builtin.view.hex_editor.menu.edit.copy_as"_lang, selection.has_value() && providerValid)) {
if (ImGui::MenuItem("hex.builtin.view.hex_editor.copy.hex"_lang, "CTRL + SHIFT + C"))
copyString(*selection);
if (ImGui::MenuItem("hex.builtin.view.hex_editor.copy.address"_lang))
ImGui::SetClipboardText(hex::format("0x{:08X}", selection->getStartAddress()).c_str());
ImGui::Separator();
@@ -1528,7 +1576,8 @@ namespace hex::plugin::builtin {
}
if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.remove"_lang, nullptr, false, providerValid && provider->isResizable())) {
this->openPopup<PopupRemove>(this->getSelection().getStartAddress(), 0x00);
auto selection = this->getSelection();
this->openPopup<PopupRemove>(selection.getStartAddress(), selection.getSize());
}
});
}

View File

@@ -4,20 +4,15 @@
#include <hex/providers/provider.hpp>
#include <hex/providers/buffered_reader.hpp>
#include <hex/helpers/fs.hpp>
#include <hex/helpers/fmt.hpp>
#include <hex/helpers/literals.hpp>
#include <hex/helpers/magic.hpp>
#include <cstring>
#include <cmath>
#include <cinttypes>
#include <filesystem>
#include <numeric>
#include <span>
#include <thread>
#include <vector>
#include <hex/helpers/magic.hpp>
#include <implot.h>
@@ -80,12 +75,10 @@ namespace hex::plugin::builtin {
}
void ViewInformation::analyze() {
this->m_analyzing = true;
std::thread([this] {
this->m_analyzerTask = TaskManager::createTask("hex.builtin.view.information.analyzing", 0, [this](auto &task) {
auto provider = ImHexApi::Provider::get();
auto task = ImHexApi::Tasks::createTask("hex.builtin.view.information.analyzing", provider->getActualSize());
task.setMaxValue(provider->getActualSize());
this->m_analyzedRegion = { provider->getBaseAddress(), provider->getBaseAddress() + provider->getSize() };
@@ -127,9 +120,7 @@ namespace hex::plugin::builtin {
else
this->m_highestBlockEntropy = 0;
}
this->m_analyzing = false;
}).detach();
});
}
void ViewInformation::drawContent() {
@@ -138,14 +129,14 @@ namespace hex::plugin::builtin {
auto provider = ImHexApi::Provider::get();
if (ImHexApi::Provider::isValid() && provider->isReadable()) {
ImGui::BeginDisabled(this->m_analyzing);
ImGui::BeginDisabled(this->m_analyzerTask.isRunning());
{
if (ImGui::Button("hex.builtin.view.information.analyze"_lang, ImVec2(ImGui::GetContentRegionAvail().x, 0)))
this->analyze();
}
ImGui::EndDisabled();
if (this->m_analyzing) {
if (this->m_analyzerTask.isRunning()) {
ImGui::TextSpinner("hex.builtin.view.information.analyzing"_lang);
} else {
ImGui::NewLine();

View File

@@ -2,7 +2,6 @@
#include <hex/providers/provider.hpp>
#include <pl/pattern_language.hpp>
#include <pl/patterns/pattern.hpp>
#include <provider_extra_data.hpp>
@@ -72,12 +71,12 @@ namespace hex::plugin::builtin {
static bool beginPatternTable(prv::Provider *&provider, const std::vector<std::shared_ptr<pl::ptrn::Pattern>> &patterns, std::vector<pl::ptrn::Pattern*> &sortedPatterns) {
if (ImGui::BeginTable("##Patterntable", 6, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) {
ImGui::TableSetupScrollFreeze(0, 1);
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.var_name"_lang, 0, 0, ImGui::GetID("name"));
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.color"_lang, 0, 0, ImGui::GetID("color"));
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.offset"_lang, 0, 0, ImGui::GetID("offset"));
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.size"_lang, 0, 0, ImGui::GetID("size"));
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.type"_lang, 0, 0, ImGui::GetID("type"));
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.value"_lang, 0, 0, ImGui::GetID("value"));
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.var_name"_lang, ImGuiTableColumnFlags_PreferSortAscending, 0, ImGui::GetID("name"));
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.color"_lang, ImGuiTableColumnFlags_PreferSortAscending, 0, ImGui::GetID("color"));
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.offset"_lang, ImGuiTableColumnFlags_PreferSortAscending | ImGuiTableColumnFlags_DefaultSort, 0, ImGui::GetID("offset"));
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.size"_lang, ImGuiTableColumnFlags_PreferSortAscending, 0, ImGui::GetID("size"));
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.type"_lang, ImGuiTableColumnFlags_PreferSortAscending, 0, ImGui::GetID("type"));
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.value"_lang, ImGuiTableColumnFlags_PreferSortAscending, 0, ImGui::GetID("value"));
auto sortSpecs = ImGui::TableGetSortSpecs();
@@ -108,10 +107,10 @@ namespace hex::plugin::builtin {
void ViewPatternData::drawContent() {
if (ImGui::Begin(View::toWindowName("hex.builtin.view.pattern_data.name").c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) {
auto provider = ImHexApi::Provider::get();
if (ImHexApi::Provider::isValid() && provider->isReadable()) {
if (ImHexApi::Provider::isValid() && provider->isReadable() && !ProviderExtraData::get(provider).patternLanguage.runtime->isRunning()) {
auto &sortedPatterns = this->m_sortedPatterns[ImHexApi::Provider::get()];
if (beginPatternTable(provider, ProviderExtraData::get(provider).patternLanguage.runtime->getPatterns(), sortedPatterns)) {
if (beginPatternTable(provider, ProviderExtraData::get(provider).patternLanguage.runtime->getAllPatterns(), sortedPatterns)) {
ImGui::TableHeadersRow();
if (!sortedPatterns.empty()) {
@@ -126,4 +125,4 @@ namespace hex::plugin::builtin {
ImGui::End();
}
}
}

View File

@@ -26,13 +26,13 @@ namespace hex::plugin::builtin {
static bool initialized = false;
static TextEditor::LanguageDefinition langDef;
if (!initialized) {
static constexpr std::array keywords = {
"using", "struct", "union", "enum", "bitfield", "be", "le", "if", "else", "false", "true", "this", "parent", "addressof", "sizeof", "$", "while", "for", "fn", "return", "break", "continue", "namespace", "in", "out"
constexpr static std::array keywords = {
"using", "struct", "union", "enum", "bitfield", "be", "le", "if", "else", "false", "true", "this", "parent", "addressof", "sizeof", "$", "while", "for", "fn", "return", "break", "continue", "namespace", "in", "out", "ref"
};
for (auto &k : keywords)
langDef.mKeywords.insert(k);
static constexpr std::array builtInTypes = {
constexpr static std::array builtInTypes = {
"u8", "u16", "u24", "u32", "u48", "u64", "u96", "u128", "s8", "s16", "s24", "s32", "s48", "s64", "s96", "s128", "float", "double", "char", "char16", "bool", "padding", "str", "auto"
};
for (const auto name : builtInTypes) {
@@ -80,7 +80,8 @@ namespace hex::plugin::builtin {
ViewPatternEditor::ViewPatternEditor() : View("hex.builtin.view.pattern_editor.name") {
this->m_parserRuntime = ContentRegistry::PatternLanguage::createDefaultRuntime(nullptr);
this->m_parserRuntime = std::make_unique<pl::PatternLanguage>();
ContentRegistry::PatternLanguage::configureRuntime(*this->m_parserRuntime, nullptr);
this->m_textEditor.SetLanguageDefinition(PatternLanguage());
this->m_textEditor.SetShowWhitespaces(false);
@@ -110,7 +111,8 @@ namespace hex::plugin::builtin {
EventManager::subscribe<EventProviderOpened>(this, [this](prv::Provider *provider) {
auto &patternLanguageData = ProviderExtraData::get(provider).patternLanguage;
patternLanguageData.runtime = ContentRegistry::PatternLanguage::createDefaultRuntime(provider);
patternLanguageData.runtime = std::make_unique<pl::PatternLanguage>();
ContentRegistry::PatternLanguage::configureRuntime(*patternLanguageData.runtime, provider);
if (!this->m_autoLoadPatterns)
return;
@@ -253,7 +255,7 @@ namespace hex::plugin::builtin {
return std::nullopt;
std::optional<ImColor> color;
for (const auto &pattern : ProviderExtraData::getCurrent().patternLanguage.runtime->getPatterns(address)) {
for (const auto &pattern : ProviderExtraData::getCurrent().patternLanguage.runtime->getPatternsAtAddress(address)) {
if (pattern->isHidden())
continue;
@@ -269,7 +271,7 @@ namespace hex::plugin::builtin {
ImHexApi::HexEditor::addTooltipProvider([this](u64 address, const u8 *data, size_t size) {
hex::unused(data, size);
auto patterns = ProviderExtraData::getCurrent().patternLanguage.runtime->getPatterns(address);
auto patterns = ProviderExtraData::getCurrent().patternLanguage.runtime->getPatternsAtAddress(address);
if (!patterns.empty() && !std::all_of(patterns.begin(), patterns.end(), [](const auto &pattern) { return pattern->isHidden(); })) {
ImGui::BeginTooltip();
for (const auto &pattern : patterns) {
@@ -290,6 +292,7 @@ namespace hex::plugin::builtin {
ImGui::PopStyleColor(2);
}
ImGui::PopID();
}
ImGui::EndTooltip();
}
@@ -303,7 +306,8 @@ namespace hex::plugin::builtin {
if (!this->m_syncPatternSourceCode)
ProviderExtraData::get(provider).patternLanguage.sourceCode = sourceCode;
this->m_textEditor.SetText(sourceCode);
if (provider == ImHexApi::Provider::get())
this->m_textEditor.SetText(sourceCode);
return true;
},
@@ -416,6 +420,7 @@ namespace hex::plugin::builtin {
if (this->m_dangerousFunctionCalled && !ImGui::IsPopupOpen(View::toWindowName("hex.builtin.view.pattern_editor.dangerous_function.name").c_str())) {
ImGui::OpenPopup(View::toWindowName("hex.builtin.view.pattern_editor.dangerous_function.name").c_str());
this->m_dangerousFunctionCalled = false;
}
if (ImGui::BeginPopupModal(View::toWindowName("hex.builtin.view.pattern_editor.dangerous_function.name").c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
@@ -522,7 +527,7 @@ namespace hex::plugin::builtin {
ON_SCOPE_EXIT { ImGui::PopID(); };
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
constexpr const char *Types[] = { "I", "F", "S", "B" };
constexpr static const char *Types[] = { "I", "F", "S", "B" };
if (ImGui::BeginCombo("", Types[static_cast<int>(type)])) {
for (auto i = 0; i < IM_ARRAYSIZE(Types); i++) {
if (ImGui::Selectable(Types[i]))
@@ -702,51 +707,51 @@ namespace hex::plugin::builtin {
{
ImGui::ColorButton(pattern->getVariableName().c_str(), ImColor(pattern->getColor()));
ImGui::SameLine(0, 10);
ImGui::TextFormattedColored(ImColor(0xFF9BC64D), "{}", pattern->getFormattedName());
ImGui::TextFormattedColored(ImColor(0xFF9BC64D), "{} ", pattern->getFormattedName());
ImGui::SameLine(0, 5);
ImGui::TextFormatted("{}", pattern->getDisplayName());
ImGui::SameLine();
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
ImGui::SameLine();
ImGui::TextFormatted("{}", pattern->getFormattedValue());
ImGui::TextFormatted("{} ", pattern->getFormattedValue());
if (ImGui::GetIO().KeyShift) {
ImGui::Indent();
if (ImGui::BeginTable("##extra_info", 2, ImGuiTableFlags_RowBg | ImGuiTableFlags_NoClip)) {
if (ImGui::BeginTable("##extra_info", 2, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_NoClip)) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextFormatted("{}: ", "hex.builtin.common.type"_lang);
ImGui::TextFormatted("{} ", "hex.builtin.common.type"_lang);
ImGui::TableNextColumn();
ImGui::TextFormatted("{}", pattern->getTypeName());
ImGui::TextFormatted(" {}", pattern->getTypeName());
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextFormatted("{}: ", "hex.builtin.common.address"_lang);
ImGui::TextFormatted("{} ", "hex.builtin.common.address"_lang);
ImGui::TableNextColumn();
ImGui::TextFormatted("0x{:08X}", pattern->getOffset());
ImGui::TextFormatted(" 0x{:08X}", pattern->getOffset());
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextFormatted("{}: ", "hex.builtin.common.size"_lang);
ImGui::TextFormatted("{} ", "hex.builtin.common.size"_lang);
ImGui::TableNextColumn();
ImGui::TextFormatted("{}", hex::toByteString(pattern->getSize()));
ImGui::TextFormatted(" {}", hex::toByteString(pattern->getSize()));
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextFormatted("{}: ", "hex.builtin.common.endian"_lang);
ImGui::TextFormatted("{} ", "hex.builtin.common.endian"_lang);
ImGui::TableNextColumn();
ImGui::TextFormatted("{}", pattern->getEndian() == std::endian::little ? "hex.builtin.common.little"_lang : "hex.builtin.common.big"_lang);
ImGui::TextFormatted(" {}", pattern->getEndian() == std::endian::little ? "hex.builtin.common.little"_lang : "hex.builtin.common.big"_lang);
if (const auto &comment = pattern->getComment(); comment.has_value()) {
if (const auto &comment = pattern->getComment(); comment != nullptr) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextFormatted("{}: ", "hex.builtin.common.comment"_lang);
ImGui::TextFormatted("{} ", "hex.builtin.common.comment"_lang);
ImGui::TableNextColumn();
ImGui::TextWrapped("\"%s\"", pattern->getComment()->c_str());
ImGui::TextWrapped(" \"%s\"", comment->c_str());
}
ImGui::EndTable();
@@ -773,6 +778,7 @@ namespace hex::plugin::builtin {
void ViewPatternEditor::parsePattern(const std::string &code) {
this->m_runningParsers++;
ContentRegistry::PatternLanguage::configureRuntime(*this->m_parserRuntime, nullptr);
auto ast = this->m_parserRuntime->parseString(code);
this->m_patternVariables.clear();
@@ -810,14 +816,15 @@ namespace hex::plugin::builtin {
this->m_textEditor.SetErrorMarkers({});
this->m_console.clear();
auto &runtime = ProviderExtraData::getCurrent().patternLanguage.runtime;
runtime->reset();
auto provider = ImHexApi::Provider::get();
auto &runtime = ProviderExtraData::get(provider).patternLanguage.runtime;
ContentRegistry::PatternLanguage::configureRuntime(*runtime, provider);
EventManager::post<EventHighlightingChanged>();
std::thread([this, code, &runtime] {
auto task = ImHexApi::Tasks::createTask("hex.builtin.view.pattern_editor.evaluating", 1);
TaskManager::createTask("hex.builtin.view.pattern_editor.evaluating", TaskManager::NoProgress, [this, &runtime, code](auto &task) {
task.setInterruptCallback([&runtime] { runtime->abort(); });
std::map<std::string, pl::core::Token::Literal> envVars;
for (const auto &[id, name, value, type] : this->m_envVarEntries)
@@ -844,14 +851,12 @@ namespace hex::plugin::builtin {
this->m_lastEvaluationError = runtime->getError();
}
runtime->flattenPatterns();
this->m_lastEvaluationLog = runtime->getConsoleLog();
this->m_lastEvaluationOutVars = runtime->getOutVariables();
this->m_runningEvaluators--;
this->m_lastEvaluationProcessed = false;
}).detach();
});
}
}

View File

@@ -36,6 +36,7 @@ namespace hex::plugin::builtin {
if (ImGui::Button("hex.builtin.common.open"_lang)) {
if (provider->open()) {
EventManager::post<EventProviderOpened>(provider);
ImGui::CloseCurrentPopup();
}
else {

View File

@@ -11,14 +11,16 @@ namespace hex::plugin::builtin {
ViewSettings::ViewSettings() : View("hex.builtin.view.settings.name") {
EventManager::subscribe<RequestOpenWindow>(this, [this](const std::string &name) {
if (name == "Settings") {
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.settings.name").c_str()); });
this->getWindowOpenState() = true;
TaskManager::doLater([this] {
ImGui::OpenPopup(View::toWindowName("hex.builtin.view.settings.name").c_str());
this->getWindowOpenState() = true;
});
}
});
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.help", 2000, [&, this] {
if (ImGui::MenuItem("hex.builtin.view.settings.name"_lang)) {
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.settings.name").c_str()); });
TaskManager::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.settings.name").c_str()); });
this->getWindowOpenState() = true;
}
});

View File

@@ -29,7 +29,7 @@ namespace hex::plugin::builtin {
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.help", 3000, [&, this] {
if (ImGui::MenuItem("hex.builtin.view.store.name"_lang)) {
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.store.name").c_str()); });
TaskManager::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.store.name").c_str()); });
this->getWindowOpenState() = true;
}
});

View File

@@ -44,7 +44,7 @@ namespace hex::plugin::builtin {
if (ImGui::Button("hex.builtin.view.yara.reload"_lang)) this->reloadRules();
} else {
ImGui::BeginDisabled(this->m_matching);
ImGui::BeginDisabled(this->m_matcherTask.isRunning());
{
if (ImGui::BeginCombo("hex.builtin.view.yara.header.rules"_lang, this->m_rules[this->m_selectedRule].first.string().c_str())) {
for (u32 i = 0; i < this->m_rules.size(); i++) {
@@ -63,7 +63,7 @@ namespace hex::plugin::builtin {
}
ImGui::EndDisabled();
if (this->m_matching) {
if (this->m_matcherTask.isRunning()) {
ImGui::SameLine();
ImGui::TextSpinner("hex.builtin.view.yara.matching"_lang);
}
@@ -86,7 +86,7 @@ namespace hex::plugin::builtin {
ImGui::TableHeadersRow();
if (!this->m_matching) {
if (!this->m_matcherTask.isRunning()) {
ImGuiListClipper clipper;
clipper.Begin(this->m_matches.size());
@@ -173,19 +173,13 @@ namespace hex::plugin::builtin {
void ViewYara::applyRules() {
this->clearResult();
this->m_matching = true;
std::thread([this] {
this->m_matcherTask = TaskManager::createTask("hex.builtin.view.yara.matching", 0, [this](auto &task) {
if (!ImHexApi::Provider::isValid()) return;
auto provider = ImHexApi::Provider::get();
auto task = ImHexApi::Tasks::createTask("hex.builtin.view.yara.matching", provider->getActualSize());
YR_COMPILER *compiler = nullptr;
yr_compiler_create(&compiler);
ON_SCOPE_EXIT {
yr_compiler_destroy(compiler);
this->m_matching = false;
};
yr_compiler_set_include_callback(
@@ -209,8 +203,8 @@ namespace hex::plugin::builtin {
delete[] ptr;
},
fs::toShortPath(this->m_rules[this->m_selectedRule].second).string().data());
fs::toShortPath(this->m_rules[this->m_selectedRule].second).string().data()
);
fs::File file(this->m_rules[this->m_selectedRule].second, fs::File::Mode::Read);
if (!file.isValid()) return;
@@ -220,7 +214,7 @@ namespace hex::plugin::builtin {
yr_compiler_get_error_message(compiler, errorMessage.data(), errorMessage.size());
hex::trim(errorMessage);
ImHexApi::Tasks::doLater([this, errorMessage] {
TaskManager::doLater([this, errorMessage] {
this->clearResult();
this->m_consoleMessages.push_back("Error: " + errorMessage);
@@ -246,15 +240,14 @@ namespace hex::plugin::builtin {
context.currBlock.base = 0;
context.currBlock.fetch_data = [](auto *block) -> const u8 * {
auto &context = *static_cast<ScanContext *>(block->context);
auto provider = ImHexApi::Provider::get();
context.buffer.resize(context.currBlock.size);
if (context.buffer.empty()) return nullptr;
if (context.buffer.empty())
return nullptr;
block->size = context.currBlock.size;
provider->read(context.currBlock.base + provider->getBaseAddress(), context.buffer.data(), context.buffer.size());
return context.buffer.data();
@@ -301,11 +294,11 @@ namespace hex::plugin::builtin {
ResultContext resultContext;
yr_rules_scan_mem_blocks(
rules, &iterator, 0, [](YR_SCAN_CONTEXT *context, int message, void *data, void *userData) -> int {
auto &results = *static_cast<ResultContext *>(userData);
rules, &iterator, 0, [](YR_SCAN_CONTEXT *context, int message, void *data, void *userData) -> int {
auto &results = *static_cast<ResultContext *>(userData);
switch (message) {
case CALLBACK_MSG_RULE_MATCHING:
switch (message) {
case CALLBACK_MSG_RULE_MATCHING:
{
auto rule = static_cast<YR_RULE *>(data);
@@ -315,30 +308,30 @@ namespace hex::plugin::builtin {
if (rule->strings != nullptr) {
yr_rule_strings_foreach(rule, string) {
yr_string_matches_foreach(context, string, match) {
results.newMatches.push_back({ rule->identifier, string->identifier, u64(match->offset), size_t(match->match_length), false, 0, 0 });
}
results.newMatches.push_back({ rule->identifier, string->identifier, u64(match->offset), size_t(match->match_length), false, 0, 0 });
}
}
} else {
results.newMatches.push_back({ rule->identifier, "", 0, 0, true, 0, 0 });
}
}
break;
case CALLBACK_MSG_CONSOLE_LOG:
break;
case CALLBACK_MSG_CONSOLE_LOG:
{
results.consoleMessages.emplace_back(static_cast<const char *>(data));
}
break;
default:
break;
}
break;
default:
break;
}
return CALLBACK_CONTINUE;
},
&resultContext,
0);
return CALLBACK_CONTINUE;
},
&resultContext,
0);
ImHexApi::Tasks::doLater([this, resultContext] {
TaskManager::doLater([this, resultContext] {
this->m_matches = resultContext.newMatches;
this->m_consoleMessages = resultContext.consoleMessages;
@@ -348,7 +341,7 @@ namespace hex::plugin::builtin {
match.tooltipId = ImHexApi::HexEditor::addTooltip({ match. address, match.size }, hex::format("{0} [{1}]", match.identifier, match.variable), YaraColor);
}
});
}).detach();
});
}
}

View File

@@ -19,7 +19,9 @@
#include <fonts/codicons_font.h>
#include <string>
#include <list>
#include <unordered_set>
namespace hex::plugin::builtin {
@@ -37,43 +39,53 @@ namespace hex::plugin::builtin {
nlohmann::json data;
bool operator==(const RecentProvider &other) const {
return displayName == other.displayName && type == other.type && data == other.data;
return HashFunction()(*this) == HashFunction()(other);
}
struct HashFunction {
std::size_t operator()(const RecentProvider& provider) const {
return
(std::hash<std::string>()(provider.displayName)) ^
(std::hash<std::string>()(provider.type) << 1);
}
};
};
static std::vector<RecentProvider> s_recentProviders;
static std::list<RecentProvider> s_recentProviders;
static void updateRecentProviders() {
s_recentProviders.clear();
// Query all recent providers
std::vector<std::fs::path> recentFiles;
std::vector<std::fs::path> recentFilePaths;
for (const auto &folder : fs::getDefaultPaths(fs::ImHexPath::Recent)) {
for (const auto &entry : std::fs::directory_iterator(folder)) {
if (entry.is_regular_file())
recentFiles.push_back(entry.path());
recentFilePaths.push_back(entry.path());
}
}
// Sort recent provider files by last modified time
std::sort(recentFiles.begin(), recentFiles.end(), [](const auto &a, const auto &b) {
std::sort(recentFilePaths.begin(), recentFilePaths.end(), [](const auto &a, const auto &b) {
return std::fs::last_write_time(a) > std::fs::last_write_time(b);
});
for (u32 i = 0; i < recentFiles.size() && s_recentProviders.size() < 5; i++) {
auto &path = recentFiles[i];
std::unordered_set<RecentProvider, RecentProvider::HashFunction> uniqueProviders;
for (u32 i = 0; i < recentFilePaths.size() && uniqueProviders.size() < 5; i++) {
auto &path = recentFilePaths[i];
try {
auto jsonData = nlohmann::json::parse(fs::File(path, fs::File::Mode::Read).readString());
s_recentProviders.push_back(RecentProvider {
.displayName = jsonData["displayName"],
.type = jsonData["type"],
.filePath = path,
.data = jsonData
uniqueProviders.insert(RecentProvider {
.displayName = jsonData["displayName"],
.type = jsonData["type"],
.filePath = path,
.data = jsonData
});
} catch (...) { }
}
// De-duplicate recent providers
s_recentProviders.erase(std::unique(s_recentProviders.begin(), s_recentProviders.end()), s_recentProviders.end());
std::copy(uniqueProviders.begin(), uniqueProviders.end(), std::front_inserter(s_recentProviders));
}
static void loadRecentProvider(const RecentProvider &recentProvider) {
@@ -83,13 +95,14 @@ namespace hex::plugin::builtin {
if (!provider->open() || !provider->isAvailable()) {
View::showErrorPopup("hex.builtin.popup.error.open"_lang);
ImHexApi::Tasks::doLater([provider] { ImHexApi::Provider::remove(provider); });
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); });
return;
}
EventManager::post<EventProviderOpened>(provider);
updateRecentProviders();
}
}
static void loadDefaultLayout() {
@@ -325,11 +338,12 @@ namespace hex::plugin::builtin {
ImGui::EndTable();
}
ImGui::SetCursorPos(ImVec2(ImGui::GetWindowSize().x - ImGui::CalcTextSize("X").x * 2, 0));
ImGui::SetCursorPos(ImVec2(ImGui::GetContentRegionAvail().x, 0));
if (ImGui::Hyperlink("X")) {
auto provider = ImHexApi::Provider::createProvider("hex.builtin.provider.null");
if (provider != nullptr)
(void)provider->open();
if (provider->open())
EventManager::post<EventProviderOpened>(provider);
}
}
@@ -355,8 +369,6 @@ namespace hex::plugin::builtin {
}
static void drawNoViewsBackground() {
if (isAnyViewOpen() && ImHexApi::Provider::isValid()) return;
if (ImGui::Begin("ImHexDockSpace")) {
static char title[256];
ImFormatString(title, IM_ARRAYSIZE(title), "%s/DockSpace_%08X", ImGui::GetCurrentWindow()->Name, ImGui::GetID("ImHexMainDock"));
@@ -381,7 +393,10 @@ namespace hex::plugin::builtin {
updateRecentProviders();
(void)EventManager::subscribe<EventFrameBegin>(drawWelcomeScreen);
(void)EventManager::subscribe<EventFrameBegin>(drawNoViewsBackground);
(void)EventManager::subscribe<EventFrameBegin>([]{
if (ImHexApi::Provider::isValid() && !isAnyViewOpen())
drawNoViewsBackground();
});
(void)EventManager::subscribe<EventSettingsChanged>([]() {
{
@@ -513,11 +528,11 @@ namespace hex::plugin::builtin {
});
constexpr auto CrashBackupFileName = "crash_backup.hexproj";
constexpr static auto CrashBackupFileName = "crash_backup.hexproj";
for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Config)) {
if (auto filePath = std::fs::path(path) / CrashBackupFileName; fs::exists(filePath)) {
s_safetyBackupPath = filePath;
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.welcome.safety_backup.title"_lang); });
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.welcome.safety_backup.title"_lang); });
}
}
@@ -526,7 +541,7 @@ namespace hex::plugin::builtin {
bool showTipOfTheDay = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.show_tips", 1);
if (showTipOfTheDay)
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.welcome.tip_of_the_day"_lang); });
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.welcome.tip_of_the_day"_lang); });
}
}

View File

@@ -38,7 +38,7 @@ namespace hex::plugin::builtin {
{ "hex.builtin.welcome.learn.latest.link", "https://github.com/WerWolv/ImHex/releases/latest" },
{ "hex.builtin.welcome.learn.pattern.title", "Pattern Language Dokumentation" },
{ "hex.builtin.welcome.learn.pattern.desc", "Lern ImHex Patterns zu schreiben mit unserer umfangreichen Dokumentation" },
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs/pattern_language/pattern_language.html" },
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs" },
{ "hex.builtin.welcome.learn.plugins.title", "Plugins API" },
{ "hex.builtin.welcome.learn.plugins.desc", "Erweitere ImHex mit neuen Funktionen mit Plugins" },
{ "hex.builtin.welcome.learn.plugins.link", "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide" },
@@ -101,6 +101,7 @@ namespace hex::plugin::builtin {
{ "hex.builtin.popup.error.read_only", "Schreibzugriff konnte nicht erlangt werden. Datei wurde im Lesemodus geöffnet." },
{ "hex.builtin.popup.error.open", "Öffnen der Datei fehlgeschlagen!" },
{ "hex.builtin.popup.error.create", "Erstellen der neuen Datei fehlgeschlagen!" },
{ "hex.builtin.popup.error.task_exception", "Fehler in Task '{}':\n\n{}" },
{ "hex.builtin.menu.file", "Datei" },
{ "hex.builtin.file.open_file", "Datei öffnen..." },
@@ -132,7 +133,6 @@ namespace hex::plugin::builtin {
{ "hex.builtin.menu.view", "Ansicht" },
{ "hex.builtin.menu.layout", "Layout" },
{ "hex.builtin.menu.view.fps", "FPS anzeigen" },
{ "hex.builtin.menu.view.demo", "ImGui Demo anzeigen" },
{ "hex.builtin.menu.help", "Hilfe" },
@@ -284,7 +284,8 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.hex_editor.file.save_as", "Speichern unter..." },
{ "hex.builtin.view.hex_editor.menu.edit.copy", "Kopieren" },
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "Kopieren als..." },
{ "hex.builtin.view.hex_editor.copy.hex", "String" },
{ "hex.builtin.view.hex_editor.copy.hex", "Hex String" },
{ "hex.builtin.view.hex_editor.copy.address", "Adresse" },
{ "hex.builtin.view.hex_editor.copy.c", "C Array" },
{ "hex.builtin.view.hex_editor.copy.cpp", "C++ Array" },
{ "hex.builtin.view.hex_editor.copy.csharp", "C# Array" },
@@ -292,7 +293,13 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.hex_editor.copy.python", "Python Array" },
{ "hex.builtin.view.hex_editor.copy.java", "Java Array" },
{ "hex.builtin.view.hex_editor.copy.js", "JavaScript Array" },
{ "hex.builtin.view.hex_editor.copy.ascii", "ASCII Art" },
{ "hex.builtin.view.hex_editor.copy.lua", "Lua Array" },
{ "hex.builtin.view.hex_editor.copy.go", "Go Array" },
{ "hex.builtin.view.hex_editor.copy.crystal", "Crystal Array" },
{ "hex.builtin.view.hex_editor.copy.swift", "Swift Array" },
{ "hex.builtin.view.hex_editor.copy.pascal", "Pascal Array" },
{ "hex.builtin.view.hex_editor.copy.base64", "Base64" },
{ "hex.builtin.view.hex_editor.copy.ascii", "Text Area" },
{ "hex.builtin.view.hex_editor.copy.html", "HTML" },
{ "hex.builtin.view.hex_editor.menu.edit.paste", "Einfügen" },
{ "hex.builtin.view.hex_editor.menu.edit.select_all", "Alles auswählen" },
@@ -413,11 +420,14 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.find.strings.line_feeds", "Line Feeds" },
{ "hex.builtin.view.find.sequences", "Sequenzen" },
{ "hex.builtin.view.find.regex", "Regex" },
{ "hex.builtin.view.find.regex.pattern", "Pattern" },
{ "hex.builtin.view.find.regex.full_match", "Benötige volle übereinstimmung" },
{ "hex.builtin.view.find.binary_pattern", "Binärpattern" },
{ "hex.builtin.view.find.search", "Suchen" },
{ "hex.builtin.view.find.context.copy", "Wert Kopieren" },
{ "hex.builtin.view.find.context.copy_demangle", "Demangled Wert Kopieren" },
{ "hex.builtin.view.find.search.entries", "{} Einträge gefunden" },
{ "hex.builtin.view.find.search.reset", "Zurücksetzen" },
{ "hex.builtin.command.calc.desc", "Rechner" },
{ "hex.builtin.command.cmd.desc", "Command" },

View File

@@ -39,7 +39,7 @@ namespace hex::plugin::builtin {
{ "hex.builtin.welcome.learn.latest.link", "https://github.com/WerWolv/ImHex/releases/latest" },
{ "hex.builtin.welcome.learn.pattern.title", "Pattern Language Documentation" },
{ "hex.builtin.welcome.learn.pattern.desc", "Learn how to write ImHex patterns with our extensive documentation" },
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs/pattern_language/pattern_language.html" },
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs" },
{ "hex.builtin.welcome.learn.plugins.title", "Plugins API" },
{ "hex.builtin.welcome.learn.plugins.desc", "Extend ImHex with additional features using plugins" },
{ "hex.builtin.welcome.learn.plugins.link", "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide" },
@@ -103,8 +103,10 @@ namespace hex::plugin::builtin {
{ "hex.builtin.popup.error.read_only", "Couldn't get write access. File opened in read-only mode." },
{ "hex.builtin.popup.error.open", "Failed to open file!" },
{ "hex.builtin.popup.error.create", "Failed to create new file!" },
{ "hex.builtin.popup.error.task_exception", "Exception thrown in Task '{}':\n\n{}" },
{ "hex.builtin.menu.file", "File" },
{ "hex.builtin.menu.file.create_file", "New File..." },
{ "hex.builtin.menu.file.open_file", "Open File..." },
{ "hex.builtin.menu.file.open_recent", "Open Recent" },
{ "hex.builtin.menu.file.clear_recent", "Clear" },
@@ -286,7 +288,8 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.hex_editor.menu.file.save_as", "Save As..." },
{ "hex.builtin.view.hex_editor.menu.edit.copy", "Copy" },
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "Copy as..." },
{ "hex.builtin.view.hex_editor.copy.hex", "String" },
{ "hex.builtin.view.hex_editor.copy.hex", "Hex String" },
{ "hex.builtin.view.hex_editor.copy.address", "Address" },
{ "hex.builtin.view.hex_editor.copy.c", "C Array" },
{ "hex.builtin.view.hex_editor.copy.cpp", "C++ Array" },
{ "hex.builtin.view.hex_editor.copy.csharp", "C# Array" },
@@ -294,7 +297,13 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.hex_editor.copy.python", "Python Array" },
{ "hex.builtin.view.hex_editor.copy.java", "Java Array" },
{ "hex.builtin.view.hex_editor.copy.js", "JavaScript Array" },
{ "hex.builtin.view.hex_editor.copy.ascii", "ASCII Art" },
{ "hex.builtin.view.hex_editor.copy.lua", "Lua Array" },
{ "hex.builtin.view.hex_editor.copy.go", "Go Array" },
{ "hex.builtin.view.hex_editor.copy.crystal", "Crystal Array" },
{ "hex.builtin.view.hex_editor.copy.swift", "Swift Array" },
{ "hex.builtin.view.hex_editor.copy.pascal", "Pascal Array" },
{ "hex.builtin.view.hex_editor.copy.base64", "Base64" },
{ "hex.builtin.view.hex_editor.copy.ascii", "Text Area" },
{ "hex.builtin.view.hex_editor.copy.html", "HTML" },
{ "hex.builtin.view.hex_editor.menu.edit.paste", "Paste" },
{ "hex.builtin.view.hex_editor.menu.edit.select_all", "Select all" },
@@ -417,11 +426,14 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.find.strings.line_feeds", "Line Feeds" },
{ "hex.builtin.view.find.sequences", "Sequences" },
{ "hex.builtin.view.find.regex", "Regex" },
{ "hex.builtin.view.find.regex.pattern", "Pattern" },
{ "hex.builtin.view.find.regex.full_match", "Require full match" },
{ "hex.builtin.view.find.binary_pattern", "Binary Pattern" },
{ "hex.builtin.view.find.search", "Search" },
{ "hex.builtin.view.find.context.copy", "Copy Value" },
{ "hex.builtin.view.find.context.copy_demangle", "Copy Demangled Value" },
{ "hex.builtin.view.find.search.entries", "{} entries found" },
{ "hex.builtin.view.find.search.reset", "Reset" },
{ "hex.builtin.command.calc.desc", "Calculator" },

View File

@@ -38,7 +38,7 @@ namespace hex::plugin::builtin {
{ "hex.builtin.welcome.learn.latest.link", "https://github.com/WerWolv/ImHex/releases/latest" },
{ "hex.builtin.welcome.learn.pattern.title", "Documentazione dei Pattern" },
{ "hex.builtin.welcome.learn.pattern.desc", "Scopri come scrivere pattern per ImHex con la nostra dettagliata documentazione" },
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs/pattern_language/pattern_language.html" },
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs" },
{ "hex.builtin.welcome.learn.plugins.title", "Plugins API" },
{ "hex.builtin.welcome.learn.plugins.desc", "Espandi l'utilizzo di ImHex con i Plugin" },
{ "hex.builtin.welcome.learn.plugins.link", "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide" },
@@ -101,8 +101,10 @@ namespace hex::plugin::builtin {
{ "hex.builtin.popup.error.read_only", "Impossibile scrivere sul File. File aperto solo in modalità lettura" },
{ "hex.builtin.popup.error.open", "Impossibile aprire il File!" },
{ "hex.builtin.popup.error.create", "Impossibile creare il nuovo File!" },
//{ "hex.builtin.popup.error.task_exception", "Exception thrown in Task '{}':\n\n{}" },
{ "hex.builtin.menu.file", "File" },
//{ "hex.builtin.menu.file.create_file", "New File..." },
{ "hex.builtin.menu.file.open_file", "Apri File..." },
{ "hex.builtin.menu.file.open_recent", "File recenti" },
{ "hex.builtin.menu.file.clear_recent", "Pulisci" },
@@ -287,7 +289,8 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.hex_editor.menu.file.save_as", "Salva come..." },
{ "hex.builtin.view.hex_editor.menu.edit.copy", "Copia" },
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "Copia come..." },
{ "hex.builtin.view.hex_editor.copy.hex", "Stringa" },
{ "hex.builtin.view.hex_editor.copy.hex", "Hex Stringa" },
//{ "hex.builtin.view.hex_editor.copy.address", "Address" },
{ "hex.builtin.view.hex_editor.copy.c", "C Array" },
{ "hex.builtin.view.hex_editor.copy.cpp", "C++ Array" },
{ "hex.builtin.view.hex_editor.copy.csharp", "C# Array" },
@@ -295,7 +298,13 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.hex_editor.copy.python", "Python Array" },
{ "hex.builtin.view.hex_editor.copy.java", "Java Array" },
{ "hex.builtin.view.hex_editor.copy.js", "JavaScript Array" },
{ "hex.builtin.view.hex_editor.copy.ascii", "ASCII Art" },
{ "hex.builtin.view.hex_editor.copy.lua", "Lua Array" },
{ "hex.builtin.view.hex_editor.copy.go", "Go Array" },
{ "hex.builtin.view.hex_editor.copy.crystal", "Crystal Array" },
{ "hex.builtin.view.hex_editor.copy.swift", "Swift Array" },
{ "hex.builtin.view.hex_editor.copy.pascal", "Pascal Array" },
{ "hex.builtin.view.hex_editor.copy.base64", "Base64" },
//{ "hex.builtin.view.hex_editor.copy.ascii", "Text Area" },
{ "hex.builtin.view.hex_editor.copy.html", "HTML" },
{ "hex.builtin.view.hex_editor.menu.edit.paste", "Incolla" },
{ "hex.builtin.view.hex_editor.menu.edit.select_all", "Seleziona tutti" },
@@ -416,11 +425,14 @@ namespace hex::plugin::builtin {
// { "hex.builtin.view.find.strings.line_feeds", "Line Feeds" },
// { "hex.builtin.view.find.sequences", "Sequences" },
// { "hex.builtin.view.find.regex", "Regex" },
//{ "hex.builtin.view.find.regex.pattern", "Pattern" },
//{ "hex.builtin.view.find.regex.full_match", "Require full match" },
// { "hex.builtin.view.find.binary_pattern", "Binary Pattern" },
// { "hex.builtin.view.find.search", "Search" },
// { "hex.builtin.view.find.context.copy", "Copy Value" },
// { "hex.builtin.view.find.context.copy_demangle", "Copy Demangled Value" },
// { "hex.builtin.view.find.search.entries", "{} entries found" },
// { "hex.builtin.view.find.search.reset", "Reset" },
{ "hex.builtin.command.calc.desc", "Calcolatrice" },
{ "hex.builtin.command.cmd.desc", "Comando" },

View File

@@ -38,7 +38,7 @@ namespace hex::plugin::builtin {
{ "hex.builtin.welcome.learn.latest.link", "https://github.com/WerWolv/ImHex/releases/latest" },
{ "hex.builtin.welcome.learn.pattern.title", "ImHexオリジナル言語について" },
{ "hex.builtin.welcome.learn.pattern.desc", "公式ドキュメントを読む" },
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs/pattern_language/pattern_language.html" },
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs" },
{ "hex.builtin.welcome.learn.plugins.title", "プラグインAPI" },
{ "hex.builtin.welcome.learn.plugins.desc", "ImHexの機能を拡張する" },
{ "hex.builtin.welcome.learn.plugins.link", "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide" },
@@ -81,13 +81,13 @@ namespace hex::plugin::builtin {
{ "hex.builtin.common.browse", "ファイルを参照…" },
{ "hex.builtin.common.choose_file", "ファイルを選択" },
// { "hex.builtin.common.processing", "Processing" },
//{ "hex.builtin.common.filter", "Filter" },
//{ "hex.builtin.common.value", "Value" },
{ "hex.builtin.common.filter", "フィルタ" },
{ "hex.builtin.common.value", "" },
{ "hex.builtin.common.offset", "オフセット" },
//{ "hex.builtin.common.range", "Range" },
//{ "hex.builtin.common.range.entire_data", "Entire Data" },
//{ "hex.builtin.common.range.selection", "Selection" },
//{ "hex.builtin.common.comment", "Comment" },
{ "hex.builtin.common.range", "範囲" },
{ "hex.builtin.common.range.entire_data", "データ全体" },
{ "hex.builtin.common.range.selection", "選択範囲" },
{ "hex.builtin.common.comment", "コメント" },
{ "hex.builtin.common.encoding.ascii", "ASCII" },
{ "hex.builtin.common.encoding.utf16le", "UTF-16LE" },
@@ -101,8 +101,10 @@ namespace hex::plugin::builtin {
{ "hex.builtin.popup.error.read_only", "書き込み権限を取得できませんでした。ファイルが読み取り専用で開かれました。" },
{ "hex.builtin.popup.error.open", "ファイルを開けませんでした。" },
{ "hex.builtin.popup.error.create", "新しいファイルを作成できませんでした。" },
//{ "hex.builtin.popup.error.task_exception", "Exception thrown in Task '{}':\n\n{}" },
{ "hex.builtin.menu.file", "ファイル" },
//{ "hex.builtin.menu.file.create_file", "New File..." },
{ "hex.builtin.menu.file.open_file", "ファイルを開く…" },
{ "hex.builtin.menu.file.open_recent", "最近使用したファイル" },
{ "hex.builtin.menu.file.clear_recent", "リストをクリア" },
@@ -123,9 +125,9 @@ namespace hex::plugin::builtin {
{ "hex.builtin.menu.file.export.ips", "IPSパッチ" },
{ "hex.builtin.menu.file.export.ips32", "IPS32パッチ" },
{ "hex.builtin.menu.file.export.base64.popup.export_error", "有効なBase64形式ではありません。" },
{ "hex.builtin.menu.file.export.popup.create", "データをエクスポートできません。\nファイルの作成に失敗しました。" },
//{ "hex.builtin.menu.file.bookmark.import", "Import bookmarks" },
//{ "hex.builtin.menu.file.bookmark.export", "Export bookmarks" },
{ "hex.builtin.menu.file.export.popup.create", "データをエクスポートできません。\nファイルの作成に失敗しました。" },
{ "hex.builtin.menu.file.bookmark.import", "ブックマークをインポート…" },
{ "hex.builtin.menu.file.bookmark.export", "ブックマークをエクスポート…" },
{ "hex.builtin.menu.edit", "編集" },
{ "hex.builtin.menu.edit.undo", "元に戻す" },
@@ -259,10 +261,10 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.hex_editor.name", "Hexエディタ" },
{ "hex.builtin.view.hex_editor.page", "ページ" },
//{ "hex.builtin.view.hex_editor.selection", "Selection" },
//{ "hex.builtin.view.hex_editor.selection.none", "None" },
//{ "hex.builtin.view.hex_editor.region", "Region" },
//{ "hex.builtin.view.hex_editor.data_size", "Data Size" },
{ "hex.builtin.view.hex_editor.selection", "選択中" },
{ "hex.builtin.view.hex_editor.selection.none", "なし" },
{ "hex.builtin.view.hex_editor.region", "ページの領域" },
{ "hex.builtin.view.hex_editor.data_size", "ファイルサイズ" },
//{ "hex.builtin.view.hex_editor.no_bytes", "No bytes available" },
{ "hex.builtin.view.hex_editor.menu.file.search", "検索" },
@@ -287,6 +289,7 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.hex_editor.menu.edit.copy", "コピー" },
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "〜としてコピー…" },
{ "hex.builtin.view.hex_editor.copy.hex", "文字列" },
//{ "hex.builtin.view.hex_editor.copy.address", "Address" },
{ "hex.builtin.view.hex_editor.copy.c", "C 配列" },
{ "hex.builtin.view.hex_editor.copy.cpp", "C++ 配列" },
{ "hex.builtin.view.hex_editor.copy.csharp", "C# 配列" },
@@ -294,7 +297,13 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.hex_editor.copy.python", "Python 配列" },
{ "hex.builtin.view.hex_editor.copy.java", "Java 配列" },
{ "hex.builtin.view.hex_editor.copy.js", "JavaScript 配列" },
{ "hex.builtin.view.hex_editor.copy.ascii", "アスキーアート" },
{ "hex.builtin.view.hex_editor.copy.lua", "Lua 配列" },
{ "hex.builtin.view.hex_editor.copy.go", "Go 配列" },
{ "hex.builtin.view.hex_editor.copy.crystal", "Crystal 配列" },
{ "hex.builtin.view.hex_editor.copy.swift", "Swift 配列" },
{ "hex.builtin.view.hex_editor.copy.pascal", "Pascal 配列" },
{ "hex.builtin.view.hex_editor.copy.base64", "Base64" },
//{ "hex.builtin.view.hex_editor.copy.ascii", "Text Area" },
{ "hex.builtin.view.hex_editor.copy.html", "HTML" },
{ "hex.builtin.view.hex_editor.menu.edit.paste", "貼り付け" },
{ "hex.builtin.view.hex_editor.menu.edit.select_all", "すべて選択" },
@@ -303,9 +312,9 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.hex_editor.menu.edit.resize", "リサイズ…" },
{ "hex.builtin.view.hex_editor.menu.edit.insert", "挿入…" },
{ "hex.builtin.view.information.name", "データ情報" },
{ "hex.builtin.view.information.name", "データ解析" },
{ "hex.builtin.view.information.control", "コントロール" },
{ "hex.builtin.view.information.analyze", "解析ページ" },
{ "hex.builtin.view.information.analyze", "表示中のページを解析する" },
{ "hex.builtin.view.information.analyzing", "解析中…" },
{ "hex.builtin.view.information.region", "解析する領域" },
{ "hex.builtin.view.information.magic", "Magic情報" },
@@ -318,7 +327,7 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.information.block_size.desc", "{0} ブロック/ {1} バイト" },
{ "hex.builtin.view.information.file_entropy", "ファイルのエントロピー" },
{ "hex.builtin.view.information.highest_entropy", "最大エントロピーブロック" },
{ "hex.builtin.view.information.encrypted", "暗号化もしくは圧縮されているデータの可能性が高いです。" },
{ "hex.builtin.view.information.encrypted", "暗号化や圧縮を経たデータと推測されます。" },
{ "hex.builtin.view.information.magic_db_added", "Magicデータベースが追加されました。" },
{ "hex.builtin.view.patches.name", "パッチ" },
@@ -400,31 +409,33 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.provider_settings.load_popup", "プロバイダを開く" },
{ "hex.builtin.view.provider_settings.load_error", "プロバイダを開く際にエラーが発生しました。"},
//{ "hex.builtin.view.find.name", "Find" },
// { "hex.builtin.view.find.searching", "Searching…" },
{ "hex.builtin.view.find.name", "検索" },
{ "hex.builtin.view.find.searching", "検索中…" },
// { "hex.builtin.view.find.demangled", "Demangled" },
// { "hex.builtin.view.find.range", "Range" },
// { "hex.builtin.view.find.range.entire_data", "Entire Data" },
// { "hex.builtin.view.find.range.selection", "Selection" },
{ "hex.builtin.view.find.range", "検索する範囲" },
{ "hex.builtin.view.find.range.selection", "選択中の箇所のみ" },
// { "hex.builtin.view.find.strings", "文字列" },
// { "hex.builtin.view.find.strings.min_length", "Minimum length" },
// { "hex.builtin.view.find.strings.match_settings", "Match Settings" },
// { "hex.builtin.view.find.strings.null_term", "Require Null Termination" },
{ "hex.builtin.view.find.strings.match_settings", "条件設定" },
{ "hex.builtin.view.find.strings.null_term", "ヌル終端を含む文字列のみ検索" },
// { "hex.builtin.view.find.strings.chars", "Characters" },
// { "hex.builtin.view.find.strings.lower_case", "Lower case letters" },
// { "hex.builtin.view.find.strings.upper_case", "Upper case letters" },
// { "hex.builtin.view.find.strings.numbers", "Numbers" },
// { "hex.builtin.view.find.strings.underscores", "Underscores" },
// { "hex.builtin.view.find.strings.symbols", "Symbols" },
// { "hex.builtin.view.find.strings.spaces", "Spaces" },
// { "hex.builtin.view.find.strings.line_feeds", "Line Feeds" },
// { "hex.builtin.view.find.sequences", "Sequences" },
// { "hex.builtin.view.find.regex", "Regex" },
// { "hex.builtin.view.find.binary_pattern", "Binary Pattern" },
// { "hex.builtin.view.find.search", "Search" },
// { "hex.builtin.view.find.context.copy", "Copy Value" },
{ "hex.builtin.view.find.strings.lower_case", "大文字" },
{ "hex.builtin.view.find.strings.upper_case", "小文字" },
{ "hex.builtin.view.find.strings.numbers", "数字" },
{ "hex.builtin.view.find.strings.underscores", "アンダースコア" },
{ "hex.builtin.view.find.strings.symbols", "その他の記号" },
{ "hex.builtin.view.find.strings.spaces", "半角スペース" },
{ "hex.builtin.view.find.strings.line_feeds", "ラインフィード" },
{ "hex.builtin.view.find.sequences", "通常検索" },
{ "hex.builtin.view.find.regex", "正規表現" },
// { "hex.builtin.view.find.regex.pattern", "Pattern" },
// { "hex.builtin.view.find.regex.full_match", "Require full match" },
{ "hex.builtin.view.find.binary_pattern", "16進数" },
{ "hex.builtin.view.find.search", "検索を実行" },
{ "hex.builtin.view.find.context.copy", "値をコピー" },
// { "hex.builtin.view.find.context.copy_demangle", "Copy Demangled Value" },
// { "hex.builtin.view.find.search.entries", "{} entries found" },
{ "hex.builtin.view.find.search.entries", "一致件数: {}" },
// { "hex.builtin.view.find.search.reset", "Reset" },
{ "hex.builtin.command.calc.desc", "電卓" },
{ "hex.builtin.command.cmd.desc", "コマンド" },

View File

@@ -0,0 +1,817 @@
#include <hex/api/content_registry.hpp>
#include <hex/api/localization.hpp>
namespace hex::plugin::builtin {
void registerLanguageKoKR() {
ContentRegistry::Language::registerLanguage("한국어 (KR)", "ko-KR");
ContentRegistry::Language::addLocalizations("ko-KR", {
{ "hex.builtin.welcome.header.main", "Welcome to ImHex" },
{ "hex.builtin.welcome.header.start", "시작하기" },
{ "hex.builtin.welcome.start.create_file", "새 파일 생성" },
{ "hex.builtin.welcome.start.open_file", "파일 열기" },
{ "hex.builtin.welcome.start.open_project", "프로젝트 열기" },
{ "hex.builtin.welcome.start.recent", "최근 파일들" },
{ "hex.builtin.welcome.start.open_other", "다른 공급자 열기" },
{ "hex.builtin.welcome.header.help", "도움말" },
{ "hex.builtin.welcome.help.repo", "GitHub 저장소" },
{ "hex.builtin.welcome.help.repo.link", "https://imhex.werwolv.net/git" },
{ "hex.builtin.welcome.help.gethelp", "도움 얻기" },
{ "hex.builtin.welcome.help.gethelp.link", "https://github.com/WerWolv/ImHex/discussions/categories/get-help" },
{ "hex.builtin.welcome.help.discord", "디스코드 서버" },
{ "hex.builtin.welcome.help.discord.link", "https://imhex.werwolv.net/discord" },
{ "hex.builtin.welcome.header.plugins", "로딩된 플러그인" },
{ "hex.builtin.welcome.plugins.plugin", "플러그인" },
{ "hex.builtin.welcome.plugins.author", "작성자" },
{ "hex.builtin.welcome.plugins.desc", "설명" },
{ "hex.builtin.welcome.header.customize", "커스터마이즈" },
{ "hex.builtin.welcome.customize.settings.title", "설정" },
{ "hex.builtin.welcome.customize.settings.desc", "ImHex의 설정을 변경합니다" },
{ "hex.builtin.welcome.header.update", "업데이트" },
{ "hex.builtin.welcome.update.title", "새로운 업데이트가 존재합니다!" },
{ "hex.builtin.welcome.update.desc", "ImHex {0} 가 업데이트 되었습니다! 여기서 다운로드하세요." },
{ "hex.builtin.welcome.update.link", "https://github.com/WerWolv/ImHex/releases/latest" },
{ "hex.builtin.welcome.header.learn", "Learn" },
{ "hex.builtin.welcome.learn.latest.title", "최신 릴리즈" },
{ "hex.builtin.welcome.learn.latest.desc", "ImHex의 최신 변경사항 읽기" },
{ "hex.builtin.welcome.learn.latest.link", "https://github.com/WerWolv/ImHex/releases/latest" },
{ "hex.builtin.welcome.learn.pattern.title", "패턴 언어 작성 방법 문서" },
{ "hex.builtin.welcome.learn.pattern.desc", "ImHex 패턴을 작성하는 방법을 배워 봅시다." },
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs" },
{ "hex.builtin.welcome.learn.plugins.title", "플러그인 API" },
{ "hex.builtin.welcome.learn.plugins.desc", "플러그인을 이용해 ImHex의 기능을 확장해 봅시다." },
{ "hex.builtin.welcome.learn.plugins.link", "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide" },
{ "hex.builtin.welcome.header.various", "Various" },
{ "hex.builtin.welcome.tip_of_the_day", "오늘의 팁" },
{ "hex.builtin.welcome.safety_backup.title", "손상된 데이터 복구" },
{ "hex.builtin.welcome.safety_backup.desc", "이전에 ImHex가 비 정상적으로 종료된 것 같습니다.\n이전의 작업을 복구할까요?"},
{ "hex.builtin.welcome.safety_backup.restore", "네, 복구" },
{ "hex.builtin.welcome.safety_backup.delete", "아니요, 삭제" },
{ "hex.builtin.common.endian", "엔디안" },
{ "hex.builtin.common.little_endian", "리틀 엔디안" },
{ "hex.builtin.common.big_endian", "빅 엔디안" },
{ "hex.builtin.common.little", "리틀" },
{ "hex.builtin.common.big", "" },
{ "hex.builtin.common.number_format", "포맷" },
{ "hex.builtin.common.decimal", "10진수" },
{ "hex.builtin.common.hexadecimal", "16진수" },
{ "hex.builtin.common.octal", "8진수" },
{ "hex.builtin.common.info", "정보" },
{ "hex.builtin.common.error", "에러" },
{ "hex.builtin.common.fatal", "치명적 에러" },
{ "hex.builtin.common.question", "질문" },
{ "hex.builtin.common.address", "주소" },
{ "hex.builtin.common.size", "크기" },
{ "hex.builtin.common.region", "지역" },
{ "hex.builtin.common.match_selection", "선택 범위와 일치" },
{ "hex.builtin.common.yes", "" },
{ "hex.builtin.common.no", "아니오" },
{ "hex.builtin.common.okay", "" },
{ "hex.builtin.common.load", "불러오기" },
{ "hex.builtin.common.cancel", "취소" },
{ "hex.builtin.common.set", "설정" },
{ "hex.builtin.common.close", "닫기" },
{ "hex.builtin.common.dont_show_again", "다시 보이지 않기" },
{ "hex.builtin.common.link", "링크" },
{ "hex.builtin.common.file", "파일" },
{ "hex.builtin.common.open", "열기" },
{ "hex.builtin.common.browse", "찾아보기..." },
{ "hex.builtin.common.choose_file", "파일 선택" },
{ "hex.builtin.common.processing", "작업 중" },
{ "hex.builtin.common.filter", "필터" },
{ "hex.builtin.common.value", "" },
{ "hex.builtin.common.type", "타입" },
{ "hex.builtin.common.offset", "오프셋" },
{ "hex.builtin.common.range", "범위" },
{ "hex.builtin.common.range.entire_data", "전체 데이터" },
{ "hex.builtin.common.range.selection", "선택" },
{ "hex.builtin.common.comment", "주석" },
{ "hex.builtin.common.encoding.ascii", "ASCII" },
{ "hex.builtin.common.encoding.utf16le", "UTF-16LE" },
{ "hex.builtin.common.encoding.utf16be", "UTF-16BE" },
{ "hex.builtin.common.encoding.utf8", "UTF-8" },
{ "hex.builtin.popup.exit_application.title", "프로그램을 종료하시겠습니까?" },
{ "hex.builtin.popup.exit_application.desc", "프로젝트에 저장하지 않은 내용이 있습니다.\n정말로 종료하시겠습니까?" },
{ "hex.builtin.popup.close_provider.title", "공급자를 종료하시겠습니까?" },
{ "hex.builtin.popup.close_provider.desc", "공급자에 저장하지 않은 내용이 있습니다.\n정말로 종료하시겠습니까?" },
{ "hex.builtin.popup.error.read_only", "쓰기 권한을 가져올 수 없습니다. 파일이 읽기 전용 모드로 열렸습니다." },
{ "hex.builtin.popup.error.open", "파일을 여는데 실패했습니다!" },
{ "hex.builtin.popup.error.create", "새 파일을 만드는데 실패했습니다!" },
//{ "hex.builtin.popup.error.task_exception", "Exception thrown in Task '{}':\n\n{}" },
{ "hex.builtin.menu.file", "파일" },
{ "hex.builtin.menu.file.create_file", "새 파일..." },
{ "hex.builtin.menu.file.open_file", "파일 열기..." },
{ "hex.builtin.menu.file.open_recent", "최근 파일" },
{ "hex.builtin.menu.file.clear_recent", "최근 이력 지우기" },
{ "hex.builtin.menu.file.open_other", "다른 공급자 열기..." },
{ "hex.builtin.menu.file.close", "닫기" },
{ "hex.builtin.menu.file.quit", "ImHex 종료하기" },
{ "hex.builtin.menu.file.open_project", "프로젝트 열기..." },
{ "hex.builtin.menu.file.save_project", "프로젝트 저장..." },
{ "hex.builtin.menu.file.import", "가져오기..." },
{ "hex.builtin.menu.file.import.base64", "Base64 파일" },
{ "hex.builtin.menu.file.import.base64.popup.import_error", "파일이 올바른 Base64 형식이 아닙니다!" },
{ "hex.builtin.menu.file.import.base64.popup.open_error", "파일을 여는 데 실패했습니다!" },
{ "hex.builtin.menu.file.import.ips", "IPS 패치" },
{ "hex.builtin.menu.file.import.ips32", "IPS32 패치" },
{ "hex.builtin.menu.file.export", "내보내기..." },
{ "hex.builtin.menu.file.export.title", "파일 내보내기" },
{ "hex.builtin.menu.file.export.ips", "IPS 패치" },
{ "hex.builtin.menu.file.export.ips32", "IPS32 패치" },
{ "hex.builtin.menu.file.export.base64.popup.export_error", "파일이 올바른 Base64 형식이 아닙니다!" },
{ "hex.builtin.menu.file.export.popup.create", "데이터를 내보낼 수 없습니다. 파일을 만드는 데 실패했습니다!" },
{ "hex.builtin.menu.file.bookmark.import", "북마크 가져오기" },
{ "hex.builtin.menu.file.bookmark.export", "북마크 내보내기" },
{ "hex.builtin.menu.edit", "수정" },
{ "hex.builtin.menu.edit.undo", "실행 취소" },
{ "hex.builtin.menu.edit.redo", "다시 실행" },
{ "hex.builtin.menu.edit.bookmark.create", "북마크 생성하기" },
{ "hex.builtin.menu.view", "" },
{ "hex.builtin.menu.layout", "레이아웃" },
{ "hex.builtin.menu.view.demo", "ImGui Demo 표시하기" },
{ "hex.builtin.menu.help", "도움말" },
{ "hex.builtin.view.bookmarks.name", "북마크" },
{ "hex.builtin.view.bookmarks.default_title", "북마크 [0x{0:X} - 0x{1:X}]" },
{ "hex.builtin.view.bookmarks.no_bookmarks", "북마크가 없습니다. '수정 -> 북마크 생성하기'로 북마크를 생성하세요" },
{ "hex.builtin.view.bookmarks.title.info", "정보" },
{ "hex.builtin.view.bookmarks.address", "0x{0:X} : 0x{1:X} ({2} bytes)" },
{ "hex.builtin.view.bookmarks.button.jump", "이동하기" },
{ "hex.builtin.view.bookmarks.button.remove", "지우기" },
{ "hex.builtin.view.bookmarks.header.name", "이름" },
{ "hex.builtin.view.bookmarks.header.color", "색상" },
{ "hex.builtin.view.bookmarks.header.comment", "설명" },
{ "hex.builtin.view.command_palette.name", "명령 팔레트" },
// HxD의 번역을 그대로 가져왔습니다.
{ "hex.builtin.view.data_inspector.name", "데이터 변환기" },
{ "hex.builtin.view.data_inspector.table.name", "이름" },
{ "hex.builtin.view.data_inspector.table.value", "" },
{ "hex.builtin.view.data_inspector.no_data", "선택된 바이트 없음" },
{ "hex.builtin.view.data_inspector.invert", "반전" },
{ "hex.builtin.view.data_processor.name", "데이터 프로세서" },
{ "hex.builtin.view.data_processor.help_text", "오른쪽 클릭을 눌러 새 노드를 만드세요" },
{ "hex.builtin.view.data_processor.menu.remove_selection", "선택 영역 삭제" },
{ "hex.builtin.view.data_processor.menu.remove_node", "노드 삭제" },
{ "hex.builtin.view.data_processor.menu.remove_link", "링크 삭제" },
{ "hex.builtin.view.data_processor.menu.file.load_processor", "데이터 프로세서 불러오기..." },
{ "hex.builtin.view.data_processor.menu.file.save_processor", "데이터 프로세서 저장하기..." },
{ "hex.builtin.view.disassembler.name", "디스어셈블러" },
{ "hex.builtin.view.disassembler.position", "위치" },
{ "hex.builtin.view.disassembler.base", "베이스 주소" },
{ "hex.builtin.view.disassembler.region", "코드 영역" },
{ "hex.builtin.view.disassembler.settings.header", "설정" },
{ "hex.builtin.view.disassembler.settings.mode", "모드" },
{ "hex.builtin.view.disassembler.arch", "아키텍쳐" },
{ "hex.builtin.view.disassembler.16bit", "16-bit" },
{ "hex.builtin.view.disassembler.32bit", "32-bit" },
{ "hex.builtin.view.disassembler.64bit", "64-bit" },
{ "hex.builtin.view.disassembler.arm.arm", "ARM" },
{ "hex.builtin.view.disassembler.arm.thumb", "Thumb" },
{ "hex.builtin.view.disassembler.arm.default", "Default" },
{ "hex.builtin.view.disassembler.arm.cortex_m", "Cortex-M" },
{ "hex.builtin.view.disassembler.arm.armv8", "ARMv8" },
{ "hex.builtin.view.disassembler.mips.mips32", "MIPS32" },
{ "hex.builtin.view.disassembler.mips.mips64", "MIPS64" },
{ "hex.builtin.view.disassembler.mips.mips32R6", "MIPS32R6" },
{ "hex.builtin.view.disassembler.mips.mips2", "MIPS II" },
{ "hex.builtin.view.disassembler.mips.mips3", "MIPS III" },
{ "hex.builtin.view.disassembler.mips.micro", "Micro" },
{ "hex.builtin.view.disassembler.ppc.qpx", "Quad Processing Extensions" },
{ "hex.builtin.view.disassembler.ppc.spe", "Signal Processing Engine" },
{ "hex.builtin.view.disassembler.ppc.booke", "Book-E" },
{ "hex.builtin.view.disassembler.sparc.v9", "Sparc V9" },
{ "hex.builtin.view.disassembler.riscv.compressed", "Compressed" },
{ "hex.builtin.view.disassembler.m68k.000", "000" },
{ "hex.builtin.view.disassembler.m68k.010", "010" },
{ "hex.builtin.view.disassembler.m68k.020", "020" },
{ "hex.builtin.view.disassembler.m68k.030", "030" },
{ "hex.builtin.view.disassembler.m68k.040", "040" },
{ "hex.builtin.view.disassembler.m68k.060", "060" },
{ "hex.builtin.view.disassembler.m680x.6301", "6301" },
{ "hex.builtin.view.disassembler.m680x.6309", "6309" },
{ "hex.builtin.view.disassembler.m680x.6800", "6800" },
{ "hex.builtin.view.disassembler.m680x.6801", "6801" },
{ "hex.builtin.view.disassembler.m680x.6805", "6805" },
{ "hex.builtin.view.disassembler.m680x.6808", "6808" },
{ "hex.builtin.view.disassembler.m680x.6809", "6809" },
{ "hex.builtin.view.disassembler.m680x.6811", "6811" },
{ "hex.builtin.view.disassembler.m680x.cpu12", "CPU12" },
{ "hex.builtin.view.disassembler.m680x.hcs08", "HCS08" },
{ "hex.builtin.view.disassembler.mos65xx.6502", "6502" },
{ "hex.builtin.view.disassembler.mos65xx.65c02", "65C02" },
{ "hex.builtin.view.disassembler.mos65xx.w65c02", "W65C02" },
{ "hex.builtin.view.disassembler.mos65xx.65816", "65816" },
{ "hex.builtin.view.disassembler.mos65xx.65816_long_m", "65816 Long M" },
{ "hex.builtin.view.disassembler.mos65xx.65816_long_x", "65816 Long X" },
{ "hex.builtin.view.disassembler.mos65xx.65816_long_mx", "65816 Long MX" },
{ "hex.builtin.view.disassembler.bpf.classic", "Classic" },
{ "hex.builtin.view.disassembler.bpf.extended", "Extended" },
{ "hex.builtin.view.disassembler.disassemble", "디스어셈블" },
{ "hex.builtin.view.disassembler.disassembling", "디스어셈블 중..." },
{ "hex.builtin.view.disassembler.disassembly.title", "디스어셈블리" },
{ "hex.builtin.view.disassembler.disassembly.address", "주소" },
{ "hex.builtin.view.disassembler.disassembly.offset", "오프셋" },
{ "hex.builtin.view.disassembler.disassembly.bytes", "바이트" },
{ "hex.builtin.view.hashes.name", "해시" },
{ "hex.builtin.view.hashes.hash", "해시" },
{ "hex.builtin.view.hashes.no_settings", "설정이 존재하지 않습니다" },
{ "hex.builtin.view.hashes.function", "해시 함수" },
{ "hex.builtin.view.hashes.name", "이름" },
{ "hex.builtin.view.hashes.type", "종류" },
{ "hex.builtin.view.hashes.result", "결과" },
{ "hex.builtin.view.hashes.remove", "지우기" },
{ "hex.builtin.view.hashes.hover_info", "헥스 편집기에서 영역을 선택 후 쉬프트를 누른 채로 마우스 커서를 올리면 해당 값들의 해시를 알 수 있습니다." },
{ "hex.builtin.view.help.name", "도움말" },
{ "hex.builtin.view.help.about.name", "정보" },
{ "hex.builtin.view.help.about.translator", "Translated by mirusu400" },
{ "hex.builtin.view.help.about.source", "소스 코드는 GitHub에 존재합니다." },
{ "hex.builtin.view.help.about.donations", "후원" },
{ "hex.builtin.view.help.about.thanks", "이 작업물이 마음에 든다면, 프로젝트가 계속되도록 프로젝트에 후원해주세요. 감사합니다 <3" },
{ "hex.builtin.view.help.about.contributor", "기여자" },
{ "hex.builtin.view.help.about.libs", "사용한 라이브러리" },
{ "hex.builtin.view.help.about.paths", "ImHex 주소" },
{ "hex.builtin.view.help.about.license", "라이센스" },
{ "hex.builtin.view.help.documentation", "ImHex 문서" },
{ "hex.builtin.view.help.pattern_cheat_sheet", "패턴 언어 치트시트"},
{ "hex.builtin.view.help.calc_cheat_sheet", "치트시트 계산기" },
{ "hex.builtin.view.hex_editor.name", "헥스 편집기" },
{ "hex.builtin.view.hex_editor.page", "페이지" },
{ "hex.builtin.view.hex_editor.selection", "선택 영역" },
{ "hex.builtin.view.hex_editor.selection.none", "없음" },
{ "hex.builtin.view.hex_editor.region", "지역" },
{ "hex.builtin.view.hex_editor.data_size", "데이터 크기" },
{ "hex.builtin.view.hex_editor.no_bytes", "바이트가 존재하지 않습니다" },
{ "hex.builtin.view.hex_editor.menu.file.load_encoding_file", "커스텀 인코딩 불러오기..." },
{ "hex.builtin.view.hex_editor.menu.file.search", "검색" },
{ "hex.builtin.view.hex_editor.search.string", "문자열" },
{ "hex.builtin.view.hex_editor.search.hex", "헥스" },
{ "hex.builtin.view.hex_editor.search.find", "찾기" },
{ "hex.builtin.view.hex_editor.menu.file.goto", "이동하기" },
{ "hex.builtin.view.hex_editor.goto.offset.absolute", "절대주소" },
{ "hex.builtin.view.hex_editor.goto.offset.relative", "상대주소" },
{ "hex.builtin.view.hex_editor.goto.offset.begin", "시작" },
{ "hex.builtin.view.hex_editor.goto.offset.end", "종료" },
{ "hex.builtin.view.hex_editor.menu.file.select", "선택" },
{ "hex.builtin.view.hex_editor.select.offset.region", "지역" },
{ "hex.builtin.view.hex_editor.select.offset.begin", "시작" },
{ "hex.builtin.view.hex_editor.select.offset.end", "" },
{ "hex.builtin.view.hex_editor.select.offset.size", "크기" },
{ "hex.builtin.view.hex_editor.select.select", "선택" },
{ "hex.builtin.view.hex_editor.menu.file.save", "저장" },
{ "hex.builtin.view.hex_editor.menu.file.save_as", "다른 이름으로 저장..." },
{ "hex.builtin.view.hex_editor.menu.edit.copy", "복사" },
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "다른 방법으로 복사..." },
{ "hex.builtin.view.hex_editor.copy.hex", "문자열" },
//{ "hex.builtin.view.hex_editor.copy.address", "Address" },
{ "hex.builtin.view.hex_editor.copy.c", "C 배열" },
{ "hex.builtin.view.hex_editor.copy.cpp", "C++ 배열" },
{ "hex.builtin.view.hex_editor.copy.csharp", "C# 배열" },
{ "hex.builtin.view.hex_editor.copy.rust", "Rust 배열" },
{ "hex.builtin.view.hex_editor.copy.python", "Python 배열" },
{ "hex.builtin.view.hex_editor.copy.java", "Java 배열" },
{ "hex.builtin.view.hex_editor.copy.js", "JavaScript 배열" },
{ "hex.builtin.view.hex_editor.copy.lua", "Lua 배열" },
{ "hex.builtin.view.hex_editor.copy.go", "Go 배열" },
{ "hex.builtin.view.hex_editor.copy.crystal", "Crystal 배열" },
{ "hex.builtin.view.hex_editor.copy.swift", "Swift 배열" },
{ "hex.builtin.view.hex_editor.copy.pascal", "Pascal 배열" },
{ "hex.builtin.view.hex_editor.copy.base64", "Base64" },
//{ "hex.builtin.view.hex_editor.copy.ascii", "Text Area" },
{ "hex.builtin.view.hex_editor.copy.html", "HTML" },
{ "hex.builtin.view.hex_editor.menu.edit.paste", "붙여넣기" },
{ "hex.builtin.view.hex_editor.menu.edit.select_all", "모두 선택하기" },
{ "hex.builtin.view.hex_editor.menu.edit.set_base", "베이스 주소 설정" },
{ "hex.builtin.view.hex_editor.menu.edit.resize", "크기 변경..." },
{ "hex.builtin.view.hex_editor.menu.edit.insert", "삽입..." },
{ "hex.builtin.view.hex_editor.menu.edit.remove", "삭제..." },
{ "hex.builtin.view.information.name", "데이터 정보" },
{ "hex.builtin.view.information.control", "컨트롤" },
{ "hex.builtin.view.information.analyze", "페이지 분석" },
{ "hex.builtin.view.information.analyzing", "분석 중..." },
{ "hex.builtin.view.information.region", "분석한 영역" },
{ "hex.builtin.view.information.magic", "Magic 정보" },
{ "hex.builtin.view.information.description", "설명:" },
{ "hex.builtin.view.information.mime", "MIME 타입:" },
{ "hex.builtin.view.information.info_analysis", "정보 분석" },
{ "hex.builtin.view.information.distribution", "바이트 분포" },
{ "hex.builtin.view.information.entropy", "엔트로피" },
{ "hex.builtin.view.information.block_size", "블록 크기" },
{ "hex.builtin.view.information.block_size.desc", "{1} 바이트 중 {0} 블록 " },
{ "hex.builtin.view.information.file_entropy", "파일 엔트로피" },
{ "hex.builtin.view.information.highest_entropy", "최대 엔트로피 블록" },
{ "hex.builtin.view.information.encrypted", "이 데이터는 아마 암호화 혹은 압축되었을 가능성이 높습니다!" },
{ "hex.builtin.view.information.magic_db_added", "Magic 데이터베이스 추가됨!" },
{ "hex.builtin.view.patches.name", "패치" },
{ "hex.builtin.view.patches.offset", "오프셋" },
{ "hex.builtin.view.patches.orig", "원본 값" },
{ "hex.builtin.view.patches.patch", "수정된 값"},
{ "hex.builtin.view.patches.remove", "패치 없애기" },
{ "hex.builtin.view.pattern_editor.name", "패턴 편집기" },
{ "hex.builtin.view.pattern_editor.accept_pattern", "패턴 적용하기" },
{ "hex.builtin.view.pattern_editor.accept_pattern.desc", "하나 이상의 패턴 언어와 호환되는 데이터 타입이 발견되었습니다" },
{ "hex.builtin.view.pattern_editor.accept_pattern.pattern_language", "패턴" },
{ "hex.builtin.view.pattern_editor.accept_pattern.question", "선택한 패턴을 적용하시겠습니까?" },
{ "hex.builtin.view.pattern_editor.menu.file.load_pattern", "패턴 불러오기..." },
{ "hex.builtin.view.pattern_editor.menu.file.save_pattern", "패턴 저장하기..." },
{ "hex.builtin.view.pattern_editor.open_pattern", "패턴 열기" },
{ "hex.builtin.view.pattern_editor.evaluating", "평가 중..." },
{ "hex.builtin.view.pattern_editor.auto", "자동 평가" },
{ "hex.builtin.view.pattern_editor.console", "콘솔" },
{ "hex.builtin.view.pattern_editor.env_vars", "환경 변수" },
{ "hex.builtin.view.pattern_editor.settings", "설정" },
{ "hex.builtin.view.pattern_editor.dangerous_function.name", "위험한 함수를 허용하시겠습니까?" },
{ "hex.builtin.view.pattern_editor.dangerous_function.desc", "이 패턴은 위험한 함수를 실행하려 합니다.\n정말로 이 패턴을 신뢰하시겠습니?" },
{ "hex.builtin.view.pattern_editor.no_in_out_vars", "'in' 또는 'out' 지정자를 이용해 여기에 나타날 전역 변수를 선언합니다." },
{ "hex.builtin.view.pattern_data.name", "패턴 데이터" },
{ "hex.builtin.view.pattern_data.var_name", "이름" },
{ "hex.builtin.view.pattern_data.color", "색상" },
{ "hex.builtin.view.pattern_data.offset", "오프셋" },
{ "hex.builtin.view.pattern_data.size", "크기" },
{ "hex.builtin.view.pattern_data.type", "타입" },
{ "hex.builtin.view.pattern_data.value", "" },
{ "hex.builtin.view.settings.name", "설정" },
{ "hex.builtin.view.settings.restart_question", "변경 사항을 적용할려면 ImHex를 재시작 해야 합니다. 지금 바로 재시작하시겠습니까?" },
{ "hex.builtin.view.tools.name", "도구" },
{ "hex.builtin.view.yara.name", "Yara 규칙" },
{ "hex.builtin.view.yara.header.rules", "규칙" },
{ "hex.builtin.view.yara.reload", "재검사" },
{ "hex.builtin.view.yara.match", "일치하는 규칙" },
{ "hex.builtin.view.yara.matching", "검색 중..." },
{ "hex.builtin.view.yara.error", "Yara 컴파일러 에러: " },
{ "hex.builtin.view.yara.header.matches", "규칙" },
{ "hex.builtin.view.yara.matches.identifier", "식별자" },
{ "hex.builtin.view.yara.matches.variable", "변수" },
{ "hex.builtin.view.yara.whole_data", "모든 파일을 검색했습니다!" },
{ "hex.builtin.view.yara.no_rules", "YARA 규칙이 없습니다. ImHex의 'yara' 폴더에 YARA 규칙을 넣으세요." },
{ "hex.builtin.view.yara.rule_added", "Yara 규칙 추가됨!" },
{ "hex.builtin.view.constants.name", "상수" },
{ "hex.builtin.view.constants.row.category", "종류" },
{ "hex.builtin.view.constants.row.name", "이름" },
{ "hex.builtin.view.constants.row.desc", "설명" },
{ "hex.builtin.view.constants.row.value", "" },
{ "hex.builtin.view.store.name", "콘텐츠 스토어" },
{ "hex.builtin.view.store.desc", "ImHex의 온라인 데이터베이스에서 새로운 컨텐츠를 다운로드 받으세요." },
{ "hex.builtin.view.store.reload", "새로 고침" },
{ "hex.builtin.view.store.row.name", "이름" },
{ "hex.builtin.view.store.row.description", "설명" },
{ "hex.builtin.view.store.download", "다운로드" },
{ "hex.builtin.view.store.update", "업데이트" },
{ "hex.builtin.view.store.remove", "제거" },
{ "hex.builtin.view.store.tab.patterns", "패턴" },
{ "hex.builtin.view.store.tab.libraries", "라이브러리" },
{ "hex.builtin.view.store.tab.magics", "Magic 파일" },
{ "hex.builtin.view.store.tab.constants", "상수" },
{ "hex.builtin.view.store.tab.yara", "Yara 규칙" },
{ "hex.builtin.view.store.tab.encodings", "인코딩" },
{ "hex.builtin.view.store.loading", "스토어 콘텐츠 불러오는 중..." },
{ "hex.builtin.view.store.download_error", "파일 다운로드에 실패했습니다! 저장 폴더가 존재하지 않습니다." },
{ "hex.builtin.view.diff.name", "파일 비교" },
{ "hex.builtin.view.provider_settings.name", "공급자 설정" },
{ "hex.builtin.view.provider_settings.load_popup", "공급자 열기" },
{ "hex.builtin.view.provider_settings.load_error", "이 공급자를 여는 도중 에러가 발생했습니다!"},
{ "hex.builtin.view.find.name", "찾기" },
{ "hex.builtin.view.find.searching", "검색 중..." },
{ "hex.builtin.view.find.demangled", "Demangled" },
{ "hex.builtin.view.find.strings", "문자열" },
{ "hex.builtin.view.find.strings.min_length", "최소 길이" },
{ "hex.builtin.view.find.strings.match_settings", "검색 설정" },
{ "hex.builtin.view.find.strings.null_term", "Null로 끝난 글자만 검색" },
{ "hex.builtin.view.find.strings.chars", "문자" },
{ "hex.builtin.view.find.strings.lower_case", "소문자" },
{ "hex.builtin.view.find.strings.upper_case", "대문자" },
{ "hex.builtin.view.find.strings.numbers", "숫자" },
{ "hex.builtin.view.find.strings.underscores", "언더스코어" },
{ "hex.builtin.view.find.strings.symbols", "특수 문자" },
{ "hex.builtin.view.find.strings.spaces", "공백 문자" },
{ "hex.builtin.view.find.strings.line_feeds", "라인 피드" },
{ "hex.builtin.view.find.sequences", "텍스트 시퀸스" },
{ "hex.builtin.view.find.regex", "정규식" },
// { "hex.builtin.view.find.regex.pattern", "Pattern" },
// { "hex.builtin.view.find.regex.full_match", "Require full match" },
{ "hex.builtin.view.find.binary_pattern", "바이너리 패턴" },
{ "hex.builtin.view.find.search", "검색" },
{ "hex.builtin.view.find.context.copy", "값 복사" },
{ "hex.builtin.view.find.context.copy_demangle", "Copy Demangled Value" },
{ "hex.builtin.view.find.search.entries", "{} 개 검색됨" },
// { "hex.builtin.view.find.search.reset", "Reset" },
{ "hex.builtin.command.calc.desc", "계산기" },
{ "hex.builtin.command.cmd.desc", "명령" },
{ "hex.builtin.command.cmd.result", "명령 실행 '{0}'" },
{ "hex.builtin.command.web.desc", "웹사이트 탐색" },
{ "hex.builtin.command.web.result", "웹사이트 이동 '{0}'" },
{ "hex.builtin.inspector.binary", "Binary (8 bit)" },
{ "hex.builtin.inspector.u8", "uint8_t" },
{ "hex.builtin.inspector.i8", "int8_t" },
{ "hex.builtin.inspector.u16", "uint16_t" },
{ "hex.builtin.inspector.i16", "int16_t" },
{ "hex.builtin.inspector.u24", "uint24_t" },
{ "hex.builtin.inspector.i24", "int24_t" },
{ "hex.builtin.inspector.u32", "uint32_t" },
{ "hex.builtin.inspector.i32", "int32_t" },
{ "hex.builtin.inspector.u48", "uint48_t" },
{ "hex.builtin.inspector.i48", "int48_t" },
{ "hex.builtin.inspector.u64", "uint64_t" },
{ "hex.builtin.inspector.i64", "int64_t" },
{ "hex.builtin.inspector.float16", "half float (16 bit)" },
{ "hex.builtin.inspector.float", "float (32 bit)" },
{ "hex.builtin.inspector.double", "double (64 bit)" },
{ "hex.builtin.inspector.long_double", "long double (128 bit)" },
{ "hex.builtin.inspector.sleb128", "Signed LEB128" },
{ "hex.builtin.inspector.uleb128", "Unsigned LEB128" },
{ "hex.builtin.inspector.bool", "bool" },
{ "hex.builtin.inspector.ascii", "ASCII Character" },
{ "hex.builtin.inspector.wide", "Wide Character" },
{ "hex.builtin.inspector.utf8", "UTF-8 code point" },
{ "hex.builtin.inspector.string", "String" },
{ "hex.builtin.inspector.time32", "time32_t" },
{ "hex.builtin.inspector.time64", "time64_t" },
{ "hex.builtin.inspector.time", "time_t" },
{ "hex.builtin.inspector.dos_date", "DOS Date" },
{ "hex.builtin.inspector.dos_time", "DOS Time" },
{ "hex.builtin.inspector.guid", "GUID" },
{ "hex.builtin.inspector.rgba8", "RGBA8 Color" },
{ "hex.builtin.inspector.rgb565", "RGB565 Color" },
{ "hex.builtin.nodes.common.input", "Input" },
{ "hex.builtin.nodes.common.input.a", "Input A" },
{ "hex.builtin.nodes.common.input.b", "Input B" },
{ "hex.builtin.nodes.common.output", "Output" },
{ "hex.builtin.nodes.constants", "상수" },
{ "hex.builtin.nodes.constants.int", "정수" },
{ "hex.builtin.nodes.constants.int.header", "정수" },
{ "hex.builtin.nodes.constants.float", "실수" },
{ "hex.builtin.nodes.constants.float.header", "실수" },
{ "hex.builtin.nodes.constants.nullptr", "Nullptr" },
{ "hex.builtin.nodes.constants.nullptr.header", "Nullptr" },
{ "hex.builtin.nodes.constants.buffer", "버퍼" },
{ "hex.builtin.nodes.constants.buffer.header", "버퍼" },
{ "hex.builtin.nodes.constants.buffer.size", "크기" },
{ "hex.builtin.nodes.constants.string", "문자열" },
{ "hex.builtin.nodes.constants.string.header", "문자열" },
{ "hex.builtin.nodes.constants.rgba8", "RGBA8 색상" },
{ "hex.builtin.nodes.constants.rgba8.header", "RGBA8 색상" },
{ "hex.builtin.nodes.constants.rgba8.output.r", "Red" },
{ "hex.builtin.nodes.constants.rgba8.output.g", "Green" },
{ "hex.builtin.nodes.constants.rgba8.output.b", "Blue" },
{ "hex.builtin.nodes.constants.rgba8.output.a", "Alpha" },
{ "hex.builtin.nodes.constants.comment", "주석" },
{ "hex.builtin.nodes.constants.comment.header", "주석" },
{ "hex.builtin.nodes.display", "디스플레이" },
{ "hex.builtin.nodes.display.int", "정수" },
{ "hex.builtin.nodes.display.int.header", "정수 디스플레이" },
{ "hex.builtin.nodes.display.int.input", "" },
{ "hex.builtin.nodes.display.float", "실수" },
{ "hex.builtin.nodes.display.float.header", "실수 디스플레이" },
{ "hex.builtin.nodes.display.float.input", "" },
{ "hex.builtin.nodes.data_access", "데이터 접근" },
{ "hex.builtin.nodes.data_access.read", "읽기" },
{ "hex.builtin.nodes.data_access.read.header", "읽기" },
{ "hex.builtin.nodes.data_access.read.address", "주소" },
{ "hex.builtin.nodes.data_access.read.size", "크기" },
{ "hex.builtin.nodes.data_access.read.data", "데이터" },
{ "hex.builtin.nodes.data_access.write", "쓰기" },
{ "hex.builtin.nodes.data_access.write.header", "쓰기" },
{ "hex.builtin.nodes.data_access.write.address", "주소" },
{ "hex.builtin.nodes.data_access.write.data", "데이터" },
{ "hex.builtin.nodes.data_access.size", "데이터 크기"},
{ "hex.builtin.nodes.data_access.size.header", "데이터 크기"},
{ "hex.builtin.nodes.data_access.size.size", "크기"},
{ "hex.builtin.nodes.data_access.selection", "선택한 영역"},
{ "hex.builtin.nodes.data_access.selection.header", "선택한 영역"},
{ "hex.builtin.nodes.data_access.selection.address", "주소"},
{ "hex.builtin.nodes.data_access.selection.size", "크기"},
{ "hex.builtin.nodes.casting", "데이터 변환" },
{ "hex.builtin.nodes.casting.int_to_buffer", "정수에서 버퍼로" },
{ "hex.builtin.nodes.casting.int_to_buffer.header", "정수에서 버퍼로" },
{ "hex.builtin.nodes.casting.buffer_to_int", "버퍼에서 정수로" },
{ "hex.builtin.nodes.casting.buffer_to_int.header", "버퍼에서 정수로" },
{ "hex.builtin.nodes.arithmetic", "수학" },
{ "hex.builtin.nodes.arithmetic.add", "덧셈" },
{ "hex.builtin.nodes.arithmetic.add.header", "덧셈" },
{ "hex.builtin.nodes.arithmetic.sub", "뺄셈" },
{ "hex.builtin.nodes.arithmetic.sub.header", "뺄셈" },
{ "hex.builtin.nodes.arithmetic.mul", "곱셈" },
{ "hex.builtin.nodes.arithmetic.mul.header", "곱셈" },
{ "hex.builtin.nodes.arithmetic.div", "나눗셈" },
{ "hex.builtin.nodes.arithmetic.div.header", "나눗셈" },
{ "hex.builtin.nodes.arithmetic.mod", "나머지" },
{ "hex.builtin.nodes.arithmetic.mod.header", "나머지" },
{ "hex.builtin.nodes.buffer", "버퍼" },
{ "hex.builtin.nodes.buffer.combine", "합치기" },
{ "hex.builtin.nodes.buffer.combine.header", "버퍼 합치기" },
{ "hex.builtin.nodes.buffer.slice", "자르기" },
{ "hex.builtin.nodes.buffer.slice.header", "버퍼 자르기" },
{ "hex.builtin.nodes.buffer.slice.input.buffer", "입력" },
{ "hex.builtin.nodes.buffer.slice.input.from", "시작" },
{ "hex.builtin.nodes.buffer.slice.input.to", "" },
{ "hex.builtin.nodes.buffer.repeat", "출력" },
{ "hex.builtin.nodes.buffer.repeat.header", "버퍼 반복" },
{ "hex.builtin.nodes.buffer.repeat.input.count", "개수" },
{ "hex.builtin.nodes.control_flow", "데이터 플로우" },
{ "hex.builtin.nodes.control_flow.if", "If" },
{ "hex.builtin.nodes.control_flow.if.header", "If" },
{ "hex.builtin.nodes.control_flow.if.condition", "조건" },
{ "hex.builtin.nodes.control_flow.if.true", "True" },
{ "hex.builtin.nodes.control_flow.if.false", "False" },
{ "hex.builtin.nodes.control_flow.equals", "Equals" },
{ "hex.builtin.nodes.control_flow.equals.header", "Equals" },
{ "hex.builtin.nodes.control_flow.not", "Not" },
{ "hex.builtin.nodes.control_flow.not.header", "Not" },
{ "hex.builtin.nodes.control_flow.gt", "Greater than" },
{ "hex.builtin.nodes.control_flow.gt.header", "Greater than" },
{ "hex.builtin.nodes.control_flow.lt", "Less than" },
{ "hex.builtin.nodes.control_flow.lt.header", "Less than" },
{ "hex.builtin.nodes.control_flow.and", "AND" },
{ "hex.builtin.nodes.control_flow.and.header", "Boolean AND" },
{ "hex.builtin.nodes.control_flow.or", "OR" },
{ "hex.builtin.nodes.control_flow.or.header", "Boolean OR" },
{ "hex.builtin.nodes.bitwise", "비트 연산" },
{ "hex.builtin.nodes.bitwise.and", "AND" },
{ "hex.builtin.nodes.bitwise.and.header", "논리 AND" },
{ "hex.builtin.nodes.bitwise.or", "OR" },
{ "hex.builtin.nodes.bitwise.or.header", "논리 OR" },
{ "hex.builtin.nodes.bitwise.xor", "XOR" },
{ "hex.builtin.nodes.bitwise.xor.header", "논리 XOR" },
{ "hex.builtin.nodes.bitwise.not", "NOT" },
{ "hex.builtin.nodes.bitwise.not.header", "논리 NOT" },
{ "hex.builtin.nodes.decoding", "디코딩" },
{ "hex.builtin.nodes.decoding.base64", "Base64" },
{ "hex.builtin.nodes.decoding.base64.header", "Base64 디코더" },
{ "hex.builtin.nodes.decoding.hex", "16진수" },
{ "hex.builtin.nodes.decoding.hex.header", "16진수 decoder" },
{ "hex.builtin.nodes.crypto", "암호학" },
{ "hex.builtin.nodes.crypto.aes", "AES 복호화" },
{ "hex.builtin.nodes.crypto.aes.header", "AES 복호화" },
{ "hex.builtin.nodes.crypto.aes.key", "" },
{ "hex.builtin.nodes.crypto.aes.iv", "IV" },
{ "hex.builtin.nodes.crypto.aes.nonce", "논스" },
{ "hex.builtin.nodes.crypto.aes.mode", "모드" },
{ "hex.builtin.nodes.crypto.aes.key_length", "Key 길이" },
{ "hex.builtin.nodes.visualizer", "시작화" },
{ "hex.builtin.nodes.visualizer.digram", "다이어그램" },
{ "hex.builtin.nodes.visualizer.digram.header", "다이어그램" },
{ "hex.builtin.nodes.visualizer.layered_dist", "계층적 분포" },
{ "hex.builtin.nodes.visualizer.layered_dist.header", "계층적 분포" },
{ "hex.builtin.nodes.visualizer.image", "이미지" },
{ "hex.builtin.nodes.visualizer.image.header", "이미지 시각화" },
{ "hex.builtin.nodes.visualizer.byte_distribution", "바이트 분포" },
{ "hex.builtin.nodes.visualizer.byte_distribution.header", "바이트 분포" },
{ "hex.builtin.tools.demangler", "LLVM Demangler" },
{ "hex.builtin.tools.demangler.mangled", "Mangled name" },
{ "hex.builtin.tools.demangler.demangled", "Demangled name" },
{ "hex.builtin.tools.ascii_table", "ASCII 테이블" },
{ "hex.builtin.tools.ascii_table.octal", "8진수 표시" },
{ "hex.builtin.tools.regex_replacer", "정규식 변환기" },
{ "hex.builtin.tools.regex_replacer.pattern", "정규식 패턴" },
{ "hex.builtin.tools.regex_replacer.replace", "교체할 패턴" },
{ "hex.builtin.tools.regex_replacer.input", "입력" },
{ "hex.builtin.tools.regex_replacer.output", "출력" },
{ "hex.builtin.tools.color", "컬러 피커" },
{ "hex.builtin.tools.calc", "계산기" },
{ "hex.builtin.tools.input", "입력" },
{ "hex.builtin.tools.format.standard", "표준" },
{ "hex.builtin.tools.format.scientific", "공학용" },
{ "hex.builtin.tools.format.engineering", "엔지니어링" },
{ "hex.builtin.tools.format.programmer", "프로그래머" },
{ "hex.builtin.tools.error", "마지막 에러: '{0}'" },
{ "hex.builtin.tools.history", "이력" },
{ "hex.builtin.tools.name", "이름" },
{ "hex.builtin.tools.value", "" },
{ "hex.builtin.tools.base_converter", "진수 변환기" },
{ "hex.builtin.tools.base_converter.dec", "DEC" },
{ "hex.builtin.tools.base_converter.hex", "HEX" },
{ "hex.builtin.tools.base_converter.oct", "OCT" },
{ "hex.builtin.tools.base_converter.bin", "BIN" },
{ "hex.builtin.tools.permissions", "UNIX 권한 계산기" },
{ "hex.builtin.tools.permissions.perm_bits", "권한 비트" },
{ "hex.builtin.tools.permissions.absolute", "절대값" },
{ "hex.builtin.tools.permissions.setuid_error", "Setuid bit를 적용하기 위한 올바른 유저 권한이 필요합니다!" },
{ "hex.builtin.tools.permissions.setgid_error", "Setgid bit를 적용하기 위한 올바른 그룹 권한이 필요합니다!" },
{ "hex.builtin.tools.permissions.sticky_error", "Sticky bit를 적용하기 위한 올바른 기타 권한이 필요합니다!" },
{ "hex.builtin.tools.file_uploader", "파일 업로더" },
{ "hex.builtin.tools.file_uploader.control", "컨트롤" },
{ "hex.builtin.tools.file_uploader.upload", "업로드" },
{ "hex.builtin.tools.file_uploader.done", "완료!" },
{ "hex.builtin.tools.file_uploader.recent", "최근 업로드" },
{ "hex.builtin.tools.file_uploader.tooltip", "클릭해 복사,\nCTRL + 클릭으로 열기" },
{ "hex.builtin.tools.file_uploader.invalid_response", "Anonfiles에서 잘못된 응답이 왔습니다!" },
{ "hex.builtin.tools.file_uploader.error", "파일 업로드 실패!\n\n에러 코드: {0}" },
{ "hex.builtin.tools.wiki_explain", "Wikipedia 용어 정의" },
{ "hex.builtin.tools.wiki_explain.control", "컨트롤" },
{ "hex.builtin.tools.wiki_explain.search", "검색" },
{ "hex.builtin.tools.wiki_explain.results", "결과" },
{ "hex.builtin.tools.wiki_explain.invalid_response", "Wikipedia에서 잘못된 응답이 왔습니다!" },
{ "hex.builtin.tools.file_tools", "파일 도구" },
{ "hex.builtin.tools.file_tools.shredder", "완전 삭제 도구" },
{ "hex.builtin.tools.file_tools.shredder.warning", "이 도구는 복구할 수 없도록 파일을 제거합니다. 주의하세요." },
{ "hex.builtin.tools.file_tools.shredder.input", "삭제할 파일 " },
{ "hex.builtin.tools.file_tools.shredder.picker", "삭제할 파일을 선택하세요." },
{ "hex.builtin.tools.file_tools.shredder.fast", "빠른 삭제" },
{ "hex.builtin.tools.file_tools.shredder.shredding", "삭제 중..." },
{ "hex.builtin.tools.file_tools.shredder.shred", "삭제 완료" },
{ "hex.builtin.tools.file_tools.shredder.error.open", "파일을 여는데 실패했습니다!" },
{ "hex.builtin.tools.file_tools.shredder.success", "삭제을 완료했습니다!" },
{ "hex.builtin.tools.file_tools.splitter", "분리 도구" },
{ "hex.builtin.tools.file_tools.splitter.sizes.5_75_floppy", "\" 플로피 디스크 (1200KiB)" },
{ "hex.builtin.tools.file_tools.splitter.sizes.3_5_floppy", "\" 플로피 디스크 (1400KiB)" },
{ "hex.builtin.tools.file_tools.splitter.sizes.zip100", "Zip 100 디스크 (100MiB)" },
{ "hex.builtin.tools.file_tools.splitter.sizes.zip200", "Zip 200 디스크 (200MiB)" },
{ "hex.builtin.tools.file_tools.splitter.sizes.cdrom650", "CD-ROM (650MiB)" },
{ "hex.builtin.tools.file_tools.splitter.sizes.cdrom700", "CD-ROM (700MiB)" },
{ "hex.builtin.tools.file_tools.splitter.sizes.fat32", "FAT32 (4GiB)" },
{ "hex.builtin.tools.file_tools.splitter.sizes.custom", "Custom" },
{ "hex.builtin.tools.file_tools.splitter.input", "분리할 파일 " },
{ "hex.builtin.tools.file_tools.splitter.picker.input", "분리할 파일을 선택하세요" },
{ "hex.builtin.tools.file_tools.splitter.output", "저장 경로 " },
{ "hex.builtin.tools.file_tools.splitter.picker.output", "저장 경로를 선택하세요" },
{ "hex.builtin.tools.file_tools.splitter.picker.splitting", "분리 중..." },
{ "hex.builtin.tools.file_tools.splitter.picker.split", "분리" },
{ "hex.builtin.tools.file_tools.splitter.picker.error.open", "파일을 여는데 실패했습니다!" },
{ "hex.builtin.tools.file_tools.splitter.picker.error.size", "파일이 분리할 크기보다 작습니다" },
{ "hex.builtin.tools.file_tools.splitter.picker.error.create", "파일 조각 {0}를 만드는 데 실패했습니다" },
{ "hex.builtin.tools.file_tools.splitter.picker.success", "파일 분리를 완료했습니다!" },
{ "hex.builtin.tools.file_tools.combiner", "병합 도구" },
{ "hex.builtin.tools.file_tools.combiner.add", "추가..." },
{ "hex.builtin.tools.file_tools.combiner.add.picker", "파일 추가" },
{ "hex.builtin.tools.file_tools.combiner.delete", "삭제" },
{ "hex.builtin.tools.file_tools.combiner.clear", "비우기" },
{ "hex.builtin.tools.file_tools.combiner.output", "저장 경로 " },
{ "hex.builtin.tools.file_tools.combiner.output.picker", "저장 경로를 선택하세요" },
{ "hex.builtin.tools.file_tools.combiner.combining", "병합 중..." },
{ "hex.builtin.tools.file_tools.combiner.combine", "병합" },
{ "hex.builtin.tools.file_tools.combiner.error.open_output", "출력 파일을 여는 데 실패했습니다!" },
{ "hex.builtin.tools.file_tools.combiner.open_input", "입력 파일 {0}을 열지 못했습니다" },
{ "hex.builtin.tools.file_tools.combiner.success", "파일 병합을 완료했습니다!" },
{ "hex.builtin.tools.ieee756", "IEEE 756 부동 소수점 테스트" },
{ "hex.builtin.tools.ieee756.sign", "부포" },
{ "hex.builtin.tools.ieee756.exponent", "지수부" },
{ "hex.builtin.tools.ieee756.mantissa", "가수부" },
{ "hex.builtin.tools.ieee756.exponent_size", "지수부 크기" },
{ "hex.builtin.tools.ieee756.mantissa_size", "가수부 크기" },
{ "hex.builtin.tools.ieee756.half_precision", "Half Precision" },
{ "hex.builtin.tools.ieee756.singe_precision", "Single Precision" },
{ "hex.builtin.tools.ieee756.double_precision", "Double Precision" },
{ "hex.builtin.tools.ieee756.type", "종류" },
{ "hex.builtin.tools.ieee756.formula", "공식" },
{ "hex.builtin.tools.ieee756.result.title", "결과" },
{ "hex.builtin.tools.ieee756.result.float", "부동 소수점 결과" },
{ "hex.builtin.tools.ieee756.result.hex", "16진수 결과" },
{ "hex.builtin.setting.imhex", "ImHex" },
{ "hex.builtin.setting.imhex.recent_files", "최근 파일" },
{ "hex.builtin.setting.general", "일반" },
{ "hex.builtin.setting.general.show_tips", "시작 시 팁 표시" },
{ "hex.builtin.setting.general.auto_load_patterns", "지원하는 패턴 자동으로 로드" },
{ "hex.builtin.setting.general.sync_pattern_source", "공급자 간 패턴 소스 코드 동기화" },
{ "hex.builtin.setting.interface", "인터페이스" },
{ "hex.builtin.setting.interface.color", "색상 테마" },
{ "hex.builtin.setting.interface.color.system", "시스템" },
{ "hex.builtin.setting.interface.color.dark", "다크" },
{ "hex.builtin.setting.interface.color.light", "라이트" },
{ "hex.builtin.setting.interface.color.classic", "클래식" },
{ "hex.builtin.setting.interface.scaling", "크기" },
{ "hex.builtin.setting.interface.scaling.native", "기본" },
{ "hex.builtin.setting.interface.scaling.x0_5", "x0.5" },
{ "hex.builtin.setting.interface.scaling.x1_0", "x1.0" },
{ "hex.builtin.setting.interface.scaling.x1_5", "x1.5" },
{ "hex.builtin.setting.interface.scaling.x2_0", "x2.0" },
{ "hex.builtin.setting.interface.scaling.x3_0", "x3.0" },
{ "hex.builtin.setting.interface.scaling.x4_0", "x4.0" },
{ "hex.builtin.setting.interface.language", "언어" },
{ "hex.builtin.setting.interface.wiki_explain_language", "Wikipedia 언어" },
{ "hex.builtin.setting.interface.fps", "FPS 제한" },
{ "hex.builtin.setting.interface.fps.unlocked", "제한 없음" },
{ "hex.builtin.setting.hex_editor", "헥스 편집기" },
{ "hex.builtin.setting.hex_editor.highlight_color", "선택 영역 색상 하이라이트" },
{ "hex.builtin.setting.hex_editor.bytes_per_row", "한 줄당 바이트 수" },
{ "hex.builtin.setting.hex_editor.ascii", "ASCII 열 표시" },
{ "hex.builtin.setting.hex_editor.advanced_decoding", "추가 디코딩 열 표시" },
{ "hex.builtin.setting.hex_editor.grey_zeros", "00을 회색으로 표시" },
{ "hex.builtin.setting.hex_editor.uppercase_hex", "16진수 값을 대문자로 표시" },
{ "hex.builtin.setting.hex_editor.visualizer", "데이터 표시" },
{ "hex.builtin.setting.folders", "폴더" },
{ "hex.builtin.setting.folders.description", "패턴, 스크립트, YARA 규칙 등을 찾아볼 추가적인 폴더 경로를 지정하세요" },
{ "hex.builtin.setting.folders.add_folder", "새 폴더 추가" },
{ "hex.builtin.setting.folders.remove_folder", "선택한 폴더를 리스트에서 제거" },
{ "hex.builtin.setting.font", "글꼴" },
{ "hex.builtin.setting.font.font_path", "사용자 지정 글꼴 경로" },
{ "hex.builtin.setting.font.font_size", "글꼴 크기" },
{ "hex.builtin.setting.proxy", "프록시" },
{ "hex.builtin.setting.proxy.description", "프록시는 스토어, wikipedia, 그리고 추가적인 플러그인에 즉시 적용이 됩니다." },
{ "hex.builtin.setting.proxy.enable", "Proxy 활성화" },
{ "hex.builtin.setting.proxy.url", "Proxy 경로" },
{ "hex.builtin.setting.proxy.url.tooltip", "http(s):// 혹은 socks5:// (예., http://127.0.0.1:1080)" },
{ "hex.builtin.provider.file", "파일 공급자" },
{ "hex.builtin.provider.file.path", "파일 경로" },
{ "hex.builtin.provider.file.size", "크기" },
{ "hex.builtin.provider.file.creation", "생성 시각" },
{ "hex.builtin.provider.file.access", "마지막 접근 시각" },
{ "hex.builtin.provider.file.modification", "마지막 수정 시각" },
{ "hex.builtin.provider.gdb", "GDB 서버 공급자" },
{ "hex.builtin.provider.gdb.name", "GDB 서버 <{0}:{1}>" },
{ "hex.builtin.provider.gdb.server", "서버" },
{ "hex.builtin.provider.gdb.ip", "IP 주소" },
{ "hex.builtin.provider.gdb.port", "포트" },
{ "hex.builtin.provider.disk", "Raw 디스크 공급자" },
{ "hex.builtin.provider.disk.selected_disk", "디스크" },
{ "hex.builtin.provider.disk.disk_size", "디스크 크기" },
{ "hex.builtin.provider.disk.sector_size", "섹터 크기" },
{ "hex.builtin.provider.disk.reload", "새로 고침" },
{ "hex.builtin.provider.intel_hex", "Intel Hex 공급자" },
{ "hex.builtin.provider.intel_hex.name", "Intel Hex {0}" },
{ "hex.builtin.provider.motorola_srec", "Motorola SREC 공급자" },
{ "hex.builtin.provider.motorola_srec.name", "Motorola SREC {0}" },
{ "hex.builtin.layouts.default", "기본 값" },
{ "hex.builtin.visualizer.hexadecimal.8bit", "16진수 (8 비트)" },
{ "hex.builtin.visualizer.hexadecimal.16bit", "16진수 (16 비트)" },
{ "hex.builtin.visualizer.hexadecimal.32bit", "16진수 (32 비트)" },
{ "hex.builtin.visualizer.hexadecimal.64bit", "16진수 (64 비트)" },
{ "hex.builtin.visualizer.decimal.signed.8bit", "부호 있는 10진수 (8 비트)" },
{ "hex.builtin.visualizer.decimal.signed.16bit", "부호 있는 10진수 (16 비트)" },
{ "hex.builtin.visualizer.decimal.signed.32bit", "부호 있는 10진수 (32 비트)" },
{ "hex.builtin.visualizer.decimal.signed.64bit", "부호 있는 10진수 (64 비트)" },
{ "hex.builtin.visualizer.decimal.unsigned.8bit", "부호 없는 10진수 (8 비트)" },
{ "hex.builtin.visualizer.decimal.unsigned.16bit", "부호 없는 10진수 (16 비트)" },
{ "hex.builtin.visualizer.decimal.unsigned.32bit", "부호 없는 10진수 (32 비트)" },
{ "hex.builtin.visualizer.decimal.unsigned.64bit", "부호 없는 10진수 (64 비트)" },
{ "hex.builtin.visualizer.floating_point.32bit", "부동소수점 (32 비트)" },
{ "hex.builtin.visualizer.floating_point.64bit", "부동소수점 (64 비트)" },
{ "hex.builtin.visualizer.hexii", "HexII" },
{ "hex.builtin.visualizer.rgba8", "RGBA8 색상" },
{ "hex.builtin.hash.md5", "MD5" },
{ "hex.builtin.hash.sha1", "SHA1" },
{ "hex.builtin.hash.sha224", "SHA224" },
{ "hex.builtin.hash.sha256", "SHA256" },
{ "hex.builtin.hash.sha384", "SHA384" },
{ "hex.builtin.hash.sha512", "SHA512" },
{ "hex.builtin.hash.crc8", "CRC8" },
{ "hex.builtin.hash.crc16", "CRC16" },
{ "hex.builtin.hash.crc32", "CRC32" },
{ "hex.builtin.hash.crc.poly", "Polynomial" },
{ "hex.builtin.hash.crc.iv", "Initial Value" },
{ "hex.builtin.hash.crc.xor_out", "XOR Out" },
{ "hex.builtin.hash.crc.refl_in", "Reflect In" },
{ "hex.builtin.hash.crc.refl_out", "Reflect Out" },
});
}
}

View File

@@ -38,7 +38,7 @@ namespace hex::plugin::builtin {
{ "hex.builtin.welcome.learn.latest.link", "https://github.com/WerWolv/ImHex/releases/latest" },
{ "hex.builtin.welcome.learn.pattern.title", "Documentação da linguagem padrão" },
{ "hex.builtin.welcome.learn.pattern.desc", "Aprenda a escrever padrões ImHex com nossa extensa documentação" },
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs/pattern_language/pattern_language.html" },
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs" },
{ "hex.builtin.welcome.learn.plugins.title", "Plugins API" },
{ "hex.builtin.welcome.learn.plugins.desc", "Estenda o ImHex com recursos adicionais usando plugins" },
{ "hex.builtin.welcome.learn.plugins.link", "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide" },
@@ -101,8 +101,10 @@ namespace hex::plugin::builtin {
{ "hex.builtin.popup.error.read_only", "Não foi possível obter acesso de gravação. Arquivo aberto no modo somente leitura." },
{ "hex.builtin.popup.error.open", "Falha ao abrir o arquivo!" },
{ "hex.builtin.popup.error.create", "Falha ao criar um novo arquivo!" },
//{ "hex.builtin.popup.error.task_exception", "Exception thrown in Task '{}':\n\n{}" },
{ "hex.builtin.menu.file", "File" },
//{ "hex.builtin.menu.file.create_file", "New File..." },
{ "hex.builtin.menu.file.open_file", "Abrir Arquivo..." },
{ "hex.builtin.menu.file.open_recent", "Abrir Recentes" },
{ "hex.builtin.menu.file.clear_recent", "Limpar" },
@@ -285,6 +287,7 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.hex_editor.menu.edit.copy", "Copiar" },
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "Copiar como..." },
{ "hex.builtin.view.hex_editor.copy.hex", "String" },
//{ "hex.builtin.view.hex_editor.copy.address", "Address" },
{ "hex.builtin.view.hex_editor.copy.c", "C Array" },
{ "hex.builtin.view.hex_editor.copy.cpp", "C++ Array" },
{ "hex.builtin.view.hex_editor.copy.csharp", "C# Array" },
@@ -292,7 +295,13 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.hex_editor.copy.python", "Python Array" },
{ "hex.builtin.view.hex_editor.copy.java", "Java Array" },
{ "hex.builtin.view.hex_editor.copy.js", "JavaScript Array" },
{ "hex.builtin.view.hex_editor.copy.ascii", "ASCII Art" },
{ "hex.builtin.view.hex_editor.copy.lua", "Lua Array" },
{ "hex.builtin.view.hex_editor.copy.go", "Go Array" },
{ "hex.builtin.view.hex_editor.copy.crystal", "Crystal Array" },
{ "hex.builtin.view.hex_editor.copy.swift", "Swift Array" },
{ "hex.builtin.view.hex_editor.copy.pascal", "Pascal Array" },
{ "hex.builtin.view.hex_editor.copy.base64", "Base64" },
//{ "hex.builtin.view.hex_editor.copy.ascii", "Text Area" },
{ "hex.builtin.view.hex_editor.copy.html", "HTML" },
{ "hex.builtin.view.hex_editor.menu.edit.paste", "Colar" },
{ "hex.builtin.view.hex_editor.menu.edit.select_all", "Selecionar tudo" },
@@ -414,11 +423,14 @@ namespace hex::plugin::builtin {
// { "hex.builtin.view.find.strings.line_feeds", "Line Feeds" },
// { "hex.builtin.view.find.sequences", "Sequences" },
// { "hex.builtin.view.find.regex", "Regex" },
// { "hex.builtin.view.find.regex.pattern", "Pattern" },
// { "hex.builtin.view.find.regex.full_match", "Require full match" },
// { "hex.builtin.view.find.binary_pattern", "Binary Pattern" },
// { "hex.builtin.view.find.search", "Search" },
// { "hex.builtin.view.find.context.copy", "Copy Value" },
// { "hex.builtin.view.find.context.copy_demangle", "Copy Demangled Value" },
// { "hex.builtin.view.find.search.entries", "{} entries found" },
// { "hex.builtin.view.find.search.reset", "Reset" },
{ "hex.builtin.command.calc.desc", "Calculadora" },
{ "hex.builtin.command.cmd.desc", "Comando" },

View File

@@ -38,7 +38,7 @@ namespace hex::plugin::builtin {
{ "hex.builtin.welcome.learn.latest.link", "https://github.com/WerWolv/ImHex/releases/latest" },
{ "hex.builtin.welcome.learn.pattern.title", "模式文档" },
{ "hex.builtin.welcome.learn.pattern.desc", "如何基于我们完善的文档编写 ImHex 模式" },
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs/pattern_language/pattern_language.html" },
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs" },
{ "hex.builtin.welcome.learn.plugins.title", "插件 API" },
{ "hex.builtin.welcome.learn.plugins.desc", "通过插件扩展 ImHex 获得更多功能" },
{ "hex.builtin.welcome.learn.plugins.link", "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide" },
@@ -81,13 +81,13 @@ namespace hex::plugin::builtin {
{ "hex.builtin.common.browse", "浏览..." },
{ "hex.builtin.common.choose_file", "选择文件" },
{ "hex.builtin.common.processing", "处理" },
//{ "hex.builtin.common.filter", "Filter" },
//{ "hex.builtin.common.value", "Value" },
{ "hex.builtin.common.filter", "过滤器" },
{ "hex.builtin.common.value", "" },
{ "hex.builtin.common.offset", "偏移" },
//{ "hex.builtin.common.range", "Range" },
//{ "hex.builtin.common.range.entire_data", "Entire Data" },
//{ "hex.builtin.common.range.selection", "Selection" },
//{ "hex.builtin.common.comment", "Comment" },
{ "hex.builtin.common.range", "范围" },
{ "hex.builtin.common.range.entire_data", "所有数据" },
{ "hex.builtin.common.range.selection", "选区" },
{ "hex.builtin.common.comment", "注释" },
{ "hex.builtin.common.encoding.ascii", "ASCII" },
{ "hex.builtin.common.encoding.utf16le", "UTF-16LE" },
@@ -96,13 +96,15 @@ namespace hex::plugin::builtin {
{ "hex.builtin.popup.exit_application.title", "退出?" },
{ "hex.builtin.popup.exit_application.desc", "工程还有未保存的更改。\n确定要退出吗?" },
//{ "hex.builtin.popup.close_provider.title", "Close Provider?" },
//{ "hex.builtin.popup.close_provider.desc", "You have unsaved changes made to this Provider.\nAre you sure you want to close it?" },
{ "hex.builtin.popup.close_provider.title", "关闭提供器?" },
{ "hex.builtin.popup.close_provider.desc", "有对此提供器做出的未保存的更改。\n你确定要关闭吗?" },
{ "hex.builtin.popup.error.read_only", "无法获得写权限,文件以只读方式打开。" },
{ "hex.builtin.popup.error.open", "打开文件失败!" },
{ "hex.builtin.popup.error.create", "创建新文件失败!" },
{ "hex.builtin.popup.error.task_exception", "任务 '{}' 异常:\n\n{}" },
{ "hex.builtin.menu.file", "文件" },
{ "hex.builtin.menu.file.create_file", "新建文件..." },
{ "hex.builtin.menu.file.open_file", "打开文件..." },
{ "hex.builtin.menu.file.open_recent", "最近打开" },
{ "hex.builtin.menu.file.clear_recent", "清除" },
@@ -123,8 +125,8 @@ namespace hex::plugin::builtin {
{ "hex.builtin.menu.file.export.ips32", "IPS32 补丁" },
{ "hex.builtin.menu.file.export.base64.popup.export_error", "文件不是有效的 Base64 格式!" },
{ "hex.builtin.menu.file.export.popup.create", "无法导出文件。文件创建失败!" },
//{ "hex.builtin.menu.file.bookmark.import", "Import bookmarks" },
//{ "hex.builtin.menu.file.bookmark.export", "Export bookmarks" },
{ "hex.builtin.menu.file.bookmark.import", "导入书签" },
{ "hex.builtin.menu.file.bookmark.export", "导出书签" },
{ "hex.builtin.menu.edit", "编辑" },
{ "hex.builtin.menu.edit.undo", "撤销" },
@@ -277,17 +279,18 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.hex_editor.goto.offset.relative", "相对" },
{ "hex.builtin.view.hex_editor.goto.offset.begin", "起始" },
{ "hex.builtin.view.hex_editor.goto.offset.end", "末尾" },
//{ "hex.builtin.view.hex_editor.menu.file.select", "Select" },
// { "hex.builtin.view.hex_editor.select.offset.region", "Region" },
// { "hex.builtin.view.hex_editor.select.offset.begin", "Begin" },
// { "hex.builtin.view.hex_editor.select.offset.end", "End" },
// { "hex.builtin.view.hex_editor.select.offset.size", "Size" },
// { "hex.builtin.view.hex_editor.select.select", "Select" },
{ "hex.builtin.view.hex_editor.menu.file.select", "选择" },
{ "hex.builtin.view.hex_editor.select.offset.region", "区域" },
{ "hex.builtin.view.hex_editor.select.offset.begin", "起始" },
{ "hex.builtin.view.hex_editor.select.offset.end", "结束" },
{ "hex.builtin.view.hex_editor.select.offset.size", "大小" },
{ "hex.builtin.view.hex_editor.select.select", "选择" },
{ "hex.builtin.view.hex_editor.menu.file.save", "保存" },
{ "hex.builtin.view.hex_editor.menu.file.save_as", "另存为..." },
{ "hex.builtin.view.hex_editor.menu.edit.copy", "复制" },
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "复制为..." },
{ "hex.builtin.view.hex_editor.copy.hex", "字符串" },
{ "hex.builtin.view.hex_editor.copy.address", "地址" },
{ "hex.builtin.view.hex_editor.copy.c", "C 数组" },
{ "hex.builtin.view.hex_editor.copy.cpp", "C++ 数组" },
{ "hex.builtin.view.hex_editor.copy.csharp", "C# 数组" },
@@ -295,7 +298,13 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.hex_editor.copy.python", "Python 数组" },
{ "hex.builtin.view.hex_editor.copy.java", "Java 数组" },
{ "hex.builtin.view.hex_editor.copy.js", "JavaScript 数组" },
{ "hex.builtin.view.hex_editor.copy.ascii", "Hex DumpASCII 艺术)" },
{ "hex.builtin.view.hex_editor.copy.lua", "Lua 数组" },
{ "hex.builtin.view.hex_editor.copy.go", "Go 数组" },
{ "hex.builtin.view.hex_editor.copy.crystal", "Crystal 数组" },
{ "hex.builtin.view.hex_editor.copy.swift", "Swift 数组" },
{ "hex.builtin.view.hex_editor.copy.pascal", "Pascal 数组" },
{ "hex.builtin.view.hex_editor.copy.base64", "Base64" },
//{ "hex.builtin.view.hex_editor.copy.ascii", "Text Area" },
{ "hex.builtin.view.hex_editor.copy.html", "HTML" },
{ "hex.builtin.view.hex_editor.menu.edit.paste", "粘贴" },
{ "hex.builtin.view.hex_editor.menu.edit.select_all", "全选" },
@@ -398,30 +407,33 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.provider_settings.name", "提供器设置" },
{ "hex.builtin.view.provider_settings.load_popup", "打开提供器" },
// { "hex.builtin.view.provider_settings.load_error", "An error occurred while trying to open this provider!"},
{ "hex.builtin.view.provider_settings.load_error", "尝试打开此提供器时出现错误"},
//{ "hex.builtin.view.find.name", "Find" },
// { "hex.builtin.view.find.searching", "Searching..." },
// { "hex.builtin.view.find.demangled", "Demangled" },
// { "hex.builtin.view.find.strings", "Strings" },
// { "hex.builtin.view.find.strings.min_length", "Minimum length" },
// { "hex.builtin.view.find.strings.match_settings", "Match Settings" },
// { "hex.builtin.view.find.strings.null_term", "Require Null Termination" },
// { "hex.builtin.view.find.strings.chars", "Characters" },
// { "hex.builtin.view.find.strings.lower_case", "Lower case letters" },
// { "hex.builtin.view.find.strings.upper_case", "Upper case letters" },
// { "hex.builtin.view.find.strings.numbers", "Numbers" },
// { "hex.builtin.view.find.strings.underscores", "Underscores" },
// { "hex.builtin.view.find.strings.symbols", "Symbols" },
// { "hex.builtin.view.find.strings.spaces", "Spaces" },
// { "hex.builtin.view.find.strings.line_feeds", "Line Feeds" },
// { "hex.builtin.view.find.sequences", "Sequences" },
// { "hex.builtin.view.find.regex", "Regex" },
// { "hex.builtin.view.find.binary_pattern", "Binary Pattern" },
// { "hex.builtin.view.find.search", "Search" },
// { "hex.builtin.view.find.context.copy", "Copy Value" },
// { "hex.builtin.view.find.context.copy_demangle", "Copy Demangled Value" },
// { "hex.builtin.view.find.search.entries", "{} entries found" },
{ "hex.builtin.view.find.name", "查找" },
{ "hex.builtin.view.find.searching", "搜索中..." },
{ "hex.builtin.view.find.demangled", "还原名" },
{ "hex.builtin.view.find.strings", "字符串" },
{ "hex.builtin.view.find.strings.min_length", "最短长度" },
{ "hex.builtin.view.find.strings.match_settings", "配置设置" },
{ "hex.builtin.view.find.strings.null_term", "需要NULL终止" },
{ "hex.builtin.view.find.strings.chars", "字符" },
{ "hex.builtin.view.find.strings.lower_case", "小写字母" },
{ "hex.builtin.view.find.strings.upper_case", "大写字母" },
{ "hex.builtin.view.find.strings.numbers", "数字" },
{ "hex.builtin.view.find.strings.underscores", "下划线" },
{ "hex.builtin.view.find.strings.symbols", "符号" },
{ "hex.builtin.view.find.strings.spaces", "空格" },
{ "hex.builtin.view.find.strings.line_feeds", "换行" },
{ "hex.builtin.view.find.sequences", "序列" },
{ "hex.builtin.view.find.regex", "正则表达式" },
// { "hex.builtin.view.find.regex.pattern", "Pattern" },
// { "hex.builtin.view.find.regex.full_match", "Require full match" },
{ "hex.builtin.view.find.binary_pattern", "二进制模式" },
{ "hex.builtin.view.find.search", "搜索" },
{ "hex.builtin.view.find.context.copy", "复制值" },
{ "hex.builtin.view.find.context.copy_demangle", "复制值的还原名" },
{ "hex.builtin.view.find.search.entries", "{} 个结果" },
// { "hex.builtin.view.find.search.reset", "Reset" },
{ "hex.builtin.command.calc.desc", "计算器" },
{ "hex.builtin.command.cmd.desc", "指令" },
@@ -429,8 +441,7 @@ namespace hex::plugin::builtin {
{ "hex.builtin.command.web.desc", "网站解析" },
{ "hex.builtin.command.web.result", "导航到 '{0}'" },
// Use half width symbols for inspector names because displayable space
{ "hex.builtin.inspector.binary", "二进制(8位)" },
{ "hex.builtin.inspector.binary", "二进制8 位)" },
{ "hex.builtin.inspector.u8", "uint8_t" },
{ "hex.builtin.inspector.i8", "int8_t" },
{ "hex.builtin.inspector.u16", "uint16_t" },
@@ -443,12 +454,12 @@ namespace hex::plugin::builtin {
{ "hex.builtin.inspector.i48", "int48_t" },
{ "hex.builtin.inspector.u64", "uint64_t" },
{ "hex.builtin.inspector.i64", "int64_t" },
{ "hex.builtin.inspector.float16", "半精度浮点(16位)" },
{ "hex.builtin.inspector.float", "float(32位单精度)" },
{ "hex.builtin.inspector.double", "double(64位双精度)" },
{ "hex.builtin.inspector.long_double", "long double(128位四精度)" },
//{ "hex.builtin.inspector.sleb128", "Signed LEB128" },
//{ "hex.builtin.inspector.uleb128", "Unsigned LEB128" },
{ "hex.builtin.inspector.float16", "half float16 位)" },
{ "hex.builtin.inspector.float", "float32 位)" },
{ "hex.builtin.inspector.double", "double64 位)" },
{ "hex.builtin.inspector.long_double", "long double128 位)" },
{ "hex.builtin.inspector.sleb128", "有符号LEB128" },
{ "hex.builtin.inspector.uleb128", "无符号LEB128" },
{ "hex.builtin.inspector.bool", "bool" },
{ "hex.builtin.inspector.ascii", "ASCII 字符" },
{ "hex.builtin.inspector.wide", "宽字符" },
@@ -707,7 +718,7 @@ namespace hex::plugin::builtin {
{ "hex.builtin.setting.general", "通用" },
{ "hex.builtin.setting.general.show_tips", "在启动时显示每日提示" },
{ "hex.builtin.setting.general.auto_load_patterns", "自动加载支持的模式" },
// { "hex.builtin.setting.general.sync_pattern_source", "Sync pattern source code between providers" },
{ "hex.builtin.setting.general.sync_pattern_source", "在提供器间同步模式源码" },
{ "hex.builtin.setting.interface", "界面" },
{ "hex.builtin.setting.interface.color", "颜色主题" },
{ "hex.builtin.setting.interface.color.system", "跟随系统" },
@@ -763,10 +774,10 @@ namespace hex::plugin::builtin {
{ "hex.builtin.provider.disk.disk_size", "磁盘大小" },
{ "hex.builtin.provider.disk.sector_size", "扇区大小" },
{ "hex.builtin.provider.disk.reload", "刷新" },
//{ "hex.builtin.provider.intel_hex", "Intel Hex Provider" },
// { "hex.builtin.provider.intel_hex.name", "Intel Hex {0}" },
//{ "hex.builtin.provider.motorola_srec", "Motorola SREC Provider" },
// { "hex.builtin.provider.motorola_srec.name", "Motorola SREC {0}" },
{ "hex.builtin.provider.intel_hex", "Intel Hex" },
{ "hex.builtin.provider.intel_hex.name", "Intel Hex {0}" },
{ "hex.builtin.provider.motorola_srec", "Motorola SREC" },
{ "hex.builtin.provider.motorola_srec.name", "Motorola SREC {0}" },
{ "hex.builtin.layouts.default", "默认" },

View File

@@ -38,7 +38,7 @@ namespace hex::plugin::builtin {
{ "hex.builtin.welcome.learn.latest.link", "https://github.com/WerWolv/ImHex/releases/latest" },
{ "hex.builtin.welcome.learn.pattern.title", "模式語言說明文件" },
{ "hex.builtin.welcome.learn.pattern.desc", " 閱覽我們詳盡的說明文件來學習如何編寫 ImHex 的模式" },
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs/pattern_language/pattern_language.html" },
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs" },
{ "hex.builtin.welcome.learn.plugins.title", "外掛程式 API" },
{ "hex.builtin.welcome.learn.plugins.desc", " 使用外掛程式來拓展 ImHex 的功能" },
{ "hex.builtin.welcome.learn.plugins.link", "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide" },
@@ -101,8 +101,10 @@ namespace hex::plugin::builtin {
{ "hex.builtin.popup.error.read_only", "無法取得寫入權限。檔案已以唯讀模式開啟。" },
{ "hex.builtin.popup.error.open", "無法開啟檔案!" },
{ "hex.builtin.popup.error.create", "無法建立新檔案!" },
//{ "hex.builtin.popup.error.task_exception", "Exception thrown in Task '{}':\n\n{}" },
{ "hex.builtin.menu.file", "檔案" },
//{ "hex.builtin.menu.file.create_file", "New File..." },
{ "hex.builtin.menu.file.open_file", "開啟檔案..." },
{ "hex.builtin.menu.file.open_recent", "開啟近期" },
{ "hex.builtin.menu.file.clear_recent", "清除" },
@@ -285,6 +287,7 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.hex_editor.menu.edit.copy", "複製" },
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "複製為..." },
{ "hex.builtin.view.hex_editor.copy.hex", "字串" },
//{ "hex.builtin.view.hex_editor.copy.address", "Address" },
{ "hex.builtin.view.hex_editor.copy.c", "C 陣列" },
{ "hex.builtin.view.hex_editor.copy.cpp", "C++ 陣列" },
{ "hex.builtin.view.hex_editor.copy.csharp", "C# 陣列" },
@@ -292,7 +295,13 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.hex_editor.copy.python", "Python 陣列" },
{ "hex.builtin.view.hex_editor.copy.java", "Java 陣列" },
{ "hex.builtin.view.hex_editor.copy.js", "JavaScript 陣列" },
{ "hex.builtin.view.hex_editor.copy.ascii", "ASCII 畫" },
{ "hex.builtin.view.hex_editor.copy.lua", "Lua 陣列" },
{ "hex.builtin.view.hex_editor.copy.go", "Go 陣列" },
{ "hex.builtin.view.hex_editor.copy.crystal", "Crystal 陣列" },
{ "hex.builtin.view.hex_editor.copy.swift", "Swift 陣列" },
{ "hex.builtin.view.hex_editor.copy.pascal", "Pascal 陣列" },
{ "hex.builtin.view.hex_editor.copy.base64", "Base64" },
// { "hex.builtin.view.hex_editor.copy.ascii", "Text Area" },
{ "hex.builtin.view.hex_editor.copy.html", "HTML" },
{ "hex.builtin.view.hex_editor.menu.edit.paste", "貼上" },
{ "hex.builtin.view.hex_editor.menu.edit.select_all", "全選" },
@@ -415,11 +424,14 @@ namespace hex::plugin::builtin {
// { "hex.builtin.view.find.strings.line_feeds", "Line Feeds" },
// { "hex.builtin.view.find.sequences", "Sequences" },
// { "hex.builtin.view.find.regex", "Regex" },
// { "hex.builtin.view.find.regex.pattern", "Pattern" },
// { "hex.builtin.view.find.regex.full_match", "Require full match" },
// { "hex.builtin.view.find.binary_pattern", "Binary Pattern" },
// { "hex.builtin.view.find.search", "Search" },
// { "hex.builtin.view.find.context.copy", "Copy Value" },
// { "hex.builtin.view.find.context.copy_demangle", "Copy Demangled Value" },
// { "hex.builtin.view.find.search.entries", "{} entries found" },
// { "hex.builtin.view.find.search.reset", "Reset" },
{ "hex.builtin.command.calc.desc", "計算機" },
{ "hex.builtin.command.cmd.desc", "命令" },

View File

@@ -34,6 +34,7 @@ namespace hex::plugin::builtin {
void registerLanguageZhCN();
void registerLanguagePtBR();
void registerLanguageZhTW();
void registerLanguageKoKR();
}
IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") {
@@ -47,6 +48,7 @@ IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") {
registerLanguageZhCN();
registerLanguagePtBR();
registerLanguageZhTW();
registerLanguageKoKR();
registerEventHandlers();
registerDataVisualizers();

View File

@@ -11,10 +11,11 @@ if (WIN32)
source/views/view_tty_console.cpp
source/lang/en_US.cpp
source/lang/de_DE.cpp
source/lang/zh_CN.cpp
source/lang/en_US.cpp
source/lang/ko_KR.cpp
source/lang/pt_BR.cpp
source/lang/zh_CN.cpp
source/lang/zh_TW.cpp
source/content/ui_items.cpp

View File

@@ -0,0 +1,35 @@
#include <hex/api/content_registry.hpp>
#include <hex/api/localization.hpp>
namespace hex::plugin::windows {
void registerLanguageKoKR() {
ContentRegistry::Language::addLocalizations("ko-KR", {
{ "hex.windows.title_bar_button.feedback", "피드백 남기기" },
{ "hex.windows.title_bar_button.debug_build", "디버그 빌드"},
{ "hex.windows.view.tty_console.name", "TTY 콘솔" },
{ "hex.windows.view.tty_console.config", "설정"},
{ "hex.windows.view.tty_console.port", "포트" },
{ "hex.windows.view.tty_console.reload", "새로 고침" },
{ "hex.windows.view.tty_console.baud", "Baud rate" },
{ "hex.windows.view.tty_console.num_bits", "Data bits" },
{ "hex.windows.view.tty_console.stop_bits", "Stop bits" },
{ "hex.windows.view.tty_console.parity_bits", "Parity bit" },
{ "hex.windows.view.tty_console.cts", "Use CTS flow control" },
{ "hex.windows.view.tty_console.connect", "연결" },
{ "hex.windows.view.tty_console.disconnect", "연결 끊기" },
{ "hex.windows.view.tty_console.connect_error", "COM 포트 연결에 실패했습니다!" },
{ "hex.windows.view.tty_console.no_available_port", "선택한 COM 포트가 올바르지 않거나 COM 포트가 존재하지 않습니다!" },
{ "hex.windows.view.tty_console.clear", "지우기" },
{ "hex.windows.view.tty_console.auto_scroll", "자동 스크롤" },
{ "hex.windows.view.tty_console.console", "콘솔" },
{ "hex.windows.view.tty_console.send_etx", "ETX 보내기" },
{ "hex.windows.view.tty_console.send_eot", "EOT 보내기" },
{ "hex.windows.view.tty_console.send_sub", "SUB 보내기" },
{ "hex.builtin.setting.general.context_menu_entry", "Windows 컨텍스트 메뉴 항목" },
});
}
}

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