diff --git a/.github/git/git-help.md b/.github/git/git-help.md
index 9505f465..61ad99df 100644
--- a/.github/git/git-help.md
+++ b/.github/git/git-help.md
@@ -44,6 +44,32 @@ To remove the effects of `git add .` and `git commit -m "test"` or just `git add
git reset --soft HEAD~1
```
+To remove **all uncommitted and untracked changes** in Git and reset your working tree to the last commit:
+
+```bash
+git reset --hard
+git clean -fd
+```
+
+To modify the last pushed commit:
+
+```bash
+# Undo the last commit but keep the changes in your working tree
+git reset --soft HEAD~1
+
+# Make your additional modifications
+# edit files...
+
+# Stage everything
+git add .
+
+# Create a new commit
+git commit -m "Updated commit message"
+
+# Force-push to replace the remote commit
+git push --force-with-lease
+```
+
---------------
## Releasing instructions
diff --git a/.github/workflows/vs2022.yml b/.github/workflows/vs2022.yml
index 287cf15e..aa834a05 100644
--- a/.github/workflows/vs2022.yml
+++ b/.github/workflows/vs2022.yml
@@ -1,26 +1,31 @@
name: vs2022-ci
on:
- push:
- branches:
- - master
- - dev
- tags:
- - 'v*'
- paths-ignore:
- - '.gitignore'
- - '.gitattributes'
- - '**.cmd'
- - '**.bat'
- - '**.md'
-
- pull_request:
- paths-ignore:
- - '.gitignore'
- - '.gitattributes'
- - '**.cmd'
- - '**.bat'
- - '**.md'
+ workflow_dispatch:
+
+# Disabled, uncomment the below line and remove the above lines to activate
+# on:
+# push:
+# branches:
+# - master
+# - dev
+# tags:
+# - 'v*'
+# paths-ignore:
+# - '.gitignore'
+# - '.gitattributes'
+# - '**.cmd'
+# - '**.bat'
+# - '**.md'
+#
+# pull_request:
+# paths-ignore:
+# - '.gitignore'
+# - '.gitattributes'
+# - '**.cmd'
+# - '**.bat'
+# - '**.md'
+
env:
# WDK for Windows 11, version 22H2
WDK_URL: https://go.microsoft.com/fwlink/?linkid=2196230
@@ -73,7 +78,7 @@ jobs:
# working-directory: ${{env.GITHUB_WORKSPACE}}
# run: msbuild /m /p:Configuration="Release MT" /p:Platform=${{matrix.PLATFORM}} /target:zydis /target:zycore /p:OutDir=${{ github.workspace }}/hyperdbg/libraries/zydis/ ${{ github.workspace }}/hyperdbg/dependencies/zydis/msvc/Zydis.sln
- - name: Build Hyperdbg solution
+ - name: Build HyperDbg solution
working-directory: ${{env.GITHUB_WORKSPACE}}
run: msbuild /m /p:Configuration=${{matrix.BUILD_CONFIGURATION}} /p:Platform=${{matrix.PLATFORM}} ${{env.SOLUTION_FILE_PATH}}
diff --git a/.github/workflows/vs2026.yml b/.github/workflows/vs2026.yml
new file mode 100644
index 00000000..0e587b16
--- /dev/null
+++ b/.github/workflows/vs2026.yml
@@ -0,0 +1,99 @@
+name: vs2026-ci
+
+on:
+ push:
+ branches:
+ - '**' # matches all branch names, including ones with slashes
+ tags:
+ - 'v*'
+ paths-ignore:
+ - '.gitignore'
+ - '.gitattributes'
+ - '**.cmd'
+ - '**.bat'
+ - '**.md'
+
+ pull_request:
+ paths-ignore:
+ - '.gitignore'
+ - '.gitattributes'
+ - '**.cmd'
+ - '**.bat'
+ - '**.md'
+
+env:
+ SOLUTION_FILE_PATH: ./hyperdbg/hyperdbg.sln
+ RELEASE_ZIP_FILE_NAME: hyperdbg
+ BUILD_BIN_DIR: ./hyperdbg/build/bin/
+
+jobs:
+ win-amd64-build:
+ runs-on: windows-2025-vs2026
+ strategy:
+ matrix:
+ BUILD_CONFIGURATION: [release, debug]
+ PLATFORM: [x64]
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ submodules: recursive
+
+ - name: Checkout submodules recursively
+ run: git submodule update --init --recursive --remote
+
+ - name: Add MSBuild to PATH
+ uses: microsoft/setup-msbuild@v3
+
+ - name: Setup NuGet
+ uses: NuGet/setup-nuget@v2
+
+ - name: Restore NuGet packages
+ run: nuget restore ${{ env.SOLUTION_FILE_PATH }}
+
+ - name: Setup Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: '3.x'
+
+ - name: Update vcxproj files
+ run: python utils/replace-sdk-wdk.py
+
+ - name: Build HyperDbg solution
+ working-directory: ${{env.GITHUB_WORKSPACE}}
+ run: msbuild /m /p:Configuration=${{matrix.BUILD_CONFIGURATION}} /p:Platform=${{matrix.PLATFORM}} ${{env.SOLUTION_FILE_PATH}}
+
+ - name: Upload build directory
+ uses: actions/upload-artifact@v4.4.0
+ with:
+ name: build_files_${{matrix.BUILD_CONFIGURATION}}
+ path: ${{ env.BUILD_BIN_DIR }}
+
+ deploy-release:
+ name: Deploy release
+ needs: win-amd64-build
+ runs-on: windows-2025-vs2026
+ if: startsWith(github.ref, 'refs/tags/')
+ steps:
+ - name: Download build files from "build" job
+ uses: actions/download-artifact@v4.1.7
+ with:
+ name: build_files_release
+ path: ${{ env.BUILD_BIN_DIR }}
+
+ - name: Archive release
+ uses: thedoctor0/zip-release@master
+ with:
+ path: ${{ env.BUILD_BIN_DIR }}release/
+ type: 'zip'
+ filename: ${{env.RELEASE_ZIP_FILE_NAME}}-${{ github.ref_name }}.zip
+
+ - name: Release
+ uses: softprops/action-gh-release@v1
+ if: startsWith(github.ref, 'refs/tags/')
+ with:
+ files: |
+ ${{env.RELEASE_ZIP_FILE_NAME}}-${{ github.ref_name }}.zip
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitmodules b/.gitmodules
index 377dd15f..bc4340e1 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,15 +1,15 @@
-[submodule "hyperdbg/dependencies/ia32-doc"]
- path = hyperdbg/dependencies/ia32-doc
- url = https://github.com/HyperDbg/ia32-doc.git
-[submodule "hyperdbg/dependencies/zydis"]
- path = hyperdbg/dependencies/zydis
- url = https://github.com/HyperDbg/zydis.git
-[submodule "hyperdbg/dependencies/pdbex"]
- path = hyperdbg/dependencies/pdbex
- url = https://github.com/HyperDbg/pdbex.git
[submodule "hyperdbg/tests/script-engine-test"]
path = hyperdbg/tests/script-engine-test
url = https://github.com/HyperDbg/script-engine-test.git
[submodule "hyperdbg/miscellaneous/constants/pciid"]
path = hyperdbg/miscellaneous/constants/pciid
url = https://github.com/HyperDbg/pciids
+[submodule "hyperdbg/dependencies/ia32-doc"]
+ path = hyperdbg/dependencies/ia32-doc
+ url = https://github.com/HyperDbg/ia32-doc.git
+[submodule "hyperdbg/dependencies/pdbex"]
+ path = hyperdbg/dependencies/pdbex
+ url = https://github.com/HyperDbg/pdbex.git
+[submodule "hyperdbg/dependencies/zydis"]
+ path = hyperdbg/dependencies/zydis
+ url = https://github.com/HyperDbg/zydis.git
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2a3f785e..f4f7ddac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,192 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [0.21.0.0] - 2026-07-05
+New release of the HyperDbg Debugger.
+
+### Added
+- Added structure for the hyperperf (Hardware Performance Counter) project ([link](https://github.com/HyperDbg/HyperDbg/commit/c17ebc09c4d199a642352e66feebb3159582196c))
+- The 'unload' command checks whether any module is loaded or not ([link](https://docs.hyperdbg.org/commands/debugging-commands/unload))
+- Exported SDK API for checking whether any module is loaded or not ([link](https://github.com/HyperDbg/HyperDbg/commit/19e47c804f50f5dbb698f314e66b7d685a87ac1f))
+- Added user mode and kernel mode PT parameter parser ([link](https://github.com/HyperDbg/HyperDbg/pull/631))
+- Added thread (TID) and process (PID) helper functions for Intel PT ([link](https://github.com/HyperDbg/HyperDbg/pull/633))
+
+### Changed
+- Separated SDK libraries for user mode and kernel mode modules ([link](https://github.com/HyperDbg/HyperDbg/commit/c17ebc09c4d199a642352e66feebb3159582196c))
+- Added hypertrace, hyperevade, and hyperperf DLL files to SDK ([link](https://github.com/HyperDbg/HyperDbg/commit/c17ebc09c4d199a642352e66feebb3159582196c))
+- Fix pool manager uninitialize list corruption ([link](https://github.com/HyperDbg/HyperDbg/pull/629))
+- Fix 'access denied' error on loading all modules using 'load all' ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))([link](https://github.com/HyperDbg/HyperDbg/commit/2b818a5116d80d466aab7b343d4aa9d1d640f082))
+- Fix the concatenation error for the "hyperkd" string on the hypertrace project (https://github.com/HyperDbg/HyperDbg/commit/2b0cc18899ff532d9d590a71bf880fee5456c15f))
+- Organized header files for the libhyperdbg project ([link](https://github.com/HyperDbg/HyperDbg/pull/632))
+
+## [0.20.0.0-beta] - 2026-06-21
+New release of the HyperDbg Debugger.
+
+### Added
+- Added the libipt library to the project and the SDK
+- Added Intel Processor Trace (PT) example app
+- Added Linux distinction and pragmas together with new platform functions ([link](https://github.com/HyperDbg/HyperDbg/commit/9c3e0ed23b5f4bb64bd305e546dd0e86ee1910d9))
+- Added interfaces to Linux port for the serial devices ([link](https://github.com/HyperDbg/HyperDbg/commit/31b514f8df40d81d44ae07a2328c02360ce488c3))
+- Added platform IOCTL interface ([link](https://github.com/HyperDbg/HyperDbg/pull/619))
+- Added typecast for wchar, mismatch on Linux and Windows ([link](https://github.com/HyperDbg/HyperDbg/commit/10576b064a9824ab655e7bea0e35e9556ee68ca4))
+- Added missing IOCTLs for Intel PT ([link](https://github.com/HyperDbg/HyperDbg/commit/df12e9fd79851c8f378ec82a45066da510da507a))
+- Added NuGet packages for Windows SDK and WDK
+- Added Signal handler platform API for Linux ([link](https://github.com/HyperDbg/HyperDbg/pull/627))
+- Added contribution guidelines for Linux ([link](https://github.com/HyperDbg/HyperDbg/tree/master/hyperdbg/linux#readme))
+
+### Changed
+- Moved to Visual Studio 2026 ([link](https://github.com/HyperDbg/HyperDbg/pull/626))
+- Zydis and pdbex submodules are updated to VS2026
+- Fix the new form of loading and unloading in the example app and PT app ([link](https://github.com/HyperDbg/HyperDbg/commit/9ad48d30dcf6b409ae86b2d08262584cd06f606e))
+- Check whether the top-level hypervisor is Hyper-V and disable/enable VPIDs based on that, thanks to [@Idov31](https://github.com/Idov31) ([link](https://github.com/HyperDbg/HyperDbg/pull/625))
+- Fix PT operation IOCTL buffer size ([link](https://github.com/HyperDbg/HyperDbg/commit/dabf132d31503843f90949f35f8dce4601d43126))
+- CI/CD updated with NuGet packages for Visual Studio 2026 ([link](https://github.com/HyperDbg/HyperDbg/commit/5a0fad490124268550f955f594d1211d5c74f03d))
+
+## [0.19.0.0-beta] - 2026-06-10
+New release of the HyperDbg Debugger.
+
+### Added
+- First release of the HyperTrace module ([link](https://url.hyperdbg.org/hypertrace))
+- HyperTrace now enables/disables VM-entry/VM-exit controls for Load and Save IA32_DEBUGCTL MSR
+- Added Legacy LBR support to the HyperTrace module
+- Added Architectural LBR support to the HyperTrace module
+- Added the '!lbr' command for performing different Last Branch Record (LBR) operations ([link](https://docs.hyperdbg.org/commands/extension-commands/lbr))
+- Added the '!lbrdump' command for dumping saved Last Branch Record (LBR) entries ([link](https://docs.hyperdbg.org/commands/extension-commands/lbrdump))
+- Added **lbr_save()** and **lbr_print()** functions in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_save))([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_print))
+- Added mock application for compiling SDK for Linux
+- Added '!help' alias for the '.help' command
+- Added 'vm' alias for the 'load' command ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))
+- Added **lbr_check()** and **lbr_restore()** functions in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_check))([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_restore))
+- Added **lbr_restore_by_filter(filter)** function in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_restore_by_filter))
+- Added the 'kd' module in the 'load' command ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))
+- Added the 'trace' module in the 'load' command ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))
+- Exported SDK API for detecting CPU vendors
+- Initial codes for the HyperTrace project by using Intel Processor Trace (PT), thanks to [@masoudrahimi01](https://github.com/masoudrahimi01) ([link](https://github.com/HyperDbg/HyperDbg/pull/589))
+- Exported SDK APIs for loading and unloading the 'kd' and the 'trace' modules
+- Exported SDK APIs for starting (installing) the 'kd' driver
+- Exported SDK APIs for loading/unloading all modules
+- Added tests for checking PE parser in 'hyperdbg-test' project
+- Added example for loading HyperDbg in VMI mode directly from libhyperdbg
+- Fix action cleanup list removal in debugger events ([link](https://github.com/HyperDbg/HyperDbg/pull/601))
+- Added transparent-mode evade mask selection thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/602))
+- Added synthetic MSR handling thanks to [@Idov31](https://github.com/Idov31) ([link](https://github.com/HyperDbg/HyperDbg/pull/605))
+- Added use of relative RSDS fixture paths when loading PDB symbols, thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/607))
+
+### Changed
+- Fix the problem of not applying the EAX index in the CPUID event extension command ([link](https://docs.hyperdbg.org/commands/extension-commands/cpuid#parameters))
+- Refactoring the IOCTL parameter checks and status routines
+- All basic types are now defined for Linux
+- VMX instructions are ported to platform-independent files to support Linux
+- All CPU-related intrinsic instructions are ported to platform-independent files to support Linux
+- HyperDbg SDK now compiles on Linux (GCC) for both user-mode and kernel-mode
+- Fix the 'wrmsr' command IOCTL checks by receiving output in the buffer ([link](https://docs.hyperdbg.org/commands/debugging-commands/wrmsr))
+- Extensive refactoring of code base (doxygen, variables, function names)
+- Building certain modules on Linux and fixing CMake files thanks to [@maxraulea](https://github.com/maxraulea) ([link](https://github.com/HyperDbg/HyperDbg/pull/592))
+- Fix the '!hide' command's HyperEvade activation guard thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/593))
+- Fix synchronous debugger device IOCTL handles thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/595))
+- PE parser ('.pe' command) now supports richer DOS/NT/COFF/optional-header output, section bounds checking, data directory reporting, import/export parsing, TLS/debug/PDB/load-config metadata, overlay reporting, and malformed metadata warnings thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/598))([link](https://docs.hyperdbg.org/commands/meta-commands/.pe))
+- Building the script engine module on Linux (GCC) thanks to [@maxraulea](https://github.com/maxraulea) ([link](https://github.com/HyperDbg/HyperDbg/pull/596))
+- The pool manager moved from 'hyperhv' to 'hyperkd'
+- The 'load' command could load all modules using a new alias 'load all' ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))
+- The 'unload' command could remove all modules using two new aliases 'unload all' and 'unload remove all' ([link](https://docs.hyperdbg.org/commands/debugging-commands/unload))
+- Change device handle checks with module loading status checks for IOCTLs ([link](https://github.com/HyperDbg/HyperDbg/pull/610))
+- Fix standard callbacks for the VMM module ([link](https://github.com/HyperDbg/HyperDbg/pull/610))
+- Fix race condition bug within the pool manager
+
+## [0.18.1.0] - 2026-04-09
+New release of the HyperDbg Debugger.
+
+### Added
+- HyperTrace now works with HyperDbg VMM ([link](https://github.com/HyperDbg/HyperDbg/pull/568))
+- Progress on implementing Last Branch Recode (LBR) ([link](https://github.com/HyperDbg/HyperDbg/commit/1dd73675e9cd78737e013ffb35bc712f385f387e))
+- Applying LBR registers on the VMCS instead of the DEBUGCTL MSR ([link](https://github.com/HyperDbg/HyperDbg/commit/15f8b3cca15448acd18d7e198740464a19ce4fe2))
+
+### Changed
+- Fix the problem of the '!epthook' not finding the PML1 entry ([link](https://docs.hyperdbg.org/commands/extension-commands/epthook))
+- Fix the problem of getting the PML1 entry of the target address on Intel Core Ultra processors (#567) ([link](https://github.com/HyperDbg/HyperDbg/issues/567))
+- Fix the '.clang-format' formatting error
+- Restructure of the HyperTrace project
+- Add starting structure for supporting Intel Processor Trace (PT)
+
+## [0.18.0.0] - 2026-02-16
+New release of the HyperDbg Debugger.
+
+### Added
+- Script engine now supports writing libraries using the '#include' keyword thanks to [@xmaple555](https://github.com/xmaple555) ([link](https://docs.hyperdbg.org/commands/scripting-language/casting-and-inclusion))([link](https://github.com/HyperDbg/HyperDbg/issues/557))([link](https://github.com/HyperDbg/HyperDbg/pull/561))
+- Initial codes for the HyperTrace project by using Intel Last Branch Record (LBR) and Branch Trace Store (BTS) thanks to [@harimishal1](https://github.com/harimishal1) ([link](https://github.com/HyperDbg/HyperDbg/tree/master/hyperdbg/hypertrace))
+- The HyperTrace project is now linked to the hyperkd
+- Initial efforts to port HyperDbg to Linux have started thanks to [@Alish14](https://github.com/Alish14) ([link](https://github.com/HyperDbg/HyperDbg/pull/563))
+
+### Changed
+- Fix compilation error in Zydis with the new Windows WDK ([link](https://github.com/HyperDbg/zydis/commit/e61f59332ce49f8853006573ca853e404fafdd08))
+
+## [0.17.0.0] - 2025-11-10
+New release of the HyperDbg Debugger. All credit for this release goes to [@xmaple555](https://github.com/xmaple555).
+
+### Added
+- Added 1D and 2D arrays (multidimensional arrays) in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/variables-and-assignments#multidimensional-array))([link](https://github.com/HyperDbg/HyperDbg/pull/554))
+- Added compound assignments in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/variables-and-assignments#compound-assignment))([link](https://github.com/HyperDbg/HyperDbg/pull/554))
+- Added multiple assignments in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/variables-and-assignments#multiple-assignment))([link](https://github.com/HyperDbg/HyperDbg/pull/554))
+
+### Changed
+- Fix bugs for interpreting 'db_pa, 'dd_pa', 'eb_pa', and 'ed_pa' keywords in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/assumptions-and-evaluations#keywords))([link](https://github.com/HyperDbg/HyperDbg/pull/507))
+- Fix variable types in the script engine ([link](https://github.com/HyperDbg/HyperDbg/commit/43b0245fa11b5c73ce4cd21d8b8787b86a05f89d))
+- Fix and update array index for boolean expressions in the script engine ([link](https://github.com/HyperDbg/HyperDbg/commit/ba2cec3c12c3ff45ddc0004051884983ff62a0b3))
+
+## [0.16.0.0] - 2025-09-08
+New release of the HyperDbg Debugger.
+
+### Added
+- The **!xsetbv** event command was added for handling the execution of the XSETBV instruction, thanks to HyperDbg group members ([link](https://docs.hyperdbg.org/commands/extension-commands/xsetbv))
+- Display of the number of blocked context switches in the '.switch' command ([link](https://docs.hyperdbg.org/commands/meta-commands/.switch))
+- Added support for step-in (the 't' command) in the user debugger ([link](https://docs.hyperdbg.org/commands/debugging-commands/t))
+- Added support for step-over (the 'p' command) in the user debugger ([link](https://docs.hyperdbg.org/commands/debugging-commands/p))
+- Added support to show all registers or a specific register in the user debugger ([link](https://docs.hyperdbg.org/commands/debugging-commands/r))
+- Exported SDK API for running scripts in either the kernel debugger or the user debugger
+- Added support to modify registers or a specific register in the user debugger ([link](https://docs.hyperdbg.org/commands/debugging-commands/r))
+- Added support to evaluate (run) scripts on the target thread in the user debugger ([link](https://docs.hyperdbg.org/commands/debugging-commands/eval))
+- Added an indication of a thread's running or paused state to the HyperDbg signature in the user debugger ([link](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/signatures))
+- Added support for the '.formats' command in the user debugger ([link](https://docs.hyperdbg.org/commands/meta-commands/.formats))
+- Added support for interpreting parameters based on script engine expressions in the user debugger
+- Exported SDK API for evaluating expressions based on the context of the kernel debugger or the user debugger
+- Added a new mechanism for showing the 'printf' and the 'print' function messages in the user debugger ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/exports/printf))([link](https://docs.hyperdbg.org/commands/scripting-language/functions/exports/print))
+
+### Changed
+- Non-volatile XMM registers are no longer saved/restored on VM-exit handler ([link](https://learn.microsoft.com/en-us/cpp/build/x64-software-conventions?view=msvc-170))
+- Fix grammar and spelling errors throughout HyperDbg codebase ([link](https://github.com/HyperDbg/HyperDbg/pull/546))
+- Relocate extension command files into their corresponding VS directory
+- Fix infinite VM-exit bug for the '!monitor x' command thanks to [@unlockable](https://github.com/unlockable) ([link](https://github.com/HyperDbg/HyperDbg/pull/545))
+
+## [0.15.0.0] - 2025-08-18
+New release of the HyperDbg Debugger.
+
+### Added
+- Added the '!smi' command for performing operations related to System Management Interrupt (SMI) ([link](https://docs.hyperdbg.org/commands/extension-commands/smi))
+- Export the SDK functions for SMI operations ([link](https://docs.hyperdbg.org/commands/extension-commands/smi#sdk))
+- Check for Intel CET IBT (indirect branch tracking) support
+- Check for Intel CET shadow stack support
+- Added support to Intel CET for SYSCALL/SYSRET emulation ([link](https://docs.hyperdbg.org/commands/extension-commands/syscall))([link](https://docs.hyperdbg.org/commands/extension-commands/sysret))
+
+### Changed
+- The 'hyperhv' project now has build optimizations enabled
+- Reformat VMXOFF restoring routines to restore general-purpose and XMM registers correctly before moving to the previous stack
+- Fix unloading (VMXOFF) crash when restoring XMM registers
+- Fix the problem with restoring XMM registers (#468) ([link](https://github.com/HyperDbg/HyperDbg/issues/468))
+- Enhanced the '.pe' command to support PE Rich Headers thanks to [@Alish14](https://github.com/Alish14) ([link](https://github.com/HyperDbg/HyperDbg/pull/539))
+- Updated ia32-doc to fix VMCS PL3 SSP fields ([link](https://github.com/HyperDbg/ia32-doc))
+- Fix the terminating process issue of the '!syscall/!sysret' commands on 11 generation (Rocket Lake/Tiger Lake) and newer Intel processors ([link](https://github.com/HyperDbg/HyperDbg/issues/392))
+- Re-enable the support for the '.start' command in the Debugger mode ([link](https://docs.hyperdbg.org/commands/meta-commands/.start))
+- The '!mode' event command is now compatible with different EPT hook commands (e.g., !epthook, !epthook2, !monitor, .start, and .restart) ([link](https://docs.hyperdbg.org/commands/extension-commands/mode))
+- The '!mode' command doesn't need allocating extra EPTPs ([link](https://docs.hyperdbg.org/commands/extension-commands/mode))
+
+## [0.14.1.0] - 2025-07-27
+New release of the HyperDbg Debugger.
+
+### Changed
+- Restored the previous optimization on the release builds
+- Fixed the issue of not properly restoring registers after the 'CPUID' instruction
+- Fixed the building issues of the user debugger with the 'bp' and the '.start' commands
+
## [0.14.0.0] - 2025-07-23
New release of the HyperDbg Debugger.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8b980747..4b0d2c53 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -8,49 +8,13 @@ HyperDbg is a large-scale project that requires a lot of time and effort from th
Please make sure to create a [discussion](https://github.com/orgs/HyperDbg/discussions) or an [issue](https://github.com/HyperDbg/HyperDbg/issues), or even better, join the HyperDbg groups ([Telegram](https://t.me/HyperDbg), [Discord](https://discord.gg/anSPsGUtzN), [Matrix](https://matrix.to/#/#hyperdbg-discussion:matrix.org)) on social media. Discuss the way you want to implement your changes and inform developers, because we often see people simultaneously working on the same issue. To avoid this collision, make sure to inform us before you start developing.
+### Working on an Idea or a Task
+- We have a [wide range of ideas and tasks](https://github.com/orgs/HyperDbg/projects/2) that you might be interested in working on. You can choose a task and start working on it, and if you have any questions or need clarification, feel free to ask. This list will be updated frequently.
+
+### Other Things to Work on
- Writing blog posts and creating videos about use-cases of HyperDbg (make sure to add it to the [awesome](https://github.com/HyperDbg/awesome) repository).
- Fixing unresolved GitHub [issues](https://github.com/HyperDbg/HyperDbg/issues).
-- Troubleshooting problems with running on Hyper-V's nested virtualization.
-- Troubleshooting problems with running on VirtualBox's nested virtualization.
-- Supporting KDNET (sending data over the network).
-- Enhancing HyperDbg's [Transparent Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#transparent-mode), especially for anti-hypervisor methods.
-- Enhancing and adding more features to the ['.pe'](https://docs.hyperdbg.org/commands/meta-commands/.pe) command.
-- Adding HyperDbg to the system startup using UEFI.
-- Adding routines to activate and use Last Branch Record (LBR) and Branch Trace Store (BTS).
-- Creating a QT-based GUI.
-- Creating a SoftICE-style GUI.
-- Supporting nested-virtualization on HyperDbg itself.
-- Protecting HyperDbg code and memory from modification using VT-x capabilities.
-- Adding support for the Intel Processor Trace (PT).
-- Creating a wrapper that automatically interprets the [HyperDbg SDK](https://github.com/HyperDbg/HyperDbg/tree/master/hyperdbg/include/SDK) to GO, RUST, C#, Python, etc.
-- Creating syntax highlighting for dslang for different IDEs (VSCode, VIM, etc.).
-- Building HyperDbg using LLVM clang.
-- Helping us start supporting HyperDbg on Linux (discussion needed).
-- Helping us start supporting HyperDbg on AMD processors (discussion needed).
-- Adding digital (FPGA) modules to the hwdbg hardware debugger.
-- Creating a [ret-sync](https://github.com/bootleg/ret-sync) module for HyperDbg.
-- Adding fuzzing capabilities to HyperDbg (maybe integrating [AFL++](https://github.com/AFLplusplus/AFLplusplus) into HyperDbg).
-- Working on live memory migration and adding support for kernel-mode time travel debugging.
-- Integrating the [z3 project](https://github.com/Z3Prover/z3) into HyperDbg and adding commands based on the z3 solver.
-- Adding the [Bochs emulator](https://github.com/bochs-emu/Bochs) to HyperDbg.
-- ~~Creating commands to inspect and read details of PCIe devices.~~ Added: [link][link]
-- ~~Mitigating the anti-hypervisor method described [here](https://howtohypervise.blogspot.com/2019/01/a-common-missight-in-most-hypervisors.html).~~ [[Fixed](https://github.com/HyperDbg/HyperDbg/pull/497)]
-- Creating different examples of how to use the SDK (using different programming languages).
-- Debugging and fixing bugs related to HyperDbg's physical serial communication.
-- Reading symbol information from modules in memory (currently, HyperDbg opens a file which continues the debugger).
-- Adding APIC virtualization.
-- Reading the list of modules for the '[lm](https://docs.hyperdbg.org/commands/debugging-commands/lm)' command directly from kernel-mode.
-- Detecting and fixing anti-hypervisor methods described [here](https://github.com/Ahora57/MAJESTY-technologies).
-- Investigating why the symbols parser (DIA SDK) could not read symbols of the 'kernel32!*'.
-- ~~Fixing the problem with [XSETBV instruction freezing](https://github.com/HyperDbg/HyperDbg/issues/429).~~ [[Fixed](https://github.com/HyperDbg/HyperDbg/pull/491)]
-- Adding an event function that detects coverage.
-- Bypassing [al-khaser](https://github.com/LordNoteworthy/al-khaser).
-- Creating the 'alias' command that converts or registers scripts as a command, for example: "alias !list .script list.dbg" (discussion needed).
-- Adding support for [Hardware Performance Counters (HPC)](https://en.wikipedia.org/wiki/Hardware_performance_counter).
-
-- Any other interesting tasks you might find!
-
-This list will be updated frequently.
+- Any other interesting ideas you might find! (Let's have a discussion before working on them.)
## Fixing Bugs
diff --git a/CREDITS.md b/CREDITS.md
index a7990bf3..0d39ff7b 100644
--- a/CREDITS.md
+++ b/CREDITS.md
@@ -4,7 +4,7 @@ The list provided comprises individuals who have made significant contributions
## Credits:
-The attributions listed on this credits page are acknowledged without any particular order.
+Just so you know – the attributions listed on this credits page are acknowledged without any particular order.
- All of the [contributors](https://github.com/HyperDbg/HyperDbg/graphs/contributors)
- Sina Karvandi ([@Intel80x86](https://twitter.com/Intel80x86))
@@ -24,4 +24,7 @@ The attributions listed on this credits page are acknowledged without any partic
- xmaple555 ([@xmaple555](https://github.com/xmaple555)) for contributions in HyperDbg core and the script engine
- Abbas Masoumi Gorji ([@AbbasMasoumiG](https://twitter.com/AbbasMasoumiG))
- Björn Ruytenberg ([@0Xiphorus](https://twitter.com/0Xiphorus))
-- Marcis Zarins ([@CokeTree3](https://github.com/CokeTree3))
+- Marcis Zarins ([@CokeTree3](https://github.com/CokeTree3)) for his works on enhancing HyperEvade project
+- Artem Shishkin ([@honorary_bot](https://twitter.com/honorary_bot)) for always answering our hypervisor questions
+- unrustled.jimmies for helping us debug and fix issues, and his contributions in HyperDbg
+- Hari Mishal ([@harimishal1](https://github.com/harimishal1)) for his works on the hypertrace project for supporting Last Branch Record (LBR)
\ No newline at end of file
diff --git a/README.md b/README.md
index d7dcda15..fae0672e 100644
--- a/README.md
+++ b/README.md
@@ -6,11 +6,10 @@
-
# HyperDbg Debugger
-HyperDbg Debugger is an open-source, community-driven, hypervisor-assisted, user-mode, and kernel-mode Windows debugger with a focus on using modern hardware technologies. It is a debugger designed for analyzing, fuzzing, and reversing.
+**HyperDbg Debugger** is a free (as in free beer), open-source, community-driven, hypervisor-assisted, user-mode, and kernel-mode Windows debugger with a focus on using modern hardware technologies. It is a debugger designed for analyzing, fuzzing, and reversing.
You can follow **HyperDbg** on **[Twitter](https://twitter.com/HyperDbg)** or **[Mastodon](https://infosec.exchange/@hyperdbg)** to get notified about new releases, or join any of the HyperDbg groups, where you can ask developers and open-source reversing enthusiasts for help setting up and using HyperDbg.
@@ -23,12 +22,24 @@ You can follow **HyperDbg** on **[Twitter](https://twitter.com/HyperDbg)** or **
**HyperDbg** is designed with a focus on using modern hardware technologies to provide new features to the debuggers' world. It operates on top of Windows by virtualizing an already running system using Intel VT-x and EPT. This debugger aims not to use any APIs and software debugging mechanisms, but instead, it uses Second Layer Page Table (a.k.a. Extended Page Table or EPT) extensively to monitor both kernel and user executions.
-HyperDbg comes with features like hidden hooks, which are as fast as old inline hooks, but also stealth. It mimics hardware debug registers for (read & write) to a specific location, but this time entirely invisible for both Windows kernel and the programs, and of course, without any limitation in size or count!
+HyperDbg comes with features like hidden hooks, which are as fast as old inline hooks, but also stealth. It mimics hardware debug registers for (read & write) to a specific location, but this time invisible for both the Windows kernel and the programs, and of course, without any limitation in size or count!
-Using TLB-splitting, and having features such as measuring code coverage and monitoring all mov(s) to/from memory by a function, makes HyperDbg a unique debugger.
+Using TLB-splitting and having features such as measuring code coverage and monitoring all mov(s) to/from memory by a function, makes HyperDbg a unique debugger.
Although it has novel features, HyperDbg tries to be as stealthy as possible. It doesn’t use any debugging APIs to debug Windows or any application, so classic anti-debugging methods won’t detect it. Also, it resists the exploitation of time delta methods (e.g., RDTSC/RDTSCP) to detect the presence of hypervisors, therefore making it much harder for applications, packers, protectors, malware, anti-cheat engines, etc. to discover the debugger.
+## Why HyperDbg?
+
+HyperDbg is harder to set up and use, and also requires deeper low-level system knowledge compared to traditional debuggers. However, it provides two major advantages:
+
+1. **Full System & OS Control**
+HyperDbg operates at the hypervisor level, giving you powerful capabilities that are simply not possible with classic debuggers. This allows you to leverage hardware-assisted [features](https://github.com/HyperDbg/HyperDbg?tab=readme-ov-file#unique-features) for advanced reverse engineering and debugging scenarios.
+
+2. **Stealth & Detection Resistance**
+Since HyperDbg doesn't rely on standard OS debugging APIs, it is generally much harder (though not impossible) to detect. This makes it a strong choice when working against anti-debugging protections.
+
+These advantages open up entirely new debugging and reverse engineering techniques that go beyond what conventional debuggers can offer.
+
## Build & Installation
You can download the latest compiled binary files from **[releases](https://github.com/HyperDbg/HyperDbg/releases)**; otherwise, if you want to build HyperDbg, you should clone HyperDbg with the `--recursive` flag.
@@ -62,26 +73,67 @@ In case you use one of **HyperDbg**'s components in your work, please consider c
Other paper built upon HyperDbg...
-
-**2. [The Reversing Machine: Reconstructing Memory Assumptions](https://arxiv.org/pdf/2405.00298)** [[arXiv](https://arxiv.org/abs/2405.00298)]
+**2. [hwdbg: Debugging Hardware Like Software (EuroSec'25)](https://dl.acm.org/doi/abs/10.1145/3722041.3723101)** [[PDF](https://dl.acm.org/doi/pdf/10.1145/3722041.3723101)]
```
-@article{karvandi2024reversing,
- title={The Reversing Machine: Reconstructing Memory Assumptions},
- author={Karvandi, Mohammad Sina and Meghdadizanjani, Soroush and Arasteh, Sima and Monfared, Saleh Khalaj and Fallah, Mohammad K and Gorgin, Saeid and Lee, Jeong-A and van der Kouwe, Erik},
- journal={arXiv preprint arXiv:2405.00298},
- year={2024}
+@inproceedings{karvandi2025hwdbg,
+ title={hwdbg: Debugging Hardware Like Software},
+ author={Karvandi, Mohammad Sina and Meghdadizanjani, Soroush and Monfared, Saleh Khalaj and van der Kouwe, Erik and Slowinska, Asia},
+ booktitle={Proceedings of the 18th European Workshop on Systems Security},
+ pages={56--62},
+ year={2025}
}
```
+
+**3. [HyperEvade: Countering Anti-Debugging Techniques and Enhancing Transparency in Nested Virtualization using HyperDbg (DEBT'25)](https://www.jot.fm/contents/issue_2026_01/a8.html)** [[PDF](https://www.jot.fm/issues/issue_2026_01/a8.pdf)]
+
+```
+@article{ruytenberg2026hyperevade,
+ title={HyperEvade: Countering Anti-Debugging Techniques and Enhancing Transparency in Nested Virtualization using HyperDbg},
+ author={Ruytenberg, Bj{\"o}rn and Karvandi, Mohammad Sina},
+ journal={Journal of Object Technology},
+ volume={25},
+ number={1},
+ pages={1--3},
+ year={2026},
+ publisher={Association Internationale pour les Technologies Objets}
+}
+```
+
+**4. [Digital Hole: Bypassing Commercial Audio DRM Solutions with DReaMcatcher (EuroSys'26)](https://dl.acm.org/doi/abs/10.1145/3767295.3803583)** [[PDF](https://dl.acm.org/doi/pdf/10.1145/3767295.3803583)]
+
+```
+@inproceedings{ruytenberg2026digital,
+ title={Digital Hole: Bypassing Commercial Audio DRM Solutions with DReaMcatcher},
+ author={Ruytenberg, Bj{\"o}rn and Karvandi, Mohammad Sina and Bos, Herbert and van der Kouwe, Erik and Slowinska, Asia},
+ booktitle={Proceedings of the 21st European Conference on Computer Systems},
+ pages={484--496},
+ year={2026}
+}
+```
+
+**5. [TRM: An Efficient Hypervisor-Based Framework For Malware Analysis and Memory Reconstruction (AsiaCCS'26)](https://dl.acm.org/doi/10.1145/3779208.3785293)** [[PDF](https://dl.acm.org/doi/pdf/10.1145/3779208.3785293)]
+
+```
+@inproceedings{karvandi2026trm,
+ title={TRM: An Efficient Hypervisor-Based Framework For Malware Analysis and Memory Reconstruction},
+ author={Karvandi, Mohammad Sina and Meghdadizanjani, Soroush and Arasteh, Sima and Monfared, Saleh Khalaj and Fallah, Mohammad K and Gorgin, Saeid and Lee, Jeong-A and Slowinska, Asia and van der Kouwe, Erik},
+ booktitle={Proceedings of the ACM Asia Conference on Computer and Communications Security},
+ pages={68--82},
+ year={2026}
+}
+```
+
You can also read [this article](https://research.hyperdbg.org/debugger/kernel-debugger-design/) as it describes the overall architecture, technical difficulties, design decisions, and internals of HyperDbg Debugger, [this article](https://research.hyperdbg.org/vmm/transparency/) about our efforts on vm-exit transparency, [this article](https://research.hyperdbg.org/debugger/chasing-bugs/) about chasing bugs within hypervisors, and [this article](https://research.hyperdbg.org/debugger/gaining-insights/) about new reverse engineering techniques introduced in HyperDbg. More articles, posts, and resources are available at the **[awesome](https://github.com/HyperDbg/awesome)** repo, and in addition, the **[slides](https://github.com/HyperDbg/slides)** repo provides presentation slides for further reference.
## Unique Features
+
* Advanced Hypervisor-based Kernel Mode Debugger [link][link][link]
* Classic EPT Hook (Hidden Breakpoint) [link][link][link]
* Inline EPT Hook (Inline Hook) [link][link]
-* Monitor Memory For R/W (Emulating Hardware Debug Registers Without Limitation) [link][link][link]
+* Monitor Memory for R/W (Emulating Hardware Debug Registers Without Limitation) [link][link][link]
* SYSCALL Hook (Disable EFER & Handle #UD) [link][link][link]
* SYSRET Hook (Disable EFER & Handle #UD) [link][link]
* CPUID Hook & Monitor [link][link]
@@ -91,15 +143,15 @@ You can also read [this article](https://research.hyperdbg.org/debugger/kernel-d
* RDPMC Hook & Monitor [link]
* VMCALL Hook & Monitor [link]
* Debug Registers Hook & Monitor [link]
-* I/O Port (In Instruction) Hook & Monitor [link][link]
-* I/O Port (Out Instruction) Hook & Monitor [link][link]
+* I/O Port (IN Instruction) Hook & Monitor [link][link]
+* I/O Port (OUT Instruction) Hook & Monitor [link][link]
* MMIO Monitor [link]
* Exception (IDT < 32) Monitor [link][link][link]
* External-Interrupt (IDT > 32) Monitor [link][link][link]
* Running Automated Scripts [link]
-* Transparent-mode (Anti-debugging and Anti-hypervisor Resistance) [link][link]
-* Running Custom Assembly In Both VMX-root, VMX non-root (Kernel & User) [link]
-* Checking For Custom Conditions [link][link]
+* Transparent-mode and Hyperevade Project (Anti-debugging and Anti-hypervisor Resistance) [link][link][link]
+* Running Custom Assembly in Both VMX-root, VMX non-root (Kernel & User) [link]
+* Checking for Custom Conditions [link][link]
* Process-specific & Thread-specific Debugging [link][link][link]
* VMX-root Compatible Message Tracing [link]
* Powerful Kernel Side Scripting Engine [link][link]
@@ -110,18 +162,24 @@ You can also read [this article](https://research.hyperdbg.org/debugger/kernel-d
* Various Custom Scripts [link]
* HyperDbg Software Development Kit (SDK) [link]
* Event Short-circuiting [link][link]
-* Tracking records of function calls and return addresses [link]
+* Tracking Records of Function Calls and Return Addresses [link]
* Kernel-level Length Disassembler Engine (LDE) [link][link]
* Memory Execution Monitor & Execution Blocking [link]
* Custom Page-fault Injection [link]
* Different Event Calling Stages [link]
* Injecting Custom Interrupts/Exceptions/Faults [link][link]
-* Instant events in the Debugger Mode [link]
-* Detect kernel-to-user and user-to-kernel transitions [link]
-* Physical memory monitoring hooks [link]
+* Instant Events in the Debugger Mode [link]
+* Detecting Kernel-to-user and User-to-kernel Transitions [link]
+* Physical Memory Monitoring Hooks [link]
* Enumerating PCI/PCI-e Devices [link]
* Interpreting and Dumping PCI/PCI-e Configuration Space (CAM) [link]
-* Dumping IDT entries, I/O APIC, and Local APIC in XAPIC and X2APIC modes [link][link][link]
+* Dumping IDT Entries, I/O APIC, and Local APIC in XAPIC and X2APIC Modes [link][link][link]
+* Triggering and Counting System Management Mode (SMM) Interrupts (SMIs) [link]
+* Attaching to the User-mode Process and Preventing Execution [link]
+* Intercepting Execution of XSETBV Instructions [link]
+* Writing Library Script Files [link]
+* Enhanced Portable Executable (PE) Parser [link]
+* Tracing Branches using Last Branch Record (LBR) [link][link][link][link][link][link][link]
## How does it work?
@@ -133,15 +191,17 @@ You can read about the internal design of HyperDbg and its features in the [docu
## Scripts
+
You can write your **[scripts](https://github.com/HyperDbg/scripts)** to automate your debugging journey. **HyperDbg** has a powerful, fast, and entirely kernel-side implemented [script engine](https://docs.hyperdbg.org/commands/scripting-language).
## Contributing
+
Contributing to HyperDbg is super appreciated. We have made a list of potential [tasks](https://github.com/HyperDbg/HyperDbg/blob/master/CONTRIBUTING.md#things-to-work-on) that you might be interested in contributing towards.
If you want to contribute to HyperDbg, please read the [Contribution Guide](https://github.com/HyperDbg/HyperDbg/blob/master/CONTRIBUTING.md).
-
## License
+
**HyperDbg**, and all its submodules and repos, unless a license is otherwise specified, are licensed under **GPLv3** LICENSE.
Dependencies are licensed by their own.
diff --git a/examples/kernel/hyperdbg_driver/code/driver/Driver.c b/examples/kernel/hyperdbg_driver/code/driver/Driver.c
index 44922817..b4092073 100644
--- a/examples/kernel/hyperdbg_driver/code/driver/Driver.c
+++ b/examples/kernel/hyperdbg_driver/code/driver/Driver.c
@@ -83,6 +83,7 @@ DriverEntry(
//
DbgPrint("HyperDbg's device and major functions are loaded");
+
ASSERT(NT_SUCCESS(Ntstatus));
return Ntstatus;
}
@@ -105,7 +106,7 @@ DrvUnload(PDRIVER_OBJECT DriverObject)
//
// Unloading VMM and Debugger
//
- LoaderUninitializeLogTracer();
+ LoaderUninitLogTracer();
}
/**
diff --git a/examples/kernel/hyperdbg_driver/code/driver/Ioctl.c b/examples/kernel/hyperdbg_driver/code/driver/Ioctl.c
index 7d771f8d..8d7b1c5c 100644
--- a/examples/kernel/hyperdbg_driver/code/driver/Ioctl.c
+++ b/examples/kernel/hyperdbg_driver/code/driver/Ioctl.c
@@ -34,9 +34,9 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
//
// DO NOT CHANGE CALLING OF THE FOLLOWING FUNCTION
//
- PoolManagerCheckAndPerformAllocationAndDeallocation();
+ // PoolManagerCheckAndPerformAllocationAndDeallocation();
- if (g_AllowIOCTLFromUsermode)
+ if (g_VmmInitialized)
{
IrpStack = IoGetCurrentIrpStackLocation(Irp);
diff --git a/examples/kernel/hyperdbg_driver/code/driver/Loader.c b/examples/kernel/hyperdbg_driver/code/driver/Loader.c
index a84a8f63..7a2ed944 100644
--- a/examples/kernel/hyperdbg_driver/code/driver/Loader.c
+++ b/examples/kernel/hyperdbg_driver/code/driver/Loader.c
@@ -24,7 +24,7 @@ LoaderInitVmmAndReversingMachine()
//
// Allow to server IOCTL
//
- g_AllowIOCTLFromUsermode = TRUE;
+ g_VmmInitialized = TRUE;
//
// Fill the callbacks for the message tracer
@@ -90,7 +90,7 @@ LoaderInitVmmAndReversingMachine()
//
// Not loaded
//
- g_AllowIOCTLFromUsermode = FALSE;
+ g_VmmInitialized = FALSE;
return FALSE;
}
@@ -101,7 +101,7 @@ LoaderInitVmmAndReversingMachine()
* @return VOID
*/
VOID
-LoaderUninitializeLogTracer()
+LoaderUninitLogTracer()
{
LogDebugInfo("Unloading HyperDbg's debugger...\n");
diff --git a/examples/kernel/hyperdbg_driver/header/driver/Loader.h b/examples/kernel/hyperdbg_driver/header/driver/Loader.h
index c12b0d12..7ead903c 100644
--- a/examples/kernel/hyperdbg_driver/header/driver/Loader.h
+++ b/examples/kernel/hyperdbg_driver/header/driver/Loader.h
@@ -17,7 +17,7 @@
//////////////////////////////////////////////////
VOID
-LoaderUninitializeLogTracer();
+LoaderUninitLogTracer();
BOOLEAN
LoaderInitVmmAndReversingMachine();
diff --git a/examples/kernel/hyperdbg_driver/header/misc/Global.h b/examples/kernel/hyperdbg_driver/header/misc/Global.h
index 77cf5e59..db81c9d8 100644
--- a/examples/kernel/hyperdbg_driver/header/misc/Global.h
+++ b/examples/kernel/hyperdbg_driver/header/misc/Global.h
@@ -18,7 +18,7 @@
BOOLEAN g_HandleInUse;
/**
- * @brief Determines whether the clients are allowed to send IOCTL to the drive or not
+ * @brief Shows whether the VMM is initialized or not
*
*/
-BOOLEAN g_AllowIOCTLFromUsermode;
+BOOLEAN g_VmmInitialized;
\ No newline at end of file
diff --git a/examples/kernel/hyperdbg_driver/hyperdbg_driver.vcxproj b/examples/kernel/hyperdbg_driver/hyperdbg_driver.vcxproj
index 9d1bb8aa..fd70d5dc 100644
--- a/examples/kernel/hyperdbg_driver/hyperdbg_driver.vcxproj
+++ b/examples/kernel/hyperdbg_driver/hyperdbg_driver.vcxproj
@@ -1,5 +1,8 @@
+
+
+ debug
@@ -86,7 +89,7 @@
trueCreatepch.h
- Disabled
+ Fulltrue
@@ -110,7 +113,20 @@
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/kernel/hyperdbg_driver/hyperdbg_driver.vcxproj.filters b/examples/kernel/hyperdbg_driver/hyperdbg_driver.vcxproj.filters
index 2a6aa09a..3345321d 100644
--- a/examples/kernel/hyperdbg_driver/hyperdbg_driver.vcxproj.filters
+++ b/examples/kernel/hyperdbg_driver/hyperdbg_driver.vcxproj.filters
@@ -56,4 +56,7 @@
code\driver
+
+
+
\ No newline at end of file
diff --git a/examples/kernel/hyperdbg_driver/packages.config b/examples/kernel/hyperdbg_driver/packages.config
new file mode 100644
index 00000000..eb276766
--- /dev/null
+++ b/examples/kernel/hyperdbg_driver/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/user/hyperdbg_app/code/hyperdbg-app.cpp b/examples/user/hyperdbg_app/code/hyperdbg-app.cpp
index 179b0876..095876bf 100644
--- a/examples/user/hyperdbg_app/code/hyperdbg-app.cpp
+++ b/examples/user/hyperdbg_app/code/hyperdbg-app.cpp
@@ -1,135 +1,58 @@
-/**
- * @file hyperdbg-app.cpp
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief Controller of the reversing machine's module
- * @details
- *
- * @version 0.2
- * @date 2023-02-01
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
#include "pch.h"
-PVOID g_SharedMessageBuffer = NULL;
-
-/**
- * @brief Show messages
- *
- * @param Text
- * @return int
- */
-int
-hyperdbg_show_messages(const char * Text)
+static int
+ShowMessages(const char * Text)
{
- printf("%s", Text);
- return 0;
+ printf("%s", Text);
+ return 0;
}
-/**
- * @brief Show messages (shared buffer)
- *
- * @param Text
- * @return int
- */
-int
-hyperdbg_show_messages_shared_buffer()
+static int
+LoadVmm()
{
- printf("%s", (char *)g_SharedMessageBuffer);
- return 0;
-}
+ hyperdbg_u_set_text_message_callback((PVOID)ShowMessages);
-/**
- * @brief Load the driver
- *
- * @return int return zero if it was successful or non-zero if there
- * was error
- */
-int
-hyperdbg_load()
-{
- char CpuId[13] = {0};
-
- //
- // Read the vendor string
- //
- hyperdbg_u_read_vendor_string(CpuId);
-
- printf("current processor vendor is : %s\n", CpuId);
-
- if (strcmp(CpuId, "GenuineIntel") == 0)
+ if (!hyperdbg_u_detect_vmx_support())
{
- printf("virtualization technology is vt-x\n");
- }
- else
- {
- printf("this program is not designed to run in a non-VT-x "
- "environment !\n");
+ printf("[-] VT-x (VMX) is not supported / enabled on this processor\n");
return 1;
}
- //
- // Detect if the processor supports vmx operation
- //
- if (hyperdbg_u_detect_vmx_support())
+ printf("[*] loading HyperDbg VMM...\n");
+ if (hyperdbg_u_install_kd_driver() == 1 || hyperdbg_u_load_vmm() == 1)
{
- printf("vmx operation is supported by your processor\n");
- }
- else
- {
-#ifdef ENV_WINDOWS
- printf("vmx operation is not supported by your processor "
- "(if you are using an Intel processor, it might be because VBS is not disabled!)\n");
-#endif
+ printf("[-] cannot load the HyperDbg VMM\n");
return 1;
}
- //
- // Set callback function for showing messages
- //
- hyperdbg_u_set_text_message_callback(hyperdbg_show_messages);
-
- //
- // Test intepreter with shared buffer
- //
- // g_SharedMessageBuffer = hyperdbg_u_set_text_message_callback_using_shared_buffer(hyperdbg_show_messages_shared_buffer);
-
- //
- // Test interpreter
- //
- hyperdbg_u_connect_remote_debugger_using_named_pipe("\\\\.\\pipe\\HyperDbgPipe", TRUE);
- Sleep(10000);
- hyperdbg_u_run_command((CHAR *)"r");
- hyperdbg_u_run_command((CHAR *)".start path c:\\Windows\\system32\\calc.exe");
- hyperdbg_u_continue_debuggee();
- hyperdbg_u_continue_debuggee();
- hyperdbg_u_continue_debuggee();
- hyperdbg_u_continue_debuggee();
- hyperdbg_u_continue_debuggee();
- hyperdbg_u_continue_debuggee();
- hyperdbg_u_continue_debuggee();
+ printf("[+] HyperDbg VMM is running\n");
return 0;
}
-/**
- * @brief main function
- *
- * @return int
- */
int
-main()
+main(int argc, char ** argv)
{
- if (hyperdbg_load() == 0)
+ return main2(argc, argv);
+
+ if (LoadVmm() != 0)
{
- //
- // HyperDbg driver loaded successfully
- //
- // hyperdbg_unload();
- }
- else
- {
- printf("err, in loading HyperDbg\n");
+ return 1;
}
+
+ hyperdbg_u_run_command((CHAR*)"lm");
+
+ printf("[*] unloading HyperDbg VMM...\n");
+
+ //
+ // Unload the driver
+ //
+ hyperdbg_u_unload_vmm();
+ hyperdbg_u_unload_kd();
+ hyperdbg_u_stop_kd_driver();
+ hyperdbg_u_uninstall_kd_driver();
+
+ printf("[+] done\n");
+
+ return 0;
}
diff --git a/examples/user/hyperdbg_app/code/hyperdbg-ipt.cpp b/examples/user/hyperdbg_app/code/hyperdbg-ipt.cpp
new file mode 100644
index 00000000..aacd776f
--- /dev/null
+++ b/examples/user/hyperdbg_app/code/hyperdbg-ipt.cpp
@@ -0,0 +1,583 @@
+#include "pch.h"
+
+#include
+#include
+#include
+#include "../dependencies/libipt/intel-pt.h"
+#include
+
+#pragma comment(lib, "dbghelp.lib")
+
+static UINT64 g_ImageBase = 0;
+static UINT64 g_CodeBase = 0;
+static UINT64 g_CodeSize = 0;
+static UINT8 * g_Code = NULL;
+
+static int
+ShowMessages(const char * Text)
+{
+ printf("%s", Text);
+ return 0;
+}
+
+static int
+ReadImage(uint8_t * Buffer, size_t Size, const struct pt_asid * Asid, uint64_t Ip, void * Context)
+{
+ (void)Asid;
+ (void)Context;
+
+ if (g_Code == NULL || Ip < g_CodeBase || Ip >= g_CodeBase + g_CodeSize)
+ return -pte_nomap;
+
+ uint64_t Available = g_CodeBase + g_CodeSize - Ip;
+ size_t Count = (Size < Available) ? Size : (size_t)Available;
+
+ memcpy(Buffer, g_Code + (Ip - g_CodeBase), Count);
+ return (int)Count;
+}
+
+typedef struct _PROC_BASIC_INFO
+{
+ LONG ExitStatus;
+ PVOID PebBaseAddress;
+ ULONG_PTR Reserved[4];
+} PROC_BASIC_INFO;
+
+typedef LONG(NTAPI * PFN_NT_QIP)(HANDLE, ULONG, PVOID, ULONG, PULONG);
+
+static BOOLEAN
+CaptureImage(HANDLE Process, UINT64 * TextStart, UINT64 * TextEnd)
+{
+ HMODULE Ntdll = GetModuleHandleA("ntdll.dll");
+ PFN_NT_QIP NtQip = Ntdll ? (PFN_NT_QIP)GetProcAddress(Ntdll, "NtQueryInformationProcess") : NULL;
+ PROC_BASIC_INFO Pbi = {0};
+ ULONG Ret = 0;
+ SIZE_T Got = 0;
+ UINT64 Base = 0;
+ IMAGE_DOS_HEADER Dos;
+ IMAGE_NT_HEADERS64 Nt;
+ UINT64 SectionBase;
+
+ if (NtQip == NULL || NtQip(Process, 0, &Pbi, sizeof(Pbi), &Ret) < 0 || Pbi.PebBaseAddress == NULL)
+ return FALSE;
+
+ if (!ReadProcessMemory(Process, (PBYTE)Pbi.PebBaseAddress + 0x10, &Base, sizeof(Base), &Got) || Base == 0)
+ return FALSE;
+
+ if (!ReadProcessMemory(Process, (PVOID)Base, &Dos, sizeof(Dos), &Got) || Dos.e_magic != IMAGE_DOS_SIGNATURE)
+ return FALSE;
+
+ if (!ReadProcessMemory(Process, (PBYTE)Base + Dos.e_lfanew, &Nt, sizeof(Nt), &Got) || Nt.Signature != IMAGE_NT_SIGNATURE)
+ return FALSE;
+
+ g_ImageBase = Base;
+ SectionBase = Base + Dos.e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS64, OptionalHeader) + Nt.FileHeader.SizeOfOptionalHeader;
+
+ for (WORD i = 0; i < Nt.FileHeader.NumberOfSections; i++)
+ {
+ IMAGE_SECTION_HEADER Section;
+
+ if (!ReadProcessMemory(Process, (PBYTE)SectionBase + (UINT64)i * sizeof(Section), &Section, sizeof(Section), &Got))
+ return FALSE;
+
+ if (memcmp(Section.Name, ".text", 6) != 0)
+ continue;
+
+ UINT64 Start = Base + Section.VirtualAddress;
+ UINT64 Size = Section.Misc.VirtualSize ? Section.Misc.VirtualSize : Section.SizeOfRawData;
+
+ if (Size == 0)
+ return FALSE;
+
+ g_Code = (UINT8 *)malloc((size_t)Size);
+ if (g_Code == NULL)
+ return FALSE;
+
+ if (!ReadProcessMemory(Process, (PVOID)Start, g_Code, (SIZE_T)Size, &Got) || Got != Size)
+ {
+ free(g_Code);
+ g_Code = NULL;
+ return FALSE;
+ }
+
+ g_CodeBase = Start;
+ g_CodeSize = Size;
+ *TextStart = Start;
+ *TextEnd = Start + Size - 1;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static BOOLEAN
+ResolveFunction(HANDLE Process, const char * Path, const char * Name, UINT64 * Start, UINT64 * End)
+{
+ union
+ {
+ SYMBOL_INFO Info;
+ BYTE Buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
+ } Symbol = {0};
+ BOOLEAN Ok = FALSE;
+
+ SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
+ if (!SymInitialize(Process, NULL, FALSE))
+ return FALSE;
+
+ if (SymLoadModuleEx(Process, NULL, Path, NULL, (DWORD64)g_ImageBase, 0, NULL, 0) != 0)
+ {
+ Symbol.Info.SizeOfStruct = sizeof(SYMBOL_INFO);
+ Symbol.Info.MaxNameLen = MAX_SYM_NAME;
+
+ if (SymFromName(Process, Name, &Symbol.Info) && Symbol.Info.Address != 0)
+ {
+ *Start = Symbol.Info.Address;
+ *End = Symbol.Info.Address + (Symbol.Info.Size ? Symbol.Info.Size : 0x200) - 1;
+ Ok = TRUE;
+ }
+ }
+
+ SymCleanup(Process);
+ return Ok;
+}
+
+static BOOLEAN
+PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE Type)
+{
+ HYPERTRACE_PT_OPERATION_PACKETS Op = {};
+ Op.PtOperationType = Type;
+ return hyperdbg_u_pt_operation(&Op);
+}
+
+static BOOLEAN
+PtFilter(UINT32 ProcessId, UINT64 Start, UINT64 End)
+{
+ HYPERTRACE_PT_OPERATION_PACKETS Op = {};
+
+ Op.PtOperationType = HYPERTRACE_PT_OPERATION_REQUEST_TYPE_FILTER;
+ Op.FilterOptions.TraceUser = 1;
+ Op.EnableOptions.Pid = ProcessId;
+
+ if (End > Start)
+ {
+ Op.FilterOptions.NumAddrRanges = 1;
+ Op.FilterOptions.AddrRanges[0].Start = Start;
+ Op.FilterOptions.AddrRanges[0].End = End;
+ }
+
+ if (!hyperdbg_u_pt_operation(&Op))
+ return FALSE;
+
+ printf("[+] PT filter: cr3=0x%llx traceuser=%u ranges=%u buffer=0x%llx\n",
+ (unsigned long long)Op.EnableOptions.Cr3,
+ Op.FilterOptions.TraceUser,
+ Op.FilterOptions.NumAddrRanges,
+ (unsigned long long)Op.BufferSize);
+ return TRUE;
+}
+
+static const char *
+PacketName(enum pt_packet_type Type)
+{
+ switch (Type)
+ {
+ case ppt_psb: return "PSB"; case ppt_psbend: return "PSBEND"; case ppt_pad: return "PAD";
+ case ppt_fup: return "FUP"; case ppt_tip: return "TIP"; case ppt_tip_pge: return "TIP.PGE";
+ case ppt_tip_pgd: return "TIP.PGD"; case ppt_tnt_8: return "TNT8"; case ppt_tnt_64: return "TNT64";
+ case ppt_mode: return "MODE"; case ppt_pip: return "PIP"; case ppt_vmcs: return "VMCS";
+ case ppt_cbr: return "CBR"; case ppt_tsc: return "TSC"; case ppt_tma: return "TMA";
+ case ppt_mtc: return "MTC"; case ppt_cyc: return "CYC"; case ppt_ovf: return "OVF";
+ case ppt_stop: return "STOP"; case ppt_exstop: return "EXSTOP"; case ppt_mnt: return "MNT";
+ case ppt_ptw: return "PTW"; default: return "?";
+ }
+}
+
+static uint64_t
+ReconstructIp(const struct pt_packet_ip * Packet, uint64_t * LastIp)
+{
+ uint64_t Value = *LastIp;
+
+ switch (Packet->ipc)
+ {
+ case pt_ipc_update_16: Value = (Value & ~0xffffull) | (Packet->ip & 0xffffull); break;
+ case pt_ipc_update_32: Value = (Value & ~0xffffffffull) | (Packet->ip & 0xffffffffull); break;
+ case pt_ipc_update_48: Value = (Value & ~0xffffffffffffull) | (Packet->ip & 0xffffffffffffull); break;
+ case pt_ipc_sext_48:
+ Value = Packet->ip & 0xffffffffffffull;
+ if (Value & 0x800000000000ull)
+ Value |= 0xffff000000000000ull;
+ break;
+ default: Value = Packet->ip; break;
+ }
+
+ *LastIp = Value;
+ return Value;
+}
+
+static UINT64
+DecodeCorePackets(UINT32 Cpu, const UINT8 * Buffer, UINT64 Size)
+{
+ struct pt_config Config;
+ struct pt_packet_decoder * Decoder;
+ UINT64 Count = 0;
+ uint64_t LastIp = 0;
+ int Status;
+
+ pt_config_init(&Config);
+ Config.begin = (uint8_t *)Buffer;
+ Config.end = (uint8_t *)Buffer + Size;
+
+ Decoder = pt_pkt_alloc_decoder(&Config);
+ if (Decoder == NULL)
+ {
+ printf("[-] core %u: cannot allocate packet decoder\n", Cpu);
+ return 0;
+ }
+
+ for (;;)
+ {
+ Status = pt_pkt_sync_forward(Decoder);
+ if (Status < 0)
+ break;
+
+ for (;;)
+ {
+ struct pt_packet Packet;
+
+ Status = pt_pkt_next(Decoder, &Packet, sizeof(Packet));
+ if (Status < 0)
+ break;
+
+ Count++;
+
+ switch (Packet.type)
+ {
+ case ppt_tnt_8:
+ case ppt_tnt_64:
+ printf(" %-8s %2u ", PacketName(Packet.type), Packet.payload.tnt.bit_size);
+ for (uint8_t Bit = 0; Bit < Packet.payload.tnt.bit_size && Bit < 64; Bit++)
+ putchar(((Packet.payload.tnt.payload >> (Packet.payload.tnt.bit_size - 1 - Bit)) & 1) ? 'T' : 'N');
+ putchar('\n');
+ break;
+
+ case ppt_tip:
+ case ppt_fup:
+ case ppt_tip_pge:
+ case ppt_tip_pgd:
+ if (Packet.payload.ip.ipc == pt_ipc_suppressed)
+ printf(" %-8s (ip suppressed)\n", PacketName(Packet.type));
+ else
+ {
+ uint64_t Ip = ReconstructIp(&Packet.payload.ip, &LastIp);
+ printf(" %-8s 0x%016llx exe+0x%llx\n",
+ PacketName(Packet.type), (unsigned long long)Ip, (unsigned long long)(Ip - g_ImageBase));
+ }
+ break;
+
+ case ppt_pip:
+ printf(" %-8s cr3=0x%llx\n", PacketName(Packet.type), (unsigned long long)Packet.payload.pip.cr3);
+ break;
+
+ case ppt_cbr:
+ //printf(" %-8s ratio=%u\n", PacketName(Packet.type), Packet.payload.cbr.ratio);
+ break;
+
+ case ppt_tsc:
+ printf(" %-8s tsc=0x%llx\n", PacketName(Packet.type), (unsigned long long)Packet.payload.tsc.tsc);
+ break;
+
+ default:
+ //printf(" %-8s\n", PacketName(Packet.type));
+ break;
+ }
+ }
+ }
+
+ pt_pkt_free_decoder(Decoder);
+ return Count;
+}
+
+static UINT64
+DecodeCore(UINT32 Cpu, const UINT8 * Buffer, UINT64 Size)
+{
+ struct pt_config Config;
+ struct pt_insn_decoder * Decoder;
+ struct pt_image * Image;
+ UINT64 Count = 0;
+ int Status;
+
+ pt_config_init(&Config);
+ Config.begin = (uint8_t *)Buffer;
+ Config.end = (uint8_t *)Buffer + Size;
+
+ Decoder = pt_insn_alloc_decoder(&Config);
+ if (Decoder == NULL)
+ {
+ printf("[-] core %u: cannot allocate instruction decoder\n", Cpu);
+ return 0;
+ }
+
+ Image = pt_insn_get_image(Decoder);
+ pt_image_set_callback(Image, ReadImage, NULL);
+
+ for (;;)
+ {
+ Status = pt_insn_sync_forward(Decoder);
+ if (Status < 0)
+ break;
+
+ for (;;)
+ {
+ struct pt_insn Insn;
+
+ while (Status & pts_event_pending)
+ {
+ struct pt_event Event;
+ Status = pt_insn_event(Decoder, &Event, sizeof(Event));
+ if (Status < 0)
+ break;
+ }
+
+ if (Status < 0 || (Status & pts_eos))
+ break;
+
+ Status = pt_insn_next(Decoder, &Insn, sizeof(Insn));
+ if (Status < 0)
+ break;
+
+ ZydisDisassembledInstruction Disasm;
+ ZydisMachineMode Mode = (Insn.mode == ptem_32bit) ? ZYDIS_MACHINE_MODE_LEGACY_32 : ZYDIS_MACHINE_MODE_LONG_64;
+
+ if (ZYAN_SUCCESS(ZydisDisassembleIntel(Mode, Insn.ip, Insn.raw, Insn.size, &Disasm)))
+ printf(" 0x%016llx exe+0x%-6llx %s\n",
+ (unsigned long long)Insn.ip,
+ (unsigned long long)(Insn.ip - g_ImageBase),
+ Disasm.text);
+ else
+ printf(" 0x%016llx (undecodable)\n", (unsigned long long)Insn.ip);
+
+ Count++;
+ }
+
+ if (Status >= 0 && (Status & pts_eos))
+ break;
+ }
+
+ pt_insn_free_decoder(Decoder);
+ return Count;
+}
+
+static void
+RunAndTrace(const char * Path, const char * Function, BOOLEAN Packets, int PinCore)
+{
+ STARTUPINFOA Startup = {0};
+ PROCESS_INFORMATION Process = {0};
+ HYPERTRACE_PT_MMAP_PACKETS Mmap = {0};
+ HYPERTRACE_PT_OPERATION_PACKETS Sizes = {0};
+ UINT64 TextStart = 0;
+ UINT64 TextEnd = 0;
+ UINT64 FilterStart = 0;
+ UINT64 FilterEnd = 0;
+ UINT64 Total = 0;
+
+ Startup.cb = sizeof(Startup);
+
+ if (!CreateProcessA(Path, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &Startup, &Process))
+ {
+ printf("[-] cannot launch '%s' (error 0x%x)\n", Path, GetLastError());
+ return;
+ }
+
+ printf("[+] launched '%s' (pid %u, suspended)\n", Path, Process.dwProcessId);
+
+ if (PinCore >= 0)
+ {
+ DWORD_PTR Mask = (DWORD_PTR)1 << PinCore;
+ if (SetProcessAffinityMask(Process.hProcess, Mask))
+ printf("[+] pinned target to core %d (all trace should land on this core)\n", PinCore);
+ else
+ printf("[!] could not pin to core %d (error 0x%x); running unpinned\n", PinCore, GetLastError());
+ }
+ else
+ {
+ printf("[*] target unpinned (scheduler may migrate it across cores)\n");
+ }
+
+ if (!CaptureImage(Process.hProcess, &TextStart, &TextEnd))
+ {
+ printf("[-] cannot read target image / .text section\n");
+ TerminateProcess(Process.hProcess, 1);
+ goto Cleanup;
+ }
+
+ printf("[+] image base 0x%llx, .text 0x%llx-0x%llx (%llu bytes)\n",
+ (unsigned long long)g_ImageBase,
+ (unsigned long long)TextStart,
+ (unsigned long long)TextEnd,
+ (unsigned long long)g_CodeSize);
+
+ FilterStart = TextStart;
+ FilterEnd = TextEnd;
+
+ if (Function != NULL && ResolveFunction(Process.hProcess, Path, Function, &FilterStart, &FilterEnd)) {
+ printf("[+] IP filter narrowed to '%s' 0x%llx-0x%llx (%llu bytes)\n",
+ Function,
+ (unsigned long long)FilterStart,
+ (unsigned long long)FilterEnd,
+ (unsigned long long)(FilterEnd - FilterStart + 1));
+ }
+ else
+ {
+ printf("[!] IP filter: whole .text (symbol '%s' not found - build the target with a PDB)\n",
+ Function ? Function : "(none)");
+ }
+
+ if (!PtFilter(Process.dwProcessId, FilterStart, FilterEnd) ||
+ !PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE_ENABLE))
+ {
+ printf("[-] cannot enable Intel PT\n");
+ TerminateProcess(Process.hProcess, 1);
+ goto Cleanup;
+ }
+
+ if (!hyperdbg_u_pt_mmap(&Mmap))
+ {
+ printf("[-] pt_mmap failed\n");
+ PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE_DISABLE);
+ TerminateProcess(Process.hProcess, 1);
+ goto Cleanup;
+ }
+
+ printf("[+] PT enabled, %u per-core buffers mapped\n", Mmap.NumCpus);
+ printf("[*] resuming target and waiting for it to exit...\n");
+
+ ResumeThread(Process.hThread);
+ WaitForSingleObject(Process.hProcess, INFINITE);
+ printf("[+] target exited, decoding trace\n");
+
+ PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE_PAUSE);
+
+ Sizes.PtOperationType = HYPERTRACE_PT_OPERATION_REQUEST_TYPE_SIZE;
+ if (!hyperdbg_u_pt_operation(&Sizes))
+ {
+ printf("[-] cannot query PT sizes\n");
+ PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE_DISABLE);
+ goto Cleanup;
+ }
+
+ for (UINT32 i = 0; i < Mmap.NumCpus; i++)
+ {
+ UINT32 Cpu = Mmap.Cpus[i].CpuId;
+ UINT64 Bytes = (Cpu < Sizes.NumCpus) ? Sizes.BytesPerCpu[Cpu] : 0;
+
+ if (Bytes == 0)
+ continue;
+
+ if (Bytes > Mmap.Cpus[i].Size)
+ Bytes = Mmap.Cpus[i].Size;
+
+ printf("\n[*] core %u: %llu bytes of trace\n", Cpu, (unsigned long long)Bytes);
+ Total += Packets
+ ? DecodeCorePackets(Cpu, (const UINT8 *)(ULONG_PTR)Mmap.Cpus[i].UserVa, Bytes)
+ : DecodeCore(Cpu, (const UINT8 *)(ULONG_PTR)Mmap.Cpus[i].UserVa, Bytes);
+ }
+
+ printf("\n[+] decoded %llu %s total\n", (unsigned long long)Total, Packets ? "packet(s)" : "instruction(s)");
+
+ PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE_DISABLE);
+
+Cleanup:
+ if (g_Code != NULL)
+ {
+ free(g_Code);
+ g_Code = NULL;
+ }
+ if (Process.hThread != NULL)
+ CloseHandle(Process.hThread);
+ if (Process.hProcess != NULL)
+ CloseHandle(Process.hProcess);
+}
+
+static int
+LoadVmmAndTrace()
+{
+ hyperdbg_u_set_text_message_callback((PVOID)ShowMessages);
+
+ if (!hyperdbg_u_detect_vmx_support())
+ {
+ printf("[-] VT-x (VMX) is not supported / enabled on this processor\n");
+ return 1;
+ }
+
+ printf("[*] loading HyperDbg VMM...\n");
+ if (hyperdbg_u_install_kd_driver() == 1 || hyperdbg_u_load_vmm() == 1)
+ {
+ printf("[-] cannot load the HyperDbg VMM\n");
+ return 1;
+ }
+
+ printf("[+] HyperDbg VMM is running\n");
+
+ printf("[*] loading HyperTrace...\n");
+
+ if ( hyperdbg_u_load_hypertrace_module() == 1)
+ {
+ printf("[-] cannot load the HyperDbg HyperTrace\n");
+ return 1;
+ }
+
+ printf("[+] HyperDbg HyperTrace is running\n");
+
+ return 0;
+}
+
+int
+main2(int argc, char ** argv)
+{
+ const char * function = "main";
+ BOOLEAN packets = FALSE;
+ int pinCore = 0;
+
+ if (argc < 2)
+ {
+ printf("HyperDbg Intel PT tracer\n");
+ printf("usage: %s [function] [-p] [-c core]\n", argv[0]);
+ printf(" [function] symbol to IP-filter (default 'main'; pass '*' for whole .text)\n");
+ printf(" -p dump raw PT packets (TNT/TIP/FUP/PSB/...) instead of instructions\n");
+ printf(" -c core pin the target to this logical core (default 0; -1 = unpinned)\n");
+ return 1;
+ }
+
+ for (int i = 2; i < argc; i++)
+ {
+ if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "--packets") == 0)
+ packets = TRUE;
+ else if (strcmp(argv[i], "-c") == 0 && i + 1 < argc)
+ pinCore = atoi(argv[++i]);
+ else if (strcmp(argv[i], "*") == 0)
+ function = NULL;
+ else
+ function = argv[i];
+ }
+
+ if (LoadVmmAndTrace() != 0)
+ {
+ return 1;
+ }
+
+ RunAndTrace(argv[1], function, packets, pinCore);
+
+ printf("[*] unloading HyperDbg VMM...\n");
+
+ //
+ // Unload the driver
+ //
+ hyperdbg_u_unload_vmm();
+ hyperdbg_u_unload_kd();
+ hyperdbg_u_stop_kd_driver();
+ hyperdbg_u_uninstall_kd_driver();
+
+ printf("[+] done\n");
+
+ return 0;
+}
diff --git a/examples/user/hyperdbg_app/header/example-ipt.h b/examples/user/hyperdbg_app/header/example-ipt.h
new file mode 100644
index 00000000..90f00b87
--- /dev/null
+++ b/examples/user/hyperdbg_app/header/example-ipt.h
@@ -0,0 +1,16 @@
+/**
+ * @file example-ipt.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Headers for Intel PT example
+ * @details
+ *
+ * @version 0.20
+ * @date 2026-06-13
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+int
+main2(int argc, char** argv);
\ No newline at end of file
diff --git a/examples/user/hyperdbg_app/header/pch.h b/examples/user/hyperdbg_app/header/pch.h
index 79cfe414..d4bbf789 100644
--- a/examples/user/hyperdbg_app/header/pch.h
+++ b/examples/user/hyperdbg_app/header/pch.h
@@ -15,7 +15,7 @@
//
// Environment headers
//
-#include "platform/user/header/Environment.h"
+#include "platform/general/header/Environment.h"
//
// Windows SDK headers
@@ -38,3 +38,8 @@
//
#include "SDK/HyperDbgSdk.h"
#include "SDK/imports/user/HyperDbgLibImports.h"
+
+//
+// Other internal headers
+//
+#include "example-ipt.h"
diff --git a/examples/user/hyperdbg_app/hyperdbg_app.vcxproj b/examples/user/hyperdbg_app/hyperdbg_app.vcxproj
index 60ad1eb1..3072d9ac 100644
--- a/examples/user/hyperdbg_app/hyperdbg_app.vcxproj
+++ b/examples/user/hyperdbg_app/hyperdbg_app.vcxproj
@@ -11,10 +11,11 @@
-
+
+
@@ -29,13 +30,13 @@
Applicationtrue
- v143
+ v145UnicodeApplicationfalse
- v143
+ v145trueUnicode
@@ -50,33 +51,49 @@
-
+
+
+ C:\Users\masra\Desktop\libipt
+ $(SolutionDir)build\bin\$(Configuration)\$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\
+ false$(SolutionDir)build\bin\$(Configuration)\$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\
+ trueLevel3true
- _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ _DEBUG;_CONSOLE;ZYCORE_STATIC_BUILD;ZYDIS_STATIC_BUILD;%(PreprocessorDefinitions)trueMultiThreadedDebugCreatepch.h
- $(SolutionDir)include;$(ProjectDir)header;%(AdditionalIncludeDirectories)
+ $(LibIptDir)\include;$(SolutionDir)include;$(SolutionDir)dependencies\zydis\include;$(SolutionDir)dependencies\zydis\dependencies\zycore\include;$(ProjectDir)header;%(AdditionalIncludeDirectories)trueConsoletrue
- $(SolutionDir)build\bin\$(Configuration)\libhyperdbg.lib
- true
+ $(LibIptDir)\lib;%(AdditionalLibraryDirectories)
+ $(SolutionDir)build\bin\$(Configuration)\libhyperdbg.lib;$(SolutionDir)libraries\zydis\user\Zydis.lib;$(SolutionDir)libraries\zydis\user\Zycore.lib;$(SolutionDir)libraries\libipt\libipt.lib
+ false
+
+
+
+
+
+
@@ -84,23 +101,30 @@
truetruetrue
- NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ NDEBUG;_CONSOLE;ZYCORE_STATIC_BUILD;ZYDIS_STATIC_BUILD;%(PreprocessorDefinitions)trueMultiThreadedCreatepch.h
- $(SolutionDir)include;$(ProjectDir)header;%(AdditionalIncludeDirectories)
+ $(LibIptDir)\include;$(SolutionDir)include;$(SolutionDir)dependencies\zydis\include;$(SolutionDir)dependencies\zydis\dependencies\zycore\include;$(ProjectDir)header;%(AdditionalIncludeDirectories)true
- Disabled
+ MaxSpeedConsoletruetruetrue
- $(SolutionDir)build\bin\$(Configuration)\libhyperdbg.lib
+ $(LibIptDir)\lib;%(AdditionalLibraryDirectories)
+ $(SolutionDir)build\bin\$(Configuration)\libhyperdbg.lib;$(SolutionDir)libraries\zydis\user\Zydis.lib;$(SolutionDir)libraries\zydis\user\Zycore.lib;$(SolutionDir)libraries\libipt\libipt.libtrue
+
+
+
+
+
+
diff --git a/examples/user/hyperdbg_app/hyperdbg_app.vcxproj.filters b/examples/user/hyperdbg_app/hyperdbg_app.vcxproj.filters
index 6e0f241b..d7dd0c26 100644
--- a/examples/user/hyperdbg_app/hyperdbg_app.vcxproj.filters
+++ b/examples/user/hyperdbg_app/hyperdbg_app.vcxproj.filters
@@ -15,11 +15,14 @@
header
-
- header\platform
+
+ header
+
+ code
+ code
diff --git a/hwdbg/sim/modelsim/modelsim.py b/hwdbg/sim/modelsim/modelsim.py
index 64f8cfb0..e3c90db1 100644
--- a/hwdbg/sim/modelsim/modelsim.py
+++ b/hwdbg/sim/modelsim/modelsim.py
@@ -8,7 +8,7 @@ MODELSIM = "/home/sina/intelFPGA/20.1/modelsim_ase/bin"
# Check modelsim directory
#
if not os.path.exists(MODELSIM):
- print("[x] Error: The path mdoes not exist")
+ print("[x] Error: The path does not exist")
exit()
else:
print("[*] Oh, the modelsim path found :)")
@@ -152,6 +152,6 @@ print(result.stdout.decode())
#
# Run the generated WLF file
#
-print("[*] openning file in vsim: " + latest_vcd_file + ".wlf")
+print("[*] opening file in vsim: " + latest_vcd_file + ".wlf")
subprocess.run([MODELSIM_VSIM, latest_vcd_file + ".wlf",
"-do", current_script_path + '/modelsim.tcl'])
diff --git a/hwdbg/src/main/scala/hwdbg/communication/interpreter.scala b/hwdbg/src/main/scala/hwdbg/communication/interpreter.scala
index 1ab60e91..e682e612 100644
--- a/hwdbg/src/main/scala/hwdbg/communication/interpreter.scala
+++ b/hwdbg/src/main/scala/hwdbg/communication/interpreter.scala
@@ -60,7 +60,7 @@ class DebuggerPacketInterpreter(
val receivingData = Input(UInt(instanceInfo.bramDataWidth.W)) // data to be received in interpreter
//
- // Sending singals
+ // Sending signals
//
val beginSendingBuffer = Output(Bool()) // should sender start sending buffers or not?
val noNewDataSender = Output(Bool()) // should sender finish sending buffers or not?
diff --git a/hwdbg/src/main/scala/hwdbg/communication/interpreter/instance_info.scala b/hwdbg/src/main/scala/hwdbg/communication/interpreter/instance_info.scala
index 9f673117..f84df188 100644
--- a/hwdbg/src/main/scala/hwdbg/communication/interpreter/instance_info.scala
+++ b/hwdbg/src/main/scala/hwdbg/communication/interpreter/instance_info.scala
@@ -50,7 +50,7 @@ class InterpreterInstanceInfo(
val en = Input(Bool()) // chip enable signal
//
- // Sending singals
+ // Sending signals
//
val noNewDataSender = Output(Bool()) // should sender finish sending buffers or not?
val dataValidOutput = Output(Bool()) // should sender send next buffer or not?
diff --git a/hwdbg/src/main/scala/hwdbg/communication/interpreter/send_success_or_error.scala b/hwdbg/src/main/scala/hwdbg/communication/interpreter/send_success_or_error.scala
index 8f7479c1..5ae70121 100644
--- a/hwdbg/src/main/scala/hwdbg/communication/interpreter/send_success_or_error.scala
+++ b/hwdbg/src/main/scala/hwdbg/communication/interpreter/send_success_or_error.scala
@@ -35,7 +35,7 @@ class InterpreterSendSuccessOrError(
val lastSuccessOrError = Input(UInt(instanceInfo.bramDataWidth.W)) // input last error
//
- // Sending singals
+ // Sending signals
//
val noNewDataSender = Output(Bool()) // should sender finish sending buffers or not?
val dataValidOutput = Output(Bool()) // should sender send next buffer or not?
diff --git a/hwdbg/src/main/scala/hwdbg/communication/receiver.scala b/hwdbg/src/main/scala/hwdbg/communication/receiver.scala
index fc66e717..e27f9635 100644
--- a/hwdbg/src/main/scala/hwdbg/communication/receiver.scala
+++ b/hwdbg/src/main/scala/hwdbg/communication/receiver.scala
@@ -351,7 +351,7 @@ class DebuggerPacketReceiver(
//
// The receiving is done at this stage, either
- // was successful of unsucessful, we'll release the
+ // was successful or unsuccessful, we'll release the
// sharing bram resource by indicating that the receiving
// module is no longer using the bram line
//
diff --git a/hwdbg/src/main/scala/hwdbg/communication/send_receive_synchronizer.scala b/hwdbg/src/main/scala/hwdbg/communication/send_receive_synchronizer.scala
index 9ecfb03a..4ebf5a74 100644
--- a/hwdbg/src/main/scala/hwdbg/communication/send_receive_synchronizer.scala
+++ b/hwdbg/src/main/scala/hwdbg/communication/send_receive_synchronizer.scala
@@ -160,7 +160,7 @@ class SendReceiveSynchronizer(
is(sIdle) {
//
- // Peform the resource sepration of shared BRAM
+ // Perform the resource separation of shared BRAM
// and apply priority to receive over send
//
when(io.plInSignal === true.B) {
diff --git a/hwdbg/src/main/scala/hwdbg/communication/sender.scala b/hwdbg/src/main/scala/hwdbg/communication/sender.scala
index fac3e389..e1c049d9 100644
--- a/hwdbg/src/main/scala/hwdbg/communication/sender.scala
+++ b/hwdbg/src/main/scala/hwdbg/communication/sender.scala
@@ -223,7 +223,7 @@ class DebuggerPacketSender(
wrData := HyperDbgSharedConstants.INDICATOR_OF_HYPERDBG_PACKET.U >> regTransferredIndicatorLength
//
- // Add to the length transfered
+ // Add to the transferred length
//
regTransferredIndicatorLength := regTransferredIndicatorLength + instanceInfo.bramDataWidth.U
diff --git a/hwdbg/src/main/scala/hwdbg/script/script_definitions.scala b/hwdbg/src/main/scala/hwdbg/script/script_definitions.scala
index 986aae7e..5471e834 100644
--- a/hwdbg/src/main/scala/hwdbg/script/script_definitions.scala
+++ b/hwdbg/src/main/scala/hwdbg/script/script_definitions.scala
@@ -45,6 +45,6 @@ object ScriptConstantTypes {
object ScriptEvalFunc {
object ScriptOperators extends ChiselEnum {
- val sFuncUndefined, sFuncInc, sFuncDec, sFuncReference, sFuncDereference, sFuncOr, sFuncXor, sFuncAnd, sFuncAsr, sFuncAsl, sFuncAdd, sFuncSub, sFuncMul, sFuncDiv, sFuncMod, sFuncGt, sFuncLt, sFuncEgt, sFuncElt, sFuncEqual, sFuncNeq, sFuncJmp, sFuncJz, sFuncJnz, sFuncMov, sFuncStart_of_do_while, sFuncStart_of_do_while_commands, sFuncEnd_of_do_while, sFuncStart_of_for, sFuncFor_inc_dec, sFuncStart_of_for_ommands, sFuncEnd_of_if, sFuncIgnore_lvalue, sFuncPush, sFuncPop, sFuncCall, sFuncRet, sFuncPrint, sFuncFormats, sFuncEvent_enable, sFuncEvent_disable, sFuncEvent_clear, sFuncTest_statement, sFuncSpinlock_lock, sFuncSpinlock_unlock, sFuncEvent_sc, sFuncMicrosleep, sFuncPrintf, sFuncPause, sFuncFlush, sFuncEvent_trace_step, sFuncEvent_trace_step_in, sFuncEvent_trace_step_out, sFuncEvent_trace_instrumentation_step, sFuncEvent_trace_instrumentation_step_in, sFuncRdtsc, sFuncRdtscp, sFuncSpinlock_lock_custom_wait, sFuncEvent_inject, sFuncPoi, sFuncDb, sFuncDd, sFuncDw, sFuncDq, sFuncNeg, sFuncHi, sFuncLow, sFuncNot, sFuncCheck_address, sFuncDisassemble_len, sFuncDisassemble_len32, sFuncDisassemble_len64, sFuncInterlocked_increment, sFuncInterlocked_decrement, sFuncPhysical_to_virtual, sFuncVirtual_to_physical, sFuncPoi_pa, sFuncHi_pa, sFuncLow_pa, sFuncDb_pa, sFuncDd_pa, sFuncDw_pa, sFuncDq_pa, sFuncEd, sFuncEb, sFuncEq, sFuncInterlocked_exchange, sFuncInterlocked_exchange_add, sFuncEb_pa, sFuncEd_pa, sFuncEq_pa, sFuncInterlocked_compare_exchange, sFuncStrlen, sFuncStrcmp, sFuncMemcmp, sFuncStrncmp, sFuncWcslen, sFuncWcscmp, sFuncEvent_inject_error_code, sFuncMemcpy, sFuncMemcpy_pa, sFuncWcsncmp = Value
+ val sFuncUndefined, sFuncInc, sFuncDec, sFuncReference, sFuncOr, sFuncXor, sFuncAnd, sFuncAsr, sFuncAsl, sFuncAdd, sFuncSub, sFuncMul, sFuncDiv, sFuncMod, sFuncGt, sFuncLt, sFuncEgt, sFuncElt, sFuncEqual, sFuncNeq, sFuncJmp, sFuncJz, sFuncJnz, sFuncMov, sFuncStart_of_do_while, sFuncStart_of_do_while_commands, sFuncEnd_of_do_while, sFuncStart_of_for, sFuncFor_inc_dec, sFuncStart_of_for_ommands, sFuncEnd_of_if, sFuncIgnore_lvalue, sFuncPush, sFuncPop, sFuncCall, sFuncRet, sFuncPrint, sFuncFormats, sFuncEvent_enable, sFuncEvent_disable, sFuncEvent_clear, sFuncTest_statement, sFuncSpinlock_lock, sFuncSpinlock_unlock, sFuncEvent_sc, sFuncMicrosleep, sFuncPrintf, sFuncPause, sFuncFlush, sFuncEvent_trace_step, sFuncEvent_trace_step_in, sFuncEvent_trace_step_out, sFuncEvent_trace_instrumentation_step, sFuncEvent_trace_instrumentation_step_in, sFuncRdtsc, sFuncRdtscp, sFuncLbr_save, sFuncLbr_dump, sFuncLbr_print, sFuncLbr_restore, sFuncLbr_check, sFuncSpinlock_lock_custom_wait, sFuncEvent_inject, sFuncPoi, sFuncDb, sFuncDd, sFuncDw, sFuncDq, sFuncNeg, sFuncHi, sFuncLow, sFuncNot, sFuncCheck_address, sFuncDisassemble_len, sFuncDisassemble_len32, sFuncDisassemble_len64, sFuncInterlocked_increment, sFuncInterlocked_decrement, sFuncPhysical_to_virtual, sFuncVirtual_to_physical, sFuncPoi_pa, sFuncHi_pa, sFuncLow_pa, sFuncDb_pa, sFuncDd_pa, sFuncDw_pa, sFuncDq_pa, sFuncLbr_restore_by_filter, sFuncEd, sFuncEb, sFuncEq, sFuncInterlocked_exchange, sFuncInterlocked_exchange_add, sFuncEb_pa, sFuncEd_pa, sFuncEq_pa, sFuncInterlocked_compare_exchange, sFuncStrlen, sFuncStrcmp, sFuncMemcmp, sFuncStrncmp, sFuncWcslen, sFuncWcscmp, sFuncEvent_inject_error_code, sFuncMemcpy, sFuncMemcpy_pa, sFuncWcsncmp = Value
}
}
\ No newline at end of file
diff --git a/hyperdbg/.clang-format b/hyperdbg/.clang-format
index 3dbd8e3f..2a528fa1 100644
--- a/hyperdbg/.clang-format
+++ b/hyperdbg/.clang-format
@@ -1,132 +1,3 @@
-Language: C
-BasedOnStyle: webkit
-AccessModifierOffset: -4
-
-AlignAfterOpenBracket: Align
-AlignConsecutiveAssignments: true
-AlignConsecutiveDeclarations: true
-
-AlignConsecutiveMacros: true
-
-AlignEscapedNewlines: Left
-AlignOperands: true
-
-AlignTrailingComments: true
-
-AllowAllArgumentsOnNextLine: false
-AllowAllParametersOfDeclarationOnNextLine: false
-
-AllowShortBlocksOnASingleLine: false
-AllowShortCaseLabelsOnASingleLine: false
-AllowShortFunctionsOnASingleLine: Inline
-AllowShortIfStatementsOnASingleLine: false
-AllowShortLoopsOnASingleLine: false
-AlwaysBreakAfterReturnType: TopLevel
-AlwaysBreakBeforeMultilineStrings: false
-
-AlwaysBreakTemplateDeclarations: true #false
-
-BinPackArguments: false
-BinPackParameters: false
-
-BreakBeforeBraces: Custom
-BraceWrapping:
- AfterCaseLabel: true
- AfterClass: true
- AfterControlStatement: true
- AfterEnum: true
- AfterFunction: true
- AfterNamespace: false
- AfterStruct: true
- AfterUnion: true
- AfterExternBlock: false
- BeforeCatch: true
- BeforeElse: true
-
-BreakBeforeBinaryOperators: None
-BreakBeforeTernaryOperators: true
-BreakConstructorInitializers: AfterColon
-BreakStringLiterals: false
-
-ColumnLimit: 0
-CommentPragmas: '^begin_wpp|^end_wpp|^FUNC |^USESUFFIX |^USESUFFIX '
-
-ConstructorInitializerAllOnOneLineOrOnePerLine: true
-ConstructorInitializerIndentWidth: 4
-ContinuationIndentWidth: 4
-Cpp11BracedListStyle: true
-
-DerivePointerAlignment: false
-ExperimentalAutoDetectBinPacking: false
-
-IndentCaseLabels: false
-IndentPPDirectives: AfterHash
-IndentWidth: 4
-
-KeepEmptyLinesAtTheStartOfBlocks: false
-
-MacroBlockBegin: '^BEGIN_MODULE$|^BEGIN_TEST_CLASS$|^BEGIN_TEST_METHOD$'
-MacroBlockEnd: '^END_MODULE$|^END_TEST_CLASS$|^END_TEST_METHOD$'
-
-MaxEmptyLinesToKeep: 1
-NamespaceIndentation: None #All
-PointerAlignment: Middle
-ReflowComments: true
-SortIncludes: false
-
-SpaceAfterCStyleCast: false
-SpaceBeforeAssignmentOperators: true
-SpaceBeforeCtorInitializerColon: true
-SpaceBeforeParens: ControlStatements
-SpaceBeforeRangeBasedForLoopColon: true
-SpaceInEmptyParentheses: false
-SpacesInAngles: false
-SpacesInCStyleCastParentheses: false
-SpacesInParentheses: false
-SpacesInSquareBrackets: false
-
-Standard: Cpp11
-StatementMacros: [
- 'EXTERN_C',
- 'PAGED',
- 'PAGEDX',
- 'NONPAGED',
- 'PNPCODE',
- 'INITCODE',
- '_At_',
- '_When_',
- '_Success_',
- '_Check_return_',
- '_Must_inspect_result_',
- '_IRQL_requires_same_',
- '_IRQL_requires_',
- '_IRQL_requires_max_',
- '_IRQL_requires_min_',
- '_IRQL_saves_',
- '_IRQL_restores_',
- '_IRQL_saves_global_',
- '_IRQL_restores_global_',
- '_IRQL_raises_',
- '_IRQL_lowers_',
- '_Acquires_lock_',
- '_Releases_lock_',
- '_Acquires_exclusive_lock_',
- '_Releases_exclusive_lock_',
- '_Acquires_shared_lock_',
- '_Releases_shared_lock_',
- '_Requires_lock_held_',
- '_Use_decl_annotations_',
- '_Guarded_by_',
- '__drv_preferredFunction',
- '__drv_allocatesMem',
- '__drv_freesMem',
- ]
-
-TabWidth: '4'
-UseTab: Never
-
----
-
Language: Cpp
BasedOnStyle: webkit
AccessModifierOffset: -4
@@ -252,4 +123,4 @@ StatementMacros: [
]
TabWidth: '4'
-UseTab: Never
+UseTab: Never
\ No newline at end of file
diff --git a/hyperdbg/CMakeLists.txt b/hyperdbg/CMakeLists.txt
index 8b460c13..ba5b3855 100644
--- a/hyperdbg/CMakeLists.txt
+++ b/hyperdbg/CMakeLists.txt
@@ -5,7 +5,11 @@ set(CMAKE_CXX_STANDARD 23)
enable_language(ASM_MASM)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
-list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
+if(LINUX)
+
+ message(STATUS "Building on Linux")
+elseif(WIN32)
+ message(STATUS "Building on Windows")
find_package(WDK REQUIRED)
include_directories(
@@ -48,22 +52,30 @@ target_link_libraries(hyperhv Zycore Zydis)
add_subdirectory(hyperkd)
target_link_libraries(hyperkd hyperlog hyperhv kdserial)
+endif()
-add_subdirectory(dependencies/pdbex/Source)
+#add_subdirectory(dependencies/pdbex/Source)
-add_subdirectory(symbol-parser)
-target_link_libraries(symbol-parser pdbex)
+#add_subdirectory(symbol-parser)
+#target_link_libraries(symbol-parser pdbex)
+#target_link_libraries(script-engine symbol-parser)
+
+#add_subdirectory(hyperdbg-test)
+
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
+
+#add_subdirectory(symbol-parser)
+#target_link_libraries(symbol-parser pdbex)
+
+#add_subdirectory(script-engine)
+#target_link_libraries(script-engine symbol-parser)
add_subdirectory(script-engine)
-target_link_libraries(script-engine symbol-parser)
-
link_directories(libraries/zydis/user libraries/keystone/release-lib)
add_subdirectory(libhyperdbg)
-target_link_libraries(libhyperdbg Zycore Zydis script-engine keystone)
-
-
-add_subdirectory(hyperdbg-test)
+find_package(Threads REQUIRED)
+target_link_libraries(libhyperdbg Zycore Zydis script-engine keystone Threads::Threads)
add_subdirectory(hyperdbg-cli)
target_link_libraries(hyperdbg-cli libhyperdbg)
diff --git a/hyperdbg/dependencies/ia32-doc b/hyperdbg/dependencies/ia32-doc
index 6ef251e3..2bc5284e 160000
--- a/hyperdbg/dependencies/ia32-doc
+++ b/hyperdbg/dependencies/ia32-doc
@@ -1 +1 @@
-Subproject commit 6ef251e3e58c759fda025c186ef0f44c556c14c1
+Subproject commit 2bc5284e04ff862220def160517bc72baf3d1a03
diff --git a/hyperdbg/dependencies/libipt/intel-pt.h b/hyperdbg/dependencies/libipt/intel-pt.h
new file mode 100644
index 00000000..4b90482c
--- /dev/null
+++ b/hyperdbg/dependencies/libipt/intel-pt.h
@@ -0,0 +1,3177 @@
+/*
+ * Copyright (C) 2013-2026 Intel Corporation
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef INTEL_PT_H
+#define INTEL_PT_H
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Intel(R) Processor Trace (Intel PT) decoder library.
+ *
+ * This file is logically structured into the following sections:
+ *
+ * - Version
+ * - Errors
+ * - Configuration
+ * - Packet encoder / decoder
+ * - Event decoder
+ * - Query decoder
+ * - Traced image
+ * - Instruction flow decoder
+ * - Block decoder
+ */
+
+
+
+struct pt_encoder;
+struct pt_packet_decoder;
+struct pt_event_decoder;
+struct pt_query_decoder;
+struct pt_insn_decoder;
+struct pt_block_decoder;
+
+
+
+/* A macro to mark functions as exported. */
+#ifndef pt_export
+# if defined(__GNUC__)
+# define pt_export __attribute__((visibility("default")))
+# elif defined(_MSC_VER)
+# define pt_export __declspec(dllimport)
+# else
+# error "unknown compiler"
+# endif
+#endif
+
+
+
+/* Version. */
+
+
+/** The header version. */
+#define LIBIPT_VERSION_MAJOR 2
+#define LIBIPT_VERSION_MINOR 3
+#define LIBIPT_VERSION_PATCH 0
+
+#define LIBIPT_VERSION ((LIBIPT_VERSION_MAJOR << 8) + LIBIPT_VERSION_MINOR)
+
+
+/** The library version. */
+struct pt_version {
+ /** Major version number. */
+ uint8_t major;
+
+ /** Minor version number. */
+ uint8_t minor;
+
+ /** Patch level. */
+ uint16_t patch;
+
+ /** Build number. */
+ uint32_t build;
+
+ /** Version extension. */
+ const char *ext;
+};
+
+
+/** Return the library version. */
+extern pt_export struct pt_version pt_library_version(void);
+
+
+
+/* Errors. */
+
+
+
+/** Error codes. */
+enum pt_error_code {
+ /* No error. Everything is OK. */
+ pte_ok,
+
+ /* Internal decoder error. */
+ pte_internal,
+
+ /* Invalid argument. */
+ pte_invalid,
+
+ /* Decoder out of sync. */
+ pte_nosync,
+
+ /* Unknown opcode. */
+ pte_bad_opc,
+
+ /* Unknown payload. */
+ pte_bad_packet,
+
+ /* Unexpected packet context. */
+ pte_bad_context,
+
+ /* Decoder reached end of trace stream. */
+ pte_eos,
+
+ /* No packet matching the query to be found. */
+ pte_bad_query,
+
+ /* Decoder out of memory. */
+ pte_nomem,
+
+ /* Bad configuration. */
+ pte_bad_config,
+
+ /* There is no IP. */
+ pte_noip,
+
+ /* The IP has been suppressed. */
+ pte_ip_suppressed,
+
+ /* There is no memory mapped at the requested address. */
+ pte_nomap,
+
+ /* An instruction could not be decoded. */
+ pte_bad_insn,
+
+ /* No wall-clock time is available. */
+ pte_no_time,
+
+ /* No core:bus ratio available. */
+ pte_no_cbr,
+
+ /* Bad traced image. */
+ pte_bad_image,
+
+ /* A locking error. */
+ pte_bad_lock,
+
+ /* The requested feature is not supported. */
+ pte_not_supported,
+
+ /* The return address stack is empty. */
+ pte_retstack_empty,
+
+ /* A compressed return is not indicated correctly by a taken branch. */
+ pte_bad_retcomp,
+
+ /* The current decoder state does not match the state in the trace. */
+ pte_bad_status_update,
+
+ /* The trace did not contain an expected enabled event. */
+ pte_no_enable,
+
+ /* An event was ignored. */
+ pte_event_ignored,
+
+ /* Something overflowed. */
+ pte_overflow,
+
+ /* A file handling error. */
+ pte_bad_file,
+
+ /* Unknown cpu. */
+ pte_bad_cpu
+};
+
+
+/** Decode a function return value into an pt_error_code. */
+static inline enum pt_error_code pt_errcode(int status)
+{
+ return (status >= 0) ? pte_ok : (enum pt_error_code) -status;
+}
+
+/** Return a human readable error string. */
+extern pt_export const char *pt_errstr(enum pt_error_code);
+
+
+
+/* Configuration. */
+
+
+
+/** A cpu vendor. */
+enum pt_cpu_vendor {
+ pcv_unknown,
+ pcv_intel
+};
+
+/** A cpu identifier. */
+struct pt_cpu {
+ /** The cpu vendor. */
+ enum pt_cpu_vendor vendor;
+
+ /** The cpu family. */
+ uint16_t family;
+
+ /** The cpu model. */
+ uint8_t model;
+
+ /** The stepping. */
+ uint8_t stepping;
+};
+
+/** A collection of Intel PT errata. */
+struct pt_errata {
+ /** BDM70: Intel(R) Processor Trace PSB+ Packets May Contain
+ * Unexpected Packets.
+ *
+ * Same as: SKD024, SKL021, KBL021.
+ *
+ * Some Intel Processor Trace packets should be issued only between
+ * TIP.PGE and TIP.PGD packets. Due to this erratum, when a TIP.PGE
+ * packet is generated it may be preceded by a PSB+ that incorrectly
+ * includes FUP and MODE.Exec packets.
+ */
+ uint32_t bdm70:1;
+
+ /** BDM64: An Incorrect LBR or Intel(R) Processor Trace Packet May Be
+ * Recorded Following a Transactional Abort.
+ *
+ * Use of Intel(R) Transactional Synchronization Extensions (Intel(R)
+ * TSX) may result in a transactional abort. If an abort occurs
+ * immediately following a branch instruction, an incorrect branch
+ * target may be logged in an LBR (Last Branch Record) or in an Intel(R)
+ * Processor Trace (Intel(R) PT) packet before the LBR or Intel PT
+ * packet produced by the abort.
+ */
+ uint32_t bdm64:1;
+
+ /** SKD007: Intel(R) PT Buffer Overflow May Result in Incorrect Packets.
+ *
+ * Same as: SKL049, KBL041.
+ *
+ * Under complex micro-architectural conditions, an Intel PT (Processor
+ * Trace) OVF (Overflow) packet may be issued after the first byte of a
+ * multi-byte CYC (Cycle Count) packet, instead of any remaining bytes
+ * of the CYC.
+ */
+ uint32_t skd007:1;
+
+ /** SKD022: VM Entry That Clears TraceEn May Generate a FUP.
+ *
+ * Same as: SKL024, KBL023.
+ *
+ * If VM entry clears Intel(R) PT (Intel Processor Trace)
+ * IA32_RTIT_CTL.TraceEn (MSR 570H, bit 0) while PacketEn is 1 then a
+ * FUP (Flow Update Packet) will precede the TIP.PGD (Target IP Packet,
+ * Packet Generation Disable). VM entry can clear TraceEn if the
+ * VM-entry MSR-load area includes an entry for the IA32_RTIT_CTL MSR.
+ */
+ uint32_t skd022:1;
+
+ /** SKD010: Intel(R) PT FUP May be Dropped After OVF.
+ *
+ * Same as: SKD014, SKL033, KBL030.
+ *
+ * Some Intel PT (Intel Processor Trace) OVF (Overflow) packets may not
+ * be followed by a FUP (Flow Update Packet) or TIP.PGE (Target IP
+ * Packet, Packet Generation Enable).
+ */
+ uint32_t skd010:1;
+
+ /** SKL014: Intel(R) PT TIP.PGD May Not Have Target IP Payload.
+ *
+ * Same as: KBL014.
+ *
+ * When Intel PT (Intel Processor Trace) is enabled and a direct
+ * unconditional branch clears IA32_RTIT_STATUS.FilterEn (MSR 571H, bit
+ * 0), due to this erratum, the resulting TIP.PGD (Target IP Packet,
+ * Packet Generation Disable) may not have an IP payload with the target
+ * IP.
+ */
+ uint32_t skl014:1;
+
+ /** APL12: Intel(R) PT OVF May Be Followed By An Unexpected FUP Packet.
+ *
+ * Certain Intel PT (Processor Trace) packets including FUPs (Flow
+ * Update Packets), should be issued only between TIP.PGE (Target IP
+ * Packet - Packet Generation Enable) and TIP.PGD (Target IP Packet -
+ * Packet Generation Disable) packets. When outside a TIP.PGE/TIP.PGD
+ * pair, as a result of IA32_RTIT_STATUS.FilterEn[0] (MSR 571H) being
+ * cleared, an OVF (Overflow) packet may be unexpectedly followed by a
+ * FUP.
+ */
+ uint32_t apl12:1;
+
+ /** APL11: Intel(R) PT OVF Packet May Be Followed by TIP.PGD Packet
+ *
+ * If Intel PT (Processor Trace) encounters an internal buffer overflow
+ * and generates an OVF (Overflow) packet just as IA32_RTIT_CTL (MSR
+ * 570H) bit 0 (TraceEn) is cleared, or during a far transfer that
+ * causes IA32_RTIT_STATUS.ContextEn[1] (MSR 571H) to be cleared, the
+ * OVF may be followed by a TIP.PGD (Target Instruction Pointer - Packet
+ * Generation Disable) packet.
+ */
+ uint32_t apl11:1;
+
+ /** SKL168: Intel(R) PT CYC Packets Can be Dropped When Immediately
+ * Preceding PSB
+ *
+ * Due to a rare microarchitectural condition, generation of an Intel
+ * PT (Processor Trace) PSB (Packet Stream Boundary) packet can cause a
+ * single CYC (Cycle Count) packet, possibly along with an associated
+ * MTC (Mini Time Counter) packet, to be dropped.
+ */
+ uint32_t skl168:1;
+
+ /** SKZ84: Use of VMX TSC Scaling or TSC Offsetting Will Result in
+ * Corrupted Intel PT Packets
+ *
+ * When Intel(R) PT (Processor Trace) is enabled within a VMX (Virtual
+ * Machine Extensions) guest, and TSC (Time Stamp Counter) offsetting
+ * or TSC scaling is enabled for that guest, by setting primary
+ * processor-based execution control bit 3 or secondary processor-based
+ * execution control bit 25, respectively, in the VMCS (Virtual Machine
+ * Control Structure) for that guest, any TMA (TSC(MTC Alignment)
+ * packet generated will have corrupted values in the CTC (Core Timer
+ * Copy) and FastCounter fields. Additionally, the corrupted TMA
+ * packet will be followed by a bogus data byte.
+ */
+ uint32_t skz84:1;
+
+ /* Reserve a few bytes for the future. */
+ uint32_t reserved[15];
+};
+
+/** A collection of decoder-specific configuration flags. */
+struct pt_conf_flags {
+ /** The decoder variant. */
+ union {
+ /** Flags for the block decoder. */
+ struct {
+ /** End a block after a call instruction. */
+ uint32_t end_on_call:1;
+
+ /** Enable tick events for timing updates. */
+ uint32_t enable_tick_events:1;
+
+ /** End a block after a jump instruction. */
+ uint32_t end_on_jump:1;
+
+#if (LIBIPT_VERSION >= 0x201)
+ /** Preserve timing calibration on overflow. */
+ uint32_t keep_tcal_on_ovf:1;
+
+ /** Enable iflags events.
+ *
+ * Use this only when Event Tracing was enabled via
+ * IA32_RTIT_CTL[31].
+ */
+ uint32_t enable_iflags_events:1;
+#endif
+ } block;
+
+ /** Flags for the instruction flow decoder. */
+ struct {
+ /** Enable tick events for timing updates. */
+ uint32_t enable_tick_events:1;
+
+#if (LIBIPT_VERSION >= 0x201)
+ /** Preserve timing calibration on overflow. */
+ uint32_t keep_tcal_on_ovf:1;
+
+ /** Enable iflags events.
+ *
+ * Use this only when Event Tracing was enabled via
+ * IA32_RTIT_CTL[31].
+ */
+ uint32_t enable_iflags_events:1;
+#endif
+ } insn;
+
+#if (LIBIPT_VERSION >= 0x201)
+ /** Flags for the query decoder. */
+ struct {
+ /** Preserve timing calibration on overflow. */
+ uint32_t keep_tcal_on_ovf:1;
+
+ /** Enable iflags events.
+ *
+ * Use this only when Event Tracing was enabled via
+ * IA32_RTIT_CTL[31].
+ */
+ uint32_t enable_iflags_events:1;
+ } query;
+
+ /** Flags for the event decoder. */
+ struct {
+ /** Preserve timing calibration on overflow. */
+ uint32_t keep_tcal_on_ovf:1;
+
+ /** Enable iflags events.
+ *
+ * Use this only when Event Tracing was enabled via
+ * IA32_RTIT_CTL[31].
+ */
+ uint32_t enable_iflags_events:1;
+ } event;
+#endif /* (LIBIPT_VERSION >= 0x201) */
+
+ /* Reserve a few bytes for future extensions. */
+ uint32_t reserved[4];
+ } variant;
+};
+
+/** The address filter configuration. */
+struct pt_conf_addr_filter {
+ /** The address filter configuration.
+ *
+ * This corresponds to the respective fields in IA32_RTIT_CTL MSR.
+ */
+ union {
+ uint64_t addr_cfg;
+
+ struct {
+ uint32_t addr0_cfg:4;
+ uint32_t addr1_cfg:4;
+ uint32_t addr2_cfg:4;
+ uint32_t addr3_cfg:4;
+ } ctl;
+ } config;
+
+ /** The address ranges configuration.
+ *
+ * This corresponds to the IA32_RTIT_ADDRn_A/B MSRs.
+ */
+ uint64_t addr0_a;
+ uint64_t addr0_b;
+ uint64_t addr1_a;
+ uint64_t addr1_b;
+ uint64_t addr2_a;
+ uint64_t addr2_b;
+ uint64_t addr3_a;
+ uint64_t addr3_b;
+
+ /* Reserve some space. */
+ uint64_t reserved[8];
+};
+
+/** An unknown packet. */
+struct pt_packet_unknown;
+
+/** An Intel PT decoder configuration.
+ */
+struct pt_config {
+ /** The size of the config structure in bytes. */
+ size_t size;
+
+ /** The trace buffer begin address. */
+ uint8_t *begin;
+
+ /** The trace buffer end address. */
+ uint8_t *end;
+
+ /** An optional callback for handling unknown packets.
+ *
+ * If \@callback is not NULL, it is called for any unknown opcode.
+ */
+ struct {
+ /** The callback function.
+ *
+ * It shall decode the packet at \@pos into \@unknown.
+ * It shall return the number of bytes read upon success.
+ * It shall return a negative pt_error_code otherwise.
+ * The below context is passed as \@context.
+ */
+ int (*callback)(struct pt_packet_unknown *unknown,
+ const struct pt_config *config,
+ const uint8_t *pos, void *context);
+
+ /** The user-defined context for this configuration. */
+ void *context;
+ } decode;
+
+ /** The cpu on which Intel PT has been recorded. */
+ struct pt_cpu cpu;
+
+ /** The errata to apply when encoding or decoding Intel PT. */
+ struct pt_errata errata;
+
+ /* The CTC frequency.
+ *
+ * This is only required if MTC packets have been enabled in
+ * IA32_RTIT_CTRL.MTCEn.
+ */
+ uint32_t cpuid_0x15_eax, cpuid_0x15_ebx;
+
+ /* The MTC frequency as defined in IA32_RTIT_CTL.MTCFreq.
+ *
+ * This is only required if MTC packets have been enabled in
+ * IA32_RTIT_CTRL.MTCEn.
+ */
+ uint8_t mtc_freq;
+
+ /* The nominal frequency as defined in MSR_PLATFORM_INFO[15:8].
+ *
+ * This is only required if CYC packets have been enabled in
+ * IA32_RTIT_CTRL.CYCEn.
+ *
+ * If zero, timing calibration will only be able to use MTC and CYC
+ * packets.
+ *
+ * If not zero, timing calibration will also be able to use CBR
+ * packets.
+ */
+ uint8_t nom_freq;
+
+ /** A collection of decoder-specific flags. */
+ struct pt_conf_flags flags;
+
+ /** The address filter configuration. */
+ struct pt_conf_addr_filter addr_filter;
+};
+
+
+/** Zero-initialize an Intel PT configuration. */
+static inline void pt_config_init(struct pt_config *config)
+{
+ memset(config, 0, sizeof(*config));
+
+ config->size = sizeof(*config);
+}
+
+/** Determine errata for a given cpu.
+ *
+ * Updates \@errata based on \@cpu.
+ *
+ * Returns 0 on success, a negative error code otherwise.
+ * Returns -pte_invalid if \@errata or \@cpu is NULL.
+ * Returns -pte_bad_cpu if \@cpu is not known.
+ */
+extern pt_export int pt_cpu_errata(struct pt_errata *errata,
+ const struct pt_cpu *cpu);
+
+
+
+/* Packet encoder / decoder. */
+
+
+
+/** Intel PT packet types. */
+enum pt_packet_type {
+ /* An invalid packet. */
+ ppt_invalid,
+
+ /* A packet decodable by the optional decoder callback. */
+ ppt_unknown,
+
+ /* Actual packets supported by this library. */
+ ppt_pad,
+ ppt_psb,
+ ppt_psbend,
+ ppt_fup,
+ ppt_tip,
+ ppt_tip_pge,
+ ppt_tip_pgd,
+ ppt_tnt_8,
+ ppt_tnt_64,
+ ppt_mode,
+ ppt_pip,
+ ppt_vmcs,
+ ppt_cbr,
+ ppt_tsc,
+ ppt_tma,
+ ppt_mtc,
+ ppt_cyc,
+ ppt_stop,
+ ppt_ovf,
+ ppt_mnt,
+ ppt_exstop,
+ ppt_mwait,
+ ppt_pwre,
+ ppt_pwrx,
+ ppt_ptw,
+#if (LIBIPT_VERSION >= 0x201)
+ ppt_cfe,
+ ppt_evd,
+#endif
+#if (LIBIPT_VERSION >= 0x202)
+ ppt_trig,
+#endif
+};
+
+/** The IP compression. */
+enum pt_ip_compression {
+ /* The bits encode the payload size and the encoding scheme.
+ *
+ * No payload. The IP has been suppressed.
+ */
+ pt_ipc_suppressed = 0x0,
+
+ /* Payload: 16 bits. Update last IP. */
+ pt_ipc_update_16 = 0x01,
+
+ /* Payload: 32 bits. Update last IP. */
+ pt_ipc_update_32 = 0x02,
+
+ /* Payload: 48 bits. Sign extend to full address. */
+ pt_ipc_sext_48 = 0x03,
+
+ /* Payload: 48 bits. Update last IP. */
+ pt_ipc_update_48 = 0x04,
+
+ /* Payload: 64 bits. Full address. */
+ pt_ipc_full = 0x06
+};
+
+/** An execution mode. */
+enum pt_exec_mode {
+ ptem_unknown,
+ ptem_16bit,
+ ptem_32bit,
+ ptem_64bit
+};
+
+/** Mode packet leaves. */
+enum pt_mode_leaf {
+ pt_mol_exec = 0x00,
+ pt_mol_tsx = 0x20
+};
+
+/** A TNT-8 or TNT-64 packet. */
+struct pt_packet_tnt {
+ /** TNT payload bit size. */
+ uint8_t bit_size;
+
+ /** TNT payload excluding stop bit. */
+ uint64_t payload;
+};
+
+/** A packet with IP payload. */
+struct pt_packet_ip {
+ /** IP compression. */
+ enum pt_ip_compression ipc;
+
+ /** Zero-extended payload ip. */
+ uint64_t ip;
+};
+
+/** A mode.exec packet. */
+struct pt_packet_mode_exec {
+ /** The mode.exec csl bit. */
+ uint32_t csl:1;
+
+ /** The mode.exec csd bit. */
+ uint32_t csd:1;
+
+#if (LIBIPT_VERSION >= 0x201)
+ /** The mode.exec if bit.
+ *
+ * Enable Event Tracing to get updates when IF changes.
+ */
+ uint32_t iflag:1;
+#endif
+};
+
+static inline enum pt_exec_mode
+pt_get_exec_mode(const struct pt_packet_mode_exec *packet)
+{
+ if (packet->csl)
+ return packet->csd ? ptem_unknown : ptem_64bit;
+ else
+ return packet->csd ? ptem_32bit : ptem_16bit;
+}
+
+static inline struct pt_packet_mode_exec
+pt_set_exec_mode(enum pt_exec_mode mode)
+{
+ struct pt_packet_mode_exec packet;
+
+ memset(&packet, 0, sizeof(packet));
+ switch (mode) {
+ default:
+ packet.csl = 1;
+ packet.csd = 1;
+ break;
+
+ case ptem_64bit:
+ packet.csl = 1;
+ break;
+
+ case ptem_32bit:
+ packet.csd = 1;
+ break;
+
+ case ptem_16bit:
+ break;
+ }
+
+ return packet;
+}
+
+/** A mode.tsx packet. */
+struct pt_packet_mode_tsx {
+ /** The mode.tsx intx bit. */
+ uint32_t intx:1;
+
+ /** The mode.tsx abrt bit. */
+ uint32_t abrt:1;
+};
+
+/** A mode packet. */
+struct pt_packet_mode {
+ /** Mode leaf. */
+ enum pt_mode_leaf leaf;
+
+ /** Mode bits. */
+ union {
+ /** Packet: mode.exec. */
+ struct pt_packet_mode_exec exec;
+
+ /** Packet: mode.tsx. */
+ struct pt_packet_mode_tsx tsx;
+ } bits;
+};
+
+/** A PIP packet. */
+struct pt_packet_pip {
+ /** The CR3 value. */
+ uint64_t cr3;
+
+ /** The non-root bit. */
+ uint32_t nr:1;
+};
+
+/** A TSC packet. */
+struct pt_packet_tsc {
+ /** The TSC value. */
+ uint64_t tsc;
+};
+
+/** A CBR packet. */
+struct pt_packet_cbr {
+ /** The core/bus cycle ratio. */
+ uint8_t ratio;
+};
+
+/** A TMA packet. */
+struct pt_packet_tma {
+ /** The crystal clock tick counter value. */
+ uint16_t ctc;
+
+ /** The fast counter value. */
+ uint16_t fc;
+};
+
+/** A MTC packet. */
+struct pt_packet_mtc {
+ /** The crystal clock tick counter value. */
+ uint8_t ctc;
+};
+
+/** A CYC packet. */
+struct pt_packet_cyc {
+ /** The cycle counter value. */
+ uint64_t value;
+};
+
+/** A VMCS packet. */
+struct pt_packet_vmcs {
+ /* The VMCS Base Address (i.e. the shifted payload). */
+ uint64_t base;
+};
+
+/** A MNT packet. */
+struct pt_packet_mnt {
+ /** The raw payload. */
+ uint64_t payload;
+};
+
+/** A EXSTOP packet. */
+struct pt_packet_exstop {
+ /** A flag specifying the binding of the packet:
+ *
+ * set: binds to the next FUP.
+ * clear: standalone.
+ */
+ uint32_t ip:1;
+};
+
+/** A MWAIT packet. */
+struct pt_packet_mwait {
+ /** The MWAIT hints (EAX). */
+ uint32_t hints;
+
+ /** The MWAIT extensions (ECX). */
+ uint32_t ext;
+};
+
+/** A PWRE packet. */
+struct pt_packet_pwre {
+ /** The resolved thread C-state. */
+ uint8_t state;
+
+ /** The resolved thread sub C-state. */
+ uint8_t sub_state;
+
+ /** A flag indicating whether the C-state entry was initiated by h/w. */
+ uint32_t hw:1;
+};
+
+/** A PWRX packet. */
+struct pt_packet_pwrx {
+ /** The core C-state at the time of the wake. */
+ uint8_t last;
+
+ /** The deepest core C-state achieved during sleep. */
+ uint8_t deepest;
+
+ /** The wake reason:
+ *
+ * - due to external interrupt received.
+ */
+ uint32_t interrupt:1;
+
+ /** - due to store to monitored address. */
+ uint32_t store:1;
+
+ /** - due to h/w autonomous condition such as HDC. */
+ uint32_t autonomous:1;
+};
+
+/** A PTW packet. */
+struct pt_packet_ptw {
+ /** The raw payload. */
+ uint64_t payload;
+
+ /** The payload size as encoded in the packet. */
+ uint8_t plc;
+
+ /** A flag saying whether a FUP is following PTW that provides
+ * the IP of the corresponding PTWRITE instruction.
+ */
+ uint32_t ip:1;
+};
+
+static inline int pt_ptw_size(uint8_t plc)
+{
+ switch (plc) {
+ case 0:
+ return 4;
+
+ case 1:
+ return 8;
+
+ case 2:
+ case 3:
+ return -pte_bad_packet;
+ }
+
+ return -pte_internal;
+}
+
+#if (LIBIPT_VERSION >= 0x201)
+/* Control-flow event types. */
+enum pt_cfe_type {
+ pt_cfe_intr = 0x01,
+ pt_cfe_iret = 0x02,
+ pt_cfe_smi = 0x03,
+ pt_cfe_rsm = 0x04,
+ pt_cfe_sipi = 0x05,
+ pt_cfe_init = 0x06,
+ pt_cfe_vmentry = 0x07,
+ pt_cfe_vmexit = 0x08,
+ pt_cfe_vmexit_intr = 0x09,
+ pt_cfe_shutdown = 0x0a,
+ pt_cfe_uintr = 0x0c,
+ pt_cfe_uiret = 0x0d,
+#if (LIBIPT_VERSION >= 0x202)
+ pt_cfe_swintr = 0x0e,
+ pt_cfe_syscall = 0x0f,
+#endif
+};
+
+/* Interrupt vectors defined in Table 6-1 in §6.5 of Vol.1 of the SDM. */
+enum pt_cfe_intr {
+ pt_cfe_intr_de = 0, /* Divide Error. */
+ pt_cfe_intr_db = 1, /* Debug. */
+ pt_cfe_intr_nmi = 2, /* Non Maskable Interrupt. */
+ pt_cfe_intr_bp = 3, /* Breakpoint. */
+ pt_cfe_intr_of = 4, /* Overflow. */
+ pt_cfe_intr_br = 5, /* Bound Range Exceeded. */
+ pt_cfe_intr_ud = 6, /* Undefined Opcode. */
+ pt_cfe_intr_nm = 7, /* Device Not Available. */
+ pt_cfe_intr_df = 8, /* Double Fault. */
+ pt_cfe_intr_ts = 10, /* Invalid TSS. */
+ pt_cfe_intr_np = 11, /* Segment Not Present. */
+ pt_cfe_intr_ss = 12, /* Stack Segment Fault. */
+ pt_cfe_intr_gp = 13, /* General Protection Fault. */
+ pt_cfe_intr_pf = 14, /* Page Fault. */
+ pt_cfe_intr_mf = 16, /* Math Fault. */
+ pt_cfe_intr_ac = 17, /* Alignment Check. */
+ pt_cfe_intr_mc = 18, /* Machine Check. */
+ pt_cfe_intr_xm = 19, /* SIMD Floating Point Exception. */
+ pt_cfe_intr_ve = 20, /* Virtualization Exception. */
+ pt_cfe_intr_cp = 21, /* Control Protection Exception. */
+};
+
+/** A CFE packet. */
+struct pt_packet_cfe {
+ /** The type of control-flow event. */
+ enum pt_cfe_type type;
+
+ /** The vector depending on the type:
+ *
+ * pt_cfe_intr: the event vector.
+ * pt_cfe_vmexit_intr: the event vector.
+ * pt_cfe_sipi: the SIPI vector.
+ * pt_cfe_uintr: the user interrupt vector.
+ * pt_cfe_swintr: the event vector.
+ */
+ uint8_t vector;
+
+ /** A flag specifying the binding of the packet:
+ *
+ * set: binds to the next FUP.
+ * clear: binds to the next FUP + TIP, if tracing enabled.
+ * clear: standalone, if tracing disabled.
+ */
+ uint32_t ip:1;
+};
+
+/* Event data types. */
+enum pt_evd_type {
+ pt_evd_cr2 = 0x00, /* Page fault linear address (cr2). */
+ pt_evd_vmxq = 0x01, /* VMX exit qualification. */
+ pt_evd_vmxr = 0x02, /* VMX exit reason. */
+};
+
+/** A EVD packet. */
+struct pt_packet_evd {
+ /** The type of control-flow event. */
+ enum pt_evd_type type;
+
+ /** The payload depending on the type:
+ *
+ * 0x00: page fault linear address (cr2).
+ * 0x01: vmx exit qualification.
+ * 0x02: vmx exit reason.
+ */
+ uint64_t payload;
+};
+#endif /* (LIBIPT_VERSION >= 0x201) */
+
+#if (LIBIPT_VERSION >= 0x202)
+/** A TRIG packet. */
+struct pt_packet_trig {
+ /** A bit vector of triggers that are represented by this packet. */
+ uint8_t trbv;
+
+ /** An instruction count from the last IP packet (FUP, TIP*, or TNT)
+ * indicating the instruction to which this packet is attributed.
+ *
+ * This field is only valid if \@icntv is set.
+ */
+ uint16_t icnt;
+
+ /** A flag saying whether a FUP is following TRIG that provides a
+ * reference IP from which to start counting.
+ */
+ uint32_t ip:1;
+
+ /** A flag saying whether the \@icnt field is valid.*/
+ uint32_t icntv:1;
+
+ /** A flag saying whether there were other triggers firing that are not
+ * reported.
+ */
+ uint32_t mult:1;
+};
+#endif /* (LIBIPT_VERSION >= 0x202) */
+
+/** An unknown packet decodable by the optional decoder callback. */
+struct pt_packet_unknown {
+ /** Pointer to the raw packet bytes. */
+ const uint8_t *packet;
+
+ /** Optional pointer to a user-defined structure. */
+ void *priv;
+};
+
+/** An Intel PT packet. */
+struct pt_packet {
+ /** The type of the packet.
+ *
+ * This also determines the \@payload field.
+ */
+ enum pt_packet_type type;
+
+ /** The size of the packet including opcode and payload. */
+ uint8_t size;
+
+ /** Packet specific data. */
+ union {
+ /** Packets: pad, ovf, psb, psbend, stop - no payload. */
+
+ /** Packet: tnt-8, tnt-64. */
+ struct pt_packet_tnt tnt;
+
+ /** Packet: tip, fup, tip.pge, tip.pgd. */
+ struct pt_packet_ip ip;
+
+ /** Packet: mode. */
+ struct pt_packet_mode mode;
+
+ /** Packet: pip. */
+ struct pt_packet_pip pip;
+
+ /** Packet: tsc. */
+ struct pt_packet_tsc tsc;
+
+ /** Packet: cbr. */
+ struct pt_packet_cbr cbr;
+
+ /** Packet: tma. */
+ struct pt_packet_tma tma;
+
+ /** Packet: mtc. */
+ struct pt_packet_mtc mtc;
+
+ /** Packet: cyc. */
+ struct pt_packet_cyc cyc;
+
+ /** Packet: vmcs. */
+ struct pt_packet_vmcs vmcs;
+
+ /** Packet: mnt. */
+ struct pt_packet_mnt mnt;
+
+ /** Packet: exstop. */
+ struct pt_packet_exstop exstop;
+
+ /** Packet: mwait. */
+ struct pt_packet_mwait mwait;
+
+ /** Packet: pwre. */
+ struct pt_packet_pwre pwre;
+
+ /** Packet: pwrx. */
+ struct pt_packet_pwrx pwrx;
+
+ /** Packet: ptw. */
+ struct pt_packet_ptw ptw;
+
+#if (LIBIPT_VERSION >= 0x201)
+ /** Packet: cfe. */
+ struct pt_packet_cfe cfe;
+
+ /** Packet: evd. */
+ struct pt_packet_evd evd;
+#endif
+#if (LIBIPT_VERSION >= 0x202)
+ /** Packet: trig. */
+ struct pt_packet_trig trig;
+#endif
+ /** Packet: unknown. */
+ struct pt_packet_unknown unknown;
+ } payload;
+};
+
+
+
+/* Packet encoder. */
+
+
+
+/** Allocate an Intel PT packet encoder.
+ *
+ * The encoder will work on the buffer defined in \@config, it shall contain
+ * raw trace data and remain valid for the lifetime of the encoder.
+ *
+ * The encoder starts at the beginning of the trace buffer.
+ */
+extern pt_export struct pt_encoder *
+pt_alloc_encoder(const struct pt_config *config);
+
+/** Free an Intel PT packet encoder.
+ *
+ * The \@encoder must not be used after a successful return.
+ */
+extern pt_export void pt_free_encoder(struct pt_encoder *encoder);
+
+/** Hard set synchronization point of an Intel PT packet encoder.
+ *
+ * Synchronize \@encoder to \@offset within the trace buffer.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_eos if the given offset is behind the end of the trace buffer.
+ * Returns -pte_invalid if \@encoder is NULL.
+ */
+extern pt_export int pt_enc_sync_set(struct pt_encoder *encoder,
+ uint64_t offset);
+
+/** Get the current packet encoder position.
+ *
+ * Fills the current \@encoder position into \@offset.
+ *
+ * This is useful for reporting errors.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@encoder or \@offset is NULL.
+ */
+extern pt_export int pt_enc_get_offset(const struct pt_encoder *encoder,
+ uint64_t *offset);
+
+/* Return a pointer to \@encoder's configuration.
+ *
+ * Returns a non-null pointer on success, NULL if \@encoder is NULL.
+ */
+extern pt_export const struct pt_config *
+pt_enc_get_config(const struct pt_encoder *encoder);
+
+/** Encode an Intel PT packet.
+ *
+ * Writes \@packet at \@encoder's current position in the Intel PT buffer and
+ * advances the \@encoder beyond the written packet.
+ *
+ * The \@packet.size field is ignored.
+ *
+ * In case of errors, the \@encoder is not advanced and nothing is written
+ * into the Intel PT buffer.
+ *
+ * Returns the number of bytes written on success, a negative error code
+ * otherwise.
+ *
+ * Returns -pte_bad_opc if \@packet.type is not known.
+ * Returns -pte_bad_packet if \@packet's payload is invalid.
+ * Returns -pte_eos if \@encoder reached the end of the Intel PT buffer.
+ * Returns -pte_invalid if \@encoder or \@packet is NULL.
+ */
+extern pt_export int pt_enc_next(struct pt_encoder *encoder,
+ const struct pt_packet *packet);
+
+
+
+/* Packet decoder. */
+
+
+
+/** Allocate an Intel PT packet decoder.
+ *
+ * The decoder will work on the buffer defined in \@config, it shall contain
+ * raw trace data and remain valid for the lifetime of the decoder.
+ *
+ * The decoder needs to be synchronized before it can be used.
+ */
+extern pt_export struct pt_packet_decoder *
+pt_pkt_alloc_decoder(const struct pt_config *config);
+
+/** Free an Intel PT packet decoder.
+ *
+ * The \@decoder must not be used after a successful return.
+ */
+extern pt_export void pt_pkt_free_decoder(struct pt_packet_decoder *decoder);
+
+/** Synchronize an Intel PT packet decoder.
+ *
+ * Search for the next synchronization point in forward or backward direction.
+ *
+ * If \@decoder has not been synchronized, yet, the search is started at the
+ * beginning of the trace buffer in case of forward synchronization and at the
+ * end of the trace buffer in case of backward synchronization.
+ *
+ * Returns zero or a positive value on success, a negative error code otherwise.
+ *
+ * Returns -pte_eos if no further synchronization point is found.
+ * Returns -pte_invalid if \@decoder is NULL.
+ */
+extern pt_export int pt_pkt_sync_forward(struct pt_packet_decoder *decoder);
+extern pt_export int pt_pkt_sync_backward(struct pt_packet_decoder *decoder);
+
+/** Hard set synchronization point of an Intel PT decoder.
+ *
+ * Synchronize \@decoder to \@offset within the trace buffer.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_eos if the given offset is behind the end of the trace buffer.
+ * Returns -pte_invalid if \@decoder is NULL.
+ */
+extern pt_export int pt_pkt_sync_set(struct pt_packet_decoder *decoder,
+ uint64_t offset);
+
+/** Get the current decoder position.
+ *
+ * Fills the current \@decoder position into \@offset.
+ *
+ * This is useful for reporting errors.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@decoder or \@offset is NULL.
+ * Returns -pte_nosync if \@decoder is out of sync.
+ */
+extern pt_export int pt_pkt_get_offset(const struct pt_packet_decoder *decoder,
+ uint64_t *offset);
+
+/** Get the position of the last synchronization point.
+ *
+ * Fills the last synchronization position into \@offset.
+ *
+ * This is useful when splitting a trace stream for parallel decoding.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@decoder or \@offset is NULL.
+ * Returns -pte_nosync if \@decoder is out of sync.
+ */
+extern pt_export int
+pt_pkt_get_sync_offset(const struct pt_packet_decoder *decoder,
+ uint64_t *offset);
+
+/* Return a pointer to \@decoder's configuration.
+ *
+ * Returns a non-null pointer on success, NULL if \@decoder is NULL.
+ */
+extern pt_export const struct pt_config *
+pt_pkt_get_config(const struct pt_packet_decoder *decoder);
+
+/** Decode the next packet and advance the decoder.
+ *
+ * Decodes the packet at \@decoder's current position into \@packet and
+ * adjusts the \@decoder's position by the number of bytes the packet had
+ * consumed.
+ *
+ * The \@size argument must be set to sizeof(struct pt_packet).
+ *
+ * Returns the number of bytes consumed on success, a negative error code
+ * otherwise.
+ *
+ * Returns -pte_bad_opc if the packet is unknown.
+ * Returns -pte_bad_packet if an unknown packet payload is encountered.
+ * Returns -pte_eos if \@decoder reached the end of the Intel PT buffer.
+ * Returns -pte_invalid if \@decoder or \@packet is NULL.
+ * Returns -pte_nosync if \@decoder is out of sync.
+ */
+extern pt_export int pt_pkt_next(struct pt_packet_decoder *decoder,
+ struct pt_packet *packet, size_t size);
+
+
+
+/* Event decoder. */
+
+
+
+/** Event types. */
+enum pt_event_type {
+ /* Tracing has been enabled/disabled. */
+ ptev_enabled,
+ ptev_disabled,
+
+ /* Tracing has been disabled asynchronously. */
+ ptev_async_disabled,
+
+ /* An asynchronous branch, e.g. interrupt. */
+ ptev_async_branch,
+
+ /* A synchronous paging event. */
+ ptev_paging,
+
+ /* An asynchronous paging event. */
+ ptev_async_paging,
+
+ /* Trace overflow. */
+ ptev_overflow,
+
+ /* An execution mode change. */
+ ptev_exec_mode,
+
+ /* A transactional execution state change. */
+ ptev_tsx,
+
+ /* Trace Stop. */
+ ptev_stop,
+
+ /* A synchronous vmcs event. */
+ ptev_vmcs,
+
+ /* An asynchronous vmcs event. */
+ ptev_async_vmcs,
+
+ /* Execution has stopped. */
+ ptev_exstop,
+
+ /* An MWAIT operation completed. */
+ ptev_mwait,
+
+ /* A power state was entered. */
+ ptev_pwre,
+
+ /* A power state was exited. */
+ ptev_pwrx,
+
+ /* A PTWRITE event. */
+ ptev_ptwrite,
+
+ /* A timing event. */
+ ptev_tick,
+
+ /* A core:bus ratio event. */
+ ptev_cbr,
+
+ /* A maintenance event. */
+ ptev_mnt,
+
+#if (LIBIPT_VERSION >= 0x201)
+ /* An indirect branch event. */
+ ptev_tip,
+
+ /* A conditional branch indicator event. */
+ ptev_tnt,
+
+ /* An interrupt status event. */
+ ptev_iflags,
+
+ /* An interrupt or exception event.
+ *
+ * This event extends the async_branch event generated for the
+ * control-flow change; it does not replace that event.
+ */
+ ptev_interrupt,
+
+ /* A return from interrupt event. */
+ ptev_iret,
+
+ /* A system management interrupt. */
+ ptev_smi,
+
+ /* A return from system management mode. */
+ ptev_rsm,
+
+ /* A SIPI message. */
+ ptev_sipi,
+
+ /* An INIT reset. */
+ ptev_init,
+
+ /* A Virtual Machine entry. */
+ ptev_vmentry,
+
+ /* A Virtual Machine exit. */
+ ptev_vmexit,
+
+ /* A shutdown event. */
+ ptev_shutdown,
+
+ /* A user interrupt. */
+ ptev_uintr,
+
+ /* A return from user interrupt. */
+ ptev_uiret,
+#endif
+#if (LIBIPT_VERSION >= 0x202)
+ /* A trigger event. */
+ ptev_trig,
+
+ /* A software interrupt. */
+ ptev_swintr,
+
+ /* A system call. */
+ ptev_syscall,
+#endif
+};
+
+/** An event. */
+struct pt_event {
+ /** The type of the event. */
+ enum pt_event_type type;
+
+ /** A flag indicating that the event IP has been suppressed. */
+ uint32_t ip_suppressed:1;
+
+ /** A flag indicating that the event is for status update. */
+ uint32_t status_update:1;
+
+ /** A flag indicating that the event has timing information. */
+ uint32_t has_tsc:1;
+
+ /** The time stamp count of the event.
+ *
+ * This field is only valid if \@has_tsc is set.
+ */
+ uint64_t tsc;
+
+ /** The number of lost mtc and cyc packets.
+ *
+ * This gives an idea about the quality of the \@tsc. The more packets
+ * were dropped, the less precise timing is.
+ */
+ uint32_t lost_mtc;
+ uint32_t lost_cyc;
+
+ /* Reserved space for future extensions. */
+ uint64_t reserved[2];
+
+ /** Event specific data. */
+ union {
+ /** Event: enabled. */
+ struct {
+ /** The address at which tracing resumes. */
+ uint64_t ip;
+
+ /** A flag indicating that tracing resumes from the IP
+ * at which tracing had been disabled before.
+ */
+ uint32_t resumed:1;
+ } enabled;
+
+ /** Event: disabled. */
+ struct {
+ /** The destination of the first branch inside a
+ * filtered area.
+ *
+ * This field is not valid if \@ip_suppressed is set.
+ */
+ uint64_t ip;
+
+ /* The exact source ip needs to be determined using
+ * disassembly and the filter configuration.
+ */
+ } disabled;
+
+ /** Event: async disabled. */
+ struct {
+ /** The source address of the asynchronous branch that
+ * disabled tracing.
+ */
+ uint64_t at;
+
+ /** The destination of the first branch inside a
+ * filtered area.
+ *
+ * This field is not valid if \@ip_suppressed is set.
+ */
+ uint64_t ip;
+ } async_disabled;
+
+ /** Event: async branch. */
+ struct {
+ /** The branch source address. */
+ uint64_t from;
+
+ /** The branch destination address.
+ *
+ * This field is not valid if \@ip_suppressed is set.
+ */
+ uint64_t to;
+ } async_branch;
+
+ /** Event: paging. */
+ struct {
+ /** The updated CR3 value.
+ *
+ * The lower 5 bit have been zeroed out.
+ * The upper bits have been zeroed out depending on the
+ * maximum possible address.
+ */
+ uint64_t cr3;
+
+ /** A flag indicating whether the cpu is operating in
+ * vmx non-root (guest) mode.
+ */
+ uint32_t non_root:1;
+
+ /* The address at which the event is effective is
+ * obvious from the disassembly.
+ */
+ } paging;
+
+ /** Event: async paging. */
+ struct {
+ /** The updated CR3 value.
+ *
+ * The lower 5 bit have been zeroed out.
+ * The upper bits have been zeroed out depending on the
+ * maximum possible address.
+ */
+ uint64_t cr3;
+
+ /** A flag indicating whether the cpu is operating in
+ * vmx non-root (guest) mode.
+ */
+ uint32_t non_root:1;
+
+ /** The address at which the event is effective. */
+ uint64_t ip;
+ } async_paging;
+
+ /** Event: overflow. */
+ struct {
+ /** The address at which tracing resumes after overflow.
+ *
+ * This field is not valid, if ip_suppressed is set.
+ * In this case, the overflow resolved while tracing
+ * was disabled.
+ */
+ uint64_t ip;
+ } overflow;
+
+ /** Event: exec mode. */
+ struct {
+ /** The execution mode. */
+ enum pt_exec_mode mode;
+
+ /** The address at which the event is effective. */
+ uint64_t ip;
+ } exec_mode;
+
+ /** Event: tsx. */
+ struct {
+ /** The address at which the event is effective.
+ *
+ * This field is not valid if \@ip_suppressed is set.
+ */
+ uint64_t ip;
+
+ /** A flag indicating speculative execution mode. */
+ uint32_t speculative:1;
+
+ /** A flag indicating speculative execution aborts. */
+ uint32_t aborted:1;
+ } tsx;
+
+ /** Event: vmcs. */
+ struct {
+ /** The VMCS base address.
+ *
+ * The address is zero-extended with the lower 12 bits
+ * all zero.
+ */
+ uint64_t base;
+
+ /* The new VMCS base address should be stored and
+ * applied on subsequent VM entries.
+ */
+ } vmcs;
+
+ /** Event: async vmcs. */
+ struct {
+ /** The VMCS base address.
+ *
+ * The address is zero-extended with the lower 12 bits
+ * all zero.
+ */
+ uint64_t base;
+
+ /** The address at which the event is effective. */
+ uint64_t ip;
+
+ /* An async paging event that binds to the same IP
+ * will always succeed this async vmcs event.
+ */
+ } async_vmcs;
+
+ /** Event: execution stopped. */
+ struct {
+ /** The address at which execution has stopped. This is
+ * the last instruction that did not complete.
+ *
+ * This field is not valid, if \@ip_suppressed is set.
+ */
+ uint64_t ip;
+ } exstop;
+
+ /** Event: mwait. */
+ struct {
+ /** The address of the instruction causing the mwait.
+ *
+ * This field is not valid, if \@ip_suppressed is set.
+ */
+ uint64_t ip;
+
+ /** The mwait hints (eax).
+ *
+ * Reserved bits are undefined.
+ */
+ uint32_t hints;
+
+ /** The mwait extensions (ecx).
+ *
+ * Reserved bits are undefined.
+ */
+ uint32_t ext;
+ } mwait;
+
+ /** Event: power state entry. */
+ struct {
+ /** The resolved thread C-state. */
+ uint8_t state;
+
+ /** The resolved thread sub C-state. */
+ uint8_t sub_state;
+
+ /** A flag indicating whether the C-state entry was
+ * initiated by h/w.
+ */
+ uint32_t hw:1;
+ } pwre;
+
+ /** Event: power state exit. */
+ struct {
+ /** The core C-state at the time of the wake. */
+ uint8_t last;
+
+ /** The deepest core C-state achieved during sleep. */
+ uint8_t deepest;
+
+ /** The wake reason:
+ *
+ * - due to external interrupt received.
+ */
+ uint32_t interrupt:1;
+
+ /** - due to store to monitored address. */
+ uint32_t store:1;
+
+ /** - due to h/w autonomous condition such as HDC. */
+ uint32_t autonomous:1;
+ } pwrx;
+
+ /** Event: ptwrite. */
+ struct {
+ /** The address of the ptwrite instruction.
+ *
+ * This field is not valid, if \@ip_suppressed is set.
+ *
+ * In this case, the address is obvious from the
+ * disassembly.
+ */
+ uint64_t ip;
+
+ /** The size of the below \@payload in bytes. */
+ uint8_t size;
+
+ /** The ptwrite payload. */
+ uint64_t payload;
+ } ptwrite;
+
+ /** Event: tick. */
+ struct {
+ /** The instruction address near which the tick
+ * occurred.
+ *
+ * A timestamp can sometimes be attributed directly to
+ * an instruction (e.g. to an indirect branch that
+ * receives CYC + TIP) and sometimes not (e.g. MTC).
+ *
+ * This field is not valid, if \@ip_suppressed is set.
+ */
+ uint64_t ip;
+ } tick;
+
+ /** Event: cbr. */
+ struct {
+ /** The core:bus ratio. */
+ uint16_t ratio;
+ } cbr;
+
+ /** Event: mnt. */
+ struct {
+ /** The raw payload. */
+ uint64_t payload;
+ } mnt;
+
+#if (LIBIPT_VERSION >= 0x201)
+ /** Event: tip. */
+ struct {
+ /** The target instruction address. */
+ uint64_t ip;
+ } tip;
+
+ /** Event: tnt. */
+ struct {
+ /** A sequence of conditional branch indicator bits.
+ *
+ * Indicators are ordered from oldest (bits[size-1]) to
+ * youngest (bits[0]) branch:
+ *
+ * 0...branch not taken
+ * 1...branch taken
+ */
+ uint64_t bits;
+
+ /** The number of valid bits in @bits. */
+ uint8_t size;
+ } tnt;
+
+ /** Event: iflags. */
+ struct {
+ /** The EFLAGS.IF status. */
+ uint32_t iflag:1;
+
+ /** The address of the instruction at which the new
+ * status applies.
+ *
+ * This field is not valid, if \@ip_suppressed is set.
+ */
+ uint64_t ip;
+ } iflags;
+
+ /** Event: interrupt/exception. */
+ struct {
+ /** A flag saying whether the \@cr2 field is valid. */
+ uint32_t has_cr2:1;
+
+ /** The interrupt/exception vector. */
+ uint8_t vector;
+
+ /** The page fault linear address in cr2.
+ *
+ * This field is only valid if \@has_cr2 is set.
+ */
+ uint64_t cr2;
+
+ /** The address of the instruction at which the
+ * interrupt or exception occurred.
+ *
+ * For faults, this will be the faulting instruction.
+ * For traps, this will be the next instruction.
+ *
+ * This field is not valid, if \@ip_suppressed is set.
+ */
+ uint64_t ip;
+ } interrupt;
+
+ /** Event: iret. */
+ struct {
+ /** The address of the instruction.
+ *
+ * This field is not valid, if \@ip_suppressed is set.
+ */
+ uint64_t ip;
+ } iret;
+
+ /** Event: smi. */
+ struct {
+ /** The address of the instruction at/before which the
+ * system management interrupt occurred.
+ *
+ * This field is not valid, if \@ip_suppressed is set.
+ */
+ uint64_t ip;
+ } smi;
+
+ /** Event: rsm. */
+ struct {
+ /** The address of the instruction.
+ *
+ * This field is not valid, if \@ip_suppressed is set.
+ */
+ uint64_t ip;
+ } rsm;
+
+ /** Event: sipi. */
+ struct {
+ /** The SIPI vector. */
+ uint8_t vector;
+ } sipi;
+
+ /** Event: init. */
+ struct {
+ /** The address of the instruction.
+ *
+ * This field is not valid, if \@ip_suppressed is set.
+ */
+ uint64_t ip;
+ } init;
+
+ /** Event: vmentry. */
+ struct {
+ /** The address of the instruction.
+ *
+ * This field is not valid, if \@ip_suppressed is set.
+ */
+ uint64_t ip;
+ } vmentry;
+
+ /** Event: vmexit. */
+ struct {
+ /** A flag saying whether the \@vector field is valid.
+ *
+ * When set, the vmexit occurred due to an interrupt or
+ * exception.
+ */
+ uint32_t has_vector:1;
+
+ /** A flag saying whether the \@vmxr field is valid. */
+ uint32_t has_vmxr:1;
+
+ /** A flag saying whether the \@vmxq field is valid. */
+ uint32_t has_vmxq:1;
+
+ /** The interrupt/exception vector.
+ *
+ * This field is only valid if \@has_vector is set.
+ */
+ uint8_t vector;
+
+ /** The vmexit reason.
+ *
+ * This field is only valid if \@has_vmxr is set.
+ */
+ uint64_t vmxr;
+
+ /** The vmexit qualification.
+ *
+ * This field is only valid if \@has_vmxq is set.
+ */
+ uint64_t vmxq;
+
+ /** The address of the instruction at which the
+ * interrupt or exception occurred.
+ *
+ * For faults, this will be the faulting instruction.
+ * For traps, this will be the next instruction.
+ *
+ * This field is not valid, if \@ip_suppressed is set.
+ */
+ uint64_t ip;
+ } vmexit;
+
+ /** Event: shutdown. */
+ struct {
+ /** The address of the first instruction that did not
+ * complete due to the shutdown.
+ *
+ * This field is not valid, if \@ip_suppressed is set.
+ */
+ uint64_t ip;
+ } shutdown;
+
+ /** Event: user interrupt. */
+ struct {
+ /** The user interrupt vector. */
+ uint8_t vector;
+
+ /** The address of the instruction before which the
+ * user interrupt was delivered.
+ *
+ * This field is not valid, if \@ip_suppressed is set.
+ */
+ uint64_t ip;
+ } uintr;
+
+ /** Event: uiret. */
+ struct {
+ /** The address of the instruction.
+ *
+ * This field is not valid, if \@ip_suppressed is set.
+ */
+ uint64_t ip;
+ } uiret;
+#endif /* (LIBIPT_VERSION >= 0x201) */
+
+#if (LIBIPT_VERSION >= 0x202)
+ /** Event: trigger. */
+ struct {
+ /** A bit vector of triggers represented by this event.
+ *
+ * Triggers are configured via IA32_RTIT_TRIGGERx_CFG.
+ */
+ uint8_t trbv;
+
+ /** The number of instructions after the anchor.
+ *
+ * The insn and block decoders will attempty to reduce
+ * \@icount to zero and update \@ip.
+ *
+ * This field is not valid, if \@ip_suppressed is set.
+ */
+ uint16_t icnt;
+
+ /** The address of the anchor instruction.
+ *
+ * If this field is zero, use the address of the last
+ * trig, tip, tip.pge, or async event, or the address
+ * after applying the final bit in the last tnt event.
+ *
+ * The insn and block decoders will supply a non-zero
+ * address or set \@ip_suppressed.
+ *
+ * The event is reported when reaching the instruction
+ * address before the instruction itself to correctly
+ * handle cases where the instruction faults.
+ *
+ * This field is not valid, if \@ip_suppressed is set.
+ */
+ uint64_t ip;
+
+ /** A flag saying whether there were other triggers
+ * firing that are not reported.
+ */
+ uint32_t mult:1;
+ } trig;
+
+ /** Event: software interrupt. */
+ struct {
+ /** The interrupt vector. */
+ uint8_t vector;
+
+ /** The address of the instruction that generated the
+ * software interrupt.
+ *
+ * This field is not valid, if \@ip_suppressed is set.
+ */
+ uint64_t ip;
+ } swintr;
+
+ /** Event: system call. */
+ struct {
+ /** The address of the instruction.
+ *
+ * This field is not valid, if \@ip_suppressed is set.
+ */
+ uint64_t ip;
+ } syscall;
+#endif /* (LIBIPT_VERSION >= 0x202) */
+ } variant;
+};
+
+
+#if (LIBIPT_VERSION >= 0x201)
+/** Allocate an Intel PT event decoder.
+ *
+ * The decoder will work on the buffer defined in \@config, it shall contain
+ * raw trace data and remain valid for the lifetime of the decoder.
+ *
+ * The decoder needs to be synchronized before it can be used.
+ */
+extern pt_export struct pt_event_decoder *
+pt_evt_alloc_decoder(const struct pt_config *config);
+
+/** Free an Intel PT event decoder.
+ *
+ * The \@decoder must not be used after a successful return.
+ */
+extern pt_export void pt_evt_free_decoder(struct pt_event_decoder *decoder);
+
+/** Synchronize an Intel PT event decoder.
+ *
+ * Search for the next synchronization point in forward or backward direction.
+ *
+ * If \@decoder has not been synchronized, yet, the search is started at the
+ * beginning of the trace buffer in case of forward synchronization and at the
+ * end of the trace buffer in case of backward synchronization.
+ *
+ * Returns zero or a positive value on success, a negative error code otherwise.
+ *
+ * Returns -pte_bad_opc if an unknown packet is encountered.
+ * Returns -pte_bad_packet if an unknown packet payload is encountered.
+ * Returns -pte_eos if no further synchronization point is found.
+ * Returns -pte_invalid if \@decoder is NULL.
+ */
+extern pt_export int pt_evt_sync_forward(struct pt_event_decoder *decoder);
+extern pt_export int pt_evt_sync_backward(struct pt_event_decoder *decoder);
+
+/** Manually synchronize an Intel PT event decoder.
+ *
+ * Synchronize \@decoder on the syncpoint at \@offset. There must be a PSB
+ * packet at \@offset.
+ *
+ * Returns zero or a positive value on success, a negative error code otherwise.
+ *
+ * Returns -pte_bad_opc if an unknown packet is encountered.
+ * Returns -pte_bad_packet if an unknown packet payload is encountered.
+ * Returns -pte_eos if \@offset lies outside of \@decoder's trace buffer.
+ * Returns -pte_eos if \@decoder reaches the end of its trace buffer.
+ * Returns -pte_invalid if \@decoder is NULL.
+ * Returns -pte_nosync if there is no syncpoint at \@offset.
+ */
+extern pt_export int pt_evt_sync_set(struct pt_event_decoder *decoder,
+ uint64_t offset);
+
+/** Get the current decoder position.
+ *
+ * Fills the current \@decoder position into \@offset.
+ *
+ * This is useful for reporting errors.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@decoder or \@offset is NULL.
+ * Returns -pte_nosync if \@decoder is out of sync.
+ */
+extern pt_export int pt_evt_get_offset(const struct pt_event_decoder *decoder,
+ uint64_t *offset);
+
+/** Get the position of the last synchronization point.
+ *
+ * Fills the last synchronization position into \@offset.
+ *
+ * This is useful for splitting a trace stream for parallel decoding.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@decoder or \@offset is NULL.
+ * Returns -pte_nosync if \@decoder is out of sync.
+ */
+extern pt_export int
+pt_evt_get_sync_offset(const struct pt_event_decoder *decoder,
+ uint64_t *offset);
+
+/* Return a pointer to \@decoder's configuration.
+ *
+ * Returns a non-null pointer on success, NULL if \@decoder is NULL.
+ */
+extern pt_export const struct pt_config *
+pt_evt_get_config(const struct pt_event_decoder *decoder);
+
+/** Determine the next event.
+ *
+ * On success, provides the next event in \@event.
+ *
+ * The \@size argument must be set to sizeof(struct pt_event).
+ *
+ * Returns zero or a positive value on success, a negative error code
+ * otherwise.
+ *
+ * Returns -pte_bad_opc if the packet is unknown.
+ * Returns -pte_bad_packet if an unknown packet payload is encountered.
+ * Returns -pte_eos if \@decoder reached the end of the Intel PT buffer.
+ * Returns -pte_invalid if \@decoder or \@event is NULL.
+ * Returns -pte_nosync if \@decoder is out of sync.
+ */
+extern pt_export int pt_evt_next(struct pt_event_decoder *decoder,
+ struct pt_event *event, size_t size);
+#endif /* (LIBIPT_VERSION >= 0x201) */
+
+
+
+/* Query decoder. */
+
+
+
+/** Decoder status flags. */
+enum pt_status_flag {
+ /** There is an event pending. */
+ pts_event_pending = 1 << 0,
+
+ /** The address has been suppressed. */
+ pts_ip_suppressed = 1 << 1,
+
+ /** There is no more trace data available. */
+ pts_eos = 1 << 2
+};
+
+/** Allocate an Intel PT query decoder.
+ *
+ * The decoder will work on the buffer defined in \@config, it shall contain
+ * raw trace data and remain valid for the lifetime of the decoder.
+ *
+ * The decoder needs to be synchronized before it can be used.
+ */
+extern pt_export struct pt_query_decoder *
+pt_qry_alloc_decoder(const struct pt_config *config);
+
+/** Free an Intel PT query decoder.
+ *
+ * The \@decoder must not be used after a successful return.
+ */
+extern pt_export void pt_qry_free_decoder(struct pt_query_decoder *decoder);
+
+/** Synchronize an Intel PT query decoder.
+ *
+ * Search for the next synchronization point in forward or backward direction.
+ *
+ * If \@decoder has not been synchronized, yet, the search is started at the
+ * beginning of the trace buffer in case of forward synchronization and at the
+ * end of the trace buffer in case of backward synchronization.
+ *
+ * If \@ip is not NULL, set it to last ip.
+ *
+ * Returns a non-negative pt_status_flag bit-vector on success, a negative error
+ * code otherwise.
+ *
+ * Returns -pte_bad_opc if an unknown packet is encountered.
+ * Returns -pte_bad_packet if an unknown packet payload is encountered.
+ * Returns -pte_eos if no further synchronization point is found.
+ * Returns -pte_invalid if \@decoder is NULL.
+ */
+extern pt_export int pt_qry_sync_forward(struct pt_query_decoder *decoder,
+ uint64_t *ip);
+extern pt_export int pt_qry_sync_backward(struct pt_query_decoder *decoder,
+ uint64_t *ip);
+
+/** Manually synchronize an Intel PT query decoder.
+ *
+ * Synchronize \@decoder on the syncpoint at \@offset. There must be a PSB
+ * packet at \@offset.
+ *
+ * If \@ip is not NULL, set it to last ip.
+ *
+ * Returns a non-negative pt_status_flag bit-vector on success, a negative error
+ * code otherwise.
+ *
+ * Returns -pte_bad_opc if an unknown packet is encountered.
+ * Returns -pte_bad_packet if an unknown packet payload is encountered.
+ * Returns -pte_eos if \@offset lies outside of \@decoder's trace buffer.
+ * Returns -pte_eos if \@decoder reaches the end of its trace buffer.
+ * Returns -pte_invalid if \@decoder is NULL.
+ * Returns -pte_nosync if there is no syncpoint at \@offset.
+ */
+extern pt_export int pt_qry_sync_set(struct pt_query_decoder *decoder,
+ uint64_t *ip, uint64_t offset);
+
+/** Get the current decoder position.
+ *
+ * Fills the current \@decoder position into \@offset.
+ *
+ * This is useful for reporting errors.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@decoder or \@offset is NULL.
+ * Returns -pte_nosync if \@decoder is out of sync.
+ */
+extern pt_export int pt_qry_get_offset(const struct pt_query_decoder *decoder,
+ uint64_t *offset);
+
+/** Get the position of the last synchronization point.
+ *
+ * Fills the last synchronization position into \@offset.
+ *
+ * This is useful for splitting a trace stream for parallel decoding.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@decoder or \@offset is NULL.
+ * Returns -pte_nosync if \@decoder is out of sync.
+ */
+extern pt_export int
+pt_qry_get_sync_offset(const struct pt_query_decoder *decoder,
+ uint64_t *offset);
+
+/* Return a pointer to \@decoder's configuration.
+ *
+ * Returns a non-null pointer on success, NULL if \@decoder is NULL.
+ */
+extern pt_export const struct pt_config *
+pt_qry_get_config(const struct pt_query_decoder *decoder);
+
+/** Query whether the next unconditional branch has been taken.
+ *
+ * On success, provides 1 (taken) or 0 (not taken) in \@taken for the next
+ * conditional branch and updates \@decoder.
+ *
+ * Returns a non-negative pt_status_flag bit-vector on success, a negative error
+ * code otherwise.
+ *
+ * Returns -pte_bad_opc if an unknown packet is encountered.
+ * Returns -pte_bad_packet if an unknown packet payload is encountered.
+ * Returns -pte_bad_query if no conditional branch is found.
+ * Returns -pte_eos if decoding reached the end of the Intel PT buffer.
+ * Returns -pte_invalid if \@decoder or \@taken is NULL.
+ * Returns -pte_nosync if \@decoder is out of sync.
+ */
+extern pt_export int pt_qry_cond_branch(struct pt_query_decoder *decoder,
+ int *taken);
+
+/** Get the next indirect branch destination.
+ *
+ * On success, provides the linear destination address of the next indirect
+ * branch in \@ip and updates \@decoder.
+ *
+ * Returns a non-negative pt_status_flag bit-vector on success, a negative error
+ * code otherwise.
+ *
+ * Returns -pte_bad_opc if an unknown packet is encountered.
+ * Returns -pte_bad_packet if an unknown packet payload is encountered.
+ * Returns -pte_bad_query if no indirect branch is found.
+ * Returns -pte_eos if decoding reached the end of the Intel PT buffer.
+ * Returns -pte_invalid if \@decoder or \@ip is NULL.
+ * Returns -pte_nosync if \@decoder is out of sync.
+ */
+extern pt_export int pt_qry_indirect_branch(struct pt_query_decoder *decoder,
+ uint64_t *ip);
+
+/** Query the next pending event.
+ *
+ * On success, provides the next event \@event and updates \@decoder.
+ *
+ * The \@size argument must be set to sizeof(struct pt_event).
+ *
+ * Returns a non-negative pt_status_flag bit-vector on success, a negative error
+ * code otherwise.
+ *
+ * Returns -pte_bad_opc if an unknown packet is encountered.
+ * Returns -pte_bad_packet if an unknown packet payload is encountered.
+ * Returns -pte_bad_query if no event is found.
+ * Returns -pte_eos if decoding reached the end of the Intel PT buffer.
+ * Returns -pte_invalid if \@decoder or \@event is NULL.
+ * Returns -pte_invalid if \@size is too small.
+ * Returns -pte_nosync if \@decoder is out of sync.
+ */
+extern pt_export int pt_qry_event(struct pt_query_decoder *decoder,
+ struct pt_event *event, size_t size);
+
+/** Query the current time.
+ *
+ * On success, provides the time at the last query in \@time.
+ *
+ * The time is similar to what a rdtsc instruction would return. Depending
+ * on the configuration, the time may not be fully accurate. If TSC is not
+ * enabled, the time is relative to the last synchronization and can't be used
+ * to correlate with other TSC-based time sources. In this case, -pte_no_time
+ * is returned and the relative time is provided in \@time.
+ *
+ * Some timing-related packets may need to be dropped (mostly due to missing
+ * calibration or incomplete configuration). To get an idea about the quality
+ * of the estimated time, we record the number of dropped MTC and CYC packets.
+ *
+ * If \@lost_mtc is not NULL, set it to the number of lost MTC packets.
+ * If \@lost_cyc is not NULL, set it to the number of lost CYC packets.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@decoder or \@time is NULL.
+ * Returns -pte_no_time if there has not been a TSC packet.
+ */
+extern pt_export int pt_qry_time(struct pt_query_decoder *decoder,
+ uint64_t *time, uint32_t *lost_mtc,
+ uint32_t *lost_cyc);
+
+/** Return the current core bus ratio.
+ *
+ * On success, provides the current core:bus ratio in \@cbr. The ratio is
+ * defined as core cycles per bus clock cycle.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@decoder or \@cbr is NULL.
+ * Returns -pte_no_cbr if there has not been a CBR packet.
+ */
+extern pt_export int pt_qry_core_bus_ratio(struct pt_query_decoder *decoder,
+ uint32_t *cbr);
+
+
+
+/* Traced image. */
+
+
+
+/** An Intel PT address space identifier.
+ *
+ * This identifies a particular address space when adding file sections or
+ * when reading memory.
+ */
+struct pt_asid {
+ /** The size of this object - set to sizeof(struct pt_asid). */
+ size_t size;
+
+ /** The CR3 value. */
+ uint64_t cr3;
+
+ /** The VMCS Base address. */
+ uint64_t vmcs;
+};
+
+/** An unknown CR3 value to be used for pt_asid objects. */
+static const uint64_t pt_asid_no_cr3 = 0xffffffffffffffffull;
+
+/** An unknown VMCS Base value to be used for pt_asid objects. */
+static const uint64_t pt_asid_no_vmcs = 0xffffffffffffffffull;
+
+/** Initialize an address space identifier. */
+static inline void pt_asid_init(struct pt_asid *asid)
+{
+ asid->size = sizeof(*asid);
+ asid->cr3 = pt_asid_no_cr3;
+ asid->vmcs = pt_asid_no_vmcs;
+}
+
+
+/** A cache of traced image sections. */
+struct pt_image_section_cache;
+
+/** Allocate a traced memory image section cache.
+ *
+ * An optional \@name may be given to the cache. The name string is copied.
+ *
+ * Returns a new traced memory image section cache on success, NULL otherwise.
+ */
+extern pt_export struct pt_image_section_cache *
+pt_iscache_alloc(const char *name);
+
+/** Free a traced memory image section cache.
+ *
+ * The \@iscache must have been allocated with pt_iscache_alloc().
+ * The \@iscache must not be used after a successful return.
+ */
+extern pt_export void pt_iscache_free(struct pt_image_section_cache *iscache);
+
+/** Set the image section cache limit.
+ *
+ * Set the limit for a section cache in bytes. A non-zero limit will keep the
+ * least recently used sections mapped until the limit is reached. A limit of
+ * zero disables caching.
+ *
+ * Returns zero on success, a negative pt_error_code otherwise.
+ * Returns -pte_invalid if \@iscache is NULL.
+ */
+extern pt_export int
+pt_iscache_set_limit(struct pt_image_section_cache *iscache, uint64_t limit);
+
+/** Get the image section cache name.
+ *
+ * Returns a pointer to \@iscache's name or NULL if there is no name.
+ */
+extern pt_export const char *
+pt_iscache_name(const struct pt_image_section_cache *iscache);
+
+/** Add a new file section to the traced memory image section cache.
+ *
+ * Adds a new section consisting of \@size bytes starting at \@offset in
+ * \@filename loaded at the virtual address \@vaddr if \@iscache does not
+ * already contain such a section.
+ *
+ * Returns an image section identifier (isid) uniquely identifying that section
+ * in \@iscache.
+ *
+ * The section is silently truncated to match the size of \@filename.
+ *
+ * Returns a positive isid on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@iscache or \@filename is NULL.
+ * Returns -pte_invalid if \@offset is too big.
+ */
+extern pt_export int pt_iscache_add_file(struct pt_image_section_cache *iscache,
+ const char *filename, uint64_t offset,
+ uint64_t size, uint64_t vaddr);
+
+/** Read memory from a cached file section
+ *
+ * Reads \@size bytes of memory starting at virtual address \@vaddr in the
+ * section identified by \@isid in \@iscache into \@buffer.
+ *
+ * The caller is responsible for allocating a \@buffer of at least \@size bytes.
+ *
+ * The read request may be truncated if it crosses section boundaries or if
+ * \@size is getting too big. We support reading at least 4Kbyte in one chunk
+ * unless the read would cross a section boundary.
+ *
+ * Returns the number of bytes read on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@iscache or \@buffer is NULL.
+ * Returns -pte_invalid if \@size is zero.
+ * Returns -pte_nomap if \@vaddr is not contained in section \@isid.
+ * Returns -pte_bad_image if \@iscache does not contain \@isid.
+ */
+extern pt_export int pt_iscache_read(struct pt_image_section_cache *iscache,
+ uint8_t *buffer, uint64_t size, int isid,
+ uint64_t vaddr);
+
+/** The traced memory image. */
+struct pt_image;
+
+
+/** Allocate a traced memory image.
+ *
+ * An optional \@name may be given to the image. The name string is copied.
+ *
+ * Returns a new traced memory image on success, NULL otherwise.
+ */
+extern pt_export struct pt_image *pt_image_alloc(const char *name);
+
+/** Free a traced memory image.
+ *
+ * The \@image must have been allocated with pt_image_alloc().
+ * The \@image must not be used after a successful return.
+ */
+extern pt_export void pt_image_free(struct pt_image *image);
+
+/** Get the image name.
+ *
+ * Returns a pointer to \@image's name or NULL if there is no name.
+ */
+extern pt_export const char *pt_image_name(const struct pt_image *image);
+
+/** Add a new file section to the traced memory image.
+ *
+ * Adds \@size bytes starting at \@offset in \@filename. The section is
+ * loaded at the virtual address \@vaddr in the address space \@asid.
+ *
+ * The \@asid may be NULL or (partially) invalid. In that case only the valid
+ * fields are considered when comparing with other address-spaces. Use this
+ * when tracing a single process or when adding sections to all processes.
+ *
+ * The section is silently truncated to match the size of \@filename.
+ *
+ * Existing sections that would overlap with the new section will be shrunk
+ * or split.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@image or \@filename is NULL.
+ * Returns -pte_invalid if \@offset is too big.
+ */
+extern pt_export int pt_image_add_file(struct pt_image *image,
+ const char *filename, uint64_t offset,
+ uint64_t size,
+ const struct pt_asid *asid,
+ uint64_t vaddr);
+
+/** Add a section from an image section cache.
+ *
+ * Add the section from \@iscache identified by \@isid in address space \@asid.
+ *
+ * Existing sections that would overlap with the new section will be shrunk
+ * or split.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ * Returns -pte_invalid if \@image or \@iscache is NULL.
+ * Returns -pte_bad_image if \@iscache does not contain \@isid.
+ */
+extern pt_export int pt_image_add_cached(struct pt_image *image,
+ struct pt_image_section_cache *iscache,
+ int isid, const struct pt_asid *asid);
+
+/** Copy an image.
+ *
+ * Adds all sections from \@src to \@image. Sections that could not be added
+ * will be ignored.
+ *
+ * Returns the number of ignored sections on success, a negative error code
+ * otherwise.
+ *
+ * Returns -pte_invalid if \@image or \@src is NULL.
+ */
+extern pt_export int pt_image_copy(struct pt_image *image,
+ const struct pt_image *src);
+
+/** Remove all sections loaded from a file.
+ *
+ * Removes all sections loaded from \@filename from the address space \@asid.
+ * Specify the same \@asid that was used for adding sections from \@filename.
+ *
+ * Returns the number of removed sections on success, a negative error code
+ * otherwise.
+ *
+ * Returns -pte_invalid if \@image or \@filename is NULL.
+ */
+extern pt_export int pt_image_remove_by_filename(struct pt_image *image,
+ const char *filename,
+ const struct pt_asid *asid);
+
+/** Remove all sections loaded into an address space.
+ *
+ * Removes all sections loaded into \@asid. Specify the same \@asid that was
+ * used for adding sections.
+ *
+ * Returns the number of removed sections on success, a negative error code
+ * otherwise.
+ *
+ * Returns -pte_invalid if \@image is NULL.
+ */
+extern pt_export int pt_image_remove_by_asid(struct pt_image *image,
+ const struct pt_asid *asid);
+
+/** A read memory callback function.
+ *
+ * It shall read \@size bytes of memory from address space \@asid starting
+ * at \@ip into \@buffer.
+ *
+ * It shall return the number of bytes read on success.
+ * It shall return a negative pt_error_code otherwise.
+ */
+typedef int (read_memory_callback_t)(uint8_t *buffer, size_t size,
+ const struct pt_asid *asid,
+ uint64_t ip, void *context);
+
+/** Set the memory callback for the traced memory image.
+ *
+ * Sets \@callback for reading memory. The callback is used for addresses
+ * that are not found in file sections. The \@context argument is passed
+ * to \@callback on each use.
+ *
+ * There can only be one callback at any time. A subsequent call will replace
+ * the previous callback. If \@callback is NULL, the callback is removed.
+ *
+ * Returns -pte_invalid if \@image is NULL.
+ */
+extern pt_export int pt_image_set_callback(struct pt_image *image,
+ read_memory_callback_t *callback,
+ void *context);
+
+
+
+/* Instruction flow decoder. */
+
+
+
+/** The instruction class.
+ *
+ * We provide only a very coarse classification suitable for reconstructing
+ * the execution flow.
+ */
+enum pt_insn_class {
+#if (LIBIPT_VERSION >= 0x201)
+ /* The instruction has not been classified. */
+ ptic_unknown,
+
+ /* For backwards compatibility. */
+ ptic_error = ptic_unknown,
+#else
+ /* The instruction has not been classified. */
+ ptic_error,
+#endif
+
+ /* The instruction is something not listed below. */
+ ptic_other,
+
+ /* The instruction is a near (function) call. */
+ ptic_call,
+
+ /* The instruction is a near (function) return. */
+ ptic_return,
+
+ /* The instruction is a near unconditional jump. */
+ ptic_jump,
+
+ /* The instruction is a near conditional jump. */
+ ptic_cond_jump,
+
+ /* The instruction is a call-like far transfer.
+ * E.g. SYSCALL, SYSENTER, or FAR CALL.
+ */
+ ptic_far_call,
+
+ /* The instruction is a return-like far transfer.
+ * E.g. SYSRET, SYSEXIT, IRET, or FAR RET.
+ */
+ ptic_far_return,
+
+ /* The instruction is a jump-like far transfer.
+ * E.g. FAR JMP.
+ */
+ ptic_far_jump,
+
+ /* The instruction is a PTWRITE. */
+ ptic_ptwrite,
+
+#if (LIBIPT_VERSION >= 0x201)
+ /* The instruction is an indirect jump or a far transfer. */
+ ptic_indirect,
+#endif
+};
+
+/** The maximal size of an instruction. */
+enum {
+ pt_max_insn_size = 15
+};
+
+/** A single traced instruction. */
+struct pt_insn {
+ /** The virtual address in its process. */
+ uint64_t ip;
+
+ /** The image section identifier for the section containing this
+ * instruction.
+ *
+ * A value of zero means that the section did not have an identifier.
+ * The section was not added via an image section cache or the memory
+ * was read via the read memory callback.
+ */
+ int isid;
+
+ /** The execution mode. */
+ enum pt_exec_mode mode;
+
+ /** A coarse classification. */
+ enum pt_insn_class iclass;
+
+ /** The raw bytes. */
+ uint8_t raw[pt_max_insn_size];
+
+ /** The size in bytes. */
+ uint8_t size;
+
+ /** A collection of flags giving additional information:
+ *
+ * - the instruction was executed speculatively.
+ */
+ uint32_t speculative:1;
+
+ /** - this instruction is truncated in its image section.
+ *
+ * It starts in the image section identified by \@isid and continues
+ * in one or more other sections.
+ */
+ uint32_t truncated:1;
+};
+
+
+/** Allocate an Intel PT instruction flow decoder.
+ *
+ * The decoder will work on the buffer defined in \@config, it shall contain
+ * raw trace data and remain valid for the lifetime of the decoder.
+ *
+ * The decoder needs to be synchronized before it can be used.
+ */
+extern pt_export struct pt_insn_decoder *
+pt_insn_alloc_decoder(const struct pt_config *config);
+
+/** Free an Intel PT instruction flow decoder.
+ *
+ * This will destroy the decoder's default image.
+ *
+ * The \@decoder must not be used after a successful return.
+ */
+extern pt_export void pt_insn_free_decoder(struct pt_insn_decoder *decoder);
+
+/** Synchronize an Intel PT instruction flow decoder.
+ *
+ * Search for the next synchronization point in forward or backward direction.
+ *
+ * If \@decoder has not been synchronized, yet, the search is started at the
+ * beginning of the trace buffer in case of forward synchronization and at the
+ * end of the trace buffer in case of backward synchronization.
+ *
+ * Returns zero or a positive value on success, a negative error code otherwise.
+ *
+ * Returns -pte_bad_opc if an unknown packet is encountered.
+ * Returns -pte_bad_packet if an unknown packet payload is encountered.
+ * Returns -pte_eos if no further synchronization point is found.
+ * Returns -pte_invalid if \@decoder is NULL.
+ */
+extern pt_export int pt_insn_sync_forward(struct pt_insn_decoder *decoder);
+extern pt_export int pt_insn_sync_backward(struct pt_insn_decoder *decoder);
+
+/** Manually synchronize an Intel PT instruction flow decoder.
+ *
+ * Synchronize \@decoder on the syncpoint at \@offset. There must be a PSB
+ * packet at \@offset.
+ *
+ * Returns zero or a positive value on success, a negative error code otherwise.
+ *
+ * Returns -pte_bad_opc if an unknown packet is encountered.
+ * Returns -pte_bad_packet if an unknown packet payload is encountered.
+ * Returns -pte_eos if \@offset lies outside of \@decoder's trace buffer.
+ * Returns -pte_eos if \@decoder reaches the end of its trace buffer.
+ * Returns -pte_invalid if \@decoder is NULL.
+ * Returns -pte_nosync if there is no syncpoint at \@offset.
+ */
+extern pt_export int pt_insn_sync_set(struct pt_insn_decoder *decoder,
+ uint64_t offset);
+
+#if (LIBIPT_VERSION >= 0x202)
+/** Re-synchronize an Intel PT instruction flow decoder.
+ *
+ * Scan ahead for the next IP providing packet. Apply state changing packets
+ * along the way, including timing packets, but ignore everything else.
+ *
+ * Returns a non-negative pt_status_flag bit-vector on success, a negative
+ * error code otherwise.
+ *
+ * Returns pts_ip_suppressed if re-synchronization succeeded with tracing
+ * disabled.
+ *
+ * Returns -pte_event_ignored if an event cannot safely be skipped
+ * (e.g. ptwrite). Use pt_insn_event() to read the event, then continue with
+ * pt_insn_resync() until re-synchronization completes or fails with an error.
+ *
+ * Returns -pte_bad_opc if an unknown packet is encountered.
+ * Returns -pte_bad_packet if an unknown packet payload is encountered.
+ * Returns -pte_eos if no further synchronization point is found.
+ * Returns -pte_invalid if \@decoder is NULL.
+ */
+extern pt_export int pt_insn_resync(struct pt_insn_decoder *decoder);
+#endif
+
+/** Get the current decoder position.
+ *
+ * Fills the current \@decoder position into \@offset.
+ *
+ * This is useful for reporting errors.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@decoder or \@offset is NULL.
+ * Returns -pte_nosync if \@decoder is out of sync.
+ */
+extern pt_export int pt_insn_get_offset(const struct pt_insn_decoder *decoder,
+ uint64_t *offset);
+
+/** Get the position of the last synchronization point.
+ *
+ * Fills the last synchronization position into \@offset.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@decoder or \@offset is NULL.
+ * Returns -pte_nosync if \@decoder is out of sync.
+ */
+extern pt_export int
+pt_insn_get_sync_offset(const struct pt_insn_decoder *decoder,
+ uint64_t *offset);
+
+/** Get the traced image.
+ *
+ * The returned image may be modified as long as no decoder that uses this
+ * image is running.
+ *
+ * Returns a pointer to the traced image the decoder uses for reading memory.
+ * Returns NULL if \@decoder is NULL.
+ */
+extern pt_export struct pt_image *
+pt_insn_get_image(struct pt_insn_decoder *decoder);
+
+/** Set the traced image.
+ *
+ * Sets the image that \@decoder uses for reading memory to \@image. If \@image
+ * is NULL, sets the image to \@decoder's default image.
+ *
+ * Only one image can be active at any time.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ * Return -pte_invalid if \@decoder is NULL.
+ */
+extern pt_export int pt_insn_set_image(struct pt_insn_decoder *decoder,
+ struct pt_image *image);
+
+/* Return a pointer to \@decoder's configuration.
+ *
+ * Returns a non-null pointer on success, NULL if \@decoder is NULL.
+ */
+extern pt_export const struct pt_config *
+pt_insn_get_config(const struct pt_insn_decoder *decoder);
+
+/** Return the current time.
+ *
+ * On success, provides the time at the last preceding timing packet in \@time.
+ *
+ * The time is similar to what a rdtsc instruction would return. Depending
+ * on the configuration, the time may not be fully accurate. If TSC is not
+ * enabled, the time is relative to the last synchronization and can't be used
+ * to correlate with other TSC-based time sources. In this case, -pte_no_time
+ * is returned and the relative time is provided in \@time.
+ *
+ * Some timing-related packets may need to be dropped (mostly due to missing
+ * calibration or incomplete configuration). To get an idea about the quality
+ * of the estimated time, we record the number of dropped MTC and CYC packets.
+ *
+ * If \@lost_mtc is not NULL, set it to the number of lost MTC packets.
+ * If \@lost_cyc is not NULL, set it to the number of lost CYC packets.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@decoder or \@time is NULL.
+ * Returns -pte_no_time if there has not been a TSC packet.
+ */
+extern pt_export int pt_insn_time(struct pt_insn_decoder *decoder,
+ uint64_t *time, uint32_t *lost_mtc,
+ uint32_t *lost_cyc);
+
+/** Return the current core bus ratio.
+ *
+ * On success, provides the current core:bus ratio in \@cbr. The ratio is
+ * defined as core cycles per bus clock cycle.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@decoder or \@cbr is NULL.
+ * Returns -pte_no_cbr if there has not been a CBR packet.
+ */
+extern pt_export int pt_insn_core_bus_ratio(struct pt_insn_decoder *decoder,
+ uint32_t *cbr);
+
+/** Return the current address space identifier.
+ *
+ * On success, provides the current address space identifier in \@asid.
+ *
+ * The \@size argument must be set to sizeof(struct pt_asid). At most \@size
+ * bytes will be copied and \@asid->size will be set to the actual size of the
+ * provided address space identifier.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@decoder or \@asid is NULL.
+ */
+extern pt_export int pt_insn_asid(const struct pt_insn_decoder *decoder,
+ struct pt_asid *asid, size_t size);
+
+/** Determine the next instruction.
+ *
+ * On success, provides the next instruction in execution order in \@insn.
+ *
+ * The \@size argument must be set to sizeof(struct pt_insn).
+ *
+ * Returns a non-negative pt_status_flag bit-vector on success, a negative error
+ * code otherwise.
+ *
+ * Returns pts_eos to indicate the end of the trace stream. Subsequent calls
+ * to pt_insn_next() will continue to return pts_eos until trace is required
+ * to determine the next instruction.
+ *
+ * Returns -pte_event_ignored to indicate that the user needs to drain events
+ * using pt_insn_event() before continuing.
+ *
+ * Returns -pte_bad_context if the decoder encountered an unexpected packet.
+ * Returns -pte_bad_opc if the decoder encountered unknown packets.
+ * Returns -pte_bad_packet if the decoder encountered unknown packet payloads.
+ * Returns -pte_bad_query if the decoder got out of sync.
+ * Returns -pte_eos if decoding reached the end of the Intel PT buffer.
+ * Returns -pte_invalid if \@decoder or \@insn is NULL.
+ * Returns -pte_nomap if the memory at the instruction address can't be read.
+ * Returns -pte_nosync if \@decoder is out of sync.
+ */
+extern pt_export int pt_insn_next(struct pt_insn_decoder *decoder,
+ struct pt_insn *insn, size_t size);
+
+/** Get the next pending event.
+ *
+ * On success, provides the next event in \@event and updates \@decoder.
+ *
+ * The \@size argument must be set to sizeof(struct pt_event).
+ *
+ * Returns a non-negative pt_status_flag bit-vector on success, a negative error
+ * code otherwise.
+ *
+ * Returns -pte_bad_query if there is no event.
+ * Returns -pte_invalid if \@decoder or \@event is NULL.
+ * Returns -pte_invalid if \@size is too small.
+ */
+extern pt_export int pt_insn_event(struct pt_insn_decoder *decoder,
+ struct pt_event *event, size_t size);
+
+
+
+/* Block decoder. */
+
+
+
+/** A block of instructions.
+ *
+ * Instructions in this block are executed sequentially but are not necessarily
+ * contiguous in memory. Users are expected to follow direct branches.
+ */
+struct pt_block {
+ /** The IP of the first instruction in this block. */
+ uint64_t ip;
+
+ /** The IP of the last instruction in this block.
+ *
+ * This can be used for error-detection.
+ */
+ uint64_t end_ip;
+
+ /** The image section that contains the instructions in this block.
+ *
+ * A value of zero means that the section did not have an identifier.
+ * The section was not added via an image section cache or the memory
+ * was read via the read memory callback.
+ */
+ int isid;
+
+ /** The execution mode for all instructions in this block. */
+ enum pt_exec_mode mode;
+
+ /** The instruction class for the last instruction in this block.
+ *
+ * This field may be set to ptic_unknown (ptic_error prior to v2.1) to
+ * indicate that the instruction class is not available. The block
+ * decoder may choose to not provide the instruction class in some
+ * cases for performance reasons.
+ */
+ enum pt_insn_class iclass;
+
+ /** The number of instructions in this block. */
+ uint16_t ninsn;
+
+ /** The raw bytes of the last instruction in this block in case the
+ * instruction does not fit entirely into this block's section.
+ *
+ * This field is only valid if \@truncated is set.
+ */
+ uint8_t raw[pt_max_insn_size];
+
+ /** The size of the last instruction in this block in bytes.
+ *
+ * This field is only valid if \@truncated is set.
+ */
+ uint8_t size;
+
+ /** A collection of flags giving additional information about the
+ * instructions in this block.
+ *
+ * - all instructions in this block were executed speculatively.
+ */
+ uint32_t speculative:1;
+
+ /** - the last instruction in this block is truncated.
+ *
+ * It starts in this block's section but continues in one or more
+ * other sections depending on how fragmented the memory image is.
+ *
+ * The raw bytes for the last instruction are provided in \@raw and
+ * its size in \@size in this case.
+ */
+ uint32_t truncated:1;
+};
+
+/** Allocate an Intel PT block decoder.
+ *
+ * The decoder will work on the buffer defined in \@config, it shall contain
+ * raw trace data and remain valid for the lifetime of the decoder.
+ *
+ * The decoder needs to be synchronized before it can be used.
+ */
+extern pt_export struct pt_block_decoder *
+pt_blk_alloc_decoder(const struct pt_config *config);
+
+/** Free an Intel PT block decoder.
+ *
+ * This will destroy the decoder's default image.
+ *
+ * The \@decoder must not be used after a successful return.
+ */
+extern pt_export void pt_blk_free_decoder(struct pt_block_decoder *decoder);
+
+/** Synchronize an Intel PT block decoder.
+ *
+ * Search for the next synchronization point in forward or backward direction.
+ *
+ * If \@decoder has not been synchronized, yet, the search is started at the
+ * beginning of the trace buffer in case of forward synchronization and at the
+ * end of the trace buffer in case of backward synchronization.
+ *
+ * Returns zero or a positive value on success, a negative error code otherwise.
+ *
+ * Returns -pte_bad_opc if an unknown packet is encountered.
+ * Returns -pte_bad_packet if an unknown packet payload is encountered.
+ * Returns -pte_eos if no further synchronization point is found.
+ * Returns -pte_invalid if \@decoder is NULL.
+ */
+extern pt_export int pt_blk_sync_forward(struct pt_block_decoder *decoder);
+extern pt_export int pt_blk_sync_backward(struct pt_block_decoder *decoder);
+
+/** Manually synchronize an Intel PT block decoder.
+ *
+ * Synchronize \@decoder on the syncpoint at \@offset. There must be a PSB
+ * packet at \@offset.
+ *
+ * Returns zero or a positive value on success, a negative error code otherwise.
+ *
+ * Returns -pte_bad_opc if an unknown packet is encountered.
+ * Returns -pte_bad_packet if an unknown packet payload is encountered.
+ * Returns -pte_eos if \@offset lies outside of \@decoder's trace buffer.
+ * Returns -pte_eos if \@decoder reaches the end of its trace buffer.
+ * Returns -pte_invalid if \@decoder is NULL.
+ * Returns -pte_nosync if there is no syncpoint at \@offset.
+ */
+extern pt_export int pt_blk_sync_set(struct pt_block_decoder *decoder,
+ uint64_t offset);
+
+#if (LIBIPT_VERSION >= 0x202)
+/** Re-synchronize an Intel PT block decoder.
+ *
+ * Scan ahead for the next IP providing packet. Apply state changing packets
+ * along the way, including timing packets, but ignore everything else.
+ *
+ * Returns a non-negative pt_status_flag bit-vector on success, a negative
+ * error code otherwise.
+ *
+ * Returns pts_ip_suppressed if re-synchronization succeeded with tracing
+ * disabled.
+ *
+ * Returns -pte_event_ignored if an event cannot safely be skipped
+ * (e.g. ptwrite). Use pt_blk_event() to read the event, then continue with
+ * pt_blk_resync() until re-synchronization completes or fails with an error.
+ *
+ * Returns -pte_bad_opc if an unknown packet is encountered.
+ * Returns -pte_bad_packet if an unknown packet payload is encountered.
+ * Returns -pte_eos if no further synchronization point is found.
+ * Returns -pte_invalid if \@decoder is NULL.
+ */
+extern pt_export int pt_blk_resync(struct pt_block_decoder *decoder);
+#endif
+
+/** Get the current decoder position.
+ *
+ * Fills the current \@decoder position into \@offset.
+ *
+ * This is useful for reporting errors.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@decoder or \@offset is NULL.
+ * Returns -pte_nosync if \@decoder is out of sync.
+ */
+extern pt_export int pt_blk_get_offset(const struct pt_block_decoder *decoder,
+ uint64_t *offset);
+
+/** Get the position of the last synchronization point.
+ *
+ * Fills the last synchronization position into \@offset.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@decoder or \@offset is NULL.
+ * Returns -pte_nosync if \@decoder is out of sync.
+ */
+extern pt_export int
+pt_blk_get_sync_offset(const struct pt_block_decoder *decoder,
+ uint64_t *offset);
+
+/** Get the traced image.
+ *
+ * The returned image may be modified as long as \@decoder is not running.
+ *
+ * Returns a pointer to the traced image \@decoder uses for reading memory.
+ * Returns NULL if \@decoder is NULL.
+ */
+extern pt_export struct pt_image *
+pt_blk_get_image(struct pt_block_decoder *decoder);
+
+/** Set the traced image.
+ *
+ * Sets the image that \@decoder uses for reading memory to \@image. If \@image
+ * is NULL, sets the image to \@decoder's default image.
+ *
+ * Only one image can be active at any time.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ * Return -pte_invalid if \@decoder is NULL.
+ */
+extern pt_export int pt_blk_set_image(struct pt_block_decoder *decoder,
+ struct pt_image *image);
+
+/* Return a pointer to \@decoder's configuration.
+ *
+ * Returns a non-null pointer on success, NULL if \@decoder is NULL.
+ */
+extern pt_export const struct pt_config *
+pt_blk_get_config(const struct pt_block_decoder *decoder);
+
+/** Return the current time.
+ *
+ * On success, provides the time at the last preceding timing packet in \@time.
+ *
+ * The time is similar to what a rdtsc instruction would return. Depending
+ * on the configuration, the time may not be fully accurate. If TSC is not
+ * enabled, the time is relative to the last synchronization and can't be used
+ * to correlate with other TSC-based time sources. In this case, -pte_no_time
+ * is returned and the relative time is provided in \@time.
+ *
+ * Some timing-related packets may need to be dropped (mostly due to missing
+ * calibration or incomplete configuration). To get an idea about the quality
+ * of the estimated time, we record the number of dropped MTC and CYC packets.
+ *
+ * If \@lost_mtc is not NULL, set it to the number of lost MTC packets.
+ * If \@lost_cyc is not NULL, set it to the number of lost CYC packets.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@decoder or \@time is NULL.
+ * Returns -pte_no_time if there has not been a TSC packet.
+ */
+extern pt_export int pt_blk_time(struct pt_block_decoder *decoder,
+ uint64_t *time, uint32_t *lost_mtc,
+ uint32_t *lost_cyc);
+
+/** Return the current core bus ratio.
+ *
+ * On success, provides the current core:bus ratio in \@cbr. The ratio is
+ * defined as core cycles per bus clock cycle.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@decoder or \@cbr is NULL.
+ * Returns -pte_no_cbr if there has not been a CBR packet.
+ */
+extern pt_export int pt_blk_core_bus_ratio(struct pt_block_decoder *decoder,
+ uint32_t *cbr);
+
+/** Return the current address space identifier.
+ *
+ * On success, provides the current address space identifier in \@asid.
+ *
+ * The \@size argument must be set to sizeof(struct pt_asid). At most \@size
+ * bytes will be copied and \@asid->size will be set to the actual size of the
+ * provided address space identifier.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ *
+ * Returns -pte_invalid if \@decoder or \@asid is NULL.
+ */
+extern pt_export int pt_blk_asid(const struct pt_block_decoder *decoder,
+ struct pt_asid *asid, size_t size);
+
+/** Determine the next block of instructions.
+ *
+ * On success, provides the next block of instructions in execution order in
+ * \@block.
+ *
+ * The \@size argument must be set to sizeof(struct pt_block).
+ *
+ * Returns a non-negative pt_status_flag bit-vector on success, a negative error
+ * code otherwise.
+ *
+ * Returns pts_eos to indicate the end of the trace stream. Subsequent calls
+ * to pt_block_next() will continue to return pts_eos until trace is required
+ * to determine the next instruction.
+ *
+ * Returns -pte_bad_context if the decoder encountered an unexpected packet.
+ * Returns -pte_bad_opc if the decoder encountered unknown packets.
+ * Returns -pte_bad_packet if the decoder encountered unknown packet payloads.
+ * Returns -pte_bad_query if the decoder got out of sync.
+ * Returns -pte_eos if decoding reached the end of the Intel PT buffer.
+ * Returns -pte_invalid if \@decoder or \@block is NULL.
+ * Returns -pte_nomap if the memory at the instruction address can't be read.
+ * Returns -pte_nosync if \@decoder is out of sync.
+ */
+extern pt_export int pt_blk_next(struct pt_block_decoder *decoder,
+ struct pt_block *block, size_t size);
+
+/** Get the next pending event.
+ *
+ * On success, provides the next event in \@event and updates \@decoder.
+ *
+ * The \@size argument must be set to sizeof(struct pt_event).
+ *
+ * Returns a non-negative pt_status_flag bit-vector on success, a negative error
+ * code otherwise.
+ *
+ * Returns -pte_bad_query if there is no event.
+ * Returns -pte_invalid if \@decoder or \@event is NULL.
+ * Returns -pte_invalid if \@size is too small.
+ */
+extern pt_export int pt_blk_event(struct pt_block_decoder *decoder,
+ struct pt_event *event, size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* INTEL_PT_H */
diff --git a/hyperdbg/dependencies/pdbex b/hyperdbg/dependencies/pdbex
index 42a9fbb8..0e114472 160000
--- a/hyperdbg/dependencies/pdbex
+++ b/hyperdbg/dependencies/pdbex
@@ -1 +1 @@
-Subproject commit 42a9fbb821c7d140c5e00da60f5a5887c2fd8444
+Subproject commit 0e1144729a5b2d737cce11d1c0e083033630fff8
diff --git a/hyperdbg/dependencies/zydis b/hyperdbg/dependencies/zydis
index d45e7416..e910df2f 160000
--- a/hyperdbg/dependencies/zydis
+++ b/hyperdbg/dependencies/zydis
@@ -1 +1 @@
-Subproject commit d45e7416b2123706c3695fa802e6b29543f1a549
+Subproject commit e910df2fa54273b1a489b39771d331036e8de2db
diff --git a/hyperdbg/hyperdbg-cli/CMakeLists.txt b/hyperdbg/hyperdbg-cli/CMakeLists.txt
index b7293ad3..8eb54082 100644
--- a/hyperdbg/hyperdbg-cli/CMakeLists.txt
+++ b/hyperdbg/hyperdbg-cli/CMakeLists.txt
@@ -1,7 +1,7 @@
# Code generated by Visual Studio kit, DO NOT EDIT.
set(SourceFiles
"hyperdbg-cli.cpp"
- "../include/platform/user/header/Environment.h"
+ "../include/platform/general/header/Environment.h"
)
include_directories(
"../include"
diff --git a/hyperdbg/hyperdbg-cli/hyperdbg-cli.cpp b/hyperdbg/hyperdbg-cli/hyperdbg-cli.cpp
index 926608ce..38086308 100644
--- a/hyperdbg/hyperdbg-cli/hyperdbg-cli.cpp
+++ b/hyperdbg/hyperdbg-cli/hyperdbg-cli.cpp
@@ -1,7 +1,7 @@
/**
* @file hyperdbg-cli.cpp
* @author Sina Karvandi (sina@hyperdbg.org)
- * @brief Main HyperDbg Cli source coede
+ * @brief Main HyperDbg Cli source code
* @details
* @version 0.1
* @date 2020-04-11
@@ -10,16 +10,15 @@
*
*/
-//
-// Environment headers
-//
-#include "platform/user/header/Environment.h"
+#ifdef _WIN32
+# include
+# include
+#endif
-#include
#include
-#include
#include
#include
+#include
#include "SDK/HyperDbgSdk.h"
#include "SDK/imports/user/HyperDbgLibImports.h"
@@ -29,9 +28,9 @@ using namespace std;
/**
* @brief CLI main function
*
- * @param argc
- * @param argv
- * @return int
+ * @param argc the number of arguments
+ * @param argv the arguments
+ * @return int zero on success, 1 on failure
*/
int
main(int argc, char * argv[])
@@ -43,12 +42,19 @@ main(int argc, char * argv[])
//
// Set console output code page to UTF-8
//
+#ifdef _WIN32
SetConsoleOutputCP(CP_UTF8);
+#endif
printf("HyperDbg Debugger [version: %s, build: %s]\n", CompleteVersion, BuildVersion);
printf("Please visit https://docs.hyperdbg.org for more information...\n");
printf("HyperDbg is released under the GNU Public License v3 (GPLv3).\n\n");
+#if BETA_VERSION == 1
+ printf("Notice: This is a beta release and may contain bugs or stability issues. ");
+ printf("If you encounter any problems, please report them and consider using the previous stable release.\n\n");
+#endif
+
if (argc != 1)
{
//
@@ -79,7 +85,7 @@ main(int argc, char * argv[])
//
reset = TRUE;
- GetMultiLinecCommand:
+ GetMultiLineCommand:
string temp_command = "";
@@ -120,7 +126,7 @@ main(int argc, char * argv[])
//
// Get next command
//
- goto GetMultiLinecCommand;
+ goto GetMultiLineCommand;
}
else
{
diff --git a/hyperdbg/hyperdbg-cli/hyperdbg-cli.vcxproj b/hyperdbg/hyperdbg-cli/hyperdbg-cli.vcxproj
index 66c49f57..5b16f0d4 100644
--- a/hyperdbg/hyperdbg-cli/hyperdbg-cli.vcxproj
+++ b/hyperdbg/hyperdbg-cli/hyperdbg-cli.vcxproj
@@ -22,14 +22,14 @@
Applicationtrue
- v143
+ v145UnicodefalseApplicationfalse
- v143
+ v145trueUnicodefalse
@@ -82,15 +82,21 @@
if exist "$(OutDir)SDK\" rd /q /s "$(OutDir)SDK\"
xcopy /E /I /Y "$(SolutionDir)include\SDK" "$(OutDir)SDK"
-xcopy /E /I /Y "$(SolutionDir)..\examples" "$(OutDir)SDK\Examples"
-mkdir "$(OutDir)SDK\Libraries"
-copy "$(OutDir)pdbex.lib" "$(OutDir)SDK\Libraries\pdbex.lib"
-copy "$(OutDir)kdserial.lib" "$(OutDir)SDK\Libraries\kdserial.lib"
-copy "$(OutDir)libhyperdbg.dll" "$(OutDir)SDK\Libraries\libhyperdbg.dll"
-copy "$(OutDir)script-engine.dll" "$(OutDir)SDK\Libraries\script-engine.dll"
-copy "$(OutDir)symbol-parser.dll" "$(OutDir)SDK\Libraries\symbol-parser.dll"
-copy "$(OutDir)hyperlog.dll" "$(OutDir)SDK\Libraries\hyperlog.dll"
-copy "$(OutDir)hyperhv.dll" "$(OutDir)SDK\Libraries\hyperhv.dll"
+xcopy /E /I /Y "$(SolutionDir)..\examples" "$(OutDir)SDK\examples"
+mkdir "$(OutDir)SDK\libraries"
+mkdir "$(OutDir)SDK\libraries\kernel"
+mkdir "$(OutDir)SDK\libraries\user"
+copy "$(OutDir)pdbex.dll" "$(OutDir)SDK\libraries\user\pdbex.dll"
+copy "$(OutDir)libipt.dll" "$(OutDir)SDK\libraries\user\libipt.dll"
+copy "$(OutDir)script-engine.dll" "$(OutDir)SDK\libraries\user\script-engine.dll"
+copy "$(OutDir)symbol-parser.dll" "$(OutDir)SDK\libraries\user\symbol-parser.dll"
+copy "$(OutDir)libhyperdbg.dll" "$(OutDir)SDK\libraries\user\libhyperdbg.dll"
+copy "$(OutDir)hyperlog.dll" "$(OutDir)SDK\libraries\kernel\hyperlog.dll"
+copy "$(OutDir)hyperhv.dll" "$(OutDir)SDK\libraries\kernel\hyperhv.dll"
+copy "$(OutDir)hypertrace.dll" "$(OutDir)SDK\libraries\kernel\hyperevade.dll"
+copy "$(OutDir)hypertrace.dll" "$(OutDir)SDK\libraries\kernel\hypertrace.dll"
+copy "$(OutDir)hyperperf.dll" "$(OutDir)SDK\libraries\kernel\hyperperf.dll"
+copy "$(OutDir)kdserial.dll" "$(OutDir)SDK\libraries\kernel\kdserial.dll"
if exist "$(OutDir)constants\" rd /q /s "$(OutDir)constants\"
mkdir "$(OutDir)constants"
copy "$(SolutionDir)miscellaneous\constants\pciid\pci.ids" "$(OutDir)constants\pci.ids"
@@ -110,7 +116,7 @@ copy "$(SolutionDir)miscellaneous\constants\pciid\pci.ids" "$(OutDir)constants\p
MultiThreadedDebugtruestdcpp20
- Disabled
+ MaxSpeedConsole
@@ -126,15 +132,21 @@ copy "$(SolutionDir)miscellaneous\constants\pciid\pci.ids" "$(OutDir)constants\p
if exist "$(OutDir)SDK\" rd /q /s "$(OutDir)SDK\"
xcopy /E /I /Y "$(SolutionDir)include\SDK" "$(OutDir)SDK"
-xcopy /E /I /Y "$(SolutionDir)..\examples" "$(OutDir)SDK\Examples"
-mkdir "$(OutDir)SDK\Libraries"
-copy "$(OutDir)pdbex.lib" "$(OutDir)SDK\Libraries\pdbex.lib"
-copy "$(OutDir)kdserial.lib" "$(OutDir)SDK\Libraries\kdserial.lib"
-copy "$(OutDir)libhyperdbg.dll" "$(OutDir)SDK\Libraries\libhyperdbg.dll"
-copy "$(OutDir)script-engine.dll" "$(OutDir)SDK\Libraries\script-engine.dll"
-copy "$(OutDir)symbol-parser.dll" "$(OutDir)SDK\Libraries\symbol-parser.dll"
-copy "$(OutDir)hyperlog.dll" "$(OutDir)SDK\Libraries\hyperlog.dll"
-copy "$(OutDir)hyperhv.dll" "$(OutDir)SDK\Libraries\hyperhv.dll"
+xcopy /E /I /Y "$(SolutionDir)..\examples" "$(OutDir)SDK\examples"
+mkdir "$(OutDir)SDK\libraries"
+mkdir "$(OutDir)SDK\libraries\kernel"
+mkdir "$(OutDir)SDK\libraries\user"
+copy "$(OutDir)pdbex.dll" "$(OutDir)SDK\libraries\user\pdbex.dll"
+copy "$(OutDir)libipt.dll" "$(OutDir)SDK\libraries\user\libipt.dll"
+copy "$(OutDir)script-engine.dll" "$(OutDir)SDK\libraries\user\script-engine.dll"
+copy "$(OutDir)symbol-parser.dll" "$(OutDir)SDK\libraries\user\symbol-parser.dll"
+copy "$(OutDir)libhyperdbg.dll" "$(OutDir)SDK\libraries\user\libhyperdbg.dll"
+copy "$(OutDir)hyperlog.dll" "$(OutDir)SDK\libraries\kernel\hyperlog.dll"
+copy "$(OutDir)hyperhv.dll" "$(OutDir)SDK\libraries\kernel\hyperhv.dll"
+copy "$(OutDir)hypertrace.dll" "$(OutDir)SDK\libraries\kernel\hyperevade.dll"
+copy "$(OutDir)hypertrace.dll" "$(OutDir)SDK\libraries\kernel\hypertrace.dll"
+copy "$(OutDir)hyperperf.dll" "$(OutDir)SDK\libraries\kernel\hyperperf.dll"
+copy "$(OutDir)kdserial.dll" "$(OutDir)SDK\libraries\kernel\kdserial.dll"
if exist "$(OutDir)constants\" rd /q /s "$(OutDir)constants\"
mkdir "$(OutDir)constants"
copy "$(SolutionDir)miscellaneous\constants\pciid\pci.ids" "$(OutDir)constants\pci.ids"
@@ -143,9 +155,6 @@ copy "$(SolutionDir)miscellaneous\constants\pciid\pci.ids" "$(OutDir)constants\p
-
-
-
diff --git a/hyperdbg/hyperdbg-cli/hyperdbg-cli.vcxproj.filters b/hyperdbg/hyperdbg-cli/hyperdbg-cli.vcxproj.filters
index a9a66de5..7f812426 100644
--- a/hyperdbg/hyperdbg-cli/hyperdbg-cli.vcxproj.filters
+++ b/hyperdbg/hyperdbg-cli/hyperdbg-cli.vcxproj.filters
@@ -17,9 +17,4 @@
code
-
-
- header\platform
-
-
\ No newline at end of file
diff --git a/hyperdbg/hyperdbg-test/code/hardware/hwdbg-tests.cpp b/hyperdbg/hyperdbg-test/code/hardware/hwdbg-tests.cpp
index 46647903..2ea4af5f 100644
--- a/hyperdbg/hyperdbg-test/code/hardware/hwdbg-tests.cpp
+++ b/hyperdbg/hyperdbg-test/code/hardware/hwdbg-tests.cpp
@@ -15,23 +15,23 @@ namespace fs = std::filesystem;
/**
* @brief function to comment each line by adding ';' at the start
- * @param content
+ * @param Content the content to comment out
*
* @return std::string
*/
std::string
-commentContent(const std::string & content)
+CommentContent(const std::string & Content)
{
- std::istringstream iss(content);
- std::string line;
- std::string commentedContent;
+ std::istringstream Iss(Content);
+ std::string Line;
+ std::string CommentedContent;
- while (std::getline(iss, line))
+ while (std::getline(Iss, Line))
{
- commentedContent += line + "\n; ";
+ CommentedContent += Line + "\n; ";
}
- return commentedContent;
+ return CommentedContent;
}
/**
@@ -42,9 +42,9 @@ commentContent(const std::string & content)
* @return BOOLEAN
*/
BOOLEAN
-ReadDirectoryAndCreateHwdbgTestCases(const char * HwdbgScriptTestCasesPath)
+ReadDirectoryAndCreateHwdbgTestCases(const CHAR * HwdbgScriptTestCasesPath)
{
- CHAR tempFilePath[MAX_PATH] = {0};
+ CHAR TempFilePath[MAX_PATH] = {0};
//
// Iterate through the directory
@@ -61,7 +61,7 @@ ReadDirectoryAndCreateHwdbgTestCases(const char * HwdbgScriptTestCasesPath)
//
// Get the file path
//
- std::string filePath = entry.path().string();
+ std::string FilePath = entry.path().string();
//
// Output the file name
@@ -71,10 +71,10 @@ ReadDirectoryAndCreateHwdbgTestCases(const char * HwdbgScriptTestCasesPath)
//
// Open the file and read its contents
//
- std::ifstream file(filePath);
- if (file.is_open())
+ std::ifstream File(FilePath);
+ if (File.is_open())
{
- std::string content((std::istreambuf_iterator(file)),
+ std::string Content((std::istreambuf_iterator(File)),
std::istreambuf_iterator());
//
@@ -84,19 +84,19 @@ ReadDirectoryAndCreateHwdbgTestCases(const char * HwdbgScriptTestCasesPath)
// std::cout << content << std::endl;
- std::string compiled_version_file_path = HWDBG_SCRIPT_TEST_CASE_COMPILED_SCRIPTS_DIRECTORY "\\" + entry.path().filename().string() + ".hex.txt";
+ std::string CompiledVersionFilePath = HWDBG_SCRIPT_TEST_CASE_COMPILED_SCRIPTS_DIRECTORY "\\" + entry.path().filename().string() + ".hex.txt";
//
// Run the test case command
//
- printf("File content: %s\n", content.c_str());
+ printf("File content: %s\n", Content.c_str());
- if (!hwdbg_script_run_script(content.c_str(),
+ if (!hwdbg_script_run_script(Content.c_str(),
HWDBG_TEST_READ_INSTANCE_INFO_PATH,
- compiled_version_file_path.c_str(),
+ CompiledVersionFilePath.c_str(),
DEFAULT_INITIAL_BRAM_BUFFER_SIZE))
{
- std::cout << "[-] Could not run the script: " << filePath << std::endl;
+ std::cout << "[-] Could not run the script: " << FilePath << std::endl;
return FALSE;
}
@@ -107,7 +107,7 @@ ReadDirectoryAndCreateHwdbgTestCases(const char * HwdbgScriptTestCasesPath)
//
// Parse the hwdbg compiled test cases from the file
//
- if (!hyperdbg_u_setup_path_for_filename(compiled_version_file_path.c_str(), tempFilePath, MAX_PATH, FALSE))
+ if (!hyperdbg_u_setup_path_for_filename(CompiledVersionFilePath.c_str(), TempFilePath, MAX_PATH, FALSE))
{
//
// Error could not find the test case files
@@ -116,48 +116,48 @@ ReadDirectoryAndCreateHwdbgTestCases(const char * HwdbgScriptTestCasesPath)
return FALSE;
}
- std::ifstream compiledFile(tempFilePath);
- if (compiledFile.is_open())
+ std::ifstream CompiledFile(TempFilePath);
+ if (CompiledFile.is_open())
{
//
// Read the existing content of the compiled file
//
- std::string compiledContent((std::istreambuf_iterator(compiledFile)),
+ std::string CompiledContent((std::istreambuf_iterator(CompiledFile)),
std::istreambuf_iterator());
- compiledFile.close(); // Close the file after reading
+ CompiledFile.close(); // Close the file after reading
//
// Comment the content
//
- std::string commentedContent = commentContent(content);
+ std::string CommentedContent = CommentContent(Content);
//
// Concatenate the new content (prepend the original content)
//
- std::string newContent = "; The raw script file is available at: " HWDBG_SCRIPT_TEST_CASE_COMPILED_SCRIPTS_DIRECTORY "\\" +
+ std::string NewContent = "; The raw script file is available at: " HWDBG_SCRIPT_TEST_CASE_COMPILED_SCRIPTS_DIRECTORY "\\" +
entry.path().filename().string() +
"\n;\n; !hw script " +
- commentedContent +
+ CommentedContent +
"\n" +
- compiledContent;
+ CompiledContent;
//
// Write the new content back to the file (overwriting it)
//
- std::ofstream compiledFileOut(tempFilePath);
- if (compiledFileOut.is_open())
+ std::ofstream CompiledFileOut(TempFilePath);
+ if (CompiledFileOut.is_open())
{
- compiledFileOut << newContent;
- compiledFileOut.close();
+ CompiledFileOut << NewContent;
+ CompiledFileOut.close();
}
else
{
- std::cerr << "Could not open file for writing: " << compiled_version_file_path << std::endl;
+ std::cerr << "Could not open file for writing: " << CompiledVersionFilePath << std::endl;
}
}
else
{
- std::cerr << "Could not open compiled file: " << compiled_version_file_path << std::endl;
+ std::cerr << "Could not open compiled file: " << CompiledVersionFilePath << std::endl;
}
std::cout << "--------------------------------------------" << std::endl;
@@ -165,11 +165,11 @@ ReadDirectoryAndCreateHwdbgTestCases(const char * HwdbgScriptTestCasesPath)
//
// Close the file
//
- file.close();
+ File.close();
}
else
{
- std::cerr << "Could not open file: " << filePath << std::endl;
+ std::cerr << "Could not open file: " << FilePath << std::endl;
}
}
}
@@ -194,8 +194,8 @@ ReadDirectoryAndCreateHwdbgTestCases(const char * HwdbgScriptTestCasesPath)
BOOLEAN
HwdbgTestCreateTestCases()
{
- int testNum = 0;
- CHAR dirPath[MAX_PATH] = {0};
+ INT32 TestNum = 0;
+ CHAR dirPath[MAX_PATH] = {0};
//
// Parse the hwdbg test cases from the file
diff --git a/hyperdbg/hyperdbg-test/code/main.cpp b/hyperdbg/hyperdbg-test/code/main.cpp
index 1238f94b..d4d4b356 100644
--- a/hyperdbg/hyperdbg-test/code/main.cpp
+++ b/hyperdbg/hyperdbg-test/code/main.cpp
@@ -43,10 +43,25 @@ main(int argc, char * argv[])
printf("\n[x] The main command parser test cases failed\n");
}
}
- else if (!strcmp(argv[1], TEST_CASE_PARAMETER_FOR_SCRIPT_SEMANTIC_TEST_CASES))
+ else if (!strcmp(argv[1], TEST_CASE_PARAMETER_FOR_PE_PARSER))
{
//
// # Test case 2
+ // Testing PE parser helpers
+ //
+ if (TestPeParser())
+ {
+ printf("\n[*] The PE parser test cases passed successfully\n");
+ }
+ else
+ {
+ printf("\n[x] The PE parser test cases failed\n");
+ }
+ }
+ else if (!strcmp(argv[1], TEST_CASE_PARAMETER_FOR_SCRIPT_SEMANTIC_TEST_CASES))
+ {
+ //
+ // # Test case 3
// Testing script semantic test cases
//
if (TestSemanticScripts())
@@ -58,6 +73,21 @@ main(int argc, char * argv[])
printf("\n[x] The script semantic test cases failed\n");
}
}
+ else if (!strcmp(argv[1], TEST_CASE_PARAMETER_FOR_CODEVIEW_RSDS_PARSER))
+ {
+ //
+ // # Test case 4
+ // Testing CodeView RSDS parser helpers
+ //
+ if (TestCodeViewRsdsParser())
+ {
+ printf("\n[*] The CodeView RSDS parser test cases passed successfully\n");
+ }
+ else
+ {
+ printf("\n[x] The CodeView RSDS parser test cases failed\n");
+ }
+ }
else if (!strcmp(argv[1], TEST_HWDBG_FUNCTIONALITIES))
{
//
diff --git a/hyperdbg/hyperdbg-test/code/namedpipe.cpp b/hyperdbg/hyperdbg-test/code/namedpipe.cpp
index fccdfade..d3cf2ad2 100644
--- a/hyperdbg/hyperdbg-test/code/namedpipe.cpp
+++ b/hyperdbg/hyperdbg-test/code/namedpipe.cpp
@@ -12,7 +12,7 @@
#include "pch.h"
/**
- * @brief Create a named pipe server
+ * @brief Connect and transfer buffers via named pipe
*
* @return UINT32
*/
@@ -204,14 +204,14 @@ NamedPipeServerCreatePipe(LPCSTR PipeName, UINT32 OutputBufferSize, UINT32 Input
* @return BOOLEAN
*/
BOOLEAN
-NamedPipeServerWaitForClientConntection(HANDLE PipeHandle)
+NamedPipeServerWaitForClientConnection(HANDLE PipeHandle)
{
//
// Wait for the client to connect
//
- BOOL bClientConnected = ConnectNamedPipe(PipeHandle, NULL);
+ BOOLEAN ClientConnected = ConnectNamedPipe(PipeHandle, NULL);
- if (FALSE == bClientConnected)
+ if (FALSE == ClientConnected)
{
printf("err, occurred while connecting to the client (%x)\n",
GetLastError());
@@ -234,9 +234,9 @@ NamedPipeServerWaitForClientConntection(HANDLE PipeHandle)
* @return UINT32
*/
UINT32
-NamedPipeServerReadClientMessage(HANDLE PipeHandle, char * BufferToSave, int MaximumReadBufferLength)
+NamedPipeServerReadClientMessage(HANDLE PipeHandle, CHAR * BufferToSave, INT32 MaximumReadBufferLength)
{
- DWORD cbBytes;
+ DWORD BytesTransferred;
//
// We are connected to the client.
@@ -248,13 +248,13 @@ NamedPipeServerReadClientMessage(HANDLE PipeHandle, char * BufferToSave, int Max
//
// Read client message
//
- BOOL bResult = ReadFile(PipeHandle, // handle to pipe
- BufferToSave, // buffer to receive data
- MaximumReadBufferLength, // size of buffer
- &cbBytes, // number of bytes read
- NULL); // not overlapped I/O
+ BOOLEAN Result = ReadFile(PipeHandle, // handle to pipe
+ BufferToSave, // buffer to receive data
+ MaximumReadBufferLength, // size of buffer
+ &BytesTransferred, // number of bytes read
+ NULL); // not overlapped I/O
- if ((!bResult) || (0 == cbBytes))
+ if ((!Result) || (0 == BytesTransferred))
{
printf("err, occurred while reading from the client (%x)\n",
GetLastError());
@@ -265,29 +265,37 @@ NamedPipeServerReadClientMessage(HANDLE PipeHandle, char * BufferToSave, int Max
//
// Number of bytes that the client sends to us
//
- return cbBytes;
+ return BytesTransferred;
}
+/**
+ * @brief Send a message to the client over named pipe
+ *
+ * @param PipeHandle Handle of the named pipe
+ * @param BufferToSend Buffer containing the message to send
+ * @param BufferSize Size of the buffer to send
+ * @return BOOLEAN TRUE if successful, FALSE otherwise
+ */
BOOLEAN
NamedPipeServerSendMessageToClient(HANDLE PipeHandle,
- char * BufferToSend,
- int BufferSize)
+ CHAR * BufferToSend,
+ INT32 BufferSize)
{
- DWORD cbBytes;
+ DWORD BytesTransferred;
//
// Reply to client
//
- BOOLEAN bResult =
- WriteFile(PipeHandle, // handle to pipe
- BufferToSend, // buffer to write from
- BufferSize, // number of bytes to write, include the NULL
- &cbBytes, // number of bytes written
- NULL); // not overlapped I/O
+ BOOLEAN Result =
+ WriteFile(PipeHandle, // handle to pipe
+ BufferToSend, // buffer to write from
+ BufferSize, // number of bytes to write, include the NULL
+ &BytesTransferred, // number of bytes written
+ NULL); // not overlapped I/O
- if ((!bResult) || (BufferSize != cbBytes))
+ if ((!Result) || (BufferSize != (INT32)BytesTransferred))
{
- printf("Error occurred while writing to the client (%x)\n",
+ printf("err, occurred while writing to the client (%x)\n",
GetLastError());
CloseHandle(PipeHandle);
return FALSE;
@@ -363,15 +371,15 @@ NamedPipeClientCreatePipe(LPCSTR PipeName)
}
/**
- * @brief send client message over named pipe
+ * @brief Send client message over named pipe
*
- * @param PipeHandle
- * @param BufferToSend
- * @param BufferSize
- * @return BOOLEAN
+ * @param PipeHandle Handle of the named pipe
+ * @param BufferToSend Buffer containing the message to send
+ * @param BufferSize Size of the buffer to send
+ * @return BOOLEAN TRUE if successful, FALSE otherwise
*/
BOOLEAN
-NamedPipeClientSendMessage(HANDLE PipeHandle, char * BufferToSend, int BufferSize)
+NamedPipeClientSendMessage(HANDLE PipeHandle, CHAR * BufferToSend, INT32 BufferSize)
{
//
// We are done connecting to the server pipe,
@@ -380,19 +388,19 @@ NamedPipeClientSendMessage(HANDLE PipeHandle, char * BufferToSend, int BufferSiz
// on handle - hPipe
//
- DWORD cbBytes;
+ DWORD BytesTransferred;
//
// Send the message to server
//
- BOOL bResult =
- WriteFile(PipeHandle, // handle to pipe
- BufferToSend, // buffer to write from
- BufferSize, // number of bytes to write, include the NULL
- &cbBytes, // number of bytes written
- NULL); // not overlapped I/O
+ BOOLEAN Result =
+ WriteFile(PipeHandle, // handle to pipe
+ BufferToSend, // buffer to write from
+ BufferSize, // number of bytes to write, include the NULL
+ &BytesTransferred, // number of bytes written
+ NULL); // not overlapped I/O
- if ((!bResult) || (BufferSize != cbBytes))
+ if ((!Result) || (BufferSize != (INT32)BytesTransferred))
{
printf("err, occurred while writing to the server (%x)\n",
GetLastError());
@@ -410,35 +418,40 @@ NamedPipeClientSendMessage(HANDLE PipeHandle, char * BufferToSend, int BufferSiz
}
}
-//
-// Read the count of read buffer
-//
+/**
+ * @brief Read a message from the server over named pipe
+ *
+ * @param PipeHandle Handle of the named pipe
+ * @param BufferToRead Buffer to store the received message
+ * @param MaximumSizeOfBuffer Maximum size of the receive buffer
+ * @return UINT32 number of bytes read, or 0 on failure
+ */
UINT32
-NamedPipeClientReadMessage(HANDLE PipeHandle, char * BufferToRead, int MaximumSizeOfBuffer)
+NamedPipeClientReadMessage(HANDLE PipeHandle, CHAR * BufferToRead, INT32 MaximumSizeOfBuffer)
{
- DWORD cbBytes;
+ DWORD BytesTransferred;
//
// Read server response
//
- BOOL bResult = ReadFile(PipeHandle, // handle to pipe
- BufferToRead, // buffer to receive data
- MaximumSizeOfBuffer, // size of buffer
- &cbBytes, // number of bytes read
- NULL); // not overlapped I/O
+ BOOLEAN Result = ReadFile(PipeHandle, // handle to pipe
+ BufferToRead, // buffer to receive data
+ MaximumSizeOfBuffer, // size of buffer
+ &BytesTransferred, // number of bytes read
+ NULL); // not overlapped I/O
- if ((!bResult) || (0 == cbBytes))
+ if ((!Result) || (0 == BytesTransferred))
{
printf("err, occurred while reading from the server (%x)\n",
GetLastError());
CloseHandle(PipeHandle);
- return NULL; // Error
+ return 0; // Error
}
//
// Success
//
- return cbBytes;
+ return BytesTransferred;
}
/**
@@ -460,19 +473,19 @@ NamedPipeClientClosePipe(HANDLE PipeHandle)
////////////////////////////////////////////////////////////////////////////
/**
- * @brief and example of how to use named pipe as a server
+ * @brief An example of how to use named pipe as a server
*
- * @return int
+ * @return INT32
*/
-int
+INT32
NamedPipeServerExample()
{
- HANDLE PipeHandle;
- BOOLEAN SentMessageResult;
- UINT32 ReadBytes;
- const int BufferSize = 1024;
- char BufferToRead[BufferSize] = {0};
- char BufferToSend[BufferSize] = "test message to send from server !!!";
+ HANDLE PipeHandle;
+ BOOLEAN SentMessageResult;
+ UINT32 ReadBytes;
+ const INT32 BufferSize = 1024;
+ CHAR BufferToRead[BufferSize] = {0};
+ CHAR BufferToSend[BufferSize] = "test message to send from server !!!";
printf("create name pipe\n");
PipeHandle = NamedPipeServerCreatePipe("\\\\.\\Pipe\\HyperDbgTests",
@@ -489,7 +502,7 @@ NamedPipeServerExample()
printf("success!\n");
printf("wait for the client connection\n");
- if (!NamedPipeServerWaitForClientConntection(PipeHandle))
+ if (!NamedPipeServerWaitForClientConnection(PipeHandle))
{
//
// Error in connection
@@ -516,7 +529,7 @@ NamedPipeServerExample()
SentMessageResult = NamedPipeServerSendMessageToClient(
PipeHandle,
BufferToSend,
- (int)strlen(BufferToSend) + 1);
+ (INT32)strlen(BufferToSend) + 1);
if (!SentMessageResult)
{
@@ -538,20 +551,19 @@ NamedPipeServerExample()
////////////////////////////////////////////////////////////////////////////
/**
- * @brief and example of how to use named pipe as a client
+ * @brief An example of how to use named pipe as a client
*
- * @return int
+ * @return INT32
*/
-int
+INT32
NamedPipeClientExample()
{
- HANDLE PipeHandle;
- BOOLEAN SentMessageResult;
- UINT32 ReadBytes;
- const int BufferSize = 1024;
- char Buffer[BufferSize] = "test message to send from client !!!";
-
- PipeHandle = NamedPipeClientCreatePipe("\\\\.\\Pipe\\HyperDbgTests");
+ HANDLE PipeHandle;
+ BOOLEAN SentMessageResult;
+ UINT32 ReadBytes;
+ const INT32 BufferSize = 1024;
+ CHAR Buffer[BufferSize] = "test message to send from client !!!";
+ PipeHandle = NamedPipeClientCreatePipe("\\\\.\\Pipe\\HyperDbgTests");
if (!PipeHandle)
{
@@ -562,7 +574,7 @@ NamedPipeClientExample()
}
SentMessageResult =
- NamedPipeClientSendMessage(PipeHandle, Buffer, (int)strlen(Buffer) + 1);
+ NamedPipeClientSendMessage(PipeHandle, Buffer, (INT32)strlen(Buffer) + 1);
if (!SentMessageResult)
{
diff --git a/hyperdbg/hyperdbg-test/code/tests/test-codeview-rsds-parser.cpp b/hyperdbg/hyperdbg-test/code/tests/test-codeview-rsds-parser.cpp
new file mode 100644
index 00000000..a121929e
--- /dev/null
+++ b/hyperdbg/hyperdbg-test/code/tests/test-codeview-rsds-parser.cpp
@@ -0,0 +1,932 @@
+/**
+ * @file test-codeview-rsds-parser.cpp
+ * @author jtaw5649
+ * @brief Test cases for CodeView RSDS parser helpers
+ * @details
+ * @version 0.19
+ * @date 2026-06-02
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+static constexpr SIZE_T RsdsFixtureSize = 0x600;
+static constexpr LONG RsdsPeHeaderOffset = 0x80;
+static constexpr DWORD RsdsSectionRva = 0x1000;
+static constexpr DWORD RsdsSectionRaw = 0x200;
+static constexpr DWORD RsdsSectionSize = 0x300;
+static constexpr DWORD RsdsDebugDirectoryRva = 0x1100;
+static constexpr DWORD RsdsDebugDirectoryRaw = 0x300;
+static constexpr DWORD RsdsPayloadRva = 0x1140;
+static constexpr DWORD RsdsPayloadRaw = 0x340;
+static constexpr DWORD RsdsLoadedDebugRva = 0x280;
+static constexpr DWORD RsdsLoadedPayloadRva = 0x2c0;
+static constexpr SIZE_T RsdsHighLoadedSize = 0x22000;
+static constexpr DWORD RsdsHighLoadedDebugRva = 0x20000;
+static constexpr DWORD RsdsHighLoadedPayloadRva = 0x20100;
+static constexpr DWORD RsdsBogusRawPointer = 0xfffff000;
+
+static const GUID RsdsGuid64 = {0x67452301, 0xab89, 0xefcd, {0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe}};
+static const GUID RsdsGuid32 = {0x01234567, 0x89ab, 0xcdef, {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}};
+static const GUID RsdsGuidMulti = {0xaabbccdd, 0xeeff, 0x1122, {0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa}};
+
+/**
+ * @brief Calculates the file offset of the optional header based on the PE header offset
+ *
+ * @return SIZE_T The file offset of the optional header
+ */
+static SIZE_T
+RsdsOptionalHeaderOffset()
+{
+ return RsdsPeHeaderOffset + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER);
+}
+
+/**
+ * @brief Calculates the file offset of the first section header based on the optional header size
+ *
+ * @param OptionalHeaderSize The size of the optional header, obtained from the IMAGE_FILE_HEADER
+ *
+ * @return SIZE_T The file offset of the first section header
+ */
+static SIZE_T
+RsdsSectionHeaderOffset(SIZE_T OptionalHeaderSize)
+{
+ return RsdsOptionalHeaderOffset() + OptionalHeaderSize;
+}
+
+/**
+ * @brief Builds a minimal PE image in the provided buffer with the specified architecture
+ *
+ * @param Buffer The buffer to write the PE image into. Must be at least RsdsFixtureSize bytes
+ * @param Is32Bit Whether to build a 32-bit (true) or 64-bit (false) PE image
+ *
+ * @return VOID
+ */
+static VOID
+RsdsBuildMinimalPe(BYTE * Buffer, BOOLEAN Is32Bit)
+{
+ ZeroMemory(Buffer, RsdsFixtureSize);
+
+ IMAGE_DOS_HEADER * DosHeader = (IMAGE_DOS_HEADER *)Buffer;
+ DosHeader->e_magic = IMAGE_DOS_SIGNATURE;
+ DosHeader->e_lfanew = RsdsPeHeaderOffset;
+
+ BYTE * NtHeaders = Buffer + RsdsPeHeaderOffset;
+ *(DWORD *)NtHeaders = IMAGE_NT_SIGNATURE;
+
+ IMAGE_FILE_HEADER * FileHeader = (IMAGE_FILE_HEADER *)(NtHeaders + sizeof(DWORD));
+ FileHeader->Machine = Is32Bit ? IMAGE_FILE_MACHINE_I386 : IMAGE_FILE_MACHINE_AMD64;
+ FileHeader->NumberOfSections = 1;
+ FileHeader->SizeOfOptionalHeader = Is32Bit ? sizeof(IMAGE_OPTIONAL_HEADER32) : sizeof(IMAGE_OPTIONAL_HEADER64);
+
+ BYTE * OptionalHeader = NtHeaders + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER);
+ if (Is32Bit)
+ {
+ IMAGE_OPTIONAL_HEADER32 * OptionalHeader32 = (IMAGE_OPTIONAL_HEADER32 *)OptionalHeader;
+ OptionalHeader32->Magic = IMAGE_NT_OPTIONAL_HDR32_MAGIC;
+ OptionalHeader32->SizeOfHeaders = 0x200;
+ OptionalHeader32->SizeOfImage = 0x2000;
+ OptionalHeader32->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
+ OptionalHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = RsdsDebugDirectoryRva;
+ OptionalHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size = sizeof(IMAGE_DEBUG_DIRECTORY);
+ }
+ else
+ {
+ IMAGE_OPTIONAL_HEADER64 * OptionalHeader64 = (IMAGE_OPTIONAL_HEADER64 *)OptionalHeader;
+ OptionalHeader64->Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ OptionalHeader64->SizeOfHeaders = 0x200;
+ OptionalHeader64->SizeOfImage = 0x2000;
+ OptionalHeader64->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
+ OptionalHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = RsdsDebugDirectoryRva;
+ OptionalHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size = sizeof(IMAGE_DEBUG_DIRECTORY);
+ }
+
+ IMAGE_SECTION_HEADER * SectionHeader = (IMAGE_SECTION_HEADER *)(Buffer + RsdsSectionHeaderOffset(FileHeader->SizeOfOptionalHeader));
+ CopyMemory(SectionHeader->Name, ".rdata", sizeof(".rdata") - 1);
+ SectionHeader->Misc.VirtualSize = RsdsSectionSize;
+ SectionHeader->VirtualAddress = RsdsSectionRva;
+ SectionHeader->SizeOfRawData = RsdsSectionSize;
+ SectionHeader->PointerToRawData = RsdsSectionRaw;
+}
+
+/**
+ * @brief Updates the debug directory entry in the PE image to point to the specified directory
+ *
+ * @param Buffer The buffer containing the PE image
+ * @param DirectoryRva The RVA of the debug directory to set
+ * @param DirectorySize The size of the debug directory
+ *
+ * @return VOID
+ */
+static VOID
+RsdsSetDebugDirectory(BYTE * Buffer, DWORD DirectoryRva, DWORD DirectorySize)
+{
+ BYTE * NtHeaders = Buffer + RsdsPeHeaderOffset;
+ BYTE * OptionalHeader = NtHeaders + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER);
+ WORD Magic = *(WORD *)OptionalHeader;
+
+ if (Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
+ {
+ IMAGE_OPTIONAL_HEADER32 * OptionalHeader32 = (IMAGE_OPTIONAL_HEADER32 *)OptionalHeader;
+ OptionalHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = DirectoryRva;
+ OptionalHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size = DirectorySize;
+ }
+ else
+ {
+ IMAGE_OPTIONAL_HEADER64 * OptionalHeader64 = (IMAGE_OPTIONAL_HEADER64 *)OptionalHeader;
+ OptionalHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = DirectoryRva;
+ OptionalHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size = DirectorySize;
+ }
+}
+
+/**
+ * @brief Updates the NumberOfRvaAndSizes field in the optional header to the specified value
+ *
+ * @param Buffer The buffer containing the PE image
+ * @param NumberOfRvaAndSizes The value to set for the NumberOfRvaAndSizes field
+ *
+ * @return VOID
+ */
+static VOID
+RsdsSetNumberOfRvaAndSizes(BYTE * Buffer, DWORD NumberOfRvaAndSizes)
+{
+ BYTE * NtHeaders = Buffer + RsdsPeHeaderOffset;
+ BYTE * OptionalHeader = NtHeaders + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER);
+ WORD Magic = *(WORD *)OptionalHeader;
+
+ if (Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
+ {
+ ((IMAGE_OPTIONAL_HEADER32 *)OptionalHeader)->NumberOfRvaAndSizes = NumberOfRvaAndSizes;
+ }
+ else
+ {
+ ((IMAGE_OPTIONAL_HEADER64 *)OptionalHeader)->NumberOfRvaAndSizes = NumberOfRvaAndSizes;
+ }
+}
+
+/**
+ * @brief Updates the SizeOfImage field in the optional header to the specified value
+ *
+ * @param Buffer The buffer containing the PE image
+ * @param SizeOfImage The value to set for the SizeOfImage field
+ *
+ * @return VOID
+ */
+static VOID
+RsdsSetSizeOfImage(BYTE * Buffer, DWORD SizeOfImage)
+{
+ BYTE * NtHeaders = Buffer + RsdsPeHeaderOffset;
+ BYTE * OptionalHeader = NtHeaders + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER);
+ WORD Magic = *(WORD *)OptionalHeader;
+
+ if (Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
+ {
+ ((IMAGE_OPTIONAL_HEADER32 *)OptionalHeader)->SizeOfImage = SizeOfImage;
+ }
+ else
+ {
+ ((IMAGE_OPTIONAL_HEADER64 *)OptionalHeader)->SizeOfImage = SizeOfImage;
+ }
+}
+
+/**
+ * @brief Writes an RSDS CodeView payload to the specified location in the buffer
+ *
+ * @param Buffer The buffer to write the payload into
+ * @param RawOffset The file offset to write the payload at
+ * @param Guid The GUID to include in the payload
+ * @param Age The age to include in the payload
+ * @param Path The path to include in the payload
+ * @param IncludeNul Whether to include a NUL terminator at the end of the path
+ *
+ * @return VOID
+ */
+static VOID
+RsdsWritePayload(BYTE * Buffer, DWORD RawOffset, const GUID & Guid, DWORD Age, const CHAR * Path, BOOLEAN IncludeNul)
+{
+ BYTE * Payload = Buffer + RawOffset;
+ CopyMemory(Payload, "RSDS", sizeof(DWORD));
+ CopyMemory(Payload + sizeof(DWORD), &Guid, sizeof(Guid));
+ CopyMemory(Payload + sizeof(DWORD) + sizeof(GUID), &Age, sizeof(Age));
+
+ SIZE_T PathLength = strlen(Path);
+ CopyMemory(Payload + sizeof(DWORD) + sizeof(GUID) + sizeof(DWORD), Path, PathLength);
+ if (IncludeNul)
+ {
+ Payload[sizeof(DWORD) + sizeof(GUID) + sizeof(DWORD) + PathLength] = '\0';
+ }
+}
+
+/**
+ * @brief Calculates the size of an RSDS CodeView payload based on the path length and whether to include a NUL terminator
+ *
+ * @param Path The path to be included in the payload
+ * @param IncludeNul Whether to include a NUL terminator at the end of the path
+ *
+ * @return DWORD The size of the payload in bytes
+ */
+static DWORD
+RsdsPayloadSize(const CHAR * Path, BOOLEAN IncludeNul)
+{
+ return (DWORD)(sizeof(DWORD) + sizeof(GUID) + sizeof(DWORD) + strlen(Path) + (IncludeNul ? 1 : 0));
+}
+
+/**
+ * @brief Writes an IMAGE_DEBUG_DIRECTORY entry to the specified location in the buffer
+ *
+ * @param Buffer The buffer to write the debug entry into
+ * @param EntryRawOffset The file offset to write the debug entry at
+ * @param Type The Type field of the debug entry
+ * @param PayloadRva The AddressOfRawData field of the debug entry
+ * @param PayloadRaw The PointerToRawData field of the debug entry
+ * @param PayloadSize The SizeOfData field of the debug entry
+ *
+ * @return VOID
+ */
+static VOID
+RsdsWriteDebugEntry(BYTE * Buffer, DWORD EntryRawOffset, DWORD Type, DWORD PayloadRva, DWORD PayloadRaw, DWORD PayloadSize)
+{
+ IMAGE_DEBUG_DIRECTORY * DebugEntry = (IMAGE_DEBUG_DIRECTORY *)(Buffer + EntryRawOffset);
+ ZeroMemory(DebugEntry, sizeof(*DebugEntry));
+ DebugEntry->Type = Type;
+ DebugEntry->SizeOfData = PayloadSize;
+ DebugEntry->AddressOfRawData = PayloadRva;
+ DebugEntry->PointerToRawData = PayloadRaw;
+}
+
+/**
+ * @brief Builds a minimal PE image with a valid RSDS debug entry in the specified buffer
+ *
+ * @param Buffer The buffer to write the PE image into. Must be at least RsdsFixtureSize bytes
+ * @param Guid The GUID to include in the RSDS payload
+ * @param Age The age to include in the RSDS payload
+ * @param Path The path to include in the RSDS payload
+ *
+ * @return VOID
+ */
+static VOID
+RsdsWriteValidDebugEntry(BYTE * Buffer, const GUID & Guid, DWORD Age, const CHAR * Path)
+{
+ DWORD PayloadSize = RsdsPayloadSize(Path, TRUE);
+ RsdsWritePayload(Buffer, RsdsPayloadRaw, Guid, Age, Path, TRUE);
+ RsdsWriteDebugEntry(Buffer, RsdsDebugDirectoryRaw, IMAGE_DEBUG_TYPE_CODEVIEW, RsdsPayloadRva, RsdsPayloadRaw, PayloadSize);
+}
+
+/**
+ * @brief Builds a minimal PE image with a valid RSDS debug entry suitable for loaded PE parsing in the specified buffer
+ *
+ * @param Buffer The buffer to write the PE image into. Must be at least RsdsFixtureSize bytes
+ * @param Is32Bit Whether to build a 32-bit (true) or 64-bit (false) PE image
+ *
+ * @return VOID
+ */
+static VOID
+RsdsBuildLoadedPe(BYTE * Buffer, BOOLEAN Is32Bit)
+{
+ RsdsBuildMinimalPe(Buffer, Is32Bit);
+ RsdsSetDebugDirectory(Buffer, RsdsLoadedDebugRva, sizeof(IMAGE_DEBUG_DIRECTORY));
+}
+
+/**
+ * @brief Writes a valid RSDS debug entry suitable for loaded PE parsing to the specified buffer
+ *
+ * @param Buffer The buffer to write the debug entry into
+ * @param Guid The GUID to include in the RSDS payload
+ * @param Age The age to include in the RSDS payload
+ * @param Path The path to include in the RSDS payload
+ *
+ * @return VOID
+ */
+static VOID
+RsdsWriteValidLoadedDebugEntry(BYTE * Buffer, const GUID & Guid, DWORD Age, const CHAR * Path)
+{
+ DWORD PayloadSize = RsdsPayloadSize(Path, TRUE);
+ RsdsWritePayload(Buffer, RsdsLoadedPayloadRva, Guid, Age, Path, TRUE);
+ RsdsWriteDebugEntry(Buffer, RsdsLoadedDebugRva, IMAGE_DEBUG_TYPE_CODEVIEW, RsdsLoadedPayloadRva, RsdsBogusRawPointer, PayloadSize);
+}
+
+/**
+ * @brief Compares two GUIDs for equality
+ *
+ * @param Left The first GUID to compare
+ * @param Right The second GUID to compare
+ *
+ * @return BOOLEAN TRUE if the GUIDs are equal, FALSE otherwise
+ */
+static BOOLEAN
+RsdsGuidEquals(const GUID & Left, const GUID & Right)
+{
+ return memcmp(&Left, &Right, sizeof(Left)) == 0;
+}
+
+/**
+ * @brief Helper function to test that the RSDS parser successfully extracts the expected information from the provided buffer
+ *
+ * @param Buffer The buffer containing the PE image to parse
+ * @param ExpectedPdb The expected PDB file name to be extracted from the RSDS payload
+ * @param ExpectedGuid The expected GUID to be extracted from the RSDS payload
+ * @param ExpectedAge The expected age to be extracted from the RSDS payload
+ *
+ * @return BOOLEAN TRUE if the parser successfully extracted the expected information, FALSE otherwise
+ */
+static BOOLEAN
+RsdsExpectSuccess(const BYTE * Buffer, const CHAR * ExpectedPdb, const GUID & ExpectedGuid, DWORD ExpectedAge)
+{
+ CHAR PdbFileName[MAX_PATH] = {0};
+ GUID Guid = {0};
+ DWORD Age = 0;
+
+ return SymExtractCodeViewRsdsInfoFromPeImage(Buffer, RsdsFixtureSize, PdbFileName, sizeof(PdbFileName), &Guid, &Age) &&
+ strcmp(PdbFileName, ExpectedPdb) == 0 && RsdsGuidEquals(Guid, ExpectedGuid) && Age == ExpectedAge;
+}
+
+/**
+ * @brief Helper function to test that the RSDS parser fails to extract information from the provided buffer and leaves output parameters unchanged
+ *
+ * @param Buffer The buffer containing the PE image to parse
+ *
+ * @return BOOLEAN TRUE if the parser failed as expected and left output parameters unchanged, FALSE otherwise
+ */
+static BOOLEAN
+RsdsExpectFailure(const BYTE * Buffer)
+{
+ CHAR PdbFileName[MAX_PATH] = {'x'};
+ GUID Guid = RsdsGuid64;
+ GUID EmptyGuid = {0};
+ DWORD Age = 0x12345678;
+
+ return !SymExtractCodeViewRsdsInfoFromPeImage(Buffer, RsdsFixtureSize, PdbFileName, sizeof(PdbFileName), &Guid, &Age) &&
+ PdbFileName[0] == '\0' && RsdsGuidEquals(Guid, EmptyGuid) && Age == 0;
+}
+
+/**
+ * @brief Helper function to test that the RSDS parser successfully extracts the expected information from the provided buffer when parsing as a loaded PE
+ *
+ * @param Buffer The buffer containing the PE image to parse
+ * @param ExpectedPdb The expected PDB file name to be extracted from the RSDS payload
+ * @param ExpectedGuid The expected GUID to be extracted from the RSDS payload
+ * @param ExpectedAge The expected age to be extracted from the RSDS payload
+ *
+ * @return BOOLEAN TRUE if the parser successfully extracted the expected information, FALSE otherwise
+ */
+static BOOLEAN
+RsdsExpectLoadedSuccess(const BYTE * Buffer, const CHAR * ExpectedPdb, const GUID & ExpectedGuid, DWORD ExpectedAge)
+{
+ CHAR PdbFileName[MAX_PATH] = {0};
+ GUID Guid = {0};
+ DWORD Age = 0;
+
+ return SymExtractCodeViewRsdsInfoFromLoadedPeImage(Buffer, RsdsFixtureSize, PdbFileName, sizeof(PdbFileName), &Guid, &Age) &&
+ strcmp(PdbFileName, ExpectedPdb) == 0 && RsdsGuidEquals(Guid, ExpectedGuid) && Age == ExpectedAge;
+}
+
+/**
+ * @brief Helper function to test that the RSDS parser fails to extract information from the provided buffer when parsing as a loaded PE and leaves output parameters unchanged
+ *
+ * @param Buffer The buffer containing the PE image to parse
+ *
+ * @return BOOLEAN TRUE if the parser failed as expected and left output parameters unchanged, FALSE otherwise
+ */
+static BOOLEAN
+RsdsExpectLoadedFailure(const BYTE * Buffer)
+{
+ CHAR PdbFileName[MAX_PATH] = {'x'};
+ GUID Guid = RsdsGuid64;
+ GUID EmptyGuid = {0};
+ DWORD Age = 0x12345678;
+
+ return !SymExtractCodeViewRsdsInfoFromLoadedPeImage(Buffer, RsdsFixtureSize, PdbFileName, sizeof(PdbFileName), &Guid, &Age) &&
+ PdbFileName[0] == '\0' && RsdsGuidEquals(Guid, EmptyGuid) && Age == 0;
+}
+
+// Context structure for the fake fallback function used in some test cases
+typedef struct _RSDS_FAKE_FALLBACK_CONTEXT
+{
+ INT32 CallCount;
+ BOOLEAN Succeed;
+} RSDS_FAKE_FALLBACK_CONTEXT, *PRSDS_FAKE_FALLBACK_CONTEXT;
+
+/**
+ * @brief A fake fallback function that can be used to test the behavior of the RSDS parser when a fallback is triggered
+ *
+ * @param Context A pointer to an RSDS_FAKE_FALLBACK_CONTEXT structure that controls the behavior of the fallback
+ * @param PdbFile The output buffer to receive the PDB file name (must be at least MAX_PATH bytes)
+ * @param PdbFileSize The size of the PdbFile buffer in bytes
+ * @param Guid The output parameter to receive the GUID
+ * @param Age The output parameter to receive the age
+ *
+ * @return BOOLEAN TRUE if the fallback succeeded and filled output parameters, FALSE if the fallback failed and left output parameters unchanged
+ */
+static BOOLEAN
+RsdsFakeFallback(PVOID Context, CHAR * PdbFile, SIZE_T PdbFileSize, GUID * Guid, DWORD * Age)
+{
+ PRSDS_FAKE_FALLBACK_CONTEXT FallbackContext = (PRSDS_FAKE_FALLBACK_CONTEXT)Context;
+
+ FallbackContext->CallCount++;
+ if (!FallbackContext->Succeed)
+ {
+ return FALSE;
+ }
+
+ if (strcpy_s(PdbFile, PdbFileSize, "fallback.pdb") != 0)
+ {
+ return FALSE;
+ }
+
+ *Guid = RsdsGuidMulti;
+ *Age = 0x2b;
+
+ return TRUE;
+}
+
+/**
+ * @brief Runs a series of test cases to validate the behavior of the RSDS parser helper functions
+ *
+ * @return BOOLEAN TRUE if all test cases passed, FALSE if any test case failed
+ */
+BOOLEAN
+TestCodeViewRsdsParser()
+{
+ BYTE Buffer[RsdsFixtureSize] = {0};
+ INT32 TestNum = 0;
+
+ RsdsBuildMinimalPe(Buffer, FALSE);
+ RsdsWriteValidDebugEntry(Buffer, RsdsGuid64, 7, "symbols\\valid64.pdb");
+ TestNum++;
+ if (RsdsExpectSuccess(Buffer, "valid64.pdb", RsdsGuid64, 7))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] valid PE32+ RSDS entry was not parsed\n");
+ return FALSE;
+ }
+
+ RsdsBuildMinimalPe(Buffer, FALSE);
+ RsdsWriteValidDebugEntry(Buffer, RsdsGuid64, 7, "symbols\\unadvertised.pdb");
+ RsdsSetNumberOfRvaAndSizes(Buffer, IMAGE_DIRECTORY_ENTRY_DEBUG);
+ TestNum++;
+ if (RsdsExpectFailure(Buffer))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] raw parser accepted an unadvertised debug directory\n");
+ return FALSE;
+ }
+
+ RsdsBuildMinimalPe(Buffer, TRUE);
+ RsdsWriteValidDebugEntry(Buffer, RsdsGuid32, 9, "symbols/valid32.pdb");
+ TestNum++;
+ if (RsdsExpectSuccess(Buffer, "valid32.pdb", RsdsGuid32, 9))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] valid PE32 RSDS entry was not parsed\n");
+ return FALSE;
+ }
+
+ RsdsBuildMinimalPe(Buffer, FALSE);
+ RsdsWriteValidDebugEntry(Buffer, RsdsGuid64, 7, "symbols\\valid64.pdb");
+ RsdsSetDebugDirectory(Buffer, 0x3000, sizeof(IMAGE_DEBUG_DIRECTORY));
+ TestNum++;
+ if (RsdsExpectFailure(Buffer))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] unmapped debug directory parsed successfully\n");
+ return FALSE;
+ }
+
+ RsdsBuildMinimalPe(Buffer, FALSE);
+ RsdsWriteValidDebugEntry(Buffer, RsdsGuid64, 7, "symbols\\invalid.pdb");
+ CopyMemory(Buffer + RsdsPayloadRaw, "ABCD", sizeof(DWORD));
+ TestNum++;
+ if (RsdsExpectFailure(Buffer))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] unsupported CodeView signature parsed successfully\n");
+ return FALSE;
+ }
+
+ RsdsBuildMinimalPe(Buffer, FALSE);
+ RsdsWritePayload(Buffer, RsdsPayloadRaw, RsdsGuid64, 7, "symbols\\missing-nul.pdb", FALSE);
+ RsdsWriteDebugEntry(Buffer,
+ RsdsDebugDirectoryRaw,
+ IMAGE_DEBUG_TYPE_CODEVIEW,
+ RsdsPayloadRva,
+ RsdsPayloadRaw,
+ RsdsPayloadSize("symbols\\missing-nul.pdb", FALSE));
+ TestNum++;
+ if (RsdsExpectFailure(Buffer))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] RSDS path without NUL terminator parsed successfully\n");
+ return FALSE;
+ }
+
+ RsdsBuildMinimalPe(Buffer, FALSE);
+ RsdsSetDebugDirectory(Buffer, RsdsDebugDirectoryRva, sizeof(IMAGE_DEBUG_DIRECTORY) * 2);
+ RsdsWriteDebugEntry(Buffer, RsdsDebugDirectoryRaw, IMAGE_DEBUG_TYPE_CODEVIEW, RsdsPayloadRva, RsdsPayloadRaw, sizeof(DWORD));
+ CopyMemory(Buffer + RsdsPayloadRaw, "NB10", sizeof(DWORD));
+ RsdsWritePayload(Buffer, 0x390, RsdsGuidMulti, 11, "alt/second-valid.pdb", TRUE);
+ RsdsWriteDebugEntry(Buffer,
+ RsdsDebugDirectoryRaw + sizeof(IMAGE_DEBUG_DIRECTORY),
+ IMAGE_DEBUG_TYPE_CODEVIEW,
+ 0x1190,
+ 0x390,
+ RsdsPayloadSize("alt/second-valid.pdb", TRUE));
+ TestNum++;
+ if (RsdsExpectSuccess(Buffer, "second-valid.pdb", RsdsGuidMulti, 11))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] parser did not skip invalid first entry and parse second RSDS entry\n");
+ return FALSE;
+ }
+
+ RsdsBuildLoadedPe(Buffer, FALSE);
+ RsdsWriteValidLoadedDebugEntry(Buffer, RsdsGuid64, 0x21, "loaded\\loaded64.pdb");
+ TestNum++;
+ if (RsdsExpectLoadedSuccess(Buffer, "loaded64.pdb", RsdsGuid64, 0x21))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] loaded PE32+ RSDS entry was not parsed\n");
+ return FALSE;
+ }
+
+ RsdsBuildLoadedPe(Buffer, FALSE);
+ RsdsWriteValidLoadedDebugEntry(Buffer, RsdsGuid64, 0x21, "loaded\\unadvertised.pdb");
+ RsdsSetNumberOfRvaAndSizes(Buffer, IMAGE_DIRECTORY_ENTRY_DEBUG);
+ TestNum++;
+ if (RsdsExpectLoadedFailure(Buffer))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] loaded parser accepted an unadvertised debug directory\n");
+ return FALSE;
+ }
+
+ RsdsBuildLoadedPe(Buffer, TRUE);
+ RsdsWriteValidLoadedDebugEntry(Buffer, RsdsGuid32, 0x22, "loaded/loaded32.pdb");
+ TestNum++;
+ if (RsdsExpectLoadedSuccess(Buffer, "loaded32.pdb", RsdsGuid32, 0x22))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] loaded PE32 RSDS entry was not parsed\n");
+ return FALSE;
+ }
+
+ RsdsBuildLoadedPe(Buffer, FALSE);
+ RsdsWriteValidLoadedDebugEntry(Buffer, RsdsGuid64, 0x23, "loaded\\bogus-raw-ignored.pdb");
+ TestNum++;
+ if (RsdsExpectLoadedSuccess(Buffer, "bogus-raw-ignored.pdb", RsdsGuid64, 0x23))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] loaded parser used bogus PointerToRawData instead of loaded RVA\n");
+ return FALSE;
+ }
+
+ std::vector HighLoadedBuffer(RsdsHighLoadedSize);
+ RsdsBuildLoadedPe(HighLoadedBuffer.data(), FALSE);
+ RsdsSetSizeOfImage(HighLoadedBuffer.data(), (DWORD)HighLoadedBuffer.size());
+ RsdsSetDebugDirectory(HighLoadedBuffer.data(), RsdsHighLoadedDebugRva, sizeof(IMAGE_DEBUG_DIRECTORY));
+ RsdsWritePayload(HighLoadedBuffer.data(), RsdsHighLoadedPayloadRva, RsdsGuid64, 0x28, "loaded\\high-rva.pdb", TRUE);
+ RsdsWriteDebugEntry(HighLoadedBuffer.data(),
+ RsdsHighLoadedDebugRva,
+ IMAGE_DEBUG_TYPE_CODEVIEW,
+ RsdsHighLoadedPayloadRva,
+ RsdsBogusRawPointer,
+ RsdsPayloadSize("loaded\\high-rva.pdb", TRUE));
+ CHAR HighLoadedPdbFileName[MAX_PATH] = {0};
+ GUID HighLoadedGuid = {0};
+ DWORD HighLoadedAge = 0;
+ TestNum++;
+ if (SymExtractCodeViewRsdsInfoFromLoadedPeImage(HighLoadedBuffer.data(),
+ HighLoadedBuffer.size(),
+ HighLoadedPdbFileName,
+ sizeof(HighLoadedPdbFileName),
+ &HighLoadedGuid,
+ &HighLoadedAge) &&
+ strcmp(HighLoadedPdbFileName, "high-rva.pdb") == 0 && RsdsGuidEquals(HighLoadedGuid, RsdsGuid64) &&
+ HighLoadedAge == 0x28)
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] loaded parser did not parse high-RVA RSDS data\n");
+ return FALSE;
+ }
+
+ RsdsBuildLoadedPe(Buffer, FALSE);
+ RsdsWriteValidLoadedDebugEntry(Buffer, RsdsGuid64, 0x24, "loaded\\invalid-dir.pdb");
+ RsdsSetDebugDirectory(Buffer, RsdsFixtureSize - sizeof(IMAGE_DEBUG_DIRECTORY) / 2, sizeof(IMAGE_DEBUG_DIRECTORY));
+ TestNum++;
+ if (RsdsExpectLoadedFailure(Buffer))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] loaded parser accepted malformed debug directory bounds\n");
+ return FALSE;
+ }
+
+ RsdsBuildLoadedPe(Buffer, FALSE);
+ RsdsWriteValidLoadedDebugEntry(Buffer, RsdsGuid64, 0x25, "loaded\\unsupported.pdb");
+ CopyMemory(Buffer + RsdsLoadedPayloadRva, "ABCD", sizeof(DWORD));
+ TestNum++;
+ if (RsdsExpectLoadedFailure(Buffer))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] loaded parser accepted unsupported CodeView signature\n");
+ return FALSE;
+ }
+
+ RsdsBuildLoadedPe(Buffer, FALSE);
+ RsdsWritePayload(Buffer, RsdsLoadedPayloadRva, RsdsGuid64, 0x26, "loaded\\missing-nul.pdb", FALSE);
+ RsdsWriteDebugEntry(Buffer,
+ RsdsLoadedDebugRva,
+ IMAGE_DEBUG_TYPE_CODEVIEW,
+ RsdsLoadedPayloadRva,
+ RsdsBogusRawPointer,
+ RsdsPayloadSize("loaded\\missing-nul.pdb", FALSE));
+ TestNum++;
+ if (RsdsExpectLoadedFailure(Buffer))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] loaded parser accepted RSDS path without NUL terminator\n");
+ return FALSE;
+ }
+
+ RsdsBuildLoadedPe(Buffer, FALSE);
+ RsdsSetDebugDirectory(Buffer, RsdsLoadedDebugRva, sizeof(IMAGE_DEBUG_DIRECTORY) * 2);
+ RsdsWriteDebugEntry(Buffer, RsdsLoadedDebugRva, IMAGE_DEBUG_TYPE_CODEVIEW, RsdsLoadedPayloadRva, RsdsBogusRawPointer, sizeof(DWORD));
+ CopyMemory(Buffer + RsdsLoadedPayloadRva, "NB10", sizeof(DWORD));
+ RsdsWritePayload(Buffer, 0x330, RsdsGuidMulti, 0x27, "loaded/second-loaded.pdb", TRUE);
+ RsdsWriteDebugEntry(Buffer,
+ RsdsLoadedDebugRva + sizeof(IMAGE_DEBUG_DIRECTORY),
+ IMAGE_DEBUG_TYPE_CODEVIEW,
+ 0x330,
+ RsdsBogusRawPointer,
+ RsdsPayloadSize("loaded/second-loaded.pdb", TRUE));
+ TestNum++;
+ if (RsdsExpectLoadedSuccess(Buffer, "second-loaded.pdb", RsdsGuidMulti, 0x27))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] loaded parser did not skip invalid first entry and parse second RSDS entry\n");
+ return FALSE;
+ }
+
+ CHAR SymbolServerRelativePath[MAX_PATH] = {0};
+ CHAR GuidAndAgeDetails[MAX_PATH] = {0};
+ CHAR SmallGuidAndAgeDetails[MAXIMUM_GUID_AND_AGE_SIZE] = {0};
+ const GUID Guid = {0x01234567, 0x89ab, 0xcdef, {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}};
+ TestNum++;
+ if (SymFormatPdbIdentity("valid32.pdb",
+ &Guid,
+ 0x1a,
+ SymbolServerRelativePath,
+ sizeof(SymbolServerRelativePath),
+ GuidAndAgeDetails,
+ sizeof(GuidAndAgeDetails)) &&
+ strcmp(GuidAndAgeDetails, "0123456789abcdeffedcba98765432101a") == 0 &&
+ strcmp(SymbolServerRelativePath, "valid32.pdb/0123456789abcdeffedcba98765432101a/valid32.pdb") == 0)
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] PDB identity formatting did not match symbol server path and GUID+age expectations\n");
+ return FALSE;
+ }
+
+ TestNum++;
+ if (SymFormatPdbIdentity("valid32.pdb",
+ &Guid,
+ 0x1a,
+ NULL,
+ 0,
+ SmallGuidAndAgeDetails,
+ sizeof(SmallGuidAndAgeDetails)) &&
+ strcmp(SmallGuidAndAgeDetails, "0123456789abcdeffedcba98765432101a") == 0)
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] GUID+age identity did not fit the SDK-sized buffer\n");
+ return FALSE;
+ }
+
+ RsdsBuildMinimalPe(Buffer, FALSE);
+ RsdsWriteValidDebugEntry(Buffer, RsdsGuid64, 0x1c, "preferred\\preferred.pdb");
+ RSDS_FAKE_FALLBACK_CONTEXT FallbackContext = {0, TRUE};
+ CHAR PreferredPath[MAX_PATH] = {0};
+ TestNum++;
+ if (SymFormatPdbIdentityFromPeImageOrFallback(Buffer,
+ RsdsFixtureSize,
+ PreferredPath,
+ sizeof(PreferredPath),
+ NULL,
+ 0,
+ NULL,
+ 0,
+ RsdsFakeFallback,
+ &FallbackContext) &&
+ strcmp(PreferredPath, "preferred.pdb/67452301ab89efcd1032547698badcfe1c/preferred.pdb") == 0 &&
+ FallbackContext.CallCount == 0)
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] PE RSDS identity was not preferred over fallback identity\n");
+ return FALSE;
+ }
+
+ FallbackContext.CallCount = 0;
+ CHAR ZeroSizeOutput = 'x';
+ TestNum++;
+ if (!SymFormatPdbIdentityFromPeImageOrFallback(Buffer,
+ RsdsFixtureSize,
+ &ZeroSizeOutput,
+ 0,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ RsdsFakeFallback,
+ &FallbackContext) &&
+ ZeroSizeOutput == 'x' && FallbackContext.CallCount == 0)
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] zero-sized output buffer was written or reported success\n");
+ return FALSE;
+ }
+
+ FallbackContext.CallCount = 0;
+ TestNum++;
+ if (!SymFormatPdbIdentityFromPeImageOrFallback(Buffer,
+ RsdsFixtureSize,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ RsdsFakeFallback,
+ &FallbackContext) &&
+ FallbackContext.CallCount == 0)
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] identity formatting without requested output reported success or used fallback\n");
+ return FALSE;
+ }
+
+ FallbackContext.CallCount = 0;
+ CHAR SmallPdbPath[4] = {'x'};
+ CHAR SmallFailureGuidAge[64] = {'x'};
+ TestNum++;
+ if (!SymFormatPdbIdentityFromPeImageOrFallback(Buffer,
+ RsdsFixtureSize,
+ NULL,
+ 0,
+ SmallPdbPath,
+ sizeof(SmallPdbPath),
+ SmallFailureGuidAge,
+ sizeof(SmallFailureGuidAge),
+ RsdsFakeFallback,
+ &FallbackContext) &&
+ SmallPdbPath[0] == '\0' && SmallFailureGuidAge[0] == '\0' && FallbackContext.CallCount == 0)
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] output formatting failure leaked partial identity data\n");
+ return FALSE;
+ }
+
+ ZeroMemory(Buffer, sizeof(Buffer));
+ FallbackContext.CallCount = 0;
+ FallbackContext.Succeed = TRUE;
+ CHAR FallbackPdb[MAX_PATH] = {0};
+ CHAR FallbackGuidAge[MAX_PATH] = {0};
+ TestNum++;
+ if (SymFormatPdbIdentityFromPeImageOrFallback(Buffer,
+ RsdsFixtureSize,
+ NULL,
+ 0,
+ FallbackPdb,
+ sizeof(FallbackPdb),
+ FallbackGuidAge,
+ sizeof(FallbackGuidAge),
+ RsdsFakeFallback,
+ &FallbackContext) &&
+ strcmp(FallbackPdb, "fallback.pdb") == 0 &&
+ strcmp(FallbackGuidAge, "aabbccddeeff112233445566778899aa2b") == 0 &&
+ FallbackContext.CallCount == 1)
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] malformed PE bytes did not use fallback identity\n");
+ return FALSE;
+ }
+
+ FallbackContext.CallCount = 0;
+ FallbackContext.Succeed = FALSE;
+ CHAR FailedPath[MAX_PATH] = {'x'};
+ CHAR FailedPdb[MAX_PATH] = {'x'};
+ CHAR FailedGuidAge[MAX_PATH] = {'x'};
+ TestNum++;
+ if (!SymFormatPdbIdentityFromPeImageOrFallback(Buffer,
+ RsdsFixtureSize,
+ FailedPath,
+ sizeof(FailedPath),
+ FailedPdb,
+ sizeof(FailedPdb),
+ FailedGuidAge,
+ sizeof(FailedGuidAge),
+ RsdsFakeFallback,
+ &FallbackContext) &&
+ FailedPath[0] == '\0' && FailedPdb[0] == '\0' && FailedGuidAge[0] == '\0' && FallbackContext.CallCount == 1)
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] fallback failure reported success or left success-looking output\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/hyperdbg/hyperdbg-test/code/tests/test-parser.cpp b/hyperdbg/hyperdbg-test/code/tests/test-parser.cpp
index 9ae94075..355bfd45 100644
--- a/hyperdbg/hyperdbg-test/code/tests/test-parser.cpp
+++ b/hyperdbg/hyperdbg-test/code/tests/test-parser.cpp
@@ -1,7 +1,7 @@
/**
* @file test-parser.cpp
* @author Sina Karvandi (sina@hyperdbg.org)
- * @brief Perfrom test on command parser
+ * @brief Perform test on command parser
* @details
* @version 0.11
* @date 2024-08-11
@@ -11,132 +11,132 @@
*/
#include "pch.h"
-typedef char ** CHAR_PTR_PTR; // Define CHAR_PTR_PTR as a char**
+typedef CHAR ** CHAR_PTR_PTR; // Define CHAR_PTR_PTR as CHAR**
/**
* @brief Create an array of strings from a vector of strings
- * @param testCases The vector of strings to copy
+ * @param TestCases The vector of strings to copy
*
* @return A pointer to the array of strings
*/
CHAR_PTR_PTR
-createTestCaseArray(const std::vector & testCases)
+CreateTestCaseArray(const std::vector & TestCases)
{
//
// Allocate memory for the array of pointers (size: number of test cases)
//
- CHAR_PTR_PTR testCaseArray = (CHAR_PTR_PTR)malloc(testCases.size() * sizeof(UINT64));
+ CHAR_PTR_PTR TestCaseArray = (CHAR_PTR_PTR)malloc(TestCases.size() * sizeof(UINT64));
//
// Allocate memory for each string and copy the content
//
- for (size_t i = 0; i < testCases.size(); ++i)
+ for (SIZE_T i = 0; i < TestCases.size(); ++i)
{
- testCaseArray[i] = (char *)malloc(testCases[i].length() + 1); // +1 for the null terminator
+ TestCaseArray[i] = (CHAR *)malloc(TestCases[i].length() + 1); // +1 for the null terminator
- if (testCaseArray[i] == NULL)
+ if (TestCaseArray[i] == NULL)
{
return NULL;
}
- std::strcpy(testCaseArray[i], testCases[i].c_str());
+ std::strcpy(TestCaseArray[i], TestCases[i].c_str());
}
- return testCaseArray;
+ return TestCaseArray;
}
/**
* @brief Free the memory allocated for the test case array
- * @param testCaseArray The array of pointers to free
- * @param size The size of the array
+ * @param TestCaseArray The array of pointers to free
+ * @param Size The size of the array
*
* @return VOID
*/
VOID
-freeTestCaseArray(CHAR_PTR_PTR testCaseArray, size_t size)
+FreeTestCaseArray(CHAR_PTR_PTR TestCaseArray, SIZE_T Size)
{
//
// Free each string
//
- for (size_t i = 0; i < size; ++i)
+ for (SIZE_T i = 0; i < Size; ++i)
{
- free(testCaseArray[i]);
+ free(TestCaseArray[i]);
}
//
// Free the array of pointers
//
- free(testCaseArray);
+ free(TestCaseArray);
}
/**
* @brief Parse the test cases from the file
- * @param filename The name of the file to parse
+ * @param Filename The name of the file to parse
*
* @return A vector of pairs, where each pair contains a command and a vector of tokens
*/
std::vector>>
-parseTestCases(const std::string & filename)
+ParseTestCases(const std::string & Filename)
{
- std::ifstream file(filename);
- std::string line;
- std::string command;
- std::string currentToken;
- std::vector tokens;
- std::vector>> testCases;
- bool isCommand = false;
- bool addNewline = false;
+ std::ifstream file(Filename);
+ std::string Line;
+ std::string Command;
+ std::string CurrentToken;
+ std::vector Tokens;
+ std::vector>> TestCases;
+ BOOLEAN IsCommand = FALSE;
+ BOOLEAN AddNewline = FALSE;
- const std::string tokenDelimiter = "----------------------------------";
- const std::string commandDelimiter = "_____________________________________________________________";
+ const std::string TokenDelimiter = "----------------------------------";
+ const std::string CommandDelimiter = "_____________________________________________________________";
- while (std::getline(file, line))
+ while (std::getline(file, Line))
{
- if (line == commandDelimiter)
+ if (Line == CommandDelimiter)
{
//
// No new line is needed after this token
//
- addNewline = false;
+ AddNewline = FALSE;
//
// Save the previous command and its tokens if any
//
- if (!command.empty())
+ if (!Command.empty())
{
- if (!currentToken.empty())
+ if (!CurrentToken.empty())
{
- tokens.push_back(currentToken);
- currentToken.clear();
+ Tokens.push_back(CurrentToken);
+ CurrentToken.clear();
}
- testCases.push_back({command, tokens});
- command.clear();
- tokens.clear();
+ TestCases.push_back({Command, Tokens});
+ Command.clear();
+ Tokens.clear();
}
//
// is command is true since a command is started
//
- isCommand = true;
+ IsCommand = TRUE;
}
- else if (line == tokenDelimiter)
+ else if (Line == TokenDelimiter)
{
//
// No new line is needed after this token
//
- addNewline = false;
+ AddNewline = FALSE;
//
// not in command anymore
//
- isCommand = false;
+ IsCommand = FALSE;
//
// If we're in the middle of collecting a token, save it
//
- if (!currentToken.empty())
+ if (!CurrentToken.empty())
{
- tokens.push_back(currentToken);
- currentToken.clear();
+ Tokens.push_back(CurrentToken);
+ CurrentToken.clear();
}
}
else
@@ -144,110 +144,110 @@ parseTestCases(const std::string & filename)
//
// Accumulate lines for the command or token
//
- if (isCommand)
+ if (IsCommand)
{
- if (addNewline)
- command += "\n";
- command += line;
+ if (AddNewline)
+ Command += "\n";
+ Command += Line;
}
else
{
- if (addNewline)
- currentToken += "\n";
- currentToken += line;
+ if (AddNewline)
+ CurrentToken += "\n";
+ CurrentToken += Line;
}
- addNewline = true;
+ AddNewline = TRUE;
}
}
//
// Store the last command and tokens if any
//
- if (!command.empty())
+ if (!Command.empty())
{
- if (!currentToken.empty())
+ if (!CurrentToken.empty())
{
- tokens.push_back(currentToken);
+ Tokens.push_back(CurrentToken);
}
- testCases.push_back({command, tokens});
+ TestCases.push_back({Command, Tokens});
}
- return testCases;
+ return TestCases;
}
/**
* @brief Count the number of occurrences of the substring "\\n" up to a specified position
- * @param str The string to search
- * @param limit The position to search up to
+ * @param Str The string to search
+ * @param Limit The position to search up to
*
- * @return The number of occurrences of the substring "\\n"
+ * @return INT32 The number of occurrences of the substring "\\n"
*/
-int
-countBackslashNUpToPosition(const std::string & str, std::size_t limit)
+INT32
+CountBackslashNUpToPosition(const std::string & Str, std::size_t Limit)
{
- int count = 0;
- std::string::size_type pos = 0;
- std::string target = "\\n";
+ INT32 Count = 0;
+ std::string::size_type Pos = 0;
+ std::string Target = "\\n";
//
// Limit the string to search within the specified range
//
- while ((pos = str.find(target, pos)) != std::string::npos && pos < limit)
+ while ((Pos = Str.find(Target, Pos)) != std::string::npos && Pos < Limit)
{
- ++count;
- pos += target.length(); // Move past the current occurrence
+ ++Count;
+ Pos += Target.length(); // Move past the current occurrence
}
- return count;
+ return Count;
}
/**
* @brief Show parsed command and tokens
- * @param testCases A vector of pairs, where each pair contains a command and a vector of tokens
- * @param failedTokenNum The number of the failed token
- * @param failedTokenPosition The position of the failed token
+ * @param TestCase A pair containing a command and a vector of tokens
+ * @param FailedTokenNum The number of the failed token
+ * @param FailedTokenPosition The position of the failed token
*
* @return VOID
*/
VOID
ShowParsedCommandAndTokens(const std::pair> & testCase,
- UINT32 failedTokenNum,
- UINT32 failedTokenPosition)
+ std::vector> & TestCase,
+ UINT32 FailedTokenNum,
+ UINT32 FailedTokenPosition)
{
- UINT32 tokenNum = 0;
+ UINT32 TokenNum = 0;
//
// Output the parsed test case
//
- string showingCommand = testCase.first;
+ string ShowingCommand = TestCase.first;
- std::string::size_type pos = 0;
- while ((pos = showingCommand.find("\n", pos)) != std::string::npos)
+ std::string::size_type Pos = 0;
+ while ((Pos = ShowingCommand.find("\n", Pos)) != std::string::npos)
{
- showingCommand.replace(pos, 1, "\\n");
- pos += 2; // Move past the newly added characters
+ ShowingCommand.replace(Pos, 1, "\\n");
+ Pos += 2; // Move past the newly added characters
}
- std::cout << "Command: \"" << showingCommand << "\"" << std::endl;
+ std::cout << "Command: \"" << ShowingCommand << "\"" << std::endl;
std::cout << "____________________________________\n";
std::cout << "Expected Tokens: " << std::endl;
- for (const auto & token : testCase.second)
+ for (const auto & Token : TestCase.second)
{
- string showingToken = token;
+ string ShowingToken = Token;
- pos = 0;
- while ((pos = showingToken.find("\n", pos)) != std::string::npos)
+ Pos = 0;
+ while ((Pos = ShowingToken.find("\n", Pos)) != std::string::npos)
{
- showingToken.replace(pos, 1, "\\n");
- pos += 2; // Move past the newly added characters
+ ShowingToken.replace(Pos, 1, "\\n");
+ Pos += 2; // Move past the newly added characters
}
- if (tokenNum == failedTokenNum)
+ if (TokenNum == FailedTokenNum)
{
std::cout << " x ";
}
@@ -256,23 +256,23 @@ ShowParsedCommandAndTokens(const std::pair> 8) & 0xff);
+}
+
+/**
+ * @brief Writes a little-endian 32-bit value into a byte buffer at the given offset
+ *
+ * @param Buffer Pointer to the destination byte buffer
+ * @param Offset Byte offset within Buffer at which to write
+ * @param Value 32-bit value to write in little-endian order
+ */
+static VOID
+WriteDword(BYTE * Buffer, SIZE_T Offset, DWORD Value)
+{
+ Buffer[Offset] = (BYTE)(Value & 0xff);
+ Buffer[Offset + 1] = (BYTE)((Value >> 8) & 0xff);
+ Buffer[Offset + 2] = (BYTE)((Value >> 16) & 0xff);
+ Buffer[Offset + 3] = (BYTE)((Value >> 24) & 0xff);
+}
+
+/**
+ * @brief Builds a minimal valid 64-bit PE (PE32+) fixture in the supplied buffer
+ *
+ * Zeroes the buffer, then writes a valid IMAGE_DOS_HEADER pointing to PeHeaderOffset,
+ * an NT signature, an IMAGE_FILE_HEADER with machine type AMD64 and one section,
+ * and an IMAGE_OPTIONAL_HEADER64 magic value. The result is the smallest byte
+ * sequence accepted by PeImageReaderInitialize as a 64-bit PE image.
+ *
+ * @param Buffer Pointer to a buffer of at least PeFixtureSize bytes
+ */
+static VOID
+BuildMinimalPe64(BYTE * Buffer)
+{
+ ZeroMemory(Buffer, PeFixtureSize);
+
+ WriteWord(Buffer, 0, IMAGE_DOS_SIGNATURE);
+ WriteDword(Buffer, offsetof(IMAGE_DOS_HEADER, e_lfanew), PeHeaderOffset);
+
+ WriteDword(Buffer, PeHeaderOffset, IMAGE_NT_SIGNATURE);
+ WriteWord(Buffer, PeHeaderOffset + sizeof(DWORD) + offsetof(IMAGE_FILE_HEADER, Machine), IMAGE_FILE_MACHINE_AMD64);
+ WriteWord(Buffer, PeHeaderOffset + sizeof(DWORD) + offsetof(IMAGE_FILE_HEADER, NumberOfSections), 1);
+ WriteWord(Buffer,
+ PeHeaderOffset + sizeof(DWORD) + offsetof(IMAGE_FILE_HEADER, SizeOfOptionalHeader),
+ sizeof(IMAGE_OPTIONAL_HEADER64));
+ WriteWord(Buffer,
+ PeHeaderOffset + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER),
+ IMAGE_NT_OPTIONAL_HDR64_MAGIC);
+}
+
+/**
+ * @brief Builds a minimal valid 32-bit PE (PE32) fixture in the supplied buffer
+ *
+ * Zeroes the buffer, then writes a valid IMAGE_DOS_HEADER pointing to PeHeaderOffset,
+ * an NT signature, an IMAGE_FILE_HEADER with machine type I386 and one section,
+ * and an IMAGE_OPTIONAL_HEADER32 magic value. The result is the smallest byte
+ * sequence accepted by PeImageReaderInitialize as a 32-bit PE image.
+ *
+ * @param Buffer Pointer to a buffer of at least PeFixtureSize bytes
+ */
+static VOID
+BuildMinimalPe32(BYTE * Buffer)
+{
+ ZeroMemory(Buffer, PeFixtureSize);
+
+ WriteWord(Buffer, 0, IMAGE_DOS_SIGNATURE);
+ WriteDword(Buffer, offsetof(IMAGE_DOS_HEADER, e_lfanew), PeHeaderOffset);
+
+ WriteDword(Buffer, PeHeaderOffset, IMAGE_NT_SIGNATURE);
+ WriteWord(Buffer, PeHeaderOffset + sizeof(DWORD) + offsetof(IMAGE_FILE_HEADER, Machine), IMAGE_FILE_MACHINE_I386);
+ WriteWord(Buffer, PeHeaderOffset + sizeof(DWORD) + offsetof(IMAGE_FILE_HEADER, NumberOfSections), 1);
+ WriteWord(Buffer,
+ PeHeaderOffset + sizeof(DWORD) + offsetof(IMAGE_FILE_HEADER, SizeOfOptionalHeader),
+ sizeof(IMAGE_OPTIONAL_HEADER32));
+ WriteWord(Buffer,
+ PeHeaderOffset + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER),
+ IMAGE_NT_OPTIONAL_HDR32_MAGIC);
+}
+
+/**
+ * @brief Sets the SizeOfHeaders field in the PE64 optional header of a fixture buffer
+ *
+ * Computes the field offset within IMAGE_OPTIONAL_HEADER64 and writes a 32-bit
+ * little-endian value at that position.
+ *
+ * @param Buffer Pointer to a fixture buffer previously initialised by BuildMinimalPe64
+ * @param SizeOfHeaders Value to write into the SizeOfHeaders field
+ */
+static VOID
+SetPe64OptionalHeaderSizeOfHeaders(BYTE * Buffer, DWORD SizeOfHeaders)
+{
+ SIZE_T Offset = PeOptionalHeaderOffset() + offsetof(IMAGE_OPTIONAL_HEADER64, SizeOfHeaders);
+
+ WriteDword(Buffer, Offset, SizeOfHeaders);
+}
+
+/**
+ * @brief Returns a pointer to the first section header in a fixture buffer
+ *
+ * Computes the section header table offset using OptionalHeaderSize and casts
+ * the corresponding location in Buffer to IMAGE_SECTION_HEADER *.
+ *
+ * @param Buffer Pointer to a fixture buffer
+ * @param OptionalHeaderSize Size in bytes of the optional header used by the fixture
+ *
+ * @return IMAGE_SECTION_HEADER* Pointer to the first section header within the buffer
+ */
+static IMAGE_SECTION_HEADER *
+GetFixtureSectionHeader(BYTE * Buffer, SIZE_T OptionalHeaderSize)
+{
+ return (IMAGE_SECTION_HEADER *)(Buffer + PeSectionHeaderOffset(OptionalHeaderSize));
+}
+
+/**
+ * @brief Configures the .text section header in a fixture buffer
+ *
+ * Zeroes the first section header slot, writes the name ".text", and sets
+ * the virtual address, virtual size, raw data pointer, and raw data size
+ * fields to the supplied values.
+ *
+ * @param Buffer Pointer to a fixture buffer
+ * @param OptionalHeaderSize Size in bytes of the optional header used by the fixture
+ * @param VirtualAddress RVA at which the section is loaded
+ * @param VirtualSize Virtual size of the section
+ * @param PointerToRawData Raw file offset of the section data
+ * @param SizeOfRawData Size of the raw data on disk
+ */
+static VOID
+ConfigureTextSection(BYTE * Buffer, SIZE_T OptionalHeaderSize, DWORD VirtualAddress, DWORD VirtualSize, DWORD PointerToRawData, DWORD SizeOfRawData)
+{
+ IMAGE_SECTION_HEADER * SectionHeader = GetFixtureSectionHeader(Buffer, OptionalHeaderSize);
+
+ ZeroMemory(SectionHeader, sizeof(*SectionHeader));
+ CopyMemory(SectionHeader->Name, ".text", sizeof(".text") - 1);
+ SectionHeader->Misc.VirtualSize = VirtualSize;
+ SectionHeader->VirtualAddress = VirtualAddress;
+ SectionHeader->SizeOfRawData = SizeOfRawData;
+ SectionHeader->PointerToRawData = PointerToRawData;
+}
+
+/**
+ * @brief Runs all PE parser unit tests and reports pass/fail results
+ *
+ * Each numbered test case exercises a distinct behaviour of the PE image reader:
+ * 1. A valid PE32+ image initialises successfully and reports 64-bit.
+ * 2. A valid PE32 image initialises successfully and reports 32-bit.
+ * 3. A corrupt DOS magic causes initialisation to fail.
+ * 4. An optional header that is one byte too small causes initialisation to fail.
+ * 5. An e_lfanew value that points past the buffer causes initialisation to fail.
+ * 6. A valid section RVA maps to the correct raw file offset.
+ * 7. Header-range RVA resolution is enforced at SizeOfHeaders boundaries.
+ * 8. An 8-byte section name is always returned null-terminated.
+ * 9. An RVA whose raw mapping extends outside the file is rejected.
+ *
+ * @return BOOLEAN TRUE if all tests pass, FALSE if any test fails
+ */
+BOOLEAN
+TestPeParser()
+{
+ BOOLEAN OverallResult = TRUE;
+ INT32 TestNum = 0;
+ BYTE Buffer[PeFixtureSize] = {0};
+
+ BuildMinimalPe64(Buffer);
+ TestNum++;
+ {
+ PE_IMAGE_READER Reader = {0};
+
+ if (PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader) && !PeImageReaderIs32Bit(&Reader))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] valid PE64 did not initialize as PE32+\n");
+ return FALSE;
+ }
+ }
+
+ BuildMinimalPe32(Buffer);
+ TestNum++;
+ {
+ PE_IMAGE_READER Reader = {0};
+
+ if (PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader) && PeImageReaderIs32Bit(&Reader))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] valid PE32 did not initialize as PE32\n");
+ return FALSE;
+ }
+ }
+
+ BuildMinimalPe64(Buffer);
+ WriteWord(Buffer, 0, 0);
+ TestNum++;
+ {
+ PE_IMAGE_READER Reader = {0};
+
+ if (!PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] invalid DOS magic initialized successfully\n");
+ return FALSE;
+ }
+ }
+
+ BuildMinimalPe64(Buffer);
+ WriteWord(Buffer,
+ PeHeaderOffset + sizeof(DWORD) + offsetof(IMAGE_FILE_HEADER, SizeOfOptionalHeader),
+ sizeof(IMAGE_OPTIONAL_HEADER64) - 1);
+ TestNum++;
+ {
+ PE_IMAGE_READER Reader = {0};
+
+ if (!PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] truncated optional header initialized successfully\n");
+ return FALSE;
+ }
+ }
+
+ BuildMinimalPe64(Buffer);
+ WriteDword(Buffer, offsetof(IMAGE_DOS_HEADER, e_lfanew), PeFixtureSize);
+ TestNum++;
+ {
+ PE_IMAGE_READER Reader = {0};
+
+ if (!PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] invalid e_lfanew initialized successfully\n");
+ return FALSE;
+ }
+ }
+
+ BuildMinimalPe64(Buffer);
+ SetPe64OptionalHeaderSizeOfHeaders(Buffer, 0x1c0);
+ ConfigureTextSection(Buffer, sizeof(IMAGE_OPTIONAL_HEADER64), 0x1000, 0x50, 0x1c0, 0x40);
+ TestNum++;
+ {
+ PE_IMAGE_READER Reader = {0};
+ SIZE_T FileOffset = 0;
+
+ if (PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader) &&
+ PeImageReaderRvaToFileOffset(&Reader, 0x1010, 4, &FileOffset) && FileOffset == 0x1d0)
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] valid section RVA did not map to raw file offset\n");
+ return FALSE;
+ }
+ }
+
+ BuildMinimalPe64(Buffer);
+ SetPe64OptionalHeaderSizeOfHeaders(Buffer, 0x1c0);
+ TestNum++;
+ {
+ PE_IMAGE_READER Reader = {0};
+ SIZE_T FileOffset = 0;
+
+ if (PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader) &&
+ PeImageReaderRvaToFileOffset(&Reader, 0x20, 4, &FileOffset) && FileOffset == 0x20 &&
+ !PeImageReaderRvaToFileOffset(&Reader, 0x1be, 4, &FileOffset))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] header RVA bounds were not enforced\n");
+ return FALSE;
+ }
+ }
+
+ TestNum++;
+ {
+ IMAGE_SECTION_HEADER SectionHeader = {0};
+ CHAR Name[9];
+
+ FillMemory(Name, sizeof(Name), 'X');
+ CopyMemory(SectionHeader.Name, "ABCDEFGH", IMAGE_SIZEOF_SHORT_NAME);
+ if (PeImageReaderGetSectionName(&SectionHeader, Name, sizeof(Name)) &&
+ strcmp(Name, "ABCDEFGH") == 0 && Name[IMAGE_SIZEOF_SHORT_NAME] == '\0')
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] 8-byte section name was not null-terminated\n");
+ return FALSE;
+ }
+ }
+
+ BuildMinimalPe64(Buffer);
+ SetPe64OptionalHeaderSizeOfHeaders(Buffer, 0x1c0);
+ ConfigureTextSection(Buffer, sizeof(IMAGE_OPTIONAL_HEADER64), 0x1000, 0x40, 0x300, 0x20);
+ TestNum++;
+ {
+ PE_IMAGE_READER Reader = {0};
+ SIZE_T FileOffset = 0;
+
+ if (PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader) &&
+ !PeImageReaderRvaToFileOffset(&Reader, 0x1000, 1, &FileOffset))
+ {
+ printf("[+] Test number %d Passed\n", TestNum);
+ }
+ else
+ {
+ printf("[-] Test number %d Failed\n", TestNum);
+ printf("[x] RVA mapping accepted raw pointer outside file\n");
+ OverallResult = FALSE;
+ }
+ }
+
+ return OverallResult;
+}
diff --git a/hyperdbg/hyperdbg-test/code/tests/test-semantic-scripts.cpp b/hyperdbg/hyperdbg-test/code/tests/test-semantic-scripts.cpp
index 94d34f5e..9fa7695a 100644
--- a/hyperdbg/hyperdbg-test/code/tests/test-semantic-scripts.cpp
+++ b/hyperdbg/hyperdbg-test/code/tests/test-semantic-scripts.cpp
@@ -1,7 +1,7 @@
/**
- * @file test-semanitc-scripts.cpp
+ * @file test-semantic-scripts.cpp
* @author Sina Karvandi (sina@hyperdbg.org)
- * @brief Perfrom test on semantic scripts
+ * @brief Perform test on semantic scripts
* @details
* @version 0.11
* @date 2024-08-16
@@ -21,7 +21,7 @@ namespace fs = std::filesystem;
* @return VOID
*/
VOID
-ReadDirectoryAndTestSemanticTestcases(const char * ScriptSemanticPath)
+ReadDirectoryAndTestSemanticTestCases(const CHAR * ScriptSemanticPath)
{
//
// Iterate through the directory
@@ -38,7 +38,7 @@ ReadDirectoryAndTestSemanticTestcases(const char * ScriptSemanticPath)
//
// Get the file path
//
- std::string filePath = entry.path().string();
+ std::string FilePath = entry.path().string();
//
// Output the file name
@@ -48,10 +48,10 @@ ReadDirectoryAndTestSemanticTestcases(const char * ScriptSemanticPath)
//
// Open the file and read its contents
//
- std::ifstream file(filePath);
- if (file.is_open())
+ std::ifstream File(FilePath);
+ if (File.is_open())
{
- std::string content((std::istreambuf_iterator(file)),
+ std::string Content((std::istreambuf_iterator(File)),
std::istreambuf_iterator());
//
@@ -64,18 +64,18 @@ ReadDirectoryAndTestSemanticTestcases(const char * ScriptSemanticPath)
//
// Run the test case command
//
- hyperdbg_u_run_command((CHAR *)content.c_str());
+ hyperdbg_u_run_command((CHAR *)Content.c_str());
std::cout << "--------------------------------------------" << std::endl;
//
// Close the file
//
- file.close();
+ File.close();
}
else
{
- std::cerr << "Could not open file: " << filePath << std::endl;
+ std::cerr << "Could not open file: " << FilePath << std::endl;
}
}
}
@@ -94,8 +94,8 @@ ReadDirectoryAndTestSemanticTestcases(const char * ScriptSemanticPath)
BOOLEAN
TestSemanticScripts()
{
- int testNum = 0;
- CHAR dirPath[MAX_PATH] = {0};
+ INT32 TestNum = 0;
+ CHAR dirPath[MAX_PATH] = {0};
//
// Parse the semantic script test cases from the file
@@ -122,7 +122,7 @@ TestSemanticScripts()
//
// Run test cases
//
- ReadDirectoryAndTestSemanticTestcases(dirPath);
+ ReadDirectoryAndTestSemanticTestCases(dirPath);
//
// Close the connection
diff --git a/hyperdbg/hyperdbg-test/code/tools.cpp b/hyperdbg/hyperdbg-test/code/tools.cpp
index 125b1e44..4a69f73c 100644
--- a/hyperdbg/hyperdbg-test/code/tools.cpp
+++ b/hyperdbg/hyperdbg-test/code/tools.cpp
@@ -11,28 +11,48 @@
*/
#include "pch.h"
+/**
+ * @brief Convert a UINT64 value to a hex string
+ *
+ * @param Value the value to convert
+ * @return std::string the hex string representation
+ */
std::string
-Uint64ToString(UINT64 value)
+Uint64ToString(UINT64 Value)
{
ostringstream Os;
- Os << setw(16) << setfill('0') << hex << value;
+ Os << setw(16) << setfill('0') << hex << Value;
return Os.str();
}
+/**
+ * @brief Replace the first occurrence of a substring in a string
+ *
+ * @param Str the string to modify
+ * @param From the substring to search for
+ * @param To the replacement substring
+ * @return BOOLEAN TRUE if the replacement was made, FALSE otherwise
+ */
BOOLEAN
-StringReplace(std::string & str, const std::string & from, const std::string & to)
+StringReplace(std::string & Str, const std::string & From, const std::string & To)
{
- size_t start_pos = str.find(from);
- if (start_pos == string::npos)
+ SIZE_T StartPos = Str.find(From);
+ if (StartPos == string::npos)
return FALSE;
- str.replace(start_pos, from.length(), to);
+ Str.replace(StartPos, From.length(), To);
return TRUE;
}
+/**
+ * @brief Convert a C-string to a std::string
+ *
+ * @param Str the C-string to convert
+ * @return std::string the resulting string object
+ */
std::string
-ConvertToString(char * Str)
+ConvertToString(CHAR * Str)
{
- string s(Str);
+ string Result(Str);
- return s;
+ return Result;
}
diff --git a/hyperdbg/hyperdbg-test/header/namedpipe.h b/hyperdbg/hyperdbg-test/header/namedpipe.h
index 8541560a..adc69468 100644
--- a/hyperdbg/hyperdbg-test/header/namedpipe.h
+++ b/hyperdbg/hyperdbg-test/header/namedpipe.h
@@ -19,15 +19,15 @@ HANDLE
NamedPipeServerCreatePipe(LPCSTR PipeName, UINT32 OutputBufferSize, UINT32 InputBufferSize);
BOOLEAN
-NamedPipeServerWaitForClientConntection(HANDLE PipeHandle);
+NamedPipeServerWaitForClientConnection(HANDLE PipeHandle);
UINT32
-NamedPipeServerReadClientMessage(HANDLE PipeHandle, char * BufferToSave, int MaximumReadBufferLength);
+NamedPipeServerReadClientMessage(HANDLE PipeHandle, CHAR * BufferToSave, INT32 MaximumReadBufferLength);
BOOLEAN
NamedPipeServerSendMessageToClient(HANDLE PipeHandle,
- char * BufferToSend,
- int BufferSize);
+ CHAR * BufferToSend,
+ INT32 BufferSize);
VOID
NamedPipeServerCloseHandle(HANDLE PipeHandle);
@@ -40,10 +40,10 @@ HANDLE
NamedPipeClientCreatePipe(LPCSTR PipeName);
BOOLEAN
-NamedPipeClientSendMessage(HANDLE PipeHandle, char * BufferToSend, int BufferSize);
+NamedPipeClientSendMessage(HANDLE PipeHandle, CHAR * BufferToSend, INT32 BufferSize);
UINT32
-NamedPipeClientReadMessage(HANDLE PipeHandle, char * BufferToRead, int MaximumSizeOfBuffer);
+NamedPipeClientReadMessage(HANDLE PipeHandle, CHAR * BufferToRead, INT32 MaximumSizeOfBuffer);
VOID
NamedPipeClientClosePipe(HANDLE PipeHandle);
diff --git a/hyperdbg/hyperdbg-test/header/routines.h b/hyperdbg/hyperdbg-test/header/routines.h
index 44c47cdf..ed7abc8c 100644
--- a/hyperdbg/hyperdbg-test/header/routines.h
+++ b/hyperdbg/hyperdbg-test/header/routines.h
@@ -22,7 +22,7 @@ TestCase(std::vector & TestCase);
//////////////////////////////////////////////////
extern "C" {
-extern void inline AsmTest();
+extern VOID inline AsmTest();
}
//////////////////////////////////////////////////
@@ -37,10 +37,10 @@ TestCreateLookupTable(HANDLE PipeHandle, PVOID KernelInformation, UINT32 KernelI
//////////////////////////////////////////////////
std::string
-Uint64ToString(UINT64 value);
+Uint64ToString(UINT64 Value);
BOOLEAN
-StringReplace(std::string & str, const std::string & from, const std::string & to);
+StringReplace(std::string & Str, const std::string & From, const std::string & To);
std::string
-ConvertToString(char * Str);
+ConvertToString(CHAR * Str);
diff --git a/hyperdbg/hyperdbg-test/header/testcases.h b/hyperdbg/hyperdbg-test/header/testcases.h
index f3cda4e7..79ff93fa 100644
--- a/hyperdbg/hyperdbg-test/header/testcases.h
+++ b/hyperdbg/hyperdbg-test/header/testcases.h
@@ -18,5 +18,11 @@
BOOLEAN
TestCommandParser();
+BOOLEAN
+TestPeParser();
+
+BOOLEAN
+TestCodeViewRsdsParser();
+
BOOLEAN
TestSemanticScripts();
diff --git a/hyperdbg/hyperdbg-test/hyperdbg-test.vcxproj b/hyperdbg/hyperdbg-test/hyperdbg-test.vcxproj
index f4b2dbd8..b50f7554 100644
--- a/hyperdbg/hyperdbg-test/hyperdbg-test.vcxproj
+++ b/hyperdbg/hyperdbg-test/hyperdbg-test.vcxproj
@@ -21,14 +21,14 @@
Applicationtrue
- v143
+ v145UnicodefalseApplicationfalse
- v143
+ v145trueUnicodefalse
@@ -63,8 +63,8 @@
true_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)true
- $(SolutionDir)\include;$(SolutionDir)dependencies;$(ProjectDir);%(AdditionalIncludeDirectories)
- Use
+ $(SolutionDir)\include;$(SolutionDir)dependencies;$(ProjectDir);$(SolutionDir)libhyperdbg;$(SolutionDir)symbol-parser;%(AdditionalIncludeDirectories)
+ Createpch.hMultiThreadedDebugtrue
@@ -85,13 +85,13 @@
true_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)true
- $(SolutionDir)\include;$(SolutionDir)dependencies;$(ProjectDir);%(AdditionalIncludeDirectories)
- Use
+ $(SolutionDir)\include;$(SolutionDir)dependencies;$(ProjectDir);$(SolutionDir)libhyperdbg;$(SolutionDir)symbol-parser;%(AdditionalIncludeDirectories)
+ Createpch.hMultiThreadedtruestdcpp20
- Disabled
+ MaxSpeedConsole
@@ -103,23 +103,27 @@
+
+
+
+
+
-
- Create
- Create
-
+
-
+
+
+
diff --git a/hyperdbg/hyperdbg-test/hyperdbg-test.vcxproj.filters b/hyperdbg/hyperdbg-test/hyperdbg-test.vcxproj.filters
index 88a551d0..2840f4a7 100644
--- a/hyperdbg/hyperdbg-test/hyperdbg-test.vcxproj.filters
+++ b/hyperdbg/hyperdbg-test/hyperdbg-test.vcxproj.filters
@@ -21,14 +21,29 @@
{18515e99-bdbe-465f-9c92-58dc89591116}
+
+ {4905a2c5-31b5-4b16-9f84-d2b3b39726d3}
+
+
+ {2835e8e0-5525-473b-ae43-c498674fb42e}
+
+
+ {b36455ac-6726-4c17-903c-3c3e3de1b783}
+
+
+ {b3920039-7e86-412e-bf10-8a5a7946e102}
+
-
- code
- code\tests
+
+ code\tests
+
+
+ code\tests
+ code
@@ -44,30 +59,48 @@
code\hardware
+
+ code\tests
+
+
+ code\tests
+
+
+ code
+
+
+ code\components\pe
+
-
- header
- headerheader
-
- header\platform
- headerheader
+
+ header
+
+
+ header\components\pe
+
+
+ header
+
+
+ header
+ code\assembly
-
\ No newline at end of file
+
diff --git a/hyperdbg/hyperdbg-test/pch.h b/hyperdbg/hyperdbg-test/pch.h
index 3d4559f0..0d6f1d11 100644
--- a/hyperdbg/hyperdbg-test/pch.h
+++ b/hyperdbg/hyperdbg-test/pch.h
@@ -19,7 +19,7 @@ using namespace std;
//
// Environment headers
//
-#include "platform/user/header/Environment.h"
+#include "platform/general/header/Environment.h"
//
// General Headers
@@ -34,20 +34,32 @@ using namespace std;
#include
#include
#include
+#include
+
+//
+// SDK and config headers
+//
+#include "SDK/HyperDbgSdk.h"
+#include "config/Definition.h"
//
// Program Defined Headers
//
-#include "SDK/HyperDbgSdk.h"
-#include "config/Definition.h"
-#include "../hyperdbg-test/header/namedpipe.h"
-#include "../hyperdbg-test/header/routines.h"
-#include "../hyperdbg-test/header/testcases.h"
+#include "header/namedpipe.h"
+#include "header/routines.h"
+#include "header/testcases.h"
+#include "header/pdb-identity.h"
+#include "header/codeview-rsds.h"
+
+//
+// Components
+//
+#include "../include/components/pe/header/pe-image-reader.h"
//
// Hardware Debugger Headers
//
-#include "../hyperdbg-test/header/hwdbg-tests.h"
+#include "header/hwdbg-tests.h"
//
// import libhyperdbg
diff --git a/hyperdbg/hyperdbg.sln b/hyperdbg/hyperdbg.sln
index e124d57a..90b129a9 100644
--- a/hyperdbg/hyperdbg.sln
+++ b/hyperdbg/hyperdbg.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.2.32602.215
+# Visual Studio Version 18
+VisualStudioVersion = 18.7.11911.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperdbg-cli", "hyperdbg-cli\hyperdbg-cli.vcxproj", "{FBCBBBAD-4EAE-469E-827F-F59FE9E7375B}"
ProjectSection(ProjectDependencies) = postProject
@@ -60,7 +60,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "headers", "headers", "{D67D
include\SDK\Headers\Events.h = include\SDK\Headers\Events.h
include\SDK\Headers\HardwareDebugger.h = include\SDK\Headers\HardwareDebugger.h
include\SDK\Headers\Ioctls.h = include\SDK\Headers\Ioctls.h
+ include\SDK\headers\LbrDefinitions.h = include\SDK\headers\LbrDefinitions.h
include\SDK\headers\Pcie.h = include\SDK\headers\Pcie.h
+ include\SDK\headers\PortableExecutable.h = include\SDK\headers\PortableExecutable.h
+ include\SDK\headers\PtDefinitions.h = include\SDK\headers\PtDefinitions.h
include\SDK\Headers\RequestStructures.h = include\SDK\Headers\RequestStructures.h
include\SDK\Headers\ScriptEngineCommonDefinitions.h = include\SDK\Headers\ScriptEngineCommonDefinitions.h
include\SDK\Headers\Symbols.h = include\SDK\Headers\Symbols.h
@@ -87,6 +90,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "imports", "imports", "{B3D9
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperkd", "hyperkd\hyperkd.vcxproj", "{AFDD7028-1ED9-442E-8A3D-01CFA3AA1CAA}"
ProjectSection(ProjectDependencies) = postProject
+ {360E54B1-0B92-4BCA-8111-4BF384292621} = {360E54B1-0B92-4BCA-8111-4BF384292621}
+ {9FA45E25-DAEB-4C2D-806C-7908A180195D} = {9FA45E25-DAEB-4C2D-806C-7908A180195D}
{AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D} = {AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D}
{BB17323A-2460-4AE1-8AFE-B367400B934F} = {BB17323A-2460-4AE1-8AFE-B367400B934F}
EndProjectSection
@@ -97,6 +102,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{13E4
ProjectSection(SolutionItems) = preProject
include\SDK\modules\HyperEvade.h = include\SDK\modules\HyperEvade.h
include\SDK\Modules\HyperLog.h = include\SDK\Modules\HyperLog.h
+ include\SDK\modules\HyperPerf.h = include\SDK\modules\HyperPerf.h
+ include\SDK\modules\HyperTrace.h = include\SDK\modules\HyperTrace.h
include\SDK\Modules\VMM.h = include\SDK\Modules\VMM.h
EndProjectSection
EndProject
@@ -145,20 +152,49 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "kernel", "kernel", "{D0E5A2
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "code", "code", "{6498728B-D9B0-4CAB-A9E3-ACE5BC371010}"
ProjectSection(SolutionItems) = preProject
- include\platform\kernel\code\Mem.c = include\platform\kernel\code\Mem.c
+ include\platform\kernel\code\PlatformBroadcast.c = include\platform\kernel\code\PlatformBroadcast.c
+ include\platform\kernel\code\PlatformCpu.c = include\platform\kernel\code\PlatformCpu.c
+ include\platform\kernel\code\PlatformDbg.c = include\platform\kernel\code\PlatformDbg.c
+ include\platform\kernel\code\PlatformDpc.c = include\platform\kernel\code\PlatformDpc.c
+ include\platform\kernel\code\PlatformEvent.c = include\platform\kernel\code\PlatformEvent.c
+ include\platform\kernel\code\PlatformIntrinsics.c = include\platform\kernel\code\PlatformIntrinsics.c
+ include\platform\kernel\code\PlatformIntrinsicsVmx.c = include\platform\kernel\code\PlatformIntrinsicsVmx.c
+ include\platform\kernel\code\PlatformIo.c = include\platform\kernel\code\PlatformIo.c
+ include\platform\kernel\code\PlatformIrql.c = include\platform\kernel\code\PlatformIrql.c
+ include\platform\kernel\code\PlatformMem.c = include\platform\kernel\code\PlatformMem.c
+ include\platform\kernel\code\PlatformProcess.c = include\platform\kernel\code\PlatformProcess.c
+ include\platform\kernel\code\PlatformSpinlock.c = include\platform\kernel\code\PlatformSpinlock.c
+ include\platform\kernel\code\PlatformTime.c = include\platform\kernel\code\PlatformTime.c
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "header", "header", "{AA41FFF1-A730-433E-8D26-13DA5B653825}"
ProjectSection(SolutionItems) = preProject
- include\platform\kernel\header\Environment.h = include\platform\kernel\header\Environment.h
- include\platform\kernel\header\Mem.h = include\platform\kernel\header\Mem.h
+ include\platform\kernel\header\pch.h = include\platform\kernel\header\pch.h
+ include\platform\kernel\header\PlatformBroadcast.h = include\platform\kernel\header\PlatformBroadcast.h
+ include\platform\kernel\header\PlatformCpu.h = include\platform\kernel\header\PlatformCpu.h
+ include\platform\kernel\header\PlatformDbg.h = include\platform\kernel\header\PlatformDbg.h
+ include\platform\kernel\header\PlatformDpc.h = include\platform\kernel\header\PlatformDpc.h
+ include\platform\kernel\header\PlatformEvent.h = include\platform\kernel\header\PlatformEvent.h
+ include\platform\kernel\header\PlatformIntrinsics.h = include\platform\kernel\header\PlatformIntrinsics.h
+ include\platform\kernel\header\PlatformIntrinsicsVmx.h = include\platform\kernel\header\PlatformIntrinsicsVmx.h
+ include\platform\kernel\header\PlatformIo.h = include\platform\kernel\header\PlatformIo.h
+ include\platform\kernel\header\PlatformIrql.h = include\platform\kernel\header\PlatformIrql.h
+ include\platform\kernel\header\PlatformMem.h = include\platform\kernel\header\PlatformMem.h
+ include\platform\kernel\header\PlatformModuleInfo.h = include\platform\kernel\header\PlatformModuleInfo.h
+ include\platform\kernel\header\PlatformProcess.h = include\platform\kernel\header\PlatformProcess.h
+ include\platform\kernel\header\PlatformSpinlock.h = include\platform\kernel\header\PlatformSpinlock.h
+ include\platform\kernel\header\PlatformTime.h = include\platform\kernel\header\PlatformTime.h
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "code", "code", "{4BF590C3-1032-4DD2-BF87-BB9E5781977C}"
+ ProjectSection(SolutionItems) = preProject
+ include\platform\user\code\platform-intrinsics.c = include\platform\user\code\platform-intrinsics.c
+ EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "header", "header", "{DBE32379-8D5A-4454-A1B6-ACC407881898}"
ProjectSection(SolutionItems) = preProject
- include\platform\user\header\Environment.h = include\platform\user\header\Environment.h
+ include\platform\user\header\platform-intrinsics.h = include\platform\user\header\platform-intrinsics.h
+ include\platform\user\header\Windows.h = include\platform\user\header\Windows.h
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "user", "user", "{3C04357D-93B5-4472-94BB-8D22A1EB16DB}"
@@ -173,6 +209,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "kernel", "kernel", "{947577
include\SDK\imports\kernel\HyperDbgHyperEvade.h = include\SDK\imports\kernel\HyperDbgHyperEvade.h
include\SDK\Imports\Kernel\HyperDbgHyperLogImports.h = include\SDK\Imports\Kernel\HyperDbgHyperLogImports.h
include\SDK\Imports\Kernel\HyperDbgHyperLogIntrinsics.h = include\SDK\Imports\Kernel\HyperDbgHyperLogIntrinsics.h
+ include\SDK\imports\kernel\HyperDbgHyperPerf.h = include\SDK\imports\kernel\HyperDbgHyperPerf.h
+ include\SDK\imports\kernel\HyperDbgHyperTrace.h = include\SDK\imports\kernel\HyperDbgHyperTrace.h
include\SDK\Imports\Kernel\HyperDbgVmmImports.h = include\SDK\Imports\Kernel\HyperDbgVmmImports.h
EndProjectSection
EndProject
@@ -214,6 +252,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperdbg_app", "..\examples
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperevade", "hyperevade\hyperevade.vcxproj", "{B226530A-14B1-40AC-B82E-D9057400E7EE}"
+ ProjectSection(ProjectDependencies) = postProject
+ {AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D} = {AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D}
+ EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "hyper-v", "hyper-v", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
ProjectSection(SolutionItems) = preProject
@@ -226,6 +267,71 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "config", "config", "{035508
include\config\Definition.h = include\config\Definition.h
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hypertrace", "hypertrace\hypertrace.vcxproj", "{9FA45E25-DAEB-4C2D-806C-7908A180195D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "general", "general", "{17652C16-00A0-40D4-A227-697E595DE053}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "header", "header", "{9E1A2FAF-696A-4CA7-8C2E-F6B80107A143}"
+ ProjectSection(SolutionItems) = preProject
+ include\platform\general\header\Environment.h = include\platform\general\header\Environment.h
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "linux", "linux", "{63D4BB7A-C404-4A35-A302-20034DD8BA77}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "mock", "mock", "{770B65D6-5307-478C-A9EB-3E4A64B67225}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "code", "code", "{848FE945-4F37-4B5B-98C8-F22CA3AA7184}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "user", "user", "{D3722A82-0A54-4172-A0C1-1EA6500E9F1E}"
+ ProjectSection(SolutionItems) = preProject
+ linux\mock\user\Makefile = linux\mock\user\Makefile
+ linux\mock\user\mock.c = linux\mock\user\mock.c
+ linux\mock\user\pch.h = linux\mock\user\pch.h
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "kernel", "kernel", "{09E02C0A-6A6C-408A-8136-C787FDC58A5F}"
+ ProjectSection(SolutionItems) = preProject
+ linux\mock\kernel\Makefile = linux\mock\kernel\Makefile
+ linux\mock\kernel\mock.c = linux\mock\kernel\mock.c
+ linux\mock\kernel\pch.h = linux\mock\kernel\pch.h
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "windows-only", "windows-only", "{C95E342A-9622-4351-8177-CDA43A52E7B2}"
+ ProjectSection(SolutionItems) = preProject
+ include\platform\user\header\windows-only\windows-privilege.h = include\platform\user\header\windows-only\windows-privilege.h
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "windows-only", "windows-only", "{45ABB14F-86B9-40BE-9C0F-213653CE6A93}"
+ ProjectSection(SolutionItems) = preProject
+ include\platform\user\code\windows-only\windows-privilege.c = include\platform\user\code\windows-only\windows-privilege.c
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "callback", "callback", "{1AA10217-07BF-490B-A688-1D1D6A267D52}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "code", "code", "{78821DCF-DCFE-45B7-A9DD-3543BDF1FB9E}"
+ ProjectSection(SolutionItems) = preProject
+ include\components\callback\hyperlog\code\HyperLogCallback.c = include\components\callback\hyperlog\code\HyperLogCallback.c
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "header", "header", "{AD02B952-0D75-47FE-8FF7-18B3E081E2C1}"
+ ProjectSection(SolutionItems) = preProject
+ include\components\callback\hyperlog\header\HyperLogCallback.h = include\components\callback\hyperlog\header\HyperLogCallback.h
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "pe", "pe", "{9A0232BB-B06B-47EE-A096-E7B475956437}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "code", "code", "{824DF7C7-18B5-48DE-99D7-AD6B612D6204}"
+ ProjectSection(SolutionItems) = preProject
+ include\components\pe\code\pe-image-reader.cpp = include\components\pe\code\pe-image-reader.cpp
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "header", "header", "{CA2D9C24-F90A-48ED-8ABC-F296674EA2B7}"
+ ProjectSection(SolutionItems) = preProject
+ include\components\pe\header\pe-image-reader.h = include\components\pe\header\pe-image-reader.h
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperperf", "hyperperf\hyperperf.vcxproj", "{360E54B1-0B92-4BCA-8111-4BF384292621}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
debug|x64 = debug|x64
@@ -279,6 +385,14 @@ Global
{B226530A-14B1-40AC-B82E-D9057400E7EE}.debug|x64.Build.0 = debug|x64
{B226530A-14B1-40AC-B82E-D9057400E7EE}.release|x64.ActiveCfg = release|x64
{B226530A-14B1-40AC-B82E-D9057400E7EE}.release|x64.Build.0 = release|x64
+ {9FA45E25-DAEB-4C2D-806C-7908A180195D}.debug|x64.ActiveCfg = debug|x64
+ {9FA45E25-DAEB-4C2D-806C-7908A180195D}.debug|x64.Build.0 = debug|x64
+ {9FA45E25-DAEB-4C2D-806C-7908A180195D}.release|x64.ActiveCfg = release|x64
+ {9FA45E25-DAEB-4C2D-806C-7908A180195D}.release|x64.Build.0 = release|x64
+ {360E54B1-0B92-4BCA-8111-4BF384292621}.debug|x64.ActiveCfg = debug|x64
+ {360E54B1-0B92-4BCA-8111-4BF384292621}.debug|x64.Build.0 = debug|x64
+ {360E54B1-0B92-4BCA-8111-4BF384292621}.release|x64.ActiveCfg = release|x64
+ {360E54B1-0B92-4BCA-8111-4BF384292621}.release|x64.Build.0 = release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -315,6 +429,20 @@ Global
{991B8FA7-F75E-4D8A-A0BD-636FE68B6AF4} = {2104BCF9-035E-45AA-B744-68A5B8FEFF13}
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {1997E4B6-FE49-4358-ADF1-CDDB5739508E}
{03550856-D63F-4069-87E1-8BF2F129DBE3} = {1997E4B6-FE49-4358-ADF1-CDDB5739508E}
+ {17652C16-00A0-40D4-A227-697E595DE053} = {9A711E36-8A78-4CE6-A34D-F681AF89A919}
+ {9E1A2FAF-696A-4CA7-8C2E-F6B80107A143} = {17652C16-00A0-40D4-A227-697E595DE053}
+ {770B65D6-5307-478C-A9EB-3E4A64B67225} = {63D4BB7A-C404-4A35-A302-20034DD8BA77}
+ {848FE945-4F37-4B5B-98C8-F22CA3AA7184} = {17652C16-00A0-40D4-A227-697E595DE053}
+ {D3722A82-0A54-4172-A0C1-1EA6500E9F1E} = {770B65D6-5307-478C-A9EB-3E4A64B67225}
+ {09E02C0A-6A6C-408A-8136-C787FDC58A5F} = {770B65D6-5307-478C-A9EB-3E4A64B67225}
+ {C95E342A-9622-4351-8177-CDA43A52E7B2} = {DBE32379-8D5A-4454-A1B6-ACC407881898}
+ {45ABB14F-86B9-40BE-9C0F-213653CE6A93} = {4BF590C3-1032-4DD2-BF87-BB9E5781977C}
+ {1AA10217-07BF-490B-A688-1D1D6A267D52} = {DF15E9D4-976B-4E1D-B68F-9B67F93654BF}
+ {78821DCF-DCFE-45B7-A9DD-3543BDF1FB9E} = {1AA10217-07BF-490B-A688-1D1D6A267D52}
+ {AD02B952-0D75-47FE-8FF7-18B3E081E2C1} = {1AA10217-07BF-490B-A688-1D1D6A267D52}
+ {9A0232BB-B06B-47EE-A096-E7B475956437} = {DF15E9D4-976B-4E1D-B68F-9B67F93654BF}
+ {824DF7C7-18B5-48DE-99D7-AD6B612D6204} = {9A0232BB-B06B-47EE-A096-E7B475956437}
+ {CA2D9C24-F90A-48ED-8ABC-F296674EA2B7} = {9A0232BB-B06B-47EE-A096-E7B475956437}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {1444BEC7-11CE-4CA6-B77C-5F98AC9BFAEB}
diff --git a/hyperdbg/hyperevade/CMakeLists.txt b/hyperdbg/hyperevade/CMakeLists.txt
index 904c7992..85e1fe45 100644
--- a/hyperdbg/hyperevade/CMakeLists.txt
+++ b/hyperdbg/hyperevade/CMakeLists.txt
@@ -6,7 +6,7 @@ set(SourceFiles
"code/UnloadDll.c"
"../include/components/spinlock/header/Spinlock.h"
"../include/platform/kernel/header/Environment.h"
- "../include/platform/kernel/header/Mem.h"
+ "../include/platform/kernel/header/PlatformMem.h"
"header/Logging.h"
"header/pch.h"
"header/UnloadDll.h"
diff --git a/hyperdbg/hyperevade/code/SyscallFootprints.c b/hyperdbg/hyperevade/code/SyscallFootprints.c
index e018d82e..33273254 100644
--- a/hyperdbg/hyperevade/code/SyscallFootprints.c
+++ b/hyperdbg/hyperevade/code/SyscallFootprints.c
@@ -11,6 +11,49 @@
*/
#include "pch.h"
+#if ActivateHyperEvadeProject != TRUE
+
+/**
+ * @brief Handle The triggered hook on KiSystemCall64 system call handler
+ * when the Transparency mode is disabled
+ *
+ * @param Regs The virtual processor's state of registers
+ * @return VOID
+ */
+VOID
+TransparentHandleSystemCallHook(GUEST_REGS * Regs)
+{
+ UNREFERENCED_PARAMETER(Regs);
+}
+
+/**
+ * @brief Callback function to handle returns from the syscall
+ * when the Transparency mode is disabled
+ *
+ * @param Regs The virtual processor's state of registers
+ * @param ProcessId The process id of the thread
+ * @param ThreadId The thread id of the thread
+ * @param Context The context of the caller
+ * @param Params The (optional) parameters of the caller
+ *
+ * @return VOID
+ */
+VOID
+TransparentCallbackHandleAfterSyscall(GUEST_REGS * Regs,
+ UINT32 ProcessId,
+ UINT32 ThreadId,
+ UINT64 Context,
+ SYSCALL_CALLBACK_CONTEXT_PARAMS * Params)
+{
+ UNREFERENCED_PARAMETER(Regs);
+ UNREFERENCED_PARAMETER(ProcessId);
+ UNREFERENCED_PARAMETER(ThreadId);
+ UNREFERENCED_PARAMETER(Context);
+ UNREFERENCED_PARAMETER(Params);
+}
+
+#else // ActivateHyperEvadeProject != TRUE
+
/**
* @brief Handle The triggered hook on KiSystemCall64 system call handler
* when the Transparency mode is enabled
@@ -233,7 +276,7 @@ TransparentHandleNtQuerySystemInformationSyscall(GUEST_REGS * Regs)
*
* @details Returns an allocated tagged memory pointer which needs to be freed with PlatformMemFreePool()
*
- * @param virtPtr A pointer to a guest virutal memory address, containing a OBJECT_ATTRIBUTES structure
+ * @param virtPtr A pointer to a guest virtual memory address, containing a OBJECT_ATTRIBUTES structure
* @return PVOID Pointer to an allocated tagged memory pool, which needs to be freed with PlatformMemFreePool()
*/
PVOID
@@ -668,7 +711,7 @@ TransparentHandleNtQueryValueKeySyscall(GUEST_REGS * Regs)
&ContextParams);
//
- // Clean-up and return to guest exection
+ // Clean-up and return to guest execution
//
PlatformMemFreePool(NameBuf);
return;
@@ -783,7 +826,7 @@ TransparentHandleNtEnumerateKeySyscall(GUEST_REGS * Regs)
* it is possible to still detect that some tampering was done from the user space
*
* @param Ptr The pointer to a valid read/writable SYSTEM_MODULE_INFORMATION memory buffer
- * @param VirualAddress A pointer to a user-mode virual address
+ * @param VirtualAddress A pointer to a user-mode virtual address
* @param BufferSize Size of the user-mode buffer
*
* @return BOOLEAN
@@ -800,11 +843,11 @@ TransparentHandleModuleInformationQuery(PVOID Ptr, UINT64 VirtualAddress, UINT32
//
for (UINT16 i = 0; i < StructBuf->Count; i++)
{
- PCHAR path = (PCHAR)ModuleList[i].FullPathName;
+ PCHAR Path = (PCHAR)ModuleList[i].FullPathName;
for (UINT16 j = 0; j < (sizeof(HV_DRIVER) / sizeof(HV_DRIVER[0])); j++)
{
- if (strstr(path, HV_DRIVER[j]))
+ if (strstr(Path, HV_DRIVER[j]))
{
//
// If a module file name matches, remove the entry from the list by shifting it forward by one entry
@@ -912,9 +955,9 @@ TransparentHandleProcessInformationQuery(SYSCALL_CALLBACK_CONTEXT_PARAMS * Param
//
// Loop through the known list of identifiable hypervisor related processes
//
- for (UINT16 i = 0; i < (sizeof(HV_Processes) / sizeof(HV_Processes[0])); i++)
+ for (UINT16 i = 0; i < (sizeof(HV_PROCESSES) / sizeof(HV_PROCESSES[0])); i++)
{
- if (!_wcsnicmp(ImageName, HV_Processes[i], (CurStructBuf.ImageName.Length) / sizeof(WCHAR)))
+ if (!_wcsnicmp(ImageName, HV_PROCESSES[i], (CurStructBuf.ImageName.Length) / sizeof(WCHAR)))
{
//
// If the name matches, bypass it by increasing the previous entries .nextEntryOffset value
@@ -965,7 +1008,7 @@ TransparentHandleProcessInformationQuery(SYSCALL_CALLBACK_CONTEXT_PARAMS * Param
}
//
- // If the current entry didnt match any process names, move forward
+ // If the current entry did not match any process names, move forward
//
if (!MatchFound)
{
@@ -988,7 +1031,7 @@ TransparentHandleProcessInformationQuery(SYSCALL_CALLBACK_CONTEXT_PARAMS * Param
}
//
- // Zero out the matching entry, so that its data doesnt remain in memory
+ // Zero out the matching entry, so that its data doesn't remain in memory
//
if (MatchFound)
{
@@ -1015,7 +1058,7 @@ TransparentHandleProcessInformationQuery(SYSCALL_CALLBACK_CONTEXT_PARAMS * Param
/**
* @brief Handle the request for SystemFirmwareTableInformation
*
- * @param ptr The pointer to a valid read/writable SYSTEM_FIRMWARE_TABLE_INFORMATION memory buffer
+ * @param Ptr The pointer to a valid read/writable SYSTEM_FIRMWARE_TABLE_INFORMATION memory buffer
* @param BufMaxSize The size of the allocated user-mode buffer
* @param BufSizePtr A pointer to a ULONG field containing the size of the written data
*
@@ -1041,14 +1084,14 @@ TransparentHandleFirmwareInformationQuery(UINT64 Ptr, UINT32 BufMaxSize, UINT64
if (BufSize > BufMaxSize)
{
//
- // NOTE: might need zeroing the memory if the kernel did infact write to the pointer
+ // NOTE: might need zeroing the memory if the kernel did in fact write to the pointer
//
return 0;
}
//
- // If the buffer size is too big, we cant do any mitigations with the current implementation an it exceeds
- // the size of an EPT page, risking curruption when allocating the copy buffer space in root-mode.
+ // If the buffer size is too big, we can't do any mitigations with the current implementation and it exceeds
+ // the size of an EPT page, risking corruption when allocating the copy buffer space in root-mode.
//
if (BufMaxSize > PAGE_SIZE / 2)
{
@@ -1124,9 +1167,9 @@ TransparentHandleFirmwareInformationQuery(UINT64 Ptr, UINT32 BufMaxSize, UINT64
//
ULONG MatchedStringLen = (ULONG)strlen(HV_FIRM_NAMES[i]);
- ULONG oldLength = StructBuf->TableBufferLength;
+ ULONG OldLength = StructBuf->TableBufferLength;
- ULONG NewStringSize = oldLength - MatchedStringLen + NewSubstringSize;
+ ULONG NewStringSize = OldLength - MatchedStringLen + NewSubstringSize;
//
// Check if the buffer size allows the modification, in case of expansion
@@ -1143,7 +1186,7 @@ TransparentHandleFirmwareInformationQuery(UINT64 Ptr, UINT32 BufMaxSize, UINT64
//
// Update the required buffer size for the next call
//
- BufSize = (BufSize - oldLength) + NewStringSize;
+ BufSize = (BufSize - OldLength) + NewStringSize;
g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess(BufSizePtr, &BufSize, sizeof(ULONG));
//
@@ -1164,7 +1207,7 @@ TransparentHandleFirmwareInformationQuery(UINT64 Ptr, UINT32 BufMaxSize, UINT64
// Move the data after the matched string forward
// and replace the identified hypervisor string with the genuine one
//
- memmove((PVOID)(StringBuf + MatchOffset + NewSubstringSize), (PVOID)MatchEnd, oldLength - MatchedStringLen - MatchOffset);
+ memmove((PVOID)(StringBuf + MatchOffset + NewSubstringSize), (PVOID)MatchEnd, OldLength - MatchedStringLen - MatchOffset);
memcpy((PVOID)MatchStart, (PVOID)NewVendorString, NewSubstringSize);
StructBuf->TableBufferLength = NewStringSize;
@@ -1192,11 +1235,11 @@ TransparentHandleFirmwareInformationQuery(UINT64 Ptr, UINT32 BufMaxSize, UINT64
}
/**
- * @brief Replace occurances of a hypervisor specific strings with legitimate vendor strings in a provided buffer
+ * @brief Replace occurrences of a hypervisor specific strings with legitimate vendor strings in a provided buffer
*
* @param Params Set transparent callback params that contain:
in OptionalParam2 a pointer to a valid read/writable memory buffer that contains both, a WCHAR string and its length in bytes
- in OptionalParam3 max size in bytes of the allocatec buffer
+ in OptionalParam3 max size in bytes of the allocated buffer
in OptionalParam4 a pointer to a ULONG containing current size of the buffer
*
* @param DataOffset Offset in bytes from OptionalParam2 to the start of the WCHAR data string
@@ -1208,8 +1251,8 @@ TransparentHandleFirmwareInformationQuery(UINT64 Ptr, UINT32 BufMaxSize, UINT64
UINT64
TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS * Params, ULONG DataOffset, ULONG DataLenOffset)
{
- PVOID Buf = NULL;
- BOOL PoolAlloc = FALSE;
+ PVOID Buf = NULL;
+ BOOLEAN PoolAlloc = FALSE;
//
// Check that the user provided pointers are safe to read from
@@ -1231,7 +1274,7 @@ TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS *
if (BufSize > Params->OptionalParam3 || BufSize == 0)
{
//
- // NOTE: might need zeroing the memory if the kernel did infact write to the pointer
+ // NOTE: might need zeroing the memory if the kernel did in fact write to the pointer
//
return 0;
@@ -1291,7 +1334,7 @@ TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS *
//
// SPOOFS PCI device ID's(in the registry), This might be implemented in other ways that are not part of this implementation
//
- WORD Idx = TRANSPARENT_GENUINE_VENDOR_STRING_INDEX % (sizeof(TRANSPARENT_LEGIT_DEVICE_ID_VENDOR_STRINGS_WCHAR) / sizeof(TRANSPARENT_LEGIT_DEVICE_ID_VENDOR_STRINGS_WCHAR[0]));
+ WORD Idx = g_TransparentGenuineVendorStringIndex % (sizeof(TRANSPARENT_LEGIT_DEVICE_ID_VENDOR_STRINGS_WCHAR) / sizeof(TRANSPARENT_LEGIT_DEVICE_ID_VENDOR_STRINGS_WCHAR[0]));
NewVendorString = TRANSPARENT_LEGIT_DEVICE_ID_VENDOR_STRINGS_WCHAR[Idx];
}
@@ -1307,23 +1350,23 @@ TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS *
//
// Obtain the replacement vendor name string, randomized when the transparency mode was enabled
//
- NewVendorString = TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR[TRANSPARENT_GENUINE_VENDOR_STRING_INDEX];
+ NewVendorString = TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR[g_TransparentGenuineVendorStringIndex];
}
//
// Obtain the lengths of all the strings and substring
//
- ULONG tempSize = (ULONG)wcslen(NewVendorString) * sizeof(WCHAR);
+ ULONG TempSize = (ULONG)wcslen(NewVendorString) * sizeof(WCHAR);
ULONG MatchedStringLen = (ULONG)wcslen(HV_REGKEYS[i]) * sizeof(WCHAR);
- ULONG oldLength = *((PBYTE)Buf + DataLenOffset);
+ ULONG OldLength = *((PBYTE)Buf + DataLenOffset);
- ULONG NewStringSize = oldLength - MatchedStringLen + tempSize;
+ ULONG NewStringSize = OldLength - MatchedStringLen + TempSize;
//
// Check if the buffer size allows the modification, in case of expansion
//
- if (BufSize - MatchedStringLen + tempSize > Params->OptionalParam3)
+ if (BufSize - MatchedStringLen + TempSize > Params->OptionalParam3)
{
//
// If adding the new string exceeds the user allocated size,
@@ -1335,7 +1378,7 @@ TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS *
//
// Update the required buffer size for the next call
//
- BufSize = (tempSize - MatchedStringLen) + oldLength;
+ BufSize = (TempSize - MatchedStringLen) + OldLength;
g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess(Params->OptionalParam4, &BufSize, sizeof(ULONG));
//
@@ -1356,15 +1399,15 @@ TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS *
//
// Move the data after the matched string forward
//
- memmove((PVOID)(StringBuf + MatchOffset + (tempSize / sizeof(WCHAR))), (PVOID)MatchEnd, oldLength - MatchedStringLen - (MatchOffset * sizeof(WCHAR)));
+ memmove((PVOID)(StringBuf + MatchOffset + (TempSize / sizeof(WCHAR))), (PVOID)MatchEnd, OldLength - MatchedStringLen - (MatchOffset * sizeof(WCHAR)));
//
// Replace the identified hypervisor string with the genuine one, if needed
//
- memcpy((PVOID)MatchStart, (PVOID)NewVendorString, tempSize);
+ memcpy((PVOID)MatchStart, (PVOID)NewVendorString, TempSize);
*(PULONG)((PBYTE)Buf + DataLenOffset) = NewStringSize;
- BufSize = BufSize - MatchedStringLen + tempSize;
+ BufSize = BufSize - MatchedStringLen + TempSize;
//
// Write the changes back to the user buffers
@@ -1399,11 +1442,11 @@ TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS *
}
//
- // An error occured while performing the mitigations, the user buffer might be left unmodified
+ // An error occurred while performing the mitigations, the user buffer might be left unmodified
//
ReturnWithError:
LogInfo("A call for to read a registry entry, which could contain hypervisor specific data, was intercepted but the mitigations failed");
- LogInfo("The caller process recieved the results in this virtual address: %llx", Params->OptionalParam2);
+ LogInfo("The caller process received the results in this virtual address: %llx", Params->OptionalParam2);
if (Buf != NULL)
{
@@ -1420,7 +1463,7 @@ ReturnWithError:
* @param Params The set transparent callback params that contain:
in OptionalParam1 the KEY_VALUE_INFORMATION_CLASS enum value
in OptionalParam2 a pointer to a valid read/writable memory buffer that contains both, a WCHAR string and its length in bytes
- in OptionalParam3 max size in bytes of the allocatec buffer
+ in OptionalParam3 max size in bytes of the allocated buffer
in OptionalParam4 a pointer to a ULONG containing current size of the buffer
*
* @return UINT64
@@ -1497,12 +1540,12 @@ TransparentCallbackHandleAfterNtQueryValueKeySyscall(SYSCALL_CALLBACK_CONTEXT_PA
}
/**
- * @brief Callback function to handle the returns from the NtQueryValueKey syscall
+ * @brief Callback function to handle the returns from the NtEnumerateKey syscall
*
* @param Params The set transparent callback params that contain:
in OptionalParam1 the KEY_VALUE_INFORMATION_CLASS enum value
in OptionalParam2 a pointer to a valid read/writable memory buffer that contains both, a WCHAR string and its length in bytes
- in OptionalParam3 max size in bytes of the allocatec buffer
+ in OptionalParam3 max size in bytes of the allocated buffer
in OptionalParam4 a pointer to a ULONG containing current size of the buffer
*
* @return UINT64
@@ -1857,10 +1900,10 @@ TransparentCallbackHandleAfterSyscall(GUEST_REGS * Regs,
//
// Handle the return code modification after NtNtQueryValueKey system call
//
- // NOTE: The transparent mitigation will replace all occurances of a hypervisor vendor string in the registry
+ // NOTE: The transparent mitigation will replace all occurrences of a hypervisor vendor string in the registry
// key data to a randomized real hardware vendor string, no matter the meaning of the key,
- // This can cause some keys to illogical data, for example,
- // a disk drive ID having a vendor string of ASUS even though(as far as I know) ASUS doesnt produce storage devices.
+ // This can cause some keys to produce illogical data, for example,
+ // a disk drive ID having a vendor string of ASUS even though (as far as I know) ASUS doesn't produce storage devices.
//
else if (Context == g_SystemCallNumbersInformation.SysNtQueryValueKey)
{
@@ -1927,3 +1970,4 @@ TransparentCallbackHandleAfterSyscall(GUEST_REGS * Regs,
Params->OptionalParam4);
}
}
+#endif // ActivateHyperEvadeProject != TRUE
diff --git a/hyperdbg/hyperevade/code/Transparency.c b/hyperdbg/hyperevade/code/Transparency.c
index 1ab77304..611c085f 100644
--- a/hyperdbg/hyperevade/code/Transparency.c
+++ b/hyperdbg/hyperevade/code/Transparency.c
@@ -1,6 +1,7 @@
-/**
+/**
* @file Transparency.c
* @author Sina Karvandi (sina@hyperdbg.org)
+ * @author jtaw5649
* @brief Try to hide the debugger from anti-debugging and anti-hypervisor methods
* @details
* @version 0.1
@@ -14,8 +15,8 @@
/**
* @brief Hide debugger on transparent-mode (activate transparent-mode)
*
- * @param HyperevadeCallbacks
- * @param TransparentModeRequest
+ * @param HyperevadeCallbacks Pointer to the HyperEvade callbacks structure
+ * @param TransparentModeRequest Pointer to the transparent debugger mode request
*
* @return BOOLEAN
*/
@@ -23,6 +24,19 @@ BOOLEAN
TransparentHideDebugger(HYPEREVADE_CALLBACKS * HyperevadeCallbacks,
DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE * TransparentModeRequest)
{
+ UINT32 EvadeMask = TransparentModeRequest->EvadeMask;
+
+ if (EvadeMask == 0)
+ {
+ EvadeMask = TRANSPARENT_EVADE_MASK_DEFAULT;
+ }
+
+ if ((EvadeMask & ~TRANSPARENT_EVADE_MASK_ALL) != 0)
+ {
+ TransparentModeRequest->KernelStatus = DEBUGGER_ERROR_UNABLE_TO_HIDE_OR_UNHIDE_DEBUGGER;
+ return FALSE;
+ }
+
//
// Check if any of the required callbacks are NULL
//
@@ -54,17 +68,20 @@ TransparentHideDebugger(HYPEREVADE_CALLBACKS * Hyperevade
RtlCopyBytes(&g_SystemCallNumbersInformation,
&TransparentModeRequest->SystemCallNumbersInformation,
sizeof(SYSTEM_CALL_NUMBERS_INFORMATION));
-
+#if ActivateHyperEvadeProject == TRUE
//
// Choose a random genuine vendor string to replace hypervisor vendor data
//
- TRANSPARENT_GENUINE_VENDOR_STRING_INDEX = TransparentGetRand() %
- (sizeof(TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR) / sizeof(TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR[0]));
+ g_TransparentGenuineVendorStringIndex = TransparentGetRand() %
+ (sizeof(TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR) / sizeof(TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR[0]));
+#endif
//
// Enable the transparent mode
//
g_TransparentMode = TRUE;
+ g_TransparentEvadeMask = EvadeMask;
+ TransparentModeRequest->EvadeMask = EvadeMask;
TransparentModeRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
//
@@ -92,7 +109,8 @@ TransparentUnhideDebugger()
//
// Disable the transparent-mode
//
- g_TransparentMode = FALSE;
+ g_TransparentMode = FALSE;
+ g_TransparentEvadeMask = 0;
return TRUE;
}
@@ -114,7 +132,7 @@ TransparentGetRand()
UINT64 Tsc;
UINT32 Rand;
- Tsc = __rdtsc();
+ Tsc = CpuReadTsc();
Rand = Tsc & 0xffff;
return Rand;
@@ -124,7 +142,7 @@ TransparentGetRand()
* @brief Add name or process id of the target process to the list
* of processes that HyperDbg should apply transparent-mode on them
*
- * @param Measurements
+ * @param Measurements Pointer to the debugger hide and transparent mode request structure
* @return BOOLEAN
*/
BOOLEAN
@@ -188,8 +206,8 @@ TransparentAddNameOrProcessIdToTheList(PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_M
//
// Move the process name string to the end of the buffer
//
- RtlCopyBytes((void *)((UINT64)PidAndNameBuffer + sizeof(TRANSPARENCY_PROCESS)),
- (const void *)((UINT64)Measurements + sizeof(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE)),
+ RtlCopyBytes((VOID *)((UINT64)PidAndNameBuffer + sizeof(TRANSPARENCY_PROCESS)),
+ (CONST VOID *)((UINT64)Measurements + sizeof(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE)),
Measurements->LengthOfProcessName);
//
@@ -598,7 +616,7 @@ TransparentAddNameOrProcessIdToTheList(PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_M
// //
// // Save the current time
// //
-// CurrrentTime = __rdtscp(&Aux);
+// CurrrentTime = CpuReadTscp(&Aux);
//
// //
// // Save time of vm-exit on each logical processor separately
diff --git a/hyperdbg/hyperevade/code/UnloadDll.c b/hyperdbg/hyperevade/code/UnloadDll.c
index be8c9ba6..17321dbf 100644
--- a/hyperdbg/hyperevade/code/UnloadDll.c
+++ b/hyperdbg/hyperevade/code/UnloadDll.c
@@ -2,7 +2,7 @@
* @file UnloadDll.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Unloading DLL in the target Windows
- *
+ * @details
* @version 0.4
* @date 2023-07-06
*
@@ -18,6 +18,12 @@
// other module remains loaded in the memory.
//
+/**
+ * @brief Routine called on DLL initialization
+ *
+ * @param RegistryPath The registry path of the driver
+ * @return NTSTATUS
+ */
NTSTATUS
DllInitialize(
_In_ PUNICODE_STRING RegistryPath)
@@ -27,8 +33,13 @@ DllInitialize(
return STATUS_SUCCESS;
}
+/**
+ * @brief Routine called on DLL unload
+ *
+ * @return NTSTATUS
+ */
NTSTATUS
-DllUnload(void)
+DllUnload(VOID)
{
return STATUS_SUCCESS;
}
diff --git a/hyperdbg/hyperevade/code/VmxFootprints.c b/hyperdbg/hyperevade/code/VmxFootprints.c
index 129a20c6..1133f2f5 100644
--- a/hyperdbg/hyperevade/code/VmxFootprints.c
+++ b/hyperdbg/hyperevade/code/VmxFootprints.c
@@ -1,6 +1,7 @@
/**
* @file VmxFootprints.c
* @author Sina Karvandi (sina@hyperdbg.org)
+ * @author jtaw5649
* @brief Try to hide VMX methods from anti-debugging and anti-hypervisor
* @details
* @version 0.14
@@ -22,6 +23,11 @@
VOID
TransparentCheckAndModifyCpuid(PGUEST_REGS Regs, INT32 CpuInfo[])
{
+ if ((g_TransparentEvadeMask & TRANSPARENT_EVADE_MASK_CPUID) == 0)
+ {
+ return;
+ }
+
if (Regs->rax == CPUID_PROCESSOR_AND_PROCESSOR_FEATURE_IDENTIFIERS)
{
//
@@ -50,6 +56,14 @@ TransparentCheckAndModifyCpuid(PGUEST_REGS Regs, INT32 CpuInfo[])
BOOLEAN
TransparentCheckAndModifyMsrRead(PGUEST_REGS Regs, UINT32 TargetMsr)
{
+ if ((g_TransparentEvadeMask & TRANSPARENT_EVADE_MASK_MSR) == 0)
+ {
+ UNREFERENCED_PARAMETER(Regs);
+ UNREFERENCED_PARAMETER(TargetMsr);
+
+ return FALSE;
+ }
+
//
// The MSR range between 40000000H and 400000F0H is reserved and usually used by hypervisors
// when the guest operating system is Windows to indicate the OS identifier
@@ -92,6 +106,14 @@ TransparentCheckAndModifyMsrRead(PGUEST_REGS Regs, UINT32 TargetMsr)
BOOLEAN
TransparentCheckAndModifyMsrWrite(PGUEST_REGS Regs, UINT32 TargetMsr)
{
+ if ((g_TransparentEvadeMask & TRANSPARENT_EVADE_MASK_MSR) == 0)
+ {
+ UNREFERENCED_PARAMETER(Regs);
+ UNREFERENCED_PARAMETER(TargetMsr);
+
+ return FALSE;
+ }
+
// if (TargetMsr >= RESERVED_MSR_RANGE_LOW && TargetMsr <= RESERVED_MSR_RANGE_HI)
// {
// //
@@ -130,6 +152,11 @@ TransparentCheckAndModifyMsrWrite(PGUEST_REGS Regs, UINT32 TargetMsr)
VOID
TransparentCheckAndTrapFlagAfterVmexit()
{
+ if ((g_TransparentEvadeMask & TRANSPARENT_EVADE_MASK_TRAP_FLAG) == 0)
+ {
+ return;
+ }
+
//
// If RIP is incremented, then we emulate an instruction, and then
// we need to handle the trap flag if it is set in a guest
diff --git a/hyperdbg/hyperevade/header/SyscallFootprints.h b/hyperdbg/hyperevade/header/SyscallFootprints.h
index 976001fd..02e3d6a3 100644
--- a/hyperdbg/hyperevade/header/SyscallFootprints.h
+++ b/hyperdbg/hyperevade/header/SyscallFootprints.h
@@ -81,17 +81,17 @@ typedef struct _SYSTEM_PROCESS_INFORMATION
* @brief SSDT structure
*
*/
-typedef struct _SSDTStruct
+typedef struct _SSDT_STRUCT
{
- LONG * pServiceTable;
- PVOID pCounterTable;
+ LONG * ServiceTable;
+ PVOID CounterTable;
#ifdef _WIN64
UINT64 NumberOfServices;
#else
ULONG NumberOfServices;
#endif
- PCHAR pArgumentTable;
-} SSDTStruct, *PSSDTStruct;
+ PCHAR ArgumentTable;
+} SSDT_STRUCT, *PSSDT_STRUCT;
/**
* @brief Module entry
@@ -128,7 +128,7 @@ typedef NTSTATUS(NTAPI * ZWQUERYSYSTEMINFORMATION)(
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL);
-NTSTATUS(*NtCreateFileOrig)
+NTSTATUS(*g_NtCreateFileOrig)
(
PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
@@ -150,7 +150,7 @@ NTSTATUS(*NtCreateFileOrig)
* @brief A variable holding the randomly chosen index for the genuine vendor list.
* This is used for transparent vendor spoofing
*/
-static WORD TRANSPARENT_GENUINE_VENDOR_STRING_INDEX = 0;
+static WORD g_TransparentGenuineVendorStringIndex = 0;
/**
* @brief System call numbers information
@@ -161,6 +161,8 @@ SYSTEM_CALL_NUMBERS_INFORMATION g_SystemCallNumbersInformation;
// Constants //
//////////////////////////////////////////////////
+#if ActivateHyperEvadeProject == TRUE
+
/**
* @brief A list of windows processes, for which to ignore systemcall requests
* when the transparency mode is enabled
@@ -239,7 +241,7 @@ static const PWCHAR TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR[] = {
* @brief A list of common Hypervisor specific process executables
*
*/
-static const PWCH HV_Processes[] = {
+static const PWCH HV_PROCESSES[] = {
L"hyperdbg-cli.exe",
L"vboxservice.exe",
L"vmsrvc.exe",
@@ -360,7 +362,7 @@ static const PWCH HV_FILES[] = {
// HyperDbg Files
//
L"hyperhv",
- L"hyperkd"
+ L"hyperkd",
L"hyperlog",
L"libhyperdbg",
@@ -557,11 +559,12 @@ static const PWCH HV_REGKEYS[] = {
};
-//
-// @brief A list of registry keys which might contain hypervisor vendor information in their data
-//
-// NOTE: This is not a complete list, there are a lot of generic keys that also can have the identifiable data
-//
+/**
+ * @brief A list of registry keys which might contain hypervisor vendor information in their data
+ *
+ * @details NOTE: This is not a complete list, there are a lot of generic keys that also can have the identifiable data
+ *
+ */
static const PWCH TRANSPARENT_DETECTABLE_REGISTRY_KEYS[] = {
L"AcpiData",
L"SMBiosData",
@@ -609,6 +612,8 @@ static const PCHAR HV_FIRM_NAMES[] = {
};
+#endif
+
//////////////////////////////////////////////////
// Functions //
//////////////////////////////////////////////////
diff --git a/hyperdbg/hyperevade/header/Transparency.h b/hyperdbg/hyperevade/header/Transparency.h
index 1f77c801..5b3493b8 100644
--- a/hyperdbg/hyperevade/header/Transparency.h
+++ b/hyperdbg/hyperevade/header/Transparency.h
@@ -1,6 +1,7 @@
/**
* @file Transparency.h
* @author Sina Karvandi (sina@hyperdbg.org)
+ * @author jtaw5649
* @brief hide the debugger from anti-debugging and anti-hypervisor methods (headers)
* @details
* @version 0.1
@@ -64,6 +65,12 @@ typedef struct _TRANSPARENCY_PROCESS
*/
BOOLEAN g_TransparentMode;
+/**
+ * @brief The enabled transparent-mode feature mask
+ *
+ */
+UINT32 g_TransparentEvadeMask;
+
//////////////////////////////////////////////////
// Functions //
//////////////////////////////////////////////////
diff --git a/hyperdbg/hyperevade/header/VmxFootprints.h b/hyperdbg/hyperevade/header/VmxFootprints.h
index cb168493..39560e8c 100644
--- a/hyperdbg/hyperevade/header/VmxFootprints.h
+++ b/hyperdbg/hyperevade/header/VmxFootprints.h
@@ -1,7 +1,7 @@
/**
- * @file VmxFootprint.h
+ * @file VmxFootprints.h
* @author Sina Karvandi (sina@hyperdbg.org)
- * @brief Hide the debugger from VMX-footrpints of anti-debugging and anti-hypervisor methods (headers)
+ * @brief Hide the debugger from VMX-footprints of anti-debugging and anti-hypervisor methods (headers)
* @details
* @version 0.14
* @date 2024-08-06
diff --git a/hyperdbg/hyperevade/header/pch.h b/hyperdbg/hyperevade/header/pch.h
index 6684367a..60a4e99b 100644
--- a/hyperdbg/hyperevade/header/pch.h
+++ b/hyperdbg/hyperevade/header/pch.h
@@ -19,9 +19,9 @@
//
// Environment headers
//
-#include "platform/kernel/header/Environment.h"
+#include "platform/general/header/Environment.h"
-#ifdef ENV_WINDOWS
+#ifdef HYPERDBG_ENV_WINDOWS
//
// Windows defined functions
@@ -30,7 +30,7 @@
# include
# include
-#endif // ENV_WINDOWS
+#endif // HYPERDBG_ENV_WINDOWS
//
// Scope definitions
@@ -61,13 +61,14 @@
//
// Hyperlog headers
//
-#include "components/interface/HyperLogCallback.h"
+#include "components/callback/header/HyperLogCallback.h"
#include "SDK/imports/kernel/HyperDbgHyperLogIntrinsics.h"
//
// Platform independent headers
//
-#include "platform/kernel/header/Mem.h"
+#include "platform/kernel/header/PlatformMem.h"
+#include "platform/kernel/header/PlatformIntrinsics.h"
//
// Hyperevade Callbacks
diff --git a/hyperdbg/hyperevade/hyperevade.vcxproj b/hyperdbg/hyperevade/hyperevade.vcxproj
index 73963ef4..ea3a07dc 100644
--- a/hyperdbg/hyperevade/hyperevade.vcxproj
+++ b/hyperdbg/hyperevade/hyperevade.vcxproj
@@ -1,5 +1,8 @@
+
+
+ debug
@@ -27,7 +30,7 @@
WindowsKernelModeDriver10.0DynamicLibraryKMDF
- Universal
+ Desktopfalse
@@ -36,7 +39,7 @@
WindowsKernelModeDriver10.0DynamicLibraryKMDF
- Universal
+ Desktopfalse
@@ -87,7 +90,7 @@
Createpch.hstdcpp20
- Disabled
+ Fulltrue
@@ -100,29 +103,42 @@
-
-
+
-
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/hyperevade/hyperevade.vcxproj.filters b/hyperdbg/hyperevade/hyperevade.vcxproj.filters
index ee739db9..f7ed48f3 100644
--- a/hyperdbg/hyperevade/hyperevade.vcxproj.filters
+++ b/hyperdbg/hyperevade/hyperevade.vcxproj.filters
@@ -22,20 +22,20 @@
{890885f8-de8f-41df-9202-3ec320d7d816}
-
- {228a6a7a-4085-4871-a29b-15ca5576623d}
- {a66d71db-112c-4826-8181-ba265d339149}{da60b9fe-3816-4f3c-a6a9-21accd463156}
-
- {895edb89-17e8-4a1e-a648-b0ea360e98f8}
+
+ {0e801893-09df-4299-a572-6e63049d4f9f}
-
- {7c6fe4d9-4baf-4fd2-93e0-ee395cbc2ee9}
+
+ {78b7809e-ea12-450d-af96-8e658087628d}
+
+
+ {28025c67-f68b-437b-bcda-d23c9a752d42}
@@ -45,12 +45,9 @@
code
-
+ code\platform
-
- code\components\registers
- code\components\spinlock
@@ -66,15 +63,18 @@
code\components\optimizations
-
- code\interface
- codecode
+
+ code\platform
+
+
+ code\components\callback
+
@@ -83,20 +83,23 @@
header
-
+ header\platform
-
- header\platform
-
-
- header\interface
- headerheader
+
+ header\platform
+
+
+ header\components\callback
+
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/hyperevade/packages.config b/hyperdbg/hyperevade/packages.config
new file mode 100644
index 00000000..eb276766
--- /dev/null
+++ b/hyperdbg/hyperevade/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/hyperhv/CMakeLists.txt b/hyperdbg/hyperhv/CMakeLists.txt
index a92b3180..990c533c 100644
--- a/hyperdbg/hyperhv/CMakeLists.txt
+++ b/hyperdbg/hyperhv/CMakeLists.txt
@@ -5,7 +5,7 @@ set(SourceFiles
"../include/components/optimizations/code/InsertionSort.c"
"../include/components/optimizations/code/OptimizationsExamples.c"
"../include/components/spinlock/code/Spinlock.c"
- "../include/platform/kernel/code/Mem.c"
+ "../include/platform/kernel/code/PlatformMem.c"
"code/broadcast/Broadcast.c"
"code/broadcast/DpcRoutines.c"
"code/common/Bitwise.c"
@@ -102,7 +102,7 @@ set(SourceFiles
"../include/components/spinlock/header/Spinlock.h"
"../include/macros/MetaMacros.h"
"../include/platform/kernel/header/Environment.h"
- "../include/platform/kernel/header/Mem.h"
+ "../include/platform/kernel/header/PlatformMem.h"
"header/assembly/InlineAsm.h"
"header/broadcast/Broadcast.h"
"header/broadcast/DpcRoutines.h"
diff --git a/hyperdbg/hyperhv/code/assembly/AsmCommon.asm b/hyperdbg/hyperhv/code/assembly/AsmCommon.asm
index 58b0b711..785e8047 100644
--- a/hyperdbg/hyperhv/code/assembly/AsmCommon.asm
+++ b/hyperdbg/hyperhv/code/assembly/AsmCommon.asm
@@ -68,4 +68,18 @@ AsmReloadIdtr ENDP
;------------------------------------------------------------------------
+; AsmReadSsp ( );
+
+AsmReadSsp PROC
+
+ ; Save the current SSP to a memory location
+ rdsspq rax ; Save SSP to memory at the current location (stack pointer)
+
+ ; Return from the function
+ ret
+
+AsmReadSsp ENDP
+
+;------------------------------------------------------------------------
+
END
\ No newline at end of file
diff --git a/hyperdbg/hyperhv/code/assembly/AsmVmexitHandler.asm b/hyperdbg/hyperhv/code/assembly/AsmVmexitHandler.asm
index 0a41fbd1..54476abd 100644
--- a/hyperdbg/hyperhv/code/assembly/AsmVmexitHandler.asm
+++ b/hyperdbg/hyperhv/code/assembly/AsmVmexitHandler.asm
@@ -1,7 +1,8 @@
PUBLIC AsmVmexitHandler
+PUBLIC AsmVmxoffRestoreXmmRegs
EXTERN VmxVmexitHandler:PROC
-EXTERN VmxVmresume:PROC
+EXTERN VmxPerformVmresume:PROC
EXTERN VmxReturnStackPointerForVmxoff:PROC
EXTERN VmxReturnInstructionPointerForVmxoff:PROC
@@ -15,32 +16,42 @@ AsmVmexitHandler PROC
; irql less or equal as it doesn't exist, so we just put some extra space avoid
; these kind of errors
- pushfq
+ ; --------------- Save RFLAGS ----------------
+
+ pushfq ; Save the flags register (RFLAGS)
; ------------ Save XMM Registers ------------
+
+ ; 16 Byte * 16 Byte = 256 + 4 = 260 (0x104 == 0x110 but let's align it to have better performance)
+
+ sub rsp, 0110h
+
+ movaps xmmword ptr [rsp+000h], xmm0 ; each xmm register 128 bit (16 Byte)
+ movaps xmmword ptr [rsp+010h], xmm1
+ movaps xmmword ptr [rsp+020h], xmm2
+ movaps xmmword ptr [rsp+030h], xmm3
+ movaps xmmword ptr [rsp+040h], xmm4
+ movaps xmmword ptr [rsp+050h], xmm5
+
;
- ; ;;;;;;;;;;;; 16 Byte * 16 Byte = 256 + 4 = 260 (0x106 == 0x110 but let's align it to have better performance) ;;;;;;;;;;;;
- ; sub rsp, 0110h
+ ; As per Microsoft ABI documentation, the following registers are nonvolatile
+ ; So, MSVC compiler will save them on the stack if they are used in the function
+ ; Thus, for the sake of performance, we comment them out
;
- ; movaps xmmword ptr [rsp+000h], xmm0 ; each xmm register 128 bit (16 Byte)
- ; movaps xmmword ptr [rsp+010h], xmm1
- ; movaps xmmword ptr [rsp+020h], xmm2
- ; movaps xmmword ptr [rsp+030h], xmm3
- ; movaps xmmword ptr [rsp+040h], xmm4
- ; movaps xmmword ptr [rsp+050h], xmm5
- ; movaps xmmword ptr [rsp+060h], xmm6
- ; movaps xmmword ptr [rsp+070h], xmm7
- ; movaps xmmword ptr [rsp+080h], xmm8
- ; movaps xmmword ptr [rsp+090h], xmm9
- ; movaps xmmword ptr [rsp+0a0h], xmm10
- ; movaps xmmword ptr [rsp+0b0h], xmm11
- ; movaps xmmword ptr [rsp+0c0h], xmm12
- ; movaps xmmword ptr [rsp+0d0h], xmm13
- ; movaps xmmword ptr [rsp+0e0h], xmm14
- ; movaps xmmword ptr [rsp+0f0h], xmm15
- ; stmxcsr dword ptr [rsp+0100h] ; MxCsr is 4 Byte
- ;
- ;---------------------------------------------
+ ; movaps xmmword ptr [rsp+060h], xmm6
+ ; movaps xmmword ptr [rsp+070h], xmm7
+ ; movaps xmmword ptr [rsp+080h], xmm8
+ ; movaps xmmword ptr [rsp+090h], xmm9
+ ; movaps xmmword ptr [rsp+0a0h], xmm10
+ ; movaps xmmword ptr [rsp+0b0h], xmm11
+ ; movaps xmmword ptr [rsp+0c0h], xmm12
+ ; movaps xmmword ptr [rsp+0d0h], xmm13
+ ; movaps xmmword ptr [rsp+0e0h], xmm14
+ ; movaps xmmword ptr [rsp+0f0h], xmm15
+
+ stmxcsr dword ptr [rsp+0100h] ; MxCsr is 4 Byte
+
+ ; ------ Save General-purpose Registers ------
push r15
push r14
@@ -58,21 +69,28 @@ AsmVmexitHandler PROC
push rdx
push rcx
push rax
-
+
+ ; ----------- Call VM-exit Handler -----------
+
mov rcx, rsp ; Fast call argument to PGUEST_REGS
+
sub rsp, 020h ; Free some space for Shadow Section
call VmxVmexitHandler
add rsp, 020h ; Restore the state
- cmp al, 1 ; Check whether we have to turn off VMX or Not (the result is in RAX)
+ cmp al, 1 ; Check whether we have to turn off VMX or Not (the result is in RAX)
+
je AsmVmxoffHandler
-
+
+ ; ----------- Restore XMM Registers ----------
+
RestoreState:
+
pop rax
pop rcx
pop rdx
pop rbx
- pop rbp ; rsp
+ pop rbp ; rsp
pop rbp
pop rsi
pop rdi
@@ -86,71 +104,92 @@ RestoreState:
pop r15
; ------------ Restore XMM Registers ------------
+
+ movaps xmm0, xmmword ptr [rsp+000h]
+ movaps xmm1, xmmword ptr [rsp+010h]
+ movaps xmm2, xmmword ptr [rsp+020h]
+ movaps xmm3, xmmword ptr [rsp+030h]
+ movaps xmm4, xmmword ptr [rsp+040h]
+ movaps xmm5, xmmword ptr [rsp+050h]
+
;
- ; movaps xmm0, xmmword ptr [rsp+000h]
- ; movaps xmm1, xmmword ptr [rsp+010h]
- ; movaps xmm2, xmmword ptr [rsp+020h]
- ; movaps xmm3, xmmword ptr [rsp+030h]
- ; movaps xmm4, xmmword ptr [rsp+040h]
- ; movaps xmm5, xmmword ptr [rsp+050h]
- ; movaps xmm6, xmmword ptr [rsp+060h]
- ; movaps xmm7, xmmword ptr [rsp+070h]
- ; movaps xmm8, xmmword ptr [rsp+080h]
- ; movaps xmm9, xmmword ptr [rsp+090h]
- ; movaps xmm10, xmmword ptr [rsp+0a0h]
- ; movaps xmm11, xmmword ptr [rsp+0b0h]
- ; movaps xmm12, xmmword ptr [rsp+0c0h]
- ; movaps xmm13, xmmword ptr [rsp+0d0h]
- ; movaps xmm14, xmmword ptr [rsp+0e0h]
- ; movaps xmm15, xmmword ptr [rsp+0f0h]
+ ; As per Microsoft ABI documentation, the following registers are nonvolatile
+ ; So, MSVC compiler will save them on the stack if they are used in the function
+ ; Thus, for the sake of performance, we comment them out
;
- ; ldmxcsr dword ptr [rsp+0100h]
- ;
- ; add rsp, 0110h
+ ; movaps xmm6, xmmword ptr [rsp+060h]
+ ; movaps xmm7, xmmword ptr [rsp+070h]
+ ; movaps xmm8, xmmword ptr [rsp+080h]
+ ; movaps xmm9, xmmword ptr [rsp+090h]
+ ; movaps xmm10, xmmword ptr [rsp+0a0h]
+ ; movaps xmm11, xmmword ptr [rsp+0b0h]
+ ; movaps xmm12, xmmword ptr [rsp+0c0h]
+ ; movaps xmm13, xmmword ptr [rsp+0d0h]
+ ; movaps xmm14, xmmword ptr [rsp+0e0h]
+ ; movaps xmm15, xmmword ptr [rsp+0f0h]
+
+ ldmxcsr dword ptr [rsp+0100h]
+
+ add rsp, 0110h
+
+ ; --------------- Restore RFLAGS ---------------
+
+ popfq ; Restore the flags register (RFLAGS)
+
; ----------------------------------------------
- popfq
-
- sub rsp, 0100h ; to avoid error in future functions
- jmp VmxVmresume
+ jmp VmxPerformVmresume
AsmVmexitHandler ENDP
;------------------------------------------------------------------------
+AsmVmxoffRestoreXmmRegs PROC
+
+ ; ------------ Restore XMM Registers ------------
+
+ movaps xmm0, xmmword ptr [rcx+000h]
+ movaps xmm1, xmmword ptr [rcx+010h]
+ movaps xmm2, xmmword ptr [rcx+020h]
+ movaps xmm3, xmmword ptr [rcx+030h]
+ movaps xmm4, xmmword ptr [rcx+040h]
+ movaps xmm5, xmmword ptr [rcx+050h]
+
+ ;
+ ; As per Microsoft ABI documentation, the following registers are nonvolatile
+ ; So, MSVC compiler will save them on the stack if they are used in the function
+ ; Thus, for the sake of performance, we comment them out
+ ;
+ ; movaps xmm6, xmmword ptr [rcx+060h]
+ ; movaps xmm7, xmmword ptr [rcx+070h]
+ ; movaps xmm8, xmmword ptr [rcx+080h]
+ ; movaps xmm9, xmmword ptr [rcx+090h]
+ ; movaps xmm10, xmmword ptr [rcx+0a0h]
+ ; movaps xmm11, xmmword ptr [rcx+0b0h]
+ ; movaps xmm12, xmmword ptr [rcx+0c0h]
+ ; movaps xmm13, xmmword ptr [rcx+0d0h]
+ ; movaps xmm14, xmmword ptr [rcx+0e0h]
+ ; movaps xmm15, xmmword ptr [rcx+0f0h]
+
+ ldmxcsr dword ptr [rcx+0100h]
+
+ ret
+
+AsmVmxoffRestoreXmmRegs ENDP
+
+;------------------------------------------------------------------------
+
AsmVmxoffHandler PROC
-
- sub rsp, 020h ; shadow space
- call VmxReturnStackPointerForVmxoff
- add rsp, 020h ; remove for shadow space
-
- mov [rsp+88h], rax ; now, rax contains rsp
-
- sub rsp, 020h ; shadow space
- call VmxReturnInstructionPointerForVmxoff
- add rsp, 020h ; remove for shadow space
-
- mov rdx, rsp ; save current rsp
-
- mov rbx, [rsp+88h] ; read rsp again
-
- mov rsp, rbx
-
- push rax ; push the return address as we changed the stack, we push
- ; it to the new stack
-
- mov rsp, rdx ; restore previous rsp
-
- sub rbx,08h ; we push sth, so we have to add (sub) +8 from previous stack
- ; also rbx already contains the rsp
- mov [rsp+88h], rbx ; move the new pointer to the current stack
-
+
+ ; ------ Restore General-purpose Registers ------
+
RestoreState:
+
pop rax
pop rcx
pop rdx
pop rbx
- pop rbp ; rsp
+ pop rbp ; rsp
pop rbp
pop rsi
pop rdi
@@ -163,34 +202,40 @@ RestoreState:
pop r14
pop r15
- ; ------------ Restore XMM Registers ------------
- ;
- ; movaps xmm0, xmmword ptr [rsp+000h]
- ; movaps xmm1, xmmword ptr [rsp+010h]
- ; movaps xmm2, xmmword ptr [rsp+020h]
- ; movaps xmm3, xmmword ptr [rsp+030h]
- ; movaps xmm4, xmmword ptr [rsp+040h]
- ; movaps xmm5, xmmword ptr [rsp+050h]
- ; movaps xmm6, xmmword ptr [rsp+060h]
- ; movaps xmm7, xmmword ptr [rsp+070h]
- ; movaps xmm8, xmmword ptr [rsp+080h]
- ; movaps xmm9, xmmword ptr [rsp+090h]
- ; movaps xmm10, xmmword ptr [rsp+0a0h]
- ; movaps xmm11, xmmword ptr [rsp+0b0h]
- ; movaps xmm12, xmmword ptr [rsp+0c0h]
- ; movaps xmm13, xmmword ptr [rsp+0d0h]
- ; movaps xmm14, xmmword ptr [rsp+0e0h]
- ; movaps xmm15, xmmword ptr [rsp+0f0h]
- ;
- ; ldmxcsr dword ptr [rsp+0100h]
- ;
- ; add rsp, 0110h
+ ; ------------- Pass over XMM Regs -------------
+
+ ; XMM registers are restored by AsmVmxoffRestoreXmmRegs
+ ; Size of XMM registers are 110 bytes but we also remove the RFLAGS register (+8)
+ ; so we have 118 bytes to remove from the stack
+ add rsp, 0118h
+
+ ; ------------ Get Stack Pointer ---------------
+
+ sub rsp, 020h ; shadow space
+ call VmxReturnStackPointerForVmxoff
+ add rsp, 020h ; remove for shadow space
+
+ push rax ; save the current rsp, we will restore it later
+
+
+ ; ------------ Get Instruction Pointer ---------
+
+ sub rsp, 020h ; shadow space
+ call VmxReturnInstructionPointerForVmxoff
+ add rsp, 020h ; remove for shadow space
+
+ pop rsp ; restore rsp
+ push rax ; push the instruction pointer
+
; ----------------------------------------------
- popfq
- pop rsp ; restore rsp
+ ; There might be some registers that are modified by above CALLs,
+ ; but here we do not care about them since we are also in a function,
+ ; so the caller do not expect us to preserve these volatile registers
- ret ; jump back to where we called Vmcall
+ xor rax, rax ; clear RAX to indicate VMXOFF was successful (VMCALL Status)
+
+ ret ; jump back to where we called Vmcall
AsmVmxoffHandler ENDP
diff --git a/hyperdbg/hyperhv/code/broadcast/DpcRoutines.c b/hyperdbg/hyperhv/code/broadcast/DpcRoutines.c
index 89bce798..0f1e491d 100644
--- a/hyperdbg/hyperhv/code/broadcast/DpcRoutines.c
+++ b/hyperdbg/hyperhv/code/broadcast/DpcRoutines.c
@@ -135,15 +135,10 @@ DpcRoutinePerformVirtualization(KDPC * Dpc, PVOID DeferredContext, PVOID SystemA
//
VmxPerformVirtualizationOnSpecificCore();
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
return TRUE;
}
@@ -454,15 +449,10 @@ DpcRoutineEnableMovToCr3Exiting(KDPC * Dpc, PVOID DeferredContext, PVOID SystemA
//
AsmVmxVmcall(VMCALL_ENABLE_MOV_TO_CR3_EXITING, 0, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -485,15 +475,10 @@ DpcRoutineChangeToMbecSupportedEptp(KDPC * Dpc, PVOID DeferredContext, PVOID Sys
//
AsmVmxVmcall(VMCALL_CHANGE_TO_MBEC_SUPPORTED_EPTP, 0, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -516,15 +501,10 @@ DpcRoutineRestoreToNormalEptp(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArg
//
AsmVmxVmcall(VMCALL_RESTORE_TO_NORMAL_EPTP, 0, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -547,15 +527,10 @@ DpcRoutineEnableOrDisableMbec(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArg
//
AsmVmxVmcall(VMCALL_DISABLE_OR_ENABLE_MBEC, (UINT64)DeferredContext, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -578,15 +553,10 @@ DpcRoutineDisableMovToCr3Exiting(KDPC * Dpc, PVOID DeferredContext, PVOID System
//
AsmVmxVmcall(VMCALL_DISABLE_MOV_TO_CR3_EXITING, 0, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -609,15 +579,10 @@ DpcRoutineEnableEferSyscallEvents(KDPC * Dpc, PVOID DeferredContext, PVOID Syste
//
AsmVmxVmcall(VMCALL_ENABLE_SYSCALL_HOOK_EFER, 0, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -640,15 +605,10 @@ DpcRoutineDisableEferSyscallEvents(KDPC * Dpc, PVOID DeferredContext, PVOID Syst
//
AsmVmxVmcall(VMCALL_DISABLE_SYSCALL_HOOK_EFER, 0, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -671,15 +631,10 @@ DpcRoutineEnablePml(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PV
//
AsmVmxVmcall(VMCALL_ENABLE_DIRTY_LOGGING_MECHANISM, 0, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -702,15 +657,10 @@ DpcRoutineDisablePml(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, P
//
AsmVmxVmcall(VMCALL_DISABLE_DIRTY_LOGGING_MECHANISM, 0, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -732,15 +682,10 @@ DpcRoutineChangeMsrBitmapReadOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID
//
AsmVmxVmcall(VMCALL_CHANGE_MSR_BITMAP_READ, (UINT64)DeferredContext, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -763,15 +708,10 @@ DpcRoutineResetMsrBitmapReadOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID
//
AsmVmxVmcall(VMCALL_RESET_MSR_BITMAP_READ, NULL64_ZERO, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -793,15 +733,10 @@ DpcRoutineChangeMsrBitmapWriteOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOI
//
AsmVmxVmcall(VMCALL_CHANGE_MSR_BITMAP_WRITE, (UINT64)DeferredContext, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -824,15 +759,10 @@ DpcRoutineResetMsrBitmapWriteOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID
//
AsmVmxVmcall(VMCALL_RESET_MSR_BITMAP_WRITE, NULL64_ZERO, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -855,15 +785,10 @@ DpcRoutineEnableRdtscExitingAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID Sy
//
AsmVmxVmcall(VMCALL_SET_RDTSC_EXITING, 0, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -886,15 +811,10 @@ DpcRoutineDisableRdtscExitingAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID S
//
AsmVmxVmcall(VMCALL_UNSET_RDTSC_EXITING, 0, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -919,15 +839,10 @@ DpcRoutineDisableRdtscExitingForClearingTscEventsAllCores(KDPC * Dpc, PVOID Defe
//
AsmVmxVmcall(VMCALL_DISABLE_RDTSC_EXITING_ONLY_FOR_TSC_EVENTS, 0, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -951,15 +866,10 @@ DpcRoutineDisableMov2DrExitingForClearingDrEventsAllCores(KDPC * Dpc, PVOID Defe
//
AsmVmxVmcall(VMCALL_DISABLE_MOV_TO_HW_DR_EXITING_ONLY_FOR_DR_EVENTS, 0, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -982,15 +892,10 @@ DpcRoutineDisableMov2CrExitingForClearingCrEventsAllCores(KDPC * Dpc, DEBUGGER_E
//
AsmVmxVmcall(VMCALL_DISABLE_MOV_TO_CR_EXITING_ONLY_FOR_CR_EVENTS, EventOptions->OptionalParam1, EventOptions->OptionalParam2, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1013,15 +918,10 @@ DpcRoutineEnableRdpmcExitingAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID Sy
//
AsmVmxVmcall(VMCALL_SET_RDPMC_EXITING, 0, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1044,15 +944,10 @@ DpcRoutineDisableRdpmcExitingAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID S
//
AsmVmxVmcall(VMCALL_UNSET_RDPMC_EXITING, 0, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1074,15 +969,10 @@ DpcRoutineSetExceptionBitmapOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID
//
AsmVmxVmcall(VMCALL_SET_EXCEPTION_BITMAP, (UINT64)DeferredContext, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1104,15 +994,10 @@ DpcRoutineUnsetExceptionBitmapOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOI
//
AsmVmxVmcall(VMCALL_UNSET_EXCEPTION_BITMAP, (UINT64)DeferredContext, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1139,15 +1024,10 @@ DpcRoutineResetExceptionBitmapOnlyOnClearingExceptionEventsOnAllCores(KDPC * Dpc
//
AsmVmxVmcall(VMCALL_RESET_EXCEPTION_BITMAP_ONLY_ON_CLEARING_EXCEPTION_EVENTS, NULL64_ZERO, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1170,15 +1050,10 @@ DpcRoutineEnableMovDebigRegisterExitingAllCores(KDPC * Dpc, PVOID DeferredContex
//
AsmVmxVmcall(VMCALL_ENABLE_MOV_TO_DEBUG_REGS_EXITING, 0, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1200,15 +1075,10 @@ DpcRoutineEnableMovControlRegisterExitingAllCores(KDPC * Dpc, DEBUGGER_EVENT_OPT
//
AsmVmxVmcall(VMCALL_ENABLE_MOV_TO_CONTROL_REGS_EXITING, EventOptions->OptionalParam1, EventOptions->OptionalParam2, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1230,15 +1100,10 @@ DpcRoutineDisableMovControlRegisterExitingAllCores(KDPC * Dpc, DEBUGGER_EVENT_OP
//
AsmVmxVmcall(VMCALL_DISABLE_MOV_TO_CONTROL_REGS_EXITING, EventOptions->OptionalParam1, EventOptions->OptionalParam2, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1261,15 +1126,10 @@ DpcRoutineDisableMovDebigRegisterExitingAllCores(KDPC * Dpc, PVOID DeferredConte
//
AsmVmxVmcall(VMCALL_DISABLE_MOV_TO_DEBUG_REGS_EXITING, 0, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1292,15 +1152,10 @@ DpcRoutineSetEnableExternalInterruptExitingOnAllCores(KDPC * Dpc, PVOID Deferred
//
AsmVmxVmcall(VMCALL_ENABLE_EXTERNAL_INTERRUPT_EXITING, 0, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1326,15 +1181,10 @@ DpcRoutineSetDisableExternalInterruptExitingOnlyOnClearingInterruptEventsOnAllCo
//
AsmVmxVmcall(VMCALL_DISABLE_EXTERNAL_INTERRUPT_EXITING_ONLY_TO_CLEAR_INTERRUPT_COMMANDS, 0, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1356,15 +1206,10 @@ DpcRoutineChangeIoBitmapOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID Syst
//
AsmVmxVmcall(VMCALL_CHANGE_IO_BITMAP, (UINT64)DeferredContext, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1387,15 +1232,10 @@ DpcRoutineResetIoBitmapOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID Syste
//
AsmVmxVmcall(VMCALL_RESET_IO_BITMAP, NULL64_ZERO, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1418,15 +1258,10 @@ DpcRoutineEnableBreakpointOnExceptionBitmapOnAllCores(KDPC * Dpc, PVOID Deferred
//
AsmVmxVmcall(VMCALL_SET_EXCEPTION_BITMAP, EXCEPTION_VECTOR_BREAKPOINT, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1449,15 +1284,10 @@ DpcRoutineDisableBreakpointOnExceptionBitmapOnAllCores(KDPC * Dpc, PVOID Deferre
//
AsmVmxVmcall(VMCALL_UNSET_EXCEPTION_BITMAP, EXCEPTION_VECTOR_BREAKPOINT, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1480,15 +1310,10 @@ DpcRoutineEnableNmiVmexitOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID Sys
//
AsmVmxVmcall(VMCALL_SET_VM_EXIT_ON_NMIS, NULL64_ZERO, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1511,15 +1336,10 @@ DpcRoutineDisableNmiVmexitOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID Sy
//
AsmVmxVmcall(VMCALL_UNSET_VM_EXIT_ON_NMIS, NULL64_ZERO, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1547,15 +1367,10 @@ DpcRoutineEnableDbAndBpExitingOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOI
//
AsmVmxVmcall(VMCALL_SET_EXCEPTION_BITMAP, EXCEPTION_VECTOR_DEBUG_BREAKPOINT, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1583,15 +1398,10 @@ DpcRoutineDisableDbAndBpExitingOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVO
//
AsmVmxVmcall(VMCALL_UNSET_EXCEPTION_BITMAP, EXCEPTION_VECTOR_DEBUG_BREAKPOINT, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1614,15 +1424,10 @@ DpcRoutineRemoveHookAndInvalidateAllEntriesOnAllCores(KDPC * Dpc, PVOID Deferred
//
AsmVmxVmcall(VMCALL_UNHOOK_ALL_PAGES, NULL64_ZERO, NULL64_ZERO, NULL64_ZERO);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1647,15 +1452,10 @@ DpcRoutineRemoveHookAndInvalidateSingleEntryOnAllCores(KDPC * Dpc, PVOID Deferre
//
AsmVmxVmcall(VMCALL_UNHOOK_SINGLE_PAGE, UnhookingDetail->PhysicalAddress, UnhookingDetail->OriginalEntry, NULL64_ZERO);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1690,15 +1490,10 @@ DpcRoutineInvalidateEptOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID Syste
NULL64_ZERO);
}
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1721,15 +1516,10 @@ DpcRoutineInitializeGuest(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgumen
//
AsmVmxSaveState();
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -1755,13 +1545,8 @@ DpcRoutineTerminateGuest(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument
LogError("Err, there were an error terminating vmx");
}
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
diff --git a/hyperdbg/hyperhv/code/common/Bitwise.c b/hyperdbg/hyperhv/code/common/Bitwise.c
index 1d0976a9..cb844856 100644
--- a/hyperdbg/hyperhv/code/common/Bitwise.c
+++ b/hyperdbg/hyperhv/code/common/Bitwise.c
@@ -15,35 +15,35 @@
* @brief Check whether the bit is set or not
*
* @param BitNumber
- * @param addr
- * @return int
+ * @param Addr
+ * @return INT
*/
-int
-TestBit(int BitNumber, unsigned long * addr)
+INT
+TestBit(INT BitNumber, ULONG * Addr)
{
- return (BITMAP_ENTRY(BitNumber, addr) >> BITMAP_SHIFT(BitNumber)) & 1;
+ return (BITMAP_ENTRY(BitNumber, Addr) >> BITMAP_SHIFT(BitNumber)) & 1;
}
/**
* @brief unset the bit
*
* @param BitNumber
- * @param addr
+ * @param Addr
*/
-void
-ClearBit(int BitNumber, unsigned long * addr)
+VOID
+ClearBit(INT BitNumber, ULONG * Addr)
{
- BITMAP_ENTRY(BitNumber, addr) &= ~(1UL << BITMAP_SHIFT(BitNumber));
+ BITMAP_ENTRY(BitNumber, Addr) &= ~(1UL << BITMAP_SHIFT(BitNumber));
}
/**
* @brief set the bit
*
* @param BitNumber
- * @param addr
+ * @param Addr
*/
-void
-SetBit(int BitNumber, unsigned long * addr)
+VOID
+SetBit(INT BitNumber, ULONG * Addr)
{
- BITMAP_ENTRY(BitNumber, addr) |= (1UL << BITMAP_SHIFT(BitNumber));
+ BITMAP_ENTRY(BitNumber, Addr) |= (1UL << BITMAP_SHIFT(BitNumber));
}
diff --git a/hyperdbg/hyperhv/code/common/Common.c b/hyperdbg/hyperhv/code/common/Common.c
index 0619b09b..9eac49d3 100644
--- a/hyperdbg/hyperhv/code/common/Common.c
+++ b/hyperdbg/hyperhv/code/common/Common.c
@@ -61,30 +61,30 @@ CommonGetProcessNameFromProcessControlBlock(PEPROCESS Eprocess)
/**
* @brief Detects whether the string starts with another string
*
- * @param const char * pre
- * @param const char * str
+ * @param pre
+ * @param str
* @return BOOLEAN Returns true if it starts with and false if not strats with
*/
BOOLEAN
-CommonIsStringStartsWith(const char * pre, const char * str)
+CommonIsStringStartsWith(const CHAR * pre, const CHAR * str)
{
- size_t lenpre = strlen(pre),
- lenstr = strlen(str);
- return lenstr < lenpre ? FALSE : memcmp(pre, str, lenpre) == 0;
+ SIZE_T LenPre = strlen(pre),
+ LenStr = strlen(str);
+ return LenStr < LenPre ? FALSE : memcmp(pre, str, LenPre) == 0;
}
/**
* @brief Get cpuid results
*
- * @param UINT32 Func
- * @param UINT32 SubFunc
- * @param int * CpuInfo
+ * @param Func
+ * @param SubFunc
+ * @param CpuInfo
* @return VOID
*/
VOID
-CommonCpuidInstruction(UINT32 Func, UINT32 SubFunc, int * CpuInfo)
+CommonCpuidInstruction(UINT32 Func, UINT32 SubFunc, INT * CpuInfo)
{
- __cpuidex(CpuInfo, Func, SubFunc);
+ CpuCpuIdEx(CpuInfo, Func, SubFunc);
}
/**
@@ -156,7 +156,7 @@ CommonWriteDebugInformation(VIRTUAL_MACHINE_STATE * VCpu)
MemoryMapperReadMemorySafeOnTargetProcess(VCpu->LastVmexitRip, Instruction, MAXIMUM_INSTR_SIZE);
- for (size_t i = 0; i < MAXIMUM_INSTR_SIZE; i++)
+ for (SIZE_T i = 0; i < MAXIMUM_INSTR_SIZE; i++)
{
Log("%02X ", Instruction[i] & 0xffU);
}
@@ -249,4 +249,4 @@ CommonIsXCr0Valid(XCR0 XCr0)
}
return TRUE;
-}
\ No newline at end of file
+}
diff --git a/hyperdbg/hyperhv/code/components/registers/DebugRegisters.c b/hyperdbg/hyperhv/code/components/registers/DebugRegisters.c
index c12aacf5..85f7b45a 100644
--- a/hyperdbg/hyperhv/code/components/registers/DebugRegisters.c
+++ b/hyperdbg/hyperhv/code/components/registers/DebugRegisters.c
@@ -1,4 +1,4 @@
-/**
+/**
* @file DebugRegisters.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Implementation of debug registers functions
@@ -77,7 +77,7 @@ SetDebugRegisters(UINT32 DebugRegNum, DEBUG_REGISTER_TYPE ActionType, BOOLEAN Ap
//
if (DebugRegNum == 0)
{
- __writedr(0, TargetAddress);
+ CpuWriteDr(0, TargetAddress);
Dr7.GlobalBreakpoint0 = 1;
@@ -119,7 +119,7 @@ SetDebugRegisters(UINT32 DebugRegNum, DEBUG_REGISTER_TYPE ActionType, BOOLEAN Ap
}
else if (DebugRegNum == 1)
{
- __writedr(1, TargetAddress);
+ CpuWriteDr(1, TargetAddress);
Dr7.GlobalBreakpoint1 = 1;
//
@@ -160,7 +160,7 @@ SetDebugRegisters(UINT32 DebugRegNum, DEBUG_REGISTER_TYPE ActionType, BOOLEAN Ap
}
else if (DebugRegNum == 2)
{
- __writedr(2, TargetAddress);
+ CpuWriteDr(2, TargetAddress);
Dr7.GlobalBreakpoint2 = 1;
//
@@ -201,7 +201,7 @@ SetDebugRegisters(UINT32 DebugRegNum, DEBUG_REGISTER_TYPE ActionType, BOOLEAN Ap
}
else if (DebugRegNum == 3)
{
- __writedr(3, TargetAddress);
+ CpuWriteDr(3, TargetAddress);
Dr7.GlobalBreakpoint3 = 1;
//
@@ -248,11 +248,11 @@ SetDebugRegisters(UINT32 DebugRegNum, DEBUG_REGISTER_TYPE ActionType, BOOLEAN Ap
//
if (ApplyToVmcs)
{
- __vmx_vmwrite(VMCS_GUEST_DR7, Dr7.AsUInt);
+ HvSetDebugReg7(Dr7.AsUInt);
}
else
{
- __writedr(7, Dr7.AsUInt);
+ CpuWriteDr(7, Dr7.AsUInt);
}
return TRUE;
diff --git a/hyperdbg/hyperhv/code/devices/Apic.c b/hyperdbg/hyperhv/code/devices/Apic.c
index a989f95b..c1cb2863 100644
--- a/hyperdbg/hyperhv/code/devices/Apic.c
+++ b/hyperdbg/hyperhv/code/devices/Apic.c
@@ -15,7 +15,7 @@
#include "pch.h"
/**
- * @brief Perfom read I/O APIC
+ * @brief Perform read I/O APIC
*
* @param IoApicBaseVa
* @param Reg
@@ -45,7 +45,7 @@ IoApicRead(volatile IO_APIC_ENT * IoApicBaseVa, UINT32 Reg)
}
/**
- * @brief Perfom write to I/O APIC
+ * @brief Perform write to I/O APIC
*
* @param IoApicBaseVa
* @param Reg
@@ -79,18 +79,18 @@ ApicDumpIoApic(IO_APIC_ENTRY_PACKETS * IoApicPackets)
{
UINT32 Index = 0;
UINT32 Max;
- UINT64 ll, lh;
+ UINT64 Ll, Lh;
UINT64 ApicBasePa = IO_APIC_DEFAULT_BASE_ADDR;
- ll = IoApicRead(g_IoApicBase, IO_VERS_REGISTER),
+ Ll = IoApicRead(g_IoApicBase, IO_VERS_REGISTER),
- Max = (ll >> 16) & 0xff;
+ Max = (Ll >> 16) & 0xff;
// Log("IoApic @ %08x ID:%x (%x) Arb:%x\n",
// ApicBasePa,
// IoApicRead(g_IoApicBase, IO_ID_REGISTER) >> 24,
- // ll & 0xFF,
+ // Ll & 0xFF,
// IoApicRead(g_IoApicBase, IO_ARB_ID_REGISTER));
//
@@ -99,7 +99,7 @@ ApicDumpIoApic(IO_APIC_ENTRY_PACKETS * IoApicPackets)
IoApicPackets->ApicBasePa = (UINT32)ApicBasePa;
IoApicPackets->ApicBaseVa = (UINT64)g_IoApicBase;
IoApicPackets->IoIdReg = (UINT32)IoApicRead(g_IoApicBase, IO_ID_REGISTER);
- IoApicPackets->IoLl = (UINT32)ll;
+ IoApicPackets->IoLl = (UINT32)Ll;
IoApicPackets->IoArbIdReg = (UINT32)IoApicRead(g_IoApicBase, IO_ARB_ID_REGISTER);
//
@@ -117,11 +117,11 @@ ApicDumpIoApic(IO_APIC_ENTRY_PACKETS * IoApicPackets)
return;
}
- ll = IoApicRead(g_IoApicBase, IO_REDIR_BASE + Index + 0);
- lh = IoApicRead(g_IoApicBase, IO_REDIR_BASE + Index + 1);
+ Ll = IoApicRead(g_IoApicBase, IO_REDIR_BASE + Index + 0);
+ Lh = IoApicRead(g_IoApicBase, IO_REDIR_BASE + Index + 1);
- IoApicPackets->LlLhData[Index] = ll;
- IoApicPackets->LlLhData[Index + 1] = lh;
+ IoApicPackets->LlLhData[Index] = Ll;
+ IoApicPackets->LlLhData[Index + 1] = Lh;
}
}
@@ -149,7 +149,7 @@ XApicIcrWrite(UINT32 Low, UINT32 High)
VOID
X2ApicIcrWrite(UINT32 Low, UINT32 High)
{
- __writemsr(X2_MSR_BASE + TO_X2(ICROffset), ((UINT64)High << 32) | Low);
+ CpuWriteMsr(X2_MSR_BASE + TO_X2(ICROffset), ((UINT64)High << 32) | Low);
}
/**
@@ -161,7 +161,7 @@ X2ApicIcrWrite(UINT32 Low, UINT32 High)
UINT64
X2ApicRead(UINT32 Offset)
{
- return __readmsr(X2_MSR_BASE + TO_X2(Offset));
+ return CpuReadMsr(X2_MSR_BASE + TO_X2(Offset));
}
/**
@@ -369,7 +369,7 @@ ApicInitialize()
PHYSICAL_ADDRESS PaApicBase;
PHYSICAL_ADDRESS PaIoApicBase;
- ApicBaseMSR = __readmsr(IA32_APIC_BASE);
+ ApicBaseMSR = CpuReadMsr(IA32_APIC_BASE);
if (!(ApicBaseMSR & (1 << 11)))
{
diff --git a/hyperdbg/hyperhv/code/features/CompatibilityChecks.c b/hyperdbg/hyperhv/code/features/CompatibilityChecks.c
index fcabc465..4238e4c6 100644
--- a/hyperdbg/hyperhv/code/features/CompatibilityChecks.c
+++ b/hyperdbg/hyperhv/code/features/CompatibilityChecks.c
@@ -73,7 +73,7 @@ CompatibilityCheckGetX86VirtualAddressWidth()
UINT32
CompatibilityCheckGetX86PhysicalAddressWidth()
{
- int Regs[4];
+ INT32 Regs[4];
CommonCpuidInstruction(CPUID_ADDR_WIDTH, 0, Regs);
@@ -83,6 +83,36 @@ CompatibilityCheckGetX86PhysicalAddressWidth()
return (Regs[0] & 0x0ff);
}
+/**
+ * @brief Check if the processor supports CET IBT
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+CompatibilityCheckCetShadowStackSupport()
+{
+ INT32 Regs[4];
+
+ CommonCpuidInstruction(7, 0, Regs);
+
+ return (BOOLEAN)((Regs[2] & (1 << 7)) != 0); // // CpuInfo[3] is ECX
+}
+
+/**
+ * @brief Check for Intel CET IBT support
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+CompatibilityCheckCetIbtSupport()
+{
+ INT32 Regs[4];
+
+ CommonCpuidInstruction(7, 0, Regs);
+
+ return (BOOLEAN)((Regs[3] & (1 << 20)) != 0); // CpuInfo[3] is EDX
+}
+
/**
* @brief Check for mode-based execution
*
@@ -96,7 +126,7 @@ CompatibilityCheckModeBasedExecution()
// the "enable PML" VM - execution control
//
UINT32 SecondaryProcBasedVmExecControls = HvAdjustControls(IA32_VMX_PROCBASED_CTLS2_MODE_BASED_EXECUTE_CONTROL_FOR_EPT_FLAG,
- IA32_VMX_PROCBASED_CTLS2);
+ IA32_VMX_PROCBASED_CTLS2);
if (SecondaryProcBasedVmExecControls & IA32_VMX_PROCBASED_CTLS2_MODE_BASED_EXECUTE_CONTROL_FOR_EPT_FLAG)
{
@@ -172,6 +202,16 @@ CompatibilityCheckPerformChecks()
//
g_CompatibilityCheck.ModeBasedExecutionSupport = CompatibilityCheckModeBasedExecution();
+ //
+ // Check Intel CET IBT support
+ //
+ g_CompatibilityCheck.CetIbtSupport = CompatibilityCheckCetIbtSupport();
+
+ //
+ // Check Intel CET shadow stack support
+ //
+ g_CompatibilityCheck.CetShadowStackSupport = CompatibilityCheckCetShadowStackSupport();
+
//
// Check PML support
//
diff --git a/hyperdbg/hyperhv/code/features/DirtyLogging.c b/hyperdbg/hyperhv/code/features/DirtyLogging.c
index 24d85521..dab2db41 100644
--- a/hyperdbg/hyperhv/code/features/DirtyLogging.c
+++ b/hyperdbg/hyperhv/code/features/DirtyLogging.c
@@ -33,9 +33,9 @@ DirtyLoggingInitialize()
//
//
- // When PML is active each write that sets a dirty flag for EPT also generates an entry in an inmemory log,
+ // When PML is active each write that sets a dirty flag for EPT also generates an entry in an in-memory log,
// reporting the guest-physical address of the write (aligned to 4 KBytes)
- // When the log is full, a VM exit occurs, notifying the VMM.A VMM can monitor the number of pages modified
+ // When the log is full, a VM exit occurs, notifying the VMM. A VMM can monitor the number of pages modified
// by each thread by specifying an available set of log entries
//
@@ -53,7 +53,7 @@ DirtyLoggingInitialize()
// the 4 - KByte aligned physical address of the page - modification log.The page modification
// log comprises 512 64 - bit entries
//
- for (size_t i = 0; i < ProcessorsCount; i++)
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
if (g_GuestState[i].PmlBufferAddress == NULL)
{
@@ -65,7 +65,7 @@ DirtyLoggingInitialize()
//
// Allocation failed
//
- for (size_t j = 0; j < ProcessorsCount; j++)
+ for (SIZE_T j = 0; j < ProcessorsCount; j++)
{
if (g_GuestState[j].PmlBufferAddress != NULL)
{
@@ -119,12 +119,12 @@ DirtyLoggingEnable(VIRTUAL_MACHINE_STATE * VCpu)
// LogInfo("PML Buffer Address = %llx", PmlPhysAddr);
- __vmx_vmwrite(VMCS_CTRL_PML_ADDRESS, PmlPhysAddr);
+ VmxVmwrite64(VMCS_CTRL_PML_ADDRESS, PmlPhysAddr);
//
// Clear the PML index
//
- __vmx_vmwrite(VMCS_GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
+ VmxVmwrite64(VMCS_GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
//
// If the "enable PML" VM-execution control is 1 and bit 6 of EPT pointer (EPTP)
@@ -160,12 +160,12 @@ DirtyLoggingDisable(VIRTUAL_MACHINE_STATE * VCpu)
//
// Clear the address
//
- __vmx_vmwrite(VMCS_CTRL_PML_ADDRESS, NULL64_ZERO);
+ VmxVmwrite64(VMCS_CTRL_PML_ADDRESS, NULL64_ZERO);
//
// Clear the PML index
//
- __vmx_vmwrite(VMCS_GUEST_PML_INDEX, 0x0);
+ VmxVmwrite64(VMCS_GUEST_PML_INDEX, 0x0);
//
// Disable PML Enable bit
@@ -196,7 +196,7 @@ DirtyLoggingUninitialize()
//
// Free the allocated pool buffers
//
- for (size_t i = 0; i < ProcessorsCount; i++)
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
if (g_GuestState[i].PmlBufferAddress != NULL)
{
@@ -218,7 +218,7 @@ DirtyLoggingHandlePageModificationLog(VIRTUAL_MACHINE_STATE * VCpu)
//
// The guest-physical address of the access is written to the page-modification log
//
- for (size_t i = 0; i < PML_ENTITY_NUM; i++)
+ for (SIZE_T i = 0; i < PML_ENTITY_NUM; i++)
{
LogInfo("Address : %llx", VCpu->PmlBufferAddress[i]);
}
@@ -284,7 +284,7 @@ DirtyLoggingFlushPmlBuffer(VIRTUAL_MACHINE_STATE * VCpu)
//
// reset PML index
//
- __vmx_vmwrite(VMCS_GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
+ VmxVmwrite64(VMCS_GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
return TRUE;
}
diff --git a/hyperdbg/hyperhv/code/hooks/ept-hook/EptHook.c b/hyperdbg/hyperhv/code/hooks/ept-hook/EptHook.c
index 2a52e020..dc2b4fd8 100644
--- a/hyperdbg/hyperhv/code/hooks/ept-hook/EptHook.c
+++ b/hyperdbg/hyperhv/code/hooks/ept-hook/EptHook.c
@@ -80,22 +80,22 @@ EptHookReservePreallocatedPoolsForEptHooks(UINT32 Count)
// Request pages to be allocated for converting 2MB to 4KB pages
// Each core needs its own splitting page-tables
//
- PoolManagerRequestAllocation(sizeof(VMM_EPT_DYNAMIC_SPLIT), Count * ProcessorsCount, SPLIT_2MB_PAGING_TO_4KB_PAGE);
+ PoolManagerCallbackRequestAllocation(sizeof(VMM_EPT_DYNAMIC_SPLIT), Count * ProcessorsCount, SPLIT_2MB_PAGING_TO_4KB_PAGE);
//
// Request pages to be allocated for paged hook details
//
- PoolManagerRequestAllocation(sizeof(EPT_HOOKED_PAGE_DETAIL), Count, TRACKING_HOOKED_PAGES);
+ PoolManagerCallbackRequestAllocation(sizeof(EPT_HOOKED_PAGE_DETAIL), Count, TRACKING_HOOKED_PAGES);
//
// Request pages to be allocated for Trampoline of Executable hooked pages
//
- PoolManagerRequestAllocation(MAX_EXEC_TRAMPOLINE_SIZE, Count, EXEC_TRAMPOLINE);
+ PoolManagerCallbackRequestAllocation(MAX_EXEC_TRAMPOLINE_SIZE, Count, EXEC_TRAMPOLINE);
//
// Request pages to be allocated for detour hooked pages details
//
- PoolManagerRequestAllocation(sizeof(HIDDEN_HOOKS_DETOUR_DETAILS), Count, DETOUR_HOOK_DETAILS);
+ PoolManagerCallbackRequestAllocation(sizeof(HIDDEN_HOOKS_DETOUR_DETAILS), Count, DETOUR_HOOK_DETAILS);
}
/**
@@ -120,16 +120,16 @@ EptHookAllocateExtraHookingPagesForMemoryMonitorsAndExecEptHooks(UINT32 Count)
// Request pages to be allocated for converting 2MB to 4KB pages
// Each core needs its own splitting page-tables
//
- PoolManagerRequestAllocation(sizeof(VMM_EPT_DYNAMIC_SPLIT),
- Count * ProcessorsCount,
- SPLIT_2MB_PAGING_TO_4KB_PAGE);
+ PoolManagerCallbackRequestAllocation(sizeof(VMM_EPT_DYNAMIC_SPLIT),
+ Count * ProcessorsCount,
+ SPLIT_2MB_PAGING_TO_4KB_PAGE);
//
// Request pages to be allocated for paged hook details
//
- PoolManagerRequestAllocation(sizeof(EPT_HOOKED_PAGE_DETAIL),
- Count,
- TRACKING_HOOKED_PAGES);
+ PoolManagerCallbackRequestAllocation(sizeof(EPT_HOOKED_PAGE_DETAIL),
+ Count,
+ TRACKING_HOOKED_PAGES);
}
/**
@@ -150,7 +150,6 @@ EptHookCreateHookPage(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
EPT_PML1_ENTRY ChangedEntry;
SIZE_T PhysicalBaseAddress;
PVOID VirtualTarget;
- PVOID TargetBuffer;
UINT64 TargetAddressInFakePageContent;
PEPT_PML1_ENTRY TargetPage;
PEPT_HOOKED_PAGE_DETAIL HookedPage;
@@ -200,7 +199,7 @@ EptHookCreateHookPage(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
//
// Save the detail of hooked page to keep track of it
//
- HookedPage = (EPT_HOOKED_PAGE_DETAIL *)PoolManagerRequestPool(TRACKING_HOOKED_PAGES, TRUE, sizeof(EPT_HOOKED_PAGE_DETAIL));
+ HookedPage = (EPT_HOOKED_PAGE_DETAIL *)PoolManagerCallbackRequestPool(TRACKING_HOOKED_PAGES, TRUE, sizeof(EPT_HOOKED_PAGE_DETAIL));
if (!HookedPage)
{
@@ -275,26 +274,18 @@ EptHookCreateHookPage(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
//
// Split the 2MB page-table of each core to 4KB page-table
//
- for (size_t i = 0; i < ProcessorsCount; i++)
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
//
- // Set target buffer, request buffer from pool manager,
- // we also need to allocate new page to replace the current page
+ // We need to split the large page to 4KB page using pre-allocated pools
//
- TargetBuffer = (PVOID)PoolManagerRequestPool(SPLIT_2MB_PAGING_TO_4KB_PAGE, TRUE, sizeof(VMM_EPT_DYNAMIC_SPLIT));
-
- if (!TargetBuffer)
+ if (!EptSplitLargePage(g_GuestState[i].EptPageTable, TRUE, PhysicalBaseAddress))
{
- PoolManagerFreePool((UINT64)HookedPage);
+ PoolManagerCallbackFreePool((UINT64)HookedPage);
- VmmCallbackSetLastError(DEBUGGER_ERROR_PRE_ALLOCATED_BUFFER_IS_EMPTY);
- return FALSE;
- }
-
- if (!EptSplitLargePage(g_GuestState[i].EptPageTable, TargetBuffer, PhysicalBaseAddress))
- {
- PoolManagerFreePool((UINT64)HookedPage);
- PoolManagerFreePool((UINT64)TargetBuffer); // Here also other previous pools should be specified, but we forget it for now
+ //
+ // Here also other previous pools should be specified, but we forget it for now
+ //
LogDebugInfo("Err, could not split page for the address : 0x%llx", PhysicalBaseAddress);
VmmCallbackSetLastError(DEBUGGER_ERROR_EPT_COULD_NOT_SPLIT_THE_LARGE_PAGE_TO_4KB_PAGES);
@@ -311,8 +302,11 @@ EptHookCreateHookPage(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
//
if (!TargetPage)
{
- PoolManagerFreePool((UINT64)HookedPage);
- PoolManagerFreePool((UINT64)TargetBuffer); // Here also other previous pools should be specified, but we forget it for now
+ PoolManagerCallbackFreePool((UINT64)HookedPage);
+
+ //
+ // Here also other previous pools should be specified, but we forget it for now
+ //
VmmCallbackSetLastError(DEBUGGER_ERROR_EPT_FAILED_TO_GET_PML1_ENTRY_OF_TARGET_ADDRESS);
return FALSE;
@@ -913,7 +907,7 @@ EptHookInstructionMemory(PEPT_HOOKED_PAGE_DETAIL Hook,
//
// Allocate some executable memory for the trampoline
//
- Hook->Trampoline = (CHAR *)PoolManagerRequestPool(EXEC_TRAMPOLINE, TRUE, MAX_EXEC_TRAMPOLINE_SIZE);
+ Hook->Trampoline = (CHAR *)PoolManagerCallbackRequestPool(EXEC_TRAMPOLINE, TRUE, MAX_EXEC_TRAMPOLINE_SIZE);
if (!Hook->Trampoline)
{
@@ -962,7 +956,7 @@ EptHookInstructionMemory(PEPT_HOOKED_PAGE_DETAIL Hook,
// function that changes the original function and if our structure is no ready after this
// function then we probably see BSOD on other cores
//
- DetourHookDetails = (HIDDEN_HOOKS_DETOUR_DETAILS *)PoolManagerRequestPool(DETOUR_HOOK_DETAILS, TRUE, sizeof(HIDDEN_HOOKS_DETOUR_DETAILS));
+ DetourHookDetails = (HIDDEN_HOOKS_DETOUR_DETAILS *)PoolManagerCallbackRequestPool(DETOUR_HOOK_DETAILS, TRUE, sizeof(HIDDEN_HOOKS_DETOUR_DETAILS));
DetourHookDetails->HookedFunctionAddress = TargetFunction;
DetourHookDetails->ReturnAddress = Hook->Trampoline;
@@ -1007,7 +1001,6 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
EPT_PML1_ENTRY ChangedEntry;
SIZE_T PhysicalBaseAddress;
PVOID AlignedTargetVaOrPa;
- PVOID TargetBuffer;
PVOID TargetAddress;
PVOID HookFunction;
UINT64 TargetAddressInSafeMemory;
@@ -1111,7 +1104,7 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
//
// Save the detail of hooked page to keep track of it
//
- HookedPage = (EPT_HOOKED_PAGE_DETAIL *)PoolManagerRequestPool(TRACKING_HOOKED_PAGES, TRUE, sizeof(EPT_HOOKED_PAGE_DETAIL));
+ HookedPage = (EPT_HOOKED_PAGE_DETAIL *)PoolManagerCallbackRequestPool(TRACKING_HOOKED_PAGES, TRUE, sizeof(EPT_HOOKED_PAGE_DETAIL));
if (!HookedPage)
{
@@ -1162,7 +1155,7 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
if (!HookedPage->StartOfTargetPhysicalAddress)
{
- PoolManagerFreePool((UINT64)HookedPage);
+ PoolManagerCallbackFreePool((UINT64)HookedPage);
VmmCallbackSetLastError(DEBUGGER_ERROR_INVALID_ADDRESS);
return FALSE;
@@ -1190,7 +1183,7 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
if (!HookedPage->EndOfTargetPhysicalAddress)
{
- PoolManagerFreePool((UINT64)HookedPage);
+ PoolManagerCallbackFreePool((UINT64)HookedPage);
VmmCallbackSetLastError(DEBUGGER_ERROR_INVALID_ADDRESS);
return FALSE;
@@ -1251,34 +1244,25 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
//
if (!EptHookInstructionMemory(HookedPage, ProcessCr3, TargetAddress, (PVOID)TargetAddressInSafeMemory, HookFunction))
{
- PoolManagerFreePool((UINT64)HookedPage);
+ PoolManagerCallbackFreePool((UINT64)HookedPage);
VmmCallbackSetLastError(DEBUGGER_ERROR_COULD_NOT_BUILD_THE_EPT_HOOK);
return FALSE;
}
}
- for (size_t i = 0; i < ProcessorsCount; i++)
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
//
- // Set target buffer, request buffer from pool manager,
- // we also need to allocate new page to replace the current page
+ // We need to split the large page to 4KB page using pre-allocated pools
//
- TargetBuffer = (PVOID)PoolManagerRequestPool(SPLIT_2MB_PAGING_TO_4KB_PAGE, TRUE, sizeof(VMM_EPT_DYNAMIC_SPLIT));
-
- if (!TargetBuffer)
+ if (!EptSplitLargePage(g_GuestState[i].EptPageTable, TRUE, PhysicalBaseAddress))
{
- PoolManagerFreePool((UINT64)HookedPage);
-
- VmmCallbackSetLastError(DEBUGGER_ERROR_PRE_ALLOCATED_BUFFER_IS_EMPTY);
- return FALSE;
- }
-
- if (!EptSplitLargePage(g_GuestState[i].EptPageTable, TargetBuffer, PhysicalBaseAddress))
- {
- PoolManagerFreePool((UINT64)HookedPage);
- PoolManagerFreePool((UINT64)TargetBuffer); // Here also other previous pools should be specified, but we forget it for now
+ PoolManagerCallbackFreePool((UINT64)HookedPage);
+ //
+ // Here also other previous pools should be specified, but we forget it for now
+ //
LogDebugInfo("Err, could not split page for the address : 0x%llx", PhysicalBaseAddress);
VmmCallbackSetLastError(DEBUGGER_ERROR_EPT_COULD_NOT_SPLIT_THE_LARGE_PAGE_TO_4KB_PAGES);
return FALSE;
@@ -1294,8 +1278,11 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
//
if (!TargetPage)
{
- PoolManagerFreePool((UINT64)HookedPage);
- PoolManagerFreePool((UINT64)TargetBuffer); // Here also other previous pools should be specified, but we forget it for now
+ PoolManagerCallbackFreePool((UINT64)HookedPage);
+
+ //
+ // Here also other previous pools should be specified, but we forget it for now
+ //
VmmCallbackSetLastError(DEBUGGER_ERROR_EPT_FAILED_TO_GET_PML1_ENTRY_OF_TARGET_ADDRESS);
return FALSE;
@@ -1875,7 +1862,7 @@ EptHookRemoveEntryAndFreePoolFromEptHook2sDetourList(UINT64 Address)
//
// Free the pool in next ioctl
//
- if (!PoolManagerFreePool((UINT64)CurrentHookedDetails))
+ if (!PoolManagerCallbackFreePool((UINT64)CurrentHookedDetails))
{
LogError("Err, something goes wrong, the pool not found in the list of previously allocated pools by pool manager");
}
@@ -1977,7 +1964,7 @@ EptHookUnHookSingleAddressDetoursAndMonitor(PEPT_HOOKED_PAGE_DETAIL
// we add the hooked entry to the list
// of pools that will be deallocated on next IOCTL
//
- if (!PoolManagerFreePool((UINT64)HookedEntry))
+ if (!PoolManagerCallbackFreePool((UINT64)HookedEntry))
{
LogError("Err, something goes wrong, the pool not found in the list of previously allocated pools by pool manager");
return FALSE;
@@ -2082,7 +2069,7 @@ EptHookUnHookSingleAddressHiddenBreakpoint(PEPT_HOOKED_PAGE_DETAIL H
// is the HookedEntry that should be remove (not the first one as it has the
// correct PreviousByte)
//
- for (size_t i = 0; i < HookedEntry->CountOfBreakpoints; i++)
+ for (SIZE_T i = 0; i < HookedEntry->CountOfBreakpoints; i++)
{
if (HookedEntry->BreakpointAddresses[i] == VirtualAddress)
{
@@ -2126,7 +2113,7 @@ EptHookUnHookSingleAddressHiddenBreakpoint(PEPT_HOOKED_PAGE_DETAIL H
// we add the hooked entry to the list
// of pools that will be deallocated on next IOCTL
//
- if (!PoolManagerFreePool((UINT64)HookedEntry))
+ if (!PoolManagerCallbackFreePool((UINT64)HookedEntry))
{
LogError("Err, something goes wrong, the pool not found in the list of previously allocated pools by pool manager");
}
@@ -2175,7 +2162,7 @@ EptHookUnHookSingleAddressHiddenBreakpoint(PEPT_HOOKED_PAGE_DETAIL H
// in the array, then we'll ignore setting the previous bit as previous bit might
// be modified for the previous command
//
- for (size_t j = 0; j < HookedEntry->CountOfBreakpoints; j++)
+ for (SIZE_T j = 0; j < HookedEntry->CountOfBreakpoints; j++)
{
if (HookedEntry->BreakpointAddresses[j] == VirtualAddress)
{
@@ -2202,7 +2189,7 @@ EptHookUnHookSingleAddressHiddenBreakpoint(PEPT_HOOKED_PAGE_DETAIL H
// all addresses to a lower array index (because one entry is
// missing and might) be in the middle of the array
//
- for (size_t j = i /* IndexToRemove */; j < HookedEntry->CountOfBreakpoints - 1; j++)
+ for (SIZE_T j = i /* IndexToRemove */; j < HookedEntry->CountOfBreakpoints - 1; j++)
{
HookedEntry->BreakpointAddresses[j] = HookedEntry->BreakpointAddresses[j + 1];
HookedEntry->PreviousBytesOnBreakpointAddresses[j] = HookedEntry->PreviousBytesOnBreakpointAddresses[j + 1];
@@ -2287,7 +2274,7 @@ EptHookPerformUnHookSingleAddress(UINT64 VirtualAdd
//
// It's a hidden breakpoint
//
- for (size_t i = 0; i < CurrEntity->CountOfBreakpoints; i++)
+ for (SIZE_T i = 0; i < CurrEntity->CountOfBreakpoints; i++)
{
if (CurrEntity->BreakpointAddresses[i] == VirtualAddress)
{
@@ -2498,7 +2485,7 @@ EptHookUnHookAll()
// As we are in vmx-root here, we add the hooked entry to the list
// of pools that will be deallocated on next IOCTL
//
- if (!PoolManagerFreePool((UINT64)CurrEntity))
+ if (!PoolManagerCallbackFreePool((UINT64)CurrEntity))
{
LogError("Err, something goes wrong, the pool not found in the list of previously allocated pools by pool manager");
}
diff --git a/hyperdbg/hyperhv/code/hooks/ept-hook/ExecTrap.c b/hyperdbg/hyperhv/code/hooks/ept-hook/ExecTrap.c
index a7154cab..8554064b 100644
--- a/hyperdbg/hyperhv/code/hooks/ept-hook/ExecTrap.c
+++ b/hyperdbg/hyperhv/code/hooks/ept-hook/ExecTrap.c
@@ -87,7 +87,7 @@ ExecTrapTraverseThroughOsPageTables(PVMM_EPT_PAGE_TABLE EptTable, CR3_TYPE Targe
return FALSE;
}
- for (size_t i = 0; i < 512; i++)
+ for (SIZE_T i = 0; i < 512; i++)
{
// LogInfo("Address of Cr3Va: %llx", Cr3Va);
@@ -125,7 +125,7 @@ ExecTrapTraverseThroughOsPageTables(PVMM_EPT_PAGE_TABLE EptTable, CR3_TYPE Targe
//
if (PdptVa != NULL)
{
- for (size_t j = 0; j < 512; j++)
+ for (SIZE_T j = 0; j < 512; j++)
{
// LogInfo("Address of PdptVa: %llx", PdptVa);
@@ -168,7 +168,7 @@ ExecTrapTraverseThroughOsPageTables(PVMM_EPT_PAGE_TABLE EptTable, CR3_TYPE Targe
//
if (PdVa != NULL)
{
- for (size_t k = 0; k < 512; k++)
+ for (SIZE_T k = 0; k < 512; k++)
{
// LogInfo("Address of PdVa: %llx", PdVa);
@@ -216,7 +216,7 @@ ExecTrapTraverseThroughOsPageTables(PVMM_EPT_PAGE_TABLE EptTable, CR3_TYPE Targe
//
if (PtVa != NULL)
{
- for (size_t l = 0; l < 512; l++)
+ for (SIZE_T l = 0; l < 512; l++)
{
// LogInfo("Address of PtVa: %llx", PtVa);
@@ -265,7 +265,7 @@ ExecTrapEnableExecuteOnlyPages(PVMM_EPT_PAGE_TABLE EptTable)
//
// Set execute access for PML4s
//
- for (size_t i = 0; i < VMM_EPT_PML4E_COUNT; i++)
+ for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT; i++)
{
//
// We only set the top-level PML4 for intercepting user-mode execution
@@ -276,7 +276,7 @@ ExecTrapEnableExecuteOnlyPages(PVMM_EPT_PAGE_TABLE EptTable)
//
// Set execute access for PML3s
//
- for (size_t i = 0; i < VMM_EPT_PML3E_COUNT; i++)
+ for (SIZE_T i = 0; i < VMM_EPT_PML3E_COUNT; i++)
{
EptTable->PML3[i].UserModeExecute = TRUE;
}
@@ -284,9 +284,9 @@ ExecTrapEnableExecuteOnlyPages(PVMM_EPT_PAGE_TABLE EptTable)
//
// Set execute access for PML2s
//
- for (size_t i = 0; i < VMM_EPT_PML3E_COUNT; i++)
+ for (SIZE_T i = 0; i < VMM_EPT_PML3E_COUNT; i++)
{
- for (size_t j = 0; j < VMM_EPT_PML2E_COUNT; j++)
+ for (SIZE_T j = 0; j < VMM_EPT_PML2E_COUNT; j++)
{
EptTable->PML2[i][j].UserModeExecute = TRUE;
}
@@ -295,7 +295,7 @@ ExecTrapEnableExecuteOnlyPages(PVMM_EPT_PAGE_TABLE EptTable)
//
// *** disallow read or write for certain memory only (not MMIO) EPTP pages ***
//
- for (size_t i = 0; i < MAX_PHYSICAL_RAM_RANGE_COUNT; i++)
+ for (SIZE_T i = 0; i < MAX_PHYSICAL_RAM_RANGE_COUNT; i++)
{
if (PhysicalRamRegions[i].RamPhysicalAddress != NULL64_ZERO)
{
@@ -482,7 +482,7 @@ ExecTrapRestoreToNormalEptp(VIRTUAL_MACHINE_STATE * VCpu)
//
// Change EPTP
//
- __vmx_vmwrite(VMCS_CTRL_EPT_POINTER, VCpu->EptPointer.AsUInt);
+ VmxVmwrite64(VMCS_CTRL_EPT_POINTER, VCpu->EptPointer.AsUInt);
//
// It's on normal EPTP
@@ -510,7 +510,7 @@ ExecTrapChangeToUserDisabledMbecEptp(VIRTUAL_MACHINE_STATE * VCpu)
//
// Set execute access for PML4s
//
- // for (size_t i = 0; i < VMM_EPT_PML4E_COUNT; i++)
+ // for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT; i++)
// {
VCpu->EptPageTable->PML4[0].UserModeExecute = FALSE;
@@ -551,7 +551,7 @@ ExecTrapChangeToKernelDisabledMbecEptp(VIRTUAL_MACHINE_STATE * VCpu)
//
// Set execute access for PML4s
//
- // for (size_t i = 0; i < VMM_EPT_PML4E_COUNT; i++)
+ // for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT; i++)
// {
VCpu->EptPageTable->PML4[0].UserModeExecute = TRUE;
@@ -592,7 +592,7 @@ ExecTrapChangeToNormalMbecEptp(VIRTUAL_MACHINE_STATE * VCpu)
//
// Set execute access for PML4s
//
- // for (size_t i = 0; i < VMM_EPT_PML4E_COUNT; i++)
+ // for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT; i++)
// {
VCpu->EptPageTable->PML4[0].UserModeExecute = TRUE;
diff --git a/hyperdbg/hyperhv/code/hooks/ept-hook/ModeBasedExecHook.c b/hyperdbg/hyperhv/code/hooks/ept-hook/ModeBasedExecHook.c
index b3265539..b8704a1f 100644
--- a/hyperdbg/hyperhv/code/hooks/ept-hook/ModeBasedExecHook.c
+++ b/hyperdbg/hyperhv/code/hooks/ept-hook/ModeBasedExecHook.c
@@ -25,7 +25,7 @@ ModeBasedExecHookDisableUserModeExecution(PVMM_EPT_PAGE_TABLE EptTable)
//
// Set execute access for PML4s
//
- for (size_t i = 0; i < VMM_EPT_PML4E_COUNT; i++)
+ for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT; i++)
{
//
// We only set the top-level PML4 for intercepting user-mode execution
@@ -36,7 +36,7 @@ ModeBasedExecHookDisableUserModeExecution(PVMM_EPT_PAGE_TABLE EptTable)
//
// Set execute access for PML3s
//
- for (size_t i = 0; i < VMM_EPT_PML3E_COUNT; i++)
+ for (SIZE_T i = 0; i < VMM_EPT_PML3E_COUNT; i++)
{
EptTable->PML3[i].UserModeExecute = TRUE;
}
@@ -44,9 +44,9 @@ ModeBasedExecHookDisableUserModeExecution(PVMM_EPT_PAGE_TABLE EptTable)
//
// Set execute access for PML2s
//
- for (size_t i = 0; i < VMM_EPT_PML3E_COUNT; i++)
+ for (SIZE_T i = 0; i < VMM_EPT_PML3E_COUNT; i++)
{
- for (size_t j = 0; j < VMM_EPT_PML2E_COUNT; j++)
+ for (SIZE_T j = 0; j < VMM_EPT_PML2E_COUNT; j++)
{
EptTable->PML2[i][j].UserModeExecute = TRUE;
}
@@ -77,7 +77,7 @@ ModeBasedExecHookDisableKernelModeExecution(PVMM_EPT_PAGE_TABLE EptTable)
//
// Set execute access for PML4s
//
- for (size_t i = 0; i < VMM_EPT_PML4E_COUNT; i++)
+ for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT; i++)
{
EptTable->PML4[i].UserModeExecute = TRUE;
@@ -90,7 +90,7 @@ ModeBasedExecHookDisableKernelModeExecution(PVMM_EPT_PAGE_TABLE EptTable)
//
// Set execute access for PML3s
//
- for (size_t i = 0; i < VMM_EPT_PML3E_COUNT; i++)
+ for (SIZE_T i = 0; i < VMM_EPT_PML3E_COUNT; i++)
{
EptTable->PML3[i].UserModeExecute = TRUE;
}
@@ -98,9 +98,9 @@ ModeBasedExecHookDisableKernelModeExecution(PVMM_EPT_PAGE_TABLE EptTable)
//
// Set execute access for PML2s
//
- for (size_t i = 0; i < VMM_EPT_PML3E_COUNT; i++)
+ for (SIZE_T i = 0; i < VMM_EPT_PML3E_COUNT; i++)
{
- for (size_t j = 0; j < VMM_EPT_PML2E_COUNT; j++)
+ for (SIZE_T j = 0; j < VMM_EPT_PML2E_COUNT; j++)
{
EptTable->PML2[i][j].UserModeExecute = TRUE;
}
@@ -123,7 +123,7 @@ ModeBasedExecHookEnableUsermodeExecution(PVMM_EPT_PAGE_TABLE EptTable)
//
// Set execute access for PML4s
//
- for (size_t i = 0; i < VMM_EPT_PML4E_COUNT; i++)
+ for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT; i++)
{
//
// We only set the top-level PML4 for intercepting user-mode execution
@@ -134,7 +134,7 @@ ModeBasedExecHookEnableUsermodeExecution(PVMM_EPT_PAGE_TABLE EptTable)
//
// Set execute access for PML3s
//
- for (size_t i = 0; i < VMM_EPT_PML3E_COUNT; i++)
+ for (SIZE_T i = 0; i < VMM_EPT_PML3E_COUNT; i++)
{
EptTable->PML3[i].UserModeExecute = TRUE;
}
@@ -142,9 +142,9 @@ ModeBasedExecHookEnableUsermodeExecution(PVMM_EPT_PAGE_TABLE EptTable)
//
// Set execute access for PML2s
//
- for (size_t i = 0; i < VMM_EPT_PML3E_COUNT; i++)
+ for (SIZE_T i = 0; i < VMM_EPT_PML3E_COUNT; i++)
{
- for (size_t j = 0; j < VMM_EPT_PML2E_COUNT; j++)
+ for (SIZE_T j = 0; j < VMM_EPT_PML2E_COUNT; j++)
{
EptTable->PML2[i][j].UserModeExecute = TRUE;
@@ -163,7 +163,7 @@ ModeBasedExecHookEnableUsermodeExecution(PVMM_EPT_PAGE_TABLE EptTable)
//
// Set execute access for PML1s
//
- for (size_t k = 0; k < VMM_EPT_PML1E_COUNT; k++)
+ for (SIZE_T k = 0; k < VMM_EPT_PML1E_COUNT; k++)
{
Pml1Entries[k].UserModeExecute = TRUE;
}
@@ -246,7 +246,7 @@ ModeBasedExecHookInitialize()
//
// Enable EPT user-mode execution bit for the target EPTP
//
- for (size_t i = 0; i < ProcessorsCount; i++)
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
ModeBasedExecHookEnableUsermodeExecution(g_GuestState[i].EptPageTable);
}
diff --git a/hyperdbg/hyperhv/code/hooks/syscall-hook/EferHook.c b/hyperdbg/hyperhv/code/hooks/syscall-hook/EferHook.c
index 5702a2d9..2a3d0bec 100644
--- a/hyperdbg/hyperhv/code/hooks/syscall-hook/EferHook.c
+++ b/hyperdbg/hyperhv/code/hooks/syscall-hook/EferHook.c
@@ -1,4 +1,4 @@
-/**
+/**
* @file EferHook.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Implementation of the functions related to the EFER Syscall Hook
@@ -38,7 +38,7 @@ SyscallHookConfigureEFER(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN EnableEFERSyscall
//
// Reading IA32_VMX_BASIC_MSR
//
- VmxBasicMsr.AsUInt = __readmsr(IA32_VMX_BASIC);
+ VmxBasicMsr.AsUInt = CpuReadMsr(IA32_VMX_BASIC);
//
// Read previous VM-Entry and VM-Exit controls
@@ -46,7 +46,7 @@ SyscallHookConfigureEFER(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN EnableEFERSyscall
VmxVmread32P(VMCS_CTRL_VMENTRY_CONTROLS, &VmEntryControls);
VmxVmread32P(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, &VmExitControls);
- MsrValue.AsUInt = __readmsr(IA32_EFER);
+ MsrValue.AsUInt = CpuReadMsr(IA32_EFER);
if (EnableEFERSyscallHook)
{
@@ -55,17 +55,17 @@ SyscallHookConfigureEFER(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN EnableEFERSyscall
//
// Set VM-Entry controls to load EFER
//
- __vmx_vmwrite(VMCS_CTRL_VMENTRY_CONTROLS, HvAdjustControls(VmEntryControls | VM_ENTRY_LOAD_IA32_EFER, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS));
+ VmxVmwrite32(VMCS_CTRL_VMENTRY_CONTROLS, HvAdjustControls(VmEntryControls | IA32_VMX_ENTRY_CTLS_LOAD_IA32_EFER_FLAG, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS));
//
// Set VM-Exit controls to save EFER
//
- __vmx_vmwrite(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, HvAdjustControls(VmExitControls | VM_EXIT_SAVE_IA32_EFER, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS));
+ VmxVmwrite32(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, HvAdjustControls(VmExitControls | IA32_VMX_EXIT_CTLS_SAVE_IA32_EFER_FLAG, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS));
//
// Set the GUEST EFER to use this value as the EFER
//
- __vmx_vmwrite(VMCS_GUEST_EFER, MsrValue.AsUInt);
+ VmxVmwrite64(VMCS_GUEST_EFER, MsrValue.AsUInt);
//
// also, we have to set exception bitmap to cause vm-exit on #UDs
@@ -79,23 +79,23 @@ SyscallHookConfigureEFER(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN EnableEFERSyscall
//
// Set VM-Entry controls to load EFER
//
- __vmx_vmwrite(VMCS_CTRL_VMENTRY_CONTROLS, HvAdjustControls(VmEntryControls & ~VM_ENTRY_LOAD_IA32_EFER, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS));
+ VmxVmwrite32(VMCS_CTRL_VMENTRY_CONTROLS, HvAdjustControls(VmEntryControls & ~IA32_VMX_ENTRY_CTLS_LOAD_IA32_EFER_FLAG, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS));
//
// Set VM-Exit controls to save EFER
//
- __vmx_vmwrite(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, HvAdjustControls(VmExitControls & ~VM_EXIT_SAVE_IA32_EFER, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS));
+ VmxVmwrite32(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, HvAdjustControls(VmExitControls & ~IA32_VMX_EXIT_CTLS_SAVE_IA32_EFER_FLAG, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS));
//
// Set the GUEST EFER to use this value as the EFER
//
- __vmx_vmwrite(VMCS_GUEST_EFER, MsrValue.AsUInt);
+ VmxVmwrite64(VMCS_GUEST_EFER, MsrValue.AsUInt);
//
// Because we're not save or load EFER on vm-exits so
// we have to set it manually
//
- __writemsr(IA32_EFER, MsrValue.AsUInt);
+ CpuWriteMsr(IA32_EFER, MsrValue.AsUInt);
//
// unset the exception to not cause vm-exit on #UDs
@@ -119,11 +119,13 @@ SyscallHookEmulateSYSCALL(VIRTUAL_MACHINE_STATE * VCpu)
UINT64 MsrValue;
UINT64 GuestRip;
UINT64 GuestRflags;
+ UINT64 Ssp;
+ IA32_U_CET_REGISTER UcetMsr;
//
// Reading guest's RIP
//
- __vmx_vmread(VMCS_GUEST_RIP, &GuestRip);
+ VmxVmread64P(VMCS_GUEST_RIP, &GuestRip);
//
// Reading instruction length
@@ -133,29 +135,47 @@ SyscallHookEmulateSYSCALL(VIRTUAL_MACHINE_STATE * VCpu)
//
// Reading guest's Rflags
//
- __vmx_vmread(VMCS_GUEST_RFLAGS, &GuestRflags);
+ VmxVmread64P(VMCS_GUEST_RFLAGS, &GuestRflags);
//
// Save the address of the instruction following SYSCALL into RCX and then
// load RIP from IA32_LSTAR.
//
- MsrValue = __readmsr(IA32_LSTAR);
+ MsrValue = CpuReadMsr(IA32_LSTAR);
VCpu->Regs->rcx = GuestRip + InstructionLength;
GuestRip = MsrValue;
- __vmx_vmwrite(VMCS_GUEST_RIP, GuestRip);
+ VmxVmwrite64(VMCS_GUEST_RIP, GuestRip);
//
// Save RFLAGS into R11 and then mask RFLAGS using IA32_FMASK
//
- MsrValue = __readmsr(IA32_FMASK);
+ MsrValue = CpuReadMsr(IA32_FMASK);
VCpu->Regs->r11 = GuestRflags;
GuestRflags &= ~(MsrValue | X86_FLAGS_RF);
- __vmx_vmwrite(VMCS_GUEST_RFLAGS, GuestRflags);
+ VmxVmwrite64(VMCS_GUEST_RFLAGS, GuestRflags);
+
+ //
+ // Perform emulation of Intel CET (Shadow stacks)
+ //
+ if (g_CompatibilityCheck.CetShadowStackSupport)
+ {
+ UcetMsr.AsUInt = CpuReadMsr(IA32_U_CET);
+
+ //
+ // If the shadow stack is enabled, we have to save the current
+ //
+ if (UcetMsr.ShStkEn)
+ {
+ VmxVmread64P(VMCS_GUEST_SSP, &Ssp);
+ CpuWriteMsr(IA32_PL3_SSP, Ssp);
+ VmxVmwrite64(VMCS_GUEST_SSP, 0);
+ }
+ }
//
// Load the CS and SS selectors with values derived from bits 47:32 of IA32_STAR
//
- MsrValue = __readmsr(IA32_STAR);
+ MsrValue = CpuReadMsr(IA32_STAR);
Cs.Selector = (UINT16)((MsrValue >> 32) & ~3); // STAR[47:32] & ~RPL3
Cs.Base = 0; // flat segment
Cs.Limit = (UINT32)~0; // 4GB limit
@@ -185,23 +205,42 @@ SyscallHookEmulateSYSRET(VIRTUAL_MACHINE_STATE * VCpu)
UINT64 MsrValue;
UINT64 GuestRip;
UINT64 GuestRflags;
+ UINT64 Ssp;
+ IA32_U_CET_REGISTER UcetMsr;
//
// Load RIP from RCX
//
GuestRip = VCpu->Regs->rcx;
- __vmx_vmwrite(VMCS_GUEST_RIP, GuestRip);
+ VmxVmwrite64(VMCS_GUEST_RIP, GuestRip);
//
// Load RFLAGS from R11. Clear RF, VM, reserved bits
//
GuestRflags = (VCpu->Regs->r11 & ~(X86_FLAGS_RF | X86_FLAGS_VM | X86_FLAGS_RESERVED_BITS)) | X86_FLAGS_FIXED;
- __vmx_vmwrite(VMCS_GUEST_RFLAGS, GuestRflags);
+ VmxVmwrite64(VMCS_GUEST_RFLAGS, GuestRflags);
+
+ //
+ // Restore user-mode SPP
+ //
+ if (g_CompatibilityCheck.CetShadowStackSupport)
+ {
+ UcetMsr.AsUInt = CpuReadMsr(IA32_U_CET);
+
+ //
+ // If the shadow stack is enabled, we have to restore the current
+ //
+ if (UcetMsr.ShStkEn)
+ {
+ Ssp = CpuReadMsr(IA32_PL3_SSP);
+ VmxVmwrite64(VMCS_GUEST_SSP, Ssp);
+ }
+ }
//
// SYSRET loads the CS and SS selectors with values derived from bits 63:48 of IA32_STAR
//
- MsrValue = __readmsr(IA32_STAR);
+ MsrValue = CpuReadMsr(IA32_STAR);
Cs.Selector = (UINT16)(((MsrValue >> 48) + 16) | 3); // (STAR[63:48]+16) | 3 (* RPL forced to 3 *)
Cs.Base = 0; // Flat segment
Cs.Limit = (UINT32)~0; // 4GB limit
@@ -234,7 +273,7 @@ SyscallHookHandleUD(VIRTUAL_MACHINE_STATE * VCpu)
//
// Reading guest's RIP
//
- __vmx_vmread(VMCS_GUEST_RIP, &Rip);
+ VmxVmread64P(VMCS_GUEST_RIP, &Rip);
if (g_IsUnsafeSyscallOrSysretHandling)
{
@@ -272,9 +311,9 @@ SyscallHookHandleUD(VIRTUAL_MACHINE_STATE * VCpu)
//
// if ((GuestCr3.Flags & PCID_MASK) != PCID_NONE)
- OriginalCr3 = __readcr3();
+ OriginalCr3 = CpuReadCr3();
- __writecr3(GuestCr3.Flags);
+ CpuWriteCr3(GuestCr3.Flags);
//
// Read the memory
@@ -313,7 +352,7 @@ SyscallHookHandleUD(VIRTUAL_MACHINE_STATE * VCpu)
return FALSE;
}
- __writecr3(OriginalCr3);
+ CpuWriteCr3(OriginalCr3);
if (InstructionBuffer[0] == 0x0F &&
InstructionBuffer[1] == 0x05)
diff --git a/hyperdbg/hyperhv/code/hooks/syscall-hook/SyscallCallback.c b/hyperdbg/hyperhv/code/hooks/syscall-hook/SyscallCallback.c
index 49c49b6c..9b348728 100644
--- a/hyperdbg/hyperhv/code/hooks/syscall-hook/SyscallCallback.c
+++ b/hyperdbg/hyperhv/code/hooks/syscall-hook/SyscallCallback.c
@@ -1,6 +1,7 @@
-/**
+/**
* @file SyscallCallback.c
* @author Sina Karvandi (sina@hyperdbg.org)
+ * @author jtaw5649
* @brief Implementation of the functions related to the callback for Syscall
* @details
*
@@ -30,7 +31,7 @@ SyscallCallbackInitialize()
//
// Insert EPT memory page hook for Windows system call handler, KiSystemCall64()
//
- Msr.Flags = __readmsr(IA32_LSTAR);
+ Msr.Flags = CpuReadMsr(IA32_LSTAR);
//
// We set the hook at the address of the system call handler + 3
@@ -75,6 +76,17 @@ SyscallCallbackInitialize()
}
}
+/**
+ * @brief Check whether the syscall callback is initialized
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+SyscallCallbackIsInitialized()
+{
+ return g_SyscallCallbackStatus;
+}
+
/**
* @brief Uninitialize the syscall callback
*
@@ -86,9 +98,14 @@ SyscallCallbackUninitialize()
if (g_SyscallCallbackStatus)
{
//
- // Disable the syscall callback
+ // Unset the EPT hook from the syscall entry before disabling state.
//
- g_SyscallCallbackStatus = FALSE;
+ if (!ConfigureEptHookUnHookSingleAddress((UINT64)g_SystemCallHookAddress, (UINT64)NULL, (UINT32)(ULONG_PTR)PsGetCurrentProcessId()))
+ {
+ LogInfo("Error while removing the EPT hook from windows syscall handler at address 0x%p", g_SystemCallHookAddress);
+
+ return FALSE;
+ }
//
// Unset the trap flags #DBs and #BPs for the syscall callback
@@ -100,15 +117,9 @@ SyscallCallbackUninitialize()
//
PlatformMemFreePool(g_SyscallCallbackTrapFlagState);
- MSR Msr = {0};
- Msr.Flags = __readmsr(IA32_LSTAR);
-
- if (!ConfigureEptHookUnHookSingleAddress((UINT64)(Msr.Flags + 3), (UINT64)NULL, (UINT32)(ULONG_PTR)PsGetCurrentProcessId()))
- {
- LogInfo("Error while removing the EPT hook from windows syscall handler at address 0x%p+3", Msr.Flags);
-
- return FALSE;
- }
+ g_SyscallCallbackTrapFlagState = NULL;
+ g_SystemCallHookAddress = NULL;
+ g_SyscallCallbackStatus = FALSE;
return TRUE;
}
diff --git a/hyperdbg/hyperhv/code/interface/Callback.c b/hyperdbg/hyperhv/code/interface/Callback.c
index 78da4bfc..3598a9fc 100644
--- a/hyperdbg/hyperhv/code/interface/Callback.c
+++ b/hyperdbg/hyperhv/code/interface/Callback.c
@@ -86,27 +86,6 @@ VmmCallbackVmcallHandler(UINT32 CoreId,
return g_Callbacks.VmmCallbackVmcallHandler(CoreId, VmcallNumber, OptionalParam1, OptionalParam2, OptionalParam3);
}
-/**
- * @brief routine callback to handle registered MTF
- *
- * @param CoreId
- *
- * @return VOID
- */
-VOID
-VmmCallbackRegisteredMtfHandler(UINT32 CoreId)
-{
- if (g_Callbacks.VmmCallbackRegisteredMtfHandler == NULL)
- {
- //
- // ignore it
- //
- return;
- }
-
- g_Callbacks.VmmCallbackRegisteredMtfHandler(CoreId);
-}
-
/**
* @brief routine callback to handle NMI requests
*
@@ -200,6 +179,47 @@ VmmCallbackUnhandledEptViolation(UINT32 CoreId,
return g_Callbacks.VmmCallbackCheckUnhandledEptViolations(CoreId, ViolationQualification, GuestPhysicalAddr);
}
+/**
+ * @brief routine callback to handle MTF callback
+ * @param CoreId
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+VmmCallbackHandleMtfCallback(UINT32 CoreId)
+{
+ if (g_Callbacks.VmmCallbackHandleMtfCallback == NULL)
+ {
+ //
+ // ignore it as it's not handled
+ //
+ return FALSE;
+ }
+
+ return g_Callbacks.VmmCallbackHandleMtfCallback(CoreId);
+}
+
+/**
+ * @brief routine callback to check if LBR is supported and get the LBR capacity if supported
+ *
+ * @param Capacity
+ * @param IsArchLbr
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTraceCallbackLbrIsSupported(UINT32 * Capacity, BOOLEAN * IsArchLbr)
+{
+ if (g_Callbacks.HyperTraceCallbackLbrIsSupported == NULL)
+ {
+ //
+ // ignore it as it's not handled
+ //
+ return FALSE;
+ }
+ return g_Callbacks.HyperTraceCallbackLbrIsSupported(Capacity, IsArchLbr);
+}
+
/**
* @brief routine callback to handle breakpoint exception
*
@@ -263,6 +283,110 @@ DebuggingCallbackCheckThreadInterception(UINT32 CoreId)
return g_Callbacks.DebuggingCallbackCheckThreadInterception(CoreId);
}
+/**
+ * @brief routine callback to trigger on clock and IPI events for checking process or thread change
+ *
+ * @param CoreId
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+DebuggingCallbackTriggerOnClockAndIpiEvents(UINT32 CoreId)
+{
+ if (g_Callbacks.DebuggingCallbackTriggerOnClockAndIpiEvents == NULL)
+ {
+ //
+ // not handled by user debugger
+ //
+ return FALSE;
+ }
+ return g_Callbacks.DebuggingCallbackTriggerOnClockAndIpiEvents(CoreId);
+}
+
+/**
+ * @brief routine callback to ignore handling mov 2 debug registers
+ * @param CoreId
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+DebuggingCallbackIgnoreHandlingMov2DebugRegs(UINT32 CoreId)
+{
+ if (g_Callbacks.DebuggingCallbackIgnoreHandlingMov2DebugRegs == NULL)
+ {
+ //
+ // not handled by user debugger
+ //
+ return FALSE;
+ }
+ return g_Callbacks.DebuggingCallbackIgnoreHandlingMov2DebugRegs(CoreId);
+}
+
+/**
+ * @brief routine callback to request pool allocation
+ *
+ * @param Size
+ * @param Count
+ * @param Intention The intention of the buffer (buffer tag)
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+PoolManagerCallbackRequestAllocation(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention)
+{
+ if (g_Callbacks.PoolManagerCallbackRequestAllocation == NULL)
+ {
+ //
+ // ignore it as it's not handled
+ //
+ return FALSE;
+ }
+ return g_Callbacks.PoolManagerCallbackRequestAllocation(Size, Count, Intention);
+}
+
+/**
+ * @brief routine callback to request pool
+ *
+ * @param Intention The intention why we need this pool for (buffer tag)
+ * @param RequestNewPool Create a request to allocate a new pool with the same size, next time
+ * that it's safe to allocate (this way we never ran out of pools for this "Intention")
+ * @param Size If the RequestNewPool is true the we should specify a size for the new pool
+ *
+ * @return UINT64 Returns a pool address or returns null if there was an error
+ */
+UINT64
+PoolManagerCallbackRequestPool(POOL_ALLOCATION_INTENTION Intention, BOOLEAN RequestNewPool, UINT32 Size)
+{
+ if (g_Callbacks.PoolManagerCallbackRequestPool == NULL)
+ {
+ //
+ // ignore it as it's not handled
+ //
+ return 0;
+ }
+ return g_Callbacks.PoolManagerCallbackRequestPool(Intention, RequestNewPool, Size);
+}
+
+/**
+ * @brief routine callback to free pool
+ *
+ * @param AddressToFree
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+PoolManagerCallbackFreePool(UINT64 AddressToFree)
+{
+ if (g_Callbacks.PoolManagerCallbackFreePool == NULL)
+ {
+ //
+ // ignore it as it's not handled
+ //
+ return FALSE;
+ }
+ return g_Callbacks.PoolManagerCallbackFreePool(AddressToFree);
+}
+
/**
* @brief routine callback to handle cr3 process change
*
diff --git a/hyperdbg/hyperhv/code/interface/Dispatch.c b/hyperdbg/hyperhv/code/interface/Dispatch.c
index c96a703f..3d7fdd9f 100644
--- a/hyperdbg/hyperhv/code/interface/Dispatch.c
+++ b/hyperdbg/hyperhv/code/interface/Dispatch.c
@@ -116,19 +116,6 @@ DispatchEventCpuid(VIRTUAL_MACHINE_STATE * VCpu)
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
BOOLEAN PostEventTriggerReq = FALSE;
- //
- // Check if attaching is for command dispatching in user debugger
- // or a regular CPUID
- //
- if (g_Callbacks.UdCheckForCommand != NULL && g_Callbacks.UdCheckForCommand())
- {
- //
- // It's a thread command for user debugger, no need to run the
- // actual CPUID instruction and change the registers
- //
- return;
- }
-
//
// As the context to event trigger, we send the eax before the cpuid
// so that the debugger can both read the eax as it's now changed by
@@ -183,6 +170,73 @@ DispatchEventCpuid(VIRTUAL_MACHINE_STATE * VCpu)
}
}
+/**
+ * @brief Handling debugger functions related to XSETBV events
+ *
+ * @param VCpu The virtual processor's state
+ * @return VOID
+ */
+VOID
+DispatchEventXsetbv(VIRTUAL_MACHINE_STATE * VCpu)
+{
+ UINT64 Context;
+ VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
+ BOOLEAN PostEventTriggerReq = FALSE;
+
+ //
+ // As the context to event trigger, we send the ecx (XCR index) before the xsetbv
+ // so that the debugger can both read the ecx as it contains the XCR index
+ // and also can modify the results
+ //
+ if (g_TriggerEventForXsetbvs)
+ {
+ //
+ // Adjusting the core context (save ECX for the debugger)
+ //
+ Context = VCpu->Regs->rcx & 0xffffffff;
+
+ //
+ // Triggering the pre-event
+ //
+ EventTriggerResult = VmmCallbackTriggerEvents(XSETBV_INSTRUCTION_EXECUTION,
+ VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
+ (PVOID)Context,
+ &PostEventTriggerReq,
+ VCpu->Regs);
+
+ //
+ // Check whether we need to short-circuiting event emulation or not
+ //
+ if (EventTriggerResult != VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
+ {
+ //
+ // Handle the XSETBV event in the case of triggering event
+ //
+ VmxHandleXsetbv(VCpu);
+ }
+
+ //
+ // Check for the post-event triggering needs
+ //
+ if (PostEventTriggerReq)
+ {
+ VmmCallbackTriggerEvents(XSETBV_INSTRUCTION_EXECUTION,
+ VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
+ (PVOID)Context,
+ NULL,
+ VCpu->Regs);
+ }
+ }
+ else
+ {
+ //
+ // Otherwise and if there is no event, we should handle the XSETBV
+ // normally
+ //
+ VmxHandleXsetbv(VCpu);
+ }
+}
+
/**
* @brief Handling debugger functions related to RDTSC/RDTSCP events
*
@@ -326,7 +380,7 @@ DispatchEventMode(VIRTUAL_MACHINE_STATE * VCpu, DEBUGGER_EVENT_MODE_TYPE TargetM
//
// If the thread is intercepted, we should not trigger the event
// Being here means that the thread should be handled by the user-mode debugger
- //
+ // ou
// LogInfo("Thread Id: %x, process Id: %x is intercepted by user-mode debugger - RIP: %llx",
// PsGetCurrentThreadId(),
@@ -657,13 +711,9 @@ DispatchEventMov2DebugRegs(VIRTUAL_MACHINE_STATE * VCpu)
BOOLEAN PostEventTriggerReq = FALSE;
//
- // Handle access to debug registers, if we should not ignore it, it is
- // because on detecting thread scheduling we ignore the hardware debug
- // registers modifications
+ // Check to see if we should ignore handling the mov 2 debug registers or not
//
- if (g_Callbacks.KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId != NULL &&
- g_Callbacks.KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId(VCpu->CoreId,
- DEBUGGER_THREAD_PROCESS_TRACING_INTERCEPT_CLOCK_DEBUG_REGISTER_INTERCEPTION))
+ if (DebuggingCallbackIgnoreHandlingMov2DebugRegs(VCpu->CoreId))
{
return;
}
@@ -796,7 +846,7 @@ DispatchEventException(VIRTUAL_MACHINE_STATE * VCpu)
// Check if we're waiting for an NMI on this core and if the guest is NOT in
// a instrument step-in ('i' command) routine
//
- if (!VCpu->RegisterBreakOnMtf &&
+ if (!VCpu->InstrumentationStepInMtf &&
VmxBroadcastNmiHandler(VCpu, FALSE))
{
return;
@@ -831,7 +881,7 @@ DispatchEventException(VIRTUAL_MACHINE_STATE * VCpu)
//
// So, we'll ignore the injection of Exception in this case
//
- if (VCpu->RegisterBreakOnMtf)
+ if (VCpu->InstrumentationStepInMtf)
{
return;
}
@@ -920,10 +970,11 @@ DispatchEventExternalInterrupts(VIRTUAL_MACHINE_STATE * VCpu)
if ((/* VCpu->CoreId == 0 && */ InterruptExit.Vector == CLOCK_INTERRUPT) ||
(VCpu->CoreId != 0 && InterruptExit.Vector == IPI_INTERRUPT))
{
- if (g_Callbacks.DebuggerCheckProcessOrThreadChange != NULL)
- {
- g_Callbacks.DebuggerCheckProcessOrThreadChange(VCpu->CoreId);
- }
+ //
+ // Calling the callback to trigger on clock and IPI events
+ // This is usually used for detecting changes to processes and threads
+ //
+ DebuggingCallbackTriggerOnClockAndIpiEvents(VCpu->CoreId);
}
//
diff --git a/hyperdbg/hyperhv/code/interface/Export.c b/hyperdbg/hyperhv/code/interface/Export.c
index 8332a473..f959d642 100644
--- a/hyperdbg/hyperhv/code/interface/Export.c
+++ b/hyperdbg/hyperhv/code/interface/Export.c
@@ -63,29 +63,42 @@ VmFuncChangeIgnoreOneMtfState(UINT32 CoreId, BOOLEAN Set)
}
/**
- * @brief Register for break in the case of an MTF
+ * @brief Set instrumentation step in MTF (used for single stepping with MTF)
*
* @param CoreId Target core's ID
*
* @return VOID
*/
VOID
-VmFuncRegisterMtfBreak(UINT32 CoreId)
+VmFuncSetInstrumentationStepInState(UINT32 CoreId)
{
- g_GuestState[CoreId].RegisterBreakOnMtf = TRUE;
+ g_GuestState[CoreId].InstrumentationStepInMtf = TRUE;
}
/**
- * @brief Unregister for break in the case of an MTF
+ * @brief Unset instrumentation step in MTF (used for single stepping with MTF)
*
* @param CoreId Target core's ID
*
* @return VOID
*/
VOID
-VmFuncUnRegisterMtfBreak(UINT32 CoreId)
+VmFuncUnsetInstrumentationStepInState(UINT32 CoreId)
{
- g_GuestState[CoreId].RegisterBreakOnMtf = FALSE;
+ g_GuestState[CoreId].InstrumentationStepInMtf = FALSE;
+}
+
+/**
+ * @brief Query instrumentation step in MTF state
+ *
+ * @param CoreId Target core's ID
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+VmFuncQueryInstrumentationStepInState(UINT32 CoreId)
+{
+ return g_GuestState[CoreId].InstrumentationStepInMtf;
}
/**
@@ -115,25 +128,57 @@ VmFuncSetRflagTrapFlag(BOOLEAN Set)
/**
* @brief Set LOAD DEBUG CONTROLS on Vm-entry controls
*
+ * @param CoreId target core id
* @param Set Set or unset
+ *
* @return VOID
*/
VOID
-VmFuncSetLoadDebugControls(BOOLEAN Set)
+VmFuncSetLoadDebugControls(UINT32 CoreId, BOOLEAN Set)
{
- HvSetLoadDebugControls(Set);
+ HvSetLoadDebugControls(&g_GuestState[CoreId], Set);
+}
+
+/**
+ * @brief Set LOAD GUEST IA32_LBR_CTL on Vm-entry controls
+ *
+ * @param CoreId target core id
+ * @param Set Set or unset
+ *
+ * @return VOID
+ */
+VOID
+VmFuncSetLoadGuestIa32LbrCtl(UINT32 CoreId, BOOLEAN Set)
+{
+ HvSetLoadGuestIa32LbrCtl(&g_GuestState[CoreId], Set);
}
/**
* @brief Set SAVE DEBUG CONTROLS on Vm-exit controls
*
+ * @param CoreId target core id
* @param Set Set or unset
+ *
* @return VOID
*/
VOID
-VmFuncSetSaveDebugControls(BOOLEAN Set)
+VmFuncSetSaveDebugControls(UINT32 CoreId, BOOLEAN Set)
{
- HvSetSaveDebugControls(Set);
+ HvSetSaveDebugControls(&g_GuestState[CoreId], Set);
+}
+
+/**
+ * @brief Set CLEAR GUEST IA32_LBR_CTL on Vm-exit controls
+ *
+ * @param CoreId target core id
+ * @param Set Set or unset
+ *
+ * @return VOID
+ */
+VOID
+VmFuncSetClearGuestIa32LbrCtl(UINT32 CoreId, BOOLEAN Set)
+{
+ HvSetClearGuestIa32LbrCtl(&g_GuestState[CoreId], Set);
}
/**
@@ -389,6 +434,211 @@ VmFuncSetRip(UINT64 Rip)
HvSetRip(Rip);
}
+/**
+ * @brief Get the guest state of IA32_DEBUGCTL
+ *
+ * @return UINT64
+ */
+UINT64
+VmFuncGetDebugctl()
+{
+ return HvGetDebugctl();
+}
+
+/**
+ * @brief Get the guest state of IA32_DEBUGCTL on the target core from VMCS
+ * using VMCALL
+ *
+ * @return UINT64
+ */
+UINT64
+VmFuncGetDebugctlVmcallOnTargetCore()
+{
+ return CrossVmcallGetDebugctlVmcallOnTargetCore();
+}
+
+/**
+ * @brief Get the guest state of IA32_LBR_CTL
+ *
+ * @return UINT64
+ */
+UINT64
+VmFuncGetGuestIa32LbrCtl()
+{
+ return HvGetGuestIa32LbrCtl();
+}
+
+/**
+ * @brief Get the guest state of IA32_LBR_CTL on the target core from VMCS
+ *
+ * @return UINT64
+ */
+UINT64
+VmFuncGetGuestIa32LbrCtlVmcallOnTargetCore()
+{
+ return CrossVmcallGetGuestIa32LbrCtlVmcallOnTargetCore();
+}
+
+/**
+ * @brief Check if CPU support save and load debug controls on exit and load entries
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+VmFuncCheckCpuSupportForSaveAndLoadDebugControls()
+{
+ return HvCheckCpuSupportForSaveAndLoadDebugControls();
+}
+
+/**
+ * @brief Check if CPU support load and clear guest IA32_LBR_CTL controls on VM-entry and VM-exit
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+VmFuncCheckCpuSupportForLoadAndClearGuestIa32LbrCtlControls()
+{
+ return HvCheckCpuSupportForLoadAndClearGuestIa32LbrCtlControls();
+}
+
+/**
+ * @brief Set the guest state of IA32_DEBUGCTL
+ * @param Value
+ *
+ * @return VOID
+ */
+VOID
+VmFuncSetDebugctl(UINT64 Value)
+{
+ HvSetDebugctl(Value);
+}
+
+/**
+ * @brief Set the guest state of IA32_DEBUGCTL on the target core from VMCS
+ * using VMCALL
+ * @param Value
+ *
+ * @return VOID
+ */
+VOID
+VmFuncSetDebugctlVmcallOnTargetCore(UINT64 Value)
+{
+ CrossVmcallSetDebugctlVmcallOnTargetCore(Value);
+}
+
+/**
+ * @brief Set the guest state of IA32_LBR_CTL
+ * @param Value
+ *
+ * @return VOID
+ */
+VOID
+VmFuncSetGuestIa32LbrCtl(UINT64 Value)
+{
+ HvSetGuestIa32LbrCtl(Value);
+}
+
+/**
+ * @brief Set the guest state of IA32_LBR_CTL on the target core from VMCS
+ * using VMCALL
+ * @param Value
+ *
+ * @return VOID
+ */
+VOID
+VmFuncSetGuestIa32LbrCtlVmcallOnTargetCore(UINT64 Value)
+{
+ CrossVmcallSetGuestIa32LbrCtlVmcallOnTargetCore(Value);
+}
+
+/**
+ * @brief Set the guest state of MSR_LEGACY_LBR_SELECT
+ * @param FilterOptions
+ *
+ * @return VOID
+ */
+VOID
+VmFuncSetLbrSelect(UINT64 FilterOptions)
+{
+ HvSetLbrSelect(FilterOptions);
+}
+
+/**
+ * @brief Set the guest state of MSR_LEGACY_LBR_SELECT on the target core from VMCS using VMCALL
+ * @param FilterOptions
+ *
+ * @return VOID
+ */
+VOID
+VmFuncSetLbrSelectVmcallOnTargetCore(UINT64 FilterOptions)
+{
+ CrossVmcallSetLbrSelectVmcallOnTargetCore(FilterOptions);
+}
+
+/**
+ * @brief Set LOAD DEBUG CONTROLS on VM-entry controls on the target core from VMCS using VMCALL
+ *
+ * @param Set Set or unset
+ *
+ * @return VOID
+ */
+VOID
+VmFuncSetLoadDebugControlsVmcallOnTargetCore(BOOLEAN Set)
+{
+ CrossVmcallSetLoadDebugControlsVmcallOnTargetCore(Set);
+}
+
+/**
+ * @brief Set LOAD GUEST IA32_LBR_CTL on VM-entry controls on the target core from VMCS using VMCALL
+ *
+ * @param Set Set or unset
+ *
+ * @return VOID
+ */
+VOID
+VmFuncSetLoadGuestIa32LbrCtlVmcallOnTargetCore(BOOLEAN Set)
+{
+ CrossVmcallSetLoadGuestIa32LbrCtlVmcallOnTargetCore(Set);
+}
+
+/**
+ * @brief Set SAVE DEBUG CONTROLS on VM-exit controls on the target core from VMCS using VMCALL
+ *
+ * @param Set Set or unset
+ *
+ * @return VOID
+ */
+VOID
+VmFuncSetSaveDebugControlsVmcallOnTargetCore(BOOLEAN Set)
+{
+ CrossVmcallSetSaveDebugControlsVmcallOnTargetCore(Set);
+}
+
+/**
+ * @brief Set CLEAR GUEST IA32_LBR_CTL on VM-exit controls on the target core from VMCS using VMCALL
+ *
+ * @param Set Set or unset
+ *
+ * @return VOID
+ */
+VOID
+VmFuncSetClearGuestIa32LbrCtlVmcallOnTargetCore(BOOLEAN Set)
+{
+ CrossVmcallSetClearGuestIa32LbrCtlVmcallOnTargetCore(Set);
+}
+
+/**
+ * @brief Set the guest state of DR7
+ * @param Value
+ *
+ * @return VOID
+ */
+VOID
+VmFuncSetDebugReg7(UINT64 Value)
+{
+ HvSetDebugReg7(Value);
+}
+
/**
* @brief Read guest's interruptibility state
*
@@ -589,6 +839,18 @@ VmFuncSetTriggerEventForCpuids(BOOLEAN Set)
g_TriggerEventForCpuids = Set;
}
+/**
+ * @brief Set trigger event for XSETBVs
+ *
+ * @param Set Set or unset the trigger
+ * @return VOID
+ */
+VOID
+VmFuncSetTriggerEventForXsetbvs(BOOLEAN Set)
+{
+ g_TriggerEventForXsetbvs = Set;
+}
+
/**
* @brief VMX-root compatible strlen
* @param s A pointer to the string
@@ -608,7 +870,7 @@ VmFuncVmxCompatibleStrlen(const CHAR * s)
* @return UINT32
*/
UINT32
-VmFuncVmxCompatibleWcslen(const wchar_t * s)
+VmFuncVmxCompatibleWcslen(const WCHAR * s)
{
return VmxCompatibleWcslen(s);
}
@@ -692,10 +954,10 @@ VmFuncEventInjectInterruption(UINT32 InterruptionType,
* @return NTSTATUS
*/
NTSTATUS
-VmFuncVmxVmcall(unsigned long long VmcallNumber,
- unsigned long long OptionalParam1,
- unsigned long long OptionalParam2,
- unsigned long long OptionalParam3)
+VmFuncVmxVmcall(UINT64 VmcallNumber,
+ UINT64 OptionalParam1,
+ UINT64 OptionalParam2,
+ UINT64 OptionalParam3)
{
return AsmVmxVmcall(VmcallNumber, OptionalParam1, OptionalParam2, OptionalParam3);
}
@@ -768,7 +1030,7 @@ VmFuncVmxCompatibleStrncmp(const CHAR * Address1, const CHAR * Address2, SIZE_T
* @return INT32
*/
INT32
-VmFuncVmxCompatibleWcscmp(const wchar_t * Address1, const wchar_t * Address2)
+VmFuncVmxCompatibleWcscmp(const WCHAR * Address1, const WCHAR * Address2)
{
return VmxCompatibleWcscmp(Address1, Address2, NULL_ZERO, FALSE);
}
@@ -782,7 +1044,7 @@ VmFuncVmxCompatibleWcscmp(const wchar_t * Address1, const wchar_t * Address2)
* @return INT32
*/
INT32
-VmFuncVmxCompatibleWcsncmp(const wchar_t * Address1, const wchar_t * Address2, SIZE_T Num)
+VmFuncVmxCompatibleWcsncmp(const WCHAR * Address1, const WCHAR * Address2, SIZE_T Num)
{
return VmxCompatibleWcscmp(Address1, Address2, Num, TRUE);
}
@@ -796,14 +1058,14 @@ VmFuncVmxCompatibleWcsncmp(const wchar_t * Address1, const wchar_t * Address2, S
* @return INT32
*/
INT32
-VmFuncVmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, size_t Count)
+VmFuncVmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, SIZE_T Count)
{
return VmxCompatibleMemcmp(Address1, Address2, Count);
}
/**
* @brief Enables MTF and adjust external interrupt state
- * @param UINT32 CoreId
+ * @param CoreId
*
* @return VOID
*/
@@ -816,7 +1078,7 @@ VmFuncEnableMtfAndChangeExternalInterruptState(UINT32 CoreId)
/**
* @brief Checks to enable and reinject previous interrupts
*
- * @param UINT32 CoreId
+ * @param CoreId
*
* @return VOID
*/
@@ -865,3 +1127,18 @@ VmFuncIdtQueryEntries(PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS IdtQueryReques
{
IdtEmulationQueryIdtEntriesRequest(IdtQueryRequest, ReadFromVmxRoot);
}
+
+/**
+ * @brief Perform actions related to System Management Interrupts (SMIs)
+ *
+ * @param SmiOperationRequest
+ * @param ApplyFromVmxRootMode
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+VmFuncSmmPerformSmiOperation(SMI_OPERATION_PACKETS * SmiOperationRequest,
+ BOOLEAN ApplyFromVmxRootMode)
+{
+ return SmmPerformSmiOperation(SmiOperationRequest, ApplyFromVmxRootMode);
+}
diff --git a/hyperdbg/hyperhv/code/interface/HyperEvade.c b/hyperdbg/hyperhv/code/interface/HyperEvade.c
index 0d640311..2fb263c8 100644
--- a/hyperdbg/hyperhv/code/interface/HyperEvade.c
+++ b/hyperdbg/hyperhv/code/interface/HyperEvade.c
@@ -1,6 +1,7 @@
/**
* @file HyperEvade.c
* @author Sina Karvandi (sina@hyperdbg.org)
+ * @author jtaw5649
* @brief Hyperevade function wrappers
* @details
*
@@ -24,6 +25,20 @@ BOOLEAN
TransparentHideDebuggerWrapper(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE * TransparentModeRequest)
{
HYPEREVADE_CALLBACKS HyperevadeCallbacks = {0};
+ UINT32 EvadeMask = TransparentModeRequest->EvadeMask;
+
+ if (EvadeMask == 0)
+ {
+ EvadeMask = TRANSPARENT_EVADE_MASK_DEFAULT;
+ }
+
+ if ((EvadeMask & ~TRANSPARENT_EVADE_MASK_ALL) != 0)
+ {
+ TransparentModeRequest->KernelStatus = DEBUGGER_ERROR_UNABLE_TO_HIDE_OR_UNHIDE_DEBUGGER;
+ return FALSE;
+ }
+
+ TransparentModeRequest->EvadeMask = EvadeMask;
//
// *** Fill the callbacks ***
@@ -38,6 +53,11 @@ TransparentHideDebuggerWrapper(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE * Tra
HyperevadeCallbacks.LogCallbackSendBuffer = g_Callbacks.LogCallbackSendBuffer;
HyperevadeCallbacks.LogCallbackCheckIfBufferIsFull = g_Callbacks.LogCallbackCheckIfBufferIsFull;
+ //
+ // HyperTrace callback(s)
+ //
+ HyperevadeCallbacks.HyperTraceLbrIsSupported = HyperTraceCallbackLbrIsSupported;
+
//
// Memory callbacks
//
@@ -61,20 +81,24 @@ TransparentHideDebuggerWrapper(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE * Tra
HyperevadeCallbacks.HvHandleTrapFlag = HvHandleTrapFlag;
HyperevadeCallbacks.EventInjectGeneralProtection = EventInjectGeneralProtection;
- //
- // Initialize the syscall callback mechanism from hypervisor
- //
- if (!SyscallCallbackInitialize())
- {
- TransparentModeRequest->KernelStatus = DEBUGGER_ERROR_UNABLE_TO_HIDE_OR_UNHIDE_DEBUGGER;
- return FALSE;
- }
-
//
// Call the hyperevade hide debugger function
//
if (TransparentHideDebugger(&HyperevadeCallbacks, TransparentModeRequest))
{
+ //
+ // Initialize the syscall callback mechanism from hypervisor after
+ // transparent-mode accepts the request as the active state.
+ //
+ if ((EvadeMask & TRANSPARENT_EVADE_MASK_SYSCALL_HOOK) != 0 && !SyscallCallbackInitialize())
+ {
+ TransparentUnhideDebugger();
+
+ TransparentModeRequest->KernelStatus = DEBUGGER_ERROR_UNABLE_TO_HIDE_OR_UNHIDE_DEBUGGER;
+ g_CheckForFootprints = FALSE;
+ return FALSE;
+ }
+
//
// Status is set within the transparent mode (hyperevade) module
//
@@ -100,10 +124,15 @@ TransparentHideDebuggerWrapper(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE * Tra
BOOLEAN
TransparentUnhideDebuggerWrapper(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE * TransparentModeRequest)
{
- //
- // Unitialize the syscall callback mechanism from hypervisor
- //
- SyscallCallbackUninitialize();
+ if (SyscallCallbackIsInitialized() && !SyscallCallbackUninitialize())
+ {
+ if (TransparentModeRequest != NULL)
+ {
+ TransparentModeRequest->KernelStatus = DEBUGGER_ERROR_UNABLE_TO_HIDE_OR_UNHIDE_DEBUGGER;
+ }
+
+ return FALSE;
+ }
if (TransparentUnhideDebugger())
{
diff --git a/hyperdbg/hyperhv/code/memory/AddressCheck.c b/hyperdbg/hyperhv/code/memory/AddressCheck.c
index c2d50a65..4513ce01 100644
--- a/hyperdbg/hyperhv/code/memory/AddressCheck.c
+++ b/hyperdbg/hyperhv/code/memory/AddressCheck.c
@@ -17,7 +17,7 @@
*
* @param Address Address to check
*
- * @param UINT32 ProcId
+ * @param ProcId
* @return BOOLEAN Returns true if the address is valid; otherwise, false
*/
BOOLEAN
@@ -192,8 +192,8 @@ CheckAccessValidityAndSafetyWrapper(UINT64 TargetAddress, UINT32 Size, UINT32 Pr
//
// Move to new cr3
//
- OriginalCr3 = __readcr3();
- __writecr3(GuestCr3.Flags);
+ OriginalCr3 = CpuReadCr3();
+ CpuWriteCr3(GuestCr3.Flags);
//
// We'll only check address with TSX if the address is a kernel-mode
@@ -210,7 +210,7 @@ CheckAccessValidityAndSafetyWrapper(UINT64 TargetAddress, UINT32 Size, UINT32 Pr
// UINT64 AlignedPage = (UINT64)PAGE_ALIGN(TargetAddress);
// UINT64 PageCount = ((TargetAddress - AlignedPage) + Size) / PAGE_SIZE;
//
- // for (size_t i = 0; i <= PageCount; i++)
+ // for (SIZE_T i = 0; i <= PageCount; i++)
// {
// UINT64 CheckAddr = AlignedPage + (PAGE_SIZE * i);
// if (!CheckAddressValidityUsingTsx(CheckAddr))
@@ -301,7 +301,7 @@ RestoreCr3:
//
// Move back to original cr3
//
- __writecr3(OriginalCr3);
+ CpuWriteCr3(OriginalCr3);
Return:
return Result;
diff --git a/hyperdbg/hyperhv/code/memory/Layout.c b/hyperdbg/hyperhv/code/memory/Layout.c
index 9631f749..a7b69139 100644
--- a/hyperdbg/hyperhv/code/memory/Layout.c
+++ b/hyperdbg/hyperhv/code/memory/Layout.c
@@ -76,7 +76,7 @@ LayoutGetExactGuestProcessCr3()
{
CR3_TYPE GuestCr3 = {0};
- __vmx_vmread(VMCS_GUEST_CR3, &GuestCr3.Flags);
+ VmxVmread64P(VMCS_GUEST_CR3, &GuestCr3.Flags);
return GuestCr3;
}
diff --git a/hyperdbg/hyperhv/code/memory/MemoryMapper.c b/hyperdbg/hyperhv/code/memory/MemoryMapper.c
index e5c928b7..f95b1e13 100644
--- a/hyperdbg/hyperhv/code/memory/MemoryMapper.c
+++ b/hyperdbg/hyperhv/code/memory/MemoryMapper.c
@@ -63,7 +63,7 @@ MemoryMapperGetPteVa(PVOID Va, PAGING_LEVEL Level)
//
// Read the current cr3
//
- Cr3.Flags = __readcr3();
+ Cr3.Flags = CpuReadCr3();
//
// Call the wrapper
@@ -287,7 +287,7 @@ MemoryMapperSetExecuteDisableToPteOnTargetProcess(PVOID Va, BOOLEAN Set)
//
// Invalidate the TLB
//
- __invlpg(Va);
+ CpuInvlpg(Va);
//
// Restore the original process
@@ -685,7 +685,7 @@ MemoryMapperInitialize()
//
// Set the core's id and initialize memory mapper
//
- for (size_t i = 0; i < ProcessorsCount; i++)
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
//
// *** Initialize memory mapper for each core ***
@@ -717,7 +717,7 @@ MemoryMapperUninitialize()
{
ULONG ProcessorsCount = KeQueryActiveProcessorCount(0);
- for (size_t i = 0; i < ProcessorsCount; i++)
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
//
// Unmap and free the reserved buffer
@@ -804,7 +804,7 @@ MemoryMapperReadMemorySafeByPte(PHYSICAL_ADDRESS PaAddressToRead,
// because it will be automatically invalidated by the top hypervisor, however,
// we should use invlpg in physical computers as it won't invalidate it automatically
//
- __invlpg(Va);
+ CpuInvlpg(Va);
//
// Also invalidate it from vpids if we're in vmx root
@@ -888,7 +888,7 @@ MemoryMapperWriteMemorySafeByPte(PVOID SourceVA,
//
// Finally, invalidate the caches for the virtual address.
//
- __invlpg(Va);
+ CpuInvlpg(Va);
//
// Also invalidate it from vpids if we're in vmx root
@@ -1180,8 +1180,8 @@ MemoryMapperReadMemorySafeOnTargetProcess(UINT64 VaAddressToRead, PVOID BufferTo
//
// Move to new cr3
//
- OriginalCr3.Flags = __readcr3();
- __writecr3(GuestCr3.Flags);
+ OriginalCr3.Flags = CpuReadCr3();
+ CpuWriteCr3(GuestCr3.Flags);
//
// Read target memory
@@ -1191,7 +1191,7 @@ MemoryMapperReadMemorySafeOnTargetProcess(UINT64 VaAddressToRead, PVOID BufferTo
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return Result;
}
@@ -1225,8 +1225,8 @@ MemoryMapperWriteMemorySafeOnTargetProcess(UINT64 Destination, PVOID Source, SIZ
//
// Move to new cr3
//
- OriginalCr3.Flags = __readcr3();
- __writecr3(GuestCr3.Flags);
+ OriginalCr3.Flags = CpuReadCr3();
+ CpuWriteCr3(GuestCr3.Flags);
//
// Write target memory
@@ -1236,7 +1236,7 @@ MemoryMapperWriteMemorySafeOnTargetProcess(UINT64 Destination, PVOID Source, SIZ
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return Result;
}
@@ -1720,7 +1720,7 @@ MemoryMapperMapPhysicalAddressToPte(PHYSICAL_ADDRESS PhysicalAddress,
// because it will be automatically invalidated by the top hypervisor, however,
// we should use invlpg in physical computers as it won't invalidate it automatically
//
- __invlpg(TargetProcessVirtualAddress);
+ CpuInvlpg(TargetProcessVirtualAddress);
//
// Restore the original process
diff --git a/hyperdbg/hyperhv/code/memory/Segmentation.c b/hyperdbg/hyperhv/code/memory/Segmentation.c
index 21e2f9c1..26b2f4aa 100644
--- a/hyperdbg/hyperhv/code/memory/Segmentation.c
+++ b/hyperdbg/hyperhv/code/memory/Segmentation.c
@@ -1,4 +1,4 @@
-/**
+/**
* @file Segmentation.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Functions for handling memory segmentations
@@ -47,7 +47,7 @@ SegmentGetDescriptor(PUCHAR GdtBase,
Descriptor32 = &DescriptorTable32[SegSelector.Index];
SegmentSelector->Selector = Selector;
- SegmentSelector->Limit = __segmentlimit(Selector);
+ SegmentSelector->Limit = CpuSegmentLimit(Selector);
SegmentSelector->Base = ((UINT64)Descriptor32->BaseAddressLow | (UINT64)Descriptor32->BaseAddressMiddle << 16 | (UINT64)Descriptor32->BaseAddressHigh << 24);
SegmentSelector->Attributes.AsUInt = (AsmGetAccessRights(Selector) >> 8);
diff --git a/hyperdbg/hyperhv/code/memory/SwitchLayout.c b/hyperdbg/hyperhv/code/memory/SwitchLayout.c
index 6865fca4..b02ba8f2 100644
--- a/hyperdbg/hyperhv/code/memory/SwitchLayout.c
+++ b/hyperdbg/hyperhv/code/memory/SwitchLayout.c
@@ -1,4 +1,4 @@
-/**
+/**
* @file SwitchLayout.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Functions for switching memory layouts
@@ -46,12 +46,12 @@ SwitchToProcessMemoryLayout(UINT32 ProcessId)
//
// Read the current cr3
//
- CurrentProcessCr3.Flags = __readcr3();
+ CurrentProcessCr3.Flags = CpuReadCr3();
//
// Change to a new cr3 (of target process)
//
- __writecr3(GuestCr3);
+ CpuWriteCr3(GuestCr3);
ObDereferenceObject(TargetEprocess);
@@ -77,12 +77,12 @@ SwitchToCurrentProcessMemoryLayout()
//
// Read the current cr3
//
- CurrentProcessCr3.Flags = __readcr3();
+ CurrentProcessCr3.Flags = CpuReadCr3();
//
// Change to a new cr3 (of target process)
//
- __writecr3(GuestCr3.Flags);
+ CpuWriteCr3(GuestCr3.Flags);
return CurrentProcessCr3;
}
@@ -103,12 +103,12 @@ SwitchToProcessMemoryLayoutByCr3(CR3_TYPE TargetCr3)
//
// Read the current cr3
//
- CurrentProcessCr3.Flags = __readcr3();
+ CurrentProcessCr3.Flags = CpuReadCr3();
//
// Change to a new cr3 (of target process)
//
- __writecr3(TargetCr3.Flags);
+ CpuWriteCr3(TargetCr3.Flags);
return CurrentProcessCr3;
}
@@ -127,5 +127,5 @@ SwitchToPreviousProcess(CR3_TYPE PreviousProcess)
//
// Restore the original cr3
//
- __writecr3(PreviousProcess.Flags);
+ CpuWriteCr3(PreviousProcess.Flags);
}
diff --git a/hyperdbg/hyperhv/code/processor/Idt.c b/hyperdbg/hyperhv/code/processor/Idt.c
index 2cc23a44..989d3763 100644
--- a/hyperdbg/hyperhv/code/processor/Idt.c
+++ b/hyperdbg/hyperhv/code/processor/Idt.c
@@ -1,4 +1,4 @@
-/**
+/**
* @file Idt.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Routines for Interrupt Descriptor Table
@@ -21,7 +21,7 @@ VOID
IdtDumpInterruptEntries()
{
KDESCRIPTOR64 descr;
- __sidt(&descr.Limit);
+ CpuSidt(&descr.Limit);
ULONG n = (descr.Limit + 1) / sizeof(KIDTENTRY64);
diff --git a/hyperdbg/hyperhv/code/processor/Smm.c b/hyperdbg/hyperhv/code/processor/Smm.c
new file mode 100644
index 00000000..d025ab31
--- /dev/null
+++ b/hyperdbg/hyperhv/code/processor/Smm.c
@@ -0,0 +1,140 @@
+/**
+ * @file Smm.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Routines for operations related to System Management Mode (SMM)
+ * @details
+ *
+ * @version 0.15
+ * @date 2025-08-02
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/*
+ * @brief Read the count of System Management Interrupts (SMIs)
+ *
+ * @return UINT64
+ */
+UINT64
+SmmReadSmiCount()
+{
+ UINT64 SmiCount = 0;
+
+ //
+ // Read the SMI count from MSR
+ //
+ SmiCount = (UINT64)CpuReadMsr(MSR_SMI_COUNT);
+
+ return SmiCount;
+}
+
+/*
+ * @brief Trigger a Power SMI
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+SmmTriggerPowerSmi()
+{
+ UINT8 SmmResponse = 0;
+
+ //
+ // check the initial value received from 0xB3 port
+ //
+ SmmResponse = CpuIoInByte(0xb2);
+
+ //
+ // write to 0xB2 port to cause SMI
+ //
+ CpuIoOutByte(0xb2, SMI_TRIGGER_POWER_VALUE);
+
+ //
+ // Check the response in port 0xB3
+ //
+ SmmResponse = CpuIoInByte(0xb2);
+
+ if (SmmResponse == SMI_TRIGGER_POWER_VALUE)
+ {
+ //
+ // If the response is SMI_TRIGGER_POWER_VALUE, it means the SMI was triggered successfully
+ //
+ return TRUE;
+ }
+ else
+ {
+ //
+ // If the response is not SMI_TRIGGER_POWER_VALUE, it means the SMI was not triggered successfully
+ //
+ return FALSE;
+ }
+}
+
+/**
+ * @brief Perform actions related to System Management Interrupts (SMIs)
+ *
+ * @param SmiOperationRequest
+ * @param ApplyFromVmxRootMode
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+SmmPerformSmiOperation(SMI_OPERATION_PACKETS * SmiOperationRequest, BOOLEAN ApplyFromVmxRootMode)
+{
+ BOOLEAN Status = FALSE;
+
+ UNREFERENCED_PARAMETER(ApplyFromVmxRootMode);
+
+ //
+ // Check the SMI operation type and perform the corresponding action
+ //
+ switch (SmiOperationRequest->SmiOperationType)
+ {
+ case SMI_OPERATION_REQUEST_TYPE_READ_COUNT:
+
+ //
+ // Read the SMI count from the MSR
+ //
+ SmiOperationRequest->SmiCount = SmmReadSmiCount();
+
+ Status = TRUE;
+ break;
+
+ case SMI_OPERATION_REQUEST_TYPE_TRIGGER_POWER_SMI:
+
+ if (SmmTriggerPowerSmi())
+ {
+ //
+ // If the SMI was triggered successfully
+ //
+ Status = TRUE;
+ }
+ else
+ {
+ //
+ // If the SMI was not triggered successfully, set error status
+ //
+ SmiOperationRequest->KernelStatus = DEBUGGER_ERROR_UNABLE_TO_TRIGGER_SMI;
+ }
+
+ break;
+
+ default:
+
+ Status = FALSE;
+ SmiOperationRequest->KernelStatus = DEBUGGER_ERROR_INVALID_SMI_OPERATION_PARAMETERS;
+
+ break;
+ }
+
+ //
+ // Set the status of the SMI operation request
+ //
+ if (Status)
+ {
+ SmiOperationRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ }
+
+ return Status;
+}
diff --git a/hyperdbg/hyperhv/code/vmm/ept/Ept.c b/hyperdbg/hyperhv/code/vmm/ept/Ept.c
index a7788721..4295aca0 100644
--- a/hyperdbg/hyperhv/code/vmm/ept/Ept.c
+++ b/hyperdbg/hyperhv/code/vmm/ept/Ept.c
@@ -23,9 +23,9 @@ EptCheckFeatures(VOID)
{
IA32_VMX_EPT_VPID_CAP_REGISTER VpidRegister;
IA32_MTRR_DEF_TYPE_REGISTER MTRRDefType;
-
- VpidRegister.AsUInt = __readmsr(IA32_VMX_EPT_VPID_CAP);
- MTRRDefType.AsUInt = __readmsr(IA32_MTRR_DEF_TYPE);
+ g_IsVpidSupported = FALSE;
+ VpidRegister.AsUInt = CpuReadMsr(IA32_VMX_EPT_VPID_CAP);
+ MTRRDefType.AsUInt = CpuReadMsr(IA32_MTRR_DEF_TYPE);
if (!VpidRegister.PageWalkLength4 || !VpidRegister.MemoryTypeWriteBack || !VpidRegister.Pde2MbPages)
{
@@ -37,6 +37,17 @@ EptCheckFeatures(VOID)
LogDebugInfo("The processor doesn't report advanced VM-exit information for EPT violations");
}
+ if (VpidRegister.Invvpid &&
+ VpidRegister.InvvpidAllContexts &&
+ VpidRegister.InvvpidIndividualAddress &&
+ VpidRegister.InvvpidSingleContext &&
+ VpidRegister.InvvpidSingleContextRetainGlobals &&
+ !g_IsTopLevelHypervisorHyperV)
+ {
+ g_IsVpidSupported = TRUE;
+ LogDebugInfo("The processor supports VPID");
+ }
+
if (!VpidRegister.ExecuteOnlyPages)
{
g_CompatibilityCheck.ExecuteOnlySupport = FALSE;
@@ -163,8 +174,8 @@ EptBuildMtrrMap(VOID)
UINT32 CurrentRegister;
UINT32 NumberOfBitsInMask;
- MTRRCap.AsUInt = __readmsr(IA32_MTRR_CAPABILITIES);
- MTRRDefType.AsUInt = __readmsr(IA32_MTRR_DEF_TYPE);
+ MTRRCap.AsUInt = CpuReadMsr(IA32_MTRR_CAPABILITIES);
+ MTRRDefType.AsUInt = CpuReadMsr(IA32_MTRR_DEF_TYPE);
//
// All MTRRs are disabled when clear, and the
@@ -200,8 +211,8 @@ EptBuildMtrrMap(VOID)
{
const UINT32 K64Base = 0x0;
const UINT32 K64Size = 0x10000;
- IA32_MTRR_FIXED_RANGE_TYPE K64Types = {__readmsr(IA32_MTRR_FIX64K_00000)};
- for (unsigned int i = 0; i < 8; i++)
+ IA32_MTRR_FIXED_RANGE_TYPE K64Types = {CpuReadMsr(IA32_MTRR_FIX64K_00000)};
+ for (UINT32 i = 0; i < 8; i++)
{
Descriptor = &g_EptState->MemoryRanges[g_EptState->NumberOfEnabledMemoryRanges++];
Descriptor->MemoryType = K64Types.s.Types[i];
@@ -212,10 +223,10 @@ EptBuildMtrrMap(VOID)
const UINT32 K16Base = 0x80000;
const UINT32 K16Size = 0x4000;
- for (unsigned int i = 0; i < 2; i++)
+ for (UINT32 i = 0; i < 2; i++)
{
- IA32_MTRR_FIXED_RANGE_TYPE K16Types = {__readmsr(IA32_MTRR_FIX16K_80000 + i)};
- for (unsigned int j = 0; j < 8; j++)
+ IA32_MTRR_FIXED_RANGE_TYPE K16Types = {CpuReadMsr(IA32_MTRR_FIX16K_80000 + i)};
+ for (UINT32 j = 0; j < 8; j++)
{
Descriptor = &g_EptState->MemoryRanges[g_EptState->NumberOfEnabledMemoryRanges++];
Descriptor->MemoryType = K16Types.s.Types[j];
@@ -227,11 +238,11 @@ EptBuildMtrrMap(VOID)
const UINT32 K4Base = 0xC0000;
const UINT32 K4Size = 0x1000;
- for (unsigned int i = 0; i < 8; i++)
+ for (UINT32 i = 0; i < 8; i++)
{
- IA32_MTRR_FIXED_RANGE_TYPE K4Types = {__readmsr(IA32_MTRR_FIX4K_C0000 + i)};
+ IA32_MTRR_FIXED_RANGE_TYPE K4Types = {CpuReadMsr(IA32_MTRR_FIX4K_C0000 + i)};
- for (unsigned int j = 0; j < 8; j++)
+ for (UINT32 j = 0; j < 8; j++)
{
Descriptor = &g_EptState->MemoryRanges[g_EptState->NumberOfEnabledMemoryRanges++];
Descriptor->MemoryType = K4Types.s.Types[j];
@@ -247,8 +258,8 @@ EptBuildMtrrMap(VOID)
//
// For each dynamic register pair
//
- CurrentPhysBase.AsUInt = __readmsr(IA32_MTRR_PHYSBASE0 + (CurrentRegister * 2));
- CurrentPhysMask.AsUInt = __readmsr(IA32_MTRR_PHYSMASK0 + (CurrentRegister * 2));
+ CurrentPhysBase.AsUInt = CpuReadMsr(IA32_MTRR_PHYSBASE0 + (CurrentRegister * 2));
+ CurrentPhysMask.AsUInt = CpuReadMsr(IA32_MTRR_PHYSMASK0 + (CurrentRegister * 2));
//
// Is the range enabled?
@@ -270,7 +281,7 @@ EptBuildMtrrMap(VOID)
// Calculate the total size of the range
// The lowest bit of the mask that is set to 1 specifies the size of the range
//
- _BitScanForward64((ULONG *)&NumberOfBitsInMask, CurrentPhysMask.PageFrameNumber * PAGE_SIZE);
+ CpuBitScanForward64((ULONG *)&NumberOfBitsInMask, CurrentPhysMask.PageFrameNumber * PAGE_SIZE);
//
// Size of the range in bytes + Base Address
@@ -293,6 +304,28 @@ EptBuildMtrrMap(VOID)
return TRUE;
}
+/**
+ * @brief Resolve the split PML1 VA that belongs to a given PML2 entry
+ *
+ * @param EptPageTable The EPT page table
+ * @param TargetEntry The target PML2 entry
+ * @return PEPT_PML1_ENTRY Returns base VA of PML1 page, or NULL if not tracked
+ */
+_Must_inspect_result_
+static PEPT_PML1_ENTRY
+EptGetSplitPml1VaByPml2Entry(_In_ PVMM_EPT_PAGE_TABLE EptPageTable, _In_ PEPT_PML2_ENTRY TargetEntry)
+{
+ LIST_FOR_EACH_LINK(EptPageTable->DynamicSplitList, VMM_EPT_DYNAMIC_SPLIT, DynamicSplitList, CurrentSplit)
+ {
+ if (CurrentSplit->Fields.Entry == TargetEntry)
+ {
+ return &CurrentSplit->PML1[0];
+ }
+ }
+
+ return NULL;
+}
+
/**
* @brief Get the PML1 entry for this physical address if the page is split
*
@@ -303,10 +336,9 @@ EptBuildMtrrMap(VOID)
PEPT_PML1_ENTRY
EptGetPml1Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress)
{
- SIZE_T Directory, DirectoryPointer, PML4Entry;
- PEPT_PML2_ENTRY PML2;
- PEPT_PML1_ENTRY PML1;
- PEPT_PML2_POINTER PML2Pointer;
+ SIZE_T Directory, DirectoryPointer, PML4Entry;
+ PEPT_PML2_ENTRY PML2;
+ PEPT_PML1_ENTRY PML1;
Directory = ADDRMASK_EPT_PML2_INDEX(PhysicalAddress);
DirectoryPointer = ADDRMASK_EPT_PML3_INDEX(PhysicalAddress);
@@ -331,15 +363,9 @@ EptGetPml1Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress)
}
//
- // Conversion to get the right PageFrameNumber.
- // These pointers occupy the same place in the table and are directly convertible.
+ // Resolve the split PML1 VA that was recorded during EptSplitLargePage
//
- PML2Pointer = (PEPT_PML2_POINTER)PML2;
-
- //
- // If it is, translate to the PML1 pointer
- //
- PML1 = (PEPT_PML1_ENTRY)PhysicalAddressToVirtualAddress(PML2Pointer->PageFrameNumber * PAGE_SIZE);
+ PML1 = EptGetSplitPml1VaByPml2Entry(EptPageTable, PML2);
if (!PML1)
{
@@ -367,10 +393,9 @@ EptGetPml1Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress)
PVOID
EptGetPml1OrPml2Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress, BOOLEAN * IsLargePage)
{
- SIZE_T Directory, DirectoryPointer, PML4Entry;
- PEPT_PML2_ENTRY PML2;
- PEPT_PML1_ENTRY PML1;
- PEPT_PML2_POINTER PML2Pointer;
+ SIZE_T Directory, DirectoryPointer, PML4Entry;
+ PEPT_PML2_ENTRY PML2;
+ PEPT_PML1_ENTRY PML1;
Directory = ADDRMASK_EPT_PML2_INDEX(PhysicalAddress);
DirectoryPointer = ADDRMASK_EPT_PML3_INDEX(PhysicalAddress);
@@ -396,15 +421,9 @@ EptGetPml1OrPml2Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress,
}
//
- // Conversion to get the right PageFrameNumber.
- // These pointers occupy the same place in the table and are directly convertible.
+ // Resolve the split PML1 VA that was recorded during EptSplitLargePage
//
- PML2Pointer = (PEPT_PML2_POINTER)PML2;
-
- //
- // If it is, translate to the PML1 pointer
- //
- PML1 = (PEPT_PML1_ENTRY)PhysicalAddressToVirtualAddress(PML2Pointer->PageFrameNumber * PAGE_SIZE);
+ PML1 = EptGetSplitPml1VaByPml2Entry(EptPageTable, PML2);
if (!PML1)
{
@@ -450,17 +469,17 @@ EptGetPml2Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress)
}
/**
- * @brief Split 2MB (LargePage) into 4kb pages
+ * @brief Convert large pages to 4KB pages
*
* @param EptPageTable The EPT Page Table
- * @param PreAllocatedBuffer The address of pre-allocated buffer
+ * @param UsePreAllocatedBuffer Whether allocate a memory or use pre-allocated buffer
* @param PhysicalAddress Physical address of where we want to split
*
* @return BOOLEAN Returns true if it was successful or false if there was an error
*/
BOOLEAN
EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable,
- PVOID PreAllocatedBuffer,
+ BOOLEAN UsePreAllocatedBuffer,
SIZE_T PhysicalAddress)
{
PVMM_EPT_DYNAMIC_SPLIT NewSplit;
@@ -486,19 +505,21 @@ EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable,
//
if (!TargetEntry->LargePage)
{
- //
- // As it's a large page and we request a pool for it, we need to
- // free the pool because it's not used anymore
- //
- PoolManagerFreePool((UINT64)PreAllocatedBuffer);
-
return TRUE;
}
//
// Allocate the PML1 entries
//
- NewSplit = (PVMM_EPT_DYNAMIC_SPLIT)PreAllocatedBuffer;
+ if (UsePreAllocatedBuffer)
+ {
+ NewSplit = (PVMM_EPT_DYNAMIC_SPLIT)PoolManagerCallbackRequestPool(SPLIT_2MB_PAGING_TO_4KB_PAGE, TRUE, sizeof(VMM_EPT_DYNAMIC_SPLIT));
+ }
+ else
+ {
+ NewSplit = (PVMM_EPT_DYNAMIC_SPLIT)PlatformMemAllocateNonPagedPool(sizeof(VMM_EPT_DYNAMIC_SPLIT));
+ }
+
if (!NewSplit)
{
LogError("Err, failed to allocate dynamic split memory");
@@ -510,7 +531,7 @@ EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable,
// Point back to the entry in the dynamic split for easy reference for which entry that
// dynamic split is for
//
- NewSplit->u.Entry = TargetEntry;
+ NewSplit->Fields.Entry = TargetEntry;
//
// Make a template for RWX
@@ -542,7 +563,7 @@ EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable,
//
// Copy the template into all the PML1 entries
//
- __stosq((SIZE_T *)&NewSplit->PML1[0], EntryTemplate.AsUInt, VMM_EPT_PML1E_COUNT);
+ CpuStosQ((SIZE_T *)&NewSplit->PML1[0], EntryTemplate.AsUInt, VMM_EPT_PML1E_COUNT);
//
// Set the page frame numbers for identity mapping
@@ -583,6 +604,12 @@ EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable,
//
RtlCopyMemory(TargetEntry, &NewPointer, sizeof(NewPointer));
+ //
+ // Track the split so we can directly resolve PML1 VA from PML2 entry
+ // without any PA->VA reverse translation
+ //
+ InsertHeadList(&EptPageTable->DynamicSplitList, &(NewSplit->DynamicSplitList));
+
return TRUE;
}
@@ -627,8 +654,6 @@ EptIsValidForLargePage(SIZE_T PageFrameNumber)
BOOLEAN
EptSetupPML2Entry(PVMM_EPT_PAGE_TABLE EptPageTable, PEPT_PML2_ENTRY NewEntry, SIZE_T PageFrameNumber)
{
- PVOID TargetBuffer;
-
//
// Each of the 512 collections of 512 PML2 entries is setup here
// This will, in total, identity map every physical address from 0x0
@@ -646,15 +671,10 @@ EptSetupPML2Entry(PVMM_EPT_PAGE_TABLE EptPageTable, PEPT_PML2_ENTRY NewEntry, SI
}
else
{
- TargetBuffer = (PVOID)PlatformMemAllocateNonPagedPool(sizeof(VMM_EPT_DYNAMIC_SPLIT));
-
- if (!TargetBuffer)
- {
- LogError("Err, cannot allocate page for splitting edge large pages");
- return FALSE;
- }
-
- return EptSplitLargePage(EptPageTable, TargetBuffer, PageFrameNumber * SIZE_2_MB);
+ //
+ // Here we won't need to use pre-allocated buffers
+ //
+ return EptSplitLargePage(EptPageTable, FALSE, PageFrameNumber * SIZE_2_MB);
}
}
@@ -689,6 +709,11 @@ EptAllocateAndCreateIdentityPageTable(VOID)
return NULL;
}
+ //
+ // Keep track of dynamic 2MB->4KB split metadata for this EPT table.
+ //
+ InitializeListHead(&PageTable->DynamicSplitList);
+
//
// Create the template for the first entry in the PML4
//
@@ -699,7 +724,7 @@ EptAllocateAndCreateIdentityPageTable(VOID)
//
// Copy the template into each of the 512 PML4 entry slots
//
- __stosq((SIZE_T *)&PageTable->PML4[1], PageTable->PML4[0].AsUInt, VMM_EPT_PML4E_COUNT - 1);
+ CpuStosQ((SIZE_T *)&PageTable->PML4[1], PageTable->PML4[0].AsUInt, VMM_EPT_PML4E_COUNT - 1);
for (int i = 0; i < VMM_EPT_PML4E_COUNT; i++)
{
@@ -744,14 +769,14 @@ EptAllocateAndCreateIdentityPageTable(VOID)
//
// Copy the template into each of the 512 PML3 entry slots for the original entries
//
- __stosq((SIZE_T *)&PageTable->PML3[0], PML3Template.AsUInt, VMM_EPT_PML3E_COUNT);
+ CpuStosQ((SIZE_T *)&PageTable->PML3[0], PML3Template.AsUInt, VMM_EPT_PML3E_COUNT);
//
// Copt the template into each of the 512 PML3 entry slots for the reserved entries
//
- for (size_t i = 0; i < VMM_EPT_PML4E_COUNT - 1; i++)
+ for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT - 1; i++)
{
- __stosq((SIZE_T *)&PageTable->PML3_RSVD[i][0], PML3TemplateLarge.AsUInt, VMM_EPT_PML3E_COUNT);
+ CpuStosQ((SIZE_T *)&PageTable->PML3_RSVD[i][0], PML3TemplateLarge.AsUInt, VMM_EPT_PML3E_COUNT);
}
//
@@ -769,9 +794,9 @@ EptAllocateAndCreateIdentityPageTable(VOID)
//
// For each of the 512 PML3 reserved entries for reserved PML3 entries
//
- for (size_t i = 0; i < VMM_EPT_PML4E_COUNT - 1; i++)
+ for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT - 1; i++)
{
- for (size_t j = 0; j < VMM_EPT_PML3E_COUNT; j++)
+ for (SIZE_T j = 0; j < VMM_EPT_PML3E_COUNT; j++)
{
//
// Map the 1GB PML3 reserved entry to 512 PML3 (1GB) entries to describe each large page
@@ -808,7 +833,7 @@ EptAllocateAndCreateIdentityPageTable(VOID)
// this region or not. We will cause a fault in our EPT handler if the guest access a page
// outside a usable range, despite the EPT frame being present here
//
- __stosq((SIZE_T *)&PageTable->PML2[0], PML2EntryTemplate.AsUInt, VMM_EPT_PML3E_COUNT * VMM_EPT_PML2E_COUNT);
+ CpuStosQ((SIZE_T *)&PageTable->PML2[0], PML2EntryTemplate.AsUInt, VMM_EPT_PML3E_COUNT * VMM_EPT_PML2E_COUNT);
//
// For each of the 512 collections of 512 2MB PML2 entries
@@ -848,7 +873,7 @@ EptLogicalProcessorInitialize(VOID)
//
ProcessorsCount = KeQueryActiveProcessorCount(0);
- for (size_t i = 0; i < ProcessorsCount; i++)
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
//
// Allocate the identity mapped page table
@@ -860,7 +885,7 @@ EptLogicalProcessorInitialize(VOID)
//
// Try to deallocate previous pools (if any)
//
- for (size_t j = 0; j < ProcessorsCount; j++)
+ for (SIZE_T j = 0; j < ProcessorsCount; j++)
{
if (g_GuestState[j].EptPageTable != NULL)
{
@@ -1088,19 +1113,19 @@ EptHandleEptViolation(VIRTUAL_MACHINE_STATE * VCpu)
//
// Reading guest physical address
//
- __vmx_vmread(VMCS_GUEST_PHYSICAL_ADDRESS, &GuestPhysicalAddr);
+ VmxVmread64P(VMCS_GUEST_PHYSICAL_ADDRESS, &GuestPhysicalAddr);
- if (ExecTrapHandleEptViolationVmexit(VCpu, &ViolationQualification))
- {
- return TRUE;
- }
- else if (EptHandlePageHookExit(VCpu, ViolationQualification, GuestPhysicalAddr))
+ if (EptHandlePageHookExit(VCpu, ViolationQualification, GuestPhysicalAddr))
{
//
// Handled by page hook code
//
return TRUE;
}
+ else if (ExecTrapHandleEptViolationVmexit(VCpu, &ViolationQualification))
+ {
+ return TRUE;
+ }
else if (VmmCallbackUnhandledEptViolation(VCpu->CoreId, (UINT64)ViolationQualification.AsUInt, GuestPhysicalAddr))
{
//
@@ -1128,7 +1153,7 @@ EptHandleMisconfiguration(VOID)
{
UINT64 GuestPhysicalAddr = 0;
- __vmx_vmread(VMCS_GUEST_PHYSICAL_ADDRESS, &GuestPhysicalAddr);
+ VmxVmread64P(VMCS_GUEST_PHYSICAL_ADDRESS, &GuestPhysicalAddr);
LogInfo("EPT Misconfiguration!");
@@ -1211,7 +1236,7 @@ EptCheckAndHandleEptHookBreakpoints(VIRTUAL_MACHINE_STATE * VCpu, UINT64 GuestRi
if (HookedEntry->IsExecutionHook)
{
- for (size_t i = 0; i < HookedEntry->CountOfBreakpoints; i++)
+ for (SIZE_T i = 0; i < HookedEntry->CountOfBreakpoints; i++)
{
if (HookedEntry->BreakpointAddresses[i] == GuestRip)
{
@@ -1297,7 +1322,7 @@ EptCheckAndHandleBreakpoint(VIRTUAL_MACHINE_STATE * VCpu)
//
// Reading guest's RIP
//
- __vmx_vmread(VMCS_GUEST_RIP, &GuestRip);
+ VmxVmread64P(VMCS_GUEST_RIP, &GuestRip);
//
// Don't increment rip by default
diff --git a/hyperdbg/hyperhv/code/vmm/ept/Vpid.c b/hyperdbg/hyperhv/code/vmm/ept/Vpid.c
index a4874c4d..cd587b57 100644
--- a/hyperdbg/hyperhv/code/vmm/ept/Vpid.c
+++ b/hyperdbg/hyperhv/code/vmm/ept/Vpid.c
@@ -25,6 +25,12 @@ VpidInvvpid(INVVPID_TYPE Type, INVVPID_DESCRIPTOR * Descriptor)
INVVPID_DESCRIPTOR * TargetDescriptor = NULL;
INVVPID_DESCRIPTOR ZeroDescriptor = {0};
+ // No need to do anything if VPID is not supported.
+ if (!g_IsVpidSupported)
+ {
+ return;
+ }
+
if (!Descriptor)
{
TargetDescriptor = &ZeroDescriptor;
diff --git a/hyperdbg/hyperhv/code/vmm/vmx/Counters.c b/hyperdbg/hyperhv/code/vmm/vmx/Counters.c
index 9506dc6c..d1493c49 100644
--- a/hyperdbg/hyperhv/code/vmm/vmx/Counters.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/Counters.c
@@ -1,4 +1,4 @@
-/**
+/**
* @file Counters.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief The functions for emulating counters
@@ -26,7 +26,7 @@ CounterEmulateRdtsc(VIRTUAL_MACHINE_STATE * VCpu)
// to solve it, in the future we solve it using tsc offsetting
// or tsc scalling (The reason is because of that fucking patchguard :( )
//
- UINT64 Tsc = __rdtsc();
+ UINT64 Tsc = CpuReadTsc();
PGUEST_REGS GuestRegs = VCpu->Regs;
GuestRegs->rax = 0x00000000ffffffff & Tsc;
@@ -43,7 +43,7 @@ VOID
CounterEmulateRdtscp(VIRTUAL_MACHINE_STATE * VCpu)
{
UINT32 Aux = 0;
- UINT64 Tsc = __rdtscp(&Aux);
+ UINT64 Tsc = CpuReadTscp(&Aux);
PGUEST_REGS GuestRegs = VCpu->Regs;
GuestRegs->rax = 0x00000000ffffffff & Tsc;
diff --git a/hyperdbg/hyperhv/code/vmm/vmx/CrossVmcalls.c b/hyperdbg/hyperhv/code/vmm/vmx/CrossVmcalls.c
new file mode 100644
index 00000000..b64fb169
--- /dev/null
+++ b/hyperdbg/hyperhv/code/vmm/vmx/CrossVmcalls.c
@@ -0,0 +1,155 @@
+/**
+ * @file CrossVmcalls.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Routines relating to cross (standalone) VMCALLs
+ * @details
+ * @version 0.19
+ * @date 2026-04-14
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief Get the guest state of IA32_DEBUGCTL on the target core from VMCS
+ * using VMCALL
+ *
+ * @return UINT64
+ */
+UINT64
+CrossVmcallGetDebugctlVmcallOnTargetCore()
+{
+ UINT64 DebugctlValue;
+ AsmVmxVmcall(VMCALL_GET_VMCS_DEBUGCTL, (UINT64)&DebugctlValue, NULL64_ZERO, NULL64_ZERO);
+ return DebugctlValue;
+}
+
+/**
+ * @brief Get the guest state of IA32_LBR_CTL on the target core from VMCS using VMCALL
+ *
+ * @return UINT64
+ */
+UINT64
+CrossVmcallGetGuestIa32LbrCtlVmcallOnTargetCore()
+{
+ UINT64 GuestIa32LbrCtlValue;
+ AsmVmxVmcall(VMCALL_GET_GUEST_IA32_LBR_CTL, (UINT64)&GuestIa32LbrCtlValue, NULL64_ZERO, NULL64_ZERO);
+ return GuestIa32LbrCtlValue;
+}
+
+/**
+ * @brief Set the guest state of IA32_DEBUGCTL on the target core from VMCS using VMCALL
+ * @param Value
+ *
+ * @return VOID
+ */
+VOID
+CrossVmcallSetDebugctlVmcallOnTargetCore(UINT64 Value)
+{
+ AsmVmxVmcall(VMCALL_SET_VMCS_DEBUGCTL, Value, NULL64_ZERO, NULL64_ZERO);
+}
+
+/**
+ * @brief Set the guest state of IA32_LBR_CTL on the target core from VMCS using VMCALL
+ * @param Value
+ *
+ * @return VOID
+ */
+VOID
+CrossVmcallSetGuestIa32LbrCtlVmcallOnTargetCore(UINT64 Value)
+{
+ AsmVmxVmcall(VMCALL_SET_GUEST_IA32_LBR_CTL, Value, NULL64_ZERO, NULL64_ZERO);
+}
+
+/**
+ * @brief Set the guest state of MSR_LEGACY_LBR_SELECT on the target core from VMCS using VMCALL
+ * @param FilterOptions
+ *
+ * @return VOID
+ */
+VOID
+CrossVmcallSetLbrSelectVmcallOnTargetCore(UINT64 FilterOptions)
+{
+ AsmVmxVmcall(VMCALL_SET_MSR_LBR_SELECT, FilterOptions, NULL64_ZERO, NULL64_ZERO);
+}
+
+/**
+ * @brief Set LOAD DEBUG CONTROLS on Vm-entry controls on the target core from VMCS using VMCALL
+ *
+ * @param Set Set or unset
+ *
+ * @return VOID
+ */
+VOID
+CrossVmcallSetLoadDebugControlsVmcallOnTargetCore(BOOLEAN Set)
+{
+ if (Set)
+ {
+ AsmVmxVmcall(VMCALL_SET_VM_ENTRY_LOAD_DEBUG_CONTROLS, NULL64_ZERO, NULL64_ZERO, NULL64_ZERO);
+ }
+ else
+ {
+ AsmVmxVmcall(VMCALL_UNSET_VM_ENTRY_LOAD_DEBUG_CONTROLS, NULL64_ZERO, NULL64_ZERO, NULL64_ZERO);
+ }
+}
+
+/**
+ * @brief Set CLEAR GUEST IA32_LBR_CTL on Vm-entry controls on the target core from VMCS using VMCALL
+ *
+ * @param Set Set or unset
+ *
+ * @return VOID
+ */
+VOID
+CrossVmcallSetLoadGuestIa32LbrCtlVmcallOnTargetCore(BOOLEAN Set)
+{
+ if (Set)
+ {
+ AsmVmxVmcall(VMCALL_SET_VM_ENTRY_LOAD_GUEST_IA32_LBR_CTL, NULL64_ZERO, NULL64_ZERO, NULL64_ZERO);
+ }
+ else
+ {
+ AsmVmxVmcall(VMCALL_UNSET_VM_ENTRY_LOAD_GUEST_IA32_LBR_CTL, NULL64_ZERO, NULL64_ZERO, NULL64_ZERO);
+ }
+}
+
+/**
+ * @brief Set SAVE DEBUG CONTROLS on Vm-exit controls on the target core from VMCS using VMCALL
+ *
+ * @param Set Set or unset
+ *
+ * @return VOID
+ */
+VOID
+CrossVmcallSetSaveDebugControlsVmcallOnTargetCore(BOOLEAN Set)
+{
+ if (Set)
+ {
+ AsmVmxVmcall(VMCALL_SET_VM_EXIT_SAVE_DEBUG_CONTROLS, NULL64_ZERO, NULL64_ZERO, NULL64_ZERO);
+ }
+ else
+ {
+ AsmVmxVmcall(VMCALL_UNSET_VM_EXIT_SAVE_DEBUG_CONTROLS, NULL64_ZERO, NULL64_ZERO, NULL64_ZERO);
+ }
+}
+
+/**
+ * @brief Set CLEAR GUEST IA32_LBR_CTL on Vm-exit controls on the target core from VMCS using VMCALL
+ *
+ * @param Set Set or unset
+ *
+ * @return VOID
+ */
+VOID
+CrossVmcallSetClearGuestIa32LbrCtlVmcallOnTargetCore(BOOLEAN Set)
+{
+ if (Set)
+ {
+ AsmVmxVmcall(VMCALL_SET_CLEAR_GUEST_IA32_LBR_CTL, NULL64_ZERO, NULL64_ZERO, NULL64_ZERO);
+ }
+ else
+ {
+ AsmVmxVmcall(VMCALL_UNSET_CLEAR_GUEST_IA32_LBR_CTL, NULL64_ZERO, NULL64_ZERO, NULL64_ZERO);
+ }
+}
diff --git a/hyperdbg/hyperhv/code/vmm/vmx/Events.c b/hyperdbg/hyperhv/code/vmm/vmx/Events.c
index 330ccc70..34bee0dc 100644
--- a/hyperdbg/hyperhv/code/vmm/vmx/Events.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/Events.c
@@ -1,4 +1,4 @@
-/**
+/**
* @file Events.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Functions relating to Exception Bitmap and Event (Interrupt and Exception) Injection
@@ -128,7 +128,7 @@ EventInjectPageFaultWithoutErrorCode(UINT64 PageFaultAddress)
//
// Write the page-fault address
//
- __writecr2(PageFaultAddress);
+ CpuWriteCr2(PageFaultAddress);
//
// Make the error code
@@ -201,7 +201,7 @@ EventInjectPageFaults(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
//
// Cr2 is used as the page-fault address
//
- __writecr2(PageFaultAddress);
+ CpuWriteCr2(PageFaultAddress);
HvSuppressRipIncrement(VCpu);
diff --git a/hyperdbg/hyperhv/code/vmm/vmx/Hv.c b/hyperdbg/hyperhv/code/vmm/vmx/Hv.c
index 00d134da..155ced78 100644
--- a/hyperdbg/hyperhv/code/vmm/vmx/Hv.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/Hv.c
@@ -24,7 +24,7 @@ HvAdjustControls(UINT32 Ctl, UINT32 Msr)
{
MSR MsrValue = {0};
- MsrValue.Flags = __readmsr(Msr);
+ MsrValue.Flags = CpuReadMsr(Msr);
Ctl &= MsrValue.Fields.High; /* bit == 0 in high word ==> must be zero */
Ctl |= MsrValue.Fields.Low; /* bit == 1 in low word ==> must be one */
return Ctl;
@@ -73,7 +73,7 @@ HvHandleCpuid(VIRTUAL_MACHINE_STATE * VCpu)
// Otherwise, issue the CPUID to the logical processor based on the indexes
// on the VP's GPRs.
//
- __cpuidex(CpuInfo, (INT32)Regs->rax, (INT32)Regs->rcx);
+ CpuCpuIdEx(CpuInfo, (INT32)Regs->rax, (INT32)Regs->rcx);
//
// check whether we are in transparent mode or not
@@ -158,7 +158,7 @@ HvHandleControlRegisterAccess(VIRTUAL_MACHINE_STATE * VCpu,
/*
if (CrExitQualification->Fields.Register == 4)
{
- __vmx_vmread(VMCS_GUEST_RSP, &GuestRsp);
+ VmxVmread64P(VMCS_GUEST_RSP, &GuestRsp);
*RegPtr = GuestRsp;
}
*/
@@ -229,19 +229,19 @@ HvHandleControlRegisterAccess(VIRTUAL_MACHINE_STATE * VCpu,
{
case VMX_EXIT_QUALIFICATION_REGISTER_CR0:
- __vmx_vmread(VMCS_GUEST_CR0, RegPtr);
+ VmxVmread64P(VMCS_GUEST_CR0, RegPtr);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_CR3:
- __vmx_vmread(VMCS_GUEST_CR3, RegPtr);
+ VmxVmread64P(VMCS_GUEST_CR3, RegPtr);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_CR4:
- __vmx_vmread(VMCS_GUEST_CR4, RegPtr);
+ VmxVmread64P(VMCS_GUEST_CR4, RegPtr);
break;
@@ -299,10 +299,10 @@ HvResumeToNextInstruction()
{
UINT64 ResumeRIP = NULL64_ZERO;
UINT64 CurrentRIP = NULL64_ZERO;
- size_t ExitInstructionLength = 0;
+ SIZE_T ExitInstructionLength = 0;
- __vmx_vmread(VMCS_GUEST_RIP, &CurrentRIP);
- __vmx_vmread(VMCS_VMEXIT_INSTRUCTION_LENGTH, &ExitInstructionLength);
+ VmxVmread64P(VMCS_GUEST_RIP, &CurrentRIP);
+ VmxVmread64P(VMCS_VMEXIT_INSTRUCTION_LENGTH, &ExitInstructionLength);
ResumeRIP = CurrentRIP + ExitInstructionLength;
@@ -353,11 +353,11 @@ HvSetMonitorTrapFlag(BOOLEAN Set)
if (Set)
{
- CpuBasedVmExecControls |= CPU_BASED_MONITOR_TRAP_FLAG;
+ CpuBasedVmExecControls |= IA32_VMX_PROCBASED_CTLS_MONITOR_TRAP_FLAG_FLAG;
}
else
{
- CpuBasedVmExecControls &= ~CPU_BASED_MONITOR_TRAP_FLAG;
+ CpuBasedVmExecControls &= ~IA32_VMX_PROCBASED_CTLS_MONITOR_TRAP_FLAG_FLAG;
}
//
@@ -391,12 +391,28 @@ HvSetRflagTrapFlag(BOOLEAN Set)
/**
* @brief Set LOAD DEBUG CONTROLS on Vm-entry controls
*
+ * @param VCpu
* @param Set Set or unset
* @return VOID
*/
VOID
-HvSetLoadDebugControls(BOOLEAN Set)
+HvSetLoadDebugControls(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set)
{
+ ProtectedHvSetLoadDebugControls(VCpu, Set);
+}
+
+/**
+ * @brief Set LOAD GUEST IA32_LBR_CTL on Vm-entry controls
+ *
+ * @param VCpu
+ * @param Set Set or unset
+ * @return VOID
+ */
+VOID
+HvSetLoadGuestIa32LbrCtl(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set)
+{
+ UNREFERENCED_PARAMETER(VCpu);
+
UINT32 VmentryControls = 0;
//
@@ -406,28 +422,44 @@ HvSetLoadDebugControls(BOOLEAN Set)
if (Set)
{
- VmentryControls |= VM_ENTRY_LOAD_DEBUG_CONTROLS;
+ VmentryControls |= IA32_VMX_ENTRY_CTLS_LOAD_IA32_LBR_CTL_FLAG;
}
else
{
- VmentryControls &= ~VM_ENTRY_LOAD_DEBUG_CONTROLS;
+ VmentryControls &= ~IA32_VMX_ENTRY_CTLS_LOAD_IA32_LBR_CTL_FLAG;
}
//
// Set the new value
//
- VmxVmwrite64(VMCS_CTRL_VMENTRY_CONTROLS, VmentryControls);
+ VmxVmwrite32(VMCS_CTRL_VMENTRY_CONTROLS, VmentryControls);
}
/**
* @brief Set SAVE DEBUG CONTROLS on Vm-exit controls
*
+ * @param VCpu
* @param Set Set or unset
* @return VOID
*/
VOID
-HvSetSaveDebugControls(BOOLEAN Set)
+HvSetSaveDebugControls(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set)
{
+ ProtectedHvSetSaveDebugControls(VCpu, Set);
+}
+
+/**
+ * @brief Set SAVE GUEST IA32_LBR_CTL on Vm-exit controls
+ *
+ * @param VCpu
+ * @param Set Set or unset
+ * @return VOID
+ */
+VOID
+HvSetClearGuestIa32LbrCtl(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set)
+{
+ UNREFERENCED_PARAMETER(VCpu);
+
UINT32 VmexitControls = 0;
//
@@ -437,17 +469,17 @@ HvSetSaveDebugControls(BOOLEAN Set)
if (Set)
{
- VmexitControls |= VM_EXIT_SAVE_DEBUG_CONTROLS;
+ VmexitControls |= IA32_VMX_EXIT_CTLS_CLEAR_IA32_LBR_CTL_FLAG;
}
else
{
- VmexitControls &= ~VM_EXIT_SAVE_DEBUG_CONTROLS;
+ VmexitControls &= ~IA32_VMX_EXIT_CTLS_CLEAR_IA32_LBR_CTL_FLAG;
}
//
// Set the new value
//
- VmxVmwrite64(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, VmexitControls);
+ VmxVmwrite32(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, VmexitControls);
}
/**
@@ -472,22 +504,22 @@ HvRestoreRegisters()
//
// Restore FS Base
//
- __vmx_vmread(VMCS_GUEST_FS_BASE, &FsBase);
- __writemsr(IA32_FS_BASE, FsBase);
+ VmxVmread64P(VMCS_GUEST_FS_BASE, &FsBase);
+ CpuWriteMsr(IA32_FS_BASE, FsBase);
//
// Restore Gs Base
//
- __vmx_vmread(VMCS_GUEST_GS_BASE, &GsBase);
- __writemsr(IA32_GS_BASE, GsBase);
+ VmxVmread64P(VMCS_GUEST_GS_BASE, &GsBase);
+ CpuWriteMsr(IA32_GS_BASE, GsBase);
//
// Restore GDTR
//
- __vmx_vmread(VMCS_GUEST_GDTR_BASE, &GdtrBase);
- __vmx_vmread(VMCS_GUEST_GDTR_LIMIT, &GdtrLimit);
+ VmxVmread64P(VMCS_GUEST_GDTR_BASE, &GdtrBase);
+ VmxVmread64P(VMCS_GUEST_GDTR_LIMIT, &GdtrLimit);
- AsmReloadGdtr((void *)GdtrBase, (unsigned long)GdtrLimit);
+ AsmReloadGdtr((PVOID)GdtrBase, (ULONG)GdtrLimit);
//
// Restore Segment Selector
@@ -504,10 +536,10 @@ HvRestoreRegisters()
//
// Restore IDTR
//
- __vmx_vmread(VMCS_GUEST_IDTR_BASE, &IdtrBase);
- __vmx_vmread(VMCS_GUEST_IDTR_LIMIT, &IdtrLimit);
+ VmxVmread64P(VMCS_GUEST_IDTR_BASE, &IdtrBase);
+ VmxVmread64P(VMCS_GUEST_IDTR_LIMIT, &IdtrLimit);
- AsmReloadIdtr((void *)IdtrBase, (unsigned long)IdtrLimit);
+ AsmReloadIdtr((PVOID)IdtrBase, (ULONG)IdtrLimit);
}
/**
@@ -529,11 +561,11 @@ HvSetPmcVmexit(BOOLEAN Set)
if (Set)
{
- CpuBasedVmExecControls |= CPU_BASED_RDPMC_EXITING;
+ CpuBasedVmExecControls |= IA32_VMX_PROCBASED_CTLS_RDPMC_EXITING_FLAG;
}
else
{
- CpuBasedVmExecControls &= ~CPU_BASED_RDPMC_EXITING;
+ CpuBasedVmExecControls &= ~IA32_VMX_PROCBASED_CTLS_RDPMC_EXITING_FLAG;
}
//
@@ -629,11 +661,11 @@ HvSetInterruptWindowExiting(BOOLEAN Set)
//
if (Set)
{
- CpuBasedVmExecControls |= CPU_BASED_VIRTUAL_INTR_PENDING;
+ CpuBasedVmExecControls |= IA32_VMX_PROCBASED_CTLS_INTERRUPT_WINDOW_EXITING_FLAG;
}
else
{
- CpuBasedVmExecControls &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
+ CpuBasedVmExecControls &= ~IA32_VMX_PROCBASED_CTLS_INTERRUPT_WINDOW_EXITING_FLAG;
}
//
@@ -737,11 +769,11 @@ HvSetNmiWindowExiting(BOOLEAN Set)
//
if (Set)
{
- CpuBasedVmExecControls |= CPU_BASED_VIRTUAL_NMI_PENDING;
+ CpuBasedVmExecControls |= IA32_VMX_PROCBASED_CTLS_NMI_WINDOW_EXITING_FLAG;
}
else
{
- CpuBasedVmExecControls &= ~CPU_BASED_VIRTUAL_NMI_PENDING;
+ CpuBasedVmExecControls &= ~IA32_VMX_PROCBASED_CTLS_NMI_WINDOW_EXITING_FLAG;
}
//
@@ -860,11 +892,11 @@ HvHandleMovDebugRegister(VIRTUAL_MACHINE_STATE * VCpu)
if (Dr7.GeneralDetect)
{
DR6 Dr6 = {
- .AsUInt = __readdr(6),
+ .AsUInt = CpuReadDr(6),
.BreakpointCondition = 0,
.DebugRegisterAccessDetected = TRUE};
- __writedr(6, Dr6.AsUInt);
+ CpuWriteDr(6, Dr6.AsUInt);
Dr7.GeneralDetect = FALSE;
@@ -906,22 +938,22 @@ HvHandleMovDebugRegister(VIRTUAL_MACHINE_STATE * VCpu)
switch (ExitQualification.DebugRegister)
{
case VMX_EXIT_QUALIFICATION_REGISTER_DR0:
- __writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR0, GpRegister);
+ CpuWriteDr(VMX_EXIT_QUALIFICATION_REGISTER_DR0, GpRegister);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_DR1:
- __writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR1, GpRegister);
+ CpuWriteDr(VMX_EXIT_QUALIFICATION_REGISTER_DR1, GpRegister);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_DR2:
- __writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR2, GpRegister);
+ CpuWriteDr(VMX_EXIT_QUALIFICATION_REGISTER_DR2, GpRegister);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_DR3:
- __writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR3, GpRegister);
+ CpuWriteDr(VMX_EXIT_QUALIFICATION_REGISTER_DR3, GpRegister);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_DR6:
- __writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR6, GpRegister);
+ CpuWriteDr(VMX_EXIT_QUALIFICATION_REGISTER_DR6, GpRegister);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_DR7:
- __writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR7, GpRegister);
+ CpuWriteDr(VMX_EXIT_QUALIFICATION_REGISTER_DR7, GpRegister);
break;
default:
break;
@@ -932,22 +964,22 @@ HvHandleMovDebugRegister(VIRTUAL_MACHINE_STATE * VCpu)
switch (ExitQualification.DebugRegister)
{
case VMX_EXIT_QUALIFICATION_REGISTER_DR0:
- GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR0);
+ GpRegister = CpuReadDr(VMX_EXIT_QUALIFICATION_REGISTER_DR0);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_DR1:
- GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR1);
+ GpRegister = CpuReadDr(VMX_EXIT_QUALIFICATION_REGISTER_DR1);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_DR2:
- GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR2);
+ GpRegister = CpuReadDr(VMX_EXIT_QUALIFICATION_REGISTER_DR2);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_DR3:
- GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR3);
+ GpRegister = CpuReadDr(VMX_EXIT_QUALIFICATION_REGISTER_DR3);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_DR6:
- GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR6);
+ GpRegister = CpuReadDr(VMX_EXIT_QUALIFICATION_REGISTER_DR6);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_DR7:
- GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR7);
+ GpRegister = CpuReadDr(VMX_EXIT_QUALIFICATION_REGISTER_DR7);
break;
default:
break;
@@ -978,13 +1010,13 @@ HvSetNmiExiting(BOOLEAN Set)
if (Set)
{
- PinBasedControls |= PIN_BASED_VM_EXECUTION_CONTROLS_NMI_EXITING;
- VmExitControls |= VM_EXIT_ACK_INTR_ON_EXIT;
+ PinBasedControls |= IA32_VMX_PINBASED_CTLS_NMI_EXITING_FLAG;
+ VmExitControls |= IA32_VMX_EXIT_CTLS_ACKNOWLEDGE_INTERRUPT_ON_EXIT_FLAG;
}
else
{
- PinBasedControls &= ~PIN_BASED_VM_EXECUTION_CONTROLS_NMI_EXITING;
- VmExitControls &= ~VM_EXIT_ACK_INTR_ON_EXIT;
+ PinBasedControls &= ~IA32_VMX_PINBASED_CTLS_NMI_EXITING_FLAG;
+ VmExitControls &= ~IA32_VMX_EXIT_CTLS_ACKNOWLEDGE_INTERRUPT_ON_EXIT_FLAG;
}
//
@@ -1012,11 +1044,11 @@ HvSetVmxPreemptionTimerExiting(BOOLEAN Set)
if (Set)
{
- PinBasedControls |= PIN_BASED_VM_EXECUTION_CONTROLS_ACTIVE_VMX_TIMER;
+ PinBasedControls |= IA32_VMX_PINBASED_CTLS_ACTIVATE_VMX_PREEMPTION_TIMER_FLAG;
}
else
{
- PinBasedControls &= ~PIN_BASED_VM_EXECUTION_CONTROLS_ACTIVE_VMX_TIMER;
+ PinBasedControls &= ~IA32_VMX_PINBASED_CTLS_ACTIVATE_VMX_PREEMPTION_TIMER_FLAG;
}
//
@@ -1079,7 +1111,6 @@ HvSetExternalInterruptExiting(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set)
* @brief Checks to enable and reinject previous interrupts
*
* @param VCpu The virtual processor's state
- * @param Set Set or unset the External Interrupt Exiting
*
* @return VOID
*/
@@ -1152,7 +1183,7 @@ HvGetCsSelector()
//
UINT64 CsSel = NULL64_ZERO;
- __vmx_vmread(VMCS_GUEST_CS_SELECTOR, &CsSel);
+ VmxVmread64P(VMCS_GUEST_CS_SELECTOR, &CsSel);
return CsSel & 0xffff;
}
@@ -1167,7 +1198,7 @@ HvGetRflags()
{
UINT64 Rflags = NULL64_ZERO;
- __vmx_vmread(VMCS_GUEST_RFLAGS, &Rflags);
+ VmxVmread64P(VMCS_GUEST_RFLAGS, &Rflags);
return Rflags;
}
@@ -1194,7 +1225,7 @@ HvGetRip()
{
UINT64 Rip = NULL64_ZERO;
- __vmx_vmread(VMCS_GUEST_RIP, &Rip);
+ VmxVmread64P(VMCS_GUEST_RIP, &Rip);
return Rip;
}
@@ -1221,7 +1252,7 @@ HvGetInterruptibilityState()
{
UINT64 InterruptibilityState = NULL64_ZERO;
- __vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY_STATE, &InterruptibilityState);
+ VmxVmread64P(VMCS_GUEST_INTERRUPTIBILITY_STATE, &InterruptibilityState);
return InterruptibilityState;
}
@@ -1503,6 +1534,69 @@ HvGetDebugctl()
return (UINT64)HighPart << 32 | LowPart;
}
+/**
+ * @brief Get the guest state of IA32_LBR_CTL
+ *
+ * @return UINT64
+ */
+UINT64
+HvGetGuestIa32LbrCtl()
+{
+ UINT64 GuestIa32LbrCtl;
+
+ VmxVmread64P(VMCS_GUEST_LBR_CTL, &GuestIa32LbrCtl);
+
+ return GuestIa32LbrCtl;
+}
+
+/**
+ * @brief Get and store the guest state of IA32_DEBUGCTL
+ * @details mainly used from the VMCALL handler
+ *
+ * @param StoreDebugctl
+ *
+ * @return VOID
+ */
+VOID
+HvGetAndStoreDebugctl(UINT64 * StoreDebugctl)
+{
+ UINT64 DebugctlValue;
+
+ //
+ // Read DEBUGCTL from VMCS
+ //
+ DebugctlValue = HvGetDebugctl();
+
+ //
+ // Store the DEBUGCTL
+ //
+ *StoreDebugctl = DebugctlValue;
+}
+
+/**
+ * @brief Get and store the guest state of IA32_LBR_CTL
+ * @details mainly used from the VMCALL handler
+ *
+ * @param StoreGuestIa32Lbr
+ *
+ * @return VOID
+ */
+VOID
+HvGetAndStoreGuestIa32LbrCtl(UINT64 * StoreGuestIa32Lbr)
+{
+ UINT64 GuestIa32LbrCtl;
+
+ //
+ // Read IA32_LBR_CTL from VMCS
+ //
+ GuestIa32LbrCtl = HvGetGuestIa32LbrCtl();
+
+ //
+ // Store the IA32_LBR_CTL
+ //
+ *StoreGuestIa32Lbr = GuestIa32LbrCtl;
+}
+
/**
* @brief Set the guest state of IA32_DEBUGCTL
* @param Value The new state
@@ -1512,8 +1606,141 @@ HvGetDebugctl()
VOID
HvSetDebugctl(UINT64 Value)
{
- VmxVmwrite64(VMCS_GUEST_DEBUGCTL, Value & 0xFFFFFFFF);
- VmxVmwrite64(VMCS_GUEST_DEBUGCTL_HIGH, Value >> 32);
+ VmxVmwrite32(VMCS_GUEST_DEBUGCTL, Value & 0xFFFFFFFF);
+ VmxVmwrite32(VMCS_GUEST_DEBUGCTL_HIGH, Value >> 32);
+}
+
+/**
+ * @brief Set the guest state of IA32_LBR_CTL
+ * @param Value The new state
+ *
+ * @return VOID
+ */
+VOID
+HvSetGuestIa32LbrCtl(UINT64 Value)
+{
+ VmxVmwrite64(VMCS_GUEST_LBR_CTL, Value);
+}
+
+/**
+ * @brief Set LBR selector
+ * @details If VMM is active, this should be done in vmx-root, otherwise, it doesn't work
+ * @param FilterOptions The value to write on MSR_LEGACY_LBR_SELECT
+ *
+ * @return VOID
+ */
+VOID
+HvSetLbrSelect(UINT64 FilterOptions)
+{
+ CpuWriteMsr(MSR_LEGACY_LBR_SELECT, FilterOptions);
+}
+
+/**
+ * @brief Check if CPU support save and load debug controls on exit and load entries
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HvCheckCpuSupportForSaveAndLoadDebugControls()
+{
+ IA32_VMX_BASIC_REGISTER VmxBasicMsr = {0};
+
+ //
+ // Reading IA32_VMX_BASIC_MSR
+ //
+ VmxBasicMsr.AsUInt = CpuReadMsr(IA32_VMX_BASIC);
+
+ //
+ // Read 1-settings of save debug controls (exit controls)
+ //
+ UINT32 ExitCtls = HvAdjustControls(
+ IA32_VMX_EXIT_CTLS_SAVE_DEBUG_CONTROLS_FLAG,
+ VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS);
+
+ //
+ // Read 1-settings of load debug controls (entry controls)
+ //
+ UINT32 EntryCtls = HvAdjustControls(
+ IA32_VMX_ENTRY_CTLS_LOAD_DEBUG_CONTROLS_FLAG,
+ VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS);
+
+ //
+ // Check if entry and exit controls are supported on this system
+ //
+ if (ExitCtls != NULL_ZERO && EntryCtls != NULL_ZERO)
+ {
+ //
+ // Supported
+ //
+ return TRUE;
+ }
+ else
+ {
+ //
+ // Not supported
+ //
+ return FALSE;
+ }
+}
+
+/**
+ * @brief Check if CPU support load and clear guest IA32_LBR_CTL controls on entry and exit
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HvCheckCpuSupportForLoadAndClearGuestIa32LbrCtlControls()
+{
+ IA32_VMX_BASIC_REGISTER VmxBasicMsr = {0};
+
+ //
+ // Reading IA32_VMX_BASIC_MSR
+ //
+ VmxBasicMsr.AsUInt = CpuReadMsr(IA32_VMX_BASIC);
+
+ //
+ // Read 1-settings of save debug controls (exit controls)
+ //
+ UINT32 ExitCtls = HvAdjustControls(
+ IA32_VMX_EXIT_CTLS_CLEAR_IA32_LBR_CTL_FLAG,
+ VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS);
+
+ //
+ // Read 1-settings of load debug controls (entry controls)
+ //
+ UINT32 EntryCtls = HvAdjustControls(
+ IA32_VMX_ENTRY_CTLS_LOAD_IA32_LBR_CTL_FLAG,
+ VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS);
+
+ //
+ // Check if entry and exit controls are supported on this system
+ //
+ if (ExitCtls != NULL_ZERO && EntryCtls != NULL_ZERO)
+ {
+ //
+ // Supported
+ //
+ return TRUE;
+ }
+ else
+ {
+ //
+ // Not supported
+ //
+ return FALSE;
+ }
+}
+
+/**
+ * @brief Set the guest state of DR7
+ * @param Value The new value for DR7
+ *
+ * @return VOID
+ */
+VOID
+HvSetDebugReg7(UINT64 Value)
+{
+ VmxVmwrite64(VMCS_GUEST_DR7, Value);
}
/**
diff --git a/hyperdbg/hyperhv/code/vmm/vmx/IdtEmulation.c b/hyperdbg/hyperhv/code/vmm/vmx/IdtEmulation.c
index 584a7c34..09226007 100644
--- a/hyperdbg/hyperhv/code/vmm/vmx/IdtEmulation.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/IdtEmulation.c
@@ -35,7 +35,7 @@ IdtEmulationQueryIdtEntriesRequest(PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS I
//
// Since it's not in VMX Root, we can directly read the IDTR register
//
- __sidt(&IdtrReg);
+ CpuSidt(&IdtrReg);
//
// Get the IDT base address
@@ -55,9 +55,9 @@ IdtEmulationQueryIdtEntriesRequest(PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS I
//
for (UINT32 i = 0; i < MAX_NUMBER_OF_IDT_ENTRIES; i++)
{
- IdtQueryRequest->IdtEntry[i] = (UINT64)((unsigned long long)IdtEntries[i].HighestPart << 32) |
- ((unsigned long long)IdtEntries[i].HighPart << 16) |
- (unsigned long long)IdtEntries[i].LowPart;
+ IdtQueryRequest->IdtEntry[i] = (UINT64)((UINT64)IdtEntries[i].HighestPart << 32) |
+ ((UINT64)IdtEntries[i].HighPart << 16) |
+ (UINT64)IdtEntries[i].LowPart;
}
}
@@ -132,7 +132,7 @@ IdtEmulationPrepareHostIdt(_Inout_ VIRTUAL_MACHINE_STATE * VCpu)
HOST_IDT_DESCRIPTOR_COUNT * sizeof(SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64));
/*
- for (size_t i = 0; i < HOST_IDT_DESCRIPTOR_COUNT; i++)
+ for (SIZE_T i = 0; i < HOST_IDT_DESCRIPTOR_COUNT; i++)
{
SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64 CurrentEntry = WindowsIdt[i];
@@ -198,7 +198,7 @@ IdtEmulationhandleHostInterrupt(_Inout_ INTERRUPT_TRAP_FRAME * IntrTrapFrame)
//
// Store the latest exception vector
//
- VCpu->LastExceptionOccuredInHost = IntrTrapFrame->vector;
+ VCpu->LastExceptionOccurredInHost = IntrTrapFrame->vector;
switch (IntrTrapFrame->vector)
{
@@ -217,7 +217,7 @@ IdtEmulationhandleHostInterrupt(_Inout_ INTERRUPT_TRAP_FRAME * IntrTrapFrame)
if (!VmxBroadcastHandleNmiCallback((PVOID)IntrTrapFrame, FALSE))
{
//
- // We cannot just use the NMI Window Exiting here becasue
+ // We cannot just use the NMI Window Exiting here because
// in certain scenarios, VMRESUME with Error 0x7 will happen
// Which means that the layout of the VMCS is wrong
//
@@ -258,7 +258,7 @@ IdtEmulationhandleHostInterrupt(_Inout_ INTERRUPT_TRAP_FRAME * IntrTrapFrame)
//
// host page-fault
//
- PageFaultCr2 = __readcr2();
+ PageFaultCr2 = CpuReadCr2();
LogInfo("Page-fault received, rip: %llx, rsp: %llx, error: %llx, CR2: %llx",
IntrTrapFrame->rip,
@@ -278,6 +278,7 @@ IdtEmulationhandleHostInterrupt(_Inout_ INTERRUPT_TRAP_FRAME * IntrTrapFrame)
IntrTrapFrame->rsp,
IntrTrapFrame->error,
IntrTrapFrame->vector);
+ DbgBreakPoint();
break;
}
@@ -308,7 +309,7 @@ IdtEmulationHandlePageFaults(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
//
// Read the page-fault address
//
- __vmx_vmread(VMCS_EXIT_QUALIFICATION, &PageFaultAddress);
+ VmxVmread64P(VMCS_EXIT_QUALIFICATION, &PageFaultAddress);
// LogInfo("#PF Fault = %016llx, Page Fault Code = 0x%x | %s%s%s%s",
// PageFaultAddress,
@@ -355,7 +356,8 @@ IdtEmulationHandleExceptionAndNmi(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
UINT64 GuestRip = NULL64_ZERO;
BYTE TargetMem = NULL_ZERO;
- __vmx_vmread(VMCS_GUEST_RIP, &GuestRip);
+ VmxVmread64P(VMCS_GUEST_RIP, &GuestRip);
+
MemoryMapperReadMemorySafe(GuestRip, &TargetMem, sizeof(BYTE));
if (!EptCheckAndHandleBreakpoint(VCpu) || TargetMem == 0xcc)
@@ -433,7 +435,7 @@ IdtEmulationHandleExceptionAndNmi(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
if (VCpu->EnableExternalInterruptsOnContinue ||
VCpu->EnableExternalInterruptsOnContinueMtf ||
- VCpu->RegisterBreakOnMtf)
+ VCpu->InstrumentationStepInMtf)
{
//
// Ignore the nmi
@@ -479,7 +481,7 @@ IdtEmulationInjectInterruptWhenInterruptWindowIsOpen(_Inout_ VIRTUAL_MACHINE_STA
// We can't inject interrupt because the guest's state is not interruptible
// we have to queue it an re-inject it when the interrupt window is opened !
//
- for (size_t i = 0; i < PENDING_INTERRUPTS_BUFFER_CAPACITY; i++)
+ for (SIZE_T i = 0; i < PENDING_INTERRUPTS_BUFFER_CAPACITY; i++)
{
//
// Find an empty space
@@ -516,11 +518,11 @@ IdtEmulationHandleExternalInterrupt(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
//
// In order to enable External Interrupt Exiting we have to set
- // PIN_BASED_VM_EXECUTION_CONTROLS_EXTERNAL_INTERRUPT in vmx
+ // IA32_VMX_PINBASED_CTLS_EXTERNAL_INTERRUPT_EXITING_FLAG in vmx
// pin-based controls (PIN_BASED_VM_EXEC_CONTROL) and also
- // we should enable VM_EXIT_ACK_INTR_ON_EXIT on vmx vm-exit
- // controls (VMCS_CTRL_VMEXIT_CONTROLS), also this function might not
- // always be successful if the guest is not in the interruptible
+ // we should enable IA32_VMX_EXIT_CTLS_ACKNOWLEDGE_INTERRUPT_ON_EXIT_FLAG
+ // on vmx vm-exit controls (VMCS_CTRL_VMEXIT_CONTROLS), also this function
+ // might not always be successful if the guest is not in the interruptible
// state so it wait for and interrupt-window exiting to re-inject
// the interrupt into the guest
//
@@ -675,7 +677,7 @@ IdtEmulationHandleInterruptWindowExiting(_Inout_ VIRTUAL_MACHINE_STATE * VCpu)
//
if (!InjectPageFault)
{
- for (size_t i = 0; i < PENDING_INTERRUPTS_BUFFER_CAPACITY; i++)
+ for (SIZE_T i = 0; i < PENDING_INTERRUPTS_BUFFER_CAPACITY; i++)
{
//
// Find an empty space
diff --git a/hyperdbg/hyperhv/code/vmm/vmx/IoHandler.c b/hyperdbg/hyperhv/code/vmm/vmx/IoHandler.c
index b506b337..77daa753 100644
--- a/hyperdbg/hyperhv/code/vmm/vmx/IoHandler.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/IoHandler.c
@@ -37,12 +37,12 @@ IoHandleIoVmExits(VIRTUAL_MACHINE_STATE * VCpu, VMX_EXIT_QUALIFICATION_IO_INSTRU
union
{
- unsigned char * AsBytePtr;
- unsigned short * AsWordPtr;
- unsigned long * AsDwordPtr;
+ UCHAR * AsBytePtr;
+ USHORT * AsWordPtr;
+ ULONG * AsDwordPtr;
- void * AsPtr;
- UINT64 AsUint64;
+ PVOID AsPtr;
+ UINT64 AsUInt64;
} PortValue;
@@ -215,11 +215,11 @@ IoHandleSetIoBitmap(VIRTUAL_MACHINE_STATE * VCpu, UINT32 Port)
{
if (Port <= 0x7FFF)
{
- SetBit(Port, (unsigned long *)VCpu->IoBitmapVirtualAddressA);
+ SetBit(Port, (ULONG *)VCpu->IoBitmapVirtualAddressA);
}
else if ((0x8000 <= Port) && (Port <= 0xFFFF))
{
- SetBit(Port - 0x8000, (unsigned long *)VCpu->IoBitmapVirtualAddressB);
+ SetBit(Port - 0x8000, (ULONG *)VCpu->IoBitmapVirtualAddressB);
}
else
{
@@ -245,8 +245,8 @@ IoHandlePerformIoBitmapChange(VIRTUAL_MACHINE_STATE * VCpu, UINT32 Port)
//
// Means all the bitmaps should be put to 1
//
- memset((void *)VCpu->IoBitmapVirtualAddressA, 0xFF, PAGE_SIZE);
- memset((void *)VCpu->IoBitmapVirtualAddressB, 0xFF, PAGE_SIZE);
+ memset((PVOID)VCpu->IoBitmapVirtualAddressA, 0xFF, PAGE_SIZE);
+ memset((PVOID)VCpu->IoBitmapVirtualAddressB, 0xFF, PAGE_SIZE);
}
else
{
@@ -270,6 +270,6 @@ IoHandlePerformIoBitmapReset(VIRTUAL_MACHINE_STATE * VCpu)
//
// Means all the bitmaps should be put to 0
//
- memset((void *)VCpu->IoBitmapVirtualAddressA, 0x0, PAGE_SIZE);
- memset((void *)VCpu->IoBitmapVirtualAddressB, 0x0, PAGE_SIZE);
+ memset((PVOID)VCpu->IoBitmapVirtualAddressA, 0x0, PAGE_SIZE);
+ memset((PVOID)VCpu->IoBitmapVirtualAddressB, 0x0, PAGE_SIZE);
}
diff --git a/hyperdbg/hyperhv/code/vmm/vmx/ManageRegs.c b/hyperdbg/hyperhv/code/vmm/vmx/ManageRegs.c
index 6127d337..ad816203 100644
--- a/hyperdbg/hyperhv/code/vmm/vmx/ManageRegs.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/ManageRegs.c
@@ -1,4 +1,4 @@
-/**
+/**
* @file ManageRegs.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @author Alee Amini (alee@hyperdbg.org)
@@ -21,7 +21,7 @@
VOID
SetGuestCsSel(PVMX_SEGMENT_SELECTOR Cs)
{
- __vmx_vmwrite(VMCS_GUEST_CS_SELECTOR, Cs->Selector);
+ VmxVmwrite16(VMCS_GUEST_CS_SELECTOR, Cs->Selector);
}
/**
@@ -34,10 +34,10 @@ SetGuestCsSel(PVMX_SEGMENT_SELECTOR Cs)
VOID
SetGuestCs(PVMX_SEGMENT_SELECTOR Cs)
{
- __vmx_vmwrite(VMCS_GUEST_CS_BASE, Cs->Base);
- __vmx_vmwrite(VMCS_GUEST_CS_LIMIT, Cs->Limit);
- __vmx_vmwrite(VMCS_GUEST_CS_ACCESS_RIGHTS, Cs->Attributes.AsUInt);
- __vmx_vmwrite(VMCS_GUEST_CS_SELECTOR, Cs->Selector);
+ VmxVmwrite64(VMCS_GUEST_CS_BASE, Cs->Base);
+ VmxVmwrite32(VMCS_GUEST_CS_LIMIT, Cs->Limit);
+ VmxVmwrite32(VMCS_GUEST_CS_ACCESS_RIGHTS, Cs->Attributes.AsUInt);
+ VmxVmwrite16(VMCS_GUEST_CS_SELECTOR, Cs->Selector);
}
/**
@@ -50,7 +50,7 @@ GetGuestCs()
{
VMX_SEGMENT_SELECTOR Cs;
- __vmx_vmread(VMCS_GUEST_CS_BASE, &Cs.Base);
+ VmxVmread64P(VMCS_GUEST_CS_BASE, &Cs.Base);
VmxVmread32P(VMCS_GUEST_CS_LIMIT, &Cs.Limit);
VmxVmread32P(VMCS_GUEST_CS_ACCESS_RIGHTS, &Cs.Attributes.AsUInt);
VmxVmread16P(VMCS_GUEST_CS_SELECTOR, &Cs.Selector);
@@ -67,7 +67,7 @@ GetGuestCs()
VOID
SetGuestSsSel(PVMX_SEGMENT_SELECTOR Ss)
{
- __vmx_vmwrite(VMCS_GUEST_SS_SELECTOR, Ss->Selector);
+ VmxVmwrite16(VMCS_GUEST_SS_SELECTOR, Ss->Selector);
}
/**
@@ -95,7 +95,7 @@ GetGuestSs()
{
VMX_SEGMENT_SELECTOR Ss;
- __vmx_vmread(VMCS_GUEST_SS_BASE, &Ss.Base);
+ VmxVmread64P(VMCS_GUEST_SS_BASE, &Ss.Base);
VmxVmread32P(VMCS_GUEST_SS_LIMIT, &Ss.Limit);
VmxVmread32P(VMCS_GUEST_SS_ACCESS_RIGHTS, &Ss.Attributes.AsUInt);
VmxVmread16P(VMCS_GUEST_SS_SELECTOR, &Ss.Selector);
@@ -140,7 +140,7 @@ GetGuestDs()
{
VMX_SEGMENT_SELECTOR Ds;
- __vmx_vmread(VMCS_GUEST_DS_BASE, &Ds.Base);
+ VmxVmread64P(VMCS_GUEST_DS_BASE, &Ds.Base);
VmxVmread32P(VMCS_GUEST_DS_LIMIT, &Ds.Limit);
VmxVmread32P(VMCS_GUEST_DS_ACCESS_RIGHTS, &Ds.Attributes.AsUInt);
VmxVmread16P(VMCS_GUEST_DS_SELECTOR, &Ds.Selector);
@@ -185,7 +185,7 @@ GetGuestFs()
{
VMX_SEGMENT_SELECTOR Fs;
- __vmx_vmread(VMCS_GUEST_FS_BASE, &Fs.Base);
+ VmxVmread64P(VMCS_GUEST_FS_BASE, &Fs.Base);
VmxVmread32P(VMCS_GUEST_FS_LIMIT, &Fs.Limit);
VmxVmread32P(VMCS_GUEST_FS_ACCESS_RIGHTS, &Fs.Attributes.AsUInt);
VmxVmread16P(VMCS_GUEST_FS_SELECTOR, &Fs.Selector);
@@ -230,7 +230,7 @@ GetGuestGs()
{
VMX_SEGMENT_SELECTOR Gs;
- __vmx_vmread(VMCS_GUEST_GS_BASE, &Gs.Base);
+ VmxVmread64P(VMCS_GUEST_GS_BASE, &Gs.Base);
VmxVmread32P(VMCS_GUEST_GS_LIMIT, &Gs.Limit);
VmxVmread32P(VMCS_GUEST_GS_ACCESS_RIGHTS, &Gs.Attributes.AsUInt);
VmxVmread16P(VMCS_GUEST_GS_SELECTOR, &Gs.Selector);
@@ -275,7 +275,7 @@ GetGuestEs()
{
VMX_SEGMENT_SELECTOR Es;
- __vmx_vmread(VMCS_GUEST_ES_BASE, &Es.Base);
+ VmxVmread64P(VMCS_GUEST_ES_BASE, &Es.Base);
VmxVmread32P(VMCS_GUEST_ES_LIMIT, &Es.Limit);
VmxVmread32P(VMCS_GUEST_ES_ACCESS_RIGHTS, &Es.Attributes.AsUInt);
VmxVmread16P(VMCS_GUEST_ES_SELECTOR, &Es.Selector);
@@ -305,7 +305,7 @@ GetGuestIdtr()
{
UINT64 Idtr;
- __vmx_vmread(VMCS_GUEST_IDTR_BASE, &Idtr);
+ VmxVmread64P(VMCS_GUEST_IDTR_BASE, &Idtr);
return Idtr;
}
@@ -332,7 +332,7 @@ GetGuestLdtr()
{
UINT64 Ldtr;
- __vmx_vmread(VMCS_GUEST_LDTR_BASE, &Ldtr);
+ VmxVmread64P(VMCS_GUEST_LDTR_BASE, &Ldtr);
return Ldtr;
}
@@ -359,7 +359,7 @@ GetGuestGdtr()
{
UINT64 Gdtr;
- __vmx_vmread(VMCS_GUEST_GDTR_BASE, &Gdtr);
+ VmxVmread64P(VMCS_GUEST_GDTR_BASE, &Gdtr);
return Gdtr;
}
@@ -384,7 +384,7 @@ GetGuestTr()
{
UINT64 Tr;
- __vmx_vmread(VMCS_GUEST_TR_BASE, &Tr);
+ VmxVmread64P(VMCS_GUEST_TR_BASE, &Tr);
return Tr;
}
@@ -409,7 +409,9 @@ UINT64
GetGuestRFlags()
{
UINT64 RFlags;
- __vmx_vmread(VMCS_GUEST_RFLAGS, &RFlags);
+
+ VmxVmread64P(VMCS_GUEST_RFLAGS, &RFlags);
+
return RFlags;
}
@@ -447,7 +449,8 @@ GetGuestRIP()
{
UINT64 RIP;
- __vmx_vmread(VMCS_GUEST_RIP, &RIP);
+ VmxVmread64P(VMCS_GUEST_RIP, &RIP);
+
return RIP;
}
@@ -461,7 +464,8 @@ GetGuestCr0()
{
UINT64 Cr0;
- __vmx_vmread(VMCS_GUEST_CR0, &Cr0);
+ VmxVmread64P(VMCS_GUEST_CR0, &Cr0);
+
return Cr0;
}
@@ -475,7 +479,7 @@ GetGuestCr2()
{
UINT64 Cr2;
- Cr2 = __readcr2();
+ Cr2 = CpuReadCr2();
return Cr2;
}
@@ -489,7 +493,8 @@ GetGuestCr3()
{
UINT64 Cr3;
- __vmx_vmread(VMCS_GUEST_CR3, &Cr3);
+ VmxVmread64P(VMCS_GUEST_CR3, &Cr3);
+
return Cr3;
}
@@ -503,7 +508,8 @@ GetGuestCr4()
{
UINT64 Cr4;
- __vmx_vmread(VMCS_GUEST_CR4, &Cr4);
+ VmxVmread64P(VMCS_GUEST_CR4, &Cr4);
+
return Cr4;
}
@@ -517,7 +523,7 @@ GetGuestCr8()
{
UINT64 Cr8;
- Cr8 = __readcr8();
+ Cr8 = CpuReadCr8();
return Cr8;
}
@@ -542,7 +548,7 @@ SetGuestCr0(UINT64 Cr0)
VOID
SetGuestCr2(UINT64 Cr2)
{
- __writecr2(Cr2);
+ CpuWriteCr2(Cr2);
}
/**
@@ -578,7 +584,7 @@ SetGuestCr4(UINT64 Cr4)
VOID
SetGuestCr8(UINT64 Cr8)
{
- __writecr8(Cr8);
+ CpuWriteCr8(Cr8);
}
/**
@@ -590,7 +596,7 @@ SetGuestCr8(UINT64 Cr8)
VOID
SetGuestDr0(UINT64 value)
{
- __writedr(0, value);
+ CpuWriteDr(0, value);
}
/**
@@ -602,7 +608,7 @@ SetGuestDr0(UINT64 value)
VOID
SetGuestDr1(UINT64 value)
{
- __writedr(1, value);
+ CpuWriteDr(1, value);
}
/**
@@ -614,7 +620,7 @@ SetGuestDr1(UINT64 value)
VOID
SetGuestDr2(UINT64 value)
{
- __writedr(2, value);
+ CpuWriteDr(2, value);
}
/**
@@ -626,7 +632,7 @@ SetGuestDr2(UINT64 value)
VOID
SetGuestDr3(UINT64 value)
{
- __writedr(3, value);
+ CpuWriteDr(3, value);
}
/**
@@ -638,7 +644,7 @@ SetGuestDr3(UINT64 value)
VOID
SetGuestDr6(UINT64 value)
{
- __writedr(6, value);
+ CpuWriteDr(6, value);
}
/**
@@ -650,7 +656,7 @@ SetGuestDr6(UINT64 value)
VOID
SetGuestDr7(UINT64 value)
{
- __writedr(7, value);
+ CpuWriteDr(7, value);
}
/**
@@ -662,7 +668,7 @@ UINT64
GetGuestDr0()
{
UINT64 Dr0 = 0;
- Dr0 = __readdr(0);
+ Dr0 = CpuReadDr(0);
return Dr0;
}
@@ -675,7 +681,7 @@ UINT64
GetGuestDr1()
{
UINT64 Dr1 = 0;
- Dr1 = __readdr(1);
+ Dr1 = CpuReadDr(1);
return Dr1;
}
@@ -688,7 +694,7 @@ UINT64
GetGuestDr2()
{
UINT64 Dr2 = 0;
- Dr2 = __readdr(2);
+ Dr2 = CpuReadDr(2);
return Dr2;
}
@@ -701,7 +707,7 @@ UINT64
GetGuestDr3()
{
UINT64 Dr3 = 0;
- Dr3 = __readdr(3);
+ Dr3 = CpuReadDr(3);
return Dr3;
}
@@ -714,7 +720,7 @@ UINT64
GetGuestDr6()
{
UINT64 Dr6 = 0;
- Dr6 = __readdr(6);
+ Dr6 = CpuReadDr(6);
return Dr6;
}
@@ -727,6 +733,6 @@ UINT64
GetGuestDr7()
{
UINT64 Dr7 = 0;
- Dr7 = __readdr(7);
+ Dr7 = CpuReadDr(7);
return Dr7;
}
diff --git a/hyperdbg/hyperhv/code/vmm/vmx/MsrHandlers.c b/hyperdbg/hyperhv/code/vmm/vmx/MsrHandlers.c
index ca47bec3..2600002a 100644
--- a/hyperdbg/hyperhv/code/vmm/vmx/MsrHandlers.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/MsrHandlers.c
@@ -11,6 +11,49 @@
*/
#include "pch.h"
+/**
+ * @brief Checks whether an MSR belongs to the Hyper-V synthetic MSR set
+ * @details The ranges and individual registers are defined by Hyper-V TLFS
+ * synthetic MSRs and mirrored in HypervTlfs.h.
+ *
+ * @param TargetMsr The target MSR
+ * @return BOOLEAN Returns TRUE if the MSR should be forwarded to the
+ * top-level Hyper-V compatible hypervisor
+ */
+BOOLEAN
+MsrHandleIsHypervSyntheticMsr(_In_ UINT32 TargetMsr)
+{
+ switch (TargetMsr)
+ {
+ case HV_X64_MSR_GUEST_OS_ID:
+ case HV_X64_MSR_HYPERCALL:
+ case HV_X64_MSR_VP_INDEX:
+ case HV_X64_MSR_RESET:
+ case HV_X64_MSR_VP_RUNTIME:
+ case HV_X64_MSR_TIME_REF_COUNT:
+ case HV_X64_MSR_REFERENCE_TSC:
+ case HV_X64_MSR_TSC_FREQUENCY:
+ case HV_X64_MSR_APIC_FREQUENCY:
+ case HV_X64_MSR_NPIEP_CONFIG:
+ case HV_X64_MSR_GUEST_IDLE:
+ case HV_X64_MSR_REENLIGHTENMENT_CONTROL:
+ case HV_X64_MSR_TSC_EMULATION_CONTROL:
+ case HV_X64_MSR_TSC_EMULATION_STATUS:
+ case HV_X64_MSR_STIME_UNHALTED_TIMER_CONFIG:
+ case HV_X64_MSR_STIME_UNHALTED_TIMER_COUNT:
+ case HV_X64_MSR_NESTED_VP_INDEX:
+ return TRUE;
+ default:
+ return (TargetMsr >= HV_X64_MSR_EOI && TargetMsr <= HV_X64_MSR_TPR) ||
+ (TargetMsr >= HV_X64_MSR_SCONTROL && TargetMsr <= HV_X64_MSR_EOM) ||
+ (TargetMsr >= HV_X64_MSR_SINT0 && TargetMsr <= HV_X64_MSR_SINT15) ||
+ (TargetMsr >= HV_X64_MSR_STIMER0_CONFIG && TargetMsr <= HV_X64_MSR_STIMER3_COUNT) ||
+ (TargetMsr >= HV_X64_MSR_CRASH_P0 && TargetMsr <= HV_X64_MSR_CRASH_CTL) ||
+ (TargetMsr >= HV_X64_MSR_NESTED_SCONTROL && TargetMsr <= HV_X64_MSR_NESTED_EOM) ||
+ (TargetMsr >= HV_X64_MSR_NESTED_SINT0 && TargetMsr <= HV_X64_MSR_NESTED_SINT15);
+ }
+}
+
/**
* @brief Handles in the cases when RDMSR causes a vm-exit
*
@@ -54,6 +97,19 @@ MsrHandleRdmsrVmexit(VIRTUAL_MACHINE_STATE * VCpu)
// TargetMsr,
// VCpu->LastVmexitRip);
+ //
+ // Checking whether it is a synthetic MSR for Hyper-V
+ //
+ if (g_IsTopLevelHypervisorHyperV && MsrHandleIsHypervSyntheticMsr(TargetMsr))
+ {
+ Msr.Flags = CpuReadMsr(TargetMsr);
+
+ GuestRegs->rax = Msr.Fields.Low;
+ GuestRegs->rdx = Msr.Fields.High;
+
+ return;
+ }
+
//
// Check for sanity of MSR if they're valid or they're for reserved range for WRMSR and RDMSR
//
@@ -114,7 +170,7 @@ MsrHandleRdmsrVmexit(VIRTUAL_MACHINE_STATE * VCpu)
//
// Check whether the MSR should cause #GP or not
//
- if (TargetMsr <= 0xfff && TestBit(TargetMsr, (unsigned long *)g_MsrBitmapInvalidMsrs) != NULL64_ZERO)
+ if (TargetMsr <= 0xfff && TestBit(TargetMsr, (ULONG *)g_MsrBitmapInvalidMsrs) != NULL64_ZERO)
{
//
// Invalid MSR between 0x0 to 0xfff
@@ -134,7 +190,7 @@ MsrHandleRdmsrVmexit(VIRTUAL_MACHINE_STATE * VCpu)
//
// Msr is valid
//
- Msr.Flags = __readmsr(TargetMsr);
+ Msr.Flags = CpuReadMsr(TargetMsr);
//
// Check if it's EFER MSR then we show a false SCE state
@@ -204,6 +260,15 @@ MsrHandleWrmsrVmexit(VIRTUAL_MACHINE_STATE * VCpu)
// GuestRegs->rdx,
// VCpu->LastVmexitRip);
+ //
+ // Checking whether it is a synthetic MSR for Hyper-V
+ //
+ if (g_IsTopLevelHypervisorHyperV && MsrHandleIsHypervSyntheticMsr(TargetMsr))
+ {
+ CpuWriteMsr(TargetMsr, Msr.Flags);
+ return;
+ }
+
//
// Check for sanity of MSR if they're valid or they're for reserved range for WRMSR and RDMSR
//
@@ -278,7 +343,7 @@ MsrHandleWrmsrVmexit(VIRTUAL_MACHINE_STATE * VCpu)
//
// Perform the WRMSR
//
- __writemsr((unsigned long)GuestRegs->rcx, Msr.Flags);
+ CpuWriteMsr((ULONG)GuestRegs->rcx, Msr.Flags);
break;
}
@@ -317,22 +382,22 @@ MsrHandleSetMsrBitmap(VIRTUAL_MACHINE_STATE * VCpu, UINT32 Msr, BOOLEAN ReadDete
{
if (ReadDetection)
{
- SetBit(Msr, (unsigned long *)VCpu->MsrBitmapVirtualAddress);
+ SetBit(Msr, (ULONG *)VCpu->MsrBitmapVirtualAddress);
}
if (WriteDetection)
{
- SetBit(Msr, (unsigned long *)VCpu->MsrBitmapVirtualAddress + 2048);
+ SetBit(Msr, (ULONG *)VCpu->MsrBitmapVirtualAddress + 2048);
}
}
else if ((0xC0000000 <= Msr) && (Msr <= 0xC0001FFF))
{
if (ReadDetection)
{
- SetBit(Msr - 0xC0000000, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 1024));
+ SetBit(Msr - 0xC0000000, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 1024));
}
if (WriteDetection)
{
- SetBit(Msr - 0xC0000000, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 3072));
+ SetBit(Msr - 0xC0000000, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 3072));
}
}
else
@@ -366,22 +431,22 @@ MsrHandleUnSetMsrBitmap(VIRTUAL_MACHINE_STATE * VCpu, UINT32 Msr, BOOLEAN ReadDe
{
if (ReadDetection)
{
- ClearBit(Msr, (unsigned long *)VCpu->MsrBitmapVirtualAddress);
+ ClearBit(Msr, (ULONG *)VCpu->MsrBitmapVirtualAddress);
}
if (WriteDetection)
{
- ClearBit(Msr, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 2048));
+ ClearBit(Msr, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 2048));
}
}
else if ((0xC0000000 <= Msr) && (Msr <= 0xC0001FFF))
{
if (ReadDetection)
{
- ClearBit(Msr - 0xC0000000, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 1024));
+ ClearBit(Msr - 0xC0000000, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 1024));
}
if (WriteDetection)
{
- ClearBit(Msr - 0xC0000000, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 3072));
+ ClearBit(Msr - 0xC0000000, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 3072));
}
}
else
@@ -404,13 +469,13 @@ MsrHandleFilterMsrReadBitmap(VIRTUAL_MACHINE_STATE * VCpu)
//
// Ignore IA32_KERNEL_GSBASE (0xC0000102)
//
- ClearBit(0x102, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 1024));
+ ClearBit(0x102, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 1024));
//
// Ignore IA32_MPERF (0x000000e7), and IA32_APERF (0x000000e8)
//
- ClearBit(0xe7, (unsigned long *)VCpu->MsrBitmapVirtualAddress);
- ClearBit(0xe8, (unsigned long *)VCpu->MsrBitmapVirtualAddress);
+ ClearBit(0xe7, (ULONG *)VCpu->MsrBitmapVirtualAddress);
+ ClearBit(0xe8, (ULONG *)VCpu->MsrBitmapVirtualAddress);
}
/**
@@ -426,19 +491,19 @@ MsrHandleFilterMsrWriteBitmap(VIRTUAL_MACHINE_STATE * VCpu)
//
// Ignore IA32_KERNEL_GSBASE (0xC0000102)
//
- ClearBit(0x102, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 3072));
+ ClearBit(0x102, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 3072));
//
// Ignore IA32_MPERF (0x000000e7), and IA32_APERF (0x000000e8)
//
- ClearBit(0xe7, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 2048));
- ClearBit(0xe8, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 2048));
+ ClearBit(0xe7, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 2048));
+ ClearBit(0xe8, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 2048));
//
// Ignore IA32_SPEC_CTRL (0x00000048), and IA32_PRED_CMD (0x00000049)
//
- ClearBit(0x48, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 2048));
- ClearBit(0x49, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 2048));
+ ClearBit(0x48, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 2048));
+ ClearBit(0x49, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 2048));
}
/**
@@ -457,7 +522,7 @@ MsrHandlePerformMsrBitmapReadChange(VIRTUAL_MACHINE_STATE * VCpu, UINT32 MsrMask
//
// Means all the bitmaps should be put to 1
//
- memset((void *)VCpu->MsrBitmapVirtualAddress, 0xff, 2048);
+ memset((PVOID)VCpu->MsrBitmapVirtualAddress, 0xff, 2048);
//
// Filter MSR Bitmap for special MSRs
@@ -486,7 +551,7 @@ MsrHandlePerformMsrBitmapReadReset(VIRTUAL_MACHINE_STATE * VCpu)
//
// Means all the bitmaps should be put to 0
//
- memset((void *)VCpu->MsrBitmapVirtualAddress, 0x0, 2048);
+ memset((PVOID)VCpu->MsrBitmapVirtualAddress, 0x0, 2048);
}
/**
* @brief Change MSR Bitmap for write
@@ -504,7 +569,7 @@ MsrHandlePerformMsrBitmapWriteChange(VIRTUAL_MACHINE_STATE * VCpu, UINT32 MsrMas
//
// Means all the bitmaps should be put to 1
//
- memset((void *)((UINT64)VCpu->MsrBitmapVirtualAddress + 2048), 0xff, 2048);
+ memset((PVOID)((UINT64)VCpu->MsrBitmapVirtualAddress + 2048), 0xff, 2048);
//
// Filter MSR Bitmap for special MSRs
@@ -533,5 +598,5 @@ MsrHandlePerformMsrBitmapWriteReset(VIRTUAL_MACHINE_STATE * VCpu)
//
// Means all the bitmaps should be put to 0
//
- memset((void *)((UINT64)VCpu->MsrBitmapVirtualAddress + 2048), 0x0, 2048);
+ memset((PVOID)((UINT64)VCpu->MsrBitmapVirtualAddress + 2048), 0x0, 2048);
}
diff --git a/hyperdbg/hyperhv/code/vmm/vmx/Mtf.c b/hyperdbg/hyperhv/code/vmm/vmx/Mtf.c
index 466442b4..c8a004d0 100644
--- a/hyperdbg/hyperhv/code/vmm/vmx/Mtf.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/Mtf.c
@@ -33,18 +33,10 @@ MtfHandleVmexit(VIRTUAL_MACHINE_STATE * VCpu)
VCpu->IgnoreMtfUnset = FALSE;
//
- // Check if we need to re-apply a breakpoint or not
- // We check it separately because the guest might step
- // instructions on an MTF so we want to check for the step too
+ // Check for KD related MTFs
//
- if (g_Callbacks.BreakpointCheckAndHandleReApplyingBreakpoint != NULL &&
- g_Callbacks.BreakpointCheckAndHandleReApplyingBreakpoint(VCpu->CoreId))
+ if (VmmCallbackHandleMtfCallback(VCpu->CoreId))
{
- //
- // Check for re-enabling external interrupts
- //
- HvEnableAndCheckForPreviousExternalInterrupts(VCpu);
-
//
// MTF is handled
//
@@ -77,48 +69,6 @@ MtfHandleVmexit(VIRTUAL_MACHINE_STATE * VCpu)
HvEnableAndCheckForPreviousExternalInterrupts(VCpu);
}
- //
- // Check for instrumentation step-in
- //
- if (VCpu->RegisterBreakOnMtf)
- {
- //
- // MTF is handled
- //
- IsMtfHandled = TRUE;
-
- //
- // Change the MTF registration state (might be changed in the caller)
- //
- VCpu->RegisterBreakOnMtf = FALSE;
-
- //
- // Handle MTF in the debugger
- //
- VmmCallbackRegisteredMtfHandler(VCpu->CoreId);
- }
-
- //
- // check the condition of passing the execution to NMIs
- //
- // This one wastes one week of my life!
- // During the testing we realized the !epthook command in Debugger Mode
- // is not working. After some tests, it's because if in the middle of a
- // command in vmx-root and NMI is sent and the debugger waits for another
- // MTF, we'll ignore that MTF and a new MTF is not set again.
- // That's why we moved this check here so every command that needs a task
- // from MTF is doing its tasks and when we reached here, the check for halting
- // the debuggee in MTF is performed
- //
- else if (g_Callbacks.KdCheckAndHandleNmiCallback != NULL &&
- g_Callbacks.KdCheckAndHandleNmiCallback(VCpu->CoreId))
- {
- //
- // MTF is handled
- //
- IsMtfHandled = TRUE;
- }
-
//
// Check for ignored MTFs
//
diff --git a/hyperdbg/hyperhv/code/vmm/vmx/ProtectedHv.c b/hyperdbg/hyperhv/code/vmm/vmx/ProtectedHv.c
index 84e61d1c..171e30e2 100644
--- a/hyperdbg/hyperhv/code/vmm/vmx/ProtectedHv.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/ProtectedHv.c
@@ -1,4 +1,4 @@
-/**
+/**
* @file ProtectedHv.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief File for protected hypervisor resources
@@ -215,11 +215,11 @@ ProtectedHvApplySetExternalInterruptExiting(VIRTUAL_MACHINE_STATE * VCpu, BOOLEA
//
// In order to enable External Interrupt Exiting we have to set
- // PIN_BASED_VM_EXECUTION_CONTROLS_EXTERNAL_INTERRUPT in vmx
+ // IA32_VMX_PINBASED_CTLS_EXTERNAL_INTERRUPT_EXITING_FLAG in vmx
// pin-based controls (PIN_BASED_VM_EXEC_CONTROL) and also
- // we should enable VM_EXIT_ACK_INTR_ON_EXIT on vmx vm-exit
- // controls (VMCS_CTRL_VMEXIT_CONTROLS), also this function might not
- // always be successful if the guest is not in the interruptible
+ // we should enable IA32_VMX_EXIT_CTLS_ACKNOWLEDGE_INTERRUPT_ON_EXIT_FLAG
+ // on vmx vm-exit controls (VMCS_CTRL_VMEXIT_CONTROLS), also this function
+ // might not always be successful if the guest is not in the interruptible
// state so it wait for and interrupt-window exiting to re-inject
// the interrupt into the guest
//
@@ -232,13 +232,13 @@ ProtectedHvApplySetExternalInterruptExiting(VIRTUAL_MACHINE_STATE * VCpu, BOOLEA
if (Set)
{
- PinBasedControls |= PIN_BASED_VM_EXECUTION_CONTROLS_EXTERNAL_INTERRUPT;
- VmExitControls |= VM_EXIT_ACK_INTR_ON_EXIT;
+ PinBasedControls |= IA32_VMX_PINBASED_CTLS_EXTERNAL_INTERRUPT_EXITING_FLAG;
+ VmExitControls |= IA32_VMX_EXIT_CTLS_ACKNOWLEDGE_INTERRUPT_ON_EXIT_FLAG;
}
else
{
- PinBasedControls &= ~PIN_BASED_VM_EXECUTION_CONTROLS_EXTERNAL_INTERRUPT;
- VmExitControls &= ~VM_EXIT_ACK_INTR_ON_EXIT;
+ PinBasedControls &= ~IA32_VMX_PINBASED_CTLS_EXTERNAL_INTERRUPT_EXITING_FLAG;
+ VmExitControls &= ~IA32_VMX_EXIT_CTLS_ACKNOWLEDGE_INTERRUPT_ON_EXIT_FLAG;
}
//
@@ -314,11 +314,11 @@ ProtectedHvSetTscVmexit(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set, PROTECTED_HV_
if (Set)
{
- CpuBasedVmExecControls |= CPU_BASED_RDTSC_EXITING;
+ CpuBasedVmExecControls |= IA32_VMX_PROCBASED_CTLS_RDTSC_EXITING_FLAG;
}
else
{
- CpuBasedVmExecControls &= ~CPU_BASED_RDTSC_EXITING;
+ CpuBasedVmExecControls &= ~IA32_VMX_PROCBASED_CTLS_RDTSC_EXITING_FLAG;
}
//
// Set the new value
@@ -368,11 +368,11 @@ ProtectedHvSetMovDebugRegsVmexit(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set, PROT
if (Set)
{
- CpuBasedVmExecControls |= CPU_BASED_MOV_DR_EXITING;
+ CpuBasedVmExecControls |= IA32_VMX_PROCBASED_CTLS_MOV_DR_EXITING_FLAG;
}
else
{
- CpuBasedVmExecControls &= ~CPU_BASED_MOV_DR_EXITING;
+ CpuBasedVmExecControls &= ~IA32_VMX_PROCBASED_CTLS_MOV_DR_EXITING_FLAG;
}
//
@@ -399,7 +399,7 @@ ProtectedHvSetMovToCrVmexit(BOOLEAN Set, UINT64 ControlRegister, UINT64 MaskRegi
if (Set)
{
VmxVmwrite64(VMCS_CTRL_CR0_GUEST_HOST_MASK, MaskRegister);
- VmxVmwrite64(VMCS_CTRL_CR0_READ_SHADOW, __readcr0());
+ VmxVmwrite64(VMCS_CTRL_CR0_READ_SHADOW, CpuReadCr0());
}
else
{
@@ -412,7 +412,7 @@ ProtectedHvSetMovToCrVmexit(BOOLEAN Set, UINT64 ControlRegister, UINT64 MaskRegi
if (Set)
{
VmxVmwrite64(VMCS_CTRL_CR4_GUEST_HOST_MASK, MaskRegister);
- VmxVmwrite64(VMCS_CTRL_CR4_READ_SHADOW, __readcr0());
+ VmxVmwrite64(VMCS_CTRL_CR4_READ_SHADOW, CpuReadCr0());
}
else
{
@@ -513,11 +513,11 @@ ProtectedHvSetMovToCr3Vmexit(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set, PROTECTE
if (Set)
{
- CpuBasedVmExecControls |= CPU_BASED_CR3_LOAD_EXITING;
+ CpuBasedVmExecControls |= IA32_VMX_PROCBASED_CTLS_CR3_LOAD_EXITING_FLAG;
}
else
{
- CpuBasedVmExecControls &= ~CPU_BASED_CR3_LOAD_EXITING;
+ CpuBasedVmExecControls &= ~IA32_VMX_PROCBASED_CTLS_CR3_LOAD_EXITING_FLAG;
}
//
@@ -526,6 +526,140 @@ ProtectedHvSetMovToCr3Vmexit(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set, PROTECTE
VmxVmwrite64(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, CpuBasedVmExecControls);
}
+/**
+ * @brief Set LOAD DEBUG CONTROLS on Vm-entry controls
+ *
+ * @param VCpu
+ * @param Set Set or unset
+ * @param PassOver
+ *
+ * @return VOID
+ */
+VOID
+ProtectedHvSetLoadDebugControlsIntegrityCheck(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set, PROTECTED_HV_RESOURCES_PASSING_OVERS PassOver)
+{
+ UINT32 VmentryControls = 0;
+
+ //
+ // The protected checks are only performed if the "Set" is "FALSE",
+ // because if sb wants to set it to "TRUE" then we're no need to
+ // worry about it as it remains enabled
+ //
+ if (Set == FALSE)
+ {
+ //
+ // Check the top-level driver's state
+ //
+ if (VmmCallbackQueryTerminateProtectedResource(VCpu->CoreId,
+ PROTECTED_HV_RESOURCES_SAVE_AND_LOAD_DEBUG_CONTROLS,
+ NULL,
+ PassOver))
+ {
+ return;
+ }
+ }
+
+ //
+ // Read the previous flags
+ //
+ VmxVmread32P(VMCS_CTRL_VMENTRY_CONTROLS, &VmentryControls);
+
+ if (Set)
+ {
+ VmentryControls |= IA32_VMX_ENTRY_CTLS_LOAD_DEBUG_CONTROLS_FLAG;
+ }
+ else
+ {
+ VmentryControls &= ~IA32_VMX_ENTRY_CTLS_LOAD_DEBUG_CONTROLS_FLAG;
+ }
+
+ //
+ // Set the new value
+ //
+ VmxVmwrite32(VMCS_CTRL_VMENTRY_CONTROLS, VmentryControls);
+}
+
+/**
+ * @brief Set SAVE DEBUG CONTROLS on Vm-exit controls
+ *
+ * @param VCpu
+ * @param Set Set or unset
+ * @param PassOver
+ *
+ * @return VOID
+ */
+VOID
+ProtectedHvSetSaveDebugControlsIntegrityCheck(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set, PROTECTED_HV_RESOURCES_PASSING_OVERS PassOver)
+{
+ UINT32 VmexitControls = 0;
+
+ //
+ // The protected checks are only performed if the "Set" is "FALSE",
+ // because if sb wants to set it to "TRUE" then we're no need to
+ // worry about it as it remains enabled
+ //
+ if (Set == FALSE)
+ {
+ //
+ // Check the top-level driver's state
+ //
+ if (VmmCallbackQueryTerminateProtectedResource(VCpu->CoreId,
+ PROTECTED_HV_RESOURCES_SAVE_AND_LOAD_DEBUG_CONTROLS,
+ NULL,
+ PassOver))
+ {
+ return;
+ }
+ }
+
+ //
+ // Read the previous flags
+ //
+ VmxVmread32P(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, &VmexitControls);
+
+ if (Set)
+ {
+ VmexitControls |= IA32_VMX_EXIT_CTLS_SAVE_DEBUG_CONTROLS_FLAG;
+ }
+ else
+ {
+ VmexitControls &= ~IA32_VMX_EXIT_CTLS_SAVE_DEBUG_CONTROLS_FLAG;
+ }
+
+ //
+ // Set the new value
+ //
+ VmxVmwrite32(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, VmexitControls);
+}
+
+/**
+ * @brief Set LOAD DEBUG CONTROLS on VM-entry controls
+ *
+ * @param VCpu
+ * @param Set Set or unset
+ *
+ * @return VOID
+ */
+VOID
+ProtectedHvSetSaveDebugControls(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set)
+{
+ ProtectedHvSetSaveDebugControlsIntegrityCheck(VCpu, Set, PASSING_OVER_NONE);
+}
+
+/**
+ * @brief Set SAVE DEBUG CONTROLS on VM-exit controls
+ *
+ * @param VCpu
+ * @param Set Set or unset
+ *
+ * @return VOID
+ */
+VOID
+ProtectedHvSetLoadDebugControls(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set)
+{
+ ProtectedHvSetLoadDebugControlsIntegrityCheck(VCpu, Set, PASSING_OVER_NONE);
+}
+
/**
* @brief Set the RDTSC/P Exiting
*
diff --git a/hyperdbg/hyperhv/code/vmm/vmx/Vmcall.c b/hyperdbg/hyperhv/code/vmm/vmx/Vmcall.c
index 267d305e..88f6d560 100644
--- a/hyperdbg/hyperhv/code/vmm/vmx/Vmcall.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/Vmcall.c
@@ -164,7 +164,7 @@ VmxVmcallHandler(VIRTUAL_MACHINE_STATE * VCpu,
}
case VMCALL_VMXOFF:
{
- VmxVmxoff(VCpu);
+ VmxPerformVmxoff(VCpu);
VmcallStatus = STATUS_SUCCESS;
break;
@@ -365,25 +365,25 @@ VmxVmcallHandler(VIRTUAL_MACHINE_STATE * VCpu,
}
case VMCALL_SET_VM_ENTRY_LOAD_DEBUG_CONTROLS:
{
- HvSetLoadDebugControls(TRUE);
+ HvSetLoadDebugControls(VCpu, TRUE);
VmcallStatus = STATUS_SUCCESS;
break;
}
case VMCALL_UNSET_VM_ENTRY_LOAD_DEBUG_CONTROLS:
{
- HvSetLoadDebugControls(FALSE);
+ HvSetLoadDebugControls(VCpu, FALSE);
VmcallStatus = STATUS_SUCCESS;
break;
}
case VMCALL_SET_VM_EXIT_SAVE_DEBUG_CONTROLS:
{
- HvSetSaveDebugControls(TRUE);
+ HvSetSaveDebugControls(VCpu, TRUE);
VmcallStatus = STATUS_SUCCESS;
break;
}
case VMCALL_UNSET_VM_EXIT_SAVE_DEBUG_CONTROLS:
{
- HvSetSaveDebugControls(FALSE);
+ HvSetSaveDebugControls(VCpu, FALSE);
VmcallStatus = STATUS_SUCCESS;
break;
}
@@ -534,9 +534,83 @@ VmxVmcallHandler(VIRTUAL_MACHINE_STATE * VCpu,
break;
}
+ case VMCALL_GET_VMCS_DEBUGCTL:
+ {
+ //
+ // Perform getting DEBUGCTL from VMCS
+ //
+ HvGetAndStoreDebugctl((UINT64 *)OptionalParam1);
+
+ VmcallStatus = STATUS_SUCCESS;
+ break;
+ }
+ case VMCALL_SET_VMCS_DEBUGCTL:
+ {
+ //
+ // Perform setting DEBUGCTL from VMCS
+ //
+ HvSetDebugctl(OptionalParam1);
+
+ VmcallStatus = STATUS_SUCCESS;
+
+ break;
+ }
+ case VMCALL_SET_MSR_LBR_SELECT:
+ {
+ //
+ // Perform setting MSR_LEGACY_LBR_SELECT
+ //
+ HvSetLbrSelect(OptionalParam1);
+ VmcallStatus = STATUS_SUCCESS;
+ break;
+ }
+ case VMCALL_GET_GUEST_IA32_LBR_CTL:
+ {
+ //
+ // Perform getting guest IA32_LBR_CTL from VMCS
+ //
+ HvGetAndStoreGuestIa32LbrCtl((UINT64 *)OptionalParam1);
+
+ VmcallStatus = STATUS_SUCCESS;
+ break;
+ }
+ case VMCALL_SET_GUEST_IA32_LBR_CTL:
+ {
+ //
+ // Perform setting guest IA32_LBR_CTL on VMCS
+ //
+ HvSetGuestIa32LbrCtl(OptionalParam1);
+
+ VmcallStatus = STATUS_SUCCESS;
+ break;
+ }
+ case VMCALL_SET_VM_ENTRY_LOAD_GUEST_IA32_LBR_CTL:
+ {
+ HvSetLoadGuestIa32LbrCtl(VCpu, TRUE);
+ VmcallStatus = STATUS_SUCCESS;
+ break;
+ }
+ case VMCALL_UNSET_VM_ENTRY_LOAD_GUEST_IA32_LBR_CTL:
+ {
+ HvSetLoadGuestIa32LbrCtl(VCpu, FALSE);
+ VmcallStatus = STATUS_SUCCESS;
+ break;
+ }
+ case VMCALL_SET_CLEAR_GUEST_IA32_LBR_CTL:
+ {
+ HvSetClearGuestIa32LbrCtl(VCpu, TRUE);
+ VmcallStatus = STATUS_SUCCESS;
+ break;
+ }
+ case VMCALL_UNSET_CLEAR_GUEST_IA32_LBR_CTL:
+ {
+ HvSetClearGuestIa32LbrCtl(VCpu, FALSE);
+ VmcallStatus = STATUS_SUCCESS;
+ break;
+ }
default:
{
- LogError("Err, unsupported VMCALL");
+ LogError("Err, unsupported VMCALL (%llx)", VmcallNumber);
VmcallStatus = STATUS_UNSUCCESSFUL;
break;
}
diff --git a/hyperdbg/hyperhv/code/vmm/vmx/Vmexit.c b/hyperdbg/hyperhv/code/vmm/vmx/Vmexit.c
index f7a99fc8..54c5511d 100644
--- a/hyperdbg/hyperhv/code/vmm/vmx/Vmexit.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/Vmexit.c
@@ -31,9 +31,10 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
VCpu = &g_GuestState[KeGetCurrentProcessorNumberEx(NULL)];
//
- // Set the registers
+ // Set the registers (general-purpose and XMM)
//
- VCpu->Regs = GuestRegs;
+ VCpu->Regs = GuestRegs;
+ VCpu->XmmRegs = (GUEST_XMM_REGS *)(((CHAR *)GuestRegs) + sizeof(GUEST_REGS));
//
// Indicates we are in Vmx root mode in this logical core
@@ -59,12 +60,12 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
//
// Save the current rip
//
- __vmx_vmread(VMCS_GUEST_RIP, &VCpu->LastVmexitRip);
+ VmxVmread64P(VMCS_GUEST_RIP, &VCpu->LastVmexitRip);
//
// Set the rsp in general purpose registers structure
//
- __vmx_vmread(VMCS_GUEST_RSP, &VCpu->Regs->rsp);
+ VmxVmread64P(VMCS_GUEST_RSP, &VCpu->Regs->rsp);
//
// Read the exit qualification
@@ -77,6 +78,7 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
// LogInfo("VM_EXIT_REASON : 0x%x", ExitReason);
// LogInfo("VMCS_EXIT_QUALIFICATION : 0x%llx", VCpu->ExitQualification);
//
+
switch (ExitReason)
{
case VMX_EXIT_REASON_TRIPLE_FAULT:
@@ -106,7 +108,7 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
// cf=1 indicate vm instructions fail
//
// UINT64 Rflags = 0;
- // __vmx_vmread(VMCS_GUEST_RFLAGS, &Rflags);
+ // VmxVmread64P(VMCS_GUEST_RFLAGS, &Rflags);
// VmxVmwrite64(VMCS_GUEST_RFLAGS, Rflags | 0x1);
//
@@ -158,6 +160,9 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
case VMX_EXIT_REASON_IO_SMI:
case VMX_EXIT_REASON_SMI:
{
+ //
+ // Handle SMI and IO-SMI (should never happen in normal cases)
+ //
LogInfo("VM-exit reason SMM %llx | qual: %llx", ExitReason, VCpu->ExitQualification);
break;
@@ -183,6 +188,9 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
}
case VMX_EXIT_REASON_EPT_VIOLATION:
{
+ //
+ // Handle EPT violation
+ //
if (EptHandleEptViolation(VCpu) == FALSE)
{
LogError("Err, there were errors in handling EPT violation");
@@ -192,6 +200,9 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
}
case VMX_EXIT_REASON_EPT_MISCONFIGURATION:
{
+ //
+ // Handle EPT misconfiguration (should never happen)
+ //
EptHandleMisconfiguration();
break;
@@ -295,9 +306,9 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
case VMX_EXIT_REASON_EXECUTE_XSETBV:
{
//
- // Handle xsetbv (unconditional vm-exit)
+ // Dispatch and trigger the XSETBV instruction events
//
- VmxHandleXsetbv(VCpu);
+ DispatchEventXsetbv(VCpu);
break;
}
@@ -321,6 +332,9 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
}
default:
{
+ //
+ // Not handled vm-exit
+ //
LogError("Err, unknown vmexit, reason : 0x%llx", ExitReason);
break;
diff --git a/hyperdbg/hyperhv/code/vmm/vmx/Vmx.c b/hyperdbg/hyperhv/code/vmm/vmx/Vmx.c
index 939242f6..1de5c030 100644
--- a/hyperdbg/hyperhv/code/vmm/vmx/Vmx.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/Vmx.c
@@ -11,152 +11,6 @@
*/
#include "pch.h"
-/**
- * @brief VMX VMREAD instruction (64-bit)
- * @param Field
- * @param FieldValue
- *
- * @return UCHAR
- */
-inline UCHAR
-VmxVmread64(size_t Field,
- UINT64 FieldValue)
-{
- return __vmx_vmread((size_t)Field, (size_t *)FieldValue);
-}
-
-/**
- * @brief VMX VMREAD instruction (32-bit)
- * @param Field
- * @param FieldValue
- *
- * @return UCHAR
- */
-inline UCHAR
-VmxVmread32(size_t Field,
- UINT32 FieldValue)
-{
- UINT64 TargetField = 0ull;
-
- TargetField = FieldValue;
-
- return __vmx_vmread((size_t)Field, (size_t *)TargetField);
-}
-
-/**
- * @brief VMX VMREAD instruction (16-bit)
- * @param Field
- * @param FieldValue
- *
- * @return UCHAR
- */
-inline UCHAR
-VmxVmread16(size_t Field,
- UINT16 FieldValue)
-{
- UINT64 TargetField = 0ull;
-
- TargetField = FieldValue;
-
- return __vmx_vmread((size_t)Field, (size_t *)TargetField);
-}
-
-/**
- * @brief VMX VMREAD instruction (64-bit)
- * @param Field
- * @param FieldValue
- *
- * @return UCHAR
- */
-inline UCHAR
-VmxVmread64P(size_t Field,
- UINT64 * FieldValue)
-{
- return __vmx_vmread((size_t)Field, (size_t *)FieldValue);
-}
-
-/**
- * @brief VMX VMREAD instruction (32-bit)
- * @param Field
- * @param FieldValue
- *
- * @return UCHAR
- */
-inline UCHAR
-VmxVmread32P(size_t Field,
- UINT32 * FieldValue)
-{
- UINT64 TargetField = 0ull;
-
- TargetField = (UINT64)FieldValue;
-
- return __vmx_vmread((size_t)Field, (size_t *)TargetField);
-}
-
-/**
- * @brief VMX VMREAD instruction (16-bit)
- * @param Field
- * @param FieldValue
- *
- * @return UCHAR
- */
-inline UCHAR
-VmxVmread16P(size_t Field,
- UINT16 * FieldValue)
-{
- UINT64 TargetField = 0ull;
-
- TargetField = (UINT64)FieldValue;
-
- return __vmx_vmread((size_t)Field, (size_t *)TargetField);
-}
-
-/**
- * @brief VMX VMWRITE instruction (64-bit)
- * @param Field
- * @param FieldValue
- *
- * @return UCHAR
- */
-inline UCHAR
-VmxVmwrite64(size_t Field,
- UINT64 FieldValue)
-{
- return __vmx_vmwrite((size_t)Field, (size_t)FieldValue);
-}
-
-/**
- * @brief VMX VMWRITE instruction (32-bit)
- * @param Field
- * @param FieldValue
- *
- * @return UCHAR
- */
-inline UCHAR
-VmxVmwrite32(size_t Field,
- UINT32 FieldValue)
-{
- UINT64 TargetValue = NULL64_ZERO;
- TargetValue = (UINT64)FieldValue;
- return __vmx_vmwrite((size_t)Field, (size_t)TargetValue);
-}
-
-/**
- * @brief VMX VMWRITE instruction (16-bit)
- * @param Field
- * @param FieldValue
- *
- * @return UCHAR
- */
-inline UCHAR
-VmxVmwrite16(size_t Field,
- UINT16 FieldValue)
-{
- UINT64 TargetValue = NULL64_ZERO;
- TargetValue = (UINT64)FieldValue;
- return __vmx_vmwrite((size_t)Field, (size_t)TargetValue);
-}
-
/**
* @brief Check whether VMX Feature is supported or not
*
@@ -171,7 +25,7 @@ VmxCheckVmxSupport()
//
// Gets Processor Info and Feature Bits
//
- __cpuid((int *)&Data, 1);
+ CpuCpuId((INT *)&Data, 1);
//
// Check For VMX Bit CPUID.ECX[5]
@@ -184,7 +38,7 @@ VmxCheckVmxSupport()
return FALSE;
}
- FeatureControlMsr.AsUInt = __readmsr(IA32_FEATURE_CONTROL);
+ FeatureControlMsr.AsUInt = CpuReadMsr(IA32_FEATURE_CONTROL);
//
// Commented because of https://stackoverflow.com/questions/34900224/
@@ -201,7 +55,7 @@ VmxCheckVmxSupport()
// {
// FeatureControlMsr.Fields.Lock = TRUE;
// FeatureControlMsr.Fields.EnableVmxon = TRUE;
- // __writemsr(IA32_FEATURE_CONTROL, FeatureControlMsr.Flags);
+ // CpuWriteMsr(IA32_FEATURE_CONTROL, FeatureControlMsr.Flags);
// }
if (FeatureControlMsr.EnableVmxOutsideSmx == FALSE)
@@ -278,7 +132,7 @@ VmxInitialize()
ProcessorsCount = KeQueryActiveProcessorCount(0);
- for (size_t ProcessorID = 0; ProcessorID < ProcessorsCount; ProcessorID++)
+ for (SIZE_T ProcessorID = 0; ProcessorID < ProcessorsCount; ProcessorID++)
{
//
// *** Launching VM for Test (in the all logical processor) ***
@@ -420,6 +274,23 @@ VmxPerformVirtualizationOnAllCores()
return FALSE;
}
+ //
+ // Check if the top level hypervisor is Hyper-V or not
+ //
+ if (VmxIsTopLevelHypervisorHyperV())
+ {
+ //
+ // The top-level hypervisor is hyper-v
+ //
+ g_IsTopLevelHypervisorHyperV = TRUE;
+
+ LogDebugInfo(" Hyper-V is detected as the top-level hypervisor");
+ }
+ else
+ {
+ LogDebugInfo(" Hyper-V is not detected as the top-level hypervisor");
+ }
+
//
// Allocate global variable to hold Ept State
//
@@ -463,15 +334,6 @@ VmxPerformVirtualizationOnAllCores()
LogDebugInfo("MTRR memory map built successfully");
}
- //
- // Initialize Pool Manager
- //
- if (!PoolManagerInitialize())
- {
- LogError("Err, could not initialize pool manager");
- return FALSE;
- }
-
if (!EptLogicalProcessorInitialize())
{
//
@@ -547,22 +409,22 @@ VmxFixCr4AndCr0Bits()
//
// Fix Cr0
//
- CrFixed.Flags = __readmsr(IA32_VMX_CR0_FIXED0);
- Cr0.AsUInt = __readcr0();
+ CrFixed.Flags = CpuReadMsr(IA32_VMX_CR0_FIXED0);
+ Cr0.AsUInt = CpuReadCr0();
Cr0.AsUInt |= CrFixed.Fields.Low;
- CrFixed.Flags = __readmsr(IA32_VMX_CR0_FIXED1);
+ CrFixed.Flags = CpuReadMsr(IA32_VMX_CR0_FIXED1);
Cr0.AsUInt &= CrFixed.Fields.Low;
- __writecr0(Cr0.AsUInt);
+ CpuWriteCr0(Cr0.AsUInt);
//
// Fix Cr4
//
- CrFixed.Flags = __readmsr(IA32_VMX_CR4_FIXED0);
- Cr4.AsUInt = __readcr4();
+ CrFixed.Flags = CpuReadMsr(IA32_VMX_CR4_FIXED0);
+ Cr4.AsUInt = CpuReadCr4();
Cr4.AsUInt |= CrFixed.Fields.Low;
- CrFixed.Flags = __readmsr(IA32_VMX_CR4_FIXED1);
+ CrFixed.Flags = CpuReadMsr(IA32_VMX_CR4_FIXED1);
Cr4.AsUInt &= CrFixed.Fields.Low;
- __writecr4(Cr4.AsUInt);
+ CpuWriteCr4(Cr4.AsUInt);
}
/**
@@ -579,7 +441,7 @@ VmxCheckIsOnVmxRoot()
__try
{
- if (!__vmx_vmread(VMCS_GUEST_VMCS_LINK_POINTER, &VmcsLink))
+ if (!VmxVmread64P(VMCS_GUEST_VMCS_LINK_POINTER, &VmcsLink))
{
if (VmcsLink != 0)
{
@@ -662,7 +524,7 @@ VmxVirtualizeCurrentSystem(PVOID GuestStack)
VCpu->HasLaunched = TRUE;
- __vmx_vmlaunch();
+ VmxVmlaunch();
//
// ******** if Vmlaunch succeed will never be here ! ********
@@ -676,14 +538,14 @@ VmxVirtualizeCurrentSystem(PVOID GuestStack)
//
// Read error code firstly
//
- __vmx_vmread(VMCS_VM_INSTRUCTION_ERROR, &ErrorCode);
+ VmxVmread64P(VMCS_VM_INSTRUCTION_ERROR, &ErrorCode);
LogError("Err, unable to execute VMLAUNCH, status : 0x%llx", ErrorCode);
//
// Then Execute Vmxoff
//
- __vmx_off();
+ VmxVmxoff();
LogError("Err, VMXOFF Executed Successfully but it was because of an error");
return FALSE;
@@ -745,11 +607,11 @@ VmxTerminate()
* @return VOID
*/
VOID
-VmxVmptrst()
+VmxPerformVmptrst()
{
PHYSICAL_ADDRESS VmcsPhysicalAddr;
VmcsPhysicalAddr.QuadPart = 0;
- __vmx_vmptrst((unsigned __int64 *)&VmcsPhysicalAddr);
+ VmxVmptrst((UINT64 *)&VmcsPhysicalAddr);
LogDebugInfo("VMPTRST result : %llx", VmcsPhysicalAddr);
}
@@ -770,7 +632,7 @@ VmxClearVmcsState(VIRTUAL_MACHINE_STATE * VCpu)
//
// Clear the state of the VMCS to inactive
//
- VmclearStatus = __vmx_vmclear(&VCpu->VmcsRegionPhysicalAddress);
+ VmclearStatus = VmxVmclear(&VCpu->VmcsRegionPhysicalAddress);
LogDebugInfo("VMCS VMCLEAR status : 0x%x", VmclearStatus);
@@ -780,7 +642,8 @@ VmxClearVmcsState(VIRTUAL_MACHINE_STATE * VCpu)
// Otherwise terminate the VMX
//
LogDebugInfo("VMCS failed to clear, status : 0x%x", VmclearStatus);
- __vmx_off();
+ VmxVmxoff();
+
return FALSE;
}
return TRUE;
@@ -799,7 +662,8 @@ VmxLoadVmcs(VIRTUAL_MACHINE_STATE * VCpu)
{
int VmptrldStatus;
- VmptrldStatus = __vmx_vmptrld(&VCpu->VmcsRegionPhysicalAddress);
+ VmptrldStatus = VmxVmptrld(&VCpu->VmcsRegionPhysicalAddress);
+
if (VmptrldStatus)
{
LogDebugInfo("VMCS failed to load, status : 0x%x", VmptrldStatus);
@@ -829,7 +693,7 @@ VmxSetupVmcs(VIRTUAL_MACHINE_STATE * VCpu, PVOID GuestStack)
//
// Reading IA32_VMX_BASIC_MSR
//
- VmxBasicMsr.AsUInt = __readmsr(IA32_VMX_BASIC);
+ VmxBasicMsr.AsUInt = CpuReadMsr(IA32_VMX_BASIC);
VmxVmwrite64(VMCS_HOST_ES_SELECTOR, AsmGetEs() & 0xF8);
VmxVmwrite64(VMCS_HOST_CS_SELECTOR, AsmGetCs() & 0xF8);
@@ -844,8 +708,8 @@ VmxSetupVmcs(VIRTUAL_MACHINE_STATE * VCpu, PVOID GuestStack)
//
VmxVmwrite64(VMCS_GUEST_VMCS_LINK_POINTER, ~0ULL);
- VmxVmwrite64(VMCS_GUEST_DEBUGCTL, __readmsr(IA32_DEBUGCTL) & 0xFFFFFFFF);
- VmxVmwrite64(VMCS_GUEST_DEBUGCTL_HIGH, __readmsr(IA32_DEBUGCTL) >> 32);
+ VmxVmwrite64(VMCS_GUEST_DEBUGCTL, CpuReadMsr(IA32_DEBUGCTL) & 0xFFFFFFFF);
+ VmxVmwrite64(VMCS_GUEST_DEBUGCTL_HIGH, CpuReadMsr(IA32_DEBUGCTL) >> 32);
//
// ******* Time-stamp counter offset *******
@@ -872,36 +736,52 @@ VmxSetupVmcs(VIRTUAL_MACHINE_STATE * VCpu, PVOID GuestStack)
HvFillGuestSelectorData((PVOID)GdtBase, LDTR, AsmGetLdtr());
HvFillGuestSelectorData((PVOID)GdtBase, TR, AsmGetTr());
- VmxVmwrite64(VMCS_GUEST_FS_BASE, __readmsr(IA32_FS_BASE));
- VmxVmwrite64(VMCS_GUEST_GS_BASE, __readmsr(IA32_GS_BASE));
+ VmxVmwrite64(VMCS_GUEST_FS_BASE, CpuReadMsr(IA32_FS_BASE));
+ VmxVmwrite64(VMCS_GUEST_GS_BASE, CpuReadMsr(IA32_GS_BASE));
- CpuBasedVmExecControls = HvAdjustControls(CPU_BASED_ACTIVATE_IO_BITMAP | CPU_BASED_ACTIVATE_MSR_BITMAP | CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
- VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_PROCBASED_CTLS : IA32_VMX_PROCBASED_CTLS);
+ CpuBasedVmExecControls = HvAdjustControls(
+ IA32_VMX_PROCBASED_CTLS_USE_IO_BITMAPS_FLAG |
+ IA32_VMX_PROCBASED_CTLS_USE_MSR_BITMAPS_FLAG |
+ IA32_VMX_PROCBASED_CTLS_ACTIVATE_SECONDARY_CONTROLS_FLAG,
+ VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_PROCBASED_CTLS : IA32_VMX_PROCBASED_CTLS);
VmxVmwrite64(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, CpuBasedVmExecControls);
LogDebugInfo("CPU Based VM Exec Controls (Based on %s) : 0x%x",
VmxBasicMsr.VmxControls ? "IA32_VMX_TRUE_PROCBASED_CTLS" : "IA32_VMX_PROCBASED_CTLS",
CpuBasedVmExecControls);
+ UINT32 SecondaryProcBasedVmExecControlsFlags = IA32_VMX_PROCBASED_CTLS2_ENABLE_RDTSCP_FLAG |
+ IA32_VMX_PROCBASED_CTLS2_ENABLE_EPT_FLAG |
+ IA32_VMX_PROCBASED_CTLS2_ENABLE_INVPCID_FLAG |
+ IA32_VMX_PROCBASED_CTLS2_ENABLE_XSAVES_FLAG |
+ IA32_VMX_PROCBASED_CTLS2_ENABLE_USER_WAIT_PAUSE_FLAG;
- SecondaryProcBasedVmExecControls = HvAdjustControls(
- IA32_VMX_PROCBASED_CTLS2_ENABLE_RDTSCP_FLAG |
- IA32_VMX_PROCBASED_CTLS2_ENABLE_EPT_FLAG |
- IA32_VMX_PROCBASED_CTLS2_ENABLE_INVPCID_FLAG |
- IA32_VMX_PROCBASED_CTLS2_ENABLE_XSAVES_FLAG |
- IA32_VMX_PROCBASED_CTLS2_ENABLE_VPID_FLAG |
- IA32_VMX_PROCBASED_CTLS2_ENABLE_USER_WAIT_PAUSE_FLAG,
- IA32_VMX_PROCBASED_CTLS2);
+ if (g_IsVpidSupported)
+ {
+ SecondaryProcBasedVmExecControlsFlags |= IA32_VMX_PROCBASED_CTLS2_ENABLE_VPID_FLAG;
+ }
+ SecondaryProcBasedVmExecControls = HvAdjustControls(SecondaryProcBasedVmExecControlsFlags, IA32_VMX_PROCBASED_CTLS2);
VmxVmwrite64(VMCS_CTRL_SECONDARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, SecondaryProcBasedVmExecControls);
LogDebugInfo("Secondary Proc Based VM Exec Controls (IA32_VMX_PROCBASED_CTLS2) : 0x%x", SecondaryProcBasedVmExecControls);
- VmxVmwrite64(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, HvAdjustControls(0, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_PINBASED_CTLS : IA32_VMX_PINBASED_CTLS));
+ VmxVmwrite64(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS,
+ HvAdjustControls(
+ 0,
+ VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_PINBASED_CTLS : IA32_VMX_PINBASED_CTLS));
- VmxVmwrite64(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, HvAdjustControls(VM_EXIT_HOST_ADDR_SPACE_SIZE, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS));
+ VmxVmwrite64(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS,
+ HvAdjustControls(
+ IA32_VMX_EXIT_CTLS_HOST_ADDRESS_SPACE_SIZE_FLAG |
+ IA32_VMX_EXIT_CTLS_LOAD_IA32_CET_STATE_FLAG,
+ VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS));
- VmxVmwrite64(VMCS_CTRL_VMENTRY_CONTROLS, HvAdjustControls(VM_ENTRY_IA32E_MODE, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS));
+ VmxVmwrite64(VMCS_CTRL_VMENTRY_CONTROLS,
+ HvAdjustControls(
+ IA32_VMX_ENTRY_CTLS_IA32E_MODE_GUEST_FLAG |
+ IA32_VMX_ENTRY_CTLS_LOAD_CET_STATE_FLAG,
+ VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS));
VmxVmwrite64(VMCS_CTRL_CR0_GUEST_HOST_MASK, 0);
VmxVmwrite64(VMCS_CTRL_CR4_GUEST_HOST_MASK, 0);
@@ -909,14 +789,14 @@ VmxSetupVmcs(VIRTUAL_MACHINE_STATE * VCpu, PVOID GuestStack)
VmxVmwrite64(VMCS_CTRL_CR0_READ_SHADOW, 0);
VmxVmwrite64(VMCS_CTRL_CR4_READ_SHADOW, 0);
- VmxVmwrite64(VMCS_GUEST_CR0, __readcr0());
- VmxVmwrite64(VMCS_GUEST_CR3, __readcr3());
- VmxVmwrite64(VMCS_GUEST_CR4, __readcr4());
+ VmxVmwrite64(VMCS_GUEST_CR0, CpuReadCr0());
+ VmxVmwrite64(VMCS_GUEST_CR3, CpuReadCr3());
+ VmxVmwrite64(VMCS_GUEST_CR4, CpuReadCr4());
VmxVmwrite64(VMCS_GUEST_DR7, 0x400);
- VmxVmwrite64(VMCS_HOST_CR0, __readcr0());
- VmxVmwrite64(VMCS_HOST_CR4, __readcr4());
+ VmxVmwrite64(VMCS_HOST_CR0, CpuReadCr0());
+ VmxVmwrite64(VMCS_HOST_CR4, CpuReadCr4());
//
// Because we may be executing in an arbitrary user-mode, process as part
@@ -933,9 +813,9 @@ VmxSetupVmcs(VIRTUAL_MACHINE_STATE * VCpu, PVOID GuestStack)
VmxVmwrite64(VMCS_GUEST_RFLAGS, AsmGetRflags());
- VmxVmwrite64(VMCS_GUEST_SYSENTER_CS, __readmsr(IA32_SYSENTER_CS));
- VmxVmwrite64(VMCS_GUEST_SYSENTER_EIP, __readmsr(IA32_SYSENTER_EIP));
- VmxVmwrite64(VMCS_GUEST_SYSENTER_ESP, __readmsr(IA32_SYSENTER_ESP));
+ VmxVmwrite64(VMCS_GUEST_SYSENTER_CS, CpuReadMsr(IA32_SYSENTER_CS));
+ VmxVmwrite64(VMCS_GUEST_SYSENTER_EIP, CpuReadMsr(IA32_SYSENTER_EIP));
+ VmxVmwrite64(VMCS_GUEST_SYSENTER_ESP, CpuReadMsr(IA32_SYSENTER_ESP));
#if USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
@@ -953,8 +833,8 @@ VmxSetupVmcs(VIRTUAL_MACHINE_STATE * VCpu, PVOID GuestStack)
#endif // USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
- VmxVmwrite64(VMCS_HOST_FS_BASE, __readmsr(IA32_FS_BASE));
- VmxVmwrite64(VMCS_HOST_GS_BASE, __readmsr(IA32_GS_BASE));
+ VmxVmwrite64(VMCS_HOST_FS_BASE, CpuReadMsr(IA32_FS_BASE));
+ VmxVmwrite64(VMCS_HOST_GS_BASE, CpuReadMsr(IA32_GS_BASE));
#if USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
@@ -966,9 +846,9 @@ VmxSetupVmcs(VIRTUAL_MACHINE_STATE * VCpu, PVOID GuestStack)
#endif // USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
- VmxVmwrite64(VMCS_HOST_SYSENTER_CS, __readmsr(IA32_SYSENTER_CS));
- VmxVmwrite64(VMCS_HOST_SYSENTER_EIP, __readmsr(IA32_SYSENTER_EIP));
- VmxVmwrite64(VMCS_HOST_SYSENTER_ESP, __readmsr(IA32_SYSENTER_ESP));
+ VmxVmwrite64(VMCS_HOST_SYSENTER_CS, CpuReadMsr(IA32_SYSENTER_CS));
+ VmxVmwrite64(VMCS_HOST_SYSENTER_EIP, CpuReadMsr(IA32_SYSENTER_EIP));
+ VmxVmwrite64(VMCS_HOST_SYSENTER_ESP, CpuReadMsr(IA32_SYSENTER_ESP));
//
// Set MSR Bitmaps
@@ -1018,23 +898,24 @@ VmxSetupVmcs(VIRTUAL_MACHINE_STATE * VCpu, PVOID GuestStack)
}
/**
- * @brief Resume VM using VMRESUME instruction
+ * @brief Resume VM using the VMRESUME instruction
*
* @return VOID
*/
VOID
-VmxVmresume()
+VmxPerformVmresume()
{
- UINT64 ErrorCode = 0;
+ UINT32 ErrorCode = 0;
- __vmx_vmresume();
+ VmxVmresume();
//
// if VMRESUME succeed will never be here !
//
- __vmx_vmread(VMCS_VM_INSTRUCTION_ERROR, &ErrorCode);
- __vmx_off();
+ VmxVmread32P(VMCS_VM_INSTRUCTION_ERROR, &ErrorCode);
+
+ VmxVmxoff();
//
// It's such a bad error because we don't where to go !
@@ -1107,7 +988,7 @@ VmxVmfunc(UINT32 EptpIndex, UINT32 Function)
* @return VOID
*/
VOID
-VmxVmxoff(VIRTUAL_MACHINE_STATE * VCpu)
+VmxPerformVmxoff(VIRTUAL_MACHINE_STATE * VCpu)
{
UINT64 GuestRSP = 0; // Save a pointer to guest rsp for times that we want to return to previous guest stateS
UINT64 GuestRIP = 0; // Save a pointer to guest rip for times that we want to return to previous guest state
@@ -1125,19 +1006,19 @@ VmxVmxoff(VIRTUAL_MACHINE_STATE * VCpu)
// process continues to run with its expected address space mappings.
//
- __vmx_vmread(VMCS_GUEST_CR3, &GuestCr3);
- __writecr3(GuestCr3);
+ VmxVmread64P(VMCS_GUEST_CR3, &GuestCr3);
+ CpuWriteCr3(GuestCr3);
//
// Read guest rsp and rip
//
- __vmx_vmread(VMCS_GUEST_RIP, &GuestRIP);
- __vmx_vmread(VMCS_GUEST_RSP, &GuestRSP);
+ VmxVmread64P(VMCS_GUEST_RIP, &GuestRIP);
+ VmxVmread64P(VMCS_GUEST_RSP, &GuestRSP);
//
// Read instruction length
//
- __vmx_vmread(VMCS_VMEXIT_INSTRUCTION_LENGTH, &ExitInstructionLength);
+ VmxVmread64P(VMCS_VMEXIT_INSTRUCTION_LENGTH, &ExitInstructionLength);
GuestRIP += ExitInstructionLength;
//
@@ -1156,6 +1037,15 @@ VmxVmxoff(VIRTUAL_MACHINE_STATE * VCpu)
//
HvRestoreRegisters();
+ //
+ // Restore XMM registers
+ // We restore XMM registers here because we are going to execute vmxoff instruction
+ // which enables interrupts and we don't want to lose the XMM registers
+ // since immediately after vmxoff, an interrupt might occur and context switch
+ // might change the XMM registers
+ //
+ AsmVmxoffRestoreXmmRegs((UINT64)VCpu->XmmRegs);
+
//
// Before using vmxoff, you first need to use vmclear on any VMCSes that you want to be able to use again.
// See sections 24.1 and 24.11 of the SDM.
@@ -1165,7 +1055,12 @@ VmxVmxoff(VIRTUAL_MACHINE_STATE * VCpu)
//
// Execute Vmxoff
//
- __vmx_off();
+ VmxVmxoff();
+
+ //
+ // *** Note: After executing VMXOFF, XMM registers should not be used anymore
+ // Since we already restored them ***
+ //
//
// Indicate the current core is not currently virtualized
@@ -1175,7 +1070,7 @@ VmxVmxoff(VIRTUAL_MACHINE_STATE * VCpu)
//
// Now that VMX is OFF, we have to unset vmx-enable bit on cr4
//
- __writecr4(__readcr4() & (~X86_CR4_VMXE));
+ CpuWriteCr4(CpuReadCr4() & (~REG_CR4_VMXE));
}
/**
@@ -1257,7 +1152,7 @@ VmxPerformTermination()
//
// Free Identity Page Table
//
- for (size_t i = 0; i < ProcessorsCount; i++)
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
if (g_GuestState[i].EptPageTable != NULL)
{
@@ -1273,11 +1168,6 @@ VmxPerformTermination()
PlatformMemFreePool(g_EptState);
g_EptState = NULL;
- //
- // Free the Pool manager
- //
- PoolManagerUninitialize();
-
//
// Uninitialize memory mapper
//
@@ -1317,8 +1207,8 @@ VmxCompatibleStrlen(const CHAR * S)
//
// Move to new cr3
//
- OriginalCr3.Flags = __readcr3();
- __writecr3(GuestCr3.Flags);
+ OriginalCr3.Flags = CpuReadCr3();
+ CpuWriteCr3(GuestCr3.Flags);
//
// First check
@@ -1332,7 +1222,7 @@ VmxCompatibleStrlen(const CHAR * S)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0;
}
@@ -1353,7 +1243,7 @@ VmxCompatibleStrlen(const CHAR * S)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return Count;
}
@@ -1368,7 +1258,7 @@ VmxCompatibleStrlen(const CHAR * S)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0;
}
}
@@ -1377,7 +1267,7 @@ VmxCompatibleStrlen(const CHAR * S)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
}
/**
@@ -1388,9 +1278,9 @@ VmxCompatibleStrlen(const CHAR * S)
* string
*/
UINT32
-VmxCompatibleWcslen(const wchar_t * S)
+VmxCompatibleWcslen(const WCHAR * S)
{
- wchar_t Temp = NULL_ZERO;
+ WCHAR Temp = NULL_ZERO;
UINT32 Count = 0;
UINT64 AlignedAddress;
CR3_TYPE GuestCr3;
@@ -1406,15 +1296,15 @@ VmxCompatibleWcslen(const wchar_t * S)
//
// Move to new cr3
//
- OriginalCr3.Flags = __readcr3();
- __writecr3(GuestCr3.Flags);
+ OriginalCr3.Flags = CpuReadCr3();
+ CpuWriteCr3(GuestCr3.Flags);
AlignedAddress = (UINT64)PAGE_ALIGN((UINT64)S);
//
// First check
//
- if (!CheckAccessValidityAndSafety(AlignedAddress, sizeof(wchar_t)))
+ if (!CheckAccessValidityAndSafety(AlignedAddress, sizeof(WCHAR)))
{
//
// Error
@@ -1423,7 +1313,7 @@ VmxCompatibleWcslen(const wchar_t * S)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0;
}
@@ -1432,7 +1322,7 @@ VmxCompatibleWcslen(const wchar_t * S)
/*
Temp = *S;
*/
- MemoryMapperReadMemorySafe((UINT64)S, &Temp, sizeof(wchar_t));
+ MemoryMapperReadMemorySafe((UINT64)S, &Temp, sizeof(WCHAR));
if (Temp != '\0\0')
{
@@ -1444,13 +1334,13 @@ VmxCompatibleWcslen(const wchar_t * S)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return Count;
}
if (!((UINT64)S & (PAGE_SIZE - 1)))
{
- if (!CheckAccessValidityAndSafety((UINT64)S, sizeof(wchar_t)))
+ if (!CheckAccessValidityAndSafety((UINT64)S, sizeof(WCHAR)))
{
//
// Error
@@ -1459,7 +1349,7 @@ VmxCompatibleWcslen(const wchar_t * S)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0;
}
}
@@ -1468,7 +1358,7 @@ VmxCompatibleWcslen(const wchar_t * S)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
}
/**
@@ -1528,8 +1418,8 @@ VmxCompatibleStrcmp(const CHAR * Address1,
//
// Move to new cr3
//
- OriginalCr3.Flags = __readcr3();
- __writecr3(GuestCr3.Flags);
+ OriginalCr3.Flags = CpuReadCr3();
+ CpuWriteCr3(GuestCr3.Flags);
//
// First check
@@ -1543,7 +1433,7 @@ VmxCompatibleStrcmp(const CHAR * Address1,
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0x2;
}
@@ -1594,7 +1484,7 @@ VmxCompatibleStrcmp(const CHAR * Address1,
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0x2;
}
}
@@ -1610,7 +1500,7 @@ VmxCompatibleStrcmp(const CHAR * Address1,
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0x2;
}
}
@@ -1629,7 +1519,7 @@ VmxCompatibleStrcmp(const CHAR * Address1,
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return Result;
}
@@ -1643,12 +1533,12 @@ VmxCompatibleStrcmp(const CHAR * Address1,
* @return INT32 0x2 indicates error, otherwise the same result as wcscmp in string.h
*/
INT32
-VmxCompatibleWcscmp(const wchar_t * Address1,
- const wchar_t * Address2,
- SIZE_T Num,
- BOOLEAN IsWcsncmp)
+VmxCompatibleWcscmp(const WCHAR * Address1,
+ const WCHAR * Address2,
+ SIZE_T Num,
+ BOOLEAN IsWcsncmp)
{
- wchar_t C1 = NULL_ZERO, C2 = NULL_ZERO;
+ WCHAR C1 = NULL_ZERO, C2 = NULL_ZERO;
INT32 Result = 0;
UINT32 Count = 0;
UINT64 AlignedAddress1, AlignedAddress2;
@@ -1666,13 +1556,13 @@ VmxCompatibleWcscmp(const wchar_t * Address1,
//
// Move to new cr3
//
- OriginalCr3.Flags = __readcr3();
- __writecr3(GuestCr3.Flags);
+ OriginalCr3.Flags = CpuReadCr3();
+ CpuWriteCr3(GuestCr3.Flags);
//
// First check
//
- if (!CheckAccessValidityAndSafety(AlignedAddress1, sizeof(wchar_t)) || !CheckAccessValidityAndSafety(AlignedAddress2, sizeof(wchar_t)))
+ if (!CheckAccessValidityAndSafety(AlignedAddress1, sizeof(WCHAR)) || !CheckAccessValidityAndSafety(AlignedAddress2, sizeof(WCHAR)))
{
//
// Error
@@ -1681,7 +1571,7 @@ VmxCompatibleWcscmp(const wchar_t * Address1,
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0x2;
}
@@ -1711,19 +1601,19 @@ VmxCompatibleWcscmp(const wchar_t * Address1,
/*
C1 = *Address1;
*/
- MemoryMapperReadMemorySafe((UINT64)Address1, &C1, sizeof(wchar_t));
+ MemoryMapperReadMemorySafe((UINT64)Address1, &C1, sizeof(WCHAR));
/*
C2 = *Address2;
*/
- MemoryMapperReadMemorySafe((UINT64)Address2, &C2, sizeof(wchar_t));
+ MemoryMapperReadMemorySafe((UINT64)Address2, &C2, sizeof(WCHAR));
Address1++;
Address2++;
if (!((UINT64)AlignedAddress1 & (PAGE_SIZE - 1)))
{
- if (!CheckAccessValidityAndSafety((UINT64)AlignedAddress1, sizeof(wchar_t)))
+ if (!CheckAccessValidityAndSafety((UINT64)AlignedAddress1, sizeof(WCHAR)))
{
//
// Error
@@ -1732,14 +1622,14 @@ VmxCompatibleWcscmp(const wchar_t * Address1,
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0x2;
}
}
if (!((UINT64)AlignedAddress2 & (PAGE_SIZE - 1)))
{
- if (!CheckAccessValidityAndSafety((UINT64)AlignedAddress2, sizeof(wchar_t)))
+ if (!CheckAccessValidityAndSafety((UINT64)AlignedAddress2, sizeof(WCHAR)))
{
//
// Error
@@ -1748,7 +1638,7 @@ VmxCompatibleWcscmp(const wchar_t * Address1,
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0x2;
}
}
@@ -1768,7 +1658,7 @@ VmxCompatibleWcscmp(const wchar_t * Address1,
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return Result;
}
@@ -1781,7 +1671,7 @@ VmxCompatibleWcscmp(const wchar_t * Address1,
* @return INT32 0x2 indicates error, otherwise the same result as memcmp in string.h
*/
INT32
-VmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, size_t Count)
+VmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, SIZE_T Count)
{
CHAR C1 = NULL_ZERO, C2 = NULL_ZERO;
INT32 Result = 0;
@@ -1800,13 +1690,13 @@ VmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, size_t Count)
//
// Move to new cr3
//
- OriginalCr3.Flags = __readcr3();
- __writecr3(GuestCr3.Flags);
+ OriginalCr3.Flags = CpuReadCr3();
+ CpuWriteCr3(GuestCr3.Flags);
//
// First check
//
- if (!CheckAccessValidityAndSafety(AlignedAddress1, sizeof(wchar_t)) || !CheckAccessValidityAndSafety(AlignedAddress2, sizeof(wchar_t)))
+ if (!CheckAccessValidityAndSafety(AlignedAddress1, sizeof(WCHAR)) || !CheckAccessValidityAndSafety(AlignedAddress2, sizeof(WCHAR)))
{
//
// Error
@@ -1815,7 +1705,7 @@ VmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, size_t Count)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0x2;
}
@@ -1836,7 +1726,7 @@ VmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, size_t Count)
if (!((UINT64)AlignedAddress1 & (PAGE_SIZE - 1)))
{
- if (!CheckAccessValidityAndSafety((UINT64)AlignedAddress1, sizeof(wchar_t)))
+ if (!CheckAccessValidityAndSafety((UINT64)AlignedAddress1, sizeof(WCHAR)))
{
//
// Error
@@ -1845,14 +1735,14 @@ VmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, size_t Count)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0x2;
}
}
if (!((UINT64)AlignedAddress2 & (PAGE_SIZE - 1)))
{
- if (!CheckAccessValidityAndSafety((UINT64)AlignedAddress2, sizeof(wchar_t)))
+ if (!CheckAccessValidityAndSafety((UINT64)AlignedAddress2, sizeof(WCHAR)))
{
//
// Error
@@ -1861,7 +1751,7 @@ VmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, size_t Count)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0x2;
}
}
@@ -1881,6 +1771,31 @@ VmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, size_t Count)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return Result;
}
+
+/**
+ * @brief checks if the current top level hypervisor is Hyper-V
+ *
+ *
+ * @return BOOLEAN TRUE indicates that the current top level hypervisor is Hyper-V, FALSE otherwise.
+ */
+BOOLEAN
+VmxIsTopLevelHypervisorHyperV()
+{
+ INT32 ProcessorFeatures[4] = {0};
+ CpuCpuIdEx(ProcessorFeatures, CPUID_PROCESSOR_AND_PROCESSOR_FEATURE_IDENTIFIERS, 0);
+
+ if (!((ULONG)(ProcessorFeatures[2]) & HYPERV_HYPERVISOR_PRESENT_BIT))
+ {
+ return FALSE;
+ }
+
+ INT32 HypervisorVendor[4] = {0};
+ CpuCpuIdEx(HypervisorVendor, HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS, 0);
+
+ return (ULONG)(HypervisorVendor[1]) == HYPERV_CPUID_VENDOR_MICROSOFT_EBX &&
+ (ULONG)(HypervisorVendor[2]) == HYPERV_CPUID_VENDOR_MICROSOFT_ECX &&
+ (ULONG)(HypervisorVendor[3]) == HYPERV_CPUID_VENDOR_MICROSOFT_EDX;
+}
diff --git a/hyperdbg/hyperhv/code/vmm/vmx/VmxBroadcast.c b/hyperdbg/hyperhv/code/vmm/vmx/VmxBroadcast.c
index 6c17d923..6b23c7fa 100644
--- a/hyperdbg/hyperhv/code/vmm/vmx/VmxBroadcast.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/VmxBroadcast.c
@@ -157,7 +157,7 @@ VmxBroadcastNmi(VIRTUAL_MACHINE_STATE * VCpu, NMI_BROADCAST_ACTION_TYPE VmxBroad
//
// Indicate that we're waiting for NMI
//
- for (size_t i = 0; i < ProcessorsCount; i++)
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
if (i != VCpu->CoreId)
{
diff --git a/hyperdbg/hyperhv/code/vmm/vmx/VmxRegions.c b/hyperdbg/hyperhv/code/vmm/vmx/VmxRegions.c
index eae93908..5d008d3f 100644
--- a/hyperdbg/hyperhv/code/vmm/vmx/VmxRegions.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/VmxRegions.c
@@ -30,13 +30,13 @@ VmxAllocateVmxonRegion(VIRTUAL_MACHINE_STATE * VCpu)
UINT64 AlignedVmxonRegion;
UINT64 AlignedVmxonRegionPhysicalAddr;
-#ifdef ENV_WINDOWS
+#ifdef HYPERDBG_ENV_WINDOWS
//
// at IRQL > DISPATCH_LEVEL memory allocation routines don't work
//
if (KeGetCurrentIrql() > DISPATCH_LEVEL)
KeRaiseIrqlToDpcLevel();
-#endif // ENV_WINDOWS
+#endif // HYPERDBG_ENV_WINDOWS
//
// Allocating a 4-KByte Contiguous Memory region
@@ -63,7 +63,7 @@ VmxAllocateVmxonRegion(VIRTUAL_MACHINE_STATE * VCpu)
//
// get IA32_VMX_BASIC_MSR RevisionId
//
- VmxBasicMsr.AsUInt = __readmsr(IA32_VMX_BASIC);
+ VmxBasicMsr.AsUInt = CpuReadMsr(IA32_VMX_BASIC);
LogDebugInfo("Revision Identifier (IA32_VMX_BASIC - MSR 0x480) : 0x%x", VmxBasicMsr.VmcsRevisionId);
//
@@ -74,7 +74,8 @@ VmxAllocateVmxonRegion(VIRTUAL_MACHINE_STATE * VCpu)
//
// Execute Vmxon instruction
//
- VmxonStatus = __vmx_on(&AlignedVmxonRegionPhysicalAddr);
+ VmxonStatus = VmxVmxon(&AlignedVmxonRegionPhysicalAddr);
+
if (VmxonStatus)
{
LogError("Err, executing vmxon instruction failed with status : %d", VmxonStatus);
@@ -109,13 +110,13 @@ VmxAllocateVmcsRegion(VIRTUAL_MACHINE_STATE * VCpu)
UINT64 AlignedVmcsRegion;
UINT64 AlignedVmcsRegionPhysicalAddr;
-#ifdef ENV_WINDOWS
+#ifdef HYPERDBG_ENV_WINDOWS
//
// at IRQL > DISPATCH_LEVEL memory allocation routines don't work
//
if (KeGetCurrentIrql() > DISPATCH_LEVEL)
KeRaiseIrqlToDpcLevel();
-#endif // ENV_WINDOWS
+#endif // HYPERDBG_ENV_WINDOWS
//
// Allocating a 4-KByte Contiguous Memory region
@@ -139,7 +140,7 @@ VmxAllocateVmcsRegion(VIRTUAL_MACHINE_STATE * VCpu)
//
// get IA32_VMX_BASIC_MSR RevisionId
//
- VmxBasicMsr.AsUInt = __readmsr(IA32_VMX_BASIC);
+ VmxBasicMsr.AsUInt = CpuReadMsr(IA32_VMX_BASIC);
LogDebugInfo("Revision Identifier (IA32_VMX_BASIC - MSR 0x480) : 0x%x", VmxBasicMsr.VmcsRevisionId);
//
@@ -276,11 +277,11 @@ VmxAllocateInvalidMsrBimap()
{
__try
{
- __readmsr(i);
+ CpuReadMsr(i);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
- SetBit(i, (unsigned long *)InvalidMsrBitmap);
+ SetBit(i, (ULONG *)InvalidMsrBitmap);
}
}
diff --git a/hyperdbg/hyperhv/header/assembly/InlineAsm.h b/hyperdbg/hyperhv/header/assembly/InlineAsm.h
index b1ec773d..8bc23ba7 100644
--- a/hyperdbg/hyperhv/header/assembly/InlineAsm.h
+++ b/hyperdbg/hyperhv/header/assembly/InlineAsm.h
@@ -20,13 +20,13 @@
* @brief Enable VMX Operation
*
*/
-extern void inline AsmEnableVmxOperation();
+extern VOID inline AsmEnableVmxOperation();
/**
* @brief Restore in vmxoff state
*
*/
-extern void inline AsmRestoreToVmxOffState();
+extern VOID inline AsmRestoreToVmxOffState();
/**
* @brief Request Vmcall
@@ -37,18 +37,18 @@ extern void inline AsmRestoreToVmxOffState();
* @param OptionalParam3
* @return NTSTATUS
*/
-extern NTSTATUS inline AsmVmxVmcall(unsigned long long VmcallNumber,
- unsigned long long OptionalParam1,
- unsigned long long OptionalParam2,
- long long OptionalParam3);
+extern NTSTATUS inline AsmVmxVmcall(UINT64 VmcallNumber,
+ UINT64 OptionalParam1,
+ UINT64 OptionalParam2,
+ UINT64 OptionalParam3);
/**
* @brief Hyper-v vmcall handler
*
* @param GuestRegisters
- * @return void
+ * @return VOID
*/
-extern void inline AsmHypervVmcall(unsigned long long GuestRegisters);
+extern VOID inline AsmHypervVmcall(UINT64 GuestRegisters);
/**
* @brief VMFUNC instruction
@@ -56,9 +56,9 @@ extern void inline AsmHypervVmcall(unsigned long long GuestRegisters);
* @param EptpIndex
* @param Function
*
- * @return unsigned long long I'm not sure what it returns
+ * @return UINT64 I'm not sure what it returns
*/
-extern unsigned long long inline AsmVmfunc(unsigned long EptpIndex, unsigned long Function);
+extern UINT64 inline AsmVmfunc(ULONG EptpIndex, ULONG Function);
//
// ==================== Vmx Context State Operations ====================
@@ -69,14 +69,14 @@ extern unsigned long long inline AsmVmfunc(unsigned long EptpIndex, unsigned lon
* @brief Save state on vmx
*
*/
-extern void
+extern VOID
AsmVmxSaveState();
/**
* @brief Restore state on vmx
*
*/
-extern void
+extern VOID
AsmVmxRestoreState();
//
@@ -88,14 +88,20 @@ AsmVmxRestoreState();
* @brief Vm-exit handler
*
*/
-extern void
+extern VOID
AsmVmexitHandler();
/**
* @brief Save vmxoff state
*
*/
-extern void inline AsmSaveVmxOffState();
+extern VOID inline AsmSaveVmxOffState();
+
+/**
+ * @brief Restore XMM registers
+ *
+ */
+extern VOID inline AsmVmxoffRestoreXmmRegs(UINT64 XmmRegs);
//
// ==================== Extended Page Tables ====================
@@ -107,18 +113,18 @@ extern void inline AsmSaveVmxOffState();
*
* @param Type
* @param Descriptors
- * @return unsigned char
+ * @return UCHAR
*/
-extern unsigned char inline AsmInvept(unsigned long Type, void * Descriptors);
+extern UCHAR inline AsmInvept(ULONG Type, PVOID Descriptors);
/**
* @brief INVVPID wrapper
*
* @param Type
* @param Descriptors
- * @return unsigned char
+ * @return UCHAR
*/
-extern unsigned char inline AsmInvvpid(unsigned long Type, void * Descriptors);
+extern UCHAR inline AsmInvvpid(ULONG Type, PVOID Descriptors);
//
// ==================== Get segment registers ====================
@@ -130,77 +136,77 @@ extern unsigned char inline AsmInvvpid(unsigned long Type, void * Descriptors);
/**
* @brief Get CS Register
*
- * @return unsigned short
+ * @return UINT16
*/
-extern unsigned short
+extern UINT16
AsmGetCs();
/**
* @brief Get DS Register
*
- * @return unsigned short
+ * @return UINT16
*/
-extern unsigned short
+extern UINT16
AsmGetDs();
-extern void
-AsmSetDs(unsigned short DsSelector);
+extern VOID
+AsmSetDs(UINT16 DsSelector);
/**
* @brief Get ES Register
*
- * @return unsigned short
+ * @return UINT16
*/
-extern unsigned short
+extern UINT16
AsmGetEs();
-extern void
-AsmSetEs(unsigned short EsSelector);
+extern VOID
+AsmSetEs(UINT16 EsSelector);
/**
* @brief Get SS Register
*
- * @return unsigned short
+ * @return UINT16
*/
-extern unsigned short
+extern UINT16
AsmGetSs();
-extern void
-AsmSetSs(unsigned short SsSelector);
+extern VOID
+AsmSetSs(UINT16 SsSelector);
/**
* @brief Get FS Register
*
- * @return unsigned short
+ * @return UINT16
*/
-extern unsigned short
+extern UINT16
AsmGetFs();
-extern void
-AsmSetFs(unsigned short FsSelector);
+extern VOID
+AsmSetFs(UINT16 FsSelector);
/**
* @brief Get GS Register
*
- * @return unsigned short
+ * @return UINT16
*/
-extern unsigned short
+extern UINT16
AsmGetGs();
/**
* @brief Get LDTR Register
*
- * @return unsigned short
+ * @return UINT16
*/
-extern unsigned short
+extern UINT16
AsmGetLdtr();
/**
* @brief Get TR Register
*
- * @return unsigned short
+ * @return UINT16
*/
-extern unsigned short
+extern UINT16
AsmGetTr();
/* ******* Gdt related functions ******* */
@@ -208,16 +214,16 @@ AsmGetTr();
/**
* @brief get GDT base
*
- * @return unsigned long long
+ * @return UINT64
*/
-extern unsigned long long inline AsmGetGdtBase();
+extern UINT64 inline AsmGetGdtBase();
/**
* @brief Get GDT Limit
*
- * @return unsigned short
+ * @return UINT16
*/
-extern unsigned short
+extern UINT16
AsmGetGdtLimit();
/* ******* Idt related functions ******* */
@@ -225,20 +231,20 @@ AsmGetGdtLimit();
/**
* @brief Get IDT base
*
- * @return unsigned long long
+ * @return UINT64
*/
-extern unsigned long long inline AsmGetIdtBase();
+extern UINT64 inline AsmGetIdtBase();
/**
* @brief Get IDT limit
*
- * @return unsigned short
+ * @return UINT16
*/
-extern unsigned short
+extern UINT16
AsmGetIdtLimit();
extern UINT32
-AsmGetAccessRights(unsigned short Selector);
+AsmGetAccessRights(UINT16 Selector);
//
// ==================== Common Functions ====================
// File : AsmCommon.asm
@@ -247,22 +253,22 @@ AsmGetAccessRights(unsigned short Selector);
/**
* @brief Get R/EFLAGS
*
- * @return unsigned short
+ * @return UINT16
*/
-extern unsigned short
+extern UINT16
AsmGetRflags();
/**
* @brief Run CLI Instruction
*
*/
-extern void inline AsmCliInstruction();
+extern VOID inline AsmCliInstruction();
/**
* @brief Run STI Instruction
*
*/
-extern void inline AsmStiInstruction();
+extern VOID inline AsmStiInstruction();
/**
* @brief Reload new GDTR
@@ -270,17 +276,25 @@ extern void inline AsmStiInstruction();
* @param GdtBase
* @param GdtLimit
*/
-extern void
-AsmReloadGdtr(void * GdtBase, unsigned long GdtLimit);
+extern VOID
+AsmReloadGdtr(PVOID GdtBase, ULONG GdtLimit);
/**
* @brief Reload new IDTR
*
- * @param GdtBase
- * @param GdtLimit
+ * @param IdtrBase
+ * @param IdtrLimit
*/
-extern void
-AsmReloadIdtr(void * GdtBase, unsigned long GdtLimit);
+extern VOID
+AsmReloadIdtr(PVOID IdtrBase, ULONG IdtrLimit);
+
+/**
+ * @brief Read SSP
+ *
+ * @return UINT64
+ */
+extern UINT64
+AsmReadSsp();
//
// ==================== Hook Functions ====================
@@ -291,8 +305,8 @@ AsmReloadIdtr(void * GdtBase, unsigned long GdtLimit);
* @brief Detour hook handler
*
*/
-extern void
-AsmGeneralDetourHook(void);
+extern VOID
+ AsmGeneralDetourHook(VOID);
//
// ==================== Kernel Test Functions ====================
@@ -303,11 +317,11 @@ AsmGeneralDetourHook(void);
* @brief Tests with test tags wrapper
*
*/
-extern unsigned long long
-AsmTestWrapperWithTestTags(unsigned long long Param1,
- unsigned long long Param2,
- unsigned long long Param3,
- unsigned long long Param4);
+extern UINT64
+AsmTestWrapperWithTestTags(UINT64 Param1,
+ UINT64 Param2,
+ UINT64 Param3,
+ UINT64 Param4);
//
// ==================== Interrupt Handler Functions ====================
@@ -318,215 +332,215 @@ AsmTestWrapperWithTestTags(unsigned long long Param1,
* @brief The 0th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler0();
/**
* @brief The 1st entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler1();
/**
* @brief The 2nd entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler2();
/**
* @brief The 3rd entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler3();
/**
* @brief The 4th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler4();
/**
* @brief The 5th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler5();
/**
* @brief The 6th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler6();
/**
* @brief The 7th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler7();
/**
* @brief The 8th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler8();
/**
* @brief The 9th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler9();
/**
* @brief The 10th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler10();
/**
* @brief The 11th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler11();
/**
* @brief The 12th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler12();
/**
* @brief The 13th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler13();
/**
* @brief The 14th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler14();
/**
* @brief The 15th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler15();
/**
* @brief The 16th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler16();
/**
* @brief The 17th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler17();
/**
* @brief The 18th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler18();
/**
* @brief The 19th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler19();
/**
* @brief The 20th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler20();
/**
* @brief The 21st entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler21();
/**
* @brief The 22nd entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler22();
/**
* @brief The 23rd entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler23();
/**
* @brief The 24th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler24();
/**
* @brief The 25th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler25();
/**
* @brief The 26th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler26();
/**
* @brief The 27th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler27();
/**
* @brief The 28th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler28();
/**
* @brief The 29th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler29();
/**
* @brief The 30th entry in IDT
*
*/
-extern void
+extern VOID
InterruptHandler30();
diff --git a/hyperdbg/hyperhv/header/common/Bitwise.h b/hyperdbg/hyperhv/header/common/Bitwise.h
index 5e5e674a..13601671 100644
--- a/hyperdbg/hyperhv/header/common/Bitwise.h
+++ b/hyperdbg/hyperhv/header/common/Bitwise.h
@@ -15,11 +15,11 @@
// Functions //
//////////////////////////////////////////////////
-int
-TestBit(int BitNumber, unsigned long * Addr);
+INT
+TestBit(INT BitNumber, ULONG * Addr);
-void
-ClearBit(int BitNumber, unsigned long * Addr);
+VOID
+ClearBit(INT BitNumber, ULONG * Addr);
-void
-SetBit(int BitNumber, unsigned long * Addr);
+VOID
+SetBit(INT BitNumber, ULONG * Addr);
diff --git a/hyperdbg/hyperhv/header/common/Common.h b/hyperdbg/hyperhv/header/common/Common.h
index c7bc92f3..317e841c 100644
--- a/hyperdbg/hyperhv/header/common/Common.h
+++ b/hyperdbg/hyperhv/header/common/Common.h
@@ -42,8 +42,8 @@
*/
#define RPL_MASK 3
-#define BITS_PER_LONG (sizeof(unsigned long) * 8)
-#define ORDER_LONG (sizeof(unsigned long) == 4 ? 5 : 6)
+#define BITS_PER_LONG (sizeof(ULONG) * 8)
+#define ORDER_LONG (sizeof(ULONG) == 4 ? 5 : 6)
#define BITMAP_ENTRY(_nr, _bmap) ((_bmap))[(_nr) / BITS_PER_LONG]
#define BITMAP_SHIFT(_nr) ((_nr) % BITS_PER_LONG)
@@ -82,10 +82,10 @@ typedef SEGMENT_DESCRIPTOR_32 * PSEGMENT_DESCRIPTOR;
*/
typedef struct _CPUID
{
- int eax;
- int ebx;
- int ecx;
- int edx;
+ INT eax;
+ INT ebx;
+ INT ecx;
+ INT edx;
} CPUID, *PCPUID;
typedef union _CR_FIXED
@@ -94,8 +94,8 @@ typedef union _CR_FIXED
struct
{
- unsigned long Low;
- long High;
+ ULONG Low;
+ LONG High;
} Fields;
@@ -125,7 +125,7 @@ typedef struct _NT_KPROCESS
* @brief Prototype to run a function on a logical core
*
*/
-typedef void (*RunOnLogicalCoreFunc)(ULONG ProcessorId);
+typedef VOID (*RunOnLogicalCoreFunc)(ULONG ProcessorId);
//////////////////////////////////////////////////
// External Functions //
@@ -153,7 +153,7 @@ BOOLEAN
CommonAffinityBroadcastToProcessors(_In_ ULONG ProcessorNumber, _In_ RunOnLogicalCoreFunc Routine);
BOOLEAN
-CommonIsStringStartsWith(const char * pre, const char * str);
+CommonIsStringStartsWith(const CHAR * pre, const CHAR * str);
BOOLEAN
CommonIsGuestOnUsermode32Bit();
@@ -162,7 +162,7 @@ PCHAR
CommonGetProcessNameFromProcessControlBlock(PEPROCESS eprocess);
VOID
-CommonCpuidInstruction(UINT32 Func, UINT32 SubFunc, int * CpuInfo);
+CommonCpuidInstruction(UINT32 Func, UINT32 SubFunc, INT * CpuInfo);
VOID
CommonWriteDebugInformation(VIRTUAL_MACHINE_STATE * VCpu);
diff --git a/hyperdbg/hyperhv/header/common/Msr.h b/hyperdbg/hyperhv/header/common/Msr.h
index 2665c691..eab90724 100644
--- a/hyperdbg/hyperhv/header/common/Msr.h
+++ b/hyperdbg/hyperhv/header/common/Msr.h
@@ -11,6 +11,18 @@
*/
#pragma once
+//////////////////////////////////////////////////
+// MSR Numbers //
+//////////////////////////////////////////////////
+
+/**
+ * @brief MSR for System Management Interrupt (SMI) count
+ *
+ * @details This MSR is used to read the count of System Management Interrupts (SMIs)
+ * that have occurred since the last reset
+ */
+#define MSR_SMI_COUNT 0x00000034
+
//////////////////////////////////////////////////
// Structures //
//////////////////////////////////////////////////
diff --git a/hyperdbg/hyperhv/header/common/State.h b/hyperdbg/hyperhv/header/common/State.h
index c6a587e2..8ea8a312 100644
--- a/hyperdbg/hyperhv/header/common/State.h
+++ b/hyperdbg/hyperhv/header/common/State.h
@@ -132,6 +132,13 @@ typedef struct _VMM_EPT_PAGE_TABLE
DECLSPEC_ALIGN(PAGE_SIZE)
EPT_PML2_ENTRY PML2[VMM_EPT_PML3E_COUNT][VMM_EPT_PML2E_COUNT];
+ /**
+ * @brief Tracks dynamic 2MB->4KB splits for this EPT table.
+ * NOTE: Each item stores a direct VA to the split PML1 page and the corresponding PML2 entry it services.
+ *
+ */
+ LIST_ENTRY DynamicSplitList;
+
} VMM_EPT_PAGE_TABLE, *PVMM_EPT_PAGE_TABLE;
//////////////////////////////////////////////////
@@ -302,52 +309,53 @@ typedef struct _NMI_BROADCASTING_STATE
*/
typedef struct _VIRTUAL_MACHINE_STATE
{
- BOOLEAN IsOnVmxRootMode; // Detects whether the current logical core is on Executing on VMX Root Mode
- BOOLEAN IncrementRip; // Checks whether it has to redo the previous instruction or not (it used mainly in Ept routines)
- BOOLEAN HasLaunched; // Indicate whether the core is virtualized or not
- BOOLEAN IgnoreMtfUnset; // Indicate whether the core should ignore unsetting the MTF or not
- BOOLEAN WaitForImmediateVmexit; // Whether the current core is waiting for an immediate vm-exit or not
- BOOLEAN EnableExternalInterruptsOnContinue; // Whether to enable external interrupts on the continue or not
- BOOLEAN EnableExternalInterruptsOnContinueMtf; // Whether to enable external interrupts on the continue state of MTF or not
- BOOLEAN RegisterBreakOnMtf; // Registered Break in the case of MTFs (used in instrumentation step-in)
- BOOLEAN IgnoreOneMtf; // Ignore (mark as handled) for one MTF
- BOOLEAN NotNormalEptp; // Indicate that the target processor is on the normal EPTP or not
- BOOLEAN MbecEnabled; // Indicate that the target processor is on MBEC-enabled mode or not
- PUINT64 PmlBufferAddress; // Address of buffer used for dirty logging
- BOOLEAN Test; // Used for test purposes
- UINT64 TestNumber; // Used for test purposes (Number)
- GUEST_REGS * Regs; // The virtual processor's general-purpose registers
- UINT32 CoreId; // The core's unique identifier
- UINT32 ExitReason; // The core's exit reason
- UINT32 ExitQualification; // The core's exit qualification
- UINT64 LastVmexitRip; // RIP in the current VM-exit
- UINT64 VmxonRegionPhysicalAddress; // Vmxon region physical address
- UINT64 VmxonRegionVirtualAddress; // VMXON region virtual address
- UINT64 VmcsRegionPhysicalAddress; // VMCS region physical address
- UINT64 VmcsRegionVirtualAddress; // VMCS region virtual address
- UINT64 VmmStack; // Stack for VMM in VM-Exit State
- UINT64 MsrBitmapVirtualAddress; // Msr Bitmap Virtual Address
- UINT64 MsrBitmapPhysicalAddress; // Msr Bitmap Physical Address
- UINT64 IoBitmapVirtualAddressA; // I/O Bitmap Virtual Address (A)
- UINT64 IoBitmapPhysicalAddressA; // I/O Bitmap Physical Address (A)
- UINT64 IoBitmapVirtualAddressB; // I/O Bitmap Virtual Address (B)
- UINT64 IoBitmapPhysicalAddressB; // I/O Bitmap Physical Address (B)
- UINT32 QueuedNmi; // Queued NMIs
- UINT32 PendingExternalInterrupts[PENDING_INTERRUPTS_BUFFER_CAPACITY]; // This list holds a buffer for external-interrupts that are in pending state due to the external-interrupt
- // blocking and waits for interrupt-window exiting
- // From hvpp :
- // Pending interrupt queue (FIFO).
- // Make storage for up-to 64 pending interrupts.
- // In practice I haven't seen more than 2 pending interrupts.
- VMX_VMXOFF_STATE VmxoffState; // Shows the vmxoff state of the guest
- NMI_BROADCASTING_STATE NmiBroadcastingState; // Shows the state of NMI broadcasting
- VM_EXIT_TRANSPARENCY TransparencyState; // The state of the debugger in transparent-mode
- PEPT_HOOKED_PAGE_DETAIL MtfEptHookRestorePoint; // It shows the detail of the hooked paged that should be restore in MTF vm-exit
- UINT8 LastExceptionOccuredInHost; // The vector of last exception occured in host
- UINT64 HostIdt; // host Interrupt Descriptor Table (actual type is SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64*)
- UINT64 HostGdt; // host Global Descriptor Table (actual type is SEGMENT_DESCRIPTOR_32* or SEGMENT_DESCRIPTOR_64*)
- UINT64 HostTss; // host Task State Segment (actual type is TASK_STATE_SEGMENT_64*)
- UINT64 HostInterruptStack; // host interrupt RSP
+ BOOLEAN IsOnVmxRootMode; // Detects whether the current logical core is on Executing on VMX Root Mode
+ BOOLEAN IncrementRip; // Checks whether it has to redo the previous instruction or not (it used mainly in Ept routines)
+ BOOLEAN HasLaunched; // Indicate whether the core is virtualized or not
+ BOOLEAN IgnoreMtfUnset; // Indicate whether the core should ignore unsetting the MTF or not
+ BOOLEAN WaitForImmediateVmexit; // Whether the current core is waiting for an immediate vm-exit or not
+ BOOLEAN EnableExternalInterruptsOnContinue; // Whether to enable external interrupts on the continue or not
+ BOOLEAN EnableExternalInterruptsOnContinueMtf; // Whether to enable external interrupts on the continue state of MTF or not
+ BOOLEAN InstrumentationStepInMtf; // Instrumentation step in MTF or not (used for single stepping with MTF)
+ BOOLEAN IgnoreOneMtf; // Ignore (mark as handled) for one MTF
+ BOOLEAN NotNormalEptp; // Indicate that the target processor is on the normal EPTP or not
+ BOOLEAN MbecEnabled; // Indicate that the target processor is on MBEC-enabled mode or not
+ PUINT64 PmlBufferAddress; // Address of buffer used for dirty logging
+ BOOLEAN Test; // Used for test purposes
+ UINT64 TestNumber; // Used for test purposes (Number)
+ GUEST_REGS * Regs; // The virtual processor's general-purpose registers
+ GUEST_XMM_REGS * XmmRegs; // The virtual processor's XMM registers
+ UINT32 CoreId; // The core's unique identifier
+ UINT32 ExitReason; // The core's exit reason
+ UINT32 ExitQualification; // The core's exit qualification
+ UINT64 LastVmexitRip; // RIP in the current VM-exit
+ UINT64 VmxonRegionPhysicalAddress; // Vmxon region physical address
+ UINT64 VmxonRegionVirtualAddress; // VMXON region virtual address
+ UINT64 VmcsRegionPhysicalAddress; // VMCS region physical address
+ UINT64 VmcsRegionVirtualAddress; // VMCS region virtual address
+ UINT64 VmmStack; // Stack for VMM in VM-Exit State
+ UINT64 MsrBitmapVirtualAddress; // Msr Bitmap Virtual Address
+ UINT64 MsrBitmapPhysicalAddress; // Msr Bitmap Physical Address
+ UINT64 IoBitmapVirtualAddressA; // I/O Bitmap Virtual Address (A)
+ UINT64 IoBitmapPhysicalAddressA; // I/O Bitmap Physical Address (A)
+ UINT64 IoBitmapVirtualAddressB; // I/O Bitmap Virtual Address (B)
+ UINT64 IoBitmapPhysicalAddressB; // I/O Bitmap Physical Address (B)
+ UINT32 QueuedNmi; // Queued NMIs
+ UINT32 PendingExternalInterrupts[PENDING_INTERRUPTS_BUFFER_CAPACITY]; // This list holds a buffer for external-interrupts that are in pending state due to the external-interrupt
+ // blocking and waits for interrupt-window exiting
+ // From hvpp :
+ // Pending interrupt queue (FIFO).
+ // Make storage for up-to 64 pending interrupts.
+ // In practice I haven't seen more than 2 pending interrupts.
+ VMX_VMXOFF_STATE VmxoffState; // Shows the vmxoff state of the guest
+ NMI_BROADCASTING_STATE NmiBroadcastingState; // Shows the state of NMI broadcasting
+ VM_EXIT_TRANSPARENCY TransparencyState; // The state of the debugger in transparent-mode
+ PEPT_HOOKED_PAGE_DETAIL MtfEptHookRestorePoint; // It shows the detail of the hooked paged that should be restore in MTF vm-exit
+ UINT8 LastExceptionOccurredInHost; // The vector of last exception occurred in host
+ UINT64 HostIdt; // host Interrupt Descriptor Table (actual type is SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64*)
+ UINT64 HostGdt; // host Global Descriptor Table (actual type is SEGMENT_DESCRIPTOR_32* or SEGMENT_DESCRIPTOR_64*)
+ UINT64 HostTss; // host Task State Segment (actual type is TASK_STATE_SEGMENT_64*)
+ UINT64 HostInterruptStack; // host interrupt RSP
//
// EPT Descriptors
diff --git a/hyperdbg/hyperhv/header/common/UnloadDll.h b/hyperdbg/hyperhv/header/common/UnloadDll.h
index c6388ac7..2dc53a57 100644
--- a/hyperdbg/hyperhv/header/common/UnloadDll.h
+++ b/hyperdbg/hyperhv/header/common/UnloadDll.h
@@ -15,6 +15,7 @@
// Exported Functions //
//////////////////////////////////////////////////
-__declspec(dllexport) NTSTATUS DllInitialize(_In_ PUNICODE_STRING RegistryPath);
+__declspec(dllexport) NTSTATUS
+DllInitialize(_In_ PUNICODE_STRING RegistryPath);
-__declspec(dllexport) NTSTATUS DllUnload(void);
+__declspec(dllexport) NTSTATUS DllUnload(VOID);
diff --git a/hyperdbg/hyperhv/header/features/CompatibilityChecks.h b/hyperdbg/hyperhv/header/features/CompatibilityChecks.h
index 52bf74e2..a7b4baa1 100644
--- a/hyperdbg/hyperhv/header/features/CompatibilityChecks.h
+++ b/hyperdbg/hyperhv/header/features/CompatibilityChecks.h
@@ -27,6 +27,8 @@ typedef struct _COMPATIBILITY_CHECKS_STATUS
BOOLEAN PmlSupport; // check Page Modification Logging (PML) support
BOOLEAN ModeBasedExecutionSupport; // check for mode based execution support (processors after Kaby Lake release will support this feature)
BOOLEAN ExecuteOnlySupport; // Support for execute-only pages (indicating that data accesses are not allowed while instruction fetches are allowed)
+ BOOLEAN CetIbtSupport; // CET IBT support (indicating that indirect branch tracking is supported)
+ BOOLEAN CetShadowStackSupport; // CET shadow stack support (indicating that shadow stacks are supported)
UINT32 VirtualAddressWidth; // Virtual address width for x86 processors
UINT32 PhysicalAddressWidth; // Physical address width for x86 processors
diff --git a/hyperdbg/hyperhv/header/globals/GlobalVariables.h b/hyperdbg/hyperhv/header/globals/GlobalVariables.h
index c8effacf..b0b71f10 100644
--- a/hyperdbg/hyperhv/header/globals/GlobalVariables.h
+++ b/hyperdbg/hyperhv/header/globals/GlobalVariables.h
@@ -148,6 +148,8 @@ BOOLEAN g_TriggerEventForVmcalls;
*/
BOOLEAN g_TriggerEventForCpuids;
+BOOLEAN g_TriggerEventForXsetbvs;
+
//////////////////////////////////////////////////
// Global Variable (Execution Trap) //
//////////////////////////////////////////////////
@@ -183,7 +185,7 @@ BOOLEAN g_IsInterceptingInstructions;
//////////////////////////////////////////////////
/**
- * @brief Shows whether the the VMM is waiting to inject a page-fault
+ * @brief Shows whether the VMM is waiting to inject a page-fault
* or not
*
*/
@@ -206,3 +208,13 @@ UINT64 g_PageFaultInjectionAddressTo;
*
*/
UINT32 g_PageFaultInjectionErrorCode;
+
+/**
+ * @brief Whether VPID is supported or not
+ */
+BOOLEAN g_IsVpidSupported;
+
+/**
+ * @brief Whether the top level hypervisor is Hyper-V or not
+ */
+BOOLEAN g_IsTopLevelHypervisorHyperV;
diff --git a/hyperdbg/hyperhv/header/hooks/SyscallCallback.h b/hyperdbg/hyperhv/header/hooks/SyscallCallback.h
index 80c30ac4..efbac8bc 100644
--- a/hyperdbg/hyperhv/header/hooks/SyscallCallback.h
+++ b/hyperdbg/hyperhv/header/hooks/SyscallCallback.h
@@ -1,6 +1,7 @@
/**
* @file SyscallHook.h
* @author Sina Karvandi (sina@hyperdbg.org)
+ * @author jtaw5649
* @brief Header for syscall hook callbacks
* @details
*
@@ -78,6 +79,9 @@ typedef struct _SYSCALL_CALLBACK_TRAP_FLAG_STATE
BOOLEAN
SyscallCallbackInitialize();
+BOOLEAN
+SyscallCallbackIsInitialized();
+
BOOLEAN
SyscallCallbackUninitialize();
diff --git a/hyperdbg/hyperhv/header/interface/Callback.h b/hyperdbg/hyperhv/header/interface/Callback.h
index c97d1b44..294cb22a 100644
--- a/hyperdbg/hyperhv/header/interface/Callback.h
+++ b/hyperdbg/hyperhv/header/interface/Callback.h
@@ -44,15 +44,21 @@ VmmCallbackUnhandledEptViolation(UINT32 CoreId,
UINT64 ViolationQualification,
UINT64 GuestPhysicalAddr);
+BOOLEAN
+VmmCallbackHandleMtfCallback(UINT32 CoreId);
+
VOID
VmmCallbackSetLastError(UINT32 LastError);
-VOID
-VmmCallbackRegisteredMtfHandler(UINT32 CoreId);
-
VOID
VmmCallbackNmiBroadcastRequestHandler(UINT32 CoreId, BOOLEAN IsOnVmxNmiHandler);
+//
+// HyperTrace Callbacks
+//
+BOOLEAN
+HyperTraceCallbackLbrIsSupported(UINT32 * Capacity, BOOLEAN * IsArchLbr);
+
//
// Debugging Callbacks
//
@@ -66,6 +72,25 @@ DebuggingCallbackHandleDebugBreakpointException(UINT32 CoreId);
BOOLEAN
DebuggingCallbackCheckThreadInterception(UINT32 CoreId);
+BOOLEAN
+DebuggingCallbackTriggerOnClockAndIpiEvents(UINT32 CoreId);
+
+BOOLEAN
+DebuggingCallbackIgnoreHandlingMov2DebugRegs(UINT32 CoreId);
+
+//
+// Pool Manager Callbacks
+//
+
+BOOLEAN
+PoolManagerCallbackRequestAllocation(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention);
+
+UINT64
+PoolManagerCallbackRequestPool(POOL_ALLOCATION_INTENTION Intention, BOOLEAN RequestNewPool, UINT32 Size);
+
+BOOLEAN
+PoolManagerCallbackFreePool(UINT64 AddressToFree);
+
//
// Interception Callbacks
//
diff --git a/hyperdbg/hyperhv/header/interface/Dispatch.h b/hyperdbg/hyperhv/header/interface/Dispatch.h
index f771bdd8..f35ed6ef 100644
--- a/hyperdbg/hyperhv/header/interface/Dispatch.h
+++ b/hyperdbg/hyperhv/header/interface/Dispatch.h
@@ -25,6 +25,9 @@ DispatchEventEferSyscall(VIRTUAL_MACHINE_STATE * VCpu);
VOID
DispatchEventCpuid(VIRTUAL_MACHINE_STATE * VCpu);
+VOID
+DispatchEventXsetbv(VIRTUAL_MACHINE_STATE * VCpu);
+
VOID
DispatchEventTsc(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN IsRdtscp);
diff --git a/hyperdbg/hyperhv/header/processor/Smm.h b/hyperdbg/hyperhv/header/processor/Smm.h
new file mode 100644
index 00000000..05946608
--- /dev/null
+++ b/hyperdbg/hyperhv/header/processor/Smm.h
@@ -0,0 +1,30 @@
+/**
+ * @file Smm.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Headers relating to operations related to System Management Mode (SMM)
+ * @details
+ *
+ * @version 0.15
+ * @date 2025-08-02
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Constants //
+//////////////////////////////////////////////////
+
+/**
+ * @brief SMI trigger port value
+ *
+ */
+#define SMI_TRIGGER_POWER_VALUE 0x80
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+BOOLEAN
+SmmPerformSmiOperation(SMI_OPERATION_PACKETS * SmiOperationRequest, BOOLEAN ApplyFromVmxRootMode);
diff --git a/hyperdbg/hyperhv/header/vmm/ept/Ept.h b/hyperdbg/hyperhv/header/vmm/ept/Ept.h
index 2259a78e..b8a69750 100644
--- a/hyperdbg/hyperhv/header/vmm/ept/Ept.h
+++ b/hyperdbg/hyperhv/header/vmm/ept/Ept.h
@@ -147,14 +147,14 @@ typedef struct _VMM_EPT_DYNAMIC_SPLIT
EPT_PML1_ENTRY PML1[VMM_EPT_PML1E_COUNT];
/**
- * @brief The pointer to the 2MB entry in the page table which this split is servicing.
+ * @brief The pointer to the 2MB entry in the page table which this split is servicing
*
*/
union
{
PEPT_PML2_ENTRY Entry;
PEPT_PML2_POINTER Pointer;
- } u;
+ } Fields;
/**
* @brief Linked list entries for each dynamic split
@@ -209,16 +209,16 @@ PVMM_EPT_PAGE_TABLE
EptAllocateAndCreateIdentityPageTable(VOID);
/**
- * @brief Convert 2MB pages to 4KB pages
+ * @brief Convert large pages to 4KB pages
*
* @param EptPageTable
- * @param PreAllocatedBuffer
+ * @param UsePreAllocatedBuffer
* @param PhysicalAddress
* @return BOOLEAN
*/
BOOLEAN
EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable,
- PVOID PreAllocatedBuffer,
+ BOOLEAN UsePreAllocatedBuffer,
SIZE_T PhysicalAddress);
/**
diff --git a/hyperdbg/hyperhv/header/vmm/vmx/CrossVmcalls.h b/hyperdbg/hyperhv/header/vmm/vmx/CrossVmcalls.h
new file mode 100644
index 00000000..a973f57d
--- /dev/null
+++ b/hyperdbg/hyperhv/header/vmm/vmx/CrossVmcalls.h
@@ -0,0 +1,43 @@
+/**
+ * @file CrossVmcalls.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Headers relating to cross (standalone) VMCALLs
+ * @details
+ * @version 0.19
+ * @date 2026-04-14
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+UINT64
+CrossVmcallGetDebugctlVmcallOnTargetCore();
+
+UINT64
+CrossVmcallGetGuestIa32LbrCtlVmcallOnTargetCore();
+
+VOID
+CrossVmcallSetDebugctlVmcallOnTargetCore(UINT64 Value);
+
+VOID
+CrossVmcallSetGuestIa32LbrCtlVmcallOnTargetCore(UINT64 Value);
+
+VOID
+CrossVmcallSetLbrSelectVmcallOnTargetCore(UINT64 FilterOptions);
+
+VOID
+CrossVmcallSetLoadDebugControlsVmcallOnTargetCore(BOOLEAN Set);
+
+VOID
+CrossVmcallSetLoadGuestIa32LbrCtlVmcallOnTargetCore(BOOLEAN Set);
+
+VOID
+CrossVmcallSetSaveDebugControlsVmcallOnTargetCore(BOOLEAN Set);
+
+VOID
+CrossVmcallSetClearGuestIa32LbrCtlVmcallOnTargetCore(BOOLEAN Set);
diff --git a/hyperdbg/hyperhv/header/vmm/vmx/Hv.h b/hyperdbg/hyperhv/header/vmm/vmx/Hv.h
index 6f11105d..2aa85bea 100644
--- a/hyperdbg/hyperhv/header/vmm/vmx/Hv.h
+++ b/hyperdbg/hyperhv/header/vmm/vmx/Hv.h
@@ -118,20 +118,42 @@ HvSetRflagTrapFlag(BOOLEAN Set);
/**
* @brief Set LOAD DEBUG CONTROLS on Vm-entry controls
*
+ * @param VCpu
* @param Set Set or unset
* @return VOID
*/
VOID
-HvSetLoadDebugControls(BOOLEAN Set);
+HvSetLoadDebugControls(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set);
+
+/**
+ * @brief Set LOAD GUEST IA32_LBR_CTL on Vm-entry controls
+ *
+ * @param VCpu
+ * @param Set Set or unset
+ * @return VOID
+ */
+VOID
+HvSetLoadGuestIa32LbrCtl(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set);
/**
* @brief Set SAVE DEBUG CONTROLS on Vm-exit controls
*
+ * @param VCpu
* @param Set Set or unset
* @return VOID
*/
VOID
-HvSetSaveDebugControls(BOOLEAN Set);
+HvSetSaveDebugControls(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set);
+
+/**
+ * @brief Set SAVE GUEST IA32_LBR_CTL on Vm-exit controls
+ *
+ * @param VCpu
+ * @param Set Set or unset
+ * @return VOID
+ */
+VOID
+HvSetClearGuestIa32LbrCtl(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set);
/**
* @brief Reset GDTR/IDTR and other old when you do vmxoff as the patchguard
@@ -456,6 +478,36 @@ HvSetPendingDebugExceptions(UINT64 Value);
UINT64
HvGetDebugctl();
+/**
+ * @brief Get the guest state of IA32_LBR_CTL
+ *
+ * @return UINT64
+ */
+UINT64
+HvGetGuestIa32LbrCtl();
+
+/**
+ * @brief Get and store the guest state of IA32_DEBUGCTL
+ * @details mainly used from the VMCALL handler
+ *
+ * @param StoreDebugctl
+ *
+ * @return VOID
+ */
+VOID
+HvGetAndStoreDebugctl(UINT64 * StoreDebugctl);
+
+/**
+ * @brief Get and store the guest state of IA32_LBR_CTL
+ * @details mainly used from the VMCALL handler
+ *
+ * @param StoreGuestIa32Lbr
+ *
+ * @return VOID
+ */
+VOID
+HvGetAndStoreGuestIa32LbrCtl(UINT64 * StoreGuestIa32Lbr);
+
/**
* @brief Set the guest state of IA32_DEBUGCTL
* @param Value The new state
@@ -465,6 +517,50 @@ HvGetDebugctl();
VOID
HvSetDebugctl(UINT64 Value);
+/**
+ * @brief Set the guest state of IA32_LBR_CTL
+ * @param Value The new state
+ *
+ * @return VOID
+ */
+VOID
+HvSetGuestIa32LbrCtl(UINT64 Value);
+
+/**
+ * @brief Set LBR selector
+ * @details If VMM is active, this should be done in vmx-root, otherwise, it doesn't work
+ * @param FilterOptions The value to write on MSR_LEGACY_LBR_SELECT
+ *
+ * @return VOID
+ */
+VOID
+HvSetLbrSelect(UINT64 FilterOptions);
+
+/**
+ * @brief Check if CPU support save and load debug controls on exit and load entries
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HvCheckCpuSupportForSaveAndLoadDebugControls();
+
+/**
+ * @brief Check if CPU support load and clear guest IA32_LBR_CTL controls on VM-entry and VM-exit
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HvCheckCpuSupportForLoadAndClearGuestIa32LbrCtlControls();
+
+/**
+ * @brief Set the guest state of DR7
+ * @param Value The new value for DR7
+ *
+ * @return VOID
+ */
+VOID
+HvSetDebugReg7(UINT64 Value);
+
/**
* @brief Handle the case when the trap flag is set, and
* we need to inject the single-step exception right
@@ -473,4 +569,4 @@ HvSetDebugctl(UINT64 Value);
* @return VOID
*/
VOID
-HvHandleTrapFlag();
\ No newline at end of file
+HvHandleTrapFlag();
diff --git a/hyperdbg/hyperhv/header/vmm/vmx/IoHandler.h b/hyperdbg/hyperhv/header/vmm/vmx/IoHandler.h
index 15767148..20b698f6 100644
--- a/hyperdbg/hyperhv/header/vmm/vmx/IoHandler.h
+++ b/hyperdbg/hyperhv/header/vmm/vmx/IoHandler.h
@@ -39,124 +39,76 @@ typedef enum _IO_OP_ENCODING
// I/O Instructions Functions //
//////////////////////////////////////////////////
-unsigned char
-__inbyte(unsigned short);
-#pragma intrinsic(__inbyte)
-
inline UINT8
IoInByte(UINT16 port)
{
- return __inbyte(port);
+ return CpuIoInByte(port);
}
-unsigned short
-__inword(unsigned short);
-#pragma intrinsic(__inword)
-
inline UINT16
IoInWord(UINT16 port)
{
- return __inword(port);
+ return CpuIoInWord(port);
}
-unsigned long
-__indword(unsigned short);
-#pragma intrinsic(__indword)
-
inline UINT32
IoInDword(UINT16 port)
{
- return __indword(port);
+ return CpuIoInDword(port);
}
-void
-__inbytestring(unsigned short, unsigned char *, unsigned long);
-#pragma intrinsic(__inbytestring)
-
-inline void
+inline VOID
IoInByteString(UINT16 port, UINT8 * data, UINT32 size)
{
- __inbytestring(port, data, size);
+ CpuIoInByteString(port, data, size);
}
-void
-__inwordstring(unsigned short, unsigned short *, unsigned long);
-#pragma intrinsic(__inwordstring)
-
-inline void
+inline VOID
IoInWordString(UINT16 port, UINT16 * data, UINT32 size)
{
- __inwordstring(port, data, size);
+ CpuIoInWordString(port, data, size);
}
-void
-__indwordstring(unsigned short, unsigned long *, unsigned long);
-#pragma intrinsic(__indwordstring)
-
-inline void
+inline VOID
IoInDwordString(UINT16 port, UINT32 * data, UINT32 size)
{
- __indwordstring(port, (unsigned long *)data, size);
+ CpuIoInDwordString(port, data, size);
}
-void
-__outbyte(unsigned short, unsigned char);
-#pragma intrinsic(__outbyte)
-
-inline void
+inline VOID
IoOutByte(UINT16 port, UINT8 value)
{
- __outbyte(port, value);
+ CpuIoOutByte(port, value);
}
-void
-__outword(unsigned short, unsigned short);
-#pragma intrinsic(__outword)
-
-inline void
+inline VOID
IoOutWord(UINT16 port, UINT16 value)
{
- __outword(port, value);
+ CpuIoOutWord(port, value);
}
-void
-__outdword(unsigned short, unsigned long);
-#pragma intrinsic(__outdword)
-
-inline void
+inline VOID
IoOutDword(UINT16 port, UINT32 value)
{
- __outdword(port, value);
+ CpuIoOutDword(port, value);
}
-void
-__outbytestring(unsigned short, unsigned char *, unsigned long);
-#pragma intrinsic(__outbytestring)
-
-inline void
+inline VOID
IoOutByteString(UINT16 port, UINT8 * data, UINT32 count)
{
- __outbytestring(port, data, count);
+ CpuIoOutByteString(port, data, count);
}
-void
-__outwordstring(unsigned short, unsigned short *, unsigned long);
-#pragma intrinsic(__outwordstring)
-
-inline void
+inline VOID
IoOutWordString(UINT16 port, UINT16 * data, UINT32 count)
{
- __outwordstring(port, data, count);
+ CpuIoOutWordString(port, data, count);
}
-void
-__outdwordstring(unsigned short, unsigned long *, unsigned long);
-#pragma intrinsic(__outdwordstring)
-
-inline void
+inline VOID
IoOutDwordString(UINT16 port, UINT32 * data, UINT32 count)
{
- __outdwordstring(port, (unsigned long *)data, count);
+ CpuIoOutDwordString(port, data, count);
}
//////////////////////////////////////////////////
diff --git a/hyperdbg/hyperhv/header/vmm/vmx/MsrHandlers.h b/hyperdbg/hyperhv/header/vmm/vmx/MsrHandlers.h
index ecd91e1b..3114949d 100644
--- a/hyperdbg/hyperhv/header/vmm/vmx/MsrHandlers.h
+++ b/hyperdbg/hyperhv/header/vmm/vmx/MsrHandlers.h
@@ -15,6 +15,9 @@
// Functions //
//////////////////////////////////////////////////
+BOOLEAN
+MsrHandleIsHypervSyntheticMsr(_In_ UINT32 TargetMsr);
+
VOID
MsrHandleRdmsrVmexit(VIRTUAL_MACHINE_STATE * VCpu);
diff --git a/hyperdbg/hyperhv/header/vmm/vmx/ProtectedHv.h b/hyperdbg/hyperhv/header/vmm/vmx/ProtectedHv.h
index aeb1f8f0..9f8d669f 100644
--- a/hyperdbg/hyperhv/header/vmm/vmx/ProtectedHv.h
+++ b/hyperdbg/hyperhv/header/vmm/vmx/ProtectedHv.h
@@ -84,3 +84,13 @@ ProtectedHvSetMov2CrExiting(BOOLEAN Set, UINT64 ControlRegister, UINT64 MaskRegi
VOID
ProtectedHvSetMov2Cr3Exiting(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set);
+
+//
+// Save and load state on vm-exit and vm-entry
+//
+
+VOID
+ProtectedHvSetSaveDebugControls(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set);
+
+VOID
+ProtectedHvSetLoadDebugControls(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set);
diff --git a/hyperdbg/hyperhv/header/vmm/vmx/Vmcall.h b/hyperdbg/hyperhv/header/vmm/vmx/Vmcall.h
index d96e0ac7..33001dc2 100644
--- a/hyperdbg/hyperhv/header/vmm/vmx/Vmcall.h
+++ b/hyperdbg/hyperhv/header/vmm/vmx/Vmcall.h
@@ -161,8 +161,7 @@
/**
* @brief VMCALL to reset exception bitmap on VMCS
- * @details THIS VMCALL SHOULD BE USED ONLY IN
- * RESETTING (CLEARING) EXCEPTION EVENTS
+ * @details THIS VMCALL SHOULD BE USED ONLY IN RESETTING (CLEARING) EXCEPTION EVENTS
*
*/
#define VMCALL_RESET_EXCEPTION_BITMAP_ONLY_ON_CLEARING_EXCEPTION_EVENTS 0x00000019
@@ -321,6 +320,60 @@
*/
#define VMCALL_WRITE_PHYSICAL_MEMORY 0x00000031
+/**
+ * @brief VMCALL to get IA32_DEBUGCTL on VMCS
+ *
+ */
+#define VMCALL_GET_VMCS_DEBUGCTL 0x00000032
+
+/**
+ * @brief VMCALL to set IA32_DEBUGCTL on VMCS
+ *
+ */
+#define VMCALL_SET_VMCS_DEBUGCTL 0x00000033
+
+/**
+ * @brief VMCALL to set MSR_LEGACY_LBR_SELECT using WRMSR
+ *
+ */
+#define VMCALL_SET_MSR_LBR_SELECT 0x00000034
+
+/**
+ * @brief VMCALL to get the guest state of IA32_LBR_CTL on VMCS
+ *
+ */
+#define VMCALL_GET_GUEST_IA32_LBR_CTL 0x00000035
+
+/**
+ * @brief VMCALL to set the guest state of IA32_LBR_CTL on VMCS
+ *
+ */
+#define VMCALL_SET_GUEST_IA32_LBR_CTL 0x00000036
+
+/**
+ * @brief VMCALL to set LOAD GUEST IA32_LBR_CTL on VM-entry controls
+ *
+ */
+#define VMCALL_SET_VM_ENTRY_LOAD_GUEST_IA32_LBR_CTL 0x00000037
+
+/**
+ * @brief VMCALL to unset LOAD GUEST IA32_LBR_CTL on VM-entry controls
+ *
+ */
+#define VMCALL_UNSET_VM_ENTRY_LOAD_GUEST_IA32_LBR_CTL 0x00000038
+
+/**
+ * @brief VMCALL to set CLEAR GUEST IA32_LBR_CTL on VM-exit controls
+ *
+ */
+#define VMCALL_SET_CLEAR_GUEST_IA32_LBR_CTL 0x00000039
+
+/**
+ * @brief VMCALL to unset CLEAR GUEST IA32_LBR_CTL on VM-exit controls
+ *
+ */
+#define VMCALL_UNSET_CLEAR_GUEST_IA32_LBR_CTL 0x0000003A
+
//////////////////////////////////////////////////
// Functions //
//////////////////////////////////////////////////
diff --git a/hyperdbg/hyperhv/header/vmm/vmx/Vmx.h b/hyperdbg/hyperhv/header/vmm/vmx/Vmx.h
index f116a9e9..2cb7b05d 100644
--- a/hyperdbg/hyperhv/header/vmm/vmx/Vmx.h
+++ b/hyperdbg/hyperhv/header/vmm/vmx/Vmx.h
@@ -27,81 +27,6 @@
*/
#define VMXON_SIZE 4096
-/**
- * @brief PIN-Based Execution
- *
- */
-#define PIN_BASED_VM_EXECUTION_CONTROLS_EXTERNAL_INTERRUPT 0x00000001
-#define PIN_BASED_VM_EXECUTION_CONTROLS_NMI_EXITING 0x00000008
-#define PIN_BASED_VM_EXECUTION_CONTROLS_VIRTUAL_NMI 0x00000020
-#define PIN_BASED_VM_EXECUTION_CONTROLS_ACTIVE_VMX_TIMER 0x00000040
-#define PIN_BASED_VM_EXECUTION_CONTROLS_PROCESS_POSTED_INTERRUPTS 0x00000080
-
-/**
- * @brief CPU-Based Controls
- *
- */
-#define CPU_BASED_VIRTUAL_INTR_PENDING 0x00000004
-#define CPU_BASED_USE_TSC_OFFSETTING 0x00000008
-#define CPU_BASED_HLT_EXITING 0x00000080
-#define CPU_BASED_INVLPG_EXITING 0x00000200
-#define CPU_BASED_MWAIT_EXITING 0x00000400
-#define CPU_BASED_RDPMC_EXITING 0x00000800
-#define CPU_BASED_RDTSC_EXITING 0x00001000
-#define CPU_BASED_CR3_LOAD_EXITING 0x00008000
-#define CPU_BASED_CR3_STORE_EXITING 0x00010000
-#define CPU_BASED_CR8_LOAD_EXITING 0x00080000
-#define CPU_BASED_CR8_STORE_EXITING 0x00100000
-#define CPU_BASED_TPR_SHADOW 0x00200000
-#define CPU_BASED_VIRTUAL_NMI_PENDING 0x00400000
-#define CPU_BASED_MOV_DR_EXITING 0x00800000
-#define CPU_BASED_UNCOND_IO_EXITING 0x01000000
-#define CPU_BASED_ACTIVATE_IO_BITMAP 0x02000000
-#define CPU_BASED_MONITOR_TRAP_FLAG 0x08000000
-#define CPU_BASED_ACTIVATE_MSR_BITMAP 0x10000000
-#define CPU_BASED_MONITOR_EXITING 0x20000000
-#define CPU_BASED_PAUSE_EXITING 0x40000000
-#define CPU_BASED_ACTIVATE_SECONDARY_CONTROLS 0x80000000
-
-/**
- * @brief Secondary CPU-Based Controls
- *
- */
-#define CPU_BASED_CTL2_ENABLE_EPT 0x2
-#define CPU_BASED_CTL2_RDTSCP 0x8
-#define CPU_BASED_CTL2_ENABLE_VPID 0x20
-#define CPU_BASED_CTL2_UNRESTRICTED_GUEST 0x80
-#define CPU_BASED_CTL2_VIRTUAL_INTERRUPT_DELIVERY 0x200
-#define CPU_BASED_CTL2_ENABLE_INVPCID 0x1000
-#define CPU_BASED_CTL2_ENABLE_VMFUNC 0x2000
-#define CPU_BASED_CTL2_ENABLE_XSAVE_XRSTORS 0x100000
-
-/**
- * @brief VM-exit Control Bits
- *
- */
-#define VM_EXIT_SAVE_DEBUG_CONTROLS 0x00000004
-#define VM_EXIT_HOST_ADDR_SPACE_SIZE 0x00000200
-#define VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL 0x00001000
-#define VM_EXIT_ACK_INTR_ON_EXIT 0x00008000
-#define VM_EXIT_SAVE_IA32_PAT 0x00040000
-#define VM_EXIT_LOAD_IA32_PAT 0x00080000
-#define VM_EXIT_SAVE_IA32_EFER 0x00100000
-#define VM_EXIT_LOAD_IA32_EFER 0x00200000
-#define VM_EXIT_SAVE_VMX_PREEMPTION_TIMER 0x00400000
-
-/**
- * @brief VM-entry Control Bits
- *
- */
-#define VM_ENTRY_LOAD_DEBUG_CONTROLS 0x00000004
-#define VM_ENTRY_IA32E_MODE 0x00000200
-#define VM_ENTRY_SMM 0x00000400
-#define VM_ENTRY_DEACT_DUAL_MONITOR 0x00000800
-#define VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL 0x00002000
-#define VM_ENTRY_LOAD_IA32_PAT 0x00004000
-#define VM_ENTRY_LOAD_IA32_EFER 0x00008000
-
/**
* @brief CPUID RCX(s) - Based on Hyper-V
*
@@ -280,6 +205,12 @@ enum HYPERCALL_CODE
HvCallFlushGuestPhysicalAddressList = 0x00B0
};
+/** @brief Hyper-V CPUID leaves
+*/
+#define HYPERV_CPUID_VENDOR_MICROSOFT_EBX 0x7263694d // "Micr"
+#define HYPERV_CPUID_VENDOR_MICROSOFT_ECX 0x666f736f // "osof"
+#define HYPERV_CPUID_VENDOR_MICROSOFT_EDX 0x76482074 // "t Hv"
+
//////////////////////////////////////////////////
// Enums //
//////////////////////////////////////////////////
@@ -300,50 +231,13 @@ typedef enum _MOV_TO_DEBUG_REG
AccessFromDebugRegister = 1,
} MOV_TO_DEBUG_REG;
-//////////////////////////////////////////////////
-// VMX Instructions //
-//////////////////////////////////////////////////
-
-extern inline UCHAR
-VmxVmread64(size_t Field, UINT64 FieldValue);
-
-extern inline UCHAR
-VmxVmread32(size_t Field, UINT32 FieldValue);
-
-extern inline UCHAR
-VmxVmread16(size_t Field, UINT16 FieldValue);
-
-extern inline UCHAR
-VmxVmread64P(size_t Field, UINT64 * FieldValue);
-
-extern inline UCHAR
-VmxVmread32P(size_t Field, UINT32 * FieldValue);
-
-extern inline UCHAR
-VmxVmread16P(size_t Field, UINT16 * FieldValue);
-
-extern inline UCHAR
-VmxVmwrite64(size_t Field, UINT64 FieldValue);
-
-extern inline UCHAR
-VmxVmwrite32(size_t Field, UINT32 FieldValue);
-
-extern inline UCHAR
-VmxVmwrite16(size_t Field, UINT16 FieldValue);
-
-VOID
-VmxVmptrst();
-
-VOID
-VmxVmresume();
-
-VOID
-VmxVmxoff(VIRTUAL_MACHINE_STATE * VCpu);
-
//////////////////////////////////////////////////
// Functions //
//////////////////////////////////////////////////
+BOOLEAN
+VmxIsTopLevelHypervisorHyperV();
+
BOOLEAN
VmxCheckVmxSupport();
@@ -356,24 +250,9 @@ VmxPerformVirtualizationOnAllCores();
BOOLEAN
VmxTerminate();
-VOID
-VmxPerformTermination();
-
-VOID
-VmxHandleXsetbv(VIRTUAL_MACHINE_STATE * VCpu);
-
-VOID
-VmxHandleVmxPreemptionTimerVmexit(VIRTUAL_MACHINE_STATE * VCpu);
-
-VOID
-VmxHandleTripleFaults(VIRTUAL_MACHINE_STATE * VCpu);
-
BOOLEAN
VmxPerformVirtualizationOnSpecificCore();
-VOID
-VmxFixCr4AndCr0Bits();
-
BOOLEAN
VmxLoadVmcs(_In_ VIRTUAL_MACHINE_STATE * VCpu);
@@ -389,6 +268,33 @@ VmxVirtualizeCurrentSystem(PVOID GuestStack);
BOOLEAN
VmxSetupVmcs(_In_ VIRTUAL_MACHINE_STATE * VCpu, _In_ PVOID GuestStack);
+VOID
+VmxPerformVmptrst();
+
+VOID
+VmxPerformVmresume();
+
+VOID
+VmxPerformVmxoff(VIRTUAL_MACHINE_STATE * VCpu);
+
+VOID
+VmxPerformTermination();
+
+VOID
+VmxHandleXsetbv(VIRTUAL_MACHINE_STATE * VCpu);
+
+VOID
+VmxHandleVmxPreemptionTimerVmexit(VIRTUAL_MACHINE_STATE * VCpu);
+
+VOID
+VmxHandleTripleFaults(VIRTUAL_MACHINE_STATE * VCpu);
+
+VOID
+VmxFixCr4AndCr0Bits();
+
+VOID
+VmxCompatibleMicroSleep(UINT64 ns);
+
UINT64
VmxReturnStackPointerForVmxoff();
@@ -405,7 +311,7 @@ UINT32
VmxCompatibleStrlen(const CHAR * S);
UINT32
-VmxCompatibleWcslen(const wchar_t * S);
+VmxCompatibleWcslen(const WCHAR * S);
INT32
VmxCompatibleStrcmp(const CHAR * Address1,
@@ -414,15 +320,12 @@ VmxCompatibleStrcmp(const CHAR * Address1,
BOOLEAN IsStrncmp);
INT32
-VmxCompatibleWcscmp(const wchar_t * Address1,
- const wchar_t * Address2,
- SIZE_T Num,
- BOOLEAN IsWcsncmp);
+VmxCompatibleWcscmp(const WCHAR * Address1,
+ const WCHAR * Address2,
+ SIZE_T Num,
+ BOOLEAN IsWcsncmp);
INT32
VmxCompatibleMemcmp(const CHAR * Address1,
const CHAR * Address2,
- size_t Count);
-
-VOID
-VmxCompatibleMicroSleep(UINT64 ns);
\ No newline at end of file
+ SIZE_T Count);
diff --git a/hyperdbg/hyperhv/hyperhv.vcxproj b/hyperdbg/hyperhv/hyperhv.vcxproj
index 3bed16d4..53c55a14 100644
--- a/hyperdbg/hyperhv/hyperhv.vcxproj
+++ b/hyperdbg/hyperhv/hyperhv.vcxproj
@@ -1,5 +1,8 @@
+
+
+ debug
@@ -28,7 +31,7 @@
WindowsKernelModeDriver10.0DynamicLibraryKMDF
- Universal
+ Desktopfalsefalse
@@ -38,7 +41,7 @@
WindowsKernelModeDriver10.0DynamicLibraryKMDF
- Universal
+ Desktopfalsefalse
@@ -53,13 +56,16 @@
DbgengKernelDebugger
- true
+
+ $(SolutionDir)build\bin\$(Configuration)\$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\
+ falseDbgengKernelDebugger
- true
+
+ $(SolutionDir)build\bin\$(Configuration)\false$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\
@@ -111,7 +117,7 @@
pch.h$(IntDir)$(TargetName).pchNeither
- Disabled
+ FullZYDIS_STATIC_BUILD;ZYCORE_STATIC_BUILD;ZYAN_NO_LIBC;ZYDIS_NO_LIBC;%(PreprocessorDefinitions)stdcpp20
@@ -126,13 +132,16 @@
-
+
-
+
+
+
+
@@ -162,15 +171,16 @@
-
+
+
@@ -229,21 +239,22 @@
-
+
-
-
+
+
+
+
-
@@ -266,15 +277,16 @@
-
+
+
@@ -290,8 +302,21 @@
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/hyperhv/hyperhv.vcxproj.filters b/hyperdbg/hyperhv/hyperhv.vcxproj.filters
index da238598..fbbe5e33 100644
--- a/hyperdbg/hyperhv/hyperhv.vcxproj.filters
+++ b/hyperdbg/hyperhv/hyperhv.vcxproj.filters
@@ -141,6 +141,12 @@
{c310c4a9-c337-454d-94ca-4c6b1216cf41}
+
+ {20e523af-8b6d-4293-bd6d-ce6087f2d4a2}
+
+
+ {58bb81a8-dd12-4e47-b6c8-7d61981fef62}
+
@@ -197,9 +203,6 @@
code\memory
-
- code\memory
- code\components\registers
@@ -299,7 +302,7 @@
code\interface
-
+ code\platform
@@ -314,15 +317,30 @@
code\mmio
-
- code\interface
- code\hooks\syscall-hookcode\interface
+
+ code\processor
+
+
+ code\vmm\vmx
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\components\callback
+
@@ -331,9 +349,6 @@
header\common
-
- header\common
- header\common
@@ -376,9 +391,6 @@
header\memory
-
- header\memory
- header\vmm\vmx
@@ -571,10 +583,7 @@
header\interface
-
- header\platform
-
-
+ header\platform
@@ -592,12 +601,27 @@
header\mmio
-
- header\interface
- header\hooks
+
+ header\processor
+
+
+ header\vmm\vmx
+
+
+ header\platform
+
+
+ header\platform
+
+
+ header\platform
+
+
+ header\components\callback
+
@@ -622,7 +646,10 @@
code\assembly
- code
+ code\assembly
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/hyperhv/packages.config b/hyperdbg/hyperhv/packages.config
new file mode 100644
index 00000000..eb276766
--- /dev/null
+++ b/hyperdbg/hyperhv/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/hyperhv/pch.h b/hyperdbg/hyperhv/pch.h
index 4b05699f..43398529 100644
--- a/hyperdbg/hyperhv/pch.h
+++ b/hyperdbg/hyperhv/pch.h
@@ -27,9 +27,9 @@
//
// Environment headers
//
-#include "platform/kernel/header/Environment.h"
+#include "platform/general/header/Environment.h"
-#ifdef ENV_WINDOWS
+#ifdef HYPERDBG_ENV_WINDOWS
//
// General WDK headers
@@ -39,7 +39,7 @@
# include
# include
-#endif // ENV_WINDOWS
+#endif // HYPERDBG_ENV_WINDOWS
//
// Definition of Intel primitives (External header)
@@ -60,7 +60,10 @@
//
// Platform independent headers
//
-#include "platform/kernel/header/Mem.h"
+#include "platform/kernel/header/PlatformMem.h"
+#include "platform/kernel/header/PlatformIntrinsics.h"
+#include "platform/kernel/header/PlatformBroadcast.h"
+#include "platform/kernel/header/PlatformIntrinsicsVmx.h"
//
// VMM Callbacks
@@ -91,9 +94,7 @@
#include "vmm/vmx/VmxBroadcast.h"
#include "memory/MemoryMapper.h"
#include "interface/Dispatch.h"
-#include "common/Dpc.h"
#include "common/Msr.h"
-#include "memory/PoolManager.h"
#include "common/Trace.h"
#include "assembly/InlineAsm.h"
#include "vmm/ept/Vpid.h"
@@ -107,6 +108,7 @@
#include "vmm/vmx/Events.h"
#include "devices/Apic.h"
#include "devices/Pci.h"
+#include "processor/Smm.h"
#include "processor/Idt.h"
#include "vmm/vmx/Mtf.h"
#include "vmm/vmx/Counters.h"
@@ -114,6 +116,7 @@
#include "vmm/ept/Invept.h"
#include "vmm/vmx/Vmcall.h"
#include "interface/DirectVmcall.h"
+#include "vmm/vmx/CrossVmcalls.h"
#include "vmm/vmx/Hv.h"
#include "vmm/vmx/MsrHandlers.h"
#include "vmm/vmx/ProtectedHv.h"
@@ -172,7 +175,7 @@
//
#include "SDK/modules/HyperLog.h"
#include "SDK/imports/kernel/HyperDbgHyperLogIntrinsics.h"
-#include "components/interface/HyperLogCallback.h"
+#include "components/callback/header/HyperLogCallback.h"
//
// Transparent-mode (hyperevade) headers
diff --git a/hyperdbg/hyperkd/CMakeLists.txt b/hyperdbg/hyperkd/CMakeLists.txt
index 0adcdfbc..2dc81aaf 100644
--- a/hyperdbg/hyperkd/CMakeLists.txt
+++ b/hyperdbg/hyperkd/CMakeLists.txt
@@ -5,7 +5,7 @@ set(SourceFiles
"../include/components/optimizations/code/InsertionSort.c"
"../include/components/optimizations/code/OptimizationsExamples.c"
"../include/components/spinlock/code/Spinlock.c"
- "../include/platform/kernel/code/Mem.c"
+ "../include/platform/kernel/code/PlatformMem.c"
"../script-eval/code/Functions.c"
"../script-eval/code/Keywords.c"
"../script-eval/code/PseudoRegisters.c"
@@ -49,7 +49,7 @@ set(SourceFiles
"../include/components/spinlock/header/Spinlock.h"
"../include/macros/MetaMacros.h"
"../include/platform/kernel/header/Environment.h"
- "../include/platform/kernel/header/Mem.h"
+ "../include/platform/kernel/header/PlatformMem.h"
"header/assembly/Assembly.h"
"header/common/Common.h"
"header/common/Dpc.h"
diff --git a/hyperdbg/hyperkd/code/common/Synchronization.c b/hyperdbg/hyperkd/code/common/Synchronization.c
new file mode 100644
index 00000000..a35b753e
--- /dev/null
+++ b/hyperdbg/hyperkd/code/common/Synchronization.c
@@ -0,0 +1,61 @@
+/**
+ * @file Synchronization.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Routines synchronization objects
+ * @details
+ * @version 0.16
+ * @date 2025-08-30
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief Initialize a waiting event
+ *
+ * @param Event
+ * @return VOID
+ */
+VOID
+SynchronizationInitializeEvent(PRKEVENT Event)
+{
+ //
+ // Initialize an event
+ //
+ KeInitializeEvent(Event, SynchronizationEvent, FALSE);
+}
+
+/**
+ * @brief Set (signal) a waiting event
+ *
+ * @param Event
+ * @return VOID
+ */
+VOID
+SynchronizationSetEvent(PRKEVENT Event)
+{
+ //
+ // Set (signal) an event
+ //
+ KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
+}
+
+/**
+ * @brief Wait for a waiting event
+ *
+ * @param Event
+ * @return VOID
+ */
+VOID
+SynchronizationWaitForEvent(PRKEVENT Event)
+{
+ //
+ // Wait for an event
+ //
+ KeWaitForSingleObject(Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+}
diff --git a/hyperdbg/hyperkd/code/debugger/broadcast/DpcRoutines.c b/hyperdbg/hyperkd/code/debugger/broadcast/DpcRoutines.c
index 5f765241..9296f576 100644
--- a/hyperdbg/hyperkd/code/debugger/broadcast/DpcRoutines.c
+++ b/hyperdbg/hyperkd/code/debugger/broadcast/DpcRoutines.c
@@ -1,4 +1,4 @@
-/**
+/**
* @file DpcRoutines.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief All the dpc routines which relates to executing on a single core
@@ -138,7 +138,7 @@ DpcRoutinePerformWriteMsr(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgumen
//
// write on MSR
//
- __writemsr(CurrentDebuggingState->MsrState.Msr, CurrentDebuggingState->MsrState.Value);
+ CpuWriteMsr((ULONG)CurrentDebuggingState->MsrState.Msr, CurrentDebuggingState->MsrState.Value);
//
// As this function is designed for a single,
@@ -170,7 +170,7 @@ DpcRoutinePerformReadMsr(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument
//
// read on MSR
//
- CurrentDebuggingState->MsrState.Value = __readmsr(CurrentDebuggingState->MsrState.Msr);
+ CurrentDebuggingState->MsrState.Value = CpuReadMsr((ULONG)CurrentDebuggingState->MsrState.Msr);
//
// As this function is designed for a single,
@@ -200,17 +200,12 @@ DpcRoutineWriteMsrToAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgu
//
// write on MSR
//
- __writemsr(CurrentDebuggingState->MsrState.Msr, CurrentDebuggingState->MsrState.Value);
+ CpuWriteMsr((ULONG)CurrentDebuggingState->MsrState.Msr, CurrentDebuggingState->MsrState.Value);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -234,17 +229,12 @@ DpcRoutineReadMsrToAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgum
//
// read msr
//
- CurrentDebuggingState->MsrState.Value = __readmsr(CurrentDebuggingState->MsrState.Msr);
+ CurrentDebuggingState->MsrState.Value = CpuReadMsr((ULONG)CurrentDebuggingState->MsrState.Msr);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
-
- //
- // Mark the DPC as being complete
- //
- KeSignalCallDpcDone(SystemArgument1);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
}
/**
@@ -267,13 +257,36 @@ DpcRoutineVmExitAndHaltSystemAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID S
//
VmFuncVmxVmcall(DEBUGGER_VMCALL_VM_EXIT_HALT_SYSTEM, 0, 0, 0);
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
//
- // Wait for all DPCs to synchronize at this point
- //
- KeSignalCallDpcSynchronize(SystemArgument2);
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
+}
+
+/**
+ * @brief Broadcast applying hardware debug register
+ *
+ * @param Dpc
+ * @param DeferredContext
+ * @param SystemArgument1
+ * @param SystemArgument2
+ * @return BOOLEAN
+ */
+BOOLEAN
+DpcRoutineSetHardwareDebugRegisters(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
+{
+ UNREFERENCED_PARAMETER(Dpc);
+ UNREFERENCED_PARAMETER(DeferredContext);
//
- // Mark the DPC as being complete
+ // Apply hardware debug registers
//
- KeSignalCallDpcDone(SystemArgument1);
+ UdApplyHardwareDebugRegister(DeferredContext);
+
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
+ //
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
+
+ return TRUE;
}
diff --git a/hyperdbg/hyperkd/code/debugger/commands/BreakpointCommands.c b/hyperdbg/hyperkd/code/debugger/commands/BreakpointCommands.c
index c50d1dc7..496e600b 100644
--- a/hyperdbg/hyperkd/code/debugger/commands/BreakpointCommands.c
+++ b/hyperdbg/hyperkd/code/debugger/commands/BreakpointCommands.c
@@ -50,7 +50,7 @@ BreakpointCheckAndPerformActionsOnTrapFlags(UINT32 ProcessId, UINT32 ThreadId, B
Result = BinarySearchPerformSearchItem((UINT64 *)&g_TrapFlagState.ThreadInformation[0],
g_TrapFlagState.NumberOfItems,
&Index,
- ProcThrdInfo.asUInt);
+ ProcThrdInfo.AsUInt);
//
// Indicate whether the trap flag is set by the debugger or not
@@ -195,7 +195,7 @@ BreakpointRestoreTheTrapFlagOnceTriggered(UINT32 ProcessId, UINT32 ThreadId)
Result = BinarySearchPerformSearchItem((UINT64 *)&g_TrapFlagState.ThreadInformation[0],
g_TrapFlagState.NumberOfItems,
&Index,
- ProcThrdInfo.asUInt);
+ ProcThrdInfo.AsUInt);
if (Result)
{
@@ -215,7 +215,7 @@ BreakpointRestoreTheTrapFlagOnceTriggered(UINT32 ProcessId, UINT32 ThreadId)
&g_TrapFlagState.NumberOfItems,
MAXIMUM_NUMBER_OF_THREAD_INFORMATION_FOR_TRAPS,
&Index, // not used
- ProcThrdInfo.asUInt);
+ ProcThrdInfo.AsUInt);
goto Return;
}
@@ -290,9 +290,8 @@ BreakpointCheckAndHandleDebugBreakpoint(UINT32 CoreId)
//
KdHandleDebugEventsWhenKernelDebuggerIsAttached(DbgState, TrapSetByDebugger);
}
- else if (UdHandleInstantBreak(DbgState,
- DEBUGGEE_PAUSING_REASON_DEBUGGEE_GENERAL_DEBUG_BREAK,
- NULL))
+ else if (g_UserDebuggerState == TRUE &&
+ UdHandleDebugEventsWhenUserDebuggerIsAttached(DbgState, TrapSetByDebugger))
{
//
// if the above function returns true, no need for further action
@@ -338,9 +337,8 @@ BreakpointCheckAndHandleDebugBreakpoint(UINT32 CoreId)
//
KdHandleDebugEventsWhenKernelDebuggerIsAttached(DbgState, TrapSetByDebugger);
}
- else if (UdHandleInstantBreak(DbgState,
- DEBUGGEE_PAUSING_REASON_DEBUGGEE_GENERAL_DEBUG_BREAK,
- NULL))
+ else if (g_UserDebuggerState == TRUE &&
+ UdHandleDebugEventsWhenUserDebuggerIsAttached(DbgState, TrapSetByDebugger))
{
//
// if the above function returns true, no need for further action
@@ -434,15 +432,14 @@ BreakpointClearAndDeallocateMemory(PDEBUGGEE_BP_DESCRIPTOR BreakpointDesc)
/**
* @brief Check and reapply breakpoint
*
- * @param CoreId
+ * @param DbgState The state of the debugger on the current core
*
* @return BOOLEAN
*/
BOOLEAN
-BreakpointCheckAndHandleReApplyingBreakpoint(UINT32 CoreId)
+BreakpointCheckAndHandleReApplyingBreakpoint(PROCESSOR_DEBUGGING_STATE * DbgState)
{
- BOOLEAN Result = FALSE;
- PROCESSOR_DEBUGGING_STATE * DbgState = &g_DbgState[CoreId];
+ BOOLEAN Result = FALSE;
if (DbgState->SoftwareBreakpointState != NULL)
{
diff --git a/hyperdbg/hyperkd/code/debugger/commands/Callstack.c b/hyperdbg/hyperkd/code/debugger/commands/Callstack.c
index 14555c2e..6587d5b5 100644
--- a/hyperdbg/hyperkd/code/debugger/commands/Callstack.c
+++ b/hyperdbg/hyperkd/code/debugger/commands/Callstack.c
@@ -59,7 +59,7 @@ CallstackWalkthroughStack(PDEBUGGER_SINGLE_CALLSTACK_FRAME AddressToSaveFrames,
//
// Walkthrough the stack
//
- for (size_t i = 0; i < FrameIndex; i++)
+ for (SIZE_T i = 0; i < FrameIndex; i++)
{
//
// Compute the current stack position address
diff --git a/hyperdbg/hyperkd/code/debugger/commands/DebuggerCommands.c b/hyperdbg/hyperkd/code/debugger/commands/DebuggerCommands.c
index a5ae9e66..940d0946 100644
--- a/hyperdbg/hyperkd/code/debugger/commands/DebuggerCommands.c
+++ b/hyperdbg/hyperkd/code/debugger/commands/DebuggerCommands.c
@@ -12,6 +12,55 @@
*/
#include "pch.h"
+/**
+ * @brief read registers
+ * @param Regs
+ * @param ReadRegisterRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+DebuggerCommandReadRegisters(GUEST_REGS * Regs,
+ PDEBUGGEE_REGISTER_READ_DESCRIPTION ReadRegisterRequest)
+{
+ GUEST_EXTRA_REGISTERS ERegs = {0};
+
+ if (ReadRegisterRequest->RegisterId == DEBUGGEE_SHOW_ALL_REGISTERS)
+ {
+ //
+ // Add General purpose registers
+ //
+ memcpy((PVOID)((CHAR *)ReadRegisterRequest + sizeof(DEBUGGEE_REGISTER_READ_DESCRIPTION)),
+ Regs,
+ sizeof(GUEST_REGS));
+
+ //
+ // Read Extra registers
+ //
+ ERegs.CS = (UINT16)DebuggerGetRegValueWrapper(NULL, REGISTER_CS);
+ ERegs.SS = (UINT16)DebuggerGetRegValueWrapper(NULL, REGISTER_SS);
+ ERegs.DS = (UINT16)DebuggerGetRegValueWrapper(NULL, REGISTER_DS);
+ ERegs.ES = (UINT16)DebuggerGetRegValueWrapper(NULL, REGISTER_ES);
+ ERegs.FS = (UINT16)DebuggerGetRegValueWrapper(NULL, REGISTER_FS);
+ ERegs.GS = (UINT16)DebuggerGetRegValueWrapper(NULL, REGISTER_GS);
+ ERegs.RFLAGS = DebuggerGetRegValueWrapper(NULL, REGISTER_RFLAGS);
+ ERegs.RIP = DebuggerGetRegValueWrapper(NULL, REGISTER_RIP);
+
+ //
+ // copy at the end of ReadRegisterRequest structure
+ //
+ memcpy((PVOID)((CHAR *)ReadRegisterRequest + sizeof(DEBUGGEE_REGISTER_READ_DESCRIPTION) + sizeof(GUEST_REGS)),
+ &ERegs,
+ sizeof(GUEST_EXTRA_REGISTERS));
+ }
+ else
+ {
+ ReadRegisterRequest->Value = DebuggerGetRegValueWrapper(Regs, ReadRegisterRequest->RegisterId);
+ }
+
+ return TRUE;
+}
+
/**
* @brief Read memory for different commands
*
@@ -308,7 +357,7 @@ DebuggerReadOrWriteMsr(PDEBUGGER_READ_AND_WRITE_ON_MSR ReadOrWriteMsrRequest, UI
//
// Means that we should apply it on all cores
//
- for (size_t i = 0; i < ProcessorsCount; i++)
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
g_DbgState[i].MsrState.Msr = ReadOrWriteMsrRequest->Msr;
g_DbgState[i].MsrState.Value = ReadOrWriteMsrRequest->Value;
@@ -362,7 +411,7 @@ DebuggerReadOrWriteMsr(PDEBUGGER_READ_AND_WRITE_ON_MSR ReadOrWriteMsrRequest, UI
//
// Means that we should apply it on all cores
//
- for (size_t i = 0; i < ProcessorsCount; i++)
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
g_DbgState[i].MsrState.Msr = ReadOrWriteMsrRequest->Msr;
}
@@ -376,7 +425,7 @@ DebuggerReadOrWriteMsr(PDEBUGGER_READ_AND_WRITE_ON_MSR ReadOrWriteMsrRequest, UI
// When we reach here, all processors read their shits
// so we have to fill that fucking buffer for user mode
//
- for (size_t i = 0; i < ProcessorsCount; i++)
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
UserBuffer[i] = g_DbgState[i].MsrState.Value;
}
@@ -493,7 +542,7 @@ DebuggerCommandEditMemory(PDEBUGGER_EDIT_MEMORY EditMemRequest)
//
// Edit the memory
//
- for (size_t i = 0; i < EditMemRequest->CountOf64Chunks; i++)
+ for (SIZE_T i = 0; i < EditMemRequest->CountOf64Chunks; i++)
{
DestinationAddress = (PVOID)((UINT64)EditMemRequest->Address + (i * LengthOfEachChunk));
SourceAddress = (PVOID)((UINT64)EditMemRequest + SIZEOF_DEBUGGER_EDIT_MEMORY + (i * sizeof(UINT64)));
@@ -510,7 +559,7 @@ DebuggerCommandEditMemory(PDEBUGGER_EDIT_MEMORY EditMemRequest)
else if (EditMemRequest->MemoryType == EDIT_PHYSICAL_MEMORY)
{
//
- // Check whether the physical addres
+ // Check whether the physical address
//
if (!CheckAddressPhysical(EditMemRequest->Address))
{
@@ -521,7 +570,7 @@ DebuggerCommandEditMemory(PDEBUGGER_EDIT_MEMORY EditMemRequest)
//
// Edit the physical memory
//
- for (size_t i = 0; i < EditMemRequest->CountOf64Chunks; i++)
+ for (SIZE_T i = 0; i < EditMemRequest->CountOf64Chunks; i++)
{
DestinationAddress = (PVOID)((UINT64)EditMemRequest->Address + (i * LengthOfEachChunk));
SourceAddress = (PVOID)((UINT64)EditMemRequest + SIZEOF_DEBUGGER_EDIT_MEMORY + (i * sizeof(UINT64)));
@@ -546,7 +595,7 @@ DebuggerCommandEditMemory(PDEBUGGER_EDIT_MEMORY EditMemRequest)
}
//
- // Set the resutls
+ // Set the results
//
EditMemRequest->Result = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
@@ -610,7 +659,7 @@ DebuggerCommandEditMemoryVmxRoot(PDEBUGGER_EDIT_MEMORY EditMemRequest)
//
// Edit the memory
//
- for (size_t i = 0; i < EditMemRequest->CountOf64Chunks; i++)
+ for (SIZE_T i = 0; i < EditMemRequest->CountOf64Chunks; i++)
{
DestinationAddress = (PVOID)((UINT64)EditMemRequest->Address + (i * LengthOfEachChunk));
SourceAddress = (PVOID)((UINT64)EditMemRequest + SIZEOF_DEBUGGER_EDIT_MEMORY + (i * sizeof(UINT64)));
@@ -627,7 +676,7 @@ DebuggerCommandEditMemoryVmxRoot(PDEBUGGER_EDIT_MEMORY EditMemRequest)
else if (EditMemRequest->MemoryType == EDIT_PHYSICAL_MEMORY)
{
//
- // Check whether the physical addres
+ // Check whether the physical address
//
if (!CheckAddressPhysical(EditMemRequest->Address))
{
@@ -638,7 +687,7 @@ DebuggerCommandEditMemoryVmxRoot(PDEBUGGER_EDIT_MEMORY EditMemRequest)
//
// Edit the physical memory
//
- for (size_t i = 0; i < EditMemRequest->CountOf64Chunks; i++)
+ for (SIZE_T i = 0; i < EditMemRequest->CountOf64Chunks; i++)
{
DestinationAddress = (PVOID)((UINT64)EditMemRequest->Address + (i * LengthOfEachChunk));
SourceAddress = (PVOID)((UINT64)EditMemRequest + SIZEOF_DEBUGGER_EDIT_MEMORY + (i * sizeof(UINT64)));
@@ -656,7 +705,7 @@ DebuggerCommandEditMemoryVmxRoot(PDEBUGGER_EDIT_MEMORY EditMemRequest)
}
//
- // Set the resutls
+ // Set the results
//
EditMemRequest->Result = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
return TRUE;
@@ -756,7 +805,7 @@ PerformSearchAddress(UINT64 * AddressToSaveResults,
//
SourceAddress = (PVOID)((UINT64)SearchMemRequest + SIZEOF_DEBUGGER_SEARCH_MEMORY);
- for (size_t BaseIterator = (size_t)StartAddress; BaseIterator < ((UINT64)EndAddress); BaseIterator += LengthOfEachChunk)
+ for (SIZE_T BaseIterator = (SIZE_T)StartAddress; BaseIterator < ((UINT64)EndAddress); BaseIterator += LengthOfEachChunk)
{
//
// *** Search the memory ***
@@ -795,7 +844,7 @@ PerformSearchAddress(UINT64 * AddressToSaveResults,
// Try to check each element (we don't start from the very first element as
// it checked before )
//
- for (size_t i = LengthOfEachChunk; i < SearchMemRequest->CountOf64Chunks; i++)
+ for (SIZE_T i = LengthOfEachChunk; i < SearchMemRequest->CountOf64Chunks; i++)
{
//
// I know, we have a double check here ;)
@@ -1203,7 +1252,7 @@ DebuggerCommandSearchMemory(PDEBUGGER_SEARCH_MEMORY SearchMemRequest)
// that we used aligned page addresses so the results should be checked to
// see whether the results are between the user's entered addresses or not
//
- for (size_t i = 0; i < MaximumSearchResults; i++)
+ for (SIZE_T i = 0; i < MaximumSearchResults; i++)
{
CurrentValue = SearchResultsStorage[i];
@@ -1455,7 +1504,7 @@ DebuggerCommandPreactivateFunctionality(PDEBUGGER_PREACTIVATE_COMMAND Preactivat
case DEBUGGER_PREACTIVATE_COMMAND_TYPE_MODE:
//
- // Request for allocating the mode mechanism
+ // Request for enabling the mode mechanism
//
ConfigureInitializeExecTrapOnAllProcessors();
diff --git a/hyperdbg/hyperkd/code/debugger/communication/SerialConnection.c b/hyperdbg/hyperkd/code/debugger/communication/SerialConnection.c
index 33adbafe..f7c55d7a 100644
--- a/hyperdbg/hyperkd/code/debugger/communication/SerialConnection.c
+++ b/hyperdbg/hyperkd/code/debugger/communication/SerialConnection.c
@@ -19,7 +19,7 @@
VOID
SerialConnectionTest()
{
- for (size_t i = 0; i < 100; i++)
+ for (SIZE_T i = 0; i < 100; i++)
{
KdHyperDbgTest((UINT16)i);
}
@@ -166,7 +166,7 @@ SerialConnectionSend(CHAR * Buffer, UINT32 Length)
return FALSE;
}
- for (size_t i = 0; i < Length; i++)
+ for (SIZE_T i = 0; i < Length; i++)
{
KdHyperDbgSendByte(Buffer[i], TRUE);
}
@@ -206,7 +206,7 @@ SerialConnectionSendTwoBuffers(CHAR * Buffer1, UINT32 Length1, CHAR * Buffer2, U
//
// Send first buffer
//
- for (size_t i = 0; i < Length1; i++)
+ for (SIZE_T i = 0; i < Length1; i++)
{
KdHyperDbgSendByte(Buffer1[i], TRUE);
}
@@ -214,7 +214,7 @@ SerialConnectionSendTwoBuffers(CHAR * Buffer1, UINT32 Length1, CHAR * Buffer2, U
//
// Send second buffer
//
- for (size_t i = 0; i < Length2; i++)
+ for (SIZE_T i = 0; i < Length2; i++)
{
KdHyperDbgSendByte(Buffer2[i], TRUE);
}
@@ -261,7 +261,7 @@ SerialConnectionSendThreeBuffers(CHAR * Buffer1,
//
// Send first buffer
//
- for (size_t i = 0; i < Length1; i++)
+ for (SIZE_T i = 0; i < Length1; i++)
{
KdHyperDbgSendByte(Buffer1[i], TRUE);
}
@@ -269,7 +269,7 @@ SerialConnectionSendThreeBuffers(CHAR * Buffer1,
//
// Send second buffer
//
- for (size_t i = 0; i < Length2; i++)
+ for (SIZE_T i = 0; i < Length2; i++)
{
KdHyperDbgSendByte(Buffer2[i], TRUE);
}
@@ -277,7 +277,7 @@ SerialConnectionSendThreeBuffers(CHAR * Buffer1,
//
// Send third buffer
//
- for (size_t i = 0; i < Length3; i++)
+ for (SIZE_T i = 0; i < Length3; i++)
{
KdHyperDbgSendByte(Buffer3[i], TRUE);
}
diff --git a/hyperdbg/hyperkd/code/debugger/core/Debugger.c b/hyperdbg/hyperkd/code/debugger/core/Debugger.c
index 6432d1d8..4b7b65ad 100644
--- a/hyperdbg/hyperkd/code/debugger/core/Debugger.c
+++ b/hyperdbg/hyperkd/code/debugger/core/Debugger.c
@@ -47,41 +47,106 @@ DebuggerSetLastError(UINT32 LastError)
}
/**
- * @brief Initialize Debugger Structures and Routines
+ * @brief Initialize script engine global variables and per-core stack buffers
*
* @return BOOLEAN Shows whether the initialization process was successful
* or not
*/
BOOLEAN
-DebuggerInitialize()
+DebuggerInitializeScriptEngine()
{
ULONG ProcessorsCount = KeQueryActiveProcessorCount(0);
PROCESSOR_DEBUGGING_STATE * CurrentDebuggerState = NULL;
//
- // Also allocate the debugging state
+ // Initialize script engines global variables holder
//
- if (!GlobalDebuggingStateAllocateZeroedMemory())
+ if (!g_ScriptGlobalVariables)
{
+ g_ScriptGlobalVariables = PlatformMemAllocateNonPagedPool(MAX_VAR_COUNT * sizeof(UINT64));
+ }
+
+ if (!g_ScriptGlobalVariables)
+ {
+ //
+ // Out of resource, initialization of script engine's global variable holders failed
+ //
return FALSE;
}
//
- // Allocate buffer for saving events
+ // Zero the global variables memory
//
- if (GlobalEventsAllocateZeroedMemory() == FALSE)
- {
- return FALSE;
- }
+ RtlZeroMemory(g_ScriptGlobalVariables, MAX_VAR_COUNT * sizeof(UINT64));
//
- // Set the core's IDs
+ // Initialize the local and temp variables
//
- for (UINT32 i = 0; i < ProcessorsCount; i++)
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
- g_DbgState[i].CoreId = i;
+ CurrentDebuggerState = &g_DbgState[i];
+
+ if (!CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer)
+ {
+ CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer = PlatformMemAllocateNonPagedPool(MAX_STACK_BUFFER_COUNT * sizeof(UINT64));
+ }
+
+ if (!CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer)
+ {
+ //
+ // Out of resource, initialization of script engine's stack buffer holders failed
+ //
+ return FALSE;
+ }
+
+ //
+ // Zero stack buffer memory
+ //
+ RtlZeroMemory(CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer, MAX_STACK_BUFFER_COUNT * sizeof(UINT64));
}
+ return TRUE;
+}
+
+/**
+ * @brief Initialize trap flag state and breakpoint related structures
+ *
+ * @return BOOLEAN Shows whether the initialization process was successful
+ * or not
+ */
+BOOLEAN
+DebuggerInitializeTrapsAndBreakpoints()
+{
+ //
+ // Zero the TRAP FLAG state memory
+ //
+ RtlZeroMemory(&g_TrapFlagState, sizeof(DEBUGGER_TRAP_FLAG_STATE));
+
+ //
+ // Request pages for breakpoint detail
+ //
+ PoolManagerRequestAllocation(sizeof(DEBUGGEE_BP_DESCRIPTOR),
+ MAXIMUM_BREAKPOINTS_WITHOUT_CONTINUE,
+ BREAKPOINT_DEFINITION_STRUCTURE);
+
+ //
+ // Initialize list of breakpoints and breakpoint id
+ //
+ g_MaximumBreakpointId = 0;
+ InitializeListHead(&g_BreakpointsListHead);
+
+ return TRUE;
+}
+
+/**
+ * @brief Initialize VMM operations (events and related operations)
+ *
+ * @return BOOLEAN Shows whether the initialization process was successful
+ * or not
+ */
+BOOLEAN
+DebuggerInitializeVmmOperations()
+{
//
// Initialize lists relating to the debugger events store
//
@@ -111,86 +176,8 @@ DebuggerInitialize()
InitializeListHead(&g_Events->TrapExecutionInstructionTraceEventsHead);
InitializeListHead(&g_Events->ControlRegister3ModifiedEventsHead);
InitializeListHead(&g_Events->ControlRegisterModifiedEventsHead);
+ InitializeListHead(&g_Events->XsetbvInstructionExecutionEventsHead);
- //
- // Enabled Debugger Events
- //
- g_EnableDebuggerEvents = TRUE;
-
- //
- // Set initial state of triggering events for VMCALLs
- //
- VmFuncSetTriggerEventForVmcalls(FALSE);
-
- //
- // Set initial state of triggering events for VMCALLs
- //
- VmFuncSetTriggerEventForCpuids(FALSE);
-
- //
- // Initialize script engines global variables holder
- //
- if (!g_ScriptGlobalVariables)
- {
- g_ScriptGlobalVariables = PlatformMemAllocateNonPagedPool(MAX_VAR_COUNT * sizeof(UINT64));
- }
-
- if (!g_ScriptGlobalVariables)
- {
- //
- // Out of resource, initialization of script engine's global variable holders failed
- //
- return FALSE;
- }
-
- //
- // Zero the global variables memory
- //
- RtlZeroMemory(g_ScriptGlobalVariables, MAX_VAR_COUNT * sizeof(UINT64));
-
- //
- // Zero the TRAP FLAG state memory
- //
- RtlZeroMemory(&g_TrapFlagState, sizeof(DEBUGGER_TRAP_FLAG_STATE));
-
- //
- // Initialize the local and temp variables
- //
- for (size_t i = 0; i < ProcessorsCount; i++)
- {
- CurrentDebuggerState = &g_DbgState[i];
-
- if (!CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer)
- {
- CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer = PlatformMemAllocateNonPagedPool(MAX_STACK_BUFFER_COUNT * sizeof(UINT64));
- }
-
- if (!CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer)
- {
- //
- // Out of resource, initialization of script engine's stack buffer holders failed
- //
- return FALSE;
- }
-
- //
- // Zero stack buffer memory
- //
- RtlZeroMemory(CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer, MAX_STACK_BUFFER_COUNT * sizeof(UINT64));
- }
-
- //
- // Request pages for breakpoint detail
- //
- PoolManagerRequestAllocation(sizeof(DEBUGGEE_BP_DESCRIPTOR),
- MAXIMUM_BREAKPOINTS_WITHOUT_CONTINUE,
- BREAKPOINT_DEFINITION_STRUCTURE);
-
- //
- // Initialize list of breakpoints and breakpoint id
- //
- g_MaximumBreakpointId = 0;
- InitializeListHead(&g_BreakpointsListHead);
//
// Initialize NMI broadcasting mechanism
@@ -198,16 +185,16 @@ DebuggerInitialize()
VmFuncVmxBroadcastInitialize();
//
- // Initialize attaching mechanism,
- // we'll use the functionalities of the attaching in reading modules
- // of user mode applications (other than attaching mechanism itself)
+ // Set initial state of triggering events for VMCALLs
//
- if (!AttachingInitialize())
- {
- return FALSE;
- }
+ VmFuncSetTriggerEventForVmcalls(FALSE);
//
+ // Set initial state of triggering events for CPUIDs
+ //
+ VmFuncSetTriggerEventForCpuids(FALSE);
+
+ //
// Pre-allocate pools for possible EPT hooks
//
ConfigureEptHookReservePreallocatedPoolsForEptHooks(MAXIMUM_NUMBER_OF_INITIAL_PREALLOCATED_EPT_HOOKS);
@@ -221,21 +208,96 @@ DebuggerInitialize()
//
}
+
+ //
+ // Enabled Debugger VMX Events
+ //
+ g_EnableDebuggerVmxEvents = TRUE;
+
return TRUE;
}
/**
- * @brief Uninitialize Debugger Structures and Routines
+ * @brief Initialize Debugger Structures and Routines
*
+ * @return BOOLEAN Shows whether the initialization process was successful
+ * or not
+ */
+BOOLEAN
+DebuggerInitialize()
+{
+ ULONG ProcessorsCount = KeQueryActiveProcessorCount(0);
+
+ //
+ // Also allocate the debugging state
+ //
+ if (!GlobalDebuggingStateAllocateZeroedMemory())
+ {
+ return FALSE;
+ }
+
+ //
+ // Allocate buffer for saving events
+ //
+ if (GlobalEventsAllocateZeroedMemory() == FALSE)
+ {
+ return FALSE;
+ }
+
+ //
+ // Set the core's IDs
+ //
+ for (UINT32 i = 0; i < ProcessorsCount; i++)
+ {
+ g_DbgState[i].CoreId = i;
+ }
+
+ //
+ // Initialize Pool Manager
+ //
+ if (!PoolManagerInitialize())
+ {
+ LogError("Err, could not initialize pool manager");
+ return FALSE;
+ }
+
+ //
+ // Initialize script engine global variables and per-core stack buffers
+ //
+ if (!DebuggerInitializeScriptEngine())
+ {
+ return FALSE;
+ }
+
+ //
+ // Initialize trap flag state and breakpoint related structures
+ //
+ if (!DebuggerInitializeTrapsAndBreakpoints())
+ {
+ return FALSE;
+ }
+
+ //
+ // Initialize attaching mechanism,
+ // we'll use the functionalities of the attaching in reading modules
+ // of user mode applications (other than attaching mechanism itself)
+ //
+ if (!AttachingInitialize())
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Uninitialize Debugger VMM Operations (Events and other related operations)
+ *
+ * @return VOID
*/
VOID
-DebuggerUninitialize()
+DebuggerUninitializeVmmOperations()
{
- ULONG ProcessorsCount;
- PROCESSOR_DEBUGGING_STATE * CurrentDebuggerState = NULL;
-
- ProcessorsCount = KeQueryActiveProcessorCount(0);
-
//
// *** Disable, terminate and clear all the events ***
//
@@ -252,7 +314,7 @@ DebuggerUninitialize()
//
// Disable triggering events
//
- g_EnableDebuggerEvents = FALSE;
+ g_EnableDebuggerVmxEvents = FALSE;
//
// Clear all events (Check if the kernel debugger is enable
@@ -281,6 +343,25 @@ DebuggerUninitialize()
// Uninitialize NMI broadcasting mechanism
//
VmFuncVmxBroadcastUninitialize();
+}
+
+/**
+ * @brief Uninitialize Debugger Structures and Routines
+ *
+ * @return VOID
+ */
+VOID
+DebuggerUninitialize()
+{
+ ULONG ProcessorsCount;
+ PROCESSOR_DEBUGGING_STATE * CurrentDebuggerState = NULL;
+
+ ProcessorsCount = KeQueryActiveProcessorCount(0);
+
+ //
+ // Free the Pool manager
+ //
+ PoolManagerUninitialize();
//
// Free g_Events
@@ -990,7 +1071,7 @@ DebuggerAddActionToEvent(PDEBUGGER_EVENT Event,
//
// Copy the memory of script to our non-paged pool
//
- RtlCopyMemory((void *)Action->ScriptConfiguration.ScriptBuffer, (const void *)InTheCaseOfRunScript->ScriptBuffer, InTheCaseOfRunScript->ScriptLength);
+ RtlCopyMemory((PVOID)Action->ScriptConfiguration.ScriptBuffer, (const PVOID)InTheCaseOfRunScript->ScriptBuffer, InTheCaseOfRunScript->ScriptLength);
//
// Set other fields
@@ -1081,7 +1162,7 @@ DebuggerTriggerEvents(VMM_EVENT_TYPE_ENUM EventType,
//
// Check if triggering debugging actions are allowed or not
//
- if (!g_EnableDebuggerEvents || g_InterceptBreakpointsAndEventsForCommandsInRemoteComputer)
+ if (!g_EnableDebuggerVmxEvents || g_InterceptBreakpointsAndEventsForCommandsInRemoteComputer)
{
//
// Debugger is not enabled
@@ -1146,7 +1227,8 @@ DebuggerTriggerEvents(VMM_EVENT_TYPE_ENUM EventType,
}
//
- // Check event type specific conditions
+ // Check event type specific conditions, if the event is not mentioned
+ // here, it means that it doesn't have any special condition
//
switch (CurrentEvent->EventType)
{
@@ -1389,7 +1471,22 @@ DebuggerTriggerEvents(VMM_EVENT_TYPE_ENUM EventType,
break;
- default:
+ case XSETBV_INSTRUCTION_EXECUTION:
+
+ //
+ // check if XSETBV is what we want or not
+ //
+ if (CurrentEvent->Options.OptionalParam1 != (UINT64)NULL /*FALSE*/ && CurrentEvent->Options.OptionalParam2 != (UINT64)Context)
+ {
+ //
+ // The XCR is not what we want (and the user didn't intend to get all XSETBVs)
+ //
+ continue;
+ }
+
+ break;
+
+ default: // All other events that don't have conditions
break;
}
@@ -1797,7 +1894,7 @@ DebuggerGetEventByTag(UINT64 Tag)
//
// We have to iterate through all events
//
- for (size_t i = 0; i < sizeof(DEBUGGER_CORE_EVENTS) / sizeof(LIST_ENTRY); i++)
+ for (SIZE_T i = 0; i < sizeof(DEBUGGER_CORE_EVENTS) / sizeof(LIST_ENTRY); i++)
{
TempList = (PLIST_ENTRY)((UINT64)(g_Events) + (i * sizeof(LIST_ENTRY)));
TempList2 = TempList;
@@ -1841,7 +1938,7 @@ DebuggerEnableOrDisableAllEvents(BOOLEAN IsEnable)
//
// We have to iterate through all events
//
- for (size_t i = 0; i < sizeof(DEBUGGER_CORE_EVENTS) / sizeof(LIST_ENTRY); i++)
+ for (SIZE_T i = 0; i < sizeof(DEBUGGER_CORE_EVENTS) / sizeof(LIST_ENTRY); i++)
{
TempList = (PLIST_ENTRY)((UINT64)(g_Events) + (i * sizeof(LIST_ENTRY)));
TempList2 = TempList;
@@ -1898,7 +1995,7 @@ DebuggerTerminateAllEvents(BOOLEAN InputFromVmxRoot)
//
// We have to iterate through all events
//
- for (size_t i = 0; i < sizeof(DEBUGGER_CORE_EVENTS) / sizeof(LIST_ENTRY); i++)
+ for (SIZE_T i = 0; i < sizeof(DEBUGGER_CORE_EVENTS) / sizeof(LIST_ENTRY); i++)
{
TempList = (PLIST_ENTRY)((UINT64)(g_Events) + (i * sizeof(LIST_ENTRY)));
TempList2 = TempList;
@@ -1950,7 +2047,7 @@ DebuggerRemoveAllEvents(BOOLEAN PoolManagerAllocatedMemory)
//
// We have to iterate through all events
//
- for (size_t i = 0; i < sizeof(DEBUGGER_CORE_EVENTS) / sizeof(LIST_ENTRY); i++)
+ for (SIZE_T i = 0; i < sizeof(DEBUGGER_CORE_EVENTS) / sizeof(LIST_ENTRY); i++)
{
TempList = (PLIST_ENTRY)((UINT64)(g_Events) + (i * sizeof(LIST_ENTRY)));
TempList2 = TempList;
@@ -2102,6 +2199,9 @@ DebuggerGetEventListByEventType(VMM_EVENT_TYPE_ENUM EventType)
case CONTROL_REGISTER_MODIFIED:
ResultList = &g_Events->ControlRegisterModifiedEventsHead;
break;
+ case XSETBV_INSTRUCTION_EXECUTION:
+ ResultList = &g_Events->XsetbvInstructionExecutionEventsHead;
+ break;
default:
//
@@ -2461,7 +2561,7 @@ DebuggerRemoveEventFromEventList(UINT64 Tag)
//
// We have to iterate through all events
//
- for (size_t i = 0; i < sizeof(DEBUGGER_CORE_EVENTS) / sizeof(LIST_ENTRY); i++)
+ for (SIZE_T i = 0; i < sizeof(DEBUGGER_CORE_EVENTS) / sizeof(LIST_ENTRY); i++)
{
TempList = (PLIST_ENTRY)((UINT64)(g_Events) + (i * sizeof(LIST_ENTRY)));
TempList2 = TempList;
@@ -2513,12 +2613,12 @@ DebuggerRemoveAllActionsFromEvent(PDEBUGGER_EVENT Event, BOOLEAN PoolManagerAllo
//
// Remove all actions
//
- TempList = &Event->ActionsListHead;
- TempList2 = TempList;
+ TempList = Event->ActionsListHead.Flink;
+ TempList2 = &Event->ActionsListHead;
- while (TempList2 != TempList->Flink)
+ while (TempList != TempList2)
{
- TempList = TempList->Flink;
+ PLIST_ENTRY NextList = TempList->Flink;
PDEBUGGER_EVENT_ACTION CurrentAction = CONTAINING_RECORD(TempList, DEBUGGER_EVENT_ACTION, ActionsList);
//
@@ -2545,6 +2645,8 @@ DebuggerRemoveAllActionsFromEvent(PDEBUGGER_EVENT Event, BOOLEAN PoolManagerAllo
// if it's a custom buffer then the buffer
// is appended to the Action
//
+ RemoveEntryList(&CurrentAction->ActionsList);
+
if (PoolManagerAllocatedMemory)
{
PoolManagerFreePool((UINT64)CurrentAction);
@@ -2553,6 +2655,8 @@ DebuggerRemoveAllActionsFromEvent(PDEBUGGER_EVENT Event, BOOLEAN PoolManagerAllo
{
PlatformMemFreePool(CurrentAction);
}
+
+ TempList = NextList;
}
//
// Remember to free the pool
@@ -3005,6 +3109,15 @@ DebuggerApplyEvent(PDEBUGGER_EVENT Event,
break;
}
+ case XSETBV_INSTRUCTION_EXECUTION:
+ {
+ //
+ // Apply the XSETBV instruction execution events
+ //
+ ApplyEventXsetbvExecutionEvent(Event, ResultsToReturn, InputFromVmxRoot);
+
+ break;
+ }
default:
{
//
@@ -3576,6 +3689,16 @@ DebuggerTerminateEvent(UINT64 Tag, BOOLEAN InputFromVmxRoot)
break;
}
+ case XSETBV_INSTRUCTION_EXECUTION:
+ {
+ //
+ // Call XSETBV instruction execution event terminator
+ //
+ TerminateXsetbvExecutionEvent(Event, InputFromVmxRoot);
+ Result = TRUE;
+
+ break;
+ }
default:
LogError("Err, unknown event for termination");
Result = FALSE;
diff --git a/hyperdbg/hyperkd/code/debugger/core/HaltedCore.c b/hyperdbg/hyperkd/code/debugger/core/HaltedCore.c
index 2b0696d7..8cae1122 100644
--- a/hyperdbg/hyperkd/code/debugger/core/HaltedCore.c
+++ b/hyperdbg/hyperkd/code/debugger/core/HaltedCore.c
@@ -443,7 +443,7 @@ HaltedCoreBroadcastTaskAllCores(PROCESSOR_DEBUGGING_STATE * DbgState,
//
if (Synchronize)
{
- for (size_t i = 0; i < ProcessorsCount; i++)
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
if (DbgState->CoreId != i)
{
diff --git a/hyperdbg/hyperkd/code/debugger/events/ApplyEvents.c b/hyperdbg/hyperkd/code/debugger/events/ApplyEvents.c
index 3e8056ea..1fea130a 100644
--- a/hyperdbg/hyperkd/code/debugger/events/ApplyEvents.c
+++ b/hyperdbg/hyperkd/code/debugger/events/ApplyEvents.c
@@ -134,7 +134,7 @@ ApplyEventMonitorEvent(PDEBUGGER_EVENT Event,
// LogInfo("Start address: %llx, end address: %llx", TempStartAddress, TempEndAddress, RemainingSize);
- for (size_t i = 0; i <= PagesBytes; i++)
+ for (SIZE_T i = 0; i <= PagesBytes; i++)
{
if (RemainingSize >= PAGE_SIZE)
{
@@ -1205,15 +1205,6 @@ ApplyEventTrapModeChangeEvent(PDEBUGGER_EVENT Event,
// or not and if it's activated then we can just add the current process
// to the watchlist, otherwise the user needs to preactivate this event
//
-
- //
- // Technically, it's possible to initiate this mechanism at this point
- // but it involves preallocating huge buffers so we prefer not to allocate
- // these amount of buffers by default in HyperDbg as the users might not
- // really use this mechanism and it would be a waste of system resources
- // so, if the user needs to use this mechanism, it can use the 'preactivate'
- // command to first activate this mechanism and then use it
- //
if (VmFuncQueryModeExecTrap())
{
//
@@ -1283,6 +1274,12 @@ ApplyEventCpuidExecutionEvent(PDEBUGGER_EVENT Event,
// their custom optional parameters
//
VmFuncSetTriggerEventForCpuids(TRUE);
+
+ //
+ // Setting an indicator to CPUID EAX index (if any)
+ //
+ Event->Options.OptionalParam1 = Event->InitOptions.OptionalParam1;
+ Event->Options.OptionalParam2 = Event->InitOptions.OptionalParam2;
}
/**
@@ -1313,3 +1310,30 @@ ApplyEventTracingEvent(PDEBUGGER_EVENT Event,
//
Event->Options.OptionalParam1 = Event->InitOptions.OptionalParam1;
}
+
+/**
+ * @brief Applying XSETBV instruction execution events
+ *
+ * @param Event The created event object
+ * @param ResultsToReturn Result buffer that should be returned to
+ * the user-mode
+ * @param InputFromVmxRoot Whether the input comes from VMX root-mode or IOCTL
+ *
+ * @return VOID
+ */
+VOID
+ApplyEventXsetbvExecutionEvent(PDEBUGGER_EVENT Event,
+ PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn,
+ BOOLEAN InputFromVmxRoot)
+{
+ UNREFERENCED_PARAMETER(Event);
+ UNREFERENCED_PARAMETER(ResultsToReturn);
+ UNREFERENCED_PARAMETER(InputFromVmxRoot);
+
+ //
+ // Enable triggering events for XSETBVs. This event doesn't support custom optional
+ // parameter(s) because it's unconditional. Users can use condition(s) to check for
+ // their custom optional parameters
+ //
+ VmFuncSetTriggerEventForXsetbvs(TRUE);
+}
diff --git a/hyperdbg/hyperkd/code/debugger/events/Termination.c b/hyperdbg/hyperkd/code/debugger/events/Termination.c
index af011e41..b6f59de4 100644
--- a/hyperdbg/hyperkd/code/debugger/events/Termination.c
+++ b/hyperdbg/hyperkd/code/debugger/events/Termination.c
@@ -1130,7 +1130,7 @@ TerminateSyscallHookEferEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
//
// For this event we should also check for sysret instructions events too
// because both of them are emulated by a single bit in vmx controls
- // and a MSR so if there is anything in out events list then we can
+ // and an MSR so if there is anything in out events list then we can
// remove all the events
//
if (DebuggerEventListCount(&g_Events->SyscallHooksEferSyscallEventsHead) > 1 ||
@@ -1221,7 +1221,7 @@ TerminateSysretHookEferEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
//
// For this event we should also check for syscall instructions events too
// because both of them are emulated by a single bit in vmx controls
- // and a MSR so if there is anything in out events list then we can
+ // and an MSR so if there is anything in out events list then we can
// remove all the events
//
if (DebuggerEventListCount(&g_Events->SyscallHooksEferSysretEventsHead) > 1 ||
@@ -1580,6 +1580,49 @@ TerminateQueryDebuggerResourceMovToCr3Exiting(UINT32
return FALSE;
}
+/**
+ * @brief Check and modify state of save and load debug controls (DR7 and IA32_DEBUGCTLS)
+ * on exit and entry VM controls
+ *
+ * @param CoreId Core specific resource
+ * @param PassOver The pass over option
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+TerminateQueryDebuggerResourceSaveAndLoadDebugControls(UINT32 CoreId,
+ PROTECTED_HV_RESOURCES_PASSING_OVERS PassOver)
+{
+ UNREFERENCED_PARAMETER(PassOver);
+
+ //
+ // Check if debug register load and save on entry and exit controls are needed for thread interception
+ //
+ if (ThreadQueryDebugRegisterInterceptionStateByCoreId(CoreId))
+ {
+ //
+ // We should ignore it as we want this to interception of thread to work
+ //
+ return TRUE;
+ }
+
+ //
+ // Query the hypertrace project about this controls since there might be using this load and save controls
+ //
+ if (HyperTraceLbrQueryStateOfLbrSaveAndLoadVmExitAndEntryControls(CoreId))
+ {
+ //
+ // We should ignore it since LBR feature of hypertrace is still using it
+ //
+ return TRUE;
+ }
+
+ //
+ // Do not terminate
+ //
+ return FALSE;
+}
+
/**
* @brief Remove single hook from the hooked pages list and invalidate TLB
* @details Should be called from vmx root-mode
@@ -1755,6 +1798,12 @@ TerminateQueryDebuggerResource(UINT32 CoreId,
break;
+ case PROTECTED_HV_RESOURCES_SAVE_AND_LOAD_DEBUG_CONTROLS:
+
+ Result = TerminateQueryDebuggerResourceSaveAndLoadDebugControls(CoreId, PassOver);
+
+ break;
+
default:
Result = FALSE;
@@ -1769,3 +1818,46 @@ TerminateQueryDebuggerResource(UINT32 CoreId,
//
return Result;
}
+
+/**
+ * @brief Termination function for XSETBV Instruction events
+ *
+ * @param Event Target Event Object
+ * @param InputFromVmxRoot Whether the input comes from VMX root-mode or IOCTL
+ *
+ * @return VOID
+ */
+VOID
+TerminateXsetbvExecutionEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
+{
+ UNREFERENCED_PARAMETER(Event);
+ UNREFERENCED_PARAMETER(InputFromVmxRoot);
+
+ if (DebuggerEventListCount(&g_Events->XsetbvInstructionExecutionEventsHead) > 1)
+ {
+ //
+ // There are still other events in the queue (list), we should only remove
+ // this special event (not all events)
+ //
+
+ //
+ // Nothing we can do for this event type, let it work because of other events
+ //
+ return;
+ }
+ else
+ {
+ //
+ // Nothing else is in the list, we have to restore everything to default
+ // as the current event is the only event in the list
+ //
+
+ //
+ // We set the global variable related to the xsetbv to FALSE
+ // so the vm-exit handler, no longer triggers events related
+ // to the xsetbvs (still they cause vm-exits as xsetbv is an
+ // unconditional instruction for vm-exit)
+ //
+ VmFuncSetTriggerEventForXsetbvs(FALSE);
+ }
+}
diff --git a/hyperdbg/hyperkd/code/debugger/kernel-level/Kd.c b/hyperdbg/hyperkd/code/debugger/kernel-level/Kd.c
index 6927da1a..f3f7017b 100644
--- a/hyperdbg/hyperkd/code/debugger/kernel-level/Kd.c
+++ b/hyperdbg/hyperkd/code/debugger/kernel-level/Kd.c
@@ -24,7 +24,7 @@ KdInitializeKernelDebugger()
//
// Allocate DPC routine
//
- // for (size_t i = 0; i < CoreCount; i++)
+ // for (SIZE_T i = 0; i < CoreCount; i++)
// {
// g_DbgState[i].KdDpcObject = PlatformMemAllocateNonPagedPool(sizeof(KDPC));
//
@@ -245,6 +245,24 @@ KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId(UINT32
return Result;
}
+/**
+ * @brief Query to ignore handling mov 2 debug regs exiting
+ * @param CoreId
+ *
+ * @return BOOLEAN whether it's activated or not
+ */
+BOOLEAN
+KdQueryIgnoreHandlingMov2DebugRegs(UINT32 CoreId)
+{
+ //
+ // Handle access to debug registers, if we should not ignore it, it is
+ // because on detecting thread scheduling we ignore the hardware debug
+ // registers modifications
+ //
+ return KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId(CoreId,
+ DEBUGGER_THREAD_PROCESS_TRACING_INTERCEPT_CLOCK_DEBUG_REGISTER_INTERCEPTION);
+}
+
/**
* @brief calculate the checksum of received buffer from debugger
*
@@ -401,6 +419,62 @@ KdLoggingResponsePacketToDebugger(
return Result;
}
+/**
+ * @brief Regular step-over, step one instruction to the debuggee if
+ * there is a call then it jumps the call
+ *
+ * @param LastRip Last RIP register
+ * @param IsNextInstructionACall
+ * @param CallLength
+ *
+ * @return VOID
+ */
+VOID
+KdRegularStepOver(UINT64 LastRip, BOOLEAN IsNextInstructionACall, UINT32 CallLength)
+{
+ UINT64 NextAddressForHardwareDebugBp = 0;
+ ULONG ProcessorsCount;
+
+ // LogInfo("Last Rip: %llx, IsNextInstructionACall: %s, Call length: %x",
+ // LastRip,
+ // IsNextInstructionACall ? "true" : "false",
+ // CallLength);
+
+ if (IsNextInstructionACall)
+ {
+ //
+ // It's a call, we should put a hardware debug register breakpoint
+ // on the next instruction
+ //
+ NextAddressForHardwareDebugBp = LastRip + CallLength;
+
+ ProcessorsCount = KeQueryActiveProcessorCount(0);
+
+ //
+ // Store the detail of the hardware debug register to avoid trigger
+ // in other processes
+ //
+ g_HardwareDebugRegisterDetailsForStepOver.Address = NextAddressForHardwareDebugBp;
+ g_HardwareDebugRegisterDetailsForStepOver.ProcessId = HANDLE_TO_UINT32(PsGetCurrentProcessId());
+ g_HardwareDebugRegisterDetailsForStepOver.ThreadId = HANDLE_TO_UINT32(PsGetCurrentThreadId());
+
+ //
+ // Add hardware debug breakpoints on all core on vm-entry
+ //
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
+ {
+ g_DbgState[i].HardwareDebugRegisterForStepping = NextAddressForHardwareDebugBp;
+ }
+ }
+ else
+ {
+ //
+ // Any instruction other than call (regular step)
+ //
+ TracingRegularStepInInstruction();
+ }
+}
+
/**
* @brief Handles debug events when kernel-debugger is attached
*
@@ -587,7 +661,7 @@ KdContinueDebuggee(PROCESSOR_DEBUGGING_STATE * DbgState,
// Unlock all the cores
//
ULONG ProcessorsCount = KeQueryActiveProcessorCount(0);
- for (size_t i = 0; i < ProcessorsCount; i++)
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
SpinlockUnlock(&g_DbgState[i].Lock);
}
@@ -614,104 +688,6 @@ KdContinueDebuggeeJustCurrentCore(PROCESSOR_DEBUGGING_STATE * DbgState)
SpinlockUnlock(&DbgState->Lock);
}
-/**
- * @brief read registers
- * @param DbgState The state of the debugger on the current core
- * @param ReadRegisterRequest
- *
- * @return BOOLEAN
- */
-_Use_decl_annotations_
-BOOLEAN
-KdReadRegisters(PROCESSOR_DEBUGGING_STATE * DbgState, PDEBUGGEE_REGISTER_READ_DESCRIPTION ReadRegisterRequest)
-{
- GUEST_EXTRA_REGISTERS ERegs = {0};
-
- if (ReadRegisterRequest->RegisterId == DEBUGGEE_SHOW_ALL_REGISTERS)
- {
- //
- // Add General purpose registers
- //
- memcpy((void *)((CHAR *)ReadRegisterRequest + sizeof(DEBUGGEE_REGISTER_READ_DESCRIPTION)),
- DbgState->Regs,
- sizeof(GUEST_REGS));
-
- //
- // Read Extra registers
- //
- ERegs.CS = (UINT16)DebuggerGetRegValueWrapper(NULL, REGISTER_CS);
- ERegs.SS = (UINT16)DebuggerGetRegValueWrapper(NULL, REGISTER_SS);
- ERegs.DS = (UINT16)DebuggerGetRegValueWrapper(NULL, REGISTER_DS);
- ERegs.ES = (UINT16)DebuggerGetRegValueWrapper(NULL, REGISTER_ES);
- ERegs.FS = (UINT16)DebuggerGetRegValueWrapper(NULL, REGISTER_FS);
- ERegs.GS = (UINT16)DebuggerGetRegValueWrapper(NULL, REGISTER_GS);
- ERegs.RFLAGS = DebuggerGetRegValueWrapper(NULL, REGISTER_RFLAGS);
- ERegs.RIP = DebuggerGetRegValueWrapper(NULL, REGISTER_RIP);
-
- //
- // copy at the end of ReadRegisterRequest structure
- //
- memcpy((void *)((CHAR *)ReadRegisterRequest + sizeof(DEBUGGEE_REGISTER_READ_DESCRIPTION) + sizeof(GUEST_REGS)),
- &ERegs,
- sizeof(GUEST_EXTRA_REGISTERS));
- }
- else
- {
- ReadRegisterRequest->Value = DebuggerGetRegValueWrapper(DbgState->Regs, ReadRegisterRequest->RegisterId);
- }
-
- return TRUE;
-}
-
-/**
- * @brief read registers
- * @param Regs
- * @param ReadRegisterRequest
- *
- * @return BOOLEAN
- */
-_Use_decl_annotations_
-BOOLEAN
-KdReadMemory(PGUEST_REGS Regs, PDEBUGGEE_REGISTER_READ_DESCRIPTION ReadRegisterRequest)
-{
- GUEST_EXTRA_REGISTERS ERegs = {0};
-
- if (ReadRegisterRequest->RegisterId == DEBUGGEE_SHOW_ALL_REGISTERS)
- {
- //
- // Add General purpose registers
- //
- memcpy((void *)((CHAR *)ReadRegisterRequest + sizeof(DEBUGGEE_REGISTER_READ_DESCRIPTION)),
- Regs,
- sizeof(GUEST_REGS));
-
- //
- // Read Extra registers
- //
- ERegs.CS = (UINT16)DebuggerGetRegValueWrapper(NULL, REGISTER_CS);
- ERegs.SS = (UINT16)DebuggerGetRegValueWrapper(NULL, REGISTER_SS);
- ERegs.DS = (UINT16)DebuggerGetRegValueWrapper(NULL, REGISTER_DS);
- ERegs.ES = (UINT16)DebuggerGetRegValueWrapper(NULL, REGISTER_ES);
- ERegs.FS = (UINT16)DebuggerGetRegValueWrapper(NULL, REGISTER_FS);
- ERegs.GS = (UINT16)DebuggerGetRegValueWrapper(NULL, REGISTER_GS);
- ERegs.RFLAGS = DebuggerGetRegValueWrapper(NULL, REGISTER_RFLAGS);
- ERegs.RIP = DebuggerGetRegValueWrapper(NULL, REGISTER_RIP);
-
- //
- // copy at the end of ReadRegisterRequest structure
- //
- memcpy((void *)((CHAR *)ReadRegisterRequest + sizeof(DEBUGGEE_REGISTER_READ_DESCRIPTION) + sizeof(GUEST_REGS)),
- &ERegs,
- sizeof(GUEST_EXTRA_REGISTERS));
- }
- else
- {
- ReadRegisterRequest->Value = DebuggerGetRegValueWrapper(Regs, ReadRegisterRequest->RegisterId);
- }
-
- return TRUE;
-}
-
/**
* @brief change the current operating core to new core
*
@@ -878,7 +854,7 @@ KdNotifyDebuggeeForUserInput(DEBUGGEE_USER_INPUT_PACKET * Descriptor, UINT32 Len
}
/**
- * @brief Notify user-mode to unload the debuggee and close the connections
+ * @brief Send the result of formats command to the kernel debugger
* @param Value
*
* @return VOID
@@ -972,14 +948,14 @@ KdHandleHaltsWhenNmiReceivedFromVmxRoot(PROCESSOR_DEBUGGING_STATE * DbgState)
* @brief Tries to get the lock and won't return until successfully get the lock
*
* @param DbgState The state of the debugger on the current core
- * @param LONG Lock variable
+ * @param Lock The lock variable
*
* @return VOID
*/
VOID
KdCustomDebuggerBreakSpinlockLock(PROCESSOR_DEBUGGING_STATE * DbgState, volatile LONG * Lock)
{
- unsigned wait = 1;
+ UINT32 Wait = 1;
//
// *** Lock handling breaks ***
@@ -987,9 +963,9 @@ KdCustomDebuggerBreakSpinlockLock(PROCESSOR_DEBUGGING_STATE * DbgState, volatile
while (!SpinlockTryLock(Lock))
{
- for (unsigned i = 0; i < wait; ++i)
+ for (UINT32 i = 0; i < Wait; ++i)
{
- _mm_pause();
+ CpuPause();
}
//
@@ -1026,13 +1002,13 @@ KdCustomDebuggerBreakSpinlockLock(PROCESSOR_DEBUGGING_STATE * DbgState, volatile
// clamp it to the MaxWait.
//
- if (wait * 2 > 65536)
+ if (Wait * 2 > 65536)
{
- wait = 65536;
+ Wait = 65536;
}
else
{
- wait = wait * 2;
+ Wait = Wait * 2;
}
}
}
@@ -1118,19 +1094,57 @@ KdHandleBreakpointAndDebugBreakpointsCallback(UINT32
}
/**
- * @brief Handle #DBs and #BPs for kernel debugger
- * @details This function can be used in vmx-root
+ * @brief Handle NMI state for MTF
+ * @param DbgState The state of the debugger on the current core
*
- * @param CoreId
+ * @details This function should be called in vmx-root mode
+ * @return BOOLEAN
+ */
+BOOLEAN
+KdCheckAndHandleNmiStateForMtf(PROCESSOR_DEBUGGING_STATE * DbgState)
+{
+ BOOLEAN Result = FALSE;
+
+ if (DbgState->NmiState.WaitingToBeLocked)
+ {
+ //
+ // The NMI wait is handled here
+ //
+ Result = TRUE;
+
+ //
+ // Handle break of the core
+ //
+ if (DbgState->NmiState.NmiCalledInVmxRootRelatedToHaltDebuggee)
+ {
+ //
+ // Handle it like an NMI is received from VMX root
+ //
+ KdHandleHaltsWhenNmiReceivedFromVmxRoot(DbgState);
+ }
+ else
+ {
+ //
+ // Handle halt of the current core as an NMI
+ //
+ KdHandleNmi(DbgState);
+ }
+ }
+
+ return Result;
+}
+
+/**
+ * @brief Handle instrumentation step-in for kernel debugger
+ * @details This function will be called from vmx-root mode
+ *
+ * @param DbgState The state of the debugger on the current core
*
* @return VOID
*/
-_Use_decl_annotations_
VOID
-KdHandleRegisteredMtfCallback(UINT32 CoreId)
+KdHandleInstrumentationStepIn(PROCESSOR_DEBUGGING_STATE * DbgState)
{
- PROCESSOR_DEBUGGING_STATE * DbgState = &g_DbgState[CoreId];
-
//
// Check for tracing instructions
//
@@ -1149,7 +1163,7 @@ KdHandleRegisteredMtfCallback(UINT32 CoreId)
//
UINT64 CsSel = NULL64_ZERO;
DEBUGGER_TRIGGERED_EVENT_DETAILS TargetContext = {0};
- UINT64 LastVmexitRip = VmFuncGetLastVmexitRip(CoreId);
+ UINT64 LastVmexitRip = VmFuncGetLastVmexitRip(DbgState->CoreId);
//
// Check if the cs selector changed or not, which indicates that the
@@ -1186,6 +1200,82 @@ KdHandleRegisteredMtfCallback(UINT32 CoreId)
}
}
+/**
+ * @brief Handle Monitor Trap Flag (MTF) callback for kernel debugger
+ * @details This function will be called from vmx-root mode
+ *
+ * @param CoreId
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+KdHandleMtfCallback(UINT32 CoreId)
+{
+ PROCESSOR_DEBUGGING_STATE * DbgState = &g_DbgState[CoreId];
+ BOOLEAN IsMtfHandled = FALSE;
+
+ //
+ // *** Check if we need to re-apply a breakpoint or not
+ // We check it separately because the guest might step
+ // instructions on an MTF so we want to check for the step too ***
+ //
+ if (BreakpointCheckAndHandleReApplyingBreakpoint(DbgState))
+ {
+ //
+ // Check for re-enabling external interrupts
+ //
+ VmFuncEnableAndCheckForPreviousExternalInterrupts(DbgState->CoreId);
+
+ //
+ // MTF is handled
+ //
+ IsMtfHandled = TRUE;
+ }
+
+ //
+ // *** Check for instrumentation step-in ***
+ //
+ if (VmFuncQueryInstrumentationStepInState(DbgState->CoreId))
+ {
+ //
+ // Unset the MTF instrumentation state (might be changed in the caller)
+ //
+ VmFuncUnsetInstrumentationStepInState(DbgState->CoreId);
+
+ //
+ // Handle MTF in the debugger
+ //
+ KdHandleInstrumentationStepIn(DbgState);
+
+ //
+ // MTF is handled
+ //
+ IsMtfHandled = TRUE;
+ }
+
+ //
+ // check the condition of passing the execution to NMIs
+ //
+ // This one wastes one week of my life!
+ // During the testing we realized the !epthook command in Debugger Mode
+ // is not working. After some tests, it's because if in the middle of a
+ // command in vmx-root and NMI is sent and the debugger waits for another
+ // MTF, we'll ignore that MTF and a new MTF is not set again.
+ // That's why we moved this check here so every command that needs a task
+ // from MTF is doing its tasks and when we reached here, the check for halting
+ // the debuggee in MTF is performed
+ //
+ else if (KdCheckAndHandleNmiStateForMtf(DbgState))
+ {
+ //
+ // MTF is handled
+ //
+ IsMtfHandled = TRUE;
+ }
+
+ return IsMtfHandled;
+}
+
/**
* @brief Handle #DBs and #BPs for kernel debugger
* @details This function can be used in vmx-root
@@ -1297,49 +1387,6 @@ KdHandleBreakpointAndDebugBreakpoints(PROCESSOR_DEBUGGING_STATE * DbgState
}
}
-/**
- * @brief Handle NMI vm-exits
- * @param CoreId
- *
- * @details This function should be called in vmx-root mode
- * @return BOOLEAN
- */
-_Use_decl_annotations_
-BOOLEAN
-KdCheckAndHandleNmiCallback(UINT32 CoreId)
-{
- BOOLEAN Result = FALSE;
- PROCESSOR_DEBUGGING_STATE * DbgState = &g_DbgState[CoreId];
-
- if (DbgState->NmiState.WaitingToBeLocked)
- {
- //
- // The NMI wait is handled here
- //
- Result = TRUE;
-
- //
- // Handle break of the core
- //
- if (DbgState->NmiState.NmiCalledInVmxRootRelatedToHaltDebuggee)
- {
- //
- // Handle it like an NMI is received from VMX root
- //
- KdHandleHaltsWhenNmiReceivedFromVmxRoot(DbgState);
- }
- else
- {
- //
- // Handle halt of the current core as an NMI
- //
- KdHandleNmi(DbgState);
- }
- }
-
- return Result;
-}
-
/**
* @brief Handle NMI Vm-exits
* @param DbgState The state of the debugger on the current core
@@ -1407,9 +1454,9 @@ KdGuaranteedStepInstruction(PROCESSOR_DEBUGGING_STATE * DbgState)
DbgState->InstrumentationStepInTrace.CsSel = (UINT16)CsSel;
//
- // Set an indicator of a break in the case of an MTF
+ // Set an indicator of instrumentation step-in MTF
//
- VmFuncRegisterMtfBreak(DbgState->CoreId);
+ VmFuncSetInstrumentationStepInState(DbgState->CoreId);
//
// Not unset MTF again
@@ -1492,74 +1539,6 @@ KdCheckGuestOperatingModeChanges(UINT16 PreviousCsSelector, UINT16 CurrentCsSele
return TRUE;
}
-/**
- * @brief Regular step-in | step one instruction to the debuggee
- * @param DbgState The state of the debugger on the current core
- *
- * @return VOID
- */
-VOID
-KdRegularStepInInstruction(PROCESSOR_DEBUGGING_STATE * DbgState)
-{
- TracingPerformRegularStepInInstruction(DbgState);
-
- //
- // Unset the trap flag on the next VM-exit
- //
- BreakpointRestoreTheTrapFlagOnceTriggered(HANDLE_TO_UINT32(PsGetCurrentProcessId()), HANDLE_TO_UINT32(PsGetCurrentThreadId()));
-}
-
-/**
- * @brief Regular step-over | step one instruction to the debuggee if
- * there is a call then it jumps the call
- *
- * @param DbgState The state of the debugger on the current core
- * @param IsNextInstructionACall
- * @param CallLength
- *
- * @return VOID
- */
-VOID
-KdRegularStepOver(PROCESSOR_DEBUGGING_STATE * DbgState, BOOLEAN IsNextInstructionACall, UINT32 CallLength)
-{
- UINT64 NextAddressForHardwareDebugBp = 0;
- ULONG ProcessorsCount;
-
- if (IsNextInstructionACall)
- {
- //
- // It's a call, we should put a hardware debug register breakpoint
- // on the next instruction
- //
- NextAddressForHardwareDebugBp = VmFuncGetLastVmexitRip(DbgState->CoreId) + CallLength;
-
- ProcessorsCount = KeQueryActiveProcessorCount(0);
-
- //
- // Store the detail of the hardware debug register to avoid trigger
- // in other processes
- //
- g_HardwareDebugRegisterDetailsForStepOver.Address = NextAddressForHardwareDebugBp;
- g_HardwareDebugRegisterDetailsForStepOver.ProcessId = HANDLE_TO_UINT32(PsGetCurrentProcessId());
- g_HardwareDebugRegisterDetailsForStepOver.ThreadId = HANDLE_TO_UINT32(PsGetCurrentThreadId());
-
- //
- // Add hardware debug breakpoints on all core on vm-entry
- //
- for (size_t i = 0; i < ProcessorsCount; i++)
- {
- g_DbgState[i].HardwareDebugRegisterForStepping = NextAddressForHardwareDebugBp;
- }
- }
- else
- {
- //
- // Any instruction other than call (regular step)
- //
- KdRegularStepInInstruction(DbgState);
- }
-}
-
/**
* @brief Send event registration buffer to user-mode to register the event
* @param EventDetailHeader
@@ -1670,7 +1649,7 @@ KdQueryRflagTrapState()
g_TrapFlagState.NumberOfItems,
g_TrapFlagState.NumberOfItems);
- for (size_t i = 0; i < MAXIMUM_NUMBER_OF_THREAD_INFORMATION_FOR_TRAPS; i++)
+ for (SIZE_T i = 0; i < MAXIMUM_NUMBER_OF_THREAD_INFORMATION_FOR_TRAPS; i++)
{
LogInfo("g_TrapFlagState.ThreadInformation[%d].ProcessId = %x | ThreadId = %x",
i,
@@ -1694,7 +1673,7 @@ KdCheckAllCoresAreLocked()
//
// Query core debugging Lock info
//
- for (size_t i = 0; i < ProcessorsCount; i++)
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
if (!SpinlockCheckLock(&g_DbgState[i].Lock))
{
@@ -1757,7 +1736,7 @@ KdQuerySystemState()
//
Log("================================================ Debugging Lock Info ================================================\n");
- for (size_t i = 0; i < ProcessorsCount; i++)
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
if (SpinlockCheckLock(&g_DbgState[i].Lock))
{
@@ -1775,7 +1754,7 @@ KdQuerySystemState()
//
Log("\n================================================ NMI Receiver State =======+=========================================\n");
- for (size_t i = 0; i < ProcessorsCount; i++)
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
if (g_DbgState[i].NmiState.NmiCalledInVmxRootRelatedToHaltDebuggee)
{
@@ -2295,6 +2274,9 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState)
PDEBUGGER_SEARCH_MEMORY SearchQueryPacket;
PDEBUGGEE_BP_PACKET BpPacket;
PDEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS PtePacket;
+ PSMI_OPERATION_PACKETS SmiOperationPacket;
+ PHYPERTRACE_LBR_DUMP_PACKETS HyperTraceLbrdumpPacket;
+ PHYPERTRACE_PT_OPERATION_PACKETS HyperTracePtOperationPacket;
PDEBUGGER_APIC_REQUEST ApicPacket;
PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS IdtEntryPacket;
PDEBUGGER_PAGE_IN_REQUEST PageinPacket;
@@ -2422,7 +2404,10 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState)
//
// Step-over (p command)
//
- KdRegularStepOver(DbgState, SteppingPacket->IsCurrentInstructionACall, SteppingPacket->CallLength);
+ KdRegularStepOver(
+ VmFuncGetLastVmexitRip(DbgState->CoreId),
+ SteppingPacket->IsCurrentInstructionACall,
+ SteppingPacket->CallLength);
//
// Unlock other cores
@@ -2448,9 +2433,9 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState)
//
//
- // Indicate a step
+ // Indicate a step-in
//
- KdRegularStepInInstruction(DbgState);
+ TracingRegularStepInInstruction();
//
// Unlock other cores
@@ -2613,7 +2598,7 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState)
//
// Read registers
//
- if (KdReadRegisters(DbgState, ReadRegisterPacket))
+ if (DebuggerCommandReadRegisters(DbgState->Regs, ReadRegisterPacket))
{
ReadRegisterPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
}
@@ -2988,6 +2973,63 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState)
break;
+ case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_PERFORM_SMI_OPERATION:
+
+ SmiOperationPacket = (SMI_OPERATION_PACKETS *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
+
+ //
+ // Perform the SMI operations (it's in vmx-root)
+ //
+ VmFuncSmmPerformSmiOperation(SmiOperationPacket, TRUE);
+
+ //
+ // Send the result of the '!smi' back to the debuggee
+ //
+ KdResponsePacketToDebugger(DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGEE_TO_DEBUGGER,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_SMI_OPERATION_REQUESTS,
+ (CHAR *)SmiOperationPacket,
+ SIZEOF_SMI_OPERATION_PACKETS);
+
+ break;
+
+ case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_PERFORM_HYPERTRACE_LBR_DUMP:
+
+ HyperTraceLbrdumpPacket = (HYPERTRACE_LBR_DUMP_PACKETS *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
+
+ //
+ // Perform the HyperTrace LBR dump (it's in vmx-root)
+ //
+ HyperTraceLbrPerformDump(HyperTraceLbrdumpPacket);
+
+ //
+ // Send the result of the HyperTrace LBR dump back to the debuggee
+ //
+ KdResponsePacketToDebugger(DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGEE_TO_DEBUGGER,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_HYPERTRACE_LBR_DUMP_REQUESTS,
+ (CHAR *)HyperTraceLbrdumpPacket,
+ SIZEOF_HYPERTRACE_LBR_DUMP_PACKETS);
+
+ break;
+
+ case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_PERFORM_HYPERTRACE_PT_OPERATION:
+
+ HyperTracePtOperationPacket = (HYPERTRACE_PT_OPERATION_PACKETS *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
+
+ //
+ // Perform the HyperTrace PT operations (it's in vmx-root)
+ //
+ HyperTracePtPerformOperation(HyperTracePtOperationPacket);
+
+ //
+ // Send the result of the HyperTrace PT back to the debuggee
+ //
+ KdResponsePacketToDebugger(DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGEE_TO_DEBUGGER,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_HYPERTRACE_PT_OPERATION_REQUESTS,
+ (CHAR *)HyperTracePtOperationPacket,
+ SIZEOF_HYPERTRACE_PT_OPERATION_PACKETS);
+
+ break;
+
case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_PERFORM_ACTIONS_ON_APIC:
ApicPacket = (DEBUGGER_APIC_REQUEST *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
diff --git a/hyperdbg/hyperhv/code/memory/PoolManager.c b/hyperdbg/hyperkd/code/debugger/memory/PoolManager.c
similarity index 88%
rename from hyperdbg/hyperhv/code/memory/PoolManager.c
rename to hyperdbg/hyperkd/code/debugger/memory/PoolManager.c
index d5c5b01e..3c195e68 100644
--- a/hyperdbg/hyperhv/code/memory/PoolManager.c
+++ b/hyperdbg/hyperkd/code/debugger/memory/PoolManager.c
@@ -68,9 +68,15 @@ PoolManagerInitialize()
InitializeListHead(&g_ListOfAllocatedPoolsHead);
//
- // Nothing to deallocate
+ // Nothing to deallocate or allocate at the beginning
//
- g_IsNewRequestForDeAllocation = FALSE;
+ g_IsNewRequestForDeAllocation = FALSE;
+ g_IsNewRequestForAllocationReceived = FALSE;
+
+ //
+ // Memory allocator is initialized
+ //
+ g_PoolManagerInitialized = TRUE;
//
// Initialized successfully
@@ -86,19 +92,25 @@ PoolManagerInitialize()
VOID
PoolManagerUninitialize()
{
- PLIST_ENTRY ListTemp = 0;
- ListTemp = &g_ListOfAllocatedPoolsHead;
+ PLIST_ENTRY Link;
+
+ //
+ // Pool manager is not initialized anymore
+ //
+ g_PoolManagerInitialized = FALSE;
SpinlockLock(&LockForReadingPool);
- while (&g_ListOfAllocatedPoolsHead != ListTemp->Flink)
+ Link = g_ListOfAllocatedPoolsHead.Flink;
+
+ while (Link != &g_ListOfAllocatedPoolsHead)
{
- ListTemp = ListTemp->Flink;
+ PLIST_ENTRY Next = Link->Flink;
//
// Get the head of the record
//
- PPOOL_TABLE PoolTable = (PPOOL_TABLE)CONTAINING_RECORD(ListTemp, POOL_TABLE, PoolsList);
+ PPOOL_TABLE PoolTable = (PPOOL_TABLE)CONTAINING_RECORD(Link, POOL_TABLE, PoolsList);
//
// Free the alloocated buffer (if not already changed)
@@ -111,14 +123,20 @@ PoolManagerUninitialize()
//
// Unlink the PoolTable
//
- RemoveEntryList(&PoolTable->PoolsList);
+ RemoveEntryList(Link);
//
// Free the record itself
//
PlatformMemFreePool(PoolTable);
+
+ Link = Next;
}
+ InitializeListHead(&g_ListOfAllocatedPoolsHead);
+ g_IsNewRequestForDeAllocation = FALSE;
+ g_IsNewRequestForAllocationReceived = FALSE;
+
SpinlockUnlock(&LockForReadingPool);
PlmgrFreeRequestNewAllocation();
@@ -252,7 +270,7 @@ PoolManagerRequestPool(POOL_ALLOCATION_INTENTION Intention, BOOLEAN RequestNewPo
BOOLEAN
PoolManagerAllocateAndAddToPoolTable(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention)
{
- for (size_t i = 0; i < Count; i++)
+ for (SIZE_T i = 0; i < Count; i++)
{
POOL_TABLE * SinglePool = NULL;
@@ -301,16 +319,17 @@ PoolManagerAllocateAndAddToPoolTable(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_
BOOLEAN
PoolManagerCheckAndPerformAllocationAndDeallocation()
{
- BOOLEAN Result = TRUE;
- PLIST_ENTRY ListTemp = 0;
+ BOOLEAN Result = TRUE;
//
- // let's make sure we're on vmx non-root and also we have new allocation
+ // Make sure we're on vmx non-root and also we have new allocation
+ // and also pool manager is initialized, otherwise we shouldn't allocate or deallocate
//
- if (VmxGetCurrentExecutionMode() == TRUE)
+ if (!g_PoolManagerInitialized || VmFuncVmxGetCurrentExecutionMode() == TRUE)
{
//
// allocation's can't be done from vmx root
+ // or pool manager is not initialized yet
//
return FALSE;
}
@@ -320,6 +339,8 @@ PoolManagerCheckAndPerformAllocationAndDeallocation()
//
PAGED_CODE();
+ SpinlockLock(&LockForReadingPool);
+
//
// Check for new allocation
//
@@ -350,18 +371,16 @@ PoolManagerCheckAndPerformAllocationAndDeallocation()
//
if (g_IsNewRequestForDeAllocation)
{
- ListTemp = &g_ListOfAllocatedPoolsHead;
+ PLIST_ENTRY Link = g_ListOfAllocatedPoolsHead.Flink;
- SpinlockLock(&LockForReadingPool);
-
- while (&g_ListOfAllocatedPoolsHead != ListTemp->Flink)
+ while (Link != &g_ListOfAllocatedPoolsHead)
{
- ListTemp = ListTemp->Flink;
+ PLIST_ENTRY Next = Link->Flink;
//
// Get the head of the record
//
- PPOOL_TABLE PoolTable = (PPOOL_TABLE)CONTAINING_RECORD(ListTemp, POOL_TABLE, PoolsList);
+ PPOOL_TABLE PoolTable = (PPOOL_TABLE)CONTAINING_RECORD(Link, POOL_TABLE, PoolsList);
//
// Check whether this pool should be freed or not and
@@ -382,16 +401,16 @@ PoolManagerCheckAndPerformAllocationAndDeallocation()
//
// Now we should remove the entry from the g_ListOfAllocatedPoolsHead
//
- RemoveEntryList(&PoolTable->PoolsList);
+ RemoveEntryList(Link);
//
// Free the structure pool
//
PlatformMemFreePool(PoolTable);
}
- }
- SpinlockUnlock(&LockForReadingPool);
+ Link = Next;
+ }
}
//
@@ -400,6 +419,8 @@ PoolManagerCheckAndPerformAllocationAndDeallocation()
g_IsNewRequestForDeAllocation = FALSE;
g_IsNewRequestForAllocationReceived = FALSE;
+ SpinlockUnlock(&LockForReadingPool);
+
return Result;
}
diff --git a/hyperdbg/hyperkd/code/debugger/meta-events/Tracing.c b/hyperdbg/hyperkd/code/debugger/meta-events/Tracing.c
index 52af8b00..8a7837ca 100644
--- a/hyperdbg/hyperkd/code/debugger/meta-events/Tracing.c
+++ b/hyperdbg/hyperkd/code/debugger/meta-events/Tracing.c
@@ -26,9 +26,9 @@ TracingPerformInstrumentationStepIn(PROCESSOR_DEBUGGING_STATE * DbgState)
DbgState->TracingMode = TRUE;
//
- // Register break on MTF
+ // Set instrumentation step-in state
//
- VmFuncRegisterMtfBreak(DbgState->CoreId);
+ VmFuncSetInstrumentationStepInState(DbgState->CoreId);
VmFuncEnableMtfAndChangeExternalInterruptState(DbgState->CoreId);
}
@@ -73,9 +73,9 @@ TracingRestoreSystemState(PROCESSOR_DEBUGGING_STATE * DbgState)
DbgState->TracingMode = FALSE;
//
- // Unregister break on MTF
+ // Uset the instrumentation step-in state
//
- VmFuncUnRegisterMtfBreak(DbgState->CoreId);
+ VmFuncUnsetInstrumentationStepInState(DbgState->CoreId);
//
// Check for reenabling external interrupts
@@ -104,16 +104,36 @@ TracingCheckForContinuingSteps(PROCESSOR_DEBUGGING_STATE * DbgState)
}
/**
- * @brief Regular step-in | step one instruction to the debuggee
- * @param DbgState The state of the debugger on the current core
+ * @brief Regular step-in, step one instruction to the debuggee
*
* @return VOID
*/
VOID
-TracingPerformRegularStepInInstruction(PROCESSOR_DEBUGGING_STATE * DbgState)
+TracingRegularStepInInstruction()
{
- UNREFERENCED_PARAMETER(DbgState);
+ //
+ // Perform the step-in
+ //
+ TracingPerformRegularStepInInstruction();
+ //
+ // Unset the trap flag on the next VM-exit
+ //
+ if (!BreakpointRestoreTheTrapFlagOnceTriggered(HANDLE_TO_UINT32(PsGetCurrentProcessId()), HANDLE_TO_UINT32(PsGetCurrentThreadId())))
+ {
+ LogWarning("Warning, it is currently not possible to add the current process/thread to the list of processes "
+ "where the trap flag should be masked. Please ensure that you manually unset the trap flag");
+ }
+}
+
+/**
+ * @brief Regular step-in, step one instruction to the debuggee
+ *
+ * @return VOID
+ */
+VOID
+TracingPerformRegularStepInInstruction()
+{
UINT64 Interruptibility;
UINT64 InterruptibilityOld = NULL64_ZERO;
diff --git a/hyperdbg/hyperkd/code/debugger/objects/Thread.c b/hyperdbg/hyperkd/code/debugger/objects/Thread.c
index f46683df..c209c10b 100644
--- a/hyperdbg/hyperkd/code/debugger/objects/Thread.c
+++ b/hyperdbg/hyperkd/code/debugger/objects/Thread.c
@@ -1,4 +1,4 @@
-/**
+/**
* @file Thread.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Implementation of kernel debugger functions for threads
@@ -442,7 +442,7 @@ ThreadDetectChangeByDebugRegisterOnGs(PROCESSOR_DEBUGGING_STATE * DbgState,
// from user-mode then IA32_KERNEL_GS_BASE should be used
// but it's not for our case
//
- MsrGsBase = __readmsr(IA32_GS_BASE);
+ MsrGsBase = CpuReadMsr(IA32_GS_BASE);
//
// Now, we have the gs base on MSR
@@ -467,8 +467,8 @@ ThreadDetectChangeByDebugRegisterOnGs(PROCESSOR_DEBUGGING_STATE * DbgState,
// want dr7 and dr0 remove their configuration on vm-exits and also
// we'll be able to change the dr7 of the guest on VMCS
//
- VmFuncSetLoadDebugControls(TRUE);
- VmFuncSetSaveDebugControls(TRUE);
+ VmFuncSetLoadDebugControls(DbgState->CoreId, TRUE);
+ VmFuncSetSaveDebugControls(DbgState->CoreId, TRUE);
//
// Intercept #DBs by changing exception bitmap (one core)
@@ -528,8 +528,8 @@ ThreadDetectChangeByDebugRegisterOnGs(PROCESSOR_DEBUGGING_STATE * DbgState,
// Disable load debug controls and save debug controls because
// no longer needed
//
- VmFuncSetLoadDebugControls(FALSE);
- VmFuncSetSaveDebugControls(FALSE);
+ VmFuncSetLoadDebugControls(DbgState->CoreId, FALSE);
+ VmFuncSetSaveDebugControls(DbgState->CoreId, FALSE);
//
// Disable intercepting #DBs
@@ -543,6 +543,23 @@ ThreadDetectChangeByDebugRegisterOnGs(PROCESSOR_DEBUGGING_STATE * DbgState,
}
}
+/**
+ * @brief Query for deubg register interception state
+ * @param CoreId
+ *
+ * @return BOOLEAN whether it's activated or not
+ */
+BOOLEAN
+ThreadQueryDebugRegisterInterceptionStateByCoreId(UINT32 CoreId)
+{
+ BOOLEAN Result = FALSE;
+ PROCESSOR_DEBUGGING_STATE * DbgState = &g_DbgState[CoreId];
+
+ Result = DbgState->ThreadOrProcessTracingDetails.DebugRegisterInterceptionState;
+
+ return Result;
+}
+
/**
* @brief Enable or disable the thread change monitoring detection
* on the running core based on intercepting clock interrupts
diff --git a/hyperdbg/hyperkd/code/debugger/user-level/Attaching.c b/hyperdbg/hyperkd/code/debugger/user-level/Attaching.c
index 59a9a148..7b83da01 100644
--- a/hyperdbg/hyperkd/code/debugger/user-level/Attaching.c
+++ b/hyperdbg/hyperkd/code/debugger/user-level/Attaching.c
@@ -579,7 +579,7 @@ AttachingAdjustNopSledBuffer(UINT64 ReservedBuffAddress, UINT32 ProcessId)
//
// Fill the memory with nops
//
- memset((void *)ReservedBuffAddress, 0x90, PAGE_SIZE);
+ memset((PVOID)ReservedBuffAddress, 0x90, PAGE_SIZE);
//
// Set jmps to form a loop (little endians)
@@ -656,11 +656,17 @@ AttachingCheckThreadInterceptionWithUserDebugger(UINT32 CoreId)
//
// Handling state through the user-mode debugger
//
- UdCheckAndHandleBreakpointsAndDebugBreaks(DbgState,
- DEBUGGEE_PAUSING_REASON_DEBUGGEE_GENERAL_THREAD_INTERCEPTED,
- NULL);
+ if (UdCheckAndHandleBreakpointsAndDebugBreaks(DbgState,
+ DEBUGGEE_PAUSING_REASON_DEBUGGEE_GENERAL_THREAD_INTERCEPTED,
+ NULL))
+ {
+ //
+ // Check for possible commands that need to be executed
+ //
+ UdCheckForCommand(DbgState, ProcessDebuggingDetail);
- return TRUE;
+ return TRUE;
+ }
}
//
@@ -718,6 +724,11 @@ AttachingConfigureInterceptingThreads(UINT64 ProcessDebuggingToken, BOOLEAN Enab
}
else
{
+ //
+ // Unpause the threads of the target process
+ //
+ ThreadHolderUnpauseAllThreadsInProcess(ProcessDebuggingDetail);
+
//
// Remove the process from the watching list
//
@@ -1093,11 +1104,6 @@ AttachingContinueProcess(PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS ContinueReque
//
if (AttachingConfigureInterceptingThreads(ContinueRequest->Token, FALSE))
{
- //
- // Unpause the threads of the target process
- //
- ThreadHolderUnpauseAllThreadsInProcess(ProcessDebuggingDetails);
-
//
// The continuing operation was successful
//
@@ -1335,11 +1341,17 @@ AttachingSwitchProcess(PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS SwitchRequest)
//
// Fill the needed details by user mode
//
- SwitchRequest->Token = ProcessDebuggingDetail->Token;
- SwitchRequest->ProcessId = ProcessDebuggingDetail->ProcessId;
- SwitchRequest->ThreadId = ThreadDebuggingDetail->ThreadId;
- SwitchRequest->Is32Bit = ProcessDebuggingDetail->Is32Bit;
- SwitchRequest->IsPaused = ThreadDebuggingDetail->IsPaused;
+ SwitchRequest->Token = ProcessDebuggingDetail->Token;
+ SwitchRequest->ProcessId = ProcessDebuggingDetail->ProcessId;
+ SwitchRequest->ThreadId = ThreadDebuggingDetail->ThreadId;
+ SwitchRequest->Is32Bit = ProcessDebuggingDetail->Is32Bit;
+ SwitchRequest->Rip = ThreadDebuggingDetail->ThreadRip;
+ SwitchRequest->IsPaused = ThreadDebuggingDetail->IsPaused;
+ SwitchRequest->SizeOfInstruction = ThreadDebuggingDetail->SizeOfInstruction;
+
+ memcpy(&SwitchRequest->InstructionBytesOnRip[0],
+ &ThreadDebuggingDetail->InstructionBytesOnRip[0],
+ ThreadDebuggingDetail->SizeOfInstruction);
SwitchRequest->Result = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
return TRUE;
diff --git a/hyperdbg/hyperkd/code/debugger/user-level/ThreadHolder.c b/hyperdbg/hyperkd/code/debugger/user-level/ThreadHolder.c
index 4a5201bd..0d37c3b6 100644
--- a/hyperdbg/hyperkd/code/debugger/user-level/ThreadHolder.c
+++ b/hyperdbg/hyperkd/code/debugger/user-level/ThreadHolder.c
@@ -86,7 +86,7 @@ ThreadHolderIsAnyPausedThreadInProcess(PUSERMODE_DEBUGGING_PROCESS_DETAILS Proce
PUSERMODE_DEBUGGING_THREAD_HOLDER ThreadHolder =
CONTAINING_RECORD(TempList, USERMODE_DEBUGGING_THREAD_HOLDER, ThreadHolderList);
- for (size_t i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
+ for (SIZE_T i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
{
if (ThreadHolder->Threads[i].ThreadId != NULL_ZERO && ThreadHolder->Threads[i].IsPaused)
{
@@ -118,7 +118,7 @@ ThreadHolderUnpauseAllThreadsInProcess(PUSERMODE_DEBUGGING_PROCESS_DETAILS Proce
PUSERMODE_DEBUGGING_THREAD_HOLDER ThreadHolder =
CONTAINING_RECORD(TempList, USERMODE_DEBUGGING_THREAD_HOLDER, ThreadHolderList);
- for (size_t i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
+ for (SIZE_T i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
{
if (ThreadHolder->Threads[i].ThreadId != NULL_ZERO && ThreadHolder->Threads[i].IsPaused)
{
@@ -165,7 +165,7 @@ ThreadHolderGetProcessThreadDetailsByProcessIdAndThreadId(UINT32 ProcessId, UINT
PUSERMODE_DEBUGGING_THREAD_HOLDER ThreadHolder =
CONTAINING_RECORD(TempList, USERMODE_DEBUGGING_THREAD_HOLDER, ThreadHolderList);
- for (size_t i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
+ for (SIZE_T i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
{
if (ThreadHolder->Threads[i].ThreadId == ThreadId)
{
@@ -213,7 +213,7 @@ ThreadHolderGetProcessFirstThreadDetailsByProcessId(UINT32 ProcessId)
PUSERMODE_DEBUGGING_THREAD_HOLDER ThreadHolder =
CONTAINING_RECORD(TempList, USERMODE_DEBUGGING_THREAD_HOLDER, ThreadHolderList);
- for (size_t i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
+ for (SIZE_T i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
{
if (ThreadHolder->Threads[i].ThreadId != NULL_ZERO)
{
@@ -262,7 +262,7 @@ ThreadHolderGetProcessDebuggingDetailsByThreadId(UINT32 ThreadId)
PUSERMODE_DEBUGGING_THREAD_HOLDER ThreadHolder =
CONTAINING_RECORD(TempList2, USERMODE_DEBUGGING_THREAD_HOLDER, ThreadHolderList);
- for (size_t i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
+ for (SIZE_T i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
{
if (ThreadHolder->Threads[i].ThreadId == ThreadId)
{
@@ -305,7 +305,7 @@ ThreadHolderFindOrCreateThreadDebuggingDetail(UINT32 ThreadId, PUSERMODE_DEBUGGI
PUSERMODE_DEBUGGING_THREAD_HOLDER ThreadHolder =
CONTAINING_RECORD(TempList, USERMODE_DEBUGGING_THREAD_HOLDER, ThreadHolderList);
- for (size_t i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
+ for (SIZE_T i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
{
if (ThreadHolder->Threads[i].ThreadId == ThreadId)
{
@@ -337,7 +337,7 @@ ThreadHolderFindOrCreateThreadDebuggingDetail(UINT32 ThreadId, PUSERMODE_DEBUGGI
PUSERMODE_DEBUGGING_THREAD_HOLDER ThreadHolder =
CONTAINING_RECORD(TempList, USERMODE_DEBUGGING_THREAD_HOLDER, ThreadHolderList);
- for (size_t i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
+ for (SIZE_T i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
{
if (ThreadHolder->Threads[i].ThreadId == NULL_ZERO)
{
@@ -415,7 +415,7 @@ ThreadHolderApplyActionToPausedThreads(PUSERMODE_DEBUGGING_PROCESS_DETAILS Proce
//
// Apply the command
//
- for (size_t i = 0; i < MAX_USER_ACTIONS_FOR_THREADS; i++)
+ for (SIZE_T i = 0; i < MAX_USER_ACTIONS_FOR_THREADS; i++)
{
if (ThreadDebuggingDetails->UdAction[i].ActionType == DEBUGGER_UD_COMMAND_ACTION_TYPE_NONE)
{
@@ -454,12 +454,12 @@ ThreadHolderApplyActionToPausedThreads(PUSERMODE_DEBUGGING_PROCESS_DETAILS Proce
PUSERMODE_DEBUGGING_THREAD_HOLDER ThreadHolder =
CONTAINING_RECORD(TempList, USERMODE_DEBUGGING_THREAD_HOLDER, ThreadHolderList);
- for (size_t i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
+ for (SIZE_T i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
{
if (ThreadHolder->Threads[i].ThreadId != NULL_ZERO &&
ThreadHolder->Threads[i].IsPaused)
{
- for (size_t j = 0; j < MAX_USER_ACTIONS_FOR_THREADS; j++)
+ for (SIZE_T j = 0; j < MAX_USER_ACTIONS_FOR_THREADS; j++)
{
if (ThreadHolder->Threads[i].UdAction[j].ActionType == DEBUGGER_UD_COMMAND_ACTION_TYPE_NONE)
{
@@ -554,7 +554,7 @@ ThreadHolderQueryCountOfActiveDebuggingThreadsAndProcesses()
PUSERMODE_DEBUGGING_THREAD_HOLDER ThreadHolder =
CONTAINING_RECORD(TempList2, USERMODE_DEBUGGING_THREAD_HOLDER, ThreadHolderList);
- for (size_t i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
+ for (SIZE_T i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
{
if (ThreadHolder->Threads[i].IsPaused)
{
@@ -631,16 +631,18 @@ ThreadHolderQueryDetailsOfActiveDebuggingThreadsAndProcesses(
PUSERMODE_DEBUGGING_THREAD_HOLDER ThreadHolder =
CONTAINING_RECORD(TempList2, USERMODE_DEBUGGING_THREAD_HOLDER, ThreadHolderList);
- for (size_t i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
+ for (SIZE_T i = 0; i < MAX_THREADS_IN_A_PROCESS_HOLDER; i++)
{
if (ThreadHolder->Threads[i].IsPaused)
{
//
// A paused thread should be saved
//
- BufferToStoreDetails[CurrentIndex].IsProcess = FALSE;
- BufferToStoreDetails[CurrentIndex].ProcessId = ProcessDebuggingDetails->ProcessId;
- BufferToStoreDetails[CurrentIndex].ThreadId = ThreadHolder->Threads[i].ThreadId;
+ BufferToStoreDetails[CurrentIndex].IsProcess = FALSE;
+ BufferToStoreDetails[CurrentIndex].ProcessId = ProcessDebuggingDetails->ProcessId;
+ BufferToStoreDetails[CurrentIndex].ThreadId = ThreadHolder->Threads[i].ThreadId;
+ BufferToStoreDetails[CurrentIndex].NumberOfBlockedContextSwitches = ThreadHolder->Threads[i].NumberOfBlockedContextSwitches;
+
CurrentIndex++;
if (MaxCount == CurrentIndex)
{
diff --git a/hyperdbg/hyperkd/code/debugger/user-level/Ud.c b/hyperdbg/hyperkd/code/debugger/user-level/Ud.c
index a32dd7f8..3d0a7e84 100644
--- a/hyperdbg/hyperkd/code/debugger/user-level/Ud.c
+++ b/hyperdbg/hyperkd/code/debugger/user-level/Ud.c
@@ -67,6 +67,11 @@ UdInitializeUserDebugger()
//
ThreadHolderAllocateThreadHoldingBuffers();
+ //
+ // Initialize command waiting event
+ //
+ SynchronizationInitializeEvent(&g_UserDebuggerWaitingCommandEvent);
+
//
// Indicate that the user debugger is active
//
@@ -165,80 +170,310 @@ UdHandleInstantBreak(PROCESSOR_DEBUGGING_STATE * DbgState,
}
/**
- * @brief Restore the thread to the original direction
+ * @brief Apply hardware debug registers to all cores
*
- * @param ThreadDebuggingDetails
+ * @param TargetAddress
*
* @return VOID
*/
VOID
-UdRestoreToOriginalDirection(PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadDebuggingDetails)
+UdApplyHardwareDebugRegister(PVOID TargetAddress)
{
- //
- // Configure the RIP again
- //
- VmFuncSetRip(ThreadDebuggingDetails->ThreadRip);
+ SetDebugRegisters(DEBUGGER_DEBUG_REGISTER_FOR_STEP_OVER,
+ BREAK_ON_INSTRUCTION_FETCH,
+ FALSE,
+ (UINT64)TargetAddress);
}
/**
- * @brief Perform stepping though the instructions in target thread
- *
- * @param ThreadDebuggingDetails
+ * @brief Send the result of formats command to the user debugger
+ * @param Value
*
* @return VOID
*/
VOID
-UdStepInstructions(PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadDebuggingDetails,
- DEBUGGER_REMOTE_STEPPING_REQUEST SteppingType)
+UdSendFormatsFunctionResult(UINT64 Value)
+{
+ g_UserDebuggerFormatsResultPacket.Result = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ g_UserDebuggerFormatsResultPacket.Value = Value;
+}
+
+/**
+ * @brief routines to broadcast setting hardware debug registers on all cores
+ * @param TargetAddress
+ *
+ * @return VOID
+ */
+VOID
+UdBroadcastSetHardwareDebugRegistersAllCores(PVOID TargetAddress)
{
//
- // Configure the RIP
+ // Broadcast to all cores
//
- UdRestoreToOriginalDirection(ThreadDebuggingDetails);
+ KeGenericCallDpc(DpcRoutineSetHardwareDebugRegisters, TargetAddress);
+}
+
+/**
+ * @brief Regular step-over, step one instruction to the debuggee on user debugger if
+ * there is a call then it jumps the call
+ *
+ * @param LastRip Last RIP register
+ * @param IsNextInstructionACall
+ * @param CallLength
+ *
+ * @return VOID
+ */
+VOID
+UdRegularStepOver(UINT64 LastRip, BOOLEAN IsNextInstructionACall, UINT32 CallLength)
+{
+ UINT64 NextAddressForHardwareDebugBp = 0;
+
+ // LogInfo("Last Rip: %llx, IsNextInstructionACall: %s, Call length: %x",
+ // LastRip,
+ // IsNextInstructionACall ? "true" : "false",
+ // CallLength);
+
+ if (IsNextInstructionACall)
+ {
+ //
+ // It's a call, we should put a hardware debug register breakpoint
+ // on the next instruction
+ //
+ NextAddressForHardwareDebugBp = LastRip + CallLength;
+
+ //
+ // Broadcast to apply hardware debug registers to all cores
+ //
+ UdBroadcastSetHardwareDebugRegistersAllCores((PVOID)NextAddressForHardwareDebugBp);
+ }
+ else
+ {
+ //
+ // Any instruction other than call (regular step)
+ //
+ TracingRegularStepInInstruction();
+ }
+}
+
+/**
+ * @brief Handles debug events when user-debugger is attached
+ *
+ * @param DbgState The state of the debugger on the current core
+ * @param TrapSetByDebugger Shows whether a trap set by debugger or not
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+UdHandleDebugEventsWhenUserDebuggerIsAttached(PROCESSOR_DEBUGGING_STATE * DbgState,
+ BOOLEAN TrapSetByDebugger)
+{
+ UNREFERENCED_PARAMETER(TrapSetByDebugger);
+
+ if (UdHandleInstantBreak(DbgState,
+ DEBUGGEE_PAUSING_REASON_DEBUGGEE_GENERAL_DEBUG_BREAK,
+ NULL))
+ {
+ //
+ // Handled by user debugger
+ //
+ return TRUE;
+ }
+ else
+ {
+ //
+ // Not handled by user debugger
+ //
+ return FALSE;
+ }
+}
+
+/**
+ * @brief Perform stepping though the instructions in the target thread
+ *
+ * @param DbgState The state of the debugger on the current core
+ * @param ProcessDebuggingDetail
+ * @param ThreadDebuggingDetails
+ * @param SteppingType
+ * @param IsCurrentInstructionACall
+ * @param CallInstructionSize
+ *
+ * @return VOID
+ */
+VOID
+UdStepInstructions(PROCESSOR_DEBUGGING_STATE * DbgState,
+ PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail,
+ PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadDebuggingDetails,
+ DEBUGGER_REMOTE_STEPPING_REQUEST SteppingType,
+ BOOLEAN IsCurrentInstructionACall,
+ UINT32 CallInstructionSize)
+{
+ UNREFERENCED_PARAMETER(ThreadDebuggingDetails);
switch (SteppingType)
{
case DEBUGGER_REMOTE_STEPPING_REQUEST_STEP_IN:
//
- // Set the trap-flag
+ // Apply step-in (t command)
//
- VmFuncSetRflagTrapFlag(TRUE);
+ TracingRegularStepInInstruction();
//
- // Indicate that we should set the trap flag to the FALSE next time on
- // the same process/thread
+ // Continue the debuggee process
//
- if (!BreakpointRestoreTheTrapFlagOnceTriggered(HANDLE_TO_UINT32(PsGetCurrentProcessId()), HANDLE_TO_UINT32(PsGetCurrentThreadId())))
- {
- LogWarning("Warning, it is currently not possible to add the current process/thread to the list of processes "
- "where the trap flag should be masked. Please ensure that you manually unset the trap flag");
- }
+ AttachingConfigureInterceptingThreads(ProcessDebuggingDetail->Token, FALSE);
break;
case DEBUGGER_REMOTE_STEPPING_REQUEST_STEP_OVER:
+ //
+ // Apply Step-over (p command)
+ //
+ UdRegularStepOver(
+ VmFuncGetLastVmexitRip(DbgState->CoreId),
+ IsCurrentInstructionACall,
+ CallInstructionSize);
+
+ //
+ // Continue the debuggee process
+ //
+ AttachingConfigureInterceptingThreads(ProcessDebuggingDetail->Token, FALSE);
+
break;
default:
break;
}
+}
+
+/**
+ * @brief Perform reading register(s) in the target thread
+ *
+ * @param DbgState The state of the debugger on the current core
+ * @param RegisterId
+ *
+ * @return VOID
+ */
+VOID
+UdReadRegisters(PROCESSOR_DEBUGGING_STATE * DbgState,
+ UINT32 RegisterId)
+{
+ UNREFERENCED_PARAMETER(DbgState);
+ UNREFERENCED_PARAMETER(RegisterId);
+
+ PDEBUGGER_UD_COMMAND_PACKET ActionRequest;
+ PDEBUGGEE_REGISTER_READ_DESCRIPTION RegDesc;
//
- // Continue the current instruction won't pass it
+ // Recover the action request buffer and optional storage buffer
//
- VmFuncSuppressRipIncrement(KeGetCurrentProcessorNumberEx(NULL));
+ ActionRequest = (DEBUGGER_UD_COMMAND_PACKET *)g_UserDebuggerWaitingCommandBuffer;
+ RegDesc = (PDEBUGGEE_REGISTER_READ_DESCRIPTION)((UINT8 *)g_UserDebuggerWaitingCommandBuffer + sizeof(DEBUGGER_UD_COMMAND_PACKET));
//
- // It's not paused anymore!
+ // *** Here, we should read the registers and put them in the optional storage buffer ***
//
- ThreadDebuggingDetails->IsPaused = FALSE;
+ DebuggerCommandReadRegisters(DbgState->Regs, RegDesc);
+
+ //
+ // Set the register request result
+ //
+ RegDesc->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+
+ //
+ // Set the action request result
+ //
+ ActionRequest->Result = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+
+ //
+ // Set the event to indicate that the command is completed
+ //
+ SynchronizationSetEvent(&g_UserDebuggerWaitingCommandEvent);
+}
+
+/**
+ * @brief Perform running script in the target thread
+ *
+ * @param DbgState The state of the debugger on the current core
+ *
+ * @return VOID
+ */
+VOID
+UdRunScript(PROCESSOR_DEBUGGING_STATE * DbgState)
+{
+ PDEBUGGER_UD_COMMAND_PACKET ActionRequest;
+ DEBUGGEE_SCRIPT_PACKET * ScriptPacket;
+ DEBUGGER_TRIGGERED_EVENT_DETAILS EventTriggerDetail = {0};
+
+ //
+ // Recover the action request buffer and optional storage buffer
+ //
+ ActionRequest = (DEBUGGER_UD_COMMAND_PACKET *)g_UserDebuggerWaitingCommandBuffer;
+ ScriptPacket = (DEBUGGEE_SCRIPT_PACKET *)((UINT8 *)g_UserDebuggerWaitingCommandBuffer + sizeof(DEBUGGER_UD_COMMAND_PACKET));
+
+ //
+ // *** Here, we should execute script buffer and put them in the optional storage buffer ***
+ //
+
+ //
+ // Set a tag to the script so it shows the message is from script engine
+ //
+ EventTriggerDetail.Tag = OPERATION_LOG_MESSAGE_MANDATORY;
+
+ //
+ // Run the script in the target process (thread)
+ //
+ if (DebuggerPerformRunScript(DbgState,
+ NULL,
+ ScriptPacket,
+ &EventTriggerDetail))
+ {
+ //
+ // Check if we need to format the output or not
+ //
+ if (ScriptPacket->IsFormat)
+ {
+ //
+ // For the format, we need to get the result from the script engine
+ // through global variables, we store the result of format into
+ // optional parameters
+ //
+ ScriptPacket->Result = g_UserDebuggerFormatsResultPacket.Result;
+ ScriptPacket->FormatValue = g_UserDebuggerFormatsResultPacket.Value;
+ }
+ else
+ {
+ //
+ // Set status
+ //
+ ScriptPacket->Result = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ }
+ }
+ else
+ {
+ //
+ // Set status
+ //
+ ScriptPacket->Result = DEBUGGER_ERROR_PREPARING_DEBUGGEE_TO_RUN_SCRIPT;
+ }
+
+ //
+ // Set the action request result
+ //
+ ActionRequest->Result = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+
+ //
+ // Set the event to indicate that the command is completed
+ //
+ SynchronizationSetEvent(&g_UserDebuggerWaitingCommandEvent);
}
/**
* @brief Perform the user-mode commands
*
+ * @param DbgState The state of the debugger on the current core
+ * @param ProcessDebuggingDetails
* @param ThreadDebuggingDetails
* @param UserAction
* @param OptionalParam1
@@ -249,15 +484,15 @@ UdStepInstructions(PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadDebuggingDetails,
* @return BOOLEAN
*/
BOOLEAN
-UdPerformCommand(PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadDebuggingDetails,
- DEBUGGER_UD_COMMAND_ACTION_TYPE UserAction,
- UINT64 OptionalParam1,
- UINT64 OptionalParam2,
- UINT64 OptionalParam3,
- UINT64 OptionalParam4)
+UdPerformCommand(PROCESSOR_DEBUGGING_STATE * DbgState,
+ PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail,
+ PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadDebuggingDetails,
+ DEBUGGER_UD_COMMAND_ACTION_TYPE UserAction,
+ UINT64 OptionalParam1,
+ UINT64 OptionalParam2,
+ UINT64 OptionalParam3,
+ UINT64 OptionalParam4)
{
- UNREFERENCED_PARAMETER(OptionalParam2);
- UNREFERENCED_PARAMETER(OptionalParam3);
UNREFERENCED_PARAMETER(OptionalParam4);
//
@@ -270,7 +505,31 @@ UdPerformCommand(PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadDebuggingDetails,
//
// Stepping through the instructions
//
- UdStepInstructions(ThreadDebuggingDetails, (DEBUGGER_REMOTE_STEPPING_REQUEST)OptionalParam1);
+ UdStepInstructions(DbgState,
+ ProcessDebuggingDetail,
+ ThreadDebuggingDetails,
+ (DEBUGGER_REMOTE_STEPPING_REQUEST)OptionalParam1,
+ (BOOLEAN)OptionalParam2,
+ (UINT32)OptionalParam3);
+
+ break;
+
+ case DEBUGGER_UD_COMMAND_ACTION_TYPE_READ_REGISTERS:
+
+ //
+ // Read the registers
+ //
+ UdReadRegisters(DbgState,
+ (UINT32)OptionalParam1);
+
+ break;
+
+ case DEBUGGER_UD_COMMAND_ACTION_TYPE_EXECUTE_SCRIPT_BUFFER:
+
+ //
+ // Execute the script buffer
+ //
+ UdRunScript(DbgState);
break;
@@ -280,6 +539,7 @@ UdPerformCommand(PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadDebuggingDetails,
// Invalid user action
//
return FALSE;
+
break;
}
@@ -289,20 +549,17 @@ UdPerformCommand(PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadDebuggingDetails,
/**
* @brief Check for the user-mode commands
*
+ * @param DbgState The state of the debugger on the current core
+ * @param ProcessDebuggingDetail
+ *
* @return BOOLEAN
*/
BOOLEAN
-UdCheckForCommand()
+UdCheckForCommand(PROCESSOR_DEBUGGING_STATE * DbgState,
+ PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail)
{
PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadDebuggingDetails;
-
- //
- // Check if user-debugger is initialized or not
- //
- if (!g_UserDebuggerState)
- {
- return FALSE;
- }
+ BOOLEAN CommandFound = FALSE;
ThreadDebuggingDetails = ThreadHolderGetProcessThreadDetailsByProcessIdAndThreadId(HANDLE_TO_UINT32(PsGetCurrentProcessId()),
HANDLE_TO_UINT32(PsGetCurrentThreadId()));
@@ -314,7 +571,7 @@ UdCheckForCommand()
//
// If we reached here, the current thread is in debugger attached mechanism
- // now we check whether it's a regular CPUID or a debugger paused thread CPUID
+ // now we check whether it's paused or not
//
if (!ThreadDebuggingDetails->IsPaused)
{
@@ -325,14 +582,21 @@ UdCheckForCommand()
// Here, we're sure that this thread is looking for command, let
// see if we find anything
//
- for (size_t i = 0; i < MAX_USER_ACTIONS_FOR_THREADS; i++)
+ for (SIZE_T i = 0; i < MAX_USER_ACTIONS_FOR_THREADS; i++)
{
if (ThreadDebuggingDetails->UdAction[i].ActionType != DEBUGGER_UD_COMMAND_ACTION_TYPE_NONE)
{
+ //
+ // We found a command for this thread
+ //
+ CommandFound = TRUE;
+
//
// Perform the command
//
- UdPerformCommand(ThreadDebuggingDetails,
+ UdPerformCommand(DbgState,
+ ProcessDebuggingDetail,
+ ThreadDebuggingDetails,
ThreadDebuggingDetails->UdAction[i].ActionType,
ThreadDebuggingDetails->UdAction[i].OptionalParam1,
ThreadDebuggingDetails->UdAction[i].OptionalParam2,
@@ -360,21 +624,27 @@ UdCheckForCommand()
}
//
- // Won't change the registers for cpuid
+ // Return whether we found a command or not
//
- return TRUE;
+ return CommandFound;
}
/**
* @brief Dispatch the user-mode commands
*
* @param ActionRequest
+ * @param ActionRequestInputLength
+ * @param ActionRequestOutputLength
+ *
* @return BOOLEAN
*/
BOOLEAN
-UdDispatchUsermodeCommands(PDEBUGGER_UD_COMMAND_PACKET ActionRequest)
+UdDispatchUsermodeCommands(PDEBUGGER_UD_COMMAND_PACKET ActionRequest,
+ UINT32 ActionRequestInputLength,
+ UINT32 ActionRequestOutputLength)
{
PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetails;
+ BOOLEAN Result;
//
// Find the thread debugging detail of the thread
@@ -386,24 +656,68 @@ UdDispatchUsermodeCommands(PDEBUGGER_UD_COMMAND_PACKET ActionRequest)
//
// Token not found!
//
+ ActionRequest->Result = DEBUGGER_ERROR_INVALID_THREAD_DEBUGGING_TOKEN;
+
return FALSE;
}
//
- // Based on the documentation, HyperDbg stops intercepting threads
- // when the debugger sent the first command, but if user presses
- // run the 'pause' command, all the threads (or new threads) that will enter
- // the user-mode will be intercepted
+ // Check if this command needs the action request to be waited for completion or not
//
- if (ProcessDebuggingDetails->IsOnThreadInterceptingPhase)
+ if (ActionRequest->WaitForEventCompletion)
{
- AttachingConfigureInterceptingThreads(ProcessDebuggingDetails->Token, FALSE);
+ //
+ // Set the command event buffer
+ //
+ g_UserDebuggerWaitingCommandBuffer = (PVOID)ActionRequest;
+
+ //
+ // Set the input command buffer length
+ //
+ g_UserDebuggerWaitingCommandInputBufferLength = ActionRequestInputLength;
+
+ //
+ // Set the output command buffer length
+ //
+ g_UserDebuggerWaitingCommandOutputBufferLength = ActionRequestOutputLength;
}
//
// Apply the command to all threads or just one thread
//
- return ThreadHolderApplyActionToPausedThreads(ProcessDebuggingDetails, ActionRequest);
+ Result = ThreadHolderApplyActionToPausedThreads(ProcessDebuggingDetails, ActionRequest);
+
+ //
+ // Check if we need to wait for the command event completion or not
+ //
+ if (Result && ActionRequest->WaitForEventCompletion)
+ {
+ //
+ // Wait for the command to be completed
+ //
+ SynchronizationWaitForEvent(&g_UserDebuggerWaitingCommandEvent);
+ }
+
+ //
+ // Since the command is applied successfully, we can set the result
+ // Note that if the command contains another layer of optional buffers
+ // the result of that optional buffer might be different than this result
+ // this one is just for applying the command itself
+ //
+ if (Result)
+ {
+ //
+ // If we are not waiting for the event completion, we should set the
+ // result of the action request here as we successfully applied the command
+ //
+ ActionRequest->Result = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ }
+ else
+ {
+ ActionRequest->Result = DEBUGGER_ERROR_UNABLE_TO_APPLY_COMMAND_TO_THE_TARGET_THREAD;
+ }
+
+ return Result;
}
/**
@@ -411,11 +725,16 @@ UdDispatchUsermodeCommands(PDEBUGGER_UD_COMMAND_PACKET ActionRequest)
*
* @param ThreadDebuggingDetails
* @param ProcessDebuggingDetails
+ * @param InstructionBytesBuffer
+ * @param SizeOfInstruction
+ *
* @return VOID
*/
VOID
UdSetThreadPausingState(PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadDebuggingDetails,
- PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetails)
+ PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetails,
+ PVOID InstructionBytesBuffer,
+ UINT32 SizeOfInstruction)
{
UNREFERENCED_PARAMETER(ProcessDebuggingDetails);
@@ -424,10 +743,25 @@ UdSetThreadPausingState(PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadDebuggingDetai
//
ThreadDebuggingDetails->ThreadRip = VmFuncGetRip();
+ //
+ // Set the number of context switches to one (reset it if already set)
+ //
+ ThreadDebuggingDetails->NumberOfBlockedContextSwitches = 1;
+
//
// Indicate that it's spinning
//
ThreadDebuggingDetails->IsPaused = TRUE;
+
+ //
+ // Set size of instruction
+ //
+ ThreadDebuggingDetails->SizeOfInstruction = SizeOfInstruction;
+
+ //
+ // Copy the current running instruction
+ //
+ memcpy(&ThreadDebuggingDetails->InstructionBytesOnRip[0], InstructionBytesBuffer, SizeOfInstruction);
}
/**
@@ -526,6 +860,11 @@ UdCheckAndHandleBreakpointsAndDebugBreaks(PROCESSOR_DEBUGGING_STATE * DbgS
//
if (ThreadDebuggingDetails->IsPaused)
{
+ //
+ // Increase the number of context switches
+ //
+ ThreadDebuggingDetails->NumberOfBlockedContextSwitches++;
+
//
// The thread is already paused, so we don't need to pause it again
//
@@ -629,11 +968,6 @@ UdCheckAndHandleBreakpointsAndDebugBreaks(PROCESSOR_DEBUGGING_STATE * DbgS
&PausePacket.InstructionBytesOnRip,
ExitInstructionLength);
- //
- // Copy registers to the pause packet
- //
- RtlCopyMemory(&PausePacket.GuestRegs, DbgState->Regs, sizeof(GUEST_REGS));
-
//
// Send the pause packet, along with RIP and an indication
// to pause to the user debugger
@@ -646,7 +980,10 @@ UdCheckAndHandleBreakpointsAndDebugBreaks(PROCESSOR_DEBUGGING_STATE * DbgS
//
// Set the thread debugging details
//
- UdSetThreadPausingState(ThreadDebuggingDetails, ProcessDebuggingDetails);
+ UdSetThreadPausingState(ThreadDebuggingDetails,
+ ProcessDebuggingDetails,
+ &PausePacket.InstructionBytesOnRip,
+ ExitInstructionLength);
//
// Everything was okay
diff --git a/hyperdbg/hyperkd/code/debugger/user-level/UserAccess.c b/hyperdbg/hyperkd/code/debugger/user-level/UserAccess.c
index 6af637b0..ea97ce52 100644
--- a/hyperdbg/hyperkd/code/debugger/user-level/UserAccess.c
+++ b/hyperdbg/hyperkd/code/debugger/user-level/UserAccess.c
@@ -606,7 +606,7 @@ UserAccessPrintLoadedModulesX86(PEPROCESS Proc,
}
TempSize = TempSize * 2;
- memcpy(&ModulesList[CurrentSavedModules].FilePath, (const void *)Entry->FullDllName.Buffer, TempSize);
+ memcpy(&ModulesList[CurrentSavedModules].FilePath, (const PVOID)Entry->FullDllName.Buffer, TempSize);
CurrentSavedModules++;
}
diff --git a/hyperdbg/hyperkd/code/driver/Driver.c b/hyperdbg/hyperkd/code/driver/Driver.c
index 2cbe2ecf..053eb828 100644
--- a/hyperdbg/hyperkd/code/driver/Driver.c
+++ b/hyperdbg/hyperkd/code/driver/Driver.c
@@ -101,9 +101,9 @@ DrvUnload(PDRIVER_OBJECT DriverObject)
IoDeleteDevice(DriverObject->DeviceObject);
//
- // Unloading VMM and Debugger
+ // Unloading Log Tracer
//
- LoaderUninitializeLogTracer();
+ LoaderUninitLogTracer();
}
/**
@@ -155,10 +155,15 @@ DrvCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
}
//
- // Initialize the vmm and the debugger
+ // Initialize HyperLog and Log Tracer
//
- if (LoaderInitVmmAndDebugger())
+ if (LoaderInitHyperLog())
{
+ //
+ // Set the variable so next CreateFile won't call log initializer again
+ //
+ g_HandleInUse = TRUE;
+
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
diff --git a/hyperdbg/hyperkd/code/driver/Ioctl.c b/hyperdbg/hyperkd/code/driver/Ioctl.c
index 97e85d28..ddd88593 100644
--- a/hyperdbg/hyperkd/code/driver/Ioctl.c
+++ b/hyperdbg/hyperkd/code/driver/Ioctl.c
@@ -13,19 +13,390 @@
#include "pch.h"
/**
- * @brief Driver IOCTL Dispatcher
+ * @brief Validates amd adjusts the parameters of an IOCTL request
+ * @param BufferSize The expected size of the input buffer
+ * @param Irp The IRP representing the IOCTL request
+ * @IrpStack The current stack location of the IRP
+ * @InBuffLength Output parameter to receive the actual input buffer length
+ * @OutBuffLength Output parameter to receive the actual output buffer length
+ *
+ * @return TRUE if the parameters are valid, FALSE otherwise
+ */
+BOOLEAN
+DrvValidateAndAdjustIoctlParameter(UINT32 BufferSize,
+ PVOID * TargetBuffer,
+ PIRP Irp,
+ PIO_STACK_LOCATION IrpStack,
+ ULONG * InBuffLength,
+ ULONG * OutBuffLength)
+{
+ //
+ // First validate the parameters
+ //
+ if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < BufferSize || Irp->AssociatedIrp.SystemBuffer == NULL)
+ {
+ LogError("Err, invalid parameter to IOCTL dispatcher");
+ return FALSE;
+ }
+
+ *InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
+ *OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
+
+ if (!*InBuffLength || !*OutBuffLength)
+ {
+ return FALSE;
+ }
+
+ //
+ // Set the target buffer to the system buffer of the IRP
+ //
+ *TargetBuffer = Irp->AssociatedIrp.SystemBuffer;
+
+ //
+ // Validation was successful
+ //
+ return TRUE;
+}
+
+/**
+ * @brief Adjusts the status and output buffer size for an IOCTL request
+ *
+ * @param ExpectedOutputBufferSize The expected size of the output buffer
+ * @param DoNotChangeInformation Output parameter to indicate whether to change the information field of the IRP's I/O status block
+ * @param Irp The IRP representing the IOCTL request
+ * @param Status Output parameter to receive the status to be set in the IRP's I/O status block
+ *
+ * @return VOID
+ */
+VOID
+DrvAdjustStatusAndSetOutputSize(UINT32 ExpectedOutputBufferSize,
+ BOOLEAN * DoNotChangeInformation,
+ PIRP Irp,
+ NTSTATUS * Status)
+{
+ Irp->IoStatus.Information = ExpectedOutputBufferSize;
+ *Status = STATUS_SUCCESS;
+
+ //
+ // Avoid zeroing it
+ //
+ *DoNotChangeInformation = TRUE;
+}
+
+/**
+ * @brief Checks whether the IOCTL request is allowed based on the current state of the driver and the system
+ * @param Ioctl The IOCTL code of the request
+ *
+ * @return BOOLEAN TRUE if the IOCTL request is allowed, FALSE otherwise
+ */
+BOOLEAN
+IoctlCheckIoctlAllowed(ULONG Ioctl)
+{
+ ULONG IoctlFunction = CTL_CODE_FUNCTION(Ioctl);
+
+ //
+ // First 100 IOCTLs are about loading and initializing modules
+ //
+ if (IoctlFunction > IOCTL_BASIC_IOCTL && IoctlFunction <= IOCTL_BASIC_IOCTL + 0x100)
+ {
+ //
+ // Always allow these IOCTLs even if we don't allow IOCTL from user-mode, because they are used for loading and initializing the driver and its components
+ //
+ return TRUE;
+ }
+ else if (IoctlFunction > IOCTL_KD_IOCTL && IoctlFunction <= IOCTL_KD_IOCTL + 0x100)
+ {
+ //
+ // Allow if the KD module is initialized
+ //
+ return g_KdInitialized;
+ }
+ else if (IoctlFunction > IOCTL_VMM_IOCTL && IoctlFunction <= IOCTL_VMM_IOCTL + 0x100)
+ {
+ //
+ // Allow if the VMM module is initialized
+ //
+ return g_VmmInitialized;
+ }
+ else if (IoctlFunction > IOCTL_HYPERTRACE_IOCTL && IoctlFunction <= IOCTL_HYPERTRACE_IOCTL + 0x100)
+ {
+ //
+ // Allow if the HyperTrace module is initialized
+ //
+ return g_HyperTraceInitialized;
+ }
+ else
+ {
+ //
+ // For other (unknown) IOCTLs, we don't allow them
+ //
+ return FALSE;
+ }
+}
+
+/**
+ * @brief Resolve a process id to the CR3 the Intel PT engine should match.
+ *
+ * @details Intel PT's CR3 filter compares the live CR3, which differs between
+ * user and kernel mode when KVA shadowing (KPTI) is enabled:
+ * - kernel-mode runs under _KPROCESS.DirectoryTableBase
+ * - user-mode runs under _KPROCESS.UserDirectoryTableBase (shadow)
+ * So pick the kernel CR3 for kernel-only traces, otherwise the user
+ * (shadow) CR3 — falling back to the kernel CR3 when KVA shadowing is
+ * off (UserDirectoryTableBase has a zero page base in that case, i.e.
+ * user-mode also runs under the kernel CR3).
+ *
+ * @param ProcessId Target process id
+ * @param TraceUser Whether CPL>0 will be traced
+ * @param TraceKernel Whether CPL==0 will be traced
+ *
+ * @return UINT64 CR3 page base (low 12 bits cleared), or 0 if the pid is gone
+ */
+static UINT64
+DrvResolvePtTargetCr3(UINT32 ProcessId, BOOLEAN TraceUser, BOOLEAN TraceKernel)
+{
+ //
+ // _KPROCESS.UserDirectoryTableBase offset (x64 Windows 10 1803+ / 11).
+ // Only this one constant is build-specific; adjust it if the user CR3
+ // ever reads wrong on a newer kernel.
+ //
+ const ULONG UserDirTableBaseOffset = 0x388;
+
+ PEPROCESS TargetProcess;
+ UINT64 KernelCr3;
+ UINT64 UserCr3;
+ UINT64 Chosen;
+
+ if (PsLookupProcessByProcessId((HANDLE)(ULONG_PTR)ProcessId, &TargetProcess) != STATUS_SUCCESS)
+ {
+ return 0;
+ }
+
+ KernelCr3 = (UINT64)((NT_KPROCESS *)TargetProcess)->DirectoryTableBase;
+ UserCr3 = *(UINT64 *)((UCHAR *)TargetProcess + UserDirTableBaseOffset);
+
+ ObDereferenceObject(TargetProcess);
+
+ if (TraceKernel && !TraceUser)
+ {
+ //
+ // Kernel-only trace — match the kernel CR3
+ //
+ Chosen = KernelCr3;
+ }
+ else if ((UserCr3 & ~0xFFFULL) != 0)
+ {
+ //
+ // KVA shadowing on — user mode runs under the shadow CR3
+ //
+ Chosen = UserCr3;
+ }
+ else
+ {
+ //
+ // KVA shadowing off — user mode runs under the kernel CR3
+ //
+ Chosen = KernelCr3;
+ }
+
+ return Chosen & ~0xFFFULL;
+}
+
+/**
+ * @brief IOCTL Dispatcher for Basic IOCTLs (initialization and event registration)
*
- * @param DeviceObject
* @param Irp
+ * @param IrpStack
+ * @param DoNotChangeInformation
* @return NTSTATUS
*/
NTSTATUS
-DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+DrvDispatchBasicIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN * DoNotChangeInformation)
{
- UNREFERENCED_PARAMETER(DeviceObject);
+ PREGISTER_NOTIFY_BUFFER RegisterEventRequest;
+ PDEBUGGER_INIT_VMM_PACKET InitVmmRequest;
+ PDEBUGGER_INIT_HYPERTRACE_PACKET InitHyperTraceRequest;
+ ULONG InBuffLength;
+ ULONG OutBuffLength;
+ NTSTATUS Status = STATUS_SUCCESS;
+ UINT32 Ioctl = IrpStack->Parameters.DeviceIoControl.IoControlCode;
- PIO_STACK_LOCATION IrpStack;
- PREGISTER_NOTIFY_BUFFER RegisterEventRequest;
+ switch (Ioctl)
+ {
+ case IOCTL_INIT_VMM:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_INIT_VMM_PACKET,
+ (PVOID *)&InitVmmRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Initialize the debugger and the vmm
+ //
+ if (LoaderInitDebuggerAndVmm(InitVmmRequest))
+ {
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ //
+ // There was a problem, so not loaded
+ //
+ Status = STATUS_UNSUCCESSFUL;
+ }
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_INIT_VMM_PACKET, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_INIT_HYPERTRACE:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_INIT_HYPERTRACE_PACKET,
+ (PVOID *)&InitHyperTraceRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Initialize the HyperTrace (if supported by the processor)
+ //
+ LoaderInitHyperTrace(InitHyperTraceRequest, TRUE);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_INIT_HYPERTRACE_PACKET, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_REGISTER_EVENT:
+
+ //
+ // First validate the parameters.
+ //
+ if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_REGISTER_EVENT || Irp->AssociatedIrp.SystemBuffer == NULL)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ LogError("Err, invalid parameter to IOCTL dispatcher");
+ break;
+ }
+
+ //
+ // IRPs supply a pointer to a buffer at Irp->AssociatedIrp.SystemBuffer.
+ // This buffer represents both the input buffer and the output buffer that
+ // are specified in calls to DeviceIoControl
+ //
+ RegisterEventRequest = (PREGISTER_NOTIFY_BUFFER)Irp->AssociatedIrp.SystemBuffer;
+
+ switch (RegisterEventRequest->Type)
+ {
+ case IRP_BASED:
+
+ LogRegisterIrpBasedNotification((PVOID)Irp, &Status);
+
+ break;
+ case EVENT_BASED:
+
+ if (LogRegisterEventBasedNotification((PVOID)Irp))
+ {
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ Status = STATUS_UNSUCCESSFUL;
+ }
+
+ break;
+ default:
+ LogError("Err, unknown notification type from user-mode");
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ break;
+
+ case IOCTL_RETURN_IRP_PENDING_PACKETS_AND_DISALLOW_IOCTL:
+
+ //
+ // Send an immediate message, and we're no longer get new IRP
+ //
+ LogCallbackSendBuffer(OPERATION_HYPERVISOR_DRIVER_END_OF_IRPS,
+ "$",
+ sizeof(CHAR),
+ TRUE);
+
+ Status = STATUS_SUCCESS;
+
+ break;
+
+ default:
+ LogError("Err, unknown IOCTL");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+ }
+
+ return Status;
+}
+
+/**
+ * @brief IOCTL Dispatcher for KD (Kernel Debugger) IOCTLs
+ *
+ * @param Irp
+ * @param IrpStack
+ * @param DoNotChangeInformation
+ * @return NTSTATUS
+ */
+NTSTATUS
+DrvDispatchKdIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN * DoNotChangeInformation)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ UINT32 Ioctl = IrpStack->Parameters.DeviceIoControl.IoControlCode;
+
+ UNREFERENCED_PARAMETER(Irp);
+ UNREFERENCED_PARAMETER(DoNotChangeInformation);
+
+ switch (Ioctl)
+ {
+ default:
+ LogError("Err, unknown IOCTL");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+ }
+
+ return Status;
+}
+
+/**
+ * @brief IOCTL Dispatcher for VMM IOCTLs
+ *
+ * @param Irp
+ * @param IrpStack
+ * @param DoNotChangeInformation
+ * @return NTSTATUS
+ */
+NTSTATUS
+DrvDispatchVmmIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN * DoNotChangeInformation)
+{
PDEBUGGER_READ_MEMORY DebuggerReadMemRequest;
PDEBUGGER_READ_AND_WRITE_ON_MSR DebuggerReadOrWriteMsrRequest;
PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE DebuggerHideAndUnhideRequest;
@@ -58,1629 +429,1375 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
PDEBUGGER_PREPARE_DEBUGGEE DebuggeeRequest;
PDEBUGGER_PAUSE_PACKET_RECEIVED DebuggerPauseKernelRequest;
PDEBUGGER_GENERAL_ACTION DebuggerNewActionRequest;
+ PSMI_OPERATION_PACKETS SmiOperationRequest;
PVOID BufferToStoreThreadsAndProcessesDetails;
- NTSTATUS Status;
ULONG InBuffLength; // Input buffer length
ULONG OutBuffLength; // Output buffer length
SIZE_T ReturnSize;
- BOOLEAN DoNotChangeInformation = FALSE;
+ NTSTATUS Status = STATUS_SUCCESS;
+ UINT32 Ioctl = IrpStack->Parameters.DeviceIoControl.IoControlCode;
+
+ switch (Ioctl)
+ {
+ case IOCTL_TERMINATE_VMX:
+
+ //
+ // Uninitialize the VMM and the debugger
+ //
+ LoaderUninitVmmAndDebugger();
+
+ Status = STATUS_SUCCESS;
+
+ break;
+
+ case IOCTL_DEBUGGER_READ_MEMORY:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_READ_MEMORY,
+ (PVOID *)&DebuggerReadMemRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if (DebuggerCommandReadMemory(DebuggerReadMemRequest,
+ ((CHAR *)DebuggerReadMemRequest) + SIZEOF_DEBUGGER_READ_MEMORY,
+ &ReturnSize) == TRUE)
+ {
+ //
+ // Return the header a read bytes
+ //
+ DrvAdjustStatusAndSetOutputSize((UINT32)(ReturnSize + SIZEOF_DEBUGGER_READ_MEMORY), DoNotChangeInformation, Irp, &Status);
+ }
+ else
+ {
+ //
+ // Just return the header to the user-mode
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_READ_MEMORY, DoNotChangeInformation, Irp, &Status);
+ }
+
+ break;
+
+ case IOCTL_DEBUGGER_READ_OR_WRITE_MSR:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_READ_AND_WRITE_ON_MSR,
+ (PVOID *)&DebuggerReadOrWriteMsrRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Both usermode and to send to usermode and the coming buffer are
+ // at the same place
+ //
+ Status = DebuggerReadOrWriteMsr(DebuggerReadOrWriteMsrRequest, (UINT64 *)DebuggerReadOrWriteMsrRequest, &ReturnSize);
+
+ //
+ // Set the size
+ //
+ if (Status == STATUS_SUCCESS)
+ {
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize((UINT32)ReturnSize, DoNotChangeInformation, Irp, &Status);
+ }
+
+ break;
+
+ case IOCTL_DEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS,
+ (PVOID *)&DebuggerPteRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Both usermode and to send to usermode and the coming buffer are
+ // at the same place (it's not in vmx-root)
+ //
+ ExtensionCommandPte(DebuggerPteRequest, FALSE);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_DEBUGGER_REGISTER_EVENT:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_GENERAL_EVENT_DETAIL,
+ (PVOID *)&DebuggerNewEventRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Both usermode and to send to usermode and the coming buffer are
+ // at the same place (not coming from the VMX-root mode)
+ //
+ DebuggerParseEvent(DebuggerNewEventRequest,
+ (PDEBUGGER_EVENT_AND_ACTION_RESULT)Irp->AssociatedIrp.SystemBuffer,
+ FALSE);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(sizeof(DEBUGGER_EVENT_AND_ACTION_RESULT), DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_DEBUGGER_ADD_ACTION_TO_EVENT:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_GENERAL_ACTION,
+ (PVOID *)&DebuggerNewActionRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Both usermode and to send to usermode and the coming buffer are
+ // at the same place
+ //
+ DebuggerParseAction(DebuggerNewActionRequest,
+ (PDEBUGGER_EVENT_AND_ACTION_RESULT)Irp->AssociatedIrp.SystemBuffer,
+ FALSE);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(sizeof(DEBUGGER_EVENT_AND_ACTION_RESULT), DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_DEBUGGER_HIDE_AND_UNHIDE_TO_TRANSPARENT_THE_DEBUGGER:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE,
+ (PVOID *)&DebuggerHideAndUnhideRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // check if it's a !hide or !unhide command
+ //
+ if (DebuggerHideAndUnhideRequest->IsHide == TRUE)
+ {
+ //
+ // It's a hide request
+ //
+ TransparentHideDebuggerWrapper(DebuggerHideAndUnhideRequest);
+ }
+ else
+ {
+ //
+ // It's a unhide request
+ //
+ TransparentUnhideDebuggerWrapper(DebuggerHideAndUnhideRequest);
+ }
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_DEBUGGER_VA2PA_AND_PA2VA_COMMANDS:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_VA2PA_AND_PA2VA_COMMANDS,
+ (PVOID *)&DebuggerVa2paAndPa2vaRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Both usermode and to send to usermode and the coming buffer are
+ // at the same place (we're not in vmx-root here)
+ //
+ ExtensionCommandVa2paAndPa2va(DebuggerVa2paAndPa2vaRequest, FALSE);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_VA2PA_AND_PA2VA_COMMANDS, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_DEBUGGER_EDIT_MEMORY:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_EDIT_MEMORY,
+ (PVOID *)&DebuggerEditMemoryRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Here we should validate whether the input parameter is
+ // valid or in other words whether we received enough space or not
+ //
+ if (IrpStack->Parameters.DeviceIoControl.InputBufferLength != SIZEOF_DEBUGGER_EDIT_MEMORY + DebuggerEditMemoryRequest->CountOf64Chunks * sizeof(UINT64))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Both usermode and to send to usermode and the coming buffer are
+ // at the same place
+ //
+ DebuggerCommandEditMemory(DebuggerEditMemoryRequest);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_EDIT_MEMORY, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_DEBUGGER_SEARCH_MEMORY:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_SEARCH_MEMORY,
+ (PVOID *)&DebuggerSearchMemoryRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // The OutBuffLength should have at least MaximumSearchResults * sizeof(UINT64)
+ // free space to store the results
+ //
+ if (OutBuffLength < MaximumSearchResults * sizeof(UINT64))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Here we should validate whether the input parameter is
+ // valid or in other words whether we received enough space or not
+ //
+ if (IrpStack->Parameters.DeviceIoControl.InputBufferLength != SIZEOF_DEBUGGER_SEARCH_MEMORY + DebuggerSearchMemoryRequest->CountOf64Chunks * sizeof(UINT64))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Both usermode and to send to usermode and the coming buffer are
+ // at the same place
+ //
+ if (DebuggerCommandSearchMemory(DebuggerSearchMemoryRequest) != STATUS_SUCCESS)
+ {
+ //
+ // It is because it was not valid in any of the ways to the function
+ // then we're sure that the usermode code won't interpret it's previous
+ // buffer as a valid buffer and will not show it to the user
+ //
+ RtlZeroMemory(DebuggerSearchMemoryRequest, MaximumSearchResults * sizeof(UINT64));
+ }
+
+ //
+ // Configure IRP status, and also we send the results
+ // buffer, with it's null values (if any)
+ //
+ DrvAdjustStatusAndSetOutputSize(MaximumSearchResults * sizeof(UINT64), DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_DEBUGGER_MODIFY_EVENTS:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_MODIFY_EVENTS,
+ (PVOID *)&DebuggerModifyEventRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Both usermode and to send to usermode and the coming buffer are
+ // at the same place
+ //
+ DebuggerParseEventsModification(DebuggerModifyEventRequest, FALSE, EnableInstantEventMechanism ? g_KernelDebuggerState : FALSE);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_MODIFY_EVENTS, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_DEBUGGER_FLUSH_LOGGING_BUFFERS:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_FLUSH_LOGGING_BUFFERS,
+ (PVOID *)&DebuggerFlushBuffersRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Perform the flush
+ //
+ DebuggerCommandFlush(DebuggerFlushBuffersRequest);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_FLUSH_LOGGING_BUFFERS, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS,
+ (PVOID *)&DebuggerAttachOrDetachToThreadRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Perform the attach to the target process
+ //
+ AttachingTargetProcess(DebuggerAttachOrDetachToThreadRequest);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_PREPARE_DEBUGGEE:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_PREPARE_DEBUGGEE,
+ (PVOID *)&DebuggeeRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Perform the action
+ //
+ SerialConnectionPrepare(DebuggeeRequest);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_PREPARE_DEBUGGEE, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_PAUSE_PACKET_RECEIVED:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_PAUSE_PACKET_RECEIVED,
+ (PVOID *)&DebuggerPauseKernelRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Perform the action
+ //
+ KdHaltSystem(DebuggerPauseKernelRequest);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_PAUSE_PACKET_RECEIVED, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_SEND_SIGNAL_EXECUTION_IN_DEBUGGEE_FINISHED:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_SEND_COMMAND_EXECUTION_FINISHED_SIGNAL,
+ (PVOID *)&DebuggerCommandExecutionFinishedRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Perform the signal operation
+ //
+ DebuggerCommandSignalExecutionState(DebuggerCommandExecutionFinishedRequest);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_SEND_COMMAND_EXECUTION_FINISHED_SIGNAL, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_SEND_USERMODE_MESSAGES_TO_DEBUGGER:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_SEND_USERMODE_MESSAGES_TO_DEBUGGER,
+ (PVOID *)&DebuggerSendUsermodeMessageRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Second validation phase
+ //
+ if (DebuggerSendUsermodeMessageRequest->Length == NULL_ZERO ||
+ IrpStack->Parameters.DeviceIoControl.InputBufferLength != SIZEOF_DEBUGGER_SEND_USERMODE_MESSAGES_TO_DEBUGGER + DebuggerSendUsermodeMessageRequest->Length)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Perform the signal operation
+ //
+ DebuggerCommandSendMessage(DebuggerSendUsermodeMessageRequest);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_SEND_USERMODE_MESSAGES_TO_DEBUGGER, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_SEND_GENERAL_BUFFER_FROM_DEBUGGEE_TO_DEBUGGER:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER,
+ (PVOID *)&DebuggerSendBufferFromDebuggeeToDebuggerRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Second validation phase
+ //
+ if (DebuggerSendBufferFromDebuggeeToDebuggerRequest->LengthOfBuffer == NULL_ZERO ||
+ IrpStack->Parameters.DeviceIoControl.InputBufferLength != SIZEOF_DEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER + DebuggerSendBufferFromDebuggeeToDebuggerRequest->LengthOfBuffer)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Perform the signal operation
+ //
+ DebuggerCommandSendGeneralBufferToDebugger(DebuggerSendBufferFromDebuggeeToDebuggerRequest);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_PERFORM_KERNEL_SIDE_TESTS:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_PERFORM_KERNEL_TESTS,
+ (PVOID *)&DebuggerKernelTestRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Perform the kernel-side tests
+ //
+ TestKernelPerformTests(DebuggerKernelTestRequest);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_PERFORM_KERNEL_TESTS, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_RESERVE_PRE_ALLOCATED_POOLS:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_PREALLOC_COMMAND,
+ (PVOID *)&DebuggerReservePreallocPoolRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Perform the reservation pools
+ //
+ DebuggerCommandReservePreallocatedPools(DebuggerReservePreallocPoolRequest);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_PREALLOC_COMMAND, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_PREACTIVATE_FUNCTIONALITY:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_PREACTIVATE_COMMAND,
+ (PVOID *)&DebuggerPreactivationRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Perform the activation of the functionality
+ //
+ DebuggerCommandPreactivateFunctionality(DebuggerPreactivationRequest);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_PREACTIVATE_COMMAND, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_PERFORM_ACTIONS_ON_APIC:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_APIC_REQUEST,
+ (PVOID *)&DebuggerApicRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(ExtensionCommandPerformActionsForApicRequests(DebuggerApicRequest), DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_QUERY_IDT_ENTRY:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS,
+ (PVOID *)&DebuggerQueryIdtRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Perform the query of IDT entries (not from vmx-root)
+ //
+ ExtensionCommandPerformQueryIdtEntriesRequest(DebuggerQueryIdtRequest, FALSE);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_SET_BREAKPOINT_USER_DEBUGGER:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGEE_BP_PACKET,
+ (PVOID *)&DebuggerBreakpointRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Perform setting the breakpoint (for the user mode debugger)
+ // Switching to the target process memory is needed as we are
+ // in HyperDbg's process memory layout and we need to switch to
+ // the target process memory layout to set the breakpoint
+ //
+ BreakpointAddNew(DebuggerBreakpointRequest, TRUE);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGEE_BP_PACKET, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_PERFORM_SMI_OPERATION:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_SMI_OPERATION_PACKETS,
+ (PVOID *)&SmiOperationRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Perform the SMI operation (it's not from vmx-root)
+ //
+ VmFuncSmmPerformSmiOperation(SmiOperationRequest, FALSE);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_SMI_OPERATION_PACKETS, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_SEND_USER_DEBUGGER_COMMANDS:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_UD_COMMAND_PACKET,
+ (PVOID *)&DebuggerUdCommandRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Perform the dispatching of user debugger command
+ //
+ UdDispatchUsermodeCommands(DebuggerUdCommandRequest, InBuffLength, OutBuffLength);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(OutBuffLength, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_GET_DETAIL_OF_ACTIVE_THREADS_AND_PROCESSES:
+
+ OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
+
+ if (!OutBuffLength)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Both usermode and to send to usermode is here
+ //
+ BufferToStoreThreadsAndProcessesDetails = (PVOID)Irp->AssociatedIrp.SystemBuffer;
+
+ //
+ // Perform the dispatching of user debugger command
+ //
+ AttachingQueryDetailsOfActiveDebuggingThreadsAndProcesses(BufferToStoreThreadsAndProcessesDetails, OutBuffLength);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(OutBuffLength, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_GET_USER_MODE_MODULE_DETAILS:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_USERMODE_LOADED_MODULE_DETAILS,
+ (PVOID *)&DebuggerUsermodeModulesRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Getting the modules details
+ //
+ UserAccessGetLoadedModules(DebuggerUsermodeModulesRequest, OutBuffLength);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(OutBuffLength, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_QUERY_COUNT_OF_ACTIVE_PROCESSES_OR_THREADS:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS,
+ (PVOID *)&DebuggerUsermodeProcessOrThreadQueryRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Getting the count result
+ //
+ if (DebuggerUsermodeProcessOrThreadQueryRequest->QueryType == DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_QUERY_PROCESS_COUNT)
+ {
+ ProcessQueryCount(DebuggerUsermodeProcessOrThreadQueryRequest);
+ }
+ else if (DebuggerUsermodeProcessOrThreadQueryRequest->QueryType == DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_QUERY_THREAD_COUNT)
+ {
+ ThreadQueryCount(DebuggerUsermodeProcessOrThreadQueryRequest);
+ }
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_GET_LIST_OF_THREADS_AND_PROCESSES:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS,
+ (PVOID *)&DebuggerUsermodeProcessOrThreadQueryRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Getting the list of processes or threads
+ //
+ if (DebuggerUsermodeProcessOrThreadQueryRequest->QueryType == DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_QUERY_PROCESS_LIST)
+ {
+ ProcessQueryList(DebuggerUsermodeProcessOrThreadQueryRequest,
+ DebuggerUsermodeProcessOrThreadQueryRequest,
+ OutBuffLength);
+ }
+ else if (DebuggerUsermodeProcessOrThreadQueryRequest->QueryType == DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_QUERY_THREAD_LIST)
+ {
+ ThreadQueryList(DebuggerUsermodeProcessOrThreadQueryRequest,
+ DebuggerUsermodeProcessOrThreadQueryRequest,
+ OutBuffLength);
+ }
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(OutBuffLength, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_QUERY_CURRENT_THREAD:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET,
+ (PVOID *)&GetInformationThreadRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Get the information
+ //
+ ThreadQueryDetails(GetInformationThreadRequest);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_QUERY_CURRENT_PROCESS:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET,
+ (PVOID *)&GetInformationProcessRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Get the information
+ //
+ ProcessQueryDetails(GetInformationProcessRequest);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_REQUEST_REV_MACHINE_SERVICE:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_REVERSING_MACHINE_RECONSTRUCT_MEMORY_REQUEST,
+ (PVOID *)&RevServiceRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Perform the service request
+ //
+ ConfigureInitializeExecTrapOnAllProcessors();
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_REVERSING_MACHINE_RECONSTRUCT_MEMORY_REQUEST, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_DEBUGGER_BRING_PAGES_IN:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_PAGE_IN_REQUEST,
+ (PVOID *)&DebuggerPageinRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Both usermode and to send to usermode and the coming buffer are
+ // at the same place (it's in VMI-mode)
+ //
+ DebuggerCommandBringPagein(DebuggerPageinRequest);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_PAGE_IN_REQUEST, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_PCIE_ENDPOINT_ENUM:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET,
+ (PVOID *)&PcitreeRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Both usermode and to send to usermode and the coming buffer are
+ // at the same place (it's in VMI-mode)
+ //
+ ExtensionCommandPcitree(PcitreeRequest, FALSE);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_PCIDEVINFO_ENUM:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET,
+ (PVOID *)&PcidevinfoRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Both usermode and to send to usermode and the coming buffer are
+ // at the same place (it's in VMI-mode)
+ //
+ ExtensionCommandPcidevinfo(PcidevinfoRequest, FALSE);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ default:
+ LogError("Err, unknown IOCTL");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+ }
+
+ return Status;
+}
+
+/**
+ * @brief IOCTL Dispatcher for HyperTrace IOCTLs
+ *
+ * @param Irp
+ * @param IrpStack
+ * @param DoNotChangeInformation
+ * @return NTSTATUS
+ */
+NTSTATUS
+DrvDispatchHyperTraceIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN * DoNotChangeInformation)
+{
+ PHYPERTRACE_LBR_OPERATION_PACKETS HyperTraceLbrOperationRequest;
+ PHYPERTRACE_LBR_DUMP_PACKETS HyperTraceLbrdumpRequest;
+ PHYPERTRACE_PT_OPERATION_PACKETS HyperTracePtOperationRequest;
+ PHYPERTRACE_PT_MMAP_PACKETS HyperTracePtMmapRequest;
+ ULONG InBuffLength;
+ ULONG OutBuffLength;
+ NTSTATUS Status = STATUS_SUCCESS;
+ UINT32 Ioctl = IrpStack->Parameters.DeviceIoControl.IoControlCode;
+
+ switch (Ioctl)
+ {
+ case IOCTL_PERFORM_HYPERTRACE_UNLOAD:
+
+ //
+ // Perform the unload of HyperTrace (there is no parameter for this IOCTL)
+ //
+ LoaderUninitHyperTrace();
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(0, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_PERFORM_HYPERTRACE_LBR_OPERATION:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_HYPERTRACE_LBR_OPERATION_PACKETS,
+ (PVOID *)&HyperTraceLbrOperationRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Perform the HyperTrace LBR operation
+ //
+ HyperTraceLbrPerformOperation(HyperTraceLbrOperationRequest);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_HYPERTRACE_LBR_OPERATION_PACKETS, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_PERFORM_HYPERTRACE_LBR_DUMP:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_HYPERTRACE_LBR_DUMP_PACKETS,
+ (PVOID *)&HyperTraceLbrdumpRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Perform the HyperTrace LBR dump operation
+ //
+ HyperTraceLbrPerformDump(HyperTraceLbrdumpRequest);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_HYPERTRACE_LBR_DUMP_PACKETS, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_PERFORM_HYPERTRACE_PT_OPERATION:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_HYPERTRACE_PT_OPERATION_PACKETS,
+ (PVOID *)&HyperTracePtOperationRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // If the caller asked to filter by a process id (and didn't
+ // already provide an explicit CR3), resolve the PID to the CR3
+ // the PT engine should match here — hyperkd owns the NT_KPROCESS
+ // layout, whereas the hypertrace engine only consumes a CR3. The
+ // kernel/user CR3 is chosen based on the requested trace mode so
+ // it works whether or not KVA shadowing (KPTI) is enabled.
+ //
+ if (HyperTracePtOperationRequest->EnableOptions.Pid != 0 &&
+ HyperTracePtOperationRequest->EnableOptions.Cr3 == 0)
+ {
+ HyperTracePtOperationRequest->EnableOptions.Cr3 =
+ DrvResolvePtTargetCr3(HyperTracePtOperationRequest->EnableOptions.Pid,
+ (BOOLEAN)(HyperTracePtOperationRequest->FilterOptions.TraceUser != 0),
+ (BOOLEAN)(HyperTracePtOperationRequest->FilterOptions.TraceKernel != 0));
+ }
+
+ //
+ // Perform the HyperTrace PT operation
+ //
+ HyperTracePtPerformOperation(HyperTracePtOperationRequest);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_HYPERTRACE_PT_OPERATION_PACKETS, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ case IOCTL_PERFORM_HYPERTRACE_PT_MMAP:
+
+ //
+ // Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
+ //
+ if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_HYPERTRACE_PT_MMAP_PACKETS,
+ (PVOID *)&HyperTracePtMmapRequest,
+ Irp,
+ IrpStack,
+ &InBuffLength,
+ &OutBuffLength))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Map the per-CPU PT output buffers into the calling user process
+ //
+ HyperTracePtMmap(HyperTracePtMmapRequest);
+
+ //
+ // Adjust the status and output size
+ //
+ DrvAdjustStatusAndSetOutputSize(SIZEOF_HYPERTRACE_PT_MMAP_PACKETS, DoNotChangeInformation, Irp, &Status);
+
+ break;
+
+ default:
+ LogError("Err, unknown IOCTL");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+ }
+
+ return Status;
+}
+
+/**
+ * @brief Driver IOCTL Dispatcher
+ *
+ * @param DeviceObject
+ * @param Irp
+ * @return NTSTATUS
+ */
+NTSTATUS
+DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+ UNREFERENCED_PARAMETER(DeviceObject);
+
+ PIO_STACK_LOCATION IrpStack;
+ NTSTATUS Status = STATUS_SUCCESS;
+ BOOLEAN DoNotChangeInformation = FALSE;
+ UINT32 Ioctl = 0;
+ ULONG IoctlFunction = 0;
//
// Here's the best place to see if there is any allocation pending
- // to be allcated as we're in PASSIVE_LEVEL
+ // to be allocated as we're in PASSIVE_LEVEL
//
PoolManagerCheckAndPerformAllocationAndDeallocation();
- if (g_AllowIOCTLFromUsermode)
+ //
+ // Get the current stack location of the IRP to access the parameters of the IOCTL request
+ //
+ IrpStack = IoGetCurrentIrpStackLocation(Irp);
+
+ //
+ // Get the IOCTL code from the parameters
+ //
+ Ioctl = IrpStack->Parameters.DeviceIoControl.IoControlCode;
+
+ //
+ // If we don't allow IOCTL from user-mode, we just complete the request with success, and return
+ //
+ if (!IoctlCheckIoctlAllowed(Ioctl))
{
- IrpStack = IoGetCurrentIrpStackLocation(Irp);
-
- switch (IrpStack->Parameters.DeviceIoControl.IoControlCode)
- {
- case IOCTL_REGISTER_EVENT:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_REGISTER_EVENT || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- //
- // IRPs supply a pointer to a buffer at Irp->AssociatedIrp.SystemBuffer.
- // This buffer represents both the input buffer and the output buffer that
- // are specified in calls to DeviceIoControl
- //
- RegisterEventRequest = (PREGISTER_NOTIFY_BUFFER)Irp->AssociatedIrp.SystemBuffer;
-
- switch (RegisterEventRequest->Type)
- {
- case IRP_BASED:
-
- LogRegisterIrpBasedNotification((PVOID)Irp, &Status);
-
- break;
- case EVENT_BASED:
-
- if (LogRegisterEventBasedNotification((PVOID)Irp))
- {
- Status = STATUS_SUCCESS;
- }
- else
- {
- Status = STATUS_UNSUCCESSFUL;
- }
-
- break;
- default:
- LogError("Err, unknown notification type from user-mode");
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- break;
-
- case IOCTL_RETURN_IRP_PENDING_PACKETS_AND_DISALLOW_IOCTL:
-
- //
- // Dis-allow new IOCTL
- //
- g_AllowIOCTLFromUsermode = FALSE;
-
- //
- // Send an immediate message, and we're no longer get new IRP
- //
- LogCallbackSendBuffer(OPERATION_HYPERVISOR_DRIVER_END_OF_IRPS,
- "$",
- sizeof(CHAR),
- TRUE);
-
- Status = STATUS_SUCCESS;
-
- break;
-
- case IOCTL_TERMINATE_VMX:
-
- //
- // Uninitialize the debugger and its sub-mechanisms
- //
- DebuggerUninitialize();
-
- //
- // Terminate VMX
- //
- VmFuncUninitVmm();
-
- Status = STATUS_SUCCESS;
-
- break;
-
- case IOCTL_DEBUGGER_READ_MEMORY:
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGER_READ_MEMORY || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- DebuggerReadMemRequest = (PDEBUGGER_READ_MEMORY)Irp->AssociatedIrp.SystemBuffer;
-
- if (DebuggerCommandReadMemory(DebuggerReadMemRequest,
- ((CHAR *)DebuggerReadMemRequest) + SIZEOF_DEBUGGER_READ_MEMORY,
- &ReturnSize) == TRUE)
- {
- //
- // Return the header a read bytes
- //
- Irp->IoStatus.Information = ReturnSize + SIZEOF_DEBUGGER_READ_MEMORY;
- }
- else
- {
- //
- // Just return the header to the user-mode
- //
- Irp->IoStatus.Information = SIZEOF_DEBUGGER_READ_MEMORY;
- }
-
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_DEBUGGER_READ_OR_WRITE_MSR:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGER_READ_AND_WRITE_ON_MSR || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- DebuggerReadOrWriteMsrRequest = (PDEBUGGER_READ_AND_WRITE_ON_MSR)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Only the rdmsr needs and output buffer
- //
- if (DebuggerReadOrWriteMsrRequest->ActionType != DEBUGGER_MSR_WRITE)
- {
- if (!OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- Status = DebuggerReadOrWriteMsr(DebuggerReadOrWriteMsrRequest, (UINT64 *)DebuggerReadOrWriteMsrRequest, &ReturnSize);
-
- //
- // Set the size
- //
- if (Status == STATUS_SUCCESS)
- {
- Irp->IoStatus.Information = ReturnSize;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
- }
-
- break;
-
- case IOCTL_DEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- DebuggerPteRequest = (PDEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place (it's not in vmx-root)
- //
- ExtensionCommandPte(DebuggerPteRequest, FALSE);
-
- Irp->IoStatus.Information = SIZEOF_DEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_DEBUGGER_REGISTER_EVENT:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(DEBUGGER_GENERAL_EVENT_DETAIL) || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- DebuggerNewEventRequest = (PDEBUGGER_GENERAL_EVENT_DETAIL)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place (not coming from the VMX-root mode)
- //
- DebuggerParseEvent(DebuggerNewEventRequest,
- (PDEBUGGER_EVENT_AND_ACTION_RESULT)Irp->AssociatedIrp.SystemBuffer,
- FALSE);
-
- Irp->IoStatus.Information = sizeof(DEBUGGER_EVENT_AND_ACTION_RESULT);
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_DEBUGGER_ADD_ACTION_TO_EVENT:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(DEBUGGER_GENERAL_ACTION) || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- DebuggerNewActionRequest = (PDEBUGGER_GENERAL_ACTION)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- DebuggerParseAction(DebuggerNewActionRequest,
- (PDEBUGGER_EVENT_AND_ACTION_RESULT)Irp->AssociatedIrp.SystemBuffer,
- FALSE);
-
- Irp->IoStatus.Information = sizeof(DEBUGGER_EVENT_AND_ACTION_RESULT);
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_DEBUGGER_HIDE_AND_UNHIDE_TO_TRANSPARENT_THE_DEBUGGER:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- DebuggerHideAndUnhideRequest = (PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // check if it's a !hide or !unhide command
- //
- if (DebuggerHideAndUnhideRequest->IsHide == TRUE)
- {
- //
- // It's a hide request
- //
- TransparentHideDebuggerWrapper(DebuggerHideAndUnhideRequest);
- }
- else
- {
- //
- // It's a unhide request
- //
- TransparentUnhideDebuggerWrapper(DebuggerHideAndUnhideRequest);
- }
-
- //
- // Set size
- //
- Irp->IoStatus.Information = SIZEOF_DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_DEBUGGER_VA2PA_AND_PA2VA_COMMANDS:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGER_VA2PA_AND_PA2VA_COMMANDS || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- DebuggerVa2paAndPa2vaRequest = (PDEBUGGER_VA2PA_AND_PA2VA_COMMANDS)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place (we're not in vmx-root here)
- //
- ExtensionCommandVa2paAndPa2va(DebuggerVa2paAndPa2vaRequest, FALSE);
-
- //
- // Configure IRP status
- //
- Irp->IoStatus.Information = SIZEOF_DEBUGGER_VA2PA_AND_PA2VA_COMMANDS;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_DEBUGGER_EDIT_MEMORY:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGER_EDIT_MEMORY || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Cast buffer to understandable buffer
- //
- DebuggerEditMemoryRequest = (PDEBUGGER_EDIT_MEMORY)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Here we should validate whether the input parameter is
- // valid or in other words whether we received enough space or not
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength != SIZEOF_DEBUGGER_EDIT_MEMORY + DebuggerEditMemoryRequest->CountOf64Chunks * sizeof(UINT64))
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- DebuggerCommandEditMemory(DebuggerEditMemoryRequest);
-
- //
- // Configure IRP status
- //
- Irp->IoStatus.Information = SIZEOF_DEBUGGER_EDIT_MEMORY;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_DEBUGGER_SEARCH_MEMORY:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGER_SEARCH_MEMORY || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- //
- // The OutBuffLength should have at least MaximumSearchResults * sizeof(UINT64)
- // free space to store the results
- //
- if (!InBuffLength || OutBuffLength < MaximumSearchResults * sizeof(UINT64))
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Cast buffer to understandable buffer
- //
- DebuggerSearchMemoryRequest = (PDEBUGGER_SEARCH_MEMORY)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Here we should validate whether the input parameter is
- // valid or in other words whether we received enough space or not
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength != SIZEOF_DEBUGGER_SEARCH_MEMORY + DebuggerSearchMemoryRequest->CountOf64Chunks * sizeof(UINT64))
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- if (DebuggerCommandSearchMemory(DebuggerSearchMemoryRequest) != STATUS_SUCCESS)
- {
- //
- // It is because it was not valid in any of the ways to the function
- // then we're sure that the usermode code won't interpret it's previous
- // buffer as a valid buffer and will not show it to the user
- //
- RtlZeroMemory(DebuggerSearchMemoryRequest, MaximumSearchResults * sizeof(UINT64));
- }
-
- //
- // Configure IRP status, and also we send the results
- // buffer, with it's null values (if any)
- //
- Irp->IoStatus.Information = MaximumSearchResults * sizeof(UINT64);
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_DEBUGGER_MODIFY_EVENTS:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(DEBUGGER_MODIFY_EVENTS) || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- DebuggerModifyEventRequest = (PDEBUGGER_MODIFY_EVENTS)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- DebuggerParseEventsModification(DebuggerModifyEventRequest, FALSE, EnableInstantEventMechanism ? g_KernelDebuggerState : FALSE);
-
- Irp->IoStatus.Information = SIZEOF_DEBUGGER_MODIFY_EVENTS;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_DEBUGGER_FLUSH_LOGGING_BUFFERS:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGER_FLUSH_LOGGING_BUFFERS || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- DebuggerFlushBuffersRequest = (PDEBUGGER_FLUSH_LOGGING_BUFFERS)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Perform the flush
- //
- DebuggerCommandFlush(DebuggerFlushBuffersRequest);
-
- Irp->IoStatus.Information = SIZEOF_DEBUGGER_FLUSH_LOGGING_BUFFERS;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- DebuggerAttachOrDetachToThreadRequest = (PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Perform the attach to the target process
- //
- AttachingTargetProcess(DebuggerAttachOrDetachToThreadRequest);
-
- Irp->IoStatus.Information = SIZEOF_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_PREPARE_DEBUGGEE:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGER_PREPARE_DEBUGGEE || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- DebuggeeRequest = (PDEBUGGER_PREPARE_DEBUGGEE)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Perform the action
- //
- SerialConnectionPrepare(DebuggeeRequest);
-
- Irp->IoStatus.Information = SIZEOF_DEBUGGER_PREPARE_DEBUGGEE;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_PAUSE_PACKET_RECEIVED:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGER_PAUSE_PACKET_RECEIVED || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- DebuggerPauseKernelRequest = (PDEBUGGER_PAUSE_PACKET_RECEIVED)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Perform the action
- //
- KdHaltSystem(DebuggerPauseKernelRequest);
-
- Irp->IoStatus.Information = SIZEOF_DEBUGGER_PAUSE_PACKET_RECEIVED;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_SEND_SIGNAL_EXECUTION_IN_DEBUGGEE_FINISHED:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGER_SEND_COMMAND_EXECUTION_FINISHED_SIGNAL || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- DebuggerCommandExecutionFinishedRequest = (PDEBUGGER_SEND_COMMAND_EXECUTION_FINISHED_SIGNAL)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Perform the signal operation
- //
- DebuggerCommandSignalExecutionState(DebuggerCommandExecutionFinishedRequest);
-
- Irp->IoStatus.Information = SIZEOF_DEBUGGER_SEND_COMMAND_EXECUTION_FINISHED_SIGNAL;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_SEND_USERMODE_MESSAGES_TO_DEBUGGER:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGER_SEND_USERMODE_MESSAGES_TO_DEBUGGER || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- DebuggerSendUsermodeMessageRequest = (PDEBUGGER_SEND_USERMODE_MESSAGES_TO_DEBUGGER)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Second validation phase
- //
- if (DebuggerSendUsermodeMessageRequest->Length == NULL_ZERO ||
- IrpStack->Parameters.DeviceIoControl.InputBufferLength != SIZEOF_DEBUGGER_SEND_USERMODE_MESSAGES_TO_DEBUGGER + DebuggerSendUsermodeMessageRequest->Length)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Perform the signal operation
- //
- DebuggerCommandSendMessage(DebuggerSendUsermodeMessageRequest);
-
- Irp->IoStatus.Information = SIZEOF_DEBUGGER_SEND_USERMODE_MESSAGES_TO_DEBUGGER;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_SEND_GENERAL_BUFFER_FROM_DEBUGGEE_TO_DEBUGGER:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- DebuggerSendBufferFromDebuggeeToDebuggerRequest = (PDEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Second validation phase
- //
- if (DebuggerSendBufferFromDebuggeeToDebuggerRequest->LengthOfBuffer == NULL_ZERO ||
- IrpStack->Parameters.DeviceIoControl.InputBufferLength != SIZEOF_DEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER + DebuggerSendBufferFromDebuggeeToDebuggerRequest->LengthOfBuffer)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Perform the signal operation
- //
- DebuggerCommandSendGeneralBufferToDebugger(DebuggerSendBufferFromDebuggeeToDebuggerRequest);
-
- Irp->IoStatus.Information = SIZEOF_DEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_PERFROM_KERNEL_SIDE_TESTS:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGER_PERFORM_KERNEL_TESTS || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- DebuggerKernelTestRequest = (PDEBUGGER_PERFORM_KERNEL_TESTS)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Perform the kernel-side tests
- //
- TestKernelPerformTests(DebuggerKernelTestRequest);
-
- Irp->IoStatus.Information = SIZEOF_DEBUGGER_PERFORM_KERNEL_TESTS;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_RESERVE_PRE_ALLOCATED_POOLS:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGER_PREALLOC_COMMAND || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- DebuggerReservePreallocPoolRequest = (PDEBUGGER_PREALLOC_COMMAND)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Perform the reservation pools
- //
- DebuggerCommandReservePreallocatedPools(DebuggerReservePreallocPoolRequest);
-
- Irp->IoStatus.Information = SIZEOF_DEBUGGER_PREALLOC_COMMAND;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_PREACTIVATE_FUNCTIONALITY:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGER_PREACTIVATE_COMMAND || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- DebuggerPreactivationRequest = (PDEBUGGER_PREACTIVATE_COMMAND)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Perform the activation of the functionality
- //
- DebuggerCommandPreactivateFunctionality(DebuggerPreactivationRequest);
-
- Irp->IoStatus.Information = SIZEOF_DEBUGGER_PREACTIVATE_COMMAND;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_PERFROM_ACTIONS_ON_APIC:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGER_APIC_REQUEST || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- DebuggerApicRequest = (PDEBUGGER_APIC_REQUEST)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Perform the actions relating to the APIC request
- //
- Irp->IoStatus.Information = ExtensionCommandPerformActionsForApicRequests(DebuggerApicRequest);
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_QUERY_IDT_ENTRY:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS ||
- Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- DebuggerQueryIdtRequest = (PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Perform the query of IDT entries (not from vmx-root)
- //
- ExtensionCommandPerformQueryIdtEntriesRequest(DebuggerQueryIdtRequest, FALSE);
-
- Irp->IoStatus.Information = SIZEOF_INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_SET_BREAKPOINT_USER_DEBUGGER:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGEE_BP_PACKET ||
- Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- DebuggerBreakpointRequest = (PDEBUGGEE_BP_PACKET)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Perform setting the breakpoint (for the user mode debugger)
- // Switching to the target process memory is needed as we are
- // in HyperDbg's process memory layout and we need to switch to
- // the target process memory layout to set the breakpoint
- //
- BreakpointAddNew(DebuggerBreakpointRequest, TRUE);
-
- Irp->IoStatus.Information = SIZEOF_DEBUGGEE_BP_PACKET;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_SEND_USER_DEBUGGER_COMMANDS:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(DEBUGGER_UD_COMMAND_PACKET) || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- DebuggerUdCommandRequest = (PDEBUGGER_UD_COMMAND_PACKET)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Perform the dispatching of user debugger command
- //
- UdDispatchUsermodeCommands(DebuggerUdCommandRequest);
-
- Irp->IoStatus.Information = sizeof(DEBUGGER_UD_COMMAND_PACKET);
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_GET_DETAIL_OF_ACTIVE_THREADS_AND_PROCESSES:
-
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode is here
- //
- BufferToStoreThreadsAndProcessesDetails = (PVOID)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Perform the dispatching of user debugger command
- //
- AttachingQueryDetailsOfActiveDebuggingThreadsAndProcesses(BufferToStoreThreadsAndProcessesDetails, OutBuffLength);
-
- Irp->IoStatus.Information = OutBuffLength;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_GET_USER_MODE_MODULE_DETAILS:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(USERMODE_LOADED_MODULE_DETAILS) || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- DebuggerUsermodeModulesRequest = (PUSERMODE_LOADED_MODULE_DETAILS)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Getting the modules details
- //
- UserAccessGetLoadedModules(DebuggerUsermodeModulesRequest, OutBuffLength);
-
- Irp->IoStatus.Information = OutBuffLength;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_QUERY_COUNT_OF_ACTIVE_PROCESSES_OR_THREADS:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS) || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- DebuggerUsermodeProcessOrThreadQueryRequest = (PDEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Getting the count result
- //
- if (DebuggerUsermodeProcessOrThreadQueryRequest->QueryType == DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_QUERY_PROCESS_COUNT)
- {
- ProcessQueryCount(DebuggerUsermodeProcessOrThreadQueryRequest);
- }
- else if (DebuggerUsermodeProcessOrThreadQueryRequest->QueryType == DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_QUERY_THREAD_COUNT)
- {
- ThreadQueryCount(DebuggerUsermodeProcessOrThreadQueryRequest);
- }
-
- Irp->IoStatus.Information = SIZEOF_DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_GET_LIST_OF_THREADS_AND_PROCESSES:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS) || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- DebuggerUsermodeProcessOrThreadQueryRequest = (PDEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Getting the list of processes or threads
- //
- if (DebuggerUsermodeProcessOrThreadQueryRequest->QueryType == DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_QUERY_PROCESS_LIST)
- {
- ProcessQueryList(DebuggerUsermodeProcessOrThreadQueryRequest,
- DebuggerUsermodeProcessOrThreadQueryRequest,
- OutBuffLength);
- }
- else if (DebuggerUsermodeProcessOrThreadQueryRequest->QueryType == DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS_QUERY_THREAD_LIST)
- {
- ThreadQueryList(DebuggerUsermodeProcessOrThreadQueryRequest,
- DebuggerUsermodeProcessOrThreadQueryRequest,
- OutBuffLength);
- }
-
- Irp->IoStatus.Information = OutBuffLength;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_QUERY_CURRENT_THREAD:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- GetInformationThreadRequest = (PDEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Get the information
- //
- ThreadQueryDetails(GetInformationThreadRequest);
-
- Irp->IoStatus.Information = SIZEOF_DEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_QUERY_CURRENT_PROCESS:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- GetInformationProcessRequest = (PDEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Get the information
- //
- ProcessQueryDetails(GetInformationProcessRequest);
-
- Irp->IoStatus.Information = SIZEOF_DEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_REQUEST_REV_MACHINE_SERVICE:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_REVERSING_MACHINE_RECONSTRUCT_MEMORY_REQUEST || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength || !OutBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place
- //
- RevServiceRequest = (PREVERSING_MACHINE_RECONSTRUCT_MEMORY_REQUEST)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Perform the service request
- //
- ConfigureInitializeExecTrapOnAllProcessors();
-
- Irp->IoStatus.Information = SIZEOF_REVERSING_MACHINE_RECONSTRUCT_MEMORY_REQUEST;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_DEBUGGER_BRING_PAGES_IN:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGER_PAGE_IN_REQUEST || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- DebuggerPageinRequest = (PDEBUGGER_PAGE_IN_REQUEST)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place (it's in VMI-mode)
- //
- DebuggerCommandBringPagein(DebuggerPageinRequest);
-
- Irp->IoStatus.Information = SIZEOF_DEBUGGER_PAGE_IN_REQUEST;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_PCIE_ENDPOINT_ENUM:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- PcitreeRequest = (PDEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place (it's in VMI-mode)
- //
- ExtensionCommandPcitree(PcitreeRequest, FALSE);
-
- Irp->IoStatus.Information = SIZEOF_DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- case IOCTL_PCIDEVINFO_ENUM:
-
- //
- // First validate the parameters.
- //
- if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_DEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET || Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- LogError("Err, invalid parameter to IOCTL dispatcher");
- break;
- }
-
- InBuffLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- OutBuffLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- if (!InBuffLength)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- PcidevinfoRequest = (PDEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET)Irp->AssociatedIrp.SystemBuffer;
-
- //
- // Both usermode and to send to usermode and the coming buffer are
- // at the same place (it's in VMI-mode)
- //
- ExtensionCommandPcidevinfo(PcidevinfoRequest, FALSE);
-
- Irp->IoStatus.Information = SIZEOF_DEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET;
- Status = STATUS_SUCCESS;
-
- //
- // Avoid zeroing it
- //
- DoNotChangeInformation = TRUE;
-
- break;
-
- default:
- LogError("Err, unknown IOCTL");
- Status = STATUS_NOT_IMPLEMENTED;
- break;
- }
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_SUCCESS;
+ }
+
+ //
+ // Dispatch to the appropriate handler based on the IOCTL range
+ //
+ IoctlFunction = CTL_CODE_FUNCTION(Ioctl);
+
+ if (IoctlFunction > IOCTL_BASIC_IOCTL && IoctlFunction <= IOCTL_BASIC_IOCTL + 0x100)
+ {
+ Status = DrvDispatchBasicIoControl(Irp, IrpStack, &DoNotChangeInformation);
+ }
+ else if (IoctlFunction > IOCTL_KD_IOCTL && IoctlFunction <= IOCTL_KD_IOCTL + 0x100)
+ {
+ Status = DrvDispatchKdIoControl(Irp, IrpStack, &DoNotChangeInformation);
+ }
+ else if (IoctlFunction > IOCTL_VMM_IOCTL && IoctlFunction <= IOCTL_VMM_IOCTL + 0x100)
+ {
+ Status = DrvDispatchVmmIoControl(Irp, IrpStack, &DoNotChangeInformation);
+ }
+ else if (IoctlFunction > IOCTL_HYPERTRACE_IOCTL && IoctlFunction <= IOCTL_HYPERTRACE_IOCTL + 0x100)
+ {
+ Status = DrvDispatchHyperTraceIoControl(Irp, IrpStack, &DoNotChangeInformation);
}
else
{
- //
- // We're no longer serve IOCTL
- //
- Status = STATUS_SUCCESS;
+ Status = STATUS_NOT_IMPLEMENTED;
}
if (Status != STATUS_PENDING)
diff --git a/hyperdbg/hyperkd/code/driver/Loader.c b/hyperdbg/hyperkd/code/driver/Loader.c
index 90cc6216..0ae0309d 100644
--- a/hyperdbg/hyperkd/code/driver/Loader.c
+++ b/hyperdbg/hyperkd/code/driver/Loader.c
@@ -11,59 +11,214 @@
#include "pch.h"
/**
- * @brief Initialize the VMM and Debugger
+ * @brief Initialize the hyper trace module
+ *
+ * @param RunningOnHypervisorEnvironment Whether the initialization is being done for hypervisor environment or not
*
* @return BOOLEAN
*/
BOOLEAN
-LoaderInitVmmAndDebugger()
+LoaderInitHyperTrace(PDEBUGGER_INIT_HYPERTRACE_PACKET InitHyperTracePacket, BOOLEAN RunningOnHypervisorEnvironment)
+{
+ HYPERTRACE_CALLBACKS HyperTraceCallbacks = {0};
+
+ //
+ // *** Fill the callbacks for using hypertrace ***
+ //
+
+ //
+ // Fill the callbacks for using hyperlog in hypertrace
+ // We use the callbacks directly to avoid two calls to the same function
+ //
+ HyperTraceCallbacks.LogCallbackPrepareAndSendMessageToQueueWrapper = LogCallbackPrepareAndSendMessageToQueueWrapper;
+ HyperTraceCallbacks.LogCallbackSendMessageToQueue = LogCallbackSendMessageToQueue;
+ HyperTraceCallbacks.LogCallbackSendBuffer = LogCallbackSendBuffer;
+ HyperTraceCallbacks.LogCallbackCheckIfBufferIsFull = LogCallbackCheckIfBufferIsFull;
+
+ //
+ // Fill the callbacks for using hyperhv in hypertrace
+ //
+ HyperTraceCallbacks.VmFuncVmxGetCurrentExecutionMode = VmFuncVmxGetCurrentExecutionMode;
+
+ //
+ // *** Legacy LBR callbacks ***
+ //
+
+ HyperTraceCallbacks.VmFuncCheckCpuSupportForSaveAndLoadDebugControls = VmFuncCheckCpuSupportForSaveAndLoadDebugControls;
+
+ HyperTraceCallbacks.VmFuncGetDebugctl = VmFuncGetDebugctl;
+ HyperTraceCallbacks.VmFuncGetDebugctlVmcallOnTargetCore = VmFuncGetDebugctlVmcallOnTargetCore;
+ HyperTraceCallbacks.VmFuncSetDebugctl = VmFuncSetDebugctl;
+ HyperTraceCallbacks.VmFuncSetDebugctlVmcallOnTargetCore = VmFuncSetDebugctlVmcallOnTargetCore;
+
+ HyperTraceCallbacks.VmFuncSetLoadDebugControls = VmFuncSetLoadDebugControls;
+ HyperTraceCallbacks.VmFuncSetLoadDebugControlsVmcallOnTargetCore = VmFuncSetLoadDebugControlsVmcallOnTargetCore;
+ HyperTraceCallbacks.VmFuncSetSaveDebugControls = VmFuncSetSaveDebugControls;
+ HyperTraceCallbacks.VmFuncSetSaveDebugControlsVmcallOnTargetCore = VmFuncSetSaveDebugControlsVmcallOnTargetCore;
+
+ HyperTraceCallbacks.VmFuncSetLbrSelect = VmFuncSetLbrSelect;
+ HyperTraceCallbacks.VmFuncSetLbrSelectVmcallOnTargetCore = VmFuncSetLbrSelectVmcallOnTargetCore;
+
+ //
+ // *** Architectural LBR callbacks ***
+ //
+
+ HyperTraceCallbacks.VmFuncCheckCpuSupportForLoadAndClearGuestIa32LbrCtlControls = VmFuncCheckCpuSupportForLoadAndClearGuestIa32LbrCtlControls;
+
+ HyperTraceCallbacks.VmFuncGetGuestIa32LbrCtl = VmFuncGetGuestIa32LbrCtl;
+ HyperTraceCallbacks.VmFuncGetGuestIa32LbrCtlVmcallOnTargetCore = VmFuncGetGuestIa32LbrCtlVmcallOnTargetCore;
+ HyperTraceCallbacks.VmFuncSetGuestIa32LbrCtl = VmFuncSetGuestIa32LbrCtl;
+ HyperTraceCallbacks.VmFuncSetGuestIa32LbrCtlVmcallOnTargetCore = VmFuncSetGuestIa32LbrCtlVmcallOnTargetCore;
+
+ HyperTraceCallbacks.VmFuncSetLoadGuestIa32LbrCtl = VmFuncSetLoadGuestIa32LbrCtl;
+ HyperTraceCallbacks.VmFuncSetLoadGuestIa32LbrCtlVmcallOnTargetCore = VmFuncSetLoadGuestIa32LbrCtlVmcallOnTargetCore;
+ HyperTraceCallbacks.VmFuncSetClearGuestIa32LbrCtl = VmFuncSetClearGuestIa32LbrCtl;
+ HyperTraceCallbacks.VmFuncSetClearGuestIa32LbrCtlVmcallOnTargetCore = VmFuncSetClearGuestIa32LbrCtlVmcallOnTargetCore;
+
+ //
+ // Initialize hypertrace module
+ //
+ if (HyperTraceInitCallback(&HyperTraceCallbacks, RunningOnHypervisorEnvironment))
+ {
+ LogDebugInfo("HyperDbg's hypertrace loaded successfully");
+
+ //
+ // Mark hypertrace as initialized
+ //
+ g_HyperTraceInitialized = TRUE;
+
+ //
+ // Set the kernel status to success
+ //
+ InitHyperTracePacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+
+ return TRUE;
+ }
+ else
+ {
+ //
+ // We won't fail the loading just because of hypertrace, so we just log the error and continue without loading hypertrace
+ //
+ LogDebugInfo("Err, HyperDbg's hypertrace was not loaded");
+
+ //
+ // Set the kernel status to indicate failure
+ //
+ InitHyperTracePacket->KernelStatus = DEBUGGER_ERROR_HYPERTRACE_NOT_INITIALIZED;
+
+ return FALSE;
+ }
+}
+
+/**
+ * @brief Initialize the hyper log module
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+LoaderInitHyperLog()
{
MESSAGE_TRACING_CALLBACKS MsgTracingCallbacks = {0};
- VMM_CALLBACKS VmmCallbacks = {0};
//
- // Allow to server IOCTL
- //
- g_AllowIOCTLFromUsermode = TRUE;
-
- //
- // Fill the callbacks for the message tracer
+ // *** Fill the callbacks for the message tracer ***
//
MsgTracingCallbacks.VmxOperationCheck = VmFuncVmxGetCurrentExecutionMode;
MsgTracingCallbacks.CheckImmediateMessageSending = KdCheckImmediateMessagingMechanism;
MsgTracingCallbacks.SendImmediateMessage = KdLoggingResponsePacketToDebugger;
//
- // Fill the callbacks for using hyperlog in VMM
+ // Initialize message tracer (if not already initialized)
+ //
+ if (g_HyperLogInitialized == FALSE && LogInitialize(&MsgTracingCallbacks))
+ {
+ g_HyperLogInitialized = TRUE;
+
+ LogDebugInfo("HyperDbg's hyperlog loaded successfully");
+
+ return TRUE;
+ }
+ else
+ {
+ //
+ // We use DbgPrint here because if the hyperlog is not loaded we can't use it to log the error
+ // so we just log the error with DbgPrint and continue without loading hyperlog
+ //
+ DbgPrint("Err, HyperDbg's hyperlog was not loaded or already loaded");
+ return FALSE;
+ }
+}
+
+/**
+ * @brief Initialize the VMM
+ *
+ * @param InitVmmPacket The packet to fill the result of the initialization
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+LoaderInitVmm(PDEBUGGER_INIT_VMM_PACKET InitVmmPacket)
+{
+ VMM_CALLBACKS VmmCallbacks = {0};
+
+ //
+ // Check if KD is not already initialized, if so we cannot initialize VMM
+ //
+ if (!g_KdInitialized)
+ {
+ InitVmmPacket->KernelStatus = DEBUGGER_ERROR_VMM_CANNOT_BE_INITIALIZED_IF_DEBUGGER_IS_NOT_LOADED;
+ return FALSE;
+ }
+
+ //
+ // Check if HyperTrace is already initialized, if so we cannot initialize VMM
+ //
+ if (g_HyperTraceInitialized)
+ {
+ InitVmmPacket->KernelStatus = DEBUGGER_ERROR_VMM_CANNOT_BE_INITIALIZED_IF_HYPERTRACE_IS_LOADED;
+ return FALSE;
+ }
+
+ //
+ // *** Fill the callbacks for using hyperlog in VMM ***
//
VmmCallbacks.LogCallbackPrepareAndSendMessageToQueueWrapper = LogCallbackPrepareAndSendMessageToQueueWrapper;
VmmCallbacks.LogCallbackSendMessageToQueue = LogCallbackSendMessageToQueue;
VmmCallbacks.LogCallbackSendBuffer = LogCallbackSendBuffer;
VmmCallbacks.LogCallbackCheckIfBufferIsFull = LogCallbackCheckIfBufferIsFull;
+ //
+ // Fill the HyperTrace callback(s)
+ //
+ VmmCallbacks.HyperTraceCallbackLbrIsSupported = HyperTraceLbrIsSupported;
+
//
// Fill the VMM callbacks
//
VmmCallbacks.VmmCallbackTriggerEvents = DebuggerTriggerEvents;
VmmCallbacks.VmmCallbackSetLastError = DebuggerSetLastError;
VmmCallbacks.VmmCallbackVmcallHandler = DebuggerVmcallHandler;
- VmmCallbacks.VmmCallbackRegisteredMtfHandler = KdHandleRegisteredMtfCallback;
VmmCallbacks.VmmCallbackNmiBroadcastRequestHandler = KdHandleNmiBroadcastDebugBreaks;
VmmCallbacks.VmmCallbackQueryTerminateProtectedResource = TerminateQueryDebuggerResource;
VmmCallbacks.VmmCallbackRestoreEptState = UserAccessCheckForLoadedModuleDetails;
VmmCallbacks.VmmCallbackCheckUnhandledEptViolations = AttachingCheckUnhandledEptViolation;
+ VmmCallbacks.VmmCallbackHandleMtfCallback = KdHandleMtfCallback;
//
// Fill the debugging callbacks
//
- VmmCallbacks.DebuggingCallbackHandleBreakpointException = BreakpointHandleBreakpoints;
- VmmCallbacks.DebuggingCallbackHandleDebugBreakpointException = BreakpointCheckAndHandleDebugBreakpoint;
- VmmCallbacks.BreakpointCheckAndHandleReApplyingBreakpoint = BreakpointCheckAndHandleReApplyingBreakpoint;
- VmmCallbacks.UdCheckForCommand = UdCheckForCommand;
- VmmCallbacks.DebuggerCheckProcessOrThreadChange = DebuggerCheckProcessOrThreadChange;
- VmmCallbacks.DebuggingCallbackCheckThreadInterception = AttachingCheckThreadInterceptionWithUserDebugger;
- VmmCallbacks.KdCheckAndHandleNmiCallback = KdCheckAndHandleNmiCallback;
- VmmCallbacks.KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId = KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId;
+ VmmCallbacks.DebuggingCallbackHandleBreakpointException = BreakpointHandleBreakpoints;
+ VmmCallbacks.DebuggingCallbackHandleDebugBreakpointException = BreakpointCheckAndHandleDebugBreakpoint;
+ VmmCallbacks.DebuggingCallbackCheckThreadInterception = AttachingCheckThreadInterceptionWithUserDebugger;
+ VmmCallbacks.DebuggingCallbackTriggerOnClockAndIpiEvents = DebuggerCheckProcessOrThreadChange;
+ VmmCallbacks.DebuggingCallbackIgnoreHandlingMov2DebugRegs = KdQueryIgnoreHandlingMov2DebugRegs;
+
+ //
+ // Fill the pool manager callbacks
+ //
+ VmmCallbacks.PoolManagerCallbackRequestAllocation = PoolManagerRequestAllocation;
+ VmmCallbacks.PoolManagerCallbackRequestPool = PoolManagerRequestPool;
+ VmmCallbacks.PoolManagerCallbackFreePool = PoolManagerFreePool;
//
// Fill the interception callbacks
@@ -71,70 +226,226 @@ LoaderInitVmmAndDebugger()
VmmCallbacks.InterceptionCallbackTriggerCr3ProcessChange = ProcessTriggerCr3ProcessChange;
//
- // Initialize message tracer
+ // Initialize VMX
//
- if (LogInitialize(&MsgTracingCallbacks))
+ if (VmFuncInitVmm(&VmmCallbacks))
{
+ LogDebugInfo("HyperDbg's hypervisor loaded successfully");
+
//
- // Initialize Vmx
+ // Initialize VMM opeartions (event related state from the debugger)
//
- if (VmFuncInitVmm(&VmmCallbacks))
+ if (!DebuggerInitializeVmmOperations())
{
- LogDebugInfo("HyperDbg's hypervisor loaded successfully");
-
- //
- // Initialize the debugger
- //
- if (DebuggerInitialize())
- {
- LogDebugInfo("HyperDbg's debugger loaded successfully");
-
- //
- // Set the variable so no one else can get a handle anymore
- //
- g_HandleInUse = TRUE;
-
- return TRUE;
- }
- else
- {
- LogError("Err, HyperDbg's debugger was not loaded");
- }
- }
- else
- {
- LogError("Err, HyperDbg's hypervisor was not loaded");
+ return FALSE;
}
+
+ //
+ // VMM module initialized
+ //
+ g_VmmInitialized = TRUE;
+
+ return TRUE;
}
else
{
- LogError("Err, HyperDbg's message tracing module was not loaded");
+ LogError("Err, HyperDbg's hypervisor was not loaded");
+ }
+
+ return FALSE;
+}
+
+/**
+ * @brief Initialize the debugger
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+LoaderInitKd()
+{
+ //
+ // If the debugger is already initialized, we don't need to initialize it again
+ // and simply return true
+ //
+ if (g_KdInitialized)
+ {
+ return TRUE;
}
//
- // Not loaded
+ // The debugger is not initialized, so we try to initialize it
//
- g_AllowIOCTLFromUsermode = FALSE;
+ if (DebuggerInitialize())
+ {
+ LogDebugInfo("HyperDbg's debugger loaded successfully");
+ //
+ // KD module initialized
+ //
+ g_KdInitialized = TRUE;
+
+ return TRUE;
+ }
+
+ LogError("Err, HyperDbg's debugger was not loaded");
return FALSE;
}
+/**
+ * @brief Initialize the debugger and the vmm
+ *
+ * @param InitVmmPacket The packet to fill the result of the initialization
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+LoaderInitDebuggerAndVmm(PDEBUGGER_INIT_VMM_PACKET InitVmmPacket)
+{
+ //
+ // First we need to initialize the debugger
+ // because the VMM relies on the debugger for some of its functionalities,
+ // so if we cannot initialize the debugger we cannot initialize the VMM
+ //
+ if (!LoaderInitKd())
+ {
+ //
+ // Unable to initialize the debugger, so we cannot initialize the VMM, and we return false
+ //
+ InitVmmPacket->KernelStatus = DEBUGGER_ERROR_CANNOT_INITIALIZE_DEBUGGER;
+
+ return FALSE;
+ }
+
+ //
+ // Now we can initialize the VMM
+ //
+ if (!LoaderInitVmm(InitVmmPacket))
+ {
+ return FALSE;
+ }
+
+ //
+ // Set the kernel status to success
+ //
+ InitVmmPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+
+ return TRUE;
+}
+
+/**
+ * @brief Uninitialize the hyper trace module
+ *
+ * @return VOID
+ */
+VOID
+LoaderUninitHyperTrace()
+{
+ //
+ // Mark hypertrace as uninitialized before uninitializing it to avoid any potential reentrancy issues during the uninitialization process
+ //
+ g_HyperTraceInitialized = FALSE;
+
+ //
+ // Uninitialize the hypertrace
+ //
+ HyperTraceUninit();
+}
+
+/**
+ * @brief Uninitialize the VMM
+ *
+ * @return VOID
+ */
+VOID
+LoaderUninitVmm()
+{
+ //
+ // Mark VMM as uninitialized before uninitializing it to avoid any potential reentrancy issues during the uninitialization process
+ //
+ g_VmmInitialized = FALSE;
+
+ //
+ // Uninitialize the HyperTrace (if it was initialized)
+ //
+ // If the trace module is currently loaded, it must be unloaded before the VMM module can be unloaded
+ // HyperTrace can operate both with and without the VMM module. When loaded after the VMM module, HyperTrace can make
+ // use of hypervisor-specific features. Otherwise, it will operate normally, but those features will not be available
+ // The trace module will be unloaded automatically and may be reloaded later if needed
+ //
+ // Note: The user mode should automatically request to unload the 'trace' module if it is already loaded
+ // however, here we also unload it just in case if this function is directly called or the user mode
+ // code did not unload it
+ //
+ LoaderUninitHyperTrace();
+
+ //
+ // First remove all VMM related state from the debugger
+ //
+ DebuggerUninitializeVmmOperations();
+
+ //
+ // Terminate VMM and its sub-mechanisms
+ //
+ VmFuncUninitVmm();
+}
+
+/**
+ * @brief Uninitialize the debugger
+ *
+ * @return VOID
+ */
+VOID
+LoaderUninitKd()
+{
+ //
+ // Mark KD as uninitialized before uninitializing it to avoid any potential reentrancy issues during the uninitialization process
+ //
+ g_KdInitialized = FALSE;
+
+ //
+ // Uninitialize the debugger and its sub-mechanisms
+ //
+ DebuggerUninitialize();
+}
+
+/**
+ * @brief Uninitialize the VMM and the debugger
+ *
+ * @return VOID
+ */
+VOID
+LoaderUninitVmmAndDebugger()
+{
+ //
+ // Uninitialize the VMM first because it relies on the debugger for some
+ //
+ LoaderUninitVmm();
+
+ //
+ // Uninitialize the debugger
+ //
+ LoaderUninitKd();
+}
+
/**
* @brief Uninitialize the log tracer
*
* @return VOID
*/
VOID
-LoaderUninitializeLogTracer()
+LoaderUninitLogTracer()
{
- LogDebugInfo("Unloading HyperDbg's debugger...\n");
-
#if !UseDbgPrintInsteadOfUsermodeMessageTracking
+ LogDebugInfo("Unloading hyperlog...\n");
+
//
- // Uinitialize log buffer
+ // Uinitialize log buffer if it was initialized
//
- LogDebugInfo("Uninitializing logs\n");
- LogUnInitialize();
+ if (g_HyperLogInitialized)
+ {
+ g_HyperLogInitialized = FALSE;
+ LogUnInitialize();
+ }
#endif
}
diff --git a/hyperdbg/hyperkd/header/assembly/Assembly.h b/hyperdbg/hyperkd/header/assembly/Assembly.h
index 45f19848..f68e409e 100644
--- a/hyperdbg/hyperkd/header/assembly/Assembly.h
+++ b/hyperdbg/hyperkd/header/assembly/Assembly.h
@@ -19,9 +19,14 @@
/**
* @brief Tests with test tags wrapper
*
+ * @param Param1
+ * @param Param2
+ * @param Param3
+ * @param Param4
+ * @return UINT64
*/
-extern unsigned long long
-AsmTestWrapperWithTestTags(unsigned long long Param1, unsigned long long Param2, unsigned long long Param3, unsigned long long Param4);
+extern UINT64
+AsmTestWrapperWithTestTags(UINT64 Param1, UINT64 Param2, UINT64 Param3, UINT64 Param4);
//
// ==================== Kernel Test Functions ====================
@@ -35,10 +40,10 @@ AsmTestWrapperWithTestTags(unsigned long long Param1, unsigned long long Param2,
* @param Param2
* @param Param3
* @param Param4
- * @return unsigned long long
+ * @return VOID
*/
-extern void
-AsmDebuggerCustomCodeHandler(unsigned long long Param1, unsigned long long Param2, unsigned long long Param3, unsigned long long Param4);
+extern VOID
+AsmDebuggerCustomCodeHandler(UINT64 Param1, UINT64 Param2, UINT64 Param3, UINT64 Param4);
/**
* @brief default condition code handler
@@ -46,14 +51,14 @@ AsmDebuggerCustomCodeHandler(unsigned long long Param1, unsigned long long Param
* @param Param1
* @param Param2
* @param Param3
- * @return unsigned long long
+ * @return UINT64
*/
-extern unsigned long long
-AsmDebuggerConditionCodeHandler(unsigned long long Param1, unsigned long long Param2, unsigned long long Param3);
+extern UINT64
+AsmDebuggerConditionCodeHandler(UINT64 Param1, UINT64 Param2, UINT64 Param3);
/**
* @brief Spin on thread
*
*/
-extern void
+extern VOID
AsmDebuggerSpinOnThread();
diff --git a/hyperdbg/hyperkd/header/common/Dpc.h b/hyperdbg/hyperkd/header/common/Dpc.h
deleted file mode 100644
index 30b419ec..00000000
--- a/hyperdbg/hyperkd/header/common/Dpc.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * @file Dpc.h
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief Definition for Windows DPC functions
- * @details
- * @version 0.1
- * @date 2020-04-10
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#pragma once
-
-//////////////////////////////////////////////////
-// Functions //
-//////////////////////////////////////////////////
-
-NTKERNELAPI
-_IRQL_requires_max_(APC_LEVEL)
-_IRQL_requires_min_(PASSIVE_LEVEL)
-_IRQL_requires_same_
-VOID
-KeGenericCallDpc(
- _In_ PKDEFERRED_ROUTINE Routine,
- _In_opt_ PVOID Context);
-
-NTKERNELAPI
-_IRQL_requires_(DISPATCH_LEVEL)
-_IRQL_requires_same_
-VOID
-KeSignalCallDpcDone(
- _In_ PVOID SystemArgument1);
-
-NTKERNELAPI
-_IRQL_requires_(DISPATCH_LEVEL)
-_IRQL_requires_same_
-LOGICAL
-KeSignalCallDpcSynchronize(
- _In_ PVOID SystemArgument2);
diff --git a/hyperdbg/hyperkd/header/common/Synchronization.h b/hyperdbg/hyperkd/header/common/Synchronization.h
new file mode 100644
index 00000000..6833c241
--- /dev/null
+++ b/hyperdbg/hyperkd/header/common/Synchronization.h
@@ -0,0 +1,26 @@
+/**
+ * @file Synchronization.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Routines for synchronization objects
+ * @details
+ *
+ * @version 0.16
+ * @date 2025-08-30
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+VOID
+SynchronizationInitializeEvent(PRKEVENT Event);
+
+VOID
+SynchronizationSetEvent(PRKEVENT Event);
+
+VOID
+SynchronizationWaitForEvent(PRKEVENT Event);
diff --git a/hyperdbg/hyperkd/header/debugger/broadcast/DpcRoutines.h b/hyperdbg/hyperkd/header/debugger/broadcast/DpcRoutines.h
index 0a300664..50e24308 100644
--- a/hyperdbg/hyperkd/header/debugger/broadcast/DpcRoutines.h
+++ b/hyperdbg/hyperkd/header/debugger/broadcast/DpcRoutines.h
@@ -32,3 +32,6 @@ DpcRoutineReadMsrToAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgum
VOID
DpcRoutineVmExitAndHaltSystemAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2);
+
+BOOLEAN
+DpcRoutineSetHardwareDebugRegisters(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2);
diff --git a/hyperdbg/hyperkd/header/debugger/commands/BreakpointCommands.h b/hyperdbg/hyperkd/header/debugger/commands/BreakpointCommands.h
index ada2eb9b..9fc7c4b5 100644
--- a/hyperdbg/hyperkd/header/debugger/commands/BreakpointCommands.h
+++ b/hyperdbg/hyperkd/header/debugger/commands/BreakpointCommands.h
@@ -45,7 +45,7 @@ BreakpointCheckAndHandleDebuggerDefinedBreakpoints(PROCESSOR_DEBUGGING_STATE * D
BOOLEAN ChangeMtfState);
BOOLEAN
-BreakpointCheckAndHandleReApplyingBreakpoint(UINT32 CoreId);
+BreakpointCheckAndHandleReApplyingBreakpoint(PROCESSOR_DEBUGGING_STATE * DbgState);
BOOLEAN
BreakpointCheckAndHandleDebugBreakpoint(UINT32 CoreId);
diff --git a/hyperdbg/hyperkd/header/debugger/commands/DebuggerCommands.h b/hyperdbg/hyperkd/header/debugger/commands/DebuggerCommands.h
index 586756fe..c0043a3f 100644
--- a/hyperdbg/hyperkd/header/debugger/commands/DebuggerCommands.h
+++ b/hyperdbg/hyperkd/header/debugger/commands/DebuggerCommands.h
@@ -17,6 +17,10 @@
// Functions //
//////////////////////////////////////////////////
+BOOLEAN
+DebuggerCommandReadRegisters(GUEST_REGS * Regs,
+ PDEBUGGEE_REGISTER_READ_DESCRIPTION ReadRegisterRequest);
+
BOOLEAN
DebuggerCommandReadMemory(PDEBUGGER_READ_MEMORY ReadMemRequest, PVOID UserBuffer, PSIZE_T ReturnSize);
diff --git a/hyperdbg/hyperkd/header/debugger/core/Debugger.h b/hyperdbg/hyperkd/header/debugger/core/Debugger.h
index c9bada08..3553e20a 100644
--- a/hyperdbg/hyperkd/header/debugger/core/Debugger.h
+++ b/hyperdbg/hyperkd/header/debugger/core/Debugger.h
@@ -68,6 +68,7 @@ typedef struct _DEBUGGER_CORE_EVENTS
LIST_ENTRY TrapExecutionInstructionTraceEventsHead; // TRAP_EXECUTION_INSTRUCTION_TRACE
LIST_ENTRY ControlRegister3ModifiedEventsHead; // CONTROL_REGISTER_3_MODIFIED
LIST_ENTRY ControlRegisterModifiedEventsHead; // CONTROL_REGISTER_MODIFIED
+ LIST_ENTRY XsetbvInstructionExecutionEventsHead; // XSETBV_INSTRUCTION_EXECUTION
} DEBUGGER_CORE_EVENTS, *PDEBUGGER_CORE_EVENTS;
@@ -187,9 +188,21 @@ DebuggerGetLastError();
VOID
DebuggerSetLastError(UINT32 LastError);
+BOOLEAN
+DebuggerInitializeScriptEngine();
+
+BOOLEAN
+DebuggerInitializeTrapsAndBreakpoints();
+
+BOOLEAN
+DebuggerInitializeVmmOperations();
+
BOOLEAN
DebuggerInitialize();
+VOID
+DebuggerUninitializeVmmOperations();
+
VOID
DebuggerUninitialize();
diff --git a/hyperdbg/hyperkd/header/debugger/core/State.h b/hyperdbg/hyperkd/header/debugger/core/State.h
index c5da64bf..7a41c1a0 100644
--- a/hyperdbg/hyperkd/header/debugger/core/State.h
+++ b/hyperdbg/hyperkd/header/debugger/core/State.h
@@ -105,7 +105,7 @@ typedef struct _DEBUGGER_PROCESS_THREAD_INFORMATION
{
union
{
- UINT64 asUInt;
+ UINT64 AsUInt;
struct
{
@@ -168,16 +168,17 @@ typedef struct _PROCESSOR_DEBUGGING_STATE
UINT32 CoreId;
BOOLEAN ShortCircuitingEvent;
BOOLEAN IgnoreDisasmInNextPacket;
+ BOOLEAN BreakStarterCore;
+ BOOLEAN Test; // Used for testing purposes
+ BOOLEAN DoNotNmiNotifyOtherCoresByThisCore;
+ BOOLEAN TracingMode; // Indicate that the target processor is on the tracing mode or not
PROCESSOR_DEBUGGING_MSR_READ_OR_WRITE MsrState;
DATE_TIME_HOLDER DateTimeHolder;
PDEBUGGEE_BP_DESCRIPTOR SoftwareBreakpointState;
DEBUGGEE_INSTRUMENTATION_STEP_IN_TRACE InstrumentationStepInTrace;
- BOOLEAN DoNotNmiNotifyOtherCoresByThisCore;
- BOOLEAN TracingMode; // Indicate that the target processor is on the tracing mode or not
DEBUGGEE_PROCESS_OR_THREAD_TRACING_DETAILS ThreadOrProcessTracingDetails;
KD_NMI_STATE NmiState;
DEBUGGEE_HALTED_CORE_TASK HaltedCoreTask;
- BOOLEAN BreakStarterCore;
UINT16 InstructionLengthHint;
UINT64 HardwareDebugRegisterForStepping;
UINT64 * ScriptEngineCoreSpecificStackBuffer;
diff --git a/hyperdbg/hyperkd/header/debugger/events/ApplyEvents.h b/hyperdbg/hyperkd/header/debugger/events/ApplyEvents.h
index 17238173..bde54526 100644
--- a/hyperdbg/hyperkd/header/debugger/events/ApplyEvents.h
+++ b/hyperdbg/hyperkd/header/debugger/events/ApplyEvents.h
@@ -105,3 +105,8 @@ VOID
ApplyEventTracingEvent(PDEBUGGER_EVENT Event,
PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn,
BOOLEAN InputFromVmxRoot);
+
+VOID
+ApplyEventXsetbvExecutionEvent(PDEBUGGER_EVENT Event,
+ PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn,
+ BOOLEAN InputFromVmxRoot);
diff --git a/hyperdbg/hyperkd/header/debugger/events/Termination.h b/hyperdbg/hyperkd/header/debugger/events/Termination.h
index 5e4a1669..3e240938 100644
--- a/hyperdbg/hyperkd/header/debugger/events/Termination.h
+++ b/hyperdbg/hyperkd/header/debugger/events/Termination.h
@@ -82,3 +82,6 @@ TerminateQueryDebuggerResource(UINT32 CoreId,
PROTECTED_HV_RESOURCES_TYPE ResourceType,
PVOID Context,
PROTECTED_HV_RESOURCES_PASSING_OVERS PassOver);
+
+VOID
+TerminateXsetbvExecutionEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot);
diff --git a/hyperdbg/hyperkd/header/debugger/kernel-level/Kd.h b/hyperdbg/hyperkd/header/debugger/kernel-level/Kd.h
index abfbf0f8..bf98f656 100644
--- a/hyperdbg/hyperkd/header/debugger/kernel-level/Kd.h
+++ b/hyperdbg/hyperkd/header/debugger/kernel-level/Kd.h
@@ -112,13 +112,6 @@ KdContinueDebuggee(_Inout_ PROCESSOR_DEBUGGING_STATE *
static VOID
KdContinueDebuggeeJustCurrentCore(PROCESSOR_DEBUGGING_STATE * DbgState);
-static BOOLEAN
-KdReadRegisters(_In_ PROCESSOR_DEBUGGING_STATE * DbgState,
- _Inout_ PDEBUGGEE_REGISTER_READ_DESCRIPTION ReadRegisterRequest);
-static BOOLEAN
-KdReadMemory(_In_ PGUEST_REGS Regs,
- _Inout_ PDEBUGGEE_REGISTER_READ_DESCRIPTION ReadRegisterRequest);
-
static BOOLEAN
KdSwitchCore(PROCESSOR_DEBUGGING_STATE * DbgState,
DEBUGGEE_CHANGE_CORE_PACKET * ChangeCorePacket);
@@ -135,12 +128,6 @@ KdNotifyDebuggeeForUserInput(DEBUGGEE_USER_INPUT_PACKET * Descriptor, UINT32 Len
static VOID
KdGuaranteedStepInstruction(PROCESSOR_DEBUGGING_STATE * DbgState);
-static VOID
-KdRegularStepInInstruction(PROCESSOR_DEBUGGING_STATE * DbgState);
-
-static VOID
-KdRegularStepOver(PROCESSOR_DEBUGGING_STATE * DbgState, BOOLEAN IsNextInstructionACall, UINT32 CallLength);
-
static BOOLEAN
KdPerformRegisterEvent(PDEBUGGEE_EVENT_AND_ACTION_HEADER_FOR_REMOTE_PACKET EventDetailHeader,
DEBUGGER_EVENT_AND_ACTION_RESULT * DebuggerEventAndActionResult);
@@ -180,8 +167,6 @@ KdHandleDebugEventsWhenKernelDebuggerIsAttached(PROCESSOR_DEBUGGING_STATE * DbgS
VOID
KdManageSystemHaltOnVmxRoot(PROCESSOR_DEBUGGING_STATE * DbgState,
PDEBUGGER_TRIGGERED_EVENT_DETAILS EventDetails);
-BOOLEAN
-KdCheckAndHandleNmiCallback(_In_ UINT32 CoreId);
VOID
KdHandleNmi(_Inout_ PROCESSOR_DEBUGGING_STATE * DbgState);
@@ -210,12 +195,12 @@ KdHandleBreakpointAndDebugBreakpoints(_Inout_ PROCESSOR_DEBUGGING_STATE * DbgSta
_In_ DEBUGGEE_PAUSING_REASON Reason,
PDEBUGGER_TRIGGERED_EVENT_DETAILS EventDetails);
-VOID
-KdHandleRegisteredMtfCallback(_In_ UINT32 CoreId);
-
VOID
KdHandleHaltsWhenNmiReceivedFromVmxRoot(_Inout_ PROCESSOR_DEBUGGING_STATE * DbgState);
+BOOLEAN
+KdHandleMtfCallback(UINT32 CoreId);
+
BOOLEAN
KdCheckImmediateMessagingMechanism(UINT32 OperationCode);
@@ -248,3 +233,6 @@ KdCheckTheHaltedCore(PROCESSOR_DEBUGGING_STATE * DbgState);
BOOLEAN
KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId(UINT32 CoreId,
DEBUGGER_THREAD_PROCESS_TRACING TracingType);
+
+BOOLEAN
+KdQueryIgnoreHandlingMov2DebugRegs(UINT32 CoreId);
diff --git a/hyperdbg/hyperhv/header/memory/PoolManager.h b/hyperdbg/hyperkd/header/debugger/memory/PoolManager.h
similarity index 86%
rename from hyperdbg/hyperhv/header/memory/PoolManager.h
rename to hyperdbg/hyperkd/header/debugger/memory/PoolManager.h
index 5c5dbc7b..ef4af344 100644
--- a/hyperdbg/hyperhv/header/memory/PoolManager.h
+++ b/hyperdbg/hyperkd/header/debugger/memory/PoolManager.h
@@ -76,6 +76,12 @@ volatile LONG LockForRequestAllocation;
*/
volatile LONG LockForReadingPool;
+/**
+ * @brief Pool manager memory allocator initialized
+ *
+ */
+BOOLEAN g_PoolManagerInitialized;
+
/**
* @brief We set it when there is a new allocation
*
@@ -114,18 +120,23 @@ static VOID PlmgrFreeRequestNewAllocation(VOID);
// Public Interfaces
//
-/**
- * @brief Initializes the Pool Manager and pre-allocate some pools
- *
- * @return BOOLEAN
- */
BOOLEAN
PoolManagerInitialize();
-/**
- * @brief De-allocate all the allocated pools
- *
- * @return VOID
- */
VOID
PoolManagerUninitialize();
+
+VOID
+PoolManagerShowPreAllocatedPools();
+
+BOOLEAN
+PoolManagerCheckAndPerformAllocationAndDeallocation();
+
+BOOLEAN
+PoolManagerRequestAllocation(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention);
+
+UINT64
+PoolManagerRequestPool(POOL_ALLOCATION_INTENTION Intention, BOOLEAN RequestNewPool, UINT32 Size);
+
+BOOLEAN
+PoolManagerFreePool(UINT64 AddressToFree);
diff --git a/hyperdbg/hyperkd/header/debugger/meta-events/Tracing.h b/hyperdbg/hyperkd/header/debugger/meta-events/Tracing.h
index 42eb7fb1..f444fdb8 100644
--- a/hyperdbg/hyperkd/header/debugger/meta-events/Tracing.h
+++ b/hyperdbg/hyperkd/header/debugger/meta-events/Tracing.h
@@ -28,4 +28,7 @@ VOID
TracingPerformInstrumentationStepIn(PROCESSOR_DEBUGGING_STATE * DbgState);
VOID
-TracingPerformRegularStepInInstruction(PROCESSOR_DEBUGGING_STATE * DbgState);
+TracingRegularStepInInstruction();
+
+VOID
+TracingPerformRegularStepInInstruction();
diff --git a/hyperdbg/hyperkd/header/debugger/objects/Thread.h b/hyperdbg/hyperkd/header/debugger/objects/Thread.h
index 1133e68d..b68e6fc9 100644
--- a/hyperdbg/hyperkd/header/debugger/objects/Thread.h
+++ b/hyperdbg/hyperkd/header/debugger/objects/Thread.h
@@ -38,3 +38,6 @@ ThreadQueryList(PDEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS DebuggerUsermodeProc
BOOLEAN
ThreadQueryDetails(PDEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET GetInformationThreadRequest);
+
+BOOLEAN
+ThreadQueryDebugRegisterInterceptionStateByCoreId(UINT32 CoreId);
diff --git a/hyperdbg/hyperkd/header/debugger/user-level/ThreadHolder.h b/hyperdbg/hyperkd/header/debugger/user-level/ThreadHolder.h
index f00e81db..7b59f644 100644
--- a/hyperdbg/hyperkd/header/debugger/user-level/ThreadHolder.h
+++ b/hyperdbg/hyperkd/header/debugger/user-level/ThreadHolder.h
@@ -34,6 +34,9 @@ typedef struct _USERMODE_DEBUGGING_THREAD_DETAILS
UINT32 ThreadId;
UINT64 ThreadRip; // if IsPaused is TRUE
BOOLEAN IsPaused;
+ BYTE InstructionBytesOnRip[MAXIMUM_INSTR_SIZE];
+ UINT32 SizeOfInstruction;
+ UINT64 NumberOfBlockedContextSwitches;
DEBUGGER_UD_COMMAND_ACTION UdAction[MAX_USER_ACTIONS_FOR_THREADS];
} USERMODE_DEBUGGING_THREAD_DETAILS, *PUSERMODE_DEBUGGING_THREAD_DETAILS;
diff --git a/hyperdbg/hyperkd/header/debugger/user-level/Ud.h b/hyperdbg/hyperkd/header/debugger/user-level/Ud.h
index 5b2149fd..b9134e0f 100644
--- a/hyperdbg/hyperkd/header/debugger/user-level/Ud.h
+++ b/hyperdbg/hyperkd/header/debugger/user-level/Ud.h
@@ -56,13 +56,26 @@ UdHandleInstantBreak(PROCESSOR_DEBUGGING_STATE * DbgState,
DEBUGGEE_PAUSING_REASON Reason,
PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail);
+VOID
+UdApplyHardwareDebugRegister(PVOID TargetAddress);
+
BOOLEAN
UdCheckAndHandleBreakpointsAndDebugBreaks(PROCESSOR_DEBUGGING_STATE * DbgState,
DEBUGGEE_PAUSING_REASON Reason,
PDEBUGGER_TRIGGERED_EVENT_DETAILS EventDetails);
BOOLEAN
-UdDispatchUsermodeCommands(PDEBUGGER_UD_COMMAND_PACKET ActionRequest);
+UdDispatchUsermodeCommands(PDEBUGGER_UD_COMMAND_PACKET ActionRequest,
+ UINT32 ActionRequestInputLength,
+ UINT32 ActionRequestOutputLength);
BOOLEAN
-UdCheckForCommand();
+UdCheckForCommand(PROCESSOR_DEBUGGING_STATE * DbgState,
+ PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail);
+
+BOOLEAN
+UdHandleDebugEventsWhenUserDebuggerIsAttached(PROCESSOR_DEBUGGING_STATE * DbgState,
+ BOOLEAN TrapSetByDebugger);
+
+VOID
+UdSendFormatsFunctionResult(UINT64 Value);
diff --git a/hyperdbg/hyperkd/header/debugger/user-level/UserAccess.h b/hyperdbg/hyperkd/header/debugger/user-level/UserAccess.h
index cb2c8c40..4acb1b8e 100644
--- a/hyperdbg/hyperkd/header/debugger/user-level/UserAccess.h
+++ b/hyperdbg/hyperkd/header/debugger/user-level/UserAccess.h
@@ -45,7 +45,7 @@ typedef struct _RTL_USER_PROCESS_PARAMETERS
* @brief Random windows type
*
*/
-typedef void(__stdcall * PPS_POST_PROCESS_INIT_ROUTINE)(void); // not exported
+typedef VOID(__stdcall * PPS_POST_PROCESS_INIT_ROUTINE)(VOID); // not exported
/**
* @brief PEB 64-bit
diff --git a/hyperdbg/hyperkd/header/driver/Driver.h b/hyperdbg/hyperkd/header/driver/Driver.h
index b5739220..e3233b0b 100644
--- a/hyperdbg/hyperkd/header/driver/Driver.h
+++ b/hyperdbg/hyperkd/header/driver/Driver.h
@@ -45,3 +45,15 @@ DrvUnsupported(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS
DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+
+NTSTATUS
+DrvDispatchBasicIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN * DoNotChangeInformation);
+
+NTSTATUS
+DrvDispatchKdIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN * DoNotChangeInformation);
+
+NTSTATUS
+DrvDispatchVmmIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN * DoNotChangeInformation);
+
+NTSTATUS
+DrvDispatchHyperTraceIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN * DoNotChangeInformation);
diff --git a/hyperdbg/hyperkd/header/driver/Loader.h b/hyperdbg/hyperkd/header/driver/Loader.h
index 955231cf..6d34e67d 100644
--- a/hyperdbg/hyperkd/header/driver/Loader.h
+++ b/hyperdbg/hyperkd/header/driver/Loader.h
@@ -17,7 +17,19 @@
//////////////////////////////////////////////////
BOOLEAN
-LoaderInitVmmAndDebugger();
+LoaderInitHyperLog();
+
+BOOLEAN
+LoaderInitHyperTrace(PDEBUGGER_INIT_HYPERTRACE_PACKET InitHyperTracePacket, BOOLEAN RunningOnHypervisorEnvironment);
+
+BOOLEAN
+LoaderInitDebuggerAndVmm(PDEBUGGER_INIT_VMM_PACKET InitVmmPacket);
VOID
-LoaderUninitializeLogTracer();
+LoaderUninitVmmAndDebugger();
+
+VOID
+LoaderUninitHyperTrace();
+
+VOID
+LoaderUninitLogTracer();
diff --git a/hyperdbg/hyperkd/header/globals/Global.h b/hyperdbg/hyperkd/header/globals/Global.h
index 0c25aee7..02195709 100644
--- a/hyperdbg/hyperkd/header/globals/Global.h
+++ b/hyperdbg/hyperkd/header/globals/Global.h
@@ -16,6 +16,54 @@
*/
PROCESSOR_DEBUGGING_STATE * g_DbgState;
+/**
+ * @brief Shows whether the hyperlog module is initialized or not
+ *
+ */
+BOOLEAN g_HyperLogInitialized;
+
+/**
+ * @brief Shows whether the KD module is initialized or not
+ *
+ */
+BOOLEAN g_KdInitialized;
+
+/**
+ * @brief Shows whether the VMM is initialized or not
+ *
+ */
+BOOLEAN g_VmmInitialized;
+
+/**
+ * @brief Shows whether the hypertrace module is initialized or not
+ *
+ */
+BOOLEAN g_HyperTraceInitialized;
+
+/**
+ * @brief Event to show whether the user debugger is waiting for a command or not
+ *
+ */
+KEVENT g_UserDebuggerWaitingCommandEvent;
+
+/**
+ * @brief Buffer to hold the command from user debugger
+ *
+ */
+PVOID g_UserDebuggerWaitingCommandBuffer;
+
+/**
+ * @brief Length of the input command buffer from user debugger
+ *
+ */
+UINT32 g_UserDebuggerWaitingCommandInputBufferLength;
+
+/**
+ * @brief Length of the output command buffer from user debugger
+ *
+ */
+UINT32 g_UserDebuggerWaitingCommandOutputBufferLength;
+
/**
* @brief Holder of script engines global variables
*
@@ -35,12 +83,6 @@ DEBUGGER_TRAP_FLAG_STATE g_TrapFlagState;
*/
BOOLEAN g_HandleInUse;
-/**
- * @brief Determines whether the clients are allowed to send IOCTL to the drive or not
- *
- */
-BOOLEAN g_AllowIOCTLFromUsermode;
-
/**
* @brief events list (for debugger)
*
@@ -60,6 +102,12 @@ DEBUGGEE_REQUEST_TO_IGNORE_BREAKS_UNTIL_AN_EVENT g_IgnoreBreaksToDebugger;
*/
HARDWARE_DEBUG_REGISTER_DETAILS g_HardwareDebugRegisterDetailsForStepOver;
+/**
+ * @brief Holds the result of user debugger formats command
+ *
+ */
+DEBUGGEE_FORMATS_PACKET g_UserDebuggerFormatsResultPacket;
+
/**
* @brief Process switch to EPROCESS or Process ID
*
@@ -82,7 +130,7 @@ UINT32 g_LastError;
* @brief Determines whether the debugger events should be active or not
*
*/
-BOOLEAN g_EnableDebuggerEvents;
+BOOLEAN g_EnableDebuggerVmxEvents;
/**
* @brief List header of breakpoints for debugger-mode
diff --git a/hyperdbg/hyperkd/header/pch.h b/hyperdbg/hyperkd/header/pch.h
index 0f59a783..630ee6b9 100644
--- a/hyperdbg/hyperkd/header/pch.h
+++ b/hyperdbg/hyperkd/header/pch.h
@@ -22,9 +22,9 @@
//
// Environment headers
//
-#include "platform/kernel/header/Environment.h"
+#include "platform/general/header/Environment.h"
-#ifdef ENV_WINDOWS
+#ifdef HYPERDBG_ENV_WINDOWS
//
// General WDK headers
@@ -33,7 +33,7 @@
# include
# include
-#endif // ENV_WINDOWS
+#endif // HYPERDBG_ENV_WINDOWS
//
// Definition of Intel primitives (External header)
@@ -84,7 +84,11 @@
//
// Platform independent headers
//
-#include "platform/kernel/header/Mem.h"
+#include "platform/kernel/header/PlatformMem.h"
+#include "platform/kernel/header/PlatformIntrinsics.h"
+#include "platform/kernel/header/PlatformBroadcast.h"
+#include "platform/kernel/header/PlatformProcess.h"
+#include "platform/kernel/header/PlatformCpu.h"
//
// Optimization algorithms
@@ -110,6 +114,8 @@
#include "header/debugger/script-engine/ScriptEngine.h"
#include "header/debugger/memory/Memory.h"
#include "header/common/Common.h"
+#include "header/common/Synchronization.h"
+#include "header/debugger/memory/PoolManager.h"
#include "header/debugger/memory/Allocations.h"
#include "header/debugger/kernel-level/Kd.h"
#include "header/debugger/user-level/Ud.h"
@@ -133,11 +139,6 @@
#include "header/debugger/broadcast/HaltedRoutines.h"
#include "header/debugger/broadcast/HaltedBroadcast.h"
-//
-// DPC Headers
-//
-#include "header/common/Dpc.h"
-
//
// Events & Meta events
//
@@ -153,6 +154,12 @@
//
#include "../script-eval/header/ScriptEngineHeader.h"
+//
+// Tracing (hypertrace) headers
+//
+#include "SDK/modules/HyperTrace.h"
+#include "SDK/imports/kernel/HyperDbgHyperTrace.h"
+
//
// Global variables
//
diff --git a/hyperdbg/hyperkd/hyperkd.vcxproj b/hyperdbg/hyperkd/hyperkd.vcxproj
index a756dd53..b165f75d 100644
--- a/hyperdbg/hyperkd/hyperkd.vcxproj
+++ b/hyperdbg/hyperkd/hyperkd.vcxproj
@@ -1,5 +1,8 @@
+
+
+ debug
@@ -27,7 +30,7 @@
WindowsKernelModeDriver10.0DriverKMDF
- Universal
+ Desktopfalse
@@ -36,7 +39,7 @@
WindowsKernelModeDriver10.0DriverKMDF
- Universal
+ Desktopfalse
@@ -51,13 +54,16 @@
DbgengKernelDebugger$(SolutionDir)build\bin\$(Configuration)\$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\
- true
+
+
+ falseDbgengKernelDebugger$(SolutionDir)build\bin\$(Configuration)\$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\
- true
+
+ false
@@ -76,7 +82,7 @@
trueDriverEntry
- $(SolutionDir)build\bin\$(Configuration)\hyperlog.lib;$(SolutionDir)build\bin\$(Configuration)\hyperhv.lib;$(SolutionDir)build\bin\$(Configuration)\kdserial.lib;%(AdditionalDependencies)
+ $(SolutionDir)build\bin\$(Configuration)\hyperlog.lib;$(SolutionDir)build\bin\$(Configuration)\hyperhv.lib;$(SolutionDir)build\bin\$(Configuration)\kdserial.lib;$(SolutionDir)build\bin\$(Configuration)\hypertrace.lib;%(AdditionalDependencies)
@@ -91,12 +97,12 @@
Createpch.hstdcpp20
- Disabled
+ FulltrueDriverEntry
- $(SolutionDir)build\bin\$(Configuration)\hyperlog.lib;$(SolutionDir)build\bin\$(Configuration)\hyperhv.lib;$(SolutionDir)build\bin\$(Configuration)\kdserial.lib;%(AdditionalDependencies)
+ $(SolutionDir)build\bin\$(Configuration)\hyperlog.lib;$(SolutionDir)build\bin\$(Configuration)\hyperhv.lib;$(SolutionDir)build\bin\$(Configuration)\kdserial.lib;$(SolutionDir)build\bin\$(Configuration)\hypertrace.lib;%(AdditionalDependencies)
@@ -108,13 +114,18 @@
-
+
+
+
+
+
+
@@ -132,6 +143,7 @@
+
@@ -153,11 +165,14 @@
-
-
+
+
+
+
+
-
+
@@ -177,6 +192,7 @@
+
@@ -195,7 +211,20 @@
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/hyperkd/hyperkd.vcxproj.filters b/hyperdbg/hyperkd/hyperkd.vcxproj.filters
index f403ffcf..8a1a1c5b 100644
--- a/hyperdbg/hyperkd/hyperkd.vcxproj.filters
+++ b/hyperdbg/hyperkd/hyperkd.vcxproj.filters
@@ -261,9 +261,27 @@
code\debugger\meta-events
-
+ code\platform
+
+ code\common
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\debugger\memory
+
@@ -347,9 +365,6 @@
header\macros
-
- header\common
- header\assembly
@@ -392,16 +407,34 @@
header\debugger\meta-events
-
+ header\platform
-
+
+ header\common
+
+ header\platform
+
+ header\platform
+
+
+ header\platform
+
+
+ header\platform
+
+
+ header\debugger\memory
+ code\assembly
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/hyperkd/packages.config b/hyperdbg/hyperkd/packages.config
new file mode 100644
index 00000000..eb276766
--- /dev/null
+++ b/hyperdbg/hyperkd/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/hyperlog/CMakeLists.txt b/hyperdbg/hyperlog/CMakeLists.txt
index b760f0f4..d6e772a5 100644
--- a/hyperdbg/hyperlog/CMakeLists.txt
+++ b/hyperdbg/hyperlog/CMakeLists.txt
@@ -1,12 +1,12 @@
# Code generated by Visual Studio kit, DO NOT EDIT.
set(SourceFiles
"../include/components/spinlock/code/Spinlock.c"
- "../include/platform/kernel/code/Mem.c"
+ "../include/platform/kernel/code/PlatformMem.c"
"code/Logging.c"
"code/UnloadDll.c"
"../include/components/spinlock/header/Spinlock.h"
"../include/platform/kernel/header/Environment.h"
- "../include/platform/kernel/header/Mem.h"
+ "../include/platform/kernel/header/PlatformMem.h"
"header/Logging.h"
"header/pch.h"
"header/UnloadDll.h"
diff --git a/hyperdbg/hyperlog/code/Logging.c b/hyperdbg/hyperlog/code/Logging.c
index ae30cbd8..1cc3111f 100644
--- a/hyperdbg/hyperlog/code/Logging.c
+++ b/hyperdbg/hyperlog/code/Logging.c
@@ -99,42 +99,42 @@ LogInitialize(MESSAGE_TRACING_CALLBACKS * MsgTracingCallbacks)
{
ULONG ProcessorsCount;
- ProcessorsCount = KeQueryActiveProcessorCount(0);
+ ProcessorsCount = PlatformCpuGetActiveProcessorCount();
//
// Initialize buffers for trace message and data messages
//(we have two buffers one for vmx root and one for vmx non-root)
//
- MessageBufferInformation = PlatformMemAllocateZeroedNonPagedPool(sizeof(LOG_BUFFER_INFORMATION) * 2);
+ g_MessageBufferInformation = PlatformMemAllocateZeroedNonPagedPool(sizeof(LOG_BUFFER_INFORMATION) * 2);
- if (!MessageBufferInformation)
+ if (!g_MessageBufferInformation)
{
return FALSE; // STATUS_INSUFFICIENT_RESOURCES
}
//
- // Allocate VmxTempMessage and VmxLogMessage
+ // Allocate g_VmxTempMessage and g_VmxLogMessage
//
- VmxTempMessage = NULL;
- VmxTempMessage = PlatformMemAllocateZeroedNonPagedPool(PacketChunkSize * ProcessorsCount);
+ g_VmxTempMessage = NULL;
+ g_VmxTempMessage = PlatformMemAllocateZeroedNonPagedPool(PacketChunkSize * ProcessorsCount);
- if (!VmxTempMessage)
+ if (!g_VmxTempMessage)
{
- PlatformMemFreePool(MessageBufferInformation);
- MessageBufferInformation = NULL;
+ PlatformMemFreePool(g_MessageBufferInformation);
+ g_MessageBufferInformation = NULL;
return FALSE; // STATUS_INSUFFICIENT_RESOURCES
}
- VmxLogMessage = NULL;
- VmxLogMessage = PlatformMemAllocateZeroedNonPagedPool(PacketChunkSize * ProcessorsCount);
+ g_VmxLogMessage = NULL;
+ g_VmxLogMessage = PlatformMemAllocateZeroedNonPagedPool(PacketChunkSize * ProcessorsCount);
- if (!VmxLogMessage)
+ if (!g_VmxLogMessage)
{
- PlatformMemFreePool(MessageBufferInformation);
- MessageBufferInformation = NULL;
+ PlatformMemFreePool(g_MessageBufferInformation);
+ g_MessageBufferInformation = NULL;
- PlatformMemFreePool(VmxTempMessage);
- VmxTempMessage = NULL;
+ PlatformMemFreePool(g_VmxTempMessage);
+ g_VmxTempMessage = NULL;
return FALSE; // STATUS_INSUFFICIENT_RESOURCES
}
@@ -142,12 +142,12 @@ LogInitialize(MESSAGE_TRACING_CALLBACKS * MsgTracingCallbacks)
//
// Initialize the lock for Vmx-root mode (HIGH_IRQL Spinlock)
//
- VmxRootLoggingLock = 0;
+ g_VmxRootLoggingLock = 0;
//
// Allocate buffer for messages and initialize the core buffer information
//
- for (int i = 0; i < 2; i++)
+ for (UINT32 i = 0; i < 2; i++)
{
//
// initialize the lock
@@ -155,17 +155,17 @@ LogInitialize(MESSAGE_TRACING_CALLBACKS * MsgTracingCallbacks)
// for both but the second buffer spinlock is useless
// as we use our custom spinlock
//
- KeInitializeSpinLock(&MessageBufferInformation[i].BufferLock);
- KeInitializeSpinLock(&MessageBufferInformation[i].BufferLockForNonImmMessage);
+ PlatformSpinlockInitialize(&g_MessageBufferInformation[i].BufferLock);
+ PlatformSpinlockInitialize(&g_MessageBufferInformation[i].BufferLockForNonImmMessage);
//
// allocate the buffer for regular buffers
//
- MessageBufferInformation[i].BufferStartAddress = (UINT64)PlatformMemAllocateNonPagedPool(LogBufferSize);
- MessageBufferInformation[i].BufferForMultipleNonImmediateMessage = (UINT64)PlatformMemAllocateNonPagedPool(PacketChunkSize);
+ g_MessageBufferInformation[i].BufferStartAddress = (UINT64)PlatformMemAllocateNonPagedPool(LogBufferSize);
+ g_MessageBufferInformation[i].BufferForMultipleNonImmediateMessage = (UINT64)PlatformMemAllocateNonPagedPool(PacketChunkSize);
- if (!MessageBufferInformation[i].BufferStartAddress ||
- !MessageBufferInformation[i].BufferForMultipleNonImmediateMessage)
+ if (!g_MessageBufferInformation[i].BufferStartAddress ||
+ !g_MessageBufferInformation[i].BufferForMultipleNonImmediateMessage)
{
return FALSE; // STATUS_INSUFFICIENT_RESOURCES
}
@@ -173,9 +173,9 @@ LogInitialize(MESSAGE_TRACING_CALLBACKS * MsgTracingCallbacks)
//
// allocate the buffer for priority buffers
//
- MessageBufferInformation[i].BufferStartAddressPriority = (UINT64)PlatformMemAllocateNonPagedPool(LogBufferSizePriority);
+ g_MessageBufferInformation[i].BufferStartAddressPriority = (UINT64)PlatformMemAllocateNonPagedPool(LogBufferSizePriority);
- if (!MessageBufferInformation[i].BufferStartAddressPriority)
+ if (!g_MessageBufferInformation[i].BufferStartAddressPriority)
{
return FALSE; // STATUS_INSUFFICIENT_RESOURCES
}
@@ -183,21 +183,21 @@ LogInitialize(MESSAGE_TRACING_CALLBACKS * MsgTracingCallbacks)
//
// Zeroing the buffer
//
- RtlZeroMemory((void *)MessageBufferInformation[i].BufferStartAddress, LogBufferSize);
- RtlZeroMemory((void *)MessageBufferInformation[i].BufferForMultipleNonImmediateMessage, PacketChunkSize);
- RtlZeroMemory((void *)MessageBufferInformation[i].BufferStartAddressPriority, LogBufferSizePriority);
+ PlatformZeroMemory((PVOID)g_MessageBufferInformation[i].BufferStartAddress, LogBufferSize);
+ PlatformZeroMemory((PVOID)g_MessageBufferInformation[i].BufferForMultipleNonImmediateMessage, PacketChunkSize);
+ PlatformZeroMemory((PVOID)g_MessageBufferInformation[i].BufferStartAddressPriority, LogBufferSizePriority);
//
// Set the end address
//
- MessageBufferInformation[i].BufferEndAddress = (UINT64)MessageBufferInformation[i].BufferStartAddress + LogBufferSize;
- MessageBufferInformation[i].BufferEndAddressPriority = (UINT64)MessageBufferInformation[i].BufferStartAddressPriority + LogBufferSizePriority;
+ g_MessageBufferInformation[i].BufferEndAddress = (UINT64)g_MessageBufferInformation[i].BufferStartAddress + LogBufferSize;
+ g_MessageBufferInformation[i].BufferEndAddressPriority = (UINT64)g_MessageBufferInformation[i].BufferStartAddressPriority + LogBufferSizePriority;
}
//
// Copy the callbacks into the global callback holder
//
- RtlCopyBytes(&g_MsgTracingCallbacks, MsgTracingCallbacks, sizeof(MESSAGE_TRACING_CALLBACKS));
+ PlatformWriteMemory(&g_MsgTracingCallbacks, MsgTracingCallbacks, sizeof(MESSAGE_TRACING_CALLBACKS));
return TRUE;
}
@@ -218,7 +218,7 @@ LogUnInitialize()
//
// Check if the buffer is allocated or not
//
- if (MessageBufferInformation == NULL64_ZERO)
+ if (g_MessageBufferInformation == NULL64_ZERO)
{
continue; // No need to free the buffers
}
@@ -226,29 +226,29 @@ LogUnInitialize()
//
// Free each buffers
//
- if (MessageBufferInformation[i].BufferStartAddress != NULL64_ZERO)
+ if (g_MessageBufferInformation[i].BufferStartAddress != NULL64_ZERO)
{
- PlatformMemFreePool((PVOID)MessageBufferInformation[i].BufferStartAddress);
+ PlatformMemFreePool((PVOID)g_MessageBufferInformation[i].BufferStartAddress);
}
- if (MessageBufferInformation[i].BufferStartAddressPriority != NULL64_ZERO)
+ if (g_MessageBufferInformation[i].BufferStartAddressPriority != NULL64_ZERO)
{
- PlatformMemFreePool((PVOID)MessageBufferInformation[i].BufferStartAddressPriority);
+ PlatformMemFreePool((PVOID)g_MessageBufferInformation[i].BufferStartAddressPriority);
}
- if (MessageBufferInformation[i].BufferForMultipleNonImmediateMessage != NULL64_ZERO)
+ if (g_MessageBufferInformation[i].BufferForMultipleNonImmediateMessage != NULL64_ZERO)
{
- PlatformMemFreePool((PVOID)MessageBufferInformation[i].BufferForMultipleNonImmediateMessage);
+ PlatformMemFreePool((PVOID)g_MessageBufferInformation[i].BufferForMultipleNonImmediateMessage);
}
}
//
// de-allocate buffers for trace message and data messages if they are allocated
//
- if (MessageBufferInformation != NULL64_ZERO)
+ if (g_MessageBufferInformation != NULL64_ZERO)
{
- PlatformMemFreePool((PVOID)MessageBufferInformation);
- MessageBufferInformation = NULL;
+ PlatformMemFreePool((PVOID)g_MessageBufferInformation);
+ g_MessageBufferInformation = NULL;
}
}
@@ -291,9 +291,9 @@ LogCallbackCheckIfBufferIsFull(BOOLEAN Priority)
//
if (Priority)
{
- CurrentIndexToWritePriority = MessageBufferInformation[Index].CurrentIndexToWritePriority;
+ CurrentIndexToWritePriority = g_MessageBufferInformation[Index].CurrentIndexToWritePriority;
- if (MessageBufferInformation[Index].CurrentIndexToWritePriority > MaximumPacketsCapacityPriority - 1)
+ if (g_MessageBufferInformation[Index].CurrentIndexToWritePriority > MaximumPacketsCapacityPriority - 1)
{
//
// start from the beginning
@@ -303,9 +303,9 @@ LogCallbackCheckIfBufferIsFull(BOOLEAN Priority)
}
else
{
- CurrentIndexToWrite = MessageBufferInformation[Index].CurrentIndexToWrite;
+ CurrentIndexToWrite = g_MessageBufferInformation[Index].CurrentIndexToWrite;
- if (MessageBufferInformation[Index].CurrentIndexToWrite > MaximumPacketsCapacity - 1)
+ if (g_MessageBufferInformation[Index].CurrentIndexToWrite > MaximumPacketsCapacity - 1)
{
//
// start from the beginning
@@ -321,11 +321,11 @@ LogCallbackCheckIfBufferIsFull(BOOLEAN Priority)
if (Priority)
{
- Header = (BUFFER_HEADER *)((UINT64)MessageBufferInformation[Index].BufferStartAddressPriority + (CurrentIndexToWritePriority * (PacketChunkSize + sizeof(BUFFER_HEADER))));
+ Header = (BUFFER_HEADER *)((UINT64)g_MessageBufferInformation[Index].BufferStartAddressPriority + (CurrentIndexToWritePriority * (PacketChunkSize + sizeof(BUFFER_HEADER))));
}
else
{
- Header = (BUFFER_HEADER *)((UINT64)MessageBufferInformation[Index].BufferStartAddress + (CurrentIndexToWrite * (PacketChunkSize + sizeof(BUFFER_HEADER))));
+ Header = (BUFFER_HEADER *)((UINT64)g_MessageBufferInformation[Index].BufferStartAddress + (CurrentIndexToWrite * (PacketChunkSize + sizeof(BUFFER_HEADER))));
}
//
@@ -384,7 +384,7 @@ LogCallbackSendBuffer(UINT32 OperationCode, PVOID Buffer, UINT32 BufferLength, B
//
// vmx non-root
//
- OldIRQL = KeRaiseIrqlToDpcLevel();
+ OldIRQL = PlatformIrqlRaiseToDpcLevel();
}
//
@@ -403,7 +403,7 @@ LogCallbackSendBuffer(UINT32 OperationCode, PVOID Buffer, UINT32 BufferLength, B
//
// vmx non-root
//
- KeLowerIrql(OldIRQL);
+ PlatformIrqlLower(OldIRQL);
}
return TRUE;
@@ -419,7 +419,7 @@ LogCallbackSendBuffer(UINT32 OperationCode, PVOID Buffer, UINT32 BufferLength, B
// Set the index
//
Index = 1;
- SpinlockLock(&VmxRootLoggingLock);
+ SpinlockLock(&g_VmxRootLoggingLock);
}
else
{
@@ -431,7 +431,7 @@ LogCallbackSendBuffer(UINT32 OperationCode, PVOID Buffer, UINT32 BufferLength, B
//
// Acquire the lock
//
- KeAcquireSpinLock(&MessageBufferInformation[Index].BufferLock, &OldIRQL);
+ PlatformSpinlockAcquire(&g_MessageBufferInformation[Index].BufferLock, &OldIRQL);
}
//
@@ -439,22 +439,22 @@ LogCallbackSendBuffer(UINT32 OperationCode, PVOID Buffer, UINT32 BufferLength, B
//
if (Priority)
{
- if (MessageBufferInformation[Index].CurrentIndexToWritePriority > MaximumPacketsCapacityPriority - 1)
+ if (g_MessageBufferInformation[Index].CurrentIndexToWritePriority > MaximumPacketsCapacityPriority - 1)
{
//
// start from the beginning
//
- MessageBufferInformation[Index].CurrentIndexToWritePriority = 0;
+ g_MessageBufferInformation[Index].CurrentIndexToWritePriority = 0;
}
}
else
{
- if (MessageBufferInformation[Index].CurrentIndexToWrite > MaximumPacketsCapacity - 1)
+ if (g_MessageBufferInformation[Index].CurrentIndexToWrite > MaximumPacketsCapacity - 1)
{
//
// start from the beginning
//
- MessageBufferInformation[Index].CurrentIndexToWrite = 0;
+ g_MessageBufferInformation[Index].CurrentIndexToWrite = 0;
}
}
@@ -465,11 +465,11 @@ LogCallbackSendBuffer(UINT32 OperationCode, PVOID Buffer, UINT32 BufferLength, B
if (Priority)
{
- Header = (BUFFER_HEADER *)((UINT64)MessageBufferInformation[Index].BufferStartAddressPriority + (MessageBufferInformation[Index].CurrentIndexToWritePriority * (PacketChunkSize + sizeof(BUFFER_HEADER))));
+ Header = (BUFFER_HEADER *)((UINT64)g_MessageBufferInformation[Index].BufferStartAddressPriority + (g_MessageBufferInformation[Index].CurrentIndexToWritePriority * (PacketChunkSize + sizeof(BUFFER_HEADER))));
}
else
{
- Header = (BUFFER_HEADER *)((UINT64)MessageBufferInformation[Index].BufferStartAddress + (MessageBufferInformation[Index].CurrentIndexToWrite * (PacketChunkSize + sizeof(BUFFER_HEADER))));
+ Header = (BUFFER_HEADER *)((UINT64)g_MessageBufferInformation[Index].BufferStartAddress + (g_MessageBufferInformation[Index].CurrentIndexToWrite * (PacketChunkSize + sizeof(BUFFER_HEADER))));
}
//
@@ -490,28 +490,28 @@ LogCallbackSendBuffer(UINT32 OperationCode, PVOID Buffer, UINT32 BufferLength, B
if (Priority)
{
- SavingBuffer = (PVOID)((UINT64)MessageBufferInformation[Index].BufferStartAddressPriority + (MessageBufferInformation[Index].CurrentIndexToWritePriority * (PacketChunkSize + sizeof(BUFFER_HEADER))) + sizeof(BUFFER_HEADER));
+ SavingBuffer = (PVOID)((UINT64)g_MessageBufferInformation[Index].BufferStartAddressPriority + (g_MessageBufferInformation[Index].CurrentIndexToWritePriority * (PacketChunkSize + sizeof(BUFFER_HEADER))) + sizeof(BUFFER_HEADER));
}
else
{
- SavingBuffer = (PVOID)((UINT64)MessageBufferInformation[Index].BufferStartAddress + (MessageBufferInformation[Index].CurrentIndexToWrite * (PacketChunkSize + sizeof(BUFFER_HEADER))) + sizeof(BUFFER_HEADER));
+ SavingBuffer = (PVOID)((UINT64)g_MessageBufferInformation[Index].BufferStartAddress + (g_MessageBufferInformation[Index].CurrentIndexToWrite * (PacketChunkSize + sizeof(BUFFER_HEADER))) + sizeof(BUFFER_HEADER));
}
//
// Copy the buffer
//
- RtlCopyBytes(SavingBuffer, Buffer, BufferLength);
+ PlatformWriteMemory(SavingBuffer, Buffer, BufferLength);
//
// Increment the next index to write
//
if (Priority)
{
- MessageBufferInformation[Index].CurrentIndexToWritePriority = MessageBufferInformation[Index].CurrentIndexToWritePriority + 1;
+ g_MessageBufferInformation[Index].CurrentIndexToWritePriority = g_MessageBufferInformation[Index].CurrentIndexToWritePriority + 1;
}
else
{
- MessageBufferInformation[Index].CurrentIndexToWrite = MessageBufferInformation[Index].CurrentIndexToWrite + 1;
+ g_MessageBufferInformation[Index].CurrentIndexToWrite = g_MessageBufferInformation[Index].CurrentIndexToWrite + 1;
}
//
@@ -531,7 +531,7 @@ LogCallbackSendBuffer(UINT32 OperationCode, PVOID Buffer, UINT32 BufferLength, B
//
// Insert dpc to queue
//
- KeInsertQueueDpc(&g_GlobalNotifyRecord->Dpc, g_GlobalNotifyRecord, NULL);
+ PlatformDpcInsertQueueDpc(&g_GlobalNotifyRecord->Dpc, g_GlobalNotifyRecord, NULL);
//
// set notify routine to null
@@ -545,14 +545,14 @@ LogCallbackSendBuffer(UINT32 OperationCode, PVOID Buffer, UINT32 BufferLength, B
//
if (IsVmxRoot)
{
- SpinlockUnlock(&VmxRootLoggingLock);
+ SpinlockUnlock(&g_VmxRootLoggingLock);
}
else
{
//
// Release the lock
//
- KeReleaseSpinLock(&MessageBufferInformation[Index].BufferLock, OldIRQL);
+ PlatformSpinlockRelease(&g_MessageBufferInformation[Index].BufferLock, OldIRQL);
}
return TRUE;
@@ -586,7 +586,7 @@ LogMarkAllAsRead(BOOLEAN IsVmxRoot)
//
// Acquire the lock
//
- SpinlockLock(&VmxRootLoggingLock);
+ SpinlockLock(&g_VmxRootLoggingLock);
}
else
{
@@ -598,19 +598,19 @@ LogMarkAllAsRead(BOOLEAN IsVmxRoot)
//
// Acquire the lock
//
- KeAcquireSpinLock(&MessageBufferInformation[Index].BufferLock, &OldIRQL);
+ PlatformSpinlockAcquire(&g_MessageBufferInformation[Index].BufferLock, &OldIRQL);
}
//
// We have iterate through the all indexes
//
- for (size_t i = 0; i < MaximumPacketsCapacity; i++)
+ for (SIZE_T i = 0; i < MaximumPacketsCapacity; i++)
{
//
// Compute the current buffer to read
//
- BUFFER_HEADER * Header = (BUFFER_HEADER *)((UINT64)MessageBufferInformation[Index].BufferStartAddress +
- (MessageBufferInformation[Index].CurrentIndexToSend *
+ BUFFER_HEADER * Header = (BUFFER_HEADER *)((UINT64)g_MessageBufferInformation[Index].BufferStartAddress +
+ (g_MessageBufferInformation[Index].CurrentIndexToSend *
(PacketChunkSize + sizeof(BUFFER_HEADER))));
if (!Header->Valid)
@@ -625,14 +625,14 @@ LogMarkAllAsRead(BOOLEAN IsVmxRoot)
//
if (IsVmxRoot)
{
- SpinlockUnlock(&VmxRootLoggingLock);
+ SpinlockUnlock(&g_VmxRootLoggingLock);
}
else
{
//
// Release the lock
//
- KeReleaseSpinLock(&MessageBufferInformation[Index].BufferLock, OldIRQL);
+ PlatformSpinlockRelease(&g_MessageBufferInformation[Index].BufferLock, OldIRQL);
}
return ResultsOfBuffersSetToRead;
@@ -646,7 +646,7 @@ LogMarkAllAsRead(BOOLEAN IsVmxRoot)
//
// Second, save the buffer contents
//
- PVOID SendingBuffer = (PVOID)((UINT64)MessageBufferInformation[Index].BufferStartAddress + (MessageBufferInformation[Index].CurrentIndexToSend * (PacketChunkSize + sizeof(BUFFER_HEADER))) + sizeof(BUFFER_HEADER));
+ PVOID SendingBuffer = (PVOID)((UINT64)g_MessageBufferInformation[Index].BufferStartAddress + (g_MessageBufferInformation[Index].CurrentIndexToSend * (PacketChunkSize + sizeof(BUFFER_HEADER))) + sizeof(BUFFER_HEADER));
//
// Finally, set the current index to invalid as we sent it
@@ -658,21 +658,21 @@ LogMarkAllAsRead(BOOLEAN IsVmxRoot)
// there might be multiple messages on the start of the queue that didn't read yet)
// we don't free the header
//
- RtlZeroMemory(SendingBuffer, Header->BufferLength);
+ PlatformZeroMemory(SendingBuffer, Header->BufferLength);
//
// Check to see whether we passed the index or not
//
- if (MessageBufferInformation[Index].CurrentIndexToSend > MaximumPacketsCapacity - 2)
+ if (g_MessageBufferInformation[Index].CurrentIndexToSend > MaximumPacketsCapacity - 2)
{
- MessageBufferInformation[Index].CurrentIndexToSend = 0;
+ g_MessageBufferInformation[Index].CurrentIndexToSend = 0;
}
else
{
//
// Increment the next index to read
//
- MessageBufferInformation[Index].CurrentIndexToSend = MessageBufferInformation[Index].CurrentIndexToSend + 1;
+ g_MessageBufferInformation[Index].CurrentIndexToSend = g_MessageBufferInformation[Index].CurrentIndexToSend + 1;
}
}
@@ -682,14 +682,14 @@ LogMarkAllAsRead(BOOLEAN IsVmxRoot)
//
if (IsVmxRoot)
{
- SpinlockUnlock(&VmxRootLoggingLock);
+ SpinlockUnlock(&g_VmxRootLoggingLock);
}
else
{
//
// Release the lock
//
- KeReleaseSpinLock(&MessageBufferInformation[Index].BufferLock, OldIRQL);
+ PlatformSpinlockRelease(&g_MessageBufferInformation[Index].BufferLock, OldIRQL);
}
return ResultsOfBuffersSetToRead;
@@ -725,7 +725,7 @@ LogReadBuffer(BOOLEAN IsVmxRoot, PVOID BufferToSaveMessage, UINT32 * ReturnedLen
//
// Acquire the lock
//
- SpinlockLock(&VmxRootLoggingLock);
+ SpinlockLock(&g_VmxRootLoggingLock);
}
else
{
@@ -737,7 +737,7 @@ LogReadBuffer(BOOLEAN IsVmxRoot, PVOID BufferToSaveMessage, UINT32 * ReturnedLen
//
// Acquire the lock
//
- KeAcquireSpinLock(&MessageBufferInformation[Index].BufferLock, &OldIRQL);
+ PlatformSpinlockAcquire(&g_MessageBufferInformation[Index].BufferLock, &OldIRQL);
}
//
@@ -748,14 +748,14 @@ LogReadBuffer(BOOLEAN IsVmxRoot, PVOID BufferToSaveMessage, UINT32 * ReturnedLen
//
// Check for priority message
//
- Header = (BUFFER_HEADER *)((UINT64)MessageBufferInformation[Index].BufferStartAddressPriority + (MessageBufferInformation[Index].CurrentIndexToSendPriority * (PacketChunkSize + sizeof(BUFFER_HEADER))));
+ Header = (BUFFER_HEADER *)((UINT64)g_MessageBufferInformation[Index].BufferStartAddressPriority + (g_MessageBufferInformation[Index].CurrentIndexToSendPriority * (PacketChunkSize + sizeof(BUFFER_HEADER))));
if (!Header->Valid)
{
//
// Check for regular message
//
- Header = (BUFFER_HEADER *)((UINT64)MessageBufferInformation[Index].BufferStartAddress + (MessageBufferInformation[Index].CurrentIndexToSend * (PacketChunkSize + sizeof(BUFFER_HEADER))));
+ Header = (BUFFER_HEADER *)((UINT64)g_MessageBufferInformation[Index].BufferStartAddress + (g_MessageBufferInformation[Index].CurrentIndexToSend * (PacketChunkSize + sizeof(BUFFER_HEADER))));
if (!Header->Valid)
{
@@ -769,14 +769,14 @@ LogReadBuffer(BOOLEAN IsVmxRoot, PVOID BufferToSaveMessage, UINT32 * ReturnedLen
//
if (IsVmxRoot)
{
- SpinlockUnlock(&VmxRootLoggingLock);
+ SpinlockUnlock(&g_VmxRootLoggingLock);
}
else
{
//
// Release the lock
//
- KeReleaseSpinLock(&MessageBufferInformation[Index].BufferLock, OldIRQL);
+ PlatformSpinlockRelease(&g_MessageBufferInformation[Index].BufferLock, OldIRQL);
}
return FALSE;
@@ -794,7 +794,7 @@ LogReadBuffer(BOOLEAN IsVmxRoot, PVOID BufferToSaveMessage, UINT32 * ReturnedLen
//
// First copy the header
//
- RtlCopyBytes(BufferToSaveMessage, &Header->OperationNumber, sizeof(UINT32));
+ PlatformWriteMemory(BufferToSaveMessage, &Header->OperationNumber, sizeof(UINT32));
//
// Second, save the buffer contents
@@ -803,11 +803,11 @@ LogReadBuffer(BOOLEAN IsVmxRoot, PVOID BufferToSaveMessage, UINT32 * ReturnedLen
if (PriorityMessageIsAvailable)
{
- SendingBuffer = (PVOID)((UINT64)MessageBufferInformation[Index].BufferStartAddressPriority + (MessageBufferInformation[Index].CurrentIndexToSendPriority * (PacketChunkSize + sizeof(BUFFER_HEADER))) + sizeof(BUFFER_HEADER));
+ SendingBuffer = (PVOID)((UINT64)g_MessageBufferInformation[Index].BufferStartAddressPriority + (g_MessageBufferInformation[Index].CurrentIndexToSendPriority * (PacketChunkSize + sizeof(BUFFER_HEADER))) + sizeof(BUFFER_HEADER));
}
else
{
- SendingBuffer = (PVOID)((UINT64)MessageBufferInformation[Index].BufferStartAddress + (MessageBufferInformation[Index].CurrentIndexToSend * (PacketChunkSize + sizeof(BUFFER_HEADER))) + sizeof(BUFFER_HEADER));
+ SendingBuffer = (PVOID)((UINT64)g_MessageBufferInformation[Index].BufferStartAddress + (g_MessageBufferInformation[Index].CurrentIndexToSend * (PacketChunkSize + sizeof(BUFFER_HEADER))) + sizeof(BUFFER_HEADER));
}
//
@@ -815,7 +815,7 @@ LogReadBuffer(BOOLEAN IsVmxRoot, PVOID BufferToSaveMessage, UINT32 * ReturnedLen
//
PVOID SavingAddress = (PVOID)((UINT64)BufferToSaveMessage + sizeof(UINT32));
- RtlCopyBytes(SavingAddress, SendingBuffer, Header->BufferLength);
+ PlatformWriteMemory(SavingAddress, SendingBuffer, Header->BufferLength);
#if ShowMessagesOnDebugger
@@ -830,21 +830,21 @@ LogReadBuffer(BOOLEAN IsVmxRoot, PVOID BufferToSaveMessage, UINT32 * ReturnedLen
//
if (Header->BufferLength > DbgPrintLimitation)
{
- for (size_t i = 0; i <= Header->BufferLength / DbgPrintLimitation; i++)
+ for (SIZE_T i = 0; i <= Header->BufferLength / DbgPrintLimitation; i++)
{
if (i != 0)
{
- DbgPrint("%s", (char *)((UINT64)SendingBuffer + (DbgPrintLimitation * i) - 2));
+ PlatformDbgPrint("%s", (CHAR *)((UINT64)SendingBuffer + (DbgPrintLimitation * i) - 2));
}
else
{
- DbgPrint("%s", (char *)((UINT64)SendingBuffer + (DbgPrintLimitation * i)));
+ PlatformDbgPrint("%s", (CHAR *)((UINT64)SendingBuffer + (DbgPrintLimitation * i)));
}
}
}
else
{
- DbgPrint("%s", (char *)SendingBuffer);
+ PlatformDbgPrint("%s", (CHAR *)SendingBuffer);
}
}
#endif
@@ -864,23 +864,23 @@ LogReadBuffer(BOOLEAN IsVmxRoot, PVOID BufferToSaveMessage, UINT32 * ReturnedLen
// there might be multiple messages on the start of the queue that didn't read yet)
// we don't free the header
//
- RtlZeroMemory(SendingBuffer, Header->BufferLength);
+ PlatformZeroMemory(SendingBuffer, Header->BufferLength);
if (PriorityMessageIsAvailable)
{
//
// Check to see whether we passed the index or not
//
- if (MessageBufferInformation[Index].CurrentIndexToSendPriority > MaximumPacketsCapacityPriority - 2)
+ if (g_MessageBufferInformation[Index].CurrentIndexToSendPriority > MaximumPacketsCapacityPriority - 2)
{
- MessageBufferInformation[Index].CurrentIndexToSendPriority = 0;
+ g_MessageBufferInformation[Index].CurrentIndexToSendPriority = 0;
}
else
{
//
// Increment the next index to read
//
- MessageBufferInformation[Index].CurrentIndexToSendPriority = MessageBufferInformation[Index].CurrentIndexToSendPriority + 1;
+ g_MessageBufferInformation[Index].CurrentIndexToSendPriority = g_MessageBufferInformation[Index].CurrentIndexToSendPriority + 1;
}
}
else
@@ -888,16 +888,16 @@ LogReadBuffer(BOOLEAN IsVmxRoot, PVOID BufferToSaveMessage, UINT32 * ReturnedLen
//
// Check to see whether we passed the index or not
//
- if (MessageBufferInformation[Index].CurrentIndexToSend > MaximumPacketsCapacity - 2)
+ if (g_MessageBufferInformation[Index].CurrentIndexToSend > MaximumPacketsCapacity - 2)
{
- MessageBufferInformation[Index].CurrentIndexToSend = 0;
+ g_MessageBufferInformation[Index].CurrentIndexToSend = 0;
}
else
{
//
// Increment the next index to read
//
- MessageBufferInformation[Index].CurrentIndexToSend = MessageBufferInformation[Index].CurrentIndexToSend + 1;
+ g_MessageBufferInformation[Index].CurrentIndexToSend = g_MessageBufferInformation[Index].CurrentIndexToSend + 1;
}
}
@@ -907,14 +907,14 @@ LogReadBuffer(BOOLEAN IsVmxRoot, PVOID BufferToSaveMessage, UINT32 * ReturnedLen
//
if (IsVmxRoot)
{
- SpinlockUnlock(&VmxRootLoggingLock);
+ SpinlockUnlock(&g_VmxRootLoggingLock);
}
else
{
//
// Release the lock
//
- KeReleaseSpinLock(&MessageBufferInformation[Index].BufferLock, OldIRQL);
+ PlatformSpinlockRelease(&g_MessageBufferInformation[Index].BufferLock, OldIRQL);
}
return TRUE;
@@ -950,11 +950,11 @@ LogCheckForNewMessage(BOOLEAN IsVmxRoot, BOOLEAN Priority)
if (Priority)
{
- Header = (BUFFER_HEADER *)((UINT64)MessageBufferInformation[Index].BufferStartAddressPriority + (MessageBufferInformation[Index].CurrentIndexToSendPriority * (PacketChunkSize + sizeof(BUFFER_HEADER))));
+ Header = (BUFFER_HEADER *)((UINT64)g_MessageBufferInformation[Index].BufferStartAddressPriority + (g_MessageBufferInformation[Index].CurrentIndexToSendPriority * (PacketChunkSize + sizeof(BUFFER_HEADER))));
}
else
{
- Header = (BUFFER_HEADER *)((UINT64)MessageBufferInformation[Index].BufferStartAddress + (MessageBufferInformation[Index].CurrentIndexToSend * (PacketChunkSize + sizeof(BUFFER_HEADER))));
+ Header = (BUFFER_HEADER *)((UINT64)g_MessageBufferInformation[Index].BufferStartAddress + (g_MessageBufferInformation[Index].CurrentIndexToSend * (PacketChunkSize + sizeof(BUFFER_HEADER))));
}
if (!Header->Valid)
@@ -988,17 +988,17 @@ LogCallbackPrepareAndSendMessageToQueueWrapper(UINT32 OperationCode,
BOOLEAN IsImmediateMessage,
BOOLEAN ShowCurrentSystemTime,
BOOLEAN Priority,
- const char * Fmt,
+ const CHAR * Fmt,
va_list ArgList)
{
- int SprintfResult;
- size_t WrittenSize;
+ INT32 SprintfResult;
+ SIZE_T WrittenSize;
BOOLEAN IsVmxRootMode;
BOOLEAN Result = FALSE; // by default, we assume error happens
- char * LogMessage = NULL;
- char * TempMessage = NULL;
- char TimeBuffer[20] = {0};
- ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
+ CHAR * LogMessage = NULL;
+ CHAR * TempMessage = NULL;
+ CHAR TimeBuffer[20] = {0};
+ ULONG CurrentCore = PlatformCpuGetCurrentProcessorNumber();
//
// Set Vmx State
@@ -1011,8 +1011,8 @@ LogCallbackPrepareAndSendMessageToQueueWrapper(UINT32 OperationCode,
//
if (IsVmxRootMode)
{
- LogMessage = &VmxLogMessage[CurrentCore * PacketChunkSize];
- TempMessage = &VmxTempMessage[CurrentCore * PacketChunkSize];
+ LogMessage = &g_VmxLogMessage[CurrentCore * PacketChunkSize];
+ TempMessage = &g_VmxTempMessage[CurrentCore * PacketChunkSize];
}
else
{
@@ -1069,9 +1069,9 @@ LogCallbackPrepareAndSendMessageToQueueWrapper(UINT32 OperationCode,
//
TIME_FIELDS TimeFields;
LARGE_INTEGER SystemTime, LocalTime;
- KeQuerySystemTime(&SystemTime);
- ExSystemTimeToLocalTime(&SystemTime, &LocalTime);
- RtlTimeToTimeFields(&LocalTime, &TimeFields);
+ PlatformTimeQuerySystemTime(&SystemTime);
+ PlatformTimeConvertToLocalTime(&SystemTime, &LocalTime);
+ PlatformTimeConvertToTimeFields(&LocalTime, &TimeFields);
//
// We won't use this because we can't use in any IRQL
@@ -1179,7 +1179,7 @@ LogCallbackPrepareAndSendMessageToQueue(UINT32 OperationCode,
BOOLEAN IsImmediateMessage,
BOOLEAN ShowCurrentSystemTime,
BOOLEAN Priority,
- const char * Fmt,
+ const CHAR * Fmt,
...)
{
va_list ArgList;
@@ -1275,7 +1275,7 @@ LogCallbackSendMessageToQueue(UINT32 OperationCode, BOOLEAN IsImmediateMessage,
// Set the index
//
Index = 1;
- SpinlockLock(&VmxRootLoggingLockForNonImmBuffers);
+ SpinlockLock(&g_VmxRootLoggingLockForNonImmBuffers);
}
else
{
@@ -1287,7 +1287,7 @@ LogCallbackSendMessageToQueue(UINT32 OperationCode, BOOLEAN IsImmediateMessage,
//
// Acquire the lock
//
- KeAcquireSpinLock(&MessageBufferInformation[Index].BufferLockForNonImmMessage, &OldIRQL);
+ PlatformSpinlockAcquire(&g_MessageBufferInformation[Index].BufferLockForNonImmMessage, &OldIRQL);
}
//
// Set the result to True
@@ -1297,50 +1297,50 @@ LogCallbackSendMessageToQueue(UINT32 OperationCode, BOOLEAN IsImmediateMessage,
//
// If log message WrittenSize is above the buffer then we have to send the previous buffer
//
- if ((MessageBufferInformation[Index].CurrentLengthOfNonImmBuffer + BufferLen) > PacketChunkSize - 1 && MessageBufferInformation[Index].CurrentLengthOfNonImmBuffer != 0)
+ if ((g_MessageBufferInformation[Index].CurrentLengthOfNonImmBuffer + BufferLen) > PacketChunkSize - 1 && g_MessageBufferInformation[Index].CurrentLengthOfNonImmBuffer != 0)
{
//
// Send the previous buffer (non-immediate message),
// accumulated messages don't have priority
//
Result = LogCallbackSendBuffer(OPERATION_LOG_NON_IMMEDIATE_MESSAGE,
- (PVOID)MessageBufferInformation[Index].BufferForMultipleNonImmediateMessage,
- MessageBufferInformation[Index].CurrentLengthOfNonImmBuffer,
+ (PVOID)g_MessageBufferInformation[Index].BufferForMultipleNonImmediateMessage,
+ g_MessageBufferInformation[Index].CurrentLengthOfNonImmBuffer,
FALSE);
//
// Free the immediate buffer
//
- MessageBufferInformation[Index].CurrentLengthOfNonImmBuffer = 0;
- RtlZeroMemory((void *)MessageBufferInformation[Index].BufferForMultipleNonImmediateMessage, PacketChunkSize);
+ g_MessageBufferInformation[Index].CurrentLengthOfNonImmBuffer = 0;
+ PlatformZeroMemory((PVOID)g_MessageBufferInformation[Index].BufferForMultipleNonImmediateMessage, PacketChunkSize);
}
//
// We have to save the message
//
- RtlCopyBytes((void *)(MessageBufferInformation[Index].BufferForMultipleNonImmediateMessage +
- MessageBufferInformation[Index].CurrentLengthOfNonImmBuffer),
- LogMessage,
- BufferLen);
+ PlatformWriteMemory((PVOID)(g_MessageBufferInformation[Index].BufferForMultipleNonImmediateMessage +
+ g_MessageBufferInformation[Index].CurrentLengthOfNonImmBuffer),
+ LogMessage,
+ BufferLen);
//
// add the length
//
- MessageBufferInformation[Index].CurrentLengthOfNonImmBuffer += BufferLen;
+ g_MessageBufferInformation[Index].CurrentLengthOfNonImmBuffer += BufferLen;
// Check if we're in Vmx-root, if it is then we use our customized HIGH_IRQL Spinlock,
// if not we use the windows spinlock
//
if (IsVmxRootMode)
{
- SpinlockUnlock(&VmxRootLoggingLockForNonImmBuffers);
+ SpinlockUnlock(&g_VmxRootLoggingLockForNonImmBuffers);
}
else
{
//
// Release the lock
//
- KeReleaseSpinLock(&MessageBufferInformation[Index].BufferLockForNonImmMessage, OldIRQL);
+ PlatformSpinlockRelease(&g_MessageBufferInformation[Index].BufferLockForNonImmMessage, OldIRQL);
}
return Result;
@@ -1390,18 +1390,18 @@ LogNotifyUsermodeCallback(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument
//
if (!(Irp->CurrentLocation <= Irp->StackCount + 1))
{
- DbgPrint("Err, probably two or more functions called DPC for an object");
+ PlatformDbgPrint("Err, probably two or more functions called DPC for an object");
return;
}
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ IrpSp = PlatformIoGetCurrentIrpStackLocation(Irp);
InBuffLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutBuffLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
if (!InBuffLength || !OutBuffLength)
{
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ PlatformIoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
}
@@ -1428,14 +1428,14 @@ LogNotifyUsermodeCallback(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument
// we have to return here as there is nothing to send here
//
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ PlatformIoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
}
Irp->IoStatus.Information = Length;
Irp->IoStatus.Status = STATUS_SUCCESS;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ PlatformIoCompleteRequest(Irp, IO_NO_INCREMENT);
}
break;
@@ -1443,12 +1443,12 @@ LogNotifyUsermodeCallback(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument
//
// Signal the Event created in user-mode.
//
- KeSetEvent(NotifyRecord->Message.Event, 0, FALSE);
+ PlatformEventSet(NotifyRecord->Message.Event, 0, FALSE);
//
// Dereference the object as we are done with it.
//
- ObDereferenceObject(NotifyRecord->Message.Event);
+ PlatformObjectDereference(NotifyRecord->Message.Event);
break;
@@ -1488,7 +1488,7 @@ LogRegisterIrpBasedNotification(PVOID TargetIrp, LONG * Status)
if (g_GlobalNotifyRecord == NULL)
{
- IrpStack = IoGetCurrentIrpStackLocation(Irp);
+ IrpStack = PlatformIoGetCurrentIrpStackLocation(Irp);
RegisterEvent = (PREGISTER_NOTIFY_BUFFER)Irp->AssociatedIrp.SystemBuffer;
//
@@ -1505,12 +1505,12 @@ LogRegisterIrpBasedNotification(PVOID TargetIrp, LONG * Status)
NotifyRecord->Type = IRP_BASED;
NotifyRecord->Message.PendingIrp = Irp;
- KeInitializeDpc(&NotifyRecord->Dpc, // Dpc
- LogNotifyUsermodeCallback, // DeferredRoutine
- NotifyRecord // DeferredContext
+ PlatformDpcInitialize(&NotifyRecord->Dpc, // Dpc
+ LogNotifyUsermodeCallback, // DeferredRoutine
+ NotifyRecord // DeferredContext
);
- IoMarkIrpPending(Irp);
+ PlatformIoMarkIrpPending(Irp);
//
// check for new message (for both Vmx-root mode or Vmx non root-mode)
@@ -1527,7 +1527,7 @@ LogRegisterIrpBasedNotification(PVOID TargetIrp, LONG * Status)
//
// Insert dpc to queue
//
- KeInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
+ PlatformDpcInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
}
else if (LogCheckForNewMessage(TRUE, TRUE))
{
@@ -1538,7 +1538,7 @@ LogRegisterIrpBasedNotification(PVOID TargetIrp, LONG * Status)
//
// Insert dpc to queue
//
- KeInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
+ PlatformDpcInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
}
else if (LogCheckForNewMessage(FALSE, FALSE))
{
@@ -1550,7 +1550,7 @@ LogRegisterIrpBasedNotification(PVOID TargetIrp, LONG * Status)
//
// Insert dpc to queue
//
- KeInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
+ PlatformDpcInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
}
else if (LogCheckForNewMessage(TRUE, FALSE))
{
@@ -1561,7 +1561,7 @@ LogRegisterIrpBasedNotification(PVOID TargetIrp, LONG * Status)
//
// Insert dpc to queue
//
- KeInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
+ PlatformDpcInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
}
else
{
@@ -1599,7 +1599,7 @@ LogRegisterEventBasedNotification(PVOID TargetIrp)
PREGISTER_NOTIFY_BUFFER RegisterEvent;
PIRP Irp = (PIRP)TargetIrp;
- IrpStack = IoGetCurrentIrpStackLocation(Irp);
+ IrpStack = PlatformIoGetCurrentIrpStackLocation(Irp);
RegisterEvent = (PREGISTER_NOTIFY_BUFFER)Irp->AssociatedIrp.SystemBuffer;
//
@@ -1609,31 +1609,31 @@ LogRegisterEventBasedNotification(PVOID TargetIrp)
if (NULL == NotifyRecord)
{
- DbgPrint("Err, unable to allocate memory for notify record\n");
+ PlatformDbgPrint("Err, unable to allocate memory for notify record\n");
return FALSE;
}
NotifyRecord->Type = EVENT_BASED;
- KeInitializeDpc(&NotifyRecord->Dpc, // Dpc
- LogNotifyUsermodeCallback, // DeferredRoutine
- NotifyRecord // DeferredContext
+ PlatformDpcInitialize(&NotifyRecord->Dpc, // Dpc
+ LogNotifyUsermodeCallback, // DeferredRoutine
+ NotifyRecord // DeferredContext
);
//
// Get the object pointer from the handle
// Note we must be in the context of the process that created the handle
//
- Status = ObReferenceObjectByHandle(RegisterEvent->hEvent,
- SYNCHRONIZE | EVENT_MODIFY_STATE,
- *ExEventObjectType,
- Irp->RequestorMode,
- &NotifyRecord->Message.Event,
- NULL);
+ Status = PlatformObjectReferenceByHandle(RegisterEvent->hEvent,
+ SYNCHRONIZE | EVENT_MODIFY_STATE,
+ *ExEventObjectType,
+ Irp->RequestorMode,
+ &NotifyRecord->Message.Event,
+ NULL);
if (!NT_SUCCESS(Status))
{
- DbgPrint("Err, unable to reference user mode event object, status = 0x%x\n", Status);
+ PlatformDbgPrint("Err, unable to reference user mode event object, status = 0x%x\n", Status);
PlatformMemFreePool(NotifyRecord);
return FALSE;
}
@@ -1641,7 +1641,7 @@ LogRegisterEventBasedNotification(PVOID TargetIrp)
//
// Insert dpc to the queue
//
- KeInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
+ PlatformDpcInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
return TRUE;
}
diff --git a/hyperdbg/hyperlog/code/UnloadDll.c b/hyperdbg/hyperlog/code/UnloadDll.c
index be8c9ba6..0f82e50e 100644
--- a/hyperdbg/hyperlog/code/UnloadDll.c
+++ b/hyperdbg/hyperlog/code/UnloadDll.c
@@ -28,7 +28,7 @@ DllInitialize(
}
NTSTATUS
-DllUnload(void)
+DllUnload(VOID)
{
return STATUS_SUCCESS;
}
diff --git a/hyperdbg/hyperlog/header/Logging.h b/hyperdbg/hyperlog/header/Logging.h
index 87065edc..c098d883 100644
--- a/hyperdbg/hyperlog/header/Logging.h
+++ b/hyperdbg/hyperlog/header/Logging.h
@@ -20,13 +20,13 @@
* @brief VMX buffer for logging messages
*
*/
-char * VmxLogMessage;
+CHAR * g_VmxLogMessage;
/**
* @brief VMX temporary buffer for logging messages
*
*/
-char * VmxTempMessage;
+CHAR * g_VmxTempMessage;
//////////////////////////////////////////////////
// Structures //
@@ -70,8 +70,8 @@ typedef struct _LOG_BUFFER_INFORMATION
KSPIN_LOCK BufferLock; // SpinLock to protect access to the queue
KSPIN_LOCK BufferLockForNonImmMessage; // SpinLock to protect access to the queue of non-imm messages
- UINT64 BufferForMultipleNonImmediateMessage; // Start address of the buffer for accumulating non-immadiate messages
- UINT32 CurrentLengthOfNonImmBuffer; // the current size of the buffer for accumulating non-immadiate messages
+ UINT64 BufferForMultipleNonImmediateMessage; // Start address of the buffer for accumulating non-immediate messages
+ UINT32 CurrentLengthOfNonImmBuffer; // the current size of the buffer for accumulating non-immediate messages
//
// Regular buffers
@@ -101,19 +101,19 @@ typedef struct _LOG_BUFFER_INFORMATION
* @brief Global Variable for buffer on all cores
*
*/
-LOG_BUFFER_INFORMATION * MessageBufferInformation;
+LOG_BUFFER_INFORMATION * g_MessageBufferInformation;
/**
* @brief Vmx-root lock for logging
*
*/
-volatile LONG VmxRootLoggingLock;
+volatile LONG g_VmxRootLoggingLock;
/**
* @brief Vmx-root lock for logging
*
*/
-volatile LONG VmxRootLoggingLockForNonImmBuffers;
+volatile LONG g_VmxRootLoggingLockForNonImmBuffers;
//////////////////////////////////////////////////
// Illustration //
diff --git a/hyperdbg/hyperlog/header/UnloadDll.h b/hyperdbg/hyperlog/header/UnloadDll.h
index c6388ac7..b4801b98 100644
--- a/hyperdbg/hyperlog/header/UnloadDll.h
+++ b/hyperdbg/hyperlog/header/UnloadDll.h
@@ -17,4 +17,4 @@
__declspec(dllexport) NTSTATUS DllInitialize(_In_ PUNICODE_STRING RegistryPath);
-__declspec(dllexport) NTSTATUS DllUnload(void);
+__declspec(dllexport) NTSTATUS DllUnload(VOID);
diff --git a/hyperdbg/hyperlog/header/pch.h b/hyperdbg/hyperlog/header/pch.h
index 1dd8a75d..17cd5fec 100644
--- a/hyperdbg/hyperlog/header/pch.h
+++ b/hyperdbg/hyperlog/header/pch.h
@@ -19,9 +19,9 @@
//
// Environment headers
//
-#include "platform/kernel/header/Environment.h"
+#include "platform/general/header/Environment.h"
-#ifdef ENV_WINDOWS
+#ifdef HYPERDBG_ENV_WINDOWS
//
// Windows defined functions
@@ -30,7 +30,7 @@
# include
# include
-#endif // ENV_WINDOWS
+#endif // HYPERDBG_ENV_WINDOWS
//
// Scope definitions
@@ -48,4 +48,12 @@
//
// Platform independent headers
//
-#include "platform/kernel/header/Mem.h"
+#include "platform/kernel/header/PlatformCpu.h"
+#include "platform/kernel/header/PlatformDbg.h"
+#include "platform/kernel/header/PlatformDpc.h"
+#include "platform/kernel/header/PlatformEvent.h"
+#include "platform/kernel/header/PlatformIo.h"
+#include "platform/kernel/header/PlatformIrql.h"
+#include "platform/kernel/header/PlatformMem.h"
+#include "platform/kernel/header/PlatformSpinlock.h"
+#include "platform/kernel/header/PlatformTime.h"
diff --git a/hyperdbg/hyperlog/hyperlog.inf b/hyperdbg/hyperlog/hyperlog.inf
deleted file mode 100644
index 8601163e..00000000
--- a/hyperdbg/hyperlog/hyperlog.inf
+++ /dev/null
@@ -1,77 +0,0 @@
-;
-; hyperlog.inf
-;
-
-[Version]
-Signature="$WINDOWS NT$"
-Class=System ; TODO: specify appropriate Class
-ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} ; TODO: specify appropriate ClassGuid
-Provider=%ManufacturerName%
-CatalogFile=hyperlog.cat
-DriverVer= ; TODO: set DriverVer in stampinf property pages
-PnpLockdown=1
-
-[DestinationDirs]
-DefaultDestDir = 12
-hyperlog_Device_CoInstaller_CopyFiles = 11
-
-[SourceDisksNames]
-1 = %DiskName%,,,""
-
-[SourceDisksFiles]
-hyperlog.sys = 1,,
-WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames
-
-;*****************************************
-; Install Section
-;*****************************************
-
-[Manufacturer]
-%ManufacturerName%=Standard,NT$ARCH$
-
-[Standard.NT$ARCH$]
-%hyperlog.DeviceDesc%=hyperlog_Device, Root\hyperlog ; TODO: edit hw-id
-
-[hyperlog_Device.NT]
-CopyFiles=Drivers_Dir
-
-[Drivers_Dir]
-hyperlog.sys
-
-;-------------- Service installation
-[hyperlog_Device.NT.Services]
-AddService = hyperlog,%SPSVCINST_ASSOCSERVICE%, hyperlog_Service_Inst
-
-; -------------- hyperlog driver install sections
-[hyperlog_Service_Inst]
-DisplayName = %hyperlog.SVCDESC%
-ServiceType = 1 ; SERVICE_KERNEL_DRIVER
-StartType = 3 ; SERVICE_DEMAND_START
-ErrorControl = 1 ; SERVICE_ERROR_NORMAL
-ServiceBinary = %12%\hyperlog.sys
-
-;
-;--- hyperlog_Device Coinstaller installation ------
-;
-
-[hyperlog_Device.NT.CoInstallers]
-AddReg=hyperlog_Device_CoInstaller_AddReg
-CopyFiles=hyperlog_Device_CoInstaller_CopyFiles
-
-[hyperlog_Device_CoInstaller_AddReg]
-HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller"
-
-[hyperlog_Device_CoInstaller_CopyFiles]
-WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll
-
-[hyperlog_Device.NT.Wdf]
-KmdfService = hyperlog, hyperlog_wdfsect
-[hyperlog_wdfsect]
-KmdfLibraryVersion = $KMDFVERSION$
-
-[Strings]
-SPSVCINST_ASSOCSERVICE= 0x00000002
-ManufacturerName="" ;TODO: Replace with your manufacturer name
-DiskName = "hyperlog Installation Disk"
-hyperlog.DeviceDesc = "hyperlog Device"
-hyperlog.SVCDESC = "hyperlog Service"
diff --git a/hyperdbg/hyperlog/hyperlog.vcxproj b/hyperdbg/hyperlog/hyperlog.vcxproj
index 269be648..5e0ba787 100644
--- a/hyperdbg/hyperlog/hyperlog.vcxproj
+++ b/hyperdbg/hyperlog/hyperlog.vcxproj
@@ -1,5 +1,8 @@
+
+
+ debug
@@ -27,7 +30,7 @@
WindowsKernelModeDriver10.0DynamicLibraryKMDF
- Universal
+ Desktopfalse
@@ -36,7 +39,7 @@
WindowsKernelModeDriver10.0DynamicLibraryKMDF
- Universal
+ Desktopfalse
@@ -87,7 +90,7 @@
Createpch.hstdcpp20
- Disabled
+ Fulltrue
@@ -96,27 +99,51 @@
hyperlog.def
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/hyperlog/hyperlog.vcxproj.filters b/hyperdbg/hyperlog/hyperlog.vcxproj.filters
index 32ae1d04..b7765775 100644
--- a/hyperdbg/hyperlog/hyperlog.vcxproj.filters
+++ b/hyperdbg/hyperlog/hyperlog.vcxproj.filters
@@ -20,11 +20,6 @@
{21f0281e-fc2a-4e13-97ac-e4b35a05a31e}
-
-
- Driver Files
-
- code
@@ -35,7 +30,31 @@
code
-
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+ code\platform
@@ -52,11 +71,32 @@
header
-
+ header\platform
-
+
+ header\platform
+
+
+ header\platform
+
+
+ header\platform
+
+
+ header\platform
+
+
+ header\platform
+
+
+ header\platform
+
+ header\platform
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/hyperlog/packages.config b/hyperdbg/hyperlog/packages.config
new file mode 100644
index 00000000..eb276766
--- /dev/null
+++ b/hyperdbg/hyperlog/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/hyperperf/CMakeLists.txt b/hyperdbg/hyperperf/CMakeLists.txt
new file mode 100644
index 00000000..d6b1310f
--- /dev/null
+++ b/hyperdbg/hyperperf/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Code generated by Visual Studio kit, DO NOT EDIT.
+set(SourceFiles
+ "../include/components/spinlock/code/Spinlock.c"
+ "../include/platform/kernel/code/PlatformMem.c"
+ "code/Logging.c"
+ "code/UnloadDll.c"
+ "../include/components/spinlock/header/Spinlock.h"
+ "../include/platform/kernel/header/Environment.h"
+ "../include/platform/kernel/header/PlatformMem.h"
+ "header/Logging.h"
+ "header/pch.h"
+ "header/UnloadDll.h"
+ "hyperperf.def"
+)
+include_directories(
+ "../include"
+ "header"
+)
+wdk_add_library(hyperperf SHARED
+ KMDF 1.15
+ ${SourceFiles}
+)
diff --git a/hyperdbg/hyperperf/code/api/PerfApi.c b/hyperdbg/hyperperf/code/api/PerfApi.c
new file mode 100644
index 00000000..59cef4c4
--- /dev/null
+++ b/hyperdbg/hyperperf/code/api/PerfApi.c
@@ -0,0 +1,84 @@
+/**
+ * @file PerfApi.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief PMU routines for HyperPerf module
+ * @details
+ * @version 0.21
+ * @date 2026-06-22
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ */
+#include "pch.h"
+
+/**
+ * @brief Initialize the hyperperf module callbacks
+ * @details This only for callback initialization, not for PMU, etc. initialization
+ *
+ * @param HyperPerfCallbacks Pointer to the HyperPerf callbacks structure to be registered
+ * @param RunningOnHypervisorEnvironment Whether the initialization is being done for hypervisor environment or not,
+ * it can be used to skip some of the initialization steps if it is not for hypervisor environment and behave differently based on that
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperPerfInitCallback(HYPERPERF_CALLBACKS * HyperPerfCallbacks,
+ BOOLEAN RunningOnHypervisorEnvironment)
+{
+ //
+ // Check if any of the required callbacks are NULL
+ //
+ for (UINT32 i = 0; i < sizeof(HYPERPERF_CALLBACKS) / sizeof(UINT64); i++)
+ {
+ if (((PVOID *)HyperPerfCallbacks)[i] == NULL)
+ {
+ //
+ // The callback has null entry, so we cannot proceed
+ //
+ return FALSE;
+ }
+ }
+
+ //
+ // Save the callbacks
+ //
+ PlatformWriteMemory(&g_Callbacks, HyperPerfCallbacks, sizeof(HYPERPERF_CALLBACKS));
+
+ //
+ // Set the flag to indicate whether the initialization is being done for hypervisor environment or not
+ //
+ g_RunningOnHypervisorEnvironment = RunningOnHypervisorEnvironment;
+
+ //
+ // Enable callbacks and set the initialized flag
+ //
+ g_HyperPerfCallbacksInitialized = TRUE;
+
+ return TRUE;
+}
+
+/**
+ * @brief Uninitialize the hypertrace module
+ *
+ * @return VOID
+ */
+VOID
+HyperPerfUninit()
+{
+ //
+ // Check if the callbacks are initialized, if not, we don't need to handle anymore
+ //
+ if (!g_HyperPerfCallbacksInitialized)
+ {
+ return;
+ }
+
+ //
+ // Reset the environment flag to default value
+ //
+ g_RunningOnHypervisorEnvironment = FALSE;
+
+ //
+ // Set callbacks to not initialized
+ //
+ g_HyperPerfCallbacksInitialized = FALSE;
+}
diff --git a/hyperdbg/hyperperf/code/broadcast/Broadcast.c b/hyperdbg/hyperperf/code/broadcast/Broadcast.c
new file mode 100644
index 00000000..ad97bd34
--- /dev/null
+++ b/hyperdbg/hyperperf/code/broadcast/Broadcast.c
@@ -0,0 +1,26 @@
+/**
+ * @file Broadcast.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Broadcasting functions
+ * @details
+ * @version 0.21
+ * @date 2026-06-22
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief Routines to enable LBR on all cores
+ *
+ * @return VOID
+ */
+VOID
+BroadcastEnableLbrOnAllCores()
+{
+ //
+ // Broadcast to all cores
+ //
+ KeGenericCallDpc(DpcRoutineTestPmu, NULL);
+}
diff --git a/hyperdbg/hyperperf/code/broadcast/DpcRoutines.c b/hyperdbg/hyperperf/code/broadcast/DpcRoutines.c
new file mode 100644
index 00000000..f5443618
--- /dev/null
+++ b/hyperdbg/hyperperf/code/broadcast/DpcRoutines.c
@@ -0,0 +1,35 @@
+/**
+ * @file DpcRoutines.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief DPC routines
+ * @details
+ * @version 0.21
+ * @date 2026-06-22
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief Broadcast enabling LBR
+ *
+ * @param Dpc
+ * @param DeferredContext
+ * @param SystemArgument1
+ * @param SystemArgument2
+ * @return BOOLEAN
+ */
+BOOLEAN
+DpcRoutineTestPmu(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
+{
+ UNREFERENCED_PARAMETER(Dpc);
+ UNREFERENCED_PARAMETER(DeferredContext);
+
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
+ //
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
+
+ return TRUE;
+}
diff --git a/hyperdbg/hyperperf/code/common/UnloadDll.c b/hyperdbg/hyperperf/code/common/UnloadDll.c
new file mode 100644
index 00000000..17321dbf
--- /dev/null
+++ b/hyperdbg/hyperperf/code/common/UnloadDll.c
@@ -0,0 +1,45 @@
+/**
+ * @file UnloadDll.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Unloading DLL in the target Windows
+ * @details
+ * @version 0.4
+ * @date 2023-07-06
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+//
+// We'll add these functions, so whenever HyperDbg's driver is unloaded
+// DllUnload will be called to unload this dll from the memory.
+// this way we can remove the HyperDbg after unloading as there is no
+// other module remains loaded in the memory.
+//
+
+/**
+ * @brief Routine called on DLL initialization
+ *
+ * @param RegistryPath The registry path of the driver
+ * @return NTSTATUS
+ */
+NTSTATUS
+DllInitialize(
+ _In_ PUNICODE_STRING RegistryPath)
+{
+ UNREFERENCED_PARAMETER(RegistryPath);
+
+ return STATUS_SUCCESS;
+}
+
+/**
+ * @brief Routine called on DLL unload
+ *
+ * @return NTSTATUS
+ */
+NTSTATUS
+DllUnload(VOID)
+{
+ return STATUS_SUCCESS;
+}
diff --git a/hyperdbg/hyperperf/header/api/PerfApi.h b/hyperdbg/hyperperf/header/api/PerfApi.h
new file mode 100644
index 00000000..660f4d20
--- /dev/null
+++ b/hyperdbg/hyperperf/header/api/PerfApi.h
@@ -0,0 +1,19 @@
+/**
+ * @file PerfApi.h
+ * @author
+ * @brief Header for general PMU routines for HyperPerf module
+ * @details
+ * @version 0.21
+ * @date 2026-06-22
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+//
+// Most of the functions are defined and exported
+//
diff --git a/hyperdbg/hyperperf/header/broadcast/Broadcast.h b/hyperdbg/hyperperf/header/broadcast/Broadcast.h
new file mode 100644
index 00000000..8698872f
--- /dev/null
+++ b/hyperdbg/hyperperf/header/broadcast/Broadcast.h
@@ -0,0 +1,20 @@
+
+/**
+ * @file Broadcast.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Headers for broadcasting functions
+ * @details
+ * @version 0.21
+ * @date 2026-06-22
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+VOID
+BroadcastTestPmuOnAllCores();
diff --git a/hyperdbg/hyperperf/header/broadcast/DpcRoutines.h b/hyperdbg/hyperperf/header/broadcast/DpcRoutines.h
new file mode 100644
index 00000000..397ef8b1
--- /dev/null
+++ b/hyperdbg/hyperperf/header/broadcast/DpcRoutines.h
@@ -0,0 +1,20 @@
+
+/**
+ * @file DpcRoutines.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Definition for DPC functions
+ * @details
+ * @version 0.21
+ * @date 2026-06-22
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+BOOLEAN
+DpcRoutineTestPmu(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2);
diff --git a/hyperdbg/hyperperf/header/common/UnloadDll.h b/hyperdbg/hyperperf/header/common/UnloadDll.h
new file mode 100644
index 00000000..9bb252d2
--- /dev/null
+++ b/hyperdbg/hyperperf/header/common/UnloadDll.h
@@ -0,0 +1,22 @@
+/**
+ * @file UnloadDll.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Headers for unloading DLL in the target Windows
+ *
+ * @version 0.4
+ * @date 2023-07-06
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Exported Functions //
+//////////////////////////////////////////////////
+
+__declspec(dllexport) NTSTATUS
+DllInitialize(_In_ PUNICODE_STRING RegistryPath);
+
+__declspec(dllexport) NTSTATUS
+ DllUnload(VOID);
diff --git a/hyperdbg/hyperperf/header/globals/GlobalVariables.h b/hyperdbg/hyperperf/header/globals/GlobalVariables.h
new file mode 100644
index 00000000..79c0f02e
--- /dev/null
+++ b/hyperdbg/hyperperf/header/globals/GlobalVariables.h
@@ -0,0 +1,35 @@
+
+/**
+ * @file GlobalVariables.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Definition for global variables
+ * @details
+ * @version 0.21
+ * @date 2026-06-22
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Global Variables //
+//////////////////////////////////////////////////
+
+/**
+ * @brief List of callbacks
+ *
+ */
+HYPERPERF_CALLBACKS g_Callbacks;
+
+/**
+ * @brief The flag indicating whether the hyperperf module callbacks is initialized or not
+ *
+ */
+BOOLEAN g_HyperPerfCallbacksInitialized;
+
+/**
+ * @brief The flag indicating whether the initialization is being done for hypervisor environment or not
+ *
+ */
+BOOLEAN g_RunningOnHypervisorEnvironment;
diff --git a/hyperdbg/hyperperf/header/pch.h b/hyperdbg/hyperperf/header/pch.h
new file mode 100644
index 00000000..35e14b66
--- /dev/null
+++ b/hyperdbg/hyperperf/header/pch.h
@@ -0,0 +1,111 @@
+
+/**
+ * @file pch.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Headers of Message logging and tracing
+ * @details
+ * @version 0.21
+ * @date 2026-06-22
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#define _NO_CRT_STDIO_INLINE
+
+#pragma warning(disable : 4201) // Suppress nameless struct/union warning
+
+//
+// Environment headers
+//
+#include "platform/general/header/Environment.h"
+
+#ifdef HYPERDBG_ENV_WINDOWS
+
+//
+// Windows defined functions
+//
+# include
+# include
+# include
+
+#endif // HYPERDBG_ENV_WINDOWS
+
+//
+// Scope definitions
+//
+#define HYPERDBG_KERNEL_MODE
+#define HYPERDBG_HYPERPERF
+
+//
+// Add ia32-doc
+//
+#include "ia32-doc/out/ia32.h"
+
+//
+// SDK headers
+//
+#include "SDK/HyperDbgSdk.h"
+
+//
+// Configuration
+//
+#include "config/Configuration.h"
+
+//
+// Platform independent headers
+//
+#include "platform/kernel/header/PlatformMem.h"
+#include "platform/kernel/header/PlatformIntrinsics.h"
+#include "platform/kernel/header/PlatformBroadcast.h"
+#include "platform/kernel/header/PlatformCpu.h"
+#include "platform/kernel/header/PlatformSpinlock.h"
+#include "platform/kernel/header/PlatformIrql.h"
+#include "platform/kernel/header/PlatformDpc.h"
+#include "platform/kernel/header/PlatformTime.h"
+#include "platform/kernel/header/PlatformDbg.h"
+#include "platform/kernel/header/PlatformIo.h"
+#include "platform/kernel/header/PlatformEvent.h"
+
+//
+// Unload function (to be called when the driver is unloaded)
+//
+#include "common/UnloadDll.h"
+
+//
+// Hyperlog headers
+//
+#include "components/callback/header/HyperLogCallback.h"
+#include "SDK/imports/kernel/HyperDbgHyperLogIntrinsics.h"
+
+//
+// Spinlock headers
+//
+#include "components/spinlock/header/Spinlock.h"
+
+//
+// HyperPerf Callbacks
+//
+#include "SDK/modules/HyperPerf.h"
+
+//
+// Definition of general tracing types
+//
+#include "api/PerfApi.h"
+
+//
+// DPC and broadcasting function headers
+//
+#include "broadcast/DpcRoutines.h"
+#include "broadcast/Broadcast.h"
+
+//
+// Export functions
+//
+#include "SDK/imports/kernel/HyperDbgHyperPerf.h"
+
+//
+// Global variables
+//
+#include "globals/GlobalVariables.h"
diff --git a/hyperdbg/hyperperf/header/pt/Pt.h b/hyperdbg/hyperperf/header/pt/Pt.h
new file mode 100644
index 00000000..07a10506
--- /dev/null
+++ b/hyperdbg/hyperperf/header/pt/Pt.h
@@ -0,0 +1,167 @@
+/**
+ * @file Pt.h
+ * @author Masoud Rahimi Jafari (Masoodrahimy1379@gmail.com)
+ * @brief Header for Processor Trace (PT) tracing routines for HyperTrace module
+ * @details Engine that programs Intel PT MSRs from VMX root or kernel context.
+ * Buffer / ToPA management is kept here; user-visible PT structures
+ * live in the SDK header [PtDefinitions.h].
+ * @version 0.19
+ * @date 2026-04-29
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Constants //
+//////////////////////////////////////////////////
+
+//
+// Pool tag for PT contiguous allocations (ASCII "PtHd")
+//
+#define POOL_TAG_PT 'dHtP'
+
+//////////////////////////////////////////////////
+// Structures //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Narrow input descriptor for PtFilter.
+ *
+ * These are the only fields a caller is allowed to set per-CPU
+ * when reconfiguring an active PT trace. Engine-internal options
+ * (BranchEn, TscEn, MtcEn, CycEn, RetCompression, *Freq, etc.)
+ * stay under the engine's control and are NOT exposed here.
+ *
+ * BufferSize == 0 means "keep whatever the per-CPU slot already
+ * has" — pure filter changes don't touch the ToPA / output /
+ * overflow buffers and can run from a DPC.
+ */
+typedef struct _PT_FILTER_OPTIONS
+{
+ BOOLEAN TraceUser;
+ BOOLEAN TraceKernel;
+ UINT64 TargetCr3;
+ UINT64 BufferSize;
+ UINT32 NumAddrRanges;
+ PT_ADDR_RANGE AddrRanges[PT_MAX_ADDR_RANGES];
+
+} PT_FILTER_OPTIONS, *PPT_FILTER_OPTIONS;
+
+/**
+ * @brief Per-CPU bookkeeping for the user-mode mmap surface.
+ *
+ * One MDL + user VA per CPU describes the main output buffer
+ * immediately followed by the 4 KB overflow page as a single
+ * virtually contiguous region in the mapping process. Lives in
+ * g_PtUserMappings; lifetime tied to the PT enable cycle.
+ */
+typedef struct _PT_USER_MAPPING
+{
+ PMDL Mdl;
+ PVOID UserVa;
+
+} PT_USER_MAPPING, *PPT_USER_MAPPING;
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+//
+// HyperDbg-style wrappers (mirroring Lbr*)
+//
+
+BOOLEAN
+PtCheck();
+
+BOOLEAN
+PtStart();
+
+VOID
+PtStop();
+
+VOID
+PtPause();
+
+VOID
+PtResume();
+
+UINT64
+PtSize();
+
+VOID
+PtDump();
+
+VOID
+PtFlush();
+
+//
+// LBR-style filter wrapper, one CPU at a time. Mirrors LbrFilter in shape:
+// caller passes a PT_FILTER_OPTIONS describing only the user-tunable bits
+// (TraceUser, TraceKernel, TargetCr3, BufferSize, NumAddrRanges, AddrRanges),
+// and PtFilter handles the stop / config-update / start sequence on the
+// CURRENT CPU. Engine-internal config (BranchEn, TscEn, etc.) is left
+// untouched in the per-CPU PT_TRACE_CONFIG.
+//
+VOID
+PtFilter(const PT_FILTER_OPTIONS * FilterOptions);
+
+//
+// PASSIVE_LEVEL helpers — call before / after the per-core DPC broadcasts.
+// Required because MmAllocateContiguousMemorySpecifyCache and
+// MmFreeContiguousMemory must run at IRQL == PASSIVE_LEVEL.
+//
+
+BOOLEAN
+PtAllocateAllCpuBuffers();
+
+VOID
+PtFreeAllCpuBuffers();
+
+//
+// User-mode mmap surface: map every per-CPU main output + overflow
+// buffer into the calling user process. Idempotent within an enable
+// cycle; torn down by PtFreeAllCpuBuffers (i.e. PT disable / flush).
+//
+INT32
+PtMmapAllCpuBuffersToUser(PT_USER_BUFFER_DESC * OutDescs, UINT32 MaxDescs, UINT32 * OutNumCpus);
+
+VOID
+PtUnmapAllCpuBuffersFromUser();
+
+//
+// Engine routines (operate on a specific PT_PER_CPU instance)
+//
+
+INT32
+PtEngineQueryCapabilities(PT_CAPABILITIES * OutCaps);
+
+VOID
+PtEngineInitDefaultConfig(PT_TRACE_CONFIG * Config);
+
+INT32
+PtEngineAllocateBuffers(PT_PER_CPU * Cpu, const PT_TRACE_CONFIG * Config);
+
+VOID
+PtEngineFreeBuffers(PT_PER_CPU * Cpu);
+
+INT32
+PtEngineStart(PT_PER_CPU * Cpu);
+
+UINT64
+PtEngineStop(PT_PER_CPU * Cpu, PT_OUTPUT_BUFFER * Out);
+
+INT32
+PtEnginePause(PT_PER_CPU * Cpu);
+
+INT32
+PtEngineResume(PT_PER_CPU * Cpu);
+
+UINT64
+PtEngineHandlePmi(PT_PER_CPU * Cpu, PT_OUTPUT_BUFFER * Out);
+
+BOOLEAN
+PtEngineIsPtPmi();
+
+INT32
+PtEngineSizeToTopaEncoding(UINT64 SizeInBytes);
diff --git a/hyperdbg/hyperperf/hyperperf.def b/hyperdbg/hyperperf/hyperperf.def
new file mode 100644
index 00000000..1415f880
--- /dev/null
+++ b/hyperdbg/hyperperf/hyperperf.def
@@ -0,0 +1,6 @@
+LIBRARY hyperperf
+
+EXPORTS
+
+ DllInitialize PRIVATE
+ DllUnload PRIVATE
\ No newline at end of file
diff --git a/hyperdbg/hyperperf/hyperperf.vcxproj b/hyperdbg/hyperperf/hyperperf.vcxproj
new file mode 100644
index 00000000..20624659
--- /dev/null
+++ b/hyperdbg/hyperperf/hyperperf.vcxproj
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+ debug
+ x64
+
+
+ release
+ x64
+
+
+
+ {360E54B1-0B92-4BCA-8111-4BF384292621}
+ {1bc93793-694f-48fe-9372-81e2b05556fd}
+ v4.5
+ 12.0
+ Debug
+ x64
+ hyperperf
+ $(LatestTargetPlatformVersion)
+
+
+
+ Windows10
+ true
+ WindowsKernelModeDriver10.0
+ DynamicLibrary
+ KMDF
+ Desktop
+ false
+
+
+ Windows10
+ false
+ WindowsKernelModeDriver10.0
+ DynamicLibrary
+ KMDF
+ Desktop
+ false
+
+
+
+
+
+
+
+
+
+
+ DbgengKernelDebugger
+ $(SolutionDir)build\bin\$(Configuration)\
+ $(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\
+ false
+
+
+ DbgengKernelDebugger
+ $(SolutionDir)build\bin\$(Configuration)\
+ $(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\
+ false
+
+
+
+ sha256
+
+
+ $(SolutionDir)\include;$(ProjectDir)header;$(SolutionDir)dependencies;%(AdditionalIncludeDirectories)
+ true
+ Create
+ pch.h
+ stdcpp20
+
+
+ true
+
+ true
+ hyperperf.def
+
+
+
+
+ sha256
+
+
+ $(SolutionDir)\include;$(ProjectDir)header;$(SolutionDir)dependencies;%(AdditionalIncludeDirectories)
+ true
+ Create
+ pch.h
+ stdcpp20
+ Full
+
+
+ true
+
+ true
+ hyperperf.def
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/hyperperf/hyperperf.vcxproj.filters b/hyperdbg/hyperperf/hyperperf.vcxproj.filters
new file mode 100644
index 00000000..d4254192
--- /dev/null
+++ b/hyperdbg/hyperperf/hyperperf.vcxproj.filters
@@ -0,0 +1,119 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+ {1ab177b4-9e6c-460e-834a-8fced04b42a3}
+
+
+ {21f0281e-fc2a-4e13-97ac-e4b35a05a31e}
+
+
+ {09d5457a-bade-4a3f-a171-641110492d57}
+
+
+ {b8b32a09-61fb-433a-ad79-eb7cfc5f3437}
+
+
+ {32ea8333-847b-443d-8992-4140d54dc1d3}
+
+
+ {df6eb164-34b2-4f2a-9530-b88443662fb7}
+
+
+ {cb4e742a-6e43-4798-af4a-72bcb11089c9}
+
+
+ {ab21116d-5f5b-4ef8-82bb-6585ac3dec95}
+
+
+ {57d56081-eede-41a3-b9f0-e7019d32c986}
+
+
+ {4f62540b-d186-479e-83a0-1b550134f487}
+
+
+ {9fe877a7-e261-4579-9752-a3156b6e69d9}
+
+
+ {8bc2336a-b1c5-4e93-9793-23a5cfdc741d}
+
+
+ {fc73555b-2be3-4898-bcdb-df83fa3e1388}
+
+
+
+
+ code\platform
+
+
+ code\broadcast
+
+
+ code\broadcast
+
+
+ code\common
+
+
+ code\api
+
+
+ code\platform
+
+
+ code\broadcast
+
+
+ code\platform
+
+
+ code\components\callback
+
+
+
+
+ header\platform
+
+
+ header\broadcast
+
+
+ header\broadcast
+
+
+ header\common
+
+
+ header\globals
+
+
+ header\api
+
+
+ header\platform
+
+
+ header\platform
+
+
+ header\platform
+
+
+ header\components\callback
+
+
+ header
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/hyperperf/packages.config b/hyperdbg/hyperperf/packages.config
new file mode 100644
index 00000000..eb276766
--- /dev/null
+++ b/hyperdbg/hyperperf/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/hypertrace/CMakeLists.txt b/hyperdbg/hypertrace/CMakeLists.txt
new file mode 100644
index 00000000..ec2c68bb
--- /dev/null
+++ b/hyperdbg/hypertrace/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Code generated by Visual Studio kit, DO NOT EDIT.
+set(SourceFiles
+ "../include/components/spinlock/code/Spinlock.c"
+ "../include/platform/kernel/code/PlatformMem.c"
+ "code/Logging.c"
+ "code/UnloadDll.c"
+ "../include/components/spinlock/header/Spinlock.h"
+ "../include/platform/kernel/header/Environment.h"
+ "../include/platform/kernel/header/PlatformMem.h"
+ "header/Logging.h"
+ "header/pch.h"
+ "header/UnloadDll.h"
+ "hypertrace.def"
+)
+include_directories(
+ "../include"
+ "header"
+)
+wdk_add_library(hypertrace SHARED
+ KMDF 1.15
+ ${SourceFiles}
+)
diff --git a/hyperdbg/hypertrace/code/api/LbrApi.c b/hyperdbg/hypertrace/code/api/LbrApi.c
new file mode 100644
index 00000000..f0e92040
--- /dev/null
+++ b/hyperdbg/hypertrace/code/api/LbrApi.c
@@ -0,0 +1,586 @@
+/**
+ * @file LbrApi.c
+ * @author Hari Mishal (harimishal6@gmail.com)
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Tracing routines for HyperTrace module (Intel Last Branch Record)
+ * @details
+ * @version 0.18
+ * @date 2025-12-02
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ */
+#include "pch.h"
+
+/**
+ * @brief Example of performing LBR trace
+ *
+ * @return VOID
+ */
+VOID
+HyperTraceLbrExamplePerformTrace()
+{
+ if (LbrStart(LBR_SELECT_WITHOUT_FILTER))
+ {
+ for (volatile int i = 0; i < 50; i++)
+ {
+ if (i % 2)
+ {
+ INT A = i * 2;
+ A += 5;
+ }
+ else
+ {
+ CpuNop();
+ CpuNop();
+ }
+ }
+
+ LogInfo("Dumping LBR Buffer...\n");
+
+ LbrStop();
+ LbrPrint(); // This will print the collected LBR branches to the log
+ }
+}
+
+/**
+ * @brief Query the state of LBR save and load VM exit and entry controls
+ *
+ * @param CoreId The index of the processor core to query
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTraceLbrQueryStateOfLbrSaveAndLoadVmExitAndEntryControls(UINT32 CoreId)
+{
+ UNREFERENCED_PARAMETER(CoreId); // Right now there is no core specifc controls for LBR
+
+ return g_LastBranchRecordEnabled;
+}
+
+/**
+ * @brief Set the kernel status in the HyperTrace LBR operation request structure
+ *
+ * @param HyperTraceLbrOperationRequest Pointer to the HyperTrace LBR operation request packet
+ * @param Status The kernel status code to write into the request
+ *
+ * @return VOID
+ */
+VOID
+HyperTraceLbrSetKernelStatus(
+ HYPERTRACE_LBR_OPERATION_PACKETS * HyperTraceLbrOperationRequest,
+ UINT32 Status)
+{
+ if (HyperTraceLbrOperationRequest != NULL)
+ {
+ HyperTraceLbrOperationRequest->KernelStatus = Status;
+ }
+}
+
+/**
+ * @brief Set the kernel status in the HyperTrace LBR dump operation request structure
+ *
+ * @param HyperTraceLbrDumpOperationRequest Pointer to the HyperTrace LBR dump operation request packet
+ * @param Status The kernel status code to write into the request
+ *
+ * @return VOID
+ */
+VOID
+HyperTraceLbrDumpSetKernelStatus(
+ HYPERTRACE_LBR_DUMP_PACKETS * HyperTraceLbrDumpOperationRequest,
+ UINT32 Status)
+{
+ if (HyperTraceLbrDumpOperationRequest != NULL)
+ {
+ HyperTraceLbrDumpOperationRequest->KernelStatus = Status;
+ }
+}
+
+/**
+ * @brief Check if LBR is supported and enabled on the current core
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTraceLbrCheck()
+{
+ //
+ // Only check LBR once it is already initialized
+ //
+ if (!g_LastBranchRecordEnabled)
+ {
+ return FALSE;
+ }
+
+ return LbrCheck();
+}
+
+/**
+ * @brief Restore (re-enable) LBR collection on the current core with the specified filter options
+ * @param FilterOptions A bitmask of filter options to apply to the LBR branches
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTraceLbrRestoreByFilter(UINT64 FilterOptions)
+{
+ //
+ // Only restore (re-enable) LBR once it is already initialized
+ //
+ if (!g_LastBranchRecordEnabled)
+ {
+ return FALSE;
+ }
+
+ return LbrStart(FilterOptions);
+}
+
+/**
+ * @brief Restore (re-enable) LBR collection on the current core with previous filter options
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTraceLbrRestore()
+{
+ return HyperTraceLbrRestoreByFilter(g_LbrFilterOptions);
+}
+
+/**
+ * @brief Check if LBR is supported on the current CPU and get its capacity
+ *
+ * @param Capacity Pointer to a variable to receive the LBR capacity (number of entries)
+ * @param IsArchLbr Pointer to a variable to receive whether the supported LBR is architectural LBR or not (legacy LBR)
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTraceLbrIsSupported(UINT32 * Capacity, BOOLEAN * IsArchLbr)
+{
+ //
+ // Check for ARCHITECTURAL LBR support first, if not supported then check for LEGACY LBR support
+ //
+ if (!LbrCheckAndReadArchitecturalLbrDetails())
+ {
+ //
+ // If the CPU does not support architectural LBR, we can check for legacy LBR support as a fallback
+ //
+ if (!LbrCheckAndReadLegacyLbrDetails())
+ {
+ return FALSE;
+ }
+ }
+
+ //
+ // Set capacity when the pointer is valid
+ //
+ if (Capacity != NULL)
+ {
+ *Capacity = (UINT32)g_LbrCapacity;
+ }
+
+ //
+ // Set IsArchLbr when the pointer is valid
+ //
+ if (IsArchLbr != NULL)
+ {
+ *IsArchLbr = g_ArchBasedLastBranchRecord;
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Enable LBR tracing for HyperTrace
+ *
+ * @param HyperTraceOperationRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTraceLbrEnable(HYPERTRACE_LBR_OPERATION_PACKETS * HyperTraceOperationRequest)
+{
+ //
+ // Check if LBR is already enabled or not
+ //
+ // We allow re-enabling LBR even if it is already enabled to support scenarios where
+ // the LBR is deactivated as a result of a #DB and wants to re-enable it again
+ /*
+ if (g_LastBranchRecordEnabled)
+ {
+ HyperTraceLbrSetKernelStatus(HyperTraceOperationRequest, DEBUGGER_ERROR_LBR_ALREADY_ENABLED);
+ return FALSE;
+ }
+ */
+
+ //
+ // Check for ARCHITECTURAL LBR support first, if not supported then check for LEGACY LBR support
+ //
+ if (!LbrCheckAndReadArchitecturalLbrDetails())
+ {
+ //
+ // If the CPU does not support architectural LBR, we can check for legacy LBR support as a fallback
+ //
+ if (!LbrCheckAndReadLegacyLbrDetails())
+ {
+ HyperTraceLbrSetKernelStatus(HyperTraceOperationRequest, DEBUGGER_ERROR_LBR_NOT_SUPPORTED);
+ return FALSE;
+ }
+ }
+
+ //
+ // Check VMCS support for LBR if the initialization is being done for hypervisor environment
+ //
+ if (g_RunningOnHypervisorEnvironment)
+ {
+ if ((g_ArchBasedLastBranchRecord && !g_Callbacks.VmFuncCheckCpuSupportForLoadAndClearGuestIa32LbrCtlControls()) ||
+ (!g_ArchBasedLastBranchRecord && !g_Callbacks.VmFuncCheckCpuSupportForSaveAndLoadDebugControls()))
+ {
+ HyperTraceLbrSetKernelStatus(HyperTraceOperationRequest, DEBUGGER_ERROR_LBR_NOT_SUPPORTED_ON_VMCS);
+ return FALSE;
+ }
+ }
+
+ //
+ // Broadcast enabling LBR on all cores
+ //
+ BroadcastEnableLbrOnAllCores();
+
+ //
+ // Check if LBR is enabled or not (for example in VMs, LBR flags are usually masked)
+ //
+ if (!LbrCheck())
+ {
+ HyperTraceLbrSetKernelStatus(HyperTraceOperationRequest, DEBUGGER_ERROR_LBR_NOT_SUPPORTED);
+ return FALSE;
+ }
+
+ //
+ // Set the flag to indicate that LBR tracing is enabled
+ //
+ g_LastBranchRecordEnabled = TRUE;
+
+ //
+ // Set successful status
+ //
+ HyperTraceLbrSetKernelStatus(HyperTraceOperationRequest, DEBUGGER_OPERATION_WAS_SUCCESSFUL);
+
+ return TRUE;
+}
+
+/**
+ * @brief Disable LBR tracing for HyperTrace
+ *
+ * @param HyperTraceOperationRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTraceLbrDisable(HYPERTRACE_LBR_OPERATION_PACKETS * HyperTraceOperationRequest)
+{
+ //
+ // Check if LBR is already disabled or not
+ //
+ if (!g_LastBranchRecordEnabled)
+ {
+ HyperTraceLbrSetKernelStatus(HyperTraceOperationRequest, DEBUGGER_ERROR_LBR_ALREADY_DISABLED);
+ return FALSE;
+ }
+
+ //
+ // Disabling LBR
+ //
+ g_LastBranchRecordEnabled = FALSE;
+
+ //
+ // Broadcast disabling LBR on all cores
+ //
+ BroadcastDisableLbrOnAllCores();
+
+ //
+ // Set successful status
+ //
+ HyperTraceLbrSetKernelStatus(HyperTraceOperationRequest, DEBUGGER_OPERATION_WAS_SUCCESSFUL);
+
+ return TRUE;
+}
+
+/**
+ * @brief Flush LBR tracing for HyperTrace
+ *
+ * @param HyperTraceOperationRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTraceLbrFlush(HYPERTRACE_LBR_OPERATION_PACKETS * HyperTraceOperationRequest)
+{
+ //
+ // Check if LBR is already disabled or not
+ //
+ if (!g_LastBranchRecordEnabled)
+ {
+ HyperTraceLbrSetKernelStatus(HyperTraceOperationRequest, DEBUGGER_ERROR_LBR_ALREADY_DISABLED);
+ return FALSE;
+ }
+
+ //
+ // Disabling LBR
+ //
+ g_LastBranchRecordEnabled = FALSE;
+
+ //
+ // Broadcast flushing LBR on all cores
+ //
+ BroadcastFlushLbrOnAllCores();
+
+ //
+ // Set successful status
+ //
+ HyperTraceLbrSetKernelStatus(HyperTraceOperationRequest, DEBUGGER_OPERATION_WAS_SUCCESSFUL);
+
+ return TRUE;
+}
+
+/**
+ * @brief Save LBR tracing for HyperTrace
+ *
+ * @param HyperTraceOperationRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTraceLbrSave(HYPERTRACE_LBR_OPERATION_PACKETS * HyperTraceOperationRequest)
+{
+ //
+ // Check if LBR is already disabled or not
+ //
+ if (!g_LastBranchRecordEnabled)
+ {
+ HyperTraceLbrSetKernelStatus(HyperTraceOperationRequest, DEBUGGER_ERROR_LBR_ALREADY_DISABLED);
+ return FALSE;
+ }
+
+ // LogInfo("Saving LBR Buffer...\n");
+
+ //
+ // Save the LBR state
+ //
+ LbrSave();
+
+ //
+ // The operation was successful
+ //
+ HyperTraceLbrSetKernelStatus(HyperTraceOperationRequest, DEBUGGER_OPERATION_WAS_SUCCESSFUL);
+
+ return TRUE;
+}
+
+/**
+ * @brief Print LBR tracing for HyperTrace
+ *
+ * @param HyperTraceOperationRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTraceLbrPrint(HYPERTRACE_LBR_OPERATION_PACKETS * HyperTraceOperationRequest)
+{
+ //
+ // Check if LBR is already disabled or not
+ //
+ if (!g_LastBranchRecordEnabled)
+ {
+ HyperTraceLbrSetKernelStatus(HyperTraceOperationRequest, DEBUGGER_ERROR_LBR_ALREADY_DISABLED);
+ return FALSE;
+ }
+
+ // LogInfo("Dumping LBR Buffer...\n");
+
+ //
+ // Save the LBR state
+ //
+ LbrSave();
+
+ //
+ // This will print the collected LBR branches to the log
+ //
+ LbrPrint();
+
+ //
+ // The operation was successful
+ //
+ HyperTraceLbrSetKernelStatus(HyperTraceOperationRequest, DEBUGGER_OPERATION_WAS_SUCCESSFUL);
+
+ return TRUE;
+}
+
+/**
+ * @brief Update LBR filter options for HyperTrace
+ *
+ * @param HyperTraceOperationRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTraceLbrUpdateFilterOptions(HYPERTRACE_LBR_OPERATION_PACKETS * HyperTraceOperationRequest)
+{
+ //
+ // Check if LBR is already disabled or not
+ //
+ if (!g_LastBranchRecordEnabled)
+ {
+ HyperTraceLbrSetKernelStatus(HyperTraceOperationRequest, DEBUGGER_ERROR_LBR_ALREADY_DISABLED);
+ return FALSE;
+ }
+
+ //
+ // Update the LBR filter options based on the request
+ //
+ BroadcastFilterLbrOptionsOnAllCores((UINT64)HyperTraceOperationRequest->LbrFilterOptions);
+
+ //
+ // The operation was successful
+ //
+ HyperTraceLbrSetKernelStatus(HyperTraceOperationRequest, DEBUGGER_OPERATION_WAS_SUCCESSFUL);
+
+ return TRUE;
+}
+
+/**
+ * @brief Perform actions related to HyperTrace LBR dumping
+ *
+ * @param LbrDumpRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTraceLbrPerformDump(HYPERTRACE_LBR_DUMP_PACKETS * LbrDumpRequest)
+{
+ ULONG ProcessorsCount;
+
+ //
+ // Check if LBR is enabled or not before dumping
+ //
+ if (!g_LastBranchRecordEnabled)
+ {
+ HyperTraceLbrDumpSetKernelStatus(LbrDumpRequest, DEBUGGER_ERROR_LBR_ALREADY_DISABLED);
+ return FALSE;
+ }
+
+ //
+ // Get the number of processors in the system to validate the requested core id for dumping
+ //
+ ProcessorsCount = KeQueryActiveProcessorCount(0);
+
+ //
+ // Check if core id is valid
+ //
+ if (LbrDumpRequest->CoreId >= ProcessorsCount)
+ {
+ HyperTraceLbrDumpSetKernelStatus(LbrDumpRequest, DEBUGGER_ERROR_INVALID_CORE_ID);
+ return FALSE;
+ }
+
+ //
+ // Check if next core is valid in the case of dumping all cores
+ //
+ if (LbrDumpRequest->CoreId == ProcessorsCount - 1)
+ {
+ LbrDumpRequest->NextCoreIsValid = FALSE;
+ }
+ else
+ {
+ LbrDumpRequest->NextCoreIsValid = TRUE;
+ }
+
+ //
+ // Set ARCH or LEGACY LBR flag in the dump request structure based on the type of LBR supported by the CPU
+ //
+ LbrDumpRequest->ArchBasedLBR = g_ArchBasedLastBranchRecord;
+
+ //
+ // Set the current LBR capacity in the dump request structure based on the type of LBR supported by the CPU
+ //
+ LbrDumpRequest->CurrentLbrCapacity = (UINT8)g_LbrCapacity;
+
+ //
+ // Copy the LBR stack entries of the requested core into the dump request structure to be sent back to usermode
+ //
+ RtlCopyMemory(&LbrDumpRequest->LbrStack, &g_LbrStateList[LbrDumpRequest->CoreId], sizeof(LBR_STACK_ENTRY));
+
+ //
+ // Set successful status
+ //
+ HyperTraceLbrDumpSetKernelStatus(LbrDumpRequest, DEBUGGER_OPERATION_WAS_SUCCESSFUL);
+
+ return TRUE;
+}
+
+/**
+ * @brief Perform actions related to HyperTrace LBR operations
+ *
+ * @param LbrOperationRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTraceLbrPerformOperation(HYPERTRACE_LBR_OPERATION_PACKETS * LbrOperationRequest)
+{
+ BOOLEAN Status = TRUE;
+
+ //
+ // Check if the hypertrace module is initialized before performing any operation
+ //
+ if (!g_HyperTraceCallbacksInitialized)
+ {
+ HyperTraceLbrSetKernelStatus(LbrOperationRequest, DEBUGGER_ERROR_HYPERTRACE_NOT_INITIALIZED);
+ return FALSE;
+ }
+
+ //
+ // Perform the requested operation
+ //
+ switch (LbrOperationRequest->LbrOperationType)
+ {
+ case HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_ENABLE:
+
+ // LogInfo("HyperTrace: Enabling LBR tracing...\n");
+
+ HyperTraceLbrEnable(LbrOperationRequest);
+
+ break;
+
+ case HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_DISABLE:
+
+ // LogInfo("HyperTrace: Disabling LBR tracing...\n");
+
+ HyperTraceLbrDisable(LbrOperationRequest);
+
+ break;
+
+ case HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_FLUSH:
+
+ // LogInfo("HyperTrace: Flushing LBR tracing...\n");
+
+ HyperTraceLbrFlush(LbrOperationRequest);
+
+ break;
+
+ case HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_FILTER:
+
+ // LogInfo("HyperTrace: Updating LBR filter options...\n");
+
+ HyperTraceLbrUpdateFilterOptions(LbrOperationRequest);
+
+ break;
+
+ default:
+
+ Status = FALSE;
+ HyperTraceLbrSetKernelStatus(LbrOperationRequest, DEBUGGER_ERROR_INVALID_HYPERTRACE_OPERATION_TYPE);
+
+ break;
+ }
+
+ return Status;
+}
diff --git a/hyperdbg/hypertrace/code/api/PtApi.c b/hyperdbg/hypertrace/code/api/PtApi.c
new file mode 100644
index 00000000..408848c3
--- /dev/null
+++ b/hyperdbg/hypertrace/code/api/PtApi.c
@@ -0,0 +1,644 @@
+/**
+ * @file PtApi.c
+ * @author Masoud Rahimi Jafari (Masoodrahimy1379@gmail.com)
+ * @brief Tracing routines for HyperTrace module (Intel Processor Trace)
+ * @details
+ * @version 0.19
+ * @date 2026-04-29
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ */
+#include "pch.h"
+
+/**
+ * @brief Translate a user-mode HYPERTRACE_PT_OPERATION_PACKETS into a
+ * kernel-side PT_TRACE_CONFIG, falling back to defaults when the
+ * caller left fields zero (e.g. a bare `!pt filter`).
+ *
+ * The returned config is value-typed; HyperTracePtFilter's slow
+ * path copies it into every per-CPU slot via
+ * HyperTracePtSeedConfigOnAllCpus.
+ * @return VOID
+ */
+static VOID
+HyperTracePtBuildConfig(const HYPERTRACE_PT_OPERATION_PACKETS * Req,
+ PT_TRACE_CONFIG * OutCfg)
+{
+ UINT32 Copy;
+
+ //
+ // Start from defaults; only the fields the user can drive are then
+ // overridden.
+ //
+ PtEngineInitDefaultConfig(OutCfg);
+
+ //
+ // If the request specifies neither user nor kernel, default to both
+ // (matches LBR behaviour when filter is empty).
+ //
+ if (Req->FilterOptions.TraceUser || Req->FilterOptions.TraceKernel)
+ {
+ OutCfg->TraceUser = (Req->FilterOptions.TraceUser != 0) ? TRUE : FALSE;
+ OutCfg->TraceKernel = (Req->FilterOptions.TraceKernel != 0) ? TRUE : FALSE;
+ }
+
+ OutCfg->TargetCr3 = Req->EnableOptions.Cr3;
+
+ if (Req->BufferSize != 0)
+ {
+ OutCfg->BufferSize = Req->BufferSize;
+ }
+
+ OutCfg->NumAddrRanges = Req->FilterOptions.NumAddrRanges;
+ if (OutCfg->NumAddrRanges > PT_MAX_ADDR_RANGES)
+ OutCfg->NumAddrRanges = PT_MAX_ADDR_RANGES;
+
+ for (Copy = 0; Copy < OutCfg->NumAddrRanges; Copy++)
+ {
+ OutCfg->AddrRanges[Copy] = Req->FilterOptions.AddrRanges[Copy];
+ }
+}
+
+/**
+ * @brief Push a fully-formed PT_TRACE_CONFIG into every active per-CPU
+ * slot. Used by the Enable path so PtAllocateAllCpuBuffers picks up
+ * the right BufferSize on every core. Runs at PASSIVE_LEVEL —
+ * does NOT start or stop tracing (callers handle that via DPC)
+ * @return VOID
+ */
+static VOID
+HyperTracePtSeedConfigOnAllCpus(const PT_TRACE_CONFIG * Cfg)
+{
+ UINT32 ProcessorsCount;
+ UINT32 i;
+
+ if (g_PtStateList == NULL || Cfg == NULL)
+ return;
+
+ ProcessorsCount = KeQueryActiveProcessorCount(0);
+
+ for (i = 0; i < ProcessorsCount; i++)
+ {
+ g_PtStateList[i].Config = *Cfg;
+ }
+}
+
+/**
+ * @brief Enable PT tracing for HyperTrace
+ *
+ * @param PtOperationRequest Pointer to the HyperTrace PT operation request packet
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTracePtEnable(HYPERTRACE_PT_OPERATION_PACKETS * PtOperationRequest)
+{
+ //
+ // Check if PT is already enabled or not
+ //
+ if (g_ProcessorTraceEnabled)
+ {
+ PtOperationRequest->KernelStatus = DEBUGGER_ERROR_PT_ALREADY_ENABLED;
+ return FALSE;
+ }
+
+ //
+ // Check PT support on CPU
+ //
+ if (!PtCheck())
+ {
+ PtOperationRequest->KernelStatus = DEBUGGER_ERROR_PT_NOT_SUPPORTED;
+ return FALSE;
+ }
+
+ //
+ // Allocate per-CPU ToPA / output / overflow buffers at PASSIVE_LEVEL
+ // (the contiguous-memory allocator cannot run from a DPC).
+ // PtAllocateAllCpuBuffers reads Cpu->Config.BufferSize, which was set
+ // either at module init (default 2MB) or by a prior !pt filter — so
+ // any pre-enable filter settings are preserved here.
+ //
+ if (!PtAllocateAllCpuBuffers())
+ {
+ //
+ // Roll back any partial allocations so we don't leak on next try.
+ //
+ PtFreeAllCpuBuffers();
+ PtOperationRequest->KernelStatus = DEBUGGER_ERROR_PT_NOT_SUPPORTED;
+ return FALSE;
+ }
+
+ //
+ // Broadcast enabling PT on all cores
+ //
+ BroadcastEnablePtOnAllCores();
+
+ //
+ // Set the flag to indicate that PT tracing is enabled
+ //
+ g_ProcessorTraceEnabled = TRUE;
+
+ //
+ // Set successful status
+ //
+ PtOperationRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+
+ return TRUE;
+}
+
+/**
+ * @brief Disable PT tracing for HyperTrace
+ *
+ * @param PtOperationRequest Pointer to the HyperTrace PT operation request packet
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTracePtDisable(HYPERTRACE_PT_OPERATION_PACKETS * PtOperationRequest)
+{
+ //
+ // Check if PT is already disabled or not
+ //
+ if (!g_ProcessorTraceEnabled)
+ {
+ if (PtOperationRequest != NULL)
+ {
+ PtOperationRequest->KernelStatus = DEBUGGER_ERROR_PT_ALREADY_DISABLED;
+ }
+
+ return FALSE;
+ }
+
+ //
+ // Disabling PT
+ //
+ g_ProcessorTraceEnabled = FALSE;
+
+ //
+ // Broadcast disabling PT on all cores (DPC stops tracing per-core)
+ //
+ BroadcastDisablePtOnAllCores();
+
+ //
+ // Free per-CPU buffers at PASSIVE_LEVEL after the broadcast has stopped
+ // tracing on every core.
+ //
+ PtFreeAllCpuBuffers();
+
+ //
+ // Set successful status
+ //
+ if (PtOperationRequest != NULL)
+ {
+ PtOperationRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Pause PT tracing on every core. Buffers stay allocated and the
+ * per-CPU CTL is preserved, so HyperTracePtResume can restart the
+ * trace exactly where it stopped.
+ *
+ * @param HyperTraceOperationRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTracePtPause(HYPERTRACE_PT_OPERATION_PACKETS * HyperTraceOperationRequest)
+{
+ if (!g_ProcessorTraceEnabled)
+ {
+ if (HyperTraceOperationRequest != NULL)
+ {
+ HyperTraceOperationRequest->KernelStatus = DEBUGGER_ERROR_PT_ALREADY_DISABLED;
+ }
+ return FALSE;
+ }
+
+ BroadcastPausePtOnAllCores();
+
+ if (HyperTraceOperationRequest != NULL)
+ {
+ HyperTraceOperationRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Resume PT tracing on every core after a prior HyperTracePtPause.
+ *
+ * @param HyperTraceOperationRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTracePtResume(HYPERTRACE_PT_OPERATION_PACKETS * HyperTraceOperationRequest)
+{
+ if (!g_ProcessorTraceEnabled)
+ {
+ if (HyperTraceOperationRequest != NULL)
+ {
+ HyperTraceOperationRequest->KernelStatus = DEBUGGER_ERROR_PT_ALREADY_DISABLED;
+ }
+ return FALSE;
+ }
+
+ BroadcastResumePtOnAllCores();
+
+ if (HyperTraceOperationRequest != NULL)
+ {
+ HyperTraceOperationRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Snapshot the current PT output position on every core and write
+ * the per-CPU byte counts into HyperTraceOperationRequest->BytesPerCpu.
+ * The returned counts are the decode window — bytes [0, BytesPerCpu[i])
+ * in CPU i's user mapping currently hold valid trace data.
+ *
+ * @param HyperTraceOperationRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTracePtSize(HYPERTRACE_PT_OPERATION_PACKETS * HyperTraceOperationRequest)
+{
+ UINT32 ProcessorsCount;
+
+ if (!g_ProcessorTraceEnabled)
+ {
+ if (HyperTraceOperationRequest != NULL)
+ {
+ HyperTraceOperationRequest->KernelStatus = DEBUGGER_ERROR_PT_ALREADY_DISABLED;
+ }
+ return FALSE;
+ }
+
+ if (HyperTraceOperationRequest == NULL)
+ return FALSE;
+
+ ProcessorsCount = KeQueryActiveProcessorCount(0);
+
+ if (ProcessorsCount > PT_MAX_CPUS_FOR_MMAP)
+ ProcessorsCount = PT_MAX_CPUS_FOR_MMAP;
+
+ RtlZeroMemory(HyperTraceOperationRequest->BytesPerCpu,
+ sizeof(HyperTraceOperationRequest->BytesPerCpu));
+
+ BroadcastSizePtOnAllCores(HyperTraceOperationRequest->BytesPerCpu);
+
+ HyperTraceOperationRequest->NumCpus = ProcessorsCount;
+ HyperTraceOperationRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ return TRUE;
+}
+
+/**
+ * @brief Dump PT trace state for HyperTrace
+ *
+ * @param HyperTraceOperationRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTracePtDump(HYPERTRACE_PT_OPERATION_PACKETS * HyperTraceOperationRequest)
+{
+ if (!g_ProcessorTraceEnabled)
+ {
+ if (HyperTraceOperationRequest != NULL)
+ {
+ HyperTraceOperationRequest->KernelStatus = DEBUGGER_ERROR_PT_ALREADY_DISABLED;
+ }
+ return FALSE;
+ }
+
+ LogInfo("Dumping PT trace summary...\n");
+
+ BroadcastDumpPtOnAllCores();
+
+ if (HyperTraceOperationRequest != NULL)
+ {
+ HyperTraceOperationRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Flush PT trace state on all cores (free buffers)
+ *
+ * @param HyperTraceOperationRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTracePtFlush(HYPERTRACE_PT_OPERATION_PACKETS * HyperTraceOperationRequest)
+{
+ if (!g_ProcessorTraceEnabled)
+ {
+ if (HyperTraceOperationRequest != NULL)
+ {
+ HyperTraceOperationRequest->KernelStatus = DEBUGGER_ERROR_PT_ALREADY_DISABLED;
+ }
+ return FALSE;
+ }
+
+ //
+ // Stop tracing on all cores via DPC (so MSRs are quiesced)
+ //
+ BroadcastFlushPtOnAllCores();
+
+ //
+ // Then free contiguous buffers at PASSIVE_LEVEL
+ //
+ PtFreeAllCpuBuffers();
+
+ //
+ // Reallocate buffers so subsequent !pt save / !pt dump / !pt enable
+ // continue to work — Flush in LBR keeps tracing alive, so we mirror
+ // that by leaving PT primed for the next !pt enable.
+ //
+ if (!PtAllocateAllCpuBuffers())
+ {
+ PtFreeAllCpuBuffers();
+ if (HyperTraceOperationRequest != NULL)
+ {
+ HyperTraceOperationRequest->KernelStatus = DEBUGGER_ERROR_PT_NOT_SUPPORTED;
+ }
+ g_ProcessorTraceEnabled = FALSE;
+ return FALSE;
+ }
+
+ //
+ // Resume tracing on all cores
+ //
+ BroadcastEnablePtOnAllCores();
+
+ if (HyperTraceOperationRequest != NULL)
+ {
+ HyperTraceOperationRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Apply a new PT trace configuration (TraceUser / TraceKernel /
+ * TargetCr3 / BufferSize / NumAddrRanges + AddrRanges) on all cores.
+ *
+ * Mirrors HyperTraceLbrUpdateFilterOptions / LbrFilter:
+ *
+ * - If PT is currently enabled, stop tracing on all cores, free
+ * and reallocate buffers (because BufferSize may have changed),
+ * push the new config into every per-CPU slot, and resume
+ * tracing on all cores.
+ * - If PT is currently disabled, only update the per-CPU config
+ * so that the next `!pt enable` picks it up.
+ *
+ * Must be called at IRQL == PASSIVE_LEVEL because of the
+ * contiguous-memory allocator.
+ */
+BOOLEAN
+HyperTracePtFilter(HYPERTRACE_PT_OPERATION_PACKETS * Req)
+{
+ PT_APPLY_CORE_FILTER_REQUEST ApplyCoreFilterReq = {0};
+ BOOLEAN WasEnabled = g_ProcessorTraceEnabled;
+ BOOLEAN BufferChanged = FALSE;
+ UINT64 ExistingSize = 0;
+
+ //
+ // Copy the user-mode request into a kernel-mode PT_APPLY_CORE_FILTER_REQUEST
+ //
+ memcpy(&ApplyCoreFilterReq.FilterOptions, &Req->FilterOptions, sizeof(PT_FILTER_OPTIONS));
+ memcpy(&ApplyCoreFilterReq.EnableOptions, &Req->EnableOptions, sizeof(PT_ENABLE_OPTIONS));
+ ApplyCoreFilterReq.BufferSize = Req->BufferSize;
+
+ //
+ // Translate the user-mode packet into PT_FILTER_OPTIONS - the narrow
+ // surface PtFilter operates on. Default to user+kernel when the
+ // caller specified neither (matches LBR's empty-filter behaviour).
+ //
+ if (Req->FilterOptions.TraceUser || Req->FilterOptions.TraceKernel)
+ {
+ ApplyCoreFilterReq.FilterOptions.TraceUser = (Req->FilterOptions.TraceUser != 0) ? TRUE : FALSE;
+ ApplyCoreFilterReq.FilterOptions.TraceKernel = (Req->FilterOptions.TraceKernel != 0) ? TRUE : FALSE;
+ }
+ else
+ {
+ ApplyCoreFilterReq.FilterOptions.TraceUser = TRUE;
+ ApplyCoreFilterReq.FilterOptions.TraceKernel = TRUE;
+ }
+
+ if (Req->FilterOptions.NumAddrRanges > PT_MAX_ADDR_RANGES)
+ ApplyCoreFilterReq.FilterOptions.NumAddrRanges = PT_MAX_ADDR_RANGES;
+
+ //
+ // Decide between fast (filter-only) and slow (buffer-resize) paths.
+ //
+ if (g_PtStateList != NULL)
+ {
+ ExistingSize = g_PtStateList[0].Config.BufferSize;
+ }
+
+ if (ApplyCoreFilterReq.BufferSize != 0 && ApplyCoreFilterReq.BufferSize != ExistingSize)
+ {
+ BufferChanged = TRUE;
+ }
+
+ if (!WasEnabled || BufferChanged)
+ {
+ //
+ // Slow path — PT is off and/or BufferSize changed. We have to
+ // free + reallocate per-CPU buffers at PASSIVE_LEVEL, so we
+ // can't go through DPC for the config seeding either.
+ //
+ PT_TRACE_CONFIG Cfg;
+
+ if (WasEnabled)
+ {
+ BroadcastFlushPtOnAllCores();
+ PtFreeAllCpuBuffers();
+ }
+
+ //
+ // Build a full PT_TRACE_CONFIG (defaults + the user-tunable
+ // fields from the request) and seed it on every CPU so the next
+ // PtAllocateAllCpuBuffers picks up the right BufferSize and
+ // PtEngineStart programs the right RTIT_CTL bits.
+ //
+ HyperTracePtBuildConfig(Req, &Cfg);
+ HyperTracePtSeedConfigOnAllCpus(&Cfg);
+
+ if (WasEnabled)
+ {
+ if (!PtAllocateAllCpuBuffers())
+ {
+ PtFreeAllCpuBuffers();
+ g_ProcessorTraceEnabled = FALSE;
+ if (Req != NULL)
+ {
+ Req->KernelStatus = DEBUGGER_ERROR_PT_NOT_SUPPORTED;
+ }
+ return FALSE;
+ }
+
+ BroadcastEnablePtOnAllCores();
+ }
+ }
+ else
+ {
+ //
+ // Fast filter-only path: PT is running and BufferSize is
+ // unchanged. Force FilterOptions.BufferSize=0 so PtFilter on each core
+ // keeps the buffer that's already allocated, then broadcast.
+ //
+ ApplyCoreFilterReq.BufferSize = 0;
+ BroadcastFilterPtOnAllCores(&ApplyCoreFilterReq);
+ }
+
+ if (Req != NULL)
+ {
+ Req->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Map every per-CPU PT main output + overflow buffer into the
+ * calling user-mode process. See HYPERTRACE_PT_MMAP_PACKETS for
+ * the full lifetime / single-process contract.
+ */
+BOOLEAN
+HyperTracePtMmap(HYPERTRACE_PT_MMAP_PACKETS * Req)
+{
+ if (Req == NULL)
+ return FALSE;
+
+ Req->NumCpus = 0;
+
+ if (!g_HyperTraceCallbacksInitialized)
+ {
+ Req->KernelStatus = DEBUGGER_ERROR_HYPERTRACE_NOT_INITIALIZED;
+ return FALSE;
+ }
+
+ if (!g_ProcessorTraceEnabled)
+ {
+ Req->KernelStatus = DEBUGGER_ERROR_PT_ALREADY_DISABLED;
+ return FALSE;
+ }
+
+ if (PtMmapAllCpuBuffersToUser(Req->Cpus, PT_MAX_CPUS_FOR_MMAP, &Req->NumCpus) != 0)
+ {
+ Req->KernelStatus = DEBUGGER_ERROR_PT_NOT_SUPPORTED;
+ return FALSE;
+ }
+
+ Req->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ return TRUE;
+}
+
+/**
+ * @brief Perform actions related to HyperTrace PT
+ *
+ * @param PtOperationRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTracePtPerformOperation(HYPERTRACE_PT_OPERATION_PACKETS * PtOperationRequest)
+{
+ BOOLEAN Status = TRUE;
+
+ //
+ // Check if the hypertrace module is initialized before performing any operation
+ //
+ if (!g_HyperTraceCallbacksInitialized)
+ {
+ PtOperationRequest->KernelStatus = DEBUGGER_ERROR_HYPERTRACE_NOT_INITIALIZED;
+ return FALSE;
+ }
+
+ //
+ // Perform the requested operation
+ //
+ switch (PtOperationRequest->PtOperationType)
+ {
+ case HYPERTRACE_PT_OPERATION_REQUEST_TYPE_ENABLE:
+
+ LogInfo("HyperTrace: Enabling PT tracing...\n");
+
+ HyperTracePtEnable(PtOperationRequest);
+
+ break;
+
+ case HYPERTRACE_PT_OPERATION_REQUEST_TYPE_DISABLE:
+
+ LogInfo("HyperTrace: Disabling PT tracing...\n");
+
+ HyperTracePtDisable(PtOperationRequest);
+
+ break;
+
+ case HYPERTRACE_PT_OPERATION_REQUEST_TYPE_PAUSE:
+
+ LogInfo("HyperTrace: Pausing PT tracing...\n");
+
+ HyperTracePtPause(PtOperationRequest);
+
+ break;
+
+ case HYPERTRACE_PT_OPERATION_REQUEST_TYPE_RESUME:
+
+ LogInfo("HyperTrace: Resuming PT tracing...\n");
+
+ HyperTracePtResume(PtOperationRequest);
+
+ break;
+
+ case HYPERTRACE_PT_OPERATION_REQUEST_TYPE_SIZE:
+
+ LogInfo("HyperTrace: Snapshotting PT buffer sizes...\n");
+
+ HyperTracePtSize(PtOperationRequest);
+
+ break;
+
+ case HYPERTRACE_PT_OPERATION_REQUEST_TYPE_DUMP:
+
+ LogInfo("HyperTrace: Showing PT tracing...\n");
+
+ HyperTracePtDump(PtOperationRequest);
+
+ break;
+
+ case HYPERTRACE_PT_OPERATION_REQUEST_TYPE_FLUSH:
+
+ LogInfo("HyperTrace: Flushing PT tracing...\n");
+
+ HyperTracePtFlush(PtOperationRequest);
+
+ break;
+
+ case HYPERTRACE_PT_OPERATION_REQUEST_TYPE_FILTER:
+
+ LogInfo("HyperTrace: Updating PT filter / config...\n");
+
+ HyperTracePtFilter(PtOperationRequest);
+
+ break;
+
+ default:
+ Status = FALSE;
+ PtOperationRequest->KernelStatus = DEBUGGER_ERROR_INVALID_HYPERTRACE_OPERATION_TYPE;
+ break;
+ }
+
+ return Status;
+}
diff --git a/hyperdbg/hypertrace/code/api/TraceApi.c b/hyperdbg/hypertrace/code/api/TraceApi.c
new file mode 100644
index 00000000..94f3e961
--- /dev/null
+++ b/hyperdbg/hypertrace/code/api/TraceApi.c
@@ -0,0 +1,165 @@
+/**
+ * @file TraceApi.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Tracing routines for HyperTrace module
+ * @details
+ * @version 0.19
+ * @date 2026-04-25
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ */
+#include "pch.h"
+
+/**
+ * @brief Initialize the hypertrace module callbacks
+ * @details This only for callback initialization, not for LBR, PT, etc. initialization
+ *
+ * @param HyperTraceCallbacks Pointer to the HyperTrace callbacks structure to be registered
+ * @param RunningOnHypervisorEnvironment Whether the initialization is being done for hypervisor environment or not,
+ * it can be used to skip some of the initialization steps if it is not for hypervisor environment and behave differently based on that
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperTraceInitCallback(HYPERTRACE_CALLBACKS * HyperTraceCallbacks,
+ BOOLEAN RunningOnHypervisorEnvironment)
+{
+ UINT32 ProcessorsCount = 0;
+
+ //
+ // Check if any of the required callbacks are NULL
+ //
+ for (UINT32 i = 0; i < sizeof(HYPERTRACE_CALLBACKS) / sizeof(UINT64); i++)
+ {
+ if (((PVOID *)HyperTraceCallbacks)[i] == NULL)
+ {
+ //
+ // The callback has null entry, so we cannot proceed
+ //
+ return FALSE;
+ }
+ }
+
+ //
+ // Save the callbacks
+ //
+ PlatformWriteMemory(&g_Callbacks, HyperTraceCallbacks, sizeof(HYPERTRACE_CALLBACKS));
+
+ //
+ // Query the number of processors in the system to initialize the global LBR state list accordingly
+ //
+ ProcessorsCount = PlatformCpuGetActiveProcessorCount();
+
+ //
+ // Initialize the global LBR state list to hold LBR states for each core
+ //
+ g_LbrStateList = (LBR_STACK_ENTRY *)PlatformMemAllocateZeroedNonPagedPool(sizeof(LBR_STACK_ENTRY) * ProcessorsCount);
+
+ //
+ // Initialize the global PT per-CPU state list. Each entry starts in
+ // PT_STATE_DISABLED with no buffers allocated; PtStart() will lazily
+ // allocate ToPA / output / overflow buffers on first use per core.
+ //
+ g_PtStateList = (PT_PER_CPU *)PlatformMemAllocateZeroedNonPagedPool(sizeof(PT_PER_CPU) * ProcessorsCount);
+
+ if (g_PtStateList != NULL)
+ {
+ UINT32 i;
+ for (i = 0; i < ProcessorsCount; i++)
+ {
+ PtEngineInitDefaultConfig(&g_PtStateList[i].Config);
+ g_PtStateList[i].State = PT_STATE_DISABLED;
+ }
+ }
+
+ //
+ // Set the flag to indicate whether the initialization is being done for hypervisor environment or not
+ //
+ g_RunningOnHypervisorEnvironment = RunningOnHypervisorEnvironment;
+
+ //
+ // It is initialized, but LBR is disabled at this stage
+ //
+ g_LastBranchRecordEnabled = FALSE;
+
+ //
+ // It is initialized, but Processor Trace is disabled at this stage
+ //
+ g_ProcessorTraceEnabled = FALSE;
+
+ //
+ // Enable callbacks and set the initialized flag
+ //
+ g_HyperTraceCallbacksInitialized = TRUE;
+
+ return TRUE;
+}
+
+/**
+ * @brief Uninitialize the hypertrace module
+ *
+ * @return VOID
+ */
+VOID
+HyperTraceUninit()
+{
+ //
+ // Check if the callbacks are initialized, if not, we don't need to handle anymore
+ //
+ if (!g_HyperTraceCallbacksInitialized)
+ {
+ return;
+ }
+
+ //
+ // Disable LBR tracing if it is still enabled
+ //
+ if (g_LastBranchRecordEnabled)
+ {
+ HyperTraceLbrDisable(NULL);
+ }
+
+ //
+ // Unallocate the global LBR state list if it is allocated
+ //
+ if (g_LbrStateList != NULL)
+ {
+ PlatformMemFreePool(g_LbrStateList);
+ g_LbrStateList = NULL;
+ }
+
+ //
+ // Disable Processor Trace if it is still enabled
+ //
+ if (g_ProcessorTraceEnabled)
+ {
+ HyperTracePtDisable(NULL);
+ }
+
+ //
+ // Free PT buffers (if any) and the per-CPU state list
+ //
+ if (g_PtStateList != NULL)
+ {
+ UINT32 ProcessorsCountLocal = KeQueryActiveProcessorCount(0);
+ UINT32 i;
+
+ for (i = 0; i < ProcessorsCountLocal; i++)
+ {
+ PtEngineFreeBuffers(&g_PtStateList[i]);
+ }
+
+ PlatformMemFreePool(g_PtStateList);
+ g_PtStateList = NULL;
+ }
+
+ //
+ // Reset the environment flag to default value
+ //
+ g_RunningOnHypervisorEnvironment = FALSE;
+
+ //
+ // Set callbacks to not initialized
+ //
+ g_HyperTraceCallbacksInitialized = FALSE;
+}
diff --git a/hyperdbg/hypertrace/code/broadcast/Broadcast.c b/hyperdbg/hypertrace/code/broadcast/Broadcast.c
new file mode 100644
index 00000000..0fd14565
--- /dev/null
+++ b/hyperdbg/hypertrace/code/broadcast/Broadcast.c
@@ -0,0 +1,164 @@
+/**
+ * @file Broadcast.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Broadcasting functions
+ * @details
+ * @version 0.19
+ * @date 2026-04-19
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief Routines to enable LBR on all cores
+ *
+ * @return VOID
+ */
+VOID
+BroadcastEnableLbrOnAllCores()
+{
+ //
+ // Broadcast to all cores
+ //
+ KeGenericCallDpc(DpcRoutineEnableLbr, NULL);
+}
+
+/**
+ * @brief Routines to disable LBR on all cores
+ *
+ * @return VOID
+ */
+VOID
+BroadcastDisableLbrOnAllCores()
+{
+ //
+ // Broadcast to all cores
+ //
+ KeGenericCallDpc(DpcRoutineDisableLbr, NULL);
+}
+
+/**
+ * @brief Routines to flush LBR on all cores
+ *
+ * @return VOID
+ */
+VOID
+BroadcastFlushLbrOnAllCores()
+{
+ //
+ // Broadcast to all cores
+ //
+ KeGenericCallDpc(DpcRoutineFlushLbr, NULL);
+}
+
+/**
+ * @brief Routines to filter LBR option on all cores
+ *
+ * @param LbrFilterOptions A bitmask of filter options to apply to the LBR branches
+ *
+ * @return VOID
+ */
+VOID
+BroadcastFilterLbrOptionsOnAllCores(UINT64 LbrFilterOptions)
+{
+ //
+ // Broadcast to all cores
+ //
+ KeGenericCallDpc(DpcRoutineFilterLbrOptions, (PVOID)(UINT_PTR)LbrFilterOptions);
+}
+
+/**
+ * @brief Routines to enable PT on all cores
+ *
+ * @return VOID
+ */
+VOID
+BroadcastEnablePtOnAllCores()
+{
+ KeGenericCallDpc(DpcRoutineEnablePt, NULL);
+}
+
+/**
+ * @brief Routines to disable PT on all cores
+ *
+ * @return VOID
+ */
+VOID
+BroadcastDisablePtOnAllCores()
+{
+ KeGenericCallDpc(DpcRoutineDisablePt, NULL);
+}
+
+/**
+ * @brief Routines to pause PT tracing on all cores
+ *
+ * @return VOID
+ */
+VOID
+BroadcastPausePtOnAllCores()
+{
+ KeGenericCallDpc(DpcRoutinePausePt, NULL);
+}
+
+/**
+ * @brief Routines to resume PT tracing on all cores
+ *
+ * @return VOID
+ */
+VOID
+BroadcastResumePtOnAllCores()
+{
+ KeGenericCallDpc(DpcRoutineResumePt, NULL);
+}
+
+/**
+ * @brief Routines to snapshot per-CPU PT output positions. The DPC
+ * writes its own core's byte count into Sizes[CoreId]; the
+ * caller's UINT64 array must hold at least one slot per CPU.
+ *
+ * @return VOID
+ */
+VOID
+BroadcastSizePtOnAllCores(UINT64 * Sizes)
+{
+ KeGenericCallDpc(DpcRoutineSizePt, (PVOID)Sizes);
+}
+
+/**
+ * @brief Routines to dump PT state on all cores
+ *
+ * @return VOID
+ */
+VOID
+BroadcastDumpPtOnAllCores()
+{
+ KeGenericCallDpc(DpcRoutineDumpPt, NULL);
+}
+
+/**
+ * @brief Routines to flush PT state on all cores
+ *
+ * @return VOID
+ */
+VOID
+BroadcastFlushPtOnAllCores()
+{
+ KeGenericCallDpc(DpcRoutineFlushPt, NULL);
+}
+
+/**
+ * @brief Routines to apply a PT filter on all cores. The same Options
+ * pointer is passed to every per-core DPC; KeGenericCallDpc is
+ * synchronous so the caller's storage is valid throughout.
+ *
+ * @param FilterRequest Pointer to a PT_APPLY_CORE_FILTER_REQUEST structure containing the filter options to apply on all cores
+ *
+ * @return VOID
+ */
+VOID
+BroadcastFilterPtOnAllCores(PT_APPLY_CORE_FILTER_REQUEST * FilterRequest)
+{
+ KeGenericCallDpc(DpcRoutineFilterPt, (PVOID)FilterRequest);
+}
diff --git a/hyperdbg/hypertrace/code/broadcast/DpcRoutines.c b/hyperdbg/hypertrace/code/broadcast/DpcRoutines.c
new file mode 100644
index 00000000..b17accdd
--- /dev/null
+++ b/hyperdbg/hypertrace/code/broadcast/DpcRoutines.c
@@ -0,0 +1,350 @@
+/**
+ * @file DpcRoutines.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief DPC routines
+ * @details
+ * @version 0.19
+ * @date 2026-04-19
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief Broadcast enabling LBR
+ *
+ * @param Dpc
+ * @param DeferredContext
+ * @param SystemArgument1
+ * @param SystemArgument2
+ * @return BOOLEAN
+ */
+BOOLEAN
+DpcRoutineEnableLbr(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
+{
+ UNREFERENCED_PARAMETER(Dpc);
+ UNREFERENCED_PARAMETER(DeferredContext);
+
+ //
+ // Check if the initialization is being done for hypervisor environment or not
+ // If it is, then we need to perform some additional steps to enable LBR in VMX
+ //
+ if (g_RunningOnHypervisorEnvironment)
+ {
+ if (g_ArchBasedLastBranchRecord)
+ {
+ //
+ // Perform VMX-root mode specific operations to load and clear guest
+ // IA32_LBR_CTL MSR (VMCS_GUEST_LBR_CTL) for LBR
+ //
+ g_Callbacks.VmFuncSetLoadGuestIa32LbrCtlVmcallOnTargetCore(TRUE);
+ g_Callbacks.VmFuncSetClearGuestIa32LbrCtlVmcallOnTargetCore(TRUE);
+ }
+ else
+ {
+ //
+ // Perform VMX-root mode specific operations to enable load and save
+ // VM-exit and VM-entry controls for IA32_DEBUGCTL for LBR
+ //
+ g_Callbacks.VmFuncSetSaveDebugControlsVmcallOnTargetCore(TRUE);
+ g_Callbacks.VmFuncSetLoadDebugControlsVmcallOnTargetCore(TRUE);
+ }
+ }
+
+ //
+ // Enable LBR on all cores from VMX-root mode by VMCALL
+ // By default, all filter options are disabled, which means all branch types will be captured
+ //
+ LbrStart(LBR_SELECT_WITHOUT_FILTER);
+
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
+ //
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
+
+ return TRUE;
+}
+
+/**
+ * @brief Broadcast disabling LBR
+ *
+ * @param Dpc
+ * @param DeferredContext
+ * @param SystemArgument1
+ * @param SystemArgument2
+ * @return BOOLEAN
+ */
+BOOLEAN
+DpcRoutineDisableLbr(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
+{
+ UNREFERENCED_PARAMETER(Dpc);
+ UNREFERENCED_PARAMETER(DeferredContext);
+
+ //
+ // Disable LBR on all cores from VMX-root mode by VMCALL
+ //
+ LbrStop();
+
+ //
+ // Check if the initialization is being done for hypervisor environment or not
+ // If it is, then we need to perform some additional steps to enable LBR in VMX
+ //
+ if (g_RunningOnHypervisorEnvironment)
+ {
+ if (g_ArchBasedLastBranchRecord)
+ {
+ //
+ // Perform VMX-root mode specific operations to disable load and clear guest
+ // IA32_LBR_CTL MSR (VMCS_GUEST_LBR_CTL) for LBR
+ //
+ g_Callbacks.VmFuncSetLoadGuestIa32LbrCtlVmcallOnTargetCore(FALSE);
+ g_Callbacks.VmFuncSetClearGuestIa32LbrCtlVmcallOnTargetCore(FALSE);
+ }
+ else
+ {
+ //
+ // Perform VMX-root mode specific operations to disable load and save
+ // VM-exit and VM-entry controls for IA32_DEBUGCTL for LBR
+ //
+ g_Callbacks.VmFuncSetSaveDebugControlsVmcallOnTargetCore(FALSE);
+ g_Callbacks.VmFuncSetLoadDebugControlsVmcallOnTargetCore(FALSE);
+ }
+ }
+
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
+ //
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
+
+ return TRUE;
+}
+
+/**
+ * @brief Broadcast flushing LBR
+ *
+ * @param Dpc
+ * @param DeferredContext
+ * @param SystemArgument1
+ * @param SystemArgument2
+ * @return BOOLEAN
+ */
+BOOLEAN
+DpcRoutineFlushLbr(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
+{
+ UNREFERENCED_PARAMETER(Dpc);
+ UNREFERENCED_PARAMETER(DeferredContext);
+
+ //
+ // Flush LBR on all cores
+ //
+ LbrFlush();
+
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
+ //
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
+
+ return TRUE;
+}
+
+/**
+ * @brief Broadcast updating LBR filter options
+ *
+ * @param Dpc
+ * @param DeferredContext
+ * @param SystemArgument1
+ * @param SystemArgument2
+ * @return BOOLEAN
+ */
+BOOLEAN
+DpcRoutineFilterLbrOptions(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
+{
+ UNREFERENCED_PARAMETER(Dpc);
+
+ //
+ // Flush LBR on all cores
+ //
+ LbrFilter((UINT64)DeferredContext);
+
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
+ //
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
+
+ return TRUE;
+}
+
+/**
+ * @brief Broadcast enabling PT
+ *
+ * @param Dpc
+ * @param DeferredContext
+ * @param SystemArgument1
+ * @param SystemArgument2
+ * @return BOOLEAN
+ */
+BOOLEAN
+DpcRoutineEnablePt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
+{
+ UNREFERENCED_PARAMETER(Dpc);
+ UNREFERENCED_PARAMETER(DeferredContext);
+
+ //
+ // Enable PT on the current core. PT in the current implementation is
+ // controlled via direct MSR writes from kernel context; if PT is later
+ // wired into VMCS save/load controls, the corresponding hypervisor
+ // helpers should be invoked here similar to DpcRoutineEnableLbr.
+ //
+ PtStart();
+
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
+ //
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
+
+ return TRUE;
+}
+
+/**
+ * @brief Broadcast disabling PT
+ */
+BOOLEAN
+DpcRoutineDisablePt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
+{
+ UNREFERENCED_PARAMETER(Dpc);
+ UNREFERENCED_PARAMETER(DeferredContext);
+
+ PtStop();
+
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
+ //
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
+
+ return TRUE;
+}
+
+/**
+ * @brief Broadcast pausing PT
+ */
+BOOLEAN
+DpcRoutinePausePt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
+{
+ UNREFERENCED_PARAMETER(Dpc);
+ UNREFERENCED_PARAMETER(DeferredContext);
+
+ PtPause();
+
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
+ //
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
+
+ return TRUE;
+}
+
+/**
+ * @brief Broadcast resuming PT
+ */
+BOOLEAN
+DpcRoutineResumePt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
+{
+ UNREFERENCED_PARAMETER(Dpc);
+ UNREFERENCED_PARAMETER(DeferredContext);
+
+ PtResume();
+
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
+ //
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
+
+ return TRUE;
+}
+
+/**
+ * @brief Broadcast snapshotting per-CPU PT output position.
+ *
+ * DeferredContext is a UINT64 array (one slot per active CPU);
+ * each per-core DPC writes its own core's byte count and never
+ * touches another slot, so no synchronisation is required.
+ */
+BOOLEAN
+DpcRoutineSizePt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
+{
+ UINT64 * Sizes = (UINT64 *)DeferredContext;
+ UINT32 Core = KeGetCurrentProcessorNumberEx(NULL);
+
+ UNREFERENCED_PARAMETER(Dpc);
+
+ if (Sizes != NULL && Core < PT_MAX_CPUS_FOR_MMAP)
+ Sizes[Core] = PtSize();
+
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
+ //
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
+
+ return TRUE;
+}
+
+/**
+ * @brief Broadcast dumping PT state
+ */
+BOOLEAN
+DpcRoutineDumpPt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
+{
+ UNREFERENCED_PARAMETER(Dpc);
+ UNREFERENCED_PARAMETER(DeferredContext);
+
+ PtDump();
+
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
+ //
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
+
+ return TRUE;
+}
+
+/**
+ * @brief Broadcast flushing PT state
+ */
+BOOLEAN
+DpcRoutineFlushPt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
+{
+ UNREFERENCED_PARAMETER(Dpc);
+ UNREFERENCED_PARAMETER(DeferredContext);
+
+ PtFlush();
+
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
+ //
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
+
+ return TRUE;
+}
+
+/**
+ * @brief Broadcast applying a PT filter to all cores.
+ *
+ * DeferredContext carries the PT_APPLY_CORE_FILTER_REQUEST * supplied by the
+ * broadcaster; PtFilter writes the user-tunable fields into the
+ * current CPU's per-CPU PT_TRACE_CONFIG and reprograms PT MSRs.
+ */
+BOOLEAN
+DpcRoutineFilterPt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
+{
+ UNREFERENCED_PARAMETER(Dpc);
+
+ PtFilter((const PT_APPLY_CORE_FILTER_REQUEST *)DeferredContext);
+
+ // ------------------------------------------------------------------------------
+ // Synchronize the end of this routine with the caller
+ //
+ PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
+
+ return TRUE;
+}
diff --git a/hyperdbg/hypertrace/code/common/UnloadDll.c b/hyperdbg/hypertrace/code/common/UnloadDll.c
new file mode 100644
index 00000000..17321dbf
--- /dev/null
+++ b/hyperdbg/hypertrace/code/common/UnloadDll.c
@@ -0,0 +1,45 @@
+/**
+ * @file UnloadDll.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Unloading DLL in the target Windows
+ * @details
+ * @version 0.4
+ * @date 2023-07-06
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+//
+// We'll add these functions, so whenever HyperDbg's driver is unloaded
+// DllUnload will be called to unload this dll from the memory.
+// this way we can remove the HyperDbg after unloading as there is no
+// other module remains loaded in the memory.
+//
+
+/**
+ * @brief Routine called on DLL initialization
+ *
+ * @param RegistryPath The registry path of the driver
+ * @return NTSTATUS
+ */
+NTSTATUS
+DllInitialize(
+ _In_ PUNICODE_STRING RegistryPath)
+{
+ UNREFERENCED_PARAMETER(RegistryPath);
+
+ return STATUS_SUCCESS;
+}
+
+/**
+ * @brief Routine called on DLL unload
+ *
+ * @return NTSTATUS
+ */
+NTSTATUS
+DllUnload(VOID)
+{
+ return STATUS_SUCCESS;
+}
diff --git a/hyperdbg/hypertrace/code/lbr/Lbr.c b/hyperdbg/hypertrace/code/lbr/Lbr.c
new file mode 100644
index 00000000..de3d8c99
--- /dev/null
+++ b/hyperdbg/hypertrace/code/lbr/Lbr.c
@@ -0,0 +1,1266 @@
+/**
+ * @file Lbr.c
+ * @author Hari Mishal (harimishal6@gmail.com)
+ * @brief Last Branch Record (LBR) tracing implementation for HyperTrace module
+ * @details Modified from LIBIHT project (Thomasaon Zhao et al) with Windows style updates.
+ * @version 0.18
+ * @date 2025-12-02
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ */
+#include "pch.h"
+
+//////////////////////////////////////////////////
+// Global Definitions //
+//////////////////////////////////////////////////
+
+//
+// Typical Intel LBR capacities based on CPU model
+// This is a subset; you can expand this as needed
+//
+CPU_LBR_MAP CPU_LBR_MAPS[] = {
+ {0x5c, 32},
+ {0x5f, 32},
+ {0x4e, 32},
+ {0x5e, 32},
+ {0x8e, 32},
+ {0x9e, 32},
+ {0x55, 32},
+ {0x66, 32},
+ {0x7a, 32},
+ {0x67, 32},
+ {0x6a, 32},
+ {0x6c, 32},
+ {0x7d, 32},
+ {0x7e, 32},
+ {0x8c, 32},
+ {0x8d, 32},
+ {0xa5, 32},
+ {0xa6, 32},
+ {0xa7, 32},
+ {0xa8, 32},
+ {0x86, 32},
+ {0x8a, 32},
+ {0x96, 32},
+ {0x9c, 32},
+ {0x3d, 16},
+ {0x47, 16},
+ {0x4f, 16},
+ {0x56, 16},
+ {0x3c, 16},
+ {0x45, 16},
+ {0x46, 16},
+ {0x3f, 16},
+ {0x2a, 16},
+ {0x2d, 16},
+ {0x3a, 16},
+ {0x3e, 16},
+ {0x1a, 16},
+ {0x1e, 16},
+ {0x1f, 16},
+ {0x2e, 16},
+ {0x25, 16},
+ {0x2c, 16},
+ {0x2f, 16},
+ {0x17, 4},
+ {0x1d, 4},
+ {0x0f, 4},
+ {0x37, 8},
+ {0x4a, 8},
+ {0x4c, 8},
+ {0x4d, 8},
+ {0x5a, 8},
+ {0x5d, 8},
+ {0x1c, 8},
+ {0x26, 8},
+ {0x27, 8},
+ {0x35, 8},
+ {0x36, 8}};
+
+/**
+ * @brief Check if the current CPU supports architectural LBR
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+LbrCheckAndReadArchitecturalLbrDetails()
+{
+ ULONG a, b, c, d;
+
+ CPUID_EAX_07 Edx07 = {0};
+
+ CPUID28_EAX Eax1c = {0};
+ CPUID28_EBX Ebx1c = {0};
+ CPUID28_ECX Ecx1c = {0};
+
+ //
+ // Check for Architectural LBR support
+ //
+ //
+ xcpuidex(CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, 0x00, &a, &b, &c, &d);
+
+ Edx07.Edx.AsUInt = d;
+
+ //
+ // CPUID.07H.00H:EDX[19] == 1 means arch LBR is supported
+ //
+ if (Edx07.Edx.AsUInt & (1 << 19))
+ {
+ g_ArchBasedLastBranchRecord = TRUE;
+ }
+ else
+ {
+ //
+ // Architectural LBR is not supported by the CPU
+ //
+ g_ArchBasedLastBranchRecord = FALSE;
+
+ return FALSE;
+ }
+
+ //
+ // Being here means the CPU supports architectural LBR, we can read the LBR capabilities from CPUID 0x1c leaf
+ //
+ xcpuidex(CPUID_ARCH_LAST_BRANCH_RECORD_INFORMATION, 0x00, &a, &b, &c, &d);
+
+ //
+ // Assign LBR leafs to structure for easier access
+ //
+ Eax1c.AsUInt = a;
+ Ebx1c.AsUInt = b;
+ Ecx1c.AsUInt = c;
+
+ //
+ // Store the CPUID.1CH leaf information in a global structure for later use
+ //
+ g_Cpuid28Leafs.Eax = Eax1c;
+ g_Cpuid28Leafs.Ebx = Ebx1c;
+ g_Cpuid28Leafs.Ecx = Ecx1c;
+ g_Cpuid28Leafs.Edx = d;
+
+ //
+ // Read LBR capacity from CPUID.1CH.00H:EAX[7:0]
+ // Based on Intel SDM: For each bit n set in this field, the IA32_LBR_DEPTH.DEPTH value 8 * (n + 1) is supported
+ //
+ if (Eax1c.LbrDepthMask)
+ {
+ //
+ // Get the highest set bit in LbrDepthMask to determine the maximum supported LBR depth
+ //
+ ULONG HighestSetBit = 0;
+ for (ULONG i = 0; i < 8; i++)
+ {
+ if (Eax1c.LbrDepthMask & (1 << i))
+ {
+ HighestSetBit = i;
+ }
+ }
+ g_LbrCapacity = 8 * (HighestSetBit + 1);
+ }
+ else
+ {
+ //
+ // If LbrDepthMask is 0, it means the CPU supports architectural LBR but does not specify the depth, we can assume a default value (e.g., 16 or 32) or treat it as unsupported
+ //
+ g_LbrCapacity = MAXIMUM_LBR_CAPACITY; // Assuming a default capacity of MAXIMUM_LBR_CAPACITY if not specified
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Check if the current CPU supports LBR by examining the CPU family and model and looking up the corresponding LBR capacity
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+LbrCheckAndReadLegacyLbrDetails()
+{
+ ULONG a, b, c, d;
+ ULONG Family, Model;
+ ULONGLONG i;
+
+ xcpuid(1, &a, &b, &c, &d);
+
+ Family = ((a >> 8) & 0xF) + ((a >> 20) & 0xFF);
+ Model = ((a >> 4) & 0xF) | ((a >> 12) & 0xF0);
+
+ for (i = 0; i < sizeof(CPU_LBR_MAPS) / sizeof(CPU_LBR_MAPS[0]); ++i)
+ {
+ if (Model == CPU_LBR_MAPS[i].Model)
+ {
+ g_LbrCapacity = CPU_LBR_MAPS[i].LbrCapacity;
+ break;
+ }
+ }
+
+ if (g_LbrCapacity == 0)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Check and adjust compatibility of LBR filterings for ARCH based LBR
+ *
+ * @return VOID
+ */
+VOID
+LbrAdjustArchBasedFilteringCompatibility(IA32_LBR_CTL_REGISTER * Ia32LbrCtl)
+{
+ //
+ // Check capabilities and apply necessary adjustments based on CPU support
+ //
+ if (!g_Cpuid28Leafs.Ebx.LbrCpl)
+ {
+ //
+ // If CPL filtering is not supported
+ // we cannot filter kernel vs user mode branches, so we clear those filter bits to avoid confusion
+ //
+ Ia32LbrCtl->Bits.OS = 0;
+ Ia32LbrCtl->Bits.USR = 0;
+ }
+
+ if (!g_Cpuid28Leafs.Ebx.LbrFilter)
+ {
+ //
+ // If branch filtering is not supported, we cannot filter by branch type, so we clear all the specific branch type filter bits
+ //
+ Ia32LbrCtl->Bits.JCC = 0;
+ Ia32LbrCtl->Bits.NearRelJmp = 0;
+ Ia32LbrCtl->Bits.NearIndJmp = 0;
+ Ia32LbrCtl->Bits.NearRelCall = 0;
+ Ia32LbrCtl->Bits.NearIndCall = 0;
+ Ia32LbrCtl->Bits.NearRet = 0;
+ Ia32LbrCtl->Bits.OtherBranch = 0;
+ }
+
+ if (!g_Cpuid28Leafs.Ebx.LbrCallStack)
+ {
+ //
+ // If call-stack mode is not supported, we cannot filter by call stack, so we clear that filter bit
+ //
+ Ia32LbrCtl->Bits.CallStack = 0;
+ }
+}
+
+/**
+ * @brief Convert a filter options bitmask into IA32_LBR_CTL format for architectural LBR
+ *
+ * @param FilterOptions A bitmask of filter options (e.g., LBR_KERNEL, LBR_USER, LBR_JCC, etc.)
+ * @param Ia32LbrCtl Pointer to the IA32_LBR_CTL_REGISTER to populate with the converted filter bits
+ * @return VOID
+ */
+VOID
+LbrBuildArchBasedFilterOptions(UINT64 FilterOptions, IA32_LBR_CTL_REGISTER * Ia32LbrCtl)
+{
+ //
+ // By default, we are enabling all of them
+ //
+ Ia32LbrCtl->Bits.OS = 1;
+ Ia32LbrCtl->Bits.USR = 1;
+ Ia32LbrCtl->Bits.JCC = 1;
+ Ia32LbrCtl->Bits.NearRelCall = 1;
+ Ia32LbrCtl->Bits.NearIndCall = 1;
+ Ia32LbrCtl->Bits.NearRet = 1;
+ Ia32LbrCtl->Bits.NearIndJmp = 1;
+ Ia32LbrCtl->Bits.NearRelJmp = 1;
+ Ia32LbrCtl->Bits.OtherBranch = 1;
+ Ia32LbrCtl->Bits.CallStack = 1;
+
+ //
+ // Perform filtering the results
+ //
+ if (FilterOptions & LBR_KERNEL)
+ {
+ Ia32LbrCtl->Bits.OS = 0;
+ }
+
+ if (FilterOptions & LBR_USER)
+ {
+ Ia32LbrCtl->Bits.USR = 0;
+ }
+
+ if (FilterOptions & LBR_JCC)
+ {
+ Ia32LbrCtl->Bits.JCC = 0;
+ }
+
+ if (FilterOptions & LBR_REL_CALL)
+ {
+ Ia32LbrCtl->Bits.NearRelCall = 0;
+ }
+
+ if (FilterOptions & LBR_IND_CALL)
+ {
+ Ia32LbrCtl->Bits.NearIndCall = 0;
+ }
+
+ if (FilterOptions & LBR_RETURN)
+ {
+ Ia32LbrCtl->Bits.NearRet = 0;
+ }
+
+ if (FilterOptions & LBR_IND_JMP)
+ {
+ Ia32LbrCtl->Bits.NearIndJmp = 0;
+ }
+
+ if (FilterOptions & LBR_REL_JMP)
+ {
+ Ia32LbrCtl->Bits.NearRelJmp = 0;
+ }
+
+ if (FilterOptions & LBR_FAR_OTHER_BRANCHES)
+ {
+ Ia32LbrCtl->Bits.OtherBranch = 0;
+ }
+
+ if (FilterOptions & LBR_CALL_STACK)
+ {
+ Ia32LbrCtl->Bits.CallStack = 0;
+ }
+
+ //
+ // Adjust LBR fitlering options based on the CPU capabilities to ensure we are not setting unsupported filter bits
+ //
+ LbrAdjustArchBasedFilteringCompatibility(Ia32LbrCtl);
+}
+/**
+ * @brief Set the LBR select filter MSR (MSR_LEGACY_LBR_SELECT) for legacy LBR,
+ * dispatching via VMCALL when in VMX non-root mode
+ *
+ * @details This function is only relevant for legacy LBR. Architectural LBR encodes
+ * filter options directly in IA32_LBR_CTL and does not use MSR_LEGACY_LBR_SELECT.
+ * Note: Even though MSR_LEGACY_LBR_SELECT is a plain MSR (not a VMCS field), it
+ * must be set from VMX-root mode for the LBR MSRs to work correctly.
+ *
+ * @param FilterOptions The raw filter options bitmask to write into MSR_LEGACY_LBR_SELECT
+ * @return VOID
+ */
+VOID
+LbrSetLbrSelectFilter(UINT64 FilterOptions)
+{
+ BOOLEAN IsOnVmxRootMode;
+
+ if (g_RunningOnHypervisorEnvironment)
+ {
+ IsOnVmxRootMode = g_Callbacks.VmFuncVmxGetCurrentExecutionMode();
+
+ //
+ // If we don't set it on VMX-root mode, the LBR MSRs won't work based on our tests
+ // even though it is just a plain MSR (and not a VMCS field)
+ //
+ if (IsOnVmxRootMode)
+ {
+ //
+ // It is on VMX-root mode, run it directly to set the MSR_LEGACY_LBR_SELECT MSR value
+ //
+ g_Callbacks.VmFuncSetLbrSelect(FilterOptions);
+ }
+ else
+ {
+ //
+ // It is not on VMX-root mode, so we need to perform a VMCALL to set the MSR_LEGACY_LBR_SELECT MSR value on the target core
+ //
+ g_Callbacks.VmFuncSetLbrSelectVmcallOnTargetCore(FilterOptions);
+ }
+ }
+ else
+ {
+ xwrmsr(MSR_LEGACY_LBR_SELECT, FilterOptions);
+ }
+}
+
+/**
+ * @brief Zero out the LBR hardware state (TOS and all from/to MSR pairs)
+ *
+ * @details For architectural LBR the TOS index is not maintained by software and the CPU
+ * shifts entries automatically, so MSR_LBR_TOS is skipped in that case.
+ *
+ * @return VOID
+ */
+VOID
+LbrClearHardwareState()
+{
+ //
+ // For architectural LBR, the TOS is not used; the CPU shifts LBR entries automatically
+ // and does not update the TOS index
+ //
+ if (!g_ArchBasedLastBranchRecord)
+ {
+ xwrmsr(MSR_LBR_TOS, 0);
+ }
+
+ //
+ // Clearing LBR TO and FROM MSRs
+ //
+ for (ULONG i = 0; i < (ULONG)g_LbrCapacity; i++)
+ {
+ if (g_ArchBasedLastBranchRecord)
+ {
+ xwrmsr(IA32_LBR_0_FROM_IP + i, 0);
+ xwrmsr(IA32_LBR_0_TO_IP + i, 0);
+ }
+ else
+ {
+ xwrmsr(MSR_LASTBRANCH_0_FROM_IP + i, 0);
+ xwrmsr(MSR_LASTBRANCH_0_TO_IP + i, 0);
+ }
+ }
+}
+
+/**
+ * @brief Enable LBR collection on architectural (ARCH) based LBR
+ *
+ * @param Ia32LbrCtl Pointer to the IA32_LBR_CTL_REGISTER whose LBREn bit will be set
+ * @return VOID
+ */
+VOID
+LbrEnableArchBased(IA32_LBR_CTL_REGISTER * Ia32LbrCtl)
+{
+ Ia32LbrCtl->Bits.LBREn = 1;
+}
+
+/**
+ * @brief Enable LBR collection on legacy based LBR
+ *
+ * @param DbgCtlMsr Pointer to the IA32_DEBUGCTL MSR value to be modified
+ * @return VOID
+ */
+VOID
+LbrEnableLegacyBased(ULONGLONG * DbgCtlMsr)
+{
+ //
+ // Enable LBR and CLEAR 'Freeze LBRs on PMI' (Bit 11)
+ // If Bit 11 is set, the LBR stops recording as soon as a single PMI interrupt fires
+ //
+ *DbgCtlMsr |= IA32_DEBUGCTL_LBR_FLAG; // Bit 0 = 1
+ *DbgCtlMsr &= ~(1ULL << IA32_DEBUGCTL_FREEZE_LBRS_ON_PMI_BIT); // Bit 11 = 0
+}
+
+/**
+ * @brief Start LBR collection when running natively (outside any hypervisor environment)
+ *
+ * @param Ia32LbrCtl The pre-built IA32_LBR_CTL_REGISTER value carrying the filter bits (arch LBR)
+ * @return VOID
+ */
+VOID
+LbrStartOnNativeMode(IA32_LBR_CTL_REGISTER Ia32LbrCtl)
+{
+ ULONGLONG DbgCtlMsr = 0;
+
+ if (g_ArchBasedLastBranchRecord)
+ {
+ //
+ // No need to read the existing control since we are replacing it entirely for ARCH LBR
+ //
+ LbrEnableArchBased(&Ia32LbrCtl);
+ xwrmsr(IA32_LBR_CTL, Ia32LbrCtl.AsUInt);
+ }
+ else
+ {
+ xrdmsr(IA32_DEBUGCTL, &DbgCtlMsr);
+ LbrEnableLegacyBased(&DbgCtlMsr);
+ xwrmsr(IA32_DEBUGCTL, DbgCtlMsr);
+ }
+}
+
+/**
+ * @brief Read current LBR control register values while in VMX root-mode
+ *
+ * @param DbgCtlMsr Pointer to receive the IA32_DEBUGCTL MSR value (legacy LBR)
+ * @param Ia32LbrCtl Pointer to receive the IA32_LBR_CTL register value (arch LBR)
+ * @return VOID
+ */
+VOID
+LbrGetValuesOnVmxRootMode(ULONGLONG * DbgCtlMsr, IA32_LBR_CTL_REGISTER * Ia32LbrCtl)
+{
+ if (g_ArchBasedLastBranchRecord)
+ {
+ //
+ // It is on VMX-root mode, run it directly to get the IA32_LBR_CTL value in VMCS
+ //
+ Ia32LbrCtl->AsUInt = g_Callbacks.VmFuncGetGuestIa32LbrCtl();
+ }
+ else
+ {
+ //
+ // It is on VMX-root mode, run it directly to get the IA32_DEBUGCTL MSR value in VMCS
+ //
+ *DbgCtlMsr = g_Callbacks.VmFuncGetDebugctl();
+ }
+}
+
+/**
+ * @brief Read current LBR control register values while in VMX non-root mode (via VMCALL)
+ *
+ * @param DbgCtlMsr Pointer to receive the IA32_DEBUGCTL MSR value (legacy LBR)
+ * @param Ia32LbrCtl Pointer to receive the IA32_LBR_CTL register value (arch LBR)
+ * @return VOID
+ */
+VOID
+LbrGetValuesOnVmxNonRootMode(ULONGLONG * DbgCtlMsr, IA32_LBR_CTL_REGISTER * Ia32LbrCtl)
+{
+ if (g_ArchBasedLastBranchRecord)
+ {
+ //
+ // It is not on VMX-root mode, so we need to perform a VMCALL to get the IA32_LBR_CTL value on the target core
+ //
+ Ia32LbrCtl->AsUInt = g_Callbacks.VmFuncGetGuestIa32LbrCtlVmcallOnTargetCore();
+ }
+ else
+ {
+ //
+ // It is not on VMX-root mode, so we need to perform a VMCALL to get the IA32_DEBUGCTL MSR value on the target core
+ //
+ *DbgCtlMsr = g_Callbacks.VmFuncGetDebugctlVmcallOnTargetCore();
+ }
+}
+
+/**
+ * @brief Disable LBR collection on architectural (ARCH) based LBR
+ *
+ * @param Ia32LbrCtl Pointer to the IA32_LBR_CTL register whose LBREn bit will be cleared
+ * @return VOID
+ */
+VOID
+LbrDisableArchBased(IA32_LBR_CTL_REGISTER * Ia32LbrCtl)
+{
+ Ia32LbrCtl->Bits.LBREn = 0;
+}
+
+/**
+ * @brief Disable LBR collection on legacy based LBR
+ *
+ * @param DbgCtlMsr Pointer to the IA32_DEBUGCTL MSR value whose LBR flag will be cleared
+ * @return VOID
+ */
+VOID
+LbrDisableLegacyBased(ULONGLONG * DbgCtlMsr)
+{
+ *DbgCtlMsr &= ~IA32_DEBUGCTL_LBR_FLAG;
+}
+
+/**
+ * @brief Write back modified LBR control register values while in VMX root-mode
+ *
+ * @param DbgCtlMsr The updated IA32_DEBUGCTL MSR value to apply (legacy LBR)
+ * @param Ia32LbrCtl The updated IA32_LBR_CTL register value to apply (arch LBR)
+ * @return VOID
+ */
+VOID
+LbrSetValuesOnVmxRootMode(ULONGLONG DbgCtlMsr, IA32_LBR_CTL_REGISTER Ia32LbrCtl)
+{
+ if (g_ArchBasedLastBranchRecord)
+ {
+ //
+ // It is on VMX-root mode, run it directly to set the IA32_LBR_CTL value in VMCS
+ //
+ g_Callbacks.VmFuncSetGuestIa32LbrCtl(Ia32LbrCtl.AsUInt);
+ }
+ else
+ {
+ //
+ // It is on VMX-root mode, run it directly to set the IA32_DEBUGCTL MSR value in VMCS
+ //
+ g_Callbacks.VmFuncSetDebugctl(DbgCtlMsr);
+ }
+}
+
+/**
+ * @brief Write back modified LBR control register values while in VMX non-root mode (via VMCALL)
+ *
+ * @param DbgCtlMsr The updated IA32_DEBUGCTL MSR value to apply (legacy LBR)
+ * @param Ia32LbrCtl The updated IA32_LBR_CTL register value to apply (arch LBR)
+ * @return VOID
+ */
+VOID
+LbrSetValuesOnVmxNonRootMode(ULONGLONG DbgCtlMsr, IA32_LBR_CTL_REGISTER Ia32LbrCtl)
+{
+ if (g_ArchBasedLastBranchRecord)
+ {
+ //
+ // It is not on VMX-root mode, so we need to perform a VMCALL to set the IA32_LBR_CTL value on the target core
+ //
+ g_Callbacks.VmFuncSetGuestIa32LbrCtlVmcallOnTargetCore(Ia32LbrCtl.AsUInt);
+ }
+ else
+ {
+ //
+ // It is not on VMX-root mode, so we need to perform a VMCALL to set the IA32_DEBUGCTL MSR value on the target core
+ //
+ g_Callbacks.VmFuncSetDebugctlVmcallOnTargetCore(DbgCtlMsr);
+ }
+}
+
+/**
+ * @brief Stop LBR collection when running natively (outside any hypervisor environment)
+ *
+ * @return VOID
+ */
+VOID
+LbrStopOnNativeMode()
+{
+ ULONGLONG DbgCtlMsr = NULL64_ZERO;
+ IA32_LBR_CTL_REGISTER Ia32LbrCtl = {0};
+
+ if (g_ArchBasedLastBranchRecord)
+ {
+ xrdmsr(IA32_LBR_CTL, &Ia32LbrCtl.AsUInt);
+ LbrDisableArchBased(&Ia32LbrCtl);
+ xwrmsr(IA32_LBR_CTL, Ia32LbrCtl);
+ }
+ else
+ {
+ xrdmsr(IA32_DEBUGCTL, &DbgCtlMsr);
+ LbrDisableLegacyBased(&DbgCtlMsr);
+ xwrmsr(IA32_DEBUGCTL, DbgCtlMsr);
+ }
+}
+
+/**
+ * @brief Zero the ARCH LBR control register while in VMX root-mode
+ *
+ * @details Setting IA32_LBR_CTL to 0 simultaneously clears all filter bits and
+ * disables collection (LBREn = 0), which is the correct flush state.
+ *
+ * @return VOID
+ */
+VOID
+LbrResetArchControlOnVmxRootMode()
+{
+ //
+ // It is on VMX-root mode, set the entire IA32_LBR_CTL to 0 directly in VMCS
+ // (this also disables LBR since LBREn is cleared)
+ //
+ g_Callbacks.VmFuncSetGuestIa32LbrCtl(0);
+}
+
+/**
+ * @brief Zero the ARCH LBR control register while in VMX non-root mode (via VMCALL)
+ *
+ * @details Setting IA32_LBR_CTL to 0 simultaneously clears all filter bits and
+ * disables collection (LBREn = 0), which is the correct flush state.
+ *
+ * @return VOID
+ */
+VOID
+LbrResetArchControlOnVmxNonRootMode()
+{
+ //
+ // It is not on VMX-root mode, perform a VMCALL to set the entire IA32_LBR_CTL to 0 on the target core
+ // (this also disables LBR since LBREn is cleared)
+ //
+ g_Callbacks.VmFuncSetGuestIa32LbrCtlVmcallOnTargetCore(0);
+}
+
+/**
+ * @brief Reset the LBR control registers to zero, covering both ARCH and legacy LBR
+ * across all execution environments (native, VMX root-mode, VMX non-root mode)
+ *
+ * @details For architectural LBR, IA32_LBR_CTL is zeroed entirely (clearing filter bits
+ * and disabling collection in one write). For legacy LBR, MSR_LEGACY_LBR_SELECT
+ * is zeroed to reset the branch filter to its default capture-all state.
+ * Note: Even though MSR_LEGACY_LBR_SELECT is a plain MSR (not a VMCS field),
+ * it must be written from VMX-root mode for the change to take effect.
+ *
+ * @return VOID
+ */
+VOID
+LbrResetControlRegisters()
+{
+ BOOLEAN IsOnVmxRootMode;
+
+ if (g_RunningOnHypervisorEnvironment)
+ {
+ IsOnVmxRootMode = g_Callbacks.VmFuncVmxGetCurrentExecutionMode();
+
+ //
+ // If we don't set it on VMX-root mode, the LBR MSRs won't work based on our tests
+ // even though it is just a plain MSR (and not a VMCS field)
+ //
+ if (IsOnVmxRootMode)
+ {
+ if (g_ArchBasedLastBranchRecord)
+ {
+ LbrResetArchControlOnVmxRootMode();
+ }
+ else
+ {
+ //
+ // Reuse LbrSetLbrSelectFilter: writing 0 resets MSR_LEGACY_LBR_SELECT to
+ // its default state (capture all branch types) from VMX-root mode
+ //
+ g_Callbacks.VmFuncSetLbrSelect(0);
+ }
+ }
+ else
+ {
+ if (g_ArchBasedLastBranchRecord)
+ {
+ LbrResetArchControlOnVmxNonRootMode();
+ }
+ else
+ {
+ //
+ // Reuse LbrSetLbrSelectFilter: writing 0 resets MSR_LEGACY_LBR_SELECT to
+ // its default state (capture all branch types) via VMCALL on the target core
+ //
+ g_Callbacks.VmFuncSetLbrSelectVmcallOnTargetCore(0);
+ }
+ }
+ }
+ else
+ {
+ if (g_ArchBasedLastBranchRecord)
+ {
+ xwrmsr(IA32_LBR_CTL, 0);
+ }
+ else
+ {
+ xwrmsr(MSR_LEGACY_LBR_SELECT, 0);
+ }
+ }
+}
+
+/**
+ * @brief Adjust filter options for call stack
+ *
+ * @param FilterOptions A bitmask of filter options
+ * @return VOID
+ */
+VOID
+LbrAdjustFilterOptionsForCallStack(UINT64 * FilterOptions)
+{
+ //
+ // Call-stack mode should be used with branch type enabling configured to capture only CALLs (NEAR_REL_CALL and
+ // NEAR_IND_CALL) and RETs (NEAR_RET). When configured in this manner, the LBR array emulates a call stack,
+ // where CALLs are "pushed" and RETs "pop" them off the stack. If other branch types (JCC, NEAR_*_JMP, or
+ // OTHER_BRANCH) are enabled for recording with call-stack mode, LBR behavior may be undefined, so we will
+ // mask out any branch type filters that are not CALLs or RETs when call-stack mode is requested to ensure
+ // we are correctly emulating a call stack and avoiding undefined behavior
+ //
+
+ //
+ // If it is call_stack then we only keep the user and kernel bit and filter all branch types
+ // except calls and rets to ensure we are only capturing call stack profile
+ //
+ if (*FilterOptions & LBR_CALL_STACK)
+ {
+ //
+ // Preserve only the user/kernel privilege bits from the original options,
+ // then apply the mandatory call stack base flags
+ //
+ *FilterOptions = LBR_CALL_STACK_BASE_FLAGS | (*FilterOptions & (LBR_KERNEL | LBR_USER));
+ }
+}
+
+/**
+ * @brief Adjust filter options
+ *
+ * @param FilterOptions A bitmask of filter options
+ * @param Ia32LbrCtl Pointer to the IA32_LBR_CTL_REGISTER to adjust based on the filter options and CPU capabilities
+ *
+ * @return VOID
+ */
+VOID
+LbrAdjustFilterOptions(UINT64 FilterOptions, IA32_LBR_CTL_REGISTER * Ia32LbrCtl)
+{
+ //
+ // Adjust filter options in case of call_stack
+ //
+ LbrAdjustFilterOptionsForCallStack(&FilterOptions);
+
+ //
+ // Save the LBR filter options to a global variable for later use
+ //
+ g_LbrFilterOptions = FilterOptions;
+
+ //
+ // For architectural LBR, convert filter options into IA32_LBR_CTL bit fields
+ //
+ if (g_ArchBasedLastBranchRecord)
+ {
+ LbrBuildArchBasedFilterOptions(FilterOptions, Ia32LbrCtl);
+ }
+
+ //
+ // For legacy LBR, write the raw filter options to MSR_LEGACY_LBR_SELECT
+ // Architectural LBR encodes its filters in IA32_LBR_CTL and does not use this MSR
+ //
+ if (!g_ArchBasedLastBranchRecord)
+ {
+ LbrSetLbrSelectFilter(FilterOptions);
+ }
+}
+
+/**
+ * @brief Check if architectural LBR is enabled based on the IA32_LBR_CTL register value
+ *
+ * @param Ia32LbrCtl The IA32_LBR_CTL register value to inspect
+ * @return BOOLEAN
+ */
+BOOLEAN
+LbrCheckArchBased(IA32_LBR_CTL_REGISTER Ia32LbrCtl)
+{
+ return Ia32LbrCtl.Bits.LBREn ? TRUE : FALSE;
+}
+
+/**
+ * @brief Check if legacy LBR is enabled based on the IA32_DEBUGCTL MSR value
+ *
+ * @param DbgCtlMsr The IA32_DEBUGCTL MSR value to inspect
+ * @return BOOLEAN
+ */
+BOOLEAN
+LbrCheckLegacyBased(ULONGLONG DbgCtlMsr)
+{
+ return (DbgCtlMsr & IA32_DEBUGCTL_LBR_FLAG) ? TRUE : FALSE;
+}
+
+/**
+ * @brief Check if LBR is enabled while in VMX root-mode
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+LbrCheckOnVmxRootMode()
+{
+ ULONGLONG DbgCtlMsr = 0;
+ IA32_LBR_CTL_REGISTER Ia32LbrCtl = {0};
+
+ if (g_ArchBasedLastBranchRecord)
+ {
+ Ia32LbrCtl.AsUInt = g_Callbacks.VmFuncGetGuestIa32LbrCtl();
+ return LbrCheckArchBased(Ia32LbrCtl);
+ }
+ else
+ {
+ DbgCtlMsr = g_Callbacks.VmFuncGetDebugctl();
+ return LbrCheckLegacyBased(DbgCtlMsr);
+ }
+}
+
+/**
+ * @brief Check if LBR is enabled while in native mode or VMX non-root mode
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+LbrCheckOnNativeOrVmxNonRootMode()
+{
+ ULONGLONG DbgCtlMsr = 0;
+ IA32_LBR_CTL_REGISTER Ia32LbrCtl = {0};
+
+ if (g_ArchBasedLastBranchRecord)
+ {
+ xrdmsr(IA32_LBR_CTL, &Ia32LbrCtl.AsUInt);
+ return LbrCheckArchBased(Ia32LbrCtl);
+ }
+ else
+ {
+ xrdmsr(IA32_DEBUGCTL, &DbgCtlMsr);
+ return LbrCheckLegacyBased(DbgCtlMsr);
+ }
+}
+
+/**
+ * @brief Check if LBR is enabled or not
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+LbrCheck()
+{
+ BOOLEAN IsOnVmxRootMode = FALSE;
+
+ if (g_RunningOnHypervisorEnvironment)
+ {
+ IsOnVmxRootMode = g_Callbacks.VmFuncVmxGetCurrentExecutionMode();
+ }
+
+ if (IsOnVmxRootMode)
+ {
+ return LbrCheckOnVmxRootMode();
+ }
+ else
+ {
+ return LbrCheckOnNativeOrVmxNonRootMode();
+ }
+}
+
+/**
+ * @brief Start collecting LBR branches
+ *
+ * @param FilterOptions A bitmask of filter options to apply to the LBR branches (e.g., filtering by branch type, privilege level, etc.)
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+LbrStart(UINT64 FilterOptions)
+{
+ BOOLEAN IsOnVmxRootMode;
+ IA32_LBR_CTL_REGISTER Ia32LbrCtl = {0};
+ ULONGLONG DbgCtlMsr = 0;
+
+ if (g_LbrCapacity == 0)
+ {
+ LogInfo("Err, LBR aborting, CPU model not supported\n");
+ return FALSE;
+ }
+
+ //
+ // Adjust and set filter options
+ //
+ LbrAdjustFilterOptions(FilterOptions, &Ia32LbrCtl);
+
+ //
+ // Clear hardware state before enabling LBR
+ //
+ LbrClearHardwareState();
+
+ if (g_RunningOnHypervisorEnvironment)
+ {
+ IsOnVmxRootMode = g_Callbacks.VmFuncVmxGetCurrentExecutionMode();
+
+ //
+ // DEBUGCTL is not involved in ARCH LBR - it has its own dedicated control register
+ // So for ARCH LBR we skip reading the previous value and build the register from scratch (replacing it)
+ //
+ if (!g_ArchBasedLastBranchRecord)
+ {
+ if (IsOnVmxRootMode)
+ {
+ LbrGetValuesOnVmxRootMode(&DbgCtlMsr, &Ia32LbrCtl);
+ }
+ else
+ {
+ LbrGetValuesOnVmxNonRootMode(&DbgCtlMsr, &Ia32LbrCtl);
+ }
+ }
+
+ //
+ // Apply the appropriate bit to enable LBR based on whether it is architectural LBR or legacy LBR
+ //
+ if (g_ArchBasedLastBranchRecord)
+ {
+ LbrEnableArchBased(&Ia32LbrCtl);
+ }
+ else
+ {
+ LbrEnableLegacyBased(&DbgCtlMsr);
+ }
+
+ //
+ // Write the updated LBR control register values back based on the current VMX execution mode
+ //
+ if (IsOnVmxRootMode)
+ {
+ LbrSetValuesOnVmxRootMode(DbgCtlMsr, Ia32LbrCtl);
+ }
+ else
+ {
+ LbrSetValuesOnVmxNonRootMode(DbgCtlMsr, Ia32LbrCtl);
+ }
+ }
+ else
+ {
+ LbrStartOnNativeMode(Ia32LbrCtl);
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Stop collecting LBR branches
+ *
+ * @return VOID
+ */
+VOID
+LbrStop()
+{
+ BOOLEAN IsOnVmxRootMode;
+ ULONGLONG DbgCtlMsr = NULL64_ZERO;
+ IA32_LBR_CTL_REGISTER Ia32LbrCtl = {0};
+
+ if (g_RunningOnHypervisorEnvironment)
+ {
+ IsOnVmxRootMode = g_Callbacks.VmFuncVmxGetCurrentExecutionMode();
+
+ //
+ // Read the current LBR control register values based on the current VMX execution mode
+ //
+ if (IsOnVmxRootMode)
+ {
+ LbrGetValuesOnVmxRootMode(&DbgCtlMsr, &Ia32LbrCtl);
+ }
+ else
+ {
+ LbrGetValuesOnVmxNonRootMode(&DbgCtlMsr, &Ia32LbrCtl);
+ }
+
+ //
+ // Apply the appropriate bit to disable LBR based on whether it is architectural LBR or legacy LBR
+ //
+ if (g_ArchBasedLastBranchRecord)
+ {
+ LbrDisableArchBased(&Ia32LbrCtl);
+ }
+ else
+ {
+ LbrDisableLegacyBased(&DbgCtlMsr);
+ }
+
+ //
+ // Write the updated LBR control register values back based on the current VMX execution mode
+ //
+ if (IsOnVmxRootMode)
+ {
+ LbrSetValuesOnVmxRootMode(DbgCtlMsr, Ia32LbrCtl);
+ }
+ else
+ {
+ LbrSetValuesOnVmxNonRootMode(DbgCtlMsr, Ia32LbrCtl);
+ }
+ }
+ else
+ {
+ LbrStopOnNativeMode();
+ }
+}
+
+/**
+ * @brief Flush LBR MSRs by disabling LBR and clearing all LBR entries
+ *
+ * @return VOID
+ */
+VOID
+LbrFlush()
+{
+ // LogInfo("Flush LBR on cpu core: %d\n", KeGetCurrentProcessorNumberEx(NULL));
+
+ //
+ // Stop LBR collection and save any remaining entries
+ //
+ LbrStop();
+
+ //
+ // Reset the LBR control registers to zero:
+ // - ARCH LBR: zeroes IA32_LBR_CTL entirely (clears filters and disables collection)
+ // - Legacy LBR: zeroes MSR_LEGACY_LBR_SELECT (resets branch filter to capture-all)
+ //
+ LbrResetControlRegisters();
+
+ //
+ // Clear all remaining hardware state (TOS for legacy LBR, and all from/to MSR pairs)
+ //
+ LbrClearHardwareState();
+}
+
+/**
+ * @brief Filter LBR branches based on the provided options
+ * @param FilterOptions A bitmask of filter options to apply to the LBR branches
+ *
+ * @return VOID
+ */
+VOID
+LbrFilter(UINT64 FilterOptions)
+{
+ // LogInfo("Updating LBR filter options: 0x%llx\n", FilterOptions);
+
+ //
+ // First, we flush the LBR to clear out any existing entries that may not meet the new filter criteria
+ //
+ LbrFlush();
+
+ //
+ // Then we apply the new filter options and re-enable LBR with the updated filter settings
+ //
+ LbrStart(FilterOptions);
+}
+
+/**
+ * @brief Save LBR branches
+ *
+ * @return VOID
+ */
+VOID
+LbrSave()
+{
+ UINT64 LbrTos;
+ LBR_STACK_ENTRY * State;
+ UINT32 CurrentCore = 0;
+
+ //
+ // Get the current core id
+ //
+ CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
+
+ //
+ // Get the current processor LBR stack
+ //
+ State = &g_LbrStateList[CurrentCore];
+
+ //
+ // Read and store the current TOS index to know where the most recent branch is stored
+ // Note that there is no TOS index in ARCH LBR since everything is in order
+ //
+ if (!g_ArchBasedLastBranchRecord)
+ {
+ xrdmsr(MSR_LBR_TOS, &LbrTos);
+ State->Tos = (UINT8)LbrTos;
+ }
+
+ //
+ // Dump LBR entries into the current core's state structure
+ //
+ for (ULONG i = 0; i < (ULONG)g_LbrCapacity; i++)
+ {
+ if (g_ArchBasedLastBranchRecord)
+ {
+ xrdmsr(IA32_LBR_0_FROM_IP + i, &State->BranchEntry[i].From);
+ xrdmsr(IA32_LBR_0_TO_IP + i, &State->BranchEntry[i].To);
+ xrdmsr(IA32_LBR_0_INFO + i, &State->LastBranchInfo[i].AsUInt);
+ }
+ else
+ {
+ xrdmsr(MSR_LASTBRANCH_0_FROM_IP + i, &State->BranchEntry[i].From);
+ xrdmsr(MSR_LASTBRANCH_0_TO_IP + i, &State->BranchEntry[i].To);
+ xrdmsr(MSR_LASTBRANCH_INFO_0 + i, &State->LastBranchInfo[i].AsUInt);
+ }
+ }
+}
+
+/**
+ * @brief Get the branch type name based on the LBR branch type value (only applicable for architectural LBR)
+ *
+ * @details THIS FUNCTION IS ALSO IMPLEMENTED IN THE USER MODE
+ *
+ * @param BrType The raw branch type value from the LBR info MSR
+ * @param BrTypeName A character buffer to receive the branch type name string
+ *
+ * @return VOID
+ */
+VOID
+LbrGetArchBranchType(UINT32 BrType, CHAR * BrTypeName)
+{
+ if (BrType == LBR_BR_TYPE_COND)
+ {
+ strncpy(BrTypeName, "COND ", LBR_BR_TYPE_NAME_MAX_LEN);
+ }
+ else if (BrType == LBR_BR_TYPE_JMP_INDIRECT)
+ {
+ strncpy(BrTypeName, "JMP Indirect ", LBR_BR_TYPE_NAME_MAX_LEN);
+ }
+ else if (BrType == LBR_BR_TYPE_JMP_DIRECT)
+ {
+ strncpy(BrTypeName, "JMP Direct ", LBR_BR_TYPE_NAME_MAX_LEN);
+ }
+ else if (BrType == LBR_BR_TYPE_CALL_INDIRECT)
+ {
+ strncpy(BrTypeName, "CALL Indirect", LBR_BR_TYPE_NAME_MAX_LEN);
+ }
+ else if (BrType == LBR_BR_TYPE_CALL_DIRECT)
+ {
+ strncpy(BrTypeName, "CALL Direct ", LBR_BR_TYPE_NAME_MAX_LEN);
+ }
+ else if (BrType == LBR_BR_TYPE_RET)
+ {
+ strncpy(BrTypeName, "RET ", LBR_BR_TYPE_NAME_MAX_LEN);
+ }
+ else if (BrType >= LBR_BR_TYPE_RESERVED_MIN && BrType <= LBR_BR_TYPE_RESERVED_MAX)
+ {
+ strncpy(BrTypeName, "Reserved ", LBR_BR_TYPE_NAME_MAX_LEN);
+ }
+ else if (BrType >= LBR_BR_TYPE_OTHER_MIN && BrType <= LBR_BR_TYPE_OTHER_MAX)
+ {
+ strncpy(BrTypeName, "Other Branch ", LBR_BR_TYPE_NAME_MAX_LEN);
+ }
+ else
+ {
+ strncpy(BrTypeName, "Unknown ", LBR_BR_TYPE_NAME_MAX_LEN);
+ }
+}
+
+/**
+ * @brief Print collected LBR branches
+ *
+ * @return VOID
+ */
+VOID
+LbrPrint()
+{
+ ULONG CurrentIdx;
+ LBR_STACK_ENTRY * State;
+ UINT32 CurrentCore = 0;
+ CHAR BrTypeName[LBR_BR_TYPE_NAME_MAX_LEN] = {0};
+ UINT32 BrType = 0;
+ //
+ // Get the current core id
+ //
+ CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
+
+ //
+ // Get the current processor LBR stack
+ //
+ State = &g_LbrStateList[CurrentCore];
+
+ Log("LBR Chronological Trace on core : 0x%x\n\n", CurrentCore);
+
+ for (ULONG i = 1; i <= g_LbrCapacity; i++)
+ {
+ if (g_ArchBasedLastBranchRecord)
+ {
+ //
+ // In ARCH LBR, there is not TOS index and everything is in order
+ //
+ CurrentIdx = i - 1;
+ }
+ else
+ {
+ CurrentIdx = (ULONG)(State->Tos + i) % (ULONG)g_LbrCapacity;
+ }
+
+ if (State->BranchEntry[CurrentIdx].From == 0)
+ {
+ continue;
+ }
+
+ if (g_ArchBasedLastBranchRecord)
+ {
+ BrType = (UINT32)State->LastBranchInfo[CurrentIdx].BrType_OnlyArchLbr;
+
+ //
+ // Get the branch type name for better readability when printing
+ //
+ LbrGetArchBranchType(BrType, BrTypeName);
+
+ //
+ // Architectural LBR
+ //
+ Log("\t [%2u] Branch Mispredicted: %s, Branch type: %s, Cycle Count (Decimal): %04d (is valid? %s) - From: %016llx To: %016llx\n",
+ CurrentIdx,
+ State->LastBranchInfo[CurrentIdx].Mispred ? "true " : "false",
+ BrTypeName,
+ State->LastBranchInfo[CurrentIdx].CycleCount,
+ State->LastBranchInfo[CurrentIdx].CycCntValid_OnlyArchLbr ? "true " : "false",
+ State->BranchEntry[CurrentIdx].From,
+ State->BranchEntry[CurrentIdx].To);
+ }
+ else
+ {
+ //
+ // Legacy LBR
+ //
+ Log("\t [%2u] Branch Mispredicted: %s, Cycle Count (Decimal): %04d - From: %016llx To: %016llx\n",
+ CurrentIdx,
+ State->LastBranchInfo[CurrentIdx].Mispred ? "true " : "false",
+ State->LastBranchInfo[CurrentIdx].CycleCount,
+ State->BranchEntry[CurrentIdx].From,
+ State->BranchEntry[CurrentIdx].To);
+ }
+ }
+}
diff --git a/hyperdbg/hypertrace/code/pt/Pt.c b/hyperdbg/hypertrace/code/pt/Pt.c
new file mode 100644
index 00000000..2dfe7ce5
--- /dev/null
+++ b/hyperdbg/hypertrace/code/pt/Pt.c
@@ -0,0 +1,1510 @@
+/**
+ * @file Pt.c
+ * @author Masoud Rahimi Jafari (Masoodrahimy1379@gmail.com)
+ * @brief Processor Trace (PT) tracing implementation for HyperTrace module
+ * @details Programs Intel PT MSRs and manages per-CPU ToPA / output buffers.
+ * The engine half (PtEngine*) deals with a single PT_PER_CPU at a
+ * time and is OS-agnostic. The HyperDbg wrappers (PtCheck, PtStart,
+ * PtStop, PtPause, PtResume, PtSize, PtDump, PtFlush) operate on the
+ * global per-CPU state list (g_PtStateList) and mirror the LBR API
+ * surface.
+ * @version 0.19
+ * @date 2026-04-29
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ */
+#include "pch.h"
+
+//////////////////////////////////////////////////
+// Internal allocation helpers //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Allocate physically contiguous memory for ToPA / output buffers.
+ *
+ * Intel PT requires the output region's physical address to be aligned to
+ * its own size. We use MmAllocateContiguousMemorySpecifyCache with a
+ * BoundaryAddressMultipleOf equal to the requested size — the allocator
+ * then picks a base that does not cross any size-aligned boundary, which
+ * for a power-of-two size means the base is a multiple of that size.
+ *
+ * @param Size Bytes to allocate. Must be a power of two for size
+ * alignment.
+ * @param Alignment Requested alignment in bytes. Pass `Size` for the
+ * ToPA output region; pass PT_PAGE_SIZE for the ToPA
+ * table itself and the overflow page.
+ *
+ * @return PVOID Virtual address of the allocation, or NULL on failure.
+ */
+static PVOID
+PtAllocateContiguousAligned(UINT64 Size, UINT64 Alignment)
+{
+ PHYSICAL_ADDRESS Lo = {0};
+ PHYSICAL_ADDRESS Hi = {0};
+ PHYSICAL_ADDRESS Boundary = {0};
+ PVOID Result;
+
+ Hi.QuadPart = MAXULONG64;
+ Boundary.QuadPart = (LONGLONG)Alignment;
+
+ Result = MmAllocateContiguousMemorySpecifyCache(
+ (SIZE_T)Size,
+ Lo,
+ Hi,
+ Boundary,
+ MmCached);
+
+ if (Result != NULL)
+ {
+ RtlSecureZeroMemory(Result, (SIZE_T)Size);
+ }
+
+ return Result;
+}
+
+/**
+ * @brief Free a physically contiguous allocation made by PtAllocateContiguousAligned.
+ */
+static VOID
+PtFreeContiguous(PVOID Va)
+{
+ if (Va != NULL)
+ {
+ MmFreeContiguousMemory(Va);
+ }
+}
+
+/**
+ * @brief Translate a kernel virtual address to a physical address.
+ */
+static UINT64
+PtVaToPa(PVOID Va)
+{
+ PHYSICAL_ADDRESS Pa = MmGetPhysicalAddress(Va);
+ return (UINT64)Pa.QuadPart;
+}
+
+//////////////////////////////////////////////////
+// User-mode mmap helpers //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Build an MDL whose PFN list concatenates the main output
+ * buffer and the overflow page, then map the combined region
+ * into the current user process as one virtually contiguous
+ * range.
+ *
+ * Main and overflow come from separate
+ * MmAllocateContiguousMemorySpecifyCache calls so they are each
+ * physically contiguous but not contiguous with each other. By
+ * constructing one MDL whose PFN array is [main pfns | overflow
+ * pfns], MmMapLockedPagesSpecifyCache produces a single user VA
+ * range of MainSize + OverflowSize bytes that the consumer reads
+ * as one stream (main first, overflow second). Pages are
+ * non-paged so MDL_PAGES_LOCKED is enough to satisfy the mapper.
+ *
+ * Wrapped in SEH because MmMapLockedPagesSpecifyCache raises on
+ * quota / VAD failures rather than returning NULL.
+ *
+ * @return INT32 0 on success, -1 on failure (outputs untouched).
+ */
+static INT32
+PtMmapCpuRegionToUser(PVOID MainVa,
+ UINT64 MainPhysical,
+ SIZE_T MainSize,
+ UINT64 OverflowPhysical,
+ SIZE_T OverflowSize,
+ PMDL * OutMdl,
+ PVOID * OutUserVa)
+{
+ SIZE_T TotalSize = MainSize + OverflowSize;
+ ULONG MainPages;
+ ULONG OverflowPages;
+ ULONG i;
+ PFN_NUMBER * Pfns;
+ PFN_NUMBER MainPfnBase;
+ PFN_NUMBER OverflowPfnBase;
+ PMDL Mdl;
+ PVOID UserVa = NULL;
+
+ if (MainVa == NULL || MainSize == 0 || OverflowSize == 0 || TotalSize == 0)
+ return -1;
+
+ //
+ // Sizes must be whole pages — ToPA-backed buffers always are.
+ //
+ if ((MainSize & (PT_PAGE_SIZE - 1)) != 0 || (OverflowSize & (PT_PAGE_SIZE - 1)) != 0)
+ return -1;
+
+ //
+ // IoAllocateMdl sizes the embedded PFN array from the byte range we
+ // pass in. The seed VA only sets the byte-offset within the first
+ // page (0 for our page-aligned contiguous allocations); we overwrite
+ // the PFN list below so it stops describing MainVa past its own end.
+ //
+ Mdl = IoAllocateMdl(MainVa, (ULONG)TotalSize, FALSE, FALSE, NULL);
+ if (Mdl == NULL)
+ return -1;
+
+ MainPages = (ULONG)(MainSize >> PAGE_SHIFT);
+ OverflowPages = (ULONG)(OverflowSize >> PAGE_SHIFT);
+ MainPfnBase = (PFN_NUMBER)(MainPhysical >> PAGE_SHIFT);
+ OverflowPfnBase = (PFN_NUMBER)(OverflowPhysical >> PAGE_SHIFT);
+
+ Pfns = MmGetMdlPfnArray(Mdl);
+ for (i = 0; i < MainPages; i++)
+ Pfns[i] = MainPfnBase + i;
+ for (i = 0; i < OverflowPages; i++)
+ Pfns[MainPages + i] = OverflowPfnBase + i;
+
+ //
+ // Pages are physically present and non-pageable (contiguous memory);
+ // tag the MDL so MmMapLockedPagesSpecifyCache accepts it.
+ //
+ Mdl->MdlFlags |= MDL_PAGES_LOCKED;
+
+ __try
+ {
+ UserVa = MmMapLockedPagesSpecifyCache(
+ Mdl,
+ UserMode,
+ MmCached,
+ NULL,
+ FALSE,
+ NormalPagePriority);
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER)
+ {
+ UserVa = NULL;
+ }
+
+ if (UserVa == NULL)
+ {
+ IoFreeMdl(Mdl);
+ return -1;
+ }
+
+ *OutMdl = Mdl;
+ *OutUserVa = UserVa;
+ return 0;
+}
+
+/**
+ * @brief Tear down the combined user mapping produced by
+ * PtMmapCpuRegionToUser. Caller must be in the mapping process;
+ * see the cooperative single-process contract.
+ */
+static VOID
+PtUnmapCpuRegionFromUser(PMDL Mdl, PVOID UserVa)
+{
+ if (UserVa != NULL && Mdl != NULL)
+ {
+ __try
+ {
+ MmUnmapLockedPages(UserVa, Mdl);
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER)
+ {
+ //
+ // Mapping process may have already exited.
+ //
+ }
+ }
+
+ if (Mdl != NULL)
+ {
+ IoFreeMdl(Mdl);
+ }
+}
+
+//////////////////////////////////////////////////
+// Engine routines //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Convert a buffer size in bytes to the ToPA Size field encoding.
+ * Valid sizes are 4KB * 2^N for N = 0..15.
+ *
+ * @param SizeInBytes
+ * @return INT32 Encoding 0..15, or -1 if the size is not supported.
+ */
+INT32
+PtEngineSizeToTopaEncoding(UINT64 SizeInBytes)
+{
+ UINT64 Pages;
+ INT32 N;
+
+ if (SizeInBytes < PT_PAGE_SIZE)
+ return -1;
+
+ Pages = SizeInBytes / PT_PAGE_SIZE;
+
+ //
+ // Must be an exact power-of-two number of pages
+ //
+ if ((Pages & (Pages - 1)) != 0)
+ return -1;
+
+ N = 0;
+ while ((Pages >> N) != 1)
+ N++;
+
+ if (N > 15)
+ return -1;
+
+ return N;
+}
+
+/**
+ * @brief Probe Intel PT capabilities via CPUID leaf 7 / leaf 0x14.
+ *
+ * @param OutCaps Optional. If non-NULL, populated with detailed capabilities.
+ *
+ * @return INT32 0 on success (PT supported), -1 if PT is not supported.
+ */
+INT32
+PtEngineQueryCapabilities(PT_CAPABILITIES * OutCaps)
+{
+ int Info[4] = {0};
+ int MaxSubleaf = 0;
+ UINT64 VmxMisc;
+
+ //
+ // Check PT support: CPUID.(EAX=07H,ECX=0):EBX[25]
+ //
+ __cpuidex(Info, 0x07, 0);
+ if ((Info[1] & (1 << 25)) == 0)
+ return -1;
+
+ if (OutCaps == NULL)
+ return 0;
+
+ RtlZeroMemory(OutCaps, sizeof(*OutCaps));
+
+ //
+ // Leaf 0x14, sub-leaf 0: capability flags
+ //
+ Info[0] = Info[1] = Info[2] = Info[3] = 0;
+ __cpuidex(Info, 0x14, 0);
+
+ MaxSubleaf = Info[0]; /* EAX: max valid sub-leaf */
+
+ //
+ // EBX capabilities
+ //
+ OutCaps->Cr3Filtering = (Info[1] >> 0) & 1;
+ OutCaps->PsbCycConfigurable = (Info[1] >> 1) & 1;
+ OutCaps->IpFiltering = (Info[1] >> 2) & 1;
+ OutCaps->MtcSupport = (Info[1] >> 3) & 1;
+ OutCaps->PtwriteSupport = (Info[1] >> 4) & 1;
+ OutCaps->PowerEventTrace = (Info[1] >> 5) & 1;
+
+ //
+ // ECX capabilities
+ //
+ OutCaps->TopaOutput = (Info[2] >> 0) & 1;
+ OutCaps->TopaMultiEntry = (Info[2] >> 1) & 1;
+ OutCaps->SingleRangeOutput = (Info[2] >> 2) & 1;
+ OutCaps->TransportOutput = (Info[2] >> 3) & 1;
+ OutCaps->IpPayloadsAreLip = (Info[2] >> 31) & 1;
+
+ //
+ // Sub-leaf 1: detailed numerics
+ //
+ if (MaxSubleaf >= 1)
+ {
+ Info[0] = Info[1] = Info[2] = Info[3] = 0;
+ __cpuidex(Info, 0x14, 1);
+
+ OutCaps->NumAddrRanges = (UINT32)(Info[0] & 0x7);
+ OutCaps->MtcPeriodBitmap = (UINT16)((Info[0] >> 16) & 0xFFFF);
+ OutCaps->CycThresholdBitmap = (UINT16)(Info[1] & 0xFFFF);
+ OutCaps->PsbFreqBitmap = (UINT16)((Info[1] >> 16) & 0xFFFF);
+ }
+
+ //
+ // VMX support: IA32_VMX_MISC[14] indicates Intel PT may be used in VMX
+ // operation. Reading IA32_VMX_MISC is unconditional on a VMX-capable
+ // CPU; if the CPU isn't VMX-capable the bit is meaningless and the
+ // value falls through as 0.
+ //
+ VmxMisc = __readmsr(0x00000485 /* IA32_VMX_MISC */);
+ OutCaps->VmxSupport = (VmxMisc >> 14) & 1;
+
+ return 0;
+}
+
+/**
+ * @brief Initialize a PT_TRACE_CONFIG with sensible defaults.
+ * Trace user + kernel, branch + TSC packets, 2 MB output buffer.
+ */
+VOID
+PtEngineInitDefaultConfig(PT_TRACE_CONFIG * Config)
+{
+ UINT32 i;
+
+ Config->TraceUser = TRUE;
+ Config->TraceKernel = TRUE;
+ Config->TargetCr3 = 0;
+ Config->NumAddrRanges = 0;
+ Config->EnableBranch = TRUE;
+ Config->EnableTsc = FALSE;
+ Config->EnableMtc = FALSE;
+ Config->EnableCyc = FALSE;
+ Config->EnableRetCompression = FALSE;
+ Config->MtcFreq = 0;
+ Config->CycThresh = 0;
+ Config->PsbFreq = 0;
+ Config->BufferSize = PT_DEFAULT_BUFFER_SIZE;
+
+ for (i = 0; i < PT_MAX_ADDR_RANGES; i++)
+ {
+ Config->AddrRanges[i].Start = 0;
+ Config->AddrRanges[i].End = 0;
+ Config->AddrRanges[i].IsStopRange = FALSE;
+ }
+}
+
+/**
+ * @brief Allocate the ToPA table, output buffer, and overflow zone for one
+ * per-CPU PT context, then build the ToPA entries.
+ *
+ * ToPA layout:
+ * [0] main output buffer (Config->BufferSize), INT=1
+ * [1] overflow page (4 KB), INT=0
+ * [2] END, wraps back to ToPA table (circular)
+ *
+ * @return INT32 0 on success, -1 on allocation failure, -2 on bad config.
+ */
+INT32
+PtEngineAllocateBuffers(PT_PER_CPU * Cpu, const PT_TRACE_CONFIG * Config)
+{
+ INT32 SizeEncoding;
+ UINT64 BufSize;
+ PT_TOPA_ENTRY * Topa;
+
+ if (Cpu == NULL || Config == NULL)
+ return -2;
+
+ BufSize = Config->BufferSize;
+ if (BufSize == 0)
+ BufSize = PT_DEFAULT_BUFFER_SIZE;
+
+ //
+ // Validate buffer size is a valid ToPA encoding
+ //
+ SizeEncoding = PtEngineSizeToTopaEncoding(BufSize);
+ if (SizeEncoding < 0)
+ return -2;
+
+ //
+ // 1. ToPA table — one 4KB page, must be 4KB-aligned
+ //
+ Cpu->Buffer.TopaVa = (PT_TOPA_ENTRY *)PtAllocateContiguousAligned(PT_PAGE_SIZE, PT_PAGE_SIZE);
+ if (Cpu->Buffer.TopaVa == NULL)
+ return -1;
+ Cpu->Buffer.TopaPhysical = PtVaToPa(Cpu->Buffer.TopaVa);
+
+ //
+ // 2. Main output buffer — must be aligned to its own size
+ //
+ Cpu->Buffer.OutputVa = PtAllocateContiguousAligned(BufSize, BufSize);
+ if (Cpu->Buffer.OutputVa == NULL)
+ {
+ PtFreeContiguous(Cpu->Buffer.TopaVa);
+ Cpu->Buffer.TopaVa = NULL;
+ return -1;
+ }
+ Cpu->Buffer.OutputPhysical = PtVaToPa(Cpu->Buffer.OutputVa);
+ Cpu->Buffer.OutputSize = BufSize;
+
+ //
+ // 3. Overflow landing zone — 4KB
+ //
+ Cpu->Buffer.OverflowVa = PtAllocateContiguousAligned(PT_OVERFLOW_SIZE, PT_PAGE_SIZE);
+ if (Cpu->Buffer.OverflowVa == NULL)
+ {
+ PtFreeContiguous(Cpu->Buffer.OutputVa);
+ Cpu->Buffer.OutputVa = NULL;
+ PtFreeContiguous(Cpu->Buffer.TopaVa);
+ Cpu->Buffer.TopaVa = NULL;
+ return -1;
+ }
+ Cpu->Buffer.OverflowPhysical = PtVaToPa(Cpu->Buffer.OverflowVa);
+
+ //
+ // 4. Build the ToPA table — 3 entries
+ //
+ Topa = Cpu->Buffer.TopaVa;
+
+ //
+ // Entry 0: main data buffer, INT=1 (trigger PMI when full)
+ //
+ Topa[0].Value = 0;
+ Topa[0].BaseAddr = Cpu->Buffer.OutputPhysical >> 12;
+ Topa[0].Size = (UINT64)SizeEncoding;
+ Topa[0].Int = 1;
+ Topa[0].Stop = 0;
+
+ //
+ // Entry 1: overflow landing zone (4 KB), no interrupt
+ //
+ Topa[1].Value = 0;
+ Topa[1].BaseAddr = Cpu->Buffer.OverflowPhysical >> 12;
+ Topa[1].Size = PT_TOPA_SIZE_4K;
+ Topa[1].Int = 0;
+ Topa[1].Stop = 0;
+
+ //
+ // Entry 2: END — circular, points back to this ToPA table
+ //
+ Topa[2].Value = 0;
+ Topa[2].End = 1;
+ Topa[2].BaseAddr = Cpu->Buffer.TopaPhysical >> 12;
+
+ //
+ // Copy config and initialize state
+ //
+ Cpu->Config = *Config;
+ Cpu->Config.BufferSize = BufSize;
+ Cpu->SavedCtl.Value = 0;
+ Cpu->State = PT_STATE_READY;
+ Cpu->TotalBytesCaptured = 0;
+
+ return 0;
+}
+
+/**
+ * @brief Free all PT buffers belonging to one per-CPU context.
+ * Must not be called while State == PT_STATE_TRACING.
+ */
+VOID
+PtEngineFreeBuffers(PT_PER_CPU * Cpu)
+{
+ if (Cpu == NULL)
+ return;
+
+ //
+ // Refuse to free while tracing — caller must stop first
+ //
+ if (Cpu->State == PT_STATE_TRACING)
+ return;
+
+ if (Cpu->Buffer.OverflowVa)
+ {
+ PtFreeContiguous(Cpu->Buffer.OverflowVa);
+ Cpu->Buffer.OverflowVa = NULL;
+ Cpu->Buffer.OverflowPhysical = 0;
+ }
+ if (Cpu->Buffer.OutputVa)
+ {
+ PtFreeContiguous(Cpu->Buffer.OutputVa);
+ Cpu->Buffer.OutputVa = NULL;
+ Cpu->Buffer.OutputPhysical = 0;
+ Cpu->Buffer.OutputSize = 0;
+ }
+ if (Cpu->Buffer.TopaVa)
+ {
+ PtFreeContiguous(Cpu->Buffer.TopaVa);
+ Cpu->Buffer.TopaVa = NULL;
+ Cpu->Buffer.TopaPhysical = 0;
+ }
+
+ Cpu->State = PT_STATE_DISABLED;
+ Cpu->TotalBytesCaptured = 0;
+ Cpu->SavedCtl.Value = 0;
+}
+
+/**
+ * @brief Build IA32_RTIT_CTL from a config + capabilities.
+ * Does not set TraceEn; caller is responsible for enabling last.
+ */
+static PT_RTIT_CTL_REGISTER
+PtEngineBuildCtlFromConfig(const PT_TRACE_CONFIG * Cfg,
+ const PT_CAPABILITIES * Caps)
+{
+ PT_RTIT_CTL_REGISTER Ctl;
+ Ctl.Value = 0;
+
+ //
+ // Core settings
+ //
+ Ctl.TraceEn = 0; /* enabled last, after everything is set */
+ Ctl.ToPA = 1; /* always use ToPA output */
+ Ctl.FabricEn = 0; /* always output to memory */
+
+ //
+ // Privilege filter
+ //
+ Ctl.Os = Cfg->TraceKernel ? 1 : 0;
+ Ctl.User = Cfg->TraceUser ? 1 : 0;
+
+ //
+ // CR3 filtering
+ //
+ Ctl.Cr3Filter = (Cfg->TargetCr3 != 0) ? 1 : 0;
+
+ //
+ // Branch tracing — the core functionality
+ //
+ Ctl.BranchEn = Cfg->EnableBranch ? 1 : 0;
+
+ //
+ // Timing packets
+ //
+ Ctl.TscEn = Cfg->EnableTsc ? 1 : 0;
+
+ if (Caps->MtcSupport)
+ {
+ Ctl.MtcEn = Cfg->EnableMtc ? 1 : 0;
+ if (Cfg->EnableMtc && ((1 << Cfg->MtcFreq) & Caps->MtcPeriodBitmap))
+ Ctl.MtcFreq = Cfg->MtcFreq;
+ }
+
+ if (Caps->PsbCycConfigurable)
+ {
+ Ctl.CycEn = Cfg->EnableCyc ? 1 : 0;
+ if (Cfg->EnableCyc && ((1 << Cfg->CycThresh) & Caps->CycThresholdBitmap))
+ Ctl.CycThresh = Cfg->CycThresh;
+ if ((1 << Cfg->PsbFreq) & Caps->PsbFreqBitmap)
+ Ctl.PsbFreq = Cfg->PsbFreq;
+ }
+
+ //
+ // RET compression
+ //
+ Ctl.DisRetc = Cfg->EnableRetCompression ? 0 : 1;
+
+ //
+ // IP filter range configuration
+ //
+ Ctl.Addr0Cfg = 0;
+ Ctl.Addr1Cfg = 0;
+ Ctl.Addr2Cfg = 0;
+ Ctl.Addr3Cfg = 0;
+
+ if (Cfg->NumAddrRanges > 0 && Caps->IpFiltering)
+ {
+ if (Cfg->NumAddrRanges >= 1 && Caps->NumAddrRanges >= 1)
+ Ctl.Addr0Cfg = Cfg->AddrRanges[0].IsStopRange ? 2 : 1;
+ if (Cfg->NumAddrRanges >= 2 && Caps->NumAddrRanges >= 2)
+ Ctl.Addr1Cfg = Cfg->AddrRanges[1].IsStopRange ? 2 : 1;
+ if (Cfg->NumAddrRanges >= 3 && Caps->NumAddrRanges >= 3)
+ Ctl.Addr2Cfg = Cfg->AddrRanges[2].IsStopRange ? 2 : 1;
+ if (Cfg->NumAddrRanges >= 4 && Caps->NumAddrRanges >= 4)
+ Ctl.Addr3Cfg = Cfg->AddrRanges[3].IsStopRange ? 2 : 1;
+ }
+
+ return Ctl;
+}
+
+/**
+ * @brief Start tracing on the CURRENT CPU using the passed PT_PER_CPU.
+ * Programs all PT MSRs and sets TraceEn=1.
+ *
+ * Must be called from the target CPU (DPC or VMX root).
+ *
+ * @return INT32 0 on success, -1 on error.
+ */
+INT32
+PtEngineStart(PT_PER_CPU * Cpu)
+{
+ PT_RTIT_CTL_REGISTER Ctl;
+ PT_CAPABILITIES Caps;
+ UINT32 i;
+ BOOLEAN IsOnVmxRootMode = FALSE;
+
+ if (Cpu == NULL)
+ return -1;
+ if (Cpu->State != PT_STATE_READY && Cpu->State != PT_STATE_STOPPED)
+ return -1;
+ if (Cpu->Buffer.TopaVa == NULL || Cpu->Buffer.OutputVa == NULL)
+ return -1;
+
+ if (PtEngineQueryCapabilities(&Caps) != 0)
+ return -1;
+
+ //
+ // Detect VMX-root context if running under HyperDbg's hypervisor.
+ //
+ // Intel PT MSRs (IA32_RTIT_*) are NOT in the default MSR bitmap, so a
+ // direct WRMSR to them in either VMX root or VMX non-root passes
+ // through to hardware without trapping. This means the same MSR
+ // sequence below works correctly from a DPC running in the guest as
+ // well as from a VMX-root packet handler. We still read the mode for
+ // logging and for any future hypervisor-only code (e.g. setting the
+ // "Clear IA32_RTIT_CTL on VM-exit" VMCS control or saving guest-side
+ // RTIT state across VM transitions).
+ //
+ if (g_RunningOnHypervisorEnvironment)
+ {
+ IsOnVmxRootMode = g_Callbacks.VmFuncVmxGetCurrentExecutionMode();
+ // LogInfo("PT: PtEngineStart on core %u (vmx-root=%u)\n",
+ // KeGetCurrentProcessorNumberEx(NULL),
+ // (UINT32)IsOnVmxRootMode);
+ }
+
+ //
+ // Don't request more IP ranges or features than the CPU supports
+ //
+ if (Cpu->Config.NumAddrRanges > Caps.NumAddrRanges)
+ return -1;
+ if (Cpu->Config.NumAddrRanges > 0 && !Caps.IpFiltering)
+ return -1;
+ if (Cpu->Config.TargetCr3 != 0 && !Caps.Cr3Filtering)
+ return -1;
+
+ //
+ // Step 1: Ensure tracing is off and clear status
+ //
+ {
+ PT_RTIT_CTL_REGISTER Cur;
+ Cur.Value = __readmsr(MSR_IA32_RTIT_CTL);
+ if (Cur.TraceEn)
+ {
+ Cur.TraceEn = 0;
+ __writemsr(MSR_IA32_RTIT_CTL, Cur.Value);
+ }
+ }
+
+ __writemsr(MSR_IA32_RTIT_STATUS, 0);
+
+ //
+ // Step 2: Set output base and reset output position
+ //
+ __writemsr(MSR_IA32_RTIT_OUTPUT_BASE, Cpu->Buffer.TopaPhysical);
+ {
+ PT_OUTPUT_MASK_PTRS_REGISTER InitMask;
+ InitMask.Value = 0;
+ InitMask.LowerMask = 0x7F;
+ InitMask.MaskOrTableOffset = 0;
+ InitMask.OutputOffset = 0;
+ __writemsr(MSR_IA32_RTIT_OUTPUT_MASK_PTRS, InitMask.Value);
+ }
+
+ //
+ // Step 3: Set CR3 filter
+ //
+ __writemsr(MSR_IA32_RTIT_CR3_MATCH, Cpu->Config.TargetCr3);
+
+ //
+ // Step 4: Set IP address ranges. IMPORTANT: only touch ADDRn MSRs the
+ // CPU actually supports; writing to non-existent ADDRn MSRs causes #GP.
+ //
+ for (i = 0; i < Caps.NumAddrRanges; i++)
+ {
+ UINT32 MsrA = MSR_IA32_RTIT_ADDR0_A + (i * 2);
+ UINT32 MsrB = MSR_IA32_RTIT_ADDR0_B + (i * 2);
+
+ if (i < Cpu->Config.NumAddrRanges)
+ {
+ __writemsr(MsrA, Cpu->Config.AddrRanges[i].Start);
+ __writemsr(MsrB, Cpu->Config.AddrRanges[i].End);
+ }
+ else
+ {
+ __writemsr(MsrA, 0);
+ __writemsr(MsrB, 0);
+ }
+ }
+
+ //
+ // Step 5: Build IA32_RTIT_CTL and enable
+ //
+ Ctl = PtEngineBuildCtlFromConfig(&Cpu->Config, &Caps);
+
+ //
+ // Save the CTL value for resume
+ //
+ Cpu->SavedCtl = Ctl;
+
+ //
+ // Enable tracing — MUST be the last MSR write
+ //
+ Ctl.TraceEn = 1;
+ Cpu->SavedCtl.TraceEn = 1;
+ __writemsr(MSR_IA32_RTIT_CTL, Ctl.Value);
+
+ //
+ // Step 6: Verify tracing started
+ //
+ {
+ PT_RTIT_STATUS_REGISTER Status;
+ Status.Value = __readmsr(MSR_IA32_RTIT_STATUS);
+ if (Status.Error)
+ {
+ Ctl.TraceEn = 0;
+ __writemsr(MSR_IA32_RTIT_CTL, Ctl.Value);
+ Cpu->State = PT_STATE_ERROR;
+ return -1;
+ }
+ }
+
+ Cpu->State = PT_STATE_TRACING;
+ return 0;
+}
+
+/**
+ * @brief Read current output position, calculate bytes written, and
+ * optionally copy trace data into Out starting at Out->WriteOffset,
+ * then advance WriteOffset.
+ */
+static UINT64
+PtEngineReadBytesWritten(const PT_BUFFER * Buf, PT_OUTPUT_BUFFER * Out)
+{
+ PT_OUTPUT_MASK_PTRS_REGISTER Mask;
+ UINT32 TopaIndex;
+ UINT32 BytesInEntry;
+ UINT64 Total = 0;
+
+ Mask.Value = __readmsr(MSR_IA32_RTIT_OUTPUT_MASK_PTRS);
+
+ TopaIndex = (UINT32)(Mask.MaskOrTableOffset >> 0);
+ BytesInEntry = (UINT32)Mask.OutputOffset;
+
+ //
+ // ToPA layout:
+ // Entry[0] = main buffer (OutputSize bytes)
+ // Entry[1] = overflow (4KB)
+ // Entry[2] = END
+ //
+ if (TopaIndex == 0)
+ {
+ Total = BytesInEntry;
+ }
+ else if (TopaIndex >= 1)
+ {
+ Total = Buf->OutputSize + BytesInEntry;
+ }
+
+ //
+ // Copy trace data if the caller provided a buffer with enough room
+ //
+ if (Out != NULL && Out->Buffer != NULL && Total > 0)
+ {
+ if (Out->WriteOffset + Total <= Out->Length)
+ {
+ UINT8 * Dest = (UINT8 *)Out->Buffer + Out->WriteOffset;
+ UINT64 MainBytes = (Total < Buf->OutputSize) ? Total : Buf->OutputSize;
+ UINT64 SpillBytes = (Total > Buf->OutputSize) ? (Total - Buf->OutputSize) : 0;
+
+ RtlCopyMemory(Dest, Buf->OutputVa, (SIZE_T)MainBytes);
+
+ if (SpillBytes > 0)
+ RtlCopyMemory(Dest + MainBytes, Buf->OverflowVa, (SIZE_T)SpillBytes);
+
+ Out->WriteOffset += Total;
+ }
+ // else: not enough space — skip copy, WriteOffset unchanged
+ }
+
+ return Total;
+}
+
+/**
+ * @brief Stop tracing on the CURRENT CPU. Reads final output position,
+ * copies trace data if requested, resets PT MSRs.
+ *
+ * @return UINT64 Total bytes captured (across all PMIs + final), or 0 on error.
+ */
+UINT64
+PtEngineStop(PT_PER_CPU * Cpu, PT_OUTPUT_BUFFER * Out)
+{
+ UINT64 BytesThisRun;
+ UINT32 i;
+ BOOLEAN IsOnVmxRootMode = FALSE;
+
+ if (Cpu == NULL)
+ return 0;
+ if (Cpu->State != PT_STATE_TRACING && Cpu->State != PT_STATE_PAUSED)
+ return 0;
+
+ //
+ // Detect VMX-root context for symmetry with PtEngineStart. Direct WRMSR
+ // works in both modes for PT MSRs (not in MSR bitmap by default).
+ //
+ if (g_RunningOnHypervisorEnvironment)
+ {
+ IsOnVmxRootMode = g_Callbacks.VmFuncVmxGetCurrentExecutionMode();
+ // LogInfo("PT: PtEngineStop on core %u (vmx-root=%u)\n",
+ // KeGetCurrentProcessorNumberEx(NULL),
+ // (UINT32)IsOnVmxRootMode);
+ }
+
+ //
+ // Disable tracing
+ //
+ {
+ PT_RTIT_CTL_REGISTER Ctl;
+ Ctl.Value = __readmsr(MSR_IA32_RTIT_CTL);
+ Ctl.TraceEn = 0;
+ __writemsr(MSR_IA32_RTIT_CTL, Ctl.Value);
+ }
+
+ //
+ // Read final output position and copy data if requested
+ //
+ BytesThisRun = PtEngineReadBytesWritten(&Cpu->Buffer, Out);
+ Cpu->TotalBytesCaptured += BytesThisRun;
+
+ //
+ // Check for hardware error
+ //
+ {
+ PT_RTIT_STATUS_REGISTER Status;
+ Status.Value = __readmsr(MSR_IA32_RTIT_STATUS);
+ if (Status.Error)
+ {
+ Cpu->State = PT_STATE_ERROR;
+ return 0;
+ }
+ }
+
+ //
+ // Reset all PT MSRs
+ //
+ __writemsr(MSR_IA32_RTIT_CTL, 0);
+ __writemsr(MSR_IA32_RTIT_STATUS, 0);
+ __writemsr(MSR_IA32_RTIT_OUTPUT_BASE, 0);
+ __writemsr(MSR_IA32_RTIT_OUTPUT_MASK_PTRS, 0);
+ __writemsr(MSR_IA32_RTIT_CR3_MATCH, 0);
+
+ //
+ // Clear all ADDRn MSRs that this CPU supports.
+ // NumAddrRanges was validated against caps in PtEngineStart.
+ //
+ for (i = 0; i < Cpu->Config.NumAddrRanges; i++)
+ {
+ __writemsr(MSR_IA32_RTIT_ADDR0_A + (i * 2), 0);
+ __writemsr(MSR_IA32_RTIT_ADDR0_B + (i * 2), 0);
+ }
+
+ Cpu->State = PT_STATE_STOPPED;
+ return Cpu->TotalBytesCaptured;
+}
+
+/**
+ * @brief Pause tracing on the CURRENT CPU. Preserves buffer state.
+ */
+INT32
+PtEnginePause(PT_PER_CPU * Cpu)
+{
+ PT_RTIT_CTL_REGISTER Ctl;
+
+ if (Cpu == NULL || Cpu->State != PT_STATE_TRACING)
+ return -1;
+
+ Ctl.Value = __readmsr(MSR_IA32_RTIT_CTL);
+ Ctl.TraceEn = 0;
+ __writemsr(MSR_IA32_RTIT_CTL, Ctl.Value);
+
+ Cpu->State = PT_STATE_PAUSED;
+ return 0;
+}
+
+/**
+ * @brief Resume tracing on the CURRENT CPU after pause.
+ */
+INT32
+PtEngineResume(PT_PER_CPU * Cpu)
+{
+ PT_RTIT_CTL_REGISTER Ctl;
+
+ if (Cpu == NULL || Cpu->State != PT_STATE_PAUSED)
+ return -1;
+
+ Ctl = Cpu->SavedCtl;
+ Ctl.TraceEn = 1;
+ __writemsr(MSR_IA32_RTIT_CTL, Ctl.Value);
+
+ Cpu->State = PT_STATE_TRACING;
+ return 0;
+}
+
+/**
+ * @brief Check whether the latest PMI was raised by Intel PT
+ * (IA32_PERF_GLOBAL_STATUS bit 55).
+ */
+BOOLEAN
+PtEngineIsPtPmi()
+{
+ UINT64 GlobalStatus = __readmsr(MSR_IA32_PERF_GLOBAL_STATUS);
+ return (GlobalStatus & PERF_GLOBAL_STATUS_TOPA_PMI) ? TRUE : FALSE;
+}
+
+/**
+ * @brief Handle a ToPA PMI on the CURRENT CPU. Caller is responsible for
+ * having already disabled tracing (e.g. via VMCS clear of RTIT_CTL).
+ *
+ * @return UINT64 number of bytes captured in this PMI event.
+ */
+UINT64
+PtEngineHandlePmi(PT_PER_CPU * Cpu, PT_OUTPUT_BUFFER * Out)
+{
+ UINT64 BytesThisEvent;
+
+ if (Cpu == NULL)
+ return 0;
+
+ //
+ // 1. Read how many bytes were written and copy them out
+ //
+ BytesThisEvent = PtEngineReadBytesWritten(&Cpu->Buffer, Out);
+ Cpu->TotalBytesCaptured += BytesThisEvent;
+
+ //
+ // 2. Reset output position to start of buffer BEFORE acknowledging the
+ // PMI. PT keeps tracing during the handler (TraceEn stays 1) and the
+ // hardware is free to raise another ToPA PMI as soon as PendTopaPmi /
+ // PERF_GLOBAL_STATUS.TopaPmi are cleared. If MASK_PTRS still points
+ // deep into the overflow page (or past wrap) at that moment, a
+ // back-to-back PMI would observe stale state.
+ //
+ {
+ PT_OUTPUT_MASK_PTRS_REGISTER ResetMask;
+ ResetMask.Value = 0;
+ ResetMask.LowerMask = 0x7F;
+ ResetMask.MaskOrTableOffset = 0;
+ ResetMask.OutputOffset = 0;
+ __writemsr(MSR_IA32_RTIT_OUTPUT_MASK_PTRS, ResetMask.Value);
+ }
+
+ //
+ // 3. Clear PT pending PMI bits in IA32_RTIT_STATUS
+ //
+ {
+ PT_RTIT_STATUS_REGISTER Status;
+ Status.Value = __readmsr(MSR_IA32_RTIT_STATUS);
+ Status.PendTopaPmi = 0;
+ Status.PendPsbPmi = 0;
+ Status.Error = 0;
+ Status.Stopped = 0;
+ __writemsr(MSR_IA32_RTIT_STATUS, Status.Value);
+ }
+
+ //
+ // 4. Acknowledge the global PMI bit
+ //
+ __writemsr(MSR_IA32_PERF_GLOBAL_OVF_CTRL, PERF_GLOBAL_STATUS_TOPA_PMI);
+
+ return BytesThisEvent;
+}
+
+//////////////////////////////////////////////////
+// HyperDbg-style wrappers //
+// (mirror of Lbr.c API surface) //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Check whether Intel PT is supported on the current CPU.
+ * Mirrors LbrCheck — must be called once before any Pt* operation.
+ *
+ * If running under HyperDbg's hypervisor we also verify that the
+ * platform's IA32_VMX_MISC MSR advertises PT-in-VMX support, since
+ * without that bit set we may not be able to keep PT alive across
+ * VM transitions in a future VMCS-controlled implementation. This
+ * is a soft check — the current direct-MSR path still works because
+ * PT MSRs aren't trapped — but it surfaces the situation in the log.
+ *
+ * @return BOOLEAN TRUE if Intel PT is available.
+ */
+BOOLEAN
+PtCheck()
+{
+ PT_CAPABILITIES Caps = {0};
+
+ if (PtEngineQueryCapabilities(&Caps) != 0)
+ return FALSE;
+
+ //
+ // We require ToPA output for our buffer scheme
+ //
+ if (!Caps.TopaOutput)
+ {
+ LogInfo("PT: CPU does not support ToPA output; PT cannot be used here.\n");
+ return FALSE;
+ }
+
+ if (g_RunningOnHypervisorEnvironment && !Caps.VmxSupport)
+ {
+ // LogInfo("PT: IA32_VMX_MISC[14] is clear - Intel PT in VMX is not "
+ // "advertised on this CPU. Direct MSR programming still works "
+ // "from VMX non-root because PT MSRs are not trapped.\n");
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Allocate ToPA / output / overflow buffers for every active CPU.
+ *
+ * Must be called at IRQL == PASSIVE_LEVEL (before broadcasting the
+ * per-core enable DPC), because MmAllocateContiguousMemorySpecifyCache
+ * is paged.
+ *
+ * Idempotent: cores that already have buffers (State != DISABLED)
+ * are skipped.
+ *
+ * @return BOOLEAN TRUE if every core ended up with a usable buffer set.
+ */
+BOOLEAN
+PtAllocateAllCpuBuffers()
+{
+ UINT32 ProcessorsCount;
+ UINT32 i;
+
+ if (g_PtStateList == NULL)
+ return FALSE;
+
+ ProcessorsCount = KeQueryActiveProcessorCount(0);
+
+ for (i = 0; i < ProcessorsCount; i++)
+ {
+ PT_PER_CPU * Cpu = &g_PtStateList[i];
+ PT_TRACE_CONFIG Cfg = Cpu->Config;
+
+ if (Cpu->State != PT_STATE_DISABLED)
+ continue;
+
+ if (Cfg.BufferSize == 0)
+ PtEngineInitDefaultConfig(&Cfg);
+
+ if (PtEngineAllocateBuffers(Cpu, &Cfg) != 0)
+ {
+ // LogInfo("PT: buffer allocation failed on core %u\n", i);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Free ToPA / output / overflow buffers for every active CPU.
+ *
+ * Must be called at IRQL == PASSIVE_LEVEL (after broadcasting any
+ * per-core disable DPC), because MmFreeContiguousMemory is paged.
+ */
+VOID
+PtFreeAllCpuBuffers()
+{
+ UINT32 ProcessorsCount;
+ UINT32 i;
+
+ if (g_PtStateList == NULL)
+ return;
+
+ //
+ // Drop any live user mappings before the underlying contiguous
+ // memory goes away. Must run in the same process that called the
+ // mmap IOCTL — see HYPERTRACE_PT_MMAP_PACKETS for the contract.
+ //
+ PtUnmapAllCpuBuffersFromUser();
+
+ ProcessorsCount = KeQueryActiveProcessorCount(0);
+
+ for (i = 0; i < ProcessorsCount; i++)
+ {
+ PtEngineFreeBuffers(&g_PtStateList[i]);
+ }
+}
+
+/**
+ * @brief Map every per-CPU PT main output buffer and 4 KB overflow page
+ * into the current user process as a single virtually contiguous
+ * region per CPU, and fill OutDescs[i] with the base UserVa and
+ * the total Size (main + overflow) for that CPU.
+ *
+ * PT buffers must already exist (PtAllocateAllCpuBuffers must
+ * have run, i.e. PT is enabled). Idempotent within an enable
+ * cycle: a second call returns the already-cached mappings. On
+ * any per-CPU failure the partial work is rolled back and the
+ * function returns -1.
+ *
+ * @return INT32 0 on success, -1 on failure.
+ */
+INT32
+PtMmapAllCpuBuffersToUser(PT_USER_BUFFER_DESC * OutDescs, UINT32 MaxDescs, UINT32 * OutNumCpus)
+{
+ UINT32 ProcessorsCount;
+ UINT32 i;
+
+ if (OutDescs == NULL || OutNumCpus == NULL || g_PtStateList == NULL)
+ return -1;
+
+ ProcessorsCount = KeQueryActiveProcessorCount(0);
+ if (ProcessorsCount == 0 || ProcessorsCount > MaxDescs || ProcessorsCount > PT_MAX_CPUS_FOR_MMAP)
+ return -1;
+
+ if (!g_PtUserMappingsActive)
+ {
+ for (i = 0; i < ProcessorsCount; i++)
+ {
+ PT_PER_CPU * Cpu = &g_PtStateList[i];
+
+ if (Cpu->Buffer.OutputVa == NULL || Cpu->Buffer.OverflowVa == NULL)
+ {
+ PtUnmapAllCpuBuffersFromUser();
+ return -1;
+ }
+
+ if (PtMmapCpuRegionToUser(Cpu->Buffer.OutputVa,
+ Cpu->Buffer.OutputPhysical,
+ (SIZE_T)Cpu->Buffer.OutputSize,
+ Cpu->Buffer.OverflowPhysical,
+ (SIZE_T)PT_OVERFLOW_SIZE,
+ &g_PtUserMappings[i].Mdl,
+ &g_PtUserMappings[i].UserVa) != 0)
+ {
+ PtUnmapAllCpuBuffersFromUser();
+ return -1;
+ }
+ }
+
+ g_PtUserMappingsActive = TRUE;
+ }
+
+ for (i = 0; i < ProcessorsCount; i++)
+ {
+ OutDescs[i].CpuId = i;
+ OutDescs[i].Reserved = 0;
+ OutDescs[i].UserVa = (UINT64)(ULONG_PTR)g_PtUserMappings[i].UserVa;
+ OutDescs[i].Size = g_PtStateList[i].Buffer.OutputSize + PT_OVERFLOW_SIZE;
+ }
+
+ *OutNumCpus = ProcessorsCount;
+ return 0;
+}
+
+/**
+ * @brief Release every user mapping created by PtMmapAllCpuBuffersToUser.
+ * Called by PtFreeAllCpuBuffers (i.e. on PT disable / flush) so
+ * user VAs stop being usable before the backing memory is freed.
+ * Also used as a rollback path on partial mmap failure.
+ *
+ * Always walks the full table (PtUnmapCpuRegionFromUser is
+ * NULL-safe) so rollback after a half-finished mapping still
+ * cleans up the CPUs that were mapped before the failure.
+ */
+VOID
+PtUnmapAllCpuBuffersFromUser()
+{
+ UINT32 i;
+
+ for (i = 0; i < PT_MAX_CPUS_FOR_MMAP; i++)
+ {
+ PtUnmapCpuRegionFromUser(g_PtUserMappings[i].Mdl,
+ g_PtUserMappings[i].UserVa);
+ g_PtUserMappings[i].Mdl = NULL;
+ g_PtUserMappings[i].UserVa = NULL;
+ }
+
+ g_PtUserMappingsActive = FALSE;
+}
+
+/**
+ * @brief Start PT tracing on the CURRENT CPU. Buffers must already be
+ * allocated by PtAllocateAllCpuBuffers (called at PASSIVE_LEVEL).
+ *
+ * Mirrors LbrStart but takes no parameters: per-CPU configuration is
+ * sourced from g_PtStateList[core].Config (defaulted at init time).
+ *
+ * @return BOOLEAN TRUE on success.
+ */
+BOOLEAN
+PtStart()
+{
+ UINT32 CurrentCore;
+ PT_PER_CPU * Cpu;
+
+ if (g_PtStateList == NULL)
+ {
+ LogInfo("PT: per-CPU state not initialized.\n");
+ return FALSE;
+ }
+
+ CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
+ Cpu = &g_PtStateList[CurrentCore];
+
+ if (Cpu->State == PT_STATE_DISABLED)
+ {
+ //
+ // Buffers should have been allocated at PASSIVE_LEVEL beforehand.
+ // Allocating from a DPC is unsafe (MmAllocateContiguousMemory* is
+ // a paged routine) so just bail out.
+ //
+ // LogInfo("PT: buffers not allocated for core %u\n", CurrentCore);
+ return FALSE;
+ }
+
+ if (PtEngineStart(Cpu) != 0)
+ {
+ // LogInfo("PT: PtEngineStart failed on core %u (state=%d)\n", CurrentCore, Cpu->State);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Stop PT tracing on the CURRENT CPU.
+ * Trace data accumulated in the per-CPU output buffer is left in
+ * place; PtSize / PtDump can read it later.
+ */
+VOID
+PtStop()
+{
+ UINT32 CurrentCore;
+ PT_PER_CPU * Cpu;
+
+ if (g_PtStateList == NULL)
+ return;
+
+ CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
+ Cpu = &g_PtStateList[CurrentCore];
+
+ // LogInfo("PT: stopping trace on core %d\n", CurrentCore);
+
+ PtEngineStop(Cpu, NULL);
+}
+
+/**
+ * @brief Pause PT tracing on the CURRENT CPU. Buffer state is preserved
+ * so a subsequent PtResume picks up where this left off.
+ */
+VOID
+PtPause()
+{
+ UINT32 CurrentCore;
+ PT_PER_CPU * Cpu;
+
+ if (g_PtStateList == NULL)
+ return;
+
+ CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
+ Cpu = &g_PtStateList[CurrentCore];
+
+ // LogInfo("PT: pausing trace on core %u\n", CurrentCore);
+
+ PtEnginePause(Cpu);
+}
+
+/**
+ * @brief Resume PT tracing on the CURRENT CPU after a prior PtPause.
+ */
+VOID
+PtResume()
+{
+ UINT32 CurrentCore;
+ PT_PER_CPU * Cpu;
+
+ if (g_PtStateList == NULL)
+ return;
+
+ CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
+ Cpu = &g_PtStateList[CurrentCore];
+
+ // LogInfo("PT: resuming trace on core %u\n", CurrentCore);
+
+ PtEngineResume(Cpu);
+}
+
+/**
+ * @brief Snapshot the current PT output position on the CURRENT CPU
+ * without disturbing tracing state. The returned value is the
+ * number of bytes of valid trace data sitting in this CPU's
+ * main + overflow buffer, i.e. the offset a decoder should stop
+ * at when reading from the user mapping.
+ */
+UINT64
+PtSize()
+{
+ UINT32 CurrentCore;
+ PT_PER_CPU * Cpu;
+ PT_OUTPUT_MASK_PTRS_REGISTER Mask;
+ UINT32 TopaIndex;
+ UINT32 BytesInEntry;
+
+ if (g_PtStateList == NULL)
+ return 0;
+
+ CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
+ Cpu = &g_PtStateList[CurrentCore];
+
+ if (Cpu->State != PT_STATE_TRACING && Cpu->State != PT_STATE_PAUSED && Cpu->State != PT_STATE_STOPPED)
+ return 0;
+
+ //
+ // Read MASK_PTRS without touching MSRs that would disturb tracing.
+ // For an active trace this gives the live byte count; for stopped
+ // traces it returns the position at the moment tracing was disabled.
+ //
+ Mask.Value = __readmsr(MSR_IA32_RTIT_OUTPUT_MASK_PTRS);
+ TopaIndex = (UINT32)Mask.MaskOrTableOffset;
+ BytesInEntry = (UINT32)Mask.OutputOffset;
+
+ if (TopaIndex == 0)
+ return BytesInEntry;
+
+ return Cpu->Buffer.OutputSize + BytesInEntry;
+}
+
+/**
+ * @brief Print PT trace summary for the CURRENT CPU.
+ *
+ * PT packets are a compressed binary stream that requires a decoder
+ * (libipt or similar) to be human-readable, so this only emits the
+ * per-CPU statistics; bulk packet data is preserved in the output
+ * buffer for offline retrieval.
+ */
+VOID
+PtDump()
+{
+ UINT32 CurrentCore;
+ PT_PER_CPU * Cpu;
+
+ if (g_PtStateList == NULL)
+ return;
+
+ CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
+ Cpu = &g_PtStateList[CurrentCore];
+
+ Log("PT trace summary for core %u\n", CurrentCore);
+ Log(" State : %d\n", Cpu->State);
+ Log(" TotalBytesCaptured : 0x%llx\n", Cpu->TotalBytesCaptured);
+ Log(" OutputBufferSize : 0x%llx\n", Cpu->Buffer.OutputSize);
+ Log(" TopaPhysical : 0x%llx\n", Cpu->Buffer.TopaPhysical);
+ Log(" OutputPhysical : 0x%llx\n", Cpu->Buffer.OutputPhysical);
+ Log(" TraceUser/Kernel : %u / %u\n", Cpu->Config.TraceUser, Cpu->Config.TraceKernel);
+ Log(" TargetCr3 : 0x%llx\n", Cpu->Config.TargetCr3);
+}
+
+/**
+ * @brief LBR-style filter wrapper: refresh tracing on the CURRENT CPU with
+ * a fresh PT_FILTER_OPTIONS.
+ *
+ * Mirrors LbrFilter — the caller hands in only the fields a user is
+ * allowed to drive (TraceUser, TraceKernel, TargetCr3, BufferSize,
+ * NumAddrRanges, AddrRanges) and PtFilter writes them into the
+ * per-CPU PT_TRACE_CONFIG one at a time. Engine-managed options
+ * (BranchEn, TscEn, MtcEn, CycEn, RetCompression, *Freq) are left
+ * alone, so a filter call can never accidentally turn off the
+ * packet types the engine relies on.
+ *
+ * BufferSize == 0 keeps the per-CPU value already in place, so
+ * pure filter changes (privilege bits, CR3, IP ranges) skip any
+ * reallocation of the ToPA / output / overflow buffers and can
+ * run entirely from a DPC. Genuine buffer-size changes still need
+ * a PASSIVE_LEVEL caller to free + reallocate; HyperTracePtFilter
+ * handles that case before broadcasting.
+ */
+VOID
+PtFilter(const PT_APPLY_CORE_FILTER_REQUEST * FilterRequest)
+{
+ UINT32 CurrentCore;
+ PT_PER_CPU * Cpu;
+ UINT32 i;
+ PT_CAPABILITIES Caps = {0};
+
+ if (g_PtStateList == NULL || FilterRequest == NULL)
+ return;
+
+ if (PtEngineQueryCapabilities(&Caps) != 0)
+ return;
+
+ CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
+ Cpu = &g_PtStateList[CurrentCore];
+
+ // LogInfo("PT: applying filter on core %u\n", CurrentCore);
+
+ //
+ // Stop tracing on this CPU first so we can safely mutate Cpu->Config
+ // and reprogram the RTIT_CTL bits.
+ //
+ if (Cpu->State == PT_STATE_TRACING || Cpu->State == PT_STATE_PAUSED)
+ {
+ PtEngineStop(Cpu, NULL);
+ }
+
+ //
+ // Apply only the user-tunable fields to this CPU's per-CPU config.
+ //
+ Cpu->Config.TraceUser = (BOOLEAN)FilterRequest->FilterOptions.TraceUser;
+ Cpu->Config.TraceKernel = (BOOLEAN)FilterRequest->FilterOptions.TraceKernel;
+
+ if (FilterRequest->EnableOptions.Cr3 != 0 && !Caps.Cr3Filtering)
+ {
+ // LogInfo("PT: CR3 filtering requested but not supported by CPU\n");
+ Cpu->Config.TargetCr3 = 0;
+ }
+ else
+ {
+ Cpu->Config.TargetCr3 = FilterRequest->EnableOptions.Cr3;
+ }
+
+ if (FilterRequest->FilterOptions.NumAddrRanges > Caps.NumAddrRanges)
+ {
+ // LogInfo("PT: requested %u IP filter ranges, but CPU only supports %u\n", FilterRequest->FilterOptions.NumAddrRanges, Caps.NumAddrRanges);
+ Cpu->Config.NumAddrRanges = Caps.NumAddrRanges;
+ }
+ else if (FilterRequest->FilterOptions.NumAddrRanges > 0 && !Caps.IpFiltering)
+ {
+ // LogInfo("PT: IP filtering requested but not supported by CPU\n");
+ Cpu->Config.NumAddrRanges = 0;
+ }
+ else
+ {
+ Cpu->Config.NumAddrRanges = FilterRequest->FilterOptions.NumAddrRanges;
+ }
+
+ if (FilterRequest->BufferSize != 0)
+ {
+ Cpu->Config.BufferSize = FilterRequest->BufferSize;
+ }
+
+ for (i = 0; i < PT_MAX_ADDR_RANGES; i++)
+ {
+ Cpu->Config.AddrRanges[i] = FilterRequest->FilterOptions.AddrRanges[i];
+ }
+
+ //
+ // If the per-CPU buffers haven't been allocated yet, leave the slot
+ // configured so the next PtStart picks it up — skip starting here
+ // because PtEngineStart needs ToPA / output / overflow already
+ // allocated at PASSIVE_LEVEL.
+ //
+ if (Cpu->State == PT_STATE_DISABLED)
+ return;
+
+ PtEngineStart(Cpu);
+}
+
+/**
+ * @brief Flush PT trace state on the CURRENT CPU — disables tracing and
+ * clears the bytes-captured counter so the next PtStart begins from
+ * a fresh baseline. Buffer freeing happens at PASSIVE_LEVEL via
+ * PtFreeAllCpuBuffers; this is safe to call from a DPC.
+ *
+ * Mirrors LbrFlush.
+ */
+VOID
+PtFlush()
+{
+ UINT32 CurrentCore;
+ PT_PER_CPU * Cpu;
+
+ if (g_PtStateList == NULL)
+ return;
+
+ CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
+ Cpu = &g_PtStateList[CurrentCore];
+
+ // LogInfo("PT: flush on core %u\n", CurrentCore);
+
+ if (Cpu->State == PT_STATE_TRACING || Cpu->State == PT_STATE_PAUSED)
+ {
+ PtEngineStop(Cpu, NULL);
+ }
+
+ Cpu->TotalBytesCaptured = 0;
+}
diff --git a/hyperdbg/hypertrace/header/api/LbrApi.h b/hyperdbg/hypertrace/header/api/LbrApi.h
new file mode 100644
index 00000000..7569fe2e
--- /dev/null
+++ b/hyperdbg/hypertrace/header/api/LbrApi.h
@@ -0,0 +1,21 @@
+/**
+ * @file LbrApi.h
+ * @author Hari Mishal (harimishal6@gmail.com)
+ * @brief Header for LBR tracing routines for HyperTrace module (Intel Last Branch Record)
+ * @details
+ * @version 0.18
+ * @date 2025-12-02
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+VOID
+HyperTraceLbrExamplePerformTrace();
+
+BOOLEAN
+HyperTraceLbrDisable(HYPERTRACE_LBR_OPERATION_PACKETS * HyperTraceOperationRequest);
diff --git a/hyperdbg/hypertrace/header/api/PtApi.h b/hyperdbg/hypertrace/header/api/PtApi.h
new file mode 100644
index 00000000..d75ea2b0
--- /dev/null
+++ b/hyperdbg/hypertrace/header/api/PtApi.h
@@ -0,0 +1,21 @@
+/**
+ * @file PtApi.h
+ * @author Masoud Rahimi Jafari (Masoodrahimy1379@gmail.com)
+ * @brief Header for PT tracing routines for HyperTrace module (Intel Processor Trace)
+ * @details
+ * @version 0.19
+ * @date 2026-04-29
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+//
+// The exported HyperTracePt* API is declared in
+// SDK/imports/kernel/HyperDbgHyperTrace.h (with the dllexport / dllimport
+// decoration). Internal-only PT helpers should be declared here.
+//
diff --git a/hyperdbg/hypertrace/header/api/TraceApi.h b/hyperdbg/hypertrace/header/api/TraceApi.h
new file mode 100644
index 00000000..1dff92cf
--- /dev/null
+++ b/hyperdbg/hypertrace/header/api/TraceApi.h
@@ -0,0 +1,47 @@
+/**
+ * @file TraceApi.h
+ * @author
+ * @brief Header for general tracing routines for HyperTrace module
+ * @details
+ * @version 0.19
+ * @date 2026-04-25
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+//
+// Most of the functions are defined and exported
+//
+
+//////////////////////////////////////////////////
+// Platform Wrappers //
+//////////////////////////////////////////////////
+
+#define xrdmsr(msr, pval) (*(pval) = CpuReadMsr(msr))
+#define xwrmsr(msr, val) (msr, val)
+
+// CPUID (Fixed C6001: initialized CpuInfo)
+#define xcpuid(code, a, b, c, d) \
+ { \
+ int CpuInfo[4] = {0}; \
+ CpuCpuId(CpuInfo, code); \
+ *a = CpuInfo[0]; \
+ *b = CpuInfo[1]; \
+ *c = CpuInfo[2]; \
+ *d = CpuInfo[3]; \
+ }
+
+#define xcpuidex(code, subleaf, a, b, c, d) \
+ { \
+ int CpuInfo[4] = {0}; \
+ CpuCpuIdEx(CpuInfo, code, subleaf); \
+ *a = CpuInfo[0]; \
+ *b = CpuInfo[1]; \
+ *c = CpuInfo[2]; \
+ *d = CpuInfo[3]; \
+ }
diff --git a/hyperdbg/hypertrace/header/broadcast/Broadcast.h b/hyperdbg/hypertrace/header/broadcast/Broadcast.h
new file mode 100644
index 00000000..eb857072
--- /dev/null
+++ b/hyperdbg/hypertrace/header/broadcast/Broadcast.h
@@ -0,0 +1,53 @@
+
+/**
+ * @file Broadcast.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Headers for broadcasting functions
+ * @details
+ * @version 0.19
+ * @date 2026-04-19
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+VOID
+BroadcastEnableLbrOnAllCores();
+
+VOID
+BroadcastDisableLbrOnAllCores();
+
+VOID
+BroadcastFlushLbrOnAllCores();
+
+VOID
+BroadcastFilterLbrOptionsOnAllCores(UINT64 LbrFilterOptions);
+
+VOID
+BroadcastEnablePtOnAllCores();
+
+VOID
+BroadcastDisablePtOnAllCores();
+
+VOID
+BroadcastPausePtOnAllCores();
+
+VOID
+BroadcastResumePtOnAllCores();
+
+VOID
+BroadcastSizePtOnAllCores(UINT64 * Sizes);
+
+VOID
+BroadcastDumpPtOnAllCores();
+
+VOID
+BroadcastFlushPtOnAllCores();
+
+VOID
+BroadcastFilterPtOnAllCores(PT_APPLY_CORE_FILTER_REQUEST * FilterRequest);
diff --git a/hyperdbg/hypertrace/header/broadcast/DpcRoutines.h b/hyperdbg/hypertrace/header/broadcast/DpcRoutines.h
new file mode 100644
index 00000000..da4c94b5
--- /dev/null
+++ b/hyperdbg/hypertrace/header/broadcast/DpcRoutines.h
@@ -0,0 +1,53 @@
+
+/**
+ * @file DpcRoutines.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Definition for DPC functions
+ * @details
+ * @version 0.19
+ * @date 2026-04-19
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+BOOLEAN
+DpcRoutineEnableLbr(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2);
+
+BOOLEAN
+DpcRoutineDisableLbr(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2);
+
+BOOLEAN
+DpcRoutineFlushLbr(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2);
+
+BOOLEAN
+DpcRoutineFilterLbrOptions(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2);
+
+BOOLEAN
+DpcRoutineEnablePt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2);
+
+BOOLEAN
+DpcRoutineDisablePt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2);
+
+BOOLEAN
+DpcRoutinePausePt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2);
+
+BOOLEAN
+DpcRoutineResumePt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2);
+
+BOOLEAN
+DpcRoutineSizePt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2);
+
+BOOLEAN
+DpcRoutineDumpPt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2);
+
+BOOLEAN
+DpcRoutineFlushPt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2);
+
+BOOLEAN
+DpcRoutineFilterPt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2);
diff --git a/hyperdbg/hypertrace/header/common/UnloadDll.h b/hyperdbg/hypertrace/header/common/UnloadDll.h
new file mode 100644
index 00000000..9bb252d2
--- /dev/null
+++ b/hyperdbg/hypertrace/header/common/UnloadDll.h
@@ -0,0 +1,22 @@
+/**
+ * @file UnloadDll.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Headers for unloading DLL in the target Windows
+ *
+ * @version 0.4
+ * @date 2023-07-06
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Exported Functions //
+//////////////////////////////////////////////////
+
+__declspec(dllexport) NTSTATUS
+DllInitialize(_In_ PUNICODE_STRING RegistryPath);
+
+__declspec(dllexport) NTSTATUS
+ DllUnload(VOID);
diff --git a/hyperdbg/hypertrace/header/globals/GlobalVariables.h b/hyperdbg/hypertrace/header/globals/GlobalVariables.h
new file mode 100644
index 00000000..7e50072c
--- /dev/null
+++ b/hyperdbg/hypertrace/header/globals/GlobalVariables.h
@@ -0,0 +1,101 @@
+
+/**
+ * @file GlobalVariables.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Definition for global variables
+ * @details
+ * @version 0.19
+ * @date 2026-04-19
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Global Variables //
+//////////////////////////////////////////////////
+
+/**
+ * @brief List of callbacks
+ *
+ */
+HYPERTRACE_CALLBACKS g_Callbacks;
+
+/**
+ * @brief The flag indicating whether the hypertrace module callbacks is initialized or not
+ *
+ */
+BOOLEAN g_HyperTraceCallbacksInitialized;
+
+/**
+ * @brief The flag indicating whether the initialization is being done for hypervisor environment or not
+ *
+ */
+BOOLEAN g_RunningOnHypervisorEnvironment;
+
+/**
+ * @brief The flag indicating whether the architectural LBR is supported by the CPU or not
+ * if false it means the legacy LBR is supported
+ *
+ */
+BOOLEAN g_ArchBasedLastBranchRecord;
+
+/**
+ * @brief The flag indicating whether the hypertrace LBR tracing is initialized or not
+ *
+ */
+BOOLEAN g_LastBranchRecordEnabled;
+
+/**
+ * @brief This will be a dynamically allocated array to hold LBR states for each core
+ *
+ */
+LBR_STACK_ENTRY * g_LbrStateList;
+
+/**
+ * @brief The global variable to hold the LBR capacity of the current CPU
+ *
+ */
+ULONGLONG g_LbrCapacity;
+
+/**
+ * @brief The global variable to hold CPUID leaf 0x28 information (Architectural LBR Enumeration Leaf)
+ *
+ */
+CPUID28_LEAFS g_Cpuid28Leafs;
+
+/**
+ * @brief The global variable to hold the current LBR filter options bitmask (for both architectural and legacy LBR)
+ *
+ */
+UINT64 g_LbrFilterOptions;
+
+/**
+ * @brief The flag indicating whether the hypertrace Processor Trace is initialized or not
+ *
+ */
+BOOLEAN g_ProcessorTraceEnabled;
+
+/**
+ * @brief Dynamically allocated array of per-CPU Intel PT state.
+ * Sized to KeQueryActiveProcessorCount(0) at hypertrace init.
+ */
+PT_PER_CPU * g_PtStateList;
+
+/**
+ * @brief Per-CPU MDL + user-mode VA for the PT mmap surface (main
+ * output buffer concatenated with the 4 KB overflow page in a
+ * single contiguous user mapping). Populated by
+ * PtMmapAllCpuBuffersToUser, torn down by
+ * PtUnmapAllCpuBuffersFromUser. The user VAs are only valid in
+ * the address space of the process that called the mmap IOCTL —
+ * see HYPERTRACE_PT_MMAP_PACKETS for the contract.
+ */
+PT_USER_MAPPING g_PtUserMappings[PT_MAX_CPUS_FOR_MMAP];
+
+/**
+ * @brief Set while g_PtUserMappings holds live user mappings; cleared
+ * by PtUnmapAllCpuBuffersFromUser.
+ */
+BOOLEAN g_PtUserMappingsActive;
diff --git a/hyperdbg/hypertrace/header/lbr/Lbr.h b/hyperdbg/hypertrace/header/lbr/Lbr.h
new file mode 100644
index 00000000..a9293850
--- /dev/null
+++ b/hyperdbg/hypertrace/header/lbr/Lbr.h
@@ -0,0 +1,188 @@
+/**
+ * @file Lbr.h
+ * @author Hari Mishal (harimishal6@gmail.com)
+ * @brief Message logging and tracing implementation
+ * @details Modified from LIBIHT project (Thomasaon Zhao et al) with Windows style updates.
+ * @version 0.18
+ * @date 2025-12-02
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Constants //
+//////////////////////////////////////////////////
+
+//
+// Legacy LBR MSRs
+//
+#ifndef MSR_LEGACY_LBR_SELECT
+# define MSR_LEGACY_LBR_SELECT 0x000001C8 // originally defined in SDK to be used by other module like HyperHV
+#endif // !MSR_LEGACY_LBR_SELECT
+#define MSR_LBR_TOS 0x000001C9
+#define MSR_LASTBRANCH_0_FROM_IP 0x00000680
+#define MSR_LASTBRANCH_0_TO_IP 0x000006C0
+#define MSR_LASTBRANCH_INFO_0 0x00000DC0
+#define LBR_SELECT_WITHOUT_FILTER 0x00000000
+
+//
+// Arch LBR MSRs
+//
+#define IA32_LBR_0_FROM_IP 0x1500
+#define IA32_LBR_0_TO_IP 0x1600
+#define IA32_LBR_0_INFO 0x1200
+
+#define CPUID_ARCH_LAST_BRANCH_RECORD_INFORMATION 0x1c
+
+//
+// This MSR could be used as an alternative to MSR_LBR_SELECT and IA32_DEBUGCTL for enabling and configuring LBR
+// For using that in hypervisor Load Guest IA32_LBR_CTL Entry Control and Clear IA32_LBR_CTL Exit Control should
+// be configured, plus host could control it over Guest IA32_LBR_CTL on VMCS
+//
+#define IA32_LBR_CTL 0x000014CE
+
+//////////////////////////////////////////////////
+// CPUID Structures //
+//////////////////////////////////////////////////
+
+/*
+ * @brief Intel Architectural LBR CPUID detection/enumeration details:
+ */
+typedef union _CPUID28_EAX
+{
+ struct
+ {
+ /* Supported LBR depth values */
+ UINT32 LbrDepthMask : 8;
+ UINT32 Reserved : 22;
+ /* Deep C-state Reset */
+ UINT32 LbrDeepCReset : 1;
+ /* IP values contain LIP */
+ UINT32 LbrLip : 1;
+ };
+ UINT32 AsUInt;
+} CPUID28_EAX, *PCPUID28_EAX;
+
+typedef union _CPUID28_EBX
+{
+ struct
+ {
+ /* CPL Filtering Supported */
+ UINT32 LbrCpl : 1;
+ /* Branch Filtering Supported */
+ UINT32 LbrFilter : 1;
+ /* Call-stack Mode Supported */
+ UINT32 LbrCallStack : 1;
+ UINT32 Reserved : 29;
+ };
+ UINT32 AsUInt;
+} CPUID28_EBX, *PCPUID28_EBX;
+
+typedef union _CPUID28_ECX
+{
+ struct
+ {
+ /* Mispredict Bit Supported */
+ UINT32 LbrMispred : 1;
+ /* Timed LBRs Supported */
+ UINT32 LbrTimedLbr : 1;
+ /* Branch Type Field Supported */
+ UINT32 LbrBrType : 1;
+ UINT32 Reserved : 29;
+ };
+ UINT32 AsUInt;
+} CPUID28_ECX, *PCPUID28_ECX;
+
+/*
+ * @brief The structure to hold the CPUID leaf 0x28 details for Architectural LBRs
+ */
+typedef struct _CPUID28_LEAFS
+{
+ CPUID28_EAX Eax;
+ CPUID28_EBX Ebx;
+ CPUID28_ECX Ecx;
+ UINT32 Edx;
+} CPUID28_LEAFS, *PCPUID28_LEAFS;
+
+//////////////////////////////////////////////////
+// MSR Structures //
+//////////////////////////////////////////////////
+
+/**
+ * @brief The structure to hold the IA32_LBR_CTL MSR, which is used to enable and configure the LBR feature
+ * @details MSR Address: 0x14CEH (Hex) / 5326 (Dec)
+ */
+typedef union _IA32_LBR_CTL_REGISTER
+{
+ ULONG64 AsUInt;
+
+ struct
+ {
+ ULONG64 LBREn : 1; // [0] When set, enables LBR recording
+ ULONG64 OS : 1; // [1] When set, allows LBR recording when CPL == 0
+ ULONG64 USR : 1; // [2] When set, allows LBR recording when CPL != 0
+ ULONG64 CallStack : 1; // [3] When set, records branches in call-stack mode (See Section 7.1.2.4)
+ ULONG64 Reserved0 : 12; // [15:4] Reserved (must be zero)
+ ULONG64 JCC : 1; // [16] When set, records taken conditional branches (See Section 7.1.2.3)
+ ULONG64 NearRelJmp : 1; // [17] When set, records near relative JMPs (See Section 7.1.2.3)
+ ULONG64 NearIndJmp : 1; // [18] When set, records near indirect JMPs (See Section 7.1.2.3)
+ ULONG64 NearRelCall : 1; // [19] When set, records near relative CALLs (See Section 7.1.2.3)
+ ULONG64 NearIndCall : 1; // [20] When set, records near indirect CALLs (See Section 7.1.2.3)
+ ULONG64 NearRet : 1; // [21] When set, records near RETs (See Section 7.1.2.3)
+ ULONG64 OtherBranch : 1; // [22] When set, records other branches (See Section 7.1.2.3)
+ ULONG64 Reserved1 : 41; // [63:23] Reserved (must be zero)
+ } Bits;
+
+} IA32_LBR_CTL_REGISTER, *PIA32_LBR_CTL_REGISTER;
+
+//////////////////////////////////////////////////
+// Global Variables //
+//////////////////////////////////////////////////
+
+/**
+ * @brief The structure to hold the mapping of CPU model to its LBR capacity
+ *
+ */
+typedef struct _CPU_LBR_MAP
+{
+ ULONG Model;
+ ULONG LbrCapacity;
+} CPU_LBR_MAP, *PCPU_LBR_MAP;
+
+/**
+ * @brief The global variable to hold the mapping of CPU model to its LBR capacity
+ *
+ */
+extern CPU_LBR_MAP CPU_LBR_MAPS[];
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+BOOLEAN
+LbrCheckAndReadLegacyLbrDetails();
+
+BOOLEAN
+LbrCheckAndReadArchitecturalLbrDetails();
+
+BOOLEAN
+LbrStart(UINT64 FilterOptions);
+
+BOOLEAN
+LbrCheck();
+
+VOID
+LbrFilter(UINT64 FilterOptions);
+
+VOID
+LbrStop();
+
+VOID
+LbrFlush();
+
+VOID
+LbrSave();
+
+VOID
+LbrPrint();
diff --git a/hyperdbg/hypertrace/header/pch.h b/hyperdbg/hypertrace/header/pch.h
new file mode 100644
index 00000000..4e591600
--- /dev/null
+++ b/hyperdbg/hypertrace/header/pch.h
@@ -0,0 +1,124 @@
+/**
+ * @file pch.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Headers of Message logging and tracing
+ * @details
+ * @version 0.2
+ * @date 2023-01-23
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#define _NO_CRT_STDIO_INLINE
+
+#pragma warning(disable : 4201) // Suppress nameless struct/union warning
+
+//
+// Environment headers
+//
+#include "platform/general/header/Environment.h"
+
+#ifdef HYPERDBG_ENV_WINDOWS
+
+//
+// Windows defined functions
+//
+# include
+# include
+# include
+
+#endif // HYPERDBG_ENV_WINDOWS
+
+//
+// Scope definitions
+//
+#define HYPERDBG_KERNEL_MODE
+#define HYPERDBG_HYPERTRACE
+
+//
+// Add ia32-doc
+//
+#include "ia32-doc/out/ia32.h"
+
+//
+// SDK headers
+//
+#include "SDK/HyperDbgSdk.h"
+
+//
+// Configuration
+//
+#include "config/Configuration.h"
+
+//
+// Platform independent headers
+//
+#include "platform/kernel/header/PlatformMem.h"
+#include "platform/kernel/header/PlatformIntrinsics.h"
+#include "platform/kernel/header/PlatformBroadcast.h"
+#include "platform/kernel/header/PlatformCpu.h"
+#include "platform/kernel/header/PlatformSpinlock.h"
+#include "platform/kernel/header/PlatformIrql.h"
+#include "platform/kernel/header/PlatformDpc.h"
+#include "platform/kernel/header/PlatformTime.h"
+#include "platform/kernel/header/PlatformDbg.h"
+#include "platform/kernel/header/PlatformIo.h"
+#include "platform/kernel/header/PlatformEvent.h"
+
+//
+// Unload function (to be called when the driver is unloaded)
+//
+#include "common/UnloadDll.h"
+
+//
+// Hyperlog headers
+//
+#include "components/callback/header/HyperLogCallback.h"
+#include "SDK/imports/kernel/HyperDbgHyperLogIntrinsics.h"
+
+//
+// Spinlock headers
+//
+#include "components/spinlock/header/Spinlock.h"
+
+//
+// Hypertrace Callbacks
+//
+#include "SDK/modules/HyperTrace.h"
+
+//
+// Definition of general tracing types
+//
+#include "api/TraceApi.h"
+
+//
+// Definition of tracing types and structures (Last Branch Record)
+//
+#include "lbr/Lbr.h"
+#include "api/LbrApi.h"
+
+//
+// Definition of tracing types and structures (Processor Trace).
+// Pt.h must come before broadcast/Broadcast.h because Broadcast.h
+// references PT_FILTER_OPTIONS in its function signatures.
+//
+#include "pt/Pt.h"
+#include "api/PtApi.h"
+
+//
+// DPC and broadcasting function headers
+//
+#include "broadcast/DpcRoutines.h"
+#include "broadcast/Broadcast.h"
+
+//
+// Export functions
+//
+#include "SDK/imports/kernel/HyperDbgHyperTrace.h"
+
+//
+// Global variables
+//
+#include "globals/GlobalVariables.h"
diff --git a/hyperdbg/hypertrace/header/pt/Pt.h b/hyperdbg/hypertrace/header/pt/Pt.h
new file mode 100644
index 00000000..f7801bbb
--- /dev/null
+++ b/hyperdbg/hypertrace/header/pt/Pt.h
@@ -0,0 +1,146 @@
+/**
+ * @file Pt.h
+ * @author Masoud Rahimi Jafari (Masoodrahimy1379@gmail.com)
+ * @brief Header for Processor Trace (PT) tracing routines for HyperTrace module
+ * @details Engine that programs Intel PT MSRs from VMX root or kernel context.
+ * Buffer / ToPA management is kept here; user-visible PT structures
+ * live in the SDK header [PtDefinitions.h].
+ * @version 0.19
+ * @date 2026-04-29
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Structures //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Per-CPU bookkeeping for the user-mode mmap surface.
+ *
+ * One MDL + user VA per CPU describes the main output buffer
+ * immediately followed by the 4 KB overflow page as a single
+ * virtually contiguous region in the mapping process. Lives in
+ * g_PtUserMappings; lifetime tied to the PT enable cycle.
+ */
+typedef struct _PT_USER_MAPPING
+{
+ PMDL Mdl;
+ PVOID UserVa;
+
+} PT_USER_MAPPING, *PPT_USER_MAPPING;
+
+/**
+ * @brief PT apply core filter requests.
+ */
+typedef struct _PT_APPLY_CORE_FILTER_REQUEST
+{
+ PT_FILTER_OPTIONS FilterOptions;
+ PT_ENABLE_OPTIONS EnableOptions;
+ UINT64 BufferSize; /* Output buffer size (0 = default / PT_DEFAULT_BUFFER_SIZE) */
+
+} PT_APPLY_CORE_FILTER_REQUEST, *PPT_APPLY_CORE_FILTER_REQUEST;
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+//
+// HyperDbg-style wrappers (mirroring Lbr*)
+//
+
+BOOLEAN
+PtCheck();
+
+BOOLEAN
+PtStart();
+
+VOID
+PtStop();
+
+VOID
+PtPause();
+
+VOID
+PtResume();
+
+UINT64
+PtSize();
+
+VOID
+PtDump();
+
+VOID
+PtFlush();
+
+//
+// LBR-style filter wrapper, one CPU at a time. Mirrors LbrFilter in shape:
+// caller passes a PT_APPLY_CORE_FILTER_REQUEST describing only the user-tunable bits
+// (TraceUser, TraceKernel, TargetCr3, BufferSize, NumAddrRanges, AddrRanges),
+// and PtFilter handles the stop / config-update / start sequence on the
+// CURRENT CPU. Engine-internal config (BranchEn, TscEn, etc.) is left
+// untouched in the per-CPU PT_TRACE_CONFIG.
+//
+VOID
+PtFilter(const PT_APPLY_CORE_FILTER_REQUEST * FilterRequest);
+
+//
+// PASSIVE_LEVEL helpers — call before / after the per-core DPC broadcasts.
+// Required because MmAllocateContiguousMemorySpecifyCache and
+// MmFreeContiguousMemory must run at IRQL == PASSIVE_LEVEL.
+//
+
+BOOLEAN
+PtAllocateAllCpuBuffers();
+
+VOID
+PtFreeAllCpuBuffers();
+
+//
+// User-mode mmap surface: map every per-CPU main output + overflow
+// buffer into the calling user process. Idempotent within an enable
+// cycle; torn down by PtFreeAllCpuBuffers (i.e. PT disable / flush).
+//
+INT32
+PtMmapAllCpuBuffersToUser(PT_USER_BUFFER_DESC * OutDescs, UINT32 MaxDescs, UINT32 * OutNumCpus);
+
+VOID
+PtUnmapAllCpuBuffersFromUser();
+
+//
+// Engine routines (operate on a specific PT_PER_CPU instance)
+//
+
+INT32
+PtEngineQueryCapabilities(PT_CAPABILITIES * OutCaps);
+
+VOID
+PtEngineInitDefaultConfig(PT_TRACE_CONFIG * Config);
+
+INT32
+PtEngineAllocateBuffers(PT_PER_CPU * Cpu, const PT_TRACE_CONFIG * Config);
+
+VOID
+PtEngineFreeBuffers(PT_PER_CPU * Cpu);
+
+INT32
+PtEngineStart(PT_PER_CPU * Cpu);
+
+UINT64
+PtEngineStop(PT_PER_CPU * Cpu, PT_OUTPUT_BUFFER * Out);
+
+INT32
+PtEnginePause(PT_PER_CPU * Cpu);
+
+INT32
+PtEngineResume(PT_PER_CPU * Cpu);
+
+UINT64
+PtEngineHandlePmi(PT_PER_CPU * Cpu, PT_OUTPUT_BUFFER * Out);
+
+BOOLEAN
+PtEngineIsPtPmi();
+
+INT32
+PtEngineSizeToTopaEncoding(UINT64 SizeInBytes);
diff --git a/hyperdbg/hypertrace/hypertrace.def b/hyperdbg/hypertrace/hypertrace.def
new file mode 100644
index 00000000..54a2d6b2
--- /dev/null
+++ b/hyperdbg/hypertrace/hypertrace.def
@@ -0,0 +1,6 @@
+LIBRARY hypertrace
+
+EXPORTS
+
+ DllInitialize PRIVATE
+ DllUnload PRIVATE
\ No newline at end of file
diff --git a/hyperdbg/hypertrace/hypertrace.vcxproj b/hyperdbg/hypertrace/hypertrace.vcxproj
new file mode 100644
index 00000000..1b0d38f2
--- /dev/null
+++ b/hyperdbg/hypertrace/hypertrace.vcxproj
@@ -0,0 +1,153 @@
+
+
+
+
+
+
+
+ debug
+ x64
+
+
+ release
+ x64
+
+
+
+ {9FA45E25-DAEB-4C2D-806C-7908A180195D}
+ {1bc93793-694f-48fe-9372-81e2b05556fd}
+ v4.5
+ 12.0
+ Debug
+ x64
+ hypertrace
+ $(LatestTargetPlatformVersion)
+
+
+
+ Windows10
+ true
+ WindowsKernelModeDriver10.0
+ DynamicLibrary
+ KMDF
+ Desktop
+ false
+
+
+ Windows10
+ false
+ WindowsKernelModeDriver10.0
+ DynamicLibrary
+ KMDF
+ Desktop
+ false
+
+
+
+
+
+
+
+
+
+
+ DbgengKernelDebugger
+ $(SolutionDir)build\bin\$(Configuration)\
+ $(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\
+ false
+
+
+ DbgengKernelDebugger
+ $(SolutionDir)build\bin\$(Configuration)\
+ $(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\
+ false
+
+
+
+ sha256
+
+
+ $(SolutionDir)\include;$(ProjectDir)header;$(SolutionDir)dependencies;%(AdditionalIncludeDirectories)
+ true
+ Create
+ pch.h
+ stdcpp20
+
+
+ true
+
+ true
+ hypertrace.def
+
+
+
+
+ sha256
+
+
+ $(SolutionDir)\include;$(ProjectDir)header;$(SolutionDir)dependencies;%(AdditionalIncludeDirectories)
+ true
+ Create
+ pch.h
+ stdcpp20
+ Full
+
+
+ true
+
+ true
+ hypertrace.def
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/hypertrace/hypertrace.vcxproj.filters b/hyperdbg/hypertrace/hypertrace.vcxproj.filters
new file mode 100644
index 00000000..32ace76c
--- /dev/null
+++ b/hyperdbg/hypertrace/hypertrace.vcxproj.filters
@@ -0,0 +1,155 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+ {1ab177b4-9e6c-460e-834a-8fced04b42a3}
+
+
+ {21f0281e-fc2a-4e13-97ac-e4b35a05a31e}
+
+
+ {09d5457a-bade-4a3f-a171-641110492d57}
+
+
+ {b8b32a09-61fb-433a-ad79-eb7cfc5f3437}
+
+
+ {32ea8333-847b-443d-8992-4140d54dc1d3}
+
+
+ {2271439b-db98-4351-9457-77225ccee301}
+
+
+ {d2eb3e6f-49d6-49c6-a255-a0158414ff54}
+
+
+ {df6eb164-34b2-4f2a-9530-b88443662fb7}
+
+
+ {cb4e742a-6e43-4798-af4a-72bcb11089c9}
+
+
+ {ab21116d-5f5b-4ef8-82bb-6585ac3dec95}
+
+
+ {57d56081-eede-41a3-b9f0-e7019d32c986}
+
+
+ {a59b8bf9-45ee-49c9-bbac-9b065f41f1a2}
+
+
+ {7d49a3f4-a2eb-48b1-8f41-220b9ccf30dc}
+
+
+ {4f62540b-d186-479e-83a0-1b550134f487}
+
+
+ {9fe877a7-e261-4579-9752-a3156b6e69d9}
+
+
+ {8bc2336a-b1c5-4e93-9793-23a5cfdc741d}
+
+
+ {fc73555b-2be3-4898-bcdb-df83fa3e1388}
+
+
+
+
+ code\platform
+
+
+ code\api
+
+
+ code\api
+
+
+ code\broadcast
+
+
+ code\broadcast
+
+
+ code\common
+
+
+ code\lbr
+
+
+ code\pt
+
+
+ code\api
+
+
+ code\platform
+
+
+ code\broadcast
+
+
+ code\platform
+
+
+ code\components\callback
+
+
+
+
+ header
+
+
+ header\platform
+
+
+ header\api
+
+
+ header\broadcast
+
+
+ header\broadcast
+
+
+ header\common
+
+
+ header\globals
+
+
+ header\lbr
+
+
+ header\pt
+
+
+ header\api
+
+
+ header\api
+
+
+ header\platform
+
+
+ header\platform
+
+
+ header\platform
+
+
+ header\components\callback
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/hypertrace/packages.config b/hyperdbg/hypertrace/packages.config
new file mode 100644
index 00000000..eb276766
--- /dev/null
+++ b/hyperdbg/hypertrace/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/include/SDK/HyperDbgSdk.h b/hyperdbg/include/SDK/HyperDbgSdk.h
index 23583067..fc53dd57 100644
--- a/hyperdbg/include/SDK/HyperDbgSdk.h
+++ b/hyperdbg/include/SDK/HyperDbgSdk.h
@@ -1,13 +1,15 @@
#pragma once
-#include "SDK/headers/Constants.h"
+//
+// General SDK Headers
+//
#include "SDK/headers/BasicTypes.h"
+#include "SDK/headers/Constants.h"
#include "SDK/headers/ErrorCodes.h"
#include "SDK/headers/Connection.h"
#include "SDK/headers/DataTypes.h"
#include "SDK/headers/Ioctls.h"
#include "SDK/headers/Events.h"
-#include "SDK/headers/RequestStructures.h"
#include "SDK/headers/Symbols.h"
#include "SDK/headers/HardwareDebugger.h"
@@ -16,6 +18,21 @@
//
#include "SDK/headers/Pcie.h"
+//
+// Last Branch Records
+//
+#include "SDK/headers/LbrDefinitions.h"
+
+//
+// Intel Processor Trace
+//
+#include "SDK/headers/PtDefinitions.h"
+
+//
+// Request Packets
+//
+#include "SDK/headers/RequestStructures.h"
+
//
// Asserts
//
diff --git a/hyperdbg/include/SDK/headers/BasicTypes.h b/hyperdbg/include/SDK/headers/BasicTypes.h
index 0df9d348..17e5c84a 100644
--- a/hyperdbg/include/SDK/headers/BasicTypes.h
+++ b/hyperdbg/include/SDK/headers/BasicTypes.h
@@ -11,43 +11,102 @@
*/
#pragma once
-#pragma warning(disable : 4201) // Suppress nameless struct/union warning
+#ifdef _WIN32 // Windows
+
+# pragma warning(disable : 4201) // Suppress nameless struct/union warning
+
+#endif
//////////////////////////////////////////////////
// Basic Datatypes //
//////////////////////////////////////////////////
typedef unsigned long long QWORD;
-typedef unsigned __int64 UINT64, *PUINT64;
-typedef unsigned long DWORD;
typedef int BOOL;
-typedef unsigned char BYTE;
-typedef unsigned short WORD;
-typedef int INT;
-typedef unsigned int UINT;
-typedef unsigned int * PUINT;
-typedef unsigned __int64 ULONG64, *PULONG64;
-typedef unsigned __int64 DWORD64, *PDWORD64;
-typedef char CHAR;
-typedef wchar_t WCHAR;
-#define VOID void
-typedef unsigned char UCHAR;
+typedef short SHORT;
+typedef long LONG;
+
typedef unsigned short USHORT;
typedef unsigned long ULONG;
-typedef UCHAR BOOLEAN; // winnt
-typedef BOOLEAN * PBOOLEAN; // winnt
+typedef char CHAR;
+typedef unsigned char UCHAR;
+typedef UCHAR BOOLEAN;
+typedef BOOLEAN * PBOOLEAN;
+
+typedef unsigned long DWORD;
+typedef unsigned long ULONG;
+typedef unsigned char BYTE;
+typedef unsigned short USHORT;
+typedef unsigned short WORD;
+typedef int INT;
+typedef unsigned int UINT;
+typedef unsigned int * PUINT;
+
+typedef int INT;
+typedef signed char INT8, *PINT8;
+typedef signed short INT16, *PINT16;
+typedef signed int INT32, *PINT32;
+
+typedef unsigned char UINT8, *PUINT8;
+typedef unsigned short UINT16, *PUINT16;
+typedef unsigned int UINT32, *PUINT32;
+
+typedef void * PVOID;
+
+#ifdef _WIN32 // Windows
-typedef signed char INT8, *PINT8;
-typedef signed short INT16, *PINT16;
-typedef signed int INT32, *PINT32;
typedef signed __int64 INT64, *PINT64;
-typedef unsigned char UINT8, *PUINT8;
-typedef unsigned short UINT16, *PUINT16;
-typedef unsigned int UINT32, *PUINT32;
typedef unsigned __int64 UINT64, *PUINT64;
+typedef unsigned __int64 ULONG64, *PULONG64;
+typedef unsigned __int64 DWORD64, *PDWORD64;
+
+typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
+typedef unsigned __int64 ULONGLONG;
+
+typedef wchar_t WCHAR;
+
+#elif defined(__linux__) // Linux
+
+typedef void VOID;
+
+typedef size_t SIZE_T;
+typedef SIZE_T * PSIZE_T;
+
+typedef signed long long INT64, *PINT64;
+typedef unsigned long long UINT64, *PUINT64;
+
+typedef unsigned long long ULONG64, *PULONG64;
+typedef unsigned long long DWORD64, *PDWORD64;
+
+typedef unsigned long long ULONGLONG;
+typedef unsigned long long ULONG_PTR, *PULONG_PTR;
+
+typedef INT64 LONGLONG;
+
+typedef union _LARGE_INTEGER {
+ struct { DWORD LowPart; LONG HighPart; };
+ LONGLONG QuadPart;
+} LARGE_INTEGER, *PLARGE_INTEGER;
+
+//
+// To be fixed later, linux wchar_t is 4 bytes, but windows wchar_t is 2 bytes
+//
+// typedef UINT16 wchar_t;
+typedef UINT16 WCHAR;
+// typedef wchar_t WCHAR;
+
+typedef PVOID HANDLE;
+typedef HANDLE * PHANDLE;
+
+// Windows pointer-style aliases (used by the cross-platform driver/IOCTL wrappers)
+typedef PVOID LPVOID;
+typedef DWORD * LPDWORD;
+
+#endif
+
#define NULL_ZERO 0
#define NULL64_ZERO 0ull
@@ -63,9 +122,16 @@ typedef unsigned __int64 UINT64, *PUINT64;
#define SECOND_LOWER_8_BITS 0x000000000000ff00
#define UPPER_48_BITS_AND_LOWER_8_BITS 0xffffffffffff00ff
+#if defined(__linux__) // Linux
+
+# define MAX_PATH 260
+
+#endif
+
//
// DO NOT FUCKING TOUCH THIS STRUCTURE WITHOUT COORDINATION WITH SINA
//
+#pragma pack(push, 1) // Ensure no padding
typedef struct GUEST_REGS
{
//
@@ -94,6 +160,45 @@ typedef struct GUEST_REGS
//
} GUEST_REGS, *PGUEST_REGS;
+#pragma pack(pop)
+
+typedef struct XMM_REG
+{
+ UINT64 XmmLow; // Low 64 bits
+ UINT64 XmmHigh; // High 64 bits
+
+} XMM_REG;
+
+#pragma pack(push, 1) // Ensure no padding
+typedef struct GUEST_XMM_REGS
+{
+ XMM_REG xmm0; // 0x00
+ XMM_REG xmm1; // 0x10
+ XMM_REG xmm2; // 0x20
+ XMM_REG xmm3; // 0x30
+ XMM_REG xmm4; // 0x40
+ XMM_REG xmm5; // 0x50
+
+ //
+ // As per Microsoft ABI documentation, the following registers are nonvolatile
+ // So, MSVC compiler will save them on the stack if they are used in the function
+ // Thus, for the sake of performance, we comment them out
+ //
+ XMM_REG xmm6_not_saved; // 0x60
+ XMM_REG xmm7_not_saved; // 0x70
+ XMM_REG xmm8_not_saved; // 0x80
+ XMM_REG xmm9_not_saved; // 0x90
+ XMM_REG xmm10_not_saved; // 0xA0
+ XMM_REG xmm11_not_saved; // 0xB0
+ XMM_REG xmm12_not_saved; // 0xC0
+ XMM_REG xmm13_not_saved; // 0xD0
+ XMM_REG xmm14_not_saved; // 0xE0
+ XMM_REG xmm15_not_saved; // 0xF0
+
+ UINT32 mxcsr; // 0x100
+
+} GUEST_XMM_REGS, *PGUEST_XMM_REGS;
+#pragma pack(pop)
/**
* @brief struct for extra registers
diff --git a/hyperdbg/include/SDK/headers/Connection.h b/hyperdbg/include/SDK/headers/Connection.h
index 920997de..aac62f47 100644
--- a/hyperdbg/include/SDK/headers/Connection.h
+++ b/hyperdbg/include/SDK/headers/Connection.h
@@ -100,6 +100,9 @@ typedef enum _DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_PERFORM_ACTIONS_ON_APIC,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_QUERY_PCIDEVINFO,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_READ_IDT_ENTRIES,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_PERFORM_SMI_OPERATION,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_PERFORM_HYPERTRACE_LBR_DUMP,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_PERFORM_HYPERTRACE_PT_OPERATION,
//
// Debuggee to debugger
@@ -137,6 +140,9 @@ typedef enum _DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_APIC_REQUESTS,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_PCIDEVINFO,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_QUERY_IDT_ENTRIES_REQUESTS,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_SMI_OPERATION_REQUESTS,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_HYPERTRACE_LBR_DUMP_REQUESTS,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_HYPERTRACE_PT_OPERATION_REQUESTS,
//
// hardware debuggee to debugger
diff --git a/hyperdbg/include/SDK/headers/Constants.h b/hyperdbg/include/SDK/headers/Constants.h
index 15609cc7..dae3aa47 100644
--- a/hyperdbg/include/SDK/headers/Constants.h
+++ b/hyperdbg/include/SDK/headers/Constants.h
@@ -1,6 +1,7 @@
/**
* @file Constants.h
* @author Sina Karvandi (sina@hyperdbg.org)
+ * @author jtaw5649
* @brief HyperDbg's SDK constants
* @details This file contains definitions of constants
* used in HyperDbg
@@ -17,9 +18,11 @@
//////////////////////////////////////////////////
#define VERSION_MAJOR 0
-#define VERSION_MINOR 14
+#define VERSION_MINOR 21
#define VERSION_PATCH 0
+#define BETA_VERSION FALSE
+
//
// Example of __DATE__ string: "Jul 27 2012"
// 01234567890
@@ -76,9 +79,9 @@
#define BUILD_SEC_CH0 (__TIME__[6])
#define BUILD_SEC_CH1 (__TIME__[7])
-#ifdef __cplusplus // becasue it's not valid in C
+#ifdef __cplusplus // because it's not valid in C
-const unsigned char BuildDateTime[] = {
+const UCHAR BuildDateTime[] = {
BUILD_YEAR_CH0,
BUILD_YEAR_CH1,
BUILD_YEAR_CH2,
@@ -106,11 +109,16 @@ const unsigned char BuildDateTime[] = {
# define TOSTRING(x) STRINGIFY(x)
// Complete version as a string
-# define HYPERDBG_COMPLETE_VERSION "v" TOSTRING(VERSION_MAJOR) "." TOSTRING(VERSION_MINOR) "." TOSTRING(VERSION_PATCH) "\0"
-const unsigned char CompleteVersion[] = HYPERDBG_COMPLETE_VERSION;
+# if BETA_VERSION == FALSE
+# define HYPERDBG_COMPLETE_VERSION "v" TOSTRING(VERSION_MAJOR) "." TOSTRING(VERSION_MINOR) "." TOSTRING(VERSION_PATCH) "\0"
+# else
+# define HYPERDBG_COMPLETE_VERSION "v" TOSTRING(VERSION_MAJOR) "." TOSTRING(VERSION_MINOR) "." TOSTRING(VERSION_PATCH) "-beta\0"
+# endif
-const unsigned char BuildVersion[] = {
+const UCHAR CompleteVersion[] = HYPERDBG_COMPLETE_VERSION;
+
+const UCHAR BuildVersion[] = {
BUILD_YEAR_CH0,
BUILD_YEAR_CH1,
BUILD_YEAR_CH2,
@@ -127,7 +135,7 @@ const unsigned char BuildVersion[] = {
'\0'};
-const unsigned char BuildSignature[] = {
+const UCHAR BuildSignature[] = {
TOSTRING(VERSION_MAJOR)[0],
'.',
TOSTRING(VERSION_MINOR)[0],
@@ -369,23 +377,17 @@ const unsigned char BuildSignature[] = {
#define OPERATION_LOG_NON_IMMEDIATE_MESSAGE 4U
#define OPERATION_LOG_WITH_TAG 5U
-#define OPERATION_COMMAND_FROM_DEBUGGER_CLOSE_AND_UNLOAD_VMM \
- 6U | OPERATION_MANDATORY_DEBUGGEE_BIT
-#define OPERATION_DEBUGGEE_USER_INPUT 7U | OPERATION_MANDATORY_DEBUGGEE_BIT
-#define OPERATION_DEBUGGEE_REGISTER_EVENT 8U | OPERATION_MANDATORY_DEBUGGEE_BIT
-#define OPERATION_DEBUGGEE_ADD_ACTION_TO_EVENT \
- 9 | OPERATION_MANDATORY_DEBUGGEE_BIT
-#define OPERATION_DEBUGGEE_CLEAR_EVENTS 10U | OPERATION_MANDATORY_DEBUGGEE_BIT
-#define OPERATION_DEBUGGEE_CLEAR_EVENTS_WITHOUT_NOTIFYING_DEBUGGER 11U | OPERATION_MANDATORY_DEBUGGEE_BIT
-#define OPERATION_HYPERVISOR_DRIVER_IS_SUCCESSFULLY_LOADED \
- 12U | OPERATION_MANDATORY_DEBUGGEE_BIT
-#define OPERATION_HYPERVISOR_DRIVER_END_OF_IRPS \
- 13U | OPERATION_MANDATORY_DEBUGGEE_BIT
-#define OPERATION_COMMAND_FROM_DEBUGGER_RELOAD_SYMBOL \
- 14U | OPERATION_MANDATORY_DEBUGGEE_BIT
-
-#define OPERATION_NOTIFICATION_FROM_USER_DEBUGGER_PAUSE \
- 15U | OPERATION_MANDATORY_DEBUGGEE_BIT
+#define OPERATION_LOG_MESSAGE_MANDATORY 6U | OPERATION_MANDATORY_DEBUGGEE_BIT
+#define OPERATION_COMMAND_FROM_DEBUGGER_CLOSE_AND_UNLOAD_VMM 7U | OPERATION_MANDATORY_DEBUGGEE_BIT
+#define OPERATION_DEBUGGEE_USER_INPUT 8U | OPERATION_MANDATORY_DEBUGGEE_BIT
+#define OPERATION_DEBUGGEE_REGISTER_EVENT 9U | OPERATION_MANDATORY_DEBUGGEE_BIT
+#define OPERATION_DEBUGGEE_ADD_ACTION_TO_EVENT 10U | OPERATION_MANDATORY_DEBUGGEE_BIT
+#define OPERATION_DEBUGGEE_CLEAR_EVENTS 11U | OPERATION_MANDATORY_DEBUGGEE_BIT
+#define OPERATION_DEBUGGEE_CLEAR_EVENTS_WITHOUT_NOTIFYING_DEBUGGER 12U | OPERATION_MANDATORY_DEBUGGEE_BIT
+#define OPERATION_HYPERVISOR_DRIVER_IS_SUCCESSFULLY_LOADED 13U | OPERATION_MANDATORY_DEBUGGEE_BIT
+#define OPERATION_HYPERVISOR_DRIVER_END_OF_IRPS 14U | OPERATION_MANDATORY_DEBUGGEE_BIT
+#define OPERATION_COMMAND_FROM_DEBUGGER_RELOAD_SYMBOL 15U | OPERATION_MANDATORY_DEBUGGEE_BIT
+#define OPERATION_NOTIFICATION_FROM_USER_DEBUGGER_PAUSE 16U | OPERATION_MANDATORY_DEBUGGEE_BIT
//////////////////////////////////////////////////
// Breakpoints & Debug Breakpoints //
@@ -617,34 +619,34 @@ typedef enum _SEGMENT_REGISTERS
/**
* @brief Intel CPU flags in CR0
*/
-#define X86_CR0_PE 0x00000001 /* Enable Protected Mode (RW) */
-#define X86_CR0_MP 0x00000002 /* Monitor Coprocessor (RW) */
-#define X86_CR0_EM 0x00000004 /* Require FPU Emulation (RO) */
-#define X86_CR0_TS 0x00000008 /* Task Switched (RW) */
-#define X86_CR0_ET 0x00000010 /* Extension type (RO) */
-#define X86_CR0_NE 0x00000020 /* Numeric Error Reporting (RW) */
-#define X86_CR0_WP 0x00010000 /* Supervisor Write Protect (RW) */
-#define X86_CR0_AM 0x00040000 /* Alignment Checking (RW) */
-#define X86_CR0_NW 0x20000000 /* Not Write-Through (RW) */
-#define X86_CR0_CD 0x40000000 /* Cache Disable (RW) */
-#define X86_CR0_PG 0x80000000 /* Paging */
+#define REG_CR0_PE 0x00000001 /* Enable Protected Mode (RW) */
+#define REG_CR0_MP 0x00000002 /* Monitor Coprocessor (RW) */
+#define REG_CR0_EM 0x00000004 /* Require FPU Emulation (RO) */
+#define REG_CR0_TS 0x00000008 /* Task Switched (RW) */
+#define REG_CR0_ET 0x00000010 /* Extension type (RO) */
+#define REG_CR0_NE 0x00000020 /* Numeric Error Reporting (RW) */
+#define REG_CR0_WP 0x00010000 /* Supervisor Write Protect (RW) */
+#define REG_CR0_AM 0x00040000 /* Alignment Checking (RW) */
+#define REG_CR0_NW 0x20000000 /* Not Write-Through (RW) */
+#define REG_CR0_CD 0x40000000 /* Cache Disable (RW) */
+#define REG_CR0_PG 0x80000000 /* Paging */
/**
* @brief Intel CPU features in CR4
*
*/
-#define X86_CR4_VME 0x0001 /* enable vm86 extensions */
-#define X86_CR4_PVI 0x0002 /* virtual interrupts flag enable */
-#define X86_CR4_TSD 0x0004 /* disable time stamp at ipl 3 */
-#define X86_CR4_DE 0x0008 /* enable debugging extensions */
-#define X86_CR4_PSE 0x0010 /* enable page size extensions */
-#define X86_CR4_PAE 0x0020 /* enable physical address extensions */
-#define X86_CR4_MCE 0x0040 /* Machine check enable */
-#define X86_CR4_PGE 0x0080 /* enable global pages */
-#define X86_CR4_PCE 0x0100 /* enable performance counters at ipl 3 */
-#define X86_CR4_OSFXSR 0x0200 /* enable fast FPU save and restore */
-#define X86_CR4_OSXMMEXCPT 0x0400 /* enable unmasked SSE exceptions */
-#define X86_CR4_VMXE 0x2000 /* enable VMX */
+#define REG_CR4_VME 0x0001 /* enable vm86 extensions */
+#define REG_CR4_PVI 0x0002 /* virtual interrupts flag enable */
+#define REG_CR4_TSD 0x0004 /* disable time stamp at ipl 3 */
+#define REG_CR4_DE 0x0008 /* enable debugging extensions */
+#define REG_CR4_PSE 0x0010 /* enable page size extensions */
+#define REG_CR4_PAE 0x0020 /* enable physical address extensions */
+#define REG_CR4_MCE 0x0040 /* Machine check enable */
+#define REG_CR4_PGE 0x0080 /* enable global pages */
+#define REG_CR4_PCE 0x0100 /* enable performance counters at ipl 3 */
+#define REG_CR4_OSFXSR 0x0200 /* enable fast FPU save and restore */
+#define REG_CR4_OSXMMEXCPT 0x0400 /* enable unmasked SSE exceptions */
+#define REG_CR4_VMXE 0x2000 /* enable VMX */
/*
* @brief Segment register and corresponding GDT meaning in Windows
@@ -674,6 +676,18 @@ typedef enum _SEGMENT_REGISTERS
#define CPUID_HV_VENDOR_AND_MAX_FUNCTIONS 0x40000000
#define CPUID_HV_INTERFACE 0x40000001
+/**
+ * @brief Transparent-mode feature mask
+ *
+ */
+#define TRANSPARENT_EVADE_MASK_SYSCALL_HOOK 0x00000001
+#define TRANSPARENT_EVADE_MASK_CPUID 0x00000002
+#define TRANSPARENT_EVADE_MASK_MSR 0x00000004
+#define TRANSPARENT_EVADE_MASK_TRAP_FLAG 0x00000008
+#define TRANSPARENT_EVADE_MASK_ALL \
+ (TRANSPARENT_EVADE_MASK_SYSCALL_HOOK | TRANSPARENT_EVADE_MASK_CPUID | TRANSPARENT_EVADE_MASK_MSR | TRANSPARENT_EVADE_MASK_TRAP_FLAG)
+#define TRANSPARENT_EVADE_MASK_DEFAULT TRANSPARENT_EVADE_MASK_ALL
+
/**
* @brief Cpuid to get virtual address width
*
diff --git a/hyperdbg/include/SDK/headers/DataTypes.h b/hyperdbg/include/SDK/headers/DataTypes.h
index 1594e3fb..0c03ca5a 100644
--- a/hyperdbg/include/SDK/headers/DataTypes.h
+++ b/hyperdbg/include/SDK/headers/DataTypes.h
@@ -28,6 +28,39 @@ typedef enum _PAGING_LEVEL
PagingLevelPageMapLevel4
} PAGING_LEVEL;
+//////////////////////////////////////////////////
+// CPU Information //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Different processor vendors
+ *
+ */
+typedef enum _GENERIC_PROCESSOR_VENDOR
+{
+ GENERIC_PROCESSOR_VENDOR_INTEL,
+ GENERIC_PROCESSOR_VENDOR_AMD,
+ GENERIC_PROCESSOR_VENDOR_OTHERS,
+} GENERIC_PROCESSOR_VENDOR;
+
+//////////////////////////////////////////////////
+// List Entries //
+//////////////////////////////////////////////////
+
+//
+// Doubly linked list structure. Can be used as either a list head, or
+// as link words.
+//
+#if defined(__linux__)
+
+typedef struct _LIST_ENTRY
+{
+ struct _LIST_ENTRY * Flink;
+ struct _LIST_ENTRY * Blink;
+} LIST_ENTRY, *PLIST_ENTRY;
+
+#endif // defined(__linux__)
+
//////////////////////////////////////////////////
// Pool Manager //
//////////////////////////////////////////////////
@@ -126,7 +159,7 @@ typedef int (*SendMessageWithParamCallback)(const char * Text);
* as a custom ShowMessages function (using shared buffer)
*
*/
-typedef int (*SendMessageWWithSharedBufferCallback)();
+typedef int (*SendMessageWithSharedBufferCallback)(VOID);
//////////////////////////////////////////////////
// Communications //
@@ -238,7 +271,6 @@ typedef struct _DEBUGGEE_UD_PAUSED_PACKET
VMM_CALLBACK_EVENT_CALLING_STAGE_TYPE EventCallingStage;
BYTE InstructionBytesOnRip[MAXIMUM_INSTR_SIZE];
UINT16 ReadInstructionLen;
- GUEST_REGS GuestRegs;
} DEBUGGEE_UD_PAUSED_PACKET, *PDEBUGGEE_UD_PAUSED_PACKET;
diff --git a/hyperdbg/include/SDK/headers/ErrorCodes.h b/hyperdbg/include/SDK/headers/ErrorCodes.h
index e6d4b09e..bf31a55c 100644
--- a/hyperdbg/include/SDK/headers/ErrorCodes.h
+++ b/hyperdbg/include/SDK/headers/ErrorCodes.h
@@ -107,7 +107,7 @@
0xc000000c
/**
- * @brief error, an invalid address is specified based on anotehr process's cr3
+ * @brief error, an invalid address is specified based on another process's cr3
* in !e* or e* commands
*
*/
@@ -552,7 +552,7 @@
#define DEBUGGER_ERROR_DEBUGGER_ALREADY_UNHIDE 0xc0000054
/**
- * @brief error, the user debugger cannot be initalized
+ * @brief error, the user debugger cannot be initialized
*
*/
#define DEBUGGER_ERROR_DEBUGGER_NOT_INITIALIZED 0xc0000055
@@ -563,6 +563,96 @@
*/
#define DEBUGGER_ERROR_CANNOT_PUT_EPT_HOOKS_ON_PHYSICAL_ADDRESS_ABOVE_512_GB 0xc0000056
+/**
+ * @brief error, invalid parameters for SMI operation request
+ *
+ */
+#define DEBUGGER_ERROR_INVALID_SMI_OPERATION_PARAMETERS 0xc0000057
+
+/**
+ * @brief error, unable to trigger SMI
+ *
+ */
+#define DEBUGGER_ERROR_UNABLE_TO_TRIGGER_SMI 0xc0000058
+
+/**
+ * @brief error, unable to apply the command to the target thread
+ *
+ */
+#define DEBUGGER_ERROR_UNABLE_TO_APPLY_COMMAND_TO_THE_TARGET_THREAD 0xc0000059
+
+/**
+ * @brief error, HyperTrace is not initialized
+ *
+ */
+#define DEBUGGER_ERROR_HYPERTRACE_NOT_INITIALIZED 0xc000005a
+
+/**
+ * @brief error, invalid HyperTrace operation type is specified in the request
+ *
+ */
+#define DEBUGGER_ERROR_INVALID_HYPERTRACE_OPERATION_TYPE 0xc000005b
+
+/**
+ * @brief error, LBR is already enabled
+ *
+ */
+#define DEBUGGER_ERROR_LBR_ALREADY_ENABLED 0xc000005c
+
+/**
+ * @brief error, LBR is already disabled
+ *
+ */
+#define DEBUGGER_ERROR_LBR_ALREADY_DISABLED 0xc000005d
+
+/**
+ * @brief error, LBR is not supported by the processor
+ *
+ */
+#define DEBUGGER_ERROR_LBR_NOT_SUPPORTED 0xc000005e
+
+/**
+ * @brief error, LBR not supported on VMCS
+ *
+ */
+#define DEBUGGER_ERROR_LBR_NOT_SUPPORTED_ON_VMCS 0xc000005f
+
+/**
+ * @brief error, PT is already enabled
+ *
+ */
+#define DEBUGGER_ERROR_PT_ALREADY_ENABLED 0xc0000060
+
+/**
+ * @brief error, PT is already disabled
+ *
+ */
+#define DEBUGGER_ERROR_PT_ALREADY_DISABLED 0xc0000061
+
+/**
+ * @brief error, PT is not supported by the processor
+ *
+ */
+#define DEBUGGER_ERROR_PT_NOT_SUPPORTED 0xc0000062
+
+/**
+ * @brief error, VMM cannot be initialized while HyperTrace module is already loaded
+ *
+ */
+#define DEBUGGER_ERROR_VMM_CANNOT_BE_INITIALIZED_IF_HYPERTRACE_IS_LOADED 0xc0000063
+
+/**
+ * @brief error, VMM cannot be initialized if the debugger is not loaded
+ *
+ */
+#define DEBUGGER_ERROR_VMM_CANNOT_BE_INITIALIZED_IF_DEBUGGER_IS_NOT_LOADED 0xc0000064
+
+/**
+ * @brief error, cannot initialize the debugger
+ *
+ */
+#define DEBUGGER_ERROR_CANNOT_INITIALIZE_DEBUGGER 0xc0000065
+
//
// WHEN YOU ADD ANYTHING TO THIS LIST OF ERRORS, THEN
// MAKE SURE TO ADD AN ERROR MESSAGE TO ShowErrorMessage(UINT32 Error)
diff --git a/hyperdbg/include/SDK/headers/Events.h b/hyperdbg/include/SDK/headers/Events.h
index 5035e9e0..0af4052a 100644
--- a/hyperdbg/include/SDK/headers/Events.h
+++ b/hyperdbg/include/SDK/headers/Events.h
@@ -169,6 +169,11 @@ typedef enum _VMM_EVENT_TYPE_ENUM
TRAP_EXECUTION_MODE_CHANGED,
TRAP_EXECUTION_INSTRUCTION_TRACE,
+ //
+ // XSETBV Instruction Execution Events
+ //
+ XSETBV_INSTRUCTION_EXECUTION
+
} VMM_EVENT_TYPE_ENUM;
/**
@@ -194,8 +199,6 @@ typedef enum _DEBUGGER_EVENT_SYSCALL_SYSRET_TYPE
} DEBUGGER_EVENT_SYSCALL_SYSRET_TYPE;
-#define SIZEOF_DEBUGGER_MODIFY_EVENTS sizeof(DEBUGGER_MODIFY_EVENTS)
-
/**
* @brief Type of mode change traps
*
@@ -248,6 +251,8 @@ typedef struct _DEBUGGER_MODIFY_EVENTS
} DEBUGGER_MODIFY_EVENTS, *PDEBUGGER_MODIFY_EVENTS;
+#define SIZEOF_DEBUGGER_MODIFY_EVENTS sizeof(DEBUGGER_MODIFY_EVENTS)
+
/**
* @brief request for performing a short-circuiting event
*
@@ -335,6 +340,8 @@ typedef enum _PROTECTED_HV_RESOURCES_TYPE
PROTECTED_HV_RESOURCES_MOV_TO_CR3_EXITING,
+ PROTECTED_HV_RESOURCES_SAVE_AND_LOAD_DEBUG_CONTROLS,
+
} PROTECTED_HV_RESOURCES_TYPE;
//////////////////////////////////////////////////
@@ -352,8 +359,6 @@ typedef struct _DEBUGGER_GENERAL_EVENT_DETAIL
CommandsEventList; // Linked-list of commands list (used for tracing purpose
// in user mode)
- time_t CreationTime; // Date of creating this event
-
UINT32 CoreId; // determines the core index to apply this event to, if it's
// 0xffffffff means that we have to apply it to all cores
@@ -396,6 +401,8 @@ typedef struct _DEBUGGER_GENERAL_EVENT_DETAIL
} DEBUGGER_GENERAL_EVENT_DETAIL, *PDEBUGGER_GENERAL_EVENT_DETAIL;
+#define SIZEOF_DEBUGGER_GENERAL_EVENT_DETAIL sizeof(DEBUGGER_GENERAL_EVENT_DETAIL)
+
/**
* @brief Each event can have multiple actions
* @details THIS STRUCTURE IS ONLY USED IN USER MODE
@@ -415,6 +422,8 @@ typedef struct _DEBUGGER_GENERAL_ACTION
} DEBUGGER_GENERAL_ACTION, *PDEBUGGER_GENERAL_ACTION;
+#define SIZEOF_DEBUGGER_GENERAL_ACTION sizeof(DEBUGGER_GENERAL_ACTION)
+
/**
* @brief Status of register buffers
*
diff --git a/hyperdbg/include/SDK/headers/HardwareDebugger.h b/hyperdbg/include/SDK/headers/HardwareDebugger.h
index 814659b6..d80122e3 100644
--- a/hyperdbg/include/SDK/headers/HardwareDebugger.h
+++ b/hyperdbg/include/SDK/headers/HardwareDebugger.h
@@ -30,7 +30,7 @@
/**
* @brief Initial default buffer size (BRAN Size)
- * @details Number of 4-Byte intergers (256 * 4 Byte * 8 bits = 8-kilobits)
+ * @details Number of 4-Byte integers (256 * 4 Byte * 8 bits = 8-kilobits)
*
*/
#define DEFAULT_INITIAL_BRAM_BUFFER_SIZE 256
diff --git a/hyperdbg/include/SDK/headers/Ioctls.h b/hyperdbg/include/SDK/headers/Ioctls.h
index 37cb6139..20a2057a 100644
--- a/hyperdbg/include/SDK/headers/Ioctls.h
+++ b/hyperdbg/include/SDK/headers/Ioctls.h
@@ -53,114 +53,172 @@
#endif // !FILE_DEVICE_UNKNOWN
+/**
+ * @brief Extract the function from an IOCTL code
+ *
+ */
+#define CTL_CODE_FUNCTION(Code) (((Code) >> 2) & 0xFFF)
+
+/**
+ * @brief Base code for IOCTLs
+ *
+ */
+#define IOCTL_START_CODE 0x800
+
+/**
+ * @brief ioctl, for basic communication between user-mode and kernel-mode, and for loading and initializing the driver and its components
+ *
+ */
+#define IOCTL_BASIC_IOCTL IOCTL_START_CODE + 0x00
+
+/**
+ * @brief ioctl, for KD (Kernel Debugger) related functionalities
+ *
+ */
+#define IOCTL_KD_IOCTL IOCTL_START_CODE + 0x100
+
+/**
+ * @brief ioctl, for VMM and debugger related functionalities
+ *
+ */
+#define IOCTL_VMM_IOCTL IOCTL_START_CODE + 0x200
+
+/**
+ * @brief ioctl, for HyperTrace related functionalities
+ *
+ */
+#define IOCTL_HYPERTRACE_IOCTL IOCTL_START_CODE + 0x300
+
//////////////////////////////////////////////////
-// IOCTLs //
+// Basic IOCTLs //
//////////////////////////////////////////////////
+/**
+ * @brief ioctl, initialize the VMM module
+ *
+ */
+#define IOCTL_INIT_VMM \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_BASIC_IOCTL + 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+/**
+ * @brief ioctl, initialize the HyperTrace module
+ *
+ */
+#define IOCTL_INIT_HYPERTRACE \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_BASIC_IOCTL + 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
/**
* @brief ioctl, register a new event
*
*/
#define IOCTL_REGISTER_EVENT \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_BASIC_IOCTL + 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, irp pending mechanism for reading from message tracing buffers
*
*/
#define IOCTL_RETURN_IRP_PENDING_PACKETS_AND_DISALLOW_IOCTL \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_BASIC_IOCTL + 0x04, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+//////////////////////////////////////////////////
+// KD IOCTLs //
+//////////////////////////////////////////////////
+
+//////////////////////////////////////////////////
+// VMM IOCTLs //
+//////////////////////////////////////////////////
/**
* @brief ioctl, to terminate vmx and exit form debugger
*
*/
#define IOCTL_TERMINATE_VMX \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, request to read memory
*
*/
#define IOCTL_DEBUGGER_READ_MEMORY \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, request to read or write on a special MSR
*
*/
#define IOCTL_DEBUGGER_READ_OR_WRITE_MSR \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, request to read page table entries
*
*/
#define IOCTL_DEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x04, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, register an event
*
*/
#define IOCTL_DEBUGGER_REGISTER_EVENT \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x05, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, add action to event
*
*/
#define IOCTL_DEBUGGER_ADD_ACTION_TO_EVENT \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x06, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, request to enable or disable transparent-mode
*
*/
#define IOCTL_DEBUGGER_HIDE_AND_UNHIDE_TO_TRANSPARENT_THE_DEBUGGER \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x808, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x07, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, for !va2pa and !pa2va commands
*
*/
#define IOCTL_DEBUGGER_VA2PA_AND_PA2VA_COMMANDS \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x809, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x08, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, request to edit virtual and physical memory
*
*/
#define IOCTL_DEBUGGER_EDIT_MEMORY \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80a, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x09, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, request to search virtual and physical memory
*
*/
#define IOCTL_DEBUGGER_SEARCH_MEMORY \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80b, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x0a, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, request to modify an event (enable/disable/clear)
*
*/
#define IOCTL_DEBUGGER_MODIFY_EVENTS \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80c, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x0b, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, flush the kernel buffers
*
*/
#define IOCTL_DEBUGGER_FLUSH_LOGGING_BUFFERS \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80d, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x0c, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, attach or detach user-mode processes
*
*/
#define IOCTL_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80e, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x0d, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, print states (Deprecated)
@@ -168,158 +226,205 @@
*
*/
#define IOCTL_DEBUGGER_PRINT \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80f, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x0e, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, prepare debuggee
*
*/
#define IOCTL_PREPARE_DEBUGGEE \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x810, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x0f, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, pause and halt the system
*
*/
#define IOCTL_PAUSE_PACKET_RECEIVED \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x811, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x10, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, send a signal that execution of command finished
*
*/
#define IOCTL_SEND_SIGNAL_EXECUTION_IN_DEBUGGEE_FINISHED \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x812, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x11, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, send user-mode messages to the debugger
*
*/
#define IOCTL_SEND_USERMODE_MESSAGES_TO_DEBUGGER \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x813, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x12, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, send general buffer from debuggee to debugger
*
*/
#define IOCTL_SEND_GENERAL_BUFFER_FROM_DEBUGGEE_TO_DEBUGGER \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x814, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x13, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, to perform kernel-side tests
*
*/
-#define IOCTL_PERFROM_KERNEL_SIDE_TESTS \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x815, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_PERFORM_KERNEL_SIDE_TESTS \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x14, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, to reserve pre-allocated pools
*
*/
#define IOCTL_RESERVE_PRE_ALLOCATED_POOLS \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x816, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x15, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, to send user debugger commands
*
*/
#define IOCTL_SEND_USER_DEBUGGER_COMMANDS \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x817, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x16, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, to get active threads/processes that are debugging
*
*/
#define IOCTL_GET_DETAIL_OF_ACTIVE_THREADS_AND_PROCESSES \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x818, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x17, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, to get user mode modules details
*
*/
#define IOCTL_GET_USER_MODE_MODULE_DETAILS \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x819, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x18, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, query count of active threads or processes
*
*/
#define IOCTL_QUERY_COUNT_OF_ACTIVE_PROCESSES_OR_THREADS \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x81a, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x19, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, to get list threads/processes
*
*/
#define IOCTL_GET_LIST_OF_THREADS_AND_PROCESSES \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x81b, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x1a, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, query the current process details
*
*/
#define IOCTL_QUERY_CURRENT_PROCESS \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x81c, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x1b, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, query the current thread details
*
*/
#define IOCTL_QUERY_CURRENT_THREAD \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x81d, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x1c, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, request service from the reversing machine
*
*/
#define IOCTL_REQUEST_REV_MACHINE_SERVICE \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x81e, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x1d, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, request to bring pages in
*
*/
#define IOCTL_DEBUGGER_BRING_PAGES_IN \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x81f, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x1e, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, to preactivate a functionality
*
*/
#define IOCTL_PREACTIVATE_FUNCTIONALITY \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x820, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x1f, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, to enumerate PCIe endpoints
*
*/
#define IOCTL_PCIE_ENDPOINT_ENUM \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x821, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x20, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, to perform actions related to APIC
*
*/
-#define IOCTL_PERFROM_ACTIONS_ON_APIC \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x822, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_PERFORM_ACTIONS_ON_APIC \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x21, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, to query for PCI endpoint info
*
*/
#define IOCTL_PCIDEVINFO_ENUM \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x823, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x22, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, to query the IDT entries
*
*/
#define IOCTL_QUERY_IDT_ENTRY \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x824, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x24, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, to set breakpoint for the user debugger
*
*/
#define IOCTL_SET_BREAKPOINT_USER_DEBUGGER \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x825, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x25, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+/**
+ * @brief ioctl, to perform SMI operations
+ *
+ */
+#define IOCTL_PERFORM_SMI_OPERATION \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x26, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+//////////////////////////////////////////////////
+// HyperTrace IOCTLs //
+//////////////////////////////////////////////////
+
+/**
+ * @brief ioctl, to unload HyperTrace module
+ *
+ */
+#define IOCTL_PERFORM_HYPERTRACE_UNLOAD \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_HYPERTRACE_IOCTL + 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+/**
+ * @brief ioctl, to perform HyperTrace LBR operations
+ *
+ */
+#define IOCTL_PERFORM_HYPERTRACE_LBR_OPERATION \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_HYPERTRACE_IOCTL + 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+/**
+ * @brief ioctl, to perform HyperTrace LBR dump
+ *
+ */
+#define IOCTL_PERFORM_HYPERTRACE_LBR_DUMP \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_HYPERTRACE_IOCTL + 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+/**
+ * @brief ioctl, to perform HyperTrace PT operations
+ *
+ */
+#define IOCTL_PERFORM_HYPERTRACE_PT_OPERATION \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_HYPERTRACE_IOCTL + 0x04, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+/**
+ * @brief ioctl, to map per-CPU HyperTrace PT output buffers into the
+ * calling user-mode process. See HYPERTRACE_PT_MMAP_PACKETS.
+ *
+ */
+#define IOCTL_PERFORM_HYPERTRACE_PT_MMAP \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_HYPERTRACE_IOCTL + 0x05, METHOD_BUFFERED, FILE_ANY_ACCESS)
diff --git a/hyperdbg/include/SDK/headers/LbrDefinitions.h b/hyperdbg/include/SDK/headers/LbrDefinitions.h
new file mode 100644
index 00000000..49e634d3
--- /dev/null
+++ b/hyperdbg/include/SDK/headers/LbrDefinitions.h
@@ -0,0 +1,171 @@
+/**
+ * @file LbrDefinitions.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Last Branch Record (LBR) related data structures
+ * @details
+ * @version 0.19
+ * @date 2026-04-27
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Constants //
+//////////////////////////////////////////////////
+
+/**
+ * @brief MSR address of LBR_SELECT, which is used to configure the LBR filtering options
+ */
+#define MSR_LEGACY_LBR_SELECT 0x000001C8
+
+/**
+ * @brief Maximum LBR capacity that is supported by processors
+ *
+ */
+#define MAXIMUM_LBR_CAPACITY 0x20 // 32 entries, which is the maximum supported by modern Intel CPUs
+
+/*
+ * Intel LBR_SELECT bits
+ *
+ * Hardware branch filter (not available on all CPUs)
+ */
+#define LBR_KERNEL_BIT 0 /* do not capture at ring0 */
+#define LBR_USER_BIT 1 /* do not capture at ring > 0 */
+#define LBR_JCC_BIT 2 /* do not capture conditional branches */
+#define LBR_REL_CALL_BIT 3 /* do not capture relative calls */
+#define LBR_IND_CALL_BIT 4 /* do not capture indirect calls */
+#define LBR_RETURN_BIT 5 /* do not capture near returns */
+#define LBR_IND_JMP_BIT 6 /* do not capture indirect jumps */
+#define LBR_REL_JMP_BIT 7 /* do not capture relative jumps */
+#define LBR_FAR_BIT 8 /* do not capture far branches */
+#define LBR_CALL_STACK_BIT 9 /* enable call stack: not available on all CPUs */
+
+/*
+ * We mask it out before writing it to
+ * the actual MSR. But it helps the constraint code to understand
+ * that this is a separate configuration.
+ */
+#define LBR_KERNEL (1 << LBR_KERNEL_BIT)
+#define LBR_USER (1 << LBR_USER_BIT)
+#define LBR_JCC (1 << LBR_JCC_BIT)
+#define LBR_REL_CALL (1 << LBR_REL_CALL_BIT)
+#define LBR_IND_CALL (1 << LBR_IND_CALL_BIT)
+#define LBR_RETURN (1 << LBR_RETURN_BIT)
+#define LBR_IND_JMP (1 << LBR_IND_JMP_BIT)
+#define LBR_REL_JMP (1 << LBR_REL_JMP_BIT)
+#define LBR_FAR_OTHER_BRANCHES (1 << LBR_FAR_BIT) // It is used for OTHER BRANCHES in ARCH LBR
+#define LBR_CALL_STACK (1 << LBR_CALL_STACK_BIT)
+
+/**
+ * @brief For call-stack mode, only CALLs and RETs should be captured
+ * Capturing other branch types may lead to undefined behavior
+ */
+#define LBR_CALL_STACK_BASE_FLAGS (LBR_CALL_STACK | (LBR_JCC | LBR_IND_JMP | LBR_REL_JMP | LBR_FAR_OTHER_BRANCHES))
+
+/**
+ * @brief Branch Type Encodings (Only on Architectural LBR, not available in Legacy LBR)
+ */
+#define LBR_BR_TYPE_COND 0x0
+#define LBR_BR_TYPE_JMP_INDIRECT 0x1
+#define LBR_BR_TYPE_JMP_DIRECT 0x2
+#define LBR_BR_TYPE_CALL_INDIRECT 0x3
+#define LBR_BR_TYPE_CALL_DIRECT 0x4
+#define LBR_BR_TYPE_RET 0x5
+#define LBR_BR_TYPE_RESERVED_MIN 0x6 /* 011xb */
+#define LBR_BR_TYPE_RESERVED_MAX 0x7 /* 011xb */
+#define LBR_BR_TYPE_OTHER_MIN 0x8 /* 1xxxb */
+#define LBR_BR_TYPE_OTHER_MAX 0xF /* 1xxxb */
+
+#define LBR_BR_TYPE_NAME_MAX_LEN 16 /* longest string is "CALL Indirect\0" = 14 chars, rounded up */
+
+//////////////////////////////////////////////////
+// MSR Structures //
+//////////////////////////////////////////////////
+/**
+ * MSR_LBR_INFO_x - Last Branch Record Info Register
+ * Register Address: 1200H-121FH, 4608-4639
+ */
+typedef union
+{
+ struct
+ {
+ /** Bits 15:0 - Elapsed core clocks since last update to the LBR stack (saturating) */
+ UINT64 CycleCount : 16;
+
+ /** Bits 55:16 - Undefined. May be zero or non-zero.
+ * Writes of non-zero values do not fault, but reads may return a different value. */
+ UINT64 Reserved : 40;
+
+ /**
+ * Bits 59:56 - Branch type recorded by this LBR entry.
+ * Encodings:
+ * 0000b = COND
+ * 0001b = JMP Indirect
+ * 0010b = JMP Direct
+ * 0011b = CALL Indirect
+ * 0100b = CALL Direct
+ * 0101b = RET
+ * 011xb = Reserved
+ * 1xxxb = Other Branch
+ */
+ UINT64 BrType_OnlyArchLbr : 4;
+
+ /** Bit 60 - When set, the CycleCount field contains a valid elapsed cycle count */
+ UINT64 CycCntValid_OnlyArchLbr : 1;
+
+ /**
+ * Bit 61 - TSX Abort indicator.
+ * When set:
+ * LBR_FROM = EIP at the time of the TSX Abort
+ * LBR_TO = EIP of the start of HLE region OR EIP of the RTM Abort Handler
+ * Undefined on processors that do not support Intel TSX
+ * (CPUID.07H.00H:EBX.HLE[4] = 0 and CPUID.07H.00H:EBX.RTM[11] = 0).
+ */
+ UINT64 TsxAbort : 1;
+
+ /**
+ * Bit 62 - When set, indicates the branch retired during a TSX transaction.
+ * Undefined on processors that do not support Intel TSX
+ * (CPUID.07H.00H:EBX.HLE[4] = 0 and CPUID.07H.00H:EBX.RTM[11] = 0).
+ */
+ UINT64 InTsx : 1;
+
+ /**
+ * Bit 63 - Branch misprediction flag.
+ * When set, the target of the branch was mispredicted and/or the
+ * direction (taken/non-taken) was mispredicted.
+ * When clear, the branch target/direction was correctly predicted.
+ */
+ UINT64 Mispred : 1;
+ };
+ UINT64 AsUInt;
+} MSR_LBR_INFO, *PMSR_LBR_INFO;
+
+//////////////////////////////////////////////////
+// Structures //
+//////////////////////////////////////////////////
+
+/**
+ * @brief The structure to hold a single LBR entry (from and to addresses)
+ *
+ */
+typedef struct _LBR_BRANCH_ENTRY
+{
+ ULONGLONG From;
+ ULONGLONG To;
+
+} LBR_BRANCH_ENTRY, PLBR_BRANCH_ENTRY;
+
+/**
+ * @brief The structure to hold the LBR stack for a single processor core, including the branch entries and the TOS index
+ *
+ */
+typedef struct _LBR_STACK_ENTRY
+{
+ LBR_BRANCH_ENTRY BranchEntry[MAXIMUM_LBR_CAPACITY];
+ MSR_LBR_INFO LastBranchInfo[MAXIMUM_LBR_CAPACITY];
+ UINT8 Tos;
+
+} LBR_STACK_ENTRY, PLBR_STACK_ENTRY;
diff --git a/hyperdbg/include/SDK/headers/PtDefinitions.h b/hyperdbg/include/SDK/headers/PtDefinitions.h
new file mode 100644
index 00000000..cb827378
--- /dev/null
+++ b/hyperdbg/include/SDK/headers/PtDefinitions.h
@@ -0,0 +1,369 @@
+/**
+ * @file PtDefinitions.h
+ * @author Masoud Rahimi Jafari (Masoodrahimy1379@gmail.com)
+ * @brief Intel Processor Trace (PT) related data structures and hardware
+ * definitions shared between the kernel and user-mode components.
+ * @details
+ * @version 0.19
+ * @date 2026-04-29
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// MSR Addresses //
+// (Intel SDM Vol. 3, Chapter 32) //
+//////////////////////////////////////////////////
+
+#define MSR_IA32_RTIT_OUTPUT_BASE 0x00000560
+#define MSR_IA32_RTIT_OUTPUT_MASK_PTRS 0x00000561
+#define MSR_IA32_RTIT_CTL 0x00000570
+#define MSR_IA32_RTIT_STATUS 0x00000571
+#define MSR_IA32_RTIT_CR3_MATCH 0x00000572
+
+#define MSR_IA32_RTIT_ADDR0_A 0x00000580
+#define MSR_IA32_RTIT_ADDR0_B 0x00000581
+#define MSR_IA32_RTIT_ADDR1_A 0x00000582
+#define MSR_IA32_RTIT_ADDR1_B 0x00000583
+#define MSR_IA32_RTIT_ADDR2_A 0x00000584
+#define MSR_IA32_RTIT_ADDR2_B 0x00000585
+#define MSR_IA32_RTIT_ADDR3_A 0x00000586
+#define MSR_IA32_RTIT_ADDR3_B 0x00000587
+
+//
+// Used in PMI acknowledgment
+//
+#define MSR_IA32_PERF_GLOBAL_STATUS 0x0000038E
+#define MSR_IA32_PERF_GLOBAL_OVF_CTRL 0x00000390
+
+//
+// Bit 55 of IA32_PERF_GLOBAL_STATUS: ToPA PMI pending
+//
+#define PERF_GLOBAL_STATUS_TOPA_PMI (1ULL << 55)
+
+//////////////////////////////////////////////////
+// Constants //
+//////////////////////////////////////////////////
+
+#define PT_PAGE_SIZE 0x1000ULL /* 4 KB */
+#define PT_OVERFLOW_SIZE PT_PAGE_SIZE /* 4 KB overflow landing zone */
+#define PT_MAX_ADDR_RANGES 4
+
+//
+// Maximum CPUs that the PT user-mode mmap surface can describe in a
+// single request. Sized to fit one HYPERTRACE_PT_MMAP_PACKETS within a
+// typical IOCTL buffer and to cover realistic host topologies.
+//
+#define PT_MAX_CPUS_FOR_MMAP 64
+
+//
+// ToPA entry Size field encoding: value N = 4KB * 2^N
+//
+#define PT_TOPA_SIZE_4K 0
+#define PT_TOPA_SIZE_8K 1
+#define PT_TOPA_SIZE_16K 2
+#define PT_TOPA_SIZE_32K 3
+#define PT_TOPA_SIZE_64K 4
+#define PT_TOPA_SIZE_128K 5
+#define PT_TOPA_SIZE_256K 6
+#define PT_TOPA_SIZE_512K 7
+#define PT_TOPA_SIZE_1M 8
+#define PT_TOPA_SIZE_2M 9
+#define PT_TOPA_SIZE_4M 10
+#define PT_TOPA_SIZE_8M 11
+#define PT_TOPA_SIZE_16M 12
+#define PT_TOPA_SIZE_32M 13
+#define PT_TOPA_SIZE_64M 14
+#define PT_TOPA_SIZE_128M 15
+
+//////////////////////////////////////////////////
+// MSR Structures //
+//////////////////////////////////////////////////
+
+/**
+ * @brief IA32_RTIT_CTL — PT master control register
+ * @details Intel SDM Vol. 3, Section 32.2.7.2
+ */
+typedef union _PT_RTIT_CTL_REGISTER
+{
+ struct
+ {
+ UINT64 TraceEn : 1; /* [0] Enable tracing */
+ UINT64 CycEn : 1; /* [1] CYC packets */
+ UINT64 Os : 1; /* [2] Trace CPL 0 */
+ UINT64 User : 1; /* [3] Trace CPL > 0 */
+ UINT64 PwrEvtEn : 1; /* [4] Power event trace */
+ UINT64 FupOnPtw : 1; /* [5] FUP on PTWRITE */
+ UINT64 FabricEn : 1; /* [6] Trace to fabric (must be 0) */
+ UINT64 Cr3Filter : 1; /* [7] Filter by CR3 */
+ UINT64 ToPA : 1; /* [8] Use ToPA output scheme */
+ UINT64 MtcEn : 1; /* [9] MTC packets */
+ UINT64 TscEn : 1; /* [10] TSC packets */
+ UINT64 DisRetc : 1; /* [11] Disable RET compression */
+ UINT64 PtwEn : 1; /* [12] PTWRITE packets */
+ UINT64 BranchEn : 1; /* [13] Branch trace (TNT, TIP, FUP) */
+ UINT64 MtcFreq : 4; /* [14:17] MTC frequency */
+ UINT64 Reserved0 : 1; /* [18] Must be 0 */
+ UINT64 CycThresh : 4; /* [19:22] CYC threshold */
+ UINT64 Reserved1 : 1; /* [23] Must be 0 */
+ UINT64 PsbFreq : 4; /* [24:27] PSB frequency */
+ UINT64 Reserved2 : 4; /* [28:31] Must be 0 */
+ UINT64 Addr0Cfg : 4; /* [32:35] Range 0 mode (1=filter / 2=stop) */
+ UINT64 Addr1Cfg : 4; /* [36:39] Range 1 mode */
+ UINT64 Addr2Cfg : 4; /* [40:43] Range 2 mode */
+ UINT64 Addr3Cfg : 4; /* [44:47] Range 3 mode */
+ UINT64 Reserved3 : 16; /* [48:63] Must be 0 */
+ };
+ UINT64 Value;
+} PT_RTIT_CTL_REGISTER, *PPT_RTIT_CTL_REGISTER;
+
+/**
+ * @brief IA32_RTIT_STATUS — PT status / error register
+ * @details Intel SDM Vol. 3, Section 32.2.7.4
+ */
+typedef union _PT_RTIT_STATUS_REGISTER
+{
+ struct
+ {
+ UINT64 FilterEn : 1; /* [0] RO: IP filter allowing trace */
+ UINT64 ContextEn : 1; /* [1] RO: Context (CR3) allowing trace */
+ UINT64 TriggerEn : 1; /* [2] RO: Trigger conditions met */
+ UINT64 Reserved0 : 1; /* [3] Must be 0 */
+ UINT64 Error : 1; /* [4] RO/Sticky: Operational error */
+ UINT64 Stopped : 1; /* [5] RO: TraceStop hit */
+ UINT64 PendTopaPmi : 1; /* [6] RW: ToPA PMI pending — clear this */
+ UINT64 PendPsbPmi : 1; /* [7] RW: PSB+ PMI pending — clear this */
+ UINT64 Reserved1 : 24; /* [8:31] Must be 0 */
+ UINT64 PacketByteCnt : 17; /* [32:48] Bytes since last PSB */
+ UINT64 Reserved2 : 15; /* [49:63] Must be 0 */
+ };
+ UINT64 Value;
+} PT_RTIT_STATUS_REGISTER, *PPT_RTIT_STATUS_REGISTER;
+
+/**
+ * @brief IA32_RTIT_OUTPUT_MASK_PTRS — Output position tracker
+ * @details Intel SDM Vol. 3, Section 32.2.7.8
+ */
+typedef union _PT_OUTPUT_MASK_PTRS_REGISTER
+{
+ struct
+ {
+ UINT64 LowerMask : 7; /* [0:6] Forced to 0x7F */
+ UINT64 MaskOrTableOffset : 25; /* [7:31] ToPA: table entry index */
+ UINT64 OutputOffset : 32; /* [32:63] Byte offset in current entry */
+ };
+ UINT64 Value;
+} PT_OUTPUT_MASK_PTRS_REGISTER, *PPT_OUTPUT_MASK_PTRS_REGISTER;
+
+/**
+ * @brief ToPA Table Entry
+ * @details Intel SDM Vol. 3, Section 32.2.7.2 (Table of Physical Addresses)
+ */
+typedef union _PT_TOPA_ENTRY
+{
+ struct
+ {
+ UINT64 End : 1; /* [0] Last entry — wraps to next table */
+ UINT64 Reserved0 : 1; /* [1] Must be 0 */
+ UINT64 Int : 1; /* [2] Generate PMI when region fills */
+ UINT64 Reserved1 : 1; /* [3] Must be 0 */
+ UINT64 Stop : 1; /* [4] Stop tracing when region fills */
+ UINT64 Reserved2 : 1; /* [5] Must be 0 */
+ UINT64 Size : 4; /* [6:9] Region size (4K*2^N) */
+ UINT64 Reserved3 : 2; /* [10:11] Must be 0 */
+ UINT64 BaseAddr : 36; /* [12:47] Physical address >> 12 */
+ UINT64 Reserved4 : 16; /* [48:63] Must be 0 */
+ };
+ UINT64 Value;
+} PT_TOPA_ENTRY, *PPT_TOPA_ENTRY;
+
+//////////////////////////////////////////////////
+// Capability / Config //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Discovered Intel PT capabilities (populated from CPUID leaf 0x14).
+ */
+typedef struct _PT_CAPABILITIES
+{
+ UINT32 Cr3Filtering : 1; /* Can filter by process CR3 */
+ UINT32 PsbCycConfigurable : 1; /* PSBFreq and CYC configurable */
+ UINT32 IpFiltering : 1; /* IP filtering and TraceStop supported */
+ UINT32 MtcSupport : 1; /* MTC packets supported */
+ UINT32 PtwriteSupport : 1; /* PTWRITE instruction supported */
+ UINT32 PowerEventTrace : 1; /* Power event trace supported */
+ UINT32 VmxSupport : 1; /* PT works in VMX operations */
+ UINT32 TopaOutput : 1; /* ToPA output scheme supported */
+ UINT32 TopaMultiEntry : 1; /* ToPA tables can have >1 entry */
+ UINT32 SingleRangeOutput : 1; /* Single contiguous range output */
+ UINT32 TransportOutput : 1; /* Trace transport subsystem output */
+ UINT32 IpPayloadsAreLip : 1; /* IP payloads are LIP (not RIP) */
+ UINT32 Reserved : 20;
+
+ UINT32 NumAddrRanges; /* Number of ADDRn_CFG pairs (0-4) */
+ UINT16 MtcPeriodBitmap; /* Supported MTC period values */
+ UINT16 CycThresholdBitmap; /* Supported CYC threshold values */
+ UINT16 PsbFreqBitmap; /* Supported PSB frequency values */
+
+} PT_CAPABILITIES, *PPT_CAPABILITIES;
+
+/**
+ * @brief Intel PT trace state machine.
+ */
+typedef enum _PT_STATE
+{
+ PT_STATE_DISABLED = 0, /* No buffers allocated, PT off */
+ PT_STATE_READY, /* Buffers allocated, MSRs not yet programmed */
+ PT_STATE_TRACING, /* TraceEn=1, actively generating packets */
+ PT_STATE_PAUSED, /* TraceEn=0 temporarily (PMI or user pause) */
+ PT_STATE_STOPPED, /* Tracing done, buffer has valid data */
+ PT_STATE_ERROR /* Hardware error (check IA32_RTIT_STATUS) */
+} PT_STATE;
+
+/**
+ * @brief Intel PT IP filter range.
+ */
+typedef struct _PT_ADDR_RANGE
+{
+ UINT64 Start; /* Start virtual address — written to ADDRn_A */
+ UINT64 End; /* End virtual address — written to ADDRn_B */
+ BOOLEAN IsStopRange; /* FALSE = filter (only trace inside range)
+ TRUE = trace-stop (stop when entering range) */
+} PT_ADDR_RANGE, *PPT_ADDR_RANGE;
+
+/**
+ * @brief Intel PT trace configuration — what the user specifies.
+ */
+typedef struct _PT_TRACE_CONFIG
+{
+ //
+ // What to trace
+ //
+ BOOLEAN TraceUser; /* Trace CPL 3 (user mode) */
+ BOOLEAN TraceKernel; /* Trace CPL 0 (kernel mode) */
+ UINT64 TargetCr3; /* Process to trace (0 = trace all) */
+
+ //
+ // IP filtering
+ //
+ UINT32 NumAddrRanges; /* 0-4 active ranges */
+ PT_ADDR_RANGE AddrRanges[PT_MAX_ADDR_RANGES];
+
+ //
+ // Packet options
+ //
+ BOOLEAN EnableBranch; /* BranchEn — must be TRUE for useful traces */
+ BOOLEAN EnableTsc; /* TscEn — timestamps at PSB boundaries */
+ BOOLEAN EnableMtc; /* MtcEn — wall-clock timing packets */
+ BOOLEAN EnableCyc; /* CycEn — cycle-accurate packets */
+ BOOLEAN EnableRetCompression; /* TRUE keeps RET compression */
+ UINT8 MtcFreq; /* 0-15: MTC period (must be in capabilities) */
+ UINT8 CycThresh; /* 0-15: CYC threshold */
+ UINT8 PsbFreq; /* 0-15: PSB frequency (0 = every 2KB) */
+
+ //
+ // Buffer size
+ //
+ UINT64 BufferSize; /* Main output buffer size in bytes
+ Must be 4KB * 2^N (4KB, 8KB, ..., 128MB)
+ Default: PT_DEFAULT_BUFFER_SIZE (2MB) */
+} PT_TRACE_CONFIG, *PPT_TRACE_CONFIG;
+
+//////////////////////////////////////////////////
+// Per-CPU Trace State //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Per-CPU PT buffer layout
+ *
+ * ToPA Table (one 4KB page, 3 entries used):
+ * Entry[0] — Main data buffer (BufferSize), INT=1
+ * Entry[1] — Overflow zone (4KB), INT=0
+ * Entry[2] — END, points back to ToPA table (circular)
+ */
+typedef struct _PT_BUFFER
+{
+ //
+ // ToPA table
+ //
+ PT_TOPA_ENTRY * TopaVa; /* Virtual addr of the ToPA table */
+ UINT64 TopaPhysical; /* Physical addr — IA32_RTIT_OUTPUT_BASE */
+
+ //
+ // Main output buffer
+ //
+ PVOID OutputVa; /* Virtual addr — read trace data from here */
+ UINT64 OutputPhysical; /* Physical addr — goes into ToPA entry[0] */
+ UINT64 OutputSize; /* Bytes (e.g., 0x200000 for 2MB) */
+
+ //
+ // Overflow landing zone (4KB)
+ //
+ PVOID OverflowVa; /* Virtual addr of overflow page */
+ UINT64 OverflowPhysical; /* Physical addr — ToPA entry[1] */
+
+} PT_BUFFER, *PPT_BUFFER;
+
+/**
+ * @brief Per-CPU Intel PT state — one of these per logical processor.
+ */
+typedef struct _PT_PER_CPU
+{
+ PT_BUFFER Buffer; /* ToPA + output buffers */
+ PT_RTIT_CTL_REGISTER SavedCtl; /* Last written IA32_RTIT_CTL */
+ PT_TRACE_CONFIG Config; /* Current trace configuration */
+ PT_STATE State; /* Current state machine position */
+ UINT64 TotalBytesCaptured; /* Accumulated across PMI events */
+
+} PT_PER_CPU, *PPT_PER_CPU;
+
+//////////////////////////////////////////////////
+// Trace Output Descriptor //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Trace output descriptor
+ *
+ * Passed to the engine to receive trace data. WriteOffset serves dual purpose:
+ * - Input: where in Buffer to start writing new data.
+ * - Output: updated to Buffer[0..WriteOffset) = valid data after the call.
+ *
+ * If the remaining space (Length - WriteOffset) is smaller than the new data,
+ * the copy is skipped and WriteOffset is not updated.
+ * Pass NULL instead of a PT_OUTPUT_BUFFER * to skip copying entirely.
+ */
+typedef struct _PT_OUTPUT_BUFFER
+{
+ PVOID Buffer; /* Destination buffer for trace data */
+ UINT64 Length; /* Total size of Buffer in bytes */
+ UINT64 WriteOffset; /* Next write position; valid data is [0..WriteOffset) */
+
+} PT_OUTPUT_BUFFER, *PPT_OUTPUT_BUFFER;
+
+//////////////////////////////////////////////////
+// User-mode mmap descriptor //
+//////////////////////////////////////////////////
+
+/**
+ * @brief One per-CPU descriptor returned by the PT mmap surface.
+ *
+ * The main output buffer and the 4 KB overflow page are stitched
+ * into a single virtually contiguous region in the calling user
+ * process — main first, then overflow, matching the order PT
+ * writes them on a ToPA PMI. Consumers read the whole stream
+ * as Size bytes starting at UserVa.
+ *
+ * UserVa is valid only in the address space of the process that
+ * issued the mmap IOCTL, and only until PT is disabled / flushed
+ * (at which point the underlying kernel buffers are torn down).
+ */
+typedef struct _PT_USER_BUFFER_DESC
+{
+ UINT32 CpuId;
+ UINT32 Reserved;
+ UINT64 UserVa; /* base of the combined main + overflow mapping */
+ UINT64 Size; /* total bytes in the mapping (main + overflow) */
+
+} PT_USER_BUFFER_DESC, *PPT_USER_BUFFER_DESC;
diff --git a/hyperdbg/include/SDK/headers/RequestStructures.h b/hyperdbg/include/SDK/headers/RequestStructures.h
index 7fce50cb..5e5b66b4 100644
--- a/hyperdbg/include/SDK/headers/RequestStructures.h
+++ b/hyperdbg/include/SDK/headers/RequestStructures.h
@@ -1,6 +1,7 @@
/**
* @file RequestStructures.h
* @author Sina Karvandi (sina@hyperdbg.org)
+ * @author jtaw5649
* @brief HyperDbg's SDK Headers Request Packets
* @details This file contains definitions of request packets (enums, structs)
* @version 0.2
@@ -12,6 +13,36 @@
#pragma once
#include "Pcie.h"
+#define SIZEOF_DEBUGGER_INIT_VMM_PACKET \
+ sizeof(DEBUGGER_INIT_VMM_PACKET)
+
+/**
+ * @brief request for initializing VMM
+ *
+ */
+typedef struct _DEBUGGER_INIT_VMM_PACKET
+{
+ UINT32 KernelStatus;
+
+} DEBUGGER_INIT_VMM_PACKET, *PDEBUGGER_INIT_VMM_PACKET;
+
+// ==============================================================================================
+
+#define SIZEOF_DEBUGGER_INIT_HYPERTRACE_PACKET \
+ sizeof(DEBUGGER_INIT_HYPERTRACE_PACKET)
+
+/**
+ * @brief request for initializing HyperTrace
+ *
+ */
+typedef struct _DEBUGGER_INIT_HYPERTRACE_PACKET
+{
+ UINT32 KernelStatus;
+
+} DEBUGGER_INIT_HYPERTRACE_PACKET, *PDEBUGGER_INIT_HYPERTRACE_PACKET;
+
+// ==============================================================================================
+
#define SIZEOF_DEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS \
sizeof(DEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS)
@@ -41,8 +72,7 @@ typedef struct _DEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS
} DEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS,
*PDEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS;
-/* ==============================================================================================
- */
+// ==============================================================================================
#define SIZEOF_DEBUGGER_VA2PA_AND_PA2VA_COMMANDS \
sizeof(DEBUGGER_VA2PA_AND_PA2VA_COMMANDS)
@@ -61,8 +91,8 @@ typedef struct _DEBUGGER_VA2PA_AND_PA2VA_COMMANDS
} DEBUGGER_VA2PA_AND_PA2VA_COMMANDS, *PDEBUGGER_VA2PA_AND_PA2VA_COMMANDS;
-/* ==============================================================================================
- */
+// ==============================================================================================
+
#define SIZEOF_DEBUGGER_PAGE_IN_REQUEST \
sizeof(DEBUGGER_PAGE_IN_REQUEST)
@@ -80,8 +110,7 @@ typedef struct _DEBUGGER_PAGE_IN_REQUEST
} DEBUGGER_PAGE_IN_REQUEST, *PDEBUGGER_PAGE_IN_REQUEST;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief different modes of reconstruct requests
@@ -122,8 +151,7 @@ typedef struct _REVERSING_MACHINE_RECONSTRUCT_MEMORY_REQUEST
} REVERSING_MACHINE_RECONSTRUCT_MEMORY_REQUEST, *PREVERSING_MACHINE_RECONSTRUCT_MEMORY_REQUEST;
-/* ==============================================================================================
- */
+// ==============================================================================================
#define SIZEOF_DEBUGGER_DT_COMMAND_OPTIONS \
sizeof(DEBUGGER_DT_COMMAND_OPTIONS)
@@ -134,18 +162,17 @@ typedef struct _REVERSING_MACHINE_RECONSTRUCT_MEMORY_REQUEST
*/
typedef struct _DEBUGGER_DT_COMMAND_OPTIONS
{
- const char * TypeName;
+ const CHAR * TypeName;
UINT64 SizeOfTypeName;
UINT64 Address;
BOOLEAN IsStruct;
PVOID BufferAddress;
UINT32 TargetPid;
- const char * AdditionalParameters;
+ const CHAR * AdditionalParameters;
} DEBUGGER_DT_COMMAND_OPTIONS, *PDEBUGGER_DT_COMMAND_OPTIONS;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief different types of prealloc requests
@@ -179,8 +206,7 @@ typedef struct _DEBUGGER_PREALLOC_COMMAND
} DEBUGGER_PREALLOC_COMMAND, *PDEBUGGER_PREALLOC_COMMAND;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief different types of preactivate requests
@@ -206,8 +232,7 @@ typedef struct _DEBUGGER_PREACTIVATE_COMMAND
} DEBUGGER_PREACTIVATE_COMMAND, *PDEBUGGER_PREACTIVATE_COMMAND;
-/* ==============================================================================================
- */
+// ==============================================================================================
#define SIZEOF_DEBUGGER_READ_MEMORY sizeof(DEBUGGER_READ_MEMORY)
@@ -281,8 +306,7 @@ typedef struct _DEBUGGER_READ_MEMORY
} DEBUGGER_READ_MEMORY, *PDEBUGGER_READ_MEMORY;
-/* ==============================================================================================
- */
+// ==============================================================================================
#define SIZEOF_DEBUGGER_FLUSH_LOGGING_BUFFERS \
sizeof(DEBUGGER_FLUSH_LOGGING_BUFFERS)
@@ -299,8 +323,7 @@ typedef struct _DEBUGGER_FLUSH_LOGGING_BUFFERS
} DEBUGGER_FLUSH_LOGGING_BUFFERS, *PDEBUGGER_FLUSH_LOGGING_BUFFERS;
-/* ==============================================================================================
- */
+// ==============================================================================================
#define SIZEOF_DEBUGGER_TEST_QUERY_BUFFER \
sizeof(DEBUGGER_TEST_QUERY_BUFFER)
@@ -338,8 +361,7 @@ typedef struct _DEBUGGER_DEBUGGER_TEST_QUERY_BUFFER
} DEBUGGER_DEBUGGER_TEST_QUERY_BUFFER, *PDEBUGGER_DEBUGGER_TEST_QUERY_BUFFER;
-/* ==============================================================================================
- */
+// ==============================================================================================
#define SIZEOF_DEBUGGER_PERFORM_KERNEL_TESTS \
sizeof(DEBUGGER_PERFORM_KERNEL_TESTS)
@@ -354,8 +376,7 @@ typedef struct _DEBUGGER_PERFORM_KERNEL_TESTS
} DEBUGGER_PERFORM_KERNEL_TESTS, *PDEBUGGER_PERFORM_KERNEL_TESTS;
-/* ==============================================================================================
- */
+// ==============================================================================================
#define SIZEOF_DEBUGGER_SEND_COMMAND_EXECUTION_FINISHED_SIGNAL \
sizeof(DEBUGGER_SEND_COMMAND_EXECUTION_FINISHED_SIGNAL)
@@ -371,8 +392,7 @@ typedef struct _DEBUGGER_SEND_COMMAND_EXECUTION_FINISHED_SIGNAL
} DEBUGGER_SEND_COMMAND_EXECUTION_FINISHED_SIGNAL,
*PDEBUGGER_SEND_COMMAND_EXECUTION_FINISHED_SIGNAL;
-/* ==============================================================================================
- */
+// ==============================================================================================
#define SIZEOF_DEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER \
sizeof(DEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER)
@@ -395,8 +415,7 @@ typedef struct _DEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER
} DEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER,
*PDEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER;
-/* ==============================================================================================
- */
+// ==============================================================================================
#define SIZEOF_DEBUGGER_SEND_USERMODE_MESSAGES_TO_DEBUGGER \
sizeof(DEBUGGER_SEND_USERMODE_MESSAGES_TO_DEBUGGER)
@@ -417,8 +436,7 @@ typedef struct _DEBUGGER_SEND_USERMODE_MESSAGES_TO_DEBUGGER
} DEBUGGER_SEND_USERMODE_MESSAGES_TO_DEBUGGER,
*PDEBUGGER_SEND_USERMODE_MESSAGES_TO_DEBUGGER;
-/* ==============================================================================================
- */
+// ==============================================================================================
#define SIZEOF_DEBUGGER_READ_AND_WRITE_ON_MSR \
sizeof(DEBUGGER_READ_AND_WRITE_ON_MSR)
@@ -439,18 +457,19 @@ typedef enum _DEBUGGER_MSR_ACTION_TYPE
*/
typedef struct _DEBUGGER_READ_AND_WRITE_ON_MSR
{
- UINT64 Msr; // It's actually a 32-Bit value but let's not mess with a register
- UINT32 CoreNumber; // specifies the core to execute wrmsr or read the msr
- // (DEBUGGER_READ_AND_WRITE_ON_MSR_APPLY_ALL_CORES mean all
- // the cores)
- DEBUGGER_MSR_ACTION_TYPE
- ActionType; // Detects whether user needs wrmsr or rdmsr
- UINT64 Value;
+ UINT64 Msr; // It's actually a 32-Bit value but let's not mess with a register
+ UINT32 CoreNumber; // specifies the core to execute wrmsr or read the msr
+ // (DEBUGGER_READ_AND_WRITE_ON_MSR_APPLY_ALL_CORES mean all
+ // the cores)
+ DEBUGGER_MSR_ACTION_TYPE ActionType; // Detects whether user needs wrmsr or rdmsr
+ UINT64 Value;
} DEBUGGER_READ_AND_WRITE_ON_MSR, *PDEBUGGER_READ_AND_WRITE_ON_MSR;
-/* ==============================================================================================
- */
+#define SIZEOF_DEBUGGER_READ_AND_WRITE_ON_MSR \
+ sizeof(DEBUGGER_READ_AND_WRITE_ON_MSR)
+
+// ==============================================================================================
#define SIZEOF_DEBUGGER_EDIT_MEMORY sizeof(DEBUGGER_EDIT_MEMORY)
@@ -491,8 +510,7 @@ typedef struct _DEBUGGER_EDIT_MEMORY
} DEBUGGER_EDIT_MEMORY, *PDEBUGGER_EDIT_MEMORY;
-/* ==============================================================================================
- */
+// ==============================================================================================
#define SIZEOF_DEBUGGER_SEARCH_MEMORY sizeof(DEBUGGER_SEARCH_MEMORY)
@@ -536,8 +554,7 @@ typedef struct _DEBUGGER_SEARCH_MEMORY
} DEBUGGER_SEARCH_MEMORY, *PDEBUGGER_SEARCH_MEMORY;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief Windows System call values that are intercepted by transparency mode
@@ -597,11 +614,12 @@ typedef struct _DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE
DEBUGGER_ERROR_UNABLE_TO_HIDE_OR_UNHIDE_DEBUGGER
*/
+ UINT32 EvadeMask; // zero means TRANSPARENT_EVADE_MASK_DEFAULT
+
} DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE,
*PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE;
-/* ==============================================================================================
- */
+// ==============================================================================================
#define SIZEOF_DEBUGGER_PREPARE_DEBUGGEE sizeof(DEBUGGER_PREPARE_DEBUGGEE)
@@ -619,8 +637,7 @@ typedef struct _DEBUGGER_PREPARE_DEBUGGEE
} DEBUGGER_PREPARE_DEBUGGEE, *PDEBUGGER_PREPARE_DEBUGGEE;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief The structure of changing core packet in HyperDbg
@@ -633,8 +650,8 @@ typedef struct _DEBUGGEE_CHANGE_CORE_PACKET
} DEBUGGEE_CHANGE_CORE_PACKET, *PDEBUGGEE_CHANGE_CORE_PACKET;
-/* ==============================================================================================
- */
+// ==============================================================================================
+
#define SIZEOF_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS \
sizeof(DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS)
@@ -666,7 +683,10 @@ typedef struct _DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS
UINT32 ThreadId;
BOOLEAN CheckCallbackAtFirstInstruction;
BOOLEAN Is32Bit;
- BOOLEAN IsPaused; // used in switching to threads
+ UINT64 Rip; // used in switching threads
+ BYTE InstructionBytesOnRip[MAXIMUM_INSTR_SIZE]; // used in switching threads
+ UINT32 SizeOfInstruction; // used in switching threads
+ BOOLEAN IsPaused; // used in switching to threads
DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_TYPE Action;
UINT32 CountOfActiveDebuggingThreadsAndProcesses; // used in showing the list of active threads/processes
UINT64 Token;
@@ -675,8 +695,8 @@ typedef struct _DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS
} DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS,
*PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS;
-/* ==============================================================================================
- */
+// ==============================================================================================
+
#define SIZEOF_DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS \
sizeof(DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS)
@@ -782,8 +802,10 @@ typedef struct _DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS
} DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS,
*PDEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS;
-/* ==============================================================================================
- */
+#define SIZEOF_DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS \
+ sizeof(DEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS)
+
+// ==============================================================================================
/**
* @brief The structure for saving the callstack frame of one parameter
@@ -833,8 +855,8 @@ typedef struct _DEBUGGER_CALLSTACK_REQUEST
} DEBUGGER_CALLSTACK_REQUEST, *PDEBUGGER_CALLSTACK_REQUEST;
-/* ==============================================================================================
- */
+// ==============================================================================================
+
#define SIZEOF_USERMODE_DEBUGGING_THREAD_OR_PROCESS_STATE_DETAILS \
sizeof(USERMODE_DEBUGGING_THREAD_OR_PROCESS_STATE_DETAILS)
@@ -842,12 +864,12 @@ typedef struct _USERMODE_DEBUGGING_THREAD_OR_PROCESS_STATE_DETAILS
{
UINT32 ProcessId;
UINT32 ThreadId;
+ UINT64 NumberOfBlockedContextSwitches;
BOOLEAN IsProcess;
} USERMODE_DEBUGGING_THREAD_OR_PROCESS_STATE_DETAILS, *PUSERMODE_DEBUGGING_THREAD_OR_PROCESS_STATE_DETAILS;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief Used for run the script
@@ -887,8 +909,7 @@ typedef struct _DEBUGGER_EVENT_REQUEST_CUSTOM_CODE
} DEBUGGER_EVENT_REQUEST_CUSTOM_CODE, *PDEBUGGER_EVENT_REQUEST_CUSTOM_CODE;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief User-mode debugging actions
@@ -899,6 +920,8 @@ typedef enum _DEBUGGER_UD_COMMAND_ACTION_TYPE
DEBUGGER_UD_COMMAND_ACTION_TYPE_NONE = 0,
DEBUGGER_UD_COMMAND_ACTION_TYPE_PAUSE,
DEBUGGER_UD_COMMAND_ACTION_TYPE_REGULAR_STEP,
+ DEBUGGER_UD_COMMAND_ACTION_TYPE_READ_REGISTERS,
+ DEBUGGER_UD_COMMAND_ACTION_TYPE_EXECUTE_SCRIPT_BUFFER,
} DEBUGGER_UD_COMMAND_ACTION_TYPE;
@@ -926,12 +949,14 @@ typedef struct _DEBUGGER_UD_COMMAND_PACKET
UINT64 ProcessDebuggingDetailToken;
UINT32 TargetThreadId;
BOOLEAN ApplyToAllPausedThreads;
+ BOOLEAN WaitForEventCompletion;
UINT32 Result;
} DEBUGGER_UD_COMMAND_PACKET, *PDEBUGGER_UD_COMMAND_PACKET;
-/* ==============================================================================================
- */
+#define SIZEOF_DEBUGGER_UD_COMMAND_PACKET sizeof(DEBUGGER_UD_COMMAND_PACKET)
+
+// ==============================================================================================
/**
* @brief Debugger process switch and process details
@@ -963,8 +988,7 @@ typedef struct _DEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET
} DEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET, *PDEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief Debugger size of DEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET
@@ -1011,8 +1035,7 @@ typedef struct _DEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET
#define SIZEOF_DEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET \
sizeof(DEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET)
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief stepping and tracking types
@@ -1053,7 +1076,7 @@ typedef struct _DEBUGGEE_STEP_PACKET
*/
#define DEBUGGER_REMOTE_TRACKING_DEFAULT_COUNT_OF_STEPPING 0xffffffff
-/* ==============================================================================================
+// ==============================================================================================
/**
* @brief Perform actions related to APIC
@@ -1187,8 +1210,7 @@ typedef struct _LAPIC_PAGE
UINT8 Reserved3F4[0x0C]; // valid only for X2APIC
} LAPIC_PAGE, *PLAPIC_PAGE;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief Maximum number of I/O APIC entries
@@ -1221,8 +1243,266 @@ typedef struct _IO_APIC_ENTRY_PACKETS
static_assert(sizeof(IO_APIC_ENTRY_PACKETS) < PacketChunkSize,
"err (static_assert), size of PacketChunkSize should be bigger than IO_APIC_ENTRY_PACKETS");
-/* ==============================================================================================
+// ==============================================================================================
+
+/**
+ * @brief Perform actions related to SMIs
+ *
*/
+typedef enum _SMI_OPERATION_REQUEST_TYPE
+{
+ SMI_OPERATION_REQUEST_TYPE_READ_COUNT,
+ SMI_OPERATION_REQUEST_TYPE_TRIGGER_POWER_SMI,
+
+} SMI_OPERATION_REQUEST_TYPE;
+
+/**
+ * @brief The structure of I/O APIC result packet in HyperDbg
+ *
+ */
+typedef struct _SMI_OPERATION_PACKETS
+{
+ SMI_OPERATION_REQUEST_TYPE SmiOperationType;
+ UINT64 SmiCount;
+ UINT32 KernelStatus;
+
+} SMI_OPERATION_PACKETS, *PSMI_OPERATION_PACKETS;
+
+/**
+ * @brief Debugger size of SMI_OPERATION_PACKETS
+ *
+ */
+#define SIZEOF_SMI_OPERATION_PACKETS \
+ sizeof(SMI_OPERATION_PACKETS)
+
+// ==============================================================================================
+
+/**
+ * @brief Perform actions related to HyperTrace for LBR
+ *
+ */
+typedef enum _HYPERTRACE_LBR_OPERATION_REQUEST_TYPE
+{
+ HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_ENABLE,
+ HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_DISABLE,
+ HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_FLUSH,
+
+ HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_FILTER,
+
+ // HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_QUERY,
+ // HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_DUMP,
+
+} HYPERTRACE_LBR_OPERATION_REQUEST_TYPE;
+
+/**
+ * @brief The structure of HyperTrace LBR result packet in HyperDbg
+ *
+ */
+typedef struct _HYPERTRACE_LBR_OPERATION_PACKETS
+{
+ HYPERTRACE_LBR_OPERATION_REQUEST_TYPE LbrOperationType;
+ UINT32 LbrFilterOptions;
+ UINT32 KernelStatus;
+
+} HYPERTRACE_LBR_OPERATION_PACKETS, *PHYPERTRACE_LBR_OPERATION_PACKETS;
+
+/**
+ * @brief Debugger size of HYPERTRACE_LBR_OPERATION_PACKETS
+ *
+ */
+#define SIZEOF_HYPERTRACE_LBR_OPERATION_PACKETS \
+ sizeof(HYPERTRACE_LBR_OPERATION_PACKETS)
+
+// ==============================================================================================
+
+/**
+ * @brief The structure of HyperTrace LBR dump result packet in HyperDbg
+ *
+ */
+typedef struct _HYPERTRACE_LBR_DUMP_PACKETS
+{
+ UINT32 CoreId;
+ BOOLEAN NextCoreIsValid; // In the case of dumping all cores, this flag indicates whether the next core number is valid
+ BOOLEAN ArchBasedLBR; // Whether the LBR is architecture-based
+ LBR_STACK_ENTRY LbrStack;
+ UINT8 CurrentLbrCapacity;
+ UINT32 KernelStatus;
+
+} HYPERTRACE_LBR_DUMP_PACKETS, *PHYPERTRACE_LBR_DUMP_PACKETS;
+
+/**
+ * @brief In the case of dumping all cores, this value is used to specify that all cores should be dumped
+ *
+ */
+#define HYPERTRACE_LBR_DUMP_ALL_CORES 0xffffffff
+
+/**
+ * @brief Debugger size of HYPERTRACE_LBR_DUMP_PACKETS
+ *
+ */
+#define SIZEOF_HYPERTRACE_LBR_DUMP_PACKETS \
+ sizeof(HYPERTRACE_LBR_DUMP_PACKETS)
+
+// ==============================================================================================
+
+/**
+ * @brief Perform actions related to HyperTrace for PT
+ *
+ */
+typedef enum _HYPERTRACE_PT_OPERATION_REQUEST_TYPE
+{
+ HYPERTRACE_PT_OPERATION_REQUEST_TYPE_ENABLE,
+ HYPERTRACE_PT_OPERATION_REQUEST_TYPE_DISABLE,
+ HYPERTRACE_PT_OPERATION_REQUEST_TYPE_PAUSE,
+ HYPERTRACE_PT_OPERATION_REQUEST_TYPE_RESUME,
+ HYPERTRACE_PT_OPERATION_REQUEST_TYPE_SIZE,
+ HYPERTRACE_PT_OPERATION_REQUEST_TYPE_FLUSH,
+ HYPERTRACE_PT_OPERATION_REQUEST_TYPE_DUMP,
+ HYPERTRACE_PT_OPERATION_REQUEST_TYPE_FILTER,
+ HYPERTRACE_PT_OPERATION_REQUEST_TYPE_PACKET,
+
+} HYPERTRACE_PT_OPERATION_REQUEST_TYPE;
+
+/**
+ * @brief The maximum buffer size for PT
+ *
+ */
+#define PT_DEFAULT_BUFFER_SIZE 0x200000 // 2 MB
+
+/**
+ * @brief The default core for PT
+ *
+ */
+#define PT_DEFAULT_PINNING_CORE 0x0 // 0th core
+
+/**
+ * @brief PT enable options structure
+ *
+ */
+typedef struct _PT_ENABLE_OPTIONS
+{
+ UINT32 EnableByCr3 : 1; // Enable by CR3
+ UINT32 EnableByPid : 1; // Enable by PID
+ UINT32 EnableByTid : 1; // Enable by TID
+ UINT32 EnableByPname : 1; // Enable by process name
+
+ UINT32 Pid;
+ UINT32 Tid;
+ UINT64 Cr3;
+ CHAR ProcessName[256];
+
+} PT_ENABLE_OPTIONS, *PPT_ENABLE_OPTIONS;
+
+/**
+ * @brief PT filter options structure
+ *
+ */
+typedef struct _PT_FILTER_OPTIONS
+{
+ UINT32 TraceUser : 1; // Trace user mode
+ UINT32 TraceKernel : 1; // Trace kernel mode
+
+ UINT8 NumAddrRanges; /* Number of valid AddrRanges entries */
+ PT_ADDR_RANGE AddrRanges[PT_MAX_ADDR_RANGES]; // Address ranges to filter by
+
+} PT_FILTER_OPTIONS, *PPT_FILTER_OPTIONS;
+
+/**
+ * @brief PT packet options structure
+ *
+ */
+typedef struct _PT_PACKET_OPTIONS
+{
+ UINT32 PSB : 1; // PSB packet
+ UINT32 PIP : 1; // PIP packet
+ UINT32 TSC : 1; // TSC packet
+ UINT32 MTC : 1; // MTC packet
+ UINT32 CYC : 1; // CYC packet
+ UINT32 TNT : 1; // TNT packet
+ UINT32 TIP : 1; // TIP packet
+ UINT32 FUP : 1; // FUP packet
+ UINT32 MODE : 1; // MODE packet
+
+} PT_PACKET_OPTIONS, *PPT_PACKET_OPTIONS;
+
+/**
+ * @brief The structure of HyperTrace PT result packet in HyperDbg
+ *
+ */
+typedef struct _HYPERTRACE_PT_OPERATION_PACKETS
+{
+ HYPERTRACE_PT_OPERATION_REQUEST_TYPE PtOperationType;
+ UINT32 KernelStatus;
+
+ //
+ // Enable
+ //
+ UINT64 BufferSize; /* Output buffer size (0 = default / PT_DEFAULT_BUFFER_SIZE) */
+ PT_ENABLE_OPTIONS EnableOptions; /* Options for enabling PT (CPL, CR3, PID, TID, Pname) */
+ UINT32 CoreId; /* Core ID for running (pinning) process/thread */
+
+ //
+ // Filter
+ //
+ PT_FILTER_OPTIONS FilterOptions; /* Options for filtering PT (CPL, AddrRanges) */
+
+ //
+ // Packet
+ //
+ PT_PACKET_OPTIONS PacketOptions; /* Options for PT packets */
+
+ //
+ // Size
+ //
+ UINT32 NumCpus; /* CPUs populated in BytesPerCpu */
+ UINT64 BytesPerCpu[PT_MAX_CPUS_FOR_MMAP];
+
+} HYPERTRACE_PT_OPERATION_PACKETS, *PHYPERTRACE_PT_OPERATION_PACKETS;
+
+/**
+ * @brief Debugger size of HYPERTRACE_PT_OPERATION_PACKETS
+ *
+ */
+#define SIZEOF_HYPERTRACE_PT_OPERATION_PACKETS \
+ sizeof(HYPERTRACE_PT_OPERATION_PACKETS)
+
+// ==============================================================================================
+
+/**
+ * @brief Result packet for the HyperTrace PT mmap surface.
+ *
+ * On success KernelStatus is DEBUGGER_OPERATION_WAS_SUCCESSFUL,
+ * NumCpus gives the number of CPUs that were mapped, and
+ * Cpus[0..NumCpus) hand back a single { UserVa, Size } per CPU.
+ * Each Size covers the main output buffer immediately followed
+ * by the 4 KB overflow page as one contiguous byte stream.
+ *
+ * Mapping contract (cooperative single-process):
+ * - The IOCTL maps into the address space of the process that
+ * calls DeviceIoControl. The returned user VAs are not
+ * portable across processes.
+ * - Mapping is tied to the PT enable cycle. PT disable / flush
+ * tears the mapping down; the caller must not touch the
+ * user VAs afterwards.
+ * - Calling the IOCTL twice within the same enable cycle
+ * returns the existing mapping (idempotent).
+ */
+typedef struct _HYPERTRACE_PT_MMAP_PACKETS
+{
+ UINT32 KernelStatus;
+ UINT32 NumCpus;
+ PT_USER_BUFFER_DESC Cpus[PT_MAX_CPUS_FOR_MMAP];
+
+} HYPERTRACE_PT_MMAP_PACKETS, *PHYPERTRACE_PT_MMAP_PACKETS;
+
+/**
+ * @brief Debugger size of HYPERTRACE_PT_MMAP_PACKETS
+ *
+ */
+#define SIZEOF_HYPERTRACE_PT_MMAP_PACKETS \
+ sizeof(HYPERTRACE_PT_MMAP_PACKETS)
+
+// ==============================================================================================
/**
* @brief Maximum number of IDT entries
@@ -1255,8 +1535,7 @@ typedef struct _INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS
static_assert(sizeof(INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS) < PacketChunkSize,
"err (static_assert), size of PacketChunkSize should be bigger than INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS");
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief The structure of .formats result packet in HyperDbg
@@ -1269,8 +1548,7 @@ typedef struct _DEBUGGEE_FORMATS_PACKET
} DEBUGGEE_FORMATS_PACKET, *PDEBUGGEE_FORMATS_PACKET;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief The structure of .sym reload packet in HyperDbg
@@ -1282,8 +1560,7 @@ typedef struct _DEBUGGEE_SYMBOL_REQUEST_PACKET
} DEBUGGEE_SYMBOL_REQUEST_PACKET, *PDEBUGGEE_SYMBOL_REQUEST_PACKET;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief The structure of bp command packet in HyperDbg
@@ -1334,8 +1611,7 @@ typedef struct _DEBUGGEE_BP_LIST_OR_MODIFY_PACKET
} DEBUGGEE_BP_LIST_OR_MODIFY_PACKET, *PDEBUGGEE_BP_LIST_OR_MODIFY_PACKET;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief Whether a jump is taken or not taken
@@ -1351,8 +1627,7 @@ typedef enum _DEBUGGER_CONDITIONAL_JUMP_STATUS
} DEBUGGER_CONDITIONAL_JUMP_STATUS;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief The structure of script packet in HyperDbg
@@ -1363,6 +1638,7 @@ typedef struct _DEBUGGEE_SCRIPT_PACKET
UINT32 ScriptBufferSize;
UINT32 ScriptBufferPointer;
BOOLEAN IsFormat;
+ UINT64 FormatValue;
UINT32 Result;
//
@@ -1371,8 +1647,7 @@ typedef struct _DEBUGGEE_SCRIPT_PACKET
} DEBUGGEE_SCRIPT_PACKET, *PDEBUGGEE_SCRIPT_PACKET;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief The structure of result of search packet in HyperDbg
@@ -1385,8 +1660,7 @@ typedef struct _DEBUGGEE_RESULT_OF_SEARCH_PACKET
} DEBUGGEE_RESULT_OF_SEARCH_PACKET, *PDEBUGGEE_RESULT_OF_SEARCH_PACKET;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief Register Descriptor Structure to use in r command.
@@ -1400,8 +1674,7 @@ typedef struct _DEBUGGEE_REGISTER_READ_DESCRIPTION
} DEBUGGEE_REGISTER_READ_DESCRIPTION, *PDEBUGGEE_REGISTER_READ_DESCRIPTION;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief Register Descriptor Structure to write on registers.
@@ -1415,8 +1688,7 @@ typedef struct _DEBUGGEE_REGISTER_WRITE_DESCRIPTION
} DEBUGGEE_REGISTER_WRITE_DESCRIPTION, *PDEBUGGEE_REGISTER_WRITE_DESCRIPTION;
-/* ==============================================================================================
- */
+// ==============================================================================================
#define SIZEOF_DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET \
sizeof(DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET)
@@ -1440,8 +1712,7 @@ typedef struct _DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET
static_assert(sizeof(DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET) < PacketChunkSize,
"err (static_assert), size of PacketChunkSize should be bigger than DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET");
-/* ==============================================================================================
- */
+// ==============================================================================================
#define SIZEOF_DEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET \
sizeof(DEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET)
@@ -1465,5 +1736,4 @@ typedef struct _DEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET
static_assert(sizeof(DEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET) < PacketChunkSize,
"err (static_assert), size of PacketChunkSize should be bigger than DEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET");
-/* ==============================================================================================
- */
+// ==============================================================================================
diff --git a/hyperdbg/include/SDK/headers/ScriptEngineCommonDefinitions.h b/hyperdbg/include/SDK/headers/ScriptEngineCommonDefinitions.h
index 4c5536a7..2a8f16fb 100644
--- a/hyperdbg/include/SDK/headers/ScriptEngineCommonDefinitions.h
+++ b/hyperdbg/include/SDK/headers/ScriptEngineCommonDefinitions.h
@@ -58,6 +58,10 @@ typedef struct ACTION_BUFFER {
#define SYMBOL_STACK_INDEX_TYPE 15
#define SYMBOL_STACK_BASE_INDEX_TYPE 16
#define SYMBOL_RETURN_VALUE_TYPE 17
+#define SYMBOL_REFERENCE_LOCAL_ID_TYPE 18
+#define SYMBOL_REFERENCE_TEMP_TYPE 19
+#define SYMBOL_DEREFERENCE_LOCAL_ID_TYPE 20
+#define SYMBOL_DEREFERENCE_TEMP_TYPE 21
static const char *const SymbolTypeNames[] = {
"SYMBOL_UNDEFINED",
@@ -77,7 +81,11 @@ static const char *const SymbolTypeNames[] = {
"SYMBOL_FUNCTION_PARAMETER_TYPE",
"SYMBOL_STACK_INDEX_TYPE",
"SYMBOL_STACK_BASE_INDEX_TYPE",
-"SYMBOL_RETURN_VALUE_TYPE"
+"SYMBOL_RETURN_VALUE_TYPE",
+"SYMBOL_REFERENCE_LOCAL_ID_TYPE",
+"SYMBOL_REFERENCE_TEMP_TYPE",
+"SYMBOL_DEREFERENCE_LOCAL_ID_TYPE",
+"SYMBOL_DEREFERENCE_TEMP_TYPE"
};
#define SYMBOL_MEM_VALID_CHECK_MASK (1 << 31)
@@ -90,111 +98,115 @@ static const char *const SymbolTypeNames[] = {
#define FUNC_INC 1
#define FUNC_DEC 2
#define FUNC_REFERENCE 3
-#define FUNC_DEREFERENCE 4
-#define FUNC_OR 5
-#define FUNC_XOR 6
-#define FUNC_AND 7
-#define FUNC_ASR 8
-#define FUNC_ASL 9
-#define FUNC_ADD 10
-#define FUNC_SUB 11
-#define FUNC_MUL 12
-#define FUNC_DIV 13
-#define FUNC_MOD 14
-#define FUNC_GT 15
-#define FUNC_LT 16
-#define FUNC_EGT 17
-#define FUNC_ELT 18
-#define FUNC_EQUAL 19
-#define FUNC_NEQ 20
-#define FUNC_JMP 21
-#define FUNC_JZ 22
-#define FUNC_JNZ 23
-#define FUNC_MOV 24
-#define FUNC_START_OF_DO_WHILE 25
-#define FUNC_START_OF_DO_WHILE_COMMANDS 26
-#define FUNC_END_OF_DO_WHILE 27
-#define FUNC_START_OF_FOR 28
-#define FUNC_FOR_INC_DEC 29
-#define FUNC_START_OF_FOR_OMMANDS 30
-#define FUNC_END_OF_IF 31
-#define FUNC_IGNORE_LVALUE 32
-#define FUNC_PUSH 33
-#define FUNC_POP 34
-#define FUNC_CALL 35
-#define FUNC_RET 36
-#define FUNC_PRINT 37
-#define FUNC_FORMATS 38
-#define FUNC_EVENT_ENABLE 39
-#define FUNC_EVENT_DISABLE 40
-#define FUNC_EVENT_CLEAR 41
-#define FUNC_TEST_STATEMENT 42
-#define FUNC_SPINLOCK_LOCK 43
-#define FUNC_SPINLOCK_UNLOCK 44
-#define FUNC_EVENT_SC 45
-#define FUNC_MICROSLEEP 46
-#define FUNC_PRINTF 47
-#define FUNC_PAUSE 48
-#define FUNC_FLUSH 49
-#define FUNC_EVENT_TRACE_STEP 50
-#define FUNC_EVENT_TRACE_STEP_IN 51
-#define FUNC_EVENT_TRACE_STEP_OUT 52
-#define FUNC_EVENT_TRACE_INSTRUMENTATION_STEP 53
-#define FUNC_EVENT_TRACE_INSTRUMENTATION_STEP_IN 54
-#define FUNC_RDTSC 55
-#define FUNC_RDTSCP 56
-#define FUNC_SPINLOCK_LOCK_CUSTOM_WAIT 57
-#define FUNC_EVENT_INJECT 58
-#define FUNC_POI 59
-#define FUNC_DB 60
-#define FUNC_DD 61
-#define FUNC_DW 62
-#define FUNC_DQ 63
-#define FUNC_NEG 64
-#define FUNC_HI 65
-#define FUNC_LOW 66
-#define FUNC_NOT 67
-#define FUNC_CHECK_ADDRESS 68
-#define FUNC_DISASSEMBLE_LEN 69
-#define FUNC_DISASSEMBLE_LEN32 70
-#define FUNC_DISASSEMBLE_LEN64 71
-#define FUNC_INTERLOCKED_INCREMENT 72
-#define FUNC_INTERLOCKED_DECREMENT 73
-#define FUNC_PHYSICAL_TO_VIRTUAL 74
-#define FUNC_VIRTUAL_TO_PHYSICAL 75
-#define FUNC_POI_PA 76
-#define FUNC_HI_PA 77
-#define FUNC_LOW_PA 78
-#define FUNC_DB_PA 79
-#define FUNC_DD_PA 80
-#define FUNC_DW_PA 81
-#define FUNC_DQ_PA 82
-#define FUNC_ED 83
-#define FUNC_EB 84
-#define FUNC_EQ 85
-#define FUNC_INTERLOCKED_EXCHANGE 86
-#define FUNC_INTERLOCKED_EXCHANGE_ADD 87
-#define FUNC_EB_PA 88
-#define FUNC_ED_PA 89
-#define FUNC_EQ_PA 90
-#define FUNC_INTERLOCKED_COMPARE_EXCHANGE 91
-#define FUNC_STRLEN 92
-#define FUNC_STRCMP 93
-#define FUNC_MEMCMP 94
-#define FUNC_STRNCMP 95
-#define FUNC_WCSLEN 96
-#define FUNC_WCSCMP 97
-#define FUNC_EVENT_INJECT_ERROR_CODE 98
-#define FUNC_MEMCPY 99
-#define FUNC_MEMCPY_PA 100
-#define FUNC_WCSNCMP 101
+#define FUNC_OR 4
+#define FUNC_XOR 5
+#define FUNC_AND 6
+#define FUNC_ASR 7
+#define FUNC_ASL 8
+#define FUNC_ADD 9
+#define FUNC_SUB 10
+#define FUNC_MUL 11
+#define FUNC_DIV 12
+#define FUNC_MOD 13
+#define FUNC_GT 14
+#define FUNC_LT 15
+#define FUNC_EGT 16
+#define FUNC_ELT 17
+#define FUNC_EQUAL 18
+#define FUNC_NEQ 19
+#define FUNC_JMP 20
+#define FUNC_JZ 21
+#define FUNC_JNZ 22
+#define FUNC_MOV 23
+#define FUNC_START_OF_DO_WHILE 24
+#define FUNC_START_OF_DO_WHILE_COMMANDS 25
+#define FUNC_END_OF_DO_WHILE 26
+#define FUNC_START_OF_FOR 27
+#define FUNC_FOR_INC_DEC 28
+#define FUNC_START_OF_FOR_OMMANDS 29
+#define FUNC_END_OF_IF 30
+#define FUNC_IGNORE_LVALUE 31
+#define FUNC_PUSH 32
+#define FUNC_POP 33
+#define FUNC_CALL 34
+#define FUNC_RET 35
+#define FUNC_PRINT 36
+#define FUNC_FORMATS 37
+#define FUNC_EVENT_ENABLE 38
+#define FUNC_EVENT_DISABLE 39
+#define FUNC_EVENT_CLEAR 40
+#define FUNC_TEST_STATEMENT 41
+#define FUNC_SPINLOCK_LOCK 42
+#define FUNC_SPINLOCK_UNLOCK 43
+#define FUNC_EVENT_SC 44
+#define FUNC_MICROSLEEP 45
+#define FUNC_PRINTF 46
+#define FUNC_PAUSE 47
+#define FUNC_FLUSH 48
+#define FUNC_EVENT_TRACE_STEP 49
+#define FUNC_EVENT_TRACE_STEP_IN 50
+#define FUNC_EVENT_TRACE_STEP_OUT 51
+#define FUNC_EVENT_TRACE_INSTRUMENTATION_STEP 52
+#define FUNC_EVENT_TRACE_INSTRUMENTATION_STEP_IN 53
+#define FUNC_RDTSC 54
+#define FUNC_RDTSCP 55
+#define FUNC_LBR_SAVE 56
+#define FUNC_LBR_DUMP 57
+#define FUNC_LBR_PRINT 58
+#define FUNC_LBR_RESTORE 59
+#define FUNC_LBR_CHECK 60
+#define FUNC_SPINLOCK_LOCK_CUSTOM_WAIT 61
+#define FUNC_EVENT_INJECT 62
+#define FUNC_POI 63
+#define FUNC_DB 64
+#define FUNC_DD 65
+#define FUNC_DW 66
+#define FUNC_DQ 67
+#define FUNC_NEG 68
+#define FUNC_HI 69
+#define FUNC_LOW 70
+#define FUNC_NOT 71
+#define FUNC_CHECK_ADDRESS 72
+#define FUNC_DISASSEMBLE_LEN 73
+#define FUNC_DISASSEMBLE_LEN32 74
+#define FUNC_DISASSEMBLE_LEN64 75
+#define FUNC_INTERLOCKED_INCREMENT 76
+#define FUNC_INTERLOCKED_DECREMENT 77
+#define FUNC_PHYSICAL_TO_VIRTUAL 78
+#define FUNC_VIRTUAL_TO_PHYSICAL 79
+#define FUNC_POI_PA 80
+#define FUNC_HI_PA 81
+#define FUNC_LOW_PA 82
+#define FUNC_DB_PA 83
+#define FUNC_DD_PA 84
+#define FUNC_DW_PA 85
+#define FUNC_DQ_PA 86
+#define FUNC_LBR_RESTORE_BY_FILTER 87
+#define FUNC_ED 88
+#define FUNC_EB 89
+#define FUNC_EQ 90
+#define FUNC_INTERLOCKED_EXCHANGE 91
+#define FUNC_INTERLOCKED_EXCHANGE_ADD 92
+#define FUNC_EB_PA 93
+#define FUNC_ED_PA 94
+#define FUNC_EQ_PA 95
+#define FUNC_INTERLOCKED_COMPARE_EXCHANGE 96
+#define FUNC_STRLEN 97
+#define FUNC_STRCMP 98
+#define FUNC_MEMCMP 99
+#define FUNC_STRNCMP 100
+#define FUNC_WCSLEN 101
+#define FUNC_WCSCMP 102
+#define FUNC_EVENT_INJECT_ERROR_CODE 103
+#define FUNC_MEMCPY 104
+#define FUNC_MEMCPY_PA 105
+#define FUNC_WCSNCMP 106
static const char *const FunctionNames[] = {
"FUNC_UNDEFINED",
"FUNC_INC",
"FUNC_DEC",
"FUNC_REFERENCE",
-"FUNC_DEREFERENCE",
"FUNC_OR",
"FUNC_XOR",
"FUNC_AND",
@@ -247,6 +259,11 @@ static const char *const FunctionNames[] = {
"FUNC_EVENT_TRACE_INSTRUMENTATION_STEP_IN",
"FUNC_RDTSC",
"FUNC_RDTSCP",
+"FUNC_LBR_SAVE",
+"FUNC_LBR_DUMP",
+"FUNC_LBR_PRINT",
+"FUNC_LBR_RESTORE",
+"FUNC_LBR_CHECK",
"FUNC_SPINLOCK_LOCK_CUSTOM_WAIT",
"FUNC_EVENT_INJECT",
"FUNC_POI",
@@ -273,6 +290,7 @@ static const char *const FunctionNames[] = {
"FUNC_DD_PA",
"FUNC_DW_PA",
"FUNC_DQ_PA",
+"FUNC_LBR_RESTORE_BY_FILTER",
"FUNC_ED",
"FUNC_EB",
"FUNC_EQ",
diff --git a/hyperdbg/include/SDK/headers/Symbols.h b/hyperdbg/include/SDK/headers/Symbols.h
index 6688de02..960b5e78 100644
--- a/hyperdbg/include/SDK/headers/Symbols.h
+++ b/hyperdbg/include/SDK/headers/Symbols.h
@@ -39,7 +39,7 @@ typedef struct _USERMODE_LOADED_MODULE_SYMBOLS
{
UINT64 BaseAddress;
UINT64 Entrypoint;
- wchar_t FilePath[MAX_PATH];
+ WCHAR FilePath[MAX_PATH];
} USERMODE_LOADED_MODULE_SYMBOLS, *PUSERMODE_LOADED_MODULE_SYMBOLS;
@@ -57,6 +57,8 @@ typedef struct _USERMODE_LOADED_MODULE_DETAILS
} USERMODE_LOADED_MODULE_DETAILS, *PUSERMODE_LOADED_MODULE_DETAILS;
+#define SIZEOF_USERMODE_LOADED_MODULE_DETAILS sizeof(USERMODE_LOADED_MODULE_DETAILS)
+
/**
* @brief Callback type that should be used to add
* list of Addresses to ObjectNames
diff --git a/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperLogImports.h b/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperLogImports.h
index 7324ed8d..f3a388a3 100644
--- a/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperLogImports.h
+++ b/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperLogImports.h
@@ -34,7 +34,7 @@ LogCallbackPrepareAndSendMessageToQueue(UINT32 OperationCode,
BOOLEAN IsImmediateMessage,
BOOLEAN ShowCurrentSystemTime,
BOOLEAN Priority,
- const char * Fmt,
+ const CHAR * Fmt,
...);
IMPORT_EXPORT_HYPERLOG BOOLEAN
@@ -42,7 +42,7 @@ LogCallbackPrepareAndSendMessageToQueueWrapper(UINT32 OperationCode,
BOOLEAN IsImmediateMessage,
BOOLEAN ShowCurrentSystemTime,
BOOLEAN Priority,
- const char * Fmt,
+ const CHAR * Fmt,
va_list ArgList);
IMPORT_EXPORT_HYPERLOG BOOLEAN
diff --git a/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperLogIntrinsics.h b/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperLogIntrinsics.h
index 6819bc26..837fb661 100644
--- a/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperLogIntrinsics.h
+++ b/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperLogIntrinsics.h
@@ -52,7 +52,7 @@ typedef enum _LOG_TYPE
DbgPrint("[!] Error (%s:%d) | " format "\n", \
__func__, \
__LINE__, \
- ##__VA_ARGS__); \
+ ##__VA_ARGS__); \
DbgBreakPoint()
/**
@@ -118,7 +118,7 @@ typedef enum _LOG_TYPE
"[!] Error (%s:%d) | " format "\n", \
__func__, \
__LINE__, \
- ##__VA_ARGS__); \
+ ##__VA_ARGS__); \
if (DebugMode) \
DbgBreakPoint()
diff --git a/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperPerf.h b/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperPerf.h
new file mode 100644
index 00000000..f6997795
--- /dev/null
+++ b/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperPerf.h
@@ -0,0 +1,33 @@
+/**
+ * @file HyperDbgHyperPerf.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Headers relating exported functions from hyperperf (pmu) module
+ * @version 0.21
+ * @date 2026-06-22
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#ifdef HYPERDBG_HYPERPERF
+# define IMPORT_EXPORT_HYPERPERF __declspec(dllexport)
+#else
+# define IMPORT_EXPORT_HYPERPERF __declspec(dllimport)
+#endif
+
+//////////////////////////////////////////////////
+// HyperPerf Functions //
+//////////////////////////////////////////////////
+
+//
+// Initialize the hyperperf module with the provided callbacks
+//
+IMPORT_EXPORT_HYPERPERF BOOLEAN
+HyperPerfInitCallback(HYPERPERF_CALLBACKS * HyperPerfCallbacks, BOOLEAN RunningOnHypervisorEnvironment);
+
+//
+// Uninitialize the HyperPerf module
+//
+IMPORT_EXPORT_HYPERPERF VOID
+HyperPerfUninit();
diff --git a/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperTrace.h b/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperTrace.h
new file mode 100644
index 00000000..5da661de
--- /dev/null
+++ b/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperTrace.h
@@ -0,0 +1,114 @@
+/**
+ * @file HyperDbgHyperTrace.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Headers relating exported functions from hypertrace (tracing) module
+ * @version 0.18
+ * @date 2026-02-08
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#ifdef HYPERDBG_HYPERTRACE
+# define IMPORT_EXPORT_HYPERTRACE __declspec(dllexport)
+#else
+# define IMPORT_EXPORT_HYPERTRACE __declspec(dllimport)
+#endif
+
+//////////////////////////////////////////////////
+// HyperTrace Functions //
+//////////////////////////////////////////////////
+
+//
+// Initialize the hypertrace module with the provided callbacks
+//
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTraceInitCallback(HYPERTRACE_CALLBACKS * HyperTraceCallbacks, BOOLEAN RunningOnHypervisorEnvironment);
+
+//
+// Uninitialize the HyperTrace module
+//
+IMPORT_EXPORT_HYPERTRACE VOID
+HyperTraceUninit();
+
+//////////////////////////////////////////////////
+// LBR Functions //
+//////////////////////////////////////////////////
+
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTraceLbrIsSupported(UINT32 * Capacity, BOOLEAN * IsArchLbr);
+
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTraceLbrCheck();
+
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTraceLbrRestore();
+
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTraceLbrRestoreByFilter(UINT64 FilterOptions);
+
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTraceLbrSave(HYPERTRACE_LBR_OPERATION_PACKETS * HyperTraceOperationRequest);
+
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTraceLbrPrint(HYPERTRACE_LBR_OPERATION_PACKETS * HyperTraceOperationRequest);
+
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTraceLbrFlush(HYPERTRACE_LBR_OPERATION_PACKETS * HyperTraceOperationRequest);
+
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTraceLbrQueryStateOfLbrSaveAndLoadVmExitAndEntryControls(UINT32 CoreId);
+
+//
+// Perform operations related to HyperTrace LBR dumping
+//
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTraceLbrPerformDump(HYPERTRACE_LBR_DUMP_PACKETS * LbrDumpRequest);
+
+//
+// Perform operations related to HyperTrace LBR based on the request type and parameters
+//
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTraceLbrPerformOperation(HYPERTRACE_LBR_OPERATION_PACKETS * LbrOperationRequest);
+
+//////////////////////////////////////////////////
+// PT Functions //
+//////////////////////////////////////////////////
+
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTracePtEnable(HYPERTRACE_PT_OPERATION_PACKETS * PtOperationRequest);
+
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTracePtDisable(HYPERTRACE_PT_OPERATION_PACKETS * PtOperationRequest);
+
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTracePtPause(HYPERTRACE_PT_OPERATION_PACKETS * PtOperationRequest);
+
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTracePtResume(HYPERTRACE_PT_OPERATION_PACKETS * PtOperationRequest);
+
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTracePtSize(HYPERTRACE_PT_OPERATION_PACKETS * PtOperationRequest);
+
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTracePtDump(HYPERTRACE_PT_OPERATION_PACKETS * PtOperationRequest);
+
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTracePtFlush(HYPERTRACE_PT_OPERATION_PACKETS * PtOperationRequest);
+
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTracePtFilter(HYPERTRACE_PT_OPERATION_PACKETS * PtOperationRequest);
+
+//
+// Perform operations related to HyperTrace PT based on the request type and parameters
+//
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTracePtPerformOperation(HYPERTRACE_PT_OPERATION_PACKETS * PtOperationRequest);
+
+//
+// Map every per-CPU PT main output + overflow buffer into the calling
+// user process. See HYPERTRACE_PT_MMAP_PACKETS for the lifetime contract.
+//
+IMPORT_EXPORT_HYPERTRACE BOOLEAN
+HyperTracePtMmap(HYPERTRACE_PT_MMAP_PACKETS * Req);
diff --git a/hyperdbg/include/SDK/imports/kernel/HyperDbgVmmImports.h b/hyperdbg/include/SDK/imports/kernel/HyperDbgVmmImports.h
index 4479eeee..c64991a3 100644
--- a/hyperdbg/include/SDK/imports/kernel/HyperDbgVmmImports.h
+++ b/hyperdbg/include/SDK/imports/kernel/HyperDbgVmmImports.h
@@ -21,10 +21,10 @@
//////////////////////////////////////////////////
IMPORT_EXPORT_VMM NTSTATUS
-VmFuncVmxVmcall(unsigned long long VmcallNumber,
- unsigned long long OptionalParam1,
- unsigned long long OptionalParam2,
- unsigned long long OptionalParam3);
+VmFuncVmxVmcall(UINT64 VmcallNumber,
+ UINT64 OptionalParam1,
+ UINT64 OptionalParam2,
+ UINT64 OptionalParam3);
IMPORT_EXPORT_VMM VOID
VmFuncPerformRipIncrement(UINT32 CoreId);
@@ -45,16 +45,22 @@ IMPORT_EXPORT_VMM VOID
VmFuncSetRflagTrapFlag(BOOLEAN Set);
IMPORT_EXPORT_VMM VOID
-VmFuncRegisterMtfBreak(UINT32 CoreId);
+VmFuncSetInstrumentationStepInState(UINT32 CoreId);
IMPORT_EXPORT_VMM VOID
-VmFuncUnRegisterMtfBreak(UINT32 CoreId);
+VmFuncUnsetInstrumentationStepInState(UINT32 CoreId);
IMPORT_EXPORT_VMM VOID
-VmFuncSetLoadDebugControls(BOOLEAN Set);
+VmFuncSetLoadDebugControls(UINT32 CoreId, BOOLEAN Set);
IMPORT_EXPORT_VMM VOID
-VmFuncSetSaveDebugControls(BOOLEAN Set);
+VmFuncSetLoadGuestIa32LbrCtl(UINT32 CoreId, BOOLEAN Set);
+
+IMPORT_EXPORT_VMM VOID
+VmFuncSetSaveDebugControls(UINT32 CoreId, BOOLEAN Set);
+
+IMPORT_EXPORT_VMM VOID
+VmFuncSetClearGuestIa32LbrCtl(UINT32 CoreId, BOOLEAN Set);
IMPORT_EXPORT_VMM VOID
VmFuncSetPmcVmexit(BOOLEAN Set);
@@ -101,12 +107,48 @@ VmFuncSetRflags(UINT64 Rflags);
IMPORT_EXPORT_VMM VOID
VmFuncSetRip(UINT64 Rip);
+IMPORT_EXPORT_VMM VOID
+VmFuncSetDebugReg7(UINT64 Value);
+
+IMPORT_EXPORT_VMM VOID
+VmFuncSetDebugctl(UINT64 Value);
+
+IMPORT_EXPORT_VMM VOID
+VmFuncSetDebugctlVmcallOnTargetCore(UINT64 Value);
+
+IMPORT_EXPORT_VMM VOID
+VmFuncSetGuestIa32LbrCtl(UINT64 Value);
+
+IMPORT_EXPORT_VMM VOID
+VmFuncSetGuestIa32LbrCtlVmcallOnTargetCore(UINT64 Value);
+
+IMPORT_EXPORT_VMM VOID
+VmFuncSetLbrSelect(UINT64 FilterOptions);
+
+IMPORT_EXPORT_VMM VOID
+VmFuncSetLbrSelectVmcallOnTargetCore(UINT64 FilterOptions);
+
+IMPORT_EXPORT_VMM VOID
+VmFuncSetLoadDebugControlsVmcallOnTargetCore(BOOLEAN Set);
+
+IMPORT_EXPORT_VMM VOID
+VmFuncSetLoadGuestIa32LbrCtlVmcallOnTargetCore(BOOLEAN Set);
+
+IMPORT_EXPORT_VMM VOID
+VmFuncSetSaveDebugControlsVmcallOnTargetCore(BOOLEAN Set);
+
+IMPORT_EXPORT_VMM VOID
+VmFuncSetClearGuestIa32LbrCtlVmcallOnTargetCore(BOOLEAN Set);
+
IMPORT_EXPORT_VMM VOID
VmFuncSetTriggerEventForVmcalls(BOOLEAN Set);
IMPORT_EXPORT_VMM VOID
VmFuncSetTriggerEventForCpuids(BOOLEAN Set);
+IMPORT_EXPORT_VMM VOID
+VmFuncSetTriggerEventForXsetbvs(BOOLEAN Set);
+
IMPORT_EXPORT_VMM VOID
VmFuncSetInterruptibilityState(UINT64 InterruptibilityState);
@@ -159,6 +201,10 @@ IMPORT_EXPORT_VMM VOID
VmFuncIdtQueryEntries(PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS IdtQueryRequest,
BOOLEAN ReadFromVmxRoot);
+IMPORT_EXPORT_VMM BOOLEAN
+VmFuncSmmPerformSmiOperation(SMI_OPERATION_PACKETS * SmiOperationRequest,
+ BOOLEAN ApplyFromVmxRootMode);
+
IMPORT_EXPORT_VMM UINT16
VmFuncGetCsSelector();
@@ -174,6 +220,18 @@ VmFuncGetRflags();
IMPORT_EXPORT_VMM UINT64
VmFuncGetRip();
+IMPORT_EXPORT_VMM UINT64
+VmFuncGetDebugctl();
+
+IMPORT_EXPORT_VMM UINT64
+VmFuncGetDebugctlVmcallOnTargetCore();
+
+IMPORT_EXPORT_VMM UINT64
+VmFuncGetGuestIa32LbrCtl();
+
+IMPORT_EXPORT_VMM UINT64
+VmFuncGetGuestIa32LbrCtlVmcallOnTargetCore();
+
IMPORT_EXPORT_VMM UINT64
VmFuncGetInterruptibilityState();
@@ -187,7 +245,7 @@ IMPORT_EXPORT_VMM UINT32
VmFuncVmxCompatibleStrlen(const CHAR * s);
IMPORT_EXPORT_VMM UINT32
-VmFuncVmxCompatibleWcslen(const wchar_t * s);
+VmFuncVmxCompatibleWcslen(const WCHAR * s);
IMPORT_EXPORT_VMM VOID
VmFuncVmxCompatibleMicroSleep(UINT64 us);
@@ -207,6 +265,15 @@ VmFuncVmxGetCurrentExecutionMode();
IMPORT_EXPORT_VMM BOOLEAN
VmFuncQueryModeExecTrap();
+IMPORT_EXPORT_VMM BOOLEAN
+VmFuncCheckCpuSupportForSaveAndLoadDebugControls();
+
+IMPORT_EXPORT_VMM BOOLEAN
+VmFuncQueryInstrumentationStepInState(UINT32 CoreId);
+
+IMPORT_EXPORT_VMM BOOLEAN
+VmFuncCheckCpuSupportForLoadAndClearGuestIa32LbrCtlControls();
+
IMPORT_EXPORT_VMM INT32
VmFuncVmxCompatibleStrcmp(const CHAR * Address1, const CHAR * Address2);
@@ -214,13 +281,13 @@ IMPORT_EXPORT_VMM INT32
VmFuncVmxCompatibleStrncmp(const CHAR * Address1, const CHAR * Address2, SIZE_T Num);
IMPORT_EXPORT_VMM INT32
-VmFuncVmxCompatibleWcscmp(const wchar_t * Address1, const wchar_t * Address2);
+VmFuncVmxCompatibleWcscmp(const WCHAR * Address1, const WCHAR * Address2);
IMPORT_EXPORT_VMM INT32
-VmFuncVmxCompatibleWcsncmp(const wchar_t * Address1, const wchar_t * Address2, SIZE_T Num);
+VmFuncVmxCompatibleWcsncmp(const WCHAR * Address1, const WCHAR * Address2, SIZE_T Num);
IMPORT_EXPORT_VMM INT32
-VmFuncVmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, size_t Count);
+VmFuncVmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, SIZE_T Count);
IMPORT_EXPORT_VMM BOOLEAN
VmFuncApicStoreLocalApicFields(PLAPIC_PAGE LocalApicBuffer, PBOOLEAN IsUsingX2APIC);
@@ -692,25 +759,6 @@ ReadPhysicalMemoryUsingMapIoSpace(PVOID PhysicalAddress, PVOID Buffer, SIZE_T Bu
IMPORT_EXPORT_VMM BOOLEAN
WritePhysicalMemoryUsingMapIoSpace(PVOID PhysicalAddress, PVOID Buffer, SIZE_T BufferSize);
-//////////////////////////////////////////////////
-// Pool Manager //
-//////////////////////////////////////////////////
-
-IMPORT_EXPORT_VMM BOOLEAN
-PoolManagerCheckAndPerformAllocationAndDeallocation();
-
-IMPORT_EXPORT_VMM BOOLEAN
-PoolManagerRequestAllocation(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention);
-
-IMPORT_EXPORT_VMM UINT64
-PoolManagerRequestPool(POOL_ALLOCATION_INTENTION Intention, BOOLEAN RequestNewPool, UINT32 Size);
-
-IMPORT_EXPORT_VMM BOOLEAN
-PoolManagerFreePool(UINT64 AddressToFree);
-
-IMPORT_EXPORT_VMM VOID
-PoolManagerShowPreAllocatedPools();
-
//////////////////////////////////////////////////
// VMX Registers Modification //
//////////////////////////////////////////////////
diff --git a/hyperdbg/include/SDK/imports/user/HyperDbgLibImports.h b/hyperdbg/include/SDK/imports/user/HyperDbgLibImports.h
index 8ae491ac..2491fca1 100644
--- a/hyperdbg/include/SDK/imports/user/HyperDbgLibImports.h
+++ b/hyperdbg/include/SDK/imports/user/HyperDbgLibImports.h
@@ -1,6 +1,7 @@
/**
* @file HyperDbgLibImports.h
* @author Sina Karvandi (sina@hyperdbg.org)
+ * @author jtaw5649
* @brief Headers relating exported functions from controller interface
* @version 0.2
* @date 2023-02-02
@@ -10,12 +11,21 @@
*/
#pragma once
-#ifdef HYPERDBG_LIBHYPERDBG
-# define IMPORT_EXPORT_LIBHYPERDBG __declspec(dllexport)
+#ifdef _WIN32
+// MSVC (Windows)
+# ifdef HYPERDBG_LIBHYPERDBG
+# define IMPORT_EXPORT_LIBHYPERDBG __declspec(dllexport)
+# else
+# define IMPORT_EXPORT_LIBHYPERDBG __declspec(dllimport)
+# endif
#else
-# define IMPORT_EXPORT_LIBHYPERDBG __declspec(dllimport)
+// GCC/Clang (Linux)
+# ifdef HYPERDBG_LIBHYPERDBG
+# define IMPORT_EXPORT_LIBHYPERDBG __attribute__((visibility("default")))
+# else
+# define IMPORT_EXPORT_LIBHYPERDBG
+# endif
#endif
-
//
// Header file of libhyperdbg
// Imports
@@ -33,6 +43,21 @@ hyperdbg_u_detect_vmx_support();
IMPORT_EXPORT_LIBHYPERDBG VOID
hyperdbg_u_read_vendor_string(CHAR *);
+IMPORT_EXPORT_LIBHYPERDBG GENERIC_PROCESSOR_VENDOR
+hyperdbg_u_get_processor_vendor();
+
+//
+// All Modules
+//
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_is_any_module_loaded();
+
+IMPORT_EXPORT_LIBHYPERDBG INT
+hyperdbg_u_load_all_modules();
+
+IMPORT_EXPORT_LIBHYPERDBG INT
+hyperdbg_u_unload_all_modules();
+
//
// VMM Module
//
@@ -42,14 +67,35 @@ hyperdbg_u_load_vmm();
IMPORT_EXPORT_LIBHYPERDBG INT
hyperdbg_u_unload_vmm();
+//
+// KD (Kernel Debugger) Module
+//
IMPORT_EXPORT_LIBHYPERDBG INT
-hyperdbg_u_install_vmm_driver();
+hyperdbg_u_unload_kd();
IMPORT_EXPORT_LIBHYPERDBG INT
-hyperdbg_u_uninstall_vmm_driver();
+hyperdbg_u_install_kd_driver();
IMPORT_EXPORT_LIBHYPERDBG INT
-hyperdbg_u_stop_vmm_driver();
+hyperdbg_u_uninstall_kd_driver();
+
+IMPORT_EXPORT_LIBHYPERDBG INT
+hyperdbg_u_start_kd_driver();
+
+IMPORT_EXPORT_LIBHYPERDBG INT
+hyperdbg_u_stop_kd_driver();
+
+IMPORT_EXPORT_LIBHYPERDBG INT
+hyperdbg_u_load_kd_module();
+
+//
+// HyperTrace Module
+//
+IMPORT_EXPORT_LIBHYPERDBG INT
+hyperdbg_u_load_hypertrace_module();
+
+IMPORT_EXPORT_LIBHYPERDBG INT
+hyperdbg_u_unload_hypertrace_module();
//
// Testing parser
@@ -249,6 +295,30 @@ hyperdbg_u_get_io_apic(IO_APIC_ENTRY_PACKETS * io_apic);
IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
hyperdbg_u_get_idt_entry(INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS * idt_packet);
+//
+// SMM related command
+// Exported functionality of the '!smi' command
+//
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_perform_smi_operation(SMI_OPERATION_PACKETS * SmiOperation);
+
+//
+// LBR related command
+// Exported functionality of the '!lbrdump' command
+//
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_lbr_dump(HYPERTRACE_LBR_DUMP_PACKETS * LbrdumpRequest);
+
+//
+// Intel PT related commands
+// Exported functionality of the '!pt' command + the PT mmap surface
+//
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_pt_operation(HYPERTRACE_PT_OPERATION_PACKETS * PtRequest);
+
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_pt_mmap(HYPERTRACE_PT_MMAP_PACKETS * MmapRequest);
+
//
// Transparent mode related command
// Exported functionality of the '!hide', and '!unhide' commands
@@ -256,6 +326,9 @@ hyperdbg_u_get_idt_entry(INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS * idt_packet
IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
hyperdbg_u_enable_transparent_mode(UINT32 ProcessId, CHAR * ProcessName, BOOLEAN IsProcessId);
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_enable_transparent_mode_ex(UINT32 ProcessId, CHAR * ProcessName, BOOLEAN IsProcessId, UINT32 EvadeMask);
+
IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
hyperdbg_u_disable_transparent_mode();
@@ -279,9 +352,18 @@ hwdbg_script_run_script(const CHAR * script,
const CHAR * hardware_script_file_path_to_save,
UINT32 initial_bram_buffer_size);
-VOID
+IMPORT_EXPORT_LIBHYPERDBG VOID
hwdbg_script_engine_wrapper_test_parser(const CHAR * Expr);
+//
+// Run script and evaluate expression
+//
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_run_script(CHAR * Expr, BOOLEAN ShowErrorMessageIfAny);
+
+IMPORT_EXPORT_LIBHYPERDBG UINT64
+hyperdbg_u_eval_expression(CHAR * Expr, PBOOLEAN HasError);
+
#ifdef __cplusplus
}
#endif
diff --git a/hyperdbg/include/SDK/imports/user/HyperDbgScriptImports.h b/hyperdbg/include/SDK/imports/user/HyperDbgScriptImports.h
index 29f188fc..1e31f6d7 100644
--- a/hyperdbg/include/SDK/imports/user/HyperDbgScriptImports.h
+++ b/hyperdbg/include/SDK/imports/user/HyperDbgScriptImports.h
@@ -10,10 +10,20 @@
*/
#pragma once
-#ifdef HYPERDBG_SCRIPT_ENGINE
-# define IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE __declspec(dllexport)
+#ifdef _WIN32
+ // MSVC (Windows)
+# ifdef HYPERDBG_SCRIPT_ENGINE
+# define IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE __declspec(dllexport)
+# else
+# define IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE __declspec(dllimport)
+# endif
#else
-# define IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE __declspec(dllimport)
+ // GCC/Clang (Linux)
+# ifdef HYPERDBG_SCRIPT_ENGINE
+# define IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE __attribute__((visibility("default")))
+# else
+# define IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE
+# endif
#endif
//
@@ -40,53 +50,53 @@ HardwareScriptInterpreterCheckScriptBufferWithScriptCapabilities(HWDBG_INSTANCE_
IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE BOOLEAN
HardwareScriptInterpreterCompressBuffer(UINT64 * Buffer,
- size_t BufferLength,
+ SIZE_T BufferLength,
UINT32 ScriptVariableLength,
UINT32 BramDataWidth,
- size_t * NewBufferSize,
- size_t * NumberOfBytesPerChunk);
+ SIZE_T * NewBufferSize,
+ SIZE_T * NumberOfBytesPerChunk);
IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE BOOLEAN
HardwareScriptInterpreterConvertSymbolToHwdbgShortSymbolBuffer(
HWDBG_INSTANCE_INFORMATION * InstanceInfo,
SYMBOL * SymbolBuffer,
- size_t SymbolBufferLength,
+ SIZE_T SymbolBufferLength,
UINT32 NumberOfStages,
HWDBG_SHORT_SYMBOL ** NewShortSymbolBuffer,
- size_t * NewBufferSize);
+ SIZE_T * NewBufferSize);
IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE VOID
HardwareScriptInterpreterFreeHwdbgShortSymbolBuffer(HWDBG_SHORT_SYMBOL * NewShortSymbolBuffer);
IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE PVOID
-ScriptEngineParse(char * str);
+ScriptEngineParse(CHAR * Str);
IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE BOOLEAN
ScriptEngineSetHwdbgInstanceInfo(HWDBG_INSTANCE_INFORMATION * InstancInfo);
-IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE void
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE VOID
PrintSymbolBuffer(const PVOID SymbolBuffer);
-IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE void
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE VOID
RemoveSymbolBuffer(PVOID SymbolBuffer);
-IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE void
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE VOID
PrintSymbol(PVOID Symbol);
IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE UINT64
-ScriptEngineConvertNameToAddress(const char * FunctionOrVariableName, PBOOLEAN WasFound);
+ScriptEngineConvertNameToAddress(const CHAR * FunctionOrVariableName, PBOOLEAN WasFound);
IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE UINT32
-ScriptEngineLoadFileSymbol(UINT64 BaseAddress, const char * PdbFileName, const char * CustomModuleName);
+ScriptEngineLoadFileSymbol(UINT64 BaseAddress, const CHAR * PdbFileName, const CHAR * CustomModuleName);
IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE UINT32
ScriptEngineUnloadAllSymbols();
IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE UINT32
-ScriptEngineUnloadModuleSymbol(char * ModuleName);
+ScriptEngineUnloadModuleSymbol(CHAR * ModuleName);
IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE UINT32
-ScriptEngineSearchSymbolForMask(const char * SearchMask);
+ScriptEngineSearchSymbolForMask(const CHAR * SearchMask);
IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE BOOLEAN
ScriptEngineGetFieldOffset(CHAR * TypeName, CHAR * FieldName, UINT32 * FieldOffset);
@@ -95,19 +105,27 @@ IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE BOOLEAN
ScriptEngineGetDataTypeSize(CHAR * TypeName, UINT64 * TypeSize);
IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE BOOLEAN
-ScriptEngineCreateSymbolTableForDisassembler(void * CallbackFunction);
+ScriptEngineCreateSymbolTableForDisassembler(PVOID CallbackFunction);
IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE BOOLEAN
-ScriptEngineConvertFileToPdbPath(const char * LocalFilePath, char * ResultPath, size_t ResultPathSize);
+ScriptEngineConvertFileToPdbPath(const CHAR * LocalFilePath, CHAR * ResultPath, SIZE_T ResultPathSize);
IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE BOOLEAN
-ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetails(const char * LocalFilePath, char * PdbFilePath, char * GuidAndAgeDetails, BOOLEAN Is32BitModule);
+ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetails(const CHAR * LocalFilePath, CHAR * PdbFilePath, CHAR * GuidAndAgeDetails, BOOLEAN Is32BitModule);
IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE BOOLEAN
-ScriptEngineSymbolInitLoad(PVOID BufferToStoreDetails, UINT32 StoredLength, BOOLEAN DownloadIfAvailable, const char * SymbolPath, BOOLEAN IsSilentLoad);
+ScriptEngineConvertLoadedModuleToPdbFileAndGuidAndAgeDetails(const BYTE * LoadedImageBytes,
+ SIZE_T LoadedImageSize,
+ const CHAR * LocalFilePath,
+ CHAR * PdbFilePath,
+ CHAR * GuidAndAgeDetails,
+ BOOLEAN Is32BitModule);
IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE BOOLEAN
-ScriptEngineShowDataBasedOnSymbolTypes(const char * TypeName, UINT64 Address, BOOLEAN IsStruct, PVOID BufferAddress, const char * AdditionalParameters);
+ScriptEngineSymbolInitLoad(PVOID BufferToStoreDetails, UINT32 StoredLength, BOOLEAN DownloadIfAvailable, const CHAR * SymbolPath, BOOLEAN IsSilentLoad);
+
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE BOOLEAN
+ScriptEngineShowDataBasedOnSymbolTypes(const CHAR * TypeName, UINT64 Address, BOOLEAN IsStruct, PVOID BufferAddress, const CHAR * AdditionalParameters);
IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE VOID
ScriptEngineSymbolAbortLoading();
diff --git a/hyperdbg/include/SDK/imports/user/HyperDbgSymImports.h b/hyperdbg/include/SDK/imports/user/HyperDbgSymImports.h
index 98d97b53..c5059cab 100644
--- a/hyperdbg/include/SDK/imports/user/HyperDbgSymImports.h
+++ b/hyperdbg/include/SDK/imports/user/HyperDbgSymImports.h
@@ -10,10 +10,20 @@
*/
#pragma once
-#ifdef HYPERDBG_SYMBOL_PARSER
-# define IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER __declspec(dllexport)
+#ifdef _WIN32
+ // MSVC (Windows)
+# ifdef HYPERDBG_SYMBOL_PARSER
+# define IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER __declspec(dllexport)
+# else
+# define IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER __declspec(dllimport)
+# endif
#else
-# define IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER __declspec(dllimport)
+ // GCC/Clang (Linux)
+# ifdef HYPERDBG_SYMBOL_PARSER
+# define IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER __attribute__((visibility("default")))
+# else
+# define IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER
+# endif
#endif
//
@@ -31,19 +41,19 @@ IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER VOID
SymbolAbortLoading();
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER UINT64
-SymConvertNameToAddress(const char * FunctionOrVariableName, PBOOLEAN WasFound);
+SymConvertNameToAddress(const CHAR * FunctionOrVariableName, PBOOLEAN WasFound);
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER UINT32
-SymLoadFileSymbol(UINT64 BaseAddress, const char * PdbFileName, const char * CustomModuleName);
+SymLoadFileSymbol(UINT64 BaseAddress, const CHAR * PdbFileName, const CHAR * CustomModuleName);
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER UINT32
SymUnloadAllSymbols();
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER UINT32
-SymUnloadModuleSymbol(char * ModuleName);
+SymUnloadModuleSymbol(CHAR * ModuleName);
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER UINT32
-SymSearchSymbolForMask(const char * SearchMask);
+SymSearchSymbolForMask(const CHAR * SearchMask);
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN
SymGetFieldOffset(CHAR * TypeName, CHAR * FieldName, UINT32 * FieldOffset);
@@ -52,39 +62,47 @@ IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN
SymGetDataTypeSize(CHAR * TypeName, UINT64 * TypeSize);
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN
-SymCreateSymbolTableForDisassembler(void * CallbackFunction);
+SymCreateSymbolTableForDisassembler(PVOID CallbackFunction);
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN
-SymConvertFileToPdbPath(const char * LocalFilePath, char * ResultPath, size_t ResultPathSize);
+SymConvertFileToPdbPath(const CHAR * LocalFilePath, CHAR * ResultPath, SIZE_T ResultPathSize);
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN
-SymConvertFileToPdbFileAndGuidAndAgeDetails(const char * LocalFilePath,
- char * PdbFilePath,
- char * GuidAndAgeDetails,
+SymConvertFileToPdbFileAndGuidAndAgeDetails(const CHAR * LocalFilePath,
+ CHAR * PdbFilePath,
+ CHAR * GuidAndAgeDetails,
BOOLEAN Is32BitModule);
+IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN
+SymConvertLoadedModuleToPdbFileAndGuidAndAgeDetails(const BYTE * LoadedImageBytes,
+ SIZE_T LoadedImageSize,
+ const CHAR * LocalFilePath,
+ CHAR * PdbFilePath,
+ CHAR * GuidAndAgeDetails,
+ BOOLEAN Is32BitModule);
+
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN
SymbolInitLoad(PVOID BufferToStoreDetails,
UINT32 StoredLength,
BOOLEAN DownloadIfAvailable,
- const char * SymbolPath,
+ const CHAR * SymbolPath,
BOOLEAN IsSilentLoad);
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN
-SymShowDataBasedOnSymbolTypes(const char * TypeName,
+SymShowDataBasedOnSymbolTypes(const CHAR * TypeName,
UINT64 Address,
BOOLEAN IsStruct,
PVOID BufferAddress,
- const char * AdditionalParameters);
+ const CHAR * AdditionalParameters);
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN
-SymQuerySizeof(_In_ const char * StructNameOrTypeName, _Out_ UINT32 * SizeOfField);
+SymQuerySizeof(_In_ const CHAR * StructNameOrTypeName, _Out_ UINT32 * SizeOfField);
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN
-SymCastingQueryForFiledsAndTypes(_In_ const char * StructName,
- _In_ const char * FiledOfStructName,
+SymCastingQueryForFiledsAndTypes(_In_ const CHAR * StructName,
+ _In_ const CHAR * FiledOfStructName,
_Out_ PBOOLEAN IsStructNamePointerOrNot,
_Out_ PBOOLEAN IsFiledOfStructNamePointerOrNot,
- _Out_ char ** NewStructOrTypeName,
+ _Out_ CHAR ** NewStructOrTypeName,
_Out_ UINT32 * OffsetOfFieldFromTop,
_Out_ UINT32 * SizeOfField);
diff --git a/hyperdbg/include/SDK/modules/HyperEvade.h b/hyperdbg/include/SDK/modules/HyperEvade.h
index b1368348..e09c7e0a 100644
--- a/hyperdbg/include/SDK/modules/HyperEvade.h
+++ b/hyperdbg/include/SDK/modules/HyperEvade.h
@@ -2,7 +2,7 @@
* @file HyperEvade.h
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief HyperDbg's SDK for hyperevade project
- * @details This file contains definitions of HyperLog routines
+ * @details This file contains definitions of HyperEvade routines
* @version 0.14
* @date 2025-06-07
*
@@ -24,7 +24,7 @@ typedef BOOLEAN (*LOG_CALLBACK_PREPARE_AND_SEND_MESSAGE_TO_QUEUE)(UINT32 O
BOOLEAN IsImmediateMessage,
BOOLEAN ShowCurrentSystemTime,
BOOLEAN Priority,
- const char * Fmt,
+ const CHAR * Fmt,
va_list ArgList);
/**
@@ -48,6 +48,12 @@ typedef BOOLEAN (*LOG_CALLBACK_SEND_BUFFER)(_In_ UINT32
*/
typedef BOOLEAN (*LOG_CALLBACK_CHECK_IF_BUFFER_IS_FULL)(BOOLEAN Priority);
+/**
+ * @brief A function that checks if LBR is supported on the current CPU and gets its capacity
+ *
+ */
+typedef BOOLEAN (*HYPERTRACE_LBR_IS_SUPPORTED)(UINT32 * Capacity, BOOLEAN * IsArchLbr);
+
/**
* @brief A function that checks the validity and safety of the target address
*
@@ -112,6 +118,11 @@ typedef struct _HYPEREVADE_CALLBACKS
LOG_CALLBACK_SEND_BUFFER LogCallbackSendBuffer;
LOG_CALLBACK_CHECK_IF_BUFFER_IS_FULL LogCallbackCheckIfBufferIsFull;
+ //
+ // HyperTrace callback(s)
+ //
+ HYPERTRACE_LBR_IS_SUPPORTED HyperTraceLbrIsSupported;
+
//
// *** HYPEREVADE callbacks ***
//
diff --git a/hyperdbg/include/SDK/modules/HyperPerf.h b/hyperdbg/include/SDK/modules/HyperPerf.h
new file mode 100644
index 00000000..fe76e097
--- /dev/null
+++ b/hyperdbg/include/SDK/modules/HyperPerf.h
@@ -0,0 +1,80 @@
+/**
+ * @file HyperPerf.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief HyperDbg's SDK for hyperperf project
+ * @details This file contains definitions of HyperPerf routines
+ * @version 0.21
+ * @date 2026-06-22
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Callback Types //
+//////////////////////////////////////////////////
+
+/**
+ * @brief A function from the message tracer that send the inputs to the
+ * queue of the messages
+ *
+ */
+typedef BOOLEAN (*LOG_CALLBACK_PREPARE_AND_SEND_MESSAGE_TO_QUEUE)(UINT32 OperationCode,
+ BOOLEAN IsImmediateMessage,
+ BOOLEAN ShowCurrentSystemTime,
+ BOOLEAN Priority,
+ const CHAR * Fmt,
+ va_list ArgList);
+
+/**
+ * @brief A function that sends the messages to message tracer buffers
+ *
+ */
+typedef BOOLEAN (*LOG_CALLBACK_SEND_MESSAGE_TO_QUEUE)(UINT32 OperationCode, BOOLEAN IsImmediateMessage, CHAR * LogMessage, UINT32 BufferLen, BOOLEAN Priority);
+
+/**
+ * @brief A function that sends the messages to message tracer buffers
+ *
+ */
+typedef BOOLEAN (*LOG_CALLBACK_SEND_BUFFER)(_In_ UINT32 OperationCode,
+ _In_reads_bytes_(BufferLength) PVOID Buffer,
+ _In_ UINT32 BufferLength,
+ _In_ BOOLEAN Priority);
+
+/**
+ * @brief A function that checks whether the priority or regular buffer is full or not
+ *
+ */
+typedef BOOLEAN (*LOG_CALLBACK_CHECK_IF_BUFFER_IS_FULL)(BOOLEAN Priority);
+
+/**
+ * @brief A function that checks whether the current execution mode is VMX-root mode or not
+ *
+ */
+typedef BOOLEAN (*VM_FUNC_VMX_GET_CURRENT_EXECUTION_MODE)();
+
+//////////////////////////////////////////////////
+// Callback Structure //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Prototype of each function needed by hyperperf module
+ *
+ */
+typedef struct _HYPERPERF_CALLBACKS
+{
+ //
+ // *** Log (Hyperlog) callbacks ***
+ //
+ LOG_CALLBACK_PREPARE_AND_SEND_MESSAGE_TO_QUEUE LogCallbackPrepareAndSendMessageToQueueWrapper;
+ LOG_CALLBACK_SEND_MESSAGE_TO_QUEUE LogCallbackSendMessageToQueue;
+ LOG_CALLBACK_SEND_BUFFER LogCallbackSendBuffer;
+ LOG_CALLBACK_CHECK_IF_BUFFER_IS_FULL LogCallbackCheckIfBufferIsFull;
+
+ //
+ // *** Hypervisor (Hyperhv) callbacks ***
+ //
+ VM_FUNC_VMX_GET_CURRENT_EXECUTION_MODE VmFuncVmxGetCurrentExecutionMode;
+
+} HYPERPERF_CALLBACKS, *PHYPERPERF_CALLBACKS;
diff --git a/hyperdbg/include/SDK/modules/HyperTrace.h b/hyperdbg/include/SDK/modules/HyperTrace.h
new file mode 100644
index 00000000..17ace198
--- /dev/null
+++ b/hyperdbg/include/SDK/modules/HyperTrace.h
@@ -0,0 +1,255 @@
+/**
+ * @file HyperTrace.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief HyperDbg's SDK for hypertrace project
+ * @details This file contains definitions of HyperTrace routines
+ * @version 0.14
+ * @date 2025-06-07
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Callback Types //
+//////////////////////////////////////////////////
+
+/**
+ * @brief A function from the message tracer that send the inputs to the
+ * queue of the messages
+ *
+ */
+typedef BOOLEAN (*LOG_CALLBACK_PREPARE_AND_SEND_MESSAGE_TO_QUEUE)(UINT32 OperationCode,
+ BOOLEAN IsImmediateMessage,
+ BOOLEAN ShowCurrentSystemTime,
+ BOOLEAN Priority,
+ const CHAR * Fmt,
+ va_list ArgList);
+
+/**
+ * @brief A function that sends the messages to message tracer buffers
+ *
+ */
+typedef BOOLEAN (*LOG_CALLBACK_SEND_MESSAGE_TO_QUEUE)(UINT32 OperationCode, BOOLEAN IsImmediateMessage, CHAR * LogMessage, UINT32 BufferLen, BOOLEAN Priority);
+
+/**
+ * @brief A function that sends the messages to message tracer buffers
+ *
+ */
+typedef BOOLEAN (*LOG_CALLBACK_SEND_BUFFER)(_In_ UINT32 OperationCode,
+ _In_reads_bytes_(BufferLength) PVOID Buffer,
+ _In_ UINT32 BufferLength,
+ _In_ BOOLEAN Priority);
+
+/**
+ * @brief A function that checks whether the priority or regular buffer is full or not
+ *
+ */
+typedef BOOLEAN (*LOG_CALLBACK_CHECK_IF_BUFFER_IS_FULL)(BOOLEAN Priority);
+
+/**
+ * @brief A function that gets the guest state of IA32_DEBUGCTL
+ */
+typedef UINT64 (*VM_FUNC_GET_DEBUGCTL)();
+
+/**
+ * @brief A function that gets the guest state of IA32_DEBUGCTL on the target core using VMCALL
+ */
+typedef UINT64 (*VM_FUNC_GET_DEBUGCTL_VMCALL_ON_TARGET_CORE)();
+
+/**
+ * @brief A function that gets the guest state of IA32_LBR_CTL
+ */
+typedef UINT64 (*VM_FUNC_GET_GUEST_IA32_LBR_CTL)();
+
+/**
+ * @brief A function that gets the guest state of IA32_LBR_CTL on the target core using VMCALL
+ */
+typedef UINT64 (*VM_FUNC_GET_GUEST_IA32_LBR_CTL_VMCALL_ON_TARGET_CORE)();
+
+/**
+ * @brief A function that gets the guest state of IA32_DEBUGCTL
+ *
+ */
+typedef VOID (*VM_FUNC_SET_DEBUGCTL)(UINT64 Value);
+
+/**
+ * @brief A function that gets the guest state of IA32_DEBUGCTL on the target core using VMCALL
+ *
+ */
+typedef VOID (*VM_FUNC_SET_DEBUGCTL_VMCALL_ON_TARGET_CORE)(UINT64 Value);
+
+/**
+ * @brief A function that sets guest IA32_LBR_CTL
+ *
+ */
+typedef VOID (*VM_FUNC_SET_GUEST_IA32_LBR_CTL)(UINT64 Value);
+
+/**
+ * @brief A function that sets guest IA32_LBR_CTL on the target core using VMCALL
+ *
+ */
+typedef VOID (*VM_FUNC_SET_GUEST_IA32_LBR_CTL_VMCALL_ON_TARGET_CORE)(UINT64 Value);
+
+/**
+ * @brief A function that set MSR_LEGACY_LBR_SELECT
+ *
+ */
+typedef VOID (*VM_FUNC_SET_LBR_SELECT)(UINT64 FilterOptions);
+
+/**
+ * @brief A function that set MSR_LEGACY_LBR_SELECT on the target core using VMCALL
+ *
+ */
+typedef VOID (*VM_FUNC_SET_LBR_SELECT_VMCALL_ON_TARGET_CORE)(UINT64 FilterOptions);
+
+/**
+ * @brief A function that checks whether IA32_DEBUGCTL can be used in load and save of exit and entry controls
+ *
+ */
+typedef BOOLEAN (*VM_FUNC_CHECK_CPU_SUPPORT_FOR_SAVE_AND_LOAD_DEBUG_CONTROLS)();
+
+/**
+ * @brief A function that checks whether guest IA32_LBR_CTL can be used in load and clear of guest IA32_LBR_CTL controls
+ *
+ */
+typedef BOOLEAN (*VM_FUNC_CHECK_CPU_SUPPORT_FOR_LOAD_AND_CLEAR_GUEST_IA32_LBR_CTL_CONTROLS)();
+
+/**
+ * @brief A function that sets load debug controls on VM-entry controls
+ *
+ */
+typedef VOID (*VM_FUNC_SET_LOAD_DEBUG_CONTROLS)(UINT32 CoreId, BOOLEAN Set);
+
+/**
+ * @brief A function that sets load debug controls on VM-entry controls on the target core from VMCS using VMCALL
+ *
+ */
+typedef VOID (*VM_FUNC_SET_LOAD_DEBUG_CONTROLS_VMCALL_ON_TARGET_CORE)(BOOLEAN Set);
+
+/**
+ * @brief A function that sets load guest IA32_LBR_CTL on VM-entry controls
+ *
+ */
+typedef VOID (*VM_FUNC_SET_LOAD_GUEST_IA32_LBR_CTL)(UINT32 CoreId, BOOLEAN Set);
+
+/**
+ * @brief A function that sets load guest IA32_LBR_CTL on VM-entry controls on the target core from VMCS using VMCALL
+ *
+ */
+typedef VOID (*VM_FUNC_SET_LOAD_GUEST_IA32_LBR_CTL_VMCALL_ON_TARGET_CORE)(BOOLEAN Set);
+
+/**
+ * @brief A function that sets save debug controls on VM-exit controls
+ *
+ */
+typedef VOID (*VM_FUNC_SET_SAVE_DEBUG_CONTROLS)(UINT32 CoreId, BOOLEAN Set);
+
+/**
+ * @brief A function that sets save debug controls on VM-exit controls on the target core from VMCS using VMCALL
+ *
+ */
+typedef VOID (*VM_FUNC_SET_SAVE_DEBUG_CONTROLS_VMCALL_ON_TARGET_CORE)(BOOLEAN Set);
+
+/**
+ * @brief A function that sets clear guest IA32_LBR_CTL on VM-exit controls
+ *
+ */
+typedef VOID (*VM_FUNC_SET_CLEAR_GUEST_IA32_LBR_CTL)(UINT32 CoreId, BOOLEAN Set);
+
+/**
+ * @brief A function that sets clear guest IA32_LBR_CTL on VM-exit controls on the target core from VMCS using VMCALL
+ *
+ */
+typedef VOID (*VM_FUNC_SET_CLEAR_GUEST_IA32_LBR_CTL_VMCALL_ON_TARGET_CORE)(BOOLEAN Set);
+
+/**
+ * @brief A function that checks whether the current execution mode is VMX-root mode or not
+ *
+ */
+typedef BOOLEAN (*VM_FUNC_VMX_GET_CURRENT_EXECUTION_MODE)();
+
+/**
+ * @brief A function that checks the validity and safety of the target address
+ *
+ */
+typedef BOOLEAN (*CHECK_ACCESS_VALIDITY_AND_SAFETY)(UINT64 TargetAddress, UINT32 Size);
+
+/**
+ * @brief A function that reads memory safely on the target process
+ *
+ */
+typedef BOOLEAN (*MEMORY_MAPPER_READ_MEMORY_SAFE_ON_TARGET_PROCESS)(UINT64 VaAddressToRead, PVOID BufferToSaveMemory, SIZE_T SizeToRead);
+
+/**
+ * @brief A function that writes memory safely on the target process
+ *
+ */
+typedef BOOLEAN (*MEMORY_MAPPER_WRITE_MEMORY_SAFE_ON_TARGET_PROCESS)(UINT64 Destination, PVOID Source, SIZE_T Size);
+
+/**
+ * @brief A function that gets the process name from the process control block
+ *
+ */
+typedef PCHAR (*COMMON_GET_PROCESS_NAME_FROM_PROCESS_CONTROL_BLOCK)(PVOID Eprocess);
+
+//////////////////////////////////////////////////
+// Callback Structure //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Prototype of each function needed by hypertrace module
+ *
+ */
+typedef struct _HYPERTRACE_CALLBACKS
+{
+ //
+ // *** Log (Hyperlog) callbacks ***
+ //
+ LOG_CALLBACK_PREPARE_AND_SEND_MESSAGE_TO_QUEUE LogCallbackPrepareAndSendMessageToQueueWrapper;
+ LOG_CALLBACK_SEND_MESSAGE_TO_QUEUE LogCallbackSendMessageToQueue;
+ LOG_CALLBACK_SEND_BUFFER LogCallbackSendBuffer;
+ LOG_CALLBACK_CHECK_IF_BUFFER_IS_FULL LogCallbackCheckIfBufferIsFull;
+
+ //
+ // *** Hypervisor (Hyperhv) callbacks ***
+ //
+ VM_FUNC_VMX_GET_CURRENT_EXECUTION_MODE VmFuncVmxGetCurrentExecutionMode;
+
+ //
+ // *** Legacy LBR callbacks ***
+ //
+
+ VM_FUNC_CHECK_CPU_SUPPORT_FOR_SAVE_AND_LOAD_DEBUG_CONTROLS VmFuncCheckCpuSupportForSaveAndLoadDebugControls;
+
+ VM_FUNC_GET_DEBUGCTL VmFuncGetDebugctl;
+ VM_FUNC_GET_DEBUGCTL_VMCALL_ON_TARGET_CORE VmFuncGetDebugctlVmcallOnTargetCore;
+ VM_FUNC_SET_DEBUGCTL VmFuncSetDebugctl;
+ VM_FUNC_SET_DEBUGCTL_VMCALL_ON_TARGET_CORE VmFuncSetDebugctlVmcallOnTargetCore;
+
+ VM_FUNC_SET_LOAD_DEBUG_CONTROLS VmFuncSetLoadDebugControls;
+ VM_FUNC_SET_LOAD_DEBUG_CONTROLS_VMCALL_ON_TARGET_CORE VmFuncSetLoadDebugControlsVmcallOnTargetCore;
+ VM_FUNC_SET_SAVE_DEBUG_CONTROLS VmFuncSetSaveDebugControls;
+ VM_FUNC_SET_SAVE_DEBUG_CONTROLS_VMCALL_ON_TARGET_CORE VmFuncSetSaveDebugControlsVmcallOnTargetCore;
+
+ VM_FUNC_SET_LBR_SELECT VmFuncSetLbrSelect;
+ VM_FUNC_SET_LBR_SELECT_VMCALL_ON_TARGET_CORE VmFuncSetLbrSelectVmcallOnTargetCore;
+
+ //
+ // *** Architectural LBR callbacks ***
+ //
+
+ VM_FUNC_CHECK_CPU_SUPPORT_FOR_LOAD_AND_CLEAR_GUEST_IA32_LBR_CTL_CONTROLS VmFuncCheckCpuSupportForLoadAndClearGuestIa32LbrCtlControls;
+
+ VM_FUNC_GET_GUEST_IA32_LBR_CTL VmFuncGetGuestIa32LbrCtl;
+ VM_FUNC_GET_GUEST_IA32_LBR_CTL_VMCALL_ON_TARGET_CORE VmFuncGetGuestIa32LbrCtlVmcallOnTargetCore;
+ VM_FUNC_SET_GUEST_IA32_LBR_CTL VmFuncSetGuestIa32LbrCtl;
+ VM_FUNC_SET_GUEST_IA32_LBR_CTL_VMCALL_ON_TARGET_CORE VmFuncSetGuestIa32LbrCtlVmcallOnTargetCore;
+
+ VM_FUNC_SET_LOAD_GUEST_IA32_LBR_CTL VmFuncSetLoadGuestIa32LbrCtl;
+ VM_FUNC_SET_LOAD_GUEST_IA32_LBR_CTL_VMCALL_ON_TARGET_CORE VmFuncSetLoadGuestIa32LbrCtlVmcallOnTargetCore;
+ VM_FUNC_SET_CLEAR_GUEST_IA32_LBR_CTL VmFuncSetClearGuestIa32LbrCtl;
+ VM_FUNC_SET_CLEAR_GUEST_IA32_LBR_CTL_VMCALL_ON_TARGET_CORE VmFuncSetClearGuestIa32LbrCtlVmcallOnTargetCore;
+
+} HYPERTRACE_CALLBACKS, *PHYPERTRACE_CALLBACKS;
diff --git a/hyperdbg/include/SDK/modules/VMM.h b/hyperdbg/include/SDK/modules/VMM.h
index 89f3b9cd..d961d45c 100644
--- a/hyperdbg/include/SDK/modules/VMM.h
+++ b/hyperdbg/include/SDK/modules/VMM.h
@@ -2,7 +2,7 @@
* @file VMM.h
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief HyperDbg's SDK for VMM project
- * @details This file contains definitions of HyperLog routines
+ * @details This file contains definitions of VMM routines
* @version 0.2
* @date 2023-01-15
*
@@ -24,7 +24,7 @@ typedef BOOLEAN (*LOG_CALLBACK_PREPARE_AND_SEND_MESSAGE_TO_QUEUE)(UINT32 O
BOOLEAN IsImmediateMessage,
BOOLEAN ShowCurrentSystemTime,
BOOLEAN Priority,
- const char * Fmt,
+ const CHAR * Fmt,
va_list ArgList);
/**
@@ -48,6 +48,12 @@ typedef BOOLEAN (*LOG_CALLBACK_SEND_BUFFER)(_In_ UINT32
*/
typedef BOOLEAN (*LOG_CALLBACK_CHECK_IF_BUFFER_IS_FULL)(BOOLEAN Priority);
+/**
+ * @brief A function that checks if LBR is supported on the current CPU and gets its capacity
+ *
+ */
+typedef BOOLEAN (*HYPERTRACE_LBR_IS_SUPPORTED)(UINT32 * Capacity, BOOLEAN * IsArchLbr);
+
/**
* @brief A function that handles trigger events
*
@@ -77,16 +83,37 @@ typedef BOOLEAN (*DEBUGGING_CALLBACK_HANDLE_DEBUG_BREAKPOINT_EXCEPTION)(UINT32 C
typedef BOOLEAN (*DEBUGGING_CALLBACK_CHECK_THREAD_INTERCEPTION)(UINT32 CoreId);
/**
- * @brief Check for commands in user-debugger
+ * @brief Trigger on clock and IPI events for checking process or thread change
*
*/
-typedef BOOLEAN (*UD_CHECK_FOR_COMMAND)();
+typedef BOOLEAN (*DEBUGGING_CALLBACK_TRIGGER_ON_CLOCK_AND_IPI_EVENTS)(_In_ UINT32 CoreId);
/**
- * @brief Handle registered MTF callback
+ * @brief routine callback to ignore handling mov 2 debug registers
+ *
+ * @param CoreId
+ *
+ * @return BOOLEAN
+ */
+typedef BOOLEAN (*DEBUGGING_CALLBACK_IGNORE_HANDLING_MOV_2_DEBUG_REGS)(_In_ UINT32 CoreId);
+
+/**
+ * @brief Request pool allocation
*
*/
-typedef VOID (*VMM_CALLBACK_REGISTERED_MTF_HANDLER)(UINT32 CoreId);
+typedef BOOLEAN (*POOL_MANAGER_REQUEST_ALLOCATION)(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention);
+
+/**
+ * @brief Request pool
+ *
+ */
+typedef UINT64 (*POOL_MANAGER_REQUEST_POOL)(POOL_ALLOCATION_INTENTION Intention, BOOLEAN RequestNewPool, UINT32 Size);
+
+/**
+ * @brief Free pool
+ *
+ */
+typedef BOOLEAN (*POOL_MANAGER_FREE_POOL)(UINT64 AddressToFree);
/**
* @brief Check for user-mode access for loaded module details
@@ -100,36 +127,24 @@ typedef BOOLEAN (*VMM_CALLBACK_RESTORE_EPT_STATE)(UINT32 CoreId);
*/
typedef BOOLEAN (*VMM_CALLBACK_CHECK_UNHANDLED_EPT_VIOLATION)(UINT32 CoreId, UINT64 ViolationQualification, UINT64 GuestPhysicalAddr);
+/**
+ * @brief Handle MTF callback
+ *
+ */
+typedef BOOLEAN (*VMM_CALLBACK_HANDLE_MTF_CALLBACK)(UINT32 CoreId);
+
/**
* @brief Handle cr3 process change callbacks
*
*/
typedef VOID (*INTERCEPTION_CALLBACK_TRIGGER_CR3_CHANGE)(UINT32 CoreId);
-/**
- * @brief Check for process or thread change callback
- *
- */
-typedef BOOLEAN (*INTERCEPTION_CALLBACK_TRIGGER_CLOCK_AND_IPI)(_In_ UINT32 CoreId);
-
-/**
- * @brief Check and handle reapplying breakpoint
- *
- */
-typedef BOOLEAN (*BREAKPOINT_CHECK_AND_HANDLE_REAPPLYING_BREAKPOINT)(UINT32 CoreId);
-
/**
* @brief Handle NMI broadcast
*
*/
typedef VOID (*VMM_CALLBACK_NMI_BROADCAST_REQUEST_HANDLER)(UINT32 CoreId, BOOLEAN IsOnVmxNmiHandler);
-/**
- * @brief Check and handle NMI callbacks
- *
- */
-typedef BOOLEAN (*KD_CHECK_AND_HANDLE_NMI_CALLBACK)(UINT32 CoreId);
-
/**
* @brief Set the top-level driver's error status
*
@@ -145,12 +160,6 @@ typedef BOOLEAN (*VMM_CALLBACK_QUERY_TERMINATE_PROTECTED_RESOURCE)(UINT32
PVOID Context,
PROTECTED_HV_RESOURCES_PASSING_OVERS PassOver);
-/**
- * @brief Query debugger thread or process tracing details by core ID
- *
- */
-typedef BOOLEAN (*KD_QUERY_DEBUGGER_THREAD_OR_PROCESS_TRACING_DETAILS_BY_CORE_ID)(UINT32 CoreId,
- DEBUGGER_THREAD_PROCESS_TRACING TracingType);
/**
* @brief Handler of debugger specific VMCALLs
*
@@ -174,42 +183,47 @@ typedef struct _VMM_CALLBACKS
//
// Log (Hyperlog) callbacks
//
- LOG_CALLBACK_PREPARE_AND_SEND_MESSAGE_TO_QUEUE LogCallbackPrepareAndSendMessageToQueueWrapper; // Fixed
- LOG_CALLBACK_SEND_MESSAGE_TO_QUEUE LogCallbackSendMessageToQueue; // Fixed
- LOG_CALLBACK_SEND_BUFFER LogCallbackSendBuffer; // Fixed
- LOG_CALLBACK_CHECK_IF_BUFFER_IS_FULL LogCallbackCheckIfBufferIsFull; // Fixed
+ LOG_CALLBACK_PREPARE_AND_SEND_MESSAGE_TO_QUEUE LogCallbackPrepareAndSendMessageToQueueWrapper;
+ LOG_CALLBACK_SEND_MESSAGE_TO_QUEUE LogCallbackSendMessageToQueue;
+ LOG_CALLBACK_SEND_BUFFER LogCallbackSendBuffer;
+ LOG_CALLBACK_CHECK_IF_BUFFER_IS_FULL LogCallbackCheckIfBufferIsFull;
+
+ //
+ // HyperTrace callback(s)
+ //
+ HYPERTRACE_LBR_IS_SUPPORTED HyperTraceCallbackLbrIsSupported;
//
// VMM callbacks
//
- VMM_CALLBACK_TRIGGER_EVENTS VmmCallbackTriggerEvents; // Fixed
- VMM_CALLBACK_SET_LAST_ERROR VmmCallbackSetLastError; // Fixed
- VMM_CALLBACK_VMCALL_HANDLER VmmCallbackVmcallHandler; // Fixed
- VMM_CALLBACK_NMI_BROADCAST_REQUEST_HANDLER VmmCallbackNmiBroadcastRequestHandler; // Fixed
- VMM_CALLBACK_QUERY_TERMINATE_PROTECTED_RESOURCE VmmCallbackQueryTerminateProtectedResource; // Fixed
- VMM_CALLBACK_RESTORE_EPT_STATE VmmCallbackRestoreEptState; // Fixed
- VMM_CALLBACK_CHECK_UNHANDLED_EPT_VIOLATION VmmCallbackCheckUnhandledEptViolations; // Fixed
+ VMM_CALLBACK_TRIGGER_EVENTS VmmCallbackTriggerEvents;
+ VMM_CALLBACK_SET_LAST_ERROR VmmCallbackSetLastError;
+ VMM_CALLBACK_VMCALL_HANDLER VmmCallbackVmcallHandler;
+ VMM_CALLBACK_NMI_BROADCAST_REQUEST_HANDLER VmmCallbackNmiBroadcastRequestHandler;
+ VMM_CALLBACK_QUERY_TERMINATE_PROTECTED_RESOURCE VmmCallbackQueryTerminateProtectedResource;
+ VMM_CALLBACK_RESTORE_EPT_STATE VmmCallbackRestoreEptState;
+ VMM_CALLBACK_CHECK_UNHANDLED_EPT_VIOLATION VmmCallbackCheckUnhandledEptViolations;
+ VMM_CALLBACK_HANDLE_MTF_CALLBACK VmmCallbackHandleMtfCallback;
//
// Debugging callbacks
//
- DEBUGGING_CALLBACK_HANDLE_BREAKPOINT_EXCEPTION DebuggingCallbackHandleBreakpointException; // Fixed
- DEBUGGING_CALLBACK_HANDLE_DEBUG_BREAKPOINT_EXCEPTION DebuggingCallbackHandleDebugBreakpointException; // Fixed
- DEBUGGING_CALLBACK_CHECK_THREAD_INTERCEPTION DebuggingCallbackCheckThreadInterception; // Fixed
+ DEBUGGING_CALLBACK_HANDLE_BREAKPOINT_EXCEPTION DebuggingCallbackHandleBreakpointException;
+ DEBUGGING_CALLBACK_HANDLE_DEBUG_BREAKPOINT_EXCEPTION DebuggingCallbackHandleDebugBreakpointException;
+ DEBUGGING_CALLBACK_CHECK_THREAD_INTERCEPTION DebuggingCallbackCheckThreadInterception;
+ DEBUGGING_CALLBACK_TRIGGER_ON_CLOCK_AND_IPI_EVENTS DebuggingCallbackTriggerOnClockAndIpiEvents;
+ DEBUGGING_CALLBACK_IGNORE_HANDLING_MOV_2_DEBUG_REGS DebuggingCallbackIgnoreHandlingMov2DebugRegs;
+
+ //
+ // Pool manager callbacks
+ //
+ POOL_MANAGER_REQUEST_ALLOCATION PoolManagerCallbackRequestAllocation;
+ POOL_MANAGER_REQUEST_POOL PoolManagerCallbackRequestPool;
+ POOL_MANAGER_FREE_POOL PoolManagerCallbackFreePool;
//
// Interception callbacks
//
- INTERCEPTION_CALLBACK_TRIGGER_CR3_CHANGE InterceptionCallbackTriggerCr3ProcessChange; // Fixed
-
- //
- // Callbacks to be removed
- //
- BREAKPOINT_CHECK_AND_HANDLE_REAPPLYING_BREAKPOINT BreakpointCheckAndHandleReApplyingBreakpoint;
- UD_CHECK_FOR_COMMAND UdCheckForCommand;
- KD_CHECK_AND_HANDLE_NMI_CALLBACK KdCheckAndHandleNmiCallback;
- VMM_CALLBACK_REGISTERED_MTF_HANDLER VmmCallbackRegisteredMtfHandler; // Fixed but not good
- INTERCEPTION_CALLBACK_TRIGGER_CLOCK_AND_IPI DebuggerCheckProcessOrThreadChange;
- KD_QUERY_DEBUGGER_THREAD_OR_PROCESS_TRACING_DETAILS_BY_CORE_ID KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId;
+ INTERCEPTION_CALLBACK_TRIGGER_CR3_CHANGE InterceptionCallbackTriggerCr3ProcessChange;
} VMM_CALLBACKS, *PVMM_CALLBACKS;
diff --git a/hyperdbg/include/components/interface/HyperLogCallback.c b/hyperdbg/include/components/callback/code/HyperLogCallback.c
similarity index 98%
rename from hyperdbg/include/components/interface/HyperLogCallback.c
rename to hyperdbg/include/components/callback/code/HyperLogCallback.c
index 935cb571..2d77def5 100644
--- a/hyperdbg/include/components/interface/HyperLogCallback.c
+++ b/hyperdbg/include/components/callback/code/HyperLogCallback.c
@@ -29,7 +29,7 @@ LogCallbackPrepareAndSendMessageToQueue(UINT32 OperationCode,
BOOLEAN IsImmediateMessage,
BOOLEAN ShowCurrentSystemTime,
BOOLEAN Priority,
- const char * Fmt,
+ const CHAR * Fmt,
...)
{
BOOLEAN Result;
diff --git a/hyperdbg/include/components/interface/HyperLogCallback.h b/hyperdbg/include/components/callback/header/HyperLogCallback.h
similarity index 95%
rename from hyperdbg/include/components/interface/HyperLogCallback.h
rename to hyperdbg/include/components/callback/header/HyperLogCallback.h
index 95812f1e..b7906988 100644
--- a/hyperdbg/include/components/interface/HyperLogCallback.h
+++ b/hyperdbg/include/components/callback/header/HyperLogCallback.h
@@ -21,7 +21,7 @@ LogCallbackPrepareAndSendMessageToQueue(UINT32 OperationCode,
BOOLEAN IsImmediateMessage,
BOOLEAN ShowCurrentSystemTime,
BOOLEAN Priority,
- const char * Fmt,
+ const CHAR * Fmt,
...);
BOOLEAN
diff --git a/hyperdbg/include/components/optimizations/code/InsertionSort.c b/hyperdbg/include/components/optimizations/code/InsertionSort.c
index b6d75e00..949f79b2 100644
--- a/hyperdbg/include/components/optimizations/code/InsertionSort.c
+++ b/hyperdbg/include/components/optimizations/code/InsertionSort.c
@@ -76,7 +76,7 @@ InsertionSortDeleteItem(UINT64 ArrayPtr[], UINT32 * NumberOfItems, UINT32 Index)
return FALSE;
}
- for (size_t i = Index + 1; i < *NumberOfItems; i++)
+ for (SIZE_T i = Index + 1; i < *NumberOfItems; i++)
{
ArrayPtr[i - 1] = ArrayPtr[i];
}
diff --git a/hyperdbg/include/components/pe/code/pe-image-reader.cpp b/hyperdbg/include/components/pe/code/pe-image-reader.cpp
new file mode 100644
index 00000000..b5abaacd
--- /dev/null
+++ b/hyperdbg/include/components/pe/code/pe-image-reader.cpp
@@ -0,0 +1,339 @@
+/**
+ * @file pe-image-reader.cpp
+ * @author jtaw5649
+ * @brief Bounded in-memory Portable Executable reader
+ * @details
+ * @version 0.19
+ * @date 2026-06-01
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief Checks whether the byte range [Offset, Offset + Length) lies entirely within an image buffer
+ *
+ * Validates that neither the offset nor the combined offset-plus-length overflows
+ * and that both fall within the bounds of the image.
+ *
+ * @param ImageSize Total size of the image buffer in bytes
+ * @param Offset Starting byte offset to test
+ * @param Length Number of bytes in the range
+ *
+ * @return BOOLEAN TRUE if the range is valid, FALSE if it exceeds the image bounds
+ */
+static BOOLEAN
+PeImageReaderHasRange(SIZE_T ImageSize, SIZE_T Offset, SIZE_T Length)
+{
+ return Offset <= ImageSize && Length <= ImageSize - Offset;
+}
+
+/**
+ * @brief Adds two SIZE_T values with overflow detection
+ *
+ * Returns FALSE without modifying Result when the addition would overflow;
+ * otherwise writes the sum to *Result and returns TRUE.
+ *
+ * @param Left First operand
+ * @param Right Second operand
+ * @param Result Output pointer that receives the sum on success; must not be NULL
+ *
+ * @return BOOLEAN TRUE if the addition succeeded, FALSE on overflow or NULL pointer
+ */
+static BOOLEAN
+PeImageReaderAddSize(SIZE_T Left, SIZE_T Right, SIZE_T * Result)
+{
+ if (Result == NULL || Right > (SIZE_T)-1 - Left)
+ {
+ return FALSE;
+ }
+
+ *Result = Left + Right;
+ return TRUE;
+}
+
+/**
+ * @brief Retrieves the SizeOfHeaders value from the PE optional header
+ *
+ * Reads the field from IMAGE_OPTIONAL_HEADER32 or IMAGE_OPTIONAL_HEADER64
+ * depending on the bitness recorded in the reader.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER; must not be NULL
+ *
+ * @return DWORD The SizeOfHeaders value from the optional header
+ */
+static DWORD
+PeImageReaderGetSizeOfHeaders(PPE_IMAGE_READER Reader)
+{
+ const BYTE * OptionalHeader = Reader->NtHeaders + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER);
+
+ if (Reader->Is32Bit)
+ {
+ return ((const IMAGE_OPTIONAL_HEADER32 *)OptionalHeader)->SizeOfHeaders;
+ }
+
+ return ((const IMAGE_OPTIONAL_HEADER64 *)OptionalHeader)->SizeOfHeaders;
+}
+
+/**
+ * @brief Parses and validates all PE headers in an in-memory image buffer
+ *
+ * Verifies the DOS signature, the NT signature, the optional header magic,
+ * and ensures all headers and the section table fit within the supplied buffer.
+ * On success the Reader structure is populated with pointers into ImageBase.
+ *
+ * @param ImageBase Pointer to the start of the image buffer; must not be NULL
+ * @param ImageSize Size of the buffer in bytes
+ * @param Reader Output structure to populate on success; must not be NULL
+ *
+ * @return BOOLEAN TRUE if the image was parsed successfully, FALSE on any
+ * validation failure or NULL argument
+ */
+BOOLEAN
+PeImageReaderInitialize(const BYTE * ImageBase, SIZE_T ImageSize, PPE_IMAGE_READER Reader)
+{
+ if (ImageBase == NULL || Reader == NULL)
+ {
+ return FALSE;
+ }
+
+ ZeroMemory(Reader, sizeof(*Reader));
+
+ if (!PeImageReaderHasRange(ImageSize, 0, sizeof(IMAGE_DOS_HEADER)))
+ {
+ return FALSE;
+ }
+
+ const IMAGE_DOS_HEADER * DosHeader = (const IMAGE_DOS_HEADER *)ImageBase;
+ if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE || DosHeader->e_lfanew < 0)
+ {
+ return FALSE;
+ }
+
+ SIZE_T NtHeaderOffset = (SIZE_T)DosHeader->e_lfanew;
+ if (!PeImageReaderHasRange(ImageSize, NtHeaderOffset, sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER)))
+ {
+ return FALSE;
+ }
+
+ const BYTE * NtHeaders = ImageBase + NtHeaderOffset;
+ if (*(const DWORD *)NtHeaders != IMAGE_NT_SIGNATURE)
+ {
+ return FALSE;
+ }
+
+ const IMAGE_FILE_HEADER * FileHeader = (const IMAGE_FILE_HEADER *)(NtHeaders + sizeof(DWORD));
+ SIZE_T OptionalHeaderOffset = NtHeaderOffset + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER);
+
+ if (FileHeader->SizeOfOptionalHeader < sizeof(WORD) ||
+ !PeImageReaderHasRange(ImageSize, OptionalHeaderOffset, FileHeader->SizeOfOptionalHeader))
+ {
+ return FALSE;
+ }
+
+ WORD OptionalHeaderMagic = *(const WORD *)(ImageBase + OptionalHeaderOffset);
+ BOOLEAN Is32Bit = FALSE;
+ SIZE_T MinimumOptionalHeaderSize = 0;
+
+ if (OptionalHeaderMagic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
+ {
+ Is32Bit = TRUE;
+ MinimumOptionalHeaderSize = sizeof(IMAGE_OPTIONAL_HEADER32);
+ }
+ else if (OptionalHeaderMagic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
+ {
+ MinimumOptionalHeaderSize = sizeof(IMAGE_OPTIONAL_HEADER64);
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ if (FileHeader->SizeOfOptionalHeader < MinimumOptionalHeaderSize)
+ {
+ return FALSE;
+ }
+
+ SIZE_T SectionTableOffset = OptionalHeaderOffset + FileHeader->SizeOfOptionalHeader;
+ SIZE_T SectionTableSize = (SIZE_T)FileHeader->NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
+
+ if (FileHeader->NumberOfSections != 0 && SectionTableSize / sizeof(IMAGE_SECTION_HEADER) != FileHeader->NumberOfSections)
+ {
+ return FALSE;
+ }
+
+ if (!PeImageReaderHasRange(ImageSize, SectionTableOffset, SectionTableSize))
+ {
+ return FALSE;
+ }
+
+ Reader->ImageBase = ImageBase;
+ Reader->ImageSize = ImageSize;
+ Reader->DosHeader = DosHeader;
+ Reader->NtHeaders = NtHeaders;
+ Reader->FileHeader = FileHeader;
+ Reader->SectionHeaders = (const IMAGE_SECTION_HEADER *)(ImageBase + SectionTableOffset);
+ Reader->OptionalHeaderMagic = OptionalHeaderMagic;
+ Reader->Is32Bit = Is32Bit;
+
+ return TRUE;
+}
+
+/**
+ * @brief Returns whether the PE image is a 32-bit (PE32) image
+ *
+ * Examines the Is32Bit flag populated by PeImageReaderInitialize.
+ * A return value of FALSE means either the reader is NULL or the image is PE32+.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ *
+ * @return BOOLEAN TRUE for PE32 (32-bit), FALSE for PE32+ (64-bit) or NULL reader
+ */
+BOOLEAN
+PeImageReaderIs32Bit(PPE_IMAGE_READER Reader)
+{
+ if (Reader == NULL)
+ {
+ return FALSE;
+ }
+
+ return Reader->Is32Bit;
+}
+
+/**
+ * @brief Returns a validated pointer into the image at a raw file offset
+ *
+ * Verifies that the range [Offset, Offset + Length) lies within the image
+ * buffer before setting *Pointer. Use this function when working with raw
+ * file offsets rather than virtual addresses.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER; must not be NULL
+ * @param Offset Raw file offset from the start of the image
+ * @param Length Number of bytes that must be accessible at the offset
+ * @param Pointer Output pointer set to ImageBase + Offset on success; must not be NULL
+ *
+ * @return BOOLEAN TRUE on success, FALSE on invalid arguments or out-of-bounds offset
+ */
+BOOLEAN
+PeImageReaderGetPointerAtOffset(PPE_IMAGE_READER Reader, SIZE_T Offset, SIZE_T Length, const BYTE ** Pointer)
+{
+ if (Reader == NULL || Reader->ImageBase == NULL || Pointer == NULL || !PeImageReaderHasRange(Reader->ImageSize, Offset, Length))
+ {
+ return FALSE;
+ }
+
+ *Pointer = Reader->ImageBase + Offset;
+ return TRUE;
+}
+
+/**
+ * @brief Copies the section name from a section header into a null-terminated buffer
+ *
+ * The PE section name field (IMAGE_SIZEOF_SHORT_NAME bytes) is not required to be
+ * null-terminated when it uses all 8 bytes. This function always appends a null
+ * terminator and truncates to NameBufferSize - 1 characters if necessary.
+ *
+ * @param SectionHeader Pointer to the section header to read; must not be NULL
+ * @param NameBuffer Destination buffer for the null-terminated name; must not be NULL
+ * @param NameBufferSize Size of NameBuffer in bytes; must be at least 1
+ *
+ * @return BOOLEAN TRUE on success, FALSE on NULL arguments or zero-length buffer
+ */
+BOOLEAN
+PeImageReaderGetSectionName(const IMAGE_SECTION_HEADER * SectionHeader, CHAR * NameBuffer, SIZE_T NameBufferSize)
+{
+ if (SectionHeader == NULL || NameBuffer == NULL || NameBufferSize == 0)
+ {
+ return FALSE;
+ }
+
+ SIZE_T NameLength = 0;
+ while (NameLength < IMAGE_SIZEOF_SHORT_NAME && SectionHeader->Name[NameLength] != '\0')
+ {
+ NameLength++;
+ }
+
+ SIZE_T CopyLength = NameLength;
+ if (CopyLength >= NameBufferSize)
+ {
+ CopyLength = NameBufferSize - 1;
+ }
+
+ CopyMemory(NameBuffer, SectionHeader->Name, CopyLength);
+ NameBuffer[CopyLength] = '\0';
+
+ return TRUE;
+}
+
+/**
+ * @brief Translates a relative virtual address (RVA) to a raw file offset
+ *
+ * First checks whether the RVA falls within the PE headers (before any section),
+ * in which case the file offset equals the RVA. Otherwise iterates the section
+ * table to find the section that contains the range [Rva, Rva + Length) and
+ * computes the corresponding raw offset via PointerToRawData. Returns FALSE if
+ * no section contains the range, if the raw data mapping is out of bounds, or if
+ * any arithmetic overflows.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER; must not be NULL
+ * @param Rva Relative virtual address to translate
+ * @param Length Number of bytes that must be accessible at the translated offset
+ * @param FileOffset Output pointer that receives the raw file offset on success; must not be NULL
+ *
+ * @return BOOLEAN TRUE if the RVA was translated successfully, FALSE otherwise
+ */
+BOOLEAN
+PeImageReaderRvaToFileOffset(PPE_IMAGE_READER Reader, DWORD Rva, DWORD Length, PSIZE_T FileOffset)
+{
+ if (Reader == NULL || Reader->ImageBase == NULL || Reader->FileHeader == NULL || Reader->SectionHeaders == NULL || FileOffset == NULL)
+ {
+ return FALSE;
+ }
+
+ DWORD SizeOfHeaders = PeImageReaderGetSizeOfHeaders(Reader);
+ SIZE_T HeaderEnd = 0;
+
+ if (PeImageReaderAddSize((SIZE_T)Rva, (SIZE_T)Length, &HeaderEnd) &&
+ SizeOfHeaders <= Reader->ImageSize && Rva < SizeOfHeaders && HeaderEnd <= SizeOfHeaders &&
+ PeImageReaderHasRange(Reader->ImageSize, (SIZE_T)Rva, (SIZE_T)Length))
+ {
+ *FileOffset = (SIZE_T)Rva;
+ return TRUE;
+ }
+
+ for (WORD Index = 0; Index < Reader->FileHeader->NumberOfSections; Index++)
+ {
+ const IMAGE_SECTION_HEADER * SectionHeader = &Reader->SectionHeaders[Index];
+ DWORD SectionSpan = max(SectionHeader->Misc.VirtualSize, SectionHeader->SizeOfRawData);
+
+ if (SectionSpan == 0 || Rva < SectionHeader->VirtualAddress)
+ {
+ continue;
+ }
+
+ DWORD Delta = Rva - SectionHeader->VirtualAddress;
+ if (Delta >= SectionSpan || Length > SectionSpan - Delta)
+ {
+ continue;
+ }
+
+ if (Delta > SectionHeader->SizeOfRawData || Length > SectionHeader->SizeOfRawData - Delta)
+ {
+ return FALSE;
+ }
+
+ SIZE_T RawOffset = 0;
+
+ if (!PeImageReaderAddSize((SIZE_T)SectionHeader->PointerToRawData, (SIZE_T)Delta, &RawOffset) ||
+ !PeImageReaderHasRange(Reader->ImageSize, RawOffset, (SIZE_T)Length))
+ {
+ return FALSE;
+ }
+
+ *FileOffset = RawOffset;
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/hyperdbg/include/components/pe/header/pe-image-reader.h b/hyperdbg/include/components/pe/header/pe-image-reader.h
new file mode 100644
index 00000000..61fd23a5
--- /dev/null
+++ b/hyperdbg/include/components/pe/header/pe-image-reader.h
@@ -0,0 +1,102 @@
+/**
+ * @file pe-image-reader.h
+ * @author jtaw5649
+ * @brief Bounded in-memory Portable Executable reader
+ * @details
+ * @version 0.19
+ * @date 2026-06-01
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#ifndef _WIN32
+// On Windows these are provided by winnt.h; define them here for other platforms.
+
+typedef struct _IMAGE_DOS_HEADER
+{ // DOS .EXE header
+ WORD e_magic; // Magic number
+ WORD e_cblp; // Bytes on last page of file
+ WORD e_cp; // Pages in file
+ WORD e_crlc; // Relocations
+ WORD e_cparhdr; // Size of header in paragraphs
+ WORD e_minalloc; // Minimum extra paragraphs needed
+ WORD e_maxalloc; // Maximum extra paragraphs needed
+ WORD e_ss; // Initial (relative) SS value
+ WORD e_sp; // Initial SP value
+ WORD e_csum; // Checksum
+ WORD e_ip; // Initial IP value
+ WORD e_cs; // Initial (relative) CS value
+ WORD e_lfarlc; // File address of relocation table
+ WORD e_ovno; // Overlay number
+ WORD e_res[4]; // Reserved words
+ WORD e_oemid; // OEM identifier (for e_oeminfo)
+ WORD e_oeminfo; // OEM information; e_oemid specific
+ WORD e_res2[10]; // Reserved words
+ LONG e_lfanew; // File address of new exe header
+} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
+
+typedef struct _IMAGE_FILE_HEADER
+{
+ WORD Machine;
+ WORD NumberOfSections;
+ DWORD TimeDateStamp;
+ DWORD PointerToSymbolTable;
+ DWORD NumberOfSymbols;
+ WORD SizeOfOptionalHeader;
+ WORD Characteristics;
+} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
+
+# define IMAGE_SIZEOF_SHORT_NAME 8
+
+typedef struct _IMAGE_SECTION_HEADER
+{
+ BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
+ union
+ {
+ DWORD PhysicalAddress;
+ DWORD VirtualSize;
+ } Misc;
+ DWORD VirtualAddress;
+ DWORD SizeOfRawData;
+ DWORD PointerToRawData;
+ DWORD PointerToRelocations;
+ DWORD PointerToLinenumbers;
+ WORD NumberOfRelocations;
+ WORD NumberOfLinenumbers;
+ DWORD Characteristics;
+} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
+
+#endif // _WIN32
+
+typedef struct _PE_IMAGE_READER
+{
+ const BYTE * ImageBase;
+ SIZE_T ImageSize;
+ const IMAGE_DOS_HEADER * DosHeader;
+ const BYTE * NtHeaders;
+ const IMAGE_FILE_HEADER * FileHeader;
+ const IMAGE_SECTION_HEADER * SectionHeaders;
+ WORD OptionalHeaderMagic;
+ BOOLEAN Is32Bit;
+} PE_IMAGE_READER, *PPE_IMAGE_READER;
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+BOOLEAN
+PeImageReaderInitialize(const BYTE * ImageBase, SIZE_T ImageSize, PPE_IMAGE_READER Reader);
+
+BOOLEAN
+PeImageReaderIs32Bit(PPE_IMAGE_READER Reader);
+
+BOOLEAN
+PeImageReaderGetPointerAtOffset(PPE_IMAGE_READER Reader, SIZE_T Offset, SIZE_T Length, const BYTE ** Pointer);
+
+BOOLEAN
+PeImageReaderGetSectionName(const IMAGE_SECTION_HEADER * SectionHeader, CHAR * NameBuffer, SIZE_T NameBufferSize);
+
+BOOLEAN
+PeImageReaderRvaToFileOffset(PPE_IMAGE_READER Reader, DWORD Rva, DWORD Length, PSIZE_T FileOffset);
diff --git a/hyperdbg/include/components/spinlock/code/Spinlock.c b/hyperdbg/include/components/spinlock/code/Spinlock.c
index 53c47c8b..4b3e908b 100644
--- a/hyperdbg/include/components/spinlock/code/Spinlock.c
+++ b/hyperdbg/include/components/spinlock/code/Spinlock.c
@@ -26,15 +26,15 @@
#include "pch.h"
/**
- * @brief The maximum wait before PAUSE
+ * @brief The maximum Wait before PAUSE
*
*/
-static unsigned MaxWait = 65536;
+static UINT32 g_MaxWait = 65536;
/**
* @brief Tries to get the lock otherwise returns
*
- * @param LONG Lock variable
+ * @param Lock Lock variable
* @return BOOLEAN If it was successful on getting the lock
*/
BOOLEAN
@@ -46,32 +46,33 @@ SpinlockTryLock(volatile LONG * Lock)
/**
* @brief Tries to get the lock and won't return until successfully get the lock
*
- * @param LONG Lock variable
+ * @param Lock Lock variable
+ * @return VOID
*/
-void
+VOID
SpinlockLock(volatile LONG * Lock)
{
- unsigned wait = 1;
+ UINT32 Wait = 1;
while (!SpinlockTryLock(Lock))
{
- for (unsigned i = 0; i < wait; ++i)
+ for (UINT32 i = 0; i < Wait; ++i)
{
_mm_pause();
}
//
- // Don't call "pause" too many times. If the wait becomes too big,
+ // Don't call "pause" too many times. If the Wait becomes too big,
// clamp it to the MaxWait.
//
- if (wait * 2 > MaxWait)
+ if (Wait * 2 > g_MaxWait)
{
- wait = MaxWait;
+ Wait = g_MaxWait;
}
else
{
- wait = wait * 2;
+ Wait = Wait * 2;
}
}
}
@@ -83,34 +84,35 @@ SpinlockLock(volatile LONG * Lock)
* @param Destination A pointer to the destination value
* @param Exchange The exchange value
* @param Comperand The value to compare to Destination
+ * @return VOID
*/
-void
+VOID
SpinlockInterlockedCompareExchange(
LONG volatile * Destination,
LONG Exchange,
LONG Comperand)
{
- unsigned wait = 1;
+ UINT32 Wait = 1;
while (InterlockedCompareExchange(Destination, Exchange, Comperand) != Comperand)
{
- for (unsigned i = 0; i < wait; ++i)
+ for (UINT32 i = 0; i < Wait; ++i)
{
_mm_pause();
}
//
- // Don't call "pause" too many times. If the wait becomes too big,
+ // Don't call "pause" too many times. If the Wait becomes too big,
// clamp it to the MaxWait.
//
- if (wait * 2 > MaxWait)
+ if (Wait * 2 > g_MaxWait)
{
- wait = MaxWait;
+ Wait = g_MaxWait;
}
else
{
- wait = wait * 2;
+ Wait = Wait * 2;
}
}
}
@@ -118,33 +120,34 @@ SpinlockInterlockedCompareExchange(
/**
* @brief Tries to get the lock and won't return until successfully get the lock
*
- * @param LONG Lock variable
- * @param LONG MaxWait Maximum wait (pause) count
+ * @param Lock Lock variable
+ * @param MaximumWait Maximum wait (pause) count
+ * @return VOID
*/
-void
-SpinlockLockWithCustomWait(volatile LONG * Lock, unsigned MaximumWait)
+VOID
+SpinlockLockWithCustomWait(volatile LONG * Lock, UINT32 MaximumWait)
{
- unsigned wait = 1;
+ UINT32 Wait = 1;
while (!SpinlockTryLock(Lock))
{
- for (unsigned i = 0; i < wait; ++i)
+ for (UINT32 i = 0; i < Wait; ++i)
{
_mm_pause();
}
//
- // Don't call "pause" too many times. If the wait becomes too big,
+ // Don't call "pause" too many times. If the Wait becomes too big,
// clamp it to the MaxWait.
//
- if (wait * 2 > MaximumWait)
+ if (Wait * 2 > MaximumWait)
{
- wait = MaximumWait;
+ Wait = MaximumWait;
}
else
{
- wait = wait * 2;
+ Wait = Wait * 2;
}
}
}
@@ -152,9 +155,10 @@ SpinlockLockWithCustomWait(volatile LONG * Lock, unsigned MaximumWait)
/**
* @brief Release the lock
*
- * @param LONG Lock variable
+ * @param Lock Lock variable
+ * @return VOID
*/
-void
+VOID
SpinlockUnlock(volatile LONG * Lock)
{
*Lock = 0;
@@ -163,7 +167,8 @@ SpinlockUnlock(volatile LONG * Lock)
/**
* @brief Check the lock without changing the state
*
- * @param LONG Lock variable
+ * @param Lock Lock variable
+ * @return BOOLEAN Whether the lock is acquired or not
*/
BOOLEAN
SpinlockCheckLock(volatile LONG * Lock)
diff --git a/hyperdbg/include/components/spinlock/header/Spinlock.h b/hyperdbg/include/components/spinlock/header/Spinlock.h
index bd3f2d0a..13cdf22b 100644
--- a/hyperdbg/include/components/spinlock/header/Spinlock.h
+++ b/hyperdbg/include/components/spinlock/header/Spinlock.h
@@ -21,16 +21,16 @@ SpinlockTryLock(volatile LONG * Lock);
BOOLEAN
SpinlockCheckLock(volatile LONG * Lock);
-void
+VOID
SpinlockLock(volatile LONG * Lock);
-void
-SpinlockLockWithCustomWait(volatile LONG * Lock, unsigned MaxWait);
+VOID
+SpinlockLockWithCustomWait(volatile LONG * Lock, UINT32 MaxWait);
-void
+VOID
SpinlockUnlock(volatile LONG * Lock);
-void
+VOID
SpinlockInterlockedCompareExchange(
LONG volatile * Destination,
LONG Exchange,
diff --git a/hyperdbg/include/config/Configuration.h b/hyperdbg/include/config/Configuration.h
index e0e4dec3..9a78bc41 100644
--- a/hyperdbg/include/config/Configuration.h
+++ b/hyperdbg/include/config/Configuration.h
@@ -77,4 +77,4 @@
/**
* @brief Activates the hyperevade project
*/
-#define ActivateHyperEvadeProject TRUE
+#define ActivateHyperEvadeProject FALSE
diff --git a/hyperdbg/include/config/Definition.h b/hyperdbg/include/config/Definition.h
index f9089a6d..1580f1e4 100644
--- a/hyperdbg/include/config/Definition.h
+++ b/hyperdbg/include/config/Definition.h
@@ -79,6 +79,16 @@
*/
#define TEST_CASE_PARAMETER_FOR_MAIN_COMMAND_PARSER "test-command-parser"
+/**
+ * @brief Test case parameter for testing PE parser
+ */
+#define TEST_CASE_PARAMETER_FOR_PE_PARSER "test-pe-parser"
+
+/**
+ * @brief Test case parameter for testing CodeView RSDS parser
+ */
+#define TEST_CASE_PARAMETER_FOR_CODEVIEW_RSDS_PARSER "test-codeview-rsds-parser"
+
/**
* @brief Test case parameter for testing semantic script tests
*/
diff --git a/hyperdbg/include/hyper-v/HypervTlfs.h b/hyperdbg/include/hyper-v/HypervTlfs.h
index ebca8eba..4df98634 100644
--- a/hyperdbg/include/hyper-v/HypervTlfs.h
+++ b/hyperdbg/include/hyper-v/HypervTlfs.h
@@ -216,6 +216,29 @@ enum hv_isolation_type
#define HV_REGISTER_SINT14 0x4000009E
#define HV_REGISTER_SINT15 0x4000009F
+// #define HV_X64_MSR_TIME_REF_COUNT 0x40000020ULL
+// #define HV_X64_MSR_REFERENCE_TSC 0x40000021ULL
+#define HV_X64_MSR_NPIEP_CONFIG 0x40000040ULL
+// #define HV_X64_MSR_SCONTROL 0x40000080ULL
+// #define HV_X64_MSR_EOM 0x40000084ULL
+// #define HV_X64_MSR_SINT0 0x40000090ULL
+// #define HV_X64_MSR_SINT15 0x4000009FULL
+// #define HV_X64_MSR_STIMER0_CONFIG 0x400000B0ULL
+// #define HV_X64_MSR_STIMER3_COUNT 0x400000B7ULL
+// #define HV_X64_MSR_GUEST_IDLE 0x400000F0ULL
+// #define HV_X64_MSR_CRASH_P0 0x40000100ULL
+// #define HV_X64_MSR_CRASH_CTL 0x40000105ULL
+// #define HV_X64_MSR_REENLIGHTENMENT_CONTROL 0x40000106ULL
+// #define HV_X64_MSR_TSC_EMULATION_CONTROL 0x40000107ULL
+// #define HV_X64_MSR_TSC_EMULATION_STATUS 0x40000108ULL
+#define HV_X64_MSR_STIME_UNHALTED_TIMER_CONFIG 0x40000114ULL
+#define HV_X64_MSR_STIME_UNHALTED_TIMER_COUNT 0x40000115ULL
+#define HV_X64_MSR_NESTED_VP_INDEX 0x40001002ULL
+#define HV_X64_MSR_NESTED_SCONTROL 0x40001080ULL
+#define HV_X64_MSR_NESTED_EOM 0x40001084ULL
+#define HV_X64_MSR_NESTED_SINT0 0x40001090ULL
+#define HV_X64_MSR_NESTED_SINT15 0x4000109FULL
+
/*
* Synthetic Timer MSRs. Four timers per vcpu.
*/
diff --git a/hyperdbg/include/platform/user/code/.gitkeep b/hyperdbg/include/platform/general/code/.gitkeep
similarity index 100%
rename from hyperdbg/include/platform/user/code/.gitkeep
rename to hyperdbg/include/platform/general/code/.gitkeep
diff --git a/hyperdbg/include/platform/general/header/Environment.h b/hyperdbg/include/platform/general/header/Environment.h
new file mode 100644
index 00000000..4abf4d21
--- /dev/null
+++ b/hyperdbg/include/platform/general/header/Environment.h
@@ -0,0 +1,96 @@
+/**
+ * @file Environment.h
+ * @author Behrooz Abbassi (BehroozAbbassi@hyperdbg.org)
+ * @brief The running environment of HyperDbg
+ * @details
+ * @version 0.1
+ * @date 2022-01-17
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Definitions //
+//////////////////////////////////////////////////
+
+//
+// Check for platform
+//
+#if defined(_WIN32) || defined(_WIN64)
+# define HYPERDBG_ENV_WINDOWS
+#elif defined(__linux__)
+// # error "This code cannot compile on Linux yet"
+# define HYPERDBG_ENV_LINUX
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
+# error "This code cannot compile on BSD yet"
+# define HYPERDBG_ENV_BSD
+#else
+# error "This code cannot compile on non-Windows, non-Linux, and non-BSD platforms"
+#endif
+
+#ifdef HYPERDBG_ENV_LINUX
+
+// SAL annotations
+# define _In_
+# define _Out_
+# define _Inout_
+# define _In_opt_
+# define _Out_opt_
+# define _In_z_
+# define _Outptr_
+# define _In_reads_bytes_(x)
+# define _Out_writes_bytes_(x)
+# define _Inout_updates_bytes_all_(x)
+
+// wchar_t is a C++ built-in but needs this header in C
+# include
+
+// POSIX sleep primitives (usleep) backing the Win32 Sleep() shim below
+# include
+
+// Windows string/char types
+typedef char TCHAR;
+typedef char * LPTSTR;
+typedef const char * LPCTSTR;
+typedef const char * LPCSTR;
+typedef char * LPSTR;
+typedef const char * PCSTR;
+typedef char * PSTR;
+typedef short * PWCHAR;
+
+// Windows socket type (Linux sockets are plain int)
+typedef int SOCKET;
+# define INVALID_SOCKET ((SOCKET)(-1))
+# define SOCKET_ERROR (-1)
+
+// Windows calling convention (no-op on Linux)
+# define WINAPI
+
+// Windows module handle (equivalent to dlopen's void * on Linux)
+typedef void * HMODULE;
+
+// Misc Windows macros
+# define UNREFERENCED_PARAMETER(P) ((void)(P))
+
+// Win32 wait/event constants (used by the cross-platform sync wrappers)
+# define INFINITE 0xFFFFFFFF
+# define WAIT_OBJECT_0 0x00000000
+
+// Win32 invalid handle sentinel (returned by the cross-platform file/serial wrappers)
+# define INVALID_HANDLE_VALUE ((HANDLE)(SIZE_T)-1)
+
+// Win32 console-control event codes (kept at their Windows values so the
+// shared BreakController() switch compiles unchanged). On Linux these are
+// produced by the platform-signal layer from POSIX signals.
+# define CTRL_C_EVENT 0
+# define CTRL_BREAK_EVENT 1
+# define CTRL_CLOSE_EVENT 2
+# define CTRL_LOGOFF_EVENT 5
+# define CTRL_SHUTDOWN_EVENT 6
+
+// Win32 Sleep(milliseconds) -> POSIX usleep(microseconds)
+# define Sleep(Milliseconds) usleep((useconds_t)(Milliseconds) * 1000)
+
+#endif // HYPERDBG_ENV_LINUX
diff --git a/hyperdbg/include/platform/general/header/nt-list.h b/hyperdbg/include/platform/general/header/nt-list.h
new file mode 100644
index 00000000..0dc4dd2b
--- /dev/null
+++ b/hyperdbg/include/platform/general/header/nt-list.h
@@ -0,0 +1,145 @@
+/**
+ * @file nt-list.h
+ * @author Max Raulea (max.raulea@gmail.com)
+ * @brief Cross-platform NT-style intrusive doubly-linked list helpers + CONTAINING_RECORD
+ * @details The shared debugger code uses the NT LIST_ENTRY API (InitializeListHead,
+ * InsertHeadList, RemoveEntryList, CONTAINING_RECORD, ...). On Windows these
+ * come from (or, under USE_NATIVE_SDK_HEADERS, from the in-tree
+ * platform/user/header/Windows.h). Platforms whose system headers don't ship
+ * them (Linux) get them here, so the shared code compiles unchanged.
+ *
+ * These operate on the exact LIST_ENTRY {Flink, Blink} layout defined in
+ * SDK/headers/DataTypes.h, which is part of the kernel<->user IOCTL ABI --
+ * that's why we mirror the NT list rather than reaching for sys/queue.h
+ * (different layout + a colliding LIST_ENTRY name).
+ *
+ * The body is compiled only where the OS headers don't already provide these
+ * (i.e. not on Windows), so including this unconditionally is safe.
+ *
+ * @version 0.20
+ * @date 2026-06-16
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#ifndef _WIN32
+
+# include // offsetof
+
+//
+// Given the address of a LIST_ENTRY field embedded in a struct, recover the
+// address of the containing struct.
+//
+# ifndef CONTAINING_RECORD
+# define CONTAINING_RECORD(address, type, field) \
+ ((type *)((char *)(address) - offsetof(type, field)))
+# endif
+
+//
+// Initialize a list head to the empty (points-to-self) state.
+//
+static inline VOID
+InitializeListHead(PLIST_ENTRY ListHead)
+{
+ ListHead->Flink = ListHead->Blink = ListHead;
+}
+
+//
+// TRUE if the list has no entries.
+//
+static inline BOOLEAN
+IsListEmpty(const LIST_ENTRY * ListHead)
+{
+ return (BOOLEAN)(ListHead->Flink == ListHead);
+}
+
+//
+// Unlink an entry. Returns TRUE if the list is now empty.
+//
+static inline BOOLEAN
+RemoveEntryList(PLIST_ENTRY Entry)
+{
+ PLIST_ENTRY Flink = Entry->Flink;
+ PLIST_ENTRY Blink = Entry->Blink;
+
+ Blink->Flink = Flink;
+ Flink->Blink = Blink;
+
+ return (BOOLEAN)(Flink == Blink);
+}
+
+//
+// Unlink and return the first entry.
+//
+static inline PLIST_ENTRY
+RemoveHeadList(PLIST_ENTRY ListHead)
+{
+ PLIST_ENTRY Entry = ListHead->Flink;
+ PLIST_ENTRY Flink = Entry->Flink;
+
+ ListHead->Flink = Flink;
+ Flink->Blink = ListHead;
+
+ return Entry;
+}
+
+//
+// Unlink and return the last entry.
+//
+static inline PLIST_ENTRY
+RemoveTailList(PLIST_ENTRY ListHead)
+{
+ PLIST_ENTRY Entry = ListHead->Blink;
+ PLIST_ENTRY Blink = Entry->Blink;
+
+ ListHead->Blink = Blink;
+ Blink->Flink = ListHead;
+
+ return Entry;
+}
+
+//
+// Insert an entry at the tail of the list.
+//
+static inline VOID
+InsertTailList(PLIST_ENTRY ListHead, PLIST_ENTRY Entry)
+{
+ PLIST_ENTRY Blink = ListHead->Blink;
+
+ Entry->Flink = ListHead;
+ Entry->Blink = Blink;
+ Blink->Flink = Entry;
+ ListHead->Blink = Entry;
+}
+
+//
+// Insert an entry at the head of the list.
+//
+static inline VOID
+InsertHeadList(PLIST_ENTRY ListHead, PLIST_ENTRY Entry)
+{
+ PLIST_ENTRY Flink = ListHead->Flink;
+
+ Entry->Flink = Flink;
+ Entry->Blink = ListHead;
+ Flink->Blink = Entry;
+ ListHead->Flink = Entry;
+}
+
+//
+// Splice the entries of ListToAppend onto the tail of ListHead.
+//
+static inline VOID
+AppendTailList(PLIST_ENTRY ListHead, PLIST_ENTRY ListToAppend)
+{
+ PLIST_ENTRY ListEnd = ListHead->Blink;
+
+ ListHead->Blink->Flink = ListToAppend;
+ ListHead->Blink = ListToAppend->Blink;
+ ListToAppend->Blink->Flink = ListHead;
+ ListToAppend->Blink = ListEnd;
+}
+
+#endif // !_WIN32
diff --git a/hyperdbg/include/platform/kernel/code/Mem.c b/hyperdbg/include/platform/kernel/code/Mem.c
deleted file mode 100644
index 4dfd1a83..00000000
--- a/hyperdbg/include/platform/kernel/code/Mem.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * @file mem.c
- * @author Behrooz Abbassi (BehroozAbbassi@hyperdbg.org)
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief Implementation of cross APIs for different platforms for memory allocation
- * @details
- * @version 0.1
- * @date 2022-01-17
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#include "pch.h"
-
-/**
- * @brief Allocate a contiguous zeroed memory
- *
- * @param NumberOfBytes
- * @return PVOID
- */
-PVOID
-PlatformMemAllocateContiguousZeroedMemory(SIZE_T NumberOfBytes)
-{
- PVOID Result = NULL;
- PHYSICAL_ADDRESS MaxPhysicalAddr = {.QuadPart = MAXULONG64};
-
- Result = MmAllocateContiguousMemory(NumberOfBytes, MaxPhysicalAddr);
- if (Result != NULL)
- RtlSecureZeroMemory(Result, NumberOfBytes);
-
- return Result;
-}
-
-/**
- * @brief Allocate a non-paged buffer
- *
- * @param NumberOfBytes
- * @return PVOID
- */
-PVOID
-PlatformMemAllocateNonPagedPool(SIZE_T NumberOfBytes)
-{
- PVOID Result = ExAllocatePoolWithTag(NonPagedPool, NumberOfBytes, POOLTAG);
-
- return Result;
-}
-
-/**
- * @brief Allocate a non-paged buffer (use QUOTA)
- *
- * @param NumberOfBytes
- * @return PVOID
- */
-PVOID
-PlatformMemAllocateNonPagedPoolWithQuota(SIZE_T NumberOfBytes)
-{
- PVOID Result = ExAllocatePool2(POOL_FLAG_NON_PAGED | POOL_FLAG_USE_QUOTA, NumberOfBytes, POOLTAG);
-
- return Result;
-}
-
-/**
- * @brief Allocate a non-paged buffer (zeroed)
- *
- * @param NumberOfBytes
- * @return PVOID
- */
-PVOID
-PlatformMemAllocateZeroedNonPagedPool(SIZE_T NumberOfBytes)
-{
- PVOID Result = ExAllocatePoolWithTag(NonPagedPool, NumberOfBytes, POOLTAG);
-
- if (Result != NULL)
- RtlSecureZeroMemory(Result, NumberOfBytes);
-
- return Result;
-}
-
-/**
- * @brief Free (dellocate) a non-paged buffer
- *
- * @param BufferAddress
- * @return VOID
- */
-VOID
-PlatformMemFreePool(PVOID BufferAddress)
-{
- ExFreePoolWithTag(BufferAddress, POOLTAG);
-}
diff --git a/hyperdbg/include/platform/kernel/code/PlatformBroadcast.c b/hyperdbg/include/platform/kernel/code/PlatformBroadcast.c
new file mode 100644
index 00000000..4c097194
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/code/PlatformBroadcast.c
@@ -0,0 +1,44 @@
+/**
+ * @file PlatformBroadcast.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Implementation of cross platform APIs for broadcasting routines
+ * @details
+ * @version 0.19
+ * @date 2026-05-08
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+#if defined(__linux__)
+# include "../header/PlatformBroadcast.h"
+#endif // defined(__linux__)
+
+/**
+ * @brief This function synchronize the function execution for a single core
+ *
+ * @return VOID
+ */
+VOID
+PlatformBroadcastSynchronizeEndOfRoutine(PVOID SystemArgument1, PVOID SystemArgument2)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ //
+ // Wait for all DPCs to synchronize at this point
+ //
+ KeSignalCallDpcSynchronize(SystemArgument2);
+
+ //
+ // Mark the DPC as being complete
+ //
+ KeSignalCallDpcDone(SystemArgument1);
+
+#elif defined(__linux__)
+ //
+ // Not needed for Linux
+ //
+#else
+# error "Unsupported platform"
+#endif
+}
diff --git a/hyperdbg/include/platform/kernel/code/PlatformCpu.c b/hyperdbg/include/platform/kernel/code/PlatformCpu.c
new file mode 100644
index 00000000..eaece365
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/code/PlatformCpu.c
@@ -0,0 +1,62 @@
+/**
+ * @file PlatformCpu.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Implementation of cross platform APIs for CPU and processor queries
+ * @details
+ * @version 0.19
+ * @date 2026-05-09
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+#if defined(__linux__)
+# include "../header/PlatformCpu.h"
+#endif // defined(__linux__)
+
+/**
+ * @brief Get the count of active logical processors
+ *
+ * @return ULONG
+ */
+ULONG
+PlatformCpuGetActiveProcessorCount(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ return KeQueryActiveProcessorCount(0);
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
+
+/**
+ * @brief Get the current logical processor number
+ *
+ * @return ULONG
+ */
+ULONG
+PlatformCpuGetCurrentProcessorNumber(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ return KeGetCurrentProcessorNumberEx(NULL);
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
diff --git a/hyperdbg/include/platform/kernel/code/PlatformDbg.c b/hyperdbg/include/platform/kernel/code/PlatformDbg.c
new file mode 100644
index 00000000..f1f866ec
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/code/PlatformDbg.c
@@ -0,0 +1,44 @@
+/**
+ * @file PlatformDbg.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Implementation of cross platform APIs for kernel debug output
+ * @details
+ * @version 0.19
+ * @date 2026-05-09
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+#if defined(__linux__)
+# include "../header/PlatformDbg.h"
+#endif // defined(__linux__)
+
+/**
+ * @brief Print a debug message to the kernel debugger
+ *
+ * @param Format printf-style format string
+ * @param ... Variable arguments
+ * @return VOID
+ */
+VOID
+PlatformDbgPrint(const CHAR * Format, ...)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ va_list ArgList;
+ va_start(ArgList, Format);
+ vDbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, Format, ArgList);
+ va_end(ArgList);
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
diff --git a/hyperdbg/include/platform/kernel/code/PlatformDpc.c b/hyperdbg/include/platform/kernel/code/PlatformDpc.c
new file mode 100644
index 00000000..6c459699
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/code/PlatformDpc.c
@@ -0,0 +1,68 @@
+/**
+ * @file PlatformDpc.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Implementation of cross platform APIs for Deferred Procedure Call (DPC) management
+ * @details
+ * @version 0.19
+ * @date 2026-05-09
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+#if defined(__linux__)
+# include "../header/PlatformDpc.h"
+#endif // defined(__linux__)
+
+/**
+ * @brief Initialize a DPC object
+ *
+ * @param Dpc Pointer to the KDPC structure to initialize
+ * @param DeferredRoutine The deferred procedure to be called
+ * @param DeferredContext Optional context passed to the deferred routine
+ * @return VOID
+ */
+VOID
+PlatformDpcInitialize(PRKDPC Dpc, PKDEFERRED_ROUTINE DeferredRoutine, PVOID DeferredContext)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ KeInitializeDpc(Dpc, DeferredRoutine, DeferredContext);
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
+
+/**
+ * @brief Insert a DPC into the system DPC queue for execution
+ *
+ * @param Dpc Pointer to the initialized KDPC structure
+ * @param SystemArgument1 First system-defined argument passed to the deferred routine
+ * @param SystemArgument2 Second system-defined argument passed to the deferred routine
+ * @return BOOLEAN TRUE if the DPC was successfully queued, FALSE if it was already in the queue
+ */
+BOOLEAN
+PlatformDpcInsertQueueDpc(PRKDPC Dpc, PVOID SystemArgument1, PVOID SystemArgument2)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ return KeInsertQueueDpc(Dpc, SystemArgument1, SystemArgument2);
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
diff --git a/hyperdbg/include/platform/kernel/code/PlatformEvent.c b/hyperdbg/include/platform/kernel/code/PlatformEvent.c
new file mode 100644
index 00000000..aed1673c
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/code/PlatformEvent.c
@@ -0,0 +1,105 @@
+/**
+ * @file PlatformEvent.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Implementation of cross platform APIs for kernel event and object management
+ * @details
+ * @version 0.19
+ * @date 2026-05-09
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+#if defined(__linux__)
+# include "../header/PlatformEvent.h"
+#endif // defined(__linux__)
+
+/**
+ * @brief Dereference a kernel object, decrementing its reference count
+ *
+ * @param Object Pointer to the kernel object to dereference
+ * @return VOID
+ */
+VOID
+PlatformObjectDereference(PVOID Object)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ ObDereferenceObject(Object);
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
+
+/**
+ * @brief Signal (set) a kernel event object
+ *
+ * @param Event Pointer to the KEVENT to signal
+ * @param Increment Priority increment for any waiting threads to be awakened
+ * @param Wait If TRUE, the caller intends to immediately call a wait routine after this call
+ * @return LONG The previous signal state of the event
+ */
+LONG
+PlatformEventSet(PKEVENT Event, KPRIORITY Increment, BOOLEAN Wait)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ return KeSetEvent(Event, Increment, Wait);
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
+
+/**
+ * @brief Obtain a pointer to a kernel object by its user-mode handle and increment its reference count
+ *
+ * @param Handle User-mode handle referencing the kernel object
+ * @param DesiredAccess Access mask for the requested access rights
+ * @param ObjectType Pointer to the object type object (e.g., *ExEventObjectType); NULL to skip type check
+ * @param AccessMode Processor mode to use for access checks (KernelMode or UserMode)
+ * @param Object Receives a pointer to the referenced kernel object body
+ * @param HandleInformation Optional; receives access state information
+ * @return NTSTATUS STATUS_SUCCESS on success, or an error code on failure
+ */
+NTSTATUS
+PlatformObjectReferenceByHandle(HANDLE Handle,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_TYPE ObjectType,
+ KPROCESSOR_MODE AccessMode,
+ PVOID * Object,
+ POBJECT_HANDLE_INFORMATION HandleInformation)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ return ObReferenceObjectByHandle(Handle,
+ DesiredAccess,
+ ObjectType,
+ AccessMode,
+ Object,
+ HandleInformation);
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
diff --git a/hyperdbg/include/platform/kernel/code/PlatformIntrinsics.c b/hyperdbg/include/platform/kernel/code/PlatformIntrinsics.c
new file mode 100644
index 00000000..3233d67e
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/code/PlatformIntrinsics.c
@@ -0,0 +1,792 @@
+/**
+ * @file PlatformIntrinsics.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Implementation of cross platform APIs for intrinsic functions (x86 instructions)
+ * @details
+ * @version 0.19
+ * @date 2026-04-27
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+#if defined(__linux__)
+# include "../header/PlatformIntrinsics.h"
+#endif // defined(__linux__)
+
+//////////////////////////////////////////////////
+// CR Registers //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Read CR0
+ *
+ * @return ULONG_PTR
+ */
+inline ULONG_PTR
+CpuReadCr0(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return __readcr0();
+#elif defined(__linux__)
+ ULONG_PTR __val;
+ __asm__ __volatile__("mov %%cr0, %0" : "=r"(__val));
+ return __val;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Write CR0
+ *
+ * @param Cr0Value
+ */
+inline VOID
+CpuWriteCr0(ULONG_PTR Cr0Value)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __writecr0(Cr0Value);
+#elif defined(__linux__)
+ __asm__ __volatile__("mov %0, %%cr0" : : "r"(Cr0Value) : "memory");
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Read CR2
+ *
+ * @return ULONG_PTR
+ */
+inline ULONG_PTR
+CpuReadCr2(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return __readcr2();
+#elif defined(__linux__)
+ ULONG_PTR __val;
+ __asm__ __volatile__("mov %%cr2, %0" : "=r"(__val));
+ return __val;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Write CR2
+ *
+ * @param Cr2Value
+ */
+inline VOID
+CpuWriteCr2(ULONG_PTR Cr2Value)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __writecr2(Cr2Value);
+#elif defined(__linux__)
+ __asm__ __volatile__("mov %0, %%cr2" : : "r"(Cr2Value) : "memory");
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Read CR3
+ *
+ * @return ULONG_PTR
+ */
+inline ULONG_PTR
+CpuReadCr3(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return __readcr3();
+#elif defined(__linux__)
+ ULONG_PTR __val;
+ __asm__ __volatile__("mov %%cr3, %0" : "=r"(__val));
+ return __val;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Write CR3
+ *
+ * @param Cr3Value
+ */
+inline VOID
+CpuWriteCr3(ULONG_PTR Cr3Value)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __writecr3(Cr3Value);
+#elif defined(__linux__)
+ __asm__ __volatile__("mov %0, %%cr3" : : "r"(Cr3Value) : "memory");
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Read CR4
+ *
+ * @return ULONG_PTR
+ */
+inline ULONG_PTR
+CpuReadCr4(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return __readcr4();
+#elif defined(__linux__)
+ ULONG_PTR __val;
+ __asm__ __volatile__("mov %%cr4, %0" : "=r"(__val));
+ return __val;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Write CR4
+ *
+ * @param Cr4Value
+ */
+inline VOID
+CpuWriteCr4(ULONG_PTR Cr4Value)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __writecr4(Cr4Value);
+#elif defined(__linux__)
+ __asm__ __volatile__("mov %0, %%cr4" : : "r"(Cr4Value) : "memory");
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Read CR8
+ *
+ * @return ULONG_PTR
+ */
+inline ULONG_PTR
+CpuReadCr8(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return __readcr8();
+#elif defined(__linux__)
+ ULONG_PTR __val;
+ __asm__ __volatile__("mov %%cr8, %0" : "=r"(__val));
+ return __val;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Write CR8
+ *
+ * @param Cr8Value
+ */
+inline VOID
+CpuWriteCr8(ULONG_PTR Cr8Value)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __writecr8(Cr8Value);
+#elif defined(__linux__)
+ __asm__ __volatile__("mov %0, %%cr8" : : "r"(Cr8Value) : "memory");
+#else
+# error "Unsupported platform"
+#endif
+}
+
+//////////////////////////////////////////////////
+// MSR Instructions //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Read an MSR
+ *
+ * @param MsrAddress
+ * @return UINT64
+ */
+inline UINT64
+CpuReadMsr(ULONG MsrAddress)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return __readmsr(MsrAddress);
+#elif defined(__linux__)
+ UINT32 __lo, __hi;
+ __asm__ __volatile__("rdmsr" : "=a"(__lo), "=d"(__hi) : "c"(MsrAddress));
+ return ((UINT64)__hi << 32) | __lo;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Write an MSR
+ *
+ * @param MsrAddress
+ * @param MsrValue
+ */
+inline VOID
+CpuWriteMsr(ULONG MsrAddress, UINT64 MsrValue)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __writemsr(MsrAddress, MsrValue);
+#elif defined(__linux__)
+ __asm__ __volatile__("wrmsr" : : "c"(MsrAddress), "a"((UINT32)MsrValue), "d"((UINT32)(MsrValue >> 32)));
+#else
+# error "Unsupported platform"
+#endif
+}
+
+//////////////////////////////////////////////////
+// CPUID Instructions //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Execute CPUID
+ *
+ * @param CpuInfo
+ * @param FunctionId
+ */
+inline VOID
+CpuCpuId(INT32 * CpuInfo, INT32 FunctionId)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __cpuid(CpuInfo, FunctionId);
+#elif defined(__linux__)
+ __asm__ __volatile__("cpuid" : "=a"(CpuInfo[0]), "=b"(CpuInfo[1]), "=c"(CpuInfo[2]), "=d"(CpuInfo[3]) : "a"(FunctionId), "c"(0));
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Execute CPUID with sub-leaf
+ *
+ * @param CpuInfo
+ * @param FunctionId
+ * @param SubFunctionId
+ */
+inline VOID
+CpuCpuIdEx(INT32 * CpuInfo, INT32 FunctionId, INT32 SubFunctionId)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __cpuidex(CpuInfo, FunctionId, SubFunctionId);
+#elif defined(__linux__)
+ __asm__ __volatile__("cpuid" : "=a"(CpuInfo[0]), "=b"(CpuInfo[1]), "=c"(CpuInfo[2]), "=d"(CpuInfo[3]) : "a"(FunctionId), "c"(SubFunctionId));
+#else
+# error "Unsupported platform"
+#endif
+}
+
+//////////////////////////////////////////////////
+// TSC Instructions //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Read Time-Stamp Counter
+ *
+ * @return UINT64
+ */
+inline UINT64
+CpuReadTsc(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return __rdtsc();
+#elif defined(__linux__)
+ UINT32 __lo, __hi;
+ __asm__ __volatile__("rdtsc" : "=a"(__lo), "=d"(__hi));
+ return ((UINT64)__hi << 32) | __lo;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Read Time-Stamp Counter and Processor ID
+ *
+ * @param Aux
+ * @return UINT64
+ */
+inline UINT64
+CpuReadTscp(UINT32 * Aux)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return __rdtscp(Aux);
+#elif defined(__linux__)
+ UINT32 __lo, __hi;
+ __asm__ __volatile__("rdtscp" : "=a"(__lo), "=d"(__hi), "=c"(*Aux));
+ return ((UINT64)__hi << 32) | __lo;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+//////////////////////////////////////////////////
+// Interlocked (Atomic) Operations //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Atomic 64-bit exchange
+ */
+inline INT64
+CpuInterlockedExchange64(INT64 volatile * Target, INT64 Value)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return InterlockedExchange64(Target, Value);
+#elif defined(__linux__)
+ return __atomic_exchange_n(Target, Value, __ATOMIC_SEQ_CST);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Atomic 64-bit exchange-add
+ */
+inline INT64
+CpuInterlockedExchangeAdd64(INT64 volatile * Addend, INT64 Value)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return InterlockedExchangeAdd64(Addend, Value);
+#elif defined(__linux__)
+ return __atomic_fetch_add(Addend, Value, __ATOMIC_SEQ_CST);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Atomic 64-bit increment
+ */
+inline INT64
+CpuInterlockedIncrement64(INT64 volatile * Addend)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return InterlockedIncrement64(Addend);
+#elif defined(__linux__)
+ return __atomic_add_fetch(Addend, 1LL, __ATOMIC_SEQ_CST);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Atomic 64-bit decrement
+ */
+inline INT64
+CpuInterlockedDecrement64(INT64 volatile * Addend)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return InterlockedDecrement64(Addend);
+#elif defined(__linux__)
+ return __atomic_sub_fetch(Addend, 1LL, __ATOMIC_SEQ_CST);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Atomic 64-bit compare-exchange
+ */
+inline INT64
+CpuInterlockedCompareExchange64(INT64 volatile * Destination, INT64 ExChange, INT64 Comparand)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return InterlockedCompareExchange64(Destination, ExChange, Comparand);
+#elif defined(__linux__)
+ INT64 Expected = Comparand;
+ __atomic_compare_exchange_n(Destination, &Expected, ExChange, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+ return Expected;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+//////////////////////////////////////////////////
+// Descriptor Table Instructions //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Store Interrupt Descriptor Table Register
+ *
+ * @param Idtr
+ */
+inline VOID
+CpuSidt(VOID * Idtr)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __sidt(Idtr);
+#elif defined(__linux__)
+ __asm__ __volatile__("sidt %0" : "=m"(*(char *)Idtr) : : "memory");
+#else
+# error "Unsupported platform"
+#endif
+}
+
+//////////////////////////////////////////////////
+// TLB Instructions //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Invalidate TLB entry for a virtual address
+ *
+ * @param Address
+ */
+inline VOID
+CpuInvlpg(VOID * Address)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __invlpg(Address);
+#elif defined(__linux__)
+ __asm__ __volatile__("invlpg (%0)" : : "r"(Address) : "memory");
+#else
+# error "Unsupported platform"
+#endif
+}
+
+//////////////////////////////////////////////////
+// String Store Instructions //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Store UINT64 value to memory Count times
+ *
+ * @param Destination
+ * @param Value
+ * @param Count
+ */
+inline VOID
+CpuStosQ(UINT64 * Destination, UINT64 Value, SIZE_T Count)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __stosq((unsigned __int64 *)Destination, Value, Count);
+#elif defined(__linux__)
+ __asm__ __volatile__("rep stosq" : "+D"(Destination), "+c"(Count) : "a"(Value) : "memory");
+#else
+# error "Unsupported platform"
+#endif
+}
+
+//////////////////////////////////////////////////
+// Bit Scan Instructions //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Bit scan forward (64-bit)
+ *
+ * @param Index
+ * @param Mask
+ * @return UCHAR
+ */
+inline UCHAR
+CpuBitScanForward64(ULONG * Index, UINT64 Mask)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return (UCHAR)_BitScanForward64((unsigned long *)Index, Mask);
+#elif defined(__linux__)
+ if (!Mask)
+ return 0;
+ *Index = (ULONG)__builtin_ctzll(Mask);
+ return 1;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+//////////////////////////////////////////////////
+// Misc Instructions //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Execute NOP
+ */
+inline VOID
+CpuNop(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __nop();
+#elif defined(__linux__)
+ __asm__ __volatile__("nop");
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Execute PAUSE (spin-wait hint)
+ */
+inline VOID
+CpuPause(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ _mm_pause();
+#elif defined(__linux__)
+ __asm__ __volatile__("pause");
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Return the segment limit for a selector
+ *
+ * @param Selector
+ * @return ULONG
+ */
+inline ULONG
+CpuSegmentLimit(UINT32 Selector)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return __segmentlimit(Selector);
+#elif defined(__linux__)
+
+ UINT32 Limit;
+
+ __asm__ __volatile__(
+ "lsl %1, %0"
+ : "=r"(Limit)
+ : "rm"(Selector)
+ : "cc");
+
+ return Limit;
+
+#else
+# error "Unsupported platform"
+#endif
+}
+
+//////////////////////////////////////////////////
+// I/O Port Instructions //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Read a byte from an I/O port
+ *
+ * @param Port
+ * @return UINT8
+ */
+inline UINT8
+CpuIoInByte(UINT16 Port)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return __inbyte(Port);
+#elif defined(__linux__)
+ UINT8 __val;
+ __asm__ __volatile__("inb %1, %0" : "=a"(__val) : "Nd"(Port));
+ return __val;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Read a word from an I/O port
+ *
+ * @param Port
+ * @return UINT16
+ */
+inline UINT16
+CpuIoInWord(UINT16 Port)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return __inword(Port);
+#elif defined(__linux__)
+ UINT16 __val;
+ __asm__ __volatile__("inw %1, %0" : "=a"(__val) : "Nd"(Port));
+ return __val;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Read a dword from an I/O port
+ *
+ * @param Port
+ * @return UINT32
+ */
+inline UINT32
+CpuIoInDword(UINT16 Port)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return __indword(Port);
+#elif defined(__linux__)
+ UINT32 __val;
+ __asm__ __volatile__("inl %1, %0" : "=a"(__val) : "Nd"(Port));
+ return __val;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Read a byte string from an I/O port
+ *
+ * @param Port
+ * @param Data
+ * @param Size
+ */
+inline VOID
+CpuIoInByteString(UINT16 Port, UINT8 * Data, UINT32 Size)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __inbytestring(Port, Data, Size);
+#elif defined(__linux__)
+ __asm__ __volatile__("rep insb" : "+D"(Data), "+c"(Size) : "d"(Port) : "memory");
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Read a word string from an I/O port
+ *
+ * @param Port
+ * @param Data
+ * @param Size
+ */
+inline VOID
+CpuIoInWordString(UINT16 Port, UINT16 * Data, UINT32 Size)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __inwordstring(Port, Data, Size);
+#elif defined(__linux__)
+ __asm__ __volatile__("rep insw" : "+D"(Data), "+c"(Size) : "d"(Port) : "memory");
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Read a dword string from an I/O port
+ *
+ * @param Port
+ * @param Data
+ * @param Size
+ */
+inline VOID
+CpuIoInDwordString(UINT16 Port, UINT32 * Data, UINT32 Size)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __indwordstring(Port, (unsigned long *)Data, Size);
+#elif defined(__linux__)
+ __asm__ __volatile__("rep insl" : "+D"(Data), "+c"(Size) : "d"(Port) : "memory");
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Write a byte to an I/O port
+ *
+ * @param Port
+ * @param Value
+ */
+inline VOID
+CpuIoOutByte(UINT16 Port, UINT8 Value)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __outbyte(Port, Value);
+#elif defined(__linux__)
+ __asm__ __volatile__("outb %0, %1" : : "a"(Value), "Nd"(Port));
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Write a word to an I/O port
+ *
+ * @param Port
+ * @param Value
+ */
+inline VOID
+CpuIoOutWord(UINT16 Port, UINT16 Value)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __outword(Port, Value);
+#elif defined(__linux__)
+ __asm__ __volatile__("outw %0, %1" : : "a"(Value), "Nd"(Port));
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Write a dword to an I/O port
+ *
+ * @param Port
+ * @param Value
+ */
+inline VOID
+CpuIoOutDword(UINT16 Port, UINT32 Value)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __outdword(Port, Value);
+#elif defined(__linux__)
+ __asm__ __volatile__("outl %0, %1" : : "a"(Value), "Nd"(Port));
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Write a byte string to an I/O port
+ *
+ * @param Port
+ * @param Data
+ * @param Count
+ */
+inline VOID
+CpuIoOutByteString(UINT16 Port, UINT8 * Data, UINT32 Count)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __outbytestring(Port, Data, Count);
+#elif defined(__linux__)
+ __asm__ __volatile__("rep outsb" : "+S"(Data), "+c"(Count) : "d"(Port) : "memory");
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Write a word string to an I/O port
+ *
+ * @param Port
+ * @param Data
+ * @param Count
+ */
+inline VOID
+CpuIoOutWordString(UINT16 Port, UINT16 * Data, UINT32 Count)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __outwordstring(Port, Data, Count);
+#elif defined(__linux__)
+ __asm__ __volatile__("rep outsw" : "+S"(Data), "+c"(Count) : "d"(Port) : "memory");
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Write a dword string to an I/O port
+ *
+ * @param Port
+ * @param Data
+ * @param Count
+ */
+inline VOID
+CpuIoOutDwordString(UINT16 Port, UINT32 * Data, UINT32 Count)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __outdwordstring(Port, (unsigned long *)Data, Count);
+#elif defined(__linux__)
+ __asm__ __volatile__("rep outsl" : "+S"(Data), "+c"(Count) : "d"(Port) : "memory");
+#else
+# error "Unsupported platform"
+#endif
+}
diff --git a/hyperdbg/include/platform/kernel/code/PlatformIntrinsicsVmx.c b/hyperdbg/include/platform/kernel/code/PlatformIntrinsicsVmx.c
new file mode 100644
index 00000000..e3abc6fa
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/code/PlatformIntrinsicsVmx.c
@@ -0,0 +1,456 @@
+/**
+ * @file PlatformIntrinsicsVmx.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Implementation of cross platform APIs for intrinsic functions (VMX instructions)
+ * @details
+ * @version 0.19
+ * @date 2026-04-27
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+#if defined(__linux__)
+# include "../header/PlatformIntrinsicsVmx.h"
+#endif // defined(__linux__)
+
+#if defined(__linux__)
+
+/**
+ * @brief Linux inline-asm helper for VMREAD
+ * Mirrors __vmx_vmread: returns 0=success, 1=VMfail valid (ZF), 2=VMfail invalid (CF)
+ */
+static inline UCHAR
+__linux_vmx_vmread(size_t Field, size_t * FieldValue)
+{
+ unsigned char cf, zf;
+ __asm__ __volatile__(
+ "vmread %[field], %[val] \n\t"
+ "setc %[cf] \n\t"
+ "setz %[zf] \n\t"
+ : [val] "=rm"(*FieldValue),
+ [cf] "=qm"(cf),
+ [zf] "=qm"(zf)
+ : [field] "r"(Field)
+ : "cc");
+ return cf ? 2 : (zf ? 1 : 0);
+}
+
+/**
+ * @brief Linux inline-asm helper for VMWRITE
+ * Mirrors __vmx_vmwrite: returns 0=success, 1=VMfail valid (ZF), 2=VMfail invalid (CF)
+ */
+static inline UCHAR
+__linux_vmx_vmwrite(size_t Field, size_t FieldValue)
+{
+ unsigned char cf, zf;
+ __asm__ __volatile__(
+ "vmwrite %[val], %[field] \n\t"
+ "setc %[cf] \n\t"
+ "setz %[zf] \n\t"
+ : [cf] "=qm"(cf),
+ [zf] "=qm"(zf)
+ : [val] "rm"(FieldValue),
+ [field] "r"(Field)
+ : "cc");
+ return cf ? 2 : (zf ? 1 : 0);
+}
+
+/**
+ * @brief Linux inline-asm helper for VMPTRST
+ * Stores the current VMCS pointer into the given physical address
+ */
+static inline VOID
+__linux_vmx_vmptrst(UINT64 * VmcsPhysicalAddress)
+{
+ __asm__ __volatile__(
+ "vmptrst %[addr]"
+ :
+ : [addr] "m"(*VmcsPhysicalAddress)
+ : "memory");
+}
+
+/**
+ * @brief Linux inline-asm helper for VMPTRLD
+ * Returns 0=success, 1=VMfail valid (ZF), 2=VMfail invalid (CF)
+ */
+static inline UCHAR
+__linux_vmx_vmptrld(UINT64 * VmcsPhysicalAddress)
+{
+ unsigned char cf, zf;
+ __asm__ __volatile__(
+ "vmptrld %[addr] \n\t"
+ "setc %[cf] \n\t"
+ "setz %[zf] \n\t"
+ : [cf] "=qm"(cf),
+ [zf] "=qm"(zf)
+ : [addr] "m"(*VmcsPhysicalAddress)
+ : "cc", "memory");
+ return cf ? 2 : (zf ? 1 : 0);
+}
+
+/**
+ * @brief Linux inline-asm helper for VMCLEAR
+ * Returns 0=success, 1=VMfail valid (ZF), 2=VMfail invalid (CF)
+ */
+static inline UCHAR
+__linux_vmx_vmclear(UINT64 * VmcsPhysicalAddress)
+{
+ unsigned char cf, zf;
+ __asm__ __volatile__(
+ "vmclear %[addr] \n\t"
+ "setc %[cf] \n\t"
+ "setz %[zf] \n\t"
+ : [cf] "=qm"(cf),
+ [zf] "=qm"(zf)
+ : [addr] "m"(*VmcsPhysicalAddress)
+ : "cc", "memory");
+ return cf ? 2 : (zf ? 1 : 0);
+}
+
+/**
+ * @brief Linux inline-asm helper for VMXON
+ * Returns 0=success, 1=VMfail valid (ZF), 2=VMfail invalid (CF)
+ */
+static inline UCHAR
+__linux_vmx_vmxon(UINT64 * VmxonRegionPhysicalAddress)
+{
+ unsigned char cf, zf;
+ __asm__ __volatile__(
+ "vmxon %[addr] \n\t"
+ "setc %[cf] \n\t"
+ "setz %[zf] \n\t"
+ : [cf] "=qm"(cf),
+ [zf] "=qm"(zf)
+ : [addr] "m"(*VmxonRegionPhysicalAddress)
+ : "cc", "memory");
+ return cf ? 2 : (zf ? 1 : 0);
+}
+
+#endif // defined(__linux__)
+
+/**
+ * @brief VMX VMREAD instruction (64-bit)
+ * @param Field
+ * @param FieldValue
+ *
+ * @return UCHAR
+ */
+inline UCHAR
+VmxVmread64(size_t Field,
+ UINT64 FieldValue)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return __vmx_vmread((size_t)Field, (size_t *)FieldValue);
+#elif defined(__linux__)
+ return __linux_vmx_vmread((size_t)Field, (size_t *)FieldValue);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief VMX VMREAD instruction (32-bit)
+ * @param Field
+ * @param FieldValue
+ *
+ * @return UCHAR
+ */
+inline UCHAR
+VmxVmread32(size_t Field,
+ UINT32 FieldValue)
+{
+ UINT64 TargetField = 0ull;
+ TargetField = FieldValue;
+
+#if defined(_WIN32) || defined(_WIN64)
+ return __vmx_vmread((size_t)Field, (size_t *)TargetField);
+#elif defined(__linux__)
+ return __linux_vmx_vmread((size_t)Field, (size_t *)TargetField);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief VMX VMREAD instruction (16-bit)
+ * @param Field
+ * @param FieldValue
+ *
+ * @return UCHAR
+ */
+inline UCHAR
+VmxVmread16(size_t Field,
+ UINT16 FieldValue)
+{
+ UINT64 TargetField = 0ull;
+ TargetField = FieldValue;
+
+#if defined(_WIN32) || defined(_WIN64)
+ return __vmx_vmread((size_t)Field, (size_t *)TargetField);
+#elif defined(__linux__)
+ return __linux_vmx_vmread((size_t)Field, (size_t *)TargetField);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief VMX VMREAD instruction (64-bit, pointer variant)
+ * @param Field
+ * @param FieldValue
+ *
+ * @return UCHAR
+ */
+inline UCHAR
+VmxVmread64P(size_t Field,
+ UINT64 * FieldValue)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return __vmx_vmread((size_t)Field, (size_t *)FieldValue);
+#elif defined(__linux__)
+ return __linux_vmx_vmread((size_t)Field, (size_t *)FieldValue);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief VMX VMREAD instruction (32-bit, pointer variant)
+ * @param Field
+ * @param FieldValue
+ *
+ * @return UCHAR
+ */
+inline UCHAR
+VmxVmread32P(size_t Field,
+ UINT32 * FieldValue)
+{
+ UINT64 TargetField = 0ull;
+ TargetField = (UINT64)FieldValue;
+
+#if defined(_WIN32) || defined(_WIN64)
+ return __vmx_vmread((size_t)Field, (size_t *)TargetField);
+#elif defined(__linux__)
+ return __linux_vmx_vmread((size_t)Field, (size_t *)TargetField);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief VMX VMREAD instruction (16-bit, pointer variant)
+ * @param Field
+ * @param FieldValue
+ *
+ * @return UCHAR
+ */
+inline UCHAR
+VmxVmread16P(size_t Field,
+ UINT16 * FieldValue)
+{
+ UINT64 TargetField = 0ull;
+ TargetField = (UINT64)FieldValue;
+
+#if defined(_WIN32) || defined(_WIN64)
+ return __vmx_vmread((size_t)Field, (size_t *)TargetField);
+#elif defined(__linux__)
+ return __linux_vmx_vmread((size_t)Field, (size_t *)TargetField);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief VMX VMWRITE instruction (64-bit)
+ * @param Field
+ * @param FieldValue
+ *
+ * @return UCHAR
+ */
+inline UCHAR
+VmxVmwrite64(size_t Field,
+ UINT64 FieldValue)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return __vmx_vmwrite((size_t)Field, (size_t)FieldValue);
+#elif defined(__linux__)
+ return __linux_vmx_vmwrite((size_t)Field, (size_t)FieldValue);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief VMX VMWRITE instruction (32-bit)
+ * @param Field
+ * @param FieldValue
+ *
+ * @return UCHAR
+ */
+inline UCHAR
+VmxVmwrite32(size_t Field,
+ UINT32 FieldValue)
+{
+ UINT64 TargetValue = NULL64_ZERO;
+ TargetValue = (UINT64)FieldValue;
+
+#if defined(_WIN32) || defined(_WIN64)
+ return __vmx_vmwrite((size_t)Field, (size_t)TargetValue);
+#elif defined(__linux__)
+ return __linux_vmx_vmwrite((size_t)Field, (size_t)TargetValue);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief VMX VMWRITE instruction (16-bit)
+ * @param Field
+ * @param FieldValue
+ *
+ * @return UCHAR
+ */
+inline UCHAR
+VmxVmwrite16(size_t Field,
+ UINT16 FieldValue)
+{
+ UINT64 TargetValue = NULL64_ZERO;
+ TargetValue = (UINT64)FieldValue;
+
+#if defined(_WIN32) || defined(_WIN64)
+ return __vmx_vmwrite((size_t)Field, (size_t)TargetValue);
+#elif defined(__linux__)
+ return __linux_vmx_vmwrite((size_t)Field, (size_t)TargetValue);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief VMX VMPTRST instruction
+ *
+ * @param VmcsPhysicalAddress
+ *
+ * @return VOID
+ */
+inline VOID
+VmxVmptrst(UINT64 * VmcsPhysicalAddress)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __vmx_vmptrst(VmcsPhysicalAddress);
+#elif defined(__linux__)
+ __linux_vmx_vmptrst(VmcsPhysicalAddress);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief VMX VMRESUME instruction
+ *
+ * @return VOID
+ */
+inline VOID
+VmxVmresume(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __vmx_vmresume();
+#elif defined(__linux__)
+ __asm__ __volatile__("vmresume" ::: "cc", "memory");
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief VMX VMXOFF instruction
+ *
+ * @return VOID
+ */
+inline VOID
+VmxVmxoff(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __vmx_off();
+#elif defined(__linux__)
+ __asm__ __volatile__("vmxoff" ::: "cc", "memory");
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief VMX VMLAUNCH instruction
+ *
+ * @return VOID
+ */
+inline VOID
+VmxVmlaunch(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __vmx_vmlaunch();
+#elif defined(__linux__)
+ __asm__ __volatile__("vmlaunch" ::: "cc", "memory");
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief VMX VMPTRLD instruction
+ *
+ * @param VmcsPhysicalAddress
+ *
+ * @return UCHAR
+ */
+inline UCHAR
+VmxVmptrld(UINT64 * VmcsPhysicalAddress)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return __vmx_vmptrld(VmcsPhysicalAddress);
+#elif defined(__linux__)
+ return __linux_vmx_vmptrld(VmcsPhysicalAddress);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief VMX VMCLEAR instruction
+ *
+ * @param VmcsPhysicalAddress
+ *
+ * @return UCHAR
+ */
+inline UCHAR
+VmxVmclear(UINT64 * VmcsPhysicalAddress)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return __vmx_vmclear(VmcsPhysicalAddress);
+#elif defined(__linux__)
+ return __linux_vmx_vmclear(VmcsPhysicalAddress);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief VMX VMXON instruction
+ *
+ * @param VmxonRegionPhysicalAddress
+ *
+ * @return UCHAR
+ */
+inline UCHAR
+VmxVmxon(UINT64 * VmxonRegionPhysicalAddress)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return __vmx_on(VmxonRegionPhysicalAddress);
+#elif defined(__linux__)
+ return __linux_vmx_vmxon(VmxonRegionPhysicalAddress);
+#else
+# error "Unsupported platform"
+#endif
+}
diff --git a/hyperdbg/include/platform/kernel/code/PlatformIo.c b/hyperdbg/include/platform/kernel/code/PlatformIo.c
new file mode 100644
index 00000000..36af0a73
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/code/PlatformIo.c
@@ -0,0 +1,89 @@
+/**
+ * @file PlatformIo.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Implementation of cross platform APIs for I/O Request Packet (IRP) management
+ * @details
+ * @version 0.19
+ * @date 2026-05-09
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+#if defined(__linux__)
+# include "../header/PlatformIo.h"
+#endif // defined(__linux__)
+
+/**
+ * @brief Get the current I/O stack location from an IRP
+ *
+ * @param Irp Pointer to the IRP (I/O Request Packet)
+ * @return PIO_STACK_LOCATION Pointer to the current stack location
+ */
+PIO_STACK_LOCATION
+PlatformIoGetCurrentIrpStackLocation(PIRP Irp)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ return IoGetCurrentIrpStackLocation(Irp);
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
+
+/**
+ * @brief Complete an IRP and release it back to the I/O manager
+ *
+ * @param Irp Pointer to the IRP to complete
+ * @param PriorityBoost Priority boost value (e.g., IO_NO_INCREMENT)
+ * @return VOID
+ */
+VOID
+PlatformIoCompleteRequest(PIRP Irp, CCHAR PriorityBoost)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ IoCompleteRequest(Irp, PriorityBoost);
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
+
+/**
+ * @brief Mark the current IRP stack location as pending
+ *
+ * @param Irp Pointer to the IRP to mark as pending
+ * @return VOID
+ */
+VOID
+PlatformIoMarkIrpPending(PIRP Irp)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ IoMarkIrpPending(Irp);
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
diff --git a/hyperdbg/include/platform/kernel/code/PlatformIrql.c b/hyperdbg/include/platform/kernel/code/PlatformIrql.c
new file mode 100644
index 00000000..dd44f269
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/code/PlatformIrql.c
@@ -0,0 +1,63 @@
+/**
+ * @file PlatformIrql.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Implementation of cross platform APIs for IRQL management
+ * @details
+ * @version 0.19
+ * @date 2026-05-09
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+#if defined(__linux__)
+# include "../header/PlatformIrql.h"
+#endif // defined(__linux__)
+
+/**
+ * @brief Raise the current IRQL to DISPATCH_LEVEL
+ *
+ * @return KIRQL The previous IRQL before the raise
+ */
+KIRQL
+PlatformIrqlRaiseToDpcLevel(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ return KeRaiseIrqlToDpcLevel();
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
+
+/**
+ * @brief Lower the current IRQL to the previously saved value
+ *
+ * @param OldIrql The previous IRQL to restore
+ * @return VOID
+ */
+VOID
+PlatformIrqlLower(KIRQL OldIrql)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ KeLowerIrql(OldIrql);
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
diff --git a/hyperdbg/include/platform/kernel/code/PlatformMem.c b/hyperdbg/include/platform/kernel/code/PlatformMem.c
new file mode 100644
index 00000000..27e8112d
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/code/PlatformMem.c
@@ -0,0 +1,280 @@
+/**
+ * @file PlatformMem.c
+ * @author Behrooz Abbassi (BehroozAbbassi@hyperdbg.org)
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @author alireza moradi (alish014)
+ * @brief Implementation of cross APIs for different platforms for memory allocation
+ * @details
+ * @version 0.1
+ * @date 2022-01-17
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+#if defined(__linux__)
+# include "../header/PlatformMem.h"
+#endif // defined(__linux__)
+
+/**
+ * @brief Platform independent wrapper for sprintf_s / snprintf
+ *
+ * @param Buffer output buffer
+ * @param BufferSize size of the output buffer
+ * @param Format format string
+ * @return INT number of characters written, or -1 on error
+ */
+INT
+PlatformSprintf(char * Buffer, SIZE_T BufferSize, const char * Format, ...)
+{
+ va_list Args;
+ va_start(Args, Format);
+ INT Result;
+#if defined(_WIN32) || defined(_WIN64)
+ Result = vsprintf_s(Buffer, BufferSize, Format, Args);
+#elif defined(__linux__)
+ Result = vsnprintf(Buffer, BufferSize, Format, Args);
+#else
+# error "Unsupported platform"
+#endif
+ va_end(Args);
+ return Result;
+}
+
+/////////////////////////////////////////////////
+/// ... New Unified API ...
+/////////////////////////////////////////////////
+
+/**
+ * @brief Allocates a block of memory in the kernel pool.
+ * @details On Windows: Allocates from NonPagedPool and zeroes it.
+ * On Linux: Uses kzalloc (GFP_KERNEL) which zeroes memory.
+ *
+ * @param Size The number of bytes to allocate.
+ * @return PVOID Pointer to the allocated memory, or NULL on failure.
+ */
+PVOID
+PlatformAllocateMemory(
+ SIZE_T Size)
+{
+#ifdef _WIN32
+ PVOID Result = ExAllocatePool2(
+ POOL_FLAG_NON_PAGED, // non-paged pool
+ Size,
+ POOLTAG);
+
+ if (Result != NULL)
+ RtlSecureZeroMemory(Result, Size);
+
+ return Result;
+#else
+ // Linux Kernel: kzalloc allocates zeroed memory
+ PVOID ptr = kzalloc(Size, GFP_KERNEL);
+
+ if (ptr)
+ {
+ printk(KERN_INFO "MemAllocKernel: Allocated %zu bytes at %px\n", Size, ptr);
+ }
+ else
+ {
+ printk(KERN_ERR "MemAllocKernel: failed to allocate %zu bytes\n", Size);
+ }
+
+ return ptr;
+#endif
+}
+
+/**
+ * @brief Frees a previously allocated memory block.
+ * @param Memory Pointer to the memory block. Handles NULL safely.
+ */
+VOID
+PlatformFreeMemory(
+ PVOID Memory)
+{
+ if (!Memory)
+ return;
+
+#ifdef _WIN32
+ ExFreePoolWithTag(Memory, POOLTAG);
+#else
+ kfree(Memory);
+#endif
+}
+
+/**
+ * @brief Writes data from a buffer to a memory address.
+ * @param Process Reserved (unused).
+ * @param Address Destination address.
+ * @param Buffer Source buffer.
+ * @param Size Number of bytes to copy.
+ * @return VOID
+ */
+VOID
+PlatformWriteMemory(
+ PVOID Address, // Destination
+ PVOID Buffer, // Source
+ SIZE_T Size)
+{
+#ifdef _WIN32
+ RtlCopyMemory(Address, Buffer, Size);
+#else
+ memcpy(Address, Buffer, Size);
+#endif
+}
+
+/**
+ * @brief Sets a memory block to a specific value.
+ * @param Destination Memory address.
+ * @param Value Value to set.
+ * @param Size Number of bytes.
+ */
+VOID
+PlatformSetMemory(
+ PVOID Destination,
+ int Value,
+ SIZE_T Size)
+{
+ if (!Destination)
+ return;
+
+#ifdef _WIN32
+ RtlFillMemory(Destination, Size, Value);
+#else
+ memset(Destination, Value, Size);
+#endif
+}
+
+/**
+ * @brief Zeros a memory block.
+ * @param Destination Memory address.
+ * @param Size Number of bytes.
+ */
+VOID
+PlatformZeroMemory(
+ PVOID Destination,
+ SIZE_T Size)
+{
+ if (!Destination)
+ return;
+
+#ifdef _WIN32
+ RtlZeroMemory(Destination, Size);
+#elif defined(__linux__)
+ memset(Destination, 0, Size);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/////////////////////////////////////////////////
+/// ... Backward Compatibility / Specific APIs ...
+/////////////////////////////////////////////////
+
+/**
+ * @brief Allocates contiguous zeroed physical memory.
+ * @details On Windows: Uses MmAllocateContiguousMemory.
+ * On Linux: Uses kmalloc (which is usually physically contiguous) or dma_alloc_coherent.
+ * For simplicity in this driver, we map to kzalloc.
+ * @param NumberOfBytes Size in bytes.
+ * @return PVOID Pointer to memory or NULL.
+ */
+PVOID
+PlatformMemAllocateContiguousZeroedMemory(SIZE_T NumberOfBytes)
+{
+#ifdef _WIN32
+ PVOID Result = NULL;
+ PHYSICAL_ADDRESS MaxPhysicalAddr = {0};
+ MaxPhysicalAddr.QuadPart = MAXULONG64;
+
+ Result = MmAllocateContiguousMemory(NumberOfBytes, MaxPhysicalAddr);
+ if (Result != NULL)
+ RtlSecureZeroMemory(Result, NumberOfBytes);
+ return Result;
+#else
+ // In Linux, kmalloc/kzalloc returns physically contiguous memory
+ // (unless vmalloc is used, which we aren't using here).
+ return kzalloc(NumberOfBytes, GFP_KERNEL);
+#endif
+}
+
+/**
+ * @brief Allocates non-paged pool memory.
+ * @param NumberOfBytes Size in bytes.
+ * @return PVOID Pointer to memory.
+ */
+PVOID
+PlatformMemAllocateNonPagedPool(SIZE_T NumberOfBytes)
+{
+#ifdef _WIN32
+ return ExAllocatePool2(
+ POOL_FLAG_NON_PAGED,
+ NumberOfBytes,
+ POOLTAG);
+#else
+ // Linux kernel memory is non-paged by default (except vmalloc)
+ return kmalloc(NumberOfBytes, GFP_KERNEL);
+#endif
+}
+
+/**
+ * @brief Allocates non-paged pool memory with quota charging.
+ * @param NumberOfBytes Size in bytes.
+ * @return PVOID Pointer to memory.
+ */
+PVOID
+PlatformMemAllocateNonPagedPoolWithQuota(SIZE_T NumberOfBytes)
+{
+#ifdef _WIN32
+ // POOL_FLAG_USE_QUOTA is used with ExAllocatePool2
+ // Note: Ensure your WDK supports ExAllocatePool2, otherwise use ExAllocatePoolWithQuotaTag
+ return ExAllocatePool2(
+ POOL_FLAG_NON_PAGED | POOL_FLAG_USE_QUOTA,
+ NumberOfBytes,
+ POOLTAG);
+#else
+ // Quotas are not explicitly managed in simple Linux kernel allocations like this
+ return kmalloc(NumberOfBytes, GFP_KERNEL);
+#endif
+}
+
+/**
+ * @brief Allocates zeroed non-paged pool memory.
+ * @param NumberOfBytes Size in bytes.
+ * @return PVOID Pointer to memory.
+ */
+PVOID
+PlatformMemAllocateZeroedNonPagedPool(SIZE_T NumberOfBytes)
+{
+#ifdef _WIN32
+ PVOID Result = ExAllocatePool2(
+ POOL_FLAG_NON_PAGED,
+ NumberOfBytes,
+ POOLTAG);
+ if (Result != NULL)
+ RtlSecureZeroMemory(Result, NumberOfBytes);
+ return Result;
+#else
+ return kzalloc(NumberOfBytes, GFP_KERNEL);
+#endif
+}
+
+/**
+ * @brief Frees a memory pool.
+ * @param BufferAddress Pointer to the memory to free.
+ * @return PVOID (Void pointer in original API, usually ignored).
+ */
+PVOID
+PlatformMemFreePool(PVOID BufferAddress)
+{
+ if (!BufferAddress)
+ return NULL;
+
+#ifdef _WIN32
+ ExFreePoolWithTag(BufferAddress, POOLTAG);
+#else
+ kfree(BufferAddress);
+#endif
+ return NULL;
+}
diff --git a/hyperdbg/include/platform/kernel/code/PlatformProcess.c b/hyperdbg/include/platform/kernel/code/PlatformProcess.c
new file mode 100644
index 00000000..5943df34
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/code/PlatformProcess.c
@@ -0,0 +1,131 @@
+/**
+ * @file PlatformProcess.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Implementation of cross platform APIs for process and thread queries
+ * @details
+ * @version 0.19
+ * @date 2026-05-09
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+#if defined(__linux__)
+# include "../header/PlatformProcess.h"
+#endif // defined(__linux__)
+
+/**
+ * @brief Get the current thread ID
+ *
+ * @return HANDLE
+ */
+HANDLE
+PlatformProcessGetCurrentThreadId(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ return PsGetCurrentThreadId();
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
+
+/**
+ * @brief Get the current process ID
+ *
+ * @return HANDLE
+ */
+HANDLE
+PlatformProcessGetCurrentProcessId(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ return PsGetCurrentProcessId();
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
+
+/**
+ * @brief Get the current process (PEPROCESS)
+ *
+ * @return PVOID Pointer to the EPROCESS structure for the current process
+ */
+PVOID
+PlatformProcessGetCurrentProcess(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ return (PVOID)PsGetCurrentProcess();
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
+
+/**
+ * @brief Get the current thread (PETHREAD)
+ *
+ * @return PVOID Pointer to the ETHREAD structure for the current thread
+ */
+PVOID
+PlatformProcessGetCurrentThread(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ return (PVOID)PsGetCurrentThread();
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
+
+/**
+ * @brief Get the TEB (Thread Environment Block) of the current thread
+ *
+ * @return PVOID Pointer to the TEB of the current thread
+ */
+PVOID
+PlatformProcessGetCurrentThreadTeb(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ return PsGetCurrentThreadTeb();
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
diff --git a/hyperdbg/include/platform/kernel/code/PlatformSpinlock.c b/hyperdbg/include/platform/kernel/code/PlatformSpinlock.c
new file mode 100644
index 00000000..7e091499
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/code/PlatformSpinlock.c
@@ -0,0 +1,90 @@
+/**
+ * @file PlatformSpinlock.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Implementation of cross platform APIs for kernel spinlock operations
+ * @details
+ * @version 0.19
+ * @date 2026-05-09
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+#if defined(__linux__)
+# include "../header/PlatformSpinlock.h"
+#endif // defined(__linux__)
+
+/**
+ * @brief Initialize a kernel spinlock
+ *
+ * @param SpinLock Pointer to the KSPIN_LOCK to initialize
+ * @return VOID
+ */
+VOID
+PlatformSpinlockInitialize(PKSPIN_LOCK SpinLock)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ KeInitializeSpinLock(SpinLock);
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
+
+/**
+ * @brief Acquire a kernel spinlock, raising IRQL to DISPATCH_LEVEL
+ *
+ * @param SpinLock Pointer to the KSPIN_LOCK to acquire
+ * @param OldIrql Receives the previous IRQL value to be restored on release
+ * @return VOID
+ */
+VOID
+PlatformSpinlockAcquire(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ KeAcquireSpinLock(SpinLock, OldIrql);
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
+
+/**
+ * @brief Release a previously acquired kernel spinlock and restore IRQL
+ *
+ * @param SpinLock Pointer to the KSPIN_LOCK to release
+ * @param OldIrql The previous IRQL value saved during acquire
+ * @return VOID
+ */
+VOID
+PlatformSpinlockRelease(PKSPIN_LOCK SpinLock, KIRQL OldIrql)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ KeReleaseSpinLock(SpinLock, OldIrql);
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
diff --git a/hyperdbg/include/platform/kernel/code/PlatformTime.c b/hyperdbg/include/platform/kernel/code/PlatformTime.c
new file mode 100644
index 00000000..dcb80a8d
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/code/PlatformTime.c
@@ -0,0 +1,90 @@
+/**
+ * @file PlatformTime.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Implementation of cross platform APIs for system time operations
+ * @details
+ * @version 0.19
+ * @date 2026-05-09
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+#if defined(__linux__)
+# include "../header/PlatformTime.h"
+#endif // defined(__linux__)
+
+/**
+ * @brief Query the current system time
+ *
+ * @param SystemTime Receives the current system time as a LARGE_INTEGER (100-nanosecond units since January 1, 1601)
+ * @return VOID
+ */
+VOID
+PlatformTimeQuerySystemTime(PLARGE_INTEGER SystemTime)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ KeQuerySystemTime(SystemTime);
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
+
+/**
+ * @brief Convert system time (UTC) to local time
+ *
+ * @param SystemTime Pointer to the system time value in UTC
+ * @param LocalTime Receives the converted local time value
+ * @return VOID
+ */
+VOID
+PlatformTimeConvertToLocalTime(PLARGE_INTEGER SystemTime, PLARGE_INTEGER LocalTime)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ ExSystemTimeToLocalTime(SystemTime, LocalTime);
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
+
+/**
+ * @brief Convert a LARGE_INTEGER time value to a TIME_FIELDS structure
+ *
+ * @param Time Pointer to the time value to convert
+ * @param TimeFields Receives the broken-down time fields (year, month, day, hour, minute, etc.)
+ * @return VOID
+ */
+VOID
+PlatformTimeConvertToTimeFields(PLARGE_INTEGER Time, PTIME_FIELDS TimeFields)
+{
+#if defined(_WIN32) || defined(_WIN64)
+
+ RtlTimeToTimeFields(Time, TimeFields);
+
+#elif defined(__linux__)
+
+# error "Not yet implemented"
+
+#else
+
+# error "Unsupported platform"
+
+#endif
+}
diff --git a/hyperdbg/include/platform/kernel/header/Environment.h b/hyperdbg/include/platform/kernel/header/Environment.h
deleted file mode 100644
index fe306852..00000000
--- a/hyperdbg/include/platform/kernel/header/Environment.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * @file Environment.h
- * @author Behrooz Abbassi (BehroozAbbassi@hyperdbg.org)
- * @brief The running environment of HyperDbg
- * @details
- * @version 0.1
- * @date 2022-01-17
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#pragma once
-
-//////////////////////////////////////////////////
-// Definitions //
-//////////////////////////////////////////////////
-
-//
-// Check for platform
-//
-
-#if defined(_WIN32) || defined(_WIN64)
-# define ENV_WINDOWS
-#elif defined(__linux__)
-# error "This code cannot compile on Linux yet"
-# define ENV_LINUX
-#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
-# error "This code cannot compile on BSD yet"
-# define ENV_BSD
-#else
-# error "This code cannot compile on non-Windows, non-Linux, and non-BSD platforms"
-#endif
diff --git a/hyperdbg/include/platform/kernel/header/Mem.h b/hyperdbg/include/platform/kernel/header/Mem.h
deleted file mode 100644
index 5016d131..00000000
--- a/hyperdbg/include/platform/kernel/header/Mem.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * @file Mem.h
- * @author Behrooz Abbassi (BehroozAbbassi@hyperdbg.org)
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief Cross platform APIs for memory allocation
- * @details
- * @version 0.1
- * @date 2022-01-17
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#pragma once
-
-//////////////////////////////////////////////////
-// Functions //
-//////////////////////////////////////////////////
-
-//
-// Some functions are globally defined in SDK
-//
-
-PVOID
-PlatformMemAllocateContiguousZeroedMemory(SIZE_T NumberOfBytes);
-
-// ----------------------------------------------------------------------------
-// Cross Platform Memory Allocate/Free Functions
-//
-PVOID
-PlatformMemAllocateNonPagedPool(SIZE_T NumberOfBytes);
-
-PVOID
-PlatformMemAllocateNonPagedPoolWithQuota(SIZE_T NumberOfBytes);
-
-PVOID
-PlatformMemAllocateZeroedNonPagedPool(SIZE_T NumberOfBytes);
-
-VOID
-PlatformMemFreePool(PVOID BufferAddress);
diff --git a/hyperdbg/hyperhv/header/common/Dpc.h b/hyperdbg/include/platform/kernel/header/PlatformBroadcast.h
similarity index 56%
rename from hyperdbg/hyperhv/header/common/Dpc.h
rename to hyperdbg/include/platform/kernel/header/PlatformBroadcast.h
index 30b419ec..97b2bab1 100644
--- a/hyperdbg/hyperhv/header/common/Dpc.h
+++ b/hyperdbg/include/platform/kernel/header/PlatformBroadcast.h
@@ -1,20 +1,26 @@
/**
- * @file Dpc.h
+ * @file PlatformBroadcast.h
* @author Sina Karvandi (sina@hyperdbg.org)
- * @brief Definition for Windows DPC functions
+ * @brief Cross platform APIs for broadcasting routines
* @details
- * @version 0.1
- * @date 2020-04-10
+ * @version 0.19
+ * @date 2026-05-08
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#pragma once
+#if defined(__linux__)
+# include "../../../../include/SDK/HyperDbgSdk.h"
+#endif // defined(__linux__)
+
//////////////////////////////////////////////////
// Functions //
//////////////////////////////////////////////////
+#if defined(_WIN32) || defined(_WIN64)
+
NTKERNELAPI
_IRQL_requires_max_(APC_LEVEL)
_IRQL_requires_min_(PASSIVE_LEVEL)
@@ -37,3 +43,12 @@ _IRQL_requires_same_
LOGICAL
KeSignalCallDpcSynchronize(
_In_ PVOID SystemArgument2);
+
+#endif // defined(_WIN32) || defined(_WIN64)
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+VOID
+PlatformBroadcastSynchronizeEndOfRoutine(PVOID SystemArgument1, PVOID SystemArgument2);
diff --git a/hyperdbg/include/platform/kernel/header/PlatformCpu.h b/hyperdbg/include/platform/kernel/header/PlatformCpu.h
new file mode 100644
index 00000000..fb3413f9
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/header/PlatformCpu.h
@@ -0,0 +1,26 @@
+/**
+ * @file PlatformCpu.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Cross platform APIs for CPU and processor queries
+ * @details
+ * @version 0.19
+ * @date 2026-05-09
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#if defined(__linux__)
+# include "../../../../include/SDK/HyperDbgSdk.h"
+#endif // defined(__linux__)
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+ULONG
+PlatformCpuGetActiveProcessorCount(VOID);
+
+ULONG
+PlatformCpuGetCurrentProcessorNumber(VOID);
diff --git a/hyperdbg/include/platform/kernel/header/PlatformDbg.h b/hyperdbg/include/platform/kernel/header/PlatformDbg.h
new file mode 100644
index 00000000..c10e6cc3
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/header/PlatformDbg.h
@@ -0,0 +1,23 @@
+/**
+ * @file PlatformDbg.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Cross platform APIs for kernel debug output
+ * @details
+ * @version 0.19
+ * @date 2026-05-09
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#if defined(__linux__)
+# include "../../../../include/SDK/HyperDbgSdk.h"
+#endif // defined(__linux__)
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+VOID
+PlatformDbgPrint(const CHAR * Format, ...);
diff --git a/hyperdbg/include/platform/kernel/header/PlatformDpc.h b/hyperdbg/include/platform/kernel/header/PlatformDpc.h
new file mode 100644
index 00000000..72476ae8
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/header/PlatformDpc.h
@@ -0,0 +1,30 @@
+/**
+ * @file PlatformDpc.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Cross platform APIs for Deferred Procedure Call (DPC) management
+ * @details
+ * @version 0.19
+ * @date 2026-05-09
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#if defined(__linux__)
+# include "../../../../include/SDK/HyperDbgSdk.h"
+#endif // defined(__linux__)
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+#if defined(_WIN32) || defined(_WIN64)
+
+VOID
+PlatformDpcInitialize(PRKDPC Dpc, PKDEFERRED_ROUTINE DeferredRoutine, PVOID DeferredContext);
+
+BOOLEAN
+PlatformDpcInsertQueueDpc(PRKDPC Dpc, PVOID SystemArgument1, PVOID SystemArgument2);
+
+#endif // defined(_WIN32) || defined(_WIN64)
diff --git a/hyperdbg/include/platform/kernel/header/PlatformEvent.h b/hyperdbg/include/platform/kernel/header/PlatformEvent.h
new file mode 100644
index 00000000..da38a7da
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/header/PlatformEvent.h
@@ -0,0 +1,38 @@
+/**
+ * @file PlatformEvent.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Cross platform APIs for kernel event and object management
+ * @details
+ * @version 0.19
+ * @date 2026-05-09
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#if defined(__linux__)
+# include "../../../../include/SDK/HyperDbgSdk.h"
+#endif // defined(__linux__)
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+VOID
+PlatformObjectDereference(PVOID Object);
+
+#if defined(_WIN32) || defined(_WIN64)
+
+LONG
+PlatformEventSet(PKEVENT Event, KPRIORITY Increment, BOOLEAN Wait);
+
+NTSTATUS
+PlatformObjectReferenceByHandle(HANDLE Handle,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_TYPE ObjectType,
+ KPROCESSOR_MODE AccessMode,
+ PVOID * Object,
+ POBJECT_HANDLE_INFORMATION HandleInformation);
+
+#endif // defined(_WIN32) || defined(_WIN64)
diff --git a/hyperdbg/include/platform/kernel/header/PlatformIntrinsics.h b/hyperdbg/include/platform/kernel/header/PlatformIntrinsics.h
new file mode 100644
index 00000000..618fc71b
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/header/PlatformIntrinsics.h
@@ -0,0 +1,365 @@
+/**
+ * @file PlatformIntrinsics.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Cross platform APIs for intrinsic functions (x86 instructions)
+ * @details
+ * @version 0.19
+ * @date 2026-05-05
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#if defined(__linux__)
+# include "../../../../include/SDK/HyperDbgSdk.h"
+#endif // defined(__linux__)
+
+//////////////////////////////////////////////////
+// CR Registers //
+//////////////////////////////////////////////////
+
+//
+// READCR0
+//
+extern inline ULONG_PTR
+ CpuReadCr0(VOID);
+
+//
+// WRITECR0
+//
+extern inline VOID
+CpuWriteCr0(ULONG_PTR Cr0Value);
+
+//
+// READCR2
+//
+extern inline ULONG_PTR
+ CpuReadCr2(VOID);
+
+//
+// WRITECR2
+//
+extern inline VOID
+CpuWriteCr2(ULONG_PTR Cr2Value);
+
+//
+// READCR3
+//
+extern inline ULONG_PTR
+ CpuReadCr3(VOID);
+
+//
+// WRITECR3
+//
+extern inline VOID
+CpuWriteCr3(ULONG_PTR Cr3Value);
+
+//
+// READCR4
+//
+extern inline ULONG_PTR
+ CpuReadCr4(VOID);
+
+//
+// WRITECR4
+//
+extern inline VOID
+CpuWriteCr4(ULONG_PTR Cr4Value);
+
+//
+// READCR8
+//
+extern inline ULONG_PTR
+ CpuReadCr8(VOID);
+
+//
+// WRITECR8
+//
+extern inline VOID
+CpuWriteCr8(ULONG_PTR Cr8Value);
+
+//////////////////////////////////////////////////
+// MSR Instructions //
+//////////////////////////////////////////////////
+
+//
+// RDMSR
+//
+extern inline UINT64
+CpuReadMsr(ULONG MsrAddress);
+
+//
+// WRMSR
+//
+extern inline VOID
+CpuWriteMsr(ULONG MsrAddress, UINT64 MsrValue);
+
+//////////////////////////////////////////////////
+// Debug Register Instructions //
+//////////////////////////////////////////////////
+
+//
+// MOV DR (read)
+//
+#if defined(_WIN32) || defined(_WIN64)
+# define CpuReadDr(DrNumber) __readdr(DrNumber)
+#elif defined(__linux__)
+# define CpuReadDr(DrNumber) \
+ ({ \
+ ULONG_PTR __val; \
+ switch (DrNumber) \
+ { \
+ case 0: \
+ __asm__ volatile("mov %%dr0, %0" : "=r"(__val)); \
+ break; \
+ case 1: \
+ __asm__ volatile("mov %%dr1, %0" : "=r"(__val)); \
+ break; \
+ case 2: \
+ __asm__ volatile("mov %%dr2, %0" : "=r"(__val)); \
+ break; \
+ case 3: \
+ __asm__ volatile("mov %%dr3, %0" : "=r"(__val)); \
+ break; \
+ case 6: \
+ __asm__ volatile("mov %%dr6, %0" : "=r"(__val)); \
+ break; \
+ case 7: \
+ __asm__ volatile("mov %%dr7, %0" : "=r"(__val)); \
+ break; \
+ default: \
+ __val = 0; \
+ break; \
+ } \
+ __val; \
+ })
+#else
+# error "Unsupported platform"
+#endif
+
+//
+// MOV DR (write)
+//
+#if defined(_WIN32) || defined(_WIN64)
+# define CpuWriteDr(DrNumber, DrValue) __writedr(DrNumber, DrValue)
+#elif defined(__linux__)
+# define CpuWriteDr(DrNumber, DrValue) \
+ do \
+ { \
+ switch (DrNumber) \
+ { \
+ case 0: \
+ __asm__ volatile("mov %0, %%dr0" : : "r"((ULONG_PTR)(DrValue))); \
+ break; \
+ case 1: \
+ __asm__ volatile("mov %0, %%dr1" : : "r"((ULONG_PTR)(DrValue))); \
+ break; \
+ case 2: \
+ __asm__ volatile("mov %0, %%dr2" : : "r"((ULONG_PTR)(DrValue))); \
+ break; \
+ case 3: \
+ __asm__ volatile("mov %0, %%dr3" : : "r"((ULONG_PTR)(DrValue))); \
+ break; \
+ case 6: \
+ __asm__ volatile("mov %0, %%dr6" : : "r"((ULONG_PTR)(DrValue))); \
+ break; \
+ case 7: \
+ __asm__ volatile("mov %0, %%dr7" : : "r"((ULONG_PTR)(DrValue))); \
+ break; \
+ default: \
+ break; \
+ } \
+ } while (0)
+#else
+# error "Unsupported platform"
+#endif
+
+//////////////////////////////////////////////////
+// CPUID Instructions //
+//////////////////////////////////////////////////
+
+//
+// CPUID
+//
+extern inline VOID
+CpuCpuId(INT32 * CpuInfo, INT32 FunctionId);
+
+//
+// CPUID (with sub-leaf)
+//
+extern inline VOID
+CpuCpuIdEx(INT32 * CpuInfo, INT32 FunctionId, INT32 SubFunctionId);
+
+//////////////////////////////////////////////////
+// TSC Instructions //
+//////////////////////////////////////////////////
+
+//
+// RDTSC
+//
+extern inline UINT64
+ CpuReadTsc(VOID);
+
+//
+// RDTSCP
+//
+extern inline UINT64
+CpuReadTscp(UINT32 * Aux);
+
+//////////////////////////////////////////////////
+// Interlocked (Atomic) Operations //
+//////////////////////////////////////////////////
+
+extern inline INT64
+CpuInterlockedExchange64(INT64 volatile * Target, INT64 Value);
+
+extern inline INT64
+CpuInterlockedExchangeAdd64(INT64 volatile * Addend, INT64 Value);
+
+extern inline INT64
+CpuInterlockedIncrement64(INT64 volatile * Addend);
+
+extern inline INT64
+CpuInterlockedDecrement64(INT64 volatile * Addend);
+
+extern inline INT64
+CpuInterlockedCompareExchange64(INT64 volatile * Destination, INT64 ExChange, INT64 Comparand);
+
+//////////////////////////////////////////////////
+// Descriptor Table Instructions //
+//////////////////////////////////////////////////
+
+//
+// SIDT
+//
+extern inline VOID
+CpuSidt(VOID * Idtr);
+
+//////////////////////////////////////////////////
+// TLB Instructions //
+//////////////////////////////////////////////////
+
+//
+// INVLPG
+//
+extern inline VOID
+CpuInvlpg(VOID * Address);
+
+//////////////////////////////////////////////////
+// String Store Instructions //
+//////////////////////////////////////////////////
+
+//
+// STOSQ
+//
+extern inline VOID
+CpuStosQ(UINT64 * Destination, UINT64 Value, SIZE_T Count);
+
+//////////////////////////////////////////////////
+// Bit Scan Instructions //
+//////////////////////////////////////////////////
+
+//
+// BSF 64
+//
+extern inline UCHAR
+CpuBitScanForward64(ULONG * Index, UINT64 Mask);
+
+//////////////////////////////////////////////////
+// Misc Instructions //
+//////////////////////////////////////////////////
+
+//
+// NOP
+//
+extern inline VOID
+ CpuNop(VOID);
+
+//
+// PAUSE
+//
+extern inline VOID
+ CpuPause(VOID);
+
+//
+// Segment Limit
+//
+extern inline ULONG
+CpuSegmentLimit(UINT32 Selector);
+
+//////////////////////////////////////////////////
+// I/O Port Instructions //
+//////////////////////////////////////////////////
+
+//
+// IN Byte
+//
+extern inline UINT8
+CpuIoInByte(UINT16 Port);
+
+//
+// IN Word
+//
+extern inline UINT16
+CpuIoInWord(UINT16 Port);
+
+//
+// IN Dword
+//
+extern inline UINT32
+CpuIoInDword(UINT16 Port);
+
+//
+// IN Byte String
+//
+extern inline VOID
+CpuIoInByteString(UINT16 Port, UINT8 * Data, UINT32 Size);
+
+//
+// IN Word String
+//
+extern inline VOID
+CpuIoInWordString(UINT16 Port, UINT16 * Data, UINT32 Size);
+
+//
+// IN Dword String
+//
+extern inline VOID
+CpuIoInDwordString(UINT16 Port, UINT32 * Data, UINT32 Size);
+
+//
+// OUT Byte
+//
+extern inline VOID
+CpuIoOutByte(UINT16 Port, UINT8 Value);
+
+//
+// OUT Word
+//
+extern inline VOID
+CpuIoOutWord(UINT16 Port, UINT16 Value);
+
+//
+// OUT Dword
+//
+extern inline VOID
+CpuIoOutDword(UINT16 Port, UINT32 Value);
+
+//
+// OUT Byte String
+//
+extern inline VOID
+CpuIoOutByteString(UINT16 Port, UINT8 * Data, UINT32 Count);
+
+//
+// OUT Word String
+//
+extern inline VOID
+CpuIoOutWordString(UINT16 Port, UINT16 * Data, UINT32 Count);
+
+//
+// OUT Dword String
+//
+extern inline VOID
+CpuIoOutDwordString(UINT16 Port, UINT32 * Data, UINT32 Count);
diff --git a/hyperdbg/include/platform/kernel/header/PlatformIntrinsicsVmx.h b/hyperdbg/include/platform/kernel/header/PlatformIntrinsicsVmx.h
new file mode 100644
index 00000000..7b27b1aa
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/header/PlatformIntrinsicsVmx.h
@@ -0,0 +1,95 @@
+/**
+ * @file PlatformIntrinsicsVmx.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Cross platform APIs for intrinsic functions (VMX instructions)
+ * @details
+ * @version 0.19
+ * @date 2026-04-27
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#if defined(__linux__)
+# include "../../../../include/SDK/HyperDbgSdk.h"
+#endif // defined(__linux__)
+
+//////////////////////////////////////////////////
+// VMX Instructions //
+//////////////////////////////////////////////////
+
+//
+// VMPTRST
+//
+extern inline VOID
+VmxVmptrst(UINT64 * VmcsPhysicalAddress);
+
+//
+// VMPTRLD
+//
+extern inline UCHAR
+VmxVmptrld(UINT64 * VmcsPhysicalAddress);
+
+//
+// VMCLEAR
+//
+extern inline UCHAR
+VmxVmclear(UINT64 * VmcsPhysicalAddress);
+
+//
+// VMXON
+//
+extern inline UCHAR
+VmxVmxon(UINT64 * VmxonRegionPhysicalAddress);
+
+//
+// VMLAUNCH
+//
+extern inline VOID
+ VmxVmlaunch(VOID);
+
+//
+// VMRESUME
+//
+extern inline VOID
+ VmxVmresume(VOID);
+
+//
+// VMXOFF
+//
+extern inline VOID
+ VmxVmxoff(VOID);
+
+//
+// VMREAD
+//
+extern inline UCHAR
+VmxVmread64(size_t Field, UINT64 FieldValue);
+
+extern inline UCHAR
+VmxVmread32(size_t Field, UINT32 FieldValue);
+
+extern inline UCHAR
+VmxVmread16(size_t Field, UINT16 FieldValue);
+
+extern inline UCHAR
+VmxVmread64P(size_t Field, UINT64 * FieldValue);
+
+extern inline UCHAR
+VmxVmread32P(size_t Field, UINT32 * FieldValue);
+
+extern inline UCHAR
+VmxVmread16P(size_t Field, UINT16 * FieldValue);
+
+//
+// VMWRITE
+//
+extern inline UCHAR
+VmxVmwrite64(size_t Field, UINT64 FieldValue);
+
+extern inline UCHAR
+VmxVmwrite32(size_t Field, UINT32 FieldValue);
+
+extern inline UCHAR
+VmxVmwrite16(size_t Field, UINT16 FieldValue);
diff --git a/hyperdbg/include/platform/kernel/header/PlatformIo.h b/hyperdbg/include/platform/kernel/header/PlatformIo.h
new file mode 100644
index 00000000..e6df744e
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/header/PlatformIo.h
@@ -0,0 +1,33 @@
+/**
+ * @file PlatformIo.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Cross platform APIs for I/O Request Packet (IRP) management
+ * @details
+ * @version 0.19
+ * @date 2026-05-09
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#if defined(__linux__)
+# include "../../../../include/SDK/HyperDbgSdk.h"
+#endif // defined(__linux__)
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+#if defined(_WIN32) || defined(_WIN64)
+
+PIO_STACK_LOCATION
+PlatformIoGetCurrentIrpStackLocation(PIRP Irp);
+
+VOID
+PlatformIoCompleteRequest(PIRP Irp, CCHAR PriorityBoost);
+
+VOID
+PlatformIoMarkIrpPending(PIRP Irp);
+
+#endif // defined(_WIN32) || defined(_WIN64)
diff --git a/hyperdbg/include/platform/kernel/header/PlatformIrql.h b/hyperdbg/include/platform/kernel/header/PlatformIrql.h
new file mode 100644
index 00000000..8ebaa70c
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/header/PlatformIrql.h
@@ -0,0 +1,30 @@
+/**
+ * @file PlatformIrql.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Cross platform APIs for IRQL (Interrupt Request Level) management
+ * @details
+ * @version 0.19
+ * @date 2026-05-09
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#if defined(__linux__)
+# include "../../../../include/SDK/HyperDbgSdk.h"
+#endif // defined(__linux__)
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+#if defined(_WIN32) || defined(_WIN64)
+
+KIRQL
+PlatformIrqlRaiseToDpcLevel(VOID);
+
+VOID
+PlatformIrqlLower(KIRQL OldIrql);
+
+#endif // defined(_WIN32) || defined(_WIN64)
diff --git a/hyperdbg/include/platform/kernel/header/PlatformMem.h b/hyperdbg/include/platform/kernel/header/PlatformMem.h
new file mode 100644
index 00000000..b031fee1
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/header/PlatformMem.h
@@ -0,0 +1,74 @@
+/**
+ * @file PlatformMem.h
+ * @author Behrooz Abbassi (BehroozAbbassi@hyperdbg.org)
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @author Alirez Moradi (alish014)
+ * @brief Cross platform APIs for memory allocation
+ * @details
+ * @version 0.1
+ * @date 2022-01-17
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#if defined(__linux__)
+// # include "../../general/header/GeneralTypes.h"
+# include "../../../../include/SDK/HyperDbgSdk.h"
+#endif // defined(__linux__)
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+INT
+PlatformSprintf(char * Buffer, SIZE_T BufferSize, const char * Format, ...);
+
+VOID
+PlatformFreeMemory(PVOID Memory);
+
+VOID
+PlatformWriteMemory(PVOID Address, PVOID Buffer, SIZE_T Size);
+
+VOID
+PlatformSetMemory(PVOID Destination, int Value, SIZE_T Size);
+
+VOID
+PlatformZeroMemory(PVOID Destination, SIZE_T Size);
+
+VOID
+PlatformFreeMemory(PVOID Memory);
+
+PVOID
+PlatformAllocateMemory(SIZE_T Size);
+
+PVOID
+PlatformMemAllocateContiguousZeroedMemory(SIZE_T NumberOfBytes);
+
+PVOID
+PlatformMemAllocateNonPagedPool(SIZE_T NumberOfBytes);
+
+PVOID
+PlatformMemAllocateNonPagedPoolWithQuota(SIZE_T NumberOfBytes);
+
+PVOID
+PlatformMemAllocateZeroedNonPagedPool(SIZE_T NumberOfBytes);
+
+PVOID
+PlatformMemFreePool(PVOID BufferAddress);
+
+PVOID
+PlatformMemAllocateContiguousZeroedMemory(SIZE_T NumberOfBytes);
+
+PVOID
+PlatformMemAllocateNonPagedPool(SIZE_T NumberOfBytes);
+
+PVOID
+PlatformMemAllocateNonPagedPoolWithQuota(SIZE_T NumberOfBytes);
+
+PVOID
+PlatformMemAllocateZeroedNonPagedPool(SIZE_T NumberOfBytes);
+
+PVOID
+PlatformMemFreePool(PVOID BufferAddress);
diff --git a/hyperdbg/include/platform/kernel/header/PlatformModuleInfo.h b/hyperdbg/include/platform/kernel/header/PlatformModuleInfo.h
new file mode 100644
index 00000000..5f83f048
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/header/PlatformModuleInfo.h
@@ -0,0 +1,17 @@
+// PlatformModuleInfo.h
+
+#if defined(__linux__)
+
+# ifndef MODULE_INFO_H
+# define MODULE_INFO_H
+
+# include
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alish");
+MODULE_DESCRIPTION("Linux Kernel module Mock");
+MODULE_VERSION("0.1");
+
+# endif // _MODULE_INFO_H_
+
+#endif // defined(__linux__)
diff --git a/hyperdbg/include/platform/kernel/header/PlatformProcess.h b/hyperdbg/include/platform/kernel/header/PlatformProcess.h
new file mode 100644
index 00000000..4eedd377
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/header/PlatformProcess.h
@@ -0,0 +1,35 @@
+/**
+ * @file PlatformProcess.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Cross platform APIs for process and thread queries
+ * @details
+ * @version 0.19
+ * @date 2026-05-09
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#if defined(__linux__)
+# include "../../../../include/SDK/HyperDbgSdk.h"
+#endif // defined(__linux__)
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+HANDLE
+PlatformProcessGetCurrentThreadId(VOID);
+
+HANDLE
+PlatformProcessGetCurrentProcessId(VOID);
+
+PVOID
+PlatformProcessGetCurrentProcess(VOID);
+
+PVOID
+PlatformProcessGetCurrentThread(VOID);
+
+PVOID
+PlatformProcessGetCurrentThreadTeb(VOID);
diff --git a/hyperdbg/include/platform/kernel/header/PlatformSpinlock.h b/hyperdbg/include/platform/kernel/header/PlatformSpinlock.h
new file mode 100644
index 00000000..e8327e8e
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/header/PlatformSpinlock.h
@@ -0,0 +1,33 @@
+/**
+ * @file PlatformSpinlock.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Cross platform APIs for kernel spinlock operations
+ * @details
+ * @version 0.19
+ * @date 2026-05-09
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#if defined(__linux__)
+# include "../../../../include/SDK/HyperDbgSdk.h"
+#endif // defined(__linux__)
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+#if defined(_WIN32) || defined(_WIN64)
+
+VOID
+PlatformSpinlockInitialize(PKSPIN_LOCK SpinLock);
+
+VOID
+PlatformSpinlockAcquire(PKSPIN_LOCK SpinLock, PKIRQL OldIrql);
+
+VOID
+PlatformSpinlockRelease(PKSPIN_LOCK SpinLock, KIRQL OldIrql);
+
+#endif // defined(_WIN32) || defined(_WIN64)
diff --git a/hyperdbg/include/platform/kernel/header/PlatformTime.h b/hyperdbg/include/platform/kernel/header/PlatformTime.h
new file mode 100644
index 00000000..b760c184
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/header/PlatformTime.h
@@ -0,0 +1,33 @@
+/**
+ * @file PlatformTime.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Cross platform APIs for system time operations
+ * @details
+ * @version 0.19
+ * @date 2026-05-09
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#if defined(__linux__)
+# include "../../../../include/SDK/HyperDbgSdk.h"
+#endif // defined(__linux__)
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+#if defined(_WIN32) || defined(_WIN64)
+
+VOID
+PlatformTimeQuerySystemTime(PLARGE_INTEGER SystemTime);
+
+VOID
+PlatformTimeConvertToLocalTime(PLARGE_INTEGER SystemTime, PLARGE_INTEGER LocalTime);
+
+VOID
+PlatformTimeConvertToTimeFields(PLARGE_INTEGER Time, PTIME_FIELDS TimeFields);
+
+#endif // defined(_WIN32) || defined(_WIN64)
diff --git a/hyperdbg/include/platform/kernel/header/pch.h b/hyperdbg/include/platform/kernel/header/pch.h
new file mode 100644
index 00000000..3111fda3
--- /dev/null
+++ b/hyperdbg/include/platform/kernel/header/pch.h
@@ -0,0 +1,5 @@
+//
+// DO NOT DELETE OR INCLDUE THIS FILE
+//
+// It is used to tell the Linux compiler that the header "pch.h" is empty while it is used within Windows MSVC compiler
+//
diff --git a/hyperdbg/include/platform/user/code/platform-intrinsics.c b/hyperdbg/include/platform/user/code/platform-intrinsics.c
new file mode 100644
index 00000000..805c78e9
--- /dev/null
+++ b/hyperdbg/include/platform/user/code/platform-intrinsics.c
@@ -0,0 +1,201 @@
+/**
+ * @file platform-intrinsics.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Implementation of cross platform APIs for intrinsic functions (x86 instructions)
+ * @details
+ * @version 0.19
+ * @date 2026-05-06
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+#if defined(__linux__)
+# include "../header/platform-intrinsics.h"
+#endif // defined(__linux__)
+
+//////////////////////////////////////////////////
+// CPUID Instructions //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Execute CPUID
+ *
+ * @param CpuInfo
+ * @param FunctionId
+ */
+ VOID
+CpuCpuId(INT32 * CpuInfo, INT32 FunctionId)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __cpuid(CpuInfo, FunctionId);
+#elif defined(__linux__)
+ __asm__ __volatile__("cpuid" : "=a"(CpuInfo[0]), "=b"(CpuInfo[1]), "=c"(CpuInfo[2]), "=d"(CpuInfo[3]) : "a"(FunctionId), "c"(0));
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Execute CPUID with sub-leaf
+ *
+ * @param CpuInfo
+ * @param FunctionId
+ * @param SubFunctionId
+ */
+ VOID
+CpuCpuIdEx(INT32 * CpuInfo, INT32 FunctionId, INT32 SubFunctionId)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ __cpuidex(CpuInfo, FunctionId, SubFunctionId);
+#elif defined(__linux__)
+ __asm__ __volatile__("cpuid" : "=a"(CpuInfo[0]), "=b"(CpuInfo[1]), "=c"(CpuInfo[2]), "=d"(CpuInfo[3]) : "a"(FunctionId), "c"(SubFunctionId));
+#else
+# error "Unsupported platform"
+#endif
+}
+
+//////////////////////////////////////////////////
+// TSC Instructions //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Read Time-Stamp Counter
+ *
+ * @return UINT64
+ */
+ UINT64
+CpuReadTsc(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return __rdtsc();
+#elif defined(__linux__)
+ UINT32 __lo, __hi;
+ __asm__ __volatile__("rdtsc" : "=a"(__lo), "=d"(__hi));
+ return ((UINT64)__hi << 32) | __lo;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+//////////////////////////////////////////////////
+// Misc Instructions //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Read Time-Stamp Counter (serializing)
+ *
+ * @param Aux processor ID output (may be NULL)
+ * @return UINT64
+ */
+UINT64
+CpuReadTscp(UINT32 * Aux)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return __rdtscp(Aux);
+#elif defined(__linux__)
+ UINT32 __lo, __hi, __aux;
+ __asm__ __volatile__("rdtscp" : "=a"(__lo), "=d"(__hi), "=c"(__aux));
+ if (Aux)
+ *Aux = __aux;
+ return ((UINT64)__hi << 32) | __lo;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Execute PAUSE (spin-wait hint)
+ */
+VOID
+CpuPause(VOID)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ _mm_pause();
+#elif defined(__linux__)
+ __asm__ __volatile__("pause");
+#else
+# error "Unsupported platform"
+#endif
+}
+
+//////////////////////////////////////////////////
+// Interlocked (Atomic) Operations //
+//////////////////////////////////////////////////
+
+INT64
+CpuInterlockedExchange64(INT64 volatile * Target, INT64 Value)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return InterlockedExchange64(Target, Value);
+#elif defined(__linux__)
+ return __atomic_exchange_n(Target, Value, __ATOMIC_SEQ_CST);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+INT64
+CpuInterlockedExchangeAdd64(INT64 volatile * Addend, INT64 Value)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return InterlockedExchangeAdd64(Addend, Value);
+#elif defined(__linux__)
+ return __atomic_fetch_add(Addend, Value, __ATOMIC_SEQ_CST);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+INT64
+CpuInterlockedIncrement64(INT64 volatile * Addend)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return InterlockedIncrement64(Addend);
+#elif defined(__linux__)
+ return __atomic_add_fetch(Addend, 1LL, __ATOMIC_SEQ_CST);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+INT64
+CpuInterlockedDecrement64(INT64 volatile * Addend)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return InterlockedDecrement64(Addend);
+#elif defined(__linux__)
+ return __atomic_sub_fetch(Addend, 1LL, __ATOMIC_SEQ_CST);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+INT64
+CpuInterlockedCompareExchange64(INT64 volatile * Destination, INT64 ExChange, INT64 Comparand)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return InterlockedCompareExchange64(Destination, ExChange, Comparand);
+#elif defined(__linux__)
+ INT64 Expected = Comparand;
+ __atomic_compare_exchange_n(Destination, &Expected, ExChange, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+ return Expected;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+UCHAR
+CpuInterlockedBitTestAndSet(volatile LONG * Base, LONG Bit)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ return _interlockedbittestandset(Base, Bit);
+#elif defined(__linux__)
+ LONG Mask = (1L << Bit);
+ LONG Old = __atomic_fetch_or(Base, Mask, __ATOMIC_SEQ_CST);
+ return (UCHAR)((Old >> Bit) & 1);
+#else
+# error "Unsupported platform"
+#endif
+}
diff --git a/hyperdbg/include/platform/user/code/platform-ioctl.c b/hyperdbg/include/platform/user/code/platform-ioctl.c
new file mode 100644
index 00000000..edfc699d
--- /dev/null
+++ b/hyperdbg/include/platform/user/code/platform-ioctl.c
@@ -0,0 +1,83 @@
+/**
+ * @file platform-ioctl.c
+ * @author Max Raulea (max.raulea@gmail.com)
+ * @brief User mode cross-platform implementation of the local kernel-driver IOCTL transport
+ * @details See platform-ioctl.h. The Windows branch forwards directly to Win32
+ * DeviceIoControl. The Linux branch is currently stubbed (returns FALSE) and is
+ * the home where the ioctl()-based implementation against the /dev/HyperDbg
+ * character device will live once the kernel module exists.
+ *
+ * @version 0.20
+ * @date 2026-06-09
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+#if defined(__linux__)
+# include "../header/platform-ioctl.h"
+#endif // defined(__linux__)
+
+#if defined(_WIN32)
+
+BOOL
+PlatformDeviceIoControl(HANDLE Device,
+ DWORD IoControlCode,
+ LPVOID InBuffer,
+ DWORD InBufferSize,
+ LPVOID OutBuffer,
+ DWORD OutBufferSize,
+ LPDWORD BytesReturned,
+ LPVOID Overlapped)
+{
+ return DeviceIoControl(Device,
+ IoControlCode,
+ InBuffer,
+ InBufferSize,
+ OutBuffer,
+ OutBufferSize,
+ BytesReturned,
+ (LPOVERLAPPED)Overlapped);
+}
+
+#elif defined(__linux__)
+
+//
+// TODO: implement the local driver transport on Linux using ioctl() against a
+// /dev/HyperDbg character device exposed by the kernel module:
+// - open the device once (in the library init path) -> file descriptor stored
+// in g_DeviceHandle
+// - PlatformDeviceIoControl -> ioctl(fd, IoControlCode, ...) with the in/out
+// buffer marshalling the driver expects (likely a single in-out buffer)
+// - close on teardown
+// The kernel module does not exist yet, so this returns failure for now: callers
+// that have already asserted g_DeviceHandle will simply report the IOCTL failed
+// rather than crashing.
+//
+
+BOOL
+PlatformDeviceIoControl(HANDLE Device,
+ DWORD IoControlCode,
+ LPVOID InBuffer,
+ DWORD InBufferSize,
+ LPVOID OutBuffer,
+ DWORD OutBufferSize,
+ LPDWORD BytesReturned,
+ LPVOID Overlapped)
+{
+ (void)Device;
+ (void)IoControlCode;
+ (void)InBuffer;
+ (void)InBufferSize;
+ (void)OutBuffer;
+ (void)OutBufferSize;
+ (void)Overlapped;
+ if (BytesReturned)
+ *BytesReturned = 0;
+ return FALSE;
+}
+
+#else
+# error "Unsupported platform"
+#endif
diff --git a/hyperdbg/include/platform/user/code/platform-lib-calls.c b/hyperdbg/include/platform/user/code/platform-lib-calls.c
new file mode 100644
index 00000000..19768c55
--- /dev/null
+++ b/hyperdbg/include/platform/user/code/platform-lib-calls.c
@@ -0,0 +1,613 @@
+/**
+ * @file platform-lib-calls.c
+ * @author Max Raulea (max.raulea@gmail.com)
+ * @brief User mode Cross platform APIs for platofrm dependend library calls
+ * @details
+ * @version 0.19
+ * @date 2026-06-01
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+#if defined(__linux__)
+# include "../header/platform-lib-calls.h"
+# include
+# include
+# include
+# include
+# include
+#endif // defined(__linux__)
+
+/**
+ * @brief Platform independent wrapper for vsprintf_s / vsnprintf
+ *
+ * @param Buffer output buffer
+ * @param BufferSize size of the output buffer
+ * @param Format format string
+ * @param ArgList variadic argument list
+ * @return INT number of characters written, or -1 on error
+ */
+INT
+PlatformVsnprintf(char * Buffer, SIZE_T BufferSize, const char * Format, va_list ArgList)
+{
+#if defined(_WIN32)
+ return vsprintf_s(Buffer, BufferSize, Format, ArgList);
+#elif defined(__linux__)
+ return vsnprintf(Buffer, BufferSize, Format, ArgList);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper for _strdup / strdup
+ *
+ * @param Str string to duplicate
+ * @return char * pointer to the duplicated string, or NULL on failure
+ */
+char *
+PlatformStrDup(const char * Str)
+{
+#if defined(_WIN32)
+ return _strdup(Str);
+#elif defined(__linux__)
+ return strdup(Str);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper for RtlZeroMemory / memset
+ *
+ * @param Buffer pointer to the memory region to zero
+ * @param Size number of bytes to zero
+ */
+VOID
+PlatformZeroMemory(PVOID Buffer, SIZE_T Size)
+{
+#if defined(_WIN32)
+ RtlZeroMemory(Buffer, Size);
+#elif defined(__linux__)
+ memset(Buffer, 0, Size);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper for QueryPerformanceFrequency
+ *
+ * @param Frequency output — ticks per second
+ * @return BOOLEAN TRUE on success
+ */
+BOOLEAN
+PlatformQueryPerformanceFrequency(LARGE_INTEGER * Frequency)
+{
+#if defined(_WIN32)
+ return (BOOLEAN)QueryPerformanceFrequency((LARGE_INTEGER *)Frequency);
+#elif defined(__linux__)
+ Frequency->QuadPart = 1000000000LL; // clock_gettime gives nanosecond resolution
+ return TRUE;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper for QueryPerformanceCounter
+ *
+ * @param Count output — current tick count
+ * @return BOOLEAN TRUE on success
+ */
+BOOLEAN
+PlatformQueryPerformanceCounter(LARGE_INTEGER * Count)
+{
+#if defined(_WIN32)
+ return (BOOLEAN)QueryPerformanceCounter((LARGE_INTEGER *)Count);
+#elif defined(__linux__)
+ struct timespec Ts;
+ clock_gettime(CLOCK_MONOTONIC, &Ts);
+ Count->QuadPart = (INT64)Ts.tv_sec * 1000000000LL + Ts.tv_nsec;
+ return TRUE;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper for sprintf_s / snprintf
+ *
+ * @param Buffer output buffer
+ * @param BufferSize size of the output buffer
+ * @param Format format string
+ * @return INT number of characters written, or -1 on error
+ */
+INT
+PlatformSprintf(char * Buffer, SIZE_T BufferSize, const char * Format, ...)
+{
+ va_list Args;
+ va_start(Args, Format);
+ INT Result;
+#if defined(_WIN32)
+ Result = vsprintf_s(Buffer, BufferSize, Format, Args);
+#elif defined(__linux__)
+ Result = vsnprintf(Buffer, BufferSize, Format, Args);
+#else
+# error "Unsupported platform"
+#endif
+ va_end(Args);
+ return Result;
+}
+
+/**
+ * @brief Platform independent wrapper for GetCurrentThreadId / gettid
+ *
+ * @return UINT32 thread ID of the calling thread
+ */
+UINT32
+PlatformGetCurrentThreadId(VOID)
+{
+#if defined(_WIN32)
+ return (UINT32)GetCurrentThreadId();
+#elif defined(__linux__)
+ return (UINT32)syscall(SYS_gettid);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper for GetCurrentProcessorNumber / sched_getcpu
+ *
+ * @return UINT32 logical processor index the calling thread is running on
+ */
+UINT32
+PlatformGetCurrentProcessorNumber(VOID)
+{
+#if defined(_WIN32)
+ return (UINT32)GetCurrentProcessorNumber();
+#elif defined(__linux__)
+ return (UINT32)sched_getcpu();
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper for GetCurrentProcessId / getpid
+ *
+ * @return UINT32 PID of the calling process
+ */
+UINT32
+PlatformGetCurrentProcessId(VOID)
+{
+#if defined(_WIN32)
+ return (UINT32)GetCurrentProcessId();
+#elif defined(__linux__)
+ return (UINT32)getpid();
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper to get the current process name
+ *
+ * @return CHAR* pointer to a static buffer holding the process name, or NULL on failure
+ */
+CHAR *
+PlatformGetCurrentProcessName(VOID)
+{
+ static CHAR ProcessNameBuf[MAX_PATH] = {0};
+
+#if defined(_WIN32)
+ //
+ // Use base kernel32 only (no psapi/shlwapi) so this compiles in every
+ // project that builds platform-lib-calls.c (e.g. script-engine, which has
+ // a minimal include set). GetModuleFileNameA(NULL, ...) returns the full
+ // path of the current process image.
+ //
+ if (GetModuleFileNameA(NULL, ProcessNameBuf, MAX_PATH) == 0)
+ {
+ return NULL;
+ }
+
+ //
+ // Return the basename (strip the directory part)
+ //
+ char * LastSeparator = strrchr(ProcessNameBuf, '\\');
+ if (LastSeparator)
+ {
+ return LastSeparator + 1;
+ }
+
+ return ProcessNameBuf;
+
+#elif defined(__linux__)
+ FILE * f = fopen("/proc/self/comm", "r");
+ if (f)
+ {
+ if (fgets(ProcessNameBuf, sizeof(ProcessNameBuf), f))
+ {
+ size_t Len = strlen(ProcessNameBuf);
+ if (Len > 0 && ProcessNameBuf[Len - 1] == '\n')
+ ProcessNameBuf[Len - 1] = '\0';
+ }
+ fclose(f);
+ return ProcessNameBuf;
+ }
+ return NULL;
+
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper for CreateEvent
+ *
+ * @param ManualReset TRUE for a manual-reset event, FALSE for auto-reset
+ * @param InitialState TRUE if the event starts signaled
+ * @return HANDLE to the event, or NULL on failure
+ */
+HANDLE
+PlatformCreateEvent(BOOLEAN ManualReset, BOOLEAN InitialState)
+{
+#if defined(_WIN32)
+ return CreateEvent(NULL, ManualReset, InitialState, NULL);
+#elif defined(__linux__)
+ //
+ // TODO: back this with a pthread mutex+cond (or eventfd) when the Linux
+ // kernel-debugger transport is implemented. For now return a dummy
+ // non-NULL handle so existing NULL-checks treat creation as success.
+ //
+ (void)ManualReset;
+ (void)InitialState;
+ return (HANDLE)(uintptr_t)1;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper for SetEvent
+ */
+BOOLEAN
+PlatformSetEvent(HANDLE EventHandle)
+{
+#if defined(_WIN32)
+ return (BOOLEAN)SetEvent(EventHandle);
+#elif defined(__linux__)
+ (void)EventHandle; // TODO: signal the underlying cond/eventfd
+ return TRUE;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper for ResetEvent
+ */
+BOOLEAN
+PlatformResetEvent(HANDLE EventHandle)
+{
+#if defined(_WIN32)
+ return (BOOLEAN)ResetEvent(EventHandle);
+#elif defined(__linux__)
+ (void)EventHandle; // TODO: clear the underlying cond/eventfd
+ return TRUE;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper for WaitForSingleObject
+ *
+ * @return 0 (WAIT_OBJECT_0) on success
+ */
+DWORD
+PlatformWaitForSingleObject(HANDLE Handle, DWORD TimeoutMilliseconds)
+{
+#if defined(_WIN32)
+ return WaitForSingleObject(Handle, TimeoutMilliseconds);
+#elif defined(__linux__)
+ //
+ // TODO: wait on the underlying cond/eventfd. For now return immediately as
+ // success — no real transport exists yet to wait on.
+ //
+ (void)Handle;
+ (void)TimeoutMilliseconds;
+ return 0;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper for CloseHandle
+ */
+BOOLEAN
+PlatformCloseHandle(HANDLE Handle)
+{
+#if defined(_WIN32)
+ return (BOOLEAN)CloseHandle(Handle);
+#elif defined(__linux__)
+ (void)Handle; // TODO: free the underlying cond/eventfd or close the fd
+ return TRUE;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper for GetLastError
+ */
+DWORD
+PlatformGetLastError(VOID)
+{
+#if defined(_WIN32)
+ return GetLastError();
+#elif defined(__linux__)
+ return (DWORD)errno;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper to write raw bytes to the console
+ *
+ * @details Used to emit pre-encoded UTF-8 byte sequences (e.g. box-drawing
+ * characters) directly to standard output. On Windows this goes
+ * through WriteConsoleA so the console code page is bypassed; on
+ * Linux the terminal is UTF-8 native so the bytes are written as-is.
+ *
+ * @param Buffer pointer to the bytes to write
+ * @param NumberOfBytes number of bytes to write
+ * @return BOOLEAN TRUE on success
+ */
+BOOLEAN
+PlatformWriteConsole(const VOID * Buffer, DWORD NumberOfBytes)
+{
+#if defined(_WIN32)
+ return (BOOLEAN)WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), Buffer, NumberOfBytes, NULL, NULL);
+#elif defined(__linux__)
+ return (BOOLEAN)(fwrite(Buffer, 1, NumberOfBytes, stdout) == NumberOfBytes);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper to create/open a file for writing
+ *
+ * @param Path wide path of the file to create (truncated if it exists)
+ * @return HANDLE to the opened file, or INVALID_HANDLE_VALUE on failure
+ */
+HANDLE
+PlatformOpenFileForWriting(const WCHAR * Path)
+{
+#if defined(_WIN32)
+ return CreateFileW(Path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+#elif defined(__linux__)
+ //
+ // TODO: handle this later. The path arrives as a std::wstring (4-byte
+ // wchar_t on Linux) and must be narrowed to a UTF-8 char* before it
+ // can be handed to fopen. Until that conversion is wired up, fail the
+ // open so callers (e.g. dump.cpp) bail out cleanly instead of writing
+ // to a bogus handle.
+ //
+ (void)Path;
+ return INVALID_HANDLE_VALUE;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper to write a buffer to an open file
+ *
+ * @param FileHandle handle returned by PlatformOpenFileForWriting
+ * @param Buffer pointer to the bytes to write
+ * @param NumberOfBytes number of bytes to write
+ * @return BOOLEAN TRUE on success
+ */
+BOOLEAN
+PlatformWriteFile(HANDLE FileHandle, const VOID * Buffer, DWORD NumberOfBytes)
+{
+#if defined(_WIN32)
+ DWORD BytesWritten;
+ return (BOOLEAN)WriteFile(FileHandle, Buffer, NumberOfBytes, &BytesWritten, NULL);
+#elif defined(__linux__)
+ return (BOOLEAN)(fwrite(Buffer, 1, NumberOfBytes, (FILE *)FileHandle) == NumberOfBytes);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper to close a file opened by
+ * PlatformOpenFileForWriting
+ *
+ * @param FileHandle handle to close
+ * @return BOOLEAN TRUE on success
+ */
+BOOLEAN
+PlatformCloseFile(HANDLE FileHandle)
+{
+#if defined(_WIN32)
+ return (BOOLEAN)CloseHandle(FileHandle);
+#elif defined(__linux__)
+ return (BOOLEAN)(fclose((FILE *)FileHandle) == 0);
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper to map an entire file read-only into memory
+ *
+ * @details The returned pointer stays valid until released with PlatformUnmapFile;
+ * the underlying file/descriptor is closed before returning (the mapping
+ * outlives it on both platforms).
+ *
+ * @param Path wide path of the file to map
+ * @param OutFileSize output — size of the file in bytes (0 on failure)
+ * @return VOID* base address of the mapped file, or NULL on failure
+ */
+VOID *
+PlatformMapFileReadOnly(const WCHAR * Path, PSIZE_T OutFileSize, PHANDLE OutFileHandle)
+{
+#if defined(_WIN32)
+ HANDLE FileHandle;
+ HANDLE MapObjectHandle;
+ VOID * BaseAddr;
+ LARGE_INTEGER FileSize;
+
+ *OutFileSize = 0;
+ *OutFileHandle = INVALID_HANDLE_VALUE;
+
+ FileHandle = CreateFileW(Path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (FileHandle == INVALID_HANDLE_VALUE)
+ {
+ return NULL;
+ }
+
+ if (!GetFileSizeEx(FileHandle, &FileSize))
+ {
+ CloseHandle(FileHandle);
+ return NULL;
+ }
+
+ MapObjectHandle = CreateFileMapping(FileHandle, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (MapObjectHandle == NULL)
+ {
+ CloseHandle(FileHandle);
+ return NULL;
+ }
+
+ BaseAddr = MapViewOfFile(MapObjectHandle, FILE_MAP_READ, 0, 0, 0);
+
+ //
+ // The view stays valid after the mapping object handle is closed. The file
+ // handle is kept open and handed back so the caller can still issue raw
+ // reads (PlatformReadFileAtOffset); it is closed by PlatformUnmapFile.
+ //
+ CloseHandle(MapObjectHandle);
+
+ if (BaseAddr == NULL)
+ {
+ CloseHandle(FileHandle);
+ return NULL;
+ }
+
+ *OutFileSize = (SIZE_T)FileSize.QuadPart;
+ *OutFileHandle = FileHandle;
+ return BaseAddr;
+#elif defined(__linux__)
+ //
+ // TODO (linux): implement the real mapping. Expected contract:
+ // 1. Narrow the 4-byte wchar_t 'Path' to a UTF-8 char* (the project still
+ // lacks a wchar_t->UTF-8 helper; the same one is needed by
+ // PlatformOpenFileForWriting for the dump.cpp write path).
+ // 2. fd = open(narrowed_path, O_RDONLY); // fail -> NULL
+ // 3. fstat(fd, &st) to get the file size.
+ // 4. base = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ // 5. *OutFileHandle = (HANDLE)(intptr_t)fd; // keep fd open for raw reads
+ // 6. *OutFileSize = st.st_size; return base; (return NULL on any failure)
+ // PlatformUnmapFile must then munmap(base, size) and close the fd — which is
+ // why both the size and the handle are passed back in on unmap. The raw-read
+ // path (PlatformReadFileAtOffset) would pread() from that same fd.
+ //
+ // Until implemented, fail the map so PE-parser callers print "could not open
+ // the file" and bail out cleanly instead of dereferencing a bogus pointer.
+ //
+ (void)Path;
+ *OutFileSize = 0;
+ *OutFileHandle = INVALID_HANDLE_VALUE;
+ return NULL;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper for a positioned (seek + read) file read
+ *
+ * @param FileHandle handle handed back by PlatformMapFileReadOnly
+ * @param Offset byte offset to read from (absolute, from start of file)
+ * @param Buffer destination buffer
+ * @param NumberOfBytes number of bytes to read
+ * @param BytesRead output — number of bytes actually read
+ * @return BOOLEAN TRUE on success
+ */
+BOOLEAN
+PlatformReadFileAtOffset(HANDLE FileHandle, UINT64 Offset, VOID * Buffer, DWORD NumberOfBytes, LPDWORD BytesRead)
+{
+#if defined(_WIN32)
+ LARGE_INTEGER Distance;
+ Distance.QuadPart = (LONGLONG)Offset;
+
+ if (!SetFilePointerEx(FileHandle, Distance, NULL, FILE_BEGIN))
+ {
+ return FALSE;
+ }
+
+ return (BOOLEAN)ReadFile(FileHandle, Buffer, NumberOfBytes, BytesRead, NULL);
+#elif defined(__linux__)
+ //
+ // TODO (linux): pread((int)(intptr_t)FileHandle, Buffer, NumberOfBytes, Offset)
+ // once PlatformMapFileReadOnly wraps a real fd. Unreached today
+ // because the map returns NULL on Linux, so callers bail first.
+ //
+ (void)FileHandle;
+ (void)Offset;
+ (void)Buffer;
+ (void)NumberOfBytes;
+ if (BytesRead != NULL)
+ {
+ *BytesRead = 0;
+ }
+ return FALSE;
+#else
+# error "Unsupported platform"
+#endif
+}
+
+/**
+ * @brief Platform independent wrapper to release a mapping from PlatformMapFileReadOnly
+ *
+ * @param BaseAddress base address returned by PlatformMapFileReadOnly
+ * @param FileSize size that was reported by PlatformMapFileReadOnly (needed by munmap)
+ * @param FileHandle file handle handed back by PlatformMapFileReadOnly
+ */
+VOID
+PlatformUnmapFile(VOID * BaseAddress, SIZE_T FileSize, HANDLE FileHandle)
+{
+#if defined(_WIN32)
+ (void)FileSize; // not needed by UnmapViewOfFile
+ if (BaseAddress != NULL)
+ {
+ UnmapViewOfFile(BaseAddress);
+ }
+ if (FileHandle != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(FileHandle);
+ }
+#elif defined(__linux__)
+ //
+ // TODO (linux): munmap(BaseAddress, FileSize) and close the fd behind
+ // FileHandle once PlatformMapFileReadOnly is implemented.
+ // No-op for now since the map always returns NULL.
+ //
+ (void)BaseAddress;
+ (void)FileSize;
+ (void)FileHandle;
+#else
+# error "Unsupported platform"
+#endif
+}
diff --git a/hyperdbg/include/platform/user/code/platform-serial.c b/hyperdbg/include/platform/user/code/platform-serial.c
new file mode 100644
index 00000000..6266c0a8
--- /dev/null
+++ b/hyperdbg/include/platform/user/code/platform-serial.c
@@ -0,0 +1,270 @@
+/**
+ * @file platform-serial.c
+ * @author Max Raulea (max.raulea@gmail.com)
+ * @brief User mode cross-platform implementation of the kernel-debugger serial transport
+ * @details See platform-serial.h. The Windows branch wraps the Win32 serial primitives
+ * (CreateFile / Comm* / overlapped ReadFile/WriteFile) and owns the per-direction
+ * OVERLAPPED state internally so the protocol layer never sees it. The Linux
+ * branch is currently stubbed (returns FALSE/NULL) and is the home where the
+ * termios-based implementation over /dev/tty* will live.
+ *
+ * @version 0.20
+ * @date 2026-06-08
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+#if defined(__linux__)
+# include "../header/platform-serial.h"
+#endif // defined(__linux__)
+
+#if defined(_WIN32)
+
+//
+// Per-direction overlapped I/O state, owned by the transport layer.
+//
+static OVERLAPPED g_PlatformOverlappedReadDebugger = {0};
+static OVERLAPPED g_PlatformOverlappedReadDebuggee = {0};
+static OVERLAPPED g_PlatformOverlappedWriteDebugger = {0};
+
+HANDLE
+PlatformSerialOpen(const char * PortName, PLATFORM_SERIAL_IO_ROLE Role)
+{
+ HANDLE Comm;
+ char PortNo[24] = {0};
+
+ //
+ // Append name to make a Windows-understandable format
+ //
+ sprintf_s(PortNo, sizeof(PortNo), "\\\\.\\%s", PortName);
+
+ if (Role == PLATFORM_SERIAL_IO_DEBUGGEE)
+ {
+ //
+ // Debuggee uses non-overlapped (blocking) I/O
+ //
+ Comm = CreateFile(PortNo,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL);
+
+ g_PlatformOverlappedReadDebuggee.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ }
+ else
+ {
+ //
+ // Debugger uses overlapped (async) I/O
+ //
+ Comm = CreateFile(PortNo,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_OVERLAPPED,
+ NULL);
+
+ g_PlatformOverlappedReadDebugger.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ g_PlatformOverlappedWriteDebugger.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ }
+
+ if (Comm == INVALID_HANDLE_VALUE)
+ {
+ return NULL;
+ }
+
+ //
+ // Purge the serial port
+ //
+ PurgeComm(Comm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
+
+ return Comm;
+}
+
+BOOLEAN
+PlatformSerialConfigure(HANDLE Handle, DWORD BaudRate)
+{
+ DCB SerialParams = {0};
+ SerialParams.DCBlength = sizeof(SerialParams);
+
+ if (GetCommState(Handle, &SerialParams) == FALSE)
+ {
+ return FALSE;
+ }
+
+ SerialParams.BaudRate = BaudRate;
+ SerialParams.ByteSize = 8;
+ SerialParams.StopBits = ONESTOPBIT;
+ SerialParams.Parity = NOPARITY;
+
+ if (SetCommState(Handle, &SerialParams) == FALSE)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOLEAN
+PlatformSerialReadByte(HANDLE Handle,
+ CHAR * OutByte,
+ DWORD * BytesRead,
+ PLATFORM_SERIAL_IO_ROLE Role)
+{
+ OVERLAPPED * Ovl = (Role == PLATFORM_SERIAL_IO_DEBUGGEE)
+ ? &g_PlatformOverlappedReadDebuggee
+ : &g_PlatformOverlappedReadDebugger;
+
+ if (Role == PLATFORM_SERIAL_IO_DEBUGGEE)
+ {
+ //
+ // Apply a read timeout for the debuggee side
+ //
+ COMMTIMEOUTS Timeouts;
+ GetCommTimeouts(Handle, &Timeouts);
+ Timeouts.ReadIntervalTimeout = MAXDWORD;
+ Timeouts.ReadTotalTimeoutConstant = 5000;
+ Timeouts.ReadTotalTimeoutMultiplier = 0;
+ Timeouts.WriteTotalTimeoutConstant = 0;
+ Timeouts.WriteTotalTimeoutMultiplier = 0;
+ SetCommTimeouts(Handle, &Timeouts);
+ }
+
+ if (!ReadFile(Handle, OutByte, sizeof(CHAR), NULL, Ovl))
+ {
+ if (GetLastError() != ERROR_IO_PENDING)
+ {
+ return FALSE;
+ }
+ }
+
+ WaitForSingleObject(Ovl->hEvent, INFINITE);
+ GetOverlappedResult(Handle, Ovl, BytesRead, FALSE);
+ ResetEvent(Ovl->hEvent);
+
+ return TRUE;
+}
+
+BOOLEAN
+PlatformSerialWrite(HANDLE Handle, const void * Buffer, UINT32 Length, BOOLEAN Synchronous)
+{
+ if (Synchronous)
+ {
+ DWORD BytesWritten = 0;
+ if (WriteFile(Handle, Buffer, Length, &BytesWritten, NULL) == FALSE)
+ {
+ return FALSE;
+ }
+ return (BytesWritten == Length);
+ }
+ else
+ {
+ if (WriteFile(Handle, Buffer, Length, NULL, &g_PlatformOverlappedWriteDebugger))
+ {
+ return TRUE;
+ }
+
+ if (GetLastError() != ERROR_IO_PENDING)
+ {
+ return FALSE;
+ }
+
+ if (WaitForSingleObject(g_PlatformOverlappedWriteDebugger.hEvent, INFINITE) != WAIT_OBJECT_0)
+ {
+ return FALSE;
+ }
+
+ ResetEvent(g_PlatformOverlappedWriteDebugger.hEvent);
+ return TRUE;
+ }
+}
+
+BOOLEAN
+PlatformSerialClose(HANDLE Handle)
+{
+ if (g_PlatformOverlappedReadDebugger.hEvent)
+ CloseHandle(g_PlatformOverlappedReadDebugger.hEvent);
+ if (g_PlatformOverlappedReadDebuggee.hEvent)
+ CloseHandle(g_PlatformOverlappedReadDebuggee.hEvent);
+ if (g_PlatformOverlappedWriteDebugger.hEvent)
+ CloseHandle(g_PlatformOverlappedWriteDebugger.hEvent);
+
+ g_PlatformOverlappedReadDebugger.hEvent = NULL;
+ g_PlatformOverlappedReadDebuggee.hEvent = NULL;
+ g_PlatformOverlappedWriteDebugger.hEvent = NULL;
+
+ if (Handle)
+ return (BOOLEAN)CloseHandle(Handle);
+
+ return TRUE;
+}
+
+#elif defined(__linux__)
+
+//
+// TODO: implement the serial transport on Linux using termios over /dev/tty*:
+// - PlatformSerialOpen -> open(PortName, O_RDWR | O_NOCTTY)
+// - PlatformSerialConfigure -> tcgetattr/cfsetspeed/tcsetattr (raw, 8-N-1)
+// - PlatformSerialReadByte -> read() (with VTIME/VMIN or poll() for the timeout role)
+// - PlatformSerialWrite -> write()
+// - PlatformSerialClose -> close()
+// Named-pipe transport would map onto a UNIX domain socket / FIFO.
+//
+// Until then these return failure so the kernel-debugger connection simply
+// reports "not supported on Linux yet" rather than crashing.
+//
+
+HANDLE
+PlatformSerialOpen(const char * PortName, PLATFORM_SERIAL_IO_ROLE Role)
+{
+ (void)PortName;
+ (void)Role;
+ return NULL;
+}
+
+BOOLEAN
+PlatformSerialConfigure(HANDLE Handle, DWORD BaudRate)
+{
+ (void)Handle;
+ (void)BaudRate;
+ return FALSE;
+}
+
+BOOLEAN
+PlatformSerialReadByte(HANDLE Handle,
+ CHAR * OutByte,
+ DWORD * BytesRead,
+ PLATFORM_SERIAL_IO_ROLE Role)
+{
+ (void)Handle;
+ (void)OutByte;
+ (void)Role;
+ if (BytesRead)
+ *BytesRead = 0;
+ return FALSE;
+}
+
+BOOLEAN
+PlatformSerialWrite(HANDLE Handle, const void * Buffer, UINT32 Length, BOOLEAN Synchronous)
+{
+ (void)Handle;
+ (void)Buffer;
+ (void)Length;
+ (void)Synchronous;
+ return FALSE;
+}
+
+BOOLEAN
+PlatformSerialClose(HANDLE Handle)
+{
+ (void)Handle;
+ return TRUE;
+}
+
+#else
+# error "Unsupported platform"
+#endif
diff --git a/hyperdbg/include/platform/user/code/platform-signal.c b/hyperdbg/include/platform/user/code/platform-signal.c
new file mode 100644
index 00000000..b0f83071
--- /dev/null
+++ b/hyperdbg/include/platform/user/code/platform-signal.c
@@ -0,0 +1,137 @@
+/**
+ * @file platform-signal.c
+ * @author Max Raulea (max.raulea@gmail.com)
+ * @brief User mode cross-platform implementation of the console-control handler
+ * @details See platform-signal.h. The Windows branch forwards to SetConsoleCtrlHandler.
+ * The Linux branch blocks the handled signals and dispatches them from a
+ * dedicated sigwait() thread. sigwait() (rather than a sigaction() handler)
+ * is used deliberately: BreakController calls ShowMessages (printf), socket
+ * I/O and Sleep, none of which are async-signal-safe. Running the handler on
+ * a normal thread woken by sigwait() sidesteps that entirely and mirrors the
+ * Windows model where the console-control handler also runs on its own thread.
+ *
+ * @version 0.20
+ * @date 2026-06-16
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+#if defined(__linux__)
+# include "../header/platform-signal.h"
+#endif // defined(__linux__)
+
+#if defined(_WIN32)
+
+BOOLEAN
+PlatformInstallCtrlHandler(PLATFORM_CTRL_HANDLER Handler)
+{
+ return (BOOLEAN)SetConsoleCtrlHandler((PHANDLER_ROUTINE)Handler, TRUE);
+}
+
+#elif defined(__linux__)
+
+# include
+# include
+
+//
+// The installed handler, read by the dispatch thread.
+//
+static PLATFORM_CTRL_HANDLER g_PlatformCtrlHandler = NULL;
+
+//
+// Map a POSIX signal onto the Win32 console-control event the shared handler
+// understands. Only the two interactive break signals are mapped:
+// SIGINT (CTRL+C) -> CTRL_C_EVENT
+// SIGQUIT (CTRL+\) -> CTRL_BREAK_EVENT
+// SIGTERM/SIGHUP are intentionally left at their default disposition so the
+// process stays killable/terminable the usual way; the CLOSE/LOGOFF/SHUTDOWN
+// console events have no clean Linux analog.
+//
+static DWORD
+PlatformMapSignalToCtrlType(int Signal)
+{
+ switch (Signal)
+ {
+ case SIGINT:
+ return CTRL_C_EVENT;
+ case SIGQUIT:
+ return CTRL_BREAK_EVENT;
+ default:
+ return (DWORD)-1;
+ }
+}
+
+//
+// Dedicated thread: waits for the handled signals and dispatches them to the
+// installed handler in ordinary (async-signal-safe) thread context.
+//
+static void *
+PlatformSignalThread(void * Arg)
+{
+ sigset_t WaitSet;
+ int Signal;
+
+ (void)Arg;
+
+ sigemptyset(&WaitSet);
+ sigaddset(&WaitSet, SIGINT);
+ sigaddset(&WaitSet, SIGQUIT);
+
+ while (1)
+ {
+ if (sigwait(&WaitSet, &Signal) != 0)
+ {
+ continue;
+ }
+
+ DWORD CtrlType = PlatformMapSignalToCtrlType(Signal);
+
+ if (g_PlatformCtrlHandler != NULL && CtrlType != (DWORD)-1)
+ {
+ g_PlatformCtrlHandler(CtrlType);
+ }
+ }
+
+ return NULL;
+}
+
+BOOLEAN
+PlatformInstallCtrlHandler(PLATFORM_CTRL_HANDLER Handler)
+{
+ sigset_t BlockSet;
+ pthread_t Thread;
+
+ g_PlatformCtrlHandler = Handler;
+
+ //
+ // Block the handled signals in this (main) thread. Done before any other
+ // thread is created, the mask is inherited by every thread, guaranteeing
+ // the signals are delivered to our sigwait() thread and nowhere else.
+ //
+ sigemptyset(&BlockSet);
+ sigaddset(&BlockSet, SIGINT);
+ sigaddset(&BlockSet, SIGQUIT);
+
+ if (pthread_sigmask(SIG_BLOCK, &BlockSet, NULL) != 0)
+ {
+ return FALSE;
+ }
+
+ if (pthread_create(&Thread, NULL, PlatformSignalThread, NULL) != 0)
+ {
+ return FALSE;
+ }
+
+ //
+ // Fire-and-forget: the thread lives for the life of the process.
+ //
+ pthread_detach(Thread);
+
+ return TRUE;
+}
+
+#else
+# error "Unsupported platform"
+#endif
diff --git a/hyperdbg/include/platform/user/code/windows-only/windows-privilege.c b/hyperdbg/include/platform/user/code/windows-only/windows-privilege.c
new file mode 100644
index 00000000..67f84983
--- /dev/null
+++ b/hyperdbg/include/platform/user/code/windows-only/windows-privilege.c
@@ -0,0 +1,67 @@
+/**
+ * @file windows-privilege.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Implementation of Windows only APIs for adjusting privileges
+ * @details
+ * @version 0.19
+ * @date 2026-05-28
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief Is privileges already adjusted
+ */
+BOOLEAN g_PrivilegesAlreadyAdjusted = FALSE;
+
+/**
+ * @brief Adjust kernel debug privilege
+ *
+ * @return BOOLEAN return TRUE if it was successful or FALSE if there
+ */
+BOOLEAN
+WindowsSetDebugPrivilege()
+{
+#ifdef _WIN32 // Windows
+ BOOL Status;
+ HANDLE Token;
+
+ //
+ // Check if we already adjusted the privilege
+ //
+ if (g_PrivilegesAlreadyAdjusted)
+ {
+ return TRUE;
+ }
+
+ //
+ // Enable Debug privilege
+ //
+ Status = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &Token);
+ if (!Status)
+ {
+ ShowMessages("err, OpenProcessToken failed (%x)\n", GetLastError());
+ return FALSE;
+ }
+
+ Status = SetPrivilege(Token, SE_DEBUG_NAME, TRUE);
+ if (!Status)
+ {
+ CloseHandle(Token);
+ return FALSE;
+ }
+
+ //
+ // Indicate that the privilege is already adjusted
+ //
+ g_PrivilegesAlreadyAdjusted = TRUE;
+
+ CloseHandle(Token);
+ return TRUE;
+
+#elif defined(__linux__) // Linux
+ return TRUE; // No need to adjust privileges on Linux
+#endif
+}
diff --git a/hyperdbg/include/platform/user/header/Environment.h b/hyperdbg/include/platform/user/header/Environment.h
deleted file mode 100644
index fe306852..00000000
--- a/hyperdbg/include/platform/user/header/Environment.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * @file Environment.h
- * @author Behrooz Abbassi (BehroozAbbassi@hyperdbg.org)
- * @brief The running environment of HyperDbg
- * @details
- * @version 0.1
- * @date 2022-01-17
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#pragma once
-
-//////////////////////////////////////////////////
-// Definitions //
-//////////////////////////////////////////////////
-
-//
-// Check for platform
-//
-
-#if defined(_WIN32) || defined(_WIN64)
-# define ENV_WINDOWS
-#elif defined(__linux__)
-# error "This code cannot compile on Linux yet"
-# define ENV_LINUX
-#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
-# error "This code cannot compile on BSD yet"
-# define ENV_BSD
-#else
-# error "This code cannot compile on non-Windows, non-Linux, and non-BSD platforms"
-#endif
diff --git a/hyperdbg/include/platform/user/header/platform-intrinsics.h b/hyperdbg/include/platform/user/header/platform-intrinsics.h
new file mode 100644
index 00000000..f90b7c90
--- /dev/null
+++ b/hyperdbg/include/platform/user/header/platform-intrinsics.h
@@ -0,0 +1,80 @@
+/**
+ * @file platform-intrinsics.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief User mode Cross platform APIs for intrinsic functions (x86 instructions)
+ * @details
+ * @version 0.19
+ * @date 2026-05-06
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#if defined(__linux__)
+# include "../../../../include/SDK/HyperDbgSdk.h"
+#endif // defined(__linux__)
+
+//////////////////////////////////////////////////
+// CPUID Instructions //
+//////////////////////////////////////////////////
+
+//
+// CPUID
+//
+VOID
+CpuCpuId(INT32 * CpuInfo, INT32 FunctionId);
+
+//
+// CPUID (with sub-leaf)
+//
+VOID
+CpuCpuIdEx(INT32 * CpuInfo, INT32 FunctionId, INT32 SubFunctionId);
+
+//////////////////////////////////////////////////
+// TSC Instructions //
+//////////////////////////////////////////////////
+
+//
+// RDTSC
+//
+UINT64
+CpuReadTsc(VOID);
+
+//
+// RDTSCP
+//
+UINT64
+CpuReadTscp(UINT32 * Aux);
+
+//////////////////////////////////////////////////
+// Misc Instructions //
+//////////////////////////////////////////////////
+
+//
+// PAUSE
+//
+VOID
+CpuPause(VOID);
+
+//////////////////////////////////////////////////
+// Interlocked (Atomic) Operations //
+//////////////////////////////////////////////////
+
+INT64
+CpuInterlockedExchange64(INT64 volatile * Target, INT64 Value);
+
+INT64
+CpuInterlockedExchangeAdd64(INT64 volatile * Addend, INT64 Value);
+
+INT64
+CpuInterlockedIncrement64(INT64 volatile * Addend);
+
+INT64
+CpuInterlockedDecrement64(INT64 volatile * Addend);
+
+INT64
+CpuInterlockedCompareExchange64(INT64 volatile * Destination, INT64 ExChange, INT64 Comparand);
+
+UCHAR
+CpuInterlockedBitTestAndSet(volatile LONG * Base, LONG Bit);
diff --git a/hyperdbg/include/platform/user/header/platform-ioctl.h b/hyperdbg/include/platform/user/header/platform-ioctl.h
new file mode 100644
index 00000000..c2c7ce14
--- /dev/null
+++ b/hyperdbg/include/platform/user/header/platform-ioctl.h
@@ -0,0 +1,40 @@
+/**
+ * @file platform-ioctl.h
+ * @author Max Raulea (max.raulea@gmail.com)
+ * @brief User mode cross-platform interface for the local kernel-driver IOCTL transport
+ * @details Distinct from the serial transport (platform-serial), which talks to a remote
+ * debuggee. This interface is the LOCAL control channel: the userspace library
+ * drives the HyperDbg kernel driver through device I/O control codes. The command
+ * and packet layers are platform independent; only the device-control primitive
+ * underneath them is OS specific. Windows maps onto Win32 DeviceIoControl over a
+ * \\.\HyperDbgDebuggerDevice handle; Linux will map onto ioctl() against a
+ * /dev/HyperDbg character device exposed by the (future) kernel module (TODO).
+ *
+ * @version 0.20
+ * @date 2026-06-09
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#if defined(__linux__)
+# include "../../../../include/SDK/HyperDbgSdk.h"
+#endif // defined(__linux__)
+
+//
+// SEND an I/O control code to the local kernel driver. Mirrors the Win32
+// DeviceIoControl signature so the call sites stay verbatim apart from the name.
+// The Overlapped parameter is kept as a void * so the shared signature does not
+// leak OVERLAPPED into the protocol code; synchronous callers pass NULL.
+// Returns TRUE on success; on failure use PlatformGetLastError for the reason.
+//
+BOOL
+PlatformDeviceIoControl(HANDLE Device,
+ DWORD IoControlCode,
+ LPVOID InBuffer,
+ DWORD InBufferSize,
+ LPVOID OutBuffer,
+ DWORD OutBufferSize,
+ LPDWORD BytesReturned,
+ LPVOID Overlapped);
diff --git a/hyperdbg/include/platform/user/header/platform-lib-calls.h b/hyperdbg/include/platform/user/header/platform-lib-calls.h
new file mode 100644
index 00000000..021d4a5b
--- /dev/null
+++ b/hyperdbg/include/platform/user/header/platform-lib-calls.h
@@ -0,0 +1,137 @@
+/**
+ * @file platform-lib-calls.h
+ * @author Max Raulea (max.raulea@gmail.com)
+ * @brief User mode Cross platform APIs for platofrm dependend library calls
+ * @details
+ * @version 0.19
+ * @date 2026-06-01
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#if defined(__linux__)
+# include "../../../../include/SDK/HyperDbgSdk.h"
+#endif // defined(__linux__)
+
+#include
+#include
+
+//
+// VSNPRINTF
+//
+INT
+PlatformVsnprintf(char * Buffer, SIZE_T BufferSize, const char * Format, va_list ArgList);
+
+//
+// STRDUP
+//
+char *
+PlatformStrDup(const char * Str);
+
+//
+// SET MEMORY TO ZERO
+//
+VOID
+PlatformZeroMemory(PVOID Buffer, SIZE_T Size);
+
+//
+// SPRINTF
+//
+INT
+PlatformSprintf(char * Buffer, SIZE_T BufferSize, const char * Format, ...);
+
+//
+// HIGH-RESOLUTION PERFORMANCE COUNTER
+//
+BOOLEAN
+PlatformQueryPerformanceFrequency(LARGE_INTEGER * Frequency);
+
+BOOLEAN
+PlatformQueryPerformanceCounter(LARGE_INTEGER * Count);
+
+//
+// EVENT / SYNCHRONIZATION OBJECTS
+//
+HANDLE
+PlatformCreateEvent(BOOLEAN ManualReset, BOOLEAN InitialState);
+
+BOOLEAN
+PlatformSetEvent(HANDLE EventHandle);
+
+BOOLEAN
+PlatformResetEvent(HANDLE EventHandle);
+
+DWORD
+PlatformWaitForSingleObject(HANDLE Handle, DWORD TimeoutMilliseconds);
+
+BOOLEAN
+PlatformCloseHandle(HANDLE Handle);
+
+//
+// LAST OS ERROR
+//
+// TODO (linux, correctness): the wrappers below only unify the success/failure
+// *boolean* convention. The actual error semantics still differ across platforms
+// and must be reconciled later:
+// - PlatformGetLastError returns raw Linux errno (EACCES=13, ...) which does NOT
+// match the Win32 ERROR_* code space (ERROR_ACCESS_DENIED=5, ...). Code that
+// merely logs/checks-nonzero is fine; code that compares against ERROR_* needs
+// an errno -> ERROR_* mapping here.
+// - Failure sentinels are not uniform across the Win32 calls we wrap: file opens
+// fail with INVALID_HANDLE_VALUE (not NULL), most other handle calls fail with
+// NULL. Callers must test the right one.
+// For now: getting the project to compile is step 1; correctness comes next.
+//
+DWORD
+PlatformGetLastError(VOID);
+
+//
+// CONSOLE OUTPUT (raw bytes to stdout)
+//
+BOOLEAN
+PlatformWriteConsole(const VOID * Buffer, DWORD NumberOfBytes);
+
+//
+// FILE I/O
+//
+HANDLE
+PlatformOpenFileForWriting(const WCHAR * Path);
+
+BOOLEAN
+PlatformWriteFile(HANDLE FileHandle, const VOID * Buffer, DWORD NumberOfBytes);
+
+BOOLEAN
+PlatformCloseFile(HANDLE FileHandle);
+
+//
+// READ-ONLY FILE MAPPING
+//
+// PlatformMapFileReadOnly also hands back the still-open file handle in
+// *OutFileHandle, so callers can issue supplementary raw reads via
+// PlatformReadFileAtOffset; release everything with PlatformUnmapFile.
+//
+VOID *
+PlatformMapFileReadOnly(const WCHAR * Path, PSIZE_T OutFileSize, PHANDLE OutFileHandle);
+
+BOOLEAN
+PlatformReadFileAtOffset(HANDLE FileHandle, UINT64 Offset, VOID * Buffer, DWORD NumberOfBytes, LPDWORD BytesRead);
+
+VOID
+PlatformUnmapFile(VOID * BaseAddress, SIZE_T FileSize, HANDLE FileHandle);
+
+//
+// PROCESS / THREAD IDENTITY
+//
+UINT32
+PlatformGetCurrentThreadId(VOID);
+
+UINT32
+PlatformGetCurrentProcessorNumber(VOID);
+
+UINT32
+PlatformGetCurrentProcessId(VOID);
+
+CHAR *
+ PlatformGetCurrentProcessName(VOID);
diff --git a/hyperdbg/include/platform/user/header/platform-serial.h b/hyperdbg/include/platform/user/header/platform-serial.h
new file mode 100644
index 00000000..f33b48ec
--- /dev/null
+++ b/hyperdbg/include/platform/user/header/platform-serial.h
@@ -0,0 +1,70 @@
+/**
+ * @file platform-serial.h
+ * @author Max Raulea (max.raulea@gmail.com)
+ * @brief User mode cross-platform interface for the kernel-debugger serial transport
+ * @details The kernel-debugging *protocol* in kd.cpp is platform independent; only
+ * the byte transport underneath it (serial COM port / named pipe) is OS
+ * specific. This interface isolates those primitives so the protocol layer
+ * can stay shared. Windows maps onto Win32 (CreateFile / Comm* / overlapped
+ * ReadFile/WriteFile); Linux will map onto termios over /dev/tty* (TODO).
+ *
+ * @version 0.20
+ * @date 2026-06-08
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#if defined(__linux__)
+# include "../../../../include/SDK/HyperDbgSdk.h"
+#endif // defined(__linux__)
+
+//
+// Distinguishes the two I/O modes the transport uses. On Windows the debugger
+// side opens the port for overlapped (async) I/O while the debuggee side uses
+// blocking I/O; this enum lets the platform layer pick the right mechanism
+// without leaking OVERLAPPED into the protocol code.
+//
+typedef enum _PLATFORM_SERIAL_IO_ROLE
+{
+ PLATFORM_SERIAL_IO_DEBUGGER, // overlapped / async reads
+ PLATFORM_SERIAL_IO_DEBUGGEE, // blocking reads (with comm timeout)
+
+} PLATFORM_SERIAL_IO_ROLE;
+
+//
+// OPEN a serial COM port by name for the given role.
+// Returns a transport handle, or NULL on failure.
+//
+HANDLE
+PlatformSerialOpen(const char * PortName, PLATFORM_SERIAL_IO_ROLE Role);
+
+//
+// CONFIGURE baud rate and the fixed 8-N-1 framing the protocol expects.
+//
+BOOLEAN
+PlatformSerialConfigure(HANDLE Handle, DWORD BaudRate);
+
+//
+// READ a single byte. *BytesRead is set to the number of bytes actually read.
+// The caller (protocol layer) owns the packet-assembly loop.
+//
+BOOLEAN
+PlatformSerialReadByte(HANDLE Handle,
+ CHAR * OutByte,
+ DWORD * BytesRead,
+ PLATFORM_SERIAL_IO_ROLE Role);
+
+//
+// WRITE a buffer. Synchronous selects blocking write (debuggee/handshaking)
+// versus overlapped write (debugger).
+//
+BOOLEAN
+PlatformSerialWrite(HANDLE Handle, const void * Buffer, UINT32 Length, BOOLEAN Synchronous);
+
+//
+// CLOSE the transport handle and release any associated OS resources.
+//
+BOOLEAN
+PlatformSerialClose(HANDLE Handle);
diff --git a/hyperdbg/include/platform/user/header/platform-signal.h b/hyperdbg/include/platform/user/header/platform-signal.h
new file mode 100644
index 00000000..9a3f73db
--- /dev/null
+++ b/hyperdbg/include/platform/user/header/platform-signal.h
@@ -0,0 +1,43 @@
+/**
+ * @file platform-signal.h
+ * @author Max Raulea (max.raulea@gmail.com)
+ * @brief User mode cross-platform interface for the console-control (CTRL+C / CTRL+BREAK) handler
+ * @details HyperDbg installs a single handler (BreakController) that pauses the
+ * debuggee when the user hits CTRL+C / CTRL+BREAK. The handler body is
+ * platform independent; only the OS mechanism that delivers the event
+ * and the thread context it runs in are OS specific. This interface
+ * isolates that registration. Windows maps onto SetConsoleCtrlHandler;
+ * Linux maps onto POSIX signals serviced by a dedicated sigwait() thread
+ * so the handler runs in ordinary thread context (matching Windows, which
+ * also dispatches the handler on its own thread).
+ *
+ * @version 0.20
+ * @date 2026-06-16
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#if defined(__linux__)
+# include "../../../../include/SDK/HyperDbgSdk.h"
+#endif // defined(__linux__)
+
+//
+// Console-control handler signature. Matches the Win32 PHANDLER_ROUTINE shape
+// (and BreakController) so the same function pointer is usable on both platforms.
+// CtrlType is one of the CTRL_*_EVENT codes.
+//
+typedef BOOL (*PLATFORM_CTRL_HANDLER)(DWORD CtrlType);
+
+//
+// INSTALL the process console-control handler.
+// Windows: registers Handler via SetConsoleCtrlHandler.
+// Linux: blocks the relevant signals process-wide and starts a dedicated
+// sigwait() thread that translates them into CTRL_*_EVENT codes and
+// invokes Handler. Must be called once, before other threads spawn,
+// so the blocked-signal mask is inherited by every thread.
+// Returns TRUE on success, FALSE on failure.
+//
+BOOLEAN
+PlatformInstallCtrlHandler(PLATFORM_CTRL_HANDLER Handler);
diff --git a/hyperdbg/include/platform/user/header/windows-only/windows-privilege.h b/hyperdbg/include/platform/user/header/windows-only/windows-privilege.h
new file mode 100644
index 00000000..a8c19eaa
--- /dev/null
+++ b/hyperdbg/include/platform/user/header/windows-only/windows-privilege.h
@@ -0,0 +1,23 @@
+/**
+ * @file windows-privilege.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Windows only APIs for adjusting privileges
+ * @details
+ * @version 0.19
+ * @date 2026-05-28
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#if defined(__linux__)
+# include "../../../../include/SDK/HyperDbgSdk.h"
+#endif // defined(__linux__)
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+BOOLEAN
+WindowsSetDebugPrivilege();
diff --git a/hyperdbg/kdserial/kdserial.vcxproj b/hyperdbg/kdserial/kdserial.vcxproj
index d63b62f0..22ed068a 100644
--- a/hyperdbg/kdserial/kdserial.vcxproj
+++ b/hyperdbg/kdserial/kdserial.vcxproj
@@ -1,5 +1,8 @@
+
+
+ debug
@@ -31,6 +34,7 @@
+
@@ -45,7 +49,7 @@
v4.514.0kdserial
- Universal
+ Desktop10.0.10135.0$(LatestTargetPlatformVersion)
@@ -77,6 +81,7 @@
false$(SolutionDir)build\bin\$(Configuration)\$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\
+ falsekdserial
@@ -84,6 +89,7 @@
false$(SolutionDir)build\bin\$(Configuration)\$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\
+ falsefalse
@@ -118,7 +124,7 @@
$(IntDir);%(AdditionalIncludeDirectories);$(KM_IncludePath);$(ProjectDir)..\..\inctruestdcpp20
- Disabled
+ Full$(DDK_LIB_PATH);%(AdditionalLibraryDirectories);$(SolutionDir)libraries\kdserial\$(PlatformTarget)
@@ -138,5 +144,15 @@
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/kdserial/packages.config b/hyperdbg/kdserial/packages.config
new file mode 100644
index 00000000..eb276766
--- /dev/null
+++ b/hyperdbg/kdserial/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/kdserial/usif.c b/hyperdbg/kdserial/usif.c
index 263ec62a..a409130f 100644
--- a/hyperdbg/kdserial/usif.c
+++ b/hyperdbg/kdserial/usif.c
@@ -21,7 +21,7 @@ Abstract:
#define USIF_FIFO_STAT 0x00000044 // FIFO status register
#define USIF_FIFO_STAT_TXFFS 0x00FF0000 // TX filled FIFO stages
#define USIF_FIFO_STAT_RXFFS 0x000000FF // RX filled FIFO stages
-#define USIF_TXD 0x00040000 // Transmisson data register
+#define USIF_TXD 0x00040000 // Transmission data register
#define USIF_RXD 0x00080000 // Reception data register
// ------------------------------------------------------------------ Functions
diff --git a/hyperdbg/libhyperdbg/CMakeLists.txt b/hyperdbg/libhyperdbg/CMakeLists.txt
index 91d5ce95..fac7603f 100644
--- a/hyperdbg/libhyperdbg/CMakeLists.txt
+++ b/hyperdbg/libhyperdbg/CMakeLists.txt
@@ -1,6 +1,6 @@
# Code generated by Visual Studio kit, DO NOT EDIT.
set(SourceFiles
- "../include/platform/user/header/Environment.h"
+ "../include/platform/general/header/Environment.h"
"../include/platform/user/header/Windows.h"
"header/assembler.h"
"header/commands.h"
@@ -27,6 +27,11 @@ set(SourceFiles
"header/transparency.h"
"header/ud.h"
"pch.h"
+ "../include/platform/user/code/platform-intrinsics.c"
+ "../include/platform/user/code/platform-lib-calls.c"
+ "../include/platform/user/code/platform-serial.c"
+ "../include/platform/user/code/platform-ioctl.c"
+ "../include/platform/user/code/platform-signal.c"
"../script-eval/code/Functions.c"
"../script-eval/code/Keywords.c"
"../script-eval/code/PseudoRegisters.c"
@@ -166,4 +171,23 @@ include_directories(
"../script-eval"
"../dependencies/keystone/include"
)
+set_source_files_properties(
+ "../include/platform/user/code/platform-intrinsics.c"
+ "../include/platform/user/code/platform-lib-calls.c"
+ "../include/platform/user/code/platform-serial.c"
+ "../include/platform/user/code/platform-ioctl.c"
+ "../include/platform/user/code/platform-signal.c"
+ "../script-eval/code/Functions.c"
+ "../script-eval/code/Keywords.c"
+ "../script-eval/code/PseudoRegisters.c"
+ "../script-eval/code/Regs.c"
+ "../script-eval/code/ScriptEngineEval.c"
+ PROPERTIES LANGUAGE CXX
+)
+
+if(UNIX)
+ list(REMOVE_ITEM SourceFiles "code/debugger/script-engine/symbol.cpp")
+ list(APPEND SourceFiles "code/debugger/script-engine/symbol-linux.cpp")
+endif()
+
add_library(libhyperdbg SHARED ${SourceFiles})
diff --git a/hyperdbg/libhyperdbg/code/app/libhyperdbg.cpp b/hyperdbg/libhyperdbg/code/app/libhyperdbg.cpp
index 30ffee01..5a2c812a 100644
--- a/hyperdbg/libhyperdbg/code/app/libhyperdbg.cpp
+++ b/hyperdbg/libhyperdbg/code/app/libhyperdbg.cpp
@@ -18,535 +18,80 @@ using namespace std;
//
extern HANDLE g_DeviceHandle;
extern HANDLE g_IsDriverLoadedSuccessfully;
-extern BOOLEAN g_IsVmxOffProcessStart;
-extern PVOID g_MessageHandler;
-extern PVOID g_MessageHandlerSharedBuffer;
+extern BOOLEAN g_IsMessageLoggingWindowClosed;
extern TCHAR g_DriverLocation[MAX_PATH];
extern TCHAR g_DriverName[MAX_PATH];
extern BOOLEAN g_UseCustomDriverLocation;
extern LIST_ENTRY g_EventTrace;
-extern BOOLEAN g_LogOpened;
-extern BOOLEAN g_BreakPrintingOutput;
-extern BOOLEAN g_IsConnectedToRemoteDebugger;
-extern BOOLEAN g_OutputSourcesInitialized;
-extern BOOLEAN g_IsSerialConnectedToRemoteDebugger;
-extern BOOLEAN g_IsDebuggerModulesLoaded;
-extern BOOLEAN g_IsReversingMachineModulesLoaded;
-extern BOOLEAN g_PrivilegesAlreadyAdjusted;
-extern LIST_ENTRY g_OutputSources;
+extern BOOLEAN g_IsKdModuleLoaded;
+extern BOOLEAN g_IsVmmModuleLoaded;
+extern BOOLEAN g_IsHyperTraceModuleLoaded;
/**
- * @brief Set the function callback that will be called if any message
- * needs to be shown
- *
- * @param Handler Function that handles the messages
- * @return VOID
- */
-VOID
-SetTextMessageCallback(PVOID Handler)
-{
- g_MessageHandler = Handler;
-}
-
-/**
- * @brief Set the function callback that will be called if any message
- * needs to be shown
- *
- * @param Handler Function that handles the messages
- * @return PVOID
- */
-PVOID
-SetTextMessageCallbackUsingSharedBuffer(PVOID Handler)
-{
- g_MessageHandler = Handler;
- g_MessageHandlerSharedBuffer = malloc(COMMUNICATION_BUFFER_SIZE + TCP_END_OF_BUFFER_CHARS_COUNT);
-
- if (!g_MessageHandlerSharedBuffer)
- {
- g_MessageHandler = NULL;
- return NULL;
- }
-
- RtlZeroMemory(g_MessageHandlerSharedBuffer, COMMUNICATION_BUFFER_SIZE + TCP_END_OF_BUFFER_CHARS_COUNT);
-
- return g_MessageHandlerSharedBuffer;
-}
-
-/**
- * @brief Unset the function callback that will be called if any message
- * needs to be shown
- *
- * @return VOID
- */
-VOID
-UnsetTextMessageCallback()
-{
- g_MessageHandler = NULL;
- free(g_MessageHandlerSharedBuffer);
- g_MessageHandlerSharedBuffer = NULL;
-}
-
-/**
- * @brief Show messages
- *
- * @param Fmt format string message
- * @param ... arguments
- * @return VOID
- */
-VOID
-ShowMessages(const char * Fmt, ...)
-{
- va_list ArgList;
- va_list Args;
- char TempMessage[COMMUNICATION_BUFFER_SIZE + TCP_END_OF_BUFFER_CHARS_COUNT] = {0};
-
- if (g_MessageHandler == NULL && !g_IsConnectedToRemoteDebugger && !g_IsSerialConnectedToRemoteDebugger)
- {
- va_start(Args, Fmt);
-
- vprintf(Fmt, Args);
-
- va_end(Args);
-
- if (!g_LogOpened)
- {
- return;
- }
- }
-
- va_start(ArgList, Fmt);
-
- int SprintfResult = vsprintf_s(TempMessage, Fmt, ArgList);
-
- va_end(ArgList);
-
- if (SprintfResult != -1)
- {
- if (g_IsConnectedToRemoteDebugger)
- {
- //
- // vsprintf_s and vswprintf_s return the number of characters written,
- // not including the terminating null character, or a negative value
- // if an output error occurs.
- //
- RemoteConnectionSendResultsToHost(TempMessage, SprintfResult);
- }
- else if (g_IsSerialConnectedToRemoteDebugger)
- {
- KdSendUsermodePrints(TempMessage, SprintfResult);
- }
-
- if (g_LogOpened)
- {
- //
- // .logopen command executed
- //
- LogopenSaveToFile(TempMessage);
- }
- if (g_MessageHandler != NULL)
- {
- //
- // There is another handler
- //
- if (g_MessageHandlerSharedBuffer == NULL)
- {
- ((SendMessageWithParamCallback)g_MessageHandler)(TempMessage);
- }
- else
- {
- memcpy(g_MessageHandlerSharedBuffer, TempMessage, strlen(TempMessage) + 1);
- ((SendMessageWWithSharedBufferCallback)g_MessageHandler)();
- }
- }
- }
-}
-
-/**
- * @brief Read kernel buffers using IRP Pending
- *
- * @param Device Driver handle
- * @return VOID
- */
-VOID
-ReadIrpBasedBuffer()
-{
- BOOL Status;
- ULONG ReturnedLength;
- REGISTER_NOTIFY_BUFFER RegisterEvent;
- UINT32 OperationCode;
- DWORD ErrorNum;
- HANDLE Handle;
-
- RegisterEvent.hEvent = NULL;
- RegisterEvent.Type = IRP_BASED;
-
- //
- // Create another handle to be used in for reading kernel messages,
- // it is because I noticed that if I use a same handle for IRP Pending
- // and other IOCTLs then if I complete that IOCTL then both of the current
- // IOCTL and the Pending IRP are completed and return to user mode,
- // even if it's odd but that what happens, so this way we can solve it
- // if you know why this problem happens, then contact me !
- //
- Handle = CreateFileA(
- "\\\\.\\HyperDbgDebuggerDevice",
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, /// lpSecurityAttirbutes
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
- NULL); /// lpTemplateFile
-
- if (Handle == INVALID_HANDLE_VALUE)
- {
- ErrorNum = GetLastError();
-
- if (ErrorNum == ERROR_ACCESS_DENIED)
- {
- ShowMessages("err, access denied\nare you sure you have administrator "
- "rights?\n");
- }
- else if (ErrorNum == ERROR_GEN_FAILURE)
- {
- ShowMessages("err, a device attached to the system is not functioning\n"
- "vmx feature might be disabled from BIOS or VBS/HVCI is active\n");
- }
- else
- {
- ShowMessages("err, CreateFile failed with (%x)\n", ErrorNum);
- }
-
- g_DeviceHandle = NULL;
- Handle = NULL;
-
- return;
- }
-
- //
- // allocate buffer for transferring messages
- //
- char * OutputBuffer = (char *)malloc(UsermodeBufferSize);
-
- try
- {
- while (TRUE)
- {
- if (!g_IsVmxOffProcessStart)
- {
- //
- // Clear the buffer
- //
- ZeroMemory(OutputBuffer, UsermodeBufferSize);
-
- Sleep(DefaultSpeedOfReadingKernelMessages); // we're not trying to eat all of the CPU ;)
-
- Status = DeviceIoControl(
- Handle, // Handle to device
- IOCTL_REGISTER_EVENT, // IO Control Code (IOCTL)
- &RegisterEvent, // Input Buffer to driver.
- SIZEOF_REGISTER_EVENT * 2, // Length of input buffer in bytes. (x 2 is bcuz as the
- // driver is x64 and has 64 bit values)
- OutputBuffer, // Output Buffer from driver.
- UsermodeBufferSize, // Length of output buffer in bytes.
- &ReturnedLength, // Bytes placed in buffer.
- NULL // synchronous call
- );
-
- if (!Status)
- {
- //
- // Error occurred for second time, and we show the error message
- //
- // ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
-
- //
- // if we reach here, the packet is probably failed, it might
- // be because of using flush command
- //
- continue;
- }
-
- //
- // Compute the received buffer's operation code
- //
- OperationCode = 0;
- memcpy(&OperationCode, OutputBuffer, sizeof(UINT32));
-
- /*
- ShowMessages("Returned Length : 0x%x \n", ReturnedLength);
- ShowMessages("Operation Code : 0x%x \n", OperationCode);
- */
-
- switch (OperationCode)
- {
- case OPERATION_LOG_NON_IMMEDIATE_MESSAGE:
-
- if (g_BreakPrintingOutput)
- {
- //
- // means that the user asserts a CTRL+C or CTRL+BREAK Signal
- // we shouldn't show or save anything in this case
- //
- continue;
- }
-
- ShowMessages("%s", OutputBuffer + sizeof(UINT32));
-
- break;
- case OPERATION_LOG_INFO_MESSAGE:
-
- if (g_BreakPrintingOutput)
- {
- //
- // means that the user asserts a CTRL+C or CTRL+BREAK Signal
- // we shouldn't show or save anything in this case
- //
- continue;
- }
-
- ShowMessages("%s", OutputBuffer + sizeof(UINT32));
-
- break;
- case OPERATION_LOG_ERROR_MESSAGE:
- if (g_BreakPrintingOutput)
- {
- //
- // means that the user asserts a CTRL+C or CTRL+BREAK Signal
- // we shouldn't show or save anything in this case
- //
- continue;
- }
-
- ShowMessages("%s", OutputBuffer + sizeof(UINT32));
-
- break;
- case OPERATION_LOG_WARNING_MESSAGE:
-
- if (g_BreakPrintingOutput)
- {
- //
- // means that the user asserts a CTRL+C or CTRL+BREAK Signal
- // we shouldn't show or save anything in this case
- //
- continue;
- }
-
- ShowMessages("%s", OutputBuffer + sizeof(UINT32));
-
- break;
-
- case OPERATION_COMMAND_FROM_DEBUGGER_CLOSE_AND_UNLOAD_VMM:
-
- KdCloseConnection();
-
- break;
-
- case OPERATION_DEBUGGEE_USER_INPUT:
-
- KdHandleUserInputInDebuggee((DEBUGGEE_USER_INPUT_PACKET *)(OutputBuffer + sizeof(UINT32)));
-
- break;
-
- case OPERATION_DEBUGGEE_REGISTER_EVENT:
-
- KdRegisterEventInDebuggee(
- (PDEBUGGER_GENERAL_EVENT_DETAIL)(OutputBuffer + sizeof(UINT32)),
- ReturnedLength);
-
- break;
-
- case OPERATION_DEBUGGEE_ADD_ACTION_TO_EVENT:
-
- KdAddActionToEventInDebuggee(
- (PDEBUGGER_GENERAL_ACTION)(OutputBuffer + sizeof(UINT32)),
- ReturnedLength);
-
- break;
-
- case OPERATION_DEBUGGEE_CLEAR_EVENTS:
-
- KdSendModifyEventInDebuggee(
- (PDEBUGGER_MODIFY_EVENTS)(OutputBuffer + sizeof(UINT32)),
- TRUE);
-
- break;
-
- case OPERATION_DEBUGGEE_CLEAR_EVENTS_WITHOUT_NOTIFYING_DEBUGGER:
-
- KdSendModifyEventInDebuggee(
- (PDEBUGGER_MODIFY_EVENTS)(OutputBuffer + sizeof(UINT32)),
- FALSE);
-
- break;
-
- case OPERATION_HYPERVISOR_DRIVER_IS_SUCCESSFULLY_LOADED:
-
- //
- // Indicate that driver (Hypervisor) is loaded successfully
- //
- SetEvent(g_IsDriverLoadedSuccessfully);
-
- break;
-
- case OPERATION_HYPERVISOR_DRIVER_END_OF_IRPS:
-
- //
- // End of receiving messages (IRPs), nothing to do
- //
- break;
-
- case OPERATION_COMMAND_FROM_DEBUGGER_RELOAD_SYMBOL:
-
- //
- // Pause debugger after getting the results
- //
- KdReloadSymbolsInDebuggee(TRUE,
- ((PDEBUGGEE_SYMBOL_REQUEST_PACKET)(OutputBuffer + sizeof(UINT32)))->ProcessId);
-
- break;
-
- case OPERATION_NOTIFICATION_FROM_USER_DEBUGGER_PAUSE:
-
- //
- // handle pausing packet from user debugger
- //
- UdHandleUserDebuggerPausing(
- (PDEBUGGEE_UD_PAUSED_PACKET)(OutputBuffer + sizeof(UINT32)));
-
- break;
-
- default:
-
- //
- // Check if there are available output sources
- //
- if (!g_OutputSourcesInitialized || !ForwardingCheckAndPerformEventForwarding(OperationCode,
- OutputBuffer + sizeof(UINT32),
- ReturnedLength - sizeof(UINT32) - 1))
- {
- if (g_BreakPrintingOutput)
- {
- //
- // means that the user asserts a CTRL+C or CTRL+BREAK Signal
- // we shouldn't show or save anything in this case
- //
- continue;
- }
-
- ShowMessages("%s", OutputBuffer + sizeof(UINT32));
- }
-
- break;
- }
- }
- else
- {
- //
- // the thread should not work anymore
- //
- free(OutputBuffer);
-
- //
- // closeHandle
- //
- if (!CloseHandle(Handle))
- {
- ShowMessages("err, closing handle 0x%x\n", GetLastError());
- }
-
- return;
- }
- }
- }
- catch (const std::exception &)
- {
- ShowMessages("err, exception occurred in creating handle or parsing buffer\n");
- }
-
- free(OutputBuffer);
-
- //
- // closeHandle
- //
- if (!CloseHandle(Handle))
- {
- ShowMessages("err, closing handle 0x%x\n", GetLastError());
- };
-}
-
-/**
- * @brief Create a thread for pending buffers
- *
- * @param Data
- * @return DWORD Device Handle
- */
-DWORD WINAPI
-IrpBasedBufferThread(void * data)
-{
- //
- // Do stuff. This will be the first function called on the new
- // thread. When this function returns, the thread goes away. See
- // MSDN for more details. Test Irp Based Notifications
- //
- ReadIrpBasedBuffer();
-
- return 0;
-}
-
-/**
- * @brief Adjust kernel debug privilege
- *
- * @return BOOLEAN return TRUE if it was successful or FALSE if there
- */
-BOOLEAN
-SetDebugPrivilege()
-{
- BOOL Status;
- HANDLE Token;
-
- //
- // Check if we already adjusted the privilege
- //
- if (g_PrivilegesAlreadyAdjusted)
- {
- return TRUE;
- }
-
- //
- // Enable Debug privilege
- //
- Status = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &Token);
- if (!Status)
- {
- ShowMessages("err, OpenProcessToken failed (%x)\n", GetLastError());
- return FALSE;
- }
-
- Status = SetPrivilege(Token, SE_DEBUG_NAME, TRUE);
- if (!Status)
- {
- CloseHandle(Token);
- return FALSE;
- }
-
- //
- // Indicate that the privilege is already adjusted
- //
- g_PrivilegesAlreadyAdjusted = TRUE;
-
- CloseHandle(Token);
- return TRUE;
-}
-
-/**
- * @brief Install VMM driver
+ * @brief Install (start) VMM driver
*
* @return INT return zero if it was successful or non-zero if there
* was error
*/
INT
-HyperDbgInstallVmmDriver()
+HyperDbgStartDriver()
{
+ if (!ManageDriver(g_DriverName, g_DriverLocation, DRIVER_FUNC_INSTALL))
+ {
+ //
+ // Error - remove driver
+ //
+ ManageDriver(g_DriverName, g_DriverLocation, DRIVER_FUNC_REMOVE);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Stop the driver
+ *
+ * @return INT return zero if it was successful or non-zero if there
+ * was error
+ */
+INT
+HyperDbgStopDriver(LPCTSTR DriverName)
+{
+ //
+ // Unload the driver if loaded
+ //
+ if (g_DriverLocation[0] != (TCHAR)0 && ManageDriver(DriverName, g_DriverLocation, DRIVER_FUNC_STOP))
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+/**
+ * @brief Install KD (Kernel Debugger) driver
+ *
+ * @return INT return zero if it was successful or non-zero if there
+ * was error
+ */
+INT
+HyperDbgInstallKdDriver()
+{
+ //
+ // Check if the driver is already loaded, if that's the case, we shouldn't try to load it again
+ //
+ if (g_IsKdModuleLoaded)
+ {
+ //
+ // The driver is already loaded, so we shouldn't try to load it again
+ // but we can consider it as success and return zero
+ //
+ return 0;
+ }
+
//
// The driver is not started yet so let us the install driver
// First setup full path to driver name
@@ -569,14 +114,9 @@ HyperDbgInstallVmmDriver()
strcpy_s(g_DriverName, KERNEL_DEBUGGER_DRIVER_NAME);
}
- if (!ManageDriver(g_DriverName, g_DriverLocation, DRIVER_FUNC_INSTALL))
+ if (HyperDbgStartDriver() != 0)
{
- ShowMessages("unable to install VMM driver\n");
-
- //
- // Error - remove driver
- //
- ManageDriver(g_DriverName, g_DriverLocation, DRIVER_FUNC_REMOVE);
+ ShowMessages("unable to install KD driver\n");
return 1;
}
@@ -585,35 +125,23 @@ HyperDbgInstallVmmDriver()
}
/**
- * @brief Stop the driver
+ * @brief Start KD driver
*
- * @return int return zero if it was successful or non-zero if there
- * was error
+ * @return INT return zero if it was successful or non-zero if there was error
*/
-int
-HyperDbgStopDriver(LPCTSTR DriverName)
+INT
+HyperDbgStartKdDriver()
{
- //
- // Unload the driver if loaded
- //
- if (g_DriverLocation[0] != (TCHAR)0 && ManageDriver(DriverName, g_DriverLocation, DRIVER_FUNC_STOP))
- {
- return 0;
- }
- else
- {
- return 1;
- }
+ return HyperDbgStartDriver();
}
/**
- * @brief Stop VMM driver
+ * @brief Stop KD driver
*
- * @return INT return zero if it was successful or non-zero if there
- * was error
+ * @return INT return zero if it was successful or non-zero if there was error
*/
INT
-HyperDbgStopVmmDriver()
+HyperDbgStopKdDriver()
{
return HyperDbgStopDriver(g_DriverName);
}
@@ -621,10 +149,10 @@ HyperDbgStopVmmDriver()
/**
* @brief Remove the driver
*
- * @return int return zero if it was successful or non-zero if there
+ * @return INT return zero if it was successful or non-zero if there
* was error
*/
-int
+INT
HyperDbgUninstallDriver(LPCTSTR DriverName)
{
//
@@ -641,33 +169,154 @@ HyperDbgUninstallDriver(LPCTSTR DriverName)
}
/**
- * @brief Remove the VMM driver
+ * @brief Remove the KD (Kernel Debugger) driver
*
* @return INT return zero if it was successful or non-zero if there
* was error
*/
INT
-HyperDbgUninstallVmmDriver()
+HyperDbgUninstallKdDriver()
{
return HyperDbgUninstallDriver(g_DriverName);
}
/**
- * @brief Create handle from VMM module
+ * @brief Initialize VMM module
*
* @return INT return zero if it was successful or non-zero if there
* was error
*/
INT
-HyperDbgCreateHandleFromVmmModule()
+HyperDbgInitHyperTraceModule()
+{
+ BOOL Status;
+ DWORD BytesReturned;
+ DEBUGGER_INIT_HYPERTRACE_PACKET InitHyperTracePacket = {0};
+
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnOne);
+
+ //
+ // Send IOCTL to initialize HyperTrace module
+ //
+ Status = DeviceIoControl(g_DeviceHandle, // Handle to device
+ IOCTL_INIT_HYPERTRACE, // IO Control Code (IOCTL)
+ &InitHyperTracePacket, // Input Buffer to driver.
+ SIZEOF_DEBUGGER_INIT_HYPERTRACE_PACKET, // Length of input buffer in bytes.
+ &InitHyperTracePacket, // Output Buffer from driver.
+ SIZEOF_DEBUGGER_INIT_HYPERTRACE_PACKET, // Length of output buffer in bytes.
+ &BytesReturned, // Bytes placed in buffer.
+ NULL // synchronous call
+ );
+
+ //
+ // Check if the IOCTL was successful, if not show the error message and return
+ //
+ if (!Status)
+ {
+ ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
+ return 1;
+ }
+
+ //
+ // Check the kernel status
+ //
+ if (InitHyperTracePacket.KernelStatus != DEBUGGER_OPERATION_WAS_SUCCESSFUL)
+ {
+ ShowErrorMessage(InitHyperTracePacket.KernelStatus);
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Initialize VMM module
+ *
+ * @return INT return zero if it was successful or non-zero if there
+ * was error
+ */
+INT
+HyperDbgInitVmmModule()
+{
+ BOOL Status;
+ DWORD BytesReturned;
+ DEBUGGER_INIT_VMM_PACKET InitVmmPacket = {0};
+
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnOne);
+
+ //
+ // Create event to show if the kd module is loaded or not
+ //
+ g_IsDriverLoadedSuccessfully = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+ //
+ // Send IOCTL to initialize VMM module
+ //
+ Status = DeviceIoControl(g_DeviceHandle, // Handle to device
+ IOCTL_INIT_VMM, // IO Control Code (IOCTL)
+ &InitVmmPacket, // Input Buffer to driver.
+ SIZEOF_DEBUGGER_INIT_VMM_PACKET, // Length of input buffer in bytes.
+ &InitVmmPacket, // Output Buffer from driver.
+ SIZEOF_DEBUGGER_INIT_VMM_PACKET, // Length of output buffer in bytes.
+ &BytesReturned, // Bytes placed in buffer.
+ NULL // synchronous call
+ );
+
+ //
+ // check if the IOCTL was successful, if not show the error message and return
+ //
+ if (!Status)
+ {
+ ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
+ CloseHandle(g_IsDriverLoadedSuccessfully);
+ return 1;
+ }
+
+ //
+ // Check the kernel status for early errors (e.g., HyperTrace already loaded)
+ //
+ if (InitVmmPacket.KernelStatus != DEBUGGER_OPERATION_WAS_SUCCESSFUL &&
+ InitVmmPacket.KernelStatus != 0)
+ {
+ ShowErrorMessage(InitVmmPacket.KernelStatus);
+ CloseHandle(g_IsDriverLoadedSuccessfully);
+ return 1;
+ }
+
+ //
+ // We wait for the first message from the kernel debugger to continue
+ //
+ WaitForSingleObject(
+ g_IsDriverLoadedSuccessfully,
+ INFINITE);
+
+ //
+ // No need to handle anymore
+ //
+ CloseHandle(g_IsDriverLoadedSuccessfully);
+
+ //
+ // VMM module is initialized at this point
+ //
+ return 0;
+}
+
+/**
+ * @brief Create handle from KD (HyperKD) module
+ *
+ * @return INT return zero if it was successful or non-zero if there
+ * was error
+ */
+INT
+HyperDbgCreateHandleFromKdModule()
{
DWORD ErrorNum;
DWORD ThreadId;
if (g_DeviceHandle)
{
- ShowMessages("handle of the driver found, if you use 'load' before, please "
- "unload it using 'unload'\n");
+ ShowMessages("handle of the driver found, if you use the 'load' command before, please "
+ "unload it using the 'unload' command\n");
return 1;
}
@@ -675,7 +324,7 @@ HyperDbgCreateHandleFromVmmModule()
// Make sure that this variable is false, because it might be set to
// true as the result of a previous load
//
- g_IsVmxOffProcessStart = FALSE;
+ g_IsMessageLoggingWindowClosed = FALSE;
//
// Init entering vmx
@@ -686,7 +335,7 @@ HyperDbgCreateHandleFromVmmModule()
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, /// lpSecurityAttirbutes
OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
+ FILE_ATTRIBUTE_NORMAL,
NULL); /// lpTemplateFile
if (g_DeviceHandle == INVALID_HANDLE_VALUE)
@@ -730,7 +379,7 @@ HyperDbgCreateHandleFromVmmModule()
}
/**
- * @brief Unload VMM driver
+ * @brief Unload VMM module
*
* @return INT return zero if it was successful or non-zero if there
* was error
@@ -738,11 +387,27 @@ HyperDbgCreateHandleFromVmmModule()
INT
HyperDbgUnloadVmm()
{
- BOOL Status;
+ BOOL Status;
+ DWORD BytesReturned;
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnOne);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnOne);
- ShowMessages("start terminating...\n");
+ ShowMessages("start terminating vmm...\n");
+
+ //
+ // Check if HyperTrace module is loaded, if so we need to unload it before unloading VMM
+ //
+ if (g_IsHyperTraceModuleLoaded)
+ {
+ ShowMessages(
+ "the trace module is currently loaded and will be unloaded before the vmm module\nnote that hypertrace (trace) "
+ "use the hypervisor (vmm) features when it is loaded after vmm, however, hypertrace can also operate without the vmm "
+ "module, although hypervisor-specific features will not be available\n"
+ "the 'trace' module will now be unloaded automatically. You can reload it later "
+ "using the command 'load trace', which will load the trace module again without enabling hypervisor-dependent features\n");
+
+ HyperDbgUnloadHyperTrace();
+ }
//
// Uninitialize the user debugger if it's initialized
@@ -750,7 +415,7 @@ HyperDbgUnloadVmm()
UdUninitializeUserDebugger();
//
- // Send IOCTL to mark complete all IRP Pending
+ // Send IOCTL terminate VMX
//
Status = DeviceIoControl(g_DeviceHandle, // Handle to device
IOCTL_TERMINATE_VMX, // IO Control Code (IOCTL)
@@ -759,7 +424,7 @@ HyperDbgUnloadVmm()
// as the driver is x64 and has 64 bit values)
NULL, // Output Buffer from driver.
0, // Length of output buffer in bytes.
- NULL, // Bytes placed in buffer.
+ &BytesReturned, // Bytes placed in buffer.
NULL // synchronous call
);
@@ -772,20 +437,117 @@ HyperDbgUnloadVmm()
return 1;
}
+ //
+ // Hypervisor (VMM) module is not loaded anymore
+ //
+ g_IsVmmModuleLoaded = FALSE;
+
+ ShowMessages("you're not on HyperDbg's hypervisor anymore!\n");
+
+ return 0;
+}
+
+/**
+ * @brief Unload HyperTrace module
+ *
+ * @return INT return zero if it was successful or non-zero if there
+ * was error
+ */
+INT
+HyperDbgUnloadHyperTrace()
+{
+ BOOL Status;
+ DWORD BytesReturned;
+
+ AssertShowMessageReturnStmt(g_IsHyperTraceModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_HYPERTRACE_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnOne);
+
+ ShowMessages("start terminating trace module...\n");
+
+ //
+ // Send IOCTL to unload HyperTrace module
+ //
+ Status = DeviceIoControl(g_DeviceHandle, // Handle to device
+ IOCTL_PERFORM_HYPERTRACE_UNLOAD, // IO Control Code (IOCTL)
+ NULL, // Input Buffer to driver.
+ 0, // Length of input buffer in bytes. (x 2 is bcuz
+ // as the driver is x64 and has 64 bit values)
+ NULL, // Output Buffer from driver.
+ 0, // Length of output buffer in bytes.
+ &BytesReturned, // Bytes placed in buffer.
+ NULL // synchronous call
+ );
+
+ //
+ // wait to make sure we don't use an invalid handle in another Ioctl
+ //
+ if (!Status)
+ {
+ ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
+ return 1;
+ }
+
+ //
+ // HyperTrace module is not loaded anymore
+ //
+ g_IsHyperTraceModuleLoaded = FALSE;
+
+ ShowMessages("the trace module is unloaded!\n");
+
+ return 0;
+}
+
+/**
+ * @brief Unload KD driver
+ *
+ * @return INT return zero if it was successful or non-zero if there was error
+ */
+INT
+HyperDbgUnloadKd()
+{
+ BOOL Status;
+ DWORD BytesReturned;
+
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnOne);
+
+ //
+ // Check if HyperTrace module is loaded, if so we need to unload it before unloading KD because KD is used by HyperTrace
+ //
+ if (g_IsHyperTraceModuleLoaded)
+ {
+ ShowMessages("err, unable to unload the kd module because the trace module is currently loaded "
+ "and uses the kd module, if you want to unload the kd module, please first unload "
+ "the trace module using the 'unload trace' command\n");
+ return 1;
+ }
+
+ //
+ // Check if VMM module is loaded, if so we need to unload it before unloading KD because KD is used by VMM
+ //
+ if (g_IsVmmModuleLoaded)
+ {
+ ShowMessages("err, unable to unload the kd module because the vmm module is currently loaded "
+ "and uses the kd module, if you want to unload the kd module, please first unload "
+ "the vmm module using the 'unload vmm' command\n");
+ return 1;
+ }
+
+ //
+ // Indicate that the message logging window is closed
+ //
+ g_IsMessageLoggingWindowClosed = TRUE;
+
//
// Send IOCTL to mark complete all IRP Pending
//
Status = DeviceIoControl(
g_DeviceHandle, // Handle to device
- IOCTL_RETURN_IRP_PENDING_PACKETS_AND_DISALLOW_IOCTL, // IO
- // Control
- // code
+ IOCTL_RETURN_IRP_PENDING_PACKETS_AND_DISALLOW_IOCTL, // IO Control Code (IOCTL)
NULL, // Input Buffer to driver.
0, // Length of input buffer in bytes. (x 2 is bcuz as the
// driver is x64 and has 64 bit values)
NULL, // Output Buffer from driver.
0, // Length of output buffer in bytes.
- NULL, // Bytes placed in buffer.
+ &BytesReturned, // Bytes placed in buffer.
NULL // synchronous call
);
@@ -799,11 +561,9 @@ HyperDbgUnloadVmm()
}
//
- // Indicate that the finish process start or not
+ // Wait for a while to make sure that all IRP pending are completed and the driver is ready to be unloaded
//
- g_IsVmxOffProcessStart = TRUE;
-
- Sleep(1000); // Wait so next thread can return from IRP Pending
+ Sleep(1000);
//
// Send IRP_MJ_CLOSE to driver to terminate Vmxs
@@ -823,18 +583,163 @@ HyperDbgUnloadVmm()
//
// Debugger module is not loaded anymore
//
- g_IsDebuggerModulesLoaded = FALSE;
+ g_IsKdModuleLoaded = FALSE;
//
// Check if we found an already built symbol table
//
SymbolDeleteSymTable();
- ShowMessages("you're not on HyperDbg's hypervisor anymore!\n");
+ ShowMessages("the debugger module is unloaded!\n");
return 0;
}
+/**
+ * @brief check if any module is loaded (KD, VMM, HyperTrace, etc.)
+ *
+ * @return BOOLEAN return TRUE if any module is loaded, otherwise return FALSE
+ */
+BOOLEAN
+HyperDbgIsAnyModuleLoaded()
+{
+ INT RetVal = 0;
+
+ //
+ // Check if any module is loaded (KD, VMM, HyperTrace, etc.)
+ //
+ if (g_IsKdModuleLoaded || g_IsVmmModuleLoaded || g_IsHyperTraceModuleLoaded)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+/**
+ * @brief unload all modules (KD, VMM, HyperTrace, etc.)
+ *
+ * @return INT return zero if it was successful or non-zero if there
+ * was error
+ */
+INT
+HyperDbgUnloadAllModules()
+{
+ INT RetVal = 0;
+
+ //
+ // Unload HyperTrace module if loaded
+ //
+ if (g_IsHyperTraceModuleLoaded && HyperDbgUnloadHyperTrace() != 0)
+ {
+ return 1;
+ }
+
+ //
+ // Unload VMM module if loaded
+ //
+ if (g_IsVmmModuleLoaded && HyperDbgUnloadVmm() != 0)
+ {
+ return 1;
+ }
+
+ //
+ // Unload KD module if loaded
+ //
+ if (g_IsKdModuleLoaded && HyperDbgUnloadKd() != 0)
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * @brief load kd module
+ *
+ * @return int return zero if it was successful or non-zero if there
+ */
+INT
+HyperDbgLoadKdModule()
+{
+ //
+ // Check if the module is already loaded, if that's the case, we don't
+ // need to handle anymore
+ //
+ if (g_IsKdModuleLoaded)
+ {
+ //
+ // Return zero to indicate that the module is loaded successfully,
+ // and we no need to re-load it anymore
+ //
+ return 0;
+ }
+
+ //
+ // Enable Debug privilege to the current token
+ //
+ if (!WindowsSetDebugPrivilege())
+ {
+ ShowMessages("err, couldn't set debug privilege\n");
+ return 1;
+ }
+
+ //
+ // Create handle from the KD module
+ //
+ if (HyperDbgCreateHandleFromKdModule() == 1)
+ {
+ //
+ // No need to handle anymore
+ //
+ return 1;
+ }
+
+ //
+ // KD module is loaded at this point
+ //
+
+ //
+ // If we reach here so the module are loaded
+ //
+ g_IsKdModuleLoaded = TRUE;
+
+ return 0;
+}
+
+/**
+ * @brief Get the vendor of the current processor
+ *
+ * @return GENERIC_PROCESSOR_VENDOR the vendor of the processor
+ */
+GENERIC_PROCESSOR_VENDOR
+HyperDbgGetProcessorVendor()
+{
+ CHAR CpuId[13] = {0};
+
+ //
+ // Read the vendor string
+ //
+ CpuReadVendorString(CpuId);
+
+ // ShowMessages("current processor vendor is : %s\n", CpuId);
+
+ if (strcmp(CpuId, "GenuineIntel") == 0)
+ {
+ return GENERIC_PROCESSOR_VENDOR_INTEL;
+ }
+ else if (strcmp(CpuId, "AuthenticAMD") == 0)
+ {
+ return GENERIC_PROCESSOR_VENDOR_AMD;
+ }
+ else
+ {
+ return GENERIC_PROCESSOR_VENDOR_OTHERS;
+ }
+}
+
/**
* @brief load vmm module
*
@@ -843,42 +748,52 @@ HyperDbgUnloadVmm()
INT
HyperDbgLoadVmmModule()
{
- char CpuId[13] = {0};
+ //
+ // Check if the module is already loaded, if that's the case, we don't
+ // need to handle anymore
+ //
+ if (g_IsVmmModuleLoaded)
+ {
+ //
+ // Return zero to indicate that the module is loaded successfully,
+ // and we no need to re-load it anymore
+ //
+ return 0;
+ }
//
- // Enable Debug privilege to the current token
+ // Check if the HyperTrace module is loaded or not
//
- if (!SetDebugPrivilege())
+ if (g_IsHyperTraceModuleLoaded)
{
- ShowMessages("err, couldn't set debug privilege\n");
+ ShowMessages(
+ "err, the trace module is currently loaded and should be unloaded before loading the vmm module\n"
+ "Note that HyperTrace (trace) uses the hypervisor (vmm) features when it is loaded after the vmm module, "
+ "however, HyperTrace can also operate without the vmm module, although hypervisor-specific features will not be available\n"
+ "to solve this problem, first unload the trace module using the 'unload trace' command, next, load "
+ "the vmm module and then load the trace module again. This way, the trace module is reloaded with hypervisor APIs\n");
return 1;
}
//
- // Read the vendor string
+ // Check if the processor is a genuine Intel processor (required for VT-x)
//
- CpuReadVendorString(CpuId);
-
- ShowMessages("current processor vendor is : %s\n", CpuId);
-
- if (strcmp(CpuId, "GenuineIntel") == 0)
+ if (HyperDbgGetProcessorVendor() != GENERIC_PROCESSOR_VENDOR_INTEL)
{
- ShowMessages("virtualization technology is vt-x\n");
- }
- else
- {
- ShowMessages("this program is not designed to run in a non-VT-x "
- "environment !\n");
+ ShowMessages("err, this program is not designed to run in a non-VT-x "
+ "environment. It needs an Intel processor.\n");
return 1;
}
+ ShowMessages("virtualization technology is vt-x\n");
+
if (VmxSupportDetection())
{
ShowMessages("vmx operation is supported by your processor\n");
}
else
{
-#ifdef ENV_WINDOWS
+#ifdef HYPERDBG_ENV_WINDOWS
ShowMessages("vmx operation is not supported by your processor "
"(if you are using an Intel processor, it might be because VBS is not disabled!)\n");
#endif
@@ -886,41 +801,137 @@ HyperDbgLoadVmmModule()
}
//
- // Create event to show if the hypervisor is loaded or not
+ // Load the KD module and create handle to it
//
- g_IsDriverLoadedSuccessfully = CreateEvent(NULL, FALSE, FALSE, NULL);
-
- if (HyperDbgCreateHandleFromVmmModule() == 1)
+ if (HyperDbgLoadKdModule() == 1)
{
- //
- // No need to handle anymore
- //
- CloseHandle(g_IsDriverLoadedSuccessfully);
return 1;
}
//
- // Vmm module (Hypervisor) is loaded
+ // Initialize VMM module
//
+ if (HyperDbgInitVmmModule() == 1)
+ {
+ ShowMessages("err, initializing VMM module\n");
- //
- // We wait for the first message from the kernel debugger to continue
- //
- WaitForSingleObject(
- g_IsDriverLoadedSuccessfully,
- INFINITE);
-
- //
- // No need to handle anymore
- //
- CloseHandle(g_IsDriverLoadedSuccessfully);
+ return 1;
+ }
//
// If we reach here so the module are loaded
//
- g_IsDebuggerModulesLoaded = TRUE;
+ g_IsVmmModuleLoaded = TRUE;
ShowMessages("vmm module is running...\n");
return 0;
}
+
+/**
+ * @brief load hypertrace module
+ *
+ * @return int return zero if it was successful or non-zero if there
+ * was error
+ */
+INT
+HyperDbgLoadHyperTraceModule()
+{
+ //
+ // Check if the module is already loaded, if that's the case, we don't
+ // need to handle anymore
+ //
+ if (g_IsHyperTraceModuleLoaded)
+ {
+ //
+ // Return zero to indicate that the module is loaded successfully,
+ // and we no need to re-load it anymore
+ //
+ return 0;
+ }
+
+ //
+ // Enable Debug privilege to the current token
+ //
+ if (!WindowsSetDebugPrivilege())
+ {
+ ShowMessages("err, couldn't set debug privilege\n");
+ return 1;
+ }
+
+ //
+ // Check if the processor is a genuine Intel processor (required for HyperTrace)
+ //
+ if (HyperDbgGetProcessorVendor() != GENERIC_PROCESSOR_VENDOR_INTEL)
+ {
+ ShowMessages("err, this program is not designed to run in a non-Intel "
+ "environment as it needs Intel PT (Processor Trace) and Intel LBR "
+ "(Last Branch Record). It needs an Intel processor.\n");
+ return 1;
+ }
+
+ //
+ // Load the KD module and create handle to it
+ //
+ if (HyperDbgLoadKdModule() == 1)
+ {
+ return 1;
+ }
+
+ //
+ // Initialize HyperTrace module
+ //
+ if (HyperDbgInitHyperTraceModule() == 1)
+ {
+ ShowMessages("err, initializing hypertrace module\n");
+
+ return 1;
+ }
+
+ //
+ // If we reach here so the module are loaded
+ //
+ g_IsHyperTraceModuleLoaded = TRUE;
+
+ ShowMessages("hypertrace (trace) module is running...\n");
+
+ return 0;
+}
+
+/**
+ * @brief load all modules (KD, VMM, HyperTrace, etc.)
+ *
+ * @return INT return zero if it was successful or non-zero if there
+ * was error
+ */
+INT
+HyperDbgLoadAllModules()
+{
+ INT RetVal = 0;
+
+ //
+ // Load KD module if not loaded
+ //
+ if (!g_IsKdModuleLoaded && HyperDbgLoadKdModule() != 0)
+ {
+ return 1;
+ }
+
+ //
+ // Load VMM module if not loaded
+ //
+ if (!g_IsVmmModuleLoaded && HyperDbgLoadVmmModule() != 0)
+ {
+ return 1;
+ }
+
+ //
+ // Load HyperTrace module if not loaded
+ //
+ if (!g_IsHyperTraceModuleLoaded && HyperDbgLoadHyperTraceModule() != 0)
+ {
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/hyperdbg/libhyperdbg/code/app/messaging.cpp b/hyperdbg/libhyperdbg/code/app/messaging.cpp
new file mode 100644
index 00000000..ca0f7264
--- /dev/null
+++ b/hyperdbg/libhyperdbg/code/app/messaging.cpp
@@ -0,0 +1,149 @@
+/**
+ * @file messaging.cpp
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Functions for handling messages
+ * @details
+ * @version 0.19
+ * @date 2026-05-28
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+using namespace std;
+
+//
+// Global Variables
+//
+extern PVOID g_MessageHandler;
+extern PVOID g_MessageHandlerSharedBuffer;
+extern BOOLEAN g_LogOpened;
+extern BOOLEAN g_IsConnectedToRemoteDebugger;
+extern BOOLEAN g_IsSerialConnectedToRemoteDebugger;
+
+/**
+ * @brief Set the function callback that will be called if any message
+ * needs to be shown
+ *
+ * @param Handler Function that handles the messages
+ * @return VOID
+ */
+VOID
+SetTextMessageCallback(PVOID Handler)
+{
+ g_MessageHandler = Handler;
+}
+
+/**
+ * @brief Set the function callback that will be called if any message
+ * needs to be shown
+ *
+ * @param Handler Function that handles the messages
+ * @return PVOID
+ */
+PVOID
+SetTextMessageCallbackUsingSharedBuffer(PVOID Handler)
+{
+ g_MessageHandler = Handler;
+ g_MessageHandlerSharedBuffer = malloc(COMMUNICATION_BUFFER_SIZE + TCP_END_OF_BUFFER_CHARS_COUNT);
+
+ if (!g_MessageHandlerSharedBuffer)
+ {
+ g_MessageHandler = NULL;
+ return NULL;
+ }
+
+ RtlZeroMemory(g_MessageHandlerSharedBuffer, COMMUNICATION_BUFFER_SIZE + TCP_END_OF_BUFFER_CHARS_COUNT);
+
+ return g_MessageHandlerSharedBuffer;
+}
+
+/**
+ * @brief Unset the function callback that will be called if any message
+ * needs to be shown
+ *
+ * @return VOID
+ */
+VOID
+UnsetTextMessageCallback()
+{
+ g_MessageHandler = NULL;
+ free(g_MessageHandlerSharedBuffer);
+ g_MessageHandlerSharedBuffer = NULL;
+}
+
+/**
+ * @brief Show messages
+ *
+ * @param Fmt format string message
+ * @param ... arguments
+ * @return VOID
+ */
+VOID
+ShowMessages(const CHAR * Fmt, ...)
+{
+ va_list ArgList;
+ va_list Args;
+ CHAR TempMessage[COMMUNICATION_BUFFER_SIZE + TCP_END_OF_BUFFER_CHARS_COUNT] = {0};
+
+ if (g_MessageHandler == NULL && !g_IsConnectedToRemoteDebugger && !g_IsSerialConnectedToRemoteDebugger)
+ {
+ va_start(Args, Fmt);
+
+ vprintf(Fmt, Args);
+
+ va_end(Args);
+
+ if (!g_LogOpened)
+ {
+ return;
+ }
+ }
+
+ va_start(ArgList, Fmt);
+
+ INT SprintfResult = PlatformVsnprintf(TempMessage, sizeof(TempMessage), Fmt, ArgList);
+
+ va_end(ArgList);
+
+ if (SprintfResult != -1)
+ {
+ if (g_IsConnectedToRemoteDebugger)
+ {
+ //
+ // vsprintf_s and vswprintf_s return the number of characters written,
+ // not including the terminating null character, or a negative value
+ // if an output error occurs.
+ //
+ RemoteConnectionSendResultsToHost(TempMessage, SprintfResult);
+ }
+ else if (g_IsSerialConnectedToRemoteDebugger)
+ {
+ KdSendUsermodePrints(TempMessage, SprintfResult);
+ }
+
+ if (g_LogOpened)
+ {
+ //
+ // .logopen command executed
+ //
+ LogopenSaveToFile(TempMessage);
+ }
+ if (g_MessageHandler != NULL)
+ {
+ //
+ // There is another handler
+ //
+ if (g_MessageHandlerSharedBuffer == NULL)
+ {
+ ((SendMessageWithParamCallback)g_MessageHandler)(TempMessage);
+ }
+ else
+ {
+ memcpy(g_MessageHandlerSharedBuffer, TempMessage, strlen(TempMessage) + 1);
+ ((SendMessageWithSharedBufferCallback)g_MessageHandler)();
+ }
+ }
+ }
+}
diff --git a/hyperdbg/libhyperdbg/code/app/packets.cpp b/hyperdbg/libhyperdbg/code/app/packets.cpp
new file mode 100644
index 00000000..e7a39339
--- /dev/null
+++ b/hyperdbg/libhyperdbg/code/app/packets.cpp
@@ -0,0 +1,347 @@
+/**
+ * @file packets.cpp
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Functions for handling packets from the driver
+ * @details
+ * @version 0.19
+ * @date 2026-05-28
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+using namespace std;
+
+//
+// Global Variables
+//
+extern HANDLE g_DeviceHandle;
+extern HANDLE g_IsDriverLoadedSuccessfully;
+extern BOOLEAN g_IsMessageLoggingWindowClosed;
+extern BOOLEAN g_BreakPrintingOutput;
+extern BOOLEAN g_OutputSourcesInitialized;
+
+/**
+ * @brief Read kernel buffers using IRP Pending
+ *
+ * @param Device Driver handle
+ * @return VOID
+ */
+VOID
+ReadIrpBasedBuffer()
+{
+ BOOL Status;
+ ULONG ReturnedLength;
+ REGISTER_NOTIFY_BUFFER RegisterEvent;
+ DWORD ErrorNum;
+ HANDLE Handle;
+ UINT32 OperationCode;
+
+ RegisterEvent.hEvent = NULL;
+ RegisterEvent.Type = IRP_BASED;
+
+ //
+ // Keep the packet reader on a dedicated synchronous handle. It blocks on
+ // a pending IOCTL while the main debugger handle continues sending other
+ // synchronous IOCTLs.
+ //
+ Handle = CreateFileA(
+ "\\\\.\\HyperDbgDebuggerDevice",
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, /// lpSecurityAttirbutes
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL); /// lpTemplateFile
+
+ if (Handle == INVALID_HANDLE_VALUE)
+ {
+ ErrorNum = GetLastError();
+
+ if (ErrorNum == ERROR_ACCESS_DENIED)
+ {
+ ShowMessages("err, access denied\nare you sure you have administrator "
+ "rights?\n");
+ }
+ else if (ErrorNum == ERROR_GEN_FAILURE)
+ {
+ ShowMessages("err, a device attached to the system is not functioning\n"
+ "vmx feature might be disabled from BIOS or VBS/HVCI is active\n");
+ }
+ else
+ {
+ ShowMessages("err, CreateFile failed with (%x)\n", ErrorNum);
+ }
+
+ g_DeviceHandle = NULL;
+ Handle = NULL;
+
+ return;
+ }
+
+ //
+ // allocate buffer for transferring messages
+ //
+ CHAR * OutputBuffer = (CHAR *)malloc(UsermodeBufferSize);
+
+ try
+ {
+ while (!g_IsMessageLoggingWindowClosed)
+ {
+ //
+ // Clear the buffer
+ //
+ ZeroMemory(OutputBuffer, UsermodeBufferSize);
+
+ Status = DeviceIoControl(
+ Handle, // Handle to device
+ IOCTL_REGISTER_EVENT, // IO Control Code (IOCTL)
+ &RegisterEvent, // Input Buffer to driver.
+ SIZEOF_REGISTER_EVENT * 2, // Length of input buffer in bytes. (x 2 is bcuz as the
+ // driver is x64 and has 64 bit values)
+ OutputBuffer, // Output Buffer from driver.
+ UsermodeBufferSize, // Length of output buffer in bytes.
+ &ReturnedLength, // Bytes placed in buffer.
+ NULL // synchronous call
+ );
+
+ if (!Status)
+ {
+ //
+ // Error occurred for second time, and we show the error message
+ //
+ // ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
+
+ //
+ // if we reach here, the packet is probably failed, it might
+ // be because of using flush command
+ //
+ continue;
+ }
+
+ //
+ // Compute the received buffer's operation code
+ //
+ memcpy(&OperationCode, OutputBuffer, sizeof(UINT32));
+
+ // ShowMessages("Returned Length : 0x%x \n", ReturnedLength);
+ // ShowMessages("Operation Code : 0x%x \n", OperationCode);
+
+ //
+ // Check if the operation code contains mandatory debuggee bit
+ // If that's the case, we shouldn't wait (sleep) for new messages
+ //
+ if ((OperationCode & OPERATION_MANDATORY_DEBUGGEE_BIT) == 0)
+ {
+ Sleep(DefaultSpeedOfReadingKernelMessages); // we're not trying to eat all of the CPU ;)
+ }
+
+ switch (OperationCode)
+ {
+ case OPERATION_LOG_NON_IMMEDIATE_MESSAGE:
+
+ if (g_BreakPrintingOutput)
+ {
+ //
+ // means that the user asserts a CTRL+C or CTRL+BREAK Signal
+ // we shouldn't show or save anything in this case
+ //
+ continue;
+ }
+
+ ShowMessages("%s", OutputBuffer + sizeof(UINT32));
+
+ break;
+
+ case OPERATION_LOG_MESSAGE_MANDATORY:
+
+ ShowMessages("%s", OutputBuffer + sizeof(UINT32));
+
+ break;
+
+ case OPERATION_LOG_INFO_MESSAGE:
+
+ if (g_BreakPrintingOutput)
+ {
+ //
+ // means that the user asserts a CTRL+C or CTRL+BREAK Signal
+ // we shouldn't show or save anything in this case
+ //
+ continue;
+ }
+
+ ShowMessages("%s", OutputBuffer + sizeof(UINT32));
+
+ break;
+
+ case OPERATION_LOG_ERROR_MESSAGE:
+ if (g_BreakPrintingOutput)
+ {
+ //
+ // means that the user asserts a CTRL+C or CTRL+BREAK Signal
+ // we shouldn't show or save anything in this case
+ //
+ continue;
+ }
+
+ ShowMessages("%s", OutputBuffer + sizeof(UINT32));
+
+ break;
+
+ case OPERATION_LOG_WARNING_MESSAGE:
+
+ if (g_BreakPrintingOutput)
+ {
+ //
+ // means that the user asserts a CTRL+C or CTRL+BREAK Signal
+ // we shouldn't show or save anything in this case
+ //
+ continue;
+ }
+
+ ShowMessages("%s", OutputBuffer + sizeof(UINT32));
+
+ break;
+
+ case OPERATION_COMMAND_FROM_DEBUGGER_CLOSE_AND_UNLOAD_VMM:
+
+ KdCloseConnection();
+
+ break;
+
+ case OPERATION_DEBUGGEE_USER_INPUT:
+
+ KdHandleUserInputInDebuggee((DEBUGGEE_USER_INPUT_PACKET *)(OutputBuffer + sizeof(UINT32)));
+
+ break;
+
+ case OPERATION_DEBUGGEE_REGISTER_EVENT:
+
+ KdRegisterEventInDebuggee(
+ (PDEBUGGER_GENERAL_EVENT_DETAIL)(OutputBuffer + sizeof(UINT32)),
+ ReturnedLength);
+
+ break;
+
+ case OPERATION_DEBUGGEE_ADD_ACTION_TO_EVENT:
+
+ KdAddActionToEventInDebuggee(
+ (PDEBUGGER_GENERAL_ACTION)(OutputBuffer + sizeof(UINT32)),
+ ReturnedLength);
+
+ break;
+
+ case OPERATION_DEBUGGEE_CLEAR_EVENTS:
+
+ KdSendModifyEventInDebuggee(
+ (PDEBUGGER_MODIFY_EVENTS)(OutputBuffer + sizeof(UINT32)),
+ TRUE);
+
+ break;
+
+ case OPERATION_DEBUGGEE_CLEAR_EVENTS_WITHOUT_NOTIFYING_DEBUGGER:
+
+ KdSendModifyEventInDebuggee(
+ (PDEBUGGER_MODIFY_EVENTS)(OutputBuffer + sizeof(UINT32)),
+ FALSE);
+
+ break;
+
+ case OPERATION_HYPERVISOR_DRIVER_IS_SUCCESSFULLY_LOADED:
+
+ //
+ // Indicate that driver (Hypervisor) is loaded successfully
+ //
+ SetEvent(g_IsDriverLoadedSuccessfully);
+
+ break;
+
+ case OPERATION_HYPERVISOR_DRIVER_END_OF_IRPS:
+
+ //
+ // End of receiving messages (IRPs), nothing to do
+ // it will just end the thread at next round because of the check of
+ // g_IsMessageLoggingWindowClosed at the beginning of the loop
+ //
+ break;
+
+ case OPERATION_COMMAND_FROM_DEBUGGER_RELOAD_SYMBOL:
+
+ //
+ // Pause debugger after getting the results
+ //
+ KdReloadSymbolsInDebuggee(TRUE,
+ ((PDEBUGGEE_SYMBOL_REQUEST_PACKET)(OutputBuffer + sizeof(UINT32)))->ProcessId);
+
+ break;
+
+ case OPERATION_NOTIFICATION_FROM_USER_DEBUGGER_PAUSE:
+
+ //
+ // handle pausing packet from user debugger
+ //
+ UdHandleUserDebuggerPausing(
+ (PDEBUGGEE_UD_PAUSED_PACKET)(OutputBuffer + sizeof(UINT32)));
+
+ break;
+
+ default:
+
+ //
+ // Check if there are available output sources
+ //
+ if (!g_OutputSourcesInitialized || !ForwardingCheckAndPerformEventForwarding(OperationCode,
+ OutputBuffer + sizeof(UINT32),
+ ReturnedLength - sizeof(UINT32) - 1))
+ {
+ if (g_BreakPrintingOutput)
+ {
+ //
+ // means that the user asserts a CTRL+C or CTRL+BREAK Signal
+ // we shouldn't show or save anything in this case
+ //
+ continue;
+ }
+
+ ShowMessages("%s", OutputBuffer + sizeof(UINT32));
+ }
+
+ break;
+ }
+ }
+ }
+ catch (const std::exception &)
+ {
+ ShowMessages("err, exception occurred in creating handle or parsing buffer\n");
+ }
+
+ free(OutputBuffer);
+
+ //
+ // close handle
+ //
+ if (!CloseHandle(Handle))
+ {
+ ShowMessages("err, closing handle 0x%x\n", GetLastError());
+ }
+}
+
+/**
+ * @brief Create a thread for pending buffers
+ *
+ * @param Data
+ * @return DWORD Device Handle
+ */
+DWORD WINAPI
+IrpBasedBufferThread(PVOID Data)
+{
+ //
+ // Do stuff. This will be the first function called on the new
+ // thread. When this function returns, the thread goes away. See
+ // MSDN for more details. Test Irp Based Notifications
+ //
+ ReadIrpBasedBuffer();
+
+ return 0;
+}
diff --git a/hyperdbg/libhyperdbg/code/assembly/asm-vmx-checks.asm b/hyperdbg/libhyperdbg/code/assembly/asm-vmx-checks.asm
index bc2360d7..dd81a1d8 100644
--- a/hyperdbg/libhyperdbg/code/assembly/asm-vmx-checks.asm
+++ b/hyperdbg/libhyperdbg/code/assembly/asm-vmx-checks.asm
@@ -10,25 +10,32 @@ PUBLIC AsmVmxSupportDetection
;------------------------------------------------------------------------
AsmVmxSupportDetection PROC
-
- xor eax, eax
- inc eax
+ push rbx
+ push rcx
+ push rdx
+
+ xor eax, eax
+ inc eax
cpuid
- xor rax, rax
- bt ecx, 05h
- jc VMXSupport
+ xor rax, rax
+ bt ecx, 05h
+ jc VMXSupport
VMXNotSupport:
jmp RetInst
VMXSupport:
- mov rax, 01h
+ mov rax, 01h
RetInst:
+ pop rdx
+ pop rcx
+ pop rbx
+
ret
AsmVmxSupportDetection ENDP
;------------------------------------------------------------------------
-END
\ No newline at end of file
+END
\ No newline at end of file
diff --git a/hyperdbg/libhyperdbg/code/common/common.cpp b/hyperdbg/libhyperdbg/code/common/common.cpp
index 6cf6e689..2f494eab 100644
--- a/hyperdbg/libhyperdbg/code/common/common.cpp
+++ b/hyperdbg/libhyperdbg/code/common/common.cpp
@@ -44,11 +44,11 @@ SeparateTo64BitValue(UINT64 Value)
* @return VOID
*/
VOID
-PrintBits(const UINT32 Size, const void * Ptr)
+PrintBits(const UINT32 Size, const VOID * Ptr)
{
- unsigned char * Buf = (unsigned char *)Ptr;
- unsigned char Byte;
- int i, j;
+ UCHAR * Buf = (UCHAR *)Ptr;
+ UCHAR Byte;
+ INT i, j;
for (i = Size - 1; i >= 0; i--)
{
@@ -72,10 +72,10 @@ PrintBits(const UINT32 Size, const void * Ptr)
BOOL
Replace(std::string & str, const std::string & from, const std::string & to)
{
- size_t start_pos = str.find(from);
- if (start_pos == std::string::npos)
+ SIZE_T StartPos = str.find(from);
+ if (StartPos == std::string::npos)
return FALSE;
- str.replace(start_pos, from.size(), to);
+ str.replace(StartPos, from.size(), to);
return TRUE;
}
@@ -90,7 +90,7 @@ Replace(std::string & str, const std::string & from, const std::string & to)
VOID
ReplaceAll(string & str, const string & from, const string & to)
{
- size_t SartPos = 0;
+ SIZE_T SartPos = 0;
if (from.empty())
return;
@@ -114,7 +114,7 @@ ReplaceAll(string & str, const string & from, const string & to)
* @return const vector
*/
const vector
-Split(const string & s, const char & c)
+Split(const string & s, const CHAR & c)
{
string buff {""};
vector v;
@@ -210,18 +210,18 @@ IsDecimalNotation(const string & s)
* @brief converts hex to bytes
*
* @param hex
- * @return vector
+ * @return vector
*/
-vector
+vector
HexToBytes(const string & hex)
{
- vector Bytes;
+ vector Bytes;
- for (unsigned int i = 0; i < hex.length(); i += 2)
+ for (UINT32 i = 0; i < hex.length(); i += 2)
{
std::string byteString = hex.substr(i, 2);
- char byte = (char)strtol(byteString.c_str(), NULL, 16);
- Bytes.push_back(byte);
+ CHAR Byte = (CHAR)strtol(byteString.c_str(), NULL, 16);
+ Bytes.push_back(Byte);
}
return Bytes;
@@ -283,19 +283,19 @@ ConvertStringToUInt64(string TextToConvert, PUINT64 Result)
}
else
{
- errno = 0;
- char * unparsed = NULL;
- const char * s = TextToConvert.c_str();
- const unsigned long long int n = strtoull(s, &unparsed, 10);
+ errno = 0;
+ CHAR * Unparsed = NULL;
+ const CHAR * S = TextToConvert.c_str();
+ const UINT64 N = strtoull(S, &Unparsed, 10);
- if (errno || (!n && s == unparsed))
+ if (errno || (!N && S == Unparsed))
{
// fflush(stdout);
// perror(s);
return FALSE;
}
- *Result = n;
+ *Result = N;
return TRUE;
}
}
@@ -316,11 +316,11 @@ ConvertStringToUInt64(string TextToConvert, PUINT64 Result)
//
// It's a hex number
//
- const char * Text = TextToConvert.c_str();
- errno = 0;
- unsigned long long result = strtoull(Text, NULL, 16);
+ const CHAR * Text = TextToConvert.c_str();
+ errno = 0;
+ UINT64 ResultValue = strtoull(Text, NULL, 16);
- *Result = result;
+ *Result = ResultValue;
if (errno == EINVAL)
{
@@ -386,8 +386,8 @@ ConvertStringToUInt32(string TextToConvert, PUINT32 Result)
{
try
{
- int i = std::stoi(TextToConvert);
- *Result = i;
+ INT I = std::stoi(TextToConvert);
+ *Result = I;
return TRUE;
}
catch (std::invalid_argument const &)
@@ -500,7 +500,7 @@ GetLowerStringFromCommandToken(CommandToken TargetToken)
* @return BOOLEAN shows whether text is equal or not
*/
BOOLEAN
-CompareLowerCaseStrings(CommandToken TargetToken, const char * StringToCompare)
+CompareLowerCaseStrings(CommandToken TargetToken, const CHAR * StringToCompare)
{
//
// Extract the token type and value from the tuple
@@ -687,7 +687,7 @@ SetPrivilege(HANDLE Token, // access token handle
*
* @param s
*/
-static inline void
+static inline VOID
ltrim(std::string & s)
{
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch) { return !std::isspace(ch); }));
@@ -698,7 +698,7 @@ ltrim(std::string & s)
*
* @param s
*/
-static inline void
+static inline VOID
rtrim(std::string & s)
{
s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) { return !std::isspace(ch); })
@@ -711,7 +711,7 @@ rtrim(std::string & s)
*
* @param s
*/
-void
+VOID
Trim(std::string & s)
{
ltrim(s);
@@ -737,7 +737,7 @@ RemoveSpaces(std::string str)
* @return BOOLEAN shows whether the file exist or not
*/
BOOLEAN
-IsFileExistA(const char * FileName)
+IsFileExistA(const CHAR * FileName)
{
struct stat buffer;
return (stat(FileName, &buffer) == 0);
@@ -750,7 +750,7 @@ IsFileExistA(const char * FileName)
* @return BOOLEAN shows whether the file exist or not
*/
BOOLEAN
-IsFileExistW(const wchar_t * FileName)
+IsFileExistW(const WCHAR * FileName)
{
struct _stat64i32 buffer;
return (_wstat(FileName, &buffer) == 0);
@@ -762,9 +762,9 @@ IsFileExistW(const wchar_t * FileName)
* @param Text
*/
BOOLEAN
-IsEmptyString(char * Text)
+IsEmptyString(CHAR * Text)
{
- size_t Len;
+ SIZE_T Len;
if (Text == NULL || Text[0] == '\0')
{
@@ -772,7 +772,7 @@ IsEmptyString(char * Text)
}
Len = strlen(Text);
- for (size_t i = 0; i < Len; i++)
+ for (SIZE_T i = 0; i < Len; i++)
{
if (Text[i] != ' ' && Text[i] != '\t' && Text[i] != '\n')
{
@@ -860,10 +860,10 @@ StringToWString(std::wstring & ws, const std::string & s)
* @param Input
* @param ToSearch
* @param Pos
- * @return size_t
+ * @return SIZE_T
*/
-size_t
-FindCaseInsensitive(std::string Input, std::string ToSearch, size_t Pos)
+SIZE_T
+FindCaseInsensitive(std::string Input, std::string ToSearch, SIZE_T Pos)
{
// Convert complete given String to lower case
std::transform(Input.begin(), Input.end(), Input.begin(), ::tolower);
@@ -879,10 +879,10 @@ FindCaseInsensitive(std::string Input, std::string ToSearch, size_t Pos)
* @param Input
* @param ToSearch
* @param Pos
- * @return size_t
+ * @return SIZE_T
*/
-size_t
-FindCaseInsensitiveW(std::wstring Input, std::wstring ToSearch, size_t Pos)
+SIZE_T
+FindCaseInsensitiveW(std::wstring Input, std::wstring ToSearch, SIZE_T Pos)
{
// Convert complete given String to lower case
std::transform(Input.begin(), Input.end(), Input.begin(), ::tolower);
@@ -898,31 +898,29 @@ FindCaseInsensitiveW(std::wstring Input, std::wstring ToSearch, size_t Pos)
* std::transform(vs.begin(), vs.end(), std::back_inserter(vc), ConvertStringVectorToCharPointerArray);
* from: https://stackoverflow.com/questions/7048888/stdvectorstdstring-to-char-array
*
- * @param Input
- * @param ToSearch
- * @param Pos
- * @return size_t
+ * @param s
+ * @return CHAR*
*/
-char *
+CHAR *
ConvertStringVectorToCharPointerArray(const std::string & s)
{
- char * pc = new char[s.size() + 1];
- std::strcpy(pc, s.c_str());
- return pc;
+ CHAR * Pc = new CHAR[s.size() + 1];
+ std::strcpy(Pc, s.c_str());
+ return Pc;
}
/**
* @brief Get cpuid results
*
- * @param UINT32 Func
- * @param UINT32 SubFunc
- * @param int * CpuInfo
+ * @param Func
+ * @param SubFunc
+ * @param CpuInfo
* @return VOID
*/
VOID
-CommonCpuidInstruction(UINT32 Func, UINT32 SubFunc, int * CpuInfo)
+CommonCpuidInstruction(UINT32 Func, UINT32 SubFunc, INT * CpuInfo)
{
- __cpuidex(CpuInfo, Func, SubFunc);
+ CpuIdEx(CpuInfo, Func, SubFunc);
}
/**
@@ -933,7 +931,7 @@ CommonCpuidInstruction(UINT32 Func, UINT32 SubFunc, int * CpuInfo)
UINT32
Getx86VirtualAddressWidth()
{
- int Regs[4];
+ INT Regs[4];
CommonCpuidInstruction(CPUID_ADDR_WIDTH, 0, Regs);
@@ -951,8 +949,8 @@ Getx86VirtualAddressWidth()
BOOLEAN
CheckCpuSupportRtm()
{
- int Regs1[4];
- int Regs2[4];
+ INT Regs1[4];
+ INT Regs2[4];
BOOLEAN Result;
//
diff --git a/hyperdbg/libhyperdbg/code/common/list.cpp b/hyperdbg/libhyperdbg/code/common/list.cpp
deleted file mode 100644
index 58c2fc44..00000000
--- a/hyperdbg/libhyperdbg/code/common/list.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @file list.cpp
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief The list working functions headers
- * @details
- * @version 0.1
- * @date 2020-04-11
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#include "pch.h"
-//
-///**
-// * @brief List initializer
-// *
-// * @param ListHead
-// */
-// void
-// InitializeListHead(PLIST_ENTRY ListHead)
-//{
-// ListHead->Flink = ListHead->Blink = ListHead;
-//}
-//
-///**
-// * @brief insert entry to the top of the list
-// *
-// * @param ListHead
-// * @param Entry
-// */
-// void
-// InsertHeadList(PLIST_ENTRY ListHead, PLIST_ENTRY Entry)
-//{
-// PLIST_ENTRY Flink;
-//
-// Flink = ListHead->Flink;
-// Entry->Flink = Flink;
-// Entry->Blink = ListHead;
-// Flink->Blink = Entry;
-// ListHead->Flink = Entry;
-//}
-//
-///**
-// * @brief remove the entry from the list
-// *
-// * @param Entry
-// * @return BOOLEAN
-// */
-// BOOLEAN
-// RemoveEntryList(PLIST_ENTRY Entry)
-//{
-// PLIST_ENTRY PrevEntry;
-// PLIST_ENTRY NextEntry;
-//
-// NextEntry = Entry->Flink;
-// PrevEntry = Entry->Blink;
-// if ((NextEntry->Blink != Entry) || (PrevEntry->Flink != Entry))
-// {
-// //
-// // Error
-// //
-// _CrtDbgBreak();
-// }
-//
-// PrevEntry->Flink = NextEntry;
-// NextEntry->Blink = PrevEntry;
-// return (BOOLEAN)(PrevEntry == NextEntry);
-//}
diff --git a/hyperdbg/libhyperdbg/code/common/spinlock.cpp b/hyperdbg/libhyperdbg/code/common/spinlock.cpp
index 4303a100..96cc5e0c 100644
--- a/hyperdbg/libhyperdbg/code/common/spinlock.cpp
+++ b/hyperdbg/libhyperdbg/code/common/spinlock.cpp
@@ -29,35 +29,35 @@
* @brief The maximum wait before PAUSE
*
*/
-static unsigned MaxWait = 65536;
+static UINT32 MaxWait = 65536;
/**
* @brief Tries to get the lock otherwise returns
*
- * @param LONG Lock variable
+ * @param Lock Lock variable
* @return BOOLEAN If it was successful on getting the lock
*/
BOOLEAN
SpinlockTryLock(volatile LONG * Lock)
{
- return (!(*Lock) && !_interlockedbittestandset(Lock, 0));
+ return (!(*Lock) && !CpuInterlockedBitTestAndSet(Lock, 0));
}
/**
* @brief Tries to get the lock and won't return until successfully get the lock
*
- * @param LONG Lock variable
+ * @param Lock Lock variable
*/
-void
+VOID
SpinlockLock(volatile LONG * Lock)
{
- unsigned wait = 1;
+ UINT32 Wait = 1;
while (!SpinlockTryLock(Lock))
{
- for (unsigned i = 0; i < wait; ++i)
+ for (UINT32 i = 0; i < Wait; ++i)
{
- _mm_pause();
+ CpuPause();
}
//
@@ -65,13 +65,13 @@ SpinlockLock(volatile LONG * Lock)
// clamp it to the MaxWait.
//
- if (wait * 2 > MaxWait)
+ if (Wait * 2 > MaxWait)
{
- wait = MaxWait;
+ Wait = MaxWait;
}
else
{
- wait = wait * 2;
+ Wait = Wait * 2;
}
}
}
@@ -79,19 +79,19 @@ SpinlockLock(volatile LONG * Lock)
/**
* @brief Tries to get the lock and won't return until successfully get the lock
*
- * @param LONG Lock variable
- * @param LONG MaxWait Maximum wait (pause) count
+ * @param Lock Lock variable
+ * @param MaximumWait Maximum wait (pause) count
*/
-void
-SpinlockLockWithCustomWait(volatile LONG * Lock, unsigned MaximumWait)
+VOID
+SpinlockLockWithCustomWait(volatile LONG * Lock, UINT32 MaximumWait)
{
- unsigned wait = 1;
+ UINT32 Wait = 1;
while (!SpinlockTryLock(Lock))
{
- for (unsigned i = 0; i < wait; ++i)
+ for (UINT32 i = 0; i < Wait; ++i)
{
- _mm_pause();
+ CpuPause();
}
//
@@ -99,13 +99,13 @@ SpinlockLockWithCustomWait(volatile LONG * Lock, unsigned MaximumWait)
// clamp it to the MaxWait.
//
- if (wait * 2 > MaximumWait)
+ if (Wait * 2 > MaximumWait)
{
- wait = MaximumWait;
+ Wait = MaximumWait;
}
else
{
- wait = wait * 2;
+ Wait = Wait * 2;
}
}
}
@@ -113,9 +113,9 @@ SpinlockLockWithCustomWait(volatile LONG * Lock, unsigned MaximumWait)
/**
* @brief Release the lock
*
- * @param LONG Lock variable
+ * @param Lock Lock variable
*/
-void
+VOID
SpinlockUnlock(volatile LONG * Lock)
{
*Lock = 0;
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/a.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/a.cpp
index 8ddb6550..c7aca424 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/a.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/a.cpp
@@ -94,7 +94,7 @@ ParseUserCmd(const std::string & command)
// if yes, asm snippet was provided right after "a" command (2nd index)
// i.e. no address were provided to assembling to
//
- CmdVec.emplace_back(""); // emtpty addres string
+ CmdVec.emplace_back(""); // empty address string
}
std::string RawAsm(CmdIt + 1, CloseIt); // remove "{}"
CmdVec.emplace_back(RawAsm);
@@ -192,7 +192,7 @@ CommandAssemble(vector CommandTokens, string Command)
if (CMD.isEmpty())
{
//
- // Error messeges are already printed
+ // Error messages are already printed
//
return;
}
@@ -275,7 +275,7 @@ CommandAssemble(vector CommandTokens, string Command)
if (ProcId == 0)
{
- ProcId = GetCurrentProcessId();
+ ProcId = PlatformGetCurrentProcessId();
}
if (Address) // was the user only trying to get the bytes?
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/bp.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/bp.cpp
index 949f1477..8beed864 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/bp.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/bp.cpp
@@ -15,7 +15,7 @@
// Global Variables
//
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
-extern BOOLEAN g_IsSerialConnectedToRemoteDebugger;
+extern BOOLEAN g_IsVmmModuleLoaded;
extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
/**
@@ -67,7 +67,7 @@ CommandBpPerformApplyingBreakpointOnUserDebugger(DEBUGGEE_BP_PACKET * BpPacket)
}
else
{
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// Send IOCTL
@@ -195,7 +195,7 @@ CommandBp(vector CommandTokens, string Command)
//
#if ActivateUserModeDebugger == FALSE
- if (!g_IsSerialConnectedToRemoteDebugger)
+ if (!g_IsSerialConnectedToRemoteDebuggee)
{
ShowMessages("the user-mode debugger in VMI Mode is still in the beta version and not stable. "
"we decided to exclude it from this release and release it in future versions. "
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/continue.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/continue.cpp
index bb8b3065..af385224 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/continue.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/continue.cpp
@@ -11,14 +11,6 @@
*/
#include "pch.h"
-//
-// Global Variables
-//
-extern BOOLEAN g_BreakPrintingOutput;
-extern BOOLEAN g_IsConnectedToRemoteDebuggee;
-extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
-extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
-
/**
* @brief help of the continue command
*
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/cpu.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/cpu.cpp
index 6cf56b30..970d44ec 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/cpu.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/cpu.cpp
@@ -140,12 +140,12 @@ private:
// Calling __cpuid with 0x0 as the function_id argument
// gets the number of the highest valid function ID.
//
- __cpuid(cpui.data(), 0);
+ CpuCpuId(cpui.data(), 0);
nIds_ = cpui[0];
for (int i = 0; i <= nIds_; ++i)
{
- __cpuidex(cpui.data(), i, 0);
+ CpuIdEx(cpui.data(), i, 0);
data_.push_back(cpui);
}
@@ -189,7 +189,7 @@ private:
// Calling __cpuid with 0x80000000 as the function_id argument
// gets the number of the highest valid extended ID.
//
- __cpuid(cpui.data(), 0x80000000);
+ CpuCpuId(cpui.data(), 0x80000000);
nExIds_ = cpui[0];
char brand[0x40];
@@ -197,7 +197,7 @@ private:
for (int i = 0x80000000; i <= nExIds_; ++i)
{
- __cpuidex(cpui.data(), i, 0);
+ CpuIdEx(cpui.data(), i, 0);
extdata_.push_back(cpui);
}
@@ -246,7 +246,7 @@ const InstructionSet::InstructionSet_Internal InstructionSet::CPU_Rep;
/**
* @brief Reads the CPU vendor string
*
- * @return char *
+ * @return VOID
*/
VOID
CpuReadVendorString(CHAR * Result)
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/dt-struct.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/dt-struct.cpp
index 3e7d490d..c3c3db68 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/dt-struct.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/dt-struct.cpp
@@ -35,13 +35,13 @@ CommandDtHelp()
"[pid ProcessId (hex)] [padding Padding (yesno)] [offset Offset (yesno)] "
"[bitfield Bitfield (yesno)] [native Native (yesno)] [decl Declaration (yesno)] "
"[def Definitions (yesno)] [func Functions (yesno)] [pragma Pragma (yesno)] "
- "[prefix Prefix (string)] [suffix Suffix (string)] [inline Expantion (string)] "
+ "[prefix Prefix (string)] [suffix Suffix (string)] [inline Expansion (string)] "
"[output FileName (string)]\n\n");
ShowMessages("syntax : \t!dt [Module!SymbolName (string)] [AddressExpression (string)] "
"[padding Padding (yesno)] [offset Offset (yesno)] [bitfield Bitfield (yesno)] "
"[native Native (yesno)] [decl Declaration (yesno)] [def Definitions (yesno)] "
"[func Functions (yesno)] [pragma Pragma (yesno)] [prefix Prefix (string)] "
- "[suffix Suffix (string)] [inline Expantion (string)] [output FileName (string)]\n");
+ "[suffix Suffix (string)] [inline Expansion (string)] [output FileName (string)]\n");
ShowMessages("\n");
ShowMessages("\t\te.g : dt nt!_EPROCESS\n");
@@ -183,9 +183,9 @@ CommandDtAndStructConvertHyperDbgArgsToPdbex(vector ExtraArgs,
else
{
//
- // none/inline/all expected but didn't see it
+ // none/unnamed/all expected but didn't see it
//
- ShowMessages("err, please insert 'none', 'inline', or 'all' as the argument\n\n");
+ ShowMessages("err, please insert 'none', 'unnamed', or 'all' as the argument\n\n");
return FALSE;
}
@@ -314,13 +314,13 @@ CommandDtAndStructConvertHyperDbgArgsToPdbex(vector ExtraArgs,
*/
BOOLEAN
CommandDtShowDataBasedOnSymbolTypes(
- const char * TypeName,
+ const CHAR * TypeName,
UINT64 Address,
BOOLEAN IsStruct,
PVOID BufferAddress,
UINT32 TargetPid,
BOOLEAN IsPhysicalAddress,
- const char * AdditionalParameters)
+ const CHAR * AdditionalParameters)
{
UINT64 StructureSize = 0;
BOOLEAN ResultOfFindingSize = FALSE;
@@ -353,7 +353,7 @@ CommandDtShowDataBasedOnSymbolTypes(
//
// Use the current process for the pid
//
- TargetPid = GetCurrentProcessId();
+ TargetPid = PlatformGetCurrentProcessId();
}
}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/e.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/e.cpp
index 634dc8df..f85bf35a 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/e.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/e.cpp
@@ -15,6 +15,8 @@
// Global Variables
//
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+extern BOOLEAN g_IsKdModuleLoaded;
+extern BOOLEAN g_IsVmmModuleLoaded;
extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
/**
@@ -69,6 +71,7 @@ WriteMemoryContent(UINT64 AddressToEdit,
UINT64 * BufferToEdit)
{
BOOL Status;
+ DWORD BytesReturned;
BOOLEAN StatusReturn = FALSE;
DEBUGGER_EDIT_MEMORY * FinalBuffer;
DEBUGGER_EDIT_MEMORY EditMemoryRequest = {0};
@@ -79,7 +82,7 @@ WriteMemoryContent(UINT64 AddressToEdit,
//
if (!g_IsSerialConnectedToRemoteDebuggee)
{
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
}
//
@@ -147,7 +150,7 @@ WriteMemoryContent(UINT64 AddressToEdit,
FinalSize, // Input buffer length
FinalBuffer, // Output Buffer from driver.
SIZEOF_DEBUGGER_EDIT_MEMORY, // Length of output buffer in bytes.
- NULL, // Bytes placed in buffer.
+ &BytesReturned, // Bytes placed in buffer.
NULL // synchronous call
);
@@ -231,7 +234,7 @@ HyperDbgWriteMemory(PVOID DestinationAddress,
//
// Copy requested memory in 64bit chunks
//
- for (size_t i = 0; i < NumberOfBytes; i++)
+ for (SIZE_T i = 0; i < NumberOfBytes; i++)
{
TargetBuffer[i] = BufferToEdit[i];
}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/eval.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/eval.cpp
index f0d292b5..202701cb 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/eval.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/eval.cpp
@@ -14,7 +14,8 @@
//
// Global Variables
//
-extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
/**
* @brief help of the ? command
@@ -194,11 +195,6 @@ ErrorMessage:
VOID
CommandEval(vector CommandTokens, string Command)
{
- PVOID CodeBuffer;
- UINT64 BufferAddress;
- UINT32 BufferLength;
- UINT32 Pointer;
-
if (CommandTokens.size() == 1)
{
ShowMessages("incorrect use of the '%s'\n\n",
@@ -242,56 +238,25 @@ CommandEval(vector CommandTokens, string Command)
return;
}
- if (g_IsSerialConnectedToRemoteDebuggee)
+ //
+ // Check if we're connected to a remote debuggee (kernel debugger) or the user debugger
+ //
+ if (g_IsSerialConnectedToRemoteDebuggee || g_ActiveProcessDebuggingState.IsActive)
{
//
- // Send over serial
+ // Send data to the target user debugger or kernel debugger
//
-
- //
- // Run script engine handler
- //
- CodeBuffer = ScriptEngineParseWrapper((char *)Command.c_str(), TRUE);
-
- if (CodeBuffer == NULL)
- {
- //
- // return to show that this item contains an script
- //
- return;
- }
-
- //
- // Print symbols (test)
- //
- // PrintSymbolBufferWrapper(CodeBuffer);
-
- //
- // Set the buffer and length
- //
- BufferAddress = ScriptEngineWrapperGetHead(CodeBuffer);
- BufferLength = ScriptEngineWrapperGetSize(CodeBuffer);
- Pointer = ScriptEngineWrapperGetPointer(CodeBuffer);
-
- //
- // Send it to the remote debuggee
- //
- KdSendScriptPacketToDebuggee(BufferAddress, BufferLength, Pointer, FALSE);
-
- //
- // Remove the buffer of script engine interpreted code
- //
- ScriptEngineWrapperRemoveSymbolBuffer(CodeBuffer);
+ ScriptEngineExecuteSingleExpression((CHAR *)Command.c_str(), TRUE, FALSE);
}
else
{
//
- // It's a test
+ // It's a test (simulated) run of the script-engine
//
- ShowMessages("this command should not be used while you're in VMI-Mode or not in debugger-mode, "
- "the results that you see is a simulated result for TESTING script-engine "
- "and is not based on the status of your system. You can use this command, "
- "ONLY in debugger-mode\n\n");
+ ShowMessages("this command should not be used while you're in VMI-Mode (not attached to the user debugger) "
+ "or not in the debugger mode, the results that you see is a simulated result for TESTING the script engine "
+ "and is not based on the status of your system. You can use this command, either in the debugger mode "
+ "(kernel debugger), or when you attached to a user debugger\n\n");
ShowMessages("test expression : %s \n", Command.c_str());
ScriptEngineWrapperTestParser(Command);
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/events.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/events.cpp
index f1b5450a..27561c23 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/events.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/events.cpp
@@ -18,6 +18,7 @@ extern LIST_ENTRY g_EventTrace;
extern BOOLEAN g_EventTraceInitialized;
extern BOOLEAN g_BreakPrintingOutput;
extern BOOLEAN g_AutoFlush;
+extern BOOLEAN g_IsVmmModuleLoaded;
extern BOOLEAN g_IsConnectedToRemoteDebuggee;
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
extern BOOLEAN g_IsSerialConnectedToRemoteDebugger;
@@ -697,9 +698,9 @@ CommandEventsModifyAndQueryEvents(UINT64 Tag,
//
//
- // Check if debugger is loaded or not
+ // Check if the VMM module is loaded or not
//
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// Fill the structure to send it to the kernel
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/exit.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/exit.cpp
index 45f315e5..b691c60b 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/exit.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/exit.cpp
@@ -17,6 +17,8 @@
extern HANDLE g_DeviceHandle;
extern BOOLEAN g_IsConnectedToHyperDbgLocally;
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+extern BOOLEAN g_IsKdModuleLoaded;
+extern BOOLEAN g_IsVmmModuleLoaded;
/**
* @brief help of the exit command
@@ -58,11 +60,14 @@ CommandExit(vector CommandTokens, string Command)
//
//
- // unload and exit if the vmm module is loaded
+ // unload and exit if the any module is loaded
//
if (g_DeviceHandle)
{
- HyperDbgUnloadVmm();
+ //
+ // Unload all modules
+ //
+ HyperDbgUnloadAllModules();
}
}
else if (g_IsSerialConnectedToRemoteDebuggee)
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/flush.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/flush.cpp
index eb6d24ae..c286207b 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/flush.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/flush.cpp
@@ -14,6 +14,7 @@
//
// Global Variables
//
+extern BOOLEAN g_IsKdModuleLoaded;
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
/**
@@ -45,16 +46,16 @@ CommandFlushRequestFlush()
if (g_IsSerialConnectedToRemoteDebuggee)
{
//
- // It's a debug-mode
+ // It's on a debugger mode
//
KdSendFlushPacketToDebuggee();
}
else
{
//
- // It's a vmi-mode
+ // It's on a local debugging mode
//
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
//
// By the way, we don't need to send an input buffer
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/gu.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/gu.cpp
index 1f7136ff..36362c21 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/gu.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/gu.cpp
@@ -103,7 +103,7 @@ CommandGu(vector CommandTokens, string Command)
//
g_IsInstrumentingInstructions = TRUE;
- for (size_t i = 0; i < StepCount; i++)
+ for (SIZE_T i = 0; i < StepCount; i++)
{
//
// For logging purpose
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/i.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/i.cpp
index 81055446..29fdad73 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/i.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/i.cpp
@@ -104,7 +104,7 @@ CommandI(vector CommandTokens, string Command)
//
g_IsInstrumentingInstructions = TRUE;
- for (size_t i = 0; i < StepCount; i++)
+ for (SIZE_T i = 0; i < StepCount; i++)
{
//
// For logging purpose
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/lm.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/lm.cpp
index ff3dbac2..ce0cfb12 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/lm.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/lm.cpp
@@ -16,6 +16,7 @@ using namespace std;
//
// Global Variables
//
+extern BOOLEAN g_IsKdModuleLoaded;
extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
/**
@@ -48,7 +49,7 @@ CommandLmHelp()
* @return wstring
*/
std::wstring
-CommandLmConvertWow64CompatibilityPaths(const wchar_t * LocalFilePath)
+CommandLmConvertWow64CompatibilityPaths(const WCHAR * LocalFilePath)
{
std::wstring filePath(LocalFilePath);
@@ -56,7 +57,7 @@ CommandLmConvertWow64CompatibilityPaths(const wchar_t * LocalFilePath)
std::transform(filePath.begin(), filePath.end(), filePath.begin(), ::tolower);
// Replace "\windows\system32" with "\windows\syswow64"
- size_t pos = filePath.find(L":\\windows\\system32");
+ SIZE_T pos = filePath.find(L":\\windows\\system32");
if (pos != std::string::npos)
{
filePath.replace(pos, 18, L":\\Windows\\SysWOW64");
@@ -80,7 +81,7 @@ CommandLmConvertWow64CompatibilityPaths(const wchar_t * LocalFilePath)
* @return BOOLEAN
*/
BOOLEAN
-CommandLmShowUserModeModule(UINT32 ProcessId, const char * SearchModule)
+CommandLmShowUserModeModule(UINT32 ProcessId, const CHAR * SearchModule)
{
BOOLEAN Status;
ULONG ReturnedLength;
@@ -89,14 +90,14 @@ CommandLmShowUserModeModule(UINT32 ProcessId, const char * SearchModule)
PUSERMODE_LOADED_MODULE_DETAILS ModuleDetailsRequest = NULL;
PUSERMODE_LOADED_MODULE_SYMBOLS Modules = NULL;
USERMODE_LOADED_MODULE_DETAILS ModuleCountRequest = {0};
- size_t CharSize = 0;
- wchar_t * WcharBuff = NULL;
+ SIZE_T CharSize = 0;
+ WCHAR * WcharBuff = NULL;
wstring SearchModuleString;
//
// Check if debugger is loaded or not
//
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// Set the module details to get the details
@@ -189,7 +190,7 @@ CommandLmShowUserModeModule(UINT32 ProcessId, const char * SearchModule)
if (SearchModule != NULL)
{
CharSize = strlen(SearchModule) + 1;
- WcharBuff = (wchar_t *)malloc(CharSize * 2);
+ WcharBuff = (WCHAR *)malloc(CharSize * 2);
if (WcharBuff == NULL)
{
@@ -203,7 +204,7 @@ CommandLmShowUserModeModule(UINT32 ProcessId, const char * SearchModule)
SearchModuleString.assign(WcharBuff, wcslen(WcharBuff));
}
- for (size_t i = 0; i < ModulesCount; i++)
+ for (SIZE_T i = 0; i < ModulesCount; i++)
{
//
// Check if we need to search for the module or not
@@ -213,7 +214,7 @@ CommandLmShowUserModeModule(UINT32 ProcessId, const char * SearchModule)
//
// Convert FullPathName to string
//
- std::wstring FullPathName((wchar_t *)Modules[i].FilePath);
+ std::wstring FullPathName((WCHAR *)Modules[i].FilePath);
if (FindCaseInsensitiveW(FullPathName, SearchModuleString, 0) == std::wstring::npos)
{
@@ -271,7 +272,7 @@ CommandLmShowUserModeModule(UINT32 ProcessId, const char * SearchModule)
* @return BOOLEAN
*/
BOOLEAN
-CommandLmShowKernelModeModule(const char * SearchModule)
+CommandLmShowKernelModeModule(const CHAR * SearchModule)
{
PRTL_PROCESS_MODULES ModulesInfo = NULL;
string SearchModuleString;
@@ -302,7 +303,7 @@ CommandLmShowKernelModeModule(const char * SearchModule)
//
// Convert FullPathName to string
//
- std::string FullPathName((char *)CurrentModule->FullPathName);
+ std::string FullPathName((CHAR *)CurrentModule->FullPathName);
if (FindCaseInsensitive(FullPathName, SearchModuleString, 0) == std::string::npos)
{
@@ -317,7 +318,7 @@ CommandLmShowKernelModeModule(const char * SearchModule)
ShowMessages("%x\t", CurrentModule->ImageSize);
auto PathName = CurrentModule->FullPathName + CurrentModule->OffsetToFileName;
- UINT32 PathNameLen = (UINT32)strlen((const char *)PathName);
+ UINT32 PathNameLen = (UINT32)strlen((const CHAR *)PathName);
ShowMessages("%s\t", PathName);
@@ -362,8 +363,8 @@ CommandLm(vector CommandTokens, string Command)
BOOLEAN OnlyShowKernelModules = FALSE;
BOOLEAN OnlyShowUserModules = FALSE;
UINT32 TargetPid = NULL;
- char Search[MAX_PATH] = {0};
- char * SearchString = NULL;
+ CHAR Search[MAX_PATH] = {0};
+ CHAR * SearchString = NULL;
//
// Interpret command specific details (if any)
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/load.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/load.cpp
index 9f29970e..3ea642c4 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/load.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/load.cpp
@@ -14,10 +14,10 @@
//
// Global Variables
//
-extern HANDLE g_IsDriverLoadedSuccessfully;
-extern HANDLE g_DeviceHandle;
extern BOOLEAN g_IsConnectedToHyperDbgLocally;
-extern BOOLEAN g_IsDebuggerModulesLoaded;
+extern BOOLEAN g_IsKdModuleLoaded;
+extern BOOLEAN g_IsVmmModuleLoaded;
+extern BOOLEAN g_IsHyperTraceModuleLoaded;
/**
* @brief help of the load command
@@ -27,12 +27,15 @@ extern BOOLEAN g_IsDebuggerModulesLoaded;
VOID
CommandLoadHelp()
{
- ShowMessages("load : installs the drivers and load the modules.\n\n");
+ ShowMessages("load : installs drivers and load modules.\n\n");
- ShowMessages("syntax : \tload [ModuleName (string)]\n");
+ ShowMessages("syntax : \tload [ModuleNameOrAll (string)]\n");
ShowMessages("\n");
ShowMessages("\t\te.g : load vmm\n");
+ ShowMessages("\t\te.g : load kd\n");
+ ShowMessages("\t\te.g : load trace\n");
+ ShowMessages("\t\te.g : load all\n");
}
/**
@@ -64,24 +67,47 @@ CommandLoad(vector CommandTokens, string Command)
//
// Check for the module
//
- if (CompareLowerCaseStrings(CommandTokens.at(1), "vmm"))
+ if (CompareLowerCaseStrings(CommandTokens.at(1), "all") || CompareLowerCaseStrings(CommandTokens.at(1), "."))
{
//
- // Check to make sure that the driver is not already loaded
+ // Load aa Modules
//
- if (g_DeviceHandle)
+ ShowMessages("loading the all modules\n");
+
+ if (HyperDbgInstallKdDriver() == 1 || HyperDbgLoadAllModules() == 1)
{
- ShowMessages("handle of the driver found, if you use 'load' before, please "
- "first unload it then call 'unload'\n");
+ ShowMessages("failed to install or load drivers\n");
return;
}
//
- // Load VMM Module
+ // If in vmi-mode then initialize and load symbols (pdb)
+ // for previously downloaded symbols
+ // When the VMM module is loaded, we use the current
+ // process (HyperDbg's process) as the base for user-mode
+ // symbols
//
- ShowMessages("loading the vmm driver\n");
+ SymbolLocalReload(GetCurrentProcessId());
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(1), "vmm") ||
+ CompareLowerCaseStrings(CommandTokens.at(1), "vm"))
+ {
+ //
+ // Check to make sure that the driver is not already loaded
+ //
+ if (g_IsVmmModuleLoaded)
+ {
+ ShowMessages("the vmm module is already running, if you use 'load' before, please "
+ "first unload it using the 'unload' command\n");
+ return;
+ }
- if (HyperDbgInstallVmmDriver() == 1 || HyperDbgLoadVmmModule() == 1)
+ //
+ // Load the VMM Module
+ //
+ ShowMessages("loading the vmm module\n");
+
+ if (HyperDbgInstallKdDriver() == 1 || HyperDbgLoadVmmModule() == 1)
{
ShowMessages("failed to install or load the driver\n");
return;
@@ -96,6 +122,58 @@ CommandLoad(vector CommandTokens, string Command)
//
SymbolLocalReload(GetCurrentProcessId());
}
+ else if (CompareLowerCaseStrings(CommandTokens.at(1), "trace") ||
+ CompareLowerCaseStrings(CommandTokens.at(1), "hypertrace"))
+ {
+ //
+ // Check to make sure that the driver is not already loaded
+ //
+ if (g_IsHyperTraceModuleLoaded)
+ {
+ ShowMessages("the trace module is already running, if you use 'load' before, please "
+ "first unload it using the 'unload' command\n");
+ return;
+ }
+
+ //
+ // Load the HyperTrace Module
+ //
+ ShowMessages("loading the trace module\n");
+
+ if (HyperDbgInstallKdDriver() == 1 || HyperDbgLoadHyperTraceModule() == 1)
+ {
+ ShowMessages("failed to install or load the driver\n");
+ return;
+ }
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(1), "kd") ||
+ CompareLowerCaseStrings(CommandTokens.at(1), "dbg") ||
+ CompareLowerCaseStrings(CommandTokens.at(1), "debugger") ||
+ CompareLowerCaseStrings(CommandTokens.at(1), "debug") ||
+ CompareLowerCaseStrings(CommandTokens.at(1), "kerneldebugger") ||
+ CompareLowerCaseStrings(CommandTokens.at(1), "kerneldebug"))
+ {
+ //
+ // Check to make sure that the driver is not already loaded
+ //
+ if (g_IsKdModuleLoaded)
+ {
+ ShowMessages("the kd module is already running, if you use 'load' before, please "
+ "first unload it using the 'unload' command\n");
+ return;
+ }
+
+ //
+ // Load the KD Module
+ //
+ ShowMessages("loading the kd module\n");
+
+ if (HyperDbgInstallKdDriver() == 1 || HyperDbgLoadKdModule() == 1)
+ {
+ ShowMessages("failed to install or load the driver\n");
+ return;
+ }
+ }
else
{
//
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/p.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/p.cpp
index 4836feb6..a50a41d2 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/p.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/p.cpp
@@ -108,7 +108,7 @@ CommandP(vector CommandTokens, string Command)
//
g_IsInstrumentingInstructions = TRUE;
- for (size_t i = 0; i < StepCount; i++)
+ for (SIZE_T i = 0; i < StepCount; i++)
{
//
// For logging purpose
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/pause.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/pause.cpp
index 33cee8af..5d2246e7 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/pause.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/pause.cpp
@@ -54,9 +54,8 @@ CommandPauseRequest()
}
else if (g_ActiveProcessDebuggingState.IsActive && UdPauseProcess(g_ActiveProcessDebuggingState.ProcessDebuggingToken))
{
- ShowMessages("please keep interacting with the process until all the "
- "threads are intercepted and halted; whenever you execute "
- "the first command, the thread interception will be stopped\n");
+ ShowMessages("please keep interacting with the process until all the threads are intercepted "
+ "and halted; you can run the 'g' command to continue the debuggee\n");
}
}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/preactivate.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/preactivate.cpp
index a4c35914..ee88936d 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/preactivate.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/preactivate.cpp
@@ -11,6 +11,12 @@
*/
#include "pch.h"
+//
+// Global Variables
+//
+extern HANDLE g_DeviceHandle;
+extern BOOLEAN g_IsVmmModuleLoaded;
+
/**
* @brief help of the preactivate command
*
@@ -44,7 +50,7 @@ CommandPreactivate(vector CommandTokens, string Command)
{
BOOL Status;
ULONG ReturnedLength;
- DEBUGGER_PREACTIVATE_COMMAND PreactivateRequest = {0};
+ DEBUGGER_PREACTIVATE_COMMAND PreactivateRequest = {};
if (CommandTokens.size() != 2)
{
@@ -71,12 +77,12 @@ CommandPreactivate(vector CommandTokens, string Command)
return;
}
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
//
// Send IOCTL
//
- Status = DeviceIoControl(
+ Status = PlatformDeviceIoControl(
g_DeviceHandle, // Handle to device
IOCTL_PREACTIVATE_FUNCTIONALITY, // IO Control Code (IOCTL)
&PreactivateRequest, // Input Buffer to driver.
@@ -90,7 +96,7 @@ CommandPreactivate(vector CommandTokens, string Command)
if (!Status)
{
- ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
+ ShowMessages("ioctl failed with code 0x%x\n", PlatformGetLastError());
return;
}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/prealloc.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/prealloc.cpp
index 5fecc38e..0bf9545b 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/prealloc.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/prealloc.cpp
@@ -11,6 +11,11 @@
*/
#include "pch.h"
+//
+// Global Variables
+//
+extern BOOLEAN g_IsKdModuleLoaded;
+
/**
* @brief help of the prealloc command
*
@@ -57,7 +62,7 @@ CommandPrealloc(vector CommandTokens, string Command)
BOOL Status;
ULONG ReturnedLength;
UINT64 Count;
- DEBUGGER_PREALLOC_COMMAND PreallocRequest = {0};
+ DEBUGGER_PREALLOC_COMMAND PreallocRequest = {};
string SecondParam;
if (CommandTokens.size() != 3)
@@ -133,12 +138,12 @@ CommandPrealloc(vector CommandTokens, string Command)
//
PreallocRequest.Count = (UINT32)Count;
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
//
// Send IOCTL
//
- Status = DeviceIoControl(
+ Status = PlatformDeviceIoControl(
g_DeviceHandle, // Handle to device
IOCTL_RESERVE_PRE_ALLOCATED_POOLS, // IO Control Code (IOCTL)
&PreallocRequest, // Input Buffer to driver.
@@ -152,7 +157,7 @@ CommandPrealloc(vector CommandTokens, string Command)
if (!Status)
{
- ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
+ ShowMessages("ioctl failed with code 0x%x\n", PlatformGetLastError());
return;
}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/print.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/print.cpp
index 3dd95374..da7af0e0 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/print.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/print.cpp
@@ -14,11 +14,6 @@
using namespace std;
-//
-// Global Variables
-//
-extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
-
/**
* @brief help of the print command
*
@@ -46,11 +41,6 @@ CommandPrintHelp()
VOID
CommandPrint(vector CommandTokens, string Command)
{
- PVOID CodeBuffer;
- UINT64 BufferAddress;
- UINT32 BufferLength;
- UINT32 Pointer;
-
if (CommandTokens.size() == 1)
{
ShowMessages("incorrect use of the '%s'\n\n",
@@ -80,54 +70,8 @@ CommandPrint(vector CommandTokens, string Command)
Command.insert(0, "print(");
Command.append(");");
- if (g_IsSerialConnectedToRemoteDebuggee)
- {
- //
- // Send over serial
- //
-
- //
- // Run script engine handler
- //
- CodeBuffer = ScriptEngineParseWrapper((char *)Command.c_str(), TRUE);
-
- if (CodeBuffer == NULL)
- {
- //
- // return to show that this item contains an script
- //
- return;
- }
-
- //
- // Print symbols (test)
- //
- // PrintSymbolBufferWrapper(CodeBuffer);
-
- //
- // Set the buffer and length
- //
- BufferAddress = ScriptEngineWrapperGetHead(CodeBuffer);
- BufferLength = ScriptEngineWrapperGetSize(CodeBuffer);
- Pointer = ScriptEngineWrapperGetPointer(CodeBuffer);
-
- //
- // Send it to the remote debuggee
- //
- KdSendScriptPacketToDebuggee(BufferAddress, BufferLength, Pointer, FALSE);
-
- //
- // Remove the buffer of script engine interpreted code
- //
- ScriptEngineWrapperRemoveSymbolBuffer(CodeBuffer);
-
- ShowMessages("\n");
- }
- else
- {
- //
- // error
- //
- ShowMessages("err, you're not connected to any debuggee\n");
- }
+ //
+ // Execute the expression
+ //
+ ScriptEngineExecuteSingleExpression((CHAR *)Command.c_str(), TRUE, FALSE);
}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/r.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/r.cpp
index 15fc2598..ca0aaa73 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/r.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/r.cpp
@@ -17,7 +17,8 @@
//
// Global Variables
//
-extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
std::map RegistersMap = {
{"rax", REGISTER_RAX},
@@ -201,10 +202,30 @@ HyperDbgReadAllRegisters(GUEST_REGS * GuestRegisters, GUEST_EXTRA_REGISTERS * Ex
//
RegState->RegisterId = DEBUGGEE_SHOW_ALL_REGISTERS;
- if (!KdSendReadRegisterPacketToDebuggee(RegState, SizeOfRegState))
+ //
+ // Check whether a kernel debugger is connected or a user-mode debugger is active
+ //
+ if (g_IsSerialConnectedToRemoteDebuggee)
{
- free(RegState);
- return FALSE;
+ if (!KdSendReadRegisterPacketToDebuggee(RegState, SizeOfRegState))
+ {
+ free(RegState);
+ return FALSE;
+ }
+ }
+ else if (g_ActiveProcessDebuggingState.IsActive && g_ActiveProcessDebuggingState.IsPaused)
+ {
+ //
+ // It's stepping over user debugger
+ //
+ if (!UdSendReadRegisterToUserDebugger(g_ActiveProcessDebuggingState.ProcessDebuggingToken,
+ g_ActiveProcessDebuggingState.ThreadId,
+ RegState,
+ SizeOfRegState))
+ {
+ free(RegState);
+ return FALSE;
+ }
}
if (RegState->KernelStatus == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
@@ -253,9 +274,25 @@ HyperDbgReadTargetRegister(REGS_ENUM RegisterId, UINT64 * TargetRegister)
//
RegState.RegisterId = (UINT32)RegisterId;
- if (!KdSendReadRegisterPacketToDebuggee(&RegState, sizeof(DEBUGGEE_REGISTER_READ_DESCRIPTION)))
+ if (g_IsSerialConnectedToRemoteDebuggee)
{
- return FALSE;
+ if (!KdSendReadRegisterPacketToDebuggee(&RegState, sizeof(DEBUGGEE_REGISTER_READ_DESCRIPTION)))
+ {
+ return FALSE;
+ }
+ }
+ else if (g_ActiveProcessDebuggingState.IsActive && g_ActiveProcessDebuggingState.IsPaused)
+ {
+ //
+ // It's stepping over user debugger
+ //
+ if (!UdSendReadRegisterToUserDebugger(g_ActiveProcessDebuggingState.ProcessDebuggingToken,
+ g_ActiveProcessDebuggingState.ThreadId,
+ &RegState,
+ sizeof(DEBUGGEE_REGISTER_READ_DESCRIPTION)))
+ {
+ return FALSE;
+ }
}
if (RegState.KernelStatus == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
@@ -414,31 +451,24 @@ HyperDbgRegisterShowTargetRegister(REGS_ENUM RegisterId)
VOID
CommandR(vector CommandTokens, string Command)
{
- //
- // Interpret here
- //
- PVOID CodeBuffer;
- UINT64 BufferAddress;
- UINT32 BufferLength;
- UINT32 Pointer;
REGS_ENUM RegKind;
std::vector Tmp;
-
- std::string SetRegValue;
+ std::string SetRegisterValue;
if (CommandTokens.size() == 1)
{
//
// show all registers
//
- if (g_IsSerialConnectedToRemoteDebuggee)
+ if (g_IsSerialConnectedToRemoteDebuggee ||
+ (g_ActiveProcessDebuggingState.IsActive && g_ActiveProcessDebuggingState.IsPaused))
{
HyperDbgRegisterShowAll();
}
else
{
ShowMessages("err, reading registers (r) is not valid in the current "
- "context, you should connect to a debuggee\n");
+ "context, you should connect to a debuggee or attach to a process\n");
}
return;
@@ -476,14 +506,15 @@ CommandR(vector CommandTokens, string Command)
//
// send the request
//
- if (g_IsSerialConnectedToRemoteDebuggee)
+ if (g_IsSerialConnectedToRemoteDebuggee ||
+ (g_ActiveProcessDebuggingState.IsActive && g_ActiveProcessDebuggingState.IsPaused))
{
HyperDbgRegisterShowTargetRegister(RegKind);
}
else
{
ShowMessages("err, reading registers (r) is not valid in the current "
- "context, you should connect to a debuggee\n");
+ "context, you should connect to a debuggee or attach to a process\n");
}
}
else
@@ -495,7 +526,6 @@ CommandR(vector CommandTokens, string Command)
//
// if command contains a '=' means user wants modify the register
//
-
else if (Command.find('=', 0) != string::npos)
{
Command.erase(0, 1);
@@ -525,55 +555,12 @@ CommandR(vector CommandTokens, string Command)
//
// send the request
//
- SetRegValue = "@" + tmp + '=' + Tmp[1] + "; ";
+ SetRegisterValue = "@" + tmp + '=' + Tmp[1] + "; ";
- if (g_IsSerialConnectedToRemoteDebuggee)
- {
- //
- // Send over serial
- //
-
- //
- // Run script engine handler
- //
- CodeBuffer = ScriptEngineParseWrapper((char *)SetRegValue.c_str(), TRUE);
- if (CodeBuffer == NULL)
- {
- //
- // return to show that this item contains an script
- //
- return;
- }
-
- //
- // Print symbols (test)
- //
- // PrintSymbolBufferWrapper(CodeBuffer);
-
- //
- // Set the buffer and length
- //
- BufferAddress = ScriptEngineWrapperGetHead(CodeBuffer);
- BufferLength = ScriptEngineWrapperGetSize(CodeBuffer);
- Pointer = ScriptEngineWrapperGetPointer(CodeBuffer);
-
- //
- // Send it to the remote debuggee
- //
- KdSendScriptPacketToDebuggee(BufferAddress, BufferLength, Pointer, FALSE);
-
- //
- // Remove the buffer of script engine interpreted code
- //
- ScriptEngineWrapperRemoveSymbolBuffer(CodeBuffer);
- }
- else
- {
- //
- // error
- //
- ShowMessages("err, you're not connected to any debuggee\n");
- }
+ //
+ // Send data to the target user debugger or kernel debugger
+ //
+ ScriptEngineExecuteSingleExpression((CHAR *)SetRegisterValue.c_str(), TRUE, FALSE);
}
else
{
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/rdmsr.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/rdmsr.cpp
index 418ed31f..b5f948f5 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/rdmsr.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/rdmsr.cpp
@@ -11,6 +11,11 @@
*/
#include "pch.h"
+//
+// Global Variables
+//
+extern BOOLEAN g_IsKdModuleLoaded;
+
/**
* @brief help of the rdmsr command
*
@@ -183,7 +188,7 @@ CommandRdmsr(vector CommandTokens, string Command)
return;
}
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
MsrReadRequest.ActionType = DEBUGGER_MSR_READ;
MsrReadRequest.Msr = Msr;
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/s.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/s.cpp
index aa4d4bf8..9c3eff59 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/s.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/s.cpp
@@ -15,6 +15,7 @@
// Global Variables
//
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+extern BOOLEAN g_IsKdModuleLoaded;
extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
/**
@@ -62,6 +63,7 @@ VOID
CommandSearchSendRequest(UINT64 * BufferToSendAsIoctl, UINT32 BufferToSendAsIoctlSize)
{
BOOL Status;
+ DWORD BytesReturned;
UINT64 CurrentValue;
PUINT64 ResultsBuffer = NULL;
@@ -87,7 +89,7 @@ CommandSearchSendRequest(UINT64 * BufferToSendAsIoctl, UINT32 BufferToSendAsIoct
ResultsBuffer, // Output Buffer from driver.
MaximumSearchResults *
sizeof(UINT64), // Length of output buffer in bytes.
- NULL, // Bytes placed in buffer.
+ &BytesReturned, // Bytes placed in buffer.
NULL // synchronous call
);
@@ -102,7 +104,7 @@ CommandSearchSendRequest(UINT64 * BufferToSendAsIoctl, UINT32 BufferToSendAsIoct
//
// Show the results (if any)
//
- for (size_t i = 0; i < MaximumSearchResults; i++)
+ for (SIZE_T i = 0; i < MaximumSearchResults; i++)
{
CurrentValue = ResultsBuffer[i];
@@ -372,7 +374,7 @@ CommandSearchMemory(vector CommandTokens, string Command)
if (!SetValue)
{
//
- // At least on walue is there
+ // At least one value is there
//
SetValue = TRUE;
}
@@ -454,7 +456,7 @@ CommandSearchMemory(vector CommandTokens, string Command)
if (!g_IsSerialConnectedToRemoteDebuggee)
{
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
}
//
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/t.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/t.cpp
index 9d9b7330..afc48d51 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/t.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/t.cpp
@@ -93,7 +93,7 @@ CommandT(vector CommandTokens, string Command)
if (g_ActiveProcessDebuggingState.IsActive && !g_ActiveProcessDebuggingState.IsPaused)
{
ShowMessages("the target process is running, use the "
- "'pause' command or press CTRL+C to pause the process\n");
+ "'pause' command to pause the process\n");
return;
}
@@ -102,7 +102,7 @@ CommandT(vector CommandTokens, string Command)
//
g_IsInstrumentingInstructions = TRUE;
- for (size_t i = 0; i < StepCount; i++)
+ for (SIZE_T i = 0; i < StepCount; i++)
{
//
// For logging purpose
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/test.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/test.cpp
index faa95779..ffe824d8 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/test.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/test.cpp
@@ -14,6 +14,7 @@
//
// Global Variables
//
+extern BOOLEAN g_IsKdModuleLoaded;
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
/**
@@ -52,7 +53,7 @@ CommandTestPerformKernelTestsIoctl()
ULONG ReturnedLength;
DEBUGGER_PERFORM_KERNEL_TESTS KernelTestRequest = {0};
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// By the way, we don't need to send an input buffer
@@ -62,7 +63,7 @@ CommandTestPerformKernelTestsIoctl()
//
Status = DeviceIoControl(
g_DeviceHandle, // Handle to device
- IOCTL_PERFROM_KERNEL_SIDE_TESTS, // IO Control Code (IOCTL)
+ IOCTL_PERFORM_KERNEL_SIDE_TESTS, // IO Control Code (IOCTL)
&KernelTestRequest, // Input Buffer to driver.
SIZEOF_DEBUGGER_PERFORM_KERNEL_TESTS, // Input buffer length
&KernelTestRequest, // Output Buffer from driver.
@@ -115,6 +116,24 @@ CommandTestAllFunctionalities()
return;
}
+ //
+ // Test PE parser helpers
+ //
+ if (!OpenHyperDbgTestProcess(&ThreadHandle, &ProcessHandle, (CHAR *)TEST_CASE_PARAMETER_FOR_PE_PARSER))
+ {
+ ShowMessages("err, start HyperDbg test process for testing the PE parser\n");
+ return;
+ }
+
+ //
+ // Test CodeView RSDS parser helpers
+ //
+ if (!OpenHyperDbgTestProcess(&ThreadHandle, &ProcessHandle, (CHAR *)TEST_CASE_PARAMETER_FOR_CODEVIEW_RSDS_PARSER))
+ {
+ ShowMessages("err, start HyperDbg test process for testing the CodeView RSDS parser\n");
+ return;
+ }
+
//
// Test script engine (script parser) using semantic tests
//
@@ -216,7 +235,7 @@ SendCommandAndWaitForResponse:
RtlZeroMemory(Buffer, TEST_CASE_MAXIMUM_BUFFERS_TO_COMMUNICATE);
ReadBytes =
- NamedPipeServerReadClientMessage(PipeHandle, (char *)Buffer, TEST_CASE_MAXIMUM_BUFFERS_TO_COMMUNICATE);
+ NamedPipeServerReadClientMessage(PipeHandle, (CHAR *)Buffer, TEST_CASE_MAXIMUM_BUFFERS_TO_COMMUNICATE);
if (!ReadBytes)
{
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/unload.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/unload.cpp
index e42b0534..0738fc1b 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/unload.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/unload.cpp
@@ -15,7 +15,9 @@
// Global Variables
//
extern BOOLEAN g_IsConnectedToHyperDbgLocally;
-extern BOOLEAN g_IsDebuggerModulesLoaded;
+extern BOOLEAN g_IsKdModuleLoaded;
+extern BOOLEAN g_IsVmmModuleLoaded;
+extern BOOLEAN g_IsHyperTraceModuleLoaded;
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
extern BOOLEAN g_IsSerialConnectedToRemoteDebugger;
@@ -27,14 +29,45 @@ extern BOOLEAN g_IsSerialConnectedToRemoteDebugger;
VOID
CommandUnloadHelp()
{
- ShowMessages(
- "unload : unloads the kernel modules and uninstalls the drivers.\n\n");
+ ShowMessages("unload : unloads the kernel modules and uninstalls drivers.\n\n");
- ShowMessages("syntax : \tunload [remove] [ModuleName (string)]\n");
+ ShowMessages("syntax : \tunload [ModuleNameOrAll (string)]\n");
+ ShowMessages("syntax : \tunload [remove] [all]\n");
ShowMessages("\n");
ShowMessages("\t\te.g : unload vmm\n");
- ShowMessages("\t\te.g : unload remove vmm\n");
+ ShowMessages("\t\te.g : unload trace\n");
+ ShowMessages("\t\te.g : unload kd\n");
+ ShowMessages("\t\te.g : unload all\n");
+ ShowMessages("\t\te.g : unload remove all\n");
+}
+
+/**
+ * @brief check the environment for unload command
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+CommandUnloadCheckEnvironment()
+{
+ if (!g_IsConnectedToHyperDbgLocally)
+ {
+ ShowMessages("you're not connected to any instance of HyperDbg, did you "
+ "use '.connect'? \n");
+ return FALSE;
+ }
+
+ //
+ // Check to avoid using this command in debugger-mode
+ //
+ if (g_IsSerialConnectedToRemoteDebuggee || g_IsSerialConnectedToRemoteDebugger)
+ {
+ ShowMessages("you're connected to a an instance of HyperDbg, please use "
+ "'.debug close' command\n");
+ return FALSE;
+ }
+
+ return TRUE;
}
/**
@@ -59,60 +92,147 @@ CommandUnload(vector CommandTokens, string Command)
//
// Check for the module
//
- if ((CommandTokens.size() == 2 && CompareLowerCaseStrings(CommandTokens.at(1), "vmm")) ||
- (CommandTokens.size() == 3 && CompareLowerCaseStrings(CommandTokens.at(2), "vmm") && CompareLowerCaseStrings(CommandTokens.at(1), "remove")))
+ if (CommandTokens.size() == 2 &&
+ (CompareLowerCaseStrings(CommandTokens.at(1), "vmm") || CompareLowerCaseStrings(CommandTokens.at(1), "vm")))
{
- if (!g_IsConnectedToHyperDbgLocally)
+ //
+ // Check the environment
+ //
+ if (!CommandUnloadCheckEnvironment())
{
- ShowMessages("you're not connected to any instance of HyperDbg, did you "
- "use '.connect'? \n");
return;
}
- //
- // Check to avoid using this command in debugger-mode
- //
- if (g_IsSerialConnectedToRemoteDebuggee || g_IsSerialConnectedToRemoteDebugger)
- {
- ShowMessages("you're connected to a an instance of HyperDbg, please use "
- "'.debug close' command\n");
- return;
- }
-
- if (g_IsDebuggerModulesLoaded)
+ if (g_IsVmmModuleLoaded)
{
HyperDbgUnloadVmm();
+
+ HyperDbgUnloadKd(); // Test: Should be removed
}
else
{
- ShowMessages("there is nothing to unload\n");
+ ShowMessages("the vmm module is not loadedd\n");
}
-
+ }
+ else if (CommandTokens.size() == 2 &&
+ (CompareLowerCaseStrings(CommandTokens.at(1), "trace") || CompareLowerCaseStrings(CommandTokens.at(1), "hypertrace")))
+ {
//
- // Check to remove the driver
+ // Check the environment
//
- if (CompareLowerCaseStrings(CommandTokens.at(1), "remove"))
+ if (!CommandUnloadCheckEnvironment())
{
- //
- // Stop the driver
- //
- if (HyperDbgStopVmmDriver())
- {
- ShowMessages("err, failed to stop driver\n");
- return;
- }
-
- //
- // Uninstall the driver
- //
- if (HyperDbgUninstallVmmDriver())
- {
- ShowMessages("err, failed to uninstall the driver\n");
- return;
- }
-
- ShowMessages("the driver is removed\n");
+ return;
}
+
+ if (g_IsHyperTraceModuleLoaded)
+ {
+ HyperDbgUnloadHyperTrace();
+ }
+ else
+ {
+ ShowMessages("the trace (hypertrace) module is not loadedd\n");
+ }
+ }
+ else if (CommandTokens.size() == 2 &&
+ (CompareLowerCaseStrings(CommandTokens.at(1), "kd") || CompareLowerCaseStrings(CommandTokens.at(1), "dbg") ||
+ CompareLowerCaseStrings(CommandTokens.at(1), "debugger") || CompareLowerCaseStrings(CommandTokens.at(1), "debug") ||
+ CompareLowerCaseStrings(CommandTokens.at(1), "kerneldebugger") || CompareLowerCaseStrings(CommandTokens.at(1), "kerneldebug")))
+ {
+ //
+ // Check the environment
+ //
+ if (!CommandUnloadCheckEnvironment())
+ {
+ return;
+ }
+
+ if (g_IsKdModuleLoaded)
+ {
+ HyperDbgUnloadKd();
+ }
+ else
+ {
+ ShowMessages("the kd (kernel debugger) module is not loadedd\n");
+ }
+ }
+ else if (CommandTokens.size() == 2 &&
+ (CompareLowerCaseStrings(CommandTokens.at(1), "all") || CompareLowerCaseStrings(CommandTokens.at(1), ".")))
+ {
+ //
+ // Check the environment
+ //
+ if (!CommandUnloadCheckEnvironment())
+ {
+ return;
+ }
+
+ //
+ // Check if any module is loaded
+ //
+ if (!HyperDbgIsAnyModuleLoaded())
+ {
+ ShowMessages("no module is loaded\n");
+ return;
+ }
+
+ ShowMessages("unloading all modules\n");
+
+ //
+ // Unload all modules
+ //
+ if (HyperDbgUnloadAllModules() != 0)
+ {
+ ShowMessages("err, failed to unload all modules\n");
+ return;
+ }
+ else
+ {
+ ShowMessages("all modules are unloaded\n");
+ }
+ }
+ else if (CommandTokens.size() == 3 && CompareLowerCaseStrings(CommandTokens.at(1), "remove") &&
+ (CompareLowerCaseStrings(CommandTokens.at(2), "all") ||
+ CompareLowerCaseStrings(CommandTokens.at(2), ".") ||
+ CompareLowerCaseStrings(CommandTokens.at(2), "vmm") ||
+ CompareLowerCaseStrings(CommandTokens.at(2), "vm")))
+ {
+ //
+ // Check the environment
+ //
+ if (!CommandUnloadCheckEnvironment())
+ {
+ return;
+ }
+
+ //
+ // Unload all modules before removing the driver
+ //
+ if (HyperDbgUnloadAllModules())
+ {
+ ShowMessages("err, failed to unload all modules\n");
+ return;
+ }
+
+ //
+ // Stop the driver
+ //
+ if (HyperDbgStopKdDriver())
+ {
+ ShowMessages("err, failed to stop driver\n");
+ return;
+ }
+
+ //
+ // Uninstall the driver
+ //
+ if (HyperDbgUninstallKdDriver())
+ {
+ ShowMessages("err, failed to uninstall the driver\n");
+ return;
+ }
+
+ ShowMessages("all drivers are removed\n");
}
else
{
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/wrmsr.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/wrmsr.cpp
index 1636e830..7e6fb434 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/wrmsr.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/wrmsr.cpp
@@ -11,6 +11,11 @@
*/
#include "pch.h"
+//
+// Global Variables
+//
+extern BOOLEAN g_IsKdModuleLoaded;
+
/**
* @brief help of the wrmsr command
*
@@ -43,6 +48,7 @@ CommandWrmsr(vector CommandTokens, string Command)
{
BOOL Status;
UINT64 Msr;
+ ULONG ReturnedLength;
DEBUGGER_READ_AND_WRITE_ON_MSR MsrWriteRequest = {0};
BOOL IsNextCoreId = FALSE;
BOOL SetMsr = FALSE;
@@ -145,7 +151,7 @@ CommandWrmsr(vector CommandTokens, string Command)
return;
}
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
MsrWriteRequest.ActionType = DEBUGGER_MSR_WRITE;
MsrWriteRequest.Msr = Msr;
@@ -157,9 +163,9 @@ CommandWrmsr(vector CommandTokens, string Command)
IOCTL_DEBUGGER_READ_OR_WRITE_MSR, // IO Control Code (IOCTL)
&MsrWriteRequest, // Input Buffer to driver.
SIZEOF_DEBUGGER_READ_AND_WRITE_ON_MSR, // Input buffer length
- NULL, // Output Buffer from driver.
- NULL, // Length of output buffer in bytes.
- NULL, // Bytes placed in buffer.
+ &MsrWriteRequest, // Output Buffer from driver.
+ SIZEOF_DEBUGGER_READ_AND_WRITE_ON_MSR, // Length of output buffer in bytes.
+ &ReturnedLength, // Bytes placed in buffer.
NULL // synchronous call
);
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/apic.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/apic.cpp
index e91d2c5c..b68c93cb 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/apic.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/apic.cpp
@@ -14,6 +14,7 @@
//
// Global Variables
//
+extern BOOLEAN g_IsKdModuleLoaded;
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
/**
@@ -97,14 +98,14 @@ CommandApicSendRequest(DEBUGGER_APIC_REQUEST_TYPE ApicType,
}
else
{
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// Send IOCTL
//
Status = DeviceIoControl(
g_DeviceHandle, // Handle to device
- IOCTL_PERFROM_ACTIONS_ON_APIC, // IO Control Code (IOCTL)
+ IOCTL_PERFORM_ACTIONS_ON_APIC, // IO Control Code (IOCTL)
ApicRequest, // Input Buffer to driver.
SIZEOF_DEBUGGER_APIC_REQUEST, // Input buffer length
ApicRequest, // Output Buffer from driver.
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/cpuid.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/cpuid.cpp
index f149fa51..5475401a 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/cpuid.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/cpuid.cpp
@@ -91,7 +91,7 @@ CommandCpuid(vector CommandTokens, string Command)
else if (!GetEax)
{
//
- // It's probably an msr
+ // It's probably an index of EAX
//
if (!ConvertTokenToUInt64(Section, &SpecialTarget))
{
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/hide.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/hide.cpp
index 2e88983a..1675d709 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/hide.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/hide.cpp
@@ -1,6 +1,7 @@
/**
* @file hide.cpp
* @author Sina Karvandi (sina@hyperdbg.org)
+ * @author jtaw5649
* @brief !hide command
* @details
* @version 0.1
@@ -14,15 +15,7 @@
//
// Global Variables
//
-extern UINT64 g_CpuidAverage;
-extern UINT64 g_CpuidStandardDeviation;
-extern UINT64 g_CpuidMedian;
-
-extern UINT64 g_RdtscAverage;
-extern UINT64 g_RdtscStandardDeviation;
-extern UINT64 g_RdtscMedian;
-
-extern BOOLEAN g_TransparentResultsMeasured;
+extern BOOLEAN g_IsVmmModuleLoaded;
extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
/**
@@ -226,7 +219,7 @@ CommandHideFillSystemCalls(SYSTEM_CALL_NUMBERS_INFORMATION * SyscallNumberDetail
Result = FALSE;
}
- return TRUE;
+ return Result;
}
/**
@@ -234,27 +227,36 @@ CommandHideFillSystemCalls(SYSTEM_CALL_NUMBERS_INFORMATION * SyscallNumberDetail
* @param ProcessId
* @param ProcessName
* @param IsProcessId
+ * @param EvadeMask
*
* @return BOOLEAN
*/
BOOLEAN
-HyperDbgEnableTransparentMode(UINT32 ProcessId, CHAR * ProcessName, BOOLEAN IsProcessId)
+HyperDbgEnableTransparentModeEx(UINT32 ProcessId, CHAR * ProcessName, BOOLEAN IsProcessId, UINT32 EvadeMask)
{
BOOLEAN Status;
ULONG ReturnedLength;
DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE HideRequest = {0};
PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE FinalRequestBuffer = 0;
- size_t RequestBufferSize = 0;
+ SIZE_T RequestBufferSize = 0;
+ UINT32 EffectiveEvadeMask = EvadeMask == 0 ? TRANSPARENT_EVADE_MASK_DEFAULT : EvadeMask;
//
// Check if debugger is loaded or not
//
- // AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ // AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// We wanna hide the debugger and make transparent vm-exits
//
- HideRequest.IsHide = TRUE;
+ if ((EffectiveEvadeMask & ~TRANSPARENT_EVADE_MASK_ALL) != 0)
+ {
+ ShowMessages("unknown transparent-mode evade mask bits\n");
+ return FALSE;
+ }
+
+ HideRequest.IsHide = TRUE;
+ HideRequest.EvadeMask = EffectiveEvadeMask;
HideRequest.TrueIfProcessIdAndFalseIfProcessName = IsProcessId;
@@ -276,6 +278,13 @@ HyperDbgEnableTransparentMode(UINT32 ProcessId, CHAR * ProcessName, BOOLEAN IsPr
RequestBufferSize = sizeof(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE) + HideRequest.LengthOfProcessName;
}
+ if ((EffectiveEvadeMask & TRANSPARENT_EVADE_MASK_SYSCALL_HOOK) != 0 &&
+ !CommandHideFillSystemCalls(&HideRequest.SystemCallNumbersInformation))
+ {
+ ShowMessages("warning, failed to resolve one or more syscall numbers for transparent-mode\n");
+ return FALSE;
+ }
+
//
// Allocate the requested buffer
//
@@ -361,6 +370,20 @@ HyperDbgEnableTransparentMode(UINT32 ProcessId, CHAR * ProcessName, BOOLEAN IsPr
return TRUE;
}
+/**
+ * @brief Enable transparent mode
+ * @param ProcessId
+ * @param ProcessName
+ * @param IsProcessId
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperDbgEnableTransparentMode(UINT32 ProcessId, CHAR * ProcessName, BOOLEAN IsProcessId)
+{
+ return HyperDbgEnableTransparentModeEx(ProcessId, ProcessName, IsProcessId, 0);
+}
+
/**
* @brief !hide command handler
*
@@ -374,7 +397,7 @@ CommandHide(vector CommandTokens, string Command)
UINT32 TargetPid;
BOOLEAN TrueIfProcessIdAndFalseIfProcessName;
-#if ActivateHyperEvadeProject == TRUE
+#if ActivateHyperEvadeProject != TRUE
ShowMessages("warning, the !hide command (hyperevade project) is in the Beta phase and is not yet well-tested, "
"so it is disabled in this version. If you want to test, you can enable it "
@@ -383,7 +406,7 @@ CommandHide(vector CommandTokens, string Command)
#endif
- if (CommandTokens.size() <= 2 && CommandTokens.size() != 1)
+ if (CommandTokens.size() != 1 && CommandTokens.size() != 3)
{
ShowMessages("incorrect use of the '%s'\n\n",
GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/idt.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/idt.cpp
index 2c82e182..69e117fd 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/idt.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/idt.cpp
@@ -15,6 +15,7 @@
// Global Variables
//
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+extern BOOLEAN g_IsKdModuleLoaded;
extern BOOLEAN g_AddressConversion;
/**
@@ -63,7 +64,7 @@ HyperDbgGetIdtEntry(INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS * IdtPacket)
}
else
{
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// Send IOCTL
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/ioapic.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/ioapic.cpp
index 41734745..ab1f18b4 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/ioapic.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/ioapic.cpp
@@ -11,11 +11,6 @@
*/
#include "pch.h"
-//
-// Global Variables
-//
-extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
-
/**
* @brief help of the !ioapic command
*
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/lbr.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/lbr.cpp
new file mode 100644
index 00000000..3d2718e8
--- /dev/null
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/lbr.cpp
@@ -0,0 +1,384 @@
+/**
+ * @file lbr.cpp
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief !lbr command
+ * @details
+ * @version 0.19
+ * @date 2026-04-05
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+//
+// Global Variables
+//
+extern HANDLE g_DeviceHandle;
+extern BOOLEAN g_IsHyperTraceModuleLoaded;
+
+/**
+ * @brief help of the !lbr command
+ *
+ * @return VOID
+ */
+VOID
+CommandLbrHelp()
+{
+ ShowMessages("!lbr : performs operation for Last Branch Record (LBR).\n");
+ ShowMessages("for dumping LBR entries, you can use the '!lbrdump' command\n");
+
+ ShowMessages("syntax : \t!lbr [Function (string)]\n");
+ ShowMessages("syntax : \t!lbr [filter FilterOptions (string)]\n");
+
+ ShowMessages("\n");
+ ShowMessages("\t\te.g : !lbr enable\n");
+ ShowMessages("\t\te.g : !lbr disable\n");
+ ShowMessages("\t\te.g : !lbr flush\n");
+
+ ShowMessages("\n");
+ ShowMessages("\t\te.g : !lbr filter\n");
+ ShowMessages("\t\te.g : !lbr filter kernel jcc ind_jmp rel_jmp far\n");
+ ShowMessages("\t\te.g : !lbr filter kernel jcc return ind_jmp rel_jmp far\n");
+ ShowMessages("\t\te.g : !lbr filter kernel jcc ind_jmp rel_jmp\n");
+ ShowMessages("\t\te.g : !lbr filter user rel_call ind_call return far\n");
+ ShowMessages("\t\te.g : !lbr filter call_stack user\n");
+ ShowMessages("\t\te.g : !lbr filter call_stack kernel\n");
+
+ ShowMessages("\nlist of filter options: \n");
+ ShowMessages("\t kernel: do not capture at ring0\n");
+ ShowMessages("\t user: do not capture at ring > 0\n");
+ ShowMessages("\t jcc: do not capture conditional branches\n");
+ ShowMessages("\t rel_call: do not capture relative calls\n");
+ ShowMessages("\t ind_call: do not capture indirect calls\n");
+ ShowMessages("\t return: do not capture near returns\n");
+ ShowMessages("\t ind_jmp: do not capture indirect jumps\n");
+ ShowMessages("\t rel_jmp: do not capture relative jumps\n");
+ ShowMessages("\t far: do not capture far branches (only in legacy LBR. check docs for details)\n");
+ ShowMessages("\t other_branches: do not capture jmp/call ptr*, jmp/call m*, ret (0c8h), sys*, interrupts,\n");
+ ShowMessages("\t exceptions (other than debug exceptions), iret, int3, intn, into, tsx abort\n");
+ ShowMessages("\t eenter, eresume, eexit, aex, init, sipi, rsm (only in ARCH LBR. check docs for details)\n");
+ ShowMessages("\t call_stack: enable LBR stack to use LIFO filtering to capture call stack profile\n");
+ ShowMessages("\t not available on CPUs older than Haswell. for this item you can only specify the 'user'\n");
+ ShowMessages("\t or the 'kernel'. it prevents all types of branches except calls and rets\n");
+ ShowMessages("\t (no option): capture everything (default option)\n");
+
+ ShowMessages("\nnote 1: LBR is usually not supported (or is emulated) in nested virtualization (VM) environments\n");
+ ShowMessages("note 2: LBR will be disabled if there is a debug-break (#DB) condition, such as the trap flags or\n");
+ ShowMessages(" hardware debug registers (to learn how to mitigate this, check the documentation)\n");
+}
+
+/**
+ * @brief Send LBR requests
+ *
+ * @param LbrRequest
+ *
+ * @return VOID
+ */
+BOOLEAN
+CommandLbrSendRequest(HYPERTRACE_LBR_OPERATION_PACKETS * LbrRequest)
+{
+ BOOL Status;
+ ULONG ReturnedLength;
+
+ AssertShowMessageReturnStmt(g_IsHyperTraceModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_HYPERTRACE_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+
+ //
+ // Send IOCTL
+ //
+ Status = DeviceIoControl(
+ g_DeviceHandle, // Handle to device
+ IOCTL_PERFORM_HYPERTRACE_LBR_OPERATION, // IO Control Code (IOCTL)
+ LbrRequest, // Input Buffer to driver.
+ SIZEOF_HYPERTRACE_LBR_OPERATION_PACKETS, // Input buffer length
+ LbrRequest, // Output Buffer from driver.
+ SIZEOF_HYPERTRACE_LBR_OPERATION_PACKETS, // Length of output buffer in bytes.
+ &ReturnedLength, // Bytes placed in buffer.
+ NULL // synchronous call
+ );
+
+ if (!Status)
+ {
+ ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
+
+ return FALSE;
+ }
+
+ if (LbrRequest->KernelStatus == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+/**
+ * @brief Request to perform an LBR operation
+ *
+ * @param LbrRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperDbgPerformLbrOperation(HYPERTRACE_LBR_OPERATION_PACKETS * LbrRequest)
+{
+ return CommandLbrSendRequest(LbrRequest);
+}
+/**
+ * @brief Parses simple (no-argument) LBR operations: enable, disable, flush
+ *
+ * @param CommandTokens
+ * @param LbrRequest
+ *
+ * @return BOOLEAN TRUE if parsed successfully
+ */
+BOOLEAN
+CommandLbrParseSimpleOperation(vector CommandTokens, HYPERTRACE_LBR_OPERATION_PACKETS * LbrRequest)
+{
+ if (CommandTokens.size() != 2)
+ {
+ return FALSE;
+ }
+
+ if (CompareLowerCaseStrings(CommandTokens.at(1), "enable"))
+ {
+ LbrRequest->LbrOperationType = HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_ENABLE;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(1), "disable"))
+ {
+ LbrRequest->LbrOperationType = HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_DISABLE;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(1), "flush"))
+ {
+ LbrRequest->LbrOperationType = HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_FLUSH;
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Check validity of the filter options in case of call_stack mode
+ *
+ * @param LbrRequest
+ * @return BOOLEAN TRUE if the filter options are valid in case of call_stack mode
+ */
+BOOLEAN
+CommandLbrValidateCallStackFilterOptions(HYPERTRACE_LBR_OPERATION_PACKETS * LbrRequest)
+{
+ if (LbrRequest->LbrFilterOptions & LBR_CALL_STACK)
+ {
+ //
+ // Call-stack mode should be used with branch type enabling configured to capture only CALLs (NEAR_REL_CALL and
+ // NEAR_IND_CALL) and RETs (NEAR_RET). if the user specifed LBR_REL_CALL | LBR_IND_CALL | LBR_RETURN then
+ // it is invalid
+ //
+ if ((LbrRequest->LbrFilterOptions & (LBR_REL_CALL | LBR_IND_CALL | LBR_RETURN)))
+ {
+ ShowMessages("err, invalid filter options for 'call_stack' mode. when the 'call_stack' is enabled,"
+ " 'rel_call', 'ind_call', and 'return' could not be specified as filter options\n\n");
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * @brief Parses the LBR filter operation and accumulates filter option flags
+ *
+ * @param CommandTokens
+ * @param LbrRequest
+ *
+ * @return BOOLEAN TRUE if parsed successfully
+ */
+BOOLEAN
+CommandLbrParseFilterOperation(vector CommandTokens, HYPERTRACE_LBR_OPERATION_PACKETS * LbrRequest)
+{
+ LbrRequest->LbrOperationType = HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_FILTER;
+ LbrRequest->LbrFilterOptions = 0; // no options = capture everything
+
+ for (SIZE_T i = 2; i < CommandTokens.size(); i++)
+ {
+ if (CompareLowerCaseStrings(CommandTokens.at(i), "kernel"))
+ {
+ LbrRequest->LbrFilterOptions |= LBR_KERNEL;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "user"))
+ {
+ LbrRequest->LbrFilterOptions |= LBR_USER;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "jcc"))
+ {
+ LbrRequest->LbrFilterOptions |= LBR_JCC;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "rel_call"))
+ {
+ LbrRequest->LbrFilterOptions |= LBR_REL_CALL;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "ind_call"))
+ {
+ LbrRequest->LbrFilterOptions |= LBR_IND_CALL;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "return"))
+ {
+ LbrRequest->LbrFilterOptions |= LBR_RETURN;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "ind_jmp"))
+ {
+ LbrRequest->LbrFilterOptions |= LBR_IND_JMP;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "rel_jmp"))
+ {
+ LbrRequest->LbrFilterOptions |= LBR_REL_JMP;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "far") ||
+ CompareLowerCaseStrings(CommandTokens.at(i), "other_branch") ||
+ CompareLowerCaseStrings(CommandTokens.at(i), "other_branches"))
+ {
+ LbrRequest->LbrFilterOptions |= LBR_FAR_OTHER_BRANCHES;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "call_stack"))
+ {
+ LbrRequest->LbrFilterOptions |= LBR_CALL_STACK;
+ }
+ else
+ {
+ ShowMessages("unknown filter option '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(i)).c_str());
+ return FALSE;
+ }
+ }
+
+ //
+ // Call-stack mode should be used with branch type enabling configured to capture only CALLs (NEAR_REL_CALL and
+ // NEAR_IND_CALL) and RETs (NEAR_RET). When configured in this manner, the LBR array emulates a call stack,
+ // where CALLs are "pushed" and RETs "pop" them off the stack. If other branch types (JCC, NEAR_*_JMP, or
+ // OTHER_BRANCH) are enabled for recording with call-stack mode, LBR behavior may be undefined, so we will
+ // mask out any branch type filters that are not CALLs or RETs when call-stack mode is requested to ensure
+ // we are correctly emulating a call stack and avoiding undefined behavior
+ //
+
+ //
+ // If it is call_stack then we only keep the user and kernel bit and filter all branch types
+ // except calls and rets to ensure we are only capturing call stack profile
+ //
+ if (LbrRequest->LbrFilterOptions & LBR_CALL_STACK)
+ {
+ //
+ // Validate the filter options in case of call_stack mode
+ //
+ if (CommandLbrValidateCallStackFilterOptions(LbrRequest) == FALSE)
+ {
+ return FALSE;
+ }
+
+ //
+ // Preserve only the user/kernel privilege bits from the original options,
+ // then apply the mandatory call stack base flags
+ //
+ LbrRequest->LbrFilterOptions = LBR_CALL_STACK_BASE_FLAGS | (LbrRequest->LbrFilterOptions & (LBR_KERNEL | LBR_USER));
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Displays the success message appropriate for the completed LBR operation
+ *
+ * @param LbrRequest
+ *
+ * @return VOID
+ */
+VOID
+CommandLbrShowSuccessMessage(const HYPERTRACE_LBR_OPERATION_PACKETS * LbrRequest)
+{
+ switch (LbrRequest->LbrOperationType)
+ {
+ case HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_ENABLE:
+ ShowMessages("LBR enabled successfully\n");
+ break;
+ case HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_DISABLE:
+ ShowMessages("LBR disabled successfully\n");
+ break;
+ case HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_FLUSH:
+ ShowMessages("LBR branches are flushed\n");
+ break;
+ case HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_FILTER:
+ ShowMessages("LBR filter options are updated successfully\n");
+ break;
+ default:
+ ShowMessages("unknown LBR operation type\n");
+ break;
+ }
+}
+
+/**
+ * @brief !lbr command handler
+ *
+ * @param CommandTokens
+ * @param Command
+ *
+ * @return VOID
+ */
+VOID
+CommandLbr(vector CommandTokens, string Command)
+{
+ HYPERTRACE_LBR_OPERATION_PACKETS LbrRequest = {0};
+ BOOLEAN ParseResult = FALSE;
+
+ if (CommandTokens.size() == 1)
+ {
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
+ CommandLbrHelp();
+ return;
+ }
+
+ //
+ // Dispatch to the appropriate parser based on the subcommand
+ //
+ if (CompareLowerCaseStrings(CommandTokens.at(1), "enable") ||
+ CompareLowerCaseStrings(CommandTokens.at(1), "disable") ||
+ CompareLowerCaseStrings(CommandTokens.at(1), "flush"))
+ {
+ ParseResult = CommandLbrParseSimpleOperation(CommandTokens, &LbrRequest);
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(1), "filter"))
+ {
+ ParseResult = CommandLbrParseFilterOperation(CommandTokens, &LbrRequest);
+ }
+ else
+ {
+ ParseResult = FALSE;
+ }
+
+ if (!ParseResult)
+ {
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
+ CommandLbrHelp();
+ return;
+ }
+
+ //
+ // Check if the HyperTrace module is loaded, as it is required for LBR operations
+ //
+ AssertShowMessageReturnStmt(g_IsHyperTraceModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_HYPERTRACE_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
+
+ //
+ // Send the LBR operation request
+ //
+ if (CommandLbrSendRequest(&LbrRequest))
+ {
+ CommandLbrShowSuccessMessage(&LbrRequest);
+ }
+ else
+ {
+ ShowErrorMessage(LbrRequest.KernelStatus);
+ }
+}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/lbrdump.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/lbrdump.cpp
new file mode 100644
index 00000000..6df20e4a
--- /dev/null
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/lbrdump.cpp
@@ -0,0 +1,351 @@
+/**
+ * @file lbrdump.cpp
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief !lbrdump command
+ * @details
+ * @version 0.19
+ * @date 2026-05-03
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+//
+// Global Variables
+//
+extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+extern BOOLEAN g_IsHyperTraceModuleLoaded;
+extern BOOLEAN g_IsHyperTraceModuleLoaded;
+
+/**
+ * @brief Send LBR dump requests
+ *
+ * @param LbrdumpRequest
+ *
+ * @return VOID
+ */
+BOOLEAN
+HyperDbgLbrdumpSendRequest(HYPERTRACE_LBR_DUMP_PACKETS * LbrdumpRequest)
+{
+ BOOL Status;
+ ULONG ReturnedLength;
+
+ if (g_IsSerialConnectedToRemoteDebuggee)
+ {
+ //
+ // Send the request over serial kernel debugger
+ //
+ if (!KdSendHyperTraceLbrdumpPacketsToDebuggee(LbrdumpRequest, SIZEOF_HYPERTRACE_LBR_DUMP_PACKETS))
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ AssertShowMessageReturnStmt(g_IsHyperTraceModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_HYPERTRACE_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+
+ //
+ // Send IOCTL
+ //
+ Status = DeviceIoControl(
+ g_DeviceHandle, // Handle to device
+ IOCTL_PERFORM_HYPERTRACE_LBR_DUMP, // IO Control Code (IOCTL)
+ LbrdumpRequest, // Input Buffer to driver.
+ SIZEOF_HYPERTRACE_LBR_DUMP_PACKETS, // Input buffer length
+ LbrdumpRequest, // Output Buffer from driver.
+ SIZEOF_HYPERTRACE_LBR_DUMP_PACKETS, // Length of output buffer in bytes.
+ &ReturnedLength, // Bytes placed in buffer.
+ NULL // synchronous call
+ );
+
+ if (!Status)
+ {
+ ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
+
+ return FALSE;
+ }
+ }
+
+ //
+ // Sending the request was successful
+ //
+ return TRUE;
+}
+
+/**
+ * @brief help of the !lbrdump command
+ *
+ * @return VOID
+ */
+VOID
+CommandLbrdumpHelp()
+{
+ ShowMessages("!lbrdump : dumps Last Branch Record (LBR).\n");
+ ShowMessages("for using this command, you should configure it using the '!lbr' command\n");
+
+ ShowMessages("syntax : \t!lbrdump [core CoreId (hex)]\n");
+
+ ShowMessages("\n");
+ ShowMessages("\t\te.g : !lbrdump\n");
+ ShowMessages("\t\te.g : !lbrdump core 1\n");
+}
+
+/**
+ * @brief Get the branch type name based on the LBR branch type value (only applicable for architectural LBR)
+ *
+ * @details THIS FUNCTION IS ALSO IMPLEMENTED IN THE USER MODE
+ *
+ * @param BrType The raw branch type value from the LBR info MSR
+ * @param BrTypeName A character buffer to receive the branch type name string
+ *
+ * @return VOID
+ */
+VOID
+CommandLbrdumpGetArchBranchTypet(UINT32 BrType, CHAR * BrTypeName)
+{
+ if (BrType == LBR_BR_TYPE_COND)
+ {
+ strncpy(BrTypeName, "COND ", LBR_BR_TYPE_NAME_MAX_LEN);
+ }
+ else if (BrType == LBR_BR_TYPE_JMP_INDIRECT)
+ {
+ strncpy(BrTypeName, "JMP Indirect ", LBR_BR_TYPE_NAME_MAX_LEN);
+ }
+ else if (BrType == LBR_BR_TYPE_JMP_DIRECT)
+ {
+ strncpy(BrTypeName, "JMP Direct ", LBR_BR_TYPE_NAME_MAX_LEN);
+ }
+ else if (BrType == LBR_BR_TYPE_CALL_INDIRECT)
+ {
+ strncpy(BrTypeName, "CALL Indirect", LBR_BR_TYPE_NAME_MAX_LEN);
+ }
+ else if (BrType == LBR_BR_TYPE_CALL_DIRECT)
+ {
+ strncpy(BrTypeName, "CALL Direct ", LBR_BR_TYPE_NAME_MAX_LEN);
+ }
+ else if (BrType == LBR_BR_TYPE_RET)
+ {
+ strncpy(BrTypeName, "RET ", LBR_BR_TYPE_NAME_MAX_LEN);
+ }
+ else if (BrType >= LBR_BR_TYPE_RESERVED_MIN && BrType <= LBR_BR_TYPE_RESERVED_MAX)
+ {
+ strncpy(BrTypeName, "Reserved ", LBR_BR_TYPE_NAME_MAX_LEN);
+ }
+ else if (BrType >= LBR_BR_TYPE_OTHER_MIN && BrType <= LBR_BR_TYPE_OTHER_MAX)
+ {
+ strncpy(BrTypeName, "Other Branch ", LBR_BR_TYPE_NAME_MAX_LEN);
+ }
+ else
+ {
+ strncpy(BrTypeName, "Unknown ", LBR_BR_TYPE_NAME_MAX_LEN);
+ }
+}
+
+/**
+ * @brief Print collected LBR branches
+ *
+ * @param LbrdumpRequest
+ *
+ * @return VOID
+ */
+VOID
+CommandLbrdumpPrint(HYPERTRACE_LBR_DUMP_PACKETS * LbrdumpRequest)
+{
+ ULONG CurrentIdx;
+ BOOLEAN IsCoreEmpty = TRUE;
+ CHAR BrTypeName[LBR_BR_TYPE_NAME_MAX_LEN] = {0};
+ UINT32 BrType = 0;
+
+ ShowMessages("LBR Chronological Trace on core: 0x%x\n\n", LbrdumpRequest->CoreId);
+
+ for (ULONG i = 1; i <= LbrdumpRequest->CurrentLbrCapacity; i++)
+ {
+ if (LbrdumpRequest->ArchBasedLBR)
+ {
+ //
+ // In ARCH LBR, there is not TOS index and everything is in order
+ //
+ CurrentIdx = i - 1;
+ }
+ else
+ {
+ CurrentIdx = (ULONG)(LbrdumpRequest->LbrStack.Tos + i) % (ULONG)LbrdumpRequest->CurrentLbrCapacity;
+ }
+
+ if (LbrdumpRequest->LbrStack.BranchEntry[CurrentIdx].From == 0)
+ {
+ continue;
+ }
+
+ IsCoreEmpty = FALSE;
+
+ if (LbrdumpRequest->ArchBasedLBR)
+ {
+ BrType = (UINT32)LbrdumpRequest->LbrStack.LastBranchInfo[CurrentIdx].BrType_OnlyArchLbr;
+
+ //
+ // Get the branch type name for better readability when printing
+ //
+ CommandLbrdumpGetArchBranchTypet(BrType, BrTypeName);
+
+ //
+ // Architectural LBR
+ //
+ ShowMessages("\t [%2u] Branch Mispredicted: %s, Branch type: %s, Cycle Count (Decimal): %04d (is valid? %s) - From: %016llx To: %016llx\n",
+ CurrentIdx,
+ LbrdumpRequest->LbrStack.LastBranchInfo[CurrentIdx].Mispred ? "true " : "false",
+ BrTypeName,
+ LbrdumpRequest->LbrStack.LastBranchInfo[CurrentIdx].CycleCount,
+ LbrdumpRequest->LbrStack.LastBranchInfo[CurrentIdx].CycCntValid_OnlyArchLbr ? "true " : "false",
+ LbrdumpRequest->LbrStack.BranchEntry[CurrentIdx].From,
+ LbrdumpRequest->LbrStack.BranchEntry[CurrentIdx].To);
+ }
+ else
+ {
+ //
+ // Legacy LBR
+ //
+ ShowMessages("\t [%2u] Branch Mispredicted: %s, Cycle Count (Decimal): %04d - From: %016llx To: %016llx\n",
+ CurrentIdx,
+ LbrdumpRequest->LbrStack.LastBranchInfo[CurrentIdx].Mispred ? "true " : "false",
+ LbrdumpRequest->LbrStack.LastBranchInfo[CurrentIdx].CycleCount,
+ LbrdumpRequest->LbrStack.BranchEntry[CurrentIdx].From,
+ LbrdumpRequest->LbrStack.BranchEntry[CurrentIdx].To);
+ }
+ }
+
+ if (IsCoreEmpty)
+ {
+ ShowMessages("\t no LBR entries found for this core\n"
+ "\t you can use the 'lbr_save();' function in the script engine\n"
+ "\t on the target core to save the LBR entries before dumping\n\n"
+ "\t ===========================================================\n\n");
+ }
+ else
+ {
+ ShowMessages("\n\t ===========================================================\n\n");
+ }
+}
+
+/**
+ * @brief !lbrdump command handler
+ *
+ * @param CommandTokens
+ * @param Command
+ *
+ * @return VOID
+ */
+VOID
+CommandLbrdump(vector CommandTokens, string Command)
+{
+ HYPERTRACE_LBR_DUMP_PACKETS LbrdumpRequest = {0};
+ UINT32 CoreId = 0;
+ BOOLEAN ContinueDumpingAllCores = TRUE;
+
+ if (CommandTokens.size() != 1 && CommandTokens.size() != 3)
+ {
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
+ CommandLbrdumpHelp();
+ return;
+ }
+
+ //
+ // Check if the HyperTrace module is loaded, as it is required for LBR operations
+ //
+ AssertShowMessageReturnStmt(g_IsHyperTraceModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_HYPERTRACE_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
+
+ if (CommandTokens.size() == 3)
+ {
+ if (CompareLowerCaseStrings(CommandTokens.at(1), "core"))
+ {
+ if (!ConvertTokenToUInt32(CommandTokens.at(2), &CoreId))
+ {
+ //
+ // Unknown parameter
+ //
+ ShowMessages("unknown parameter '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
+ CommandLbrdumpHelp();
+
+ return;
+ }
+ }
+ else
+ {
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
+ CommandLbrdumpHelp();
+ return;
+ }
+ }
+ else
+ {
+ //
+ // If no core is specified, we can set the CoreId to a special value (e.g., 0xFFFFFFFF) to indicate that the dump should be performed for all cores
+ //
+ CoreId = HYPERTRACE_LBR_DUMP_ALL_CORES;
+ }
+
+ //
+ // If the CoreId is set to the special value for dumping all cores,
+ // we can set it to 0 to start dumping from the first core and rely on the NextCoreIsValid flag
+ // in the dump request structure to indicate whether there are more cores to be dumped or not in
+ // the driver response
+ //
+ if (CoreId == HYPERTRACE_LBR_DUMP_ALL_CORES)
+ {
+ LbrdumpRequest.CoreId = 0;
+ }
+ else
+ {
+ LbrdumpRequest.CoreId = CoreId;
+ }
+
+ while (ContinueDumpingAllCores)
+ {
+ //
+ // Send the LBR dump request
+ //
+ if (HyperDbgLbrdumpSendRequest(&LbrdumpRequest))
+ {
+ if (LbrdumpRequest.KernelStatus == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
+ {
+ //
+ // Show entries of the LBR stack in the request structure which are filled by the driver in response to the dump request
+ //
+ CommandLbrdumpPrint(&LbrdumpRequest);
+
+ if (CoreId == HYPERTRACE_LBR_DUMP_ALL_CORES && LbrdumpRequest.NextCoreIsValid)
+ {
+ //
+ // If the NextCoreIsValid flag is set, it means there are more cores to be
+ // dumped in the case of dumping all cores, so we can update the CoreId
+ // in the dump request structure to the next core number for the next
+ // iteration of dumping
+ //
+ LbrdumpRequest.CoreId++;
+ }
+ else
+ {
+ //
+ // If the NextCoreIsValid flag is not set, it means there are no more
+ // cores to be dumped in the case of dumping all cores, so we can break the loop
+ //
+ ContinueDumpingAllCores = FALSE;
+ }
+ }
+ else
+ {
+ ShowErrorMessage(LbrdumpRequest.KernelStatus);
+ break;
+ }
+ }
+ else
+ {
+ ShowMessages("failed to send LBR dump request\n");
+ break;
+ }
+ }
+}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pa2va.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pa2va.cpp
index fa88b64c..30a09ad7 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pa2va.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pa2va.cpp
@@ -14,6 +14,7 @@
//
// Global Variables
//
+extern BOOLEAN g_IsKdModuleLoaded;
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
@@ -163,7 +164,7 @@ CommandPa2va(vector CommandTokens, string Command)
}
else
{
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
if (Pid == 0)
{
diff --git a/hyperdbg/libhyperdbg/pcicam.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pcicam.cpp
similarity index 97%
rename from hyperdbg/libhyperdbg/pcicam.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pcicam.cpp
index d3a0a493..31c520cb 100644
--- a/hyperdbg/libhyperdbg/pcicam.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pcicam.cpp
@@ -1,6 +1,6 @@
/**
* @file pcicam.cpp
- * @author Bjrn Ruytenberg (bjorn@bjornweb.nl)
+ * @author Bj�rn Ruytenberg (bjorn@bjornweb.nl)
* @brief !pcicam command
* @details
* @version 0.13
@@ -14,6 +14,7 @@
//
// Global Variables
//
+extern BOOLEAN g_IsKdModuleLoaded;
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
/**
@@ -52,7 +53,7 @@ CommandPcicam(vector CommandTokens, string Command)
UINT32 TargetDevice = 0;
UINT32 TargetFunction = 0;
- const char * PciHeaderTypes[] = {"Endpoint", "PCI-to-PCI Bridge", "PCI-to-CardBus Bridge"};
+ const CHAR * PciHeaderTypes[] = {"Endpoint", "PCI-to-PCI Bridge", "PCI-to-CardBus Bridge"};
if (CommandTokens.size() < 4 || CommandTokens.size() > 5)
{
@@ -122,7 +123,7 @@ CommandPcicam(vector CommandTokens, string Command)
}
else
{
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
//
// Send IOCTL
@@ -150,8 +151,8 @@ CommandPcicam(vector CommandTokens, string Command)
//
// For some reason, MSVC refuses to initialize these at top of case
//
- const char * PciHeaderTypeAsString[] = {"Endpoint", "PCI-to-PCI Bridge", "PCI-to-CardBus Bridge"};
- const char * PciMmioBarTypeAsString[] = {"32-bit Wide",
+ const CHAR * PciHeaderTypeAsString[] = {"Endpoint", "PCI-to-PCI Bridge", "PCI-to-CardBus Bridge"};
+ const CHAR * PciMmioBarTypeAsString[] = {"32-bit Wide",
"Reserved",
"64-bit Wide",
"Reserved"};
@@ -345,7 +346,7 @@ CommandPcicam(vector CommandTokens, string Command)
//
for (UINT8 j = 0; j < 16; j++)
{
- char c = (char)*(cs + j);
+ CHAR c = (CHAR) * (cs + j);
if (c >= 32 && c <= 126)
{
ShowMessages("%c", c);
@@ -365,7 +366,7 @@ CommandPcicam(vector CommandTokens, string Command)
//
// An err occurred, no results
//
- ShowMessages("An err occured, no results:");
+ ShowMessages("An error occurred, no results:");
ShowErrorMessage(PcidevinfoPacket.KernelStatus);
}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pcitree.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pcitree.cpp
index ea7df659..4084e25c 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pcitree.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pcitree.cpp
@@ -1,6 +1,6 @@
/**
* @file pcitree.cpp
- * @author Bjrn Ruytenberg (bjorn@bjornweb.nl)
+ * @author Bj�rn Ruytenberg (bjorn@bjornweb.nl)
* @brief !pcitree command
* @details
* @version 0.10.3
@@ -14,6 +14,7 @@
//
// Global Variables
//
+extern BOOLEAN g_IsKdModuleLoaded;
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
/**
@@ -64,7 +65,7 @@ CommandPcitree(vector CommandTokens, string Command)
}
else
{
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
//
// Send IOCTL
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pt.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pt.cpp
new file mode 100644
index 00000000..09a96caf
--- /dev/null
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pt.cpp
@@ -0,0 +1,1610 @@
+/**
+ * @file pt.cpp
+ * @author Masoud Rahimi Jafari (Masoodrahimy1379@gmail.com)
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief !pt command
+ * @details
+ * @version 0.19
+ * @date 2026-04-29
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+//
+// Global Variables
+//
+extern BOOLEAN g_IsHyperTraceModuleLoaded;
+extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+
+/**
+ * @brief help of the !pt command
+ *
+ * @return VOID
+ */
+VOID
+CommandPtHelp()
+{
+ ShowMessages("!pt : enables, disables and configures Intel Processor Trace (PT).\n\n");
+
+ ShowMessages("syntax : \t!pt enable\n");
+ ShowMessages("syntax : \t!pt enable [size BufferSize (hex)]\n");
+ ShowMessages("syntax : \t!pt enable [pid ProcessId (hex)] [size BufferSize (hex)] [core CoreId (hex)]\n");
+ ShowMessages("syntax : \t!pt enable [tid ThreadId (hex)] [size BufferSize (hex)] [core CoreId (hex)]\n");
+ ShowMessages("syntax : \t!pt enable [pname ProcessName (string)] [size BufferSize (hex)] [core CoreId (hex)]\n");
+ ShowMessages("syntax : \t!pt enable [path Path (string)] [size BufferSize (hex)] [core CoreId (hex)]\n");
+ ShowMessages("syntax : \t!pt enable [cr3 Cr3Value (hex)] [size BufferSize (hex)]\n");
+ ShowMessages("syntax : \t!pt disable\n");
+ ShowMessages("syntax : \t!pt pause\n");
+ ShowMessages("syntax : \t!pt resume\n");
+ ShowMessages("syntax : \t!pt flush\n");
+ ShowMessages("syntax : \t!pt dump print [type TypeOfDump (string)]\n");
+ ShowMessages("syntax : \t!pt dump path [type TypeOfDump (string)]\n");
+ ShowMessages("syntax : \t!pt filter [Mode (string)]\n");
+ ShowMessages("syntax : \t!pt filter [range1 FromAddress (hex) ToAddress (hex)] [range2 FromAddress (hex) ToAddress (hex)] [range3 FromAddress (hex) ToAddress (hex)] [range4 FromAddress (hex) ToAddress (hex)]\n");
+ ShowMessages("syntax : \t!pt filter [range1 module ModuleName (string)] [range2 module ModuleName (string)] [range3 module ModuleName (string)] [range4 module ModuleName (string)]\n");
+ ShowMessages("syntax : \t!pt filter [stoprange1 FromAddress (hex) ToAddress (hex)] [stoprange2 FromAddress (hex) ToAddress (hex)] [stoprange3 FromAddress (hex) ToAddress (hex)] [stoprange4 FromAddress (hex) ToAddress (hex)]\n");
+ ShowMessages("syntax : \t!pt filter [stoprange1 module ModuleName (string)] [stoprange2 module ModuleName (string)] [stoprange3 module ModuleName (string)] [stoprange4 module ModuleName (string)]\n");
+ ShowMessages("syntax : \t!pt packet [PacketType (string)]\n");
+
+ ShowMessages("\n");
+ ShowMessages("\t\te.g : !pt enable\n");
+ ShowMessages("\t\te.g : !pt enable size 0x200000\n");
+ ShowMessages("\t\te.g : !pt enable pid 0x4a8\n");
+ ShowMessages("\t\te.g : !pt enable pname notepad.exe\n");
+ ShowMessages("\t\te.g : !pt enable tid 0x1234 core 3\n");
+ ShowMessages("\t\te.g : !pt enable cr3 0x1aabb000\n");
+ ShowMessages("\t\te.g : !pt enable pid 0x4a8 size 0x200000\n");
+ ShowMessages("\t\te.g : !pt enable path \"c:\\programs\\my exe file.exe\" size 0x200000 core 3\n");
+ ShowMessages("\t\te.g : !pt disable\n");
+ ShowMessages("\t\te.g : !pt pause\n");
+ ShowMessages("\t\te.g : !pt resume\n");
+ ShowMessages("\t\te.g : !pt flush\n");
+ ShowMessages("\t\te.g : !pt dump print type instruction\n");
+ ShowMessages("\t\te.g : !pt dump print type packet\n");
+ ShowMessages("\t\te.g : !pt dump path C:\\trace.txt type instruction\n");
+ ShowMessages("\t\te.g : !pt filter user\n");
+ ShowMessages("\t\te.g : !pt filter user kernel\n");
+ ShowMessages("\t\te.g : !pt filter range1 0x140001000 0x140002000\n");
+ ShowMessages("\t\te.g : !pt filter range1 module main\n");
+ ShowMessages("\t\te.g : !pt filter range1 module ntdll range2 module nt\n");
+ ShowMessages("\t\te.g : !pt filter stoprange1 0x140003000 0x140004000\n");
+ ShowMessages("\t\te.g : !pt packet psb pip tsc\n");
+
+ ShowMessages("\n");
+ ShowMessages("Where:\n");
+ ShowMessages("\t[Mode (string)] could be 'kernel' or/and 'user'\n");
+ ShowMessages("\t[TypeOfDump (string)] could be 'instruction' or 'packet'\n");
+ ShowMessages("\t[ModuleName (string)] could be 'main' (the main module of the process), 'nt', 'win32k', or any other module name\n");
+ ShowMessages("\t[PacketType (string)] could be either or a combination of 'psb', 'pip', 'tsc', 'mtc', 'cyc', 'tnt', 'tip', 'fup', or 'mode'\n");
+ ShowMessages("\n");
+}
+
+/**
+ * @brief Send PT requests
+ *
+ * @param PtRequest
+ *
+ * @return VOID
+ */
+BOOLEAN
+CommandPtSendRequest(HYPERTRACE_PT_OPERATION_PACKETS * PtRequest)
+{
+ BOOL Status;
+ ULONG ReturnedLength;
+
+ if (g_IsSerialConnectedToRemoteDebuggee)
+ {
+ //
+ // Send the request over serial kernel debugger
+ //
+ if (!KdSendHyperTracePtPacketsToDebuggee(PtRequest, SIZEOF_HYPERTRACE_PT_OPERATION_PACKETS))
+ {
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+ }
+ else
+ {
+ AssertShowMessageReturnStmt(g_IsHyperTraceModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_HYPERTRACE_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+
+ //
+ // Send IOCTL
+ //
+ Status = DeviceIoControl(
+ g_DeviceHandle, // Handle to device
+ IOCTL_PERFORM_HYPERTRACE_PT_OPERATION, // IO Control Code (IOCTL)
+ PtRequest, // Input Buffer to driver.
+ SIZEOF_HYPERTRACE_PT_OPERATION_PACKETS, // Input buffer length
+ PtRequest, // Output Buffer from driver.
+ SIZEOF_HYPERTRACE_PT_OPERATION_PACKETS, // Length of output buffer in bytes.
+ &ReturnedLength, // Bytes placed in buffer.
+ NULL // synchronous call
+ );
+
+ if (!Status)
+ {
+ ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
+
+ return FALSE;
+ }
+
+ if (PtRequest->KernelStatus == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+}
+
+/**
+ * @brief Request to perform an PT operation
+ *
+ * @param PtRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperDbgPerformPtOperation(HYPERTRACE_PT_OPERATION_PACKETS * PtRequest)
+{
+ return CommandPtSendRequest(PtRequest);
+}
+
+/**
+ * @brief Send pt enable command
+ *
+ * @return BOOLEAN
+ */
+static BOOLEAN
+CommandPtSendEnable()
+{
+ HYPERTRACE_PT_OPERATION_PACKETS PtRequest = {};
+
+ //
+ // Set the PtRequest structure for the operation
+ //
+ PtRequest.PtOperationType = HYPERTRACE_PT_OPERATION_REQUEST_TYPE_ENABLE;
+
+ //
+ // Send the request to perform the operation
+ //
+ if (!HyperDbgPerformPtOperation(&PtRequest))
+ {
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+/**
+ * @brief Send pt disable command
+ *
+ * @return BOOLEAN
+ */
+static BOOLEAN
+CommandPtSendDisable()
+{
+ HYPERTRACE_PT_OPERATION_PACKETS PtRequest = {};
+
+ //
+ // Set the PtRequest structure for the operation
+ //
+ PtRequest.PtOperationType = HYPERTRACE_PT_OPERATION_REQUEST_TYPE_DISABLE;
+
+ //
+ // Send the request to perform the operation
+ //
+ if (!HyperDbgPerformPtOperation(&PtRequest))
+ {
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+/**
+ * @brief Send pt pause command
+ *
+ * @return BOOLEAN
+ */
+static BOOLEAN
+CommandPtSendPause()
+{
+ HYPERTRACE_PT_OPERATION_PACKETS PtRequest = {};
+
+ //
+ // Set the PtRequest structure for the operation
+ //
+ PtRequest.PtOperationType = HYPERTRACE_PT_OPERATION_REQUEST_TYPE_PAUSE;
+
+ //
+ // Send the request to perform the operation
+ //
+ if (!HyperDbgPerformPtOperation(&PtRequest))
+ {
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+/**
+ * @brief Send pt resume command
+ *
+ * @return BOOLEAN
+ */
+static BOOLEAN
+CommandPtSendResume()
+{
+ HYPERTRACE_PT_OPERATION_PACKETS PtRequest = {};
+
+ //
+ // Set the PtRequest structure for the operation
+ //
+ PtRequest.PtOperationType = HYPERTRACE_PT_OPERATION_REQUEST_TYPE_RESUME;
+
+ //
+ // Send the request to perform the operation
+ //
+ if (!HyperDbgPerformPtOperation(&PtRequest))
+ {
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+/**
+ * @brief Send pt flush command
+ *
+ * @return BOOLEAN
+ */
+static BOOLEAN
+CommandPtSendFlush()
+{
+ HYPERTRACE_PT_OPERATION_PACKETS PtRequest = {};
+
+ //
+ // Set the PtRequest structure for the operation
+ //
+ PtRequest.PtOperationType = HYPERTRACE_PT_OPERATION_REQUEST_TYPE_FLUSH;
+
+ //
+ // Send the request to perform the operation
+ //
+ if (!HyperDbgPerformPtOperation(&PtRequest))
+ {
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+/**
+ * @brief Send pt filter command
+ *
+ * @return BOOLEAN
+ */
+static BOOLEAN
+CommandPtSendFilterByPid(UINT32 ProcessId,
+ BOOLEAN IsUserMode,
+ BOOLEAN IsKernelMode,
+ UINT64 StartRange1,
+ UINT64 EndRange1,
+ UINT64 StartRange2,
+ UINT64 EndRange2,
+ UINT64 StartRange3,
+ UINT64 EndRange3,
+ UINT64 StartRange4,
+ UINT64 EndRange4)
+{
+ HYPERTRACE_PT_OPERATION_PACKETS Op = {};
+ UINT8 NumberOfRanges = 0;
+
+ //
+ // Set the Op structure for the operation
+ //
+ Op.PtOperationType = HYPERTRACE_PT_OPERATION_REQUEST_TYPE_FILTER;
+
+ //
+ // Set execution modes
+ //
+ Op.FilterOptions.TraceUser = IsUserMode ? 1 : 0;
+ Op.FilterOptions.TraceKernel = IsKernelMode ? 1 : 0;
+
+ //
+ // Set the process ID
+ //
+ Op.EnableOptions.Pid = ProcessId;
+
+ //
+ // Set the first range if provided
+ //
+ if (StartRange1 != NULL && EndRange1 != NULL)
+ {
+ Op.FilterOptions.AddrRanges[NumberOfRanges].Start = StartRange1;
+ Op.FilterOptions.AddrRanges[NumberOfRanges].End = EndRange1;
+ NumberOfRanges++;
+ }
+
+ //
+ // Set the second range if provided
+ //
+ if (StartRange2 != NULL && EndRange2 != NULL)
+ {
+ Op.FilterOptions.AddrRanges[NumberOfRanges].Start = StartRange2;
+ Op.FilterOptions.AddrRanges[NumberOfRanges].End = EndRange2;
+ NumberOfRanges++;
+ }
+
+ //
+ // Set the third range if provided
+ //
+ if (StartRange3 != NULL && EndRange3 != NULL)
+ {
+ Op.FilterOptions.AddrRanges[NumberOfRanges].Start = StartRange3;
+ Op.FilterOptions.AddrRanges[NumberOfRanges].End = EndRange3;
+ NumberOfRanges++;
+ }
+
+ //
+ // Set the fourth range if provided
+ //
+ if (StartRange4 != NULL && EndRange4 != NULL)
+ {
+ Op.FilterOptions.AddrRanges[NumberOfRanges].Start = StartRange4;
+ Op.FilterOptions.AddrRanges[NumberOfRanges].End = EndRange4;
+ NumberOfRanges++;
+ }
+
+ //
+ // Set number of ranges
+ //
+ Op.FilterOptions.NumAddrRanges = NumberOfRanges;
+
+ //
+ // Send the request to perform the operation
+ //
+ if (!HyperDbgPerformPtOperation(&Op))
+ {
+ return FALSE;
+ }
+ else
+ {
+ ShowMessages("[+] PT Filter: cr3=0x%llx, pid=0x%x, user=%x, kernel=%x, ranges=%x\n",
+ Op.EnableOptions.Cr3,
+ Op.EnableOptions.Pid,
+ Op.FilterOptions.TraceUser,
+ Op.FilterOptions.TraceKernel,
+ Op.FilterOptions.NumAddrRanges);
+
+ return TRUE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Shared core: enable PT, wait for the target, decode and disable
+ *
+ * @details Called by the three specialised helpers after they have filled
+ * Process with a valid hProcess (and optionally hThread).
+ * Owns and closes all handles in Process before returning.
+ *
+ * @param Process Pointer to a PROCESS_INFORMATION whose hProcess (and
+ * optionally hThread) have already been opened/created
+ * @param Path Executable path used for symbol resolution, or NULL
+ * @param Function Symbol name to narrow the IP filter, or NULL
+ * @param Packets TRUE → decode raw packets; FALSE → decode instructions
+ * @param PinCore ≥ 0 → pin the target to that logical core; < 0 → free
+ * @param LaunchedNew TRUE → process was launched suspended here (will be
+ * resumed, and terminated on error); FALSE → the
+ * process was already running (never terminated)
+ *
+ * @return VOID
+ */
+static VOID
+CommandPtRunAndTraceCore(PROCESS_INFORMATION * Process,
+ const CHAR * Path,
+ const CHAR * Function,
+ BOOLEAN Packets,
+ int PinCore,
+ BOOLEAN LaunchedNew)
+{
+ DWORD_PTR Mask;
+ HYPERTRACE_PT_MMAP_PACKETS Mmap = {};
+ HYPERTRACE_PT_OPERATION_PACKETS Sizes = {};
+ IMAGE_SYMBOL_CONTEXT Ctx = {};
+ UINT64 TextStart = 0;
+ UINT64 TextEnd = 0;
+ UINT64 FilterStart = 0;
+ UINT64 FilterEnd = 0;
+ UINT64 Total = 0;
+
+ if (PinCore < 0)
+ {
+ PinCore = PT_DEFAULT_PINNING_CORE;
+ }
+
+ Mask = (DWORD_PTR)1 << PinCore;
+
+ //
+ // Set process affinity to the specified core so that all PT trace will land on that core
+ //
+ if (SetProcessAffinityMask(Process->hProcess, Mask))
+ {
+ ShowMessages("[+] pinned target to core %d (all trace should land on this core)\n", PinCore);
+ }
+ else
+ {
+ ShowMessages("[!] could not pin to core %d (error 0x%x); running unpinned\n", PinCore, GetLastError());
+ }
+
+ //
+ // Capture the .text section of the target process image for symbol resolution
+ //
+ if (!PtHelperCaptureImage(Process->hProcess, &TextStart, &TextEnd, &Ctx))
+ {
+ ShowMessages("[-] cannot read target image / .text section\n");
+
+ if (LaunchedNew)
+ TerminateProcess(Process->hProcess, 1);
+
+ goto Cleanup;
+ }
+
+ ShowMessages("[+] image base 0x%llx, .text 0x%llx-0x%llx (%llu bytes)\n",
+ (UINT64)Ctx.ImageBase,
+ (UINT64)TextStart,
+ (UINT64)TextEnd,
+ (UINT64)Ctx.CodeSize);
+
+ FilterStart = TextStart;
+ FilterEnd = TextEnd;
+
+ //
+ // Narrow the IP filter to the specified function if possible
+ //
+ if (Function != NULL && Path != NULL &&
+ PtHelperResolveFunction(Process->hProcess, Path, Function, Ctx.ImageBase, &FilterStart, &FilterEnd))
+ {
+ ShowMessages("[+] IP filter narrowed to '%s' 0x%llx-0x%llx (%llu bytes)\n",
+ Function,
+ (UINT64)FilterStart,
+ (UINT64)FilterEnd,
+ (UINT64)(FilterEnd - FilterStart + 1));
+ }
+ else
+ {
+ ShowMessages("[!] IP filter: whole .text (symbol '%s' not found or not applicable)\n",
+ Function ? Function : "(none)");
+ }
+
+ //
+ // Enable PT with the specified filter and wait for the target process to exit
+ //
+ if (!CommandPtSendFilterByPid(Process->dwProcessId, TRUE, FALSE, FilterStart, FilterEnd, NULL, NULL, NULL, NULL, NULL, NULL) ||
+ !CommandPtSendEnable())
+ {
+ ShowMessages("[-] cannot enable Intel PT\n");
+
+ if (LaunchedNew)
+ {
+ TerminateProcess(Process->hProcess, 1);
+ }
+
+ goto Cleanup;
+ }
+
+ //
+ // Request the PT buffers to be mapped into user space so that we can decode them after the target exits
+ //
+ if (!HyperDbgPtMmapSendRequest(&Mmap))
+ {
+ ShowMessages("[-] MMAP failed\n");
+ CommandPtSendDisable();
+ if (LaunchedNew)
+ TerminateProcess(Process->hProcess, 1);
+ goto Cleanup;
+ }
+
+ ShowMessages("[+] PT enabled, %u per-core buffers mapped\n", Mmap.NumCpus);
+
+ if (LaunchedNew)
+ {
+ ShowMessages("[*] resuming target and waiting for it to exit...\n");
+ ResumeThread(Process->hThread);
+ }
+ else
+ {
+ ShowMessages("[*] waiting for target process to exit...\n");
+ }
+
+ //
+ // Wait for the target process to exit before decoding the trace
+ //
+ WaitForSingleObject(Process->hProcess, INFINITE);
+
+ ShowMessages("[+] target exited, decoding trace\n");
+
+ //
+ // Pause PT so that the buffers are not being written to while we decode them
+ //
+ CommandPtSendPause();
+
+ Sizes.PtOperationType = HYPERTRACE_PT_OPERATION_REQUEST_TYPE_SIZE;
+
+ //
+ // Request the sizes of the PT buffers for each core so that we know how much to decode
+ //
+ if (!CommandPtSendRequest(&Sizes))
+ {
+ ShowMessages("[-] cannot query PT sizes\n");
+ CommandPtSendDisable();
+ goto Cleanup;
+ }
+
+ //
+ // Decode the trace for each core that has a non-zero buffer size
+ //
+ for (UINT32 i = 0; i < Mmap.NumCpus; i++)
+ {
+ UINT32 Cpu = Mmap.Cpus[i].CpuId;
+ UINT64 Bytes = (Cpu < Sizes.NumCpus) ? Sizes.BytesPerCpu[Cpu] : 0;
+
+ if (Bytes == 0)
+ continue;
+
+ if (Bytes > Mmap.Cpus[i].Size)
+ Bytes = Mmap.Cpus[i].Size;
+
+ ShowMessages("\n[*] core %u: %llu bytes of trace\n", Cpu, (UINT64)Bytes);
+ Total += Packets
+ ? PtHelperDecodeCorePackets(Cpu, (const UINT8 *)(ULONG_PTR)Mmap.Cpus[i].UserVa, Bytes, Ctx.ImageBase)
+ : PtHelperDecodeCore(Cpu, (const UINT8 *)(ULONG_PTR)Mmap.Cpus[i].UserVa, Bytes, &Ctx);
+ }
+
+ ShowMessages("\n[+] decoded %llu %s total\n", (UINT64)Total, Packets ? "packet(s)" : "instruction(s)");
+
+ //
+ // Disable PT now that we are done decoding the trace
+ //
+ CommandPtSendDisable();
+
+Cleanup:
+
+ if (Ctx.Code != NULL)
+ {
+ free(Ctx.Code);
+ Ctx.Code = NULL;
+ }
+
+ if (Process->hThread != NULL)
+ CloseHandle(Process->hThread);
+ if (Process->hProcess != NULL)
+ CloseHandle(Process->hProcess);
+}
+
+/**
+ * @brief Launch an executable at Path as a suspended process, enable PT, and
+ * decode the trace after the process exits
+ *
+ * @param Path Full path to the executable to launch
+ * @param Function Symbol name to narrow the IP filter, or NULL for whole .text
+ * @param Packets TRUE → decode raw packets; FALSE → decode instructions
+ * @param PinCore ≥ 0 → pin to that logical core; < 0 → unpinned
+ *
+ * @return VOID
+ */
+static VOID
+CommandPtRunAndTraceByPath(const CHAR * Path, const CHAR * Function, BOOLEAN Packets, int PinCore)
+{
+ STARTUPINFOA Startup = {};
+ PROCESS_INFORMATION Process = {};
+
+ Startup.cb = sizeof(Startup);
+
+ if (!CreateProcessA(Path, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &Startup, &Process))
+ {
+ ShowMessages("[-] cannot launch '%s' (error 0x%x)\n", Path, GetLastError());
+ return;
+ }
+
+ ShowMessages("[+] launched '%s' (pid %u, suspended)\n", Path, Process.dwProcessId);
+
+ CommandPtRunAndTraceCore(&Process, Path, Function, Packets, PinCore, TRUE);
+}
+
+/**
+ * @brief Open an existing process by PID, enable PT, and decode the trace
+ * after the process exits
+ *
+ * @param ProcessId PID of the target process
+ * @param Function Symbol name to narrow the IP filter, or NULL for whole .text
+ * @param Packets TRUE → decode raw packets; FALSE → decode instructions
+ * @param PinCore ≥ 0 → pin to that logical core; < 0 → unpinned
+ *
+ * @return VOID
+ */
+static VOID
+CommandPtRunAndTraceByPid(UINT32 ProcessId, const CHAR * Function, BOOLEAN Packets, int PinCore)
+{
+ PROCESS_INFORMATION Process = {};
+
+ Process.hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)ProcessId);
+
+ if (Process.hProcess == NULL)
+ {
+ ShowMessages("[-] cannot open process 0x%x (error 0x%x)\n", ProcessId, GetLastError());
+ return;
+ }
+
+ Process.dwProcessId = ProcessId;
+
+ ShowMessages("[+] attached to pid 0x%x\n", ProcessId);
+
+ CommandPtRunAndTraceCore(&Process, NULL, Function, Packets, PinCore, FALSE);
+}
+
+/**
+ * @brief Open an existing thread by TID, derive its owning process, enable PT,
+ * and decode the trace after the process exits
+ *
+ * @param ThreadId TID of the target thread
+ * @param Function Symbol name to narrow the IP filter, or NULL for whole .text
+ * @param Packets TRUE → decode raw packets; FALSE → decode instructions
+ * @param PinCore ≥ 0 → pin to that logical core; < 0 → unpinned
+ *
+ * @return VOID
+ */
+static VOID
+CommandPtRunAndTraceByTid(UINT32 ThreadId, const CHAR * Function, BOOLEAN Packets, int PinCore)
+{
+ PROCESS_INFORMATION Process = {};
+ HANDLE ThreadHandle = NULL;
+ DWORD OwningPid = 0;
+ THREAD_BASIC_INFO_EX Tbi = {0};
+ ULONG RetTid = 0;
+ HMODULE NtdllTid = GetModuleHandleA("ntdll.dll");
+ PFN_NT_QIT NtQit = NtdllTid ? (PFN_NT_QIT)GetProcAddress(NtdllTid, "NtQueryInformationThread") : NULL;
+
+ ThreadHandle = OpenThread(THREAD_ALL_ACCESS, FALSE, (DWORD)ThreadId);
+
+ if (ThreadHandle == NULL)
+ {
+ ShowMessages("[-] cannot open thread 0x%x (error 0x%x)\n", ThreadId, GetLastError());
+ return;
+ }
+
+ if (NtQit == NULL || NtQit(ThreadHandle, 0, &Tbi, sizeof(Tbi), &RetTid) < 0 || Tbi.ClientId.UniqueProcess == NULL)
+ {
+ ShowMessages("[-] cannot get owning PID for thread 0x%x\n", ThreadId);
+ CloseHandle(ThreadHandle);
+ return;
+ }
+
+ OwningPid = (DWORD)(ULONG_PTR)Tbi.ClientId.UniqueProcess;
+
+ if (OwningPid == 0)
+ {
+ ShowMessages("[-] cannot get owning PID for thread 0x%x\n", ThreadId);
+ CloseHandle(ThreadHandle);
+ return;
+ }
+
+ Process.hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, OwningPid);
+
+ if (Process.hProcess == NULL)
+ {
+ ShowMessages("[-] cannot open process %u (error 0x%x)\n", OwningPid, GetLastError());
+ CloseHandle(ThreadHandle);
+ return;
+ }
+
+ Process.hThread = ThreadHandle;
+ Process.dwProcessId = OwningPid;
+ Process.dwThreadId = ThreadId;
+
+ ShowMessages("[+] attached to tid 0x%x (owning pid %u)\n", ThreadId, OwningPid);
+
+ CommandPtRunAndTraceCore(&Process, NULL, Function, Packets, PinCore, FALSE);
+}
+
+/**
+ * @brief Wrapper: dispatch to the appropriate trace helper based on whichever
+ * selector (Path, ProcessId, ThreadId) is provided
+ *
+ * @param Path Executable path, or NULL
+ * @param Function Symbol name for IP filter, or NULL
+ * @param Packets TRUE → raw packets; FALSE → instructions
+ * @param PinCore Logical core to pin the target to, or < 0 for unpinned
+ * @param ProcessId PID of an existing process, or 0
+ * @param ThreadId TID of an existing thread, or 0
+ *
+ * @return VOID
+ */
+static VOID
+CommandPtRunAndTrace(const CHAR * Path, const CHAR * Function, BOOLEAN Packets, int PinCore, UINT32 ProcessId, UINT32 ThreadId)
+{
+ if (Path != NULL)
+ CommandPtRunAndTraceByPath(Path, Function, Packets, PinCore);
+ else if (ThreadId != 0)
+ CommandPtRunAndTraceByTid(ThreadId, Function, Packets, PinCore);
+ else if (ProcessId != 0)
+ CommandPtRunAndTraceByPid(ProcessId, Function, Packets, PinCore);
+ else
+ ShowMessages("[-] no path, PID, or TID specified\n");
+}
+
+/**
+ * @brief Map the per-CPU PT output buffers into the current process
+ *
+ * @details On success MmapRequest->Cpus[0..NumCpus) hold one { UserVa, Size }
+ * per CPU, valid in this process until PT is disabled / flushed.
+ * Only meaningful in local (VMI) mode.
+ *
+ * @param MmapRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperDbgPtMmapSendRequest(HYPERTRACE_PT_MMAP_PACKETS * MmapRequest)
+{
+ BOOL Status;
+ ULONG ReturnedLength;
+
+ if (g_IsSerialConnectedToRemoteDebuggee)
+ {
+ //
+ // The mmap surface maps into the caller's address space, which only
+ // makes sense in local mode (no remote-debuggee transport for it).
+ //
+ ShowMessages("err, PT mmap is only available in local (VMI) mode\n");
+ return FALSE;
+ }
+
+ AssertShowMessageReturnStmt(g_IsHyperTraceModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_HYPERTRACE_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+
+ Status = DeviceIoControl(
+ g_DeviceHandle, // Handle to device
+ IOCTL_PERFORM_HYPERTRACE_PT_MMAP, // IO Control Code (IOCTL)
+ MmapRequest, // Input Buffer to driver.
+ SIZEOF_HYPERTRACE_PT_MMAP_PACKETS, // Input buffer length
+ MmapRequest, // Output Buffer from driver.
+ SIZEOF_HYPERTRACE_PT_MMAP_PACKETS, // Length of output buffer in bytes.
+ &ReturnedLength, // Bytes placed in buffer.
+ NULL // synchronous call
+ );
+
+ if (!Status)
+ {
+ ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
+ return FALSE;
+ }
+
+ return MmapRequest->KernelStatus == DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+}
+
+/**
+ * @brief Parse and display enable options for !pt enable command
+ *
+ * @param CommandTokens The command tokens to parse
+ * @param PtRequest The PT request structure to fill with parsed options
+ *
+ * @return VOID
+ */
+static VOID
+CommandPtParseEnable(vector & CommandTokens, HYPERTRACE_PT_OPERATION_PACKETS * PtRequest)
+{
+ BOOLEAN HasPid = FALSE;
+ BOOLEAN HasPname = FALSE;
+ BOOLEAN HasPath = FALSE;
+ BOOLEAN HasTid = FALSE;
+ BOOLEAN HasCr3 = FALSE;
+ BOOLEAN HasSize = FALSE;
+ BOOLEAN HasCore = FALSE;
+ UINT64 Pid = 0;
+ UINT64 Tid = 0;
+ UINT64 Cr3 = 0;
+ UINT64 Size = 0;
+ UINT32 Core = 0;
+ string Pname;
+ string Path;
+
+ for (SIZE_T i = 2; i < CommandTokens.size(); i++)
+ {
+ if (CompareLowerCaseStrings(CommandTokens.at(i), "pid"))
+ {
+ if (i + 1 >= CommandTokens.size())
+ {
+ ShowMessages("err, 'pid' expects a hex process ID\n\n");
+ CommandPtHelp();
+ return;
+ }
+ i++;
+ if (!ConvertTokenToUInt64(CommandTokens.at(i), &Pid))
+ {
+ ShowMessages("err, '%s' is not a valid hex process ID\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(i)).c_str());
+ CommandPtHelp();
+ return;
+ }
+ HasPid = TRUE;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "pname"))
+ {
+ if (i + 1 >= CommandTokens.size())
+ {
+ ShowMessages("err, 'pname' expects a process name\n\n");
+ CommandPtHelp();
+ return;
+ }
+ i++;
+ Pname = GetCaseSensitiveStringFromCommandToken(CommandTokens.at(i));
+ HasPname = TRUE;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "path"))
+ {
+ if (i + 1 >= CommandTokens.size())
+ {
+ ShowMessages("err, 'path' expects a process executable path\n\n");
+ CommandPtHelp();
+ return;
+ }
+ i++;
+ Path = GetCaseSensitiveStringFromCommandToken(CommandTokens.at(i));
+ HasPath = TRUE;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "tid"))
+ {
+ if (i + 1 >= CommandTokens.size())
+ {
+ ShowMessages("err, 'tid' expects a hex thread ID\n\n");
+ CommandPtHelp();
+ return;
+ }
+ i++;
+ if (!ConvertTokenToUInt64(CommandTokens.at(i), &Tid))
+ {
+ ShowMessages("err, '%s' is not a valid hex thread ID\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(i)).c_str());
+ CommandPtHelp();
+ return;
+ }
+ HasTid = TRUE;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "cr3"))
+ {
+ if (i + 1 >= CommandTokens.size())
+ {
+ ShowMessages("err, 'cr3' expects a hex CR3 value\n\n");
+ CommandPtHelp();
+ return;
+ }
+ i++;
+ if (!ConvertTokenToUInt64(CommandTokens.at(i), &Cr3))
+ {
+ ShowMessages("err, '%s' is not a valid hex CR3 value\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(i)).c_str());
+ CommandPtHelp();
+ return;
+ }
+ HasCr3 = TRUE;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "size"))
+ {
+ if (i + 1 >= CommandTokens.size())
+ {
+ ShowMessages("err, 'size' expects a hex buffer size\n\n");
+ CommandPtHelp();
+ return;
+ }
+ i++;
+ if (!ConvertTokenToUInt64(CommandTokens.at(i), &Size))
+ {
+ ShowMessages("err, '%s' is not a valid hex size\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(i)).c_str());
+ CommandPtHelp();
+ return;
+ }
+ HasSize = TRUE;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "core"))
+ {
+ if (i + 1 >= CommandTokens.size())
+ {
+ ShowMessages("err, 'core' expects a hex value as the core number\n\n");
+ CommandPtHelp();
+ return;
+ }
+ i++;
+ if (!ConvertTokenToUInt32(CommandTokens.at(i), &Core))
+ {
+ ShowMessages("err, '%s' is not a valid hex size\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(i)).c_str());
+ CommandPtHelp();
+ return;
+ }
+ HasCore = TRUE;
+ }
+ else
+ {
+ ShowMessages("err, unknown 'enable' option '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(i)).c_str());
+ CommandPtHelp();
+ return;
+ }
+ }
+
+ //
+ // pid, pname, tid, cr3 are mutually exclusive target selectors
+ //
+ INT32 SelectorCount = (HasPid ? 1 : 0) + (HasPname ? 1 : 0) + (HasPath ? 1 : 0) + (HasTid ? 1 : 0) + (HasCr3 ? 1 : 0);
+ if (SelectorCount > 1)
+ {
+ ShowMessages("err, only one of 'pid', 'pname', 'path', 'tid', 'cr3' may be specified at a time\n\n");
+ CommandPtHelp();
+ return;
+ }
+
+ //
+ // Show parsed enable options
+ //
+ ShowMessages("PT enable:\n");
+
+ if (HasPid)
+ {
+ ShowMessages(" target pid : 0x%llx\n", Pid);
+
+ PtRequest->EnableOptions.EnableByPid = 1;
+ PtRequest->EnableOptions.Pid = (UINT32)Pid;
+ }
+ else if (HasPname)
+ {
+ ShowMessages(" target pname : %s\n", Pname.c_str());
+
+ PtRequest->EnableOptions.EnableByCr3 = 1;
+ strcpy_s(PtRequest->EnableOptions.ProcessName, sizeof(PtRequest->EnableOptions.ProcessName), Pname.c_str());
+ }
+ else if (HasPath)
+ {
+ ShowMessages(" target path : %s\n", Path.c_str());
+
+ PtRequest->EnableOptions.EnableByPid = 1; // Path is resolved to a PID
+ }
+ else if (HasTid)
+ {
+ ShowMessages(" target tid : 0x%llx\n", Tid);
+
+ PtRequest->EnableOptions.EnableByTid = 1;
+ PtRequest->EnableOptions.Tid = (UINT32)Tid;
+ }
+ else if (HasCr3)
+ {
+ ShowMessages(" target cr3 : 0x%llx\n", Cr3);
+
+ PtRequest->EnableOptions.EnableByCr3 = 1;
+ PtRequest->EnableOptions.Cr3 = Cr3;
+ }
+ else
+ {
+ ShowMessages(" target : all (no process/thread filter)\n");
+ }
+
+ //
+ // Check for size options
+ //
+ if (HasSize)
+ {
+ ShowMessages(" buffer size : 0x%llx bytes\n", Size);
+
+ PtRequest->BufferSize = Size;
+ }
+ else
+ {
+ ShowMessages(" buffer size : default (%llx bytes)\n", PT_DEFAULT_BUFFER_SIZE);
+
+ PtRequest->BufferSize = PT_DEFAULT_BUFFER_SIZE;
+ }
+
+ //
+ // Check for core options
+ //
+ if (HasCore)
+ {
+ ShowMessages(" core : 0x%x\n", Core);
+ PtRequest->CoreId = Core;
+ }
+ else
+ {
+ ShowMessages(" core : default (0x%x)\n", PT_DEFAULT_PINNING_CORE);
+ PtRequest->CoreId = PT_DEFAULT_PINNING_CORE;
+ }
+
+ //
+ // Fill the PtRequest structure with parsed options
+ //
+ PtRequest->PtOperationType = HYPERTRACE_PT_OPERATION_REQUEST_TYPE_ENABLE;
+
+ //
+ // Temporary workaround for testing:
+ // If a path, PID, or TID is specified, invoke CommandPtRunAndTrace directly
+ // to launch/attach and decode the trace in one step.
+ // TODO: Should be removed once the kernel-side enable/filter path is complete.
+ //
+ if (HasPath)
+ {
+ ShowMessages(" Running '%s' on core: %llx\n", Path.c_str(), PtRequest->CoreId);
+ CommandPtRunAndTrace(Path.c_str(), NULL, FALSE, PtRequest->CoreId, 0, 0);
+ }
+ else if (HasPid)
+ {
+ ShowMessages(" Tracing pid 0x%llx on core: %llx\n", Pid, PtRequest->CoreId);
+ CommandPtRunAndTrace(NULL, NULL, FALSE, PtRequest->CoreId, (UINT32)Pid, 0);
+ }
+ else if (HasTid)
+ {
+ ShowMessages(" Tracing tid 0x%llx on core: %llx\n", Tid, PtRequest->CoreId);
+ CommandPtRunAndTrace(NULL, NULL, FALSE, PtRequest->CoreId, 0, (UINT32)Tid);
+ }
+}
+
+/**
+ * @brief Parse and display !pt dump parameters
+ *
+ * @param CommandTokens The command tokens to parse
+ * @param PtRequest The PT request structure to fill with parsed options
+ *
+ * @return VOID
+ */
+static VOID
+CommandPtParseDump(vector & CommandTokens, HYPERTRACE_PT_OPERATION_PACKETS * PtRequest)
+{
+ if (CommandTokens.size() < 3)
+ {
+ ShowMessages("err, 'dump' requires additional options\n\n");
+ CommandPtHelp();
+ return;
+ }
+
+ if (CompareLowerCaseStrings(CommandTokens.at(2), "print"))
+ {
+ //
+ // !pt dump print type
+ //
+ if (CommandTokens.size() != 5 || !CompareLowerCaseStrings(CommandTokens.at(3), "type"))
+ {
+ ShowMessages("err, syntax: !pt dump print type \n\n");
+ CommandPtHelp();
+ return;
+ }
+
+ if (!CompareLowerCaseStrings(CommandTokens.at(4), "instruction") &&
+ !CompareLowerCaseStrings(CommandTokens.at(4), "packet"))
+ {
+ ShowMessages("err, dump type must be 'instruction' or 'packet', got '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(4)).c_str());
+ CommandPtHelp();
+ return;
+ }
+
+ ShowMessages("PT dump to console:\n");
+ ShowMessages(" output : console (print)\n");
+ ShowMessages(" format : %s\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(4)).c_str());
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(2), "path"))
+ {
+ //
+ // !pt dump path type
+ //
+ if (CommandTokens.size() != 6 || !CompareLowerCaseStrings(CommandTokens.at(4), "type"))
+ {
+ ShowMessages("err, syntax: !pt dump path type \n\n");
+ CommandPtHelp();
+ return;
+ }
+
+ if (!CompareLowerCaseStrings(CommandTokens.at(5), "instruction") &&
+ !CompareLowerCaseStrings(CommandTokens.at(5), "packet"))
+ {
+ ShowMessages("err, dump type must be 'instruction' or 'packet', got '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(5)).c_str());
+ CommandPtHelp();
+ return;
+ }
+
+ ShowMessages("PT dump to file:\n");
+ ShowMessages(" output : file\n");
+ ShowMessages(" path : %s\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(3)).c_str());
+ ShowMessages(" format : %s\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(5)).c_str());
+ }
+ else
+ {
+ ShowMessages("err, unknown 'dump' sub-option '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2)).c_str());
+ CommandPtHelp();
+ }
+}
+
+/**
+ * @brief Parse and display !pt filter parameters
+ *
+ * @param CommandTokens The command tokens to parse
+ * @param PtRequest The PT request structure to fill with parsed options
+ *
+ * @return VOID
+ */
+static VOID
+CommandPtParseFilter(vector & CommandTokens, HYPERTRACE_PT_OPERATION_PACKETS * PtRequest)
+{
+ struct PtRangeEntry
+ {
+ BOOLEAN Active;
+ BOOLEAN IsModule;
+ UINT64 Start;
+ UINT64 End;
+ string ModuleName;
+ };
+
+ PtRangeEntry Ranges[4] = {};
+ PtRangeEntry StopRanges[4] = {};
+ BOOLEAN TraceUser = FALSE;
+ BOOLEAN TraceKernel = FALSE;
+
+ for (SIZE_T i = 2; i < CommandTokens.size(); i++)
+ {
+ if (CompareLowerCaseStrings(CommandTokens.at(i), "user"))
+ {
+ TraceUser = TRUE;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "kernel"))
+ {
+ TraceKernel = TRUE;
+ }
+ else
+ {
+ //
+ // Resolve range1..range4 / stoprange1..stoprange4
+ //
+ BOOLEAN IsStop = FALSE;
+ INT32 RangeIdx = -1;
+
+ if (CompareLowerCaseStrings(CommandTokens.at(i), "range1"))
+ {
+ IsStop = FALSE;
+ RangeIdx = 0;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "range2"))
+ {
+ IsStop = FALSE;
+ RangeIdx = 1;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "range3"))
+ {
+ IsStop = FALSE;
+ RangeIdx = 2;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "range4"))
+ {
+ IsStop = FALSE;
+ RangeIdx = 3;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "stoprange1"))
+ {
+ IsStop = TRUE;
+ RangeIdx = 0;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "stoprange2"))
+ {
+ IsStop = TRUE;
+ RangeIdx = 1;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "stoprange3"))
+ {
+ IsStop = TRUE;
+ RangeIdx = 2;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "stoprange4"))
+ {
+ IsStop = TRUE;
+ RangeIdx = 3;
+ }
+ else
+ {
+ ShowMessages("err, unknown filter option '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(i)).c_str());
+ CommandPtHelp();
+ return;
+ }
+
+ PtRangeEntry * Entry = IsStop ? &StopRanges[RangeIdx] : &Ranges[RangeIdx];
+
+ if (i + 1 >= CommandTokens.size())
+ {
+ ShowMessages("err, '%s' expects or 'module '\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(i)).c_str());
+ CommandPtHelp();
+ return;
+ }
+
+ if (CompareLowerCaseStrings(CommandTokens.at(i + 1), "module"))
+ {
+ //
+ // range module
+ //
+ if (i + 2 >= CommandTokens.size())
+ {
+ ShowMessages("err, 'module' expects a module name\n\n");
+ CommandPtHelp();
+ return;
+ }
+ i += 2;
+ Entry->IsModule = TRUE;
+ Entry->ModuleName = GetCaseSensitiveStringFromCommandToken(CommandTokens.at(i));
+ Entry->Active = TRUE;
+ }
+ else
+ {
+ //
+ // range
+ //
+ if (i + 2 >= CommandTokens.size())
+ {
+ ShowMessages("err, '%s' expects \n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(i)).c_str());
+ CommandPtHelp();
+ return;
+ }
+ i++;
+ if (!ConvertTokenToUInt64(CommandTokens.at(i), &Entry->Start))
+ {
+ ShowMessages("err, '%s' is not a valid address\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(i)).c_str());
+ CommandPtHelp();
+ return;
+ }
+ i++;
+ if (!ConvertTokenToUInt64(CommandTokens.at(i), &Entry->End))
+ {
+ ShowMessages("err, '%s' is not a valid address\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(i)).c_str());
+ CommandPtHelp();
+ return;
+ }
+ Entry->IsModule = FALSE;
+ Entry->Active = TRUE;
+ }
+ }
+ }
+
+ //
+ // Show parsed filter options
+ //
+ ShowMessages("PT filter:\n");
+
+ if (TraceUser)
+ {
+ ShowMessages(" privilege : user (CPL > 0)\n");
+
+ PtRequest->FilterOptions.TraceUser = 1;
+ }
+ if (TraceKernel)
+ {
+ ShowMessages(" privilege : kernel (CPL == 0)\n");
+
+ PtRequest->FilterOptions.TraceKernel = 1;
+ }
+ if (!TraceUser && !TraceKernel)
+ {
+ ShowMessages(" privilege : (default - user + kernel)\n");
+
+ PtRequest->FilterOptions.TraceUser = 1;
+ PtRequest->FilterOptions.TraceKernel = 1;
+ }
+
+ for (INT32 r = 0; r < 4; r++)
+ {
+ if (Ranges[r].Active)
+ {
+ if (Ranges[r].IsModule)
+ ShowMessages(" range%d : module '%s'\n", r + 1, Ranges[r].ModuleName.c_str());
+ else
+ ShowMessages(" range%d : 0x%llx - 0x%llx\n", r + 1, Ranges[r].Start, Ranges[r].End);
+ }
+
+ //
+ // Set the PtRequest structure for filter operation
+ //
+ PtRequest->FilterOptions.AddrRanges[r].IsStopRange = FALSE;
+
+ PtRequest->FilterOptions.AddrRanges[r].Start = Ranges[r].Start;
+ PtRequest->FilterOptions.AddrRanges[r].End = Ranges[r].End;
+ }
+
+ for (INT32 r = 0; r < 4; r++)
+ {
+ if (StopRanges[r].Active)
+ {
+ if (StopRanges[r].IsModule)
+ ShowMessages(" stoprange%d : module '%s'\n", r + 1, StopRanges[r].ModuleName.c_str());
+ else
+ ShowMessages(" stoprange%d : 0x%llx - 0x%llx\n", r + 1, StopRanges[r].Start, StopRanges[r].End);
+ }
+
+ //
+ // Set the PtRequest structure for filter operation
+ //
+ PtRequest->FilterOptions.AddrRanges[r].IsStopRange = TRUE;
+
+ PtRequest->FilterOptions.AddrRanges[r].Start = Ranges[r].Start;
+ PtRequest->FilterOptions.AddrRanges[r].End = Ranges[r].End;
+ }
+
+ //
+ // Set the PtRequest structure for filter operation
+ //
+ PtRequest->PtOperationType = HYPERTRACE_PT_OPERATION_REQUEST_TYPE_FILTER;
+}
+
+/**
+ * @brief Parse and display !pt packet parameters
+ * @param CommandTokens The command tokens to parse
+ * @param PtRequest The PT request structure to fill with parsed options
+ *
+ * @return VOID
+ */
+static VOID
+CommandPtParsePacket(vector & CommandTokens, HYPERTRACE_PT_OPERATION_PACKETS * PtRequest)
+{
+ if (CommandTokens.size() < 3)
+ {
+ ShowMessages("err, 'packet' requires at least one option\n\n");
+ CommandPtHelp();
+ return;
+ }
+
+ BOOLEAN PktPsb = FALSE;
+ BOOLEAN PktPip = FALSE;
+ BOOLEAN PktTsc = FALSE;
+ BOOLEAN PktMtc = FALSE;
+ BOOLEAN PktCyc = FALSE;
+ BOOLEAN PktTnt = FALSE;
+ BOOLEAN PktTip = FALSE;
+ BOOLEAN PktFup = FALSE;
+ BOOLEAN PktMode = FALSE;
+
+ for (SIZE_T i = 2; i < CommandTokens.size(); i++)
+ {
+ if (CompareLowerCaseStrings(CommandTokens.at(i), "psb"))
+ PktPsb = TRUE;
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "pip"))
+ PktPip = TRUE;
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "tsc"))
+ PktTsc = TRUE;
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "mtc"))
+ PktMtc = TRUE;
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "cyc"))
+ PktCyc = TRUE;
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "tnt"))
+ PktTnt = TRUE;
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "tip"))
+ PktTip = TRUE;
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "fup"))
+ PktFup = TRUE;
+ else if (CompareLowerCaseStrings(CommandTokens.at(i), "mode"))
+ PktMode = TRUE;
+ else
+ {
+ ShowMessages("err, unknown 'packet' option '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(i)).c_str());
+ CommandPtHelp();
+ return;
+ }
+ }
+
+ //
+ // Show parsed packet options
+ //
+ ShowMessages("PT packet filter:\n");
+
+ if (PktPsb)
+ {
+ ShowMessages(" packet type: PSB (Packet Stream Boundary)\n");
+
+ PtRequest->PacketOptions.PSB = 1;
+ }
+ if (PktPip)
+ {
+ ShowMessages(" packet type: PIP (Paging Information Packet)\n");
+
+ PtRequest->PacketOptions.PIP = 1;
+ }
+ if (PktTsc)
+ {
+ ShowMessages(" packet type: TSC (Timestamp Counter)\n");
+
+ PtRequest->PacketOptions.TSC = 1;
+ }
+ if (PktMtc)
+ {
+ ShowMessages(" packet type: MTC (Mini Timestamp Counter)\n");
+
+ PtRequest->PacketOptions.MTC = 1;
+ }
+ if (PktCyc)
+ {
+ ShowMessages(" packet type: CYC (Cycle Counter)\n");
+
+ PtRequest->PacketOptions.CYC = 1;
+ }
+ if (PktTnt)
+ {
+ ShowMessages(" packet type: TNT (Taken/Not-Taken)\n");
+
+ PtRequest->PacketOptions.TNT = 1;
+ }
+ if (PktTip)
+ {
+ ShowMessages(" packet type: TIP (Target IP)\n");
+
+ PtRequest->PacketOptions.TNT = 1;
+ }
+ if (PktFup)
+ {
+ ShowMessages(" packet type: FUP (Flow Update Packet)\n");
+
+ PtRequest->PacketOptions.FUP = 1;
+ }
+ if (PktMode)
+ {
+ ShowMessages(" packet type: MODE (Mode packet)\n");
+
+ PtRequest->PacketOptions.MODE = 1;
+ }
+
+ //
+ // Set the PtRequest structure for packet operation
+ //
+ PtRequest->PtOperationType = HYPERTRACE_PT_OPERATION_REQUEST_TYPE_PACKET;
+}
+
+/**
+ * @brief !pt command handler
+ *
+ * @param CommandTokens
+ * @param Command
+ *
+ * @return VOID
+ */
+VOID
+CommandPt(vector CommandTokens, string Command)
+{
+ HYPERTRACE_PT_OPERATION_PACKETS PtRequest = {};
+
+ if (CommandTokens.size() == 1)
+ {
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
+ CommandPtHelp();
+ return;
+ }
+
+ //
+ // Parse subcommands
+ //
+ if (CompareLowerCaseStrings(CommandTokens.at(1), "enable"))
+ {
+ //
+ // Parse and display enable options for !pt enable command
+ //
+ CommandPtParseEnable(CommandTokens, &PtRequest);
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(1), "disable"))
+ {
+ if (CommandTokens.size() != 2)
+ {
+ ShowMessages("err, 'disable' takes no arguments\n\n");
+ CommandPtHelp();
+ return;
+ }
+
+ //
+ // Parse and display disable options for !pt disable command
+ //
+ CommandPtSendDisable();
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(1), "pause"))
+ {
+ if (CommandTokens.size() != 2)
+ {
+ ShowMessages("err, 'pause' takes no arguments\n\n");
+ CommandPtHelp();
+ return;
+ }
+
+ //
+ // Parse and display pause options for !pt pause command
+ //
+ CommandPtSendPause();
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(1), "resume"))
+ {
+ if (CommandTokens.size() != 2)
+ {
+ ShowMessages("err, 'resume' takes no arguments\n\n");
+ CommandPtHelp();
+ return;
+ }
+
+ //
+ // Parse and display resume options for !pt resume command
+ //
+ CommandPtSendResume();
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(1), "flush"))
+ {
+ if (CommandTokens.size() != 2)
+ {
+ ShowMessages("err, 'flush' takes no arguments\n\n");
+ CommandPtHelp();
+ return;
+ }
+
+ //
+ // Parse and display flush options for !pt flush command
+ //
+ CommandPtSendFlush();
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(1), "dump"))
+ {
+ //
+ // Parse and display dump options for !pt dump command
+ //
+ CommandPtParseDump(CommandTokens, &PtRequest);
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(1), "filter"))
+ {
+ //
+ // Parse and display filter options for !pt filter command
+ //
+ CommandPtParseFilter(CommandTokens, &PtRequest);
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(1), "packet"))
+ {
+ //
+ // Parse and display packet options for !pt packet command
+ //
+ CommandPtParsePacket(CommandTokens, &PtRequest);
+ }
+ else
+ {
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
+ CommandPtHelp();
+ }
+
+ //
+ // Send the PT request to the debugger
+ //
+ CommandPtSendRequest(&PtRequest);
+}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pte.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pte.cpp
index 97f06f4a..7618f598 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pte.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pte.cpp
@@ -14,6 +14,7 @@
//
// Global Variables
//
+extern BOOLEAN g_IsKdModuleLoaded;
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
@@ -206,7 +207,7 @@ CommandPte(vector CommandTokens, string Command)
}
else
{
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
if (Pid == 0)
{
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/rev.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/rev.cpp
index 191d4f6e..53c16ce4 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/rev.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/rev.cpp
@@ -14,10 +14,8 @@
//
// Global Variables
//
-extern BOOLEAN g_IsSerialConnectedToRemoteDebugger;
-extern std::wstring g_StartCommandPath;
-extern std::wstring g_StartCommandPathAndArguments;
-extern BOOLEAN g_IsSerialConnectedToRemoteDebugger;
+extern BOOLEAN g_IsSerialConnectedToRemoteDebugger;
+extern BOOLEAN g_IsSerialConnectedToRemoteDebugger;
/**
* @brief help of the !rev command
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/smi.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/smi.cpp
new file mode 100644
index 00000000..0efa6c41
--- /dev/null
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/smi.cpp
@@ -0,0 +1,178 @@
+/**
+ * @file smi.cpp
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief !smi command
+ * @details
+ * @version 0.15
+ * @date 2025-08-02
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+//
+// Global Variables
+//
+extern BOOLEAN g_IsKdModuleLoaded;
+extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+
+/**
+ * @brief help of the !smi command
+ *
+ * @return VOID
+ */
+VOID
+CommandSmiHelp()
+{
+ ShowMessages("!smi : shows details and triggers functionalities related to System Management Interrupt (SMI).\n");
+ ShowMessages("Note : SMIs are triggered using APM I/O Decode Registers and SMI count are from MSR_SMI_COUNT MSR (0x34).\n\n");
+
+ ShowMessages("syntax : \t!smi [Function (string)]\n");
+
+ ShowMessages("\n");
+ ShowMessages("\t\te.g : !smi count\n");
+ ShowMessages("\t\te.g : !smi trigger\n");
+}
+
+/**
+ * @brief Send SMI requests
+ *
+ * @param SmiRequest
+ *
+ * @return VOID
+ */
+BOOLEAN
+CommandSmiSendRequest(SMI_OPERATION_PACKETS * SmiOperationRequest)
+{
+ BOOL Status;
+ ULONG ReturnedLength;
+
+ if (g_IsSerialConnectedToRemoteDebuggee)
+ {
+ //
+ // Send the request over serial kernel debugger
+ //
+ if (!KdSendSmiPacketsToDebuggee(SmiOperationRequest, SIZEOF_SMI_OPERATION_PACKETS))
+ {
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+ }
+ else
+ {
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+
+ //
+ // Send IOCTL
+ //
+ Status = DeviceIoControl(
+ g_DeviceHandle, // Handle to device
+ IOCTL_PERFORM_SMI_OPERATION, // IO Control Code (IOCTL)
+ SmiOperationRequest, // Input Buffer to driver.
+ SIZEOF_SMI_OPERATION_PACKETS, // Input buffer length
+ SmiOperationRequest, // Output Buffer from driver.
+ SIZEOF_SMI_OPERATION_PACKETS, // Length of output buffer in bytes.
+ &ReturnedLength, // Bytes placed in buffer.
+ NULL // synchronous call
+ );
+
+ if (!Status)
+ {
+ ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
+
+ return FALSE;
+ }
+
+ if (SmiOperationRequest->KernelStatus == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+}
+
+/**
+ * @brief Request to perform an SMI operation
+ *
+ * @param SmiOperation
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperDbgPerformSmiOperation(SMI_OPERATION_PACKETS * SmiOperation)
+{
+ return CommandSmiSendRequest(SmiOperation);
+}
+
+/**
+ * @brief !smi command handler
+ *
+ * @param CommandTokens
+ * @param Command
+ *
+ * @return VOID
+ */
+VOID
+CommandSmi(vector CommandTokens, string Command)
+{
+ SMI_OPERATION_PACKETS SmiOperationRequest = {0};
+
+ if (CommandTokens.size() != 2)
+ {
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
+
+ CommandSmiHelp();
+ return;
+ }
+
+ if (CompareLowerCaseStrings(CommandTokens.at(1), "count"))
+ {
+ SmiOperationRequest.SmiOperationType = SMI_OPERATION_REQUEST_TYPE_READ_COUNT;
+ }
+ else if (CompareLowerCaseStrings(CommandTokens.at(1), "trigger"))
+ {
+ SmiOperationRequest.SmiOperationType = SMI_OPERATION_REQUEST_TYPE_TRIGGER_POWER_SMI;
+ }
+ else
+ {
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
+ CommandSmiHelp();
+ return;
+ }
+
+ //
+ // Send the SMI operation request
+ //
+ if (CommandSmiSendRequest(&SmiOperationRequest))
+ {
+ if (SmiOperationRequest.SmiOperationType == SMI_OPERATION_REQUEST_TYPE_READ_COUNT)
+ {
+ if (SmiOperationRequest.SmiCount == 0)
+ {
+ ShowMessages("SMI count: 0 (for security reasons, nested-virtualization environment (VMs) are unable to communicate with UEFI firmware)\n");
+ }
+ else
+ {
+ ShowMessages("SMI count: 0x%x\n", SmiOperationRequest.SmiCount);
+ }
+ }
+ else if (SmiOperationRequest.SmiOperationType == SMI_OPERATION_REQUEST_TYPE_TRIGGER_POWER_SMI)
+ {
+ ShowMessages("power SMI triggered successfully (you can use '!smi count' to view the number of executed SMIs)\n");
+ }
+ }
+ else
+ {
+ ShowErrorMessage(SmiOperationRequest.KernelStatus);
+ return;
+ }
+}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/syscall-sysret.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/syscall-sysret.cpp
index 38d0e2a5..4b3f887b 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/syscall-sysret.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/syscall-sysret.cpp
@@ -167,7 +167,9 @@ CommandSyscallAndSysret(vector CommandTokens, string Command)
//
// It's probably a syscall address
//
- if (!ConvertTokenToUInt64(Section, &SpecialTarget))
+ if (!SymbolConvertNameOrExprToAddress(
+ GetCaseSensitiveStringFromCommandToken(Section),
+ &SpecialTarget))
{
//
// Unknown parameter
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/track.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/track.cpp
index 0dc11414..fee0841c 100644
Binary files a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/track.cpp and b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/track.cpp differ
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/unhide.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/unhide.cpp
index 693c0824..7ede211d 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/unhide.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/unhide.cpp
@@ -11,6 +11,11 @@
*/
#include "pch.h"
+//
+// Global Variables
+//
+extern BOOLEAN g_IsVmmModuleLoaded;
+
/**
* @brief help of the !unhide command
*
@@ -42,7 +47,7 @@ HyperDbgDisableTransparentMode()
//
// Check if debugger is loaded or not
//
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// We don't wanna hide the debugger and make transparent vm-exits
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/va2pa.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/va2pa.cpp
index b6150178..795462de 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/va2pa.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/va2pa.cpp
@@ -14,6 +14,7 @@
//
// Global Variables
//
+extern BOOLEAN g_IsKdModuleLoaded;
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
@@ -164,7 +165,7 @@ CommandVa2pa(vector CommandTokens, string Command)
}
else
{
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
if (Pid == 0)
{
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/xsetbv.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/xsetbv.cpp
new file mode 100644
index 00000000..ab5d5ca0
--- /dev/null
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/xsetbv.cpp
@@ -0,0 +1,171 @@
+/**
+ * @file xsetbv.cpp
+ * @author unrustled.jimmies
+ * @brief !xsetbv command
+ * @details This command
+ * @version 0.16
+ * @date 2025-08-20
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief help of the !xsetbv command
+ *
+ * @return VOID
+ */
+VOID
+CommandXsetbvHelp()
+{
+ ShowMessages("!xsetbv : monitors execution of xsetbv instructions.\n\n");
+
+ ShowMessages("syntax : \t!xsetbv [Xcr (hex)] [pid ProcessId (hex)] [core CoreId (hex)] "
+ "[imm IsImmediate (yesno)] [sc EnableShortCircuiting (onoff)] [stage CallingStage (prepostall)] "
+ "[buffer PreAllocatedBuffer (hex)] [script { Script (string) }] [asm condition { Condition (assembly/hex) }] "
+ "[asm code { Code (assembly/hex) }] [output {OutputName (string)}]\n");
+
+ ShowMessages("\n");
+ ShowMessages("\t\te.g : !xsetbv\n");
+ ShowMessages("\t\te.g : !xsetbv 0\n");
+ ShowMessages("\t\te.g : !xsetbv pid 400\n");
+ ShowMessages("\t\te.g : !xsetbv core 2 pid 400\n");
+ ShowMessages("\t\te.g : !xsetbv script { printf(\"XSETBV instruction is executed with XCR index: %%llx\\n\", @rcx); }\n");
+ ShowMessages("\t\te.g : !xsetbv asm code { nop; nop; nop }\n");
+}
+
+/**
+ * @brief !xsetbv command handler
+ *
+ * @param CommandTokens
+ * @param Command
+ *
+ * @return VOID
+ */
+VOID
+CommandXsetbv(vector CommandTokens, string Command)
+{
+ PDEBUGGER_GENERAL_EVENT_DETAIL Event = NULL;
+ PDEBUGGER_GENERAL_ACTION ActionBreakToDebugger = NULL;
+ PDEBUGGER_GENERAL_ACTION ActionCustomCode = NULL;
+ PDEBUGGER_GENERAL_ACTION ActionScript = NULL;
+ BOOLEAN GetXcr = FALSE;
+ UINT32 EventLength;
+ UINT64 SpecialTarget = 0;
+ UINT32 ActionBreakToDebuggerLength = 0;
+ UINT32 ActionCustomCodeLength = 0;
+ UINT32 ActionScriptLength = 0;
+ DEBUGGER_EVENT_PARSING_ERROR_CAUSE EventParsingErrorCause;
+
+ //
+ // Interpret and fill the general event and action fields
+ //
+ if (!InterpretGeneralEventAndActionsFields(
+ &CommandTokens,
+ XSETBV_INSTRUCTION_EXECUTION,
+ &Event,
+ &EventLength,
+ &ActionBreakToDebugger,
+ &ActionBreakToDebuggerLength,
+ &ActionCustomCode,
+ &ActionCustomCodeLength,
+ &ActionScript,
+ &ActionScriptLength,
+ &EventParsingErrorCause))
+ {
+ return;
+ }
+
+ //
+ // Interpret command specific details (if any), of XCR index
+ //
+ for (auto Section : CommandTokens)
+ {
+ if (CompareLowerCaseStrings(Section, "!xsetbv"))
+ {
+ continue;
+ }
+ else if (!GetXcr)
+ {
+ //
+ // It's probably an XCR index
+ //
+ if (!ConvertTokenToUInt64(Section, &SpecialTarget))
+ {
+ //
+ // Unknown parameter
+ //
+ ShowMessages("unknown parameter '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(Section).c_str());
+ CommandXsetbvHelp();
+
+ FreeEventsAndActionsMemory(Event, ActionBreakToDebugger, ActionCustomCode, ActionScript);
+ return;
+ }
+ else
+ {
+ //
+ // A special XCR is set
+ //
+ GetXcr = TRUE;
+ }
+ }
+ else
+ {
+ //
+ // Unknown parameter
+ //
+ ShowMessages("unknown parameter '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(Section).c_str());
+
+ CommandXsetbvHelp();
+
+ FreeEventsAndActionsMemory(Event, ActionBreakToDebugger, ActionCustomCode, ActionScript);
+ return;
+ }
+ }
+
+ //
+ // Set the target XCR (if not specific then it means all XCRs)
+ //
+ Event->Options.OptionalParam1 = GetXcr;
+
+ if (GetXcr)
+ {
+ Event->Options.OptionalParam2 = SpecialTarget;
+ }
+
+ //
+ // Send the ioctl to the kernel for event registration
+ //
+ if (!SendEventToKernel(Event, EventLength))
+ {
+ //
+ // There was an error, probably the handle was not initialized
+ // we have to free the Action before exit, it is because, we
+ // already freed the Event and string buffers
+ //
+
+ FreeEventsAndActionsMemory(Event, ActionBreakToDebugger, ActionCustomCode, ActionScript);
+ return;
+ }
+
+ //
+ // Add the event to the kernel
+ //
+ if (!RegisterActionToEvent(Event,
+ ActionBreakToDebugger,
+ ActionBreakToDebuggerLength,
+ ActionCustomCode,
+ ActionCustomCodeLength,
+ ActionScript,
+ ActionScriptLength))
+ {
+ //
+ // There was an error
+ //
+ FreeEventsAndActionsMemory(Event, ActionBreakToDebugger, ActionCustomCode, ActionScript);
+ return;
+ }
+}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/hwdbg-commands/hw.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/hwdbg-commands/hw.cpp
index 7d06c0d9..036355e9 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/hwdbg-commands/hw.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/hwdbg-commands/hw.cpp
@@ -14,8 +14,7 @@
//
// Global Variables
//
-extern HWDBG_INSTANCE_INFORMATION g_HwdbgInstanceInfo;
-extern BOOLEAN g_HwdbgInstanceInfoIsValid;
+extern BOOLEAN g_HwdbgInstanceInfoIsValid;
/**
* @brief help of the !hw command
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/hwdbg-commands/hw_clk.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/hwdbg-commands/hw_clk.cpp
index dd707e72..d6d5f588 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/hwdbg-commands/hw_clk.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/hwdbg-commands/hw_clk.cpp
@@ -44,7 +44,7 @@ CommandHwClkHelp()
* @return BOOLEAN
*/
BOOLEAN
-CommandHwClkPerfomTest(vector CommandTokens,
+CommandHwClkPerformTest(vector CommandTokens,
const TCHAR * InstanceFilePathToRead,
const TCHAR * InstanceFilePathToSave,
const TCHAR * HardwareScriptFilePathToSave,
@@ -68,7 +68,7 @@ CommandHwClkPerfomTest(vector CommandTokens,
if (!HwdbgLoadInstanceInfo(InstanceFilePathToRead, InitialBramBufferSize))
{
//
- // No need for freeing memory so reuturn directly
+ // No need for freeing memory so return directly
//
return FALSE;
}
@@ -90,7 +90,7 @@ CommandHwClkPerfomTest(vector CommandTokens,
&EventParsingErrorCause))
{
//
- // No need for freeing memory so reuturn directly
+ // No need for freeing memory so return directly
//
return FALSE;
}
@@ -158,7 +158,7 @@ CommandHwClk(vector CommandTokens, string Command)
//
// Perform test with default file path and initial BRAM buffer size
//
- CommandHwClkPerfomTest(CommandTokens,
+ CommandHwClkPerformTest(CommandTokens,
HWDBG_TEST_READ_INSTANCE_INFO_PATH,
HWDBG_TEST_WRITE_INSTANCE_INFO_PATH,
HWDBG_TEST_WRITE_SCRIPT_BUFFER_PATH,
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/attach.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/attach.cpp
index 89521aad..24f2ede8 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/attach.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/attach.cpp
@@ -14,7 +14,6 @@
//
// Global Variables
//
-extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
extern BOOLEAN g_IsSerialConnectedToRemoteDebugger;
/**
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/debug.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/debug.cpp
index ec6e332e..42e9fb4e 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/debug.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/debug.cpp
@@ -14,11 +14,7 @@
//
// Global Variables
//
-extern HANDLE g_SerialListeningThreadHandle;
-extern HANDLE g_SerialRemoteComPortHandle;
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
-extern BOOLEAN g_IsSerialConnectedToRemoteDebugger;
-extern BOOLEAN g_IsDebuggeeRunning;
/**
* @brief help of the .debug command
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/detach.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/detach.cpp
index 1c5eb62b..565957ed 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/detach.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/detach.cpp
@@ -14,8 +14,8 @@
//
// Global Variables
//
+extern BOOLEAN g_IsVmmModuleLoaded;
extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
-extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
/**
* @brief help of the .detach command
@@ -43,7 +43,7 @@ DetachFromProcess()
//
// Check if debugger is loaded or not
//
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
//
// Check if we attached to a process or not
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/dump.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/dump.cpp
index 4c4ba8ac..2ac5bc92 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/dump.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/dump.cpp
@@ -212,7 +212,7 @@ CommandDump(vector CommandTokens, string Command)
//
// Default process we read from current process
//
- Pid = GetCurrentProcessId();
+ Pid = PlatformGetCurrentProcessId();
}
//
@@ -226,14 +226,19 @@ CommandDump(vector CommandTokens, string Command)
//
// Create or open the file for writing the dump file
//
- DumpFileHandle = CreateFileW(
- Filepath.c_str(),
- GENERIC_WRITE,
- 0,
- NULL,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
+ // TEMPORARY LINUX SHIM (same as in pe.cpp): std::wstring stores native
+ // wchar_t (4 bytes on Linux), but the HyperDbg WCHAR type is 2 bytes
+ // (UINT16) and PlatformOpenFileForWriting takes a const WCHAR *. On Linux
+ // the cast is a bogus 2-byte reinterpretation, acceptable only because
+ // Linux file I/O is still stubbed (the path is never opened). On Windows
+ // WCHAR == wchar_t, so it is a plain correct pointer. TODO(Linux): remove
+ // once real file I/O lands and convert wchar_t -> 2-byte WCHAR properly.
+ //
+#ifdef __linux__
+ DumpFileHandle = PlatformOpenFileForWriting((const WCHAR *)Filepath.c_str());
+#else
+ DumpFileHandle = PlatformOpenFileForWriting(Filepath.c_str());
+#endif
if (DumpFileHandle == INVALID_HANDLE_VALUE)
{
@@ -249,7 +254,7 @@ CommandDump(vector CommandTokens, string Command)
ActualLength = NULL;
Iterator = Length / PAGE_SIZE;
- for (size_t i = 0; i <= Iterator; i++)
+ for (SIZE_T i = 0; i <= Iterator; i++)
{
UINT64 Address = StartAddress + (i * PAGE_SIZE);
@@ -284,7 +289,7 @@ CommandDump(vector CommandTokens, string Command)
//
if (DumpFileHandle != NULL)
{
- CloseHandle(DumpFileHandle);
+ PlatformCloseFile(DumpFileHandle);
DumpFileHandle = NULL;
}
@@ -302,8 +307,6 @@ CommandDump(vector CommandTokens, string Command)
VOID
CommandDumpSaveIntoFile(PVOID Buffer, UINT32 Length)
{
- DWORD BytesWritten;
-
//
// Check if handle is valid
//
@@ -316,11 +319,11 @@ CommandDumpSaveIntoFile(PVOID Buffer, UINT32 Length)
//
// Write the buffer into the dump file
//
- if (!WriteFile(DumpFileHandle, Buffer, Length, &BytesWritten, NULL))
+ if (!PlatformWriteFile(DumpFileHandle, Buffer, Length))
{
ShowMessages("err, unable to write buffer into the dump\n");
- CloseHandle(DumpFileHandle);
+ PlatformCloseFile(DumpFileHandle);
DumpFileHandle = NULL;
return;
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/formats.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/formats.cpp
index c8ce1013..65a83280 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/formats.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/formats.cpp
@@ -42,10 +42,10 @@ CommandFormatsHelp()
VOID
CommandFormatsShowResults(UINT64 U64Value)
{
- time_t t;
- struct tm * tmp;
- char MY_TIME[50];
- unsigned int Character;
+ time_t t;
+ struct tm * tmp;
+ CHAR MY_TIME[50];
+ UINT32 Character;
time(&t);
@@ -75,10 +75,10 @@ CommandFormatsShowResults(UINT64 U64Value)
//
// iterate through 8, 8 bits (8*6)
//
- unsigned char * TempCharacter = (unsigned char *)&U64Value;
- for (size_t j = 0; j < sizeof(UINT64); j++)
+ UCHAR * TempCharacter = (UCHAR *)&U64Value;
+ for (SIZE_T j = 0; j < sizeof(UINT64); j++)
{
- Character = (unsigned int)TempCharacter[j];
+ Character = (UINT32)TempCharacter[j];
if (isprint(Character))
{
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/logopen.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/logopen.cpp
index 0d54b08b..abb0ea31 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/logopen.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/logopen.cpp
@@ -107,7 +107,7 @@ CommandLogopen(vector CommandTokens, string Command)
* @return VOID
*/
VOID
-LogopenSaveToFile(const char * Text)
+LogopenSaveToFile(const CHAR * Text)
{
g_LogOpenFile << Text;
}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/pagein.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/pagein.cpp
index ab66f024..a01aec56 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/pagein.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/pagein.cpp
@@ -15,6 +15,7 @@
// Global Variables
//
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+extern BOOLEAN g_IsVmmModuleLoaded;
extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
/**
@@ -81,10 +82,10 @@ BOOLEAN
CommandPageinCheckAndInterpretModeString(const std::string & ModeString,
PAGE_FAULT_EXCEPTION * PageFaultErrorCode)
{
- std::unordered_set AllowedChars = {'p', 'w', 'u', 'f', 'k', 's', 'h', 'g'};
- std::unordered_set FoundChars;
+ std::unordered_set AllowedChars = {'p', 'w', 'u', 'f', 'k', 's', 'h', 'g'};
+ std::unordered_set FoundChars;
- for (char c : ModeString)
+ for (CHAR c : ModeString)
{
if (AllowedChars.count(c) == 0)
{
@@ -99,7 +100,7 @@ CommandPageinCheckAndInterpretModeString(const std::string & ModeString,
//
// Found a character more than once
//
- return false;
+ return FALSE;
}
FoundChars.insert(c);
@@ -108,7 +109,7 @@ CommandPageinCheckAndInterpretModeString(const std::string & ModeString,
//
// All checks passed, let's interpret the page-fault code
//
- for (char c : ModeString)
+ for (CHAR c : ModeString)
{
if (c == 'p')
{
@@ -203,7 +204,7 @@ CommandPageinRequest(UINT64 TargetVirtualAddrFrom,
}
else
{
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
//
// For know, the support for the '.pagein' command is excluded from
@@ -215,14 +216,14 @@ CommandPageinRequest(UINT64 TargetVirtualAddrFrom,
if (Pid == 0)
{
- Pid = GetCurrentProcessId();
+ Pid = PlatformGetCurrentProcessId();
PageFaultRequest.ProcessId = Pid;
}
//
// Send IOCTL
//
- Status = DeviceIoControl(
+ Status = PlatformDeviceIoControl(
g_DeviceHandle, // Handle to device
IOCTL_DEBUGGER_BRING_PAGES_IN, // IO Control Code (IOCTL)
&PageFaultRequest, // Input Buffer to driver.
@@ -236,7 +237,7 @@ CommandPageinRequest(UINT64 TargetVirtualAddrFrom,
if (!Status)
{
- ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
+ ShowMessages("ioctl failed with code 0x%x\n", PlatformGetLastError());
return;
}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/pe.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/pe.cpp
index 0f6b32b7..1d9fe58e 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/pe.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/pe.cpp
@@ -11,8 +11,6 @@
*/
#include "pch.h"
-using namespace std;
-
/**
* @brief help of the .pe command
*
@@ -21,10 +19,11 @@ using namespace std;
VOID
CommandPeHelp()
{
- ShowMessages(".pe : parses portable executable (PE) files and dump sections.\n\n");
+ ShowMessages(".pe : parses portable executable (PE) files, displays header metadata, and dumps sections.\n\n");
ShowMessages("syntax : \t.pe [header] [FilePath (string)]\n");
ShowMessages("syntax : \t.pe [section] [SectionName (string)] [FilePath (string)]\n");
+ ShowMessages("\n.pe section dumps are capped at 1 MiB per matching section and 4 MiB total.\n");
ShowMessages("\n");
ShowMessages("\t\te.g : .pe header c:\\reverse\\myfile.exe\n");
@@ -62,7 +61,16 @@ CommandPe(vector CommandTokens, string Command)
{
if (CommandTokens.size() == 3)
{
- ShowMessages("please specify a valid PE file\n\n");
+ ShowMessages("err, incorrect use of the '%s' command\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
+ CommandPeHelp();
+ return;
+ }
+
+ if (CommandTokens.size() != 4)
+ {
+ ShowMessages("err, incorrect use of the '%s' command\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandPeHelp();
return;
}
@@ -71,6 +79,14 @@ CommandPe(vector CommandTokens, string Command)
}
else if (CompareLowerCaseStrings(CommandTokens.at(1), "header"))
{
+ if (CommandTokens.size() != 3)
+ {
+ ShowMessages("err, incorrect use of the '%s' command\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
+ CommandPeHelp();
+ return;
+ }
+
ShowDumpOfSection = FALSE;
TempFilePath = GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2));
}
@@ -90,10 +106,32 @@ CommandPe(vector CommandTokens, string Command)
//
StringToWString(Filepath, TempFilePath);
+ //
+ // TEMPORARY LINUX SHIM:
+ // std::wstring stores native wchar_t, which is 4 bytes on Linux, but the
+ // HyperDbg WCHAR type is 2 bytes (UINT16) and the PE-parser path APIs take
+ // a const WCHAR *. The cast below exists ONLY so the project compiles on
+ // Linux. On Linux it produces a bogus 2-byte reinterpretation of the 4-byte
+ // buffer; that is acceptable for now only because Linux file I/O is still
+ // stubbed (the path is never actually opened). On Windows WCHAR == wchar_t,
+ // so it is a plain, correct pointer with no reinterpretation.
+ //
+ // TODO (Linux): remove this cast once real Linux file I/O lands. The proper
+ // fix is to convert the 4-byte wchar_t path into a 2-byte WCHAR/UTF-16
+ // buffer (e.g. a std::wstring -> WCHAR helper) and pass that, so the PE
+ // parser receives a valid path. The same conversion is needed by
+ // PlatformMapFileReadOnly / PlatformOpenFileForWriting.
+ //
+#ifdef __linux__
+ const WCHAR * FilepathW = (const WCHAR *)Filepath.c_str();
+#else
+ const WCHAR * FilepathW = Filepath.c_str();
+#endif
+
//
// Detect whether PE is 32-bit or 64-bit
//
- if (!PeIsPE32BitOr64Bit(Filepath.c_str(), &Is32Bit))
+ if (!PeIsPE32BitOr64Bit(FilepathW, &Is32Bit))
{
//
// File was invalid, the error message is shown in the above function
@@ -106,10 +144,10 @@ CommandPe(vector CommandTokens, string Command)
//
if (!ShowDumpOfSection)
{
- PeShowSectionInformationAndDump(Filepath.c_str(), NULL, Is32Bit);
+ PeShowSectionInformationAndDump(FilepathW, NULL, Is32Bit);
}
else
{
- PeShowSectionInformationAndDump(Filepath.c_str(), GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2)).c_str(), Is32Bit);
+ PeShowSectionInformationAndDump(FilepathW, GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2)).c_str(), Is32Bit);
}
}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/restart.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/restart.cpp
index c0cc2d96..626856b7 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/restart.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/restart.cpp
@@ -89,15 +89,33 @@ CommandRestart(vector CommandTokens, string Command)
//
if (g_StartCommandPathAndArguments.empty())
{
+ //
+ // TEMPORARY LINUX SHIM (same as in pe.cpp/dump.cpp): the path is a
+ // std::wstring of native wchar_t (4 bytes on Linux), but UdAttachToProcess
+ // takes a 2-byte HyperDbg WCHAR * (UINT16). The cast is a bogus 2-byte
+ // reinterpretation on Linux, acceptable only because the user-debugger
+ // path is still stubbed there. On Windows WCHAR == wchar_t, so it is a
+ // plain correct pointer. TODO(Linux): convert wchar_t -> 2-byte WCHAR
+ // properly once the Linux user-debugger path is real.
+ //
UdAttachToProcess(NULL,
- g_StartCommandPath.c_str(),
+ (WCHAR *)g_StartCommandPath.c_str(),
NULL,
FALSE);
}
else
{
+ //
+ // TEMPORARY LINUX SHIM (same as in pe.cpp/dump.cpp): the path/arguments
+ // are std::wstring of native wchar_t (4 bytes on Linux), but
+ // UdAttachToProcess takes 2-byte HyperDbg WCHAR * (UINT16). The casts are
+ // a bogus 2-byte reinterpretation on Linux, acceptable only because the
+ // user-debugger path is still stubbed there. On Windows WCHAR == wchar_t,
+ // so they are plain correct pointers. TODO(Linux): convert wchar_t ->
+ // 2-byte WCHAR properly once the Linux user-debugger path is real.
+ //
UdAttachToProcess(NULL,
- g_StartCommandPath.c_str(),
+ (WCHAR *)g_StartCommandPath.c_str(),
(WCHAR *)g_StartCommandPathAndArguments.c_str(),
FALSE);
}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/script.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/script.cpp
index ebbad88c..f594ff37 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/script.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/script.cpp
@@ -47,9 +47,9 @@ CommandScriptHelp()
VOID
CommandScriptRunCommand(std::string Input, vector PathAndArgs)
{
- int CommandExecutionResult = 0;
- char * LineContent = NULL;
- int i = 0;
+ INT CommandExecutionResult = 0;
+ CHAR * LineContent = NULL;
+ INT i = 0;
//
// Replace the $arg*s
@@ -69,7 +69,7 @@ CommandScriptRunCommand(std::string Input, vector PathAndArgs)
//
// Convert script to char*
//
- LineContent = (char *)Input.c_str();
+ LineContent = (CHAR *)Input.c_str();
if (IsEmptyString(LineContent))
{
@@ -109,7 +109,7 @@ HyperDbgScriptReadFileAndExecuteCommand(std::vector & PathAndArgs)
{
std::string Line;
BOOLEAN IsOpened = FALSE;
- bool Reset = false;
+ BOOLEAN Reset = FALSE;
string CommandToExecute = "";
string PathOfScriptFile = "";
@@ -134,7 +134,7 @@ HyperDbgScriptReadFileAndExecuteCommand(std::vector & PathAndArgs)
//
// Reset multiline command
//
- Reset = true;
+ Reset = TRUE;
while (std::getline(File, Line))
{
@@ -154,7 +154,7 @@ HyperDbgScriptReadFileAndExecuteCommand(std::vector & PathAndArgs)
//
// The command is expected to be continued
//
- Reset = false;
+ Reset = FALSE;
//
// Append to the previous command
@@ -168,7 +168,7 @@ HyperDbgScriptReadFileAndExecuteCommand(std::vector & PathAndArgs)
//
// Reset for the next commands round
//
- Reset = true;
+ Reset = TRUE;
//
// Append this line too
@@ -222,14 +222,14 @@ HyperDbgScriptReadFileAndExecuteCommand(std::vector & PathAndArgs)
* @return INT
*/
INT
-ScriptReadFileAndExecuteCommandline(INT argc, CHAR * argv[])
+HyperDbgScriptReadFileAndExecuteCommandline(INT argc, CHAR * argv[])
{
vector Args;
//
// Convert it to the array
//
- for (size_t i = 2; i < argc; i++)
+ for (SIZE_T i = 2; i < argc; i++)
{
std::string TempStr(argv[i]);
Args.push_back(TempStr);
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/start.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/start.cpp
index 2446727c..c628cdb2 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/start.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/start.cpp
@@ -60,7 +60,7 @@ CommandStart(vector CommandTokens, string Command)
return;
}
- //
+//
// Disable user-mode debugger in this version
//
#if ActivateUserModeDebugger == FALSE
@@ -147,8 +147,17 @@ CommandStart(vector CommandTokens, string Command)
//
if (Arguments.empty())
{
+ //
+ // TEMPORARY LINUX SHIM (same as in pe.cpp/dump.cpp): the path is a
+ // std::wstring of native wchar_t (4 bytes on Linux), but UdAttachToProcess
+ // takes a 2-byte HyperDbg WCHAR * (UINT16). The cast is a bogus 2-byte
+ // reinterpretation on Linux, acceptable only because the user-debugger
+ // path is still stubbed there. On Windows WCHAR == wchar_t, so it is a
+ // plain correct pointer. TODO(Linux): convert wchar_t -> 2-byte WCHAR
+ // properly once the Linux user-debugger path is real.
+ //
UdAttachToProcess(NULL,
- g_StartCommandPath.c_str(),
+ (WCHAR *)g_StartCommandPath.c_str(),
NULL,
FALSE);
}
@@ -164,8 +173,17 @@ CommandStart(vector CommandTokens, string Command)
//
StringToWString(g_StartCommandPathAndArguments, Arguments);
+ //
+ // TEMPORARY LINUX SHIM (same as in pe.cpp/dump.cpp): the path/arguments
+ // are std::wstring of native wchar_t (4 bytes on Linux), but
+ // UdAttachToProcess takes 2-byte HyperDbg WCHAR * (UINT16). The casts are
+ // a bogus 2-byte reinterpretation on Linux, acceptable only because the
+ // user-debugger path is still stubbed there. On Windows WCHAR == wchar_t,
+ // so they are plain correct pointers. TODO(Linux): convert wchar_t ->
+ // 2-byte WCHAR properly once the Linux user-debugger path is real.
+ //
UdAttachToProcess(NULL,
- g_StartCommandPath.c_str(),
+ (WCHAR *)g_StartCommandPath.c_str(),
(WCHAR *)g_StartCommandPathAndArguments.c_str(),
FALSE);
}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/switch.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/switch.cpp
index 27c88cdc..65bf33ea 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/switch.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/switch.cpp
@@ -11,12 +11,6 @@
*/
#include "pch.h"
-//
-// Global Variables
-//
-extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
-extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
-
/**
* @brief help of the .switch command
*
@@ -33,6 +27,7 @@ CommandSwitchHelp()
ShowMessages("syntax : \t.switch [tid ThreadId (hex)]\n");
ShowMessages("\n");
+ ShowMessages("\t\te.g : .switch\n");
ShowMessages("\t\te.g : .switch list\n");
ShowMessages("\t\te.g : .switch pid b60 \n");
ShowMessages("\t\te.g : .switch tid b60 \n");
@@ -51,7 +46,7 @@ CommandSwitch(vector CommandTokens, string Command)
{
UINT32 PidOrTid = NULL;
- if (CommandTokens.size() > 3 || CommandTokens.size() == 2)
+ if (CommandTokens.size() > 3)
{
ShowMessages("incorrect use of the '%s'\n\n",
GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
@@ -62,7 +57,7 @@ CommandSwitch(vector CommandTokens, string Command)
//
// Perform switching or listing the threads
//
- if (CommandTokens.size() == 1)
+ if (CommandTokens.size() == 1 || (CommandTokens.size() == 2 && CompareLowerCaseStrings(CommandTokens.at(1), "list")))
{
UdShowListActiveDebuggingProcessesAndThreads();
}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/sympath.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/sympath.cpp
index 5b8cd8e7..b413cf8a 100644
--- a/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/sympath.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/sympath.cpp
@@ -107,7 +107,7 @@ CommandSympath(vector CommandTokens, string Command)
//
// Check if the string contains '*'
//
- char Delimiter = '*';
+ CHAR Delimiter = '*';
if (Command.find(Delimiter) != std::string::npos)
{
//
diff --git a/hyperdbg/libhyperdbg/code/debugger/communication/forwarding.cpp b/hyperdbg/libhyperdbg/code/debugger/communication/forwarding.cpp
index 6ec387e1..b6d3d940 100644
--- a/hyperdbg/libhyperdbg/code/debugger/communication/forwarding.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/communication/forwarding.cpp
@@ -211,7 +211,7 @@ ForwardingCloseOutputSource(PDEBUGGER_EVENT_FORWARDING SourceDescriptor)
*
* @return HANDLE returns handle of the source
*/
-VOID *
+PVOID
ForwardingCreateOutputSource(DEBUGGER_EVENT_FORWARDING_TYPE SourceType,
const string & Description,
SOCKET * Socket,
@@ -232,7 +232,7 @@ ForwardingCreateOutputSource(DEBUGGER_EVENT_FORWARDING_TYPE SourceType,
// The handle might be INVALID_HANDLE_VALUE which will be
// checked by the caller
//
- return (void *)FileHandle;
+ return (PVOID)FileHandle;
}
else if (SourceType == EVENT_FORWARDING_MODULE)
{
@@ -260,7 +260,7 @@ ForwardingCreateOutputSource(DEBUGGER_EVENT_FORWARDING_TYPE SourceType,
//
// The handle is the location of the hyperdbg_event_forwarding function
//
- return (void *)hyperdbg_event_forwarding;
+ return (PVOID)hyperdbg_event_forwarding;
}
else if (SourceType == EVENT_FORWARDING_NAMEDPIPE)
{
@@ -274,7 +274,7 @@ ForwardingCreateOutputSource(DEBUGGER_EVENT_FORWARDING_TYPE SourceType,
return INVALID_HANDLE_VALUE;
}
- return (void *)PipeHandle;
+ return (PVOID)PipeHandle;
}
else if (SourceType == EVENT_FORWARDING_TCP)
{
@@ -287,7 +287,7 @@ ForwardingCreateOutputSource(DEBUGGER_EVENT_FORWARDING_TYPE SourceType,
// Split the ip and port by : delimiter
//
IpPortDelimiter = ':';
- size_t find = Description.find(IpPortDelimiter);
+ SIZE_T find = Description.find(IpPortDelimiter);
Ip = Description.substr(0, find);
Port = Description.substr(find + 1, find + Description.size());
@@ -302,7 +302,7 @@ ForwardingCreateOutputSource(DEBUGGER_EVENT_FORWARDING_TYPE SourceType,
// because this functionality doesn't work with handlers; however,
// send 1 or TRUE is a valid handle
//
- return (void *)TRUE;
+ return (PVOID)TRUE;
}
else
{
@@ -347,7 +347,7 @@ ForwardingPerformEventForwarding(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetail,
BOOLEAN Result = FALSE;
PLIST_ENTRY TempList = 0;
- for (size_t i = 0; i < DebuggerOutputSourceMaximumRemoteSourceForSingleEvent; i++)
+ for (SIZE_T i = 0; i < DebuggerOutputSourceMaximumRemoteSourceForSingleEvent; i++)
{
//
// Check whether we reached to the end of the events
diff --git a/hyperdbg/libhyperdbg/code/debugger/communication/namedpipe.cpp b/hyperdbg/libhyperdbg/code/debugger/communication/namedpipe.cpp
index 732d3afc..a52fca2c 100644
--- a/hyperdbg/libhyperdbg/code/debugger/communication/namedpipe.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/communication/namedpipe.cpp
@@ -93,7 +93,7 @@ NamedPipeServerWaitForClientConntection(HANDLE PipeHandle)
* @return UINT32
*/
UINT32
-NamedPipeServerReadClientMessage(HANDLE PipeHandle, char * BufferToSave, int MaximumReadBufferLength)
+NamedPipeServerReadClientMessage(HANDLE PipeHandle, CHAR * BufferToSave, INT MaximumReadBufferLength)
{
DWORD cbBytes;
@@ -129,8 +129,8 @@ NamedPipeServerReadClientMessage(HANDLE PipeHandle, char * BufferToSave, int Max
BOOLEAN
NamedPipeServerSendMessageToClient(HANDLE PipeHandle,
- char * BufferToSend,
- int BufferSize)
+ CHAR * BufferToSend,
+ INT BufferSize)
{
DWORD cbBytes;
@@ -289,7 +289,7 @@ NamedPipeClientCreatePipeOverlappedIo(LPCSTR PipeName)
* @return BOOLEAN
*/
BOOLEAN
-NamedPipeClientSendMessage(HANDLE PipeHandle, char * BufferToSend, int BufferSize)
+NamedPipeClientSendMessage(HANDLE PipeHandle, CHAR * BufferToSend, INT BufferSize)
{
//
// We are done connecting to the server pipe,
@@ -328,7 +328,7 @@ NamedPipeClientSendMessage(HANDLE PipeHandle, char * BufferToSend, int BufferSiz
// Read the count of read buffer
//
UINT32
-NamedPipeClientReadMessage(HANDLE PipeHandle, char * BufferToRead, int MaximumSizeOfBuffer)
+NamedPipeClientReadMessage(HANDLE PipeHandle, CHAR * BufferToRead, INT MaximumSizeOfBuffer)
{
DWORD cbBytes;
@@ -376,17 +376,17 @@ NamedPipeClientClosePipe(HANDLE PipeHandle)
/**
* @brief and example of how to use named pipe as a server
*
- * @return int
+ * @return INT
*/
-int
+INT
NamedPipeServerExample()
{
HANDLE PipeHandle;
BOOLEAN SentMessageResult;
UINT32 ReadBytes;
- const int BufferSize = 1024;
- char BufferToRead[BufferSize] = {0};
- char BufferToSend[BufferSize] = "test message to send from server !!!";
+ const INT BufferSize = 1024;
+ CHAR BufferToRead[BufferSize] = {0};
+ CHAR BufferToSend[BufferSize] = "test message to send from server !!!";
PipeHandle = NamedPipeServerCreatePipe("\\\\.\\Pipe\\HyperDbgTests",
BufferSize,
@@ -447,16 +447,16 @@ NamedPipeServerExample()
/**
* @brief and example of how to use named pipe as a client
*
- * @return int
+ * @return INT
*/
-int
+INT
NamedPipeClientExample()
{
HANDLE PipeHandle;
BOOLEAN SentMessageResult;
UINT32 ReadBytes;
- const int BufferSize = 1024;
- char Buffer[BufferSize] = "test message to send from client !!!";
+ const INT BufferSize = 1024;
+ CHAR Buffer[BufferSize] = "test message to send from client !!!";
PipeHandle = NamedPipeClientCreatePipe("\\\\.\\Pipe\\HyperDbgTests");
diff --git a/hyperdbg/libhyperdbg/code/debugger/communication/remote-connection.cpp b/hyperdbg/libhyperdbg/code/debugger/communication/remote-connection.cpp
index f0a3022e..75198438 100644
--- a/hyperdbg/libhyperdbg/code/debugger/communication/remote-connection.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/communication/remote-connection.cpp
@@ -39,7 +39,7 @@ extern HANDLE g_EndOfMessageReceivedEvent;
VOID
RemoteConnectionListen(PCSTR Port)
{
- char recvbuf[COMMUNICATION_BUFFER_SIZE] = {0};
+ CHAR recvbuf[COMMUNICATION_BUFFER_SIZE] = {0};
//
// Check if the debugger or debuggee is already active
@@ -75,7 +75,7 @@ RemoteConnectionListen(PCSTR Port)
//
// Check whether the signature of debuggee and debugger match or not
//
- if (strcmp((const char *)BuildSignature, recvbuf) != 0)
+ if (strcmp((const CHAR *)BuildSignature, recvbuf) != 0)
{
//
// Build version not matched
@@ -154,12 +154,12 @@ RemoteConnectionListen(PCSTR Port)
//
// Execute the command
//
- int CommandExecutionResult = HyperDbgInterpreter(recvbuf);
+ INT CommandExecutionResult = HyperDbgInterpreter(recvbuf);
//
// Send end of buffer
//
- RemoteConnectionSendResultsToHost((const char *)g_EndOfBufferCheckTcp, sizeof(g_EndOfBufferCheckTcp));
+ RemoteConnectionSendResultsToHost((const CHAR *)g_EndOfBufferCheckTcp, sizeof(g_EndOfBufferCheckTcp));
//
// if the debugger encounters an exit state then the return will be 1
@@ -191,7 +191,7 @@ RemoteConnectionListen(PCSTR Port)
//
// Indicate that we're not in remote debugger anymore
//
- ShowMessages("closing the conntection...\n");
+ ShowMessages("closing the connection...\n");
//
// Close the connection
@@ -210,7 +210,7 @@ RemoteConnectionListen(PCSTR Port)
DWORD WINAPI
RemoteConnectionThreadListeningToDebuggee(LPVOID lpParam)
{
- char RecvBuf[COMMUNICATION_BUFFER_SIZE + TCP_END_OF_BUFFER_CHARS_COUNT] = {0};
+ CHAR RecvBuf[COMMUNICATION_BUFFER_SIZE + TCP_END_OF_BUFFER_CHARS_COUNT] = {0};
UINT32 BuffLenReceived = 0;
while (g_IsConnectedToRemoteDebuggee)
@@ -229,7 +229,7 @@ RemoteConnectionThreadListeningToDebuggee(LPVOID lpParam)
//
// Check if it's end of the buffer
//
- for (size_t i = 0; i < BuffLenReceived; i++)
+ for (SIZE_T i = 0; i < BuffLenReceived; i++)
{
if (RecvBuf[i] == g_EndOfBufferCheckTcp[0] &&
RecvBuf[i + 1] == g_EndOfBufferCheckTcp[1] &&
@@ -364,7 +364,7 @@ RemoteConnectionConnect(PCSTR Ip, PCSTR Port)
//
// Check to see whether the version of debugger and debuggee matches together or not
//
- if (CommunicationClientSendMessage(g_ClientConnectSocket, (const char *)BuildSignature, sizeof(BuildSignature)) != 0)
+ if (CommunicationClientSendMessage(g_ClientConnectSocket, (const CHAR *)BuildSignature, sizeof(BuildSignature)) != 0)
{
//
// Failed
@@ -388,7 +388,7 @@ RemoteConnectionConnect(PCSTR Ip, PCSTR Port)
//
// Check if the handshake was successful or not
//
- if (strcmp((const char *)"OK", Recv) != 0)
+ if (strcmp((const CHAR *)"OK", Recv) != 0)
{
//
// Build version not matched
@@ -438,11 +438,11 @@ RemoteConnectionConnect(PCSTR Ip, PCSTR Port)
*
* @param sendbuf address of message buffer
* @param len length of buffer
- * @return int returning 0 means that there was no error in
+ * @return INT returning 0 means that there was no error in
* executing the function and 1 shows there was an error
*/
-int
-RemoteConnectionSendCommand(const char * sendbuf, int len)
+INT
+RemoteConnectionSendCommand(const CHAR * sendbuf, INT len)
{
//
// Send Message
@@ -474,11 +474,11 @@ RemoteConnectionSendCommand(const char * sendbuf, int len)
*
* @param sendbuf buffer address
* @param len length of buffer
- * @return int returning 0 means that there was no error in
+ * @return INT returning 0 means that there was no error in
* executing the function and 1 shows there was an error
*/
-int
-RemoteConnectionSendResultsToHost(const char * sendbuf, int len)
+INT
+RemoteConnectionSendResultsToHost(const CHAR * sendbuf, INT len)
{
//
// Send the message
@@ -497,10 +497,10 @@ RemoteConnectionSendResultsToHost(const char * sendbuf, int len)
/**
* @brief Close the connect from client side to the debuggee
*
- * @return int returning 0 means that there was no error in
+ * @return INT returning 0 means that there was no error in
* executing the function and 1 shows there was an error
*/
-int
+INT
RemoteConnectionCloseTheConnectionWithDebuggee()
{
CommunicationClientShutdownConnection(g_ClientConnectSocket);
diff --git a/hyperdbg/libhyperdbg/code/debugger/communication/tcpclient.cpp b/hyperdbg/libhyperdbg/code/debugger/communication/tcpclient.cpp
index b601f3f9..831b361c 100644
--- a/hyperdbg/libhyperdbg/code/debugger/communication/tcpclient.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/communication/tcpclient.cpp
@@ -17,23 +17,23 @@
* @param Ip
* @param Port
* @param ConnectSocketArg
- * @return int
+ * @return INT
*/
-int
+INT
CommunicationClientConnectToServer(PCSTR Ip, PCSTR Port, SOCKET * ConnectSocketArg)
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL, *ptr = NULL, hints;
- int iResult;
+ INT IResult;
//
// Initialize Winsock
//
- iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
- if (iResult != 0)
+ IResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
+ if (IResult != 0)
{
- ShowMessages("err, WSAStartup failed (%x)\n", iResult);
+ ShowMessages("err, WSAStartup failed (%x)\n", IResult);
return 1;
}
@@ -45,10 +45,10 @@ CommunicationClientConnectToServer(PCSTR Ip, PCSTR Port, SOCKET * ConnectSocketA
//
// Resolve the server address and port
//
- iResult = getaddrinfo(Ip, Port, &hints, &result);
- if (iResult != 0)
+ IResult = getaddrinfo(Ip, Port, &hints, &result);
+ if (IResult != 0)
{
- ShowMessages("getaddrinfo failed (%x)\n", iResult);
+ ShowMessages("getaddrinfo failed (%x)\n", IResult);
WSACleanup();
return 1;
}
@@ -72,8 +72,8 @@ CommunicationClientConnectToServer(PCSTR Ip, PCSTR Port, SOCKET * ConnectSocketA
//
// Connect to server.
//
- iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
- if (iResult == SOCKET_ERROR)
+ IResult = connect(ConnectSocket, ptr->ai_addr, (INT)ptr->ai_addrlen);
+ if (IResult == SOCKET_ERROR)
{
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
@@ -105,18 +105,18 @@ CommunicationClientConnectToServer(PCSTR Ip, PCSTR Port, SOCKET * ConnectSocketA
* @param ConnectSocket
* @param sendbuf
* @param buflen
- * @return int
+ * @return INT
*/
-int
-CommunicationClientSendMessage(SOCKET ConnectSocket, const char * sendbuf, int buflen)
+INT
+CommunicationClientSendMessage(SOCKET ConnectSocket, const CHAR * sendbuf, INT buflen)
{
- int iResult;
+ INT IResult;
//
// Send an initial buffer
//
- iResult = send(ConnectSocket, sendbuf, buflen, 0);
- if (iResult == SOCKET_ERROR)
+ IResult = send(ConnectSocket, sendbuf, buflen, 0);
+ if (IResult == SOCKET_ERROR)
{
ShowMessages("err, send failed (%x)\n", WSAGetLastError());
closesocket(ConnectSocket);
@@ -131,18 +131,18 @@ CommunicationClientSendMessage(SOCKET ConnectSocket, const char * sendbuf, int b
* @brief shutdown the connection as a client
*
* @param ConnectSocket
- * @return int
+ * @return INT
*/
-int
+INT
CommunicationClientShutdownConnection(SOCKET ConnectSocket)
{
- int iResult;
+ INT IResult;
//
// shutdown the connection since no more data will be sent
//
- iResult = shutdown(ConnectSocket, SD_SEND);
- if (iResult == SOCKET_ERROR)
+ IResult = shutdown(ConnectSocket, SD_SEND);
+ if (IResult == SOCKET_ERROR)
{
//
// We comment this line because the connection might be removed;
@@ -167,12 +167,12 @@ CommunicationClientShutdownConnection(SOCKET ConnectSocket)
* @param RecvBuf
* @param MaxBuffLen
* @param BuffLenRecvd
- * @return int
+ * @return INT
*/
-int
+INT
CommunicationClientReceiveMessage(SOCKET ConnectSocket, CHAR * RecvBuf, UINT32 MaxBuffLen, PUINT32 BuffLenRecvd)
{
- int Result;
+ INT Result;
//
// Receive until the peer closes the connection
@@ -210,9 +210,9 @@ CommunicationClientReceiveMessage(SOCKET ConnectSocket, CHAR * RecvBuf, UINT32 M
* @brief cleanup the connection as client
*
* @param ConnectSocket
- * @return int
+ * @return INT
*/
-int
+INT
CommunicationClientCleanup(SOCKET ConnectSocket)
{
//
diff --git a/hyperdbg/libhyperdbg/code/debugger/communication/tcpserver.cpp b/hyperdbg/libhyperdbg/code/debugger/communication/tcpserver.cpp
index 764ff0eb..19129e29 100644
--- a/hyperdbg/libhyperdbg/code/debugger/communication/tcpserver.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/communication/tcpserver.cpp
@@ -27,13 +27,13 @@
* @param ListenSocketArg
* @return int
*/
-int
+INT
CommunicationServerCreateServerAndWaitForClient(PCSTR Port,
SOCKET * ClientSocketArg,
SOCKET * ListenSocketArg)
{
WSADATA wsaData;
- int iResult;
+ INT IResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
@@ -44,10 +44,10 @@ CommunicationServerCreateServerAndWaitForClient(PCSTR Port,
//
// Initialize Winsock
//
- iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
- if (iResult != 0)
+ IResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
+ if (IResult != 0)
{
- ShowMessages("err, WSAStartup failed (%x)\n", iResult);
+ ShowMessages("err, WSAStartup failed (%x)\n", IResult);
return 1;
}
@@ -60,10 +60,10 @@ CommunicationServerCreateServerAndWaitForClient(PCSTR Port,
//
// Resolve the server address and port
//
- iResult = getaddrinfo(NULL, Port, &hints, &result);
- if (iResult != 0)
+ IResult = getaddrinfo(NULL, Port, &hints, &result);
+ if (IResult != 0)
{
- ShowMessages("err, getaddrinfo failed (%x)\n", iResult);
+ ShowMessages("err, getaddrinfo failed (%x)\n", IResult);
WSACleanup();
return 1;
}
@@ -84,8 +84,8 @@ CommunicationServerCreateServerAndWaitForClient(PCSTR Port,
//
// Setup the TCP listening socket
//
- iResult = ::bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
- if (iResult == SOCKET_ERROR)
+ IResult = ::bind(ListenSocket, result->ai_addr, (INT)result->ai_addrlen);
+ if (IResult == SOCKET_ERROR)
{
ShowMessages("err, bind failed (%x)\n", WSAGetLastError());
freeaddrinfo(result);
@@ -96,8 +96,8 @@ CommunicationServerCreateServerAndWaitForClient(PCSTR Port,
freeaddrinfo(result);
- iResult = listen(ListenSocket, SOMAXCONN);
- if (iResult == SOCKET_ERROR)
+ IResult = listen(ListenSocket, SOMAXCONN);
+ if (IResult == SOCKET_ERROR)
{
ShowMessages("err, listen failed (%x)\n", WSAGetLastError());
closesocket(ListenSocket);
@@ -109,9 +109,9 @@ CommunicationServerCreateServerAndWaitForClient(PCSTR Port,
// Accept a client socket
//
sockaddr_in name = {0};
- int addrlen = sizeof(name);
+ INT AddrLen = sizeof(name);
- ClientSocket = accept(ListenSocket, (struct sockaddr *)&name, &addrlen);
+ ClientSocket = accept(ListenSocket, (struct sockaddr *)&name, &AddrLen);
if (ClientSocket == INVALID_SOCKET)
{
@@ -141,24 +141,24 @@ CommunicationServerCreateServerAndWaitForClient(PCSTR Port,
* @param ClientSocket
* @param recvbuf
* @param recvbuflen
- * @return int
+ * @return INT
*/
-int
-CommunicationServerReceiveMessage(SOCKET ClientSocket, char * recvbuf, int recvbuflen)
+INT
+CommunicationServerReceiveMessage(SOCKET ClientSocket, CHAR * recvbuf, INT recvbuflen)
{
- int iResult;
+ INT IResult;
//
// Receive until the peer shuts down the connection
//
- iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
- if (iResult > 0)
+ IResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
+ if (IResult > 0)
{
//
// ShowMessages("bytes received: %d\n", iResult);
//
}
- else if (iResult == 0)
+ else if (IResult == 0)
{
//
// ShowMessages("connection closing...\n");
@@ -182,18 +182,18 @@ CommunicationServerReceiveMessage(SOCKET ClientSocket, char * recvbuf, int recvb
* @param ClientSocket
* @param sendbuf
* @param length
- * @return int
+ * @return INT
*/
-int
-CommunicationServerSendMessage(SOCKET ClientSocket, const char * sendbuf, int length)
+INT
+CommunicationServerSendMessage(SOCKET ClientSocket, const CHAR * sendbuf, INT length)
{
- int iSendResult;
+ INT ISendResult;
//
// Echo the buffer back to the sender
//
- iSendResult = send(ClientSocket, sendbuf, length, 0);
- if (iSendResult == SOCKET_ERROR)
+ ISendResult = send(ClientSocket, sendbuf, length, 0);
+ if (ISendResult == SOCKET_ERROR)
{
/*
ShowMessages("err, send failed (%x)\n", WSAGetLastError());
@@ -210,13 +210,13 @@ CommunicationServerSendMessage(SOCKET ClientSocket, const char * sendbuf, int le
*
* @param ClientSocket
* @param ListenSocket
- * @return int
+ * @return INT
*/
-int
+INT
CommunicationServerShutdownAndCleanupConnection(SOCKET ClientSocket,
SOCKET ListenSocket)
{
- int iResult;
+ INT IResult;
//
// No longer need server socket
@@ -226,8 +226,8 @@ CommunicationServerShutdownAndCleanupConnection(SOCKET ClientSocket,
//
// shutdown the connection since we're done
//
- iResult = shutdown(ClientSocket, SD_SEND);
- if (iResult == SOCKET_ERROR)
+ IResult = shutdown(ClientSocket, SD_SEND);
+ if (IResult == SOCKET_ERROR)
{
//
// We comment this line because the connection might be removed;
@@ -295,7 +295,7 @@ CommunicationServerShutdownAndCleanupConnection(SOCKET ClientSocket,
// }
// }
//
-// ShowMessages("close conntection\n");
+// ShowMessages("close connection\n");
//
// //
// // Close the connection
diff --git a/hyperdbg/libhyperdbg/code/debugger/core/break-control.cpp b/hyperdbg/libhyperdbg/code/debugger/core/break-control.cpp
index 8509d265..a703ac8c 100644
--- a/hyperdbg/libhyperdbg/code/debugger/core/break-control.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/core/break-control.cpp
@@ -15,7 +15,7 @@
// Global Variables
//
extern BOOLEAN g_BreakPrintingOutput;
-extern BOOLEAN g_IsDebuggerModulesLoaded;
+extern BOOLEAN g_IsKdModuleLoaded;
extern BOOLEAN g_AutoUnpause;
extern BOOLEAN g_IsConnectedToRemoteDebuggee;
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
@@ -79,7 +79,7 @@ BreakController(DWORD CtrlType)
KdBreakControlCheckAndPauseDebugger(TRUE);
}
}
- else if (!g_IsDebuggerModulesLoaded && !g_IsConnectedToRemoteDebuggee)
+ else if (!g_IsKdModuleLoaded && !g_IsConnectedToRemoteDebuggee)
{
//
// vmm module is not loaded here
diff --git a/hyperdbg/libhyperdbg/code/debugger/core/debugger.cpp b/hyperdbg/libhyperdbg/code/debugger/core/debugger.cpp
index 6a26e969..de827e8c 100644
--- a/hyperdbg/libhyperdbg/code/debugger/core/debugger.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/core/debugger.cpp
@@ -26,6 +26,8 @@ extern BOOLEAN g_IsConnectedToRemoteDebuggee;
extern BOOLEAN g_IsConnectedToRemoteDebugger;
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
extern BOOLEAN g_IsSerialConnectedToRemoteDebugger;
+extern BOOLEAN g_IsKdModuleLoaded;
+extern BOOLEAN g_IsVmmModuleLoaded;
extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
/**
@@ -243,7 +245,8 @@ ShowErrorMessage(UINT32 Error)
break;
case DEBUGGER_ERROR_EPT_COULD_NOT_SPLIT_THE_LARGE_PAGE_TO_4KB_PAGES:
- ShowMessages("err, could not convert 2MB large page to 4KB pages (%x)\n",
+ ShowMessages("err, could not convert 2MB large page to 4KB pages "
+ "(maybe pre-allocated buffers are empty?) (%x)\n",
Error);
break;
@@ -495,7 +498,7 @@ ShowErrorMessage(UINT32 Error)
break;
case DEBUGGER_ERROR_THE_MODE_EXEC_TRAP_IS_NOT_INITIALIZED:
- ShowMessages("err, the '!mode' event command cannot be directly initialized in the Debugger Mode. "
+ ShowMessages("err, for performance reasons, the '!mode' event command cannot be directly initialized in the Debugger Mode. "
"You can use the 'preactivate mode' command to preactivate this mechanism after that, "
"you can use the '!mode' event (%x)\n",
Error);
@@ -553,6 +556,88 @@ ShowErrorMessage(UINT32 Error)
Error);
break;
+ case DEBUGGER_ERROR_INVALID_SMI_OPERATION_PARAMETERS:
+ ShowMessages("err, invalid SMI operation parameter(s) are specified (%x)\n",
+ Error);
+ break;
+
+ case DEBUGGER_ERROR_UNABLE_TO_TRIGGER_SMI:
+ ShowMessages("err, unable to trigger SMI, are you running on a nested-virtualization environment? (%x)\n",
+ Error);
+ break;
+
+ case DEBUGGER_ERROR_UNABLE_TO_APPLY_COMMAND_TO_THE_TARGET_THREAD:
+ ShowMessages("err, unable to apply command to the target thread (%x)\n",
+ Error);
+ break;
+
+ case DEBUGGER_ERROR_HYPERTRACE_NOT_INITIALIZED:
+ ShowMessages("err, the hypertrace module is not loaded and initialized, "
+ "use the 'load trace' command to load the hypertrace module (%x)\n",
+ Error);
+ break;
+
+ case DEBUGGER_ERROR_INVALID_HYPERTRACE_OPERATION_TYPE:
+ ShowMessages("err, invalid hypertrace operation type is specified (%x)\n",
+ Error);
+ break;
+
+ case DEBUGGER_ERROR_LBR_ALREADY_ENABLED:
+ ShowMessages("err, LBR is already enabled, you can disable it using the '!lbr' command (%x)\n",
+ Error);
+ break;
+
+ case DEBUGGER_ERROR_LBR_ALREADY_DISABLED:
+ ShowMessages("err, LBR is already disabled, you can enable it using the '!lbr' command (%x)\n",
+ Error);
+ break;
+
+ case DEBUGGER_ERROR_LBR_NOT_SUPPORTED:
+ ShowMessages("err, LBR is not supported on this processor, this is likely caused by running inside "
+ "a nested virtualization (VM) environment that masks and removes LBR CPU flags (%x)\n",
+ Error);
+ break;
+
+ case DEBUGGER_ERROR_LBR_NOT_SUPPORTED_ON_VMCS:
+ ShowMessages("err, LBR is not supported on VMCS (%x)\n",
+ Error);
+ break;
+
+ case DEBUGGER_ERROR_PT_ALREADY_ENABLED:
+ ShowMessages("err, PT is already enabled (%x)\n",
+ Error);
+ break;
+
+ case DEBUGGER_ERROR_PT_ALREADY_DISABLED:
+ ShowMessages("err, PT is already disabled (%x)\n",
+ Error);
+ break;
+
+ case DEBUGGER_ERROR_PT_NOT_SUPPORTED:
+ ShowMessages("err, PT is not supported on this processor (%x)\n",
+ Error);
+ break;
+
+ case DEBUGGER_ERROR_VMM_CANNOT_BE_INITIALIZED_IF_HYPERTRACE_IS_LOADED:
+ ShowMessages("err, hypertrace is already loaded, please unload hypertrace module using the "
+ "'unload' command and then load the 'VMM' module. Then you can load hypertrace "
+ "after loading the VMM as it is because hypertrace behaves differently to sync "
+ "with VMM modules; it needs to have this notion that it is running within the "
+ "hypervisor, so that is why it needs to be initialized again if the VMM module "
+ "is loaded (%x)\n",
+ Error);
+ break;
+
+ case DEBUGGER_ERROR_VMM_CANNOT_BE_INITIALIZED_IF_DEBUGGER_IS_NOT_LOADED:
+ ShowMessages("err, the VMM module cannot be initialized because the debugger is not loaded (%x)\n",
+ Error);
+ break;
+
+ case DEBUGGER_ERROR_CANNOT_INITIALIZE_DEBUGGER:
+ ShowMessages("err, cannot initialize the debugger (%x)\n",
+ Error);
+ break;
+
default:
ShowMessages("err, error not found (%x)\n",
Error);
@@ -571,6 +656,7 @@ ShowErrorMessage(UINT32 Error)
UINT64
DebuggerGetNtoskrnlBase()
{
+#ifdef _WIN32
UINT64 NtoskrnlBase = NULL;
PRTL_PROCESS_MODULES Modules = NULL;
@@ -582,7 +668,7 @@ DebuggerGetNtoskrnlBase()
for (UINT32 i = 0; i < Modules->NumberOfModules; i++)
{
- if (!strcmp((const char *)Modules->Modules[i].FullPathName + Modules->Modules[i].OffsetToFileName,
+ if (!strcmp((const CHAR *)Modules->Modules[i].FullPathName + Modules->Modules[i].OffsetToFileName,
"ntoskrnl.exe"))
{
NtoskrnlBase = (UINT64)Modules->Modules[i].ImageBase;
@@ -593,6 +679,14 @@ DebuggerGetNtoskrnlBase()
free(Modules);
return NtoskrnlBase;
+#else
+ //
+ // TODO(Linux): NT-style system module enumeration (PRTL_PROCESS_MODULES via
+ // NtQuerySystemInformation) has no Linux analog. The kernel-module base lookup
+ // will need a Linux-specific mechanism once the kernel side exists.
+ //
+ return NULL64_ZERO;
+#endif
}
/**
@@ -634,7 +728,7 @@ DebuggerPauseDebuggee()
//
// Send a pause IOCTL
//
- StatusIoctl = DeviceIoControl(g_DeviceHandle, // Handle to device
+ StatusIoctl = PlatformDeviceIoControl(g_DeviceHandle, // Handle to device
IOCTL_PAUSE_PACKET_RECEIVED, // IO Control Code (IOCTL)
&PauseRequest, // Input Buffer to driver.
SIZEOF_DEBUGGER_PAUSE_PACKET_RECEIVED, // Input buffer
@@ -648,7 +742,7 @@ DebuggerPauseDebuggee()
if (!StatusIoctl)
{
- ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
+ ShowMessages("ioctl failed with code 0x%x\n", PlatformGetLastError());
return FALSE;
}
@@ -863,7 +957,7 @@ InterpretScript(vector * CommandTokens,
//
// Run script engine handler
//
- PVOID CodeBuffer = ScriptEngineParseWrapper((char *)TargetBracketString.c_str(), TRUE);
+ PVOID CodeBuffer = ScriptEngineParseWrapper((CHAR *)TargetBracketString.c_str(), TRUE);
if (CodeBuffer == NULL)
{
@@ -939,11 +1033,11 @@ InterpretConditionsAndCodes(vector * CommandTokens,
string Temp;
vector ParsedBytes;
- vector IndexesToRemove;
+ vector IndexesToRemove;
UCHAR * FinalBuffer;
UINT32 AssembledByteCount;
- int NewIndexToRemove = 0;
- int Index = 0;
+ INT NewIndexToRemove = 0;
+ INT Index = 0;
for (auto Section : *CommandTokens)
{
@@ -1040,7 +1134,7 @@ InterpretConditionsAndCodes(vector * CommandTokens,
//
// * FinalBuffer *
//
- FinalBuffer = (unsigned char *)malloc(AssembledByteCount);
+ FinalBuffer = (UCHAR *)malloc(AssembledByteCount);
if (FinalBuffer == NULL)
{
@@ -1163,12 +1257,12 @@ InterpretOutput(vector * CommandTokens,
BOOLEAN IsTextVisited = FALSE;
string TargetBracketString = "";
- vector IndexesToRemove;
+ vector IndexesToRemove;
string Token;
- int NewIndexToRemove = 0;
- int Index = 0;
- char Delimiter = ',';
- size_t Pos = 0;
+ INT NewIndexToRemove = 0;
+ INT Index = 0;
+ CHAR Delimiter = ',';
+ SIZE_T Pos = 0;
for (auto Section : *CommandTokens)
{
@@ -1300,14 +1394,13 @@ SendEventToKernel(PDEBUGGER_GENERAL_EVENT_DETAIL Event,
//
// It's either a debuggee or a local debugging instance
//
-
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// Send IOCTL
//
- Status = DeviceIoControl(g_DeviceHandle, // Handle to device
+ Status = PlatformDeviceIoControl(g_DeviceHandle, // Handle to device
IOCTL_DEBUGGER_REGISTER_EVENT, // IO Control Code (IOCTL)
Event, // Input Buffer to driver.
EventBufferLength, // Input buffer length
@@ -1324,7 +1417,7 @@ SendEventToKernel(PDEBUGGER_GENERAL_EVENT_DETAIL Event,
if (!Status)
{
- ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
+ ShowMessages("ioctl failed with code 0x%x\n", PlatformGetLastError());
return FALSE;
}
}
@@ -1463,10 +1556,9 @@ RegisterActionToEvent(PDEBUGGER_GENERAL_EVENT_DETAIL Event,
else
{
//
- // It's either a local debugger to in vmi-mode remote conntection
+ // It's either a local debugger to in vmi-mode remote connection
//
-
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// Send IOCTLs
@@ -1477,7 +1569,7 @@ RegisterActionToEvent(PDEBUGGER_GENERAL_EVENT_DETAIL Event,
//
if (ActionBreakToDebugger != NULL)
{
- Status = DeviceIoControl(
+ Status = PlatformDeviceIoControl(
g_DeviceHandle, // Handle to device
IOCTL_DEBUGGER_ADD_ACTION_TO_EVENT, // IO Control Code (IOCTL)
ActionBreakToDebugger, // Input Buffer to driver.
@@ -1495,7 +1587,7 @@ RegisterActionToEvent(PDEBUGGER_GENERAL_EVENT_DETAIL Event,
if (!Status)
{
- ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
+ ShowMessages("ioctl failed with code 0x%x\n", PlatformGetLastError());
return FALSE;
}
}
@@ -1505,7 +1597,7 @@ RegisterActionToEvent(PDEBUGGER_GENERAL_EVENT_DETAIL Event,
//
if (ActionCustomCode != NULL)
{
- Status = DeviceIoControl(
+ Status = PlatformDeviceIoControl(
g_DeviceHandle, // Handle to device
IOCTL_DEBUGGER_ADD_ACTION_TO_EVENT, // IO Control Code (IOCTL)
ActionCustomCode, // Input Buffer to driver.
@@ -1523,7 +1615,7 @@ RegisterActionToEvent(PDEBUGGER_GENERAL_EVENT_DETAIL Event,
if (!Status)
{
- ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
+ ShowMessages("ioctl failed with code 0x%x\n", PlatformGetLastError());
return FALSE;
}
}
@@ -1533,7 +1625,7 @@ RegisterActionToEvent(PDEBUGGER_GENERAL_EVENT_DETAIL Event,
//
if (ActionScript != NULL)
{
- Status = DeviceIoControl(
+ Status = PlatformDeviceIoControl(
g_DeviceHandle, // Handle to device
IOCTL_DEBUGGER_ADD_ACTION_TO_EVENT, // IO Control Code (IOCTL)
ActionScript, // Input Buffer to driver.
@@ -1551,7 +1643,7 @@ RegisterActionToEvent(PDEBUGGER_GENERAL_EVENT_DETAIL Event,
if (!Status)
{
- ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
+ ShowMessages("ioctl failed with code 0x%x\n", PlatformGetLastError());
return FALSE;
}
}
@@ -1693,10 +1785,10 @@ InterpretGeneralEventAndActionsFields(
UINT32 RequestBuffer = 0;
PLIST_ENTRY TempList;
BOOLEAN OutputSourceFound;
- vector IndexesToRemove;
+ vector IndexesToRemove;
vector ListOfValidSourceTags;
- int NewIndexToRemove = 0;
- int Index = 0;
+ INT NewIndexToRemove = 0;
+ INT Index = 0;
//
// Create a command string to show in the history
@@ -1717,7 +1809,7 @@ InterpretGeneralEventAndActionsFields(
//
PVOID BufferOfCommandString = malloc(BufferOfCommandStringLength);
- RtlZeroMemory(BufferOfCommandString, BufferOfCommandStringLength);
+ PlatformZeroMemory(BufferOfCommandString, BufferOfCommandStringLength);
//
// Copy the string to the buffer
@@ -1754,7 +1846,7 @@ InterpretGeneralEventAndActionsFields(
//
// Disassemble the buffer
//
- HyperDbgDisassembler64((unsigned char *)ConditionBufferAddress, 0x0,
+ HyperDbgDisassembler64((UCHAR *)ConditionBufferAddress, 0x0,
ConditionBufferLength);
ShowMessages("}\n\n");
@@ -1794,7 +1886,7 @@ InterpretGeneralEventAndActionsFields(
//
// Disassemble the buffer
//
- HyperDbgDisassembler64((unsigned char *)CodeBufferAddress, 0x0,
+ HyperDbgDisassembler64((UCHAR *)CodeBufferAddress, 0x0,
CodeBufferLength);
ShowMessages("}\n\n");
@@ -2022,7 +2114,7 @@ InterpretGeneralEventAndActionsFields(
LengthOfEventBuffer = sizeof(DEBUGGER_GENERAL_EVENT_DETAIL) + ConditionBufferLength;
TempEvent = (PDEBUGGER_GENERAL_EVENT_DETAIL)malloc(LengthOfEventBuffer);
- RtlZeroMemory(TempEvent, LengthOfEventBuffer);
+ PlatformZeroMemory(TempEvent, LengthOfEventBuffer);
//
// Check if buffer is available
@@ -2056,7 +2148,7 @@ InterpretGeneralEventAndActionsFields(
ShowMessages("notice: as you're debugging a user-mode application, "
"this event will only trigger on your current debugging process "
"(pid:%x). If you want the event from the entire system, "
- "add 'pid all' to the event\n",
+ "add 'pid all' to the event\n\n",
g_ActiveProcessDebuggingState.ProcessId);
TempEvent->ProcessId = g_ActiveProcessDebuggingState.ProcessId;
@@ -2071,11 +2163,6 @@ InterpretGeneralEventAndActionsFields(
//
TempEvent->EventType = EventType;
- //
- // Get the current time
- //
- TempEvent->CreationTime = time(0);
-
//
// Set buffer string command
//
@@ -2109,7 +2196,7 @@ InterpretGeneralEventAndActionsFields(
TempActionCustomCode = (PDEBUGGER_GENERAL_ACTION)malloc(LengthOfCustomCodeActionBuffer);
- RtlZeroMemory(TempActionCustomCode, LengthOfCustomCodeActionBuffer);
+ PlatformZeroMemory(TempActionCustomCode, LengthOfCustomCodeActionBuffer);
memcpy(
(PVOID)((UINT64)TempActionCustomCode + sizeof(DEBUGGER_GENERAL_ACTION)),
@@ -2148,7 +2235,7 @@ InterpretGeneralEventAndActionsFields(
LengthOfScriptActionBuffer = sizeof(DEBUGGER_GENERAL_ACTION) + ScriptBufferLength;
TempActionScript = (PDEBUGGER_GENERAL_ACTION)malloc(LengthOfScriptActionBuffer);
- RtlZeroMemory(TempActionScript, LengthOfScriptActionBuffer);
+ PlatformZeroMemory(TempActionScript, LengthOfScriptActionBuffer);
memcpy((PVOID)((UINT64)TempActionScript + sizeof(DEBUGGER_GENERAL_ACTION)),
(PVOID)ScriptBufferAddress,
@@ -2194,7 +2281,7 @@ InterpretGeneralEventAndActionsFields(
TempActionBreak = (PDEBUGGER_GENERAL_ACTION)malloc(LengthOfBreakActionBuffer);
- RtlZeroMemory(TempActionBreak, LengthOfBreakActionBuffer);
+ PlatformZeroMemory(TempActionBreak, LengthOfBreakActionBuffer);
//
// Set the action Tag
diff --git a/hyperdbg/libhyperdbg/code/debugger/core/interpreter.cpp b/hyperdbg/libhyperdbg/code/debugger/core/interpreter.cpp
index 7c37d0fb..edc0ab52 100644
--- a/hyperdbg/libhyperdbg/code/debugger/core/interpreter.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/core/interpreter.cpp
@@ -16,26 +16,21 @@
//
extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
extern CommandType g_CommandsList;
-
-extern BOOLEAN g_ShouldPreviousCommandBeContinued;
-extern BOOLEAN g_IsCommandListInitialized;
-extern BOOLEAN g_LogOpened;
-extern BOOLEAN g_ExecutingScript;
-extern BOOLEAN g_IsConnectedToHyperDbgLocally;
-extern BOOLEAN g_IsConnectedToRemoteDebuggee;
-extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
-extern BOOLEAN g_IsDebuggeeRunning;
-extern BOOLEAN g_BreakPrintingOutput;
-extern BOOLEAN g_IsInterpreterOnString;
-extern BOOLEAN g_IsInterpreterPreviousCharacterABackSlash;
-extern BOOLEAN g_RtmSupport;
-
-extern UINT32 g_VirtualAddressWidth;
-extern UINT32 g_InterpreterCountOfOpenCurlyBrackets;
-extern ULONG g_CurrentRemoteCore;
-
-extern string g_ServerPort;
-extern string g_ServerIp;
+extern BOOLEAN g_ShouldPreviousCommandBeContinued;
+extern BOOLEAN g_IsCommandListInitialized;
+extern BOOLEAN g_LogOpened;
+extern BOOLEAN g_ExecutingScript;
+extern BOOLEAN g_IsConnectedToRemoteDebuggee;
+extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+extern BOOLEAN g_BreakPrintingOutput;
+extern BOOLEAN g_IsInterpreterOnString;
+extern BOOLEAN g_IsInterpreterPreviousCharacterABackSlash;
+extern BOOLEAN g_RtmSupport;
+extern UINT32 g_VirtualAddressWidth;
+extern UINT32 g_InterpreterCountOfOpenCurlyBrackets;
+extern ULONG g_CurrentRemoteCore;
+extern string g_ServerPort;
+extern string g_ServerIp;
class CommandParser
{
@@ -50,16 +45,16 @@ public:
{
std::vector tokens;
std::string current;
- bool InQuotes = FALSE;
- int IdxBracket = 0;
+ BOOLEAN InQuotes = FALSE;
+ INT IdxBracket = 0;
//
// mainly for removing \ from escaped chars
//
std::string input = ConstInput;
- for (size_t i = 0; i < input.length(); ++i)
+ for (SIZE_T i = 0; i < input.length(); ++i)
{
- char c = input[i];
+ CHAR c = input[i];
if (c == '/') // start comment parse
{
@@ -68,16 +63,16 @@ public:
//
if (!InQuotes)
{
- size_t j = i;
- char c2 = input[++j];
+ SIZE_T j = i;
+ CHAR c2 = input[++j];
if (c2 == '/') // start to look for comments
{
//
// to solve cases like: //"}"
//
- size_t StrLitEnd = 0;
- size_t StrLitBeg = input.find("\"", i);
+ SIZE_T StrLitEnd = 0;
+ SIZE_T StrLitBeg = input.find("\"", i);
if (StrLitBeg != std::string::npos)
{
if (i)
@@ -104,8 +99,8 @@ public:
//
// assuming " }" as the end of a line comment aka //, if we are within {}
//
- bool CmntEndBrkt = false;
- size_t CloseBrktPos = 0;
+ BOOLEAN CmntEndBrkt = FALSE;
+ SIZE_T CloseBrktPos = 0;
if (IdxBracket)
{
//
@@ -131,16 +126,16 @@ public:
CloseBrktPos = std::string::npos;
}
- size_t NewLineSrtPos = input.find("\\n", i); // "\\n" entered by user
+ SIZE_T NewLineSrtPos = input.find("\\n", i); // "\\n" entered by user
if (StrLitBeg && StrLitBeg <= NewLineSrtPos && NewLineSrtPos <= StrLitEnd) // is it within the string literal?
{
NewLineSrtPos = std::string::npos;
}
- size_t NewLineChrPos = input.find('\n', i);
+ SIZE_T NewLineChrPos = input.find('\n', i);
- std::vector PosVec = {CloseBrktPos, NewLineSrtPos, NewLineChrPos};
+ std::vector PosVec = {CloseBrktPos, NewLineSrtPos, NewLineChrPos};
- auto min = *(min_element(PosVec.begin(), PosVec.end())); // see which one occures first
+ auto min = *(min_element(PosVec.begin(), PosVec.end())); // see which one occurs first
if (min != std::string::npos && input[min - 1] != '\\')
{
@@ -167,7 +162,7 @@ public:
}
else
{
- bool IsNewLineEsc = false;
+ BOOLEAN IsNewLineEsc = FALSE;
if (NewLineSrtPos != std::string::npos)
{
IsNewLineEsc = input[NewLineSrtPos - 1] == '\\';
@@ -227,14 +222,14 @@ public:
// fix the escaped newline
if (IsNewLineEsc)
{
- size_t start_pos = 0;
+ SIZE_T start_pos = 0;
while ((start_pos = comment.find("\\\\n", start_pos)) != std::string::npos)
{
comment.replace(start_pos, 3, "\\n");
start_pos += 2; // Handles case where 'to' is a substring of 'from'
}
- IsNewLineEsc = false;
+ IsNewLineEsc = FALSE;
}
//
@@ -256,7 +251,7 @@ public:
}
else if (c2 == '*')
{
- size_t EndPose = input.find("*/", i + 2); // +2 for cases like /*/
+ SIZE_T EndPose = input.find("*/", i + 2); // +2 for cases like /*/
if (EndPose != std::string::npos)
{
@@ -361,7 +356,7 @@ public:
}
}
- if (((c == ' ' && !InQuotes) || c == ' ') && !InQuotes && !IdxBracket) // finding seperator space char // Tab seperator added too
+ if (((c == ' ' && !InQuotes) || c == ' ') && !InQuotes && !IdxBracket) // finding separator space char // Tab separator added too
{
if (!current.empty() && current != " ")
{
@@ -503,10 +498,10 @@ public:
//
// get len of longest string
//
- const int sz = 200; // size
- int g_s1Len = 0, g_s2Len = 0, g_s3Len = 0;
- int s1 = 0, s2 = 0, s3 = 0;
- char LineToPrint1[sz], LineToPrint2[sz], LineToPrint3[sz];
+ const INT sz = 200; // size
+ INT g_s1Len = 0, g_s2Len = 0, g_s3Len = 0;
+ INT s1 = 0, s2 = 0, s3 = 0;
+ CHAR LineToPrint1[sz], LineToPrint2[sz], LineToPrint3[sz];
for (const auto & Token : Tokens)
{
@@ -671,10 +666,10 @@ private:
*
* @return The position of the first difference, or -1 if the strings are equal
*/
-int
-FindDifferencePosition(const char * prsTok, const char * fileTok)
+INT
+FindDifferencePosition(const CHAR * prsTok, const CHAR * fileTok)
{
- int i = 0;
+ INT i = 0;
//
// Loop until a difference is found or until the end of any string is reached
@@ -711,7 +706,7 @@ FindDifferencePosition(const char * prsTok, const char * fileTok)
* @param FailedTokenNum The failed token number (if any)
* @param FailedTokenPosition The failed token position (if any)
*
- * @return BOOLEAN returns true if the command was parsed successfully and false if there was an error
+ * @return BOOLEAN returns TRUE if the command was parsed successfully and FALSE if there was an error
*/
BOOLEAN
HyperDbgTestCommandParser(CHAR * Command,
@@ -947,7 +942,7 @@ HyperDbgInterpreter(CHAR * Command)
// Detect whether it's a .help command or not
//
if (!FirstCommand.compare(".help") || !FirstCommand.compare("help") ||
- !FirstCommand.compare(".hh"))
+ !FirstCommand.compare(".hh") || !FirstCommand.compare("!help"))
{
if (Tokens.size() == 2)
{
@@ -1022,14 +1017,14 @@ HyperDbgInterpreter(CHAR * Command)
* @return VOID
*/
VOID
-InterpreterRemoveComments(char * CommandText)
+InterpreterRemoveComments(CHAR * CommandText)
{
BOOLEAN IsComment = FALSE;
BOOLEAN IsOnBracketString = FALSE;
BOOLEAN IsOnString = FALSE;
UINT32 LengthOfCommand = (UINT32)strlen(CommandText);
- for (size_t i = 0; i < LengthOfCommand; i++)
+ for (SIZE_T i = 0; i < LengthOfCommand; i++)
{
if (IsComment)
{
@@ -1041,7 +1036,7 @@ InterpreterRemoveComments(char * CommandText)
{
if (CommandText[i] != '\0')
{
- memmove((void *)&CommandText[i], (const void *)&CommandText[i + 1], strlen(CommandText) - i);
+ memmove((PVOID)&CommandText[i], (const PVOID)&CommandText[i + 1], strlen(CommandText) - i);
i--;
}
}
@@ -1102,9 +1097,10 @@ HyperDbgShowSignature()
//
// Debugging a special process
//
- ShowMessages("%x:%x u%sHyperDbg> ",
+ ShowMessages("%x:%x %s u%sHyperDbg> ",
g_ActiveProcessDebuggingState.ProcessId,
g_ActiveProcessDebuggingState.ThreadId,
+ g_ActiveProcessDebuggingState.IsPaused ? "(paused)" : "(running)",
g_ActiveProcessDebuggingState.Is32Bit ? "86" : "64");
}
else if (g_IsSerialConnectedToRemoteDebuggee)
@@ -1147,7 +1143,7 @@ CheckMultilineCommand(CHAR * CurrentCommand, BOOLEAN Reset)
CurrentCommandLen = (UINT32)CurrentCommandStr.length();
- for (size_t i = 0; i < CurrentCommandLen; i++)
+ for (SIZE_T i = 0; i < CurrentCommandLen; i++)
{
switch (CurrentCommandStr.at(i))
{
@@ -1235,7 +1231,7 @@ ContinuePreviousCommand()
BOOLEAN Result = g_ShouldPreviousCommandBeContinued;
//
- // We should keep it false for the next command
+ // We should keep it FALSE for the next command
//
g_ShouldPreviousCommandBeContinued = FALSE;
@@ -1299,12 +1295,17 @@ InitializeDebugger()
//
// Set the callback for symbol message handler
//
- ScriptEngineSetTextMessageCallbackWrapper(ShowMessages);
+ //
+ // ShowMessages is passed as PVOID (the callback API stores it in a PVOID and
+ // casts to the concrete fn-ptr type at the invocation site); g++ requires the
+ // explicit function-pointer -> void* cast that MSVC performs implicitly.
+ //
+ ScriptEngineSetTextMessageCallbackWrapper((PVOID)ShowMessages);
//
// Register the CTRL+C and CTRL+BREAK Signals handler
//
- if (!SetConsoleCtrlHandler(BreakController, TRUE))
+ if (!PlatformInstallCtrlHandler(BreakController))
{
ShowMessages("err, when registering CTRL+C and CTRL+BREAK Signals "
"handler\n");
@@ -1344,6 +1345,7 @@ InitializeCommandsDictionary()
g_CommandsList[".help"] = {NULL, &CommandHelpHelp, DEBUGGER_COMMAND_HELP_ATTRIBUTES};
g_CommandsList[".hh"] = {NULL, &CommandHelpHelp, DEBUGGER_COMMAND_HELP_ATTRIBUTES};
g_CommandsList["help"] = {NULL, &CommandHelpHelp, DEBUGGER_COMMAND_HELP_ATTRIBUTES};
+ g_CommandsList["!help"] = {NULL, &CommandHelpHelp, DEBUGGER_COMMAND_HELP_ATTRIBUTES};
g_CommandsList["clear"] = {&CommandCls, &CommandClsHelp, DEBUGGER_COMMAND_CLEAR_ATTRIBUTES};
g_CommandsList[".cls"] = {&CommandCls, &CommandClsHelp, DEBUGGER_COMMAND_CLEAR_ATTRIBUTES};
@@ -1626,6 +1628,16 @@ InitializeCommandsDictionary()
g_CommandsList["!idt"] = {&CommandIdt, &CommandIdtHelp, DEBUGGER_COMMAND_IDT_ATTRIBUTES};
+ g_CommandsList["!smi"] = {&CommandSmi, &CommandSmiHelp, DEBUGGER_COMMAND_SMI_ATTRIBUTES};
+
+ g_CommandsList["!lbr"] = {&CommandLbr, &CommandLbrHelp, DEBUGGER_COMMAND_LBR_ATTRIBUTES};
+
+ g_CommandsList["!lbrdump"] = {&CommandLbrdump, &CommandLbrdumpHelp, DEBUGGER_COMMAND_LBRDUMP_ATTRIBUTES};
+ g_CommandsList["!lbrdmp"] = {&CommandLbrdump, &CommandLbrdumpHelp, DEBUGGER_COMMAND_LBRDUMP_ATTRIBUTES};
+ g_CommandsList["!lbrprint"] = {&CommandLbrdump, &CommandLbrdumpHelp, DEBUGGER_COMMAND_LBRDUMP_ATTRIBUTES};
+
+ g_CommandsList["!pt"] = {&CommandPt, &CommandPtHelp, DEBUGGER_COMMAND_PT_ATTRIBUTES};
+
//
// hwdbg commands
//
@@ -1635,4 +1647,6 @@ InitializeCommandsDictionary()
g_CommandsList["!hwdbg_clock"] = {&CommandHwClk, &CommandHwClkHelp, DEBUGGER_COMMAND_HWDBG_HW_CLK_ATTRIBUTES};
g_CommandsList["!hw"] = {&CommandHw, &CommandHwHelp, DEBUGGER_COMMAND_HWDBG_HW_ATTRIBUTES};
+
+ g_CommandsList["!xsetbv"] = {&CommandXsetbv, &CommandXsetbvHelp, DEBUGGER_COMMAND_XSETBV_ATTRIBUTES};
}
diff --git a/hyperdbg/libhyperdbg/code/debugger/core/steppings.cpp b/hyperdbg/libhyperdbg/code/debugger/core/steppings.cpp
index 6f672666..b48aa019 100644
--- a/hyperdbg/libhyperdbg/code/debugger/core/steppings.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/core/steppings.cpp
@@ -98,11 +98,9 @@ SteppingRegularStepIn()
//
// It's stepping over user debugger
//
- UdSendStepPacketToDebuggee(g_ActiveProcessDebuggingState.ProcessDebuggingToken,
- g_ActiveProcessDebuggingState.ThreadId,
- RequestFormat);
-
- return TRUE;
+ return UdSendStepPacketToDebuggee(g_ActiveProcessDebuggingState.ProcessDebuggingToken,
+ g_ActiveProcessDebuggingState.ThreadId,
+ RequestFormat);
}
else
{
@@ -137,11 +135,9 @@ SteppingStepOver()
//
// It's stepping over user debugger
//
- UdSendStepPacketToDebuggee(g_ActiveProcessDebuggingState.ProcessDebuggingToken,
- g_ActiveProcessDebuggingState.ThreadId,
- RequestFormat);
-
- return TRUE;
+ return UdSendStepPacketToDebuggee(g_ActiveProcessDebuggingState.ProcessDebuggingToken,
+ g_ActiveProcessDebuggingState.ThreadId,
+ RequestFormat);
}
else
{
@@ -184,11 +180,9 @@ SteppingStepOverForGu(BOOLEAN LastInstruction)
//
// It's stepping over user debugger
//
- UdSendStepPacketToDebuggee(g_ActiveProcessDebuggingState.ProcessDebuggingToken,
- g_ActiveProcessDebuggingState.ThreadId,
- RequestFormat);
-
- return TRUE;
+ return UdSendStepPacketToDebuggee(g_ActiveProcessDebuggingState.ProcessDebuggingToken,
+ g_ActiveProcessDebuggingState.ThreadId,
+ RequestFormat);
}
else
{
diff --git a/hyperdbg/libhyperdbg/code/debugger/driver-loader/install.cpp b/hyperdbg/libhyperdbg/code/debugger/driver-loader/install.cpp
index 5a9f858a..0c6e0326 100644
--- a/hyperdbg/libhyperdbg/code/debugger/driver-loader/install.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/driver-loader/install.cpp
@@ -59,7 +59,7 @@ InstallDriver(SC_HANDLE SchSCManager, LPCTSTR DriverName, LPCTSTR ServiceExe)
{
//
// The service is already been created
- // means that, the driver is previosuly installed
+ // means that, the driver is previously installed
//
ShowMessages("the service (driver) already exists\n");
@@ -477,7 +477,7 @@ SetupPathForFileName(const CHAR * FileName,
HANDLE FileHandle;
DWORD FileLocLen = 0;
HMODULE ProcHandle = GetModuleHandle(NULL);
- char * Pos;
+ CHAR * Pos;
//
// Get the current directory.
diff --git a/hyperdbg/libhyperdbg/code/debugger/kernel-level/kd.cpp b/hyperdbg/libhyperdbg/code/debugger/kernel-level/kd.cpp
index 74284c46..4020c620 100644
--- a/hyperdbg/libhyperdbg/code/debugger/kernel-level/kd.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/kernel-level/kd.cpp
@@ -14,19 +14,18 @@
//
// Global Variables
//
-extern PMODULE_SYMBOL_DETAIL g_SymbolTable;
-extern UINT32 g_SymbolTableSize;
-extern UINT32 g_SymbolTableCurrentIndex;
-extern HANDLE g_SerialListeningThreadHandle;
-extern HANDLE g_SerialRemoteComPortHandle;
-extern HANDLE g_DebuggeeStopCommandEventHandle;
+extern HANDLE g_SerialListeningThreadHandle;
+extern HANDLE g_SerialRemoteComPortHandle;
+extern HANDLE g_DebuggeeStopCommandEventHandle;
extern DEBUGGER_SYNCRONIZATION_EVENTS_STATE
g_KernelSyncronizationObjectsHandleTable[DEBUGGER_MAXIMUM_SYNCRONIZATION_KERNEL_DEBUGGER_OBJECTS];
extern BYTE g_CurrentRunningInstruction[MAXIMUM_INSTR_SIZE];
extern BOOLEAN g_IsConnectedToHyperDbgLocally;
+#ifdef _WIN32
extern OVERLAPPED g_OverlappedIoStructureForReadDebugger;
extern OVERLAPPED g_OverlappedIoStructureForWriteDebugger;
extern OVERLAPPED g_OverlappedIoStructureForReadDebuggee;
+#endif // _WIN32
extern DEBUGGER_EVENT_AND_ACTION_RESULT g_DebuggeeResultOfRegisteringEvent;
extern DEBUGGER_EVENT_AND_ACTION_RESULT
g_DebuggeeResultOfAddingActionsToEvent;
@@ -34,7 +33,8 @@ extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
extern BOOLEAN g_IsSerialConnectedToRemoteDebugger;
extern BOOLEAN g_IsDebuggerConntectedToNamedPipe;
extern BOOLEAN g_IsDebuggeeRunning;
-extern BOOLEAN g_IsDebuggerModulesLoaded;
+extern BOOLEAN g_IsKdModuleLoaded;
+extern BOOLEAN g_IsVmmModuleLoaded;
extern BOOLEAN g_SerialConnectionAlreadyClosed;
extern BOOLEAN g_IgnoreNewLoggingMessages;
extern BOOLEAN g_SharedEventStatus;
@@ -100,7 +100,7 @@ KdCheckForTheEndOfTheBuffer(PUINT32 CurrentLoopIndex, BYTE * Buffer)
BOOLEAN
KdCompareBufferWithString(CHAR * Buffer, const CHAR * CompareBuffer)
{
- int Result;
+ INT Result;
Result = strcmp(Buffer, CompareBuffer);
@@ -529,7 +529,7 @@ KdSendReadRegisterPacketToDebuggee(PDEBUGGEE_REGISTER_READ_DESCRIPTION RegDes, U
//
// Set the request data
//
- DbgWaitSetRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_READ_REGISTERS, RegDes, RegBuffSize);
+ DbgWaitSetKernelRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_READ_REGISTERS, RegDes, RegBuffSize);
//
// Send the 'r' command as read register packet
@@ -564,7 +564,7 @@ KdSendWriteRegisterPacketToDebuggee(PDEBUGGEE_REGISTER_WRITE_DESCRIPTION RegDes)
//
// Set the request data
//
- DbgWaitSetRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_WRITE_REGISTER, RegDes, sizeof(DEBUGGEE_REGISTER_WRITE_DESCRIPTION));
+ DbgWaitSetKernelRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_WRITE_REGISTER, RegDes, sizeof(DEBUGGEE_REGISTER_WRITE_DESCRIPTION));
//
// Send write register packet
@@ -599,7 +599,7 @@ KdSendReadMemoryPacketToDebuggee(PDEBUGGER_READ_MEMORY ReadMem, UINT32 RequestSi
//
// Set the request data
//
- DbgWaitSetRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_READ_MEMORY, ReadMem, RequestSize);
+ DbgWaitSetKernelRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_READ_MEMORY, ReadMem, RequestSize);
//
// Send u-d command as read memory packet
@@ -635,7 +635,7 @@ KdSendEditMemoryPacketToDebuggee(PDEBUGGER_EDIT_MEMORY EditMem, UINT32 Size)
//
// Set the request data
//
- DbgWaitSetRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_EDIT_MEMORY, EditMem, sizeof(DEBUGGER_EDIT_MEMORY));
+ DbgWaitSetKernelRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_EDIT_MEMORY, EditMem, sizeof(DEBUGGER_EDIT_MEMORY));
//
// Send d command as read memory packet
@@ -997,7 +997,7 @@ KdSendApicActionPacketsToDebuggee(PDEBUGGER_APIC_REQUEST ApicRequest, UINT32 Exp
//
// Set the request data
//
- DbgWaitSetRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_APIC_ACTIONS, ApicRequest, ExpectedRequestSize);
+ DbgWaitSetKernelRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_APIC_ACTIONS, ApicRequest, ExpectedRequestSize);
//
// Send the APIC request packets
@@ -1020,6 +1020,111 @@ KdSendApicActionPacketsToDebuggee(PDEBUGGER_APIC_REQUEST ApicRequest, UINT32 Exp
return TRUE;
}
+/**
+ * @brief Send requests for SMI operation packet to the debuggee
+ *
+ * @param SmiOperationRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+KdSendSmiPacketsToDebuggee(PSMI_OPERATION_PACKETS SmiOperationRequest, UINT32 ExpectedRequestSize)
+{
+ //
+ // Set the request data
+ //
+ DbgWaitSetKernelRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_SMI_OPERATION_RESULT, SmiOperationRequest, ExpectedRequestSize);
+
+ //
+ // Send the SMI request packets
+ //
+ if (!KdCommandPacketAndBufferToDebuggee(
+ DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_VMX_ROOT,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_PERFORM_SMI_OPERATION,
+ (CHAR *)SmiOperationRequest,
+ SIZEOF_SMI_OPERATION_PACKETS))
+ {
+ return FALSE;
+ }
+
+ //
+ // Wait until the result of actions to SMI is received
+ //
+ DbgWaitForKernelResponse(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_SMI_OPERATION_RESULT);
+
+ return TRUE;
+}
+
+/**
+ * @brief Send requests for HyperTrace LBR dump packet to the debuggee
+ *
+ * @param HyperTraceLbrdumpRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+KdSendHyperTraceLbrdumpPacketsToDebuggee(PHYPERTRACE_LBR_DUMP_PACKETS HyperTraceLbrdumpRequest, UINT32 ExpectedRequestSize)
+{
+ //
+ // Set the request data
+ //
+ DbgWaitSetKernelRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_HYPERTRACE_LBR_DUMP_RESULT, HyperTraceLbrdumpRequest, ExpectedRequestSize);
+
+ //
+ // Send the LBR request packets
+ //
+ if (!KdCommandPacketAndBufferToDebuggee(
+ DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_VMX_ROOT,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_PERFORM_HYPERTRACE_LBR_DUMP,
+ (CHAR *)HyperTraceLbrdumpRequest,
+ SIZEOF_HYPERTRACE_LBR_DUMP_PACKETS))
+ {
+ return FALSE;
+ }
+
+ //
+ // Wait until the result of actions to HyperTrace LBR is received
+ //
+ DbgWaitForKernelResponse(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_HYPERTRACE_LBR_DUMP_RESULT);
+
+ return TRUE;
+}
+
+/**
+ * @brief Send requests for HyperTrace PT operation packet to the debuggee
+ *
+ * @param HyperTracePtOperationRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+KdSendHyperTracePtPacketsToDebuggee(PHYPERTRACE_PT_OPERATION_PACKETS HyperTracePtOperationRequest, UINT32 ExpectedRequestSize)
+{
+ //
+ // Set the request data
+ //
+ DbgWaitSetKernelRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_HYPERTRACE_PT_OPERATION_RESULT, HyperTracePtOperationRequest, ExpectedRequestSize);
+
+ //
+ // Send the PT request packets
+ //
+ if (!KdCommandPacketAndBufferToDebuggee(
+ DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_VMX_ROOT,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_PERFORM_HYPERTRACE_PT_OPERATION,
+ (CHAR *)HyperTracePtOperationRequest,
+ SIZEOF_HYPERTRACE_PT_OPERATION_PACKETS))
+ {
+ return FALSE;
+ }
+
+ //
+ // Wait until the result of actions to HyperTrace PT is received
+ //
+ DbgWaitForKernelResponse(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_HYPERTRACE_PT_OPERATION_RESULT);
+
+ return TRUE;
+}
+
/**
* @brief Send requests for IDT packet to the debuggee
* @param IdtRequest
@@ -1032,9 +1137,9 @@ KdSendQueryIdtPacketsToDebuggee(PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS IdtR
//
// Set the request data
//
- DbgWaitSetRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_IDT_ENTRIES,
- IdtRequest,
- sizeof(INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS));
+ DbgWaitSetKernelRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_IDT_ENTRIES,
+ IdtRequest,
+ sizeof(INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS));
//
// Send the IDT request packets
@@ -1187,7 +1292,7 @@ KdSendScriptPacketToDebuggee(UINT64 BufferAddress, UINT32 BufferLength, UINT32 P
* @return BOOLEAN
*/
BOOLEAN
-KdSendUserInputPacketToDebuggee(const char * Sendbuf, int Len, BOOLEAN IgnoreBreakingAgain)
+KdSendUserInputPacketToDebuggee(const CHAR * Sendbuf, INT Len, BOOLEAN IgnoreBreakingAgain)
{
PDEBUGGEE_USER_INPUT_PACKET UserInputPacket;
UINT32 SizeOfStruct = 0;
@@ -1453,7 +1558,7 @@ BOOLEAN
KdReceivePacketFromDebuggee(CHAR * BufferToSave,
UINT32 * LengthReceived)
{
- char ReadData = NULL; /* temperory Character */
+ CHAR ReadData = NULL; /* temperory Character */
DWORD NoBytesRead = 0; /* Bytes read by ReadFile() */
UINT32 Loop = 0;
@@ -1462,6 +1567,7 @@ KdReceivePacketFromDebuggee(CHAR * BufferToSave,
//
do
{
+#ifdef _WIN32
//
// It's in the debugger
//
@@ -1497,6 +1603,18 @@ KdReceivePacketFromDebuggee(CHAR * BufferToSave,
// Reset event for next try
//
ResetEvent(g_OverlappedIoStructureForReadDebugger.hEvent);
+#else
+ //
+ // Linux: read one byte through the cross-platform serial transport
+ //
+ if (!PlatformSerialReadByte(g_SerialRemoteComPortHandle,
+ &ReadData,
+ &NoBytesRead,
+ PLATFORM_SERIAL_IO_DEBUGGER))
+ {
+ return FALSE;
+ }
+#endif
//
// We already now that the maximum packet size is MaxSerialPacketSize
@@ -1543,10 +1661,11 @@ BOOLEAN
KdReceivePacketFromDebugger(CHAR * BufferToSave,
UINT32 * LengthReceived)
{
- char ReadData = NULL; /* temperory Character */
+ CHAR ReadData = NULL; /* temperory Character */
DWORD NoBytesRead = 0; /* Bytes read by ReadFile() */
UINT32 Loop = 0;
+#ifdef _WIN32
//
// Set the timeout in milliseconds (e.g., 5000 ms = 5 seconds)
//
@@ -1563,12 +1682,14 @@ KdReceivePacketFromDebugger(CHAR * BufferToSave,
Timeouts.WriteTotalTimeoutConstant = 0;
Timeouts.WriteTotalTimeoutMultiplier = 0;
SetCommTimeouts(g_SerialRemoteComPortHandle, &Timeouts);
+#endif
//
// Read data and store in a buffer
//
do
{
+#ifdef _WIN32
//
// It's in the debuggee
//
@@ -1604,6 +1725,19 @@ KdReceivePacketFromDebugger(CHAR * BufferToSave,
// Reset event for next try
//
ResetEvent(g_OverlappedIoStructureForReadDebuggee.hEvent);
+#else
+ //
+ // Linux: read one byte through the cross-platform serial transport
+ // (the 5s read timeout is applied inside the platform layer)
+ //
+ if (!PlatformSerialReadByte(g_SerialRemoteComPortHandle,
+ &ReadData,
+ &NoBytesRead,
+ PLATFORM_SERIAL_IO_DEBUGGEE))
+ {
+ return FALSE;
+ }
+#endif
//
// We already now that the maximum packet size is MaxSerialPacketSize
@@ -1678,6 +1812,7 @@ KdSendPacketToDebuggee(const CHAR * Buffer, UINT32 Length, BOOLEAN SendEndOfBuff
return FALSE;
}
+#ifdef _WIN32
if (g_IsSerialConnectedToRemoteDebugger || g_IsDebuggeeInHandshakingPhase)
{
//
@@ -1743,6 +1878,20 @@ KdSendPacketToDebuggee(const CHAR * Buffer, UINT32 Length, BOOLEAN SendEndOfBuff
//
ResetEvent(g_OverlappedIoStructureForWriteDebugger.hEvent);
}
+#else
+ //
+ // Linux: write through the cross-platform serial transport. The debuggee /
+ // handshaking path is synchronous; the debugger path is overlapped (handled
+ // inside the platform layer).
+ //
+ {
+ BOOLEAN Synchronous = (g_IsSerialConnectedToRemoteDebugger || g_IsDebuggeeInHandshakingPhase);
+ if (!PlatformSerialWrite(g_SerialRemoteComPortHandle, Buffer, Length, Synchronous))
+ {
+ return FALSE;
+ }
+ }
+#endif
Out:
if (SendEndOfBuffer)
@@ -2068,7 +2217,7 @@ KdPrepareSerialConnectionToRemoteSystem(HANDLE SerialHandle,
//
// Initialize the handle table
//
- for (size_t i = 0; i < DEBUGGER_MAXIMUM_SYNCRONIZATION_KERNEL_DEBUGGER_OBJECTS; i++)
+ for (SIZE_T i = 0; i < DEBUGGER_MAXIMUM_SYNCRONIZATION_KERNEL_DEBUGGER_OBJECTS; i++)
{
g_KernelSyncronizationObjectsHandleTable[i].IsOnWaitingState = FALSE;
g_KernelSyncronizationObjectsHandleTable[i].EventHandle =
@@ -2268,7 +2417,7 @@ StartAgain:
// ShowMessages("the answer to the PING request is received: %s\n", ReceivedPingBuildVersionBuffer);
- if (strcmp((const char *)BuildSignature, ReceivedPingBuildVersionBuffer) == 0)
+ if (strcmp((const CHAR *)BuildSignature, ReceivedPingBuildVersionBuffer) == 0)
{
//
// Build version matched
@@ -2327,7 +2476,7 @@ KdPrepareAndConnectDebugPort(const CHAR * PortName,
BOOL Status; /* Status */
DCB SerialParams = {0}; /* Initializing DCB structure */
COMMTIMEOUTS Timeouts = {0}; /* Initializing timeouts structure */
- char PortNo[20] = {0}; /* contain friendly name */
+ CHAR PortNo[20] = {0}; /* contain friendly name */
BOOLEAN StatusIoctl;
ULONG ReturnedLength;
PDEBUGGER_PREPARE_DEBUGGEE DebuggeeRequest;
@@ -2530,7 +2679,7 @@ KdPrepareAndConnectDebugPort(const CHAR * PortName,
//
// Load the VMM
//
- if (HyperDbgInstallVmmDriver() == 1 || HyperDbgLoadVmmModule() == 1)
+ if (HyperDbgInstallKdDriver() == 1 || HyperDbgLoadVmmModule() == 1)
{
CloseHandle(Comm);
g_SerialRemoteComPortHandle = NULL;
@@ -2550,7 +2699,7 @@ KdPrepareAndConnectDebugPort(const CHAR * PortName,
g_SerialRemoteComPortHandle = NULL;
g_IsConnectedToHyperDbgLocally = FALSE;
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
}
//
@@ -2923,7 +3072,7 @@ KdCloseConnection()
//
if (g_IsSerialConnectedToRemoteDebugger)
{
- if (g_IsConnectedToHyperDbgLocally && g_IsDebuggerModulesLoaded)
+ if (g_IsConnectedToHyperDbgLocally && g_IsKdModuleLoaded)
{
//
// The messages (and outputs) should no longer be passed
@@ -2999,7 +3148,7 @@ KdRegisterEventInDebuggee(PDEBUGGER_GENERAL_EVENT_DETAIL EventRegBuffer,
ULONG ReturnedLength;
DEBUGGER_EVENT_AND_ACTION_RESULT ReturnedBuffer = {0};
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// Send IOCTL
@@ -3053,7 +3202,7 @@ KdAddActionToEventInDebuggee(PDEBUGGER_GENERAL_ACTION ActionAddingBuffer,
ULONG ReturnedLength;
DEBUGGER_EVENT_AND_ACTION_RESULT ReturnedBuffer = {0};
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
Status =
DeviceIoControl(g_DeviceHandle, // Handle to device
@@ -3110,7 +3259,7 @@ KdSendModifyEventInDebuggee(PDEBUGGER_MODIFY_EVENTS ModifyEvent, BOOLEAN SendThe
//
// Check if debugger is loaded or not
//
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// Send the request to the kernel
@@ -3364,7 +3513,7 @@ KdUninitializeConnection()
//
// Close synchronization objects
//
- for (size_t i = 0; i < DEBUGGER_MAXIMUM_SYNCRONIZATION_KERNEL_DEBUGGER_OBJECTS; i++)
+ for (SIZE_T i = 0; i < DEBUGGER_MAXIMUM_SYNCRONIZATION_KERNEL_DEBUGGER_OBJECTS; i++)
{
if (g_KernelSyncronizationObjectsHandleTable[i].EventHandle != NULL)
{
diff --git a/hyperdbg/libhyperdbg/code/debugger/kernel-level/kernel-listening.cpp b/hyperdbg/libhyperdbg/code/debugger/kernel-level/kernel-listening.cpp
index 9181344e..3619e430 100644
--- a/hyperdbg/libhyperdbg/code/debugger/kernel-level/kernel-listening.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/kernel-level/kernel-listening.cpp
@@ -15,11 +15,7 @@
//
// Global Variables
//
-extern DEBUGGER_SYNCRONIZATION_EVENTS_STATE
- g_KernelSyncronizationObjectsHandleTable[DEBUGGER_MAXIMUM_SYNCRONIZATION_KERNEL_DEBUGGER_OBJECTS];
extern BYTE g_CurrentRunningInstruction[MAXIMUM_INSTR_SIZE];
-extern OVERLAPPED g_OverlappedIoStructureForReadDebugger;
-extern OVERLAPPED g_OverlappedIoStructureForWriteDebugger;
extern HANDLE g_SerialRemoteComPortHandle;
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
extern BOOLEAN g_IsDebuggeeRunning;
@@ -33,6 +29,8 @@ extern DEBUGGER_EVENT_AND_ACTION_RESULT g_DebuggeeResultOfAddingActionsToEvent;
extern UINT64 g_ResultOfEvaluatedExpression;
extern UINT32 g_ErrorStateOfResultOfEvaluatedExpression;
extern UINT64 g_KernelBaseAddress;
+extern DEBUGGER_SYNCRONIZATION_EVENTS_STATE
+ g_KernelSyncronizationObjectsHandleTable[DEBUGGER_MAXIMUM_SYNCRONIZATION_KERNEL_DEBUGGER_OBJECTS];
/**
* @brief Check if the remote debuggee needs to pause the system
@@ -69,6 +67,9 @@ ListeningSerialPortInDebugger()
PDEBUGGEE_BP_PACKET BpPacket;
PDEBUGGER_SHORT_CIRCUITING_EVENT ShortCircuitingPacket;
PDEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS PtePacket;
+ PSMI_OPERATION_PACKETS SmiOperationPacket;
+ PHYPERTRACE_LBR_DUMP_PACKETS HyperTraceLbrdumpPacket;
+ PHYPERTRACE_PT_OPERATION_PACKETS HyperTracePtOperationPacket;
PDEBUGGER_PAGE_IN_REQUEST PageinPacket;
PDEBUGGER_VA2PA_AND_PA2VA_COMMANDS Va2paPa2vaPacket;
PDEBUGGEE_BP_LIST_OR_MODIFY_PACKET ListOrModifyBreakpointPacket;
@@ -800,7 +801,7 @@ StartAgain:
//
// Get the address and size of the caller
//
- DbgWaitGetRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_READ_REGISTERS, &CallerAddress, &CallerSize);
+ DbgWaitGetKernelRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_READ_REGISTERS, &CallerAddress, &CallerSize);
//
// Copy the memory buffer for the caller
@@ -821,7 +822,7 @@ StartAgain:
//
// Get the address and size of the caller
//
- DbgWaitGetRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_WRITE_REGISTER, &CallerAddress, &CallerSize);
+ DbgWaitGetKernelRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_WRITE_REGISTER, &CallerAddress, &CallerSize);
//
// Copy the memory buffer for the caller
@@ -842,7 +843,7 @@ StartAgain:
//
// Get the address and size of the caller
//
- DbgWaitGetRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_APIC_ACTIONS, &CallerAddress, &CallerSize);
+ DbgWaitGetKernelRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_APIC_ACTIONS, &CallerAddress, &CallerSize);
//
// Copy the memory buffer for the caller
@@ -863,7 +864,7 @@ StartAgain:
//
// Get the address and size of the caller
//
- DbgWaitGetRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_IDT_ENTRIES, &CallerAddress, &CallerSize);
+ DbgWaitGetKernelRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_IDT_ENTRIES, &CallerAddress, &CallerSize);
//
// Copy the memory buffer for the caller
@@ -884,7 +885,7 @@ StartAgain:
//
// Get the address and size of the caller
//
- DbgWaitGetRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_READ_MEMORY, &CallerAddress, &CallerSize);
+ DbgWaitGetKernelRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_READ_MEMORY, &CallerAddress, &CallerSize);
//
// Copy the memory buffer for the caller
@@ -905,7 +906,7 @@ StartAgain:
//
// Get the address and size of the caller
//
- DbgWaitGetRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_EDIT_MEMORY, &CallerAddress, &CallerSize);
+ DbgWaitGetKernelRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_EDIT_MEMORY, &CallerAddress, &CallerSize);
//
// Copy the memory buffer for the caller
@@ -984,6 +985,69 @@ StartAgain:
break;
+ case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_SMI_OPERATION_REQUESTS:
+
+ SmiOperationPacket = (SMI_OPERATION_PACKETS *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
+
+ //
+ // Get the address and size of the caller
+ //
+ DbgWaitGetKernelRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_SMI_OPERATION_RESULT, &CallerAddress, &CallerSize);
+
+ //
+ // Copy the memory buffer for the caller
+ //
+ memcpy(CallerAddress, SmiOperationPacket, CallerSize);
+
+ //
+ // Signal the event relating to receiving result of SMI operation
+ //
+ DbgReceivedKernelResponse(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_SMI_OPERATION_RESULT);
+
+ break;
+
+ case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_HYPERTRACE_LBR_DUMP_REQUESTS:
+
+ HyperTraceLbrdumpPacket = (HYPERTRACE_LBR_DUMP_PACKETS *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
+
+ //
+ // Get the address and size of the caller
+ //
+ DbgWaitGetKernelRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_HYPERTRACE_LBR_DUMP_RESULT, &CallerAddress, &CallerSize);
+
+ //
+ // Copy the memory buffer for the caller
+ //
+ memcpy(CallerAddress, HyperTraceLbrdumpPacket, CallerSize);
+
+ //
+ // Signal the event relating to receiving result of HyperTrace LBR dump
+ //
+ DbgReceivedKernelResponse(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_HYPERTRACE_LBR_DUMP_RESULT);
+
+ break;
+
+ case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_HYPERTRACE_PT_OPERATION_REQUESTS:
+
+ HyperTracePtOperationPacket = (HYPERTRACE_PT_OPERATION_PACKETS *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
+
+ //
+ // Get the address and size of the caller
+ //
+ DbgWaitGetKernelRequestData(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_HYPERTRACE_PT_OPERATION_RESULT, &CallerAddress, &CallerSize);
+
+ //
+ // Copy the memory buffer for the caller
+ //
+ memcpy(CallerAddress, HyperTracePtOperationPacket, CallerSize);
+
+ //
+ // Signal the event relating to receiving result of HyperTrace PT operation
+ //
+ DbgReceivedKernelResponse(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_HYPERTRACE_PT_OPERATION_RESULT);
+
+ break;
+
case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_BRINGING_PAGES_IN:
PageinPacket = (DEBUGGER_PAGE_IN_REQUEST *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
@@ -1132,8 +1196,8 @@ StartAgain:
if (PcidevinfoPacket->KernelStatus == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
{
// For some reason, MSVC refuses to initialize these at top of case
- const char * PciHeaderTypeAsString[] = {"Endpoint", "PCI-to-PCI Bridge", "PCI-to-CardBus Bridge"};
- const char * PciMmioBarTypeAsString[] = {"32-bit Wide",
+ const CHAR * PciHeaderTypeAsString[] = {"Endpoint", "PCI-to-PCI Bridge", "PCI-to-CardBus Bridge"};
+ const CHAR * PciMmioBarTypeAsString[] = {"32-bit Wide",
"Reserved",
"64-bit Wide",
"Reserved"};
@@ -1314,7 +1378,7 @@ StartAgain:
// Replace non-printable characters with "."
for (UINT8 j = 0; j < 16; j++)
{
- char c = (char)*(cs + j);
+ CHAR c = (CHAR) * (cs + j);
if (c >= 32 && c <= 126)
{
ShowMessages("%c", c);
@@ -1375,7 +1439,7 @@ ListeningSerialPortInDebuggee()
StartAgain:
BOOL Status; /* Status */
- char SerialBuffer[MaxSerialPacketSize] = {
+ CHAR SerialBuffer[MaxSerialPacketSize] = {
0}; /* Buffer to send and receive data */
DWORD EventMask = 0; /* Event mask to trigger */
char ReadData = NULL; /* temperory Character */
diff --git a/hyperdbg/libhyperdbg/code/debugger/misc/assembler.cpp b/hyperdbg/libhyperdbg/code/debugger/misc/assembler.cpp
index 390e14ef..8c8990ee 100644
--- a/hyperdbg/libhyperdbg/code/debugger/misc/assembler.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/misc/assembler.cpp
@@ -36,7 +36,7 @@ AssembleData::ParseAssemblyData()
// split assembly line by ';'
//
std::vector AssemblyInstructions;
- size_t Pos = 0;
+ SIZE_T Pos = 0;
std::string Delimiter = ";";
while ((Pos = RawAsm.find(Delimiter)) != std::string::npos)
{
@@ -59,11 +59,11 @@ AssembleData::ParseAssemblyData()
{
std::string Expr {};
UINT64 ExprAddr {};
- size_t Start {};
+ SIZE_T Start {};
while ((Start = InstructionLine.find('<', Start)) != std::string::npos)
{
- size_t End = InstructionLine.find('>', Start);
+ SIZE_T End = InstructionLine.find('>', Start);
if (End != std::string::npos)
{
std::string Expr = InstructionLine.substr(Start + 1, End - Start - 1);
@@ -160,7 +160,7 @@ AssembleData::Assemble(UINT64 StartAddr, ks_arch Arch, INT Mode, INT Syntax)
{
ShowMessages("generated assembly: %lu (decimal) bytes, %lu (decimal) statements ==>> ", (int)BytesCount, (int)StatementCount);
- size_t i;
+ SIZE_T i;
ShowMessages("%s = ", AsmFixed.c_str());
for (i = 0; i < BytesCount; i++)
{
diff --git a/hyperdbg/libhyperdbg/code/debugger/misc/callstack.cpp b/hyperdbg/libhyperdbg/code/debugger/misc/callstack.cpp
index cd14ddeb..729c592f 100644
--- a/hyperdbg/libhyperdbg/code/debugger/misc/callstack.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/misc/callstack.cpp
@@ -98,7 +98,7 @@ CallstackReturnAddressToCallingAddress(UCHAR * ReturnAddress, PUINT32 IndexOfCal
// The mask of F8 is used because we want to mask out the bottom
// three bits (which are most often used for register selection)
//
- const unsigned char RmMask = 0xF8;
+ const UCHAR RmMask = 0xF8;
//
// 7-byte format:
@@ -223,7 +223,7 @@ CallstackShowFrames(PDEBUGGER_SINGLE_CALLSTACK_FRAME CallstackFrames,
//
// Print callstack frames
//
- for (size_t i = 0; i < FrameCount; i++)
+ for (SIZE_T i = 0; i < FrameCount; i++)
{
IsCall = FALSE;
@@ -233,7 +233,7 @@ CallstackShowFrames(PDEBUGGER_SINGLE_CALLSTACK_FRAME CallstackFrames,
// Check if it's call or just a simple code address
//
if (CallstackFrames[i].IsExecutable && CallstackReturnAddressToCallingAddress(
- (unsigned char *)&CallstackFrames[i].InstructionBytesOnRip[MAXIMUM_CALL_INSTR_SIZE],
+ (UCHAR *)&CallstackFrames[i].InstructionBytesOnRip[MAXIMUM_CALL_INSTR_SIZE],
&CallLength))
{
//
diff --git a/hyperdbg/libhyperdbg/code/debugger/misc/disassembler.cpp b/hyperdbg/libhyperdbg/code/debugger/misc/disassembler.cpp
index d6d2aa75..edd85b69 100644
--- a/hyperdbg/libhyperdbg/code/debugger/misc/disassembler.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/misc/disassembler.cpp
@@ -55,7 +55,7 @@ typedef struct ZydisSymbol_
/**
* @brief The symbol name.
*/
- const char * name;
+ const CHAR * name;
} ZydisSymbol;
ZydisFormatterFunc default_print_address_absolute;
@@ -120,13 +120,13 @@ DisassembleBuffer(ZydisDecoder * decoder,
ZyanU64 runtime_address,
ZyanU8 * data,
ZyanUSize length,
- uint32_t maximum_instr,
+ UINT32 maximum_instr,
BOOLEAN is_x86_64,
BOOLEAN show_of_branch_is_taken,
PRFLAGS rflags)
{
ZydisFormatter formatter;
- int instr_decoded = 0;
+ INT InstrDecoded = 0;
UINT64 UsedBaseAddress = NULL;
if (g_DisassemblerSyntax == 1)
@@ -160,7 +160,7 @@ DisassembleBuffer(ZydisDecoder * decoder,
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT];
ZydisDecodedInstruction instruction;
- char buffer[256];
+ CHAR buffer[256];
while (ZYAN_SUCCESS(ZydisDecoderDecodeFull(decoder, data, length, &instruction, operands)))
{
@@ -192,7 +192,7 @@ DisassembleBuffer(ZydisDecoder * decoder,
//
// Show the memory for this instruction
//
- for (size_t i = 0; i < instruction.length; i++)
+ for (SIZE_T i = 0; i < instruction.length; i++)
{
ZyanU8 MemoryContent = data[i];
ShowMessages(" %02X", MemoryContent);
@@ -203,7 +203,7 @@ DisassembleBuffer(ZydisDecoder * decoder,
#define PaddingLength 12
if (instruction.length < PaddingLength)
{
- for (size_t i = 0; i < PaddingLength - instruction.length; i++)
+ for (SIZE_T i = 0; i < PaddingLength - instruction.length; i++)
{
ShowMessages(" ");
}
@@ -253,9 +253,9 @@ DisassembleBuffer(ZydisDecoder * decoder,
data += instruction.length;
length -= instruction.length;
runtime_address += instruction.length;
- instr_decoded++;
+ InstrDecoded++;
- if (instr_decoded == maximum_instr)
+ if (InstrDecoded == maximum_instr)
{
return;
}
@@ -265,9 +265,9 @@ DisassembleBuffer(ZydisDecoder * decoder,
/**
* @brief Zydis test
*
- * @return int
+ * @return INT
*/
-int
+INT
ZydisTest()
{
if (ZydisGetVersion() != ZYDIS_VERSION)
@@ -327,15 +327,15 @@ ZydisTest()
* @param Rflags in the case ShowBranchIsTakenOrNot is true, we use this
* variable to show the result of jump
*
- * @return int
+ * @return INT
*/
-int
-HyperDbgDisassembler64(unsigned char * BufferToDisassemble,
- UINT64 BaseAddress,
- UINT64 Size,
- UINT32 MaximumInstrDecoded,
- BOOLEAN ShowBranchIsTakenOrNot,
- PRFLAGS Rflags)
+INT
+HyperDbgDisassembler64(UCHAR * BufferToDisassemble,
+ UINT64 BaseAddress,
+ UINT64 Size,
+ UINT32 MaximumInstrDecoded,
+ BOOLEAN ShowBranchIsTakenOrNot,
+ PRFLAGS Rflags)
{
if (ZydisGetVersion() != ZYDIS_VERSION)
{
@@ -367,15 +367,15 @@ HyperDbgDisassembler64(unsigned char * BufferToDisassemble,
* @param Rflags in the case ShowBranchIsTakenOrNot is true, we use this
* variable to show the result of jump
*
- * @return int
+ * @return INT
*/
-int
-HyperDbgDisassembler32(unsigned char * BufferToDisassemble,
- UINT64 BaseAddress,
- UINT64 Size,
- UINT32 MaximumInstrDecoded,
- BOOLEAN ShowBranchIsTakenOrNot,
- PRFLAGS Rflags)
+INT
+HyperDbgDisassembler32(UCHAR * BufferToDisassemble,
+ UINT64 BaseAddress,
+ UINT64 Size,
+ UINT32 MaximumInstrDecoded,
+ BOOLEAN ShowBranchIsTakenOrNot,
+ PRFLAGS Rflags)
{
if (ZydisGetVersion() != ZYDIS_VERSION)
{
@@ -407,16 +407,16 @@ HyperDbgDisassembler32(unsigned char * BufferToDisassemble,
* @return DEBUGGER_NEXT_INSTRUCTION_FINDER_STATUS
*/
DEBUGGER_CONDITIONAL_JUMP_STATUS
-HyperDbgIsConditionalJumpTaken(unsigned char * BufferToDisassemble,
- UINT64 BuffLength,
- RFLAGS Rflags,
- BOOLEAN Isx86_64)
+HyperDbgIsConditionalJumpTaken(UCHAR * BufferToDisassemble,
+ UINT64 BuffLength,
+ RFLAGS Rflags,
+ BOOLEAN Isx86_64)
{
ZydisDecoder decoder;
ZydisFormatter formatter;
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT];
- UINT64 CurrentRip = 0;
- int instr_decoded = 0;
+ UINT64 CurrentRip = 0;
+ INT InstrDecoded = 0;
ZydisDecodedInstruction instruction;
UINT32 MaximumInstrDecoded = 1;
@@ -753,18 +753,18 @@ HyperDbgIsConditionalJumpTaken(unsigned char * BufferToDisassemble,
*/
BOOLEAN
HyperDbgCheckWhetherTheCurrentInstructionIsCall(
- unsigned char * BufferToDisassemble,
- UINT64 BuffLength,
- BOOLEAN Isx86_64,
- PUINT32 CallLength)
+ UCHAR * BufferToDisassemble,
+ UINT64 BuffLength,
+ BOOLEAN Isx86_64,
+ PUINT32 CallLength)
{
ZydisDecoder decoder;
ZydisFormatter formatter;
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT];
- UINT64 CurrentRip = 0;
- int instr_decoded = 0;
+ UINT64 CurrentRip = 0;
+ INT InstrDecoded = 0;
ZydisDecodedInstruction instruction;
- char buffer[256];
+ CHAR buffer[256];
UINT32 MaximumInstrDecoded = 1;
//
@@ -854,15 +854,15 @@ HyperDbgCheckWhetherTheCurrentInstructionIsCall(
*/
UINT32
HyperDbgLengthDisassemblerEngine(
- unsigned char * BufferToDisassemble,
- UINT64 BuffLength,
- BOOLEAN Isx86_64)
+ UCHAR * BufferToDisassemble,
+ UINT64 BuffLength,
+ BOOLEAN Isx86_64)
{
ZydisDecoder decoder;
ZydisFormatter formatter;
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT];
- UINT64 CurrentRip = 0;
- int instr_decoded = 0;
+ UINT64 CurrentRip = 0;
+ INT InstrDecoded = 0;
ZydisDecodedInstruction instruction;
UINT32 MaximumInstrDecoded = 1;
@@ -981,18 +981,18 @@ ZydisFormatterPrintAddressAbsoluteForTrackingInstructions(const ZydisFormatter *
*/
BOOLEAN
HyperDbgCheckWhetherTheCurrentInstructionIsCallOrRet(
- unsigned char * BufferToDisassemble,
- UINT64 CurrentRip,
- UINT32 BuffLength,
- BOOLEAN Isx86_64,
- PBOOLEAN IsRet)
+ UCHAR * BufferToDisassemble,
+ UINT64 CurrentRip,
+ UINT32 BuffLength,
+ BOOLEAN Isx86_64,
+ PBOOLEAN IsRet)
{
ZydisDecoder decoder;
ZydisFormatter formatter;
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT];
- int instr_decoded = 0;
+ INT InstrDecoded = 0;
ZydisDecodedInstruction instruction;
- char buffer[256];
+ CHAR buffer[256];
UINT32 MaximumInstrDecoded = 1;
if (ZydisGetVersion() != ZYDIS_VERSION)
@@ -1093,17 +1093,17 @@ HyperDbgCheckWhetherTheCurrentInstructionIsCallOrRet(
*/
BOOLEAN
HyperDbgCheckWhetherTheCurrentInstructionIsRet(
- unsigned char * BufferToDisassemble,
- UINT64 BuffLength,
- BOOLEAN Isx86_64)
+ UCHAR * BufferToDisassemble,
+ UINT64 BuffLength,
+ BOOLEAN Isx86_64)
{
ZydisDecoder decoder;
ZydisFormatter formatter;
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT];
- UINT64 CurrentRip = 0;
- int instr_decoded = 0;
+ UINT64 CurrentRip = 0;
+ INT InstrDecoded = 0;
ZydisDecodedInstruction instruction;
- char buffer[256];
+ CHAR buffer[256];
UINT32 MaximumInstrDecoded = 1;
if (ZydisGetVersion() != ZYDIS_VERSION)
@@ -1182,17 +1182,17 @@ HyperDbgCheckWhetherTheCurrentInstructionIsRet(
*/
UINT32
HyperDbgGetImmediateValueOnEaxForSyscallNumber(
- unsigned char * BufferToDisassemble,
- UINT64 BuffLength,
- BOOLEAN Isx86_64)
+ UCHAR * BufferToDisassemble,
+ UINT64 BuffLength,
+ BOOLEAN Isx86_64)
{
ZydisDecoder decoder;
ZydisFormatter formatter;
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT];
- UINT64 CurrentRip = 0;
- int instr_decoded = 0;
+ UINT64 CurrentRip = 0;
+ INT InstrDecoded = 0;
ZydisDecodedInstruction instruction;
- char buffer[256];
+ CHAR buffer[256];
UINT32 MaximumInstrDecoded = 1;
if (ZydisGetVersion() != ZYDIS_VERSION)
diff --git a/hyperdbg/libhyperdbg/pci-id.cpp b/hyperdbg/libhyperdbg/code/debugger/misc/pci-id.cpp
similarity index 88%
rename from hyperdbg/libhyperdbg/pci-id.cpp
rename to hyperdbg/libhyperdbg/code/debugger/misc/pci-id.cpp
index 11db8e39..d6fef971 100644
--- a/hyperdbg/libhyperdbg/pci-id.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/misc/pci-id.cpp
@@ -1,6 +1,6 @@
/**
* @file pci-id.cpp
- * @author Bjrn Ruytenberg (bjorn@bjornweb.nl)
+ * @author Bj�rn Ruytenberg (bjorn@bjornweb.nl)
* @brief Provides runtime access to PCI ID database
* @details
* @version 0.12
@@ -11,19 +11,19 @@
*/
#include "pch.h"
-static char * PciIdDatabaseBuffer = NULL;
+static CHAR * PciIdDatabaseBuffer = NULL;
/**
* @brief Trims whitespaces in passed string
*
* @param Str
* @param MaxLen
- * @return char *
+ * @return CHAR*
*/
-char *
-TrimWhitespace(char * Str, UINT8 MaxLen)
+CHAR *
+TrimWhitespace(CHAR * Str, UINT8 MaxLen)
{
- char * End;
+ CHAR * End;
while (*Str == ' ')
Str++; // Trim leading space
if (*Str == '\0')
@@ -39,13 +39,13 @@ TrimWhitespace(char * Str, UINT8 MaxLen)
* @brief Converts passed string to lowercase
*
* @param Str
- * @return char *
+ * @return CHAR*
*/
-char *
-ToLower(char * Str)
+CHAR *
+ToLower(CHAR * Str)
{
UINT8 StrLength = (UINT8)strnlen_s(Str, PCI_ID_AS_STR_LENGTH);
- char * CurrentChar = Str;
+ CHAR * CurrentChar = Str;
while (CurrentChar < Str + StrLength)
{
@@ -61,12 +61,12 @@ ToLower(char * Str)
* @param DestBuffer
* @param CharLimit
* @param SrcBuffer
- * @return char *
+ * @return CHAR*
*/
-char *
-ReadLine(char * DestBuffer, UINT64 CharLimit, char ** SrcBuffer)
+CHAR *
+ReadLine(CHAR * DestBuffer, UINT64 CharLimit, CHAR ** SrcBuffer)
{
- char * Line = strchr(*SrcBuffer, '\n');
+ CHAR * Line = strchr(*SrcBuffer, '\n');
if (!Line)
{
return NULL;
@@ -87,19 +87,19 @@ ReadLine(char * DestBuffer, UINT64 CharLimit, char ** SrcBuffer)
* @return Vendor *
*/
Vendor *
-GetVendorByIdStr(const char * Filename, const char * VendorId)
+GetVendorByIdStr(const CHAR * Filename, const CHAR * VendorId)
{
Vendor * MatchedVendor = NULL;
BOOLEAN FoundVendorId = FALSE;
Device * LastDevice = NULL;
SubDevice * LastSubDevice = NULL;
- char * PciIdDbBufPtr = NULL;
- char Line[1024] = {'\0'};
+ CHAR * PciIdDbBufPtr = NULL;
+ CHAR Line[1024] = {'\0'};
if (!PciIdDatabaseBuffer)
{
FILE * f = fopen(Filename, "rb");
- size_t Length = 0;
+ SIZE_T Length = 0;
if (f == NULL)
{
@@ -110,7 +110,7 @@ GetVendorByIdStr(const char * Filename, const char * VendorId)
fseek(f, 0, SEEK_END);
Length = ftell(f);
- PciIdDatabaseBuffer = (char *)malloc(Length);
+ PciIdDatabaseBuffer = (CHAR *)malloc(Length);
if (!PciIdDatabaseBuffer)
{
return NULL;
@@ -125,7 +125,7 @@ GetVendorByIdStr(const char * Filename, const char * VendorId)
while (ReadLine(Line, sizeof(Line), &PciIdDbBufPtr) != NULL)
{
- char FormatStr[24];
+ CHAR FormatStr[24];
// Skip comments and empty lines
if (Line[0] == '#' || Line[0] == '\0')
@@ -137,7 +137,7 @@ GetVendorByIdStr(const char * Filename, const char * VendorId)
// We assume PCI ID database comprises unique entries only, i.e. we return the first matching entry
if (Line[0] != '\t' && FoundVendorId == FALSE)
{
- char VendorBuf[PCI_ID_AS_STR_LENGTH + 1], VendorNameBuf[PCI_NAME_STR_LENGTH + 1];
+ CHAR VendorBuf[PCI_ID_AS_STR_LENGTH + 1], VendorNameBuf[PCI_NAME_STR_LENGTH + 1];
snprintf(FormatStr, sizeof(FormatStr), "%%4s %%%d[^\n]", PCI_NAME_STR_LENGTH); // FormatStr = "%4s %PCI_NAME_STR_LENGTH[^\n]"
if (sscanf(Line, FormatStr, VendorBuf, VendorNameBuf) == 2)
@@ -150,8 +150,8 @@ GetVendorByIdStr(const char * Filename, const char * VendorId)
return NULL;
}
- int result = sscanf(VendorBuf, "%hx", &(MatchedVendor->VendorId));
- if (result != 1)
+ INT Result = sscanf(VendorBuf, "%hx", &(MatchedVendor->VendorId));
+ if (Result != 1)
{
return NULL;
}
@@ -163,7 +163,7 @@ GetVendorByIdStr(const char * Filename, const char * VendorId)
// Get all devices for vendor
else if (Line[0] == '\t' && Line[1] != '\t' && FoundVendorId == TRUE)
{
- char DeviceBuf[PCI_ID_AS_STR_LENGTH + 1], DeviceNameBuf[PCI_NAME_STR_LENGTH + 1];
+ CHAR DeviceBuf[PCI_ID_AS_STR_LENGTH + 1], DeviceNameBuf[PCI_NAME_STR_LENGTH + 1];
snprintf(FormatStr, sizeof(FormatStr), "%%4s %%%d[^\n]", PCI_NAME_STR_LENGTH); // FormatStr = "%4s %PCI_NAME_STR_LENGTH[^\n]"
if (sscanf(Line + 1, FormatStr, DeviceBuf, DeviceNameBuf) == 2)
@@ -201,7 +201,7 @@ GetVendorByIdStr(const char * Filename, const char * VendorId)
// Get all subdevices for device
else if (Line[0] == '\t' && Line[1] == '\t' && FoundVendorId == TRUE && LastDevice)
{
- char SubVendorBuf[PCI_ID_AS_STR_LENGTH + 1], SubDeviceBuf[PCI_ID_AS_STR_LENGTH + 1], SubsystemNameBuf[PCI_NAME_STR_LENGTH + 1];
+ CHAR SubVendorBuf[PCI_ID_AS_STR_LENGTH + 1], SubDeviceBuf[PCI_ID_AS_STR_LENGTH + 1], SubsystemNameBuf[PCI_NAME_STR_LENGTH + 1];
snprintf(FormatStr, sizeof(FormatStr), "%%4s %%4s %%%d[^\n]", PCI_NAME_STR_LENGTH); // FormatStr = "%4s %4s %PCI_NAME_STR_LENGTH[^\n]"
if (sscanf(Line + 2, FormatStr, SubVendorBuf, SubDeviceBuf, SubsystemNameBuf) == 3)
@@ -254,9 +254,9 @@ GetVendorByIdStr(const char * Filename, const char * VendorId)
* @brief Frees Vendor and all of its members
*
* @param VendorToFree
- * @return void
+ * @return VOID
*/
-void
+VOID
FreeVendor(Vendor * VendorToFree)
{
if (VendorToFree == NULL)
@@ -269,9 +269,9 @@ FreeVendor(Vendor * VendorToFree)
while (CurrentSubDevice)
{
- SubDevice * nextSubDevice = CurrentSubDevice->Next;
+ SubDevice * NextSubDevice = CurrentSubDevice->Next;
free(CurrentSubDevice);
- CurrentSubDevice = nextSubDevice;
+ CurrentSubDevice = NextSubDevice;
}
Device * NextDevice = CurrentDevice->Next;
@@ -282,9 +282,9 @@ FreeVendor(Vendor * VendorToFree)
/**
* @brief Frees PciIdDatabaseBuffer
- * @return void
+ * @return VOID
*/
-void
+VOID
FreePciIdDatabase()
{
if (PciIdDatabaseBuffer != NULL)
@@ -304,15 +304,15 @@ FreePciIdDatabase()
Vendor *
GetVendorById(UINT16 VendorId)
{
- char VendorIdAsStr[5];
- char ExecutablePath[MAX_PATH];
+ CHAR VendorIdAsStr[5];
+ CHAR ExecutablePath[MAX_PATH];
HMODULE hModule = GetModuleHandle(NULL);
snprintf(VendorIdAsStr, sizeof(VendorIdAsStr), "%04X", VendorId);
GetModuleFileName(hModule, ExecutablePath, sizeof(ExecutablePath));
// Extract executable name
- char * ExecutableName = strrchr(ExecutablePath, '\\');
+ CHAR * ExecutableName = strrchr(ExecutablePath, '\\');
if (ExecutableName != NULL)
{
ExecutableName++;
diff --git a/hyperdbg/libhyperdbg/code/debugger/misc/pt-helper.cpp b/hyperdbg/libhyperdbg/code/debugger/misc/pt-helper.cpp
new file mode 100644
index 00000000..6f80b752
--- /dev/null
+++ b/hyperdbg/libhyperdbg/code/debugger/misc/pt-helper.cpp
@@ -0,0 +1,432 @@
+/**
+ * @file pt-help.cpp
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief PT helper functions
+ * @details
+ * @version 0.21
+ * @date 2026-07-03
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief Read the process image for PT decoding
+ *
+ * @param Buffer
+ * @param Size
+ * @param Asid
+ * @param Ip
+ * @param Context
+ *
+ * @return int
+ */
+int
+PtHelperReadImage(UINT8 * Buffer, SIZE_T Size, const struct pt_asid * Asid, UINT64 Ip, VOID * Context)
+{
+ (VOID) Asid;
+
+ IMAGE_SYMBOL_CONTEXT * Ctx = (IMAGE_SYMBOL_CONTEXT *)Context;
+
+ if (Ctx == NULL || Ctx->Code == NULL || Ip < Ctx->CodeBase || Ip >= Ctx->CodeBase + Ctx->CodeSize)
+ return -pte_nomap;
+
+ UINT64 Available = Ctx->CodeBase + Ctx->CodeSize - Ip;
+ SIZE_T Count = (Size < Available) ? Size : (SIZE_T)Available;
+
+ memcpy(Buffer, Ctx->Code + (Ip - Ctx->CodeBase), Count);
+ return (int)Count;
+}
+
+/**
+ * @brief Capture the .text section of a process image
+ *
+ * @param Process
+ * @param TextStart
+ * @param TextEnd
+ * @param Ctx
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+PtHelperCaptureImage(HANDLE Process, UINT64 * TextStart, UINT64 * TextEnd, IMAGE_SYMBOL_CONTEXT * Ctx)
+{
+ HMODULE Ntdll = GetModuleHandleA("ntdll.dll");
+ PFN_NT_QIP NtQip = Ntdll ? (PFN_NT_QIP)GetProcAddress(Ntdll, "NtQueryInformationProcess") : NULL;
+ PROC_BASIC_INFO Pbi = {0};
+ ULONG Ret = 0;
+ SIZE_T Got = 0;
+ UINT64 Base = 0;
+ IMAGE_DOS_HEADER Dos;
+ IMAGE_NT_HEADERS64 Nt;
+ UINT64 SectionBase;
+
+ if (NtQip == NULL || NtQip(Process, 0, &Pbi, sizeof(Pbi), &Ret) < 0 || Pbi.PebBaseAddress == NULL)
+ return FALSE;
+
+ if (!ReadProcessMemory(Process, (PBYTE)Pbi.PebBaseAddress + 0x10, &Base, sizeof(Base), &Got) || Base == 0)
+ return FALSE;
+
+ if (!ReadProcessMemory(Process, (PVOID)Base, &Dos, sizeof(Dos), &Got) || Dos.e_magic != IMAGE_DOS_SIGNATURE)
+ return FALSE;
+
+ if (!ReadProcessMemory(Process, (PBYTE)Base + Dos.e_lfanew, &Nt, sizeof(Nt), &Got) || Nt.Signature != IMAGE_NT_SIGNATURE)
+ return FALSE;
+
+ Ctx->ImageBase = Base;
+ SectionBase = Base + Dos.e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS64, OptionalHeader) + Nt.FileHeader.SizeOfOptionalHeader;
+
+ for (WORD i = 0; i < Nt.FileHeader.NumberOfSections; i++)
+ {
+ IMAGE_SECTION_HEADER Section;
+
+ if (!ReadProcessMemory(Process, (PBYTE)SectionBase + (UINT64)i * sizeof(Section), &Section, sizeof(Section), &Got))
+ return FALSE;
+
+ if (memcmp(Section.Name, ".text", 6) != 0)
+ continue;
+
+ UINT64 Start = Base + Section.VirtualAddress;
+ UINT64 Size = Section.Misc.VirtualSize ? Section.Misc.VirtualSize : Section.SizeOfRawData;
+
+ if (Size == 0)
+ return FALSE;
+
+ Ctx->Code = (UINT8 *)malloc((SIZE_T)Size);
+ if (Ctx->Code == NULL)
+ return FALSE;
+
+ if (!ReadProcessMemory(Process, (PVOID)Start, Ctx->Code, (SIZE_T)Size, &Got) || Got != Size)
+ {
+ free(Ctx->Code);
+ Ctx->Code = NULL;
+ return FALSE;
+ }
+
+ Ctx->CodeBase = Start;
+ Ctx->CodeSize = Size;
+ *TextStart = Start;
+ *TextEnd = Start + Size - 1;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ * @brief Resolve function address using symbol information
+ *
+ * @param Process
+ * @param Path
+ * @param Name
+ * @param ImageBase
+ * @param Start
+ * @param End
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+PtHelperResolveFunction(HANDLE Process, const CHAR * Path, const CHAR * Name, UINT64 ImageBase, UINT64 * Start, UINT64 * End)
+{
+ union
+ {
+ SYMBOL_INFO Info;
+ BYTE Buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
+ } Symbol = {0};
+ BOOLEAN Ok = FALSE;
+
+ SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
+ if (!SymInitialize(Process, NULL, FALSE))
+ return FALSE;
+
+ if (SymLoadModuleEx(Process, NULL, Path, NULL, (DWORD64)ImageBase, 0, NULL, 0) != 0)
+ {
+ Symbol.Info.SizeOfStruct = sizeof(SYMBOL_INFO);
+ Symbol.Info.MaxNameLen = MAX_SYM_NAME;
+
+ if (SymFromName(Process, Name, &Symbol.Info) && Symbol.Info.Address != 0)
+ {
+ *Start = Symbol.Info.Address;
+ *End = Symbol.Info.Address + (Symbol.Info.Size ? Symbol.Info.Size : 0x200) - 1;
+ Ok = TRUE;
+ }
+ }
+
+ SymCleanup(Process);
+ return Ok;
+}
+
+/**
+ * @brief Get PT packet name
+ *
+ * @param Type
+ *
+ * @return const CHAR *
+ */
+const CHAR *
+PtHelperPacketName(enum pt_packet_type Type)
+{
+ switch (Type)
+ {
+ case ppt_psb:
+ return "PSB";
+ case ppt_psbend:
+ return "PSBEND";
+ case ppt_pad:
+ return "PAD";
+ case ppt_fup:
+ return "FUP";
+ case ppt_tip:
+ return "TIP";
+ case ppt_tip_pge:
+ return "TIP.PGE";
+ case ppt_tip_pgd:
+ return "TIP.PGD";
+ case ppt_tnt_8:
+ return "TNT8";
+ case ppt_tnt_64:
+ return "TNT64";
+ case ppt_mode:
+ return "MODE";
+ case ppt_pip:
+ return "PIP";
+ case ppt_vmcs:
+ return "VMCS";
+ case ppt_cbr:
+ return "CBR";
+ case ppt_tsc:
+ return "TSC";
+ case ppt_tma:
+ return "TMA";
+ case ppt_mtc:
+ return "MTC";
+ case ppt_cyc:
+ return "CYC";
+ case ppt_ovf:
+ return "OVF";
+ case ppt_stop:
+ return "STOP";
+ case ppt_exstop:
+ return "EXSTOP";
+ case ppt_mnt:
+ return "MNT";
+ case ppt_ptw:
+ return "PTW";
+ default:
+ return "?";
+ }
+}
+
+/**
+ * @brief Reconstruct IP from PT packet
+ *
+ * @param Packet
+ * @param LastIp
+ *
+ * @return UINT64
+ */
+UINT64
+PtHelperReconstructIp(const struct pt_packet_ip * Packet, UINT64 * LastIp)
+{
+ UINT64 Value = *LastIp;
+
+ switch (Packet->ipc)
+ {
+ case pt_ipc_update_16:
+ Value = (Value & ~0xffffull) | (Packet->ip & 0xffffull);
+ break;
+ case pt_ipc_update_32:
+ Value = (Value & ~0xffffffffull) | (Packet->ip & 0xffffffffull);
+ break;
+ case pt_ipc_update_48:
+ Value = (Value & ~0xffffffffffffull) | (Packet->ip & 0xffffffffffffull);
+ break;
+ case pt_ipc_sext_48:
+ Value = Packet->ip & 0xffffffffffffull;
+ if (Value & 0x800000000000ull)
+ Value |= 0xffff000000000000ull;
+ break;
+ default:
+ Value = Packet->ip;
+ break;
+ }
+
+ *LastIp = Value;
+ return Value;
+}
+
+/**
+ * @brief Decode PT packets
+ *
+ * @param Cpu
+ * @param Buffer
+ * @param Size
+ * @param ImageBase
+ *
+ * @return UINT64
+ */
+UINT64
+PtHelperDecodeCorePackets(UINT32 Cpu, const UINT8 * Buffer, UINT64 Size, UINT64 ImageBase)
+{
+ struct pt_config Config;
+ struct pt_packet_decoder * Decoder;
+ UINT64 Count = 0;
+ UINT64 LastIp = 0;
+ int Status;
+
+ pt_config_init(&Config);
+ Config.begin = (UINT8 *)Buffer;
+ Config.end = (UINT8 *)Buffer + Size;
+
+ Decoder = pt_pkt_alloc_decoder(&Config);
+ if (Decoder == NULL)
+ {
+ ShowMessages("[-] core %u: cannot allocate packet decoder\n", Cpu);
+ return 0;
+ }
+
+ for (;;)
+ {
+ Status = pt_pkt_sync_forward(Decoder);
+ if (Status < 0)
+ break;
+
+ for (;;)
+ {
+ struct pt_packet Packet;
+
+ Status = pt_pkt_next(Decoder, &Packet, sizeof(Packet));
+ if (Status < 0)
+ break;
+
+ Count++;
+
+ switch (Packet.type)
+ {
+ case ppt_tnt_8:
+ case ppt_tnt_64:
+ ShowMessages(" %-8s %2u ", PtHelperPacketName(Packet.type), Packet.payload.tnt.bit_size);
+ for (UINT8 Bit = 0; Bit < Packet.payload.tnt.bit_size && Bit < 64; Bit++)
+ putchar(((Packet.payload.tnt.payload >> (Packet.payload.tnt.bit_size - 1 - Bit)) & 1) ? 'T' : 'N');
+ putchar('\n');
+ break;
+
+ case ppt_tip:
+ case ppt_fup:
+ case ppt_tip_pge:
+ case ppt_tip_pgd:
+ if (Packet.payload.ip.ipc == pt_ipc_suppressed)
+ ShowMessages(" %-8s (ip suppressed)\n", PtHelperPacketName(Packet.type));
+ else
+ {
+ UINT64 Ip = PtHelperReconstructIp(&Packet.payload.ip, &LastIp);
+ ShowMessages(" %-8s 0x%016llx exe+0x%llx\n",
+ PtHelperPacketName(Packet.type),
+ (UINT64)Ip,
+ (UINT64)(Ip - ImageBase));
+ }
+ break;
+
+ case ppt_pip:
+ ShowMessages(" %-8s cr3=0x%llx\n", PtHelperPacketName(Packet.type), (UINT64)Packet.payload.pip.cr3);
+ break;
+
+ case ppt_cbr:
+ // ShowMessages(" %-8s ratio=%u\n", PtHelperPacketName(Packet.type), Packet.payload.cbr.ratio);
+ break;
+
+ case ppt_tsc:
+ ShowMessages(" %-8s tsc=0x%llx\n", PtHelperPacketName(Packet.type), (UINT64)Packet.payload.tsc.tsc);
+ break;
+
+ default:
+ // ShowMessages(" %-8s\n", PtHelperPacketName(Packet.type));
+ break;
+ }
+ }
+ }
+
+ pt_pkt_free_decoder(Decoder);
+ return Count;
+}
+
+/**
+ * @brief Decode PT instructions
+ *
+ * @param Cpu
+ * @param Buffer
+ * @param Size
+ * @param Ctx
+ *
+ * @return UINT64
+ */
+UINT64
+PtHelperDecodeCore(UINT32 Cpu, const UINT8 * Buffer, UINT64 Size, IMAGE_SYMBOL_CONTEXT * Ctx)
+{
+ struct pt_config Config;
+ struct pt_insn_decoder * Decoder;
+ struct pt_image * Image;
+ UINT64 Count = 0;
+ int Status;
+
+ pt_config_init(&Config);
+ Config.begin = (UINT8 *)Buffer;
+ Config.end = (UINT8 *)Buffer + Size;
+
+ Decoder = pt_insn_alloc_decoder(&Config);
+ if (Decoder == NULL)
+ {
+ ShowMessages("[-] core %u: cannot allocate instruction decoder\n", Cpu);
+ return 0;
+ }
+
+ Image = pt_insn_get_image(Decoder);
+ pt_image_set_callback(Image, PtHelperReadImage, Ctx);
+
+ for (;;)
+ {
+ Status = pt_insn_sync_forward(Decoder);
+ if (Status < 0)
+ break;
+
+ for (;;)
+ {
+ struct pt_insn Insn;
+
+ while (Status & pts_event_pending)
+ {
+ struct pt_event Event;
+ Status = pt_insn_event(Decoder, &Event, sizeof(Event));
+ if (Status < 0)
+ break;
+ }
+
+ if (Status < 0 || (Status & pts_eos))
+ break;
+
+ Status = pt_insn_next(Decoder, &Insn, sizeof(Insn));
+ if (Status < 0)
+ break;
+
+ ZydisDisassembledInstruction Disasm;
+ ZydisMachineMode Mode = (Insn.mode == ptem_32bit) ? ZYDIS_MACHINE_MODE_LEGACY_32 : ZYDIS_MACHINE_MODE_LONG_64;
+
+ if (ZYAN_SUCCESS(ZydisDisassembleIntel(Mode, Insn.ip, Insn.raw, Insn.size, &Disasm)))
+ ShowMessages(" 0x%016llx exe+0x%-6llx %s\n",
+ (UINT64)Insn.ip,
+ (UINT64)(Insn.ip - Ctx->ImageBase),
+ Disasm.text);
+ else
+ ShowMessages(" 0x%016llx (undecodable)\n", (UINT64)Insn.ip);
+
+ Count++;
+ }
+
+ if (Status >= 0 && (Status & pts_eos))
+ break;
+ }
+
+ pt_insn_free_decoder(Decoder);
+ return Count;
+}
diff --git a/hyperdbg/libhyperdbg/code/debugger/misc/readmem.cpp b/hyperdbg/libhyperdbg/code/debugger/misc/readmem.cpp
index e0a4b9dc..4cfcf555 100644
--- a/hyperdbg/libhyperdbg/code/debugger/misc/readmem.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/misc/readmem.cpp
@@ -15,6 +15,7 @@
//
// Global Variables
//
+extern BOOLEAN g_IsKdModuleLoaded;
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
/**
@@ -49,11 +50,11 @@ HyperDbgReadMemory(UINT64 TargetAddress,
UINT32 SizeOfTargetBuffer;
//
- // Check if driver is loaded if it's in VMI mode
+ // Check if driver is loaded if it's in local debugging mode
//
if (!g_IsSerialConnectedToRemoteDebuggee)
{
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
}
//
@@ -104,9 +105,8 @@ HyperDbgReadMemory(UINT64 TargetAddress,
else
{
//
- // It's on VMI mode
+ // It's on local debugging mode
//
-
Status = DeviceIoControl(g_DeviceHandle, // Handle to device
IOCTL_DEBUGGER_READ_MEMORY, // IO Control Code (IOCTL)
MemReadRequest, // Input Buffer to driver.
@@ -164,7 +164,7 @@ HyperDbgReadMemory(UINT64 TargetAddress,
// Copy the buffer
//
memcpy(TargetBufferToStore,
- ((unsigned char *)MemReadRequest) + sizeof(DEBUGGER_READ_MEMORY),
+ ((UCHAR *)MemReadRequest) + sizeof(DEBUGGER_READ_MEMORY),
*ReturnLength);
//
@@ -413,11 +413,13 @@ HyperDbgShowMemoryOrDisassemble(DEBUGGER_SHOW_MEMORY_STYLE Style,
* @param Address location of where to read the memory
* @param MemoryType type of memory (phyical or virtual)
* @param Length Length of memory to show
+ *
+ * @return VOID
*/
-void
-ShowMemoryCommandDB(unsigned char * OutputBuffer, UINT32 Size, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, UINT64 Length)
+VOID
+ShowMemoryCommandDB(UCHAR * OutputBuffer, UINT32 Size, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, UINT64 Length)
{
- unsigned int Character;
+ UINT32 Character;
for (UINT32 i = 0; i < Size; i += 16)
{
@@ -434,7 +436,7 @@ ShowMemoryCommandDB(unsigned char * OutputBuffer, UINT32 Size, UINT64 Address, D
//
// Print the hex code
//
- for (size_t j = 0; j < 16; j++)
+ for (SIZE_T j = 0; j < 16; j++)
{
//
// check to see if the address is valid or not
@@ -453,7 +455,7 @@ ShowMemoryCommandDB(unsigned char * OutputBuffer, UINT32 Size, UINT64 Address, D
// Print the character
//
ShowMessages(" ");
- for (size_t j = 0; j < 16; j++)
+ for (SIZE_T j = 0; j < 16; j++)
{
Character = (OutputBuffer[i + j]);
if (isprint(Character))
@@ -481,11 +483,13 @@ ShowMemoryCommandDB(unsigned char * OutputBuffer, UINT32 Size, UINT64 Address, D
* @param Address location of where to read the memory
* @param MemoryType type of memory (phyical or virtual)
* @param Length Length of memory to show
+ *
+ * @return VOID
*/
-void
-ShowMemoryCommandDC(unsigned char * OutputBuffer, UINT32 Size, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, UINT64 Length)
+VOID
+ShowMemoryCommandDC(UCHAR * OutputBuffer, UINT32 Size, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, UINT64 Length)
{
- unsigned int Character;
+ UINT32 Character;
for (UINT32 i = 0; i < Size; i += 16)
{
if (MemoryType == DEBUGGER_READ_PHYSICAL_ADDRESS)
@@ -501,7 +505,7 @@ ShowMemoryCommandDC(unsigned char * OutputBuffer, UINT32 Size, UINT64 Address, D
//
// Print the hex code
//
- for (size_t j = 0; j < 16; j += 4)
+ for (SIZE_T j = 0; j < 16; j += 4)
{
//
// check to see if the address is valid or not
@@ -522,7 +526,7 @@ ShowMemoryCommandDC(unsigned char * OutputBuffer, UINT32 Size, UINT64 Address, D
//
ShowMessages(" ");
- for (size_t j = 0; j < 16; j++)
+ for (SIZE_T j = 0; j < 16; j++)
{
Character = (OutputBuffer[i + j]);
if (isprint(Character))
@@ -550,9 +554,11 @@ ShowMemoryCommandDC(unsigned char * OutputBuffer, UINT32 Size, UINT64 Address, D
* @param Address location of where to read the memory
* @param MemoryType type of memory (phyical or virtual)
* @param Length Length of memory to show
+ *
+ * @return VOID
*/
-void
-ShowMemoryCommandDD(unsigned char * OutputBuffer, UINT32 Size, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, UINT64 Length)
+VOID
+ShowMemoryCommandDD(UCHAR * OutputBuffer, UINT32 Size, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, UINT64 Length)
{
for (UINT32 i = 0; i < Size; i += 16)
{
@@ -569,7 +575,7 @@ ShowMemoryCommandDD(unsigned char * OutputBuffer, UINT32 Size, UINT64 Address, D
//
// Print the hex code
//
- for (size_t j = 0; j < 16; j += 4)
+ for (SIZE_T j = 0; j < 16; j += 4)
{
//
// check to see if the address is valid or not
@@ -599,9 +605,11 @@ ShowMemoryCommandDD(unsigned char * OutputBuffer, UINT32 Size, UINT64 Address, D
* @param Address location of where to read the memory
* @param MemoryType type of memory (phyical or virtual)
* @param Length Length of memory to show
+ *
+ * @return VOID
*/
-void
-ShowMemoryCommandDQ(unsigned char * OutputBuffer, UINT32 Size, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, UINT64 Length)
+VOID
+ShowMemoryCommandDQ(UCHAR * OutputBuffer, UINT32 Size, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, UINT64 Length)
{
for (UINT32 i = 0; i < Size; i += 16)
{
@@ -618,7 +626,7 @@ ShowMemoryCommandDQ(unsigned char * OutputBuffer, UINT32 Size, UINT64 Address, D
//
// Print the hex code
//
- for (size_t j = 0; j < 16; j += 8)
+ for (SIZE_T j = 0; j < 16; j += 8)
{
//
// check to see if the address is valid or not
diff --git a/hyperdbg/libhyperdbg/code/debugger/script-engine/script-engine-wrapper.cpp b/hyperdbg/libhyperdbg/code/debugger/script-engine/script-engine-wrapper.cpp
index b6d727e4..cf32100a 100644
--- a/hyperdbg/libhyperdbg/code/debugger/script-engine/script-engine-wrapper.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/script-engine/script-engine-wrapper.cpp
@@ -23,7 +23,6 @@ extern UINT64 * g_ScriptStackBuffer;
extern UINT64 g_CurrentExprEvalResult;
extern BOOLEAN g_CurrentExprEvalResultHasError;
extern UINT64 * g_HwdbgPinsStatus;
-extern BOOLEAN g_HwdbgInstanceInfoIsValid;
//
// Temporary structures used only for testing
@@ -52,7 +51,7 @@ typedef struct _ALLOCATED_MEMORY_FOR_SCRIPT_ENGINE_CASTING
* @return UINT64
*/
UINT64
-ScriptEngineConvertNameToAddressWrapper(const char * FunctionOrVariableName, PBOOLEAN WasFound)
+ScriptEngineConvertNameToAddressWrapper(const CHAR * FunctionOrVariableName, PBOOLEAN WasFound)
{
return ScriptEngineConvertNameToAddress(FunctionOrVariableName, WasFound);
}
@@ -66,7 +65,7 @@ ScriptEngineConvertNameToAddressWrapper(const char * FunctionOrVariableName, PBO
* @return UINT32
*/
UINT32
-ScriptEngineLoadFileSymbolWrapper(UINT64 BaseAddress, const char * PdbFileName, const char * CustomModuleName)
+ScriptEngineLoadFileSymbolWrapper(UINT64 BaseAddress, const CHAR * PdbFileName, const CHAR * CustomModuleName)
{
return ScriptEngineLoadFileSymbol(BaseAddress, PdbFileName, CustomModuleName);
}
@@ -102,7 +101,7 @@ ScriptEngineUnloadAllSymbolsWrapper()
* @return UINT32
*/
UINT32
-ScriptEngineUnloadModuleSymbolWrapper(char * ModuleName)
+ScriptEngineUnloadModuleSymbolWrapper(CHAR * ModuleName)
{
return ScriptEngineUnloadModuleSymbol(ModuleName);
}
@@ -115,7 +114,7 @@ ScriptEngineUnloadModuleSymbolWrapper(char * ModuleName)
* @return UINT32
*/
UINT32
-ScriptEngineSearchSymbolForMaskWrapper(const char * SearchMask)
+ScriptEngineSearchSymbolForMaskWrapper(const CHAR * SearchMask)
{
return ScriptEngineSearchSymbolForMask(SearchMask);
}
@@ -158,7 +157,7 @@ ScriptEngineGetDataTypeSizeWrapper(CHAR * TypeName, UINT64 * TypeSize)
* @return BOOLEAN
*/
BOOLEAN
-ScriptEngineCreateSymbolTableForDisassemblerWrapper(void * CallbackFunction)
+ScriptEngineCreateSymbolTableForDisassemblerWrapper(PVOID CallbackFunction)
{
return ScriptEngineCreateSymbolTableForDisassembler(CallbackFunction);
}
@@ -172,7 +171,7 @@ ScriptEngineCreateSymbolTableForDisassemblerWrapper(void * CallbackFunction)
* @return BOOLEAN
*/
BOOLEAN
-ScriptEngineConvertFileToPdbPathWrapper(const char * LocalFilePath, char * ResultPath, size_t ResultPathSize)
+ScriptEngineConvertFileToPdbPathWrapper(const CHAR * LocalFilePath, CHAR * ResultPath, SIZE_T ResultPathSize)
{
return ScriptEngineConvertFileToPdbPath(LocalFilePath, ResultPath, ResultPathSize);
@@ -193,7 +192,7 @@ BOOLEAN
ScriptEngineSymbolInitLoadWrapper(PMODULE_SYMBOL_DETAIL BufferToStoreDetails,
UINT32 StoredLength,
BOOLEAN DownloadIfAvailable,
- const char * SymbolPath,
+ const CHAR * SymbolPath,
BOOLEAN IsSilentLoad)
{
return ScriptEngineSymbolInitLoad(BufferToStoreDetails, StoredLength, DownloadIfAvailable, SymbolPath, IsSilentLoad);
@@ -212,11 +211,11 @@ ScriptEngineSymbolInitLoadWrapper(PMODULE_SYMBOL_DETAIL BufferToStoreDetails,
*/
BOOLEAN
ScriptEngineShowDataBasedOnSymbolTypesWrapper(
- const char * TypeName,
+ const CHAR * TypeName,
UINT64 Address,
BOOLEAN IsStruct,
PVOID BufferAddress,
- const char * AdditionalParameters)
+ const CHAR * AdditionalParameters)
{
return ScriptEngineShowDataBasedOnSymbolTypes(TypeName, Address, IsStruct, BufferAddress, AdditionalParameters);
}
@@ -244,15 +243,45 @@ ScriptEngineSymbolAbortLoadingWrapper()
* @return BOOLEAN
*/
BOOLEAN
-ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetailsWrapper(const char * LocalFilePath,
- char * PdbFilePath,
- char * GuidAndAgeDetails,
+ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetailsWrapper(const CHAR * LocalFilePath,
+ CHAR * PdbFilePath,
+ CHAR * GuidAndAgeDetails,
BOOLEAN Is32BitModule)
{
return ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetails(LocalFilePath, PdbFilePath, GuidAndAgeDetails, Is32BitModule);
}
+/**
+ * @brief ScriptEngineConvertLoadedModuleToPdbFileAndGuidAndAgeDetails wrapper
+ *
+ * @param LoadedImageBytes
+ * @param LoadedImageSize
+ * @param LocalFilePath
+ * @param PdbFilePath
+ * @param GuidAndAgeDetails
+ * @param Is32BitModule
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+ScriptEngineConvertLoadedModuleToPdbFileAndGuidAndAgeDetailsWrapper(const BYTE * LoadedImageBytes,
+ SIZE_T LoadedImageSize,
+ const CHAR * LocalFilePath,
+ CHAR * PdbFilePath,
+ CHAR * GuidAndAgeDetails,
+ BOOLEAN Is32BitModule)
+
+{
+ return ScriptEngineConvertLoadedModuleToPdbFileAndGuidAndAgeDetails(
+ LoadedImageBytes,
+ LoadedImageSize,
+ LocalFilePath,
+ PdbFilePath,
+ GuidAndAgeDetails,
+ Is32BitModule);
+}
+
//
// *********************** Function links (wrapper) ***********************
//
@@ -266,7 +295,7 @@ ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetailsWrapper(const char * LocalFi
* @return PVOID
*/
PVOID
-ScriptEngineParseWrapper(char * Expr, BOOLEAN ShowErrorMessageIfAny)
+ScriptEngineParseWrapper(CHAR * Expr, BOOLEAN ShowErrorMessageIfAny)
{
PSYMBOL_BUFFER SymbolBuffer;
SymbolBuffer = (PSYMBOL_BUFFER)ScriptEngineParse(Expr);
@@ -394,8 +423,8 @@ ScriptEngineEvalWrapper(PGUEST_REGS GuestRegs,
#ifdef _SCRIPT_ENGINE_CODEEXEC_DBG_EN
printf("Address = %lld, StackIndx = %lld, StackBaseIndx = %lld\n", i, ScriptGeneralRegisters.StackIndx, ScriptGeneralRegisters.StackBaseIndx);
- PSYMBOL Operator = (PSYMBOL)((unsigned long long)CodeBuffer->Head +
- (unsigned long long)(i * sizeof(SYMBOL)));
+ PSYMBOL Operator = (PSYMBOL)((UINT64)CodeBuffer->Head +
+ (UINT64)(i * sizeof(SYMBOL)));
printf("Function = %s\n", FunctionNames[Operator->Value]);
printf("Stack Buffer:\n");
for (UINT64 j = 0; j < ScriptGeneralRegisters.StackIndx; j++)
@@ -668,12 +697,12 @@ ScriptEngineWrapperTestParser(const string & Expr)
GUEST_REGS GuestRegs = {0};
- char test[] = "Hello world !";
- wchar_t testw[] =
+ CHAR test[] = "Hello world !";
+ WCHAR testw[] =
L"A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 "
L"9 a b c d e f g h i j k l m n o p q r s t u v w x y z";
- char * RspReg = (char *)malloc(0x100);
+ CHAR * RspReg = (CHAR *)malloc(0x100);
if (RspReg == NULL)
{
diff --git a/hyperdbg/libhyperdbg/code/debugger/script-engine/script-engine.cpp b/hyperdbg/libhyperdbg/code/debugger/script-engine/script-engine.cpp
index e0abeb21..73b07f71 100644
--- a/hyperdbg/libhyperdbg/code/debugger/script-engine/script-engine.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/script-engine/script-engine.cpp
@@ -14,9 +14,10 @@
//
// Global Variables
//
-extern UINT64 g_ResultOfEvaluatedExpression;
-extern UINT32 g_ErrorStateOfResultOfEvaluatedExpression;
-extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+extern UINT64 g_ResultOfEvaluatedExpression;
+extern UINT32 g_ErrorStateOfResultOfEvaluatedExpression;
+extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
/**
* @brief Get the value from the evaluation of single expression
@@ -29,10 +30,6 @@ extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
UINT64
ScriptEngineEvalSingleExpression(string Expr, PBOOLEAN HasError)
{
- PVOID CodeBuffer;
- UINT64 BufferAddress;
- UINT32 BufferLength;
- UINT32 Pointer;
UINT64 Result = NULL;
//
@@ -41,45 +38,16 @@ ScriptEngineEvalSingleExpression(string Expr, PBOOLEAN HasError)
Expr.insert(0, "formats(");
Expr.append(");");
- //
- // Run script engine handler
- //
- CodeBuffer = ScriptEngineParseWrapper((char *)Expr.c_str(), FALSE);
-
- if (CodeBuffer == NULL)
+ if (g_IsSerialConnectedToRemoteDebuggee || g_ActiveProcessDebuggingState.IsActive)
{
//
- // return to show that this item contains an script
+ // Send data to the target user debugger or kernel debugger
//
- *HasError = TRUE;
- return NULL;
- }
-
- //
- // Print symbols (test)
- //
- // PrintSymbolBufferWrapper(CodeBuffer);
-
- //
- // Set the buffer and length
- //
- BufferAddress = ScriptEngineWrapperGetHead(CodeBuffer);
- BufferLength = ScriptEngineWrapperGetSize(CodeBuffer);
- Pointer = ScriptEngineWrapperGetPointer(CodeBuffer);
-
- //
- // Check if it's connected over remote debuggee (in the Debugger Mode)
- //
- if (g_IsSerialConnectedToRemoteDebuggee)
- {
- //
- // Send over serial
- //
-
- //
- // Send it to the remote debuggee
- //
- KdSendScriptPacketToDebuggee(BufferAddress, BufferLength, Pointer, TRUE);
+ if (!ScriptEngineExecuteSingleExpression((CHAR *)Expr.c_str(), TRUE, TRUE))
+ {
+ *HasError = TRUE;
+ return NULL;
+ }
//
// Check whether there was an error in evaluation or not
@@ -116,10 +84,115 @@ ScriptEngineEvalSingleExpression(string Expr, PBOOLEAN HasError)
Result = ScriptEngineEvalUInt64StyleExpressionWrapper(Expr, HasError);
}
+ return Result;
+}
+
+/**
+ * @brief Execute single expression for the kernel debugger and the user-mode debugger
+ *
+ * @param Expr
+ * @param ShowErrorMessageIfAny
+ * @param IsFormat If it's a format expression
+ *
+ * @return BOOLEAN Returns TRUE if it was successful
+ */
+BOOLEAN
+ScriptEngineExecuteSingleExpression(CHAR * Expr, BOOLEAN ShowErrorMessageIfAny, BOOLEAN IsFormat)
+{
+ PVOID CodeBuffer;
+ UINT64 BufferAddress;
+ UINT32 BufferLength;
+ UINT32 Pointer;
+ BOOLEAN Result = FALSE;
+
+ //
+ // Check whether a kernel debugger is connected or a user-mode debugger is active
+ //
+ if (!g_IsSerialConnectedToRemoteDebuggee && !g_ActiveProcessDebuggingState.IsActive)
+ {
+ if (ShowErrorMessageIfAny)
+ {
+ ShowMessages("err, you're not connected to any debuggee (neither user debugger nor kernel debugger)\n");
+ }
+ return FALSE;
+ }
+
+ //
+ // Check if the user-mode debuggee is paused
+ //
+ if (g_ActiveProcessDebuggingState.IsActive && !g_ActiveProcessDebuggingState.IsPaused)
+ {
+ if (ShowErrorMessageIfAny)
+ {
+ ShowMessages("err, the target process is NOT paused, you should run 'pause' to pause it\n");
+ }
+ return FALSE;
+ }
+
+ //
+ // Run script engine handler
+ //
+ CodeBuffer = ScriptEngineParseWrapper(Expr, ShowErrorMessageIfAny);
+
+ if (CodeBuffer == NULL)
+ {
+ //
+ // return to show that this item contains an error
+ //
+ return FALSE;
+ }
+
+ //
+ // Print symbols (test)
+ //
+ // PrintSymbolBufferWrapper(CodeBuffer);
+
+ //
+ // Set the buffer and length
+ //
+ BufferAddress = ScriptEngineWrapperGetHead(CodeBuffer);
+ BufferLength = ScriptEngineWrapperGetSize(CodeBuffer);
+ Pointer = ScriptEngineWrapperGetPointer(CodeBuffer);
+
+ if (g_IsSerialConnectedToRemoteDebuggee)
+ {
+ //
+ // Send it to the remote debuggee (kernel debugger)
+ //
+ Result = KdSendScriptPacketToDebuggee(BufferAddress,
+ BufferLength,
+ Pointer,
+ IsFormat);
+ }
+ else if (g_ActiveProcessDebuggingState.IsActive)
+ {
+ //
+ // Send it to the user debugger
+ //
+ Result = UdSendScriptBufferToProcess(
+ g_ActiveProcessDebuggingState.ProcessDebuggingToken,
+ g_ActiveProcessDebuggingState.ThreadId,
+ BufferAddress,
+ BufferLength,
+ Pointer,
+ IsFormat);
+ }
+ else
+ {
+ //
+ // Not connected to any debuggee
+ //
+ ShowMessages("err, you're not connected to any debuggee (neither user debugger nor kernel debugger)\n");
+ Result = FALSE;
+ }
+
//
// Remove the buffer of script engine interpreted code
//
ScriptEngineWrapperRemoveSymbolBuffer(CodeBuffer);
+ //
+ // Return result
+ //
return Result;
}
diff --git a/hyperdbg/libhyperdbg/code/debugger/script-engine/symbol-linux.cpp b/hyperdbg/libhyperdbg/code/debugger/script-engine/symbol-linux.cpp
new file mode 100644
index 00000000..2f7f65a4
--- /dev/null
+++ b/hyperdbg/libhyperdbg/code/debugger/script-engine/symbol-linux.cpp
@@ -0,0 +1,107 @@
+/**
+ * @file symbol-linux.cpp
+ * @author Max Raulea (max.raulea@gmail.com)
+ * @brief Linux stub implementations of the symbol subsystem
+ * @details The Windows implementation uses DbgHelp + PDB files (symbol-parser/).
+ * Linux uses ELF/DWARF which requires a separate implementation.
+ * These stubs allow the library to compile and link on Linux while
+ * keeping all call sites intact.
+ *
+ * TODO: implement a real ELF/DWARF symbol parser for Linux
+ * (libdw / libelf / libbfd) and replace these stubs.
+ *
+ * @version 0.1
+ * @date 2026-06-08
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+#ifdef __linux__
+
+VOID
+SymbolBuildAndShowSymbolTable()
+{
+ ShowMessages("err, symbol table is not supported on Linux yet\n");
+}
+
+BOOLEAN
+SymbolShowFunctionNameBasedOnAddress(UINT64 Address, PUINT64 UsedBaseAddress)
+{
+ return FALSE;
+}
+
+BOOLEAN
+SymbolLoadOrDownloadSymbols(BOOLEAN IsDownload, BOOLEAN SilentLoad)
+{
+ if (!SilentLoad)
+ ShowMessages("err, symbol loading is not supported on Linux yet\n");
+ return FALSE;
+}
+
+/**
+ * @brief Attempt to resolve a name or expression to an address.
+ *
+ * On Linux, full symbol resolution (ELF/DWARF) is not yet implemented.
+ * This stub handles the common case of a plain hex/decimal literal so that
+ * numeric addresses still work everywhere in the debugger.
+ */
+BOOLEAN
+SymbolConvertNameOrExprToAddress(const string & TextToConvert, PUINT64 Result)
+{
+ try
+ {
+ *Result = std::stoull(TextToConvert, nullptr, 0);
+ return TRUE;
+ }
+ catch (...)
+ {
+ return FALSE;
+ }
+}
+
+BOOLEAN
+SymbolDeleteSymTable()
+{
+ return TRUE;
+}
+
+BOOLEAN
+SymbolBuildSymbolTable(PMODULE_SYMBOL_DETAIL * BufferToStoreDetails,
+ PUINT32 StoredLength,
+ UINT32 UserProcessId,
+ BOOLEAN SendOverSerial)
+{
+ return FALSE;
+}
+
+BOOLEAN
+SymbolBuildAndUpdateSymbolTable(PMODULE_SYMBOL_DETAIL SymbolDetail)
+{
+ return FALSE;
+}
+
+VOID
+SymbolInitialReload()
+{
+}
+
+BOOLEAN
+SymbolLocalReload(UINT32 UserProcessId)
+{
+ return FALSE;
+}
+
+VOID
+SymbolPrepareDebuggerWithSymbolInfo(UINT32 UserProcessId)
+{
+}
+
+BOOLEAN
+SymbolReloadSymbolTableInDebuggerMode(UINT32 ProcessId)
+{
+ return FALSE;
+}
+
+#endif // __linux__
diff --git a/hyperdbg/libhyperdbg/code/debugger/script-engine/symbol.cpp b/hyperdbg/libhyperdbg/code/debugger/script-engine/symbol.cpp
index 34eacb9d..bfb02fbe 100644
--- a/hyperdbg/libhyperdbg/code/debugger/script-engine/symbol.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/script-engine/symbol.cpp
@@ -19,7 +19,6 @@ extern PMODULE_SYMBOL_DETAIL g_SymbolTable;
extern UINT32 g_SymbolTableSize;
extern UINT32 g_SymbolTableCurrentIndex;
extern BOOLEAN g_IsExecutingSymbolLoadingRoutines;
-extern BOOLEAN g_IsSerialConnectedToRemoteDebugger;
extern BOOLEAN g_AddressConversion;
extern std::map g_DisassemblerSymbolMap;
@@ -86,10 +85,10 @@ SymbolPrepareDebuggerWithSymbolInfo(UINT32 UserProcessId)
* @return VOID
*/
VOID
-SymbolCreateDisassemblerMapCallback(UINT64 Address,
- char * ModuleName,
- char * ObjectName,
- unsigned int ObjectSize)
+SymbolCreateDisassemblerMapCallback(UINT64 Address,
+ CHAR * ModuleName,
+ CHAR * ObjectName,
+ UINT32 ObjectSize)
{
//
// It has a string, should not be initialized with zero
@@ -273,7 +272,7 @@ SymbolBuildAndShowSymbolTable()
//
// show packet details
//
- for (size_t i = 0; i < g_SymbolTableSize / sizeof(MODULE_SYMBOL_DETAIL); i++)
+ for (SIZE_T i = 0; i < g_SymbolTableSize / sizeof(MODULE_SYMBOL_DETAIL); i++)
{
ShowMessages("is pdb details available? : %s\n", g_SymbolTable[i].IsSymbolDetailsFound ? "true" : "false");
ShowMessages("is pdb a path instead of module name? : %s\n", g_SymbolTable[i].IsLocalSymbolPath ? "true" : "false");
@@ -424,6 +423,291 @@ SymbolConvertNameOrExprToAddress(const string & TextToConvert, PUINT64 Result)
return IsFound;
}
+/**
+ * @brief Read user virtual memory of the debuggee process
+ *
+ * @param BaseAddress the base address to read from
+ * @param UserProcessId the target process id to read its memory
+ * @param ReadSize the size of bytes to read
+ * @param Bytes the output vector to receive the read bytes
+ *
+ * @return BOOLEAN shows whether the reading was successful or not
+ */
+static BOOLEAN
+SymbolReadUserVirtualMemoryExact(UINT64 BaseAddress, UINT32 UserProcessId, UINT32 ReadSize, std::vector & Bytes)
+{
+ BOOL Status = FALSE;
+ ULONG ReturnedLength = 0;
+ if (ReadSize > 0xffffffffu - SIZEOF_DEBUGGER_READ_MEMORY)
+ {
+ return FALSE;
+ }
+
+ UINT32 SizeOfTargetBuffer = SIZEOF_DEBUGGER_READ_MEMORY + ReadSize;
+ DEBUGGER_READ_MEMORY ReadMemoryRequest = {0};
+ DEBUGGER_READ_MEMORY * MemReadRequest = NULL;
+
+ Bytes.clear();
+
+ if (g_DeviceHandle == NULL || BaseAddress == 0 || UserProcessId == 0 || ReadSize == 0)
+ {
+ return FALSE;
+ }
+
+ MemReadRequest = (DEBUGGER_READ_MEMORY *)malloc(SizeOfTargetBuffer);
+ if (MemReadRequest == NULL)
+ {
+ return FALSE;
+ }
+
+ ReadMemoryRequest.Address = BaseAddress;
+ ReadMemoryRequest.Pid = UserProcessId;
+ ReadMemoryRequest.Size = ReadSize;
+ ReadMemoryRequest.MemoryType = DEBUGGER_READ_VIRTUAL_ADDRESS;
+ ReadMemoryRequest.ReadingType = READ_FROM_KERNEL;
+
+ RtlZeroMemory(MemReadRequest, SizeOfTargetBuffer);
+ memcpy(MemReadRequest, &ReadMemoryRequest, sizeof(DEBUGGER_READ_MEMORY));
+
+ Status = DeviceIoControl(g_DeviceHandle,
+ IOCTL_DEBUGGER_READ_MEMORY,
+ MemReadRequest,
+ SIZEOF_DEBUGGER_READ_MEMORY,
+ MemReadRequest,
+ SizeOfTargetBuffer,
+ &ReturnedLength,
+ NULL);
+
+ if (!Status || MemReadRequest->KernelStatus != DEBUGGER_OPERATION_WAS_SUCCESSFUL || ReturnedLength != SizeOfTargetBuffer)
+ {
+ free(MemReadRequest);
+ return FALSE;
+ }
+
+ Bytes.resize(ReadSize);
+ memcpy(Bytes.data(), ((UCHAR *)MemReadRequest) + SIZEOF_DEBUGGER_READ_MEMORY, ReadSize);
+
+ free(MemReadRequest);
+ return TRUE;
+}
+
+/**
+ * @brief Check if the provided range is valid and update the required size to read if needed
+ *
+ * @param Offset the offset of the range to check
+ * @param Length the length of the range to check
+ * @param RequiredSize a pointer to the variable containing the current required size, which will be updated if the end of the range exceeds it
+ *
+ * @return BOOLEAN TRUE if the range is valid and RequiredSize is updated if needed, FALSE if the range is invalid (e.g., due to overflow)
+ */
+static BOOLEAN
+SymbolAddLoadedImageReadRange(UINT32 Offset, UINT32 Length, UINT32 * RequiredSize)
+{
+ UINT32 EndOffset = 0;
+
+ if (RequiredSize == NULL)
+ {
+ return FALSE;
+ }
+
+ if (Length == 0)
+ {
+ return TRUE;
+ }
+
+ if (Offset > 0xffffffffu - Length)
+ {
+ return FALSE;
+ }
+
+ EndOffset = Offset + Length;
+ if (EndOffset > *RequiredSize)
+ {
+ *RequiredSize = EndOffset;
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Check if the provided range is within the bounds of the loaded image bytes
+ *
+ * @param LoadedImageBytes the vector containing the bytes of the loaded image
+ * @param Offset the offset of the range to check
+ * @param Length the length of the range to check
+ *
+ * @return BOOLEAN TRUE if the range is within bounds, FALSE otherwise
+ */
+static BOOLEAN
+SymbolLoadedImageHasRange(const std::vector & LoadedImageBytes, UINT32 Offset, UINT32 Length)
+{
+ return Length <= LoadedImageBytes.size() && Offset <= LoadedImageBytes.size() - Length;
+}
+
+/**
+ * @brief Parse the headers of a loaded PE image from the provided bytes and extract the SizeOfImage and DebugDirectory details
+ *
+ * @param LoadedImagePrefix a vector containing the initial bytes of the loaded image, which should include at least the DOS header and NT headers
+ * @param SizeOfImage an output pointer to receive the SizeOfImage extracted from the optional header
+ * @param DebugDirectory an optional output pointer to receive the IMAGE_DATA_DIRECTORY entry for the debug directory if available (can be NULL if not needed)
+ *
+ * @return BOOLEAN TRUE if the headers were successfully parsed and SizeOfImage was extracted, FALSE otherwise (e.g., if the headers are invalid or incomplete)
+ */
+static BOOLEAN
+SymbolGetLoadedImageHeaderDetails(const std::vector & LoadedImagePrefix, UINT32 * SizeOfImage, IMAGE_DATA_DIRECTORY * DebugDirectory)
+{
+ if (LoadedImagePrefix.size() < sizeof(IMAGE_DOS_HEADER) || SizeOfImage == NULL)
+ {
+ return FALSE;
+ }
+
+ if (DebugDirectory != NULL)
+ {
+ RtlZeroMemory(DebugDirectory, sizeof(*DebugDirectory));
+ }
+
+ const IMAGE_DOS_HEADER * DosHeader = (const IMAGE_DOS_HEADER *)LoadedImagePrefix.data();
+ if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE || DosHeader->e_lfanew < 0)
+ {
+ return FALSE;
+ }
+
+ SIZE_T NtHeaderOffset = (SIZE_T)DosHeader->e_lfanew;
+ if (NtHeaderOffset > LoadedImagePrefix.size() || sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) > LoadedImagePrefix.size() - NtHeaderOffset)
+ {
+ return FALSE;
+ }
+
+ const BYTE * NtHeaders = LoadedImagePrefix.data() + NtHeaderOffset;
+ if (*(const DWORD *)NtHeaders != IMAGE_NT_SIGNATURE)
+ {
+ return FALSE;
+ }
+
+ const IMAGE_FILE_HEADER * FileHeader = (const IMAGE_FILE_HEADER *)(NtHeaders + sizeof(DWORD));
+ SIZE_T OptionalHeaderOffset = NtHeaderOffset + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER);
+
+ if (OptionalHeaderOffset > LoadedImagePrefix.size() || FileHeader->SizeOfOptionalHeader < sizeof(WORD) ||
+ FileHeader->SizeOfOptionalHeader > LoadedImagePrefix.size() - OptionalHeaderOffset)
+ {
+ return FALSE;
+ }
+
+ const BYTE * OptionalHeader = LoadedImagePrefix.data() + OptionalHeaderOffset;
+ WORD Magic = *(const WORD *)OptionalHeader;
+
+ if (Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC && FileHeader->SizeOfOptionalHeader >= sizeof(IMAGE_OPTIONAL_HEADER32))
+ {
+ const IMAGE_OPTIONAL_HEADER32 * OptionalHeader32 = (const IMAGE_OPTIONAL_HEADER32 *)OptionalHeader;
+
+ *SizeOfImage = OptionalHeader32->SizeOfImage;
+ if (DebugDirectory != NULL && OptionalHeader32->NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_DEBUG)
+ {
+ *DebugDirectory = OptionalHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG];
+ }
+
+ return TRUE;
+ }
+
+ if (Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC && FileHeader->SizeOfOptionalHeader >= sizeof(IMAGE_OPTIONAL_HEADER64))
+ {
+ const IMAGE_OPTIONAL_HEADER64 * OptionalHeader64 = (const IMAGE_OPTIONAL_HEADER64 *)OptionalHeader;
+
+ *SizeOfImage = OptionalHeader64->SizeOfImage;
+ if (DebugDirectory != NULL && OptionalHeader64->NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_DEBUG)
+ {
+ *DebugDirectory = OptionalHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG];
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ * @brief Read the necessary bytes of a loaded user-mode module to extract the debug directory and code view information for symbol loading
+ *
+ * @param BaseAddress the base address of the loaded module in the user process
+ * @param UserProcessId the target process id to read its memory
+ * @param LoadedImageBytes an output vector to receive the bytes of the loaded image that are necessary for symbol extraction (should be cleared and filled by this function)
+ *
+ * @return BOOLEAN TRUE if the necessary bytes were successfully read, FALSE otherwise (e.g., if memory reading failed or headers are invalid)
+ */
+static BOOLEAN
+SymbolReadLoadedUserModuleForCodeView(UINT64 BaseAddress, UINT32 UserProcessId, std::vector & LoadedImageBytes)
+{
+ static constexpr UINT32 InitialLoadedImagePrefixSize = 4 * 1024;
+ static constexpr UINT32 MaximumLoadedImageCodeViewReadSize = 4 * 1024 * 1024;
+
+ UINT32 SizeOfImage = 0;
+ UINT32 RequiredSize = InitialLoadedImagePrefixSize;
+ IMAGE_DATA_DIRECTORY DebugDirectory = {0};
+
+ if (!SymbolReadUserVirtualMemoryExact(BaseAddress, UserProcessId, InitialLoadedImagePrefixSize, LoadedImageBytes))
+ {
+ return FALSE;
+ }
+
+ if (!SymbolGetLoadedImageHeaderDetails(LoadedImageBytes, &SizeOfImage, &DebugDirectory) || SizeOfImage == 0)
+ {
+ return TRUE;
+ }
+
+ if (DebugDirectory.VirtualAddress == 0 || DebugDirectory.Size < sizeof(IMAGE_DEBUG_DIRECTORY) ||
+ DebugDirectory.Size % sizeof(IMAGE_DEBUG_DIRECTORY) != 0)
+ {
+ return TRUE;
+ }
+
+ if (!SymbolAddLoadedImageReadRange(DebugDirectory.VirtualAddress, DebugDirectory.Size, &RequiredSize) ||
+ RequiredSize > SizeOfImage ||
+ RequiredSize > MaximumLoadedImageCodeViewReadSize)
+ {
+ return TRUE;
+ }
+
+ if (RequiredSize > LoadedImageBytes.size() && !SymbolReadUserVirtualMemoryExact(BaseAddress, UserProcessId, RequiredSize, LoadedImageBytes))
+ {
+ return FALSE;
+ }
+
+ if (SymbolLoadedImageHasRange(LoadedImageBytes, DebugDirectory.VirtualAddress, DebugDirectory.Size))
+ {
+ const IMAGE_DEBUG_DIRECTORY * DebugEntries = (const IMAGE_DEBUG_DIRECTORY *)(LoadedImageBytes.data() + DebugDirectory.VirtualAddress);
+ DWORD DebugEntryCount = DebugDirectory.Size / sizeof(IMAGE_DEBUG_DIRECTORY);
+
+ for (DWORD Index = 0; Index < DebugEntryCount; Index++)
+ {
+ const IMAGE_DEBUG_DIRECTORY * DebugEntry = &DebugEntries[Index];
+
+ if (DebugEntry->Type != IMAGE_DEBUG_TYPE_CODEVIEW ||
+ DebugEntry->SizeOfData < sizeof(DWORD) + sizeof(GUID) + sizeof(DWORD))
+ {
+ continue;
+ }
+
+ UINT32 NextRequiredSize = RequiredSize;
+ if (!SymbolAddLoadedImageReadRange(DebugEntry->AddressOfRawData, DebugEntry->SizeOfData, &NextRequiredSize) ||
+ NextRequiredSize > SizeOfImage ||
+ NextRequiredSize > MaximumLoadedImageCodeViewReadSize)
+ {
+ continue;
+ }
+
+ RequiredSize = NextRequiredSize;
+ }
+ }
+
+ if (RequiredSize <= LoadedImageBytes.size())
+ {
+ LoadedImageBytes.resize(RequiredSize);
+ return TRUE;
+ }
+
+ return SymbolReadUserVirtualMemoryExact(BaseAddress, UserProcessId, RequiredSize, LoadedImageBytes);
+}
+
/**
* @brief Delete and free structures and variables related to the symbols
*
@@ -478,10 +762,10 @@ SymbolBuildSymbolTable(PMODULE_SYMBOL_DETAIL * BufferToStoreDetails,
ULONG ReturnedLength;
PRTL_PROCESS_MODULES ModuleInfo = NULL;
PMODULE_SYMBOL_DETAIL ModuleSymDetailArray = NULL;
- char SystemRoot[MAX_PATH] = {0};
- char ModuleSymbolPath[MAX_PATH] = {0};
- char TempPath[MAX_PATH] = {0};
- char ModuleSymbolGuidAndAge[MAXIMUM_GUID_AND_AGE_SIZE] = {0};
+ CHAR SystemRoot[MAX_PATH] = {0};
+ CHAR ModuleSymbolPath[MAX_PATH] = {0};
+ CHAR TempPath[MAX_PATH] = {0};
+ CHAR ModuleSymbolGuidAndAge[MAXIMUM_GUID_AND_AGE_SIZE] = {0};
BOOLEAN IsSymbolPdbDetailAvailable = FALSE;
BOOLEAN IsFreeUsermodeModulesBuffer = FALSE;
UINT32 ModuleDetailsSize = 0;
@@ -514,7 +798,7 @@ SymbolBuildSymbolTable(PMODULE_SYMBOL_DETAIL * BufferToStoreDetails,
transform(SystemRootString.begin(),
SystemRootString.end(),
SystemRootString.begin(),
- [](unsigned char c) { return std::tolower(c); });
+ [](UCHAR c) { return std::tolower(c); });
//
// Remove system32 from the root
@@ -631,7 +915,7 @@ SymbolBuildSymbolTable(PMODULE_SYMBOL_DETAIL * BufferToStoreDetails,
//
// check the module list
//
- if (ModuleCountRequest.Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
+ if (ModuleDetailsRequest->Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
{
//
// Se the modules buffer
@@ -651,7 +935,7 @@ SymbolBuildSymbolTable(PMODULE_SYMBOL_DETAIL * BufferToStoreDetails,
}
else
{
- ShowErrorMessage(ModuleCountRequest.Result);
+ ShowErrorMessage(ModuleDetailsRequest->Result);
free(ModuleDetailsRequest);
break;
}
@@ -725,17 +1009,31 @@ SymbolBuildSymbolTable(PMODULE_SYMBOL_DETAIL * BufferToStoreDetails,
RtlZeroMemory(ModuleSymbolPath, sizeof(ModuleSymbolPath));
RtlZeroMemory(TempPath, sizeof(TempPath));
RtlZeroMemory(ModuleSymbolGuidAndAge, sizeof(ModuleSymbolGuidAndAge));
+ std::vector LoadedImageBytes;
//
// Convert symbol path from unicode to ascii
//
wcstombs(TempPath, Modules[i].FilePath, MAX_PATH);
- if (ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetailsWrapper(
- TempPath,
- ModuleSymbolPath,
- ModuleSymbolGuidAndAge,
- ModuleDetailsRequest->Is32Bit))
+ if (SendOverSerial && Modules[i].BaseAddress != 0 &&
+ SymbolReadLoadedUserModuleForCodeView(Modules[i].BaseAddress, UserProcessId, LoadedImageBytes) &&
+ ScriptEngineConvertLoadedModuleToPdbFileAndGuidAndAgeDetailsWrapper(LoadedImageBytes.data(),
+ LoadedImageBytes.size(),
+ TempPath,
+ ModuleSymbolPath,
+ ModuleSymbolGuidAndAge,
+ ModuleDetailsRequest->Is32Bit))
+ {
+ IsSymbolPdbDetailAvailable = TRUE;
+
+ // ShowMessages("Hash : %s , Symbol path : %s\n", ModuleSymbolGuidAndAge, ModuleSymbolPath);
+ }
+ else if (ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetailsWrapper(
+ TempPath,
+ ModuleSymbolPath,
+ ModuleSymbolGuidAndAge,
+ ModuleDetailsRequest->Is32Bit))
{
IsSymbolPdbDetailAvailable = TRUE;
@@ -807,7 +1105,7 @@ SymbolBuildSymbolTable(PMODULE_SYMBOL_DETAIL * BufferToStoreDetails,
RtlZeroMemory(ModuleSymbolPath, sizeof(ModuleSymbolPath));
RtlZeroMemory(ModuleSymbolGuidAndAge, sizeof(ModuleSymbolGuidAndAge));
- string ModuleFullPath((const char *)ModuleInfo->Modules[i].FullPathName);
+ string ModuleFullPath((const CHAR *)ModuleInfo->Modules[i].FullPathName);
if (ModuleFullPath.rfind("\\SystemRoot\\", 0) == 0)
{
@@ -875,7 +1173,7 @@ SymbolBuildSymbolTable(PMODULE_SYMBOL_DETAIL * BufferToStoreDetails,
//
if (SendOverSerial)
{
- KdSendSymbolDetailPacket(&ModuleSymDetailArray[IndexInSymbolBuffer], i, ModuleInfo->NumberOfModules + ModulesCount);
+ KdSendSymbolDetailPacket(&ModuleSymDetailArray[IndexInSymbolBuffer], IndexInSymbolBuffer, ModuleInfo->NumberOfModules + ModulesCount);
}
}
@@ -1010,7 +1308,7 @@ SymbolCheckAndAllocateModuleInformation(PRTL_PROCESS_MODULES * Modules)
//
// Enable Debug privilege to the current token
//
- if (!SetDebugPrivilege())
+ if (!WindowsSetDebugPrivilege())
{
ShowMessages("err, couldn't set debug privilege\n");
return FALSE;
diff --git a/hyperdbg/libhyperdbg/code/debugger/tests/tests.cpp b/hyperdbg/libhyperdbg/code/debugger/tests/tests.cpp
index 1fb9aa68..2516858d 100644
--- a/hyperdbg/libhyperdbg/code/debugger/tests/tests.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/tests/tests.cpp
@@ -29,7 +29,7 @@ SetupTestName(_Inout_updates_bytes_all_(BufferLength) PCHAR TestLocation,
HANDLE fileHandle;
DWORD driverLocLen = 0;
HMODULE ProcHandle = GetModuleHandle(NULL);
- char * Pos;
+ CHAR * Pos;
//
// Get the current directory.
@@ -115,12 +115,12 @@ CreateProcessAndOpenPipeConnection(PHANDLE ConnectionPipeHandle,
HANDLE PipeHandle;
BOOLEAN SentMessageResult;
UINT32 ReadBytes;
- char * BufferToRead;
- char * BufferToSend;
- char HandshakeBuffer[] = "Hello, Dear Test Process... Yes, I'm HyperDbg Debugger :)";
+ CHAR * BufferToRead;
+ CHAR * BufferToSend;
+ CHAR HandshakeBuffer[] = "Hello, Dear Test Process... Yes, I'm HyperDbg Debugger :)";
PROCESS_INFORMATION ProcessInfo;
STARTUPINFO StartupInfo;
- char CmdArgs[] = TEST_PROCESS_NAME " im-hyperdbg";
+ CHAR CmdArgs[] = TEST_PROCESS_NAME " im-hyperdbg";
PipeHandle = NamedPipeServerCreatePipe("\\\\.\\Pipe\\HyperDbgTests",
TEST_CASE_MAXIMUM_BUFFERS_TO_COMMUNICATE,
@@ -133,7 +133,7 @@ CreateProcessAndOpenPipeConnection(PHANDLE ConnectionPipeHandle,
return FALSE;
}
- BufferToRead = (char *)malloc(TEST_CASE_MAXIMUM_BUFFERS_TO_COMMUNICATE);
+ BufferToRead = (CHAR *)malloc(TEST_CASE_MAXIMUM_BUFFERS_TO_COMMUNICATE);
if (!BufferToRead)
{
@@ -143,7 +143,7 @@ CreateProcessAndOpenPipeConnection(PHANDLE ConnectionPipeHandle,
return FALSE;
}
- BufferToSend = (char *)malloc(TEST_CASE_MAXIMUM_BUFFERS_TO_COMMUNICATE);
+ BufferToSend = (CHAR *)malloc(TEST_CASE_MAXIMUM_BUFFERS_TO_COMMUNICATE);
if (!BufferToSend)
{
diff --git a/hyperdbg/libhyperdbg/code/debugger/transparency/gaussian-rng.cpp b/hyperdbg/libhyperdbg/code/debugger/transparency/gaussian-rng.cpp
index a45cd251..dff25845 100644
--- a/hyperdbg/libhyperdbg/code/debugger/transparency/gaussian-rng.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/transparency/gaussian-rng.cpp
@@ -21,7 +21,7 @@
double
Median(vector Cases)
{
- size_t Size = Cases.size();
+ SIZE_T Size = Cases.size();
if (Size == 0)
{
@@ -52,7 +52,7 @@ template
T
Average(const vector & vec)
{
- size_t Sz;
+ SIZE_T Sz;
T Mean;
Sz = vec.size();
if (Sz == 1)
@@ -122,11 +122,11 @@ Randn(double mu, double sigma)
{
double U1, U2, W, mult;
static double X1, X2;
- static int call = 0;
+ static INT Call = 0;
- if (call == 1)
+ if (Call == 1)
{
- call = !call;
+ Call = !Call;
return (mu + sigma * (double)X2);
}
@@ -141,7 +141,7 @@ Randn(double mu, double sigma)
X1 = U1 * mult;
X2 = U2 * mult;
- call = !call;
+ Call = !Call;
return (mu + sigma * (double)X1);
}
@@ -158,7 +158,7 @@ VOID
GuassianGenerateRandom(vector Data, UINT64 * AverageOfData, UINT64 * StandardDeviationOfData, UINT64 * MedianOfData)
{
vector FinalData;
- int CountOfOutliers = 0;
+ INT CountOfOutliers = 0;
double Medians;
double Mad;
double StandardDeviation;
diff --git a/hyperdbg/libhyperdbg/code/debugger/transparency/transparency.cpp b/hyperdbg/libhyperdbg/code/debugger/transparency/transparency.cpp
index 48250170..9e3f6b67 100644
--- a/hyperdbg/libhyperdbg/code/debugger/transparency/transparency.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/transparency/transparency.cpp
@@ -16,13 +16,13 @@ using namespace std;
/**
* @brief get the difference clock cycles between two rdtsc(s)
*
- * @return unsigned long long
+ * @return UINT64
*/
-unsigned long long
+UINT64
TransparentModeRdtscDiffVmexit()
{
- unsigned long long ret, ret2;
- int cpuid_result[4] = {0};
+ UINT64 Ret, Ret2;
+ INT CpuidResult[4] = {0};
//
// GCC
@@ -33,7 +33,7 @@ TransparentModeRdtscDiffVmexit()
//
// Win32
//
- ret = __rdtsc();
+ Ret = CpuReadTsc();
/* vm exit forced here. it uses: eax = 0; cpuid; */
@@ -45,7 +45,7 @@ TransparentModeRdtscDiffVmexit()
//
// WIN32
//
- __cpuid(cpuid_result, 0);
+ CpuCpuId(CpuidResult, 0);
//
// GCC
@@ -56,44 +56,32 @@ TransparentModeRdtscDiffVmexit()
//
// WIN32
//
- ret2 = __rdtsc();
+ Ret2 = CpuReadTsc();
- return ret2 - ret;
+ return Ret2 - Ret;
}
/**
* @brief get the difference clock cycles between rdtsc+cpuid+rdtsc
*
- * @return unsigned long long
+ * @return UINT64
*/
-unsigned long long
+UINT64
TransparentModeRdtscVmexitTracing()
{
- unsigned long long ret, ret2;
-
- //
- // GCC
- //
- // __asm__ volatile("rdtsc" : "=a" (eax), "=d" (edx));
- // ret = ((unsigned long long)eax) | (((unsigned long long)edx) << 32);
+ UINT64 Ret, Ret2;
//
// WIN32
//
- ret = __rdtsc();
-
- //
- // GCC
- //
- // __asm__ volatile("rdtsc" : "=a"(eax), "=d"(edx));
- // ret2 = ((unsigned long long)eax) | (((unsigned long long)edx) << 32);
+ Ret = CpuReadTsc();
//
// WIN32
//
- ret2 = __rdtsc();
+ Ret2 = CpuReadTsc();
- return ret2 - ret;
+ return Ret2 - Ret;
}
/**
@@ -103,9 +91,9 @@ TransparentModeRdtscVmexitTracing()
* @param Average a pointer to save average on it
* @param StandardDeviation a pointer to standard deviation average on it
* @param Median a pointer to save median on it
- * @return int
+ * @return INT
*/
-int
+INT
TransparentModeCpuidTimeStampCounter(UINT64 * Average,
UINT64 * StandardDeviation,
UINT64 * Median)
@@ -145,9 +133,9 @@ TransparentModeCpuidTimeStampCounter(UINT64 * Average,
* @param Average a pointer to save average on it
* @param StandardDeviation a pointer to standard deviation average on it
* @param Median a pointer to save median on it
- * @return int
+ * @return INT
*/
-int
+INT
TransparentModeRdtscEmulationDetection(UINT64 * Average,
UINT64 * StandardDeviation,
UINT64 * Median)
diff --git a/hyperdbg/libhyperdbg/code/debugger/user-level/pe-parser.cpp b/hyperdbg/libhyperdbg/code/debugger/user-level/pe-parser.cpp
index 1b7900de..ce0dfc4a 100644
--- a/hyperdbg/libhyperdbg/code/debugger/user-level/pe-parser.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/user-level/pe-parser.cpp
@@ -11,6 +11,3651 @@
*/
#include "pch.h"
+/**
+ * @brief Returns a human-readable name for a PE subsystem identifier
+ *
+ * Maps the Subsystem field from IMAGE_OPTIONAL_HEADER to a descriptive string.
+ * Unknown subsystem values return "Unknown".
+ *
+ * @param Subsystem The Subsystem value from the PE optional header
+ *
+ * @return const CHAR* A static string describing the subsystem
+ */
+static const CHAR *
+PeGetSubsystemName(WORD Subsystem)
+{
+ switch (Subsystem)
+ {
+ case IMAGE_SUBSYSTEM_NATIVE:
+ return "Device Driver(Native windows Process)";
+ case IMAGE_SUBSYSTEM_WINDOWS_GUI:
+ return "Windows GUI";
+ case IMAGE_SUBSYSTEM_WINDOWS_CUI:
+ return "Windows CLI";
+ case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI:
+ return "Windows CE GUI";
+ default:
+ return "Unknown";
+ }
+}
+
+/**
+ * @brief Prints the set DLL characteristics flags from a PE optional header
+ *
+ * Iterates a table of known IMAGE_DLLCHARACTERISTICS_* flag values and prints
+ * the name of each flag that is set in DllCharacteristics, separated by commas.
+ * Prints "None" when no flags are set.
+ *
+ * @param DllCharacteristics The DllCharacteristics field from the PE optional header
+ */
+static VOID
+PeShowDllCharacteristics(WORD DllCharacteristics)
+{
+ BOOLEAN AnyFlag = FALSE;
+
+ struct DLL_CHARACTERISTIC_NAME
+ {
+ WORD Flag;
+ const CHAR * Name;
+ };
+
+ static const DLL_CHARACTERISTIC_NAME CommonDllCharacteristics[] = {
+ {IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA, "High Entropy VA"},
+ {IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE, "Dynamic Base"},
+ {IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY, "Force Integrity"},
+ {IMAGE_DLLCHARACTERISTICS_NX_COMPAT, "NX Compatible"},
+ {IMAGE_DLLCHARACTERISTICS_NO_ISOLATION, "No Isolation"},
+ {IMAGE_DLLCHARACTERISTICS_NO_SEH, "No SEH"},
+ {IMAGE_DLLCHARACTERISTICS_NO_BIND, "No Bind"},
+ {IMAGE_DLLCHARACTERISTICS_APPCONTAINER, "AppContainer"},
+ {IMAGE_DLLCHARACTERISTICS_WDM_DRIVER, "WDM Driver"},
+ {IMAGE_DLLCHARACTERISTICS_GUARD_CF, "Guard CF"},
+ {IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE, "Terminal Server Aware"},
+ };
+
+ for (UINT32 Index = 0; Index < RTL_NUMBER_OF(CommonDllCharacteristics); Index++)
+ {
+ if ((DllCharacteristics & CommonDllCharacteristics[Index].Flag) == CommonDllCharacteristics[Index].Flag)
+ {
+ ShowMessages("%s%s", AnyFlag ? ", " : "", CommonDllCharacteristics[Index].Name);
+ AnyFlag = TRUE;
+ }
+ }
+
+ if (!AnyFlag)
+ {
+ ShowMessages("None");
+ }
+}
+
+/**
+ * @brief Prints the raw file offset corresponding to the PE entrypoint RVA
+ *
+ * Resolves AddressOfEntryPoint through the section table to obtain a file offset
+ * and prints it. Prints "not mapped" when the RVA cannot be resolved.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param AddressOfEntryPoint The AddressOfEntryPoint field from the PE optional header
+ */
+static VOID
+PeShowEntrypointFileOffset(PPE_IMAGE_READER Reader, DWORD AddressOfEntryPoint)
+{
+ SIZE_T FileOffset = 0;
+
+ if (PeImageReaderRvaToFileOffset(Reader, AddressOfEntryPoint, 1, &FileOffset))
+ {
+ ShowMessages("\n%-36s%#llx", "Entrypoint file offset :", (UINT64)FileOffset);
+ }
+ else
+ {
+ ShowMessages("\n%-36s%s", "Entrypoint file offset :", "not mapped");
+ }
+}
+
+/**
+ * @brief Returns the name of a PE data directory by its index
+ *
+ * Maps IMAGE_DIRECTORY_ENTRY_* index values to descriptive strings using
+ * the standard ordering defined in the PE specification. Returns "Unknown"
+ * for indices at or beyond IMAGE_NUMBEROF_DIRECTORY_ENTRIES.
+ *
+ * @param Index Zero-based data directory index (IMAGE_DIRECTORY_ENTRY_*)
+ *
+ * @return const CHAR* A static string naming the data directory
+ */
+static const CHAR *
+PeGetDataDirectoryName(UINT32 Index)
+{
+ static const CHAR * DirectoryNames[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] = {
+ "Export Table",
+ "Import Table",
+ "Resource Table",
+ "Exception Table",
+ "Certificate Table",
+ "Base Relocation Table",
+ "Debug",
+ "Architecture",
+ "Global Ptr",
+ "TLS Table",
+ "Load Config Table",
+ "Bound Import",
+ "Import Address Table",
+ "Delay Import Descriptor",
+ "CLR Runtime Header",
+ "Reserved",
+ };
+
+ if (Index < RTL_NUMBER_OF(DirectoryNames))
+ {
+ return DirectoryNames[Index];
+ }
+
+ return "Unknown";
+}
+
+/**
+ * @brief Adds two DWORD values with overflow detection
+ *
+ * Returns FALSE without modifying Result when the addition would exceed MAXDWORD;
+ * otherwise writes the sum to *Result and returns TRUE.
+ *
+ * @param Left First operand
+ * @param Right Second operand
+ * @param Result Output pointer that receives the sum on success; must not be NULL
+ *
+ * @return BOOLEAN TRUE if the addition succeeded, FALSE on overflow or NULL pointer
+ */
+static BOOLEAN
+PeAddDword(DWORD Left, DWORD Right, DWORD * Result)
+{
+ if (Result == NULL || Right > MAXDWORD - Left)
+ {
+ return FALSE;
+ }
+
+ *Result = Left + Right;
+ return TRUE;
+}
+
+/**
+ * @brief Adds two ULONGLONG values with overflow detection
+ *
+ * Returns FALSE without modifying Result when the addition would overflow a
+ * 64-bit unsigned integer; otherwise writes the sum to *Result and returns TRUE.
+ *
+ * @param Left First operand
+ * @param Right Second operand
+ * @param Result Output pointer that receives the sum on success; must not be NULL
+ *
+ * @return BOOLEAN TRUE if the addition succeeded, FALSE on overflow or NULL pointer
+ */
+static BOOLEAN
+PeAddUlonglong(ULONGLONG Left, ULONGLONG Right, ULONGLONG * Result)
+{
+ if (Result == NULL || Right > (~((ULONGLONG)0) - Left))
+ {
+ return FALSE;
+ }
+
+ *Result = Left + Right;
+ return TRUE;
+}
+
+/**
+ * @brief Comparator for sorting PE_RAW_SECTION_RANGE entries by ascending start offset
+ *
+ * Intended for use with qsort(). Entries with the same Start are further ordered
+ * by End in ascending order.
+ *
+ * @param Left Pointer to the first PE_RAW_SECTION_RANGE to compare
+ * @param Right Pointer to the second PE_RAW_SECTION_RANGE to compare
+ *
+ * @return INT Negative if Left < Right, positive if Left > Right, zero if equal
+ */
+static INT
+PeCompareRawSectionRange(const VOID * Left, const VOID * Right)
+{
+ const PE_RAW_SECTION_RANGE * LeftRange = (const PE_RAW_SECTION_RANGE *)Left;
+ const PE_RAW_SECTION_RANGE * RightRange = (const PE_RAW_SECTION_RANGE *)Right;
+
+ if (LeftRange->Start < RightRange->Start)
+ {
+ return -1;
+ }
+
+ if (LeftRange->Start > RightRange->Start)
+ {
+ return 1;
+ }
+
+ if (LeftRange->End < RightRange->End)
+ {
+ return -1;
+ }
+
+ if (LeftRange->End > RightRange->End)
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Checks whether an RVA range is fully contained within another RVA range
+ *
+ * Both ranges are expressed as a base RVA and a size. Returns FALSE if any
+ * addition overflows or if [Rva, Rva+Size) extends outside [RangeRva, RangeRva+RangeSize).
+ *
+ * @param RangeRva Base RVA of the enclosing range
+ * @param RangeSize Size of the enclosing range in bytes
+ * @param Rva Base RVA of the range to test
+ * @param Size Size of the range to test in bytes
+ *
+ * @return BOOLEAN TRUE if [Rva, Rva+Size) lies entirely within [RangeRva, RangeRva+RangeSize)
+ */
+static BOOLEAN
+PeRvaContainsRange(DWORD RangeRva, DWORD RangeSize, DWORD Rva, DWORD Size)
+{
+ DWORD RangeEnd = 0;
+ DWORD RvaEnd = 0;
+
+ if (!PeAddDword(RangeRva, RangeSize, &RangeEnd) || !PeAddDword(Rva, Size, &RvaEnd))
+ {
+ return FALSE;
+ }
+
+ return Rva >= RangeRva && RvaEnd <= RangeEnd;
+}
+
+/**
+ * @brief Returns a validated pointer into the image at the location mapped by an RVA
+ *
+ * Translates Rva to a raw file offset via PeImageReaderRvaToFileOffset and then
+ * validates the range through PeImageReaderGetPointerAtOffset.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param Rva Relative virtual address to look up
+ * @param Length Number of bytes that must be accessible at the resolved offset
+ * @param Pointer Output pointer set to the resolved image location on success; must not be NULL
+ *
+ * @return BOOLEAN TRUE on success, FALSE if the RVA cannot be resolved or is out of bounds
+ */
+static BOOLEAN
+PeGetPointerAtRva(PPE_IMAGE_READER Reader, DWORD Rva, DWORD Length, const BYTE ** Pointer)
+{
+ SIZE_T FileOffset = 0;
+
+ if (!PeImageReaderRvaToFileOffset(Reader, Rva, Length, &FileOffset))
+ {
+ return FALSE;
+ }
+
+ return PeImageReaderGetPointerAtOffset(Reader, FileOffset, Length, Pointer);
+}
+
+typedef enum _PE_ASCII_STRING_STATUS
+{
+ PeAsciiStringInvalid,
+ PeAsciiStringOk,
+ PeAsciiStringTruncated,
+} PE_ASCII_STRING_STATUS;
+
+/**
+ * @brief Reads an ASCII string from the image at the given RVA
+ *
+ * Reads up to MaxLength bytes starting at Rva, stopping at the first null
+ * terminator. Non-printable bytes are replaced with '.'. The output buffer is
+ * always null-terminated. Returns PeAsciiStringInvalid if any mapped byte
+ * cannot be resolved, PeAsciiStringOk when the null terminator is found within
+ * MaxLength, and PeAsciiStringTruncated otherwise.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param Rva Starting RVA of the string
+ * @param MaxLength Maximum number of bytes to scan
+ * @param Buffer Destination buffer for the null-terminated output
+ * @param BufferSize Size of Buffer in bytes; must be at least 1
+ *
+ * @return PE_ASCII_STRING_STATUS Result indicating whether the string was read successfully
+ */
+static PE_ASCII_STRING_STATUS
+PeReadAsciiStringAtRva(PPE_IMAGE_READER Reader, DWORD Rva, DWORD MaxLength, CHAR * Buffer, SIZE_T BufferSize)
+{
+ if (Buffer == NULL || BufferSize == 0 || MaxLength == 0)
+ {
+ return PeAsciiStringInvalid;
+ }
+
+ Buffer[0] = '\0';
+
+ SIZE_T OutputIndex = 0;
+ for (DWORD Index = 0; Index < MaxLength; Index++)
+ {
+ DWORD CharacterRva = 0;
+ const BYTE * Character = NULL;
+
+ if (!PeAddDword(Rva, Index, &CharacterRva) || !PeGetPointerAtRva(Reader, CharacterRva, 1, &Character))
+ {
+ return PeAsciiStringInvalid;
+ }
+
+ if (*Character == '\0')
+ {
+ return PeAsciiStringOk;
+ }
+
+ if (OutputIndex + 1 < BufferSize)
+ {
+ Buffer[OutputIndex++] = (*Character >= 0x20 && *Character <= 0x7e) ? (CHAR)*Character : '.';
+ Buffer[OutputIndex] = '\0';
+ }
+ }
+
+ return PeAsciiStringTruncated;
+}
+
+/**
+ * @brief Returns a human-readable description of a PE_ASCII_STRING_STATUS value
+ *
+ * @param Status The status value returned by PeReadAsciiStringAtRva or related functions
+ *
+ * @return const CHAR* A static string describing the status
+ */
+static const CHAR *
+PeAsciiStatusName(PE_ASCII_STRING_STATUS Status)
+{
+ switch (Status)
+ {
+ case PeAsciiStringInvalid:
+ return "invalid mapping";
+ case PeAsciiStringTruncated:
+ return "truncated or unterminated";
+ default:
+ return "readable";
+ }
+}
+
+/**
+ * @brief Converts an absolute virtual address to a relative virtual address
+ *
+ * Subtracts ImageBase from Va and checks that the difference fits in a DWORD.
+ * Returns FALSE when Va < ImageBase or when the difference exceeds MAXDWORD.
+ *
+ * @param Va Absolute virtual address to convert
+ * @param ImageBase Base address of the image
+ * @param Rva Output pointer that receives the RVA on success; must not be NULL
+ *
+ * @return BOOLEAN TRUE on success, FALSE when the conversion is not representable
+ */
+static BOOLEAN
+PeVaToRva(ULONGLONG Va, ULONGLONG ImageBase, DWORD * Rva)
+{
+ ULONGLONG Difference = 0;
+
+ if (Rva == NULL || Va < ImageBase)
+ {
+ return FALSE;
+ }
+
+ Difference = Va - ImageBase;
+ if (Difference > MAXDWORD)
+ {
+ return FALSE;
+ }
+
+ *Rva = (DWORD)Difference;
+ return TRUE;
+}
+
+/**
+ * @brief Reads a DWORD from a byte buffer at the specified byte offset
+ *
+ * Uses CopyMemory to avoid strict-aliasing and alignment issues.
+ *
+ * @param Buffer Pointer to the source byte buffer
+ * @param Offset Byte offset within Buffer at which to read
+ *
+ * @return DWORD The 32-bit value read from Buffer + Offset
+ */
+static DWORD
+PeReadDwordFromBuffer(const BYTE * Buffer, SIZE_T Offset)
+{
+ DWORD Value = 0;
+
+ CopyMemory(&Value, Buffer + Offset, sizeof(Value));
+ return Value;
+}
+
+/**
+ * @brief Reads a WORD from a byte buffer at the specified byte offset
+ *
+ * Uses CopyMemory to avoid strict-aliasing and alignment issues.
+ *
+ * @param Buffer Pointer to the source byte buffer
+ * @param Offset Byte offset within Buffer at which to read
+ *
+ * @return WORD The 16-bit value read from Buffer + Offset
+ */
+static WORD
+PeReadWordFromBuffer(const BYTE * Buffer, SIZE_T Offset)
+{
+ WORD Value = 0;
+
+ CopyMemory(&Value, Buffer + Offset, sizeof(Value));
+ return Value;
+}
+
+/**
+ * @brief Reads a BYTE from a byte buffer at the specified byte offset
+ *
+ * Uses CopyMemory to provide a consistent read interface.
+ *
+ * @param Buffer Pointer to the source byte buffer
+ * @param Offset Byte offset within Buffer at which to read
+ *
+ * @return BYTE The 8-bit value read from Buffer + Offset
+ */
+static BYTE
+PeReadByteFromBuffer(const BYTE * Buffer, SIZE_T Offset)
+{
+ BYTE Value = 0;
+
+ CopyMemory(&Value, Buffer + Offset, sizeof(Value));
+ return Value;
+}
+
+/**
+ * @brief Reads a ULONGLONG from a byte buffer at the specified byte offset
+ *
+ * Uses CopyMemory to avoid strict-aliasing and alignment issues.
+ *
+ * @param Buffer Pointer to the source byte buffer
+ * @param Offset Byte offset within Buffer at which to read
+ *
+ * @return ULONGLONG The 64-bit value read from Buffer + Offset
+ */
+static ULONGLONG
+PeReadQwordFromBuffer(const BYTE * Buffer, SIZE_T Offset)
+{
+ ULONGLONG Value = 0;
+
+ CopyMemory(&Value, Buffer + Offset, sizeof(Value));
+ return Value;
+}
+
+/**
+ * @brief Reads a pointer-sized value from a load configuration structure
+ *
+ * Reads a DWORD when Is32Bit is TRUE (PE32 pointer), or a QWORD when FALSE
+ * (PE32+ pointer), returning the result as a ULONGLONG in both cases.
+ *
+ * @param Buffer Pointer to the load configuration byte buffer
+ * @param Offset Byte offset within Buffer of the field to read
+ * @param Is32Bit TRUE to read a 32-bit pointer, FALSE to read a 64-bit pointer
+ *
+ * @return ULONGLONG The pointer value widened to 64 bits
+ */
+static ULONGLONG
+PeReadLoadConfigPointer(const BYTE * Buffer, SIZE_T Offset, BOOLEAN Is32Bit)
+{
+ return Is32Bit ? PeReadDwordFromBuffer(Buffer, Offset) : PeReadQwordFromBuffer(Buffer, Offset);
+}
+
+/**
+ * @brief Reads an ASCII string from a raw byte pointer up to MaxLength bytes
+ *
+ * Scans StringPointer[0..MaxLength-1] for a null terminator. Non-printable
+ * bytes are replaced with '.'. The output is always null-terminated.
+ * Returns PeAsciiStringOk when the terminator is found, PeAsciiStringTruncated
+ * when MaxLength is exhausted without a terminator, and PeAsciiStringInvalid
+ * on NULL arguments.
+ *
+ * @param StringPointer Pointer to the source ASCII data; must not be NULL
+ * @param MaxLength Maximum number of bytes to scan
+ * @param Buffer Destination buffer for the null-terminated output
+ * @param BufferSize Size of Buffer in bytes; must be at least 1
+ *
+ * @return PE_ASCII_STRING_STATUS Result indicating whether the string was read successfully
+ */
+static PE_ASCII_STRING_STATUS
+PeReadAsciiStringFromBuffer(const BYTE * StringPointer, DWORD MaxLength, CHAR * Buffer, SIZE_T BufferSize)
+{
+ if (StringPointer == NULL || Buffer == NULL || BufferSize == 0 || MaxLength == 0)
+ {
+ return PeAsciiStringInvalid;
+ }
+
+ Buffer[0] = '\0';
+
+ SIZE_T OutputIndex = 0;
+ for (DWORD Index = 0; Index < MaxLength; Index++)
+ {
+ if (StringPointer[Index] == '\0')
+ {
+ return PeAsciiStringOk;
+ }
+
+ if (OutputIndex + 1 < BufferSize)
+ {
+ Buffer[OutputIndex++] = (StringPointer[Index] >= 0x20 && StringPointer[Index] <= 0x7e) ? (CHAR)StringPointer[Index] : '.';
+ Buffer[OutputIndex] = '\0';
+ }
+ }
+
+ return PeAsciiStringTruncated;
+}
+
+/**
+ * @brief Reads an ASCII string located at a fixed offset within a PE data directory
+ *
+ * Computes the target RVA as Directory->VirtualAddress + Offset, clamps the
+ * maximum read length to the remaining bytes in the directory, and delegates
+ * to PeReadAsciiStringAtRva.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param Directory Pointer to the data directory entry that contains the string
+ * @param Offset Byte offset within the directory at which the string begins
+ * @param MaxLength Maximum number of bytes to scan for the null terminator
+ * @param Buffer Destination buffer for the null-terminated output
+ * @param BufferSize Size of Buffer in bytes
+ *
+ * @return PE_ASCII_STRING_STATUS Result indicating whether the string was read successfully
+ */
+static PE_ASCII_STRING_STATUS
+PeReadAsciiStringInDirectory(PPE_IMAGE_READER Reader,
+ const IMAGE_DATA_DIRECTORY * Directory,
+ DWORD Offset,
+ DWORD MaxLength,
+ CHAR * Buffer,
+ SIZE_T BufferSize)
+{
+ DWORD StringRva = 0;
+
+ if (Directory == NULL || Offset >= Directory->Size || !PeAddDword(Directory->VirtualAddress, Offset, &StringRva))
+ {
+ return PeAsciiStringInvalid;
+ }
+
+ DWORD Remaining = Directory->Size - Offset;
+ return PeReadAsciiStringAtRva(Reader, StringRva, Remaining < MaxLength ? Remaining : MaxLength, Buffer, BufferSize);
+}
+
+/**
+ * @brief Computes the standard PE file checksum
+ *
+ * Implements the algorithm used by the Windows PE loader: sums all 16-bit
+ * words of the image (treating the checksum field itself as zero), folds the
+ * carry, and adds the total image size. The result matches the value stored
+ * in the optional header CheckSum field for well-formed images.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param ChecksumOffset Raw file offset of the 4-byte checksum field (excluded from summation)
+ * @param Checksum Output pointer that receives the computed checksum on success
+ *
+ * @return BOOLEAN TRUE on success, FALSE on NULL arguments or invalid checksum offset
+ */
+static BOOLEAN
+PeComputeChecksum(PPE_IMAGE_READER Reader, SIZE_T ChecksumOffset, DWORD * Checksum)
+{
+ ULONGLONG Sum = 0;
+
+ if (Reader == NULL || Checksum == NULL || ChecksumOffset > Reader->ImageSize || sizeof(DWORD) > Reader->ImageSize - ChecksumOffset)
+ {
+ return FALSE;
+ }
+
+ for (SIZE_T Offset = 0; Offset < Reader->ImageSize; Offset += sizeof(WORD))
+ {
+ WORD Value = 0;
+
+ if (Offset >= ChecksumOffset && Offset < ChecksumOffset + sizeof(DWORD))
+ {
+ Value = 0;
+ }
+ else if (Offset + 1 < Reader->ImageSize)
+ {
+ CopyMemory(&Value, Reader->ImageBase + Offset, sizeof(Value));
+ }
+ else
+ {
+ Value = Reader->ImageBase[Offset];
+ }
+
+ Sum += Value;
+ Sum = (Sum & 0xffff) + (Sum >> 16);
+ }
+
+ Sum = (Sum & 0xffff) + (Sum >> 16);
+ *Checksum = (DWORD)Sum + (DWORD)Reader->ImageSize;
+ return TRUE;
+}
+
+/**
+ * @brief Prints the stored and computed PE optional header checksums
+ *
+ * Displays HeaderChecksum as read from the optional header and, when the image
+ * is small enough, also computes and displays the expected value via
+ * PeComputeChecksum. Skips computation for images larger than 64 MiB.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER (may be NULL to skip computation)
+ * @param HeaderChecksum Checksum value as stored in the PE optional header
+ * @param ChecksumOffset Raw file offset of the checksum field within the image
+ */
+static VOID
+PeShowChecksum(PPE_IMAGE_READER Reader, DWORD HeaderChecksum, SIZE_T ChecksumOffset)
+{
+ const SIZE_T MaxChecksumBytes = 64 * 1024 * 1024;
+ DWORD ComputedChecksum = 0;
+
+ ShowMessages("\n%-36s%#x", "Optional header checksum :", HeaderChecksum);
+ if (Reader != NULL && Reader->ImageSize > MaxChecksumBytes)
+ {
+ ShowMessages("\n%-36s%s", "Computed PE checksum :", "skipped, file is larger than local cap");
+ return;
+ }
+
+ if (PeComputeChecksum(Reader, ChecksumOffset, &ComputedChecksum))
+ {
+ ShowMessages("\n%-36s%#x (%s)", "Computed PE checksum :", ComputedChecksum, ComputedChecksum == HeaderChecksum ? "matches" : "differs");
+ }
+ else
+ {
+ ShowMessages("\n%-36s%s", "Computed PE checksum :", "not available");
+ }
+}
+
+/**
+ * @brief Prints the contents of the PE certificate (security) directory
+ *
+ * The certificate directory is stored at a raw file offset rather than an RVA.
+ * Iterates WIN_CERTIFICATE entries, printing the file offset, length, revision,
+ * and type of each. Stops when the directory is empty, invalid, or a certificate
+ * length or alignment error is detected.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param SecurityDirectory Pointer to the IMAGE_DIRECTORY_ENTRY_SECURITY data directory entry
+ */
+static VOID
+PeShowCertificateTable(PPE_IMAGE_READER Reader, const IMAGE_DATA_DIRECTORY * SecurityDirectory)
+{
+ const DWORD MaxCertificates = 0x1000;
+
+ ShowMessages("\n\nCertificate table\n-----------------");
+
+ if (SecurityDirectory->VirtualAddress == 0 || SecurityDirectory->Size == 0)
+ {
+ ShowMessages("\n%-36s%s", "Certificate table :", "empty");
+ return;
+ }
+
+ const BYTE * DirectoryPointer = NULL;
+ if (!PeImageReaderGetPointerAtOffset(Reader, SecurityDirectory->VirtualAddress, SecurityDirectory->Size, &DirectoryPointer))
+ {
+ ShowMessages("\n%-36s%s", "Certificate table :", "invalid bounds");
+ return;
+ }
+
+ DWORD Offset = 0;
+ DWORD Count = 0;
+ while (Offset < SecurityDirectory->Size && Count < MaxCertificates)
+ {
+ if (SecurityDirectory->Size - Offset < 8)
+ {
+ ShowMessages("\n%-36s%#llx", "Warning, truncated certificate at :", (UINT64)SecurityDirectory->VirtualAddress + Offset);
+ break;
+ }
+
+ const BYTE * Entry = DirectoryPointer + Offset;
+ DWORD Length = PeReadDwordFromBuffer(Entry, 0);
+ WORD Revision = PeReadWordFromBuffer(Entry, 4);
+ WORD Type = PeReadWordFromBuffer(Entry, 6);
+
+ ShowMessages("\n[%u] file offset %#llx length %#x revision %#x type %#x", Count, (UINT64)SecurityDirectory->VirtualAddress + Offset, Length, Revision, Type);
+
+ if (Length < 8)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "certificate length is smaller than header");
+ break;
+ }
+
+ if (Length > SecurityDirectory->Size - Offset)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "certificate entry extends past directory");
+ break;
+ }
+
+ DWORD AlignedLength = (Length + 7) & ~7u;
+ if (AlignedLength < Length || AlignedLength > SecurityDirectory->Size - Offset)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "certificate alignment extends past directory");
+ break;
+ }
+
+ Offset += AlignedLength;
+ Count++;
+ }
+
+ ShowMessages("\n%-36s%u", "Certificate entry count :", Count);
+ if (Count == MaxCertificates)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, certificate cap reached :", MaxCertificates);
+ }
+}
+
+/**
+ * @brief Prints base relocation blocks and per-type entry counts
+ *
+ * Iterates IMAGE_BASE_RELOCATION blocks within the .reloc directory,
+ * printing the page RVA, block size, and entry count for each. Accumulates
+ * a per-type summary and emits warnings for malformed or oversized data.
+ * Processing stops at 0x10000 blocks or 0x100000 entries.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param RelocDirectory Pointer to the IMAGE_DIRECTORY_ENTRY_BASERELOC data directory entry
+ */
+static VOID
+PeShowBaseRelocations(PPE_IMAGE_READER Reader, const IMAGE_DATA_DIRECTORY * RelocDirectory)
+{
+ const DWORD MaxBlocks = 0x10000;
+ const DWORD MaxEntries = 0x100000;
+ const DWORD MaxPrintedBlocks = 0x20;
+ DWORD TypeCounts[16] = {0};
+ DWORD BlockCount = 0;
+ ULONGLONG EntryCount = 0;
+ BOOLEAN EntryCapped = FALSE;
+
+ ShowMessages("\n\nBase relocations\n----------------");
+
+ if (RelocDirectory->VirtualAddress == 0 || RelocDirectory->Size == 0)
+ {
+ ShowMessages("\n%-36s%s", "Base relocation table :", "empty");
+ return;
+ }
+
+ DWORD Offset = 0;
+ while (Offset < RelocDirectory->Size && BlockCount < MaxBlocks && EntryCount < MaxEntries)
+ {
+ DWORD BlockRva = 0;
+ if (!PeAddDword(RelocDirectory->VirtualAddress, Offset, &BlockRva) || RelocDirectory->Size - Offset < sizeof(IMAGE_BASE_RELOCATION))
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "relocation block header is truncated");
+ break;
+ }
+
+ const BYTE * BlockPointer = NULL;
+ if (!PeGetPointerAtRva(Reader, BlockRva, sizeof(IMAGE_BASE_RELOCATION), &BlockPointer))
+ {
+ ShowMessages("\n%-36s%#x", "Warning, invalid relocation block RVA :", BlockRva);
+ break;
+ }
+
+ DWORD PageRva = PeReadDwordFromBuffer(BlockPointer, 0);
+ DWORD SizeOfBlock = PeReadDwordFromBuffer(BlockPointer, 4);
+
+ if (SizeOfBlock < sizeof(IMAGE_BASE_RELOCATION))
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "relocation block size is smaller than header");
+ break;
+ }
+
+ if (SizeOfBlock > RelocDirectory->Size - Offset)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "relocation block extends past directory");
+ break;
+ }
+
+ if (((SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) & 1) != 0)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, odd relocation block size :", SizeOfBlock);
+ }
+
+ DWORD EntriesInBlock = (SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
+ if (BlockCount < MaxPrintedBlocks)
+ {
+ ShowMessages("\n[%u] page RVA %#x block size %#x entries %u", BlockCount, PageRva, SizeOfBlock, EntriesInBlock);
+ }
+
+ DWORD EntriesRva = 0;
+ if (!PeAddDword(BlockRva, sizeof(IMAGE_BASE_RELOCATION), &EntriesRva))
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "relocation entries RVA overflow");
+ break;
+ }
+
+ const BYTE * Entries = NULL;
+ if (EntriesInBlock != 0 && !PeGetPointerAtRva(Reader, EntriesRva, EntriesInBlock * sizeof(WORD), &Entries))
+ {
+ ShowMessages("\n%-36s%#x", "Warning, invalid relocation entries RVA :", EntriesRva);
+ break;
+ }
+
+ for (DWORD EntryIndex = 0; EntryIndex < EntriesInBlock && EntryCount < MaxEntries; EntryIndex++)
+ {
+ WORD Entry = PeReadWordFromBuffer(Entries, EntryIndex * sizeof(WORD));
+ WORD Type = (Entry >> 12) & 0xf;
+
+ TypeCounts[Type]++;
+ EntryCount++;
+ if (EntryCount == MaxEntries)
+ {
+ EntryCapped = TRUE;
+ break;
+ }
+
+ if (Type == IMAGE_REL_BASED_HIGHADJ)
+ {
+ if (EntryIndex + 1 >= EntriesInBlock)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "HIGHADJ relocation is missing its pair entry");
+ }
+ else
+ {
+ EntryIndex++;
+ EntryCount++;
+ }
+ }
+ }
+
+ if (EntryCount == MaxEntries)
+ {
+ EntryCapped = TRUE;
+ }
+
+ Offset += SizeOfBlock;
+ BlockCount++;
+ }
+
+ ShowMessages("\n%-36s%u", "Relocation block count :", BlockCount);
+ ShowMessages("\n%-36s%llu", "Relocation entry count :", EntryCount);
+ for (DWORD Type = 0; Type < RTL_NUMBER_OF(TypeCounts); Type++)
+ {
+ if (TypeCounts[Type] != 0)
+ {
+ ShowMessages("\n%-36s%u = %u", "Relocation type count :", Type, TypeCounts[Type]);
+ }
+ }
+
+ if (BlockCount == MaxBlocks)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, relocation block cap reached :", MaxBlocks);
+ }
+ if (EntryCapped)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, relocation entry cap reached :", MaxEntries);
+ }
+ if (BlockCount > MaxPrintedBlocks)
+ {
+ ShowMessages("\n%-36s%#x", "Info, printed relocation blocks :", MaxPrintedBlocks);
+ }
+}
+
+/**
+ * @brief Prints bound import descriptors and their forwarder references
+ *
+ * Iterates IMAGE_BOUND_IMPORT_DESCRIPTOR entries, printing the module name,
+ * timestamp, and forwader reference count for each. Also expands forwader
+ * references inline. Processing stops after 0x1000 descriptors.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param BoundImportDirectory Pointer to the IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT data directory entry
+ */
+static VOID
+PeShowBoundImports(PPE_IMAGE_READER Reader, const IMAGE_DATA_DIRECTORY * BoundImportDirectory)
+{
+ const DWORD MaxDescriptors = 0x1000;
+ const DWORD MaxNameLength = 0x200;
+
+ ShowMessages("\n\nBound imports\n-------------");
+
+ if (BoundImportDirectory->VirtualAddress == 0 || BoundImportDirectory->Size == 0)
+ {
+ ShowMessages("\n%-36s%s", "Bound import directory :", "empty");
+ return;
+ }
+
+ DWORD Offset = 0;
+ DWORD DescriptorCount = 0;
+ while (Offset < BoundImportDirectory->Size && DescriptorCount < MaxDescriptors)
+ {
+ DWORD DescriptorRva = 0;
+ if (!PeAddDword(BoundImportDirectory->VirtualAddress, Offset, &DescriptorRva) || BoundImportDirectory->Size - Offset < sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR))
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "bound import descriptor is truncated");
+ break;
+ }
+
+ const BYTE * Descriptor = NULL;
+ if (!PeGetPointerAtRva(Reader, DescriptorRva, sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR), &Descriptor))
+ {
+ ShowMessages("\n%-36s%#x", "Warning, invalid bound descriptor RVA :", DescriptorRva);
+ break;
+ }
+
+ DWORD TimeDateStamp = PeReadDwordFromBuffer(Descriptor, 0);
+ WORD OffsetModuleName = PeReadWordFromBuffer(Descriptor, 4);
+ WORD NumberOfModuleForwarders = PeReadWordFromBuffer(Descriptor, 6);
+
+ if (TimeDateStamp == 0 && OffsetModuleName == 0 && NumberOfModuleForwarders == 0)
+ {
+ break;
+ }
+
+ CHAR ModuleName[MaxNameLength + 1] = {0};
+ PE_ASCII_STRING_STATUS NameStatus = PeReadAsciiStringInDirectory(Reader,
+ BoundImportDirectory,
+ OffsetModuleName,
+ MaxNameLength,
+ ModuleName,
+ sizeof(ModuleName));
+
+ ShowMessages("\n[%u] module %s timestamp %#x forwarder refs %u",
+ DescriptorCount,
+ NameStatus == PeAsciiStringOk ? ModuleName : PeAsciiStatusName(NameStatus),
+ TimeDateStamp,
+ NumberOfModuleForwarders);
+
+ DWORD DescriptorSpan = sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR) + (NumberOfModuleForwarders * (DWORD)sizeof(IMAGE_BOUND_FORWARDER_REF));
+ if (DescriptorSpan > BoundImportDirectory->Size - Offset)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "bound import forwarder refs extend past directory");
+ break;
+ }
+
+ for (WORD ForwarderIndex = 0; ForwarderIndex < NumberOfModuleForwarders; ForwarderIndex++)
+ {
+ DWORD ForwarderOffset = Offset + sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR) + (ForwarderIndex * (DWORD)sizeof(IMAGE_BOUND_FORWARDER_REF));
+ DWORD ForwarderRva = 0;
+
+ if (!PeAddDword(BoundImportDirectory->VirtualAddress, ForwarderOffset, &ForwarderRva))
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "bound forwarder RVA overflow");
+ break;
+ }
+
+ const BYTE * Forwarder = NULL;
+ if (!PeGetPointerAtRva(Reader, ForwarderRva, sizeof(IMAGE_BOUND_FORWARDER_REF), &Forwarder))
+ {
+ ShowMessages("\n%-36s%#x", "Warning, invalid bound forwarder RVA :", ForwarderRva);
+ break;
+ }
+
+ DWORD ForwarderTimeDateStamp = PeReadDwordFromBuffer(Forwarder, 0);
+ WORD ForwarderOffsetModuleName = PeReadWordFromBuffer(Forwarder, 4);
+ CHAR ForwarderName[MaxNameLength + 1] = {0};
+
+ PE_ASCII_STRING_STATUS ForwarderNameStatus = PeReadAsciiStringInDirectory(Reader,
+ BoundImportDirectory,
+ ForwarderOffsetModuleName,
+ MaxNameLength,
+ ForwarderName,
+ sizeof(ForwarderName));
+ ShowMessages("\n [%u] forwarder %s timestamp %#x",
+ ForwarderIndex,
+ ForwarderNameStatus == PeAsciiStringOk ? ForwarderName : PeAsciiStatusName(ForwarderNameStatus),
+ ForwarderTimeDateStamp);
+ }
+
+ Offset += DescriptorSpan;
+ DescriptorCount++;
+ }
+
+ ShowMessages("\n%-36s%u", "Bound import descriptor count :", DescriptorCount);
+ if (DescriptorCount == MaxDescriptors)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, bound import cap reached :", MaxDescriptors);
+ }
+}
+
+/**
+ * @brief Computes the 64-bit FNV-1a hash of a byte buffer
+ *
+ * Uses the standard FNV-1a parameters: offset basis 14695981039346656037
+ * and prime 1099511628211. Suitable for non-cryptographic fingerprinting.
+ *
+ * @param Data Pointer to the input data
+ * @param Size Number of bytes to hash
+ *
+ * @return ULONGLONG The 64-bit FNV-1a hash value
+ */
+static ULONGLONG
+PeFnv1a64(const BYTE * Data, DWORD Size)
+{
+ ULONGLONG Hash = 14695981039346656037ull;
+
+ for (DWORD Index = 0; Index < Size; Index++)
+ {
+ Hash ^= Data[Index];
+ Hash *= 1099511628211ull;
+ }
+
+ return Hash;
+}
+
+/**
+ * @brief Computes the Shannon entropy of a byte buffer
+ *
+ * Calculates the frequency of each byte value (0-255) and applies the
+ * standard information-entropy formula. A return value near 8.0 indicates
+ * high entropy (e.g. compressed or encrypted data); values near 0.0 indicate
+ * low entropy (e.g. sparse, mostly-zero data).
+ *
+ * @param Data Pointer to the input data
+ * @param Size Number of bytes to analyse
+ *
+ * @return double Shannon entropy in bits per byte (0.0 to 8.0)
+ */
+static double
+PeCalculateEntropy(const BYTE * Data, DWORD Size)
+{
+ DWORD Counts[256] = {0};
+ double Entropy = 0.0;
+
+ for (DWORD Index = 0; Index < Size; Index++)
+ {
+ Counts[Data[Index]]++;
+ }
+
+ for (DWORD Index = 0; Index < RTL_NUMBER_OF(Counts); Index++)
+ {
+ if (Counts[Index] != 0)
+ {
+ double Probability = (double)Counts[Index] / (double)Size;
+ Entropy -= Probability * (log(Probability) / log(2.0));
+ }
+ }
+
+ return Entropy;
+}
+
+/**
+ * @brief Reads a 16-bit word from the image at the location mapped by an RVA
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param Rva Relative virtual address to read from
+ * @param Value Output pointer that receives the WORD value on success; must not be NULL
+ *
+ * @return BOOLEAN TRUE on success, FALSE if the RVA cannot be resolved or Value is NULL
+ */
+static BOOLEAN
+PeReadWordAtRva(PPE_IMAGE_READER Reader, DWORD Rva, WORD * Value)
+{
+ const BYTE * Pointer = NULL;
+
+ if (Value == NULL || !PeGetPointerAtRva(Reader, Rva, sizeof(WORD), &Pointer))
+ {
+ return FALSE;
+ }
+
+ CopyMemory(Value, Pointer, sizeof(*Value));
+ return TRUE;
+}
+
+/**
+ * @brief Reads an import/export thunk value (DWORD or QWORD) from an RVA
+ *
+ * Reads sizeof(DWORD) bytes when Is32Bit is TRUE, or sizeof(ULONGLONG) bytes
+ * when FALSE, and widens the result to a ULONGLONG.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param Rva Relative virtual address of the thunk entry
+ * @param Is32Bit TRUE to read a 32-bit thunk, FALSE to read a 64-bit thunk
+ * @param Value Output pointer that receives the thunk value on success; must not be NULL
+ *
+ * @return BOOLEAN TRUE on success, FALSE if the RVA cannot be resolved or Value is NULL
+ */
+static BOOLEAN
+PeReadThunkAtRva(PPE_IMAGE_READER Reader, DWORD Rva, BOOLEAN Is32Bit, ULONGLONG * Value)
+{
+ const BYTE * Pointer = NULL;
+ DWORD Size = Is32Bit ? sizeof(DWORD) : sizeof(ULONGLONG);
+
+ if (Value == NULL || !PeGetPointerAtRva(Reader, Rva, Size, &Pointer))
+ {
+ return FALSE;
+ }
+
+ if (Is32Bit)
+ {
+ DWORD Value32 = 0;
+ CopyMemory(&Value32, Pointer, sizeof(Value32));
+ *Value = Value32;
+ }
+ else
+ {
+ CopyMemory(Value, Pointer, sizeof(*Value));
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Prints a named resource type identifier and its occurrence count
+ *
+ * Maps well-known RT_* integer type identifiers (1-12, 14, 16, 24) to
+ * human-readable names. Unknown or unnamed type IDs are silently ignored.
+ *
+ * @param TypeId Numeric resource type identifier (RT_* value)
+ * @param Count Number of resources of this type found in the resource directory
+ */
+static VOID
+PeShowResourceTypeCount(DWORD TypeId, DWORD Count)
+{
+ const CHAR * TypeName = NULL;
+
+ switch (TypeId)
+ {
+ case 1:
+ TypeName = "cursor";
+ break;
+ case 2:
+ TypeName = "bitmap";
+ break;
+ case 3:
+ TypeName = "icon";
+ break;
+ case 4:
+ TypeName = "menu";
+ break;
+ case 5:
+ TypeName = "dialog";
+ break;
+ case 6:
+ TypeName = "string";
+ break;
+ case 7:
+ TypeName = "font directory";
+ break;
+ case 8:
+ TypeName = "font";
+ break;
+ case 9:
+ TypeName = "accelerator";
+ break;
+ case 10:
+ TypeName = "rcdata";
+ break;
+ case 11:
+ TypeName = "message table";
+ break;
+ case 12:
+ TypeName = "group cursor";
+ break;
+ case 14:
+ TypeName = "group icon";
+ break;
+ case 16:
+ TypeName = "version";
+ break;
+ case 24:
+ TypeName = "manifest";
+ break;
+ default:
+ TypeName = NULL;
+ break;
+ }
+
+ if (TypeName != NULL)
+ {
+ ShowMessages("\n%-36s%s (%u) = %u", "Resource type count :", TypeName, TypeId, Count);
+ }
+}
+
+/**
+ * @brief Traverses and prints the PE resource directory tree
+ *
+ * Performs an iterative depth-first walk of the three-level resource directory
+ * (type / name or id / language), printing directory and data-entry statistics.
+ * Accumulates per-type counts for well-known resource types and reports total
+ * declared and mapped data bytes. Processing is capped at 0x4000 nodes and
+ * 0x10000 entries to prevent runaway on corrupt images.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param ResourceDirectory Pointer to the IMAGE_DIRECTORY_ENTRY_RESOURCE data directory entry
+ */
+static VOID
+PeShowResources(PPE_IMAGE_READER Reader, const IMAGE_DATA_DIRECTORY * ResourceDirectory)
+{
+ const DWORD MaxDepth = 8;
+ const DWORD MaxNodes = 0x4000;
+ const DWORD MaxEntries = 0x10000;
+ const DWORD MaxVisitedOffsets = 0x4000;
+
+ typedef struct _RESOURCE_NODE
+ {
+ DWORD Offset;
+ DWORD Depth;
+ DWORD TypeId;
+ } RESOURCE_NODE;
+
+ RESOURCE_NODE * Stack = NULL;
+ DWORD * Visited = NULL;
+ DWORD StackCount = 0;
+ DWORD VisitedCount = 0;
+ DWORD TypeCounts[25] = {0};
+ DWORD DirectoryCount = 0;
+ DWORD EntryCount = 0;
+ DWORD DeclaredDataEntryCount = 0;
+ DWORD MappedDataEntryCount = 0;
+ DWORD InvalidEntryCount = 0;
+ DWORD NamedRootTypeCount = 0;
+ ULONGLONG DeclaredDataBytes = 0;
+ ULONGLONG MappedDataBytes = 0;
+ BOOLEAN NodeCapReached = FALSE;
+ BOOLEAN EntryCapReached = FALSE;
+
+ ShowMessages("\n\nResources\n---------");
+
+ if (ResourceDirectory->VirtualAddress == 0 || ResourceDirectory->Size == 0)
+ {
+ ShowMessages("\n%-36s%s", "Resource directory :", "empty");
+ return;
+ }
+
+ if (ResourceDirectory->Size < 16)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "resource directory is smaller than one header");
+ return;
+ }
+
+ Stack = new (std::nothrow) RESOURCE_NODE[MaxNodes];
+ Visited = new (std::nothrow) DWORD[MaxVisitedOffsets];
+
+ if (Stack == NULL || Visited == NULL)
+ {
+ ShowMessages("\n%-36s%s", "Resource directory :", "memory allocation failed");
+ delete[] Stack;
+ delete[] Visited;
+ return;
+ }
+
+ ZeroMemory(Stack, sizeof(RESOURCE_NODE) * MaxNodes);
+ ZeroMemory(Visited, sizeof(DWORD) * MaxVisitedOffsets);
+
+ Stack[StackCount].Offset = 0;
+ Stack[StackCount].Depth = 0;
+ Stack[StackCount].TypeId = 0;
+ StackCount++;
+
+ while (StackCount != 0)
+ {
+ RESOURCE_NODE Node = Stack[--StackCount];
+
+ if (DirectoryCount >= MaxNodes)
+ {
+ NodeCapReached = TRUE;
+ break;
+ }
+
+ if (Node.Depth > MaxDepth)
+ {
+ InvalidEntryCount++;
+ continue;
+ }
+
+ BOOLEAN Seen = FALSE;
+ for (DWORD Index = 0; Index < VisitedCount; Index++)
+ {
+ if (Visited[Index] == Node.Offset)
+ {
+ Seen = TRUE;
+ break;
+ }
+ }
+
+ if (Seen)
+ {
+ InvalidEntryCount++;
+ continue;
+ }
+
+ if (VisitedCount < MaxVisitedOffsets)
+ {
+ Visited[VisitedCount++] = Node.Offset;
+ }
+ else
+ {
+ NodeCapReached = TRUE;
+ break;
+ }
+
+ DWORD DirectoryRva = 0;
+ if (!PeAddDword(ResourceDirectory->VirtualAddress, Node.Offset, &DirectoryRva) ||
+ Node.Offset > ResourceDirectory->Size || ResourceDirectory->Size - Node.Offset < 16)
+ {
+ InvalidEntryCount++;
+ continue;
+ }
+
+ const BYTE * Directory = NULL;
+ if (!PeGetPointerAtRva(Reader, DirectoryRva, 16, &Directory))
+ {
+ InvalidEntryCount++;
+ continue;
+ }
+
+ WORD NamedEntries = PeReadWordFromBuffer(Directory, 12);
+ WORD IdEntries = PeReadWordFromBuffer(Directory, 14);
+ DWORD EntryTotal = (DWORD)NamedEntries + (DWORD)IdEntries;
+ DWORD EntryBytes = 0;
+
+ if (EntryTotal > (MAXDWORD - 16) / 8 || !PeAddDword(16, EntryTotal * 8, &EntryBytes) ||
+ EntryBytes > ResourceDirectory->Size - Node.Offset)
+ {
+ InvalidEntryCount++;
+ continue;
+ }
+
+ DirectoryCount++;
+
+ const BYTE * Entries = NULL;
+ if (EntryTotal != 0 && !PeGetPointerAtRva(Reader, DirectoryRva, EntryBytes, &Entries))
+ {
+ InvalidEntryCount++;
+ continue;
+ }
+
+ for (DWORD EntryIndex = 0; EntryIndex < EntryTotal; EntryIndex++)
+ {
+ if (EntryCount >= MaxEntries)
+ {
+ EntryCapReached = TRUE;
+ break;
+ }
+
+ const BYTE * Entry = Entries + 16 + (EntryIndex * 8);
+ DWORD NameOrId = PeReadDwordFromBuffer(Entry, 0);
+ DWORD OffsetToData = PeReadDwordFromBuffer(Entry, 4);
+ DWORD ChildOffset = OffsetToData & 0x7fffffff;
+ DWORD TypeId = Node.TypeId;
+
+ EntryCount++;
+
+ if ((NameOrId & 0x80000000) != 0)
+ {
+ DWORD StringOffset = NameOrId & 0x7fffffff;
+ DWORD StringRva = 0;
+
+ if (StringOffset > ResourceDirectory->Size || ResourceDirectory->Size - StringOffset < sizeof(WORD) ||
+ !PeAddDword(ResourceDirectory->VirtualAddress, StringOffset, &StringRva))
+ {
+ InvalidEntryCount++;
+ }
+ else
+ {
+ const BYTE * String = NULL;
+ if (!PeGetPointerAtRva(Reader, StringRva, sizeof(WORD), &String))
+ {
+ InvalidEntryCount++;
+ }
+ else
+ {
+ WORD StringLength = PeReadWordFromBuffer(String, 0);
+ DWORD StringBytes = (DWORD)sizeof(WORD) + ((DWORD)StringLength * sizeof(WCHAR));
+
+ if (StringBytes > ResourceDirectory->Size - StringOffset || !PeGetPointerAtRva(Reader, StringRva, StringBytes, &String))
+ {
+ InvalidEntryCount++;
+ }
+ }
+ }
+ if (Node.Depth == 0)
+ {
+ NamedRootTypeCount++;
+ }
+ }
+ else if (Node.Depth == 0)
+ {
+ TypeId = NameOrId & 0xffff;
+ if (TypeId < RTL_NUMBER_OF(TypeCounts))
+ {
+ TypeCounts[TypeId]++;
+ }
+ }
+
+ if ((OffsetToData & 0x80000000) != 0)
+ {
+ if (ChildOffset > ResourceDirectory->Size || ResourceDirectory->Size - ChildOffset < 16 || Node.Depth + 1 > MaxDepth)
+ {
+ InvalidEntryCount++;
+ continue;
+ }
+
+ if (StackCount >= MaxNodes)
+ {
+ NodeCapReached = TRUE;
+ continue;
+ }
+
+ Stack[StackCount].Offset = ChildOffset;
+ Stack[StackCount].Depth = Node.Depth + 1;
+ Stack[StackCount].TypeId = TypeId;
+ StackCount++;
+ }
+ else
+ {
+ DWORD DataEntryRva = 0;
+ if (ChildOffset > ResourceDirectory->Size || ResourceDirectory->Size - ChildOffset < 16 ||
+ !PeAddDword(ResourceDirectory->VirtualAddress, ChildOffset, &DataEntryRva))
+ {
+ InvalidEntryCount++;
+ continue;
+ }
+
+ const BYTE * DataEntry = NULL;
+ if (!PeGetPointerAtRva(Reader, DataEntryRva, 16, &DataEntry))
+ {
+ InvalidEntryCount++;
+ continue;
+ }
+
+ DWORD DataRva = PeReadDwordFromBuffer(DataEntry, 0);
+ DWORD DataSize = PeReadDwordFromBuffer(DataEntry, 4);
+
+ BOOLEAN PayloadMapped = TRUE;
+ if (DataSize != 0)
+ {
+ const BYTE * Payload = NULL;
+ if (!PeGetPointerAtRva(Reader, DataRva, DataSize, &Payload))
+ {
+ InvalidEntryCount++;
+ PayloadMapped = FALSE;
+ }
+ }
+
+ DeclaredDataBytes += DataSize;
+ DeclaredDataEntryCount++;
+ if (PayloadMapped)
+ {
+ MappedDataBytes += DataSize;
+ MappedDataEntryCount++;
+ }
+ }
+ }
+
+ if (EntryCapReached)
+ {
+ break;
+ }
+ }
+
+ ShowMessages("\n%-36s%u", "Resource directory count :", DirectoryCount);
+ ShowMessages("\n%-36s%u", "Resource entry count :", EntryCount);
+ ShowMessages("\n%-36s%u", "Resource declared data entries :", DeclaredDataEntryCount);
+ ShowMessages("\n%-36s%u", "Resource mapped data entries :", MappedDataEntryCount);
+ ShowMessages("\n%-36s%u", "Resource invalid entry count :", InvalidEntryCount);
+ ShowMessages("\n%-36s%u", "Resource named root types :", NamedRootTypeCount);
+ ShowMessages("\n%-36s%#llx", "Resource declared data bytes :", DeclaredDataBytes);
+ ShowMessages("\n%-36s%#llx", "Resource mapped data bytes :", MappedDataBytes);
+
+ for (DWORD TypeId = 0; TypeId < RTL_NUMBER_OF(TypeCounts); TypeId++)
+ {
+ if (TypeCounts[TypeId] != 0)
+ {
+ PeShowResourceTypeCount(TypeId, TypeCounts[TypeId]);
+ }
+ }
+
+ if (NodeCapReached)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, resource node cap reached :", MaxNodes);
+ }
+ if (EntryCapReached)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, resource entry cap reached :", MaxEntries);
+ }
+
+ delete[] Stack;
+ delete[] Visited;
+}
+
+/**
+ * @brief Prints RUNTIME_FUNCTION entries from the x64 exception directory
+ *
+ * Decodes IMAGE_RUNTIME_FUNCTION_ENTRY records for AMD64 images, printing
+ * the begin address, end address, unwind RVA, and key unwind info fields
+ * for the first 0x20 entries. For non-AMD64 machines the directory size
+ * is reported without per-entry decoding. Processing is capped at 0x100000
+ * entries.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param ExceptionDirectory Pointer to the IMAGE_DIRECTORY_ENTRY_EXCEPTION data directory entry
+ * @param Machine Machine type from the PE file header (IMAGE_FILE_MACHINE_*)
+ * @param Is32Bit TRUE if the PE image is 32-bit
+ */
+static VOID
+PeShowExceptions(PPE_IMAGE_READER Reader, const IMAGE_DATA_DIRECTORY * ExceptionDirectory, WORD Machine, BOOLEAN Is32Bit)
+{
+ const DWORD RuntimeFunctionSize = 12;
+ const DWORD MaxEntries = 0x100000;
+ const DWORD MaxPrintedEntries = 0x20;
+ const DWORD MaxWarnings = 8;
+
+ ShowMessages("\n\nExceptions\n----------");
+
+ if (ExceptionDirectory->VirtualAddress == 0 || ExceptionDirectory->Size == 0)
+ {
+ ShowMessages("\n%-36s%s", "Exception directory :", "empty");
+ return;
+ }
+
+ if (Machine != IMAGE_FILE_MACHINE_AMD64 || Is32Bit)
+ {
+ ShowMessages("\n%-36s%s", "Exception directory :", "present, x64 runtime-function decoding skipped for this machine");
+ ShowMessages("\n%-36s%#x", "Raw exception directory size :", ExceptionDirectory->Size);
+ return;
+ }
+
+ if (ExceptionDirectory->Size < RuntimeFunctionSize)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "exception directory is smaller than one runtime function entry");
+ return;
+ }
+
+ if ((ExceptionDirectory->Size % RuntimeFunctionSize) != 0)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, malformed exception size :", ExceptionDirectory->Size);
+ }
+
+ DWORD EntryCount = ExceptionDirectory->Size / RuntimeFunctionSize;
+ BOOLEAN EntryCapped = FALSE;
+ DWORD RangeWarnings = 0;
+ DWORD UnwindWarnings = 0;
+ DWORD SkippedNullEntries = 0;
+ DWORD PrintedEntries = 0;
+ if (EntryCount > MaxEntries)
+ {
+ EntryCount = MaxEntries;
+ EntryCapped = TRUE;
+ }
+
+ ShowMessages("\n%-36s%u", "Runtime function count :", EntryCount);
+
+ for (DWORD EntryIndex = 0; EntryIndex < EntryCount; EntryIndex++)
+ {
+ DWORD EntryRva = 0;
+ if (!PeAddDword(ExceptionDirectory->VirtualAddress, EntryIndex * RuntimeFunctionSize, &EntryRva))
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "runtime function entry RVA overflow");
+ break;
+ }
+
+ const BYTE * Entry = NULL;
+ if (!PeGetPointerAtRva(Reader, EntryRva, RuntimeFunctionSize, &Entry))
+ {
+ ShowMessages("\n%-36s%#x", "Warning, invalid runtime entry RVA :", EntryRva);
+ break;
+ }
+
+ DWORD BeginAddress = PeReadDwordFromBuffer(Entry, 0);
+ DWORD EndAddress = PeReadDwordFromBuffer(Entry, 4);
+ DWORD UnwindRva = PeReadDwordFromBuffer(Entry, 8);
+
+ if (BeginAddress == 0 && EndAddress == 0 && UnwindRva == 0)
+ {
+ SkippedNullEntries++;
+ continue;
+ }
+
+ if (BeginAddress >= EndAddress)
+ {
+ if (RangeWarnings < MaxWarnings && PrintedEntries < MaxPrintedEntries)
+ {
+ ShowMessages("\n%-36s%u", "Warning, invalid runtime range index :", EntryIndex);
+ }
+ RangeWarnings++;
+ }
+
+ const BYTE * Unwind = NULL;
+ BOOLEAN UnwindMapped = UnwindRva != 0 && PeGetPointerAtRva(Reader, UnwindRva, 4, &Unwind);
+ if (!UnwindMapped)
+ {
+ if (UnwindWarnings < MaxWarnings && PrintedEntries < MaxPrintedEntries)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, invalid unwind RVA :", UnwindRva);
+ }
+ UnwindWarnings++;
+ }
+
+ if (PrintedEntries < MaxPrintedEntries)
+ {
+ if (UnwindMapped)
+ {
+ BYTE VersionAndFlags = PeReadByteFromBuffer(Unwind, 0);
+ BYTE Frame = PeReadByteFromBuffer(Unwind, 3);
+
+ ShowMessages("\n[%u] begin %#x end %#x unwind %#x version %u flags %#x prolog %#x codes %u frame reg %u frame off %u",
+ EntryIndex,
+ BeginAddress,
+ EndAddress,
+ UnwindRva,
+ VersionAndFlags & 0x7,
+ VersionAndFlags >> 3,
+ PeReadByteFromBuffer(Unwind, 1),
+ PeReadByteFromBuffer(Unwind, 2),
+ Frame & 0xf,
+ Frame >> 4);
+ }
+ else
+ {
+ ShowMessages("\n[%u] begin %#x end %#x unwind %#x", EntryIndex, BeginAddress, EndAddress, UnwindRva);
+ }
+ PrintedEntries++;
+ }
+ }
+
+ if (EntryCapped)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, exception entry cap reached :", MaxEntries);
+ }
+ if (EntryCount > MaxPrintedEntries)
+ {
+ ShowMessages("\n%-36s%u", "Info, printed exception entries :", PrintedEntries);
+ }
+ if (SkippedNullEntries != 0)
+ {
+ ShowMessages("\n%-36s%u", "Info, skipped null runtime entries :", SkippedNullEntries);
+ }
+ if (RangeWarnings > MaxWarnings)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, invalid range warnings shown :", MaxWarnings);
+ }
+ if (UnwindWarnings > MaxWarnings)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, invalid unwind warnings shown :", MaxWarnings);
+ }
+}
+
+/**
+ * @brief Resolves a delay-import address field to a relative virtual address
+ *
+ * Handles both the legacy VA-based format (UsesRva == FALSE) and the newer
+ * RVA-based format (UsesRva == TRUE). For VA-based descriptors the address is
+ * converted via PeVaToRva using the supplied image base.
+ *
+ * @param Address Raw address value read from the delay-import descriptor
+ * @param UsesRva TRUE if the descriptor uses RVAs, FALSE if it uses VAs
+ * @param ImageBase Image base used for VA-to-RVA conversion when UsesRva is FALSE
+ * @param Rva Output pointer that receives the resolved RVA on success; must not be NULL
+ *
+ * @return BOOLEAN TRUE on success, FALSE when the address cannot be converted to an RVA
+ */
+static BOOLEAN
+PeResolveDelayImportAddress(ULONGLONG Address, BOOLEAN UsesRva, ULONGLONG ImageBase, DWORD * Rva)
+{
+ if (Rva == NULL)
+ {
+ return FALSE;
+ }
+
+ if (UsesRva)
+ {
+ if (Address > MAXDWORD)
+ {
+ return FALSE;
+ }
+
+ *Rva = (DWORD)Address;
+ return TRUE;
+ }
+
+ return PeVaToRva(Address, ImageBase, Rva);
+}
+
+/**
+ * @brief Prints delay-import descriptors and their imported function names or ordinals
+ *
+ * Iterates ImgDelayDescr records, resolving DLL names and import thunk arrays.
+ * Supports both legacy VA-based and RVA-based descriptor formats. Processing
+ * is capped at 0x1000 descriptors and 0x2000 total imported symbols.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param DelayImportDirectory Pointer to the IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT data directory entry
+ * @param Is32Bit TRUE if the PE image is 32-bit
+ * @param ImageBase Preferred image base used for VA-to-RVA conversion
+ */
+static VOID
+PeShowDelayImports(PPE_IMAGE_READER Reader, const IMAGE_DATA_DIRECTORY * DelayImportDirectory, BOOLEAN Is32Bit, ULONGLONG ImageBase)
+{
+ const DWORD MaxDescriptors = 0x1000;
+ const DWORD MaxTotalImports = 0x2000;
+ const DWORD MaxDllNameLength = 0x200;
+ const DWORD MaxImportNameLength = 0x200;
+ const DWORD DescriptorSize = 32;
+
+ ShowMessages("\n\nDelay imports\n-------------");
+
+ if (DelayImportDirectory->VirtualAddress == 0 || DelayImportDirectory->Size == 0)
+ {
+ ShowMessages("\n%-36s%s", "Delay import directory :", "empty");
+ return;
+ }
+
+ if (DelayImportDirectory->Size < DescriptorSize)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "delay import directory is smaller than one descriptor");
+ return;
+ }
+
+ DWORD DescriptorCount = DelayImportDirectory->Size / DescriptorSize;
+ if ((DelayImportDirectory->Size % DescriptorSize) != 0)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, malformed delay import size :", DelayImportDirectory->Size);
+ }
+
+ BOOLEAN DescriptorCapped = FALSE;
+ if (DescriptorCount > MaxDescriptors)
+ {
+ DescriptorCount = MaxDescriptors;
+ DescriptorCapped = TRUE;
+ }
+
+ DWORD TotalImports = 0;
+ BOOLEAN FoundTerminator = FALSE;
+ BOOLEAN TotalImportsCapped = FALSE;
+
+ for (DWORD DescriptorIndex = 0; DescriptorIndex < DescriptorCount; DescriptorIndex++)
+ {
+ DWORD DescriptorRva = 0;
+ if (!PeAddDword(DelayImportDirectory->VirtualAddress, DescriptorIndex * DescriptorSize, &DescriptorRva))
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "delay import descriptor RVA overflow");
+ break;
+ }
+
+ const BYTE * Descriptor = NULL;
+ if (!PeGetPointerAtRva(Reader, DescriptorRva, DescriptorSize, &Descriptor))
+ {
+ ShowMessages("\n%-36s%#x", "Warning, invalid delay descriptor RVA :", DescriptorRva);
+ break;
+ }
+
+ DWORD Attributes = PeReadDwordFromBuffer(Descriptor, 0);
+ DWORD NameValue = PeReadDwordFromBuffer(Descriptor, 4);
+ DWORD IatValue = PeReadDwordFromBuffer(Descriptor, 12);
+ DWORD IntValue = PeReadDwordFromBuffer(Descriptor, 16);
+ DWORD BoundIatValue = PeReadDwordFromBuffer(Descriptor, 20);
+ DWORD UnloadIatValue = PeReadDwordFromBuffer(Descriptor, 24);
+ DWORD TimeDateStamp = PeReadDwordFromBuffer(Descriptor, 28);
+
+ if (Attributes == 0 && NameValue == 0 && PeReadDwordFromBuffer(Descriptor, 8) == 0 && IatValue == 0 && IntValue == 0 &&
+ BoundIatValue == 0 && UnloadIatValue == 0 && TimeDateStamp == 0)
+ {
+ FoundTerminator = TRUE;
+ break;
+ }
+
+ BOOLEAN UsesRva = (Attributes & 1) != 0;
+ DWORD NameRva = 0;
+ DWORD LookupThunkRva = 0;
+ DWORD IatThunkRva = 0;
+
+ if (!UsesRva)
+ {
+ ShowMessages("\n%-36s%s", "Info :", "delay import descriptor uses VA fields");
+ }
+
+ if (!PeResolveDelayImportAddress(NameValue, UsesRva, ImageBase, &NameRva))
+ {
+ ShowMessages("\n[%u] DLL name %s", DescriptorIndex, "invalid VA/RVA");
+ ShowMessages("\n%-36s%s", "Warning :", "skipping delay imports for descriptor with unreadable DLL name");
+ continue;
+ }
+
+ CHAR DllName[MaxDllNameLength + 1] = {0};
+ PE_ASCII_STRING_STATUS DllNameStatus = PeReadAsciiStringAtRva(Reader,
+ NameRva,
+ MaxDllNameLength,
+ DllName,
+ sizeof(DllName));
+ if (DllNameStatus != PeAsciiStringOk)
+ {
+ ShowMessages("\n[%u] DLL name %s", DescriptorIndex, PeAsciiStatusName(DllNameStatus));
+ ShowMessages("\n%-36s%s", "Warning :", "skipping delay imports for descriptor with unreadable DLL name");
+ continue;
+ }
+
+ ShowMessages("\n[%u] DLL name %s attributes %#x timestamp %#x", DescriptorIndex, DllName, Attributes, TimeDateStamp);
+
+ if (!PeResolveDelayImportAddress(IntValue != 0 ? IntValue : IatValue, UsesRva, ImageBase, &LookupThunkRva) ||
+ !PeResolveDelayImportAddress(IatValue, UsesRva, ImageBase, &IatThunkRva))
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "delay import thunk VA/RVA is invalid");
+ continue;
+ }
+
+ DWORD ThunkSize = Is32Bit ? sizeof(DWORD) : sizeof(ULONGLONG);
+ for (DWORD ThunkIndex = 0; TotalImports < MaxTotalImports; ThunkIndex++)
+ {
+ DWORD LookupEntryRva = 0;
+ DWORD IatEntryRva = 0;
+ if (!PeAddDword(LookupThunkRva, ThunkIndex * ThunkSize, &LookupEntryRva) ||
+ !PeAddDword(IatThunkRva, ThunkIndex * ThunkSize, &IatEntryRva))
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "delay import thunk RVA overflow");
+ break;
+ }
+
+ ULONGLONG ThunkValue = 0;
+ if (!PeReadThunkAtRva(Reader, LookupEntryRva, Is32Bit, &ThunkValue))
+ {
+ ShowMessages("\n%-36s%#x", "Warning, invalid delay thunk RVA :", LookupEntryRva);
+ break;
+ }
+
+ if (ThunkValue == 0)
+ {
+ break;
+ }
+
+ ULONGLONG OrdinalFlag = Is32Bit ? IMAGE_ORDINAL_FLAG32 : IMAGE_ORDINAL_FLAG64;
+ if ((ThunkValue & OrdinalFlag) != 0)
+ {
+ ShowMessages("\n [%u] ordinal %u thunk RVA %#x", ThunkIndex, (UINT32)(ThunkValue & 0xffff), IatEntryRva);
+ TotalImports++;
+ continue;
+ }
+
+ DWORD NameRvaFromThunk = 0;
+ if (!PeResolveDelayImportAddress(ThunkValue, UsesRva, ImageBase, &NameRvaFromThunk))
+ {
+ ShowMessages("\n%-36s%#llx", "Warning, invalid delay import name VA/RVA :", (UINT64)ThunkValue);
+ TotalImports++;
+ continue;
+ }
+
+ WORD Hint = 0;
+ if (!PeReadWordAtRva(Reader, NameRvaFromThunk, &Hint))
+ {
+ ShowMessages("\n%-36s%#x", "Warning, invalid delay import hint RVA :", NameRvaFromThunk);
+ TotalImports++;
+ continue;
+ }
+
+ DWORD ImportNameRva = 0;
+ if (!PeAddDword(NameRvaFromThunk, sizeof(WORD), &ImportNameRva))
+ {
+ ShowMessages("\n%-36s%#x", "Warning, invalid delay import name RVA :", NameRvaFromThunk);
+ TotalImports++;
+ continue;
+ }
+
+ CHAR ImportName[MaxImportNameLength + 1] = {0};
+ PE_ASCII_STRING_STATUS ImportNameStatus = PeReadAsciiStringAtRva(Reader,
+ ImportNameRva,
+ MaxImportNameLength,
+ ImportName,
+ sizeof(ImportName));
+ if (ImportNameStatus != PeAsciiStringOk)
+ {
+ ShowMessages("\n%-36s%#x, %s", "Warning, invalid delay import name RVA :", ImportNameRva, PeAsciiStatusName(ImportNameStatus));
+ TotalImports++;
+ continue;
+ }
+
+ ShowMessages("\n [%u] hint %#x name %s thunk RVA %#x", ThunkIndex, Hint, ImportName, IatEntryRva);
+ TotalImports++;
+ }
+
+ if (TotalImports >= MaxTotalImports)
+ {
+ TotalImportsCapped = TRUE;
+ break;
+ }
+ }
+
+ if (!FoundTerminator)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "delay import descriptor terminator not found before bounds or cap");
+ }
+ if (DescriptorCapped)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, delay descriptor cap reached :", MaxDescriptors);
+ }
+ if (TotalImportsCapped)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, delay import cap reached :", MaxTotalImports);
+ }
+}
+
+/**
+ * @brief Prints the RVA and size of an IMAGE_DATA_DIRECTORY embedded within the CLR runtime header
+ *
+ * Reads two consecutive DWORDs from the CLR header buffer at Offset to obtain
+ * a sub-directory RVA and size. Also reports whether the range is mapped
+ * within the image.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param Header Pointer to the CLR runtime header byte buffer
+ * @param AvailableSize Number of validated bytes available in Header
+ * @param Offset Byte offset within Header of the IMAGE_DATA_DIRECTORY to read
+ * @param Label Column label to print before the values
+ */
+static VOID
+PeShowClrDirectoryBounds(PPE_IMAGE_READER Reader, const BYTE * Header, DWORD AvailableSize, SIZE_T Offset, const CHAR * Label)
+{
+ if (Offset > AvailableSize || sizeof(IMAGE_DATA_DIRECTORY) > AvailableSize - Offset)
+ {
+ return;
+ }
+
+ DWORD Rva = PeReadDwordFromBuffer(Header, Offset);
+ DWORD Size = PeReadDwordFromBuffer(Header, Offset + sizeof(DWORD));
+
+ ShowMessages("\n%-36sRVA %#x size %#x", Label, Rva, Size);
+ if (Rva != 0 && Size != 0)
+ {
+ const BYTE * Pointer = NULL;
+ ShowMessages(", %s", PeGetPointerAtRva(Reader, Rva, Size, &Pointer) ? "mapped" : "not mapped");
+ }
+}
+
+/**
+ * @brief Prints CLR (.NET) runtime header information
+ *
+ * Reads the IMAGE_COR20_HEADER from the CLR data directory, printing the
+ * runtime version, flags, entry point token or RVA, and the bounds of each
+ * embedded sub-directory (metadata, resources, strong name, etc.).
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param ClrDirectory Pointer to the IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR data directory entry
+ */
+static VOID
+PeShowClrRuntime(PPE_IMAGE_READER Reader, const IMAGE_DATA_DIRECTORY * ClrDirectory)
+{
+ ShowMessages("\n\nCLR runtime\n-----------");
+
+ if (ClrDirectory->VirtualAddress == 0 || ClrDirectory->Size == 0)
+ {
+ ShowMessages("\n%-36s%s", "CLR runtime header :", "empty");
+ return;
+ }
+
+ if (ClrDirectory->Size < 0x48)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "CLR runtime header is smaller than required fields");
+ return;
+ }
+
+ const BYTE * Header = NULL;
+ if (!PeGetPointerAtRva(Reader, ClrDirectory->VirtualAddress, 0x48, &Header))
+ {
+ ShowMessages("\n%-36s%s", "CLR runtime header :", "not mapped");
+ return;
+ }
+
+ DWORD HeaderSize = PeReadDwordFromBuffer(Header, 0);
+ DWORD AvailableSize = ClrDirectory->Size < HeaderSize ? ClrDirectory->Size : HeaderSize;
+
+ ShowMessages("\n%-36s%#x", "Header size :", HeaderSize);
+ if (HeaderSize < 0x48 || AvailableSize < 0x48)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "CLR runtime header is truncated");
+ return;
+ }
+
+ if (!PeGetPointerAtRva(Reader, ClrDirectory->VirtualAddress, AvailableSize, &Header))
+ {
+ ShowMessages("\n%-36s%s", "CLR runtime header :", "invalid bounds");
+ return;
+ }
+
+ WORD MajorRuntimeVersion = PeReadWordFromBuffer(Header, 4);
+ WORD MinorRuntimeVersion = PeReadWordFromBuffer(Header, 6);
+ DWORD Flags = PeReadDwordFromBuffer(Header, 16);
+ DWORD EntryPoint = PeReadDwordFromBuffer(Header, 20);
+
+ ShowMessages("\n%-36s%u.%u", "Runtime version :", MajorRuntimeVersion, MinorRuntimeVersion);
+ PeShowClrDirectoryBounds(Reader, Header, AvailableSize, 8, "Metadata directory :");
+ ShowMessages("\n%-36s%#x", "Flags :", Flags);
+ ShowMessages("\n%-36s%#x (%s)", "Entry point token/RVA :", EntryPoint, (Flags & 0x10) != 0 ? "native RVA" : "managed token");
+ PeShowClrDirectoryBounds(Reader, Header, AvailableSize, 24, "Resources directory :");
+ PeShowClrDirectoryBounds(Reader, Header, AvailableSize, 32, "Strong name directory :");
+ PeShowClrDirectoryBounds(Reader, Header, AvailableSize, 40, "Code manager table :");
+ PeShowClrDirectoryBounds(Reader, Header, AvailableSize, 48, "VTable fixups :");
+ PeShowClrDirectoryBounds(Reader, Header, AvailableSize, 56, "Export address table jumps :");
+ PeShowClrDirectoryBounds(Reader, Header, AvailableSize, 64, "Managed native header :");
+}
+
+/**
+ * @brief Prints Thread Local Storage (TLS) directory fields and TLS callback addresses
+ *
+ * Reads IMAGE_TLS_DIRECTORY32 or IMAGE_TLS_DIRECTORY64 depending on Is32Bit and
+ * prints all fields. Then walks the null-terminated callback VA array, converting
+ * each entry to an RVA and file offset. Processing stops at 0x200 callbacks.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param TlsDirectory Pointer to the IMAGE_DIRECTORY_ENTRY_TLS data directory entry
+ * @param Is32Bit TRUE if the PE image is 32-bit
+ * @param ImageBase Preferred image base used for VA-to-RVA conversion
+ */
+static VOID
+PeShowTls(PPE_IMAGE_READER Reader, const IMAGE_DATA_DIRECTORY * TlsDirectory, BOOLEAN Is32Bit, ULONGLONG ImageBase)
+{
+ const DWORD MaxCallbacks = 0x200;
+ DWORD TlsSize = Is32Bit ? sizeof(IMAGE_TLS_DIRECTORY32) : sizeof(IMAGE_TLS_DIRECTORY64);
+
+ ShowMessages("\n\nTLS\n---");
+
+ if (TlsDirectory->VirtualAddress == 0 || TlsDirectory->Size == 0)
+ {
+ ShowMessages("\n%-36s%s", "TLS directory :", "empty");
+ return;
+ }
+
+ if (!PeRvaContainsRange(TlsDirectory->VirtualAddress, TlsDirectory->Size, TlsDirectory->VirtualAddress, TlsSize))
+ {
+ ShowMessages("\n%-36s%s", "TLS directory :", "invalid bounds");
+ return;
+ }
+
+ const BYTE * TlsPointer = NULL;
+ if (!PeGetPointerAtRva(Reader, TlsDirectory->VirtualAddress, TlsSize, &TlsPointer))
+ {
+ ShowMessages("\n%-36s%s", "TLS directory :", "not mapped");
+ return;
+ }
+
+ ULONGLONG StartRawDataVa = Is32Bit ? PeReadDwordFromBuffer(TlsPointer, 0) : PeReadQwordFromBuffer(TlsPointer, 0);
+ ULONGLONG EndRawDataVa = Is32Bit ? PeReadDwordFromBuffer(TlsPointer, 4) : PeReadQwordFromBuffer(TlsPointer, 8);
+ ULONGLONG AddressOfIndexVa = Is32Bit ? PeReadDwordFromBuffer(TlsPointer, 8) : PeReadQwordFromBuffer(TlsPointer, 16);
+ ULONGLONG AddressCallbacksVa = Is32Bit ? PeReadDwordFromBuffer(TlsPointer, 12) : PeReadQwordFromBuffer(TlsPointer, 24);
+ DWORD SizeOfZeroFill = Is32Bit ? PeReadDwordFromBuffer(TlsPointer, 16) : PeReadDwordFromBuffer(TlsPointer, 32);
+ DWORD Characteristics = Is32Bit ? PeReadDwordFromBuffer(TlsPointer, 20) : PeReadDwordFromBuffer(TlsPointer, 36);
+
+ ShowMessages("\n%-36s%#llx", "Start address of raw data VA :", StartRawDataVa);
+ ShowMessages("\n%-36s%#llx", "End address of raw data VA :", EndRawDataVa);
+ ShowMessages("\n%-36s%#llx", "Address of index VA :", AddressOfIndexVa);
+ ShowMessages("\n%-36s%#llx", "Address of callbacks VA :", AddressCallbacksVa);
+ ShowMessages("\n%-36s%#x", "Size of zero fill :", SizeOfZeroFill);
+ ShowMessages("\n%-36s%#x", "Characteristics :", Characteristics);
+
+ DWORD CallbacksRva = 0;
+ if (AddressCallbacksVa == 0)
+ {
+ ShowMessages("\n%-36s%s", "TLS callbacks :", "empty");
+ return;
+ }
+
+ if (!PeVaToRva(AddressCallbacksVa, ImageBase, &CallbacksRva))
+ {
+ ShowMessages("\n%-36s%#llx", "Warning, invalid callbacks VA :", AddressCallbacksVa);
+ return;
+ }
+
+ DWORD EntrySize = Is32Bit ? sizeof(DWORD) : sizeof(ULONGLONG);
+ for (DWORD CallbackIndex = 0; CallbackIndex < MaxCallbacks; CallbackIndex++)
+ {
+ DWORD EntryRva = 0;
+ if (!PeAddDword(CallbacksRva, CallbackIndex * EntrySize, &EntryRva))
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "TLS callback RVA overflow");
+ return;
+ }
+
+ ULONGLONG CallbackVa = 0;
+ if (!PeReadThunkAtRva(Reader, EntryRva, Is32Bit, &CallbackVa))
+ {
+ ShowMessages("\n%-36s%#x", "Warning, invalid callback entry RVA :", EntryRva);
+ return;
+ }
+
+ if (CallbackVa == 0)
+ {
+ return;
+ }
+
+ DWORD CallbackRva = 0;
+ SIZE_T FileOffset = 0;
+ if (PeVaToRva(CallbackVa, ImageBase, &CallbackRva))
+ {
+ if (PeImageReaderRvaToFileOffset(Reader, CallbackRva, 1, &FileOffset))
+ {
+ ShowMessages("\n [%u] VA %#llx RVA %#x file offset %#llx", CallbackIndex, CallbackVa, CallbackRva, (UINT64)FileOffset);
+ }
+ else
+ {
+ ShowMessages("\n [%u] VA %#llx RVA %#x file offset %s", CallbackIndex, CallbackVa, CallbackRva, "not mapped");
+ }
+ }
+ else
+ {
+ ShowMessages("\n [%u] VA %#llx RVA %s", CallbackIndex, CallbackVa, "invalid");
+ }
+ }
+
+ ShowMessages("\n%-36s%#x", "Warning, TLS callback cap reached :", MaxCallbacks);
+}
+
+/**
+ * @brief Prints CodeView debug information embedded in a debug directory entry
+ *
+ * Handles both the RSDS (PDB 7.0) and NB10 (PDB 2.0) CodeView formats.
+ * For RSDS entries, prints the GUID, age, and PDB path. For NB10 entries,
+ * prints the offset, signature, age, and PDB path. Silently returns for
+ * non-CodeView entries or entries with insufficient data.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param Entry Pointer to the IMAGE_DEBUG_DIRECTORY entry to decode
+ */
+static VOID
+PeShowDebugCodeView(PPE_IMAGE_READER Reader, const IMAGE_DEBUG_DIRECTORY * Entry)
+{
+ const DWORD MaxPdbPathLength = 0x400;
+
+ if (Entry->Type != IMAGE_DEBUG_TYPE_CODEVIEW || Entry->SizeOfData < sizeof(DWORD))
+ {
+ return;
+ }
+
+ const BYTE * Payload = NULL;
+ if ((Entry->PointerToRawData == 0 || !PeImageReaderGetPointerAtOffset(Reader, Entry->PointerToRawData, Entry->SizeOfData, &Payload)) &&
+ (Entry->AddressOfRawData == 0 || !PeGetPointerAtRva(Reader, Entry->AddressOfRawData, Entry->SizeOfData, &Payload)))
+ {
+ ShowMessages("\n%-36s%s", " CodeView payload :", "invalid bounds");
+ return;
+ }
+
+ if (memcmp(Payload, "RSDS", sizeof(DWORD)) == 0)
+ {
+ if (Entry->SizeOfData < 24)
+ {
+ ShowMessages("\n%-36s%s", " CodeView RSDS :", "truncated");
+ return;
+ }
+
+ DWORD Age = PeReadDwordFromBuffer(Payload, 20);
+ DWORD PathOffset = 24;
+ DWORD PathSize = Entry->SizeOfData - 24;
+ DWORD PathLimit = PathSize < MaxPdbPathLength ? PathSize : MaxPdbPathLength;
+ CHAR PdbPath[MaxPdbPathLength + 1] = {0};
+ const BYTE * Guid = Payload + 4;
+
+ PE_ASCII_STRING_STATUS PathStatus = PeReadAsciiStringFromBuffer(Payload + PathOffset, PathLimit, PdbPath, sizeof(PdbPath));
+ ShowMessages("\n%-36s%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ " CodeView RSDS GUID :",
+ Guid[3],
+ Guid[2],
+ Guid[1],
+ Guid[0],
+ Guid[5],
+ Guid[4],
+ Guid[7],
+ Guid[6],
+ Guid[8],
+ Guid[9],
+ Guid[10],
+ Guid[11],
+ Guid[12],
+ Guid[13],
+ Guid[14],
+ Guid[15]);
+ ShowMessages("\n%-36s%u", " CodeView age :", Age);
+ ShowMessages("\n%-36s%s", " CodeView PDB path :", PathStatus == PeAsciiStringOk ? PdbPath : PeAsciiStatusName(PathStatus));
+ }
+ else if (memcmp(Payload, "NB10", sizeof(DWORD)) == 0)
+ {
+ if (Entry->SizeOfData < 16)
+ {
+ ShowMessages("\n%-36s%s", " CodeView NB10 :", "truncated");
+ return;
+ }
+
+ DWORD Offset = PeReadDwordFromBuffer(Payload, 4);
+ DWORD Timestamp = PeReadDwordFromBuffer(Payload, 8);
+ DWORD Age = PeReadDwordFromBuffer(Payload, 12);
+ DWORD PathOffset = 16;
+ DWORD PathSize = Entry->SizeOfData - 16;
+ DWORD PathLimit = PathSize < MaxPdbPathLength ? PathSize : MaxPdbPathLength;
+ CHAR PdbPath[MaxPdbPathLength + 1] = {0};
+
+ PE_ASCII_STRING_STATUS PathStatus = PeReadAsciiStringFromBuffer(Payload + PathOffset, PathLimit, PdbPath, sizeof(PdbPath));
+ ShowMessages("\n%-36s%#x", " CodeView NB10 offset :", Offset);
+ ShowMessages("\n%-36s%#x", " CodeView NB10 signature :", Timestamp);
+ ShowMessages("\n%-36s%u", " CodeView age :", Age);
+ ShowMessages("\n%-36s%s", " CodeView PDB path :", PathStatus == PeAsciiStringOk ? PdbPath : PeAsciiStatusName(PathStatus));
+ }
+}
+
+/**
+ * @brief Prints all IMAGE_DEBUG_DIRECTORY entries in the debug data directory
+ *
+ * Iterates the debug directory, printing characteristics, timestamp, version,
+ * type, size, and address fields for each entry. Also validates the raw data
+ * bounds and delegates to PeShowDebugCodeView for CodeView entries.
+ * Processing is capped at 0x1000 entries.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param DebugDirectory Pointer to the IMAGE_DIRECTORY_ENTRY_DEBUG data directory entry
+ */
+static VOID
+PeShowDebug(PPE_IMAGE_READER Reader, const IMAGE_DATA_DIRECTORY * DebugDirectory)
+{
+ const DWORD MaxDebugEntries = 0x1000;
+
+ ShowMessages("\n\nDebug\n-----");
+
+ if (DebugDirectory->VirtualAddress == 0 || DebugDirectory->Size == 0)
+ {
+ ShowMessages("\n%-36s%s", "Debug directory :", "empty");
+ return;
+ }
+
+ DWORD EntryCount = DebugDirectory->Size / sizeof(IMAGE_DEBUG_DIRECTORY);
+ if (EntryCount == 0)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "debug directory is smaller than one descriptor");
+ return;
+ }
+
+ if ((DebugDirectory->Size % sizeof(IMAGE_DEBUG_DIRECTORY)) != 0)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, malformed debug size :", DebugDirectory->Size);
+ }
+
+ BOOLEAN EntryCapped = FALSE;
+ if (EntryCount > MaxDebugEntries)
+ {
+ EntryCount = MaxDebugEntries;
+ EntryCapped = TRUE;
+ }
+
+ for (DWORD EntryIndex = 0; EntryIndex < EntryCount; EntryIndex++)
+ {
+ DWORD EntryRva = 0;
+ if (!PeAddDword(DebugDirectory->VirtualAddress, EntryIndex * (DWORD)sizeof(IMAGE_DEBUG_DIRECTORY), &EntryRva))
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "debug directory RVA overflow");
+ break;
+ }
+
+ const IMAGE_DEBUG_DIRECTORY * Entry = NULL;
+ if (!PeGetPointerAtRva(Reader, EntryRva, sizeof(IMAGE_DEBUG_DIRECTORY), (const BYTE **)&Entry))
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "debug directory entry is not mapped");
+ break;
+ }
+
+ ShowMessages("\n[%u] characteristics %#x time date stamp %#x major %u minor %u type %u size %#x address %#x raw %#x",
+ EntryIndex,
+ Entry->Characteristics,
+ Entry->TimeDateStamp,
+ Entry->MajorVersion,
+ Entry->MinorVersion,
+ Entry->Type,
+ Entry->SizeOfData,
+ Entry->AddressOfRawData,
+ Entry->PointerToRawData);
+
+ if (Entry->SizeOfData != 0 && Entry->PointerToRawData != 0)
+ {
+ const BYTE * Payload = NULL;
+ ShowMessages("\n%-36s%s", " Payload bounds :", PeImageReaderGetPointerAtOffset(Reader, Entry->PointerToRawData, Entry->SizeOfData, &Payload) ? "valid" : "invalid");
+ }
+
+ PeShowDebugCodeView(Reader, Entry);
+ }
+
+ if (EntryCapped)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, debug entry cap reached :", MaxDebugEntries);
+ }
+}
+
+/**
+ * @brief Checks whether a load configuration structure contains a specific field
+ *
+ * Returns TRUE when the range [Offset, Offset + FieldSize) lies entirely within
+ * the first AvailableSize bytes of the load config buffer.
+ *
+ * @param AvailableSize Number of bytes available in the load config buffer
+ * @param Offset Byte offset of the field within the load config structure
+ * @param FieldSize Size of the field in bytes
+ *
+ * @return BOOLEAN TRUE if the field is present, FALSE if it is beyond AvailableSize
+ */
+static BOOLEAN
+PeLoadConfigHasField(DWORD AvailableSize, SIZE_T Offset, SIZE_T FieldSize)
+{
+ return Offset <= AvailableSize && FieldSize <= AvailableSize - Offset;
+}
+
+/**
+ * @brief Prints a DWORD field from the load config structure if it is present
+ *
+ * Uses PeLoadConfigHasField to verify the field is within AvailableSize before
+ * reading and printing the value with the supplied label.
+ *
+ * @param Config Pointer to the load configuration byte buffer
+ * @param AvailableSize Number of validated bytes in Config
+ * @param Offset Byte offset of the DWORD field within Config
+ * @param Label Column label to print before the value
+ */
+static VOID
+PeShowLoadConfigDword(const BYTE * Config, DWORD AvailableSize, SIZE_T Offset, const CHAR * Label)
+{
+ if (PeLoadConfigHasField(AvailableSize, Offset, sizeof(DWORD)))
+ {
+ ShowMessages("\n%-36s%#x", Label, PeReadDwordFromBuffer(Config, Offset));
+ }
+}
+
+/**
+ * @brief Prints a pointer-sized field from the load config structure if it is present
+ *
+ * Reads sizeof(DWORD) or sizeof(ULONGLONG) depending on Is32Bit, verifies
+ * presence with PeLoadConfigHasField, and prints the value as a hex address.
+ *
+ * @param Config Pointer to the load configuration byte buffer
+ * @param AvailableSize Number of validated bytes in Config
+ * @param Offset Byte offset of the pointer field within Config
+ * @param Label Column label to print before the value
+ * @param Is32Bit TRUE to read a 32-bit pointer, FALSE for a 64-bit pointer
+ */
+static VOID
+PeShowLoadConfigPointer(const BYTE * Config, DWORD AvailableSize, SIZE_T Offset, const CHAR * Label, BOOLEAN Is32Bit)
+{
+ SIZE_T FieldSize = Is32Bit ? sizeof(DWORD) : sizeof(ULONGLONG);
+
+ if (PeLoadConfigHasField(AvailableSize, Offset, FieldSize))
+ {
+ ShowMessages("\n%-36s%#llx", Label, PeReadLoadConfigPointer(Config, Offset, Is32Bit));
+ }
+}
+
+/**
+ * @brief Prints a count field (pointer-sized) from the load config structure if present
+ *
+ * Behaves identically to PeShowLoadConfigPointer but formats the value as a
+ * decimal count rather than a hex address.
+ *
+ * @param Config Pointer to the load configuration byte buffer
+ * @param AvailableSize Number of validated bytes in Config
+ * @param Offset Byte offset of the count field within Config
+ * @param Label Column label to print before the value
+ * @param Is32Bit TRUE to read a 32-bit count, FALSE for a 64-bit count
+ */
+static VOID
+PeShowLoadConfigCount(const BYTE * Config, DWORD AvailableSize, SIZE_T Offset, const CHAR * Label, BOOLEAN Is32Bit)
+{
+ SIZE_T FieldSize = Is32Bit ? sizeof(DWORD) : sizeof(ULONGLONG);
+
+ if (PeLoadConfigHasField(AvailableSize, Offset, FieldSize))
+ {
+ ShowMessages("\n%-36s%llu", Label, PeReadLoadConfigPointer(Config, Offset, Is32Bit));
+ }
+}
+
+/**
+ * @brief Prints the names of set guard control-flow flags from a load config guard flags field
+ *
+ * Iterates a table of known guard flag bitmasks and prints the name of each
+ * set bit. Reports "None" when no known flags are set, and appends the
+ * unknown bitmask when unrecognised bits are present.
+ *
+ * @param GuardFlags The GuardFlags field value from the load configuration structure
+ */
+static VOID
+PeShowLoadConfigGuardFlags(DWORD GuardFlags)
+{
+ BOOLEAN AnyFlag = FALSE;
+ DWORD KnownMask = 0;
+
+ struct GUARD_FLAG_NAME
+ {
+ DWORD Flag;
+ const CHAR * Name;
+ };
+
+ static const GUARD_FLAG_NAME GuardFlagNames[] = {
+ {0x00000100, "CF instrumented"},
+ {0x00000200, "CFW instrumented"},
+ {0x00000400, "CF function table present"},
+ {0x00000800, "Security cookie unused"},
+ {0x00001000, "Protect delayed load IAT"},
+ {0x00002000, "Delayed load IAT in its own section"},
+ {0x00004000, "Export suppression info present"},
+ {0x00008000, "Enable export suppression"},
+ {0x00010000, "Long jump table present"},
+ {0x00020000, "RF instrumented"},
+ {0x00040000, "RF enable"},
+ {0x00080000, "RF strict"},
+ {0x00100000, "Retpoline present"},
+ {0x00200000, "EH continuation table present"},
+ {0x00400000, "XFG enabled"},
+ {0x00800000, "CastGuard present"},
+ {0x01000000, "Memcpy function present"},
+ };
+
+ for (UINT32 Index = 0; Index < RTL_NUMBER_OF(GuardFlagNames); Index++)
+ {
+ KnownMask |= GuardFlagNames[Index].Flag;
+ if ((GuardFlags & GuardFlagNames[Index].Flag) == GuardFlagNames[Index].Flag)
+ {
+ ShowMessages("%s%s", AnyFlag ? ", " : "", GuardFlagNames[Index].Name);
+ AnyFlag = TRUE;
+ }
+ }
+
+ if (!AnyFlag)
+ {
+ ShowMessages(GuardFlags == 0 ? "None" : "No known guard flags");
+ }
+
+ DWORD UnknownMask = GuardFlags & ~KnownMask;
+ if (UnknownMask != 0)
+ {
+ ShowMessages(", unknown mask %#x", UnknownMask);
+ }
+}
+
+/**
+ * @brief Prints extended load config fields introduced in Windows 8.1 and later
+ *
+ * Handles guard address-taken IAT, guard long-jump tables, dynamic value
+ * relocation, CHPE metadata, RF (return-flow) guards, EH continuation tables,
+ * XFG, CastGuard, and memcpy pointer fields. Each field is printed only when
+ * AvailableSize covers its offset.
+ *
+ * @param Config Pointer to the load configuration byte buffer
+ * @param AvailableSize Number of validated bytes in Config
+ * @param Is32Bit TRUE for PE32 field offsets, FALSE for PE32+ field offsets
+ */
+static VOID
+PeShowLoadConfigModernFields(const BYTE * Config, DWORD AvailableSize, BOOLEAN Is32Bit)
+{
+ PeShowLoadConfigPointer(Config, AvailableSize, Is32Bit ? 104 : 160, "Guard address-taken IAT table :", Is32Bit);
+ PeShowLoadConfigCount(Config, AvailableSize, Is32Bit ? 108 : 168, "Guard address-taken IAT count :", Is32Bit);
+ PeShowLoadConfigPointer(Config, AvailableSize, Is32Bit ? 112 : 176, "Guard long jump target table :", Is32Bit);
+ PeShowLoadConfigCount(Config, AvailableSize, Is32Bit ? 116 : 184, "Guard long jump target count :", Is32Bit);
+ PeShowLoadConfigPointer(Config, AvailableSize, Is32Bit ? 120 : 192, "Dynamic value reloc table :", Is32Bit);
+ PeShowLoadConfigPointer(Config, AvailableSize, Is32Bit ? 124 : 200, "CHPE metadata pointer :", Is32Bit);
+ PeShowLoadConfigPointer(Config, AvailableSize, Is32Bit ? 128 : 208, "Guard RF failure routine :", Is32Bit);
+ PeShowLoadConfigPointer(Config, AvailableSize, Is32Bit ? 132 : 216, "Guard RF failure routine ptr :", Is32Bit);
+ PeShowLoadConfigDword(Config, AvailableSize, Is32Bit ? 136 : 224, "Dynamic value reloc offset :");
+ if (PeLoadConfigHasField(AvailableSize, Is32Bit ? 140 : 228, sizeof(WORD)))
+ {
+ ShowMessages("\n%-36s%#x", "Dynamic value reloc section :", PeReadWordFromBuffer(Config, Is32Bit ? 140 : 228));
+ }
+ PeShowLoadConfigPointer(Config, AvailableSize, Is32Bit ? 144 : 232, "Guard RF verify stack ptr :", Is32Bit);
+ PeShowLoadConfigDword(Config, AvailableSize, Is32Bit ? 148 : 240, "Hot patch table offset :");
+ PeShowLoadConfigPointer(Config, AvailableSize, Is32Bit ? 156 : 248, "Enclave config pointer :", Is32Bit);
+ PeShowLoadConfigPointer(Config, AvailableSize, Is32Bit ? 160 : 256, "Volatile metadata pointer :", Is32Bit);
+ PeShowLoadConfigPointer(Config, AvailableSize, Is32Bit ? 164 : 264, "Guard EH continuation table :", Is32Bit);
+ PeShowLoadConfigCount(Config, AvailableSize, Is32Bit ? 168 : 272, "Guard EH continuation count :", Is32Bit);
+ PeShowLoadConfigPointer(Config, AvailableSize, Is32Bit ? 172 : 280, "Guard XFG check pointer :", Is32Bit);
+ PeShowLoadConfigPointer(Config, AvailableSize, Is32Bit ? 176 : 288, "Guard XFG dispatch pointer :", Is32Bit);
+ PeShowLoadConfigPointer(Config, AvailableSize, Is32Bit ? 180 : 296, "Guard XFG table dispatch ptr :", Is32Bit);
+ PeShowLoadConfigPointer(Config, AvailableSize, Is32Bit ? 184 : 304, "CastGuard failure mode :", Is32Bit);
+ PeShowLoadConfigPointer(Config, AvailableSize, Is32Bit ? 188 : 312, "Guard memcpy pointer :", Is32Bit);
+}
+
+/**
+ * @brief Prints the load configuration directory
+ *
+ * Reads the self-describing size field at the start of the load config
+ * structure, clamps to the directory bounds, and prints security cookie,
+ * SEH handler table, guard CF fields, guard flags, and extended modern
+ * fields via helper functions.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param LoadConfigDirectory Pointer to the IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG data directory entry
+ * @param Is32Bit TRUE if the PE image is 32-bit
+ */
+static VOID
+PeShowLoadConfig(PPE_IMAGE_READER Reader, const IMAGE_DATA_DIRECTORY * LoadConfigDirectory, BOOLEAN Is32Bit)
+{
+ ShowMessages("\n\nLoad config\n-----------");
+
+ if (LoadConfigDirectory->VirtualAddress == 0 || LoadConfigDirectory->Size == 0)
+ {
+ ShowMessages("\n%-36s%s", "Load config directory :", "empty");
+ return;
+ }
+
+ if (LoadConfigDirectory->Size < sizeof(DWORD))
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "load config size is too small");
+ return;
+ }
+
+ const BYTE * Config = NULL;
+ if (!PeGetPointerAtRva(Reader, LoadConfigDirectory->VirtualAddress, sizeof(DWORD), &Config))
+ {
+ ShowMessages("\n%-36s%s", "Load config directory :", "not mapped");
+ return;
+ }
+
+ DWORD ConfigSize = PeReadDwordFromBuffer(Config, 0);
+ DWORD AvailableSize = LoadConfigDirectory->Size < ConfigSize ? LoadConfigDirectory->Size : ConfigSize;
+
+ ShowMessages("\n%-36s%#x", "Size :", ConfigSize);
+ if (AvailableSize < sizeof(DWORD))
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "load config size is too small");
+ return;
+ }
+
+ if (!PeGetPointerAtRva(Reader, LoadConfigDirectory->VirtualAddress, AvailableSize, &Config))
+ {
+ ShowMessages("\n%-36s%s", "Load config directory :", "invalid bounds");
+ return;
+ }
+
+ PeShowLoadConfigDword(Config, AvailableSize, 4, "Time date stamp :");
+ if (PeLoadConfigHasField(AvailableSize, 8, sizeof(WORD)))
+ {
+ WORD MajorVersion = 0;
+ CopyMemory(&MajorVersion, Config + 8, sizeof(MajorVersion));
+ ShowMessages("\n%-36s%u", "Major version :", MajorVersion);
+ }
+ if (PeLoadConfigHasField(AvailableSize, 10, sizeof(WORD)))
+ {
+ WORD MinorVersion = 0;
+ CopyMemory(&MinorVersion, Config + 10, sizeof(MinorVersion));
+ ShowMessages("\n%-36s%u", "Minor version :", MinorVersion);
+ }
+ PeShowLoadConfigDword(Config, AvailableSize, 12, "Global flags clear :");
+ PeShowLoadConfigDword(Config, AvailableSize, 16, "Global flags set :");
+ PeShowLoadConfigDword(Config, AvailableSize, 20, "Critical section timeout :");
+ PeShowLoadConfigDword(Config, AvailableSize, Is32Bit ? 44 : 72, "Process heap flags :");
+ PeShowLoadConfigPointer(Config, AvailableSize, Is32Bit ? 60 : 88, "Security cookie :", Is32Bit);
+ PeShowLoadConfigPointer(Config, AvailableSize, Is32Bit ? 64 : 96, "SE handler table :", Is32Bit);
+ PeShowLoadConfigCount(Config, AvailableSize, Is32Bit ? 68 : 104, "SE handler count :", Is32Bit);
+ PeShowLoadConfigPointer(Config, AvailableSize, Is32Bit ? 72 : 112, "Guard CF check pointer :", Is32Bit);
+ PeShowLoadConfigPointer(Config, AvailableSize, Is32Bit ? 76 : 120, "Guard CF dispatch pointer :", Is32Bit);
+ PeShowLoadConfigPointer(Config, AvailableSize, Is32Bit ? 80 : 128, "Guard CF function table :", Is32Bit);
+ PeShowLoadConfigCount(Config, AvailableSize, Is32Bit ? 84 : 136, "Guard CF function count :", Is32Bit);
+ PeShowLoadConfigDword(Config, AvailableSize, Is32Bit ? 88 : 144, "Guard flags :");
+ if (PeLoadConfigHasField(AvailableSize, Is32Bit ? 88 : 144, sizeof(DWORD)))
+ {
+ DWORD GuardFlags = PeReadDwordFromBuffer(Config, Is32Bit ? 88 : 144);
+ ShowMessages("\n%-36s", "Guard flag names :");
+ PeShowLoadConfigGuardFlags(GuardFlags);
+ }
+ PeShowLoadConfigModernFields(Config, AvailableSize, Is32Bit);
+}
+
+/**
+ * @brief Prints a summary of all PE data directory entries
+ *
+ * Iterates IMAGE_NUMBEROF_DIRECTORY_ENTRIES slots, printing the name, RVA
+ * (or file offset for the certificate entry), size, and mapping status of
+ * each. Entries beyond NumberOfRvaAndSizes are marked as "not declared".
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param Directories Pointer to the data directory array from the optional header
+ * @param NumberOfRvaAndSizes Value of NumberOfRvaAndSizes from the optional header
+ */
+static VOID
+PeShowDataDirectories(PPE_IMAGE_READER Reader,
+ const IMAGE_DATA_DIRECTORY * Directories,
+ DWORD NumberOfRvaAndSizes)
+{
+ ShowMessages("\n\nData directories\n----------------");
+ ShowMessages("\n%-36s%u", "Number of RVA and sizes :", NumberOfRvaAndSizes);
+ if (NumberOfRvaAndSizes > IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "number of RVA and sizes exceeds PE directory table");
+ }
+
+ for (UINT32 Index = 0; Index < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; Index++)
+ {
+ const CHAR * Name = PeGetDataDirectoryName(Index);
+ const CHAR * AddressLabel = Index == IMAGE_DIRECTORY_ENTRY_SECURITY ? "file offset" : "RVA";
+
+ if (Index >= NumberOfRvaAndSizes)
+ {
+ ShowMessages("\n[%2u] %-27s %s", Index, Name, "not declared");
+ continue;
+ }
+
+ const IMAGE_DATA_DIRECTORY * Directory = &Directories[Index];
+ if (Directory->VirtualAddress == 0 || Directory->Size == 0)
+ {
+ ShowMessages("\n[%2u] %-27s %s %#x, size %#x, %s",
+ Index,
+ Name,
+ AddressLabel,
+ Directory->VirtualAddress,
+ Directory->Size,
+ "empty");
+ continue;
+ }
+
+ const BYTE * Pointer = NULL;
+ SIZE_T FileOffset = 0;
+
+ if (Index == IMAGE_DIRECTORY_ENTRY_SECURITY)
+ {
+ BOOLEAN HasBounds = PeImageReaderGetPointerAtOffset(Reader,
+ Directory->VirtualAddress,
+ Directory->Size,
+ &Pointer);
+
+ ShowMessages("\n[%2u] %-27s file offset %#x, size %#x, %s",
+ Index,
+ Name,
+ Directory->VirtualAddress,
+ Directory->Size,
+ HasBounds ? "valid bounds" : "invalid bounds");
+ if (HasBounds)
+ {
+ ShowMessages(", mapped file offset %#llx", (UINT64)Directory->VirtualAddress);
+ }
+
+ continue;
+ }
+
+ if (PeImageReaderRvaToFileOffset(Reader, Directory->VirtualAddress, Directory->Size, &FileOffset))
+ {
+ ShowMessages("\n[%2u] %-27s RVA %#x, size %#x, mapped file offset %#llx",
+ Index,
+ Name,
+ Directory->VirtualAddress,
+ Directory->Size,
+ (UINT64)FileOffset);
+ }
+ else
+ {
+ ShowMessages("\n[%2u] %-27s RVA %#x, size %#x, %s",
+ Index,
+ Name,
+ Directory->VirtualAddress,
+ Directory->Size,
+ "not mapped");
+ }
+ }
+}
+
+/**
+ * @brief Prints overlay data information and PE layout warnings
+ *
+ * Identifies data appended after all mapped sections (overlay), checks for
+ * section overlaps and gaps, validates SizeOfImage, and emits warnings for
+ * mismatched optional header magic/machine combinations, sections that extend
+ * beyond SizeOfImage, and inconsistent section raw data boundaries.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param Machine Machine type from the PE file header
+ * @param OptionalHeaderMagic Magic value from the PE optional header
+ * @param AddressOfEntryPoint AddressOfEntryPoint from the PE optional header
+ * @param SizeOfImage SizeOfImage from the PE optional header
+ * @param SizeOfHeaders SizeOfHeaders from the PE optional header
+ * @param Directories Pointer to the data directory array
+ * @param NumberOfRvaAndSizes Value of NumberOfRvaAndSizes from the optional header
+ */
+static VOID
+PeShowOverlayAndWarnings(PPE_IMAGE_READER Reader,
+ WORD Machine,
+ WORD OptionalHeaderMagic,
+ DWORD AddressOfEntryPoint,
+ DWORD SizeOfImage,
+ DWORD SizeOfHeaders,
+ const IMAGE_DATA_DIRECTORY * Directories,
+ DWORD NumberOfRvaAndSizes)
+{
+ ULONGLONG OverlayOffset = SizeOfHeaders < Reader->ImageSize ? SizeOfHeaders : Reader->ImageSize;
+ BOOLEAN OverlayUnreliable = FALSE;
+
+ ShowMessages("\n\nOverlay and warnings\n--------------------");
+
+ if ((ULONGLONG)SizeOfHeaders > (ULONGLONG)Reader->ImageSize)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "size of headers is larger than file size");
+ }
+
+ if (OptionalHeaderMagic == IMAGE_NT_OPTIONAL_HDR64_MAGIC && Machine == IMAGE_FILE_MACHINE_I386)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "PE32+ optional header with i386 machine type");
+ }
+ else if (OptionalHeaderMagic == IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
+ (Machine == IMAGE_FILE_MACHINE_AMD64 || Machine == IMAGE_FILE_MACHINE_IA64))
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "PE32 optional header with 64-bit machine type");
+ }
+
+ for (UINT32 SectionIndex = 0; SectionIndex < Reader->FileHeader->NumberOfSections; SectionIndex++)
+ {
+ CHAR SectionName[IMAGE_SIZEOF_SHORT_NAME + 1];
+ const IMAGE_SECTION_HEADER * Section = &Reader->SectionHeaders[SectionIndex];
+ DWORD VirtualSpan = Section->Misc.VirtualSize > Section->SizeOfRawData ? Section->Misc.VirtualSize : Section->SizeOfRawData;
+ DWORD VirtualEnd = 0;
+
+ PeImageReaderGetSectionName(Section, SectionName, sizeof(SectionName));
+
+ if (VirtualSpan != 0)
+ {
+ if (!PeAddDword(Section->VirtualAddress, VirtualSpan, &VirtualEnd))
+ {
+ ShowMessages("\n%-36ssection '%s' RVA range overflows", "Warning :", SectionName);
+ }
+ else if (SizeOfImage != 0 && VirtualEnd > SizeOfImage)
+ {
+ ShowMessages("\n%-36ssection '%s' RVA range exceeds SizeOfImage", "Warning :", SectionName);
+ }
+ }
+
+ if (Section->SizeOfRawData != 0)
+ {
+ ULONGLONG RawStart = Section->PointerToRawData;
+ ULONGLONG RawEnd = 0;
+
+ if (!PeAddUlonglong(RawStart, Section->SizeOfRawData, &RawEnd))
+ {
+ ShowMessages("\n%-36ssection '%s' raw data range overflows", "Warning :", SectionName);
+ OverlayUnreliable = TRUE;
+ }
+ else if (RawStart > (ULONGLONG)Reader->ImageSize || RawEnd > (ULONGLONG)Reader->ImageSize)
+ {
+ ShowMessages("\n%-36ssection '%s' raw data is outside file", "Warning :", SectionName);
+ OverlayUnreliable = TRUE;
+ }
+ else if (RawEnd > OverlayOffset)
+ {
+ OverlayOffset = RawEnd;
+ }
+ }
+ }
+
+ if (Reader->FileHeader->NumberOfSections > 1)
+ {
+ PE_RAW_SECTION_RANGE * Ranges = (PE_RAW_SECTION_RANGE *)malloc(sizeof(PE_RAW_SECTION_RANGE) * Reader->FileHeader->NumberOfSections);
+ UINT32 Count = 0;
+
+ if (Ranges == NULL)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "raw section overlap check skipped, allocation failed");
+ }
+ else
+ {
+ for (UINT32 SectionIndex = 0; SectionIndex < Reader->FileHeader->NumberOfSections; SectionIndex++)
+ {
+ const IMAGE_SECTION_HEADER * Section = &Reader->SectionHeaders[SectionIndex];
+ ULONGLONG End;
+
+ if (Section->SizeOfRawData == 0 ||
+ !PeAddUlonglong(Section->PointerToRawData, Section->SizeOfRawData, &End) ||
+ Section->PointerToRawData > Reader->ImageSize || End > Reader->ImageSize)
+ {
+ continue;
+ }
+
+ Ranges[Count].Start = Section->PointerToRawData;
+ Ranges[Count].End = End;
+ Ranges[Count].Section = Section;
+ Count++;
+ }
+
+ if (Count > 1)
+ {
+ UINT32 MaxEndIndex = 0;
+
+ qsort(Ranges, Count, sizeof(Ranges[0]), PeCompareRawSectionRange);
+
+ for (UINT32 RangeIndex = 1; RangeIndex < Count; RangeIndex++)
+ {
+ if (Ranges[RangeIndex].Start < Ranges[MaxEndIndex].End)
+ {
+ CHAR LeftName[IMAGE_SIZEOF_SHORT_NAME + 1];
+ CHAR RightName[IMAGE_SIZEOF_SHORT_NAME + 1];
+
+ PeImageReaderGetSectionName(Ranges[MaxEndIndex].Section, LeftName, sizeof(LeftName));
+ PeImageReaderGetSectionName(Ranges[RangeIndex].Section, RightName, sizeof(RightName));
+ ShowMessages("\n%-36sraw data overlap detected between '%s' and '%s'; additional overlaps may be omitted",
+ "Warning :",
+ LeftName,
+ RightName);
+ }
+
+ if (Ranges[RangeIndex].End > Ranges[MaxEndIndex].End)
+ {
+ MaxEndIndex = RangeIndex;
+ }
+ }
+ }
+
+ free(Ranges);
+ }
+ }
+
+ if (AddressOfEntryPoint != 0)
+ {
+ BOOLEAN EntrypointFound = FALSE;
+ const IMAGE_SECTION_HEADER * EntrypointSection = NULL;
+
+ for (UINT32 SectionIndex = 0; SectionIndex < Reader->FileHeader->NumberOfSections; SectionIndex++)
+ {
+ const IMAGE_SECTION_HEADER * Section = &Reader->SectionHeaders[SectionIndex];
+ DWORD VirtualSpan = Section->Misc.VirtualSize > Section->SizeOfRawData ? Section->Misc.VirtualSize : Section->SizeOfRawData;
+ DWORD VirtualEnd = 0;
+
+ if (VirtualSpan == 0 || !PeAddDword(Section->VirtualAddress, VirtualSpan, &VirtualEnd))
+ {
+ continue;
+ }
+
+ if (AddressOfEntryPoint >= Section->VirtualAddress && AddressOfEntryPoint < VirtualEnd)
+ {
+ EntrypointFound = TRUE;
+ EntrypointSection = Section;
+ break;
+ }
+ }
+
+ if (!EntrypointFound)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "entrypoint is outside all sections");
+ }
+ else if ((EntrypointSection->Characteristics & IMAGE_SCN_MEM_EXECUTE) == 0)
+ {
+ CHAR SectionName[IMAGE_SIZEOF_SHORT_NAME + 1];
+
+ PeImageReaderGetSectionName(EntrypointSection, SectionName, sizeof(SectionName));
+ ShowMessages("\n%-36sentrypoint section '%s' is not executable", "Warning :", SectionName);
+ }
+ }
+
+ if (OverlayUnreliable)
+ {
+ ShowMessages("\n%-36s%s", "Overlay :", "not computed because section raw data is invalid");
+ }
+ else if ((ULONGLONG)Reader->ImageSize > OverlayOffset)
+ {
+ ULONGLONG OverlaySize = (ULONGLONG)Reader->ImageSize - OverlayOffset;
+
+ ShowMessages("\n%-36s%#llx", "Overlay offset :", OverlayOffset);
+ ShowMessages("\n%-36s%#llx", "Overlay size :", OverlaySize);
+
+ if (Directories != NULL && NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_SECURITY)
+ {
+ const IMAGE_DATA_DIRECTORY * SecurityDirectory = &Directories[IMAGE_DIRECTORY_ENTRY_SECURITY];
+
+ if (SecurityDirectory->VirtualAddress != 0 && SecurityDirectory->Size != 0 &&
+ (ULONGLONG)SecurityDirectory->VirtualAddress >= OverlayOffset)
+ {
+ ShowMessages("\n%-36s%s", "Info :", "overlay includes certificate data; not necessarily suspicious");
+ }
+ }
+ }
+ else
+ {
+ ShowMessages("\n%-36s%s", "Overlay :", "none");
+ }
+}
+
+/**
+ * @brief Prints all import descriptors and their imported function names or ordinals
+ *
+ * Iterates IMAGE_IMPORT_DESCRIPTOR records, resolving DLL names and walking
+ * the original-first-thunk (or first-thunk) arrays to print each imported
+ * symbol with its hint and IAT RVA. Warns when the null terminator descriptor
+ * is not found within the declared directory size. Processing is capped at
+ * 0x1000 descriptors and 0x2000 total imports.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param ImportDirectory Pointer to the IMAGE_DIRECTORY_ENTRY_IMPORT data directory entry
+ * @param Is32Bit TRUE if the PE image is 32-bit
+ */
+static VOID
+PeShowImports(PPE_IMAGE_READER Reader, const IMAGE_DATA_DIRECTORY * ImportDirectory, BOOLEAN Is32Bit)
+{
+ const DWORD MaxImportDescriptors = 0x1000;
+ const DWORD MaxTotalImports = 0x2000;
+ const DWORD MaxDllNameLength = 0x200;
+ const DWORD MaxImportNameLength = 0x200;
+
+ ShowMessages("\n\nImports\n-------");
+
+ if (ImportDirectory->VirtualAddress == 0 || ImportDirectory->Size == 0)
+ {
+ ShowMessages("\n%-36s%s", "Import directory :", "empty");
+ return;
+ }
+
+ const BYTE * DirectoryPointer = NULL;
+ if (!PeGetPointerAtRva(Reader, ImportDirectory->VirtualAddress, sizeof(IMAGE_IMPORT_DESCRIPTOR), &DirectoryPointer))
+ {
+ ShowMessages("\n%-36s%s", "Import directory :", "not mapped");
+ return;
+ }
+
+ DWORD DescriptorCount = ImportDirectory->Size / sizeof(IMAGE_IMPORT_DESCRIPTOR);
+ if (DescriptorCount == 0)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "import directory is smaller than one descriptor");
+ return;
+ }
+
+ BOOLEAN DescriptorCapped = FALSE;
+ if (DescriptorCount > MaxImportDescriptors)
+ {
+ DescriptorCount = MaxImportDescriptors;
+ DescriptorCapped = TRUE;
+ }
+
+ DWORD TotalImports = 0;
+ BOOLEAN FoundTerminator = FALSE;
+ BOOLEAN TotalImportsCapped = FALSE;
+
+ for (DWORD DescriptorIndex = 0; DescriptorIndex < DescriptorCount; DescriptorIndex++)
+ {
+ DWORD DescriptorRva = 0;
+
+ if (!PeAddDword(ImportDirectory->VirtualAddress,
+ DescriptorIndex * (DWORD)sizeof(IMAGE_IMPORT_DESCRIPTOR),
+ &DescriptorRva))
+ {
+ break;
+ }
+
+ const IMAGE_IMPORT_DESCRIPTOR * Descriptor = NULL;
+ if (!PeGetPointerAtRva(Reader,
+ DescriptorRva,
+ sizeof(IMAGE_IMPORT_DESCRIPTOR),
+ (const BYTE **)&Descriptor))
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "import descriptor is not mapped");
+ break;
+ }
+
+ if (Descriptor->OriginalFirstThunk == 0 && Descriptor->TimeDateStamp == 0 && Descriptor->ForwarderChain == 0 &&
+ Descriptor->Name == 0 && Descriptor->FirstThunk == 0)
+ {
+ FoundTerminator = TRUE;
+ break;
+ }
+
+ CHAR DllName[MaxDllNameLength + 1] = {0};
+ PE_ASCII_STRING_STATUS DllNameStatus = PeReadAsciiStringAtRva(Reader,
+ Descriptor->Name,
+ MaxDllNameLength,
+ DllName,
+ sizeof(DllName));
+ if (DllNameStatus != PeAsciiStringOk)
+ {
+ ShowMessages("\n[%u] DLL name %s", DescriptorIndex, PeAsciiStatusName(DllNameStatus));
+ ShowMessages("\n%-36s%s", "Warning :", "skipping imports for descriptor with unreadable DLL name");
+ continue;
+ }
+
+ ShowMessages("\n[%u] DLL name %s", DescriptorIndex, DllName);
+
+ DWORD LookupThunkRva = Descriptor->OriginalFirstThunk != 0 ? Descriptor->OriginalFirstThunk : Descriptor->FirstThunk;
+ if (LookupThunkRva == 0 || Descriptor->FirstThunk == 0)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "import thunk array is empty");
+ continue;
+ }
+
+ DWORD ThunkSize = Is32Bit ? sizeof(DWORD) : sizeof(ULONGLONG);
+ for (DWORD ThunkIndex = 0; TotalImports < MaxTotalImports; ThunkIndex++)
+ {
+ DWORD LookupEntryRva = 0;
+ DWORD IatEntryRva = 0;
+ if (!PeAddDword(LookupThunkRva, ThunkIndex * ThunkSize, &LookupEntryRva) ||
+ !PeAddDword(Descriptor->FirstThunk, ThunkIndex * ThunkSize, &IatEntryRva))
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "import thunk RVA overflow");
+ break;
+ }
+
+ ULONGLONG ThunkValue = 0;
+ if (!PeReadThunkAtRva(Reader, LookupEntryRva, Is32Bit, &ThunkValue))
+ {
+ ShowMessages("\n%-36s%#x", "Warning, invalid thunk RVA :", LookupEntryRva);
+ break;
+ }
+
+ if (ThunkValue == 0)
+ {
+ break;
+ }
+
+ ULONGLONG OrdinalFlag = Is32Bit ? IMAGE_ORDINAL_FLAG32 : IMAGE_ORDINAL_FLAG64;
+ if ((ThunkValue & OrdinalFlag) != 0)
+ {
+ ShowMessages("\n [%u] ordinal %u thunk RVA %#x", ThunkIndex, (UINT32)(ThunkValue & 0xffff), IatEntryRva);
+ TotalImports++;
+ continue;
+ }
+
+ if (ThunkValue > MAXDWORD)
+ {
+ ShowMessages("\n%-36s%#llx", "Warning, invalid import name RVA :", (UINT64)ThunkValue);
+ TotalImports++;
+ continue;
+ }
+
+ DWORD NameRva = (DWORD)ThunkValue;
+ WORD Hint = 0;
+ if (!PeReadWordAtRva(Reader, NameRva, &Hint))
+ {
+ ShowMessages("\n%-36s%#x", "Warning, invalid import hint RVA :", NameRva);
+ TotalImports++;
+ continue;
+ }
+
+ DWORD ImportNameRva = 0;
+ if (!PeAddDword(NameRva, sizeof(WORD), &ImportNameRva))
+ {
+ ShowMessages("\n%-36s%#x", "Warning, invalid import name RVA :", NameRva);
+ TotalImports++;
+ continue;
+ }
+
+ CHAR ImportName[MaxImportNameLength + 1] = {0};
+ PE_ASCII_STRING_STATUS ImportNameStatus = PeReadAsciiStringAtRva(Reader,
+ ImportNameRva,
+ MaxImportNameLength,
+ ImportName,
+ sizeof(ImportName));
+ if (ImportNameStatus != PeAsciiStringOk)
+ {
+ ShowMessages("\n%-36s%#x, %s", "Warning, invalid import name RVA :", ImportNameRva, PeAsciiStatusName(ImportNameStatus));
+ TotalImports++;
+ continue;
+ }
+
+ ShowMessages("\n [%u] hint %#x name %s thunk RVA %#x", ThunkIndex, Hint, ImportName, IatEntryRva);
+ TotalImports++;
+ }
+
+ if (TotalImports >= MaxTotalImports)
+ {
+ TotalImportsCapped = TRUE;
+ break;
+ }
+ }
+
+ if (!FoundTerminator)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "import descriptor terminator not found before bounds or cap");
+ }
+
+ if (DescriptorCapped)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, descriptor cap reached :", MaxImportDescriptors);
+ }
+
+ if (TotalImportsCapped)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, import cap reached :", MaxTotalImports);
+ }
+}
+
+/**
+ * @brief Validates and retrieves a pointer to a PE export table array
+ *
+ * Computes the total byte size of the table as Count * EntrySize, verifies
+ * that the multiplication does not overflow, and then resolves the table RVA
+ * via PeGetPointerAtRva. When Count is zero *Pointer is set to NULL and TRUE
+ * is returned without any range check.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param TableRva RVA of the export table array
+ * @param Count Number of entries in the table
+ * @param EntrySize Size of each entry in bytes
+ * @param Pointer Output pointer set to the validated table location on success
+ *
+ * @return BOOLEAN TRUE on success, FALSE on overflow or if the RVA is not mapped
+ */
+static BOOLEAN
+PeValidateExportTable(PPE_IMAGE_READER Reader, DWORD TableRva, DWORD Count, DWORD EntrySize, const BYTE ** Pointer)
+{
+ DWORD TableSize = 0;
+
+ if (Count == 0)
+ {
+ *Pointer = NULL;
+ return TRUE;
+ }
+
+ if (EntrySize != 0 && Count > MAXDWORD / EntrySize)
+ {
+ return FALSE;
+ }
+
+ TableSize = Count * EntrySize;
+ return PeGetPointerAtRva(Reader, TableRva, TableSize, Pointer);
+}
+
+/**
+ * @brief Prints one export entry including its ordinal, name, and function RVA or forwarder
+ *
+ * If FunctionRva falls within the export directory's RVA range the entry is
+ * treated as a forwarder string and that string is read and displayed.
+ * Otherwise the raw function RVA is printed.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param ExportDirectory Pointer to the IMAGE_DIRECTORY_ENTRY_EXPORT data directory entry
+ * @param Index Zero-based display index of this export entry
+ * @param Ordinal Export ordinal (base-adjusted)
+ * @param Name Export name string, or an error description if not available
+ * @param FunctionRva RVA of the exported function or forwarder string
+ */
+static VOID
+PeShowExportEntry(PPE_IMAGE_READER Reader,
+ const IMAGE_DATA_DIRECTORY * ExportDirectory,
+ DWORD Index,
+ DWORD Ordinal,
+ const CHAR * Name,
+ DWORD FunctionRva)
+{
+ const DWORD MaxForwarderLength = 0x1000;
+
+ if (PeRvaContainsRange(ExportDirectory->VirtualAddress, ExportDirectory->Size, FunctionRva, 1))
+ {
+ DWORD ForwarderRemaining = ExportDirectory->Size - (FunctionRva - ExportDirectory->VirtualAddress);
+ DWORD ForwarderMaxLength = ForwarderRemaining < MaxForwarderLength ? ForwarderRemaining : MaxForwarderLength;
+
+ CHAR Forwarder[MaxForwarderLength + 1] = {0};
+ PE_ASCII_STRING_STATUS ForwarderStatus = PeReadAsciiStringAtRva(Reader,
+ FunctionRva,
+ ForwarderMaxLength,
+ Forwarder,
+ sizeof(Forwarder));
+ if (ForwarderStatus == PeAsciiStringOk)
+ {
+ ShowMessages("\n[%u] ordinal %u name %s forwarder %s", Index, Ordinal, Name, Forwarder);
+ }
+ else
+ {
+ ShowMessages("\n[%u] ordinal %u name %s forwarder %s", Index, Ordinal, Name, PeAsciiStatusName(ForwarderStatus));
+ }
+
+ return;
+ }
+
+ ShowMessages("\n[%u] ordinal %u name %s RVA %#x", Index, Ordinal, Name, FunctionRva);
+}
+
+/**
+ * @brief Prints the export directory including the export address, name, and ordinal tables
+ *
+ * Reads the IMAGE_EXPORT_DIRECTORY header, validates the three export tables
+ * (AddressOfFunctions, AddressOfNames, AddressOfNameOrdinals), and iterates
+ * all exported functions. Named exports are matched via the name-ordinal table;
+ * unnamed exports are printed with their ordinal. Forwarder strings are handled
+ * via PeShowExportEntry. Processing is capped at 0x2000 total exports.
+ *
+ * @param Reader Pointer to an initialized PE_IMAGE_READER
+ * @param ExportDirectory Pointer to the IMAGE_DIRECTORY_ENTRY_EXPORT data directory entry
+ */
+static VOID
+PeShowExports(PPE_IMAGE_READER Reader, const IMAGE_DATA_DIRECTORY * ExportDirectory)
+{
+ const DWORD MaxExports = 0x2000;
+ const DWORD MaxDllNameLength = 0x200;
+ const DWORD MaxExportNameLength = 0x200;
+
+ ShowMessages("\n\nExports\n-------");
+
+ if (ExportDirectory->VirtualAddress == 0 || ExportDirectory->Size == 0)
+ {
+ ShowMessages("\n%-36s%s", "Export directory :", "empty");
+ return;
+ }
+
+ if (!PeRvaContainsRange(ExportDirectory->VirtualAddress,
+ ExportDirectory->Size,
+ ExportDirectory->VirtualAddress,
+ sizeof(IMAGE_EXPORT_DIRECTORY)))
+ {
+ ShowMessages("\n%-36s%s", "Export directory :", "invalid bounds");
+ return;
+ }
+
+ const IMAGE_EXPORT_DIRECTORY * Directory = NULL;
+ if (!PeGetPointerAtRva(Reader,
+ ExportDirectory->VirtualAddress,
+ sizeof(IMAGE_EXPORT_DIRECTORY),
+ (const BYTE **)&Directory))
+ {
+ ShowMessages("\n%-36s%s", "Export directory :", "not mapped");
+ return;
+ }
+
+ CHAR DllName[MaxDllNameLength + 1] = {0};
+ PE_ASCII_STRING_STATUS DllNameStatus = PeReadAsciiStringAtRva(Reader,
+ Directory->Name,
+ MaxDllNameLength,
+ DllName,
+ sizeof(DllName));
+ ShowMessages("\n%-36s%s", "DLL name :", DllNameStatus == PeAsciiStringOk ? DllName : PeAsciiStatusName(DllNameStatus));
+ ShowMessages("\n%-36s%u", "Ordinal base :", Directory->Base);
+ ShowMessages("\n%-36s%u", "Address table count :", Directory->NumberOfFunctions);
+ ShowMessages("\n%-36s%u", "Name pointer count :", Directory->NumberOfNames);
+
+ const BYTE * AddressTablePointer = NULL;
+ const BYTE * NamePointerTablePointer = NULL;
+ const BYTE * OrdinalTablePointer = NULL;
+
+ BOOLEAN AddressTableValid = PeValidateExportTable(Reader,
+ Directory->AddressOfFunctions,
+ Directory->NumberOfFunctions,
+ sizeof(DWORD),
+ &AddressTablePointer);
+ BOOLEAN NamePointerTableValid = PeValidateExportTable(Reader,
+ Directory->AddressOfNames,
+ Directory->NumberOfNames,
+ sizeof(DWORD),
+ &NamePointerTablePointer);
+ BOOLEAN OrdinalTableValid = PeValidateExportTable(Reader,
+ Directory->AddressOfNameOrdinals,
+ Directory->NumberOfNames,
+ sizeof(WORD),
+ &OrdinalTablePointer);
+
+ if (!AddressTableValid)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "export address table is not mapped");
+ return;
+ }
+
+ if (!NamePointerTableValid)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "export name pointer table is not mapped");
+ }
+
+ if (!OrdinalTableValid)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "export ordinal table is not mapped");
+ }
+
+ DWORD NamedCount = Directory->NumberOfNames;
+ BOOLEAN NamedCapped = FALSE;
+ if (NamedCount > MaxExports)
+ {
+ NamedCount = MaxExports;
+ NamedCapped = TRUE;
+ }
+
+ DWORD FunctionCount = Directory->NumberOfFunctions;
+ BOOLEAN FunctionCapped = FALSE;
+ if (FunctionCount > MaxExports)
+ {
+ FunctionCount = MaxExports;
+ FunctionCapped = TRUE;
+ }
+
+ BYTE NamedAddressIndexes[MaxExports] = {0};
+
+ if (NamePointerTableValid && OrdinalTableValid)
+ {
+ for (DWORD NameIndex = 0; NameIndex < NamedCount; NameIndex++)
+ {
+ DWORD NameRva = 0;
+ WORD AddressIndex = 0;
+
+ CopyMemory(&NameRva, NamePointerTablePointer + (NameIndex * sizeof(DWORD)), sizeof(NameRva));
+ CopyMemory(&AddressIndex, OrdinalTablePointer + (NameIndex * sizeof(WORD)), sizeof(AddressIndex));
+
+ if (AddressIndex >= Directory->NumberOfFunctions)
+ {
+ ShowMessages("\n%-36s%u", "Warning, invalid export ordinal index :", AddressIndex);
+ continue;
+ }
+
+ DWORD FunctionRva = 0;
+ CopyMemory(&FunctionRva, AddressTablePointer + (AddressIndex * sizeof(DWORD)), sizeof(FunctionRva));
+
+ CHAR ExportName[MaxExportNameLength + 1] = {0};
+ PE_ASCII_STRING_STATUS ExportNameStatus = PeReadAsciiStringAtRva(Reader,
+ NameRva,
+ MaxExportNameLength,
+ ExportName,
+ sizeof(ExportName));
+ if (ExportNameStatus != PeAsciiStringOk)
+ {
+ ShowMessages("\n%-36s%#x, %s", "Warning, invalid export name RVA :", NameRva, PeAsciiStatusName(ExportNameStatus));
+ continue;
+ }
+
+ DWORD DisplayOrdinal = 0;
+ if (!PeAddDword(Directory->Base, AddressIndex, &DisplayOrdinal))
+ {
+ ShowMessages("\n%-36s%u", "Warning, invalid export ordinal index :", AddressIndex);
+ continue;
+ }
+
+ if (AddressIndex < FunctionCount)
+ {
+ NamedAddressIndexes[AddressIndex] = TRUE;
+ }
+
+ PeShowExportEntry(Reader,
+ ExportDirectory,
+ NameIndex,
+ DisplayOrdinal,
+ ExportName,
+ FunctionRva);
+ }
+ }
+
+ for (DWORD AddressIndex = 0; AddressIndex < FunctionCount; AddressIndex++)
+ {
+ if (NamedAddressIndexes[AddressIndex])
+ {
+ continue;
+ }
+
+ DWORD FunctionRva = 0;
+ CopyMemory(&FunctionRva, AddressTablePointer + (AddressIndex * sizeof(DWORD)), sizeof(FunctionRva));
+
+ DWORD DisplayOrdinal = 0;
+ if (!PeAddDword(Directory->Base, AddressIndex, &DisplayOrdinal))
+ {
+ ShowMessages("\n%-36s%u", "Warning, invalid export ordinal index :", AddressIndex);
+ continue;
+ }
+
+ PeShowExportEntry(Reader,
+ ExportDirectory,
+ AddressIndex,
+ DisplayOrdinal,
+ "",
+ FunctionRva);
+ }
+
+ if (NamedCapped)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, named export cap reached :", MaxExports);
+ }
+
+ if (FunctionCapped)
+ {
+ ShowMessages("\n%-36s%#x", "Warning, export cap reached :", MaxExports);
+ }
+}
+
+/**
+ * @brief Locates the Rich header signature in a PE file
+ *
+ * The Rich header is an undocumented Microsoft structure embedded in PE files
+ * that contains information about the tools and compilers used during the build process.
+ * This function searches for the "Rich" signature string within the DOS stub area.
+ *
+ * @param DosHeader Pointer to the DOS header structure of the PE file
+ * @param SearchSize Capped number of bytes to search
+ * @param StartOffset Offset to start searching from
+ * @param Key Output buffer to store the 4-byte XOR key found after "Rich" signature
+ *
+ * @note The Rich header is located between the DOS header and PE header
+ * @note The XOR key is used to decode the actual Rich header entries
+ **/
+static INT
+FindRichHeader(PIMAGE_DOS_HEADER DosHeader, DWORD SearchSize, DWORD StartOffset, CHAR Key[])
+{
+ if (DosHeader == NULL || Key == NULL)
+ {
+ return -1;
+ }
+
+ //
+ // Get PE header offset - this defines our search boundary
+ //
+ LONG Offset = DosHeader->e_lfanew;
+
+ if (SearchSize < sizeof(IMAGE_DOS_HEADER) ||
+ DosHeader->e_magic != IMAGE_DOS_SIGNATURE ||
+ Offset < (LONG)sizeof(IMAGE_DOS_HEADER) ||
+ Offset < 8)
+ {
+ return -1;
+ }
+
+ CHAR * BaseAddr = (CHAR *)DosHeader;
+ DWORD SearchLimit = (DWORD)Offset;
+ if (SearchLimit > SearchSize)
+ {
+ SearchLimit = SearchSize;
+ }
+
+ if (StartOffset + 8 < StartOffset || StartOffset + 8 > SearchLimit)
+ {
+ return -1;
+ }
+
+ //
+ // Search for "Rich" signature
+ // We need 4 bytes for "Rich" and 4 bytes for the key before the PE header.
+ //
+ for (DWORD Offset = StartOffset; Offset + 8 <= SearchLimit; ++Offset)
+ {
+ //
+ // Check for "Rich" signature (4 ASCII bytes)
+ //
+ if (BaseAddr[Offset] == 'R' &&
+ BaseAddr[Offset + 1] == 'i' &&
+ BaseAddr[Offset + 2] == 'c' &&
+ BaseAddr[Offset + 3] == 'h')
+ {
+ //
+ // Extract the 4-byte XOR key that immediately follows "Rich"
+ //
+ memcpy(Key, BaseAddr + Offset + 4, 4);
+
+ //
+ // Return the offset where "Rich" signature was found
+ //
+ return Offset;
+ }
+ }
+
+ //
+ // Rich header signature not found
+ //
+ return -1;
+}
+
+/**
+ * @brief Decrypts Rich header data using XOR decryption and initializes header info
+ *
+ * The Rich header is encrypted using a simple XOR cipher with a 4-byte key.
+ * This function decrypts the entire header in-place and populates the
+ * PEFILE_RICH_HEADER_INFO structure with metadata about the decrypted data.
+ *
+ * @param RichHeaderPtr Pointer to the raw Rich header data to be decrypted
+ * @param RichHeaderSize Size of the Rich header data in bytes
+ * @param Key 4-byte XOR key used for decryption
+ * @param PeFileRichHeaderInfo structure containing Rich header metadata and buffer information
+ *
+ * @note The Rich header uses a repeating 4-byte XOR key for encryption
+ * @note After decryption, the header contains 16 bytes of metadata followed by 8-byte entries
+ * @note Each entry represents one compilation tool (compiler, linker, assembler, etc.)
+ *
+ */
+static BOOLEAN
+FindRichEntries(CHAR * RichHeaderPtr,
+ INT RichHeaderSize,
+ CHAR Key[],
+ PRICH_HEADER_INFO PeFileRichHeaderInfo)
+{
+ if (RichHeaderPtr == NULL || Key == NULL || PeFileRichHeaderInfo == NULL ||
+ RichHeaderSize < 16 || ((RichHeaderSize - 16) % 8) != 0)
+ {
+ return FALSE;
+ }
+
+ INT EntryCount = (RichHeaderSize - 16) / 8;
+
+ if (EntryCount <= 0)
+ {
+ return FALSE;
+ }
+
+ //
+ // Decrypt the entire Rich header using XOR with the 4-byte key
+ //
+ for (int i = 0; i < RichHeaderSize; i += 4)
+ {
+ //
+ // Apply XOR decryption to each 4-byte block
+ //
+ for (int x = 0; x < 4; x++)
+ {
+ RichHeaderPtr[i + x] ^= Key[x];
+ }
+ }
+
+ if (RichHeaderPtr[0] != 'D' || RichHeaderPtr[1] != 'a' ||
+ RichHeaderPtr[2] != 'n' || RichHeaderPtr[3] != 'S')
+ {
+ return FALSE;
+ }
+
+ for (int i = 4; i < 16; i++)
+ {
+ if (RichHeaderPtr[i] != 0)
+ {
+ return FALSE;
+ }
+ }
+
+ //
+ // Initialize the Rich header info structure
+ //
+ PeFileRichHeaderInfo->Size = RichHeaderSize;
+ PeFileRichHeaderInfo->PtrToBuffer = RichHeaderPtr;
+
+ //
+ // Calculate number of entries: subtract 16-byte header, divide by 8 bytes per entry
+ //
+ PeFileRichHeaderInfo->Entries = EntryCount;
+
+ return TRUE;
+}
+
+/**
+ * @brief Parses decrypted Rich header data into structured entries
+ *
+ * After decryption, the Rich header contains a series of 8-byte entries, each describing
+ * a compilation tool used during the build process. This function extracts and converts
+ * the little-endian binary data into structured RICH_ENTRY objects.
+ *
+ * Rich header format after decryption:
+ * - Bytes 0-15: Header metadata (DanS signature + padding)
+ * - Bytes 16+: 8-byte entries (prodID:2, buildID:2, useCount:4)
+ *
+ * @param RichHeaderSize Size of the entire Rich header in bytes
+ * @param RichHeaderPtr Pointer to the decrypted Rich header data
+ * @param PeFileRichHeader structure containing the parsed Rich header entries
+ *
+ * @warning Assumes the Rich header has been properly decrypted first
+ */
+static BOOLEAN
+SetRichEntries(INT RichHeaderSize, CHAR * RichHeaderPtr, PRICH_HEADER PeFileRichHeader)
+{
+ if (RichHeaderPtr == NULL || PeFileRichHeader == NULL || PeFileRichHeader->Entries == NULL ||
+ RichHeaderSize < 16 || ((RichHeaderSize - 16) % 8) != 0)
+ {
+ return FALSE;
+ }
+
+ INT EntryCount = (RichHeaderSize - 16) / 8;
+
+ if (EntryCount <= 0)
+ {
+ return FALSE;
+ }
+
+ //
+ // Start at offset 16 to skip the header metadata, process 8-byte entries
+ //
+ for (int i = 16, EntryIndex = 0; i + 8 <= RichHeaderSize; i += 8, EntryIndex++)
+ {
+ //
+ // Extract Product ID (bytes 2-3 of entry, little-endian)
+ //
+ WORD ProdID = ((UCHAR)RichHeaderPtr[i + 3] << 8) | (UCHAR)RichHeaderPtr[i + 2];
+
+ //
+ // Extract Build ID (bytes 0-1 of entry, little-endian)
+ //
+ WORD BuildID = ((UCHAR)RichHeaderPtr[i + 1] << 8) | (UCHAR)RichHeaderPtr[i];
+
+ //
+ // Extract Use Count (bytes 4-7 of entry, little-endian 32-bit)
+ //
+ DWORD UseCount = PeReadDwordFromBuffer((const BYTE *)RichHeaderPtr, i + 4);
+
+ //
+ // Store the parsed entry (adjust index: i/8 gives entry number, -2 for header offset)
+ //
+ PeFileRichHeader->Entries[EntryIndex] = {ProdID, BuildID, UseCount};
+ }
+
+ PeFileRichHeader->Entries[EntryCount] = {0x0000, 0x0000, 0x00000000};
+
+ return TRUE;
+}
+
+/**
+ * @brief Determines the size of the Rich header by finding the DanS signature
+ *
+ * The Rich header begins with the "DanS" signature (after decryption) and ends
+ * with the "Rich" signature. This function works backwards from the "Rich" signature
+ * to find the beginning and calculate the total size.
+ *
+ * Rich header structure:
+ * [DanS signature] [Padding] [Tool Entries] [Rich signature] [XOR Key]
+ *
+ * @param Key 4-byte XOR key for decryption (extracted from after "Rich" signature)
+ * @param Index Offset where "Rich" signature was found
+ * @param DataPtr Pointer to the beginning of the PE file data
+ *
+ * @return INT Size of the Rich header in bytes, or 0 if DanS signature not found
+ *
+ */
+static INT
+DecryptRichHeader(CHAR Key[], INT Index, CHAR * DataPtr, INT DataSize)
+{
+ if (Key == NULL || DataPtr == NULL || DataSize < 16 || Index < 16 || Index + 4 > DataSize)
+ {
+ return 0;
+ }
+
+ //
+ // Start searching backwards from just before the "Rich" signature
+ //
+ INT IndexPointer = Index - 4;
+ INT RichHeaderSize = 0;
+
+ //
+ // Search backwards for the DanS signature that marks the beginning
+ //
+ while (IndexPointer >= 0)
+ {
+ CHAR TmpChar[4];
+
+ //
+ // Read 4 bytes and decrypt them with the XOR key
+ //
+ memcpy(TmpChar, DataPtr + IndexPointer, 4);
+
+ for (int i = 0; i < 4; i++)
+ {
+ TmpChar[i] ^= Key[i];
+ }
+
+ //
+ // Move backwards and increment size counter
+ //
+ IndexPointer -= 4;
+ RichHeaderSize += 4;
+
+ //
+ // Check for DanS signature after decryption.
+ //
+ if (TmpChar[0] == 'D' && TmpChar[1] == 'a' && TmpChar[2] == 'n' && TmpChar[3] == 'S')
+ {
+ return RichHeaderSize;
+ }
+ }
+
+ return 0;
+}
+
/**
* @brief Show hex dump of sections of PE
* @param Ptr
@@ -19,17 +3664,24 @@
*
* @return VOID
*/
-VOID
-PeHexDump(CHAR * Ptr, int Size, int SecAddress)
+
+static VOID
+PeHexDump(CHAR * Ptr, SIZE_T Size, ULONGLONG SecAddress)
{
- int i = 1, Temp = 0;
+ SIZE_T i = 1;
+ INT Temp = 0;
+
+ if (Ptr == NULL || Size == 0)
+ {
+ return;
+ }
//
// Buffer to store the character dump displayed at the
// right side
//
- wchar_t Buf[18];
- ShowMessages("\n\n%x: |", SecAddress);
+ CHAR Buf[18];
+ ShowMessages("\n\n%llx: |", SecAddress);
Buf[Temp] = ' '; // initial space
Buf[Temp + 16] = ' '; // final space
@@ -38,7 +3690,7 @@ PeHexDump(CHAR * Ptr, int Size, int SecAddress)
for (; i <= Size; i++, Ptr++, Temp++)
{
- Buf[Temp] = !iswcntrl((*Ptr) & 0xff) ? (*Ptr) & 0xff : '.';
+ Buf[Temp] = !iscntrl((*Ptr) & 0xff) ? (*Ptr) & 0xff : '.';
ShowMessages("%-3.2x", (*Ptr) & 0xff);
if (i % 16 == 0)
@@ -46,9 +3698,9 @@ PeHexDump(CHAR * Ptr, int Size, int SecAddress)
//
// print the character dump to the right
//
- _putws(Buf);
+ ShowMessages("%s\n", Buf);
if (i + 1 <= Size)
- ShowMessages("%x: ", SecAddress += 16);
+ ShowMessages("%llx: ", SecAddress += 16);
Temp = 0;
}
if (i % 4 == 0)
@@ -59,7 +3711,7 @@ PeHexDump(CHAR * Ptr, int Size, int SecAddress)
Buf[Temp] = 0;
for (; i % 16 != 0; i++)
ShowMessages("%-3.2c", ' ');
- _putws(Buf);
+ ShowMessages("%s\n", Buf);
}
}
@@ -72,47 +3724,59 @@ PeHexDump(CHAR * Ptr, int Size, int SecAddress)
* @return BOOLEAN
*/
BOOLEAN
-PeShowSectionInformationAndDump(const WCHAR * AddressOfFile, const CHAR * SectionToShow, BOOLEAN Is32Bit)
+PeShowSectionInformationAndDump(const WCHAR * AddressOfFile,
+ const CHAR * SectionToShow,
+ BOOLEAN Is32Bit)
{
- BOOLEAN Result = FALSE;
- HANDLE MapObjectHandle, FileHandle; // File Mapping Object
- UINT32 NumberOfSections; // Number of sections
- LPVOID BaseAddr; // Pointer to the base memory of mapped file
- PIMAGE_DOS_HEADER DosHeader; // Pointer to DOS Header
- PIMAGE_NT_HEADERS32 NtHeader32 = NULL; // Pointer to NT Header 32 bit
- PIMAGE_NT_HEADERS64 NtHeader64 = NULL; // Pointer to NT Header 64 bit
- IMAGE_FILE_HEADER Header; // Pointer to image file header of NT Header
- IMAGE_OPTIONAL_HEADER32 OpHeader32; // Optional Header of PE files present in NT Header structure
- IMAGE_OPTIONAL_HEADER64 OpHeader64; // Optional Header of PE files present in NT Header structure
- PIMAGE_SECTION_HEADER SecHeader; // Section Header or Section Table Header
+ RICH_HEADER_INFO PeFileRichHeaderInfo {0};
+ RICH_HEADER PeFileRichHeader {0};
+ BOOLEAN Result = FALSE, RichFound = FALSE, SectionFound = FALSE;
+ const DWORD MaxRichReadSize = 1024 * 1024;
+ const INT MaxRichHeaderSize = 256 * 1024;
+ const INT MaxRichHeaderEntries = 0x4000;
+ const DWORD MaxSectionScanBytes = 16 * 1024 * 1024;
+ const ULONGLONG MaxTotalSectionScanBytes = 64 * 1024 * 1024;
+ const SIZE_T MaxSectionDumpBytes = 1024 * 1024;
+ const ULONGLONG MaxTotalSectionDumpBytes = 4 * 1024 * 1024;
+ HANDLE FileHandle = INVALID_HANDLE_VALUE; // Open file handle (kept for the raw Rich-header read)
+ SIZE_T MappedSize = 0; // Size of the mapped file in bytes
+ UINT32 NumberOfSections; // Number of sections
+ LPVOID BaseAddr = NULL; // Pointer to the base memory of mapped file
+ PIMAGE_DOS_HEADER DosHeader; // Pointer to DOS Header
+ PIMAGE_NT_HEADERS32 NtHeader32 = NULL; // Pointer to NT Header 32 bit
+ PIMAGE_NT_HEADERS64 NtHeader64 = NULL; // Pointer to NT Header 64 bit
+ IMAGE_FILE_HEADER Header; // Pointer to image file header of NT Header
+ IMAGE_OPTIONAL_HEADER32 OpHeader32; // Optional Header of PE files present in NT Header structure
+ IMAGE_OPTIONAL_HEADER64 OpHeader64; // Optional Header of PE files present in NT Header structure
+ const IMAGE_SECTION_HEADER * SecHeader; // Section Header or Section Table Header
+ PE_IMAGE_READER Reader;
+ IMAGE_DATA_DIRECTORY EmptyDirectory = {0};
+ LARGE_INTEGER FileSize;
+ CHAR Key[4];
+ INT RichHeaderOffset = -1;
+ const CHAR * RichHeaderStatus = "not found";
+ BOOLEAN RichSearchCapped = FALSE;
+ ULONGLONG RemainingSectionScanBytes = MaxTotalSectionScanBytes;
+ ULONGLONG RemainingSectionDumpBytes = MaxTotalSectionDumpBytes;
+ time_t TimeDateStamp;
//
- // Open the EXE File
+ // Open and map the EXE file read-only. The wrapper also hands back the open
+ // file handle so the raw Rich-header read below can still seek/read it.
//
- FileHandle = CreateFileW(AddressOfFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (FileHandle == INVALID_HANDLE_VALUE)
- {
- ShowMessages("err, could not open the file specified\n");
- return FALSE;
- };
-
- //
- // Mapping Given EXE file to Memory
- //
- MapObjectHandle =
- CreateFileMapping(FileHandle, NULL, PAGE_READONLY, 0, 0, NULL);
-
- if (MapObjectHandle == NULL)
- {
- CloseHandle(FileHandle);
- return FALSE;
- }
-
- BaseAddr = MapViewOfFile(MapObjectHandle, FILE_MAP_READ, 0, 0, 0);
+ BaseAddr = PlatformMapFileReadOnly(AddressOfFile, &MappedSize, &FileHandle);
if (BaseAddr == NULL)
{
- CloseHandle(FileHandle);
+ ShowMessages("err, could not open the file specified\n");
+ return FALSE;
+ }
+
+ FileSize.QuadPart = (LONGLONG)MappedSize;
+
+ if (FileSize.QuadPart < (LONGLONG)sizeof(IMAGE_DOS_HEADER))
+ {
+ PlatformUnmapFile(BaseAddr, MappedSize, FileHandle);
return FALSE;
}
@@ -121,6 +3785,139 @@ PeShowSectionInformationAndDump(const WCHAR * AddressOfFile, const CHAR * Sectio
//
DosHeader = (PIMAGE_DOS_HEADER)BaseAddr; // 0x04000000
+ if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE ||
+ DosHeader->e_lfanew < sizeof(IMAGE_DOS_HEADER) ||
+ (LONGLONG)DosHeader->e_lfanew > FileSize.QuadPart ||
+ (LONGLONG)DosHeader->e_lfanew + (LONGLONG)(Is32Bit ? sizeof(IMAGE_NT_HEADERS32) : sizeof(IMAGE_NT_HEADERS64)) > FileSize.QuadPart)
+ {
+ ShowMessages("\nGiven File is not a valid PE file\n");
+ Result = FALSE;
+ goto Finished;
+ }
+
+ if (!PeImageReaderInitialize((const BYTE *)BaseAddr, (SIZE_T)FileSize.QuadPart, &Reader))
+ {
+ ShowMessages("\nGiven File is not a valid PE file\n");
+ Result = FALSE;
+ goto Finished;
+ }
+
+ if (DosHeader->e_lfanew > 0 && (ULONGLONG)DosHeader->e_lfanew <= (ULONGLONG)MAXDWORD)
+ {
+ CHAR * DataPtr = NULL;
+ DWORD BytesRead = 0;
+ DWORD RichReadSize = (DWORD)DosHeader->e_lfanew;
+ DWORD SearchOffset = 0;
+ BOOLEAN HadCandidate = FALSE;
+ LARGE_INTEGER FileStart = {0};
+
+ if (RichReadSize > MaxRichReadSize)
+ {
+ RichReadSize = MaxRichReadSize;
+ RichHeaderStatus = "not found in first 1 MiB";
+ RichSearchCapped = TRUE;
+ }
+
+ if (RichReadSize >= 8)
+ {
+ DataPtr = new (std::nothrow) CHAR[RichReadSize];
+ if (DataPtr == NULL)
+ {
+ RichHeaderStatus = "allocation failed";
+ goto SkipRichHeader;
+ }
+
+ if (!PlatformReadFileAtOffset(FileHandle, 0, DataPtr, RichReadSize, &BytesRead) || BytesRead != RichReadSize)
+ {
+ RichHeaderStatus = "read failed";
+ delete[] DataPtr;
+ goto SkipRichHeader;
+ }
+
+ for (;;)
+ {
+ CHAR * RichHeaderPtr = NULL;
+
+ RichHeaderOffset = FindRichHeader(DosHeader, RichReadSize, SearchOffset, Key);
+ if (RichHeaderOffset < 0)
+ {
+ break;
+ }
+
+ HadCandidate = TRUE;
+ RichHeaderStatus = RichSearchCapped ? "malformed candidate in first 1 MiB" : "malformed";
+
+ INT RichHeaderSize = DecryptRichHeader(Key, RichHeaderOffset, DataPtr, (INT)RichReadSize);
+ INT IndexPointer = RichHeaderOffset - RichHeaderSize;
+
+ if (RichHeaderSize < 16 || RichHeaderSize > MaxRichHeaderSize || ((RichHeaderSize - 16) % 8) != 0 ||
+ (RichHeaderSize - 16) / 8 == 0 || (RichHeaderSize - 16) / 8 > MaxRichHeaderEntries ||
+ IndexPointer < 0 || RichHeaderSize > (INT)RichReadSize || IndexPointer > (INT)RichReadSize - RichHeaderSize)
+ {
+ SearchOffset = (DWORD)RichHeaderOffset + 1;
+ continue;
+ }
+
+ RichHeaderPtr = new (std::nothrow) CHAR[RichHeaderSize];
+ if (RichHeaderPtr == NULL)
+ {
+ RichHeaderStatus = "allocation failed";
+ break;
+ }
+
+ memcpy(RichHeaderPtr, DataPtr + IndexPointer, RichHeaderSize);
+
+ if (!FindRichEntries(RichHeaderPtr, RichHeaderSize, Key, &PeFileRichHeaderInfo))
+ {
+ delete[] RichHeaderPtr;
+ SearchOffset = (DWORD)RichHeaderOffset + 1;
+ continue;
+ }
+
+ RichHeaderPtr = NULL;
+
+ if (PeFileRichHeaderInfo.Entries > MaxRichHeaderEntries || PeFileRichHeaderInfo.Entries >= INT_MAX / (INT)sizeof(RICH_HEADER_ENTRY) - 1)
+ {
+ delete[] PeFileRichHeaderInfo.PtrToBuffer;
+ PeFileRichHeaderInfo = {0};
+ SearchOffset = (DWORD)RichHeaderOffset + 1;
+ continue;
+ }
+
+ PeFileRichHeader.Entries = new (std::nothrow) RICH_HEADER_ENTRY[PeFileRichHeaderInfo.Entries + 1];
+ if (PeFileRichHeader.Entries == NULL)
+ {
+ RichHeaderStatus = "allocation failed";
+ delete[] PeFileRichHeaderInfo.PtrToBuffer;
+ PeFileRichHeaderInfo = {0};
+ break;
+ }
+
+ if (!SetRichEntries(RichHeaderSize, PeFileRichHeaderInfo.PtrToBuffer, &PeFileRichHeader))
+ {
+ delete[] PeFileRichHeaderInfo.PtrToBuffer;
+ PeFileRichHeaderInfo = {0};
+ delete[] PeFileRichHeader.Entries;
+ PeFileRichHeader.Entries = NULL;
+ SearchOffset = (DWORD)RichHeaderOffset + 1;
+ continue;
+ }
+
+ RichFound = TRUE;
+ break;
+ }
+
+ if (!RichFound && !HadCandidate && (DWORD)DosHeader->e_lfanew <= MaxRichReadSize)
+ {
+ RichHeaderStatus = "not found";
+ }
+
+ delete[] DataPtr;
+ }
+ }
+
+SkipRichHeader:
+
//
// Check for Valid DOS file
//
@@ -170,6 +3967,30 @@ PeShowSectionInformationAndDump(const WCHAR * AddressOfFile, const CHAR * Sectio
goto Finished;
}
+ if (RichFound)
+ {
+ ShowMessages("\n===============================================================================\n");
+ ShowMessages(" RICH HEADER \n");
+ ShowMessages("===============================================================================\n");
+ ShowMessages("Entries: %d\n\n", PeFileRichHeaderInfo.Entries);
+ ShowMessages("%-10s %-10s %-10s\n", "Build ID", "Prod ID", "Use Count");
+ ShowMessages("---------------------------------------\n");
+
+ for (int i = 0; i < PeFileRichHeaderInfo.Entries; i++)
+ {
+ ShowMessages("0x%08X 0x%08X %10u\n",
+ PeFileRichHeader.Entries[i].BuildID,
+ PeFileRichHeader.Entries[i].ProdID,
+ PeFileRichHeader.Entries[i].UseCount);
+ }
+
+ ShowMessages("==============Rich Header End ==================\n");
+ }
+ else
+ {
+ ShowMessages("=========== Rich Header Not Shown (%s) ===========\n", RichHeaderStatus);
+ }
+
//
// Offset of NT Header is found at 0x3c location in DOS header specified by
// e_lfanew
@@ -280,9 +4101,10 @@ PeShowSectionInformationAndDump(const WCHAR * AddressOfFile, const CHAR * Sectio
//
// Determine Time Stamp
//
+ TimeDateStamp = Header.TimeDateStamp;
ShowMessages("\n%-36s%s",
"Time Stamp :",
- ctime((const time_t *)&(Header.TimeDateStamp)));
+ ctime(&TimeDateStamp));
//
// Determine number of sections
@@ -292,6 +4114,9 @@ PeShowSectionInformationAndDump(const WCHAR * AddressOfFile, const CHAR * Sectio
ShowMessages("\n%-36s%d",
"Size of optional header :",
Header.SizeOfOptionalHeader);
+ ShowMessages("\n%-36s%#x", "Raw machine value :", Header.Machine);
+ ShowMessages("\n%-36s%#x", "Pointer to symbol table :", Header.PointerToSymbolTable);
+ ShowMessages("\n%-36s%#x", "Raw characteristics value :", Header.Characteristics);
ShowMessages("\n\nDumping PE Optional Header "
"Info....\n-----------------------------------");
@@ -306,13 +4131,20 @@ PeShowSectionInformationAndDump(const WCHAR * AddressOfFile, const CHAR * Sectio
ShowMessages("\n%-36s%#x",
"Address of Entry Point : ",
OpHeader32.AddressOfEntryPoint);
+ ShowMessages("\n%-36s%#x", "Raw optional header magic :", OpHeader32.Magic);
+ PeShowEntrypointFileOffset(&Reader, OpHeader32.AddressOfEntryPoint);
ShowMessages("\n%-36s%#llx", "Base Address of the Image : ", OpHeader32.ImageBase);
- ShowMessages("\n%-36s%s", "SubSystem type : ", OpHeader32.Subsystem == 1 ? "Device Driver(Native windows Process)" : OpHeader32.Subsystem == 2 ? "Windows GUI"
- : OpHeader32.Subsystem == 3 ? "Windows CLI"
- : OpHeader32.Subsystem == 3 ? "Windows CLI"
- : OpHeader32.Subsystem == 9 ? "Windows CE GUI"
- : "Unknown");
+ ShowMessages("\n%-36s%s", "SubSystem type : ", PeGetSubsystemName(OpHeader32.Subsystem));
ShowMessages("\n%-36s%s", "Given file is a : ", OpHeader32.Magic == 0x20b ? "PE32+(64)" : "PE32");
+ ShowMessages("\n%-36s%#x", "File Alignment :", OpHeader32.FileAlignment);
+ ShowMessages("\n%-36s%#x", "Size of Image :", OpHeader32.SizeOfImage);
+ ShowMessages("\n%-36s%#x", "Size of Headers :", OpHeader32.SizeOfHeaders);
+ PeShowChecksum(&Reader,
+ OpHeader32.CheckSum,
+ (SIZE_T)(Reader.NtHeaders - Reader.ImageBase) + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + FIELD_OFFSET(IMAGE_OPTIONAL_HEADER32, CheckSum));
+ ShowMessages("\n%-36s%#x", "Raw DLL characteristics value :", OpHeader32.DllCharacteristics);
+ ShowMessages("\n%-36s", "DLL characteristics flags :");
+ PeShowDllCharacteristics(OpHeader32.DllCharacteristics);
ShowMessages("\n%-36s%d", "Size of code segment(.text) : ", OpHeader32.SizeOfCode);
ShowMessages("\n%-36s%#x",
"Base address of code segment(RVA) :",
@@ -328,6 +4160,39 @@ PeShowSectionInformationAndDump(const WCHAR * AddressOfFile, const CHAR * Sectio
ShowMessages("\n%-36s%#x", "Section Alignment :", OpHeader32.SectionAlignment);
ShowMessages("\n%-36s%d", "Major Linker Version : ", OpHeader32.MajorLinkerVersion);
ShowMessages("\n%-36s%d", "Minor Linker Version : ", OpHeader32.MinorLinkerVersion);
+ PeShowDataDirectories(&Reader, OpHeader32.DataDirectory, OpHeader32.NumberOfRvaAndSizes);
+ PeShowCertificateTable(&Reader,
+ OpHeader32.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_SECURITY ? &OpHeader32.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY] : &EmptyDirectory);
+ PeShowBaseRelocations(&Reader,
+ OpHeader32.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BASERELOC ? &OpHeader32.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC] : &EmptyDirectory);
+ PeShowBoundImports(&Reader,
+ OpHeader32.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT ? &OpHeader32.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT] : &EmptyDirectory);
+ PeShowResources(&Reader,
+ OpHeader32.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_RESOURCE ? &OpHeader32.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE] : &EmptyDirectory);
+ PeShowExceptions(&Reader,
+ OpHeader32.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_EXCEPTION ? &OpHeader32.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION] : &EmptyDirectory,
+ Header.Machine,
+ TRUE);
+ PeShowDelayImports(&Reader,
+ OpHeader32.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT ? &OpHeader32.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT] : &EmptyDirectory,
+ TRUE,
+ OpHeader32.ImageBase);
+ PeShowClrRuntime(&Reader,
+ OpHeader32.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR ? &OpHeader32.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR] : &EmptyDirectory);
+ PeShowTls(&Reader,
+ OpHeader32.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_TLS ? &OpHeader32.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS] : &EmptyDirectory,
+ TRUE,
+ OpHeader32.ImageBase);
+ PeShowDebug(&Reader,
+ OpHeader32.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_DEBUG ? &OpHeader32.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG] : &EmptyDirectory);
+ PeShowLoadConfig(&Reader,
+ OpHeader32.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG ? &OpHeader32.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG] : &EmptyDirectory,
+ TRUE);
+ PeShowImports(&Reader,
+ OpHeader32.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_IMPORT ? &OpHeader32.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] : &EmptyDirectory,
+ TRUE);
+ PeShowExports(&Reader,
+ OpHeader32.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_EXPORT ? &OpHeader32.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] : &EmptyDirectory);
}
else
{
@@ -339,13 +4204,20 @@ PeShowSectionInformationAndDump(const WCHAR * AddressOfFile, const CHAR * Sectio
ShowMessages("\n%-36s%#x",
"Address of Entry Point : ",
OpHeader64.AddressOfEntryPoint);
+ ShowMessages("\n%-36s%#x", "Raw optional header magic :", OpHeader64.Magic);
+ PeShowEntrypointFileOffset(&Reader, OpHeader64.AddressOfEntryPoint);
ShowMessages("\n%-36s%#llx", "Base Address of the Image : ", OpHeader64.ImageBase);
- ShowMessages("\n%-36s%s", "SubSystem type : ", OpHeader64.Subsystem == 1 ? "Device Driver(Native windows Process)" : OpHeader64.Subsystem == 2 ? "Windows GUI"
- : OpHeader64.Subsystem == 3 ? "Windows CLI"
- : OpHeader64.Subsystem == 3 ? "Windows CLI"
- : OpHeader64.Subsystem == 9 ? "Windows CE GUI"
- : "Unknown");
+ ShowMessages("\n%-36s%s", "SubSystem type : ", PeGetSubsystemName(OpHeader64.Subsystem));
ShowMessages("\n%-36s%s", "Given file is a : ", OpHeader64.Magic == 0x20b ? "PE32+(64)" : "PE32");
+ ShowMessages("\n%-36s%#x", "File Alignment :", OpHeader64.FileAlignment);
+ ShowMessages("\n%-36s%#x", "Size of Image :", OpHeader64.SizeOfImage);
+ ShowMessages("\n%-36s%#x", "Size of Headers :", OpHeader64.SizeOfHeaders);
+ PeShowChecksum(&Reader,
+ OpHeader64.CheckSum,
+ (SIZE_T)(Reader.NtHeaders - Reader.ImageBase) + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + FIELD_OFFSET(IMAGE_OPTIONAL_HEADER64, CheckSum));
+ ShowMessages("\n%-36s%#x", "Raw DLL characteristics value :", OpHeader64.DllCharacteristics);
+ ShowMessages("\n%-36s", "DLL characteristics flags :");
+ PeShowDllCharacteristics(OpHeader64.DllCharacteristics);
ShowMessages("\n%-36s%d", "Size of code segment(.text) : ", OpHeader64.SizeOfCode);
ShowMessages("\n%-36s%#x",
"Base address of code segment(RVA) :",
@@ -357,6 +4229,39 @@ PeShowSectionInformationAndDump(const WCHAR * AddressOfFile, const CHAR * Sectio
ShowMessages("\n%-36s%#x", "Section Alignment :", OpHeader64.SectionAlignment);
ShowMessages("\n%-36s%d", "Major Linker Version : ", OpHeader64.MajorLinkerVersion);
ShowMessages("\n%-36s%d", "Minor Linker Version : ", OpHeader64.MinorLinkerVersion);
+ PeShowDataDirectories(&Reader, OpHeader64.DataDirectory, OpHeader64.NumberOfRvaAndSizes);
+ PeShowCertificateTable(&Reader,
+ OpHeader64.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_SECURITY ? &OpHeader64.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY] : &EmptyDirectory);
+ PeShowBaseRelocations(&Reader,
+ OpHeader64.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BASERELOC ? &OpHeader64.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC] : &EmptyDirectory);
+ PeShowBoundImports(&Reader,
+ OpHeader64.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT ? &OpHeader64.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT] : &EmptyDirectory);
+ PeShowResources(&Reader,
+ OpHeader64.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_RESOURCE ? &OpHeader64.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE] : &EmptyDirectory);
+ PeShowExceptions(&Reader,
+ OpHeader64.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_EXCEPTION ? &OpHeader64.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION] : &EmptyDirectory,
+ Header.Machine,
+ FALSE);
+ PeShowDelayImports(&Reader,
+ OpHeader64.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT ? &OpHeader64.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT] : &EmptyDirectory,
+ FALSE,
+ OpHeader64.ImageBase);
+ PeShowClrRuntime(&Reader,
+ OpHeader64.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR ? &OpHeader64.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR] : &EmptyDirectory);
+ PeShowTls(&Reader,
+ OpHeader64.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_TLS ? &OpHeader64.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS] : &EmptyDirectory,
+ FALSE,
+ OpHeader64.ImageBase);
+ PeShowDebug(&Reader,
+ OpHeader64.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_DEBUG ? &OpHeader64.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG] : &EmptyDirectory);
+ PeShowLoadConfig(&Reader,
+ OpHeader64.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG ? &OpHeader64.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG] : &EmptyDirectory,
+ FALSE);
+ PeShowImports(&Reader,
+ OpHeader64.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_IMPORT ? &OpHeader64.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] : &EmptyDirectory,
+ FALSE);
+ PeShowExports(&Reader,
+ OpHeader64.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_EXPORT ? &OpHeader64.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] : &EmptyDirectory);
}
ShowMessages("\n\nDumping Sections Header "
@@ -365,30 +4270,31 @@ PeShowSectionInformationAndDump(const WCHAR * AddressOfFile, const CHAR * Sectio
//
// Retrieve a pointer to First Section Header(or Section Table Entry)
//
- if (Is32Bit)
- {
- SecHeader = IMAGE_FIRST_SECTION(NtHeader32);
- NumberOfSections = NtHeader32->FileHeader.NumberOfSections;
- }
- else
- {
- SecHeader = IMAGE_FIRST_SECTION(NtHeader64);
- NumberOfSections = NtHeader64->FileHeader.NumberOfSections;
- }
+ SecHeader = Reader.SectionHeaders;
+ NumberOfSections = Reader.FileHeader->NumberOfSections;
for (UINT32 i = 0; i < NumberOfSections; i++, SecHeader++)
{
- if (Is32Bit)
+ CHAR SectionName[IMAGE_SIZEOF_SHORT_NAME + 1];
+ const BYTE * Pointer = NULL;
+ const CHAR * RawDataBounds = "empty";
+
+ PeImageReaderGetSectionName(SecHeader, SectionName, sizeof(SectionName));
+
+ if (SecHeader->SizeOfRawData != 0)
{
- ShowMessages("\n\nSection Info (%d of %d)", i + 1, NtHeader32->FileHeader.NumberOfSections);
- }
- else
- {
- ShowMessages("\n\nSection Info (%d of %d)", i + 1, NtHeader64->FileHeader.NumberOfSections);
+ RawDataBounds = PeImageReaderGetPointerAtOffset(&Reader,
+ SecHeader->PointerToRawData,
+ SecHeader->SizeOfRawData,
+ &Pointer)
+ ? "valid"
+ : "invalid";
}
+ ShowMessages("\n\nSection Info (%d of %d)", i + 1, NumberOfSections);
+
ShowMessages("\n---------------------");
- ShowMessages("\n%-36s%s", "Section Header name : ", SecHeader->Name);
+ ShowMessages("\n%-36s%s", "Section Header name : ", SectionName);
ShowMessages("\n%-36s%#x",
"ActualSize of code or data : ",
SecHeader->Misc.VirtualSize);
@@ -399,6 +4305,31 @@ PeShowSectionInformationAndDump(const WCHAR * AddressOfFile, const CHAR * Sectio
ShowMessages("\n%-36s%#x",
"Pointer to Raw Data : ",
SecHeader->PointerToRawData);
+ ShowMessages("\n%-36s%s", "Raw data bounds :", RawDataBounds);
+ if (Pointer != NULL && SecHeader->SizeOfRawData != 0)
+ {
+ if (SecHeader->SizeOfRawData > MaxSectionScanBytes)
+ {
+ ShowMessages("\n%-36s%s", "Raw data entropy :", "skipped, section is larger than local cap");
+ ShowMessages("\n%-36s%s", "Raw data FNV-1a64 :", "skipped, section is larger than local cap");
+ }
+ else if ((ULONGLONG)SecHeader->SizeOfRawData > RemainingSectionScanBytes)
+ {
+ RemainingSectionScanBytes = 0;
+ ShowMessages("\n%-36s%s", "Raw data entropy :", "skipped, global scan budget exhausted");
+ ShowMessages("\n%-36s%s", "Raw data FNV-1a64 :", "skipped, global scan budget exhausted");
+ }
+ else
+ {
+ ShowMessages("\n%-36s%.4f", "Raw data entropy :", PeCalculateEntropy(Pointer, SecHeader->SizeOfRawData));
+ ShowMessages("\n%-36s%#llx", "Raw data FNV-1a64 :", PeFnv1a64(Pointer, SecHeader->SizeOfRawData));
+ RemainingSectionScanBytes -= SecHeader->SizeOfRawData;
+ }
+ }
+ if (SecHeader->SizeOfRawData != 0 && SecHeader->Misc.VirtualSize > SecHeader->SizeOfRawData)
+ {
+ ShowMessages("\n%-36s%s", "Warning :", "virtual size is larger than raw data");
+ }
ShowMessages("\n%-36s%#x",
"Pointer to Relocations : ",
SecHeader->PointerToRelocations);
@@ -432,27 +4363,88 @@ PeShowSectionInformationAndDump(const WCHAR * AddressOfFile, const CHAR * Sectio
//
if (SectionToShow != NULL)
{
- if (!_strcmpi(SectionToShow, (const char *)SecHeader->Name))
+ if (!_strcmpi(SectionToShow, SectionName))
{
+ SectionFound = TRUE;
+
if (SecHeader->SizeOfRawData != 0)
{
+ SIZE_T DumpSize = SecHeader->SizeOfRawData;
+ BOOLEAN TruncatedBySectionCap = FALSE;
+ BOOLEAN TruncatedByGlobalCap = FALSE;
+
+ if (Pointer == NULL)
+ {
+ ShowMessages("\nerr, invalid section raw data\n");
+ continue;
+ }
+
+ if (RemainingSectionDumpBytes == 0)
+ {
+ ShowMessages("\n%-36s%s", "Warning, section dump skipped :", "global dump budget exhausted");
+ continue;
+ }
+
+ if (DumpSize > MaxSectionDumpBytes)
+ {
+ DumpSize = MaxSectionDumpBytes;
+ TruncatedBySectionCap = TRUE;
+ }
+
+ if ((ULONGLONG)DumpSize > RemainingSectionDumpBytes)
+ {
+ DumpSize = (SIZE_T)RemainingSectionDumpBytes;
+ TruncatedByGlobalCap = TRUE;
+ }
+
+ if (TruncatedBySectionCap)
+ {
+ ShowMessages("\n%-36s%#llx of %#x bytes",
+ "Warning, section dump truncated by section cap :",
+ (UINT64)DumpSize,
+ SecHeader->SizeOfRawData);
+ }
+ if (TruncatedByGlobalCap)
+ {
+ ShowMessages("\n%-36s%#llx of %#x bytes",
+ "Warning, section dump truncated by global cap :",
+ (UINT64)DumpSize,
+ SecHeader->SizeOfRawData);
+ }
+
if (Is32Bit)
{
- PeHexDump((char *)((UINT64)DosHeader + SecHeader->PointerToRawData),
- SecHeader->SizeOfRawData,
- OpHeader32.ImageBase + SecHeader->VirtualAddress);
+ PeHexDump((CHAR *)Pointer,
+ DumpSize,
+ (ULONGLONG)OpHeader32.ImageBase + SecHeader->VirtualAddress);
}
else
{
- PeHexDump((char *)((UINT64)DosHeader + SecHeader->PointerToRawData),
- SecHeader->SizeOfRawData,
- (int)(OpHeader64.ImageBase + SecHeader->VirtualAddress));
+ PeHexDump((CHAR *)Pointer,
+ DumpSize,
+ OpHeader64.ImageBase + SecHeader->VirtualAddress);
}
+
+ RemainingSectionDumpBytes -= DumpSize;
}
}
}
}
+ PeShowOverlayAndWarnings(&Reader,
+ Header.Machine,
+ Is32Bit ? OpHeader32.Magic : OpHeader64.Magic,
+ Is32Bit ? OpHeader32.AddressOfEntryPoint : OpHeader64.AddressOfEntryPoint,
+ Is32Bit ? OpHeader32.SizeOfImage : OpHeader64.SizeOfImage,
+ Is32Bit ? OpHeader32.SizeOfHeaders : OpHeader64.SizeOfHeaders,
+ Is32Bit ? OpHeader32.DataDirectory : OpHeader64.DataDirectory,
+ Is32Bit ? OpHeader32.NumberOfRvaAndSizes : OpHeader64.NumberOfRvaAndSizes);
+
+ if (SectionToShow != NULL && !SectionFound)
+ {
+ ShowMessages("\nerr, section '%s' was not found\n", SectionToShow);
+ }
+
ShowMessages("\n==============================================================="
"================\n");
@@ -465,8 +4457,17 @@ Finished:
//
// Unmap and close the handles
//
- UnmapViewOfFile(BaseAddr);
- CloseHandle(MapObjectHandle);
+ if (PeFileRichHeaderInfo.PtrToBuffer != NULL)
+ {
+ delete[] PeFileRichHeaderInfo.PtrToBuffer;
+ }
+
+ if (PeFileRichHeader.Entries != NULL)
+ {
+ delete[] PeFileRichHeader.Entries;
+ }
+
+ PlatformUnmapFile(BaseAddr, MappedSize, FileHandle);
return Result;
}
@@ -481,45 +4482,31 @@ Finished:
BOOLEAN
PeIsPE32BitOr64Bit(const WCHAR * AddressOfFile, PBOOLEAN Is32Bit)
{
- BOOLEAN Result = FALSE;
- HANDLE MapObjectHandle, FileHandle; // File Mapping Object
- LPVOID BaseAddr; // Pointer to the base memory of mapped file
- PIMAGE_DOS_HEADER DosHeader; // Pointer to DOS Header
- PIMAGE_NT_HEADERS32 NtHeader32 = NULL; // Pointer to NT Header 32 bit
- IMAGE_OPTIONAL_HEADER32 OpHeader32; // Optional Header of PE files present in NT Header structure
- IMAGE_FILE_HEADER Header; // Pointer to image file header of NT Header
+ BOOLEAN Result = FALSE;
+ HANDLE FileHandle = INVALID_HANDLE_VALUE; // Open file handle
+ SIZE_T MappedSize = 0; // Size of the mapped file in bytes
+ LPVOID BaseAddr; // Pointer to the base memory of mapped file
+ PIMAGE_DOS_HEADER DosHeader; // Pointer to DOS Header
+ PIMAGE_NT_HEADERS32 NtHeader32 = NULL; // Pointer to NT Header 32 bit
+ PE_IMAGE_READER Reader;
+ LARGE_INTEGER FileSize;
//
- // Open the EXE File
+ // Open and map the EXE file read-only
//
- FileHandle = CreateFileW(AddressOfFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (FileHandle == INVALID_HANDLE_VALUE)
- {
- ShowMessages("err, unable to read the file (%x)\n", GetLastError());
- return FALSE;
- };
-
- //
- // Mapping Given EXE file to Memory
- //
- MapObjectHandle =
- CreateFileMapping(FileHandle, NULL, PAGE_READONLY, 0, 0, NULL);
-
- if (MapObjectHandle == NULL)
- {
- CloseHandle(FileHandle);
-
- ShowMessages("err, unable to create file mappings (%x)\n", GetLastError());
- return FALSE;
- }
-
- BaseAddr = MapViewOfFile(MapObjectHandle, FILE_MAP_READ, 0, 0, 0);
+ BaseAddr = PlatformMapFileReadOnly(AddressOfFile, &MappedSize, &FileHandle);
if (BaseAddr == NULL)
{
- CloseHandle(FileHandle);
+ ShowMessages("err, unable to read or map the file (%x)\n", PlatformGetLastError());
+ return FALSE;
+ }
- ShowMessages("err, unable to create map view of file (%x)\n", GetLastError());
+ FileSize.QuadPart = (LONGLONG)MappedSize;
+
+ if (FileSize.QuadPart < (LONGLONG)sizeof(IMAGE_DOS_HEADER))
+ {
+ PlatformUnmapFile(BaseAddr, MappedSize, FileHandle);
return FALSE;
}
@@ -539,6 +4526,15 @@ PeIsPE32BitOr64Bit(const WCHAR * AddressOfFile, PBOOLEAN Is32Bit)
goto Finished;
}
+ if (DosHeader->e_lfanew < sizeof(IMAGE_DOS_HEADER) ||
+ (LONGLONG)DosHeader->e_lfanew + (LONGLONG)sizeof(IMAGE_NT_HEADERS32) > FileSize.QuadPart)
+ {
+ Result = FALSE;
+
+ ShowMessages("err, invalid image NT header offset\n");
+ goto Finished;
+ }
+
//
// Offset of NT Header is found at 0x3c location in DOS header specified by
// e_lfanew
@@ -559,21 +4555,19 @@ PeIsPE32BitOr64Bit(const WCHAR * AddressOfFile, PBOOLEAN Is32Bit)
goto Finished;
}
- //
- // Info about Optional Header
- //
- OpHeader32 = NtHeader32->OptionalHeader;
+ if (!PeImageReaderInitialize((const BYTE *)BaseAddr, (SIZE_T)FileSize.QuadPart, &Reader))
+ {
+ Result = FALSE;
- //
- // Get the IMAGE FILE HEADER Structure
- //
- Header = NtHeader32->FileHeader;
+ ShowMessages("err, the selected file is not in a valid PE format\n");
+ goto Finished;
+ }
//
// Only few are determined (for remaining refer
// to the above specification)
//
- switch (Header.Machine)
+ switch (Reader.FileHeader->Machine)
{
case IMAGE_FILE_MACHINE_I386:
*Is32Bit = TRUE;
@@ -597,8 +4591,7 @@ Finished:
//
// Unmap and close the handles
//
- UnmapViewOfFile(BaseAddr);
- CloseHandle(MapObjectHandle);
+ PlatformUnmapFile(BaseAddr, MappedSize, FileHandle);
return Result;
}
@@ -658,5 +4651,5 @@ PeGetSyscallNumber(LPCSTR NtFunctionName)
// since usually the syscall handler is less than 30 bytes,
// and we want to avoid disassembling another function
//
- return HyperDbgGetImmediateValueOnEaxForSyscallNumber((unsigned char *)TargetFunc, 30, TRUE);
+ return HyperDbgGetImmediateValueOnEaxForSyscallNumber((UCHAR *)TargetFunc, 30, TRUE);
}
diff --git a/hyperdbg/libhyperdbg/code/debugger/user-level/ud.cpp b/hyperdbg/libhyperdbg/code/debugger/user-level/ud.cpp
index 26665fd4..111930b4 100644
--- a/hyperdbg/libhyperdbg/code/debugger/user-level/ud.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/user-level/ud.cpp
@@ -17,6 +17,9 @@
extern UINT32 g_ProcessIdOfLatestStartingProcess;
extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
extern BOOLEAN g_IsUserDebuggerInitialized;
+extern BOOLEAN g_IsVmmModuleLoaded;
+extern UINT64 g_ResultOfEvaluatedExpression;
+extern UINT32 g_ErrorStateOfResultOfEvaluatedExpression;
extern CommandType g_CommandsList;
extern DEBUGGER_SYNCRONIZATION_EVENTS_STATE
g_UserSyncronizationObjectsHandleTable[DEBUGGER_MAXIMUM_SYNCRONIZATION_USER_DEBUGGER_OBJECTS];
@@ -35,7 +38,7 @@ UdInitializeUserDebugger()
//
// Initialize the handle table
//
- for (size_t i = 0; i < DEBUGGER_MAXIMUM_SYNCRONIZATION_USER_DEBUGGER_OBJECTS; i++)
+ for (SIZE_T i = 0; i < DEBUGGER_MAXIMUM_SYNCRONIZATION_USER_DEBUGGER_OBJECTS; i++)
{
g_UserSyncronizationObjectsHandleTable[i].IsOnWaitingState = FALSE;
g_UserSyncronizationObjectsHandleTable[i].EventHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
@@ -68,12 +71,12 @@ UdUninitializeUserDebugger()
//
// Remove the active process
//
- UdRemoveActiveDebuggingProcess(TRUE);
+ UdRemoveActiveDebuggingProcess();
//
// Initialize the handle table
//
- for (size_t i = 0; i < DEBUGGER_MAXIMUM_SYNCRONIZATION_USER_DEBUGGER_OBJECTS; i++)
+ for (SIZE_T i = 0; i < DEBUGGER_MAXIMUM_SYNCRONIZATION_USER_DEBUGGER_OBJECTS; i++)
{
if (g_UserSyncronizationObjectsHandleTable[i].EventHandle != NULL)
{
@@ -97,43 +100,56 @@ UdUninitializeUserDebugger()
/**
* @brief set the current active debugging process (thread)
* @param DebuggingId
+ * @param Rip
* @param ProcessId
* @param ThreadId
* @param Is32Bit
+ * @param InstructionBytesOnRip
*
* @return VOID
*/
VOID
UdSetActiveDebuggingProcess(UINT64 DebuggingId,
+ UINT64 Rip,
UINT32 ProcessId,
UINT32 ThreadId,
BOOLEAN Is32Bit,
- BOOLEAN IsPaused)
+ BOOLEAN IsPaused,
+ BYTE InstructionBytesOnRip[])
{
- g_ActiveProcessDebuggingState.ProcessId = ProcessId;
- g_ActiveProcessDebuggingState.ThreadId = ThreadId;
- g_ActiveProcessDebuggingState.Is32Bit = Is32Bit;
+ //
+ // Activate the debugging
+ //
+ g_ActiveProcessDebuggingState.IsActive = TRUE;
+
+ //
+ // Set the details
+ //
+ g_ActiveProcessDebuggingState.ProcessId = ProcessId;
+ g_ActiveProcessDebuggingState.ThreadId = ThreadId;
+ g_ActiveProcessDebuggingState.Is32Bit = Is32Bit;
+ g_ActiveProcessDebuggingState.Rip = Rip;
+
g_ActiveProcessDebuggingState.ProcessDebuggingToken = DebuggingId;
+ //
+ // Set current instruction
+ //
+ memcpy(&g_ActiveProcessDebuggingState.InstructionBytesOnRip[0], &InstructionBytesOnRip[0], MAXIMUM_INSTR_SIZE);
+
//
// Set pausing state
//
g_ActiveProcessDebuggingState.IsPaused = IsPaused;
-
- //
- // Activate the debugging
- //
- g_ActiveProcessDebuggingState.IsActive = TRUE;
}
/**
* @brief Remove the current active debugging process (thread)
- * @param DontSwitchToNewProcess
*
* @return VOID
*/
VOID
-UdRemoveActiveDebuggingProcess(BOOLEAN DontSwitchToNewProcess)
+UdRemoveActiveDebuggingProcess()
{
//
// Activate the debugging
@@ -369,9 +385,9 @@ UdAttachToProcess(UINT32 TargetPid,
UdInitializeUserDebugger();
//
- // Check if debugger is loaded or not
+ // Check if the VMM module is loaded or not
//
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// Check whether it's starting a new process or not
@@ -458,9 +474,8 @@ UdAttachToProcess(UINT32 TargetPid,
// it's a .attach command, no need for further action
//
ShowMessages("successfully attached to the target process!\n"
- "please keep interacting with the process until all the "
- "threads are intercepted and halted; whenever you execute "
- "the first command, the thread interception will be stopped\n");
+ "please keep interacting with the process until all the threads are "
+ "intercepted and halted; you can run the 'g' command to continue the debuggee\n");
return TRUE;
}
@@ -677,9 +692,9 @@ UdKillProcess(UINT32 TargetPid)
DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS KillRequest = {0};
//
- // Check if debugger is loaded or not
+ // Check if VMM module is loaded or not
//
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// Check if the process exists
@@ -743,7 +758,7 @@ UdKillProcess(UINT32 TargetPid)
//
// Remove the current active debugging process (thread)
//
- UdRemoveActiveDebuggingProcess(FALSE);
+ UdRemoveActiveDebuggingProcess();
//
// The operation of attaching was successful
@@ -775,9 +790,9 @@ UdDetachProcess(UINT32 TargetPid, UINT64 ProcessDetailToken)
DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS DetachRequest = {0};
//
- // Check if debugger is loaded or not
+ // Check if the VMM module is loaded or not
//
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// Send the continue command to the target process as we
@@ -825,7 +840,7 @@ UdDetachProcess(UINT32 TargetPid, UINT64 ProcessDetailToken)
//
// Remove the current active debugging process (thread)
//
- UdRemoveActiveDebuggingProcess(FALSE);
+ UdRemoveActiveDebuggingProcess();
//
// The operation of attaching was successful
@@ -854,9 +869,9 @@ UdPauseProcess(UINT64 ProcessDebuggingToken)
DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS PauseRequest = {0};
//
- // Check if debugger is loaded or not
+ // Check if the VMM module is loaded or not
//
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// We wanna pause a process
@@ -922,9 +937,9 @@ UdContinueProcess(UINT64 ProcessDebuggingToken)
DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS PauseRequest = {0};
//
- // Check if debugger is loaded or not
+ // Check if the VMM module is loaded or not
//
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// We wanna continue a process
@@ -980,65 +995,243 @@ UdContinueProcess(UINT64 ProcessDebuggingToken)
* @param ProcessDetailToken
* @param ThreadId
* @param ActionType
+ * @param OptionalBuffer
+ * @param OptionalBufferSize
* @param ApplyToAllPausedThreads
+ * @param WaitForEventCompletion
* @param OptionalParam1
* @param OptionalParam2
* @param OptionalParam3
* @param OptionalParam4
*
- * @return VOID
+ * @return BOOLEAN
*/
-VOID
+BOOLEAN
UdSendCommand(UINT64 ProcessDetailToken,
UINT32 ThreadId,
DEBUGGER_UD_COMMAND_ACTION_TYPE ActionType,
+ PVOID OptionalBuffer,
+ UINT32 OptionalBufferSize,
BOOLEAN ApplyToAllPausedThreads,
+ BOOLEAN WaitForEventCompletion,
UINT64 OptionalParam1,
UINT64 OptionalParam2,
UINT64 OptionalParam3,
UINT64 OptionalParam4)
{
- BOOL Status;
- ULONG ReturnedLength;
- DEBUGGER_UD_COMMAND_PACKET CommandPacket;
+ BOOL Status;
+ ULONG ReturnedLength;
+ UINT32 TargetBufferSize = 0;
+ DEBUGGER_UD_COMMAND_PACKET * CommandPacket;
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+
+ //
+ // Calculate the target buffer size
+ //
+ if (OptionalBufferSize == 0)
+ {
+ TargetBufferSize = sizeof(DEBUGGER_UD_COMMAND_PACKET);
+ }
+ else
+ {
+ TargetBufferSize = sizeof(DEBUGGER_UD_COMMAND_PACKET) + OptionalBufferSize;
+ }
+
+ //
+ // Allocate the target buffer
+ //
+ CommandPacket = (DEBUGGER_UD_COMMAND_PACKET *)malloc(TargetBufferSize);
+
+ if (CommandPacket == NULL)
+ {
+ ShowMessages("err, unable to allocate memory for command\n");
+ return FALSE;
+ }
//
// Zero the packet
//
- RtlZeroMemory(&CommandPacket, sizeof(DEBUGGER_UD_COMMAND_PACKET));
+ RtlZeroMemory(CommandPacket, TargetBufferSize);
//
// Set to the details
//
- CommandPacket.ProcessDebuggingDetailToken = ProcessDetailToken;
- CommandPacket.ApplyToAllPausedThreads = ApplyToAllPausedThreads;
- CommandPacket.TargetThreadId = ThreadId;
- CommandPacket.UdAction.ActionType = ActionType;
- CommandPacket.UdAction.OptionalParam1 = OptionalParam1;
- CommandPacket.UdAction.OptionalParam2 = OptionalParam2;
- CommandPacket.UdAction.OptionalParam3 = OptionalParam3;
- CommandPacket.UdAction.OptionalParam4 = OptionalParam4;
+ CommandPacket->ProcessDebuggingDetailToken = ProcessDetailToken;
+ CommandPacket->ApplyToAllPausedThreads = ApplyToAllPausedThreads;
+ CommandPacket->TargetThreadId = ThreadId;
+ CommandPacket->WaitForEventCompletion = WaitForEventCompletion;
+ CommandPacket->UdAction.ActionType = ActionType;
+ CommandPacket->UdAction.OptionalParam1 = OptionalParam1;
+ CommandPacket->UdAction.OptionalParam2 = OptionalParam2;
+ CommandPacket->UdAction.OptionalParam3 = OptionalParam3;
+ CommandPacket->UdAction.OptionalParam4 = OptionalParam4;
+
+ //
+ // Copy the optional buffer if it's present
+ //
+ if (OptionalBuffer != NULL && OptionalBufferSize != 0)
+ {
+ //
+ // Append the optional buffer to the command packet buffer
+ //
+ memcpy((PVOID)((UINT8 *)CommandPacket + sizeof(DEBUGGER_UD_COMMAND_PACKET)), OptionalBuffer, OptionalBufferSize);
+ }
//
// Send IOCTL
//
- Status = DeviceIoControl(g_DeviceHandle, // Handle to device
- IOCTL_SEND_USER_DEBUGGER_COMMANDS, // IO Control Code (IOCTL)
- &CommandPacket, // Input Buffer to driver.
- sizeof(DEBUGGER_UD_COMMAND_PACKET), // Input buffer length
- &CommandPacket, // Output Buffer from driver.
- sizeof(DEBUGGER_UD_COMMAND_PACKET), // Length of output buffer in bytes.
- &ReturnedLength, // Bytes placed in buffer.
- NULL // synchronous call
+ Status = DeviceIoControl(g_DeviceHandle, // Handle to device
+ IOCTL_SEND_USER_DEBUGGER_COMMANDS, // IO Control Code (IOCTL)
+ CommandPacket, // Input Buffer to driver.
+ TargetBufferSize, // Input buffer length
+ CommandPacket, // Output Buffer from driver.
+ TargetBufferSize, // Length of output buffer in bytes.
+ &ReturnedLength, // Bytes placed in buffer.
+ NULL // synchronous call
);
if (!Status)
{
ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
- return;
+
+ free(CommandPacket);
+ return FALSE;
}
+
+ if (CommandPacket->Result != DEBUGGER_OPERATION_WAS_SUCCESSFUL)
+ {
+ ShowErrorMessage((UINT32)CommandPacket->Result);
+
+ free(CommandPacket);
+ return FALSE;
+ }
+
+ //
+ // Copy the result of optional buffer to the caller buffer
+ //
+ if (OptionalBuffer != NULL && OptionalBufferSize != 0)
+ {
+ //
+ // Append the optional buffer to the command packet buffer
+ //
+ memcpy(OptionalBuffer,
+ (PVOID)((UINT8 *)CommandPacket + sizeof(DEBUGGER_UD_COMMAND_PACKET)),
+ OptionalBufferSize);
+ }
+
+ //
+ // Free the allocated buffer
+ //
+ free(CommandPacket);
+
+ return TRUE;
+}
+
+/**
+ * @brief Send the command to the user debugger
+ *
+ * @param ProcessDetailToken
+ * @param TargetThreadId
+ * @param RegDes
+ * @param RegBuffSize
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+UdSendReadRegisterToUserDebugger(UINT64 ProcessDetailToken,
+ UINT32 TargetThreadId,
+ PDEBUGGEE_REGISTER_READ_DESCRIPTION RegDes,
+ UINT32 RegBuffSize)
+
+{
+ //
+ // Send the read register command
+ //
+ return UdSendCommand(ProcessDetailToken,
+ TargetThreadId,
+ DEBUGGER_UD_COMMAND_ACTION_TYPE_READ_REGISTERS,
+ RegDes,
+ RegBuffSize,
+ FALSE,
+ TRUE,
+ RegDes->RegisterId,
+ NULL,
+ NULL,
+ NULL);
+}
+
+/**
+ * @brief Send script buffer to the user debugger
+ *
+ * @param ProcessDetailToken
+ * @param TargetThreadId
+ * @param BufferAddress
+ * @param BufferLength
+ * @param Pointer
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+UdSendScriptBufferToProcess(UINT64 ProcessDetailToken,
+ UINT32 TargetThreadId,
+ UINT64 BufferAddress,
+ UINT32 BufferLength,
+ UINT32 Pointer,
+ BOOLEAN IsFormat)
+
+{
+ PDEBUGGEE_SCRIPT_PACKET ScriptPacket;
+ UINT32 SizeOfStruct = 0;
+ BOOLEAN Result = FALSE;
+
+ SizeOfStruct = sizeof(DEBUGGEE_SCRIPT_PACKET) + BufferLength;
+
+ ScriptPacket = (DEBUGGEE_SCRIPT_PACKET *)malloc(SizeOfStruct);
+
+ RtlZeroMemory(ScriptPacket, SizeOfStruct);
+
+ //
+ // Fill the script packet buffer
+ //
+ ScriptPacket->ScriptBufferSize = BufferLength;
+ ScriptPacket->ScriptBufferPointer = Pointer;
+ ScriptPacket->IsFormat = IsFormat;
+
+ //
+ // Move the buffer at the bottom of the script packet
+ //
+ memcpy((PVOID)((UINT64)ScriptPacket + sizeof(DEBUGGEE_SCRIPT_PACKET)),
+ (PVOID)BufferAddress,
+ BufferLength);
+
+ //
+ // Send the script buffer command
+ //
+ Result = UdSendCommand(ProcessDetailToken,
+ TargetThreadId,
+ DEBUGGER_UD_COMMAND_ACTION_TYPE_EXECUTE_SCRIPT_BUFFER,
+ ScriptPacket,
+ SizeOfStruct,
+ FALSE,
+ TRUE,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+
+ //
+ // Check if it's a format expression and if there was an error or not
+ //
+ if (IsFormat && Result)
+ {
+ g_ErrorStateOfResultOfEvaluatedExpression = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ g_ResultOfEvaluatedExpression = ScriptPacket->FormatValue;
+ }
+
+ free(ScriptPacket);
+
+ return Result;
}
/**
@@ -1047,35 +1240,66 @@ UdSendCommand(UINT64 ProcessDetailToken,
* @param TargetThreadId
* @param StepType
*
- * @return VOID
+ * @return BOOLEAN
*/
-VOID
-UdSendStepPacketToDebuggee(UINT64 ProcessDetailToken, UINT32 TargetThreadId, DEBUGGER_REMOTE_STEPPING_REQUEST StepType)
+BOOLEAN
+UdSendStepPacketToDebuggee(UINT64 ProcessDetailToken,
+ UINT32 TargetThreadId,
+ DEBUGGER_REMOTE_STEPPING_REQUEST StepType)
{
- //
- // Wait until the result of user-input received
- //
- g_UserSyncronizationObjectsHandleTable
- [DEBUGGER_SYNCRONIZATION_OBJECT_USER_DEBUGGER_IS_DEBUGGER_RUNNING]
- .IsOnWaitingState = TRUE;
+ BOOLEAN IsCurrentInstructionACall = FALSE;
+ UINT32 CallInstructionSize = 0;
//
- // Send the 'continue' command
+ // Check for specific stepping type
//
- UdSendCommand(ProcessDetailToken,
- TargetThreadId,
- DEBUGGER_UD_COMMAND_ACTION_TYPE_REGULAR_STEP,
- FALSE,
- StepType,
- NULL,
- NULL,
- NULL);
+ if (StepType == DEBUGGER_REMOTE_STEPPING_REQUEST_STEP_OVER)
+ {
+ //
+ // We should check whether the current instruction is a 'call'
+ // instruction or not, if yes we have to compute the length of call
+ //
+ if (HyperDbgCheckWhetherTheCurrentInstructionIsCall(
+ (UCHAR *)&g_ActiveProcessDebuggingState.InstructionBytesOnRip[0],
+ MAXIMUM_INSTR_SIZE,
+ g_ActiveProcessDebuggingState.Is32Bit ? FALSE : TRUE, // equals to !g_IsRunningInstruction32Bit
+ &CallInstructionSize))
+ {
+ //
+ // It's a call in step-over
+ //
+ IsCurrentInstructionACall = TRUE;
+ CallInstructionSize = CallInstructionSize;
+ }
+ }
- WaitForSingleObject(
- g_UserSyncronizationObjectsHandleTable
- [DEBUGGER_SYNCRONIZATION_OBJECT_USER_DEBUGGER_IS_DEBUGGER_RUNNING]
- .EventHandle,
- INFINITE);
+ //
+ // Send the 'step' command
+ //
+ if (UdSendCommand(ProcessDetailToken,
+ TargetThreadId,
+ DEBUGGER_UD_COMMAND_ACTION_TYPE_REGULAR_STEP,
+ NULL,
+ 0,
+ FALSE,
+ FALSE,
+ StepType,
+ IsCurrentInstructionACall,
+ CallInstructionSize,
+ NULL))
+ {
+ //
+ // Wait until the result of user-input received
+ //
+ DbgWaitForUserResponse(DEBUGGER_SYNCRONIZATION_OBJECT_USER_DEBUGGER_IS_DEBUGGER_RUNNING);
+
+ return TRUE;
+ }
+
+ //
+ // An error happened
+ //
+ return FALSE;
}
/**
@@ -1094,9 +1318,9 @@ UdSetActiveDebuggingThreadByPidOrTid(UINT32 TargetPidOrTid, BOOLEAN IsTid)
DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS SwitchRequest = {0};
//
- // Check if debugger is loaded or not
+ // Check if the VMM module is loaded or not
//
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// We wanna switch to a process or thread
@@ -1120,8 +1344,7 @@ UdSetActiveDebuggingThreadByPidOrTid(UINT32 TargetPidOrTid, BOOLEAN IsTid)
//
Status = DeviceIoControl(
g_DeviceHandle, // Handle to device
- IOCTL_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS, // IO Control
- // code
+ IOCTL_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS, // IO Control code
&SwitchRequest, // Input Buffer to driver.
SIZEOF_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS, // Input buffer length
&SwitchRequest, // Output Buffer from driver.
@@ -1146,10 +1369,12 @@ UdSetActiveDebuggingThreadByPidOrTid(UINT32 TargetPidOrTid, BOOLEAN IsTid)
// Set the current active debugging process (thread)
//
UdSetActiveDebuggingProcess(SwitchRequest.Token,
+ SwitchRequest.Rip,
SwitchRequest.ProcessId,
SwitchRequest.ThreadId,
SwitchRequest.Is32Bit,
- SwitchRequest.IsPaused);
+ SwitchRequest.IsPaused,
+ SwitchRequest.InstructionBytesOnRip);
//
// The operation of attaching was successful
@@ -1179,9 +1404,9 @@ UdShowListActiveDebuggingProcessesAndThreads()
UINT32 SizeOfBufferForThreadsAndProcessDetails = NULL;
//
- // Check if debugger is loaded or not
+ // Check if the VMM module is loaded or not
//
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// Check if user debugger is active or not
@@ -1275,7 +1500,7 @@ UdShowListActiveDebuggingProcessesAndThreads()
//
// Show list of active processes and threads
//
- for (size_t i = 0; i < QueryCountOfActiveThreadsRequest.CountOfActiveDebuggingThreadsAndProcesses; i++)
+ for (SIZE_T i = 0; i < QueryCountOfActiveThreadsRequest.CountOfActiveDebuggingThreadsAndProcesses; i++)
{
if (AddressOfThreadsAndProcessDetails[i].IsProcess)
{
@@ -1298,9 +1523,10 @@ UdShowListActiveDebuggingProcessesAndThreads()
{
CheckCurrentProcessOrThread = TRUE;
}
- ShowMessages("\t%s %04x (thread)\n",
+ ShowMessages("\t%s %04x (thread) | # blkd exec attempts: %llx\n",
CheckCurrentProcessOrThread ? "->" : " ",
- AddressOfThreadsAndProcessDetails[i].ThreadId);
+ AddressOfThreadsAndProcessDetails[i].ThreadId,
+ AddressOfThreadsAndProcessDetails[i].NumberOfBlockedContextSwitches);
}
}
}
diff --git a/hyperdbg/libhyperdbg/code/debugger/user-level/user-listening.cpp b/hyperdbg/libhyperdbg/code/debugger/user-level/user-listening.cpp
index 1d9b5476..bcb78a05 100644
--- a/hyperdbg/libhyperdbg/code/debugger/user-level/user-listening.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/user-level/user-listening.cpp
@@ -28,15 +28,6 @@ extern DEBUGGER_SYNCRONIZATION_EVENTS_STATE
VOID
UdHandleUserDebuggerPausing(PDEBUGGEE_UD_PAUSED_PACKET PausePacket)
{
- //
- // Set the current active debugging process (thread)
- //
- UdSetActiveDebuggingProcess(PausePacket->ProcessDebuggingToken,
- PausePacket->ProcessId,
- PausePacket->ThreadId,
- PausePacket->Is32Bit,
- TRUE);
-
//
// Perform extra tasks for pausing reasons
//
@@ -50,9 +41,9 @@ UdHandleUserDebuggerPausing(PDEBUGGEE_UD_PAUSED_PACKET PausePacket)
break;
case DEBUGGEE_PAUSING_REASON_DEBUGGEE_GENERAL_THREAD_INTERCEPTED:
- ShowMessages("\nthread: %x from process: %x intercepted\n",
- PausePacket->ThreadId,
- PausePacket->ProcessId);
+ // ShowMessages("\nthread: %x from process: %x intercepted\n",
+ // PausePacket->ThreadId,
+ // PausePacket->ProcessId);
break;
@@ -77,31 +68,48 @@ UdHandleUserDebuggerPausing(PDEBUGGEE_UD_PAUSED_PACKET PausePacket)
}
}
- if (!PausePacket->Is32Bit)
+ //
+ // For the first thread that is paused, show the disassembly
+ //
+ if (g_ActiveProcessDebuggingState.IsPaused == FALSE || PausePacket->ThreadId == g_ActiveProcessDebuggingState.ThreadId)
{
//
- // Show diassembles
+ // Set the current active debugging process (thread)
//
- ShowMessages("\n");
- HyperDbgDisassembler64(PausePacket->InstructionBytesOnRip,
- PausePacket->Rip,
- MAXIMUM_INSTR_SIZE,
- 1,
- TRUE,
- (PRFLAGS)&PausePacket->Rflags);
- }
- else
- {
- //
- // Show diassembles
- //
- ShowMessages("\n");
- HyperDbgDisassembler32(PausePacket->InstructionBytesOnRip,
- PausePacket->Rip,
- MAXIMUM_INSTR_SIZE,
- 1,
- TRUE,
- (PRFLAGS)&PausePacket->Rflags);
+ UdSetActiveDebuggingProcess(PausePacket->ProcessDebuggingToken,
+ PausePacket->Rip,
+ PausePacket->ProcessId,
+ PausePacket->ThreadId,
+ PausePacket->Is32Bit,
+ TRUE,
+ &PausePacket->InstructionBytesOnRip[0]);
+
+ if (!PausePacket->Is32Bit)
+ {
+ //
+ // Show diassembles
+ //
+ ShowMessages("\n");
+ HyperDbgDisassembler64(PausePacket->InstructionBytesOnRip,
+ PausePacket->Rip,
+ MAXIMUM_INSTR_SIZE,
+ 1,
+ TRUE,
+ (PRFLAGS)&PausePacket->Rflags);
+ }
+ else
+ {
+ //
+ // Show diassembles
+ //
+ ShowMessages("\n");
+ HyperDbgDisassembler32(PausePacket->InstructionBytesOnRip,
+ PausePacket->Rip,
+ MAXIMUM_INSTR_SIZE,
+ 1,
+ TRUE,
+ (PRFLAGS)&PausePacket->Rflags);
+ }
}
//
diff --git a/hyperdbg/libhyperdbg/code/export/export.cpp b/hyperdbg/libhyperdbg/code/export/export.cpp
index 0786054f..f78f73a5 100644
--- a/hyperdbg/libhyperdbg/code/export/export.cpp
+++ b/hyperdbg/libhyperdbg/code/export/export.cpp
@@ -1,6 +1,7 @@
/**
* @file export.cpp
* @author Sina Karvandi (sina@hyperdbg.org)
+ * @author jtaw5649
* @brief Exported functions from libhyperdbg interface
* @details
* @version 0.10
@@ -53,7 +54,29 @@ hyperdbg_u_load_vmm()
}
/**
- * @brief Unload the VMM
+ * @brief Check if any module is loaded
+ *
+ * @return BOOLEAN Returns true if any module is loaded and false if no module is loaded
+ */
+BOOLEAN
+hyperdbg_u_is_any_module_loaded()
+{
+ return HyperDbgIsAnyModuleLoaded();
+}
+
+/**
+ * @brief Unload all modules
+ *
+ * @return INT Returns 0 if it was successful and 1 if it was failed
+ */
+INT
+hyperdbg_u_unload_all_modules()
+{
+ return HyperDbgUnloadAllModules();
+}
+
+/**
+ * @brief Unload the VMM module
*
* @return INT Returns 0 if it was successful and 1 if it was failed
*/
@@ -64,36 +87,113 @@ hyperdbg_u_unload_vmm()
}
/**
- * @brief Install the VMM driver
+ * @brief Unload the trace module
*
* @return INT Returns 0 if it was successful and 1 if it was failed
*/
INT
-hyperdbg_u_install_vmm_driver()
+hyperdbg_u_unload_hypertrace_module()
{
- return HyperDbgInstallVmmDriver();
+ return HyperDbgUnloadHyperTrace();
}
/**
- * @brief Uninstall the VMM driver
+ * @brief Unload the KD module
*
* @return INT Returns 0 if it was successful and 1 if it was failed
*/
INT
-hyperdbg_u_uninstall_vmm_driver()
+hyperdbg_u_unload_kd()
{
- return HyperDbgUninstallVmmDriver();
+ return HyperDbgUnloadKd();
}
/**
- * @brief Stop the VMM driver
+ * @brief Install the KD driver
*
* @return INT Returns 0 if it was successful and 1 if it was failed
*/
INT
-hyperdbg_u_stop_vmm_driver()
+hyperdbg_u_install_kd_driver()
{
- return HyperDbgStopVmmDriver();
+ return HyperDbgInstallKdDriver();
+}
+
+/**
+ * @brief Uninstall the KD (Kernel Debugger) driver
+ *
+ * @return INT Returns 0 if it was successful and 1 if it was failed
+ */
+INT
+hyperdbg_u_uninstall_kd_driver()
+{
+ return HyperDbgUninstallKdDriver();
+}
+
+/**
+ * @brief Start the KD driver
+ *
+ * @return INT Returns 0 if it was successful and 1 if it was failed
+ */
+INT
+hyperdbg_u_start_kd_driver()
+{
+ return HyperDbgStartKdDriver();
+}
+
+/**
+ * @brief Stop the KD driver
+ *
+ * @return INT Returns 0 if it was successful and 1 if it was failed
+ */
+INT
+hyperdbg_u_stop_kd_driver()
+{
+ return HyperDbgStopKdDriver();
+}
+
+/**
+ * @brief Get the vendor of the current processor
+ *
+ * @return GENERIC_PROCESSOR_VENDOR the vendor of the processor
+ */
+GENERIC_PROCESSOR_VENDOR
+hyperdbg_u_get_processor_vendor()
+{
+ return HyperDbgGetProcessorVendor();
+}
+
+/**
+ * @brief Load the KD module
+ *
+ * @return INT Returns 0 if it was successful and 1 if it was failed
+ */
+INT
+hyperdbg_u_load_kd_module()
+{
+ return HyperDbgLoadKdModule();
+}
+
+/**
+ * @brief Load the hypertrace module
+ *
+ * @return INT Returns 0 if it was successful and 1 if it was failed
+ */
+INT
+hyperdbg_u_load_hypertrace_module()
+{
+ return HyperDbgLoadHyperTraceModule();
+}
+
+/**
+ * @brief Load all modules
+ *
+ * @return INT Returns 0 if it was successful and 1 if it was failed
+ */
+INT
+hyperdbg_u_load_all_modules()
+{
+ return HyperDbgLoadAllModules();
}
/**
@@ -200,7 +300,7 @@ hyperdbg_u_unset_text_message_callback()
INT
hyperdbg_u_script_read_file_and_execute_commandline(INT argc, CHAR * argv[])
{
- return ScriptReadFileAndExecuteCommandline(argc, argv);
+ return HyperDbgScriptReadFileAndExecuteCommandline(argc, argv);
}
/**
@@ -281,14 +381,14 @@ hyperdbg_u_pause_debuggee()
* @param address The address of the breakpoint
* @param pid The process ID of the breakpoint
* @param tid The thread ID of the breakpoint
- * @param core_numer The core number of the breakpoint
+ * @param core_number The core number of the breakpoint
*
* @return BOOLEAN
*/
BOOLEAN
-hyperdbg_u_set_breakpoint(UINT64 address, UINT32 pid, UINT32 tid, UINT32 core_numer)
+hyperdbg_u_set_breakpoint(UINT64 address, UINT32 pid, UINT32 tid, UINT32 core_number)
{
- return CommandBpRequest(address, pid, tid, core_numer);
+ return CommandBpRequest(address, pid, tid, core_number);
}
/**
@@ -726,6 +826,19 @@ hyperdbg_u_get_idt_entry(INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS * idt_packet
return HyperDbgGetIdtEntry(idt_packet);
}
+/**
+ * @brief Perform SMI operation
+ *
+ * @param SmiOperation The SMI operation packet
+ *
+ * @return
+ */
+BOOLEAN
+hyperdbg_u_perform_smi_operation(SMI_OPERATION_PACKETS * SmiOperation)
+{
+ return HyperDbgPerformSmiOperation(SmiOperation);
+}
+
/**
* @brief Run hwdbg script
*
@@ -776,6 +889,21 @@ hyperdbg_u_enable_transparent_mode(UINT32 ProcessId, CHAR * ProcessName, BOOLEAN
return HyperDbgEnableTransparentMode(ProcessId, ProcessName, IsProcessId);
}
+/**
+ * @brief Enable transparent mode with a feature mask
+ * @param ProcessId The process ID to enable transparent mode for
+ * @param ProcessName The process name to enable transparent mode for
+ * @param IsProcessId If true, ProcessId is used, otherwise ProcessName is used
+ * @param EvadeMask The transparent-mode feature mask, or zero for default behavior
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+hyperdbg_u_enable_transparent_mode_ex(UINT32 ProcessId, CHAR * ProcessName, BOOLEAN IsProcessId, UINT32 EvadeMask)
+{
+ return HyperDbgEnableTransparentModeEx(ProcessId, ProcessName, IsProcessId, EvadeMask);
+}
+
/**
* @brief Disable transparent mode
*
@@ -786,3 +914,73 @@ hyperdbg_u_disable_transparent_mode()
{
return HyperDbgDisableTransparentMode();
}
+
+/**
+ * @brief Run HyperDbg scripts in the target process (user debugger) or
+ * debuggee (kernel debugger)
+ * @param Expr The expression to run
+ * @param ShowErrorMessageIfAny If true, show error message if any
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+hyperdbg_u_run_script(CHAR * Expr, BOOLEAN ShowErrorMessageIfAny)
+{
+ return ScriptEngineExecuteSingleExpression(Expr, ShowErrorMessageIfAny, FALSE);
+}
+
+/**
+ * @brief Evaluate expression and return result based on the target
+ * process (user debugger) or debuggee (kernel debugger) context
+ *
+ * @param Expr The expression to evaluate
+ * @param HasError If true, there was an error in evaluation
+ *
+ * @return UINT64 The result of the evaluated expression
+ */
+UINT64
+hyperdbg_u_eval_expression(CHAR * Expr, PBOOLEAN HasError)
+{
+ return ScriptEngineEvalSingleExpression(Expr, HasError);
+}
+
+/**
+ * @brief Dump LBR stack
+ *
+ * @param LbrdumpRequest The LBR dump request packet
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+hyperdbg_u_lbr_dump(HYPERTRACE_LBR_DUMP_PACKETS * LbrdumpRequest)
+{
+ return HyperDbgLbrdumpSendRequest(LbrdumpRequest);
+}
+
+/**
+ * @brief Perform an Intel PT operation (enable / disable / pause / resume /
+ * size / dump / flush / filter)
+ *
+ * @param PtRequest The PT operation request packet
+ *
+ * @return BOOLEAN TRUE if the operation was successful, otherwise FALSE
+ */
+BOOLEAN
+hyperdbg_u_pt_operation(HYPERTRACE_PT_OPERATION_PACKETS * PtRequest)
+{
+ return HyperDbgPerformPtOperation(PtRequest);
+}
+
+/**
+ * @brief Map the per-CPU Intel PT output buffers into the calling process
+ *
+ * @param MmapRequest The PT mmap request packet; filled with per-CPU
+ * { UserVa, Size } on success
+ *
+ * @return BOOLEAN TRUE if the operation was successful, otherwise FALSE
+ */
+BOOLEAN
+hyperdbg_u_pt_mmap(HYPERTRACE_PT_MMAP_PACKETS * MmapRequest)
+{
+ return HyperDbgPtMmapSendRequest(MmapRequest);
+}
diff --git a/hyperdbg/libhyperdbg/code/hwdbg/hwdbg-interpreter.cpp b/hyperdbg/libhyperdbg/code/hwdbg/hwdbg-interpreter.cpp
index 6fd2e1f7..bc074b33 100644
--- a/hyperdbg/libhyperdbg/code/hwdbg/hwdbg-interpreter.cpp
+++ b/hyperdbg/libhyperdbg/code/hwdbg/hwdbg-interpreter.cpp
@@ -117,7 +117,7 @@ HwdbgInterpretPacket(PVOID BufferReceived, UINT32 LengthReceived)
//
// Read port arrangements
//
- for (size_t i = 0; i < g_HwdbgInstanceInfo.numberOfPorts; i++)
+ for (SIZE_T i = 0; i < g_HwdbgInstanceInfo.numberOfPorts; i++)
{
g_HwdbgPortConfiguration.push_back(InstanceInfoPorts[i]);
}
@@ -184,12 +184,12 @@ BOOLEAN
HwdbgInterpreterFillMemoryFromFile(
const TCHAR * FileName,
UINT32 * MemoryBuffer,
- size_t BufferSize)
+ SIZE_T BufferSize)
{
std::ifstream File(FileName);
std::string Line;
BOOLEAN Result = TRUE;
- size_t Index = 0;
+ SIZE_T Index = 0;
if (!File.is_open())
{
@@ -243,7 +243,7 @@ HwdbgInterpreterFillFileFromMemory(
HWDBG_INSTANCE_INFORMATION * InstanceInfo,
const TCHAR * FileName,
UINT32 * MemoryBuffer,
- size_t BufferSize,
+ SIZE_T BufferSize,
HWDBG_ACTION_ENUMS RequestedAction)
{
std::ofstream File(FileName);
@@ -254,8 +254,8 @@ HwdbgInterpreterFillFileFromMemory(
return FALSE;
}
- size_t Address = 0;
- for (size_t I = 0; I < BufferSize / sizeof(UINT32); ++I)
+ SIZE_T Address = 0;
+ for (SIZE_T I = 0; I < BufferSize / sizeof(UINT32); ++I)
{
File << std::hex << std::setw(8) << std::setfill('0') << MemoryBuffer[I];
File << " ; +0x" << std::hex << std::setw(1) << std::setfill('0') << Address;
@@ -347,7 +347,7 @@ HwdbgComputeNumberOfFlipFlopsNeeded(
sizeof(HWDBG_SHORT_SYMBOL) / sizeof(UINT64));
//
- // size of main operator (/ 2 is becasue Type is not inffered)
+ // size of main operator (/ 2 is because Type is not inferred)
//
NumberOfNeededFlipFlopsInTargetDevice += (NumberOfStages * g_HwdbgInstanceInfo.scriptVariableLength * (sizeof(HWDBG_SHORT_SYMBOL) / sizeof(UINT64)) / 2);
@@ -572,7 +572,7 @@ HwdbgShowIntanceInfo(HWDBG_INSTANCE_INFORMATION * InstanceInfo)
* @return BOOLEAN
*/
BOOLEAN
-HwdbgReadInstanceInfoFromFile(const TCHAR * FileName, UINT32 * MemoryBuffer, size_t BufferSize)
+HwdbgReadInstanceInfoFromFile(const TCHAR * FileName, UINT32 * MemoryBuffer, SIZE_T BufferSize)
{
TCHAR TestFilePath[MAX_PATH] = {0};
diff --git a/hyperdbg/libhyperdbg/code/hwdbg/hwdbg-scripts.cpp b/hyperdbg/libhyperdbg/code/hwdbg/hwdbg-scripts.cpp
index 1932d7b9..f905eba3 100644
--- a/hyperdbg/libhyperdbg/code/hwdbg/hwdbg-scripts.cpp
+++ b/hyperdbg/libhyperdbg/code/hwdbg/hwdbg-scripts.cpp
@@ -36,7 +36,7 @@ HwdbgScriptPrintScriptBuffer(CHAR * ScriptBuffer, UINT32 ScriptBufferSize)
ScriptBufferSize * 8 // Converted to bits
);
- for (size_t i = 0; i < ScriptBufferSize; i++)
+ for (SIZE_T i = 0; i < ScriptBufferSize; i++)
{
ShowMessages("%02X ", (UINT8)ScriptBuffer[i]);
}
@@ -60,11 +60,11 @@ HwdbgScriptPrintScriptBuffer(CHAR * ScriptBuffer, UINT32 ScriptBufferSize)
BOOLEAN
HwdbgScriptCompressScriptBuffer(HWDBG_INSTANCE_INFORMATION * InstanceInfo,
SYMBOL * ScriptBuffer,
- size_t ScriptBufferSize,
+ SIZE_T ScriptBufferSize,
UINT32 NumberOfStagesForScript,
HWDBG_SHORT_SYMBOL ** NewScriptBuffer,
- size_t * NewCompressedBufferSize,
- size_t * NumberOfBytesPerChunk)
+ SIZE_T * NewCompressedBufferSize,
+ SIZE_T * NumberOfBytesPerChunk)
{
//
// Now, converting the script based on supported script variable length
@@ -148,12 +148,12 @@ HwdbgScriptCompressScriptBuffer(HWDBG_INSTANCE_INFORMATION * InstanceInfo,
*/
VOID
HwdbgScriptPrintFinalScriptBufferAndHardwareDetails(HWDBG_INSTANCE_INFORMATION * InstanceInfo,
- size_t NewCompressedBufferSize,
+ SIZE_T NewCompressedBufferSize,
UINT32 NumberOfStagesForScript,
UINT32 NumberOfOperandsForScript,
HWDBG_SHORT_SYMBOL * NewScriptBuffer,
- size_t NumberOfNeededFlipFlopsInTargetDevice,
- size_t NumberOfBytesPerChunk,
+ SIZE_T NumberOfNeededFlipFlopsInTargetDevice,
+ SIZE_T NumberOfBytesPerChunk,
UINT32 NumberOfOperandsImplemented)
{
ShowMessages("\n---------------------------------------------------------\n");
@@ -169,7 +169,7 @@ HwdbgScriptPrintFinalScriptBufferAndHardwareDetails(HWDBG_INSTANCE_INFORMATION *
NumberOfNeededFlipFlopsInTargetDevice,
NumberOfBytesPerChunk);
- for (size_t i = 0; i < NewCompressedBufferSize; i++)
+ for (SIZE_T i = 0; i < NewCompressedBufferSize; i++)
{
ShowMessages("%02X ", (UINT8)((CHAR *)NewScriptBuffer)[i]);
}
@@ -193,7 +193,7 @@ HwdbgScriptWriteScriptConfigurationPacketIntoFile(HWDBG_INSTANCE_INFORMATION * I
UINT32 NumberOfStagesForScript,
UINT32 NumberOfOperandsImplemented,
HWDBG_SHORT_SYMBOL * NewScriptBuffer,
- size_t NewCompressedBufferSize)
+ SIZE_T NewCompressedBufferSize)
{
TCHAR TestFilePath[MAX_PATH] = {0};
@@ -237,9 +237,9 @@ HwdbgScriptCreateHwdbgScript(CHAR * ScriptBuffer,
UINT32 NumberOfStagesForScript = 0;
UINT32 NumberOfOperandsImplemented = 0;
UINT32 NumberOfOperandsForScript = 0;
- size_t NewCompressedBufferSize = 0;
- size_t NumberOfNeededFlipFlopsInTargetDevice = 0;
- size_t NumberOfBytesPerChunk = 0;
+ SIZE_T NewCompressedBufferSize = 0;
+ SIZE_T NumberOfNeededFlipFlopsInTargetDevice = 0;
+ SIZE_T NumberOfBytesPerChunk = 0;
HWDBG_SHORT_SYMBOL * NewScriptBuffer = NULL;
//
@@ -344,7 +344,7 @@ HwdbgScriptGetScriptBufferFromRawString(string ScriptString,
//
// Run script engine handler
//
- ResultingCodeBuffer = ScriptEngineParseWrapper((char *)ScriptString.c_str(), TRUE);
+ ResultingCodeBuffer = ScriptEngineParseWrapper((CHAR *)ScriptString.c_str(), TRUE);
if (ResultingCodeBuffer == NULL)
{
diff --git a/hyperdbg/libhyperdbg/code/objects/objects.cpp b/hyperdbg/libhyperdbg/code/objects/objects.cpp
index f63707ac..a0fe54ce 100644
--- a/hyperdbg/libhyperdbg/code/objects/objects.cpp
+++ b/hyperdbg/libhyperdbg/code/objects/objects.cpp
@@ -14,7 +14,7 @@
//
// Global Variables
//
-extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+extern BOOLEAN g_IsKdModuleLoaded;
/**
* @brief Get details about processes or threads
@@ -149,9 +149,9 @@ ObjectShowProcessesOrThreadList(BOOLEAN IsProcess,
PDEBUGGEE_THREAD_LIST_DETAILS_ENTRY ThreadEntries = NULL;
//
- // Check if driver is loaded
+ // Check if the debugger module is loaded
//
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// We wanna query the count of active processes or threads
@@ -302,7 +302,7 @@ ObjectShowProcessesOrThreadList(BOOLEAN IsProcess,
//
// Show list of active processes and threads
//
- for (size_t i = 0; i < QueryCountOfActiveThreadsOrProcessesRequest.Count; i++)
+ for (SIZE_T i = 0; i < QueryCountOfActiveThreadsOrProcessesRequest.Count; i++)
{
//
// Details of process/thread should be shown
diff --git a/hyperdbg/libhyperdbg/code/rev/rev-ctrl.cpp b/hyperdbg/libhyperdbg/code/rev/rev-ctrl.cpp
index 1d965fc4..4a21a2dc 100644
--- a/hyperdbg/libhyperdbg/code/rev/rev-ctrl.cpp
+++ b/hyperdbg/libhyperdbg/code/rev/rev-ctrl.cpp
@@ -12,6 +12,11 @@
*/
#include "pch.h"
+//
+// Global Variables
+//
+extern BOOLEAN g_IsVmmModuleLoaded;
+
/**
* @brief Request service from the reversing machine
*
@@ -28,7 +33,7 @@ RevRequestService(REVERSING_MACHINE_RECONSTRUCT_MEMORY_REQUEST * RevRequest)
//
// Check if debugger is loaded or not
//
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// Send the request to the kernel
diff --git a/hyperdbg/libhyperdbg/header/libhyperdbg.h b/hyperdbg/libhyperdbg/header/app/libhyperdbg.h
similarity index 64%
rename from hyperdbg/libhyperdbg/header/libhyperdbg.h
rename to hyperdbg/libhyperdbg/header/app/libhyperdbg.h
index 3e18f7cb..ca3dce77 100644
--- a/hyperdbg/libhyperdbg/header/libhyperdbg.h
+++ b/hyperdbg/libhyperdbg/header/app/libhyperdbg.h
@@ -15,27 +15,57 @@
// Functions //
//////////////////////////////////////////////////
+BOOLEAN
+HyperDbgIsAnyModuleLoaded();
+
INT
-HyperDbgCreateHandleFromVmmModule();
+HyperDbgUnloadAllModules();
+
+INT
+HyperDbgInitHyperTraceModule();
INT
HyperDbgUnloadVmm();
INT
-HyperDbgInstallVmmDriver();
+HyperDbgUnloadHyperTrace();
INT
-HyperDbgUninstallVmmDriver();
+HyperDbgUnloadKd();
+
+INT
+HyperDbgInstallKdDriver();
+
+INT
+HyperDbgUninstallKdDriver();
+
+INT
+HyperDbgLoadKdModule();
INT
HyperDbgLoadVmmModule();
INT
-HyperDbgStopVmmDriver();
+HyperDbgLoadHyperTraceModule();
+
+INT
+HyperDbgLoadAllModules();
+
+INT
+HyperDbgStartKdDriver();
+
+INT
+HyperDbgStopKdDriver();
INT
HyperDbgInterpreter(CHAR * Command);
+INT
+HyperDbgScriptReadFileAndExecuteCommandline(INT argc, CHAR * argv[]);
+
+GENERIC_PROCESSOR_VENDOR
+HyperDbgGetProcessorVendor();
+
BOOLEAN
HyperDbgTestCommandParser(CHAR * Command,
UINT32 NumberOfTokens,
@@ -46,20 +76,5 @@ HyperDbgTestCommandParser(CHAR * Command,
VOID
HyperDbgTestCommandParserShowTokens(CHAR * Command);
-INT
-ScriptReadFileAndExecuteCommandline(INT argc, CHAR * argv[]);
-
VOID
HyperDbgShowSignature();
-
-VOID
-SetTextMessageCallback(PVOID Handler);
-
-PVOID
-SetTextMessageCallbackUsingSharedBuffer(PVOID Handler);
-
-VOID
-UnsetTextMessageCallback();
-
-BOOLEAN
-SetDebugPrivilege();
diff --git a/hyperdbg/libhyperdbg/header/app/messaging.h b/hyperdbg/libhyperdbg/header/app/messaging.h
new file mode 100644
index 00000000..db804888
--- /dev/null
+++ b/hyperdbg/libhyperdbg/header/app/messaging.h
@@ -0,0 +1,25 @@
+/**
+ * @file messaging.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief headers for messaging functions
+ * @details
+ * @version 0.19
+ * @date 2026-05-28
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+VOID
+SetTextMessageCallback(PVOID Handler);
+
+PVOID
+SetTextMessageCallbackUsingSharedBuffer(PVOID Handler);
+
+VOID
+UnsetTextMessageCallback();
diff --git a/hyperdbg/libhyperdbg/header/app/packets.h b/hyperdbg/libhyperdbg/header/app/packets.h
new file mode 100644
index 00000000..98015021
--- /dev/null
+++ b/hyperdbg/libhyperdbg/header/app/packets.h
@@ -0,0 +1,22 @@
+/**
+ * @file packets.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief headers for kernel packet functions
+ * @details
+ * @version 0.19
+ * @date 2026-05-28
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+VOID
+ReadIrpBasedBuffer();
+
+DWORD WINAPI
+IrpBasedBufferThread(void * data);
diff --git a/hyperdbg/libhyperdbg/header/common.h b/hyperdbg/libhyperdbg/header/common.h
deleted file mode 100644
index be7c47e7..00000000
--- a/hyperdbg/libhyperdbg/header/common.h
+++ /dev/null
@@ -1,223 +0,0 @@
-/**
- * @file common.h
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief header for HyperDbg's general functions for reading and converting and
- * etc
- * @details
- * @version 0.1
- * @date 2020-05-27
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#pragma once
-
-//////////////////////////////////////////////////
-// Definitions //
-//////////////////////////////////////////////////
-
-#define AssertReturn return;
-
-#define AssertReturnFalse return FALSE;
-
-#define AssertReturnOne return 1;
-
-#define PAUSE_MESSAGE_IN_USER_DEBUGGER "\nTo pause the target process, run the 'pause' command"
-
-#define ASSERT_MESSAGE_DRIVER_NOT_LOADED "handle of the driver not found, probably the driver is not loaded. Did you use 'load' command?\n"
-
-#define ASSERT_MESSAGE_BUILD_SIGNATURE_DOESNT_MATCH "the handshaking process was successful; however, there is a mismatch between " \
- "the version/build of the debuggee and the debugger. please use the same " \
- "version/build for both the debuggee and debugger\n"
-
-#define ASSERT_MESSAGE_CANNOT_SPECIFY_PID "err, since HyperDbg won't context-switch to keep the system in a halted state, " \
- "you cannot specify 'pid' for this command in the debugger mode. You can switch to the target process " \
- "memory layout using the '.process' or the '.thread' command. After that, you can use " \
- "this command without specifying the process ID. Alternatively, you can modify the current " \
- "CR3 register to achieve the same functionality\n"
-
-#define AssertReturnStmt(expr, stmt, rc) \
- do \
- { \
- if (expr) \
- { \
- /* likely */ \
- } \
- else \
- { \
- stmt; \
- rc; \
- } \
- } while (0)
-
-#define AssertShowMessageReturnStmt(expr, message, rc) \
- do \
- { \
- if (expr) \
- { \
- /* likely */ \
- } \
- else \
- { \
- ShowMessages(message); \
- rc; \
- } \
- } while (0)
-
-/**
- * @brief Size of each page (4096 bytes)
- *
- */
-#define PAGE_SIZE 0x1000
-
-/**
- * @brief Aligning a page
- *
- */
-#define PAGE_ALIGN(Va) ((PVOID)((ULONG_PTR)(Va) & ~(PAGE_SIZE - 1)))
-
-/**
- * @brief Cpuid to get virtual address width
- *
- */
-#define CPUID_ADDR_WIDTH 0x80000008
-
-//////////////////////////////////////////////////
-// Assembly Functions //
-//////////////////////////////////////////////////
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern bool
-AsmVmxSupportDetection();
-
-#ifdef __cplusplus
-}
-#endif
-
-//////////////////////////////////////////////////
-// Spinlocks //
-//////////////////////////////////////////////////
-
-void
-SpinlockLock(volatile LONG * Lock);
-
-void
-SpinlockLockWithCustomWait(volatile LONG * Lock, unsigned MaximumWait);
-
-void
-SpinlockUnlock(volatile LONG * Lock);
-
-//////////////////////////////////////////////////
-// Functions //
-//////////////////////////////////////////////////
-
-VOID
-PrintBits(const UINT32 size, const void * ptr);
-
-BOOL
-Replace(std::string & str, const std::string & from, const std::string & to);
-
-VOID
-ReplaceAll(string & str, const string & from, const string & to);
-
-const vector
-Split(const string & s, const char & c);
-
-BOOLEAN
-IsNumber(const string & str);
-
-UINT32
-Log2Ceil(UINT32 n);
-
-BOOLEAN
-IsHexNotation(const string & s);
-
-vector
-HexToBytes(const string & hex);
-
-BOOLEAN
-ConvertStringToUInt64(string TextToConvert, PUINT64 Result);
-
-BOOLEAN
-ConvertStringToUInt32(string TextToConvert, PUINT32 Result);
-
-BOOLEAN
-ConvertTokenToUInt64(CommandToken TargetToken, PUINT64 Result);
-
-BOOLEAN
-ConvertTokenToUInt32(CommandToken TargetToken, PUINT32 Result);
-
-std::string
-GetCaseSensitiveStringFromCommandToken(CommandToken TargetToken);
-
-std::string
-GetLowerStringFromCommandToken(CommandToken TargetToken);
-
-BOOLEAN
-CompareLowerCaseStrings(CommandToken TargetToken, const char * StringToCompare);
-
-BOOLEAN
-IsTokenBracketString(CommandToken TargetToken);
-
-BOOLEAN
-HasEnding(string const & fullString, string const & ending);
-
-BOOLEAN
-ValidateIP(const string & ip);
-
-BOOL
-SetPrivilege(HANDLE Token, // access token handle
- LPCTSTR Privilege, // name of privilege to enable/disable
- BOOL EnablePrivilege // to enable or disable privilege
-);
-
-void
-Trim(std::string & s);
-
-std::string
-RemoveSpaces(std::string str);
-
-BOOLEAN
-IsFileExistA(const char * FileName);
-
-BOOLEAN
-IsFileExistW(const wchar_t * FileName);
-
-VOID
-GetConfigFilePath(PWCHAR ConfigPath);
-
-VOID
-StringToWString(std::wstring & ws, const std::string & s);
-
-size_t
-FindCaseInsensitive(std::string Input, std::string ToSearch, size_t Pos);
-
-size_t
-FindCaseInsensitiveW(std::wstring Input, std::wstring ToSearch, size_t Pos);
-
-char *
-ConvertStringVectorToCharPointerArray(const std::string & s);
-
-std::vector
-ListDirectory(const std::string & Directory, const std::string & Extension);
-
-BOOLEAN
-IsEmptyString(char * Text);
-
-VOID
-CommonCpuidInstruction(UINT32 Func, UINT32 SubFunc, int * CpuInfo);
-
-BOOLEAN
-CheckCpuSupportRtm();
-
-UINT32
-Getx86VirtualAddressWidth();
-
-BOOLEAN
-CheckAccessValidityAndSafety(UINT64 TargetAddress, UINT32 Size);
-
-BOOLEAN
-VmxSupportDetection();
diff --git a/hyperdbg/libhyperdbg/header/common/common.h b/hyperdbg/libhyperdbg/header/common/common.h
new file mode 100644
index 00000000..bdf2a82b
--- /dev/null
+++ b/hyperdbg/libhyperdbg/header/common/common.h
@@ -0,0 +1,326 @@
+/**
+ * @file common.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief header for HyperDbg's general functions for reading and converting and
+ * etc
+ * @details
+ * @version 0.1
+ * @date 2020-05-27
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Definitions //
+//////////////////////////////////////////////////
+
+#define AssertReturn return;
+
+#define AssertReturnFalse return FALSE;
+
+#define AssertReturnOne return 1;
+
+#define PAUSE_MESSAGE_IN_USER_DEBUGGER "\nTo pause the target process, run the 'pause' command"
+
+#define ASSERT_MESSAGE_DRIVER_NOT_LOADED "handle of the driver not found, probably the driver is not loaded. Did you use 'load' command?\n"
+
+#define ASSERT_MESSAGE_KD_NOT_LOADED "the kd (kernel debugger) module is not loaded. Did you use 'load kd' command?\n"
+
+#define ASSERT_MESSAGE_VMM_NOT_LOADED "the vmm (virtualization) module is not loaded. Did you use 'load vmm' command?\n"
+
+#define ASSERT_MESSAGE_HYPERTRACE_NOT_LOADED "the trace (hypertrace) module is not loaded. Did you use 'load trace' command?\n"
+
+#define ASSERT_MESSAGE_BUILD_SIGNATURE_DOESNT_MATCH "the handshaking process was successful; however, there is a mismatch between " \
+ "the version/build of the debuggee and the debugger. please use the same " \
+ "version/build for both the debuggee and debugger\n"
+
+#define ASSERT_MESSAGE_CANNOT_SPECIFY_PID "err, since HyperDbg won't context-switch to keep the system in a halted state, " \
+ "you cannot specify 'pid' for this command in the debugger mode. You can switch to the target process " \
+ "memory layout using the '.process' or the '.thread' command. After that, you can use " \
+ "this command without specifying the process ID. Alternatively, you can modify the current " \
+ "CR3 register to achieve the same functionality\n"
+
+#define AssertReturnStmt(expr, stmt, rc) \
+ do \
+ { \
+ if (expr) \
+ { \
+ /* likely */ \
+ } \
+ else \
+ { \
+ stmt; \
+ rc; \
+ } \
+ } while (0)
+
+#define AssertShowMessageReturnStmt(expr1, expr2, message1, message2, rc) \
+ do \
+ { \
+ if (expr1 && expr2) \
+ { \
+ /* likely */ \
+ } \
+ else \
+ { \
+ if (!expr1) \
+ ShowMessages(message1); \
+ else if (!expr2) \
+ ShowMessages(message2); \
+ rc; \
+ } \
+ } while (0)
+
+/**
+ * @brief Size of each page (4096 bytes)
+ *
+ */
+#define PAGE_SIZE 0x1000
+
+/**
+ * @brief Aligning a page
+ *
+ */
+#define PAGE_ALIGN(Va) ((PVOID)((ULONG_PTR)(Va) & ~(PAGE_SIZE - 1)))
+
+/**
+ * @brief Cpuid to get virtual address width
+ *
+ */
+#define CPUID_ADDR_WIDTH 0x80000008
+
+//////////////////////////////////////////////////
+// Kernel & User Synchronization //
+//////////////////////////////////////////////////
+
+#define DbgWaitForKernelResponse(KernelSyncObjectId) \
+ do \
+ { \
+ DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
+ &g_KernelSyncronizationObjectsHandleTable[KernelSyncObjectId]; \
+ \
+ SyncronizationObject->IsOnWaitingState = TRUE; \
+ PlatformWaitForSingleObject(SyncronizationObject->EventHandle, INFINITE); \
+ \
+ } while (FALSE);
+
+#define DbgWaitForUserResponse(UserSyncObjectId) \
+ do \
+ { \
+ DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
+ &g_UserSyncronizationObjectsHandleTable[UserSyncObjectId]; \
+ \
+ SyncronizationObject->IsOnWaitingState = TRUE; \
+ PlatformWaitForSingleObject(SyncronizationObject->EventHandle, INFINITE); \
+ \
+ } while (FALSE);
+
+#define DbgWaitSetKernelRequestData(KernelSyncObjectId, ReqData, ReqSize) \
+ do \
+ { \
+ DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
+ &g_KernelSyncronizationObjectsHandleTable[KernelSyncObjectId]; \
+ \
+ SyncronizationObject->RequestData = (PVOID)ReqData; \
+ SyncronizationObject->RequestSize = (UINT32)ReqSize; \
+ \
+ } while (FALSE);
+
+#define DbgWaitSetUserRequestData(UserSyncObjectId, ReqData, ReqSize) \
+ do \
+ { \
+ DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
+ &g_UserSyncronizationObjectsHandleTable[UserSyncObjectId]; \
+ \
+ SyncronizationObject->RequestData = (PVOID)ReqData; \
+ SyncronizationObject->RequestSize = (UINT32)ReqSize; \
+ \
+ } while (FALSE);
+
+#define DbgWaitGetKernelRequestData(KernelSyncObjectId, ReqData, ReqSize) \
+ do \
+ { \
+ DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
+ &g_KernelSyncronizationObjectsHandleTable[KernelSyncObjectId]; \
+ \
+ *ReqData = SyncronizationObject->RequestData; \
+ *ReqSize = SyncronizationObject->RequestSize; \
+ SyncronizationObject->RequestData = NULL; \
+ SyncronizationObject->RequestSize = NULL_ZERO; \
+ \
+ } while (FALSE);
+
+#define DbgWaitGetUserRequestData(UserSyncObjectId, ReqData, ReqSize) \
+ do \
+ { \
+ DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
+ &g_UserSyncronizationObjectsHandleTable[UserSyncObjectId]; \
+ \
+ *ReqData = SyncronizationObject->RequestData; \
+ *ReqSize = SyncronizationObject->RequestSize; \
+ SyncronizationObject->RequestData = NULL; \
+ SyncronizationObject->RequestSize = NULL_ZERO; \
+ \
+ } while (FALSE);
+
+#define DbgReceivedKernelResponse(KernelSyncObjectId) \
+ do \
+ { \
+ DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
+ &g_KernelSyncronizationObjectsHandleTable[KernelSyncObjectId]; \
+ \
+ SyncronizationObject->IsOnWaitingState = FALSE; \
+ SetEvent(SyncronizationObject->EventHandle); \
+ } while (FALSE);
+
+#define DbgReceivedUserResponse(UserSyncObjectId) \
+ do \
+ { \
+ DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
+ &g_UserSyncronizationObjectsHandleTable[UserSyncObjectId]; \
+ \
+ SyncronizationObject->IsOnWaitingState = FALSE; \
+ SetEvent(SyncronizationObject->EventHandle); \
+ } while (FALSE);
+
+//////////////////////////////////////////////////
+// Assembly Functions //
+//////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern BOOLEAN
+AsmVmxSupportDetection();
+
+#ifdef __cplusplus
+}
+#endif
+
+//////////////////////////////////////////////////
+// Spinlocks //
+//////////////////////////////////////////////////
+
+VOID
+SpinlockLock(volatile LONG * Lock);
+
+VOID
+SpinlockLockWithCustomWait(volatile LONG * Lock, UINT32 MaximumWait);
+
+VOID
+SpinlockUnlock(volatile LONG * Lock);
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+VOID
+PrintBits(const UINT32 size, const VOID * ptr);
+
+BOOL
+Replace(std::string & str, const std::string & from, const std::string & to);
+
+VOID
+ReplaceAll(string & str, const string & from, const string & to);
+
+const vector
+Split(const string & s, const CHAR & c);
+
+BOOLEAN
+IsNumber(const string & str);
+
+UINT32
+Log2Ceil(UINT32 n);
+
+BOOLEAN
+IsHexNotation(const string & s);
+
+vector
+HexToBytes(const string & hex);
+
+BOOLEAN
+ConvertStringToUInt64(string TextToConvert, PUINT64 Result);
+
+BOOLEAN
+ConvertStringToUInt32(string TextToConvert, PUINT32 Result);
+
+BOOLEAN
+ConvertTokenToUInt64(CommandToken TargetToken, PUINT64 Result);
+
+BOOLEAN
+ConvertTokenToUInt32(CommandToken TargetToken, PUINT32 Result);
+
+std::string
+GetCaseSensitiveStringFromCommandToken(CommandToken TargetToken);
+
+std::string
+GetLowerStringFromCommandToken(CommandToken TargetToken);
+
+BOOLEAN
+CompareLowerCaseStrings(CommandToken TargetToken, const CHAR * StringToCompare);
+
+BOOLEAN
+IsTokenBracketString(CommandToken TargetToken);
+
+BOOLEAN
+HasEnding(string const & fullString, string const & ending);
+
+BOOLEAN
+ValidateIP(const string & ip);
+
+BOOL
+SetPrivilege(HANDLE Token, // access token handle
+ LPCTSTR Privilege, // name of privilege to enable/disable
+ BOOL EnablePrivilege // to enable or disable privilege
+);
+
+VOID
+Trim(std::string & s);
+
+std::string
+RemoveSpaces(std::string str);
+
+BOOLEAN
+IsFileExistA(const CHAR * FileName);
+
+BOOLEAN
+IsFileExistW(const WCHAR * FileName);
+
+VOID
+GetConfigFilePath(PWCHAR ConfigPath);
+
+VOID
+StringToWString(std::wstring & ws, const std::string & s);
+
+SIZE_T
+FindCaseInsensitive(std::string Input, std::string ToSearch, SIZE_T Pos);
+
+SIZE_T
+FindCaseInsensitiveW(std::wstring Input, std::wstring ToSearch, SIZE_T Pos);
+
+CHAR *
+ConvertStringVectorToCharPointerArray(const std::string & s);
+
+std::vector
+ListDirectory(const std::string & Directory, const std::string & Extension);
+
+BOOLEAN
+IsEmptyString(CHAR * Text);
+
+VOID
+CommonCpuidInstruction(UINT32 Func, UINT32 SubFunc, INT * CpuInfo);
+
+BOOLEAN
+CheckCpuSupportRtm();
+
+UINT32
+Getx86VirtualAddressWidth();
+
+BOOLEAN
+CheckAccessValidityAndSafety(UINT64 TargetAddress, UINT32 Size);
+
+BOOLEAN
+VmxSupportDetection();
diff --git a/hyperdbg/libhyperdbg/header/list.h b/hyperdbg/libhyperdbg/header/common/list.h
similarity index 100%
rename from hyperdbg/libhyperdbg/header/list.h
rename to hyperdbg/libhyperdbg/header/common/list.h
diff --git a/hyperdbg/libhyperdbg/header/commands.h b/hyperdbg/libhyperdbg/header/debugger/commands/commands.h
similarity index 89%
rename from hyperdbg/libhyperdbg/header/commands.h
rename to hyperdbg/libhyperdbg/header/debugger/commands/commands.h
index 23bbb3f3..9e24fec9 100644
--- a/hyperdbg/libhyperdbg/header/commands.h
+++ b/hyperdbg/libhyperdbg/header/debugger/commands/commands.h
@@ -40,84 +40,84 @@ CommandSettingsGetValueFromConfigFile(std::string OptionName, std::string & Opti
VOID
CpuReadVendorString(CHAR * Result);
-int
+INT
ReadCpuDetails();
VOID
-ShowMessages(const char * Fmt, ...);
+ShowMessages(const CHAR * Fmt, ...);
string
SeparateTo64BitValue(UINT64 Value);
-void
-ShowMemoryCommandDB(unsigned char * OutputBuffer, UINT32 Size, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, UINT64 Length);
+VOID
+ShowMemoryCommandDB(UCHAR * OutputBuffer, UINT32 Size, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, UINT64 Length);
-void
-ShowMemoryCommandDD(unsigned char * OutputBuffer, UINT32 Size, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, UINT64 Length);
+VOID
+ShowMemoryCommandDD(UCHAR * OutputBuffer, UINT32 Size, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, UINT64 Length);
-void
-ShowMemoryCommandDC(unsigned char * OutputBuffer, UINT32 Size, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, UINT64 Length);
+VOID
+ShowMemoryCommandDC(UCHAR * OutputBuffer, UINT32 Size, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, UINT64 Length);
-void
-ShowMemoryCommandDQ(unsigned char * OutputBuffer, UINT32 Size, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, UINT64 Length);
+VOID
+ShowMemoryCommandDQ(UCHAR * OutputBuffer, UINT32 Size, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, UINT64 Length);
VOID
CommandPteShowResults(UINT64 TargetVa, PDEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS PteRead);
DEBUGGER_CONDITIONAL_JUMP_STATUS
-HyperDbgIsConditionalJumpTaken(unsigned char * BufferToDisassemble,
- UINT64 BuffLength,
- RFLAGS Rflags,
- BOOLEAN Isx86_64);
+HyperDbgIsConditionalJumpTaken(UCHAR * BufferToDisassemble,
+ UINT64 BuffLength,
+ RFLAGS Rflags,
+ BOOLEAN Isx86_64);
-int
-HyperDbgDisassembler64(unsigned char * BufferToDisassemble,
- UINT64 BaseAddress,
- UINT64 Size,
- UINT32 MaximumInstrDecoded,
- BOOLEAN ShowBranchIsTakenOrNot,
- PRFLAGS Rflags);
+INT
+HyperDbgDisassembler64(UCHAR * BufferToDisassemble,
+ UINT64 BaseAddress,
+ UINT64 Size,
+ UINT32 MaximumInstrDecoded,
+ BOOLEAN ShowBranchIsTakenOrNot,
+ PRFLAGS Rflags);
-int
-HyperDbgDisassembler32(unsigned char * BufferToDisassemble,
- UINT64 BaseAddress,
- UINT64 Size,
- UINT32 MaximumInstrDecoded,
- BOOLEAN ShowBranchIsTakenOrNot,
- PRFLAGS Rflags);
+INT
+HyperDbgDisassembler32(UCHAR * BufferToDisassemble,
+ UINT64 BaseAddress,
+ UINT64 Size,
+ UINT32 MaximumInstrDecoded,
+ BOOLEAN ShowBranchIsTakenOrNot,
+ PRFLAGS Rflags);
UINT32
HyperDbgLengthDisassemblerEngine(
- unsigned char * BufferToDisassemble,
- UINT64 BuffLength,
- BOOLEAN Isx86_64);
+ UCHAR * BufferToDisassemble,
+ UINT64 BuffLength,
+ BOOLEAN Isx86_64);
BOOLEAN
HyperDbgCheckWhetherTheCurrentInstructionIsCall(
- unsigned char * BufferToDisassemble,
- UINT64 BuffLength,
- BOOLEAN Isx86_64,
- PUINT32 CallLength);
+ UCHAR * BufferToDisassemble,
+ UINT64 BuffLength,
+ BOOLEAN Isx86_64,
+ PUINT32 CallLength);
BOOLEAN
HyperDbgCheckWhetherTheCurrentInstructionIsCallOrRet(
- unsigned char * BufferToDisassemble,
- UINT64 CurrentRip,
- UINT32 BuffLength,
- BOOLEAN Isx86_64,
- PBOOLEAN IsRet);
+ UCHAR * BufferToDisassemble,
+ UINT64 CurrentRip,
+ UINT32 BuffLength,
+ BOOLEAN Isx86_64,
+ PBOOLEAN IsRet);
BOOLEAN
HyperDbgCheckWhetherTheCurrentInstructionIsRet(
- unsigned char * BufferToDisassemble,
- UINT64 BuffLength,
- BOOLEAN Isx86_64);
+ UCHAR * BufferToDisassemble,
+ UINT64 BuffLength,
+ BOOLEAN Isx86_64);
UINT32
HyperDbgGetImmediateValueOnEaxForSyscallNumber(
- unsigned char * BufferToDisassemble,
- UINT64 BuffLength,
- BOOLEAN Isx86_64);
+ UCHAR * BufferToDisassemble,
+ UINT64 BuffLength,
+ BOOLEAN Isx86_64);
VOID
HyperDbgShowMemoryOrDisassemble(DEBUGGER_SHOW_MEMORY_STYLE Style,
@@ -348,6 +348,8 @@ typedef std::map CommandType;
#define DEBUGGER_COMMAND_CPUID_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
+#define DEBUGGER_COMMAND_XSETBV_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
+
#define DEBUGGER_COMMAND_MSRREAD_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
#define DEBUGGER_COMMAND_MSRWRITE_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
@@ -472,6 +474,18 @@ typedef std::map CommandType;
#define DEBUGGER_COMMAND_IDT_ATTRIBUTES \
DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
+#define DEBUGGER_COMMAND_SMI_ATTRIBUTES \
+ DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
+
+#define DEBUGGER_COMMAND_LBR_ATTRIBUTES \
+ NULL
+
+#define DEBUGGER_COMMAND_LBRDUMP_ATTRIBUTES \
+ DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
+
+#define DEBUGGER_COMMAND_PT_ATTRIBUTES \
+ NULL
+
//////////////////////////////////////////////////
// Command Functions //
//////////////////////////////////////////////////
@@ -755,6 +769,18 @@ CommandPcicam(vector CommandTokens, string Command);
VOID
CommandIdt(vector CommandTokens, string Command);
+VOID
+CommandSmi(vector CommandTokens, string Command);
+
+VOID
+CommandLbr(vector CommandTokens, string Command);
+
+VOID
+CommandLbrdump(vector CommandTokens, string Command);
+
+VOID
+CommandPt(vector CommandTokens, string Command);
+
//
// hwdbg commands
//
@@ -763,3 +789,9 @@ CommandHwClk(vector CommandTokens, string Command);
VOID
CommandHw(vector CommandTokens, string Command);
+
+VOID
+CommandXsetbv(vector CommandTokens, string Command);
+
+VOID
+CommandXsetbvHelp();
diff --git a/hyperdbg/libhyperdbg/header/help.h b/hyperdbg/libhyperdbg/header/debugger/commands/help.h
similarity index 96%
rename from hyperdbg/libhyperdbg/header/help.h
rename to hyperdbg/libhyperdbg/header/debugger/commands/help.h
index ae1bb603..70340e54 100644
--- a/hyperdbg/libhyperdbg/header/help.h
+++ b/hyperdbg/libhyperdbg/header/debugger/commands/help.h
@@ -306,6 +306,18 @@ CommandPcicamHelp();
VOID
CommandIdtHelp();
+VOID
+CommandSmiHelp();
+
+VOID
+CommandLbrHelp();
+
+VOID
+CommandLbrdumpHelp();
+
+VOID
+CommandPtHelp();
+
//
// hwdbg commands
//
diff --git a/hyperdbg/libhyperdbg/header/communication.h b/hyperdbg/libhyperdbg/header/debugger/communication/communication.h
similarity index 79%
rename from hyperdbg/libhyperdbg/header/communication.h
rename to hyperdbg/libhyperdbg/header/debugger/communication/communication.h
index f53325b4..c33e377f 100644
--- a/hyperdbg/libhyperdbg/header/communication.h
+++ b/hyperdbg/libhyperdbg/header/debugger/communication/communication.h
@@ -29,13 +29,13 @@ CommunicationServerCreateServerAndWaitForClient(PCSTR Port,
SOCKET * ClientSocketArg,
SOCKET * ListenSocketArg);
-int
-CommunicationServerReceiveMessage(SOCKET ClientSocket, char * recvbuf, int recvbuflen);
+INT
+CommunicationServerReceiveMessage(SOCKET ClientSocket, CHAR * recvbuf, INT recvbuflen);
-int
-CommunicationServerSendMessage(SOCKET ClientSocket, const char * sendbuf, int length);
+INT
+CommunicationServerSendMessage(SOCKET ClientSocket, const CHAR * sendbuf, INT length);
-int
+INT
CommunicationServerShutdownAndCleanupConnection(SOCKET ClientSocket,
SOCKET ListenSocket);
@@ -43,19 +43,19 @@ CommunicationServerShutdownAndCleanupConnection(SOCKET ClientSocket,
// Client //
//////////////////////////////////////////
-int
+INT
CommunicationClientConnectToServer(PCSTR Ip, PCSTR Port, SOCKET * ConnectSocketArg);
-int
-CommunicationClientSendMessage(SOCKET ConnectSocket, const char * sendbuf, int buflen);
+INT
+CommunicationClientSendMessage(SOCKET ConnectSocket, const CHAR * sendbuf, INT buflen);
-int
+INT
CommunicationClientShutdownConnection(SOCKET ConnectSocket);
-int
+INT
CommunicationClientReceiveMessage(SOCKET ConnectSocket, CHAR * RecvBuf, UINT32 MaxBuffLen, PUINT32 BuffLenRecvd);
-int
+INT
CommunicationClientCleanup(SOCKET ConnectSocket);
//////////////////////////////////////////
@@ -68,11 +68,11 @@ RemoteConnectionListen(PCSTR Port);
VOID
RemoteConnectionConnect(PCSTR Ip, PCSTR Port);
-int
-RemoteConnectionSendCommand(const char * sendbuf, int len);
+INT
+RemoteConnectionSendCommand(const CHAR * sendbuf, INT len);
-int
-RemoteConnectionSendResultsToHost(const char * sendbuf, int len);
+INT
+RemoteConnectionSendResultsToHost(const CHAR * sendbuf, INT len);
-int
+INT
RemoteConnectionCloseTheConnectionWithDebuggee();
diff --git a/hyperdbg/libhyperdbg/header/forwarding.h b/hyperdbg/libhyperdbg/header/debugger/communication/forwarding.h
similarity index 97%
rename from hyperdbg/libhyperdbg/header/forwarding.h
rename to hyperdbg/libhyperdbg/header/debugger/communication/forwarding.h
index 2f3b0a0e..467aafae 100644
--- a/hyperdbg/libhyperdbg/header/forwarding.h
+++ b/hyperdbg/libhyperdbg/header/debugger/communication/forwarding.h
@@ -19,7 +19,7 @@
* @brief maximum characters for event forwarding source names
*
*/
-typedef void (*hyperdbg_event_forwarding_t)(const char *, unsigned int);
+typedef VOID (*hyperdbg_event_forwarding_t)(const CHAR *, UINT32);
//////////////////////////////////////////
// Output Source Forwarding //
diff --git a/hyperdbg/libhyperdbg/header/namedpipe.h b/hyperdbg/libhyperdbg/header/debugger/communication/namedpipe.h
similarity index 75%
rename from hyperdbg/libhyperdbg/header/namedpipe.h
rename to hyperdbg/libhyperdbg/header/debugger/communication/namedpipe.h
index 3438376d..5a15c31e 100644
--- a/hyperdbg/libhyperdbg/header/namedpipe.h
+++ b/hyperdbg/libhyperdbg/header/debugger/communication/namedpipe.h
@@ -22,12 +22,12 @@ BOOLEAN
NamedPipeServerWaitForClientConntection(HANDLE PipeHandle);
UINT32
-NamedPipeServerReadClientMessage(HANDLE PipeHandle, char * BufferToSave, int MaximumReadBufferLength);
+NamedPipeServerReadClientMessage(HANDLE PipeHandle, CHAR * BufferToSave, INT MaximumReadBufferLength);
BOOLEAN
NamedPipeServerSendMessageToClient(HANDLE PipeHandle,
- char * BufferToSend,
- int BufferSize);
+ CHAR * BufferToSend,
+ INT BufferSize);
VOID
NamedPipeServerCloseHandle(HANDLE PipeHandle);
@@ -43,10 +43,10 @@ HANDLE
NamedPipeClientCreatePipeOverlappedIo(LPCSTR PipeName);
BOOLEAN
-NamedPipeClientSendMessage(HANDLE PipeHandle, char * BufferToSend, int BufferSize);
+NamedPipeClientSendMessage(HANDLE PipeHandle, CHAR * BufferToSend, INT BufferSize);
UINT32
-NamedPipeClientReadMessage(HANDLE PipeHandle, char * BufferToRead, int MaximumSizeOfBuffer);
+NamedPipeClientReadMessage(HANDLE PipeHandle, CHAR * BufferToRead, INT MaximumSizeOfBuffer);
VOID
NamedPipeClientClosePipe(HANDLE PipeHandle);
diff --git a/hyperdbg/libhyperdbg/header/debugger.h b/hyperdbg/libhyperdbg/header/debugger/core/debugger.h
similarity index 91%
rename from hyperdbg/libhyperdbg/header/debugger.h
rename to hyperdbg/libhyperdbg/header/debugger/core/debugger.h
index e2e419ec..9ac1012c 100644
--- a/hyperdbg/libhyperdbg/header/debugger.h
+++ b/hyperdbg/libhyperdbg/header/debugger/core/debugger.h
@@ -1,6 +1,7 @@
/**
* @file debugger.h
* @author Sina Karvandi (sina@hyperdbg.org)
+ * @author jtaw5649
* @brief General debugger functions
* @details
* @version 0.1
@@ -60,6 +61,9 @@
#define DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_APIC_ACTIONS 0x1c
#define DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_PCIDEVINFO_RESULT 0x1d
#define DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_IDT_ENTRIES 0x1e
+#define DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_SMI_OPERATION_RESULT 0x1f
+#define DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_HYPERTRACE_LBR_DUMP_RESULT 0x20
+#define DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_HYPERTRACE_PT_OPERATION_RESULT 0x21
//////////////////////////////////////////////////
// Event Details //
@@ -100,7 +104,7 @@ typedef enum _DEBUGGER_EVENT_PARSING_ERROR_CAUSE
//
// User-debugger
//
-#define DEBUGGER_SYNCRONIZATION_OBJECT_USER_DEBUGGER_IS_DEBUGGER_RUNNING 0x30
+#define DEBUGGER_SYNCRONIZATION_OBJECT_USER_DEBUGGER_IS_DEBUGGER_RUNNING 0x0
//////////////////////////////////////////////////
// Event Details //
@@ -193,7 +197,7 @@ DWORD WINAPI
ListeningSerialPauseDebuggerThread(PVOID Param);
VOID
-LogopenSaveToFile(const char * Text);
+LogopenSaveToFile(const CHAR * Text);
BOOL
BreakController(DWORD CtrlType);
@@ -232,13 +236,13 @@ BOOLEAN
CommandBpRequest(UINT64 Address, UINT32 Pid, UINT32 Tid, UINT32 CoreNumer);
VOID
-CommandTrackHandleReceivedInstructions(unsigned char * BufferToDisassemble,
- UINT32 BuffLength,
- BOOLEAN Isx86_64,
- UINT64 RipAddress);
+CommandTrackHandleReceivedInstructions(UCHAR * BufferToDisassemble,
+ UINT32 BuffLength,
+ BOOLEAN Isx86_64,
+ UINT64 RipAddress);
VOID
-CommandTrackHandleReceivedCallInstructions(const char * NameOfFunctionFromSymbols,
+CommandTrackHandleReceivedCallInstructions(const CHAR * NameOfFunctionFromSymbols,
UINT64 ComputedAbsoluteAddress);
VOID
@@ -301,8 +305,23 @@ HyperDbgGetIoApic(IO_APIC_ENTRY_PACKETS * IoApic);
BOOLEAN
HyperDbgGetIdtEntry(INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS * IdtPacket);
+BOOLEAN
+HyperDbgPerformSmiOperation(SMI_OPERATION_PACKETS * SmiOperation);
+
BOOLEAN
HyperDbgEnableTransparentMode(UINT32 ProcessId, CHAR * ProcessName, BOOLEAN IsProcessId);
+BOOLEAN
+HyperDbgEnableTransparentModeEx(UINT32 ProcessId, CHAR * ProcessName, BOOLEAN IsProcessId, UINT32 EvadeMask);
+
BOOLEAN
HyperDbgDisableTransparentMode();
+
+BOOLEAN
+HyperDbgLbrdumpSendRequest(HYPERTRACE_LBR_DUMP_PACKETS * LbrdumpRequest);
+
+BOOLEAN
+HyperDbgPerformPtOperation(HYPERTRACE_PT_OPERATION_PACKETS * PtRequest);
+
+BOOLEAN
+HyperDbgPtMmapSendRequest(HYPERTRACE_PT_MMAP_PACKETS * MmapRequest);
diff --git a/hyperdbg/libhyperdbg/header/steppings.h b/hyperdbg/libhyperdbg/header/debugger/core/steppings.h
similarity index 100%
rename from hyperdbg/libhyperdbg/header/steppings.h
rename to hyperdbg/libhyperdbg/header/debugger/core/steppings.h
diff --git a/hyperdbg/libhyperdbg/header/install.h b/hyperdbg/libhyperdbg/header/debugger/driver-loader/install.h
similarity index 100%
rename from hyperdbg/libhyperdbg/header/install.h
rename to hyperdbg/libhyperdbg/header/debugger/driver-loader/install.h
diff --git a/hyperdbg/libhyperdbg/header/kd.h b/hyperdbg/libhyperdbg/header/debugger/kernel-level/kd.h
similarity index 70%
rename from hyperdbg/libhyperdbg/header/kd.h
rename to hyperdbg/libhyperdbg/header/debugger/kernel-level/kd.h
index edfcaa4b..9a7e2798 100644
--- a/hyperdbg/libhyperdbg/header/kd.h
+++ b/hyperdbg/libhyperdbg/header/debugger/kernel-level/kd.h
@@ -11,59 +11,12 @@
*/
#pragma once
-//////////////////////////////////////////////////
-// Definitions //
-//////////////////////////////////////////////////
-
-#define DbgWaitForKernelResponse(KernelSyncObjectId) \
- do \
- { \
- DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
- &g_KernelSyncronizationObjectsHandleTable[KernelSyncObjectId]; \
- \
- SyncronizationObject->IsOnWaitingState = TRUE; \
- WaitForSingleObject(SyncronizationObject->EventHandle, INFINITE); \
- \
- } while (FALSE);
-
-#define DbgWaitSetRequestData(KernelSyncObjectId, ReqData, ReqSize) \
- do \
- { \
- DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
- &g_KernelSyncronizationObjectsHandleTable[KernelSyncObjectId]; \
- \
- SyncronizationObject->RequestData = (PVOID)ReqData; \
- SyncronizationObject->RequestSize = (UINT32)ReqSize; \
- \
- } while (FALSE);
-
-#define DbgWaitGetRequestData(KernelSyncObjectId, ReqData, ReqSize) \
- do \
- { \
- DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
- &g_KernelSyncronizationObjectsHandleTable[KernelSyncObjectId]; \
- \
- *ReqData = SyncronizationObject->RequestData; \
- *ReqSize = SyncronizationObject->RequestSize; \
- SyncronizationObject->RequestData = NULL; \
- SyncronizationObject->RequestSize = NULL_ZERO; \
- \
- } while (FALSE);
-
-#define DbgReceivedKernelResponse(KernelSyncObjectId) \
- do \
- { \
- DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
- &g_KernelSyncronizationObjectsHandleTable[KernelSyncObjectId]; \
- \
- SyncronizationObject->IsOnWaitingState = FALSE; \
- SetEvent(SyncronizationObject->EventHandle); \
- } while (FALSE);
-
//////////////////////////////////////////////////
// Display Windows Details //
//////////////////////////////////////////////////
+#ifdef _WIN32
+// HKEY / RegCloseKey are Windows registry APIs; this RAII helper is Windows-only
struct HKeyHolder
{
private:
@@ -86,6 +39,7 @@ public:
HKEY * operator&() { return &m_Key; }
};
+#endif // _WIN32
//////////////////////////////////////////////////
// Functions //
@@ -201,6 +155,15 @@ KdSendVa2paAndPa2vaPacketToDebuggee(PDEBUGGER_VA2PA_AND_PA2VA_COMMANDS Va2paAndP
BOOLEAN
KdSendApicActionPacketsToDebuggee(PDEBUGGER_APIC_REQUEST ApicRequest, UINT32 ExpectedRequestSize);
+BOOLEAN
+KdSendSmiPacketsToDebuggee(PSMI_OPERATION_PACKETS SmiOperationRequest, UINT32 ExpectedRequestSize);
+
+BOOLEAN
+KdSendHyperTraceLbrdumpPacketsToDebuggee(PHYPERTRACE_LBR_DUMP_PACKETS HyperTraceLbrdumpRequest, UINT32 ExpectedRequestSize);
+
+BOOLEAN
+KdSendHyperTracePtPacketsToDebuggee(PHYPERTRACE_PT_OPERATION_PACKETS HyperTracePtOperationRequest, UINT32 ExpectedRequestSize);
+
BOOLEAN
KdSendQueryIdtPacketsToDebuggee(PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS IdtRequest);
@@ -218,7 +181,7 @@ BOOLEAN
KdSendScriptPacketToDebuggee(UINT64 BufferAddress, UINT32 BufferLength, UINT32 Pointer, BOOLEAN IsFormat);
BOOLEAN
-KdSendUserInputPacketToDebuggee(const char * Sendbuf, int Len, BOOLEAN IgnoreBreakingAgain);
+KdSendUserInputPacketToDebuggee(const CHAR * Sendbuf, INT Len, BOOLEAN IgnoreBreakingAgain);
BOOLEAN
KdSendSearchRequestPacketToDebuggee(UINT64 * SearchRequestBuffer, UINT32 SearchRequestBufferSize);
@@ -256,6 +219,12 @@ KdReloadSymbolsInDebuggee(BOOLEAN PauseDebuggee, UINT32 UserProcessId);
BOOLEAN
KdSendResponseOfThePingPacket();
+BOOLEAN
+KdSendPcitreePacketToDebuggee(PDEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET PcitreePacket);
+
+BOOLEAN
+KdSendPcidevinfoPacketToDebuggee(PDEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET PcidevinfoPacket);
+
VOID
KdUninitializeConnection();
@@ -281,9 +250,3 @@ KdBreakControlCheckAndContinueDebugger();
VOID
KdSetStatusAndWaitForPause();
-
-BOOLEAN
-KdSendPcitreePacketToDebuggee(PDEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET PcitreePacket);
-
-BOOLEAN
-KdSendPcidevinfoPacketToDebuggee(PDEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET PcidevinfoPacket);
diff --git a/hyperdbg/libhyperdbg/header/assembler.h b/hyperdbg/libhyperdbg/header/debugger/misc/assembler.h
similarity index 75%
rename from hyperdbg/libhyperdbg/header/assembler.h
rename to hyperdbg/libhyperdbg/header/debugger/misc/assembler.h
index 8b5e585b..5a133a0e 100644
--- a/hyperdbg/libhyperdbg/header/assembler.h
+++ b/hyperdbg/libhyperdbg/header/debugger/misc/assembler.h
@@ -15,13 +15,13 @@
class AssembleData
{
public:
- std::string AsmRaw {};
- std::string AsmFixed {};
- size_t StatementCount {};
- size_t BytesCount {};
- unsigned char * EncodedBytes {};
- vector EncBytesIntVec {};
- ks_err KsErr {};
+ std::string AsmRaw {};
+ std::string AsmFixed {};
+ SIZE_T StatementCount {};
+ SIZE_T BytesCount {};
+ UCHAR * EncodedBytes {};
+ vector EncBytesIntVec {};
+ ks_err KsErr {};
AssembleData() = default;
diff --git a/hyperdbg/libhyperdbg/header/inipp.h b/hyperdbg/libhyperdbg/header/debugger/misc/inipp.h
similarity index 100%
rename from hyperdbg/libhyperdbg/header/inipp.h
rename to hyperdbg/libhyperdbg/header/debugger/misc/inipp.h
diff --git a/hyperdbg/libhyperdbg/pci-id.h b/hyperdbg/libhyperdbg/header/debugger/misc/pci-id.h
similarity index 85%
rename from hyperdbg/libhyperdbg/pci-id.h
rename to hyperdbg/libhyperdbg/header/debugger/misc/pci-id.h
index a33e0867..b2196274 100644
--- a/hyperdbg/libhyperdbg/pci-id.h
+++ b/hyperdbg/libhyperdbg/header/debugger/misc/pci-id.h
@@ -1,6 +1,6 @@
/**
* @file pci-id.h
- * @author Bjrn Ruytenberg (bjorn@bjornweb.nl)
+ * @author Bj�rn Ruytenberg (bjorn@bjornweb.nl)
* @brief PCI ID-related data structures
* @details
* @version 0.12
@@ -18,14 +18,14 @@ typedef struct SubDevice
{
UINT16 SubVendorId;
UINT16 SubDeviceId;
- char SubSystemName[PCI_NAME_STR_LENGTH];
+ CHAR SubSystemName[PCI_NAME_STR_LENGTH];
struct SubDevice * Next;
} SubDevice;
typedef struct Device
{
UINT16 DeviceId;
- char DeviceName[PCI_NAME_STR_LENGTH];
+ CHAR DeviceName[PCI_NAME_STR_LENGTH];
SubDevice * SubDevices;
struct Device * Next;
} Device;
@@ -33,7 +33,7 @@ typedef struct Device
typedef struct Vendor
{
UINT16 VendorId;
- char VendorName[PCI_NAME_STR_LENGTH];
+ CHAR VendorName[PCI_NAME_STR_LENGTH];
Device * Devices;
} Vendor;
@@ -46,6 +46,7 @@ typedef struct Vendor
//////////////////////////////////////////////////
// Functions //
//////////////////////////////////////////////////
+
Vendor *
GetVendorById(UINT16 VendorId);
void
diff --git a/hyperdbg/libhyperdbg/header/debugger/misc/pt-helper.h b/hyperdbg/libhyperdbg/header/debugger/misc/pt-helper.h
new file mode 100644
index 00000000..b3f595f4
--- /dev/null
+++ b/hyperdbg/libhyperdbg/header/debugger/misc/pt-helper.h
@@ -0,0 +1,28 @@
+/**
+ * @file pt-helper.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Headers for PT helper functions
+ * @details
+ * @version 0.21
+ * @date 2026-07-03
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+UINT64
+PtHelperDecodeCorePackets(UINT32 Cpu, const UINT8 * Buffer, UINT64 Size, UINT64 ImageBase);
+
+UINT64
+PtHelperDecodeCore(UINT32 Cpu, const UINT8 * Buffer, UINT64 Size, IMAGE_SYMBOL_CONTEXT * Ctx);
+
+BOOLEAN
+PtHelperCaptureImage(HANDLE Process, UINT64 * TextStart, UINT64 * TextEnd, IMAGE_SYMBOL_CONTEXT * Ctx);
+
+BOOLEAN
+PtHelperResolveFunction(HANDLE Process, const CHAR * Path, const CHAR * Name, UINT64 ImageBase, UINT64 * Start, UINT64 * End);
diff --git a/hyperdbg/libhyperdbg/header/script-engine.h b/hyperdbg/libhyperdbg/header/debugger/script-engine/script-engine.h
similarity index 62%
rename from hyperdbg/libhyperdbg/header/script-engine.h
rename to hyperdbg/libhyperdbg/header/debugger/script-engine/script-engine.h
index e9fe3fbf..408b4ab1 100644
--- a/hyperdbg/libhyperdbg/header/script-engine.h
+++ b/hyperdbg/libhyperdbg/header/debugger/script-engine/script-engine.h
@@ -15,10 +15,10 @@
// Pdb Parser Wrapper (from script-engine) //
//////////////////////////////////////////////////
UINT64
-ScriptEngineConvertNameToAddressWrapper(const char * FunctionOrVariableName, PBOOLEAN WasFound);
+ScriptEngineConvertNameToAddressWrapper(const CHAR * FunctionOrVariableName, PBOOLEAN WasFound);
UINT32
-ScriptEngineLoadFileSymbolWrapper(UINT64 BaseAddress, const char * PdbFileName, const char * CustomModuleName);
+ScriptEngineLoadFileSymbolWrapper(UINT64 BaseAddress, const CHAR * PdbFileName, const CHAR * CustomModuleName);
VOID
ScriptEngineSetTextMessageCallbackWrapper(PVOID Handler);
@@ -27,10 +27,10 @@ UINT32
ScriptEngineUnloadAllSymbolsWrapper();
UINT32
-ScriptEngineUnloadModuleSymbolWrapper(char * ModuleName);
+ScriptEngineUnloadModuleSymbolWrapper(CHAR * ModuleName);
UINT32
-ScriptEngineSearchSymbolForMaskWrapper(const char * SearchMask);
+ScriptEngineSearchSymbolForMaskWrapper(const CHAR * SearchMask);
BOOLEAN
ScriptEngineGetFieldOffsetWrapper(CHAR * TypeName, CHAR * FieldName, UINT32 * FieldOffset);
@@ -39,31 +39,39 @@ BOOLEAN
ScriptEngineGetDataTypeSizeWrapper(CHAR * TypeName, UINT64 * TypeSize);
BOOLEAN
-ScriptEngineCreateSymbolTableForDisassemblerWrapper(void * CallbackFunction);
+ScriptEngineCreateSymbolTableForDisassemblerWrapper(VOID * CallbackFunction);
BOOLEAN
-ScriptEngineConvertFileToPdbPathWrapper(const char * LocalFilePath, char * ResultPath, size_t ResultPathSize);
+ScriptEngineConvertFileToPdbPathWrapper(const CHAR * LocalFilePath, CHAR * ResultPath, SIZE_T ResultPathSize);
BOOLEAN
-ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetailsWrapper(const char * LocalFilePath,
- char * PdbFilePath,
- char * GuidAndAgeDetails,
+ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetailsWrapper(const CHAR * LocalFilePath,
+ CHAR * PdbFilePath,
+ CHAR * GuidAndAgeDetails,
BOOLEAN Is32BitModule);
+BOOLEAN
+ScriptEngineConvertLoadedModuleToPdbFileAndGuidAndAgeDetailsWrapper(const BYTE * LoadedImageBytes,
+ SIZE_T LoadedImageSize,
+ const CHAR * LocalFilePath,
+ CHAR * PdbFilePath,
+ CHAR * GuidAndAgeDetails,
+ BOOLEAN Is32BitModule);
+
BOOLEAN
ScriptEngineSymbolInitLoadWrapper(PMODULE_SYMBOL_DETAIL BufferToStoreDetails,
UINT32 StoredLength,
BOOLEAN DownloadIfAvailable,
- const char * SymbolPath,
+ const CHAR * SymbolPath,
BOOLEAN IsSilentLoad);
BOOLEAN
ScriptEngineShowDataBasedOnSymbolTypesWrapper(
- const char * TypeName,
+ const CHAR * TypeName,
UINT64 Address,
BOOLEAN IsStruct,
PVOID BufferAddress,
- const char * AdditionalParameters);
+ const CHAR * AdditionalParameters);
VOID
ScriptEngineSymbolAbortLoadingWrapper();
@@ -82,7 +90,7 @@ BOOLEAN
ScriptAutomaticStatementsTestWrapper(const string & Expr, UINT64 ExpectationValue, BOOLEAN ExceptError);
PVOID
-ScriptEngineParseWrapper(char * Expr, BOOLEAN ShowErrorMessageIfAny);
+ScriptEngineParseWrapper(CHAR * Expr, BOOLEAN ShowErrorMessageIfAny);
VOID
PrintSymbolBufferWrapper(PVOID SymbolBuffer);
@@ -108,3 +116,6 @@ ScriptEngineEvalUInt64StyleExpressionWrapper(const string & Expr, PBOOLEAN HasEr
UINT64
ScriptEngineEvalSingleExpression(string Expr, PBOOLEAN HasError);
+
+BOOLEAN
+ScriptEngineExecuteSingleExpression(CHAR * Expr, BOOLEAN ShowErrorMessageIfAny, BOOLEAN IsFormat);
diff --git a/hyperdbg/libhyperdbg/header/symbol.h b/hyperdbg/libhyperdbg/header/debugger/script-engine/symbol.h
similarity index 63%
rename from hyperdbg/libhyperdbg/header/symbol.h
rename to hyperdbg/libhyperdbg/header/debugger/script-engine/symbol.h
index 6fab7ff4..b80cdc45 100644
--- a/hyperdbg/libhyperdbg/header/symbol.h
+++ b/hyperdbg/libhyperdbg/header/debugger/script-engine/symbol.h
@@ -26,6 +26,53 @@ typedef struct _LOCAL_FUNCTION_DESCRIPTION
} LOCAL_FUNCTION_DESCRIPTION, *PLOCAL_FUNCTION_DESCRIPTION;
+/**
+ * @brief Save the local module symbols' description
+ *
+ */
+typedef struct _IMAGE_SYMBOL_CONTEXT
+{
+ UINT64 ImageBase;
+ UINT64 CodeBase;
+ UINT64 CodeSize;
+ UINT8 * Code;
+} IMAGE_SYMBOL_CONTEXT;
+
+/*
+ * @brief Process basic information structure
+ */
+typedef struct _PROC_BASIC_INFO
+{
+ LONG ExitStatus;
+ PVOID PebBaseAddress;
+ ULONG_PTR Reserved[4];
+} PROC_BASIC_INFO;
+
+/**
+ * @brief Thread basic information
+ *
+ */
+typedef struct _THREAD_BASIC_INFO_EX
+{
+ LONG ExitStatus;
+ PVOID TebBaseAddress;
+ struct
+ {
+ HANDLE UniqueProcess;
+ HANDLE UniqueThread;
+ } ClientId;
+ ULONG_PTR AffinityMask;
+ LONG Priority;
+ LONG BasePriority;
+} THREAD_BASIC_INFO_EX;
+
+//////////////////////////////////////////////////
+// Function Defs //
+//////////////////////////////////////////////////
+
+typedef LONG(NTAPI * PFN_NT_QIP)(HANDLE, ULONG, PVOID, ULONG, PULONG);
+typedef LONG(NTAPI * PFN_NT_QIT)(HANDLE, ULONG, PVOID, ULONG, PULONG);
+
//////////////////////////////////////////////////
// Pdbex //
//////////////////////////////////////////////////
@@ -72,5 +119,8 @@ SymbolPrepareDebuggerWithSymbolInfo(UINT32 UserProcessId);
BOOLEAN
SymbolReloadSymbolTableInDebuggerMode(UINT32 ProcessId);
+#ifdef _WIN32
+// PRTL_PROCESS_MODULES is from winternl.h — Windows-only
BOOLEAN
SymbolCheckAndAllocateModuleInformation(PRTL_PROCESS_MODULES * Modules);
+#endif // _WIN32
diff --git a/hyperdbg/libhyperdbg/header/tests.h b/hyperdbg/libhyperdbg/header/debugger/tests/tests.h
similarity index 100%
rename from hyperdbg/libhyperdbg/header/tests.h
rename to hyperdbg/libhyperdbg/header/debugger/tests/tests.h
diff --git a/hyperdbg/libhyperdbg/header/transparency.h b/hyperdbg/libhyperdbg/header/debugger/transparency/transparency.h
similarity index 100%
rename from hyperdbg/libhyperdbg/header/transparency.h
rename to hyperdbg/libhyperdbg/header/debugger/transparency/transparency.h
diff --git a/hyperdbg/libhyperdbg/header/debugger/user-level/pe-parser.h b/hyperdbg/libhyperdbg/header/debugger/user-level/pe-parser.h
new file mode 100644
index 00000000..af5ca293
--- /dev/null
+++ b/hyperdbg/libhyperdbg/header/debugger/user-level/pe-parser.h
@@ -0,0 +1,57 @@
+/**
+ * @file pe-parser.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Header for Portable Executable parser
+ * @details
+ * @version 0.1
+ * @date 2021-12-26
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Structures //
+//////////////////////////////////////////////////
+
+typedef struct _RICH_HEADER_INFO
+{
+ int Size;
+ CHAR * PtrToBuffer;
+ int Entries;
+} RICH_HEADER_INFO, *PRICH_HEADER_INFO;
+
+typedef struct _RICH_HEADER_ENTRY
+{
+ WORD ProdID;
+ WORD BuildID;
+ DWORD UseCount;
+} RICH_HEADER_ENTRY, *PRICH_HEADER_ENTRY;
+
+typedef struct _RICH_HEADER
+{
+ PRICH_HEADER_ENTRY Entries;
+} RICH_HEADER, *PRICH_HEADER;
+
+typedef struct _PE_RAW_SECTION_RANGE
+{
+ ULONGLONG Start;
+ ULONGLONG End;
+ const IMAGE_SECTION_HEADER * Section;
+} PE_RAW_SECTION_RANGE, *PPE_RAW_SECTION_RANGE;
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+BOOLEAN
+PeShowSectionInformationAndDump(const WCHAR * AddressOfFile,
+ const CHAR * SectionToShow,
+ BOOLEAN Is32Bit);
+
+BOOLEAN
+PeIsPE32BitOr64Bit(const WCHAR * AddressOfFile, PBOOLEAN Is32Bit);
+
+UINT32
+PeGetSyscallNumber(LPCSTR NtFunctionName);
diff --git a/hyperdbg/libhyperdbg/header/ud.h b/hyperdbg/libhyperdbg/header/debugger/user-level/ud.h
similarity index 53%
rename from hyperdbg/libhyperdbg/header/ud.h
rename to hyperdbg/libhyperdbg/header/debugger/user-level/ud.h
index 416d5a34..dc4f38cd 100644
--- a/hyperdbg/libhyperdbg/header/ud.h
+++ b/hyperdbg/libhyperdbg/header/debugger/user-level/ud.h
@@ -11,30 +11,6 @@
*/
#pragma once
-//////////////////////////////////////////////////
-// Definitions //
-//////////////////////////////////////////////////
-
-#define DbgWaitForUserResponse(UserSyncObjectId) \
- do \
- { \
- DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
- &g_UserSyncronizationObjectsHandleTable[UserSyncObjectId]; \
- \
- SyncronizationObject->IsOnWaitingState = TRUE; \
- WaitForSingleObject(SyncronizationObject->EventHandle, INFINITE); \
- } while (FALSE);
-
-#define DbgReceivedUserResponse(UserSyncObjectId) \
- do \
- { \
- DEBUGGER_SYNCRONIZATION_EVENTS_STATE * SyncronizationObject = \
- &g_UserSyncronizationObjectsHandleTable[UserSyncObjectId]; \
- \
- SyncronizationObject->IsOnWaitingState = FALSE; \
- SetEvent(SyncronizationObject->EventHandle); \
- } while (FALSE);
-
//////////////////////////////////////////////////
// Structures //
//////////////////////////////////////////////////
@@ -53,7 +29,10 @@ typedef struct _ACTIVE_DEBUGGING_PROCESS
BOOLEAN IsPaused;
GUEST_REGS Registers; // thread registers
UINT64 Context; // $context
+ UINT64 Rip;
BOOLEAN Is32Bit;
+ BYTE InstructionBytesOnRip[MAXIMUM_INSTR_SIZE];
+
} ACTIVE_DEBUGGING_PROCESS, *PACTIVE_DEBUGGING_PROCESS;
//////////////////////////////////////////////////
@@ -67,20 +46,25 @@ VOID
UdUninitializeUserDebugger();
VOID
-UdRemoveActiveDebuggingProcess(BOOLEAN DontSwitchToNewProcess);
+UdRemoveActiveDebuggingProcess();
VOID
UdHandleUserDebuggerPausing(PDEBUGGEE_UD_PAUSED_PACKET PausePacket);
-VOID
-UdSendStepPacketToDebuggee(UINT64 ThreadDetailToken, UINT32 TargetThreadId, DEBUGGER_REMOTE_STEPPING_REQUEST StepType);
-
VOID
UdSetActiveDebuggingProcess(UINT64 DebuggingId,
+ UINT64 Rip,
UINT32 ProcessId,
UINT32 ThreadId,
BOOLEAN Is32Bit,
- BOOLEAN IsPaused);
+ BOOLEAN IsPaused,
+ BYTE InstructionBytesOnRip[]);
+
+BOOLEAN
+UdSendStepPacketToDebuggee(UINT64 ThreadDetailToken,
+ UINT32 TargetThreadId,
+ DEBUGGER_REMOTE_STEPPING_REQUEST StepType);
+
BOOLEAN
UdSetActiveDebuggingThreadByPidOrTid(UINT32 TargetPidOrTid, BOOLEAN IsTid);
@@ -113,3 +97,30 @@ UdContinueProcess(UINT64 ProcessDebuggingToken);
BOOLEAN
UdPauseProcess(UINT64 ProcessDebuggingToken);
+
+BOOLEAN
+UdSendCommand(UINT64 ProcessDetailToken,
+ UINT32 ThreadId,
+ DEBUGGER_UD_COMMAND_ACTION_TYPE ActionType,
+ PVOID OptionalBuffer,
+ UINT32 OptionalBufferSize,
+ BOOLEAN ApplyToAllPausedThreads,
+ BOOLEAN WaitForEventCompletion,
+ UINT64 OptionalParam1,
+ UINT64 OptionalParam2,
+ UINT64 OptionalParam3,
+ UINT64 OptionalParam4);
+
+BOOLEAN
+UdSendScriptBufferToProcess(UINT64 ProcessDetailToken,
+ UINT32 TargetThreadId,
+ UINT64 BufferAddress,
+ UINT32 BufferLength,
+ UINT32 Pointer,
+ BOOLEAN IsFormat);
+
+BOOLEAN
+UdSendReadRegisterToUserDebugger(UINT64 ProcessDetailToken,
+ UINT32 TargetThreadId,
+ PDEBUGGEE_REGISTER_READ_DESCRIPTION RegDes,
+ UINT32 RegBuffSize);
diff --git a/hyperdbg/libhyperdbg/header/export.h b/hyperdbg/libhyperdbg/header/export/export.h
similarity index 100%
rename from hyperdbg/libhyperdbg/header/export.h
rename to hyperdbg/libhyperdbg/header/export/export.h
diff --git a/hyperdbg/libhyperdbg/header/globals.h b/hyperdbg/libhyperdbg/header/globals/globals.h
similarity index 96%
rename from hyperdbg/libhyperdbg/header/globals.h
rename to hyperdbg/libhyperdbg/header/globals/globals.h
index 9140c4c8..bf8dfd11 100644
--- a/hyperdbg/libhyperdbg/header/globals.h
+++ b/hyperdbg/libhyperdbg/header/globals/globals.h
@@ -11,6 +11,28 @@
*/
#pragma once
+//////////////////////////////////////////////////
+// Module Loading Status //
+//////////////////////////////////////////////////
+
+/**
+ * @brief shows whether the kernel debugger (KD) module is loaded or not
+ *
+ */
+BOOLEAN g_IsKdModuleLoaded = FALSE;
+
+/**
+ * @brief shows whether the VMM module is loaded or not
+ *
+ */
+BOOLEAN g_IsVmmModuleLoaded = FALSE;
+
+/**
+ * @brief shows whether the HyperTrace module is loaded or not
+ *
+ */
+BOOLEAN g_IsHyperTraceModuleLoaded = FALSE;
+
//////////////////////////////////////////////////
// Feature Indicators //
//////////////////////////////////////////////////
@@ -295,10 +317,12 @@ DEBUGGER_EVENT_AND_ACTION_RESULT g_DebuggeeResultOfAddingActionsToEvent = {
* to write simultaneously but it's needed for write)
*
*/
+#ifdef _WIN32
OVERLAPPED g_OverlappedIoStructureForReadDebugger = {0};
OVERLAPPED g_OverlappedIoStructureForWriteDebugger = {0};
OVERLAPPED g_OverlappedIoStructureForReadDebuggee = {0};
+#endif // _WIN32
/**
* @brief Shows whether the queried event is enabled or disabled
@@ -341,14 +365,6 @@ UINT64 * g_ScriptStackBuffer;
*/
BOOLEAN g_IsCommandListInitialized = FALSE;
-/**
- * @brief this variable is used to indicate that modules
- * are loaded so we make sure to later use a trace of
- * loading in 'unload' command (used in Debugger VMM)
- *
- */
-BOOLEAN g_IsDebuggerModulesLoaded = FALSE;
-
/**
* @brief State of active debugging thread
*
@@ -450,10 +466,10 @@ PVOID g_MessageHandler = 0;
PVOID g_MessageHandlerSharedBuffer = 0;
/**
- * @brief Shows whether the vmxoff process start or not
+ * @brief Shows whether the message logging window is closed or not
*
*/
-BOOLEAN g_IsVmxOffProcessStart;
+BOOLEAN g_IsMessageLoggingWindowClosed;
/**
* @brief Holds the global handle of device which is used
@@ -559,11 +575,6 @@ BOOLEAN g_IsInstrumentingInstructions = FALSE;
*/
UINT64 g_KernelBaseAddress;
-/**
- * @brief Is privileges already adjusted
- */
-BOOLEAN g_PrivilegesAlreadyAdjusted = FALSE;
-
//////////////////////////////////////////////////
// Settings //
//////////////////////////////////////////////////
diff --git a/hyperdbg/libhyperdbg/header/hwdbg-interpreter.h b/hyperdbg/libhyperdbg/header/hwdbg/hwdbg-interpreter.h
similarity index 93%
rename from hyperdbg/libhyperdbg/header/hwdbg-interpreter.h
rename to hyperdbg/libhyperdbg/header/hwdbg/hwdbg-interpreter.h
index 3275e176..fc823d56 100644
--- a/hyperdbg/libhyperdbg/header/hwdbg-interpreter.h
+++ b/hyperdbg/libhyperdbg/header/hwdbg/hwdbg-interpreter.h
@@ -26,13 +26,13 @@ HwdbgInterpreterFillFileFromMemory(
HWDBG_INSTANCE_INFORMATION * InstanceInfo,
const TCHAR * FileName,
UINT32 * MemoryBuffer,
- size_t BufferSize,
+ SIZE_T BufferSize,
HWDBG_ACTION_ENUMS RequestedAction);
BOOLEAN
HwdbgInterpreterFillMemoryFromFile(const TCHAR * FileName,
UINT32 * MemoryBuffer,
- size_t BufferSize);
+ SIZE_T BufferSize);
SIZE_T
HwdbgComputeNumberOfFlipFlopsNeeded(
@@ -48,7 +48,7 @@ HwdbgInterpreterSendPacketAndBufferToHwdbg(HWDBG_INSTANCE_INFORMATION * Instance
UINT32 BufferLength);
BOOLEAN
-HwdbgReadInstanceInfoFromFile(const TCHAR * FileName, UINT32 * MemoryBuffer, size_t BufferSize);
+HwdbgReadInstanceInfoFromFile(const TCHAR * FileName, UINT32 * MemoryBuffer, SIZE_T BufferSize);
BOOLEAN
HwdbgWriteTestInstanceInfoRequestIntoFile(HWDBG_INSTANCE_INFORMATION * InstanceInfo,
diff --git a/hyperdbg/libhyperdbg/header/hwdbg-scripts.h b/hyperdbg/libhyperdbg/header/hwdbg/hwdbg-scripts.h
similarity index 100%
rename from hyperdbg/libhyperdbg/header/hwdbg-scripts.h
rename to hyperdbg/libhyperdbg/header/hwdbg/hwdbg-scripts.h
diff --git a/hyperdbg/libhyperdbg/header/objects.h b/hyperdbg/libhyperdbg/header/objects/objects.h
similarity index 100%
rename from hyperdbg/libhyperdbg/header/objects.h
rename to hyperdbg/libhyperdbg/header/objects/objects.h
diff --git a/hyperdbg/libhyperdbg/header/pe-parser.h b/hyperdbg/libhyperdbg/header/pe-parser.h
deleted file mode 100644
index 180569e3..00000000
--- a/hyperdbg/libhyperdbg/header/pe-parser.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * @file pe-parser.h
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief Header for Portable Executable parser
- * @details
- * @version 0.1
- * @date 2021-12-26
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#pragma once
-
-//////////////////////////////////////////////////
-// Functions //
-//////////////////////////////////////////////////
-
-BOOLEAN
-PeShowSectionInformationAndDump(const WCHAR * AddressOfFile, const CHAR * SectionToShow, BOOLEAN Is32Bit);
-
-BOOLEAN
-PeIsPE32BitOr64Bit(const WCHAR * AddressOfFile, PBOOLEAN Is32Bit);
-
-UINT32
-PeGetSyscallNumber(LPCSTR NtFunctionName);
diff --git a/hyperdbg/libhyperdbg/header/rev-ctrl.h b/hyperdbg/libhyperdbg/header/rev/rev-ctrl.h
similarity index 100%
rename from hyperdbg/libhyperdbg/header/rev-ctrl.h
rename to hyperdbg/libhyperdbg/header/rev/rev-ctrl.h
diff --git a/hyperdbg/libhyperdbg/libhyperdbg.vcxproj b/hyperdbg/libhyperdbg/libhyperdbg.vcxproj
index 98415643..cd1d0655 100644
--- a/hyperdbg/libhyperdbg/libhyperdbg.vcxproj
+++ b/hyperdbg/libhyperdbg/libhyperdbg.vcxproj
@@ -21,14 +21,14 @@
DynamicLibrarytrue
- v143
+ v145NotSetfalseDynamicLibraryfalse
- v143
+ v145trueNotSetfalse
@@ -78,7 +78,7 @@
Windowstruefalse
- $(SolutionDir)libraries\zydis\user\Zycore.lib;$(SolutionDir)libraries\zydis\user\Zydis.lib;$(SolutionDir)build\bin\$(Configuration)\script-engine.lib;$(SolutionDir)libraries\keystone\$(Configuration)-lib\keystone.lib;%(AdditionalDependencies)
+ $(SolutionDir)libraries\zydis\user\Zycore.lib;$(SolutionDir)libraries\zydis\user\Zydis.lib;$(SolutionDir)build\bin\$(Configuration)\script-engine.lib;$(SolutionDir)libraries\keystone\$(Configuration)-lib\keystone.lib;$(SolutionDir)libraries\libipt\libipt.lib;%(AdditionalDependencies)%(AdditionalLibraryDirectories)false
@@ -87,7 +87,9 @@
- msbuild "$(SolutionDir)dependencies\zydis\msvc\Zydis.sln" /m /p:Configuration="Release MT" /p:Platform=$(Platform) /target:zydis /target:zycore /p:OutDir="$(SolutionDir)libraries\zydis\user"
+ copy "$(SolutionDir)libraries\libipt\libipt.lib" "$(OutDir)"
+copy "$(SolutionDir)libraries\libipt\libipt.dll" "$(OutDir)"
+msbuild "$(SolutionDir)dependencies\zydis\msvc\Zydis.sln" /m /p:Configuration="Release MT" /p:Platform=$(Platform) /target:zydis /target:zycore /p:OutDir="$(SolutionDir)libraries\zydis\user"
@@ -106,7 +108,7 @@
CompileAsCpptruestdcpp20
- Disabled
+ MaxSpeedWindows
@@ -114,7 +116,7 @@
truetruefalse
- $(SolutionDir)libraries\zydis\user\Zycore.lib;$(SolutionDir)libraries\zydis\user\Zydis.lib;$(SolutionDir)build\bin\$(Configuration)\script-engine.lib;$(SolutionDir)libraries\keystone\$(Configuration)-lib\keystone.lib;%(AdditionalDependencies)
+ $(SolutionDir)libraries\zydis\user\Zycore.lib;$(SolutionDir)libraries\zydis\user\Zydis.lib;$(SolutionDir)build\bin\$(Configuration)\script-engine.lib;$(SolutionDir)libraries\keystone\$(Configuration)-lib\keystone.lib;$(SolutionDir)libraries\libipt\libipt.lib;%(AdditionalDependencies)%(AdditionalLibraryDirectories)true
@@ -123,47 +125,68 @@
- msbuild "$(SolutionDir)dependencies\zydis\msvc\Zydis.sln" /m /p:Configuration="Release MT" /p:Platform=$(Platform) /target:zydis /target:zycore /p:OutDir="$(SolutionDir)libraries\zydis\user"
+ copy "$(SolutionDir)libraries\libipt\libipt.lib" "$(OutDir)"
+copy "$(SolutionDir)libraries\libipt\libipt.dll" "$(OutDir)"
+msbuild "$(SolutionDir)dependencies\zydis\msvc\Zydis.sln" /m /p:Configuration="Release MT" /p:Platform=$(Platform) /target:zydis /target:zycore /p:OutDir="$(SolutionDir)libraries\zydis\user"
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
@@ -178,11 +201,17 @@
+
+
+
+
+
+
@@ -202,6 +231,8 @@
+
+
@@ -221,7 +252,6 @@
-
@@ -298,8 +328,6 @@
-
-
diff --git a/hyperdbg/libhyperdbg/libhyperdbg.vcxproj.filters b/hyperdbg/libhyperdbg/libhyperdbg.vcxproj.filters
index 06b9ee0a..492c7f91 100644
--- a/hyperdbg/libhyperdbg/libhyperdbg.vcxproj.filters
+++ b/hyperdbg/libhyperdbg/libhyperdbg.vcxproj.filters
@@ -84,97 +84,199 @@
{cfacdcfe-8503-4a00-b7e2-75b0e906f75e}
+
+ {223523be-9b81-41cc-b708-872e292fd1f5}
+
+
+ {8e3c36aa-4263-4c94-9910-884ad9652921}
+
+
+ {5b7dcc48-4010-40db-973f-bf46eb1e810b}
+
+
+ {b6d17c7a-e6e7-490b-b581-c6a06d0d61a9}
+
+
+ {a5552ded-23bb-45ad-85c2-d8d85a5b4e49}
+
+
+ {da7e68cc-540c-4efc-b4de-c23b4b13e2ec}
+
+
+ {d6010267-4888-46f5-9bdb-2339565710d2}
+
+
+ {e81c07d3-5e98-4bdb-a00b-2b99e023553c}
+
+
+ {477d3059-08d7-433b-83c3-bbf57658deaf}
+
+
+ {559b68f3-8bf0-447a-a714-0e355c22516f}
+
+
+ {88de3dbf-90ab-47ef-94fe-8c21ce73c9f1}
+
+
+ {c1f438ff-fd3b-4fb4-989b-f145290e3837}
+
+
+ {c5b26259-abcc-459f-9b7e-fd90c34ad646}
+
+
+ {99425a01-168c-4b6b-a53f-d62fbb7c8cab}
+
+
+ {c7f85132-1802-4462-990f-3fffb0365dbc}
+
+
+ {4f4eca9f-c1f6-4342-91ef-2b533292e238}
+
+
+ {bde7408e-fad9-4329-98ac-e604674f7bbf}
+
+
+ {06e9888f-57f0-4d59-8f7e-1fdd336be9cc}
+
+
+ {0d88d581-8ff4-40f2-8585-3fdb97d4d211}
+
+
+ {439dcb49-1825-4076-affe-17b505e4033a}
+
+
+ {16331b3c-c8fd-4b12-abb4-7617d21db9d0}
+
+
+ {2d2c16a6-3fdc-4b63-a282-f2762a1f340d}
+
+
+ {9dcff6b3-9ebd-46f3-a0c5-c69d06357949}
+
+
+ {3e4dda9f-6050-409f-85e2-4cf7c8a95743}
+ header
-
- header
-
-
- header
-
-
- header
-
-
- header
-
-
- header
-
-
- header
-
-
- header
-
-
- header
-
-
- header
-
-
- header
-
-
- header
-
-
- header
-
-
- header
-
-
- header
-
-
- header
-
-
- header
-
-
- header
-
-
- header
-
-
- header
-
-
- header
-
-
- header\platform
-
-
- header
- header\platform
-
- header
+
+ header\platform
-
- header
+
+ header\platform
-
- header
+
+ header\platform
-
- header
+
+ header\platform
-
- header
+
+ header\platform
-
- header
+
+ header\platform
+
+
+ header\platform\windows-only
+
+
+ header\components\pe
+
+
+ header\app
+
+
+ header\app
+
+
+ header\app
+
+
+ header\common
+
+
+ header\common
+
+
+ header\export
+
+
+ header\globals
+
+
+ header\hwdbg
+
+
+ header\hwdbg
+
+
+ header\rev
+
+
+ header\objects
+
+
+ header\debugger\commands
+
+
+ header\debugger\commands
+
+
+ header\debugger\communication
+
+
+ header\debugger\communication
+
+
+ header\debugger\communication
+
+
+ header\debugger\core
+
+
+ header\debugger\core
+
+
+ header\debugger\driver-loader
+
+
+ header\debugger\kernel-level
+
+
+ header\debugger\misc
+
+
+ header\debugger\misc
+
+
+ header\debugger\misc
+
+
+ header\debugger\user-level
+
+
+ header\debugger\user-level
+
+
+ header\debugger\transparency
+
+
+ header\debugger\tests
+
+
+ header\debugger\script-engine
+
+
+ header\debugger\script-engine
+
+
+ header\debugger\misc
@@ -190,9 +292,6 @@
code\common
-
- code\common
- code\debugger\commands\debugging-commands
@@ -580,18 +679,63 @@
code\debugger\commands\debugging-commands
-
- code\debugger\misc
-
-
- code\debugger\commands\extension-commands
- code\debugger\commands\extension-commandscode\debugger\commands\debugging-commands
+
+ code\debugger\commands\extension-commands
+
+
+ code\debugger\commands\extension-commands
+
+
+ code\debugger\commands\extension-commands
+
+
+ code\debugger\misc
+
+
+ code\debugger\commands\extension-commands
+
+
+ code\debugger\commands\extension-commands
+
+
+ code\debugger\commands\extension-commands
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\app
+
+
+ code\app
+
+
+ code\platform\windows-only
+
+
+ code\components\pe
+
+
+ code\debugger\misc
+
diff --git a/hyperdbg/libhyperdbg/pch.cpp b/hyperdbg/libhyperdbg/pch.cpp
index 92958c22..fa15fce4 100644
--- a/hyperdbg/libhyperdbg/pch.cpp
+++ b/hyperdbg/libhyperdbg/pch.cpp
@@ -14,7 +14,7 @@
//
// Global variables
//
-#include "header/globals.h"
+#include "header/globals/globals.h"
//
// When you are using pre-compiled headers, this source file is necessary for
diff --git a/hyperdbg/libhyperdbg/pch.h b/hyperdbg/libhyperdbg/pch.h
index 6017232f..6a6eaee8 100644
--- a/hyperdbg/libhyperdbg/pch.h
+++ b/hyperdbg/libhyperdbg/pch.h
@@ -14,7 +14,7 @@
//
// Environment headers
//
-#include "platform/user/header/Environment.h"
+#include "platform/general/header/Environment.h"
//
// Windows SDK headers
@@ -41,42 +41,46 @@ typedef RFLAGS * PRFLAGS;
#define USE_NATIVE_SDK_HEADERS
#define _AMD64_
-#if defined(USE__NATIVE_PHNT_HEADERS)
+#ifdef _WIN32
+# if defined(USE__NATIVE_PHNT_HEADERS)
//
// Dirty fix: the "PCWCHAR" in undefined in "ntrtl.h" so I deifined it here.
//
typedef const wchar_t *LPCWCHAR, *PCWCHAR;
-# define PHNT_MODE PHNT_MODE_USER
-# define PHNT_VERSION PHNT_WIN11 // Windows 11
-# define PHNT_PATCH_FOR_HYPERDBG TRUE
+# define PHNT_MODE PHNT_MODE_USER
+# define PHNT_VERSION PHNT_WIN11 // Windows 11
+# define PHNT_PATCH_FOR_HYPERDBG TRUE
-# include
-# include
+# include
+# include
-#elif defined(USE_NATIVE_SDK_HEADERS)
+# elif defined(USE_NATIVE_SDK_HEADERS)
-# include
-# include
-# include
-# include
+# include
+# include
+# include
+# include
+# endif
+
+#endif //_WIN32
+
+#ifdef _WIN32
+# include
+# include
+# include
+# include
+# include
+# include
+# include
+# include
+# include
+# include
+# include
#endif
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
#include
-#include
-#include
#include
#include
#include
@@ -103,6 +107,7 @@ typedef const wchar_t *LPCWCHAR, *PCWCHAR;
#include
#include
#include
+#include
//
// Scope definitions
@@ -118,11 +123,6 @@ typedef const wchar_t *LPCWCHAR, *PCWCHAR;
# define NDEBUG
#endif // !NDEBUG
-//
-// Keystone
-//
-#include "keystone/keystone.h"
-
//
// HyperDbg defined headers
//
@@ -130,6 +130,11 @@ typedef const wchar_t *LPCWCHAR, *PCWCHAR;
#include "config/Definition.h"
#include "SDK/HyperDbgSdk.h"
+//
+// Keystone
+//
+#include "keystone/keystone.h"
+
//
// Script-engine
//
@@ -141,49 +146,108 @@ typedef const wchar_t *LPCWCHAR, *PCWCHAR;
#include "SDK/imports/user/HyperDbgScriptImports.h"
#include "SDK/imports/user/HyperDbgLibImports.h"
+//
+// Platform lib calls (cross-platform wrappers)
+//
+#include "platform/user/header/platform-lib-calls.h"
+
+//
+// Platform intrinsics (cross-platform CPU instructions and atomic ops)
+//
+#include "platform/user/header/platform-intrinsics.h"
+
+//
+// Platform serial transport (cross-platform kernel-debugger serial I/O)
+//
+#include "platform/user/header/platform-serial.h"
+
+//
+// Platform IOCTL transport (cross-platform local kernel-driver device I/O)
+//
+#include "platform/user/header/platform-ioctl.h"
+
+//
+// Platform signal (cross-platform console-control / CTRL+C handler registration)
+//
+#include "platform/user/header/platform-signal.h"
+
+//
+// NT-style intrusive linked-list helpers + CONTAINING_RECORD (self-guards to
+// non-Windows; Windows gets these from / the native-SDK shim)
+//
+#include "platform/general/header/nt-list.h"
+
+//
+// Platform-specific intrinsics
+//
+#ifdef _WIN32
+# include "platform/user/header/windows-only/windows-privilege.h"
+#endif
+
//
// PCI IDs
//
-#include "pci-id.h"
+#include "header/debugger/misc/pci-id.h"
+
+//
+// Intel PT
+//
+#include "../dependencies/libipt/intel-pt.h"
//
// General
//
-#include "header/libhyperdbg.h"
-#include "header/export.h"
-#include "header/inipp.h"
-#include "header/commands.h"
-#include "header/common.h"
-#include "header/symbol.h"
-#include "header/debugger.h"
-#include "header/script-engine.h"
-#include "header/help.h"
-#include "header/install.h"
-#include "header/list.h"
-#include "header/tests.h"
-#include "header/transparency.h"
-#include "header/communication.h"
-#include "header/namedpipe.h"
-#include "header/forwarding.h"
-#include "header/kd.h"
-#include "header/pe-parser.h"
-#include "header/ud.h"
-#include "header/objects.h"
-#include "header/steppings.h"
-#include "header/rev-ctrl.h"
-#include "header/assembler.h"
+#include "header/app/libhyperdbg.h"
+#include "header/export/export.h"
+#include "header/debugger/misc/inipp.h"
+#include "header/debugger/commands/commands.h"
+#include "header/common/common.h"
+#include "header/debugger/script-engine/symbol.h"
+#include "header/debugger/misc/pt-helper.h"
+#include "header/debugger/core/debugger.h"
+#include "header/debugger/script-engine/script-engine.h"
+#include "header/debugger/commands/help.h"
+#ifdef _WIN32
+# include "header/debugger/driver-loader/install.h"
+#endif
+#include "header/common/list.h"
+#include "header/debugger/tests/tests.h"
+#include "header/app/messaging.h"
+#include "header/app/packets.h"
+#include "header/debugger/transparency/transparency.h"
+#include "header/debugger/communication/communication.h"
+#include "header/debugger/communication/namedpipe.h"
+#include "header/debugger/communication/forwarding.h"
+#include "header/debugger/kernel-level/kd.h"
+
+//
+// Components
+//
+#include "../include/components/pe/header/pe-image-reader.h"
+
+#include "header/debugger/user-level/pe-parser.h"
+#include "header/debugger/user-level/ud.h"
+#include "header/objects/objects.h"
+#include "header/debugger/core/steppings.h"
+#include "header/rev/rev-ctrl.h"
+#include "header/debugger/misc/assembler.h"
//
// hwdbg
//
-#include "header/hwdbg-interpreter.h"
-#include "header/hwdbg-scripts.h"
+#include "header/hwdbg/hwdbg-interpreter.h"
+#include "header/hwdbg/hwdbg-scripts.h"
+
+//
+// Zydis headers
+//
+#include
//
// Libraries
//
-#ifdef ENV_WINDOWS
+#ifdef HYPERDBG_ENV_WINDOWS
# pragma comment(lib, "ntdll.lib")
@@ -208,4 +272,9 @@ typedef const wchar_t *LPCWCHAR, *PCWCHAR;
# pragma comment(lib, "Psapi.lib")
# pragma comment(lib, "Kernel32.lib")
-#endif // ENV_WINDOWS
+//
+// For resolving symbols on Intel PT
+//
+# pragma comment(lib, "dbghelp.lib")
+
+#endif // HYPERDBG_ENV_WINDOWS
diff --git a/hyperdbg/libraries/libipt/libipt.dll b/hyperdbg/libraries/libipt/libipt.dll
new file mode 100644
index 00000000..7c873442
Binary files /dev/null and b/hyperdbg/libraries/libipt/libipt.dll differ
diff --git a/hyperdbg/libraries/libipt/libipt.lib b/hyperdbg/libraries/libipt/libipt.lib
new file mode 100644
index 00000000..8f04d94f
Binary files /dev/null and b/hyperdbg/libraries/libipt/libipt.lib differ
diff --git a/hyperdbg/linux/.gitignore b/hyperdbg/linux/.gitignore
new file mode 100644
index 00000000..289431e5
--- /dev/null
+++ b/hyperdbg/linux/.gitignore
@@ -0,0 +1,95 @@
+#
+# NOTE! Don't add files that are generated in specific
+# subdirectories here. Add them in the ".gitignore" file
+# in that subdirectory instead.
+#
+# NOTE! Please use 'git ls-files -i --exclude-standard'
+# command after changing this file, to see if there are
+# any tracked files which get ignored after the change.
+#
+# Normal rules
+#
+.*
+*.o
+*.o.*
+*.a
+*.s
+*.ko
+*.so
+*.so.dbg
+*.mod.c
+*.i
+*.lst
+*.symtypes
+*.order
+modules.builtin
+*.elf
+*.bin
+*.gz
+*.bz2
+*.lzma
+*.xz
+*.lzo
+*.patch
+*.gcno
+*.mod
+
+#
+# Top-level generic files
+#
+/tags
+/TAGS
+/linux
+/vmlinux
+/vmlinuz
+/System.map
+/Module.markers
+Module.symvers
+
+#
+# Debian directory (make deb-pkg)
+#
+/debian/
+
+#
+# git files that we don't want to ignore even it they are dot-files
+#
+!.gitignore
+!.mailmap
+
+#
+# Generated include files
+#
+include/config
+include/linux/version.h
+include/generated
+arch/*/include/generated
+
+# stgit generated dirs
+patches-*
+
+# quilt's files
+patches
+series
+
+# cscope files
+cscope.*
+ncscope.*
+
+# gnu global files
+GPATH
+GRTAGS
+GSYMS
+GTAGS
+
+*.orig
+*~
+\#*#
+
+#
+# Leavings from module signing
+#
+extra_certificates
+signing_key.priv
+signing_key.x509
+x509.genkey
diff --git a/hyperdbg/linux/README.md b/hyperdbg/linux/README.md
new file mode 100644
index 00000000..7071f314
--- /dev/null
+++ b/hyperdbg/linux/README.md
@@ -0,0 +1,51 @@
+# HyperDbg for Linux
+
+## Status
+
+⚠️ **HyperDbg for Linux is not yet ready.**
+
+Linux is currently **not supported**.
+
+We are in the process of porting HyperDbg to Linux. This effort is ongoing and may take some time to complete.
+
+# Contributing to the Linux Port
+
+HyperDbg is being ported from Windows to Linux. The work is incremental: most
+of the codebase compiles file-by-file as the Win32-specific calls get replaced
+with a platform-independent interface.
+
+## Building
+
+```bash
+cmake . # generate the Makefiles
+make # build
+```
+
+Run these from the repo root (or the relevant subdirectory). `cmake .` only
+needs to be re-run when the CMake files change; otherwise `make` is enough.
+
+## How to contribute
+
+The port progresses one source file at a time. To pick up work:
+
+1. Build and find the next file that fails to compile.
+2. Go through it and make it Linux-compatible.
+3. Where the code calls Windows-only APIs (serial, registry, signals,
+ threads, etc.), don't `#ifdef` inline — route the call through the
+ **platform-independent interface** so both Windows and Linux share the same
+ call site with separate backing implementations.
+4. Rebuild until the file is clean, then move to the next one.
+
+## The platform interface
+
+User-mode abstractions live in `include/platform/user/` (`header/` for the
+interface, `code/` for the implementations). See existing examples such as
+`platform-serial`, `platform-signal`, and `platform-ioctl` for the pattern to
+follow. Kernel-mode equivalents are under `include/platform/kernel/`.
+
+## Guidelines
+
+- Keep platform-specific code behind the platform abstraction, not scattered
+ through the logic.
+- Match the surrounding code's style and conventions.
+- Build before submitting — every changed file should compile.
\ No newline at end of file
diff --git a/hyperdbg/linux/mock/kernel/.gitignore b/hyperdbg/linux/mock/kernel/.gitignore
new file mode 100644
index 00000000..69180853
--- /dev/null
+++ b/hyperdbg/linux/mock/kernel/.gitignore
@@ -0,0 +1,7 @@
+# Ignore all C source and header files copied into this directory
+*.c
+*.h
+
+# Except the files that permanently live here
+!mock.c
+!pch.h
\ No newline at end of file
diff --git a/hyperdbg/linux/mock/kernel/Makefile b/hyperdbg/linux/mock/kernel/Makefile
new file mode 100644
index 00000000..b8e5c4e6
--- /dev/null
+++ b/hyperdbg/linux/mock/kernel/Makefile
@@ -0,0 +1,27 @@
+KDIR := /lib/modules/$(shell uname -r)/build
+PWD := $(shell pwd)
+obj-m := HyperDbg.o
+HyperDbg-objs := mock.o \
+ PlatformMem.o \
+ PlatformIntrinsicsVmx.o \
+ PlatformIntrinsics.o
+
+ccflags-y += -I$(PWD)/../../../include
+ccflags-y += -I$(PWD)/../../../include/platform/kernel/header
+ccflags-y += -I$(PWD)/../../../include/platform/kernel/code
+
+all: clean PlatformMem.c PlatformIntrinsicsVmx.c PlatformIntrinsics.c
+ $(MAKE) -C $(KDIR) M=$(PWD) modules
+
+PlatformMem.c:
+ cp ../../../include/platform/kernel/code/PlatformMem.c $(PWD)/PlatformMem.c
+PlatformIntrinsics.c:
+ cp ../../../include/platform/kernel/code/PlatformIntrinsics.c $(PWD)/PlatformIntrinsics.c
+PlatformIntrinsicsVmx.c:
+ cp ../../../include/platform/kernel/code/PlatformIntrinsicsVmx.c $(PWD)/PlatformIntrinsicsVmx.c
+
+clean:
+ $(MAKE) -C $(KDIR) M=$(PWD) clean
+ rm -f $(PWD)/PlatformMem.c
+ rm -f $(PWD)/PlatformIntrinsics.c
+ rm -f $(PWD)/PlatformIntrinsicsVmx.c
\ No newline at end of file
diff --git a/hyperdbg/linux/mock/kernel/README.md b/hyperdbg/linux/mock/kernel/README.md
new file mode 100644
index 00000000..37864ebf
--- /dev/null
+++ b/hyperdbg/linux/mock/kernel/README.md
@@ -0,0 +1,92 @@
+# HyperDbg Linux Kernel Module
+
+This directory contains a Linux kernel module that demonstrates and tests the
+cross-platform memory management APIs (`PlatformMem.c`) from the HyperDbg project.
+
+The module provides a simple test harness (`mock.c`) that exercises memory
+allocation, copy, and deallocation functions in kernel space
+
+---
+## Prerequisites
+Before building the module, ensure you have the necessary development tools
+and kernel headers installed:
+
+```bash
+# Install build essentials and kernel module utilities
+sudo apt-get update
+sudo apt-get install build-essential kmod
+
+# Install kernel headers for your running kernel
+sudo apt-get install linux-headers-`uname -r`
+```
+
+---
+# project structure
+
+```
+hyperdbg/
+ ├── include/
+ │ └── platform/
+ │ └── kernel/
+ │ ├── header/
+ │ └── code/
+ └── linux/
+ └── mock/
+ ├── Makefile
+ ├── mock.c
+ └── HyperDbg.ko
+
+```
+
+
+
+---
+## Build the Module
+```bash
+cd hyperdbg/linux/mock
+```
+
+then build module:
+```bash
+make
+```
+
+If successful, this will generate:
+
+```bash
+HyperDbg.ko
+```
+---
+# Load the Module
+
+to insert the module into the kernel:
+
+```bash
+sudo insmod HyperDbg.ko
+```
+
+---
+# Verify Module Loaded Successfully
+
+you can use `lsmod` :
+```bash
+lsmod | grep HyperDbg
+```
+
+or you can inspect kernel module:
+```bash
+sudo dmesg | tail -10
+```
+---
+# Remove the Module
+```bash
+sudo rmmod HyperDbg
+```
+
+---
+
+# finally you can clean project:
+```bash
+make clean
+```
+
diff --git a/hyperdbg/linux/mock/kernel/mock.c b/hyperdbg/linux/mock/kernel/mock.c
new file mode 100644
index 00000000..47d0d516
--- /dev/null
+++ b/hyperdbg/linux/mock/kernel/mock.c
@@ -0,0 +1,104 @@
+/**
+ * @file mock.c
+ * @author Alireza moradi (alish014)
+ * @brief Mock Linux kernel module for testing cross-platform memory APIs.
+ * @details This file demonstrates the usage of the unified Platform* memory
+ * API (Allocate, Write, Set, Free) within a Linux kernel module environment.
+ * @version 0.18
+ * @date 2026-02-05
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ */
+#include "pch.h"
+
+/**
+ * @brief Global pointer to the allocated test buffer.
+ * @details Stores the address returned by PlatformAllocateMemory so it can be
+ * freed when the module unloads.
+ */
+static PVOID g_AllocatedBuffer = NULL;
+
+/**
+ * @brief Size of the buffer to allocate during tests.
+ * @note Default size is 4096 bytes (1 page).
+ */
+static SIZE_T g_BufferSize = 4096;
+
+/**
+ * @brief Module initialization entry point.
+ *
+ * @details Performs the following test sequence:
+ * 1. Allocates memory using the cross-platform wrapper.
+ * 2. Copies a test string into the allocated memory.
+ * 3. Prints the content to the kernel log.
+ * 4. Zeroes out the memory contents.
+ *
+ * @return int
+ * - 0: Initialization successful.
+ * - -ENOMEM: Memory allocation failed.
+ */
+static int __init
+mock_init(void)
+{
+ char source_data[] = "This is a test string from Linux kernel module";
+
+ printk(KERN_INFO "Mock module loading\n");
+
+ // 1. Allocation
+ g_AllocatedBuffer = PlatformAllocateMemory(g_BufferSize);
+ if (!g_AllocatedBuffer)
+ return -ENOMEM;
+
+ // 2. Copying (Write Memory)
+ // We pass NULL for 'Process' as the current implementation targets local kernel memory.
+ PlatformWriteMemory(g_AllocatedBuffer, source_data, sizeof(source_data));
+
+ printk(KERN_INFO "Copied data: %s\n", (char *)g_AllocatedBuffer);
+
+ // 3. Zeroing (Set Memory)
+ PlatformSetMemory(g_AllocatedBuffer, 0, g_BufferSize);
+
+ printk(KERN_INFO "Buffer zeroed\n");
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // Test codes (should be removed if running this kernel module)
+ //
+
+ VmxVmread64(0, 0); // Just to test the intrinsic wrapper compiles and links correctly
+
+ CpuReadMsr(0x1); // Just to test the intrinsic wrapper compiles and links correctly
+
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ return 0;
+}
+
+/**
+ * @brief Module cleanup/exit entry point.
+ *
+ * @details Frees the global buffer allocated during initialization to prevent
+ * memory leaks.
+ *
+ * @return void
+ */
+static void __exit
+mock_exit(void)
+{
+ printk(KERN_INFO "Mock module unloading\n");
+
+ // 4. Freeing
+ if (g_AllocatedBuffer)
+ {
+ PlatformFreeMemory(g_AllocatedBuffer);
+ g_AllocatedBuffer = NULL; // Good practice to nullify after free
+ }
+}
+
+// Register entry and exit points
+module_init(mock_init);
+module_exit(mock_exit);
+
+// Module Metadata
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alireza Moradi");
+MODULE_DESCRIPTION("Cross-platform memory API test module");
diff --git a/hyperdbg/linux/mock/kernel/pch.h b/hyperdbg/linux/mock/kernel/pch.h
new file mode 100644
index 00000000..d581b542
--- /dev/null
+++ b/hyperdbg/linux/mock/kernel/pch.h
@@ -0,0 +1,39 @@
+/**
+ * @file pch.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Pre-compiled headers for Linux mock
+ * @details
+ * @version 0.19
+ * @date 2026-04-27
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+
+//
+// Scope definitions
+//
+#define HYPERDBG_KERNEL_MODE
+#define HYPERDBG_LINUX
+
+//
+// General Linux driver headers
+//
+#include
+
+//
+// SDK headers
+//
+#include "../../../include/SDK/HyperDbgSdk.h"
+
+//
+// Environment headers
+//
+#include "../../../include/platform/general/header/Environment.h"
+
+//
+// Platform headers
+//
+#include "../../../include/platform/kernel/header/PlatformMem.h"
+#include "../../../include/platform/kernel/header/PlatformIntrinsics.h"
+#include "../../../include/platform/kernel/header/PlatformIntrinsicsVmx.h"
diff --git a/hyperdbg/linux/mock/user/Makefile b/hyperdbg/linux/mock/user/Makefile
new file mode 100644
index 00000000..229a6c0c
--- /dev/null
+++ b/hyperdbg/linux/mock/user/Makefile
@@ -0,0 +1,27 @@
+CC = gcc
+PWD := $(shell pwd)
+CFLAGS = -Wall -Wextra -std=c11 -O2
+CFLAGS += -I$(PWD)/../../../include
+CFLAGS += -I$(PWD)/../../../include/platform/user/header
+CFLAGS += -I$(PWD)/../../../include/platform/user/code
+TARGET = mock
+SRCS = mock.c \
+ platform-intrinsics.c
+OBJS = $(SRCS:.c=.o)
+
+.PHONY: all clean
+
+all: clean platform-intrinsics.c $(TARGET)
+
+$(TARGET): $(OBJS)
+ $(CC) $(CFLAGS) -o $@ $^
+
+%.o: %.c pch.h
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+platform-intrinsics.c:
+ cp $(PWD)/../../../include/platform/user/code/platform-intrinsics.c $(PWD)/platform-intrinsics.c
+
+clean:
+ rm -f $(OBJS) $(TARGET)
+ rm -f $(PWD)/platform-intrinsics.c
\ No newline at end of file
diff --git a/hyperdbg/linux/mock/user/README.md b/hyperdbg/linux/mock/user/README.md
new file mode 100644
index 00000000..3fa5fc70
--- /dev/null
+++ b/hyperdbg/linux/mock/user/README.md
@@ -0,0 +1,53 @@
+# mock — HyperDbg Hello World
+
+A minimal user-mode Linux application that prints **"Hello world HyperDbg!"** to stdout and imports HyperDbg SDK.
+
+---
+
+---
+
+## Requirements
+
+- GCC (any reasonably recent version)
+- GNU Make
+- Linux (user-mode, no special privileges needed)
+
+Install on Debian/Ubuntu:
+
+```bash
+sudo apt update && sudo apt install build-essential
+```
+
+---
+
+## Build
+
+```bash
+make
+```
+
+This compiles `mock.c` into an executable called `mock`.
+
+---
+
+## Run
+
+```bash
+./mock
+```
+
+Expected output:
+
+```
+Hello world HyperDbg!
+```
+
+---
+
+## Clean
+
+Remove compiled objects and the binary:
+
+```bash
+make clean
+```
diff --git a/hyperdbg/linux/mock/user/mock.c b/hyperdbg/linux/mock/user/mock.c
new file mode 100644
index 00000000..fea47233
--- /dev/null
+++ b/hyperdbg/linux/mock/user/mock.c
@@ -0,0 +1,29 @@
+/**
+ * @file mock.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Mock user-mode application for testing the HyperDbg
+ * @details
+ * @version 0.19
+ * @date 2026-04-28
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+int
+main(void)
+{
+ printf("Hello world HyperDbg!\n");
+
+ //////////////////////////////////////////////////////////////
+ //
+ // Test for working intrinsics
+ //
+ CpuReadTsc();
+ CpuCpuId(NULL, 0);
+
+ //////////////////////////////////////////////////////////////
+
+ return 0;
+}
diff --git a/hyperdbg/linux/mock/user/pch.h b/hyperdbg/linux/mock/user/pch.h
new file mode 100644
index 00000000..6bc2c282
--- /dev/null
+++ b/hyperdbg/linux/mock/user/pch.h
@@ -0,0 +1,37 @@
+/**
+ * @file mock.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Header for the mock user-mode application for testing the HyperDbg
+ * @details
+ * @version 0.19
+ * @date 2026-04-28
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#ifndef PCH_H
+#define PCH_H
+
+//
+// Scope definitions
+//
+#define HYPERDBG_USER_MODE
+#define HYPERDBG_LINUX
+
+#include
+#include
+#include
+#include
+#include
+
+//
+// SDK headers
+//
+#include "../../../include/SDK/HyperDbgSdk.h"
+
+//
+// Platform headers
+//
+#include "../../../include/platform/user/header/platform-intrinsics.h"
+
+#endif // PCH_H
diff --git a/hyperdbg/script-engine/CMakeLists.txt b/hyperdbg/script-engine/CMakeLists.txt
index 367a8b7b..85623bea 100644
--- a/hyperdbg/script-engine/CMakeLists.txt
+++ b/hyperdbg/script-engine/CMakeLists.txt
@@ -1,20 +1,20 @@
# Code generated by Visual Studio kit, DO NOT EDIT.
set(SourceFiles
- "../include/platform/user/header/Environment.h"
+ "../include/platform/general/header/Environment.h"
"header/common.h"
"header/globals.h"
"header/parse-table.h"
"header/scanner.h"
"header/script-engine.h"
"header/type.h"
- "pch.h"
+ "header/pch.h"
"code/common.c"
"code/globals.c"
"code/parse-table.c"
"code/scanner.c"
"code/script-engine.c"
"code/type.c"
- "pch.c"
+ "code/pch.c"
)
include_directories(
"header"
diff --git a/hyperdbg/script-engine/code/common.c b/hyperdbg/script-engine/code/common.c
index 0bb71e7a..33118985 100644
--- a/hyperdbg/script-engine/code/common.c
+++ b/hyperdbg/script-engine/code/common.c
@@ -14,7 +14,7 @@
/**
* @brief Allocates a new token
*
- * @return Token
+ * @return PSCRIPT_ENGINE_TOKEN the allocated new unknown token
*/
PSCRIPT_ENGINE_TOKEN
NewUnknownToken()
@@ -49,14 +49,22 @@ NewUnknownToken()
// Init fields
//
strcpy(Token->Value, "");
- Token->Type = UNKNOWN;
- Token->Len = 0;
- Token->MaxLen = TOKEN_VALUE_MAX_LEN;
- Token->VariableType = 0;
+ Token->Type = UNKNOWN;
+ Token->Len = 0;
+ Token->MaxLen = TOKEN_VALUE_MAX_LEN;
+ Token->VariableType = (VARIABLE_TYPE *)VARIABLE_TYPE_LONG;
+ Token->VariableMemoryIdx = 0;
return Token;
}
+/**
+ * @brief Allocates a new token with given type and value
+ *
+ * @param Type the type of the token
+ * @param Value the value string of the token
+ * @return PSCRIPT_ENGINE_TOKEN the allocated new token
+ */
PSCRIPT_ENGINE_TOKEN
NewToken(SCRIPT_ENGINE_TOKEN_TYPE Type, char * Value)
{
@@ -76,12 +84,13 @@ NewToken(SCRIPT_ENGINE_TOKEN_TYPE Type, char * Value)
//
// Init fields
//
- unsigned int Len = (unsigned int)strlen(Value);
- Token->Type = Type;
- Token->Len = Len;
- Token->MaxLen = Len;
- Token->Value = (char *)calloc(Token->MaxLen + 1, sizeof(char));
- Token->VariableType = 0;
+ unsigned int Len = (unsigned int)strlen(Value);
+ Token->Type = Type;
+ Token->Len = Len;
+ Token->MaxLen = Len;
+ Token->Value = (char *)calloc(Token->MaxLen + 1, sizeof(char));
+ Token->VariableType = (VARIABLE_TYPE *)VARIABLE_TYPE_LONG;
+ Token->VariableMemoryIdx = 0;
if (Token->Value == NULL)
{
@@ -101,6 +110,7 @@ NewToken(SCRIPT_ENGINE_TOKEN_TYPE Type, char * Value)
* @brief Removes allocated memory of a token
*
* @param Token
+ * @return void
*/
void
RemoveToken(PSCRIPT_ENGINE_TOKEN * Token)
@@ -113,9 +123,10 @@ RemoveToken(PSCRIPT_ENGINE_TOKEN * Token)
/**
* @brief Prints token
- * @detail prints value and type of token
+ * @details prints value and type of token
*
- * @param Token
+ * @param Token the token to print
+ * @return void
*/
void
PrintToken(PSCRIPT_ENGINE_TOKEN Token)
@@ -212,6 +223,9 @@ PrintToken(PSCRIPT_ENGINE_TOKEN Token)
case FUNCTION_PARAMETER_ID:
printf(" FUNCTION_PARAMETER_ID>\n");
break;
+ case DEFERENCE_TEMP:
+ printf(" DEFERENCE_TEMP>\n");
+ break;
default:
printf(" ERROR>\n");
break;
@@ -222,7 +236,8 @@ PrintToken(PSCRIPT_ENGINE_TOKEN Token)
* @brief Appends char to the token value
*
* @param Token
- * @param char
+ * @param c the character to append
+ * @return void
*/
void
AppendByte(PSCRIPT_ENGINE_TOKEN Token, char c)
@@ -263,7 +278,8 @@ AppendByte(PSCRIPT_ENGINE_TOKEN Token, char c)
* @brief Appends wchar_t to the token value
*
* @param Token
- * @param char
+ * @param c the wide character to append
+ * @return void
*/
void
AppendWchar(PSCRIPT_ENGINE_TOKEN Token, wchar_t c)
@@ -303,7 +319,8 @@ AppendWchar(PSCRIPT_ENGINE_TOKEN Token, wchar_t c)
/**
* @brief Copies a PTOKEN
*
- * @return PTOKEN
+ * @param Token the token to copy
+ * @return PSCRIPT_ENGINE_TOKEN the copied token
*/
PSCRIPT_ENGINE_TOKEN
CopyToken(PSCRIPT_ENGINE_TOKEN Token)
@@ -339,9 +356,9 @@ CopyToken(PSCRIPT_ENGINE_TOKEN Token)
}
/**
- * allocates a new SCRIPT_ENGINE_TOKEN_LIST
+ * @brief Allocates a new SCRIPT_ENGINE_TOKEN_LIST
*
- * @return SCRIPT_ENGINE_TOKEN_LIST
+ * @return PSCRIPT_ENGINE_TOKEN_LIST the allocated token list
*/
PSCRIPT_ENGINE_TOKEN_LIST
NewTokenList(void)
@@ -379,6 +396,7 @@ NewTokenList(void)
* @brief Removes allocated memory of a SCRIPT_ENGINE_TOKEN_LIST
*
* @param TokenList
+ * @return void
*/
void
RemoveTokenList(PSCRIPT_ENGINE_TOKEN_LIST TokenList)
@@ -399,6 +417,7 @@ RemoveTokenList(PSCRIPT_ENGINE_TOKEN_LIST TokenList)
* @brief Prints each Token inside a TokenList
*
* @param TokenList
+ * @return void
*/
void
PrintTokenList(PSCRIPT_ENGINE_TOKEN_LIST TokenList)
@@ -414,9 +433,9 @@ PrintTokenList(PSCRIPT_ENGINE_TOKEN_LIST TokenList)
/**
* @brief Adds Token to the last empty position of TokenList
*
- * @param Token
- * @param TokenList
- * @return TokenList
+ * @param TokenList the token list to push into
+ * @param Token the token to add
+ * @return PSCRIPT_ENGINE_TOKEN_LIST
*/
PSCRIPT_ENGINE_TOKEN_LIST
Push(PSCRIPT_ENGINE_TOKEN_LIST TokenList, PSCRIPT_ENGINE_TOKEN Token)
@@ -477,7 +496,7 @@ Push(PSCRIPT_ENGINE_TOKEN_LIST TokenList, PSCRIPT_ENGINE_TOKEN Token)
* @brief Removes last Token of a TokenList and returns it
*
* @param TokenList
- @ @return Token
+ * @return PSCRIPT_ENGINE_TOKEN
*/
PSCRIPT_ENGINE_TOKEN
Pop(PSCRIPT_ENGINE_TOKEN_LIST TokenList)
@@ -498,7 +517,7 @@ Pop(PSCRIPT_ENGINE_TOKEN_LIST TokenList)
* @brief Returns last Token of a TokenList
*
* @param TokenList
- * @return Token
+ * @return PSCRIPT_ENGINE_TOKEN
*/
PSCRIPT_ENGINE_TOKEN
Top(PSCRIPT_ENGINE_TOKEN_LIST TokenList)
@@ -513,10 +532,27 @@ Top(PSCRIPT_ENGINE_TOKEN_LIST TokenList)
return *ReadAddr;
}
+/**
+ * @brief Returns the token at a specific index from the top of the token list
+ *
+ * @param TokenList the token list to index into
+ * @param Index the zero-based index from the top
+ * @return PSCRIPT_ENGINE_TOKEN
+ */
+PSCRIPT_ENGINE_TOKEN
+TopIndexed(PSCRIPT_ENGINE_TOKEN_LIST TokenList, int Index)
+{
+ uintptr_t Head = (uintptr_t)TokenList->Head;
+ uintptr_t Pointer = (uintptr_t)TokenList->Pointer - 1 - Index;
+ PSCRIPT_ENGINE_TOKEN * ReadAddr = (PSCRIPT_ENGINE_TOKEN *)(Head + Pointer * sizeof(PSCRIPT_ENGINE_TOKEN));
+
+ return *ReadAddr;
+}
+
/**
* @brief Checks whether input char belongs to hexadecimal digit-set or not
*
- * @param char
+ * @param c the character to check
* @return char
*/
char
@@ -531,7 +567,7 @@ IsHex(char c)
/**
* @brief Checks whether input char belongs to decimal digit-set or not
*
- * @param char
+ * @param c the character to check
* @return char
*/
char
@@ -546,7 +582,7 @@ IsDecimal(char c)
/**
* @brief Checks whether input char belongs to alphabet set or not
*
- * @param char
+ * @param c the character to check
* @return char
*/
char
@@ -563,7 +599,7 @@ IsLetter(char c)
/**
* @brief Checks whether input char is underscore (_) or not
*
- * @param char
+ * @param c the character to check
* @return char
*/
char
@@ -580,8 +616,8 @@ IsUnderscore(char c)
/**
* @brief Checks whether input char belongs to binary digit-set or not
*
- * @param char
- * @return bool
+ * @param c the character to check
+ * @return char
*/
char
IsBinary(char c)
@@ -597,7 +633,7 @@ IsBinary(char c)
/**
* @brief Checks whether input char belongs to octal digit-set or not
*
- * @param char
+ * @param c the character to check
* @return char
*/
char
@@ -612,8 +648,8 @@ IsOctal(char c)
/**
* @brief Allocates a new temporary variable and returns it
*
- * @param Error
- * @return PTOKEN
+ * @param Error the error type pointer
+ * @return PSCRIPT_ENGINE_TOKEN
*/
PSCRIPT_ENGINE_TOKEN
NewTemp(PSCRIPT_ENGINE_ERROR_TYPE Error)
@@ -650,22 +686,23 @@ NewTemp(PSCRIPT_ENGINE_ERROR_TYPE Error)
/**
* @brief Frees the memory allocated by Temp
*
- * @param Temp
+ * @param Temp the token representing the temporary variable
+ * @return VOID
*/
-void
+VOID
FreeTemp(PSCRIPT_ENGINE_TOKEN Temp)
{
- int id = (int)DecimalToInt(Temp->Value);
- if (Temp->Type == TEMP)
+ INT Id = (INT)DecimalToInt(Temp->Value);
+ if (Temp->Type == TEMP || Temp->Type == DEFERENCE_TEMP)
{
- CurrentUserDefinedFunction->TempMap[id] = 0;
+ CurrentUserDefinedFunction->TempMap[Id] = 0;
}
}
/**
* @brief Checks whether this Token type is OneOpFunc1
*
- * @param Operator
+ * @param Operator the token to check
* @return char
*/
char
@@ -685,7 +722,7 @@ IsType1Func(PSCRIPT_ENGINE_TOKEN Operator)
/**
* @brief Checks whether this Token type is OneOpFunc2
*
- * @param Operator
+ * @param Operator the token to check
* @return char
*/
char
@@ -705,7 +742,7 @@ IsType2Func(PSCRIPT_ENGINE_TOKEN Operator)
/**
* @brief Checks whether this Token type is OperatorsTwoOperandList
*
- * @param Operator
+ * @param Operator the token to check
* @return char
*/
char
@@ -725,7 +762,7 @@ IsTwoOperandOperator(PSCRIPT_ENGINE_TOKEN Operator)
/**
* @brief Checks whether this Token type is OperatorsOneOperandList
*
- * @param Operator
+ * @param Operator the token to check
* @return char
*/
char
@@ -745,7 +782,7 @@ IsOneOperandOperator(PSCRIPT_ENGINE_TOKEN Operator)
/**
* @brief Checks whether this Token type is VarArgFunc1
*
- * @param Operator
+ * @param Operator the token to check
* @return char
*/
char
@@ -765,7 +802,7 @@ IsType4Func(PSCRIPT_ENGINE_TOKEN Operator)
/**
* @brief Checks whether this Token type is ZeroOpFunc1
*
- * @param Operator
+ * @param Operator the token to check
* @return char
*/
char
@@ -785,7 +822,7 @@ IsType5Func(PSCRIPT_ENGINE_TOKEN Operator)
/**
* @brief Checks whether this Token type is TwoOpFunc1
*
- * @param Operator
+ * @param Operator the token to check
* @return char
*/
char
@@ -805,7 +842,7 @@ IsType6Func(PSCRIPT_ENGINE_TOKEN Operator)
/**
* @brief Checks whether this Token type is TwoOpFunc2
*
- * @param Operator
+ * @param Operator the token to check
* @return char
*/
char
@@ -825,7 +862,7 @@ IsType7Func(PSCRIPT_ENGINE_TOKEN Operator)
/**
* @brief Checks whether this Token type is ThreeOpFunc1
*
- * @param Operator
+ * @param Operator the token to check
* @return char
*/
char
@@ -845,7 +882,7 @@ IsType8Func(PSCRIPT_ENGINE_TOKEN Operator)
/**
* @brief Checks whether this Token type is OneOpFunc3
*
- * @param Operator
+ * @param Operator the token to check
* @return char
*/
char
@@ -865,7 +902,7 @@ IsType9Func(PSCRIPT_ENGINE_TOKEN Operator)
/**
* @brief Checks whether this Token type is TwoOpFunc3
*
- * @param Operator
+ * @param Operator the token to check
* @return char
*/
char
@@ -885,7 +922,7 @@ IsType10Func(PSCRIPT_ENGINE_TOKEN Operator)
/**
* @brief Checks whether this Token type is ThreeOpFunc3
*
- * @param Operator
+ * @param Operator the token to check
* @return char
*/
char
@@ -905,7 +942,7 @@ IsType11Func(PSCRIPT_ENGINE_TOKEN Operator)
/**
* @brief Checks whether this Token type is OneOpFunc4
*
- * @param Operator
+ * @param Operator the token to check
* @return char
*/
char
@@ -925,7 +962,7 @@ IsType12Func(PSCRIPT_ENGINE_TOKEN Operator)
/**
* @brief Checks whether this Token type is TwoOpFunc4
*
- * @param Operator
+ * @param Operator the token to check
* @return char
*/
char
@@ -945,7 +982,7 @@ IsType13Func(PSCRIPT_ENGINE_TOKEN Operator)
/**
* @brief Checks whether this Token type is ThreeOpFunc2
*
- * @param Operator
+ * @param Operator the token to check
* @return char
*/
char
@@ -965,7 +1002,7 @@ IsType14Func(PSCRIPT_ENGINE_TOKEN Operator)
/**
* @brief Checks whether this Token type is ThreeOpFunc4
*
- * @param Operator
+ * @param Operator the token to check
* @return char
*/
char
@@ -985,7 +1022,7 @@ IsType15Func(PSCRIPT_ENGINE_TOKEN Operator)
/**
* @brief Checks whether this Token type is ZeroOpFunc2
*
- * @param Operator
+ * @param Operator the token to check
* @return char
*/
char
@@ -1003,9 +1040,9 @@ IsType16Func(PSCRIPT_ENGINE_TOKEN Operator)
}
/**
- * @brief Checks whether this Token type is assignemnt operator
+ * @brief Checks whether this Token type is assignment operator
*
- * @param Operator
+ * @param Operator the token to check
* @return char
*/
char
@@ -1026,7 +1063,7 @@ IsAssignmentOperator(PSCRIPT_ENGINE_TOKEN Operator)
* @brief Checks whether this Token is noneterminal
* NoneTerminal token starts with capital letter
*
- * @param Token
+ * @param Token the token to check
* @return char
*/
char
@@ -1042,7 +1079,7 @@ IsNoneTerminal(PSCRIPT_ENGINE_TOKEN Token)
* @brief Checks whether this Token is semantic rule
* SemanticRule token starts with '@'
*
- * @param Token
+ * @param Token the token to check
* @return char
*/
char
@@ -1057,8 +1094,8 @@ IsSemanticRule(PSCRIPT_ENGINE_TOKEN Token)
/**
* @brief Gets the Non Terminal Id object
*
- * @param Token
- * @return int
+ * @param Token the token to get the non-terminal ID of
+ * @return int the non-terminal ID or INVALID
*/
int
GetNonTerminalId(PSCRIPT_ENGINE_TOKEN Token)
@@ -1074,8 +1111,8 @@ GetNonTerminalId(PSCRIPT_ENGINE_TOKEN Token)
/**
* @brief Gets the Terminal Id object
*
- * @param Token
- * @return int
+ * @param Token the token to get the terminal ID of
+ * @return int the terminal ID or INVALID
*/
int
GetTerminalId(PSCRIPT_ENGINE_TOKEN Token)
@@ -1183,8 +1220,8 @@ GetTerminalId(PSCRIPT_ENGINE_TOKEN Token)
/**
* @brief Gets the Non Terminal Id object
*
- * @param Token
- * @return int
+ * @param Token the token to get the non-terminal ID of
+ * @return int the non-terminal ID or INVALID
*/
int
LalrGetNonTerminalId(PSCRIPT_ENGINE_TOKEN Token)
@@ -1200,8 +1237,8 @@ LalrGetNonTerminalId(PSCRIPT_ENGINE_TOKEN Token)
/**
* @brief Gets the Terminal Id object
*
- * @param Token
- * @return int
+ * @param Token the token to get the terminal ID of
+ * @return int the terminal ID or INVALID
*/
int
LalrGetTerminalId(PSCRIPT_ENGINE_TOKEN Token)
@@ -1302,8 +1339,8 @@ LalrGetTerminalId(PSCRIPT_ENGINE_TOKEN Token)
/**
* @brief Checks whether the value and type of Token1 and Token2 are the same
*
- * @param Token1
- * @param Token2
+ * @param Token1 the first token to compare
+ * @param Token2 the second token to compare
* @return char
*/
char
@@ -1349,6 +1386,7 @@ IsEqual(const PSCRIPT_ENGINE_TOKEN Token1, const PSCRIPT_ENGINE_TOKEN Token2)
*
* @param Val
* @param Type
+ * @return void
*/
void
SetType(unsigned long long * Val, unsigned char Type)
@@ -1359,14 +1397,14 @@ SetType(unsigned long long * Val, unsigned char Type)
/**
* @brief Converts an decimal string to a integer
*
- * @param str
+ * @param str the decimal string to convert
* @return unsigned long long int
*/
unsigned long long
DecimalToInt(char * str)
{
unsigned long long Acc = 0;
- size_t Len;
+ SIZE_T Len;
Len = strlen(str);
for (int i = 0; i < Len; i++)
@@ -1380,14 +1418,14 @@ DecimalToInt(char * str)
/**
* @brief Converts an decimal string to a signed integer
*
- * @param str
+ * @param str the decimal string to convert
* @return unsigned long long
*/
unsigned long long
DecimalToSignedInt(char * str)
{
long long Acc = 0;
- size_t Len;
+ SIZE_T Len;
if (str[0] == '-')
{
@@ -1414,31 +1452,31 @@ DecimalToSignedInt(char * str)
/**
* @brief Converts an hexadecimal string to integer
*
- * @param str
+ * @param str the hexadecimal string to convert
* @return unsigned long long
*/
unsigned long long
HexToInt(char * str)
{
- char temp;
- size_t len = strlen(str);
+ CHAR Temp;
+ SIZE_T Len = strlen(str);
unsigned long long Acc = 0;
- for (int i = 0; i < len; i++)
+ for (int i = 0; i < Len; i++)
{
Acc <<= 4;
if (str[i] >= '0' && str[i] <= '9')
{
- temp = str[i] - '0';
+ Temp = str[i] - '0';
}
else if (str[i] >= 'a' && str[i] <= 'f')
{
- temp = str[i] - 'a' + 10;
+ Temp = str[i] - 'a' + 10;
}
else
{
- temp = str[i] - 'A' + 10;
+ Temp = str[i] - 'A' + 10;
}
- Acc += temp;
+ Acc += Temp;
}
return Acc;
@@ -1447,13 +1485,13 @@ HexToInt(char * str)
/**
* @brief Converts an octal string to integer
*
- * @param str
+ * @param str the octal string to convert
* @return unsigned long long
*/
unsigned long long
OctalToInt(char * str)
{
- size_t Len;
+ SIZE_T Len;
unsigned long long Acc = 0;
Len = strlen(str);
@@ -1469,13 +1507,13 @@ OctalToInt(char * str)
/**
* @brief Converts a binary string to integer
*
- * @param str
+ * @param str the binary string to convert
* @return unsigned long long
*/
unsigned long long
BinaryToInt(char * str)
{
- size_t Len;
+ SIZE_T Len;
unsigned long long Acc = 0;
Len = strlen(str);
@@ -1491,16 +1529,17 @@ BinaryToInt(char * str)
/**
* @brief Rotate a character array to the left by one time
*
- * @param str
+ * @param str the string to rotate
+ * @return void
*/
void
RotateLeftStringOnce(char * str)
{
- int length = (int)strlen(str);
- char temp = str[0];
- for (int i = 0; i < (length - 1); i++)
+ INT Length = (INT)strlen(str);
+ CHAR Temp = str[0];
+ for (int i = 0; i < (Length - 1); i++)
{
str[i] = str[i + 1];
}
- str[length - 1] = temp;
+ str[Length - 1] = Temp;
}
diff --git a/hyperdbg/script-engine/code/globals.c b/hyperdbg/script-engine/code/globals.c
index ac0c47de..af68d655 100644
--- a/hyperdbg/script-engine/code/globals.c
+++ b/hyperdbg/script-engine/code/globals.c
@@ -10,3 +10,15 @@
*
*/
#include "pch.h"
+
+PSCRIPT_ENGINE_TOKEN_LIST GlobalIdTable;
+PUSER_DEFINED_FUNCTION_NODE UserDefinedFunctionHead;
+PUSER_DEFINED_FUNCTION_NODE CurrentUserDefinedFunction;
+PINCLUDE_NODE IncludeHead;
+unsigned int InputIdx;
+unsigned int CurrentLine;
+unsigned int CurrentLineIdx;
+unsigned int CurrentTokenIdx;
+HWDBG_INSTANCE_INFORMATION g_HwdbgInstanceInfo;
+BOOLEAN g_HwdbgInstanceInfoIsValid;
+PVOID g_MessageHandler;
diff --git a/hyperdbg/script-engine/code/hardware.c b/hyperdbg/script-engine/code/hardware.c
index d12a0245..2b986898 100644
--- a/hyperdbg/script-engine/code/hardware.c
+++ b/hyperdbg/script-engine/code/hardware.c
@@ -12,7 +12,7 @@
#include "pch.h"
/**
- * @brief Shows the script capablities of the target debuggee
+ * @brief Shows the script capabilities of the target debuggee
*
* @param InstanceInfo
*
@@ -21,7 +21,7 @@
VOID
HardwareScriptInterpreterShowScriptCapabilities(HWDBG_INSTANCE_INFORMATION * InstanceInfo)
{
- ShowMessages("\nThis debuggee supports the following operatiors:\n");
+ ShowMessages("\nThis debuggee supports the following operators:\n");
ShowMessages("\tlocal and global variable assignments: %s (maximum number of var: %d) \n",
InstanceInfo->scriptCapabilities.assign_local_global_var ? "supported" : "not supported",
InstanceInfo->numberOfSupportedLocalAndGlobalVariables);
@@ -67,7 +67,7 @@ HardwareScriptInterpreterShowScriptCapabilities(HWDBG_INSTANCE_INFORMATION * Ins
}
/**
- * @brief Check the script capablities with the target script buffer
+ * @brief Check the script capabilities with the target script buffer
*
* @param InstanceInfo
* @param ScriptBuffer
@@ -76,7 +76,7 @@ HardwareScriptInterpreterShowScriptCapabilities(HWDBG_INSTANCE_INFORMATION * Ins
* @param NumberOfOperands
* @param NumberOfOperandsImplemented
*
- * @return BOOLEAN TRUE if the script capablities support the script, otherwise FALSE
+ * @return BOOLEAN TRUE if the script capabilities support the script, otherwise FALSE
*/
BOOLEAN
HardwareScriptInterpreterCheckScriptBufferWithScriptCapabilities(HWDBG_INSTANCE_INFORMATION * InstanceInfo,
diff --git a/hyperdbg/script-engine/code/parse-table.c b/hyperdbg/script-engine/code/parse-table.c
index d8210e29..d5ae0383 100644
--- a/hyperdbg/script-engine/code/parse-table.c
+++ b/hyperdbg/script-engine/code/parse-table.c
@@ -14,6 +14,7 @@ const struct _SCRIPT_ENGINE_TOKEN Lhs[RULES_COUNT]=
{NON_TERMINAL, "STATEMENT"},
{NON_TERMINAL, "STATEMENT"},
{NON_TERMINAL, "STATEMENT"},
+ {NON_TERMINAL, "STATEMENT"},
{NON_TERMINAL, "S2"},
{NON_TERMINAL, "S2"},
{NON_TERMINAL, "S2"},
@@ -33,14 +34,33 @@ const struct _SCRIPT_ENGINE_TOKEN Lhs[RULES_COUNT]=
{NON_TERMINAL, "VARIABLE_TYPE1"},
{NON_TERMINAL, "VARIABLE_TYPE2"},
{NON_TERMINAL, "VARIABLE_TYPE2"},
+ {NON_TERMINAL, "VARIABLE_TYPE2"},
{NON_TERMINAL, "VARIABLE_TYPE3"},
{NON_TERMINAL, "VARIABLE_TYPE4"},
{NON_TERMINAL, "VARIABLE_TYPE4"},
+ {NON_TERMINAL, "ARRAY_DIMS"},
+ {NON_TERMINAL, "ARRAY_DIMS2"},
+ {NON_TERMINAL, "ARRAY_DIMS2"},
+ {NON_TERMINAL, "ARRAY_INIT"},
+ {NON_TERMINAL, "INIT_LIST"},
+ {NON_TERMINAL, "INIT_ITEM"},
+ {NON_TERMINAL, "INIT_ITEM"},
+ {NON_TERMINAL, "INIT_LIST_TAIL"},
+ {NON_TERMINAL, "INIT_LIST_TAIL"},
+ {NON_TERMINAL, "INIT_LIST_CONT"},
+ {NON_TERMINAL, "INIT_LIST_CONT"},
+ {NON_TERMINAL, "VARIABLE_TYPE4"},
{NON_TERMINAL, "VARIABLE_TYPE5"},
{NON_TERMINAL, "VARIABLE_TYPE5"},
{NON_TERMINAL, "VARIABLE_TYPE6"},
{NON_TERMINAL, "VARIABLE_TYPE6"},
{NON_TERMINAL, "ASSIGNMENT_STATEMENT"},
+ {NON_TERMINAL, "ASSIGNMENT_STATEMENT"},
+ {NON_TERMINAL, "ARRAY_DIMS_WRITE_OPT"},
+ {NON_TERMINAL, "ARRAY_DIMS_WRITE_OPT"},
+ {NON_TERMINAL, "ARRAY_DIMS_WRITE"},
+ {NON_TERMINAL, "ARRAY_DIMS_WRITE2"},
+ {NON_TERMINAL, "ARRAY_DIMS_WRITE2"},
{NON_TERMINAL, "ASSIGNMENT_STATEMENT'"},
{NON_TERMINAL, "ASSIGNMENT_STATEMENT'"},
{NON_TERMINAL, "ASSIGNMENT_STATEMENT'"},
@@ -120,6 +140,12 @@ const struct _SCRIPT_ENGINE_TOKEN Lhs[RULES_COUNT]=
{NON_TERMINAL, "CALL_FUNC_STATEMENT"},
{NON_TERMINAL, "CALL_FUNC_STATEMENT"},
{NON_TERMINAL, "CALL_FUNC_STATEMENT"},
+ {NON_TERMINAL, "CALL_FUNC_STATEMENT"},
+ {NON_TERMINAL, "CALL_FUNC_STATEMENT"},
+ {NON_TERMINAL, "CALL_FUNC_STATEMENT"},
+ {NON_TERMINAL, "CALL_FUNC_STATEMENT"},
+ {NON_TERMINAL, "CALL_FUNC_STATEMENT"},
+ {NON_TERMINAL, "CALL_FUNC_STATEMENT"},
{NON_TERMINAL, "VA"},
{NON_TERMINAL, "VA"},
{NON_TERMINAL, "IF_STATEMENT"},
@@ -229,6 +255,18 @@ const struct _SCRIPT_ENGINE_TOKEN Lhs[RULES_COUNT]=
{NON_TERMINAL, "E12"},
{NON_TERMINAL, "E12"},
{NON_TERMINAL, "E12"},
+ {NON_TERMINAL, "ARRAY_DIMS_READ_OPT"},
+ {NON_TERMINAL, "ARRAY_DIMS_READ_OPT"},
+ {NON_TERMINAL, "ARRAY_DIMS_READ"},
+ {NON_TERMINAL, "ARRAY_DIMS_READ2"},
+ {NON_TERMINAL, "ARRAY_DIMS_READ2"},
+ {NON_TERMINAL, "CONST_NUMBER"},
+ {NON_TERMINAL, "CONST_NUMBER"},
+ {NON_TERMINAL, "CONST_NUMBER"},
+ {NON_TERMINAL, "CONST_NUMBER"},
+ {NON_TERMINAL, "E12"},
+ {NON_TERMINAL, "E12"},
+ {NON_TERMINAL, "E12"},
{NON_TERMINAL, "E12"},
{NON_TERMINAL, "E12"},
{NON_TERMINAL, "E12"},
@@ -263,6 +301,7 @@ const struct _SCRIPT_ENGINE_TOKEN Rhs[RULES_COUNT][MAX_RHS_LEN]=
{{KEYWORD, "break"},{SEMANTIC_RULE, "@BREAK"},{SPECIAL_TOKEN, ";"}},
{{KEYWORD, "continue"},{SEMANTIC_RULE, "@CONTINUE"},{SPECIAL_TOKEN, ";"}},
{{NON_TERMINAL, "VARIABLE_TYPE3"}},
+ {{KEYWORD, "#include"},{NON_TERMINAL, "STRING"},{SEMANTIC_RULE, "@INCLUDE"},{SPECIAL_TOKEN, ";"}},
{{NON_TERMINAL, "STATEMENT2"},{NON_TERMINAL, "S2"}},
{{SPECIAL_TOKEN, "{"},{NON_TERMINAL, "STATEMENT2"},{NON_TERMINAL, "S2"},{SPECIAL_TOKEN, "}"}},
{{EPSILON, "eps"}},
@@ -281,15 +320,34 @@ const struct _SCRIPT_ENGINE_TOKEN Rhs[RULES_COUNT][MAX_RHS_LEN]=
{{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@RETURN_OF_USER_DEFINED_FUNCTION_WITH_VALUE"}},
{{SEMANTIC_RULE, "@PUSH"},{SCRIPT_VARIABLE_TYPE, "_script_variable_type"}},
{{NON_TERMINAL, "VARIABLE_TYPE1"},{NON_TERMINAL, "VARIABLE_TYPE2"}},
+ {{SPECIAL_TOKEN, "*"},{SEMANTIC_RULE, "@DECLARE_POINTER_TYPE"}},
{{EPSILON, "eps"}},
{{NON_TERMINAL, "VARIABLE_TYPE1"},{NON_TERMINAL, "VARIABLE_TYPE2"},{NON_TERMINAL, "L_VALUE"},{NON_TERMINAL, "VARIABLE_TYPE4"}},
{{SPECIAL_TOKEN, "="},{NON_TERMINAL, "EXPRESSION"},{NON_TERMINAL, "MULTIPLE_ASSIGNMENT"},{SPECIAL_TOKEN, ";"}},
+ {{SEMANTIC_RULE, "@ARRAY_L_VALUE"},{NON_TERMINAL, "ARRAY_DIMS"},{SPECIAL_TOKEN, "="},{NON_TERMINAL, "ARRAY_INIT"},{SEMANTIC_RULE, "@ARRAY_DECLARITION"},{SPECIAL_TOKEN, ";"}},
+ {{SPECIAL_TOKEN, "["},{NON_TERMINAL, "CONST_NUMBER"},{SEMANTIC_RULE, "@ARRAY_DIM_NUMBER"},{SPECIAL_TOKEN, "]"},{NON_TERMINAL, "ARRAY_DIMS2"}},
+ {{NON_TERMINAL, "ARRAY_DIMS"}},
+ {{EPSILON, "eps"}},
+ {{SPECIAL_TOKEN, "{"},{NON_TERMINAL, "INIT_LIST"},{SPECIAL_TOKEN, "}"},{SEMANTIC_RULE, "@ARRAY_LEFT_BRACKET"}},
+ {{NON_TERMINAL, "INIT_ITEM"},{NON_TERMINAL, "INIT_LIST_TAIL"}},
+ {{NON_TERMINAL, "ARRAY_INIT"}},
+ {{NON_TERMINAL, "EXPRESSION"}},
+ {{SPECIAL_TOKEN, ","},{NON_TERMINAL, "INIT_LIST_CONT"}},
+ {{EPSILON, "eps"}},
+ {{NON_TERMINAL, "INIT_ITEM"},{NON_TERMINAL, "INIT_LIST_TAIL"}},
+ {{EPSILON, "eps"}},
{{SEMANTIC_RULE, "@START_OF_USER_DEFINED_FUNCTION"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "VARIABLE_TYPE5"},{SPECIAL_TOKEN, ")"},{SPECIAL_TOKEN, "{"},{NON_TERMINAL, "S2"},{SEMANTIC_RULE, "@END_OF_USER_DEFINED_FUNCTION"},{SPECIAL_TOKEN, "}"}},
{{EPSILON, "eps"}},
{{NON_TERMINAL, "VARIABLE_TYPE1"},{NON_TERMINAL, "VARIABLE_TYPE2"},{NON_TERMINAL, "L_VALUE"},{SEMANTIC_RULE, "@FUNCTION_PARAMETER"},{NON_TERMINAL, "VARIABLE_TYPE6"}},
{{SPECIAL_TOKEN, ","},{NON_TERMINAL, "VARIABLE_TYPE1"},{NON_TERMINAL, "VARIABLE_TYPE2"},{NON_TERMINAL, "L_VALUE"},{SEMANTIC_RULE, "@FUNCTION_PARAMETER"},{NON_TERMINAL, "VARIABLE_TYPE6"}},
{{EPSILON, "eps"}},
- {{NON_TERMINAL, "L_VALUE"},{NON_TERMINAL, "ASSIGNMENT_STATEMENT'"}},
+ {{SPECIAL_TOKEN, "*"},{NON_TERMINAL, "L_VALUE"},{SPECIAL_TOKEN, "="},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@DEREFERENCE"}},
+ {{NON_TERMINAL, "L_VALUE"},{NON_TERMINAL, "ARRAY_DIMS_WRITE_OPT"},{NON_TERMINAL, "ASSIGNMENT_STATEMENT'"}},
+ {{NON_TERMINAL, "ARRAY_DIMS_WRITE"}},
+ {{EPSILON, "eps"}},
+ {{SPECIAL_TOKEN, "["},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@ARRAY_DIM_NUMBER"},{SPECIAL_TOKEN, "]"},{NON_TERMINAL, "ARRAY_DIMS_WRITE2"}},
+ {{NON_TERMINAL, "ARRAY_DIMS_WRITE"}},
+ {{EPSILON, "eps"},{SEMANTIC_RULE, "@ARRAY_INDEX_WRITE"}},
{{SPECIAL_TOKEN, "++"},{SEMANTIC_RULE, "@INC"}},
{{SPECIAL_TOKEN, "--"},{SEMANTIC_RULE, "@DEC"}},
{{SPECIAL_TOKEN, "="},{NON_TERMINAL, "EXPRESSION"},{NON_TERMINAL, "MULTIPLE_ASSIGNMENT"}},
@@ -323,6 +381,11 @@ const struct _SCRIPT_ENGINE_TOKEN Rhs[RULES_COUNT][MAX_RHS_LEN]=
{{KEYWORD, "event_trace_instrumentation_step_in"},{SPECIAL_TOKEN, "("},{SEMANTIC_RULE, "@EVENT_TRACE_INSTRUMENTATION_STEP_IN"},{SPECIAL_TOKEN, ")"}},
{{KEYWORD, "rdtsc"},{SPECIAL_TOKEN, "("},{SEMANTIC_RULE, "@RDTSC"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@IGNORE_LVALUE"}},
{{KEYWORD, "rdtscp"},{SPECIAL_TOKEN, "("},{SEMANTIC_RULE, "@RDTSCP"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@IGNORE_LVALUE"}},
+ {{KEYWORD, "lbr_save"},{SPECIAL_TOKEN, "("},{SEMANTIC_RULE, "@LBR_SAVE"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@IGNORE_LVALUE"}},
+ {{KEYWORD, "lbr_dump"},{SPECIAL_TOKEN, "("},{SEMANTIC_RULE, "@LBR_DUMP"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@IGNORE_LVALUE"}},
+ {{KEYWORD, "lbr_print"},{SPECIAL_TOKEN, "("},{SEMANTIC_RULE, "@LBR_PRINT"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@IGNORE_LVALUE"}},
+ {{KEYWORD, "lbr_restore"},{SPECIAL_TOKEN, "("},{SEMANTIC_RULE, "@LBR_RESTORE"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@IGNORE_LVALUE"}},
+ {{KEYWORD, "lbr_check"},{SPECIAL_TOKEN, "("},{SEMANTIC_RULE, "@LBR_CHECK"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@IGNORE_LVALUE"}},
{{KEYWORD, "spinlock_lock_custom_wait"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SPECIAL_TOKEN, ","},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@SPINLOCK_LOCK_CUSTOM_WAIT"},{SPECIAL_TOKEN, ")"}},
{{KEYWORD, "event_inject"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SPECIAL_TOKEN, ","},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@EVENT_INJECT"},{SPECIAL_TOKEN, ")"}},
{{KEYWORD, "poi"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@POI"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@IGNORE_LVALUE"}},
@@ -350,6 +413,7 @@ const struct _SCRIPT_ENGINE_TOKEN Rhs[RULES_COUNT][MAX_RHS_LEN]=
{{KEYWORD, "dd_pa"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@DD_PA"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@IGNORE_LVALUE"}},
{{KEYWORD, "dw_pa"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@DW_PA"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@IGNORE_LVALUE"}},
{{KEYWORD, "dq_pa"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@DQ_PA"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@IGNORE_LVALUE"}},
+ {{KEYWORD, "lbr_restore_by_filter"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@LBR_RESTORE_BY_FILTER"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@IGNORE_LVALUE"}},
{{KEYWORD, "ed"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SPECIAL_TOKEN, ","},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@ED"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@IGNORE_LVALUE"}},
{{KEYWORD, "eb"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SPECIAL_TOKEN, ","},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@EB"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@IGNORE_LVALUE"}},
{{KEYWORD, "eq"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SPECIAL_TOKEN, ","},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@EQ"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@IGNORE_LVALUE"}},
@@ -428,6 +492,11 @@ const struct _SCRIPT_ENGINE_TOKEN Rhs[RULES_COUNT][MAX_RHS_LEN]=
{{EPSILON, "eps"}},
{{KEYWORD, "rdtsc"},{SPECIAL_TOKEN, "("},{SEMANTIC_RULE, "@RDTSC"},{SPECIAL_TOKEN, ")"}},
{{KEYWORD, "rdtscp"},{SPECIAL_TOKEN, "("},{SEMANTIC_RULE, "@RDTSCP"},{SPECIAL_TOKEN, ")"}},
+ {{KEYWORD, "lbr_save"},{SPECIAL_TOKEN, "("},{SEMANTIC_RULE, "@LBR_SAVE"},{SPECIAL_TOKEN, ")"}},
+ {{KEYWORD, "lbr_dump"},{SPECIAL_TOKEN, "("},{SEMANTIC_RULE, "@LBR_DUMP"},{SPECIAL_TOKEN, ")"}},
+ {{KEYWORD, "lbr_print"},{SPECIAL_TOKEN, "("},{SEMANTIC_RULE, "@LBR_PRINT"},{SPECIAL_TOKEN, ")"}},
+ {{KEYWORD, "lbr_restore"},{SPECIAL_TOKEN, "("},{SEMANTIC_RULE, "@LBR_RESTORE"},{SPECIAL_TOKEN, ")"}},
+ {{KEYWORD, "lbr_check"},{SPECIAL_TOKEN, "("},{SEMANTIC_RULE, "@LBR_CHECK"},{SPECIAL_TOKEN, ")"}},
{{KEYWORD, "poi"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@POI"},{SPECIAL_TOKEN, ")"}},
{{KEYWORD, "db"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@DB"},{SPECIAL_TOKEN, ")"}},
{{KEYWORD, "dd"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@DD"},{SPECIAL_TOKEN, ")"}},
@@ -453,6 +522,7 @@ const struct _SCRIPT_ENGINE_TOKEN Rhs[RULES_COUNT][MAX_RHS_LEN]=
{{KEYWORD, "dd_pa"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@DD_PA"},{SPECIAL_TOKEN, ")"}},
{{KEYWORD, "dw_pa"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@DW_PA"},{SPECIAL_TOKEN, ")"}},
{{KEYWORD, "dq_pa"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@DQ_PA"},{SPECIAL_TOKEN, ")"}},
+ {{KEYWORD, "lbr_restore_by_filter"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@LBR_RESTORE_BY_FILTER"},{SPECIAL_TOKEN, ")"}},
{{KEYWORD, "ed"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SPECIAL_TOKEN, ","},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@ED"},{SPECIAL_TOKEN, ")"}},
{{KEYWORD, "eb"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SPECIAL_TOKEN, ","},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@EB"},{SPECIAL_TOKEN, ")"}},
{{KEYWORD, "eq"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SPECIAL_TOKEN, ","},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@EQ"},{SPECIAL_TOKEN, ")"}},
@@ -470,12 +540,18 @@ const struct _SCRIPT_ENGINE_TOKEN Rhs[RULES_COUNT][MAX_RHS_LEN]=
{{KEYWORD, "wcscmp"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "WstringNumber"},{SPECIAL_TOKEN, ","},{NON_TERMINAL, "WstringNumber"},{SEMANTIC_RULE, "@WCSCMP"},{SPECIAL_TOKEN, ")"}},
{{KEYWORD, "wcsncmp"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "WstringNumber"},{SPECIAL_TOKEN, ","},{NON_TERMINAL, "WstringNumber"},{SPECIAL_TOKEN, ","},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@WCSNCMP"},{SPECIAL_TOKEN, ")"}},
{{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXPRESSION"},{SPECIAL_TOKEN, ")"}},
- {{NON_TERMINAL, "L_VALUE"}},
+ {{NON_TERMINAL, "L_VALUE"},{NON_TERMINAL, "ARRAY_DIMS_READ_OPT"}},
{{SEMANTIC_RULE, "@PUSH"},{FUNCTION_ID, "_function_id"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "VA2"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@END_OF_CALLING_USER_DEFINED_FUNCTION_WITH_RETURNING_VALUE"}},
+ {{NON_TERMINAL, "ARRAY_DIMS_READ"}},
+ {{EPSILON, "eps"}},
+ {{SPECIAL_TOKEN, "["},{NON_TERMINAL, "EXPRESSION"},{SEMANTIC_RULE, "@ARRAY_DIM_NUMBER"},{SPECIAL_TOKEN, "]"},{NON_TERMINAL, "ARRAY_DIMS_READ2"}},
+ {{NON_TERMINAL, "ARRAY_DIMS_READ"}},
+ {{EPSILON, "eps"},{SEMANTIC_RULE, "@ARRAY_INDEX_READ"}},
{{SEMANTIC_RULE, "@PUSH"},{HEX, "_hex"}},
{{SEMANTIC_RULE, "@PUSH"},{DECIMAL, "_decimal"}},
{{SEMANTIC_RULE, "@PUSH"},{OCTAL, "_octal"}},
{{SEMANTIC_RULE, "@PUSH"},{BINARY, "_binary"}},
+ {{NON_TERMINAL, "CONST_NUMBER"}},
{{SEMANTIC_RULE, "@PUSH"},{PSEUDO_REGISTER, "_pseudo_register"}},
{{SPECIAL_TOKEN, "-"},{NON_TERMINAL, "E12"},{SEMANTIC_RULE, "@NEG"}},
{{SPECIAL_TOKEN, "+"},{NON_TERMINAL, "E12"}},
@@ -512,6 +588,7 @@ const unsigned int RhsSize[RULES_COUNT]=
3,
3,
1,
+4,
2,
4,
1,
@@ -530,14 +607,33 @@ const unsigned int RhsSize[RULES_COUNT]=
2,
2,
2,
+2,
1,
4,
4,
+6,
+5,
+1,
+1,
+4,
+2,
+1,
+1,
+2,
+1,
+2,
+1,
8,
1,
5,
6,
1,
+5,
+3,
+1,
+1,
+5,
+1,
2,
2,
2,
@@ -572,6 +668,11 @@ const unsigned int RhsSize[RULES_COUNT]=
4,
5,
5,
+5,
+5,
+5,
+5,
+5,
7,
7,
6,
@@ -599,6 +700,7 @@ const unsigned int RhsSize[RULES_COUNT]=
6,
6,
6,
+6,
8,
8,
8,
@@ -677,6 +779,12 @@ const unsigned int RhsSize[RULES_COUNT]=
1,
4,
4,
+4,
+4,
+4,
+4,
+4,
+5,
5,
5,
5,
@@ -719,13 +827,19 @@ const unsigned int RhsSize[RULES_COUNT]=
7,
9,
3,
-1,
+2,
6,
+1,
+1,
+5,
+1,
2,
2,
2,
2,
2,
+1,
+2,
3,
2,
3,
@@ -748,229 +862,266 @@ const unsigned int RhsSize[RULES_COUNT]=
};
const char* NoneTerminalMap[NONETERMINAL_COUNT]=
{
+"FOR_STATEMENT",
+"MULTIPLE_ASSIGNMENT2",
+"STATEMENT2",
+"E2'",
+"WSTRING",
+"StringNumber",
+"ASSIGNMENT_STATEMENT",
+"CONST_NUMBER",
+"INIT_LIST",
+"IF_STATEMENT",
"END_OF_IF",
+"BOOLEAN_EXPRESSION",
"E0'",
-"RETURN",
-"WstringNumber",
-"L_VALUE",
-"E5",
+"ARRAY_DIMS_WRITE_OPT",
"E2",
"VARIABLE_TYPE2",
-"EXPRESSION",
-"VA3",
-"MULTIPLE_ASSIGNMENT",
-"E4'",
-"DO_WHILE_STATEMENT",
-"S",
-"WSTRING",
-"FOR_STATEMENT",
-"VARIABLE_TYPE4",
-"E1'",
-"STATEMENT",
-"CALL_FUNC_STATEMENT",
-"VA2",
-"INC_DEC'",
-"ELSE_STATEMENT",
-"E2'",
-"E1",
-"STATEMENT2",
-"ASSIGNMENT_STATEMENT'",
-"E3'",
-"STRING",
-"VARIABLE_TYPE6",
-"MULTIPLE_ASSIGNMENT2",
-"BOOLEAN_EXPRESSION",
-"E12",
-"S2",
-"StringNumber",
-"E3",
-"ASSIGNMENT_STATEMENT",
-"ELSIF_STATEMENT",
"VARIABLE_TYPE5",
-"ELSIF_STATEMENT'",
-"VARIABLE_TYPE1",
-"VARIABLE_TYPE3",
-"E4",
-"E5'",
-"INC_DEC",
-"SIMPLE_ASSIGNMENT",
-"IF_STATEMENT",
+"INIT_ITEM",
+"ARRAY_DIMS_WRITE2",
"WHILE_STATEMENT",
-"VA"
+"MULTIPLE_ASSIGNMENT",
+"VARIABLE_TYPE6",
+"S",
+"INC_DEC",
+"ARRAY_DIMS_READ2",
+"L_VALUE",
+"ARRAY_INIT",
+"ARRAY_DIMS_READ_OPT",
+"VARIABLE_TYPE3",
+"SIMPLE_ASSIGNMENT",
+"E3",
+"STRING",
+"STATEMENT",
+"INC_DEC'",
+"ASSIGNMENT_STATEMENT'",
+"ELSIF_STATEMENT",
+"ELSE_STATEMENT",
+"E1'",
+"VARIABLE_TYPE4",
+"CALL_FUNC_STATEMENT",
+"WstringNumber",
+"E5",
+"E4",
+"EXPRESSION",
+"INIT_LIST_CONT",
+"E5'",
+"DO_WHILE_STATEMENT",
+"VARIABLE_TYPE1",
+"E12",
+"ARRAY_DIMS",
+"VA3",
+"VA",
+"ARRAY_DIMS2",
+"E4'",
+"RETURN",
+"ARRAY_DIMS_WRITE",
+"E1",
+"ELSIF_STATEMENT'",
+"VA2",
+"ARRAY_DIMS_READ",
+"INIT_LIST_TAIL",
+"E3'",
+"S2"
};
const char* TerminalMap[TERMINAL_COUNT]=
{
-"memcmp",
-"_register",
-"_function_parameter_id",
-"<<=",
-"db",
-"dw",
-"continue",
-"disassemble_len",
-"do",
-"strncmp",
-"--",
-"formats",
-"interlocked_increment",
-"strlen",
-"interlocked_exchange",
-"_hex",
-"event_sc",
-"|=",
-"test_statement",
-"^",
-"disassemble_len32",
-"hi_pa",
-"dq_pa",
-"flush",
-"else",
-"event_trace_step_in",
-"/=",
-"~",
-"low_pa",
-"dd_pa",
-"rdtsc",
-"++",
-"_decimal",
-"break",
-"%=",
-"hi",
-"eb_pa",
-"ed",
-"disassemble_len64",
"memcpy",
-";",
-"event_inject_error_code",
-"wcscmp",
-"^=",
-"eb",
-"poi",
-"{",
-">>=",
-"not",
-"low",
-"_wstring",
-"-=",
-"_pseudo_register",
-"+",
-"poi_pa",
-"event_disable",
"print",
-"+=",
-"*=",
+"hi",
"dq",
-"&=",
-"interlocked_compare_exchange",
-"_binary",
-"event_enable",
-"wcslen",
-"_local_id",
-"strcmp",
-",",
-"spinlock_lock_custom_wait",
-"reference",
-"microsleep",
-"return",
-"elsif",
-"eq",
-"_function_id",
-"/",
-"interlocked_decrement",
-"interlocked_exchange_add",
-"ed_pa",
-"event_trace_step_out",
-"if",
-"eq_pa",
-"_script_variable_type",
-"db_pa",
-"$",
-">>",
-"event_clear",
-"event_inject",
-"physical_to_virtual",
-"spinlock_unlock",
-"memcpy_pa",
-"spinlock_lock",
-"event_trace_instrumentation_step",
-"*",
-"&",
-"while",
-"-",
-"}",
-"=",
-"rdtscp",
-"wcsncmp",
-"for",
-"%",
-"_octal",
+"check_address",
+"event_sc",
+"interlocked_increment",
"_string",
-"_global_id",
+">>=",
"virtual_to_physical",
-"<<",
-"dd",
-"event_trace_step",
-"dw_pa",
+"++",
+"rdtsc",
+"[",
+"_octal",
+"^=",
+"}",
+"event_disable",
+"memcpy_pa",
+"-=",
+"^",
+"low_pa",
+"_wstring",
+"db_pa",
+"(",
+"eb_pa",
+"do",
"|",
-"neg",
-"printf",
+"/=",
+"=",
+"pause",
+"interlocked_decrement",
+"eb",
+"lbr_restore",
+"--",
+"while",
+"{",
+"interlocked_exchange",
+"continue",
+"event_trace_step_in",
+"%=",
+"test_statement",
+"_local_id",
+"rdtscp",
+"_binary",
+"*",
+"event_clear",
+"formats",
+"event_inject",
+"reference",
+"hi_pa",
+"wcscmp",
+"lbr_check",
+"/",
+"_function_id",
+"low",
+"dw_pa",
+"lbr_dump",
+"else",
+"_register",
+"]",
+"wcslen",
+"if",
+"-",
+"&",
+"~",
+"break",
+"for",
+"event_inject_error_code",
+"<<",
+"lbr_restore_by_filter",
+"interlocked_compare_exchange",
+"%",
+"lbr_print",
+"flush",
+"$",
+"strncmp",
+"poi",
+"_decimal",
+"dd",
+"db",
+"strlen",
+"disassemble_len64",
+"return",
+"+=",
+",",
+"strcmp",
+"eq_pa",
+"lbr_save",
+"#include",
+"disassemble_len32",
+"dq_pa",
+"ed_pa",
+"|=",
+"memcmp",
+"spinlock_lock_custom_wait",
+"ed",
+"_pseudo_register",
+"spinlock_lock",
+"eq",
+"dw",
+";",
+"interlocked_exchange_add",
+"wcsncmp",
+"+",
+"event_trace_instrumentation_step",
+"<<=",
+"not",
+"poi_pa",
+"event_trace_step_out",
+"physical_to_virtual",
+"elsif",
+"_global_id",
+"_script_variable_type",
+"*=",
")",
"event_trace_instrumentation_step_in",
-"pause",
-"check_address",
-"("
+"spinlock_unlock",
+"disassemble_len",
+"neg",
+"&=",
+"event_trace_step",
+"_hex",
+"printf",
+"dd_pa",
+"event_enable",
+"microsleep",
+"_function_parameter_id",
+">>"
};
const int ParseTable[NONETERMINAL_COUNT][TERMINAL_COUNT]=
{
- {127 ,127 ,127 ,2147483648 ,127 ,127 ,127 ,127 ,127 ,127 ,2147483648 ,127 ,127 ,127 ,127 ,2147483648 ,127 ,2147483648 ,127 ,2147483648 ,127 ,127 ,127 ,127 ,2147483648 ,127 ,2147483648 ,2147483648 ,127 ,127 ,127 ,2147483648 ,2147483648 ,127 ,2147483648 ,127 ,127 ,127 ,127 ,127 ,2147483648 ,127 ,127 ,2147483648 ,127 ,127 ,127 ,2147483648 ,127 ,127 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,127 ,127 ,127 ,2147483648 ,2147483648 ,127 ,2147483648 ,127 ,2147483648 ,127 ,127 ,127 ,127 ,2147483648 ,127 ,127 ,127 ,127 ,2147483648 ,127 ,127 ,2147483648 ,127 ,127 ,127 ,127 ,127 ,127 ,127 ,127 ,127 ,2147483648 ,127 ,127 ,127 ,127 ,127 ,127 ,127 ,2147483648 ,2147483648 ,127 ,2147483648 ,127 ,2147483648 ,127 ,127 ,127 ,2147483648 ,2147483648 ,2147483648 ,127 ,127 ,2147483648 ,127 ,127 ,127 ,2147483648 ,127 ,127 ,2147483648 ,127 ,127 ,127 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,156 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,156 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,156 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,155 ,2147483648 ,2147483648 ,156 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {28 ,28 ,28 ,2147483648 ,28 ,28 ,2147483648 ,28 ,2147483648 ,28 ,2147483648 ,2147483648 ,28 ,28 ,28 ,28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,28 ,28 ,28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,28 ,28 ,28 ,28 ,2147483648 ,28 ,2147483648 ,2147483648 ,28 ,28 ,28 ,28 ,2147483648 ,27 ,2147483648 ,28 ,2147483648 ,28 ,28 ,2147483648 ,2147483648 ,28 ,28 ,2147483648 ,2147483648 ,28 ,28 ,28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,28 ,2147483648 ,28 ,28 ,2147483648 ,28 ,28 ,28 ,2147483648 ,2147483648 ,28 ,2147483648 ,2147483648 ,2147483648 ,28 ,28 ,2147483648 ,28 ,28 ,28 ,2147483648 ,2147483648 ,28 ,2147483648 ,28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,28 ,28 ,2147483648 ,28 ,2147483648 ,2147483648 ,28 ,28 ,2147483648 ,2147483648 ,28 ,2147483648 ,28 ,28 ,2147483648 ,28 ,2147483648 ,28 ,2147483648 ,28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,28 ,28 },
- {244 ,244 ,244 ,2147483648 ,244 ,244 ,2147483648 ,244 ,2147483648 ,244 ,2147483648 ,2147483648 ,244 ,244 ,244 ,244 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,244 ,244 ,244 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,244 ,244 ,244 ,244 ,2147483648 ,244 ,2147483648 ,2147483648 ,244 ,244 ,244 ,244 ,2147483648 ,2147483648 ,2147483648 ,244 ,2147483648 ,244 ,244 ,2147483648 ,2147483648 ,244 ,244 ,245 ,2147483648 ,244 ,244 ,244 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,244 ,2147483648 ,244 ,244 ,2147483648 ,244 ,244 ,244 ,2147483648 ,2147483648 ,244 ,2147483648 ,2147483648 ,2147483648 ,244 ,244 ,2147483648 ,244 ,244 ,244 ,2147483648 ,2147483648 ,244 ,2147483648 ,244 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,244 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,244 ,244 ,2147483648 ,244 ,2147483648 ,2147483648 ,244 ,244 ,2147483648 ,2147483648 ,244 ,2147483648 ,244 ,244 ,2147483648 ,244 ,2147483648 ,244 ,2147483648 ,244 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,244 ,244 },
- {2147483648 ,236 ,237 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,235 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,234 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {171 ,171 ,171 ,2147483648 ,171 ,171 ,2147483648 ,171 ,2147483648 ,171 ,2147483648 ,2147483648 ,171 ,171 ,171 ,171 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,171 ,171 ,171 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,171 ,171 ,171 ,171 ,2147483648 ,171 ,2147483648 ,2147483648 ,171 ,171 ,171 ,171 ,2147483648 ,2147483648 ,2147483648 ,171 ,2147483648 ,171 ,171 ,2147483648 ,2147483648 ,171 ,171 ,2147483648 ,2147483648 ,171 ,171 ,171 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,171 ,2147483648 ,171 ,171 ,2147483648 ,171 ,171 ,171 ,2147483648 ,2147483648 ,171 ,2147483648 ,2147483648 ,2147483648 ,171 ,171 ,2147483648 ,171 ,171 ,171 ,2147483648 ,2147483648 ,171 ,2147483648 ,171 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,171 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,171 ,171 ,2147483648 ,171 ,2147483648 ,2147483648 ,171 ,171 ,2147483648 ,2147483648 ,171 ,2147483648 ,171 ,171 ,2147483648 ,171 ,2147483648 ,171 ,2147483648 ,171 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,171 ,171 },
- {160 ,160 ,160 ,2147483648 ,160 ,160 ,2147483648 ,160 ,2147483648 ,160 ,2147483648 ,2147483648 ,160 ,160 ,160 ,160 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,160 ,160 ,160 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,160 ,160 ,160 ,160 ,2147483648 ,160 ,2147483648 ,2147483648 ,160 ,160 ,160 ,160 ,2147483648 ,2147483648 ,2147483648 ,160 ,2147483648 ,160 ,160 ,2147483648 ,2147483648 ,160 ,160 ,2147483648 ,2147483648 ,160 ,160 ,160 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,160 ,2147483648 ,160 ,160 ,2147483648 ,160 ,160 ,160 ,2147483648 ,2147483648 ,160 ,2147483648 ,2147483648 ,2147483648 ,160 ,160 ,2147483648 ,160 ,160 ,160 ,2147483648 ,2147483648 ,160 ,2147483648 ,160 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,160 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,160 ,160 ,2147483648 ,160 ,2147483648 ,2147483648 ,160 ,160 ,2147483648 ,2147483648 ,160 ,2147483648 ,160 ,160 ,2147483648 ,160 ,2147483648 ,160 ,2147483648 ,160 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,160 ,160 },
- {2147483648 ,31 ,31 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,31 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,30 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,31 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {154 ,154 ,154 ,2147483648 ,154 ,154 ,2147483648 ,154 ,2147483648 ,154 ,2147483648 ,2147483648 ,154 ,154 ,154 ,154 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,154 ,154 ,154 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,154 ,154 ,154 ,154 ,2147483648 ,154 ,2147483648 ,2147483648 ,154 ,154 ,154 ,154 ,2147483648 ,2147483648 ,2147483648 ,154 ,2147483648 ,154 ,154 ,2147483648 ,2147483648 ,154 ,154 ,2147483648 ,2147483648 ,154 ,154 ,154 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,154 ,2147483648 ,154 ,154 ,2147483648 ,154 ,154 ,154 ,2147483648 ,2147483648 ,154 ,2147483648 ,2147483648 ,2147483648 ,154 ,154 ,2147483648 ,154 ,154 ,154 ,2147483648 ,2147483648 ,154 ,2147483648 ,154 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,154 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,154 ,154 ,2147483648 ,154 ,2147483648 ,2147483648 ,154 ,154 ,2147483648 ,2147483648 ,154 ,2147483648 ,154 ,154 ,2147483648 ,154 ,2147483648 ,154 ,2147483648 ,154 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,154 ,154 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,240 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,241 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,150 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,151 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,150 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,170 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,170 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,168 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,170 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,170 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,170 ,2147483648 ,169 ,2147483648 ,170 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,170 ,2147483648 ,2147483648 ,2147483648 ,170 ,2147483648 ,2147483648 ,170 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,129 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {0 ,0 ,0 ,2147483648 ,0 ,0 ,0 ,0 ,0 ,0 ,2147483648 ,0 ,0 ,0 ,0 ,2147483648 ,0 ,2147483648 ,0 ,2147483648 ,0 ,0 ,0 ,0 ,2147483648 ,0 ,2147483648 ,2147483648 ,0 ,0 ,0 ,2147483648 ,2147483648 ,0 ,2147483648 ,0 ,0 ,0 ,0 ,0 ,2147483648 ,0 ,0 ,2147483648 ,0 ,0 ,1 ,2147483648 ,0 ,0 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,0 ,0 ,0 ,2147483648 ,2147483648 ,0 ,2147483648 ,0 ,2147483648 ,0 ,0 ,0 ,0 ,2147483648 ,0 ,0 ,0 ,2147483648 ,2147483648 ,0 ,0 ,2147483648 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,2 ,2147483648 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,2147483648 ,2147483648 ,0 ,2147483648 ,2 ,2147483648 ,0 ,0 ,0 ,2147483648 ,2147483648 ,2147483648 ,0 ,0 ,2147483648 ,0 ,0 ,0 ,2147483648 ,0 ,0 ,2147483648 ,0 ,0 ,0 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,233 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,130 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,33 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,34 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,158 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,159 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,159 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,159 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,159 ,2147483648 ,2147483648 ,159 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {9 ,7 ,7 ,2147483648 ,9 ,9 ,11 ,9 ,5 ,9 ,2147483648 ,9 ,9 ,9 ,9 ,2147483648 ,9 ,2147483648 ,9 ,2147483648 ,9 ,9 ,9 ,9 ,2147483648 ,9 ,2147483648 ,2147483648 ,9 ,9 ,9 ,2147483648 ,2147483648 ,10 ,2147483648 ,9 ,9 ,9 ,9 ,9 ,2147483648 ,9 ,9 ,2147483648 ,9 ,9 ,2147483648 ,2147483648 ,9 ,9 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,9 ,9 ,9 ,2147483648 ,2147483648 ,9 ,2147483648 ,9 ,2147483648 ,9 ,9 ,7 ,9 ,2147483648 ,9 ,9 ,9 ,2147483648 ,2147483648 ,9 ,8 ,2147483648 ,9 ,9 ,9 ,9 ,3 ,9 ,12 ,9 ,2147483648 ,2147483648 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,2147483648 ,2147483648 ,4 ,2147483648 ,2147483648 ,2147483648 ,9 ,9 ,6 ,2147483648 ,2147483648 ,2147483648 ,7 ,9 ,2147483648 ,9 ,9 ,9 ,2147483648 ,9 ,9 ,2147483648 ,9 ,9 ,9 ,2147483648 },
- {111 ,2147483648 ,2147483648 ,2147483648 ,76 ,78 ,2147483648 ,85 ,2147483648 ,112 ,2147483648 ,54 ,88 ,109 ,103 ,2147483648 ,61 ,2147483648 ,58 ,2147483648 ,86 ,94 ,99 ,65 ,2147483648 ,67 ,2147483648 ,2147483648 ,95 ,97 ,71 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,81 ,105 ,100 ,87 ,116 ,2147483648 ,115 ,114 ,2147483648 ,101 ,75 ,2147483648 ,2147483648 ,83 ,82 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,93 ,56 ,53 ,2147483648 ,2147483648 ,79 ,2147483648 ,108 ,2147483648 ,55 ,113 ,2147483648 ,110 ,2147483648 ,73 ,90 ,62 ,2147483648 ,2147483648 ,102 ,2147483648 ,2147483648 ,89 ,104 ,106 ,68 ,2147483648 ,107 ,2147483648 ,96 ,2147483648 ,2147483648 ,57 ,74 ,91 ,60 ,117 ,59 ,69 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,72 ,118 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,92 ,2147483648 ,77 ,66 ,98 ,2147483648 ,80 ,63 ,2147483648 ,70 ,64 ,84 ,2147483648 },
- {239 ,239 ,239 ,2147483648 ,239 ,239 ,2147483648 ,239 ,2147483648 ,239 ,2147483648 ,2147483648 ,239 ,239 ,239 ,239 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,239 ,239 ,239 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,239 ,239 ,239 ,239 ,2147483648 ,239 ,2147483648 ,2147483648 ,239 ,239 ,239 ,239 ,2147483648 ,2147483648 ,2147483648 ,239 ,2147483648 ,239 ,239 ,2147483648 ,2147483648 ,239 ,239 ,2147483648 ,2147483648 ,239 ,239 ,239 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,239 ,2147483648 ,239 ,239 ,2147483648 ,239 ,239 ,239 ,2147483648 ,2147483648 ,239 ,2147483648 ,2147483648 ,2147483648 ,239 ,239 ,2147483648 ,239 ,239 ,239 ,2147483648 ,2147483648 ,239 ,2147483648 ,239 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,239 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,239 ,239 ,2147483648 ,239 ,2147483648 ,2147483648 ,239 ,239 ,2147483648 ,2147483648 ,239 ,2147483648 ,239 ,239 ,2147483648 ,239 ,2147483648 ,239 ,2147483648 ,239 ,2147483648 ,238 ,2147483648 ,2147483648 ,239 ,239 },
- {2147483648 ,2147483648 ,2147483648 ,143 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,136 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,147 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,141 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,135 ,2147483648 ,2147483648 ,142 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,148 ,2147483648 ,2147483648 ,146 ,2147483648 ,2147483648 ,2147483648 ,144 ,2147483648 ,2147483648 ,2147483648 ,139 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,138 ,140 ,2147483648 ,145 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,137 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,148 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {126 ,126 ,126 ,2147483648 ,126 ,126 ,126 ,126 ,126 ,126 ,2147483648 ,126 ,126 ,126 ,126 ,2147483648 ,126 ,2147483648 ,126 ,2147483648 ,126 ,126 ,126 ,126 ,125 ,126 ,2147483648 ,2147483648 ,126 ,126 ,126 ,2147483648 ,2147483648 ,126 ,2147483648 ,126 ,126 ,126 ,126 ,126 ,2147483648 ,126 ,126 ,2147483648 ,126 ,126 ,126 ,2147483648 ,126 ,126 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,126 ,126 ,126 ,2147483648 ,2147483648 ,126 ,2147483648 ,126 ,2147483648 ,126 ,126 ,126 ,126 ,2147483648 ,126 ,126 ,126 ,126 ,2147483648 ,126 ,126 ,2147483648 ,126 ,126 ,126 ,126 ,126 ,126 ,126 ,126 ,126 ,2147483648 ,126 ,126 ,126 ,126 ,126 ,126 ,126 ,2147483648 ,2147483648 ,126 ,2147483648 ,126 ,2147483648 ,126 ,126 ,126 ,2147483648 ,2147483648 ,2147483648 ,126 ,126 ,2147483648 ,126 ,126 ,126 ,2147483648 ,126 ,126 ,2147483648 ,126 ,126 ,126 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,162 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,162 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,162 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,161 ,2147483648 ,2147483648 ,2147483648 ,162 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,162 ,2147483648 ,2147483648 ,162 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {157 ,157 ,157 ,2147483648 ,157 ,157 ,2147483648 ,157 ,2147483648 ,157 ,2147483648 ,2147483648 ,157 ,157 ,157 ,157 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,157 ,157 ,157 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,157 ,157 ,157 ,157 ,2147483648 ,157 ,2147483648 ,2147483648 ,157 ,157 ,157 ,157 ,2147483648 ,2147483648 ,2147483648 ,157 ,2147483648 ,157 ,157 ,2147483648 ,2147483648 ,157 ,157 ,2147483648 ,2147483648 ,157 ,157 ,157 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,157 ,2147483648 ,157 ,157 ,2147483648 ,157 ,157 ,157 ,2147483648 ,2147483648 ,157 ,2147483648 ,2147483648 ,2147483648 ,157 ,157 ,2147483648 ,157 ,157 ,157 ,2147483648 ,2147483648 ,157 ,2147483648 ,157 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,157 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,157 ,157 ,2147483648 ,157 ,2147483648 ,2147483648 ,157 ,157 ,2147483648 ,2147483648 ,157 ,2147483648 ,157 ,157 ,2147483648 ,157 ,2147483648 ,157 ,2147483648 ,157 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,157 ,157 },
- {22 ,20 ,20 ,2147483648 ,22 ,22 ,24 ,22 ,18 ,22 ,2147483648 ,22 ,22 ,22 ,22 ,2147483648 ,22 ,2147483648 ,22 ,2147483648 ,22 ,22 ,22 ,22 ,2147483648 ,22 ,2147483648 ,2147483648 ,22 ,22 ,22 ,2147483648 ,2147483648 ,23 ,2147483648 ,22 ,22 ,22 ,22 ,22 ,2147483648 ,22 ,22 ,2147483648 ,22 ,22 ,2147483648 ,2147483648 ,22 ,22 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,22 ,22 ,22 ,2147483648 ,2147483648 ,22 ,2147483648 ,22 ,2147483648 ,22 ,22 ,20 ,22 ,2147483648 ,22 ,22 ,22 ,26 ,2147483648 ,22 ,21 ,2147483648 ,22 ,22 ,22 ,22 ,16 ,22 ,25 ,22 ,2147483648 ,2147483648 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,2147483648 ,2147483648 ,17 ,2147483648 ,2147483648 ,2147483648 ,22 ,22 ,19 ,2147483648 ,2147483648 ,2147483648 ,20 ,22 ,2147483648 ,22 ,22 ,22 ,2147483648 ,22 ,22 ,2147483648 ,22 ,22 ,22 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,48 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,52 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,46 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,40 ,2147483648 ,2147483648 ,47 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,51 ,2147483648 ,2147483648 ,2147483648 ,49 ,2147483648 ,2147483648 ,2147483648 ,44 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,43 ,45 ,2147483648 ,50 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,42 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,166 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,166 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,166 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,164 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,166 ,2147483648 ,2147483648 ,2147483648 ,166 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,165 ,2147483648 ,2147483648 ,2147483648 ,166 ,2147483648 ,2147483648 ,166 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,232 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,38 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,153 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,152 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,153 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,149 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,149 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {214 ,220 ,220 ,2147483648 ,179 ,181 ,2147483648 ,188 ,2147483648 ,215 ,2147483648 ,2147483648 ,191 ,212 ,206 ,222 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,189 ,197 ,202 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,229 ,198 ,200 ,176 ,2147483648 ,223 ,2147483648 ,2147483648 ,184 ,208 ,203 ,190 ,2147483648 ,2147483648 ,2147483648 ,217 ,2147483648 ,204 ,178 ,2147483648 ,2147483648 ,186 ,185 ,2147483648 ,2147483648 ,226 ,228 ,196 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,182 ,2147483648 ,211 ,225 ,2147483648 ,216 ,220 ,213 ,2147483648 ,2147483648 ,193 ,2147483648 ,2147483648 ,2147483648 ,205 ,221 ,2147483648 ,192 ,207 ,209 ,2147483648 ,2147483648 ,210 ,2147483648 ,199 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,194 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,230 ,231 ,2147483648 ,227 ,2147483648 ,2147483648 ,177 ,218 ,2147483648 ,2147483648 ,224 ,2147483648 ,220 ,195 ,2147483648 ,180 ,2147483648 ,201 ,2147483648 ,183 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,187 ,219 },
- {13 ,13 ,13 ,2147483648 ,13 ,13 ,13 ,13 ,13 ,13 ,2147483648 ,13 ,13 ,13 ,13 ,2147483648 ,13 ,2147483648 ,13 ,2147483648 ,13 ,13 ,13 ,13 ,2147483648 ,13 ,2147483648 ,2147483648 ,13 ,13 ,13 ,2147483648 ,2147483648 ,13 ,2147483648 ,13 ,13 ,13 ,13 ,13 ,2147483648 ,13 ,13 ,2147483648 ,13 ,13 ,14 ,2147483648 ,13 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,13 ,13 ,13 ,2147483648 ,2147483648 ,13 ,2147483648 ,13 ,2147483648 ,13 ,13 ,13 ,13 ,2147483648 ,13 ,13 ,13 ,13 ,2147483648 ,13 ,13 ,2147483648 ,13 ,13 ,13 ,13 ,13 ,13 ,13 ,13 ,2147483648 ,2147483648 ,13 ,13 ,13 ,13 ,13 ,13 ,13 ,2147483648 ,2147483648 ,13 ,2147483648 ,15 ,2147483648 ,13 ,13 ,13 ,2147483648 ,2147483648 ,2147483648 ,13 ,13 ,2147483648 ,13 ,13 ,13 ,2147483648 ,13 ,13 ,2147483648 ,13 ,13 ,13 ,2147483648 },
- {242 ,242 ,242 ,2147483648 ,242 ,242 ,2147483648 ,242 ,2147483648 ,242 ,2147483648 ,2147483648 ,242 ,242 ,242 ,242 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,242 ,242 ,242 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,242 ,242 ,242 ,242 ,2147483648 ,242 ,2147483648 ,2147483648 ,242 ,242 ,242 ,242 ,2147483648 ,2147483648 ,2147483648 ,242 ,2147483648 ,242 ,242 ,2147483648 ,2147483648 ,242 ,242 ,2147483648 ,2147483648 ,242 ,242 ,242 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,242 ,2147483648 ,242 ,242 ,2147483648 ,242 ,242 ,242 ,2147483648 ,2147483648 ,242 ,2147483648 ,2147483648 ,2147483648 ,242 ,242 ,2147483648 ,242 ,242 ,242 ,2147483648 ,2147483648 ,242 ,2147483648 ,242 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,242 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,242 ,242 ,2147483648 ,242 ,2147483648 ,2147483648 ,242 ,242 ,2147483648 ,2147483648 ,242 ,243 ,242 ,242 ,2147483648 ,242 ,2147483648 ,242 ,2147483648 ,242 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,242 ,242 },
- {163 ,163 ,163 ,2147483648 ,163 ,163 ,2147483648 ,163 ,2147483648 ,163 ,2147483648 ,2147483648 ,163 ,163 ,163 ,163 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,163 ,163 ,163 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,163 ,163 ,163 ,163 ,2147483648 ,163 ,2147483648 ,2147483648 ,163 ,163 ,163 ,163 ,2147483648 ,2147483648 ,2147483648 ,163 ,2147483648 ,163 ,163 ,2147483648 ,2147483648 ,163 ,163 ,2147483648 ,2147483648 ,163 ,163 ,163 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,163 ,2147483648 ,163 ,163 ,2147483648 ,163 ,163 ,163 ,2147483648 ,2147483648 ,163 ,2147483648 ,2147483648 ,2147483648 ,163 ,163 ,2147483648 ,163 ,163 ,163 ,2147483648 ,2147483648 ,163 ,2147483648 ,163 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,163 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,163 ,163 ,2147483648 ,163 ,2147483648 ,2147483648 ,163 ,163 ,2147483648 ,2147483648 ,163 ,2147483648 ,163 ,163 ,2147483648 ,163 ,2147483648 ,163 ,2147483648 ,163 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,163 ,163 },
- {2147483648 ,39 ,39 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,39 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,39 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {123 ,123 ,123 ,2147483648 ,123 ,123 ,123 ,123 ,123 ,123 ,2147483648 ,123 ,123 ,123 ,123 ,2147483648 ,123 ,2147483648 ,123 ,2147483648 ,123 ,123 ,123 ,123 ,123 ,123 ,2147483648 ,2147483648 ,123 ,123 ,123 ,2147483648 ,2147483648 ,123 ,2147483648 ,123 ,123 ,123 ,123 ,123 ,2147483648 ,123 ,123 ,2147483648 ,123 ,123 ,123 ,2147483648 ,123 ,123 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,123 ,123 ,123 ,2147483648 ,2147483648 ,123 ,2147483648 ,123 ,2147483648 ,123 ,123 ,123 ,123 ,2147483648 ,123 ,123 ,123 ,123 ,122 ,123 ,123 ,2147483648 ,123 ,123 ,123 ,123 ,123 ,123 ,123 ,123 ,123 ,2147483648 ,123 ,123 ,123 ,123 ,123 ,123 ,123 ,2147483648 ,2147483648 ,123 ,2147483648 ,123 ,2147483648 ,123 ,123 ,123 ,2147483648 ,2147483648 ,2147483648 ,123 ,123 ,2147483648 ,123 ,123 ,123 ,2147483648 ,123 ,123 ,2147483648 ,123 ,123 ,123 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,36 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,35 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {124 ,124 ,124 ,2147483648 ,124 ,124 ,124 ,124 ,124 ,124 ,2147483648 ,124 ,124 ,124 ,124 ,2147483648 ,124 ,2147483648 ,124 ,2147483648 ,124 ,124 ,124 ,124 ,124 ,124 ,2147483648 ,2147483648 ,124 ,124 ,124 ,2147483648 ,2147483648 ,124 ,2147483648 ,124 ,124 ,124 ,124 ,124 ,2147483648 ,124 ,124 ,2147483648 ,124 ,124 ,124 ,2147483648 ,124 ,124 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,124 ,124 ,124 ,2147483648 ,2147483648 ,124 ,2147483648 ,124 ,2147483648 ,124 ,124 ,124 ,124 ,2147483648 ,124 ,124 ,124 ,124 ,2147483648 ,124 ,124 ,2147483648 ,124 ,124 ,124 ,124 ,124 ,124 ,124 ,124 ,124 ,2147483648 ,124 ,124 ,124 ,124 ,124 ,124 ,124 ,2147483648 ,2147483648 ,124 ,2147483648 ,124 ,2147483648 ,124 ,124 ,124 ,2147483648 ,2147483648 ,2147483648 ,124 ,124 ,2147483648 ,124 ,124 ,124 ,2147483648 ,124 ,124 ,2147483648 ,124 ,124 ,124 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,32 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {167 ,167 ,167 ,2147483648 ,167 ,167 ,2147483648 ,167 ,2147483648 ,167 ,2147483648 ,2147483648 ,167 ,167 ,167 ,167 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,167 ,167 ,167 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,167 ,167 ,167 ,167 ,2147483648 ,167 ,2147483648 ,2147483648 ,167 ,167 ,167 ,167 ,2147483648 ,2147483648 ,2147483648 ,167 ,2147483648 ,167 ,167 ,2147483648 ,2147483648 ,167 ,167 ,2147483648 ,2147483648 ,167 ,167 ,167 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,167 ,2147483648 ,167 ,167 ,2147483648 ,167 ,167 ,167 ,2147483648 ,2147483648 ,167 ,2147483648 ,2147483648 ,2147483648 ,167 ,167 ,2147483648 ,167 ,167 ,167 ,2147483648 ,2147483648 ,167 ,2147483648 ,167 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,167 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,167 ,167 ,2147483648 ,167 ,2147483648 ,2147483648 ,167 ,167 ,2147483648 ,2147483648 ,167 ,2147483648 ,167 ,167 ,2147483648 ,167 ,2147483648 ,167 ,2147483648 ,167 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,167 ,167 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,175 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,175 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,175 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,175 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,172 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,175 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,174 ,175 ,2147483648 ,175 ,2147483648 ,175 ,2147483648 ,2147483648 ,2147483648 ,173 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,175 ,2147483648 ,2147483648 ,2147483648 ,175 ,2147483648 ,2147483648 ,175 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,134 ,134 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,134 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,134 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,132 ,132 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,133 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,132 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,131 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,132 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,133 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,121 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,128 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,119 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,120 ,2147483648 ,2147483648 ,2147483648 ,2147483648 }
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,156 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,178 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,179 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,179 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {23 ,23 ,23 ,23 ,23 ,23 ,23 ,2147483648 ,2147483648 ,23 ,2147483648 ,23 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,23 ,23 ,2147483648 ,2147483648 ,23 ,2147483648 ,23 ,2147483648 ,23 ,19 ,2147483648 ,2147483648 ,2147483648 ,23 ,23 ,23 ,23 ,2147483648 ,18 ,2147483648 ,23 ,25 ,23 ,2147483648 ,23 ,21 ,23 ,2147483648 ,21 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,2147483648 ,22 ,23 ,23 ,23 ,2147483648 ,21 ,2147483648 ,23 ,17 ,2147483648 ,2147483648 ,2147483648 ,24 ,20 ,23 ,2147483648 ,23 ,23 ,2147483648 ,23 ,23 ,2147483648 ,23 ,23 ,2147483648 ,23 ,23 ,23 ,23 ,27 ,2147483648 ,2147483648 ,23 ,23 ,23 ,2147483648 ,23 ,23 ,23 ,2147483648 ,23 ,23 ,23 ,2147483648 ,23 ,23 ,23 ,2147483648 ,23 ,23 ,2147483648 ,23 ,2147483648 ,23 ,23 ,23 ,23 ,2147483648 ,21 ,26 ,2147483648 ,2147483648 ,23 ,23 ,23 ,23 ,2147483648 ,23 ,2147483648 ,23 ,23 ,23 ,23 ,21 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,188 ,2147483648 ,2147483648 ,2147483648 ,188 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,188 ,2147483648 ,188 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,188 ,2147483648 ,2147483648 ,2147483648 ,187 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,188 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,188 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,188 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,271 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,280 ,280 ,280 ,2147483648 ,280 ,281 ,2147483648 ,280 ,2147483648 ,280 ,2147483648 ,280 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,280 ,2147483648 ,280 ,280 ,280 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,280 ,280 ,280 ,2147483648 ,2147483648 ,2147483648 ,280 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,280 ,280 ,280 ,280 ,2147483648 ,2147483648 ,2147483648 ,280 ,280 ,280 ,280 ,2147483648 ,280 ,280 ,280 ,280 ,2147483648 ,280 ,2147483648 ,280 ,2147483648 ,280 ,280 ,280 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,280 ,280 ,2147483648 ,280 ,2147483648 ,2147483648 ,280 ,280 ,280 ,280 ,280 ,280 ,280 ,2147483648 ,2147483648 ,2147483648 ,280 ,280 ,280 ,2147483648 ,280 ,280 ,280 ,2147483648 ,280 ,2147483648 ,280 ,280 ,2147483648 ,280 ,280 ,2147483648 ,280 ,280 ,280 ,2147483648 ,2147483648 ,280 ,280 ,2147483648 ,280 ,2147483648 ,280 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,280 ,280 ,2147483648 ,2147483648 ,280 ,2147483648 ,280 ,2147483648 ,2147483648 ,280 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,54 ,2147483648 ,2147483648 ,53 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,54 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,54 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,54 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,261 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,262 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,260 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,259 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,41 ,41 ,41 ,2147483648 ,41 ,2147483648 ,2147483648 ,41 ,2147483648 ,41 ,2147483648 ,41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,41 ,2147483648 ,41 ,41 ,41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,41 ,41 ,41 ,2147483648 ,2147483648 ,41 ,41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,41 ,41 ,41 ,41 ,2147483648 ,2147483648 ,2147483648 ,41 ,41 ,41 ,41 ,2147483648 ,41 ,41 ,41 ,41 ,2147483648 ,41 ,2147483648 ,41 ,2147483648 ,41 ,41 ,41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,41 ,41 ,2147483648 ,41 ,2147483648 ,2147483648 ,41 ,41 ,41 ,41 ,41 ,41 ,41 ,2147483648 ,2147483648 ,2147483648 ,41 ,41 ,41 ,2147483648 ,41 ,41 ,41 ,2147483648 ,41 ,2147483648 ,41 ,41 ,2147483648 ,41 ,41 ,2147483648 ,41 ,41 ,41 ,2147483648 ,2147483648 ,41 ,41 ,2147483648 ,41 ,2147483648 ,41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,41 ,41 ,2147483648 ,2147483648 ,41 ,2147483648 ,41 ,2147483648 ,2147483648 ,41 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,147 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {153 ,153 ,153 ,153 ,153 ,153 ,153 ,2147483648 ,2147483648 ,153 ,2147483648 ,153 ,2147483648 ,2147483648 ,2147483648 ,153 ,153 ,153 ,2147483648 ,2147483648 ,153 ,2147483648 ,153 ,2147483648 ,153 ,153 ,2147483648 ,2147483648 ,2147483648 ,153 ,153 ,153 ,153 ,2147483648 ,153 ,153 ,153 ,153 ,153 ,2147483648 ,153 ,153 ,153 ,2147483648 ,153 ,153 ,153 ,153 ,153 ,153 ,153 ,153 ,2147483648 ,153 ,153 ,153 ,153 ,2147483648 ,153 ,2147483648 ,153 ,153 ,2147483648 ,2147483648 ,2147483648 ,153 ,153 ,153 ,2147483648 ,153 ,153 ,2147483648 ,153 ,153 ,153 ,153 ,153 ,2147483648 ,153 ,153 ,153 ,153 ,153 ,2147483648 ,2147483648 ,153 ,153 ,153 ,153 ,153 ,153 ,153 ,2147483648 ,153 ,153 ,153 ,2147483648 ,153 ,153 ,153 ,2147483648 ,153 ,153 ,2147483648 ,153 ,2147483648 ,153 ,153 ,153 ,153 ,2147483648 ,153 ,153 ,2147483648 ,2147483648 ,153 ,153 ,153 ,153 ,2147483648 ,153 ,2147483648 ,153 ,153 ,153 ,153 ,153 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,175 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,175 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,182 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,181 ,2147483648 ,182 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,182 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,182 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,182 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,182 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,56 ,2147483648 ,56 ,2147483648 ,55 ,2147483648 ,56 ,2147483648 ,2147483648 ,2147483648 ,56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,56 ,56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,186 ,186 ,186 ,2147483648 ,186 ,2147483648 ,2147483648 ,186 ,2147483648 ,186 ,2147483648 ,186 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,186 ,2147483648 ,186 ,186 ,186 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,186 ,186 ,186 ,2147483648 ,2147483648 ,2147483648 ,186 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,186 ,186 ,186 ,186 ,2147483648 ,2147483648 ,2147483648 ,186 ,186 ,186 ,186 ,2147483648 ,186 ,186 ,186 ,186 ,2147483648 ,186 ,2147483648 ,186 ,2147483648 ,186 ,186 ,186 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,186 ,186 ,2147483648 ,186 ,2147483648 ,2147483648 ,186 ,186 ,186 ,186 ,186 ,186 ,186 ,2147483648 ,2147483648 ,2147483648 ,186 ,186 ,186 ,2147483648 ,186 ,186 ,186 ,2147483648 ,186 ,2147483648 ,186 ,186 ,2147483648 ,186 ,186 ,2147483648 ,186 ,186 ,186 ,2147483648 ,2147483648 ,186 ,186 ,2147483648 ,186 ,2147483648 ,186 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,186 ,186 ,2147483648 ,2147483648 ,186 ,2147483648 ,186 ,2147483648 ,2147483648 ,186 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,33 ,2147483648 ,2147483648 ,32 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,33 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,33 ,31 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,33 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,50 ,2147483648 ,49 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,43 ,43 ,43 ,2147483648 ,43 ,2147483648 ,2147483648 ,43 ,2147483648 ,43 ,2147483648 ,43 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,43 ,2147483648 ,43 ,43 ,43 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,43 ,43 ,43 ,2147483648 ,2147483648 ,42 ,43 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,43 ,43 ,43 ,43 ,2147483648 ,2147483648 ,2147483648 ,43 ,43 ,43 ,43 ,2147483648 ,43 ,43 ,43 ,43 ,2147483648 ,43 ,2147483648 ,43 ,2147483648 ,43 ,43 ,43 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,43 ,43 ,2147483648 ,43 ,2147483648 ,2147483648 ,43 ,43 ,43 ,43 ,43 ,43 ,43 ,2147483648 ,2147483648 ,2147483648 ,43 ,43 ,43 ,2147483648 ,43 ,43 ,43 ,2147483648 ,43 ,2147483648 ,43 ,43 ,2147483648 ,43 ,43 ,2147483648 ,43 ,43 ,43 ,2147483648 ,2147483648 ,43 ,43 ,2147483648 ,43 ,2147483648 ,43 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,43 ,43 ,2147483648 ,2147483648 ,43 ,2147483648 ,43 ,2147483648 ,2147483648 ,43 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,59 ,2147483648 ,59 ,2147483648 ,58 ,2147483648 ,59 ,2147483648 ,2147483648 ,2147483648 ,59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,59 ,59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,154 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,177 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,176 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,176 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,51 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,52 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {0 ,0 ,0 ,0 ,0 ,0 ,0 ,2147483648 ,2147483648 ,0 ,2147483648 ,0 ,2147483648 ,2147483648 ,2147483648 ,2 ,0 ,0 ,2147483648 ,2147483648 ,0 ,2147483648 ,0 ,2147483648 ,0 ,0 ,2147483648 ,2147483648 ,2147483648 ,0 ,0 ,0 ,0 ,2147483648 ,0 ,1 ,0 ,0 ,0 ,2147483648 ,0 ,0 ,0 ,2147483648 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,2147483648 ,0 ,0 ,0 ,0 ,2147483648 ,0 ,2147483648 ,0 ,0 ,2147483648 ,2147483648 ,2147483648 ,0 ,0 ,0 ,2147483648 ,0 ,0 ,2147483648 ,0 ,0 ,2 ,0 ,0 ,2147483648 ,0 ,0 ,0 ,0 ,2147483648 ,2147483648 ,2147483648 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,2147483648 ,0 ,0 ,0 ,2147483648 ,0 ,0 ,0 ,2147483648 ,0 ,0 ,2147483648 ,0 ,2147483648 ,0 ,0 ,0 ,0 ,2147483648 ,0 ,0 ,2147483648 ,2147483648 ,0 ,0 ,0 ,0 ,2147483648 ,0 ,2147483648 ,0 ,0 ,0 ,0 ,0 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,160 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,160 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,160 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,160 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,257 ,2147483648 ,2147483648 ,258 ,2147483648 ,2147483648 ,2147483648 ,258 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,258 ,2147483648 ,258 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,258 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,258 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,258 ,2147483648 ,2147483648 ,258 ,258 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,258 ,2147483648 ,2147483648 ,258 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,258 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,258 ,2147483648 ,2147483648 ,258 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,258 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,258 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,273 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,274 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,272 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,275 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,40 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,254 ,2147483648 ,2147483648 ,255 ,2147483648 ,2147483648 ,2147483648 ,255 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,255 ,2147483648 ,255 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,255 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,255 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,255 ,2147483648 ,2147483648 ,255 ,255 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,255 ,2147483648 ,2147483648 ,255 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,255 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,255 ,2147483648 ,2147483648 ,255 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,255 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,255 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,34 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,158 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,158 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,159 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,158 ,157 ,2147483648 ,159 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,158 ,2147483648 },
+ {2147483648 ,2147483648 ,189 ,189 ,189 ,2147483648 ,189 ,2147483648 ,2147483648 ,189 ,2147483648 ,189 ,2147483648 ,189 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,189 ,2147483648 ,189 ,189 ,189 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,189 ,189 ,189 ,2147483648 ,2147483648 ,2147483648 ,189 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,189 ,189 ,189 ,189 ,2147483648 ,2147483648 ,2147483648 ,189 ,189 ,189 ,189 ,2147483648 ,189 ,189 ,189 ,189 ,2147483648 ,189 ,2147483648 ,189 ,2147483648 ,189 ,189 ,189 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,189 ,189 ,2147483648 ,189 ,2147483648 ,2147483648 ,189 ,189 ,189 ,189 ,189 ,189 ,189 ,2147483648 ,2147483648 ,2147483648 ,189 ,189 ,189 ,2147483648 ,189 ,189 ,189 ,2147483648 ,189 ,2147483648 ,189 ,189 ,2147483648 ,189 ,189 ,2147483648 ,189 ,189 ,189 ,2147483648 ,2147483648 ,189 ,189 ,2147483648 ,189 ,2147483648 ,189 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,189 ,189 ,2147483648 ,2147483648 ,189 ,2147483648 ,189 ,2147483648 ,2147483648 ,189 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,270 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {9 ,9 ,9 ,9 ,9 ,9 ,9 ,2147483648 ,2147483648 ,9 ,2147483648 ,9 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,9 ,9 ,2147483648 ,2147483648 ,9 ,2147483648 ,9 ,2147483648 ,9 ,5 ,2147483648 ,2147483648 ,2147483648 ,9 ,9 ,9 ,9 ,2147483648 ,4 ,2147483648 ,9 ,11 ,9 ,2147483648 ,9 ,7 ,9 ,2147483648 ,7 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,2147483648 ,8 ,9 ,9 ,9 ,2147483648 ,7 ,2147483648 ,9 ,3 ,2147483648 ,2147483648 ,2147483648 ,10 ,6 ,9 ,2147483648 ,9 ,9 ,2147483648 ,9 ,9 ,2147483648 ,9 ,9 ,2147483648 ,9 ,9 ,9 ,9 ,2147483648 ,2147483648 ,2147483648 ,9 ,9 ,9 ,13 ,9 ,9 ,9 ,2147483648 ,9 ,9 ,9 ,2147483648 ,9 ,9 ,9 ,2147483648 ,9 ,9 ,2147483648 ,9 ,2147483648 ,9 ,9 ,9 ,9 ,2147483648 ,7 ,12 ,2147483648 ,2147483648 ,9 ,9 ,9 ,9 ,2147483648 ,9 ,2147483648 ,9 ,9 ,9 ,9 ,7 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,170 ,2147483648 ,161 ,2147483648 ,2147483648 ,2147483648 ,172 ,2147483648 ,2147483648 ,2147483648 ,165 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,167 ,163 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,162 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,168 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,164 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,173 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,174 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,169 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,166 ,174 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,171 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,69 ,2147483648 ,60 ,2147483648 ,2147483648 ,2147483648 ,71 ,2147483648 ,2147483648 ,2147483648 ,64 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,66 ,62 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,61 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,67 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,63 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,72 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,68 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,65 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,70 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {149 ,149 ,149 ,149 ,149 ,149 ,149 ,2147483648 ,2147483648 ,149 ,2147483648 ,149 ,2147483648 ,2147483648 ,2147483648 ,149 ,149 ,149 ,2147483648 ,2147483648 ,149 ,2147483648 ,149 ,2147483648 ,149 ,149 ,2147483648 ,2147483648 ,2147483648 ,149 ,149 ,149 ,149 ,2147483648 ,149 ,149 ,149 ,149 ,149 ,2147483648 ,149 ,149 ,149 ,2147483648 ,149 ,149 ,149 ,149 ,149 ,149 ,149 ,149 ,2147483648 ,149 ,149 ,149 ,149 ,149 ,149 ,2147483648 ,149 ,149 ,2147483648 ,2147483648 ,2147483648 ,149 ,149 ,149 ,2147483648 ,149 ,149 ,2147483648 ,149 ,149 ,149 ,149 ,149 ,2147483648 ,149 ,149 ,149 ,149 ,149 ,2147483648 ,2147483648 ,149 ,149 ,149 ,149 ,149 ,149 ,149 ,2147483648 ,149 ,149 ,149 ,2147483648 ,149 ,149 ,149 ,2147483648 ,149 ,149 ,2147483648 ,149 ,2147483648 ,149 ,149 ,149 ,149 ,148 ,149 ,149 ,2147483648 ,2147483648 ,149 ,149 ,149 ,149 ,2147483648 ,149 ,2147483648 ,149 ,149 ,149 ,149 ,149 ,2147483648 },
+ {152 ,152 ,152 ,152 ,152 ,152 ,152 ,2147483648 ,2147483648 ,152 ,2147483648 ,152 ,2147483648 ,2147483648 ,2147483648 ,152 ,152 ,152 ,2147483648 ,2147483648 ,152 ,2147483648 ,152 ,2147483648 ,152 ,152 ,2147483648 ,2147483648 ,2147483648 ,152 ,152 ,152 ,152 ,2147483648 ,152 ,152 ,152 ,152 ,152 ,2147483648 ,152 ,152 ,152 ,2147483648 ,152 ,152 ,152 ,152 ,152 ,152 ,152 ,152 ,2147483648 ,152 ,152 ,152 ,152 ,151 ,152 ,2147483648 ,152 ,152 ,2147483648 ,2147483648 ,2147483648 ,152 ,152 ,152 ,2147483648 ,152 ,152 ,2147483648 ,152 ,152 ,152 ,152 ,152 ,2147483648 ,152 ,152 ,152 ,152 ,152 ,2147483648 ,2147483648 ,152 ,152 ,152 ,152 ,152 ,152 ,152 ,2147483648 ,152 ,152 ,152 ,2147483648 ,152 ,152 ,152 ,2147483648 ,152 ,152 ,2147483648 ,152 ,2147483648 ,152 ,152 ,152 ,152 ,2147483648 ,152 ,152 ,2147483648 ,2147483648 ,152 ,152 ,152 ,152 ,2147483648 ,152 ,2147483648 ,152 ,152 ,152 ,152 ,152 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,185 ,2147483648 ,2147483648 ,2147483648 ,184 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,185 ,2147483648 ,185 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,185 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,185 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,185 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,185 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,36 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,48 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,35 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {142 ,73 ,106 ,104 ,109 ,81 ,113 ,2147483648 ,2147483648 ,117 ,2147483648 ,91 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,76 ,143 ,2147483648 ,2147483648 ,120 ,2147483648 ,121 ,2147483648 ,131 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,84 ,114 ,127 ,96 ,2147483648 ,2147483648 ,2147483648 ,129 ,2147483648 ,87 ,2147483648 ,78 ,2147483648 ,92 ,2147483648 ,2147483648 ,77 ,74 ,99 ,115 ,119 ,140 ,97 ,2147483648 ,2147483648 ,107 ,123 ,94 ,2147483648 ,2147483648 ,2147483648 ,139 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,141 ,2147483648 ,125 ,134 ,2147483648 ,95 ,85 ,2147483648 ,138 ,100 ,2147483648 ,102 ,101 ,135 ,112 ,2147483648 ,2147483648 ,2147483648 ,136 ,133 ,93 ,2147483648 ,111 ,124 ,132 ,2147483648 ,137 ,98 ,126 ,2147483648 ,79 ,128 ,103 ,2147483648 ,130 ,144 ,2147483648 ,89 ,2147483648 ,108 ,118 ,88 ,116 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,90 ,80 ,110 ,105 ,2147483648 ,86 ,2147483648 ,83 ,122 ,75 ,82 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,282 ,282 ,282 ,2147483648 ,282 ,2147483648 ,2147483648 ,282 ,2147483648 ,282 ,2147483648 ,282 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,282 ,283 ,282 ,282 ,282 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,282 ,282 ,282 ,2147483648 ,2147483648 ,2147483648 ,282 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,282 ,282 ,282 ,282 ,2147483648 ,2147483648 ,2147483648 ,282 ,282 ,282 ,282 ,2147483648 ,282 ,282 ,282 ,282 ,2147483648 ,282 ,2147483648 ,282 ,2147483648 ,282 ,282 ,282 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,282 ,282 ,2147483648 ,282 ,2147483648 ,2147483648 ,282 ,282 ,282 ,282 ,282 ,282 ,282 ,2147483648 ,2147483648 ,2147483648 ,282 ,282 ,282 ,2147483648 ,282 ,282 ,282 ,2147483648 ,282 ,2147483648 ,282 ,282 ,2147483648 ,282 ,282 ,2147483648 ,282 ,282 ,282 ,2147483648 ,2147483648 ,282 ,282 ,2147483648 ,282 ,2147483648 ,282 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,282 ,282 ,2147483648 ,2147483648 ,282 ,2147483648 ,282 ,2147483648 ,2147483648 ,282 ,2147483648 },
+ {2147483648 ,2147483648 ,197 ,197 ,197 ,2147483648 ,197 ,2147483648 ,2147483648 ,197 ,2147483648 ,197 ,2147483648 ,197 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,197 ,2147483648 ,197 ,197 ,197 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,197 ,197 ,197 ,2147483648 ,2147483648 ,2147483648 ,197 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,197 ,197 ,197 ,197 ,2147483648 ,2147483648 ,2147483648 ,197 ,197 ,197 ,197 ,2147483648 ,197 ,197 ,197 ,197 ,2147483648 ,197 ,2147483648 ,197 ,2147483648 ,197 ,197 ,197 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,197 ,197 ,2147483648 ,197 ,2147483648 ,2147483648 ,197 ,197 ,197 ,197 ,197 ,197 ,197 ,2147483648 ,2147483648 ,2147483648 ,197 ,197 ,197 ,2147483648 ,197 ,197 ,197 ,2147483648 ,197 ,2147483648 ,197 ,197 ,2147483648 ,197 ,197 ,2147483648 ,197 ,197 ,197 ,2147483648 ,2147483648 ,197 ,197 ,2147483648 ,197 ,2147483648 ,197 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,197 ,197 ,2147483648 ,2147483648 ,197 ,2147483648 ,197 ,2147483648 ,2147483648 ,197 ,2147483648 },
+ {2147483648 ,2147483648 ,193 ,193 ,193 ,2147483648 ,193 ,2147483648 ,2147483648 ,193 ,2147483648 ,193 ,2147483648 ,193 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,193 ,2147483648 ,193 ,193 ,193 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,193 ,193 ,193 ,2147483648 ,2147483648 ,2147483648 ,193 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,193 ,193 ,193 ,193 ,2147483648 ,2147483648 ,2147483648 ,193 ,193 ,193 ,193 ,2147483648 ,193 ,193 ,193 ,193 ,2147483648 ,193 ,2147483648 ,193 ,2147483648 ,193 ,193 ,193 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,193 ,193 ,2147483648 ,193 ,2147483648 ,2147483648 ,193 ,193 ,193 ,193 ,193 ,193 ,193 ,2147483648 ,2147483648 ,2147483648 ,193 ,193 ,193 ,2147483648 ,193 ,193 ,193 ,2147483648 ,193 ,2147483648 ,193 ,193 ,2147483648 ,193 ,193 ,2147483648 ,193 ,193 ,193 ,2147483648 ,2147483648 ,193 ,193 ,2147483648 ,193 ,2147483648 ,193 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,193 ,193 ,2147483648 ,2147483648 ,193 ,2147483648 ,193 ,2147483648 ,2147483648 ,193 ,2147483648 },
+ {2147483648 ,2147483648 ,180 ,180 ,180 ,2147483648 ,180 ,2147483648 ,2147483648 ,180 ,2147483648 ,180 ,2147483648 ,180 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,180 ,2147483648 ,180 ,180 ,180 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,180 ,180 ,180 ,2147483648 ,2147483648 ,2147483648 ,180 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,180 ,180 ,180 ,180 ,2147483648 ,2147483648 ,2147483648 ,180 ,180 ,180 ,180 ,2147483648 ,180 ,180 ,180 ,180 ,2147483648 ,180 ,2147483648 ,180 ,2147483648 ,180 ,180 ,180 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,180 ,180 ,2147483648 ,180 ,2147483648 ,2147483648 ,180 ,180 ,180 ,180 ,180 ,180 ,180 ,2147483648 ,2147483648 ,2147483648 ,180 ,180 ,180 ,2147483648 ,180 ,180 ,180 ,2147483648 ,180 ,2147483648 ,180 ,180 ,2147483648 ,180 ,180 ,2147483648 ,180 ,180 ,180 ,2147483648 ,2147483648 ,180 ,180 ,2147483648 ,180 ,2147483648 ,180 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,180 ,180 ,2147483648 ,2147483648 ,180 ,2147483648 ,180 ,2147483648 ,2147483648 ,180 ,2147483648 },
+ {2147483648 ,2147483648 ,46 ,46 ,46 ,2147483648 ,46 ,2147483648 ,2147483648 ,46 ,2147483648 ,46 ,2147483648 ,46 ,2147483648 ,47 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,46 ,2147483648 ,46 ,46 ,46 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,46 ,46 ,46 ,2147483648 ,2147483648 ,46 ,46 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,46 ,46 ,46 ,46 ,2147483648 ,2147483648 ,2147483648 ,46 ,46 ,46 ,46 ,2147483648 ,46 ,46 ,46 ,46 ,2147483648 ,46 ,2147483648 ,46 ,2147483648 ,46 ,46 ,46 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,46 ,46 ,2147483648 ,46 ,2147483648 ,2147483648 ,46 ,46 ,46 ,46 ,46 ,46 ,46 ,2147483648 ,2147483648 ,2147483648 ,46 ,46 ,46 ,2147483648 ,46 ,46 ,46 ,2147483648 ,46 ,2147483648 ,46 ,46 ,2147483648 ,46 ,46 ,2147483648 ,46 ,46 ,46 ,2147483648 ,2147483648 ,46 ,46 ,2147483648 ,46 ,2147483648 ,46 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,46 ,46 ,2147483648 ,2147483648 ,46 ,2147483648 ,46 ,2147483648 ,2147483648 ,46 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,201 ,2147483648 ,2147483648 ,2147483648 ,201 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,201 ,2147483648 ,201 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,200 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,198 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,201 ,2147483648 ,2147483648 ,201 ,201 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,201 ,2147483648 ,2147483648 ,199 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,201 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,201 ,2147483648 ,2147483648 ,201 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,201 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,201 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,155 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,30 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,215 ,213 ,218 ,2147483648 ,222 ,2147483648 ,2147483648 ,226 ,2147483648 ,202 ,2147483648 ,263 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,229 ,2147483648 ,230 ,251 ,240 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,223 ,236 ,207 ,2147483648 ,2147483648 ,2147483648 ,238 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,252 ,203 ,263 ,268 ,2147483648 ,2147483648 ,2147483648 ,224 ,228 ,249 ,208 ,2147483648 ,253 ,216 ,232 ,205 ,2147483648 ,252 ,2147483648 ,248 ,2147483648 ,265 ,269 ,267 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,234 ,243 ,2147483648 ,206 ,2147483648 ,2147483648 ,247 ,209 ,263 ,211 ,210 ,244 ,221 ,2147483648 ,2147483648 ,2147483648 ,245 ,242 ,204 ,2147483648 ,220 ,233 ,241 ,2147483648 ,246 ,2147483648 ,235 ,264 ,2147483648 ,237 ,212 ,2147483648 ,239 ,250 ,266 ,2147483648 ,2147483648 ,217 ,227 ,2147483648 ,225 ,2147483648 ,252 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,219 ,214 ,2147483648 ,2147483648 ,263 ,2147483648 ,231 ,2147483648 ,2147483648 ,252 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,278 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,279 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,145 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,146 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,38 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,39 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,196 ,2147483648 ,2147483648 ,2147483648 ,196 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,196 ,2147483648 ,196 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,196 ,2147483648 ,2147483648 ,195 ,196 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,196 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,196 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,196 ,2147483648 ,2147483648 ,194 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,196 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,196 },
+ {2147483648 ,2147483648 ,29 ,29 ,29 ,2147483648 ,29 ,2147483648 ,2147483648 ,29 ,2147483648 ,29 ,2147483648 ,29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,29 ,2147483648 ,29 ,29 ,29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,29 ,29 ,29 ,2147483648 ,2147483648 ,2147483648 ,29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,29 ,29 ,29 ,29 ,2147483648 ,2147483648 ,2147483648 ,29 ,29 ,29 ,29 ,2147483648 ,29 ,29 ,29 ,29 ,2147483648 ,29 ,2147483648 ,29 ,2147483648 ,29 ,29 ,29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,29 ,29 ,2147483648 ,29 ,2147483648 ,2147483648 ,29 ,29 ,29 ,29 ,29 ,29 ,29 ,2147483648 ,2147483648 ,2147483648 ,29 ,29 ,29 ,2147483648 ,29 ,29 ,29 ,2147483648 ,29 ,2147483648 ,29 ,29 ,2147483648 ,29 ,29 ,28 ,29 ,29 ,29 ,2147483648 ,2147483648 ,29 ,29 ,2147483648 ,29 ,2147483648 ,29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,29 ,29 ,2147483648 ,2147483648 ,29 ,2147483648 ,29 ,2147483648 ,2147483648 ,29 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,57 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,183 ,183 ,183 ,2147483648 ,183 ,2147483648 ,2147483648 ,183 ,2147483648 ,183 ,2147483648 ,183 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,183 ,2147483648 ,183 ,183 ,183 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,183 ,183 ,183 ,2147483648 ,2147483648 ,2147483648 ,183 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,183 ,183 ,183 ,183 ,2147483648 ,2147483648 ,2147483648 ,183 ,183 ,183 ,183 ,2147483648 ,183 ,183 ,183 ,183 ,2147483648 ,183 ,2147483648 ,183 ,2147483648 ,183 ,183 ,183 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,183 ,183 ,2147483648 ,183 ,2147483648 ,2147483648 ,183 ,183 ,183 ,183 ,183 ,183 ,183 ,2147483648 ,2147483648 ,2147483648 ,183 ,183 ,183 ,2147483648 ,183 ,183 ,183 ,2147483648 ,183 ,2147483648 ,183 ,183 ,2147483648 ,183 ,183 ,2147483648 ,183 ,183 ,183 ,2147483648 ,2147483648 ,183 ,183 ,2147483648 ,183 ,2147483648 ,183 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,183 ,183 ,2147483648 ,2147483648 ,183 ,2147483648 ,183 ,2147483648 ,2147483648 ,183 ,2147483648 },
+ {150 ,150 ,150 ,150 ,150 ,150 ,150 ,2147483648 ,2147483648 ,150 ,2147483648 ,150 ,2147483648 ,2147483648 ,2147483648 ,150 ,150 ,150 ,2147483648 ,2147483648 ,150 ,2147483648 ,150 ,2147483648 ,150 ,150 ,2147483648 ,2147483648 ,2147483648 ,150 ,150 ,150 ,150 ,2147483648 ,150 ,150 ,150 ,150 ,150 ,2147483648 ,150 ,150 ,150 ,2147483648 ,150 ,150 ,150 ,150 ,150 ,150 ,150 ,150 ,2147483648 ,150 ,150 ,150 ,150 ,150 ,150 ,2147483648 ,150 ,150 ,2147483648 ,2147483648 ,2147483648 ,150 ,150 ,150 ,2147483648 ,150 ,150 ,2147483648 ,150 ,150 ,150 ,150 ,150 ,2147483648 ,150 ,150 ,150 ,150 ,150 ,2147483648 ,2147483648 ,150 ,150 ,150 ,150 ,150 ,150 ,150 ,2147483648 ,150 ,150 ,150 ,2147483648 ,150 ,150 ,150 ,2147483648 ,150 ,150 ,2147483648 ,150 ,2147483648 ,150 ,150 ,150 ,150 ,2147483648 ,150 ,150 ,2147483648 ,2147483648 ,150 ,150 ,150 ,150 ,2147483648 ,150 ,2147483648 ,150 ,150 ,150 ,150 ,150 ,2147483648 },
+ {2147483648 ,2147483648 ,277 ,277 ,277 ,2147483648 ,277 ,2147483648 ,2147483648 ,277 ,2147483648 ,277 ,2147483648 ,277 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,277 ,2147483648 ,277 ,277 ,277 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,277 ,277 ,277 ,2147483648 ,2147483648 ,2147483648 ,277 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,277 ,277 ,277 ,277 ,2147483648 ,2147483648 ,2147483648 ,277 ,277 ,277 ,277 ,2147483648 ,277 ,277 ,277 ,277 ,2147483648 ,277 ,2147483648 ,277 ,2147483648 ,277 ,277 ,277 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,277 ,277 ,2147483648 ,277 ,2147483648 ,2147483648 ,277 ,277 ,277 ,277 ,277 ,277 ,277 ,2147483648 ,2147483648 ,2147483648 ,277 ,277 ,277 ,2147483648 ,277 ,277 ,277 ,2147483648 ,277 ,2147483648 ,277 ,277 ,2147483648 ,277 ,277 ,2147483648 ,277 ,277 ,277 ,2147483648 ,2147483648 ,277 ,277 ,2147483648 ,277 ,2147483648 ,277 ,2147483648 ,2147483648 ,276 ,2147483648 ,2147483648 ,277 ,277 ,2147483648 ,2147483648 ,277 ,2147483648 ,277 ,2147483648 ,2147483648 ,277 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,256 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,45 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,44 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,192 ,2147483648 ,2147483648 ,2147483648 ,192 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,192 ,2147483648 ,192 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,192 ,2147483648 ,2147483648 ,2147483648 ,192 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,191 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,192 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,192 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,192 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,190 },
+ {14 ,14 ,14 ,14 ,14 ,14 ,14 ,2147483648 ,2147483648 ,14 ,2147483648 ,14 ,2147483648 ,2147483648 ,2147483648 ,16 ,14 ,14 ,2147483648 ,2147483648 ,14 ,2147483648 ,14 ,2147483648 ,14 ,14 ,2147483648 ,2147483648 ,2147483648 ,14 ,14 ,14 ,14 ,2147483648 ,14 ,15 ,14 ,14 ,14 ,2147483648 ,14 ,14 ,14 ,2147483648 ,14 ,14 ,14 ,14 ,14 ,14 ,14 ,14 ,2147483648 ,14 ,14 ,14 ,14 ,2147483648 ,14 ,2147483648 ,14 ,14 ,2147483648 ,2147483648 ,2147483648 ,14 ,14 ,14 ,2147483648 ,14 ,14 ,2147483648 ,14 ,14 ,2147483648 ,14 ,14 ,2147483648 ,14 ,14 ,14 ,14 ,14 ,2147483648 ,2147483648 ,14 ,14 ,14 ,2147483648 ,14 ,14 ,14 ,2147483648 ,14 ,14 ,14 ,2147483648 ,14 ,14 ,14 ,2147483648 ,14 ,14 ,2147483648 ,14 ,2147483648 ,14 ,14 ,14 ,14 ,2147483648 ,14 ,14 ,2147483648 ,2147483648 ,14 ,14 ,14 ,14 ,2147483648 ,14 ,2147483648 ,14 ,14 ,14 ,14 ,14 ,2147483648 }
};
const char* KeywordList[]= {
"print",
@@ -993,6 +1144,11 @@ const char* KeywordList[]= {
"event_trace_instrumentation_step_in",
"rdtsc",
"rdtscp",
+"lbr_save",
+"lbr_dump",
+"lbr_print",
+"lbr_restore",
+"lbr_check",
"spinlock_lock_custom_wait",
"event_inject",
"poi",
@@ -1020,6 +1176,7 @@ const char* KeywordList[]= {
"dd_pa",
"dw_pa",
"dq_pa",
+"lbr_restore_by_filter",
"ed",
"eb",
"eq",
@@ -1041,6 +1198,11 @@ const char* KeywordList[]= {
"wcsncmp",
"rdtsc",
"rdtscp",
+"lbr_save",
+"lbr_dump",
+"lbr_print",
+"lbr_restore",
+"lbr_check",
"poi",
"db",
"dd",
@@ -1066,6 +1228,7 @@ const char* KeywordList[]= {
"dd_pa",
"dw_pa",
"dq_pa",
+"lbr_restore_by_filter",
"ed",
"eb",
"eq",
@@ -1104,8 +1267,7 @@ const char* OperatorsTwoOperandList[]= {
const char* OperatorsOneOperandList[]= {
"@INC",
"@DEC",
-"@REFERENCE",
-"@DEREFERENCE"
+"@REFERENCE"
};
const char* AssignmentOperatorList[]= {
"@ADD_ASSIGNMENT",
@@ -1167,6 +1329,7 @@ const char* OneOpFunc1[] = {
"@DD_PA",
"@DW_PA",
"@DQ_PA",
+"@LBR_RESTORE_BY_FILTER",
};
const char* OneOpFunc2[] = {
"@PRINT",
@@ -1211,6 +1374,11 @@ const char* ZeroOpFunc1[] = {
const char* ZeroOpFunc2[] = {
"@RDTSC",
"@RDTSCP",
+"@LBR_SAVE",
+"@LBR_DUMP",
+"@LBR_PRINT",
+"@LBR_RESTORE",
+"@LBR_CHECK",
};
const char* VarArgFunc1[] = {
"@PRINTF"
@@ -1219,7 +1387,6 @@ const SYMBOL_MAP SemanticRulesMapList[]= {
{"@INC", FUNC_INC},
{"@DEC", FUNC_DEC},
{"@REFERENCE", FUNC_REFERENCE},
-{"@DEREFERENCE", FUNC_DEREFERENCE},
{"@OR", FUNC_OR},
{"@XOR", FUNC_XOR},
{"@AND", FUNC_AND},
@@ -1272,6 +1439,11 @@ const SYMBOL_MAP SemanticRulesMapList[]= {
{"@EVENT_TRACE_INSTRUMENTATION_STEP_IN", FUNC_EVENT_TRACE_INSTRUMENTATION_STEP_IN},
{"@RDTSC", FUNC_RDTSC},
{"@RDTSCP", FUNC_RDTSCP},
+{"@LBR_SAVE", FUNC_LBR_SAVE},
+{"@LBR_DUMP", FUNC_LBR_DUMP},
+{"@LBR_PRINT", FUNC_LBR_PRINT},
+{"@LBR_RESTORE", FUNC_LBR_RESTORE},
+{"@LBR_CHECK", FUNC_LBR_CHECK},
{"@SPINLOCK_LOCK_CUSTOM_WAIT", FUNC_SPINLOCK_LOCK_CUSTOM_WAIT},
{"@EVENT_INJECT", FUNC_EVENT_INJECT},
{"@POI", FUNC_POI},
@@ -1299,6 +1471,7 @@ const SYMBOL_MAP SemanticRulesMapList[]= {
{"@DD_PA", FUNC_DD_PA},
{"@DW_PA", FUNC_DW_PA},
{"@DQ_PA", FUNC_DQ_PA},
+{"@LBR_RESTORE_BY_FILTER", FUNC_LBR_RESTORE_BY_FILTER},
{"@ED", FUNC_ED},
{"@EB", FUNC_EB},
{"@EQ", FUNC_EQ},
@@ -1320,6 +1493,11 @@ const SYMBOL_MAP SemanticRulesMapList[]= {
{"@WCSNCMP", FUNC_WCSNCMP},
{"@RDTSC", FUNC_RDTSC},
{"@RDTSCP", FUNC_RDTSCP},
+{"@LBR_SAVE", FUNC_LBR_SAVE},
+{"@LBR_DUMP", FUNC_LBR_DUMP},
+{"@LBR_PRINT", FUNC_LBR_PRINT},
+{"@LBR_RESTORE", FUNC_LBR_RESTORE},
+{"@LBR_CHECK", FUNC_LBR_CHECK},
{"@POI", FUNC_POI},
{"@DB", FUNC_DB},
{"@DD", FUNC_DD},
@@ -1345,6 +1523,7 @@ const SYMBOL_MAP SemanticRulesMapList[]= {
{"@DD_PA", FUNC_DD_PA},
{"@DW_PA", FUNC_DW_PA},
{"@DQ_PA", FUNC_DQ_PA},
+{"@LBR_RESTORE_BY_FILTER", FUNC_LBR_RESTORE_BY_FILTER},
{"@ED", FUNC_ED},
{"@EB", FUNC_EB},
{"@EQ", FUNC_EQ},
@@ -1618,6 +1797,15 @@ const struct _SCRIPT_ENGINE_TOKEN LalrLhs[RULES_COUNT]=
{NON_TERMINAL, "E12"},
{NON_TERMINAL, "E12"},
{NON_TERMINAL, "E12"},
+ {NON_TERMINAL, "E12"},
+ {NON_TERMINAL, "E12"},
+ {NON_TERMINAL, "E12"},
+ {NON_TERMINAL, "E12"},
+ {NON_TERMINAL, "E12"},
+ {NON_TERMINAL, "E12"},
+ {NON_TERMINAL, "E12"},
+ {NON_TERMINAL, "E12"},
+ {NON_TERMINAL, "E12"},
{NON_TERMINAL, "E13"},
{NON_TERMINAL, "VA2"},
{NON_TERMINAL, "VA2"},
@@ -1628,7 +1816,12 @@ const struct _SCRIPT_ENGINE_TOKEN LalrLhs[RULES_COUNT]=
{NON_TERMINAL, "StringNumber"},
{NON_TERMINAL, "StringNumber"},
{NON_TERMINAL, "WstringNumber"},
- {NON_TERMINAL, "WstringNumber"}
+ {NON_TERMINAL, "WstringNumber"},
+ {NON_TERMINAL, "ARRAY1"},
+ {NON_TERMINAL, "ARRAY2"},
+ {NON_TERMINAL, "ARRAY3"},
+ {NON_TERMINAL, "ARRAY4"},
+ {NON_TERMINAL, "ARRAY4"}
};
const struct _SCRIPT_ENGINE_TOKEN LalrRhs[RULES_COUNT][MAX_RHS_LEN]=
{
@@ -1669,6 +1862,13 @@ const struct _SCRIPT_ENGINE_TOKEN LalrRhs[RULES_COUNT][MAX_RHS_LEN]=
{{KEYWORD, "~"},{NON_TERMINAL, "E12"},{SEMANTIC_RULE, "@NOT"}},
{{SPECIAL_TOKEN, "*"},{NON_TERMINAL, "E12"},{SEMANTIC_RULE, "@POI"}},
{{SPECIAL_TOKEN, "&"},{NON_TERMINAL, "E12"},{SEMANTIC_RULE, "@REFERENCE"}},
+ {{KEYWORD, "rdtsc"},{SPECIAL_TOKEN, "("},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@RDTSC"}},
+ {{KEYWORD, "rdtscp"},{SPECIAL_TOKEN, "("},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@RDTSCP"}},
+ {{KEYWORD, "lbr_save"},{SPECIAL_TOKEN, "("},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@LBR_SAVE"}},
+ {{KEYWORD, "lbr_dump"},{SPECIAL_TOKEN, "("},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@LBR_DUMP"}},
+ {{KEYWORD, "lbr_print"},{SPECIAL_TOKEN, "("},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@LBR_PRINT"}},
+ {{KEYWORD, "lbr_restore"},{SPECIAL_TOKEN, "("},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@LBR_RESTORE"}},
+ {{KEYWORD, "lbr_check"},{SPECIAL_TOKEN, "("},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@LBR_CHECK"}},
{{KEYWORD, "poi"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXP"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@POI"}},
{{KEYWORD, "db"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXP"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@DB"}},
{{KEYWORD, "dd"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXP"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@DD"}},
@@ -1696,6 +1896,7 @@ const struct _SCRIPT_ENGINE_TOKEN LalrRhs[RULES_COUNT][MAX_RHS_LEN]=
{{KEYWORD, "dd_pa"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXP"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@DD_PA"}},
{{KEYWORD, "dw_pa"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXP"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@DW_PA"}},
{{KEYWORD, "dq_pa"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXP"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@DQ_PA"}},
+ {{KEYWORD, "lbr_restore_by_filter"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXP"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@LBR_RESTORE_BY_FILTER"}},
{{KEYWORD, "ed"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXP"},{SPECIAL_TOKEN, ","},{NON_TERMINAL, "EXP"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@ED"}},
{{KEYWORD, "eb"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXP"},{SPECIAL_TOKEN, ","},{NON_TERMINAL, "EXP"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@EB"}},
{{KEYWORD, "eq"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "EXP"},{SPECIAL_TOKEN, ","},{NON_TERMINAL, "EXP"},{SPECIAL_TOKEN, ")"},{SEMANTIC_RULE, "@EQ"}},
@@ -1718,6 +1919,7 @@ const struct _SCRIPT_ENGINE_TOKEN LalrRhs[RULES_COUNT][MAX_RHS_LEN]=
{{GLOBAL_ID, "_global_id"},{SEMANTIC_RULE, "@PUSH"}},
{{LOCAL_ID, "_local_id"},{SEMANTIC_RULE, "@PUSH"}},
{{FUNCTION_PARAMETER_ID, "_function_parameter_id"},{SEMANTIC_RULE, "@PUSH"}},
+ {{NON_TERMINAL, "ARRAY1"}},
{{HEX, "_hex"},{SEMANTIC_RULE, "@PUSH"}},
{{DECIMAL, "_decimal"},{SEMANTIC_RULE, "@PUSH"}},
{{OCTAL, "_octal"},{SEMANTIC_RULE, "@PUSH"}},
@@ -1734,7 +1936,12 @@ const struct _SCRIPT_ENGINE_TOKEN LalrRhs[RULES_COUNT][MAX_RHS_LEN]=
{{NON_TERMINAL, "EXP"}},
{{NON_TERMINAL, "STRING"}},
{{NON_TERMINAL, "EXP"}},
- {{NON_TERMINAL, "WSTRING"}}
+ {{NON_TERMINAL, "WSTRING"}},
+ {{NON_TERMINAL, "ARRAY2"},{NON_TERMINAL, "ARRAY3"},{NON_TERMINAL, "ARRAY4"},{SEMANTIC_RULE, "@ARRAY_INDEX_READ"}},
+ {{LOCAL_ID, "_local_id"},{SEMANTIC_RULE, "@PUSH"}},
+ {{SPECIAL_TOKEN, "["},{NON_TERMINAL, "EXP"},{SPECIAL_TOKEN, "]"},{SEMANTIC_RULE, "@ARRAY_DIM_NUMBER"}},
+ {{NON_TERMINAL, "ARRAY3"},{NON_TERMINAL, "ARRAY4"}},
+ {{EPSILON, "eps"}}
};
const unsigned int LalrRhsSize[RULES_COUNT]=
{
@@ -1775,6 +1982,14 @@ const unsigned int LalrRhsSize[RULES_COUNT]=
3,
3,
3,
+4,
+4,
+4,
+4,
+4,
+4,
+4,
+5,
5,
5,
5,
@@ -1824,6 +2039,7 @@ const unsigned int LalrRhsSize[RULES_COUNT]=
2,
2,
2,
+1,
2,
2,
2,
@@ -1840,713 +2056,800 @@ const unsigned int LalrRhsSize[RULES_COUNT]=
1,
1,
1,
+1,
+4,
+2,
+4,
+2,
1
};
const char* LalrNoneTerminalMap[NONETERMINAL_COUNT]=
{
-"EXP",
-"WstringNumber",
-"E5",
-"VA3",
-"B2",
-"CMP",
-"BE",
-"S",
-"WSTRING",
-"B5",
-"VA2",
-"E10",
-"STRING",
-"E12",
-"B4",
-"B1",
-"E13",
-"B6",
"StringNumber",
+"WSTRING",
+"ARRAY1",
+"ARRAY2",
+"EXP",
+"E10",
+"S",
+"B5",
"E3",
+"STRING",
+"BE",
+"ARRAY3",
+"WstringNumber",
+"E13",
+"E5",
+"E4",
+"E12",
+"CMP",
+"VA3",
+"ARRAY4",
+"B2",
+"B4",
+"VA2",
"B3",
-"E4"
+"B6",
+"B1"
};
const char* LalrTerminalMap[TERMINAL_COUNT]=
{
-">>",
-"low_pa",
-"dd_pa",
-"_string",
-"memcmp",
-"physical_to_virtual",
-"_register",
-"_function_parameter_id",
-"db",
-"dw",
-"&&",
-"dq",
-"<",
-"_decimal",
-"disassemble_len",
"hi",
-"eb_pa",
-"*",
-"interlocked_compare_exchange",
-"_binary",
-"&",
-"wcslen",
-"ed",
-"_local_id",
-"disassemble_len64",
-"strcmp",
-"strncmp",
-">",
-"-",
-",",
-"wcscmp",
-"reference",
-"eb",
-"==",
-"poi",
-"_wstring",
-"wcsncmp",
-"%",
-"interlocked_increment",
-"strlen",
-"eq",
-"_global_id",
-"virtual_to_physical",
-"interlocked_exchange",
-"not",
-"_hex",
-"_octal",
-"<<",
-"||",
-"/",
-"_function_id",
-"low",
-">=",
-"interlocked_decrement",
-"dd",
-"dw_pa",
+"dq",
"check_address",
-"|",
-"interlocked_exchange_add",
-"neg",
-"^",
-"disassemble_len32",
-"hi_pa",
-")",
-"+",
-"_pseudo_register",
-"<=",
-"dq_pa",
-"poi_pa",
-"ed_pa",
-"eq_pa",
+"interlocked_increment",
+"_string",
+"virtual_to_physical",
"!=",
+"rdtsc",
+"[",
+"_octal",
+"^",
+"low_pa",
+"_wstring",
"db_pa",
-"$",
+"(",
+"|",
+"eb_pa",
+"interlocked_decrement",
+"eb",
+"lbr_restore",
+"<",
+"interlocked_exchange",
+"_local_id",
+"rdtscp",
+"_binary",
+"*",
+"reference",
+"hi_pa",
+"wcscmp",
+"/",
+"lbr_check",
+"dw_pa",
+"low",
+"_function_id",
+"lbr_dump",
+"_register",
+"]",
+"wcslen",
+"-",
+"&",
"~",
-"("
+">=",
+"<<",
+">",
+"lbr_restore_by_filter",
+"interlocked_compare_exchange",
+"%",
+"lbr_print",
+"$",
+"strncmp",
+"poi",
+"_decimal",
+"dd",
+"&&",
+"db",
+"strlen",
+"disassemble_len64",
+",",
+"strcmp",
+"eq_pa",
+"lbr_save",
+"disassemble_len32",
+"dq_pa",
+"ed_pa",
+"||",
+"<=",
+"memcmp",
+"ed",
+"_pseudo_register",
+"eq",
+"dw",
+"interlocked_exchange_add",
+"wcsncmp",
+"+",
+"==",
+"not",
+"poi_pa",
+"physical_to_virtual",
+"_global_id",
+")",
+"disassemble_len",
+"neg",
+"_hex",
+"dd_pa",
+"_function_parameter_id",
+">>"
};
const int LalrGotoTable[LALR_STATE_COUNT][LALR_NONTERMINAL_COUNT]=
{
- {10 ,2147483648 ,13 ,2147483648 ,4 ,9 ,2 ,1 ,2147483648 ,7 ,2147483648 ,14 ,2147483648 ,15 ,6 ,3 ,16 ,8 ,2147483648 ,11 ,5 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,97 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,111 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {10 ,2147483648 ,13 ,2147483648 ,4 ,9 ,117 ,2147483648 ,2147483648 ,7 ,2147483648 ,14 ,2147483648 ,15 ,6 ,3 ,16 ,8 ,2147483648 ,11 ,5 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,121 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,122 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,132 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {10 ,2147483648 ,13 ,2147483648 ,140 ,9 ,2147483648 ,2147483648 ,2147483648 ,7 ,2147483648 ,14 ,2147483648 ,15 ,6 ,2147483648 ,16 ,8 ,2147483648 ,11 ,5 ,12 },
- {10 ,2147483648 ,13 ,2147483648 ,2147483648 ,9 ,2147483648 ,2147483648 ,2147483648 ,7 ,2147483648 ,14 ,2147483648 ,15 ,6 ,2147483648 ,16 ,8 ,2147483648 ,11 ,141 ,12 },
- {10 ,2147483648 ,13 ,2147483648 ,2147483648 ,9 ,2147483648 ,2147483648 ,2147483648 ,7 ,2147483648 ,14 ,2147483648 ,15 ,142 ,2147483648 ,16 ,8 ,2147483648 ,11 ,2147483648 ,12 },
- {10 ,2147483648 ,13 ,2147483648 ,2147483648 ,9 ,2147483648 ,2147483648 ,2147483648 ,143 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,8 ,2147483648 ,11 ,2147483648 ,12 },
- {10 ,2147483648 ,13 ,2147483648 ,2147483648 ,9 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,144 ,2147483648 ,11 ,2147483648 ,12 },
- {145 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {146 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {147 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {148 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {149 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {150 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,151 },
- {2147483648 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,152 },
- {2147483648 ,2147483648 ,153 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,154 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,155 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,156 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,157 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {158 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,159 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {160 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {161 ,163 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,162 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {165 ,166 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,162 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {167 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {168 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {169 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {170 ,171 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,162 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {172 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {173 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {174 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {175 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {176 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {177 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {178 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {179 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {180 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {181 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {182 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {183 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {184 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {185 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {186 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,187 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,188 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {191 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {186 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,187 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,192 ,11 ,2147483648 ,12 },
- {193 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {194 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {195 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {196 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {186 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,187 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,197 ,11 ,2147483648 ,12 },
- {198 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {199 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {200 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {201 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {202 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {203 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {204 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {205 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {206 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {207 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {208 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {209 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,187 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,210 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,211 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {258 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {165 ,259 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,162 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {260 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {261 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {165 ,262 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,162 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {263 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {264 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {265 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {186 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,187 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,266 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {186 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,187 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,267 ,11 ,2147483648 ,12 },
- {268 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {269 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {186 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,187 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,270 ,11 ,2147483648 ,12 },
- {271 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {272 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {273 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,274 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {290 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {291 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {292 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {293 ,2147483648 ,13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,14 ,2147483648 ,15 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,11 ,2147483648 ,12 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 }
+ {2147483648 ,2147483648 ,17 ,18 ,10 ,14 ,1 ,7 ,11 ,2147483648 ,2 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,9 ,2147483648 ,2147483648 ,4 ,6 ,2147483648 ,5 ,8 ,3 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,103 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,108 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,10 ,14 ,2147483648 ,7 ,11 ,2147483648 ,137 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,9 ,2147483648 ,2147483648 ,4 ,6 ,2147483648 ,5 ,8 ,3 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,148 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,153 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,157 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,158 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,10 ,14 ,2147483648 ,7 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,9 ,2147483648 ,2147483648 ,160 ,6 ,2147483648 ,5 ,8 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,10 ,14 ,2147483648 ,7 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,9 ,2147483648 ,2147483648 ,2147483648 ,6 ,2147483648 ,161 ,8 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,10 ,14 ,2147483648 ,7 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,9 ,2147483648 ,2147483648 ,2147483648 ,162 ,2147483648 ,2147483648 ,8 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,10 ,14 ,2147483648 ,163 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,9 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,8 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,10 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,9 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,164 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,165 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,166 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,167 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,168 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,169 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,170 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,2147483648 ,14 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,171 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,2147483648 ,14 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,172 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,2147483648 ,14 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,173 ,2147483648 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,2147483648 ,14 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,174 ,2147483648 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,2147483648 ,175 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,2147483648 ,176 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,2147483648 ,177 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,2147483648 ,2147483648 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,178 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,179 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,180 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,181 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,182 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,184 ,17 ,18 ,183 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,185 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,187 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,189 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,190 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {195 ,2147483648 ,17 ,18 ,193 ,14 ,2147483648 ,2147483648 ,11 ,194 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,197 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {198 ,2147483648 ,17 ,18 ,193 ,14 ,2147483648 ,2147483648 ,11 ,194 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {199 ,2147483648 ,17 ,18 ,193 ,14 ,2147483648 ,2147483648 ,11 ,194 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,200 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,201 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,184 ,17 ,18 ,202 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,203 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {205 ,2147483648 ,17 ,18 ,204 ,14 ,2147483648 ,2147483648 ,11 ,194 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,206 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,208 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,209 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,212 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,184 ,17 ,18 ,213 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,214 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,215 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,216 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,217 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,218 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,219 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,220 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,221 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,222 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,224 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,225 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,227 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,228 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,229 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,230 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,231 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,232 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,233 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,234 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,235 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,236 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,237 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,238 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,239 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,240 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,241 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,242 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,180 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,245 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,292 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,293 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,184 ,17 ,18 ,213 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,294 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {295 ,2147483648 ,17 ,18 ,193 ,14 ,2147483648 ,2147483648 ,11 ,194 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {296 ,2147483648 ,17 ,18 ,193 ,14 ,2147483648 ,2147483648 ,11 ,194 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {297 ,2147483648 ,17 ,18 ,193 ,14 ,2147483648 ,2147483648 ,11 ,194 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,298 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,299 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,184 ,17 ,18 ,213 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,300 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,301 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,302 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,303 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,304 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,305 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,306 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,307 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,308 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,324 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,325 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,326 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,17 ,18 ,327 ,14 ,2147483648 ,2147483648 ,11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,16 ,13 ,12 ,15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 }
};
const int LalrActionTable[LALR_STATE_COUNT][LALR_TERMINAL_COUNT]=
{
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483647 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-1 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,74 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-2 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-2 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,75 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-4 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-4 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-4 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-6 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-6 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,76 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-6 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-6 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-8 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-8 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-8 ,2147483648 ,2147483648 ,77 ,2147483648 ,2147483648 ,-8 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-8 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-10 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,78 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-10 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-10 ,2147483648 ,2147483648 ,-10 ,2147483648 ,2147483648 ,-10 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-10 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-12 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-12 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-12 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-12 ,2147483648 ,2147483648 ,-12 ,2147483648 ,2147483648 ,-12 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-12 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-13 ,2147483648 ,80 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,83 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,79 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-13 ,2147483648 ,2147483648 ,2147483648 ,84 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-13 ,2147483648 ,2147483648 ,-13 ,2147483648 ,2147483648 ,-13 ,2147483648 ,2147483648 ,82 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,81 ,2147483648 ,-13 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-20 ,2147483648 ,-20 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-20 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-20 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-20 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-20 ,2147483648 ,2147483648 ,2147483648 ,-20 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-20 ,2147483648 ,2147483648 ,-20 ,2147483648 ,2147483648 ,-20 ,2147483648 ,2147483648 ,-20 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-20 ,2147483648 ,-20 ,2147483648 ,2147483648 },
- {85 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-21 ,2147483648 ,-21 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-21 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-21 ,2147483648 ,-21 ,2147483648 ,2147483648 ,2147483648 ,-21 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,86 ,-21 ,2147483648 ,2147483648 ,2147483648 ,-21 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-21 ,2147483648 ,2147483648 ,-21 ,2147483648 ,2147483648 ,-21 ,2147483648 ,2147483648 ,-21 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-21 ,2147483648 ,-21 ,2147483648 ,2147483648 },
- {-24 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-24 ,2147483648 ,-24 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-24 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-24 ,88 ,-24 ,2147483648 ,2147483648 ,2147483648 ,-24 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-24 ,-24 ,2147483648 ,2147483648 ,2147483648 ,-24 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-24 ,2147483648 ,2147483648 ,-24 ,2147483648 ,2147483648 ,-24 ,87 ,2147483648 ,-24 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-24 ,2147483648 ,-24 ,2147483648 ,2147483648 },
- {-27 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-27 ,2147483648 ,-27 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,91 ,2147483648 ,2147483648 ,-27 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-27 ,-27 ,-27 ,2147483648 ,2147483648 ,2147483648 ,-27 ,2147483648 ,2147483648 ,2147483648 ,90 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-27 ,-27 ,89 ,2147483648 ,2147483648 ,-27 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-27 ,2147483648 ,2147483648 ,-27 ,2147483648 ,2147483648 ,-27 ,-27 ,2147483648 ,-27 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-27 ,2147483648 ,-27 ,2147483648 ,2147483648 },
- {-31 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-31 ,2147483648 ,-31 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-31 ,2147483648 ,2147483648 ,-31 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-31 ,-31 ,-31 ,2147483648 ,2147483648 ,2147483648 ,-31 ,2147483648 ,2147483648 ,2147483648 ,-31 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-31 ,-31 ,-31 ,2147483648 ,2147483648 ,-31 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-31 ,2147483648 ,2147483648 ,-31 ,2147483648 ,2147483648 ,-31 ,-31 ,2147483648 ,-31 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-31 ,2147483648 ,-31 ,2147483648 ,2147483648 },
- {-32 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-32 ,2147483648 ,-32 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-32 ,2147483648 ,2147483648 ,-32 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-32 ,-32 ,-32 ,2147483648 ,2147483648 ,2147483648 ,-32 ,2147483648 ,2147483648 ,2147483648 ,-32 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-32 ,-32 ,-32 ,2147483648 ,2147483648 ,-32 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-32 ,2147483648 ,2147483648 ,-32 ,2147483648 ,2147483648 ,-32 ,-32 ,2147483648 ,-32 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-32 ,2147483648 ,-32 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,92 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,93 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,94 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,95 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,96 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,2147483648 ,60 ,24 ,2147483648 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,2147483648 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,2147483648 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,2147483648 ,45 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,98 },
- {-83 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-83 ,2147483648 ,-83 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-83 ,2147483648 ,2147483648 ,-83 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-83 ,-83 ,-83 ,2147483648 ,2147483648 ,2147483648 ,-83 ,2147483648 ,2147483648 ,2147483648 ,-83 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-83 ,-83 ,-83 ,2147483648 ,2147483648 ,-83 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-83 ,2147483648 ,2147483648 ,-83 ,2147483648 ,2147483648 ,-83 ,-83 ,2147483648 ,-83 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-83 ,2147483648 ,-83 ,2147483648 ,2147483648 },
- {-90 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-90 ,2147483648 ,-90 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-90 ,2147483648 ,2147483648 ,-90 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-90 ,-90 ,-90 ,2147483648 ,2147483648 ,2147483648 ,-90 ,2147483648 ,2147483648 ,2147483648 ,-90 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-90 ,-90 ,-90 ,2147483648 ,2147483648 ,-90 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-90 ,2147483648 ,2147483648 ,-90 ,2147483648 ,2147483648 ,-90 ,-90 ,2147483648 ,-90 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-90 ,2147483648 ,-90 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,99 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,100 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,101 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,102 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,103 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,104 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,105 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,106 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,107 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,108 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,109 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,110 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,2147483648 ,60 ,24 ,2147483648 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,2147483648 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,2147483648 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,2147483648 ,45 },
- {-89 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-89 ,2147483648 ,-89 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-89 ,2147483648 ,2147483648 ,-89 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-89 ,-89 ,-89 ,2147483648 ,2147483648 ,2147483648 ,-89 ,2147483648 ,2147483648 ,2147483648 ,-89 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-89 ,-89 ,-89 ,2147483648 ,2147483648 ,-89 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-89 ,2147483648 ,2147483648 ,-89 ,2147483648 ,2147483648 ,-89 ,-89 ,2147483648 ,-89 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-89 ,2147483648 ,-89 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,112 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,113 },
- {-86 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-86 ,2147483648 ,-86 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-86 ,2147483648 ,2147483648 ,-86 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-86 ,-86 ,-86 ,2147483648 ,2147483648 ,2147483648 ,-86 ,2147483648 ,2147483648 ,2147483648 ,-86 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-86 ,-86 ,-86 ,2147483648 ,2147483648 ,-86 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-86 ,2147483648 ,2147483648 ,-86 ,2147483648 ,2147483648 ,-86 ,-86 ,2147483648 ,-86 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-86 ,2147483648 ,-86 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,114 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,115 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,116 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,118 },
- {-88 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-88 ,2147483648 ,-88 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-88 ,2147483648 ,2147483648 ,-88 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-88 ,-88 ,-88 ,2147483648 ,2147483648 ,2147483648 ,-88 ,2147483648 ,2147483648 ,2147483648 ,-88 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-88 ,-88 ,-88 ,2147483648 ,2147483648 ,-88 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-88 ,2147483648 ,2147483648 ,-88 ,2147483648 ,2147483648 ,-88 ,-88 ,2147483648 ,-88 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-88 ,2147483648 ,-88 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-93 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,119 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,120 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,2147483648 ,60 ,24 ,2147483648 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,2147483648 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,2147483648 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,2147483648 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,2147483648 ,60 ,24 ,2147483648 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,2147483648 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,2147483648 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,2147483648 ,45 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,123 },
- {-84 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-84 ,2147483648 ,-84 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-84 ,2147483648 ,2147483648 ,-84 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-84 ,-84 ,-84 ,2147483648 ,2147483648 ,2147483648 ,-84 ,2147483648 ,2147483648 ,2147483648 ,-84 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-84 ,-84 ,-84 ,2147483648 ,2147483648 ,-84 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-84 ,2147483648 ,2147483648 ,-84 ,2147483648 ,2147483648 ,-84 ,-84 ,2147483648 ,-84 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-84 ,2147483648 ,-84 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,124 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,125 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,126 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,127 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,128 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,129 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,130 },
- {-87 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-87 ,2147483648 ,-87 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-87 ,2147483648 ,2147483648 ,-87 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-87 ,-87 ,-87 ,2147483648 ,2147483648 ,2147483648 ,-87 ,2147483648 ,2147483648 ,2147483648 ,-87 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-87 ,-87 ,-87 ,2147483648 ,2147483648 ,-87 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-87 ,2147483648 ,2147483648 ,-87 ,2147483648 ,2147483648 ,-87 ,-87 ,2147483648 ,-87 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-87 ,2147483648 ,-87 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,131 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,2147483648 ,60 ,24 ,2147483648 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,2147483648 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,2147483648 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,2147483648 ,45 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,133 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,134 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,135 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,136 },
- {-85 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-85 ,2147483648 ,-85 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-85 ,2147483648 ,2147483648 ,-85 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-85 ,-85 ,-85 ,2147483648 ,2147483648 ,2147483648 ,-85 ,2147483648 ,2147483648 ,2147483648 ,-85 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-85 ,-85 ,-85 ,2147483648 ,2147483648 ,-85 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-85 ,2147483648 ,2147483648 ,-85 ,2147483648 ,2147483648 ,-85 ,-85 ,2147483648 ,-85 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-85 ,2147483648 ,-85 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,137 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,138 },
- {-91 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-91 ,2147483648 ,-91 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-91 ,2147483648 ,2147483648 ,-91 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-91 ,-91 ,-91 ,2147483648 ,2147483648 ,2147483648 ,-91 ,2147483648 ,2147483648 ,2147483648 ,-91 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-91 ,-91 ,-91 ,2147483648 ,2147483648 ,-91 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-91 ,2147483648 ,2147483648 ,-91 ,2147483648 ,2147483648 ,-91 ,-91 ,2147483648 ,-91 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-91 ,2147483648 ,-91 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,139 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,-94 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,164 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,164 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {-35 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-35 ,2147483648 ,-35 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-35 ,2147483648 ,2147483648 ,-35 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-35 ,-35 ,-35 ,2147483648 ,2147483648 ,2147483648 ,-35 ,2147483648 ,2147483648 ,2147483648 ,-35 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-35 ,-35 ,-35 ,2147483648 ,2147483648 ,-35 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-35 ,2147483648 ,2147483648 ,-35 ,2147483648 ,2147483648 ,-35 ,-35 ,2147483648 ,-35 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-35 ,2147483648 ,-35 ,2147483648 ,2147483648 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,164 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {-34 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-34 ,2147483648 ,-34 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-34 ,2147483648 ,2147483648 ,-34 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-34 ,-34 ,-34 ,2147483648 ,2147483648 ,2147483648 ,-34 ,2147483648 ,2147483648 ,2147483648 ,-34 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-34 ,-34 ,-34 ,2147483648 ,2147483648 ,-34 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-34 ,2147483648 ,2147483648 ,-34 ,2147483648 ,2147483648 ,-34 ,-34 ,2147483648 ,-34 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-34 ,2147483648 ,-34 ,2147483648 ,2147483648 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,189 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,190 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,189 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {-37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-37 ,2147483648 ,-37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-37 ,2147483648 ,2147483648 ,-37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-37 ,-37 ,-37 ,2147483648 ,2147483648 ,2147483648 ,-37 ,2147483648 ,2147483648 ,2147483648 ,-37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-37 ,-37 ,-37 ,2147483648 ,2147483648 ,-37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-37 ,2147483648 ,2147483648 ,-37 ,2147483648 ,2147483648 ,-37 ,-37 ,2147483648 ,-37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-37 ,2147483648 ,-37 ,2147483648 ,2147483648 },
- {-36 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-36 ,2147483648 ,-36 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-36 ,2147483648 ,2147483648 ,-36 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-36 ,-36 ,-36 ,2147483648 ,2147483648 ,2147483648 ,-36 ,2147483648 ,2147483648 ,2147483648 ,-36 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-36 ,-36 ,-36 ,2147483648 ,2147483648 ,-36 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-36 ,2147483648 ,2147483648 ,-36 ,2147483648 ,2147483648 ,-36 ,-36 ,2147483648 ,-36 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-36 ,2147483648 ,-36 ,2147483648 ,2147483648 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,189 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {-33 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-33 ,2147483648 ,-33 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-33 ,2147483648 ,2147483648 ,-33 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-33 ,-33 ,-33 ,2147483648 ,2147483648 ,2147483648 ,-33 ,2147483648 ,2147483648 ,2147483648 ,-33 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-33 ,-33 ,-33 ,2147483648 ,2147483648 ,-33 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-33 ,2147483648 ,2147483648 ,-33 ,2147483648 ,2147483648 ,-33 ,-33 ,2147483648 ,-33 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-33 ,2147483648 ,-33 ,2147483648 ,2147483648 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,189 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,75 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-3 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-3 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-3 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-5 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-5 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,76 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-5 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-5 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-7 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-7 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-7 ,2147483648 ,2147483648 ,77 ,2147483648 ,2147483648 ,-7 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-7 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-9 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,78 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-9 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-9 ,2147483648 ,2147483648 ,-9 ,2147483648 ,2147483648 ,-9 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-9 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-11 ,2147483648 ,2147483648 ,-11 ,2147483648 ,2147483648 ,-11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-11 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-18 ,2147483648 ,-18 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-18 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-18 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-18 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-18 ,2147483648 ,2147483648 ,2147483648 ,-18 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-18 ,2147483648 ,2147483648 ,-18 ,2147483648 ,2147483648 ,-18 ,2147483648 ,2147483648 ,-18 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-18 ,2147483648 ,-18 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-15 ,2147483648 ,-15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-15 ,2147483648 ,2147483648 ,2147483648 ,-15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-15 ,2147483648 ,2147483648 ,-15 ,2147483648 ,2147483648 ,-15 ,2147483648 ,2147483648 ,-15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-15 ,2147483648 ,-15 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-19 ,2147483648 ,-19 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-19 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-19 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-19 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-19 ,2147483648 ,2147483648 ,2147483648 ,-19 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-19 ,2147483648 ,2147483648 ,-19 ,2147483648 ,2147483648 ,-19 ,2147483648 ,2147483648 ,-19 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-19 ,2147483648 ,-19 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-17 ,2147483648 ,-17 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-17 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-17 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-17 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-17 ,2147483648 ,2147483648 ,2147483648 ,-17 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-17 ,2147483648 ,2147483648 ,-17 ,2147483648 ,2147483648 ,-17 ,2147483648 ,2147483648 ,-17 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-17 ,2147483648 ,-17 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-14 ,2147483648 ,-14 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-14 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-14 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-14 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-14 ,2147483648 ,2147483648 ,2147483648 ,-14 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-14 ,2147483648 ,2147483648 ,-14 ,2147483648 ,2147483648 ,-14 ,2147483648 ,2147483648 ,-14 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-14 ,2147483648 ,-14 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-16 ,2147483648 ,-16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-16 ,2147483648 ,2147483648 ,2147483648 ,-16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-16 ,2147483648 ,2147483648 ,-16 ,2147483648 ,2147483648 ,-16 ,2147483648 ,2147483648 ,-16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-16 ,2147483648 ,-16 ,2147483648 ,2147483648 },
- {-22 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-22 ,2147483648 ,-22 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-22 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-22 ,88 ,-22 ,2147483648 ,2147483648 ,2147483648 ,-22 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-22 ,-22 ,2147483648 ,2147483648 ,2147483648 ,-22 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-22 ,2147483648 ,2147483648 ,-22 ,2147483648 ,2147483648 ,-22 ,87 ,2147483648 ,-22 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-22 ,2147483648 ,-22 ,2147483648 ,2147483648 },
- {-23 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-23 ,2147483648 ,-23 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-23 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-23 ,88 ,-23 ,2147483648 ,2147483648 ,2147483648 ,-23 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-23 ,-23 ,2147483648 ,2147483648 ,2147483648 ,-23 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-23 ,2147483648 ,2147483648 ,-23 ,2147483648 ,2147483648 ,-23 ,87 ,2147483648 ,-23 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-23 ,2147483648 ,-23 ,2147483648 ,2147483648 },
- {-25 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-25 ,2147483648 ,-25 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,91 ,2147483648 ,2147483648 ,-25 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-25 ,-25 ,-25 ,2147483648 ,2147483648 ,2147483648 ,-25 ,2147483648 ,2147483648 ,2147483648 ,90 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-25 ,-25 ,89 ,2147483648 ,2147483648 ,-25 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-25 ,2147483648 ,2147483648 ,-25 ,2147483648 ,2147483648 ,-25 ,-25 ,2147483648 ,-25 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-25 ,2147483648 ,-25 ,2147483648 ,2147483648 },
- {-26 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-26 ,2147483648 ,-26 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,91 ,2147483648 ,2147483648 ,-26 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-26 ,-26 ,-26 ,2147483648 ,2147483648 ,2147483648 ,-26 ,2147483648 ,2147483648 ,2147483648 ,90 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-26 ,-26 ,89 ,2147483648 ,2147483648 ,-26 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-26 ,2147483648 ,2147483648 ,-26 ,2147483648 ,2147483648 ,-26 ,-26 ,2147483648 ,-26 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-26 ,2147483648 ,-26 ,2147483648 ,2147483648 },
- {-28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-28 ,2147483648 ,-28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-28 ,2147483648 ,2147483648 ,-28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-28 ,-28 ,-28 ,2147483648 ,2147483648 ,2147483648 ,-28 ,2147483648 ,2147483648 ,2147483648 ,-28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-28 ,-28 ,-28 ,2147483648 ,2147483648 ,-28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-28 ,2147483648 ,2147483648 ,-28 ,2147483648 ,2147483648 ,-28 ,-28 ,2147483648 ,-28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-28 ,2147483648 ,-28 ,2147483648 ,2147483648 },
- {-29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-29 ,2147483648 ,-29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-29 ,2147483648 ,2147483648 ,-29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-29 ,-29 ,-29 ,2147483648 ,2147483648 ,2147483648 ,-29 ,2147483648 ,2147483648 ,2147483648 ,-29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-29 ,-29 ,-29 ,2147483648 ,2147483648 ,-29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-29 ,2147483648 ,2147483648 ,-29 ,2147483648 ,2147483648 ,-29 ,-29 ,2147483648 ,-29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-29 ,2147483648 ,-29 ,2147483648 ,2147483648 },
- {-30 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-30 ,2147483648 ,-30 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-30 ,2147483648 ,2147483648 ,-30 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-30 ,-30 ,-30 ,2147483648 ,2147483648 ,2147483648 ,-30 ,2147483648 ,2147483648 ,2147483648 ,-30 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-30 ,-30 ,-30 ,2147483648 ,2147483648 ,-30 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-30 ,2147483648 ,2147483648 ,-30 ,2147483648 ,2147483648 ,-30 ,-30 ,2147483648 ,-30 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-30 ,2147483648 ,-30 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,212 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-97 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,213 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,214 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,215 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-103 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-103 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,216 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-99 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-99 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-102 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-102 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,217 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,218 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,219 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,220 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,221 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,222 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,223 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,224 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,225 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,226 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,227 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,228 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,229 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,230 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,231 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,232 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,233 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,234 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,235 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,236 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-100 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-100 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-101 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-101 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,237 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-98 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-98 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {-82 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-82 ,2147483648 ,-82 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-82 ,2147483648 ,2147483648 ,-82 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-82 ,-82 ,-82 ,2147483648 ,2147483648 ,2147483648 ,-82 ,2147483648 ,2147483648 ,2147483648 ,-82 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-82 ,-82 ,-82 ,2147483648 ,2147483648 ,-82 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-82 ,2147483648 ,2147483648 ,-82 ,2147483648 ,2147483648 ,-82 ,-82 ,2147483648 ,-82 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-82 ,2147483648 ,-82 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,238 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,239 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,240 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,241 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,242 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,243 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,244 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,245 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,246 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,247 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,248 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,249 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,250 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,251 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,252 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,253 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,254 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,255 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-100 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,257 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-95 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {-92 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-92 ,2147483648 ,-92 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-92 ,2147483648 ,2147483648 ,-92 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-92 ,-92 ,-92 ,2147483648 ,2147483648 ,2147483648 ,-92 ,2147483648 ,2147483648 ,2147483648 ,-92 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-92 ,-92 ,-92 ,2147483648 ,2147483648 ,-92 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-92 ,2147483648 ,2147483648 ,-92 ,2147483648 ,2147483648 ,-92 ,-92 ,2147483648 ,-92 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-92 ,2147483648 ,-92 ,2147483648 ,2147483648 },
- {-45 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-45 ,2147483648 ,-45 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-45 ,2147483648 ,2147483648 ,-45 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-45 ,-45 ,-45 ,2147483648 ,2147483648 ,2147483648 ,-45 ,2147483648 ,2147483648 ,2147483648 ,-45 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-45 ,-45 ,-45 ,2147483648 ,2147483648 ,-45 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-45 ,2147483648 ,2147483648 ,-45 ,2147483648 ,2147483648 ,-45 ,-45 ,2147483648 ,-45 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-45 ,2147483648 ,-45 ,2147483648 ,2147483648 },
- {-49 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-49 ,2147483648 ,-49 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-49 ,2147483648 ,2147483648 ,-49 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-49 ,-49 ,-49 ,2147483648 ,2147483648 ,2147483648 ,-49 ,2147483648 ,2147483648 ,2147483648 ,-49 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-49 ,-49 ,-49 ,2147483648 ,2147483648 ,-49 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-49 ,2147483648 ,2147483648 ,-49 ,2147483648 ,2147483648 ,-49 ,-49 ,2147483648 ,-49 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-49 ,2147483648 ,-49 ,2147483648 ,2147483648 },
- {-79 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-79 ,2147483648 ,-79 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-79 ,2147483648 ,2147483648 ,-79 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-79 ,-79 ,-79 ,2147483648 ,2147483648 ,2147483648 ,-79 ,2147483648 ,2147483648 ,2147483648 ,-79 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-79 ,-79 ,-79 ,2147483648 ,2147483648 ,-79 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-79 ,2147483648 ,2147483648 ,-79 ,2147483648 ,2147483648 ,-79 ,-79 ,2147483648 ,-79 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-79 ,2147483648 ,-79 ,2147483648 ,2147483648 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,164 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {-44 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-44 ,2147483648 ,-44 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-44 ,2147483648 ,2147483648 ,-44 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-44 ,-44 ,-44 ,2147483648 ,2147483648 ,2147483648 ,-44 ,2147483648 ,2147483648 ,2147483648 ,-44 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-44 ,-44 ,-44 ,2147483648 ,2147483648 ,-44 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-44 ,2147483648 ,2147483648 ,-44 ,2147483648 ,2147483648 ,-44 ,-44 ,2147483648 ,-44 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-44 ,2147483648 ,-44 ,2147483648 ,2147483648 },
- {-38 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-38 ,2147483648 ,-38 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-38 ,2147483648 ,2147483648 ,-38 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-38 ,-38 ,-38 ,2147483648 ,2147483648 ,2147483648 ,-38 ,2147483648 ,2147483648 ,2147483648 ,-38 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-38 ,-38 ,-38 ,2147483648 ,2147483648 ,-38 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-38 ,2147483648 ,2147483648 ,-38 ,2147483648 ,2147483648 ,-38 ,-38 ,2147483648 ,-38 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-38 ,2147483648 ,-38 ,2147483648 ,2147483648 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,164 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {-41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-41 ,2147483648 ,-41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-41 ,2147483648 ,2147483648 ,-41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-41 ,-41 ,-41 ,2147483648 ,2147483648 ,2147483648 ,-41 ,2147483648 ,2147483648 ,2147483648 ,-41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-41 ,-41 ,-41 ,2147483648 ,2147483648 ,-41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-41 ,2147483648 ,2147483648 ,-41 ,2147483648 ,2147483648 ,-41 ,-41 ,2147483648 ,-41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-41 ,2147483648 ,-41 ,2147483648 ,2147483648 },
- {-62 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-62 ,2147483648 ,-62 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-62 ,2147483648 ,2147483648 ,-62 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-62 ,-62 ,-62 ,2147483648 ,2147483648 ,2147483648 ,-62 ,2147483648 ,2147483648 ,2147483648 ,-62 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-62 ,-62 ,-62 ,2147483648 ,2147483648 ,-62 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-62 ,2147483648 ,2147483648 ,-62 ,2147483648 ,2147483648 ,-62 ,-62 ,2147483648 ,-62 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-62 ,2147483648 ,-62 ,2147483648 ,2147483648 },
- {-57 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-57 ,2147483648 ,-57 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-57 ,2147483648 ,2147483648 ,-57 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-57 ,-57 ,-57 ,2147483648 ,2147483648 ,2147483648 ,-57 ,2147483648 ,2147483648 ,2147483648 ,-57 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-57 ,-57 ,-57 ,2147483648 ,2147483648 ,-57 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-57 ,2147483648 ,2147483648 ,-57 ,2147483648 ,2147483648 ,-57 ,-57 ,2147483648 ,-57 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-57 ,2147483648 ,-57 ,2147483648 ,2147483648 },
- {-59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-59 ,2147483648 ,-59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-59 ,2147483648 ,2147483648 ,-59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-59 ,-59 ,-59 ,2147483648 ,2147483648 ,2147483648 ,-59 ,2147483648 ,2147483648 ,2147483648 ,-59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-59 ,-59 ,-59 ,2147483648 ,2147483648 ,-59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-59 ,2147483648 ,2147483648 ,-59 ,2147483648 ,2147483648 ,-59 ,-59 ,2147483648 ,-59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-59 ,2147483648 ,-59 ,2147483648 ,2147483648 },
- {-42 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-42 ,2147483648 ,-42 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-42 ,2147483648 ,2147483648 ,-42 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-42 ,-42 ,-42 ,2147483648 ,2147483648 ,2147483648 ,-42 ,2147483648 ,2147483648 ,2147483648 ,-42 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-42 ,-42 ,-42 ,2147483648 ,2147483648 ,-42 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-42 ,2147483648 ,2147483648 ,-42 ,2147483648 ,2147483648 ,-42 ,-42 ,2147483648 ,-42 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-42 ,2147483648 ,-42 ,2147483648 ,2147483648 },
- {-58 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-58 ,2147483648 ,-58 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-58 ,2147483648 ,2147483648 ,-58 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-58 ,-58 ,-58 ,2147483648 ,2147483648 ,2147483648 ,-58 ,2147483648 ,2147483648 ,2147483648 ,-58 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-58 ,-58 ,-58 ,2147483648 ,2147483648 ,-58 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-58 ,2147483648 ,2147483648 ,-58 ,2147483648 ,2147483648 ,-58 ,-58 ,2147483648 ,-58 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-58 ,2147483648 ,-58 ,2147483648 ,2147483648 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {-50 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-50 ,2147483648 ,-50 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-50 ,2147483648 ,2147483648 ,-50 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-50 ,-50 ,-50 ,2147483648 ,2147483648 ,2147483648 ,-50 ,2147483648 ,2147483648 ,2147483648 ,-50 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-50 ,-50 ,-50 ,2147483648 ,2147483648 ,-50 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-50 ,2147483648 ,2147483648 ,-50 ,2147483648 ,2147483648 ,-50 ,-50 ,2147483648 ,-50 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-50 ,2147483648 ,-50 ,2147483648 ,2147483648 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {-56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-56 ,2147483648 ,-56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-56 ,2147483648 ,2147483648 ,-56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-56 ,-56 ,-56 ,2147483648 ,2147483648 ,2147483648 ,-56 ,2147483648 ,2147483648 ,2147483648 ,-56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-56 ,-56 ,-56 ,2147483648 ,2147483648 ,-56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-56 ,2147483648 ,2147483648 ,-56 ,2147483648 ,2147483648 ,-56 ,-56 ,2147483648 ,-56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-56 ,2147483648 ,-56 ,2147483648 ,2147483648 },
- {-60 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-60 ,2147483648 ,-60 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-60 ,2147483648 ,2147483648 ,-60 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-60 ,-60 ,-60 ,2147483648 ,2147483648 ,2147483648 ,-60 ,2147483648 ,2147483648 ,2147483648 ,-60 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-60 ,-60 ,-60 ,2147483648 ,2147483648 ,-60 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-60 ,2147483648 ,2147483648 ,-60 ,2147483648 ,2147483648 ,-60 ,-60 ,2147483648 ,-60 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-60 ,2147483648 ,-60 ,2147483648 ,2147483648 },
- {-47 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-47 ,2147483648 ,-47 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-47 ,2147483648 ,2147483648 ,-47 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-47 ,-47 ,-47 ,2147483648 ,2147483648 ,2147483648 ,-47 ,2147483648 ,2147483648 ,2147483648 ,-47 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-47 ,-47 ,-47 ,2147483648 ,2147483648 ,-47 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-47 ,2147483648 ,2147483648 ,-47 ,2147483648 ,2147483648 ,-47 ,-47 ,2147483648 ,-47 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-47 ,2147483648 ,-47 ,2147483648 ,2147483648 },
- {-54 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-54 ,2147483648 ,-54 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-54 ,2147483648 ,2147483648 ,-54 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-54 ,-54 ,-54 ,2147483648 ,2147483648 ,2147483648 ,-54 ,2147483648 ,2147483648 ,2147483648 ,-54 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-54 ,-54 ,-54 ,2147483648 ,2147483648 ,-54 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-54 ,2147483648 ,2147483648 ,-54 ,2147483648 ,2147483648 ,-54 ,-54 ,2147483648 ,-54 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-54 ,2147483648 ,-54 ,2147483648 ,2147483648 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,189 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {-61 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-61 ,2147483648 ,-61 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-61 ,2147483648 ,2147483648 ,-61 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-61 ,-61 ,-61 ,2147483648 ,2147483648 ,2147483648 ,-61 ,2147483648 ,2147483648 ,2147483648 ,-61 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-61 ,-61 ,-61 ,2147483648 ,2147483648 ,-61 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-61 ,2147483648 ,2147483648 ,-61 ,2147483648 ,2147483648 ,-61 ,-61 ,2147483648 ,-61 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-61 ,2147483648 ,-61 ,2147483648 ,2147483648 },
- {2147483648 ,39 ,28 ,189 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {-52 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-52 ,2147483648 ,-52 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-52 ,2147483648 ,2147483648 ,-52 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-52 ,-52 ,-52 ,2147483648 ,2147483648 ,2147483648 ,-52 ,2147483648 ,2147483648 ,2147483648 ,-52 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-52 ,-52 ,-52 ,2147483648 ,2147483648 ,-52 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-52 ,2147483648 ,2147483648 ,-52 ,2147483648 ,2147483648 ,-52 ,-52 ,2147483648 ,-52 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-52 ,2147483648 ,-52 ,2147483648 ,2147483648 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {-64 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-64 ,2147483648 ,-64 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-64 ,2147483648 ,2147483648 ,-64 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-64 ,-64 ,-64 ,2147483648 ,2147483648 ,2147483648 ,-64 ,2147483648 ,2147483648 ,2147483648 ,-64 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-64 ,-64 ,-64 ,2147483648 ,2147483648 ,-64 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-64 ,2147483648 ,2147483648 ,-64 ,2147483648 ,2147483648 ,-64 ,-64 ,2147483648 ,-64 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-64 ,2147483648 ,-64 ,2147483648 ,2147483648 },
- {2147483648 ,39 ,28 ,189 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {-46 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-46 ,2147483648 ,-46 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-46 ,2147483648 ,2147483648 ,-46 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-46 ,-46 ,-46 ,2147483648 ,2147483648 ,2147483648 ,-46 ,2147483648 ,2147483648 ,2147483648 ,-46 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-46 ,-46 ,-46 ,2147483648 ,2147483648 ,-46 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-46 ,2147483648 ,2147483648 ,-46 ,2147483648 ,2147483648 ,-46 ,-46 ,2147483648 ,-46 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-46 ,2147483648 ,-46 ,2147483648 ,2147483648 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {-63 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-63 ,2147483648 ,-63 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-63 ,2147483648 ,2147483648 ,-63 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-63 ,-63 ,-63 ,2147483648 ,2147483648 ,2147483648 ,-63 ,2147483648 ,2147483648 ,2147483648 ,-63 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-63 ,-63 ,-63 ,2147483648 ,2147483648 ,-63 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-63 ,2147483648 ,2147483648 ,-63 ,2147483648 ,2147483648 ,-63 ,-63 ,2147483648 ,-63 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-63 ,2147483648 ,-63 ,2147483648 ,2147483648 },
- {-53 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-53 ,2147483648 ,-53 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-53 ,2147483648 ,2147483648 ,-53 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-53 ,-53 ,-53 ,2147483648 ,2147483648 ,2147483648 ,-53 ,2147483648 ,2147483648 ,2147483648 ,-53 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-53 ,-53 ,-53 ,2147483648 ,2147483648 ,-53 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-53 ,2147483648 ,2147483648 ,-53 ,2147483648 ,2147483648 ,-53 ,-53 ,2147483648 ,-53 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-53 ,2147483648 ,-53 ,2147483648 ,2147483648 },
- {-43 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-43 ,2147483648 ,-43 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-43 ,2147483648 ,2147483648 ,-43 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-43 ,-43 ,-43 ,2147483648 ,2147483648 ,2147483648 ,-43 ,2147483648 ,2147483648 ,2147483648 ,-43 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-43 ,-43 ,-43 ,2147483648 ,2147483648 ,-43 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-43 ,2147483648 ,2147483648 ,-43 ,2147483648 ,2147483648 ,-43 ,-43 ,2147483648 ,-43 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-43 ,2147483648 ,-43 ,2147483648 ,2147483648 },
- {-39 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-39 ,2147483648 ,-39 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-39 ,2147483648 ,2147483648 ,-39 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-39 ,-39 ,-39 ,2147483648 ,2147483648 ,2147483648 ,-39 ,2147483648 ,2147483648 ,2147483648 ,-39 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-39 ,-39 ,-39 ,2147483648 ,2147483648 ,-39 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-39 ,2147483648 ,2147483648 ,-39 ,2147483648 ,2147483648 ,-39 ,-39 ,2147483648 ,-39 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-39 ,2147483648 ,-39 ,2147483648 ,2147483648 },
- {-55 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-55 ,2147483648 ,-55 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-55 ,2147483648 ,2147483648 ,-55 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-55 ,-55 ,-55 ,2147483648 ,2147483648 ,2147483648 ,-55 ,2147483648 ,2147483648 ,2147483648 ,-55 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-55 ,-55 ,-55 ,2147483648 ,2147483648 ,-55 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-55 ,2147483648 ,2147483648 ,-55 ,2147483648 ,2147483648 ,-55 ,-55 ,2147483648 ,-55 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-55 ,2147483648 ,-55 ,2147483648 ,2147483648 },
- {-40 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-40 ,2147483648 ,-40 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-40 ,2147483648 ,2147483648 ,-40 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-40 ,-40 ,-40 ,2147483648 ,2147483648 ,2147483648 ,-40 ,2147483648 ,2147483648 ,2147483648 ,-40 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-40 ,-40 ,-40 ,2147483648 ,2147483648 ,-40 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-40 ,2147483648 ,2147483648 ,-40 ,2147483648 ,2147483648 ,-40 ,-40 ,2147483648 ,-40 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-40 ,2147483648 ,-40 ,2147483648 ,2147483648 },
- {-51 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-51 ,2147483648 ,-51 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-51 ,2147483648 ,2147483648 ,-51 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-51 ,-51 ,-51 ,2147483648 ,2147483648 ,2147483648 ,-51 ,2147483648 ,2147483648 ,2147483648 ,-51 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-51 ,-51 ,-51 ,2147483648 ,2147483648 ,-51 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-51 ,2147483648 ,2147483648 ,-51 ,2147483648 ,2147483648 ,-51 ,-51 ,2147483648 ,-51 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-51 ,2147483648 ,-51 ,2147483648 ,2147483648 },
- {-48 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-48 ,2147483648 ,-48 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-48 ,2147483648 ,2147483648 ,-48 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-48 ,-48 ,-48 ,2147483648 ,2147483648 ,2147483648 ,-48 ,2147483648 ,2147483648 ,2147483648 ,-48 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-48 ,-48 ,-48 ,2147483648 ,2147483648 ,-48 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-48 ,2147483648 ,2147483648 ,-48 ,2147483648 ,2147483648 ,-48 ,-48 ,2147483648 ,-48 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-48 ,2147483648 ,-48 ,2147483648 ,2147483648 },
- {-75 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-75 ,2147483648 ,-75 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-75 ,2147483648 ,2147483648 ,-75 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-75 ,-75 ,-75 ,2147483648 ,2147483648 ,2147483648 ,-75 ,2147483648 ,2147483648 ,2147483648 ,-75 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-75 ,-75 ,-75 ,2147483648 ,2147483648 ,-75 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-75 ,2147483648 ,2147483648 ,-75 ,2147483648 ,2147483648 ,-75 ,-75 ,2147483648 ,-75 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-75 ,2147483648 ,-75 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,212 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-97 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,275 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,276 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,277 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,278 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,279 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,280 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,281 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,282 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,283 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,284 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,285 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,286 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,287 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,288 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,289 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-96 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {-69 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-69 ,2147483648 ,-69 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-69 ,2147483648 ,2147483648 ,-69 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-69 ,-69 ,-69 ,2147483648 ,2147483648 ,2147483648 ,-69 ,2147483648 ,2147483648 ,2147483648 ,-69 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-69 ,-69 ,-69 ,2147483648 ,2147483648 ,-69 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-69 ,2147483648 ,2147483648 ,-69 ,2147483648 ,2147483648 ,-69 ,-69 ,2147483648 ,-69 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-69 ,2147483648 ,-69 ,2147483648 ,2147483648 },
- {-70 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-70 ,2147483648 ,-70 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-70 ,2147483648 ,2147483648 ,-70 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-70 ,-70 ,-70 ,2147483648 ,2147483648 ,2147483648 ,-70 ,2147483648 ,2147483648 ,2147483648 ,-70 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-70 ,-70 ,-70 ,2147483648 ,2147483648 ,-70 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-70 ,2147483648 ,2147483648 ,-70 ,2147483648 ,2147483648 ,-70 ,-70 ,2147483648 ,-70 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-70 ,2147483648 ,-70 ,2147483648 ,2147483648 },
- {-80 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-80 ,2147483648 ,-80 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-80 ,2147483648 ,2147483648 ,-80 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-80 ,-80 ,-80 ,2147483648 ,2147483648 ,2147483648 ,-80 ,2147483648 ,2147483648 ,2147483648 ,-80 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-80 ,-80 ,-80 ,2147483648 ,2147483648 ,-80 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-80 ,2147483648 ,2147483648 ,-80 ,2147483648 ,2147483648 ,-80 ,-80 ,2147483648 ,-80 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-80 ,2147483648 ,-80 ,2147483648 ,2147483648 },
- {-65 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-65 ,2147483648 ,-65 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-65 ,2147483648 ,2147483648 ,-65 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-65 ,-65 ,-65 ,2147483648 ,2147483648 ,2147483648 ,-65 ,2147483648 ,2147483648 ,2147483648 ,-65 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-65 ,-65 ,-65 ,2147483648 ,2147483648 ,-65 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-65 ,2147483648 ,2147483648 ,-65 ,2147483648 ,2147483648 ,-65 ,-65 ,2147483648 ,-65 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-65 ,2147483648 ,-65 ,2147483648 ,2147483648 },
- {-68 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-68 ,2147483648 ,-68 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-68 ,2147483648 ,2147483648 ,-68 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-68 ,-68 ,-68 ,2147483648 ,2147483648 ,2147483648 ,-68 ,2147483648 ,2147483648 ,2147483648 ,-68 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-68 ,-68 ,-68 ,2147483648 ,2147483648 ,-68 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-68 ,2147483648 ,2147483648 ,-68 ,2147483648 ,2147483648 ,-68 ,-68 ,2147483648 ,-68 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-68 ,2147483648 ,-68 ,2147483648 ,2147483648 },
- {-67 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-67 ,2147483648 ,-67 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-67 ,2147483648 ,2147483648 ,-67 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-67 ,-67 ,-67 ,2147483648 ,2147483648 ,2147483648 ,-67 ,2147483648 ,2147483648 ,2147483648 ,-67 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-67 ,-67 ,-67 ,2147483648 ,2147483648 ,-67 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-67 ,2147483648 ,2147483648 ,-67 ,2147483648 ,2147483648 ,-67 ,-67 ,2147483648 ,-67 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-67 ,2147483648 ,-67 ,2147483648 ,2147483648 },
- {-76 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-76 ,2147483648 ,-76 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-76 ,2147483648 ,2147483648 ,-76 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-76 ,-76 ,-76 ,2147483648 ,2147483648 ,2147483648 ,-76 ,2147483648 ,2147483648 ,2147483648 ,-76 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-76 ,-76 ,-76 ,2147483648 ,2147483648 ,-76 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-76 ,2147483648 ,2147483648 ,-76 ,2147483648 ,2147483648 ,-76 ,-76 ,2147483648 ,-76 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-76 ,2147483648 ,-76 ,2147483648 ,2147483648 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {-72 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-72 ,2147483648 ,-72 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-72 ,2147483648 ,2147483648 ,-72 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-72 ,-72 ,-72 ,2147483648 ,2147483648 ,2147483648 ,-72 ,2147483648 ,2147483648 ,2147483648 ,-72 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-72 ,-72 ,-72 ,2147483648 ,2147483648 ,-72 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-72 ,2147483648 ,2147483648 ,-72 ,2147483648 ,2147483648 ,-72 ,-72 ,2147483648 ,-72 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-72 ,2147483648 ,-72 ,2147483648 ,2147483648 },
- {-71 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-71 ,2147483648 ,-71 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-71 ,2147483648 ,2147483648 ,-71 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-71 ,-71 ,-71 ,2147483648 ,2147483648 ,2147483648 ,-71 ,2147483648 ,2147483648 ,2147483648 ,-71 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-71 ,-71 ,-71 ,2147483648 ,2147483648 ,-71 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-71 ,2147483648 ,2147483648 ,-71 ,2147483648 ,2147483648 ,-71 ,-71 ,2147483648 ,-71 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-71 ,2147483648 ,-71 ,2147483648 ,2147483648 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {-66 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-66 ,2147483648 ,-66 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-66 ,2147483648 ,2147483648 ,-66 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-66 ,-66 ,-66 ,2147483648 ,2147483648 ,2147483648 ,-66 ,2147483648 ,2147483648 ,2147483648 ,-66 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-66 ,-66 ,-66 ,2147483648 ,2147483648 ,-66 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-66 ,2147483648 ,2147483648 ,-66 ,2147483648 ,2147483648 ,-66 ,-66 ,2147483648 ,-66 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-66 ,2147483648 ,-66 ,2147483648 ,2147483648 },
- {2147483648 ,39 ,28 ,2147483648 ,49 ,36 ,23 ,41 ,67 ,27 ,2147483648 ,31 ,2147483648 ,47 ,34 ,22 ,55 ,52 ,60 ,24 ,51 ,18 ,33 ,69 ,53 ,44 ,57 ,2147483648 ,64 ,2147483648 ,26 ,68 ,58 ,2147483648 ,25 ,2147483648 ,19 ,2147483648 ,65 ,73 ,43 ,54 ,29 ,35 ,59 ,62 ,38 ,2147483648 ,2147483648 ,2147483648 ,48 ,17 ,2147483648 ,42 ,70 ,63 ,40 ,2147483648 ,20 ,66 ,2147483648 ,71 ,30 ,2147483648 ,37 ,72 ,2147483648 ,56 ,32 ,50 ,61 ,2147483648 ,46 ,2147483648 ,21 ,45 },
- {-73 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-73 ,2147483648 ,-73 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-73 ,2147483648 ,2147483648 ,-73 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-73 ,-73 ,-73 ,2147483648 ,2147483648 ,2147483648 ,-73 ,2147483648 ,2147483648 ,2147483648 ,-73 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-73 ,-73 ,-73 ,2147483648 ,2147483648 ,-73 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-73 ,2147483648 ,2147483648 ,-73 ,2147483648 ,2147483648 ,-73 ,-73 ,2147483648 ,-73 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-73 ,2147483648 ,-73 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,294 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,295 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,296 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,297 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
- {-81 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-81 ,2147483648 ,-81 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-81 ,2147483648 ,2147483648 ,-81 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-81 ,-81 ,-81 ,2147483648 ,2147483648 ,2147483648 ,-81 ,2147483648 ,2147483648 ,2147483648 ,-81 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-81 ,-81 ,-81 ,2147483648 ,2147483648 ,-81 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-81 ,2147483648 ,2147483648 ,-81 ,2147483648 ,2147483648 ,-81 ,-81 ,2147483648 ,-81 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-81 ,2147483648 ,-81 ,2147483648 ,2147483648 },
- {-77 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-77 ,2147483648 ,-77 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-77 ,2147483648 ,2147483648 ,-77 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-77 ,-77 ,-77 ,2147483648 ,2147483648 ,2147483648 ,-77 ,2147483648 ,2147483648 ,2147483648 ,-77 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-77 ,-77 ,-77 ,2147483648 ,2147483648 ,-77 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-77 ,2147483648 ,2147483648 ,-77 ,2147483648 ,2147483648 ,-77 ,-77 ,2147483648 ,-77 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-77 ,2147483648 ,-77 ,2147483648 ,2147483648 },
- {-78 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-78 ,2147483648 ,-78 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-78 ,2147483648 ,2147483648 ,-78 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-78 ,-78 ,-78 ,2147483648 ,2147483648 ,2147483648 ,-78 ,2147483648 ,2147483648 ,2147483648 ,-78 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-78 ,-78 ,-78 ,2147483648 ,2147483648 ,-78 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-78 ,2147483648 ,2147483648 ,-78 ,2147483648 ,2147483648 ,-78 ,-78 ,2147483648 ,-78 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-78 ,2147483648 ,-78 ,2147483648 ,2147483648 },
- {-74 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-74 ,2147483648 ,-74 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-74 ,2147483648 ,2147483648 ,-74 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-74 ,-74 ,-74 ,2147483648 ,2147483648 ,2147483648 ,-74 ,2147483648 ,2147483648 ,2147483648 ,-74 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-74 ,-74 ,-74 ,2147483648 ,2147483648 ,-74 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-74 ,2147483648 ,2147483648 ,-74 ,2147483648 ,2147483648 ,-74 ,-74 ,2147483648 ,-74 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-74 ,2147483648 ,-74 ,2147483648 ,2147483648 }
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483647 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-1 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-2 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,84 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-2 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-4 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,85 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-4 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-4 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,86 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-6 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-6 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-6 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-6 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,87 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-8 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-8 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-8 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-8 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-8 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-10 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-10 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,88 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-10 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-10 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-10 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-10 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-12 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-12 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-12 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-12 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-12 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-12 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-12 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,93 ,2147483648 ,2147483648 ,2147483648 ,-13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,89 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-13 ,2147483648 ,90 ,2147483648 ,94 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-13 ,92 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,91 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-13 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-20 ,2147483648 ,2147483648 ,2147483648 ,-20 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-20 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-20 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-20 ,2147483648 ,-20 ,2147483648 ,-20 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-20 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-20 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-20 ,-20 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-20 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-20 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-21 ,2147483648 ,2147483648 ,2147483648 ,-21 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-21 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-21 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-21 ,2147483648 ,2147483648 ,-21 ,2147483648 ,-21 ,95 ,-21 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-21 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-21 ,2147483648 ,2147483648 ,2147483648 ,-21 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-21 ,-21 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-21 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-21 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,96 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-24 ,2147483648 ,2147483648 ,2147483648 ,-24 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-24 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-24 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-24 ,2147483648 ,98 ,-24 ,2147483648 ,-24 ,-24 ,-24 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-24 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-24 ,2147483648 ,2147483648 ,2147483648 ,-24 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-24 ,-24 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,97 ,-24 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-24 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-24 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-27 ,2147483648 ,2147483648 ,2147483648 ,-27 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-27 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-27 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,101 ,2147483648 ,2147483648 ,2147483648 ,100 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-27 ,2147483648 ,-27 ,-27 ,2147483648 ,-27 ,-27 ,-27 ,2147483648 ,2147483648 ,99 ,2147483648 ,-27 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-27 ,2147483648 ,2147483648 ,2147483648 ,-27 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-27 ,-27 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-27 ,-27 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-27 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-27 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-31 ,2147483648 ,2147483648 ,2147483648 ,-31 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-31 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-31 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-31 ,2147483648 ,2147483648 ,2147483648 ,-31 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-31 ,2147483648 ,-31 ,-31 ,2147483648 ,-31 ,-31 ,-31 ,2147483648 ,2147483648 ,-31 ,2147483648 ,-31 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-31 ,2147483648 ,2147483648 ,2147483648 ,-31 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-31 ,-31 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-31 ,-31 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-31 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-31 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-32 ,2147483648 ,2147483648 ,2147483648 ,-32 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-32 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-32 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-32 ,2147483648 ,2147483648 ,2147483648 ,-32 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-32 ,2147483648 ,-32 ,-32 ,2147483648 ,-32 ,-32 ,-32 ,2147483648 ,2147483648 ,-32 ,2147483648 ,-32 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-32 ,2147483648 ,2147483648 ,2147483648 ,-32 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-32 ,-32 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-32 ,-32 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-32 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-32 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,102 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-95 ,2147483648 ,2147483648 ,2147483648 ,-95 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-95 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-95 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-95 ,2147483648 ,2147483648 ,2147483648 ,-95 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-95 ,2147483648 ,-95 ,-95 ,2147483648 ,-95 ,-95 ,-95 ,2147483648 ,2147483648 ,-95 ,2147483648 ,-95 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-95 ,2147483648 ,2147483648 ,2147483648 ,-95 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-95 ,-95 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-95 ,-95 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-95 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-95 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,104 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,105 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,106 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,107 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-97 ,2147483648 ,2147483648 ,2147483648 ,-97 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-97 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-97 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-97 ,2147483648 ,2147483648 ,2147483648 ,-97 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-97 ,2147483648 ,-97 ,-97 ,2147483648 ,-97 ,-97 ,-97 ,2147483648 ,2147483648 ,-97 ,2147483648 ,-97 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-97 ,2147483648 ,2147483648 ,2147483648 ,-97 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-97 ,-97 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-97 ,-97 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-97 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-97 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,2147483648 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,2147483648 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-94 ,2147483648 ,2147483648 ,2147483648 ,-94 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-94 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-94 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-94 ,2147483648 ,2147483648 ,2147483648 ,-94 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-94 ,2147483648 ,-94 ,-94 ,2147483648 ,-94 ,-94 ,-94 ,2147483648 ,2147483648 ,-94 ,2147483648 ,-94 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-94 ,2147483648 ,2147483648 ,2147483648 ,-94 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-94 ,-94 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-94 ,-94 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-94 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-94 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,109 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,110 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,111 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-102 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,112 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,113 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,114 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,115 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-96 ,2147483648 ,2147483648 ,2147483648 ,-96 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-96 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-96 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-96 ,2147483648 ,2147483648 ,2147483648 ,-96 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-96 ,2147483648 ,-96 ,-96 ,2147483648 ,-96 ,-96 ,-96 ,2147483648 ,2147483648 ,-96 ,2147483648 ,-96 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-96 ,2147483648 ,2147483648 ,2147483648 ,-96 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-96 ,-96 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-96 ,-96 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-96 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-96 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,116 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,117 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,118 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,119 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-98 ,2147483648 ,2147483648 ,2147483648 ,-98 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-98 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-98 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-98 ,2147483648 ,2147483648 ,2147483648 ,-98 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-98 ,2147483648 ,-98 ,-98 ,2147483648 ,-98 ,-98 ,-98 ,2147483648 ,2147483648 ,-98 ,2147483648 ,-98 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-98 ,2147483648 ,2147483648 ,2147483648 ,-98 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-98 ,-98 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-98 ,-98 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-98 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-98 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,120 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,121 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,122 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,123 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,124 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-93 ,2147483648 ,-114 ,2147483648 ,-93 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-93 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-93 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-93 ,2147483648 ,2147483648 ,2147483648 ,-93 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-93 ,2147483648 ,-93 ,-93 ,2147483648 ,-93 ,-93 ,-93 ,2147483648 ,2147483648 ,-93 ,2147483648 ,-93 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-93 ,2147483648 ,2147483648 ,2147483648 ,-93 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-93 ,-93 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-93 ,-93 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-93 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-93 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,125 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,126 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,127 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,128 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,129 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,130 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,131 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,132 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,133 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,134 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,135 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,136 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-99 ,2147483648 ,2147483648 ,2147483648 ,-99 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-99 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-99 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-99 ,2147483648 ,2147483648 ,2147483648 ,-99 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-99 ,2147483648 ,-99 ,-99 ,2147483648 ,-99 ,-99 ,-99 ,2147483648 ,2147483648 ,-99 ,2147483648 ,-99 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-99 ,2147483648 ,2147483648 ,2147483648 ,-99 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-99 ,-99 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-99 ,-99 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-99 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-99 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,138 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,139 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,140 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,141 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,142 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,143 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,144 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,145 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,146 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,147 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,2147483648 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,2147483648 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-91 ,2147483648 ,2147483648 ,2147483648 ,-91 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-91 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-91 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-91 ,2147483648 ,2147483648 ,2147483648 ,-91 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-91 ,2147483648 ,-91 ,-91 ,2147483648 ,-91 ,-91 ,-91 ,2147483648 ,2147483648 ,-91 ,2147483648 ,-91 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-91 ,2147483648 ,2147483648 ,2147483648 ,-91 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-91 ,-91 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-91 ,-91 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-91 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-91 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,149 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,150 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,151 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,152 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,2147483648 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,2147483648 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,154 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,155 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,156 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,2147483648 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,2147483648 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-92 ,2147483648 ,2147483648 ,2147483648 ,-92 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-92 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-92 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-92 ,2147483648 ,2147483648 ,2147483648 ,-92 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-92 ,2147483648 ,-92 ,-92 ,2147483648 ,-92 ,-92 ,-92 ,2147483648 ,2147483648 ,-92 ,2147483648 ,-92 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-92 ,2147483648 ,2147483648 ,2147483648 ,-92 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-92 ,-92 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-92 ,-92 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-92 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-92 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,2147483648 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,2147483648 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-100 ,2147483648 ,2147483648 ,2147483648 ,-100 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-100 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-100 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-100 ,2147483648 ,2147483648 ,2147483648 ,-100 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-100 ,2147483648 ,-100 ,-100 ,2147483648 ,-100 ,-100 ,-100 ,2147483648 ,2147483648 ,-100 ,2147483648 ,-100 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-100 ,2147483648 ,2147483648 ,2147483648 ,-100 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-100 ,-100 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-100 ,-100 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-100 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-100 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,159 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,-103 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-117 ,2147483648 ,104 ,2147483648 ,-117 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-117 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-117 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-117 ,2147483648 ,2147483648 ,2147483648 ,-117 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-117 ,2147483648 ,-117 ,-117 ,2147483648 ,-117 ,-117 ,-117 ,2147483648 ,2147483648 ,-117 ,2147483648 ,-117 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-117 ,2147483648 ,2147483648 ,2147483648 ,-117 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-117 ,-117 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-117 ,-117 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-117 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-117 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,186 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,188 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-37 ,2147483648 ,2147483648 ,2147483648 ,-37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-37 ,2147483648 ,2147483648 ,2147483648 ,-37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-37 ,2147483648 ,-37 ,-37 ,2147483648 ,-37 ,-37 ,-37 ,2147483648 ,2147483648 ,-37 ,2147483648 ,-37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-37 ,2147483648 ,2147483648 ,2147483648 ,-37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-37 ,-37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-37 ,-37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-37 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-37 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,191 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,192 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {78 ,59 ,74 ,67 ,196 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,196 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,196 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,186 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,196 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,207 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,210 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,211 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,186 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,223 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,226 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-36 ,2147483648 ,2147483648 ,2147483648 ,-36 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-36 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-36 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-36 ,2147483648 ,2147483648 ,2147483648 ,-36 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-36 ,2147483648 ,-36 ,-36 ,2147483648 ,-36 ,-36 ,-36 ,2147483648 ,2147483648 ,-36 ,2147483648 ,-36 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-36 ,2147483648 ,2147483648 ,2147483648 ,-36 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-36 ,-36 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-36 ,-36 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-36 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-36 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-35 ,2147483648 ,2147483648 ,2147483648 ,-35 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-35 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-35 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-35 ,2147483648 ,2147483648 ,2147483648 ,-35 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-35 ,2147483648 ,-35 ,-35 ,2147483648 ,-35 ,-35 ,-35 ,2147483648 ,2147483648 ,-35 ,2147483648 ,-35 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-35 ,2147483648 ,2147483648 ,2147483648 ,-35 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-35 ,-35 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-35 ,-35 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-35 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-35 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-34 ,2147483648 ,2147483648 ,2147483648 ,-34 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-34 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-34 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-34 ,2147483648 ,2147483648 ,2147483648 ,-34 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-34 ,2147483648 ,-34 ,-34 ,2147483648 ,-34 ,-34 ,-34 ,2147483648 ,2147483648 ,-34 ,2147483648 ,-34 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-34 ,2147483648 ,2147483648 ,2147483648 ,-34 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-34 ,-34 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-34 ,-34 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-34 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-34 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-33 ,2147483648 ,2147483648 ,2147483648 ,-33 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-33 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-33 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-33 ,2147483648 ,2147483648 ,2147483648 ,-33 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-33 ,2147483648 ,-33 ,-33 ,2147483648 ,-33 ,-33 ,-33 ,2147483648 ,2147483648 ,-33 ,2147483648 ,-33 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-33 ,2147483648 ,2147483648 ,2147483648 ,-33 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-33 ,-33 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-33 ,-33 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-33 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-33 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-3 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,85 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-3 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-3 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,86 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-5 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-5 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-5 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-5 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,87 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-7 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-7 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-7 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-7 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-7 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-9 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-9 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,88 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-9 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-9 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-9 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-9 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-11 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-15 ,2147483648 ,2147483648 ,2147483648 ,-15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-15 ,2147483648 ,-15 ,2147483648 ,-15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-15 ,-15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-15 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-16 ,2147483648 ,2147483648 ,2147483648 ,-16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-16 ,2147483648 ,-16 ,2147483648 ,-16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-16 ,-16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-16 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-18 ,2147483648 ,2147483648 ,2147483648 ,-18 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-18 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-18 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-18 ,2147483648 ,-18 ,2147483648 ,-18 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-18 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-18 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-18 ,-18 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-18 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-18 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-17 ,2147483648 ,2147483648 ,2147483648 ,-17 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-17 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-17 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-17 ,2147483648 ,-17 ,2147483648 ,-17 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-17 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-17 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-17 ,-17 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-17 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-17 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-19 ,2147483648 ,2147483648 ,2147483648 ,-19 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-19 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-19 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-19 ,2147483648 ,-19 ,2147483648 ,-19 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-19 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-19 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-19 ,-19 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-19 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-19 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-14 ,2147483648 ,2147483648 ,2147483648 ,-14 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-14 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-14 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-14 ,2147483648 ,-14 ,2147483648 ,-14 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-14 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-14 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-14 ,-14 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-14 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-14 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-23 ,2147483648 ,2147483648 ,2147483648 ,-23 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-23 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-23 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-23 ,2147483648 ,98 ,-23 ,2147483648 ,-23 ,-23 ,-23 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-23 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-23 ,2147483648 ,2147483648 ,2147483648 ,-23 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-23 ,-23 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,97 ,-23 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-23 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-23 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-22 ,2147483648 ,2147483648 ,2147483648 ,-22 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-22 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-22 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-22 ,2147483648 ,98 ,-22 ,2147483648 ,-22 ,-22 ,-22 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-22 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-22 ,2147483648 ,2147483648 ,2147483648 ,-22 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-22 ,-22 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,97 ,-22 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-22 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-22 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-25 ,2147483648 ,2147483648 ,2147483648 ,-25 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-25 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-25 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,101 ,2147483648 ,2147483648 ,2147483648 ,100 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-25 ,2147483648 ,-25 ,-25 ,2147483648 ,-25 ,-25 ,-25 ,2147483648 ,2147483648 ,99 ,2147483648 ,-25 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-25 ,2147483648 ,2147483648 ,2147483648 ,-25 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-25 ,-25 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-25 ,-25 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-25 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-25 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-26 ,2147483648 ,2147483648 ,2147483648 ,-26 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-26 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-26 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,101 ,2147483648 ,2147483648 ,2147483648 ,100 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-26 ,2147483648 ,-26 ,-26 ,2147483648 ,-26 ,-26 ,-26 ,2147483648 ,2147483648 ,99 ,2147483648 ,-26 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-26 ,2147483648 ,2147483648 ,2147483648 ,-26 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-26 ,-26 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-26 ,-26 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-26 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-26 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-29 ,2147483648 ,2147483648 ,2147483648 ,-29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-29 ,2147483648 ,2147483648 ,2147483648 ,-29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-29 ,2147483648 ,-29 ,-29 ,2147483648 ,-29 ,-29 ,-29 ,2147483648 ,2147483648 ,-29 ,2147483648 ,-29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-29 ,2147483648 ,2147483648 ,2147483648 ,-29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-29 ,-29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-29 ,-29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-29 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-29 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-28 ,2147483648 ,2147483648 ,2147483648 ,-28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-28 ,2147483648 ,2147483648 ,2147483648 ,-28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-28 ,2147483648 ,-28 ,-28 ,2147483648 ,-28 ,-28 ,-28 ,2147483648 ,2147483648 ,-28 ,2147483648 ,-28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-28 ,2147483648 ,2147483648 ,2147483648 ,-28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-28 ,-28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-28 ,-28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-28 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-28 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-30 ,2147483648 ,2147483648 ,2147483648 ,-30 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-30 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-30 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-30 ,2147483648 ,2147483648 ,2147483648 ,-30 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-30 ,2147483648 ,-30 ,-30 ,2147483648 ,-30 ,-30 ,-30 ,2147483648 ,2147483648 ,-30 ,2147483648 ,-30 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-30 ,2147483648 ,2147483648 ,2147483648 ,-30 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-30 ,-30 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-30 ,-30 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-30 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-30 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,243 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-106 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,244 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-117 ,2147483648 ,104 ,2147483648 ,-117 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-117 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-117 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-117 ,2147483648 ,2147483648 ,2147483648 ,-117 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-117 ,2147483648 ,-117 ,-117 ,2147483648 ,-117 ,-117 ,-117 ,2147483648 ,2147483648 ,-117 ,2147483648 ,-117 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-117 ,2147483648 ,2147483648 ,2147483648 ,-117 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-117 ,-117 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-117 ,-117 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-117 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-117 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-113 ,2147483648 ,2147483648 ,2147483648 ,-113 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-113 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-113 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-113 ,2147483648 ,2147483648 ,2147483648 ,-113 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-113 ,2147483648 ,-113 ,-113 ,2147483648 ,-113 ,-113 ,-113 ,2147483648 ,2147483648 ,-113 ,2147483648 ,-113 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-113 ,2147483648 ,2147483648 ,2147483648 ,-113 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-113 ,-113 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-113 ,-113 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-113 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-113 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,246 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,247 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-112 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-112 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,248 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-108 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-108 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,249 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-39 ,2147483648 ,2147483648 ,2147483648 ,-39 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-39 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-39 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-39 ,2147483648 ,2147483648 ,2147483648 ,-39 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-39 ,2147483648 ,-39 ,-39 ,2147483648 ,-39 ,-39 ,-39 ,2147483648 ,2147483648 ,-39 ,2147483648 ,-39 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-39 ,2147483648 ,2147483648 ,2147483648 ,-39 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-39 ,-39 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-39 ,-39 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-39 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-39 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,250 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,251 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-44 ,2147483648 ,2147483648 ,2147483648 ,-44 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-44 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-44 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-44 ,2147483648 ,2147483648 ,2147483648 ,-44 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-44 ,2147483648 ,-44 ,-44 ,2147483648 ,-44 ,-44 ,-44 ,2147483648 ,2147483648 ,-44 ,2147483648 ,-44 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-44 ,2147483648 ,2147483648 ,2147483648 ,-44 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-44 ,-44 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-44 ,-44 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-44 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-44 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-41 ,2147483648 ,2147483648 ,2147483648 ,-41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-41 ,2147483648 ,2147483648 ,2147483648 ,-41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-41 ,2147483648 ,-41 ,-41 ,2147483648 ,-41 ,-41 ,-41 ,2147483648 ,2147483648 ,-41 ,2147483648 ,-41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-41 ,2147483648 ,2147483648 ,2147483648 ,-41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-41 ,-41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-41 ,-41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-41 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-41 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-109 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-109 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-110 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-110 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,252 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-107 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-107 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,253 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,254 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,255 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,256 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,257 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,258 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,259 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-109 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,261 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,262 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-38 ,2147483648 ,2147483648 ,2147483648 ,-38 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-38 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-38 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-38 ,2147483648 ,2147483648 ,2147483648 ,-38 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-38 ,2147483648 ,-38 ,-38 ,2147483648 ,-38 ,-38 ,-38 ,2147483648 ,2147483648 ,-38 ,2147483648 ,-38 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-38 ,2147483648 ,2147483648 ,2147483648 ,-38 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-38 ,-38 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-38 ,-38 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-38 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-38 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,263 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,264 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-40 ,2147483648 ,2147483648 ,2147483648 ,-40 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-40 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-40 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-40 ,2147483648 ,2147483648 ,2147483648 ,-40 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-40 ,2147483648 ,-40 ,-40 ,2147483648 ,-40 ,-40 ,-40 ,2147483648 ,2147483648 ,-40 ,2147483648 ,-40 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-40 ,2147483648 ,2147483648 ,2147483648 ,-40 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-40 ,-40 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-40 ,-40 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-40 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-40 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-43 ,2147483648 ,2147483648 ,2147483648 ,-43 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-43 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-43 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-43 ,2147483648 ,2147483648 ,2147483648 ,-43 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-43 ,2147483648 ,-43 ,-43 ,2147483648 ,-43 ,-43 ,-43 ,2147483648 ,2147483648 ,-43 ,2147483648 ,-43 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-43 ,2147483648 ,2147483648 ,2147483648 ,-43 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-43 ,-43 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-43 ,-43 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-43 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-43 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,265 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-111 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-111 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,266 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,267 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,268 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,269 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,270 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,271 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,272 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,273 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,274 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-90 ,2147483648 ,2147483648 ,2147483648 ,-90 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-90 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-90 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-90 ,2147483648 ,2147483648 ,2147483648 ,-90 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-90 ,2147483648 ,-90 ,-90 ,2147483648 ,-90 ,-90 ,-90 ,2147483648 ,2147483648 ,-90 ,2147483648 ,-90 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-90 ,2147483648 ,2147483648 ,2147483648 ,-90 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-90 ,-90 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-90 ,-90 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-90 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-90 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,275 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,276 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-42 ,2147483648 ,2147483648 ,2147483648 ,-42 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-42 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-42 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-42 ,2147483648 ,2147483648 ,2147483648 ,-42 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-42 ,2147483648 ,-42 ,-42 ,2147483648 ,-42 ,-42 ,-42 ,2147483648 ,2147483648 ,-42 ,2147483648 ,-42 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-42 ,2147483648 ,2147483648 ,2147483648 ,-42 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-42 ,-42 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-42 ,-42 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-42 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-42 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,277 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,278 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,279 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,280 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,281 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,282 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,283 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,284 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,285 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,286 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,287 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,288 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,289 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,290 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,291 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-104 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-101 ,2147483648 ,2147483648 ,2147483648 ,-101 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-101 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-101 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-101 ,2147483648 ,2147483648 ,2147483648 ,-101 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-101 ,2147483648 ,-101 ,-101 ,2147483648 ,-101 ,-101 ,-101 ,2147483648 ,2147483648 ,-101 ,2147483648 ,-101 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-101 ,2147483648 ,2147483648 ,2147483648 ,-101 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-101 ,-101 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-101 ,-101 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-101 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-101 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-116 ,2147483648 ,2147483648 ,2147483648 ,-116 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-116 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-116 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-116 ,2147483648 ,2147483648 ,2147483648 ,-116 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-116 ,2147483648 ,-116 ,-116 ,2147483648 ,-116 ,-116 ,-116 ,2147483648 ,2147483648 ,-116 ,2147483648 ,-116 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-116 ,2147483648 ,2147483648 ,2147483648 ,-116 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-116 ,-116 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-116 ,-116 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-116 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-116 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-115 ,2147483648 ,-115 ,2147483648 ,-115 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-115 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-115 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-115 ,2147483648 ,2147483648 ,2147483648 ,-115 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-115 ,2147483648 ,-115 ,-115 ,2147483648 ,-115 ,-115 ,-115 ,2147483648 ,2147483648 ,-115 ,2147483648 ,-115 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-115 ,2147483648 ,2147483648 ,2147483648 ,-115 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-115 ,-115 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-115 ,-115 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-115 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-115 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,186 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-52 ,2147483648 ,2147483648 ,2147483648 ,-52 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-52 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-52 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-52 ,2147483648 ,2147483648 ,2147483648 ,-52 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-52 ,2147483648 ,-52 ,-52 ,2147483648 ,-52 ,-52 ,-52 ,2147483648 ,2147483648 ,-52 ,2147483648 ,-52 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-52 ,2147483648 ,2147483648 ,2147483648 ,-52 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-52 ,-52 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-52 ,-52 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-52 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-52 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-64 ,2147483648 ,2147483648 ,2147483648 ,-64 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-64 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-64 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-64 ,2147483648 ,2147483648 ,2147483648 ,-64 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-64 ,2147483648 ,-64 ,-64 ,2147483648 ,-64 ,-64 ,-64 ,2147483648 ,2147483648 ,-64 ,2147483648 ,-64 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-64 ,2147483648 ,2147483648 ,2147483648 ,-64 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-64 ,-64 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-64 ,-64 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-64 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-64 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-53 ,2147483648 ,2147483648 ,2147483648 ,-53 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-53 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-53 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-53 ,2147483648 ,2147483648 ,2147483648 ,-53 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-53 ,2147483648 ,-53 ,-53 ,2147483648 ,-53 ,-53 ,-53 ,2147483648 ,2147483648 ,-53 ,2147483648 ,-53 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-53 ,2147483648 ,2147483648 ,2147483648 ,-53 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-53 ,-53 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-53 ,-53 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-53 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-53 },
+ {78 ,59 ,74 ,67 ,196 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-67 ,2147483648 ,2147483648 ,2147483648 ,-67 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-67 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-67 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-67 ,2147483648 ,2147483648 ,2147483648 ,-67 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-67 ,2147483648 ,-67 ,-67 ,2147483648 ,-67 ,-67 ,-67 ,2147483648 ,2147483648 ,-67 ,2147483648 ,-67 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-67 ,2147483648 ,2147483648 ,2147483648 ,-67 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-67 ,-67 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-67 ,-67 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-67 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-67 },
+ {78 ,59 ,74 ,67 ,196 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,196 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-66 ,2147483648 ,2147483648 ,2147483648 ,-66 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-66 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-66 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-66 ,2147483648 ,2147483648 ,2147483648 ,-66 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-66 ,2147483648 ,-66 ,-66 ,2147483648 ,-66 ,-66 ,-66 ,2147483648 ,2147483648 ,-66 ,2147483648 ,-66 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-66 ,2147483648 ,2147483648 ,2147483648 ,-66 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-66 ,-66 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-66 ,-66 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-66 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-66 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-59 ,2147483648 ,2147483648 ,2147483648 ,-59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-59 ,2147483648 ,2147483648 ,2147483648 ,-59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-59 ,2147483648 ,-59 ,-59 ,2147483648 ,-59 ,-59 ,-59 ,2147483648 ,2147483648 ,-59 ,2147483648 ,-59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-59 ,2147483648 ,2147483648 ,2147483648 ,-59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-59 ,-59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-59 ,-59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-59 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-59 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-56 ,2147483648 ,2147483648 ,2147483648 ,-56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-56 ,2147483648 ,2147483648 ,2147483648 ,-56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-56 ,2147483648 ,-56 ,-56 ,2147483648 ,-56 ,-56 ,-56 ,2147483648 ,2147483648 ,-56 ,2147483648 ,-56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-56 ,2147483648 ,2147483648 ,2147483648 ,-56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-56 ,-56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-56 ,-56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-56 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-56 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-87 ,2147483648 ,2147483648 ,2147483648 ,-87 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-87 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-87 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-87 ,2147483648 ,2147483648 ,2147483648 ,-87 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-87 ,2147483648 ,-87 ,-87 ,2147483648 ,-87 ,-87 ,-87 ,2147483648 ,2147483648 ,-87 ,2147483648 ,-87 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-87 ,2147483648 ,2147483648 ,2147483648 ,-87 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-87 ,-87 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-87 ,-87 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-87 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-87 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-55 ,2147483648 ,2147483648 ,2147483648 ,-55 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-55 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-55 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-55 ,2147483648 ,2147483648 ,2147483648 ,-55 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-55 ,2147483648 ,-55 ,-55 ,2147483648 ,-55 ,-55 ,-55 ,2147483648 ,2147483648 ,-55 ,2147483648 ,-55 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-55 ,2147483648 ,2147483648 ,2147483648 ,-55 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-55 ,-55 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-55 ,-55 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-55 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-55 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-83 ,2147483648 ,2147483648 ,2147483648 ,-83 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-83 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-83 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-83 ,2147483648 ,2147483648 ,2147483648 ,-83 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-83 ,2147483648 ,-83 ,-83 ,2147483648 ,-83 ,-83 ,-83 ,2147483648 ,2147483648 ,-83 ,2147483648 ,-83 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-83 ,2147483648 ,2147483648 ,2147483648 ,-83 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-83 ,-83 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-83 ,-83 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-83 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-83 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-50 ,2147483648 ,2147483648 ,2147483648 ,-50 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-50 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-50 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-50 ,2147483648 ,2147483648 ,2147483648 ,-50 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-50 ,2147483648 ,-50 ,-50 ,2147483648 ,-50 ,-50 ,-50 ,2147483648 ,2147483648 ,-50 ,2147483648 ,-50 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-50 ,2147483648 ,2147483648 ,2147483648 ,-50 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-50 ,-50 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-50 ,-50 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-50 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-50 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-71 ,2147483648 ,2147483648 ,2147483648 ,-71 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-71 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-71 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-71 ,2147483648 ,2147483648 ,2147483648 ,-71 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-71 ,2147483648 ,-71 ,-71 ,2147483648 ,-71 ,-71 ,-71 ,2147483648 ,2147483648 ,-71 ,2147483648 ,-71 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-71 ,2147483648 ,2147483648 ,2147483648 ,-71 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-71 ,-71 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-71 ,-71 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-71 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-71 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,186 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-62 ,2147483648 ,2147483648 ,2147483648 ,-62 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-62 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-62 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-62 ,2147483648 ,2147483648 ,2147483648 ,-62 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-62 ,2147483648 ,-62 ,-62 ,2147483648 ,-62 ,-62 ,-62 ,2147483648 ,2147483648 ,-62 ,2147483648 ,-62 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-62 ,2147483648 ,2147483648 ,2147483648 ,-62 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-62 ,-62 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-62 ,-62 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-62 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-62 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-69 ,2147483648 ,2147483648 ,2147483648 ,-69 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-69 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-69 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-69 ,2147483648 ,2147483648 ,2147483648 ,-69 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-69 ,2147483648 ,-69 ,-69 ,2147483648 ,-69 ,-69 ,-69 ,2147483648 ,2147483648 ,-69 ,2147483648 ,-69 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-69 ,2147483648 ,2147483648 ,2147483648 ,-69 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-69 ,-69 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-69 ,-69 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-69 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-69 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-72 ,2147483648 ,2147483648 ,2147483648 ,-72 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-72 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-72 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-72 ,2147483648 ,2147483648 ,2147483648 ,-72 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-72 ,2147483648 ,-72 ,-72 ,2147483648 ,-72 ,-72 ,-72 ,2147483648 ,2147483648 ,-72 ,2147483648 ,-72 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-72 ,2147483648 ,2147483648 ,2147483648 ,-72 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-72 ,-72 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-72 ,-72 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-72 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-72 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-61 ,2147483648 ,2147483648 ,2147483648 ,-61 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-61 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-61 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-61 ,2147483648 ,2147483648 ,2147483648 ,-61 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-61 ,2147483648 ,-61 ,-61 ,2147483648 ,-61 ,-61 ,-61 ,2147483648 ,2147483648 ,-61 ,2147483648 ,-61 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-61 ,2147483648 ,2147483648 ,2147483648 ,-61 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-61 ,-61 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-61 ,-61 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-61 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-61 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-63 ,2147483648 ,2147483648 ,2147483648 ,-63 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-63 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-63 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-63 ,2147483648 ,2147483648 ,2147483648 ,-63 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-63 ,2147483648 ,-63 ,-63 ,2147483648 ,-63 ,-63 ,-63 ,2147483648 ,2147483648 ,-63 ,2147483648 ,-63 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-63 ,2147483648 ,2147483648 ,2147483648 ,-63 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-63 ,-63 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-63 ,-63 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-63 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-63 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-45 ,2147483648 ,2147483648 ,2147483648 ,-45 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-45 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-45 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-45 ,2147483648 ,2147483648 ,2147483648 ,-45 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-45 ,2147483648 ,-45 ,-45 ,2147483648 ,-45 ,-45 ,-45 ,2147483648 ,2147483648 ,-45 ,2147483648 ,-45 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-45 ,2147483648 ,2147483648 ,2147483648 ,-45 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-45 ,-45 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-45 ,-45 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-45 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-45 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-49 ,2147483648 ,2147483648 ,2147483648 ,-49 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-49 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-49 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-49 ,2147483648 ,2147483648 ,2147483648 ,-49 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-49 ,2147483648 ,-49 ,-49 ,2147483648 ,-49 ,-49 ,-49 ,2147483648 ,2147483648 ,-49 ,2147483648 ,-49 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-49 ,2147483648 ,2147483648 ,2147483648 ,-49 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-49 ,-49 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-49 ,-49 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-49 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-49 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-68 ,2147483648 ,2147483648 ,2147483648 ,-68 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-68 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-68 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-68 ,2147483648 ,2147483648 ,2147483648 ,-68 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-68 ,2147483648 ,-68 ,-68 ,2147483648 ,-68 ,-68 ,-68 ,2147483648 ,2147483648 ,-68 ,2147483648 ,-68 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-68 ,2147483648 ,2147483648 ,2147483648 ,-68 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-68 ,-68 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-68 ,-68 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-68 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-68 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-65 ,2147483648 ,2147483648 ,2147483648 ,-65 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-65 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-65 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-65 ,2147483648 ,2147483648 ,2147483648 ,-65 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-65 ,2147483648 ,-65 ,-65 ,2147483648 ,-65 ,-65 ,-65 ,2147483648 ,2147483648 ,-65 ,2147483648 ,-65 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-65 ,2147483648 ,2147483648 ,2147483648 ,-65 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-65 ,-65 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-65 ,-65 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-65 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-65 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-48 ,2147483648 ,2147483648 ,2147483648 ,-48 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-48 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-48 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-48 ,2147483648 ,2147483648 ,2147483648 ,-48 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-48 ,2147483648 ,-48 ,-48 ,2147483648 ,-48 ,-48 ,-48 ,2147483648 ,2147483648 ,-48 ,2147483648 ,-48 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-48 ,2147483648 ,2147483648 ,2147483648 ,-48 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-48 ,-48 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-48 ,-48 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-48 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-48 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-60 ,2147483648 ,2147483648 ,2147483648 ,-60 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-60 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-60 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-60 ,2147483648 ,2147483648 ,2147483648 ,-60 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-60 ,2147483648 ,-60 ,-60 ,2147483648 ,-60 ,-60 ,-60 ,2147483648 ,2147483648 ,-60 ,2147483648 ,-60 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-60 ,2147483648 ,2147483648 ,2147483648 ,-60 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-60 ,-60 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-60 ,-60 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-60 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-60 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-47 ,2147483648 ,2147483648 ,2147483648 ,-47 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-47 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-47 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-47 ,2147483648 ,2147483648 ,2147483648 ,-47 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-47 ,2147483648 ,-47 ,-47 ,2147483648 ,-47 ,-47 ,-47 ,2147483648 ,2147483648 ,-47 ,2147483648 ,-47 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-47 ,2147483648 ,2147483648 ,2147483648 ,-47 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-47 ,-47 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-47 ,-47 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-47 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-47 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-70 ,2147483648 ,2147483648 ,2147483648 ,-70 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-70 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-70 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-70 ,2147483648 ,2147483648 ,2147483648 ,-70 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-70 ,2147483648 ,-70 ,-70 ,2147483648 ,-70 ,-70 ,-70 ,2147483648 ,2147483648 ,-70 ,2147483648 ,-70 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-70 ,2147483648 ,2147483648 ,2147483648 ,-70 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-70 ,-70 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-70 ,-70 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-70 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-70 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-57 ,2147483648 ,2147483648 ,2147483648 ,-57 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-57 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-57 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-57 ,2147483648 ,2147483648 ,2147483648 ,-57 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-57 ,2147483648 ,-57 ,-57 ,2147483648 ,-57 ,-57 ,-57 ,2147483648 ,2147483648 ,-57 ,2147483648 ,-57 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-57 ,2147483648 ,2147483648 ,2147483648 ,-57 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-57 ,-57 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-57 ,-57 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-57 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-57 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-54 ,2147483648 ,2147483648 ,2147483648 ,-54 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-54 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-54 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-54 ,2147483648 ,2147483648 ,2147483648 ,-54 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-54 ,2147483648 ,-54 ,-54 ,2147483648 ,-54 ,-54 ,-54 ,2147483648 ,2147483648 ,-54 ,2147483648 ,-54 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-54 ,2147483648 ,2147483648 ,2147483648 ,-54 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-54 ,-54 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-54 ,-54 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-54 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-54 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-58 ,2147483648 ,2147483648 ,2147483648 ,-58 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-58 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-58 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-58 ,2147483648 ,2147483648 ,2147483648 ,-58 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-58 ,2147483648 ,-58 ,-58 ,2147483648 ,-58 ,-58 ,-58 ,2147483648 ,2147483648 ,-58 ,2147483648 ,-58 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-58 ,2147483648 ,2147483648 ,2147483648 ,-58 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-58 ,-58 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-58 ,-58 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-58 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-58 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-51 ,2147483648 ,2147483648 ,2147483648 ,-51 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-51 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-51 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-51 ,2147483648 ,2147483648 ,2147483648 ,-51 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-51 ,2147483648 ,-51 ,-51 ,2147483648 ,-51 ,-51 ,-51 ,2147483648 ,2147483648 ,-51 ,2147483648 ,-51 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-51 ,2147483648 ,2147483648 ,2147483648 ,-51 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-51 ,-51 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-51 ,-51 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-51 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-51 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-46 ,2147483648 ,2147483648 ,2147483648 ,-46 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-46 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-46 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-46 ,2147483648 ,2147483648 ,2147483648 ,-46 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-46 ,2147483648 ,-46 ,-46 ,2147483648 ,-46 ,-46 ,-46 ,2147483648 ,2147483648 ,-46 ,2147483648 ,-46 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-46 ,2147483648 ,2147483648 ,2147483648 ,-46 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-46 ,-46 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-46 ,-46 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-46 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-46 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,243 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-106 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,309 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,310 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,311 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,312 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,313 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,314 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,315 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,316 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,317 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,318 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,319 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,320 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,321 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,322 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,323 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-105 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-78 ,2147483648 ,2147483648 ,2147483648 ,-78 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-78 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-78 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-78 ,2147483648 ,2147483648 ,2147483648 ,-78 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-78 ,2147483648 ,-78 ,-78 ,2147483648 ,-78 ,-78 ,-78 ,2147483648 ,2147483648 ,-78 ,2147483648 ,-78 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-78 ,2147483648 ,2147483648 ,2147483648 ,-78 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-78 ,-78 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-78 ,-78 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-78 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-78 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-88 ,2147483648 ,2147483648 ,2147483648 ,-88 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-88 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-88 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-88 ,2147483648 ,2147483648 ,2147483648 ,-88 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-88 ,2147483648 ,-88 ,-88 ,2147483648 ,-88 ,-88 ,-88 ,2147483648 ,2147483648 ,-88 ,2147483648 ,-88 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-88 ,2147483648 ,2147483648 ,2147483648 ,-88 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-88 ,-88 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-88 ,-88 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-88 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-88 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-84 ,2147483648 ,2147483648 ,2147483648 ,-84 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-84 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-84 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-84 ,2147483648 ,2147483648 ,2147483648 ,-84 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-84 ,2147483648 ,-84 ,-84 ,2147483648 ,-84 ,-84 ,-84 ,2147483648 ,2147483648 ,-84 ,2147483648 ,-84 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-84 ,2147483648 ,2147483648 ,2147483648 ,-84 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-84 ,-84 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-84 ,-84 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-84 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-84 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-80 ,2147483648 ,2147483648 ,2147483648 ,-80 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-80 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-80 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-80 ,2147483648 ,2147483648 ,2147483648 ,-80 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-80 ,2147483648 ,-80 ,-80 ,2147483648 ,-80 ,-80 ,-80 ,2147483648 ,2147483648 ,-80 ,2147483648 ,-80 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-80 ,2147483648 ,2147483648 ,2147483648 ,-80 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-80 ,-80 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-80 ,-80 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-80 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-80 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-74 ,2147483648 ,2147483648 ,2147483648 ,-74 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-74 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-74 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-74 ,2147483648 ,2147483648 ,2147483648 ,-74 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-74 ,2147483648 ,-74 ,-74 ,2147483648 ,-74 ,-74 ,-74 ,2147483648 ,2147483648 ,-74 ,2147483648 ,-74 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-74 ,2147483648 ,2147483648 ,2147483648 ,-74 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-74 ,-74 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-74 ,-74 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-74 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-74 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-79 ,2147483648 ,2147483648 ,2147483648 ,-79 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-79 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-79 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-79 ,2147483648 ,2147483648 ,2147483648 ,-79 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-79 ,2147483648 ,-79 ,-79 ,2147483648 ,-79 ,-79 ,-79 ,2147483648 ,2147483648 ,-79 ,2147483648 ,-79 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-79 ,2147483648 ,2147483648 ,2147483648 ,-79 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-79 ,-79 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-79 ,-79 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-79 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-79 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-73 ,2147483648 ,2147483648 ,2147483648 ,-73 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-73 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-73 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-73 ,2147483648 ,2147483648 ,2147483648 ,-73 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-73 ,2147483648 ,-73 ,-73 ,2147483648 ,-73 ,-73 ,-73 ,2147483648 ,2147483648 ,-73 ,2147483648 ,-73 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-73 ,2147483648 ,2147483648 ,2147483648 ,-73 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-73 ,-73 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-73 ,-73 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-73 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-73 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-81 ,2147483648 ,2147483648 ,2147483648 ,-81 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-81 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-81 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-81 ,2147483648 ,2147483648 ,2147483648 ,-81 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-81 ,2147483648 ,-81 ,-81 ,2147483648 ,-81 ,-81 ,-81 ,2147483648 ,2147483648 ,-81 ,2147483648 ,-81 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-81 ,2147483648 ,2147483648 ,2147483648 ,-81 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-81 ,-81 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-81 ,-81 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-81 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-81 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-75 ,2147483648 ,2147483648 ,2147483648 ,-75 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-75 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-75 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-75 ,2147483648 ,2147483648 ,2147483648 ,-75 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-75 ,2147483648 ,-75 ,-75 ,2147483648 ,-75 ,-75 ,-75 ,2147483648 ,2147483648 ,-75 ,2147483648 ,-75 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-75 ,2147483648 ,2147483648 ,2147483648 ,-75 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-75 ,-75 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-75 ,-75 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-75 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-75 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-77 ,2147483648 ,2147483648 ,2147483648 ,-77 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-77 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-77 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-77 ,2147483648 ,2147483648 ,2147483648 ,-77 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-77 ,2147483648 ,-77 ,-77 ,2147483648 ,-77 ,-77 ,-77 ,2147483648 ,2147483648 ,-77 ,2147483648 ,-77 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-77 ,2147483648 ,2147483648 ,2147483648 ,-77 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-77 ,-77 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-77 ,-77 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-77 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-77 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-76 ,2147483648 ,2147483648 ,2147483648 ,-76 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-76 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-76 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-76 ,2147483648 ,2147483648 ,2147483648 ,-76 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-76 ,2147483648 ,-76 ,-76 ,2147483648 ,-76 ,-76 ,-76 ,2147483648 ,2147483648 ,-76 ,2147483648 ,-76 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-76 ,2147483648 ,2147483648 ,2147483648 ,-76 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-76 ,-76 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-76 ,-76 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-76 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-76 },
+ {78 ,59 ,74 ,67 ,2147483648 ,25 ,2147483648 ,41 ,2147483648 ,38 ,2147483648 ,31 ,2147483648 ,62 ,58 ,2147483648 ,52 ,53 ,43 ,46 ,2147483648 ,71 ,44 ,21 ,57 ,69 ,49 ,35 ,19 ,2147483648 ,27 ,72 ,20 ,28 ,29 ,70 ,2147483648 ,37 ,81 ,23 ,75 ,2147483648 ,2147483648 ,2147483648 ,51 ,76 ,2147483648 ,61 ,2147483648 ,32 ,55 ,22 ,68 ,2147483648 ,83 ,39 ,36 ,2147483648 ,30 ,60 ,45 ,77 ,47 ,42 ,2147483648 ,2147483648 ,34 ,56 ,82 ,64 ,66 ,65 ,48 ,79 ,2147483648 ,26 ,63 ,54 ,80 ,2147483648 ,73 ,40 ,33 ,50 ,24 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,328 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,329 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,330 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,331 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-86 ,2147483648 ,2147483648 ,2147483648 ,-86 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-86 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-86 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-86 ,2147483648 ,2147483648 ,2147483648 ,-86 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-86 ,2147483648 ,-86 ,-86 ,2147483648 ,-86 ,-86 ,-86 ,2147483648 ,2147483648 ,-86 ,2147483648 ,-86 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-86 ,2147483648 ,2147483648 ,2147483648 ,-86 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-86 ,-86 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-86 ,-86 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-86 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-86 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-85 ,2147483648 ,2147483648 ,2147483648 ,-85 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-85 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-85 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-85 ,2147483648 ,2147483648 ,2147483648 ,-85 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-85 ,2147483648 ,-85 ,-85 ,2147483648 ,-85 ,-85 ,-85 ,2147483648 ,2147483648 ,-85 ,2147483648 ,-85 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-85 ,2147483648 ,2147483648 ,2147483648 ,-85 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-85 ,-85 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-85 ,-85 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-85 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-85 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-89 ,2147483648 ,2147483648 ,2147483648 ,-89 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-89 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-89 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-89 ,2147483648 ,2147483648 ,2147483648 ,-89 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-89 ,2147483648 ,-89 ,-89 ,2147483648 ,-89 ,-89 ,-89 ,2147483648 ,2147483648 ,-89 ,2147483648 ,-89 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-89 ,2147483648 ,2147483648 ,2147483648 ,-89 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-89 ,-89 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-89 ,-89 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-89 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-89 },
+ {2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-82 ,2147483648 ,2147483648 ,2147483648 ,-82 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-82 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-82 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-82 ,2147483648 ,2147483648 ,2147483648 ,-82 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-82 ,2147483648 ,-82 ,-82 ,2147483648 ,-82 ,-82 ,-82 ,2147483648 ,2147483648 ,-82 ,2147483648 ,-82 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-82 ,2147483648 ,2147483648 ,2147483648 ,-82 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-82 ,-82 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-82 ,-82 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-82 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,2147483648 ,-82 }
};
const struct _SCRIPT_ENGINE_TOKEN LalrSemanticRules[RULES_COUNT]=
{
@@ -2587,6 +2890,13 @@ const struct _SCRIPT_ENGINE_TOKEN LalrSemanticRules[RULES_COUNT]=
{SEMANTIC_RULE, "@NOT"},
{SEMANTIC_RULE, "@POI"},
{SEMANTIC_RULE, "@REFERENCE"},
+ {SEMANTIC_RULE, "@RDTSC"},
+ {SEMANTIC_RULE, "@RDTSCP"},
+ {SEMANTIC_RULE, "@LBR_SAVE"},
+ {SEMANTIC_RULE, "@LBR_DUMP"},
+ {SEMANTIC_RULE, "@LBR_PRINT"},
+ {SEMANTIC_RULE, "@LBR_RESTORE"},
+ {SEMANTIC_RULE, "@LBR_CHECK"},
{SEMANTIC_RULE, "@POI"},
{SEMANTIC_RULE, "@DB"},
{SEMANTIC_RULE, "@DD"},
@@ -2614,6 +2924,7 @@ const struct _SCRIPT_ENGINE_TOKEN LalrSemanticRules[RULES_COUNT]=
{SEMANTIC_RULE, "@DD_PA"},
{SEMANTIC_RULE, "@DW_PA"},
{SEMANTIC_RULE, "@DQ_PA"},
+ {SEMANTIC_RULE, "@LBR_RESTORE_BY_FILTER"},
{SEMANTIC_RULE, "@ED"},
{SEMANTIC_RULE, "@EB"},
{SEMANTIC_RULE, "@EQ"},
@@ -2636,6 +2947,7 @@ const struct _SCRIPT_ENGINE_TOKEN LalrSemanticRules[RULES_COUNT]=
{SEMANTIC_RULE, "@PUSH"},
{SEMANTIC_RULE, "@PUSH"},
{SEMANTIC_RULE, "@PUSH"},
+ {UNKNOWN, ""},
{SEMANTIC_RULE, "@PUSH"},
{SEMANTIC_RULE, "@PUSH"},
{SEMANTIC_RULE, "@PUSH"},
@@ -2652,5 +2964,10 @@ const struct _SCRIPT_ENGINE_TOKEN LalrSemanticRules[RULES_COUNT]=
{UNKNOWN, ""},
{UNKNOWN, ""},
{UNKNOWN, ""},
+ {UNKNOWN, ""},
+ {SEMANTIC_RULE, "@ARRAY_INDEX_READ"},
+ {SEMANTIC_RULE, "@PUSH"},
+ {SEMANTIC_RULE, "@ARRAY_DIM_NUMBER"},
+ {UNKNOWN, ""},
{UNKNOWN, ""}
};
diff --git a/hyperdbg/script-engine/code/scanner.c b/hyperdbg/script-engine/code/scanner.c
index e1e92549..b61bf994 100644
--- a/hyperdbg/script-engine/code/scanner.c
+++ b/hyperdbg/script-engine/code/scanner.c
@@ -16,7 +16,7 @@
*
* @param c
* @param str
- * @return PTOKEN
+ * @return PSCRIPT_ENGINE_TOKEN
*/
PSCRIPT_ENGINE_TOKEN
GetToken(char * c, char * str)
@@ -51,16 +51,16 @@ GetToken(char * c, char * str)
else if (*c == 'x')
{
char ByteString[] = "000";
- int len = (int)strlen(ByteString);
+ INT Len = (INT)strlen(ByteString);
int i = 0;
- for (; i < len; i++)
+ for (; i < Len; i++)
{
*c = sgetc(str);
if (!IsHex(*c))
break;
RotateLeftStringOnce(ByteString);
- ByteString[len - 1] = *c;
+ ByteString[Len - 1] = *c;
}
if (i == 0 || i == 3)
@@ -72,8 +72,8 @@ GetToken(char * c, char * str)
else
{
InputIdx--;
- char num = (char)strtol(ByteString, NULL, 16);
- AppendByte(Token, num);
+ CHAR Num = (CHAR)strtol(ByteString, NULL, 16);
+ AppendByte(Token, Num);
}
}
else if (*c == '"')
@@ -366,6 +366,16 @@ GetToken(char * c, char * str)
Token->Type = SPECIAL_TOKEN;
*c = sgetc(str);
return Token;
+ case '[':
+ strcpy(Token->Value, "[");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+ return Token;
+ case ']':
+ strcpy(Token->Value, "]");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+ return Token;
case '|':
*c = sgetc(str);
if (*c == '|')
@@ -493,9 +503,9 @@ GetToken(char * c, char * str)
if (WasFound)
{
RemoveToken(&Token);
- char str[20] = {0};
- sprintf(str, "%llx", Address);
- Token = NewToken(HEX, str);
+ char HexStr[20] = {0};
+ sprintf(HexStr, "%llx", Address);
+ Token = NewToken(HEX, HexStr);
}
else
{
@@ -508,7 +518,8 @@ GetToken(char * c, char * str)
{
if (GetGlobalIdentifierVal(Token) != -1)
{
- Token->Type = GLOBAL_ID;
+ Token->Type = GLOBAL_ID;
+ Token->VariableType = GetGlobalIdentifierVariableType(Token);
}
else
{
@@ -524,6 +535,23 @@ GetToken(char * c, char * str)
}
return Token;
+ case '#':
+ do
+ {
+ if (*c != '`')
+ AppendByte(Token, *c);
+ *c = sgetc(str);
+ } while (IsLetter(*c) || IsHex(*c) || (*c == '_') || (*c == '!'));
+ if (IsKeyword(Token->Value))
+ {
+ Token->Type = KEYWORD;
+ }
+ else
+ {
+ Token->Type = UNKNOWN;
+ }
+ return Token;
+
case ' ':
case '\t':
strcpy(Token->Value, "");
@@ -634,16 +662,16 @@ GetToken(char * c, char * str)
else if (*c == 'x')
{
char ByteString[] = "00000";
- int len = (int)strlen(ByteString);
+ INT Len = (INT)strlen(ByteString);
int i = 0;
- for (; i < len; i++)
+ for (; i < Len; i++)
{
*c = sgetc(str);
if (!IsHex(*c))
break;
RotateLeftStringOnce(ByteString);
- ByteString[len - 1] = *c;
+ ByteString[Len - 1] = *c;
}
if (i == 0 || i == 5)
@@ -655,8 +683,8 @@ GetToken(char * c, char * str)
else
{
InputIdx--;
- wchar_t num = (wchar_t)strtol(ByteString, NULL, 16);
- AppendWchar(Token, num);
+ WCHAR Num = (WCHAR)strtol(ByteString, NULL, 16);
+ AppendWchar(Token, Num);
}
}
else if (*c == '"')
@@ -701,14 +729,14 @@ GetToken(char * c, char * str)
}
else if ((*c >= 'a' && *c <= 'f') || (*c >= 'A' && *c <= 'F') || (*c == '_') || (*c == '!'))
{
- uint8_t NotHex = 0;
+ UINT8 NotHex = 0;
do
{
if (*c != '`')
AppendByte(Token, *c);
*c = sgetc(str);
- if (IsHex(*c) || *c == '`')
+ if (IsHex(*c) || *c == '`' || *c == '_')
{
// Nothing
}
@@ -779,7 +807,8 @@ GetToken(char * c, char * str)
}
else if (GetLocalIdentifierVal(Token) != -1)
{
- Token->Type = LOCAL_ID;
+ Token->Type = LOCAL_ID;
+ Token->VariableType = GetLocalIdentifierVariableType(Token);
}
else
{
@@ -818,9 +847,9 @@ GetToken(char * c, char * str)
if (WasFound)
{
RemoveToken(&Token);
- char str[20] = {0};
- sprintf(str, "%llx", Address);
- Token = NewToken(HEX, str);
+ char HexStr[20] = {0};
+ sprintf(HexStr, "%llx", Address);
+ Token = NewToken(HEX, HexStr);
}
else
{
@@ -841,12 +870,14 @@ GetToken(char * c, char * str)
}
else if (GetLocalIdentifierVal(Token) != -1)
{
- Token->Type = LOCAL_ID;
+ Token->Type = LOCAL_ID;
+ Token->VariableType = GetLocalIdentifierVariableType(Token);
}
else
{
Token->Type = LOCAL_UNRESOLVED_ID;
}
+ Token->VariableType;
}
}
}
@@ -891,9 +922,9 @@ GetToken(char * c, char * str)
if (WasFound)
{
RemoveToken(&Token);
- char str[20] = {0};
- sprintf(str, "%llx", Address);
- Token = NewToken(HEX, str);
+ char HexStr[20] = {0};
+ sprintf(HexStr, "%llx", Address);
+ Token = NewToken(HEX, HexStr);
}
else
{
@@ -914,7 +945,8 @@ GetToken(char * c, char * str)
}
else if (GetLocalIdentifierVal(Token) != -1)
{
- Token->Type = LOCAL_ID;
+ Token->Type = LOCAL_ID;
+ Token->VariableType = GetLocalIdentifierVariableType(Token);
}
else
{
@@ -938,7 +970,7 @@ GetToken(char * c, char * str)
*
* @param str
* @param c
- * @return PTOKEN
+ * @return PSCRIPT_ENGINE_TOKEN
*/
PSCRIPT_ENGINE_TOKEN
Scan(char * str, char * c)
@@ -1001,10 +1033,10 @@ Scan(char * str, char * c)
}
/**
- * @brief returns last character of string
+ * @brief Returns the next character in the input string
*
* @param str
- * @return last character
+ * @return CHAR the next character at the current position in the string
*/
char
sgetc(char * str)
@@ -1086,7 +1118,7 @@ IsVariableType(char * str)
}
/**
- * @brief eck if string is Id or not
+ * @brief Check if string is Id or not
*
* @param str
* @return char
diff --git a/hyperdbg/script-engine/code/script-engine.c b/hyperdbg/script-engine/code/script-engine.c
index edd0d5cf..a485631b 100644
--- a/hyperdbg/script-engine/code/script-engine.c
+++ b/hyperdbg/script-engine/code/script-engine.c
@@ -11,6 +11,7 @@
*
*/
#include "pch.h"
+#include "platform/user/header/platform-lib-calls.h"
// #define _SCRIPT_ENGINE_LALR_DBG_EN
// #define _SCRIPT_ENGINE_LL1_DBG_EN
@@ -44,10 +45,10 @@ ShowMessages(const char * Fmt, ...)
{
char TempMessage[COMMUNICATION_BUFFER_SIZE + TCP_END_OF_BUFFER_CHARS_COUNT] = {0};
va_start(ArgList, Fmt);
- int sprintfresult = vsprintf_s(TempMessage, COMMUNICATION_BUFFER_SIZE + TCP_END_OF_BUFFER_CHARS_COUNT, Fmt, ArgList);
+ INT SprintfResult = PlatformVsnprintf(TempMessage, COMMUNICATION_BUFFER_SIZE + TCP_END_OF_BUFFER_CHARS_COUNT, Fmt, ArgList);
va_end(ArgList);
- if (sprintfresult != -1)
+ if (SprintfResult != -1)
{
//
// There is another handler
@@ -213,7 +214,7 @@ ScriptEngineCreateSymbolTableForDisassembler(void * CallbackFunction)
* @return BOOLEAN
*/
BOOLEAN
-ScriptEngineConvertFileToPdbPath(const char * LocalFilePath, char * ResultPath, size_t ResultPathSize)
+ScriptEngineConvertFileToPdbPath(const char * LocalFilePath, char * ResultPath, SIZE_T ResultPathSize)
{
//
// A wrapper for pdb to path converter
@@ -300,6 +301,38 @@ ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetails(const char * LocalFilePath,
return SymConvertFileToPdbFileAndGuidAndAgeDetails(LocalFilePath, PdbFilePath, GuidAndAgeDetails, Is32BitModule);
}
+/**
+ * @brief Convert loaded module bytes to pdb attributes for symbols
+ *
+ * @param LoadedImageBytes
+ * @param LoadedImageSize
+ * @param LocalFilePath
+ * @param PdbFilePath
+ * @param GuidAndAgeDetails
+ * @param Is32BitModule
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+ScriptEngineConvertLoadedModuleToPdbFileAndGuidAndAgeDetails(const BYTE * LoadedImageBytes,
+ SIZE_T LoadedImageSize,
+ const char * LocalFilePath,
+ char * PdbFilePath,
+ char * GuidAndAgeDetails,
+ BOOLEAN Is32BitModule)
+{
+ //
+ // A wrapper for loaded module pdb to path file and guid and age detail converter
+ //
+ return SymConvertLoadedModuleToPdbFileAndGuidAndAgeDetails(
+ LoadedImageBytes,
+ LoadedImageSize,
+ LocalFilePath,
+ PdbFilePath,
+ GuidAndAgeDetails,
+ Is32BitModule);
+}
+
/**
* @brief The entry point of script engine
*
@@ -309,14 +342,15 @@ ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetails(const char * LocalFilePath,
PVOID
ScriptEngineParse(char * str)
{
- PSCRIPT_ENGINE_TOKEN_LIST Stack = NewTokenList();
+ char * ScriptSource = PlatformStrDup(str);
+ PSCRIPT_ENGINE_TOKEN_LIST Stack = NewTokenList();
PSCRIPT_ENGINE_TOKEN_LIST MatchedStack = NewTokenList();
PSYMBOL_BUFFER CodeBuffer = NewSymbolBuffer();
UserDefinedFunctionHead = malloc(sizeof(USER_DEFINED_FUNCTION_NODE));
- RtlZeroMemory(UserDefinedFunctionHead, sizeof(USER_DEFINED_FUNCTION_NODE));
- UserDefinedFunctionHead->Name = _strdup("main");
+ PlatformZeroMemory(UserDefinedFunctionHead, sizeof(USER_DEFINED_FUNCTION_NODE));
+ UserDefinedFunctionHead->Name = PlatformStrDup("main");
UserDefinedFunctionHead->IdTable = (unsigned long long)NewTokenList();
UserDefinedFunctionHead->FunctionParameterIdTable = (unsigned long long)NewTokenList();
UserDefinedFunctionHead->TempMap = calloc(MAX_TEMP_COUNT, 1);
@@ -327,7 +361,7 @@ ScriptEngineParse(char * str)
SCRIPT_ENGINE_ERROR_TYPE Error = SCRIPT_ENGINE_ERROR_FREE;
char * ErrorMessage = NULL;
- static FirstCall = 1;
+ static INT FirstCall = 1;
if (FirstCall)
{
GlobalIdTable = NewTokenList();
@@ -339,7 +373,7 @@ ScriptEngineParse(char * str)
int NonTerminalId;
int TerminalId;
int RuleId;
- char c;
+ CHAR C;
BOOL WaitForWaitStatementBooleanExpression = FALSE;
//
@@ -362,13 +396,13 @@ ScriptEngineParse(char * str)
Push(Stack, EndToken);
Push(Stack, StartToken);
- c = sgetc(str);
+ C = sgetc(ScriptSource);
- PSCRIPT_ENGINE_TOKEN CurrentIn = Scan(str, &c);
+ PSCRIPT_ENGINE_TOKEN CurrentIn = Scan(ScriptSource, &C);
if (CurrentIn->Type == UNKNOWN)
{
Error = SCRIPT_ENGINE_ERROR_SYNTAX;
- ErrorMessage = HandleError(&Error, str);
+ ErrorMessage = HandleError(&Error, ScriptSource);
CodeBuffer->Message = ErrorMessage;
RemoveTokenList(Stack);
@@ -421,16 +455,16 @@ ScriptEngineParse(char * str)
{
if (!strcmp(TopToken->Value, "BOOLEAN_EXPRESSION"))
{
- UINT64 BooleanExpressionSize = BooleanExpressionExtractEnd(str, &WaitForWaitStatementBooleanExpression, CurrentIn);
+ UINT64 BooleanExpressionSize = BooleanExpressionExtractEnd(ScriptSource, &WaitForWaitStatementBooleanExpression, CurrentIn);
- ScriptEngineBooleanExpresssionParse(BooleanExpressionSize, CurrentIn, MatchedStack, CodeBuffer, str, &c, &Error);
+ ScriptEngineBooleanExpresssionParse(BooleanExpressionSize, CurrentIn, MatchedStack, CodeBuffer, ScriptSource, &C, &Error);
if (Error != SCRIPT_ENGINE_ERROR_FREE)
{
break;
}
RemoveToken(&CurrentIn);
- CurrentIn = Scan(str, &c);
+ CurrentIn = Scan(ScriptSource, &C);
if (CurrentIn->Type == UNKNOWN)
{
Error = SCRIPT_ENGINE_ERROR_UNKNOWN_TOKEN;
@@ -438,7 +472,7 @@ ScriptEngineParse(char * str)
}
RemoveToken(&CurrentIn);
- CurrentIn = Scan(str, &c);
+ CurrentIn = Scan(ScriptSource, &C);
if (CurrentIn->Type == UNKNOWN)
{
Error = SCRIPT_ENGINE_ERROR_UNKNOWN_TOKEN;
@@ -494,7 +528,7 @@ ScriptEngineParse(char * str)
Push(MatchedStack, CurrentIn);
- CurrentIn = Scan(str, &c);
+ CurrentIn = Scan(ScriptSource, &C);
if (CurrentIn->Type == UNKNOWN)
{
Error = SCRIPT_ENGINE_ERROR_SYNTAX;
@@ -508,7 +542,7 @@ ScriptEngineParse(char * str)
{
WaitForWaitStatementBooleanExpression = TRUE;
}
- CodeGen(MatchedStack, CodeBuffer, TopToken, &Error);
+ CodeGen(MatchedStack, CodeBuffer, TopToken, &Error, &ScriptSource);
if (Error != SCRIPT_ENGINE_ERROR_FREE)
{
break;
@@ -525,7 +559,7 @@ ScriptEngineParse(char * str)
else
{
RemoveToken(&CurrentIn);
- CurrentIn = Scan(str, &c);
+ CurrentIn = Scan(ScriptSource, &C);
if (CurrentIn->Type == UNKNOWN)
{
@@ -543,7 +577,7 @@ ScriptEngineParse(char * str)
if (Error != SCRIPT_ENGINE_ERROR_FREE)
{
- ErrorMessage = HandleError(&Error, str);
+ ErrorMessage = HandleError(&Error, ScriptSource);
}
else
{
@@ -561,6 +595,16 @@ ScriptEngineParse(char * str)
Symbol->Type = SYMBOL_TEMP_TYPE;
Symbol->Value += UserDefinedFunctionHead->MaxTempNumber;
}
+ else if (Symbol->Type == SYMBOL_REFERENCE_LOCAL_ID_TYPE)
+ {
+ Symbol->Type = SYMBOL_REFERENCE_TEMP_TYPE;
+ Symbol->Value += UserDefinedFunctionHead->MaxTempNumber;
+ }
+ else if (Symbol->Type == SYMBOL_DEREFERENCE_LOCAL_ID_TYPE)
+ {
+ Symbol->Type = SYMBOL_DEREFERENCE_TEMP_TYPE;
+ Symbol->Value += UserDefinedFunctionHead->MaxTempNumber;
+ }
else if (Symbol->Type == SYMBOL_VARIABLE_COUNT_TYPE)
{
UINT64 VariableCount = Symbol->Value;
@@ -572,6 +616,16 @@ ScriptEngineParse(char * str)
Symbol->Type = SYMBOL_TEMP_TYPE | (Symbol->Type & 0xffffffff00000000);
Symbol->Value += UserDefinedFunctionHead->MaxTempNumber;
}
+ else if ((Symbol->Type & 0x7fffffff) == SYMBOL_REFERENCE_LOCAL_ID_TYPE)
+ {
+ Symbol->Type = SYMBOL_REFERENCE_LOCAL_ID_TYPE | (Symbol->Type & 0xffffffff00000000);
+ Symbol->Value += UserDefinedFunctionHead->MaxTempNumber;
+ }
+ else if ((Symbol->Type & 0x7fffffff) == SYMBOL_DEREFERENCE_LOCAL_ID_TYPE)
+ {
+ Symbol->Type = SYMBOL_DEREFERENCE_LOCAL_ID_TYPE | (Symbol->Type & 0xffffffff00000000);
+ Symbol->Value += UserDefinedFunctionHead->MaxTempNumber;
+ }
}
i += VariableCount;
}
@@ -615,12 +669,29 @@ ScriptEngineParse(char * str)
UserDefinedFunctionHead = 0;
}
+ if (IncludeHead)
+ {
+ PINCLUDE_NODE Node = IncludeHead;
+ while (Node)
+ {
+ if (Node->FilePath)
+ free(Node->FilePath);
+
+ PINCLUDE_NODE Temp = Node;
+ Node = Node->NextNode;
+ free(Temp);
+ }
+ IncludeHead = 0;
+ }
+
if (CurrentIn)
RemoveToken(&CurrentIn);
if (TopToken)
RemoveToken(&TopToken);
+ free(ScriptSource);
+
return (PVOID)CodeBuffer;
}
@@ -631,21 +702,24 @@ ScriptEngineParse(char * str)
* @param CodeBuffer
* @param Operator
* @param Error
+ * @param ScriptSource the script source string
+ * @return VOID
*/
void
-CodeGen(PSCRIPT_ENGINE_TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, PSCRIPT_ENGINE_TOKEN Operator, PSCRIPT_ENGINE_ERROR_TYPE Error)
+CodeGen(PSCRIPT_ENGINE_TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, PSCRIPT_ENGINE_TOKEN Operator, PSCRIPT_ENGINE_ERROR_TYPE Error, char ** ScriptSource)
{
PSCRIPT_ENGINE_TOKEN Op0 = NULL;
PSCRIPT_ENGINE_TOKEN Op1 = NULL;
PSCRIPT_ENGINE_TOKEN Op2 = NULL;
PSCRIPT_ENGINE_TOKEN Temp = NULL;
- PSYMBOL OperatorSymbol = NULL;
- PSYMBOL Op0Symbol = NULL;
- PSYMBOL Op1Symbol = NULL;
- PSYMBOL Op2Symbol = NULL;
- PSYMBOL TempSymbol = NULL;
- VARIABLE_TYPE * VariableType = NULL;
+ PSYMBOL OperatorSymbol = NULL;
+ PSYMBOL Op0Symbol = NULL;
+ PSYMBOL Op1Symbol = NULL;
+ PSYMBOL Op2Symbol = NULL;
+ PSYMBOL TempSymbol = NULL;
+ VARIABLE_TYPE * VariableType = NULL;
+ VARIABLE_TYPE * PointerVariableType = NULL;
//
// It is in user-defined function if CurrentFunctionSymbol is not null
@@ -671,7 +745,62 @@ CodeGen(PSCRIPT_ENGINE_TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, PSCRI
while (TRUE)
{
- if (!strcmp(Operator->Value, "@START_OF_USER_DEFINED_FUNCTION"))
+ if (!strcmp(Operator->Value, "@INCLUDE"))
+ {
+ char * IncludeFilePath;
+ char FullPath[MAX_PATH_LEN];
+ char * IncludeFileBuffer;
+ BOOLEAN IncludedPath = FALSE;
+
+ Temp = Pop(MatchedStack);
+ IncludeFilePath = Temp->Value;
+
+ ResolveIncludePath(IncludeFilePath, FullPath);
+
+ if (!FileExists(FullPath))
+ {
+ *Error = SCRIPT_ENGINE_ERROR_SYNTAX;
+ break;
+ }
+
+ if (!ParseIncludeFile(FullPath, &IncludeFileBuffer))
+ {
+ *Error = SCRIPT_ENGINE_ERROR_SYNTAX;
+ break;
+ }
+
+ if (!IncludeHead)
+ {
+ IncludeHead = calloc(sizeof(INCLUDE_NODE), 1);
+ IncludeHead->FilePath = PlatformStrDup(FullPath);
+ }
+ else
+ {
+ PINCLUDE_NODE Node, PrevNode = NULL;
+
+ for (Node = IncludeHead; Node; PrevNode = Node, Node = Node->NextNode)
+ {
+ if (!strcmp(Node->FilePath, FullPath))
+ {
+ IncludedPath = TRUE;
+ break;
+ }
+ }
+
+ if (!IncludedPath && PrevNode)
+ {
+ PrevNode->NextNode = calloc(sizeof(INCLUDE_NODE), 1);
+ PrevNode->NextNode->FilePath = PlatformStrDup(FullPath);
+ }
+ }
+
+ if (!IncludedPath)
+ {
+ *ScriptSource = InsertStrNew(*ScriptSource, InputIdx, IncludeFileBuffer);
+ }
+ }
+
+ else if (!strcmp(Operator->Value, "@START_OF_USER_DEFINED_FUNCTION"))
{
Op0 = Pop(MatchedStack);
VariableType = HandleType(MatchedStack);
@@ -707,10 +836,10 @@ CodeGen(PSCRIPT_ENGINE_TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, PSCRI
Node = Node->NextNode;
}
Node->NextNode = malloc(sizeof(USER_DEFINED_FUNCTION_NODE));
- RtlZeroMemory(Node->NextNode, sizeof(USER_DEFINED_FUNCTION_NODE));
+ PlatformZeroMemory(Node->NextNode, sizeof(USER_DEFINED_FUNCTION_NODE));
CurrentUserDefinedFunction = Node->NextNode;
- CurrentUserDefinedFunction->Name = _strdup(Op0->Value);
+ CurrentUserDefinedFunction->Name = PlatformStrDup(Op0->Value);
CurrentUserDefinedFunction->Address = CodeBuffer->Pointer; // CurrentPointer
CurrentUserDefinedFunction->VariableType = (long long unsigned)VariableType;
CurrentUserDefinedFunction->IdTable = (unsigned long long)NewTokenList();
@@ -816,6 +945,7 @@ CodeGen(PSCRIPT_ENGINE_TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, PSCRI
Symbol->Type = SYMBOL_TEMP_TYPE;
Symbol->Value += CurrentUserDefinedFunction->MaxTempNumber;
}
+
else if (Symbol->Type == SYMBOL_VARIABLE_COUNT_TYPE)
{
UINT64 VariableCount = Symbol->Value;
@@ -1098,9 +1228,12 @@ CodeGen(PSCRIPT_ENGINE_TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, PSCRI
}
else if (!strcmp(Operator->Value, "@MULTIPLE_ASSIGNMENT"))
{
- PSYMBOL Symbol = NewSymbol();
- Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
- Symbol->Value = FUNC_MOV;
+ int Op1Capacity = 8;
+ int Op1Count = 0;
+ PSCRIPT_ENGINE_TOKEN * Op1Array = (PSCRIPT_ENGINE_TOKEN *)malloc(sizeof(PSCRIPT_ENGINE_TOKEN) * Op1Capacity);
+ PSYMBOL Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_MOV;
Op0 = Pop(MatchedStack);
Op0Symbol = ToSymbol(Op0, Error);
@@ -1108,6 +1241,14 @@ CodeGen(PSCRIPT_ENGINE_TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, PSCRI
for (int i = MatchedStack->Pointer; i > 0; i--)
{
Op1 = Top(MatchedStack);
+
+ if (Op1Count >= Op1Capacity)
+ {
+ Op1Capacity *= 2;
+ Op1Array = (PSCRIPT_ENGINE_TOKEN *)realloc(Op1Array, sizeof(PSCRIPT_ENGINE_TOKEN) * Op1Capacity);
+ }
+ Op1Array[Op1Count++] = Op1;
+
if (Op1->Type == TEMP || Op1->Type == HEX || Op1->Type == OCTAL || Op1->Type == BINARY || Op1->Type == PSEUDO_REGISTER)
{
*Error = SCRIPT_ENGINE_ERROR_SYNTAX;
@@ -1133,7 +1274,7 @@ CodeGen(PSCRIPT_ENGINE_TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, PSCRI
Op1Symbol = NewSymbol();
free((void *)Op1Symbol->Value);
- Op1Symbol->Value = NewLocalIdentifier(Op1);
+ Op1Symbol->Value = NewLocalIdentifier(Op1, 8);
SetType(&Op1Symbol->Type, SYMBOL_LOCAL_ID_TYPE);
Pop(MatchedStack);
PushSymbol(CodeBuffer, Op1Symbol);
@@ -1176,7 +1317,20 @@ CodeGen(PSCRIPT_ENGINE_TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, PSCRI
break;
}
- // Op1Symbol->VariableType = (unsigned long long)VariableType;
+ for (int i = 0; i < Op1Count; i++)
+ {
+ Op1 = Op1Array[i];
+ if (Op1->Type == LOCAL_UNRESOLVED_ID || Op1->Type == LOCAL_ID)
+ {
+ SetLocalIdentifierVariableType(Op1, VariableType);
+ }
+ else if (Op1->Type == GLOBAL_UNRESOLVED_ID || Op1->Type == GLOBAL_ID)
+ {
+ SetGlobalIdentifierVariableType(Op1, VariableType);
+ }
+ }
+
+ Op1 = 0;
}
}
@@ -1188,6 +1342,143 @@ CodeGen(PSCRIPT_ENGINE_TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, PSCRI
{
break;
}
+
+ free(Op1Array);
+ }
+ else if (!strcmp(Operator->Value, "@ARRAY_INDEX_READ") || !strcmp(Operator->Value, "@ARRAY_INDEX_WRITE"))
+ {
+ int ArrayCapacity = 8;
+ int TokenCount = 0;
+ PSCRIPT_ENGINE_TOKEN * TokenArray = (PSCRIPT_ENGINE_TOKEN *)malloc(sizeof(PSCRIPT_ENGINE_TOKEN) * ArrayCapacity);
+ PSCRIPT_ENGINE_TOKEN IdToken;
+ PSYMBOL IdSymbol;
+ int ElementOffset = 0;
+ PSYMBOL Symbol;
+ PSCRIPT_ENGINE_TOKEN OffsetToken;
+ PSYMBOL OffsetSymbol;
+
+ while (MatchedStack->Pointer)
+ {
+ if (TokenCount >= ArrayCapacity)
+ {
+ TokenCount *= 2;
+ TokenArray = (PSCRIPT_ENGINE_TOKEN *)realloc(TokenArray, sizeof(PSCRIPT_ENGINE_TOKEN) * ArrayCapacity);
+ }
+
+ Temp = Top(MatchedStack);
+ if (!strcmp(Top(MatchedStack)->Value, "@ARRAY_DIM_NUMBER"))
+ {
+ Pop(MatchedStack);
+ TokenArray[TokenCount] = Pop(MatchedStack);
+ TokenCount++;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ IdToken = Pop(MatchedStack);
+ IdSymbol = ToSymbol(IdToken, Error);
+
+ if (IdToken->Type == LOCAL_UNRESOLVED_ID)
+ {
+ *Error = SCRIPT_ENGINE_ERROR_SYNTAX;
+ break;
+ }
+
+ for (int i = 0; i < TokenCount / 2; i++)
+ {
+ PSCRIPT_ENGINE_TOKEN tmp = TokenArray[i];
+ TokenArray[i] = TokenArray[TokenCount - i - 1];
+ TokenArray[TokenCount - i - 1] = tmp;
+ }
+
+ VariableType = (VARIABLE_TYPE *)IdToken->VariableType;
+ Temp = NewTemp(Error);
+ TempSymbol = ToSymbol(Temp, Error);
+ OffsetToken = NewTemp(Error);
+ OffsetSymbol = ToSymbol(OffsetToken, Error);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_MOV;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_NUM_TYPE;
+ Symbol->Value = 0;
+ PushSymbol(CodeBuffer, Symbol);
+
+ PushSymbol(CodeBuffer, OffsetSymbol);
+
+ for (int i = 0; i < TokenCount; i++)
+ {
+ if (!VariableType->Base)
+ {
+ *Error = SCRIPT_ENGINE_ERROR_SYNTAX;
+ break;
+ }
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_MUL;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_NUM_TYPE;
+ Symbol->Value = VariableType->Base->Size;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Symbol = ToSymbol(TokenArray[i], Error);
+ PushSymbol(CodeBuffer, Symbol);
+
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_ADD;
+ PushSymbol(CodeBuffer, Symbol);
+
+ PushSymbol(CodeBuffer, TempSymbol);
+ PushSymbol(CodeBuffer, OffsetSymbol);
+ PushSymbol(CodeBuffer, OffsetSymbol);
+
+ VariableType = VariableType->Base;
+ }
+
+ if (*Error != SCRIPT_ENGINE_ERROR_FREE)
+ {
+ break;
+ }
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_ADD;
+ PushSymbol(CodeBuffer, Symbol);
+
+ PushSymbol(CodeBuffer, IdSymbol);
+ PushSymbol(CodeBuffer, OffsetSymbol);
+ PushSymbol(CodeBuffer, OffsetSymbol);
+
+ if (!strcmp(Operator->Value, "@ARRAY_INDEX_READ"))
+ {
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_POI;
+ PushSymbol(CodeBuffer, Symbol);
+
+ PushSymbol(CodeBuffer, OffsetSymbol);
+ PushSymbol(CodeBuffer, OffsetSymbol);
+ }
+ else if (!strcmp(Operator->Value, "@ARRAY_INDEX_WRITE"))
+ {
+ OffsetToken->Type = DEFERENCE_TEMP;
+ }
+
+ Push(MatchedStack, OffsetToken);
+
+ FreeTemp(Temp);
}
else if (!strcmp(Operator->Value, "@MOV"))
{
@@ -1207,7 +1498,7 @@ CodeGen(PSCRIPT_ENGINE_TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, PSCRI
{
Op1Symbol = NewSymbol();
free((void *)Op1Symbol->Value);
- Op1Symbol->Value = NewLocalIdentifier(Op1);
+ Op1Symbol->Value = NewLocalIdentifier(Op1, 8);
SetType(&Op1Symbol->Type, SYMBOL_LOCAL_ID_TYPE);
}
else
@@ -1217,8 +1508,18 @@ CodeGen(PSCRIPT_ENGINE_TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, PSCRI
if (MatchedStack->Pointer > 0)
{
- if (Top(MatchedStack)->Type == SCRIPT_VARIABLE_TYPE)
+ if (!strcmp(Top(MatchedStack)->Value, "@DECLARE_POINTER_TYPE") || Top(MatchedStack)->Type == SCRIPT_VARIABLE_TYPE)
{
+ if (!strcmp(Top(MatchedStack)->Value, "@DECLARE_POINTER_TYPE"))
+ {
+ PointerVariableType = calloc(1, sizeof(VARIABLE_TYPE));
+ PointerVariableType->Kind = TY_PTR;
+ PointerVariableType->Size = 8;
+ PointerVariableType->Align = 8;
+ PointerVariableType->IsUnsigned = TRUE;
+ Pop(MatchedStack);
+ }
+
VariableType = HandleType(MatchedStack);
if (VariableType->Kind == TY_UNKNOWN)
@@ -1227,7 +1528,20 @@ CodeGen(PSCRIPT_ENGINE_TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, PSCRI
break;
}
- // Op1Symbol->VariableType = (unsigned long long)VariableType;
+ if (PointerVariableType)
+ {
+ PointerVariableType->Base = VariableType;
+ VariableType = PointerVariableType;
+ }
+
+ if (Op1->Type == LOCAL_UNRESOLVED_ID || Op1->Type == LOCAL_ID)
+ {
+ SetLocalIdentifierVariableType(Op1, VariableType);
+ }
+ else if (Op1->Type == GLOBAL_UNRESOLVED_ID || Op1->Type == GLOBAL_ID)
+ {
+ SetGlobalIdentifierVariableType(Op1, VariableType);
+ }
}
}
@@ -1244,6 +1558,310 @@ CodeGen(PSCRIPT_ENGINE_TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, PSCRI
break;
}
}
+ else if (!strcmp(Operator->Value, "@DECLARE_POINTER_TYPE"))
+ {
+ Push(MatchedStack, CopyToken(Operator));
+ }
+ else if (!strcmp(Operator->Value, "@ARRAY_DIM_NUMBER") || !strcmp(Operator->Value, "@ARRAY_LEFT_BRACKET") || !strcmp(Operator->Value, "@ARRAY_L_VALUE"))
+ {
+ Push(MatchedStack, CopyToken(Operator));
+ }
+ else if (!strcmp(Operator->Value, "@DEREFERENCE"))
+ {
+ PSYMBOL Symbol;
+
+ Op0 = Pop(MatchedStack);
+ Op1 = Pop(MatchedStack);
+
+ if (Op1->Type == LOCAL_UNRESOLVED_ID)
+ {
+ *Error = SCRIPT_ENGINE_ERROR_SYNTAX;
+ break;
+ }
+
+ if (((VARIABLE_TYPE *)Op1->VariableType)->Size == 4)
+ {
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_ED;
+
+ Op0Symbol = ToSymbol(Op0, Error);
+ Op1Symbol = ToSymbol(Op1, Error);
+
+ Temp = NewTemp(Error);
+ TempSymbol = ToSymbol(Temp, Error);
+
+ PushSymbol(CodeBuffer, Symbol);
+ PushSymbol(CodeBuffer, Op0Symbol);
+ PushSymbol(CodeBuffer, Op1Symbol);
+ PushSymbol(CodeBuffer, TempSymbol);
+ FreeTemp(Temp);
+ }
+ else if (((VARIABLE_TYPE *)Op1->VariableType)->Size == 8)
+ {
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_EQ;
+
+ Op0Symbol = ToSymbol(Op0, Error);
+ Op1Symbol = ToSymbol(Op1, Error);
+
+ Temp = NewTemp(Error);
+ TempSymbol = ToSymbol(Temp, Error);
+
+ PushSymbol(CodeBuffer, Symbol);
+ PushSymbol(CodeBuffer, Op0Symbol);
+ PushSymbol(CodeBuffer, Op1Symbol);
+ PushSymbol(CodeBuffer, TempSymbol);
+ FreeTemp(Temp);
+ }
+
+ else if (((VARIABLE_TYPE *)Op1->VariableType)->Size == 1)
+ {
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_EB;
+
+ Op0Symbol = ToSymbol(Op0, Error);
+ Op1Symbol = ToSymbol(Op1, Error);
+
+ Temp = NewTemp(Error);
+ TempSymbol = ToSymbol(Temp, Error);
+
+ PushSymbol(CodeBuffer, Symbol);
+ PushSymbol(CodeBuffer, Op0Symbol);
+ PushSymbol(CodeBuffer, Op1Symbol);
+ PushSymbol(CodeBuffer, TempSymbol);
+ FreeTemp(Temp);
+ }
+ }
+ else if (!strcmp(Operator->Value, "@ARRAY_DECLARITION"))
+ {
+ int TokenCapacity = 8;
+ int TokenCount = 0;
+ PSCRIPT_ENGINE_TOKEN * TokenArray = (PSCRIPT_ENGINE_TOKEN *)malloc(sizeof(PSCRIPT_ENGINE_TOKEN) * TokenCapacity);
+ PSCRIPT_ENGINE_TOKEN IdToken = NULL;
+ PSYMBOL IdSymbol = NewSymbol();
+ ;
+ VARIABLE_TYPE * VariableType2 = NULL;
+ int Last_ARRAY_DIM_NUMBER_Idx = 0;
+ int ArrayElementCount = 0;
+ PSYMBOL Symbol = NULL;
+ int BaseTypeSize = 0;
+
+ for (int i = MatchedStack->Pointer; i > 0; i--)
+ {
+ Temp = Pop(MatchedStack);
+ if (!strcmp(Temp->Value, "@ARRAY_L_VALUE"))
+ {
+ break;
+ }
+
+ if (TokenCount >= TokenCapacity)
+ {
+ TokenCapacity *= 2;
+ TokenArray = (PSCRIPT_ENGINE_TOKEN *)realloc(TokenArray, sizeof(PSCRIPT_ENGINE_TOKEN) * TokenCapacity);
+ }
+ TokenArray[TokenCount++] = Temp;
+ }
+
+ for (SIZE_T i = 0; i < TokenCount / 2; i++)
+ {
+ PSCRIPT_ENGINE_TOKEN tmp = TokenArray[i];
+ TokenArray[i] = TokenArray[TokenCount - i - 1];
+ TokenArray[TokenCount - i - 1] = tmp;
+ }
+
+ IdToken = Pop(MatchedStack);
+
+ if (MatchedStack->Pointer > 0)
+ {
+ if (Top(MatchedStack)->Type == SCRIPT_VARIABLE_TYPE)
+ {
+ VariableType = HandleType(MatchedStack);
+
+ if (VariableType->Kind == TY_UNKNOWN)
+ {
+ *Error = SCRIPT_ENGINE_ERROR_UNDEFINED_VARIABLE_TYPE;
+ break;
+ }
+ }
+ }
+
+ if (!VariableType)
+ {
+ VariableType = VARIABLE_TYPE_LONG;
+ }
+
+ BaseTypeSize = VariableType->Size;
+
+ for (int i = TokenCount - 1; i >= 0; i--)
+ {
+ if (!strcmp(TokenArray[i]->Value, "@ARRAY_DIM_NUMBER"))
+ {
+ Last_ARRAY_DIM_NUMBER_Idx = i;
+ break;
+ }
+ }
+
+ for (int i = Last_ARRAY_DIM_NUMBER_Idx; i >= 0; i--)
+ {
+ if (!strcmp(TokenArray[i]->Value, "@ARRAY_DIM_NUMBER"))
+ {
+ VariableType2 = calloc(1, sizeof(VARIABLE_TYPE));
+ VariableType2->Kind = TY_ARRAY;
+ VariableType2->Size = VariableType->Size * atoi(TokenArray[i - 1]->Value);
+ VariableType2->Align = VariableType->Align;
+ VariableType2->Base = VariableType;
+ VariableType2->ArrayLen = atoi(TokenArray[i - 1]->Value);
+ VariableType = VariableType2;
+ i--;
+ }
+ }
+
+ if (IdToken->Type == LOCAL_UNRESOLVED_ID)
+ {
+ IdSymbol->Value = NewLocalIdentifier(IdToken, VariableType->Size);
+ SetType(&IdSymbol->Type, SYMBOL_REFERENCE_LOCAL_ID_TYPE);
+ SetLocalIdentifierVariableType(IdToken, VariableType);
+ }
+
+ for (int i = Last_ARRAY_DIM_NUMBER_Idx + 1; i < TokenCount; i++)
+ {
+ if (TokenArray[i]->Type != SEMANTIC_RULE)
+ {
+ if ((ArrayElementCount * BaseTypeSize) > VariableType->Size)
+ {
+ *Error = SCRIPT_ENGINE_ERROR_SYNTAX;
+ break;
+ }
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_MUL;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_NUM_TYPE;
+ Symbol->Value = BaseTypeSize;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_NUM_TYPE;
+ Symbol->Value = ArrayElementCount;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Temp = NewTemp(Error);
+ TempSymbol = ToSymbol(Temp, Error);
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_ADD;
+
+ PushSymbol(CodeBuffer, Symbol);
+ PushSymbol(CodeBuffer, IdSymbol);
+ PushSymbol(CodeBuffer, TempSymbol);
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+
+ if (BaseTypeSize == 4)
+ {
+ Symbol->Value = FUNC_ED;
+ }
+ else if (BaseTypeSize == 8)
+ {
+ Symbol->Value = FUNC_EQ;
+ }
+ else if (BaseTypeSize == 1)
+ {
+ Symbol->Value = FUNC_EB;
+ }
+
+ PushSymbol(CodeBuffer, Symbol);
+
+ Symbol = ToSymbol(TokenArray[i], Error);
+ PushSymbol(CodeBuffer, Symbol);
+
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ FreeTemp(Temp);
+
+ ArrayElementCount++;
+ }
+ }
+
+ if (*Error != SCRIPT_ENGINE_ERROR_FREE)
+ {
+ break;
+ }
+
+ while ((ArrayElementCount * BaseTypeSize) < VariableType->Size)
+ {
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_MUL;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_NUM_TYPE;
+ Symbol->Value = BaseTypeSize;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_NUM_TYPE;
+ Symbol->Value = ArrayElementCount;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Temp = NewTemp(Error);
+ TempSymbol = ToSymbol(Temp, Error);
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_ADD;
+
+ PushSymbol(CodeBuffer, Symbol);
+ PushSymbol(CodeBuffer, IdSymbol);
+ PushSymbol(CodeBuffer, TempSymbol);
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+
+ if (BaseTypeSize == 4)
+ {
+ Symbol->Value = FUNC_ED;
+ }
+ else if (BaseTypeSize == 8)
+ {
+ Symbol->Value = FUNC_EQ;
+ }
+ else if (BaseTypeSize == 1)
+ {
+ Symbol->Value = FUNC_EB;
+ }
+
+ PushSymbol(CodeBuffer, Symbol);
+
+ Symbol = Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_NUM_TYPE;
+ Symbol->Value = 0;
+ PushSymbol(CodeBuffer, Symbol);
+
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ FreeTemp(Temp);
+
+ ArrayElementCount++;
+ }
+ }
else if (IsType2Func(Operator))
{
PushSymbol(CodeBuffer, OperatorSymbol);
@@ -1259,8 +1877,9 @@ CodeGen(PSCRIPT_ENGINE_TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, PSCRI
else if (IsType1Func(Operator))
{
PushSymbol(CodeBuffer, OperatorSymbol);
- Op0 = Pop(MatchedStack);
- Op0Symbol = ToSymbol(Op0, Error);
+ Op0 = Pop(MatchedStack);
+ VariableType = (VARIABLE_TYPE *)Op0->VariableType;
+ Op0Symbol = ToSymbol(Op0, Error);
Temp = NewTemp(Error);
Push(MatchedStack, Temp);
@@ -1530,68 +2149,465 @@ CodeGen(PSCRIPT_ENGINE_TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, PSCRI
}
else if (IsAssignmentOperator(Operator))
{
- PushSymbol(CodeBuffer, OperatorSymbol);
- Op0 = Pop(MatchedStack);
- Op0Symbol = ToSymbol(Op0, Error);
+ BOOL Handled = FALSE;
+ Op1 = TopIndexed(MatchedStack, 1);
- Op1 = Pop(MatchedStack);
- Op1Symbol = ToSymbol(Op1, Error);
-
- PushSymbol(CodeBuffer, Op0Symbol);
- PushSymbol(CodeBuffer, Op1Symbol);
- PushSymbol(CodeBuffer, Op1Symbol);
-
- //
- // Free the operand if it is a temp value
- //
- FreeTemp(Op0);
- if (*Error != SCRIPT_ENGINE_ERROR_FREE)
+ if (((VARIABLE_TYPE *)Op1->VariableType)->Kind == TY_PTR)
{
- break;
+ if (!strcmp(Operator->Value, "@ADD_ASSIGNMENT"))
+ {
+ PSYMBOL Symbol = NULL;
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_MUL;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_NUM_TYPE;
+ Symbol->Value = ((VARIABLE_TYPE *)Op1->VariableType)->Base->Size;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Op0 = Pop(MatchedStack);
+ Op0Symbol = ToSymbol(Op0, Error);
+ PushSymbol(CodeBuffer, Op0Symbol);
+
+ Temp = NewTemp(Error);
+ TempSymbol = ToSymbol(Temp, Error);
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_ADD;
+ PushSymbol(CodeBuffer, Symbol);
+
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ Op1 = Pop(MatchedStack);
+ Op1Symbol = ToSymbol(Op1, Error);
+ PushSymbol(CodeBuffer, Op1Symbol);
+ PushSymbol(CodeBuffer, Op1Symbol);
+
+ FreeTemp(Op0);
+ if (*Error != SCRIPT_ENGINE_ERROR_FREE)
+ {
+ break;
+ }
+ }
+ else if (!strcmp(Operator->Value, "@SUB_ASSIGNMENT"))
+ {
+ PSYMBOL Symbol = NULL;
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_MUL;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_NUM_TYPE;
+ Symbol->Value = ((VARIABLE_TYPE *)Op1->VariableType)->Base->Size;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Op0 = Pop(MatchedStack);
+ Op0Symbol = ToSymbol(Op0, Error);
+ PushSymbol(CodeBuffer, Op0Symbol);
+
+ Temp = NewTemp(Error);
+ TempSymbol = ToSymbol(Temp, Error);
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_SUB;
+ PushSymbol(CodeBuffer, Symbol);
+
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ Op1 = Pop(MatchedStack);
+ Op1Symbol = ToSymbol(Op1, Error);
+ PushSymbol(CodeBuffer, Op1Symbol);
+ PushSymbol(CodeBuffer, Op1Symbol);
+
+ FreeTemp(Op0);
+ if (*Error != SCRIPT_ENGINE_ERROR_FREE)
+ {
+ break;
+ }
+ }
+ else
+ {
+ *Error = SCRIPT_ENGINE_ERROR_SYNTAX;
+ Op0 = Pop(MatchedStack);
+ Op1 = Pop(MatchedStack);
+ }
+ Handled = TRUE;
+ }
+
+ if (!Handled)
+ {
+ PushSymbol(CodeBuffer, OperatorSymbol);
+ Op0 = Pop(MatchedStack);
+ Op0Symbol = ToSymbol(Op0, Error);
+
+ Op1 = Pop(MatchedStack);
+ Op1Symbol = ToSymbol(Op1, Error);
+
+ PushSymbol(CodeBuffer, Op0Symbol);
+ PushSymbol(CodeBuffer, Op1Symbol);
+ PushSymbol(CodeBuffer, Op1Symbol);
+
+ //
+ // Free the operand if it is a temp value
+ //
+ FreeTemp(Op0);
+ if (*Error != SCRIPT_ENGINE_ERROR_FREE)
+ {
+ break;
+ }
}
}
else if (IsTwoOperandOperator(Operator))
{
- PushSymbol(CodeBuffer, OperatorSymbol);
- Op0 = Pop(MatchedStack);
- Op0Symbol = ToSymbol(Op0, Error);
+ BOOL Handled = FALSE;
+ Op0 = TopIndexed(MatchedStack, 0);
+ Op1 = TopIndexed(MatchedStack, 1);
- Op1 = Pop(MatchedStack);
- Op1Symbol = ToSymbol(Op1, Error);
-
- Temp = NewTemp(Error);
- Push(MatchedStack, Temp);
- TempSymbol = ToSymbol(Temp, Error);
-
- PushSymbol(CodeBuffer, Op0Symbol);
- PushSymbol(CodeBuffer, Op1Symbol);
- PushSymbol(CodeBuffer, TempSymbol);
-
- //
- // Free the operand if it is a temp value
- //
- FreeTemp(Op0);
- FreeTemp(Op1);
- if (*Error != SCRIPT_ENGINE_ERROR_FREE)
+ if (!strcmp(Operator->Value, "@ADD") || !strcmp(Operator->Value, "@SUB"))
{
- break;
+ if (((VARIABLE_TYPE *)Op0->VariableType)->Kind == TY_PTR && ((VARIABLE_TYPE *)Op1->VariableType)->Kind == TY_PTR)
+ {
+ *Error = SCRIPT_ENGINE_ERROR_SYNTAX;
+ Op0 = Pop(MatchedStack);
+ Op1 = Pop(MatchedStack);
+ Handled = TRUE;
+ }
+ else if (((VARIABLE_TYPE *)Op0->VariableType)->Kind == TY_PTR && ((VARIABLE_TYPE *)Op1->VariableType)->Kind != TY_PTR)
+ {
+ if (!strcmp(Operator->Value, "@SUB"))
+ {
+ *Error = SCRIPT_ENGINE_ERROR_SYNTAX;
+ Op0 = Pop(MatchedStack);
+ Op1 = Pop(MatchedStack);
+ }
+ else
+ {
+ PSYMBOL Symbol = NULL;
+
+ Op0 = Pop(MatchedStack);
+ Op1 = Pop(MatchedStack);
+ Op0Symbol = ToSymbol(Op0, Error);
+ Op1Symbol = ToSymbol(Op1, Error);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_MUL;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_NUM_TYPE;
+ Symbol->Value = ((VARIABLE_TYPE *)Op0->VariableType)->Base->Size;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Op1Symbol = ToSymbol(Op1, Error);
+ PushSymbol(CodeBuffer, Op1Symbol);
+
+ Temp = NewTemp(Error);
+ TempSymbol = ToSymbol(Temp, Error);
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ PushSymbol(CodeBuffer, OperatorSymbol);
+ Op0Symbol = ToSymbol(Op0, Error);
+ PushSymbol(CodeBuffer, Op0Symbol);
+ PushSymbol(CodeBuffer, TempSymbol);
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ Push(MatchedStack, Temp);
+
+ //
+ // Free the operand if it is a temp value
+ //
+ FreeTemp(Op0);
+ FreeTemp(Op1);
+ if (*Error != SCRIPT_ENGINE_ERROR_FREE)
+ {
+ break;
+ }
+ }
+ Handled = TRUE;
+ }
+ else if (((VARIABLE_TYPE *)Op0->VariableType)->Kind != TY_PTR && ((VARIABLE_TYPE *)Op1->VariableType)->Kind == TY_PTR)
+ {
+ PSYMBOL Symbol = NULL;
+
+ Op0 = Pop(MatchedStack);
+ Op1 = Pop(MatchedStack);
+ Op0Symbol = ToSymbol(Op0, Error);
+ Op1Symbol = ToSymbol(Op1, Error);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_MUL;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_NUM_TYPE;
+ Symbol->Value = ((VARIABLE_TYPE *)Op1->VariableType)->Base->Size;
+ PushSymbol(CodeBuffer, Symbol);
+
+ PushSymbol(CodeBuffer, Op0Symbol);
+
+ Temp = NewTemp(Error);
+ TempSymbol = ToSymbol(Temp, Error);
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ PushSymbol(CodeBuffer, OperatorSymbol);
+ PushSymbol(CodeBuffer, TempSymbol);
+ PushSymbol(CodeBuffer, Op1Symbol);
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ Push(MatchedStack, Temp);
+
+ //
+ // Free the operand if it is a temp value
+ //
+ FreeTemp(Op0);
+ FreeTemp(Op1);
+ if (*Error != SCRIPT_ENGINE_ERROR_FREE)
+ {
+ break;
+ }
+
+ Handled = TRUE;
+ }
+
+ else if (((VARIABLE_TYPE *)Op0->VariableType)->Kind == TY_ARRAY && ((VARIABLE_TYPE *)Op1->VariableType)->Kind == TY_ARRAY)
+ {
+ *Error = SCRIPT_ENGINE_ERROR_SYNTAX;
+ Op0 = Pop(MatchedStack);
+ Op1 = Pop(MatchedStack);
+ Handled = TRUE;
+ }
+ else if (((VARIABLE_TYPE *)Op0->VariableType)->Kind == TY_ARRAY && ((VARIABLE_TYPE *)Op1->VariableType)->Kind != TY_ARRAY)
+ {
+ if (!strcmp(Operator->Value, "@SUB"))
+ {
+ *Error = SCRIPT_ENGINE_ERROR_SYNTAX;
+ Op0 = Pop(MatchedStack);
+ Op1 = Pop(MatchedStack);
+ }
+ else
+ {
+ PSYMBOL Symbol = NULL;
+ int VariableBaseSize = 0;
+ VariableType = (VARIABLE_TYPE *)Op0->VariableType;
+ while (VariableType->Base)
+ {
+ VariableType = VariableType->Base;
+ }
+ VariableBaseSize = VariableType->Size;
+
+ Op0 = Pop(MatchedStack);
+ Op1 = Pop(MatchedStack);
+ Op0Symbol = ToSymbol(Op0, Error);
+ Op1Symbol = ToSymbol(Op1, Error);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_MUL;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_NUM_TYPE;
+ Symbol->Value = VariableBaseSize;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Op1Symbol = ToSymbol(Op1, Error);
+ PushSymbol(CodeBuffer, Op1Symbol);
+
+ Temp = NewTemp(Error);
+ TempSymbol = ToSymbol(Temp, Error);
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ PushSymbol(CodeBuffer, OperatorSymbol);
+ Op0Symbol = ToSymbol(Op0, Error);
+ PushSymbol(CodeBuffer, Op0Symbol);
+ PushSymbol(CodeBuffer, TempSymbol);
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ Push(MatchedStack, Temp);
+
+ //
+ // Free the operand if it is a temp value
+ //
+ FreeTemp(Op0);
+ FreeTemp(Op1);
+ if (*Error != SCRIPT_ENGINE_ERROR_FREE)
+ {
+ break;
+ }
+ }
+ Handled = TRUE;
+ }
+ else if (((VARIABLE_TYPE *)Op0->VariableType)->Kind != TY_ARRAY && ((VARIABLE_TYPE *)Op1->VariableType)->Kind == TY_ARRAY)
+ {
+ PSYMBOL Symbol = NULL;
+ int VariableBaseSize = 0;
+ VariableType = (VARIABLE_TYPE *)Op1->VariableType;
+ while (VariableType->Base)
+ {
+ VariableType = VariableType->Base;
+ }
+ VariableBaseSize = VariableType->Size;
+
+ Op0 = Pop(MatchedStack);
+ Op1 = Pop(MatchedStack);
+ Op0Symbol = ToSymbol(Op0, Error);
+ Op1Symbol = ToSymbol(Op1, Error);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_MUL;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_NUM_TYPE;
+ Symbol->Value = VariableBaseSize;
+ PushSymbol(CodeBuffer, Symbol);
+
+ PushSymbol(CodeBuffer, Op0Symbol);
+
+ Temp = NewTemp(Error);
+ TempSymbol = ToSymbol(Temp, Error);
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ PushSymbol(CodeBuffer, OperatorSymbol);
+ PushSymbol(CodeBuffer, TempSymbol);
+ PushSymbol(CodeBuffer, Op1Symbol);
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ Push(MatchedStack, Temp);
+
+ //
+ // Free the operand if it is a temp value
+ //
+ FreeTemp(Op0);
+ FreeTemp(Op1);
+ if (*Error != SCRIPT_ENGINE_ERROR_FREE)
+ {
+ break;
+ }
+
+ Handled = TRUE;
+ }
+ }
+
+ if (!Handled)
+ {
+ PushSymbol(CodeBuffer, OperatorSymbol);
+ Op0 = Pop(MatchedStack);
+ Op0Symbol = ToSymbol(Op0, Error);
+
+ Op1 = Pop(MatchedStack);
+ Op1Symbol = ToSymbol(Op1, Error);
+
+ Temp = NewTemp(Error);
+ Temp->VariableType = (VARIABLE_TYPE *)GetCommonVariableType((VARIABLE_TYPE *)Op0->VariableType, (VARIABLE_TYPE *)Op1->VariableType);
+ Push(MatchedStack, Temp);
+ TempSymbol = ToSymbol(Temp, Error);
+
+ PushSymbol(CodeBuffer, Op0Symbol);
+ PushSymbol(CodeBuffer, Op1Symbol);
+ PushSymbol(CodeBuffer, TempSymbol);
+
+ //
+ // Free the operand if it is a temp value
+ //
+ FreeTemp(Op0);
+ FreeTemp(Op1);
+ if (*Error != SCRIPT_ENGINE_ERROR_FREE)
+ {
+ break;
+ }
}
}
else if (IsOneOperandOperator(Operator))
{
- PushSymbol(CodeBuffer, OperatorSymbol);
- Op0 = Pop(MatchedStack);
- Op0Symbol = ToSymbol(Op0, Error);
+ BOOL Handled = FALSE;
+ Op0 = Top(MatchedStack);
- PushSymbol(CodeBuffer, Op0Symbol);
-
- //
- // Free the operand if it is a temp value
- //
- FreeTemp(Op0);
- if (*Error != SCRIPT_ENGINE_ERROR_FREE)
+ if (((VARIABLE_TYPE *)Op0->VariableType)->Kind == TY_PTR)
{
- break;
+ if (!strcmp(Operator->Value, "@INC"))
+ {
+ PSYMBOL Symbol = NULL;
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_ADD;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_NUM_TYPE;
+ Symbol->Value = ((VARIABLE_TYPE *)Op0->VariableType)->Base->Size;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Op0 = Pop(MatchedStack);
+ Op0Symbol = ToSymbol(Op0, Error);
+ PushSymbol(CodeBuffer, Op0Symbol);
+ PushSymbol(CodeBuffer, Op0Symbol);
+
+ FreeTemp(Op0);
+ if (*Error != SCRIPT_ENGINE_ERROR_FREE)
+ {
+ break;
+ }
+ Handled = TRUE;
+ }
+
+ else if (!strcmp(Operator->Value, "@DEC"))
+ {
+ PSYMBOL Symbol = NULL;
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
+ Symbol->Value = FUNC_SUB;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Symbol = NewSymbol();
+ Symbol->Type = SYMBOL_NUM_TYPE;
+ Symbol->Value = ((VARIABLE_TYPE *)Op0->VariableType)->Base->Size;
+ PushSymbol(CodeBuffer, Symbol);
+
+ Op0 = Pop(MatchedStack);
+ Op0Symbol = ToSymbol(Op0, Error);
+ PushSymbol(CodeBuffer, Op0Symbol);
+ PushSymbol(CodeBuffer, Op0Symbol);
+
+ FreeTemp(Op0);
+ if (*Error != SCRIPT_ENGINE_ERROR_FREE)
+ {
+ break;
+ }
+ Handled = TRUE;
+ }
+ }
+
+ if (!Handled)
+ {
+ PushSymbol(CodeBuffer, OperatorSymbol);
+ Op0 = Pop(MatchedStack);
+ Op0Symbol = ToSymbol(Op0, Error);
+
+ PushSymbol(CodeBuffer, Op0Symbol);
+
+ //
+ // Free the operand if it is a temp value
+ //
+ FreeTemp(Op0);
+ if (*Error != SCRIPT_ENGINE_ERROR_FREE)
+ {
+ break;
+ }
}
}
else if (!strcmp(Operator->Value, "@VARGSTART"))
@@ -2514,7 +3530,7 @@ ScriptEngineBooleanExpresssionParse(
int InputPointer = 0;
int RhsSize = 0;
unsigned int InputIdxTemp;
- char Ctemp;
+ CHAR CTemp;
while (1)
{
@@ -2559,13 +3575,13 @@ ScriptEngineBooleanExpresssionParse(
Push(Stack, State);
InputIdxTemp = InputIdx;
- Ctemp = *c;
+ CTemp = *c;
CurrentIn = Scan(str, c);
if (InputIdx - 1 > BooleanExpressionSize)
{
InputIdx = InputIdxTemp;
- *c = Ctemp;
+ *c = CTemp;
RemoveToken(&CurrentIn);
@@ -2606,7 +3622,7 @@ ScriptEngineBooleanExpresssionParse(
}
else
{
- CodeGen(MatchedStack, CodeBuffer, SemanticRule, Error);
+ CodeGen(MatchedStack, CodeBuffer, SemanticRule, Error, &str);
if (*Error != SCRIPT_ENGINE_ERROR_FREE)
{
break;
@@ -2807,9 +3823,20 @@ ToSymbol(PSCRIPT_ENGINE_TOKEN Token, PSCRIPT_ENGINE_ERROR_TYPE Error)
return Symbol;
case LOCAL_ID:
+ {
Symbol->Value = GetLocalIdentifierVal(Token);
- SetType(&Symbol->Type, SYMBOL_LOCAL_ID_TYPE);
+
+ if (((VARIABLE_TYPE *)Token->VariableType)->Kind == TY_ARRAY)
+ {
+ SetType(&Symbol->Type, SYMBOL_REFERENCE_LOCAL_ID_TYPE);
+ }
+ else
+ {
+ SetType(&Symbol->Type, SYMBOL_LOCAL_ID_TYPE);
+ }
+
return Symbol;
+ }
case DECIMAL:
Symbol->Value = DecimalToInt(Token->Value);
@@ -2847,8 +3874,18 @@ ToSymbol(PSCRIPT_ENGINE_TOKEN Token, PSCRIPT_ENGINE_ERROR_TYPE Error)
return Symbol;
case TEMP:
+
Symbol->Value = DecimalToInt(Token->Value);
- SetType(&Symbol->Type, SYMBOL_TEMP_TYPE);
+
+ if (((VARIABLE_TYPE *)Token->VariableType)->Kind == TY_ARRAY)
+ {
+ SetType(&Symbol->Type, SYMBOL_REFERENCE_TEMP_TYPE);
+ }
+ else
+ {
+ SetType(&Symbol->Type, SYMBOL_TEMP_TYPE);
+ }
+
return Symbol;
case STRING:
@@ -2864,6 +3901,11 @@ ToSymbol(PSCRIPT_ENGINE_TOKEN Token, PSCRIPT_ENGINE_ERROR_TYPE Error)
SetType(&Symbol->Type, SYMBOL_FUNCTION_PARAMETER_ID_TYPE);
return Symbol;
+ case DEFERENCE_TEMP:
+ Symbol->Value = DecimalToInt(Token->Value);
+ SetType(&Symbol->Type, SYMBOL_DEREFERENCE_TEMP_TYPE);
+ return Symbol;
+
default:
*Error = SCRIPT_ENGINE_ERROR_UNRESOLVED_VARIABLE;
Symbol->Type = INVALID;
@@ -3050,8 +4092,8 @@ PrintSymbolBuffer(const PVOID SymbolBuffer)
PrintSymbol((PVOID)Symbol);
if (Symbol->Type == SYMBOL_STRING_TYPE || Symbol->Type == SYMBOL_WSTRING_TYPE)
{
- int temp = GetSymbolHeapSize(Symbol);
- i += temp;
+ INT Temp = GetSymbolHeapSize(Symbol);
+ i += Temp;
}
else
{
@@ -3346,7 +4388,7 @@ GetLocalIdentifierVal(PSCRIPT_ENGINE_TOKEN Token)
CurrentToken = *(((PSCRIPT_ENGINE_TOKEN_LIST)CurrentUserDefinedFunction->IdTable)->Head + i);
if (!strcmp(Token->Value, CurrentToken->Value))
{
- return (int)i;
+ return (int)CurrentToken->VariableMemoryIdx;
}
}
return -1;
@@ -3366,19 +4408,100 @@ NewGlobalIdentifier(PSCRIPT_ENGINE_TOKEN Token)
return GlobalIdTable->Pointer - 1;
}
+/**
+ * @brief
+ *
+ * @param Token
+ */
+VOID
+SetGlobalIdentifierVariableType(PSCRIPT_ENGINE_TOKEN Token, VARIABLE_TYPE * VariableType)
+{
+ PSCRIPT_ENGINE_TOKEN CurrentToken;
+ for (uintptr_t i = 0; i < GlobalIdTable->Pointer; i++)
+ {
+ CurrentToken = *(GlobalIdTable->Head + i);
+ if (!strcmp(Token->Value, CurrentToken->Value))
+ {
+ CurrentToken->VariableType = (VARIABLE_TYPE *)VariableType;
+ }
+ }
+}
+
+/**
+ * @brief
+ *
+ * @param Token
+ */
+VARIABLE_TYPE *
+GetGlobalIdentifierVariableType(PSCRIPT_ENGINE_TOKEN Token)
+{
+ PSCRIPT_ENGINE_TOKEN CurrentToken;
+ for (uintptr_t i = 0; i < GlobalIdTable->Pointer; i++)
+ {
+ CurrentToken = *(GlobalIdTable->Head + i);
+ if (!strcmp(Token->Value, CurrentToken->Value))
+ {
+ return CurrentToken->VariableType;
+ }
+ }
+ return 0;
+}
+
/**
* @brief Allocates a new local variable and returns the integer assigned to it
*
* @param Token
* @return int
*/
-int
-NewLocalIdentifier(PSCRIPT_ENGINE_TOKEN Token)
+unsigned long long
+NewLocalIdentifier(PSCRIPT_ENGINE_TOKEN Token, unsigned int VariableSize)
{
- PSCRIPT_ENGINE_TOKEN CopiedToken = CopyToken(Token);
+ PSCRIPT_ENGINE_TOKEN CopiedToken = CopyToken(Token);
+ unsigned int VariableNumber = ((VariableSize + 8 - 1) & ~(8 - 1)) / 8;
+ CopiedToken->VariableMemoryIdx = CurrentUserDefinedFunction->LocalVariableNumber;
+ CurrentUserDefinedFunction->LocalVariableNumber += VariableNumber;
Push(((PSCRIPT_ENGINE_TOKEN_LIST)CurrentUserDefinedFunction->IdTable), CopiedToken);
- CurrentUserDefinedFunction->LocalVariableNumber++;
- return ((PSCRIPT_ENGINE_TOKEN_LIST)CurrentUserDefinedFunction->IdTable)->Pointer - 1;
+ return CopiedToken->VariableMemoryIdx;
+}
+
+/**
+ * @brief
+ *
+ * @param Token
+ */
+VOID
+SetLocalIdentifierVariableType(PSCRIPT_ENGINE_TOKEN Token, VARIABLE_TYPE * VariableType)
+{
+ PSCRIPT_ENGINE_TOKEN CurrentToken;
+ for (uintptr_t i = 0; i < ((PSCRIPT_ENGINE_TOKEN_LIST)CurrentUserDefinedFunction->IdTable)->Pointer; i++)
+ {
+ CurrentToken = *(((PSCRIPT_ENGINE_TOKEN_LIST)CurrentUserDefinedFunction->IdTable)->Head + i);
+ if (!strcmp(Token->Value, CurrentToken->Value))
+ {
+ CurrentToken->VariableType = VariableType;
+ }
+ }
+}
+
+/**
+ * @brief
+ *
+ * @param Token
+ * @return VARIABLE_TYPE*
+ */
+VARIABLE_TYPE *
+GetLocalIdentifierVariableType(PSCRIPT_ENGINE_TOKEN Token)
+{
+ PSCRIPT_ENGINE_TOKEN CurrentToken;
+ for (uintptr_t i = 0; i < ((PSCRIPT_ENGINE_TOKEN_LIST)CurrentUserDefinedFunction->IdTable)->Pointer; i++)
+ {
+ CurrentToken = *(((PSCRIPT_ENGINE_TOKEN_LIST)CurrentUserDefinedFunction->IdTable)->Head + i);
+ if (!strcmp(Token->Value, CurrentToken->Value))
+ {
+ return CurrentToken->VariableType;
+ }
+ }
+ return 0;
}
/**
@@ -3420,7 +4543,7 @@ GetFunctionParameterIdentifier(PSCRIPT_ENGINE_TOKEN Token)
* @brief
*
* @param Token
- * @return bool
+ * @return PUSER_DEFINED_FUNCTION_NODE
*/
PUSER_DEFINED_FUNCTION_NODE
GetUserDefinedFunctionNode(PSCRIPT_ENGINE_TOKEN Token)
diff --git a/hyperdbg/script-engine/code/script_include.c b/hyperdbg/script-engine/code/script_include.c
new file mode 100644
index 00000000..f24d57ef
--- /dev/null
+++ b/hyperdbg/script-engine/code/script_include.c
@@ -0,0 +1,199 @@
+/**
+ * @file script_include.c
+ * @author M.H. Gholamrezaei (mh@hyperdbg.org)
+ *
+ * @brief Include file path resolution and parsing routines
+ * @details
+ * @version 0.1
+ * @date 2020-10-22
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+#include "script_include.h"
+
+/**
+ * @brief Trims leading whitespace from a string in-place
+ *
+ * @param Str the string to left-trim
+ * @return VOID
+ */
+static VOID
+Ltrim(char * Str)
+{
+ char * P = Str;
+
+ while (*P && isspace((unsigned char)*P))
+ P++;
+
+ if (P != Str)
+ memmove(Str, P, strlen(P) + 1);
+}
+
+/**
+ * @brief Trims trailing whitespace from a string in-place
+ *
+ * @param Str the string to right-trim
+ * @return VOID
+ */
+static VOID
+Rtrim(char * Str)
+{
+ char * End = Str + strlen(Str);
+
+ while (End > Str && isspace((unsigned char)End[-1]))
+ End--;
+
+ *End = '\0';
+}
+
+/**
+ * @brief Trims leading and trailing whitespace from a string in-place
+ *
+ * @param Str the string to trim
+ * @return VOID
+ */
+static VOID
+Trim(char * Str)
+{
+ Ltrim(Str);
+ Rtrim(Str);
+}
+
+/**
+ * @brief Inserts a string into another string at a given index
+ *
+ * @param Str the original string (will be reallocated)
+ * @param InputIdx the index at which to insert
+ * @param Buf the string to insert
+ * @return char * the new string, or the original on allocation failure
+ */
+char *
+InsertStrNew(char * Str, int InputIdx, const char * Buf)
+{
+ SIZE_T LenStr = strlen(Str);
+ SIZE_T LenBuf = strlen(Buf);
+
+ if (InputIdx < 0 || (SIZE_T)InputIdx > LenStr)
+ return Str;
+
+ char * NewStr = (char *)realloc(Str, LenStr + LenBuf + 1);
+ if (!NewStr)
+ return Str;
+
+ memmove(NewStr + InputIdx + LenBuf,
+ NewStr + InputIdx,
+ LenStr - InputIdx + 1);
+
+ memcpy(NewStr + InputIdx, Buf, LenBuf);
+
+ return NewStr;
+}
+
+/**
+ * @brief Checks whether a file path is absolute
+ *
+ * @param Path the file path to check
+ * @return BOOLEAN TRUE if the path is absolute, FALSE otherwise
+ */
+BOOLEAN
+IsAbsolutePath(const char * Path)
+{
+ if (!Path || !Path[0])
+ return FALSE;
+
+ if (strlen(Path) >= 3 &&
+ ((Path[1] == ':' && (Path[2] == '\\' || Path[2] == '/'))))
+ return TRUE;
+
+ return FALSE;
+}
+
+/**
+ * @brief Resolves an include file path to a full absolute path
+ *
+ * @param IncludeFilePath the include file path (relative or absolute)
+ * @param OutPath the buffer to receive the resolved path
+ * @return VOID
+ */
+VOID
+ResolveIncludePath(const char * IncludeFilePath, char * OutPath)
+{
+ if (IsAbsolutePath(IncludeFilePath))
+ {
+ strncpy(OutPath, IncludeFilePath, MAX_PATH_LEN - 1);
+ OutPath[MAX_PATH_LEN - 1] = '\0';
+ return;
+ }
+
+ CHAR ExeDir[MAX_PATH_LEN];
+ GetModuleFileNameA(NULL, ExeDir, MAX_PATH_LEN);
+
+ char * P = strrchr(ExeDir, '\\');
+ if (P)
+ *P = '\0';
+
+ snprintf(
+ OutPath,
+ MAX_PATH_LEN,
+ "%s\\%s",
+ ExeDir,
+ IncludeFilePath);
+}
+
+/**
+ * @brief Checks whether a file exists at the given path
+ *
+ * @param Path the file path to check
+ * @return BOOLEAN TRUE if the file exists, FALSE otherwise
+ */
+BOOLEAN
+FileExists(const char * Path)
+{
+ DWORD Attr = GetFileAttributesA(Path);
+
+ if (Attr == INVALID_FILE_ATTRIBUTES)
+ return FALSE;
+
+ if (Attr & FILE_ATTRIBUTE_DIRECTORY)
+ return FALSE;
+
+ return TRUE;
+}
+
+/**
+ * @brief Reads and parses an include file into a buffer
+ *
+ * @param IncludeFile the path to the include file
+ * @param Buffer pointer to receive the allocated file content buffer
+ * @return BOOLEAN TRUE if the file was parsed successfully, FALSE otherwise
+ */
+BOOLEAN
+ParseIncludeFile(char * IncludeFile, char ** Buffer)
+{
+ FILE * Fp = fopen(IncludeFile, "r");
+ fseek(Fp, 0, SEEK_END);
+ LONG Size = ftell(Fp);
+ rewind(Fp);
+ *Buffer = calloc(Size + 1, 1);
+ fread(*Buffer, 1, Size, Fp);
+ (*Buffer)[Size] = '\0';
+ Trim(*Buffer);
+ SIZE_T Len = strlen(*Buffer);
+ if ((*Buffer)[0] == '?' &&
+ (*Buffer)[1] == ' ' &&
+ (*Buffer)[2] == '{' &&
+ (*Buffer)[Len - 1] == '}')
+ {
+ memmove(
+ *Buffer,
+ *Buffer + 3,
+ Len - 3 + 1);
+
+ (*Buffer)[strlen(*Buffer) - 1] = '\0';
+
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/hyperdbg/script-engine/code/type.c b/hyperdbg/script-engine/code/type.c
index f0e7cee2..b0719061 100644
--- a/hyperdbg/script-engine/code/type.c
+++ b/hyperdbg/script-engine/code/type.c
@@ -1,3 +1,15 @@
+/**
+ * @file type.c
+ * @author M.H. Gholamrezaei (mh@hyperdbg.org)
+ *
+ * @brief Routines for handling variable types
+ * @details
+ * @version 0.1
+ * @date 2020-10-22
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
#include "pch.h"
VARIABLE_TYPE * VARIABLE_TYPE_UNKNOWN = &(VARIABLE_TYPE) {TY_UNKNOWN};
@@ -20,9 +32,10 @@ VARIABLE_TYPE * VARIABLE_TYPE_DOUBLE = &(VARIABLE_TYPE) {TY_DOUBLE, 8, 8};
VARIABLE_TYPE * VARIABLE_TYPE_LDOUBLE = &(VARIABLE_TYPE) {TY_LDOUBLE, 16, 16};
/**
- * @brief Return a variable type
+ * @brief Return a variable type based on the token stack
*
- * @param str
+ * @param PtokenStack the token stack containing type tokens
+ * @return VARIABLE_TYPE * pointer to the resolved variable type
*/
VARIABLE_TYPE *
HandleType(PSCRIPT_ENGINE_TOKEN_LIST PtokenStack)
@@ -163,3 +176,26 @@ HandleType(PSCRIPT_ENGINE_TOKEN_LIST PtokenStack)
}
return Result;
}
+
+/**
+ * @brief Returns the common variable type between two types
+ *
+ * @param Ty1 the first variable type
+ * @param Ty2 the second variable type
+ * @return VARIABLE_TYPE * pointer to the common variable type
+ */
+VARIABLE_TYPE *
+GetCommonVariableType(VARIABLE_TYPE * Ty1, VARIABLE_TYPE * Ty2)
+{
+ // if (Ty1->Kind == TY_ARRAY)
+ //{
+ // return Ty1;
+ // }
+
+ // if (Ty2->Kind == TY_ARRAY)
+ //{
+ // return Ty2;
+ // }
+
+ return VARIABLE_TYPE_LONG;
+}
diff --git a/hyperdbg/script-engine/header/common.h b/hyperdbg/script-engine/header/common.h
index c67589f7..c3431088 100644
--- a/hyperdbg/script-engine/header/common.h
+++ b/hyperdbg/script-engine/header/common.h
@@ -60,6 +60,7 @@ typedef enum _SCRIPT_ENGINE_TOKEN_TYPE
FUNCTION_ID,
FUNCTION_PARAMETER_ID,
SCRIPT_VARIABLE_TYPE,
+ DEFERENCE_TEMP,
UNKNOWN
} SCRIPT_ENGINE_TOKEN_TYPE;
@@ -72,7 +73,8 @@ typedef struct _SCRIPT_ENGINE_TOKEN
char * Value;
unsigned int Len;
unsigned int MaxLen;
- unsigned long long VariableType;
+ VARIABLE_TYPE * VariableType;
+ unsigned long long VariableMemoryIdx;
} SCRIPT_ENGINE_TOKEN, *PSCRIPT_ENGINE_TOKEN;
/**
@@ -94,16 +96,16 @@ NewUnknownToken(void);
PSCRIPT_ENGINE_TOKEN
NewToken(SCRIPT_ENGINE_TOKEN_TYPE Type, char * Value);
-void
+VOID
RemoveToken(PSCRIPT_ENGINE_TOKEN * Token);
-void
+VOID
PrintToken(PSCRIPT_ENGINE_TOKEN Token);
-void
-AppendByte(PSCRIPT_ENGINE_TOKEN Token, char c);
+VOID
+AppendByte(PSCRIPT_ENGINE_TOKEN Token, CHAR c);
-void
+VOID
AppendWchar(PSCRIPT_ENGINE_TOKEN Token, wchar_t c);
PSCRIPT_ENGINE_TOKEN
@@ -112,8 +114,14 @@ CopyToken(PSCRIPT_ENGINE_TOKEN Token);
PSCRIPT_ENGINE_TOKEN
NewTemp(PSCRIPT_ENGINE_ERROR_TYPE);
-void
- FreeTemp(PSCRIPT_ENGINE_ERROR_TYPE);
+VOID
+FreeTemp(PSCRIPT_ENGINE_TOKEN Temp);
+
+VARIABLE_TYPE *
+HandleType(PSCRIPT_ENGINE_TOKEN_LIST PtokenStack);
+
+VARIABLE_TYPE *
+GetCommonVariableType(VARIABLE_TYPE * Ty1, VARIABLE_TYPE * Ty2);
////////////////////////////////////////////////////
// SCRIPT_ENGINE_TOKEN_LIST related functions //
@@ -122,10 +130,10 @@ void
PSCRIPT_ENGINE_TOKEN_LIST
NewTokenList(void);
-void
+VOID
RemoveTokenList(PSCRIPT_ENGINE_TOKEN_LIST TokenList);
-void
+VOID
PrintTokenList(PSCRIPT_ENGINE_TOKEN_LIST TokenList);
PSCRIPT_ENGINE_TOKEN_LIST
@@ -137,6 +145,9 @@ Pop(PSCRIPT_ENGINE_TOKEN_LIST TokenList);
PSCRIPT_ENGINE_TOKEN
Top(PSCRIPT_ENGINE_TOKEN_LIST TokenList);
+PSCRIPT_ENGINE_TOKEN
+TopIndexed(PSCRIPT_ENGINE_TOKEN_LIST TokenList, int Index);
+
char
IsNoneTerminal(PSCRIPT_ENGINE_TOKEN Token);
@@ -180,7 +191,7 @@ IsBinary(char c);
char
IsOctal(char c);
-void
+VOID
SetType(unsigned long long * Val, unsigned char Type);
unsigned long long
@@ -198,7 +209,7 @@ OctalToInt(char * str);
unsigned long long
BinaryToInt(char * str);
-void
+VOID
RotateLeftStringOnce(char * str);
////////////////////////////////////////////////////
@@ -260,20 +271,29 @@ char
IsOneOperandOperator(PSCRIPT_ENGINE_TOKEN Operator);
/**
- *
+ * @brief User-defined function linked list node
*/
-typedef struct USER_DEFINED_FUNCTION_NODE
+typedef struct _USER_DEFINED_FUNCTION_NODE
{
- char * Name;
- long long unsigned Address;
- long long unsigned VariableType;
- long long unsigned ParameterNumber;
- long long unsigned MaxTempNumber;
- long long unsigned LocalVariableNumber;
- long long unsigned IdTable;
- long long unsigned FunctionParameterIdTable;
- char * TempMap;
- struct USER_DEFINED_FUNCTION_NODE * NextNode;
+ char * Name;
+ long long unsigned Address;
+ long long unsigned VariableType;
+ long long unsigned ParameterNumber;
+ long long unsigned MaxTempNumber;
+ long long unsigned LocalVariableNumber;
+ long long unsigned IdTable;
+ long long unsigned FunctionParameterIdTable;
+ char * TempMap;
+ struct _USER_DEFINED_FUNCTION_NODE * NextNode;
} USER_DEFINED_FUNCTION_NODE, *PUSER_DEFINED_FUNCTION_NODE;
+/**
+ * @brief Include file linked list node
+ */
+typedef struct _INCLUDE_NODE
+{
+ char * FilePath;
+ struct _INCLUDE_NODE * NextNode;
+} INCLUDE_NODE, *PINCLUDE_NODE;
+
#endif // !COMMON_H
diff --git a/hyperdbg/script-engine/header/globals.h b/hyperdbg/script-engine/header/globals.h
index 7de42324..d8855032 100644
--- a/hyperdbg/script-engine/header/globals.h
+++ b/hyperdbg/script-engine/header/globals.h
@@ -12,7 +12,7 @@
#pragma once
#ifndef GLOBALS_H
-# define GLOABLS_H
+# define GLOBALS_H
# define MAX_TEMP_COUNT 128
#endif // !GLOBALS_H
@@ -21,16 +21,16 @@
* @brief Instance information of the current hwdbg debuggee
*
*/
-HWDBG_INSTANCE_INFORMATION g_HwdbgInstanceInfo;
+extern HWDBG_INSTANCE_INFORMATION g_HwdbgInstanceInfo;
/**
* @brief Shows whether the instance info is valid (received) or not
*
*/
-BOOLEAN g_HwdbgInstanceInfoIsValid;
+extern BOOLEAN g_HwdbgInstanceInfoIsValid;
/**
* @brief Message handler function
*
*/
-PVOID g_MessageHandler;
+extern PVOID g_MessageHandler;
diff --git a/hyperdbg/script-engine/header/parse-table.h b/hyperdbg/script-engine/header/parse-table.h
index 4d642a95..eb7a0242 100644
--- a/hyperdbg/script-engine/header/parse-table.h
+++ b/hyperdbg/script-engine/header/parse-table.h
@@ -1,24 +1,24 @@
#pragma once
#ifndef PARSE_TABLE_H
#define PARSE_TABLE_H
-#define RULES_COUNT 246
-#define TERMINAL_COUNT 119
-#define NONETERMINAL_COUNT 49
+#define RULES_COUNT 284
+#define TERMINAL_COUNT 128
+#define NONETERMINAL_COUNT 63
#define START_VARIABLE "S"
#define MAX_RHS_LEN 15
-#define KEYWORD_LIST_LENGTH 109
-#define OPERATORS_ONE_OPERAND_LIST_LENGTH 4
+#define KEYWORD_LIST_LENGTH 121
+#define OPERATORS_ONE_OPERAND_LIST_LENGTH 3
#define OPERATORS_TWO_OPERAND_LIST_LENGTH 16
#define REGISTER_MAP_LIST_LENGTH 120
#define PSEUDO_REGISTER_MAP_LIST_LENGTH 16
#define SCRIPT_VARIABLE_TYPE_LIST_LENGTH 10
#define ASSIGNMENT_OPERATOR_LIST_LENGTH 10
-#define SEMANTIC_RULES_MAP_LIST_LENGTH 155
+#define SEMANTIC_RULES_MAP_LIST_LENGTH 166
#define THREEOPFUNC1_LENGTH 1
#define THREEOPFUNC2_LENGTH 3
#define TWOOPFUNC1_LENGTH 8
#define TWOOPFUNC2_LENGTH 2
-#define ONEOPFUNC1_LENGTH 25
+#define ONEOPFUNC1_LENGTH 26
#define ONEOPFUNC2_LENGTH 10
#define ONEOPFUNC3_LENGTH 1
#define TWOOPFUNC3_LENGTH 1
@@ -27,7 +27,7 @@
#define ONEOPFUNC4_LENGTH 1
#define TWOOPFUNC4_LENGTH 1
#define ZEROOPFUNC1_LENGTH 7
-#define ZEROOPFUNC2_LENGTH 2
+#define ZEROOPFUNC2_LENGTH 7
#define VARARGFUNC1_LENGTH 1
extern const struct _SCRIPT_ENGINE_TOKEN Lhs[RULES_COUNT];
extern const struct _SCRIPT_ENGINE_TOKEN Rhs[RULES_COUNT][MAX_RHS_LEN];
@@ -60,11 +60,11 @@ extern const SYMBOL_MAP PseudoRegisterMapList[];
extern const char* ScriptVariableTypeList[];
-#define LALR_RULES_COUNT 103
-#define LALR_TERMINAL_COUNT 76
-#define LALR_NONTERMINAL_COUNT 22
+#define LALR_RULES_COUNT 117
+#define LALR_TERMINAL_COUNT 86
+#define LALR_NONTERMINAL_COUNT 26
#define LALR_MAX_RHS_LEN 9
-#define LALR_STATE_COUNT 298
+#define LALR_STATE_COUNT 332
extern const struct _SCRIPT_ENGINE_TOKEN LalrLhs[RULES_COUNT];
extern const struct _SCRIPT_ENGINE_TOKEN LalrRhs[RULES_COUNT][MAX_RHS_LEN];
extern const unsigned int LalrRhsSize[RULES_COUNT];
diff --git a/hyperdbg/script-engine/header/pch.h b/hyperdbg/script-engine/header/pch.h
index bb2af1da..e51ebe45 100644
--- a/hyperdbg/script-engine/header/pch.h
+++ b/hyperdbg/script-engine/header/pch.h
@@ -19,7 +19,7 @@
//
// Environment headers
//
-#include "platform/user/header/Environment.h"
+#include "platform/general/header/Environment.h"
//
// Exclude rarely-used stuff from Windows headers
@@ -29,7 +29,13 @@
//
// Windows Header Files
//
-#include
+#ifdef _WIN32
+# include
+#endif
+
+#include
+#include
+
#include