diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 65812eea..7d2e8556 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -7,6 +7,13 @@ assignees: ''
---
+**Note**
+We're fortunate to have a community of highly skilled system engineers and reverse engineers contributing to HyperDbg. However, as an open-source, community-driven debugger, our resources and developer time are limited.
+
+Since most HyperDbg users are professional programmers, we encourage you to contribute by submitting pull requests (PRs) whenever possible. While we will address issues created by users, we greatly appreciate your efforts to resolve issues independently and submit PRs. If you're unable to create a PR, please feel free to create an issue, and we'll do our best to address it.
+
+Thank you for reporting issues and for your contributions! ❤️
+
**Describe the bug**
A clear and concise description of what the bug is.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index bbcbbe7d..e7f6d791 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -7,6 +7,13 @@ assignees: ''
---
+**Note**
+We're fortunate to have a community of highly skilled system engineers and reverse engineers contributing to HyperDbg. However, as an open-source, community-driven debugger, our resources and developer time are limited.
+
+Since most HyperDbg users are professional programmers, we encourage you to contribute by submitting pull requests (PRs) whenever possible. While we will address requests for new features created by users, we greatly appreciate your efforts to add them independently and submit PRs. If you're unable to create a PR, please feel free to create your request, and we'll do our best to address it. You can also create issues or discussions to discuss the possible features that you want to add to HyperDbg.
+
+Thank you for requesting new features and for your contributions! ❤️
+
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
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 dc844290..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,12 +78,12 @@ 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}}
- name: Upload build directory
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4.4.0
with:
name: build_files_${{matrix.BUILD_CONFIGURATION}}
path: ${{ env.BUILD_BIN_DIR }}
@@ -86,12 +91,12 @@ jobs:
deploy-release:
name: Deploy release
needs: win-amd64-build
- runs-on: windows-2019
+ runs-on: windows-2022
if: startsWith(github.ref, 'refs/tags/')
steps:
- name: Download build files from "build" job
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4.1.7
with:
name: build_files_release
path: ${{ env.BUILD_BIN_DIR }}
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/.gitignore b/.gitignore
index c38435e2..0c2f68c0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -377,16 +377,26 @@ MigrationBackup/
!/hyperdbg/libraries/DIA/x84/*
!/hyperdbg/libraries/DIA/x64/*
-# KdSerial Libraries
+# kdserial libraries
!/hyperdbg/libraries/kdserial/*
!/hyperdbg/libraries/kdserial/x86/*
!/hyperdbg/libraries/kdserial/x64/*
!/hyperdbg/libraries/kdserial/arm/*
!/hyperdbg/libraries/kdserial/arm64/*
+# Ignore keystone libraries
+!/hyperdbg/libraries/keystone/release/
+!/hyperdbg/libraries/keystone/debug/
+!/hyperdbg/libraries/keystone/release/*
+!/hyperdbg/libraries/keystone/debug/*
# Code review tools
compile_commands.json
StructLayoutSettings.json
-*.metaproj
\ No newline at end of file
+*.metaproj
+
+#ignore clion config files
+.idea
+cmake-build-debug
+/hyperdbg/hyperhv/zydis/
diff --git a/.gitmodules b/.gitmodules
index c15beeab..bc4340e1 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,12 +1,12 @@
+[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/phnt"]
- path = hyperdbg/dependencies/phnt
- url = https://github.com/HyperDbg/phnt.git
-[submodule "hyperdbg/script-engine/modules/script-engine-test"]
- path = hyperdbg/script-engine/modules/script-engine-test
- url = https://github.com/HyperDbg/script-engine-test
[submodule "hyperdbg/dependencies/pdbex"]
path = hyperdbg/dependencies/pdbex
url = https://github.com/HyperDbg/pdbex.git
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 21c6c2ec..f4f7ddac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,412 @@ 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.
+
+### Added
+- **microsleep(microseconds)** function in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/timings/microsleep))
+- **rdtsc()** and **rdtscp()** functions in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/timings/rdtsc))([link](https://docs.hyperdbg.org/commands/scripting-language/functions/timings/rdtscp))
+- Added functions to get system-call number from the running system ([link](https://github.com/HyperDbg/HyperDbg/commit/5d33cb7395c57fd6af170bfed90376598347679c))
+- Added the support for the '.start' command in the VMI mode ([link](https://docs.hyperdbg.org/commands/meta-commands/.start))
+- Added a new mechanism for finding the system-call number based on the running system ([link](https://github.com/HyperDbg/HyperDbg/commit/5d33cb7395c57fd6af170bfed90376598347679c))
+- Added hyperevade transparency project ([link](https://url.hyperdbg.org/hyperevade))
+- Added support to the '.attach' and '.detach' in the debugger mode ([link](https://docs.hyperdbg.org/commands/meta-commands/.attach))([link](https://docs.hyperdbg.org/commands/meta-commands/.detach))
+- Added support to the '.start' command in the VMI mode for the user debugger ([link](https://docs.hyperdbg.org/commands/meta-commands/.start))
+- Added support to setting the breakpoint using the 'bp' command in the VMI mode ([link](https://docs.hyperdbg.org/commands/debugging-commands/bp))
+- Added EPT page table support for MMIO addresses above 512 GB
+
+### Changed
+- Redesigned the '!mode' extension command without extra EPTP ([link](https://github.com/HyperDbg/HyperDbg/commit/a93b78dfadbf94d2d69f24413170c983ec379f48))
+- The user mode debugger now uses MBEC for preventing user-mode code execution ([link](https://github.com/HyperDbg/HyperDbg/commit/6893c1b19f1edaf57d0074bd60abcd518bf77338))
+- Apply transparent-mode based on dynamic system-calls ([link](https://github.com/HyperDbg/HyperDbg/commit/1eb960607331fc0c2622804d7aff65702c155649))
+- Breakpoint initialization is changed from kernel debugger to the regular debugger ([link](https://github.com/HyperDbg/HyperDbg/commit/e5326f895dcddb1adbc873a9fecede7af7eb7651))
+- Fixed the build issue on new Windows SDK for Token structures ([link](https://github.com/HyperDbg/HyperDbg/pull/530))
+- Fixed retrieving valid watching process IDs for the execution trap and user-mode execution prevention
+- Fixed crashing the driver if the hyperlog memory was not properly allocated
+- The target runner image for deploying HyperDbg (CI/CD) changed from Windows Server 2019 to 2022
+- Restored the pid and the process name parameters of the '!hide' command ([link](https://docs.hyperdbg.org/commands/extension-commands/hide))
+- Fixed crashing Windows when using 'TPAUSE' instruction on bare metal Windows 11 24h2
+- Check to avoid putting EPT hooks on physical addresses greater than 512 GB
+
+## [0.13.2.0] - 2025-05-26
+New release of the HyperDbg Debugger.
+
+### Added
+- Intercepting system-call return results using the TRAP flag for the transparent-mode
+- Added optional parameters and context for the transparent-mode system-call return interceptions
+
+### Changed
+- Set variable length (stack frames) for showing the callstack ([link](https://docs.hyperdbg.org/commands/debugging-commands/k))
+- Fixed VMCS layout corruption due to NMI injection (VMRESUME 0x7 error) in nested-virtualization on Meteor Lake processors
+- Restore RDMSR handler for VM-exits
+
+## [0.13.1.0] - 2025-04-14
+New release of the HyperDbg Debugger.
+
+### Added
+- Added new transparency methods for hiding nested virtualization environments thanks to [@CokeTree3](https://github.com/CokeTree3) ([link](https://github.com/HyperDbg/HyperDbg/pull/515))
+
+### Changed
+- Fix '.thread' command crash ([link](https://github.com/HyperDbg/HyperDbg/pull/510))
+- Update .clang-format format file based on the new version of LLVM
+- Update the list of required contributions
+
+## [0.13.0.0] - 2025-02-25
+New release of the HyperDbg Debugger.
+
+### Added
+- Added mitigation for the anti-hypervisor method in handling the trap flag for emulated instructions ([link](https://github.com/HyperDbg/HyperDbg/pull/497))
+- Export the SDK functions for enabling and disabling transparent mode ([link](https://docs.hyperdbg.org/commands/extension-commands/hide#sdk))([link](https://docs.hyperdbg.org/commands/extension-commands/unhide#sdk))
+- New description of changing script engine constants ([link](https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/change-script-engine-limitations))
+- Added the command for interpreting PCI CAM (PCI configuration space) fields ([link](https://docs.hyperdbg.org/commands/extension-commands/pcicam))
+- Added the command for dumping PCI CAM (PCI configuration space) memory ([link](https://docs.hyperdbg.org/commands/extension-commands/pcicam))
+- Checking for and unloading the older version of the driver (if it exists) ([link](https://github.com/HyperDbg/HyperDbg/pull/503))
+- **memcpy_pa()** function in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/memory/memcpy_pa))
+- **poi_pa**, **hi_pa**, **low_pa**, **db_pa**, **dd_pa**, **dw_pa**, and **dq_pa** keywords in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/assumptions-and-evaluations#keywords))
+- **eb_pa**, **ed_pa**, and **eq_pa** functions in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/memory/eb_pa-ed_pa-eq_pa))
+
+### Changed
+- Fix the 'lm' command issue of not showing kernel module addresses (KASLR leak mitigation) introduced in Windows 11 24h2 ([link](https://docs.hyperdbg.org/commands/debugging-commands/lm))
+- Deprecated TSC mitigation for the transparent mode ([link](https://docs.hyperdbg.org/commands/extension-commands/measure))
+- Changed the parameters of the '!hide' command ([link](https://docs.hyperdbg.org/commands/extension-commands/hide))
+- Changed the parameters of the '!unhide' command ([link](https://docs.hyperdbg.org/commands/extension-commands/unhide))
+- Fix containing backslash escape character in script strings ([link](https://github.com/HyperDbg/HyperDbg/pull/499))
+- Fix reading/writing into devices' physical memory (MMIO region) in VMI Mode ([link](https://github.com/HyperDbg/HyperDbg/pull/500))
+- All test cases for command parsing are now passed ([link](https://github.com/HyperDbg/HyperDbg/pull/504))
+- The '.sympath' command now requires the symbol server path to be within quotes, although it is not mandatory ([link](https://docs.hyperdbg.org/commands/meta-commands/.sympath))
+
+## [0.12.0.0] - 2025-01-02
+New release of the HyperDbg Debugger.
+
+### Added
+- Added the PCI tree command ([link](https://docs.hyperdbg.org/commands/extension-commands/pcitree))
+- Added the proper handling for the xsetbv VM exits thanks to [@Shtan7](https://github.com/Shtan7) ([link](https://github.com/HyperDbg/HyperDbg/pull/491))
+- Added the IDT command for interpreting Interrupt Descriptor Table (IDT) ([link](https://docs.hyperdbg.org/commands/extension-commands/idt))
+- Export SDK APIs for getting Interrupt Descriptor Table (IDT) entries
+
+### Changed
+- Fix buffer overflow in the symbols path converter thanks to [@binophism](https://github.com/binophism) ([link](https://github.com/HyperDbg/HyperDbg/pull/490))
+- Fix script engine's "printf" function to improve safety thanks to [@Reodus](https://github.com/Reodus) ([link](https://github.com/HyperDbg/HyperDbg/pull/489))
+
+## [0.11.0.0] - 2024-12-03
+New release of the HyperDbg Debugger.
+
+### Added
+- Added the local APIC command (xAPIC and x2APIC modes) ([link](https://docs.hyperdbg.org/commands/extension-commands/apic))
+- Added the I/O APIC command ([link](https://docs.hyperdbg.org/commands/extension-commands/ioapic))
+- The new link is added to help increase the number of EPT hook breakpoints in a single page ([link](https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/number-of-ept-hooks-in-one-page))
+- Export SDK APIs for Local APIC and X2APIC
+
+### Changed
+- The link for changing the communication buffer size is updated ([link](https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/increase-communication-buffer-size))
+- Update Microsoft's DIA SDK and symsrv
+
+## [0.10.2.0] - 2024-10-11
+New release of the HyperDbg Debugger.
+
+### Added
+- Automated test case parsing and test case compilation (generation) for the hwdbg debugger
+- Export hwdbg testing functions
+- Automated test case interpretation and emulation of hwdbg hardware scripts
+- Create JSON representation of hwdbg configs
+
+### Changed
+- Fix main command parser bugs according to test cases
+- Improvements in symbol structure, token structure, and stack buffer in the script engine
+- Fix compatibility mode program crash when terminating 32-bit process (#479) ([link](https://github.com/HyperDbg/HyperDbg/pull/479))
+- Extensive refactor of chip instance info interpretation codes of hwdbg debugger
+- Separating functions of hwdbg interpreter and script manager
+- Fix synthesize inconsistencies between Icarus iVerilog and Xilinx ISim
+- Fix runtime error for deallocating memory from separate DLLs
+- Exporting standard functions (import/export) for the script engine
+- Exporting standard functions (import/export) for the symbol parser
+- Avoid passing signals once the stage is not configured
+
+## [0.10.1.0] - 2024-09-08
+New release of the HyperDbg Debugger.
+
+### Added
+- Added feature to pause the debuggee immediately upon connection
+- The '.debug' command now supports pausing the debuggee at startup ([link](https://docs.hyperdbg.org/commands/meta-commands/.debug))
+- Export SDK API for assembling instructions
+- The 'struct' command now supports a path as output ([link](https://docs.hyperdbg.org/commands/debugging-commands/struct))
+- Export SDK API closing connection to the remote debuggee
+- Automated tests for the main command parser
+- Export SDK APIs for stepping and tracing instructions
+- Export SDK APIs for tracking execution
+
+### Changed
+- HyperDbg command-line comment sign is changed from '#' to C-like comments ('//' and '/**/')
+- Integrating a new command parser for the regular HyperDbg commands
+- Fix showing a list of active outputs using the 'output' command ([link](https://docs.hyperdbg.org/commands/debugging-commands/output))
+- Fix the issue of passing arguments to the '.start' command ([link](https://docs.hyperdbg.org/commands/meta-commands/.start))
+- Fix the problem with parsing multiple spaces within the events (#420) ([link](https://github.com/HyperDbg/HyperDbg/issues/420))
+- Fix the problem with escaping '{' in the command parser (#421) ([link](https://github.com/HyperDbg/HyperDbg/issues/421))
+- Fix nested brackets issues in the main command parser
+- Fix script engine bugs on order of passing arguments to functions (#453) ([link](https://github.com/HyperDbg/HyperDbg/issues/453))
+- Fix the script test case for factorial computation ([link](https://github.com/HyperDbg/script-engine-test/blob/main/semantic-test-cases/manual-test-cases_60-69.ds))
+- Fix the script test case for computation iterative Fibonacci ([link](https://github.com/HyperDbg/script-engine-test/blob/main/semantic-test-cases/manual-test-cases_60-69.ds))
+- Fix miscomputation of physical address width for physical address validity checks (#469) ([link](https://github.com/HyperDbg/HyperDbg/issues/469))
+
+## [0.10.0.0] - 2024-07-22
+New release of the HyperDbg Debugger.
+
+### Added
+- Support using assembly conditions and codes in all events ([link](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-a-condition))([link](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-an-action))
+- Added support for forwarding events to binary (DLL) modules ([link](https://docs.hyperdbg.org/tips-and-tricks/misc/event-forwarding))([link](https://docs.hyperdbg.org/commands/debugging-commands/output))([link](https://github.com/HyperDbg/event-forwarding-examples))
+- Added the assembler command 'a' for virtual memory ([link](https://docs.hyperdbg.org/commands/debugging-commands/a))
+- Added the assembler command '!a' for physical memory ([link](https://docs.hyperdbg.org/commands/extension-commands/a))
+- Providing a unified SDK API for reading memory in the VMI Mode and the Debugger Mode
+- Export SDK APIs for reading/writing into registers in the Debugger Mode
+- Export SDK API for writing memory in the VMI Mode and the Debugger Mode
+- Export SDK API for getting kernel base address
+- Export SDK API for connecting to the debugger and from debuggee in the Debugger Mode
+- Export SDK API for starting a new process
+- Add and export SDK API for unsetting message callback
+- Event commands are coming with more examples regarding scripts and assembly codes
+- Add message callback using shared memory
+- Add maximum execution limitation to the script IRs (#435) ([link](https://github.com/HyperDbg/HyperDbg/pull/435))
+
+### Changed
+- Fix clearing '!monitor' hooks on a different process or if the process is closed (#409) ([link](https://github.com/HyperDbg/HyperDbg/issues/409))
+- Fix triggering multiple '!monitor' hooks with different contexts (#415) ([link](https://github.com/HyperDbg/HyperDbg/issues/415))
+- Fix the problem of repeating commands once kHyperDbg is disconnected
+- Fix step-over hangs if the process terminates/excepts within call instruction (#406) ([link](https://github.com/HyperDbg/HyperDbg/issues/406))
+- Fix crash on editing invalid physical addresses (#424) ([link](https://github.com/HyperDbg/HyperDbg/issues/424))
+- Fix exporting VMM module load and install it in the SDK
+- Fix function interpretation issues and update the parser and the code execution (#435) ([link](https://github.com/HyperDbg/HyperDbg/pull/435))
+
+## [0.9.1.0] - 2024-06-30
+New release of the HyperDbg Debugger.
+
+### Added
+- Regular port/pin value read and modification in hwdbg
+- Conditional statement evaluation in hwdbg
+- Added automatic script buffer packet generator for hwdbg
+- Added support for @hw_pinX and @hw_portX registers
+- Added hwdbg instance information interpreter
+- Added stack buffer in vmx-root ([link](https://github.com/HyperDbg/HyperDbg/commit/5df4d2a5268a6b190dc126bf6cfe0527703296eb))
+- Exporting functions to support loading drivers with different names
+- Exporting function to connect and load HyperDbg drivers
+- Exporting function to connect and load HyperDbg drivers
+- **$date** and **$time** pseudo-registers are added ([link](https://docs.hyperdbg.org/commands/scripting-language/assumptions-and-evaluations#pseudo-registers))([link](https://github.com/HyperDbg/HyperDbg/issues/397))
+
+### Changed
+- Fix using constant WSTRINGs in the **wcsncmp** function ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/strings/wcsncmp))
+- Fix `phnt` build error with 24H2 SDK
+- `hprdbgctrl.dll` changed to `libhyperdbg.dll`
+- `hprdbgkd.sys` changed to `hyperkd.sys`
+- `hprdbghv.dll` changed to `hyperhv.dll`
+- Dividing user/kernel exported headers in the SDK
+
+## [0.9.0.0] - 2024-06-09
+New release of the HyperDbg Debugger.
+
+### Added
+- The **!monitor** command now physical address hooking ([link](https://docs.hyperdbg.org/commands/extension-commands/monitor))
+- **hwdbg** is merged to HyperDbg codebase ([link](https://hwdbg.hyperdbg.org))
+- **strncmp(Str1, Str2, Num)**, and **wcsncmp(WStr1, WStr2, Num)** functions in script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/strings/strncmp))([link](https://docs.hyperdbg.org/commands/scripting-language/functions/strings/wcsncmp))
+
+### Changed
+- Using a separate HOST IDT in VMCS (not OS IDT) (fix to this [VM escape](https://www.unknowncheats.me/forum/c-and-c-/390593-vm-escape-via-nmi.html) issues)
+- Using a dedicated HOST GDT and TSS Stack
+- Checking for race-condition of not locked cores before applying instant-events and switching cores
+- The error message for invalid address is changed ([more information](https://docs.hyperdbg.org/tips-and-tricks/considerations/accessing-invalid-address))
+- Fix the problem of not locking all cores after running the '.pagein' command
+
+## [0.8.4.0] - 2024-05-10
+New release of the HyperDbg Debugger.
+
+### Changed
+- Fixed the signedness overflow of the command parser
+
## [0.8.3.0] - 2024-05-03
New release of the HyperDbg Debugger.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 86595a5f..4b0d2c53 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -2,21 +2,19 @@
First off, thanks for taking the time to contribute! ❤️
-HyperDbg is a large-scale project that requires a lot of time and effort from the community. Given the current number of developers and their limited time and resources, we cannot develop every part simultaneously. Therefore, new developers are warmly welcomed to join and add their contributions to the project. Here, we made a list of potential improvements that you can contribute on. Feel free to open up an issue if you think you have any ideas that would make a good addition to the list, or if you want to implement one of the below items, or if you'd like to discuss a question you might have.
+HyperDbg is a large-scale project that requires a lot of time and effort from the community. Given the current number of developers and their limited time and resources, we cannot develop every part simultaneously. Therefore, new developers are warmly welcomed to join and add their contributions to the project. Here, we made a list of potential improvements that you can contribute on. Feel free to open up an issue if you think you have any ideas that would make a good addition to the list.
## Things to Work on
-- Writing blog posts about use-cases of HyperDbg
-- 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 net)
-- Adding an assembler to the project
-- Enhancing HyperDbg's [Transparent Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#transparent-mode), especially anti-hypervisor methods
-- Making a SoftICE-style GUI
-- Enhancing and adding more features to the ['.pe'](https://docs.hyperdbg.org/commands/meta-commands/.pe) command
-- Anything else you might find interesting ;)
+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.
-This list will be updated frequently.
+### 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).
+- 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 36bfb4ad..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))
@@ -21,4 +21,10 @@ The attributions listed on this credits page are acknowledged without any partic
- Ddkwork ([@ddkwork](https://github.com/ddkwork)) for making GUI
- Mohammad K. Fallah ([@mkfallah11](https://github.com/mkfallah11)) for implementing the optimization algorithms
- Xandora Team ([xandora.io](https://www.xandora.io)) for [Keystone](https://github.com/keystone-engine/keystone) engine
-- xmaple555 ([@xmaple555](https://github.com/xmaple555)) for contributions in HyperDbg core and the script engine
\ No newline at end of file
+- 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)) 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 ef9a7374..fae0672e 100644
--- a/README.md
+++ b/README.md
@@ -6,25 +6,40 @@
-
# 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)** to get notified about new releases, or join the HyperDbg **[Telegram](https://t.me/HyperDbg)** group, where you can ask developers and open-source reversing enthusiasts for help with setting up and running HyperDbg.
+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.
+
+- **[Telegram](https://t.me/HyperDbg)**
+- **[Discord](https://discord.gg/anSPsGUtzN)**
+- **[Matrix](https://matrix.to/#/#hyperdbg-discussion:matrix.org)**
## Description
-**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 Intel PT. 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** 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.
@@ -35,7 +50,7 @@ Please visit **[Build & Install](https://docs.hyperdbg.org/getting-started/build
## Tutorials
-The **[OpenSecurityTraining2's "Reversing with HyperDbg (Dbg3301)"](https://ost2.fyi/Dbg3301)** tutorial is the recommended way to get started with and learn HyperDbg, guiding you through the initial steps of using HyperDbg, covering essential concepts, principles, debugging functionalities, along with practical examples and numerous reverse engineering methods that are unique to HyperDbg.
+The **OpenSecurityTraining2's "Reversing with HyperDbg (Dbg3301)**" tutorial series, available on [**OST2's website**](https://ost2.fyi/Dbg3301) (_preferred_) and [**YouTube**](https://www.youtube.com/playlist?list=PLUFkSN0XLZ-kF1f143wlw8ujlH2A45nZY) is the recommended way to get started with and learn HyperDbg. It guides you through the initial steps of using HyperDbg, covering essential concepts, principles, and debugging functionalities, along with practical examples and numerous reverse engineering methods that are unique to HyperDbg.
If you're interested in understanding the internal design and architecture of hypervisors and HyperDbg, you can read the [**Hypervisor From Scratch**](https://rayanfam.com/tutorials) tutorials.
@@ -54,26 +69,71 @@ In case you use one of **HyperDbg**'s components in your work, please consider c
year={2022}
}
```
+
-**2. [The Reversing Machine: Reconstructing Memory Assumptions](https://arxiv.org/pdf/2405.00298)** [[arXiv](https://arxiv.org/abs/2405.00298)]
+Other paper built upon HyperDbg...
+
+**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)]
```
-@misc{karvandi2024reversing,
- Author = {Mohammad Sina Karvandi and Soroush Meghdadizanjani and Sima Arasteh and Saleh Khalaj Monfared and Mohammad K. Fallah and Saeid Gorgin and Jeong-A Lee and Erik van der Kouwe},
- Title = {The Reversing Machine: Reconstructing Memory Assumptions},
- Year = {2024},
- Eprint = {arXiv:2405.00298},
+@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}
}
```
-You can also read [this article](https://research.hyperdbg.org/debugger/kernel-debugger-design.html) as it describes the overall architecture, technical difficulties, design decisions, and internals of HyperDbg Debugger, [this article](https://research.hyperdbg.org/debugger/transparency.html) about our efforts on vm-exit transparency, and [this article](https://research.hyperdbg.org/debugger/chasing-bugs.html) about chasing bugs within hypervisors. 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.
+**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
-### First Release (v0.1.0.0)
+
* 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]
@@ -83,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]
@@ -100,30 +160,26 @@ You can also read [this article](https://research.hyperdbg.org/debugger/kernel-d
* Event Forwarding (#DFIR) [link][link]
* Transparent Breakpoint Handler [link][link]
* Various Custom Scripts [link]
-
-### Second Release (v0.2.0.0)
* HyperDbg Software Development Kit (SDK) [link]
-
-### Third Release (v0.3.0.0)
* 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]
-
-### Fourth Release (v0.4.0.0)
* Memory Execution Monitor & Execution Blocking [link]
* Custom Page-fault Injection [link]
-
-### Fifth Release (v0.5.0.0)
* Different Event Calling Stages [link]
-
-### Sixth Release (v0.6.0.0)
* Injecting Custom Interrupts/Exceptions/Faults [link][link]
-
-### Seventh Release (v0.7.0.0)
-* Instant events in the Debugger Mode [link]
-
-### Eighth Release (v0.8.0.0)
-* Detect kernel-to-user and user-to-kernel transitions [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]
+* 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?
@@ -135,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/README.md b/examples/README.md
new file mode 100644
index 00000000..47fa15b3
--- /dev/null
+++ b/examples/README.md
@@ -0,0 +1,3 @@
+# User-Mode and Kernel-Mode Examples
+
+Examples for user-mode and kernel-mode are **NOT** yet completed and are currently **under construction**!
diff --git a/examples/kernel/README.md b/examples/kernel/README.md
new file mode 100644
index 00000000..e509023b
--- /dev/null
+++ b/examples/kernel/README.md
@@ -0,0 +1,3 @@
+NOTE
+============
+Build it directly from the main HyperDbg solution file. Do not build it independently, as it requires dependency files from the main HyperDbg libraries to be built first.
\ No newline at end of file
diff --git a/examples/kernel/hyperdbg_driver/CMakeLists.txt b/examples/kernel/hyperdbg_driver/CMakeLists.txt
new file mode 100644
index 00000000..3b2ca0b2
--- /dev/null
+++ b/examples/kernel/hyperdbg_driver/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Code generated by Visual Studio kit, DO NOT EDIT.
+set(SourceFiles
+ "header/core/Core.h"
+ "header/driver/Driver.h"
+ "header/driver/Loader.h"
+ "header/misc/Global.h"
+ "header/pch.h"
+ "code/core/Core.c"
+ "code/driver/Driver.c"
+ "code/driver/Ioctl.c"
+ "code/driver/Loader.c"
+)
+include_directories(
+ "../../../hyperdbg/include"
+ "header"
+)
+wdk_add_driver(hyperdbg_driver
+ KMDF 1.15
+ ${SourceFiles}
+)
diff --git a/hyperdbg/include/SDK/Examples/hyperdbg_driver/code/core/Core.c b/examples/kernel/hyperdbg_driver/code/core/Core.c
similarity index 100%
rename from hyperdbg/include/SDK/Examples/hyperdbg_driver/code/core/Core.c
rename to examples/kernel/hyperdbg_driver/code/core/Core.c
diff --git a/hyperdbg/include/SDK/Examples/hyperdbg_driver/code/driver/Driver.c b/examples/kernel/hyperdbg_driver/code/driver/Driver.c
similarity index 99%
rename from hyperdbg/include/SDK/Examples/hyperdbg_driver/code/driver/Driver.c
rename to examples/kernel/hyperdbg_driver/code/driver/Driver.c
index 44922817..b4092073 100644
--- a/hyperdbg/include/SDK/Examples/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/hyperdbg/include/SDK/Examples/hyperdbg_driver/code/driver/Ioctl.c b/examples/kernel/hyperdbg_driver/code/driver/Ioctl.c
similarity index 84%
rename from hyperdbg/include/SDK/Examples/hyperdbg_driver/code/driver/Ioctl.c
rename to examples/kernel/hyperdbg_driver/code/driver/Ioctl.c
index f80b0c04..8d7b1c5c 100644
--- a/hyperdbg/include/SDK/Examples/hyperdbg_driver/code/driver/Ioctl.c
+++ b/examples/kernel/hyperdbg_driver/code/driver/Ioctl.c
@@ -26,15 +26,17 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
PREGISTER_NOTIFY_BUFFER RegisterEventRequest;
NTSTATUS Status;
+ UNREFERENCED_PARAMETER(DeviceObject);
+
//
// Here's the best place to see if there is any allocation pending
// to be allcated as we're in PASSIVE_LEVEL
//
// DO NOT CHANGE CALLING OF THE FOLLOWING FUNCTION
//
- PoolManagerCheckAndPerformAllocationAndDeallocation();
+ // PoolManagerCheckAndPerformAllocationAndDeallocation();
- if (g_AllowIOCTLFromUsermode)
+ if (g_VmmInitialized)
{
IrpStack = IoGetCurrentIrpStackLocation(Irp);
@@ -62,10 +64,21 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
switch (RegisterEventRequest->Type)
{
case IRP_BASED:
- Status = LogRegisterIrpBasedNotification(DeviceObject, Irp);
+
+ LogRegisterIrpBasedNotification((PVOID)Irp, &Status);
+
break;
case EVENT_BASED:
- Status = LogRegisterEventBasedNotification(DeviceObject, Irp);
+
+ if (LogRegisterEventBasedNotification((PVOID)Irp))
+ {
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ Status = STATUS_UNSUCCESSFUL;
+ }
+
break;
default:
LogError("Err, unknown notification type from user-mode");
diff --git a/hyperdbg/include/SDK/Examples/hyperdbg_driver/code/driver/Loader.c b/examples/kernel/hyperdbg_driver/code/driver/Loader.c
similarity index 96%
rename from hyperdbg/include/SDK/Examples/hyperdbg_driver/code/driver/Loader.c
rename to examples/kernel/hyperdbg_driver/code/driver/Loader.c
index a84a8f63..7a2ed944 100644
--- a/hyperdbg/include/SDK/Examples/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/hyperdbg/include/SDK/Examples/hyperdbg_driver/header/core/Core.h b/examples/kernel/hyperdbg_driver/header/core/Core.h
similarity index 100%
rename from hyperdbg/include/SDK/Examples/hyperdbg_driver/header/core/Core.h
rename to examples/kernel/hyperdbg_driver/header/core/Core.h
diff --git a/hyperdbg/include/SDK/Examples/hyperdbg_driver/header/driver/Driver.h b/examples/kernel/hyperdbg_driver/header/driver/Driver.h
similarity index 100%
rename from hyperdbg/include/SDK/Examples/hyperdbg_driver/header/driver/Driver.h
rename to examples/kernel/hyperdbg_driver/header/driver/Driver.h
diff --git a/hyperdbg/include/SDK/Examples/hyperdbg_driver/header/driver/Loader.h b/examples/kernel/hyperdbg_driver/header/driver/Loader.h
similarity index 93%
rename from hyperdbg/include/SDK/Examples/hyperdbg_driver/header/driver/Loader.h
rename to examples/kernel/hyperdbg_driver/header/driver/Loader.h
index c12b0d12..7ead903c 100644
--- a/hyperdbg/include/SDK/Examples/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/hyperdbg/include/SDK/Examples/hyperdbg_driver/header/misc/Global.h b/examples/kernel/hyperdbg_driver/header/misc/Global.h
similarity index 77%
rename from hyperdbg/include/SDK/Examples/hyperdbg_driver/header/misc/Global.h
rename to examples/kernel/hyperdbg_driver/header/misc/Global.h
index 77cf5e59..db81c9d8 100644
--- a/hyperdbg/include/SDK/Examples/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/hyperdbg/include/SDK/Examples/hyperdbg_driver/header/pch.h b/examples/kernel/hyperdbg_driver/header/pch.h
similarity index 69%
rename from hyperdbg/include/SDK/Examples/hyperdbg_driver/header/pch.h
rename to examples/kernel/hyperdbg_driver/header/pch.h
index ed1f5358..2d085776 100644
--- a/hyperdbg/include/SDK/Examples/hyperdbg_driver/header/pch.h
+++ b/examples/kernel/hyperdbg_driver/header/pch.h
@@ -9,12 +9,6 @@
* @copyright This project is released under the GNU Public License v3.
*
*/
-#include
-#include
-#include
-#include
-#include
-#include
//
// Scope definitions
@@ -23,14 +17,15 @@
#define HYPERDBG_RM
//
-// Definition of Intel primitives (External header)
+// General WDK headers
//
-// #include "ia32-doc/out/ia32.h"
+#include
+#include
//
// Import Configuration and Definitions
//
-#include "Configuration.h"
+#include "config/Configuration.h"
//
// Macros
@@ -45,15 +40,15 @@
//
// Import HyperLog Module
//
-#include "SDK/Modules/HyperLog.h"
-#include "SDK/Imports/HyperDbgHyperLogImports.h"
-#include "SDK/Imports/HyperDbgHyperLogIntrinsics.h"
+#include "SDK/modules/HyperLog.h"
+#include "SDK/imports/kernel/HyperDbgHyperLogImports.h"
+#include "SDK/imports/kernel/HyperDbgHyperLogIntrinsics.h"
//
// Import VMM Module
//
-#include "SDK/Modules/VMM.h"
-#include "SDK/Imports/HyperDbgVmmImports.h"
+#include "SDK/modules/VMM.h"
+#include "SDK/imports/kernel/HyperDbgVmmImports.h"
//
// Local Driver headers
diff --git a/hyperdbg/include/SDK/Examples/hyperdbg_driver/hyperdbg_driver.vcxproj b/examples/kernel/hyperdbg_driver/hyperdbg_driver.vcxproj
similarity index 59%
rename from hyperdbg/include/SDK/Examples/hyperdbg_driver/hyperdbg_driver.vcxproj
rename to examples/kernel/hyperdbg_driver/hyperdbg_driver.vcxproj
index a6cb2789..fd70d5dc 100644
--- a/hyperdbg/include/SDK/Examples/hyperdbg_driver/hyperdbg_driver.vcxproj
+++ b/examples/kernel/hyperdbg_driver/hyperdbg_driver.vcxproj
@@ -1,5 +1,8 @@
+
+
+ debug
@@ -9,14 +12,6 @@
releasex64
-
- debug
- ARM64
-
-
- release
- ARM64
- {79AB8BD3-03A4-4B65-ABF6-313C10A00CC5}
@@ -47,22 +42,6 @@
Universalfalse
-
- Windows10
- true
- WindowsKernelModeDriver10.0
- Driver
- KMDF
- Universal
-
-
- Windows10
- false
- WindowsKernelModeDriver10.0
- Driver
- KMDF
- Universal
-
@@ -81,18 +60,12 @@
$(SolutionDir)build\bin\$(Configuration)\$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\
-
- DbgengKernelDebugger
-
-
- DbgengKernelDebugger
- sha256
- $(SolutionDir)\include;$(ProjectDir)header;%(AdditionalIncludeDirectories)
+ $(SolutionDir)include;$(ProjectDir)header;%(AdditionalIncludeDirectories)true
@@ -101,7 +74,7 @@
true
- $(SolutionDir)build\bin\$(Configuration)\hyperlog.lib;$(SolutionDir)build\bin\$(Configuration)\hprdbghv.lib;%(AdditionalDependencies)
+ $(SolutionDir)build\bin\$(Configuration)\hyperlog.lib;$(SolutionDir)build\bin\$(Configuration)\hyperhv.lib;%(AdditionalDependencies)DriverEntry
@@ -110,29 +83,20 @@
sha256
- $(SolutionDir)\include;$(ProjectDir)header;%(AdditionalIncludeDirectories)
+ $(SolutionDir)include;$(ProjectDir)header;%(AdditionalIncludeDirectories)trueCreatepch.h
+ Fulltrue
- $(SolutionDir)build\bin\$(Configuration)\hyperlog.lib;$(SolutionDir)build\bin\$(Configuration)\hprdbghv.lib;%(AdditionalDependencies)
+ $(SolutionDir)build\bin\$(Configuration)\hyperlog.lib;$(SolutionDir)build\bin\$(Configuration)\hyperhv.lib;%(AdditionalDependencies)DriverEntry
-
-
- sha256
-
-
-
-
- sha256
-
-
@@ -149,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/hyperdbg/include/SDK/Examples/hyperdbg_driver/hyperdbg_driver.vcxproj.filters b/examples/kernel/hyperdbg_driver/hyperdbg_driver.vcxproj.filters
similarity index 96%
rename from hyperdbg/include/SDK/Examples/hyperdbg_driver/hyperdbg_driver.vcxproj.filters
rename to examples/kernel/hyperdbg_driver/hyperdbg_driver.vcxproj.filters
index 2a6aa09a..3345321d 100644
--- a/hyperdbg/include/SDK/Examples/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/README.md b/examples/user/README.md
new file mode 100644
index 00000000..e509023b
--- /dev/null
+++ b/examples/user/README.md
@@ -0,0 +1,3 @@
+NOTE
+============
+Build it directly from the main HyperDbg solution file. Do not build it independently, as it requires dependency files from the main HyperDbg libraries to be built first.
\ No newline at end of file
diff --git a/examples/user/hyperdbg_app/CMakeLists.txt b/examples/user/hyperdbg_app/CMakeLists.txt
new file mode 100644
index 00000000..28460d83
--- /dev/null
+++ b/examples/user/hyperdbg_app/CMakeLists.txt
@@ -0,0 +1,11 @@
+# Code generated by Visual Studio kit, DO NOT EDIT.
+set(SourceFiles
+ "../../../platform/user/header/Environment.h"
+ "header/pch.h"
+ "code/hyperdbg-app.cpp"
+)
+include_directories(
+ "../../../hyperdbg/include"
+ "header"
+)
+add_executable(hyperdbg_app ${SourceFiles})
diff --git a/examples/user/hyperdbg_app/code/hyperdbg-app.cpp b/examples/user/hyperdbg_app/code/hyperdbg-app.cpp
new file mode 100644
index 00000000..095876bf
--- /dev/null
+++ b/examples/user/hyperdbg_app/code/hyperdbg-app.cpp
@@ -0,0 +1,58 @@
+#include "pch.h"
+
+static int
+ShowMessages(const char * Text)
+{
+ printf("%s", Text);
+ return 0;
+}
+
+static int
+LoadVmm()
+{
+ 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");
+
+ return 0;
+}
+
+int
+main(int argc, char ** argv)
+{
+ return main2(argc, argv);
+
+ if (LoadVmm() != 0)
+ {
+ 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/hyperdbg/include/SDK/Examples/hyperdbg_app/header/pch.h b/examples/user/hyperdbg_app/header/pch.h
similarity index 75%
rename from hyperdbg/include/SDK/Examples/hyperdbg_app/header/pch.h
rename to examples/user/hyperdbg_app/header/pch.h
index 80114722..d4bbf789 100644
--- a/hyperdbg/include/SDK/Examples/hyperdbg_app/header/pch.h
+++ b/examples/user/hyperdbg_app/header/pch.h
@@ -12,14 +12,14 @@
*/
#pragma once
-//
-// add headers that you want to pre-compile here
-//
+ //
+ // Environment headers
+ //
+#include "platform/general/header/Environment.h"
//
// Windows SDK headers
//
-
#define WIN32_LEAN_AND_MEAN
//
@@ -36,6 +36,10 @@
//
// HyperDbg SDK headers
//
-#include "Definition.h"
#include "SDK/HyperDbgSdk.h"
-#include "SDK/Imports/HyperDbgCtrlImports.h"
+#include "SDK/imports/user/HyperDbgLibImports.h"
+
+//
+// Other internal headers
+//
+#include "example-ipt.h"
diff --git a/hyperdbg/include/SDK/Examples/hyperdbg_app/hprdbgrev.vcxproj b/examples/user/hyperdbg_app/hyperdbg_app.vcxproj
similarity index 56%
rename from hyperdbg/include/SDK/Examples/hyperdbg_app/hprdbgrev.vcxproj
rename to examples/user/hyperdbg_app/hyperdbg_app.vcxproj
index 7a781963..3072d9ac 100644
--- a/hyperdbg/include/SDK/Examples/hyperdbg_app/hprdbgrev.vcxproj
+++ b/examples/user/hyperdbg_app/hyperdbg_app.vcxproj
@@ -1,14 +1,6 @@
-
- debug
- Win32
-
-
- release
- Win32
- debugx64
@@ -19,9 +11,11 @@
+
+
@@ -33,29 +27,16 @@
hyperdbg_app
-
- Application
- true
- v143
- Unicode
-
-
- Application
- false
- v143
- true
- Unicode
- Applicationtrue
- v143
+ v145UnicodeApplicationfalse
- v143
+ v145trueUnicode
@@ -64,73 +45,55 @@
-
-
-
-
-
-
-
+
+
+ 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)\
+ true
-
-
- Level3
- true
- WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
- true
-
-
- Console
- true
-
-
-
-
- Level3
- true
- true
- true
- WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
- true
-
-
- Console
- true
- true
- true
-
- Level3true
- _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)\hprdbgctrl.lib;%(AdditionalDependencies)
- 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
+
+
+
+
+
+
@@ -138,22 +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
+ MaxSpeedConsoletruetruetrue
- $(SolutionDir)build\bin\$(Configuration)\hprdbgctrl.lib;%(AdditionalDependencies)
+ $(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/hyperdbg/include/SDK/Examples/hyperdbg_app/hprdbgrev.vcxproj.filters b/examples/user/hyperdbg_app/hyperdbg_app.vcxproj.filters
similarity index 66%
rename from hyperdbg/include/SDK/Examples/hyperdbg_app/hprdbgrev.vcxproj.filters
rename to examples/user/hyperdbg_app/hyperdbg_app.vcxproj.filters
index e6fb0974..d7dd0c26 100644
--- a/hyperdbg/include/SDK/Examples/hyperdbg_app/hprdbgrev.vcxproj.filters
+++ b/examples/user/hyperdbg_app/hyperdbg_app.vcxproj.filters
@@ -7,13 +7,22 @@
{c40916c8-414b-486b-bfd1-13bcbafd8fa1}
+
+ {14cb7f22-aa90-410e-a333-f05e0ec7981f}
+ header
+
+ header
+
+
+ code
+ code
diff --git a/hwdbg/.github/workflows/test.yml b/hwdbg/.github/workflows/test.yml
new file mode 100644
index 00000000..cbd456fa
--- /dev/null
+++ b/hwdbg/.github/workflows/test.yml
@@ -0,0 +1,59 @@
+name: Continuous Integration
+
+on:
+ push:
+ tags: ['*']
+ branches: ['main']
+ pull_request:
+ workflow_dispatch:
+
+env:
+ verilator-version: v5.012
+ verilator-install-dir: verilator-install
+
+jobs:
+ ci:
+ name: ci
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Cleanup
+ run: sed -i "s/%NAME%/test/g" build.sc
+ - name: Cache Scala
+ uses: coursier/cache-action@v6
+ - name: Setup Scala
+ uses: coursier/setup-action@v1
+ with:
+ jvm: adopt:11
+ apps: sbt mill
+ - name: Setup Dependencies
+ run: |
+ sudo apt-get install ccache
+ - name: Get Cached Verilator
+ id: get-cached-verilator
+ uses: actions/cache@v4
+ with:
+ path: ${{ env.verilator-install-dir }}
+ key: verilator-${{ env.verilator-version }}
+ - name: Install Verilator
+ if: steps.get-cached-verilator.outputs.cache-hit != 'true'
+ run: |
+ sudo apt-get install git help2man perl python3 make autoconf g++ flex bison numactl perl-doc libfl-dev
+ git clone https://github.com/verilator/verilator
+ unset VERILATOR_ROOT
+ cd verilator
+ git checkout ${{ env.verilator-version }}
+ autoconf
+ ./configure --prefix=$(pwd)/../${{ env.verilator-install-dir }}
+ make
+ make install
+ - name: Set PATH
+ run: |
+ echo "$(pwd)/${{ env.verilator-install-dir }}/bin" >> $GITHUB_PATH
+ echo VERILATOR_ROOT="$(pwd)/${{ env.verilator-install-dir }}/share/verilator" >> $GITHUB_ENV
+ ln -sf $(pwd)/${{ env.verilator-install-dir }}/bin/verilator_bin $(pwd)/${{ env.verilator-install-dir }}/share/verilator/verilator_bin
+ - name: SBT Test
+ run: sbt test
+ - name: mill Test
+ run: mill _.test
diff --git a/hwdbg/.gitignore b/hwdbg/.gitignore
new file mode 100644
index 00000000..6404852f
--- /dev/null
+++ b/hwdbg/.gitignore
@@ -0,0 +1,366 @@
+### Project Specific stuff
+test_run_dir/*
+### XilinxISE template
+# intermediate build files
+*.bgn
+*.bit
+*.bld
+*.cmd_log
+*.drc
+*.ll
+*.lso
+*.msd
+*.msk
+*.ncd
+*.ngc
+*.ngd
+*.ngr
+*.pad
+*.par
+*.pcf
+*.prj
+*.ptwx
+*.rbb
+*.rbd
+*.stx
+*.syr
+*.twr
+*.twx
+*.unroutes
+*.ut
+*.xpi
+*.xst
+*_bitgen.xwbt
+*_envsettings.html
+*_map.map
+*_map.mrp
+*_map.ngm
+*_map.xrpt
+*_ngdbuild.xrpt
+*_pad.csv
+*_pad.txt
+*_par.xrpt
+*_summary.html
+*_summary.xml
+*_usage.xml
+*_xst.xrpt
+
+# project-wide generated files
+*.gise
+par_usage_statistics.html
+usage_statistics_webtalk.html
+webtalk.log
+webtalk_pn.xml
+
+# generated folders
+iseconfig/
+xlnx_auto_0_xdb/
+xst/
+_ngo/
+_xmsgs/
+### Eclipse template
+*.pydevproject
+.metadata
+.gradle
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+
+# Eclipse Core
+.project
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# CDT-specific
+.cproject
+
+# JDT-specific (Eclipse Java Development Tools)
+.classpath
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# TeXlipse plugin
+.texlipse
+### C template
+# Object files
+*.o
+*.ko
+*.obj
+*.elf
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Libraries
+*.lib
+*.a
+*.la
+*.lo
+
+# Shared objects (inc. Windows DLLs)
+*.dll
+*.so
+*.so.*
+*.dylib
+
+# Executables
+*.exe
+*.out
+*.app
+*.i*86
+*.x86_64
+*.hex
+
+# Debug files
+*.dSYM/
+### SBT template
+# Simple Build Tool
+# http://www.scala-sbt.org/release/docs/Getting-Started/Directories.html#configuring-version-control
+
+target/
+lib_managed/
+src_managed/
+project/boot/
+.history
+.cache
+### Emacs template
+# -*- mode: gitignore; -*-
+*~
+\#*\#
+/.emacs.desktop
+/.emacs.desktop.lock
+*.elc
+auto-save-list
+tramp
+.\#*
+
+# Org-mode
+.org-id-locations
+*_archive
+
+# flymake-mode
+*_flymake.*
+
+# eshell files
+/eshell/history
+/eshell/lastdir
+
+# elpa packages
+/elpa/
+
+# reftex files
+*.rel
+
+# AUCTeX auto folder
+/auto/
+
+# cask packages
+.cask/
+### Vim template
+[._]*.s[a-w][a-z]
+[._]s[a-w][a-z]
+*.un~
+Session.vim
+.netrwhist
+*~
+### JetBrains template
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
+
+*.iml
+
+## Directory-based project format:
+.idea/
+# if you remove the above rule, at least ignore the following:
+
+# User-specific stuff:
+# .idea/workspace.xml
+# .idea/tasks.xml
+# .idea/dictionaries
+
+# Sensitive or high-churn files:
+# .idea/dataSources.ids
+# .idea/dataSources.xml
+# .idea/sqlDataSources.xml
+# .idea/dynamic.xml
+# .idea/uiDesigner.xml
+
+# Gradle:
+# .idea/gradle.xml
+# .idea/libraries
+
+# Mongo Explorer plugin:
+# .idea/mongoSettings.xml
+
+## File-based project format:
+*.ipr
+*.iws
+
+## Plugin-specific files:
+
+# IntelliJ
+/out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+### C++ template
+# Compiled Object files
+*.slo
+*.lo
+*.o
+*.obj
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Fortran module files
+*.mod
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.exe
+*.out
+*.app
+### OSX template
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+### Xcode template
+# Xcode
+#
+# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
+
+## Build generated
+build/
+DerivedData
+
+## Various settings
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+xcuserdata
+
+## Other
+*.xccheckout
+*.moved-aside
+*.xcuserstate
+### Scala template
+*.class
+*.log
+/.bsp
+
+# sbt specific
+.cache
+.history
+.lib/
+dist/*
+target/
+lib_managed/
+src_managed/
+project/boot/
+project/plugins/project/
+
+# Scala-IDE specific
+.scala_dependencies
+.worksheet
+### Java template
+*.class
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+# Visual Studio Code
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+!.vscode/*.code-snippets
+
+# Local History for Visual Studio Code
+.history/
+
+# Built Visual Studio Code Extensions
+*.vsix
+
+# Scala metals
+.metals/*
+
+# Scala metals
+.bloop/
+
+# Temporary disable the generated verilog files
+generated/
+
+# BRAM emulation content
+# bram_instance_info.txt
\ No newline at end of file
diff --git a/hwdbg/.mill-version b/hwdbg/.mill-version
new file mode 100644
index 00000000..62d5dbdf
--- /dev/null
+++ b/hwdbg/.mill-version
@@ -0,0 +1 @@
+0.11.5
diff --git a/hwdbg/.scalafmt.conf b/hwdbg/.scalafmt.conf
new file mode 100644
index 00000000..18f480ad
--- /dev/null
+++ b/hwdbg/.scalafmt.conf
@@ -0,0 +1,5 @@
+version = "3.8.1"
+runner.dialect = scala213
+maxColumn = 150
+docstrings.style = Asterisk
+docstrings.oneline = unfold
diff --git a/hwdbg/CODE_OF_CONDUCT.md b/hwdbg/CODE_OF_CONDUCT.md
new file mode 100644
index 00000000..b8d25f92
--- /dev/null
+++ b/hwdbg/CODE_OF_CONDUCT.md
@@ -0,0 +1,76 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, sex characteristics, gender identity and expression,
+level of experience, education, socio-economic status, nationality, personal
+appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+ advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+ address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the project team at sina@rayanfam.com. All
+complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. The project team is
+obligated to maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good
+faith may face temporary or permanent repercussions as determined by other
+members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
+available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see
+https://www.contributor-covenant.org/faq
diff --git a/hwdbg/LICENSE b/hwdbg/LICENSE
new file mode 100644
index 00000000..f288702d
--- /dev/null
+++ b/hwdbg/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/hwdbg/README.md b/hwdbg/README.md
new file mode 100644
index 00000000..317a6f0a
--- /dev/null
+++ b/hwdbg/README.md
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+
+
+
+
+## Description
+The **hwdbg** debugger chip generator is a gate-level debugging tool designed to make configurable and synthesizable hardware debuggers for white-box and black-box chip fuzzing, testing, and reverse engineering. The primary goal of **hwdbg** is to provide control over hardware, enabling monitoring and modification of signals down to the granular level of a single clock cycle. It is written in Chisel and Verilog.
+
+- ⚠️ This project is a work in progress and is not yet ready for testing.
+
+**hwdbg** is a highly customizable debugger designed to ease hardware debugging by bringing software debugging concepts into the hardware debugging domain. **hwdbg** aims to help with the complexities associated with debugging hardware, including chips and IP cores. Key features of **hwdbg** include the ability to step through the hardware design at the clock-cycle level, visualize waveforms, inspect values (e.g., like a logical analyzer), and modify signals. Moreover, it is synthesizable into [FPGAs](https://github.com/HyperDbg/hwdbg-fpga) and has the potential for fabrication into physical chips.
+
+```
+ ┏━━━━━━━━━━━━━━━━━━━━━━━┓
+ _ _ _ ┃
+ | |_ _ _ _ _| || |_ ___ ┃
+ | . || | | |/ . || . \/ . | ┃
+ |_|_||__/_/ \___||___/\_. | ┃
+ <___' ┃
+ ┃ ╱|、
+ HyperDbg's chip-level debugger ┃ (˚ˎ 。7
+ ┃ |、 ˜〵
+ ┗━━━━━━━━━━━━━━━━━━━━━━━┛ じしˍ,)ノ
+```
+## Publications
+
+In case you use **hwdbg** in your work, please consider citing our paper.
+
+**[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)]
+
+```
+@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}
+}
+```
+
+## Deployment Board
+
+[This repository](https://github.com/HyperDbg/hwdbg-fpga) contains pre-built TCL files to facilitate project creation for running **hwdbg** on various FPGA development boards.
+
+## Output
+
+For generating SystemVerilog files, you need to install [Chisel](https://www.chisel-lang.org/docs/installation). Once installed, use the following commands:
+
+```sh
+$ sbt run
+```
+
+This command prompts you to select a component. The `hwdbg.Main` class contains the debugger for synthesis purposes, while the `hwdbg.MainWithInitializedBRAM` class includes a pre-initialized Block RAM (BRAM), primarily for simulation and testing.
+
+After selecting the appropriate class for synthesis (option `1`) or simulation (option `2`), the output should look like this:
+
+```sh
+$ sbt run
+[info] welcome to sbt 1.9.7 (Eclipse Adoptium Java 17.0.10)
+[info] loading settings for project -build-build-build from metals.sbt ...
+[info] loading project definition from /home/sina/HyperDbg//project/project/project
+[info] loading settings for project -build-build from metals.sbt ...
+[info] loading project definition from /home/sina/HyperDbg//project/project
+[success] Generated .bloop/-build-build.json
+[success] Total time: 1 s, completed Apr 16, 2024, 1:49:05 PM
+[info] loading settings for project -build from metals.sbt,plugins.sbt ...
+[info] loading project definition from /home/sina/HyperDbg//project
+[success] Total time: 0 s, completed Apr 16, 2024, 1:49:05 PM
+[info] loading settings for project root from build.sbt ...
+[info] set current project to hwdbg (in build file:/home/sina/HyperDbg/hwdbg/)
+
+Multiple main classes detected. Select one to run:
+ [1] hwdbg.Main
+ [2] hwdbg.MainWithInitializedBRAM
+
+Enter number: 2
+[info] running hwdbg.MainWithInitializedBRAM
+```
+
+The generated code for the debugger can be found in the `generated` directory.
+
+## Testbenches
+
+To test **hwdbg**, [cocotb](https://www.cocotb.org/) should be installed. After that, first, run the debugger (generated SystemVerilog files) and then run the following commands:
+
+```sh
+cd sim/hwdbg/DebuggerModuleTestingBRAM
+./test.sh
+```
+
+The above command generates a waves file at `./sim/hwdbg/DebuggerModuleTestingBRAM/sim_build/DebuggerModuleTestingBRAM.fst` which can be read using [GTKWave](https://gtkwave.sourceforge.net/).
+
+```sh
+cd sim/hwdbg/DebuggerModuleTestingBRAM
+gtkwave ./sim_build/DebuggerModuleTestingBRAM.fst
+```
+
+### ModelSim
+
+If you prefer to use ModelSim instead of GTKWave, you can configure the `modelsim.config` file. Please visit here for more information.
+
+## API
+
+If you want to create the latest version of API documentation, you can run the following command:
+
+```sh
+$ sbt doc
+```
+
+This will generate documentation at `./target/scala-{version}/api/index.html`.
+
+## License
+
+**hwdbg** and all its submodules and repos, unless a license is otherwise specified, are licensed under **GPLv3** LICENSE.
diff --git a/hwdbg/build.sbt b/hwdbg/build.sbt
new file mode 100644
index 00000000..cf4b4ab5
--- /dev/null
+++ b/hwdbg/build.sbt
@@ -0,0 +1,29 @@
+// See README.md for license details.
+
+ThisBuild / scalaVersion := "2.13.12"
+ThisBuild / version := "0.1.0"
+ThisBuild / organization := "org.hyperdbg"
+
+val chiselVersion = "6.2.0"
+
+lazy val root = (project in file("."))
+ .settings(
+ name := "hwdbg",
+ libraryDependencies ++= Seq(
+ "org.chipsalliance" %% "chisel" % chiselVersion,
+ "org.scalatest" %% "scalatest" % "3.2.16" % "test",
+ "io.circe" %% "circe-core" % "0.14.3",
+ "io.circe" %% "circe-generic" % "0.14.3",
+ "io.circe" %% "circe-parser" % "0.14.3"
+ ),
+ scalacOptions ++= Seq(
+ "-language:reflectiveCalls",
+ "-deprecation",
+ "-feature",
+ "-Xcheckinit",
+ "-Ymacro-annotations"
+ ),
+ addCompilerPlugin(
+ "org.chipsalliance" % "chisel-plugin" % chiselVersion cross CrossVersion.full
+ )
+ )
diff --git a/hwdbg/build.sc b/hwdbg/build.sc
new file mode 100644
index 00000000..1880b58f
--- /dev/null
+++ b/hwdbg/build.sc
@@ -0,0 +1,30 @@
+// import Mill dependency
+import mill._
+import mill.define.Sources
+import mill.modules.Util
+import mill.scalalib.TestModule.ScalaTest
+import scalalib._
+// support BSP
+import mill.bsp._
+
+object hwdbg extends SbtModule { m =>
+ override def millSourcePath = os.pwd
+ override def scalaVersion = "2.13.12"
+ override def scalacOptions = Seq(
+ "-language:reflectiveCalls",
+ "-deprecation",
+ "-feature",
+ "-Xcheckinit",
+ )
+ override def ivyDeps = Agg(
+ ivy"org.chipsalliance::chisel:6.0.0",
+ )
+ override def scalacPluginIvyDeps = Agg(
+ ivy"org.chipsalliance:::chisel-plugin:6.0.0",
+ )
+ object test extends SbtModuleTests with TestModule.ScalaTest {
+ override def ivyDeps = m.ivyDeps() ++ Agg(
+ ivy"org.scalatest::scalatest::3.2.16"
+ )
+ }
+}
diff --git a/hwdbg/project/build.properties b/hwdbg/project/build.properties
new file mode 100644
index 00000000..b19d4e1e
--- /dev/null
+++ b/hwdbg/project/build.properties
@@ -0,0 +1 @@
+sbt.version = 1.9.7
diff --git a/hwdbg/project/metals.sbt b/hwdbg/project/metals.sbt
new file mode 100644
index 00000000..ac57eb45
--- /dev/null
+++ b/hwdbg/project/metals.sbt
@@ -0,0 +1,8 @@
+// format: off
+// DO NOT EDIT! This file is auto-generated.
+
+// This file enables sbt-bloop to create bloop config files.
+
+addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.18")
+
+// format: on
diff --git a/hwdbg/project/plugins.sbt b/hwdbg/project/plugins.sbt
new file mode 100644
index 00000000..5708f81a
--- /dev/null
+++ b/hwdbg/project/plugins.sbt
@@ -0,0 +1 @@
+logLevel := Level.Warn
diff --git a/hwdbg/project/project/metals.sbt b/hwdbg/project/project/metals.sbt
new file mode 100644
index 00000000..ac57eb45
--- /dev/null
+++ b/hwdbg/project/project/metals.sbt
@@ -0,0 +1,8 @@
+// format: off
+// DO NOT EDIT! This file is auto-generated.
+
+// This file enables sbt-bloop to create bloop config files.
+
+addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.18")
+
+// format: on
diff --git a/hwdbg/project/project/project/metals.sbt b/hwdbg/project/project/project/metals.sbt
new file mode 100644
index 00000000..ac57eb45
--- /dev/null
+++ b/hwdbg/project/project/project/metals.sbt
@@ -0,0 +1,8 @@
+// format: off
+// DO NOT EDIT! This file is auto-generated.
+
+// This file enables sbt-bloop to create bloop config files.
+
+addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.18")
+
+// format: on
diff --git a/hwdbg/sim/.gitignore b/hwdbg/sim/.gitignore
new file mode 100644
index 00000000..85f87a22
--- /dev/null
+++ b/hwdbg/sim/.gitignore
@@ -0,0 +1,164 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+# For a library or package, you might want to ignore these files since the code is
+# intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# poetry
+# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+# This is especially recommended for binary packages to ensure reproducibility, and is more
+# commonly ignored for libraries.
+# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# pdm
+# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+# in version control.
+# https://pdm.fming.dev/#use-with-ide
+.pdm.toml
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# PyCharm
+# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+# and can be added to the global gitignore or merged into this file. For a more nuclear
+# option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/
+
+# cocotb folders and files
+sim_build/
+results.xml
\ No newline at end of file
diff --git a/hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/Makefile b/hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/Makefile
new file mode 100644
index 00000000..6f5989ca
--- /dev/null
+++ b/hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/Makefile
@@ -0,0 +1,23 @@
+# Makefile
+
+TOPLEVEL_LANG = verilog
+
+VERILOG_SOURCES += $(shell pwd)/../../../generated/DebuggerModuleTestingBRAM.sv
+VERILOG_SOURCES += $(shell pwd)/../../../generated/InitRegMemFromFile.sv
+VERILOG_SOURCES += $(shell pwd)/../../../generated/DebuggerMain.sv
+VERILOG_SOURCES += $(shell pwd)/../../../generated/SendReceiveSynchronizer.sv
+VERILOG_SOURCES += $(shell pwd)/../../../generated/DebuggerPacketReceiver.sv
+VERILOG_SOURCES += $(shell pwd)/../../../generated/DebuggerPacketSender.sv
+VERILOG_SOURCES += $(shell pwd)/../../../generated/DebuggerPacketInterpreter.sv
+VERILOG_SOURCES += $(shell pwd)/../../../generated/InterpreterInstanceInfo.sv
+VERILOG_SOURCES += $(shell pwd)/../../../generated/InterpreterSendSuccessOrError.sv
+VERILOG_SOURCES += $(shell pwd)/../../../generated/ScriptExecutionEngine.sv
+VERILOG_SOURCES += $(shell pwd)/../../../generated/InterpreterScriptBufferHandler.sv
+VERILOG_SOURCES += $(shell pwd)/../../../generated/ScriptEngineGetValue.sv
+VERILOG_SOURCES += $(shell pwd)/../../../generated/ScriptEngineSetValue.sv
+VERILOG_SOURCES += $(shell pwd)/../../../generated/ScriptEngineEval.sv
+
+TOPLEVEL = DebuggerModuleTestingBRAM
+MODULE = test_DebuggerModuleTestingBRAM
+
+include $(shell cocotb-config --makefiles)/Makefile.sim
\ No newline at end of file
diff --git a/hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/bram_instance_info.txt b/hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/bram_instance_info.txt
new file mode 100644
index 00000000..f84b6a6e
--- /dev/null
+++ b/hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/bram_instance_info.txt
@@ -0,0 +1,261 @@
+Content of BRAM after emulation:
+
+PS to PL area:
+mem_0: 0000005a | Checksum
+mem_1: 00000000 | Checksum
+mem_2: 52444247 | Indicator
+mem_3: 48595045 | Indicator
+mem_4: 00000004 | TypeOfThePacket
+mem_5: 00000001 | RequestedActionOfThePacket
+mem_6: 00000000 | Start of Optional Data
+mem_7: 00000000
+mem_8: 00000000
+mem_9: 00000000
+mem_10: 00000000
+mem_11: 00000000
+mem_12: 00000000
+mem_13: 00000000
+mem_14: 00000000
+mem_15: 00000000
+mem_16: 00000000
+mem_17: 00000000
+mem_18: 00000000
+mem_19: 00000000
+mem_20: 00000000
+mem_21: 00000000
+mem_22: 00000000
+mem_23: 00000000
+mem_24: 00000000
+mem_25: 00000000
+mem_26: 00000000
+mem_27: 00000000
+mem_28: 00000000
+mem_29: 00000000
+mem_30: 00000000
+mem_31: 00000000
+mem_32: 00000000
+mem_33: 00000000
+mem_34: 00000000
+mem_35: 00000000
+mem_36: 00000000
+mem_37: 00000000
+mem_38: 00000000
+mem_39: 00000000
+mem_40: 00000000
+mem_41: 00000000
+mem_42: 00000000
+mem_43: 00000000
+mem_44: 00000000
+mem_45: 00000000
+mem_46: 00000000
+mem_47: 00000000
+mem_48: 00000000
+mem_49: 00000000
+mem_50: 00000000
+mem_51: 00000000
+mem_52: 00000000
+mem_53: 00000000
+mem_54: 00000000
+mem_55: 00000000
+mem_56: 00000000
+mem_57: 00000000
+mem_58: 00000000
+mem_59: 00000000
+mem_60: 00000000
+mem_61: 00000000
+mem_62: 00000000
+mem_63: 00000000
+mem_64: 00000000
+mem_65: 00000000
+mem_66: 00000000
+mem_67: 00000000
+mem_68: 00000000
+mem_69: 00000000
+mem_70: 00000000
+mem_71: 00000000
+mem_72: 00000000
+mem_73: 00000000
+mem_74: 00000000
+mem_75: 00000000
+mem_76: 00000000
+mem_77: 00000000
+mem_78: 00000000
+mem_79: 00000000
+mem_80: 00000000
+mem_81: 00000000
+mem_82: 00000000
+mem_83: 00000000
+mem_84: 00000000
+mem_85: 00000000
+mem_86: 00000000
+mem_87: 00000000
+mem_88: 00000000
+mem_89: 00000000
+mem_90: 00000000
+mem_91: 00000000
+mem_92: 00000000
+mem_93: 00000000
+mem_94: 00000000
+mem_95: 00000000
+mem_96: 00000000
+mem_97: 00000000
+mem_98: 00000000
+mem_99: 00000000
+mem_100: 00000000
+mem_101: 00000000
+mem_102: 00000000
+mem_103: 00000000
+mem_104: 00000000
+mem_105: 00000000
+mem_106: 00000000
+mem_107: 00000000
+mem_108: 00000000
+mem_109: 00000000
+mem_110: 00000000
+mem_111: 00000000
+mem_112: 00000000
+mem_113: 00000000
+mem_114: 00000000
+mem_115: 00000000
+mem_116: 00000000
+mem_117: 00000000
+mem_118: 00000000
+mem_119: 00000000
+mem_120: 00000000
+mem_121: 00000000
+mem_122: 00000000
+mem_123: 00000000
+mem_124: 00000000
+mem_125: 00000000
+mem_126: 00000000
+mem_127: 00000000
+
+PL to PS area:
+mem_128: 00000000 | Checksum
+mem_129: 00000000 | Checksum
+mem_130: 52444247 | Indicator
+mem_131: 48595045 | Indicator
+mem_132: 00000005 | TypeOfThePacket
+mem_133: 00000002 | RequestedActionOfThePacket
+mem_134: 00000100 | Start of Optional Data
+mem_135: 00000020
+mem_136: 00000008
+mem_137: 00000002
+mem_138: 00000002
+mem_139: 00000002
+mem_140: 00000001
+mem_141: 00000400
+mem_142: 00000000
+mem_143: 00000200
+mem_144: 00000020
+mem_145: 00000002
+mem_146: 01ff9efb
+mem_147: 00000000
+mem_148: 0000000d
+mem_149: 00000020
+mem_150: 0000000c
+mem_151: 00000014
+mem_152: 00000000
+mem_153: 00000000
+mem_154: 00000000
+mem_155: 00000000
+mem_156: 00000000
+mem_157: 00000000
+mem_158: 00000000
+mem_159: 00000000
+mem_160: 00000000
+mem_161: 00000000
+mem_162: 00000000
+mem_163: 00000000
+mem_164: 00000000
+mem_165: 00000000
+mem_166: 00000000
+mem_167: 00000000
+mem_168: 00000000
+mem_169: 00000000
+mem_170: 00000000
+mem_171: 00000000
+mem_172: 00000000
+mem_173: 00000000
+mem_174: 00000000
+mem_175: 00000000
+mem_176: 00000000
+mem_177: 00000000
+mem_178: 00000000
+mem_179: 00000000
+mem_180: 00000000
+mem_181: 00000000
+mem_182: 00000000
+mem_183: 00000000
+mem_184: 00000000
+mem_185: 00000000
+mem_186: 00000000
+mem_187: 00000000
+mem_188: 00000000
+mem_189: 00000000
+mem_190: 00000000
+mem_191: 00000000
+mem_192: 00000000
+mem_193: 00000000
+mem_194: 00000000
+mem_195: 00000000
+mem_196: 00000000
+mem_197: 00000000
+mem_198: 00000000
+mem_199: 00000000
+mem_200: 00000000
+mem_201: 00000000
+mem_202: 00000000
+mem_203: 00000000
+mem_204: 00000000
+mem_205: 00000000
+mem_206: 00000000
+mem_207: 00000000
+mem_208: 00000000
+mem_209: 00000000
+mem_210: 00000000
+mem_211: 00000000
+mem_212: 00000000
+mem_213: 00000000
+mem_214: 00000000
+mem_215: 00000000
+mem_216: 00000000
+mem_217: 00000000
+mem_218: 00000000
+mem_219: 00000000
+mem_220: 00000000
+mem_221: 00000000
+mem_222: 00000000
+mem_223: 00000000
+mem_224: 00000000
+mem_225: 00000000
+mem_226: 00000000
+mem_227: 00000000
+mem_228: 00000000
+mem_229: 00000000
+mem_230: 00000000
+mem_231: 00000000
+mem_232: 00000000
+mem_233: 00000000
+mem_234: 00000000
+mem_235: 00000000
+mem_236: 00000000
+mem_237: 00000000
+mem_238: 00000000
+mem_239: 00000000
+mem_240: 00000000
+mem_241: 00000000
+mem_242: 00000000
+mem_243: 00000000
+mem_244: 00000000
+mem_245: 00000000
+mem_246: 00000000
+mem_247: 00000000
+mem_248: 00000000
+mem_249: 00000000
+mem_250: 00000000
+mem_251: 00000000
+mem_252: 00000000
+mem_253: 00000000
+mem_254: 00000000
+mem_255: 00000000
diff --git a/hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/script_buffer_response.txt b/hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/script_buffer_response.txt
new file mode 100644
index 00000000..3c75ec44
--- /dev/null
+++ b/hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/script_buffer_response.txt
@@ -0,0 +1,261 @@
+Content of BRAM after emulation:
+
+PS to PL area:
+mem_0: 00000017 | Checksum
+mem_1: 00000000 | Checksum
+mem_2: 52444247 | Indicator
+mem_3: 48595045 | Indicator
+mem_4: 00000004 | TypeOfThePacket
+mem_5: 00000002 | RequestedActionOfThePacket
+mem_6: 00000033 | Start of Optional Data
+mem_7: 00000006
+mem_8: 0000000a
+mem_9: 00000003
+mem_10: 00000001
+mem_11: 0000000f
+mem_12: 00000000
+mem_13: 0000000f
+mem_14: 00000000
+mem_15: 00000006
+mem_16: 00000013
+mem_17: 00000003
+mem_18: 00000001
+mem_19: 00000004
+mem_20: 00000000
+mem_21: 00000007
+mem_22: 00000000
+mem_23: 00000006
+mem_24: 00000016
+mem_25: 00000003
+mem_26: 00000013
+mem_27: 00000007
+mem_28: 00000000
+mem_29: 00000000
+mem_30: 00000000
+mem_31: 00000006
+mem_32: 00000018
+mem_33: 00000003
+mem_34: 00000000
+mem_35: 00000000
+mem_36: 00000000
+mem_37: 00000004
+mem_38: 00000002
+mem_39: 00000006
+mem_40: 00000018
+mem_41: 00000003
+mem_42: 00000000
+mem_43: 00000000
+mem_44: 00000000
+mem_45: 00000004
+mem_46: 00000003
+mem_47: 00000006
+mem_48: 00000015
+mem_49: 00000003
+mem_50: 00000028
+mem_51: 00000000
+mem_52: 00000000
+mem_53: 00000000
+mem_54: 00000000
+mem_55: 00000006
+mem_56: 00000013
+mem_57: 00000003
+mem_58: 00000001
+mem_59: 00000004
+mem_60: 00000001
+mem_61: 00000007
+mem_62: 00000000
+mem_63: 00000006
+mem_64: 00000016
+mem_65: 00000003
+mem_66: 00000022
+mem_67: 00000007
+mem_68: 00000000
+mem_69: 00000000
+mem_70: 00000000
+mem_71: 00000006
+mem_72: 00000018
+mem_73: 00000003
+mem_74: 00000000
+mem_75: 00000000
+mem_76: 00000000
+mem_77: 00000004
+mem_78: 00000004
+mem_79: 00000006
+mem_80: 00000018
+mem_81: 00000003
+mem_82: 00000000
+mem_83: 00000000
+mem_84: 00000000
+mem_85: 00000004
+mem_86: 00000005
+mem_87: 00000006
+mem_88: 00000015
+mem_89: 00000003
+mem_90: 00000028
+mem_91: 00000000
+mem_92: 00000000
+mem_93: 00000000
+mem_94: 00000000
+mem_95: 00000006
+mem_96: 00000018
+mem_97: 00000003
+mem_98: 00000000
+mem_99: 00000000
+mem_100: 00000000
+mem_101: 00000004
+mem_102: 00000006
+mem_103: 00000006
+mem_104: 00000018
+mem_105: 00000003
+mem_106: 00000000
+mem_107: 00000000
+mem_108: 00000000
+mem_109: 00000004
+mem_110: 00000007
+mem_111: 00000000
+mem_112: 00000000
+mem_113: 00000000
+mem_114: 00000000
+mem_115: 00000000
+mem_116: 00000000
+mem_117: 00000000
+mem_118: 00000000
+mem_119: 00000000
+mem_120: 00000000
+mem_121: 00000000
+mem_122: 00000000
+mem_123: 00000000
+mem_124: 00000000
+mem_125: 00000000
+mem_126: 00000000
+mem_127: 00000000
+
+PL to PS area:
+mem_128: 00000000 | Checksum
+mem_129: 00000000 | Checksum
+mem_130: 52444247 | Indicator
+mem_131: 48595045 | Indicator
+mem_132: 00000005 | TypeOfThePacket
+mem_133: 00000001 | RequestedActionOfThePacket
+mem_134: 7fffffff | Start of Optional Data
+mem_135: 00000000
+mem_136: 00000000
+mem_137: 00000000
+mem_138: 00000000
+mem_139: 00000000
+mem_140: 00000000
+mem_141: 00000000
+mem_142: 00000000
+mem_143: 00000000
+mem_144: 00000000
+mem_145: 00000000
+mem_146: 00000000
+mem_147: 00000000
+mem_148: 00000000
+mem_149: 00000000
+mem_150: 00000000
+mem_151: 00000000
+mem_152: 00000000
+mem_153: 00000000
+mem_154: 00000000
+mem_155: 00000000
+mem_156: 00000000
+mem_157: 00000000
+mem_158: 00000000
+mem_159: 00000000
+mem_160: 00000000
+mem_161: 00000000
+mem_162: 00000000
+mem_163: 00000000
+mem_164: 00000000
+mem_165: 00000000
+mem_166: 00000000
+mem_167: 00000000
+mem_168: 00000000
+mem_169: 00000000
+mem_170: 00000000
+mem_171: 00000000
+mem_172: 00000000
+mem_173: 00000000
+mem_174: 00000000
+mem_175: 00000000
+mem_176: 00000000
+mem_177: 00000000
+mem_178: 00000000
+mem_179: 00000000
+mem_180: 00000000
+mem_181: 00000000
+mem_182: 00000000
+mem_183: 00000000
+mem_184: 00000000
+mem_185: 00000000
+mem_186: 00000000
+mem_187: 00000000
+mem_188: 00000000
+mem_189: 00000000
+mem_190: 00000000
+mem_191: 00000000
+mem_192: 00000000
+mem_193: 00000000
+mem_194: 00000000
+mem_195: 00000000
+mem_196: 00000000
+mem_197: 00000000
+mem_198: 00000000
+mem_199: 00000000
+mem_200: 00000000
+mem_201: 00000000
+mem_202: 00000000
+mem_203: 00000000
+mem_204: 00000000
+mem_205: 00000000
+mem_206: 00000000
+mem_207: 00000000
+mem_208: 00000000
+mem_209: 00000000
+mem_210: 00000000
+mem_211: 00000000
+mem_212: 00000000
+mem_213: 00000000
+mem_214: 00000000
+mem_215: 00000000
+mem_216: 00000000
+mem_217: 00000000
+mem_218: 00000000
+mem_219: 00000000
+mem_220: 00000000
+mem_221: 00000000
+mem_222: 00000000
+mem_223: 00000000
+mem_224: 00000000
+mem_225: 00000000
+mem_226: 00000000
+mem_227: 00000000
+mem_228: 00000000
+mem_229: 00000000
+mem_230: 00000000
+mem_231: 00000000
+mem_232: 00000000
+mem_233: 00000000
+mem_234: 00000000
+mem_235: 00000000
+mem_236: 00000000
+mem_237: 00000000
+mem_238: 00000000
+mem_239: 00000000
+mem_240: 00000000
+mem_241: 00000000
+mem_242: 00000000
+mem_243: 00000000
+mem_244: 00000000
+mem_245: 00000000
+mem_246: 00000000
+mem_247: 00000000
+mem_248: 00000000
+mem_249: 00000000
+mem_250: 00000000
+mem_251: 00000000
+mem_252: 00000000
+mem_253: 00000000
+mem_254: 00000000
+mem_255: 00000000
diff --git a/hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/test.sh b/hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/test.sh
new file mode 100755
index 00000000..a83ca694
--- /dev/null
+++ b/hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/test.sh
@@ -0,0 +1 @@
+make SIM=icarus WAVES=1
diff --git a/hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/test_DebuggerModuleTestingBRAM.py b/hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/test_DebuggerModuleTestingBRAM.py
new file mode 100644
index 00000000..3d8323e7
--- /dev/null
+++ b/hwdbg/sim/hwdbg/DebuggerModuleTestingBRAM/test_DebuggerModuleTestingBRAM.py
@@ -0,0 +1,570 @@
+##
+# @file test_DebuggerModuleTestingBRAM.py
+#
+# @author Sina Karvandi (sina@hyperdbg.org)
+#
+# @brief Testing module for DebuggerModuleTestingBRAM
+#
+# @details
+#
+# @version 0.1
+#
+# @date 2024-04-21
+#
+# @copyright This project is released under the GNU Public License v3.
+#
+
+import random
+import re
+
+import cocotb
+from cocotb.clock import Clock
+from cocotb.triggers import Timer
+from cocotb.types import LogicArray
+
+maximum_number_of_clock_cycles = 1000
+
+'''
+ input clock,
+ reset,
+ io_en,
+ io_inputPin_0,
+ io_inputPin_1,
+ io_inputPin_2,
+ io_inputPin_3,
+ io_inputPin_4,
+ io_inputPin_5,
+ io_inputPin_6,
+ io_inputPin_7,
+ io_inputPin_8,
+ io_inputPin_9,
+ io_inputPin_10,
+ io_inputPin_11,
+ io_inputPin_12,
+ io_inputPin_13,
+ io_inputPin_14,
+ io_inputPin_15,
+ io_inputPin_16,
+ io_inputPin_17,
+ io_inputPin_18,
+ io_inputPin_19,
+ io_inputPin_20,
+ io_inputPin_21,
+ io_inputPin_22,
+ io_inputPin_23,
+ io_inputPin_24,
+ io_inputPin_25,
+ io_inputPin_26,
+ io_inputPin_27,
+ io_inputPin_28,
+ io_inputPin_29,
+ io_inputPin_30,
+ io_inputPin_31,
+ output io_outputPin_0,
+ io_outputPin_1,
+ io_outputPin_2,
+ io_outputPin_3,
+ io_outputPin_4,
+ io_outputPin_5,
+ io_outputPin_6,
+ io_outputPin_7,
+ io_outputPin_8,
+ io_outputPin_9,
+ io_outputPin_10,
+ io_outputPin_11,
+ io_outputPin_12,
+ io_outputPin_13,
+ io_outputPin_14,
+ io_outputPin_15,
+ io_outputPin_16,
+ io_outputPin_17,
+ io_outputPin_18,
+ io_outputPin_19,
+ io_outputPin_20,
+ io_outputPin_21,
+ io_outputPin_22,
+ io_outputPin_23,
+ io_outputPin_24,
+ io_outputPin_25,
+ io_outputPin_26,
+ io_outputPin_27,
+ io_outputPin_28,
+ io_outputPin_29,
+ io_outputPin_30,
+ io_outputPin_31,
+ input io_plInSignal,
+ output io_psOutInterrupt
+'''
+
+#
+# Define a function to extract the numeric part of the string
+#
+def extract_number(s):
+ return int(s.split('_')[1])
+
+def print_bram_content(dut):
+ """Printing contents of Block RAM and saving them to a file"""
+
+ #
+ # Print the instances and signals (which includes the ports) of the design's toplevel
+ #
+ print("===================================================================")
+ # print("Onstances and signals (which includes the ports) of the design's toplevel:")
+ # print(dir(dut))
+ # print("===================================================================")
+
+ #
+ # Print the instances and signals of "inst_sub_block" under the toplevel
+ # which is the instance name of a Verilog module or VHDL entity/component
+ #
+ # print("Onstances and signals of 'dataOut_initRegMemFromFileModule' under the toplevel:")
+ # print(dir(dut.dataOut_initRegMemFromFileModule))
+
+ items_inside_bram_emulator = dir(dut.dataOut_initRegMemFromFileModule)
+ mem_items = []
+
+ for item in items_inside_bram_emulator:
+ if item.startswith("mem_"):
+ mem_items.append(item)
+
+ #
+ # Sort the list using the custom key function
+ #
+ sorted_list = sorted(mem_items, key=extract_number)
+
+ with open("script_buffer_response.txt", "w") as file:
+ # with open("bram_instance_info.txt", "w") as file:
+ file.write("Content of BRAM after emulation:\n")
+ print("Content of BRAM after emulation:")
+
+ #
+ # The second half of the BRAM is used for PL to PS communication
+ #
+ address_of_ps_to_pl_communication = "mem_0"
+ address_of_ps_to_pl_communication_checksum1 = "mem_0"
+ address_of_ps_to_pl_communication_checksum2 = "mem_1"
+ address_of_ps_to_pl_communication_indicator1 = "mem_2"
+ address_of_ps_to_pl_communication_indicator2 = "mem_3"
+ address_of_ps_to_pl_communication_type_of_packet = "mem_4"
+ address_of_ps_to_pl_communication_requested_action_of_the_packet = "mem_5"
+ address_of_ps_to_pl_communication_start_of_data = "mem_6"
+
+ len_of_sorted_list_div_by_2 = int(len(sorted_list) / 2)
+ address_of_pl_to_ps_communication = "mem_" + str(len_of_sorted_list_div_by_2)
+ address_of_pl_to_ps_communication_checksum1 = "mem_" + str(len_of_sorted_list_div_by_2 + 0)
+ address_of_pl_to_ps_communication_checksum2 = "mem_" + str(len_of_sorted_list_div_by_2 + 1)
+ address_of_pl_to_ps_communication_indicator1 = "mem_" + str(len_of_sorted_list_div_by_2 + 2)
+ address_of_pl_to_ps_communication_indicator2 = "mem_" + str(len_of_sorted_list_div_by_2 + 3)
+ address_of_pl_to_ps_communication_type_of_packet = "mem_" + str(len_of_sorted_list_div_by_2 + 4)
+ address_of_pl_to_ps_communication_requested_action_of_the_packet = "mem_" + str(len_of_sorted_list_div_by_2 + 5)
+ address_of_pl_to_ps_communication_start_of_data = "mem_" + str(len_of_sorted_list_div_by_2 + 6)
+
+ print("Address of PL to PS communication: " + address_of_pl_to_ps_communication)
+
+ for item in sorted_list:
+ element = getattr(dut.dataOut_initRegMemFromFileModule, item)
+
+ #
+ # Print the target register in binary format
+ #
+ # print(str(element))
+
+ #
+ # Convert binary to int
+ #
+ int_content = int(str(element.value), 2)
+
+ #
+ # Convert integer to hexadecimal string with at least 8 characters
+ #
+ hex_string = f'{int_content:08x}'
+
+ final_string = ""
+ if len(item) == 5:
+ final_string = item + ": " + hex_string
+ elif len(item) == 6:
+ final_string = item + ": " + hex_string
+ else:
+ final_string = item + ": " + hex_string
+
+ #
+ # Make a separation between PS and PL area
+ #
+ if item == address_of_ps_to_pl_communication:
+ file.write("\nPS to PL area:\n")
+ print("\nPS to PL area:")
+ elif item == address_of_pl_to_ps_communication:
+ file.write("\nPL to PS area:\n")
+ print("\nPL to PS area:")
+
+ if item == address_of_ps_to_pl_communication_checksum1 or \
+ item == address_of_ps_to_pl_communication_checksum2 or \
+ item == address_of_pl_to_ps_communication_checksum1 or \
+ item == address_of_pl_to_ps_communication_checksum2:
+ final_string = final_string + " | Checksum"
+ elif item == address_of_ps_to_pl_communication_indicator1 or \
+ item == address_of_ps_to_pl_communication_indicator2 or \
+ item == address_of_pl_to_ps_communication_indicator1 or \
+ item == address_of_pl_to_ps_communication_indicator2:
+ final_string = final_string + " | Indicator"
+ elif item == address_of_ps_to_pl_communication_type_of_packet or \
+ item == address_of_pl_to_ps_communication_type_of_packet:
+ final_string = final_string + " | TypeOfThePacket"
+ elif item == address_of_ps_to_pl_communication_requested_action_of_the_packet or \
+ item == address_of_pl_to_ps_communication_requested_action_of_the_packet:
+ final_string = final_string + " | RequestedActionOfThePacket"
+ elif item == address_of_ps_to_pl_communication_start_of_data or \
+ item == address_of_pl_to_ps_communication_start_of_data:
+ final_string = final_string + " | Start of Optional Data"
+
+ #
+ # Print contents of BRAM
+ #
+ file.write(final_string + "\n")
+ print(final_string)
+
+ print("\n===================================================================\n")
+
+
+#
+# Define a function to extract value of symbol
+#
+def get_symbol_value(dut, value):
+ element_value = getattr(dut.debuggerMainModule.outputPin_scriptExecutionEngineModule, value)
+ hex_string_value = ""
+ try:
+ int_content_value = int(str(element_value.value), 2)
+ hex_string_value = f'{int_content_value:x}'
+ except:
+ hex_string_value = str(element_value.value)
+
+ final_string_value = f'{value}: 0x{hex_string_value}' + " (bin: " + str(element_value.value) + ")"
+ return final_string_value
+
+#
+# Define a function to extract type of symbol
+#
+def get_symbol_type(dut, type):
+ element_type = getattr(dut.debuggerMainModule.outputPin_scriptExecutionEngineModule, type)
+ hex_string_type = ""
+ try:
+ int_content_type = int(str(element_type.value), 2)
+ hex_string_type = f'{int_content_type:x}'
+ except:
+ hex_string_type = str(element_type.value)
+
+ final_string_type = f'{type} : 0x{hex_string_type}' + " (bin: " + str(element_type.value) + ")"
+ return final_string_type
+
+#
+# Define a function to extract stage index
+#
+def get_stage_index(dut, stage_index):
+ stage_index_str = "stageRegs_" + str(stage_index) + "_stageIndex"
+ element_stage_index = getattr(dut.debuggerMainModule.outputPin_scriptExecutionEngineModule, stage_index_str)
+ hex_string_stage_index = ""
+ try:
+ int_content_stage_index = int(str(element_stage_index.value), 2)
+ hex_string_stage_index = f'{int_content_stage_index:x}'
+ except:
+ hex_string_stage_index = str(element_stage_index.value)
+
+ final_string_stage_index = f'{stage_index}: 0x{hex_string_stage_index}' + " (bin: " + str(element_stage_index.value) + ")"
+ return final_string_stage_index
+
+#
+# Define a function to extract content of stages
+#
+def extract_stage_details(dut):
+
+ print("Script Stage Registers Configuration:\n")
+ all_elements = dir(dut.debuggerMainModule.outputPin_scriptExecutionEngineModule)
+
+ #
+ # Define the pattern to match
+ #
+ pattern_value = re.compile(r'stageRegs_\d+_stageSymbol_Value')
+ pattern_type = re.compile(r'stageRegs_\d+_stageSymbol_Type')
+ pattern_stage_index = re.compile(r'stageRegs_\d+_stageIndex')
+
+ #
+ # Filter the list using the patterns
+ #
+ filtered_strings_values = [s for s in all_elements if pattern_value.match(s)]
+ filtered_strings_types = [s for s in all_elements if pattern_type.match(s)]
+ filtered_strings_stage_index = [s for s in all_elements if pattern_stage_index.match(s)]
+
+ #
+ # Sort the lists
+ #
+ sorted_values = sorted(filtered_strings_values, key=extract_number)
+ sorted_types = sorted(filtered_strings_types, key=extract_number)
+ sorted_stage_index = sorted(filtered_strings_stage_index, key=extract_number)
+
+ #
+ # Print the filtered strings
+ #
+ # print(sorted_values)
+ # print(sorted_types)
+ # print(sorted_stage_index)
+
+ for index, element in enumerate(sorted_values):
+
+ try:
+ final_string_type = get_symbol_type(dut, sorted_types[index])
+
+ #
+ # Print the type
+ #
+ print(final_string_type)
+ except:
+ print("This stage does not contain a 'type'")
+
+ try:
+ final_string_value = get_symbol_value(dut, sorted_values[index])
+
+ #
+ # Print the value
+ #
+ print(final_string_value)
+ except:
+ print("Unable to get stage 'value' configuration details")
+
+ try:
+ final_string_stage_index = get_stage_index(dut, index)
+
+ #
+ # Print the stage index
+ #
+ print("index: " + final_string_stage_index)
+
+ except:
+ print("index: " + str(index) +": This stage does not contain a 'stage index'")
+
+ print("\n")
+
+
+ #
+ # Check stage enable bit
+ #
+ try:
+ stage_enabled = "stageRegs_" + str(index) + "_stageEnable"
+ is_stage_enabled = getattr(dut.debuggerMainModule.outputPin_scriptExecutionEngineModule, stage_enabled)
+ print("\t Stage enabled bit: " + str(is_stage_enabled))
+ except:
+ print("\t Stage enabled bit: (unavailable)")
+
+ try:
+ final_string_value = get_symbol_value(dut, "stageRegs_" + str(index) + "_getOperatorSymbol_0_Value")
+ final_string_type = get_symbol_type(dut, "stageRegs_" + str(index) + "_getOperatorSymbol_0_Type")
+
+ print("\t Get (0) | " + final_string_type)
+ print("\t Get (0) | " + final_string_value)
+ except:
+ print("\t stage at:" + str(index) + " does not contain a Get (0) buffer")
+
+ print("\n")
+
+ try:
+ final_string_value = get_symbol_value(dut, "stageRegs_" + str(index) + "_getOperatorSymbol_1_Value")
+ final_string_type = get_symbol_type(dut, "stageRegs_" + str(index) + "_getOperatorSymbol_1_Type")
+
+ print("\t Get (1) | " + final_string_type)
+ print("\t Get (1) | " + final_string_value)
+ except:
+ print("\t stage at:" + str(index) + " does not contain a Get (1) buffer")
+
+ print("\n")
+
+ try:
+ final_string_value = get_symbol_value(dut, "stageRegs_" + str(index) + "_setOperatorSymbol_0_Value")
+ final_string_type = get_symbol_type(dut, "stageRegs_" + str(index) + "_setOperatorSymbol_0_Type")
+
+ print("\t Set (0) | " + final_string_type)
+ print("\t Set (0) | " + final_string_value)
+ except:
+ print("\t stage at:" + str(index) + " does not contain a Set (0) buffer")
+
+ print("\n\n")
+
+def set_input_pins(dut):
+ dut.io_inputPin_0.value = 1
+ dut.io_inputPin_1.value = 1
+ dut.io_inputPin_2.value = 1
+ dut.io_inputPin_3.value = 1
+ dut.io_inputPin_4.value = 1
+ dut.io_inputPin_5.value = 1
+ dut.io_inputPin_6.value = 1
+ dut.io_inputPin_7.value = 1
+ dut.io_inputPin_8.value = 1
+ dut.io_inputPin_9.value = 1
+ dut.io_inputPin_10.value = 1
+ dut.io_inputPin_11.value = 1
+ dut.io_inputPin_12.value = 1
+ dut.io_inputPin_13.value = 1
+ dut.io_inputPin_14.value = 1
+ dut.io_inputPin_15.value = 1
+ dut.io_inputPin_16.value = 1
+ dut.io_inputPin_17.value = 1
+ dut.io_inputPin_18.value = 1
+ dut.io_inputPin_19.value = 1
+ dut.io_inputPin_20.value = 1
+ dut.io_inputPin_21.value = 1
+ dut.io_inputPin_22.value = 1
+ dut.io_inputPin_23.value = 1
+ dut.io_inputPin_24.value = 1
+ dut.io_inputPin_25.value = 1
+ dut.io_inputPin_26.value = 1
+ dut.io_inputPin_27.value = 1
+ dut.io_inputPin_28.value = 1
+ dut.io_inputPin_29.value = 1
+ dut.io_inputPin_30.value = 1
+ dut.io_inputPin_31.value = 1
+
+@cocotb.test()
+async def DebuggerModuleTestingBRAM_test(dut):
+ """Test hwdbg module (with pre-defined BRAM)"""
+
+ #
+ # Assert initial output is unknown
+ #
+ assert LogicArray(dut.io_outputPin_0.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_1.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_2.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_3.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_4.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_5.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_6.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_7.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_8.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_9.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_10.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_11.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_12.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_13.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_14.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_15.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_16.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_17.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_18.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_19.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_20.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_21.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_22.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_23.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_24.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_25.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_26.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_27.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_28.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_29.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_30.value) == LogicArray("X")
+ assert LogicArray(dut.io_outputPin_31.value) == LogicArray("X")
+
+ #
+ # Create a 10ns period clock on port clock
+ #
+ clock = Clock(dut.clock, 10, units="ns")
+
+ #
+ # Start the clock. Start it low to avoid issues on the first RisingEdge
+ #
+ cocotb.start_soon(clock.start(start_high=False))
+
+ dut._log.info("Initialize and reset module")
+
+ #
+ # Initial values
+ #
+ dut.io_en.value = 0
+ dut.io_plInSignal.value = 0
+
+ #
+ # Reset DUT
+ #
+ dut.reset.value = 1
+ for _ in range(10):
+ await Timer(10, units="ns")
+ dut.reset.value = 0
+
+
+ dut._log.info("Enabling an interrupting chip to receive commands from BRAM")
+
+ #
+ # Enable chip
+ #
+ dut.io_en.value = 1
+
+ #
+ # Set initial input value to prevent it from floating
+ #
+ dut._log.info("Initializing input pins")
+ # set_input_pins(dut)
+
+ #
+ # Tell the hwdbg to receive BRAM results
+ #
+ dut.io_plInSignal.value = 1
+ await Timer(10, units="ns")
+ dut.io_plInSignal.value = 0
+
+ #
+ # Synchronize with the clock. This will regisiter the initial `inputPinX` value
+ #
+ await Timer(10, units="ns")
+
+ #
+ # Wait until the debuggee sends an interrupt to debugger
+ #
+ clock_counter = 0
+ interrupt_not_delivered = False
+
+ while str(dut.io_psOutInterrupt) != "1":
+
+ # print("State of interrupt: '" + str(dut.io_psOutInterrupt) + "'")
+
+ if clock_counter % 10 == 0:
+ print("Number of clock cycles spent in debuggee (PL): " + str(clock_counter))
+
+ clock_counter = clock_counter + 1
+ await Timer(10, units="ns")
+
+ #
+ # Apply a limitation to the number of clock cycles that
+ # can be executed to avoid infinite time
+ #
+ if (clock_counter >= maximum_number_of_clock_cycles):
+ interrupt_not_delivered = True
+ break
+
+ #
+ # Being here means either the debuggee sent an interrupt to the PS
+ # or the maximum clock cycles reached
+ #
+ if interrupt_not_delivered:
+ print("Maximum clock cycles reached")
+ else:
+ print("Debuggee (PL) interrupted Debugger (PS)")
+
+ #
+ # Run one more clock cycle to apply the latest BRAM modifications
+ #
+ await Timer(10, units="ns")
+
+ #
+ # Print contents of BRAM
+ #
+ print_bram_content(dut)
+
+ #
+ # Print the script stage configuration
+ #
+ extract_stage_details(dut)
+
+ #
+ # Check the final input on the next clock and run the circuit for a couple
+ # of more clock cycles
+ #
+ for _ in range(100):
+ set_input_pins(dut)
+ await Timer(10, units="ns")
diff --git a/hwdbg/sim/hwdbg/communication/DebuggerPacketReceiver/Makefile b/hwdbg/sim/hwdbg/communication/DebuggerPacketReceiver/Makefile
new file mode 100644
index 00000000..8678f015
--- /dev/null
+++ b/hwdbg/sim/hwdbg/communication/DebuggerPacketReceiver/Makefile
@@ -0,0 +1,8 @@
+# Makefile
+
+TOPLEVEL_LANG = verilog
+VERILOG_SOURCES = $(shell pwd)/../../../../generated/DebuggerPacketReceiver.sv
+TOPLEVEL = DebuggerPacketReceiver
+MODULE = test_DebuggerPacketReceiver
+
+include $(shell cocotb-config --makefiles)/Makefile.sim
diff --git a/hwdbg/sim/hwdbg/communication/DebuggerPacketReceiver/test.sh b/hwdbg/sim/hwdbg/communication/DebuggerPacketReceiver/test.sh
new file mode 100644
index 00000000..a83ca694
--- /dev/null
+++ b/hwdbg/sim/hwdbg/communication/DebuggerPacketReceiver/test.sh
@@ -0,0 +1 @@
+make SIM=icarus WAVES=1
diff --git a/hwdbg/sim/hwdbg/communication/DebuggerPacketReceiver/test_DebuggerPacketReceiver.py b/hwdbg/sim/hwdbg/communication/DebuggerPacketReceiver/test_DebuggerPacketReceiver.py
new file mode 100644
index 00000000..e3c19085
--- /dev/null
+++ b/hwdbg/sim/hwdbg/communication/DebuggerPacketReceiver/test_DebuggerPacketReceiver.py
@@ -0,0 +1,187 @@
+##
+# @file test_DebuggerPacketReceiver.py
+#
+# @author Sina Karvandi (sina@hyperdbg.org)
+#
+# @brief Testing module for DebuggerPacketReceiver
+#
+# @details
+#
+# @version 0.1
+#
+# @date 2024-04-22
+#
+# @copyright This project is released under the GNU Public License v3.
+#
+
+import random
+
+import cocotb
+from cocotb.clock import Clock
+from cocotb.triggers import Timer
+from cocotb.types import LogicArray
+
+'''
+ input clock,
+ reset,
+ io_en,
+ io_plInSignal,
+ output [12:0] io_rdWrAddr,
+ input [31:0] io_rdData,
+ output [31:0] io_requestedActionOfThePacketOutput,
+ output io_requestedActionOfThePacketOutputValid,
+ input io_noNewDataReceiver,
+ io_readNextData,
+ output io_dataValidOutput,
+ output [31:0] io_receivingData,
+ output io_finishedReceivingBuffer
+'''
+
+@cocotb.test()
+async def DebuggerPacketReceiver_test(dut):
+ """Test DebuggerPacketReceiver module"""
+
+ #
+ # Assert initial output is unknown
+ #
+ assert LogicArray(dut.io_rdWrAddr.value) == LogicArray("XXXXXXXXXXXXX")
+ assert LogicArray(dut.io_requestedActionOfThePacketOutput.value) == LogicArray("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
+ assert LogicArray(dut.io_requestedActionOfThePacketOutputValid.value) == LogicArray("X")
+ assert LogicArray(dut.io_dataValidOutput.value) == LogicArray("X")
+ assert LogicArray(dut.io_receivingData.value) == LogicArray("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
+ assert LogicArray(dut.io_finishedReceivingBuffer.value) == LogicArray("X")
+
+ clock = Clock(dut.clock, 10, units="ns") # Create a 10ns period clock on port clock
+
+ #
+ # Start the clock. Start it low to avoid issues on the first RisingEdge
+ #
+ cocotb.start_soon(clock.start(start_high=False))
+
+ dut._log.info("Initialize and reset module")
+
+ #
+ # Initial values
+ #
+ dut.io_en.value = 0
+ dut.io_readNextData.value = 0
+ dut.io_noNewDataReceiver.value = 0
+ dut.io_plInSignal.value = 0
+
+ #
+ # Reset DUT
+ #
+ dut.reset.value = 1
+ for _ in range(10):
+ await Timer(10, units="ns")
+ dut.reset.value = 0
+
+ dut._log.info("Enabling chip")
+
+ #
+ # Enable chip
+ #
+ dut.io_en.value = 1
+
+ for test_number in range(10):
+
+ dut._log.info("Enable receiving data on the chip (" + str(test_number) + ")")
+
+ #
+ # Tell the receiver to start receiving data (This mainly operates based on
+ # a rising-edge detector, so we'll need to make it low)
+ #
+ dut.io_plInSignal.value = 1
+ await Timer(10, units="ns")
+ dut.io_plInSignal.value = 0
+
+ #
+ # Wait until the receive operation is done (finished)
+ #
+ for i in range(30):
+
+ if (dut.io_finishedReceivingBuffer.value == 1):
+ break
+ else:
+ match dut.io_rdWrAddr.value:
+ case 0x0: # checksum
+ dut.io_rdData.value = 0x00001234
+ case 0x8: # indicator
+ dut.io_rdData.value = 0x48595045 # first 32 bits of the indicator
+ case 0x10: # type
+ dut.io_rdData.value = 0x4 # debugger to hardware packet (DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL)
+ case 0x14: # requested action
+ dut.io_rdData.value = 0x14141414
+ case 0x18: # General output
+ dut.io_rdData.value = 0x18181818
+ case 0x1c: # General output
+ dut.io_rdData.value = 0x1c1c1c1c
+ case 0x20: # General output
+ dut.io_rdData.value = 0x20202020
+ case 0x24: # General output
+ dut.io_rdData.value = 0x24242424
+ case 0x28: # General output
+ dut.io_rdData.value = 0x28282828
+ case 0x2c: # General output
+ dut.io_rdData.value = 0x2c2c2c2c
+ case 0x30: # General output
+ dut.io_rdData.value = 0x30303030
+ case 0x34: # General output
+ dut.io_rdData.value = 0x34343434
+ case 0x38: # General output
+ dut.io_rdData.value = 0x38383838
+ case 0x3c: # General output
+ dut.io_rdData.value = 0x3c3c3c3c
+ case 0x40: # General output
+ dut.io_rdData.value = 0x40404040
+ case 0x44: # General output
+ dut.io_rdData.value = 0x44444444
+ case 0x48: # General output
+ dut.io_rdData.value = 0x48484848
+ case 0x4c: # General output
+ dut.io_rdData.value = 0x4c4c4c4c
+ case 0x50: # General output
+ dut.io_rdData.value = 0x50505050
+ case _:
+ assert "invalid address in the address line"
+
+ if dut.io_requestedActionOfThePacketOutputValid.value == 1:
+
+ #
+ # No new data needed to be received
+ #
+ if test_number % 3 == 0:
+ dut.io_noNewDataReceiver.value = 1
+ await Timer(10, units="ns")
+ dut.io_noNewDataReceiver.value = 0
+ else:
+ #
+ # Make change to the io_readNextData signal as it operates mainly
+ # based on a rising-edge detector
+ #
+ if dut.io_readNextData.value == 0:
+ dut.io_readNextData.value = 1
+ else:
+ dut.io_readNextData.value = 0
+
+
+ #
+ # Go to the next clock cycle
+ #
+ await Timer(10, units="ns")
+
+ if test_number % 3 != 0:
+ dut.io_noNewDataReceiver.value = 1
+ await Timer(10, units="ns")
+ dut.io_noNewDataReceiver.value = 0
+
+ #
+ # Run extra waiting clocks
+ #
+ for _ in range(10):
+ await Timer(10, units="ns")
+
+ #
+ # Check the final input on the next clock
+ #
+ await Timer(10, units="ns")
diff --git a/hwdbg/sim/hwdbg/communication/DebuggerPacketSender/Makefile b/hwdbg/sim/hwdbg/communication/DebuggerPacketSender/Makefile
new file mode 100644
index 00000000..16ee52f3
--- /dev/null
+++ b/hwdbg/sim/hwdbg/communication/DebuggerPacketSender/Makefile
@@ -0,0 +1,8 @@
+# Makefile
+
+TOPLEVEL_LANG = verilog
+VERILOG_SOURCES = $(shell pwd)/../../../../generated/DebuggerPacketSender.sv
+TOPLEVEL = DebuggerPacketSender
+MODULE = test_DebuggerPacketSender
+
+include $(shell cocotb-config --makefiles)/Makefile.sim
diff --git a/hwdbg/sim/hwdbg/communication/DebuggerPacketSender/test.sh b/hwdbg/sim/hwdbg/communication/DebuggerPacketSender/test.sh
new file mode 100644
index 00000000..a83ca694
--- /dev/null
+++ b/hwdbg/sim/hwdbg/communication/DebuggerPacketSender/test.sh
@@ -0,0 +1 @@
+make SIM=icarus WAVES=1
diff --git a/hwdbg/sim/hwdbg/communication/DebuggerPacketSender/test_DebuggerPacketSender.py b/hwdbg/sim/hwdbg/communication/DebuggerPacketSender/test_DebuggerPacketSender.py
new file mode 100644
index 00000000..f2b77f1f
--- /dev/null
+++ b/hwdbg/sim/hwdbg/communication/DebuggerPacketSender/test_DebuggerPacketSender.py
@@ -0,0 +1,165 @@
+##
+# @file test_DebuggerPacketSender.py
+#
+# @author Sina Karvandi (sina@hyperdbg.org)
+#
+# @brief Testing module for DebuggerPacketSender
+#
+# @details
+#
+# @version 0.1
+#
+# @date 2024-04-21
+#
+# @copyright This project is released under the GNU Public License v3.
+#
+
+import random
+
+import cocotb
+from cocotb.clock import Clock
+from cocotb.triggers import Timer
+from cocotb.types import LogicArray
+
+'''
+ input clock,
+ reset,
+ io_en,
+ output io_psOutInterrupt,
+ output [12:0] io_rdWrAddr,
+ output io_wrEna,
+ output [31:0] io_wrData,
+ input io_beginSendingBuffer,
+ io_noNewDataSender,
+ io_dataValidInput,
+ output io_sendWaitForBuffer,
+ io_finishedSendingBuffer,
+ input [31:0] io_requestedActionOfThePacketInput,
+ io_sendingData
+'''
+
+@cocotb.test()
+async def DebuggerPacketSender_test(dut):
+ """Test DebuggerPacketSender module"""
+
+ #
+ # Assert initial output is unknown
+ #
+ assert LogicArray(dut.io_psOutInterrupt.value) == LogicArray("X")
+ assert LogicArray(dut.io_rdWrAddr.value) == LogicArray("XXXXXXXXXXXXX")
+ assert LogicArray(dut.io_wrEna.value) == LogicArray("X")
+ assert LogicArray(dut.io_wrData.value) == LogicArray("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
+ assert LogicArray(dut.io_sendWaitForBuffer.value) == LogicArray("X")
+ assert LogicArray(dut.io_finishedSendingBuffer.value) == LogicArray("X")
+
+ clock = Clock(dut.clock, 10, units="ns") # Create a 10ns period clock on port clock
+
+ #
+ # Start the clock. Start it low to avoid issues on the first RisingEdge
+ #
+ cocotb.start_soon(clock.start(start_high=False))
+
+ dut._log.info("Initialize and reset module")
+
+ #
+ # Initial values
+ #
+ dut.io_en.value = 0
+ dut.io_beginSendingBuffer.value = 0
+
+ #
+ # Reset DUT
+ #
+ dut.reset.value = 1
+ for _ in range(10):
+ await Timer(10, units="ns")
+ dut.reset.value = 0
+
+ dut._log.info("Enabling chip")
+
+ #
+ # Enable chip
+ #
+ dut.io_en.value = 1
+
+ for test_number in range(10):
+
+ dut._log.info("Enable sending data on the chip (" + str(test_number) + ")")
+
+ #
+ # Still there is data to send
+ #
+ dut.io_noNewDataSender.value = 0
+
+ #
+ # Tell the sender to start sending data (This mainly operates based on
+ # a rising-edge detector, so we'll need to make it low)
+ #
+ dut.io_beginSendingBuffer.value = 1
+ await Timer(10, units="ns")
+ dut.io_beginSendingBuffer.value = 0
+
+ #
+ # No new data at this stage
+ #
+ dut.io_dataValidInput.value = 0
+ dut.io_sendingData.value = 0
+
+ #
+ # Adjust the requested action of the packet
+ #
+ dut.io_requestedActionOfThePacketInput.value = 0x55859555
+
+ #
+ # Synchronize with the clock. This will apply the initial values
+ #
+ await Timer(10, units="ns")
+
+ #
+ # This will change the behavior of the data producer to only
+ # generate extra data for 2 of the test case rounds, the third
+ # test case doesn't have any extra data
+ #
+ if test_number % 3 != 0 :
+ #
+ # Run until the module asks for further buffers
+ #
+ for i in range(100):
+ if dut.io_sendWaitForBuffer.value == 1:
+ val = random.randint(0, 0xffffffff)
+
+ #
+ # Indicate that the data is valid
+ #
+ dut.io_dataValidInput.value = 1
+
+ #
+ # Assign the random value to send as the data
+ #
+ dut.io_sendingData.value = val
+
+ await Timer(10, units="ns")
+
+ #
+ # Now, tell the sender module that there is no longer needed to send data
+ #
+ for i in range(100):
+ if dut.io_sendWaitForBuffer.value == 1:
+ dut.io_noNewDataSender.value = 1
+ await Timer(10, units="ns")
+ dut.io_noNewDataSender.value = 0
+ break
+
+ await Timer(10, units="ns")
+
+
+ #
+ # Run extra waiting clocks
+ #
+ for _ in range(10):
+ await Timer(10, units="ns")
+
+ #
+ # Check the final input on the next clock
+ #
+ await Timer(10, units="ns")
diff --git a/hwdbg/sim/hwdbg/communication/SendReceiveSynchronizer/Makefile b/hwdbg/sim/hwdbg/communication/SendReceiveSynchronizer/Makefile
new file mode 100644
index 00000000..425db36d
--- /dev/null
+++ b/hwdbg/sim/hwdbg/communication/SendReceiveSynchronizer/Makefile
@@ -0,0 +1,10 @@
+# Makefile
+
+TOPLEVEL_LANG = verilog
+VERILOG_SOURCES += $(shell pwd)/../../../../generated/SendReceiveSynchronizer.sv
+VERILOG_SOURCES += $(shell pwd)/../../../../generated/DebuggerPacketReceiver.sv
+VERILOG_SOURCES += $(shell pwd)/../../../../generated/DebuggerPacketSender.sv
+TOPLEVEL = SendReceiveSynchronizer
+MODULE = test_SendReceiveSynchronizer
+
+include $(shell cocotb-config --makefiles)/Makefile.sim
diff --git a/hwdbg/sim/hwdbg/communication/SendReceiveSynchronizer/test.sh b/hwdbg/sim/hwdbg/communication/SendReceiveSynchronizer/test.sh
new file mode 100644
index 00000000..a83ca694
--- /dev/null
+++ b/hwdbg/sim/hwdbg/communication/SendReceiveSynchronizer/test.sh
@@ -0,0 +1 @@
+make SIM=icarus WAVES=1
diff --git a/hwdbg/sim/hwdbg/communication/SendReceiveSynchronizer/test_SendReceiveSynchronizer.py b/hwdbg/sim/hwdbg/communication/SendReceiveSynchronizer/test_SendReceiveSynchronizer.py
new file mode 100644
index 00000000..a9b0f2b7
--- /dev/null
+++ b/hwdbg/sim/hwdbg/communication/SendReceiveSynchronizer/test_SendReceiveSynchronizer.py
@@ -0,0 +1,352 @@
+##
+# @file test_SendReceiveSynchronizer.py
+#
+# @author Sina Karvandi (sina@hyperdbg.org)
+#
+# @brief Testing module for SendReceiveSynchronizer
+#
+# @details
+#
+# @version 0.1
+#
+# @date 2024-04-23
+#
+# @copyright This project is released under the GNU Public License v3.
+#
+
+import random
+
+import cocotb
+from cocotb.clock import Clock
+from cocotb.triggers import Timer
+from cocotb.types import LogicArray
+
+'''
+ input clock,
+ reset,
+ io_en,
+ io_plInSignal,
+ output io_psOutInterrupt,
+ output [12:0] io_rdWrAddr,
+ input [31:0] io_rdData,
+ output io_wrEna,
+ output [31:0] io_wrData,
+ io_requestedActionOfThePacketOutput,
+ output io_requestedActionOfThePacketOutputValid,
+ input io_noNewDataReceiver,
+ io_readNextData,
+ output io_dataValidOutput,
+ output [31:0] io_receivingData,
+ input io_beginSendingBuffer,
+ io_noNewDataSender,
+ io_dataValidInput,
+ output io_sendWaitForBuffer,
+ input [31:0] io_requestedActionOfThePacketInput,
+ io_sendingData
+'''
+
+@cocotb.test()
+async def SendReceiveSynchronizer_test(dut):
+ """Test SendReceiveSynchronizer module"""
+
+ global DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE
+
+ #
+ # Assert initial output is unknown
+ #
+ assert LogicArray(dut.io_psOutInterrupt.value) == LogicArray("X")
+ assert LogicArray(dut.io_rdWrAddr.value) == LogicArray("XXXXXXXXXXXXX")
+ assert LogicArray(dut.io_wrEna.value) == LogicArray("X")
+ assert LogicArray(dut.io_wrData.value) == LogicArray("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
+ assert LogicArray(dut.io_requestedActionOfThePacketOutput.value) == LogicArray("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
+ assert LogicArray(dut.io_requestedActionOfThePacketOutputValid.value) == LogicArray("X")
+ assert LogicArray(dut.io_dataValidOutput.value) == LogicArray("X")
+ assert LogicArray(dut.io_receivingData.value) == LogicArray("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
+ assert LogicArray(dut.io_sendWaitForBuffer.value) == LogicArray("X")
+
+ clock = Clock(dut.clock, 10, units="ns") # Create a 10ns period clock on port clock
+
+ #
+ # Start the clock. Start it low to avoid issues on the first RisingEdge
+ #
+ cocotb.start_soon(clock.start(start_high=False))
+
+ dut._log.info("Initialize and reset module")
+
+ #
+ # Initial values
+ #
+ dut.io_en.value = 0
+ dut.io_beginSendingBuffer.value = 0
+ dut.io_noNewDataSender.value = 0
+ dut.io_dataValidInput.value = 0
+ dut.io_readNextData.value = 0
+ dut.io_noNewDataReceiver.value = 0
+ dut.io_plInSignal.value = 0
+ dut.io_requestedActionOfThePacketInput.value = 0
+ dut.io_requestedActionOfThePacketInput.value = 0
+
+ #
+ # Reset DUT
+ #
+ dut.reset.value = 1
+ for _ in range(10):
+ await Timer(10, units="ns")
+ dut.reset.value = 0
+
+ dut._log.info("Enabling chip")
+
+ #
+ # Enable chip
+ #
+ dut.io_en.value = 1
+
+ for test_number in range(10):
+
+ ###############################################################
+ # #
+ # Receiving Logic #
+ # #
+ ###############################################################
+
+ dut._log.info("Enable receiving data on the chip (" + str(test_number) + ")")
+
+ #
+ # Tell the receiver to start receiving data (This mainly operates based on
+ # a rising-edge detector, so we'll need to make it low)
+ #
+ dut.io_plInSignal.value = 1
+ await Timer(10, units="ns")
+ dut.io_plInSignal.value = 0
+
+ #
+ # Activate sending logic to test whether the chip fails synchronizing signals or not
+ #
+ dut.io_beginSendingBuffer.value = 1
+ await Timer(10, units="ns")
+ dut.io_beginSendingBuffer.value = 0
+
+ #
+ # Wait until the receive operation is done (finished)
+ #
+ for i in range(30):
+
+ match dut.io_rdWrAddr.value:
+
+ #
+ # For the PS data range
+ #
+ case 0x0: # checksum
+ dut.io_rdData.value = 0x00001234
+ case 0x8: # indicator
+ dut.io_rdData.value = 0x48595045 # first 32 bits of the indicator
+ case 0x10: # type
+ dut.io_rdData.value = 0x4 # debugger to hardware packet (DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL)
+ case 0x14: # requested action
+ dut.io_rdData.value = 0x14141414
+ case 0x18: # General output
+ dut.io_rdData.value = 0x18181818
+ case 0x1c: # General output
+ dut.io_rdData.value = 0x1c1c1c1c
+ case 0x20: # General output
+ dut.io_rdData.value = 0x20202020
+ case 0x24: # General output
+ dut.io_rdData.value = 0x24242424
+ case 0x28: # General output
+ dut.io_rdData.value = 0x28282828
+ case 0x2c: # General output
+ dut.io_rdData.value = 0x2c2c2c2c
+ case 0x30: # General output
+ dut.io_rdData.value = 0x30303030
+ case 0x34: # General output
+ dut.io_rdData.value = 0x34343434
+ case 0x38: # General output
+ dut.io_rdData.value = 0x38383838
+ case 0x3c: # General output
+ dut.io_rdData.value = 0x3c3c3c3c
+ case 0x40: # General output
+ dut.io_rdData.value = 0x40404040
+ case 0x44: # General output
+ dut.io_rdData.value = 0x44444444
+ case 0x48: # General output
+ dut.io_rdData.value = 0x48484848
+ case 0x4c: # General output
+ dut.io_rdData.value = 0x4c4c4c4c
+ case 0x50: # General output
+ dut.io_rdData.value = 0x50505050
+
+ #
+ # For the PL data range
+ #
+ case 0x1000: # checksum
+ dut.io_rdData.value = 0x10001000
+ case 0x1008: # indicator 1
+ dut.io_rdData.value = 0x48595045 # The first 32 bits of the indicator
+ case 0x100c: # indicator 2
+ dut.io_rdData.value = 0x100c100c # The second 32 bits of the indicator
+ case 0x1010: # type
+ dut.io_rdData.value = 0x4 # debugger to hardware packet (DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL)
+ case 0x1014: # requested action
+ dut.io_rdData.value = 0x10141014
+ case 0x1018: # General output
+ dut.io_rdData.value = 0x10181018
+ case 0x101c: # General output
+ dut.io_rdData.value = 0x101c101c
+ case 0x1020: # General output
+ dut.io_rdData.value = 0x10201020
+ case 0x1024: # General output
+ dut.io_rdData.value = 0x10241024
+ case 0x1028: # General output
+ dut.io_rdData.value = 0x10281028
+ case 0x102c: # General output
+ dut.io_rdData.value = 0x102c102c
+ case 0x1030: # General output
+ dut.io_rdData.value = 0x10301030
+ case 0x1034: # General output
+ dut.io_rdData.value = 0x10341034
+ case 0x1038: # General output
+ dut.io_rdData.value = 0x10381038
+ case 0x103c: # General output
+ dut.io_rdData.value = 0x103c103c
+ case 0x1040: # General output
+ dut.io_rdData.value = 0x10401040
+ case 0x1044: # General output
+ dut.io_rdData.value = 0x10441044
+ case 0x1048: # General output
+ dut.io_rdData.value = 0x10481048
+ case 0x104c: # General output
+ dut.io_rdData.value = 0x104c104c
+ case 0x1050: # General output
+ dut.io_rdData.value = 0x10501050
+ case _:
+ assert 1 == 2, "invalid address in the address line"
+
+ if dut.io_requestedActionOfThePacketOutputValid.value == 1:
+
+ #
+ # No new data needed to be received
+ #
+ if test_number % 3 == 0:
+ dut.io_noNewDataReceiver.value = 1
+ await Timer(10, units="ns")
+ dut.io_noNewDataReceiver.value = 0
+ else:
+ #
+ # Make change to the io_readNextData signal as it operates mainly
+ # based on a rising-edge detector
+ #
+ if dut.io_readNextData.value == 0:
+ dut.io_readNextData.value = 1
+ else:
+ dut.io_readNextData.value = 0
+
+ #
+ # Go to the next clock cycle
+ #
+ await Timer(10, units="ns")
+
+
+ if test_number % 3 != 0:
+ dut.io_noNewDataReceiver.value = 1
+ await Timer(10, units="ns")
+ dut.io_noNewDataReceiver.value = 0
+
+ #
+ # Run extra waiting clocks
+ #
+ for _ in range(10):
+ await Timer(10, units="ns")
+
+ ###############################################################
+ # #
+ # Sending Logic #
+ # #
+ ###############################################################
+
+ dut._log.info("Enable sending data on the chip (" + str(test_number) + ")")
+
+ #
+ # There is data to send
+ #
+ dut.io_noNewDataSender.value = 0
+ dut.io_beginSendingBuffer.value = 0
+
+ #
+ # Tell the sender to start sending data (This mainly operates based on
+ # a rising-edge detector, so we'll need to make it low)
+ #
+ dut.io_beginSendingBuffer.value = 1
+ await Timer(10, units="ns")
+ dut.io_beginSendingBuffer.value = 0
+
+ #
+ # Activate receiving logic to test whether the chip fails synchronizing signals or not
+ #
+ dut.io_plInSignal.value = 1
+ await Timer(10, units="ns")
+ dut.io_plInSignal.value = 0
+
+ #
+ # No new data at this stage
+ #
+ dut.io_dataValidInput.value = 0
+ dut.io_sendingData.value = 0
+
+ #
+ # Adjust the requested action of the packet
+ #
+ dut.io_requestedActionOfThePacketInput.value = 0x55859555
+
+ #
+ # Synchronize with the clock. This will apply the initial values
+ #
+ await Timer(10, units="ns")
+
+ #
+ # This will change the behavior of the data producer to only
+ # generate extra data for 2 of the test case rounds, the third
+ # test case doesn't have any extra data
+ #
+ if test_number % 3 != 0 :
+ #
+ # Run until the module asks for further buffers
+ #
+ for i in range(100):
+ if dut.io_sendWaitForBuffer.value == 1:
+ val = random.randint(0, 0xffffffff)
+
+ #
+ # Indicate that the data is valid
+ #
+ dut.io_dataValidInput.value = 1
+
+ #
+ # Assign the random value to send as the data
+ #
+ dut.io_sendingData.value = val
+
+ await Timer(10, units="ns")
+
+ #
+ # Now, tell the sender module that there is no longer needed to send data
+ #
+ for i in range(100):
+ if dut.io_sendWaitForBuffer.value == 1:
+ dut.io_noNewDataSender.value = 1
+ await Timer(10, units="ns")
+ dut.io_noNewDataSender.value = 0
+ break
+
+ await Timer(10, units="ns")
+
+
+ #
+ # Run extra waiting clocks
+ #
+ for _ in range(10):
+ await Timer(10, units="ns")
+
+ #
+ # Check the final input on the next clock
+ #
+ await Timer(10, units="ns")
diff --git a/hwdbg/sim/modelsim/README.md b/hwdbg/sim/modelsim/README.md
new file mode 100644
index 00000000..f511e03c
--- /dev/null
+++ b/hwdbg/sim/modelsim/README.md
@@ -0,0 +1,32 @@
+# Automated ModelSim Viewer
+
+First of all, make sure to edit the address of the "ModelSim" directory in **modelsim.py**.
+
+After that, only modify the "modelsim.config" file.
+
+In the "modelsim.config" file, the first line that starts with "module:" is the name of the target module's **Tester** class. The rest of the lines are signals to be shown.
+
+For example:
+```
+module:DebuggerModuleTest
+clock
+inputPin
+```
+
+If you don't specify the signals to be filtered, then **ALL** signals will be shown.
+
+For example:
+```
+module:DebuggerModuleTest
+```
+
+At last, run it with the following command:
+```
+python3 modelsim.py
+```
+
+or,
+```
+python3 sim/modelsim.py
+```
+
diff --git a/hwdbg/sim/modelsim/modelsim.config b/hwdbg/sim/modelsim/modelsim.config
new file mode 100644
index 00000000..cc537f5f
--- /dev/null
+++ b/hwdbg/sim/modelsim/modelsim.config
@@ -0,0 +1,3 @@
+module:DebuggerModuleTest
+io_inputPin
+io_outputPin
\ No newline at end of file
diff --git a/hwdbg/sim/modelsim/modelsim.py b/hwdbg/sim/modelsim/modelsim.py
new file mode 100644
index 00000000..e3c90db1
--- /dev/null
+++ b/hwdbg/sim/modelsim/modelsim.py
@@ -0,0 +1,157 @@
+import os
+import subprocess
+import glob
+
+MODELSIM = "/home/sina/intelFPGA/20.1/modelsim_ase/bin"
+
+#
+# Check modelsim directory
+#
+if not os.path.exists(MODELSIM):
+ print("[x] Error: The path does not exist")
+ exit()
+else:
+ print("[*] Oh, the modelsim path found :)")
+
+MODELSIM_VCD2WLF = MODELSIM + "/vcd2wlf"
+MODELSIM_VSIM = MODELSIM + "/vsim"
+
+#
+# Config file variables
+#
+CONFIG_TEST_MODULE_CLASS = ""
+CONFIG_SHOW_ALL_WAVES = True
+CONFIG_WAVES_LIST = []
+
+#
+# Check if user is root or not
+#
+if os.geteuid() != 0:
+ print("[x] you should run this script with root (sudo) user permission")
+ exit()
+else:
+ print("[*] user is root")
+
+#
+# Get the current script's directory
+#
+current_script_path = os.path.dirname(os.path.abspath(__file__))
+
+WAVE_OUTPUT_FILES_PATH = current_script_path + \
+ "/../test_run_dir/DUT_should_pass/"
+CONFIG_FILE_PATH = current_script_path + "/modelsim.config"
+print("[*] current script path:", WAVE_OUTPUT_FILES_PATH)
+
+#
+# Check config file
+#
+if os.path.exists(CONFIG_FILE_PATH) == False:
+ print("[x] config file not found")
+ exit()
+
+#
+# Interpreting config file
+#
+with open(CONFIG_FILE_PATH, 'r') as file:
+ for line in file:
+
+ if line.lower().startswith("module:") or line.lower().startswith("module :"):
+ # it's the test module name
+ CONFIG_TEST_MODULE_CLASS = line.split(":")[1]
+ print("[*] found module name:", CONFIG_TEST_MODULE_CLASS)
+ else:
+ # it's a wave, so no longer need to show all waves
+ if line.isspace() == False:
+ CONFIG_SHOW_ALL_WAVES = False
+ CONFIG_WAVES_LIST.append(line)
+ print("[*] signal filter for:", line)
+
+#
+# Show message if all signals need to be shown
+#
+if CONFIG_SHOW_ALL_WAVES == True:
+ print("[*] no signal filter found, assuming all signals to be shown!")
+
+#
+# Check if test module is empty or not
+#
+if CONFIG_TEST_MODULE_CLASS.isspace() == True:
+ print("[x] main test module not found, please add 'module:' to the config file")
+ exit()
+
+#
+# Set the current working directory
+#
+os.chdir(current_script_path + "/..")
+print("[*] current working directory: " + format(os.getcwd()))
+
+#
+# Create TCL config file
+#
+print("[*] writing to TCL config file: " +
+ current_script_path + '/modelsim.tcl')
+if CONFIG_SHOW_ALL_WAVES:
+ with open(current_script_path + '/modelsim.tcl', 'w') as f:
+ # add the clock at top of the signals by default
+ f.write("add wave -position insertpoint clock\n")
+ f.write("add wave -position insertpoint *\n")
+else:
+ with open(current_script_path + '/modelsim.tcl', 'w') as f:
+ for item in CONFIG_WAVES_LIST:
+ f.write("add wave -position insertpoint {*" + item.replace('\n','').replace('\r', '') + '*}\n')
+
+#
+# Remove all the previous *.wlf, *.vcd, *.fir files
+#
+print("[*] removing previously generated files")
+for file_name in os.listdir(WAVE_OUTPUT_FILES_PATH):
+ if file_name.endswith('.wlf') or file_name.endswith('.vcd') or file_name.endswith('.fir'):
+ os.remove(os.path.join(WAVE_OUTPUT_FILES_PATH, file_name))
+
+#
+# Run the VCD wave generator
+#
+print("[*] running chisel VCD file generator for module: " +
+ CONFIG_TEST_MODULE_CLASS)
+print("running command: '" + "sbt testOnly " + CONFIG_TEST_MODULE_CLASS + " -- -DwriteVcd=1" + "'")
+result = subprocess.run(
+ ["sbt", "testOnly " + CONFIG_TEST_MODULE_CLASS + " -- -DwriteVcd=1"], stdout=subprocess.PIPE)
+print(result.stdout.decode())
+
+#
+# Get all files in directory
+#
+files = glob.glob(WAVE_OUTPUT_FILES_PATH + "/*")
+
+#
+# Sort files by last modified time
+#
+files.sort(key=lambda x: os.path.getmtime(x))
+
+#
+# Check if the list is empty or not
+#
+if not files or not files[-1].endswith('.vcd') :
+ print("[x] there was an error in generating VCD files")
+ exit()
+
+#
+# Get the latest modified file
+#
+latest_vcd_file = files[-1]
+print("[*] latest generated VCD file: " + latest_vcd_file)
+
+#
+# Converting VCD to WLF
+#
+print("[*] converting VCD file to WLF file")
+result = subprocess.run(
+ [MODELSIM_VCD2WLF, latest_vcd_file, latest_vcd_file + ".wlf"], stdout=subprocess.PIPE)
+print(result.stdout.decode())
+
+#
+# Run the generated WLF file
+#
+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/sim/modelsim/modelsim.tcl b/hwdbg/sim/modelsim/modelsim.tcl
new file mode 100644
index 00000000..59c53356
--- /dev/null
+++ b/hwdbg/sim/modelsim/modelsim.tcl
@@ -0,0 +1,2 @@
+add wave -position insertpoint {*io_inputPin*}
+add wave -position insertpoint {*io_outputPin*}
diff --git a/hwdbg/sim/plain-sv/PlainSystemVerilogDUT.sv b/hwdbg/sim/plain-sv/PlainSystemVerilogDUT.sv
new file mode 100644
index 00000000..12c7fa1f
--- /dev/null
+++ b/hwdbg/sim/plain-sv/PlainSystemVerilogDUT.sv
@@ -0,0 +1,162 @@
+//////////////////////////////////////////////////////////////////////////////////
+// Company:
+// Engineer: Sina Karvandi (sina@hyperdbg.org)
+//
+// Create Date: 09/18/2024
+// Design Name:
+// Module Name: PlainSystemVerilogDUT
+// Project Name: PlainSystemVerilogDUT
+// Target Devices:
+// Tool Versions:
+// Description: This code is used for plain simulation of the top-level
+// design of hwdbg debugger
+//
+// Dependencies:
+//
+// Revision:
+// Revision 0.01 - File Created
+// Additional Comments:
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+module PlainSystemVerilogDUT;
+
+ //
+ // Parameters
+ //
+ parameter CLK_PERIOD = 10; // Clock period
+
+ //
+ // Signal Declarations
+ //
+ logic clock;
+ logic reset;
+ logic io_en;
+ logic [31:0] io_inputPin; // Array for input pins
+ logic [31:0] io_outputPin; // Array for output pins
+ logic io_plInSignal;
+ logic io_psOutInterrupt;
+
+ //
+ // Instantiate the DUT (Device Under Test)
+ //
+ DebuggerModuleTestingBRAM uut (
+ .clock(clock),
+ .reset(reset),
+ .io_en(io_en),
+ .io_inputPin_0(io_inputPin[0]),
+ .io_inputPin_1(io_inputPin[1]),
+ .io_inputPin_2(io_inputPin[2]),
+ .io_inputPin_3(io_inputPin[3]),
+ .io_inputPin_4(io_inputPin[4]),
+ .io_inputPin_5(io_inputPin[5]),
+ .io_inputPin_6(io_inputPin[6]),
+ .io_inputPin_7(io_inputPin[7]),
+ .io_inputPin_8(io_inputPin[8]),
+ .io_inputPin_9(io_inputPin[9]),
+ .io_inputPin_10(io_inputPin[10]),
+ .io_inputPin_11(io_inputPin[11]),
+ .io_inputPin_12(io_inputPin[12]),
+ .io_inputPin_13(io_inputPin[13]),
+ .io_inputPin_14(io_inputPin[14]),
+ .io_inputPin_15(io_inputPin[15]),
+ .io_inputPin_16(io_inputPin[16]),
+ .io_inputPin_17(io_inputPin[17]),
+ .io_inputPin_18(io_inputPin[18]),
+ .io_inputPin_19(io_inputPin[19]),
+ .io_inputPin_20(io_inputPin[20]),
+ .io_inputPin_21(io_inputPin[21]),
+ .io_inputPin_22(io_inputPin[22]),
+ .io_inputPin_23(io_inputPin[23]),
+ .io_inputPin_24(io_inputPin[24]),
+ .io_inputPin_25(io_inputPin[25]),
+ .io_inputPin_26(io_inputPin[26]),
+ .io_inputPin_27(io_inputPin[27]),
+ .io_inputPin_28(io_inputPin[28]),
+ .io_inputPin_29(io_inputPin[29]),
+ .io_inputPin_30(io_inputPin[30]),
+ .io_inputPin_31(io_inputPin[31]),
+ .io_outputPin_0(io_outputPin[0]),
+ .io_outputPin_1(io_outputPin[1]),
+ .io_outputPin_2(io_outputPin[2]),
+ .io_outputPin_3(io_outputPin[3]),
+ .io_outputPin_4(io_outputPin[4]),
+ .io_outputPin_5(io_outputPin[5]),
+ .io_outputPin_6(io_outputPin[6]),
+ .io_outputPin_7(io_outputPin[7]),
+ .io_outputPin_8(io_outputPin[8]),
+ .io_outputPin_9(io_outputPin[9]),
+ .io_outputPin_10(io_outputPin[10]),
+ .io_outputPin_11(io_outputPin[11]),
+ .io_outputPin_12(io_outputPin[12]),
+ .io_outputPin_13(io_outputPin[13]),
+ .io_outputPin_14(io_outputPin[14]),
+ .io_outputPin_15(io_outputPin[15]),
+ .io_outputPin_16(io_outputPin[16]),
+ .io_outputPin_17(io_outputPin[17]),
+ .io_outputPin_18(io_outputPin[18]),
+ .io_outputPin_19(io_outputPin[19]),
+ .io_outputPin_20(io_outputPin[20]),
+ .io_outputPin_21(io_outputPin[21]),
+ .io_outputPin_22(io_outputPin[22]),
+ .io_outputPin_23(io_outputPin[23]),
+ .io_outputPin_24(io_outputPin[24]),
+ .io_outputPin_25(io_outputPin[25]),
+ .io_outputPin_26(io_outputPin[26]),
+ .io_outputPin_27(io_outputPin[27]),
+ .io_outputPin_28(io_outputPin[28]),
+ .io_outputPin_29(io_outputPin[29]),
+ .io_outputPin_30(io_outputPin[30]),
+ .io_outputPin_31(io_outputPin[31]),
+ .io_plInSignal(io_plInSignal),
+ .io_psOutInterrupt(io_psOutInterrupt)
+ );
+
+ //
+ // Clock generation
+ //
+ initial begin
+ clock = 0;
+ forever #(CLK_PERIOD / 2) clock = ~clock;
+ end
+
+ //
+ // Test procedure
+ //
+ initial begin
+ // Initialize signals
+ reset = 1;
+ io_en = 1;
+ io_plInSignal = 0;
+ io_inputPin = 32'h0; // Initialize all input pins to 0
+
+ #100; // Hold reset for 100 ns
+
+ // Apply reset
+ @(posedge clock);
+ reset = 0; // Release reset
+ @(posedge clock);
+
+ //
+ // Example input stimulus
+ //
+ io_inputPin = 32'hFFFF_FFFF; // Apply some input pattern
+
+ //
+ // Enable PL input signal
+ //
+ io_plInSignal = 1;
+
+ //
+ // Wait for a few clock cycles
+ //
+ repeat (10000) @(posedge clock);
+
+ //
+ // Finish the simulation after some time
+ //
+ repeat (20) @(posedge clock);
+ $finish;
+ end
+
+endmodule
diff --git a/hwdbg/src/main/scala/hwdbg/communication/interpreter.scala b/hwdbg/src/main/scala/hwdbg/communication/interpreter.scala
new file mode 100644
index 00000000..e682e612
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/communication/interpreter.scala
@@ -0,0 +1,515 @@
+/**
+ * @file
+ * interpreter.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Remote debugger packet interpreter module
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-04-19
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.communication.interpreter
+
+import chisel3._
+import chisel3.util.{switch, is}
+import circt.stage.ChiselStage
+
+import hwdbg.configs._
+import hwdbg.types._
+import hwdbg.script._
+
+object DebuggerPacketInterpreterEnums {
+ object State extends ChiselEnum {
+ val sIdle, sNewActionReceived, sSendResponse, sDone = Value
+ }
+}
+
+class DebuggerPacketInterpreter(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+) extends Module {
+
+ //
+ // Import state enum
+ //
+ import DebuggerPacketInterpreterEnums.State
+ import DebuggerPacketInterpreterEnums.State._
+
+ val io = IO(new Bundle {
+
+ //
+ // Chip signals
+ //
+ val en = Input(Bool()) // chip enable signal
+
+ //
+ // Receiving signals
+ //
+ val requestedActionOfThePacketInput = Input(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W)) // the requested action
+ val requestedActionOfThePacketInputValid = Input(Bool()) // whether data on the requested action is valid or not
+
+ val noNewDataReceiver = Output(Bool()) // are interpreter expects more data?
+ val readNextData = Output(Bool()) // whether the next data should be read or not?
+
+ val dataValidInput = Input(Bool()) // whether data on the receiving data line is valid or not?
+ val receivingData = Input(UInt(instanceInfo.bramDataWidth.W)) // data to be received in interpreter
+
+ //
+ // Sending signals
+ //
+ val beginSendingBuffer = Output(Bool()) // should sender start sending buffers or not?
+ val noNewDataSender = Output(Bool()) // should sender finish sending buffers or not?
+ val dataValidOutput = Output(Bool()) // should sender send next buffer or not?
+
+ val sendWaitForBuffer = Input(Bool()) // should the interpreter send next buffer or not?
+
+ val requestedActionOfThePacketOutput = Output(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W)) // the requested action
+ val sendingData = Output(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the debugger
+
+ //
+ // Script stage configuration signals
+ //
+ val finishedScriptConfiguration = Output(Bool()) // whether script configuration finished or not?
+ val configureStage = Output(Bool()) // whether the configuration of stage should start or not?
+ val targetOperator = Output(new HwdbgShortSymbol(instanceInfo.scriptVariableLength)) // Current operator to be configured
+ })
+
+ //
+ // State registers
+ //
+ val state = RegInit(sIdle)
+
+ //
+ // Last error register
+ //
+ val lastSuccesOrErrorMessage = RegInit(0.U(instanceInfo.bramDataWidth.W))
+
+ //
+ // Last error register
+ //
+ val enablePinOfScriptBufferHandler = RegInit(false.B)
+
+ //
+ // Output pins
+ //
+ val noNewDataReceiver = WireInit(false.B)
+ val readNextData = WireInit(false.B)
+
+ val regBeginSendingBuffer = RegInit(false.B)
+ val noNewDataSender = WireInit(false.B)
+ val dataValidOutput = WireInit(false.B)
+ val sendingData = WireInit(0.U(instanceInfo.bramDataWidth.W))
+
+ val regRequestedActionOfThePacketOutput = RegInit(0.U(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W))
+
+ val finishedScriptConfiguration = WireInit(false.B)
+ val configureStage = WireInit(false.B)
+ val initialSymbol = Wire(new HwdbgShortSymbol(instanceInfo.scriptVariableLength))
+ initialSymbol.Type := 0.U
+ initialSymbol.Value := 0.U
+ val targetOperator = WireInit(initialSymbol)
+
+ //
+ // Apply the chip enable signal
+ //
+ when(io.en === true.B) {
+
+ switch(state) {
+
+ is(sIdle) {
+
+ //
+ // Check if the debugger need a new action (a new command is received)
+ //
+ when(io.requestedActionOfThePacketInputValid) {
+
+ //
+ // An action is received
+ //
+ state := sNewActionReceived
+
+ }.otherwise {
+
+ //
+ // Remain at the same state (no action)
+ //
+ state := sIdle
+ }
+
+ }
+ is(sNewActionReceived) {
+
+ // -------------------------------------------------------------------------
+ // Now, the action needs to be dispatched
+ //
+ val inputAction = io.requestedActionOfThePacketInput
+
+ when(inputAction === HwdbgActionEnums.hwdbgActionSendInstanceInfo.id.U) {
+
+ //
+ // *** Configure sending instance info ***
+ //
+
+ //
+ // Set the response packet type
+ //
+ regRequestedActionOfThePacketOutput := HwdbgResponseEnums.hwdbgResponseInstanceInfo.id.U
+
+ //
+ // This action needs a response
+ //
+ state := sSendResponse
+
+ }.elsewhen(inputAction === HwdbgActionEnums.hwdbgActionConfigureScriptBuffer.id.U) {
+
+ //
+ // *** Configure the internal buffer with script ***
+ //
+
+ //
+ // Enable the buffer config module
+ //
+ enablePinOfScriptBufferHandler := true.B
+
+ val (
+ moduleReadNextData,
+ moduleFinishedScriptConfiguration,
+ moduleConfigureStage,
+ moduleTargetOperator
+ ) =
+ InterpreterScriptBufferHandler(
+ debug,
+ instanceInfo
+ )(
+ enablePinOfScriptBufferHandler,
+ io.dataValidInput,
+ io.receivingData
+ )
+
+ //
+ // Connect the script stage configuration signals
+ //
+ readNextData := moduleReadNextData
+ configureStage := moduleConfigureStage
+ finishedScriptConfiguration := moduleFinishedScriptConfiguration
+ targetOperator := moduleTargetOperator
+
+ when(moduleFinishedScriptConfiguration === true.B) {
+
+ //
+ // *** Script stage buffer configuration finished! ***
+ //
+
+ //
+ // Disable the buffer config module
+ //
+ enablePinOfScriptBufferHandler := false.B
+
+ //
+ // Set the response packet type
+ //
+ regRequestedActionOfThePacketOutput := HwdbgResponseEnums.hwdbgResponseSuccessOrErrorMessage.id.U
+
+ //
+ // Set the success message
+ //
+ lastSuccesOrErrorMessage := HwdbgSuccessOrErrorEnums.hwdbgOperationWasSuccessful.id.U
+
+ //
+ // This action needs a response
+ //
+ state := sSendResponse
+
+ }.otherwise {
+
+ //
+ // *** Script stage buffer configuration NOT finished, read the buffer ***
+ //
+
+ //
+ // Stay at the same state
+ //
+ state := sNewActionReceived
+ }
+
+ }.otherwise {
+
+ //
+ // *** Invalid action ***
+ //
+
+ //
+ // Set the response packet type
+ //
+ regRequestedActionOfThePacketOutput := HwdbgResponseEnums.hwdbgResponseSuccessOrErrorMessage.id.U
+
+ //
+ // Set the latest error
+ //
+ lastSuccesOrErrorMessage := HwdbgSuccessOrErrorEnums.hwdbgErrorInvalidPacket.id.U
+
+ //
+ // This action needs a response
+ //
+ state := sSendResponse
+
+ }
+
+ //
+ // -------------------------------------------------------------------------
+ //
+
+ }
+ is(sSendResponse) {
+
+ //
+ // Finish the receiving
+ //
+ noNewDataReceiver := true.B
+
+ //
+ // Begin sending response
+ //
+ regBeginSendingBuffer := true.B
+
+ //
+ // Wait until the sender module is reading to send data
+ //
+ when(io.sendWaitForBuffer === true.B) {
+
+ // -------------------------------------------------------------------------
+ // Now, the response needs to be sent
+ //
+ when(regRequestedActionOfThePacketOutput === HwdbgResponseEnums.hwdbgResponseInstanceInfo.id.U) {
+
+ //
+ // *** Send instance information ***
+ //
+
+ //
+ // Instantiate the instance info module
+ //
+
+ val (
+ noNewDataSenderModule,
+ dataValidOutputModule,
+ sendingDataModule
+ ) =
+ InterpreterInstanceInfo(
+ debug,
+ instanceInfo
+ )(
+ io.sendWaitForBuffer // send waiting for buffer as an activation signal to the module
+ )
+
+ //
+ // Set data validity
+ //
+ dataValidOutput := dataValidOutputModule
+
+ //
+ // Set data
+ //
+ sendingData := sendingDataModule
+
+ //
+ // Once sending data is done, we'll go to the Done state
+ //
+ when(noNewDataSenderModule === true.B) {
+ state := sDone
+ }
+
+ }.elsewhen(regRequestedActionOfThePacketOutput === HwdbgResponseEnums.hwdbgResponseSuccessOrErrorMessage.id.U) {
+
+ //
+ // *** Send result of applying command (and errors) ***
+ //
+
+ //
+ // Instantiate the invalid packet module
+ //
+ val (
+ noNewDataSenderModule,
+ dataValidOutputModule,
+ sendingDataModule
+ ) =
+ InterpreterSendSuccessOrError(
+ debug,
+ instanceInfo
+ )(
+ io.sendWaitForBuffer, // send waiting for buffer as an activation signal to the module
+ lastSuccesOrErrorMessage
+ )
+
+ //
+ // Set data validity
+ //
+ dataValidOutput := dataValidOutputModule
+
+ //
+ // Set data
+ //
+ sendingData := sendingDataModule
+
+ //
+ // Once sending data is done, we'll go to the Done state
+ //
+ when(noNewDataSenderModule === true.B) {
+ state := sDone
+ }
+ }
+
+ //
+ // -------------------------------------------------------------------------
+ //
+
+ }.otherwise {
+
+ //
+ // The sender module is not ready for sending buffer
+ // so, we need to stay at this state
+ //
+ state := sSendResponse
+ }
+ }
+ is(sDone) {
+
+ //
+ // Finish the receiving, sending communication
+ //
+ noNewDataReceiver := true.B
+ noNewDataSender := true.B
+
+ //
+ // No longer need to begin sending data
+ //
+ regBeginSendingBuffer := false.B
+
+ //
+ // Go to the idle state
+ //
+ state := sIdle
+ }
+ }
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Connect output pins
+ //
+ io.noNewDataReceiver := noNewDataReceiver
+ io.readNextData := readNextData
+
+ io.beginSendingBuffer := regBeginSendingBuffer
+ io.noNewDataSender := noNewDataSender
+ io.dataValidOutput := dataValidOutput
+ io.requestedActionOfThePacketOutput := regRequestedActionOfThePacketOutput
+ io.sendingData := sendingData
+
+ io.configureStage := configureStage
+ io.finishedScriptConfiguration := finishedScriptConfiguration
+ io.targetOperator := targetOperator
+}
+
+object DebuggerPacketInterpreter {
+
+ def apply(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+ )(
+ en: Bool,
+ requestedActionOfThePacketInput: UInt,
+ requestedActionOfThePacketInputValid: Bool,
+ dataValidInput: Bool,
+ receivingData: UInt,
+ sendWaitForBuffer: Bool
+ ): (Bool, Bool, Bool, Bool, Bool, UInt, UInt, Bool, Bool, HwdbgShortSymbol) = {
+
+ val debuggerPacketInterpreter = Module(
+ new DebuggerPacketInterpreter(
+ debug,
+ instanceInfo
+ )
+ )
+
+ val noNewDataReceiver = Wire(Bool())
+ val readNextData = Wire(Bool())
+
+ val beginSendingBuffer = Wire(Bool())
+ val noNewDataSender = Wire(Bool())
+ val dataValidOutput = Wire(Bool())
+
+ val requestedActionOfThePacketOutput = Wire(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W))
+ val sendingData = Wire(UInt(instanceInfo.bramDataWidth.W))
+
+ val finishedScriptConfiguration = Wire(Bool())
+ val configureStage = Wire(Bool())
+ val targetOperator = Wire(new HwdbgShortSymbol(instanceInfo.scriptVariableLength))
+
+ //
+ // Configure the input signals
+ //
+ debuggerPacketInterpreter.io.en := en
+
+ //
+ // Configure the input signals related to the receiving signals
+ //
+ debuggerPacketInterpreter.io.requestedActionOfThePacketInput := requestedActionOfThePacketInput
+ debuggerPacketInterpreter.io.requestedActionOfThePacketInputValid := requestedActionOfThePacketInputValid
+ debuggerPacketInterpreter.io.dataValidInput := dataValidInput
+ debuggerPacketInterpreter.io.receivingData := receivingData
+
+ //
+ // Configure the input signals related to the sending signals
+ //
+ debuggerPacketInterpreter.io.sendWaitForBuffer := sendWaitForBuffer
+
+ //
+ // Configure the output signals
+ //
+ noNewDataReceiver := debuggerPacketInterpreter.io.noNewDataReceiver
+ readNextData := debuggerPacketInterpreter.io.readNextData
+
+ //
+ // Configure the output signals related to sending packets
+ //
+ beginSendingBuffer := debuggerPacketInterpreter.io.beginSendingBuffer
+ noNewDataSender := debuggerPacketInterpreter.io.noNewDataSender
+ dataValidOutput := debuggerPacketInterpreter.io.dataValidOutput
+
+ //
+ // Configure the output signals related to received packets
+ //
+ requestedActionOfThePacketOutput := debuggerPacketInterpreter.io.requestedActionOfThePacketOutput
+ sendingData := debuggerPacketInterpreter.io.sendingData
+
+ //
+ // Configure the output signals related to stage configuration
+ //
+ finishedScriptConfiguration := debuggerPacketInterpreter.io.finishedScriptConfiguration
+ configureStage := debuggerPacketInterpreter.io.configureStage
+ targetOperator := debuggerPacketInterpreter.io.targetOperator
+
+ //
+ // Return the output result
+ //
+ (
+ noNewDataReceiver,
+ readNextData,
+ beginSendingBuffer,
+ noNewDataSender,
+ dataValidOutput,
+ requestedActionOfThePacketOutput,
+ sendingData,
+ finishedScriptConfiguration,
+ configureStage,
+ targetOperator
+ )
+ }
+}
diff --git a/hwdbg/src/main/scala/hwdbg/communication/interpreter/instance_info.scala b/hwdbg/src/main/scala/hwdbg/communication/interpreter/instance_info.scala
new file mode 100644
index 00000000..f84df188
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/communication/interpreter/instance_info.scala
@@ -0,0 +1,462 @@
+/**
+ * @file
+ * port_information.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Send port information (in interpreter)
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-05-04
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.communication.interpreter
+
+import chisel3._
+import chisel3.util.{switch, is, log2Ceil}
+import circt.stage.ChiselStage
+
+import hwdbg.configs._
+import hwdbg.utils._
+
+object InterpreterInstanceInfoEnums {
+ object State extends ChiselEnum {
+ val sIdle, sSendVersion, sSendMaximumNumberOfStages, sSendScriptVariableLength, sSendNumberOfSupportedLocalAndGlobalVariables,
+ sSendNumberOfSupportedTemporaryVariables, sSendMaximumNumberOfSupportedGetScriptOperators, sSendMaximumNumberOfSupportedSetScriptOperators,
+ sSendSharedMemorySize, sSendDebuggerAreaOffset, sSendDebuggeeAreaOffset, sSendNumberOfPins, sSendNumberOfPorts, sSendScriptCapabilities1,
+ sSendScriptCapabilities2, sSendBramAddrWidth, sSendBramDataWidth, sSendPortsConfiguration, sDone = Value
+ }
+}
+
+class InterpreterInstanceInfo(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+) extends Module {
+
+ //
+ // Import state enum
+ //
+ import InterpreterInstanceInfoEnums.State
+ import InterpreterInstanceInfoEnums.State._
+
+ val io = IO(new Bundle {
+
+ //
+ // Chip signals
+ //
+ val en = Input(Bool()) // chip enable signal
+
+ //
+ // Sending signals
+ //
+ val noNewDataSender = Output(Bool()) // should sender finish sending buffers or not?
+ val dataValidOutput = Output(Bool()) // should sender send next buffer or not?
+ val sendingData = Output(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the debugger
+
+ })
+
+ //
+ // State registers
+ //
+ val state = RegInit(sIdle)
+
+ //
+ // Get number of input/output ports
+ //
+ val numberOfPorts = instanceInfo.portsConfiguration.size
+
+ //
+ // Convert input port pins into vector
+ //
+ // val pinsVec = RegInit(VecInit(Seq.fill(numberOfPorts)(0.U(instanceInfo.bramDataWidth.W))))
+ val pinsVec = VecInit(instanceInfo.portsConfiguration.map(_.U))
+
+ //
+ // Determine the width for numberOfSentPins
+ //
+ val numberOfSentPinsWidth = log2Ceil(numberOfPorts)
+
+ //
+ // Registers for keeping track of sent pin details
+ //
+ val numberOfSentPins = RegInit(0.U(numberOfSentPinsWidth.W))
+
+ //
+ // Output pins
+ //
+ val noNewDataSender = WireInit(false.B)
+ val dataValidOutput = WireInit(false.B)
+ val sendingData = WireInit(0.U(instanceInfo.bramDataWidth.W))
+
+ //
+ // Apply the chip enable signal
+ //
+ when(io.en === true.B) {
+
+ switch(state) {
+
+ is(sIdle) {
+
+ //
+ // Going to the next state (sending the version of the debugger)
+ //
+ state := sSendVersion
+ }
+ is(sSendVersion) {
+
+ //
+ // Set the version
+ //
+ sendingData := instanceInfo.version.U
+
+ //
+ // The output is valid
+ //
+ dataValidOutput := true.B
+
+ state := sSendMaximumNumberOfStages
+
+ }
+ is(sSendMaximumNumberOfStages) {
+
+ //
+ // Set the maximum number of stages supported by this instance of the debugger
+ //
+ sendingData := instanceInfo.maximumNumberOfStages.U
+
+ //
+ // The output is valid
+ //
+ dataValidOutput := true.B
+
+ state := sSendScriptVariableLength
+
+ }
+ is(sSendScriptVariableLength) {
+
+ //
+ // Set the script variable length of this instance of the debugger
+ //
+ sendingData := instanceInfo.scriptVariableLength.U
+
+ //
+ // The output is valid
+ //
+ dataValidOutput := true.B
+
+ state := sSendNumberOfSupportedLocalAndGlobalVariables
+
+ }
+ is(sSendNumberOfSupportedLocalAndGlobalVariables) {
+
+ //
+ // Set the number of supported local variables for this instance of the debugger
+ //
+ sendingData := instanceInfo.numberOfSupportedLocalAndGlobalVariables.U
+
+ //
+ // The output is valid
+ //
+ dataValidOutput := true.B
+
+ state := sSendNumberOfSupportedTemporaryVariables
+
+ }
+ is(sSendNumberOfSupportedTemporaryVariables) {
+
+ //
+ // Set the number of supported temporary variables for this instance of the debugger
+ //
+ sendingData := instanceInfo.numberOfSupportedTemporaryVariables.U
+
+ //
+ // The output is valid
+ //
+ dataValidOutput := true.B
+
+ state := sSendMaximumNumberOfSupportedGetScriptOperators
+
+ }
+ is(sSendMaximumNumberOfSupportedGetScriptOperators) {
+
+ //
+ // Set the maximum number of supported GET operators by this instance of the
+ // debugger in the script engine
+ //
+ sendingData := instanceInfo.maximumNumberOfSupportedGetScriptOperators.U
+
+ //
+ // The output is valid
+ //
+ dataValidOutput := true.B
+
+ state := sSendMaximumNumberOfSupportedSetScriptOperators
+
+ }
+ is(sSendMaximumNumberOfSupportedSetScriptOperators) {
+
+ //
+ // Set the maximum number of supported SET operators by this instance of the
+ // debugger in the script engine
+ //
+ sendingData := instanceInfo.maximumNumberOfSupportedSetScriptOperators.U
+
+ //
+ // The output is valid
+ //
+ dataValidOutput := true.B
+
+ state := sSendSharedMemorySize
+
+ }
+ is(sSendSharedMemorySize) {
+
+ //
+ // Set the shared memory size used by this instance of the debugger
+ //
+ sendingData := instanceInfo.sharedMemorySize.U
+
+ //
+ // The output is valid
+ //
+ dataValidOutput := true.B
+
+ state := sSendDebuggerAreaOffset
+
+ }
+ is(sSendDebuggerAreaOffset) {
+
+ //
+ // Set the start offset of the debugger to the debuggee memory for this
+ // instance of the debugger
+ //
+ sendingData := instanceInfo.debuggerAreaOffset.U
+
+ //
+ // The output is valid
+ //
+ dataValidOutput := true.B
+
+ state := sSendDebuggeeAreaOffset
+
+ }
+ is(sSendDebuggeeAreaOffset) {
+
+ //
+ // Set the start offset of the debuggee to the debugger memory for this
+ // instance of the debugger
+ //
+ sendingData := instanceInfo.debuggeeAreaOffset.U
+
+ //
+ // The output is valid
+ //
+ dataValidOutput := true.B
+
+ state := sSendNumberOfPins
+
+ }
+ is(sSendNumberOfPins) {
+
+ //
+ // Set the number of pins in this instance of the debugger
+ //
+ sendingData := instanceInfo.numberOfPins.U
+
+ //
+ // The output is valid
+ //
+ dataValidOutput := true.B
+
+ state := sSendNumberOfPorts
+
+ }
+ is(sSendNumberOfPorts) {
+
+ //
+ // Set the number of ports in this instance of the debugger
+ //
+ sendingData := instanceInfo.numberOfPorts.U
+
+ //
+ // The output is valid
+ //
+ dataValidOutput := true.B
+
+ state := sSendScriptCapabilities1
+
+ }
+ is(sSendScriptCapabilities1) {
+
+ //
+ // Set the first bits (most significant) of the supported operators capabilities of this instance
+ // of the debugger
+ //
+ sendingData := BitwiseFunction
+ .getBitsInRange(instanceInfo.scriptCapabilities, instanceInfo.bramDataWidth, instanceInfo.bramDataWidth + instanceInfo.bramDataWidth - 1)
+ .U
+
+ //
+ // The output is valid
+ //
+ dataValidOutput := true.B
+
+ state := sSendScriptCapabilities2
+
+ }
+ is(sSendScriptCapabilities2) {
+
+ //
+ // Set the second bits (least significant) of the supported operators capabilities of this instance
+ // of the debugger
+ //
+ sendingData := BitwiseFunction.getBitsInRange(instanceInfo.scriptCapabilities, 0, instanceInfo.bramDataWidth - 1).U
+
+ //
+ // The output is valid
+ //
+ dataValidOutput := true.B
+
+ state := sSendBramAddrWidth
+
+ }
+ is(sSendBramAddrWidth) {
+
+ //
+ // Set the BRAM address width in this instance of the debugger
+ //
+ sendingData := instanceInfo.bramAddrWidth.U
+
+ //
+ // The output is valid
+ //
+ dataValidOutput := true.B
+
+ state := sSendBramDataWidth
+
+ }
+ is(sSendBramDataWidth) {
+
+ //
+ // Set the BRAM data width in this instance of the debugger
+ //
+ sendingData := instanceInfo.bramDataWidth.U
+
+ //
+ // The output is valid
+ //
+ dataValidOutput := true.B
+
+ state := sSendPortsConfiguration
+
+ }
+ is(sSendPortsConfiguration) {
+
+ //
+ // Send input port items
+ //
+
+ //
+ // Adjust data
+ //
+ sendingData := pinsVec(numberOfSentPins)
+
+ //
+ // Data is valid
+ //
+ dataValidOutput := true.B
+
+ when(numberOfSentPins === (numberOfPorts - 1).U) {
+
+ //
+ // Reset the pins sent for sending details
+ //
+ numberOfSentPins := 0.U
+
+ state := sDone
+
+ }.otherwise {
+
+ //
+ // Send next index
+ //
+ numberOfSentPins := numberOfSentPins + 1.U
+
+ //
+ // Stay at the same state
+ //
+ state := sSendPortsConfiguration
+ }
+ }
+ is(sDone) {
+
+ //
+ // Indicate that sending data is done
+ //
+ noNewDataSender := true.B
+
+ //
+ // Goto the idle state
+ //
+ state := sIdle
+ }
+ }
+
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Connect output pins
+ //
+ io.noNewDataSender := noNewDataSender
+ io.dataValidOutput := dataValidOutput
+ io.sendingData := sendingData
+
+}
+
+object InterpreterInstanceInfo {
+
+ def apply(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+ )(
+ en: Bool
+ ): (Bool, Bool, UInt) = {
+
+ val interpreterInstanceInfo = Module(
+ new InterpreterInstanceInfo(
+ debug,
+ instanceInfo
+ )
+ )
+
+ val noNewDataSender = Wire(Bool())
+ val dataValidOutput = Wire(Bool())
+ val sendingData = Wire(UInt(instanceInfo.bramDataWidth.W))
+
+ //
+ // Configure the input signals
+ //
+ interpreterInstanceInfo.io.en := en
+
+ //
+ // Configure the output signals
+ //
+ noNewDataSender := interpreterInstanceInfo.io.noNewDataSender
+ dataValidOutput := interpreterInstanceInfo.io.dataValidOutput
+ sendingData := interpreterInstanceInfo.io.sendingData
+
+ //
+ // Return the output result
+ //
+ (
+ noNewDataSender,
+ dataValidOutput,
+ sendingData
+ )
+ }
+}
diff --git a/hwdbg/src/main/scala/hwdbg/communication/interpreter/script_buffer_handler.scala b/hwdbg/src/main/scala/hwdbg/communication/interpreter/script_buffer_handler.scala
new file mode 100644
index 00000000..ee7462f9
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/communication/interpreter/script_buffer_handler.scala
@@ -0,0 +1,301 @@
+/**
+ * @file
+ * script_buffer_handler.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Configures the script stages from shared memory
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-06-14
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.communication.interpreter
+
+import chisel3._
+import chisel3.util.{switch, is}
+import circt.stage.ChiselStage
+
+import hwdbg.configs._
+import hwdbg.types._
+import hwdbg.script._
+
+object InterpreterScriptBufferHandlerEnums {
+ object State extends ChiselEnum {
+ val sIdle, sReadSizeOfBuffer, sReadTypeOfOperator, sReadValueOfOperator, sDone = Value
+ }
+}
+
+class InterpreterScriptBufferHandler(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+) extends Module {
+
+ //
+ // Import state enum
+ //
+ import InterpreterScriptBufferHandlerEnums.State
+ import InterpreterScriptBufferHandlerEnums.State._
+
+ val io = IO(new Bundle {
+
+ //
+ // Chip signals
+ //
+ val en = Input(Bool()) // chip enable signal
+
+ //
+ // Receiving signals
+ //
+ val readNextData = Output(Bool()) // whether the next data should be read or not?
+
+ val dataValidInput = Input(Bool()) // whether data on the receiving data line is valid or not?
+ val receivingData = Input(UInt(instanceInfo.bramDataWidth.W)) // data to be received in interpreter
+
+ //
+ // Script stage configuration signals
+ //
+ val finishedScriptConfiguration = Output(Bool()) // whether configuration finished or not?
+ val configureStage = Output(Bool()) // whether the configuration of stage should start or not?
+ val targetOperator = Output(new HwdbgShortSymbol(instanceInfo.scriptVariableLength)) // Current operator to be configured
+ })
+
+ //
+ // State registers
+ //
+ val state = RegInit(sIdle)
+
+ //
+ // Internal registers
+ //
+ val regScriptNumberOfSymbols = Reg(UInt(instanceInfo.bramDataWidth.W))
+
+ //
+ // Output pins
+ //
+ val readNextData = WireInit(false.B)
+
+ val finishedScriptConfiguration = WireInit(false.B)
+ val configureStage = RegInit(false.B)
+
+ val regTargetOperator = Reg(new HwdbgShortSymbol(instanceInfo.scriptVariableLength))
+
+ //
+ // Apply the chip enable signal
+ //
+ when(io.en === true.B) {
+
+ switch(state) {
+
+ is(sIdle) {
+
+ //
+ // Read next data for the size of the buffer
+ //
+ readNextData := true.B
+
+ //
+ // Move to the next state
+ //
+ state := sReadSizeOfBuffer
+ }
+ is(sReadSizeOfBuffer) {
+
+ when(io.dataValidInput) {
+
+ //
+ // Data is valid and number of symbols is now available
+ //
+ regScriptNumberOfSymbols := io.receivingData
+
+ //
+ // Request next data
+ //
+ readNextData := true.B
+
+ //
+ // Move to the configuration state
+ //
+ state := sReadTypeOfOperator
+
+ }.otherwise {
+
+ //
+ // Stay at the same state since the data is not yet received
+ //
+ state := sReadSizeOfBuffer
+ }
+ }
+ is(sReadTypeOfOperator) {
+
+ //
+ // Not valid for configuring yet
+ //
+ configureStage := false.B
+
+ when(io.dataValidInput) {
+
+ //
+ // Request next data
+ //
+ readNextData := true.B
+
+ //
+ // Read the operator's "Type" data
+ //
+ regTargetOperator.Type := io.receivingData
+
+ //
+ // Next, we need to read "Value"
+ //
+ state := sReadValueOfOperator
+
+ }.otherwise {
+
+ //
+ // Stay at the same state since the data is not received yet
+ //
+ state := sReadTypeOfOperator
+ }
+ }
+ is(sReadValueOfOperator) {
+
+ when(io.dataValidInput) {
+
+ //
+ // Configure the stages
+ //
+ configureStage := true.B
+
+ //
+ // Read the operator's "Value" data
+ //
+ regTargetOperator.Value := io.receivingData
+
+ //
+ // Decrement the remaining symbols
+ //
+ regScriptNumberOfSymbols := regScriptNumberOfSymbols - 1.U
+
+ //
+ // Check if reading is scripts are finished or not
+ //
+ when(regScriptNumberOfSymbols === 0.U) {
+
+ //
+ // Configurartion was done
+ //
+ state := sDone
+
+ }.otherwise {
+
+ //
+ // Request next data
+ //
+ readNextData := true.B
+
+ //
+ // Again, read the next type
+ //
+ state := sReadTypeOfOperator
+ }
+ }.otherwise {
+
+ //
+ // Stay at the same state since the data is not received yet
+ //
+ state := sReadValueOfOperator
+ }
+ }
+ is(sDone) {
+
+ //
+ // Not valid for configuring anymore
+ //
+ configureStage := false.B
+
+ //
+ // Finished configuration
+ //
+ finishedScriptConfiguration := true.B
+
+ //
+ // Move to the idle state
+ //
+ state := sIdle
+ }
+ }
+ }
+
+ //
+ // Connect output pins
+ //
+ io.readNextData := readNextData
+
+ io.finishedScriptConfiguration := finishedScriptConfiguration
+ io.configureStage := configureStage
+ io.targetOperator := regTargetOperator
+
+}
+
+object InterpreterScriptBufferHandler {
+
+ def apply(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+ )(
+ en: Bool,
+ dataValidInput: Bool,
+ receivingData: UInt
+ ): (Bool, Bool, Bool, HwdbgShortSymbol) = {
+
+ val interpreterScriptBufferHandler = Module(
+ new InterpreterScriptBufferHandler(
+ debug,
+ instanceInfo
+ )
+ )
+
+ val readNextData = Wire(Bool())
+
+ val finishedScriptConfiguration = Wire(Bool())
+ val configureStage = Wire(Bool())
+ val targetOperator = Wire(new HwdbgShortSymbol(instanceInfo.scriptVariableLength))
+
+ //
+ // Configure the input signals
+ //
+ interpreterScriptBufferHandler.io.en := en
+
+ //
+ // Configure the input signals related to the receiving signals
+ //
+ interpreterScriptBufferHandler.io.dataValidInput := dataValidInput
+ interpreterScriptBufferHandler.io.receivingData := receivingData
+
+ //
+ // Configure the output signals
+ //
+ readNextData := interpreterScriptBufferHandler.io.readNextData
+
+ //
+ // Configure the output signals related to configuring stage operators
+ //
+ finishedScriptConfiguration := interpreterScriptBufferHandler.io.finishedScriptConfiguration
+ configureStage := interpreterScriptBufferHandler.io.configureStage
+ targetOperator := interpreterScriptBufferHandler.io.targetOperator
+
+ //
+ // Return the output result
+ //
+ (
+ readNextData,
+ finishedScriptConfiguration,
+ configureStage,
+ targetOperator
+ )
+ }
+}
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
new file mode 100644
index 00000000..5ae70121
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/communication/interpreter/send_success_or_error.scala
@@ -0,0 +1,125 @@
+/**
+ * @file
+ * send_success_or_error.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Send an indication of invalid packet error or success message (in the interpreter)
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-05-04
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.communication.interpreter
+
+import chisel3._
+import chisel3.util.{switch, is}
+import circt.stage.ChiselStage
+
+import hwdbg.configs._
+
+class InterpreterSendSuccessOrError(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+) extends Module {
+
+ val io = IO(new Bundle {
+
+ //
+ // Chip signals
+ //
+ val en = Input(Bool()) // chip enable signal
+ val lastSuccessOrError = Input(UInt(instanceInfo.bramDataWidth.W)) // input last error
+
+ //
+ // Sending signals
+ //
+ val noNewDataSender = Output(Bool()) // should sender finish sending buffers or not?
+ val dataValidOutput = Output(Bool()) // should sender send next buffer or not?
+ val sendingData = Output(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the debugger
+
+ })
+
+ //
+ // Output pins
+ //
+ val noNewDataSender = WireInit(false.B)
+ val dataValidOutput = WireInit(false.B)
+ val sendingData = WireInit(0.U(instanceInfo.bramDataWidth.W))
+
+ //
+ // Apply the chip enable signal
+ //
+ when(io.en === true.B) {
+
+ //
+ // Set the version
+ //
+ sendingData := io.lastSuccessOrError
+
+ //
+ // Sending the version in one clock cycle
+ //
+ noNewDataSender := true.B
+ dataValidOutput := true.B
+
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Connect output pins
+ //
+ io.noNewDataSender := noNewDataSender
+ io.dataValidOutput := dataValidOutput
+ io.sendingData := sendingData
+
+}
+
+object InterpreterSendSuccessOrError {
+
+ def apply(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+ )(
+ en: Bool,
+ lastSuccessOrError: UInt
+ ): (Bool, Bool, UInt) = {
+
+ val interpreterSendSuccessOrError = Module(
+ new InterpreterSendSuccessOrError(
+ debug,
+ instanceInfo
+ )
+ )
+
+ val noNewDataSender = Wire(Bool())
+ val dataValidOutput = Wire(Bool())
+ val sendingData = Wire(UInt(instanceInfo.bramDataWidth.W))
+
+ //
+ // Configure the input signals
+ //
+ interpreterSendSuccessOrError.io.en := en
+ interpreterSendSuccessOrError.io.lastSuccessOrError := lastSuccessOrError
+
+ //
+ // Configure the output signals
+ //
+ noNewDataSender := interpreterSendSuccessOrError.io.noNewDataSender
+ dataValidOutput := interpreterSendSuccessOrError.io.dataValidOutput
+ sendingData := interpreterSendSuccessOrError.io.sendingData
+
+ //
+ // Return the output result
+ //
+ (
+ noNewDataSender,
+ dataValidOutput,
+ sendingData
+ )
+ }
+}
diff --git a/hwdbg/src/main/scala/hwdbg/communication/receiver.scala b/hwdbg/src/main/scala/hwdbg/communication/receiver.scala
new file mode 100644
index 00000000..e27f9635
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/communication/receiver.scala
@@ -0,0 +1,444 @@
+/**
+ * @file
+ * receiver.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Remote debugger packet receiver module
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-04-08
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.communication
+
+import chisel3._
+import chisel3.util.{switch, is}
+import circt.stage.ChiselStage
+
+import hwdbg.configs._
+import hwdbg.types._
+import hwdbg.utils._
+import hwdbg.constants._
+
+object DebuggerPacketReceiverEnums {
+ object State extends ChiselEnum {
+ val sIdle, sReadChecksum, sReadIndicator, sReadTypeOfThePacket, sReadRequestedActionOfThePacket, sRequestedActionIsValid, sWaitToReadActionBuffer,
+ sReadActionBuffer, sDone = Value
+ }
+}
+
+class DebuggerPacketReceiver(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+) extends Module {
+
+ //
+ // Import state enum
+ //
+ import DebuggerPacketReceiverEnums.State
+ import DebuggerPacketReceiverEnums.State._
+
+ val io = IO(new Bundle {
+
+ //
+ // Chip signals
+ //
+ val en = Input(Bool()) // chip enable signal
+
+ //
+ // Interrupt signals (lines)
+ // Note: Only PL input signal is received here,
+ // a separate module will control the PS signal
+ //
+ val plInSignal = Input(Bool()) // PS to PL signal
+
+ //
+ // BRAM (Block RAM) ports
+ //
+ val rdWrAddr = Output(UInt(instanceInfo.bramAddrWidth.W)) // read/write address
+ val rdData = Input(UInt(instanceInfo.bramDataWidth.W)) // read data
+
+ //
+ // Receiving signals
+ //
+ val requestedActionOfThePacketOutput = Output(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W)) // the requested action
+ val requestedActionOfThePacketOutputValid = Output(Bool()) // whether data on the requested action is valid or not
+ val noNewDataReceiver = Input(Bool()) // receive done or not?
+
+ // this contains and edge-detection mechanism, which means reader should make it low after reading the data
+ val readNextData = Input(Bool()) // whether the next data should be read or not?
+
+ val dataValidOutput = Output(Bool()) // whether data on the receiving data line is valid or not?
+ val receivingData = Output(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the reader
+
+ val finishedReceivingBuffer = Output(Bool()) // Receiving is done or not?
+
+ })
+
+ //
+ // State registers
+ //
+ val state = RegInit(sIdle)
+
+ //
+ // Output pins
+ //
+ val rdWrAddr = WireInit(0.U(instanceInfo.bramAddrWidth.W))
+ val regRdWrAddr = RegInit(0.U(instanceInfo.bramAddrWidth.W))
+ val finishedReceivingBuffer = WireInit(false.B)
+ val regRequestedActionOfThePacketOutput = RegInit(0.U(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W))
+ val regRequestedActionOfThePacketOutputValid = RegInit(false.B)
+ val regDataValidOutput = RegInit(false.B)
+ val regReceivingData = RegInit(0.U(instanceInfo.bramDataWidth.W))
+
+ //
+ // Rising-edge detector for start receiving signal
+ //
+ val risingEdgePlInSignal = io.plInSignal & !RegNext(io.plInSignal)
+
+ //
+ // Rising-edge detector for reading next data signal
+ //
+ val risingEdgeReadNextData = io.readNextData & !RegNext(io.readNextData)
+
+ //
+ // Structure (as wire) of the received packet buffer
+ //
+ val receivedPacketBuffer = WireInit(0.U.asTypeOf(new DebuggerRemotePacket())) // here the wire is not used
+
+ //
+ // Apply the chip enable signal
+ //
+ when(io.en === true.B) {
+
+ switch(state) {
+
+ is(sIdle) {
+
+ //
+ // Create logs from communication structure offsets
+ //
+ LogInfo(debug)(f"The offset of Checksum is 0x${receivedPacketBuffer.Offset.checksum}%x")
+ LogInfo(debug)(f"The offset of Indicator is 0x${receivedPacketBuffer.Offset.indicator}%x")
+ LogInfo(debug)(f"The offset of TypeOfThePacket is 0x${receivedPacketBuffer.Offset.typeOfThePacket}%x")
+ LogInfo(debug)(f"The offset of requestedActionOfThePacketOutput is 0x${receivedPacketBuffer.Offset.requestedActionOfThePacket}%x")
+
+ //
+ // Check whether the interrupt from the PS is received or not
+ //
+ when(risingEdgePlInSignal === true.B) {
+ state := sReadChecksum
+ }
+
+ //
+ // Configure the output pins in case of sIdle
+ //
+ rdWrAddr := 0.U
+ regRequestedActionOfThePacketOutput := 0.U
+ regRequestedActionOfThePacketOutputValid := false.B
+ regDataValidOutput := false.B
+ regReceivingData := 0.U
+ finishedReceivingBuffer := false.B
+
+ }
+ is(sReadChecksum) {
+
+ //
+ // Adjust address to read Checksum from BRAM (Not Used)
+ //
+ rdWrAddr := (instanceInfo.debuggerAreaOffset + receivedPacketBuffer.Offset.checksum).U
+
+ //
+ // Goes to the next section
+ //
+ state := sReadIndicator
+
+ }
+ is(sReadIndicator) {
+
+ //
+ // Adjust address to read Indicator from BRAM
+ //
+ rdWrAddr := (instanceInfo.debuggerAreaOffset + receivedPacketBuffer.Offset.indicator).U
+
+ //
+ // Goes to the next section
+ //
+ state := sReadTypeOfThePacket
+
+ }
+ is(sReadTypeOfThePacket) {
+
+ //
+ // Adjust address to read TypeOfThePacket from BRAM
+ //
+ rdWrAddr := (instanceInfo.debuggerAreaOffset + receivedPacketBuffer.Offset.typeOfThePacket).U
+
+ //
+ // Check whether the indicator is valid or not
+ //
+ LogInfo(debug)(
+ f"Comparing first 0x${BitwiseFunction.getBitsInRange(HyperDbgSharedConstants.INDICATOR_OF_HYPERDBG_PACKET, 32, (32 + instanceInfo.bramDataWidth - 1))}%x number of the indicator (little-endian)"
+ )
+
+ when(
+ io.rdData === BitwiseFunction
+ .getBitsInRange(HyperDbgSharedConstants.INDICATOR_OF_HYPERDBG_PACKET, 32, (32 + instanceInfo.bramDataWidth - 1))
+ .U
+ ) {
+
+ //
+ // Indicator of packet is valid
+ // (Goes to the next section)
+ //
+ state := sReadRequestedActionOfThePacket
+
+ }.otherwise {
+
+ //
+ // Indicator of packet is not valid
+ // (Receiving was done but not found a valid packet,
+ // so, go to the idle state)
+ //
+ state := sDone
+ }
+ }
+ is(sReadRequestedActionOfThePacket) {
+
+ //
+ // Adjust address to read RequestedActionOfThePacket from BRAM
+ //
+ rdWrAddr := (instanceInfo.debuggerAreaOffset + receivedPacketBuffer.Offset.requestedActionOfThePacket).U
+
+ //
+ // Save the address into a register
+ //
+ regRdWrAddr := (instanceInfo.debuggerAreaOffset + receivedPacketBuffer.Offset.requestedActionOfThePacket + (instanceInfo.bramDataWidth >> 3)).U
+
+ //
+ // Check whether the type of the packet is valid or not
+ //
+ val packetType: DebuggerRemotePacketType.Value = DebuggerRemotePacketType.DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL
+ LogInfo(debug)(
+ f"Check packet type with DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL (0x${packetType.id}%x)"
+ )
+ when(io.rdData === packetType.id.U) {
+
+ //
+ // Type of packet is valid
+ // (Goes to the next section)
+ //
+ state := sRequestedActionIsValid
+
+ }.otherwise {
+
+ //
+ // Type of packet is not valid
+ // (Receiving was done but not found a valid packet,
+ // so, go to the idle state)
+ //
+ state := sDone
+ }
+
+ }
+ is(sRequestedActionIsValid) {
+
+ //
+ // Read the RequestedActionOfThePacket
+ //
+ regRequestedActionOfThePacketOutput := io.rdData
+
+ //
+ // The RequestedActionOfThePacketOutput is valid from now
+ //
+ regRequestedActionOfThePacketOutputValid := true.B
+
+ //
+ // Goes to the next section
+ //
+ state := sWaitToReadActionBuffer
+
+ }
+ is(sWaitToReadActionBuffer) {
+
+ //
+ // The value of the received buffer is valid here, however,
+ // in order to make difference when a new value is read, the
+ // following signals goes to the off state
+ //
+ regDataValidOutput := false.B
+
+ //
+ // Check if the caller needs to read the next part of
+ // the block RAM or the receiving data should be finished
+ //
+ when(io.noNewDataReceiver === true.B) {
+
+ //
+ // No new data, the receiving is done
+ //
+ state := sDone
+
+ }.elsewhen(risingEdgeReadNextData === true.B) {
+
+ //
+ // Adjust address to read next data to BRAM
+ //
+ rdWrAddr := regRdWrAddr
+ regRdWrAddr := regRdWrAddr + (instanceInfo.bramDataWidth >> 3).U
+
+ //
+ // Read the next offset of the buffer
+ //
+ state := sReadActionBuffer
+
+ }.otherwise {
+
+ //
+ // Stay at the same state
+ //
+ state := sWaitToReadActionBuffer
+ }
+
+ }
+ is(sReadActionBuffer) {
+
+ //
+ // Data outputs are now valid
+ //
+ regDataValidOutput := true.B
+
+ //
+ // Adjust the read buffer data
+ //
+ regReceivingData := io.rdData
+
+ when(io.noNewDataReceiver === true.B) {
+
+ //
+ // No new data, the receiving is done
+ //
+ state := sDone
+
+ }.otherwise {
+
+ //
+ // Return to the previous state of action
+ //
+ state := sWaitToReadActionBuffer
+
+ }
+
+ }
+ is(sDone) {
+
+ //
+ // Reset the temporary address holder
+ //
+ regRdWrAddr := 0.U
+
+ //
+ // Requested action buffer and the receiving buffer is no longer valid
+ //
+ regRequestedActionOfThePacketOutput := 0.U
+ regRequestedActionOfThePacketOutputValid := false.B
+ regReceivingData := 0.U
+ regDataValidOutput := false.B
+
+ //
+ // The receiving is done at this stage, either
+ // was successful or unsuccessful, we'll release the
+ // sharing bram resource by indicating that the receiving
+ // module is no longer using the bram line
+ //
+ finishedReceivingBuffer := true.B
+
+ //
+ // Go to the idle state
+ //
+ state := sIdle
+ }
+ }
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Connect output pins
+ //
+ io.rdWrAddr := rdWrAddr
+ io.requestedActionOfThePacketOutput := regRequestedActionOfThePacketOutput
+ io.requestedActionOfThePacketOutputValid := regRequestedActionOfThePacketOutputValid
+ io.dataValidOutput := regDataValidOutput
+ io.receivingData := regReceivingData
+ io.finishedReceivingBuffer := finishedReceivingBuffer
+
+}
+
+object DebuggerPacketReceiver {
+
+ def apply(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+ )(
+ en: Bool,
+ plInSignal: Bool,
+ rdData: UInt,
+ noNewDataReceiver: Bool,
+ readNextData: Bool
+ ): (UInt, UInt, Bool, Bool, UInt, Bool) = {
+
+ val debuggerPacketReceiver = Module(
+ new DebuggerPacketReceiver(
+ debug,
+ instanceInfo
+ )
+ )
+
+ val rdWrAddr = Wire(UInt(instanceInfo.bramAddrWidth.W))
+ val requestedActionOfThePacketOutput = Wire(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W))
+ val requestedActionOfThePacketOutputValid = Wire(Bool())
+ val dataValidOutput = Wire(Bool())
+ val receivingData = Wire(UInt(instanceInfo.bramDataWidth.W))
+ val finishedReceivingBuffer = Wire(Bool())
+
+ //
+ // Configure the input signals
+ //
+ debuggerPacketReceiver.io.en := en
+ debuggerPacketReceiver.io.plInSignal := plInSignal
+ debuggerPacketReceiver.io.rdData := rdData
+ debuggerPacketReceiver.io.noNewDataReceiver := noNewDataReceiver
+ debuggerPacketReceiver.io.readNextData := readNextData
+
+ //
+ // Configure the output signals
+ //
+ rdWrAddr := debuggerPacketReceiver.io.rdWrAddr
+
+ //
+ // Configure the output signals related to received packets
+ //
+ requestedActionOfThePacketOutput := debuggerPacketReceiver.io.requestedActionOfThePacketOutput
+ requestedActionOfThePacketOutputValid := debuggerPacketReceiver.io.requestedActionOfThePacketOutputValid
+ dataValidOutput := debuggerPacketReceiver.io.dataValidOutput
+ receivingData := debuggerPacketReceiver.io.receivingData
+ finishedReceivingBuffer := debuggerPacketReceiver.io.finishedReceivingBuffer
+
+ //
+ // Return the output result
+ //
+ (
+ rdWrAddr,
+ requestedActionOfThePacketOutput,
+ requestedActionOfThePacketOutputValid,
+ dataValidOutput,
+ receivingData,
+ finishedReceivingBuffer
+ )
+ }
+}
diff --git a/hwdbg/src/main/scala/hwdbg/communication/send_receive_synchronizer.scala b/hwdbg/src/main/scala/hwdbg/communication/send_receive_synchronizer.scala
new file mode 100644
index 00000000..4ebf5a74
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/communication/send_receive_synchronizer.scala
@@ -0,0 +1,383 @@
+/**
+ * @file
+ * send_receive_synchronizer.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Send and receive synchronizer module
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-04-17
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.communication
+
+import chisel3._
+import chisel3.util.{switch, is}
+import circt.stage.ChiselStage
+
+import hwdbg.configs._
+import hwdbg.types._
+
+object SendReceiveSynchronizerEnums {
+ object State extends ChiselEnum {
+ val sIdle, sReceiver, sSender = Value
+ }
+}
+
+class SendReceiveSynchronizer(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+) extends Module {
+
+ //
+ // Import state enum
+ //
+ import SendReceiveSynchronizerEnums.State
+ import SendReceiveSynchronizerEnums.State._
+
+ val io = IO(new Bundle {
+
+ //
+ // Chip signals
+ //
+ val en = Input(Bool()) // chip enable signal
+
+ //
+ // Interrupt signals (lines)
+ //
+ val plInSignal = Input(Bool()) // PS to PL signal
+ val psOutInterrupt = Output(Bool()) // PL to PS interrupt
+
+ //
+ // BRAM (Block RAM) ports
+ //
+ val rdWrAddr = Output(UInt(instanceInfo.bramAddrWidth.W)) // read/write address
+ val rdData = Input(UInt(instanceInfo.bramDataWidth.W)) // read data
+ val wrEna = Output(Bool()) // enable writing
+ val wrData = Output(UInt(instanceInfo.bramDataWidth.W)) // write data
+
+ //
+ // Receiver ports
+ //
+ val requestedActionOfThePacketOutput = Output(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W)) // the requested action
+ val requestedActionOfThePacketOutputValid = Output(Bool()) // whether data on the requested action is valid or not
+
+ val noNewDataReceiver = Input(Bool()) // receive done or not?
+ val readNextData = Input(Bool()) // whether the next data should be read or not?
+
+ val dataValidOutput = Output(Bool()) // whether data on the receiving data line is valid or not?
+ val receivingData = Output(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the reader
+
+ //
+ // Sender ports
+ //
+ val beginSendingBuffer = Input(Bool()) // should sender start sending buffers or not?
+ val noNewDataSender = Input(Bool()) // should sender finish sending buffers or not?
+ val dataValidInput = Input(Bool()) // should sender send next buffer or not?
+
+ val sendWaitForBuffer = Output(Bool()) // should the external module send next buffer or not?
+
+ val requestedActionOfThePacketInput = Input(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W)) // the requested action
+ val sendingData = Input(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the debugger
+
+ })
+
+ //
+ // State registers
+ //
+ val state = RegInit(sIdle)
+
+ //
+ // Saving state of the controlling pins
+ //
+ val regPlInSignal = RegInit(false.B)
+ val regBeginSendingBuffer = RegInit(false.B)
+
+ //
+ // Shared BRAM pins
+ //
+ val sharedRdWrAddr = WireInit(0.U(instanceInfo.bramAddrWidth.W)) // read/write address
+ val sharedRdData = WireInit(0.U(instanceInfo.bramDataWidth.W)) // read data
+ val sharedWrEna = WireInit(false.B) // enable writing
+ val sharedWrData = WireInit(0.U(instanceInfo.bramDataWidth.W)) // write data
+
+ //
+ // Instantiate the packet receiver module
+ //
+ val (
+ receiverRdWrAddr,
+ requestedActionOfThePacketOutput,
+ requestedActionOfThePacketOutputValid,
+ dataValidOutput,
+ receivingData,
+ finishedReceivingBuffer
+ ) =
+ DebuggerPacketReceiver(
+ debug,
+ instanceInfo
+ )(
+ io.en,
+ regPlInSignal,
+ io.rdData,
+ io.noNewDataReceiver,
+ io.readNextData
+ )
+
+ //
+ // Instantiate the packet sender module
+ //
+ val (
+ psOutInterrupt,
+ senderRdWrAddr,
+ wrEna,
+ wrData,
+ sendWaitForBuffer,
+ finishedSendingBuffer
+ ) =
+ DebuggerPacketSender(
+ debug,
+ instanceInfo
+ )(
+ io.en,
+ regBeginSendingBuffer,
+ io.noNewDataSender,
+ io.dataValidInput,
+ io.requestedActionOfThePacketInput,
+ io.sendingData
+ )
+
+ //
+ // Apply the chip enable signal
+ //
+ when(io.en === true.B) {
+
+ switch(state) {
+
+ is(sIdle) {
+
+ //
+ // Perform the resource separation of shared BRAM
+ // and apply priority to receive over send
+ //
+ when(io.plInSignal === true.B) {
+
+ //
+ // Activate the receiver module
+ //
+ regPlInSignal := true.B
+
+ //
+ // Go to the receiver state
+ //
+ state := sReceiver
+
+ }.elsewhen(io.beginSendingBuffer === true.B && io.plInSignal === false.B) {
+
+ //
+ // Activate the sender module
+ //
+ regBeginSendingBuffer := true.B
+
+ //
+ // Go to the sender state
+ //
+ state := sSender
+
+ }.otherwise {
+
+ //
+ // Stay at the same state as there is no communication
+ //
+ state := sIdle
+
+ }
+
+ }
+ is(sReceiver) {
+
+ //
+ // Check whether the receiving is finished
+ //
+ when(finishedReceivingBuffer === true.B) {
+
+ //
+ // No longer in the receiver state
+ //
+ regPlInSignal := false.B
+
+ //
+ // Go to the idle state
+ //
+ state := sIdle
+
+ }.otherwise {
+
+ //
+ // Connect the address of BRAM reader to the receiver address
+ //
+ sharedRdWrAddr := receiverRdWrAddr
+
+ //
+ // On the receiver, writing is not allowed
+ //
+ sharedWrEna := false.B
+
+ //
+ // Stay at the same state
+ //
+ state := sReceiver
+
+ }
+ }
+ is(sSender) {
+
+ //
+ // Check whether sending data is finished
+ //
+ when(finishedSendingBuffer === true.B) {
+
+ //
+ // No longer in the sender state
+ //
+ regBeginSendingBuffer := false.B
+
+ //
+ // Go to the idle state
+ //
+ state := sIdle
+
+ }.otherwise {
+
+ //
+ // Connect shared BRAM signals to the sender
+ //
+ sharedRdWrAddr := senderRdWrAddr
+ sharedWrEna := wrEna
+ sharedWrData := wrData
+
+ //
+ // Stay at the same state
+ //
+ state := sSender
+
+ }
+ }
+ }
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Connect output pins (Interrupt)
+ //
+ io.psOutInterrupt := psOutInterrupt
+
+ //
+ // Connect output pins (BRAM)
+ //
+ io.rdWrAddr := sharedRdWrAddr
+ io.wrEna := wrEna
+ io.wrData := wrData
+
+ //
+ // Connect output pins (Receiver)
+ //
+ io.requestedActionOfThePacketOutput := requestedActionOfThePacketOutput
+ io.requestedActionOfThePacketOutputValid := requestedActionOfThePacketOutputValid
+ io.dataValidOutput := dataValidOutput
+ io.receivingData := receivingData
+
+ //
+ // Connect output pins (Sender)
+ //
+ io.sendWaitForBuffer := sendWaitForBuffer
+
+}
+
+object SendReceiveSynchronizer {
+
+ def apply(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+ )(
+ en: Bool,
+ plInSignal: Bool,
+ rdData: UInt,
+ noNewDataReceiver: Bool,
+ readNextData: Bool,
+ beginSendingBuffer: Bool,
+ noNewDataSender: Bool,
+ dataValidInput: Bool,
+ requestedActionOfThePacketInput: UInt,
+ sendingData: UInt
+ ): (Bool, UInt, Bool, UInt, UInt, Bool, Bool, UInt, Bool) = {
+
+ val sendReceiveSynchronizerModule = Module(
+ new SendReceiveSynchronizer(
+ debug,
+ instanceInfo
+ )
+ )
+
+ val psOutInterrupt = Wire(Bool())
+
+ val rdWrAddr = Wire(UInt(instanceInfo.bramAddrWidth.W))
+ val wrEna = Wire(Bool())
+ val wrData = Wire(UInt(instanceInfo.bramDataWidth.W))
+
+ val requestedActionOfThePacketOutput = Wire(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W))
+ val requestedActionOfThePacketOutputValid = Wire(Bool())
+ val dataValidOutput = Wire(Bool())
+ val receivingData = Wire(UInt(instanceInfo.bramDataWidth.W))
+
+ val sendWaitForBuffer = Wire(Bool())
+
+ //
+ // Configure the input signals
+ //
+ sendReceiveSynchronizerModule.io.en := en
+ sendReceiveSynchronizerModule.io.plInSignal := plInSignal
+ sendReceiveSynchronizerModule.io.rdData := rdData
+ sendReceiveSynchronizerModule.io.noNewDataReceiver := noNewDataReceiver
+ sendReceiveSynchronizerModule.io.readNextData := readNextData
+ sendReceiveSynchronizerModule.io.beginSendingBuffer := beginSendingBuffer
+ sendReceiveSynchronizerModule.io.noNewDataSender := noNewDataSender
+ sendReceiveSynchronizerModule.io.dataValidInput := dataValidInput
+ sendReceiveSynchronizerModule.io.requestedActionOfThePacketInput := requestedActionOfThePacketInput
+ sendReceiveSynchronizerModule.io.sendingData := sendingData
+
+ //
+ // Configure the output signals
+ //
+ psOutInterrupt := sendReceiveSynchronizerModule.io.psOutInterrupt
+ rdWrAddr := sendReceiveSynchronizerModule.io.rdWrAddr
+ wrEna := sendReceiveSynchronizerModule.io.wrEna
+ wrData := sendReceiveSynchronizerModule.io.wrData
+
+ requestedActionOfThePacketOutput := sendReceiveSynchronizerModule.io.requestedActionOfThePacketOutput
+ requestedActionOfThePacketOutputValid := sendReceiveSynchronizerModule.io.requestedActionOfThePacketOutputValid
+ dataValidOutput := sendReceiveSynchronizerModule.io.dataValidOutput
+ receivingData := sendReceiveSynchronizerModule.io.receivingData
+
+ sendWaitForBuffer := sendReceiveSynchronizerModule.io.sendWaitForBuffer
+
+ //
+ // Return the output result
+ //
+ (
+ psOutInterrupt,
+ rdWrAddr,
+ wrEna,
+ wrData,
+ requestedActionOfThePacketOutput,
+ requestedActionOfThePacketOutputValid,
+ dataValidOutput,
+ receivingData,
+ sendWaitForBuffer
+ )
+ }
+}
diff --git a/hwdbg/src/main/scala/hwdbg/communication/sender.scala b/hwdbg/src/main/scala/hwdbg/communication/sender.scala
new file mode 100644
index 00000000..e1c049d9
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/communication/sender.scala
@@ -0,0 +1,494 @@
+/**
+ * @file
+ * sender.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Remote debugger packet sender module
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-04-16
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.communication
+
+import chisel3._
+import chisel3.util.{switch, is, log2Ceil}
+import circt.stage.ChiselStage
+
+import hwdbg.configs._
+import hwdbg.types._
+import hwdbg.constants._
+
+object DebuggerPacketSenderEnums {
+ object State extends ChiselEnum {
+ val sIdle, sWriteChecksum, sWriteIndicator, sWriteTypeOfThePacket, sWriteRequestedActionOfThePacket, sWaitToGetData, sSendData, sDone = Value
+ }
+}
+
+class DebuggerPacketSender(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+) extends Module {
+
+ //
+ // Import state enum
+ //
+ import DebuggerPacketSenderEnums.State
+ import DebuggerPacketSenderEnums.State._
+
+ val io = IO(new Bundle {
+
+ //
+ // Chip signals
+ //
+ val en = Input(Bool()) // chip enable signal
+
+ //
+ // Interrupt signals (lines)
+ // Note: Only PS output signal is exported here,
+ // a separate module will control the PL signal
+ //
+ val psOutInterrupt = Output(Bool()) // PL to PS interrupt
+
+ //
+ // BRAM (Block RAM) ports
+ //
+ val rdWrAddr = Output(UInt(instanceInfo.bramAddrWidth.W)) // read/write address
+ val wrEna = Output(Bool()) // enable writing
+ val wrData = Output(UInt(instanceInfo.bramDataWidth.W)) // write data
+
+ //
+ // Sending signals
+ //
+ val beginSendingBuffer = Input(Bool()) // should sender start sending buffers or not?
+ val noNewDataSender = Input(Bool()) // should sender finish sending buffers or not?
+ val dataValidInput = Input(Bool()) // should sender send next buffer or not?
+
+ val sendWaitForBuffer = Output(Bool()) // should the external module send next buffer or not?
+ val finishedSendingBuffer = Output(Bool()) // indicate that the sender finished sending buffers and ready to send next packet
+
+ val requestedActionOfThePacketInput = Input(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W)) // the requested action
+ val sendingData = Input(UInt(instanceInfo.bramDataWidth.W)) // data to be sent to the debugger
+
+ })
+
+ //
+ // State registers
+ //
+ val state = RegInit(sIdle)
+
+ //
+ // Output pins
+ //
+ val psOutInterrupt = WireInit(false.B)
+ val wrEna = WireInit(false.B)
+ val wrData = WireInit(0.U(instanceInfo.bramDataWidth.W))
+ val sendWaitForBuffer = WireInit(false.B)
+ val finishedSendingBuffer = WireInit(false.B)
+ val rdWrAddr = WireInit(0.U(instanceInfo.bramAddrWidth.W))
+
+ //
+ // Temporary address and data holder (register)
+ //
+ val regRdWrAddr = RegInit(0.U(instanceInfo.bramAddrWidth.W))
+ val regDataToSend = RegInit(0.U(instanceInfo.bramDataWidth.W))
+
+ //
+ // Rising-edge detector for start sending signal
+ //
+ val risingEdgeBeginSendingBuffer = io.beginSendingBuffer & !RegNext(io.beginSendingBuffer)
+
+ //
+ // Keeping the state of whether sending data has been started or not
+ // Means that if the sender is in the middle of sending the headers
+ // of the packet or the actual data
+ //
+ val regIsSendingDataStarted = RegInit(false.B)
+
+ //
+ // Used to hold the transferred length of the indicator
+ //
+ val lengthOfIndicator: Int = new DebuggerRemotePacket().Indicator.getWidth
+ val regTransferredIndicatorLength = RegInit(0.U((log2Ceil(lengthOfIndicator) + 1).W))
+
+ //
+ // Structure (as wire) of the received packet buffer
+ //
+ val sendingPacketBuffer = WireInit(0.U.asTypeOf(new DebuggerRemotePacket()))
+
+ //
+ // Apply the chip enable signal
+ //
+ when(io.en === true.B) {
+
+ switch(state) {
+
+ is(sIdle) {
+
+ //
+ // Check whether the interrupt from the PS is received or not
+ //
+ when(risingEdgeBeginSendingBuffer === true.B) {
+ state := sWriteChecksum
+ }
+
+ //
+ // Configure the outputs in case of sIdle
+ //
+ psOutInterrupt := false.B
+ rdWrAddr := 0.U
+ regRdWrAddr := 0.U
+ wrEna := false.B
+ wrData := 0.U
+ sendWaitForBuffer := false.B
+ finishedSendingBuffer := false.B
+
+ //
+ // Sending data has not been started
+ //
+ regIsSendingDataStarted := false.B
+
+ }
+ is(sWriteChecksum) {
+
+ //
+ // Enable writing to the BRAM
+ //
+ wrEna := true.B
+
+ //
+ // Adjust address to write Checksum to BRAM (Not Used)
+ //
+ rdWrAddr := (instanceInfo.debuggeeAreaOffset + sendingPacketBuffer.Offset.checksum).U
+
+ //
+ // Adjust data to write Checksum
+ //
+ wrData := 0.U // Checksum is ignored
+
+ //
+ // Reset the transferred bytes of the indicator
+ //
+ regTransferredIndicatorLength := 0.U
+
+ //
+ // Goes to the next section
+ //
+ state := sWriteIndicator
+ }
+ is(sWriteIndicator) {
+
+ if (instanceInfo.bramDataWidth >= lengthOfIndicator) {
+
+ //
+ // Enable writing to the BRAM
+ //
+ wrEna := true.B
+
+ //
+ // Adjust address to write Indicator to BRAM
+ //
+ rdWrAddr := (instanceInfo.debuggeeAreaOffset + sendingPacketBuffer.Offset.indicator).U
+
+ //
+ // Adjust data to write Indicator
+ //
+ wrData := HyperDbgSharedConstants.INDICATOR_OF_HYPERDBG_PACKET.U
+
+ //
+ // Goes to the next section
+ //
+ state := sWriteTypeOfThePacket
+
+ } else {
+
+ //
+ // Enable writing to the BRAM
+ //
+ wrEna := true.B
+
+ //
+ // Adjust address to write Indicator to BRAM (Address granularity is in the byte format so,
+ // it'll be divided by 8 or shift to right by 3)
+ //
+ rdWrAddr := (instanceInfo.debuggeeAreaOffset + sendingPacketBuffer.Offset.indicator).U + (regTransferredIndicatorLength >> 3)
+
+ //
+ // Adjust data to write Indicator
+ //
+ wrData := HyperDbgSharedConstants.INDICATOR_OF_HYPERDBG_PACKET.U >> regTransferredIndicatorLength
+
+ //
+ // Add to the transferred length
+ //
+ regTransferredIndicatorLength := regTransferredIndicatorLength + instanceInfo.bramDataWidth.U
+
+ when(regTransferredIndicatorLength >= lengthOfIndicator.U) {
+
+ //
+ // Disable writing to the BRAM
+ //
+ wrEna := false.B
+
+ //
+ // Goes to the next section
+ //
+ state := sWriteTypeOfThePacket
+
+ }.otherwise {
+
+ //
+ // Stay at the same state
+ //
+ state := sWriteIndicator
+ }
+ }
+ }
+ is(sWriteTypeOfThePacket) {
+
+ //
+ // Enable writing to the BRAM
+ //
+ wrEna := true.B
+
+ //
+ // Adjust address to write type of packet to BRAM
+ //
+ rdWrAddr := (instanceInfo.debuggeeAreaOffset + sendingPacketBuffer.Offset.typeOfThePacket).U
+
+ //
+ // Adjust data to write type of packet
+ //
+ val packetType: DebuggerRemotePacketType.Value = DebuggerRemotePacketType.DEBUGGEE_TO_DEBUGGER_HARDWARE_LEVEL
+ wrData := packetType.id.U
+
+ //
+ // Goes to the next section
+ //
+ state := sWriteRequestedActionOfThePacket
+
+ }
+ is(sWriteRequestedActionOfThePacket) {
+
+ //
+ // Enable writing to the BRAM
+ //
+ wrEna := true.B
+
+ //
+ // Adjust address to write requested action of packet to BRAM
+ //
+ rdWrAddr := (instanceInfo.debuggeeAreaOffset + sendingPacketBuffer.Offset.requestedActionOfThePacket).U
+
+ //
+ // Adjust data to write requested action of packet
+ //
+ wrData := io.requestedActionOfThePacketInput
+
+ //
+ // Goes to the next section
+ //
+ state := sWaitToGetData
+
+ }
+ is(sWaitToGetData) {
+
+ //
+ // Disable writing to the BRAM
+ //
+ wrEna := false.B
+
+ //
+ // Indicate that the module is waiting for data
+ //
+ sendWaitForBuffer := true.B
+
+ //
+ // Check whether sending actual data already started or not
+ //
+ when(regIsSendingDataStarted === false.B) {
+
+ //
+ // It's not yet started, so we adjust the address to the start
+ // of the buffer after the last field of the header
+ //
+ regRdWrAddr := (instanceInfo.debuggeeAreaOffset + sendingPacketBuffer.Offset.startOfDataBuffer).U
+
+ //
+ // Indicate that sending data already started
+ //
+ regIsSendingDataStarted := true.B
+ }
+
+ //
+ // Wait to receive the data or check whether sending was done at this state
+ // (Two states will go us to the 'done' state)
+ //
+ when(io.noNewDataSender === true.B) {
+
+ //
+ // Sending data was done
+ //
+ state := sDone
+
+ }.elsewhen(io.dataValidInput === true.B) {
+
+ //
+ // Store the data to send in a register
+ //
+ regDataToSend := io.sendingData
+
+ //
+ // The data is valid, so let's send it
+ //
+ state := sSendData
+
+ }.otherwise {
+
+ //
+ // Stay in the same state as the data is not ready (valid)
+ //
+ state := sWaitToGetData
+ }
+
+ }
+ is(sSendData) {
+
+ //
+ // Not waiting for the buffer at this state
+ //
+ sendWaitForBuffer := false.B
+
+ //
+ // Enable writing to the BRAM
+ //
+ wrEna := true.B
+
+ //
+ // Adjust address to write next data to BRAM (Address granularity is in the byte format so,
+ // it'll be divided by 8 or shift to right by 3)
+ //
+ rdWrAddr := regRdWrAddr
+ regRdWrAddr := regRdWrAddr + (instanceInfo.bramDataWidth >> 3).U
+
+ //
+ // Adjust data to write as the sending data
+ //
+ wrData := regDataToSend
+
+ //
+ // Check whether sending was done at this state (Two states will go us to the 'done' state)
+ //
+ when(io.noNewDataSender === true.B) {
+
+ //
+ // Sending data was done
+ //
+ state := sDone
+
+ }.otherwise {
+
+ //
+ // Again go to the state for waiting for new data
+ //
+ state := sWaitToGetData
+
+ }
+
+ }
+ is(sDone) {
+
+ //
+ // Adjust the output bits
+ //
+ finishedSendingBuffer := true.B
+
+ //
+ // Interrupt the PS
+ //
+ psOutInterrupt := true.B
+
+ //
+ // Go to the idle state
+ //
+ state := sIdle
+ }
+ }
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Connect output pins to internal registers
+ //
+ io.psOutInterrupt := psOutInterrupt
+ io.rdWrAddr := rdWrAddr
+ io.wrEna := wrEna
+ io.wrData := wrData
+ io.sendWaitForBuffer := sendWaitForBuffer
+ io.finishedSendingBuffer := finishedSendingBuffer
+
+}
+
+object DebuggerPacketSender {
+
+ def apply(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+ )(
+ en: Bool,
+ beginSendingBuffer: Bool,
+ noNewDataSender: Bool,
+ dataValidInput: Bool,
+ requestedActionOfThePacketInput: UInt,
+ sendingData: UInt
+ ): (Bool, UInt, Bool, UInt, Bool, Bool) = {
+
+ val debuggerPacketSender = Module(
+ new DebuggerPacketSender(
+ debug,
+ instanceInfo
+ )
+ )
+
+ val psOutInterrupt = Wire(Bool())
+ val rdWrAddr = Wire(UInt(instanceInfo.bramAddrWidth.W))
+ val wrEna = Wire(Bool())
+ val wrData = Wire(UInt(instanceInfo.bramDataWidth.W))
+ val sendWaitForBuffer = Wire(Bool())
+ val finishedSendingBuffer = Wire(Bool())
+
+ //
+ // Configure the input signals
+ //
+ debuggerPacketSender.io.en := en
+ debuggerPacketSender.io.beginSendingBuffer := beginSendingBuffer
+ debuggerPacketSender.io.noNewDataSender := noNewDataSender
+ debuggerPacketSender.io.dataValidInput := dataValidInput
+ debuggerPacketSender.io.requestedActionOfThePacketInput := requestedActionOfThePacketInput
+ debuggerPacketSender.io.sendingData := sendingData
+
+ //
+ // Configure the output signals
+ //
+ psOutInterrupt := debuggerPacketSender.io.psOutInterrupt
+ rdWrAddr := debuggerPacketSender.io.rdWrAddr
+ wrEna := debuggerPacketSender.io.wrEna
+ wrData := debuggerPacketSender.io.wrData
+
+ //
+ // Configure the output signals related to sending packets
+ //
+ sendWaitForBuffer := debuggerPacketSender.io.sendWaitForBuffer
+ finishedSendingBuffer := debuggerPacketSender.io.finishedSendingBuffer
+
+ //
+ // Return the output result
+ //
+ (psOutInterrupt, rdWrAddr, wrEna, wrData, sendWaitForBuffer, finishedSendingBuffer)
+ }
+}
diff --git a/hwdbg/src/main/scala/hwdbg/configs/config.json b/hwdbg/src/main/scala/hwdbg/configs/config.json
new file mode 100644
index 00000000..b2fb33f2
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/configs/config.json
@@ -0,0 +1,52 @@
+{
+ "Version": {
+ "VERSION_MAJOR": 0,
+ "VERSION_MINOR": 2,
+ "VERSION_PATCH": 0
+ },
+ "DebuggerConfigurations": {
+ "ENABLE_DEBUG": true,
+ "NUMBER_OF_PINS": 32,
+ "PORT_PINS_MAP": [12, 20]
+ },
+ "ScriptEngineConfigurations": {
+ "MAXIMUM_NUMBER_OF_STAGES": 32,
+ "MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS": 2,
+ "MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS": 1,
+ "SCRIPT_VARIABLE_LENGTH": 8,
+ "NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES": 2,
+ "NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES": 2,
+ "SCRIPT_ENGINE_EVAL_CAPABILITIES": [
+ "assign_local_global_var",
+ "assign_registers",
+ "conditional_statements_and_comparison_operators",
+ "stack_assignments",
+ "func_or",
+ "func_xor",
+ "func_and",
+ "func_asl",
+ "func_add",
+ "func_sub",
+ "func_mul",
+ "func_gt",
+ "func_lt",
+ "func_egt",
+ "func_elt",
+ "func_equal",
+ "func_neq",
+ "func_jmp",
+ "func_jz",
+ "func_jnz",
+ "func_mov"
+ ]
+ },
+ "MemoryCommunicationConfigurations": {
+ "BLOCK_RAM_ADDR_WIDTH": 13,
+ "BLOCK_RAM_DATA_WIDTH": 32,
+ "ENABLE_BLOCK_RAM_DELAY": true,
+ "DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE": 1024,
+ "BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION": 0,
+ "BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION": 512
+ }
+ }
+
\ No newline at end of file
diff --git a/hwdbg/src/main/scala/hwdbg/configs/configs.scala b/hwdbg/src/main/scala/hwdbg/configs/configs.scala
new file mode 100644
index 00000000..a315055b
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/configs/configs.scala
@@ -0,0 +1,500 @@
+/**
+ * @file
+ * configs.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Configuration files
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-04-03
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.configs
+
+import io.circe._
+import io.circe.parser._
+import io.circe.generic.auto._
+import scala.io.Source
+
+import chisel3._
+import chisel3.util._
+
+import hwdbg.utils._
+
+/**
+ * @brief
+ * Version of hwdbg (Definition and Default Values)
+ * @warning
+ * will be checked with HyperDbg
+ */
+object Version {
+
+ //
+ // Constant version info
+ //
+ var VERSION_MAJOR: Int = 0
+ var VERSION_MINOR: Int = 1
+ var VERSION_PATCH: Int = 0
+
+ def getEncodedVersion: Int = {
+ (VERSION_MAJOR << 16) | (VERSION_MINOR << 8) | VERSION_PATCH
+ }
+
+ def extractMajor(encodedVersion: Int): Int = {
+ encodedVersion >> 16
+ }
+
+ def extractMinor(encodedVersion: Int): Int = {
+ (encodedVersion >> 8) & 0xff // Masking to get only the 8 bits
+ }
+
+ def extractPatch(encodedVersion: Int): Int = {
+ encodedVersion & 0xff // Masking to get only the 8 bits
+ }
+}
+
+/**
+ * @brief
+ * Design constants (Definition and Default Values)
+ */
+object DebuggerConfigurations {
+
+ //
+ // whether to enable debug or not
+ //
+ var ENABLE_DEBUG: Boolean = true
+
+ //
+ // Number of input/output pins
+ //
+ var NUMBER_OF_PINS: Int = 32
+
+ //
+ // The configuration of ports and pins
+ //
+ // The following constant shows the key value object of the mappings
+ // of pins to ports (used for inputs/outputs)
+ // For example,
+ // port 0 (in) -> contains 12 pins
+ // port 1 (in) -> contains 20 pins
+ //
+ // var PORT_PINS_MAP: Array[Int] = Array(12, 18, 2)
+ // var PORT_PINS_MAP: Array[Int] = Array(12, 10, 5, 3, 2)
+ var PORT_PINS_MAP: Array[Int] = Array(12, 20)
+}
+
+/**
+ * @brief
+ * Design constants for script engine (Definition and Default Values)
+ */
+object ScriptEngineConfigurations {
+
+ //
+ // Maximum number of stages
+ //
+ var MAXIMUM_NUMBER_OF_STAGES: Int = 32
+
+ //
+ // Maximum number of stages
+ //
+ var MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS: Int = 2 // for get values
+
+ //
+ // Maximum number of stages
+ //
+ var MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS: Int = 1 // for get value
+
+ //
+ // Script variable length
+ //
+ var SCRIPT_VARIABLE_LENGTH: Int = 8
+
+ //
+ // Number supported of local and global variables
+ //
+ var NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES: Int = 2
+
+ //
+ // Number supported of temporary variables
+ //
+ var NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES: Int = 2
+
+ //
+ // Define the capabilities you want to enable
+ //
+ var SCRIPT_ENGINE_EVAL_CAPABILITIES = Seq(
+ //
+ // Statements and expressions
+ //
+ HwdbgScriptCapabilities.assign_local_global_var,
+ HwdbgScriptCapabilities.assign_registers,
+ // HwdbgScriptCapabilities.assign_pseudo_registers,
+ HwdbgScriptCapabilities.conditional_statements_and_comparison_operators,
+ HwdbgScriptCapabilities.stack_assignments,
+
+ //
+ // Operators
+ //
+ HwdbgScriptCapabilities.func_or,
+ HwdbgScriptCapabilities.func_xor,
+ HwdbgScriptCapabilities.func_and,
+ HwdbgScriptCapabilities.func_asl,
+ HwdbgScriptCapabilities.func_add,
+ HwdbgScriptCapabilities.func_sub,
+ HwdbgScriptCapabilities.func_mul,
+ // HwdbgScriptCapabilities.func_div,
+ // HwdbgScriptCapabilities.func_mod,
+ HwdbgScriptCapabilities.func_gt,
+ HwdbgScriptCapabilities.func_lt,
+ HwdbgScriptCapabilities.func_egt,
+ HwdbgScriptCapabilities.func_elt,
+ HwdbgScriptCapabilities.func_equal,
+ HwdbgScriptCapabilities.func_neq,
+ HwdbgScriptCapabilities.func_jmp,
+ HwdbgScriptCapabilities.func_jz,
+ HwdbgScriptCapabilities.func_jnz,
+ HwdbgScriptCapabilities.func_mov
+ // HwdbgScriptCapabilities.func_printf,
+ )
+}
+
+/**
+ * @brief
+ * The constants for memory communication (Definition and Default Values)
+ */
+object MemoryCommunicationConfigurations {
+
+ //
+ // Address width of the Block RAM (BRAM)
+ //
+ var BLOCK_RAM_ADDR_WIDTH: Int = 13
+
+ //
+ // Data width of the Block RAM (BRAM)
+ //
+ var BLOCK_RAM_DATA_WIDTH: Int = 32
+
+ //
+ // Emulate block RAM by inferring a register to delay one clock cycle
+ //
+ var ENABLE_BLOCK_RAM_DELAY: Boolean = true
+
+ //
+ // Default number of bytes used in initialized SRAM memory
+ //
+ var DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE: Int = 8192 / 8 // 8 Kilobits
+
+ //
+ // Base address of PS to PL SRAM communication memory
+ //
+ var BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION: Int = 0
+
+ //
+ // Base address of PL to PS SRAM communication memory
+ //
+ var BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION: Int = DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE / 2
+}
+
+/**
+ * @brief
+ * The structure of script capabilities information in hwdbg
+ * @details
+ * Same as _HWDBG_INSTANCE_INFORMATION in HyperDbg
+ */
+case class HwdbgInstanceInformation(
+ version: Int, // Target version of HyperDbg (same as hwdbg)
+ maximumNumberOfStages: Int, // Number of stages that this instance of hwdbg supports (NumberOfSupportedStages == 0 means script engine is disabled)
+ scriptVariableLength: Int, // Maximum length of variables (and other script elements)
+ numberOfSupportedLocalAndGlobalVariables: Int, // Number of supported local (and global) variables
+ numberOfSupportedTemporaryVariables: Int, // Number of supported temporary variables
+ maximumNumberOfSupportedGetScriptOperators: Int, // Maximum supported GET operators in a single func
+ maximumNumberOfSupportedSetScriptOperators: Int, // Maximum supported SET operators in a single func
+ sharedMemorySize: Int, // Size of shared memory
+ debuggerAreaOffset: Int, // The memory offset of debugger
+ debuggeeAreaOffset: Int, // The memory offset of debuggee
+ numberOfPins: Int, // Number of pins
+ numberOfPorts: Int, // Number of ports
+ scriptCapabilities: Long, // Capabilities bitmask
+ bramAddrWidth: Int, // BRAM address width
+ bramDataWidth: Int, // BRAM data width
+ portsConfiguration: Array[Int] // Port arrangement
+)
+
+/**
+ * @brief
+ * The script engine capabilities (Definition and Default Values)
+ */
+object HwdbgScriptCapabilities {
+
+ //
+ // Statements and expressions
+ //
+ val assign_local_global_var: Long = 1L << 0
+ val assign_registers: Long = 1L << 1
+ val assign_pseudo_registers: Long = 1L << 2
+ val conditional_statements_and_comparison_operators: Long = 1L << 3
+ val stack_assignments: Long = 1L << 4
+
+ //
+ // Operators
+ //
+ val func_or: Long = 1L << 5
+ val func_xor: Long = 1L << 6
+ val func_and: Long = 1L << 7
+ val func_asr: Long = 1L << 8
+ val func_asl: Long = 1L << 9
+ val func_add: Long = 1L << 10
+ val func_sub: Long = 1L << 11
+ val func_mul: Long = 1L << 12
+ val func_div: Long = 1L << 13
+ val func_mod: Long = 1L << 14
+ val func_gt: Long = 1L << 15
+ val func_lt: Long = 1L << 16
+ val func_egt: Long = 1L << 17
+ val func_elt: Long = 1L << 18
+ val func_equal: Long = 1L << 19
+ val func_neq: Long = 1L << 20
+ val func_jmp: Long = 1L << 21
+ val func_jz: Long = 1L << 22
+ val func_jnz: Long = 1L << 23
+ val func_mov: Long = 1L << 24
+ val func_printf: Long = 1L << 25
+
+ def allCapabilities: Seq[Long] = Seq(
+ assign_local_global_var,
+ assign_registers,
+ assign_pseudo_registers,
+ conditional_statements_and_comparison_operators,
+ stack_assignments,
+ func_or,
+ func_xor,
+ func_and,
+ func_asr,
+ func_asl,
+ func_add,
+ func_sub,
+ func_mul,
+ func_div,
+ func_mod,
+ func_gt,
+ func_lt,
+ func_egt,
+ func_elt,
+ func_equal,
+ func_neq,
+ func_jmp,
+ func_jz,
+ func_jnz,
+ func_mov,
+ func_printf
+ )
+
+ //
+ // Utility method to create a bitmask from a sequence of capabilities
+ //
+ def createCapabilitiesMask(capabilities: Seq[Long]): Long = {
+ capabilities.foldLeft(0L)(_ | _)
+ }
+
+ //
+ // Function to check if a capability is supported
+ //
+ def isCapabilitySupported(supportedCapabilities: Long, capability: Long): Boolean = {
+ (supportedCapabilities & capability) != 0
+ }
+
+}
+
+object HwdbgInstanceInformation {
+
+ //
+ // Function to create an instance of HwdbgInstanceInformation
+ //
+ def createInstanceInformation(
+ version: Int,
+ maximumNumberOfStages: Int,
+ scriptVariableLength: Int,
+ numberOfSupportedLocalAndGlobalVariables: Int,
+ numberOfSupportedTemporaryVariables: Int,
+ maximumNumberOfSupportedGetScriptOperators: Int,
+ maximumNumberOfSupportedSetScriptOperators: Int,
+ sharedMemorySize: Int,
+ debuggerAreaOffset: Int,
+ debuggeeAreaOffset: Int,
+ numberOfPins: Int,
+ numberOfPorts: Int,
+ enabledCapabilities: Seq[Long],
+ bramAddrWidth: Int,
+ bramDataWidth: Int,
+ portsConfiguration: Array[Int]
+ ): HwdbgInstanceInformation = {
+
+ val capabilitiesMask = HwdbgScriptCapabilities.createCapabilitiesMask(enabledCapabilities)
+
+ //
+ // Printing the versioning info
+ //
+ LogInfo(true)("=======================================================================")
+ LogInfo(true)(
+ s"Generating code for hwdbg v${Version.extractMajor(version)}.${Version.extractMinor(version)}.${Version.extractPatch(version)} ($version)"
+ )
+ LogInfo(true)("Please visit https://hwdbg.hyperdbg.org/docs for more information...")
+ LogInfo(true)("hwdbg is released under the GNU Public License v3 (GPLv3).")
+ LogInfo(true)("=======================================================================")
+
+ HwdbgInstanceInformation(
+ version = version,
+ maximumNumberOfStages = maximumNumberOfStages,
+ scriptVariableLength = scriptVariableLength,
+ numberOfSupportedLocalAndGlobalVariables = numberOfSupportedLocalAndGlobalVariables,
+ numberOfSupportedTemporaryVariables = numberOfSupportedTemporaryVariables,
+ maximumNumberOfSupportedGetScriptOperators = maximumNumberOfSupportedGetScriptOperators,
+ maximumNumberOfSupportedSetScriptOperators = maximumNumberOfSupportedSetScriptOperators,
+ sharedMemorySize = sharedMemorySize,
+ debuggerAreaOffset = debuggerAreaOffset,
+ debuggeeAreaOffset = debuggeeAreaOffset,
+ numberOfPins = numberOfPins,
+ numberOfPorts = numberOfPorts,
+ scriptCapabilities = capabilitiesMask,
+ bramAddrWidth = bramAddrWidth,
+ bramDataWidth = bramDataWidth,
+ portsConfiguration = portsConfiguration
+ )
+ }
+}
+
+object ConfigLoader {
+
+ //
+ // Case classes for each configuration section
+ //
+ case class VersionConfig(
+ VERSION_MAJOR: Int,
+ VERSION_MINOR: Int,
+ VERSION_PATCH: Int
+ )
+ case class DebuggerConfigurationsConfig(
+ ENABLE_DEBUG: Boolean,
+ NUMBER_OF_PINS: Int,
+ PORT_PINS_MAP: Array[Int]
+ )
+ case class ScriptEngineConfigurationsConfig(
+ MAXIMUM_NUMBER_OF_STAGES: Int,
+ MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS: Int,
+ MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS: Int,
+ SCRIPT_VARIABLE_LENGTH: Int,
+ NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES: Int,
+ NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES: Int,
+ SCRIPT_ENGINE_EVAL_CAPABILITIES: Seq[String]
+ )
+ case class MemoryCommunicationConfigurationsConfig(
+ BLOCK_RAM_ADDR_WIDTH: Int,
+ BLOCK_RAM_DATA_WIDTH: Int,
+ ENABLE_BLOCK_RAM_DELAY: Boolean,
+ DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE: Int,
+ BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION: Int,
+ BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION: Int
+ )
+ case class FullConfig(
+ Version: VersionConfig,
+ DebuggerConfigurations: DebuggerConfigurationsConfig,
+ ScriptEngineConfigurations: ScriptEngineConfigurationsConfig,
+ MemoryCommunicationConfigurations: MemoryCommunicationConfigurationsConfig
+ )
+
+ //
+ // Function to load configuration from a JSON file
+ //
+ def loadConfig(filePath: String): Option[FullConfig] = {
+ val source = Source.fromFile(filePath)
+ val jsonString = try source.getLines().mkString("\n") finally source.close()
+
+ decode[FullConfig](jsonString) match {
+ case Right(config) => Some(config)
+ case Left(error) =>
+ println(s"Failed to parse JSON configuration: $error")
+ None
+ }
+ }
+}
+
+object LoadConfiguration {
+
+ def loadFromJson(configPath: String): Unit = {
+
+ val configOpt = ConfigLoader.loadConfig(configPath)
+
+ configOpt.foreach { config =>
+
+ //
+ // *** Set the values in the respective objects ***
+ //
+
+ //
+ // Read the version
+ //
+ Version.VERSION_MAJOR = config.Version.VERSION_MAJOR
+ Version.VERSION_MINOR = config.Version.VERSION_MINOR
+ Version.VERSION_PATCH = config.Version.VERSION_PATCH
+
+ //
+ // Read the debugger configurations
+ //
+ DebuggerConfigurations.ENABLE_DEBUG = config.DebuggerConfigurations.ENABLE_DEBUG
+ DebuggerConfigurations.NUMBER_OF_PINS = config.DebuggerConfigurations.NUMBER_OF_PINS
+ DebuggerConfigurations.PORT_PINS_MAP = config.DebuggerConfigurations.PORT_PINS_MAP
+
+ //
+ // Read the script engine configurations
+ //
+ ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_STAGES = config.ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_STAGES
+ ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS = config.ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS
+ ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS = config.ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS
+ ScriptEngineConfigurations.SCRIPT_VARIABLE_LENGTH = config.ScriptEngineConfigurations.SCRIPT_VARIABLE_LENGTH
+ ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES = config.ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES
+ ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES = config.ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES
+
+ //
+ // Convert string capability names to the corresponding values in HwdbgScriptCapabilities
+ //
+ ScriptEngineConfigurations.SCRIPT_ENGINE_EVAL_CAPABILITIES = config.ScriptEngineConfigurations.SCRIPT_ENGINE_EVAL_CAPABILITIES.flatMap {
+ case "assign_local_global_var" => Some(HwdbgScriptCapabilities.assign_local_global_var)
+ case "assign_registers" => Some(HwdbgScriptCapabilities.assign_registers)
+ case "conditional_statements_and_comparison_operators" => Some(HwdbgScriptCapabilities.conditional_statements_and_comparison_operators)
+ case "stack_assignments" => Some(HwdbgScriptCapabilities.stack_assignments)
+ case "func_or" => Some(HwdbgScriptCapabilities.func_or)
+ case "func_xor" => Some(HwdbgScriptCapabilities.func_xor)
+ case "func_and" => Some(HwdbgScriptCapabilities.func_and)
+ case "func_asl" => Some(HwdbgScriptCapabilities.func_asl)
+ case "func_add" => Some(HwdbgScriptCapabilities.func_add)
+ case "func_sub" => Some(HwdbgScriptCapabilities.func_sub)
+ case "func_mul" => Some(HwdbgScriptCapabilities.func_mul)
+ case "func_gt" => Some(HwdbgScriptCapabilities.func_gt)
+ case "func_lt" => Some(HwdbgScriptCapabilities.func_lt)
+ case "func_egt" => Some(HwdbgScriptCapabilities.func_egt)
+ case "func_elt" => Some(HwdbgScriptCapabilities.func_elt)
+ case "func_equal" => Some(HwdbgScriptCapabilities.func_equal)
+ case "func_neq" => Some(HwdbgScriptCapabilities.func_neq)
+ case "func_jmp" => Some(HwdbgScriptCapabilities.func_jmp)
+ case "func_jz" => Some(HwdbgScriptCapabilities.func_jz)
+ case "func_jnz" => Some(HwdbgScriptCapabilities.func_jnz)
+ case "func_mov" => Some(HwdbgScriptCapabilities.func_mov)
+ case _ => None
+ }
+
+ //
+ // Read memory communication configurations
+ //
+ MemoryCommunicationConfigurations.BLOCK_RAM_ADDR_WIDTH = config.MemoryCommunicationConfigurations.BLOCK_RAM_ADDR_WIDTH
+ MemoryCommunicationConfigurations.BLOCK_RAM_DATA_WIDTH = config.MemoryCommunicationConfigurations.BLOCK_RAM_DATA_WIDTH
+ MemoryCommunicationConfigurations.ENABLE_BLOCK_RAM_DELAY = config.MemoryCommunicationConfigurations.ENABLE_BLOCK_RAM_DELAY
+ MemoryCommunicationConfigurations.DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE = config.MemoryCommunicationConfigurations.DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE
+ MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION = config.MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION
+ MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION = config.MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION
+ }
+ }
+}
\ No newline at end of file
diff --git a/hwdbg/src/main/scala/hwdbg/configs/constants.scala b/hwdbg/src/main/scala/hwdbg/configs/constants.scala
new file mode 100644
index 00000000..9a4e219d
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/configs/constants.scala
@@ -0,0 +1,68 @@
+/**
+ * @file
+ * constants.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Constant values
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-04-16
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.constants
+
+import chisel3._
+import chisel3.util._
+
+/**
+ * @brief
+ * Shared value with HyperDbg
+ * @warning
+ * used in HyperDbg
+ */
+object HyperDbgSharedConstants {
+
+ //
+ // Constant indicator of a HyperDbg packet
+ //
+ val INDICATOR_OF_HYPERDBG_PACKET: Long = 0x4859504552444247L // HYPERDBG = 0x4859504552444247
+
+}
+
+/**
+ * @brief
+ * Enumeration for different packet types in HyperDbg packets (DEBUGGER_REMOTE_PACKET_TYPE)
+ * @warning
+ * Used in HyperDbg
+ */
+object DebuggerRemotePacketType extends Enumeration {
+
+ //
+ // Debugger to debuggee (vmx-root)
+ //
+ val DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_VMX_ROOT = Value(1)
+
+ //
+ // Debugger to debuggee (user-mode)
+ //
+ val DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_USER_MODE = Value(2)
+
+ //
+ // Debuggee to debugger (user-mode and kernel-mode, vmx-root mode)
+ //
+ val DEBUGGEE_TO_DEBUGGER = Value(3)
+
+ //
+ // Debugger to debuggee (hardware), used in hwdbg
+ //
+ val DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL = Value(4)
+
+ //
+ // Debuggee to debugger (hardware), used in hwdbg
+ //
+ val DEBUGGEE_TO_DEBUGGER_HARDWARE_LEVEL = Value(5)
+}
diff --git a/hwdbg/src/main/scala/hwdbg/configs/test_configs.scala b/hwdbg/src/main/scala/hwdbg/configs/test_configs.scala
new file mode 100644
index 00000000..f34ba50e
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/configs/test_configs.scala
@@ -0,0 +1,36 @@
+/**
+ * @file
+ * configs.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Configuration files for testing hwdbg
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-04-15
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.configs
+
+import chisel3._
+import chisel3.util._
+
+/**
+ * @brief
+ * The configuration constants for testing
+ */
+object TestingConfigurations {
+
+ // val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/instance_info.hex.txt"
+ val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_buffer.hex.txt"
+ // val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_conditional_statements_pins.hex.txt"
+ // val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_simple_pin_assignments.hex.txt"
+ // val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_simple_port_assignments.hex.txt"
+ // val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_conditional_statements_ports.hex.txt"
+ // val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_conditional_statements_ports_with_port_assignments.hex.txt"
+ // val BRAM_INITIALIZATION_FILE_PATH: String = "./src/test/bram/script_conditional_statement_global_var.txt"
+
+}
diff --git a/hwdbg/src/main/scala/hwdbg/libs/mem/init_mem.scala b/hwdbg/src/main/scala/hwdbg/libs/mem/init_mem.scala
new file mode 100644
index 00000000..ba957a7b
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/libs/mem/init_mem.scala
@@ -0,0 +1,105 @@
+/**
+ * @file
+ * init_mem.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Initialize SRAM memory from a file
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-04-03
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.libs.mem
+
+import chisel3._
+import chisel3.util.experimental.loadMemoryFromFileInline
+
+import hwdbg.configs._
+
+class InitMemInline(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ memoryFile: String,
+ addrWidth: Int,
+ width: Int,
+ size: Int
+) extends Module {
+
+ val io = IO(new Bundle {
+ val enable = Input(Bool())
+ val write = Input(Bool())
+ val addr = Input(UInt(addrWidth.W))
+ val dataIn = Input(UInt(width.W))
+ val dataOut = Output(UInt(width.W))
+ })
+
+ val mem = SyncReadMem(size / width, UInt(width.W))
+
+ //
+ // Initialize memory
+ //
+ if (memoryFile.trim().nonEmpty) {
+ loadMemoryFromFileInline(mem, memoryFile)
+ }
+
+ io.dataOut := DontCare
+
+ when(io.enable) {
+ val rdwrPort = mem(io.addr)
+ when(io.write) {
+ rdwrPort := io.dataIn
+ }.otherwise {
+ io.dataOut := rdwrPort
+ }
+ }
+}
+
+object InitMemInline {
+
+ def apply(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ memoryFile: String,
+ addrWidth: Int,
+ width: Int,
+ size: Int
+ )(
+ enable: Bool,
+ write: Bool,
+ addr: UInt,
+ dataIn: UInt
+ ): UInt = {
+
+ val initMemInlineModule = Module(
+ new InitMemInline(
+ debug,
+ memoryFile,
+ addrWidth,
+ width,
+ size
+ )
+ )
+
+ val dataOut = Wire(UInt(width.W))
+
+ //
+ // Configure the input signals
+ //
+ initMemInlineModule.io.enable := enable
+ initMemInlineModule.io.write := write
+ initMemInlineModule.io.addr := addr
+ initMemInlineModule.io.dataIn := dataIn
+
+ //
+ // Configure the output signals
+ //
+ dataOut := initMemInlineModule.io.dataOut
+
+ //
+ // Return the output result
+ //
+ dataOut
+ }
+}
diff --git a/hwdbg/src/main/scala/hwdbg/libs/mem/init_reg_mem_from_file.scala b/hwdbg/src/main/scala/hwdbg/libs/mem/init_reg_mem_from_file.scala
new file mode 100644
index 00000000..0c5c2475
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/libs/mem/init_reg_mem_from_file.scala
@@ -0,0 +1,159 @@
+/**
+ * @file
+ * init_reg_mem_from_file.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Initialize registers from a file
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-04-14
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.libs.mem
+
+import scala.collection.mutable.ArrayBuffer
+import scala.io.Source
+
+import chisel3._
+
+import hwdbg.utils._
+import hwdbg.configs._
+
+object InitRegMemFromFileTools {
+ def readmemh(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ path: String,
+ width: Int
+ ): Seq[UInt] = {
+
+ var counter: Int = 0
+ val buffer = new ArrayBuffer[UInt]
+ for (line <- Source.fromFile(path).getLines()) {
+
+ val tokens: Array[String] = line.split("(//)").map(_.trim)
+
+ if (tokens.nonEmpty && tokens.head != "" && tokens.head.split(";")(0).trim != "") {
+
+ val i = Integer.parseInt(tokens.head.split(";")(0).trim, 16)
+
+ LogInfo(debug)(
+ f"Initialize memory [${counter}%x]: 0x${i}%x"
+ )
+
+ counter = counter + 4
+ buffer.append(i.U(width.W))
+ }
+ }
+
+ buffer.toSeq
+
+ }
+}
+
+class InitRegMemFromFile(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ emulateBlockRamDelay: Boolean,
+ memoryFile: String,
+ addrWidth: Int,
+ width: Int,
+ size: Int
+) extends Module {
+
+ val io = IO(new Bundle {
+ val enable = Input(Bool())
+ val write = Input(Bool())
+ val addr = Input(UInt(addrWidth.W))
+ val dataIn = Input(UInt(width.W))
+ val dataOut = Output(UInt(width.W))
+ })
+
+ //
+ // Not needed to show the BRAM information
+ //
+ val mem = RegInit(VecInit(InitRegMemFromFileTools.readmemh(false, memoryFile, width)))
+
+ val actualAddr = Wire(UInt(addrWidth.W))
+ val actualData = Wire(UInt(width.W))
+ val actualWrite = Wire(Bool())
+
+ //
+ // This because the address of the saved registers are using 4 bytes granularities
+ // E.g., 4 Rsh 2 = 1 | 8 Rsh 2 = 2 | 12 Rsh 2 = 3
+ //
+ if (emulateBlockRamDelay) {
+ //
+ // In case, if it is an emulation of BRAM, a one clock delay is injected
+ //
+ actualAddr := RegNext(io.addr >> 2)
+ actualData := RegNext(io.dataIn)
+ actualWrite := RegNext(io.write)
+ } else {
+ actualAddr := io.addr >> 2
+ actualData := io.dataIn
+ actualWrite := io.write
+ }
+
+ when(io.enable) {
+ val rdwrPort = mem(actualAddr)
+ io.dataOut := rdwrPort
+
+ when(actualWrite) {
+ mem(actualAddr) := actualData
+ }
+ }.otherwise {
+ io.dataOut := 0.U
+ }
+}
+
+object InitRegMemFromFile {
+
+ def apply(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ emulateBlockRamDelay: Boolean,
+ memoryFile: String,
+ addrWidth: Int,
+ width: Int,
+ size: Int
+ )(
+ enable: Bool,
+ write: Bool,
+ addr: UInt,
+ dataIn: UInt
+ ): UInt = {
+
+ val initRegMemFromFileModule = Module(
+ new InitRegMemFromFile(
+ debug,
+ emulateBlockRamDelay,
+ memoryFile,
+ addrWidth,
+ width,
+ size
+ )
+ )
+
+ val dataOut = Wire(UInt(width.W))
+
+ //
+ // Configure the input signals
+ //
+ initRegMemFromFileModule.io.enable := enable
+ initRegMemFromFileModule.io.write := write
+ initRegMemFromFileModule.io.addr := addr
+ initRegMemFromFileModule.io.dataIn := dataIn
+
+ //
+ // Configure the output signals
+ //
+ dataOut := initRegMemFromFileModule.io.dataOut
+
+ //
+ // Return the output result
+ //
+ dataOut
+ }
+}
diff --git a/hwdbg/src/main/scala/hwdbg/libs/mux/mux_2_to_1_io.scala b/hwdbg/src/main/scala/hwdbg/libs/mux/mux_2_to_1_io.scala
new file mode 100644
index 00000000..a011d9c5
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/libs/mux/mux_2_to_1_io.scala
@@ -0,0 +1,73 @@
+/**
+ * @file
+ * mux_2_to_1_io.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Implementation of MUX 2 to 1 (I/O)
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-05-05
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.libs.mux
+
+import chisel3._
+
+import hwdbg.configs._
+
+class Mux2To1IO(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG
+) extends Module {
+
+ val io = IO(new Bundle {
+
+ val a = Input(Bool())
+ val b = Input(Bool())
+ val select = Input(Bool())
+ val out = Output(Bool())
+
+ })
+ io.out := io.a & io.select | io.b & (~io.select)
+
+}
+
+object Mux2To1IO {
+
+ def apply(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG
+ )(
+ a: Bool,
+ b: Bool,
+ select: Bool
+ ): (Bool) = {
+
+ val mux2To1IO = Module(
+ new Mux2To1IO(
+ debug
+ )
+ )
+
+ val out = Wire(Bool())
+
+ //
+ // Configure the input signals
+ //
+ mux2To1IO.io.a := a
+ mux2To1IO.io.b := b
+ mux2To1IO.io.select := select
+
+ //
+ // Configure the output signals
+ //
+ out := mux2To1IO.io.out
+
+ //
+ // Return the output result
+ //
+ out
+ }
+}
diff --git a/hwdbg/src/main/scala/hwdbg/libs/mux/mux_2_to_1_lookup.scala b/hwdbg/src/main/scala/hwdbg/libs/mux/mux_2_to_1_lookup.scala
new file mode 100644
index 00000000..eeebef43
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/libs/mux/mux_2_to_1_lookup.scala
@@ -0,0 +1,80 @@
+/**
+ * @file
+ * mux_2_to_1_lookup.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Implementation of MUX 2 to 1 (Mux-Lookup)
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-05-05
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.libs.mux
+
+import chisel3._
+import chisel3.util._
+
+import hwdbg.configs._
+
+class Mux2To1Lookup(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG
+) extends Module {
+
+ val io = IO(new Bundle {
+
+ val a = Input(Bool())
+ val b = Input(Bool())
+ val select = Input(Bool())
+ val out = Output(Bool())
+
+ })
+
+ val inputs = Array(
+ false.B -> io.a,
+ true.B -> io.b
+ )
+
+ io.out := MuxLookup(io.select, io.a)(inputs)
+
+}
+
+object Mux2To1Lookup {
+
+ def apply(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG
+ )(
+ a: Bool,
+ b: Bool,
+ select: Bool
+ ): (Bool) = {
+
+ val mux2To1Lookup = Module(
+ new Mux2To1Lookup(
+ debug
+ )
+ )
+
+ val out = Wire(Bool())
+
+ //
+ // Configure the input signals
+ //
+ mux2To1Lookup.io.a := a
+ mux2To1Lookup.io.b := b
+ mux2To1Lookup.io.select := select
+
+ //
+ // Configure the output signals
+ //
+ out := mux2To1Lookup.io.out
+
+ //
+ // Return the output result
+ //
+ out
+ }
+}
diff --git a/hwdbg/src/main/scala/hwdbg/libs/mux/mux_4_to_1_onehot.scala b/hwdbg/src/main/scala/hwdbg/libs/mux/mux_4_to_1_onehot.scala
new file mode 100644
index 00000000..dfa9e0b9
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/libs/mux/mux_4_to_1_onehot.scala
@@ -0,0 +1,83 @@
+/**
+ * @file
+ * mux_4_to_1_onehot.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Implementation of MUX 4 to 1 (One Hot)
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-05-05
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.libs.mux
+
+import chisel3._
+import chisel3.util._
+
+import hwdbg.configs._
+
+class Mux4To1OneHot(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ width: Int = 32
+) extends Module {
+
+ val io = IO(new Bundle {
+
+ val in0 = Input(UInt(width.W))
+ val in1 = Input(UInt(width.W))
+ val in2 = Input(UInt(width.W))
+ val in3 = Input(UInt(width.W))
+ val sel = Input(UInt(log2Ceil(width).W))
+ val out = Output(UInt(width.W))
+
+ })
+
+ io.out := Mux1H(io.sel, Seq(io.in0, io.in1, io.in2, io.in3))
+
+}
+
+object Mux4To1OneHot {
+
+ def apply(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ width: Int = 32
+ )(
+ in0: UInt,
+ in1: UInt,
+ in2: UInt,
+ in3: UInt,
+ sel: UInt
+ ): (UInt) = {
+
+ val mux4To1OneHot = Module(
+ new Mux4To1OneHot(
+ debug
+ )
+ )
+
+ val out = Wire(UInt(width.W))
+
+ //
+ // Configure the input signals
+ //
+ mux4To1OneHot.io.in0 := in0
+ mux4To1OneHot.io.in1 := in1
+ mux4To1OneHot.io.in2 := in2
+ mux4To1OneHot.io.in3 := in3
+ mux4To1OneHot.io.sel := sel
+
+ //
+ // Configure the output signals
+ //
+ out := mux4To1OneHot.io.out
+
+ //
+ // Return the output result
+ //
+ out
+ }
+}
diff --git a/hwdbg/src/main/scala/hwdbg/main.scala b/hwdbg/src/main/scala/hwdbg/main.scala
new file mode 100644
index 00000000..87955c35
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/main.scala
@@ -0,0 +1,320 @@
+/**
+ * @file
+ * main.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * hwdbg's main debugger module
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-04-04
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg
+
+import chisel3._
+import circt.stage.ChiselStage
+
+import hwdbg.configs._
+import hwdbg.types._
+import hwdbg.utils._
+import hwdbg.script._
+import hwdbg.communication._
+import hwdbg.communication.interpreter._
+
+class DebuggerMain(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ numberOfPins: Int,
+ maximumNumberOfStages: Int,
+ maximumNumberOfSupportedGetScriptOperators: Int,
+ maximumNumberOfSupportedSetScriptOperators: Int,
+ sharedMemorySize: Int,
+ debuggerAreaOffset: Int,
+ debuggeeAreaOffset: Int,
+ scriptVariableLength: Int,
+ numberOfSupportedLocalAndGlobalVariables: Int,
+ numberOfSupportedTemporaryVariables: Int,
+ scriptCapabilities: Seq[Long],
+ bramAddrWidth: Int,
+ bramDataWidth: Int,
+ portsConfiguration: Array[Int]
+) extends Module {
+
+ //
+ // Ensure sum of input port values equals numberOfPins (NUMBER_OF_PINS)
+ //
+ require(
+ portsConfiguration.sum == numberOfPins,
+ "err, the sum of the portsConfiguration (PORT_PINS_MAP) values must equal the numberOfPins (NUMBER_OF_PINS)."
+ )
+
+ //
+ // Ensure script variable length is not bigger than BRAM data width
+ //
+ require(
+ bramDataWidth >= scriptVariableLength,
+ "err, the script variable length should not be bigger than BRAM data width."
+ )
+
+ //
+ // Ensure the maximum number of stages is not bigger than the maximum number
+ // that can be stored within the script variable length. This is because
+ // if a JUMP for conditional statements wants to set the target location,
+ // it cannot store its destination in a script variable.
+ //
+ require(
+ maximumNumberOfStages < math.pow(2, scriptVariableLength),
+ "err, the maximum number of stages should be less than 2 to the power of the script variable length."
+ )
+
+ //
+ // Ensure the number of pin + ports is not bigger than the maximum number
+ // that can be stored within the script variable length. This is because
+ // for setting and getting pins/ports values, hwdbg uses an index which
+ // should fit within a variable size.
+ //
+ require(
+ numberOfPins + portsConfiguration.size < math.pow(2, scriptVariableLength),
+ "err, the maximum number of pins + ports should be less than 2 to the power of the script variable length."
+ )
+
+ //
+ // Ensure the number of set operators are equal to 1 since otherwise two variables (local, global and
+ // temp) might be written simultaneously.
+ //
+ require(
+ maximumNumberOfSupportedSetScriptOperators == 1,
+ "err, the supported number of SET operators can be only 1."
+ )
+
+ val io = IO(new Bundle {
+
+ //
+ // Chip signals
+ //
+ val en = Input(Bool()) // chip enable signal
+
+ //
+ // Input/Output signals
+ //
+ val inputPin = Input(Vec(numberOfPins, UInt(1.W))) // input pins
+ val outputPin = Output(Vec(numberOfPins, UInt(1.W))) // output pins
+
+ //
+ // Interrupt signals (lines)
+ //
+ val plInSignal = Input(Bool()) // PS to PL signal
+ val psOutInterrupt = Output(Bool()) // PL to PS interrupt
+
+ //
+ // BRAM (Block RAM) ports
+ //
+ val rdWrAddr = Output(UInt(bramAddrWidth.W)) // read/write address
+ val rdData = Input(UInt(bramDataWidth.W)) // read data
+ val wrEna = Output(Bool()) // enable writing
+ val wrData = Output(UInt(bramDataWidth.W)) // write data
+
+ })
+
+ //
+ // *** Create an instance of the debugger ***
+ //
+ val instanceInfo = HwdbgInstanceInformation.createInstanceInformation(
+ version = Version.getEncodedVersion,
+ maximumNumberOfStages = maximumNumberOfStages,
+ scriptVariableLength = scriptVariableLength,
+ numberOfSupportedLocalAndGlobalVariables = numberOfSupportedLocalAndGlobalVariables,
+ numberOfSupportedTemporaryVariables = numberOfSupportedTemporaryVariables,
+ maximumNumberOfSupportedGetScriptOperators = maximumNumberOfSupportedGetScriptOperators,
+ maximumNumberOfSupportedSetScriptOperators = maximumNumberOfSupportedSetScriptOperators,
+ sharedMemorySize = sharedMemorySize,
+ debuggerAreaOffset = debuggerAreaOffset,
+ debuggeeAreaOffset = debuggeeAreaOffset,
+ numberOfPins = numberOfPins,
+ numberOfPorts = portsConfiguration.size,
+ enabledCapabilities = scriptCapabilities,
+ bramAddrWidth = bramAddrWidth,
+ bramDataWidth = bramDataWidth,
+ portsConfiguration = portsConfiguration
+ )
+
+ //
+ // Wire signals for the synchronizer
+ //
+ val requestedActionOfThePacketOutput = Wire(UInt(new DebuggerRemotePacket().RequestedActionOfThePacket.getWidth.W))
+ val requestedActionOfThePacketOutputValid = Wire(Bool())
+ val dataValidOutput = Wire(Bool())
+ val receivingData = Wire(UInt(bramDataWidth.W))
+ val sendWaitForBuffer = Wire(Bool())
+
+ // -----------------------------------------------------------------------
+ // Create instance from interpreter
+ //
+ val (
+ noNewDataReceiver,
+ readNextData,
+ beginSendingBuffer,
+ noNewDataSender,
+ dataValidInterpreterOutput,
+ requestedActionOfThePacketInterpreterOutput,
+ sendingData,
+ finishedScriptConfiguration,
+ configureStage,
+ targetOperator
+ ) =
+ DebuggerPacketInterpreter(
+ debug,
+ instanceInfo
+ )(
+ io.en,
+ requestedActionOfThePacketOutput,
+ requestedActionOfThePacketOutputValid,
+ dataValidOutput,
+ receivingData,
+ sendWaitForBuffer
+ )
+
+ // -----------------------------------------------------------------------
+ // Create instance from script execution engine
+ //
+ val (outputPin) =
+ ScriptExecutionEngine(
+ debug,
+ instanceInfo
+ )(
+ io.en,
+ finishedScriptConfiguration,
+ configureStage,
+ targetOperator,
+ io.inputPin
+ )
+
+ // -----------------------------------------------------------------------
+ // Create instance from synchronizer
+ //
+ val (
+ psOutInterrupt,
+ rdWrAddr,
+ wrEna,
+ wrData,
+ outRequestedActionOfThePacketOutput,
+ outRequestedActionOfThePacketOutputValid,
+ outDataValidOutput,
+ outReceivingData,
+ outSendWaitForBuffer
+ ) =
+ SendReceiveSynchronizer(
+ debug,
+ instanceInfo
+ )(
+ io.en,
+ io.plInSignal,
+ io.rdData,
+ noNewDataReceiver,
+ readNextData,
+ beginSendingBuffer,
+ noNewDataSender,
+ dataValidInterpreterOutput,
+ requestedActionOfThePacketInterpreterOutput,
+ sendingData
+ )
+
+ // -----------------------------------------------------------------------
+ // Connect synchronizer signals to wires
+ //
+ requestedActionOfThePacketOutput := outRequestedActionOfThePacketOutput
+ requestedActionOfThePacketOutputValid := outRequestedActionOfThePacketOutputValid
+ dataValidOutput := outDataValidOutput
+ receivingData := outReceivingData
+ sendWaitForBuffer := outSendWaitForBuffer
+
+ // -----------------------------------------------------------------------
+ // Configure the output signals
+ //
+ io.wrEna := wrEna
+ io.wrData := wrData
+ io.rdWrAddr := rdWrAddr
+
+ io.outputPin := outputPin
+
+ io.psOutInterrupt := psOutInterrupt
+
+}
+
+object DebuggerMain {
+
+ def apply(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ numberOfPins: Int,
+ maximumNumberOfStages: Int,
+ maximumNumberOfSupportedGetScriptOperators: Int,
+ maximumNumberOfSupportedSetScriptOperators: Int,
+ sharedMemorySize: Int,
+ debuggerAreaOffset: Int,
+ debuggeeAreaOffset: Int,
+ scriptVariableLength: Int,
+ numberOfSupportedLocalAndGlobalVariables: Int,
+ numberOfSupportedTemporaryVariables: Int,
+ scriptCapabilities: Seq[Long],
+ bramAddrWidth: Int,
+ bramDataWidth: Int,
+ portsConfiguration: Array[Int]
+ )(
+ en: Bool,
+ inputPin: Vec[UInt],
+ plInSignal: Bool,
+ rdData: UInt
+ ): (Vec[UInt], Bool, UInt, Bool, UInt) = {
+
+ val debuggerMainModule = Module(
+ new DebuggerMain(
+ debug,
+ numberOfPins,
+ maximumNumberOfStages,
+ maximumNumberOfSupportedGetScriptOperators,
+ maximumNumberOfSupportedSetScriptOperators,
+ sharedMemorySize,
+ debuggerAreaOffset,
+ debuggeeAreaOffset,
+ scriptVariableLength,
+ numberOfSupportedLocalAndGlobalVariables,
+ numberOfSupportedTemporaryVariables,
+ scriptCapabilities,
+ bramAddrWidth,
+ bramDataWidth,
+ portsConfiguration
+ )
+ )
+
+ val outputPin = Wire(Vec(numberOfPins, UInt(1.W)))
+ val psOutInterrupt = Wire(Bool())
+ val rdWrAddr = Wire(UInt(bramAddrWidth.W))
+ val wrEna = Wire(Bool())
+ val wrData = Wire(UInt(bramDataWidth.W))
+
+ //
+ // Configure the input signals
+ //
+ debuggerMainModule.io.en := en
+ debuggerMainModule.io.inputPin := inputPin
+ debuggerMainModule.io.plInSignal := plInSignal
+ debuggerMainModule.io.rdData := rdData
+
+ //
+ // Configure the output signals
+ //
+ outputPin := debuggerMainModule.io.outputPin
+ psOutInterrupt := debuggerMainModule.io.psOutInterrupt
+ rdWrAddr := debuggerMainModule.io.rdWrAddr
+ wrEna := debuggerMainModule.io.wrEna
+ wrData := debuggerMainModule.io.wrData
+
+ //
+ // Return the output result
+ //
+ (outputPin, psOutInterrupt, rdWrAddr, wrEna, wrData)
+ }
+}
diff --git a/hwdbg/src/main/scala/hwdbg/script/eval.scala b/hwdbg/src/main/scala/hwdbg/script/eval.scala
new file mode 100644
index 00000000..2fbb89e9
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/script/eval.scala
@@ -0,0 +1,507 @@
+/**
+ * @file
+ * eval.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Script execution engine
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-05-17
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.script
+
+import chisel3._
+import chisel3.util._
+
+import hwdbg.configs._
+import hwdbg.utils._
+import hwdbg.stage._
+
+class ScriptEngineEval(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+) extends Module {
+
+ //
+ // Import operators enum
+ //
+ import hwdbg.script.ScriptEvalFunc.ScriptOperators
+ import hwdbg.script.ScriptEvalFunc.ScriptOperators._
+
+ val io = IO(new Bundle {
+
+ //
+ // Chip signals
+ //
+ val en = Input(Bool()) // chip enable signal
+
+ //
+ // Stage configuration signals
+ //
+ val stageConfig = Input(new Stage(debug, instanceInfo))
+ val nextStage = Output(
+ UInt(
+ log2Ceil(
+ instanceInfo.maximumNumberOfStages * (instanceInfo.maximumNumberOfSupportedGetScriptOperators + instanceInfo.maximumNumberOfSupportedSetScriptOperators + 1)
+ ).W
+ )
+ )
+
+ //
+ // Output signals
+ //
+ val outputPin = Output(Vec(instanceInfo.numberOfPins, UInt(1.W))) // output pins
+ val resultingLocalGlobalVariables = Output(
+ Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W))
+ ) // output of local (and global) variables
+ val resultingTempVariables =
+ Output(Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W))) // output of temporary variables
+ })
+
+ //
+ // Output pins
+ //
+ val nextStage = WireInit(
+ 0.U(
+ log2Ceil(
+ instanceInfo.maximumNumberOfStages * (instanceInfo.maximumNumberOfSupportedGetScriptOperators + instanceInfo.maximumNumberOfSupportedSetScriptOperators + 1)
+ ).W
+ )
+ )
+
+ //
+ // Assign operator value (split the signal into only usable part)
+ //
+ LogInfo(debug)("Usable size of Value in the SYMBOL: " + ScriptOperators().getWidth)
+ val mainOperatorValue = io.stageConfig.stageSymbol.Value(ScriptOperators().getWidth - 1, 0).asTypeOf(ScriptOperators())
+
+ // -------------------------------------------------------------------------
+ // Get value module
+ //
+ val getValueModuleOutput = Wire(Vec(instanceInfo.maximumNumberOfSupportedGetScriptOperators, UInt(instanceInfo.scriptVariableLength.W)))
+
+ for (i <- 0 until instanceInfo.maximumNumberOfSupportedGetScriptOperators) {
+
+ getValueModuleOutput(i) := ScriptEngineGetValue(
+ debug,
+ instanceInfo
+ )(
+ io.en,
+ io.stageConfig.getOperatorSymbol(i),
+ io.stageConfig.localGlobalVariables,
+ io.stageConfig.tempVariables,
+ io.stageConfig.pinValues
+ )
+ }
+
+ // -------------------------------------------------------------------------
+ // *** Implementing the evaluation engine ***
+ //
+ //
+ val srcVal = WireInit(VecInit(Seq.fill(instanceInfo.maximumNumberOfSupportedGetScriptOperators)(0.U(instanceInfo.scriptVariableLength.W))))
+ val desVal = WireInit(VecInit(Seq.fill(instanceInfo.maximumNumberOfSupportedSetScriptOperators)(0.U(instanceInfo.scriptVariableLength.W))))
+
+ //
+ // Apply the chip enable signal
+ //
+ when(io.en === true.B) {
+
+ switch(mainOperatorValue) {
+
+ is(sFuncOr) {
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_or) == true) {
+
+ srcVal(0) := getValueModuleOutput(0)
+ srcVal(1) := getValueModuleOutput(1)
+
+ desVal(0) := srcVal(0) | srcVal(1)
+
+ nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
+ }
+ }
+ is(sFuncXor) {
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_xor) == true) {
+
+ srcVal(0) := getValueModuleOutput(0)
+ srcVal(1) := getValueModuleOutput(1)
+
+ desVal(0) := srcVal(0) ^ srcVal(1)
+
+ nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
+ }
+ }
+ is(sFuncAnd) {
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_and) == true) {
+
+ srcVal(0) := getValueModuleOutput(0)
+ srcVal(1) := getValueModuleOutput(1)
+
+ desVal(0) := srcVal(0) & srcVal(1)
+
+ nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
+ }
+ }
+ is(sFuncAsr) {
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_asr) == true) {
+
+ srcVal(0) := getValueModuleOutput(0)
+ srcVal(1) := getValueModuleOutput(1)
+
+ desVal(0) := srcVal(0) >> srcVal(1)(log2Ceil(instanceInfo.scriptVariableLength), 0)
+
+ nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
+ }
+ }
+ is(sFuncAsl) {
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_asl) == true) {
+
+ srcVal(0) := getValueModuleOutput(0)
+ srcVal(1) := getValueModuleOutput(1)
+
+ desVal(0) := srcVal(0) << srcVal(1)(log2Ceil(instanceInfo.scriptVariableLength), 0)
+
+ nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
+ }
+ }
+ is(sFuncAdd) {
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_add) == true) {
+
+ srcVal(0) := getValueModuleOutput(0)
+ srcVal(1) := getValueModuleOutput(1)
+
+ desVal(0) := srcVal(0) + srcVal(1)
+
+ nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
+ }
+ }
+ is(sFuncSub) {
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_sub) == true) {
+
+ srcVal(0) := getValueModuleOutput(0)
+ srcVal(1) := getValueModuleOutput(1)
+
+ desVal(0) := srcVal(0) - srcVal(1)
+
+ nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
+ }
+ }
+ is(sFuncMul) {
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_mul) == true) {
+
+ srcVal(0) := getValueModuleOutput(0)
+ srcVal(1) := getValueModuleOutput(1)
+
+ desVal(0) := srcVal(0) * srcVal(1)
+
+ nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
+ }
+ }
+ is(sFuncDiv) {
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_div) == true) {
+
+ srcVal(0) := getValueModuleOutput(0)
+ srcVal(1) := getValueModuleOutput(1)
+
+ desVal(0) := srcVal(0) / srcVal(1)
+
+ nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
+ }
+ }
+ is(sFuncMod) {
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_mod) == true) {
+
+ srcVal(0) := getValueModuleOutput(0)
+ srcVal(1) := getValueModuleOutput(1)
+
+ desVal(0) := srcVal(0) % srcVal(1)
+
+ nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
+ }
+ }
+ is(sFuncGt) {
+ if (
+ HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_gt) == true &&
+ HwdbgScriptCapabilities.isCapabilitySupported(
+ instanceInfo.scriptCapabilities,
+ HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
+ ) == true
+ ) {
+
+ srcVal(0) := getValueModuleOutput(0)
+ srcVal(1) := getValueModuleOutput(1)
+
+ desVal(0) := srcVal(0) > srcVal(1)
+
+ nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
+ }
+ }
+ is(sFuncLt) {
+ if (
+ HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_lt) == true &&
+ HwdbgScriptCapabilities.isCapabilitySupported(
+ instanceInfo.scriptCapabilities,
+ HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
+ ) == true
+ ) {
+
+ srcVal(0) := getValueModuleOutput(0)
+ srcVal(1) := getValueModuleOutput(1)
+
+ desVal(0) := srcVal(0) < srcVal(1)
+
+ nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
+ }
+ }
+ is(sFuncEgt) {
+ if (
+ HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_egt) == true &&
+ HwdbgScriptCapabilities.isCapabilitySupported(
+ instanceInfo.scriptCapabilities,
+ HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
+ ) == true
+ ) {
+
+ srcVal(0) := getValueModuleOutput(0)
+ srcVal(1) := getValueModuleOutput(1)
+
+ desVal(0) := srcVal(0) >= srcVal(1)
+
+ nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
+ }
+ }
+ is(sFuncElt) {
+ if (
+ HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_egt) == true &&
+ HwdbgScriptCapabilities.isCapabilitySupported(
+ instanceInfo.scriptCapabilities,
+ HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
+ ) == true
+ ) {
+
+ srcVal(0) := getValueModuleOutput(0)
+ srcVal(1) := getValueModuleOutput(1)
+
+ desVal(0) := srcVal(0) <= srcVal(1)
+
+ nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
+ }
+ }
+ is(sFuncEqual) {
+ if (
+ HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_equal) == true &&
+ HwdbgScriptCapabilities.isCapabilitySupported(
+ instanceInfo.scriptCapabilities,
+ HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
+ ) == true
+ ) {
+
+ srcVal(0) := getValueModuleOutput(0)
+ srcVal(1) := getValueModuleOutput(1)
+
+ desVal(0) := srcVal(0) === srcVal(1)
+
+ nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
+ }
+ }
+ is(sFuncNeq) {
+ if (
+ HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_neq) == true &&
+ HwdbgScriptCapabilities.isCapabilitySupported(
+ instanceInfo.scriptCapabilities,
+ HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
+ ) == true
+ ) {
+
+ srcVal(0) := getValueModuleOutput(0)
+ srcVal(1) := getValueModuleOutput(1)
+
+ desVal(0) := srcVal(0) =/= srcVal(1)
+
+ nextStage := io.stageConfig.stageIndex + 4.U // one main operator + two GET operators + one SET operator
+ }
+ }
+ is(sFuncJmp) {
+ if (
+ HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_jmp) == true &&
+ HwdbgScriptCapabilities.isCapabilitySupported(
+ instanceInfo.scriptCapabilities,
+ HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
+ ) == true
+ ) {
+
+ srcVal(0) := getValueModuleOutput(0)
+ nextStage := srcVal(0)
+ }
+ }
+ is(sFuncJz) {
+ if (
+ HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_jz) == true &&
+ HwdbgScriptCapabilities.isCapabilitySupported(
+ instanceInfo.scriptCapabilities,
+ HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
+ ) == true
+ ) {
+
+ srcVal(0) := getValueModuleOutput(0)
+ srcVal(1) := getValueModuleOutput(1)
+
+ when(srcVal(1) === 0.U) {
+ nextStage := srcVal(0)
+ }.otherwise {
+ nextStage := io.stageConfig.stageIndex + 3.U // one main operator + two GET operators
+ }
+ }
+ }
+ is(sFuncJnz) {
+ if (
+ HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_jnz) == true &&
+ HwdbgScriptCapabilities.isCapabilitySupported(
+ instanceInfo.scriptCapabilities,
+ HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
+ ) == true
+ ) {
+
+ srcVal(0) := getValueModuleOutput(0)
+ srcVal(1) := getValueModuleOutput(1)
+
+ when(srcVal(1) =/= 0.U) {
+ nextStage := srcVal(0)
+ }.otherwise {
+ nextStage := io.stageConfig.stageIndex + 3.U // one main operator + two GET operators
+ }
+
+ }
+ }
+ is(sFuncMov) {
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_mov) == true) {
+
+ srcVal(0) := getValueModuleOutput(0)
+
+ desVal(0) := srcVal(0)
+
+ nextStage := io.stageConfig.stageIndex + 3.U // one main operator + one GET operators + one SET operator
+ }
+ }
+ is(sFuncPrintf) {
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.func_printf) == true) {
+
+ //
+ // To be implemented
+ //
+ }
+ }
+ }
+ }
+
+ // -------------------------------------------------------------------------
+ // Set value module
+ //
+ val setValueModuleInput = Wire(Vec(instanceInfo.maximumNumberOfSupportedSetScriptOperators, Vec(instanceInfo.numberOfPins, UInt(1.W))))
+ val outputLocalGlobalVariables = Wire(
+ Vec(
+ instanceInfo.maximumNumberOfSupportedSetScriptOperators,
+ Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W))
+ )
+ )
+ val outputTempVariables = Wire(
+ Vec(
+ instanceInfo.maximumNumberOfSupportedSetScriptOperators,
+ Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W))
+ )
+ )
+
+ for (i <- 0 until instanceInfo.maximumNumberOfSupportedSetScriptOperators) {
+
+ val (
+ outputPin,
+ resultingLocalGlobalVariables,
+ resultingTempVariables
+ ) = ScriptEngineSetValue(
+ debug,
+ instanceInfo
+ )(
+ io.en,
+ io.stageConfig.setOperatorSymbol(i),
+ io.stageConfig.localGlobalVariables,
+ io.stageConfig.tempVariables,
+ desVal(i),
+ io.stageConfig.pinValues
+ )
+
+ //
+ // Connect SET output pins
+ //
+ setValueModuleInput(i) := outputPin
+ outputLocalGlobalVariables(i) := resultingLocalGlobalVariables
+ outputTempVariables(i) := resultingTempVariables
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Connect the output signals
+ //
+ io.outputPin := setValueModuleInput(0)
+ io.resultingLocalGlobalVariables := outputLocalGlobalVariables(0)
+ io.resultingTempVariables := outputTempVariables(0)
+ io.nextStage := nextStage
+}
+
+object ScriptEngineEval {
+
+ def apply(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+ )(
+ en: Bool,
+ stageConfig: Stage
+ ): (UInt, Vec[UInt], Vec[UInt], Vec[UInt]) = {
+
+ val scriptEngineEvalModule = Module(
+ new ScriptEngineEval(
+ debug,
+ instanceInfo
+ )
+ )
+
+ val outputPin = Wire(Vec(instanceInfo.numberOfPins, UInt(1.W)))
+ val resultingLocalGlobalVariables = Wire(Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W)))
+ val resultingTempVariables = Wire(Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W)))
+ val nextStage = Wire(
+ UInt(
+ log2Ceil(
+ instanceInfo.maximumNumberOfStages * (instanceInfo.maximumNumberOfSupportedGetScriptOperators + instanceInfo.maximumNumberOfSupportedSetScriptOperators + 1)
+ ).W
+ )
+ )
+
+ //
+ // Configure the input signals
+ //
+ scriptEngineEvalModule.io.en := en
+ scriptEngineEvalModule.io.stageConfig := stageConfig
+
+ //
+ // Configure the output signals
+ //
+ nextStage := scriptEngineEvalModule.io.nextStage
+ outputPin := scriptEngineEvalModule.io.outputPin
+ resultingLocalGlobalVariables := scriptEngineEvalModule.io.resultingLocalGlobalVariables
+ resultingTempVariables := scriptEngineEvalModule.io.resultingTempVariables
+
+ //
+ // Return the output result
+ //
+ (
+ nextStage,
+ outputPin,
+ resultingLocalGlobalVariables,
+ resultingTempVariables
+ )
+ }
+}
diff --git a/hwdbg/src/main/scala/hwdbg/script/exec.scala b/hwdbg/src/main/scala/hwdbg/script/exec.scala
new file mode 100644
index 00000000..1fb91e6c
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/script/exec.scala
@@ -0,0 +1,373 @@
+/**
+ * @file
+ * exec.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Script execution engine
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-05-07
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.script
+
+import chisel3._
+import chisel3.util._
+
+import hwdbg.configs._
+import hwdbg.stage._
+
+object ScriptExecutionEngineConfigStage {
+ object State extends ChiselEnum {
+ val sConfigStageSymbol, sConfigGetSymbol, sConfigSetSymbol = Value
+ }
+}
+
+class ScriptExecutionEngine(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+) extends Module {
+
+ //
+ // Import state enum
+ //
+ import ScriptExecutionEngineConfigStage.State
+ import ScriptExecutionEngineConfigStage.State._
+
+ val io = IO(new Bundle {
+
+ //
+ // Chip signals
+ //
+ val en = Input(Bool()) // chip enable signal
+
+ //
+ // Script stage configuration signals
+ //
+ val finishedScriptConfiguration = Input(Bool()) // whether script configuration finished or not?
+ val configureStage = Input(Bool()) // whether the configuration of stage should start or not?
+ val targetOperator = Input(new HwdbgShortSymbol(instanceInfo.scriptVariableLength)) // Current operator to be configured
+
+ //
+ // Input/Output signals
+ //
+ val inputPin = Input(Vec(instanceInfo.numberOfPins, UInt(1.W))) // input pins
+ val outputPin = Output(Vec(instanceInfo.numberOfPins, UInt(1.W))) // output pins
+ })
+
+ //
+ // Output pins
+ //
+ val outputPin = Wire(Vec(instanceInfo.numberOfPins, UInt(1.W)))
+
+ //
+ // Stage registers
+ //
+ val stageRegs = Reg(Vec(instanceInfo.maximumNumberOfStages, new Stage(debug, instanceInfo)))
+
+ //
+ // Stage configuration done
+ // Whether the state are configured or not
+ //
+ val stageConfigurationValid = RegInit(false.B)
+
+ //
+ // Stage configuration registers
+ //
+ val configState = RegInit(sConfigStageSymbol)
+ val configStageNumber = RegInit(0.U(log2Ceil(instanceInfo.maximumNumberOfStages).W))
+
+ //
+ // Calculate the maximum of the two values since we only want to use one register for
+ // both GET and SET
+ //
+ val maxOperators = math.max(instanceInfo.maximumNumberOfSupportedGetScriptOperators, instanceInfo.maximumNumberOfSupportedSetScriptOperators)
+
+ //
+ // Create a register with the width based on the maximum value
+ //
+ val configGetSetOperatorNumber = RegInit(0.U(log2Ceil(maxOperators).W))
+ val stageIndex = RegInit(
+ 0.U(
+ log2Ceil(
+ instanceInfo.maximumNumberOfStages * (instanceInfo.maximumNumberOfSupportedGetScriptOperators + instanceInfo.maximumNumberOfSupportedSetScriptOperators + 1)
+ ).W
+ )
+ )
+
+ // -----------------------------------------------------------------------
+ //
+ // *** Configure stage buffers ***
+ //
+ when(io.configureStage === true.B) {
+
+ switch(configState) {
+
+ is(sConfigStageSymbol) {
+
+ //
+ // Since the chip is in the configuring status, just pass all the input
+ // to output since the stage data is not valid at this stage
+ //
+ stageConfigurationValid := false.B
+
+ //
+ // Configure the stage symbol (The first symbol is the stage operator)
+ //
+ stageRegs(configStageNumber).stageSymbol := io.targetOperator
+
+ //
+ // Set the stage index
+ //
+ stageRegs(configStageNumber).stageIndex := stageIndex // store the stage index
+ stageRegs(configStageNumber).targetStage := 0.U // reset the target stage
+ stageIndex := stageIndex + 1.U // increment stage index
+
+ //
+ // If it is the very first configuration symbol, then we disable all stages
+ //
+ when(configStageNumber === 0.U) {
+ for (i <- 0 until instanceInfo.maximumNumberOfStages) {
+ stageRegs(i).stageEnable := false.B
+ }
+ }
+
+ //
+ // Going to the next state
+ //
+ configState := sConfigGetSymbol
+ }
+ is(sConfigGetSymbol) {
+
+ //
+ // Config GET operator
+ //
+ stageRegs(configStageNumber).getOperatorSymbol(configGetSetOperatorNumber) := io.targetOperator
+ configGetSetOperatorNumber := configGetSetOperatorNumber + 1.U
+
+ //
+ // Check whether this stage number should be counted in stage indexes or its empty
+ //
+ when(io.targetOperator.Type =/= 0.U) {
+ stageIndex := stageIndex + 1.U
+ }
+
+ when(configGetSetOperatorNumber === (instanceInfo.maximumNumberOfSupportedGetScriptOperators - 1).U) {
+
+ configGetSetOperatorNumber := 0.U // reset the counter
+ configState := sConfigSetSymbol // go to the next state
+ }.otherwise {
+ configState := sConfigGetSymbol // stay at the same state
+ }
+ }
+ is(sConfigSetSymbol) {
+
+ //
+ // Config SET operator
+ //
+ stageRegs(configStageNumber).setOperatorSymbol(configGetSetOperatorNumber) := io.targetOperator
+ stageRegs(configStageNumber).stageEnable := true.B // this stage is enabled
+ configGetSetOperatorNumber := configGetSetOperatorNumber + 1.U
+
+ when(io.targetOperator.Type =/= 0.U) {
+ stageIndex := stageIndex + 1.U
+ }
+
+ when(configGetSetOperatorNumber === (instanceInfo.maximumNumberOfSupportedSetScriptOperators - 1).U) {
+
+ configGetSetOperatorNumber := 0.U // reset the counter
+
+ when(io.finishedScriptConfiguration === true.B) {
+
+ //
+ // Not configuring anymore, reset the stage number
+ //
+ configStageNumber := 0.U // reset the stage number
+ stageIndex := 0.U // reset the stage index
+ configState := sConfigStageSymbol
+
+ //
+ // Stage data is now valid and can be used (scripts can apply from now on)
+ //
+ stageConfigurationValid := true.B
+
+ }.otherwise {
+ configStageNumber := configStageNumber + 1.U // Increment the stage number holder of current configuration
+ configState := sConfigStageSymbol // the next state is again a stage symbol
+ }
+ }.otherwise {
+ configState := sConfigSetSymbol // stay at the same state
+ }
+ }
+ }
+ }
+
+ // -----------------------------------------------------------------------
+ //
+ // *** Move each register (input vector) to the next stage at each clock ***
+ //
+ for (i <- 0 until instanceInfo.maximumNumberOfStages) {
+
+ if (i == 0) {
+
+ //
+ // At the first stage, the input registers should be passed to the
+ // first registers set of the stage registers
+ //
+ stageRegs(0).pinValues := io.inputPin
+
+ //
+ // Each pin start initially start from 0th target stage
+ //
+ stageRegs(0).targetStage := 0.U
+
+ } else if (i == (instanceInfo.maximumNumberOfStages - 1)) {
+
+ //
+ // At the last stage, the state registers should be passed to the output
+ // Note: At this stage script symbol is useless
+ //
+ outputPin := stageRegs(i - 1).pinValues
+
+ } else {
+
+ //
+ // Check if this stage should be ignored (passed to the next stage) or be evaluated
+ // (i - 1) is because the 0th index registers are used for storing data but the
+ // script engine assumes that the symbols start from 0, so -1 is used here
+ //
+ // Also, if the stage data is valid (configuration applied at least once)
+ //
+ when(stageConfigurationValid === true.B && stageRegs(i - 1).stageIndex === stageRegs(i - 1).targetStage && stageRegs(i - 1).stageEnable === true.B) {
+
+ //
+ // *** Based on target stage, this stage needs evaluation ***
+ //
+
+ //
+ // Instantiate an eval engine for this stage
+ //
+ val (
+ nextStage,
+ outputPin,
+ resultingLocalGlobalVariables,
+ resultingTempVariables
+ ) = ScriptEngineEval(
+ debug,
+ instanceInfo
+ )(
+ stageRegs(i - 1).stageEnable,
+ stageRegs(i - 1)
+ )
+
+ //
+ // At the normal (middle) stage, the result of state registers should be passed to
+ // the next level of stage registers
+ //
+ stageRegs(i).pinValues := outputPin
+
+ //
+ // Pass the target stage symbol number to the next stage
+ //
+ stageRegs(i).targetStage := nextStage
+
+ //
+ // Pass the local (and global) and temporary variables to the next stage
+ //
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_local_global_var) == true) {
+ stageRegs(i).localGlobalVariables := resultingLocalGlobalVariables
+ }
+
+ if (
+ HwdbgScriptCapabilities.isCapabilitySupported(
+ instanceInfo.scriptCapabilities,
+ HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
+ ) == true
+ ) {
+ stageRegs(i).tempVariables := resultingTempVariables
+ }
+
+ }.otherwise {
+
+ //
+ // *** Based on target stage, this stage should be ignore ***
+ //
+
+ //
+ // Just pass all the values to the next stage
+ //
+ stageRegs(i).pinValues := stageRegs(i - 1).pinValues
+ stageRegs(i).targetStage := stageRegs(i - 1).targetStage
+
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_local_global_var) == true) {
+ stageRegs(i).localGlobalVariables := stageRegs(i - 1).localGlobalVariables
+ }
+
+ if (
+ HwdbgScriptCapabilities.isCapabilitySupported(
+ instanceInfo.scriptCapabilities,
+ HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
+ ) == true
+ ) {
+ stageRegs(i).tempVariables := stageRegs(i - 1).tempVariables
+ }
+
+ }
+ }
+ }
+
+ // -----------------------------------------------------------------------
+
+ //
+ // Connect the output signals
+ //
+ io.outputPin := outputPin
+
+}
+
+object ScriptExecutionEngine {
+
+ def apply(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+ )(
+ en: Bool,
+ finishedScriptConfiguration: Bool,
+ configureStage: Bool,
+ targetOperator: HwdbgShortSymbol,
+ inputPin: Vec[UInt]
+ ): (Vec[UInt]) = {
+
+ val scriptExecutionEngineModule = Module(
+ new ScriptExecutionEngine(
+ debug,
+ instanceInfo
+ )
+ )
+
+ val outputPin = Wire(Vec(instanceInfo.numberOfPins, UInt(1.W)))
+
+ //
+ // Configure the input signals
+ //
+ scriptExecutionEngineModule.io.en := en
+ scriptExecutionEngineModule.io.finishedScriptConfiguration := finishedScriptConfiguration
+ scriptExecutionEngineModule.io.configureStage := configureStage
+ scriptExecutionEngineModule.io.targetOperator := targetOperator
+ scriptExecutionEngineModule.io.inputPin := inputPin
+
+ //
+ // Configure the output signals
+ //
+ outputPin := scriptExecutionEngineModule.io.outputPin
+
+ //
+ // Return the output result
+ //
+ (outputPin)
+ }
+}
diff --git a/hwdbg/src/main/scala/hwdbg/script/get_value.scala b/hwdbg/src/main/scala/hwdbg/script/get_value.scala
new file mode 100644
index 00000000..a81f475e
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/script/get_value.scala
@@ -0,0 +1,238 @@
+/**
+ * @file
+ * get_value.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Script engine get value
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-05-29
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.script
+
+import chisel3._
+import chisel3.util._
+
+import hwdbg.configs._
+import hwdbg.utils._
+import hwdbg.stage._
+
+class ScriptEngineGetValue(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+) extends Module {
+
+ //
+ // Import script data types enum
+ //
+ import hwdbg.script.ScriptConstantTypes.ScriptDataTypes
+ import hwdbg.script.ScriptConstantTypes.ScriptDataTypes._
+
+ val io = IO(new Bundle {
+
+ //
+ // Chip signals
+ //
+ val en = Input(Bool()) // chip enable signal
+
+ //
+ // Evaluation operator symbol
+ //
+ val operator = Input(new HwdbgShortSymbol(instanceInfo.scriptVariableLength))
+
+ //
+ // Input variables
+ //
+ val localGlobalVariables =
+ Input(Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W))) // Local (and Global) variables
+ val tempVariables = Input(Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W))) // Temporary variables
+
+ //
+ // Input signals
+ //
+ val inputPin = Input(Vec(instanceInfo.numberOfPins, UInt(1.W))) // input pins
+
+ //
+ // Output value
+ //
+ val outputValue = Output(UInt(instanceInfo.scriptVariableLength.W)) // output value
+ })
+
+ val outputValue = WireInit(0.U(instanceInfo.scriptVariableLength.W))
+
+ //
+ // Assign operator type (split the signal into only usable part)
+ //
+ LogInfo(debug)("Usable size of Type in the SYMBOL: " + ScriptDataTypes().getWidth)
+ val mainOperatorType = io.operator.Type(ScriptDataTypes().getWidth - 1, 0).asTypeOf(ScriptDataTypes())
+
+ //
+ // *** Implementing the getting data logic ***
+ //
+
+ //
+ // Apply the chip enable signal
+ //
+ when(io.en === true.B) {
+
+ switch(mainOperatorType) {
+
+ is(symbolGlobalIdType) {
+
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_local_global_var) == true) {
+ //
+ // Set output to local (and global) variables
+ //
+ outputValue := io.localGlobalVariables(io.operator.Value)
+ }
+ }
+ is(symbolLocalIdType) {
+
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_local_global_var) == true) {
+ //
+ // Set output to local (and global) variables
+ //
+ outputValue := io.localGlobalVariables(io.operator.Value)
+ }
+ }
+ is(symbolNumType) {
+
+ //
+ // Constant value
+ //
+ outputValue := io.operator.Value
+ }
+ is(symbolRegisterType) {
+
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_registers) == true) {
+
+ //
+ // Registers are pins and ports
+ //
+ when(instanceInfo.numberOfPins.U > io.operator.Value) {
+
+ //
+ // *** Used for getting the pin value ***
+ //
+ outputValue := io.inputPin(io.operator.Value)
+ }.otherwise {
+
+ //
+ // *** Used for getting the port value ***
+ //
+
+ //
+ // Create a vector of wires
+ //
+ val ports = Wire(Vec(instanceInfo.numberOfPorts, UInt(instanceInfo.scriptVariableLength.W)))
+ var currentPortIndex: Int = 0
+ var currentPortNum: Int = 0
+
+ //
+ // Iterate based on port configuration
+ //
+ for (port <- instanceInfo.portsConfiguration) {
+
+ LogInfo(debug)(f"connect port(${currentPortIndex}) to inputPin(${currentPortNum} to ${currentPortNum + port}) for SET")
+ ports(currentPortIndex) := io.inputPin.asUInt(currentPortNum + port - 1, currentPortNum)
+
+ currentPortNum += port
+ currentPortIndex += 1
+ }
+
+ //
+ // Set the output
+ //
+ outputValue := ports(io.operator.Value - instanceInfo.numberOfPins.U)
+ }
+ }
+ }
+ is(symbolPseudoRegType) {
+
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_pseudo_registers) == true) {
+ //
+ // To be implemented
+ //
+ outputValue := 0.U
+ }
+ }
+ is(symbolStackIndexType) {
+
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.stack_assignments) == true) {
+ //
+ // To be implemented
+ //
+ outputValue := 0.U // io.inputPin.asUInt
+ }
+ }
+ is(symbolTempType) {
+
+ if (
+ HwdbgScriptCapabilities.isCapabilitySupported(
+ instanceInfo.scriptCapabilities,
+ HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
+ ) == true
+ ) {
+ //
+ // Set output to temporary variables
+ //
+ outputValue := io.tempVariables(io.operator.Value)
+ }
+ }
+ }
+ }
+
+ //
+ // Connect the output signals
+ //
+ io.outputValue := outputValue
+
+}
+
+object ScriptEngineGetValue {
+
+ def apply(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+ )(
+ en: Bool,
+ operator: HwdbgShortSymbol,
+ localGlobalVariables: Vec[UInt],
+ tempVariables: Vec[UInt],
+ inputPin: Vec[UInt]
+ ): (UInt) = {
+
+ val scriptEngineGetValueModule = Module(
+ new ScriptEngineGetValue(
+ debug,
+ instanceInfo
+ )
+ )
+
+ val outputValue = Wire(UInt(instanceInfo.scriptVariableLength.W))
+
+ //
+ // Configure the input signals
+ //
+ scriptEngineGetValueModule.io.en := en
+ scriptEngineGetValueModule.io.operator := operator
+ scriptEngineGetValueModule.io.localGlobalVariables := localGlobalVariables
+ scriptEngineGetValueModule.io.tempVariables := tempVariables
+ scriptEngineGetValueModule.io.inputPin := inputPin
+
+ //
+ // Configure the output signal
+ //
+ outputValue := scriptEngineGetValueModule.io.outputValue
+
+ //
+ // Return the output result
+ //
+ (outputValue)
+ }
+}
diff --git a/hwdbg/src/main/scala/hwdbg/script/script_definitions.scala b/hwdbg/src/main/scala/hwdbg/script/script_definitions.scala
new file mode 100644
index 00000000..5471e834
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/script/script_definitions.scala
@@ -0,0 +1,50 @@
+package hwdbg.script
+
+import chisel3._
+import chisel3.util._
+
+/**
+ * @brief
+ * The structure of HWDBG_SHORT_SYMBOL used in script engine of HyperDbg
+ */
+class HwdbgShortSymbol(
+ scriptVariableLength: Int
+) extends Bundle {
+
+ //
+ // Ensure that the script variable length is at least 8 bits or 1 byte
+ //
+ require(
+ scriptVariableLength >= 8,
+ f"err, the minimum script variable length is 8 bits (1 byte)."
+ )
+
+ val Type = UInt(scriptVariableLength.W) // long long unsigned is 64 bits but it can be dynamic
+ val Value = UInt(scriptVariableLength.W) // long long unsigned is 64 bits but it can be dynamic
+}
+
+/**
+ * @brief
+ * Constant values for the script engine
+ */
+object ScriptConstants {
+ val SYMBOL_MEM_VALID_CHECK_MASK = 1 << 31
+ val INVALID = 0x80000000
+ val LALR_ACCEPT = 0x7fffffff
+}
+
+/**
+ * @brief
+ * Constant type values for the script engine
+ */
+object ScriptConstantTypes {
+ object ScriptDataTypes extends ChiselEnum {
+ val symbolUndefined, symbolGlobalIdType, symbolLocalIdType, symbolNumType, symbolRegisterType, symbolPseudoRegType, symbolSemanticRuleType, symbolTempType, symbolStringType, symbolVariableCountType, symbolInvalid, symbolWstringType, symbolFunctionParameterIdType, symbolReturnAddressType, symbolFunctionParameterType, symbolStackIndexType, symbolStackBaseIndexType, symbolReturnValueType = Value
+ }
+}
+
+object ScriptEvalFunc {
+ object ScriptOperators extends ChiselEnum {
+ 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/hwdbg/src/main/scala/hwdbg/script/set_value.scala b/hwdbg/src/main/scala/hwdbg/script/set_value.scala
new file mode 100644
index 00000000..9b5f554d
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/script/set_value.scala
@@ -0,0 +1,389 @@
+/**
+ * @file
+ * set_value.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Script engine set value
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-05-29
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.script
+
+import chisel3._
+import chisel3.util._
+
+import hwdbg.configs._
+import hwdbg.utils._
+import hwdbg.stage._
+
+class ScriptEngineSetValue(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+) extends Module {
+
+ //
+ // Import script data types enum
+ //
+ import hwdbg.script.ScriptConstantTypes.ScriptDataTypes
+ import hwdbg.script.ScriptConstantTypes.ScriptDataTypes._
+
+ val io = IO(new Bundle {
+
+ //
+ // Chip signals
+ //
+ val en = Input(Bool()) // chip enable signal
+
+ //
+ // Evaluation operator symbol
+ //
+ val operator = Input(new HwdbgShortSymbol(instanceInfo.scriptVariableLength))
+
+ //
+ // Input variables
+ //
+ val inputLocalGlobalVariables =
+ Input(Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W))) // Local (and Global) variables
+ val inputTempVariables =
+ Input(Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W))) // Temporary variables
+
+ //
+ // Input value
+ //
+ val inputValue = Input(UInt(instanceInfo.scriptVariableLength.W)) // input value
+
+ //
+ // Output signals
+ //
+ val inputPin = Input(Vec(instanceInfo.numberOfPins, UInt(1.W))) // output pins
+ val outputPin = Output(Vec(instanceInfo.numberOfPins, UInt(1.W))) // output pins
+
+ //
+ // Output variables
+ //
+ val outputLocalGlobalVariables =
+ Output(Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W))) // Local (and Global) variables
+ val outputTempVariables =
+ Output(Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W))) // Temporary variables
+
+ })
+
+ //
+ // Temp input
+ //
+ val inputLocalGlobalVariables = io.inputLocalGlobalVariables
+ val inputTempVariables = io.inputTempVariables
+ val inputPin = io.inputPin.asUInt
+
+ //
+ // Output pins
+ //
+ val outputPin = WireInit(0.U(instanceInfo.numberOfPins.W))
+ val outputLocalGlobalVariables = WireInit(
+ VecInit(Seq.fill(instanceInfo.numberOfSupportedLocalAndGlobalVariables)(0.U(instanceInfo.scriptVariableLength.W)))
+ ) // Local (and Global) variables
+ val outputTempVariables = WireInit(
+ VecInit(Seq.fill(instanceInfo.numberOfSupportedTemporaryVariables)(0.U(instanceInfo.scriptVariableLength.W)))
+ ) // Temporary variables
+
+ //
+ // Assign operator type (split the signal into only usable part)
+ //
+ LogInfo(debug)("Usable size of Type in the SYMBOL: " + ScriptDataTypes().getWidth)
+ val mainOperatorType = io.operator.Type(ScriptDataTypes().getWidth - 1, 0).asTypeOf(ScriptDataTypes())
+
+ //
+ // *** Implementing the setting data logic ***
+ //
+
+ //
+ // Apply the chip enable signal
+ //
+ when(io.en === true.B) {
+
+ switch(mainOperatorType) {
+
+ is(symbolUndefined) {
+
+ //
+ // In case of undefined SET value, just pass every input to the next step
+ //
+ outputPin := inputPin
+ outputLocalGlobalVariables := inputLocalGlobalVariables
+ outputTempVariables := inputTempVariables
+
+ }
+ is(symbolGlobalIdType) {
+
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_local_global_var) == true) {
+
+ //
+ // Set the local (and global) variables
+ //
+ outputPin := inputPin
+ outputLocalGlobalVariables := inputLocalGlobalVariables
+ outputTempVariables := inputTempVariables
+
+ //
+ // Set the target variable
+ //
+ outputLocalGlobalVariables(io.operator.Value) := io.inputValue
+ }
+
+ }
+ is(symbolLocalIdType) {
+
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_local_global_var) == true) {
+ //
+ // Set the target local/global variable
+ //
+ outputPin := inputPin
+ outputLocalGlobalVariables := inputLocalGlobalVariables
+ outputTempVariables := inputTempVariables
+
+ //
+ // Set the target local/global variable
+ //
+ outputLocalGlobalVariables(io.operator.Value) := io.inputValue
+ }
+
+ }
+ is(symbolRegisterType) {
+
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_registers) == true) {
+
+ when(instanceInfo.numberOfPins.U > io.operator.Value) {
+
+ //
+ // *** Used for setting the pin value ***
+ //
+
+ //
+ // Registers are pins (set the value based on less significant bit)
+ //
+ val tempShiftedBit = (1.U << io.operator.Value)
+
+ when(io.inputValue(0) === 1.U) {
+ outputPin := inputPin | tempShiftedBit; // Set the N-th bit to 1
+ }.otherwise {
+ outputPin := inputPin & ~tempShiftedBit; // Clear the N-th bit to 0
+ }
+
+ }.otherwise {
+
+ //
+ // *** Used for setting the port value ***
+ //
+
+ //
+ // Iterate based on port configuration
+ //
+ var currentPortNum: Int = 0
+ val numPorts = instanceInfo.portsConfiguration.length
+
+ for ((port, index) <- instanceInfo.portsConfiguration.zipWithIndex) {
+
+ LogInfo(debug)(f"========================= port assignment (${index} - port size: ${port}) =========================")
+
+ when(io.operator.Value === (index + instanceInfo.numberOfPins).U) {
+
+ //
+ // If the current port's bit width is bigger than the script variable length,
+ // we need to append zero
+ //
+ val targetInputValue = WireInit(0.U(port.W))
+
+ if (port > instanceInfo.scriptVariableLength) {
+
+ //
+ // Since the port size is bigger than the variable size,
+ // we need to append zeros to the target value
+ //
+ LogInfo(debug)(
+ f"Appending zeros (${port - instanceInfo.scriptVariableLength}) to input variable (targetInputValue) to support port num: ${index}"
+ )
+ targetInputValue := Cat(io.inputValue, 0.U((port - instanceInfo.scriptVariableLength).W))
+ } else {
+ //
+ // Since the variable size is bigger than the port size,
+ // we need only a portion of the input value
+ //
+ targetInputValue := io.inputValue(port - 1, 0)
+ }
+
+ //
+ // Determine the range of bits to be modified
+ //
+ val high = currentPortNum + port - 1
+ val low = currentPortNum
+
+ // Create the modified outputPin based on whether it's the first, last or a middle port
+ val modifiedOutputPin = if (index == 0) {
+
+ //
+ // First port: keep higher bits unchanged, set lower bits to input value
+ //
+ LogInfo(debug)(
+ f"Set connecting index=${index} - inputPin(${instanceInfo.numberOfPins - 1}, ${high + 1}) + targetInputValue(${port - 1}, 0)"
+ )
+ Cat(
+ inputPin(instanceInfo.numberOfPins - 1, high + 1), // Bits above the range to keep unchanged
+ targetInputValue // New value for the specified range
+ )
+ } else if (index == numPorts - 1) {
+
+ //
+ // Last port: keep lower bits unchanged, set higher bits to input value
+ //
+ LogInfo(debug)(f"Set connecting index=${index} - targetInputValue(${port - 1}, 0) + inputPin(${low - 1}, 0)")
+ Cat(
+ targetInputValue, // New value for the specified range
+ inputPin(low - 1, 0) // Bits below the range to keep unchanged
+ )
+ } else {
+
+ //
+ // Middle port: keep both higher and lower bits unchanged
+ //
+ LogInfo(debug)(
+ f"Set connecting index=${index} - inputPin(${instanceInfo.numberOfPins - 1}, ${high + 1}) + targetInputValue(${port - 1}, 0) + inputPin(${low - 1}, 0)"
+ )
+ Cat(
+ inputPin(instanceInfo.numberOfPins - 1, high + 1), // Bits above the range to keep unchanged
+ targetInputValue, // New value for the specified range
+ inputPin(low - 1, 0) // Bits below the range to keep unchanged
+ )
+ }
+
+ //
+ // Assign the modified outputPin back to outputPin
+ //
+ outputPin := modifiedOutputPin
+ }
+
+ currentPortNum += port
+ }
+ }
+
+ outputLocalGlobalVariables := inputLocalGlobalVariables
+ outputTempVariables := inputTempVariables
+ }
+ }
+ is(symbolPseudoRegType) {
+
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.assign_pseudo_registers) == true) {
+ //
+ // To be implemented
+ //
+ outputPin := 0.U
+ outputLocalGlobalVariables := inputLocalGlobalVariables
+ outputTempVariables := inputTempVariables
+ }
+
+ }
+ is(symbolStackIndexType) {
+
+ if (HwdbgScriptCapabilities.isCapabilitySupported(instanceInfo.scriptCapabilities, HwdbgScriptCapabilities.stack_assignments) == true) {
+ //
+ // To be implemented
+ //
+ outputPin := inputPin
+ outputLocalGlobalVariables := inputLocalGlobalVariables
+ outputTempVariables := inputTempVariables
+ }
+
+ }
+ is(symbolTempType) {
+
+ if (
+ HwdbgScriptCapabilities.isCapabilitySupported(
+ instanceInfo.scriptCapabilities,
+ HwdbgScriptCapabilities.conditional_statements_and_comparison_operators
+ ) == true
+ ) {
+ //
+ // Set the temporary variables
+ //
+ outputPin := inputPin
+ outputLocalGlobalVariables := inputLocalGlobalVariables
+ outputTempVariables := inputTempVariables
+
+ //
+ // Set the target temporary variable
+ //
+ outputTempVariables(io.operator.Value) := io.inputValue
+ }
+ }
+ }
+ }
+
+ //
+ // Connect the output signals
+ //
+ io.outputLocalGlobalVariables := outputLocalGlobalVariables
+ io.outputTempVariables := outputTempVariables
+
+ for (i <- 0 until instanceInfo.numberOfPins) {
+ io.outputPin(i) := outputPin(i)
+ }
+
+}
+
+object ScriptEngineSetValue {
+
+ def apply(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+ )(
+ en: Bool,
+ operator: HwdbgShortSymbol,
+ inputLocalGlobalVariables: Vec[UInt],
+ inputTempVariables: Vec[UInt],
+ inputValue: UInt,
+ inputPin: Vec[UInt]
+ ): (Vec[UInt], Vec[UInt], Vec[UInt]) = {
+
+ val scriptEngineSetValueModule = Module(
+ new ScriptEngineSetValue(
+ debug,
+ instanceInfo
+ )
+ )
+
+ val outputPin = Wire(Vec(instanceInfo.numberOfPins, UInt(1.W)))
+ val outputLocalGlobalVariables = Wire(Vec(instanceInfo.numberOfSupportedLocalAndGlobalVariables, UInt(instanceInfo.scriptVariableLength.W)))
+ val outputTempVariables = Wire(Vec(instanceInfo.numberOfSupportedTemporaryVariables, UInt(instanceInfo.scriptVariableLength.W)))
+
+ //
+ // Configure the input signals
+ //
+ scriptEngineSetValueModule.io.en := en
+ scriptEngineSetValueModule.io.operator := operator
+ scriptEngineSetValueModule.io.inputLocalGlobalVariables := inputLocalGlobalVariables
+ scriptEngineSetValueModule.io.inputTempVariables := inputTempVariables
+ scriptEngineSetValueModule.io.inputValue := inputValue
+ scriptEngineSetValueModule.io.inputPin := inputPin
+
+ //
+ // Configure the output signal
+ //
+ outputPin := scriptEngineSetValueModule.io.outputPin
+ outputLocalGlobalVariables := scriptEngineSetValueModule.io.outputLocalGlobalVariables
+ outputTempVariables := scriptEngineSetValueModule.io.outputTempVariables
+
+ //
+ // Return the output result
+ //
+ (
+ outputPin,
+ outputLocalGlobalVariables,
+ outputTempVariables
+ )
+ }
+}
diff --git a/hwdbg/src/main/scala/hwdbg/types/communication.scala b/hwdbg/src/main/scala/hwdbg/types/communication.scala
new file mode 100644
index 00000000..c0b8ef6b
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/types/communication.scala
@@ -0,0 +1,183 @@
+/**
+ * @file
+ * communication.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Data types for the communication
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-04-08
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.types
+
+import chisel3._
+
+// -----------------------------------------------------------------------
+
+//
+// Structure in C:
+//
+// typedef struct _DEBUGGER_REMOTE_PACKET
+// {
+// BYTE Checksum;
+// UINT64 Indicator; /* Shows the type of the packet */
+// DEBUGGER_REMOTE_PACKET_TYPE TypeOfThePacket;
+// DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION RequestedActionOfThePacket;
+//
+// } DEBUGGER_REMOTE_PACKET, *PDEBUGGER_REMOTE_PACKET;
+//
+
+/**
+ * @brief
+ * The packet used for communication with the remote debugger
+ */
+class DebuggerRemotePacket() extends Bundle {
+
+ //
+ // Structure fields
+ //
+ val Checksum = UInt(8.W) // 1 bytes
+ val Alignment0 = UInt((64 - 8).W) // 7 bytes
+ val Indicator = UInt(64.W) // 8 bytes
+ val TypeOfThePacket = UInt(32.W) // 4 bytes
+ val RequestedActionOfThePacket = UInt(32.W) // 4 bytes
+
+ //
+ // Offset of structure fields
+ //
+ object Offset {
+
+ val checksum = (0) / 8
+
+ val indicator = (Checksum.getWidth + Alignment0.getWidth) / 8
+
+ val typeOfThePacket = (Checksum.getWidth + Alignment0.getWidth + Indicator.getWidth) / 8
+
+ val requestedActionOfThePacket = (Checksum.getWidth + Alignment0.getWidth + Indicator.getWidth + TypeOfThePacket.getWidth) / 8
+
+ val startOfDataBuffer =
+ (Checksum.getWidth + Alignment0.getWidth + Indicator.getWidth + TypeOfThePacket.getWidth + RequestedActionOfThePacket.getWidth) / 8
+ }
+}
+
+// -----------------------------------------------------------------------
+
+//
+// Structure in C:
+//
+// typedef struct _HWDBG_PORT_INFORMATION
+// {
+// UINT32 CountOfPorts;
+//
+// /*
+//
+// Here the pin information details will be available.
+//
+// UINT32
+// Port Size
+//
+// */
+//
+// } HWDBG_PORT_INFORMATION, *PHWDBG_PORT_INFORMATION;
+
+/**
+ * @brief
+ * The structure of port information in hwdbg
+ */
+class HwdbgPortInformation() extends Bundle {
+
+ //
+ // Structure fields
+ //
+ val CountOfPorts = UInt(32.W) // 4 bytes
+
+ //
+ // Offset of structure fields
+ //
+ object Offset {
+
+ val countOfPorts = (0) / 8
+ }
+}
+
+// -----------------------------------------------------------------------
+
+//
+// Structure in C:
+//
+// typedef struct _HWDBG_PORT_INFORMATION_ITEMS
+// {
+// UINT32 PortIndex;
+//
+// } HWDBG_PORT_INFORMATION_ITEMS, *PHWDBG_PORT_INFORMATION_ITEMS;
+
+/**
+ * @brief
+ * The structure of port information (each item) in hwdbg
+ */
+class HwdbgPortInformationItems() extends Bundle {
+
+ //
+ // Structure fields
+ //
+ val PortSize = UInt(32.W) // 4 bytes
+
+ //
+ // Offset of structure fields
+ //
+ object Offset {
+
+ val portSize = (0) / 8
+ }
+}
+
+// -----------------------------------------------------------------------
+
+/**
+ * @brief
+ * Different action of hwdbg (SHARED WITH HYPERDBG) (HWDBG_ACTION_ENUMS)
+ * @warning
+ * Used in HyperDbg
+ */
+object HwdbgActionEnums extends Enumeration {
+
+ val hwdbgActionSendInstanceInfo = Value(1)
+ val hwdbgActionConfigureScriptBuffer = Value(2)
+
+}
+
+// -----------------------------------------------------------------------
+
+/**
+ * @brief
+ * Different responses of hwdbg (SHARED WITH HYPERDBG) (HWDBG_RESPONSE_ENUMS)
+ * @warning
+ * Used in HyperDbg
+ */
+object HwdbgResponseEnums extends Enumeration {
+
+ val hwdbgResponseSuccessOrErrorMessage = Value(1)
+ val hwdbgResponseInstanceInfo = Value(2)
+
+}
+
+// -----------------------------------------------------------------------
+
+/**
+ * @brief
+ * Different responses of hwdbg (SHARED WITH HYPERDBG) (HWDBG_ERROR_ENUMS)
+ * @warning
+ */
+object HwdbgSuccessOrErrorEnums extends Enumeration {
+
+ val hwdbgOperationWasSuccessful = Value(0x7fffffff)
+ val hwdbgErrorInvalidPacket = Value(1)
+
+}
+
+// -----------------------------------------------------------------------
diff --git a/hwdbg/src/main/scala/hwdbg/types/stage.scala b/hwdbg/src/main/scala/hwdbg/types/stage.scala
new file mode 100644
index 00000000..78d0fa39
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/types/stage.scala
@@ -0,0 +1,71 @@
+/**
+ * @file
+ * stage.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Data types related to stage registers
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-05-07
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.stage
+
+import chisel3._
+import chisel3.util.log2Ceil
+
+import hwdbg.configs._
+import hwdbg.script._
+
+class Stage(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ instanceInfo: HwdbgInstanceInformation
+) extends Bundle {
+
+ val pinValues = Vec(
+ instanceInfo.numberOfPins,
+ UInt(1.W)
+ ) // The value of each pin in each stage (should be passed to the next stage)
+
+ val stageSymbol = new HwdbgShortSymbol(
+ instanceInfo.scriptVariableLength
+ ) // Interpreted script symbol for the target stage (should NOT be passed to the next stage)
+
+ val getOperatorSymbol = Vec(
+ instanceInfo.maximumNumberOfSupportedGetScriptOperators,
+ new HwdbgShortSymbol(instanceInfo.scriptVariableLength)
+ ) // GET symbol operand (should NOT be passed to the next stage)
+
+ val setOperatorSymbol = Vec(
+ instanceInfo.maximumNumberOfSupportedSetScriptOperators,
+ new HwdbgShortSymbol(instanceInfo.scriptVariableLength)
+ ) // SET symbol operand (should NOT be passed to the next stage)
+
+ val targetStage = UInt(
+ log2Ceil(
+ instanceInfo.maximumNumberOfStages * (instanceInfo.maximumNumberOfSupportedGetScriptOperators + instanceInfo.maximumNumberOfSupportedSetScriptOperators + 1)
+ ).W
+ ) // Target stage that needs to be executed for the current pin values (should be passed to the next stage)
+
+ val tempVariables = Vec(
+ instanceInfo.numberOfSupportedTemporaryVariables,
+ UInt(instanceInfo.scriptVariableLength.W)
+ ) // Temporary variables
+
+ val localGlobalVariables = Vec(
+ instanceInfo.numberOfSupportedLocalAndGlobalVariables,
+ UInt(instanceInfo.scriptVariableLength.W)
+ ) // Local (and Global) variables
+
+ val stageIndex = UInt(
+ log2Ceil(
+ instanceInfo.maximumNumberOfStages * (instanceInfo.maximumNumberOfSupportedGetScriptOperators + instanceInfo.maximumNumberOfSupportedSetScriptOperators + 1)
+ ).W
+ ) // Target stage index of the current stage (configured with script configuration and remains constant during execution)
+
+ val stageEnable = Bool() // Target stage is enabled (configured) or not
+}
diff --git a/hwdbg/src/main/scala/hwdbg/utils/utils.scala b/hwdbg/src/main/scala/hwdbg/utils/utils.scala
new file mode 100644
index 00000000..162107d0
--- /dev/null
+++ b/hwdbg/src/main/scala/hwdbg/utils/utils.scala
@@ -0,0 +1,59 @@
+/**
+ * @file
+ * utils.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * Different utilities and functionalities
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-04-12
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg.utils
+
+import chisel3._
+import chisel3.util._
+
+/**
+ * @brief
+ * Create logs and debug messages
+ */
+object LogInfo {
+
+ def apply(debug: Boolean)(message: String): Unit = {
+ if (debug) {
+ println("[*] debug msg: " + message)
+ }
+ }
+}
+
+object BitwiseFunction {
+
+ def getFirstNBits(num: Long, n: Int): Long = {
+
+ val mask = (1L << n) - 1 // Create a bitmask with the first 'n' bits set to 1
+ val shifted = num >>> (java.lang.Long.SIZE - n) // Shift the bits to the right to keep the first 'n' bits
+ val firstNBits = shifted & mask // Extract the first 'n' bits by performing a bitwise AND operation
+
+ firstNBits
+ }
+
+ def getBitsInRange(num: Long, start: Int, end: Int): Long = {
+
+ require(start >= 0 && start <= 63, "Starting point must be between 0 and 63")
+ require(end >= 0 && end <= 63, "Ending point must be between 0 and 63")
+ require(start <= end, "Starting point must be less than or equal to ending point")
+
+ val numBits = end - start + 1 // Number of bits in the range
+ val mask = (1L << numBits) - 1 // Create a bitmask with 'numBits' bits set to 1
+ val shifted = num >>> (java.lang.Long.SIZE - end - 1) // Shift the bits to the right to align the range with the rightmost position
+ val bitsInRange = shifted & mask // Extract the bits within the specified range
+
+ bitsInRange
+ }
+
+}
diff --git a/hwdbg/src/main/scala/top.scala b/hwdbg/src/main/scala/top.scala
new file mode 100644
index 00000000..619fe296
--- /dev/null
+++ b/hwdbg/src/main/scala/top.scala
@@ -0,0 +1,143 @@
+/**
+ * @file
+ * top.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * hwdbg's top module
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-04-03
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg
+
+import chisel3._
+import circt.stage.ChiselStage
+
+import hwdbg._
+import hwdbg.configs._
+
+class DebuggerModule(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ numberOfPins: Int,
+ maximumNumberOfStages: Int,
+ maximumNumberOfSupportedGetScriptOperators: Int,
+ maximumNumberOfSupportedSetScriptOperators: Int,
+ sharedMemorySize: Int,
+ debuggerAreaOffset: Int,
+ debuggeeAreaOffset: Int,
+ scriptVariableLength: Int,
+ numberOfSupportedLocalAndGlobalVariables: Int,
+ numberOfSupportedTemporaryVariables: Int,
+ scriptCapabilities: Seq[Long],
+ bramAddrWidth: Int,
+ bramDataWidth: Int,
+ portsConfiguration: Array[Int]
+) extends Module {
+ val io = IO(new Bundle {
+
+ //
+ // Chip signals
+ //
+ val en = Input(Bool()) // chip enable signal
+
+ //
+ // Input/Output signals
+ //
+ val inputPin = Input(Vec(numberOfPins, UInt(1.W))) // input pins
+ val outputPin = Output(Vec(numberOfPins, UInt(1.W))) // output pins
+
+ //
+ // Interrupt signals (lines)
+ //
+ val plInSignal = Input(Bool()) // PS to PL signal
+ val psOutInterrupt = Output(Bool()) // PL to PS interrupt
+
+ //
+ // BRAM (Block RAM) ports
+ //
+ val rdWrAddr = Output(UInt(bramAddrWidth.W)) // read/write address
+ val rdData = Input(UInt(bramDataWidth.W)) // read data
+ val wrEna = Output(Bool()) // enable writing
+ val wrData = Output(UInt(bramDataWidth.W)) // write data
+
+ })
+
+ //
+ // Instantiate the debugger's main module
+ //
+ val (outputPin, psOutInterrupt, rdWrAddr, wrEna, wrData) =
+ DebuggerMain(
+ debug,
+ numberOfPins,
+ maximumNumberOfStages,
+ maximumNumberOfSupportedGetScriptOperators,
+ maximumNumberOfSupportedSetScriptOperators,
+ sharedMemorySize,
+ debuggerAreaOffset,
+ debuggeeAreaOffset,
+ scriptVariableLength,
+ numberOfSupportedLocalAndGlobalVariables,
+ numberOfSupportedTemporaryVariables,
+ scriptCapabilities,
+ bramAddrWidth,
+ bramDataWidth,
+ portsConfiguration
+ )(
+ io.en,
+ io.inputPin,
+ io.plInSignal,
+ io.rdData
+ )
+
+ io.outputPin := outputPin
+ io.psOutInterrupt := psOutInterrupt
+ io.rdWrAddr := rdWrAddr
+ io.wrEna := wrEna
+ io.wrData := wrData
+
+}
+
+object Main extends App {
+
+ //
+ // Load configuration from JSON file
+ //
+ LoadConfiguration.loadFromJson("src/main/scala/hwdbg/configs/config.json")
+
+ //
+ // Generate hwdbg verilog files
+ //
+ println(
+ ChiselStage.emitSystemVerilog(
+ new DebuggerModule(
+ DebuggerConfigurations.ENABLE_DEBUG,
+ DebuggerConfigurations.NUMBER_OF_PINS,
+ ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_STAGES,
+ ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS,
+ ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS,
+ MemoryCommunicationConfigurations.DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE,
+ MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION,
+ MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION,
+ ScriptEngineConfigurations.SCRIPT_VARIABLE_LENGTH,
+ ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES,
+ ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES,
+ ScriptEngineConfigurations.SCRIPT_ENGINE_EVAL_CAPABILITIES,
+ MemoryCommunicationConfigurations.BLOCK_RAM_ADDR_WIDTH,
+ MemoryCommunicationConfigurations.BLOCK_RAM_DATA_WIDTH,
+ DebuggerConfigurations.PORT_PINS_MAP
+ ),
+ firtoolOpts = Array(
+ "-disable-all-randomization",
+ // "-strip-debug-info",
+ "--split-verilog", // The intention for this argument (and next argument) is to separate generated files.
+ "-o",
+ "generated/"
+ )
+ )
+ )
+}
diff --git a/hwdbg/src/main/scala/top_test.scala b/hwdbg/src/main/scala/top_test.scala
new file mode 100644
index 00000000..dabe92d7
--- /dev/null
+++ b/hwdbg/src/main/scala/top_test.scala
@@ -0,0 +1,176 @@
+/**
+ * @file
+ * top_test.scala
+ * @author
+ * Sina Karvandi (sina@hyperdbg.org)
+ * @brief
+ * hwdbg's top module (with BRAM) for testing
+ * @details
+ * @version 0.1
+ * @date
+ * 2024-04-04
+ *
+ * @copyright
+ * This project is released under the GNU Public License v3.
+ */
+package hwdbg
+
+import chisel3._
+import circt.stage.ChiselStage
+
+import hwdbg._
+import hwdbg.configs._
+import hwdbg.libs.mem._
+
+class DebuggerModuleTestingBRAM(
+ debug: Boolean = DebuggerConfigurations.ENABLE_DEBUG,
+ numberOfPins: Int,
+ maximumNumberOfStages: Int,
+ maximumNumberOfSupportedGetScriptOperators: Int,
+ maximumNumberOfSupportedSetScriptOperators: Int,
+ sharedMemorySize: Int,
+ debuggerAreaOffset: Int,
+ debuggeeAreaOffset: Int,
+ scriptVariableLength: Int,
+ numberOfSupportedLocalAndGlobalVariables: Int,
+ numberOfSupportedTemporaryVariables: Int,
+ scriptCapabilities: Seq[Long],
+ bramAddrWidth: Int,
+ bramDataWidth: Int,
+ portsConfiguration: Array[Int]
+) extends Module {
+ val io = IO(new Bundle {
+
+ //
+ // Chip signals
+ //
+ val en = Input(Bool()) // chip enable signal
+
+ //
+ // Input/Output signals
+ //
+ val inputPin = Input(Vec(numberOfPins, UInt(1.W))) // input pins
+ val outputPin = Output(Vec(numberOfPins, UInt(1.W))) // output pins
+
+ //
+ // Interrupt signals (lines)
+ //
+ val plInSignal = Input(Bool()) // PS to PL signal
+ val psOutInterrupt = Output(Bool()) // PL to PS interrupt
+
+ //
+ // *** BRAM (Block RAM) ports are initialized from an external file ***
+ //
+
+ })
+
+ val bramEn = WireInit(false.B)
+ val bramWrite = WireInit(false.B)
+ val bramAddr = WireInit(0.U(bramAddrWidth.W))
+ val bramDataIn = WireInit(0.U(bramDataWidth.W))
+
+ val bramDataOut = WireInit(0.U(bramDataWidth.W))
+
+ //
+ // Instantiate the BRAM memory initializer module
+ //
+ val dataOut =
+ InitRegMemFromFile(
+ debug,
+ MemoryCommunicationConfigurations.ENABLE_BLOCK_RAM_DELAY,
+ TestingConfigurations.BRAM_INITIALIZATION_FILE_PATH,
+ bramAddrWidth,
+ bramDataWidth,
+ MemoryCommunicationConfigurations.DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE
+ )(
+ bramEn,
+ bramWrite,
+ bramAddr,
+ bramDataIn
+ )
+
+ bramDataOut := dataOut
+
+ //
+ // Instantiate the debugger's main module
+ //
+ val (outputPin, psOutInterrupt, rdWrAddr, wrEna, wrData) =
+ DebuggerMain(
+ debug,
+ numberOfPins,
+ maximumNumberOfStages,
+ maximumNumberOfSupportedGetScriptOperators,
+ maximumNumberOfSupportedSetScriptOperators,
+ sharedMemorySize,
+ debuggerAreaOffset,
+ debuggeeAreaOffset,
+ scriptVariableLength,
+ numberOfSupportedLocalAndGlobalVariables,
+ numberOfSupportedTemporaryVariables,
+ scriptCapabilities,
+ bramAddrWidth,
+ bramDataWidth,
+ portsConfiguration
+ )(
+ io.en,
+ io.inputPin,
+ io.plInSignal,
+ bramDataOut
+ )
+
+ //
+ // Connect BRAM Pins
+ //
+ bramEn := io.en // enable BRAM when the main chip enabled
+ bramAddr := rdWrAddr
+ bramWrite := wrEna
+ bramDataIn := wrData
+
+ //
+ // Connect I/O pins
+ //
+ io.outputPin := outputPin
+ io.psOutInterrupt := psOutInterrupt
+
+}
+
+object MainWithInitializedBRAM extends App {
+
+ //
+ // Load configuration from JSON file
+ //
+ LoadConfiguration.loadFromJson("src/main/scala/hwdbg/configs/config.json")
+
+ //
+ // Generate hwdbg verilog files
+ //
+ println(
+ ChiselStage.emitSystemVerilog(
+ new DebuggerModuleTestingBRAM(
+ DebuggerConfigurations.ENABLE_DEBUG,
+ DebuggerConfigurations.NUMBER_OF_PINS,
+ ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_STAGES,
+ ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_GET_SCRIPT_OPERATORS,
+ ScriptEngineConfigurations.MAXIMUM_NUMBER_OF_SUPPORTED_SET_SCRIPT_OPERATORS,
+ MemoryCommunicationConfigurations.DEFAULT_CONFIGURATION_INITIALIZED_MEMORY_SIZE,
+ MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PS_TO_PL_COMMUNICATION,
+ MemoryCommunicationConfigurations.BASE_ADDRESS_OF_PL_TO_PS_COMMUNICATION,
+ ScriptEngineConfigurations.SCRIPT_VARIABLE_LENGTH,
+ ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_LOCAL_AND_GLOBAL_VARIABLES,
+ ScriptEngineConfigurations.NUMBER_OF_SUPPORTED_TEMPORARY_VARIABLES,
+ ScriptEngineConfigurations.SCRIPT_ENGINE_EVAL_CAPABILITIES,
+ MemoryCommunicationConfigurations.BLOCK_RAM_ADDR_WIDTH,
+ MemoryCommunicationConfigurations.BLOCK_RAM_DATA_WIDTH,
+ DebuggerConfigurations.PORT_PINS_MAP
+ ),
+ firtoolOpts = Array(
+ "-disable-all-randomization",
+ // "-strip-debug-info",
+ "--lowering-options=disallowLocalVariables", // because icarus doesn't support 'automatic logic', this option prevents such logics
+ "--split-verilog", // The intention for this argument (and next argument) is to separate generated files.
+ "-o",
+ "generated/"
+ )
+ )
+ )
+}
diff --git a/hwdbg/src/main/systemverilog/sensors/constraints/top.xdc b/hwdbg/src/main/systemverilog/sensors/constraints/top.xdc
new file mode 100644
index 00000000..1c85485d
--- /dev/null
+++ b/hwdbg/src/main/systemverilog/sensors/constraints/top.xdc
@@ -0,0 +1,4620 @@
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[0]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[10]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[11]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[12]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[13]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[14]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[15]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[16]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[17]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[18]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[19]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[1]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[20]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[21]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[22]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[23]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[24]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[25]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[26]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[27]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[28]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[29]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[2]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[30]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[31]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[3]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[4]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[5]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[6]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[7]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[8]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets UART_FF_INS/RO[9]/ro_fanout_ins[0]/ro_inst[0]/x[2]]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/RO_SENS[5]/FSM_onehot_next_state[1]_i_1__0]
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets {UART_FF_INS/RO[0]/ro_fanout_ins[0]/ro_inst[0]/a}]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[0]/ro_fanout_ins[0]/ro_inst[0]/*]
+
+
+set_property IOSTANDARD DIFF_SSTL12 [get_ports QDR4_CLK_100MHZ_N]
+set_property PACKAGE_PIN BJ4 [get_ports QDR4_CLK_100MHZ_P]
+set_property PACKAGE_PIN BK3 [get_ports QDR4_CLK_100MHZ_N]
+set_property IOSTANDARD DIFF_SSTL12 [get_ports QDR4_CLK_100MHZ_P]
+
+
+
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[0]/ro_inst[0]/a]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[0]/ro_inst[0]/b]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[0]/ro_inst[0]/b_inferred_i_1__510_0[0]]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[0]/ro_inst[0]/x[0]]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[0]/ro_inst[0]/x[1]]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[0]/ro_inst[0]/x[2]]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[1]/ro_inst[0]/a]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[1]/ro_inst[0]/b]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[1]/ro_inst[0]/b_inferred_i_1__382_0[0]]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[1]/ro_inst[0]/x[0]]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[1]/ro_inst[0]/x[1]]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[1]/ro_inst[0]/x[2]]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[2]/ro_inst[0]/a]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[2]/ro_inst[0]/b]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[2]/ro_inst[0]/b_inferred_i_1__254_0[0]]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[2]/ro_inst[0]/x[0]]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[2]/ro_inst[0]/x[1]]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[2]/ro_inst[0]/x[2]]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[3]/ro_inst[0]/a]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[3]/ro_inst[0]/b]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[3]/ro_inst[0]/b_inferred_i_1__126_0[0]]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[3]/ro_inst[0]/x[0]]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[3]/ro_inst[0]/x[1]]
+#set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets design_1_i/PL_CORE_0/inst/UART_FF_INS/RO[3]/ro_inst[0]/x[2]]
+
+
+
+
+set_property PACKAGE_PIN BH24 [get_ports {led_out_ff[0]}]
+set_property IOSTANDARD LVCMOS18 [get_ports {led_out_ff[0]}]
+set_property PACKAGE_PIN BG24 [get_ports {led_out_ff[1]}]
+set_property IOSTANDARD LVCMOS18 [get_ports {led_out_ff[1]}]
+set_property PACKAGE_PIN BG25 [get_ports {led_out_ff[2]}]
+set_property IOSTANDARD LVCMOS18 [get_ports {led_out_ff[2]}]
+set_property PACKAGE_PIN BF25 [get_ports {led_out_ff[3]}]
+set_property IOSTANDARD LVCMOS18 [get_ports {led_out_ff[3]}]
+
+
+#set_property PACKAGE_PIN BP26 [get_ports uart_rx_line_0]
+#set_property IOSTANDARD LVCMOS18 [get_ports uart_rx_line_0]
+#set_property PACKAGE_PIN BN26 [get_ports uart_tx_line_0]
+#set_property IOSTANDARD LVCMOS18 [get_ports uart_tx_line_0]
+
+
+
+set_property PACKAGE_PIN BK28 [get_ports uart_rx_line]
+set_property IOSTANDARD LVCMOS18 [get_ports uart_rx_line]
+set_property PACKAGE_PIN BJ28 [get_ports uart_tx_line]
+set_property IOSTANDARD LVCMOS18 [get_ports uart_tx_line]
+#set_property PACKAGE_PIN BL26 [get_ports "UART1_RTS_B"] ;# Bank 67 VCCO - VCC1V8 - IO_L8N_T1L_N3_AD5N_67
+#set_property IOSTANDARD LVCMOS18 [get_ports "UART1_RTS_B"] ;# Bank 67 VCCO - VCC1V8 - IO_L8N_T1L_N3_AD5N_67
+#set_property PACKAGE_PIN BL27 [get_ports "UART1_CTS_B"] ;# Bank 67 VCCO - VCC1V8 - IO_L8P_T1L_N2_AD5P_67
+#set_property IOSTANDARD LVCMOS18 [get_ports "UART1_CTS_B"] ;# Bank 67 VCCO - VCC1V8 - IO_L8P_T1L_N2_AD5P_67
+
+
+#set_property PACKAGE_PIN BP26 [get_ports uart_tx_line_0]
+#set_property IOSTANDARD LVCMOS18 [get_ports uart_tx_line_0]
+#set_property PACKAGE_PIN BN26 [get_ports uart_rx_line_0]
+#set_property IOSTANDARD LVCMOS18 [get_ports uart_rx_line_0]
+
+
+
+#set_property USER_SLR_ASSIGNMENT SLR1 [get_cells -hier {*/aes_ht_free/*}]
+
+#set_property USER_SLR_ASSIGNMENT SLR1 [get_cells -hier -filter {NAME =~ */aes_ht_free}]
+
+#set_property USER_SLR_ASSIGNMENT SLR1 [get_cells -hier -filter {NAME =~ */aes_ht}]
+
+
+#set_property USER_SLR_ASSIGNMENT SLR2 [get_cells -hier -filter {NAME =~ */ff[0]}]
+#set_property USER_SLR_ASSIGNMENT SLR2 [get_cells -hier -filter {NAME =~ */ff[1]}]
+#set_property USER_SLR_ASSIGNMENT SLR2 [get_cells -hier -filter {NAME =~ */ff[2]}]
+#set_property USER_SLR_ASSIGNMENT SLR2 [get_cells -hier -filter {NAME =~ */ff[3]}]
+
+#set_property USER_SLR_ASSIGNMENT SLR0 [get_cells -hier -filter {NAME =~ */RO[0]}]
+#set_property USER_SLR_ASSIGNMENT SLR0 [get_cells -hier -filter {NAME =~ */RO[1]}]
+#set_property USER_SLR_ASSIGNMENT SLR0 [get_cells -hier -filter {NAME =~ */RO[2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells -hier -filter {NAME =~ */RO_SENS*}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells uart_rx_line_IBUF_inst]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells uart_tx_line_OBUF_inst]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][0]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][0]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][0]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][0]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][1]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][1]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][1]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][1]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][2]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][2]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][2]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][2]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][3]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][3]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][3]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][3]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][4]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][4]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][4]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][4]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][5]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][5]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][5]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][5]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][6]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][6]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][6]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][6]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_10}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_11}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_12}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_13}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_14}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_15}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_18}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_31}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_32}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_33}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_34}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_37}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_38}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_39}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_4}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_40}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_49}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_50}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_51}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_52}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_53}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_54}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_55}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_56}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_7}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[0][7]_i_9}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[10][0]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[10][1]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[10][2]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[10][3]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[10][4]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[10][5]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[10][6]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[10][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[11][0]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[11][1]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[11][2]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[11][3]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[11][4]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[11][5]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[11][6]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[11][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[12][0]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[12][1]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[12][2]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[12][3]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[12][4]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[12][5]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[12][6]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[12][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[13][0]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[13][1]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[13][2]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[13][3]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[13][4]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[13][5]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[13][6]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[13][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[14][0]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[14][1]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[14][2]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[14][3]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[14][4]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[14][5]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[14][6]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[14][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[15][0]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[15][1]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[15][2]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[15][3]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[15][4]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[15][5]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[15][6]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[15][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[1][0]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[1][0]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[1][1]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[1][1]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[1][2]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[1][2]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[1][3]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[1][3]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[1][4]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[1][4]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[1][5]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[1][5]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[1][6]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[1][6]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[1][7]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[1][7]_i_4}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[1][7]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[1][7]_i_8}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[2][0]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[2][1]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[2][2]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[2][3]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[2][4]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[2][5]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[2][6]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[2][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[3][0]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[3][1]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[3][2]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[3][3]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[3][4]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[3][5]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[3][6]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[3][7]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[3][7]_i_4}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[4][0]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[4][1]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[4][2]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[4][3]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[4][4]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[4][5]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[4][6]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[4][7]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[5][0]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[5][1]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[5][2]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[5][3]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[5][4]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[5][5]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[5][6]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[5][7]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[6][0]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[6][1]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[6][2]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[6][3]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[6][4]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[6][5]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[6][6]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[6][7]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[7][0]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[7][1]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[7][2]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[7][3]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[7][4]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[7][5]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[7][6]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[7][7]_i_4}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[8][0]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[8][1]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[8][2]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[8][3]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[8][4]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[8][5]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[8][6]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[8][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[9][0]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[9][1]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[9][2]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[9][3]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[9][4]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[9][5]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[9][6]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data[9][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_length[0]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_length[1]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_length[2]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_length[3]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_length[4]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_length_reg[0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_length_reg[1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_length_reg[2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_length_reg[3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_length_reg[4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[0][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[0][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[0][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[0][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[0][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[0][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[0][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[0][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[0][7]_i_19}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[0][7]_i_20}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[0][7]_i_21}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[0][7]_i_22}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[0][7]_i_23}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[0][7]_i_24}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[0][7]_i_29}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[0][7]_i_30}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[0][7]_i_35}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[0][7]_i_36}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[10][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[10][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[10][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[10][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[10][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[10][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[10][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[10][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[11][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[11][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[11][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[11][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[11][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[11][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[11][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[11][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[12][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[12][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[12][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[12][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[12][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[12][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[12][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[12][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[13][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[13][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[13][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[13][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[13][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[13][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[13][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[13][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[14][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[14][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[14][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[14][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[14][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[14][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[14][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[14][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[15][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[15][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[15][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[15][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[15][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[15][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[15][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[15][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[1][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[1][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[1][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[1][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[1][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[1][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[1][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[1][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[2][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[2][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[2][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[2][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[2][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[2][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[2][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[2][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[3][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[3][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[3][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[3][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[3][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[3][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[3][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[3][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[4][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[4][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[4][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[4][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[4][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[4][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[4][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[4][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[5][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[5][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[5][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[5][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[5][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[5][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[5][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[5][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[6][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[6][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[6][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[6][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[6][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[6][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[6][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[6][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[7][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[7][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[7][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[7][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[7][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[7][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[7][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[7][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[8][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[8][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[8][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[8][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[8][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[8][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[8][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[8][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[9][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[9][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[9][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[9][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[9][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[9][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[9][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/uart_tx_data_reg[9][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/uart_tx_en_reg]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[10]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[11]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[12]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[13]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[14]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[15]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[15]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[15]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[16]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[17]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[18]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[19]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[1]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[1]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[1]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[20]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[21]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[22]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[24]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[25]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[26]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[27]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[28]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[29]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[2]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[30]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[30]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[31]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[31]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[32]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[33]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[34]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[34]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[34]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[35]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[35]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_10}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_11}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_12}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_13}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_14}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_15}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_16}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_166}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_167}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_168}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_169}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_17}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_170}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_171}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_172}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_173}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_174}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_175}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_176}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_177}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_178}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_179}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_18}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_180}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_181}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_182}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_183}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_184}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_185}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_186}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_187}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_188}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_189}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_190}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_191}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_192}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_193}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_194}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_195}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_196}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_197}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_198}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_199}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_20}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_200}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_201}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_202}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_203}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_204}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_205}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_206}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_207}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_208}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_209}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_21}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_210}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_211}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_212}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_213}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_214}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_215}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_216}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_217}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_218}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_219}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_22}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_220}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_221}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_222}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_223}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_224}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_225}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_226}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_227}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_228}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_229}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_230}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_231}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_232}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_233}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_234}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_235}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_236}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_237}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_238}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_239}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_240}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_241}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_242}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_243}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_244}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_245}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_246}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_247}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_248}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_249}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_25}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_250}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_251}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_252}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_253}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_254}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_255}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_256}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_257}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_258}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_259}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_26}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_260}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_261}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_262}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_263}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_264}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_265}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_266}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_267}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_268}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_269}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_27}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_270}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_271}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_272}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_273}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_274}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_275}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_276}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_277}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_278}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_279}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_28}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_280}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_281}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_282}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_283}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_284}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_285}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_286}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_287}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_288}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_289}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_29}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_290}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_291}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_292}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_293}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_30}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_31}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_32}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_33}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_38}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_4}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_43}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_54}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_55}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_57}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_58}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_59}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_60}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_61}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_62}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_63}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_64}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_65}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_66}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_7}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_8}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[36]_i_9}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[37]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[37]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[3]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[5]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[6]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[8]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state[9]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_100}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_101}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_102}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_103}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_104}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_105}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_106}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_107}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_108}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_109}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_110}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_111}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_112}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_113}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_114}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_115}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_116}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_117}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_118}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_119}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_120}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_121}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_122}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_123}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_124}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_125}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_126}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_127}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_128}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_129}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_130}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_131}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_132}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_133}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_134}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_135}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_136}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_137}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_138}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_139}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_140}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_141}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_142}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_143}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_144}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_145}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_146}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_147}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_148}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_149}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_150}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_151}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_152}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_153}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_154}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_155}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_156}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_157}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_158}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_159}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_160}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_161}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_162}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_163}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_164}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_165}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_34}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_35}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_36}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_37}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_70}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_71}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_72}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_73}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_74}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_75}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_76}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_77}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_78}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_79}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_80}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_81}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_82}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_83}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_84}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_85}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_86}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_87}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_88}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_89}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_90}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_91}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_92}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_93}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_94}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_95}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_96}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_97}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_98}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/FSM_onehot_current_state_reg[36]_i_99}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/GND]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/VCC]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/aes_key[127]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/aes_ptx[127]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/aes_ptx[127]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[0]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[10]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[11]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[12]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[13]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[14]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[15]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[16]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[17]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[18]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[19]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[1]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[20]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[21]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[22]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[23]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[24]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[25]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[26]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[27]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[28]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[29]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[2]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[30]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[31]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[3]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[4]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[5]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[6]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[8]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_en[9]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/chain_id_reg[7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/div_frac[31]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/div_int[31]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/div_int[31]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_1]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_10]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_100]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_101]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_102]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_103]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_104]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_105]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_106]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_107]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_108]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_109]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_11]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_110]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_111]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_112]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_113]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_114]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_115]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_116]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_117]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_118]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_119]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_12]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_120]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_121]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_122]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_123]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_124]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_125]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_126]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_127]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_128]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_129]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_13]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_130]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_131]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_132]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_133]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_134]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_135]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_136]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_137]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_138]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_139]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_14]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_140]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_141]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_142]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_143]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_144]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_145]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_146]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_147]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_148]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_149]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_15]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_150]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_151]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_152]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_153]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_154]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_155]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_156]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_157]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_158]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_159]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_16]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_160]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_161]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_162]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_163]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_164]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_165]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_166]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_167]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_168]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_169]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_17]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_170]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_171]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_172]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_173]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_174]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_175]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_176]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_177]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_178]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_179]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_18]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_180]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_181]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_182]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_183]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_184]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_185]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_186]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_187]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_188]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_189]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_19]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_190]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_191]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_192]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_193]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_194]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_195]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_196]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_197]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_198]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_199]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_2]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_20]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_200]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_201]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_202]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_203]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_204]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_205]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_206]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_207]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_208]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_209]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_21]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_210]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_211]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_212]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_213]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_214]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_215]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_216]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_217]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_218]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_219]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_22]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_220]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_221]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_222]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_223]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_224]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_225]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_226]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_227]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_228]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_229]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_23]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_230]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_231]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_232]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_233]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_234]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_235]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_236]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_237]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_238]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_239]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_24]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_240]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_241]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_242]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_243]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_244]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_245]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_246]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_247]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_248]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_249]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_25]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_250]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_251]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_252]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_253]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_254]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_255]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_256]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_257]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_258]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_259]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_26]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_260]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_261]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_262]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_263]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_264]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_265]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_266]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_267]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_268]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_269]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_27]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_270]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_271]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_272]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_273]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_274]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_275]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_276]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_277]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_278]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_279]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_28]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_280]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_281]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_282]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_283]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_284]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_285]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_286]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_287]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_288]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_289]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_29]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_290]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_291]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_292]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_293]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_294]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_295]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_296]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_297]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_298]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_299]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_3]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_30]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_300]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_301]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_302]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_303]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_304]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_305]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_306]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_307]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_308]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_309]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_31]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_310]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_311]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_312]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_313]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_314]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_315]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_316]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_317]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_318]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_319]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_32]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_320]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_321]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_322]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_323]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_324]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_325]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_326]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_327]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_328]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_329]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_33]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_330]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_331]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_332]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_333]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_334]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_335]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_336]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_337]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_338]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_339]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_34]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_340]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_341]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_342]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_343]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_344]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_345]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_346]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_347]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_348]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_349]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_35]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_350]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_351]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_352]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_353]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_354]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_355]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_356]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_357]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_358]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_359]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_36]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_360]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_361]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_362]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_363]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_364]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_365]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_366]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_367]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_368]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_369]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_37]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_370]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_371]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_372]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_373]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_374]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_375]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_376]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_377]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_378]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_379]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_38]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_380]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_381]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_382]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_383]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_384]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_385]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_386]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_387]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_388]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_389]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_39]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_390]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_391]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_392]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_393]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_394]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_395]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_396]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_397]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_398]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_399]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_4]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_40]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_400]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_401]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_402]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_403]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_404]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_405]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_406]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_407]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_408]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_409]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_41]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_410]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_411]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_412]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_413]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_414]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_415]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_416]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_417]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_418]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_419]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_42]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_420]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_421]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_422]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_423]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_424]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_425]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_426]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_427]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_428]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_429]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_43]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_430]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_431]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_432]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_433]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_434]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_435]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_436]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_437]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_438]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_439]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_44]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_440]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_441]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_442]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_443]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_444]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_445]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_446]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_447]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_448]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_449]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_45]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_450]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_451]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_452]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_453]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_454]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_455]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_456]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_457]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_458]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_459]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_46]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_460]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_461]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_462]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_463]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_464]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_465]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_466]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_467]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_468]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_469]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_47]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_470]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_471]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_472]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_473]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_474]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_475]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_476]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_477]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_478]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_479]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_48]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_480]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_481]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_482]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_483]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_484]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_485]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_486]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_487]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_488]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_489]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_49]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_490]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_491]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_492]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_493]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_494]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_495]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_496]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_497]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_498]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_499]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_5]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_50]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_500]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_501]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_502]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_503]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_504]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_505]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_506]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_507]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_508]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_509]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_51]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_510]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_511]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_512]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_513]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_514]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_515]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_516]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_517]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_518]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_519]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_52]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_520]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_521]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_522]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_523]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_524]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_525]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_526]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_527]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_528]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_529]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_53]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_530]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_531]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_532]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_533]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_534]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_535]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_536]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_537]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_538]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_539]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_54]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_540]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_541]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_542]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_543]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_544]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_545]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_546]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_547]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_548]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_549]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_55]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_550]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_551]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_552]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_553]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_554]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_555]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_556]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_557]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_558]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_559]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_56]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_560]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_561]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_562]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_563]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_564]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_565]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_566]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_567]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_568]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_569]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_57]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_570]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_571]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_572]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_573]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_574]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_575]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_576]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_577]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_578]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_579]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_58]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_580]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_581]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_582]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_583]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_584]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_585]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_586]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_587]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_588]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_589]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_59]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_590]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_591]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_592]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_593]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_594]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_595]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_596]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_597]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_598]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_599]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_6]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_60]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_600]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_601]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_602]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_603]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_604]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_605]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_606]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_607]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_608]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_609]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_61]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_610]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_611]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_612]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_613]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_614]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_615]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_616]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_617]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_618]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_619]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_62]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_620]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_621]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_622]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_623]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_624]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_625]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_626]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_627]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_628]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_629]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_63]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_630]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_631]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_632]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_633]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_634]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_635]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_636]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_637]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_638]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_639]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_64]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_640]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_641]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_642]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_643]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_644]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_645]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_646]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_647]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_648]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_649]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_65]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_650]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_651]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_652]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_653]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_654]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_655]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_656]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_657]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_658]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_659]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_66]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_660]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_661]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_662]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_663]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_664]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_665]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_666]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_667]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_668]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_669]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_67]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_670]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_671]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_672]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_673]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_674]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_675]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_676]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_677]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_678]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_679]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_68]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_680]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_681]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_682]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_683]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_684]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_685]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_686]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_687]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_688]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_689]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_69]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_690]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_691]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_692]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_693]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_694]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_695]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_696]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_697]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_698]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_699]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_7]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_70]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_700]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_701]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_702]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_703]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_704]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_705]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_706]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_707]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_708]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_709]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_71]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_710]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_711]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_712]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_713]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_714]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_72]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_73]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_74]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_75]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_76]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_77]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_78]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_79]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_8]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_80]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_81]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_82]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_83]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_84]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_85]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_86]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_87]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_88]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_89]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_9]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_90]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_91]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_92]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_93]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_94]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_95]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_96]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_97]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_98]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/g0_b0_i_99]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/receiver]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[0]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[10]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[11]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[12]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[13]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[14]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[15]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[16]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[17]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[18]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[19]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[1]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[20]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[21]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[22]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[23]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[24]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[25]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[26]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[27]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[28]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[29]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[2]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[30]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[31]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[3]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[4]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[5]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[6]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[8]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_en[9]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_id_reg[7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_id_reg[7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_id_reg[7]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_meas_time[63]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_meas_time[63]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/ro_meas_time[63]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[118][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[122][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[126][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[138][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[139][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[139][7]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[154][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[163][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[170][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[176][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[179][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[183][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[187][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[190][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[194][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[202][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[216][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[224][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[232][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[36][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[37][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[38][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[62][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data[67][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[0]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[0]_rep__0_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[0]_rep__1_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[0]_rep__2_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[0]_rep__3_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[0]_rep_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[1]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[1]_rep__0_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[1]_rep__1_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[1]_rep__2_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[1]_rep__3_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[1]_rep_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[2]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[2]_rep__0_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[2]_rep__1_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[2]_rep__2_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[2]_rep_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[3]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[3]_rep__0_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[3]_rep_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[4]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[4]_rep__0_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[4]_rep_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[5]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[5]_rep_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[6]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[6]_rep_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[8]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length[8]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[0]_rep}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[0]_rep__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[0]_rep__1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[0]_rep__2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[0]_rep__3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[1]_rep}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[1]_rep__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[1]_rep__1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[1]_rep__2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[1]_rep__3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[2]_rep}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[2]_rep__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[2]_rep__1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[2]_rep__2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[3]_rep}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[3]_rep__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[4]_rep}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[4]_rep__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[5]_rep}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[6]_rep}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_length_reg[8]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[0][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[0][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[0][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[0][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[0][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[0][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[0][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[0][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[100][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[100][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[100][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[100][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[100][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[100][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[100][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[100][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[101][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[101][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[101][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[101][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[101][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[101][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[101][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[101][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[102][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[102][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[102][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[102][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[102][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[102][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[102][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[102][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[103][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[103][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[103][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[103][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[103][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[103][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[103][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[103][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[104][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[104][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[104][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[104][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[104][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[104][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[104][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[104][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[105][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[105][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[105][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[105][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[105][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[105][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[105][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[105][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[106][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[106][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[106][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[106][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[106][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[106][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[106][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[106][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[107][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[107][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[107][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[107][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[107][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[107][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[107][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[107][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[108][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[108][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[108][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[108][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[108][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[108][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[108][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[108][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[109][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[109][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[109][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[109][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[109][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[109][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[109][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[109][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[10][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[10][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[10][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[10][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[10][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[10][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[10][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[10][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[110][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[110][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[110][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[110][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[110][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[110][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[110][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[110][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[111][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[111][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[111][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[111][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[111][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[111][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[111][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[111][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[112][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[112][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[112][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[112][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[112][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[112][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[112][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[112][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[113][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[113][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[113][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[113][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[113][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[113][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[113][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[113][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[114][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[114][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[114][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[114][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[114][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[114][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[114][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[114][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[115][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[115][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[115][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[115][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[115][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[115][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[115][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[115][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[116][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[116][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[116][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[116][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[116][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[116][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[116][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[116][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[117][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[117][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[117][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[117][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[117][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[117][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[117][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[117][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[118][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[118][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[118][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[118][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[118][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[118][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[118][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[118][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[119][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[119][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[119][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[119][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[119][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[119][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[119][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[119][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[11][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[11][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[11][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[11][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[11][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[11][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[11][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[11][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[120][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[120][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[120][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[120][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[120][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[120][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[120][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[120][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[121][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[121][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[121][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[121][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[121][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[121][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[121][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[121][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[122][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[122][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[122][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[122][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[122][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[122][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[122][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[122][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[123][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[123][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[123][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[123][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[123][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[123][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[123][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[123][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[124][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[124][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[124][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[124][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[124][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[124][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[124][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[124][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[125][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[125][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[125][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[125][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[125][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[125][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[125][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[125][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[126][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[126][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[126][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[126][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[126][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[126][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[126][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[126][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[127][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[127][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[127][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[127][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[127][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[127][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[127][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[127][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[128][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[128][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[128][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[128][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[128][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[128][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[128][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[128][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[129][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[129][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[129][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[129][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[129][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[129][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[129][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[129][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[12][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[12][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[12][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[12][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[12][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[12][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[12][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[12][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[130][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[130][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[130][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[130][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[130][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[130][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[130][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[130][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[131][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[131][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[131][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[131][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[131][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[131][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[131][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[131][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[132][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[132][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[132][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[132][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[132][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[132][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[132][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[132][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[133][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[133][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[133][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[133][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[133][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[133][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[133][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[133][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[134][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[134][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[134][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[134][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[134][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[134][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[134][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[134][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[135][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[135][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[135][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[135][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[135][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[135][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[135][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[135][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[136][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[136][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[136][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[136][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[136][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[136][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[136][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[136][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[137][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[137][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[137][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[137][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[137][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[137][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[137][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[137][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[138][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[138][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[138][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[138][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[138][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[138][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[138][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[138][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[139][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[139][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[139][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[139][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[139][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[139][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[139][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[139][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[13][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[13][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[13][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[13][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[13][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[13][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[13][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[13][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[140][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[140][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[140][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[140][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[140][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[140][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[140][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[140][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[141][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[141][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[141][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[141][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[141][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[141][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[141][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[141][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[142][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[142][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[142][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[142][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[142][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[142][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[142][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[142][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[143][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[143][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[143][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[143][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[143][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[143][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[143][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[143][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[144][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[144][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[144][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[144][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[144][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[144][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[144][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[144][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[145][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[145][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[145][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[145][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[145][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[145][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[145][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[145][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[146][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[146][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[146][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[146][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[146][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[146][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[146][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[146][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[147][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[147][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[147][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[147][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[147][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[147][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[147][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[147][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[148][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[148][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[148][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[148][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[148][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[148][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[148][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[148][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[149][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[149][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[149][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[149][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[149][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[149][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[149][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[149][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[14][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[14][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[14][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[14][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[14][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[14][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[14][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[14][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[150][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[150][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[150][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[150][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[150][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[150][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[150][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[150][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[151][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[151][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[151][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[151][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[151][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[151][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[151][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[151][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[152][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[152][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[152][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[152][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[152][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[152][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[152][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[152][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[153][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[153][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[153][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[153][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[153][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[153][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[153][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[153][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[154][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[154][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[154][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[154][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[154][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[154][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[154][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[154][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[155][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[155][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[155][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[155][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[155][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[155][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[155][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[155][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[156][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[156][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[156][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[156][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[156][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[156][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[156][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[156][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[157][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[157][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[157][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[157][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[157][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[157][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[157][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[157][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[158][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[158][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[158][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[158][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[158][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[158][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[158][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[158][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[159][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[159][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[159][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[159][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[159][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[159][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[159][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[159][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[15][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[15][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[15][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[15][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[15][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[15][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[15][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[15][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[160][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[160][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[160][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[160][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[160][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[160][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[160][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[160][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[161][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[161][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[161][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[161][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[161][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[161][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[161][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[161][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[162][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[162][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[162][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[162][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[162][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[162][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[162][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[162][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[163][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[163][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[163][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[163][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[163][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[163][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[163][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[163][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[164][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[164][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[164][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[164][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[164][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[164][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[164][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[164][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[165][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[165][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[165][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[165][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[165][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[165][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[165][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[165][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[166][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[166][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[166][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[166][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[166][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[166][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[166][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[166][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[167][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[167][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[167][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[167][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[167][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[167][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[167][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[167][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[168][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[168][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[168][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[168][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[168][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[168][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[168][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[168][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[169][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[169][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[169][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[169][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[169][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[169][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[169][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[169][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[16][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[16][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[16][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[16][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[16][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[16][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[16][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[16][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[170][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[170][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[170][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[170][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[170][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[170][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[170][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[170][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[171][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[171][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[171][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[171][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[171][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[171][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[171][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[171][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[172][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[172][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[172][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[172][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[172][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[172][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[172][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[172][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[173][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[173][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[173][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[173][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[173][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[173][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[173][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[173][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[174][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[174][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[174][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[174][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[174][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[174][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[174][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[174][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[175][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[175][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[175][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[175][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[175][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[175][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[175][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[175][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[176][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[176][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[176][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[176][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[176][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[176][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[176][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[176][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[177][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[177][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[177][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[177][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[177][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[177][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[177][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[177][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[178][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[178][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[178][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[178][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[178][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[178][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[178][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[178][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[179][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[179][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[179][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[179][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[179][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[179][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[179][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[179][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[17][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[17][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[17][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[17][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[17][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[17][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[17][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[17][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[180][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[180][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[180][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[180][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[180][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[180][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[180][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[180][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[181][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[181][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[181][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[181][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[181][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[181][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[181][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[181][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[182][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[182][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[182][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[182][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[182][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[182][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[182][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[182][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[183][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[183][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[183][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[183][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[183][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[183][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[183][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[183][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[184][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[184][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[184][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[184][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[184][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[184][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[184][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[184][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[185][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[185][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[185][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[185][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[185][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[185][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[185][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[185][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[186][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[186][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[186][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[186][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[186][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[186][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[186][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[186][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[187][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[187][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[187][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[187][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[187][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[187][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[187][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[187][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[188][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[188][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[188][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[188][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[188][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[188][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[188][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[188][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[189][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[189][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[189][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[189][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[189][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[189][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[189][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[189][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[18][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[18][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[18][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[18][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[18][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[18][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[18][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[18][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[190][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[190][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[190][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[190][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[190][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[190][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[190][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[190][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[191][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[191][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[191][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[191][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[191][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[191][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[191][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[191][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[192][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[192][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[192][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[192][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[192][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[192][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[192][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[192][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[193][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[193][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[193][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[193][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[193][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[193][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[193][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[193][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[194][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[194][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[194][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[194][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[194][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[194][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[194][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[194][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[195][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[195][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[195][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[195][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[195][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[195][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[195][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[195][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[196][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[196][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[196][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[196][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[196][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[196][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[196][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[196][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[197][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[197][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[197][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[197][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[197][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[197][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[197][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[197][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[198][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[198][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[198][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[198][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[198][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[198][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[198][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[198][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[199][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[199][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[199][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[199][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[199][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[199][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[199][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[199][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[19][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[19][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[19][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[19][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[19][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[19][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[19][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[19][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[1][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[1][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[1][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[1][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[1][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[1][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[1][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[1][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[200][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[200][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[200][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[200][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[200][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[200][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[200][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[200][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[201][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[201][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[201][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[201][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[201][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[201][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[201][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[201][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[202][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[202][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[202][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[202][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[202][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[202][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[202][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[202][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[203][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[203][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[203][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[203][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[203][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[203][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[203][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[203][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[204][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[204][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[204][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[204][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[204][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[204][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[204][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[204][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[205][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[205][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[205][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[205][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[205][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[205][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[205][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[205][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[206][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[206][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[206][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[206][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[206][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[206][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[206][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[206][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[207][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[207][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[207][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[207][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[207][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[207][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[207][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[207][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[208][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[208][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[208][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[208][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[208][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[208][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[208][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[208][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[209][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[209][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[209][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[209][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[209][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[209][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[209][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[209][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[20][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[20][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[20][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[20][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[20][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[20][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[20][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[20][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[210][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[210][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[210][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[210][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[210][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[210][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[210][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[210][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[211][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[211][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[211][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[211][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[211][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[211][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[211][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[211][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[212][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[212][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[212][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[212][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[212][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[212][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[212][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[212][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[213][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[213][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[213][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[213][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[213][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[213][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[213][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[213][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[214][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[214][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[214][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[214][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[214][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[214][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[214][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[214][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[215][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[215][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[215][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[215][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[215][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[215][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[215][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[215][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[216][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[216][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[216][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[216][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[216][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[216][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[216][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[216][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[217][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[217][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[217][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[217][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[217][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[217][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[217][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[217][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[218][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[218][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[218][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[218][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[218][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[218][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[218][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[218][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[219][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[219][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[219][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[219][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[219][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[219][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[219][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[219][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[21][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[21][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[21][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[21][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[21][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[21][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[21][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[21][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[220][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[220][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[220][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[220][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[220][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[220][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[220][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[220][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[221][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[221][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[221][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[221][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[221][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[221][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[221][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[221][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[222][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[222][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[222][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[222][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[222][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[222][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[222][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[222][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[223][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[223][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[223][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[223][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[223][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[223][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[223][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[223][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[224][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[224][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[224][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[224][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[224][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[224][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[224][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[224][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[225][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[225][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[225][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[225][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[225][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[225][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[225][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[225][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[226][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[226][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[226][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[226][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[226][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[226][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[226][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[226][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[227][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[227][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[227][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[227][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[227][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[227][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[227][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[227][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[228][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[228][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[228][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[228][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[228][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[228][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[228][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[228][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[229][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[229][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[229][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[229][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[229][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[229][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[229][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[229][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[22][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[22][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[22][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[22][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[22][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[22][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[22][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[22][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[230][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[230][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[230][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[230][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[230][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[230][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[230][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[230][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[231][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[231][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[231][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[231][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[231][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[231][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[231][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[231][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[232][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[232][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[232][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[232][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[232][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[232][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[232][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[232][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[233][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[233][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[233][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[233][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[233][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[233][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[233][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[233][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[234][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[234][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[234][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[234][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[234][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[234][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[234][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[234][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[235][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[235][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[235][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[235][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[235][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[235][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[235][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[235][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[236][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[236][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[236][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[236][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[236][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[236][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[236][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[236][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[237][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[237][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[237][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[237][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[237][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[237][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[237][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[237][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[238][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[238][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[238][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[238][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[238][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[238][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[238][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[238][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[239][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[239][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[239][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[239][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[239][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[239][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[239][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[239][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[23][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[23][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[23][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[23][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[23][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[23][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[23][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[23][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[240][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[240][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[240][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[240][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[240][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[240][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[240][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[240][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[241][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[241][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[241][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[241][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[241][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[241][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[241][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[241][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[242][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[242][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[242][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[242][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[242][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[242][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[242][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[242][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[243][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[243][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[243][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[243][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[243][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[243][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[243][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[243][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[244][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[244][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[244][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[244][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[244][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[244][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[244][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[244][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[245][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[245][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[245][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[245][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[245][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[245][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[245][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[245][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[246][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[246][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[246][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[246][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[246][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[246][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[246][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[246][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[247][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[247][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[247][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[247][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[247][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[247][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[247][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[247][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[248][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[248][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[248][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[248][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[248][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[248][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[248][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[248][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[249][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[249][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[249][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[249][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[249][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[249][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[249][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[249][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[24][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[24][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[24][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[24][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[24][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[24][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[24][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[24][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[250][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[250][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[250][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[250][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[250][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[250][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[250][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[250][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[251][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[251][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[251][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[251][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[251][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[251][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[251][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[251][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[252][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[252][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[252][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[252][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[252][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[252][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[252][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[252][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[253][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[253][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[253][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[253][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[253][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[253][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[253][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[253][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[254][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[254][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[254][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[254][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[254][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[254][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[254][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[254][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[255][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[255][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[255][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[255][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[255][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[255][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[255][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[255][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[25][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[25][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[25][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[25][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[25][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[25][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[25][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[25][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[26][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[26][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[26][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[26][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[26][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[26][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[26][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[26][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[27][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[27][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[27][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[27][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[27][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[27][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[27][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[27][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[28][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[28][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[28][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[28][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[28][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[28][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[28][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[28][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[29][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[29][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[29][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[29][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[29][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[29][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[29][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[29][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[2][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[2][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[2][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[2][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[2][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[2][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[2][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[2][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[30][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[30][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[30][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[30][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[30][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[30][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[30][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[30][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[31][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[31][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[31][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[31][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[31][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[31][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[31][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[31][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[32][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[32][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[32][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[32][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[32][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[32][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[32][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[32][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[33][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[33][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[33][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[33][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[33][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[33][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[33][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[33][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[34][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[34][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[34][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[34][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[34][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[34][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[34][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[34][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[35][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[35][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[35][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[35][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[35][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[35][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[35][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[35][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[36][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[36][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[36][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[36][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[36][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[36][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[36][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[36][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[37][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[37][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[37][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[37][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[37][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[37][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[37][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[37][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[38][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[38][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[38][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[38][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[38][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[38][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[38][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[38][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[39][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[39][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[39][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[39][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[39][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[39][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[39][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[39][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[3][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[3][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[3][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[3][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[3][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[3][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[3][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[3][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[40][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[40][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[40][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[40][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[40][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[40][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[40][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[40][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[41][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[41][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[41][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[41][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[41][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[41][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[41][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[41][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[42][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[42][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[42][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[42][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[42][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[42][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[42][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[42][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[43][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[43][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[43][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[43][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[43][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[43][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[43][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[43][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[44][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[44][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[44][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[44][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[44][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[44][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[44][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[44][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[45][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[45][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[45][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[45][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[45][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[45][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[45][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[45][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[46][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[46][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[46][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[46][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[46][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[46][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[46][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[46][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[47][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[47][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[47][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[47][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[47][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[47][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[47][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[47][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[48][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[48][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[48][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[48][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[48][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[48][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[48][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[48][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[49][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[49][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[49][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[49][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[49][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[49][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[49][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[49][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[4][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[4][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[4][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[4][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[4][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[4][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[4][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[4][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[50][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[50][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[50][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[50][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[50][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[50][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[50][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[50][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[51][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[51][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[51][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[51][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[51][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[51][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[51][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[51][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[52][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[52][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[52][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[52][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[52][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[52][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[52][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[52][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[53][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[53][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[53][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[53][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[53][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[53][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[53][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[53][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[54][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[54][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[54][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[54][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[54][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[54][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[54][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[54][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[55][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[55][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[55][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[55][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[55][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[55][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[55][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[55][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[56][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[56][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[56][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[56][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[56][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[56][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[56][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[56][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[57][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[57][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[57][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[57][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[57][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[57][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[57][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[57][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[58][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[58][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[58][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[58][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[58][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[58][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[58][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[58][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[59][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[59][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[59][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[59][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[59][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[59][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[59][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[59][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[5][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[5][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[5][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[5][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[5][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[5][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[5][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[5][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[60][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[60][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[60][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[60][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[60][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[60][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[60][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[60][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[61][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[61][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[61][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[61][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[61][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[61][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[61][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[61][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[62][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[62][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[62][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[62][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[62][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[62][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[62][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[62][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[63][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[63][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[63][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[63][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[63][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[63][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[63][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[63][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[64][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[64][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[64][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[64][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[64][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[64][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[64][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[64][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[65][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[65][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[65][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[65][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[65][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[65][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[65][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[65][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[66][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[66][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[66][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[66][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[66][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[66][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[66][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[66][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[67][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[67][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[67][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[67][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[67][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[67][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[67][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[67][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[68][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[68][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[68][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[68][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[68][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[68][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[68][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[68][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[69][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[69][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[69][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[69][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[69][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[69][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[69][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[69][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[6][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[6][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[6][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[6][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[6][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[6][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[6][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[6][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[70][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[70][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[70][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[70][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[70][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[70][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[70][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[70][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[71][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[71][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[71][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[71][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[71][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[71][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[71][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[71][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[72][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[72][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[72][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[72][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[72][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[72][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[72][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[72][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[73][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[73][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[73][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[73][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[73][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[73][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[73][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[73][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[74][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[74][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[74][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[74][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[74][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[74][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[74][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[74][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[75][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[75][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[75][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[75][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[75][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[75][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[75][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[75][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[76][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[76][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[76][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[76][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[76][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[76][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[76][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[76][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[77][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[77][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[77][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[77][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[77][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[77][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[77][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[77][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[78][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[78][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[78][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[78][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[78][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[78][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[78][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[78][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[79][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[79][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[79][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[79][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[79][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[79][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[79][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[79][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[7][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[7][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[7][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[7][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[7][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[7][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[7][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[7][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[80][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[80][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[80][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[80][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[80][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[80][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[80][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[80][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[81][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[81][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[81][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[81][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[81][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[81][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[81][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[81][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[82][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[82][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[82][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[82][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[82][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[82][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[82][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[82][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[83][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[83][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[83][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[83][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[83][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[83][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[83][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[83][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[84][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[84][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[84][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[84][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[84][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[84][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[84][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[84][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[85][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[85][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[85][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[85][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[85][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[85][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[85][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[85][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[86][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[86][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[86][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[86][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[86][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[86][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[86][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[86][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[87][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[87][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[87][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[87][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[87][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[87][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[87][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[87][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[88][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[88][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[88][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[88][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[88][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[88][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[88][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[88][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[89][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[89][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[89][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[89][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[89][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[89][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[89][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[89][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[8][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[8][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[8][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[8][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[8][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[8][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[8][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[8][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[90][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[90][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[90][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[90][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[90][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[90][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[90][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[90][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[91][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[91][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[91][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[91][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[91][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[91][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[91][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[91][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[92][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[92][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[92][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[92][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[92][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[92][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[92][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[92][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[93][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[93][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[93][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[93][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[93][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[93][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[93][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[93][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[94][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[94][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[94][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[94][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[94][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[94][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[94][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[94][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[95][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[95][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[95][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[95][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[95][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[95][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[95][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[95][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[96][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[96][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[96][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[96][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[96][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[96][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[96][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[96][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[97][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[97][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[97][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[97][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[97][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[97][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[97][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[97][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[98][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[98][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[98][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[98][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[98][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[98][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[98][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[98][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[99][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[99][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[99][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[99][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[99][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[99][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[99][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[99][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[9][0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[9][1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[9][2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[9][3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[9][4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[9][5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[9][6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/rx_data_reg[9][7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/FSM_sequential_current_state[0]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/FSM_sequential_current_state[1]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/FSM_sequential_current_state[2]_i_10}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/FSM_sequential_current_state[2]_i_11}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/FSM_sequential_current_state[2]_i_12}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/FSM_sequential_current_state[2]_i_13}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/FSM_sequential_current_state[2]_i_14}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/FSM_sequential_current_state[2]_i_1__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/FSM_sequential_current_state[2]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/FSM_sequential_current_state[2]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/FSM_sequential_current_state[2]_i_4}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/FSM_sequential_current_state[2]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/FSM_sequential_current_state[2]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/FSM_sequential_current_state[2]_i_7}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/FSM_sequential_current_state[2]_i_8}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/FSM_sequential_current_state[2]_i_9}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/FSM_sequential_current_state_reg[0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/FSM_sequential_current_state_reg[1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/FSM_sequential_current_state_reg[2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/receiver/GND]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/receiver/GND_1]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/receiver/VCC]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter0_carry]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter0_carry__0]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter0_carry__1]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter0_carry__2]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter[0]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter[31]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[10]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[11]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[12]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[13]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[14]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[15]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[16]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[17]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[18]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[19]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[20]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[21]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[22]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[23]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[24]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[25]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[26]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[27]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[28]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[29]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[30]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[31]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[8]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/clock_counter_reg[9]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/current_bit[0]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/current_bit[1]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/current_bit[2]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/current_bit[3]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/current_bit[3]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/current_bit_reg[0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/current_bit_reg[1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/current_bit_reg[2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/current_bit_reg[3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[0][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[0][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[0]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[0]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[0]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[0]_rep__0_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[0]_rep__1_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[0]_rep_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[100][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[101][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[102][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[103][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[104][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[105][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[106][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[107][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[108][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[109][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[10][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[110][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[111][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[112][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[113][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[113][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[114][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[114][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[115][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[116][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[117][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[118][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[119][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[11][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[120][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[120][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[121][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[122][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[123][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[123][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[124][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[125][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[126][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[127][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[127][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[128][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[129][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[12][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[130][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[131][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[132][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[133][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[134][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[135][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[136][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[137][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[138][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[139][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[13][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[140][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[141][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[142][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[143][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[144][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[145][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[146][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[147][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[148][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[149][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[14][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[150][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[151][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[152][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[153][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[154][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[155][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[156][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[157][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[158][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[159][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[15][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[15][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[160][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[161][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[162][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[163][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[164][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[165][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[166][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[167][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[168][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[169][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[16][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[170][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[171][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[172][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[173][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[174][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[175][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[176][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[177][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[178][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[179][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[17][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[180][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[181][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[182][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[183][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[184][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[184][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[185][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[186][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[187][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[188][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[189][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[18][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[190][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[191][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[192][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[193][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[194][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[195][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[195][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[196][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[197][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[198][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[199][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[19][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[1][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[1]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[1]_rep__0_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[1]_rep__1_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[1]_rep_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[200][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[201][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[202][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[203][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[204][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[205][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[206][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[207][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[208][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[209][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[20][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[210][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[211][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[212][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[213][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[214][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[215][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[216][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[217][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[218][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[219][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[21][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[220][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[221][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[222][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[223][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[224][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[225][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[226][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[227][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[228][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[229][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[22][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[230][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[231][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[232][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[233][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[234][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[235][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[236][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[237][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[238][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[239][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[23][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[240][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[241][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[242][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[243][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[244][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[245][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[246][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[247][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[248][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[249][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[24][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[250][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[251][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[252][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[252][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[253][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[253][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[254][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[254][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[255][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[255][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[25][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[26][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[27][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[28][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[29][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[2][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[2]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[2]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[2]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[2]_rep__0_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[2]_rep__1_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[2]_rep_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[30][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[30][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[31][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[32][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[33][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[34][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[35][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[36][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[37][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[38][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[38][7]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[39][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[3][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[3]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[3]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[3]_rep__0_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[3]_rep__1_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[3]_rep_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[40][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[41][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[42][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[43][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[44][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[45][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[46][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[46][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[47][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[48][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[49][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[4][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[4]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[4]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[4]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[4]_i_4}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[4]_rep__0_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[4]_rep__1_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[4]_rep_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[50][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[51][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[52][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[53][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[54][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[55][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[56][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[57][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[58][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[59][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[5][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[5]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[5]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[5]_rep__0_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[5]_rep__1_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[5]_rep_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[60][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[60][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[61][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[62][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[63][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[64][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[65][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[66][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[67][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[68][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[69][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[6][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[6]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[6]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[6]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[6]_i_4}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[6]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[6]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[6]_rep__0_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[6]_rep__1_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[6]_rep_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[70][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[71][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[72][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[73][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[74][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[75][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[76][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[77][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[78][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[79][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[7][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[7][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[7]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[7]_i_4}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[7]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[7]_rep__0_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[7]_rep__1_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[7]_rep_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[80][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[81][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[82][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[83][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[84][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[85][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[86][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[87][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[88][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[89][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[8][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[90][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[91][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[92][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[93][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[94][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[95][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[96][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[97][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[98][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[99][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[99][7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data[9][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_length[8]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[0]_rep}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[0]_rep__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[0]_rep__1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[1]_rep}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[1]_rep__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[1]_rep__1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[2]_rep}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[2]_rep__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[2]_rep__1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[3]_rep}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[3]_rep__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[3]_rep__1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[4]_rep}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[4]_rep__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[4]_rep__1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[5]_rep}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[5]_rep__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[5]_rep__1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[6]_rep}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[6]_rep__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[6]_rep__1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[7]_rep}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[7]_rep__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_rxer/receiver/rx_data_reg[7]_rep__1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_onehot_current_state[36]_i_19}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_onehot_current_state[36]_i_56}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[0]_i_10}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[0]_i_1__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[0]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[0]_i_4}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[0]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[0]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[0]_i_7}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[0]_i_8}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[0]_i_9}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_10}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_11}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_12}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_13}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_14}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_15}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_16}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_17}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_18}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_19}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_20}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_21}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_22}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_23}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_24}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_25}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_26}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_27}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_28}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_29}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_30}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_31}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_32}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_33}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_34}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_35}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_36}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_7}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_8}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state[1]_i_9}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state_reg[0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state_reg[0]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state_reg[1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state_reg[1]_i_4}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/FSM_sequential_current_state_reg[1]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/GND]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/GND_1]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/VCC]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter[0]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[10]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[11]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[12]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[13]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[14]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[15]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[16]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[16]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[17]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[18]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[19]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[20]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[21]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[22]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[23]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[24]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[24]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[25]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[26]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[27]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[28]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[29]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[30]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[31]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[31]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[8]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[8]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/delay_counter_reg[9]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/sender]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/transfer_counter[0]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/transfer_counter[1]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/transfer_counter[2]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/transfer_counter[3]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/transfer_counter[4]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/transfer_counter[5]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/transfer_counter[5]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/transfer_counter[6]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/transfer_counter[7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/transfer_counter[7]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/transfer_counter_reg[0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/transfer_counter_reg[1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/transfer_counter_reg[2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/transfer_counter_reg[3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/transfer_counter_reg[4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/transfer_counter_reg[5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/transfer_counter_reg[6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/transfer_counter_reg[7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/tx_ready_i_1__0]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/tx_ready_reg]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[0][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[0]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[0]_i_4}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[0]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[0]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[0]_i_7}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[15][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[1][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[1]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[1]_i_4}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[1]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[1]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[1]_i_7}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[2]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[2]_i_4}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[2]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[2]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[2]_i_7}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[3][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[3]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[3]_i_4}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[3]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[3]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[3]_i_7}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[4]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[4]_i_4}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[4]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[4]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[4]_i_7}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[5]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[5]_i_4}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[5]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[5]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[5]_i_7}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[6]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[6]_i_4}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[6]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[6]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[6]_i_7}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[7][7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[7]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[7]_i_6}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[7]_i_7}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[7]_i_8}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data[7]_i_9}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[0]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[0]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[1]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[1]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[2]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[2]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[3]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[3]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[4]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[4]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[5]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[5]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[6]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[6]_i_3}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[7]_i_4}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/uart_tx_data_reg[7]_i_5}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/uart_tx_en_reg]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/FSM_sequential_current_state[0]_i_1__1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/FSM_sequential_current_state[1]_i_1__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/FSM_sequential_current_state[1]_i_1__1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/FSM_sequential_current_state[2]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/FSM_sequential_current_state[2]_i_10__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/FSM_sequential_current_state[2]_i_2__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/FSM_sequential_current_state[2]_i_3__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/FSM_sequential_current_state[2]_i_4__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/FSM_sequential_current_state[2]_i_5__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/FSM_sequential_current_state[2]_i_6__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/FSM_sequential_current_state[2]_i_7__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/FSM_sequential_current_state[2]_i_8__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/FSM_sequential_current_state[2]_i_9__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/FSM_sequential_current_state_reg[0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/FSM_sequential_current_state_reg[1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/FSM_sequential_current_state_reg[2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/sender/GND]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/sender/GND_1]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/sender/VCC]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/bit_counter[0]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/bit_counter[1]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/bit_counter[2]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/bit_counter[3]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/bit_counter[3]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/bit_counter_reg[0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/bit_counter_reg[1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/bit_counter_reg[2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/bit_counter_reg[3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/sender/clock_counter0_carry]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/sender/clock_counter0_carry__0]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/sender/clock_counter0_carry__1]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/sender/clock_counter0_carry__2]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter[0]_i_1__0}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter[32]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[0]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[10]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[11]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[12]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[13]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[14]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[15]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[16]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[17]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[18]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[19]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[1]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[20]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[21]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[22]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[23]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[24]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[25]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[26]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[27]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[28]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[29]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[2]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[30]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[31]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[32]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[3]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[4]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[5]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[6]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[7]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[8]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/clock_counter_reg[9]}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/delay_counter[31]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/delay_counter[31]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/transfer_counter[7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/sender/tx_line_i_1]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/sender/tx_line_i_2]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/sender/tx_line_i_3]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/sender/tx_line_i_4]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/sender/tx_line_i_5]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/sender/tx_line_reg]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/sender/tx_ready_i_1]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells UART_FF_INS/multibyte_uart_txer/sender/tx_ready_reg]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/uart_tx_data[7]_i_1}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells {UART_FF_INS/multibyte_uart_txer/sender/uart_tx_data[7]_i_2}]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells uart_rx_line_IBUF_inst/IBUFCTRL_INST]
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells uart_rx_line_IBUF_inst/INBUF_INST]
+
+#create_pblock pb_ff_0
+#set_property IS_SOFT FALSE [get_pblocks pb_ff_0]
+#resize_pblock [get_pblocks pb_ff_0] -add {CLOCKREGION_X6Y1:CLOCKREGION_X6Y1}
+#add_cells_to_pblock {pb_ff_0} [get_cells -hier -filter {NAME =~ */ff[0]}]
+
+
+create_pblock pb_ro_0
+add_cells_to_pblock [get_pblocks pb_ro_0] [get_cells -quiet [list {UART_FF_INS/RO[0]} {UART_FF_INS/chain[0]}]]
+resize_pblock [get_pblocks pb_ro_0] -add {CLOCKREGION_X0Y3:CLOCKREGION_X0Y3}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_0]
+#resize_pblock [get_pblocks pb_ro_0] -add {SLICE_X117Y0:SLICE_X145Y59}
+
+
+
+create_pblock pb_ro_1
+add_cells_to_pblock [get_pblocks pb_ro_1] [get_cells -quiet [list {UART_FF_INS/RO[1]} {UART_FF_INS/chain[1]}]]
+resize_pblock [get_pblocks pb_ro_1] -add {CLOCKREGION_X1Y3:CLOCKREGION_X1Y3}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_1]
+
+create_pblock pb_ro_2
+add_cells_to_pblock [get_pblocks pb_ro_2] [get_cells -quiet [list {UART_FF_INS/RO[2]} {UART_FF_INS/chain[2]}]]
+resize_pblock [get_pblocks pb_ro_2] -add {CLOCKREGION_X2Y3:CLOCKREGION_X2Y3}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_2]
+
+create_pblock pb_ro_3
+add_cells_to_pblock [get_pblocks pb_ro_3] [get_cells -quiet [list {UART_FF_INS/RO[3]} {UART_FF_INS/chain[3]}]]
+resize_pblock [get_pblocks pb_ro_3] -add {CLOCKREGION_X3Y3:CLOCKREGION_X3Y3}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_3]
+
+create_pblock pb_ro_4
+add_cells_to_pblock [get_pblocks pb_ro_4] [get_cells -quiet [list {UART_FF_INS/RO[4]} {UART_FF_INS/chain[4]}]]
+resize_pblock [get_pblocks pb_ro_4] -add {CLOCKREGION_X4Y3:CLOCKREGION_X4Y3}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_4]
+
+create_pblock pb_ro_5
+add_cells_to_pblock [get_pblocks pb_ro_5] [get_cells -quiet [list {UART_FF_INS/RO[5]} {UART_FF_INS/chain[5]}]]
+resize_pblock [get_pblocks pb_ro_5] -add {CLOCKREGION_X5Y3:CLOCKREGION_X5Y3}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_5]
+
+create_pblock pb_ro_6
+add_cells_to_pblock [get_pblocks pb_ro_6] [get_cells -quiet [list {UART_FF_INS/RO[6]} {UART_FF_INS/chain[6]}]]
+resize_pblock [get_pblocks pb_ro_6] -add {CLOCKREGION_X6Y3:CLOCKREGION_X6Y3}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_6]
+
+create_pblock pb_ro_7
+add_cells_to_pblock [get_pblocks pb_ro_7] [get_cells -quiet [list {UART_FF_INS/RO[7]} {UART_FF_INS/chain[7]}]]
+resize_pblock [get_pblocks pb_ro_7] -add {CLOCKREGION_X7Y3:CLOCKREGION_X7Y3}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_7]
+
+
+create_pblock pb_ro_8
+add_cells_to_pblock [get_pblocks pb_ro_8] [get_cells -quiet [list {UART_FF_INS/RO[8]} {UART_FF_INS/chain[8]}]]
+resize_pblock [get_pblocks pb_ro_8] -add {CLOCKREGION_X0Y2:CLOCKREGION_X0Y2}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_8]
+
+create_pblock pb_ro_9
+add_cells_to_pblock [get_pblocks pb_ro_9] [get_cells -quiet [list {UART_FF_INS/RO[9]} {UART_FF_INS/chain[9]}]]
+resize_pblock [get_pblocks pb_ro_9] -add {CLOCKREGION_X1Y2:CLOCKREGION_X1Y2}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_9]
+
+create_pblock pb_ro_10
+add_cells_to_pblock [get_pblocks pb_ro_10] [get_cells -quiet [list {UART_FF_INS/RO[10]} {UART_FF_INS/chain[10]}]]
+resize_pblock [get_pblocks pb_ro_10] -add {CLOCKREGION_X2Y2:CLOCKREGION_X2Y2}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_10]
+
+
+create_pblock pb_ro_11
+add_cells_to_pblock [get_pblocks pb_ro_11] [get_cells -quiet [list {UART_FF_INS/RO[11]} {UART_FF_INS/chain[11]}]]
+resize_pblock [get_pblocks pb_ro_11] -add {CLOCKREGION_X3Y2:CLOCKREGION_X3Y2}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_11]
+
+
+
+create_pblock pb_ro_12
+add_cells_to_pblock [get_pblocks pb_ro_12] [get_cells -quiet [list {UART_FF_INS/RO[12]} {UART_FF_INS/chain[12]}]]
+resize_pblock [get_pblocks pb_ro_12] -add {CLOCKREGION_X4Y2:CLOCKREGION_X4Y2}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_12]
+
+
+create_pblock pb_ro_13
+add_cells_to_pblock [get_pblocks pb_ro_13] [get_cells -quiet [list {UART_FF_INS/RO[13]} {UART_FF_INS/chain[13]}]]
+resize_pblock [get_pblocks pb_ro_13] -add {CLOCKREGION_X5Y2:CLOCKREGION_X5Y2}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_13]
+
+create_pblock pb_ro_14
+add_cells_to_pblock [get_pblocks pb_ro_14] [get_cells -quiet [list {UART_FF_INS/RO[14]} {UART_FF_INS/chain[14]}]]
+resize_pblock [get_pblocks pb_ro_14] -add {CLOCKREGION_X6Y2:CLOCKREGION_X6Y2}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_14]
+
+create_pblock pb_ro_15
+add_cells_to_pblock [get_pblocks pb_ro_15] [get_cells -quiet [list {UART_FF_INS/RO[15]} {UART_FF_INS/chain[15]}]]
+resize_pblock [get_pblocks pb_ro_15] -add {CLOCKREGION_X7Y2:CLOCKREGION_X7Y2}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_15]
+
+create_pblock pb_ro_16
+add_cells_to_pblock [get_pblocks pb_ro_16] [get_cells -quiet [list {UART_FF_INS/RO[16]} {UART_FF_INS/chain[16]}]]
+resize_pblock [get_pblocks pb_ro_16] -add {CLOCKREGION_X0Y1:CLOCKREGION_X0Y1}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_16]
+
+create_pblock pb_ro_17
+add_cells_to_pblock [get_pblocks pb_ro_17] [get_cells -quiet [list {UART_FF_INS/RO[17]} {UART_FF_INS/chain[17]}]]
+resize_pblock [get_pblocks pb_ro_17] -add {CLOCKREGION_X1Y1:CLOCKREGION_X1Y1}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_17]
+
+create_pblock pb_ro_18
+add_cells_to_pblock [get_pblocks pb_ro_18] [get_cells -quiet [list {UART_FF_INS/RO[18]} {UART_FF_INS/chain[18]}]]
+resize_pblock [get_pblocks pb_ro_18] -add {CLOCKREGION_X2Y1:CLOCKREGION_X2Y1}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_18]
+
+create_pblock pb_ro_19
+add_cells_to_pblock [get_pblocks pb_ro_19] [get_cells -quiet [list {UART_FF_INS/RO[19]} {UART_FF_INS/chain[19]}]]
+resize_pblock [get_pblocks pb_ro_19] -add {CLOCKREGION_X3Y1:CLOCKREGION_X3Y1}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_19]
+
+create_pblock pb_ro_20
+add_cells_to_pblock [get_pblocks pb_ro_20] [get_cells -quiet [list {UART_FF_INS/RO[20]} {UART_FF_INS/chain[20]}]]
+resize_pblock [get_pblocks pb_ro_20] -add {CLOCKREGION_X4Y1:CLOCKREGION_X4Y1}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_20]
+
+create_pblock pb_ro_21
+add_cells_to_pblock [get_pblocks pb_ro_21] [get_cells -quiet [list {UART_FF_INS/RO[21]} {UART_FF_INS/chain[21]}]]
+resize_pblock [get_pblocks pb_ro_21] -add {CLOCKREGION_X5Y1:CLOCKREGION_X5Y1}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_21]
+
+create_pblock pb_ro_22
+add_cells_to_pblock [get_pblocks pb_ro_22] [get_cells -quiet [list {UART_FF_INS/RO[22]} {UART_FF_INS/chain[22]}]]
+resize_pblock [get_pblocks pb_ro_22] -add {CLOCKREGION_X6Y1:CLOCKREGION_X6Y1}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_22]
+
+create_pblock pb_ro_23
+add_cells_to_pblock [get_pblocks pb_ro_23] [get_cells -quiet [list {UART_FF_INS/RO[23]} {UART_FF_INS/chain[23]}]]
+resize_pblock [get_pblocks pb_ro_23] -add {CLOCKREGION_X7Y1:CLOCKREGION_X7Y1}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_23]
+
+
+create_pblock pb_ro_24
+add_cells_to_pblock [get_pblocks pb_ro_24] [get_cells -quiet [list {UART_FF_INS/RO[24]} {UART_FF_INS/chain[24]}]]
+resize_pblock [get_pblocks pb_ro_24] -add {CLOCKREGION_X0Y0:CLOCKREGION_X0Y0}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_24]
+
+create_pblock pb_ro_25
+add_cells_to_pblock [get_pblocks pb_ro_25] [get_cells -quiet [list {UART_FF_INS/RO[25]} {UART_FF_INS/chain[25]}]]
+resize_pblock [get_pblocks pb_ro_25] -add {CLOCKREGION_X1Y0:CLOCKREGION_X1Y0}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_25]
+
+create_pblock pb_ro_26
+add_cells_to_pblock [get_pblocks pb_ro_26] [get_cells -quiet [list {UART_FF_INS/RO[26]} {UART_FF_INS/chain[26]}]]
+resize_pblock [get_pblocks pb_ro_26] -add {CLOCKREGION_X2Y0:CLOCKREGION_X2Y0}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_26]
+
+create_pblock pb_ro_27
+add_cells_to_pblock [get_pblocks pb_ro_27] [get_cells -quiet [list {UART_FF_INS/RO[27]} {UART_FF_INS/chain[27]}]]
+resize_pblock [get_pblocks pb_ro_27] -add {CLOCKREGION_X3Y0:CLOCKREGION_X3Y0}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_27]
+
+create_pblock pb_ro_28
+add_cells_to_pblock [get_pblocks pb_ro_28] [get_cells -quiet [list {UART_FF_INS/RO[28]} {UART_FF_INS/chain[28]}]]
+resize_pblock [get_pblocks pb_ro_28] -add {CLOCKREGION_X4Y0:CLOCKREGION_X4Y0}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_28]
+
+create_pblock pb_ro_29
+add_cells_to_pblock [get_pblocks pb_ro_29] [get_cells -quiet [list {UART_FF_INS/RO[29]} {UART_FF_INS/chain[29]}]]
+resize_pblock [get_pblocks pb_ro_29] -add {CLOCKREGION_X5Y0:CLOCKREGION_X5Y0}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_29]
+
+
+create_pblock pb_ro_30
+add_cells_to_pblock [get_pblocks pb_ro_30] [get_cells -quiet [list {UART_FF_INS/RO[30]} {UART_FF_INS/chain[30]}]]
+resize_pblock [get_pblocks pb_ro_30] -add {CLOCKREGION_X6Y0:CLOCKREGION_X6Y0}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_30]
+
+create_pblock pb_ro_31
+add_cells_to_pblock [get_pblocks pb_ro_31] [get_cells -quiet [list {UART_FF_INS/RO[31]} {UART_FF_INS/chain[31]}]]
+resize_pblock [get_pblocks pb_ro_31] -add {CLOCKREGION_X7Y0:CLOCKREGION_X7Y0}
+set_property IS_SOFT FALSE [get_pblocks pb_ro_31]
+
+
+
+
+
+
+
+#resize_pblock {pb_ro_0} -add {SLICE_X0Y180:SLICE_X19Y239}
+
+
+#set_property LOC {SLICE_X0Y180:SLICE_X19Y239} [get_cells -hier -filter {NAME =~ */RO[0]}]
+#add_cells_to_pblock {pb_ro_0} [get_cells -hier -filter {NAME =~ */RO[0]/*}]
+#add_cells_to_pblock {pb_ro_0} -verbose -clear_locs [get_cells -hier -filter {NAME =~ */RO[0]}]
+
+#set_property CLOCK_REGION X0Y3 [get_cells -hier -filter {NAME =~ */RO[0]}]
+
+#set_property BEL G5LUT [get_cells {UART_FF_INS/RO[0]/ro_fanout_ins[0]/ro_inst[0]/a_inferred_i_1__2}]
+#set_property LOC SLICE_X188Y100 [get_cells {UART_FF_INS/RO[0]/ro_fanout_ins[0]/ro_inst[0]/a_inferred_i_1__2}]
+#set_property BEL H6LUT [get_cells {UART_FF_INS/RO[0]/ro_fanout_ins[0]/ro_inst[0]/b_inferred_i_1__2}]
+#set_property LOC SLICE_X187Y95 [get_cells {UART_FF_INS/RO[0]/ro_fanout_ins[0]/ro_inst[0]/b_inferred_i_1__2}]
+
+
+#set_property USER_SLR_ASSIGNMENT SLR0 [get_cells -hier -filter {NAME =~ */RO_SENS}]
+
+#set_property USER_SLR_ASSIGNMENT SLR0 [get_cells -hier -filter {NAME =~ */chain[0]}]
+
+
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells -hier -filter {NAME =~ */instance_name}]
+
+set_property USER_SLR_ASSIGNMENT SLR0 [get_cells -hier -filter {NAME =~ */freq_gen_inst}]
+
+
+set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets -hier -filter {NAME =~ *RO*}]
+
+#set_property USER_SLR_ASSIGNMENT SLR2 [get_cells -hierarchical -filter {NAME =~ *ff*}]
+
+
+
+create_pblock pb_ff
+set_property IS_SOFT FALSE [get_pblocks pb_ff]
+resize_pblock [get_pblocks pb_ff] -add {SLICE_X155Y480:SLICE_X163Y509}
+add_cells_to_pblock {pb_ff} [get_cells -hier -filter {NAME =~ *ff*}]
+
+
+
+create_pblock pblock_SLL_1
+set_property IS_SOFT FALSE [get_pblocks pblock_SLL_1]
+resize_pblock [get_pblocks pblock_SLL_1] -add {CLOCKREGION_X7Y3:CLOCKREGION_X7Y3}
+add_cells_to_pblock {pblock_SLL_1} [get_nets {UART_FF_INS/v_int_sensor/inst/do_out}]
+add_cells_to_pblock {pblock_SLL_1} [get_cells -hier -filter {NAME =~ *v_int*}]
+set_property CONTAIN_ROUTING true [get_pblocks pblock_SLL_1]
diff --git a/hwdbg/src/main/systemverilog/sensors/src/PL_CORE.v b/hwdbg/src/main/systemverilog/sensors/src/PL_CORE.v
new file mode 100644
index 00000000..824e16b4
--- /dev/null
+++ b/hwdbg/src/main/systemverilog/sensors/src/PL_CORE.v
@@ -0,0 +1,64 @@
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+// Company:
+// Engineer:
+//
+// Create Date: 03/08/2024 04:39:27 PM
+// Design Name:
+// Module Name: PL_CORE
+// Project Name:
+// Target Devices:
+// Tool Versions:
+// Description:
+//
+// Dependencies:
+//
+// Revision:
+// Revision 0.01 - File Created
+// Additional Comments:
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+
+module PL_CORE(
+
+(* clock_buffer_type="none" *) input wire QDR4_CLK_100MHZ_P,
+(* clock_buffer_type="none" *) input wire QDR4_CLK_100MHZ_N,
+
+// input wire reg_clk,
+ input wire uart_rx_line,
+// input wire reg_eop,
+// input logic SPI_nCS,
+// output wire clk_reg_out,
+ output wire uart_tx_line,
+// output logic laser_module_trigger,
+
+ output wire [3:0] led_out_ff
+);
+
+wire clk_main;
+ clk_wiz_11 clock_main
+ (
+ // Clock out ports
+ .clk_main(clk_main), // output clk_main
+ // Status and control signals
+ .reset(reset), // input reset
+ .locked(locked), // output locked
+ // Clock in ports
+ .clk_in1_p(QDR4_CLK_100MHZ_P), // input clk_in1_p
+ .clk_in1_n(QDR4_CLK_100MHZ_N) // input clk_in1_n
+);
+
+
+UART_FF UART_FF_INS (
+ .clk (clk_main),
+ .rst ('b0),
+ .reg_clk (clk_main),
+ .reg_eop (clk_main),
+ .uart_rx_line (uart_rx_line),
+ .uart_tx_line (uart_tx_line),
+ .gpio (gpio),
+ .led_out_ff (led_out_ff)
+ );
+
+endmodule
diff --git a/hwdbg/src/main/systemverilog/sensors/src/ff_fanout.sv b/hwdbg/src/main/systemverilog/sensors/src/ff_fanout.sv
new file mode 100644
index 00000000..d27277e8
--- /dev/null
+++ b/hwdbg/src/main/systemverilog/sensors/src/ff_fanout.sv
@@ -0,0 +1,89 @@
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+// Company:
+// Engineer:
+//
+// Create Date: 11/16/2023 02:48:20 PM
+// Design Name:
+// Module Name: ff_fanout
+// Project Name:
+// Target Devices:
+// Tool Versions:
+// Description:
+//
+// Dependencies:
+//
+// Revision:
+// Revision 0.01 - File Created
+// Additional Comments:
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+
+module ff_fanout(
+input wire clk,
+input wire CE,
+input wire rst,
+input wire inp,
+output reg res
+ );
+
+
+
+//reg rst_em; // input clock on FPGA
+//reg[27:0] counter=28'd0;
+//parameter DIVISOR = 28'd1;
+//// The frequency of the output clk_out
+//// = The frequency of the input clk_in divided by DIVISOR
+//// For example: Fclk_in = 50Mhz, if you want to get 1Hz signal to blink LEDs
+//// You will modify the DIVISOR parameter value to 28'd50.000.000
+//// Then the frequency of the output clk_out = 50Mhz/50.000.000 = 1Hz
+//always @(posedge rst)
+//begin
+// counter <= counter + 28'd1;
+// if(counter>=(DIVISOR-1))
+// counter <= 28'd0;
+
+
+// rst_em <= (counter= (div_int - 1)) begin
+ int_counter <= 32'd0;
+ clk_out_internal <= ~clk_out_internal;
+ end else begin
+ int_counter <= int_counter + 1;
+ end
+ end
+ end
+
+ // Fractional Clock Division Logic
+ always_ff @(posedge clk_in or posedge reset) begin
+ if (reset) begin
+ frac_counter <= 32'd0;
+ frac_tick <= 1'b0;
+ end else begin
+ frac_counter <= frac_counter + div_frac;
+ if (frac_counter >= 32'd100000000) begin // When the counter exceeds 1.0 in fixed-point format
+ frac_counter <= frac_counter - 32'd100000000;
+ frac_tick <= 1'b1;
+ end else begin
+ frac_tick <= 1'b0;
+ end
+ end
+ end
+
+ // Combine Integer and Fractional Divisions
+ always_ff @(posedge clk_in or posedge reset) begin
+ if (reset) begin
+ clk_out <= 1'b0;
+ end else if (int_counter == 0 && frac_tick) begin
+ clk_out <= ~clk_out_internal;
+ end else begin
+ clk_out <= clk_out_internal;
+ end
+ end
+
+endmodule
diff --git a/hwdbg/src/main/systemverilog/sensors/src/inverter.v b/hwdbg/src/main/systemverilog/sensors/src/inverter.v
new file mode 100644
index 00000000..937fff73
--- /dev/null
+++ b/hwdbg/src/main/systemverilog/sensors/src/inverter.v
@@ -0,0 +1,29 @@
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+// Company:
+// Engineer:
+//
+// Create Date: 08/29/2023 01:50:41 PM
+// Design Name:
+// Module Name: inverter
+// Project Name:
+// Target Devices:
+// Tool Versions:
+// Description:
+//
+// Dependencies:
+//
+// Revision:
+// Revision 0.01 - File Created
+// Additional Comments:
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+
+module inverter(
+ in_data,out_data
+ );
+ input in_data;
+ output out_data;
+ (* dont_touch = "yes" *) assign out_data = !in_data;
+endmodule
diff --git a/hwdbg/src/main/systemverilog/sensors/src/inverter_chain.v b/hwdbg/src/main/systemverilog/sensors/src/inverter_chain.v
new file mode 100644
index 00000000..6a29a06d
--- /dev/null
+++ b/hwdbg/src/main/systemverilog/sensors/src/inverter_chain.v
@@ -0,0 +1,43 @@
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+// Company:
+// Engineer:
+//
+// Create Date: 09/11/2023 11:01:41 AM
+// Design Name:
+// Module Name: inverter_chain
+// Project Name:
+// Target Devices:
+// Tool Versions:
+// Description:
+//
+// Dependencies:
+//
+// Revision:
+// Revision 0.01 - File Created
+// Additional Comments:
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+
+module Chain(
+ chain_en,
+ in_data,
+ out_data
+ );
+ parameter N = 2000; //This is the number of inverters in chain
+ input wire chain_en;
+
+ input wire in_data; // This has to be connected to the input pin of the design according to the XDC file
+
+ output wire out_data; // make sure to connect it to one of the output pin of the circuit according to the XDC file
+ (* dont_touch = "yes" *) wire [N-1:0] intermadiate_value; //For D-flip-flop implementation, make it reg instead of wire!
+ (* dont_touch = "yes" *) inverter inverter_in (.in_data(in_data&chain_en),.out_data(intermadiate_value[0])); // this is just for initiation, for loop chain, you can remove it.
+ generate
+ genvar i;
+ for (i=0; i 0)) begin
+ current_state <= STATE_TRANSFER;
+ transfer_counter <= 'd0;
+ end else begin
+ tx_ready <= 'b1;
+ end
+ end
+
+ STATE_TRANSFER: begin
+ if (uart_tx_ready) begin
+ uart_tx_data <= tx_data[transfer_counter];
+ uart_tx_en <= 'b1;
+ current_state <= STATE_WAIT_BEWTEEN_TX;
+ delay_counter <= 'd0;
+ transfer_counter <= transfer_counter + 1;
+ end
+ end
+
+ STATE_WAIT_BEWTEEN_TX: begin
+ if (uart_tx_ready) begin
+ delay_counter <= delay_counter + 1;
+ if (delay_counter >= delay_between_tx) begin
+ if (transfer_counter >= tx_data_length) begin
+ current_state <= STATE_IDLE;
+ end else begin
+ current_state <= STATE_TRANSFER;
+ end
+ end
+ end
+ end
+ endcase
+ end
+ end
+endmodule
\ No newline at end of file
diff --git a/hwdbg/src/main/systemverilog/sensors/src/not_gate_simple.v b/hwdbg/src/main/systemverilog/sensors/src/not_gate_simple.v
new file mode 100644
index 00000000..8c915a28
--- /dev/null
+++ b/hwdbg/src/main/systemverilog/sensors/src/not_gate_simple.v
@@ -0,0 +1,31 @@
+`timescale 1ps / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+// Company:
+// Engineer:
+//
+// Create Date: 11/13/2023 05:16:59 PM
+// Design Name:
+// Module Name: not_gate_simple
+// Project Name:
+// Target Devices:
+// Tool Versions:
+// Description:
+//
+// Dependencies:
+//
+// Revision:
+// Revision 0.01 - File Created
+// Additional Comments:
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+
+module not_gate_simple(
+input wire X,
+output wire Y
+ );
+
+// (* ALLOW_COMBINATORIAL_LOOPS = "yes" *) assign #10 Y = ~X;
+ (* ALLOW_COMBINATORIAL_LOOPS = "yes" *) assign Y = ~X;
+
+endmodule
diff --git a/hwdbg/src/main/systemverilog/sensors/src/ro.v b/hwdbg/src/main/systemverilog/sensors/src/ro.v
new file mode 100644
index 00000000..bc21afd3
--- /dev/null
+++ b/hwdbg/src/main/systemverilog/sensors/src/ro.v
@@ -0,0 +1,76 @@
+`timescale 1ns/1ps
+
+
+module ro(
+// input ck_io41,
+// output ck_io33
+ input wire R_in,
+ output wire R_out);
+wire a /* synthesis keep */;
+wire b /* synthesis keep */;
+
+
+assign b = a & R_in;
+//assign b = a ;
+
+wire [2:0] x /* synthesis keep */;
+
+not_gate_simple not0(
+ .X(b),
+ .Y(x[0]));
+
+not_gate_simple not1(
+ .X(x[0]),
+ .Y(x[1]));
+
+not_gate_simple not2(
+ .X(x[1]),
+ .Y(x[2]));
+
+//not_gate_simple not3(
+// .X(x[2]),
+// .Y(x[3]));
+
+//not_gate_simple not4(
+// .X(x[3]),
+// .Y(x[4]));
+
+//not_gate_simple not5(
+// .X(x[4]),
+// .Y(x[5]));
+
+//not_gate_simple not6(
+// .X(x[5]),
+// .Y(x[6]));
+
+//not_gate_simple not7(
+// .X(x[6]),
+// .Y(x[7]));
+
+//not_gate_simple not8(
+// .X(x[7]),
+// .Y(x[8]));
+
+//not_gate_simple not9(
+// .X(x[8]),
+// .Y(x[9]));
+
+//not_gate_simple not10(
+// .X(x[9]),
+// .Y(x[10]));
+
+
+
+
+assign R_out = x[2];
+assign a = x[2] & R_in;
+
+
+
+endmodule
+
+
+
+
+
+
diff --git a/hwdbg/src/main/systemverilog/sensors/src/ro_core.sv b/hwdbg/src/main/systemverilog/sensors/src/ro_core.sv
new file mode 100644
index 00000000..d3cda0b9
--- /dev/null
+++ b/hwdbg/src/main/systemverilog/sensors/src/ro_core.sv
@@ -0,0 +1,60 @@
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+// Company:
+// Engineer:
+//
+// Create Date: 12/01/2022 04:46:30 PM
+// Design Name:
+// Module Name: reg1_core
+// Project Name:
+// Target Devices:
+// Tool Versions:
+// Description:
+//
+// Dependencies:
+//
+// Revision:
+// Revision 0.01 - File Created
+// Additional Comments:
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+module ro_core(
+ input wire [0:0] in_d,
+ output wire [0:0] wire_inj
+ );
+// localparam size_i = 127000;
+//localparam size_i = 64000;
+//localparam size_i = 1000;
+//localparam size_i = 128;
+localparam size_i = 1;
+
+ reg ce1;
+ reg CLR1;
+ wire [size_i-1:0] inp_r;
+
+// assign inp_r=in_d[size_i-1:0];
+ assign inp_r=in_d[size_i-1:0];
+
+
+ (* S = "TRUE" *)(* KEEP = "TRUE" *) wire [size_i-1:0] q_out;
+ assign wire_inj = q_out;
+
+
+
+ro_fanout ro_fanout_ins[size_i-1:0] (
+ .R_in(inp_r), // 1-bit Enable
+ .R_out(q_out) // 1-bit Data output
+);
+
+
+
+endmodule
+
+
+
+
diff --git a/hwdbg/src/main/systemverilog/sensors/src/ro_fanout.sv b/hwdbg/src/main/systemverilog/sensors/src/ro_fanout.sv
new file mode 100644
index 00000000..b909f4be
--- /dev/null
+++ b/hwdbg/src/main/systemverilog/sensors/src/ro_fanout.sv
@@ -0,0 +1,50 @@
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+// Company:
+// Engineer:
+//
+// Create Date: 03/15/2024 01:55:18 PM
+// Design Name:
+// Module Name: ro_fanout
+// Project Name:
+// Target Devices:
+// Tool Versions:
+// Description:
+//
+// Dependencies:
+//
+// Revision:
+// Revision 0.01 - File Created
+// Additional Comments:
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+
+module ro_fanout(
+input wire R_in,
+output wire R_out
+ );
+
+ localparam size_i = 1;
+
+ (* S = "TRUE" *) (* KEEP = "TRUE" *) wire [size_i-1:0] ro_input;
+ (* S = "TRUE" *) (* KEEP = "TRUE" *) wire [size_i-1:0] ro_output;
+
+ assign R_out = ro_output[0];
+
+ assign ro_input = ({size_i{R_in}});
+
+ (* S = "TRUE" *) (* KEEP = "TRUE" *) ro ro_inst[size_i-1:0](
+ .R_in(ro_input),
+ .R_out(ro_output)
+
+ );
+
+
+// (* S = "TRUE" *) (* KEEP = "TRUE" *) ro_sv #(.INVERTERS_PER_RING(3), .INVERTER_DELAY(1)) ro_inst[size_i-1:0](
+// .R_in(ro_input),
+// .R_out(ro_output)
+
+// );
+
+endmodule
diff --git a/hwdbg/src/main/systemverilog/sensors/src/ro_sensor.sv b/hwdbg/src/main/systemverilog/sensors/src/ro_sensor.sv
new file mode 100644
index 00000000..fa813431
--- /dev/null
+++ b/hwdbg/src/main/systemverilog/sensors/src/ro_sensor.sv
@@ -0,0 +1,138 @@
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+// Company:
+// Engineer:
+//
+// Create Date: 06/17/2024 05:14:28 PM
+// Design Name:
+// Module Name: ro_sensor
+// Project Name:
+// Target Devices:
+// Tool Versions:
+// Description:
+//
+// Dependencies:
+//
+// Revision:
+// Revision 0.01 - File Created
+// Additional Comments:
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+
+module ro_sensor
+ #(parameter integer width_size = 64,
+ localparam integer width_size_local = width_size)
+ (
+ input logic [width_size-1:0]ro_meas_time,
+ input logic clk,
+ input logic r_out,
+ input logic ro_counter_en,
+ output logic [width_size-1:0]ro_meas_count
+ );
+
+
+ logic [width_size-1:0] clk_temp_counter;
+ logic [width_size-1:0] ro_temp_counter;
+
+ logic measure_flag;
+
+ // RO_Counter Circuit
+ // State encoding
+ typedef enum logic [1:0] {
+ IDLE = 2'b00,
+ MEASURE = 2'b01,
+ OUT_READY = 2'b10,
+ RST_VALS = 2'b11
+
+ } state_t;
+
+ state_t current_state, next_state;
+ initial next_state <= IDLE;
+ // State transition logic
+ always_ff @(negedge clk ) begin
+ current_state <= next_state;
+ end
+
+ // Next state logic
+ always @(posedge clk) begin
+ case (current_state)
+ IDLE: begin
+ for (int i = 0; i < width_size; i++) begin
+ clk_temp_counter[i] = 1'b0;
+ end
+ if (ro_counter_en) begin
+ next_state = RST_VALS;
+ end else begin
+ next_state = IDLE;
+ end
+ end
+
+ RST_VALS: begin
+ next_state = MEASURE;
+
+ end
+
+ MEASURE: begin
+ if (clk_temp_counter < ro_meas_time) begin
+ clk_temp_counter = clk_temp_counter+ ('d1);
+ next_state = MEASURE;
+ end else begin
+ for (int i = 0; i < width_size; i++) begin
+ clk_temp_counter[i] = 1'b0;
+ end
+ next_state = OUT_READY;
+ end
+ end
+
+ OUT_READY: begin
+ next_state = IDLE;
+
+ end
+
+// default: begin
+// next_state = IDLE;
+// end
+ endcase
+ end
+
+ // Output logic
+// assign state = current_state;
+
+
+
+ always @( posedge r_out ) begin
+
+ if(current_state==MEASURE) begin
+ ro_temp_counter=ro_temp_counter+ ('d1);
+
+
+ end else if(current_state==OUT_READY) begin
+ ro_meas_count = ro_temp_counter;
+
+
+
+ end else if(current_state==RST_VALS) begin
+
+ ro_temp_counter = 'h0000000000000000;
+
+
+ end
+ end
+
+
+// `define assign_reg(index,reg1_t,reg2_t) \
+// assign reg1_t[((index+1)*60)+7:((index)*60)+8]=reg2_t[index];
+
+
+// `assign_reg(0,aes_ct,fult_count)
+// `assign_reg(1,aes_ct,fult_count)
+//// `assign_reg(2,aes_ct,fult_count)
+//// `assign_reg(3,aes_ct,fult_count)
+//// `assign_reg(4,aes_ct,fult_count)
+//// `assign_reg(5,aes_ct,fult_count)
+//// `assign_reg(6,aes_ct,fult_count)
+//// `assign_reg(7,aes_ct,fult_count)
+
+
+endmodule
diff --git a/hwdbg/src/main/systemverilog/sensors/src/top.sv b/hwdbg/src/main/systemverilog/sensors/src/top.sv
new file mode 100644
index 00000000..66732e7c
--- /dev/null
+++ b/hwdbg/src/main/systemverilog/sensors/src/top.sv
@@ -0,0 +1,1165 @@
+`timescale 1ns/1ps
+
+module UART_FF
+(
+ input logic clk,
+ input logic rst,
+ input logic uart_rx_line,
+ input logic reg_clk,
+ input logic reg_eop,
+// input logic SPI_nCS,
+// output logic clk_reg_out,
+ output logic uart_tx_line,
+// output logic laser_module_trigger,
+ output logic gpio,
+
+ output [3:0] led_out_ff
+
+);
+
+
+
+ localparam SYSTEMCLOCK = 100_000_000;
+// localparam SYSTEMCLOCK = 10_000_000;
+
+ localparam UART_BAUDRATE = 115_200;
+ localparam UART_ELEMENT_WIDTH = 8;
+ localparam MULTIBYTE_RX_NUMBER_OF_ELEMENTS = 256;
+ localparam MULTIBYTE_RX_COUNTER_WIDTH = $clog2(MULTIBYTE_RX_NUMBER_OF_ELEMENTS);
+
+ logic uart_rx_empty_buffer;
+ logic [MULTIBYTE_RX_NUMBER_OF_ELEMENTS-1:0][UART_ELEMENT_WIDTH-1:0] uart_rx_data;
+ logic [MULTIBYTE_RX_COUNTER_WIDTH:0] uart_rx_data_length;
+ logic uart_rx_updated_buffer;
+ logic uart_rx_overflow;
+ multibyte_uart_rx multibyte_uart_rxer (
+ .clk (clk),
+ .rst (rst),
+ .rx_line (uart_rx_line),
+ .rx_empty_buffer (uart_rx_empty_buffer),
+ .rx_data (uart_rx_data),
+ .rx_data_length (uart_rx_data_length),
+ .rx_updated_buffer (uart_rx_updated_buffer),
+ .rx_overflow (uart_rx_overflow)
+ );
+ defparam multibyte_uart_rxer.SYSTEMCLOCK = SYSTEMCLOCK;
+ defparam multibyte_uart_rxer.BAUDRATE = UART_BAUDRATE;
+ defparam multibyte_uart_rxer.ELEMENT_WIDTH = UART_ELEMENT_WIDTH;
+ defparam multibyte_uart_rxer.NUMBER_OF_ELEMENTS = MULTIBYTE_RX_NUMBER_OF_ELEMENTS;
+
+
+
+
+ localparam MULTIBYTE_TX_NUMBER_OF_ELEMENTS = 256;
+ localparam DELAY_COUNTER_WIDTH = 32;
+ localparam MULTIBYTE_TX_COUNTER_WIDTH = $clog2(MULTIBYTE_TX_NUMBER_OF_ELEMENTS);
+
+ logic uart_tx_en;
+ logic [MULTIBYTE_TX_NUMBER_OF_ELEMENTS-1:0][UART_ELEMENT_WIDTH-1:0] uart_tx_data;
+ logic [MULTIBYTE_TX_COUNTER_WIDTH:0] uart_tx_data_length;
+ logic [DELAY_COUNTER_WIDTH-1:0] delay_between_tx;
+ logic uart_tx_ready;
+
+ multibyte_uart_tx multibyte_uart_txer (
+ .clk (clk),
+ .rst (rst),
+ .tx_en (uart_tx_en),
+ .tx_data (uart_tx_data),
+ .tx_data_length (uart_tx_data_length),
+ .delay_between_tx (delay_between_tx),
+ .tx_line (uart_tx_line),
+ .tx_ready (uart_tx_ready)
+ );
+ defparam multibyte_uart_txer.SYSTEMCLOCK = SYSTEMCLOCK;
+ defparam multibyte_uart_txer.BAUDRATE = UART_BAUDRATE;
+ defparam multibyte_uart_txer.ELEMENT_WIDTH = UART_ELEMENT_WIDTH;
+ defparam multibyte_uart_txer.NUMBER_OF_ELEMENTS = MULTIBYTE_TX_NUMBER_OF_ELEMENTS;
+ defparam multibyte_uart_txer.DELAY_WIDTH = DELAY_COUNTER_WIDTH;
+
+
+ localparam RO_MEAS_BITS = 64;
+ localparam AES_BITS = 128;
+
+ localparam RO_EMAS_BYTE = $clog2(RO_MEAS_BITS);
+ localparam CLK_INT_DIV_BITS = 32;
+ localparam CLK_FRC_DIV_BITS = 32;
+
+
+ localparam RO_INST = 32;
+ logic [RO_INST-1:0] ro_en;
+ logic [RO_INST-1:0] ro_out;
+
+ logic [RO_MEAS_BITS-1:0] ro_meas_time;
+
+ logic [AES_BITS-1:0] aes_key;
+ logic [AES_BITS-1:0] aes_ptx;
+ logic [AES_BITS-1:0] aes_ctx;
+ logic [64-1:0] capacitance;
+
+ logic [RO_INST-1:0][RO_MEAS_BITS-1:0] ro_meas_count;
+// logic [RO_MEAS_BITS-1:0] ro_meas_count;
+
+ logic ro_counter_en;
+
+ logic [CLK_INT_DIV_BITS-1:0] div_int;
+ logic [CLK_FRC_DIV_BITS-1:0] div_frac;
+ localparam FF_INST = 4;
+
+ localparam CHAIN_INST = 32;
+ logic [CHAIN_INST-1:0] chain_en;
+
+
+ logic clk_target;
+ logic hult_signal;
+ logic [FF_INST-1:0] ff_write_en;
+ logic [FF_INST-1:0] ff_in;
+ logic [FF_INST-1:0] ff_out;
+
+ logic [8-1:0] ff_id_reg;
+ logic [8-1:0] ff_val_reg;
+
+ logic [8-1:0] ro_id_reg;
+ logic [8-1:0] ro_val_reg;
+
+ logic [8-1:0] chain_id_reg;
+ logic [8-1:0] chain_val_reg;
+
+ logic [16-1:0] temp_reg;
+ logic [16-1:0] vint_reg;
+ logic [16-1:0] vaux_reg;
+
+ initial clk_target <=clk;
+
+// (* S = "TRUE" *) (* KEEP = "TRUE" *) ff_fanout ff[FF_INST-1:0](
+// .clk(clk_target),
+// .CE(ff_write_en),
+// .inp(ff_in),
+// .rst(reg_clk),
+// .res(ff_out)
+// );RO_INST
+
+ (* S = "TRUE" *) (* KEEP = "TRUE" *) ff_fanout ff[FF_INST-1:0](
+ .clk(clk_target),
+ .CE(ff_write_en),
+ .inp(ff_in),
+// .rst(reg_eop),
+ .rst(1'b0),
+ .res(ff_out)
+ );
+
+//Inverter Chain
+
+
+ wire clk_out1;
+ wire locked;
+ wire chain_clk_out;
+ wire chain_freq_out;
+ wire clk_in1;
+
+// assign ro_enable =ro_en;
+ assign clk_in1 = clk;
+ assign gpio = chain_freq_out;
+
+ (* S = "TRUE" *) (* KEEP = "TRUE" *) Chain chain[CHAIN_INST-1:0](
+ .chain_en(chain_en),
+ .in_data(chain_clk_out),
+ .out_data(chain_freq_out)
+ );
+
+
+
+
+
+
+ clock_gen instance_name
+ (
+ // Clock out ports
+ .clk_out1(clk_out1), // output clk_out1
+ // Clock in ports
+ .clk_in1(clk_in1) // input clk_in1
+);
+
+ wire [5 : 0] channel_out;
+ wire eoc_out;
+
+ system_management_wiz_0 temp_sensor (
+ .di_in(16'b0), // input wire [15 : 0] di_in
+ .daddr_in({{2{1'b0}},channel_out}), // input wire [7 : 0] daddr_in
+ .den_in(eoc_out), // input wire den_in
+ .dwe_in(1'b0), // input wire dwe_in
+ .drdy_out(drdy_out), // output wire drdy_out
+ .do_out(temp_reg), // output wire [15 : 0] do_out
+ .dclk_in(clk_in1), // input wire dclk_in
+ .reset_in(1'b0), // input wire reset_in
+ .channel_out(channel_out), // output wire [5 : 0] channel_out
+ .eoc_out(eoc_out), // output wire eoc_out
+ .alarm_out(alarm_out), // output wire alarm_out
+ .eos_out(eos_out), // output wire eos_out
+ .busy_out(busy_out) // output wire busy_out
+);
+
+ wire [5 : 0] channel_out_vint;
+ wire eoc_out_vint;
+ wire alarm_out_1,eos_out_1,busy_out_1,drdy_out_1;
+
+system_management_wiz_1 v_int_sensor (
+ .di_in(16'b0), // input wire [15 : 0] di_in
+ .daddr_in({{2{1'b0}},channel_out_vint}), // input wire [7 : 0] daddr_in
+ .den_in(eoc_out_vint), // input wire den_in
+ .dwe_in(1'b0), // input wire dwe_in
+ .drdy_out(drdy_out_1), // output wire drdy_out
+ .do_out(vint_reg), // output wire [15 : 0] do_out
+ .dclk_in(clk_in1), // input wire dclk_in
+ .reset_in(1'b0), // input wire reset_in
+ .channel_out(channel_out_vint), // output wire [5 : 0] channel_out
+ .eoc_out(eoc_out_vint), // output wire eoc_out
+ .alarm_out(alarm_out_1), // output wire alarm_out
+ .eos_out(eos_out_1), // output wire eos_out
+ .busy_out(busy_out_1) // output wire busy_out
+);
+
+ wire [5 : 0] channel_out_vaux;
+ wire eoc_out_vaux;
+ wire alarm_out_2,eos_out_2,busy_out_2,drdy_out_2;
+
+system_management_wiz_2 v_aux_sensor (
+ .di_in(16'b0), // input wire [15 : 0] di_in
+ .daddr_in({{2{1'b0}},channel_out_vaux}), // input wire [7 : 0] daddr_in
+ .den_in(eoc_out_vaux), // input wire den_in
+ .dwe_in(1'b0), // input wire dwe_in
+ .drdy_out(drdy_out_2), // output wire drdy_out
+ .do_out(vaux_reg), // output wire [15 : 0] do_out
+ .dclk_in(clk_in1), // input wire dclk_in
+ .reset_in(1'b0), // input wire reset_in
+ .channel_out(channel_out_vaux), // output wire [5 : 0] channel_out
+ .eoc_out(eoc_out_vaux), // output wire eoc_out
+ .alarm_out(alarm_out_2), // output wire alarm_out
+ .eos_out(eos_out_2), // output wire eos_out
+ .busy_out(busy_out_2) // output wire busy_out
+);
+
+
+// clock_gen instance_name(
+// // Clock out ports
+// .clk_out1(clk_out1), // output clk_out1
+// // Status and control signals
+// .reset(1'b0), // input reset
+// .locked(locked), // output locked
+// // Clock in ports
+// .clk_in1(clk));
+
+
+ freq_generator freq_gen_inst(
+ .clk_in(clk_out1), // Input clock
+ .reset(1'b0), // Reset signal
+ .div_int(div_int), // Integer part of the division factor
+ .div_frac(div_frac), // Fractional part of the division factor (in fixed-point format, e.g., 0.5 = 32'd50000000)
+ .clk_out(chain_clk_out)
+ );
+
+
+// (* S = "TRUE" *) (* KEEP = "TRUE" *) ff_fanout ff[FF_INST-1:0](
+// .clk(reg_clk),
+// .CE(ff_write_en),
+// .inp(ff_in),
+// .rst(reg_clk),
+// .res(ff_out)
+// );
+
+// (* S = "TRUE" *) (* KEEP = "TRUE" *) ro_fanout RO[RO_INST-1:0](
+// .R_in(ro_en),
+// .R_out(ro_out)
+// );
+
+ (* S = "TRUE" *) (* KEEP = "TRUE" *) ro_core RO[RO_INST-1:0](
+
+ .in_d (ro_en),
+ .wire_inj (ro_out)
+
+ );
+
+
+
+
+ // Instantiate the Unit Under Test (UUT)
+// aes_128 aes_ht_free (
+// .clk(clk),
+// .state(aes_ptx),
+// .key(aes_key),
+// .out(aes_ctx)
+// );
+
+
+
+ // Outputs
+// wire [127:0] out;
+// wire [63:0] Capacitance;
+
+ // Instantiate the Unit Under Test (UUT)
+// top_aes aes_ht(
+// .clk(clk),
+// .rst(1'b0),
+// .state(aes_ptx),
+// .key(aes_key),
+// .out(aes_ctx),
+// .Capacitance(capacitance)
+// );
+
+
+
+
+ (* S = "TRUE" *) (* KEEP = "TRUE" *) ro_sensor #(.width_size(RO_MEAS_BITS)) RO_SENS[RO_INST-1:0] (
+ .ro_meas_time (ro_meas_time),
+ .clk (clk),
+ .r_out (ro_out),
+ .ro_counter_en (ro_counter_en),
+ .ro_meas_count (ro_meas_count)
+ );
+
+// (* S = "TRUE" *) (* KEEP = "TRUE" *) ro_sensor #(.width_size(RO_MEAS_BITS)) RO_SENS (
+// .ro_meas_time (ro_meas_time),
+// .clk (clk),
+// .r_out (ro_out[0]),
+// .ro_counter_en (ro_counter_en),
+// .ro_meas_count (ro_meas_count)
+// );
+
+
+
+
+ assign led_out_ff = ff_out;
+// assign led_out_ff[0] = 1'b1;
+ //assign clk_reg_out = reg_clk;
+
+ typedef enum {
+ STATE_INPUT,
+ STATE_UNHULT_CLK,
+ STATE_HULT_CLK,
+ STATE_SET_FF_VAL,
+ STATE_GET_FF_VAL,
+ STATE_LOCK_VAL,
+ STATE_SET_FF_ID,
+ STATE_GET_FF_ID,
+ //RO STATES
+ STATE_SET_RO_VAL,
+ STATE_GET_RO_VAL,
+ STATE_SET_RO_ID,
+ STATE_GET_RO_ID,
+ STATE_SET_RO_MEAS_TIME,
+ STATE_GET_RO_MEAS_TIME,
+ STATE_GET_MEAS_RO,
+ STATE_EXEC_MEAS_RO,
+ STATE_EXEC_MEAS_RO_POST,
+ //AES STATES
+ STATE_SET_AES_PTX,
+ STATE_GET_AES_PTX,
+ STATE_SET_AES_KEY,
+ STATE_GET_AES_KEY,
+ STATE_GET_AES_CTX,
+ //CHAIN STATES
+ STATE_ACTIVATE_CHAIN,
+ STATE_DEACTIVATE_CHAIN,
+ STATE_SET_CHAIN_FREQ_INT,
+ STATE_GET_CHAIN_FREQ_INT,
+ STATE_SET_CHAIN_FREQ_FRAC,
+ STATE_GET_CHAIN_FREQ_FRAC,
+// STATE_GET_NUMBER_OF_NCS,
+ STATE_SET_GPIO,
+ STATE_UNSET_GPIO,
+ STATE_TRANSITION_INPUT,
+
+ STATE_GET_TEMP_REG,
+ STATE_GET_VINT_REG,
+ STATE_GET_VAUX_REG,
+
+ //STATE CHAIN
+ STATE_SET_CHAIN_VAL,
+ STATE_GET_CHAIN_VAL,
+ STATE_SET_CHAIN_ID,
+ STATE_GET_CHAIN_ID
+
+ } state_t;
+ state_t current_state;
+
+ typedef enum logic[7:0] {
+ CMD_UNHULT_CLK = 7,
+ CMD_HULT_CLK = 8,
+ CMD_SET_FF_VAL = 9,
+ CMD_GET_FF_VAL = 10,
+ CMD_SET_FF_ID = 11,
+ CMD_GET_FF_ID = 12,
+// CMD_GET_NUMBER_OF_NCS = 11,
+ CMD_SET_GPIO = 13,
+ CMD_UNSET_GPIO = 14,
+ CMD_SET_RO_VAL = 15,
+ CMD_GET_RO_VAL = 16,
+ CMD_SET_RO_ID = 17,
+ CMD_GET_RO_ID = 18,
+ CMD_SET_RO_MEAS_TIME = 19,
+ CMD_GET_RO_MEAS_TIME = 20,
+ CMD_GET_MEAS_RO = 21,
+ CMD_EXEC_MEAS_RO = 22,
+ CMD_ACTIVATE_CHAIN = 23,
+ CMD_DEACTIVATE_CHAIN = 24,
+ CMD_SET_CHAIN_FREQ_INT = 25,
+ CMD_GET_CHAIN_FREQ_INT = 26,
+ CMD_SET_CHAIN_FREQ_FRAC = 27,
+ CMD_GET_CHAIN_FREQ_FRAC = 28,
+
+ CMD_SET_AES_PTX = 29,
+ CMD_GET_AES_PTX = 30,
+ CMD_SET_AES_KEY = 31,
+ CMD_GET_AES_KEY = 32,
+ CMD_GET_AES_CTX = 33,
+// CMD_AES_EXEC = 34
+ CMD_GET_TEMP_REG = 34,
+ CMD_GET_VINT_REG = 35,
+ CMD_GET_VAUX_REG = 36,
+
+ CMD_SET_CHAIN_VAL = 37,
+ CMD_GET_CHAIN_VAL = 38,
+ CMD_SET_CHAIN_ID = 39,
+ CMD_GET_CHAIN_ID = 40
+
+ } command_t;
+
+// localparam TRIGGER_ON_DEFAULT = 'h00000010;
+// localparam TRIGGER_OFFSET_DEFAULT = 'h00000010;
+// localparam NUMBER_OF_PULSES_DEFAULT = 'h0CMD_GET_CHAIN_FREQ0000010;
+// localparam PULSE_HIGH_WIDTH_DEFAULT = 'h00000010;
+// localparam PULSE_LOW_WIDTH_DEFAULT = 'h00000010;
+ localparam DELAY_BETWEEN_TX_DEFAULT = 'h00000010;
+
+
+
+
+
+ always@( hult_signal) begin
+ if (hult_signal==1'b1)
+ clk_target<=0;
+ else
+ clk_target<=clk;
+ end
+
+
+ always_ff @(posedge clk) begin
+
+ if (rst) begin
+ current_state <= STATE_INPUT;
+ hult_signal <= 'b0;
+ uart_rx_empty_buffer <= 'b0;
+ delay_between_tx <= DELAY_BETWEEN_TX_DEFAULT;
+ uart_tx_en <= 'b0;
+ for (int i = 0; i < MULTIBYTE_TX_NUMBER_OF_ELEMENTS; i++) begin
+ uart_tx_data[i] <= 'h00;
+ end
+ uart_tx_data_length <= 'd0;
+
+// gpio <= 'b0;
+// gpio_led <= 'd0;
+// trigger_on <= TRIGGER_ON_DEFAULT;
+
+ end else begin
+ current_state <= current_state;
+ uart_rx_empty_buffer <= 'b0;
+ delay_between_tx <= delay_between_tx;
+ uart_tx_en <= 'b0;
+ for (int i = 0; i < MULTIBYTE_TX_NUMBER_OF_ELEMENTS; i++) begin
+ uart_tx_data[i] <= uart_tx_data[i];
+ end
+ uart_tx_data_length <= uart_tx_data_length;
+
+
+ case (current_state)
+ STATE_INPUT: begin
+ if (uart_rx_updated_buffer) begin
+ case (uart_rx_data[uart_rx_data_length-1])
+
+
+ CMD_UNHULT_CLK: begin
+ current_state <= STATE_UNHULT_CLK;
+ end
+
+ CMD_HULT_CLK: begin
+ current_state <= STATE_HULT_CLK;
+ end
+
+ CMD_SET_FF_VAL: begin
+ current_state <= STATE_SET_FF_VAL;
+ uart_rx_empty_buffer <= 'b1;
+ end
+
+ CMD_GET_FF_VAL: begin
+ current_state <= STATE_GET_FF_VAL;
+ end
+
+ CMD_SET_FF_ID: begin
+ current_state <= STATE_SET_FF_ID;
+ uart_rx_empty_buffer <= 'b1;
+ end
+
+ CMD_GET_FF_ID: begin
+ current_state <= STATE_GET_FF_ID;
+ end
+
+
+ //CMD RO
+ CMD_SET_RO_VAL: begin
+ current_state <= STATE_SET_RO_VAL;
+ uart_rx_empty_buffer <= 'b1;
+ end
+
+ CMD_GET_RO_VAL: begin
+ current_state <= STATE_GET_RO_VAL;
+ end
+
+ CMD_SET_RO_ID: begin
+ current_state <= STATE_SET_RO_ID;
+ uart_rx_empty_buffer <= 'b1;
+ end
+
+ CMD_GET_RO_ID: begin
+ current_state <= STATE_GET_RO_ID;
+ end
+
+ //CMD CHAIN
+ CMD_SET_CHAIN_VAL: begin
+ current_state <= STATE_SET_CHAIN_VAL;
+ uart_rx_empty_buffer <= 'b1;
+ end
+
+ CMD_GET_CHAIN_VAL: begin
+ current_state <= STATE_GET_CHAIN_VAL;
+ end
+
+ CMD_SET_CHAIN_ID: begin
+ current_state <= STATE_SET_CHAIN_ID;
+ uart_rx_empty_buffer <= 'b1;
+ end
+
+ CMD_GET_CHAIN_ID: begin
+ current_state <= STATE_GET_CHAIN_ID;
+ end
+
+
+ CMD_SET_RO_MEAS_TIME: begin
+ current_state <= STATE_SET_RO_MEAS_TIME;
+ uart_rx_empty_buffer <= 'b1;
+
+ end
+
+ CMD_GET_RO_MEAS_TIME: begin
+ current_state <= STATE_GET_RO_MEAS_TIME;
+ end
+
+ //CMD SENSORS
+ CMD_GET_TEMP_REG: begin
+ current_state <= STATE_GET_TEMP_REG;
+ end
+
+ CMD_GET_VINT_REG: begin
+ current_state <= STATE_GET_VINT_REG;
+ end
+
+ CMD_GET_VAUX_REG: begin
+ current_state <= STATE_GET_VAUX_REG;
+ end
+
+
+ CMD_GET_MEAS_RO: begin
+ current_state <= STATE_GET_MEAS_RO;
+ end
+
+ CMD_EXEC_MEAS_RO: begin
+ current_state <= STATE_EXEC_MEAS_RO;
+ end
+
+ CMD_ACTIVATE_CHAIN: begin
+ current_state <= STATE_ACTIVATE_CHAIN;
+ end
+
+ CMD_DEACTIVATE_CHAIN: begin
+ current_state <= STATE_DEACTIVATE_CHAIN;
+ end
+
+ CMD_SET_CHAIN_FREQ_INT: begin
+ current_state <= STATE_SET_CHAIN_FREQ_INT;
+ uart_rx_empty_buffer <= 'b1;
+
+ end
+
+ CMD_GET_CHAIN_FREQ_INT: begin
+ current_state <= STATE_GET_CHAIN_FREQ_INT;
+ end
+
+ CMD_SET_CHAIN_FREQ_FRAC: begin
+ current_state <= STATE_SET_CHAIN_FREQ_FRAC;
+ uart_rx_empty_buffer <= 'b1;
+
+ end
+
+ CMD_GET_CHAIN_FREQ_FRAC: begin
+ current_state <= STATE_GET_CHAIN_FREQ_FRAC;
+ end
+
+ //AES CMDs
+
+ CMD_SET_AES_KEY: begin
+ current_state <= STATE_SET_AES_KEY;
+ uart_rx_empty_buffer <= 'b1;
+
+ end
+
+ CMD_GET_AES_KEY: begin
+ current_state <= STATE_GET_AES_KEY;
+ end
+
+ CMD_SET_AES_PTX: begin
+ current_state <= STATE_SET_AES_PTX;
+ uart_rx_empty_buffer <= 'b1;
+
+ end
+
+ CMD_GET_AES_PTX: begin
+ current_state <= STATE_GET_AES_PTX;
+ end
+
+ CMD_GET_AES_CTX: begin
+ current_state <= STATE_GET_AES_CTX;
+ end
+
+
+
+
+
+
+// CMD_GET_NUMBER_OF_NCS: begin
+// current_state <= STATE_GET_NUMBER_OF_NCS;
+// end
+
+ CMD_SET_GPIO: begin
+ current_state <= STATE_SET_GPIO;
+
+ end
+
+ CMD_UNSET_GPIO: begin
+ current_state <= STATE_UNSET_GPIO;
+ end
+
+ default: begin
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ endcase
+ end
+ end
+
+
+
+ STATE_UNHULT_CLK: begin
+ hult_signal <=0;
+ current_state <= STATE_TRANSITION_INPUT;
+
+ end
+
+
+
+ STATE_HULT_CLK: begin
+ hult_signal <=1;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+
+
+
+
+
+ STATE_SET_FF_ID: begin
+ if (uart_rx_updated_buffer) begin
+ if (uart_rx_data_length >= 'd1) begin
+ ff_id_reg <= uart_rx_data[0];
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+ end
+
+
+ STATE_GET_FF_ID: begin
+ if (uart_tx_ready) begin
+// uart_tx_data[3] <= trigger_offset[7:0];
+// uart_tx_data[2] <= trigger_offset[15:8];
+// uart_tx_data[1] <= trigger_offset[23:16];
+ uart_tx_data[0] <= ff_id_reg;
+ uart_tx_data_length <= 'd1;
+ uart_tx_en <= 'b1;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+ //STATE SENSORS
+
+
+ STATE_GET_TEMP_REG: begin
+ if (uart_tx_ready) begin
+ uart_tx_data[1] <= temp_reg[7:0];
+ uart_tx_data[0] <= temp_reg[15:8];
+ uart_tx_data_length <= 'd2;
+ uart_tx_en <= 'b1;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+
+
+ STATE_GET_VINT_REG: begin
+ if (uart_tx_ready) begin
+ uart_tx_data[1] <= vint_reg[7:0];
+ uart_tx_data[0] <= vint_reg[15:8];
+ uart_tx_data_length <= 'd2;
+ uart_tx_en <= 'b1;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+
+ STATE_GET_VAUX_REG: begin
+ if (uart_tx_ready) begin
+ uart_tx_data[1] <= vaux_reg[7:0];
+ uart_tx_data[0] <= vaux_reg[15:8];
+ uart_tx_data_length <= 'd2;
+ uart_tx_en <= 'b1;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+
+ STATE_SET_FF_VAL: begin
+ if (uart_rx_updated_buffer) begin
+ if (uart_rx_data_length >= 'd1) begin
+ ff_in[ff_id_reg] <= uart_rx_data[0]&1;
+ ff_write_en[ff_id_reg]<=1;
+ current_state <= STATE_LOCK_VAL;
+ end
+ end
+ end
+
+
+
+ STATE_SET_RO_MEAS_TIME: begin
+ if (uart_rx_updated_buffer) begin
+ if (uart_rx_data_length >= 'd8) begin
+ ro_meas_time[7:0] <= uart_rx_data[7];// data comes in big endian
+ ro_meas_time[15:8] <= uart_rx_data[6];
+ ro_meas_time[23:16] <= uart_rx_data[5];
+ ro_meas_time[31:24] <= uart_rx_data[4];
+ ro_meas_time[39:32] <= uart_rx_data[3];
+ ro_meas_time[47:40] <= uart_rx_data[2];
+ ro_meas_time[55:48] <= uart_rx_data[1];
+ ro_meas_time[63:56] <= uart_rx_data[0];
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+ end
+
+ STATE_GET_RO_MEAS_TIME: begin
+ if (uart_tx_ready) begin
+ uart_tx_data[7]<= ro_meas_time[7:0]; // data comes in big endian
+ uart_tx_data[6]<=ro_meas_time[15:8] ;
+ uart_tx_data[5]<=ro_meas_time[23:16];
+ uart_tx_data[4]<=ro_meas_time[31:24];
+ uart_tx_data[3]<=ro_meas_time[39:32];
+ uart_tx_data[2]<=ro_meas_time[47:40];
+ uart_tx_data[1]<=ro_meas_time[55:48];
+ uart_tx_data[0]<=ro_meas_time[63:56];
+ uart_tx_data_length <= 'd8;
+ uart_tx_en <= 'b1;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+
+
+ //AES STATES
+ STATE_SET_AES_PTX: begin
+ if (uart_rx_updated_buffer) begin
+ if (uart_rx_data_length >= 'd16) begin
+ aes_ptx[7:0] <= uart_rx_data[15];// data comes in big endian
+ aes_ptx[15:8] <= uart_rx_data[14];
+ aes_ptx[23:16] <= uart_rx_data[13];
+ aes_ptx[31:24] <= uart_rx_data[12];
+ aes_ptx[39:32] <= uart_rx_data[11];
+ aes_ptx[47:40] <= uart_rx_data[10];
+ aes_ptx[55:48] <= uart_rx_data[9];
+ aes_ptx[63:56] <= uart_rx_data[8];
+ aes_ptx[71:64] <= uart_rx_data[7];// data comes in big endian
+ aes_ptx[79:72] <= uart_rx_data[6];
+ aes_ptx[87:80] <= uart_rx_data[5];
+ aes_ptx[95:88] <= uart_rx_data[4];
+ aes_ptx[103:96] <= uart_rx_data[3];
+ aes_ptx[111:104] <= uart_rx_data[2];
+ aes_ptx[119:112] <= uart_rx_data[1];
+ aes_ptx[127:120] <= uart_rx_data[0];
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+ end
+
+
+ STATE_GET_AES_PTX: begin
+ if (uart_tx_ready) begin
+ uart_tx_data[15]<= aes_ptx[7:0]; // data comes in big endian
+ uart_tx_data[14]<=aes_ptx[15:8] ;
+ uart_tx_data[13]<=aes_ptx[23:16];
+ uart_tx_data[12]<=aes_ptx[31:24];
+ uart_tx_data[11]<=aes_ptx[39:32];
+ uart_tx_data[10]<=aes_ptx[47:40];
+ uart_tx_data[9]<=aes_ptx[55:48];
+ uart_tx_data[8]<=aes_ptx[63:56];
+ uart_tx_data[7]<= aes_ptx[71:64]; // data comes in big endian
+ uart_tx_data[6]<=aes_ptx[79:72] ;
+ uart_tx_data[5]<=aes_ptx[87:80];
+ uart_tx_data[4]<=aes_ptx[95:88];
+ uart_tx_data[3]<=aes_ptx[103:96];
+ uart_tx_data[2]<=aes_ptx[111:104];
+ uart_tx_data[1]<=aes_ptx[119:112];
+ uart_tx_data[0]<=aes_ptx[127:120];
+ uart_tx_data_length <= 'd16;
+ uart_tx_en <= 'b1;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+
+ STATE_SET_AES_KEY: begin
+ if (uart_rx_updated_buffer) begin
+ if (uart_rx_data_length >= 'd16) begin
+ aes_key[7:0] <= uart_rx_data[15];// data comes in big endian
+ aes_key[15:8] <= uart_rx_data[14];
+ aes_key[23:16] <= uart_rx_data[13];
+ aes_key[31:24] <= uart_rx_data[12];
+ aes_key[39:32] <= uart_rx_data[11];
+ aes_key[47:40] <= uart_rx_data[10];
+ aes_key[55:48] <= uart_rx_data[9];
+ aes_key[63:56] <= uart_rx_data[8];
+ aes_key[71:64] <= uart_rx_data[7];// data comes in big endian
+ aes_key[79:72] <= uart_rx_data[6];
+ aes_key[87:80] <= uart_rx_data[5];
+ aes_key[95:88] <= uart_rx_data[4];
+ aes_key[103:96] <= uart_rx_data[3];
+ aes_key[111:104] <= uart_rx_data[2];
+ aes_key[119:112] <= uart_rx_data[1];
+ aes_key[127:120] <= uart_rx_data[0];
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+ end
+
+
+ STATE_GET_AES_KEY: begin
+ if (uart_tx_ready) begin
+ uart_tx_data[15]<= aes_key[7:0]; // data comes in big endian
+ uart_tx_data[14]<=aes_key[15:8] ;
+ uart_tx_data[13]<=aes_key[23:16];
+ uart_tx_data[12]<=aes_key[31:24];
+ uart_tx_data[11]<=aes_key[39:32];
+ uart_tx_data[10]<=aes_key[47:40];
+ uart_tx_data[9]<=aes_key[55:48];
+ uart_tx_data[8]<=aes_key[63:56];
+ uart_tx_data[7]<= aes_key[71:64]; // data comes in big endian
+ uart_tx_data[6]<=aes_key[79:72] ;
+ uart_tx_data[5]<=aes_key[87:80];
+ uart_tx_data[4]<=aes_key[95:88];
+ uart_tx_data[3]<=aes_key[103:96];
+ uart_tx_data[2]<=aes_key[111:104];
+ uart_tx_data[1]<=aes_key[119:112];
+ uart_tx_data[0]<=aes_key[127:120];
+ uart_tx_data_length <= 'd16;
+ uart_tx_en <= 'b1;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+
+
+ STATE_GET_AES_CTX: begin
+ if (uart_tx_ready) begin
+ uart_tx_data[15]<= aes_ctx[7:0]; // data comes in big endian
+ uart_tx_data[14]<=aes_ctx[15:8] ;
+ uart_tx_data[13]<=aes_ctx[23:16];
+ uart_tx_data[12]<=aes_ctx[31:24];
+ uart_tx_data[11]<=aes_ctx[39:32];
+ uart_tx_data[10]<=aes_ctx[47:40];
+ uart_tx_data[9]<=aes_ctx[55:48];
+ uart_tx_data[8]<=aes_ctx[63:56];
+ uart_tx_data[7]<= aes_ctx[71:64]; // data comes in big endian
+ uart_tx_data[6]<=aes_ctx[79:72] ;
+ uart_tx_data[5]<=aes_ctx[87:80];
+ uart_tx_data[4]<=aes_ctx[95:88];
+ uart_tx_data[3]<=aes_ctx[103:96];
+ uart_tx_data[2]<=aes_ctx[111:104];
+ uart_tx_data[1]<=aes_ctx[119:112];
+ uart_tx_data[0]<=aes_ctx[127:120];
+ uart_tx_data_length <= 'd16;
+ uart_tx_en <= 'b1;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+
+
+
+
+
+ STATE_EXEC_MEAS_RO: begin
+ ro_counter_en <= 1'b1;
+ current_state <= STATE_EXEC_MEAS_RO_POST;
+
+ end
+ STATE_EXEC_MEAS_RO_POST: begin
+ ro_counter_en <= 1'b0;
+ current_state <= STATE_TRANSITION_INPUT;
+
+ end
+
+
+ STATE_GET_MEAS_RO: begin
+ if (uart_tx_ready) begin
+ uart_tx_data[7]<= ro_meas_count[ro_id_reg][7:0]; // data comes in big endian
+ uart_tx_data[6]<=ro_meas_count[ro_id_reg][15:8] ;
+ uart_tx_data[5]<=ro_meas_count[ro_id_reg][23:16];
+ uart_tx_data[4]<=ro_meas_count[ro_id_reg][31:24];
+ uart_tx_data[3]<=ro_meas_count[ro_id_reg][39:32];
+ uart_tx_data[2]<=ro_meas_count[ro_id_reg][47:40];
+ uart_tx_data[1]<=ro_meas_count[ro_id_reg][55:48];
+ uart_tx_data[0]<=ro_meas_count[ro_id_reg][63:56];
+ uart_tx_data_length <= 'd8;
+ uart_tx_en <= 'b1;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+
+
+// STATE_GET_MEAS_RO: begin
+// if (uart_tx_ready) begin
+// uart_tx_data[7]<= ro_meas_count[7:0]; // data comes in big endian
+// uart_tx_data[6]<=ro_meas_count[15:8] ;
+// uart_tx_data[5]<=ro_meas_count[23:16];
+// uart_tx_data[4]<=ro_meas_count[31:24];
+// uart_tx_data[3]<=ro_meas_count[39:32];
+// uart_tx_data[2]<=ro_meas_count[47:40];
+// uart_tx_data[1]<=ro_meas_count[55:48];
+// uart_tx_data[0]<=ro_meas_count[63:56];
+// uart_tx_data_length <= 'd8;
+// uart_tx_en <= 'b1;
+// current_state <= STATE_TRANSITION_INPUT;
+// end
+// end
+
+ STATE_ACTIVATE_CHAIN :begin
+
+// chain_en<='b1;
+ current_state <= STATE_TRANSITION_INPUT;
+
+ end
+
+
+ STATE_DEACTIVATE_CHAIN :begin
+
+// chain_en<='b0;
+ current_state <= STATE_TRANSITION_INPUT;
+
+ end
+
+
+ STATE_SET_CHAIN_FREQ_INT: begin
+ if (uart_rx_updated_buffer) begin
+ if (uart_rx_data_length >= 'd4) begin
+ div_int[7:0] <= uart_rx_data[3];// data comes in big endian
+ div_int[15:8] <= uart_rx_data[2];
+ div_int[23:16] <= uart_rx_data[1];
+ div_int[31:24] <= uart_rx_data[0];
+
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+ end
+
+ STATE_GET_CHAIN_FREQ_INT: begin
+ if (uart_tx_ready) begin
+ uart_tx_data[3]<= div_int[7:0]; // data comes in big endian
+ uart_tx_data[2]<=div_int[15:8] ;
+ uart_tx_data[1]<=div_int[23:16];
+ uart_tx_data[0]<=div_int[31:24];
+
+ uart_tx_data_length <= 'd4;
+ uart_tx_en <= 'b1;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+
+
+
+ STATE_SET_CHAIN_FREQ_FRAC: begin
+ if (uart_rx_updated_buffer) begin
+ if (uart_rx_data_length >= 'd4) begin
+ div_frac[7:0] <= uart_rx_data[3];// data comes in big endian
+ div_frac[15:8] <= uart_rx_data[2];
+ div_frac[23:16] <= uart_rx_data[1];
+ div_frac[31:24] <= uart_rx_data[0];
+
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+ end
+
+ STATE_GET_CHAIN_FREQ_FRAC: begin
+ if (uart_tx_ready) begin
+ uart_tx_data[3]<= div_frac[7:0]; // data comes in big endian
+ uart_tx_data[2]<=div_frac[15:8] ;
+ uart_tx_data[1]<=div_frac[23:16];
+ uart_tx_data[0]<=div_frac[31:24];
+
+ uart_tx_data_length <= 'd4;
+ uart_tx_en <= 'b1;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+
+
+
+
+ STATE_LOCK_VAL: begin
+
+ ff_write_en[ff_id_reg]<=0;
+ current_state <= STATE_TRANSITION_INPUT;
+
+ end
+
+
+
+
+ STATE_GET_FF_VAL: begin
+
+ if (uart_tx_ready) begin
+ uart_tx_data[0] <= {8{ff_in[ff_id_reg]}};
+ uart_tx_data_length <= 'd1;
+ uart_tx_en <= 'b1;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+
+
+// STATE_GET_NUMBER_OF_NCS: begin
+// if (uart_tx_ready) begin
+// uart_tx_data[3] <= number_of_ncs[7:0];
+// uart_tx_data[2] <= number_of_ncs[15:8];
+// uart_tx_data[1] <= number_of_ncs[23:16];
+// uart_tx_data[0] <= number_of_ncs[31:24];
+// uart_tx_data_length <= 'd4;
+// uart_tx_en <= 'b1;
+// current_state <= STATE_TRANSITION_INPUT;
+// end
+// end
+
+ STATE_SET_GPIO: begin
+ // gpio <= 'b1;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+
+
+
+ STATE_SET_RO_ID: begin
+ if (uart_rx_updated_buffer) begin
+ if (uart_rx_data_length >= 'd1) begin
+ ro_id_reg <= uart_rx_data[0];
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+ end
+
+
+ STATE_GET_RO_ID: begin
+ if (uart_tx_ready) begin
+// uart_tx_data[3] <= trigger_offset[7:0];
+// uart_tx_data[2] <= trigger_offset[15:8];
+// uart_tx_data[1] <= trigger_offset[23:16];
+ uart_tx_data[0] <= ro_id_reg;
+ uart_tx_data_length <= 'd1;
+ uart_tx_en <= 'b1;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+
+ STATE_SET_RO_VAL: begin
+ if (uart_rx_updated_buffer) begin
+ if (uart_rx_data_length >= 'd1) begin
+ ro_en[ro_id_reg] <= uart_rx_data[0]&1;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+ end
+
+
+
+
+ STATE_GET_RO_VAL: begin
+ if (uart_tx_ready) begin
+ uart_tx_data[0] <= {8{ro_en[ro_id_reg]}};
+ uart_tx_data_length <= 'd1;
+ uart_tx_en <= 'b1;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+
+ // CHAIN ID/VAL States
+
+ STATE_SET_CHAIN_ID: begin
+ if (uart_rx_updated_buffer) begin
+ if (uart_rx_data_length >= 'd1) begin
+ chain_id_reg <= uart_rx_data[0];
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+ end
+
+
+ STATE_GET_CHAIN_ID: begin
+ if (uart_tx_ready) begin
+// uart_tx_data[3] <= trigger_offset[7:0];
+// uart_tx_data[2] <= trigger_offset[15:8];
+// uart_tx_data[1] <= trigger_offset[23:16];
+ uart_tx_data[0] <= chain_id_reg;
+ uart_tx_data_length <= 'd1;
+ uart_tx_en <= 'b1;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+
+ STATE_SET_CHAIN_VAL: begin
+ if (uart_rx_updated_buffer) begin
+ if (uart_rx_data_length >= 'd1) begin
+ chain_en[chain_id_reg] <= uart_rx_data[0]&1;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+ end
+
+
+
+
+ STATE_GET_CHAIN_VAL: begin
+ if (uart_tx_ready) begin
+ uart_tx_data[0] <= {8{chain_en[chain_id_reg]}};
+ uart_tx_data_length <= 'd1;
+ uart_tx_en <= 'b1;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+ end
+
+
+
+
+
+ STATE_UNSET_GPIO: begin
+ // gpio <= 'b0;
+ current_state <= STATE_TRANSITION_INPUT;
+ end
+
+ STATE_TRANSITION_INPUT: begin
+ uart_rx_empty_buffer <= 'b1;
+ current_state <= STATE_INPUT;
+ end
+ endcase
+ end
+ end
+endmodule
\ No newline at end of file
diff --git a/hwdbg/src/main/systemverilog/sensors/src/uart_rx.sv b/hwdbg/src/main/systemverilog/sensors/src/uart_rx.sv
new file mode 100644
index 00000000..a54364b4
--- /dev/null
+++ b/hwdbg/src/main/systemverilog/sensors/src/uart_rx.sv
@@ -0,0 +1,99 @@
+module uart_rx
+#(
+ parameter SYSTEMCLOCK = 100_000_000,
+ parameter BAUDRATE = 115_200,
+ parameter ELEMENT_WIDTH = 8,
+ localparam ELEMENT_BIT_COUNTER_WIDTH = $clog2(ELEMENT_WIDTH),
+ localparam CLOCK_COUNTER_WIDTH = 32,
+ localparam CLOCKS_PER_BAUD = SYSTEMCLOCK / BAUDRATE
+)(
+ input logic clk,
+ input logic rst,
+ input logic rx_line,
+ output logic [ELEMENT_WIDTH-1:0] rx_data,
+ output logic rx_data_valid
+);
+
+ typedef enum {
+ STATE_IDLE,
+ STATE_START_BIT,
+ STATE_RECEIVE_ELEMENT,
+ STATE_CHECK_ELEMENT_RECEIVED,
+ STATE_STOP_BIT,
+ STATE_DONE
+ } state_t;
+ state_t current_state;
+
+ logic [ELEMENT_BIT_COUNTER_WIDTH:0] current_bit;
+ logic [CLOCK_COUNTER_WIDTH-1:0] clock_counter;
+ logic clocks_per_baud_reached;
+ logic half_clocks_per_baud_reached;
+
+ assign clocks_per_baud_reached = (clock_counter >= CLOCKS_PER_BAUD);
+ assign half_clocks_per_baud_reached = (clock_counter >= (CLOCKS_PER_BAUD / 2));
+ assign rx_data = rx_data;
+ assign rx_data_valid = current_state == STATE_DONE;
+
+ always_ff @(posedge clk) begin
+ if (rst) begin
+ current_state <= STATE_IDLE;
+ current_bit <= 'b0;
+ rx_data <= 'b0;
+ clock_counter <= 'd0;
+
+ end else begin
+ current_state <= current_state;
+ current_bit <= current_bit;
+ rx_data <= rx_data;
+ clock_counter <= clock_counter + 1;
+
+ case (current_state)
+
+ STATE_IDLE: begin
+ if (rx_line == 'b0) begin
+ current_state <= STATE_START_BIT;
+ clock_counter <= 'b0;
+ end
+ end
+
+ STATE_START_BIT: begin
+ if (half_clocks_per_baud_reached) begin
+ current_state <= STATE_RECEIVE_ELEMENT;
+ clock_counter <= 'b0;
+ current_bit <= 'b0;
+ end
+ end
+
+ STATE_RECEIVE_ELEMENT: begin
+ if (clocks_per_baud_reached) begin
+ rx_data[current_bit] <= rx_line;
+ current_bit <= current_bit + 1;
+ clock_counter <= 'd0;
+ current_state <= STATE_CHECK_ELEMENT_RECEIVED;
+ end
+ end
+
+ STATE_CHECK_ELEMENT_RECEIVED: begin
+ if (current_bit >= ELEMENT_WIDTH) begin
+ current_state <= STATE_STOP_BIT;
+ end else begin
+ current_state <= STATE_RECEIVE_ELEMENT;
+ end
+ end
+
+ STATE_STOP_BIT: begin
+ if (clocks_per_baud_reached) begin
+ current_state <= STATE_DONE;
+ clock_counter <= 'd0;
+ end
+ end
+
+ STATE_DONE: begin
+ current_state <= STATE_IDLE;
+ end
+
+ endcase
+ end
+ end
+
+endmodule
\ No newline at end of file
diff --git a/hwdbg/src/main/systemverilog/sensors/src/uart_tx.sv b/hwdbg/src/main/systemverilog/sensors/src/uart_tx.sv
new file mode 100644
index 00000000..a5f4a7e3
--- /dev/null
+++ b/hwdbg/src/main/systemverilog/sensors/src/uart_tx.sv
@@ -0,0 +1,104 @@
+module uart_tx
+#(
+ parameter SYSTEMCLOCK = 100_000_000,
+ parameter BAUDRATE = 115_200,
+ parameter ELEMENT_WIDTH = 8,
+ localparam ELEMENT_BIT_COUNTER_WIDTH = $clog2(ELEMENT_WIDTH),
+ localparam CLOCK_COUNTER_WIDTH = 32,
+ localparam CLOCKS_PER_BAUD = SYSTEMCLOCK / BAUDRATE
+)(
+ input logic clk,
+ input logic rst,
+ input logic tx_en,
+ input logic [ELEMENT_WIDTH-1:0] tx_data,
+ output logic tx_line,
+ output logic tx_ready
+);
+
+ typedef enum {
+ STATE_IDLE,
+ STATE_START_BIT,
+ STATE_TRANSFER_ELEMENT,
+ STATE_CHECK_ELEMENT_TRANSFERRED,
+ STATE_STOP_BIT,
+ STATE_DONE
+ } state_t;
+ state_t current_state;
+
+ logic [ELEMENT_BIT_COUNTER_WIDTH:0] bit_counter = 'b0;
+ logic [CLOCK_COUNTER_WIDTH:0] clock_counter = 'b0;
+
+ logic clocks_per_baud_reached;
+ assign clocks_per_baud_reached = (clock_counter >= CLOCKS_PER_BAUD);
+
+ always @(posedge clk) begin
+
+ if (rst) begin
+ current_state <= STATE_IDLE;
+ bit_counter <= 'd0;
+ clock_counter <= 'd0;
+ tx_line <= 'b1;
+ tx_ready <= 'b0;
+
+ end else begin
+
+ clock_counter <= clock_counter + 1;
+ current_state <= current_state;
+ bit_counter <= bit_counter;
+ tx_line <= tx_line;
+ tx_ready <= tx_ready;
+
+ case (current_state)
+
+ STATE_IDLE: begin
+ if (tx_en) begin
+ current_state <= STATE_START_BIT;
+ tx_line <= 'b0;
+ tx_ready <= 'b0;
+ end else begin
+ tx_line <= 'b1;
+ tx_ready <= 'b1;
+ end
+ end
+
+ STATE_START_BIT: begin
+ current_state <= STATE_TRANSFER_ELEMENT;
+ bit_counter <= 'd0;
+ clock_counter <= 'd0;
+ end
+
+ STATE_TRANSFER_ELEMENT: begin
+ if(clocks_per_baud_reached) begin
+ clock_counter <= 'b0;
+ tx_line <= tx_data[bit_counter];
+ bit_counter <= bit_counter + 1;
+ current_state <= STATE_CHECK_ELEMENT_TRANSFERRED;
+ end
+ end
+
+ STATE_CHECK_ELEMENT_TRANSFERRED: begin
+ if (bit_counter >= ELEMENT_WIDTH) begin
+ current_state <= STATE_STOP_BIT;
+ end else begin
+ current_state <= STATE_TRANSFER_ELEMENT;
+ end
+ end
+
+ STATE_STOP_BIT: begin
+ if(clocks_per_baud_reached) begin
+ tx_line <= 'b1;
+ clock_counter <= 'd0;
+ current_state <= STATE_DONE;
+ end
+ end
+
+ STATE_DONE: begin
+ if (clocks_per_baud_reached) begin
+ tx_ready <= 'b1;
+ current_state <= STATE_IDLE;
+ end
+ end
+ endcase
+ end
+ end
+endmodule
\ No newline at end of file
diff --git a/hwdbg/src/test/bram/instance_info.hex.txt b/hwdbg/src/test/bram/instance_info.hex.txt
new file mode 100644
index 00000000..7c72056c
--- /dev/null
+++ b/hwdbg/src/test/bram/instance_info.hex.txt
@@ -0,0 +1,256 @@
+0000005a ; +0x0 | Checksum
+00000000 ; +0x4 | Checksum
+52444247 ; +0x8 | Indicator
+48595045 ; +0xc | Indicator
+00000004 ; +0x10 | TypeOfThePacket - DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL (0x4)
+00000001 ; +0x14 | RequestedActionOfThePacket - Value (0x1)
+00000000 ; +0x18
+00000000 ; +0x1c
+00000000 ; +0x20
+00000000 ; +0x24
+00000000 ; +0x28
+00000000 ; +0x2c
+00000000 ; +0x30
+00000000 ; +0x34
+00000000 ; +0x38
+00000000 ; +0x3c
+00000000 ; +0x40
+00000000 ; +0x44
+00000000 ; +0x48
+00000000 ; +0x4c
+00000000 ; +0x50
+00000000 ; +0x54
+00000000 ; +0x58
+00000000 ; +0x5c
+00000000 ; +0x60
+00000000 ; +0x64
+00000000 ; +0x68
+00000000 ; +0x6c
+00000000 ; +0x70
+00000000 ; +0x74
+00000000 ; +0x78
+00000000 ; +0x7c
+00000000 ; +0x80
+00000000 ; +0x84
+00000000 ; +0x88
+00000000 ; +0x8c
+00000000 ; +0x90
+00000000 ; +0x94
+00000000 ; +0x98
+00000000 ; +0x9c
+00000000 ; +0xa0
+00000000 ; +0xa4
+00000000 ; +0xa8
+00000000 ; +0xac
+00000000 ; +0xb0
+00000000 ; +0xb4
+00000000 ; +0xb8
+00000000 ; +0xbc
+00000000 ; +0xc0
+00000000 ; +0xc4
+00000000 ; +0xc8
+00000000 ; +0xcc
+00000000 ; +0xd0
+00000000 ; +0xd4
+00000000 ; +0xd8
+00000000 ; +0xdc
+00000000 ; +0xe0
+00000000 ; +0xe4
+00000000 ; +0xe8
+00000000 ; +0xec
+00000000 ; +0xf0
+00000000 ; +0xf4
+00000000 ; +0xf8
+00000000 ; +0xfc
+00000000 ; +0x100
+00000000 ; +0x104
+00000000 ; +0x108
+00000000 ; +0x10c
+00000000 ; +0x110
+00000000 ; +0x114
+00000000 ; +0x118
+00000000 ; +0x11c
+00000000 ; +0x120
+00000000 ; +0x124
+00000000 ; +0x128
+00000000 ; +0x12c
+00000000 ; +0x130
+00000000 ; +0x134
+00000000 ; +0x138
+00000000 ; +0x13c
+00000000 ; +0x140
+00000000 ; +0x144
+00000000 ; +0x148
+00000000 ; +0x14c
+00000000 ; +0x150
+00000000 ; +0x154
+00000000 ; +0x158
+00000000 ; +0x15c
+00000000 ; +0x160
+00000000 ; +0x164
+00000000 ; +0x168
+00000000 ; +0x16c
+00000000 ; +0x170
+00000000 ; +0x174
+00000000 ; +0x178
+00000000 ; +0x17c
+00000000 ; +0x180
+00000000 ; +0x184
+00000000 ; +0x188
+00000000 ; +0x18c
+00000000 ; +0x190
+00000000 ; +0x194
+00000000 ; +0x198
+00000000 ; +0x19c
+00000000 ; +0x1a0
+00000000 ; +0x1a4
+00000000 ; +0x1a8
+00000000 ; +0x1ac
+00000000 ; +0x1b0
+00000000 ; +0x1b4
+00000000 ; +0x1b8
+00000000 ; +0x1bc
+00000000 ; +0x1c0
+00000000 ; +0x1c4
+00000000 ; +0x1c8
+00000000 ; +0x1cc
+00000000 ; +0x1d0
+00000000 ; +0x1d4
+00000000 ; +0x1d8
+00000000 ; +0x1dc
+00000000 ; +0x1e0
+00000000 ; +0x1e4
+00000000 ; +0x1e8
+00000000 ; +0x1ec
+00000000 ; +0x1f0
+00000000 ; +0x1f4
+00000000 ; +0x1f8
+00000000 ; +0x1fc
+00000000 ; +0x200
+00000000 ; +0x204
+00000000 ; +0x208
+00000000 ; +0x20c
+00000000 ; +0x210
+00000000 ; +0x214
+00000000 ; +0x218
+00000000 ; +0x21c
+00000000 ; +0x220
+00000000 ; +0x224
+00000000 ; +0x228
+00000000 ; +0x22c
+00000000 ; +0x230
+00000000 ; +0x234
+00000000 ; +0x238
+00000000 ; +0x23c
+00000000 ; +0x240
+00000000 ; +0x244
+00000000 ; +0x248
+00000000 ; +0x24c
+00000000 ; +0x250
+00000000 ; +0x254
+00000000 ; +0x258
+00000000 ; +0x25c
+00000000 ; +0x260
+00000000 ; +0x264
+00000000 ; +0x268
+00000000 ; +0x26c
+00000000 ; +0x270
+00000000 ; +0x274
+00000000 ; +0x278
+00000000 ; +0x27c
+00000000 ; +0x280
+00000000 ; +0x284
+00000000 ; +0x288
+00000000 ; +0x28c
+00000000 ; +0x290
+00000000 ; +0x294
+00000000 ; +0x298
+00000000 ; +0x29c
+00000000 ; +0x2a0
+00000000 ; +0x2a4
+00000000 ; +0x2a8
+00000000 ; +0x2ac
+00000000 ; +0x2b0
+00000000 ; +0x2b4
+00000000 ; +0x2b8
+00000000 ; +0x2bc
+00000000 ; +0x2c0
+00000000 ; +0x2c4
+00000000 ; +0x2c8
+00000000 ; +0x2cc
+00000000 ; +0x2d0
+00000000 ; +0x2d4
+00000000 ; +0x2d8
+00000000 ; +0x2dc
+00000000 ; +0x2e0
+00000000 ; +0x2e4
+00000000 ; +0x2e8
+00000000 ; +0x2ec
+00000000 ; +0x2f0
+00000000 ; +0x2f4
+00000000 ; +0x2f8
+00000000 ; +0x2fc
+00000000 ; +0x300
+00000000 ; +0x304
+00000000 ; +0x308
+00000000 ; +0x30c
+00000000 ; +0x310
+00000000 ; +0x314
+00000000 ; +0x318
+00000000 ; +0x31c
+00000000 ; +0x320
+00000000 ; +0x324
+00000000 ; +0x328
+00000000 ; +0x32c
+00000000 ; +0x330
+00000000 ; +0x334
+00000000 ; +0x338
+00000000 ; +0x33c
+00000000 ; +0x340
+00000000 ; +0x344
+00000000 ; +0x348
+00000000 ; +0x34c
+00000000 ; +0x350
+00000000 ; +0x354
+00000000 ; +0x358
+00000000 ; +0x35c
+00000000 ; +0x360
+00000000 ; +0x364
+00000000 ; +0x368
+00000000 ; +0x36c
+00000000 ; +0x370
+00000000 ; +0x374
+00000000 ; +0x378
+00000000 ; +0x37c
+00000000 ; +0x380
+00000000 ; +0x384
+00000000 ; +0x388
+00000000 ; +0x38c
+00000000 ; +0x390
+00000000 ; +0x394
+00000000 ; +0x398
+00000000 ; +0x39c
+00000000 ; +0x3a0
+00000000 ; +0x3a4
+00000000 ; +0x3a8
+00000000 ; +0x3ac
+00000000 ; +0x3b0
+00000000 ; +0x3b4
+00000000 ; +0x3b8
+00000000 ; +0x3bc
+00000000 ; +0x3c0
+00000000 ; +0x3c4
+00000000 ; +0x3c8
+00000000 ; +0x3cc
+00000000 ; +0x3d0
+00000000 ; +0x3d4
+00000000 ; +0x3d8
+00000000 ; +0x3dc
+00000000 ; +0x3e0
+00000000 ; +0x3e4
+00000000 ; +0x3e8
+00000000 ; +0x3ec
+00000000 ; +0x3f0
+00000000 ; +0x3f4
+00000000 ; +0x3f8
+00000000 ; +0x3fc
\ No newline at end of file
diff --git a/hwdbg/src/test/bram/script_buffer.hex.txt b/hwdbg/src/test/bram/script_buffer.hex.txt
new file mode 100644
index 00000000..73e93432
--- /dev/null
+++ b/hwdbg/src/test/bram/script_buffer.hex.txt
@@ -0,0 +1,256 @@
+000000b9 ; +0x0 | Checksum
+00000000 ; +0x4 | Checksum
+52444247 ; +0x8 | Indicator
+48595045 ; +0xc | Indicator
+00000004 ; +0x10 | TypeOfThePacket - DEBUGGER_TO_DEBUGGEE_HARDWARE_LEVEL (0x4)
+00000002 ; +0x14 | RequestedActionOfThePacket - Value (0x2)
+00000007 ; +0x18 | Start of Optional Data
+00000006 ; +0x1c
+0000000a ; +0x20
+00000003 ; +0x24
+00000000 ; +0x28
+0000000f ; +0x2c
+00000000 ; +0x30
+0000000f ; +0x34
+00000000 ; +0x38
+00000006 ; +0x3c
+00000018 ; +0x40
+00000003 ; +0x44
+00000001 ; +0x48
+00000000 ; +0x4c
+00000000 ; +0x50
+00000004 ; +0x54
+00000000 ; +0x58
+00000000 ; +0x5c
+00000000 ; +0x60
+00000000 ; +0x64
+00000000 ; +0x68
+00000000 ; +0x6c
+00000000 ; +0x70
+00000000 ; +0x74
+00000000 ; +0x78
+00000000 ; +0x7c
+00000000 ; +0x80
+00000000 ; +0x84
+00000000 ; +0x88
+00000000 ; +0x8c
+00000000 ; +0x90
+00000000 ; +0x94
+00000000 ; +0x98
+00000000 ; +0x9c
+00000000 ; +0xa0
+00000000 ; +0xa4
+00000000 ; +0xa8
+00000000 ; +0xac
+00000000 ; +0xb0
+00000000 ; +0xb4
+00000000 ; +0xb8
+00000000 ; +0xbc
+00000000 ; +0xc0
+00000000 ; +0xc4
+00000000 ; +0xc8
+00000000 ; +0xcc
+00000000 ; +0xd0
+00000000 ; +0xd4
+00000000 ; +0xd8
+00000000 ; +0xdc
+00000000 ; +0xe0
+00000000 ; +0xe4
+00000000 ; +0xe8
+00000000 ; +0xec
+00000000 ; +0xf0
+00000000 ; +0xf4
+00000000 ; +0xf8
+00000000 ; +0xfc
+00000000 ; +0x100
+00000000 ; +0x104
+00000000 ; +0x108
+00000000 ; +0x10c
+00000000 ; +0x110
+00000000 ; +0x114
+00000000 ; +0x118
+00000000 ; +0x11c
+00000000 ; +0x120
+00000000 ; +0x124
+00000000 ; +0x128
+00000000 ; +0x12c
+00000000 ; +0x130
+00000000 ; +0x134
+00000000 ; +0x138
+00000000 ; +0x13c
+00000000 ; +0x140
+00000000 ; +0x144
+00000000 ; +0x148
+00000000 ; +0x14c
+00000000 ; +0x150
+00000000 ; +0x154
+00000000 ; +0x158
+00000000 ; +0x15c
+00000000 ; +0x160
+00000000 ; +0x164
+00000000 ; +0x168
+00000000 ; +0x16c
+00000000 ; +0x170
+00000000 ; +0x174
+00000000 ; +0x178
+00000000 ; +0x17c
+00000000 ; +0x180
+00000000 ; +0x184
+00000000 ; +0x188
+00000000 ; +0x18c
+00000000 ; +0x190
+00000000 ; +0x194
+00000000 ; +0x198
+00000000 ; +0x19c
+00000000 ; +0x1a0
+00000000 ; +0x1a4
+00000000 ; +0x1a8
+00000000 ; +0x1ac
+00000000 ; +0x1b0
+00000000 ; +0x1b4
+00000000 ; +0x1b8
+00000000 ; +0x1bc
+00000000 ; +0x1c0
+00000000 ; +0x1c4
+00000000 ; +0x1c8
+00000000 ; +0x1cc
+00000000 ; +0x1d0
+00000000 ; +0x1d4
+00000000 ; +0x1d8
+00000000 ; +0x1dc
+00000000 ; +0x1e0
+00000000 ; +0x1e4
+00000000 ; +0x1e8
+00000000 ; +0x1ec
+00000000 ; +0x1f0
+00000000 ; +0x1f4
+00000000 ; +0x1f8
+00000000 ; +0x1fc
+00000000 ; +0x200
+00000000 ; +0x204
+00000000 ; +0x208
+00000000 ; +0x20c
+00000000 ; +0x210
+00000000 ; +0x214
+00000000 ; +0x218
+00000000 ; +0x21c
+00000000 ; +0x220
+00000000 ; +0x224
+00000000 ; +0x228
+00000000 ; +0x22c
+00000000 ; +0x230
+00000000 ; +0x234
+00000000 ; +0x238
+00000000 ; +0x23c
+00000000 ; +0x240
+00000000 ; +0x244
+00000000 ; +0x248
+00000000 ; +0x24c
+00000000 ; +0x250
+00000000 ; +0x254
+00000000 ; +0x258
+00000000 ; +0x25c
+00000000 ; +0x260
+00000000 ; +0x264
+00000000 ; +0x268
+00000000 ; +0x26c
+00000000 ; +0x270
+00000000 ; +0x274
+00000000 ; +0x278
+00000000 ; +0x27c
+00000000 ; +0x280
+00000000 ; +0x284
+00000000 ; +0x288
+00000000 ; +0x28c
+00000000 ; +0x290
+00000000 ; +0x294
+00000000 ; +0x298
+00000000 ; +0x29c
+00000000 ; +0x2a0
+00000000 ; +0x2a4
+00000000 ; +0x2a8
+00000000 ; +0x2ac
+00000000 ; +0x2b0
+00000000 ; +0x2b4
+00000000 ; +0x2b8
+00000000 ; +0x2bc
+00000000 ; +0x2c0
+00000000 ; +0x2c4
+00000000 ; +0x2c8
+00000000 ; +0x2cc
+00000000 ; +0x2d0
+00000000 ; +0x2d4
+00000000 ; +0x2d8
+00000000 ; +0x2dc
+00000000 ; +0x2e0
+00000000 ; +0x2e4
+00000000 ; +0x2e8
+00000000 ; +0x2ec
+00000000 ; +0x2f0
+00000000 ; +0x2f4
+00000000 ; +0x2f8
+00000000 ; +0x2fc
+00000000 ; +0x300
+00000000 ; +0x304
+00000000 ; +0x308
+00000000 ; +0x30c
+00000000 ; +0x310
+00000000 ; +0x314
+00000000 ; +0x318
+00000000 ; +0x31c
+00000000 ; +0x320
+00000000 ; +0x324
+00000000 ; +0x328
+00000000 ; +0x32c
+00000000 ; +0x330
+00000000 ; +0x334
+00000000 ; +0x338
+00000000 ; +0x33c
+00000000 ; +0x340
+00000000 ; +0x344
+00000000 ; +0x348
+00000000 ; +0x34c
+00000000 ; +0x350
+00000000 ; +0x354
+00000000 ; +0x358
+00000000 ; +0x35c
+00000000 ; +0x360
+00000000 ; +0x364
+00000000 ; +0x368
+00000000 ; +0x36c
+00000000 ; +0x370
+00000000 ; +0x374
+00000000 ; +0x378
+00000000 ; +0x37c
+00000000 ; +0x380
+00000000 ; +0x384
+00000000 ; +0x388
+00000000 ; +0x38c
+00000000 ; +0x390
+00000000 ; +0x394
+00000000 ; +0x398
+00000000 ; +0x39c
+00000000 ; +0x3a0
+00000000 ; +0x3a4
+00000000 ; +0x3a8
+00000000 ; +0x3ac
+00000000 ; +0x3b0
+00000000 ; +0x3b4
+00000000 ; +0x3b8
+00000000 ; +0x3bc
+00000000 ; +0x3c0
+00000000 ; +0x3c4
+00000000 ; +0x3c8
+00000000 ; +0x3cc
+00000000 ; +0x3d0
+00000000 ; +0x3d4
+00000000 ; +0x3d8
+00000000 ; +0x3dc
+00000000 ; +0x3e0
+00000000 ; +0x3e4
+00000000 ; +0x3e8
+00000000 ; +0x3ec
+00000000 ; +0x3f0
+00000000 ; +0x3f4
+00000000 ; +0x3f8
+00000000 ; +0x3fc
\ No newline at end of file
diff --git a/hyperdbg/CMakeLists.txt b/hyperdbg/CMakeLists.txt
new file mode 100644
index 00000000..ba5b3855
--- /dev/null
+++ b/hyperdbg/CMakeLists.txt
@@ -0,0 +1,94 @@
+# Code generated by Visual Studio kit, DO NOT EDIT.
+cmake_minimum_required(VERSION 3.28)
+project(hyperdbg C CXX)
+set(CMAKE_CXX_STANDARD 23)
+enable_language(ASM_MASM)
+set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+
+if(LINUX)
+
+ message(STATUS "Building on Linux")
+elseif(WIN32)
+ message(STATUS "Building on Windows")
+find_package(WDK REQUIRED)
+
+ include_directories(
+ "dependencies/zydis/include"
+ "dependencies/zydis/src"
+ "dependencies/zydis/dependencies/zycore/include"
+ )
+
+ file(GLOB ZydisSourceFiles "dependencies/zydis/src/*.c")
+ file(GLOB ZycoreSourceFiles "dependencies/zydis/dependencies/zycore/*.c")
+
+ set(SourceFiles
+ ${ZydisSourceFiles}
+ ${ZycoreSourceFiles}
+ # examples/ZydisWinKernel.c
+ )
+
+ add_definitions(
+ -DZYAN_NO_LIBC
+ -DZYDIS_NO_LIBC
+ -DZYCORE_STATIC_BUILD
+ -DZYDIS_STATIC_BUILD
+ )
+
+ wdk_add_library(zydisKernel
+ KMDF 1.15
+ ${SourceFiles}
+ )
+link_directories(libraries/kdserial/x64)
+add_subdirectory(kdserial)
+target_link_libraries(kdserial kdserialtransport kdhv kdtelemetry)
+
+
+add_subdirectory(hyperlog)
+link_directories(libraries/zydis/kernel)
+add_subdirectory(hyperhv)
+target_link_libraries(hyperhv Zycore Zydis)
+
+
+add_subdirectory(hyperkd)
+target_link_libraries(hyperkd hyperlog hyperhv kdserial)
+
+endif()
+
+#add_subdirectory(dependencies/pdbex/Source)
+
+#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)
+link_directories(libraries/zydis/user libraries/keystone/release-lib)
+add_subdirectory(libhyperdbg)
+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)
+
+
+
+#set(save_src_dir ${CMAKE_CURRENT_SOURCE_DIR}/examples)
+#execute_process( COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/../examples ${save_src_dir})
+#
+#add_subdirectory(examples/kernel/hyperdbg_driver)
+#target_link_libraries(hyperdbg_driver hyperlog hyperhv)
+#
+#
+#add_subdirectory(examples/user/hyperdbg_app)
+#target_link_libraries(hyperdbg_app libhyperdbg)
+
diff --git a/hyperdbg/FindWdk.cmake b/hyperdbg/FindWdk.cmake
new file mode 100644
index 00000000..12765781
--- /dev/null
+++ b/hyperdbg/FindWdk.cmake
@@ -0,0 +1,209 @@
+# Redistribution and use is allowed under the OSI-approved 3-clause BSD license.
+# Copyright (c) 2018 Sergey Podobry (sergey.podobry at gmail.com). All rights reserved.
+
+#.rst:
+# FindWDK
+# ----------
+#
+# This module searches for the installed Windows Development Kit (WDK) and
+# exposes commands for creating kernel drivers and kernel libraries.
+#
+# Output variables:
+# - `WDK_FOUND` -- if false, do not try to use WDK
+# - `WDK_ROOT` -- where WDK is installed
+# - `WDK_VERSION` -- the version of the selected WDK
+# - `WDK_WINVER` -- the WINVER used for kernel drivers and libraries
+# (default value is `0x0601` and can be changed per target or globally)
+# - `WDK_NTDDI_VERSION` -- the NTDDI_VERSION used for kernel drivers and libraries,
+# if not set, the value will be automatically calculated by WINVER
+# (default value is left blank and can be changed per target or globally)
+#
+# Example usage:
+#
+# find_package(WDK REQUIRED)
+#
+# wdk_add_library(KmdfCppLib STATIC KMDF 1.15
+# KmdfCppLib.h
+# KmdfCppLib.cpp
+# )
+# target_include_directories(KmdfCppLib INTERFACE .)
+#
+# wdk_add_driver(KmdfCppDriver KMDF 1.15
+# Main.cpp
+# )
+# target_link_libraries(KmdfCppDriver KmdfCppLib)
+#
+
+if(DEFINED ENV{WDKContentRoot})
+ file(GLOB WDK_NTDDK_FILES
+ "$ENV{WDKContentRoot}/Include/*/km/ntddk.h" # WDK 10
+ "$ENV{WDKContentRoot}/Include/km/ntddk.h" # WDK 8.0, 8.1
+ )
+else()
+ file(GLOB WDK_NTDDK_FILES
+ "C:/Program Files*/Windows Kits/*/Include/*/km/ntddk.h" # WDK 10
+ "C:/Program Files*/Windows Kits/*/Include/km/ntddk.h" # WDK 8.0, 8.1
+ )
+endif()
+
+if(WDK_NTDDK_FILES)
+ if (NOT CMAKE_VERSION VERSION_LESS 3.18.0)
+ list(SORT WDK_NTDDK_FILES COMPARE NATURAL) # sort to use the latest available WDK
+ endif()
+ list(GET WDK_NTDDK_FILES -1 WDK_LATEST_NTDDK_FILE)
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(WDK REQUIRED_VARS WDK_LATEST_NTDDK_FILE)
+
+if (NOT WDK_LATEST_NTDDK_FILE)
+ return()
+endif()
+
+get_filename_component(WDK_ROOT ${WDK_LATEST_NTDDK_FILE} DIRECTORY)
+get_filename_component(WDK_ROOT ${WDK_ROOT} DIRECTORY)
+get_filename_component(WDK_VERSION ${WDK_ROOT} NAME)
+get_filename_component(WDK_ROOT ${WDK_ROOT} DIRECTORY)
+if (NOT WDK_ROOT MATCHES ".*/[0-9][0-9.]*$") # WDK 10 has a deeper nesting level
+ get_filename_component(WDK_ROOT ${WDK_ROOT} DIRECTORY) # go up once more
+ set(WDK_LIB_VERSION "${WDK_VERSION}")
+ set(WDK_INC_VERSION "${WDK_VERSION}")
+else() # WDK 8.0, 8.1
+ set(WDK_INC_VERSION "")
+ foreach(VERSION winv6.3 win8 win7)
+ if (EXISTS "${WDK_ROOT}/Lib/${VERSION}/")
+ set(WDK_LIB_VERSION "${VERSION}")
+ break()
+ endif()
+ endforeach()
+ set(WDK_VERSION "${WDK_LIB_VERSION}")
+endif()
+
+message(STATUS "WDK_ROOT: " ${WDK_ROOT})
+message(STATUS "WDK_VERSION: " ${WDK_VERSION})
+
+set(WDK_WINVER "0x0a01" CACHE STRING "Default WINVER for WDK targets")
+set(WDK_NTDDI_VERSION "" CACHE STRING "Specified NTDDI_VERSION for WDK targets if needed")
+
+set(WDK_ADDITIONAL_FLAGS_FILE "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/wdkflags.h")
+file(WRITE ${WDK_ADDITIONAL_FLAGS_FILE} "#pragma runtime_checks(\"suc\", off)")
+
+set(WDK_COMPILE_FLAGS
+ "/Zp8" # set struct alignment
+ "/GF" # enable string pooling
+ "/GR-" # disable RTTI
+ "/Gz" # __stdcall by default
+ "/kernel" # create kernel mode binary
+ "/FIwarning.h" # disable warnings in WDK headers
+ "/FI${WDK_ADDITIONAL_FLAGS_FILE}" # include file to disable RTC
+ )
+
+set(WDK_COMPILE_DEFINITIONS "WINNT=1")
+set(WDK_COMPILE_DEFINITIONS_DEBUG "MSC_NOOPT;DEPRECATE_DDK_FUNCTIONS=1;DBG=1")
+
+if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ list(APPEND WDK_COMPILE_DEFINITIONS "_X86_=1;i386=1;STD_CALL")
+ set(WDK_PLATFORM "x86")
+elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ list(APPEND WDK_COMPILE_DEFINITIONS "_WIN64;_AMD64_;AMD64")
+ set(WDK_PLATFORM "x64")
+else()
+ message(FATAL_ERROR "Unsupported architecture")
+endif()
+
+string(CONCAT WDK_LINK_FLAGS
+ "/MANIFEST:NO " #
+ "/DRIVER " #
+ "/OPT:REF " #
+ "/INCREMENTAL:NO " #
+ "/OPT:ICF " #
+ "/SUBSYSTEM:NATIVE " #
+ "/MERGE:_TEXT=.text;_PAGE=PAGE " #
+ "/NODEFAULTLIB " # do not link default CRT
+ "/SECTION:INIT,d " #
+ "/VERSION:10.0 " #
+ )
+
+# Generate imported targets for WDK lib files
+file(GLOB WDK_LIBRARIES "${WDK_ROOT}/Lib/${WDK_LIB_VERSION}/km/${WDK_PLATFORM}/*.lib")
+foreach(LIBRARY IN LISTS WDK_LIBRARIES)
+ get_filename_component(LIBRARY_NAME ${LIBRARY} NAME_WE)
+ string(TOUPPER ${LIBRARY_NAME} LIBRARY_NAME)
+ add_library(WDK::${LIBRARY_NAME} INTERFACE IMPORTED)
+ set_property(TARGET WDK::${LIBRARY_NAME} PROPERTY INTERFACE_LINK_LIBRARIES ${LIBRARY})
+endforeach(LIBRARY)
+unset(WDK_LIBRARIES)
+
+function(wdk_add_driver _target)
+ cmake_parse_arguments(WDK "" "KMDF;WINVER;NTDDI_VERSION" "" ${ARGN})
+
+ add_executable(${_target} ${WDK_UNPARSED_ARGUMENTS})
+
+ set_target_properties(${_target} PROPERTIES SUFFIX ".sys")
+ set_target_properties(${_target} PROPERTIES COMPILE_OPTIONS "${WDK_COMPILE_FLAGS}")
+ set_target_properties(${_target} PROPERTIES COMPILE_DEFINITIONS
+ "${WDK_COMPILE_DEFINITIONS};$<$:${WDK_COMPILE_DEFINITIONS_DEBUG}>;_WIN32_WINNT=${WDK_WINVER}"
+ )
+ set_target_properties(${_target} PROPERTIES LINK_FLAGS "${WDK_LINK_FLAGS}")
+ if(WDK_NTDDI_VERSION)
+ target_compile_definitions(${_target} PRIVATE NTDDI_VERSION=${WDK_NTDDI_VERSION})
+ endif()
+
+ target_include_directories(${_target} SYSTEM PRIVATE
+ "${WDK_ROOT}/Include/${WDK_INC_VERSION}/shared"
+ "${WDK_ROOT}/Include/${WDK_INC_VERSION}/km"
+ "${WDK_ROOT}/Include/${WDK_INC_VERSION}/km/crt"
+ )
+
+ target_link_libraries(${_target} WDK::NTOSKRNL WDK::HAL WDK::BUFFEROVERFLOWK WDK::WMILIB)
+
+ if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ target_link_libraries(${_target} WDK::MEMCMP)
+ endif()
+
+ if(DEFINED WDK_KMDF)
+ target_include_directories(${_target} SYSTEM PRIVATE "${WDK_ROOT}/Include/wdf/kmdf/${WDK_KMDF}")
+ target_link_libraries(${_target}
+ "${WDK_ROOT}/Lib/wdf/kmdf/${WDK_PLATFORM}/${WDK_KMDF}/WdfDriverEntry.lib"
+ "${WDK_ROOT}/Lib/wdf/kmdf/${WDK_PLATFORM}/${WDK_KMDF}/WdfLdr.lib"
+ )
+
+ if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS "/ENTRY:FxDriverEntry@8")
+ elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS "/ENTRY:FxDriverEntry")
+ endif()
+ else()
+ if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS "/ENTRY:GsDriverEntry@8")
+ elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS "/ENTRY:GsDriverEntry")
+ endif()
+ endif()
+endfunction()
+
+function(wdk_add_library _target)
+ cmake_parse_arguments(WDK "" "KMDF;WINVER;NTDDI_VERSION" "" ${ARGN})
+
+ add_library(${_target} ${WDK_UNPARSED_ARGUMENTS})
+
+ set_target_properties(${_target} PROPERTIES COMPILE_OPTIONS "${WDK_COMPILE_FLAGS}")
+ set_target_properties(${_target} PROPERTIES COMPILE_DEFINITIONS
+ "${WDK_COMPILE_DEFINITIONS};$<$:${WDK_COMPILE_DEFINITIONS_DEBUG};>_WIN32_WINNT=${WDK_WINVER}"
+ )
+ if(WDK_NTDDI_VERSION)
+ target_compile_definitions(${_target} PRIVATE NTDDI_VERSION=${WDK_NTDDI_VERSION})
+ endif()
+
+ target_include_directories(${_target} SYSTEM PRIVATE
+ "${WDK_ROOT}/Include/${WDK_INC_VERSION}/shared"
+ "${WDK_ROOT}/Include/${WDK_INC_VERSION}/km"
+ "${WDK_ROOT}/Include/${WDK_INC_VERSION}/km/crt"
+ )
+
+ target_link_libraries(${_target} WDK::NTOSKRNL WDK::HAL WDK::WMILIB)
+
+ if(DEFINED WDK_KMDF)
+ target_include_directories(${_target} SYSTEM PRIVATE "${WDK_ROOT}/Include/wdf/kmdf/${WDK_KMDF}")
+ endif()
+endfunction()
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/keystone/include/keystone/arm.h b/hyperdbg/dependencies/keystone/include/keystone/arm.h
new file mode 100644
index 00000000..f4d2489a
--- /dev/null
+++ b/hyperdbg/dependencies/keystone/include/keystone/arm.h
@@ -0,0 +1,23 @@
+/* Keystone Assembler Engine */
+/* By Nguyen Anh Quynh, 2016 */
+
+#ifndef KEYSTONE_ARM_H
+#define KEYSTONE_ARM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "keystone.h"
+
+typedef enum ks_err_asm_arm {
+ KS_ERR_ASM_ARM_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_ARM_MISSINGFEATURE,
+ KS_ERR_ASM_ARM_MNEMONICFAIL,
+} ks_err_asm_arm;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/dependencies/keystone/include/keystone/arm64.h b/hyperdbg/dependencies/keystone/include/keystone/arm64.h
new file mode 100644
index 00000000..7a7af411
--- /dev/null
+++ b/hyperdbg/dependencies/keystone/include/keystone/arm64.h
@@ -0,0 +1,23 @@
+/* Keystone Assembler Engine */
+/* By Nguyen Anh Quynh, 2016 */
+
+#ifndef KEYSTONE_ARM64_H
+#define KEYSTONE_ARM64_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "keystone.h"
+
+typedef enum ks_err_asm_arm64 {
+ KS_ERR_ASM_ARM64_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_ARM64_MISSINGFEATURE,
+ KS_ERR_ASM_ARM64_MNEMONICFAIL,
+} ks_err_asm_arm64;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/dependencies/keystone/include/keystone/evm.h b/hyperdbg/dependencies/keystone/include/keystone/evm.h
new file mode 100644
index 00000000..60ac408c
--- /dev/null
+++ b/hyperdbg/dependencies/keystone/include/keystone/evm.h
@@ -0,0 +1,23 @@
+/* Keystone Assembler Engine */
+/* By Nguyen Anh Quynh, 2016-2018 */
+
+#ifndef KEYSTONE_EVM_H
+#define KEYSTONE_EVM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "keystone.h"
+
+typedef enum ks_err_asm_evm {
+ KS_ERR_ASM_EVM_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_EVM_MISSINGFEATURE,
+ KS_ERR_ASM_EVM_MNEMONICFAIL,
+} ks_err_asm_evm;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/dependencies/keystone/include/keystone/hexagon.h b/hyperdbg/dependencies/keystone/include/keystone/hexagon.h
new file mode 100644
index 00000000..e6158123
--- /dev/null
+++ b/hyperdbg/dependencies/keystone/include/keystone/hexagon.h
@@ -0,0 +1,24 @@
+/* Keystone Assembler Engine */
+/* By Nguyen Anh Quynh, 2016 */
+
+#ifndef KEYSTONE_HEXAGON_H
+#define KEYSTONE_HEXAGON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "keystone.h"
+
+typedef enum ks_err_asm_hexagon {
+ KS_ERR_ASM_HEXAGON_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_HEXAGON_MISSINGFEATURE,
+ KS_ERR_ASM_HEXAGON_MNEMONICFAIL,
+} ks_err_asm_hexagon;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/dependencies/keystone/include/keystone/keystone.h b/hyperdbg/dependencies/keystone/include/keystone/keystone.h
new file mode 100644
index 00000000..03fd54a3
--- /dev/null
+++ b/hyperdbg/dependencies/keystone/include/keystone/keystone.h
@@ -0,0 +1,346 @@
+/* Keystone Assembler Engine (www.keystone-engine.org) */
+/* By Nguyen Anh Quynh , 2016 */
+
+#ifndef KEYSTONE_ENGINE_H
+#define KEYSTONE_ENGINE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+#include
+#include
+
+#ifdef _MSC_VER // MSVC compiler
+#pragma warning(disable:4201)
+#pragma warning(disable:4100)
+#ifndef KEYSTONE_STATIC
+#define KEYSTONE_EXPORT __declspec(dllexport)
+#else
+#define KEYSTONE_EXPORT
+#endif
+#else
+#ifdef __GNUC__
+#include
+#ifndef KEYSTONE_STATIC
+#define KEYSTONE_EXPORT __attribute__((visibility("default")))
+#else
+#define KEYSTONE_EXPORT
+#endif
+#else
+#define KEYSTONE_EXPORT
+#endif
+#endif
+
+
+struct ks_struct;
+typedef struct ks_struct ks_engine;
+
+// Keystone API version
+#define KS_API_MAJOR 0
+#define KS_API_MINOR 9
+
+// Package version
+#define KS_VERSION_MAJOR KS_API_MAJOR
+#define KS_VERSION_MINOR KS_API_MINOR
+#define KS_VERSION_EXTRA 2
+
+/*
+ Macro to create combined version which can be compared to
+ result of ks_version() API.
+*/
+#define KS_MAKE_VERSION(major, minor) ((major << 8) + minor)
+
+// Architecture type
+typedef enum ks_arch {
+ KS_ARCH_ARM = 1, // ARM architecture (including Thumb, Thumb-2)
+ KS_ARCH_ARM64, // ARM-64, also called AArch64
+ KS_ARCH_MIPS, // Mips architecture
+ KS_ARCH_X86, // X86 architecture (including x86 & x86-64)
+ KS_ARCH_PPC, // PowerPC architecture (currently unsupported)
+ KS_ARCH_SPARC, // Sparc architecture
+ KS_ARCH_SYSTEMZ, // SystemZ architecture (S390X)
+ KS_ARCH_HEXAGON, // Hexagon architecture
+ KS_ARCH_EVM, // Ethereum Virtual Machine architecture
+ KS_ARCH_RISCV, // RISC-V architecture
+ KS_ARCH_MAX,
+} ks_arch;
+
+// Mode type
+typedef enum ks_mode {
+ KS_MODE_LITTLE_ENDIAN = 0, // little-endian mode (default mode)
+ KS_MODE_BIG_ENDIAN = 1 << 30, // big-endian mode
+ // arm / arm64
+ KS_MODE_ARM = 1 << 0, // ARM mode
+ KS_MODE_THUMB = 1 << 4, // THUMB mode (including Thumb-2)
+ KS_MODE_V8 = 1 << 6, // ARMv8 A32 encodings for ARM
+ // mips
+ KS_MODE_MICRO = 1 << 4, // MicroMips mode
+ KS_MODE_MIPS3 = 1 << 5, // Mips III ISA
+ KS_MODE_MIPS32R6 = 1 << 6, // Mips32r6 ISA
+ KS_MODE_MIPS32 = 1 << 2, // Mips32 ISA
+ KS_MODE_MIPS64 = 1 << 3, // Mips64 ISA
+ // x86 / x64
+ KS_MODE_16 = 1 << 1, // 16-bit mode
+ KS_MODE_32 = 1 << 2, // 32-bit mode
+ KS_MODE_64 = 1 << 3, // 64-bit mode
+ // ppc
+ KS_MODE_PPC32 = 1 << 2, // 32-bit mode
+ KS_MODE_PPC64 = 1 << 3, // 64-bit mode
+ KS_MODE_QPX = 1 << 4, // Quad Processing eXtensions mode
+ //riscv
+ KS_MODE_RISCV32 = 1 << 2, // 32-bit mode
+ KS_MODE_RISCV64 = 1 << 3, // 64-bit mode
+ // sparc
+ KS_MODE_SPARC32 = 1 << 2, // 32-bit mode
+ KS_MODE_SPARC64 = 1 << 3, // 64-bit mode
+ KS_MODE_V9 = 1 << 4, // SparcV9 mode
+} ks_mode;
+
+// All generic errors related to input assembly >= KS_ERR_ASM
+#define KS_ERR_ASM 128
+
+// All architecture-specific errors related to input assembly >= KS_ERR_ASM_ARCH
+#define KS_ERR_ASM_ARCH 512
+
+// All type of errors encountered by Keystone API.
+typedef enum ks_err {
+ KS_ERR_OK = 0, // No error: everything was fine
+ KS_ERR_NOMEM, // Out-Of-Memory error: ks_open(), ks_emulate()
+ KS_ERR_ARCH, // Unsupported architecture: ks_open()
+ KS_ERR_HANDLE, // Invalid handle
+ KS_ERR_MODE, // Invalid/unsupported mode: ks_open()
+ KS_ERR_VERSION, // Unsupported version (bindings)
+ KS_ERR_OPT_INVALID, // Unsupported option
+
+ // generic input assembly errors - parser specific
+ KS_ERR_ASM_EXPR_TOKEN = KS_ERR_ASM, // unknown token in expression
+ KS_ERR_ASM_DIRECTIVE_VALUE_RANGE, // literal value out of range for directive
+ KS_ERR_ASM_DIRECTIVE_ID, // expected identifier in directive
+ KS_ERR_ASM_DIRECTIVE_TOKEN, // unexpected token in directive
+ KS_ERR_ASM_DIRECTIVE_STR, // expected string in directive
+ KS_ERR_ASM_DIRECTIVE_COMMA, // expected comma in directive
+ KS_ERR_ASM_DIRECTIVE_RELOC_NAME, // expected relocation name in directive
+ KS_ERR_ASM_DIRECTIVE_RELOC_TOKEN, // unexpected token in .reloc directive
+ KS_ERR_ASM_DIRECTIVE_FPOINT, // invalid floating point in directive
+ KS_ERR_ASM_DIRECTIVE_UNKNOWN, // unknown directive
+ KS_ERR_ASM_DIRECTIVE_EQU, // invalid equal directive
+ KS_ERR_ASM_DIRECTIVE_INVALID, // (generic) invalid directive
+ KS_ERR_ASM_VARIANT_INVALID, // invalid variant
+ KS_ERR_ASM_EXPR_BRACKET, // brackets expression not supported on this target
+ KS_ERR_ASM_SYMBOL_MODIFIER, // unexpected symbol modifier following '@'
+ KS_ERR_ASM_SYMBOL_REDEFINED, // invalid symbol redefinition
+ KS_ERR_ASM_SYMBOL_MISSING, // cannot find a symbol
+ KS_ERR_ASM_RPAREN, // expected ')' in parentheses expression
+ KS_ERR_ASM_STAT_TOKEN, // unexpected token at start of statement
+ KS_ERR_ASM_UNSUPPORTED, // unsupported token yet
+ KS_ERR_ASM_MACRO_TOKEN, // unexpected token in macro instantiation
+ KS_ERR_ASM_MACRO_PAREN, // unbalanced parentheses in macro argument
+ KS_ERR_ASM_MACRO_EQU, // expected '=' after formal parameter identifier
+ KS_ERR_ASM_MACRO_ARGS, // too many positional arguments
+ KS_ERR_ASM_MACRO_LEVELS_EXCEED, // macros cannot be nested more than 20 levels deep
+ KS_ERR_ASM_MACRO_STR, // invalid macro string
+ KS_ERR_ASM_MACRO_INVALID, // invalid macro (generic error)
+ KS_ERR_ASM_ESC_BACKSLASH, // unexpected backslash at end of escaped string
+ KS_ERR_ASM_ESC_OCTAL, // invalid octal escape sequence (out of range)
+ KS_ERR_ASM_ESC_SEQUENCE, // invalid escape sequence (unrecognized character)
+ KS_ERR_ASM_ESC_STR, // broken escape string
+ KS_ERR_ASM_TOKEN_INVALID, // invalid token
+ KS_ERR_ASM_INSN_UNSUPPORTED, // this instruction is unsupported in this mode
+ KS_ERR_ASM_FIXUP_INVALID, // invalid fixup
+ KS_ERR_ASM_LABEL_INVALID, // invalid label
+ KS_ERR_ASM_FRAGMENT_INVALID, // invalid fragment
+
+ // generic input assembly errors - architecture specific
+ KS_ERR_ASM_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_MISSINGFEATURE,
+ KS_ERR_ASM_MNEMONICFAIL,
+} ks_err;
+
+// Resolver callback to provide value for a missing symbol in @symbol.
+// To handle a symbol, the resolver must put value of the symbol in @value,
+// then returns True.
+// If we do not resolve a missing symbol, this function must return False.
+// In that case, ks_asm() would eventually return with error KS_ERR_ASM_SYMBOL_MISSING.
+
+// To register the resolver, pass its function address to ks_option(), using
+// option KS_OPT_SYM_RESOLVER. For example, see samples/sample.c.
+typedef bool (*ks_sym_resolver)(const char *symbol, uint64_t *value);
+
+// Runtime option for the Keystone engine
+typedef enum ks_opt_type {
+ KS_OPT_SYNTAX = 1, // Choose syntax for input assembly
+ KS_OPT_SYM_RESOLVER, // Set symbol resolver callback
+} ks_opt_type;
+
+
+// Runtime option value (associated with ks_opt_type above)
+typedef enum ks_opt_value {
+ KS_OPT_SYNTAX_INTEL = 1 << 0, // X86 Intel syntax - default on X86 (KS_OPT_SYNTAX).
+ KS_OPT_SYNTAX_ATT = 1 << 1, // X86 ATT asm syntax (KS_OPT_SYNTAX).
+ KS_OPT_SYNTAX_NASM = 1 << 2, // X86 Nasm syntax (KS_OPT_SYNTAX).
+ KS_OPT_SYNTAX_MASM = 1 << 3, // X86 Masm syntax (KS_OPT_SYNTAX) - unsupported yet.
+ KS_OPT_SYNTAX_GAS = 1 << 4, // X86 GNU GAS syntax (KS_OPT_SYNTAX).
+ KS_OPT_SYNTAX_RADIX16 = 1 << 5, // All immediates are in hex format (i.e 12 is 0x12)
+} ks_opt_value;
+
+
+#include "arm64.h"
+#include "arm.h"
+#include "evm.h"
+#include "hexagon.h"
+#include "mips.h"
+#include "ppc.h"
+#include "riscv.h"
+#include "sparc.h"
+#include "systemz.h"
+#include "x86.h"
+
+/*
+ Return combined API version & major and minor version numbers.
+
+ @major: major number of API version
+ @minor: minor number of API version
+
+ @return hexical number as (major << 8 | minor), which encodes both
+ major & minor versions.
+ NOTE: This returned value can be compared with version number made
+ with macro KS_MAKE_VERSION
+
+ For example, second API version would return 1 in @major, and 1 in @minor
+ The return value would be 0x0101
+
+ NOTE: if you only care about returned value, but not major and minor values,
+ set both @major & @minor arguments to NULL.
+*/
+KEYSTONE_EXPORT
+unsigned int ks_version(unsigned int *major, unsigned int *minor);
+
+
+/*
+ Determine if the given architecture is supported by this library.
+
+ @arch: architecture type (KS_ARCH_*)
+
+ @return True if this library supports the given arch.
+*/
+KEYSTONE_EXPORT
+bool ks_arch_supported(ks_arch arch);
+
+
+/*
+ Create new instance of Keystone engine.
+
+ @arch: architecture type (KS_ARCH_*)
+ @mode: hardware mode. This is combined of KS_MODE_*
+ @ks: pointer to ks_engine, which will be updated at return time
+
+ @return KS_ERR_OK on success, or other value on failure (refer to ks_err enum
+ for detailed error).
+*/
+KEYSTONE_EXPORT
+ks_err ks_open(ks_arch arch, int mode, ks_engine **ks);
+
+
+/*
+ Close KS instance: MUST do to release the handle when it is not used anymore.
+ NOTE: this must be called only when there is no longer usage of Keystone.
+ The reason is the this API releases some cached memory, thus access to any
+ Keystone API after ks_close() might crash your application.
+ After this, @ks is invalid, and nolonger usable.
+
+ @ks: pointer to a handle returned by ks_open()
+
+ @return KS_ERR_OK on success, or other value on failure (refer to ks_err enum
+ for detailed error).
+*/
+KEYSTONE_EXPORT
+ks_err ks_close(ks_engine *ks);
+
+
+/*
+ Report the last error number when some API function fail.
+ Like glibc's errno, ks_errno might not retain its old error once accessed.
+
+ @ks: handle returned by ks_open()
+
+ @return: error code of ks_err enum type (KS_ERR_*, see above)
+*/
+KEYSTONE_EXPORT
+ks_err ks_errno(ks_engine *ks);
+
+
+/*
+ Return a string describing given error code.
+
+ @code: error code (see KS_ERR_* above)
+
+ @return: returns a pointer to a string that describes the error code
+ passed in the argument @code
+ */
+KEYSTONE_EXPORT
+const char *ks_strerror(ks_err code);
+
+
+/*
+ Set option for Keystone engine at runtime
+
+ @ks: handle returned by ks_open()
+ @type: type of option to be set. See ks_opt_type
+ @value: option value corresponding with @type
+
+ @return: KS_ERR_OK on success, or other value on failure.
+ Refer to ks_err enum for detailed error.
+*/
+KEYSTONE_EXPORT
+ks_err ks_option(ks_engine *ks, ks_opt_type type, size_t value);
+
+
+/*
+ Assemble a string given its the buffer, size, start address and number
+ of instructions to be decoded.
+ This API dynamically allocate memory to contain assembled instruction.
+ Resulted array of bytes containing the machine code is put into @*encoding
+
+ NOTE 1: this API will automatically determine memory needed to contain
+ output bytes in *encoding.
+
+ NOTE 2: caller must free the allocated memory itself to avoid memory leaking.
+
+ @ks: handle returned by ks_open()
+ @str: NULL-terminated assembly string. Use ; or \n to separate statements.
+ @address: address of the first assembly instruction, or 0 to ignore.
+ @encoding: array of bytes containing encoding of input assembly string.
+ NOTE: *encoding will be allocated by this function, and should be freed
+ with ks_free() function.
+ @encoding_size: size of *encoding
+ @stat_count: number of statements successfully processed
+
+ @return: 0 on success, or -1 on failure.
+
+ On failure, call ks_errno() for error code.
+*/
+KEYSTONE_EXPORT
+int ks_asm(ks_engine *ks,
+ const char *string,
+ uint64_t address,
+ unsigned char **encoding, size_t *encoding_size,
+ size_t *stat_count);
+
+
+/*
+ Free memory allocated by ks_asm()
+
+ @p: memory allocated in @encoding argument of ks_asm()
+*/
+KEYSTONE_EXPORT
+void ks_free(unsigned char *p);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/dependencies/keystone/include/keystone/mips.h b/hyperdbg/dependencies/keystone/include/keystone/mips.h
new file mode 100644
index 00000000..e71c553c
--- /dev/null
+++ b/hyperdbg/dependencies/keystone/include/keystone/mips.h
@@ -0,0 +1,23 @@
+/* Keystone Assembler Engine */
+/* By Nguyen Anh Quynh, 2016 */
+
+#ifndef KEYSTONE_MIPS_H
+#define KEYSTONE_MIPS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "keystone.h"
+
+typedef enum ks_err_asm_mips {
+ KS_ERR_ASM_MIPS_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_MIPS_MISSINGFEATURE,
+ KS_ERR_ASM_MIPS_MNEMONICFAIL,
+} ks_err_asm_mips;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/dependencies/keystone/include/keystone/ppc.h b/hyperdbg/dependencies/keystone/include/keystone/ppc.h
new file mode 100644
index 00000000..39a602c2
--- /dev/null
+++ b/hyperdbg/dependencies/keystone/include/keystone/ppc.h
@@ -0,0 +1,24 @@
+/* Keystone Assembler Engine */
+/* By Nguyen Anh Quynh, 2016 */
+
+#ifndef KEYSTONE_PPC_H
+#define KEYSTONE_PPC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "keystone.h"
+
+typedef enum ks_err_asm_ppc {
+ KS_ERR_ASM_PPC_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_PPC_MISSINGFEATURE,
+ KS_ERR_ASM_PPC_MNEMONICFAIL,
+} ks_err_asm_ppc;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/dependencies/keystone/include/keystone/riscv.h b/hyperdbg/dependencies/keystone/include/keystone/riscv.h
new file mode 100644
index 00000000..0910f986
--- /dev/null
+++ b/hyperdbg/dependencies/keystone/include/keystone/riscv.h
@@ -0,0 +1,24 @@
+/* Keystone Assembler Engine */
+/* By Nguyen Anh Quynh, 2016 */
+/* Added by Mark Juvan, 2023*/
+#ifndef KEYSTONE_RISCV_H
+#define KEYSTONE_RISCV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "keystone.h"
+
+typedef enum ks_err_asm_riscv {
+ KS_ERR_ASM_RISCV_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_RISCV_MISSINGFEATURE,
+ KS_ERR_ASM_RISCV_MNEMONICFAIL,
+} ks_err_asm_riscv;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/dependencies/keystone/include/keystone/sparc.h b/hyperdbg/dependencies/keystone/include/keystone/sparc.h
new file mode 100644
index 00000000..e49c4264
--- /dev/null
+++ b/hyperdbg/dependencies/keystone/include/keystone/sparc.h
@@ -0,0 +1,24 @@
+/* Keystone Assembler Engine */
+/* By Nguyen Anh Quynh, 2016 */
+
+#ifndef KEYSTONE_SPARC_H
+#define KEYSTONE_SPARC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "keystone.h"
+
+typedef enum ks_err_asm_sparc {
+ KS_ERR_ASM_SPARC_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_SPARC_MISSINGFEATURE,
+ KS_ERR_ASM_SPARC_MNEMONICFAIL,
+} ks_err_asm_sparc;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/dependencies/keystone/include/keystone/systemz.h b/hyperdbg/dependencies/keystone/include/keystone/systemz.h
new file mode 100644
index 00000000..ec2b07a4
--- /dev/null
+++ b/hyperdbg/dependencies/keystone/include/keystone/systemz.h
@@ -0,0 +1,24 @@
+/* Keystone Assembler Engine */
+/* By Nguyen Anh Quynh, 2016 */
+
+#ifndef KEYSTONE_SYSTEMZ_H
+#define KEYSTONE_SYSTEMZ_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "keystone.h"
+
+typedef enum ks_err_asm_systemz {
+ KS_ERR_ASM_SYSTEMZ_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_SYSTEMZ_MISSINGFEATURE,
+ KS_ERR_ASM_SYSTEMZ_MNEMONICFAIL,
+} ks_err_asm_systemz;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/dependencies/keystone/include/keystone/x86.h b/hyperdbg/dependencies/keystone/include/keystone/x86.h
new file mode 100644
index 00000000..1fac684e
--- /dev/null
+++ b/hyperdbg/dependencies/keystone/include/keystone/x86.h
@@ -0,0 +1,23 @@
+/* Keystone Assembler Engine */
+/* By Nguyen Anh Quynh, 2016 */
+
+#ifndef KEYSTONE_X86_H
+#define KEYSTONE_X86_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "keystone.h"
+
+typedef enum ks_err_asm_x86 {
+ KS_ERR_ASM_X86_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_X86_MISSINGFEATURE,
+ KS_ERR_ASM_X86_MNEMONICFAIL,
+} ks_err_asm_x86;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
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 c827cf47..0e114472 160000
--- a/hyperdbg/dependencies/pdbex
+++ b/hyperdbg/dependencies/pdbex
@@ -1 +1 @@
-Subproject commit c827cf477cc7de8fb08b989fa7bbcde439a17712
+Subproject commit 0e1144729a5b2d737cce11d1c0e083033630fff8
diff --git a/hyperdbg/dependencies/phnt b/hyperdbg/dependencies/phnt
deleted file mode 160000
index 619cbb46..00000000
--- a/hyperdbg/dependencies/phnt
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 619cbb4672c6739bcd0302a1d542f34f51effe93
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/hprdbgctrl/code/app/hprdbgctrl.cpp b/hyperdbg/hprdbgctrl/code/app/hprdbgctrl.cpp
deleted file mode 100644
index 533406d9..00000000
--- a/hyperdbg/hprdbgctrl/code/app/hprdbgctrl.cpp
+++ /dev/null
@@ -1,749 +0,0 @@
-/**
- * @file hprdbgctrl.cpp
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief Main interface to connect applications to driver
- * @details
- * @version 0.1
- * @date 2020-04-11
- *
- * @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_IsVmxOffProcessStart;
-extern Callback g_MessageHandler;
-extern TCHAR g_DriverLocation[MAX_PATH];
-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 LIST_ENTRY g_OutputSources;
-
-/**
- * @brief Set the function callback that will be called if any message
- * needs to be shown
- *
- * @param handler Function that handles the messages
- */
-VOID
-HyperDbgSetTextMessageCallback(Callback handler)
-{
- g_MessageHandler = handler;
-}
-
-/**
- * @brief Show messages
- *
- * @param Fmt format string message
- */
-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
- //
- g_MessageHandler(TempMessage);
- }
- }
-}
-
-/**
- * @brief Read kernel buffers using IRP Pending
- *
- * @param Device Driver handle
- */
-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 Install VMM driver
- *
- * @return int return zero if it was successful or non-zero if there
- * was error
- */
-HPRDBGCTRL_API int
-HyperDbgInstallVmmDriver()
-{
- //
- // The driver is not started yet so let us the install driver
- // First setup full path to driver name
- //
-
- if (!SetupDriverName(KERNEL_DEBUGGER_DRIVER_NAME, g_DriverLocation, sizeof(g_DriverLocation)))
- {
- return 1;
- }
-
- if (!ManageDriver(KERNEL_DEBUGGER_DRIVER_NAME, g_DriverLocation, DRIVER_FUNC_INSTALL))
- {
- ShowMessages("unable to install VMM driver\n");
-
- //
- // Error - remove driver
- //
- ManageDriver(KERNEL_DEBUGGER_DRIVER_NAME, 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 Stop VMM driver
- *
- * @return int return zero if it was successful or non-zero if there
- * was error
- */
-HPRDBGCTRL_API int
-HyperDbgStopVmmDriver()
-{
- return HyperDbgStopDriver(KERNEL_DEBUGGER_DRIVER_NAME);
-}
-
-/**
- * @brief Remove the driver
- *
- * @return int return zero if it was successful or non-zero if there
- * was error
- */
-int
-HyperDbgUninstallDriver(LPCTSTR DriverName)
-{
- //
- // Unload the driver if loaded. Ignore any errors
- //
- if (g_DriverLocation[0] != (TCHAR)0 && ManageDriver(DriverName, g_DriverLocation, DRIVER_FUNC_REMOVE))
- {
- return 0;
- }
- else
- {
- return 1;
- }
-}
-
-/**
- * @brief Remove the VMM driver
- *
- * @return int return zero if it was successful or non-zero if there
- * was error
- */
-HPRDBGCTRL_API int
-HyperDbgUninstallVmmDriver()
-{
- return HyperDbgUninstallDriver(KERNEL_DEBUGGER_DRIVER_NAME);
-}
-
-/**
- * @brief Load the VMM driver
- *
- * @return int return zero if it was successful or non-zero if there
- * was error
- */
-HPRDBGCTRL_API int
-HyperDbgLoadVmm()
-{
- char CpuId[13] = {0};
- DWORD ErrorNum;
- DWORD ThreadId;
-
- if (g_DeviceHandle)
- {
- ShowMessages("handle of the driver found, if you use 'load' before, please "
- "unload it using 'unload'\n");
- return 1;
- }
-
- //
- // Read the vendor string
- //
- HyperDbgReadVendorString(CpuId);
-
- ShowMessages("current processor vendor is : %s\n", CpuId);
-
- if (strcmp(CpuId, "GenuineIntel") == 0)
- {
- ShowMessages("virtualization technology is vt-x\n");
- }
- else
- {
- ShowMessages("this program is not designed to run in a non-VT-x "
- "environment !\n");
- return 1;
- }
-
- if (HyperDbgVmxSupportDetection())
- {
- ShowMessages("vmx operation is supported by your processor\n");
- }
- else
- {
- ShowMessages("vmx operation is not supported by your processor\n");
- return 1;
- }
-
- //
- // Make sure that this variable is false, because it might be set to
- // true as the result of a previous load
- //
- g_IsVmxOffProcessStart = FALSE;
-
- //
- // Init entering vmx
- //
- g_DeviceHandle = 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 (g_DeviceHandle == 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 (%x)\n", ErrorNum);
- }
-
- g_DeviceHandle = NULL;
- return 1;
- }
-
- //
- // Initialize the list of events
- //
- InitializeListHead(&g_EventTrace);
-
-#if !UseDbgPrintInsteadOfUsermodeMessageTracking
- HANDLE Thread = CreateThread(NULL, 0, IrpBasedBufferThread, NULL, 0, &ThreadId);
-
- // if (Thread)
- // {
- // ShowMessages("thread Created successfully\n");
- // }
-
-#endif
-
- return 0;
-}
-
-/**
- * @brief Unload VMM driver
- *
- * @return int return zero if it was successful or non-zero if there
- * was error
- */
-HPRDBGCTRL_API int
-HyperDbgUnloadVmm()
-{
- BOOL Status;
-
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnOne);
-
- ShowMessages("start terminating...\n");
-
- //
- // Uninitialize the user debugger if it's initialized
- //
- UdUninitializeUserDebugger();
-
- //
- // Send IOCTL to mark complete all IRP Pending
- //
- Status = DeviceIoControl(g_DeviceHandle, // Handle to device
- IOCTL_TERMINATE_VMX, // 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.
- 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;
- }
-
- //
- // 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
- 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.
- 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;
- }
-
- //
- // Indicate that the finish process start or not
- //
- g_IsVmxOffProcessStart = TRUE;
-
- Sleep(1000); // Wait so next thread can return from IRP Pending
-
- //
- // Send IRP_MJ_CLOSE to driver to terminate Vmxs
- //
- if (!CloseHandle(g_DeviceHandle))
- {
- ShowMessages("err, closing handle 0x%x\n", GetLastError());
- return 1;
- };
-
- //
- // Null the handle to indicate that the driver's device is not ready
- // to use
- //
- g_DeviceHandle = NULL;
-
- //
- // Debugger module is not loaded anymore
- //
- g_IsDebuggerModulesLoaded = FALSE;
-
- //
- // Check if we found an already built symbol table
- //
- SymbolDeleteSymTable();
-
- ShowMessages("you're not on HyperDbg's hypervisor anymore!\n");
-
- return 0;
-}
diff --git a/hyperdbg/hprdbgctrl/code/common/list.cpp b/hyperdbg/hprdbgctrl/code/common/list.cpp
deleted file mode 100644
index 58c2fc44..00000000
--- a/hyperdbg/hprdbgctrl/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/hprdbgctrl/code/debugger/commands/debugging-commands/bp.cpp b/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/bp.cpp
deleted file mode 100644
index 26c4e9a1..00000000
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/bp.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/**
- * @file bp.cpp
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief bp command
- * @details
- * @version 0.1
- * @date 2021-10-03
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#include "pch.h"
-
-//
-// Global Variables
-//
-extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
-
-/**
- * @brief help of the bp command
- *
- * @return VOID
- */
-VOID
-CommandBpHelp()
-{
- ShowMessages("bp : puts a breakpoint (0xcc).\n");
-
- ShowMessages(
- "Note : 'bp' is not an event, if you want to use an event version "
- "of breakpoints use !epthook or !epthook2 instead. See "
- "documentation for more information.\n\n");
-
- ShowMessages("syntax : \tbp [Address (hex)] [pid ProcessId (hex)] [tid ThreadId (hex)] [core CoreId (hex)]\n");
-
- ShowMessages("\n");
- ShowMessages("\t\te.g : bp nt!ExAllocatePoolWithTag\n");
- ShowMessages("\t\te.g : bp nt!ExAllocatePoolWithTag+5\n");
- ShowMessages("\t\te.g : bp nt!ExAllocatePoolWithTag+@rcx+rbx\n");
- ShowMessages("\t\te.g : bp fffff8077356f010\n");
- ShowMessages("\t\te.g : bp fffff8077356f010 pid 0x4\n");
- ShowMessages("\t\te.g : bp fffff8077356f010 tid 0x1000\n");
- ShowMessages("\t\te.g : bp fffff8077356f010 pid 0x4 core 2\n");
-}
-
-/**
- * @brief bp command handler
- *
- * @param SplitCommand
- * @param Command
- * @return VOID
- */
-VOID
-CommandBp(vector SplitCommand, string Command)
-{
- BOOL IsNextCoreId = FALSE;
- BOOL IsNextPid = FALSE;
- BOOL IsNextTid = FALSE;
-
- BOOLEAN SetCoreId = FALSE;
- BOOLEAN SetPid = FALSE;
- BOOLEAN SetTid = FALSE;
- BOOLEAN SetAddress = FALSE;
-
- UINT32 Tid = DEBUGGEE_BP_APPLY_TO_ALL_THREADS;
- UINT32 Pid = DEBUGGEE_BP_APPLY_TO_ALL_PROCESSES;
- UINT32 CoreNumer = DEBUGGEE_BP_APPLY_TO_ALL_CORES;
- UINT64 Address = NULL;
- vector SplitCommandCaseSensitive {Split(Command, ' ')};
- UINT32 IndexInCommandCaseSensitive = 0;
- BOOLEAN IsFirstCommand = TRUE;
-
- DEBUGGEE_BP_PACKET BpPacket = {0};
-
- if (SplitCommand.size() >= 9)
- {
- ShowMessages("incorrect use of the 'bp'\n\n");
- CommandBpHelp();
- return;
- }
-
- for (auto Section : SplitCommand)
- {
- IndexInCommandCaseSensitive++;
-
- //
- // Ignore the first argument as it's the command string itself (bp)
- //
- if (IsFirstCommand == TRUE)
- {
- IsFirstCommand = FALSE;
- continue;
- }
-
- if (IsNextCoreId)
- {
- if (!ConvertStringToUInt32(Section, &CoreNumer))
- {
- ShowMessages("please specify a correct hex value for core id\n\n");
- CommandBpHelp();
- return;
- }
- IsNextCoreId = FALSE;
- continue;
- }
- if (IsNextPid)
- {
- if (!ConvertStringToUInt32(Section, &Pid))
- {
- ShowMessages("please specify a correct hex value for process id\n\n");
- CommandBpHelp();
- return;
- }
- IsNextPid = FALSE;
- continue;
- }
-
- if (IsNextTid)
- {
- if (!ConvertStringToUInt32(Section, &Tid))
- {
- ShowMessages("please specify a correct hex value for thread id\n\n");
- CommandBpHelp();
- return;
- }
- IsNextTid = FALSE;
- continue;
- }
-
- if (!Section.compare("pid"))
- {
- IsNextPid = TRUE;
- continue;
- }
- if (!Section.compare("tid"))
- {
- IsNextTid = TRUE;
- continue;
- }
- if (!Section.compare("core"))
- {
- IsNextCoreId = TRUE;
- continue;
- }
-
- if (!SetAddress)
- {
- if (!SymbolConvertNameOrExprToAddress(SplitCommandCaseSensitive.at(IndexInCommandCaseSensitive - 1), &Address))
- {
- //
- // Couldn't resolve or unknown parameter
- //
- ShowMessages("err, couldn't resolve error at '%s'\n\n",
- SplitCommandCaseSensitive.at(IndexInCommandCaseSensitive - 1).c_str());
- CommandBpHelp();
- return;
- }
- else
- {
- //
- // Means that address is received
- //
- SetAddress = TRUE;
- continue;
- }
- }
- }
-
- //
- // Check if address is set or not
- //
- if (!SetAddress)
- {
- ShowMessages(
- "please specify a correct hex value as the breakpoint address\n\n");
- CommandBpHelp();
- return;
- }
- if (IsNextPid)
- {
- ShowMessages("please specify a correct hex value for process id\n\n");
- CommandBpHelp();
- return;
- }
- if (IsNextCoreId)
- {
- ShowMessages("please specify a correct hex value for core\n\n");
- CommandBpHelp();
- return;
- }
- if (IsNextTid)
- {
- ShowMessages("please specify a correct hex value for thread id\n\n");
- CommandBpHelp();
- return;
- }
-
- if (!g_IsSerialConnectedToRemoteDebuggee)
- {
- ShowMessages("err, setting breakpoints is not possible when you're not "
- "connected to a debuggee\n");
- return;
- }
-
- //
- // Set the details for the remote packet
- //
- BpPacket.Address = Address;
- BpPacket.Core = CoreNumer;
- BpPacket.Pid = Pid;
- BpPacket.Tid = Tid;
-
- //
- // Send the bp packet
- //
- KdSendBpPacketToDebuggee(&BpPacket);
-}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/e.cpp b/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/e.cpp
deleted file mode 100644
index c9906e93..00000000
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/e.cpp
+++ /dev/null
@@ -1,414 +0,0 @@
-/**
- * @file e.cpp
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief e* command
- * @details
- * @version 0.1
- * @date 2020-07-27
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#include "pch.h"
-
-//
-// Global Variables
-//
-extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
-extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
-
-/**
- * @brief help of !e* and e* commands
- *
- * @return VOID
- */
-VOID
-CommandEditMemoryHelp()
-{
- ShowMessages("eb !eb ed !ed eq !eq : edits the memory at specific address \n");
- ShowMessages("eb Byte and ASCII characters\n");
- ShowMessages("ed Double-word values (4 bytes)\n");
- ShowMessages("eq Quad-word values (8 bytes). \n");
-
- ShowMessages("\n If you want to edit physical (address) memory then add '!' "
- "at the start of the command\n");
-
- ShowMessages("syntax : \teb [Address (hex)] [Contents (hex)] [pid ProcessId (hex)]\n");
- ShowMessages("syntax : \ted [Address (hex)] [Contents (hex)] [pid ProcessId (hex)]\n");
- ShowMessages("syntax : \teq [Address (hex)] [Contents (hex)] [pid ProcessId (hex)]\n");
-
- ShowMessages("\n");
- ShowMessages("\t\te.g : eb fffff8077356f010 90 \n");
- ShowMessages("\t\te.g : eb nt!Kd_DEFAULT_Mask ff ff ff ff \n");
- ShowMessages("\t\te.g : eb nt!Kd_DEFAULT_Mask+10+@rcx ff ff ff ff \n");
- ShowMessages("\t\te.g : eb fffff8077356f010 90 90 90 90 \n");
- ShowMessages("\t\te.g : !eq 100000 9090909090909090\n");
- ShowMessages("\t\te.g : !eq nt!ExAllocatePoolWithTag+55 9090909090909090\n");
- ShowMessages("\t\te.g : !eq 100000 9090909090909090 9090909090909090 "
- "9090909090909090 9090909090909090 9090909090909090\n");
-}
-
-/**
- * @brief !e* and e* commands handler
- *
- * @param SplitCommand
- * @param Command
- * @return VOID
- */
-VOID
-CommandEditMemory(vector SplitCommand, string Command)
-{
- BOOL Status;
- UINT64 Address;
- UINT64 * FinalBuffer;
- vector ValuesToEdit;
- BOOL SetAddress = FALSE;
- BOOL SetValue = FALSE;
- BOOL SetProcId = FALSE;
- BOOL NextIsProcId = FALSE;
- DEBUGGER_EDIT_MEMORY EditMemoryRequest = {0};
- UINT64 Value = 0;
- UINT32 ProcId = 0;
- UINT32 CountOfValues = 0;
- UINT32 FinalSize = 0;
- vector SplitCommandCaseSensitive {Split(Command, ' ')};
- UINT32 IndexInCommandCaseSensitive = 0;
- BOOLEAN IsFirstCommand = TRUE;
-
- //
- // By default if the user-debugger is active, we use these commands
- // on the memory layout of the debuggee process
- //
- if (g_ActiveProcessDebuggingState.IsActive)
- {
- ProcId = g_ActiveProcessDebuggingState.ProcessId;
- }
-
- if (SplitCommand.size() <= 2)
- {
- ShowMessages("incorrect use of the 'e*'\n\n");
- CommandEditMemoryHelp();
- return;
- }
-
- for (auto Section : SplitCommand)
- {
- IndexInCommandCaseSensitive++;
-
- if (IsFirstCommand)
- {
- if (!Section.compare("!eb"))
- {
- EditMemoryRequest.MemoryType = EDIT_PHYSICAL_MEMORY;
- EditMemoryRequest.ByteSize = EDIT_BYTE;
- }
- else if (!Section.compare("!ed"))
- {
- EditMemoryRequest.MemoryType = EDIT_PHYSICAL_MEMORY;
- EditMemoryRequest.ByteSize = EDIT_DWORD;
- }
- else if (!Section.compare("!eq"))
- {
- EditMemoryRequest.MemoryType = EDIT_PHYSICAL_MEMORY;
- EditMemoryRequest.ByteSize = EDIT_QWORD;
- }
- else if (!Section.compare("eb"))
- {
- EditMemoryRequest.MemoryType = EDIT_VIRTUAL_MEMORY;
- EditMemoryRequest.ByteSize = EDIT_BYTE;
- }
- else if (!Section.compare("ed"))
- {
- EditMemoryRequest.MemoryType = EDIT_VIRTUAL_MEMORY;
- EditMemoryRequest.ByteSize = EDIT_DWORD;
- }
- else if (!Section.compare("eq"))
- {
- EditMemoryRequest.MemoryType = EDIT_VIRTUAL_MEMORY;
- EditMemoryRequest.ByteSize = EDIT_QWORD;
- }
- else
- {
- //
- // What's this? :(
- //
- ShowMessages("unknown error happened !\n\n");
- CommandEditMemoryHelp();
- return;
- }
-
- IsFirstCommand = FALSE;
-
- continue;
- }
-
- if (NextIsProcId)
- {
- //
- // It's a process id
- //
- NextIsProcId = FALSE;
-
- if (!ConvertStringToUInt32(Section, &ProcId))
- {
- ShowMessages("please specify a correct hex process id\n\n");
- CommandEditMemoryHelp();
- return;
- }
- else
- {
- //
- // Means that the proc id is set, next we should read value
- //
- continue;
- }
- }
-
- //
- // Check if it's a process id or not
- //
- if (!SetProcId && !Section.compare("pid"))
- {
- NextIsProcId = TRUE;
- continue;
- }
-
- if (!SetAddress)
- {
- if (!SymbolConvertNameOrExprToAddress(SplitCommandCaseSensitive.at(IndexInCommandCaseSensitive - 1),
- &Address))
- {
- ShowMessages("err, couldn't resolve error at '%s'\n\n",
- SplitCommandCaseSensitive.at(IndexInCommandCaseSensitive - 1).c_str());
- CommandEditMemoryHelp();
- return;
- }
- else
- {
- //
- // Means that the address is set, next we should read value
- //
- SetAddress = TRUE;
- continue;
- }
- }
-
- if (SetAddress)
- {
- //
- // Remove the hex notations
- //
- if (Section.rfind("0x", 0) == 0 || Section.rfind("0X", 0) == 0 ||
- Section.rfind("\\x", 0) == 0 || Section.rfind("\\X", 0) == 0)
- {
- Section = Section.erase(0, 2);
- }
- else if (Section.rfind('x', 0) == 0 || Section.rfind('X', 0) == 0)
- {
- Section = Section.erase(0, 1);
- }
- Section.erase(remove(Section.begin(), Section.end(), '`'), Section.end());
-
- //
- // Check if the value is valid based on byte counts
- //
- if (EditMemoryRequest.ByteSize == EDIT_BYTE && Section.size() >= 3)
- {
- ShowMessages("please specify a byte (hex) value for 'eb' or '!eb'\n\n");
- return;
- }
- if (EditMemoryRequest.ByteSize == EDIT_DWORD && Section.size() >= 9)
- {
- ShowMessages(
- "please specify a dword (hex) value for 'ed' or '!ed'\n\n");
- return;
- }
- if (EditMemoryRequest.ByteSize == EDIT_QWORD && Section.size() >= 17)
- {
- ShowMessages(
- "please specify a qword (hex) value for 'eq' or '!eq'\n\n");
- return;
- }
-
- //
- // Qword is checked by the following function, no need to double
- // check it above.
- //
-
- if (!ConvertStringToUInt64(Section, &Value))
- {
- ShowMessages("please specify a correct hex value to change the memory "
- "content\n\n");
- CommandEditMemoryHelp();
- return;
- }
- else
- {
- //
- // Add it to the list
- //
-
- ValuesToEdit.push_back(Value);
-
- //
- // Keep track of values to modify
- //
- CountOfValues++;
-
- if (!SetValue)
- {
- //
- // At least on value is there
- //
- SetValue = TRUE;
- }
- continue;
- }
- }
- }
-
- //
- // Check to prevent using process id in e* commands
- //
- if (g_IsSerialConnectedToRemoteDebuggee && ProcId != 0)
- {
- ShowMessages(ASSERT_MESSAGE_CANNOT_SPECIFY_PID);
- return;
- }
-
- if (ProcId == 0)
- {
- ProcId = GetCurrentProcessId();
- }
-
- //
- // Fill the structure
- //
- EditMemoryRequest.ProcessId = ProcId;
- EditMemoryRequest.Address = Address;
- EditMemoryRequest.CountOf64Chunks = CountOfValues;
-
- //
- // Check if address and value are set or not
- //
- if (!SetAddress)
- {
- ShowMessages("please specify a correct hex address\n\n");
- CommandEditMemoryHelp();
- return;
- }
- if (!SetValue)
- {
- ShowMessages(
- "please specify a correct hex value as the content to edit\n\n");
- CommandEditMemoryHelp();
- return;
- }
- if (NextIsProcId)
- {
- ShowMessages("please specify a correct hex value as the process id\n\n");
- CommandEditMemoryHelp();
- return;
- }
-
- //
- // Now it's time to put everything together in one structure
- //
- FinalSize = (CountOfValues * sizeof(UINT64)) + SIZEOF_DEBUGGER_EDIT_MEMORY;
-
- //
- // Set the size
- //
- EditMemoryRequest.FinalStructureSize = FinalSize;
-
- //
- // Allocate structure + buffer
- //
- FinalBuffer = (UINT64 *)malloc(FinalSize);
-
- if (!FinalBuffer)
- {
- ShowMessages("unable to allocate memory\n\n");
- return;
- }
-
- //
- // Zero the buffer
- //
- ZeroMemory(FinalBuffer, FinalSize);
-
- //
- // Copy the structure on top of the allocated buffer
- //
- memcpy(FinalBuffer, &EditMemoryRequest, SIZEOF_DEBUGGER_EDIT_MEMORY);
-
- //
- // Put the values in 64 bit structures
- //
- std::copy(ValuesToEdit.begin(), ValuesToEdit.end(), (UINT64 *)((UINT64)FinalBuffer + SIZEOF_DEBUGGER_EDIT_MEMORY));
-
- //
- // send the request
- //
- if (g_IsSerialConnectedToRemoteDebuggee)
- {
- KdSendEditMemoryPacketToDebuggee((DEBUGGER_EDIT_MEMORY *)FinalBuffer, FinalSize);
- return;
- }
-
- //
- // It's on VMI mode
- //
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
-
- Status = DeviceIoControl(
- g_DeviceHandle, // Handle to device
- IOCTL_DEBUGGER_EDIT_MEMORY, // IO Control Code (IOCTL)
- FinalBuffer, // Input Buffer to driver.
- FinalSize, // Input buffer length
- &EditMemoryRequest, // Output Buffer from driver.
- SIZEOF_DEBUGGER_EDIT_MEMORY, // Length of output buffer in bytes.
- NULL, // Bytes placed in buffer.
- NULL // synchronous call
- );
-
- if (!Status)
- {
- free(FinalBuffer);
- ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
- return;
- }
-
- if (EditMemoryRequest.Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
- {
- //
- // Was successful, nothing to do
- //
- }
- else if (
- EditMemoryRequest.Result ==
- DEBUGGER_ERROR_EDIT_MEMORY_STATUS_INVALID_ADDRESS_BASED_ON_CURRENT_PROCESS)
- {
- ShowMessages("err, the address is invalid in system process layout\n");
- }
- else if (
- EditMemoryRequest.Result ==
- DEBUGGER_ERROR_EDIT_MEMORY_STATUS_INVALID_ADDRESS_BASED_ON_OTHER_PROCESS)
- {
- ShowMessages("err, the address is invalid based on your specific process id\n");
- }
- else if (EditMemoryRequest.Result ==
- DEBUGGER_ERROR_EDIT_MEMORY_STATUS_INVALID_PARAMETER)
- {
- ShowMessages("invalid parameter\n");
- }
- else
- {
- ShowErrorMessage(EditMemoryRequest.Result);
- }
-
- //
- // Free the malloc buffer
- //
- free(FinalBuffer);
-}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/load.cpp b/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/load.cpp
deleted file mode 100644
index 7dc5a1fe..00000000
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/load.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/**
- * @file load.cpp
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief load command
- * @details
- * @version 0.1
- * @date 2020-05-27
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#include "pch.h"
-
-//
-// Global Variables
-//
-extern HANDLE g_IsDriverLoadedSuccessfully;
-extern HANDLE g_DeviceHandle;
-extern BOOLEAN g_IsConnectedToHyperDbgLocally;
-extern BOOLEAN g_IsDebuggerModulesLoaded;
-
-/**
- * @brief help of the load command
- *
- * @return VOID
- */
-VOID
-CommandLoadHelp()
-{
- ShowMessages("load : installs the drivers and load the modules.\n\n");
-
- ShowMessages("syntax : \tload [ModuleName (string)]\n");
-
- ShowMessages("\n");
- ShowMessages("\t\te.g : load vmm\n");
-}
-
-/**
- * @brief load vmm module
- *
- * @return BOOLEAN
- */
-BOOLEAN
-CommandLoadVmmModule()
-{
- BOOL Status;
- HANDLE hToken;
-
- //
- // Enable Debug privilege
- //
- Status = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
- if (!Status)
- {
- ShowMessages("err, OpenProcessToken failed (%x)\n", GetLastError());
- return FALSE;
- }
-
- Status = SetPrivilege(hToken, SE_DEBUG_NAME, TRUE);
- if (!Status)
- {
- CloseHandle(hToken);
- return FALSE;
- }
-
- //
- // Install vmm driver
- //
- if (HyperDbgInstallVmmDriver() == 1)
- {
- return FALSE;
- }
-
- //
- // Create event to show if the hypervisor is loaded or not
- //
- g_IsDriverLoadedSuccessfully = CreateEvent(NULL, FALSE, FALSE, NULL);
-
- if (HyperDbgLoadVmm() == 1)
- {
- //
- // No need to handle anymore
- //
- CloseHandle(g_IsDriverLoadedSuccessfully);
- return FALSE;
- }
-
- //
- // Vmm module (Hypervisor) is loaded
- //
-
- //
- // We wait for the first message from the kernel debugger to continue
- //
- WaitForSingleObject(
- g_IsDriverLoadedSuccessfully,
- INFINITE);
-
- //
- // No need to handle anymore
- //
- CloseHandle(g_IsDriverLoadedSuccessfully);
-
- //
- // If we reach here so the module are loaded
- //
- g_IsDebuggerModulesLoaded = TRUE;
-
- ShowMessages("vmm module is running...\n");
-
- return TRUE;
-}
-
-/**
- * @brief load command handler
- *
- * @param SplitCommand
- * @param Command
- * @return VOID
- */
-VOID
-CommandLoad(vector SplitCommand, string Command)
-{
- if (SplitCommand.size() != 2)
- {
- ShowMessages("incorrect use of the 'load'\n\n");
- CommandLoadHelp();
- return;
- }
-
- if (!g_IsConnectedToHyperDbgLocally)
- {
- ShowMessages("you're not connected to any instance of HyperDbg, did you "
- "use '.connect'? \n");
- return;
- }
-
- //
- // Check for the module
- //
- if (!SplitCommand.at(1).compare("vmm"))
- {
- //
- // Check to make sure that the driver is not already loaded
- //
- if (g_DeviceHandle)
- {
- ShowMessages("handle of the driver found, if you use 'load' before, please "
- "first unload it then call 'unload'\n");
- return;
- }
-
- //
- // Load VMM Module
- //
- ShowMessages("loading the vmm driver\n");
-
- if (!CommandLoadVmmModule())
- {
- ShowMessages("failed to install or load the driver\n");
- return;
- }
-
- //
- // 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
- //
- SymbolLocalReload(GetCurrentProcessId());
- }
- else
- {
- //
- // Module not found
- //
- ShowMessages("err, module not found\n");
- }
-}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/print.cpp b/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/print.cpp
deleted file mode 100644
index a2fde89a..00000000
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/print.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/**
- * @file print.cpp
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @author M.H. Gholamrezaei (mh@hyperdbg.org)
- * @brief print command
- * @details
- * @version 0.1
- * @date 2020-10-08
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#include "pch.h"
-
-using namespace std;
-
-//
-// Global Variables
-//
-extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
-
-/**
- * @brief help of the print command
- *
- * @return VOID
- */
-VOID
-CommandPrintHelp()
-{
- ShowMessages("print : evaluates expressions.\n\n");
-
- ShowMessages("syntax : \tprint [Expression (string)]\n");
-
- ShowMessages("\n");
- ShowMessages("\t\te.g : print dq(poi(@rcx))\n");
-}
-
-/**
- * @brief handler of print command
- *
- * @param SplitCommand
- * @param Command
- * @return VOID
- */
-VOID
-CommandPrint(vector SplitCommand, string Command)
-{
- PVOID CodeBuffer;
- UINT64 BufferAddress;
- UINT32 BufferLength;
- UINT32 Pointer;
-
- if (SplitCommand.size() == 1)
- {
- ShowMessages("incorrect use of the 'print'\n\n");
- CommandPrintHelp();
- return;
- }
-
- //
- // Trim the command
- //
- Trim(Command);
-
- //
- // Remove print from it
- //
- Command.erase(0, SplitCommand.at(0).size());
-
- //
- // Trim it again
- //
- Trim(Command);
-
- //
- // Prepend and append 'print(' and ')'
- //
- 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");
- }
-}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/r.cpp b/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/r.cpp
deleted file mode 100644
index 02159c12..00000000
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/r.cpp
+++ /dev/null
@@ -1,365 +0,0 @@
-/**
- * @file r.cpp
- * @author Alee Amini (alee@hyperdbg.org)
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief r command
- * @details
- * @version 0.1
- * @date 2021-02-27
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#include "pch.h"
-
-// using namespace std;
-
-//
-// Global Variables
-//
-extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
-
-std::map RegistersMap = {
- {"rax", REGISTER_RAX},
- {"eax", REGISTER_EAX},
- {"ax", REGISTER_AX},
- {"ah", REGISTER_AH},
- {"al", REGISTER_AL},
- {"rbx", REGISTER_RBX},
- {"ebx", REGISTER_EBX},
- {"bx", REGISTER_BX},
- {"bh", REGISTER_BH},
- {"bl", REGISTER_BL},
- {"rcx", REGISTER_RCX},
- {"ecx", REGISTER_ECX},
- {"cx", REGISTER_CX},
- {"ch", REGISTER_CH},
- {"cl", REGISTER_CL},
- {"rdx", REGISTER_RDX},
- {"edx", REGISTER_EDX},
- {"dx", REGISTER_DX},
- {"dh", REGISTER_DH},
- {"dl", REGISTER_DL},
- {"rsi", REGISTER_RSI},
- {"esi", REGISTER_ESI},
- {"si", REGISTER_SI},
- {"sil", REGISTER_SIL},
- {"rdi", REGISTER_RDI},
- {"edi", REGISTER_EDI},
- {"di", REGISTER_DI},
- {"dil", REGISTER_DIL},
- {"rbp", REGISTER_RBP},
- {"ebp", REGISTER_EBP},
- {"bp", REGISTER_BP},
- {"bpl", REGISTER_BPL},
- {"rsp", REGISTER_RSP},
- {"esp", REGISTER_ESP},
- {"sp", REGISTER_SP},
- {"spl", REGISTER_SPL},
- {"r8", REGISTER_R8},
- {"r8d", REGISTER_R8D},
- {"r8w", REGISTER_R8W},
- {"r8h", REGISTER_R8H},
- {"r8l", REGISTER_R8L},
- {"r9", REGISTER_R9},
- {"r9d", REGISTER_R9D},
- {"r9w", REGISTER_R9W},
- {"r9h", REGISTER_R9H},
- {"r9l", REGISTER_R9L},
- {"r10", REGISTER_R10},
- {"r10d", REGISTER_R10D},
- {"r10w", REGISTER_R10W},
- {"r10h", REGISTER_R10H},
- {"r10l", REGISTER_R10L},
- {"r11", REGISTER_R11},
- {"r11d", REGISTER_R11D},
- {"r11w", REGISTER_R11W},
- {"r11h", REGISTER_R11H},
- {"r11l", REGISTER_R11L},
- {"r12", REGISTER_R12},
- {"r12d", REGISTER_R12D},
- {"r12w", REGISTER_R12W},
- {"r12h", REGISTER_R12H},
- {"r12l", REGISTER_R12L},
- {"r13", REGISTER_R13},
- {"r13d", REGISTER_R13D},
- {"r13w", REGISTER_R13W},
- {"r13h", REGISTER_R13H},
- {"r13l", REGISTER_R13L},
- {"r14", REGISTER_R14},
- {"r14d", REGISTER_R14D},
- {"r14w", REGISTER_R14W},
- {"r14h", REGISTER_R14H},
- {"r14l", REGISTER_R14L},
- {"r15", REGISTER_R15},
- {"r15d", REGISTER_R15D},
- {"r15w", REGISTER_R15W},
- {"r15h", REGISTER_R15H},
- {"r15l", REGISTER_R15L},
- {"ds", REGISTER_DS},
- {"es", REGISTER_ES},
- {"fs", REGISTER_FS},
- {"gs", REGISTER_GS},
- {"cs", REGISTER_CS},
- {"ss", REGISTER_SS},
- {"rflags", REGISTER_RFLAGS},
- {"eflags", REGISTER_EFLAGS},
- {"flags", REGISTER_FLAGS},
- {"cf", REGISTER_CF},
- {"pf", REGISTER_PF},
- {"af", REGISTER_AF},
- {"zf", REGISTER_ZF},
- {"sf", REGISTER_SF},
- {"tf", REGISTER_TF},
- {"if", REGISTER_IF},
- {"df", REGISTER_DF},
- {"of", REGISTER_OF},
- {"iopl", REGISTER_IOPL},
- {"nt", REGISTER_NT},
- {"rf", REGISTER_RF},
- {"vm", REGISTER_VM},
- {"ac", REGISTER_AC},
- {"vif", REGISTER_VIF},
- {"vip", REGISTER_VIP},
- {"id", REGISTER_ID},
- {"idtr", REGISTER_IDTR},
- {"gdtr", REGISTER_GDTR},
- {"ldtr", REGISTER_LDTR},
- {"tr", REGISTER_TR},
- {"cr0", REGISTER_CR0},
- {"cr2", REGISTER_CR2},
- {"cr3", REGISTER_CR3},
- {"cr4", REGISTER_CR4},
- {"cr8", REGISTER_CR8},
- {"dr0", REGISTER_DR0},
- {"dr1", REGISTER_DR1},
- {"dr2", REGISTER_DR2},
- {"dr3", REGISTER_DR3},
- {"dr6", REGISTER_DR6},
- {"dr7", REGISTER_DR7},
- {"rip", REGISTER_RIP},
- {"eip", REGISTER_EIP},
- {"ip", REGISTER_IP},
-};
-
-/**
- * @brief help of the r command
- *
- * @return VOID
- */
-VOID
-CommandRHelp()
-{
- ShowMessages("r : reads or modifies registers.\n\n");
-
- ShowMessages("syntax : \tr\n");
- ShowMessages("syntax : \tr [Register (string)] [= Expr (string)]\n");
-
- ShowMessages("\n");
- ShowMessages("\t\te.g : r\n");
- ShowMessages("\t\te.g : r @rax\n");
- ShowMessages("\t\te.g : r rax\n");
- ShowMessages("\t\te.g : r rax = 0x55\n");
- ShowMessages("\t\te.g : r rax = @rbx + @rcx + 0n10\n");
-}
-
-/**
- * @brief handler of r show all registers command
- *
- * @return BOOLEAN
- */
-
-VOID
-ShowAllRegisters()
-{
- DEBUGGEE_REGISTER_READ_DESCRIPTION RegState = {0};
- RegState.RegisterID = DEBUGGEE_SHOW_ALL_REGISTERS;
- KdSendReadRegisterPacketToDebuggee(&RegState);
-}
-/**
- * @brief handler of r command
- *
- * @param SplitCommand
- * @param Command
- * @return VOID
- */
-VOID
-CommandR(std::vector SplitCommand, std::string Command)
-{
- //
- // Interpret here
- //
- PVOID CodeBuffer;
- UINT64 BufferAddress;
- UINT32 BufferLength;
- UINT32 Pointer;
- REGS_ENUM RegKind;
- std::vector Tmp;
-
- std::string SetRegValue = "SetRegValue";
-
- if (SplitCommand[0] != "r")
- {
- return;
- }
-
- if (SplitCommand.size() == 1)
- {
- //
- // show all registers
- //
- if (g_IsSerialConnectedToRemoteDebuggee)
- {
- ShowAllRegisters();
- }
- else
- {
- ShowMessages("err, reading registers (r) is not valid in the current "
- "context, you should connect to a debuggee\n");
- }
-
- return;
- }
- //
- // clear additional space of the command string
- //
-
- //
- // if command does not contain a '=' means user wants to read it
- //
- if (Command.find('=', 0) == string::npos)
- {
- //
- // erase '=' from the string now we have just the name of register
- //
- Command.erase(0, 1);
- ReplaceAll(Command, "@", "");
- ReplaceAll(Command, " ", "");
- if (RegistersMap.find(Command) != RegistersMap.end())
- {
- RegKind = RegistersMap[Command];
- }
- else
- {
- //
- // set the Reg to -1(invalid register)
- //
- RegKind = (REGS_ENUM)-1;
- }
- if (RegKind != -1)
- {
- DEBUGGEE_REGISTER_READ_DESCRIPTION RegState = {0};
- RegState.RegisterID = RegKind;
-
- //
- // send the request
- //
- if (g_IsSerialConnectedToRemoteDebuggee)
- {
- KdSendReadRegisterPacketToDebuggee(&RegState);
- }
- else
- {
- ShowMessages("err, reading registers (r) is not valid in the current "
- "context, you should connect to a debuggee\n");
- }
- }
- else
- {
- ShowMessages("err, invalid register\n");
- }
- }
-
- //
- // if command contains a '=' means user wants modify the register
- //
-
- else if (Command.find('=', 0) != string::npos)
- {
- Command.erase(0, 1);
- Tmp = Split(Command, '=');
- if (Tmp.size() == 2)
- {
- ReplaceAll(Tmp[0], " ", "");
- string tmp = Tmp[0];
- if (RegistersMap.find(Tmp[0]) != RegistersMap.end())
- {
- RegKind = RegistersMap[Tmp[0]];
- }
- else
- {
- ReplaceAll(tmp, "@", "");
- if (RegistersMap.find(tmp) != RegistersMap.end())
- {
- RegKind = RegistersMap[tmp];
- }
- else
- {
- RegKind = (REGS_ENUM)-1;
- }
- }
- if (RegKind != -1)
- {
- //
- // send the request
- //
-
- SetRegValue = "@" + 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");
- }
- }
- else
- {
- //
- // error
- //
- ShowMessages("err, invalid register\n");
- }
- }
- }
-}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/unload.cpp b/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/unload.cpp
deleted file mode 100644
index 804e183c..00000000
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/unload.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/**
- * @file unload.cpp
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief unload command
- * @details
- * @version 0.1
- * @date 2020-05-27
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#include "pch.h"
-
-//
-// Global Variables
-//
-extern BOOLEAN g_IsConnectedToHyperDbgLocally;
-extern BOOLEAN g_IsDebuggerModulesLoaded;
-extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
-extern BOOLEAN g_IsSerialConnectedToRemoteDebugger;
-
-/**
- * @brief help of the unload command
- *
- * @return VOID
- */
-VOID
-CommandUnloadHelp()
-{
- ShowMessages(
- "unload : unloads the kernel modules and uninstalls the drivers.\n\n");
-
- ShowMessages("syntax : \tunload [remove] [ModuleName (string)]\n");
-
- ShowMessages("\n");
- ShowMessages("\t\te.g : unload vmm\n");
- ShowMessages("\t\te.g : unload remove vmm\n");
-}
-
-/**
- * @brief unload command handler
- *
- * @param SplitCommand
- * @param Command
- * @return VOID
- */
-VOID
-CommandUnload(vector SplitCommand, string Command)
-{
- if (SplitCommand.size() != 2 && SplitCommand.size() != 3)
- {
- ShowMessages("incorrect use of the 'unload'\n\n");
- CommandUnloadHelp();
- return;
- }
-
- //
- // Check for the module
- //
- if ((SplitCommand.size() == 2 && !SplitCommand.at(1).compare("vmm")) || (SplitCommand.size() == 3 && !SplitCommand.at(2).compare("vmm") && !SplitCommand.at(1).compare("remove")))
- {
- if (!g_IsConnectedToHyperDbgLocally)
- {
- 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)
- {
- HyperDbgUnloadVmm();
- }
- else
- {
- ShowMessages("there is nothing to unload\n");
- }
-
- //
- // Check to remove the driver
- //
- if (!SplitCommand.at(1).compare("remove"))
- {
- //
- // 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");
- }
- }
- else
- {
- //
- // Module not found
- //
- ShowMessages("err, module not found\n");
- }
-}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/extension-commands/hide.cpp b/hyperdbg/hprdbgctrl/code/debugger/commands/extension-commands/hide.cpp
deleted file mode 100644
index b4b373f5..00000000
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/extension-commands/hide.cpp
+++ /dev/null
@@ -1,287 +0,0 @@
-/**
- * @file hide.cpp
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief !hide command
- * @details
- * @version 0.1
- * @date 2020-07-07
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#include "pch.h"
-
-//
-// 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 ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
-
-/**
- * @brief help of the !hide command
- *
- * @return VOID
- */
-VOID
-CommandHideHelp()
-{
- ShowMessages("!hide : tries to make HyperDbg transparent from anti-debugging "
- "and anti-hypervisor methods.\n\n");
-
- ShowMessages("syntax : \t!hide\n");
- ShowMessages("syntax : \t!hide [pid ProcessId (hex)]\n");
- ShowMessages("syntax : \t!hide [name ProcessName (string)]\n");
-
- ShowMessages("note : \tprocess names are case sensitive and you can use "
- "this command multiple times.\n");
-
- ShowMessages("\n");
- ShowMessages("\t\te.g : !hide\n");
- ShowMessages("\t\te.g : !hide pid b60 \n");
- ShowMessages("\t\te.g : !hide name procexp.exe\n");
-}
-
-/**
- * @brief !hide command handler
- *
- * @param SplitCommand
- * @param Command
- * @return VOID
- */
-VOID
-CommandHide(vector SplitCommand, string Command)
-{
- BOOLEAN Status;
- ULONG ReturnedLength;
- UINT64 TargetPid;
- BOOLEAN TrueIfProcessIdAndFalseIfProcessName;
- DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE HideRequest = {0};
- PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE FinalRequestBuffer = 0;
- size_t RequestBufferSize = 0;
-
- if (SplitCommand.size() <= 2 && SplitCommand.size() != 1)
- {
- ShowMessages("incorrect use of the '!hide'\n\n");
- CommandHideHelp();
- return;
- }
-
- //
- // Find out whether the user enters pid or name
- //
- if (SplitCommand.size() == 1)
- {
- if (g_ActiveProcessDebuggingState.IsActive)
- {
- TrueIfProcessIdAndFalseIfProcessName = TRUE;
- TargetPid = g_ActiveProcessDebuggingState.ProcessId;
- }
- else
- {
- //
- // There is no user-debugging process
- //
- ShowMessages("you're not attached to any user-mode process, "
- "please explicitly specify the process id or process name\n");
- return;
- }
- }
- else if (!SplitCommand.at(1).compare("pid"))
- {
- TrueIfProcessIdAndFalseIfProcessName = TRUE;
-
- //
- // Check for the user to not add extra arguments
- //
- if (SplitCommand.size() != 3)
- {
- ShowMessages("incorrect use of the '!hide'\n\n");
- CommandHideHelp();
- return;
- }
-
- //
- // It's just a pid for the process
- //
- if (!ConvertStringToUInt64(SplitCommand.at(2), &TargetPid))
- {
- ShowMessages("incorrect process id\n\n");
- return;
- }
- }
- else if (!SplitCommand.at(1).compare("name"))
- {
- TrueIfProcessIdAndFalseIfProcessName = FALSE;
-
- //
- // Trim the command
- //
- Trim(Command);
-
- //
- // Remove !hide from it
- //
- Command.erase(0, SplitCommand.at(0).size());
-
- //
- // remove name + space
- //
- Command.erase(0, 4 + 1);
-
- //
- // Trim it again
- //
- Trim(Command);
- }
- else
- {
- //
- // Invalid argument for the second parameter to the command
- //
- ShowMessages("incorrect use of the '!hide'\n\n");
- CommandHideHelp();
- return;
- }
-
- //
- // Check if the user used !measure or not
- //
- if (!g_TransparentResultsMeasured || !g_CpuidAverage ||
- !g_CpuidStandardDeviation || !g_CpuidMedian)
- {
- ShowMessages("the average, median and standard deviation is not measured. "
- "Did you use '!measure' command?\n");
- return;
- }
-
- //
- // Check if debugger is loaded or not
- //
- AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
-
- //
- // We wanna hide the debugger and make transparent vm-exits
- //
- HideRequest.IsHide = TRUE;
-
- //
- // Set the measured times cpuid
- //
- HideRequest.CpuidAverage = g_CpuidAverage;
- HideRequest.CpuidMedian = g_CpuidMedian;
- HideRequest.CpuidStandardDeviation = g_CpuidStandardDeviation;
-
- //
- // Set the measured times rdtsc/p
- //
- HideRequest.RdtscAverage = g_RdtscAverage;
- HideRequest.RdtscMedian = g_RdtscMedian;
- HideRequest.RdtscStandardDeviation = g_RdtscStandardDeviation;
-
- HideRequest.TrueIfProcessIdAndFalseIfProcessName =
- TrueIfProcessIdAndFalseIfProcessName;
-
- if (TrueIfProcessIdAndFalseIfProcessName)
- {
- //
- // It's a process id
- //
- HideRequest.ProcId = (UINT32)TargetPid;
-
- RequestBufferSize = sizeof(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE);
- }
- else
- {
- //
- // It's a process name
- //
- HideRequest.LengthOfProcessName = (UINT32)Command.size() + 1;
- RequestBufferSize = sizeof(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE) + Command.size() + 1;
- }
-
- //
- // Allocate the requested buffer
- //
- FinalRequestBuffer =
- (PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE)malloc(RequestBufferSize);
-
- if (FinalRequestBuffer == NULL)
- {
- ShowMessages("insufficient space\n");
- return;
- }
-
- //
- // Zero the memory
- //
- RtlZeroMemory(FinalRequestBuffer, RequestBufferSize);
-
- //
- // Copy the buffer on the top of the final buffer
- // to send the kernel
- //
- memcpy(FinalRequestBuffer, &HideRequest, sizeof(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE));
-
- //
- // If it's a name then we should add it to the end of the buffer
- //
- memcpy(((UINT64 *)((UINT64)FinalRequestBuffer +
- sizeof(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE))),
- Command.c_str(),
- Command.size());
-
- //
- // Send the request to the kernel
- //
-
- Status = DeviceIoControl(
- g_DeviceHandle, // Handle to device
- IOCTL_DEBUGGER_HIDE_AND_UNHIDE_TO_TRANSPARENT_THE_DEBUGGER, // IO Control
- // code
- FinalRequestBuffer, // Input Buffer to driver.
- (DWORD)RequestBufferSize, // Input buffer length
- FinalRequestBuffer, // Output Buffer from driver.
- SIZEOF_DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE, // 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());
- free(FinalRequestBuffer);
- return;
- }
-
- if (FinalRequestBuffer->KernelStatus == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
- {
- ShowMessages("transparent debugging successfully enabled :)\n");
- }
- else if (FinalRequestBuffer->KernelStatus ==
- DEBUGGER_ERROR_UNABLE_TO_HIDE_OR_UNHIDE_DEBUGGER)
- {
- ShowMessages("unable to hide the debugger (transparent-debugging) :(\n");
- free(FinalRequestBuffer);
- return;
- }
- else
- {
- ShowMessages("unknown error occurred :(\n");
- free(FinalRequestBuffer);
- return;
- }
-
- //
- // free the buffer
- //
- free(FinalRequestBuffer);
-}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/extension-commands/rev.cpp b/hyperdbg/hprdbgctrl/code/debugger/commands/extension-commands/rev.cpp
deleted file mode 100644
index 9463196a..00000000
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/extension-commands/rev.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-/**
- * @file rev.cpp
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief !rev command
- * @details
- * @version 0.2
- * @date 2023-03-22
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#include "pch.h"
-
-//
-// Global Variables
-//
-extern BOOLEAN g_IsSerialConnectedToRemoteDebugger;
-extern std::wstring g_StartCommandPath;
-extern std::wstring g_StartCommandPathAndArguments;
-extern BOOLEAN g_IsSerialConnectedToRemoteDebugger;
-
-/**
- * @brief help of the !rev command
- *
- * @return VOID
- */
-VOID
-CommandRevHelp()
-{
- ShowMessages("!rev : uses the reversing machine module in order to reconstruct the programmer/memory assumptions.\n\n");
-
- ShowMessages("syntax : \t!rev [config] [pid ProcessId (hex)]\n");
- ShowMessages("syntax : \t!rev [path Path (string)] [Parameters (string)]\n");
-
- ShowMessages("\n");
- ShowMessages("\t\te.g : !rev path c:\\reverse eng\\my_file.exe\n");
- ShowMessages("\t\te.g : !rev pattern\n");
- ShowMessages("\t\te.g : !rev reconstruct\n");
- ShowMessages("\t\te.g : !rev pattern pid 1c0\n");
- ShowMessages("\t\te.g : !rev reconstruct pid 1c0\n");
-}
-
-/**
- * @brief !rev command handler
- *
- * @param SplitCommand
- * @param Command
- * @return VOID
- */
-VOID
-CommandRev(vector SplitCommand, string Command)
-{
- /*
- vector PathAndArgs;
- string Arguments = "";
-
- //
- // Disable user-mode debugger in this version
- //
-#if ActivateUserModeDebugger == FALSE
-
- if (!g_IsSerialConnectedToRemoteDebugger)
- {
- 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. "
- "if you want to test the user-mode debugger in VMI Mode, you should build "
- "HyperDbg with special instructions. But starting processes is fully supported "
- "in the Debugger Mode.\n"
- "(it's not recommended to use it in VMI Mode yet!)\n");
- return;
- }
-
-#endif // !ActivateUserModeDebugger
-
- if (SplitCommand.size() <= 2)
- {
- ShowMessages("incorrect use of the '.start'\n\n");
- CommandStartHelp();
- return;
- }
-
-
- if (!SplitCommand.at(1).compare("path"))
- {
- //
- // *** It's a run of target PE file ***
- //
-
- //
- // Trim the command
- //
- Trim(Command);
-
- //
- // Remove !rev from it
- //
- Command.erase(0, SplitCommand.at(0).size());
-
- //
- // Remove path + space
- //
- Command.erase(0, 4 + 1);
-
- //
- // Trim it again
- //
- Trim(Command);
-
- //
- // Split Path and args
- //
- SplitPathAndArgs(PathAndArgs, Command);
-
- //
- // Convert path to wstring
- //
- StringToWString(g_StartCommandPath, PathAndArgs.at(0));
-
- if (PathAndArgs.size() != 1)
- {
- //
- // There are arguments to this command
- //
-
- for (auto item : PathAndArgs)
- {
- //
- // Append the arguments
- //
- // ShowMessages("Arg : %s\n", item.c_str());
- Arguments += item + " ";
- }
-
- //
- // Remove the latest space
- //
- Arguments.pop_back();
-
- //
- // Convert arguments to wstring
- //
- StringToWString(g_StartCommandPathAndArguments, Arguments);
- }
- }
- else
- {
- ShowMessages("err, couldn't resolve error at '%s'\n\n",
- SplitCommand.at(1).c_str());
- CommandStartHelp();
- return;
- }
-
- //
- // Perform run of the target file
- //
- if (Arguments.empty())
- {
- UdAttachToProcess(NULL,
- g_StartCommandPath.c_str(),
- NULL,
- TRUE);
- }
- else
- {
- UdAttachToProcess(NULL,
- g_StartCommandPath.c_str(),
- (WCHAR *)g_StartCommandPathAndArguments.c_str(),
- TRUE);
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- return;
-
- */
-
- REVERSING_MACHINE_RECONSTRUCT_MEMORY_REQUEST RevRequest = {0};
- BOOLEAN SetPid = FALSE;
- UINT32 TargetPid = NULL;
- BOOLEAN IgnoreFirstCommand = TRUE;
- REVERSING_MACHINE_RECONSTRUCT_MEMORY_MODE Mode = REVERSING_MACHINE_RECONSTRUCT_MEMORY_MODE_UNKNOWN;
- REVERSING_MACHINE_RECONSTRUCT_MEMORY_TYPE Type = REVERSING_MACHINE_RECONSTRUCT_MEMORY_TYPE_UNKNOWN;
-
- //
- // Interpret command specific details
- //
- for (auto Section : SplitCommand)
- {
- if (!Section.compare("!rev") && IgnoreFirstCommand)
- {
- IgnoreFirstCommand = FALSE;
- continue;
- }
- else if (!Section.compare("pid") && !SetPid)
- {
- SetPid = TRUE;
- }
- else if (SetPid)
- {
- if (!ConvertStringToUInt32(Section, &TargetPid))
- {
- //
- // couldn't resolve or unknown parameter
- //
- ShowMessages("err, couldn't resolve error at '%s'\n\n",
- Section.c_str());
- CommandRevHelp();
- return;
- }
- SetPid = FALSE;
- }
- else if (!Section.compare("pattern"))
- {
- Type = REVERSING_MACHINE_RECONSTRUCT_MEMORY_TYPE_PATTERN;
- }
- else if (!Section.compare("reconstruct"))
- {
- Type = REVERSING_MACHINE_RECONSTRUCT_MEMORY_TYPE_RECONSTRUCT;
- }
- else
- {
- //
- // Unknown parameter
- //
- ShowMessages("err, couldn't resolve error at '%s'\n\n",
- Section.c_str());
- CommandRevHelp();
- return;
- }
- }
-
- if (SetPid)
- {
- ShowMessages("err, please enter a valid process id in hex format, "
- "or if you want to use it in decimal format, add '0n' "
- "prefix to the number\n");
- return;
- }
-
- RevRequest.ProcessId = TargetPid;
-
- // ================================================================================
-
- //
- // Send the request to the hypervisor (kernel)
- //
- RevRequestService(&RevRequest);
-}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/extension-commands/track.cpp b/hyperdbg/hprdbgctrl/code/debugger/commands/extension-commands/track.cpp
deleted file mode 100644
index 7efefe7f..00000000
Binary files a/hyperdbg/hprdbgctrl/code/debugger/commands/extension-commands/track.cpp and /dev/null differ
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/meta-commands/debug.cpp b/hyperdbg/hprdbgctrl/code/debugger/commands/meta-commands/debug.cpp
deleted file mode 100644
index 9f004f00..00000000
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/meta-commands/debug.cpp
+++ /dev/null
@@ -1,311 +0,0 @@
-/**
- * @file debug.cpp
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief .debug command
- * @details
- * @version 0.1
- * @date 2020-12-19
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#include "pch.h"
-
-//
-// 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
- *
- * @return VOID
- */
-VOID
-CommandDebugHelp()
-{
- ShowMessages(
- ".debug : debugs a target machine or makes this machine a debuggee.\n\n");
-
- ShowMessages(
- "syntax : \t.debug [remote] [serial|namedpipe] [Baudrate (decimal)] [Address (string)]\n");
- ShowMessages(
- "syntax : \t.debug [prepare] [serial] [Baudrate (decimal)] [Address (string)]\n");
- ShowMessages("syntax : \t.debug [close]\n");
-
- ShowMessages("\n");
- ShowMessages("\t\te.g : .debug remote serial 115200 com2\n");
- ShowMessages("\t\te.g : .debug remote namedpipe \\\\.\\pipe\\HyperDbgPipe\n");
- ShowMessages("\t\te.g : .debug prepare serial 115200 com1\n");
- ShowMessages("\t\te.g : .debug prepare serial 115200 com2\n");
- ShowMessages("\t\te.g : .debug close\n");
-
- ShowMessages(
- "\nvalid baud rates (decimal) : 110, 300, 600, 1200, 2400, 4800, 9600, "
- "14400, 19200, 38400, 56000, 57600, 115200, 128000, 256000\n");
- ShowMessages("valid COM ports : COM1, COM2, COM3, COM4 \n");
-}
-
-/**
- * @brief Check if baud rate is valid or not
- *
- * @param Baudrate
- * @return BOOLEAN
- */
-BOOLEAN
-CommandDebugCheckBaudrate(DWORD Baudrate)
-{
- if (Baudrate == CBR_110 || Baudrate == CBR_300 || Baudrate == CBR_600 ||
- Baudrate == CBR_1200 || Baudrate == CBR_2400 || Baudrate == CBR_4800 ||
- Baudrate == CBR_9600 || Baudrate == CBR_14400 || Baudrate == CBR_19200 ||
- Baudrate == CBR_38400 || Baudrate == CBR_56000 || Baudrate == CBR_57600 ||
- Baudrate == CBR_115200 || Baudrate == CBR_128000 ||
- Baudrate == CBR_256000)
- {
- return TRUE;
- }
- return FALSE;
-}
-
-/**
- * @brief Check if COM port is valid or not
- *
- * @param ComPort
- * @return BOOLEAN
- */
-BOOLEAN
-CommandDebugCheckComPort(const string & ComPort, UINT32 * Port)
-{
- if (!ComPort.compare("com1"))
- {
- *Port = COM1_PORT;
- return TRUE;
- }
- else if (!ComPort.compare("com2"))
- {
- *Port = COM2_PORT;
- return TRUE;
- }
- else if (!ComPort.compare("com3"))
- {
- *Port = COM3_PORT;
- return TRUE;
- }
- else if (!ComPort.compare("com4"))
- {
- *Port = COM4_PORT;
- return TRUE;
- }
-
- return FALSE;
-}
-
-/**
- * @brief .debug command handler
- *
- * @param SplitCommand
- * @param Command
- * @return VOID
- */
-VOID
-CommandDebug(vector SplitCommand, string Command)
-{
- UINT32 Baudrate;
- UINT32 Port;
-
- if (SplitCommand.size() == 2 && !SplitCommand.at(1).compare("close"))
- {
- //
- // Check if the debugger is attached to a debuggee
- //
- if (g_IsSerialConnectedToRemoteDebuggee)
- {
- KdCloseConnection();
- }
- else
- {
- ShowMessages(
- "err, debugger is not attached to any instance of debuggee\n");
- }
- return;
- }
- else if (SplitCommand.size() <= 3)
- {
- ShowMessages("incorrect use of the '.debug'\n\n");
- CommandDebugHelp();
- return;
- }
-
- //
- // Check the main command
- //
- if (!SplitCommand.at(1).compare("remote"))
- {
- //
- // in the case of the 'remote'
- //
-
- if (!SplitCommand.at(2).compare("serial"))
- {
- //
- // Connect to a remote serial device
- //
- if (SplitCommand.size() != 5)
- {
- ShowMessages("incorrect use of the '.debug'\n\n");
- CommandDebugHelp();
- return;
- }
-
- //
- // Set baudrate
- //
- if (!IsNumber(SplitCommand.at(3)))
- {
- //
- // Unknown parameter
- //
- ShowMessages("unknown parameter '%s'\n\n",
- SplitCommand.at(3).c_str());
- CommandDebugHelp();
- return;
- }
-
- Baudrate = stoi(SplitCommand.at(3));
-
- //
- // Check if baudrate is valid or not
- //
- if (!CommandDebugCheckBaudrate(Baudrate))
- {
- //
- // Baud-rate is invalid
- //
- ShowMessages("err, baud rate is invalid\n\n");
- CommandDebugHelp();
- return;
- }
-
- //
- // check if com port address is valid or not
- //
- if (!CommandDebugCheckComPort(SplitCommand.at(4), &Port))
- {
- //
- // com port is invalid
- //
- ShowMessages("err, COM port is invalid\n\n");
- CommandDebugHelp();
- return;
- }
-
- //
- // Everything is okay, connect to the remote machine to send (debugger)
- //
- KdPrepareAndConnectDebugPort(SplitCommand.at(4).c_str(), Baudrate, Port, FALSE, FALSE);
- }
- else if (!SplitCommand.at(2).compare("namedpipe"))
- {
- //
- // Connect to a remote namedpipe
- //
- string Delimiter = "namedpipe";
- string Token = Command.substr(
- Command.find(Delimiter) + Delimiter.size() + 1,
- Command.size());
-
- //
- // Connect to a namedpipe (it's probably a Virtual Machine debugging)
- //
- KdPrepareAndConnectDebugPort(Token.c_str(), NULL, NULL, FALSE, TRUE);
- }
- else
- {
- //
- // Unknown parameter
- //
- ShowMessages("unknown parameter '%s'\n\n", SplitCommand.at(2).c_str());
- CommandDebugHelp();
- return;
- }
- }
- else if (!SplitCommand.at(1).compare("prepare"))
- {
- if (SplitCommand.size() != 5)
- {
- ShowMessages("incorrect use of the '.debug'\n\n");
- CommandDebugHelp();
- return;
- }
-
- //
- // in the case of the 'prepare'
- // currently we only support serial
- //
- if (!SplitCommand.at(2).compare("serial"))
- {
- //
- // Set baudrate
- //
- if (!IsNumber(SplitCommand.at(3)))
- {
- //
- // Unknown parameter
- //
- ShowMessages("unknown parameter '%s'\n\n",
- SplitCommand.at(3).c_str());
- CommandDebugHelp();
- return;
- }
-
- Baudrate = stoi(SplitCommand.at(3));
-
- //
- // Check if baudrate is valid or not
- //
- if (!CommandDebugCheckBaudrate(Baudrate))
- {
- //
- // Baud-rate is invalid
- //
- ShowMessages("err, baud rate is invalid\n\n");
- CommandDebugHelp();
- return;
- }
-
- //
- // check if com port address is valid or not
- //
- if (!CommandDebugCheckComPort(SplitCommand.at(4), &Port))
- {
- //
- // com port is invalid
- //
- ShowMessages("err, COM port is invalid\n\n");
- CommandDebugHelp();
- return;
- }
-
- //
- // Everything is okay, prepare to send (debuggee)
- //
- KdPrepareAndConnectDebugPort(SplitCommand.at(4).c_str(), Baudrate, Port, TRUE, FALSE);
- }
- else
- {
- ShowMessages("invalid parameter '%s'\n\n", SplitCommand.at(2));
- CommandDebugHelp();
- return;
- }
- }
- else
- {
- ShowMessages("invalid parameter '%s'\n\n", SplitCommand.at(1));
- CommandDebugHelp();
- return;
- }
-}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/meta-commands/pe.cpp b/hyperdbg/hprdbgctrl/code/debugger/commands/meta-commands/pe.cpp
deleted file mode 100644
index 3130b674..00000000
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/meta-commands/pe.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/**
- * @file pe.cpp
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief .pe command
- * @details
- * @version 0.1
- * @date 2021-12-27
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#include "pch.h"
-
-using namespace std;
-
-/**
- * @brief help of the .pe command
- *
- * @return VOID
- */
-VOID
-CommandPeHelp()
-{
- ShowMessages(".pe : parses portable executable (PE) files and dump sections.\n\n");
-
- ShowMessages("syntax : \t.pe [header] [FilePath (string)]\n");
- ShowMessages("syntax : \t.pe [section] [SectionName (string)] [FilePath (string)]\n");
-
- ShowMessages("\n");
- ShowMessages("\t\te.g : .pe header c:\\reverse files\\myfile.exe\n");
- ShowMessages("\t\te.g : .pe section .text c:\\reverse files\\myfile.exe\n");
- ShowMessages("\t\te.g : .pe section .rdata c:\\reverse files\\myfile.exe\n");
-}
-
-/**
- * @brief .pe command handler
- *
- * @param SplitCommand
- * @param Command
- * @return VOID
- */
-VOID
-CommandPe(vector SplitCommand, string Command)
-{
- BOOLEAN Is32Bit = FALSE;
- wstring Filepath;
- BOOLEAN ShowDumpOfSection = FALSE;
-
- if (SplitCommand.size() <= 2)
- {
- ShowMessages("err, incorrect use of the '.pe' command\n\n");
- CommandPeHelp();
- return;
- }
-
- //
- // Check for first option
- //
- if (!SplitCommand.at(1).compare("section"))
- {
- if (SplitCommand.size() == 3)
- {
- ShowMessages("please specify a valid PE file\n\n");
- CommandPeHelp();
- return;
- }
- ShowDumpOfSection = TRUE;
- }
- else if (!SplitCommand.at(1).compare("header"))
- {
- ShowDumpOfSection = FALSE;
- }
- else
- {
- //
- // Couldn't resolve or unknown parameter
- //
- ShowMessages("err, couldn't resolve error at '%s'\n\n",
- SplitCommand.at(1).c_str());
- CommandPeHelp();
- return;
- }
-
- //
- // Trim the command
- //
- Trim(Command);
-
- //
- // Remove .pe from it
- //
- Command.erase(0, SplitCommand.at(0).size());
-
- if (!ShowDumpOfSection)
- {
- //
- // Remove header + space
- //
- Command.erase(0, 6 + 1);
- }
- else
- {
- //
- // Remove section + space
- //
- Command.erase(0, 7 + 1);
-
- //
- // Remove the string param for section + space
- //
- Command.erase(0, SplitCommand.at(2).size() + 1);
- }
-
- //
- // Trim it again
- //
- Trim(Command);
-
- //
- // Convert path to wstring
- //
- StringToWString(Filepath, Command);
-
- //
- // Detect whether PE is 32-bit or 64-bit
- //
- if (!PeIsPE32BitOr64Bit(Filepath.c_str(), &Is32Bit))
- {
- //
- // File was invalid, the error message is shown in the above function
- //
- return;
- }
-
- //
- // Parse PE file
- //
- if (!ShowDumpOfSection)
- {
- PeShowSectionInformationAndDump(Filepath.c_str(), NULL, Is32Bit);
- }
- else
- {
- PeShowSectionInformationAndDump(Filepath.c_str(), SplitCommand.at(2).c_str(), Is32Bit);
- }
-}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/meta-commands/start.cpp b/hyperdbg/hprdbgctrl/code/debugger/commands/meta-commands/start.cpp
deleted file mode 100644
index 072964ca..00000000
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/meta-commands/start.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-/**
- * @file start.cpp
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief .start command
- * @details
- * @version 0.1
- * @date 2022-01-06
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#include "pch.h"
-
-//
-// Global Variables
-//
-extern std::wstring g_StartCommandPath;
-extern std::wstring g_StartCommandPathAndArguments;
-extern BOOLEAN g_IsSerialConnectedToRemoteDebugger;
-
-/**
- * @brief help of the .start command
- *
- * @return VOID
- */
-VOID
-CommandStartHelp()
-{
- ShowMessages(".start : runs a user-mode process.\n\n");
-
- ShowMessages("syntax : \t.start [path Path (string)] [Parameters (string)]\n");
-
- ShowMessages("\n");
- ShowMessages("\t\te.g : .start path c:\\reverse eng\\my_file.exe\n");
-}
-
-/**
- * @brief .start command handler
- *
- * @param SplitCommand
- * @param Command
- * @return VOID
- */
-VOID
-CommandStart(vector SplitCommand, string Command)
-{
- vector PathAndArgs;
- string Arguments = "";
-
- //
- // Disable user-mode debugger in this version
- //
-#if ActivateUserModeDebugger == FALSE
-
- if (!g_IsSerialConnectedToRemoteDebugger)
- {
- 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. "
- "if you want to test the user-mode debugger in VMI Mode, you should build "
- "HyperDbg with special instructions. But starting processes is fully supported "
- "in the Debugger Mode.\n"
- "(it's not recommended to use it in VMI Mode yet!)\n");
- return;
- }
-
-#endif // !ActivateUserModeDebugger
-
- if (SplitCommand.size() <= 2)
- {
- ShowMessages("incorrect use of the '.start'\n\n");
- CommandStartHelp();
- return;
- }
-
- if (!SplitCommand.at(1).compare("path"))
- {
- //
- // *** It's a run of target PE file ***
- //
-
- //
- // Trim the command
- //
- Trim(Command);
-
- //
- // Remove '.start' or 'start' from it
- //
- Command.erase(0, SplitCommand.at(0).size());
-
- //
- // Remove path + space
- //
- Command.erase(0, 4 + 1);
-
- //
- // Trim it again
- //
- Trim(Command);
-
- //
- // Split Path and args
- //
- SplitPathAndArgs(PathAndArgs, Command);
-
- //
- // Convert path to wstring
- //
- StringToWString(g_StartCommandPath, PathAndArgs.at(0));
-
- if (PathAndArgs.size() != 1)
- {
- //
- // There are arguments to this command
- //
-
- for (auto item : PathAndArgs)
- {
- //
- // Append the arguments
- //
- // ShowMessages("Arg : %s\n", item.c_str());
- Arguments += item + " ";
- }
-
- //
- // Remove the latest space
- //
- Arguments.pop_back();
-
- //
- // Convert arguments to wstring
- //
- StringToWString(g_StartCommandPathAndArguments, Arguments);
- }
- }
- else
- {
- ShowMessages("err, couldn't resolve error at '%s'\n\n",
- SplitCommand.at(1).c_str());
- CommandStartHelp();
- return;
- }
-
- //
- // Perform run of the target file
- //
- if (Arguments.empty())
- {
- UdAttachToProcess(NULL,
- g_StartCommandPath.c_str(),
- NULL,
- FALSE);
- }
- else
- {
- UdAttachToProcess(NULL,
- g_StartCommandPath.c_str(),
- (WCHAR *)g_StartCommandPathAndArguments.c_str(),
- FALSE);
- }
-}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/core/interpreter.cpp b/hyperdbg/hprdbgctrl/code/debugger/core/interpreter.cpp
deleted file mode 100644
index e64bff7b..00000000
--- a/hyperdbg/hprdbgctrl/code/debugger/core/interpreter.cpp
+++ /dev/null
@@ -1,871 +0,0 @@
-/**
- * @file interpreter.cpp
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief The hyperdbg command interpreter and driver connector
- * @details
- * @version 0.1
- * @date 2020-04-11
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#include "pch.h"
-
-using namespace std;
-
-//
-// Global Variables
-//
-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;
-
-/**
- * @brief Interpret commands
- *
- * @param Command The text of command
- * @return int returns return zero if it was successful or non-zero if there was
- * error
- */
-int
-HyperDbgInterpreter(char * Command)
-{
- BOOLEAN HelpCommand = FALSE;
- UINT64 CommandAttributes = NULL;
- CommandType::iterator Iterator;
-
- //
- // Check if it's the first command and whether the mapping of command is
- // initialized or not
- //
- if (!g_IsCommandListInitialized)
- {
- //
- // Initialize the debugger
- //
- InitializeDebugger();
-
- g_IsCommandListInitialized = TRUE;
- }
-
- //
- // Save the command into log open file
- //
- if (g_LogOpened && !g_ExecutingScript)
- {
- LogopenSaveToFile(Command);
- LogopenSaveToFile("\n");
- }
-
- //
- // Remove the comments
- //
- InterpreterRemoveComments(Command);
-
- //
- // Convert to string
- //
- string CommandString(Command);
-
- //
- // Convert to lower case
- //
- transform(CommandString.begin(), CommandString.end(), CommandString.begin(), [](unsigned char c) { return std::tolower(c); });
-
- vector SplitCommand {Split(CommandString, ' ')};
-
- //
- // Check if user entered an empty input
- //
- if (SplitCommand.empty())
- {
- ShowMessages("\n");
- return 0;
- }
-
- string FirstCommand = SplitCommand.front();
-
- //
- // Read the command's attributes
- //
- CommandAttributes = GetCommandAttributes(FirstCommand);
-
- //
- // Check if the command needs to be continued by pressing enter
- //
- if (CommandAttributes & DEBUGGER_COMMAND_ATTRIBUTE_REPEAT_ON_ENTER)
- {
- g_ShouldPreviousCommandBeContinued = TRUE;
- }
- else
- {
- g_ShouldPreviousCommandBeContinued = FALSE;
- }
-
- //
- // Check and send remote command and also we check whether this
- // is a command that should be handled in this command or we can
- // send it to the remote computer, it is because in a remote connection
- // still some of the commands should be handled in the local HyperDbg
- //
- if (g_IsConnectedToRemoteDebuggee &&
- !(CommandAttributes & DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_REMOTE_CONNECTION))
- {
- //
- // Check it here because generally, we use this variable in host
- // for showing the correct signature but we won't try to block
- // other commands, the only thing is events which is blocked
- // by the remote computer itself
- //
- if (g_BreakPrintingOutput)
- {
- g_BreakPrintingOutput = FALSE;
- }
-
- //
- // It's a connection over network (VMI-Mode)
- //
- RemoteConnectionSendCommand(Command, (UINT32)strlen(Command) + 1);
-
- ShowMessages("\n");
-
- //
- // Indicate that we sent the command to the target system
- //
- return 2;
- }
- else if (g_IsSerialConnectedToRemoteDebuggee &&
- !(CommandAttributes &
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE))
- {
- //
- // It's a connection over serial (Debugger-Mode)
- //
-
- if (CommandAttributes & DEBUGGER_COMMAND_ATTRIBUTE_WONT_STOP_DEBUGGER_AGAIN)
- {
- KdSendUserInputPacketToDebuggee(Command, (UINT32)strlen(Command) + 1, TRUE);
-
- //
- // Set the debuggee to show that it's running
- //
- KdSetStatusAndWaitForPause();
- }
- else
- {
- //
- // Disable the breakpoints and events while executing the command in the remote computer
- //
- KdSendTestQueryPacketToDebuggee(TEST_BREAKPOINT_TURN_OFF_BPS_AND_EVENTS_FOR_COMMANDS_IN_REMOTE_COMPUTER);
- KdSendUserInputPacketToDebuggee(Command, (UINT32)strlen(Command) + 1, FALSE);
- KdSendTestQueryPacketToDebuggee(TEST_BREAKPOINT_TURN_ON_BPS_AND_EVENTS_FOR_COMMANDS_IN_REMOTE_COMPUTER);
- }
-
- //
- // Indicate that we sent the command to the target system
- //
- return 2;
- }
-
- //
- // Detect whether it's a .help command or not
- //
- if (!FirstCommand.compare(".help") || !FirstCommand.compare("help") ||
- !FirstCommand.compare(".hh"))
- {
- if (SplitCommand.size() == 2)
- {
- //
- // Show that it's a help command
- //
- HelpCommand = TRUE;
- FirstCommand = SplitCommand.at(1);
- }
- else
- {
- ShowMessages("incorrect use of the '%s'\n", FirstCommand.c_str());
- CommandHelpHelp();
- return 0;
- }
- }
-
- //
- // Start parsing commands
- //
- Iterator = g_CommandsList.find(FirstCommand);
-
- if (Iterator == g_CommandsList.end())
- {
- //
- // Command doesn't exist
- //
- string CaseSensitiveCommandString(Command);
- vector CaseSensitiveSplitCommand {Split(CaseSensitiveCommandString, ' ')};
-
- if (!HelpCommand)
- {
- ShowMessages("err, couldn't resolve command at '%s'\n", CaseSensitiveSplitCommand.front().c_str());
- }
- else
- {
- ShowMessages("err, couldn't find the help for the command at '%s'\n",
- CaseSensitiveSplitCommand.at(1).c_str());
- }
- }
- else
- {
- if (HelpCommand)
- {
- Iterator->second.CommandHelpFunction();
- }
- else
- {
- //
- // Check if command is case-sensitive or not
- //
- if ((Iterator->second.CommandAttrib &
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE))
- {
- string CaseSensitiveCommandString(Command);
- Iterator->second.CommandFunction(SplitCommand, CaseSensitiveCommandString);
- }
- else
- {
- Iterator->second.CommandFunction(SplitCommand, CommandString);
- }
- }
- }
-
- //
- // Save the command into log open file
- //
- if (g_LogOpened && !g_ExecutingScript)
- {
- LogopenSaveToFile("\n");
- }
-
- return 0;
-}
-
-/**
- * @brief Remove batch comments
- *
- * @return VOID
- */
-VOID
-InterpreterRemoveComments(char * CommandText)
-{
- BOOLEAN IsComment = FALSE;
- BOOLEAN IsOnString = FALSE;
- UINT32 LengthOfCommand = (UINT32)strlen(CommandText);
-
- for (size_t i = 0; i < LengthOfCommand; i++)
- {
- if (IsComment)
- {
- if (CommandText[i] == '\n')
- {
- IsComment = FALSE;
- }
- else
- {
- if (CommandText[i] != '\0')
- {
- memmove((void *)&CommandText[i], (const void *)&CommandText[i + 1], strlen(CommandText) - i);
- i--;
- }
- }
- }
- else if (CommandText[i] == '#' && !IsOnString)
- {
- //
- // Comment detected
- //
- IsComment = TRUE;
- i--;
- }
- else if (CommandText[i] == '"')
- {
- if (i != 0 && CommandText[i - 1] == '\\')
- {
- //
- // It's an escape character for : \"
- //
- }
- else if (IsOnString)
- {
- IsOnString = FALSE;
- }
- else
- {
- IsOnString = TRUE;
- }
- }
- }
-}
-
-/**
- * @brief Show signature of HyperDbg
- *
- * @return VOID
- */
-VOID
-HyperDbgShowSignature()
-{
- if (g_IsConnectedToRemoteDebuggee)
- {
- //
- // Remote debugging over tcp (vmi-mode)
- //
- ShowMessages("[%s:%s] HyperDbg> ", g_ServerIp.c_str(), g_ServerPort.c_str());
- }
- else if (g_ActiveProcessDebuggingState.IsActive)
- {
- //
- // Debugging a special process
- //
- ShowMessages("%x:%x u%sHyperDbg> ",
- g_ActiveProcessDebuggingState.ProcessId,
- g_ActiveProcessDebuggingState.ThreadId,
- g_ActiveProcessDebuggingState.Is32Bit ? "86" : "64");
- }
- else if (g_IsSerialConnectedToRemoteDebuggee)
- {
- //
- // Remote debugging over serial (debugger-mode)
- //
- ShowMessages("%x: kHyperDbg> ", g_CurrentRemoteCore);
- }
- else
- {
- //
- // Anything other than above scenarios including local debugging
- // in vmi-mode
- //
- ShowMessages("HyperDbg> ");
- }
-}
-
-/**
- * @brief check for multi-line commands
- *
- * @param CurrentCommand
- * @param Reset
- * @return bool return true if the command needs extra input, otherwise
- * return false
- */
-bool
-HyperDbgCheckMultilineCommand(char * CurrentCommand, bool Reset)
-{
- UINT32 CurrentCommandLen = 0;
- std::string CurrentCommandStr(CurrentCommand);
-
- if (Reset)
- {
- g_IsInterpreterOnString = FALSE;
- g_IsInterpreterPreviousCharacterABackSlash = FALSE;
- g_InterpreterCountOfOpenCurlyBrackets = 0;
- }
-
- CurrentCommandLen = (UINT32)CurrentCommandStr.length();
-
- for (size_t i = 0; i < CurrentCommandLen; i++)
- {
- switch (CurrentCommandStr.at(i))
- {
- case '"':
-
- if (g_IsInterpreterPreviousCharacterABackSlash)
- {
- g_IsInterpreterPreviousCharacterABackSlash = FALSE;
- break; // it's an escaped \" double-quote
- }
-
- if (g_IsInterpreterOnString)
- g_IsInterpreterOnString = FALSE;
- else
- g_IsInterpreterOnString = TRUE;
-
- break;
-
- case '{':
-
- if (g_IsInterpreterPreviousCharacterABackSlash)
- g_IsInterpreterPreviousCharacterABackSlash = FALSE;
-
- if (!g_IsInterpreterOnString)
- g_InterpreterCountOfOpenCurlyBrackets++;
-
- break;
-
- case '}':
-
- if (g_IsInterpreterPreviousCharacterABackSlash)
- g_IsInterpreterPreviousCharacterABackSlash = FALSE;
-
- if (!g_IsInterpreterOnString && g_InterpreterCountOfOpenCurlyBrackets > 0)
- g_InterpreterCountOfOpenCurlyBrackets--;
-
- break;
-
- case '\\':
-
- if (g_IsInterpreterPreviousCharacterABackSlash)
- g_IsInterpreterPreviousCharacterABackSlash = FALSE; // it's not a escape character (two backslashes \\ )
- else
- g_IsInterpreterPreviousCharacterABackSlash = TRUE;
-
- break;
-
- default:
-
- if (g_IsInterpreterPreviousCharacterABackSlash)
- g_IsInterpreterPreviousCharacterABackSlash = FALSE;
-
- break;
- }
- }
-
- if (g_IsInterpreterOnString == FALSE && g_InterpreterCountOfOpenCurlyBrackets == 0)
- {
- //
- // either the command is finished or it's a single
- // line command
- //
- return false;
- }
- else
- {
- //
- // There still other lines, this command is incomplete
- //
- return true;
- }
-}
-
-/**
- * @brief Some of commands like stepping commands (i, p, t) and etc.
- * need to be repeated when the user press enter, this function shows
- * whether we should continue the previous command or not
- *
- * @return true means the command should be continued, false means command
- * should be ignored
- */
-bool
-HyperDbgContinuePreviousCommand()
-{
- BOOLEAN Result = g_ShouldPreviousCommandBeContinued;
-
- //
- // We should keep it false for the next command
- //
- g_ShouldPreviousCommandBeContinued = FALSE;
-
- if (Result)
- {
- return true;
- }
- else
- {
- return false;
- }
-}
-
-/**
- * @brief Get Command Attributes
- *
- * @param FirstCommand just the first word of command (without other parameters)
- * @return BOOLEAN Mask of the command's attributes
- */
-UINT64
-GetCommandAttributes(const string & FirstCommand)
-{
- CommandType::iterator Iterator;
-
- //
- // Some commands should not be passed to the remote system
- // and instead should be handled in the current debugger
- //
-
- Iterator = g_CommandsList.find(FirstCommand);
-
- if (Iterator == g_CommandsList.end())
- {
- //
- // Command doesn't exist, if it's not exists then it's better to handle
- // it locally, instead of sending it to the remote computer
- //
- return DEBUGGER_COMMAND_ATTRIBUTE_ABSOLUTE_LOCAL;
- }
- else
- {
- return Iterator->second.CommandAttrib;
- }
-
- return NULL;
-}
-
-/**
- * @brief Initialize the debugger and adjust commands for the first run
- *
- * @return VOID
- */
-VOID
-InitializeDebugger()
-{
- //
- // Initialize the mapping of functions
- //
- InitializeCommandsDictionary();
-
- //
- // Set the callback for symbol message handler
- //
- ScriptEngineSetTextMessageCallbackWrapper(ShowMessages);
-
- //
- // Register the CTRL+C and CTRL+BREAK Signals handler
- //
- if (!SetConsoleCtrlHandler(BreakController, TRUE))
- {
- ShowMessages("err, when registering CTRL+C and CTRL+BREAK Signals "
- "handler\n");
- //
- // prefer to continue
- //
- }
-
- //
- // *** Check for feature indicators ***
- //
-
- //
- // Get x86 processor width for virtual address
- //
- g_VirtualAddressWidth = Getx86VirtualAddressWidth();
-
- //
- // Check if processor supports TSX (RTM)
- //
- g_RtmSupport = CheckCpuSupportRtm();
-
- //
- // Load default settings
- //
- CommandSettingsLoadDefaultValuesFromConfigFile();
-}
-
-/**
- * @brief Initialize commands and attributes
- *
- * @return VOID
- */
-VOID
-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["clear"] = {&CommandClearScreen, &CommandClearScreenHelp, DEBUGGER_COMMAND_CLEAR_ATTRIBUTES};
- g_CommandsList[".cls"] = {&CommandClearScreen, &CommandClearScreenHelp, DEBUGGER_COMMAND_CLEAR_ATTRIBUTES};
- g_CommandsList["cls"] = {&CommandClearScreen, &CommandClearScreenHelp, DEBUGGER_COMMAND_CLEAR_ATTRIBUTES};
-
- g_CommandsList[".connect"] = {&CommandConnect, &CommandConnectHelp, DEBUGGER_COMMAND_CONNECT_ATTRIBUTES};
- g_CommandsList["connect"] = {&CommandConnect, &CommandConnectHelp, DEBUGGER_COMMAND_CONNECT_ATTRIBUTES};
-
- g_CommandsList[".listen"] = {&CommandListen, &CommandListenHelp, DEBUGGER_COMMAND_LISTEN_ATTRIBUTES};
- g_CommandsList["listen"] = {&CommandListen, &CommandListenHelp, DEBUGGER_COMMAND_LISTEN_ATTRIBUTES};
-
- g_CommandsList["g"] = {&CommandG, &CommandGHelp, DEBUGGER_COMMAND_G_ATTRIBUTES};
- g_CommandsList["go"] = {&CommandG, &CommandGHelp, DEBUGGER_COMMAND_G_ATTRIBUTES};
-
- g_CommandsList[".attach"] = {&CommandAttach, &CommandAttachHelp, DEBUGGER_COMMAND_ATTACH_ATTRIBUTES};
- g_CommandsList["attach"] = {&CommandAttach, &CommandAttachHelp, DEBUGGER_COMMAND_ATTACH_ATTRIBUTES};
-
- g_CommandsList[".detach"] = {&CommandDetach, &CommandDetachHelp, DEBUGGER_COMMAND_DETACH_ATTRIBUTES};
- g_CommandsList["detach"] = {&CommandDetach, &CommandDetachHelp, DEBUGGER_COMMAND_DETACH_ATTRIBUTES};
-
- g_CommandsList[".start"] = {&CommandStart, &CommandStartHelp, DEBUGGER_COMMAND_START_ATTRIBUTES};
- g_CommandsList["start"] = {&CommandStart, &CommandStartHelp, DEBUGGER_COMMAND_START_ATTRIBUTES};
-
- g_CommandsList[".restart"] = {&CommandRestart, &CommandRestartHelp, DEBUGGER_COMMAND_RESTART_ATTRIBUTES};
- g_CommandsList["restart"] = {&CommandRestart, &CommandRestartHelp, DEBUGGER_COMMAND_RESTART_ATTRIBUTES};
-
- g_CommandsList[".switch"] = {&CommandSwitch, &CommandSwitchHelp, DEBUGGER_COMMAND_SWITCH_ATTRIBUTES};
- g_CommandsList["switch"] = {&CommandSwitch, &CommandSwitchHelp, DEBUGGER_COMMAND_SWITCH_ATTRIBUTES};
-
- g_CommandsList[".kill"] = {&CommandKill, &CommandKillHelp, DEBUGGER_COMMAND_KILL_ATTRIBUTES};
- g_CommandsList["kill"] = {&CommandKill, &CommandKillHelp, DEBUGGER_COMMAND_KILL_ATTRIBUTES};
-
- g_CommandsList[".process"] = {&CommandProcess, &CommandProcessHelp, DEBUGGER_COMMAND_PROCESS_ATTRIBUTES};
- g_CommandsList[".process2"] = {&CommandProcess, &CommandProcessHelp, DEBUGGER_COMMAND_PROCESS_ATTRIBUTES};
- g_CommandsList["process"] = {&CommandProcess, &CommandProcessHelp, DEBUGGER_COMMAND_PROCESS_ATTRIBUTES};
- g_CommandsList["process2"] = {&CommandProcess, &CommandProcessHelp, DEBUGGER_COMMAND_PROCESS_ATTRIBUTES};
-
- g_CommandsList[".thread"] = {&CommandThread, &CommandThreadHelp, DEBUGGER_COMMAND_THREAD_ATTRIBUTES};
- g_CommandsList[".thread2"] = {&CommandThread, &CommandThreadHelp, DEBUGGER_COMMAND_THREAD_ATTRIBUTES};
- g_CommandsList["thread"] = {&CommandThread, &CommandThreadHelp, DEBUGGER_COMMAND_THREAD_ATTRIBUTES};
- g_CommandsList["thread2"] = {&CommandThread, &CommandThreadHelp, DEBUGGER_COMMAND_THREAD_ATTRIBUTES};
-
- g_CommandsList["sleep"] = {&CommandSleep, &CommandSleepHelp, DEBUGGER_COMMAND_SLEEP_ATTRIBUTES};
-
- g_CommandsList["event"] = {&CommandEvents, &CommandEventsHelp, DEBUGGER_COMMAND_EVENTS_ATTRIBUTES};
- g_CommandsList["events"] = {&CommandEvents, &CommandEventsHelp, DEBUGGER_COMMAND_EVENTS_ATTRIBUTES};
-
- g_CommandsList["setting"] = {&CommandSettings, &CommandSettingsHelp, DEBUGGER_COMMAND_SETTINGS_ATTRIBUTES};
- g_CommandsList["settings"] = {&CommandSettings, &CommandSettingsHelp, DEBUGGER_COMMAND_SETTINGS_ATTRIBUTES};
- g_CommandsList[".setting"] = {&CommandSettings, &CommandSettingsHelp, DEBUGGER_COMMAND_SETTINGS_ATTRIBUTES};
- g_CommandsList[".settings"] = {&CommandSettings, &CommandSettingsHelp, DEBUGGER_COMMAND_SETTINGS_ATTRIBUTES};
-
- g_CommandsList[".disconnect"] = {&CommandDisconnect, &CommandDisconnectHelp, DEBUGGER_COMMAND_DISCONNECT_ATTRIBUTES};
- g_CommandsList["disconnect"] = {&CommandDisconnect, &CommandDisconnectHelp, DEBUGGER_COMMAND_DISCONNECT_ATTRIBUTES};
-
- g_CommandsList[".debug"] = {&CommandDebug, &CommandDebugHelp, DEBUGGER_COMMAND_DEBUG_ATTRIBUTES};
- g_CommandsList["debug"] = {&CommandDebug, &CommandDebugHelp, DEBUGGER_COMMAND_DEBUG_ATTRIBUTES};
-
- g_CommandsList[".status"] = {&CommandStatus, &CommandStatusHelp, DEBUGGER_COMMAND_DOT_STATUS_ATTRIBUTES};
- g_CommandsList["status"] = {&CommandStatus, &CommandStatusHelp, DEBUGGER_COMMAND_STATUS_ATTRIBUTES};
-
- g_CommandsList["load"] = {&CommandLoad, &CommandLoadHelp, DEBUGGER_COMMAND_LOAD_ATTRIBUTES};
-
- g_CommandsList["exit"] = {&CommandExit, &CommandExitHelp, DEBUGGER_COMMAND_EXIT_ATTRIBUTES};
- g_CommandsList[".exit"] = {&CommandExit, &CommandExitHelp, DEBUGGER_COMMAND_EXIT_ATTRIBUTES};
-
- g_CommandsList["flush"] = {&CommandFlush, &CommandFlushHelp, DEBUGGER_COMMAND_FLUSH_ATTRIBUTES};
-
- g_CommandsList["pause"] = {&CommandPause, &CommandPauseHelp, DEBUGGER_COMMAND_PAUSE_ATTRIBUTES};
-
- g_CommandsList["unload"] = {&CommandUnload, &CommandUnloadHelp, DEBUGGER_COMMAND_UNLOAD_ATTRIBUTES};
-
- g_CommandsList[".script"] = {&CommandScript, &CommandScriptHelp, DEBUGGER_COMMAND_SCRIPT_ATTRIBUTES};
- g_CommandsList["script"] = {&CommandScript, &CommandScriptHelp, DEBUGGER_COMMAND_SCRIPT_ATTRIBUTES};
-
- g_CommandsList["output"] = {&CommandOutput, &CommandOutputHelp, DEBUGGER_COMMAND_OUTPUT_ATTRIBUTES};
-
- g_CommandsList["print"] = {&CommandPrint, &CommandPrintHelp, DEBUGGER_COMMAND_PRINT_ATTRIBUTES};
-
- g_CommandsList["?"] = {&CommandEval, &CommandEvalHelp, DEBUGGER_COMMAND_EVAL_ATTRIBUTES};
- g_CommandsList["eval"] = {&CommandEval, &CommandEvalHelp, DEBUGGER_COMMAND_EVAL_ATTRIBUTES};
- g_CommandsList["evaluate"] = {&CommandEval, &CommandEvalHelp, DEBUGGER_COMMAND_EVAL_ATTRIBUTES};
-
- g_CommandsList[".logopen"] = {&CommandLogopen, &CommandLogopenHelp, DEBUGGER_COMMAND_LOGOPEN_ATTRIBUTES};
-
- g_CommandsList[".logclose"] = {&CommandLogclose, &CommandLogcloseHelp, DEBUGGER_COMMAND_LOGCLOSE_ATTRIBUTES};
-
- g_CommandsList[".pagein"] = {&CommandPagein, &CommandPageinHelp, DEBUGGER_COMMAND_PAGEIN_ATTRIBUTES};
- g_CommandsList["pagein"] = {&CommandPagein, &CommandPageinHelp, DEBUGGER_COMMAND_PAGEIN_ATTRIBUTES};
-
- g_CommandsList["test"] = {&CommandTest, &CommandTestHelp, DEBUGGER_COMMAND_TEST_ATTRIBUTES};
-
- g_CommandsList["cpu"] = {&CommandCpu, &CommandCpuHelp, DEBUGGER_COMMAND_CPU_ATTRIBUTES};
-
- g_CommandsList["wrmsr"] = {&CommandWrmsr, &CommandWrmsrHelp, DEBUGGER_COMMAND_WRMSR_ATTRIBUTES};
-
- g_CommandsList["rdmsr"] = {&CommandRdmsr, &CommandRdmsrHelp, DEBUGGER_COMMAND_RDMSR_ATTRIBUTES};
-
- g_CommandsList["!va2pa"] = {&CommandVa2pa, &CommandVa2paHelp, DEBUGGER_COMMAND_VA2PA_ATTRIBUTES};
-
- g_CommandsList["!pa2va"] = {&CommandPa2va, &CommandPa2vaHelp, DEBUGGER_COMMAND_PA2VA_ATTRIBUTES};
-
- g_CommandsList[".formats"] = {&CommandFormats, &CommandFormatsHelp, DEBUGGER_COMMAND_FORMATS_ATTRIBUTES};
- g_CommandsList[".format"] = {&CommandFormats, &CommandFormatsHelp, DEBUGGER_COMMAND_FORMATS_ATTRIBUTES};
-
- g_CommandsList["!pte"] = {&CommandPte, &CommandPteHelp, DEBUGGER_COMMAND_PTE_ATTRIBUTES};
-
- g_CommandsList["~"] = {&CommandCore, &CommandCoreHelp, DEBUGGER_COMMAND_CORE_ATTRIBUTES};
- g_CommandsList["core"] = {&CommandCore, &CommandCoreHelp, DEBUGGER_COMMAND_CORE_ATTRIBUTES};
-
- g_CommandsList["!monitor"] = {&CommandMonitor, &CommandMonitorHelp, DEBUGGER_COMMAND_MONITOR_ATTRIBUTES};
-
- g_CommandsList["!vmcall"] = {&CommandVmcall, &CommandVmcallHelp, DEBUGGER_COMMAND_VMCALL_ATTRIBUTES};
-
- g_CommandsList["!epthook"] = {&CommandEptHook, &CommandEptHookHelp, DEBUGGER_COMMAND_EPTHOOK_ATTRIBUTES};
- g_CommandsList["bh"] = {&CommandEptHook, &CommandEptHookHelp, DEBUGGER_COMMAND_EPTHOOK_ATTRIBUTES};
-
- g_CommandsList["bp"] = {&CommandBp, &CommandBpHelp, DEBUGGER_COMMAND_BP_ATTRIBUTES};
-
- g_CommandsList["bl"] = {&CommandBl, &CommandBlHelp, DEBUGGER_COMMAND_BD_ATTRIBUTES};
-
- g_CommandsList["be"] = {&CommandBe, &CommandBeHelp, DEBUGGER_COMMAND_BD_ATTRIBUTES};
-
- g_CommandsList["bd"] = {&CommandBd, &CommandBdHelp, DEBUGGER_COMMAND_BD_ATTRIBUTES};
-
- g_CommandsList["bc"] = {&CommandBc, &CommandBcHelp, DEBUGGER_COMMAND_BD_ATTRIBUTES};
-
- g_CommandsList["!epthook2"] = {&CommandEptHook2, &CommandEptHook2Help, DEBUGGER_COMMAND_EPTHOOK2_ATTRIBUTES};
-
- g_CommandsList["!cpuid"] = {&CommandCpuid, &CommandCpuidHelp, DEBUGGER_COMMAND_CPUID_ATTRIBUTES};
-
- g_CommandsList["!msrread"] = {&CommandMsrread, &CommandMsrreadHelp, DEBUGGER_COMMAND_MSRREAD_ATTRIBUTES};
- g_CommandsList["!msread"] = {&CommandMsrread, &CommandMsrreadHelp, DEBUGGER_COMMAND_MSRREAD_ATTRIBUTES};
-
- g_CommandsList["!msrwrite"] = {&CommandMsrwrite, &CommandMsrwriteHelp, DEBUGGER_COMMAND_MSRWRITE_ATTRIBUTES};
-
- g_CommandsList["!tsc"] = {&CommandTsc, &CommandTscHelp, DEBUGGER_COMMAND_TSC_ATTRIBUTES};
-
- g_CommandsList["!pmc"] = {&CommandPmc, &CommandPmcHelp, DEBUGGER_COMMAND_PMC_ATTRIBUTES};
-
- g_CommandsList["!crwrite"] = {&CommandCrwrite, &CommandCrwriteHelp, DEBUGGER_COMMAND_CRWRITE_ATTRIBUTES};
-
- g_CommandsList["!dr"] = {&CommandDr, &CommandDrHelp, DEBUGGER_COMMAND_DR_ATTRIBUTES};
-
- g_CommandsList["!ioin"] = {&CommandIoin, &CommandIoinHelp, DEBUGGER_COMMAND_IOIN_ATTRIBUTES};
-
- g_CommandsList["!ioout"] = {&CommandIoout, &CommandIooutHelp, DEBUGGER_COMMAND_IOOUT_ATTRIBUTES};
-
- g_CommandsList["!exception"] = {&CommandException, &CommandExceptionHelp, DEBUGGER_COMMAND_EXCEPTION_ATTRIBUTES};
-
- g_CommandsList["!interrupt"] = {&CommandInterrupt, &CommandInterruptHelp, DEBUGGER_COMMAND_INTERRUPT_ATTRIBUTES};
-
- g_CommandsList["!syscall"] = {&CommandSyscallAndSysret, &CommandSyscallHelp, DEBUGGER_COMMAND_SYSCALL_ATTRIBUTES};
- g_CommandsList["!syscall2"] = {&CommandSyscallAndSysret, &CommandSyscallHelp, DEBUGGER_COMMAND_SYSCALL_ATTRIBUTES};
-
- g_CommandsList["!sysret"] = {&CommandSyscallAndSysret, &CommandSysretHelp, DEBUGGER_COMMAND_SYSRET_ATTRIBUTES};
- g_CommandsList["!sysret2"] = {&CommandSyscallAndSysret, &CommandSysretHelp, DEBUGGER_COMMAND_SYSRET_ATTRIBUTES};
-
- g_CommandsList["!mode"] = {&CommandMode, &CommandModeHelp, DEBUGGER_COMMAND_MODE_ATTRIBUTES};
-
- g_CommandsList["!trace"] = {&CommandTrace, &CommandTraceHelp, DEBUGGER_COMMAND_TRACE_ATTRIBUTES};
-
- g_CommandsList["!hide"] = {&CommandHide, &CommandHideHelp, DEBUGGER_COMMAND_HIDE_ATTRIBUTES};
-
- g_CommandsList["!unhide"] = {&CommandUnhide, &CommandUnhideHelp, DEBUGGER_COMMAND_UNHIDE_ATTRIBUTES};
-
- g_CommandsList["!measure"] = {&CommandMeasure, &CommandMeasureHelp, DEBUGGER_COMMAND_MEASURE_ATTRIBUTES};
-
- g_CommandsList["lm"] = {&CommandLm, &CommandLmHelp, DEBUGGER_COMMAND_LM_ATTRIBUTES};
-
- g_CommandsList["p"] = {&CommandP, &CommandPHelp, DEBUGGER_COMMAND_P_ATTRIBUTES};
- g_CommandsList["pr"] = {&CommandP, &CommandPHelp, DEBUGGER_COMMAND_P_ATTRIBUTES};
-
- g_CommandsList["t"] = {&CommandT, &CommandTHelp, DEBUGGER_COMMAND_T_ATTRIBUTES};
- g_CommandsList["tr"] = {&CommandT, &CommandTHelp, DEBUGGER_COMMAND_T_ATTRIBUTES};
-
- g_CommandsList["i"] = {&CommandI, &CommandIHelp, DEBUGGER_COMMAND_I_ATTRIBUTES};
- g_CommandsList["ir"] = {&CommandI, &CommandIHelp, DEBUGGER_COMMAND_I_ATTRIBUTES};
-
- g_CommandsList["gu"] = {&CommandGu, &CommandGuHelp, DEBUGGER_COMMAND_GU_ATTRIBUTES};
-
- g_CommandsList["db"] = {&CommandReadMemoryAndDisassembler,
- &CommandReadMemoryAndDisassemblerHelp,
- DEBUGGER_COMMAND_D_AND_U_ATTRIBUTES};
- g_CommandsList["dc"] = {&CommandReadMemoryAndDisassembler,
- &CommandReadMemoryAndDisassemblerHelp,
- DEBUGGER_COMMAND_D_AND_U_ATTRIBUTES};
- g_CommandsList["dd"] = {&CommandReadMemoryAndDisassembler,
- &CommandReadMemoryAndDisassemblerHelp,
- DEBUGGER_COMMAND_D_AND_U_ATTRIBUTES};
- g_CommandsList["dq"] = {&CommandReadMemoryAndDisassembler,
- &CommandReadMemoryAndDisassemblerHelp,
- DEBUGGER_COMMAND_D_AND_U_ATTRIBUTES};
- g_CommandsList["!db"] = {&CommandReadMemoryAndDisassembler,
- &CommandReadMemoryAndDisassemblerHelp,
- DEBUGGER_COMMAND_D_AND_U_ATTRIBUTES};
- g_CommandsList["!dc"] = {&CommandReadMemoryAndDisassembler,
- &CommandReadMemoryAndDisassemblerHelp,
- DEBUGGER_COMMAND_D_AND_U_ATTRIBUTES};
- g_CommandsList["!dd"] = {&CommandReadMemoryAndDisassembler,
- &CommandReadMemoryAndDisassemblerHelp,
- DEBUGGER_COMMAND_D_AND_U_ATTRIBUTES};
- g_CommandsList["!dq"] = {&CommandReadMemoryAndDisassembler,
- &CommandReadMemoryAndDisassemblerHelp,
- DEBUGGER_COMMAND_D_AND_U_ATTRIBUTES};
- g_CommandsList["!u"] = {&CommandReadMemoryAndDisassembler,
- &CommandReadMemoryAndDisassemblerHelp,
- DEBUGGER_COMMAND_D_AND_U_ATTRIBUTES};
- g_CommandsList["u"] = {&CommandReadMemoryAndDisassembler,
- &CommandReadMemoryAndDisassemblerHelp,
- DEBUGGER_COMMAND_D_AND_U_ATTRIBUTES};
- g_CommandsList["!u64"] = {&CommandReadMemoryAndDisassembler,
- &CommandReadMemoryAndDisassemblerHelp,
- DEBUGGER_COMMAND_D_AND_U_ATTRIBUTES};
- g_CommandsList["u64"] = {&CommandReadMemoryAndDisassembler,
- &CommandReadMemoryAndDisassemblerHelp,
- DEBUGGER_COMMAND_D_AND_U_ATTRIBUTES};
- g_CommandsList["!u2"] = {&CommandReadMemoryAndDisassembler,
- &CommandReadMemoryAndDisassemblerHelp,
- DEBUGGER_COMMAND_D_AND_U_ATTRIBUTES};
- g_CommandsList["u2"] = {&CommandReadMemoryAndDisassembler,
- &CommandReadMemoryAndDisassemblerHelp,
- DEBUGGER_COMMAND_D_AND_U_ATTRIBUTES};
- g_CommandsList["!u32"] = {&CommandReadMemoryAndDisassembler,
- &CommandReadMemoryAndDisassemblerHelp,
- DEBUGGER_COMMAND_D_AND_U_ATTRIBUTES};
- g_CommandsList["u32"] = {&CommandReadMemoryAndDisassembler,
- &CommandReadMemoryAndDisassemblerHelp,
- DEBUGGER_COMMAND_D_AND_U_ATTRIBUTES};
-
- g_CommandsList["eb"] = {&CommandEditMemory, &CommandEditMemoryHelp, DEBUGGER_COMMAND_E_ATTRIBUTES};
- g_CommandsList["ed"] = {&CommandEditMemory, &CommandEditMemoryHelp, DEBUGGER_COMMAND_E_ATTRIBUTES};
- g_CommandsList["eq"] = {&CommandEditMemory, &CommandEditMemoryHelp, DEBUGGER_COMMAND_E_ATTRIBUTES};
- g_CommandsList["!eb"] = {&CommandEditMemory, &CommandEditMemoryHelp, DEBUGGER_COMMAND_E_ATTRIBUTES};
- g_CommandsList["!ed"] = {&CommandEditMemory, &CommandEditMemoryHelp, DEBUGGER_COMMAND_E_ATTRIBUTES};
- g_CommandsList["!eq"] = {&CommandEditMemory, &CommandEditMemoryHelp, DEBUGGER_COMMAND_E_ATTRIBUTES};
-
- g_CommandsList["sb"] = {&CommandSearchMemory, &CommandSearchMemoryHelp, DEBUGGER_COMMAND_S_ATTRIBUTES};
- g_CommandsList["sd"] = {&CommandSearchMemory, &CommandSearchMemoryHelp, DEBUGGER_COMMAND_S_ATTRIBUTES};
- g_CommandsList["sq"] = {&CommandSearchMemory, &CommandSearchMemoryHelp, DEBUGGER_COMMAND_S_ATTRIBUTES};
- g_CommandsList["!sb"] = {&CommandSearchMemory, &CommandSearchMemoryHelp, DEBUGGER_COMMAND_S_ATTRIBUTES};
- g_CommandsList["!sd"] = {&CommandSearchMemory, &CommandSearchMemoryHelp, DEBUGGER_COMMAND_S_ATTRIBUTES};
- g_CommandsList["!sq"] = {&CommandSearchMemory, &CommandSearchMemoryHelp, DEBUGGER_COMMAND_S_ATTRIBUTES};
-
- g_CommandsList["r"] = {&CommandR, &CommandRHelp, DEBUGGER_COMMAND_R_ATTRIBUTES};
-
- g_CommandsList[".sympath"] = {&CommandSympath, &CommandSympathHelp, DEBUGGER_COMMAND_SYMPATH_ATTRIBUTES};
- g_CommandsList["sympath"] = {&CommandSympath, &CommandSympathHelp, DEBUGGER_COMMAND_SYMPATH_ATTRIBUTES};
-
- g_CommandsList[".sym"] = {&CommandSym, &CommandSymHelp, DEBUGGER_COMMAND_SYM_ATTRIBUTES};
- g_CommandsList["sym"] = {&CommandSym, &CommandSymHelp, DEBUGGER_COMMAND_SYM_ATTRIBUTES};
-
- g_CommandsList["x"] = {&CommandX, &CommandXHelp, DEBUGGER_COMMAND_X_ATTRIBUTES};
-
- g_CommandsList["prealloc"] = {&CommandPrealloc, &CommandPreallocHelp, DEBUGGER_COMMAND_PREALLOC_ATTRIBUTES};
- g_CommandsList["preallocate"] = {&CommandPrealloc, &CommandPreallocHelp, DEBUGGER_COMMAND_PREALLOC_ATTRIBUTES};
- g_CommandsList["preallocation"] = {&CommandPrealloc, &CommandPreallocHelp, DEBUGGER_COMMAND_PREALLOC_ATTRIBUTES};
-
- g_CommandsList["preactivate"] = {&CommandPreactivate, &CommandPreactivateHelp, DEBUGGER_COMMAND_PREACTIVATE_ATTRIBUTES};
- g_CommandsList["preactive"] = {&CommandPreactivate, &CommandPreactivateHelp, DEBUGGER_COMMAND_PREACTIVATE_ATTRIBUTES};
- g_CommandsList["preactivation"] = {&CommandPreactivate, &CommandPreactivateHelp, DEBUGGER_COMMAND_PREACTIVATE_ATTRIBUTES};
-
- g_CommandsList["k"] = {&CommandK, &CommandKHelp, DEBUGGER_COMMAND_K_ATTRIBUTES};
- g_CommandsList["kd"] = {&CommandK, &CommandKHelp, DEBUGGER_COMMAND_K_ATTRIBUTES};
- g_CommandsList["kq"] = {&CommandK, &CommandKHelp, DEBUGGER_COMMAND_K_ATTRIBUTES};
-
- g_CommandsList["dt"] = {&CommandDtAndStruct, &CommandDtHelp, DEBUGGER_COMMAND_DT_ATTRIBUTES};
- g_CommandsList["!dt"] = {&CommandDtAndStruct, &CommandDtHelp, DEBUGGER_COMMAND_DT_ATTRIBUTES};
-
- g_CommandsList["struct"] = {&CommandDtAndStruct, &CommandStructHelp, DEBUGGER_COMMAND_STRUCT_ATTRIBUTES};
- g_CommandsList["structure"] = {&CommandDtAndStruct, &CommandStructHelp, DEBUGGER_COMMAND_STRUCT_ATTRIBUTES};
-
- g_CommandsList[".pe"] = {&CommandPe, &CommandPeHelp, DEBUGGER_COMMAND_PE_ATTRIBUTES};
-
- g_CommandsList["!rev"] = {&CommandRev, &CommandRevHelp, DEBUGGER_COMMAND_REV_ATTRIBUTES};
- g_CommandsList["rev"] = {&CommandRev, &CommandRevHelp, DEBUGGER_COMMAND_REV_ATTRIBUTES};
-
- g_CommandsList["!track"] = {&CommandTrack, &CommandTrackHelp, DEBUGGER_COMMAND_TRACK_ATTRIBUTES};
- g_CommandsList["track"] = {&CommandTrack, &CommandTrackHelp, DEBUGGER_COMMAND_TRACK_ATTRIBUTES};
-
- g_CommandsList[".dump"] = {&CommandDump, &CommandDumpHelp, DEBUGGER_COMMAND_DUMP_ATTRIBUTES};
- g_CommandsList["dump"] = {&CommandDump, &CommandDumpHelp, DEBUGGER_COMMAND_DUMP_ATTRIBUTES};
- g_CommandsList["!dump"] = {&CommandDump, &CommandDumpHelp, DEBUGGER_COMMAND_DUMP_ATTRIBUTES};
-}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/script-engine/script-engine.cpp b/hyperdbg/hprdbgctrl/code/debugger/script-engine/script-engine.cpp
deleted file mode 100644
index e0abeb21..00000000
--- a/hyperdbg/hprdbgctrl/code/debugger/script-engine/script-engine.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * @file script-engine.cpp
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief Interpret script engine affairs
- * @details
- * @version 0.1
- * @date 2021-09-23
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#include "pch.h"
-
-//
-// Global Variables
-//
-extern UINT64 g_ResultOfEvaluatedExpression;
-extern UINT32 g_ErrorStateOfResultOfEvaluatedExpression;
-extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
-
-/**
- * @brief Get the value from the evaluation of single expression
- * from local debuggee and remote debuggee
- *
- * @param Expr
- * @param HasError
- * @return UINT64
- */
-UINT64
-ScriptEngineEvalSingleExpression(string Expr, PBOOLEAN HasError)
-{
- PVOID CodeBuffer;
- UINT64 BufferAddress;
- UINT32 BufferLength;
- UINT32 Pointer;
- UINT64 Result = NULL;
-
- //
- // Prepend and append 'formats(' and ')'
- //
- Expr.insert(0, "formats(");
- Expr.append(");");
-
- //
- // Run script engine handler
- //
- CodeBuffer = ScriptEngineParseWrapper((char *)Expr.c_str(), FALSE);
-
- if (CodeBuffer == NULL)
- {
- //
- // return to show that this item contains an script
- //
- *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);
-
- //
- // Check whether there was an error in evaluation or not
- //
- if (g_ErrorStateOfResultOfEvaluatedExpression == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
- {
- //
- // Everything was fine, return the result of the evaluated
- // expression and null the global holders
- //
- Result = g_ResultOfEvaluatedExpression;
- g_ErrorStateOfResultOfEvaluatedExpression = NULL;
- g_ResultOfEvaluatedExpression = NULL;
- *HasError = FALSE;
- }
- else
- {
- //
- // There was an error evaluating the expression from the kernel (debuggee)
- //
- g_ErrorStateOfResultOfEvaluatedExpression = NULL;
- g_ResultOfEvaluatedExpression = NULL;
-
- *HasError = TRUE;
- Result = NULL;
- }
- }
- else
- {
- //
- // It's in vmi-mode,
- // execute it locally with regs set to ZERO
- //
- Result = ScriptEngineEvalUInt64StyleExpressionWrapper(Expr, HasError);
- }
-
- //
- // Remove the buffer of script engine interpreted code
- //
- ScriptEngineWrapperRemoveSymbolBuffer(CodeBuffer);
-
- return Result;
-}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/user-level/pe-parser.cpp b/hyperdbg/hprdbgctrl/code/debugger/user-level/pe-parser.cpp
deleted file mode 100644
index 26725647..00000000
--- a/hyperdbg/hprdbgctrl/code/debugger/user-level/pe-parser.cpp
+++ /dev/null
@@ -1,604 +0,0 @@
-/**
- * @file pe-parser.cpp
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief Portable Executable parser
- * @details
- * @version 0.1
- * @date 2021-12-26
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#include "pch.h"
-
-/**
- * @brief Show hex dump of sections of PE
- * @param Ptr
- * @param Size
- * @param SecAddress
- *
- * @return VOID
- */
-VOID
-PeHexDump(CHAR * Ptr, int Size, int SecAddress)
-{
- int i = 1, Temp = 0;
-
- //
- // Buffer to store the character dump displayed at the
- // right side
- //
- wchar_t Buf[18];
- ShowMessages("\n\n%x: |", SecAddress);
-
- Buf[Temp] = ' '; // initial space
- Buf[Temp + 16] = ' '; // final space
- Buf[Temp + 17] = 0; // End of Buf
- Temp++; // Temp = 1;
-
- for (; i <= Size; i++, Ptr++, Temp++)
- {
- Buf[Temp] = !iswcntrl((*Ptr) & 0xff) ? (*Ptr) & 0xff : '.';
- ShowMessages("%-3.2x", (*Ptr) & 0xff);
-
- if (i % 16 == 0)
- {
- //
- // print the character dump to the right
- //
- _putws(Buf);
- if (i + 1 <= Size)
- ShowMessages("%x: ", SecAddress += 16);
- Temp = 0;
- }
- if (i % 4 == 0)
- ShowMessages("| ");
- }
- if (i % 16 != 0)
- {
- Buf[Temp] = 0;
- for (; i % 16 != 0; i++)
- ShowMessages("%-3.2c", ' ');
- _putws(Buf);
- }
-}
-
-/**
- * @brief Show information about different sections of PE and the dump of sections
- * @param AddressOfFile
- * @param SectionToShow
- * @param Is32Bit
- *
- * @return BOOLEAN
- */
-BOOLEAN
-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
-
- //
- // Open the EXE File
- //
- 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);
-
- if (BaseAddr == NULL)
- {
- CloseHandle(FileHandle);
- return FALSE;
- }
-
- //
- // Get the DOS Header Base
- //
- DosHeader = (PIMAGE_DOS_HEADER)BaseAddr; // 0x04000000
-
- //
- // Check for Valid DOS file
- //
- if (DosHeader->e_magic == IMAGE_DOS_SIGNATURE)
- {
- //
- // Dump the Dos Header info
- //
- ShowMessages("\nValid Dos Exe File\n------------------\n");
- ShowMessages("\nDumping DOS Header Info....\n---------------------------");
- ShowMessages("\n%-36s%s ",
- "Magic number : ",
- DosHeader->e_magic == 0x5a4d ? "MZ" : "-");
- ShowMessages("\n%-36s%#x", "Bytes on last page of file :", DosHeader->e_cblp);
- ShowMessages("\n%-36s%#x", "Pages in file : ", DosHeader->e_cp);
- ShowMessages("\n%-36s%#x", "Relocation : ", DosHeader->e_crlc);
- ShowMessages("\n%-36s%#x",
- "Size of header in paragraphs : ",
- DosHeader->e_cparhdr);
- ShowMessages("\n%-36s%#x",
- "Minimum extra paragraphs needed : ",
- DosHeader->e_minalloc);
- ShowMessages("\n%-36s%#x",
- "Maximum extra paragraphs needed : ",
- DosHeader->e_maxalloc);
- ShowMessages("\n%-36s%#x", "Initial (relative) SS value : ", DosHeader->e_ss);
- ShowMessages("\n%-36s%#x", "Initial SP value : ", DosHeader->e_sp);
- ShowMessages("\n%-36s%#x", "Checksum : ", DosHeader->e_csum);
- ShowMessages("\n%-36s%#x", "Initial IP value : ", DosHeader->e_ip);
- ShowMessages("\n%-36s%#x", "Initial (relative) CS value : ", DosHeader->e_cs);
- ShowMessages("\n%-36s%#x",
- "File address of relocation table : ",
- DosHeader->e_lfarlc);
- ShowMessages("\n%-36s%#x", "Overlay number : ", DosHeader->e_ovno);
- ShowMessages("\n%-36s%#x", "OEM identifier : ", DosHeader->e_oemid);
- ShowMessages("\n%-36s%#x",
- "OEM information(e_oemid specific) :",
- DosHeader->e_oeminfo);
- ShowMessages("\n%-36s%#x", "RVA address of PE header : ", DosHeader->e_lfanew);
- ShowMessages("\n==============================================================="
- "================\n");
- }
- else
- {
- ShowMessages("\nGiven File is not a valid DOS file\n");
- Result = FALSE;
- goto Finished;
- }
-
- //
- // Offset of NT Header is found at 0x3c location in DOS header specified by
- // e_lfanew
- // Get the Base of NT Header(PE Header) = DosHeader + RVA address of PE
- // header
- //
- if (Is32Bit)
- {
- NtHeader32 = (PIMAGE_NT_HEADERS32)((UINT64)(DosHeader) + (DosHeader->e_lfanew));
- }
- else
- {
- NtHeader64 = (PIMAGE_NT_HEADERS64)((UINT64)(DosHeader) + (DosHeader->e_lfanew));
- }
-
- //
- // Identify for valid PE file
- //
- if (Is32Bit && NtHeader32->Signature == IMAGE_NT_SIGNATURE)
- {
- ShowMessages("\nValid PE32 file \n-------------\n");
- }
- else if (!Is32Bit && NtHeader64->Signature == IMAGE_NT_SIGNATURE)
- {
- ShowMessages("\nValid PE64 file \n-------------\n");
- }
- else
- {
- ShowMessages("err, the specified file is not a valid PE file");
- Result = FALSE;
- goto Finished;
- }
-
- //
- // Dump NT Header Info....
- //
- ShowMessages("\nDumping COFF/PE Header "
- "Info....\n--------------------------------");
- ShowMessages("\n%-36s%s", "Signature :", "PE");
-
- //
- // Get the IMAGE FILE HEADER Structure
- //
- if (Is32Bit)
- {
- Header = NtHeader32->FileHeader;
- }
- else
- {
- Header = NtHeader64->FileHeader;
- }
-
- //
- // Determine Machine Architecture
- //
- ShowMessages("\n%-36s", "Machine Architecture :");
-
- //
- // Only few are determined (for remaining refer
- // to the above specification)
- //
- switch (Header.Machine)
- {
- case 0x0:
- ShowMessages("All ");
- break;
- case 0x14d:
- ShowMessages("Intel i860");
- break;
- case 0x14c:
- ShowMessages("Intel i386, i486, i586");
- break;
- case 0x200:
- ShowMessages("Intel Itanium processor");
- break;
- case 0x8664:
- ShowMessages("AMD x64");
- break;
- case 0x162:
- ShowMessages("MIPS R3000");
- break;
- case 0x166:
- ShowMessages("MIPS R4000");
- break;
- case 0x183:
- ShowMessages("DEC Alpha AXP");
- break;
- default:
- ShowMessages("Not Found");
- break;
- }
-
- //
- // Determine the characteristics of the given file
- //
- ShowMessages("\n%-36s", "Characteristics : ");
- if ((Header.Characteristics & 0x0002) == 0x0002)
- ShowMessages("Executable Image, ");
- if ((Header.Characteristics & 0x0020) == 0x0020)
- ShowMessages("Application can address > 2GB, ");
- if ((Header.Characteristics & 0x1000) == 0x1000)
- ShowMessages("System file (Kernel Mode Driver(I think)), ");
- if ((Header.Characteristics & 0x2000) == 0x2000)
- ShowMessages("Dll file, ");
- if ((Header.Characteristics & 0x4000) == 0x4000)
- ShowMessages("Application runs only in Uniprocessor, ");
-
- //
- // Determine Time Stamp
- //
- ShowMessages("\n%-36s%s",
- "Time Stamp :",
- ctime((const time_t *)&(Header.TimeDateStamp)));
-
- //
- // Determine number of sections
- //
- ShowMessages("%-36s%d", "No.sections(size) :", Header.NumberOfSections);
- ShowMessages("\n%-36s%d", "No.entries in symbol table :", Header.NumberOfSymbols);
- ShowMessages("\n%-36s%d",
- "Size of optional header :",
- Header.SizeOfOptionalHeader);
-
- ShowMessages("\n\nDumping PE Optional Header "
- "Info....\n-----------------------------------");
-
- if (Is32Bit)
- {
- //
- // Info about Optional Header
- //
- OpHeader32 = NtHeader32->OptionalHeader;
- ShowMessages("\n\nInfo of optional Header\n-----------------------");
- ShowMessages("\n%-36s%#x",
- "Address of Entry Point : ",
- 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", "Given file is a : ", OpHeader32.Magic == 0x20b ? "PE32+(64)" : "PE32");
- ShowMessages("\n%-36s%d", "Size of code segment(.text) : ", OpHeader32.SizeOfCode);
- ShowMessages("\n%-36s%#x",
- "Base address of code segment(RVA) :",
- OpHeader32.BaseOfCode);
- ShowMessages("\n%-36s%d",
- "Size of Initialized data : ",
- OpHeader32.SizeOfInitializedData);
-
- ShowMessages("\n%-36s%#x",
- "Base address of data segment(RVA) :",
- OpHeader32.BaseOfData);
-
- 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);
- }
- else
- {
- //
- // Info about Optional Header
- //
- OpHeader64 = NtHeader64->OptionalHeader;
- ShowMessages("\n\nInfo of optional Header\n-----------------------");
- ShowMessages("\n%-36s%#x",
- "Address of Entry Point : ",
- 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", "Given file is a : ", OpHeader64.Magic == 0x20b ? "PE32+(64)" : "PE32");
- ShowMessages("\n%-36s%d", "Size of code segment(.text) : ", OpHeader64.SizeOfCode);
- ShowMessages("\n%-36s%#x",
- "Base address of code segment(RVA) :",
- OpHeader64.BaseOfCode);
- ShowMessages("\n%-36s%d",
- "Size of Initialized data : ",
- OpHeader64.SizeOfInitializedData);
-
- 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);
- }
-
- ShowMessages("\n\nDumping Sections Header "
- "Info....\n--------------------------------");
-
- //
- // 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;
- }
-
- for (UINT32 i = 0; i < NumberOfSections; i++, SecHeader++)
- {
- if (Is32Bit)
- {
- 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);
- }
-
- ShowMessages("\n---------------------");
- ShowMessages("\n%-36s%s", "Section Header name : ", SecHeader->Name);
- ShowMessages("\n%-36s%#x",
- "ActualSize of code or data : ",
- SecHeader->Misc.VirtualSize);
- ShowMessages("\n%-36s%#x", "Virtual Address(RVA) :", SecHeader->VirtualAddress);
- ShowMessages("\n%-36s%#x",
- "Size of raw data (rounded to FA) : ",
- SecHeader->SizeOfRawData);
- ShowMessages("\n%-36s%#x",
- "Pointer to Raw Data : ",
- SecHeader->PointerToRawData);
- ShowMessages("\n%-36s%#x",
- "Pointer to Relocations : ",
- SecHeader->PointerToRelocations);
- ShowMessages("\n%-36s%#x",
- "Pointer to Line numbers : ",
- SecHeader->PointerToLinenumbers);
- ShowMessages("\n%-36s%#x",
- "Number of relocations : ",
- SecHeader->NumberOfRelocations);
- ShowMessages("\n%-36s%#x",
- "Number of line numbers : ",
- SecHeader->NumberOfLinenumbers);
- ShowMessages("\n%-36s%s", "Characteristics : ", "Contains ");
- if ((SecHeader->Characteristics & 0x20) == 0x20)
- ShowMessages("executable code, ");
- if ((SecHeader->Characteristics & 0x40) == 0x40)
- ShowMessages("initialized data, ");
- if ((SecHeader->Characteristics & 0x80) == 0x80)
- ShowMessages("uninitialized data, ");
- if ((SecHeader->Characteristics & 0x200) == 0x200)
- ShowMessages("comments and linker commands, ");
- if ((SecHeader->Characteristics & 0x10000000) == 0x10000000)
- ShowMessages("shareable data(via DLLs), ");
- if ((SecHeader->Characteristics & 0x40000000) == 0x40000000)
- ShowMessages("Readable, ");
- if ((SecHeader->Characteristics & 0x80000000) == 0x80000000)
- ShowMessages("Writable, ");
-
- //
- // show the hex dump if the user needs it
- //
- if (SectionToShow != NULL)
- {
- if (!_strcmpi(SectionToShow, (const char *)SecHeader->Name))
- {
- if (SecHeader->SizeOfRawData != 0)
- {
- if (Is32Bit)
- {
- PeHexDump((char *)((UINT64)DosHeader + SecHeader->PointerToRawData),
- SecHeader->SizeOfRawData,
- OpHeader32.ImageBase + SecHeader->VirtualAddress);
- }
- else
- {
- PeHexDump((char *)((UINT64)DosHeader + SecHeader->PointerToRawData),
- SecHeader->SizeOfRawData,
- (int)(OpHeader64.ImageBase + SecHeader->VirtualAddress));
- }
- }
- }
- }
- }
-
- ShowMessages("\n==============================================================="
- "================\n");
-
- //
- // Set result to true
- //
- Result = TRUE;
-
-Finished:
- //
- // Unmap and close the handles
- //
- UnmapViewOfFile(BaseAddr);
- CloseHandle(MapObjectHandle);
-
- return Result;
-}
-
-/**
- * @brief Detect whether PE is a 32-bit PE or 64-bit PE
- * @param AddressOfFile
- * @param Is32Bit
- *
- * @return BOOLEAN
- */
-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
-
- //
- // Open the EXE File
- //
- 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);
-
- if (BaseAddr == NULL)
- {
- CloseHandle(FileHandle);
-
- ShowMessages("err, unable to create map view of file (%x)\n", GetLastError());
- return FALSE;
- }
-
- //
- // Get the DOS Header Base
- //
- DosHeader = (PIMAGE_DOS_HEADER)BaseAddr; // 0x04000000
-
- //
- // Check for Valid DOS file
- //
- if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
- {
- Result = FALSE;
-
- ShowMessages("err, the selected file is not in a valid PE format\n");
- goto Finished;
- }
-
- //
- // Offset of NT Header is found at 0x3c location in DOS header specified by
- // e_lfanew
- // Get the Base of NT Header(PE Header) = DosHeader + RVA address of PE
- // header
- //
-
- NtHeader32 = (PIMAGE_NT_HEADERS32)((UINT64)(DosHeader) + (DosHeader->e_lfanew));
-
- //
- // Identify for valid PE file
- //
- if (NtHeader32->Signature != IMAGE_NT_SIGNATURE)
- {
- Result = FALSE;
-
- ShowMessages("err, invalid image NT signature\n");
- goto Finished;
- }
-
- //
- // Info about Optional Header
- //
- OpHeader32 = NtHeader32->OptionalHeader;
-
- //
- // Get the IMAGE FILE HEADER Structure
- //
- Header = NtHeader32->FileHeader;
-
- //
- // Only few are determined (for remaining refer
- // to the above specification)
- //
- switch (Header.Machine)
- {
- case IMAGE_FILE_MACHINE_I386:
- *Is32Bit = TRUE;
- Result = TRUE;
- goto Finished;
- break;
- case IMAGE_FILE_MACHINE_AMD64:
- *Is32Bit = FALSE;
- Result = TRUE;
- goto Finished;
- break;
- default:
- ShowMessages("err, PE file is not i386 or AMD64; thus, it's not supported "
- "in HyperDbg\n");
- Result = FALSE;
- goto Finished;
- break;
- }
-
-Finished:
- //
- // Unmap and close the handles
- //
- UnmapViewOfFile(BaseAddr);
- CloseHandle(MapObjectHandle);
-
- return Result;
-}
diff --git a/hyperdbg/hprdbgctrl/header/commands.h b/hyperdbg/hprdbgctrl/header/commands.h
deleted file mode 100644
index 6fe7d587..00000000
--- a/hyperdbg/hprdbgctrl/header/commands.h
+++ /dev/null
@@ -1,669 +0,0 @@
-/**
- * @file commands.h
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @author Alee Amini (alee@hyperdbg.org)
- * @brief The hyperdbg command interpreter and driver connector
- * @details
- * @version 0.1
- * @date 2020-04-11
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#pragma once
-
-using namespace std;
-
-//////////////////////////////////////////////////
-// Externs //
-//////////////////////////////////////////////////
-
-extern HANDLE g_DeviceHandle;
-
-//////////////////////////////////////////////////
-// Settings //
-//////////////////////////////////////////////////
-
-VOID
-CommandSettingsLoadDefaultValuesFromConfigFile();
-
-VOID
-CommandSettingsSetValueFromConfigFile(std::string OptionName, std::string OptionValue);
-
-BOOLEAN
-CommandSettingsGetValueFromConfigFile(std::string OptionName, std::string & OptionValue);
-
-//////////////////////////////////////////////////
-// Functions //
-//////////////////////////////////////////////////
-
-int
-ReadCpuDetails();
-
-VOID
-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
-ShowMemoryCommandDD(unsigned char * 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
-ShowMemoryCommandDQ(unsigned char * 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);
-
-int
-HyperDbgDisassembler64(unsigned char * 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);
-
-UINT32
-HyperDbgLengthDisassemblerEngine(
- unsigned char * BufferToDisassemble,
- UINT64 BuffLength,
- BOOLEAN Isx86_64);
-
-BOOLEAN
-HyperDbgCheckWhetherTheCurrentInstructionIsCall(
- unsigned char * BufferToDisassemble,
- UINT64 BuffLength,
- BOOLEAN Isx86_64,
- PUINT32 CallLength);
-
-BOOLEAN
-HyperDbgCheckWhetherTheCurrentInstructionIsCallOrRet(
- unsigned char * BufferToDisassemble,
- UINT64 CurrentRip,
- UINT32 BuffLength,
- BOOLEAN Isx86_64,
- PBOOLEAN IsRet);
-
-BOOLEAN
-HyperDbgCheckWhetherTheCurrentInstructionIsRet(
- unsigned char * BufferToDisassemble,
- UINT64 BuffLength,
- BOOLEAN Isx86_64);
-
-VOID
-HyperDbgReadMemoryAndDisassemble(DEBUGGER_SHOW_MEMORY_STYLE Style,
- UINT64 Address,
- DEBUGGER_READ_MEMORY_TYPE MemoryType,
- DEBUGGER_READ_READING_TYPE ReadingType,
- UINT32 Pid,
- UINT32 Size,
- PDEBUGGER_DT_COMMAND_OPTIONS DtDetails);
-
-VOID
-InitializeCommandsDictionary();
-
-VOID
-InitializeDebugger();
-
-VOID
-CommandDumpSaveIntoFile(PVOID Buffer, UINT32 Length);
-
-//////////////////////////////////////////////////
-// Type of Commands //
-//////////////////////////////////////////////////
-
-/**
- * @brief Command's function type
- *
- */
-typedef VOID (*CommandFuncType)(vector SplitCommand, string Command);
-
-/**
- * @brief Command's help function type
- *
- */
-typedef VOID (*CommandHelpFuncType)();
-
-/**
- * @brief Details of each command
- *
- */
-typedef struct _COMMAND_DETAIL
-{
- CommandFuncType CommandFunction;
- CommandHelpFuncType CommandHelpFunction;
- UINT64 CommandAttrib;
-
-} COMMAND_DETAIL, *PCOMMAND_DETAIL;
-
-/**
- * @brief Type saving commands and mapping to command string
- *
- */
-typedef std::map CommandType;
-
-/**
- * @brief Different attributes of commands
- *
- */
-#define DEBUGGER_COMMAND_ATTRIBUTE_EVENT \
- 0x1 | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE
-#define DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE 0x2
-#define DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_REMOTE_CONNECTION 0x4
-#define DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE 0x8
-#define DEBUGGER_COMMAND_ATTRIBUTE_REPEAT_ON_ENTER 0x10
-#define DEBUGGER_COMMAND_ATTRIBUTE_WONT_STOP_DEBUGGER_AGAIN 0x20
-
-/**
- * @brief Absolute local commands
- *
- */
-#define DEBUGGER_COMMAND_ATTRIBUTE_ABSOLUTE_LOCAL \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_REMOTE_CONNECTION
-
-/**
- * @brief Command's attributes
- *
- */
-#define DEBUGGER_COMMAND_CLEAR_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_ABSOLUTE_LOCAL
-
-#define DEBUGGER_COMMAND_HELP_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_ABSOLUTE_LOCAL
-
-#define DEBUGGER_COMMAND_CONNECT_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_ABSOLUTE_LOCAL
-
-#define DEBUGGER_COMMAND_LISTEN_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_ABSOLUTE_LOCAL
-
-#define DEBUGGER_COMMAND_G_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_ABSOLUTE_LOCAL | DEBUGGER_COMMAND_ATTRIBUTE_REPEAT_ON_ENTER
-
-#define DEBUGGER_COMMAND_ATTACH_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
-
-#define DEBUGGER_COMMAND_DETACH_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
-
-#define DEBUGGER_COMMAND_SWITCH_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
-
-#define DEBUGGER_COMMAND_START_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_WONT_STOP_DEBUGGER_AGAIN
-
-#define DEBUGGER_COMMAND_RESTART_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_WONT_STOP_DEBUGGER_AGAIN
-
-#define DEBUGGER_COMMAND_KILL_ATTRIBUTES NULL
-
-#define DEBUGGER_COMMAND_PROCESS_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
-
-#define DEBUGGER_COMMAND_THREAD_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
-
-#define DEBUGGER_COMMAND_SLEEP_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_ABSOLUTE_LOCAL
-
-#define DEBUGGER_COMMAND_EVENTS_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
-
-#define DEBUGGER_COMMAND_SETTINGS_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
-
-#define DEBUGGER_COMMAND_DISCONNECT_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_ABSOLUTE_LOCAL
-
-#define DEBUGGER_COMMAND_DEBUG_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_ABSOLUTE_LOCAL | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE
-
-#define DEBUGGER_COMMAND_DOT_STATUS_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_ABSOLUTE_LOCAL
-
-#define DEBUGGER_COMMAND_STATUS_ATTRIBUTES NULL
-
-#define DEBUGGER_COMMAND_LOAD_ATTRIBUTES NULL
-
-#define DEBUGGER_COMMAND_EXIT_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_ABSOLUTE_LOCAL
-
-#define DEBUGGER_COMMAND_FLUSH_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
-
-#define DEBUGGER_COMMAND_PAUSE_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_ABSOLUTE_LOCAL
-
-#define DEBUGGER_COMMAND_UNLOAD_ATTRIBUTES NULL
-
-#define DEBUGGER_COMMAND_SCRIPT_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_ABSOLUTE_LOCAL | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE
-
-#define DEBUGGER_COMMAND_OUTPUT_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE
-
-#define DEBUGGER_COMMAND_PRINT_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE | DEBUGGER_COMMAND_ATTRIBUTE_REPEAT_ON_ENTER
-
-#define DEBUGGER_COMMAND_EVAL_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE | DEBUGGER_COMMAND_ATTRIBUTE_REPEAT_ON_ENTER
-
-#define DEBUGGER_COMMAND_LOGOPEN_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_ABSOLUTE_LOCAL | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE
-
-#define DEBUGGER_COMMAND_LOGCLOSE_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_ABSOLUTE_LOCAL
-
-#define DEBUGGER_COMMAND_TEST_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
-
-#define DEBUGGER_COMMAND_CPU_ATTRIBUTES NULL
-
-#define DEBUGGER_COMMAND_WRMSR_ATTRIBUTES NULL
-
-#define DEBUGGER_COMMAND_RDMSR_ATTRIBUTES NULL
-
-#define DEBUGGER_COMMAND_VA2PA_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
-
-#define DEBUGGER_COMMAND_PA2VA_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
-
-#define DEBUGGER_COMMAND_FORMATS_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE | DEBUGGER_COMMAND_ATTRIBUTE_REPEAT_ON_ENTER
-
-#define DEBUGGER_COMMAND_PTE_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
-
-#define DEBUGGER_COMMAND_CORE_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
-
-#define DEBUGGER_COMMAND_MONITOR_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
-
-#define DEBUGGER_COMMAND_VMCALL_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
-
-#define DEBUGGER_COMMAND_EPTHOOK_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
-
-#define DEBUGGER_COMMAND_EPTHOOK2_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
-
-#define DEBUGGER_COMMAND_CPUID_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
-
-#define DEBUGGER_COMMAND_MSRREAD_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
-
-#define DEBUGGER_COMMAND_MSRWRITE_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
-
-#define DEBUGGER_COMMAND_TSC_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
-
-#define DEBUGGER_COMMAND_PMC_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
-
-#define DEBUGGER_COMMAND_CRWRITE_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
-
-#define DEBUGGER_COMMAND_DR_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
-
-#define DEBUGGER_COMMAND_IOIN_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
-
-#define DEBUGGER_COMMAND_IOOUT_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
-
-#define DEBUGGER_COMMAND_EXCEPTION_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
-
-#define DEBUGGER_COMMAND_INTERRUPT_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
-
-#define DEBUGGER_COMMAND_SYSCALL_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
-
-#define DEBUGGER_COMMAND_SYSRET_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
-
-#define DEBUGGER_COMMAND_MODE_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
-
-#define DEBUGGER_COMMAND_TRACE_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_EVENT
-
-#define DEBUGGER_COMMAND_HIDE_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE
-
-#define DEBUGGER_COMMAND_UNHIDE_ATTRIBUTES NULL
-
-#define DEBUGGER_COMMAND_MEASURE_ATTRIBUTES NULL
-
-#define DEBUGGER_COMMAND_LM_ATTRIBUTES NULL
-
-#define DEBUGGER_COMMAND_P_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | DEBUGGER_COMMAND_ATTRIBUTE_REPEAT_ON_ENTER
-
-#define DEBUGGER_COMMAND_T_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | DEBUGGER_COMMAND_ATTRIBUTE_REPEAT_ON_ENTER
-
-#define DEBUGGER_COMMAND_I_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | DEBUGGER_COMMAND_ATTRIBUTE_REPEAT_ON_ENTER
-
-#define DEBUGGER_COMMAND_D_AND_U_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE | DEBUGGER_COMMAND_ATTRIBUTE_REPEAT_ON_ENTER
-
-#define DEBUGGER_COMMAND_E_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE
-
-#define DEBUGGER_COMMAND_S_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE
-
-#define DEBUGGER_COMMAND_R_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE | DEBUGGER_COMMAND_ATTRIBUTE_REPEAT_ON_ENTER
-
-#define DEBUGGER_COMMAND_BP_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE
-
-#define DEBUGGER_COMMAND_BE_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
-
-#define DEBUGGER_COMMAND_BD_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
-
-#define DEBUGGER_COMMAND_BC_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
-
-#define DEBUGGER_COMMAND_BL_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
-
-#define DEBUGGER_COMMAND_SYMPATH_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE
-
-#define DEBUGGER_COMMAND_SYM_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE
-
-#define DEBUGGER_COMMAND_X_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE
-
-#define DEBUGGER_COMMAND_PREALLOC_ATTRIBUTES NULL
-
-#define DEBUGGER_COMMAND_PREACTIVATE_ATTRIBUTES NULL
-
-#define DEBUGGER_COMMAND_K_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
-
-#define DEBUGGER_COMMAND_DT_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE | DEBUGGER_COMMAND_ATTRIBUTE_REPEAT_ON_ENTER
-
-#define DEBUGGER_COMMAND_STRUCT_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE
-
-#define DEBUGGER_COMMAND_PE_ATTRIBUTES NULL
-
-// #define DEBUGGER_COMMAND_REV_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_WONT_STOP_DEBUGGER_AGAIN
-#define DEBUGGER_COMMAND_REV_ATTRIBUTES NULL
-
-#define DEBUGGER_COMMAND_TRACK_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
-
-#define DEBUGGER_COMMAND_PAGEIN_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
-
-#define DEBUGGER_COMMAND_DUMP_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_CASE_SENSITIVE
-
-#define DEBUGGER_COMMAND_GU_ATTRIBUTES \
- DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE | DEBUGGER_COMMAND_ATTRIBUTE_REPEAT_ON_ENTER
-
-//////////////////////////////////////////////////
-// Command Functions //
-//////////////////////////////////////////////////
-
-VOID
-CommandTest(vector SplitCommand, string Command);
-
-VOID
-CommandClearScreen(vector SplitCommand, string Command);
-
-VOID
-CommandReadMemoryAndDisassembler(vector SplitCommand,
- string Command);
-
-VOID
-CommandConnect(vector SplitCommand, string Command);
-
-VOID
-CommandLoad(vector SplitCommand, string Command);
-
-VOID
-CommandUnload(vector SplitCommand, string Command);
-
-VOID
-CommandScript(vector SplitCommand, string Command);
-
-VOID
-CommandCpu(vector SplitCommand, string Command);
-
-VOID
-CommandExit(vector SplitCommand, string Command);
-
-VOID
-CommandDisconnect(vector SplitCommand, string Command);
-
-VOID
-CommandFormats(vector SplitCommand, string Command);
-
-VOID
-CommandRdmsr(vector SplitCommand, string Command);
-
-VOID
-CommandWrmsr(vector SplitCommand, string Command);
-
-VOID
-CommandPte(vector SplitCommand, string Command);
-
-VOID
-CommandMonitor(vector SplitCommand, string Command);
-
-VOID
-CommandSyscallAndSysret(vector SplitCommand, string Command);
-
-VOID
-CommandEptHook(vector SplitCommand, string Command);
-
-VOID
-CommandEptHook2(vector SplitCommand, string Command);
-
-VOID
-CommandCpuid(vector SplitCommand, string Command);
-
-VOID
-CommandMsrread(vector SplitCommand, string Command);
-
-VOID
-CommandMsrwrite(vector SplitCommand, string Command);
-
-VOID
-CommandTsc(vector SplitCommand, string Command);
-
-VOID
-CommandPmc(vector SplitCommand, string Command);
-
-VOID
-CommandException(vector SplitCommand, string Command);
-
-VOID
-CommandCrwrite(vector SplitCommand, string Command);
-
-VOID
-CommandDr(vector SplitCommand, string Command);
-
-VOID
-CommandInterrupt(vector SplitCommand, string Command);
-
-VOID
-CommandIoin(vector SplitCommand, string Command);
-
-VOID
-CommandIoout(vector SplitCommand, string Command);
-
-VOID
-CommandVmcall(vector SplitCommand, string Command);
-
-VOID
-CommandMode(vector SplitCommand, string Command);
-
-VOID
-CommandTrace(vector SplitCommand, string Command);
-
-VOID
-CommandHide(vector SplitCommand, string Command);
-
-VOID
-CommandUnhide(vector SplitCommand, string Command);
-
-VOID
-CommandLogopen(vector SplitCommand, string Command);
-
-VOID
-CommandLogclose(vector SplitCommand, string Command);
-
-VOID
-CommandVa2pa(vector SplitCommand, string Command);
-
-VOID
-CommandPa2va(vector SplitCommand, string Command);
-
-VOID
-CommandEvents(vector SplitCommand, string Command);
-
-VOID
-CommandG(vector SplitCommand, string Command);
-
-VOID
-CommandLm(vector SplitCommand, string Command);
-
-VOID
-CommandSleep(vector SplitCommand, string Command);
-
-VOID
-CommandEditMemory(vector SplitCommand, string Command);
-
-VOID
-CommandSearchMemory(vector SplitCommand, string Command);
-
-VOID
-CommandMeasure(vector SplitCommand, string Command);
-
-VOID
-CommandSettings(vector SplitCommand, string Command);
-
-VOID
-CommandFlush(vector SplitCommand, string Command);
-
-VOID
-CommandPause(vector SplitCommand, string Command);
-
-VOID
-CommandListen(vector SplitCommand, string Command);
-
-VOID
-CommandStatus(vector SplitCommand, string Command);
-
-VOID
-CommandAttach(vector SplitCommand, string Command);
-
-VOID
-CommandDetach(vector SplitCommand, string Command);
-
-VOID
-CommandStart(vector SplitCommand, string Command);
-
-VOID
-CommandRestart(vector SplitCommand, string Command);
-
-VOID
-CommandSwitch(vector SplitCommand, string Command);
-
-VOID
-CommandKill(vector SplitCommand, string Command);
-
-VOID
-CommandT(vector SplitCommand, string Command);
-
-VOID
-CommandI(vector SplitCommand, string Command);
-
-VOID
-CommandPrint(vector SplitCommand, string Command);
-
-VOID
-CommandOutput(vector SplitCommand, string Command);
-
-VOID
-CommandDebug(vector SplitCommand, string Command);
-
-VOID
-CommandP(vector SplitCommand, string Command);
-
-VOID
-CommandCore(vector SplitCommand, string Command);
-
-VOID
-CommandProcess(vector SplitCommand, string Command);
-
-VOID
-CommandThread(vector SplitCommand, string Command);
-
-VOID
-CommandEval(vector SplitCommand, string Command);
-
-VOID
-CommandR(vector SplitCommand, string Command);
-
-VOID
-CommandBp(vector SplitCommand, string Command);
-
-VOID
-CommandBl(vector SplitCommand, string Command);
-
-VOID
-CommandBe(vector SplitCommand, string Command);
-
-VOID
-CommandBd(vector SplitCommand, string Command);
-
-VOID
-CommandBc(vector SplitCommand, string Command);
-
-VOID
-CommandSympath(vector SplitCommand, string Command);
-
-VOID
-CommandSym(vector SplitCommand, string Command);
-
-VOID
-CommandX(vector SplitCommand, string Command);
-
-VOID
-CommandPrealloc(vector SplitCommand, string Command);
-
-VOID
-CommandPreactivate(vector SplitCommand, string Command);
-
-VOID
-CommandDtAndStruct(vector SplitCommand, string Command);
-
-VOID
-CommandK(vector SplitCommand, string Command);
-
-VOID
-CommandPe(vector SplitCommand, string Command);
-
-VOID
-CommandRev(vector SplitCommand, string Command);
-
-VOID
-CommandTrack(vector SplitCommand, string Command);
-
-VOID
-CommandPagein(vector SplitCommand, string Command);
-
-VOID
-CommandDump(vector SplitCommand, string Command);
-
-VOID
-CommandGu(vector SplitCommand, string Command);
diff --git a/hyperdbg/hprdbgctrl/header/common.h b/hyperdbg/hprdbgctrl/header/common.h
deleted file mode 100644
index f807cd59..00000000
--- a/hyperdbg/hprdbgctrl/header/common.h
+++ /dev/null
@@ -1,203 +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 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);
-
-vector
-SplitIp(const string & str, char delim);
-
-BOOLEAN
-IsHexNotation(const string & s);
-
-vector
-HexToBytes(const string & hex);
-
-BOOLEAN
-ConvertStringToUInt64(string TextToConvert, PUINT64 Result);
-
-BOOLEAN
-ConvertStringToUInt32(string TextToConvert, PUINT32 Result);
-
-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);
-
-VOID
-SplitPathAndArgs(std::vector & Qargs, const std::string & Command);
-
-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);
diff --git a/hyperdbg/hprdbgctrl/header/install.h b/hyperdbg/hprdbgctrl/header/install.h
deleted file mode 100644
index 3713d725..00000000
--- a/hyperdbg/hprdbgctrl/header/install.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * @file hprdbgctrl.h
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief Main interface to connect applications to driver headers
- * @details
- * @version 0.1
- * @date 2020-04-11
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#pragma once
-
-//
-// The following ifdef block is the standard way of creating macros which make
-// exporting from a DLL simpler. All files within this DLL are compiled with the
-// HPRDBGCTRL_EXPORTS symbol defined on the command line. This symbol should not
-// be defined on any project that uses this DLL. This way any other project
-// whose source files include this file see HPRDBGCTRL_API functions as being
-// imported from a DLL, whereas this DLL sees symbols defined with this macro as
-// being exported.
-//
-
-#ifdef HPRDBGCTRL_EXPORTS
-# define HPRDBGCTRL_API __declspec(dllexport)
-#else
-# define HPRDBGCTRL_API __declspec(dllimport)
-#endif
-
-//////////////////////////////////////////////////
-// Installer //
-//////////////////////////////////////////////////
-
-#define DRIVER_FUNC_INSTALL 0x01
-#define DRIVER_FUNC_STOP 0x02
-#define DRIVER_FUNC_REMOVE 0x03
-
-BOOLEAN
-ManageDriver(_In_ LPCTSTR DriverName, _In_ LPCTSTR ServiceName, _In_ UINT16 Function);
-
-BOOLEAN
-SetupDriverName(const CHAR * DriverName,
- _Inout_updates_bytes_all_(BufferLength) PCHAR DriverLocation,
- ULONG BufferLength);
diff --git a/hyperdbg/hprdbgctrl/header/pe-parser.h b/hyperdbg/hprdbgctrl/header/pe-parser.h
deleted file mode 100644
index 960f034a..00000000
--- a/hyperdbg/hprdbgctrl/header/pe-parser.h
+++ /dev/null
@@ -1,22 +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);
diff --git a/hyperdbg/hprdbgctrl/pch.h b/hyperdbg/hprdbgctrl/pch.h
deleted file mode 100644
index 6eed2c9a..00000000
--- a/hyperdbg/hprdbgctrl/pch.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/**
- * @file pch.h
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief header file corresponding to the pre-compiled header
- * @details
- * @version 0.1
- * @date 2020-04-11
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#pragma once
-
-//
-// add headers that you want to pre-compile here
-//
-
-//
-// Windows SDK headers
-//
-
-#define WIN32_LEAN_AND_MEAN
-
-//
-// IA32-doc has structures for the entire intel SDM.
-//
-
-#define USE_LIB_IA32
-#if defined(USE_LIB_IA32)
-# pragma warning(push, 0)
-// # pragma warning(disable : 4201) // suppress nameless struct/union warning
-# include
-# pragma warning(pop)
-typedef RFLAGS * PRFLAGS;
-#endif // USE_LIB_IA32
-
-//
-// Native API header files for the Process Hacker project.
-//
-#define USE__NATIVE_PHNT_HEADERS
-
-#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 7
-# define PHNT_PATCH_FOR_HYPERDBG TRUE
-
-# include
-# include
-
-#elif defined(USE_NATIVE_SDK_HEADERS)
-
-# include
-# include
-# include
-
-#endif
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-//
-// STL headers
-//
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
\ No newline at end of file
+
diff --git a/hyperdbg/hyperdbg-test/pch.h b/hyperdbg/hyperdbg-test/pch.h
index 8b856ad6..0d6f1d11 100644
--- a/hyperdbg/hyperdbg-test/pch.h
+++ b/hyperdbg/hyperdbg-test/pch.h
@@ -11,6 +11,16 @@
*/
#pragma once
+//
+// namespace
+//
+using namespace std;
+
+//
+// Environment headers
+//
+#include "platform/general/header/Environment.h"
+
//
// General Headers
//
@@ -23,13 +33,35 @@
#include
#include
#include
+#include
+#include
+
+//
+// SDK and config headers
+//
+#include "SDK/HyperDbgSdk.h"
+#include "config/Definition.h"
//
// Program Defined Headers
//
-#include "SDK/HyperDbgSdk.h"
-#include "Definition.h"
-#include "..\hyperdbg-test\header\namedpipe.h"
-#include "..\hyperdbg-test\header\routines.h"
+#include "header/namedpipe.h"
+#include "header/routines.h"
+#include "header/testcases.h"
+#include "header/pdb-identity.h"
+#include "header/codeview-rsds.h"
-using namespace std;
+//
+// Components
+//
+#include "../include/components/pe/header/pe-image-reader.h"
+
+//
+// Hardware Debugger Headers
+//
+#include "header/hwdbg-tests.h"
+
+//
+// import libhyperdbg
+//
+#include "SDK/imports/user/HyperDbgLibImports.h"
diff --git a/hyperdbg/hyperdbg-test/test-cases.txt b/hyperdbg/hyperdbg-test/test-cases.txt
deleted file mode 100644
index 8570e0be..00000000
--- a/hyperdbg/hyperdbg-test/test-cases.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-output create TestOutputName namedpipe \\\\.\\Pipe\\HyperDbgOutputTest
-output open TestOutputName
-!epthook [ExAllocatePoolWithTag] script { print(@rax); } output {TestOutputName}
\ No newline at end of file
diff --git a/hyperdbg/hyperdbg.sln b/hyperdbg/hyperdbg.sln
index e6b084f3..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
@@ -11,26 +11,24 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperdbg-cli", "hyperdbg-cl
{C3DC85E1-0559-4B58-9792-DE421472DFE9} = {C3DC85E1-0559-4B58-9792-DE421472DFE9}
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hprdbghv", "hprdbghv\hprdbghv.vcxproj", "{BB17323A-2460-4AE1-8AFE-B367400B934F}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperhv", "hyperhv\hyperhv.vcxproj", "{BB17323A-2460-4AE1-8AFE-B367400B934F}"
ProjectSection(ProjectDependencies) = postProject
{2D988267-CC53-41E3-936A-48CEF9049DF5} = {2D988267-CC53-41E3-936A-48CEF9049DF5}
+ {B226530A-14B1-40AC-B82E-D9057400E7EE} = {B226530A-14B1-40AC-B82E-D9057400E7EE}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "include", "include", "{1997E4B6-FE49-4358-ADF1-CDDB5739508E}"
- ProjectSection(SolutionItems) = preProject
- include\Configuration.h = include\Configuration.h
- include\Definition.h = include\Definition.h
- include\ZycoreExportConfig.h = include\ZycoreExportConfig.h
- include\ZydisExportConfig.h = include\ZydisExportConfig.h
- EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hprdbgctrl", "hprdbgctrl\hprdbgctrl.vcxproj", "{809C3AD5-3211-4992-A472-9D81D124C5FA}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libhyperdbg", "libhyperdbg\libhyperdbg.vcxproj", "{809C3AD5-3211-4992-A472-9D81D124C5FA}"
ProjectSection(ProjectDependencies) = postProject
{AFDD7028-1ED9-442E-8A3D-01CFA3AA1CAA} = {AFDD7028-1ED9-442E-8A3D-01CFA3AA1CAA}
{C2D44C60-3F23-4972-8F60-21083B9FB112} = {C2D44C60-3F23-4972-8F60-21083B9FB112}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperdbg-test", "hyperdbg-test\hyperdbg-test.vcxproj", "{C3DC85E1-0559-4B58-9792-DE421472DFE9}"
+ ProjectSection(ProjectDependencies) = postProject
+ {809C3AD5-3211-4992-A472-9D81D124C5FA} = {809C3AD5-3211-4992-A472-9D81D124C5FA}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "script-engine", "script-engine\script-engine.vcxproj", "{C2D44C60-3F23-4972-8F60-21083B9FB112}"
ProjectSection(ProjectDependencies) = postProject
@@ -51,8 +49,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SDK", "SDK", "{7EA9E1E8-428
include\SDK\HyperDbgSdk.h = include\SDK\HyperDbgSdk.h
EndProjectSection
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Headers", "Headers", "{D67D603F-4F99-4C0B-94BE-F4A2C6CC22B5}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "headers", "headers", "{D67D603F-4F99-4C0B-94BE-F4A2C6CC22B5}"
ProjectSection(SolutionItems) = preProject
+ include\SDK\Headers\Assertions.h = include\SDK\Headers\Assertions.h
include\SDK\Headers\BasicTypes.h = include\SDK\Headers\BasicTypes.h
include\SDK\Headers\Connection.h = include\SDK\Headers\Connection.h
include\SDK\Headers\Constants.h = include\SDK\Headers\Constants.h
@@ -61,7 +60,12 @@ 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
EndProjectSection
EndProject
@@ -69,7 +73,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "script-eval", "script-eval"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "header", "header", "{4C47AB91-DF41-4741-80AF-FD87C32A961E}"
ProjectSection(SolutionItems) = preProject
- script-eval\header\ScriptEngineCommonDefinitions.h = script-eval\header\ScriptEngineCommonDefinitions.h
script-eval\header\ScriptEngineHeader.h = script-eval\header\ScriptEngineHeader.h
script-eval\header\ScriptEngineInternalHeader.h = script-eval\header\ScriptEngineInternalHeader.h
EndProjectSection
@@ -83,33 +86,24 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "code", "code", "{952986BC-7
script-eval\code\ScriptEngineEval.c = script-eval\code\ScriptEngineEval.c
EndProjectSection
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Imports", "Imports", "{B3D9DA75-8FBD-4A2C-826A-B50406396EC4}"
- ProjectSection(SolutionItems) = preProject
- include\SDK\Imports\HyperDbgCtrlImports.h = include\SDK\Imports\HyperDbgCtrlImports.h
- include\SDK\Imports\HyperDbgHyperLogImports.h = include\SDK\Imports\HyperDbgHyperLogImports.h
- include\SDK\Imports\HyperDbgHyperLogIntrinsics.h = include\SDK\Imports\HyperDbgHyperLogIntrinsics.h
- include\SDK\Imports\HyperDbgRevImports.h = include\SDK\Imports\HyperDbgRevImports.h
- include\SDK\Imports\HyperDbgScriptImports.h = include\SDK\Imports\HyperDbgScriptImports.h
- include\SDK\Imports\HyperDbgSymImports.h = include\SDK\Imports\HyperDbgSymImports.h
- include\SDK\Imports\HyperDbgVmmImports.h = include\SDK\Imports\HyperDbgVmmImports.h
- EndProjectSection
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "imports", "imports", "{B3D9DA75-8FBD-4A2C-826A-B50406396EC4}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{38E28A69-09A9-4C7E-B0F1-49E8A3B5AA0B}"
- ProjectSection(SolutionItems) = preProject
- include\SDK\Examples\example.py = include\SDK\Examples\example.py
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hprdbgkd", "hprdbgkd\hprdbgkd.vcxproj", "{AFDD7028-1ED9-442E-8A3D-01CFA3AA1CAA}"
+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
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperlog", "hyperlog\hyperlog.vcxproj", "{AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules", "Modules", "{13E49D84-7EA0-43A2-9B60-4B408A4C7602}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{13E49D84-7EA0-43A2-9B60-4B408A4C7602}"
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
@@ -150,167 +144,255 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "header", "header", "{D82074
include\components\optimizations\header\OptimizationsExamples.h = include\components\optimizations\header\OptimizationsExamples.h
EndProjectSection
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{9749520E-64FF-4633-855B-54BC541CDBB6}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "platform", "platform", "{9A711E36-8A78-4CE6-A34D-F681AF89A919}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperdbg_app", "include\SDK\Examples\hyperdbg_app\hprdbgrev.vcxproj", "{991B8FA7-F75E-4D8A-A0BD-636FE68B6AF4}"
- ProjectSection(ProjectDependencies) = postProject
- {809C3AD5-3211-4992-A472-9D81D124C5FA} = {809C3AD5-3211-4992-A472-9D81D124C5FA}
- {C2D44C60-3F23-4972-8F60-21083B9FB112} = {C2D44C60-3F23-4972-8F60-21083B9FB112}
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "user", "user", "{015523BA-4326-4A84-9CB5-E1E9B6182209}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "kernel", "kernel", "{D0E5A2D1-787E-4129-A75B-34DD4D5FDFC7}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "code", "code", "{6498728B-D9B0-4CAB-A9E3-ACE5BC371010}"
+ ProjectSection(SolutionItems) = preProject
+ 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("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperdbg_driver", "include\SDK\Examples\hyperdbg_driver\hyperdbg_driver.vcxproj", "{79AB8BD3-03A4-4B65-ABF6-313C10A00CC5}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "header", "header", "{AA41FFF1-A730-433E-8D26-13DA5B653825}"
+ ProjectSection(SolutionItems) = preProject
+ 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\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}"
+ ProjectSection(SolutionItems) = preProject
+ include\SDK\Imports\User\HyperDbgLibImports.h = include\SDK\Imports\User\HyperDbgLibImports.h
+ include\SDK\Imports\User\HyperDbgScriptImports.h = include\SDK\Imports\User\HyperDbgScriptImports.h
+ include\SDK\Imports\User\HyperDbgSymImports.h = include\SDK\Imports\User\HyperDbgSymImports.h
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "kernel", "kernel", "{947577A8-A9A5-4F90-8883-5FB722FE58E2}"
+ ProjectSection(SolutionItems) = preProject
+ 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
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "zydis", "zydis", "{08BF9299-FCE9-439C-A66C-1C8AFEC93866}"
+ ProjectSection(SolutionItems) = preProject
+ include\zydis\ZycoreExportConfig.h = include\zydis\ZycoreExportConfig.h
+ include\zydis\ZydisExportConfig.h = include\zydis\ZydisExportConfig.h
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "keystone", "keystone", "{7271D70C-319A-455C-AD4A-BE0BC46FEE15}"
+ ProjectSection(SolutionItems) = preProject
+ include\keystone\arm.h = include\keystone\arm.h
+ include\keystone\arm64.h = include\keystone\arm64.h
+ include\keystone\evm.h = include\keystone\evm.h
+ include\keystone\hexagon.h = include\keystone\hexagon.h
+ include\keystone\keystone.h = include\keystone\keystone.h
+ include\keystone\mips.h = include\keystone\mips.h
+ include\keystone\ppc.h = include\keystone\ppc.h
+ include\keystone\riscv.h = include\keystone\riscv.h
+ include\keystone\sparc.h = include\keystone\sparc.h
+ include\keystone\systemz.h = include\keystone\systemz.h
+ include\keystone\x86.h = include\keystone\x86.h
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{C5BCEFF7-8097-4331-A96E-4F4857774AD8}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "kernel", "kernel", "{5D395DF2-B247-48CC-924B-7F5D196C247A}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "user", "user", "{2104BCF9-035E-45AA-B744-68A5B8FEFF13}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperdbg_driver", "..\examples\kernel\hyperdbg_driver\hyperdbg_driver.vcxproj", "{79AB8BD3-03A4-4B65-ABF6-313C10A00CC5}"
ProjectSection(ProjectDependencies) = postProject
{BB17323A-2460-4AE1-8AFE-B367400B934F} = {BB17323A-2460-4AE1-8AFE-B367400B934F}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperdbg_app", "..\examples\user\hyperdbg_app\hyperdbg_app.vcxproj", "{991B8FA7-F75E-4D8A-A0BD-636FE68B6AF4}"
+ ProjectSection(ProjectDependencies) = postProject
+ {809C3AD5-3211-4992-A472-9D81D124C5FA} = {809C3AD5-3211-4992-A472-9D81D124C5FA}
+ 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
+ include\hyper-v\HypervTlfs.h = include\hyper-v\HypervTlfs.h
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "config", "config", "{03550856-D63F-4069-87E1-8BF2F129DBE3}"
+ ProjectSection(SolutionItems) = preProject
+ include\config\Configuration.h = include\config\Configuration.h
+ 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|ARM64 = debug|ARM64
debug|x64 = debug|x64
- debug|x86 = debug|x86
- release|ARM64 = release|ARM64
release|x64 = release|x64
- release|x86 = release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {FBCBBBAD-4EAE-469E-827F-F59FE9E7375B}.debug|ARM64.ActiveCfg = debug|x64
- {FBCBBBAD-4EAE-469E-827F-F59FE9E7375B}.debug|ARM64.Build.0 = debug|x64
{FBCBBBAD-4EAE-469E-827F-F59FE9E7375B}.debug|x64.ActiveCfg = debug|x64
{FBCBBBAD-4EAE-469E-827F-F59FE9E7375B}.debug|x64.Build.0 = debug|x64
- {FBCBBBAD-4EAE-469E-827F-F59FE9E7375B}.debug|x86.ActiveCfg = debug|x64
- {FBCBBBAD-4EAE-469E-827F-F59FE9E7375B}.debug|x86.Build.0 = debug|x64
- {FBCBBBAD-4EAE-469E-827F-F59FE9E7375B}.release|ARM64.ActiveCfg = release|x64
- {FBCBBBAD-4EAE-469E-827F-F59FE9E7375B}.release|ARM64.Build.0 = release|x64
{FBCBBBAD-4EAE-469E-827F-F59FE9E7375B}.release|x64.ActiveCfg = release|x64
{FBCBBBAD-4EAE-469E-827F-F59FE9E7375B}.release|x64.Build.0 = release|x64
- {FBCBBBAD-4EAE-469E-827F-F59FE9E7375B}.release|x86.ActiveCfg = release|x64
- {FBCBBBAD-4EAE-469E-827F-F59FE9E7375B}.release|x86.Build.0 = release|x64
- {BB17323A-2460-4AE1-8AFE-B367400B934F}.debug|ARM64.ActiveCfg = debug|x64
- {BB17323A-2460-4AE1-8AFE-B367400B934F}.debug|ARM64.Build.0 = debug|x64
{BB17323A-2460-4AE1-8AFE-B367400B934F}.debug|x64.ActiveCfg = debug|x64
{BB17323A-2460-4AE1-8AFE-B367400B934F}.debug|x64.Build.0 = debug|x64
- {BB17323A-2460-4AE1-8AFE-B367400B934F}.debug|x86.ActiveCfg = debug|x64
- {BB17323A-2460-4AE1-8AFE-B367400B934F}.debug|x86.Build.0 = debug|x64
- {BB17323A-2460-4AE1-8AFE-B367400B934F}.release|ARM64.ActiveCfg = release|x64
- {BB17323A-2460-4AE1-8AFE-B367400B934F}.release|ARM64.Build.0 = release|x64
{BB17323A-2460-4AE1-8AFE-B367400B934F}.release|x64.ActiveCfg = release|x64
{BB17323A-2460-4AE1-8AFE-B367400B934F}.release|x64.Build.0 = release|x64
- {BB17323A-2460-4AE1-8AFE-B367400B934F}.release|x86.ActiveCfg = release|x64
- {BB17323A-2460-4AE1-8AFE-B367400B934F}.release|x86.Build.0 = release|x64
- {809C3AD5-3211-4992-A472-9D81D124C5FA}.debug|ARM64.ActiveCfg = debug|x64
- {809C3AD5-3211-4992-A472-9D81D124C5FA}.debug|ARM64.Build.0 = debug|x64
{809C3AD5-3211-4992-A472-9D81D124C5FA}.debug|x64.ActiveCfg = debug|x64
{809C3AD5-3211-4992-A472-9D81D124C5FA}.debug|x64.Build.0 = debug|x64
- {809C3AD5-3211-4992-A472-9D81D124C5FA}.debug|x86.ActiveCfg = debug|x64
- {809C3AD5-3211-4992-A472-9D81D124C5FA}.debug|x86.Build.0 = debug|x64
- {809C3AD5-3211-4992-A472-9D81D124C5FA}.release|ARM64.ActiveCfg = release|x64
- {809C3AD5-3211-4992-A472-9D81D124C5FA}.release|ARM64.Build.0 = release|x64
{809C3AD5-3211-4992-A472-9D81D124C5FA}.release|x64.ActiveCfg = release|x64
{809C3AD5-3211-4992-A472-9D81D124C5FA}.release|x64.Build.0 = release|x64
- {809C3AD5-3211-4992-A472-9D81D124C5FA}.release|x86.ActiveCfg = release|x64
- {809C3AD5-3211-4992-A472-9D81D124C5FA}.release|x86.Build.0 = release|x64
- {C3DC85E1-0559-4B58-9792-DE421472DFE9}.debug|ARM64.ActiveCfg = debug|x64
- {C3DC85E1-0559-4B58-9792-DE421472DFE9}.debug|ARM64.Build.0 = debug|x64
{C3DC85E1-0559-4B58-9792-DE421472DFE9}.debug|x64.ActiveCfg = debug|x64
- {C3DC85E1-0559-4B58-9792-DE421472DFE9}.debug|x86.ActiveCfg = debug|x64
- {C3DC85E1-0559-4B58-9792-DE421472DFE9}.debug|x86.Build.0 = debug|x64
- {C3DC85E1-0559-4B58-9792-DE421472DFE9}.release|ARM64.ActiveCfg = release|x64
- {C3DC85E1-0559-4B58-9792-DE421472DFE9}.release|ARM64.Build.0 = release|x64
+ {C3DC85E1-0559-4B58-9792-DE421472DFE9}.debug|x64.Build.0 = debug|x64
{C3DC85E1-0559-4B58-9792-DE421472DFE9}.release|x64.ActiveCfg = release|x64
- {C3DC85E1-0559-4B58-9792-DE421472DFE9}.release|x86.ActiveCfg = release|x64
- {C3DC85E1-0559-4B58-9792-DE421472DFE9}.release|x86.Build.0 = release|x64
- {C2D44C60-3F23-4972-8F60-21083B9FB112}.debug|ARM64.ActiveCfg = debug|x64
- {C2D44C60-3F23-4972-8F60-21083B9FB112}.debug|ARM64.Build.0 = debug|x64
{C2D44C60-3F23-4972-8F60-21083B9FB112}.debug|x64.ActiveCfg = debug|x64
{C2D44C60-3F23-4972-8F60-21083B9FB112}.debug|x64.Build.0 = debug|x64
- {C2D44C60-3F23-4972-8F60-21083B9FB112}.debug|x86.ActiveCfg = debug|x64
- {C2D44C60-3F23-4972-8F60-21083B9FB112}.debug|x86.Build.0 = debug|x64
- {C2D44C60-3F23-4972-8F60-21083B9FB112}.release|ARM64.ActiveCfg = release|x64
- {C2D44C60-3F23-4972-8F60-21083B9FB112}.release|ARM64.Build.0 = release|x64
{C2D44C60-3F23-4972-8F60-21083B9FB112}.release|x64.ActiveCfg = release|x64
{C2D44C60-3F23-4972-8F60-21083B9FB112}.release|x64.Build.0 = release|x64
- {C2D44C60-3F23-4972-8F60-21083B9FB112}.release|x86.ActiveCfg = release|x64
- {C2D44C60-3F23-4972-8F60-21083B9FB112}.release|x86.Build.0 = release|x64
- {2D988267-CC53-41E3-936A-48CEF9049DF5}.debug|ARM64.ActiveCfg = debug|x64
- {2D988267-CC53-41E3-936A-48CEF9049DF5}.debug|ARM64.Build.0 = debug|x64
{2D988267-CC53-41E3-936A-48CEF9049DF5}.debug|x64.ActiveCfg = debug|x64
{2D988267-CC53-41E3-936A-48CEF9049DF5}.debug|x64.Build.0 = debug|x64
- {2D988267-CC53-41E3-936A-48CEF9049DF5}.debug|x86.ActiveCfg = debug|x64
- {2D988267-CC53-41E3-936A-48CEF9049DF5}.debug|x86.Build.0 = debug|x64
- {2D988267-CC53-41E3-936A-48CEF9049DF5}.release|ARM64.ActiveCfg = release|x64
- {2D988267-CC53-41E3-936A-48CEF9049DF5}.release|ARM64.Build.0 = release|x64
{2D988267-CC53-41E3-936A-48CEF9049DF5}.release|x64.ActiveCfg = release|x64
{2D988267-CC53-41E3-936A-48CEF9049DF5}.release|x64.Build.0 = release|x64
- {2D988267-CC53-41E3-936A-48CEF9049DF5}.release|x86.ActiveCfg = release|x64
- {2D988267-CC53-41E3-936A-48CEF9049DF5}.release|x86.Build.0 = release|x64
- {9CA3E213-C43F-4C1D-A6ED-C6FC568D691B}.debug|ARM64.ActiveCfg = debug|x64
- {9CA3E213-C43F-4C1D-A6ED-C6FC568D691B}.debug|ARM64.Build.0 = debug|x64
{9CA3E213-C43F-4C1D-A6ED-C6FC568D691B}.debug|x64.ActiveCfg = debug|x64
{9CA3E213-C43F-4C1D-A6ED-C6FC568D691B}.debug|x64.Build.0 = debug|x64
- {9CA3E213-C43F-4C1D-A6ED-C6FC568D691B}.debug|x86.ActiveCfg = debug|x64
- {9CA3E213-C43F-4C1D-A6ED-C6FC568D691B}.debug|x86.Build.0 = debug|x64
- {9CA3E213-C43F-4C1D-A6ED-C6FC568D691B}.release|ARM64.ActiveCfg = release|x64
- {9CA3E213-C43F-4C1D-A6ED-C6FC568D691B}.release|ARM64.Build.0 = release|x64
{9CA3E213-C43F-4C1D-A6ED-C6FC568D691B}.release|x64.ActiveCfg = release|x64
{9CA3E213-C43F-4C1D-A6ED-C6FC568D691B}.release|x64.Build.0 = release|x64
- {9CA3E213-C43F-4C1D-A6ED-C6FC568D691B}.release|x86.ActiveCfg = release|x64
- {9CA3E213-C43F-4C1D-A6ED-C6FC568D691B}.release|x86.Build.0 = release|x64
- {06FB1AF7-647C-4BA4-860A-4533763440F9}.debug|ARM64.ActiveCfg = debug|x64
- {06FB1AF7-647C-4BA4-860A-4533763440F9}.debug|ARM64.Build.0 = debug|x64
{06FB1AF7-647C-4BA4-860A-4533763440F9}.debug|x64.ActiveCfg = debug|x64
{06FB1AF7-647C-4BA4-860A-4533763440F9}.debug|x64.Build.0 = debug|x64
- {06FB1AF7-647C-4BA4-860A-4533763440F9}.debug|x86.ActiveCfg = debug|x64
- {06FB1AF7-647C-4BA4-860A-4533763440F9}.debug|x86.Build.0 = debug|x64
- {06FB1AF7-647C-4BA4-860A-4533763440F9}.release|ARM64.ActiveCfg = release|x64
- {06FB1AF7-647C-4BA4-860A-4533763440F9}.release|ARM64.Build.0 = release|x64
{06FB1AF7-647C-4BA4-860A-4533763440F9}.release|x64.ActiveCfg = release|x64
{06FB1AF7-647C-4BA4-860A-4533763440F9}.release|x64.Build.0 = release|x64
- {06FB1AF7-647C-4BA4-860A-4533763440F9}.release|x86.ActiveCfg = release|x64
- {06FB1AF7-647C-4BA4-860A-4533763440F9}.release|x86.Build.0 = release|x64
- {AFDD7028-1ED9-442E-8A3D-01CFA3AA1CAA}.debug|ARM64.ActiveCfg = debug|x64
- {AFDD7028-1ED9-442E-8A3D-01CFA3AA1CAA}.debug|ARM64.Build.0 = debug|x64
{AFDD7028-1ED9-442E-8A3D-01CFA3AA1CAA}.debug|x64.ActiveCfg = debug|x64
{AFDD7028-1ED9-442E-8A3D-01CFA3AA1CAA}.debug|x64.Build.0 = debug|x64
- {AFDD7028-1ED9-442E-8A3D-01CFA3AA1CAA}.debug|x86.ActiveCfg = debug|x64
- {AFDD7028-1ED9-442E-8A3D-01CFA3AA1CAA}.debug|x86.Build.0 = debug|x64
- {AFDD7028-1ED9-442E-8A3D-01CFA3AA1CAA}.release|ARM64.ActiveCfg = release|x64
- {AFDD7028-1ED9-442E-8A3D-01CFA3AA1CAA}.release|ARM64.Build.0 = release|x64
{AFDD7028-1ED9-442E-8A3D-01CFA3AA1CAA}.release|x64.ActiveCfg = release|x64
{AFDD7028-1ED9-442E-8A3D-01CFA3AA1CAA}.release|x64.Build.0 = release|x64
- {AFDD7028-1ED9-442E-8A3D-01CFA3AA1CAA}.release|x86.ActiveCfg = release|x64
- {AFDD7028-1ED9-442E-8A3D-01CFA3AA1CAA}.release|x86.Build.0 = release|x64
- {AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D}.debug|ARM64.ActiveCfg = debug|x64
- {AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D}.debug|ARM64.Build.0 = debug|x64
{AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D}.debug|x64.ActiveCfg = debug|x64
{AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D}.debug|x64.Build.0 = debug|x64
- {AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D}.debug|x86.ActiveCfg = debug|x64
- {AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D}.debug|x86.Build.0 = debug|x64
- {AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D}.release|ARM64.ActiveCfg = release|x64
- {AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D}.release|ARM64.Build.0 = release|x64
{AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D}.release|x64.ActiveCfg = release|x64
{AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D}.release|x64.Build.0 = release|x64
- {AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D}.release|x86.ActiveCfg = release|x64
- {AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D}.release|x86.Build.0 = release|x64
- {991B8FA7-F75E-4D8A-A0BD-636FE68B6AF4}.debug|ARM64.ActiveCfg = debug|x64
- {991B8FA7-F75E-4D8A-A0BD-636FE68B6AF4}.debug|ARM64.Build.0 = debug|x64
- {991B8FA7-F75E-4D8A-A0BD-636FE68B6AF4}.debug|x64.ActiveCfg = debug|x64
- {991B8FA7-F75E-4D8A-A0BD-636FE68B6AF4}.debug|x86.ActiveCfg = debug|Win32
- {991B8FA7-F75E-4D8A-A0BD-636FE68B6AF4}.debug|x86.Build.0 = debug|Win32
- {991B8FA7-F75E-4D8A-A0BD-636FE68B6AF4}.release|ARM64.ActiveCfg = release|x64
- {991B8FA7-F75E-4D8A-A0BD-636FE68B6AF4}.release|ARM64.Build.0 = release|x64
- {991B8FA7-F75E-4D8A-A0BD-636FE68B6AF4}.release|x64.ActiveCfg = release|x64
- {991B8FA7-F75E-4D8A-A0BD-636FE68B6AF4}.release|x86.ActiveCfg = release|Win32
- {991B8FA7-F75E-4D8A-A0BD-636FE68B6AF4}.release|x86.Build.0 = release|Win32
- {79AB8BD3-03A4-4B65-ABF6-313C10A00CC5}.debug|ARM64.ActiveCfg = debug|ARM64
- {79AB8BD3-03A4-4B65-ABF6-313C10A00CC5}.debug|ARM64.Build.0 = debug|ARM64
{79AB8BD3-03A4-4B65-ABF6-313C10A00CC5}.debug|x64.ActiveCfg = debug|x64
- {79AB8BD3-03A4-4B65-ABF6-313C10A00CC5}.debug|x86.ActiveCfg = debug|x64
- {79AB8BD3-03A4-4B65-ABF6-313C10A00CC5}.debug|x86.Build.0 = debug|x64
- {79AB8BD3-03A4-4B65-ABF6-313C10A00CC5}.release|ARM64.ActiveCfg = release|ARM64
- {79AB8BD3-03A4-4B65-ABF6-313C10A00CC5}.release|ARM64.Build.0 = release|ARM64
{79AB8BD3-03A4-4B65-ABF6-313C10A00CC5}.release|x64.ActiveCfg = release|x64
- {79AB8BD3-03A4-4B65-ABF6-313C10A00CC5}.release|x86.ActiveCfg = release|x64
- {79AB8BD3-03A4-4B65-ABF6-313C10A00CC5}.release|x86.Build.0 = release|x64
+ {991B8FA7-F75E-4D8A-A0BD-636FE68B6AF4}.debug|x64.ActiveCfg = debug|x64
+ {991B8FA7-F75E-4D8A-A0BD-636FE68B6AF4}.release|x64.ActiveCfg = release|x64
+ {B226530A-14B1-40AC-B82E-D9057400E7EE}.debug|x64.ActiveCfg = debug|x64
+ {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
@@ -321,7 +403,6 @@ Global
{4C47AB91-DF41-4741-80AF-FD87C32A961E} = {2CC2975A-9B33-400D-840F-9A71BB312928}
{952986BC-7B3D-4F50-BC69-4D11FA52D9C5} = {2CC2975A-9B33-400D-840F-9A71BB312928}
{B3D9DA75-8FBD-4A2C-826A-B50406396EC4} = {7EA9E1E8-4283-4CEF-9629-C5C98CD706C7}
- {38E28A69-09A9-4C7E-B0F1-49E8A3B5AA0B} = {7EA9E1E8-4283-4CEF-9629-C5C98CD706C7}
{13E49D84-7EA0-43A2-9B60-4B408A4C7602} = {7EA9E1E8-4283-4CEF-9629-C5C98CD706C7}
{359218DB-0EBA-4889-8713-732FACAEF18D} = {1997E4B6-FE49-4358-ADF1-CDDB5739508E}
{DF15E9D4-976B-4E1D-B68F-9B67F93654BF} = {1997E4B6-FE49-4358-ADF1-CDDB5739508E}
@@ -331,9 +412,37 @@ Global
{165C089B-6860-4AEA-9F88-67559156C2E7} = {DF15E9D4-976B-4E1D-B68F-9B67F93654BF}
{FCB5111C-C7D9-4E65-8EF7-E9BB80E54B7D} = {165C089B-6860-4AEA-9F88-67559156C2E7}
{D8207406-263E-4831-A8E9-20C4ECE5CA15} = {165C089B-6860-4AEA-9F88-67559156C2E7}
- {9749520E-64FF-4633-855B-54BC541CDBB6} = {1997E4B6-FE49-4358-ADF1-CDDB5739508E}
- {991B8FA7-F75E-4D8A-A0BD-636FE68B6AF4} = {9749520E-64FF-4633-855B-54BC541CDBB6}
- {79AB8BD3-03A4-4B65-ABF6-313C10A00CC5} = {9749520E-64FF-4633-855B-54BC541CDBB6}
+ {9A711E36-8A78-4CE6-A34D-F681AF89A919} = {1997E4B6-FE49-4358-ADF1-CDDB5739508E}
+ {015523BA-4326-4A84-9CB5-E1E9B6182209} = {9A711E36-8A78-4CE6-A34D-F681AF89A919}
+ {D0E5A2D1-787E-4129-A75B-34DD4D5FDFC7} = {9A711E36-8A78-4CE6-A34D-F681AF89A919}
+ {6498728B-D9B0-4CAB-A9E3-ACE5BC371010} = {D0E5A2D1-787E-4129-A75B-34DD4D5FDFC7}
+ {AA41FFF1-A730-433E-8D26-13DA5B653825} = {D0E5A2D1-787E-4129-A75B-34DD4D5FDFC7}
+ {4BF590C3-1032-4DD2-BF87-BB9E5781977C} = {015523BA-4326-4A84-9CB5-E1E9B6182209}
+ {DBE32379-8D5A-4454-A1B6-ACC407881898} = {015523BA-4326-4A84-9CB5-E1E9B6182209}
+ {3C04357D-93B5-4472-94BB-8D22A1EB16DB} = {B3D9DA75-8FBD-4A2C-826A-B50406396EC4}
+ {947577A8-A9A5-4F90-8883-5FB722FE58E2} = {B3D9DA75-8FBD-4A2C-826A-B50406396EC4}
+ {08BF9299-FCE9-439C-A66C-1C8AFEC93866} = {1997E4B6-FE49-4358-ADF1-CDDB5739508E}
+ {7271D70C-319A-455C-AD4A-BE0BC46FEE15} = {1997E4B6-FE49-4358-ADF1-CDDB5739508E}
+ {5D395DF2-B247-48CC-924B-7F5D196C247A} = {C5BCEFF7-8097-4331-A96E-4F4857774AD8}
+ {2104BCF9-035E-45AA-B744-68A5B8FEFF13} = {C5BCEFF7-8097-4331-A96E-4F4857774AD8}
+ {79AB8BD3-03A4-4B65-ABF6-313C10A00CC5} = {5D395DF2-B247-48CC-924B-7F5D196C247A}
+ {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
new file mode 100644
index 00000000..85e1fe45
--- /dev/null
+++ b/hyperdbg/hyperevade/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/Mem.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"
+ "hyperevade.def"
+)
+include_directories(
+ "../include"
+ "header"
+)
+wdk_add_library(hyperevade SHARED
+ KMDF 1.15
+ ${SourceFiles}
+)
diff --git a/hyperdbg/hyperevade/code/SyscallFootprints.c b/hyperdbg/hyperevade/code/SyscallFootprints.c
new file mode 100644
index 00000000..33273254
--- /dev/null
+++ b/hyperdbg/hyperevade/code/SyscallFootprints.c
@@ -0,0 +1,1973 @@
+/**
+ * @file SyscallFootprints.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Try to hide SYSCALL methods from anti-debugging and anti-hypervisor
+ * @details
+ * @version 0.14
+ * @date 2025-06-08
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#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
+ *
+ * @param Regs The virtual processor's state of registers
+ * @return VOID
+ */
+VOID
+TransparentHandleSystemCallHook(GUEST_REGS * Regs)
+{
+ //
+ // If the transparent mode is not enabled, do nothing
+ //
+ if (!g_TransparentMode)
+ {
+ return;
+ }
+
+ PCHAR CallingProcess = g_Callbacks.CommonGetProcessNameFromProcessControlBlock(PsGetCurrentProcess());
+ UINT64 Context = Regs->rax;
+
+ //
+ // Skip the transparent mitigations of system calls when the caller process
+ // is a Windows process that should receive unmodified data
+ //
+ for (ULONG i = 0; i < (sizeof(TRANSPARENT_WIN_PROCESS_IGNORE) / sizeof(TRANSPARENT_WIN_PROCESS_IGNORE[0])); i++)
+ {
+ if (strstr(CallingProcess, TRANSPARENT_WIN_PROCESS_IGNORE[i]))
+ {
+ return;
+ }
+ }
+
+ if (Context == g_SystemCallNumbersInformation.SysNtQuerySystemInformation ||
+ Context == g_SystemCallNumbersInformation.SysNtQuerySystemInformationEx)
+ {
+ //
+ // Handle the NtQuerySystemInformation System call
+ //
+
+ TransparentHandleNtQuerySystemInformationSyscall(Regs);
+ }
+ else if (Context == g_SystemCallNumbersInformation.SysNtSystemDebugControl)
+ {
+ //
+ // Handle the NtSystemDebugControl System call
+ //
+ TransparentHandleNtSystemDebugControlSyscall(Regs);
+ }
+ else if (Context == g_SystemCallNumbersInformation.SysNtQueryAttributesFile)
+ {
+ //
+ // Handle the NtQueryAttributesFile System call
+ //
+ TransparentHandleNtQueryAttributesFileSyscall(Regs);
+ }
+ else if (Context == g_SystemCallNumbersInformation.SysNtOpenDirectoryObject)
+ {
+ //
+ // Handle the NtOpenDirectoryObject System call
+ //
+ TransparentHandleNtOpenDirectoryObjectSyscall(Regs);
+ }
+ else if (Context == g_SystemCallNumbersInformation.SysNtQueryDirectoryObject)
+ {
+ //
+ // Handle the NtQueryDirectoryObject System call
+ //
+ // TransparentHandleNtQueryDirectoryObjectSyscall(Regs);
+ }
+ else if (Context == g_SystemCallNumbersInformation.SysNtQueryInformationProcess)
+ {
+ //
+ // Handle the NtQueryInformationProcess System call
+ //
+ TransparentHandleNtQueryInformationProcessSyscall(Regs);
+ }
+ else if (Context == g_SystemCallNumbersInformation.SysNtQueryInformationThread)
+ {
+ //
+ // Handle the NtQueryInformationThread System call
+ //
+ // TransparentHandleNtQueryInformationThreadSyscall(Regs);
+ }
+ else if (Context == g_SystemCallNumbersInformation.SysNtOpenFile)
+ {
+ //
+ // Handle the NtOpenFile System call
+ //
+ TransparentHandleNtOpenFileSyscall(Regs);
+ }
+ else if (Context == g_SystemCallNumbersInformation.SysNtOpenKeyEx || Context == g_SystemCallNumbersInformation.SysNtOpenKey)
+ {
+ //
+ // Handle the NtOpenKey System call
+ //
+ TransparentHandleNtOpenKeySyscall(Regs);
+ }
+ else if (Context == g_SystemCallNumbersInformation.SysNtQueryValueKey)
+ {
+ //
+ // Handle the NtQueryValueKey System call
+ //
+ TransparentHandleNtQueryValueKeySyscall(Regs);
+ }
+ else if (Context == g_SystemCallNumbersInformation.SysNtEnumerateKey)
+ {
+ //
+ // Handle the NtEnumerateKey System call
+ //
+ TransparentHandleNtEnumerateKeySyscall(Regs);
+ }
+ else
+ {
+ //
+ // The syscall is not important to us
+ //
+ }
+}
+
+/**
+ * @brief Handle The NtQuerySystemInformation system call
+ * when the Transparent mode is enabled
+ *
+ * @param Regs The virtual processor's state of registers
+ * @return VOID
+ */
+VOID
+TransparentHandleNtQuerySystemInformationSyscall(GUEST_REGS * Regs)
+{
+ SYSCALL_CALLBACK_CONTEXT_PARAMS ContextParams = {0};
+
+ switch (Regs->r10)
+ {
+ case SystemProcessInformation:
+ case SystemExtendedProcessInformation:
+ {
+ ContextParams.OptionalParam1 = SystemProcessInformation;
+ ContextParams.OptionalParam2 = Regs->rdx;
+ ContextParams.OptionalParam3 = Regs->r8 - 0x400;
+
+ g_Callbacks.SyscallCallbackSetTrapFlagAfterSyscall(Regs,
+ HANDLE_TO_UINT32(PsGetCurrentProcessId()),
+ HANDLE_TO_UINT32(PsGetCurrentThreadId()),
+ Regs->rax,
+ &ContextParams);
+
+ break;
+ }
+ case SystemModuleInformation:
+ {
+ ContextParams.OptionalParam1 = SystemModuleInformation;
+ ContextParams.OptionalParam2 = Regs->rdx;
+ ContextParams.OptionalParam3 = Regs->r8;
+
+ g_Callbacks.SyscallCallbackSetTrapFlagAfterSyscall(Regs,
+ HANDLE_TO_UINT32(PsGetCurrentProcessId()),
+ HANDLE_TO_UINT32(PsGetCurrentThreadId()),
+ Regs->rax,
+ &ContextParams);
+
+ break;
+ }
+ case SystemKernelDebuggerInformation:
+ {
+ ContextParams.OptionalParam1 = SystemKernelDebuggerInformation;
+ ContextParams.OptionalParam2 = Regs->rdx;
+ ContextParams.OptionalParam3 = Regs->r8;
+
+ g_Callbacks.SyscallCallbackSetTrapFlagAfterSyscall(Regs,
+ HANDLE_TO_UINT32(PsGetCurrentProcessId()),
+ HANDLE_TO_UINT32(PsGetCurrentThreadId()),
+ Regs->rax,
+ &ContextParams);
+ break;
+ }
+ case SystemCodeIntegrityInformation:
+ {
+ ContextParams.OptionalParam1 = SystemCodeIntegrityInformation;
+ ContextParams.OptionalParam2 = Regs->rdx;
+ ContextParams.OptionalParam3 = 0x8;
+
+ g_Callbacks.SyscallCallbackSetTrapFlagAfterSyscall(Regs,
+ HANDLE_TO_UINT32(PsGetCurrentProcessId()),
+ HANDLE_TO_UINT32(PsGetCurrentThreadId()),
+ Regs->rax,
+ &ContextParams);
+ break;
+ }
+
+ //
+ // Currently SystemFirmwareTableInformation transparent handler is not implemented
+ // As the queries produce a data buffer too large to safely copy and modify in root-mode
+ //
+
+ // case SystemFirmwareTableInformation:
+ // {
+ //
+ // ContextParams.OptionalParam1 = SystemFirmwareTableInformation;
+ // ContextParams.OptionalParam2 = Regs->rdx;
+ // ContextParams.OptionalParam3 = Regs->r8;
+ // ContextParams.OptionalParam4 = Regs->r9;
+ //
+ // g_Callbacks.SyscallCallbackSetTrapFlagAfterSyscall(Regs,
+ // HANDLE_TO_UINT32(PsGetCurrentProcessId()),
+ // HANDLE_TO_UINT32(PsGetCurrentThreadId()),
+ // Regs->rax,
+ // &ContextParams);
+ // break;
+ // }
+ default:
+ {
+ return;
+ }
+ }
+}
+
+/**
+ * @brief Obtain a copy of the PWCHAR wide character string from a OBJECT_ATTRIBUTES structure at a guest virtual address
+ *
+ * @details Returns an allocated tagged memory pointer which needs to be freed with PlatformMemFreePool()
+ *
+ * @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
+TransparentGetObjectNameFromAttributesVirtualPointer(UINT64 virtPtr)
+{
+ // PVOID buf = PlatformMemAllocateZeroedNonPagedPool(sizeof(OBJECT_ATTRIBUTES));
+ OBJECT_ATTRIBUTES Buf = {0};
+
+ //
+ // Read the OBJECT_ATTRIBUTES structure from the virtual address pointer
+ //
+ if (g_Callbacks.MemoryMapperReadMemorySafeOnTargetProcess(virtPtr, &Buf, sizeof(OBJECT_ATTRIBUTES)))
+ {
+ // PVOID Namebuf = PlatformMemAllocateZeroedNonPagedPool(sizeof(UNICODE_STRING));
+ UNICODE_STRING NameBuf = {0};
+
+ //
+ // Read the UNICODE_STRING structure from a virtual address pointer, pointed to by OBJECT_ATTRIBUTES.ObjectName struct entry
+ //
+ if (!g_Callbacks.MemoryMapperReadMemorySafeOnTargetProcess((UINT64)Buf.ObjectName, &NameBuf, sizeof(UNICODE_STRING)))
+ {
+ LogInfo("BadRead");
+ return NULL;
+ }
+
+ //
+ // The OBJECT_ATTRIBUTES structure contains a PUNICODE_STRING pointer to a guest virtual address which contains this UNICODE_STRING
+ // This in turn will contain another pointer, this time a PWCHAR, to another virtual address, which will contain the wide char string we need
+ //
+ PVOID ObjectNameBuf = PlatformMemAllocateZeroedNonPagedPool(NameBuf.Length + sizeof(WCHAR));
+
+ if (ObjectNameBuf == NULL)
+ {
+ LogInfo("Error allocating ImageName memory buffer");
+
+ return NULL;
+ }
+
+ //
+ // Read the PWCHAR string from a virtual address pointer, pointed to by OBJECT_ATTRIBUTES.ObjectName.Buffer struct entry
+ //
+ if (!g_Callbacks.MemoryMapperReadMemorySafeOnTargetProcess((UINT64)NameBuf.Buffer, ObjectNameBuf, NameBuf.Length + sizeof(WCHAR)))
+ {
+ LogInfo("BadRead");
+ PlatformMemFreePool(ObjectNameBuf);
+
+ return NULL;
+ }
+
+ //
+ // The caller is responsible for freeing the memory buffer, using PlatformMemFreePool()
+ //
+ return ObjectNameBuf;
+ }
+ return NULL;
+}
+
+/**
+ * @brief Handle The NtQueryAttributesFile system call
+ * when the Transparent mode is enabled
+ *
+ * @param Regs The virtual processor's state of registers
+ * @return VOID
+ */
+VOID
+TransparentHandleNtQueryAttributesFileSyscall(GUEST_REGS * Regs)
+{
+ SYSCALL_CALLBACK_CONTEXT_PARAMS ContextParams = {0};
+ ContextParams.OptionalParam1 = Regs->rdx;
+
+ //
+ // Check if the pointer given as the 3rd argument to the system call with type POBJECT_ATTRIBUTES is valid
+ //
+ if (g_Callbacks.CheckAccessValidityAndSafety(Regs->r10, sizeof(OBJECT_ATTRIBUTES)))
+ {
+ //
+ // From the POBJECT_ATTRIBUTES structure obtain the wide character string of the requested file path
+ //
+ PVOID PathBuf = TransparentGetObjectNameFromAttributesVirtualPointer(Regs->r10);
+ PWCH FilePath = (PWCH)PathBuf;
+
+ //
+ // If the file Attributes request is for a listed file, insert the SYSCALL trap flag and continue execution
+ //
+ for (UINT16 j = 0; j < (sizeof(HV_FILES) / sizeof(HV_FILES[0])); j++)
+ {
+ if (wcsstr(FilePath, HV_FILES[j]))
+ {
+ g_Callbacks.SyscallCallbackSetTrapFlagAfterSyscall(Regs,
+ HANDLE_TO_UINT32(PsGetCurrentProcessId()),
+ HANDLE_TO_UINT32(PsGetCurrentThreadId()),
+ Regs->rax,
+ &ContextParams);
+
+ break;
+ }
+ }
+
+ //
+ // Free the allocated copy of the directory path, obtained from TransparentGetObjectNameFromAttributesVirtualPointer()
+ //
+ PlatformMemFreePool(PathBuf);
+ }
+}
+
+/**
+ * @brief Handle The NtOpenDirectoryObject system call
+ * when the Transparent mode is enabled
+ *
+ * @param Regs The virtual processor's state of registers
+ * @return VOID
+ */
+VOID
+TransparentHandleNtOpenDirectoryObjectSyscall(GUEST_REGS * Regs)
+{
+ //
+ // Set up the context data for the callback after SYSRET
+ //
+ SYSCALL_CALLBACK_CONTEXT_PARAMS ContextParams = {0};
+ ContextParams.OptionalParam1 = Regs->r10;
+
+ //
+ // Check if the pointer given as the 3rd argument to the system call with type POBJECT_ATTRIBUTES is valid
+ //
+ if (g_Callbacks.CheckAccessValidityAndSafety(Regs->r8, sizeof(OBJECT_ATTRIBUTES)))
+ {
+ //
+ // From the POBJECT_ATTRIBUTES structure obtain the wide character string of the requested directory path
+ //
+ PVOID PathBuf = TransparentGetObjectNameFromAttributesVirtualPointer(Regs->r8);
+ PWCH DirPath = (PWCH)PathBuf;
+
+ if (DirPath == NULL)
+ {
+ return;
+ }
+
+ //
+ // If the directory object request is for a listed directory, insert the SYSCALL trap flag and continue execution
+ //
+ for (UINT16 j = 0; j < (sizeof(HV_DIRS) / sizeof(HV_DIRS[0])); j++)
+ {
+ if (wcsstr(DirPath, HV_DIRS[j]))
+ {
+ g_Callbacks.SyscallCallbackSetTrapFlagAfterSyscall(Regs,
+ HANDLE_TO_UINT32(PsGetCurrentProcessId()),
+ HANDLE_TO_UINT32(PsGetCurrentThreadId()),
+ Regs->rax,
+ &ContextParams);
+
+ break;
+ }
+ }
+
+ //
+ // Free the allocated copy of the directory path, obtained from TransparentGetObjectNameFromAttributesVirtualPointer()
+ //
+ PlatformMemFreePool(PathBuf);
+ }
+}
+
+/**
+ * @brief Handle The NtSystemDebugControl system call
+ * when the Transparent mode is enabled
+ *
+ * @param Regs The virtual processor's state of registers
+ * @return VOID
+ */
+VOID
+TransparentHandleNtSystemDebugControlSyscall(GUEST_REGS * Regs)
+{
+ //
+ // Corrupt the system call arguments, to cause the kernel to return an error
+ //
+ Regs->r9 = 0x0;
+
+ SYSCALL_CALLBACK_CONTEXT_PARAMS ContextParams = {0};
+
+ //
+ // Set the trap flag to intercept the SYSRET instruction
+ //
+ g_Callbacks.SyscallCallbackSetTrapFlagAfterSyscall(Regs,
+ HANDLE_TO_UINT32(PsGetCurrentProcessId()),
+ HANDLE_TO_UINT32(PsGetCurrentThreadId()),
+ Regs->rax,
+ &ContextParams);
+}
+
+/**
+ * @brief Handle The NtQueryInformationProcess system call
+ * when the Transparent mode is enabled
+ *
+ * @param Regs The virtual processor's state of registers
+ * @return VOID
+ */
+VOID
+TransparentHandleNtQueryInformationProcessSyscall(GUEST_REGS * Regs)
+{
+ //
+ // Set up the context parameters for the interception callback
+ //
+ SYSCALL_CALLBACK_CONTEXT_PARAMS ContextParams = {0};
+ ContextParams.OptionalParam1 = Regs->rdx; // ProcessInformationClass
+ ContextParams.OptionalParam2 = Regs->r8; // BufferPtr
+ ContextParams.OptionalParam3 = Regs->r9; // BufferSize
+
+ //
+ // Set the trap flag to intercept the SYSRET instruction
+ //
+ g_Callbacks.SyscallCallbackSetTrapFlagAfterSyscall(Regs,
+ HANDLE_TO_UINT32(PsGetCurrentProcessId()),
+ HANDLE_TO_UINT32(PsGetCurrentThreadId()),
+ Regs->rax,
+ &ContextParams);
+}
+
+/**
+ * @brief Handle The NtOpenFile system call
+ * when the Transparent mode is enabled
+ *
+ * @param Regs The virtual processor's state of registers
+ * @return VOID
+ */
+VOID
+TransparentHandleNtOpenFileSyscall(GUEST_REGS * Regs)
+{
+ //
+ // Check if the user-mode pointer in R8 to a OBJECT_ATTRIBUTES struct is valid
+ //
+ if (g_Callbacks.CheckAccessValidityAndSafety(Regs->r8, sizeof(OBJECT_ATTRIBUTES)))
+ {
+ //
+ // From the OBJECT_ATTRIBUTES struct pointer extract the file path for which this syscall is called
+ //
+ PVOID NameBuf = TransparentGetObjectNameFromAttributesVirtualPointer(Regs->r8);
+ PWCH FileName = (PWCH)NameBuf;
+ if (FileName == NULL)
+ {
+ return;
+ }
+
+ //
+ // Check if the requested file includes any hypervisor specific strings
+ // This also checks parent directory names of the requested file
+ //
+ for (UINT16 j = 0; j < (sizeof(HV_FILES) / sizeof(HV_FILES[0])); j++)
+ {
+ if (wcsstr(FileName, HV_FILES[j]))
+ {
+ LogInfo("A call to NtOpenFile systemcall for a hypervisor specific file was made");
+
+ //
+ // If a match was found, corrupt the user-mode pointers in CPU registers, so that, when the kernel-mode execution continues, it would fail.
+ //
+ Regs->r8 = 0x0;
+ Regs->r10 = 0x0;
+
+ //
+ // Set the trap flag to intercept the SYSRET instruction
+ //
+ SYSCALL_CALLBACK_CONTEXT_PARAMS ContextParams = {0};
+ g_Callbacks.SyscallCallbackSetTrapFlagAfterSyscall(Regs,
+ HANDLE_TO_UINT32(PsGetCurrentProcessId()),
+ HANDLE_TO_UINT32(PsGetCurrentThreadId()),
+ Regs->rax,
+ &ContextParams);
+
+ break;
+ }
+ }
+ //
+ // Clean up the allocated memory
+ //
+ PlatformMemFreePool(NameBuf);
+ }
+}
+
+/**
+ * @brief Handle The NtOpenKey system call
+ * when the Transparent mode is enabled
+ *
+ * @param Regs The virtual processor's state of registers
+ * @return VOID
+ */
+VOID
+TransparentHandleNtOpenKeySyscall(GUEST_REGS * Regs)
+{
+ //
+ // Check if the user-mode pointer in R8 to a OBJECT_ATTRIBUTES struct is valid
+ //
+ if (g_Callbacks.CheckAccessValidityAndSafety(Regs->r8, sizeof(OBJECT_ATTRIBUTES)))
+ {
+ //
+ // From the OBJECT_ATTRIBUTES struct pointer extract the registry key path for which this syscall is called
+ //
+ PVOID NameBuf = TransparentGetObjectNameFromAttributesVirtualPointer(Regs->r8);
+ PWCH KeyName = (PWCH)NameBuf;
+
+ if (KeyName == NULL)
+ {
+ LogInfo("BADRET");
+ return;
+ }
+
+ //
+ // Check if the requested registry entry path includes any hypervisor specific strings
+ //
+ for (UINT16 j = 0; j < (sizeof(HV_REGKEYS) / sizeof(HV_REGKEYS[0])); j++)
+ {
+ if (wcsstr(KeyName, HV_REGKEYS[j]) > 0)
+ {
+ //
+ // If a match was found, corrupt the user-mode pointer in CPU registers, so that, when the kernel-mode execution continues, it would fail.
+ //
+ Regs->r8 = 0x0;
+
+ //
+ // Set the trap flag to intercept the SYSRET instruction
+ //
+ SYSCALL_CALLBACK_CONTEXT_PARAMS ContextParams = {0};
+ g_Callbacks.SyscallCallbackSetTrapFlagAfterSyscall(Regs,
+ HANDLE_TO_UINT32(PsGetCurrentProcessId()),
+ HANDLE_TO_UINT32(PsGetCurrentThreadId()),
+ Regs->rax,
+ &ContextParams);
+
+ break;
+ }
+ }
+
+ //
+ // Clean up the allocated memory
+ //
+ PlatformMemFreePool(NameBuf);
+ }
+}
+
+/**
+ * @brief Handle The NtQueryValueKey system call
+ * when the Transparent mode is enabled
+ *
+ * @param Regs The virtual processor's state of registers
+ * @return VOID
+ */
+VOID
+TransparentHandleNtQueryValueKeySyscall(GUEST_REGS * Regs)
+{
+ //
+ // Check if the user-mode pointer in RDX to a UNICODE_STRING struct is valid
+ //
+ if (g_Callbacks.CheckAccessValidityAndSafety(Regs->rdx, sizeof(UNICODE_STRING)))
+ {
+ UNICODE_STRING NameUString = {0};
+
+ //
+ // Read the UNICODE_STRING structure from a virtual address pointer, pointed to by RDX struct entry
+ //
+ if (!g_Callbacks.MemoryMapperReadMemorySafeOnTargetProcess(Regs->rdx, &NameUString, sizeof(UNICODE_STRING)))
+ return;
+
+ //
+ // Read the PWCH wide char string from the address pointer in the UNICODE_STRING
+ //
+ PVOID NameBuf = PlatformMemAllocateZeroedNonPagedPool(NameUString.Length + sizeof(WCHAR));
+ if (NameBuf == NULL)
+ {
+ return;
+ }
+
+ if (!g_Callbacks.MemoryMapperReadMemorySafeOnTargetProcess((UINT64)NameUString.Buffer, NameBuf, NameUString.Length + sizeof(WCHAR)))
+ {
+ PlatformMemFreePool(NameBuf);
+ return;
+ }
+
+ PWCH KeyName = (PWCH)NameBuf;
+
+ //
+ // If the registry key request was for kay that could contain hypervisor specific information in its data,
+ // the return buffer(%R9) needs to be modified, but the buffer length is in the user mode stack
+ //
+ for (ULONG i = 0; i < (sizeof(TRANSPARENT_DETECTABLE_REGISTRY_KEYS) / sizeof(TRANSPARENT_DETECTABLE_REGISTRY_KEYS[0])); i++)
+ {
+ if (!wcscmp(KeyName, TRANSPARENT_DETECTABLE_REGISTRY_KEYS[i]))
+ {
+ //
+ // If a match is found, set up the context values and set the trap flag for the SYSRET callback
+ //
+
+ SYSCALL_CALLBACK_CONTEXT_PARAMS ContextParams = {0};
+
+ ContextParams.OptionalParam1 = Regs->r8;
+ ContextParams.OptionalParam2 = Regs->r9;
+
+ //
+ // Read the 5th argument of the system call from the stack at location %RSP + 0x28
+ //
+ if (g_Callbacks.CheckAccessValidityAndSafety(Regs->rsp + 0x28, sizeof(UINT64)))
+ {
+ g_Callbacks.MemoryMapperReadMemorySafeOnTargetProcess((UINT64)(Regs->rsp + 0x28), &ContextParams.OptionalParam3, sizeof(ULONG));
+ }
+ else
+ {
+ LogInfo("Process 0x%llx on thread %llx executed NtQueryValueKey systemcall but reading the provided arguments from %RSP failed", HANDLE_TO_UINT32(PsGetCurrentProcessId()), HANDLE_TO_UINT32(PsGetCurrentThreadId()));
+
+ PlatformMemFreePool(NameBuf);
+ return;
+ }
+
+ //
+ // Read the 6th argument of the system call from the stack at location %RSP + 0x30
+ //
+ if (g_Callbacks.CheckAccessValidityAndSafety(Regs->rsp + 0x30, sizeof(UINT64)))
+ {
+ g_Callbacks.MemoryMapperReadMemorySafeOnTargetProcess((UINT64)(Regs->rsp + 0x30), &ContextParams.OptionalParam4, sizeof(UINT64));
+ }
+ else
+ {
+ LogInfo("Process 0x%llx on thread %llx executed NtQueryValueKey systemcall but reading the provided arguments from %RSP failed", HANDLE_TO_UINT32(PsGetCurrentProcessId()), HANDLE_TO_UINT32(PsGetCurrentThreadId()));
+
+ PlatformMemFreePool(NameBuf);
+ return;
+ }
+
+ //
+ // Set the trap flag to intercept the SYSRET instruction
+ //
+ g_Callbacks.SyscallCallbackSetTrapFlagAfterSyscall(Regs,
+ HANDLE_TO_UINT32(PsGetCurrentProcessId()),
+ HANDLE_TO_UINT32(PsGetCurrentThreadId()),
+ Regs->rax,
+ &ContextParams);
+
+ //
+ // Clean-up and return to guest execution
+ //
+ PlatformMemFreePool(NameBuf);
+ return;
+ }
+ }
+
+ //
+ // If the call was for a registry key that contains a hypervisor specific string,
+ // The user-mode caller should just receive an error return code not a modified data buffer
+ //
+ for (UINT16 j = 1; j < (sizeof(HV_REGKEYS) / sizeof(HV_REGKEYS[0])); j++)
+ {
+ if (wcsstr(KeyName, HV_REGKEYS[j]) > 0)
+ {
+ //
+ // When the match is found, corrupt the buffer pointers in the registers
+ // and set the SYSRET callback trap flag
+ //
+ SYSCALL_CALLBACK_CONTEXT_PARAMS ContextParams = {0};
+
+ Regs->rdx = 0x0;
+ Regs->r9 = 0x0;
+
+ //
+ // Set the trap flag to intercept the SYSRET instruction
+ //
+ g_Callbacks.SyscallCallbackSetTrapFlagAfterSyscall(Regs,
+ HANDLE_TO_UINT32(PsGetCurrentProcessId()),
+ HANDLE_TO_UINT32(PsGetCurrentThreadId()),
+ Regs->rax,
+ &ContextParams);
+
+ break;
+ }
+ }
+
+ //
+ // Clean up the allocated memory
+ //
+ PlatformMemFreePool(NameBuf);
+ }
+}
+
+/**
+ * @brief Handle The NtEnumerateKey system call
+ * when the Transparent mode is enabled
+ *
+ * @param Regs The virtual processor's state of registers
+ * @return VOID
+ */
+VOID
+TransparentHandleNtEnumerateKeySyscall(GUEST_REGS * Regs)
+{
+ //
+ // Set up the context parameters for the interception callback
+ //
+ SYSCALL_CALLBACK_CONTEXT_PARAMS ContextParams = {0};
+ ContextParams.OptionalParam1 = Regs->r8;
+ ContextParams.OptionalParam2 = Regs->r9;
+
+ //
+ // Read the 5th argument of the system call from the stack at location %RSP + 0x28
+ //
+ if (g_Callbacks.CheckAccessValidityAndSafety(Regs->rsp + 0x28, sizeof(UINT64)))
+ {
+ g_Callbacks.MemoryMapperReadMemorySafeOnTargetProcess((UINT64)(Regs->rsp + 0x28), &ContextParams.OptionalParam3, sizeof(ULONG));
+ }
+ else
+ {
+ LogInfo("Process 0x%llx on thread %llx executed NtEnumerateKey systemcall but reading the provided arguments from %RSP failed", HANDLE_TO_UINT32(PsGetCurrentProcessId()), HANDLE_TO_UINT32(PsGetCurrentThreadId()));
+ return;
+ }
+
+ //
+ // Read the 6th argument of the system call from the stack at location %RSP + 0x30
+ //
+ if (g_Callbacks.CheckAccessValidityAndSafety(Regs->rsp + 0x30, sizeof(UINT64)))
+ {
+ g_Callbacks.MemoryMapperReadMemorySafeOnTargetProcess((UINT64)(Regs->rsp + 0x30), &ContextParams.OptionalParam4, sizeof(UINT64));
+ }
+ else
+ {
+ LogInfo("Process 0x%llx on thread %llx executed NtEnumerateKey systemcall but reading the provided arguments from %RSP failed", HANDLE_TO_UINT32(PsGetCurrentProcessId()), HANDLE_TO_UINT32(PsGetCurrentThreadId()));
+ return;
+ }
+
+ //
+ // If the call was made without an allocated buffer (with size 0)
+ // we have no need to intercept it
+ //
+ if (ContextParams.OptionalParam3 == 0)
+ {
+ return;
+ }
+
+ //
+ // Set the trap flag to intercept the SYSRET instruction
+ //
+ g_Callbacks.SyscallCallbackSetTrapFlagAfterSyscall(Regs,
+ HANDLE_TO_UINT32(PsGetCurrentProcessId()),
+ HANDLE_TO_UINT32(PsGetCurrentThreadId()),
+ Regs->rax,
+ &ContextParams);
+}
+
+/**
+ * @brief Handle the request for SystemModuleInformation
+ *
+ * @details This function removes entries from a list of system drivers that could reveal the presence of hypervisors
+ * This depends on an incomplete list HV_DRIVER, of known hypervisor drivers
+ * The revealing list entries are removed and overwritten, but the memory buffer is not reallocated, so
+ * 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 VirtualAddress A pointer to a user-mode virtual address
+ * @param BufferSize Size of the user-mode buffer
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+TransparentHandleModuleInformationQuery(PVOID Ptr, UINT64 VirtualAddress, UINT32 BufferSize)
+{
+ PSYSTEM_MODULE_INFORMATION StructBuf = (PSYSTEM_MODULE_INFORMATION)Ptr;
+ PSYSTEM_MODULE_ENTRY ModuleList = StructBuf->Module;
+
+ //
+ // Traverse the list of system modules and remove the system drivers
+ // matching a known list of hypervisor drivers based on their filename
+ //
+ for (UINT16 i = 0; i < StructBuf->Count; i++)
+ {
+ 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 a module file name matches, remove the entry from the list by shifting it forward by one entry
+ //
+ for (UINT16 k = i; k < StructBuf->Count - 1; k++)
+ {
+ ModuleList[k] = ModuleList[k + 1];
+ }
+
+ //
+ // Decrement the list size as one entry has been removed
+ //
+ i--;
+ StructBuf->Count--;
+
+ break;
+ }
+ }
+ }
+ if (!g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess(VirtualAddress, Ptr, BufferSize))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * @brief Handle the request for SystemProcessInformation
+ *
+ * @details This function removes entries from a list of active system processes that could reveal the presence of hypervisors
+ *
+ * @param Params Preset transparent callback params that contain:
+ in OptionalParam2 a pointer to a valid read/writable memory buffer that contains a SYSTEM_PROCESS_INFORMATION structure
+ in OptionalParam3 max size in bytes of the allocated buffer
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+TransparentHandleProcessInformationQuery(SYSCALL_CALLBACK_CONTEXT_PARAMS * Params)
+{
+ SYSTEM_PROCESS_INFORMATION PrevStructBuf = {0};
+ SYSTEM_PROCESS_INFORMATION CurStructBuf = {0};
+
+ ULONG ReadOffset, WriteOffset;
+ BOOLEAN MatchFound = FALSE;
+ ULONG PrevOffset = 0;
+
+ if (!g_Callbacks.MemoryMapperReadMemorySafeOnTargetProcess(Params->OptionalParam2, &PrevStructBuf, sizeof(SYSTEM_PROCESS_INFORMATION)))
+ {
+ return FALSE;
+ }
+
+ ReadOffset = PrevStructBuf.NextEntryOffset;
+ WriteOffset = 0;
+
+ //
+ // The first entry will always be System Idle Process, which can be skipped
+ //
+ if (PrevStructBuf.NextEntryOffset == 0 ||
+ !g_Callbacks.MemoryMapperReadMemorySafeOnTargetProcess(Params->OptionalParam2 + ReadOffset, &CurStructBuf, sizeof(SYSTEM_PROCESS_INFORMATION)))
+ {
+ return FALSE;
+ }
+
+ //
+ // Loop through all the entries and filter out the offending ones
+ //
+ do
+ {
+ MatchFound = FALSE;
+
+ if (CurStructBuf.ImageName.Length != 0)
+ {
+ //
+ // We need to search for the Image name of the process which requires extra allocation
+ //
+ PVOID StringBuf = PlatformMemAllocateZeroedNonPagedPool(CurStructBuf.ImageName.Length + sizeof(WCHAR));
+
+ if (StringBuf == NULL)
+ {
+ LogInfo("Error allocating ImageName memory buffer");
+
+ return FALSE;
+ }
+
+ //
+ // Read the WCHAR process image name from the user-mode pointer
+ //
+ if (!g_Callbacks.MemoryMapperReadMemorySafeOnTargetProcess((UINT64)CurStructBuf.ImageName.Buffer, StringBuf, CurStructBuf.ImageName.Length + sizeof(WCHAR)))
+ {
+ PlatformMemFreePool(StringBuf);
+
+ return FALSE;
+ }
+
+ PWCH ImageName = (PWCH)StringBuf;
+
+ if (ImageName == NULL)
+ {
+ PlatformMemFreePool(StringBuf);
+
+ return FALSE;
+ }
+
+ //
+ // Loop through the known list of identifiable hypervisor related processes
+ //
+ 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 the name matches, bypass it by increasing the previous entries .nextEntryOffset value
+ //
+
+ //
+ // The offset to this matching entry need to preserved for zeroing later
+ //
+ PrevOffset = PrevStructBuf.NextEntryOffset;
+
+ PrevStructBuf.NextEntryOffset = PrevStructBuf.NextEntryOffset + CurStructBuf.NextEntryOffset;
+
+ MatchFound = TRUE;
+
+ //
+ // Write the modified offset back to the usermode buffer
+ //
+ if (!g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess((UINT64)(Params->OptionalParam2 + WriteOffset), &PrevStructBuf, sizeof(SYSTEM_PROCESS_INFORMATION)))
+ {
+ LogError("Failed to modify memory buffer for the SystemProcessInformation query system call");
+ }
+
+ //
+ // The entry gets bypassed, but since the Image name is a pointer in the struct, to completely clear any presence of these processes
+ // zero out the name buffer as well
+ //
+ memset(StringBuf, 0x0, CurStructBuf.ImageName.Length);
+ ULONG BufOffset = (ULONG)((PBYTE)&CurStructBuf.ImageName.Length - (PBYTE)&CurStructBuf) + sizeof(USHORT);
+
+ if (!g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess((UINT64)(Params->OptionalParam2 + WriteOffset + PrevOffset + BufOffset), StringBuf, CurStructBuf.ImageName.Length))
+ {
+ LogError("Failed to modify memory buffer for the SystemProcessInformation query system call");
+ }
+
+ break;
+ }
+ }
+
+ PlatformMemFreePool(StringBuf);
+ }
+
+ //
+ // If the last entry been reached, exit
+ //
+ if (CurStructBuf.NextEntryOffset == 0)
+ {
+ return TRUE;
+ }
+
+ //
+ // If the current entry did not match any process names, move forward
+ //
+ if (!MatchFound)
+ {
+ WriteOffset += PrevStructBuf.NextEntryOffset;
+
+ PrevStructBuf = CurStructBuf;
+ }
+
+ //
+ // Move over to the next entry
+ //
+ ReadOffset += CurStructBuf.NextEntryOffset;
+
+ //
+ // Some internal Windows calls to this system call use different offsetting/entry structure layout and causes errors
+ //
+ if (!g_Callbacks.CheckAccessValidityAndSafety((UINT64)(Params->OptionalParam2 + ReadOffset), sizeof(SYSTEM_PROCESS_INFORMATION)))
+ {
+ return FALSE;
+ }
+
+ //
+ // Zero out the matching entry, so that its data doesn't remain in memory
+ //
+ if (MatchFound)
+ {
+ CurStructBuf = (SYSTEM_PROCESS_INFORMATION) {0};
+ if (!g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess((UINT64)(Params->OptionalParam2 + WriteOffset + PrevOffset), &CurStructBuf, sizeof(SYSTEM_PROCESS_INFORMATION)))
+ {
+ return FALSE;
+ }
+ }
+
+ //
+ // Read from the user buffer the next process entry
+ //
+ if (!g_Callbacks.MemoryMapperReadMemorySafeOnTargetProcess(Params->OptionalParam2 + ReadOffset, &CurStructBuf, sizeof(SYSTEM_PROCESS_INFORMATION)))
+ {
+ return FALSE;
+ }
+
+ } while (TRUE);
+
+ return TRUE;
+}
+
+/**
+ * @brief Handle the request for SystemFirmwareTableInformation
+ *
+ * @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
+ *
+ * @return BOOLEAN
+ */
+UINT64
+TransparentHandleFirmwareInformationQuery(UINT64 Ptr, UINT32 BufMaxSize, UINT64 BufSizePtr)
+{
+ ULONG BufSize = 0;
+
+ //
+ // Read the size of the data the kernel wrote in the buffer
+ //
+ if (!g_Callbacks.CheckAccessValidityAndSafety(BufSizePtr, sizeof(ULONG)) ||
+ !g_Callbacks.MemoryMapperReadMemorySafeOnTargetProcess(BufSizePtr, &BufSize, sizeof(ULONG)))
+ {
+ return 0;
+ }
+
+ //
+ // If the memory buffer was too small for the kernel to write the needed information, bypass the mitigations
+ //
+ if (BufSize > BufMaxSize)
+ {
+ //
+ // 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 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)
+ {
+ LogInfo("The intercepted data buffer was too large for modification, in total 0x%x bytes", BufMaxSize);
+ LogInfo("The system call return value was set to STATUS_INVALID_INFO_CLASS, but this could be detected as hypervisor intervention");
+
+ return (UINT64)(UINT32)STATUS_INVALID_INFO_CLASS;
+ }
+
+ if (BufSize == 0)
+ {
+ BufSize = BufMaxSize;
+ }
+ //
+ // From the user-mode pointer, read the SYSTEM_FIRMWARE_TABLE_INFORMATION struct
+ //
+ PVOID Buf = PlatformMemAllocateZeroedNonPagedPool(BufMaxSize + 1);
+ if (Buf == NULL)
+ {
+ return 0;
+ }
+
+ if (!g_Callbacks.MemoryMapperReadMemorySafeOnTargetProcess(Ptr, Buf, BufSize))
+ {
+ PlatformMemFreePool(Buf);
+ return 0;
+ }
+
+ PSYSTEM_FIRMWARE_TABLE_INFORMATION StructBuf = (PSYSTEM_FIRMWARE_TABLE_INFORMATION)Buf;
+
+ //
+ // The request needs to be a "get" request for an existing table
+ // with 'RSMB', 'ACPI' or 'FIRM' table providers
+ //
+ if (StructBuf->Action == SystemFirmwareTable_Get &&
+ StructBuf->TableID != 0 &&
+ (StructBuf->ProviderSignature == 0x52534D42 ||
+ StructBuf->ProviderSignature == 0x41435049 ||
+ StructBuf->ProviderSignature == 0x4649524D))
+ {
+ PCHAR StringBuf = (PCHAR)StructBuf->TableBuffer;
+
+ for (ULONG i = 0; i < (sizeof(HV_FIRM_NAMES) / sizeof(HV_FIRM_NAMES[0])); i++)
+ {
+ for (ULONG j = 0; j < StructBuf->TableBufferLength; j++)
+ {
+ WORD Count = 0;
+ PCHAR MatchStart = strstr(StringBuf + j, HV_FIRM_NAMES[i]);
+ if (MatchStart != 0)
+ {
+ LogInfo("Found Match for %s", HV_FIRM_NAMES[i]);
+
+ PCHAR NewVendorString = NULL;
+ ULONG NewSubstringSize = 0;
+
+ //
+ // Replace the first occurace of the vendor string with AMERICAN MEGATRENDS INC.
+ // The rest with To Be Filled By O.E.M.
+ //
+ if (Count == 0)
+ {
+ NewVendorString = "AMERICAN MEGATRENDS INC.";
+ NewSubstringSize = 24 * sizeof(CHAR);
+ }
+ else
+ {
+ NewVendorString = "To Be Filled By O.E.M.";
+ NewSubstringSize = 22 * sizeof(CHAR);
+ }
+
+ //
+ // Obtain the lengths of all the strings and substring
+ //
+
+ ULONG MatchedStringLen = (ULONG)strlen(HV_FIRM_NAMES[i]);
+ ULONG OldLength = StructBuf->TableBufferLength;
+
+ ULONG NewStringSize = OldLength - MatchedStringLen + NewSubstringSize;
+
+ //
+ // Check if the buffer size allows the modification, in case of expansion
+ //
+ if (BufSize - MatchedStringLen + NewSubstringSize > BufMaxSize)
+ {
+ //
+ // If adding the new string exceeds the user allocated size,
+ // zero out the buffer
+ //
+ memset(Buf, 0x0, BufMaxSize);
+ g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess(Ptr, Buf, BufMaxSize);
+
+ //
+ // Update the required buffer size for the next call
+ //
+ BufSize = (BufSize - OldLength) + NewStringSize;
+ g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess(BufSizePtr, &BufSize, sizeof(ULONG));
+
+ //
+ // And return STATUS_BUFFER_TOO_SMALL error
+ //
+
+ PlatformMemFreePool(Buf);
+ return (UINT64)(UINT32)STATUS_BUFFER_TOO_SMALL;
+ }
+
+ //
+ // Calculate the positions of the replacement
+ //
+ ULONG MatchOffset = (ULONG)((MatchStart - StringBuf));
+ PCHAR MatchEnd = StringBuf + MatchOffset + MatchedStringLen;
+
+ //
+ // 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);
+ memcpy((PVOID)MatchStart, (PVOID)NewVendorString, NewSubstringSize);
+
+ StructBuf->TableBufferLength = NewStringSize;
+ BufSize = BufSize - MatchedStringLen + NewSubstringSize;
+
+ //
+ // Write the changes back to the user buffers
+ //
+ if (!g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess(Ptr, Buf, BufSize))
+ {
+ LogInfo("Error writing to user-mode buffer: %llx", Ptr);
+ }
+
+ if (!g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess(BufSizePtr, &BufSize, sizeof(ULONG)))
+ {
+ LogInfo("Error writing to user-mode buffer: %llx", BufSizePtr);
+ }
+ }
+ }
+ }
+ }
+
+ PlatformMemFreePool(Buf);
+ return 1;
+}
+
+/**
+ * @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 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
+ *
+ * @param DataLenOffset Offset in bytes from OptionalParam2 to a ULONG containing the string length(in bytes)
+ *
+ * @return UINT64
+ */
+UINT64
+TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS * Params, ULONG DataOffset, ULONG DataLenOffset)
+{
+ PVOID Buf = NULL;
+ BOOLEAN PoolAlloc = FALSE;
+
+ //
+ // Check that the user provided pointers are safe to read from
+ //
+ if (g_Callbacks.CheckAccessValidityAndSafety(Params->OptionalParam4, sizeof(ULONG)))
+ {
+ //
+ // Read the size of the data that the kernel wrote to the buffer
+ //
+ ULONG BufSize = 0;
+ if (!g_Callbacks.MemoryMapperReadMemorySafeOnTargetProcess(Params->OptionalParam4, &BufSize, sizeof(ULONG)))
+ {
+ goto ReturnWithError;
+ }
+
+ //
+ // If the data the kernel wanted to write is bigger than what was allocated by the user
+ //
+ if (BufSize > Params->OptionalParam3 || BufSize == 0)
+ {
+ //
+ // NOTE: might need zeroing the memory if the kernel did in fact write to the pointer
+ //
+
+ return 0;
+ }
+
+ //
+ // Check that the user provided pointers are safe to read from and the buffer is not too large
+ //
+ if (Params->OptionalParam3 >= 0xC00 || !g_Callbacks.CheckAccessValidityAndSafety(Params->OptionalParam2, (UINT32)Params->OptionalParam3))
+ {
+ goto ReturnWithError;
+ }
+
+ //
+ // If the buffer is small, e.g. for just a single word, store it on the stack
+ // else, allocate a nonpaged memory buffer
+ //
+ CHAR StackBuf[MAX_PATH] = {0};
+
+ if (Params->OptionalParam3 + sizeof(WCHAR) > MAX_PATH)
+ {
+ Buf = PlatformMemAllocateZeroedNonPagedPool(Params->OptionalParam3 + sizeof(WCHAR));
+ PoolAlloc = TRUE;
+ }
+ else
+ {
+ Buf = &StackBuf;
+ }
+
+ if (!Buf || !g_Callbacks.MemoryMapperReadMemorySafeOnTargetProcess(Params->OptionalParam2, Buf, Params->OptionalParam3))
+ {
+ goto ReturnWithError;
+ }
+
+ //
+ // Get the actual data we are trying to modify(in wide char form)
+ //
+ PWCH StringBuf = (PWCH)((PBYTE)Buf + DataOffset);
+
+ //
+ // Traverse the list of registry key names and vendor strings that are specific to common hypervisors
+ // if a match is found perform the modification
+ //
+ for (UINT16 i = 0; i < (sizeof(HV_REGKEYS) / sizeof(HV_REGKEYS[0])); i++)
+ {
+ PWCH MatchStart = wcsstr(StringBuf, HV_REGKEYS[i]);
+
+ while (MatchStart != 0)
+ {
+ PWCH NewVendorString = NULL;
+
+ //
+ // If the match was for a device id, the replacement should be with a different ID string not vendor name
+ //
+ if (i < 3)
+ {
+ //
+ // SPOOFS PCI device ID's(in the registry), This might be implemented in other ways that are not part of this implementation
+ //
+ 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];
+ }
+
+ //
+ // Remove common VM strings from the data
+ //
+ else if (i < 9)
+ {
+ NewVendorString = L" ";
+ }
+ else
+ {
+ //
+ // Obtain the replacement vendor name string, randomized when the transparency mode was enabled
+ //
+ 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 MatchedStringLen = (ULONG)wcslen(HV_REGKEYS[i]) * sizeof(WCHAR);
+ ULONG OldLength = *((PBYTE)Buf + DataLenOffset);
+
+ ULONG NewStringSize = OldLength - MatchedStringLen + TempSize;
+
+ //
+ // Check if the buffer size allows the modification, in case of expansion
+ //
+ if (BufSize - MatchedStringLen + TempSize > Params->OptionalParam3)
+ {
+ //
+ // If adding the new string exceeds the user allocated size,
+ // zero out the buffer
+ //
+ memset(Buf, 0x0, Params->OptionalParam3);
+ g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess(Params->OptionalParam2, Buf, Params->OptionalParam3);
+
+ //
+ // Update the required buffer size for the next call
+ //
+ BufSize = (TempSize - MatchedStringLen) + OldLength;
+ g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess(Params->OptionalParam4, &BufSize, sizeof(ULONG));
+
+ //
+ // And return STATUS_BUFFER_OVERFLOW error
+ //
+
+ if (PoolAlloc)
+ PlatformMemFreePool(Buf);
+ return (UINT64)(UINT32)STATUS_BUFFER_OVERFLOW;
+ }
+
+ //
+ // Calculate the positions of the replacement
+ //
+ ULONG MatchOffset = (ULONG)((MatchStart - StringBuf));
+ PWCH MatchEnd = StringBuf + MatchOffset + (MatchedStringLen / sizeof(WCHAR));
+
+ //
+ // Move the data after the matched string forward
+ //
+ 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);
+
+ *(PULONG)((PBYTE)Buf + DataLenOffset) = NewStringSize;
+ BufSize = BufSize - MatchedStringLen + TempSize;
+
+ //
+ // Write the changes back to the user buffers
+ //
+ if (!g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess(Params->OptionalParam2, Buf, BufSize))
+ {
+ goto ReturnWithError;
+ }
+
+ if (!g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess(Params->OptionalParam4, &BufSize, sizeof(ULONG)))
+ {
+ goto ReturnWithError;
+ }
+
+ //
+ // Cleanup
+ //
+
+ MatchStart = wcsstr(StringBuf, HV_REGKEYS[i]);
+
+ if (!MatchStart)
+ i = 0;
+ }
+ }
+
+ //
+ // The data buffer contained no detectable strings
+ //
+ if (PoolAlloc)
+ PlatformMemFreePool(Buf);
+ return 0;
+ }
+
+ //
+ // 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 received the results in this virtual address: %llx", Params->OptionalParam2);
+
+ if (Buf != NULL)
+ {
+ if (PoolAlloc)
+ PlatformMemFreePool(Buf);
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Callback function to handle the returns from the NtQueryValueKey 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 allocated buffer
+ in OptionalParam4 a pointer to a ULONG containing current size of the buffer
+ *
+ * @return UINT64
+ */
+UINT64
+TransparentCallbackHandleAfterNtQueryValueKeySyscall(SYSCALL_CALLBACK_CONTEXT_PARAMS * Params)
+{
+ ULONG LenOffset = 0;
+ ULONG BufOffset = 0;
+
+ //
+ // Based on the KEY_VALUE_INFORMATION_CLASS given, set the struct offsets for the data buffer and its length fields
+ //
+ switch (Params->OptionalParam1)
+ {
+ //
+ // KeyValueBasicInformation and queries for a key that has a hypervisor specific name
+ //
+ case 0x0:
+ {
+ if (Params->OptionalParam2 != 0)
+ return 0;
+
+ //
+ // If the key query was for a registry key that has a hypervisor specific name, return an error code
+ //
+ return (UINT64)(UINT32)STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ //
+ // KeyValuePartialInformation
+ //
+ case 0x2:
+ {
+ LenOffset = sizeof(ULONG) * 2;
+ BufOffset = sizeof(ULONG) * 3;
+
+ break;
+ }
+
+ //
+ // KeyValueFullInformation
+ //
+ case 0x3:
+ case 0x1:
+ {
+ LenOffset = sizeof(ULONG) * 3;
+ BufOffset = sizeof(ULONG) * 4; // Name offset, Data is after it
+
+ break;
+ }
+
+ //
+ // KeyValuePartialInformationAlign64
+ //
+ case 0x4:
+ {
+ LenOffset = sizeof(ULONG) * 1;
+ BufOffset = sizeof(ULONG) * 2;
+
+ break;
+ }
+ default:
+ {
+ LogInfo("NtQueryValueKey was called with KeyValueInformationClass 0x%x, a handler for which has not been implemented", Params->OptionalParam1);
+ return 0;
+ }
+ }
+
+ //
+ // Given the user buffer, read and exchange any Hypervisor vendor strings in the registry key data
+ //
+ return TransparentReplaceVendorStringFromBufferWChar(Params, BufOffset, LenOffset);
+}
+
+/**
+ * @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 allocated buffer
+ in OptionalParam4 a pointer to a ULONG containing current size of the buffer
+ *
+ * @return UINT64
+ */
+UINT64
+TransparentCallbackHandleAfterNtEnumerateKeySyscall(SYSCALL_CALLBACK_CONTEXT_PARAMS * Params)
+{
+ ULONG LenOffset = 0;
+ ULONG BufOffset = 0;
+
+ //
+ // Based on the KEY_INFORMATION_CLASS given, set the struct offsets for the data buffer and its length fields
+ //
+ switch (Params->OptionalParam1)
+ {
+ //
+ // KeyBasicInformation
+ //
+ case 0x0:
+ {
+ LenOffset = sizeof(LARGE_INTEGER) + sizeof(ULONG);
+ BufOffset = sizeof(LARGE_INTEGER) + (sizeof(ULONG) * 2);
+
+ break;
+ }
+
+ //
+ // KeyNodeInformation
+ //
+ case 0x1:
+ {
+ return 0;
+ }
+
+ //
+ // KeyNameInformation
+ //
+ case 0x3:
+ {
+ LenOffset = 0;
+ BufOffset = sizeof(ULONG);
+
+ break;
+ }
+ default:
+ {
+ LogInfo("NtEnumerateKey was called with KeyInformationClass 0x%x, a handler for which has not been implemented", Params->OptionalParam1);
+ return 0;
+ }
+ }
+
+ //
+ // Given the user buffer, read and exchange any Hypervisor vendor strings in the registry key names
+ //
+ return TransparentReplaceVendorStringFromBufferWChar(Params, BufOffset, LenOffset);
+}
+
+/**
+ * @brief Callback function to handle the returns from the NtQuerySystemInformation syscall
+ *
+ * @param Regs The virtual processor's state of registers
+ * @param Params The (optional) parameters of the caller
+ *
+ * @return VOID
+ */
+VOID
+TransparentCallbackHandleAfterNtQuerySystemInformationSyscall(GUEST_REGS * Regs, SYSCALL_CALLBACK_CONTEXT_PARAMS * Params)
+{
+ //
+ // Handle each defined SYSTEM_INFORMATION_CLASS
+ //
+ switch (Params->OptionalParam1)
+ {
+ case SystemCodeIntegrityInformation:
+ {
+ //
+ // Check if the obtained buffer pointer is valid
+ //
+ if (g_Callbacks.CheckAccessValidityAndSafety(Params->OptionalParam2, (UINT32)Params->OptionalParam3))
+ {
+ SYSTEM_CODEINTEGRITY_INFORMATION Temp = {0};
+
+ //
+ // Read data from the saved pointer of the now filled information buffer
+ //
+ g_Callbacks.MemoryMapperReadMemorySafeOnTargetProcess(Params->OptionalParam2, &Temp, Params->OptionalParam3);
+
+ //
+ // Modify the data and write it back to the information buffer to be passed to user mode
+ //
+ Temp.CodeIntegrityOptions = 0x01;
+ g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess(Params->OptionalParam2, &Temp, Params->OptionalParam3);
+ }
+ else
+ {
+ LogInfo("A call for the NtQuerySystemInformation system call requesting SystemCodeIntegrityInformation structure was made, but the usermode buffer was not captured");
+ }
+
+ break;
+ }
+ case SystemProcessInformation:
+ case SystemExtendedProcessInformation:
+ {
+ //
+ // Check if the obtained buffer pointer is valid
+ //
+ if (Params->OptionalParam2 != 0x0 &&
+ Params->OptionalParam3 != 0x0 &&
+ g_Callbacks.CheckAccessValidityAndSafety(Params->OptionalParam2, (UINT32)Params->OptionalParam3))
+ {
+ if (!TransparentHandleProcessInformationQuery(Params))
+ {
+ //
+ // Some internal Windows calls to these system calls use different offsetting/entry structure layout and causes errors
+ //
+
+ // LogInfo("Error while modifying the buffer for data query 0x02x", Params->OptionalParam1);
+ }
+ }
+ break;
+ }
+
+ case SystemModuleInformation:
+ {
+ //
+ // Check if the obtained buffer pointer is valid
+ //
+ if (Params->OptionalParam2 != 0x0 &&
+ Params->OptionalParam3 != 0x0 &&
+ g_Callbacks.CheckAccessValidityAndSafety(Params->OptionalParam2, (UINT32)Params->OptionalParam3))
+ {
+ //
+ // Allocate a buffer to copy user buffer data to for modification
+ //
+ PVOID Buf = PlatformMemAllocateZeroedNonPagedPool(Params->OptionalParam3);
+ if (Buf == NULL)
+ {
+ LogError("Err, insufficient memory");
+ break;
+ }
+
+ //
+ // Copy over the data and perform the modifications
+ //
+ if (!g_Callbacks.MemoryMapperReadMemorySafeOnTargetProcess(Params->OptionalParam2, Buf, Params->OptionalParam3))
+ {
+ LogInfo("Error reading memory buffer given by the usermode call");
+ }
+ else
+ {
+ if (!TransparentHandleModuleInformationQuery(Buf, Params->OptionalParam2, (UINT32)Params->OptionalParam3))
+ {
+ //
+ // Some internal Windows calls to these system calls use different offsetting/entry structure layout and causes errors
+ //
+
+ // LogInfo("Error while modifying the buffer for data query 0x02x", Params->OptionalParam1);
+ }
+ }
+
+ PlatformMemFreePool(Buf);
+ }
+ break;
+ }
+ case SystemKernelDebuggerInformation:
+ {
+ //
+ // Check if the obtained buffer pointer is valid
+ //
+ if (g_Callbacks.CheckAccessValidityAndSafety(Params->OptionalParam2, (UINT32)Params->OptionalParam3))
+ {
+ //
+ // Write to the output buffer 0x0001 for "Debugger not present"
+ //
+ WORD Temp = 0x0100;
+ g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess(Params->OptionalParam2, &Temp, 2);
+ }
+ }
+ case SystemFirmwareTableInformation:
+ {
+ if (g_Callbacks.CheckAccessValidityAndSafety(Params->OptionalParam2, (UINT32)Params->OptionalParam3))
+ {
+ UINT64 RetVal = TransparentHandleFirmwareInformationQuery(Params->OptionalParam2, (UINT32)Params->OptionalParam3, Params->OptionalParam4);
+ if (RetVal == 0x0)
+ {
+ LogInfo("A query for SystemFirmwareTableInformation was made, but the transparent mitigation failed");
+ }
+ else if (RetVal != 0x1)
+ {
+ LogInfo("Changing to %llx", RetVal);
+ Regs->rax = RetVal;
+ }
+ }
+ else
+ {
+ LogInfo("A query for SystemFirmwareTableInformation was made, but the user-mode buffer was not captured");
+ }
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+}
+
+/**
+ * @brief Callback function to handle returns from the syscall
+ *
+ * @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)
+{
+ //
+ // Handle each defined system call separately, after the kernel execution has finished(at the SYSRET instruction)
+ //
+
+ //
+ // Handle the memory buffer and return code modification after NtQuerySystemInformation system call
+ //
+ if (Context == g_SystemCallNumbersInformation.SysNtQuerySystemInformation)
+ {
+ TransparentCallbackHandleAfterNtQuerySystemInformationSyscall(Regs, Params);
+ }
+ //
+ // Handle the memory buffer and return code modification after NtQueryAttributesFile system call
+ //
+ else if (Context == g_SystemCallNumbersInformation.SysNtQueryAttributesFile)
+ {
+ //
+ // Check if the obtained buffer pointer is valid
+ //
+ if (g_Callbacks.CheckAccessValidityAndSafety(Params->OptionalParam1, sizeof(FILE_BASIC_INFORMATION)))
+ {
+ FILE_BASIC_INFORMATION Buf = {0};
+ //
+ // Copy over the data from the output buffer pointer
+ //
+ if (!g_Callbacks.MemoryMapperReadMemorySafeOnTargetProcess(Params->OptionalParam1, &Buf, sizeof(FILE_BASIC_INFORMATION)))
+ {
+ LogError("Err, Virtual memory read failed");
+ }
+ else
+ {
+ //
+ // Modify the file attribute to INVALID_FILE_ATTRIBUTES and write it back to the pointer
+ //
+ Buf.FileAttributes = ((DWORD)-1);
+
+ if (!g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess(Params->OptionalParam1, &Buf, sizeof(FILE_BASIC_INFORMATION)))
+ {
+ LogError("Err, Virtual memory write failed");
+ }
+ }
+ }
+ else
+ {
+ LogInfo("A call for the NtQueryAttributeFile system call for a marked file was made, but the output buffer was not captured");
+ }
+ }
+
+ //
+ // Handle the memory buffer and return code modification after NtOpenDirectoryObject system call.
+ //
+ // NOTE: No transparent mitigations of this call have been implemented
+ //
+ else if (Context == g_SystemCallNumbersInformation.SysNtOpenDirectoryObject)
+ {
+ LogInfo("A NtOpenDirectoryObject system call was made for a known directory that reveals hypervisor presence. process: %x, thread: %x\n",
+ ProcessId,
+ ThreadId);
+ LogInfo("No action to mitigate this was made as a handler for NtOpenDirectoryObject has not been implemented");
+ }
+ //
+ // Handle the memory buffer modification after NtQueryInformationProcess system call
+ //
+ else if (Context == g_SystemCallNumbersInformation.SysNtQueryInformationProcess)
+ {
+ switch (Params->OptionalParam1)
+ {
+ case 0x07:
+ {
+ if (g_Callbacks.CheckAccessValidityAndSafety(Params->OptionalParam2, sizeof(DWORD_PTR)))
+ {
+ //
+ // Zero out the return buffer to user-mode
+ //
+ DWORD_PTR NoDebugPort = 0x0;
+
+ g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess(Params->OptionalParam2, &NoDebugPort, sizeof(DWORD_PTR));
+ }
+ break;
+ }
+ case 0x1f:
+ {
+ //
+ // Zero out the return buffer to user-mode
+ //
+ ULONG notDebugged = 0x0;
+ g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess(Params->OptionalParam2, ¬Debugged, sizeof(ULONG));
+ break;
+ }
+ case 0x1e:
+ {
+ if (g_Callbacks.CheckAccessValidityAndSafety(Params->OptionalParam2, (UINT32)Params->OptionalParam3))
+ {
+ LogInfo("Process %llx called the NtQueryInformationProcess system call with the ProcessDebugObject class, no transparent mitigations were performed", ProcessId);
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ //
+ // Handle the return code modification after NtSystemDebugControl system call
+ //
+ else if (Context == g_SystemCallNumbersInformation.SysNtSystemDebugControl)
+ {
+ //
+ // In the entry handler, the Syscall number was changed to corrupt this call, after the SYSRET, change the return code to STATUS_DEBUGGER_INACTIVE
+ //
+ Regs->rax = (UINT64)(UINT32)STATUS_DEBUGGER_INACTIVE;
+ }
+
+ //
+ // Handle the return code modification after SysNtOpenFile system call
+ //
+ else if (Context == g_SystemCallNumbersInformation.SysNtOpenFile)
+ {
+ //
+ // In the entry handler, the Syscall number was changed to corrupt this call if the request was for a known hypervisor file
+ // after the SYSRET, change the return code to STATUS_OBJECT_NAME_NOT_FOUND
+ //
+ Regs->rax = (UINT64)(UINT32)STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ //
+ // Handle the return code modification after NtNtQueryValueKey system call
+ //
+ // 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 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)
+ {
+ UINT64 RetVal;
+
+ //
+ // Call the handler of NtQueryValueKey syscall callback
+ //
+ RetVal = TransparentCallbackHandleAfterNtQueryValueKeySyscall(Params);
+
+ //
+ // If a custom(Specific to transparency) error code should be returned,
+ // set it to %RAX
+ // Else leave it to what the kernel already set it to
+ //
+ if (RetVal != 0)
+ {
+ Regs->rax = RetVal;
+ }
+ }
+ //
+ // Handle the memory buffer modification after NtOpenKey system call and its derivatives
+ //
+ else if (Context == g_SystemCallNumbersInformation.SysNtOpenKey || Context == g_SystemCallNumbersInformation.SysNtOpenKeyEx)
+ {
+ //
+ // In the entry handler, the Syscall number was changed to corrupt this call if the request was for a known hypervisor registry key
+ // after the SYSRET, change the return code to STATUS_OBJECT_NAME_NOT_FOUND
+ //
+ Regs->rax = (UINT64)(UINT32)STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+ else if (Context == g_SystemCallNumbersInformation.SysNtEnumerateKey)
+ {
+ UINT64 RetVal;
+
+ //
+ // Call the handler of NtEnumerateKey syscall callback
+ //
+ RetVal = TransparentCallbackHandleAfterNtEnumerateKeySyscall(Params);
+
+ //
+ // If a custom(Specific to transparency) error code should be returned,
+ // set it to %RAX
+ // Else leave it to what the kernel already set it to
+ //
+ if (RetVal != 0)
+ {
+ Regs->rax = RetVal;
+ }
+ }
+ else
+ {
+ //
+ // A SYSRET trap flag was inserted for a System call that does not have a transparency handler implemented
+ //
+ LogInfo("Transparent callback for an unimplemented system call handle with the trap flag for process: %x, thread: %x, context: %llx RAX: %llx (p1: %llx, p2: %llx, p3: %llx, p4: %llx) \n",
+ ProcessId,
+ ThreadId,
+ Context,
+ Regs->rax,
+ Params->OptionalParam1,
+ Params->OptionalParam2,
+ Params->OptionalParam3,
+ Params->OptionalParam4);
+ }
+}
+#endif // ActivateHyperEvadeProject != TRUE
diff --git a/hyperdbg/hyperevade/code/Transparency.c b/hyperdbg/hyperevade/code/Transparency.c
new file mode 100644
index 00000000..611c085f
--- /dev/null
+++ b/hyperdbg/hyperevade/code/Transparency.c
@@ -0,0 +1,771 @@
+/**
+ * @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
+ * @date 2020-07-07
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief Hide debugger on transparent-mode (activate transparent-mode)
+ *
+ * @param HyperevadeCallbacks Pointer to the HyperEvade callbacks structure
+ * @param TransparentModeRequest Pointer to the transparent debugger mode request
+ *
+ * @return BOOLEAN
+ */
+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
+ //
+ for (UINT32 i = 0; i < sizeof(HYPEREVADE_CALLBACKS) / sizeof(UINT64); i++)
+ {
+ if (((PVOID *)HyperevadeCallbacks)[i] == NULL)
+ {
+ //
+ // The callback has null entry, so we cannot proceed
+ //
+ TransparentModeRequest->KernelStatus = DEBUGGER_ERROR_UNABLE_TO_HIDE_OR_UNHIDE_DEBUGGER;
+ return FALSE;
+ }
+ }
+
+ //
+ // Save the callbacks
+ //
+ RtlCopyMemory(&g_Callbacks, HyperevadeCallbacks, sizeof(HYPEREVADE_CALLBACKS));
+
+ //
+ // Check whether the transparent-mode was already initialized or not
+ //
+ if (!g_TransparentMode)
+ {
+ //
+ // Store the system-call numbers information
+ //
+ RtlCopyBytes(&g_SystemCallNumbersInformation,
+ &TransparentModeRequest->SystemCallNumbersInformation,
+ sizeof(SYSTEM_CALL_NUMBERS_INFORMATION));
+#if ActivateHyperEvadeProject == TRUE
+ //
+ // Choose a random genuine vendor string to replace hypervisor vendor data
+ //
+ 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;
+
+ //
+ // Successfully enabled the transparent-mode
+ //
+ return TRUE;
+ }
+ else
+ {
+ TransparentModeRequest->KernelStatus = DEBUGGER_ERROR_DEBUGGER_ALREADY_HIDE;
+ return FALSE;
+ }
+}
+
+/**
+ * @brief Deactivate transparent-mode
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+TransparentUnhideDebugger()
+{
+ if (g_TransparentMode)
+ {
+ //
+ // Disable the transparent-mode
+ //
+ g_TransparentMode = FALSE;
+ g_TransparentEvadeMask = 0;
+
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+/**
+ * @brief Generate a random number by utilizing RDTSC instruction.
+ *
+ * Masking 16 LSB of the measured clock time.
+ * @return UINT32
+ */
+UINT32
+TransparentGetRand()
+{
+ UINT64 Tsc;
+ UINT32 Rand;
+
+ Tsc = CpuReadTsc();
+ Rand = Tsc & 0xffff;
+
+ return Rand;
+}
+
+/**
+ * @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 Pointer to the debugger hide and transparent mode request structure
+ * @return BOOLEAN
+ */
+BOOLEAN
+TransparentAddNameOrProcessIdToTheList(PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE Measurements)
+{
+ SIZE_T SizeOfBuffer;
+ PTRANSPARENCY_PROCESS PidAndNameBuffer;
+
+ //
+ // Check whether it's a process id or it's a process name
+ //
+ if (Measurements->TrueIfProcessIdAndFalseIfProcessName)
+ {
+ //
+ // It's a process Id
+ //
+ SizeOfBuffer = sizeof(TRANSPARENCY_PROCESS);
+ }
+ else
+ {
+ //
+ // It's a process name
+ //
+ SizeOfBuffer = sizeof(TRANSPARENCY_PROCESS) + Measurements->LengthOfProcessName;
+ }
+
+ //
+ // Allocate the Buffer
+ //
+ PidAndNameBuffer = PlatformMemAllocateZeroedNonPagedPool(SizeOfBuffer);
+
+ if (PidAndNameBuffer == NULL)
+ {
+ return FALSE;
+ }
+
+ //
+ // Save the address of the buffer for future de-allocation
+ //
+ PidAndNameBuffer->BufferAddress = PidAndNameBuffer;
+
+ //
+ // Check again whether it's a process id or it's a process name
+ // then fill the structure
+ //
+ if (Measurements->TrueIfProcessIdAndFalseIfProcessName)
+ {
+ //
+ // It's a process Id
+ //
+ PidAndNameBuffer->ProcessId = Measurements->ProcId;
+ PidAndNameBuffer->TrueIfProcessIdAndFalseIfProcessName = TRUE;
+ }
+ else
+ {
+ //
+ // It's a process name
+ //
+ PidAndNameBuffer->TrueIfProcessIdAndFalseIfProcessName = FALSE;
+
+ //
+ // 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)),
+ Measurements->LengthOfProcessName);
+
+ //
+ // Set the process name location
+ //
+ PidAndNameBuffer->ProcessName = (PVOID)((UINT64)PidAndNameBuffer + sizeof(TRANSPARENCY_PROCESS));
+ }
+
+ //
+ // Link it to the list of process that we need to transparent
+ // vm-exits for them
+ //
+ // InsertHeadList(&g_TransparentModeMeasurements->ProcessList, &(PidAndNameBuffer->OtherProcesses));
+
+ return TRUE;
+}
+
+//
+// /**
+// * @brief maximum random value
+// */
+// #define MY_RAND_MAX 32768
+//
+// /**
+// * @brief pre-defined log result
+// * @details we used this because we want to avoid using floating-points in
+// * kernel
+// */
+// int TransparentTableLog[] =
+// {
+// 0,
+// 69,
+// 110,
+// 139,
+// 161,
+// 179,
+// 195,
+// 208,
+// 220,
+// 230,
+// 240,
+// 248,
+// 256,
+// 264,
+// 271,
+// 277,
+// 283,
+// 289,
+// 294,
+// 300,
+// 304,
+// 309,
+// 314,
+// 318,
+// 322,
+// 326,
+// 330,
+// 333,
+// 337,
+// 340,
+// 343,
+// 347,
+// 350,
+// 353,
+// 356,
+// 358,
+// 361,
+// 364,
+// 366,
+// 369,
+// 371,
+// 374,
+// 376,
+// 378,
+// 381,
+// 383,
+// 385,
+// 387,
+// 389,
+// 391,
+// 393,
+// 395,
+// 397,
+// 399,
+// 401,
+// 403,
+// 404,
+// 406,
+// 408,
+// 409,
+// 411,
+// 413,
+// 414,
+// 416,
+// 417,
+// 419,
+// 420,
+// 422,
+// 423,
+// 425,
+// 426,
+// 428,
+// 429,
+// 430,
+// 432,
+// 433,
+// 434,
+// 436,
+// 437,
+// 438,
+// 439,
+// 441,
+// 442,
+// 443,
+// 444,
+// 445,
+// 447,
+// 448,
+// 449,
+// 450,
+// 451,
+// 452,
+// 453,
+// 454,
+// 455,
+// 456,
+// 457,
+// 458,
+// 460,
+// 461};
+//
+//
+// /**
+// * @brief Integer power function definition.
+// *
+// * @params x Base Value
+// * @params p Power Value
+// * @return int
+// */
+// int
+// TransparentPow(int x, int p)
+// {
+// int Res = 1;
+// for (int i = 0; i < p; i++)
+// {
+// Res = Res * x;
+// }
+// return Res;
+// }
+//
+// /**
+// * @brief Integer Natural Logarithm function estimation.
+// *
+// * @params x input value
+// * @return int
+// */
+// int
+// TransparentLog(int x)
+// {
+// int n = x;
+// int Digit = 0;
+//
+// while (n >= 100)
+// {
+// n = n / 10;
+// Digit++;
+// }
+//
+// //
+// // Use pre-defined values of logarithms and estimate the total value
+// //
+// return TransparentTableLog[n] / 100 + (Digit * 23) / 10;
+// }
+// /**
+// * @brief Integer root function estimation.
+// *
+// * @params x input value
+// * @return int
+// */
+// int
+// TransparentSqrt(int x)
+// {
+// int Res = 0;
+// int Bit;
+//
+// //
+// // The second-to-top bit is set.
+// //
+// Bit = 1 << 30;
+//
+// //
+// // "Bit" starts at the highest power of four <= the argument.
+// //
+// while (Bit > x)
+// Bit >>= 2;
+//
+// while (Bit != 0)
+// {
+// if (x >= Res + Bit)
+// {
+// x -= Res + Bit;
+// Res = (Res >> 1) + Bit;
+// }
+// else
+// Res >>= 1;
+// Bit >>= 2;
+// }
+// return Res;
+// }
+//
+// /**
+// * @brief Integer Gaussian Random Number Generator(GRNG) based on Box-Muller method. A Float to Integer
+// * mapping is used in the function.
+// *
+// * @params Average Mean
+// * @parans Sigma Standard Deviation of the targeted Gaussian Distribution
+// * @return int
+// */
+// int
+// TransparentRandn(int Average, int Sigma)
+// {
+// int U1, r1, U2, r2, W, Mult;
+// int X1, X2 = 0, XS1;
+// int LogTemp = 0;
+//
+// do
+// {
+// r1 = TransparentGetRand();
+// r2 = TransparentGetRand();
+//
+// U1 = (r1 % MY_RAND_MAX) - (MY_RAND_MAX / 2);
+//
+// U2 = (r2 % MY_RAND_MAX) - (MY_RAND_MAX / 2);
+//
+// W = U1 * U1 + U2 * U2;
+// } while (W >= MY_RAND_MAX * MY_RAND_MAX / 2 || W == 0);
+//
+// LogTemp = (TransparentLog(W) - TransparentLog(MY_RAND_MAX * MY_RAND_MAX));
+//
+// Mult = TransparentSqrt((-2 * LogTemp) * (MY_RAND_MAX * MY_RAND_MAX / W));
+//
+// X1 = U1 * Mult / MY_RAND_MAX;
+// XS1 = U1 * Mult;
+//
+// X2 = U2 * Mult / MY_RAND_MAX;
+//
+// return (Average + (Sigma * XS1) / MY_RAND_MAX);
+// }
+//
+//
+// /**
+// * @brief Hide debugger on transparent-mode (activate transparent-mode)
+// *
+// * @param Measurements
+// * @return NTSTATUS
+// */
+// NTSTATUS
+// TransparentHideDebugger(PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE Measurements)
+// {
+// //
+// // Check whether the transparent-mode was already initialized or not
+// //
+// if (!g_TransparentMode)
+// {
+// //
+// // Allocate the measurements buffer
+// //
+// g_TransparentModeMeasurements = (PTRANSPARENCY_MEASUREMENTS)PlatformMemAllocateZeroedNonPagedPool(sizeof(TRANSPARENCY_MEASUREMENTS));
+//
+// if (!g_TransparentModeMeasurements)
+// {
+// return STATUS_INSUFFICIENT_RESOURCES;
+// }
+//
+// //
+// // Initialize the lists
+// //
+// InitializeListHead(&g_TransparentModeMeasurements->ProcessList);
+//
+// //
+// // Fill the transparency details CPUID
+// //
+// g_TransparentModeMeasurements->CpuidAverage = Measurements->CpuidAverage;
+// g_TransparentModeMeasurements->CpuidMedian = Measurements->CpuidMedian;
+// g_TransparentModeMeasurements->CpuidStandardDeviation = Measurements->CpuidStandardDeviation;
+//
+// //
+// // Fill the transparency details RDTSC
+// //
+// g_TransparentModeMeasurements->RdtscAverage = Measurements->RdtscAverage;
+// g_TransparentModeMeasurements->RdtscMedian = Measurements->RdtscMedian;
+// g_TransparentModeMeasurements->RdtscStandardDeviation = Measurements->RdtscStandardDeviation;
+//
+// //
+// // add the new process name or Id to the list
+// //
+// TransparentAddNameOrProcessIdToTheList(Measurements);
+//
+// //
+// // Enable RDTSC and RDTSCP exiting on all cores
+// //
+// BroadcastEnableRdtscExitingAllCores();
+//
+// //
+// // Finally, enable the transparent-mode
+// //
+// g_TransparentMode = TRUE;
+// }
+// else
+// {
+// //
+// // It's already initialized, we just need to
+// // add the new process name or Id to the list
+// //
+// TransparentAddNameOrProcessIdToTheList(Measurements);
+// }
+//
+// return STATUS_SUCCESS;
+// }
+//
+// /**
+// * @brief Deactivate transparent-mode
+// *
+// * @return NTSTATUS
+// */
+// NTSTATUS
+// TransparentUnhideDebugger()
+// {
+// PLIST_ENTRY TempList = 0;
+// PVOID BufferToDeAllocate = 0;
+//
+// if (g_TransparentMode)
+// {
+// //
+// // Disable the transparent-mode
+// //
+// g_TransparentMode = FALSE;
+//
+// //
+// // Disable RDTSC and RDTSCP emulation
+// //
+// BroadcastDisableRdtscExitingAllCores();
+//
+// //
+// // Free list of allocated buffers
+// //
+// // Check for process id and process name, if not match then we don't emulate it
+// //
+// TempList = &g_TransparentModeMeasurements->ProcessList;
+// while (&g_TransparentModeMeasurements->ProcessList != TempList->Flink)
+// {
+// TempList = TempList->Flink;
+// PTRANSPARENCY_PROCESS ProcessDetails = (PTRANSPARENCY_PROCESS)CONTAINING_RECORD(TempList, TRANSPARENCY_PROCESS, OtherProcesses);
+//
+// //
+// // Save the buffer so we can de-allocate it
+// //
+// BufferToDeAllocate = ProcessDetails->BufferAddress;
+//
+// //
+// // We have to remove the event from the list
+// //
+// RemoveEntryList(&ProcessDetails->OtherProcesses);
+//
+// //
+// // Free the buffer
+// //
+// PlatformMemFreePool(BufferToDeAllocate);
+// }
+//
+// //
+// // Deallocate the measurements buffer
+// //
+// PlatformMemFreePool(g_TransparentModeMeasurements);
+// g_TransparentModeMeasurements = NULL;
+//
+// return STATUS_SUCCESS;
+// }
+// else
+// {
+// return STATUS_UNSUCCESSFUL;
+// }
+// }
+//
+// /**
+// * @brief VM-Exit handler for different exit reasons
+// * @details Should be called from vmx-root
+// *
+// * @param Regs The virtual processor's state of registers
+// * @param ExitReason Exit Reason
+// * @return BOOLEAN Return True we should emulate RDTSCP
+// * or return false if we should not emulate RDTSCP
+// */
+// BOOLEAN
+// TransparentModeStart(GUEST_REGS * Regs, UINT32 ExitReason)
+// {
+// UINT32 Aux = 0;
+// PLIST_ENTRY TempList = 0;
+// PCHAR CurrentProcessName = 0;
+// UINT32 CurrentProcessId;
+// UINT64 CurrrentTime;
+// HANDLE CurrentThreadId;
+// BOOLEAN Result = TRUE;
+// BOOLEAN IsProcessOnTransparencyList = FALSE;
+//
+// //
+// // Save the current time
+// //
+// CurrrentTime = CpuReadTscp(&Aux);
+//
+// //
+// // Save time of vm-exit on each logical processor separately
+// //
+// VCpu->TransparencyState.PreviousTimeStampCounter = CurrrentTime;
+//
+// //
+// // Find the current process id and name
+// //
+// CurrentProcessId = HANDLE_TO_UINT32(PsGetCurrentProcessId());
+// CurrentProcessName = CommonGetProcessNameFromProcessControlBlock(PsGetCurrentProcess());
+//
+// //
+// // Check for process id and process name, if not match then we don't emulate it
+// //
+// TempList = &g_TransparentModeMeasurements->ProcessList;
+// while (&g_TransparentModeMeasurements->ProcessList != TempList->Flink)
+// {
+// TempList = TempList->Flink;
+// PTRANSPARENCY_PROCESS ProcessDetails = (PTRANSPARENCY_PROCESS)CONTAINING_RECORD(TempList, TRANSPARENCY_PROCESS, OtherProcesses);
+// if (ProcessDetails->TrueIfProcessIdAndFalseIfProcessName)
+// {
+// //
+// // This entry is process id
+// //
+// if (ProcessDetails->ProcessId == CurrentProcessId)
+// {
+// //
+// // Let the transparency handler to handle it
+// //
+// IsProcessOnTransparencyList = TRUE;
+// break;
+// }
+// }
+// else
+// {
+// //
+// // This entry is a process name
+// //
+// if (CurrentProcessName != NULL && CommonIsStringStartsWith(CurrentProcessName, ProcessDetails->ProcessName))
+// {
+// //
+// // Let the transparency handler to handle it
+// //
+// IsProcessOnTransparencyList = TRUE;
+// break;
+// }
+// }
+// }
+//
+// //
+// // Check whether we find this process on transparency list or not
+// //
+// if (!IsProcessOnTransparencyList)
+// {
+// //
+// // No, we didn't let's do the normal tasks
+// //
+// return TRUE;
+// }
+//
+// //
+// // Get current thread Id
+// //
+// CurrentThreadId = PsGetCurrentThreadId();
+//
+// //
+// // Check whether we are in new thread or in previous thread
+// //
+// if (VCpu->TransparencyState.ThreadId != CurrentThreadId)
+// {
+// //
+// // It's a new thread Id reset everything
+// //
+// VCpu->TransparencyState.ThreadId = CurrentThreadId;
+// VCpu->TransparencyState.RevealedTimeStampCounterByRdtsc = NULL64_ZERO;
+// VCpu->TransparencyState.CpuidAfterRdtscDetected = FALSE;
+// }
+//
+// //
+// // Now, it's time to check and play with RDTSC/P and CPUID
+// //
+//
+// if (ExitReason == VMX_EXIT_REASON_EXECUTE_RDTSC || ExitReason == VMX_EXIT_REASON_EXECUTE_RDTSCP)
+// {
+// if (VCpu->TransparencyState.RevealedTimeStampCounterByRdtsc == NULL64_ZERO)
+// {
+// //
+// // It's a timing and the previous time for the thread is null
+// // so we need to save the time (maybe) for future use
+// //
+// VCpu->TransparencyState.RevealedTimeStampCounterByRdtsc = CurrrentTime;
+// }
+// else if (VCpu->TransparencyState.CpuidAfterRdtscDetected == TRUE)
+// {
+// //
+// // Someone tries to know about the hypervisor
+// // let's play with them
+// //
+//
+// // LogInfo("Possible RDTSC+CPUID+RDTSC");
+// }
+// else if (VCpu->TransparencyState.RevealedTimeStampCounterByRdtsc != NULL64_ZERO &&
+// VCpu->TransparencyState.CpuidAfterRdtscDetected == FALSE)
+// {
+// //
+// // It's a new rdtscp, let's save the new value
+// //
+// VCpu->TransparencyState.RevealedTimeStampCounterByRdtsc +=
+// TransparentRandn((UINT32)g_TransparentModeMeasurements->CpuidAverage,
+// (UINT32)g_TransparentModeMeasurements->CpuidStandardDeviation);
+// }
+//
+// //
+// // Adjust the rdtsc based on RevealedTimeStampCounterByRdtsc
+// //
+// Regs->rax = 0x00000000ffffffff &
+// VCpu->TransparencyState.RevealedTimeStampCounterByRdtsc;
+//
+// Regs->rdx = 0x00000000ffffffff &
+// (VCpu->TransparencyState.RevealedTimeStampCounterByRdtsc >> 32);
+//
+// //
+// // Check if we need to adjust rcx as a result of rdtscp
+// //
+// if (ExitReason == VMX_EXIT_REASON_EXECUTE_RDTSCP)
+// {
+// Regs->rcx = 0x00000000ffffffff & Aux;
+// }
+// //
+// // Shows that vm-exit handler should not emulate the RDTSC/P
+// //
+// Result = FALSE;
+// }
+// else if (ExitReason == VMX_EXIT_REASON_EXECUTE_CPUID &&
+// VCpu->TransparencyState.RevealedTimeStampCounterByRdtsc != NULL64_ZERO)
+// {
+// //
+// // The guy executed one or more CPUIDs after an rdtscp so we
+// // need to add new cpuid value to previous timer and also
+// // we need to store it somewhere to remember this behavior
+// //
+// VCpu->TransparencyState.RevealedTimeStampCounterByRdtsc +=
+// TransparentRandn((UINT32)g_TransparentModeMeasurements->CpuidAverage,
+// (UINT32)g_TransparentModeMeasurements->CpuidStandardDeviation);
+//
+// VCpu->TransparencyState.CpuidAfterRdtscDetected = TRUE;
+// }
+//
+// return Result;
+// }
+//
diff --git a/hyperdbg/hyperevade/code/UnloadDll.c b/hyperdbg/hyperevade/code/UnloadDll.c
new file mode 100644
index 00000000..17321dbf
--- /dev/null
+++ b/hyperdbg/hyperevade/code/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/hyperevade/code/VmxFootprints.c b/hyperdbg/hyperevade/code/VmxFootprints.c
new file mode 100644
index 00000000..1133f2f5
--- /dev/null
+++ b/hyperdbg/hyperevade/code/VmxFootprints.c
@@ -0,0 +1,165 @@
+/**
+ * @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
+ * @date 2025-06-08
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief Handle Cpuid Vmexits when the Transparent mode is enabled
+ *
+ * @param Regs The virtual processor's state of registers
+ * @param CpuInfo The temporary logical processor registers
+ *
+ * @return VOID
+ */
+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)
+ {
+ //
+ // Unset the Hypervisor Present-bit in RCX, which Intel and AMD have both
+ // reserved for this indication
+ //
+ CpuInfo[2] &= ~HYPERV_HYPERVISOR_PRESENT_BIT;
+ }
+ else if (Regs->rax == CPUID_HV_VENDOR_AND_MAX_FUNCTIONS || Regs->rax == HYPERV_CPUID_INTERFACE)
+ {
+ //
+ // When transparent, all CPUID leaves in the 0x40000000+ range should contain no usable data
+ //
+ CpuInfo[0] = CpuInfo[1] = CpuInfo[2] = CpuInfo[3] = 0x40000000;
+ }
+}
+
+/**
+ * @brief Handle RDMSR VM exits when the Transparent mode is enabled
+ *
+ * @param Regs The virtual processor's state of registers
+ * @param TargetMsr Target MSR in ECX register
+ *
+ * @return BOOLEAN Whether the emulation should be further continued or not
+ */
+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
+ //
+ // Sina: Needs more investigation since injecting #GP on Nested-virtualization environments
+ // will crash the VM on Meteor Lake processors since the OS expects to use synthetic timers
+ // (HV_REGISTER_STIMER0_CONFIG and HV_REGISTER_STIMER0_COUNT) to receive interrupts
+ // Ref: https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/timers
+ //
+ // if (TargetMsr >= RESERVED_MSR_RANGE_LOW && TargetMsr <= RESERVED_MSR_RANGE_HI)
+ // {
+ // LogInfo("RDMSR attempts to write to a reserved MSR range. MSR: %x",
+ // TargetMsr);
+ //
+ // g_Callbacks.EventInjectGeneralProtection();
+ // return TRUE; // Should not emulate further
+ // }
+ // else
+ // {
+ // //
+ // // Not handled in the transparent-mode
+ // //
+ // return FALSE;
+ // }
+
+ UNREFERENCED_PARAMETER(Regs);
+ UNREFERENCED_PARAMETER(TargetMsr);
+
+ return FALSE;
+}
+
+/**
+ * @brief Handle WRMSR VM exits when the Transparent mode is enabled
+ *
+ * @param Regs The virtual processor's state of registers
+ * @param TargetMsr Target MSR in ECX register
+ *
+ * @return BOOLEAN Whether the emulation should be further continued or not
+ */
+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)
+ // {
+ // //
+ // // 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
+ // //
+ //
+ // LogInfo("WRMSR attempts to write to a reserved MSR range. MSR: %x, rax: %llx, rdx: %llx",
+ // TargetMsr,
+ // Regs->rax,
+ // Regs->rdx);
+ //
+ // g_Callbacks.EventInjectGeneralProtection();
+ //
+ // return TRUE; // Should not emulate further
+ // }
+ // else
+ // {
+ // //
+ // // Not handled in the transparent-mode
+ // //
+ // return FALSE;
+ // }
+
+ UNREFERENCED_PARAMETER(Regs);
+ UNREFERENCED_PARAMETER(TargetMsr);
+
+ return FALSE;
+}
+
+/**
+ * @brief Handle anti-debugging method of a trap flag after a VM exit
+ *
+ * @return VOID
+ */
+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
+ //
+ g_Callbacks.HvHandleTrapFlag();
+}
diff --git a/hyperdbg/hyperevade/header/SyscallFootprints.h b/hyperdbg/hyperevade/header/SyscallFootprints.h
new file mode 100644
index 00000000..02e3d6a3
--- /dev/null
+++ b/hyperdbg/hyperevade/header/SyscallFootprints.h
@@ -0,0 +1,646 @@
+/**
+ * @file SyscallFootprints.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Hide the debugger from SYSCALL anti-debugging and anti-hypervisor methods (headers)
+ * @details
+ * @version 0.14
+ * @date 2024-06-08
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Enums //
+//////////////////////////////////////////////////
+
+/**
+ * @brief System information class
+ *
+ */
+typedef enum _SYSTEM_INFORMATION_CLASS
+{
+ SystemProcessInformation = 0x05,
+ SystemExtendedProcessInformation = 0x39,
+ SystemFullProcessInformation = 0x94,
+ SystemModuleInformation = 0x0B,
+ SystemKernelDebuggerInformation = 0x23,
+ SystemCodeIntegrityInformation = 0x67,
+ SystemFirmwareTableInformation = 0x4C,
+} SYSTEM_INFORMATION_CLASS,
+ *PSYSTEM_INFORMATION_CLASS;
+
+//////////////////////////////////////////////////
+// Structures //
+//////////////////////////////////////////////////
+
+/**
+ * @brief System Information for Code Integrity
+ *
+ */
+typedef struct _SYSTEM_CODEINTEGRITY_INFORMATION
+{
+ ULONG Length;
+ ULONG CodeIntegrityOptions;
+
+} SYSTEM_CODEINTEGRITY_INFORMATION, *PSYSTEM_CODEINTEGRITY_INFORMATION;
+
+/**
+ * @brief System Information for running processes
+ *
+ */
+typedef struct _SYSTEM_PROCESS_INFORMATION
+{
+ ULONG NextEntryOffset;
+ ULONG NumberOfThreads;
+ BYTE Reserved1[48];
+ UNICODE_STRING ImageName;
+ KPRIORITY BasePriority;
+ HANDLE UniqueProcessId;
+ PVOID Reserved2;
+ ULONG HandleCount;
+ ULONG SessionId;
+ PVOID Reserved3;
+ SIZE_T PeakVirtualSize;
+ SIZE_T VirtualSize;
+ ULONG Reserved4;
+ SIZE_T PeakWorkingSetSize;
+ SIZE_T WorkingSetSize;
+ PVOID Reserved5;
+ SIZE_T QuotaPagedPoolUsage;
+ PVOID Reserved6;
+ SIZE_T QuotaNonPagedPoolUsage;
+ SIZE_T PagefileUsage;
+ SIZE_T PeakPagefileUsage;
+ SIZE_T PrivatePageCount;
+ LARGE_INTEGER Reserved7[6];
+} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
+
+/**
+ * @brief SSDT structure
+ *
+ */
+typedef struct _SSDT_STRUCT
+{
+ LONG * ServiceTable;
+ PVOID CounterTable;
+#ifdef _WIN64
+ UINT64 NumberOfServices;
+#else
+ ULONG NumberOfServices;
+#endif
+ PCHAR ArgumentTable;
+} SSDT_STRUCT, *PSSDT_STRUCT;
+
+/**
+ * @brief Module entry
+ *
+ */
+typedef struct _SYSTEM_MODULE_ENTRY
+{
+ HANDLE Section;
+ PVOID MappedBase;
+ PVOID ImageBase;
+ ULONG ImageSize;
+ ULONG Flags;
+ UINT16 LoadOrderIndex;
+ UINT16 InitOrderIndex;
+ UINT16 LoadCount;
+ UINT16 OffsetToFileName;
+ UCHAR FullPathName[256];
+} SYSTEM_MODULE_ENTRY, *PSYSTEM_MODULE_ENTRY;
+
+/**
+ * @brief System Information for modules
+ *
+ */
+typedef struct _SYSTEM_MODULE_INFORMATION
+{
+ ULONG Count;
+ SYSTEM_MODULE_ENTRY Module[1];
+
+} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
+
+typedef NTSTATUS(NTAPI * ZWQUERYSYSTEMINFORMATION)(
+ IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
+ OUT PVOID SystemInformation,
+ IN ULONG SystemInformationLength,
+ OUT PULONG ReturnLength OPTIONAL);
+
+NTSTATUS(*g_NtCreateFileOrig)
+(
+ PHANDLE FileHandle,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_ATTRIBUTES ObjectAttributes,
+ PIO_STATUS_BLOCK IoStatusBlock,
+ PLARGE_INTEGER AllocationSize,
+ ULONG FileAttributes,
+ ULONG ShareAccess,
+ ULONG CreateDisposition,
+ ULONG CreateOptions,
+ PVOID EaBuffer,
+ ULONG EaLength);
+
+//////////////////////////////////////////////////
+// Globals //
+//////////////////////////////////////////////////
+
+/**
+ * @brief A variable holding the randomly chosen index for the genuine vendor list.
+ * This is used for transparent vendor spoofing
+ */
+static WORD g_TransparentGenuineVendorStringIndex = 0;
+
+/**
+ * @brief System call numbers information
+ */
+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
+ *
+ */
+static const PCHAR TRANSPARENT_WIN_PROCESS_IGNORE[] = {
+ "winlogon.exe",
+ "wininit.exe",
+ "csrss.exe",
+ "sihost.exe",
+ "explorer.exe",
+};
+
+/**
+ * @brief A brief list of genuine system vendors device ID's used for manufacturer spoofing
+ *
+ */
+static const PWCHAR TRANSPARENT_LEGIT_DEVICE_ID_VENDOR_STRINGS_WCHAR[] = {
+ L"VEN_8086", // Intel
+ L"VEN_10DE", // NVIDIA
+ L"VEN_1002", // AMD
+ L"VEN_10EC", // Realtek
+
+};
+
+/**
+ * @brief A list of genuine system vendors used for manufacturer spoofing
+ *
+ */
+static const PWCHAR TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR[] = {
+ L"ASUS",
+ L"ASUSTeK Computer INC.",
+ L"ASUSTek",
+ L"ASUSTEK COMPUTER INC.",
+
+ // MSI
+ L"Micro-Star International Co., Ltd.",
+ L"MSI",
+ L"MICRO-STAR INTERNATIONAL CO., LTD",
+
+ // Gigabyte
+ L"Gigabyte Technology Co., Ltd.",
+ L"GIGABYTE",
+ L"Gigabyte Technology",
+
+ // ASRock
+ L"ASRock",
+ L"ASRock Incorporation",
+ L"ASRock Inc.",
+
+ // Dell
+ L"Dell Inc.",
+ L"DELL",
+ L"Dell Computer Corporation",
+
+ // HP
+ L"Hewlett-Packard",
+ L"Hewlett Packard",
+ L"HP",
+ L"HP Inc.",
+
+ // Lenovo
+ L"LENOVO",
+ L"Lenovo Group Limited",
+
+ // Intel
+ L"Intel Corporation",
+ L"Intel",
+
+ // EVGA
+ L"EVGA Corporation",
+ L"EVGA",
+};
+
+/**
+ * @brief A list of common Hypervisor specific process executables
+ *
+ */
+static const PWCH HV_PROCESSES[] = {
+ L"hyperdbg-cli.exe",
+ L"vboxservice.exe",
+ L"vmsrvc.exe",
+ L"xenservice.exe",
+ L"vm3dservice.exe",
+ L"VGAuthService.exe",
+ L"vmtoolsd.exe",
+ L"vdagent.exe",
+ L"vdservice.exe",
+ L"qemuwmi.exe",
+ L"vboxtray.exe",
+ L"VBoxControl.exe",
+ L"VGAuthService.exe",
+
+ //
+ // Common Debugging Tools
+ //
+ L"ollydbg.exe",
+ L"ollyice.exe",
+ L"ProcessHacker.exe",
+ L"tcpview.exe",
+ L"autoruns.exe",
+ L"autorunsc.exe",
+ L"filemon.exe",
+ L"procmon.exe",
+ L"regmon.exe",
+ L"procexp.exe",
+ L"idaq.exe",
+ L"idaq64.exe",
+ L"ImmunityDebugger.exe",
+ L"Wireshark.exe",
+ L"dumpcap.exe",
+ L"HookExplorer.exe",
+ L"ImportREC.exe",
+ L"PETools.exe",
+ L"LordPE.exe",
+ L"SysInspector.exe",
+ L"proc_analyzer.exe",
+ L"sysAnalyzer.exe",
+ L"sniff_hit.exe",
+ L"windbg.exe",
+ L"joeboxcontrol.exe",
+ L"joeboxserver.exe",
+ L"ResourceHacker.exe",
+ L"x32dbg.exe",
+ L"x64dbg.exe",
+ L"Fiddler.exe",
+ L"httpdebugger.exe",
+ L"cheatengine-i386.exe",
+ L"cheatengine-x86_64.exe",
+ L"cheatengine-x86_64-SSE4-AVX2.exe",
+ L"frida-helper-32.exe",
+ L"frida-helper-64.exe",
+
+};
+
+/**
+ * @brief A list of common Hypervisor specific drivers
+ *
+ */
+static const PCHAR HV_DRIVER[] = {
+ "hyperkd",
+ "hyperhv",
+
+ //
+ // Drivers from VBox
+ //
+
+ "VBoxGuest",
+ "VBoxMouse",
+ "VBoxSF",
+
+ //
+ // Drivers from VMWare Tools
+ //
+
+ "vmrawdsk",
+ "giappdef",
+ "glxgi",
+ "vm3dmp",
+ "vm3dmp_loader",
+ "vm3dmp-debug",
+ "vm3dmp-stats",
+ "vmxnet3",
+ "vmxnet",
+ "vnetWFP",
+ "vnetflt",
+ "vsepflt",
+ "pvscsi",
+ "vmmemctl",
+ "vmhgfs",
+ "vmusbmouse",
+ "vmmouse",
+ "vmaudio",
+ "vmci",
+ "vsock",
+
+ //
+ // Hyper-V Drivers
+ //
+
+ "VMBusHID",
+ "vmbus",
+ "vmgid",
+ "IndirectKmd",
+ "HyperVideo",
+ "hyperkbd",
+
+};
+
+/**
+ * @brief A list of common Hypervisor specific files
+ *
+ */
+static const PWCH HV_FILES[] = {
+
+ //
+ // HyperDbg Files
+ //
+ L"hyperhv",
+ L"hyperkd",
+ L"hyperlog",
+ L"libhyperdbg",
+
+ //
+ // VMware Files
+ //
+ L"vmmouse.sys",
+ L"Vmmouse.sys",
+ L"vmusbmouse.sys",
+ L"Vmusbmouse.sys",
+ L"vm3dgl.dll",
+ L"vmdum.dll",
+ L"VmGuestLibJava.dll",
+ L"vm3dver.dll",
+ L"vmtray.dll",
+ L"VMToolsHook.dll",
+ L"vmGuestLib.dll",
+ L"vmhgfs.dll",
+ L"vmhgfs.sys",
+ L"vm3dum64_loader.dll",
+ L"vm3dum64_10.dll",
+ L"vmnet.sys",
+ L"vmusb.sys",
+ L"vm3dmp.sys",
+ L"vmci.sys",
+ L"vmmemctl.sys",
+ L"vmx86.sys",
+ L"vmrawdsk.sys",
+ L"vmkdb.sys",
+ L"vmnetuserif.sys",
+ L"vmnetadapter.sys",
+ L"VMware Tools",
+ L"VMWare",
+
+ //
+ // VirtualBox Files
+ //
+ L"VBoxMouse.sys",
+ L"VBoxGuest.sys",
+ L"VBoxSF.sys",
+ L"VBoxVideo.sys",
+ L"vboxoglpackspu.dll",
+ L"vboxoglpassthroughspu.dll",
+ L"vboxservice.exe",
+ L"vboxoglcrutil.dll",
+ L"vboxdisp.dll",
+ L"vboxhook.dll",
+ L"vboxmrxnp.dll",
+ L"vboxogl.dll",
+ L"vboxtray.exe",
+ L"VBoxControl.exe",
+ L"vboxoglerrorspu.dll",
+ L"vboxoglfeedbackspu.dll",
+ L"vboxoglarrayspu.dll",
+ L"vboxmrxnp.dll",
+ L"virtualbox guest additions",
+
+ //
+ // KVM files
+ //
+ L"balloon.sys",
+ L"netkvm.sys",
+ L"pvpanic.sys",
+ L"viofs.sys",
+ L"viogpudo.sys",
+ L"vioinput.sys",
+ L"viorng.sys",
+ L"vioscsi.sys",
+ L"vioser.sys",
+ L"viostor.sys",
+
+ //
+ // VPC files
+ //
+ L"vmsrvc.sys",
+ L"vmusrvc.sys",
+ L"vmsrvc.exe",
+ L"vmusrvc.exe",
+ L"vpc-s3.sys",
+ L"Virtio-Win",
+
+ L"qemu-ga",
+ L"SPICE Guest Tools",
+};
+
+/**
+ * @brief A list of common Hypervisor specific directories
+ *
+ */
+static const PWCH HV_DIRS[] = {
+ L"hyperhv",
+ L"VMware Tools",
+ L"Virtio-Win",
+ L"qemu-ga",
+ L"SPICE Guest Tools",
+ L"VMware",
+ L"VMWARE",
+ L"virtualbox guest additions",
+ L"VirtualBox Guest Additions",
+};
+
+/**
+ * @brief A list of common Hypervisor specific registry keys
+ *
+ */
+static const PWCH HV_REGKEYS[] = {
+
+ //
+ // PCI device vendor id's
+ //
+ // NOTE: These need to stay at the top of the list
+ //
+ L"VEN_80EE",
+ L"VEN_15AD",
+ L"VEN_5333",
+
+ //
+ // Common names
+ //
+ L"Virtual",
+ L"VIRTUAL",
+ L"virtual",
+ L"Hypervisor",
+ L"hypervisor",
+ L"HYPERVISOR",
+
+ //
+ // VMWare
+ //
+ L"VMware Tools",
+ L"VMware, Inc.",
+ L"vmusbmouse",
+ L"VMware",
+ L"VMWARE",
+ L"VMWare",
+ L"vmdebug",
+ L"vmmouse",
+ L"VMTools",
+ L"VMMEMCTL",
+ L"vmware tools",
+ L"VMW0001",
+ L"VMW0002",
+ L"VMW0003",
+
+ L"sandbox",
+ L"Sandboxie",
+
+ //
+ // VirtualBox
+ //
+ L"VirtualBox Guest Additions",
+ L"VBOX__",
+ L"VBoxGuest",
+ L"VBoxMouse",
+ L"VBoxService",
+ L"VBoxSF",
+ L"VBoxVideo",
+ L"VIRTUALBOX",
+ L"SUN MICROSYSTEMS",
+ L"VBOXVER",
+ L"VBOXAPIC",
+ L"INNOTEK GMBH",
+
+ //
+ // QEMU
+ //
+ L"qemu-ga",
+ L"SPICE Guest Tools",
+
+ //
+ // VPC
+ //
+ L"vpcbus",
+ L"vpc-s3",
+ L"vpcuhub",
+ L"msvmmouf",
+ L"Wine",
+ L"xen",
+ L"VIRTUAL MACHINE",
+ L"GOOGLE COMPUTE ENGINE",
+ L"sandbox",
+ L"Sandboxie",
+
+ //
+ // KVM
+ //
+ L"vioscsi",
+ L"viostor",
+ L"VirtIO-FS Service",
+ L"VirtioSerial",
+ L"BALLOON",
+ L"BalloonService",
+ L"netkvm",
+
+};
+
+/**
+ * @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",
+ L"Identifier",
+ L"SystemBiosVersion",
+ L"VideoBiosVersion",
+ L"ProductID",
+ L"SystemManufacturer",
+ L"SystemProductName",
+ L"DeviceDesc",
+ L"FriendlyName",
+ L"DisplayName",
+ L"ProviderName",
+ L"Device Description",
+ L"BIOSVendor",
+ L"DriverDesc",
+ L"InfSection",
+ L"Service",
+ L"0",
+ L"1",
+ L"00000000",
+};
+
+/**
+ * @brief A list of common Hypervisor firmware entries
+ *
+ * @details The list contains both a normal and uppercase versions of the entries, for better compatibility
+ *
+ */
+static const PCHAR HV_FIRM_NAMES[] = {
+ "440BX Desktop Reference Platform",
+ "VMWARE, INC.",
+ "VMware, Inc.",
+ "VMWARE",
+ "VMware",
+ "VMW",
+ "VS2005R2",
+ "VirtualBox",
+ "VIRTUALBOX",
+ "Oracle",
+ "ORACLE",
+ "Innotek",
+ "INNOTEK",
+ "Virtual",
+
+};
+
+#endif
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+VOID
+TransparentHandleNtQuerySystemInformationSyscall(GUEST_REGS * Regs);
+
+VOID
+TransparentHandleNtQueryAttributesFileSyscall(GUEST_REGS * Regs);
+
+VOID
+TransparentHandleNtSystemDebugControlSyscall(GUEST_REGS * Regs);
+
+VOID
+TransparentHandleNtOpenDirectoryObjectSyscall(GUEST_REGS * Regs);
+
+VOID
+TransparentHandleNtQueryInformationProcessSyscall(GUEST_REGS * Regs);
+
+VOID
+TransparentHandleNtOpenFileSyscall(GUEST_REGS * Regs);
+
+VOID
+TransparentHandleNtOpenKeySyscall(GUEST_REGS * Regs);
+
+VOID
+TransparentHandleNtQueryValueKeySyscall(GUEST_REGS * Regs);
+
+VOID
+TransparentHandleNtEnumerateKeySyscall(GUEST_REGS * Regs);
diff --git a/hyperdbg/hprdbghv/header/transparency/Transparency.h b/hyperdbg/hyperevade/header/Transparency.h
similarity index 78%
rename from hyperdbg/hprdbghv/header/transparency/Transparency.h
rename to hyperdbg/hyperevade/header/Transparency.h
index 1123920c..5b3493b8 100644
--- a/hyperdbg/hprdbghv/header/transparency/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
@@ -12,31 +13,14 @@
#pragma once
//////////////////////////////////////////////////
-// Functions //
-//////////////////////////////////////////////////
-
-BOOLEAN
-TransparentModeStart(VIRTUAL_MACHINE_STATE * VCpu, UINT32 ExitReason);
-
-//////////////////////////////////////////////////
-// Definitions //
+// Globals //
//////////////////////////////////////////////////
/**
- * @brief IA32_TIME_STAMP_COUNTER MSR (rcx)
+ * @brief List of callbacks
*
*/
-#define MSR_IA32_TIME_STAMP_COUNTER 0x10
-
-/**
- * @brief Maximum value that can be returned by the rand function
- *
- */
-#define RAND_MAX 0x7fff
-
-//////////////////////////////////////////////////
-// Structures //
-//////////////////////////////////////////////////
+HYPEREVADE_CALLBACKS g_Callbacks;
/**
* @brief The measurements from user-mode and kernel-mode
@@ -69,3 +53,27 @@ typedef struct _TRANSPARENCY_PROCESS
LIST_ENTRY OtherProcesses;
} TRANSPARENCY_PROCESS, *PTRANSPARENCY_PROCESS;
+
+//////////////////////////////////////////////////
+// Globals //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Shows whether the debugger transparent mode
+ * is enabled (true) or not (false)
+ *
+ */
+BOOLEAN g_TransparentMode;
+
+/**
+ * @brief The enabled transparent-mode feature mask
+ *
+ */
+UINT32 g_TransparentEvadeMask;
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+UINT32
+TransparentGetRand();
diff --git a/hyperdbg/hyperevade/header/VmxFootprints.h b/hyperdbg/hyperevade/header/VmxFootprints.h
new file mode 100644
index 00000000..39560e8c
--- /dev/null
+++ b/hyperdbg/hyperevade/header/VmxFootprints.h
@@ -0,0 +1,16 @@
+/**
+ * @file VmxFootprints.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Hide the debugger from VMX-footprints of anti-debugging and anti-hypervisor methods (headers)
+ * @details
+ * @version 0.14
+ * @date 2024-08-06
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//
+// Some of the functions are exported in the module
+//
diff --git a/hyperdbg/hyperevade/header/pch.h b/hyperdbg/hyperevade/header/pch.h
new file mode 100644
index 00000000..60a4e99b
--- /dev/null
+++ b/hyperdbg/hyperevade/header/pch.h
@@ -0,0 +1,105 @@
+/**
+ * @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_HYPEREVADE
+
+//
+// Macros
+//
+#include "macros/MetaMacros.h"
+
+//
+// Definition of Intel primitives (External header)
+//
+#include "ia32-doc/out/ia32.h"
+
+//
+// HyperDbg SDK headers
+//
+#include "SDK/HyperDbgSdk.h"
+
+//
+// Configuration
+//
+#include "config/Configuration.h"
+
+//
+// Hyperlog headers
+//
+#include "components/callback/header/HyperLogCallback.h"
+#include "SDK/imports/kernel/HyperDbgHyperLogIntrinsics.h"
+
+//
+// Platform independent headers
+//
+#include "platform/kernel/header/PlatformMem.h"
+#include "platform/kernel/header/PlatformIntrinsics.h"
+
+//
+// Hyperevade Callbacks
+//
+#include "SDK/modules/HyperEvade.h"
+
+//
+// Transparency and footprints headers
+//
+#include "Transparency.h"
+#include "VmxFootprints.h"
+#include "SyscallFootprints.h"
+
+//
+// Optimization algorithms
+//
+#include "components/optimizations/header/AvlTree.h"
+#include "components/optimizations/header/BinarySearch.h"
+#include "components/optimizations/header/InsertionSort.h"
+
+//
+// Spinlocks
+//
+#include "components/spinlock/header/Spinlock.h"
+
+//
+// Hyper-V TLFS
+//
+#include "hyper-v/HypervTlfs.h"
+
+//
+// Export functions
+//
+#include "SDK/imports/kernel/HyperDbgHyperEvade.h"
diff --git a/hyperdbg/hyperevade/hyperevade.def b/hyperdbg/hyperevade/hyperevade.def
new file mode 100644
index 00000000..ba7de297
--- /dev/null
+++ b/hyperdbg/hyperevade/hyperevade.def
@@ -0,0 +1,6 @@
+LIBRARY hyperevade
+
+EXPORTS
+
+ DllInitialize PRIVATE
+ DllUnload PRIVATE
\ No newline at end of file
diff --git a/hyperdbg/hyperevade/hyperevade.vcxproj b/hyperdbg/hyperevade/hyperevade.vcxproj
new file mode 100644
index 00000000..ea3a07dc
--- /dev/null
+++ b/hyperdbg/hyperevade/hyperevade.vcxproj
@@ -0,0 +1,144 @@
+
+
+
+
+
+
+
+ debug
+ x64
+
+
+ release
+ x64
+
+
+
+ {B226530A-14B1-40AC-B82E-D9057400E7EE}
+ {1bc93793-694f-48fe-9372-81e2b05556fd}
+ v4.5
+ 12.0
+ Debug
+ x64
+ hyperevade
+ $(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
+ hyperevade.def
+
+
+
+
+ sha256
+
+
+ $(SolutionDir)\include;$(ProjectDir)header;$(SolutionDir)dependencies;%(AdditionalIncludeDirectories)
+ true
+ Create
+ pch.h
+ stdcpp20
+ Full
+
+
+ true
+
+ true
+ hyperevade.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/hyperevade/hyperevade.vcxproj.filters b/hyperdbg/hyperevade/hyperevade.vcxproj.filters
new file mode 100644
index 00000000..f7ed48f3
--- /dev/null
+++ b/hyperdbg/hyperevade/hyperevade.vcxproj.filters
@@ -0,0 +1,105 @@
+
+
+
+
+ {8E41214B-6785-4CFE-B992-037D68949A14}
+ inf;inv;inx;mof;mc;
+
+
+ {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}
+
+
+ {890885f8-de8f-41df-9202-3ec320d7d816}
+
+
+ {a66d71db-112c-4826-8181-ba265d339149}
+
+
+ {da60b9fe-3816-4f3c-a6a9-21accd463156}
+
+
+ {0e801893-09df-4299-a572-6e63049d4f9f}
+
+
+ {78b7809e-ea12-450d-af96-8e658087628d}
+
+
+ {28025c67-f68b-437b-bcda-d23c9a752d42}
+
+
+
+
+ code
+
+
+ code
+
+
+ code\platform
+
+
+ code\components\spinlock
+
+
+ code\components\optimizations
+
+
+ code\components\optimizations
+
+
+ code\components\optimizations
+
+
+ code\components\optimizations
+
+
+ code
+
+
+ code
+
+
+ code\platform
+
+
+ code\components\callback
+
+
+
+
+ header
+
+
+ header
+
+
+ header\platform
+
+
+ header
+
+
+ header
+
+
+ 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
new file mode 100644
index 00000000..990c533c
--- /dev/null
+++ b/hyperdbg/hyperhv/CMakeLists.txt
@@ -0,0 +1,169 @@
+# Code generated by Visual Studio kit, DO NOT EDIT.
+set(SourceFiles
+ "../include/components/optimizations/code/AvlTree.c"
+ "../include/components/optimizations/code/BinarySearch.c"
+ "../include/components/optimizations/code/InsertionSort.c"
+ "../include/components/optimizations/code/OptimizationsExamples.c"
+ "../include/components/spinlock/code/Spinlock.c"
+ "../include/platform/kernel/code/PlatformMem.c"
+ "code/broadcast/Broadcast.c"
+ "code/broadcast/DpcRoutines.c"
+ "code/common/Bitwise.c"
+ "code/common/Common.c"
+ "code/common/UnloadDll.c"
+ "code/components/registers/DebugRegisters.c"
+ "code/devices/Apic.c"
+ "code/disassembler/Disassembler.c"
+ "code/disassembler/ZydisKernel.c"
+ "code/features/CompatibilityChecks.c"
+ "code/features/DirtyLogging.c"
+ "code/globals/GlobalVariableManagement.c"
+ "code/hooks/ept-hook/EptHook.c"
+ "code/hooks/ept-hook/ModeBasedExecHook.c"
+ "code/hooks/ept-hook/ExecTrap.c"
+ "code/hooks/syscall-hook/EferHook.c"
+ "code/hooks/syscall-hook/SsdtHook.c"
+ "code/interface/Callback.c"
+ "code/interface/Configuration.c"
+ "code/interface/DirectVmcall.c"
+ "code/interface/Dispatch.c"
+ "code/interface/Export.c"
+ "code/memory/AddressCheck.c"
+ "code/memory/Conversion.c"
+ "code/memory/Layout.c"
+ "code/memory/MemoryManager.c"
+ "code/memory/MemoryMapper.c"
+ "code/memory/PoolManager.c"
+ "code/memory/Segmentation.c"
+ "code/memory/SwitchLayout.c"
+ "code/transparency/Transparency.c"
+ "code/vmm/ept/Ept.c"
+ "code/vmm/ept/Invept.c"
+ "code/vmm/ept/Vpid.c"
+ "code/vmm/vmx/Counters.c"
+ "code/vmm/vmx/CrossVmexits.c"
+ "code/vmm/vmx/Events.c"
+ "code/vmm/vmx/Hv.c"
+ "code/vmm/vmx/IdtEmulation.c"
+ "code/vmm/vmx/IoHandler.c"
+ "code/vmm/vmx/ManageRegs.c"
+ "code/vmm/vmx/MsrHandlers.c"
+ "code/vmm/vmx/Mtf.c"
+ "code/vmm/vmx/ProtectedHv.c"
+ "code/vmm/vmx/Vmcall.c"
+ "code/vmm/vmx/Vmexit.c"
+ "code/vmm/vmx/Vmx.c"
+ "code/vmm/vmx/VmxBroadcast.c"
+ "code/vmm/vmx/VmxMechanisms.c"
+ "code/vmm/vmx/VmxRegions.c"
+ "code/assembly/AsmCommon.asm"
+ "code/assembly/AsmHooks.asm"
+ "code/assembly/AsmEpt.asm"
+ "code/assembly/AsmSegmentRegs.asm"
+ "code/assembly/AsmVmexitHandler.asm"
+ "code/assembly/AsmVmxContextState.asm"
+ "code/assembly/AsmVmxOperation.asm"
+ "code/assembly/AsmInterruptHandlers.asm"
+ "../dependencies/zydis/dependencies/zycore/include/Zycore/Allocator.h"
+ "../dependencies/zydis/dependencies/zycore/include/Zycore/ArgParse.h"
+ "../dependencies/zydis/dependencies/zycore/include/Zycore/Atomic.h"
+ "../dependencies/zydis/dependencies/zycore/include/Zycore/Bitset.h"
+ "../dependencies/zydis/dependencies/zycore/include/Zycore/Comparison.h"
+ "../dependencies/zydis/dependencies/zycore/include/Zycore/Defines.h"
+ "../dependencies/zydis/dependencies/zycore/include/Zycore/Format.h"
+ "../dependencies/zydis/dependencies/zycore/include/Zycore/LibC.h"
+ "../dependencies/zydis/dependencies/zycore/include/Zycore/List.h"
+ "../dependencies/zydis/dependencies/zycore/include/Zycore/Object.h"
+ "../dependencies/zydis/dependencies/zycore/include/Zycore/Status.h"
+ "../dependencies/zydis/dependencies/zycore/include/Zycore/String.h"
+ "../dependencies/zydis/dependencies/zycore/include/Zycore/Types.h"
+ "../dependencies/zydis/dependencies/zycore/include/Zycore/Vector.h"
+ "../dependencies/zydis/dependencies/zycore/include/Zycore/Zycore.h"
+ "../dependencies/zydis/include/Zydis/Decoder.h"
+ "../dependencies/zydis/include/Zydis/DecoderTypes.h"
+ "../dependencies/zydis/include/Zydis/Defines.h"
+ "../dependencies/zydis/include/Zydis/Disassembler.h"
+ "../dependencies/zydis/include/Zydis/Encoder.h"
+ "../dependencies/zydis/include/Zydis/Formatter.h"
+ "../dependencies/zydis/include/Zydis/FormatterBuffer.h"
+ "../dependencies/zydis/include/Zydis/MetaInfo.h"
+ "../dependencies/zydis/include/Zydis/Mnemonic.h"
+ "../dependencies/zydis/include/Zydis/Register.h"
+ "../dependencies/zydis/include/Zydis/Segment.h"
+ "../dependencies/zydis/include/Zydis/SharedTypes.h"
+ "../dependencies/zydis/include/Zydis/ShortString.h"
+ "../dependencies/zydis/include/Zydis/Status.h"
+ "../dependencies/zydis/include/Zydis/Utils.h"
+ "../dependencies/zydis/include/Zydis/Zydis.h"
+ "../include/components/optimizations/header/AvlTree.h"
+ "../include/components/optimizations/header/BinarySearch.h"
+ "../include/components/optimizations/header/InsertionSort.h"
+ "../include/components/optimizations/header/OptimizationsExamples.h"
+ "../include/components/spinlock/header/Spinlock.h"
+ "../include/macros/MetaMacros.h"
+ "../include/platform/kernel/header/Environment.h"
+ "../include/platform/kernel/header/PlatformMem.h"
+ "header/assembly/InlineAsm.h"
+ "header/broadcast/Broadcast.h"
+ "header/broadcast/DpcRoutines.h"
+ "header/common/Bitwise.h"
+ "header/common/Common.h"
+ "header/common/Dpc.h"
+ "header/common/Msr.h"
+ "header/common/State.h"
+ "header/common/Trace.h"
+ "header/common/UnloadDll.h"
+ "header/devices/Apic.h"
+ "header/disassembler/Disassembler.h"
+ "header/features/CompatibilityChecks.h"
+ "header/features/DirtyLogging.h"
+ "header/globals/GlobalVariableManagement.h"
+ "header/globals/GlobalVariables.h"
+ "header/hooks/Hooks.h"
+ "header/hooks/ModeBasedExecHook.h"
+ "header/hooks/ExecTrap.h"
+ "header/interface/Callback.h"
+ "header/interface/DirectVmcall.h"
+ "header/interface/Dispatch.h"
+ "header/memory/AddressCheck.h"
+ "header/memory/Conversion.h"
+ "header/memory/Layout.h"
+ "header/memory/MemoryMapper.h"
+ "header/memory/PoolManager.h"
+ "header/memory/Segmentation.h"
+ "header/memory/SwitchLayout.h"
+ "header/transparency/Transparency.h"
+ "header/vmm/ept/Ept.h"
+ "header/vmm/ept/Invept.h"
+ "header/vmm/ept/Vpid.h"
+ "header/vmm/vmx/Counters.h"
+ "header/vmm/vmx/Events.h"
+ "header/vmm/vmx/Hv.h"
+ "header/vmm/vmx/HypervTlfs.h"
+ "header/vmm/vmx/IdtEmulation.h"
+ "header/vmm/vmx/IoHandler.h"
+ "header/vmm/vmx/MsrHandlers.h"
+ "header/vmm/vmx/Mtf.h"
+ "header/vmm/vmx/ProtectedHv.h"
+ "header/vmm/vmx/Vmcall.h"
+ "header/vmm/vmx/Vmx.h"
+ "header/vmm/vmx/VmxBroadcast.h"
+ "header/vmm/vmx/VmxMechanisms.h"
+ "header/vmm/vmx/VmxRegions.h"
+ "pch.h"
+ "hyperhv.def"
+)
+include_directories(
+ "../include"
+ "header"
+ "code"
+ "."
+ "../dependencies"
+ "../script-eval"
+ "../dependencies/zydis/include"
+ "../dependencies/zydis/dependencies/zycore/include"
+)
+wdk_add_library(hyperhv SHARED
+ KMDF 1.15
+ ${SourceFiles}
+)
diff --git a/hyperdbg/hprdbghv/code/assembly/AsmCommon.asm b/hyperdbg/hyperhv/code/assembly/AsmCommon.asm
similarity index 80%
rename from hyperdbg/hprdbghv/code/assembly/AsmCommon.asm
rename to hyperdbg/hyperhv/code/assembly/AsmCommon.asm
index 58b0b711..785e8047 100644
--- a/hyperdbg/hprdbghv/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/hprdbghv/code/assembly/AsmEpt.asm b/hyperdbg/hyperhv/code/assembly/AsmEpt.asm
similarity index 100%
rename from hyperdbg/hprdbghv/code/assembly/AsmEpt.asm
rename to hyperdbg/hyperhv/code/assembly/AsmEpt.asm
diff --git a/hyperdbg/hprdbghv/code/assembly/AsmHooks.asm b/hyperdbg/hyperhv/code/assembly/AsmHooks.asm
similarity index 100%
rename from hyperdbg/hprdbghv/code/assembly/AsmHooks.asm
rename to hyperdbg/hyperhv/code/assembly/AsmHooks.asm
diff --git a/hyperdbg/hyperhv/code/assembly/AsmInterruptHandlers.asm b/hyperdbg/hyperhv/code/assembly/AsmInterruptHandlers.asm
new file mode 100644
index 00000000..de1cee3c
--- /dev/null
+++ b/hyperdbg/hyperhv/code/assembly/AsmInterruptHandlers.asm
@@ -0,0 +1,153 @@
+; This file was copied and modified from: https://github.com/jonomango/hv/blob/main/hv/interrupt-handlers.asm
+
+EXTERN IdtEmulationhandleHostInterrupt:PROC
+
+.code _text
+
+;------------------------------------------------------------------------
+
+; defined in IdtEmulation.h
+trap_frame struct
+ ; general-purpose registers
+ $rax qword ?
+ $rcx qword ?
+ $rdx qword ?
+ $rbx qword ?
+ $rbp qword ?
+ $rsi qword ?
+ $rdi qword ?
+ $r8 qword ?
+ $r9 qword ?
+ $r10 qword ?
+ $r11 qword ?
+ $r12 qword ?
+ $r13 qword ?
+ $r14 qword ?
+ $r15 qword ?
+
+ ; interrupt vector
+ $vector qword ?
+
+ ; _MACHINE_FRAME
+ $error qword ?
+ $rip qword ?
+ $cs qword ?
+ $rflags qword ?
+ $rsp qword ?
+ $ss qword ?
+trap_frame ends
+
+;------------------------------------------------------------------------
+
+; the generic interrupt handler that every stub will eventually jump to
+GenericInterruptHandler proc
+ ; allocate space for the trap_frame structure (minus the size of the
+ ; _MACHINE_FRAME, error code, and interrupt vector)
+ sub rsp, 78h
+
+ ; general-purpose registers
+ mov trap_frame.$rax[rsp], rax
+ mov trap_frame.$rcx[rsp], rcx
+ mov trap_frame.$rdx[rsp], rdx
+ mov trap_frame.$rbx[rsp], rbx
+ mov trap_frame.$rbp[rsp], rbp
+ mov trap_frame.$rsi[rsp], rsi
+ mov trap_frame.$rdi[rsp], rdi
+ mov trap_frame.$r8[rsp], r8
+ mov trap_frame.$r9[rsp], r9
+ mov trap_frame.$r10[rsp], r10
+ mov trap_frame.$r11[rsp], r11
+ mov trap_frame.$r12[rsp], r12
+ mov trap_frame.$r13[rsp], r13
+ mov trap_frame.$r14[rsp], r14
+ mov trap_frame.$r15[rsp], r15
+
+ ; first argument is the trap frame
+ mov rcx, rsp
+
+ ; call IdtEmulationhandleHostInterrupt
+ sub rsp, 20h
+ call IdtEmulationhandleHostInterrupt
+ add rsp, 20h
+
+ ; general-purpose registers
+ mov rax, trap_frame.$rax[rsp]
+ mov rcx, trap_frame.$rcx[rsp]
+ mov rdx, trap_frame.$rdx[rsp]
+ mov rbx, trap_frame.$rbx[rsp]
+ mov rbp, trap_frame.$rbp[rsp]
+ mov rsi, trap_frame.$rsi[rsp]
+ mov rdi, trap_frame.$rdi[rsp]
+ mov r8, trap_frame.$r8[rsp]
+ mov r9, trap_frame.$r9[rsp]
+ mov r10, trap_frame.$r10[rsp]
+ mov r11, trap_frame.$r11[rsp]
+ mov r12, trap_frame.$r12[rsp]
+ mov r13, trap_frame.$r13[rsp]
+ mov r14, trap_frame.$r14[rsp]
+ mov r15, trap_frame.$r15[rsp]
+
+ ; free the trap_frame
+ add rsp, 78h
+
+ ; pop the interrupt vector
+ add rsp, 8
+
+ ; pop the error code
+ add rsp, 8
+
+ iretq
+
+GenericInterruptHandler endp
+
+;------------------------------------------------------------------------
+
+; pushes error code to stack
+DEFINE_ISR macro InterruptVector:req, ProcName:req
+ProcName proc
+ ; interrupt vector is stored right before the machine frame
+ push InterruptVector
+
+ jmp GenericInterruptHandler
+ProcName endp
+endm
+
+; doesn't push error code to stack
+DEFINE_ISR_NO_ERROR macro InterruptVector:req, ProcName:req
+ProcName proc
+ ; push a dummy error code onto the stack
+ push 0
+
+ ; interrupt vector is stored right before the machine frame
+ push InterruptVector
+
+ jmp GenericInterruptHandler
+ProcName endp
+endm
+
+;------------------------------------------------------------------------
+
+DEFINE_ISR_NO_ERROR 0, InterruptHandler0
+DEFINE_ISR_NO_ERROR 1, InterruptHandler1
+DEFINE_ISR_NO_ERROR 2, InterruptHandler2
+DEFINE_ISR_NO_ERROR 3, InterruptHandler3
+DEFINE_ISR_NO_ERROR 4, InterruptHandler4
+DEFINE_ISR_NO_ERROR 5, InterruptHandler5
+DEFINE_ISR_NO_ERROR 6, InterruptHandler6
+DEFINE_ISR_NO_ERROR 7, InterruptHandler7
+DEFINE_ISR 8, InterruptHandler8
+DEFINE_ISR 10, InterruptHandler10
+DEFINE_ISR 11, InterruptHandler11
+DEFINE_ISR 12, InterruptHandler12
+DEFINE_ISR 13, InterruptHandler13
+DEFINE_ISR 14, InterruptHandler14
+DEFINE_ISR_NO_ERROR 16, InterruptHandler16
+DEFINE_ISR 17, InterruptHandler17
+DEFINE_ISR_NO_ERROR 18, InterruptHandler18
+DEFINE_ISR_NO_ERROR 19, InterruptHandler19
+DEFINE_ISR_NO_ERROR 20, InterruptHandler20
+DEFINE_ISR 30, InterruptHandler30
+
+;------------------------------------------------------------------------
+
+end
\ No newline at end of file
diff --git a/hyperdbg/hprdbghv/code/assembly/AsmSegmentRegs.asm b/hyperdbg/hyperhv/code/assembly/AsmSegmentRegs.asm
similarity index 77%
rename from hyperdbg/hprdbghv/code/assembly/AsmSegmentRegs.asm
rename to hyperdbg/hyperhv/code/assembly/AsmSegmentRegs.asm
index a61eaf4c..cb1c7f11 100644
--- a/hyperdbg/hprdbghv/code/assembly/AsmSegmentRegs.asm
+++ b/hyperdbg/hyperhv/code/assembly/AsmSegmentRegs.asm
@@ -1,8 +1,12 @@
PUBLIC AsmGetCs
PUBLIC AsmGetDs
+PUBLIC AsmSetDs
PUBLIC AsmGetEs
+PUBLIC AsmSetEs
PUBLIC AsmGetSs
+PUBLIC AsmSetSs
PUBLIC AsmGetFs
+PUBLIC AsmSetFs
PUBLIC AsmGetGs
PUBLIC AsmGetLdtr
PUBLIC AsmGetTr
@@ -44,6 +48,16 @@ AsmGetDs ENDP
;------------------------------------------------------------------------
+AsmSetDs PROC
+
+ mov rax, rcx
+ mov ds, rax
+ ret
+
+AsmSetDs ENDP
+
+;------------------------------------------------------------------------
+
AsmGetEs PROC
mov rax, es
@@ -53,6 +67,16 @@ AsmGetEs ENDP
;------------------------------------------------------------------------
+AsmSetEs PROC
+
+ mov rax, rcx
+ mov es, rax
+ ret
+
+AsmSetEs ENDP
+
+;------------------------------------------------------------------------
+
AsmGetSs PROC
mov rax, ss
@@ -62,6 +86,16 @@ AsmGetSs ENDP
;------------------------------------------------------------------------
+AsmSetSs PROC
+
+ mov rax, rcx
+ mov ss, rax
+ ret
+
+AsmSetSs ENDP
+
+;------------------------------------------------------------------------
+
AsmGetFs PROC
mov rax, fs
@@ -71,6 +105,16 @@ AsmGetFs ENDP
;------------------------------------------------------------------------
+AsmSetFs PROC
+
+ mov rax, rcx
+ mov fs, rax
+ ret
+
+AsmSetFs ENDP
+
+;------------------------------------------------------------------------
+
AsmGetGs PROC
mov rax, gs
diff --git a/hyperdbg/hyperhv/code/assembly/AsmVmexitHandler.asm b/hyperdbg/hyperhv/code/assembly/AsmVmexitHandler.asm
new file mode 100644
index 00000000..54476abd
--- /dev/null
+++ b/hyperdbg/hyperhv/code/assembly/AsmVmexitHandler.asm
@@ -0,0 +1,244 @@
+PUBLIC AsmVmexitHandler
+PUBLIC AsmVmxoffRestoreXmmRegs
+
+EXTERN VmxVmexitHandler:PROC
+EXTERN VmxPerformVmresume:PROC
+EXTERN VmxReturnStackPointerForVmxoff:PROC
+EXTERN VmxReturnInstructionPointerForVmxoff:PROC
+
+.code _text
+
+;------------------------------------------------------------------------
+
+AsmVmexitHandler PROC
+
+ push 0 ; we might be in an unaligned stack state, so the memory before stack might cause
+ ; irql less or equal as it doesn't exist, so we just put some extra space avoid
+ ; these kind of errors
+
+ ; --------------- 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
+
+ ;
+ ; 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+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
+ push r13
+ push r12
+ push r11
+ push r10
+ push r9
+ push r8
+ push rdi
+ push rsi
+ push rbp
+ push rbp ; rsp
+ push rbx
+ 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)
+
+ je AsmVmxoffHandler
+
+ ; ----------- Restore XMM Registers ----------
+
+RestoreState:
+
+ pop rax
+ pop rcx
+ pop rdx
+ pop rbx
+ pop rbp ; rsp
+ pop rbp
+ pop rsi
+ pop rdi
+ pop r8
+ pop r9
+ pop r10
+ pop r11
+ pop r12
+ pop r13
+ 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]
+
+ ;
+ ; 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 [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)
+
+ ; ----------------------------------------------
+
+ 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
+
+ ; ------ Restore General-purpose Registers ------
+
+RestoreState:
+
+ pop rax
+ pop rcx
+ pop rdx
+ pop rbx
+ pop rbp ; rsp
+ pop rbp
+ pop rsi
+ pop rdi
+ pop r8
+ pop r9
+ pop r10
+ pop r11
+ pop r12
+ pop r13
+ pop r14
+ pop r15
+
+ ; ------------- 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
+
+ ; ----------------------------------------------
+
+ ; 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
+
+ xor rax, rax ; clear RAX to indicate VMXOFF was successful (VMCALL Status)
+
+ ret ; jump back to where we called Vmcall
+
+AsmVmxoffHandler ENDP
+
+;------------------------------------------------------------------------
+
+END
diff --git a/hyperdbg/hprdbghv/code/assembly/AsmVmxContextState.asm b/hyperdbg/hyperhv/code/assembly/AsmVmxContextState.asm
similarity index 100%
rename from hyperdbg/hprdbghv/code/assembly/AsmVmxContextState.asm
rename to hyperdbg/hyperhv/code/assembly/AsmVmxContextState.asm
diff --git a/hyperdbg/hprdbghv/code/assembly/AsmVmxOperation.asm b/hyperdbg/hyperhv/code/assembly/AsmVmxOperation.asm
similarity index 100%
rename from hyperdbg/hprdbghv/code/assembly/AsmVmxOperation.asm
rename to hyperdbg/hyperhv/code/assembly/AsmVmxOperation.asm
diff --git a/hyperdbg/hprdbghv/code/broadcast/Broadcast.c b/hyperdbg/hyperhv/code/broadcast/Broadcast.c
similarity index 100%
rename from hyperdbg/hprdbghv/code/broadcast/Broadcast.c
rename to hyperdbg/hyperhv/code/broadcast/Broadcast.c
diff --git a/hyperdbg/hprdbghv/code/broadcast/DpcRoutines.c b/hyperdbg/hyperhv/code/broadcast/DpcRoutines.c
similarity index 78%
rename from hyperdbg/hprdbghv/code/broadcast/DpcRoutines.c
rename to hyperdbg/hyperhv/code/broadcast/DpcRoutines.c
index 984ec8b9..0f1e491d 100644
--- a/hyperdbg/hprdbghv/code/broadcast/DpcRoutines.c
+++ b/hyperdbg/hyperhv/code/broadcast/DpcRoutines.c
@@ -50,7 +50,7 @@ DpcRoutineRunTaskOnSingleCore(UINT32 CoreNumber, PVOID Routine, PVOID DeferredCo
//
// Allocate Memory for DPC
//
- Dpc = CrsAllocateNonPagedPool(sizeof(KDPC));
+ Dpc = PlatformMemAllocateNonPagedPool(sizeof(KDPC));
if (!Dpc)
{
@@ -91,7 +91,7 @@ DpcRoutineRunTaskOnSingleCore(UINT32 CoreNumber, PVOID Routine, PVOID DeferredCo
//
// We can't get the lock, probably sth goes wrong !
//
- CrsFreePool(Dpc);
+ PlatformMemFreePool(Dpc);
return STATUS_UNSUCCESSFUL;
}
@@ -110,7 +110,7 @@ DpcRoutineRunTaskOnSingleCore(UINT32 CoreNumber, PVOID Routine, PVOID DeferredCo
//
// Now it's safe to deallocate the bugger
//
- CrsFreePool(Dpc);
+ PlatformMemFreePool(Dpc);
return STATUS_SUCCESS;
}
@@ -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/hprdbghv/code/common/Bitwise.c b/hyperdbg/hyperhv/code/common/Bitwise.c
similarity index 54%
rename from hyperdbg/hprdbghv/code/common/Bitwise.c
rename to hyperdbg/hyperhv/code/common/Bitwise.c
index 1d0976a9..cb844856 100644
--- a/hyperdbg/hprdbghv/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/hprdbghv/code/common/Common.c b/hyperdbg/hyperhv/code/common/Common.c
similarity index 71%
rename from hyperdbg/hprdbghv/code/common/Common.c
rename to hyperdbg/hyperhv/code/common/Common.c
index dba45cfb..9eac49d3 100644
--- a/hyperdbg/hprdbghv/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);
}
@@ -191,3 +191,62 @@ CommonWriteDebugInformation(VIRTUAL_MACHINE_STATE * VCpu)
VCpu->Regs->r14,
VCpu->Regs->r15);
}
+
+/**
+ * @brief Check correctness of the XCR0 register value.
+ * @param XCr0 The XCR0 register value.
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+CommonIsXCr0Valid(XCR0 XCr0)
+{
+ CPUID_EAX_0D_ECX_00 XCr0CpuidInfo;
+ UINT64 UnsupportedXCr0Bits;
+
+ //
+ // SDM Vol.3A 2.6 EXTENDED CONTROL REGISTERS (INCLUDING XCR0) - describes the invalid
+ // states of the XCR0 register.
+ //
+
+ CommonCpuidInstruction(CPUID_EXTENDED_STATE_INFORMATION, 0, (INT32 *)&XCr0CpuidInfo);
+ UnsupportedXCr0Bits = ~(XCr0CpuidInfo.Eax.AsUInt | (UINT64)XCr0CpuidInfo.Edx.AsUInt << 32);
+
+ if ((XCr0.AsUInt & UnsupportedXCr0Bits) != 0)
+ {
+ return FALSE;
+ }
+
+ if (XCr0.X87 != 1)
+ {
+ return FALSE;
+ }
+
+ if (XCr0.Sse == 0 && XCr0.Avx == 1)
+ {
+ return FALSE;
+ }
+
+ if (XCr0.Avx == 0)
+ {
+ if ((XCr0.Opmask | XCr0.ZmmHi256 | XCr0.ZmmHi16) == 1)
+ {
+ return FALSE;
+ }
+ }
+
+ if (XCr0.Bndcsr != XCr0.Bndreg)
+ {
+ return FALSE;
+ }
+
+ if ((XCr0.Opmask | XCr0.ZmmHi256 | XCr0.ZmmHi16) == 1)
+ {
+ if ((XCr0.Opmask & XCr0.ZmmHi256 & XCr0.ZmmHi16) != 1)
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
diff --git a/hyperdbg/hprdbghv/code/common/UnloadDll.c b/hyperdbg/hyperhv/code/common/UnloadDll.c
similarity index 100%
rename from hyperdbg/hprdbghv/code/common/UnloadDll.c
rename to hyperdbg/hyperhv/code/common/UnloadDll.c
diff --git a/hyperdbg/hprdbghv/code/components/registers/DebugRegisters.c b/hyperdbg/hyperhv/code/components/registers/DebugRegisters.c
similarity index 97%
rename from hyperdbg/hprdbghv/code/components/registers/DebugRegisters.c
rename to hyperdbg/hyperhv/code/components/registers/DebugRegisters.c
index c12aacf5..85f7b45a 100644
--- a/hyperdbg/hprdbghv/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
new file mode 100644
index 00000000..c1cb2863
--- /dev/null
+++ b/hyperdbg/hyperhv/code/devices/Apic.c
@@ -0,0 +1,468 @@
+/**
+ * @file Apic.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Routines for Advanced Programmable Interrupt Controller (APIC)
+ * @details The code is derived from (https://www.cpl0.com/blog/?p=46) and the code
+ * for showing the APIC details in the XAPIC is derived from bitdefender/napoca project
+ * which is enhanced to support X2APIC mode in HyperDbg
+ *
+ * @version 0.1
+ * @date 2020-12-31
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief Perform read I/O APIC
+ *
+ * @param IoApicBaseVa
+ * @param Reg
+ *
+ * @return UINT64
+ */
+UINT64
+IoApicRead(volatile IO_APIC_ENT * IoApicBaseVa, UINT32 Reg)
+{
+ UINT32 High = 0, Low;
+
+ IoApicBaseVa->Reg = Reg;
+ Low = IoApicBaseVa->Data;
+
+ if (Reg >= IOAPIC_REDTBL(0) && Reg < IOAPIC_REDTBL(IOAPIC_REDTBL_MAX))
+ {
+ // ASSERT(Reg % 2 == 0);
+ Reg++;
+ IoApicBaseVa->Reg = Reg;
+ High = IoApicBaseVa->Data;
+ return IOAPIC_APPEND_QWORD(High, Low);
+ }
+ else
+ {
+ return Low;
+ }
+}
+
+/**
+ * @brief Perform write to I/O APIC
+ *
+ * @param IoApicBaseVa
+ * @param Reg
+ * @param Data
+ *
+ * @return VOID
+ */
+VOID
+IoApicWrite(volatile IO_APIC_ENT * IoApicBaseVa, UINT32 Reg, UINT64 Data)
+{
+ IoApicBaseVa->Reg = Reg;
+ IoApicBaseVa->Data = IOAPIC_LOW_DWORD(Data);
+
+ if (Reg >= IOAPIC_REDTBL(0) && Reg < IOAPIC_REDTBL(IOAPIC_REDTBL_MAX))
+ {
+ // ASSERT(Reg % 2 == 0);
+ Reg++;
+ IoApicBaseVa->Reg = Reg;
+ IoApicBaseVa->Data = IOAPIC_HIGH_DWORD(Data);
+ }
+}
+
+/**
+ * @brief Dump I/O APIC
+ * @param IoApicPackets
+ *
+ * @return VOID
+ */
+VOID
+ApicDumpIoApic(IO_APIC_ENTRY_PACKETS * IoApicPackets)
+{
+ UINT32 Index = 0;
+ UINT32 Max;
+ UINT64 Ll, Lh;
+
+ UINT64 ApicBasePa = IO_APIC_DEFAULT_BASE_ADDR;
+
+ Ll = IoApicRead(g_IoApicBase, IO_VERS_REGISTER),
+
+ Max = (Ll >> 16) & 0xff;
+
+ // Log("IoApic @ %08x ID:%x (%x) Arb:%x\n",
+ // ApicBasePa,
+ // IoApicRead(g_IoApicBase, IO_ID_REGISTER) >> 24,
+ // Ll & 0xFF,
+ // IoApicRead(g_IoApicBase, IO_ARB_ID_REGISTER));
+
+ //
+ // Fill the I/O APIC
+ //
+ IoApicPackets->ApicBasePa = (UINT32)ApicBasePa;
+ IoApicPackets->ApicBaseVa = (UINT64)g_IoApicBase;
+ IoApicPackets->IoIdReg = (UINT32)IoApicRead(g_IoApicBase, IO_ID_REGISTER);
+ IoApicPackets->IoLl = (UINT32)Ll;
+ IoApicPackets->IoArbIdReg = (UINT32)IoApicRead(g_IoApicBase, IO_ARB_ID_REGISTER);
+
+ //
+ // Dump inti table
+ //
+ Max *= 2;
+
+ for (Index = 0; Index <= Max; Index += 2)
+ {
+ if (Index >= MAX_NUMBER_OF_IO_APIC_ENTRIES)
+ {
+ //
+ // To prevent overflow of the target buffer
+ //
+ return;
+ }
+
+ 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;
+ }
+}
+
+/**
+ * @brief Trigger NMI on XAPIC
+ * @param Low
+ * @param High
+ *
+ * @return VOID
+ */
+VOID
+XApicIcrWrite(UINT32 Low, UINT32 High)
+{
+ *(UINT32 *)((uintptr_t)g_ApicBase + ICROffset + 0x10) = High;
+ *(UINT32 *)((uintptr_t)g_ApicBase + ICROffset) = Low;
+}
+
+/**
+ * @brief Trigger NMI on X2APIC
+ * @param Low
+ * @param High
+ *
+ * @return VOID
+ */
+VOID
+X2ApicIcrWrite(UINT32 Low, UINT32 High)
+{
+ CpuWriteMsr(X2_MSR_BASE + TO_X2(ICROffset), ((UINT64)High << 32) | Low);
+}
+
+/**
+ * @brief Read x2APIC mode
+ * @param Offset
+ *
+ * @return UINT64
+ */
+UINT64
+X2ApicRead(UINT32 Offset)
+{
+ return CpuReadMsr(X2_MSR_BASE + TO_X2(Offset));
+}
+
+/**
+ * @brief Store the local APIC in XAPIC mode
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+ApicStoretLocalApicInXApicMode(PLAPIC_PAGE LApicBuffer)
+{
+ volatile LAPIC_PAGE * LocalApicVa = g_ApicBase;
+
+ //
+ // Check if the base virtual address of local APIC is valid or not
+ //
+ if (!g_ApicBase)
+ {
+ return FALSE;
+ }
+
+ //
+ // Store fields
+ //
+ LApicBuffer->Id = LocalApicVa->Id;
+ LApicBuffer->Version = LocalApicVa->Version;
+ LApicBuffer->SpuriousInterruptVector = LocalApicVa->SpuriousInterruptVector;
+ LApicBuffer->TPR = LocalApicVa->TPR;
+ LApicBuffer->ProcessorPriority = LocalApicVa->ProcessorPriority;
+ LApicBuffer->LogicalDestination = LocalApicVa->LogicalDestination;
+ LApicBuffer->ErrorStatus = LocalApicVa->ErrorStatus;
+ LApicBuffer->LvtLINT0 = LocalApicVa->LvtLINT0;
+ LApicBuffer->LvtLINT1 = LocalApicVa->LvtLINT1;
+ LApicBuffer->LvtCmci = LocalApicVa->LvtCmci;
+ LApicBuffer->LvtPerfMonCounters = LocalApicVa->LvtPerfMonCounters;
+ LApicBuffer->LvtTimer = LocalApicVa->LvtTimer;
+ LApicBuffer->LvtThermalSensor = LocalApicVa->LvtThermalSensor;
+ LApicBuffer->LvtError = LocalApicVa->LvtError;
+ LApicBuffer->InitialCount = LocalApicVa->InitialCount;
+ LApicBuffer->CurrentCount = LocalApicVa->CurrentCount;
+ LApicBuffer->DivideConfiguration = LocalApicVa->DivideConfiguration;
+
+ //
+ // Save the ISR, TMR and IRR
+ //
+ for (UINT32 i = 0; i < 8; i++)
+ {
+ LApicBuffer->ISR[i * 4] = LocalApicVa->ISR[i * 4];
+ }
+
+ for (UINT32 i = 0; i < 8; i++)
+ {
+ LApicBuffer->TMR[i * 4] = LocalApicVa->TMR[i * 4];
+ }
+
+ for (UINT32 i = 0; i < 8; i++)
+ {
+ LApicBuffer->IRR[i * 4] = LocalApicVa->IRR[i * 4];
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Store the local APIC in X2APIC mode
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+ApicStoreLocalApicInX2ApicMode(PLAPIC_PAGE LApicBuffer)
+{
+ //
+ // Store fields
+ //
+ LApicBuffer->Id = (UINT32)X2ApicRead(APIC_ID);
+ LApicBuffer->Version = (UINT32)X2ApicRead(APIC_VERSION);
+ LApicBuffer->SpuriousInterruptVector = (UINT32)X2ApicRead(APIC_SPURIOUS_INTERRUPT_VECTOR);
+ LApicBuffer->TPR = (UINT32)X2ApicRead(APIC_TASK_PRIORITY);
+ LApicBuffer->ProcessorPriority = (UINT32)X2ApicRead(APIC_PROCESSOR_PRIORITY);
+ LApicBuffer->LogicalDestination = (UINT32)X2ApicRead(APIC_LOGICAL_DESTINATION);
+ LApicBuffer->ErrorStatus = (UINT32)X2ApicRead(APIC_ERROR_STATUS);
+ LApicBuffer->LvtLINT0 = (UINT32)X2ApicRead(APIC_LVT_LINT0);
+ LApicBuffer->LvtLINT1 = (UINT32)X2ApicRead(APIC_LVT_LINT1);
+ LApicBuffer->LvtCmci = (UINT32)X2ApicRead(APIC_LVT_CORRECTED_MACHINE_CHECK_INTERRUPT);
+ LApicBuffer->LvtPerfMonCounters = (UINT32)X2ApicRead(APIC_LVT_PERFORMANCE_MONITORING_COUNTERS);
+ LApicBuffer->LvtTimer = (UINT32)X2ApicRead(APIC_LVT_TIMER);
+ LApicBuffer->LvtThermalSensor = (UINT32)X2ApicRead(APIC_LVT_THERMAL_SENSOR);
+ LApicBuffer->LvtError = (UINT32)X2ApicRead(APIC_LVT_ERROR);
+ LApicBuffer->InitialCount = (UINT32)X2ApicRead(APIC_INITIAL_COUNT);
+ LApicBuffer->CurrentCount = (UINT32)X2ApicRead(APIC_CURRENT_COUNT);
+ LApicBuffer->DivideConfiguration = (UINT32)X2ApicRead(APIC_DIVIDE_CONFIGURATION);
+
+ //
+ // Save the ISR, TMR and IRR
+ //
+ for (UINT32 i = 0; i < 8; i++)
+ {
+ LApicBuffer->ISR[i * 4] = (UINT32)X2ApicRead(APIC_IN_SERVICE_BITS_31_0 + (0x10 * i));
+ }
+
+ for (UINT32 i = 0; i < 8; i++)
+ {
+ LApicBuffer->TMR[i * 4] = (UINT32)X2ApicRead(APIC_TRIGGER_MODE_BITS_31_0 + (0x10 * i));
+ }
+
+ for (UINT32 i = 0; i < 8; i++)
+ {
+ LApicBuffer->IRR[i * 4] = (UINT32)X2ApicRead(APIC_INTERRUPT_REQUEST_BITS_31_0 + (0x10 * i));
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Trigger NMI on X2APIC or APIC based on Current system
+ *
+ * @return VOID
+ */
+VOID
+ApicTriggerGenericNmi()
+{
+ if (g_CompatibilityCheck.IsX2Apic)
+ {
+ X2ApicIcrWrite((4 << 8) | (1 << 14) | (3 << 18), 0);
+ }
+ else
+ {
+ XApicIcrWrite((4 << 8) | (1 << 14) | (3 << 18), 0);
+ }
+}
+
+/**
+ * @brief Trigger NMI on X2APIC or APIC based on Current system
+ *
+ * @return VOID
+ */
+VOID
+ApicTriggerGenericSmi()
+{
+ LogInfo("Generating SMIs");
+ if (g_CompatibilityCheck.IsX2Apic)
+ {
+ // X2ApicIcrWrite((4 << 8) | (1 << 14) | (3 << 18), 0);
+ X2ApicIcrWrite((2 << 8) | (1 << 14) | (3 << 18), 0);
+ }
+ else
+ {
+ // XApicIcrWrite((4 << 8) | (1 << 14) | (3 << 18), 0);
+ XApicIcrWrite((2 << 8) | (1 << 14) | (3 << 18), 0);
+ }
+}
+
+/**
+ * @brief Store the details of APIC in xAPIC and x2APIC mode
+ * @param LApicBuffer
+ * @param IsUsingX2APIC
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+ApicStoreLocalApicFields(PLAPIC_PAGE LApicBuffer, PBOOLEAN IsUsingX2APIC)
+{
+ if (g_CompatibilityCheck.IsX2Apic)
+ {
+ *IsUsingX2APIC = TRUE;
+ return ApicStoreLocalApicInX2ApicMode(LApicBuffer);
+ }
+ else
+ {
+ *IsUsingX2APIC = FALSE;
+ return ApicStoretLocalApicInXApicMode(LApicBuffer);
+ }
+}
+
+/**
+ * @brief Store the details of I/O APIC
+ * @param IoApicPackets
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+ApicStoreIoApicFields(IO_APIC_ENTRY_PACKETS * IoApicPackets)
+{
+ //
+ // Dump I/O APIC Entries
+ // Note that I/O APIC is not accessed through MSRs (e.g., X2APIC)
+ // So, it's all about the physical memory
+ //
+ ApicDumpIoApic(IoApicPackets);
+
+ //
+ // There is not error defined for it at the moment
+ //
+ return TRUE;
+}
+
+/**
+ * @brief Initialize APIC
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+ApicInitialize()
+{
+ UINT64 ApicBaseMSR;
+ PHYSICAL_ADDRESS PaApicBase;
+ PHYSICAL_ADDRESS PaIoApicBase;
+
+ ApicBaseMSR = CpuReadMsr(IA32_APIC_BASE);
+
+ if (!(ApicBaseMSR & (1 << 11)))
+ {
+ return FALSE;
+ }
+
+ //
+ // Map I/O APIC default base address
+ //
+ // The exact APIC base address should be read from MADT table (ACPI)
+ // However, we don't have an ACPI parser right now, but the address
+ // is proved to stay at this (default) physical address since Intel
+ // recommends OS/BIOS to not relocate it, but it could be relocated
+ // however, this address is valid for almost all of the systems
+ //
+ PaIoApicBase.QuadPart = IO_APIC_DEFAULT_BASE_ADDR & 0xFFFFFF000;
+ g_IoApicBase = MmMapIoSpace(PaIoApicBase, 0x1000, MmNonCached);
+
+ if (!g_IoApicBase)
+ {
+ //
+ // Not gonna fail the initialization since the IOAPIC might be relocated by
+ // either OS/BIOS
+ //
+
+ // return FALSE;
+ }
+
+ if (ApicBaseMSR & (1 << 10))
+ {
+ g_CompatibilityCheck.IsX2Apic = TRUE;
+
+ return FALSE;
+ }
+ else
+ {
+ PaApicBase.QuadPart = ApicBaseMSR & 0xFFFFFF000;
+ g_ApicBase = MmMapIoSpace(PaApicBase, 0x1000, MmNonCached);
+
+ if (!g_ApicBase)
+ {
+ return FALSE;
+ }
+
+ g_CompatibilityCheck.IsX2Apic = FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Uninitialize APIC
+ *
+ * @return VOID
+ */
+VOID
+ApicUninitialize()
+{
+ //
+ // Unmap Local APIC base
+ //
+ if (g_ApicBase)
+ {
+ MmUnmapIoSpace(g_ApicBase, 0x1000);
+ }
+
+ //
+ // Unmap I/O APIC base
+ //
+ if (g_IoApicBase)
+ {
+ MmUnmapIoSpace(g_IoApicBase, 0x1000);
+ }
+}
+
+/**
+ * @brief Self IPI the current core
+ *
+ * @param Vector
+ * @return VOID
+ */
+VOID
+ApicSelfIpi(UINT32 Vector)
+{
+ //
+ // Check and apply self-IPI to x2APIC and xAPIC
+ //
+ if (g_CompatibilityCheck.IsX2Apic)
+ {
+ X2ApicIcrWrite(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_FIXED | Vector, 0);
+ }
+ else
+ {
+ XApicIcrWrite(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_FIXED | Vector, 0);
+ }
+}
diff --git a/hyperdbg/hyperhv/code/devices/Pci.c b/hyperdbg/hyperhv/code/devices/Pci.c
new file mode 100644
index 00000000..adcd1677
--- /dev/null
+++ b/hyperdbg/hyperhv/code/devices/Pci.c
@@ -0,0 +1,118 @@
+/**
+ * @file Pci.c
+ * @author Bjrn Ruytenberg (bjorn@bjornweb.nl)
+ * @brief Routines for interacting with PCI(e) fabric
+ * @details
+ * @version 0.10.3
+ * @date 2024-11-11
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief Read from PCI configuration space (CAM) at given offset
+ * @param Bus
+ * @param Device
+ * @param Function
+ * @param Offset
+ * @param Width Number of bytes to return. Supported data types: BYTE (1), WORD (2), DWORD (4), QWORD (8).
+ *
+ * @return QWORD
+ */
+QWORD
+PciReadCam(WORD Bus, WORD Device, WORD Function, BYTE Offset, UINT8 Width)
+{
+ WORD Target = 0;
+
+ //
+ // Restrict Offset to CAM address space; restrict BDF to our internal limits
+ //
+ if (Offset > CAM_CONFIG_SPACE_LENGTH ||
+ Bus >= BUS_MAX_NUM ||
+ Device >= DEVICE_MAX_NUM ||
+ Function >= FUNCTION_MAX_NUM)
+ {
+ return MAXDWORD64;
+ }
+
+ Target = Function + ((Device & 0x1F) << 3) + ((Bus & 0xFF) << 8);
+ _outpd(CFGADR, (DWORD)(Target << 8) | 0x80000000UL | ((DWORD)Offset & ~3));
+
+ switch ((UINT32)Width)
+ {
+ case sizeof(BYTE):
+ return (BYTE)_inp(CFGDAT + (Offset & 0x3));
+ break;
+ case sizeof(WORD):
+ return (WORD)_inpw(CFGDAT + (Offset & 0x2));
+ break;
+ case sizeof(DWORD):
+ return _inpd(CFGDAT);
+ break;
+ case sizeof(QWORD):
+ return (PciReadCam(Bus, Device, Function, Offset + sizeof(DWORD), sizeof(DWORD)) << 32) | PciReadCam(Bus, Device, Function, Offset + 0, sizeof(DWORD));
+ break;
+ default:
+ return MAXDWORD64;
+ }
+}
+
+/**
+ * @brief Write to PCI configuration space (CAM) at given offset
+ * @param Bus
+ * @param Device
+ * @param Function
+ * @param Offset
+ * @param Width Number of bytes to write. Supported data types: BYTE (1), WORD (2), DWORD (4), QWORD (8).
+ * @param Value to write.
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+PciWriteCam(WORD Bus, WORD Device, WORD Function, BYTE Offset, UINT8 Width, QWORD Value)
+{
+ BOOLEAN Result = TRUE;
+ WORD Target = 0;
+
+ //
+ // Restrict Offset to CAM address space; restrict BDF to our internal limits
+ //
+ if (Offset > CAM_CONFIG_SPACE_LENGTH ||
+ Bus >= BUS_MAX_NUM ||
+ Device >= DEVICE_MAX_NUM ||
+ Function >= FUNCTION_MAX_NUM)
+ {
+ Result = FALSE;
+ }
+ else
+ {
+ Target = Function + ((Device & 0x1F) << 3) + ((Bus & 0xFF) << 8);
+ _outpd(CFGADR, (DWORD)(Target << 8) | 0x80000000UL | ((DWORD)Offset & ~3));
+
+ switch ((UINT32)Width)
+ {
+ case sizeof(BYTE):
+ _outp((CFGDAT + (Offset & 0x3)), (BYTE)Value);
+ Result = TRUE;
+ break;
+ case sizeof(WORD):
+ _outpw((CFGDAT + (Offset & 0x2)), (WORD)Value);
+ Result = TRUE;
+ break;
+ case sizeof(DWORD):
+ _outpd((CFGDAT + Offset), (DWORD)Value);
+ Result = TRUE;
+ break;
+ case sizeof(QWORD):
+ Result = PciWriteCam(Bus, Device, Function, Offset + sizeof(DWORD), sizeof(DWORD), (DWORD)(Value >> 32));
+ Result = PciWriteCam(Bus, Device, Function, Offset + 0, sizeof(DWORD), (DWORD)Value);
+ break;
+ default:
+ Result = FALSE;
+ }
+ }
+
+ return Result;
+}
diff --git a/hyperdbg/hprdbghv/code/disassembler/Disassembler.c b/hyperdbg/hyperhv/code/disassembler/Disassembler.c
similarity index 88%
rename from hyperdbg/hprdbghv/code/disassembler/Disassembler.c
rename to hyperdbg/hyperhv/code/disassembler/Disassembler.c
index ad0394f4..24bae57e 100644
--- a/hyperdbg/hprdbghv/code/disassembler/Disassembler.c
+++ b/hyperdbg/hyperhv/code/disassembler/Disassembler.c
@@ -315,6 +315,50 @@ DisassemblerLengthDisassembleEngineInVmxRootOnTargetProcess(PVOID Address, BOOLE
return DisassemblerLengthDisassembleEngine(SafeMemoryToRead, Is32Bit);
}
+/**
+ * @brief Disassembler length disassembler engine
+ * @details Can be called from VMX non-root mode
+ *
+ * @param Address
+ * @param Is32Bit
+ * @param ProcessId
+ *
+ * @return UINT32
+ */
+UINT32
+DisassemblerLengthDisassembleEngineByProcessId(PVOID Address, BOOLEAN Is32Bit, UINT32 ProcessId)
+{
+ UINT64 SizeOfBufferToRead = 0;
+ BYTE MemoryToRead[MAXIMUM_INSTR_SIZE] = {0};
+ CR3_TYPE CurrentProcessCr3 = {0};
+
+ //
+ // Switch to the target process memory layout by using the process id
+ //
+ CurrentProcessCr3 = SwitchToProcessMemoryLayout(ProcessId);
+
+ //
+ // Read the maximum number of instruction that is valid to be read in the
+ // target address
+ //
+ SizeOfBufferToRead = CheckAddressMaximumInstructionLength(Address);
+
+ //
+ // Restore the original process
+ //
+ SwitchToPreviousProcess(CurrentProcessCr3);
+
+ //
+ // Find the current instruction
+ //
+ MemoryMapperReadMemoryUnsafe((UINT64)Address,
+ MemoryToRead,
+ SizeOfBufferToRead,
+ ProcessId);
+
+ return DisassemblerLengthDisassembleEngine(MemoryToRead, Is32Bit);
+}
+
/**
* @brief Shows the disassembly of only one instruction
* @details Should be called in VMX-root mode
diff --git a/hyperdbg/hprdbghv/code/disassembler/ZydisKernel.c b/hyperdbg/hyperhv/code/disassembler/ZydisKernel.c
similarity index 100%
rename from hyperdbg/hprdbghv/code/disassembler/ZydisKernel.c
rename to hyperdbg/hyperhv/code/disassembler/ZydisKernel.c
diff --git a/hyperdbg/hprdbghv/code/features/CompatibilityChecks.c b/hyperdbg/hyperhv/code/features/CompatibilityChecks.c
similarity index 83%
rename from hyperdbg/hprdbghv/code/features/CompatibilityChecks.c
rename to hyperdbg/hyperhv/code/features/CompatibilityChecks.c
index fcabc465..4238e4c6 100644
--- a/hyperdbg/hprdbghv/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/hprdbghv/code/features/DirtyLogging.c b/hyperdbg/hyperhv/code/features/DirtyLogging.c
similarity index 88%
rename from hyperdbg/hprdbghv/code/features/DirtyLogging.c
rename to hyperdbg/hyperhv/code/features/DirtyLogging.c
index c18f4e9e..dab2db41 100644
--- a/hyperdbg/hprdbghv/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,11 +53,11 @@ 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)
{
- g_GuestState[i].PmlBufferAddress = CrsAllocateNonPagedPool(PAGE_SIZE);
+ g_GuestState[i].PmlBufferAddress = PlatformMemAllocateNonPagedPool(PAGE_SIZE);
}
if (g_GuestState[i].PmlBufferAddress == NULL)
@@ -65,11 +65,11 @@ 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)
{
- CrsFreePool(g_GuestState[j].PmlBufferAddress);
+ PlatformMemFreePool(g_GuestState[j].PmlBufferAddress);
}
}
@@ -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,11 +196,11 @@ 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)
{
- CrsFreePool(g_GuestState[i].PmlBufferAddress);
+ PlatformMemFreePool(g_GuestState[i].PmlBufferAddress);
}
}
}
@@ -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/hprdbghv/code/globals/GlobalVariableManagement.c b/hyperdbg/hyperhv/code/globals/GlobalVariableManagement.c
similarity index 89%
rename from hyperdbg/hprdbghv/code/globals/GlobalVariableManagement.c
rename to hyperdbg/hyperhv/code/globals/GlobalVariableManagement.c
index f4108f6e..e651f362 100644
--- a/hyperdbg/hprdbghv/code/globals/GlobalVariableManagement.c
+++ b/hyperdbg/hyperhv/code/globals/GlobalVariableManagement.c
@@ -26,7 +26,7 @@ GlobalGuestStateAllocateZeroedMemory(VOID)
//
if (!g_GuestState)
{
- g_GuestState = CrsAllocateNonPagedPool(BufferSizeInByte);
+ g_GuestState = PlatformMemAllocateNonPagedPool(BufferSizeInByte);
if (!g_GuestState)
{
@@ -51,6 +51,6 @@ GlobalGuestStateAllocateZeroedMemory(VOID)
VOID
GlobalGuestStateFreeMemory(VOID)
{
- CrsFreePool(g_GuestState);
+ PlatformMemFreePool(g_GuestState);
g_GuestState = NULL;
}
diff --git a/hyperdbg/hprdbghv/code/hooks/ept-hook/EptHook.c b/hyperdbg/hyperhv/code/hooks/ept-hook/EptHook.c
similarity index 89%
rename from hyperdbg/hprdbghv/code/hooks/ept-hook/EptHook.c
rename to hyperdbg/hyperhv/code/hooks/ept-hook/EptHook.c
index af3b3169..dc2b4fd8 100644
--- a/hyperdbg/hprdbghv/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;
@@ -179,16 +178,28 @@ EptHookCreateHookPage(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
//
PhysicalBaseAddress = (SIZE_T)VirtualAddressToPhysicalAddressByProcessCr3(VirtualTarget, ProcessCr3);
+ //
+ // If the physical address is NULL, it means that the address is not valid
+ //
if (!PhysicalBaseAddress)
{
VmmCallbackSetLastError(DEBUGGER_ERROR_INVALID_ADDRESS);
return FALSE;
}
+ //
+ // Check if the physical address is bigger than 512 GB
+ //
+ if (PhysicalBaseAddress >= SIZE_512_GB)
+ {
+ VmmCallbackSetLastError(DEBUGGER_ERROR_CANNOT_PUT_EPT_HOOKS_ON_PHYSICAL_ADDRESS_ABOVE_512_GB);
+ return FALSE;
+ }
+
//
// 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)
{
@@ -263,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);
@@ -299,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;
@@ -503,6 +509,15 @@ EptHookPerformPageHook(VIRTUAL_MACHINE_STATE * VCpu,
return FALSE;
}
+ //
+ // Check if the physical address is bigger than 512 GB
+ //
+ if (PhysicalBaseAddress >= SIZE_512_GB)
+ {
+ VmmCallbackSetLastError(DEBUGGER_ERROR_CANNOT_PUT_EPT_HOOKS_ON_PHYSICAL_ADDRESS_ABOVE_512_GB);
+ return FALSE;
+ }
+
//
// try to see if we can find the address
//
@@ -892,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)
{
@@ -941,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;
@@ -985,8 +1000,7 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
ULONG ProcessorsCount;
EPT_PML1_ENTRY ChangedEntry;
SIZE_T PhysicalBaseAddress;
- PVOID AlignedTargetVa;
- PVOID TargetBuffer;
+ PVOID AlignedTargetVaOrPa;
PVOID TargetAddress;
PVOID HookFunction;
UINT64 TargetAddressInSafeMemory;
@@ -1024,7 +1038,7 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
TargetAddress = (PVOID)((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->StartAddress;
}
- AlignedTargetVa = PAGE_ALIGN(TargetAddress);
+ AlignedTargetVaOrPa = PAGE_ALIGN(TargetAddress);
//
// Here we have to change the CR3, it is because we are in SYSTEM process
@@ -1032,17 +1046,40 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
// user mode address of another process) then the translation is invalid
//
- //
- // based on the CR3 of target core
- //
- PhysicalBaseAddress = (SIZE_T)VirtualAddressToPhysicalAddressByProcessCr3(AlignedTargetVa, ProcessCr3);
+ if (!EptHiddenHook &&
+ ((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->MemoryType == DEBUGGER_MEMORY_HOOK_PHYSICAL_ADDRESS)
+ {
+ //
+ // The address itself is a physical address, no need for conversion
+ //
+ PhysicalBaseAddress = (SIZE_T)AlignedTargetVaOrPa;
+ }
+ else
+ {
+ //
+ // based on the CR3 of target core
+ //
+ PhysicalBaseAddress = (SIZE_T)VirtualAddressToPhysicalAddressByProcessCr3(AlignedTargetVaOrPa, ProcessCr3);
+ }
+ //
+ // Check if the physical address is valid
+ //
if (!PhysicalBaseAddress)
{
VmmCallbackSetLastError(DEBUGGER_ERROR_INVALID_ADDRESS);
return FALSE;
}
+ //
+ // Check if the physical address is bigger than 512 GB
+ //
+ if (PhysicalBaseAddress >= SIZE_512_GB)
+ {
+ VmmCallbackSetLastError(DEBUGGER_ERROR_CANNOT_PUT_EPT_HOOKS_ON_PHYSICAL_ADDRESS_ABOVE_512_GB);
+ return FALSE;
+ }
+
//
// try to see if we can find the address
//
@@ -1067,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)
{
@@ -1099,13 +1136,26 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
//
// Save the start of the target physical address
//
- HookedPage->StartOfTargetPhysicalAddress = (SIZE_T)VirtualAddressToPhysicalAddressByProcessCr3(
- (PVOID)(((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->StartAddress),
- ProcessCr3);
+ if (((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->MemoryType == DEBUGGER_MEMORY_HOOK_PHYSICAL_ADDRESS)
+ {
+ //
+ // Physical address
+ //
+ HookedPage->StartOfTargetPhysicalAddress = (SIZE_T)(((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->StartAddress);
+ }
+ else
+ {
+ //
+ // Virtual address
+ //
+ HookedPage->StartOfTargetPhysicalAddress = (SIZE_T)VirtualAddressToPhysicalAddressByProcessCr3(
+ (PVOID)(((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->StartAddress),
+ ProcessCr3);
+ }
if (!HookedPage->StartOfTargetPhysicalAddress)
{
- PoolManagerFreePool((UINT64)HookedPage);
+ PoolManagerCallbackFreePool((UINT64)HookedPage);
VmmCallbackSetLastError(DEBUGGER_ERROR_INVALID_ADDRESS);
return FALSE;
@@ -1114,13 +1164,26 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
//
// Save the end of the target physical address
//
- HookedPage->EndOfTargetPhysicalAddress = (SIZE_T)VirtualAddressToPhysicalAddressByProcessCr3(
- (PVOID)(((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->EndAddress),
- ProcessCr3);
+ if (((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->MemoryType == DEBUGGER_MEMORY_HOOK_PHYSICAL_ADDRESS)
+ {
+ //
+ // Physical address
+ //
+ HookedPage->EndOfTargetPhysicalAddress = (SIZE_T)(((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->EndAddress);
+ }
+ else
+ {
+ //
+ // Virtual address
+ //
+ HookedPage->EndOfTargetPhysicalAddress = (SIZE_T)VirtualAddressToPhysicalAddressByProcessCr3(
+ (PVOID)(((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->EndAddress),
+ ProcessCr3);
+ }
if (!HookedPage->EndOfTargetPhysicalAddress)
{
- PoolManagerFreePool((UINT64)HookedPage);
+ PoolManagerCallbackFreePool((UINT64)HookedPage);
VmmCallbackSetLastError(DEBUGGER_ERROR_INVALID_ADDRESS);
return FALSE;
@@ -1149,7 +1212,7 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
// The following line can't be used in user mode addresses
// RtlCopyBytes(&HookedPage->FakePageContents, VirtualTarget, PAGE_SIZE);
//
- MemoryMapperReadMemorySafe((UINT64)AlignedTargetVa, &HookedPage->FakePageContents, PAGE_SIZE);
+ MemoryMapperReadMemorySafe((UINT64)AlignedTargetVaOrPa, &HookedPage->FakePageContents, PAGE_SIZE);
//
// Restore to original process
@@ -1181,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;
@@ -1224,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;
@@ -1805,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");
}
@@ -1907,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;
@@ -2012,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)
{
@@ -2056,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");
}
@@ -2105,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)
{
@@ -2132,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];
@@ -2159,6 +2216,7 @@ EptHookUnHookSingleAddressHiddenBreakpoint(PEPT_HOOKED_PAGE_DETAIL H
*
* @param VirtualAddress Virtual address to unhook
* @param PhysAddress Physical address to unhook (optional)
+ * @param HookingTag Hooking tag (optional)
* @param ProcessId The process id of target process
* (in unhooking for some hooks only physical address is availables)
* @param ApplyDirectlyFromVmxRoot should it be directly applied from VMX-root mode or not
@@ -2170,11 +2228,12 @@ EptHookUnHookSingleAddressHiddenBreakpoint(PEPT_HOOKED_PAGE_DETAIL H
BOOLEAN
EptHookPerformUnHookSingleAddress(UINT64 VirtualAddress,
UINT64 PhysAddress,
+ UINT64 HookingTag,
UINT32 ProcessId,
BOOLEAN ApplyDirectlyFromVmxRoot,
EPT_SINGLE_HOOK_UNHOOKING_DETAILS * TargetUnhookingDetails)
{
- SIZE_T PhysicalAddress;
+ SIZE_T PhysicalAddress = NULL64_ZERO;
//
// Once applied directly from VMX-root mode, the process id should be the same process Id
@@ -2188,7 +2247,11 @@ EptHookPerformUnHookSingleAddress(UINT64 VirtualAdd
//
// Check if the physical address is available or not
//
- if (PhysAddress == NULL64_ZERO)
+ if (PhysAddress != NULL64_ZERO)
+ {
+ PhysicalAddress = (SIZE_T)PAGE_ALIGN(PhysAddress);
+ }
+ else if (HookingTag == NULL64_ZERO)
{
if (ApplyDirectlyFromVmxRoot)
{
@@ -2200,10 +2263,6 @@ EptHookPerformUnHookSingleAddress(UINT64 VirtualAdd
ProcessId)));
}
}
- else
- {
- PhysicalAddress = (SIZE_T)PAGE_ALIGN(PhysAddress);
- }
LIST_FOR_EACH_LINK(g_EptState->HookedPagesList, EPT_HOOKED_PAGE_DETAIL, PageHookList, CurrEntity)
{
@@ -2215,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)
{
@@ -2231,7 +2290,7 @@ EptHookPerformUnHookSingleAddress(UINT64 VirtualAdd
//
// It's either a hidden detours or a monitor (read/write/execute) entry
//
- if (CurrEntity->PhysicalBaseAddress == PhysicalAddress)
+ if ((HookingTag != NULL64_ZERO && CurrEntity->HookingTag == HookingTag) || CurrEntity->PhysicalBaseAddress == PhysicalAddress)
{
return EptHookUnHookSingleAddressDetoursAndMonitor(CurrEntity,
ApplyDirectlyFromVmxRoot,
@@ -2241,11 +2300,81 @@ EptHookPerformUnHookSingleAddress(UINT64 VirtualAdd
}
//
- // Nothing found, probably the list is not found
+ // Nothing found, probably the hooking detail is not found
//
return FALSE;
}
+/**
+ * @brief Remove all hooks from the hooked pages by the given hooking tag
+ * @details Should be called from Vmx Non-root
+ *
+ * @param HookingTag The hooking tag to unhook
+ * @return BOOLEAN If unhook was successful it returns true or if it was not successful returns false
+ */
+BOOLEAN
+EptHookUnHookAllByHookingTag(UINT64 HookingTag)
+{
+ EPT_SINGLE_HOOK_UNHOOKING_DETAILS TargetUnhookingDetails; // not used
+ BOOLEAN AtLeastOneUnhooked = FALSE;
+ BOOLEAN UnhookingResult = FALSE;
+
+ //
+ // Should be called from vmx non-root
+ //
+ if (VmxGetCurrentExecutionMode() == TRUE)
+ {
+ return FALSE;
+ }
+
+KeepUnhooking:
+ UnhookingResult = EptHookPerformUnHookSingleAddress(NULL_ZERO,
+ NULL_ZERO,
+ HookingTag,
+ NULL_ZERO,
+ FALSE,
+ &TargetUnhookingDetails);
+
+ if (UnhookingResult)
+ {
+ AtLeastOneUnhooked = TRUE;
+
+ //
+ // Keep unhooking until there is no more hooking details
+ //
+ goto KeepUnhooking;
+ }
+
+ return AtLeastOneUnhooked;
+}
+
+/**
+ * @brief Remove single hook from the hooked pages by the given hooking tag
+ * @details Should be called from Vmx root-mode
+ *
+ * @param HookingTag The hooking tag to unhook
+ * @return BOOLEAN If unhook was successful it returns true or if it was not successful returns false
+ */
+BOOLEAN
+EptHookUnHookSingleHookByHookingTagFromVmxRoot(UINT64 HookingTag,
+ EPT_SINGLE_HOOK_UNHOOKING_DETAILS * TargetUnhookingDetails)
+{
+ //
+ // Should be called from VMX root-mode
+ //
+ if (VmxGetCurrentExecutionMode() == FALSE)
+ {
+ return FALSE;
+ }
+
+ return EptHookPerformUnHookSingleAddress(NULL64_ZERO,
+ NULL64_ZERO,
+ HookingTag,
+ NULL_ZERO,
+ TRUE,
+ TargetUnhookingDetails);
+}
+
/**
* @brief Remove single hook from the hooked pages list and invalidate TLB
* @details Should be called from VMX non-root
@@ -2274,6 +2403,7 @@ EptHookUnHookSingleAddress(UINT64 VirtualAddress,
return EptHookPerformUnHookSingleAddress(VirtualAddress,
PhysAddress,
+ NULL_ZERO,
ProcessId,
FALSE,
&TargetUnhookingDetails);
@@ -2305,6 +2435,7 @@ EptHookUnHookSingleAddressFromVmxRoot(UINT64 Virtua
return EptHookPerformUnHookSingleAddress(VirtualAddress,
PhysAddress,
+ NULL64_ZERO,
NULL_ZERO,
TRUE,
TargetUnhookingDetails);
@@ -2354,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");
}
@@ -2459,7 +2590,7 @@ EptHookModifyInstructionFetchState(VIRTUAL_MACHINE_STATE * VCpu,
PVOID PmlEntry = NULL;
BOOLEAN IsLargePage = FALSE;
- PmlEntry = EptGetPml1OrPml2Entry(g_EptState->EptPageTable, (SIZE_T)PhysicalAddress, &IsLargePage);
+ PmlEntry = EptGetPml1OrPml2Entry(VCpu->EptPageTable, (SIZE_T)PhysicalAddress, &IsLargePage);
if (PmlEntry)
{
@@ -2517,7 +2648,7 @@ EptHookModifyPageReadState(VIRTUAL_MACHINE_STATE * VCpu,
PVOID PmlEntry = NULL;
BOOLEAN IsLargePage = FALSE;
- PmlEntry = EptGetPml1OrPml2Entry(g_EptState->EptPageTable, (SIZE_T)PhysicalAddress, &IsLargePage);
+ PmlEntry = EptGetPml1OrPml2Entry(VCpu->EptPageTable, (SIZE_T)PhysicalAddress, &IsLargePage);
if (PmlEntry)
{
@@ -2575,7 +2706,7 @@ EptHookModifyPageWriteState(VIRTUAL_MACHINE_STATE * VCpu,
PVOID PmlEntry = NULL;
BOOLEAN IsLargePage = FALSE;
- PmlEntry = EptGetPml1OrPml2Entry(g_EptState->EptPageTable, (SIZE_T)PhysicalAddress, &IsLargePage);
+ PmlEntry = EptGetPml1OrPml2Entry(VCpu->EptPageTable, (SIZE_T)PhysicalAddress, &IsLargePage);
if (PmlEntry)
{
diff --git a/hyperdbg/hprdbghv/code/hooks/ept-hook/ExecTrap.c b/hyperdbg/hyperhv/code/hooks/ept-hook/ExecTrap.c
similarity index 74%
rename from hyperdbg/hprdbghv/code/hooks/ept-hook/ExecTrap.c
rename to hyperdbg/hyperhv/code/hooks/ept-hook/ExecTrap.c
index e7ca0fb1..8554064b 100644
--- a/hyperdbg/hprdbghv/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);
@@ -245,134 +245,6 @@ ExecTrapTraverseThroughOsPageTables(PVMM_EPT_PAGE_TABLE EptTable, CR3_TYPE Targe
return TRUE;
}
-/**
- * @brief Initialize the needed structure for hooking user-mode execution
- * @details should be called from vmx non-root mode
- *
- * @return BOOLEAN
- */
-BOOLEAN
-ExecTrapAllocateUserDisabledMbecEptPageTable()
-{
- PVMM_EPT_PAGE_TABLE ModeBasedEptTable;
- EPT_POINTER EPTP = {0};
-
- //
- // Allocate another EPT page table
- //
- ModeBasedEptTable = EptAllocateAndCreateIdentityPageTable();
-
- if (ModeBasedEptTable == NULL)
- {
- //
- // There was an error allocating MBEC page tables
- //
- return FALSE;
- }
-
- //
- // Disable EPT user-mode execution bit for the target EPTP
- //
- ModeBasedExecHookDisableUserModeExecution(ModeBasedEptTable);
-
- //
- // Set the global address for MBEC EPT page table
- //
- g_EptState->ModeBasedUserDisabledEptPageTable = ModeBasedEptTable;
-
- //
- // For performance, we let the processor know it can cache the EPT
- //
- EPTP.MemoryType = MEMORY_TYPE_WRITE_BACK;
-
- //
- // We might utilize the 'access' and 'dirty' flag features in the dirty logging mechanism
- //
- EPTP.EnableAccessAndDirtyFlags = TRUE;
-
- //
- // Bits 5:3 (1 less than the EPT page-walk length) must be 3, indicating an EPT page-walk length of 4;
- // see Section 28.2.2
- //
- EPTP.PageWalkLength = 3;
-
- //
- // The physical page number of the page table we will be using
- //
- EPTP.PageFrameNumber = (SIZE_T)VirtualAddressToPhysicalAddress(&ModeBasedEptTable->PML4) / PAGE_SIZE;
-
- //
- // We will write the EPTP to the VMCS later
- //
- g_EptState->ModeBasedUserDisabledEptPointer.AsUInt = EPTP.AsUInt;
-
- return TRUE;
-}
-
-/**
- * @brief Initialize the needed structure for hooking kernel-mode execution
- * @details should be called from vmx non-root mode
- *
- * @return BOOLEAN
- */
-BOOLEAN
-ExecTrapAllocateKernelDisabledMbecEptPageTable()
-{
- PVMM_EPT_PAGE_TABLE ModeBasedEptTable;
- EPT_POINTER EPTP = {0};
-
- //
- // Allocate another EPT page table
- //
- ModeBasedEptTable = EptAllocateAndCreateIdentityPageTable();
-
- if (ModeBasedEptTable == NULL)
- {
- //
- // There was an error allocating MBEC page tables
- //
- return FALSE;
- }
-
- //
- // Disable EPT user-mode execution bit for the target EPTP
- //
- ModeBasedExecHookDisableKernelModeExecution(ModeBasedEptTable);
-
- //
- // Set the global address for MBEC EPT page table
- //
- g_EptState->ModeBasedKernelDisabledEptPageTable = ModeBasedEptTable;
-
- //
- // For performance, we let the processor know it can cache the EPT
- //
- EPTP.MemoryType = MEMORY_TYPE_WRITE_BACK;
-
- //
- // We might utilize the 'access' and 'dirty' flag features in the dirty logging mechanism
- //
- EPTP.EnableAccessAndDirtyFlags = TRUE;
-
- //
- // Bits 5:3 (1 less than the EPT page-walk length) must be 3, indicating an EPT page-walk length of 4;
- // see Section 28.2.2
- //
- EPTP.PageWalkLength = 3;
-
- //
- // The physical page number of the page table we will be using
- //
- EPTP.PageFrameNumber = (SIZE_T)VirtualAddressToPhysicalAddress(&ModeBasedEptTable->PML4) / PAGE_SIZE;
-
- //
- // We will write the EPTP to the VMCS later
- //
- g_EptState->ModeBasedKernelDisabledEptPointer.AsUInt = EPTP.AsUInt;
-
- return TRUE;
-}
-
/**
* @brief Adjust execute-only bits bit of target page-table
* @details should be called from vmx non-root mode
@@ -393,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
@@ -404,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;
}
@@ -412,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;
}
@@ -423,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)
{
@@ -489,7 +361,7 @@ ExecTrapReadRamPhysicalRegions()
}
/**
- * @brief Initialize the reversing machine based on service request
+ * @brief Initialize the exec trap based on service request
*
* @return BOOLEAN
*/
@@ -497,14 +369,14 @@ BOOLEAN
ExecTrapInitialize()
{
//
- // Check if the reversing machine is already initialized
+ // Check if the exec trap is already initialized
//
if (g_ExecTrapInitialized)
{
//
// Already initialized
//
- return FALSE;
+ return TRUE;
}
//
@@ -517,56 +389,11 @@ ExecTrapInitialize()
return FALSE;
}
- //
- // Read the RAM regions
- //
- ExecTrapReadRamPhysicalRegions();
-
- //
- // Allocate MBEC EPT page-table (user-disabled)
- //
- if (!ExecTrapAllocateUserDisabledMbecEptPageTable())
- {
- //
- // There was an error allocating MBEC page table for EPT tables
- //
- return FALSE;
- }
-
- //
- // Allocate MBEC EPT page-table (kernel-disabled)
- //
- if (!ExecTrapAllocateKernelDisabledMbecEptPageTable())
- {
- //
- // Free the user-disabled page-table buffer
- //
- MmFreeContiguousMemory(g_EptState->ModeBasedUserDisabledEptPageTable);
- g_EptState->ModeBasedUserDisabledEptPageTable = NULL;
-
- //
- // There was an error allocating MBEC page table for EPT tables
- //
- return FALSE;
- }
-
//
// Call the function responsible for initializing Mode-based hooks
//
if (ModeBasedExecHookInitialize() == FALSE)
{
- //
- // Free the user-disabled page-table buffer
- //
- MmFreeContiguousMemory(g_EptState->ModeBasedUserDisabledEptPageTable);
- g_EptState->ModeBasedUserDisabledEptPageTable = NULL;
-
- //
- // Free the kernel-disabled page-table buffer
- //
- MmFreeContiguousMemory(g_EptState->ModeBasedKernelDisabledEptPageTable);
- g_EptState->ModeBasedKernelDisabledEptPageTable = NULL;
-
//
// The initialization was not successful
//
@@ -641,24 +468,6 @@ ExecTrapUninitialize()
// Indicate that the uninitialization phase finished
//
g_ExecTrapUnInitializationStarted = FALSE;
-
- //
- // Free Identity Page Table for MBEC hooks (user-disabled)
- //
- if (g_EptState->ModeBasedUserDisabledEptPageTable != NULL)
- {
- MmFreeContiguousMemory(g_EptState->ModeBasedUserDisabledEptPageTable);
- g_EptState->ModeBasedUserDisabledEptPageTable = NULL;
- }
-
- //
- // Free Identity Page Table for MBEC hooks (kernel-disabled)
- //
- if (g_EptState->ModeBasedKernelDisabledEptPageTable != NULL)
- {
- MmFreeContiguousMemory(g_EptState->ModeBasedKernelDisabledEptPageTable);
- g_EptState->ModeBasedKernelDisabledEptPageTable = NULL;
- }
}
/**
@@ -673,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
@@ -681,26 +490,6 @@ ExecTrapRestoreToNormalEptp(VIRTUAL_MACHINE_STATE * VCpu)
VCpu->NotNormalEptp = FALSE;
}
-/**
- * @brief change to execute-only EPTP
- * @param VCpu The virtual processor's state
- *
- * @return VOID
- */
-VOID
-ExecTrapChangeToExecuteOnlyEptp(VIRTUAL_MACHINE_STATE * VCpu)
-{
- //
- // Change EPTP
- //
- __vmx_vmwrite(VMCS_CTRL_EPT_POINTER, g_EptState->ExecuteOnlyEptPointer.AsUInt);
-
- //
- // It's not on normal EPTP
- //
- VCpu->NotNormalEptp = TRUE;
-}
-
/**
* @brief change to user-disabled MBEC EPTP
* @param VCpu The virtual processor's state
@@ -711,9 +500,30 @@ VOID
ExecTrapChangeToUserDisabledMbecEptp(VIRTUAL_MACHINE_STATE * VCpu)
{
//
- // Change EPTP
+ // From Intel Manual:
+ // [Bit 2] If the "mode-based execute control for EPT" VM - execution control is 0, execute access;
+ // indicates whether instruction fetches are allowed from the 2-MByte page controlled by this entry.
+ // If that control is 1, execute access for supervisor-mode linear addresses; indicates whether instruction
+ // fetches are allowed from supervisor - mode linear addresses in the 2 - MByte page controlled by this entry
//
- __vmx_vmwrite(VMCS_CTRL_EPT_POINTER, g_EptState->ModeBasedUserDisabledEptPointer.AsUInt);
+
+ //
+ // Set execute access for PML4s
+ //
+ // for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT; i++)
+ // {
+ VCpu->EptPageTable->PML4[0].UserModeExecute = FALSE;
+
+ //
+ // We only set the top-level PML4 for intercepting kernel-mode execution
+ //
+ VCpu->EptPageTable->PML4[0].ExecuteAccess = TRUE;
+ // }
+
+ //
+ // Invalidate the EPT cache
+ //
+ EptInveptSingleContext(VCpu->EptPointer.AsUInt);
//
// It's not on normal EPTP
@@ -731,9 +541,30 @@ VOID
ExecTrapChangeToKernelDisabledMbecEptp(VIRTUAL_MACHINE_STATE * VCpu)
{
//
- // Change EPTP
+ // From Intel Manual:
+ // [Bit 2] If the "mode-based execute control for EPT" VM - execution control is 0, execute access;
+ // indicates whether instruction fetches are allowed from the 2-MByte page controlled by this entry.
+ // If that control is 1, execute access for supervisor-mode linear addresses; indicates whether instruction
+ // fetches are allowed from supervisor - mode linear addresses in the 2 - MByte page controlled by this entry
//
- __vmx_vmwrite(VMCS_CTRL_EPT_POINTER, g_EptState->ModeBasedKernelDisabledEptPointer.AsUInt);
+
+ //
+ // Set execute access for PML4s
+ //
+ // for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT; i++)
+ // {
+ VCpu->EptPageTable->PML4[0].UserModeExecute = TRUE;
+
+ //
+ // We only set the top-level PML4 for intercepting kernel-mode execution
+ //
+ VCpu->EptPageTable->PML4[0].ExecuteAccess = FALSE;
+ // }
+
+ //
+ // Invalidate the EPT cache
+ //
+ EptInveptSingleContext(VCpu->EptPointer.AsUInt);
//
// It's not on normal EPTP
@@ -741,6 +572,47 @@ ExecTrapChangeToKernelDisabledMbecEptp(VIRTUAL_MACHINE_STATE * VCpu)
VCpu->NotNormalEptp = TRUE;
}
+/**
+ * @brief change to normal MBEC EPTP
+ * @param VCpu The virtual processor's state
+ *
+ * @return VOID
+ */
+VOID
+ExecTrapChangeToNormalMbecEptp(VIRTUAL_MACHINE_STATE * VCpu)
+{
+ //
+ // From Intel Manual:
+ // [Bit 2] If the "mode-based execute control for EPT" VM - execution control is 0, execute access;
+ // indicates whether instruction fetches are allowed from the 2-MByte page controlled by this entry.
+ // If that control is 1, execute access for supervisor-mode linear addresses; indicates whether instruction
+ // fetches are allowed from supervisor - mode linear addresses in the 2 - MByte page controlled by this entry
+ //
+
+ //
+ // Set execute access for PML4s
+ //
+ // for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT; i++)
+ // {
+ VCpu->EptPageTable->PML4[0].UserModeExecute = TRUE;
+
+ //
+ // We only set the top-level PML4 for intercepting kernel-mode execution
+ //
+ VCpu->EptPageTable->PML4[0].ExecuteAccess = TRUE;
+ // }
+
+ //
+ // Invalidate the EPT cache
+ //
+ EptInveptSingleContext(VCpu->EptPointer.AsUInt);
+
+ //
+ // It's not on normal EPTP
+ //
+ VCpu->NotNormalEptp = FALSE;
+}
+
/**
* @brief Restore the execution of the trap to adjusted trap state
* @param VCpu The virtual processor's state
@@ -766,6 +638,10 @@ ExecTrapHandleMoveToAdjustedTrapState(VIRTUAL_MACHINE_STATE * VCpu, DEBUGGER_EVE
//
ExecTrapChangeToUserDisabledMbecEptp(VCpu);
}
+ else
+ {
+ LogError("Err, Invalid target mode for execution trap: %x", TargetMode);
+ }
}
/**
@@ -802,9 +678,7 @@ ExecTrapHandleEptViolationVmexit(VIRTUAL_MACHINE_STATE * VCpu,
//
// Trigger the event
//
- DispatchEventMode(VCpu, DEBUGGER_EVENT_MODE_TYPE_USER_MODE, TRUE);
-
- return TRUE;
+ DispatchEventMode(VCpu, DEBUGGER_EVENT_MODE_TYPE_USER_MODE);
}
else if (!ViolationQualification->EptExecutable && ViolationQualification->ExecuteAccess)
{
@@ -821,7 +695,7 @@ ExecTrapHandleEptViolationVmexit(VIRTUAL_MACHINE_STATE * VCpu,
//
// Trigger the event
//
- DispatchEventMode(VCpu, DEBUGGER_EVENT_MODE_TYPE_KERNEL_MODE, TRUE);
+ DispatchEventMode(VCpu, DEBUGGER_EVENT_MODE_TYPE_KERNEL_MODE);
}
else
{
@@ -838,17 +712,22 @@ ExecTrapHandleEptViolationVmexit(VIRTUAL_MACHINE_STATE * VCpu,
}
/**
- * @brief Handle MOV to CR3 vm-exits for hooking mode execution
+ * @brief Apply the MBEC configuration from the kernel side
* @param VCpu The virtual processor's state
*
* @return VOID
*/
VOID
-ExecTrapHandleCr3Vmexit(VIRTUAL_MACHINE_STATE * VCpu)
+ExecTrapApplyMbecConfiguratinFromKernelSide(VIRTUAL_MACHINE_STATE * VCpu)
{
BOOLEAN Result;
UINT32 Index;
+ //
+ // Acquire the lock for the exec trap process list
+ //
+ SpinlockLock(&ExecTrapProcessListLock);
+
//
// Search the list of processes for the current process's user-execution
// trap state
@@ -858,6 +737,11 @@ ExecTrapHandleCr3Vmexit(VIRTUAL_MACHINE_STATE * VCpu)
&Index,
(UINT64)PsGetCurrentProcessId());
+ //
+ // Release the lock for the exec trap process list
+ //
+ SpinlockUnlock(&ExecTrapProcessListLock);
+
//
// Check whether the procerss is in the list of interceptions or not
//
@@ -872,7 +756,7 @@ ExecTrapHandleCr3Vmexit(VIRTUAL_MACHINE_STATE * VCpu)
//
// Trigger the event
//
- DispatchEventMode(VCpu, DEBUGGER_EVENT_MODE_TYPE_KERNEL_MODE, TRUE);
+ DispatchEventMode(VCpu, DEBUGGER_EVENT_MODE_TYPE_KERNEL_MODE);
}
else if (VCpu->MbecEnabled)
{
@@ -884,6 +768,18 @@ ExecTrapHandleCr3Vmexit(VIRTUAL_MACHINE_STATE * VCpu)
}
}
+/**
+ * @brief Handle MOV to CR3 vm-exits for hooking mode execution
+ * @param VCpu The virtual processor's state
+ *
+ * @return VOID
+ */
+VOID
+ExecTrapHandleCr3Vmexit(VIRTUAL_MACHINE_STATE * VCpu)
+{
+ ExecTrapApplyMbecConfiguratinFromKernelSide(VCpu);
+}
+
/**
* @brief Add the target process to the watching list
* @param ProcessId
@@ -893,10 +789,20 @@ ExecTrapHandleCr3Vmexit(VIRTUAL_MACHINE_STATE * VCpu)
BOOLEAN
ExecTrapAddProcessToWatchingList(UINT32 ProcessId)
{
- return InsertionSortInsertItem(&g_ExecTrapState.InterceptionProcessIds[0],
- &g_ExecTrapState.NumberOfItems,
- MAXIMUM_NUMBER_OF_PROCESSES_FOR_USER_KERNEL_EXEC_THREAD,
- (UINT64)ProcessId);
+ UINT32 Index;
+ BOOLEAN Result;
+
+ SpinlockLock(&ExecTrapProcessListLock);
+
+ Result = InsertionSortInsertItem(&g_ExecTrapState.InterceptionProcessIds[0],
+ &g_ExecTrapState.NumberOfItems,
+ MAXIMUM_NUMBER_OF_PROCESSES_FOR_USER_KERNEL_EXEC_THREAD,
+ &Index,
+ (UINT64)ProcessId);
+
+ SpinlockUnlock(&ExecTrapProcessListLock);
+
+ return Result;
}
/**
@@ -908,7 +814,24 @@ ExecTrapAddProcessToWatchingList(UINT32 ProcessId)
BOOLEAN
ExecTrapRemoveProcessFromWatchingList(UINT32 ProcessId)
{
- return InsertionSortDeleteItem(&g_ExecTrapState.InterceptionProcessIds[0],
- &g_ExecTrapState.NumberOfItems,
- (UINT64)ProcessId);
+ UINT32 Index;
+ BOOLEAN Result;
+
+ SpinlockLock(&ExecTrapProcessListLock);
+
+ Result = BinarySearchPerformSearchItem(&g_ExecTrapState.InterceptionProcessIds[0],
+ g_ExecTrapState.NumberOfItems,
+ &Index,
+ (UINT64)ProcessId);
+
+ if (Result)
+ {
+ Result = InsertionSortDeleteItem(&g_ExecTrapState.InterceptionProcessIds[0],
+ &g_ExecTrapState.NumberOfItems,
+ Index);
+ }
+
+ SpinlockUnlock(&ExecTrapProcessListLock);
+
+ return Result;
}
diff --git a/hyperdbg/hprdbghv/code/hooks/ept-hook/ModeBasedExecHook.c b/hyperdbg/hyperhv/code/hooks/ept-hook/ModeBasedExecHook.c
similarity index 73%
rename from hyperdbg/hprdbghv/code/hooks/ept-hook/ModeBasedExecHook.c
rename to hyperdbg/hyperhv/code/hooks/ept-hook/ModeBasedExecHook.c
index 179c04dd..b8704a1f 100644
--- a/hyperdbg/hprdbghv/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;
}
@@ -118,10 +118,12 @@ ModeBasedExecHookDisableKernelModeExecution(PVMM_EPT_PAGE_TABLE EptTable)
BOOLEAN
ModeBasedExecHookEnableUsermodeExecution(PVMM_EPT_PAGE_TABLE EptTable)
{
+ EPT_PML1_ENTRY Pml1Entries[VMM_EPT_PML1E_COUNT];
+
//
// 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
@@ -132,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;
}
@@ -140,11 +142,37 @@ 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;
+
+ //
+ // If the PML2 entry is not a large page, we should set execute access for PML1s
+ // It usually happens when the PML2 entry is not a large page and is previously
+ // used for an EPT hook, so, it has PML1 entries
+ //
+ if (!EptTable->PML2[i][j].LargePage)
+ {
+ //
+ // Shift to the left to get the PFN
+ //
+ MemoryMapperReadMemorySafeByPhysicalAddress(EptTable->PML2[i][j].PageFrameNumber << 12, (UINT64)Pml1Entries, PAGE_SIZE);
+
+ //
+ // Set execute access for PML1s
+ //
+ for (SIZE_T k = 0; k < VMM_EPT_PML1E_COUNT; k++)
+ {
+ Pml1Entries[k].UserModeExecute = TRUE;
+ }
+
+ //
+ // Write back the PML1 entries to the EPT page table
+ //
+ MemoryMapperWriteMemorySafeByPhysicalAddress(EptTable->PML2[i][j].PageFrameNumber << 12, (UINT64)Pml1Entries, PAGE_SIZE);
+ }
}
}
@@ -218,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/hprdbghv/code/hooks/syscall-hook/EferHook.c b/hyperdbg/hyperhv/code/hooks/syscall-hook/EferHook.c
similarity index 78%
rename from hyperdbg/hprdbghv/code/hooks/syscall-hook/EferHook.c
rename to hyperdbg/hyperhv/code/hooks/syscall-hook/EferHook.c
index 5702a2d9..2a3d0bec 100644
--- a/hyperdbg/hprdbghv/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
new file mode 100644
index 00000000..9b348728
--- /dev/null
+++ b/hyperdbg/hyperhv/code/hooks/syscall-hook/SyscallCallback.c
@@ -0,0 +1,405 @@
+/**
+ * @file SyscallCallback.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @author jtaw5649
+ * @brief Implementation of the functions related to the callback for Syscall
+ * @details
+ *
+ * @version 0.14
+ * @date 2025-06-07
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief Initialize the syscall callback
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+SyscallCallbackInitialize()
+{
+ MSR Msr = {0};
+
+ //
+ // Check whether the syscall callback was already initialized or not
+ //
+ if (!g_SyscallCallbackStatus)
+ {
+ //
+ // Insert EPT memory page hook for Windows system call handler, KiSystemCall64()
+ //
+ Msr.Flags = CpuReadMsr(IA32_LSTAR);
+
+ //
+ // We set the hook at the address of the system call handler + 3
+ // because we don't want to hook the first 3 bytes of the system call handler
+ // which is SWAPGS instruction
+ //
+ g_SystemCallHookAddress = (PVOID)(Msr.Flags + 3);
+
+ //
+ // Apply the hook from vmx non-root mode
+ //
+ if (!ConfigureEptHook(g_SystemCallHookAddress, (UINT32)(ULONG_PTR)PsGetCurrentProcessId()))
+ {
+ // LogInfo("Error while inserting EPT page hook for Windows system call handler at address 0x%p+3", Msr.Flags);
+
+ return FALSE;
+ }
+
+ //
+ // Allocate buffer for the syscall callback trap flag state
+ //
+ g_SyscallCallbackTrapFlagState = (SYSCALL_CALLBACK_TRAP_FLAG_STATE *)PlatformMemAllocateZeroedNonPagedPool(sizeof(SYSCALL_CALLBACK_TRAP_FLAG_STATE));
+
+ //
+ // Intercept trap flags #DBs and #BPs for the syscall callback
+ //
+ BroadcastEnableDbAndBpExitingAllCores();
+
+ //
+ // Enable the syscall callback
+ //
+ g_SyscallCallbackStatus = TRUE;
+
+ //
+ // Successfully enabled the syscall callback
+ //
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+/**
+ * @brief Check whether the syscall callback is initialized
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+SyscallCallbackIsInitialized()
+{
+ return g_SyscallCallbackStatus;
+}
+
+/**
+ * @brief Uninitialize the syscall callback
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+SyscallCallbackUninitialize()
+{
+ if (g_SyscallCallbackStatus)
+ {
+ //
+ // Unset the EPT hook from the syscall entry before disabling state.
+ //
+ 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
+ //
+ BroadcastDisableDbAndBpExitingAllCores();
+
+ //
+ // Free the buffer for the syscall callback trap flag state
+ //
+ PlatformMemFreePool(g_SyscallCallbackTrapFlagState);
+
+ g_SyscallCallbackTrapFlagState = NULL;
+ g_SystemCallHookAddress = NULL;
+ g_SyscallCallbackStatus = FALSE;
+
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+/**
+ * @brief This function makes sure to unset the RFLAGS.TF on next trigger of #DB
+ * on the target process/thread
+ * @param ProcessId
+ * @param ThreadId
+ * @param Context
+ * @param Params
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+SyscallCallbackStoreProcessInformation(UINT32 ProcessId,
+ UINT32 ThreadId,
+ UINT64 Context,
+ SYSCALL_CALLBACK_CONTEXT_PARAMS * Params)
+{
+ UINT32 Index;
+ BOOLEAN Result;
+ BOOLEAN SuccessfullyStored;
+ SYSCALL_CALLBACK_PROCESS_THREAD_INFORMATION ProcThrdInfo = {0};
+
+ //
+ // Form the process id and thread id into a 64-bit value
+ //
+ ProcThrdInfo.Fields.ProcessId = ProcessId;
+ ProcThrdInfo.Fields.ThreadId = ThreadId;
+
+ //
+ // Make sure, nobody is in the middle of modifying the list
+ //
+ SpinlockLock(&SyscallCallbackModeTrapListLock);
+
+ //
+ // *** Search the list of processes/threads for the current process's trap flag state ***
+ //
+ Result = BinarySearchPerformSearchItem((UINT64 *)&g_SyscallCallbackTrapFlagState->ThreadInformation[0],
+ g_SyscallCallbackTrapFlagState->NumberOfItems,
+ &Index,
+ ProcThrdInfo.asUInt);
+
+ if (Result)
+ {
+ //
+ // It means that we already find this entry in the stored list
+ // so, just imply that the addition was successful (no need for extra addition)
+ //
+ SuccessfullyStored = TRUE;
+ goto Return;
+ }
+ else
+ {
+ //
+ // Insert the thread into the list as the item is not already present
+ //
+ SuccessfullyStored = InsertionSortInsertItem((UINT64 *)&g_SyscallCallbackTrapFlagState->ThreadInformation[0],
+ &g_SyscallCallbackTrapFlagState->NumberOfItems,
+ MAXIMUM_NUMBER_OF_THREAD_INFORMATION_FOR_SYSCALL_CALLBACK_TRAPS,
+ &Index,
+ ProcThrdInfo.asUInt);
+
+ if (SuccessfullyStored)
+ {
+ //
+ // Successfully inserted the thread/process into the list
+ // Now let's store the context of the caller along with parameters
+ //
+ g_SyscallCallbackTrapFlagState->Context[Index] = Context;
+ memcpy(&g_SyscallCallbackTrapFlagState->Params[Index], Params, sizeof(SYSCALL_CALLBACK_CONTEXT_PARAMS));
+ }
+
+ goto Return;
+ }
+
+Return:
+ //
+ // Unlock the list modification lock
+ //
+ SpinlockUnlock(&SyscallCallbackModeTrapListLock);
+
+ return SuccessfullyStored;
+}
+
+/**
+ * @brief Set the trap flag in the guest after a syscall
+ *
+ * @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 BOOLEAN
+ */
+BOOLEAN
+SyscallCallbackSetTrapFlagAfterSyscall(GUEST_REGS * Regs,
+ UINT32 ProcessId,
+ UINT32 ThreadId,
+ UINT64 Context,
+ SYSCALL_CALLBACK_CONTEXT_PARAMS * Params)
+{
+ //
+ // Do not add anything to the list if the syscall callback is not enabled (or disabled by the user)
+ //
+ if (!g_SyscallCallbackStatus)
+ {
+ //
+ // syscall callback is not enabled
+ //
+ return FALSE;
+ }
+
+ //
+ // Insert the thread/process into the list of processes/threads
+ //
+ if (!SyscallCallbackStoreProcessInformation(ProcessId, ThreadId, Context, Params))
+ {
+ //
+ // Failed to store the process/thread information
+ //
+ return FALSE;
+ }
+
+ //
+ // *** Successfully stored the process/thread information ***
+ //
+
+ //
+ // Set the trap flag to TRUE because we want to intercept the thread again
+ // once it returns to the user-mode (SYSRET) instruction
+ //
+ // Here the RFLAGS is in the R11 register (See Intel manual about the SYSCALL register)
+ //
+ Regs->r11 |= X86_FLAGS_TF;
+
+ //
+ // Create log message for the syscall
+ //
+ // LogInfo("Syscall callback set trap flag for process: %x, thread: %x\n", ProcessId, ThreadId);
+
+ return TRUE;
+}
+
+/**
+ * @brief Handle the trap flags as the result of interception of the return of the
+ * system-call
+ *
+ * @param VCpu The virtual processor's state
+ * @param ProcessId The process id of the thread
+ * @param ThreadId The thread id of the thread
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+SyscallCallbackCheckAndHandleAfterSyscallTrapFlags(VIRTUAL_MACHINE_STATE * VCpu,
+ UINT32 ProcessId,
+ UINT32 ThreadId)
+{
+ RFLAGS Rflags = {0};
+ UINT32 Index;
+ UINT64 Context = NULL64_ZERO;
+ SYSCALL_CALLBACK_CONTEXT_PARAMS Params;
+ SYSCALL_CALLBACK_PROCESS_THREAD_INFORMATION ProcThrdInfo = {0};
+ BOOLEAN Result;
+ BOOLEAN ResultToReturn;
+
+ //
+ // Read the trap flag
+ //
+ Rflags.AsUInt = HvGetRflags();
+
+ if (!Rflags.TrapFlag)
+ {
+ //
+ // The trap flag is not set, so we don't need to do anything
+ //
+ return FALSE;
+ }
+
+ //
+ // Form the process id and thread id into a 64-bit value
+ //
+ ProcThrdInfo.Fields.ProcessId = ProcessId;
+ ProcThrdInfo.Fields.ThreadId = ThreadId;
+
+ //
+ // Make sure, nobody is in the middle of modifying the list
+ //
+ SpinlockLock(&SyscallCallbackModeTrapListLock);
+
+ //
+ // *** Search the list of processes/threads for the current process's trap flag state ***
+ //
+ Result = BinarySearchPerformSearchItem((UINT64 *)&g_SyscallCallbackTrapFlagState->ThreadInformation[0],
+ g_SyscallCallbackTrapFlagState->NumberOfItems,
+ &Index,
+ ProcThrdInfo.asUInt);
+
+ //
+ // Check whether this thread is expected to have trap flag
+ // by the syscall callback or not
+ //
+ if (Result)
+ {
+ //
+ // Read the context of the caller
+ //
+ Context = g_SyscallCallbackTrapFlagState->Context[Index];
+
+ //
+ // Read the (optional) parameters of the caller
+ //
+ memcpy(&Params, &g_SyscallCallbackTrapFlagState->Params[Index], sizeof(SYSCALL_CALLBACK_CONTEXT_PARAMS));
+
+ //
+ // Clear the trap flag from the RFLAGS register
+ //
+ HvSetRflagTrapFlag(FALSE);
+
+ //
+ // Remove the thread/process from the list of processes/threads
+ //
+ InsertionSortDeleteItem((UINT64 *)&g_SyscallCallbackTrapFlagState->ThreadInformation[0],
+ &g_SyscallCallbackTrapFlagState->NumberOfItems,
+ Index);
+
+ //
+ // Handled by the syscall callback
+ //
+ ResultToReturn = TRUE;
+
+ goto ReturnResult;
+ }
+ else
+ {
+ //
+ // Not related to the syscall callback
+ //
+ ResultToReturn = FALSE;
+
+ goto ReturnResult;
+ }
+
+ReturnResult:
+
+ //
+ // Unlock the list modification lock
+ //
+ SpinlockUnlock(&SyscallCallbackModeTrapListLock);
+
+ //
+ // Call the callback function to handle the trap flag if its needed
+ // Note that we call it here so we already unlocked the list lock
+ // to optimize the performance (avoid holding the lock for a long time)
+ //
+ if (ResultToReturn)
+ {
+ TransparentCallbackHandleAfterSyscall(VCpu->Regs, ProcessId, ThreadId, Context, &Params);
+ }
+
+ return ResultToReturn;
+}
+
+/**
+ * @brief Handle the system call hook callback
+ *
+ * @param VCpu The virtual processor's state
+ *
+ * @return VOID
+ */
+VOID
+SyscallCallbackHandleSystemCallHook(VIRTUAL_MACHINE_STATE * VCpu)
+{
+ TransparentHandleSystemCallHook(VCpu->Regs);
+}
diff --git a/hyperdbg/hprdbghv/code/interface/Callback.c b/hyperdbg/hyperhv/code/interface/Callback.c
similarity index 59%
rename from hyperdbg/hprdbghv/code/interface/Callback.c
rename to hyperdbg/hyperhv/code/interface/Callback.c
index bf1ae9f0..3598a9fc 100644
--- a/hyperdbg/hprdbghv/code/interface/Callback.c
+++ b/hyperdbg/hyperhv/code/interface/Callback.c
@@ -12,134 +12,6 @@
*/
#include "pch.h"
-/**
- * @brief routines callback for preparing and sending message to queue
- *
- * @param OperationCode
- * @param IsImmediateMessage
- * @param ShowCurrentSystemTime
- * @param Priority
- * @param Fmt
- * @param ...
- *
- * @return BOOLEAN
- */
-BOOLEAN
-LogCallbackPrepareAndSendMessageToQueue(UINT32 OperationCode,
- BOOLEAN IsImmediateMessage,
- BOOLEAN ShowCurrentSystemTime,
- BOOLEAN Priority,
- const char * Fmt,
- ...)
-{
- BOOLEAN Result;
- va_list ArgList;
-
- if (g_Callbacks.LogCallbackPrepareAndSendMessageToQueueWrapper == NULL)
- {
- //
- // Ignore sending message to queue
- //
- return FALSE;
- }
-
- va_start(ArgList, Fmt);
-
- Result = g_Callbacks.LogCallbackPrepareAndSendMessageToQueueWrapper(OperationCode,
- IsImmediateMessage,
- ShowCurrentSystemTime,
- Priority,
- Fmt,
- ArgList);
- va_end(ArgList);
-
- return Result;
-}
-
-/**
- * @brief routines callback for sending message to queue
- *
- * @param OperationCode
- * @param IsImmediateMessage
- * @param LogMessage
- * @param BufferLen
- * @param Priority
- *
- * @return BOOLEAN
- */
-BOOLEAN
-LogCallbackSendMessageToQueue(UINT32 OperationCode,
- BOOLEAN IsImmediateMessage,
- CHAR * LogMessage,
- UINT32 BufferLen,
- BOOLEAN Priority)
-{
- if (g_Callbacks.LogCallbackSendMessageToQueue == NULL)
- {
- //
- // Ignore sending message to queue
- //
- return FALSE;
- }
-
- return g_Callbacks.LogCallbackSendMessageToQueue(OperationCode,
- IsImmediateMessage,
- LogMessage,
- BufferLen,
- Priority);
-}
-
-/**
- * @brief routines callback for checking if buffer is full
- *
- * @param Priority
- *
- * @return BOOLEAN
- */
-BOOLEAN
-LogCallbackCheckIfBufferIsFull(BOOLEAN Priority)
-{
- if (g_Callbacks.LogCallbackCheckIfBufferIsFull == NULL)
- {
- //
- // Ignore sending message to queue
- //
- return FALSE;
- }
-
- return g_Callbacks.LogCallbackCheckIfBufferIsFull(Priority);
-}
-
-/**
- * @brief routines callback for sending buffer
- * @param OperationCode
- * @param Buffer
- * @param BufferLength
- * @param Priority
- *
- * @return BOOLEAN
- */
-BOOLEAN
-LogCallbackSendBuffer(_In_ UINT32 OperationCode,
- _In_reads_bytes_(BufferLength) PVOID Buffer,
- _In_ UINT32 BufferLength,
- _In_ BOOLEAN Priority)
-
-{
- if (g_Callbacks.LogCallbackSendBuffer == NULL)
- {
- //
- // Ignore sending buffer
- //
- return FALSE;
- }
-
- return g_Callbacks.LogCallbackSendBuffer(OperationCode,
- Buffer,
- BufferLength,
- Priority);
-}
-
/**
* @brief routines callback to trigger events
* @param EventType
@@ -214,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
*
@@ -328,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
*
@@ -371,28 +263,128 @@ DebuggingCallbackHandleDebugBreakpointException(UINT32 CoreId)
}
/**
- * @brief routine callback to handle conditional page-fault exception
+ * @brief routine callback to handle thread interception
*
* @param CoreId
- * @param Address
- * @param PageFaultErrorCode
*
* @return BOOLEAN
*/
BOOLEAN
-DebuggingCallbackConditionalPageFaultException(UINT32 CoreId,
- UINT64 Address,
- UINT32 PageFaultErrorCode)
+DebuggingCallbackCheckThreadInterception(UINT32 CoreId)
{
- if (g_Callbacks.DebuggingCallbackConditionalPageFaultException == NULL)
+ if (g_Callbacks.DebuggingCallbackCheckThreadInterception == NULL)
{
//
- // re-inject it to not disrupt system normal execution
+ // not handled by user debugger
//
return FALSE;
}
- return g_Callbacks.DebuggingCallbackConditionalPageFaultException(CoreId, Address, PageFaultErrorCode);
+ 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);
}
/**
@@ -415,25 +407,3 @@ InterceptionCallbackTriggerCr3ProcessChange(UINT32 CoreId)
g_Callbacks.InterceptionCallbackTriggerCr3ProcessChange(CoreId);
}
-
-/**
- * @brief routine callback to handle cr3 process change
- *
- * @param CoreId
- * @param NewCr3
- *
- * @return VOID
- */
-VOID
-InterceptionCallbackCr3VmexitsForThreadInterception(UINT32 CoreId, CR3_TYPE NewCr3)
-{
- if (g_Callbacks.AttachingHandleCr3VmexitsForThreadInterception == NULL)
- {
- //
- // ignore it
- //
- return;
- }
-
- g_Callbacks.AttachingHandleCr3VmexitsForThreadInterception(CoreId, NewCr3);
-}
diff --git a/hyperdbg/hprdbghv/code/interface/Configuration.c b/hyperdbg/hyperhv/code/interface/Configuration.c
similarity index 92%
rename from hyperdbg/hprdbghv/code/interface/Configuration.c
rename to hyperdbg/hyperhv/code/interface/Configuration.c
index aac5db27..7e14d51d 100644
--- a/hyperdbg/hprdbghv/code/interface/Configuration.c
+++ b/hyperdbg/hyperhv/code/interface/Configuration.c
@@ -20,11 +20,6 @@
VOID
ConfigureEnableMovToCr3ExitingOnAllProcessors()
{
- //
- // Indicate that the future #PFs should or should not be checked with user debugger
- //
- g_CheckPageFaultsAndMov2Cr3VmexitsWithUserDebugger = TRUE;
-
BroadcastEnableMovToCr3ExitingOnAllProcessors();
}
@@ -50,6 +45,18 @@ ConfigureUninitializeExecTrapOnAllProcessors()
ExecTrapUninitialize();
}
+/**
+ * @brief Apply the MBEC configuration from the kernel side
+ * @param CoreId The core id
+ *
+ * @return VOID
+ */
+VOID
+ConfigureExecTrapApplyMbecConfiguratinFromKernelSide(UINT32 CoreId)
+{
+ ExecTrapApplyMbecConfiguratinFromKernelSide(&g_GuestState[CoreId]);
+}
+
/**
* @brief Add the target process to the watching list
* @param ProcessId
@@ -115,11 +122,6 @@ ConfigureDirtyLoggingUninitializeOnAllProcessors()
VOID
ConfigureDisableMovToCr3ExitingOnAllProcessors()
{
- //
- // Indicate that the future #PFs should or should not be checked with user debugger
- //
- g_CheckPageFaultsAndMov2Cr3VmexitsWithUserDebugger = FALSE;
-
BroadcastDisableMovToCr3ExitingOnAllProcessors();
}
@@ -145,6 +147,34 @@ ConfigureDisableEferSyscallEventsOnAllProcessors()
BroadcastDisableEferSyscallEventsOnAllProcessors();
}
+/**
+ * @brief Remove all hooks from the hooked pages list using Hooking Tag
+ * @details Should be called from vmx non-root
+ *
+ * @param HookingTag The hooking tag to remove all hooks
+ *
+ * @return BOOLEAN If unhook was successful it returns true or if it was not successful returns false
+ */
+BOOLEAN
+ConfigureEptHookUnHookAllByHookingTag(UINT64 HookingTag)
+{
+ return EptHookUnHookAllByHookingTag(HookingTag);
+}
+
+/**
+ * @brief Remove single hook from the hooked pages by the given hooking tag
+ * @details Should be called from Vmx root-mode
+ *
+ * @param HookingTag The hooking tag to unhook
+ * @return BOOLEAN If unhook was successful it returns true or if it was not successful returns false
+ */
+BOOLEAN
+ConfigureEptHookUnHookSingleHookByHookingTagFromVmxRoot(UINT64 HookingTag,
+ EPT_SINGLE_HOOK_UNHOOKING_DETAILS * TargetUnhookingDetails)
+{
+ return EptHookUnHookSingleHookByHookingTagFromVmxRoot(HookingTag, TargetUnhookingDetails);
+}
+
/**
* @brief Remove single hook from the hooked pages list and invalidate TLB
* @details Should be called from vmx non-root
diff --git a/hyperdbg/hprdbghv/code/interface/DirectVmcall.c b/hyperdbg/hyperhv/code/interface/DirectVmcall.c
similarity index 100%
rename from hyperdbg/hprdbghv/code/interface/DirectVmcall.c
rename to hyperdbg/hyperhv/code/interface/DirectVmcall.c
diff --git a/hyperdbg/hprdbghv/code/interface/Dispatch.c b/hyperdbg/hyperhv/code/interface/Dispatch.c
similarity index 91%
rename from hyperdbg/hprdbghv/code/interface/Dispatch.c
rename to hyperdbg/hyperhv/code/interface/Dispatch.c
index cd09af16..3d7fdd9f 100644
--- a/hyperdbg/hprdbghv/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
*
@@ -199,7 +253,6 @@ DispatchEventTsc(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN IsRdtscp)
//
// As the context to event trigger, we send the false which means
// it's an rdtsc (for rdtscp we set Context to true)
- // Note : Using !tsc command in transparent-mode is not allowed
//
EventTriggerResult = VmmCallbackTriggerEvents(TSC_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
@@ -304,12 +357,11 @@ DispatchEventVmcall(VIRTUAL_MACHINE_STATE * VCpu)
* @param VCpu The virtual processor's state
* @param IsUserMode Whether the execution event caused by a switch from kernel-to-user
* or otherwise user-to-kernel
- * @param HandleState whether the state should be handled by dispatcher or not
*
* @return VOID
*/
VOID
-DispatchEventMode(VIRTUAL_MACHINE_STATE * VCpu, DEBUGGER_EVENT_MODE_TYPE TargetMode, BOOLEAN HandleState)
+DispatchEventMode(VIRTUAL_MACHINE_STATE * VCpu, DEBUGGER_EVENT_MODE_TYPE TargetMode)
{
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
BOOLEAN PostEventTriggerReq = FALSE;
@@ -320,23 +372,48 @@ DispatchEventMode(VIRTUAL_MACHINE_STATE * VCpu, DEBUGGER_EVENT_MODE_TYPE TargetM
if (g_ExecTrapInitialized)
{
//
- // Triggering the pre-event
+ // check for user-mode thread interception
//
- EventTriggerResult = VmmCallbackTriggerEvents(TRAP_EXECUTION_MODE_CHANGED,
- VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
- (PVOID)TargetMode,
- &PostEventTriggerReq,
- VCpu->Regs);
+ if (TargetMode == DEBUGGER_EVENT_MODE_TYPE_USER_MODE &&
+ DebuggingCallbackCheckThreadInterception(VCpu->CoreId))
+ {
+ //
+ // 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(),
+ // PsGetCurrentProcessId(),
+ // VCpu->LastVmexitRip);
+
+ //
+ // In this case, we need to short circuit the event, in user-mode debugger we
+ // prevent the execution by short-circuiting the event
+ //
+ EventTriggerResult = VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT;
+ }
+ else
+ {
+ //
+ // Triggering the pre-event
+ //
+ EventTriggerResult = VmmCallbackTriggerEvents(TRAP_EXECUTION_MODE_CHANGED,
+ VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
+ (PVOID)TargetMode,
+ &PostEventTriggerReq,
+ VCpu->Regs);
+ }
//
// Check whether we need to short-circuiting event emulation or not
//
- if (EventTriggerResult != VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT && HandleState)
+ if (EventTriggerResult != VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
//
// Handle the user-mode/kernel-mode execution trap event in the case of triggering event
//
- ExecTrapHandleMoveToAdjustedTrapState(VCpu, (UINT64)TargetMode);
+ ExecTrapHandleMoveToAdjustedTrapState(VCpu, TargetMode);
}
//
@@ -349,10 +426,7 @@ DispatchEventMode(VIRTUAL_MACHINE_STATE * VCpu, DEBUGGER_EVENT_MODE_TYPE TargetM
// Otherwise and if there is no event, we should handle the
// user-mode/kernel-mode execution trap normally
//
- if (HandleState)
- {
- ExecTrapHandleMoveToAdjustedTrapState(VCpu, (UINT64)TargetMode);
- }
+ ExecTrapHandleMoveToAdjustedTrapState(VCpu, TargetMode);
}
}
@@ -518,7 +592,7 @@ DispatchEventRdmsr(VIRTUAL_MACHINE_STATE * VCpu)
//
// Handle vm-exit and perform changes
//
- MsrHandleRdmsrVmexit(VCpu->Regs);
+ MsrHandleRdmsrVmexit(VCpu);
}
//
@@ -563,7 +637,7 @@ DispatchEventWrmsr(VIRTUAL_MACHINE_STATE * VCpu)
//
// Handle vm-exit and perform changes
//
- MsrHandleWrmsrVmexit(VCpu->Regs);
+ MsrHandleWrmsrVmexit(VCpu);
}
//
@@ -637,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;
}
@@ -776,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;
@@ -811,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;
}
@@ -900,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);
}
//
@@ -961,6 +1032,14 @@ DispatchEventHiddenHookExecCc(VIRTUAL_MACHINE_STATE * VCpu, PVOID Context)
{
BOOLEAN PostEventTriggerReq = FALSE;
+ //
+ // In syscall back, a hidden hook for the system call handler gets inserted
+ //
+ if (g_SyscallCallbackStatus && Context == g_SystemCallHookAddress)
+ {
+ SyscallCallbackHandleSystemCallHook(VCpu);
+ }
+
//
// Triggering the pre-event (This command only support the
// pre-event, the post-event doesn't make sense in this command)
diff --git a/hyperdbg/hprdbghv/code/interface/Export.c b/hyperdbg/hyperhv/code/interface/Export.c
similarity index 63%
rename from hyperdbg/hprdbghv/code/interface/Export.c
rename to hyperdbg/hyperhv/code/interface/Export.c
index 617cb85f..f959d642 100644
--- a/hyperdbg/hprdbghv/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,11 +870,23 @@ VmFuncVmxCompatibleStrlen(const CHAR * s)
* @return UINT32
*/
UINT32
-VmFuncVmxCompatibleWcslen(const wchar_t * s)
+VmFuncVmxCompatibleWcslen(const WCHAR * s)
{
return VmxCompatibleWcslen(s);
}
+/**
+ * @brief VMX-root compatible micro sleep
+ * @param Us Delay in micro seconds
+ *
+ * @return VOID
+ */
+VOID
+VmFuncVmxCompatibleMicroSleep(UINT64 Us)
+{
+ VmxCompatibleMicroSleep(Us);
+}
+
/**
* @brief Inject #PF and configure CR2 register
*
@@ -680,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);
}
@@ -731,7 +1005,21 @@ VmFuncEventInjectBreakpoint()
INT32
VmFuncVmxCompatibleStrcmp(const CHAR * Address1, const CHAR * Address2)
{
- return VmxCompatibleStrcmp(Address1, Address2);
+ return VmxCompatibleStrcmp(Address1, Address2, NULL_ZERO, FALSE);
+}
+
+/**
+ * @brief VMX-root compatible strncmp
+ * @param Address1
+ * @param Address2
+ * @param Num
+ *
+ * @return INT32
+ */
+INT32
+VmFuncVmxCompatibleStrncmp(const CHAR * Address1, const CHAR * Address2, SIZE_T Num)
+{
+ return VmxCompatibleStrcmp(Address1, Address2, Num, TRUE);
}
/**
@@ -742,9 +1030,23 @@ VmFuncVmxCompatibleStrcmp(const CHAR * Address1, const CHAR * Address2)
* @return INT32
*/
INT32
-VmFuncVmxCompatibleWcscmp(const wchar_t * Address1, const wchar_t * Address2)
+VmFuncVmxCompatibleWcscmp(const WCHAR * Address1, const WCHAR * Address2)
{
- return VmxCompatibleWcscmp(Address1, Address2);
+ return VmxCompatibleWcscmp(Address1, Address2, NULL_ZERO, FALSE);
+}
+
+/**
+ * @brief VMX-root compatible wcsncmp
+ * @param Address1
+ * @param Address2
+ * @param Num
+ *
+ * @return INT32
+ */
+INT32
+VmFuncVmxCompatibleWcsncmp(const WCHAR * Address1, const WCHAR * Address2, SIZE_T Num)
+{
+ return VmxCompatibleWcscmp(Address1, Address2, Num, TRUE);
}
/**
@@ -756,14 +1058,14 @@ VmFuncVmxCompatibleWcscmp(const wchar_t * Address1, const wchar_t * Address2)
* @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
*/
@@ -776,7 +1078,7 @@ VmFuncEnableMtfAndChangeExternalInterruptState(UINT32 CoreId)
/**
* @brief Checks to enable and reinject previous interrupts
*
- * @param UINT32 CoreId
+ * @param CoreId
*
* @return VOID
*/
@@ -785,3 +1087,58 @@ VmFuncEnableAndCheckForPreviousExternalInterrupts(UINT32 CoreId)
{
HvEnableAndCheckForPreviousExternalInterrupts(&g_GuestState[CoreId]);
}
+
+/**
+ * @brief Store the details Local APIC in xapic or x2apic modes
+ * @param LocalApicBuffer
+ * @param IsUsingX2APIC
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+VmFuncApicStoreLocalApicFields(PLAPIC_PAGE LocalApicBuffer, PBOOLEAN IsUsingX2APIC)
+{
+ return ApicStoreLocalApicFields(LocalApicBuffer, IsUsingX2APIC);
+}
+
+/**
+ * @brief Store the details of I/O APIC
+ * @param IoApicPackets
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+VmFuncApicStoreIoApicFields(IO_APIC_ENTRY_PACKETS * IoApicPackets)
+{
+ return ApicStoreIoApicFields(IoApicPackets);
+}
+
+/**
+ * @brief Perform query for IDT entries
+ *
+ * @param IdtQueryRequest
+ * @param ReadFromVmxRoot
+ *
+ * @return VOID
+ */
+VOID
+VmFuncIdtQueryEntries(PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS IdtQueryRequest,
+ BOOLEAN ReadFromVmxRoot)
+{
+ 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
new file mode 100644
index 00000000..2fb263c8
--- /dev/null
+++ b/hyperdbg/hyperhv/code/interface/HyperEvade.c
@@ -0,0 +1,159 @@
+/**
+ * @file HyperEvade.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @author jtaw5649
+ * @brief Hyperevade function wrappers
+ * @details
+ *
+ * @version 0.14
+ * @date 2025-06-07
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief Wrapper for hiding debugger on transparent-mode (activate transparent-mode)
+ *
+ * @param HyperevadeCallbacks
+ * @param TransparentModeRequest
+ *
+ * @return BOOLEAN
+ */
+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 ***
+ //
+
+ //
+ // Fill the callbacks for using hyperlog in hyperevade
+ // We use the callbacks directly to avoid two calls to the same function
+ //
+ HyperevadeCallbacks.LogCallbackPrepareAndSendMessageToQueueWrapper = g_Callbacks.LogCallbackPrepareAndSendMessageToQueueWrapper;
+ HyperevadeCallbacks.LogCallbackSendMessageToQueue = g_Callbacks.LogCallbackSendMessageToQueue;
+ HyperevadeCallbacks.LogCallbackSendBuffer = g_Callbacks.LogCallbackSendBuffer;
+ HyperevadeCallbacks.LogCallbackCheckIfBufferIsFull = g_Callbacks.LogCallbackCheckIfBufferIsFull;
+
+ //
+ // HyperTrace callback(s)
+ //
+ HyperevadeCallbacks.HyperTraceLbrIsSupported = HyperTraceCallbackLbrIsSupported;
+
+ //
+ // Memory callbacks
+ //
+ HyperevadeCallbacks.CheckAccessValidityAndSafety = CheckAccessValidityAndSafety;
+ HyperevadeCallbacks.MemoryMapperReadMemorySafeOnTargetProcess = MemoryMapperReadMemorySafeOnTargetProcess;
+ HyperevadeCallbacks.MemoryMapperWriteMemorySafeOnTargetProcess = MemoryMapperWriteMemorySafeOnTargetProcess;
+
+ //
+ // Common callbacks
+ //
+ HyperevadeCallbacks.CommonGetProcessNameFromProcessControlBlock = CommonGetProcessNameFromProcessControlBlock;
+
+ //
+ // System call callbacks
+ //
+ HyperevadeCallbacks.SyscallCallbackSetTrapFlagAfterSyscall = SyscallCallbackSetTrapFlagAfterSyscall;
+
+ //
+ // VMX callbacks
+ //
+ HyperevadeCallbacks.HvHandleTrapFlag = HvHandleTrapFlag;
+ HyperevadeCallbacks.EventInjectGeneralProtection = EventInjectGeneralProtection;
+
+ //
+ // 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
+ //
+ g_CheckForFootprints = TRUE;
+ return TRUE;
+ }
+ else
+ {
+ //
+ // Status is set within the transparent mode (hyperevade) module
+ //
+ g_CheckForFootprints = FALSE;
+ return FALSE;
+ }
+}
+
+/**
+ * @brief Deactivate transparent-mode
+ * @param TransparentModeRequest
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+TransparentUnhideDebuggerWrapper(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE * TransparentModeRequest)
+{
+ if (SyscallCallbackIsInitialized() && !SyscallCallbackUninitialize())
+ {
+ if (TransparentModeRequest != NULL)
+ {
+ TransparentModeRequest->KernelStatus = DEBUGGER_ERROR_UNABLE_TO_HIDE_OR_UNHIDE_DEBUGGER;
+ }
+
+ return FALSE;
+ }
+
+ if (TransparentUnhideDebugger())
+ {
+ //
+ // Unset transparent mode for the VMM module
+ //
+ g_CheckForFootprints = FALSE;
+
+ if (TransparentModeRequest != NULL)
+ {
+ TransparentModeRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ }
+
+ return TRUE;
+ }
+ else
+ {
+ if (TransparentModeRequest != NULL)
+ {
+ TransparentModeRequest->KernelStatus = DEBUGGER_ERROR_DEBUGGER_ALREADY_UNHIDE;
+ }
+ return FALSE;
+ }
+}
diff --git a/hyperdbg/hprdbghv/code/memory/AddressCheck.c b/hyperdbg/hyperhv/code/memory/AddressCheck.c
similarity index 86%
rename from hyperdbg/hprdbghv/code/memory/AddressCheck.c
rename to hyperdbg/hyperhv/code/memory/AddressCheck.c
index 851b1f69..4513ce01 100644
--- a/hyperdbg/hprdbghv/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
@@ -112,7 +112,7 @@ CheckAddressCanonicality(UINT64 VAddr, PBOOLEAN IsKernelAddress)
/**
* @brief Checks if the physical address is correct or not based on physical address width
*
- * @param VAddr Physical address to check
+ * @param PAddr Physical address to check
*
* @return BOOLEAN
*/
@@ -130,7 +130,7 @@ CheckAddressPhysical(UINT64 PAddr)
//
// get max address for physical address
//
- MaxPA = ((UINT64)1ull << (AddrWidth - 1)) - 1;
+ MaxPA = ((UINT64)1ull << (AddrWidth)) - 1;
// LogInfo("Max physical address: %llx", MaxPA);
@@ -146,14 +146,15 @@ CheckAddressPhysical(UINT64 PAddr)
}
/**
- * @brief Check the safety to access the memory
+ * @brief Check the safety to access the memory wrapper
* @param TargetAddress
* @param Size
+ * @param ProcessId NULL if the current process is used
*
* @return BOOLEAN
*/
BOOLEAN
-CheckAccessValidityAndSafety(UINT64 TargetAddress, UINT32 Size)
+CheckAccessValidityAndSafetyWrapper(UINT64 TargetAddress, UINT32 Size, UINT32 ProcessId)
{
CR3_TYPE GuestCr3;
UINT64 OriginalCr3;
@@ -173,16 +174,26 @@ CheckAccessValidityAndSafety(UINT64 TargetAddress, UINT32 Size)
goto Return;
}
- //
- // Find the current process cr3
- //
- GuestCr3.Flags = LayoutGetCurrentProcessCr3().Flags;
+ if (ProcessId == NULL_ZERO)
+ {
+ //
+ // Find the current process cr3
+ //
+ GuestCr3.Flags = LayoutGetCurrentProcessCr3().Flags;
+ }
+ else
+ {
+ //
+ // Find the target process cr3
+ //
+ GuestCr3.Flags = LayoutGetCr3ByProcessId(ProcessId).Flags;
+ }
//
// 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
@@ -199,7 +210,7 @@ CheckAccessValidityAndSafety(UINT64 TargetAddress, UINT32 Size)
// 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))
@@ -290,14 +301,42 @@ RestoreCr3:
//
// Move back to original cr3
//
- __writecr3(OriginalCr3);
+ CpuWriteCr3(OriginalCr3);
Return:
return Result;
}
/**
- * @brief This function returns the maximum instruction length that can be read from this address
+ * @brief Check the safety to access the memory
+ * @param TargetAddress
+ * @param Size
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+CheckAccessValidityAndSafety(UINT64 TargetAddress, UINT32 Size)
+{
+ return CheckAccessValidityAndSafetyWrapper(TargetAddress, Size, NULL_ZERO);
+}
+
+/**
+ * @brief Check the safety to access the memory by process ID
+ * @param TargetAddress
+ * @param Size
+ * @param ProcessId
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+CheckAccessValidityAndSafetyByProcessId(UINT64 TargetAddress, UINT32 Size, UINT32 ProcessId)
+{
+ return CheckAccessValidityAndSafetyWrapper(TargetAddress, Size, ProcessId);
+}
+
+/**
+ * @brief This function returns the maximum instruction length that
+ * can be read from this address
* @param Address
*
* @return UINT32
diff --git a/hyperdbg/hprdbghv/code/memory/Conversion.c b/hyperdbg/hyperhv/code/memory/Conversion.c
similarity index 100%
rename from hyperdbg/hprdbghv/code/memory/Conversion.c
rename to hyperdbg/hyperhv/code/memory/Conversion.c
diff --git a/hyperdbg/hprdbghv/code/memory/Layout.c b/hyperdbg/hyperhv/code/memory/Layout.c
similarity index 97%
rename from hyperdbg/hprdbghv/code/memory/Layout.c
rename to hyperdbg/hyperhv/code/memory/Layout.c
index 9631f749..a7b69139 100644
--- a/hyperdbg/hprdbghv/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/hprdbghv/code/memory/MemoryManager.c b/hyperdbg/hyperhv/code/memory/MemoryManager.c
similarity index 56%
rename from hyperdbg/hprdbghv/code/memory/MemoryManager.c
rename to hyperdbg/hyperhv/code/memory/MemoryManager.c
index 67e5ac4d..e9fd1c6a 100644
--- a/hyperdbg/hprdbghv/code/memory/MemoryManager.c
+++ b/hyperdbg/hyperhv/code/memory/MemoryManager.c
@@ -11,6 +11,63 @@
*/
#include "pch.h"
+/**
+ * @brief Read physical memory from the physical address (used in VMI mode)
+ *
+ * @param PhysicalAddress Physical Address
+ * @param Buffer Buffer to save the memory
+ * @param BufferSize Size of the buffer
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+ReadPhysicalMemoryUsingMapIoSpace(PVOID PhysicalAddress, PVOID Buffer, SIZE_T BufferSize)
+{
+ PHYSICAL_ADDRESS PhysicalAddressTemp = {0};
+ PhysicalAddressTemp.QuadPart = (LONGLONG)PhysicalAddress;
+
+ PVOID VirtualAddress = MmMapIoSpaceEx(PhysicalAddressTemp, BufferSize, PAGE_READWRITE | PAGE_NOCACHE);
+
+ if (VirtualAddress == NULL)
+ {
+ return FALSE;
+ }
+
+ RtlCopyMemory(Buffer, VirtualAddress, BufferSize);
+
+ MmUnmapIoSpace(VirtualAddress, BufferSize);
+
+ return TRUE;
+}
+
+/**
+ * @brief Write physical memory to the physical address (used in VMI mode)
+ *
+ * @param PhysicalAddress Physical Address
+ * @param Buffer Buffer to write to the memory
+ * @param BufferSize Size of the buffer
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+WritePhysicalMemoryUsingMapIoSpace(PVOID PhysicalAddress, PVOID Buffer, SIZE_T BufferSize)
+{
+ PHYSICAL_ADDRESS PhysicalAddressTemp = {0};
+ PhysicalAddressTemp.QuadPart = (LONGLONG)PhysicalAddress;
+
+ PVOID VirtualAddress = MmMapIoSpaceEx(PhysicalAddressTemp, BufferSize, PAGE_READWRITE | PAGE_NOCACHE);
+ if (VirtualAddress == NULL)
+ {
+ return FALSE;
+ }
+
+ RtlCopyMemory(VirtualAddress, Buffer, BufferSize);
+
+ MmUnmapIoSpace(VirtualAddress, BufferSize);
+
+ return TRUE;
+}
+
/**
* @brief Read process memory
*
@@ -113,7 +170,30 @@ MemoryManagerReadProcessMemoryNormal(HANDLE PID,
}
CopyAddress.PhysicalAddress.QuadPart = (LONGLONG)Address;
- MmCopyMemory(UserBuffer, CopyAddress, Size, MM_COPY_MEMORY_PHYSICAL, ReturnSize);
+
+ if (MmCopyMemory(UserBuffer, CopyAddress, Size, MM_COPY_MEMORY_PHYSICAL, ReturnSize) != STATUS_SUCCESS && *ReturnSize == 0)
+ {
+ //
+ // If the memory is not readable, it might be an MMIO address
+ // Try again with another method
+ //
+
+ // LogInfo("reading using MMIO Map IO Space using VMCALL");
+
+ if (AsmVmxVmcall(VMCALL_READ_PHYSICAL_MEMORY, (UINT64)Address, (UINT64)UserBuffer, (UINT64)Size) == STATUS_SUCCESS)
+ {
+ *ReturnSize = Size;
+ return TRUE;
+ }
+ else
+ {
+ //
+ // unknown error
+ //
+ *ReturnSize = 0;
+ return FALSE;
+ }
+ }
}
else
{
@@ -136,3 +216,29 @@ MemoryManagerReadProcessMemoryNormal(HANDLE PID,
}
}
}
+
+/**
+ * @brief Write process memory
+ *
+ * @details This function should not be called from vmx-root mode
+ *
+ * @param TargetAddress Target Address
+ * @param UserBuffer Buffer to write to the memory
+ * @param Size Size of the buffer
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+MemoryManagerWritePhysicalMemoryNormal(PVOID TargetAddress,
+ PVOID UserBuffer,
+ SIZE_T Size)
+{
+ if (AsmVmxVmcall(VMCALL_WRITE_PHYSICAL_MEMORY, (UINT64)TargetAddress, (UINT64)UserBuffer, (UINT64)Size) == STATUS_SUCCESS)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
diff --git a/hyperdbg/hprdbghv/code/memory/MemoryMapper.c b/hyperdbg/hyperhv/code/memory/MemoryMapper.c
similarity index 91%
rename from hyperdbg/hprdbghv/code/memory/MemoryMapper.c
rename to hyperdbg/hyperhv/code/memory/MemoryMapper.c
index 22c673dd..f95b1e13 100644
--- a/hyperdbg/hprdbghv/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
@@ -680,12 +680,12 @@ MemoryMapperInitialize()
//
// Allocate the memory buffer structure
//
- g_MemoryMapper = CrsAllocateZeroedNonPagedPool(sizeof(MEMORY_MAPPER_ADDRESSES) * ProcessorsCount);
+ g_MemoryMapper = PlatformMemAllocateZeroedNonPagedPool(sizeof(MEMORY_MAPPER_ADDRESSES) * ProcessorsCount);
//
// 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
@@ -922,13 +922,16 @@ MemoryMapperWriteMemorySafeByPte(PVOID SourceVA,
*
* @param TypeOfRead Type of read
* @param AddressToRead Physical Address to read
+ * @param TargetProcessId Target Process Id
+ *
* @return UINT64 returns the target physical address and NULL if it fails
*/
_Use_decl_annotations_
UINT64
MemoryMapperReadMemorySafeByPhysicalAddressWrapperAddressMaker(
MEMORY_MAPPER_WRAPPER_FOR_MEMORY_READ TypeOfRead,
- UINT64 AddressToRead)
+ UINT64 AddressToRead,
+ UINT32 TargetProcessId)
{
PHYSICAL_ADDRESS PhysicalAddress = {0};
@@ -946,6 +949,19 @@ MemoryMapperReadMemorySafeByPhysicalAddressWrapperAddressMaker(
break;
+ case MEMORY_MAPPER_WRAPPER_READ_VIRTUAL_MEMORY_UNSAFE:
+
+ if (TargetProcessId == NULL_ZERO)
+ {
+ PhysicalAddress.QuadPart = VirtualAddressToPhysicalAddress((PVOID)AddressToRead);
+ }
+ else
+ {
+ PhysicalAddress.QuadPart = VirtualAddressToPhysicalAddressByProcessId((PVOID)AddressToRead, TargetProcessId);
+ }
+
+ break;
+
default:
return NULL64_ZERO;
@@ -963,16 +979,19 @@ MemoryMapperReadMemorySafeByPhysicalAddressWrapperAddressMaker(
* @param AddressToRead Address to read
* @param BufferToSaveMemory Destination to save
* @param SizeToRead Size
+ * @param TargetProcessId The process pid
+ *
* @return BOOLEAN if it was successful the returns TRUE and if it was
* unsuccessful then it returns FALSE
*/
_Use_decl_annotations_
BOOLEAN
-MemoryMapperReadMemorySafeByPhysicalAddressWrapper(
+MemoryMapperReadMemorySafeWrapper(
MEMORY_MAPPER_WRAPPER_FOR_MEMORY_READ TypeOfRead,
UINT64 AddressToRead,
UINT64 BufferToSaveMemory,
- SIZE_T SizeToRead)
+ SIZE_T SizeToRead,
+ UINT32 TargetProcessId)
{
ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
UINT64 AddressToCheck;
@@ -1022,7 +1041,8 @@ MemoryMapperReadMemorySafeByPhysicalAddressWrapper(
// One access is enough (page+size won't pass from the PAGE_ALIGN boundary)
//
PhysicalAddress.QuadPart = MemoryMapperReadMemorySafeByPhysicalAddressWrapperAddressMaker(TypeOfRead,
- AddressToRead);
+ AddressToRead,
+ TargetProcessId);
if (!MemoryMapperReadMemorySafeByPte(
PhysicalAddress,
@@ -1051,7 +1071,8 @@ MemoryMapperReadMemorySafeByPhysicalAddressWrapper(
// One access is enough (page+size won't pass from the PAGE_ALIGN boundary)
//
PhysicalAddress.QuadPart = MemoryMapperReadMemorySafeByPhysicalAddressWrapperAddressMaker(TypeOfRead,
- AddressToRead);
+ AddressToRead,
+ TargetProcessId);
return MemoryMapperReadMemorySafeByPte(
PhysicalAddress,
@@ -1081,10 +1102,11 @@ MemoryMapperReadMemorySafeByPhysicalAddress(UINT64 PaAddressToRead,
//
// Call the wrapper
//
- return MemoryMapperReadMemorySafeByPhysicalAddressWrapper(MEMORY_MAPPER_WRAPPER_READ_PHYSICAL_MEMORY,
- PaAddressToRead,
- BufferToSaveMemory,
- SizeToRead);
+ return MemoryMapperReadMemorySafeWrapper(MEMORY_MAPPER_WRAPPER_READ_PHYSICAL_MEMORY,
+ PaAddressToRead,
+ BufferToSaveMemory,
+ SizeToRead,
+ NULL_ZERO);
}
/**
@@ -1100,10 +1122,33 @@ _Use_decl_annotations_
BOOLEAN
MemoryMapperReadMemorySafe(UINT64 VaAddressToRead, PVOID BufferToSaveMemory, SIZE_T SizeToRead)
{
- return MemoryMapperReadMemorySafeByPhysicalAddressWrapper(MEMORY_MAPPER_WRAPPER_READ_VIRTUAL_MEMORY,
- VaAddressToRead,
- (UINT64)BufferToSaveMemory,
- SizeToRead);
+ return MemoryMapperReadMemorySafeWrapper(MEMORY_MAPPER_WRAPPER_READ_VIRTUAL_MEMORY,
+ VaAddressToRead,
+ (UINT64)BufferToSaveMemory,
+ SizeToRead,
+ NULL_ZERO);
+}
+
+/**
+ * @brief Read memory unsafely by mapping the buffer (It's a wrapper)
+ *
+ * @param VaAddressToRead Virtual Address to read
+ * @param BufferToSaveMemory Destination to save
+ * @param SizeToRead Size
+ * @param TargetProcessId The process pid
+ *
+ * @return BOOLEAN if it was successful the returns TRUE and if it was
+ * unsuccessful then it returns FALSE
+ */
+_Use_decl_annotations_
+BOOLEAN
+MemoryMapperReadMemoryUnsafe(UINT64 VaAddressToRead, PVOID BufferToSaveMemory, SIZE_T SizeToRead, UINT32 TargetProcessId)
+{
+ return MemoryMapperReadMemorySafeWrapper(MEMORY_MAPPER_WRAPPER_READ_VIRTUAL_MEMORY_UNSAFE,
+ VaAddressToRead,
+ (UINT64)BufferToSaveMemory,
+ SizeToRead,
+ TargetProcessId);
}
/**
@@ -1135,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
@@ -1146,7 +1191,7 @@ MemoryMapperReadMemorySafeOnTargetProcess(UINT64 VaAddressToRead, PVOID BufferTo
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return Result;
}
@@ -1180,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
@@ -1191,7 +1236,7 @@ MemoryMapperWriteMemorySafeOnTargetProcess(UINT64 Destination, PVOID Source, SIZ
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return Result;
}
@@ -1675,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
@@ -1719,3 +1764,51 @@ MemoryMapperSetSupervisorBitWithoutSwitchingByCr3(PVOID Va, BOOLEAN Set, PAGING_
return TRUE;
}
+
+/**
+ * @brief Read physical memory safely from vmx non-root mode
+ *
+ * @param PaAddressToRead Physical Address to read
+ * @param BufferToSaveMemory Destination to save
+ * @param SizeToRead Size
+ *
+ * @return BOOLEAN whether was successful or not
+ */
+BOOLEAN
+MemoryMapperReadMemorySafeFromVmxNonRootByPhysicalAddress(UINT64 PaAddressToRead,
+ PVOID BufferToSaveMemory,
+ SIZE_T SizeToRead)
+{
+ if (AsmVmxVmcall(VMCALL_READ_PHYSICAL_MEMORY, (UINT64)PaAddressToRead, (UINT64)BufferToSaveMemory, (UINT64)SizeToRead) == STATUS_SUCCESS)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+/**
+ * @brief Write physical memory safely from vmx non-root mode
+ *
+ * @param DestinationVa Destination Virtual Address
+ * @param Source Source Address
+ * @param SizeToWrite Size
+ *
+ * @return BOOLEAN whether was successful or not
+ */
+BOOLEAN
+MemoryMapperWriteMemorySafeFromVmxNonRootyPhysicalAddress(UINT64 DestinationPa,
+ PVOID Source,
+ SIZE_T SizeToWrite)
+{
+ if (AsmVmxVmcall(VMCALL_WRITE_PHYSICAL_MEMORY, (UINT64)DestinationPa, (UINT64)Source, (UINT64)SizeToWrite) == STATUS_SUCCESS)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
diff --git a/hyperdbg/hyperhv/code/memory/Segmentation.c b/hyperdbg/hyperhv/code/memory/Segmentation.c
new file mode 100644
index 00000000..26b2f4aa
--- /dev/null
+++ b/hyperdbg/hyperhv/code/memory/Segmentation.c
@@ -0,0 +1,195 @@
+/**
+ * @file Segmentation.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Functions for handling memory segmentations
+ *
+ * @version 0.9
+ * @date 2024-06-03
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief Get Segment Descriptor
+ *
+ * @param SegmentSelector
+ * @param Selector
+ * @param GdtBase
+ * @return BOOLEAN
+ */
+_Use_decl_annotations_
+BOOLEAN
+SegmentGetDescriptor(PUCHAR GdtBase,
+ UINT16 Selector,
+ PVMX_SEGMENT_SELECTOR SegmentSelector)
+{
+ SEGMENT_DESCRIPTOR_32 * DescriptorTable32;
+ SEGMENT_DESCRIPTOR_32 * Descriptor32;
+ SEGMENT_SELECTOR SegSelector = {.AsUInt = Selector};
+
+ if (!SegmentSelector)
+ return FALSE;
+
+#define SELECTOR_TABLE_LDT 0x1
+#define SELECTOR_TABLE_GDT 0x0
+
+ //
+ // Ignore LDT
+ //
+ if ((Selector == 0x0) || (SegSelector.Table != SELECTOR_TABLE_GDT))
+ {
+ return FALSE;
+ }
+
+ DescriptorTable32 = (SEGMENT_DESCRIPTOR_32 *)(GdtBase);
+ Descriptor32 = &DescriptorTable32[SegSelector.Index];
+
+ SegmentSelector->Selector = Selector;
+ SegmentSelector->Limit = CpuSegmentLimit(Selector);
+ SegmentSelector->Base = ((UINT64)Descriptor32->BaseAddressLow | (UINT64)Descriptor32->BaseAddressMiddle << 16 | (UINT64)Descriptor32->BaseAddressHigh << 24);
+
+ SegmentSelector->Attributes.AsUInt = (AsmGetAccessRights(Selector) >> 8);
+
+ if (SegSelector.Table == 0 && SegSelector.Index == 0)
+ {
+ SegmentSelector->Attributes.Unusable = TRUE;
+ }
+
+ if ((Descriptor32->Type == SEGMENT_DESCRIPTOR_TYPE_TSS_BUSY) || (Descriptor32->Type == SEGMENT_DESCRIPTOR_TYPE_CALL_GATE))
+ {
+ //
+ // this is a TSS or callgate etc, save the base high part
+ //
+
+ UINT64 SegmentLimitHigh;
+ SegmentLimitHigh = (*(UINT64 *)((PUCHAR)Descriptor32 + 8));
+ SegmentSelector->Base = (SegmentSelector->Base & 0xffffffff) | (SegmentLimitHigh << 32);
+ }
+
+ if (SegmentSelector->Attributes.Granularity)
+ {
+ //
+ // 4096-bit granularity is enabled for this segment, scale the limit
+ //
+ SegmentSelector->Limit = (SegmentSelector->Limit << 12) + 0xfff;
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Initialize the host GDT
+ *
+ * @param OsGdtBase
+ * @param OsGdtLimit
+ * @param TrSelector
+ * @param HostStack
+ * @param AllocatedHostGdt
+ * @param AllocatedHostTss
+ *
+ * @return VOID
+ */
+VOID
+SegmentPrepareHostGdt(
+ SEGMENT_DESCRIPTOR_32 * OsGdtBase,
+ UINT16 OsGdtLimit,
+ UINT16 TrSelector,
+ UINT64 HostStack,
+ SEGMENT_DESCRIPTOR_32 * AllocatedHostGdt,
+ TASK_STATE_SEGMENT_64 * AllocatedHostTss)
+{
+ //
+ // Copy current OS GDT into host GDT
+ // Note that the limit is the maximum addressable byte offset within the segment,
+ // so the actual size of the GDT is limit + 1
+ //
+ RtlCopyBytes(AllocatedHostGdt, OsGdtBase, OsGdtLimit + 1);
+
+ //
+ // Make sure host TSS is empty
+ //
+ RtlZeroBytes(AllocatedHostTss, sizeof(TASK_STATE_SEGMENT_64));
+
+#if USE_INTERRUPT_STACK_TABLE == TRUE
+
+ UINT64 EndOfStack = 0;
+
+ //
+ // Setup TSS memory for host (same host stack is used for all interrupts and privilege levels)
+ //
+ EndOfStack = ((UINT64)HostStack + HOST_INTERRUPT_STACK_SIZE - 1);
+ EndOfStack = ((UINT64)((ULONG_PTR)(EndOfStack) & ~(16 - 1)));
+
+ LogDebugInfo("Host Interrupt Stack, from: %llx, to: %llx", HostStack, EndOfStack);
+
+ AllocatedHostTss->Rsp0 = EndOfStack;
+ AllocatedHostTss->Rsp1 = EndOfStack;
+ AllocatedHostTss->Rsp2 = EndOfStack;
+ AllocatedHostTss->Ist1 = EndOfStack;
+ AllocatedHostTss->Ist2 = EndOfStack;
+ AllocatedHostTss->Ist3 = EndOfStack;
+ AllocatedHostTss->Ist4 = EndOfStack;
+ AllocatedHostTss->Ist5 = EndOfStack;
+ AllocatedHostTss->Ist6 = EndOfStack;
+ AllocatedHostTss->Ist7 = EndOfStack;
+
+#else
+
+ UNREFERENCED_PARAMETER(HostStack);
+
+#endif // USE_INTERRUPT_STACK_TABLE == TRUE
+
+ //
+ // Setup the TSS segment descriptor
+ //
+ SEGMENT_DESCRIPTOR_64 * GdtTssDesc = (SEGMENT_DESCRIPTOR_64 *)&AllocatedHostGdt[TrSelector];
+
+ //
+ // Point the TSS descriptor to our TSS
+ //
+ UINT64 Base = (UINT64)AllocatedHostTss;
+ GdtTssDesc->BaseAddressLow = (Base >> 00) & 0xFFFF;
+ GdtTssDesc->BaseAddressMiddle = (Base >> 16) & 0xFF;
+ GdtTssDesc->BaseAddressHigh = (Base >> 24) & 0xFF;
+ GdtTssDesc->BaseAddressUpper = (Base >> 32) & 0xFFFFFFFF;
+
+ ////////////////////////////////////////////////////////////////////
+
+ // SEGMENT_SELECTOR HostCsSelector = {0, 0, 1};
+ // SEGMENT_SELECTOR HostTrSelector = {0, 0, 2};
+ //
+ // //
+ // // Setup the CS segment descriptor
+ // //
+ // SEGMENT_DESCRIPTOR_32 CsDesc = AllocatedHostGdt[HostCsSelector.Index];
+ // CsDesc.Type = SEGMENT_DESCRIPTOR_TYPE_CODE_EXECUTE_READ;
+ // CsDesc.DescriptorType = SEGMENT_DESCRIPTOR_TYPE_CODE_OR_DATA;
+ // CsDesc.DescriptorPrivilegeLevel = 0;
+ // CsDesc.Present = 1;
+ // CsDesc.LongMode = 1;
+ // CsDesc.DefaultBig = 0;
+ // CsDesc.Granularity = 0;
+ //
+ // //
+ // // Setup the TSS segment descriptor
+ // //
+ // SEGMENT_DESCRIPTOR_64 * TssDesc = (SEGMENT_DESCRIPTOR_64 *)&AllocatedHostGdt[HostTrSelector.Index];
+ // TssDesc->Type = SEGMENT_DESCRIPTOR_TYPE_TSS_BUSY;
+ // TssDesc->DescriptorType = SEGMENT_DESCRIPTOR_TYPE_SYSTEM;
+ // TssDesc->DescriptorPrivilegeLevel = 0;
+ // TssDesc->Present = 1;
+ // TssDesc->Granularity = 0;
+ // TssDesc->SegmentLimitLow = 0x67;
+ // TssDesc->SegmentLimitHigh = 0;
+ //
+ // //
+ // // Point the TSS descriptor to our TSS
+ // //
+ // UINT64 Base = (UINT64)AllocatedHostTss;
+ // TssDesc->BaseAddressLow = (Base >> 00) & 0xFFFF;
+ // TssDesc->BaseAddressMiddle = (Base >> 16) & 0xFF;
+ // TssDesc->BaseAddressHigh = (Base >> 24) & 0xFF;
+ // TssDesc->BaseAddressUpper = (Base >> 32) & 0xFFFFFFFF;
+}
diff --git a/hyperdbg/hprdbghv/code/memory/SwitchLayout.c b/hyperdbg/hyperhv/code/memory/SwitchLayout.c
similarity index 90%
rename from hyperdbg/hprdbghv/code/memory/SwitchLayout.c
rename to hyperdbg/hyperhv/code/memory/SwitchLayout.c
index 6865fca4..b02ba8f2 100644
--- a/hyperdbg/hprdbghv/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/mmio/MmioShadowing.c b/hyperdbg/hyperhv/code/mmio/MmioShadowing.c
new file mode 100644
index 00000000..68f77ff5
--- /dev/null
+++ b/hyperdbg/hyperhv/code/mmio/MmioShadowing.c
@@ -0,0 +1,21 @@
+/**
+ * @file MmioShadowing.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Functions for MMIO shadowing
+ *
+ * @version 0.14
+ * @date 2025-02-25
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+VOID
+MmioShadowingInitialize(
+ PVOID MmioPhysicalAddress,
+ ULONG64 Size)
+{
+ UNREFERENCED_PARAMETER(MmioPhysicalAddress);
+ UNREFERENCED_PARAMETER(Size);
+}
diff --git a/hyperdbg/hyperhv/code/processor/Idt.c b/hyperdbg/hyperhv/code/processor/Idt.c
new file mode 100644
index 00000000..989d3763
--- /dev/null
+++ b/hyperdbg/hyperhv/code/processor/Idt.c
@@ -0,0 +1,42 @@
+/**
+ * @file Idt.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Routines for Interrupt Descriptor Table
+ * @details
+ *
+ * @version 0.11
+ * @date 2024-11-20
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief Dump IDT Table based on current core
+ *
+ * @return VOID
+ */
+VOID
+IdtDumpInterruptEntries()
+{
+ KDESCRIPTOR64 descr;
+ CpuSidt(&descr.Limit);
+
+ ULONG n = (descr.Limit + 1) / sizeof(KIDTENTRY64);
+
+ if (n > 0)
+ {
+ int i = 0;
+ KIDTENTRY64 * pidte = (KIDTENTRY64 *)descr.Base;
+
+ do
+ {
+ ULONG_PTR addr = ((ULONG_PTR)pidte->OffsetHigh << 32) +
+ ((ULONG_PTR)pidte->OffsetMiddle << 16) + pidte->OffsetLow;
+
+ LogInfo("Interrupt %u -> %p\n", i++, addr);
+
+ } while (pidte++, --n);
+ }
+}
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/hprdbghv/code/vmm/ept/Ept.c b/hyperdbg/hyperhv/code/vmm/ept/Ept.c
similarity index 82%
rename from hyperdbg/hprdbghv/code/vmm/ept/Ept.c
rename to hyperdbg/hyperhv/code/vmm/ept/Ept.c
index 2b5f1f99..4295aca0 100644
--- a/hyperdbg/hprdbghv/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
@@ -520,6 +541,18 @@ EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable,
EntryTemplate.WriteAccess = 1;
EntryTemplate.ExecuteAccess = 1;
+ //
+ // Set the UserModeExecute bit based on the global state of MBEC
+ //
+ if (g_ModeBasedExecutionControlState)
+ {
+ EntryTemplate.UserModeExecute = 1;
+ }
+ else
+ {
+ EntryTemplate.UserModeExecute = 0;
+ }
+
//
// copy other bits from target entry
//
@@ -530,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
@@ -547,10 +580,23 @@ EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable,
//
// Allocate a new pointer which will replace the 2MB entry with a pointer to 512 4096 byte entries
//
- NewPointer.AsUInt = 0;
- NewPointer.WriteAccess = 1;
- NewPointer.ReadAccess = 1;
- NewPointer.ExecuteAccess = 1;
+ NewPointer.AsUInt = 0;
+ NewPointer.WriteAccess = 1;
+ NewPointer.ReadAccess = 1;
+ NewPointer.ExecuteAccess = 1;
+
+ //
+ // Set the UserModeExecute bit based on the global state of MBEC
+ //
+ if (g_ModeBasedExecutionControlState)
+ {
+ NewPointer.UserModeExecute = 1;
+ }
+ else
+ {
+ NewPointer.UserModeExecute = 0;
+ }
+
NewPointer.PageFrameNumber = (SIZE_T)VirtualAddressToPhysicalAddress(&NewSplit->PML1[0]) / PAGE_SIZE;
//
@@ -558,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;
}
@@ -602,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
@@ -621,15 +671,10 @@ EptSetupPML2Entry(PVMM_EPT_PAGE_TABLE EptPageTable, PEPT_PML2_ENTRY NewEntry, SI
}
else
{
- TargetBuffer = (PVOID)CrsAllocateNonPagedPool(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);
}
}
@@ -642,7 +687,8 @@ PVMM_EPT_PAGE_TABLE
EptAllocateAndCreateIdentityPageTable(VOID)
{
PVMM_EPT_PAGE_TABLE PageTable;
- EPT_PML3_POINTER RWXTemplate;
+ EPT_PML3_POINTER PML3Template;
+ EPT_PML3_ENTRY PML3TemplateLarge;
EPT_PML2_ENTRY PML2EntryTemplate;
SIZE_T EntryGroupIndex;
SIZE_T EntryIndex;
@@ -655,7 +701,7 @@ EptAllocateAndCreateIdentityPageTable(VOID)
// Allocate address anywhere in the OS's memory space and
// zero out all entries to ensure all unused entries are marked Not Present
//
- PageTable = CrsAllocateContiguousZeroedMemory(sizeof(VMM_EPT_PAGE_TABLE));
+ PageTable = PlatformMemAllocateContiguousZeroedMemory(sizeof(VMM_EPT_PAGE_TABLE));
if (PageTable == NULL)
{
@@ -664,13 +710,37 @@ EptAllocateAndCreateIdentityPageTable(VOID)
}
//
- // Mark the first 512GB PML4 entry as present, which allows us to manage up
- // to 512GB of discrete paging structures.
+ // Keep track of dynamic 2MB->4KB split metadata for this EPT table.
//
- PageTable->PML4[0].PageFrameNumber = (SIZE_T)VirtualAddressToPhysicalAddress(&PageTable->PML3[0]) / PAGE_SIZE;
- PageTable->PML4[0].ReadAccess = 1;
- PageTable->PML4[0].WriteAccess = 1;
- PageTable->PML4[0].ExecuteAccess = 1;
+ InitializeListHead(&PageTable->DynamicSplitList);
+
+ //
+ // Create the template for the first entry in the PML4
+ //
+ PageTable->PML4[0].ReadAccess = 1;
+ PageTable->PML4[0].WriteAccess = 1;
+ PageTable->PML4[0].ExecuteAccess = 1;
+
+ //
+ // Copy the template into each of the 512 PML4 entry slots
+ //
+ 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++)
+ {
+ if (i == 0)
+ {
+ //
+ // Mark the first 512GB PML4 entry as present, which allows us to manage up
+ // to 512GB of discrete paging structures and also set other reserved bits
+ //
+ PageTable->PML4[0].PageFrameNumber = (SIZE_T)VirtualAddressToPhysicalAddress(&PageTable->PML3[0]) / PAGE_SIZE;
+ }
+ else
+ {
+ PageTable->PML4[i].PageFrameNumber = (SIZE_T)VirtualAddressToPhysicalAddress(&PageTable->PML3_RSVD[i - 1][0]) / PAGE_SIZE;
+ }
+ }
//
// Now mark each 1GB PML3 entry as RWX and map each to their PML2 entry
@@ -679,20 +749,35 @@ EptAllocateAndCreateIdentityPageTable(VOID)
//
// Ensure stack memory is cleared
//
- RWXTemplate.AsUInt = 0;
+ PML3Template.AsUInt = 0;
+ PML3TemplateLarge.AsUInt = 0;
//
// Set up one 'template' RWX PML3 entry and copy it into each of the 512 PML3 entries
- // Using the same method as SimpleVisor for copying each entry using intrinsics.
+ // Using the same method as SimpleVisor for copying each entry using intrinsics
//
- RWXTemplate.ReadAccess = 1;
- RWXTemplate.WriteAccess = 1;
- RWXTemplate.ExecuteAccess = 1;
+ PML3Template.ReadAccess = 1;
+ PML3Template.WriteAccess = 1;
+ PML3Template.ExecuteAccess = 1;
+
+ PML3TemplateLarge.LargePage = 1;
+ PML3TemplateLarge.ReadAccess = 1;
+ PML3TemplateLarge.WriteAccess = 1;
+ PML3TemplateLarge.ExecuteAccess = 1;
+ PML3TemplateLarge.MemoryType = MEMORY_TYPE_UNCACHEABLE;
//
- // Copy the template into each of the 512 PML3 entry slots
+ // Copy the template into each of the 512 PML3 entry slots for the original entries
//
- __stosq((SIZE_T *)&PageTable->PML3[0], RWXTemplate.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++)
+ {
+ CpuStosQ((SIZE_T *)&PageTable->PML3_RSVD[i][0], PML3TemplateLarge.AsUInt, VMM_EPT_PML3E_COUNT);
+ }
//
// For each of the 512 PML3 entries
@@ -700,12 +785,33 @@ EptAllocateAndCreateIdentityPageTable(VOID)
for (EntryIndex = 0; EntryIndex < VMM_EPT_PML3E_COUNT; EntryIndex++)
{
//
- // Map the 1GB PML3 entry to 512 PML2 (2MB) entries to describe each large page.
- // NOTE: We do *not* manage any PML1 (4096 byte) entries and do not allocate them.
+ // Map the 1GB PML3 entry to 512 PML2 (2MB) entries to describe each large page
+ // NOTE: We do *not* manage any PML1 (4096 byte) entries and do not allocate them
//
PageTable->PML3[EntryIndex].PageFrameNumber = (SIZE_T)VirtualAddressToPhysicalAddress(&PageTable->PML2[EntryIndex][0]) / PAGE_SIZE;
}
+ //
+ // 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 j = 0; j < VMM_EPT_PML3E_COUNT; j++)
+ {
+ //
+ // Map the 1GB PML3 reserved entry to 512 PML3 (1GB) entries to describe each large page
+ // NOTE: We do *not* manage them since they are reserved for out of 512 GB MMIO ranges
+ // The first 512GB is used for the main system memory and the rest is reserved for MMIO
+ //
+ PageTable->PML3_RSVD[i][j].PageFrameNumber = (SIZE_512_GB + // First 512GB is used for system memory
+ (i * SIZE_512_GB) + (j * SIZE_1_GB)) >> // MMIO ranges
+ 30; // Convert to page frame number
+ }
+ }
+
+ //
+ // Now we will set up the PML2 entries, which are 2MB large pages
+ //
PML2EntryTemplate.AsUInt = 0;
//
@@ -725,9 +831,9 @@ EptAllocateAndCreateIdentityPageTable(VOID)
// mark it RWX using the same template above.
// This marks the entries as "Present" regardless of if the actual system has memory at
// 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.
+ // 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
@@ -767,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
@@ -779,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)
{
@@ -1007,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))
{
//
@@ -1047,7 +1153,7 @@ EptHandleMisconfiguration(VOID)
{
UINT64 GuestPhysicalAddr = 0;
- __vmx_vmread(VMCS_GUEST_PHYSICAL_ADDRESS, &GuestPhysicalAddr);
+ VmxVmread64P(VMCS_GUEST_PHYSICAL_ADDRESS, &GuestPhysicalAddr);
LogInfo("EPT Misconfiguration!");
@@ -1130,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)
{
@@ -1216,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/hprdbghv/code/vmm/ept/Invept.c b/hyperdbg/hyperhv/code/vmm/ept/Invept.c
similarity index 100%
rename from hyperdbg/hprdbghv/code/vmm/ept/Invept.c
rename to hyperdbg/hyperhv/code/vmm/ept/Invept.c
diff --git a/hyperdbg/hprdbghv/code/vmm/ept/Vpid.c b/hyperdbg/hyperhv/code/vmm/ept/Vpid.c
similarity index 93%
rename from hyperdbg/hprdbghv/code/vmm/ept/Vpid.c
rename to hyperdbg/hyperhv/code/vmm/ept/Vpid.c
index a4874c4d..cd587b57 100644
--- a/hyperdbg/hprdbghv/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/hprdbghv/code/vmm/vmx/Counters.c b/hyperdbg/hyperhv/code/vmm/vmx/Counters.c
similarity index 95%
rename from hyperdbg/hprdbghv/code/vmm/vmx/Counters.c
rename to hyperdbg/hyperhv/code/vmm/vmx/Counters.c
index 9506dc6c..d1493c49 100644
--- a/hyperdbg/hprdbghv/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/hprdbghv/code/vmm/vmx/CrossVmexits.c b/hyperdbg/hyperhv/code/vmm/vmx/CrossVmexits.c
similarity index 61%
rename from hyperdbg/hprdbghv/code/vmm/vmx/CrossVmexits.c
rename to hyperdbg/hyperhv/code/vmm/vmx/CrossVmexits.c
index 2be2e500..aa24a0c0 100644
--- a/hyperdbg/hprdbghv/code/vmm/vmx/CrossVmexits.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/CrossVmexits.c
@@ -20,7 +20,27 @@
VOID
VmxHandleXsetbv(VIRTUAL_MACHINE_STATE * VCpu)
{
- _xsetbv(VCpu->Regs->rcx & 0xffffffff, VCpu->Regs->rdx << 32 | VCpu->Regs->rax);
+ CPUID_EAX_01 CpuidInfo;
+ VMX_SEGMENT_SELECTOR GuestCs = GetGuestCs();
+ UINT32 XCrIndex = VCpu->Regs->rcx & 0xffffffff;
+ XCR0 XCr0 = {.AsUInt = VCpu->Regs->rdx << 32 | VCpu->Regs->rax};
+ CR4 GuestCr4 = {.AsUInt = GetGuestCr4()};
+
+ if (XCrIndex != 0 || GuestCs.Attributes.DescriptorPrivilegeLevel != 0 || !CommonIsXCr0Valid(XCr0))
+ {
+ EventInjectGeneralProtection();
+ return;
+ }
+
+ CommonCpuidInstruction(CPUID_VERSION_INFORMATION, 0, (INT32 *)&CpuidInfo);
+
+ if (CpuidInfo.CpuidFeatureInformationEcx.XsaveXrstorInstruction == 0 || GuestCr4.OsXsave == 0)
+ {
+ EventInjectUndefinedOpcode(VCpu);
+ return;
+ }
+
+ _xsetbv(XCrIndex, XCr0.AsUInt);
}
/**
diff --git a/hyperdbg/hprdbghv/code/vmm/vmx/Events.c b/hyperdbg/hyperhv/code/vmm/vmx/Events.c
similarity index 95%
rename from hyperdbg/hprdbghv/code/vmm/vmx/Events.c
rename to hyperdbg/hyperhv/code/vmm/vmx/Events.c
index ae20e937..34bee0dc 100644
--- a/hyperdbg/hprdbghv/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
@@ -86,6 +86,23 @@ EventInjectUndefinedOpcode(VIRTUAL_MACHINE_STATE * VCpu)
HvSuppressRipIncrement(VCpu);
}
+/**
+ * @brief Inject NMI to the guest (Event Injection)
+ * @param VCpu The virtual processor's state
+ *
+ * @return VOID
+ */
+VOID
+EventInjectNmi(VIRTUAL_MACHINE_STATE * VCpu)
+{
+ EventInjectInterruption(INTERRUPT_TYPE_NMI, EXCEPTION_VECTOR_NMI, FALSE, 0);
+
+ //
+ // Suppress RIP increment
+ //
+ HvSuppressRipIncrement(VCpu);
+}
+
/**
* @brief Inject Debug Breakpoint Exception
*
@@ -111,7 +128,7 @@ EventInjectPageFaultWithoutErrorCode(UINT64 PageFaultAddress)
//
// Write the page-fault address
//
- __writecr2(PageFaultAddress);
+ CpuWriteCr2(PageFaultAddress);
//
// Make the error code
@@ -184,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/hprdbghv/code/vmm/vmx/Hv.c b/hyperdbg/hyperhv/code/vmm/vmx/Hv.c
similarity index 72%
rename from hyperdbg/hprdbghv/code/vmm/vmx/Hv.c
rename to hyperdbg/hyperhv/code/vmm/vmx/Hv.c
index b40a3f9c..155ced78 100644
--- a/hyperdbg/hprdbghv/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;
@@ -42,7 +42,7 @@ BOOLEAN
HvSetGuestSelector(PVOID GdtBase, UINT32 SegmentRegister, UINT16 Selector)
{
VMX_SEGMENT_SELECTOR SegmentSelector = {0};
- VmxGetSegmentDescriptor(GdtBase, Selector, &SegmentSelector);
+ SegmentGetDescriptor(GdtBase, Selector, &SegmentSelector);
if (Selector == 0x0)
{
@@ -73,14 +73,14 @@ 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
// if we are in transparent mode then ignore the
// cpuid modifications e.g. hyperviosr name or bit
//
- if (!g_TransparentMode)
+ if (!g_CheckForFootprints)
{
//
// Check if this was CPUID 1h, which is the features request
@@ -116,6 +116,10 @@ HvHandleCpuid(VIRTUAL_MACHINE_STATE * VCpu)
CpuInfo[1] = CpuInfo[2] = CpuInfo[3] = 0;
}
}
+ else
+ {
+ TransparentCheckAndModifyCpuid(Regs, CpuInfo);
+ }
//
// Copy the values from the logical processor registers into the VP GPRs
@@ -154,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;
}
*/
@@ -194,14 +198,6 @@ HvHandleControlRegisterAccess(VIRTUAL_MACHINE_STATE * VCpu,
//
InterceptionCallbackTriggerCr3ProcessChange(VCpu->CoreId);
- //
- // Call user debugger handler of thread intercepting mechanism
- //
- if (g_CheckPageFaultsAndMov2Cr3VmexitsWithUserDebugger)
- {
- InterceptionCallbackCr3VmexitsForThreadInterception(VCpu->CoreId, NewCr3Reg);
- }
-
//
// Call handler of the reversing machine
//
@@ -233,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;
@@ -277,7 +273,7 @@ HvFillGuestSelectorData(PVOID GdtBase, UINT32 SegmentRegister, UINT16 Selector)
{
VMX_SEGMENT_SELECTOR SegmentSelector = {0};
- VmxGetSegmentDescriptor(GdtBase, Selector, &SegmentSelector);
+ SegmentGetDescriptor(GdtBase, Selector, &SegmentSelector);
if (Selector == 0x0)
{
@@ -303,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;
@@ -357,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;
}
//
@@ -395,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;
//
@@ -410,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;
//
@@ -441,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);
}
/**
@@ -468,34 +496,50 @@ HvRestoreRegisters()
UINT64 GdtrLimit;
UINT64 IdtrBase;
UINT64 IdtrLimit;
+ UINT16 DsSelector;
+ UINT16 EsSelector;
+ UINT16 SsSelector;
+ UINT16 FsSelector;
//
// 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
+ //
+ VmxVmread16P(VMCS_GUEST_DS_SELECTOR, &DsSelector);
+ AsmSetDs(DsSelector);
+ VmxVmread16P(VMCS_GUEST_ES_SELECTOR, &EsSelector);
+ AsmSetEs(EsSelector);
+ VmxVmread16P(VMCS_GUEST_SS_SELECTOR, &SsSelector);
+ AsmSetSs(SsSelector);
+ VmxVmread16P(VMCS_GUEST_FS_SELECTOR, &FsSelector);
+ AsmSetFs(FsSelector);
//
// 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);
}
/**
@@ -517,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;
}
//
@@ -617,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;
}
//
@@ -725,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;
}
//
@@ -848,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;
@@ -874,7 +918,10 @@ HvHandleMovDebugRegister(VIRTUAL_MACHINE_STATE * VCpu)
// 32 bits results in a #GP(0) exception.
// (ref: Vol3B[17.2.6(Debug Registers and Intel 64 Processors)])
//
- if (ExitQualification.DirectionOfAccess == VMX_EXIT_QUALIFICATION_DIRECTION_MOV_TO_DR && (ExitQualification.DebugRegister == VMX_EXIT_QUALIFICATION_REGISTER_DR6 || ExitQualification.DebugRegister == VMX_EXIT_QUALIFICATION_REGISTER_DR7) && (GpRegister >> 32) != 0)
+ if (ExitQualification.DirectionOfAccess == VMX_EXIT_QUALIFICATION_DIRECTION_MOV_TO_DR &&
+ (ExitQualification.DebugRegister == VMX_EXIT_QUALIFICATION_REGISTER_DR6 ||
+ ExitQualification.DebugRegister == VMX_EXIT_QUALIFICATION_REGISTER_DR7) &&
+ (GpRegister >> 32) != 0)
{
EventInjectGeneralProtection();
@@ -891,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;
@@ -917,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;
@@ -963,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;
}
//
@@ -997,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;
}
//
@@ -1064,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
*/
@@ -1137,7 +1183,7 @@ HvGetCsSelector()
//
UINT64 CsSel = NULL64_ZERO;
- __vmx_vmread(VMCS_GUEST_CS_SELECTOR, &CsSel);
+ VmxVmread64P(VMCS_GUEST_CS_SELECTOR, &CsSel);
return CsSel & 0xffff;
}
@@ -1152,7 +1198,7 @@ HvGetRflags()
{
UINT64 Rflags = NULL64_ZERO;
- __vmx_vmread(VMCS_GUEST_RFLAGS, &Rflags);
+ VmxVmread64P(VMCS_GUEST_RFLAGS, &Rflags);
return Rflags;
}
@@ -1179,7 +1225,7 @@ HvGetRip()
{
UINT64 Rip = NULL64_ZERO;
- __vmx_vmread(VMCS_GUEST_RIP, &Rip);
+ VmxVmread64P(VMCS_GUEST_RIP, &Rip);
return Rip;
}
@@ -1206,7 +1252,7 @@ HvGetInterruptibilityState()
{
UINT64 InterruptibilityState = NULL64_ZERO;
- __vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY_STATE, &InterruptibilityState);
+ VmxVmread64P(VMCS_GUEST_INTERRUPTIBILITY_STATE, &InterruptibilityState);
return InterruptibilityState;
}
@@ -1366,7 +1412,10 @@ HvInitVmm(VMM_CALLBACKS * VmmCallbacks)
//
// Make sure that transparent-mode is disabled
//
- g_TransparentMode = FALSE;
+ if (g_CheckForFootprints)
+ {
+ TransparentUnhideDebuggerWrapper(NULL);
+ }
//
// Not waiting for the interrupt-window to inject page-faults
@@ -1441,3 +1490,294 @@ HvPreventExternalInterrupts(VIRTUAL_MACHINE_STATE * VCpu)
//
VCpu->EnableExternalInterruptsOnContinueMtf = TRUE;
}
+
+/**
+ * @brief Get the guest state of pending debug exceptions
+ *
+ * @return UINT64
+ */
+UINT64
+HvGetPendingDebugExceptions()
+{
+ UINT64 Value;
+ VmxVmread64P(VMCS_GUEST_PENDING_DEBUG_EXCEPTIONS, &Value);
+
+ return Value;
+}
+
+/**
+ * @brief Set the guest state of pending debug exceptions
+ * @param Value The new state
+ *
+ * @return VOID
+ */
+VOID
+HvSetPendingDebugExceptions(UINT64 Value)
+{
+ VmxVmwrite64(VMCS_GUEST_PENDING_DEBUG_EXCEPTIONS, Value);
+}
+
+/**
+ * @brief Get the guest state of IA32_DEBUGCTL
+ *
+ * @return UINT64
+ */
+UINT64
+HvGetDebugctl()
+{
+ UINT32 LowPart;
+ UINT32 HighPart;
+
+ VmxVmread32P(VMCS_GUEST_DEBUGCTL, &LowPart);
+ VmxVmread32P(VMCS_GUEST_DEBUGCTL_HIGH, &HighPart);
+
+ 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
+ *
+ * @return VOID
+ */
+VOID
+HvSetDebugctl(UINT64 Value)
+{
+ 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);
+}
+
+/**
+ * @brief Handle the case when the trap flag is set, and
+ * we need to inject the single-step exception right
+ * after vm-entry
+ *
+ * @return VOID
+ */
+VOID
+HvHandleTrapFlag()
+{
+ IA32_DEBUGCTL_REGISTER Debugctl = {.AsUInt = HvGetDebugctl()};
+ RFLAGS GuestRFlags = {.AsUInt = GetGuestRFlags()};
+ VMX_PENDING_DEBUG_EXCEPTIONS PendingDebugExceptions;
+ VMX_INTERRUPTIBILITY_STATE InterruptibilityState;
+
+ //
+ // The btf flag means that the trap flag generates the single-step exception
+ // only for branch instructions
+ //
+ if (GuestRFlags.TrapFlag && !Debugctl.Btf)
+ {
+ PendingDebugExceptions.AsUInt = HvGetPendingDebugExceptions();
+ PendingDebugExceptions.Bs = 1;
+ HvSetPendingDebugExceptions(PendingDebugExceptions.AsUInt);
+
+ InterruptibilityState.AsUInt = (UINT32)HvGetInterruptibilityState();
+
+ //
+ // We also must clear this flag in case of instruction emulation to achieve
+ // correctness of the single-step exception
+ //
+ if (InterruptibilityState.BlockingByMovSs)
+ {
+ InterruptibilityState.BlockingByMovSs = 0;
+ HvSetInterruptibilityState(InterruptibilityState.AsUInt);
+ }
+ }
+}
diff --git a/hyperdbg/hprdbghv/code/vmm/vmx/IdtEmulation.c b/hyperdbg/hyperhv/code/vmm/vmx/IdtEmulation.c
similarity index 51%
rename from hyperdbg/hprdbghv/code/vmm/vmx/IdtEmulation.c
rename to hyperdbg/hyperhv/code/vmm/vmx/IdtEmulation.c
index 0019ebfb..09226007 100644
--- a/hyperdbg/hprdbghv/code/vmm/vmx/IdtEmulation.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/IdtEmulation.c
@@ -11,6 +11,279 @@
*/
#include "pch.h"
+/**
+ * @brief Perform query for IDT entries
+ *
+ * @param IdtQueryRequest
+ * @param ReadFromVmxRoot
+ *
+ * @return VOID
+ */
+VOID
+IdtEmulationQueryIdtEntriesRequest(PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS IdtQueryRequest,
+ BOOLEAN ReadFromVmxRoot)
+{
+ SIDT_ENTRY IdtrReg;
+ KIDT_ENTRY * IdtEntries;
+
+ //
+ // Read IDTR register
+ //
+
+ if (!ReadFromVmxRoot)
+ {
+ //
+ // Since it's not in VMX Root, we can directly read the IDTR register
+ //
+ CpuSidt(&IdtrReg);
+
+ //
+ // Get the IDT base address
+ //
+ IdtEntries = (KIDT_ENTRY *)IdtrReg.IdtBase;
+ }
+ else
+ {
+ //
+ // Since it's in VMX Root, we need to read the IDTR register from the VMCS
+ //
+ IdtEntries = (KIDT_ENTRY *)GetGuestIdtr();
+ }
+
+ //
+ // Gather a list of IDT entries
+ //
+ for (UINT32 i = 0; i < MAX_NUMBER_OF_IDT_ENTRIES; i++)
+ {
+ IdtQueryRequest->IdtEntry[i] = (UINT64)((UINT64)IdtEntries[i].HighestPart << 32) |
+ ((UINT64)IdtEntries[i].HighPart << 16) |
+ (UINT64)IdtEntries[i].LowPart;
+ }
+}
+
+/**
+ * @brief Create an interrupt gate that points to the supplied interrupt handler
+ *
+ * @param VCpu The virtual processor's state
+ * @param Entry
+ *
+ * @return VOID
+ */
+VOID
+IdtEmulationCreateInterruptGate(PVOID Handler, SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64 * Entry)
+{
+ // SEGMENT_SELECTOR HostCsSelector = {0, 0, 1};
+ //
+ // Entry->InterruptStackTable = 0;
+ // Entry->SegmentSelector = HostCsSelector.AsUInt;
+ // Entry->MustBeZero0 = 0;
+ // Entry->Type = SEGMENT_DESCRIPTOR_TYPE_INTERRUPT_GATE;
+ // Entry->MustBeZero1 = 0;
+ // Entry->DescriptorPrivilegeLevel = 0;
+ // Entry->Present = 1;
+ // Entry->Reserved = 0;
+
+ UINT64 Offset = (UINT64)Handler;
+ Entry->OffsetLow = (Offset >> 0) & 0xFFFF;
+ Entry->OffsetMiddle = (Offset >> 16) & 0xFFFF;
+ Entry->OffsetHigh = (Offset >> 32) & 0xFFFFFFFF;
+
+#if USE_INTERRUPT_STACK_TABLE == TRUE
+
+ //
+ // Use first index (IST1)
+ //
+ Entry->InterruptStackTable = 1;
+
+#else
+
+ //
+ // Make sure to unset IST since we didn't use a separate stack pointer
+ // on TSS entry at GDT
+ //
+ Entry->InterruptStackTable = 0;
+
+#endif // USE_INTERRUPT_STACK_TABLE == TRUE
+}
+
+/**
+ * @brief Prepare Host IDT
+ *
+ * @param VCpu The virtual processor's state
+ *
+ * @return VOID
+ */
+VOID
+IdtEmulationPrepareHostIdt(_Inout_ VIRTUAL_MACHINE_STATE * VCpu)
+{
+ SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64 * VmxHostIdt = (SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64 *)VCpu->HostIdt;
+ SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64 * WindowsIdt = (SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64 *)AsmGetIdtBase();
+
+ //
+ // Zero the memory
+ //
+ RtlZeroMemory(VmxHostIdt, HOST_IDT_DESCRIPTOR_COUNT * sizeof(SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64));
+
+ //
+ // Copy OS interrupt (IDT) entries
+ //
+ RtlCopyBytes(VmxHostIdt,
+ WindowsIdt,
+ HOST_IDT_DESCRIPTOR_COUNT * sizeof(SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64));
+
+ /*
+ for (SIZE_T i = 0; i < HOST_IDT_DESCRIPTOR_COUNT; i++)
+ {
+ SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64 CurrentEntry = WindowsIdt[i];
+
+ UINT64 Offset = 0;
+ Offset |= ((UINT64)CurrentEntry.OffsetLow) << 0;
+ Offset |= ((UINT64)CurrentEntry.OffsetMiddle) << 16;
+ Offset |= ((UINT64)CurrentEntry.OffsetHigh) << 32;
+
+ // LogInfo("IDT Entry [%d] at: %llx", i, Offset);
+
+ IdtEmulationCreateInterruptGate((PVOID)Offset, &VmxHostIdt[i]);
+ }
+ */
+
+ //
+ // Function related to handling host IDT are a modified version of the following project:
+ // https://github.com/jonomango/hv/blob/main/hv
+ //
+
+ //
+ // Add customize interrupt handlers
+ //
+ IdtEmulationCreateInterruptGate((PVOID)InterruptHandler0, &VmxHostIdt[EXCEPTION_VECTOR_DIVIDE_ERROR]);
+ // IdtEmulationCreateInterruptGate((PVOID)InterruptHandler1, &VmxHostIdt[EXCEPTION_VECTOR_DEBUG_BREAKPOINT]); // #DB
+ IdtEmulationCreateInterruptGate((PVOID)InterruptHandler2, &VmxHostIdt[EXCEPTION_VECTOR_NMI]);
+ // IdtEmulationCreateInterruptGate((PVOID)InterruptHandler3, &VmxHostIdt[EXCEPTION_VECTOR_BREAKPOINT]); // #BP
+ IdtEmulationCreateInterruptGate((PVOID)InterruptHandler4, &VmxHostIdt[EXCEPTION_VECTOR_OVERFLOW]);
+ IdtEmulationCreateInterruptGate((PVOID)InterruptHandler5, &VmxHostIdt[EXCEPTION_VECTOR_BOUND_RANGE_EXCEEDED]);
+ IdtEmulationCreateInterruptGate((PVOID)InterruptHandler6, &VmxHostIdt[EXCEPTION_VECTOR_UNDEFINED_OPCODE]);
+ IdtEmulationCreateInterruptGate((PVOID)InterruptHandler7, &VmxHostIdt[EXCEPTION_VECTOR_NO_MATH_COPROCESSOR]);
+ IdtEmulationCreateInterruptGate((PVOID)InterruptHandler8, &VmxHostIdt[EXCEPTION_VECTOR_DOUBLE_FAULT]);
+ IdtEmulationCreateInterruptGate((PVOID)InterruptHandler10, &VmxHostIdt[EXCEPTION_VECTOR_INVALID_TASK_SEGMENT_SELECTOR]);
+ IdtEmulationCreateInterruptGate((PVOID)InterruptHandler11, &VmxHostIdt[EXCEPTION_VECTOR_SEGMENT_NOT_PRESENT]);
+ IdtEmulationCreateInterruptGate((PVOID)InterruptHandler12, &VmxHostIdt[EXCEPTION_VECTOR_STACK_SEGMENT_FAULT]);
+ IdtEmulationCreateInterruptGate((PVOID)InterruptHandler13, &VmxHostIdt[EXCEPTION_VECTOR_GENERAL_PROTECTION_FAULT]);
+ // IdtEmulationCreateInterruptGate((PVOID)InterruptHandler14, &VmxHostIdt[EXCEPTION_VECTOR_PAGE_FAULT]); // #PF
+ IdtEmulationCreateInterruptGate((PVOID)InterruptHandler16, &VmxHostIdt[EXCEPTION_VECTOR_MATH_FAULT]);
+ IdtEmulationCreateInterruptGate((PVOID)InterruptHandler17, &VmxHostIdt[EXCEPTION_VECTOR_ALIGNMENT_CHECK]);
+ IdtEmulationCreateInterruptGate((PVOID)InterruptHandler18, &VmxHostIdt[EXCEPTION_VECTOR_MACHINE_CHECK]);
+ IdtEmulationCreateInterruptGate((PVOID)InterruptHandler19, &VmxHostIdt[EXCEPTION_VECTOR_SIMD_FLOATING_POINT_NUMERIC_ERROR]);
+ IdtEmulationCreateInterruptGate((PVOID)InterruptHandler20, &VmxHostIdt[EXCEPTION_VECTOR_VIRTUAL_EXCEPTION]);
+ IdtEmulationCreateInterruptGate((PVOID)InterruptHandler30, &VmxHostIdt[EXCEPTION_VECTOR_RESERVED11]);
+}
+
+/**
+ * @brief Handle Page-fault exception bitmap VM-exits
+ *
+ * @param VCpu The virtual processor's state
+ * @param InterruptExit interrupt exit information
+ *
+ * @return VOID
+ */
+VOID
+IdtEmulationhandleHostInterrupt(_Inout_ INTERRUPT_TRAP_FRAME * IntrTrapFrame)
+{
+ UINT64 PageFaultCr2;
+ ULONG CurrentCore;
+ BOOLEAN Interruptible;
+ VMX_INTERRUPTIBILITY_STATE InterruptibilityState = {0};
+ CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
+ VIRTUAL_MACHINE_STATE * VCpu = &g_GuestState[CurrentCore];
+
+ //
+ // Store the latest exception vector
+ //
+ VCpu->LastExceptionOccurredInHost = IntrTrapFrame->vector;
+
+ switch (IntrTrapFrame->vector)
+ {
+ case EXCEPTION_VECTOR_NMI:
+
+ //
+ // host NMIs
+ //
+ // LogInfo("NMI received!");
+
+ //
+ // Check if NMI needs to be injected back to the guest or not
+ // Trap frame is sent because as this function unreference this
+ // parameter, NULL cannot be sent
+ //
+ if (!VmxBroadcastHandleNmiCallback((PVOID)IntrTrapFrame, FALSE))
+ {
+ //
+ // 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
+ //
+ // For the future reference, I think using NMI Windows Exiting
+ // here is also not useful but in theory it should serve as a
+ // backup plan if the system is not ready to receive NMIs, then
+ // we could inject it when the NMI Window is open but in reality
+ // it will corrupt the VMCS layout (VMRESUME 0x7 error)
+ //
+
+ //
+ // Check if interruptibility state allows NMIs or not
+ //
+ VmxVmread32P(VMCS_GUEST_INTERRUPTIBILITY_STATE, &InterruptibilityState.AsUInt);
+
+ Interruptible = !InterruptibilityState.BlockingByNmi;
+
+ if (Interruptible)
+ {
+ //
+ // Re-inject the NMI
+ //
+ EventInjectNmi(VCpu);
+ }
+ else
+ {
+ //
+ // Inject NMI when the NMI Window opened
+ //
+ HvSetNmiWindowExiting(TRUE);
+ }
+ }
+
+ break;
+
+ case EXCEPTION_VECTOR_PAGE_FAULT:
+
+ //
+ // host page-fault
+ //
+ PageFaultCr2 = CpuReadCr2();
+
+ LogInfo("Page-fault received, rip: %llx, rsp: %llx, error: %llx, CR2: %llx",
+ IntrTrapFrame->rip,
+ IntrTrapFrame->rsp,
+ IntrTrapFrame->error,
+ PageFaultCr2);
+
+ break;
+
+ default:
+
+ //
+ // host exceptions
+ //
+ LogInfo("Host exception, rip: %llx, rsp: %llx, error: %llx, vector: %x",
+ IntrTrapFrame->rip,
+ IntrTrapFrame->rsp,
+ IntrTrapFrame->error,
+ IntrTrapFrame->vector);
+ DbgBreakPoint();
+
+ break;
+ }
+}
+
/**
* @brief Handle Page-fault exception bitmap VM-exits
*
@@ -36,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,
@@ -46,18 +319,10 @@ IdtEmulationHandlePageFaults(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
// PageFaultErrorCode.UserModeAccess ? "u" : "",
// PageFaultErrorCode.Execute ? "f" : "");
- // Handle page-faults
- // Check page-fault with user-debugger
- // The page-fault is handled through the user debugger, no need further action
- // NOTE: THE ADDRESS SHOULD BE NULL HERE
//
- if (!DebuggingCallbackConditionalPageFaultException(VCpu->CoreId, PageFaultAddress, PageFaultErrorCode.AsUInt))
- {
- //
- // The #pf is not related to the debugger, re-inject it
- //
- EventInjectPageFaults(VCpu, InterruptExit, PageFaultAddress, PageFaultErrorCode);
- }
+ // Handle page-faults
+ //
+ EventInjectPageFaults(VCpu, InterruptExit, PageFaultAddress, PageFaultErrorCode);
}
/**
@@ -91,8 +356,10 @@ 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)
{
if (!DebuggingCallbackHandleBreakpointException(VCpu->CoreId))
@@ -138,7 +405,23 @@ IdtEmulationHandleExceptionAndNmi(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
case EXCEPTION_VECTOR_DEBUG_BREAKPOINT:
- if (!DebuggingCallbackHandleDebugBreakpointException(VCpu->CoreId))
+ //
+ // Check if syscall callback is enabled and if so, then we need to
+ // check whether the this trap flag is set because of intercepting
+ // the result of a system-call or not
+ //
+ if (g_SyscallCallbackStatus &&
+ SyscallCallbackCheckAndHandleAfterSyscallTrapFlags(VCpu,
+ HANDLE_TO_UINT32(PsGetCurrentProcessId()),
+ HANDLE_TO_UINT32(PsGetCurrentThreadId())))
+ {
+ //
+ // Being here means that this #DB was caused by a trap flag of
+ // the system-call in the syscall callback, so no need to further handle
+ // it (nothing to do)
+ //
+ }
+ else if (!DebuggingCallbackHandleDebugBreakpointException(VCpu->CoreId))
{
//
// It's not because of thread change detection, so re-inject it
@@ -152,7 +435,7 @@ IdtEmulationHandleExceptionAndNmi(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
if (VCpu->EnableExternalInterruptsOnContinue ||
VCpu->EnableExternalInterruptsOnContinueMtf ||
- VCpu->RegisterBreakOnMtf)
+ VCpu->InstrumentationStepInMtf)
{
//
// Ignore the nmi
@@ -198,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
@@ -235,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
//
@@ -321,9 +604,15 @@ IdtEmulationHandleExternalInterrupt(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
VOID
IdtEmulationHandleNmiWindowExiting(_Inout_ VIRTUAL_MACHINE_STATE * VCpu)
{
- UNREFERENCED_PARAMETER(VCpu);
+ //
+ // Inject the NMI into the guest
+ //
+ EventInjectNmi(VCpu);
- LogError("Why NMI-window exiting happens?");
+ //
+ // Disable NMI-window exiting since we have no more NMIs to inject
+ //
+ HvSetNmiWindowExiting(FALSE);
}
/**
@@ -388,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/hprdbghv/code/vmm/vmx/IoHandler.c b/hyperdbg/hyperhv/code/vmm/vmx/IoHandler.c
similarity index 91%
rename from hyperdbg/hprdbghv/code/vmm/vmx/IoHandler.c
rename to hyperdbg/hyperhv/code/vmm/vmx/IoHandler.c
index b506b337..77daa753 100644
--- a/hyperdbg/hprdbghv/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/hprdbghv/code/vmm/vmx/ManageRegs.c b/hyperdbg/hyperhv/code/vmm/vmx/ManageRegs.c
similarity index 87%
rename from hyperdbg/hprdbghv/code/vmm/vmx/ManageRegs.c
rename to hyperdbg/hyperhv/code/vmm/vmx/ManageRegs.c
index 6127d337..ad816203 100644
--- a/hyperdbg/hprdbghv/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/hprdbghv/code/vmm/vmx/MsrHandlers.c b/hyperdbg/hyperhv/code/vmm/vmx/MsrHandlers.c
similarity index 70%
rename from hyperdbg/hprdbghv/code/vmm/vmx/MsrHandlers.c
rename to hyperdbg/hyperhv/code/vmm/vmx/MsrHandlers.c
index 70f5a0e7..2600002a 100644
--- a/hyperdbg/hprdbghv/code/vmm/vmx/MsrHandlers.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/MsrHandlers.c
@@ -11,17 +11,62 @@
*/
#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
*
- * @param GuestRegs Guest's gp registers
+ * @param VCpu The virtual processor's state
+ *
* @return VOID
*/
VOID
-MsrHandleRdmsrVmexit(PGUEST_REGS GuestRegs)
+MsrHandleRdmsrVmexit(VIRTUAL_MACHINE_STATE * VCpu)
{
- MSR Msr = {0};
- UINT32 TargetMsr;
+ UINT32 TargetMsr;
+ MSR Msr = {0};
+ PGUEST_REGS GuestRegs = VCpu->Regs;
//
// RDMSR. The RDMSR instruction causes a VM exit if any of the following are true:
@@ -48,6 +93,23 @@ MsrHandleRdmsrVmexit(PGUEST_REGS GuestRegs)
// results.
//
+ // LogInfo("MSR read (RDMSR) VM-exit, MSR: %x, from: %llx",
+ // 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
//
@@ -108,7 +170,7 @@ MsrHandleRdmsrVmexit(PGUEST_REGS GuestRegs)
//
// 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
@@ -117,10 +179,18 @@ MsrHandleRdmsrVmexit(PGUEST_REGS GuestRegs)
return;
}
+ //
+ // Check for the footprints of the RDMSR in the transparent mode
+ //
+ if (g_CheckForFootprints && TransparentCheckAndModifyMsrRead(VCpu->Regs, TargetMsr))
+ {
+ return;
+ }
+
//
// Msr is valid
//
- Msr.Flags = __readmsr(TargetMsr);
+ Msr.Flags = CpuReadMsr(TargetMsr);
//
// Check if it's EFER MSR then we show a false SCE state
@@ -155,15 +225,17 @@ MsrHandleRdmsrVmexit(PGUEST_REGS GuestRegs)
/**
* @brief Handles in the cases when RDMSR causes a vm-exit
*
- * @param GuestRegs Guest's gp registers
+ * @param VCpu The virtual processor's state
+ *
* @return VOID
*/
VOID
-MsrHandleWrmsrVmexit(PGUEST_REGS GuestRegs)
+MsrHandleWrmsrVmexit(VIRTUAL_MACHINE_STATE * VCpu)
{
- MSR Msr = {0};
- UINT32 TargetMsr;
- BOOLEAN UnusedIsKernel;
+ UINT32 TargetMsr;
+ BOOLEAN UnusedIsKernel;
+ MSR Msr = {0};
+ PGUEST_REGS GuestRegs = VCpu->Regs;
//
// Execute WRMSR or RDMSR on behalf of the guest. Important that this
@@ -182,6 +254,21 @@ MsrHandleWrmsrVmexit(PGUEST_REGS GuestRegs)
Msr.Fields.Low = (ULONG)GuestRegs->rax;
Msr.Fields.High = (ULONG)GuestRegs->rdx;
+ // LogInfo("MSR write (WRMSR) VM-exit, MSR: %x, rax: %llx, rdx: %llx, from: %llx",
+ // TargetMsr,
+ // GuestRegs->rax,
+ // 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
//
@@ -245,10 +332,19 @@ MsrHandleWrmsrVmexit(PGUEST_REGS GuestRegs)
default:
+ //
+ // Check for the footprints of the WRMSR in the transparent mode
+ //
+ if (g_CheckForFootprints && TransparentCheckAndModifyMsrWrite(VCpu->Regs, TargetMsr))
+ {
+ return;
+ }
+
//
// Perform the WRMSR
//
- __writemsr((unsigned long)GuestRegs->rcx, Msr.Flags);
+ CpuWriteMsr((ULONG)GuestRegs->rcx, Msr.Flags);
+
break;
}
}
@@ -286,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
@@ -335,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
@@ -373,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);
}
/**
@@ -395,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));
}
/**
@@ -426,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
@@ -455,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
@@ -473,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
@@ -502,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/hprdbghv/code/vmm/vmx/Mtf.c b/hyperdbg/hyperhv/code/vmm/vmx/Mtf.c
similarity index 53%
rename from hyperdbg/hprdbghv/code/vmm/vmx/Mtf.c
rename to hyperdbg/hyperhv/code/vmm/vmx/Mtf.c
index bbd66d46..c8a004d0 100644
--- a/hyperdbg/hprdbghv/code/vmm/vmx/Mtf.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/Mtf.c
@@ -33,12 +33,9 @@ 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))
{
//
// MTF is handled
@@ -67,53 +64,11 @@ MtfHandleVmexit(VIRTUAL_MACHINE_STATE * VCpu)
VCpu->MtfEptHookRestorePoint = NULL;
//
- // Check for reenabling external interrupts
+ // Check for re-enabling external interrupts
//
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/hprdbghv/code/vmm/vmx/ProtectedHv.c b/hyperdbg/hyperhv/code/vmm/vmx/ProtectedHv.c
similarity index 77%
rename from hyperdbg/hprdbghv/code/vmm/vmx/ProtectedHv.c
rename to hyperdbg/hyperhv/code/vmm/vmx/ProtectedHv.c
index 7b937b04..171e30e2 100644
--- a/hyperdbg/hprdbghv/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
@@ -42,11 +42,12 @@ ProtectedHvChangeExceptionBitmapWithIntegrityCheck(VIRTUAL_MACHINE_STATE * VCpu,
}
//
- // Check for #PF by thread interception mechanism in user debugger
+ // Check for syscall callback (masking #DBs and #BPs)
//
- if (g_CheckPageFaultsAndMov2Cr3VmexitsWithUserDebugger)
+ if (g_SyscallCallbackStatus)
{
- CurrentMask |= 1 << EXCEPTION_VECTOR_PAGE_FAULT;
+ CurrentMask |= 1 << EXCEPTION_VECTOR_DEBUG_BREAKPOINT;
+ CurrentMask |= 1 << EXCEPTION_VECTOR_BREAKPOINT;
}
//
@@ -214,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
//
@@ -231,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;
}
//
@@ -304,17 +305,6 @@ ProtectedHvSetTscVmexit(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set, PROTECTED_HV_
{
return;
}
-
- //
- // Check if transparent mode is enabled
- //
- if (g_TransparentMode)
- {
- //
- // We should ignore it as we want this bit on transparent mode
- //
- return;
- }
}
//
@@ -324,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
@@ -378,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;
}
//
@@ -409,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
{
@@ -422,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
{
@@ -503,17 +493,6 @@ ProtectedHvSetMovToCr3Vmexit(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set, PROTECTE
return;
}
- //
- // Check if use debugger is in intercepting phase for threads or not
- //
- if (g_CheckPageFaultsAndMov2Cr3VmexitsWithUserDebugger)
- {
- //
- // The user debugger needs mov2cr3s
- //
- return;
- }
-
//
// Check if the trap execution is enabled or not, and whether the
// uninitialization phase started or not
@@ -534,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;
}
//
@@ -547,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/hprdbghv/code/vmm/vmx/Vmcall.c b/hyperdbg/hyperhv/code/vmm/vmx/Vmcall.c
similarity index 76%
rename from hyperdbg/hprdbghv/code/vmm/vmx/Vmcall.c
rename to hyperdbg/hyperhv/code/vmm/vmx/Vmcall.c
index c897528a..88f6d560 100644
--- a/hyperdbg/hprdbghv/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;
}
@@ -458,9 +458,159 @@ VmxVmcallHandler(VIRTUAL_MACHINE_STATE * VCpu,
VmcallStatus = STATUS_SUCCESS;
break;
}
+ case VMCALL_READ_PHYSICAL_MEM_BYPASS_CACHING_POLICIES:
+ {
+ if (ReadPhysicalMemoryUsingMapIoSpace((PVOID)OptionalParam1, (PVOID)OptionalParam2, (SIZE_T)OptionalParam3))
+ {
+ VmcallStatus = STATUS_SUCCESS;
+ }
+ else
+ {
+ VmcallStatus = STATUS_UNSUCCESSFUL;
+ }
+
+ break;
+ }
+ case VMCALL_WRITE_PHYSICAL_MEM_BYPASS_CACHING_POLICIES:
+ {
+ if (WritePhysicalMemoryUsingMapIoSpace((PVOID)OptionalParam1, (PVOID)OptionalParam2, (SIZE_T)OptionalParam3))
+ {
+ VmcallStatus = STATUS_SUCCESS;
+ }
+ else
+ {
+ VmcallStatus = STATUS_UNSUCCESSFUL;
+ }
+
+ break;
+ }
+ case VMCALL_READ_PHYSICAL_MEMORY:
+ {
+ //
+ // Check whether the physical memory is valid or not
+ //
+ if (!CheckAddressPhysical(OptionalParam1))
+ {
+ VmcallStatus = STATUS_SUCCESS;
+ break;
+ }
+
+ //
+ // Perform the read operation
+ //
+ if (MemoryMapperReadMemorySafeByPhysicalAddress((UINT64)OptionalParam1, (UINT64)OptionalParam2, (SIZE_T)OptionalParam3))
+ {
+ VmcallStatus = STATUS_SUCCESS;
+ }
+ else
+ {
+ VmcallStatus = STATUS_UNSUCCESSFUL;
+ }
+
+ break;
+ }
+ case VMCALL_WRITE_PHYSICAL_MEMORY:
+ {
+ //
+ // Check whether the physical memory is valid or not
+ //
+ if (!CheckAddressPhysical(OptionalParam1))
+ {
+ VmcallStatus = STATUS_SUCCESS;
+ break;
+ }
+
+ //
+ // Perform the write operation
+ //
+ if (MemoryMapperWriteMemorySafeByPhysicalAddress((UINT64)OptionalParam1, (UINT64)OptionalParam2, (SIZE_T)OptionalParam3))
+ {
+ VmcallStatus = STATUS_SUCCESS;
+ }
+ else
+ {
+ VmcallStatus = STATUS_UNSUCCESSFUL;
+ }
+
+ 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/hprdbghv/code/vmm/vmx/Vmexit.c b/hyperdbg/hyperhv/code/vmm/vmx/Vmexit.c
similarity index 81%
rename from hyperdbg/hprdbghv/code/vmm/vmx/Vmexit.c
rename to hyperdbg/hyperhv/code/vmm/vmx/Vmexit.c
index 95bf9c8d..54c5511d 100644
--- a/hyperdbg/hprdbghv/code/vmm/vmx/Vmexit.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/Vmexit.c
@@ -21,10 +21,9 @@
BOOLEAN
VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
{
- UINT32 ExitReason = 0;
- BOOLEAN Result = FALSE;
- BOOLEAN ShouldEmulateRdtscp = TRUE;
- VIRTUAL_MACHINE_STATE * VCpu = NULL;
+ UINT32 ExitReason = 0;
+ BOOLEAN Result = FALSE;
+ VIRTUAL_MACHINE_STATE * VCpu = NULL;
//
// *********** SEND MESSAGE AFTER WE SET THE STATE ***********
@@ -32,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
@@ -48,13 +48,9 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
ExitReason &= 0xffff;
//
- // Check if we're operating in transparent-mode or not
- // If yes then we start operating in transparent-mode
+ // Save the exit reason
//
- if (g_TransparentMode)
- {
- ShouldEmulateRdtscp = TransparentModeStart(VCpu, ExitReason);
- }
+ VCpu->ExitReason = ExitReason;
//
// Increase the RIP by default
@@ -64,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
@@ -82,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:
@@ -111,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);
//
@@ -145,7 +142,7 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
case VMX_EXIT_REASON_EXECUTE_RDMSR:
{
//
- // Handle vm-exit, events, dispatches and perform changes
+ // Handle vm-exit, events, dispatches and perform MSR read
//
DispatchEventRdmsr(VCpu);
@@ -160,8 +157,21 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
break;
}
+ 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;
+ }
case VMX_EXIT_REASON_EXECUTE_CPUID:
{
+ //
+ // Dispatch and trigger the CPUID instruction events
+ //
DispatchEventCpuid(VCpu);
break;
@@ -178,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");
@@ -187,6 +200,9 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
}
case VMX_EXIT_REASON_EPT_MISCONFIGURATION:
{
+ //
+ // Handle EPT misconfiguration (should never happen)
+ //
EptHandleMisconfiguration();
break;
@@ -264,12 +280,8 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
//
// Check whether we are allowed to change the registers
// and emulate rdtsc or not
- // Note : Using !tsc command in transparent-mode is not allowed
//
- if (ShouldEmulateRdtscp)
- {
- DispatchEventTsc(VCpu, ExitReason == VMX_EXIT_REASON_EXECUTE_RDTSCP ? TRUE : FALSE);
- }
+ DispatchEventTsc(VCpu, ExitReason == VMX_EXIT_REASON_EXECUTE_RDTSCP ? TRUE : FALSE);
break;
}
@@ -294,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;
}
@@ -320,6 +332,9 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
}
default:
{
+ //
+ // Not handled vm-exit
+ //
LogError("Err, unknown vmexit, reason : 0x%llx", ExitReason);
break;
@@ -332,6 +347,16 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
//
if (!VCpu->VmxoffState.IsVmxoffExecuted && VCpu->IncrementRip)
{
+ //
+ // If we are in transparent-mode, then we need to handle the trap flag as the result
+ // of an anti-hypervisor technique of using the trap flag after a VM-exit
+ // to detect the hypervisor
+ //
+ if (g_CheckForFootprints)
+ {
+ TransparentCheckAndTrapFlagAfterVmexit();
+ }
+
HvResumeToNextInstruction();
}
@@ -343,21 +368,6 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
Result = TRUE;
}
- //
- // Restore the previous time
- //
- if (g_TransparentMode)
- {
- if (ExitReason != VMX_EXIT_REASON_EXECUTE_RDTSC && ExitReason != VMX_EXIT_REASON_EXECUTE_RDTSCP && ExitReason != VMX_EXIT_REASON_EXECUTE_CPUID)
- {
- //
- // We not wanna change the global timer while RDTSC and RDTSCP
- // was the reason of vm-exit
- //
- __writemsr(MSR_IA32_TIME_STAMP_COUNTER, VCpu->TransparencyState.PreviousTimeStampCounter);
- }
- }
-
//
// Set indicator of Vmx non root mode to false
//
diff --git a/hyperdbg/hprdbghv/code/vmm/vmx/Vmx.c b/hyperdbg/hyperhv/code/vmm/vmx/Vmx.c
similarity index 70%
rename from hyperdbg/hprdbghv/code/vmm/vmx/Vmx.c
rename to hyperdbg/hyperhv/code/vmm/vmx/Vmx.c
index 44857e55..1de5c030 100644
--- a/hyperdbg/hprdbghv/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) ***
@@ -318,6 +172,61 @@ VmxInitialize()
//
return FALSE;
}
+
+#if USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
+
+ //
+ // Allocating Host IDT
+ //
+ if (!VmxAllocateHostIdt(GuestState))
+ {
+ //
+ // Some error in allocating Host IDT
+ //
+ return FALSE;
+ }
+#endif // USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
+
+#if USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
+
+ //
+ // Allocating Host GDT
+ //
+ if (!VmxAllocateHostGdt(GuestState))
+ {
+ //
+ // Some error in allocating Host GDT
+ //
+ return FALSE;
+ }
+
+ //
+ // Allocating Host TSS
+ //
+ if (!VmxAllocateHostTss(GuestState))
+ {
+ //
+ // Some error in allocating Host TSS
+ //
+ return FALSE;
+ }
+
+#endif // USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
+
+#if USE_INTERRUPT_STACK_TABLE == TRUE
+
+ //
+ // Allocating Host Interrupt Stack
+ //
+ if (!VmxAllocateHostInterruptStack(GuestState))
+ {
+ //
+ // Some error in allocating Interrupt Stack
+ //
+ return FALSE;
+ }
+
+#endif // USE_INTERRUPT_STACK_TABLE == TRUE
}
//
@@ -365,10 +274,27 @@ 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
//
- g_EptState = CrsAllocateZeroedNonPagedPool(sizeof(EPT_STATE));
+ g_EptState = PlatformMemAllocateZeroedNonPagedPool(sizeof(EPT_STATE));
if (!g_EptState)
{
@@ -408,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())
{
//
@@ -492,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);
}
/**
@@ -524,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)
{
@@ -555,6 +472,28 @@ VmxVirtualizeCurrentSystem(PVOID GuestStack)
LogDebugInfo("Virtualizing current system (logical core : 0x%x)", CurrentCore);
+#if USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
+
+ //
+ // Prepare Host IDT
+ //
+ IdtEmulationPrepareHostIdt(VCpu);
+#endif // USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
+
+#if USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
+
+ //
+ // Prepare Host GDT and TSS
+ //
+ SegmentPrepareHostGdt((SEGMENT_DESCRIPTOR_32 *)AsmGetGdtBase(),
+ AsmGetGdtLimit(),
+ AsmGetTr(),
+ VCpu->HostInterruptStack,
+ (SEGMENT_DESCRIPTOR_32 *)VCpu->HostGdt,
+ (TASK_STATE_SEGMENT_64 *)VCpu->HostTss);
+
+#endif // USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
+
//
// Clear the VMCS State
//
@@ -585,7 +524,7 @@ VmxVirtualizeCurrentSystem(PVOID GuestStack)
VCpu->HasLaunched = TRUE;
- __vmx_vmlaunch();
+ VmxVmlaunch();
//
// ******** if Vmlaunch succeed will never be here ! ********
@@ -599,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;
@@ -639,10 +578,22 @@ VmxTerminate()
//
MmFreeContiguousMemory((PVOID)VCpu->VmxonRegionVirtualAddress);
MmFreeContiguousMemory((PVOID)VCpu->VmcsRegionVirtualAddress);
- CrsFreePool((PVOID)VCpu->VmmStack);
- CrsFreePool((PVOID)VCpu->MsrBitmapVirtualAddress);
- CrsFreePool((PVOID)VCpu->IoBitmapVirtualAddressA);
- CrsFreePool((PVOID)VCpu->IoBitmapVirtualAddressB);
+ PlatformMemFreePool((PVOID)VCpu->VmmStack);
+ PlatformMemFreePool((PVOID)VCpu->MsrBitmapVirtualAddress);
+ PlatformMemFreePool((PVOID)VCpu->IoBitmapVirtualAddressA);
+ PlatformMemFreePool((PVOID)VCpu->IoBitmapVirtualAddressB);
+#if USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
+ PlatformMemFreePool((PVOID)VCpu->HostIdt);
+#endif // USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
+
+#if USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
+ PlatformMemFreePool((PVOID)VCpu->HostGdt);
+ PlatformMemFreePool((PVOID)VCpu->HostTss);
+#endif // USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
+
+#if USE_INTERRUPT_STACK_TABLE == TRUE
+ PlatformMemFreePool((PVOID)VCpu->HostInterruptStack);
+#endif // USE_INTERRUPT_STACK_TABLE == FALSE
return TRUE;
}
@@ -656,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);
}
@@ -681,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);
@@ -691,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;
@@ -710,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);
@@ -734,13 +687,13 @@ VmxSetupVmcs(VIRTUAL_MACHINE_STATE * VCpu, PVOID GuestStack)
UINT32 SecondaryProcBasedVmExecControls;
PVOID HostRsp;
UINT64 GdtBase = 0;
- VMX_SEGMENT_SELECTOR SegmentSelector = {0};
IA32_VMX_BASIC_REGISTER VmxBasicMsr = {0};
+ VMX_SEGMENT_SELECTOR SegmentSelector = {0};
//
// 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);
@@ -755,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 *******
@@ -783,30 +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(CPU_BASED_CTL2_RDTSCP | CPU_BASED_CTL2_ENABLE_EPT | CPU_BASED_CTL2_ENABLE_INVPCID | CPU_BASED_CTL2_ENABLE_XSAVE_XRSTORS | CPU_BASED_CTL2_ENABLE_VPID,
- 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);
@@ -814,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
@@ -838,22 +813,42 @@ 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
+
+ SegmentGetDescriptor((PUCHAR)VCpu->HostGdt, AsmGetTr(), &SegmentSelector);
- VmxGetSegmentDescriptor((PUCHAR)AsmGetGdtBase(), AsmGetTr(), &SegmentSelector);
VmxVmwrite64(VMCS_HOST_TR_BASE, SegmentSelector.Base);
+ VmxVmwrite64(VMCS_HOST_GDTR_BASE, VCpu->HostGdt);
- VmxVmwrite64(VMCS_HOST_FS_BASE, __readmsr(IA32_FS_BASE));
- VmxVmwrite64(VMCS_HOST_GS_BASE, __readmsr(IA32_GS_BASE));
+#else
+ SegmentGetDescriptor((PUCHAR)AsmGetGdtBase(), AsmGetTr(), &SegmentSelector);
+
+ VmxVmwrite64(VMCS_HOST_TR_BASE, SegmentSelector.Base);
VmxVmwrite64(VMCS_HOST_GDTR_BASE, AsmGetGdtBase());
+
+#endif // USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
+
+ 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
+
+ VmxVmwrite64(VMCS_HOST_IDTR_BASE, VCpu->HostIdt);
+
+#else
+
VmxVmwrite64(VMCS_HOST_IDTR_BASE, AsmGetIdtBase());
- 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));
+#endif // USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
+
+ 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
@@ -903,29 +898,33 @@ 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 !
// prefer to break
//
- LogError("Err, in executing VMRESUME , status : 0x%llx", ErrorCode);
+
+ LogError("Err, in executing VMRESUME, status : 0x%llx, last VM-exit reason: 0x%x",
+ ErrorCode,
+ g_GuestState[KeGetCurrentProcessorNumberEx(NULL)].ExitReason);
}
/**
@@ -989,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
@@ -1007,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;
//
@@ -1038,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.
@@ -1047,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
@@ -1057,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));
}
/**
@@ -1106,7 +1119,10 @@ VmxPerformTermination()
//
// Unhide (disable and de-allocate) transparent-mode
//
- TransparentUnhideDebugger();
+ if (g_CheckForFootprints)
+ {
+ TransparentUnhideDebuggerWrapper(NULL);
+ }
//
// Remove All the hooks if any
@@ -1130,13 +1146,13 @@ VmxPerformTermination()
//
// Free the buffer related to MSRs that cause #GP
//
- CrsFreePool(g_MsrBitmapInvalidMsrs);
+ PlatformMemFreePool(g_MsrBitmapInvalidMsrs);
g_MsrBitmapInvalidMsrs = NULL;
//
// 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)
{
@@ -1149,14 +1165,9 @@ VmxPerformTermination()
//
// Free EptState
//
- CrsFreePool(g_EptState);
+ PlatformMemFreePool(g_EptState);
g_EptState = NULL;
- //
- // Free the Pool manager
- //
- PoolManagerUninitialize();
-
//
// Uninitialize memory mapper
//
@@ -1196,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
@@ -1211,7 +1222,7 @@ VmxCompatibleStrlen(const CHAR * S)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0;
}
@@ -1232,7 +1243,7 @@ VmxCompatibleStrlen(const CHAR * S)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return Count;
}
@@ -1247,7 +1258,7 @@ VmxCompatibleStrlen(const CHAR * S)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0;
}
}
@@ -1256,7 +1267,7 @@ VmxCompatibleStrlen(const CHAR * S)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
}
/**
@@ -1267,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;
@@ -1285,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
@@ -1302,7 +1313,7 @@ VmxCompatibleWcslen(const wchar_t * S)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0;
}
@@ -1311,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')
{
@@ -1323,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
@@ -1338,7 +1349,7 @@ VmxCompatibleWcslen(const wchar_t * S)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0;
}
}
@@ -1347,87 +1358,51 @@ VmxCompatibleWcslen(const wchar_t * S)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
}
/**
- * @brief Get Segment Descriptor
+ * @brief VMX-root compatible micro sleep
+ * @param Us Delay in micro seconds
*
- * @param SegmentSelector
- * @param Selector
- * @param GdtBase
- * @return BOOLEAN
+ * @return VOID
*/
-_Use_decl_annotations_
-BOOLEAN
-VmxGetSegmentDescriptor(PUCHAR GdtBase, UINT16 Selector, PVMX_SEGMENT_SELECTOR SegmentSelector)
+VOID
+VmxCompatibleMicroSleep(UINT64 Us)
{
- SEGMENT_DESCRIPTOR_32 * DescriptorTable32;
- SEGMENT_DESCRIPTOR_32 * Descriptor32;
- SEGMENT_SELECTOR SegSelector = {.AsUInt = Selector};
+ LARGE_INTEGER Start, End, Frequency;
+ KeQueryPerformanceCounter(&Frequency);
- if (!SegmentSelector)
- return FALSE;
+ LONGLONG Ticks = (Frequency.QuadPart / 1000000) * Us;
-#define SELECTOR_TABLE_LDT 0x1
-#define SELECTOR_TABLE_GDT 0x0
+ Start = KeQueryPerformanceCounter(NULL);
- //
- // Ignore LDT
- //
- if ((Selector == 0x0) || (SegSelector.Table != SELECTOR_TABLE_GDT))
+ while (TRUE)
{
- return FALSE;
+ End = KeQueryPerformanceCounter(NULL);
+ if (End.QuadPart - Start.QuadPart > Ticks)
+ break;
}
-
- DescriptorTable32 = (SEGMENT_DESCRIPTOR_32 *)(GdtBase);
- Descriptor32 = &DescriptorTable32[SegSelector.Index];
-
- SegmentSelector->Selector = Selector;
- SegmentSelector->Limit = __segmentlimit(Selector);
- SegmentSelector->Base = ((UINT64)Descriptor32->BaseAddressLow | (UINT64)Descriptor32->BaseAddressMiddle << 16 | (UINT64)Descriptor32->BaseAddressHigh << 24);
-
- SegmentSelector->Attributes.AsUInt = (AsmGetAccessRights(Selector) >> 8);
-
- if (SegSelector.Table == 0 && SegSelector.Index == 0)
- {
- SegmentSelector->Attributes.Unusable = TRUE;
- }
-
- if ((Descriptor32->Type == SEGMENT_DESCRIPTOR_TYPE_TSS_BUSY) || (Descriptor32->Type == SEGMENT_DESCRIPTOR_TYPE_CALL_GATE))
- {
- //
- // this is a TSS or callgate etc, save the base high part
- //
-
- UINT64 SegmentLimitHigh;
- SegmentLimitHigh = (*(UINT64 *)((PUCHAR)Descriptor32 + 8));
- SegmentSelector->Base = (SegmentSelector->Base & 0xffffffff) | (SegmentLimitHigh << 32);
- }
-
- if (SegmentSelector->Attributes.Granularity)
- {
- //
- // 4096-bit granularity is enabled for this segment, scale the limit
- //
- SegmentSelector->Limit = (SegmentSelector->Limit << 12) + 0xfff;
- }
-
- return TRUE;
}
/**
- * @brief implementation of vmx-root mode compatible strcmp
+ * @brief implementation of vmx-root mode compatible strcmp and strncmp
* @param Address1
* @param Address2
+ * @param Num
+ * param IsStrncmp
*
* @return INT32 0x2 indicates error, otherwise the same result as strcmp in string.h
*/
INT32
-VmxCompatibleStrcmp(const CHAR * Address1, const CHAR * Address2)
+VmxCompatibleStrcmp(const CHAR * Address1,
+ const CHAR * Address2,
+ SIZE_T Num,
+ BOOLEAN IsStrncmp)
{
CHAR C1 = NULL_ZERO, C2 = NULL_ZERO;
INT32 Result = 0;
+ UINT32 Count = 0;
UINT64 AlignedAddress1, AlignedAddress2;
CR3_TYPE GuestCr3;
CR3_TYPE OriginalCr3;
@@ -1443,8 +1418,8 @@ VmxCompatibleStrcmp(const CHAR * Address1, const CHAR * Address2)
//
// Move to new cr3
//
- OriginalCr3.Flags = __readcr3();
- __writecr3(GuestCr3.Flags);
+ OriginalCr3.Flags = CpuReadCr3();
+ CpuWriteCr3(GuestCr3.Flags);
//
// First check
@@ -1458,12 +1433,33 @@ VmxCompatibleStrcmp(const CHAR * Address1, const CHAR * Address2)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0x2;
}
do
{
+ //
+ // Check to see if we have byte number constraints
+ //
+ if (IsStrncmp)
+ {
+ if (Count == Num)
+ {
+ //
+ // Maximum number of bytes reached
+ //
+ break;
+ }
+ else
+ {
+ //
+ // Maximum number of bytes not reached
+ //
+ Count++;
+ }
+ }
+
/*
C1 = *Address1;
*/
@@ -1488,7 +1484,7 @@ VmxCompatibleStrcmp(const CHAR * Address1, const CHAR * Address2)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0x2;
}
}
@@ -1504,7 +1500,7 @@ VmxCompatibleStrcmp(const CHAR * Address1, const CHAR * Address2)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0x2;
}
}
@@ -1523,22 +1519,28 @@ VmxCompatibleStrcmp(const CHAR * Address1, const CHAR * Address2)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return Result;
}
/**
- * @brief implementation of vmx-root mode compatible wcscmp
+ * @brief implementation of vmx-root mode compatible wcscmp and wcsncmp
* @param Address1
* @param Address2
+ * @param Num
+ * @param IsWcsncmp
*
* @return INT32 0x2 indicates error, otherwise the same result as wcscmp in string.h
*/
INT32
-VmxCompatibleWcscmp(const wchar_t * Address1, const wchar_t * Address2)
+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;
CR3_TYPE GuestCr3;
CR3_TYPE OriginalCr3;
@@ -1554,13 +1556,13 @@ VmxCompatibleWcscmp(const wchar_t * Address1, const wchar_t * Address2)
//
// 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
@@ -1569,28 +1571,49 @@ VmxCompatibleWcscmp(const wchar_t * Address1, const wchar_t * Address2)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0x2;
}
do
{
+ //
+ // Check to see if we have byte number constraints
+ //
+ if (IsWcsncmp)
+ {
+ if (Count == Num)
+ {
+ //
+ // Maximum number of bytes reached
+ //
+ break;
+ }
+ else
+ {
+ //
+ // Maximum number of bytes not reached
+ //
+ Count++;
+ }
+ }
+
/*
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
@@ -1599,14 +1622,14 @@ VmxCompatibleWcscmp(const wchar_t * Address1, const wchar_t * Address2)
//
// 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
@@ -1615,7 +1638,7 @@ VmxCompatibleWcscmp(const wchar_t * Address1, const wchar_t * Address2)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return 0x2;
}
}
@@ -1635,7 +1658,7 @@ VmxCompatibleWcscmp(const wchar_t * Address1, const wchar_t * Address2)
//
// Move back to original cr3
//
- __writecr3(OriginalCr3.Flags);
+ CpuWriteCr3(OriginalCr3.Flags);
return Result;
}
@@ -1648,7 +1671,7 @@ VmxCompatibleWcscmp(const wchar_t * Address1, const wchar_t * Address2)
* @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;
@@ -1667,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
@@ -1682,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;
}
@@ -1703,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
@@ -1712,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
@@ -1728,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;
}
}
@@ -1748,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/hprdbghv/code/vmm/vmx/VmxBroadcast.c b/hyperdbg/hyperhv/code/vmm/vmx/VmxBroadcast.c
similarity index 96%
rename from hyperdbg/hprdbghv/code/vmm/vmx/VmxBroadcast.c
rename to hyperdbg/hyperhv/code/vmm/vmx/VmxBroadcast.c
index 0e4cf03b..6b23c7fa 100644
--- a/hyperdbg/hprdbghv/code/vmm/vmx/VmxBroadcast.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/VmxBroadcast.c
@@ -28,11 +28,15 @@ VmxBroadcastInitialize()
//
ApicInitialize();
+#if USE_DEFAULT_OS_IDT_AS_HOST_IDT == TRUE
+
//
// Register NMI handler for vmx-root
//
g_NmiHandlerForKeDeregisterNmiCallback = KeRegisterNmiCallback(&VmxBroadcastHandleNmiCallback, NULL);
+#endif // USE_DEFAULT_OS_IDT_AS_HOST_IDT == TRUE
+
//
// Broadcast on all core to cause exit for NMIs
//
@@ -57,11 +61,15 @@ VmxBroadcastUninitialize()
//
g_NmiBroadcastingInitialized = FALSE;
+#if USE_DEFAULT_OS_IDT_AS_HOST_IDT == TRUE
+
//
// De-register NMI handler
//
KeDeregisterNmiCallback(g_NmiHandlerForKeDeregisterNmiCallback);
+#endif // USE_DEFAULT_OS_IDT_AS_HOST_IDT == TRUE
+
//
// Broadcast on all core to cause not to exit for NMIs
//
@@ -149,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/hprdbghv/code/vmm/vmx/VmxMechanisms.c b/hyperdbg/hyperhv/code/vmm/vmx/VmxMechanisms.c
similarity index 100%
rename from hyperdbg/hprdbghv/code/vmm/vmx/VmxMechanisms.c
rename to hyperdbg/hyperhv/code/vmm/vmx/VmxMechanisms.c
diff --git a/hyperdbg/hprdbghv/code/vmm/vmx/VmxRegions.c b/hyperdbg/hyperhv/code/vmm/vmx/VmxRegions.c
similarity index 66%
rename from hyperdbg/hprdbghv/code/vmm/vmx/VmxRegions.c
rename to hyperdbg/hyperhv/code/vmm/vmx/VmxRegions.c
index e4386f09..5d008d3f 100644
--- a/hyperdbg/hprdbghv/code/vmm/vmx/VmxRegions.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/VmxRegions.c
@@ -30,19 +30,19 @@ 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
//
VmxonSize = 2 * VMXON_SIZE;
- VmxonRegion = CrsAllocateContiguousZeroedMemory(VmxonSize + ALIGNMENT_PAGE_SIZE);
+ VmxonRegion = PlatformMemAllocateContiguousZeroedMemory(VmxonSize + ALIGNMENT_PAGE_SIZE);
if (VmxonRegion == NULL)
{
LogError("Err, couldn't allocate buffer for VMXON 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,19 +110,19 @@ 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
//
VmcsSize = 2 * VMCS_SIZE;
- VmcsRegion = CrsAllocateContiguousZeroedMemory(VmcsSize + ALIGNMENT_PAGE_SIZE);
+ VmcsRegion = PlatformMemAllocateContiguousZeroedMemory(VmcsSize + ALIGNMENT_PAGE_SIZE);
if (VmcsRegion == NULL)
{
LogError("Err, couldn't allocate Buffer for VMCS 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);
//
@@ -169,7 +170,7 @@ VmxAllocateVmmStack(_Inout_ VIRTUAL_MACHINE_STATE * VCpu)
//
// Allocate stack for the VM Exit Handler
//
- VCpu->VmmStack = (UINT64)CrsAllocateZeroedNonPagedPool(VMM_STACK_SIZE);
+ VCpu->VmmStack = (UINT64)PlatformMemAllocateZeroedNonPagedPool(VMM_STACK_SIZE);
if (VCpu->VmmStack == NULL64_ZERO)
{
@@ -195,7 +196,7 @@ VmxAllocateMsrBitmap(_Inout_ VIRTUAL_MACHINE_STATE * VCpu)
// Allocate memory for MSR Bitmap
// Should be aligned
//
- VCpu->MsrBitmapVirtualAddress = (UINT64)CrsAllocateZeroedNonPagedPool(PAGE_SIZE);
+ VCpu->MsrBitmapVirtualAddress = (UINT64)PlatformMemAllocateZeroedNonPagedPool(PAGE_SIZE);
if (VCpu->MsrBitmapVirtualAddress == NULL64_ZERO)
{
@@ -214,7 +215,7 @@ VmxAllocateMsrBitmap(_Inout_ VIRTUAL_MACHINE_STATE * VCpu)
/**
* @brief Allocate a buffer for I/O Bitmap
*
- * @param ProcessorID
+ * @param VCpu
* @return BOOLEAN Returns true if allocation was successful otherwise returns false
*/
BOOLEAN
@@ -223,7 +224,7 @@ VmxAllocateIoBitmaps(_Inout_ VIRTUAL_MACHINE_STATE * VCpu)
//
// Allocate memory for I/O Bitmap (A)
//
- VCpu->IoBitmapVirtualAddressA = (UINT64)CrsAllocateZeroedNonPagedPool(PAGE_SIZE); // should be aligned
+ VCpu->IoBitmapVirtualAddressA = (UINT64)PlatformMemAllocateZeroedNonPagedPool(PAGE_SIZE); // should be aligned
if (VCpu->IoBitmapVirtualAddressA == NULL64_ZERO)
{
@@ -239,7 +240,7 @@ VmxAllocateIoBitmaps(_Inout_ VIRTUAL_MACHINE_STATE * VCpu)
//
// Allocate memory for I/O Bitmap (B)
//
- VCpu->IoBitmapVirtualAddressB = (UINT64)CrsAllocateZeroedNonPagedPool(PAGE_SIZE); // should be aligned
+ VCpu->IoBitmapVirtualAddressB = (UINT64)PlatformMemAllocateZeroedNonPagedPool(PAGE_SIZE); // should be aligned
if (VCpu->IoBitmapVirtualAddressB == NULL64_ZERO)
{
@@ -265,7 +266,7 @@ VmxAllocateInvalidMsrBimap()
{
UINT64 * InvalidMsrBitmap;
- InvalidMsrBitmap = CrsAllocateZeroedNonPagedPool(0x1000 / 0x8);
+ InvalidMsrBitmap = PlatformMemAllocateZeroedNonPagedPool(0x1000 / 0x8);
if (InvalidMsrBitmap == NULL)
{
@@ -276,13 +277,132 @@ VmxAllocateInvalidMsrBimap()
{
__try
{
- __readmsr(i);
+ CpuReadMsr(i);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
- SetBit(i, (unsigned long *)InvalidMsrBitmap);
+ SetBit(i, (ULONG *)InvalidMsrBitmap);
}
}
return InvalidMsrBitmap;
}
+
+/**
+ * @brief Allocate a buffer for host IDT
+ *
+ * @param VCpu
+ * @return BOOLEAN Returns true if allocation was successful otherwise returns false
+ */
+BOOLEAN
+VmxAllocateHostIdt(_Inout_ VIRTUAL_MACHINE_STATE * VCpu)
+{
+ UINT32 IdtSize = HOST_IDT_DESCRIPTOR_COUNT * sizeof(SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64);
+
+ //
+ // Make sure the memory is aligned
+ //
+ if (PAGE_SIZE > IdtSize)
+ {
+ IdtSize = PAGE_SIZE;
+ }
+
+ //
+ // Allocate aligned memory for host IDT
+ //
+ VCpu->HostIdt = (UINT64)PlatformMemAllocateZeroedNonPagedPool(IdtSize); // should be aligned
+
+ if (VCpu->HostIdt == NULL64_ZERO)
+ {
+ LogError("Err, insufficient memory in allocating host IDT");
+ return FALSE;
+ }
+
+ LogDebugInfo("Host IDT virtual address : 0x%llx", VCpu->HostIdt);
+
+ return TRUE;
+}
+
+/**
+ * @brief Allocate a buffer for host GDT
+ *
+ * @param VCpu
+ * @return BOOLEAN Returns true if allocation was successful otherwise returns false
+ */
+BOOLEAN
+VmxAllocateHostGdt(_Inout_ VIRTUAL_MACHINE_STATE * VCpu)
+{
+ UINT32 GdtSize = HOST_GDT_DESCRIPTOR_COUNT * sizeof(SEGMENT_DESCRIPTOR_64);
+
+ //
+ // Make sure the memory is aligned
+ //
+ if (PAGE_SIZE > GdtSize)
+ {
+ GdtSize = PAGE_SIZE;
+ }
+
+ //
+ // Allocate aligned memory for host GDT
+ //
+ VCpu->HostGdt = (UINT64)PlatformMemAllocateZeroedNonPagedPool(GdtSize); // should be aligned
+
+ if (VCpu->HostGdt == NULL64_ZERO)
+ {
+ LogError("Err, insufficient memory in allocating host GDT");
+ return FALSE;
+ }
+
+ LogDebugInfo("Host GDT virtual address : 0x%llx", VCpu->HostGdt);
+
+ return TRUE;
+}
+
+/**
+ * @brief Allocate a buffer for host TSS
+ *
+ * @param VCpu
+ * @return BOOLEAN Returns true if allocation was successful otherwise returns false
+ */
+BOOLEAN
+VmxAllocateHostTss(_Inout_ VIRTUAL_MACHINE_STATE * VCpu)
+{
+ UINT32 TssSize = PAGE_SIZE; // Make sure the memory is aligned
+
+ //
+ // Allocate aligned memory for host TSS
+ //
+ VCpu->HostTss = (UINT64)PlatformMemAllocateZeroedNonPagedPool(TssSize); // should be aligned
+
+ if (VCpu->HostTss == NULL64_ZERO)
+ {
+ LogError("Err, insufficient memory in allocating host TSS");
+ return FALSE;
+ }
+
+ LogDebugInfo("Host TSS virtual address : 0x%llx", VCpu->HostTss);
+
+ return TRUE;
+}
+
+/**
+ * @brief Allocate a buffer for host interrupt stack
+ *
+ * @param VCpu
+ * @return BOOLEAN Returns true if allocation was successful otherwise returns false
+ */
+BOOLEAN
+VmxAllocateHostInterruptStack(_Inout_ VIRTUAL_MACHINE_STATE * VCpu)
+{
+ VCpu->HostInterruptStack = (UINT64)PlatformMemAllocateZeroedNonPagedPool(HOST_INTERRUPT_STACK_SIZE);
+
+ if (VCpu->HostInterruptStack == NULL64_ZERO)
+ {
+ LogError("Err, insufficient memory in allocating host interrupt stack");
+ return FALSE;
+ }
+
+ LogDebugInfo("Host interrupt stack virtual address : 0x%llx", VCpu->HostInterruptStack);
+
+ return TRUE;
+}
diff --git a/hyperdbg/hyperhv/header/assembly/InlineAsm.h b/hyperdbg/hyperhv/header/assembly/InlineAsm.h
new file mode 100644
index 00000000..8bc23ba7
--- /dev/null
+++ b/hyperdbg/hyperhv/header/assembly/InlineAsm.h
@@ -0,0 +1,546 @@
+/**
+ * @file InlineAsm.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief The definition of functions written in Assembly
+ * @details
+ * @version 0.1
+ * @date 2020-04-11
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//
+// ==================== Vmx Operations ====================
+// File : AsmVmxOperation.asm
+//
+
+/**
+ * @brief Enable VMX Operation
+ *
+ */
+extern VOID inline AsmEnableVmxOperation();
+
+/**
+ * @brief Restore in vmxoff state
+ *
+ */
+extern VOID inline AsmRestoreToVmxOffState();
+
+/**
+ * @brief Request Vmcall
+ *
+ * @param VmcallNumber
+ * @param OptionalParam1
+ * @param OptionalParam2
+ * @param OptionalParam3
+ * @return NTSTATUS
+ */
+extern NTSTATUS inline AsmVmxVmcall(UINT64 VmcallNumber,
+ UINT64 OptionalParam1,
+ UINT64 OptionalParam2,
+ UINT64 OptionalParam3);
+
+/**
+ * @brief Hyper-v vmcall handler
+ *
+ * @param GuestRegisters
+ * @return VOID
+ */
+extern VOID inline AsmHypervVmcall(UINT64 GuestRegisters);
+
+/**
+ * @brief VMFUNC instruction
+ *
+ * @param EptpIndex
+ * @param Function
+ *
+ * @return UINT64 I'm not sure what it returns
+ */
+extern UINT64 inline AsmVmfunc(ULONG EptpIndex, ULONG Function);
+
+//
+// ==================== Vmx Context State Operations ====================
+// File : AsmVmxContextState.asm
+//
+
+/**
+ * @brief Save state on vmx
+ *
+ */
+extern VOID
+AsmVmxSaveState();
+
+/**
+ * @brief Restore state on vmx
+ *
+ */
+extern VOID
+AsmVmxRestoreState();
+
+//
+// ==================== Vmx VM-Exit Handler ====================
+// File : AsmVmexitHandler.asm
+//
+
+/**
+ * @brief Vm-exit handler
+ *
+ */
+extern VOID
+AsmVmexitHandler();
+
+/**
+ * @brief Save vmxoff state
+ *
+ */
+extern VOID inline AsmSaveVmxOffState();
+
+/**
+ * @brief Restore XMM registers
+ *
+ */
+extern VOID inline AsmVmxoffRestoreXmmRegs(UINT64 XmmRegs);
+
+//
+// ==================== Extended Page Tables ====================
+// File : AsmEpt.asm
+//
+
+/**
+ * @brief INVEPT wrapper
+ *
+ * @param Type
+ * @param Descriptors
+ * @return UCHAR
+ */
+extern UCHAR inline AsmInvept(ULONG Type, PVOID Descriptors);
+
+/**
+ * @brief INVVPID wrapper
+ *
+ * @param Type
+ * @param Descriptors
+ * @return UCHAR
+ */
+extern UCHAR inline AsmInvvpid(ULONG Type, PVOID Descriptors);
+
+//
+// ==================== Get segment registers ====================
+// File : AsmSegmentRegs.asm
+//
+
+/* ********* Segment registers ********* */
+
+/**
+ * @brief Get CS Register
+ *
+ * @return UINT16
+ */
+extern UINT16
+AsmGetCs();
+
+/**
+ * @brief Get DS Register
+ *
+ * @return UINT16
+ */
+extern UINT16
+AsmGetDs();
+
+extern VOID
+AsmSetDs(UINT16 DsSelector);
+
+/**
+ * @brief Get ES Register
+ *
+ * @return UINT16
+ */
+extern UINT16
+AsmGetEs();
+
+extern VOID
+AsmSetEs(UINT16 EsSelector);
+
+/**
+ * @brief Get SS Register
+ *
+ * @return UINT16
+ */
+extern UINT16
+AsmGetSs();
+
+extern VOID
+AsmSetSs(UINT16 SsSelector);
+
+/**
+ * @brief Get FS Register
+ *
+ * @return UINT16
+ */
+extern UINT16
+AsmGetFs();
+
+extern VOID
+AsmSetFs(UINT16 FsSelector);
+
+/**
+ * @brief Get GS Register
+ *
+ * @return UINT16
+ */
+extern UINT16
+AsmGetGs();
+
+/**
+ * @brief Get LDTR Register
+ *
+ * @return UINT16
+ */
+extern UINT16
+AsmGetLdtr();
+
+/**
+ * @brief Get TR Register
+ *
+ * @return UINT16
+ */
+extern UINT16
+AsmGetTr();
+
+/* ******* Gdt related functions ******* */
+
+/**
+ * @brief get GDT base
+ *
+ * @return UINT64
+ */
+extern UINT64 inline AsmGetGdtBase();
+
+/**
+ * @brief Get GDT Limit
+ *
+ * @return UINT16
+ */
+extern UINT16
+AsmGetGdtLimit();
+
+/* ******* Idt related functions ******* */
+
+/**
+ * @brief Get IDT base
+ *
+ * @return UINT64
+ */
+extern UINT64 inline AsmGetIdtBase();
+
+/**
+ * @brief Get IDT limit
+ *
+ * @return UINT16
+ */
+extern UINT16
+AsmGetIdtLimit();
+
+extern UINT32
+AsmGetAccessRights(UINT16 Selector);
+//
+// ==================== Common Functions ====================
+// File : AsmCommon.asm
+//
+
+/**
+ * @brief Get R/EFLAGS
+ *
+ * @return UINT16
+ */
+extern UINT16
+AsmGetRflags();
+
+/**
+ * @brief Run CLI Instruction
+ *
+ */
+extern VOID inline AsmCliInstruction();
+
+/**
+ * @brief Run STI Instruction
+ *
+ */
+extern VOID inline AsmStiInstruction();
+
+/**
+ * @brief Reload new GDTR
+ *
+ * @param GdtBase
+ * @param GdtLimit
+ */
+extern VOID
+AsmReloadGdtr(PVOID GdtBase, ULONG GdtLimit);
+
+/**
+ * @brief Reload new IDTR
+ *
+ * @param IdtrBase
+ * @param IdtrLimit
+ */
+extern VOID
+AsmReloadIdtr(PVOID IdtrBase, ULONG IdtrLimit);
+
+/**
+ * @brief Read SSP
+ *
+ * @return UINT64
+ */
+extern UINT64
+AsmReadSsp();
+
+//
+// ==================== Hook Functions ====================
+// File : AsmHooks.asm
+//
+
+/**
+ * @brief Detour hook handler
+ *
+ */
+extern VOID
+ AsmGeneralDetourHook(VOID);
+
+//
+// ==================== Kernel Test Functions ====================
+// File : AsmKernelSideTests.asm
+//
+
+/**
+ * @brief Tests with test tags wrapper
+ *
+ */
+extern UINT64
+AsmTestWrapperWithTestTags(UINT64 Param1,
+ UINT64 Param2,
+ UINT64 Param3,
+ UINT64 Param4);
+
+//
+// ==================== Interrupt Handler Functions ====================
+// File : Interrupt Handlers.asm.asm
+//
+
+/**
+ * @brief The 0th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler0();
+
+/**
+ * @brief The 1st entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler1();
+
+/**
+ * @brief The 2nd entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler2();
+
+/**
+ * @brief The 3rd entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler3();
+
+/**
+ * @brief The 4th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler4();
+
+/**
+ * @brief The 5th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler5();
+
+/**
+ * @brief The 6th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler6();
+
+/**
+ * @brief The 7th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler7();
+
+/**
+ * @brief The 8th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler8();
+
+/**
+ * @brief The 9th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler9();
+
+/**
+ * @brief The 10th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler10();
+
+/**
+ * @brief The 11th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler11();
+
+/**
+ * @brief The 12th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler12();
+
+/**
+ * @brief The 13th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler13();
+
+/**
+ * @brief The 14th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler14();
+
+/**
+ * @brief The 15th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler15();
+
+/**
+ * @brief The 16th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler16();
+
+/**
+ * @brief The 17th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler17();
+
+/**
+ * @brief The 18th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler18();
+
+/**
+ * @brief The 19th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler19();
+
+/**
+ * @brief The 20th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler20();
+
+/**
+ * @brief The 21st entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler21();
+
+/**
+ * @brief The 22nd entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler22();
+
+/**
+ * @brief The 23rd entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler23();
+
+/**
+ * @brief The 24th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler24();
+
+/**
+ * @brief The 25th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler25();
+
+/**
+ * @brief The 26th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler26();
+
+/**
+ * @brief The 27th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler27();
+
+/**
+ * @brief The 28th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler28();
+
+/**
+ * @brief The 29th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler29();
+
+/**
+ * @brief The 30th entry in IDT
+ *
+ */
+extern VOID
+InterruptHandler30();
diff --git a/hyperdbg/hprdbghv/header/broadcast/Broadcast.h b/hyperdbg/hyperhv/header/broadcast/Broadcast.h
similarity index 100%
rename from hyperdbg/hprdbghv/header/broadcast/Broadcast.h
rename to hyperdbg/hyperhv/header/broadcast/Broadcast.h
diff --git a/hyperdbg/hprdbghv/header/broadcast/DpcRoutines.h b/hyperdbg/hyperhv/header/broadcast/DpcRoutines.h
similarity index 100%
rename from hyperdbg/hprdbghv/header/broadcast/DpcRoutines.h
rename to hyperdbg/hyperhv/header/broadcast/DpcRoutines.h
diff --git a/hyperdbg/hprdbghv/header/common/Bitwise.h b/hyperdbg/hyperhv/header/common/Bitwise.h
similarity index 71%
rename from hyperdbg/hprdbghv/header/common/Bitwise.h
rename to hyperdbg/hyperhv/header/common/Bitwise.h
index 5e5e674a..13601671 100644
--- a/hyperdbg/hprdbghv/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
new file mode 100644
index 00000000..317e841c
--- /dev/null
+++ b/hyperdbg/hyperhv/header/common/Common.h
@@ -0,0 +1,171 @@
+/**
+ * @file Common.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Header files for common functions
+ * @details
+ * @version 0.1
+ * @date 2020-04-10
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+/**
+ * @brief Core Id
+ *
+ */
+#define __CPU_INDEX__ KeGetCurrentProcessorNumberEx(NULL)
+
+/**
+ * @brief Alignment Size
+ *
+ */
+#define ALIGNMENT_PAGE_SIZE 4096
+
+/**
+ * @brief Maximum x64 Address
+ *
+ */
+#define MAXIMUM_ADDRESS 0xffffffffffffffff
+
+/**
+ * @brief System and User ring definitions
+ *
+ */
+#define DPL_USER 3
+#define DPL_SYSTEM 0
+
+/**
+ * @brief RPL Mask
+ *
+ */
+#define RPL_MASK 3
+
+#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)
+
+/**
+ * @brief Offset from a page's 4096 bytes
+ *
+ */
+#define PAGE_OFFSET(Va) ((PVOID)((ULONG_PTR)(Va) & (PAGE_SIZE - 1)))
+
+/**
+ * @brief Intel TSX Constants
+ *
+ */
+#define _XBEGIN_STARTED (~0u)
+#define _XABORT_EXPLICIT (1 << 0)
+#define _XABORT_RETRY (1 << 1)
+#define _XABORT_CONFLICT (1 << 2)
+#define _XABORT_CAPACITY (1 << 3)
+#define _XABORT_DEBUG (1 << 4)
+#define _XABORT_NESTED (1 << 5)
+
+#ifndef _XABORT_CODE
+# define _XABORT_CODE(x) (((x) >> 24) & 0xFF)
+#endif // !_XABORT_CODE
+
+//////////////////////////////////////////////////
+// Structures //
+//////////////////////////////////////////////////
+
+typedef SEGMENT_DESCRIPTOR_32 * PSEGMENT_DESCRIPTOR;
+
+/**
+ * @brief CPUID Registers
+ *
+ */
+typedef struct _CPUID
+{
+ INT eax;
+ INT ebx;
+ INT ecx;
+ INT edx;
+} CPUID, *PCPUID;
+
+typedef union _CR_FIXED
+{
+ UINT64 Flags;
+
+ struct
+ {
+ ULONG Low;
+ LONG High;
+
+ } Fields;
+
+} CR_FIXED, *PCR_FIXED;
+
+//////////////////////////////////////////////////
+// Windows-specific structures //
+//////////////////////////////////////////////////
+
+/**
+ * @brief KPROCESS Brief structure
+ *
+ */
+typedef struct _NT_KPROCESS
+{
+ DISPATCHER_HEADER Header;
+ LIST_ENTRY ProfileListHead;
+ ULONG_PTR DirectoryTableBase;
+ UCHAR Data[1];
+} NT_KPROCESS, *PNT_KPROCESS;
+
+//////////////////////////////////////////////////
+// Function Types //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Prototype to run a function on a logical core
+ *
+ */
+typedef VOID (*RunOnLogicalCoreFunc)(ULONG ProcessorId);
+
+//////////////////////////////////////////////////
+// External Functions //
+//////////////////////////////////////////////////
+
+UCHAR *
+PsGetProcessImageFileName(IN PEPROCESS Process);
+
+//////////////////////////////////////////////////
+// Function Definitions //
+//////////////////////////////////////////////////
+
+// ----------------------------------------------------------------------------
+// Private Interfaces
+//
+
+static NTSTATUS
+CommonGetHandleFromProcess(_In_ UINT32 ProcessId, _Out_ PHANDLE Handle);
+
+// ----------------------------------------------------------------------------
+// Public Interfaces
+//
+
+BOOLEAN
+CommonAffinityBroadcastToProcessors(_In_ ULONG ProcessorNumber, _In_ RunOnLogicalCoreFunc Routine);
+
+BOOLEAN
+CommonIsStringStartsWith(const CHAR * pre, const CHAR * str);
+
+BOOLEAN
+CommonIsGuestOnUsermode32Bit();
+
+PCHAR
+CommonGetProcessNameFromProcessControlBlock(PEPROCESS eprocess);
+
+VOID
+CommonCpuidInstruction(UINT32 Func, UINT32 SubFunc, INT * CpuInfo);
+
+VOID
+CommonWriteDebugInformation(VIRTUAL_MACHINE_STATE * VCpu);
+
+BOOLEAN
+CommonIsXCr0Valid(XCR0 XCr0);
diff --git a/hyperdbg/hprdbghv/header/common/Msr.h b/hyperdbg/hyperhv/header/common/Msr.h
similarity index 59%
rename from hyperdbg/hprdbghv/header/common/Msr.h
rename to hyperdbg/hyperhv/header/common/Msr.h
index 2665c691..eab90724 100644
--- a/hyperdbg/hprdbghv/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/hprdbghv/header/common/State.h b/hyperdbg/hyperhv/header/common/State.h
similarity index 55%
rename from hyperdbg/hprdbghv/header/common/State.h
rename to hyperdbg/hyperhv/header/common/State.h
index c6cdec74..8ea8a312 100644
--- a/hyperdbg/hprdbghv/header/common/State.h
+++ b/hyperdbg/hyperhv/header/common/State.h
@@ -15,11 +15,12 @@
// typedefs //
//////////////////////////////////////////////////
-typedef EPT_PML4E EPT_PML4_POINTER, *PEPT_PML4_POINTER;
-typedef EPT_PDPTE EPT_PML3_POINTER, *PEPT_PML3_POINTER;
-typedef EPT_PDE_2MB EPT_PML2_ENTRY, *PEPT_PML2_ENTRY;
-typedef EPT_PDE EPT_PML2_POINTER, *PEPT_PML2_POINTER;
-typedef EPT_PTE EPT_PML1_ENTRY, *PEPT_PML1_ENTRY;
+typedef EPT_PML4E EPT_PML4_POINTER, *PEPT_PML4_POINTER;
+typedef EPT_PDPTE EPT_PML3_POINTER, *PEPT_PML3_POINTER;
+typedef EPT_PDPTE_1GB EPT_PML3_ENTRY, *PEPT_PML3_ENTRY;
+typedef EPT_PDE_2MB EPT_PML2_ENTRY, *PEPT_PML2_ENTRY;
+typedef EPT_PDE EPT_PML2_POINTER, *PEPT_PML2_POINTER;
+typedef EPT_PTE EPT_PML1_ENTRY, *PEPT_PML1_ENTRY;
//////////////////////////////////////////////////
// Constants //
@@ -109,6 +110,14 @@ typedef struct _VMM_EPT_PAGE_TABLE
DECLSPEC_ALIGN(PAGE_SIZE)
EPT_PML4_POINTER PML4[VMM_EPT_PML4E_COUNT];
+ /**
+ * @brief Describes exactly 512 contiguous 1GB memory regions within a our singular 512GB PML4 region
+ * (This entry is used to support the entire address space).
+ * @details The reason why there is a minus one here is that the original PML3 is described in the next field.
+ */
+ DECLSPEC_ALIGN(PAGE_SIZE)
+ EPT_PML3_ENTRY PML3_RSVD[VMM_EPT_PML4E_COUNT - 1][VMM_EPT_PML3E_COUNT];
+
/**
* @brief Describes exactly 512 contiguous 1GB memory regions within a our singular 512GB PML4 region.
*/
@@ -123,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;
//////////////////////////////////////////////////
@@ -234,6 +250,11 @@ typedef struct _EPT_HOOKED_PAGE_DETAIL
*/
BOOLEAN IsHiddenBreakpoint;
+ /**
+ * @brief This field shows whether the hook is for MMIO shadowing or not
+ */
+ BOOLEAN IsMmioShadowing;
+
/**
* @brief Temporary context for the post event monitors
* It shows the context of the last address that triggered the hook
@@ -288,46 +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 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
+ 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/hprdbghv/header/common/Trace.h b/hyperdbg/hyperhv/header/common/Trace.h
similarity index 100%
rename from hyperdbg/hprdbghv/header/common/Trace.h
rename to hyperdbg/hyperhv/header/common/Trace.h
diff --git a/hyperdbg/hprdbghv/header/common/UnloadDll.h b/hyperdbg/hyperhv/header/common/UnloadDll.h
similarity index 75%
rename from hyperdbg/hprdbghv/header/common/UnloadDll.h
rename to hyperdbg/hyperhv/header/common/UnloadDll.h
index c6388ac7..2dc53a57 100644
--- a/hyperdbg/hprdbghv/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/hprdbghv/header/devices/Apic.h b/hyperdbg/hyperhv/header/devices/Apic.h
similarity index 75%
rename from hyperdbg/hprdbghv/header/devices/Apic.h
rename to hyperdbg/hyperhv/header/devices/Apic.h
index 341d2b96..a33598ea 100644
--- a/hyperdbg/hprdbghv/header/devices/Apic.h
+++ b/hyperdbg/hyperhv/header/devices/Apic.h
@@ -26,7 +26,7 @@
#define APIC_LVR 0x30
#define APIC_LVR_MASK 0xFF00FF
-#define GET_APIC_VERSION(x) ((x)&0xFFu)
+#define GET_APIC_VERSION(x) ((x) & 0xFFu)
#define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFFu)
#define APIC_INTEGRATED(x) (1)
@@ -142,6 +142,65 @@
#define APIC_EILVT3 0x530
#define APIC_BASE_MSR 0x800
+#define APIC_BASE_MSR 0x800
+
+//////////////////////////////////////////////////
+// I/O APIC //
+//////////////////////////////////////////////////
+
+typedef struct _IO_APIC_ENT
+{
+ UINT32 Reg;
+ UINT32 Pad[3];
+ UINT32 Data;
+
+} IO_APIC_ENT, *PIO_APIC_ENT;
+
+#define IO_APIC_DEFAULT_BASE_ADDR 0xFEC00000 // Default physical address of IO APIC
+
+#define IOAPIC_APPEND_QWORD(hi, lo) (((UINT64)(hi) << 32) | (UINT64)(lo))
+#define IOAPIC_LOW_DWORD(x) ((UINT32)(x))
+#define IOAPIC_HIGH_DWORD(x) ((UINT32)((x) >> 32))
+
+#define IOAPIC_REDTBL(x) (0x10 + (x) * 2)
+#define IOAPIC_REDTBL_MAX (24)
+
+#define LU_SIZE 0x400
+
+#define LU_ID_REGISTER 0x00000020
+#define LU_VERS_REGISTER 0x00000030
+#define LU_TPR 0x00000080
+#define LU_APR 0x00000090
+#define LU_PPR 0x000000A0
+#define LU_EOI 0x000000B0
+#define LU_REMOTE_REGISTER 0x000000C0
+
+#define LU_DEST 0x000000D0
+#define LU_DEST_FORMAT 0x000000E0
+
+#define LU_SPURIOUS_VECTOR 0x000000F0
+#define LU_FAULT_VECTOR 0x00000370
+
+#define LU_ISR_0 0x00000100
+#define LU_TMR_0 0x00000180
+#define LU_IRR_0 0x00000200
+#define LU_ERROR_STATUS 0x00000280
+#define LU_INT_CMD_LOW 0x00000300
+#define LU_INT_CMD_HIGH 0x00000310
+#define LU_TIMER_VECTOR 0x00000320
+#define LU_INT_VECTOR_0 0x00000350
+#define LU_INT_VECTOR_1 0x00000360
+#define LU_INITIAL_COUNT 0x00000380
+#define LU_CURRENT_COUNT 0x00000390
+#define LU_DIVIDER_CONFIG 0x000003E0
+
+#define IO_REGISTER_SELECT 0x00000000
+#define IO_REGISTER_WINDOW 0x00000010
+
+#define IO_ID_REGISTER 0x00000000
+#define IO_VERS_REGISTER 0x00000001
+#define IO_ARB_ID_REGISTER 0x00000002
+#define IO_REDIR_BASE 0x00000010
//////////////////////////////////////////////////
// Functions //
@@ -153,6 +212,12 @@ ApicInitialize();
VOID
ApicUninitialize();
+BOOLEAN
+ApicStoreLocalApicFields(PLAPIC_PAGE LApicBuffer, PBOOLEAN IsUsingX2APIC);
+
+BOOLEAN
+ApicStoreIoApicFields(IO_APIC_ENTRY_PACKETS * IoApicPackets);
+
VOID
ApicSelfIpi(UINT32 Vector);
diff --git a/hyperdbg/hyperhv/header/devices/Pci.h b/hyperdbg/hyperhv/header/devices/Pci.h
new file mode 100644
index 00000000..a14a658d
--- /dev/null
+++ b/hyperdbg/hyperhv/header/devices/Pci.h
@@ -0,0 +1,29 @@
+/**
+ * @file Pci.c
+ * @author Bjrn Ruytenberg (bjorn@bjornweb.nl)
+ * @brief Headers related to interacting with PCI(e) fabric
+ * @details
+ * @version 0.10.3
+ * @date 2024-11-11
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+#include "pch.h"
+
+//////////////////////////////////////////////////
+// Definition //
+//////////////////////////////////////////////////
+
+#define CFGADR 0xCF8
+#define CFGDAT 0xCFC
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+QWORD
+PciReadCam(WORD Bus, WORD Device, WORD Function, BYTE Offset, UINT8 Width);
+BOOLEAN
+PciWriteCam(WORD Bus, WORD Device, WORD Function, BYTE Offset, UINT8 Width, QWORD Value);
diff --git a/hyperdbg/hprdbghv/header/disassembler/Disassembler.h b/hyperdbg/hyperhv/header/disassembler/Disassembler.h
similarity index 100%
rename from hyperdbg/hprdbghv/header/disassembler/Disassembler.h
rename to hyperdbg/hyperhv/header/disassembler/Disassembler.h
diff --git a/hyperdbg/hprdbghv/header/features/CompatibilityChecks.h b/hyperdbg/hyperhv/header/features/CompatibilityChecks.h
similarity index 86%
rename from hyperdbg/hprdbghv/header/features/CompatibilityChecks.h
rename to hyperdbg/hyperhv/header/features/CompatibilityChecks.h
index 52bf74e2..a7b4baa1 100644
--- a/hyperdbg/hprdbghv/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/hprdbghv/header/features/DirtyLogging.h b/hyperdbg/hyperhv/header/features/DirtyLogging.h
similarity index 100%
rename from hyperdbg/hprdbghv/header/features/DirtyLogging.h
rename to hyperdbg/hyperhv/header/features/DirtyLogging.h
diff --git a/hyperdbg/hprdbghv/header/globals/GlobalVariableManagement.h b/hyperdbg/hyperhv/header/globals/GlobalVariableManagement.h
similarity index 100%
rename from hyperdbg/hprdbghv/header/globals/GlobalVariableManagement.h
rename to hyperdbg/hyperhv/header/globals/GlobalVariableManagement.h
diff --git a/hyperdbg/hprdbghv/header/globals/GlobalVariables.h b/hyperdbg/hyperhv/header/globals/GlobalVariables.h
similarity index 81%
rename from hyperdbg/hprdbghv/header/globals/GlobalVariables.h
rename to hyperdbg/hyperhv/header/globals/GlobalVariables.h
index 85c720fd..b0b71f10 100644
--- a/hyperdbg/hprdbghv/header/globals/GlobalVariables.h
+++ b/hyperdbg/hyperhv/header/globals/GlobalVariables.h
@@ -49,12 +49,6 @@ MEMORY_MAPPER_ADDRESSES * g_MemoryMapper;
*/
EPT_STATE * g_EptState;
-/**
- * @brief holds the measurements from the user-mode and kernel-mode
- *
- */
-TRANSPARENCY_MEASUREMENTS * g_TransparentModeMeasurements;
-
/**
* @brief List header of hidden hooks detour
*
@@ -68,18 +62,17 @@ LIST_ENTRY g_EptHook2sDetourListHead;
BOOLEAN g_IsEptHook2sDetourListInitialized;
/**
- * @brief Shows whether the debugger transparent mode
- * is enabled (true) or not (false)
- *
- */
-BOOLEAN g_TransparentMode;
-
-/**
- * @brief APIC Base
+ * @brief Local APIC Base
*
*/
VOID * g_ApicBase;
+/**
+ * @brief I/O APIC Base
+ *
+ */
+VOID * g_IoApicBase;
+
/**
* @brief check for broadcasting NMI mechanism support and its
* initialization
@@ -106,19 +99,37 @@ BOOLEAN g_IsUnsafeSyscallOrSysretHandling;
*/
UINT64 * g_MsrBitmapInvalidMsrs;
-/**
- * @brief Whether the page-fault and cr3 vm-exits in vmx-root should check
- * the #PFs or the PML4.Supervisor with user debugger or not
- *
- */
-BOOLEAN g_CheckPageFaultsAndMov2Cr3VmexitsWithUserDebugger;
-
/**
* @brief Enable interception of Cr3 for Mode-based Execution detection
*
*/
BOOLEAN g_ModeBasedExecutionControlState;
+/**
+ * @brief State of syscall callback trap flags
+ *
+ */
+SYSCALL_CALLBACK_TRAP_FLAG_STATE * g_SyscallCallbackTrapFlagState;
+
+/**
+ * @brief Shows whether the syscall callback is enabled or not
+ *
+ */
+BOOLEAN g_SyscallCallbackStatus;
+
+/**
+ * @brief Target hook address for the system call handler
+ *
+ */
+PVOID g_SystemCallHookAddress;
+
+/**
+ * @brief Shows whether the footprints (anti-debugging and
+ * anti-hypervisor) should be checked or not
+ *
+ */
+BOOLEAN g_CheckForFootprints;
+
//////////////////////////////////////////////////
// Global Variable (debugger-related) //
//////////////////////////////////////////////////
@@ -137,6 +148,8 @@ BOOLEAN g_TriggerEventForVmcalls;
*/
BOOLEAN g_TriggerEventForCpuids;
+BOOLEAN g_TriggerEventForXsetbvs;
+
//////////////////////////////////////////////////
// Global Variable (Execution Trap) //
//////////////////////////////////////////////////
@@ -172,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
*
*/
@@ -195,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/hprdbghv/header/hooks/ExecTrap.h b/hyperdbg/hyperhv/header/hooks/ExecTrap.h
similarity index 84%
rename from hyperdbg/hprdbghv/header/hooks/ExecTrap.h
rename to hyperdbg/hyperhv/header/hooks/ExecTrap.h
index 64803eb4..43f4a96a 100644
--- a/hyperdbg/hprdbghv/header/hooks/ExecTrap.h
+++ b/hyperdbg/hyperhv/header/hooks/ExecTrap.h
@@ -22,6 +22,16 @@
*/
#define MAXIMUM_NUMBER_OF_PROCESSES_FOR_USER_KERNEL_EXEC_THREAD 100
+//////////////////////////////////////////////////
+// Locks //
+//////////////////////////////////////////////////
+
+/**
+ * @brief The lock for modifying the list of processes for user-mode, kernel-mode execution traps
+ *
+ */
+volatile LONG ExecTrapProcessListLock;
+
//////////////////////////////////////////////////
// Structures //
//////////////////////////////////////////////////
@@ -62,6 +72,9 @@ ExecTrapUninitialize();
BOOLEAN
ExecTrapInitialize();
+VOID
+ExecTrapApplyMbecConfiguratinFromKernelSide(VIRTUAL_MACHINE_STATE * VCpu);
+
BOOLEAN
ExecTrapHandleEptViolationVmexit(VIRTUAL_MACHINE_STATE * VCpu,
VMX_EXIT_QUALIFICATION_EPT_VIOLATION * ViolationQualification);
diff --git a/hyperdbg/hprdbghv/header/hooks/Hooks.h b/hyperdbg/hyperhv/header/hooks/Hooks.h
similarity index 85%
rename from hyperdbg/hprdbghv/header/hooks/Hooks.h
rename to hyperdbg/hyperhv/header/hooks/Hooks.h
index 152a8964..aad7adcb 100644
--- a/hyperdbg/hprdbghv/header/hooks/Hooks.h
+++ b/hyperdbg/hyperhv/header/hooks/Hooks.h
@@ -11,6 +11,22 @@
*/
#pragma once
+//////////////////////////////////////////////////
+// Structures //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Details of detours style EPT hooks
+ *
+ */
+typedef struct _HIDDEN_HOOKS_DETOUR_DETAILS
+{
+ LIST_ENTRY OtherHooksList;
+ PVOID HookedFunctionAddress;
+ PVOID ReturnAddress;
+
+} HIDDEN_HOOKS_DETOUR_DETAILS, *PHIDDEN_HOOKS_DETOUR_DETAILS;
+
//////////////////////////////////////////////////
// Syscall Hook //
//////////////////////////////////////////////////
@@ -46,105 +62,10 @@
#define IMAGE_VXD_SIGNATURE 0x454C // LE
#define IMAGE_NT_SIGNATURE 0x00004550 // PE00
-//////////////////////////////////////////////////
-// Structure //
-//////////////////////////////////////////////////
-
-/**
- * @brief SSDT structure
- *
- */
-typedef struct _SSDTStruct
-{
- LONG * pServiceTable;
- PVOID pCounterTable;
-#ifdef _WIN64
- UINT64 NumberOfServices;
-#else
- ULONG NumberOfServices;
-#endif
- PCHAR pArgumentTable;
-} SSDTStruct, *PSSDTStruct;
-
-/**
- * @brief Details of detours style EPT hooks
- *
- */
-typedef struct _HIDDEN_HOOKS_DETOUR_DETAILS
-{
- LIST_ENTRY OtherHooksList;
- PVOID HookedFunctionAddress;
- PVOID ReturnAddress;
-
-} HIDDEN_HOOKS_DETOUR_DETAILS, *PHIDDEN_HOOKS_DETOUR_DETAILS;
-
-/**
- * @brief Module entry
- *
- */
-typedef struct _SYSTEM_MODULE_ENTRY
-{
- HANDLE Section;
- PVOID MappedBase;
- PVOID ImageBase;
- ULONG ImageSize;
- ULONG Flags;
- UINT16 LoadOrderIndex;
- UINT16 InitOrderIndex;
- UINT16 LoadCount;
- UINT16 OffsetToFileName;
- UCHAR FullPathName[256];
-} SYSTEM_MODULE_ENTRY, *PSYSTEM_MODULE_ENTRY;
-
-/**
- * @brief System Information for modules
- *
- */
-typedef struct _SYSTEM_MODULE_INFORMATION
-{
- ULONG Count;
- SYSTEM_MODULE_ENTRY Module;
-
-} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
-
-/**
- * @brief System information class
- *
- */
-typedef enum _SYSTEM_INFORMATION_CLASS
-{
- SystemModuleInformation = 11,
- SystemKernelDebuggerInformation = 35
-} SYSTEM_INFORMATION_CLASS,
- *PSYSTEM_INFORMATION_CLASS;
-
-typedef NTSTATUS(NTAPI * ZWQUERYSYSTEMINFORMATION)(
- IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
- OUT PVOID SystemInformation,
- IN ULONG SystemInformationLength,
- OUT PULONG ReturnLength OPTIONAL);
-
-NTSTATUS(*NtCreateFileOrig)
-(
- PHANDLE FileHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes,
- PIO_STATUS_BLOCK IoStatusBlock,
- PLARGE_INTEGER AllocationSize,
- ULONG FileAttributes,
- ULONG ShareAccess,
- ULONG CreateDisposition,
- ULONG CreateOptions,
- PVOID EaBuffer,
- ULONG EaLength);
-
//////////////////////////////////////////////////
// Syscall Hooks Functions //
//////////////////////////////////////////////////
-VOID
-SyscallHookTest();
-
VOID
SyscallHookConfigureEFER(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN EnableEFERSyscallHook);
@@ -334,6 +255,16 @@ EptHookRestoreAllHooksToOriginalEntry(VIRTUAL_MACHINE_STATE * VCpu);
VOID
EptHookUnHookAll();
+/**
+ * @brief Remove all hooks from the hooked pages by the given hooking tag
+ * @details Should be called from Vmx Non-root
+ *
+ * @param HookingTag The hooking tag to unhook
+ * @return BOOLEAN If unhook was successful it returns true or if it was not successful returns false
+ */
+BOOLEAN
+EptHookUnHookAllByHookingTag(UINT64 HookingTag);
+
/**
* @brief Remove single hook from the hooked pages list and invalidate TLB
* From VMX non-root mode
@@ -348,6 +279,17 @@ EptHookUnHookSingleAddress(UINT64 VirtualAddress,
UINT64 PhysAddress,
UINT32 ProcessId);
+/**
+ * @brief Remove single hook from the hooked pages by the given hooking tag
+ * @details Should be called from Vmx root-mode
+ *
+ * @param HookingTag The hooking tag to unhook
+ * @return BOOLEAN If unhook was successful it returns true or if it was not successful returns false
+ */
+BOOLEAN
+EptHookUnHookSingleHookByHookingTagFromVmxRoot(UINT64 HookingTag,
+ EPT_SINGLE_HOOK_UNHOOKING_DETAILS * TargetUnhookingDetails);
+
/**
* @brief Remove single hook from the hooked pages list and invalidate TLB
* From VMX root-mode
diff --git a/hyperdbg/hprdbghv/header/hooks/ModeBasedExecHook.h b/hyperdbg/hyperhv/header/hooks/ModeBasedExecHook.h
similarity index 100%
rename from hyperdbg/hprdbghv/header/hooks/ModeBasedExecHook.h
rename to hyperdbg/hyperhv/header/hooks/ModeBasedExecHook.h
diff --git a/hyperdbg/hyperhv/header/hooks/SyscallCallback.h b/hyperdbg/hyperhv/header/hooks/SyscallCallback.h
new file mode 100644
index 00000000..efbac8bc
--- /dev/null
+++ b/hyperdbg/hyperhv/header/hooks/SyscallCallback.h
@@ -0,0 +1,101 @@
+/**
+ * @file SyscallHook.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @author jtaw5649
+ * @brief Header for syscall hook callbacks
+ * @details
+ *
+ * @version 0.14
+ * @date 2025-06-07
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+//////////////////////////////////////////////////
+// Locks //
+//////////////////////////////////////////////////
+
+/**
+ * @brief The lock for modifying list of process/thread for syscall callback trap flags
+ *
+ */
+volatile LONG SyscallCallbackModeTrapListLock;
+
+//////////////////////////////////////////////////
+// Definitions //
+//////////////////////////////////////////////////
+
+/**
+ * @brief maximum number of thread/process ids to be allocated for keeping track of
+ * of the trap flag
+ *
+ */
+#define MAXIMUM_NUMBER_OF_THREAD_INFORMATION_FOR_SYSCALL_CALLBACK_TRAPS 500
+
+//////////////////////////////////////////////////
+// Structures //
+//////////////////////////////////////////////////
+
+/**
+ * @brief The thread/process information
+ *
+ */
+typedef struct _SYSCALL_CALLBACK_PROCESS_THREAD_INFORMATION
+{
+ union
+ {
+ UINT64 asUInt;
+
+ struct
+ {
+ UINT32 ProcessId;
+ UINT32 ThreadId;
+ } Fields;
+ };
+
+} SYSCALL_CALLBACK_PROCESS_THREAD_INFORMATION, *PSYSCALL_CALLBACK_PROCESS_THREAD_INFORMATION;
+
+/**
+ * @brief The threads that we expect to get the trap flag
+ *
+ * @details Used for keeping track of the threads that we expect to get the trap flag
+ *
+ */
+typedef struct _SYSCALL_CALLBACK_TRAP_FLAG_STATE
+{
+ UINT32 NumberOfItems;
+ SYSCALL_CALLBACK_PROCESS_THREAD_INFORMATION ThreadInformation[MAXIMUM_NUMBER_OF_THREAD_INFORMATION_FOR_SYSCALL_CALLBACK_TRAPS];
+ UINT64 Context[MAXIMUM_NUMBER_OF_THREAD_INFORMATION_FOR_SYSCALL_CALLBACK_TRAPS];
+ SYSCALL_CALLBACK_CONTEXT_PARAMS Params[MAXIMUM_NUMBER_OF_THREAD_INFORMATION_FOR_SYSCALL_CALLBACK_TRAPS];
+
+} SYSCALL_CALLBACK_TRAP_FLAG_STATE, *PSYSCALL_CALLBACK_TRAP_FLAG_STATE;
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+BOOLEAN
+SyscallCallbackInitialize();
+
+BOOLEAN
+SyscallCallbackIsInitialized();
+
+BOOLEAN
+SyscallCallbackUninitialize();
+
+BOOLEAN
+SyscallCallbackSetTrapFlagAfterSyscall(GUEST_REGS * Regs,
+ UINT32 ProcessId,
+ UINT32 ThreadId,
+ UINT64 Context,
+ SYSCALL_CALLBACK_CONTEXT_PARAMS * Params);
+
+BOOLEAN
+SyscallCallbackCheckAndHandleAfterSyscallTrapFlags(VIRTUAL_MACHINE_STATE * VCpu,
+ UINT32 ProcessId,
+ UINT32 ThreadId);
+
+VOID
+SyscallCallbackHandleSystemCallHook(VIRTUAL_MACHINE_STATE * VCpu);
diff --git a/hyperdbg/hprdbghv/header/interface/Callback.h b/hyperdbg/hyperhv/header/interface/Callback.h
similarity index 60%
rename from hyperdbg/hprdbghv/header/interface/Callback.h
rename to hyperdbg/hyperhv/header/interface/Callback.h
index d5754a21..294cb22a 100644
--- a/hyperdbg/hprdbghv/header/interface/Callback.h
+++ b/hyperdbg/hyperhv/header/interface/Callback.h
@@ -12,34 +12,6 @@
*/
#pragma once
-//
-// Log Callbacks
-//
-
-BOOLEAN
-LogCallbackPrepareAndSendMessageToQueue(UINT32 OperationCode,
- BOOLEAN IsImmediateMessage,
- BOOLEAN ShowCurrentSystemTime,
- BOOLEAN Priority,
- const char * Fmt,
- ...);
-
-BOOLEAN
-LogCallbackSendMessageToQueue(UINT32 OperationCode,
- BOOLEAN IsImmediateMessage,
- CHAR * LogMessage,
- UINT32 BufferLen,
- BOOLEAN Priority);
-
-BOOLEAN
-LogCallbackCheckIfBufferIsFull(BOOLEAN Priority);
-
-BOOLEAN
-LogCallbackSendBuffer(_In_ UINT32 OperationCode,
- _In_reads_bytes_(BufferLength) PVOID Buffer,
- _In_ UINT32 BufferLength,
- _In_ BOOLEAN Priority);
-
//
// VMM Callbacks
//
@@ -72,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
//
@@ -92,9 +70,26 @@ BOOLEAN
DebuggingCallbackHandleDebugBreakpointException(UINT32 CoreId);
BOOLEAN
-DebuggingCallbackConditionalPageFaultException(UINT32 CoreId,
- UINT64 Address,
- UINT32 PageFaultErrorCode);
+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
@@ -102,6 +97,3 @@ DebuggingCallbackConditionalPageFaultException(UINT32 CoreId,
VOID
InterceptionCallbackTriggerCr3ProcessChange(UINT32 CoreId);
-
-VOID
-InterceptionCallbackCr3VmexitsForThreadInterception(UINT32 CoreId, CR3_TYPE NewCr3);
diff --git a/hyperdbg/hprdbghv/header/interface/DirectVmcall.h b/hyperdbg/hyperhv/header/interface/DirectVmcall.h
similarity index 100%
rename from hyperdbg/hprdbghv/header/interface/DirectVmcall.h
rename to hyperdbg/hyperhv/header/interface/DirectVmcall.h
diff --git a/hyperdbg/hprdbghv/header/interface/Dispatch.h b/hyperdbg/hyperhv/header/interface/Dispatch.h
similarity index 96%
rename from hyperdbg/hprdbghv/header/interface/Dispatch.h
rename to hyperdbg/hyperhv/header/interface/Dispatch.h
index 7ec91d77..f35ed6ef 100644
--- a/hyperdbg/hprdbghv/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);
@@ -32,7 +35,7 @@ VOID
DispatchEventVmcall(VIRTUAL_MACHINE_STATE * VCpu);
VOID
-DispatchEventMode(VIRTUAL_MACHINE_STATE * VCpu, DEBUGGER_EVENT_MODE_TYPE TargetMode, BOOLEAN HandleState);
+DispatchEventMode(VIRTUAL_MACHINE_STATE * VCpu, DEBUGGER_EVENT_MODE_TYPE TargetMode);
VOID
DispatchEventMovToCr3(VIRTUAL_MACHINE_STATE * VCpu);
diff --git a/hyperdbg/hprdbghv/header/memory/AddressCheck.h b/hyperdbg/hyperhv/header/memory/AddressCheck.h
similarity index 100%
rename from hyperdbg/hprdbghv/header/memory/AddressCheck.h
rename to hyperdbg/hyperhv/header/memory/AddressCheck.h
diff --git a/hyperdbg/hprdbghv/header/memory/Conversion.h b/hyperdbg/hyperhv/header/memory/Conversion.h
similarity index 100%
rename from hyperdbg/hprdbghv/header/memory/Conversion.h
rename to hyperdbg/hyperhv/header/memory/Conversion.h
diff --git a/hyperdbg/hprdbghv/header/memory/Layout.h b/hyperdbg/hyperhv/header/memory/Layout.h
similarity index 88%
rename from hyperdbg/hprdbghv/header/memory/Layout.h
rename to hyperdbg/hyperhv/header/memory/Layout.h
index f1106df9..7fa322a4 100644
--- a/hyperdbg/hprdbghv/header/memory/Layout.h
+++ b/hyperdbg/hyperhv/header/memory/Layout.h
@@ -15,8 +15,9 @@
// Functions //
//////////////////////////////////////////////////
-CR3_TYPE
-LayoutGetCr3ByProcessId(_In_ UINT32 ProcessId);
+//
+// Some functions are exported on VMM exports
+//
UINT64
LayoutGetSystemDirectoryTableBase();
diff --git a/hyperdbg/hprdbghv/header/memory/MemoryMapper.h b/hyperdbg/hyperhv/header/memory/MemoryMapper.h
similarity index 94%
rename from hyperdbg/hprdbghv/header/memory/MemoryMapper.h
rename to hyperdbg/hyperhv/header/memory/MemoryMapper.h
index 63a43ebb..decf89d6 100644
--- a/hyperdbg/hprdbghv/header/memory/MemoryMapper.h
+++ b/hyperdbg/hyperhv/header/memory/MemoryMapper.h
@@ -35,6 +35,8 @@ typedef enum _MEMORY_MAPPER_WRAPPER_FOR_MEMORY_READ
{
MEMORY_MAPPER_WRAPPER_READ_PHYSICAL_MEMORY,
MEMORY_MAPPER_WRAPPER_READ_VIRTUAL_MEMORY,
+ MEMORY_MAPPER_WRAPPER_READ_VIRTUAL_MEMORY_UNSAFE
+
} MEMORY_MAPPER_WRAPPER_FOR_MEMORY_READ;
/**
@@ -45,7 +47,7 @@ typedef enum _MEMORY_MAPPER_WRAPPER_FOR_MEMORY_WRITE
{
MEMORY_MAPPER_WRAPPER_WRITE_PHYSICAL_MEMORY,
MEMORY_MAPPER_WRAPPER_WRITE_VIRTUAL_MEMORY_SAFE,
- MEMORY_MAPPER_WRAPPER_WRITE_VIRTUAL_MEMORY_UNSAFE,
+ MEMORY_MAPPER_WRAPPER_WRITE_VIRTUAL_MEMORY_UNSAFE
} MEMORY_MAPPER_WRAPPER_FOR_MEMORY_WRITE;
@@ -163,14 +165,16 @@ MemoryMapperWriteMemorySafeByPte(_In_ PVOID SourceVA,
static UINT64
MemoryMapperReadMemorySafeByPhysicalAddressWrapperAddressMaker(
_In_ MEMORY_MAPPER_WRAPPER_FOR_MEMORY_READ TypeOfRead,
- _In_ UINT64 AddressToRead);
+ _In_ UINT64 AddressToRead,
+ _In_ UINT32 TargetProcessId);
static BOOLEAN
-MemoryMapperReadMemorySafeByPhysicalAddressWrapper(
+MemoryMapperReadMemorySafeWrapper(
_In_ MEMORY_MAPPER_WRAPPER_FOR_MEMORY_READ TypeOfRead,
_In_ UINT64 AddressToRead,
_Inout_ UINT64 BufferToSaveMemory,
- _In_ SIZE_T SizeToRead);
+ _In_ SIZE_T SizeToRead,
+ _In_ UINT32 TargetProcessId);
static UINT64
MemoryMapperWriteMemorySafeWrapperAddressMaker(_In_ MEMORY_MAPPER_WRAPPER_FOR_MEMORY_WRITE TypeOfWrite,
diff --git a/hyperdbg/hyperhv/header/memory/Segmentation.h b/hyperdbg/hyperhv/header/memory/Segmentation.h
new file mode 100644
index 00000000..78987058
--- /dev/null
+++ b/hyperdbg/hyperhv/header/memory/Segmentation.h
@@ -0,0 +1,60 @@
+/**
+ * @file Segmentation.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Functions for handling memory segmentations
+ * @details
+ * @version 0.9
+ * @date 2024-06-03
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Constants //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Whether the hypervisor should use the default OS's
+ * GDT as the host GDT in VMCS or not
+ *
+ */
+#define USE_DEFAULT_OS_GDT_AS_HOST_GDT FALSE
+
+/**
+ * @brief Maximum number of entries in GDT
+ *
+ */
+#define HOST_GDT_DESCRIPTOR_COUNT 10 // approximately
+
+/**
+ * @brief Size of host interrupt stack
+ *
+ */
+#define HOST_INTERRUPT_STACK_SIZE 4 * PAGE_SIZE
+
+/**
+ * @brief Use Interrupt Stack Table (IST1..IST7)
+ *
+ */
+#define USE_INTERRUPT_STACK_TABLE FALSE
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+_Success_(return)
+BOOLEAN
+SegmentGetDescriptor(_In_ PUCHAR GdtBase,
+ _In_ UINT16 Selector,
+ _Out_ PVMX_SEGMENT_SELECTOR SegmentSelector);
+
+VOID
+SegmentPrepareHostGdt(
+ SEGMENT_DESCRIPTOR_32 * OsGdtBase,
+ UINT16 OsGdtLimit,
+ UINT16 TrSelector,
+ UINT64 HostStack,
+ SEGMENT_DESCRIPTOR_32 * AllocatedHostGdt,
+ TASK_STATE_SEGMENT_64 * AllocatedHostTss);
diff --git a/hyperdbg/hprdbghv/header/memory/SwitchLayout.h b/hyperdbg/hyperhv/header/memory/SwitchLayout.h
similarity index 100%
rename from hyperdbg/hprdbghv/header/memory/SwitchLayout.h
rename to hyperdbg/hyperhv/header/memory/SwitchLayout.h
diff --git a/hyperdbg/hyperhv/header/mmio/MmioShadowing.h b/hyperdbg/hyperhv/header/mmio/MmioShadowing.h
new file mode 100644
index 00000000..3aee98dd
--- /dev/null
+++ b/hyperdbg/hyperhv/header/mmio/MmioShadowing.h
@@ -0,0 +1,16 @@
+/**
+ * @file MmioShadowing.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Header files for MMIO shadowing
+ * @details
+ * @version 0.14
+ * @date 2025-02-24
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
diff --git a/hyperdbg/hyperhv/header/processor/Idt.h b/hyperdbg/hyperhv/header/processor/Idt.h
new file mode 100644
index 00000000..996d8f84
--- /dev/null
+++ b/hyperdbg/hyperhv/header/processor/Idt.h
@@ -0,0 +1,49 @@
+/**
+ * @file Idt.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Headers relating to Interrupt Descriptor Table
+ * @details
+ *
+ * @version 0.11
+ * @date 2024-11-20
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Definition //
+//////////////////////////////////////////////////
+
+typedef union _KIDTENTRY64
+{
+ struct
+ {
+ USHORT OffsetLow;
+ USHORT Selector;
+ USHORT IstIndex : 3;
+ USHORT Reserved0 : 5;
+ USHORT Type : 5;
+ USHORT Dpl : 2;
+ USHORT Present : 1;
+ USHORT OffsetMiddle;
+ ULONG OffsetHigh;
+ ULONG Reserved1;
+ };
+ UINT64 Alignment;
+} KIDTENTRY64, *PKIDTENTRY64;
+
+typedef struct _KDESCRIPTOR64
+{
+ USHORT Pad[3];
+ USHORT Limit;
+ PVOID Base;
+} KDESCRIPTOR64, *PKDESCRIPTOR64;
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+VOID
+IdtDumpInterruptEntries();
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/hprdbghv/header/vmm/ept/Ept.h b/hyperdbg/hyperhv/header/vmm/ept/Ept.h
similarity index 83%
rename from hyperdbg/hprdbghv/header/vmm/ept/Ept.h
rename to hyperdbg/hyperhv/header/vmm/ept/Ept.h
index 333e89f4..b8a69750 100644
--- a/hyperdbg/hprdbghv/header/vmm/ept/Ept.h
+++ b/hyperdbg/hyperhv/header/vmm/ept/Ept.h
@@ -30,6 +30,18 @@
*/
#define SIZE_2_MB ((SIZE_T)(512 * PAGE_SIZE))
+/**
+ * @brief Integer 1GB
+ *
+ */
+#define SIZE_1_GB ((SIZE_T)(512 * SIZE_2_MB))
+
+/**
+ * @brief Integer 512GB
+ *
+ */
+#define SIZE_512_GB ((SIZE_T)(512 * SIZE_1_GB))
+
/**
* @brief Offset into the 1st paging structure (4096 byte)
*
@@ -115,15 +127,9 @@ typedef union _IA32_MTRR_FIXED_RANGE_TYPE
*/
typedef struct _EPT_STATE
{
- LIST_ENTRY HookedPagesList; // A list of the details about hooked pages
- MTRR_RANGE_DESCRIPTOR MemoryRanges[NUM_MTRR_ENTRIES]; // Physical memory ranges described by the BIOS in the MTRRs. Used to build the EPT identity mapping.
- UINT32 NumberOfEnabledMemoryRanges; // Number of memory ranges specified in MemoryRanges
- PVMM_EPT_PAGE_TABLE EptPageTable; // Page table entries for EPT operation
- PVMM_EPT_PAGE_TABLE ModeBasedUserDisabledEptPageTable; // Page table entries for hooks based on user-mode disabled mode-based execution control bits
- PVMM_EPT_PAGE_TABLE ModeBasedKernelDisabledEptPageTable; // Page table entries for hooks based on kernel-mode disabled mode-based execution control bits
- EPT_POINTER ModeBasedUserDisabledEptPointer; // Extended-Page-Table Pointer for user-disabled mode-based execution
- EPT_POINTER ModeBasedKernelDisabledEptPointer; // Extended-Page-Table Pointer for kernel-disabled mode-based execution
- EPT_POINTER ExecuteOnlyEptPointer; // Extended-Page-Table Pointer for execute-only execution
+ LIST_ENTRY HookedPagesList; // A list of the details about hooked pages
+ MTRR_RANGE_DESCRIPTOR MemoryRanges[NUM_MTRR_ENTRIES]; // Physical memory ranges described by the BIOS in the MTRRs. Used to build the EPT identity mapping.
+ UINT32 NumberOfEnabledMemoryRanges; // Number of memory ranges specified in MemoryRanges
UINT8 DefaultMemoryType;
} EPT_STATE, *PEPT_STATE;
@@ -141,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
@@ -203,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);
/**
@@ -274,7 +280,7 @@ EptGetPml1OrPml2Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress,
* @return VOID
*/
VOID
-EptHandleMisconfiguration(VOID);
+ EptHandleMisconfiguration(VOID);
/**
* @brief This function set the specific PML1 entry in a spinlock protected area then
diff --git a/hyperdbg/hprdbghv/header/vmm/ept/Invept.h b/hyperdbg/hyperhv/header/vmm/ept/Invept.h
similarity index 93%
rename from hyperdbg/hprdbghv/header/vmm/ept/Invept.h
rename to hyperdbg/hyperhv/header/vmm/ept/Invept.h
index 501b2262..a76bc8c5 100644
--- a/hyperdbg/hprdbghv/header/vmm/ept/Invept.h
+++ b/hyperdbg/hyperhv/header/vmm/ept/Invept.h
@@ -26,4 +26,4 @@ UCHAR
EptInveptAllContexts();
UCHAR
-EptInveptSingleContext(_In_ UINT64 EptPonter);
+EptInveptSingleContext(_In_ UINT64 EptPointer);
diff --git a/hyperdbg/hprdbghv/header/vmm/ept/Vpid.h b/hyperdbg/hyperhv/header/vmm/ept/Vpid.h
similarity index 100%
rename from hyperdbg/hprdbghv/header/vmm/ept/Vpid.h
rename to hyperdbg/hyperhv/header/vmm/ept/Vpid.h
diff --git a/hyperdbg/hprdbghv/header/vmm/vmx/Counters.h b/hyperdbg/hyperhv/header/vmm/vmx/Counters.h
similarity index 100%
rename from hyperdbg/hprdbghv/header/vmm/vmx/Counters.h
rename to hyperdbg/hyperhv/header/vmm/vmx/Counters.h
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/hprdbghv/header/vmm/vmx/Events.h b/hyperdbg/hyperhv/header/vmm/vmx/Events.h
similarity index 98%
rename from hyperdbg/hprdbghv/header/vmm/vmx/Events.h
rename to hyperdbg/hyperhv/header/vmm/vmx/Events.h
index 21234310..9f49e9c1 100644
--- a/hyperdbg/hprdbghv/header/vmm/vmx/Events.h
+++ b/hyperdbg/hyperhv/header/vmm/vmx/Events.h
@@ -119,6 +119,9 @@ EventInjectGeneralProtection();
VOID
EventInjectUndefinedOpcode(VIRTUAL_MACHINE_STATE * VCpu);
+VOID
+EventInjectNmi(VIRTUAL_MACHINE_STATE * VCpu);
+
VOID
EventInjectPageFaultWithoutErrorCode(UINT64 PageFaultAddress);
diff --git a/hyperdbg/hprdbghv/header/vmm/vmx/Hv.h b/hyperdbg/hyperhv/header/vmm/vmx/Hv.h
similarity index 73%
rename from hyperdbg/hprdbghv/header/vmm/vmx/Hv.h
rename to hyperdbg/hyperhv/header/vmm/vmx/Hv.h
index fa9fbe18..2aa85bea 100644
--- a/hyperdbg/hprdbghv/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
@@ -430,3 +452,121 @@ HvEnableMtfAndChangeExternalInterruptState(VIRTUAL_MACHINE_STATE * VCpu);
*/
VOID
HvPreventExternalInterrupts(VIRTUAL_MACHINE_STATE * VCpu);
+
+/**
+ * @brief Get the guest state of pending debug exceptions
+ *
+ * @return UINT64
+ */
+UINT64
+HvGetPendingDebugExceptions();
+
+/**
+ * @brief Set the guest state of pending debug exceptions
+ * @param Value The new state
+ *
+ * @return VOID
+ */
+VOID
+HvSetPendingDebugExceptions(UINT64 Value);
+
+/**
+ * @brief Get the guest state of IA32_DEBUGCTL
+ *
+ * @return UINT64
+ */
+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
+ *
+ * @return VOID
+ */
+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
+ * after vm-entry
+ *
+ * @return VOID
+ */
+VOID
+HvHandleTrapFlag();
diff --git a/hyperdbg/hyperhv/header/vmm/vmx/IdtEmulation.h b/hyperdbg/hyperhv/header/vmm/vmx/IdtEmulation.h
new file mode 100644
index 00000000..1c0d49b8
--- /dev/null
+++ b/hyperdbg/hyperhv/header/vmm/vmx/IdtEmulation.h
@@ -0,0 +1,240 @@
+/**
+ * @file IdtEmulation.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Header for Handlers of Guest's IDT Emulator
+ * @details
+ * @version 0.1
+ * @date 2020-06-10
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Constants //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Whether the hypervisor should use the default OS's
+ * IDT as the host IDT in VMCS or not
+ *
+ */
+#define USE_DEFAULT_OS_IDT_AS_HOST_IDT FALSE
+
+/**
+ * @brief Maximum number of interrupt entries in IDT
+ *
+ */
+#define HOST_IDT_DESCRIPTOR_COUNT 256
+
+//////////////////////////////////////////////////
+// Structures //
+//////////////////////////////////////////////////
+
+#pragma pack(push, 1)
+
+typedef struct _SIDT_ENTRY
+{
+ USHORT IdtLimit;
+ ULONG_PTR IdtBase;
+} SIDT_ENTRY, *PSIDT_ENTRY;
+
+typedef struct _KIDT_ENTRY
+{
+ ULONG LowPart : 16;
+ ULONG SegmentSelector : 16;
+ ULONG Reserved1 : 5;
+ ULONG Reserved2 : 3;
+ ULONG Type : 3;
+ ULONG Size : 1;
+ ULONG Reserved3 : 1;
+ ULONG Dpl : 2;
+ ULONG Present : 1;
+ ULONG HighPart : 16;
+#if defined _M_AMD64
+ ULONG HighestPart;
+ ULONG Reserved;
+#endif
+} KIDT_ENTRY, *PKIDT_ENTRY;
+
+#pragma pack(pop)
+
+/**
+ * @brief Trap frame for interrupts
+ *
+ */
+typedef struct _INTERRUPT_TRAP_FRAME
+{
+ //
+ // general-purpose registers
+ //
+ union
+ {
+ UINT64 rax;
+ UINT32 eax;
+ UINT16 ax;
+ UINT8 al;
+ };
+ union
+ {
+ UINT64 rcx;
+ UINT32 ecx;
+ UINT16 cx;
+ UINT8 cl;
+ };
+ union
+ {
+ UINT64 rdx;
+ UINT32 edx;
+ UINT16 dx;
+ UINT8 dl;
+ };
+ union
+ {
+ UINT64 rbx;
+ UINT32 ebx;
+ UINT16 bx;
+ UINT8 bl;
+ };
+ union
+ {
+ UINT64 rbp;
+ UINT32 ebp;
+ UINT16 bp;
+ UINT8 bpl;
+ };
+ union
+ {
+ UINT64 rsi;
+ UINT32 esi;
+ UINT16 si;
+ UINT8 sil;
+ };
+ union
+ {
+ UINT64 rdi;
+ UINT32 edi;
+ UINT16 di;
+ UINT8 dil;
+ };
+ union
+ {
+ UINT64 r8;
+ UINT32 r8d;
+ UINT16 r8w;
+ UINT8 r8b;
+ };
+ union
+ {
+ UINT64 r9;
+ UINT32 r9d;
+ UINT16 r9w;
+ UINT8 r9b;
+ };
+ union
+ {
+ UINT64 r10;
+ UINT32 r10d;
+ UINT16 r10w;
+ UINT8 r10b;
+ };
+ union
+ {
+ UINT64 r11;
+ UINT32 r11d;
+ UINT16 r11w;
+ UINT8 r11b;
+ };
+ union
+ {
+ UINT64 r12;
+ UINT32 r12d;
+ UINT16 r12w;
+ UINT8 r12b;
+ };
+ union
+ {
+ UINT64 r13;
+ UINT32 r13d;
+ UINT16 r13w;
+ UINT8 r13b;
+ };
+ union
+ {
+ UINT64 r14;
+ UINT32 r14d;
+ UINT16 r14w;
+ UINT8 r14b;
+ };
+ union
+ {
+ UINT64 r15;
+ UINT32 r15d;
+ UINT16 r15w;
+ UINT8 r15b;
+ };
+
+ // interrupt vector
+ UINT8 vector;
+
+ // _MACHINE_FRAME
+ UINT64 error;
+ UINT64 rip;
+ UINT64 cs;
+ UINT64 rflags;
+ UINT64 rsp;
+ UINT64 ss;
+} INTERRUPT_TRAP_FRAME, *PINTERRUPT_TRAP_FRAME;
+
+//
+// remember to update this value in AsmInterruptHandlers.asm
+//
+static_assert(sizeof(INTERRUPT_TRAP_FRAME) == (0x78 + 0x38), "Size of INTERRUPT_TRAP_FRAME is not as expected");
+
+/**
+ * @brief Filled out when a host exception occurs
+ *
+ */
+typedef struct _HOST_EXCEPTION_INFO
+{
+ //
+ // whether an exception occurred or not
+ //
+ BOOLEAN ExceptionOccurred;
+
+ //
+ // interrupt vector
+ //
+ UINT64 Vector;
+
+ //
+ // error code
+ //
+ UINT64 Error;
+} HOST_EXCEPTION_INFO, *PHOST_EXCEPTION_INFO;
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+VOID
+IdtEmulationPrepareHostIdt(_Inout_ VIRTUAL_MACHINE_STATE * VCpu);
+
+VOID
+IdtEmulationHandleExceptionAndNmi(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
+ _In_ VMEXIT_INTERRUPT_INFORMATION InterruptExit);
+
+VOID
+IdtEmulationHandleExternalInterrupt(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
+ _In_ VMEXIT_INTERRUPT_INFORMATION InterruptExit);
+
+VOID
+IdtEmulationHandleNmiWindowExiting(_Inout_ VIRTUAL_MACHINE_STATE * VCpu);
+
+VOID
+IdtEmulationHandleInterruptWindowExiting(_Inout_ VIRTUAL_MACHINE_STATE * VCpu);
+
+VOID
+IdtEmulationQueryIdtEntriesRequest(PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS IdtQueryRequest,
+ BOOLEAN ReadFromVmxRoot);
diff --git a/hyperdbg/hprdbghv/header/vmm/vmx/IoHandler.h b/hyperdbg/hyperhv/header/vmm/vmx/IoHandler.h
similarity index 53%
rename from hyperdbg/hprdbghv/header/vmm/vmx/IoHandler.h
rename to hyperdbg/hyperhv/header/vmm/vmx/IoHandler.h
index 15767148..20b698f6 100644
--- a/hyperdbg/hprdbghv/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/hprdbghv/header/vmm/vmx/MsrHandlers.h b/hyperdbg/hyperhv/header/vmm/vmx/MsrHandlers.h
similarity index 85%
rename from hyperdbg/hprdbghv/header/vmm/vmx/MsrHandlers.h
rename to hyperdbg/hyperhv/header/vmm/vmx/MsrHandlers.h
index 4d3a6b9a..3114949d 100644
--- a/hyperdbg/hprdbghv/header/vmm/vmx/MsrHandlers.h
+++ b/hyperdbg/hyperhv/header/vmm/vmx/MsrHandlers.h
@@ -15,11 +15,14 @@
// Functions //
//////////////////////////////////////////////////
-VOID
-MsrHandleRdmsrVmexit(PGUEST_REGS GuestRegs);
+BOOLEAN
+MsrHandleIsHypervSyntheticMsr(_In_ UINT32 TargetMsr);
VOID
-MsrHandleWrmsrVmexit(PGUEST_REGS GuestRegs);
+MsrHandleRdmsrVmexit(VIRTUAL_MACHINE_STATE * VCpu);
+
+VOID
+MsrHandleWrmsrVmexit(VIRTUAL_MACHINE_STATE * VCpu);
BOOLEAN
MsrHandleSetMsrBitmap(VIRTUAL_MACHINE_STATE * VCpu, UINT32 Msr, BOOLEAN ReadDetection, BOOLEAN WriteDetection);
diff --git a/hyperdbg/hprdbghv/header/vmm/vmx/Mtf.h b/hyperdbg/hyperhv/header/vmm/vmx/Mtf.h
similarity index 100%
rename from hyperdbg/hprdbghv/header/vmm/vmx/Mtf.h
rename to hyperdbg/hyperhv/header/vmm/vmx/Mtf.h
diff --git a/hyperdbg/hprdbghv/header/vmm/vmx/ProtectedHv.h b/hyperdbg/hyperhv/header/vmm/vmx/ProtectedHv.h
similarity index 90%
rename from hyperdbg/hprdbghv/header/vmm/vmx/ProtectedHv.h
rename to hyperdbg/hyperhv/header/vmm/vmx/ProtectedHv.h
index aeb1f8f0..9f8d669f 100644
--- a/hyperdbg/hprdbghv/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/hprdbghv/header/vmm/vmx/Vmcall.h b/hyperdbg/hyperhv/header/vmm/vmx/Vmcall.h
similarity index 82%
rename from hyperdbg/hprdbghv/header/vmm/vmx/Vmcall.h
rename to hyperdbg/hyperhv/header/vmm/vmx/Vmcall.h
index 9eb06fab..33001dc2 100644
--- a/hyperdbg/hprdbghv/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
@@ -297,6 +296,84 @@
*/
#define VMCALL_DISABLE_OR_ENABLE_MBEC 0x0000002d
+/**
+ * @brief VMCALL to bypass caching policies to read MMIO
+ *
+ */
+#define VMCALL_READ_PHYSICAL_MEM_BYPASS_CACHING_POLICIES 0x0000002e // not used
+
+/**
+ * @brief VMCALL to bypass caching policies to write MMIO
+ *
+ */
+#define VMCALL_WRITE_PHYSICAL_MEM_BYPASS_CACHING_POLICIES 0x0000002f // not used
+
+/**
+ * @brief VMCALL to read physical memory
+ *
+ */
+#define VMCALL_READ_PHYSICAL_MEMORY 0x00000030
+
+/**
+ * @brief VMCALL to write physical memory
+ *
+ */
+#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/hprdbghv/header/vmm/vmx/Vmx.h b/hyperdbg/hyperhv/header/vmm/vmx/Vmx.h
similarity index 64%
rename from hyperdbg/hprdbghv/header/vmm/vmx/Vmx.h
rename to hyperdbg/hyperhv/header/vmm/vmx/Vmx.h
index 6fd11bec..2cb7b05d 100644
--- a/hyperdbg/hprdbghv/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,44 +250,9 @@ VmxPerformVirtualizationOnAllCores();
BOOLEAN
VmxTerminate();
-VOID
-VmxPerformTermination();
-
-_Success_(return != FALSE)
-BOOLEAN
-VmxAllocateVmxonRegion(_Out_ VIRTUAL_MACHINE_STATE * VCpu);
-
-_Success_(return != FALSE)
-BOOLEAN
-VmxAllocateVmcsRegion(_Out_ VIRTUAL_MACHINE_STATE * VCpu);
-
-BOOLEAN
-VmxAllocateVmmStack(_Inout_ VIRTUAL_MACHINE_STATE * VCpu);
-
-BOOLEAN
-VmxAllocateMsrBitmap(_Inout_ VIRTUAL_MACHINE_STATE * VCpu);
-
-BOOLEAN
-VmxAllocateIoBitmaps(_Inout_ VIRTUAL_MACHINE_STATE * VCpu);
-
-UINT64 *
-VmxAllocateInvalidMsrBimap();
-
-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);
@@ -409,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();
@@ -421,21 +307,25 @@ VmxGetCurrentExecutionMode();
BOOLEAN
VmxGetCurrentLaunchState();
-_Success_(return)
-BOOLEAN
-VmxGetSegmentDescriptor(_In_ PUCHAR GdtBase, _In_ UINT16 Selector, _Out_ PVMX_SEGMENT_SELECTOR SegmentSelector);
-
UINT32
VmxCompatibleStrlen(const CHAR * S);
UINT32
-VmxCompatibleWcslen(const wchar_t * S);
+VmxCompatibleWcslen(const WCHAR * S);
INT32
-VmxCompatibleStrcmp(const CHAR * Address1, const CHAR * Address2);
+VmxCompatibleStrcmp(const CHAR * Address1,
+ const CHAR * Address2,
+ SIZE_T Num,
+ BOOLEAN IsStrncmp);
INT32
-VmxCompatibleWcscmp(const wchar_t * Address1, const wchar_t * Address2);
+VmxCompatibleWcscmp(const WCHAR * Address1,
+ const WCHAR * Address2,
+ SIZE_T Num,
+ BOOLEAN IsWcsncmp);
INT32
-VmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, size_t Count);
+VmxCompatibleMemcmp(const CHAR * Address1,
+ const CHAR * Address2,
+ SIZE_T Count);
diff --git a/hyperdbg/hprdbghv/header/vmm/vmx/VmxBroadcast.h b/hyperdbg/hyperhv/header/vmm/vmx/VmxBroadcast.h
similarity index 100%
rename from hyperdbg/hprdbghv/header/vmm/vmx/VmxBroadcast.h
rename to hyperdbg/hyperhv/header/vmm/vmx/VmxBroadcast.h
diff --git a/hyperdbg/hprdbghv/header/vmm/vmx/VmxMechanisms.h b/hyperdbg/hyperhv/header/vmm/vmx/VmxMechanisms.h
similarity index 100%
rename from hyperdbg/hprdbghv/header/vmm/vmx/VmxMechanisms.h
rename to hyperdbg/hyperhv/header/vmm/vmx/VmxMechanisms.h
diff --git a/hyperdbg/hyperhv/header/vmm/vmx/VmxRegions.h b/hyperdbg/hyperhv/header/vmm/vmx/VmxRegions.h
new file mode 100644
index 00000000..e9c8b175
--- /dev/null
+++ b/hyperdbg/hyperhv/header/vmm/vmx/VmxRegions.h
@@ -0,0 +1,48 @@
+/**
+ * @file VmxRegions.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Headers for implement allocations for VMX Regions (VMXON Region, VMCS, MSR Bitmap and etc.)
+ * @details
+ * @version 0.9
+ * @date 2024-06-03
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+_Success_(return != FALSE)
+BOOLEAN
+VmxAllocateVmxonRegion(_Out_ VIRTUAL_MACHINE_STATE * VCpu);
+
+_Success_(return != FALSE)
+BOOLEAN
+VmxAllocateVmcsRegion(_Out_ VIRTUAL_MACHINE_STATE * VCpu);
+
+BOOLEAN
+VmxAllocateVmmStack(_Inout_ VIRTUAL_MACHINE_STATE * VCpu);
+
+BOOLEAN
+VmxAllocateMsrBitmap(_Inout_ VIRTUAL_MACHINE_STATE * VCpu);
+
+BOOLEAN
+VmxAllocateIoBitmaps(_Inout_ VIRTUAL_MACHINE_STATE * VCpu);
+
+UINT64 *
+VmxAllocateInvalidMsrBimap();
+
+BOOLEAN
+VmxAllocateHostIdt(_Inout_ VIRTUAL_MACHINE_STATE * VCpu);
+
+BOOLEAN
+VmxAllocateHostGdt(_Inout_ VIRTUAL_MACHINE_STATE * VCpu);
+
+BOOLEAN
+VmxAllocateHostTss(_Inout_ VIRTUAL_MACHINE_STATE * VCpu);
+
+BOOLEAN
+VmxAllocateHostInterruptStack(_Inout_ VIRTUAL_MACHINE_STATE * VCpu);
diff --git a/hyperdbg/hyperhv/hyperhv.def b/hyperdbg/hyperhv/hyperhv.def
new file mode 100644
index 00000000..c0ec4aff
--- /dev/null
+++ b/hyperdbg/hyperhv/hyperhv.def
@@ -0,0 +1,6 @@
+LIBRARY hyperhv
+
+EXPORTS
+
+ DllInitialize PRIVATE
+ DllUnload PRIVATE
\ No newline at end of file
diff --git a/hyperdbg/hprdbghv/hprdbghv.vcxproj b/hyperdbg/hyperhv/hyperhv.vcxproj
similarity index 74%
rename from hyperdbg/hprdbghv/hprdbghv.vcxproj
rename to hyperdbg/hyperhv/hyperhv.vcxproj
index 9004260e..53c55a14 100644
--- a/hyperdbg/hprdbghv/hprdbghv.vcxproj
+++ b/hyperdbg/hyperhv/hyperhv.vcxproj
@@ -1,5 +1,8 @@
+
+
+ debug
@@ -17,9 +20,9 @@
12.0DebugWin32
- hprdbghv
+ hyperhv$(LatestTargetPlatformVersion)
- hprdbghv
+ hyperhv
@@ -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)\
@@ -75,15 +81,16 @@
$(IntDir)$(TargetName).pchLevel4ZYDIS_STATIC_BUILD;ZYCORE_STATIC_BUILD;ZYAN_NO_LIBC;ZYDIS_NO_LIBC;%(PreprocessorDefinitions)
+ stdcpp20true%(AdditionalDependencies)
- %(AdditionalDependencies);;$(SolutionDir)libraries\zydis\kernel\Zycore.lib;$(SolutionDir)libraries\zydis\kernel\Zydis.lib
+ %(AdditionalDependencies);$(SolutionDir)libraries\zydis\kernel\Zycore.lib;$(SolutionDir)libraries\zydis\kernel\Zydis.lib;$(SolutionDir)build\bin\$(Configuration)\hyperevade.libtrue
- hprdbghv.def
+ hyperhv.defSHA256
@@ -97,9 +104,9 @@
true
- %(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)ntoskrnl.lib;$(DDK_LIB_PATH)hal.lib;$(DDK_LIB_PATH)wmilib.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfLdr.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfDriverEntry.lib;$(SolutionDir)libraries\zydis\kernel\Zycore.lib;$(SolutionDir)libraries\zydis\kernel\Zydis.lib
+ %(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)ntoskrnl.lib;$(DDK_LIB_PATH)hal.lib;$(DDK_LIB_PATH)wmilib.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfLdr.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfDriverEntry.lib;$(SolutionDir)libraries\zydis\kernel\Zycore.lib;$(SolutionDir)libraries\zydis\kernel\Zydis.lib;$(SolutionDir)build\bin\$(Configuration)\hyperevade.libtrue
- hprdbghv.def
+ hyperhv.deftrue
@@ -110,8 +117,9 @@
pch.h$(IntDir)$(TargetName).pchNeither
- Disabled
+ FullZYDIS_STATIC_BUILD;ZYCORE_STATIC_BUILD;ZYAN_NO_LIBC;ZYDIS_NO_LIBC;%(PreprocessorDefinitions)
+ stdcpp20SHA256
@@ -124,11 +132,16 @@
+
+
+
+
+
@@ -136,6 +149,7 @@
+
@@ -145,25 +159,28 @@
-
+
+
-
+
-
-
+
+
+
+
@@ -188,6 +205,7 @@
+
@@ -221,23 +239,28 @@
+
+
+
+
+
-
+
@@ -246,6 +269,7 @@
+
@@ -253,15 +277,16 @@
-
+
-
-
-
+
+
+
+
@@ -274,10 +299,24 @@
+
+
+
+
+
+
+
+ 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/hprdbghv/hprdbghv.vcxproj.filters b/hyperdbg/hyperhv/hyperhv.vcxproj.filters
similarity index 86%
rename from hyperdbg/hprdbghv/hprdbghv.vcxproj.filters
rename to hyperdbg/hyperhv/hyperhv.vcxproj.filters
index 0ee1ae4a..fbbe5e33 100644
--- a/hyperdbg/hprdbghv/hprdbghv.vcxproj.filters
+++ b/hyperdbg/hyperhv/hyperhv.vcxproj.filters
@@ -63,12 +63,6 @@
{20741da2-52c0-4c6c-ab4f-d8a29bae81e7}
-
- {33ddc8db-b65a-4ebd-a214-1b8060bf6ab0}
-
-
- {3646ca74-c21f-4d7d-8e93-51ec5fae9d0f}
- {bd4cf053-c1f6-40df-984d-37f9f50b85ac}
@@ -135,6 +129,24 @@
{0c6f7e8d-4829-4a45-b09d-4c40cfcc5cf7}
+
+ {36f1d8ba-6527-4c1b-8016-ae66d1bd41e7}
+
+
+ {8efcd014-6f76-436f-bca7-33f1cf2bd980}
+
+
+ {6136b867-021b-4f61-aa79-c1b6ccafe670}
+
+
+ {c310c4a9-c337-454d-94ca-4c6b1216cf41}
+
+
+ {20e523af-8b6d-4293-bd6d-ce6087f2d4a2}
+
+
+ {58bb81a8-dd12-4e47-b6c8-7d61981fef62}
+
@@ -191,9 +203,6 @@
code\memory
-
- code\memory
- code\components\registers
@@ -212,9 +221,6 @@
code\vmm\vmx
-
- code\platform
- code\globals
@@ -224,18 +230,12 @@
code\interface
-
- code\transparency
- code\hooks\ept-hookcode\hooks\syscall-hook
-
- code\hooks\syscall-hook
- code\broadcast
@@ -302,6 +302,45 @@
code\interface
+
+ code\platform
+
+
+ code\memory
+
+
+ code\devices
+
+
+ code\processor
+
+
+ code\mmio
+
+
+ code\hooks\syscall-hook
+
+
+ code\interface
+
+
+ code\processor
+
+
+ code\vmm\vmx
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\components\callback
+
@@ -310,9 +349,6 @@
header\common
-
- header\common
- header\common
@@ -355,9 +391,6 @@
header\memory
-
- header\memory
- header\vmm\vmx
@@ -373,12 +406,6 @@
header\vmm\vmx
-
- header\platform
-
-
- header\platform
- header\globals
@@ -391,9 +418,6 @@
header\common
-
- header\transparency
- header\interface
@@ -559,6 +583,45 @@
header\interface
+
+ header\platform
+
+
+ header\memory
+
+
+ header\vmm\vmx
+
+
+ header\devices
+
+
+ header\processor
+
+
+ header\mmio
+
+
+ header\hooks
+
+
+ header\processor
+
+
+ header\vmm\vmx
+
+
+ header\platform
+
+
+ header\platform
+
+
+ header\platform
+
+
+ header\components\callback
+
@@ -582,5 +645,11 @@
code\assembly
+
+ 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/hprdbghv/pch.c b/hyperdbg/hyperhv/pch.c
similarity index 100%
rename from hyperdbg/hprdbghv/pch.c
rename to hyperdbg/hyperhv/pch.c
diff --git a/hyperdbg/hprdbghv/pch.h b/hyperdbg/hyperhv/pch.h
similarity index 68%
rename from hyperdbg/hprdbghv/pch.h
rename to hyperdbg/hyperhv/pch.h
index 6f7f8fab..43398529 100644
--- a/hyperdbg/hprdbghv/pch.h
+++ b/hyperdbg/hyperhv/pch.h
@@ -17,17 +17,6 @@
#pragma warning(disable : 4201) // Suppress nameless struct/union warning
-//
-// Windows defined functions
-//
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
//
// Scope definitions
//
@@ -35,6 +24,23 @@
#define HYPERDBG_KERNEL_MODE
#define HYPERDBG_VMM
+//
+// Environment headers
+//
+#include "platform/general/header/Environment.h"
+
+#ifdef HYPERDBG_ENV_WINDOWS
+
+//
+// General WDK headers
+//
+# include
+# include
+# include
+# include
+
+#endif // HYPERDBG_ENV_WINDOWS
+
//
// Definition of Intel primitives (External header)
//
@@ -48,15 +54,21 @@
//
// HyperDbg Kernel-mode headers
//
-#include "Configuration.h"
+#include "config/Configuration.h"
#include "macros/MetaMacros.h"
-#include "platform/CrossApi.h"
-#include "platform/Environment.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/PlatformIntrinsicsVmx.h"
//
// VMM Callbacks
//
-#include "SDK/Modules/VMM.h"
+#include "SDK/modules/VMM.h"
//
// The core's state
@@ -67,20 +79,22 @@
// VMX and EPT Types
//
#include "vmm/vmx/Vmx.h"
+#include "vmm/vmx/VmxRegions.h"
#include "vmm/ept/Ept.h"
-#include "SDK/Imports/HyperDbgVmmImports.h"
+#include "SDK/imports/kernel/HyperDbgVmmImports.h"
+
+//
+// Hyper-V TLFS
+//
+#include "hyper-v/HypervTlfs.h"
//
// VMX and Capabilities
//
-#include "transparency/Transparency.h"
#include "vmm/vmx/VmxBroadcast.h"
#include "memory/MemoryMapper.h"
#include "interface/Dispatch.h"
-#include "common/Dpc.h"
-#include "vmm/vmx/HypervTlfs.h"
#include "common/Msr.h"
-#include "memory/PoolManager.h"
#include "common/Trace.h"
#include "assembly/InlineAsm.h"
#include "vmm/ept/Vpid.h"
@@ -88,17 +102,21 @@
#include "memory/Layout.h"
#include "memory/SwitchLayout.h"
#include "memory/AddressCheck.h"
+#include "memory/Segmentation.h"
#include "common/Bitwise.h"
#include "common/Common.h"
-#include "components/spinlock/header/Spinlock.h"
#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"
#include "vmm/vmx/IdtEmulation.h"
#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"
@@ -106,9 +124,11 @@
#include "vmm/vmx/VmxMechanisms.h"
#include "hooks/Hooks.h"
#include "hooks/ModeBasedExecHook.h"
+#include "hooks/SyscallCallback.h"
#include "interface/Callback.h"
#include "features/DirtyLogging.h"
#include "features/CompatibilityChecks.h"
+#include "mmio/MmioShadowing.h"
//
// Disassembler Header
@@ -139,6 +159,11 @@
#include "components/optimizations/header/BinarySearch.h"
#include "components/optimizations/header/InsertionSort.h"
+//
+// Spinlocks
+//
+#include "components/spinlock/header/Spinlock.h"
+
//
// Global Variables should be the last header to include
//
@@ -148,5 +173,12 @@
//
// HyperLog Module
//
-#include "SDK/Modules/HyperLog.h"
-#include "SDK/Imports/HyperDbgHyperLogIntrinsics.h"
+#include "SDK/modules/HyperLog.h"
+#include "SDK/imports/kernel/HyperDbgHyperLogIntrinsics.h"
+#include "components/callback/header/HyperLogCallback.h"
+
+//
+// Transparent-mode (hyperevade) headers
+//
+#include "SDK/modules/HyperEvade.h"
+#include "SDK/imports/kernel/HyperDbgHyperEvade.h"
diff --git a/hyperdbg/hyperkd/CMakeLists.txt b/hyperdbg/hyperkd/CMakeLists.txt
new file mode 100644
index 00000000..2dc81aaf
--- /dev/null
+++ b/hyperdbg/hyperkd/CMakeLists.txt
@@ -0,0 +1,102 @@
+# Code generated by Visual Studio kit, DO NOT EDIT.
+set(SourceFiles
+ "../include/components/optimizations/code/AvlTree.c"
+ "../include/components/optimizations/code/BinarySearch.c"
+ "../include/components/optimizations/code/InsertionSort.c"
+ "../include/components/optimizations/code/OptimizationsExamples.c"
+ "../include/components/spinlock/code/Spinlock.c"
+ "../include/platform/kernel/code/PlatformMem.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"
+ "code/common/Common.c"
+ "code/debugger/broadcast/DpcRoutines.c"
+ "code/debugger/broadcast/HaltedBroadcast.c"
+ "code/debugger/broadcast/HaltedRoutines.c"
+ "code/debugger/commands/BreakpointCommands.c"
+ "code/debugger/commands/Callstack.c"
+ "code/debugger/commands/DebuggerCommands.c"
+ "code/debugger/commands/ExtensionCommands.c"
+ "code/debugger/communication/SerialConnection.c"
+ "code/debugger/core/Debugger.c"
+ "code/debugger/core/DebuggerVmcalls.c"
+ "code/debugger/core/HaltedCore.c"
+ "code/debugger/events/ApplyEvents.c"
+ "code/debugger/events/DebuggerEvents.c"
+ "code/debugger/events/Termination.c"
+ "code/debugger/events/ValidateEvents.c"
+ "code/debugger/kernel-level/Kd.c"
+ "code/debugger/memory/Allocations.c"
+ "code/debugger/meta-events/MetaDispatch.c"
+ "code/debugger/meta-events/Tracing.c"
+ "code/debugger/objects/Process.c"
+ "code/debugger/objects/Thread.c"
+ "code/debugger/script-engine/ScriptEngine.c"
+ "code/debugger/tests/KernelTests.c"
+ "code/debugger/user-level/Attaching.c"
+ "code/debugger/user-level/ThreadHolder.c"
+ "code/debugger/user-level/Ud.c"
+ "code/debugger/user-level/UserAccess.c"
+ "code/driver/Driver.c"
+ "code/driver/Ioctl.c"
+ "code/driver/Loader.c"
+ "../include/components/optimizations/header/AvlTree.h"
+ "../include/components/optimizations/header/BinarySearch.h"
+ "../include/components/optimizations/header/InsertionSort.h"
+ "../include/components/optimizations/header/OptimizationsExamples.h"
+ "../include/components/spinlock/header/Spinlock.h"
+ "../include/macros/MetaMacros.h"
+ "../include/platform/kernel/header/Environment.h"
+ "../include/platform/kernel/header/PlatformMem.h"
+ "header/assembly/Assembly.h"
+ "header/common/Common.h"
+ "header/common/Dpc.h"
+ "header/debugger/broadcast/DpcRoutines.h"
+ "header/debugger/broadcast/HaltedBroadcast.h"
+ "header/debugger/broadcast/HaltedRoutines.h"
+ "header/debugger/commands/BreakpointCommands.h"
+ "header/debugger/commands/Callstack.h"
+ "header/debugger/commands/DebuggerCommands.h"
+ "header/debugger/commands/ExtensionCommands.h"
+ "header/debugger/communication/SerialConnection.h"
+ "header/debugger/core/Debugger.h"
+ "header/debugger/core/DebuggerVmcalls.h"
+ "header/debugger/core/HaltedCore.h"
+ "header/debugger/core/State.h"
+ "header/debugger/events/ApplyEvents.h"
+ "header/debugger/events/DebuggerEvents.h"
+ "header/debugger/events/Termination.h"
+ "header/debugger/events/ValidateEvents.h"
+ "header/debugger/kernel-level/Kd.h"
+ "header/debugger/memory/Allocations.h"
+ "header/debugger/memory/Memory.h"
+ "header/debugger/meta-events/MetaDispatch.h"
+ "header/debugger/meta-events/Tracing.h"
+ "header/debugger/objects/Process.h"
+ "header/debugger/objects/Thread.h"
+ "header/debugger/script-engine/ScriptEngine.h"
+ "header/debugger/tests/KernelTests.h"
+ "header/debugger/user-level/Attaching.h"
+ "header/debugger/user-level/ThreadHolder.h"
+ "header/debugger/user-level/Ud.h"
+ "header/debugger/user-level/UserAccess.h"
+ "header/driver/Driver.h"
+ "header/driver/Loader.h"
+ "header/globals/Global.h"
+ "header/pch.h"
+ "code/assembly/AsmDebugger.asm"
+)
+include_directories(
+ "../include"
+ "header"
+ "code"
+ "."
+ "../dependencies"
+ "../script-eval"
+)
+wdk_add_driver(hyperkd
+ KMDF 1.15
+ ${SourceFiles}
+)
diff --git a/hyperdbg/hprdbgkd/code/assembly/AsmDebugger.asm b/hyperdbg/hyperkd/code/assembly/AsmDebugger.asm
similarity index 97%
rename from hyperdbg/hprdbgkd/code/assembly/AsmDebugger.asm
rename to hyperdbg/hyperkd/code/assembly/AsmDebugger.asm
index 7899226c..0c35173c 100644
--- a/hyperdbg/hprdbgkd/code/assembly/AsmDebugger.asm
+++ b/hyperdbg/hyperkd/code/assembly/AsmDebugger.asm
@@ -57,7 +57,7 @@ SaveTheRegisters:
push R15
; The function will be called as DebuggerCheckForCondition(PGUEST_REGS Regs, PVOID Context);
- call R8 ; Because R8 contains the 4th argument and a pointer to the function of target condition code
+ call R8 ; Because R8 contains the 3th argument and a pointer to the function of target condition code
RestoreTheRegisters:
pop R15
diff --git a/hyperdbg/hprdbgkd/code/common/Common.c b/hyperdbg/hyperkd/code/common/Common.c
similarity index 100%
rename from hyperdbg/hprdbgkd/code/common/Common.c
rename to hyperdbg/hyperkd/code/common/Common.c
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/hprdbgkd/code/debugger/broadcast/DpcRoutines.c b/hyperdbg/hyperkd/code/debugger/broadcast/DpcRoutines.c
similarity index 76%
rename from hyperdbg/hprdbgkd/code/debugger/broadcast/DpcRoutines.c
rename to hyperdbg/hyperkd/code/debugger/broadcast/DpcRoutines.c
index 643b8834..9296f576 100644
--- a/hyperdbg/hprdbgkd/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
@@ -50,7 +50,7 @@ DpcRoutineRunTaskOnSingleCore(UINT32 CoreNumber, PVOID Routine, PVOID DeferredCo
//
// Allocate Memory for DPC
//
- Dpc = CrsAllocateZeroedNonPagedPool(sizeof(KDPC));
+ Dpc = PlatformMemAllocateZeroedNonPagedPool(sizeof(KDPC));
if (!Dpc)
{
@@ -91,7 +91,7 @@ DpcRoutineRunTaskOnSingleCore(UINT32 CoreNumber, PVOID Routine, PVOID DeferredCo
//
// We can't get the lock, probably sth goes wrong !
//
- CrsFreePool(Dpc);
+ PlatformMemFreePool(Dpc);
return STATUS_UNSUCCESSFUL;
}
@@ -110,7 +110,7 @@ DpcRoutineRunTaskOnSingleCore(UINT32 CoreNumber, PVOID Routine, PVOID DeferredCo
//
// Now it's safe to deallocate the bugger
//
- CrsFreePool(Dpc);
+ PlatformMemFreePool(Dpc);
return STATUS_SUCCESS;
}
@@ -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/hprdbgkd/code/debugger/broadcast/HaltedBroadcast.c b/hyperdbg/hyperkd/code/debugger/broadcast/HaltedBroadcast.c
similarity index 100%
rename from hyperdbg/hprdbgkd/code/debugger/broadcast/HaltedBroadcast.c
rename to hyperdbg/hyperkd/code/debugger/broadcast/HaltedBroadcast.c
diff --git a/hyperdbg/hprdbgkd/code/debugger/broadcast/HaltedRoutines.c b/hyperdbg/hyperkd/code/debugger/broadcast/HaltedRoutines.c
similarity index 100%
rename from hyperdbg/hprdbgkd/code/debugger/broadcast/HaltedRoutines.c
rename to hyperdbg/hyperkd/code/debugger/broadcast/HaltedRoutines.c
diff --git a/hyperdbg/hprdbgkd/code/debugger/commands/BreakpointCommands.c b/hyperdbg/hyperkd/code/debugger/commands/BreakpointCommands.c
similarity index 79%
rename from hyperdbg/hprdbgkd/code/debugger/commands/BreakpointCommands.c
rename to hyperdbg/hyperkd/code/debugger/commands/BreakpointCommands.c
index 5e500c31..496e600b 100644
--- a/hyperdbg/hprdbgkd/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)
{
@@ -214,7 +214,8 @@ BreakpointRestoreTheTrapFlagOnceTriggered(UINT32 ProcessId, UINT32 ThreadId)
SuccessfullyStored = InsertionSortInsertItem((UINT64 *)&g_TrapFlagState.ThreadInformation[0],
&g_TrapFlagState.NumberOfItems,
MAXIMUM_NUMBER_OF_THREAD_INFORMATION_FOR_TRAPS,
- ProcThrdInfo.asUInt);
+ &Index, // not used
+ ProcThrdInfo.AsUInt);
goto Return;
}
@@ -289,9 +290,8 @@ BreakpointCheckAndHandleDebugBreakpoint(UINT32 CoreId)
//
KdHandleDebugEventsWhenKernelDebuggerIsAttached(DbgState, TrapSetByDebugger);
}
- else if (UdCheckAndHandleBreakpointsAndDebugBreaks(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
@@ -337,9 +337,8 @@ BreakpointCheckAndHandleDebugBreakpoint(UINT32 CoreId)
//
KdHandleDebugEventsWhenKernelDebuggerIsAttached(DbgState, TrapSetByDebugger);
}
- else if (UdCheckAndHandleBreakpointsAndDebugBreaks(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
@@ -433,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)
{
@@ -460,22 +458,6 @@ BreakpointCheckAndHandleReApplyingBreakpoint(UINT32 CoreId)
(UINT64)&BreakpointByte,
sizeof(BYTE));
- //
- // Check if we should re-enabled IF bit of RFLAGS or not
- //
- if (DbgState->SoftwareBreakpointState->SetRflagsIFBitOnMtf)
- {
- RFLAGS Rflags = {0};
-
- Rflags.AsUInt = VmFuncGetRflags();
-
- Rflags.InterruptEnableFlag = TRUE;
-
- VmFuncSetRflags(Rflags.AsUInt);
-
- DbgState->SoftwareBreakpointState->SetRflagsIFBitOnMtf = FALSE;
- }
-
DbgState->SoftwareBreakpointState = NULL;
}
@@ -503,7 +485,6 @@ BreakpointCheckAndHandleDebuggerDefinedBreakpoints(PROCESSOR_DEBUGGING_STATE * D
PLIST_ENTRY TempList = 0;
UINT64 GuestRipPhysical = (UINT64)NULL;
DEBUGGER_TRIGGERED_EVENT_DETAILS TargetContext = {0};
- RFLAGS Rflags = {0};
BOOLEAN AvoidUnsetMtf = FALSE;
BOOLEAN IgnoreUserHandling = FALSE;
@@ -601,9 +582,20 @@ BreakpointCheckAndHandleDebuggerDefinedBreakpoints(PROCESSOR_DEBUGGING_STATE * D
// *** It's not safe to access CurrentBreakpointDesc anymore as the
// breakpoint might be removed ***
//
- KdHandleBreakpointAndDebugBreakpoints(DbgState,
- Reason,
- &TargetContext);
+ if (g_KernelDebuggerState)
+ {
+ KdHandleBreakpointAndDebugBreakpoints(DbgState,
+ Reason,
+ &TargetContext);
+ }
+ else if (g_UserDebuggerState)
+ {
+ UdHandleInstantBreak(DbgState, Reason, NULL);
+ }
+ else
+ {
+ LogInfo("Err, no debugger is attached to handle the breakpoint");
+ }
}
}
@@ -623,34 +615,20 @@ BreakpointCheckAndHandleDebuggerDefinedBreakpoints(PROCESSOR_DEBUGGING_STATE * D
//
DbgState->SoftwareBreakpointState = CurrentBreakpointDesc;
- //
- // Fire and MTF
- //
- VmFuncSetMonitorTrapFlag(TRUE);
- AvoidUnsetMtf = TRUE;
-
//
// As we want to continue debuggee, the MTF might arrive when the
// host finish executing it's time slice; thus, a clock interrupt
// or an IPI might be arrived and the next instruction is not what
- // we expect, because of that we check if the IF (Interrupt enable)
- // flag of RFLAGS is enabled or not, if enabled then we remove it
- // to avoid any clock-interrupt or IPI to arrive and the next
- // instruction is our next instruction in the current execution
- // context
+ // we expect. The following codes are added because we realized if the execution takes long then
+ // the execution might be switched to another routines, thus, MTF might conclude on
+ // another routine and we might (and will) trigger the same instruction soon
//
- Rflags.AsUInt = VmFuncGetRflags();
+ VmFuncEnableMtfAndChangeExternalInterruptState(DbgState->CoreId);
- if (Rflags.InterruptEnableFlag)
- {
- Rflags.InterruptEnableFlag = FALSE;
- VmFuncSetRflags(Rflags.AsUInt);
-
- //
- // An indicator to restore RFLAGS if to enabled state
- //
- DbgState->SoftwareBreakpointState->SetRflagsIFBitOnMtf = TRUE;
- }
+ //
+ // Avoid unsetting MTF
+ //
+ AvoidUnsetMtf = TRUE;
}
//
@@ -687,66 +665,106 @@ BreakpointHandleBreakpoints(UINT32 CoreId)
UINT64 GuestRip = 0;
PROCESSOR_DEBUGGING_STATE * DbgState = &g_DbgState[CoreId];
+ GuestRip = VmFuncGetRip();
+
+ //
+ // A breakpoint triggered and two things might be happened,
+ // first, a breakpoint is triggered randomly in the computer and
+ // we shouldn't do anything on it (won't change the instruction)
+ // second, the breakpoint is because of the 'bp' command, we should
+ // replace it with exact byte
+ //
+
+ //
+ // Check if the breakpoint is handled by the debugger routines
+ //
+ if (BreakpointCheckAndHandleDebuggerDefinedBreakpoints(DbgState,
+ GuestRip,
+ DEBUGGEE_PAUSING_REASON_DEBUGGEE_SOFTWARE_BREAKPOINT_HIT,
+ FALSE))
+ {
+ //
+ // The breakpoint is handled by the debugger routines
+ // so, we don't need to do anything else
+ //
+ return TRUE;
+ }
+
//
// re-inject #BP back to the guest if not handled by the hidden breakpoint
//
-
if (g_KernelDebuggerState)
{
//
- // Kernel debugger is attached, let's halt everything
- //
- GuestRip = VmFuncGetRip();
-
- //
- // A breakpoint triggered and two things might be happened,
- // first, a breakpoint is triggered randomly in the computer and
- // we shouldn't do anything on it (won't change the instruction)
- // second, the breakpoint is because of the 'bp' command, we should
- // replace it with exact byte
+ // *** Kernel debugger is attached, let's halt everything ***
//
- if (!BreakpointCheckAndHandleDebuggerDefinedBreakpoints(DbgState,
- GuestRip,
- DEBUGGEE_PAUSING_REASON_DEBUGGEE_SOFTWARE_BREAKPOINT_HIT,
- FALSE))
+ //
+ // To avoid the computer crash situation from the HyperDbg's breakpoint hitting while the interception is on
+ // we should always call BreakpointCheckAndHandleDebuggerDefinedBreakpoints first to handle the breakpoint
+ //
+
+ if (g_InterceptBreakpoints || g_InterceptBreakpointsAndEventsForCommandsInRemoteComputer)
{
//
- // To avoid the computer crash situation from the HyperDbg's breakpoint hitting while the interception is on
- // we should always call BreakpointCheckAndHandleDebuggerDefinedBreakpoints first to handle the breakpoint
+ // re-inject back to the guest as not handled if the interception is on and the breakpoint is not from the Hyperdbg's breakpoints
//
+ return FALSE;
+ }
- if (g_InterceptBreakpoints || g_InterceptBreakpointsAndEventsForCommandsInRemoteComputer)
- {
- //
- // re-inject back to the guest as not handled if the interception is on and the breakpoint is not from the Hyperdbg's breakpoints
- //
- return FALSE;
- }
+ //
+ // It's a random breakpoint byte
+ //
+ TargetContext.Context = (PVOID)GuestRip;
+ KdHandleBreakpointAndDebugBreakpoints(DbgState,
+ DEBUGGEE_PAUSING_REASON_DEBUGGEE_SOFTWARE_BREAKPOINT_HIT,
+ &TargetContext);
+ //
+ // Increment rip
+ //
+ VmFuncPerformRipIncrement(DbgState->CoreId);
+
+ //
+ // By default, we handle the random breakpoints if the kernel debugger is attached
+ //
+ return TRUE;
+ }
+ else if (g_UserDebuggerState)
+ {
+ //
+ // *** User debugger is attached, let's halt the process ***
+ //
+
+ //
+ // Check if it's a random breakpoint byte
+ //
+ if (UdHandleInstantBreak(DbgState,
+ DEBUGGEE_PAUSING_REASON_DEBUGGEE_SOFTWARE_BREAKPOINT_HIT,
+ NULL))
+ {
//
- // It's a random breakpoint byte
+ // if the above function returns true, it's handled in the user debugger
//
- TargetContext.Context = (PVOID)GuestRip;
- KdHandleBreakpointAndDebugBreakpoints(DbgState,
- DEBUGGEE_PAUSING_REASON_DEBUGGEE_SOFTWARE_BREAKPOINT_HIT,
- &TargetContext);
//
// Increment rip
//
VmFuncPerformRipIncrement(DbgState->CoreId);
+
+ return TRUE;
}
- }
- else
- {
+
//
- // re-inject back to the guest as not handled here
+ // By default, we won't handle the random (unrelated) breakpoints in the user debugger
//
return FALSE;
}
- return TRUE;
+ //
+ // *** re-inject back to the guest as not handled here ***
+ //
+ return FALSE;
}
/**
@@ -754,11 +772,12 @@ BreakpointHandleBreakpoints(UINT32 CoreId)
* @detail this function won't remove the descriptor from the list
*
* @param BreakpointDescriptor
+ * @param SwitchToTargetMemoryLayout If TRUE, it will switch to the target memory layout
*
* @return BOOLEAN
*/
BOOLEAN
-BreakpointWrite(PDEBUGGEE_BP_DESCRIPTOR BreakpointDescriptor)
+BreakpointWrite(PDEBUGGEE_BP_DESCRIPTOR BreakpointDescriptor, BOOLEAN SwitchToTargetMemoryLayout)
{
BYTE PreviousByte = NULL_ZERO;
BYTE BreakpointByte = 0xcc; // int 3
@@ -766,15 +785,44 @@ BreakpointWrite(PDEBUGGEE_BP_DESCRIPTOR BreakpointDescriptor)
//
// Check if address is safe (only one byte for 0xcc)
//
- if (!CheckAccessValidityAndSafety(BreakpointDescriptor->Address, sizeof(BYTE)))
+
+ if (SwitchToTargetMemoryLayout)
{
- return FALSE;
+ if (!CheckAccessValidityAndSafetyByProcessId(BreakpointDescriptor->Address, sizeof(BYTE), BreakpointDescriptor->Pid))
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (!CheckAccessValidityAndSafety(BreakpointDescriptor->Address, sizeof(BYTE)))
+ {
+ return FALSE;
+ }
}
//
// Read and save previous byte and save it to the descriptor
//
- MemoryMapperReadMemorySafeOnTargetProcess(BreakpointDescriptor->Address, &PreviousByte, sizeof(BYTE));
+ if (SwitchToTargetMemoryLayout)
+ {
+ MemoryMapperReadMemoryUnsafe(
+ BreakpointDescriptor->Address,
+ &PreviousByte,
+ sizeof(BYTE),
+ BreakpointDescriptor->Pid);
+ }
+ else
+ {
+ MemoryMapperReadMemorySafeOnTargetProcess(
+ BreakpointDescriptor->Address,
+ &PreviousByte,
+ sizeof(BYTE));
+ }
+
+ //
+ // Store the previous byte
+ //
BreakpointDescriptor->PreviousByte = PreviousByte;
//
@@ -786,9 +834,18 @@ BreakpointWrite(PDEBUGGEE_BP_DESCRIPTOR BreakpointDescriptor)
//
// Apply the breakpoint
//
- MemoryMapperWriteMemorySafeByPhysicalAddress(BreakpointDescriptor->PhysAddress,
- (UINT64)&BreakpointByte,
- sizeof(BYTE));
+ if (SwitchToTargetMemoryLayout)
+ {
+ MemoryMapperWriteMemorySafeFromVmxNonRootyPhysicalAddress(BreakpointDescriptor->PhysAddress,
+ (PVOID)&BreakpointByte,
+ sizeof(BYTE));
+ }
+ else
+ {
+ MemoryMapperWriteMemorySafeByPhysicalAddress(BreakpointDescriptor->PhysAddress,
+ (UINT64)&BreakpointByte,
+ sizeof(BYTE));
+ }
return TRUE;
}
@@ -885,34 +942,46 @@ BreakpointGetEntryByAddress(UINT64 Address)
/**
* @brief Add new breakpoints
* @param BpDescriptor
+ * @param SwitchToTargetMemoryLayout
*
* @return BOOLEAN
*/
BOOLEAN
-BreakpointAddNew(PDEBUGGEE_BP_PACKET BpDescriptorArg)
+BreakpointAddNew(PDEBUGGEE_BP_PACKET BpDescriptorArg, BOOLEAN SwitchToTargetMemoryLayout)
{
- PDEBUGGEE_BP_DESCRIPTOR BreakpointDescriptor = NULL;
CR3_TYPE GuestCr3 = {0};
+ PDEBUGGEE_BP_DESCRIPTOR BreakpointDescriptor = NULL;
BOOLEAN IsAddress32Bit = FALSE;
//
// Find the current process cr3
//
- GuestCr3.Flags = LayoutGetCurrentProcessCr3().Flags;
+ if (SwitchToTargetMemoryLayout)
+ {
+ //
+ // Check if the process id is valid or not
+ //
+ if (BpDescriptorArg->Pid != DEBUGGEE_BP_APPLY_TO_ALL_PROCESSES &&
+ !CommonIsProcessExist(BpDescriptorArg->Pid))
+ {
+ //
+ // Process id is invalid (Set the error)
+ //
+ BpDescriptorArg->Result = DEBUGGER_ERROR_INVALID_PROCESS_ID;
+ return FALSE;
+ }
+
+ GuestCr3.Flags = LayoutGetCr3ByProcessId(BpDescriptorArg->Pid).Flags;
+ }
+ else
+ {
+ GuestCr3.Flags = LayoutGetCurrentProcessCr3().Flags;
+ }
//
// *** Validate arguments ***
//
- //
- // Check if address is safe (only one byte for 0xcc)
- //
- if (!CheckAccessValidityAndSafety(BpDescriptorArg->Address, sizeof(BYTE)))
- {
- BpDescriptorArg->Result = DEBUGGER_ERROR_EDIT_MEMORY_STATUS_INVALID_ADDRESS_BASED_ON_CURRENT_PROCESS;
- return FALSE;
- }
-
//
// Check if the core number is not invalid
//
@@ -939,7 +1008,27 @@ BreakpointAddNew(PDEBUGGEE_BP_PACKET BpDescriptorArg)
}
//
- // We won't check for process id and thread id, if these arguments are invalid
+ // Check if address is safe (only one byte for 0xcc)
+ //
+ if (SwitchToTargetMemoryLayout)
+ {
+ if (!CheckAccessValidityAndSafetyByProcessId(BpDescriptorArg->Address, sizeof(BYTE), BpDescriptorArg->Pid))
+ {
+ BpDescriptorArg->Result = DEBUGGER_ERROR_EDIT_MEMORY_STATUS_INVALID_ADDRESS_BASED_ON_CURRENT_PROCESS;
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (!CheckAccessValidityAndSafety(BpDescriptorArg->Address, sizeof(BYTE)))
+ {
+ BpDescriptorArg->Result = DEBUGGER_ERROR_EDIT_MEMORY_STATUS_INVALID_ADDRESS_BASED_ON_CURRENT_PROCESS;
+ return FALSE;
+ }
+ }
+
+ //
+ // On the debugger mode, we won't check for process id and thread id, if these arguments are invalid
// then the HyperDbg simply ignores the breakpoints but it makes the computer slow
// it just won't be triggered
//
@@ -952,7 +1041,8 @@ BreakpointAddNew(PDEBUGGEE_BP_PACKET BpDescriptorArg)
//
// Get the pre-allocated buffer
//
- BreakpointDescriptor = (DEBUGGEE_BP_DESCRIPTOR *)PoolManagerRequestPool(BREAKPOINT_DEFINITION_STRUCTURE, TRUE, sizeof(DEBUGGEE_BP_DESCRIPTOR));
+ BreakpointDescriptor = (DEBUGGEE_BP_DESCRIPTOR *)
+ PoolManagerRequestPool(BREAKPOINT_DEFINITION_STRUCTURE, TRUE, sizeof(DEBUGGEE_BP_DESCRIPTOR));
if (BreakpointDescriptor == NULL)
{
@@ -994,15 +1084,32 @@ BreakpointAddNew(PDEBUGGEE_BP_PACKET BpDescriptorArg)
// The address is not a kernel address, thus, we check whether the debuggee is running on user-mode
// or not
//
- IsAddress32Bit = KdIsGuestOnUsermode32Bit();
+ if (SwitchToTargetMemoryLayout)
+ {
+ UserAccessIsWow64Process((HANDLE)BpDescriptorArg->Pid, &IsAddress32Bit);
+ }
+ else
+ {
+ IsAddress32Bit = KdIsGuestOnUsermode32Bit();
+ }
}
//
// Use length disassembler engine to get the instruction length
//
- BreakpointDescriptor->InstructionLength = (UINT16)DisassemblerLengthDisassembleEngineInVmxRootOnTargetProcess(
- (PVOID)BpDescriptorArg->Address,
- IsAddress32Bit);
+ if (SwitchToTargetMemoryLayout)
+ {
+ BreakpointDescriptor->InstructionLength = (UINT16)DisassemblerLengthDisassembleEngineByProcessId(
+ (PVOID)BpDescriptorArg->Address,
+ IsAddress32Bit,
+ BpDescriptorArg->Pid);
+ }
+ else
+ {
+ BreakpointDescriptor->InstructionLength = (UINT16)DisassemblerLengthDisassembleEngineInVmxRootOnTargetProcess(
+ (PVOID)BpDescriptorArg->Address,
+ IsAddress32Bit);
+ }
//
// Breakpoints are enabled by default
@@ -1017,7 +1124,7 @@ BreakpointAddNew(PDEBUGGEE_BP_PACKET BpDescriptorArg)
//
// Apply the breakpoint
//
- BreakpointWrite(BreakpointDescriptor);
+ BreakpointWrite(BreakpointDescriptor, SwitchToTargetMemoryLayout);
//
// Show that operation was successful
@@ -1081,11 +1188,12 @@ BreakpointListAllBreakpoint()
/**
* @brief List of modify breakpoints
* @param ListOrModifyBreakpoints
+ * @param SwitchToTargetMemoryLayout
*
* @return BOOLEAN
*/
BOOLEAN
-BreakpointListOrModify(PDEBUGGEE_BP_LIST_OR_MODIFY_PACKET ListOrModifyBreakpoints)
+BreakpointListOrModify(PDEBUGGEE_BP_LIST_OR_MODIFY_PACKET ListOrModifyBreakpoints, BOOLEAN SwitchToTargetMemoryLayout)
{
PDEBUGGEE_BP_DESCRIPTOR BreakpointDescriptor = NULL;
@@ -1118,7 +1226,7 @@ BreakpointListOrModify(PDEBUGGEE_BP_LIST_OR_MODIFY_PACKET ListOrModifyBreakpoint
//
// Set the breakpoint (without removing from list)
//
- BreakpointWrite(BreakpointDescriptor);
+ BreakpointWrite(BreakpointDescriptor, SwitchToTargetMemoryLayout);
}
else if (ListOrModifyBreakpoints->Request == DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_DISABLE)
{
diff --git a/hyperdbg/hprdbgkd/code/debugger/commands/Callstack.c b/hyperdbg/hyperkd/code/debugger/commands/Callstack.c
similarity index 86%
rename from hyperdbg/hprdbgkd/code/debugger/commands/Callstack.c
rename to hyperdbg/hyperkd/code/debugger/commands/Callstack.c
index e7d220dc..6587d5b5 100644
--- a/hyperdbg/hprdbgkd/code/debugger/commands/Callstack.c
+++ b/hyperdbg/hyperkd/code/debugger/commands/Callstack.c
@@ -15,6 +15,7 @@
* @brief Walkthrough the stack
*
* @param AddressToSaveFrames
+ * @param FrameCount
* @param StackBaseAddress
* @param Size
* @param Is32Bit
@@ -23,6 +24,7 @@
*/
BOOLEAN
CallstackWalkthroughStack(PDEBUGGER_SINGLE_CALLSTACK_FRAME AddressToSaveFrames,
+ UINT32 * FrameCount,
UINT64 StackBaseAddress,
UINT32 Size,
BOOLEAN Is32Bit)
@@ -57,12 +59,13 @@ 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
//
CurrentStackAddress = StackBaseAddress + (i * AddressMode);
+ *FrameCount = FrameIndex;
if (!CheckAccessValidityAndSafety(CurrentStackAddress, AddressMode))
{
@@ -71,7 +74,20 @@ CallstackWalkthroughStack(PDEBUGGER_SINGLE_CALLSTACK_FRAME AddressToSaveFrames,
//
// Stack is no longer valid or available to access from here
//
- return FALSE;
+ if (FrameIndex == 0)
+ {
+ //
+ // Stack is invalid
+ //
+ return FALSE;
+ }
+ else
+ {
+ //
+ // Stack is invalid, but there are frames that are still valid
+ //
+ return TRUE;
+ }
}
//
diff --git a/hyperdbg/hprdbgkd/code/debugger/commands/DebuggerCommands.c b/hyperdbg/hyperkd/code/debugger/commands/DebuggerCommands.c
similarity index 90%
rename from hyperdbg/hprdbgkd/code/debugger/commands/DebuggerCommands.c
rename to hyperdbg/hyperkd/code/debugger/commands/DebuggerCommands.c
index 9fea5784..940d0946 100644
--- a/hyperdbg/hprdbgkd/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
*
@@ -59,7 +108,7 @@ DebuggerCommandReadMemory(PDEBUGGER_READ_MEMORY ReadMemRequest, PVOID UserBuffer
//
// Check if the address is on a 32-bit mode process or not (just in case of disassembling)
//
- if (ReadMemRequest->MemoryType == DEBUGGER_READ_VIRTUAL_ADDRESS && ReadMemRequest->IsForDisasm)
+ if (ReadMemRequest->MemoryType == DEBUGGER_READ_VIRTUAL_ADDRESS && ReadMemRequest->GetAddressMode)
{
//
// Check if the address is in the canonical range for kernel space
@@ -69,7 +118,7 @@ DebuggerCommandReadMemory(PDEBUGGER_READ_MEMORY ReadMemRequest, PVOID UserBuffer
//
// The address is in the range of canonical kernel space, so it's 64-bit process
//
- ReadMemRequest->Is32BitAddress = FALSE;
+ ReadMemRequest->AddressMode = DEBUGGER_READ_ADDRESS_MODE_64_BIT;
}
else
{
@@ -80,7 +129,14 @@ DebuggerCommandReadMemory(PDEBUGGER_READ_MEMORY ReadMemRequest, PVOID UserBuffer
//
if (UserAccessIsWow64Process((HANDLE)ReadMemRequest->Pid, &Is32BitProcess))
{
- ReadMemRequest->Is32BitAddress = Is32BitProcess;
+ if (Is32BitProcess)
+ {
+ ReadMemRequest->AddressMode = DEBUGGER_READ_ADDRESS_MODE_32_BIT;
+ }
+ else
+ {
+ ReadMemRequest->AddressMode = DEBUGGER_READ_ADDRESS_MODE_64_BIT;
+ }
}
else
{
@@ -88,7 +144,7 @@ DebuggerCommandReadMemory(PDEBUGGER_READ_MEMORY ReadMemRequest, PVOID UserBuffer
// We couldn't determine the type of process, let's assume that it's a
// 64-bit process by default
//
- ReadMemRequest->Is32BitAddress = FALSE;
+ ReadMemRequest->AddressMode = DEBUGGER_READ_ADDRESS_MODE_64_BIT;
}
}
}
@@ -152,7 +208,7 @@ DebuggerCommandReadMemoryVmxRoot(PDEBUGGER_READ_MEMORY ReadMemRequest, UCHAR * U
//
if (!CheckAddressPhysical(Address))
{
- ReadMemRequest->KernelStatus = DEBUGGER_ERROR_INVALID_ADDRESS;
+ ReadMemRequest->KernelStatus = DEBUGGER_ERROR_INVALID_PHYSICAL_ADDRESS;
return FALSE;
}
@@ -219,7 +275,7 @@ DebuggerCommandReadMemoryVmxRoot(PDEBUGGER_READ_MEMORY ReadMemRequest, UCHAR * U
//
// Check if the address is on a 32-bit mode process or not (just in case of disassembling)
//
- if (ReadMemRequest->MemoryType == DEBUGGER_READ_VIRTUAL_ADDRESS && ReadMemRequest->IsForDisasm)
+ if (ReadMemRequest->MemoryType == DEBUGGER_READ_VIRTUAL_ADDRESS && ReadMemRequest->GetAddressMode)
{
//
// Check if the address is in the canonical range for kernel space
@@ -229,7 +285,7 @@ DebuggerCommandReadMemoryVmxRoot(PDEBUGGER_READ_MEMORY ReadMemRequest, UCHAR * U
//
// The address is in the range of canonical kernel space, so it's 64-bit process
//
- ReadMemRequest->Is32BitAddress = FALSE;
+ ReadMemRequest->AddressMode = DEBUGGER_READ_ADDRESS_MODE_64_BIT;
}
else
{
@@ -240,7 +296,14 @@ DebuggerCommandReadMemoryVmxRoot(PDEBUGGER_READ_MEMORY ReadMemRequest, UCHAR * U
//
if (UserAccessIsWow64ProcessByEprocess(PsGetCurrentProcess(), &Is32BitProcess))
{
- ReadMemRequest->Is32BitAddress = Is32BitProcess;
+ if (Is32BitProcess)
+ {
+ ReadMemRequest->AddressMode = DEBUGGER_READ_ADDRESS_MODE_32_BIT;
+ }
+ else
+ {
+ ReadMemRequest->AddressMode = DEBUGGER_READ_ADDRESS_MODE_64_BIT;
+ }
}
else
{
@@ -248,7 +311,7 @@ DebuggerCommandReadMemoryVmxRoot(PDEBUGGER_READ_MEMORY ReadMemRequest, UCHAR * U
// We couldn't determine the type of process, let's assume that it's a
// 64-bit process by default
//
- ReadMemRequest->Is32BitAddress = FALSE;
+ ReadMemRequest->AddressMode = DEBUGGER_READ_ADDRESS_MODE_64_BIT;
}
}
}
@@ -294,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;
@@ -348,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;
}
@@ -362,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;
}
@@ -479,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)));
@@ -488,21 +551,38 @@ DebuggerCommandEditMemory(PDEBUGGER_EDIT_MEMORY EditMemRequest)
// Instead of directly accessing the memory we use the MemoryMapperWriteMemorySafe
// It is because the target page might be read-only so we can make it writable
//
+
// RtlCopyBytes(DestinationAddress, SourceAddress, LengthOfEachChunk);
MemoryMapperWriteMemoryUnsafe((UINT64)DestinationAddress, SourceAddress, LengthOfEachChunk, EditMemRequest->ProcessId);
}
}
else if (EditMemRequest->MemoryType == EDIT_PHYSICAL_MEMORY)
{
+ //
+ // Check whether the physical address
+ //
+ if (!CheckAddressPhysical(EditMemRequest->Address))
+ {
+ EditMemRequest->Result = DEBUGGER_ERROR_INVALID_ADDRESS;
+ return STATUS_UNSUCCESSFUL;
+ }
+
//
// 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)));
- MemoryMapperWriteMemorySafeByPhysicalAddress((UINT64)DestinationAddress, (UINT64)SourceAddress, LengthOfEachChunk);
+ // MemoryMapperWriteMemorySafeByPhysicalAddress((UINT64)DestinationAddress, (UINT64)SourceAddress, LengthOfEachChunk);
+ // WritePhysicalMemoryUsingMapIoSpace((PVOID)SourceAddress, (PVOID)DestinationAddress, LengthOfEachChunk);
+
+ if (MemoryManagerWritePhysicalMemoryNormal((PVOID)DestinationAddress, (PVOID)SourceAddress, (SIZE_T)LengthOfEachChunk) == FALSE)
+ {
+ EditMemRequest->Result = DEBUGGER_ERROR_INVALID_ADDRESS;
+ return STATUS_UNSUCCESSFUL;
+ }
}
}
else
@@ -515,7 +595,7 @@ DebuggerCommandEditMemory(PDEBUGGER_EDIT_MEMORY EditMemRequest)
}
//
- // Set the resutls
+ // Set the results
//
EditMemRequest->Result = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
@@ -572,14 +652,14 @@ DebuggerCommandEditMemoryVmxRoot(PDEBUGGER_EDIT_MEMORY EditMemRequest)
if (!CheckAccessValidityAndSafety(EditMemRequest->Address,
EditMemRequest->ByteSize * EditMemRequest->CountOf64Chunks))
{
- EditMemRequest->KernelStatus = DEBUGGER_ERROR_INVALID_ADDRESS;
+ EditMemRequest->Result = DEBUGGER_ERROR_INVALID_ADDRESS;
return FALSE;
}
//
// 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)));
@@ -595,10 +675,19 @@ DebuggerCommandEditMemoryVmxRoot(PDEBUGGER_EDIT_MEMORY EditMemRequest)
}
else if (EditMemRequest->MemoryType == EDIT_PHYSICAL_MEMORY)
{
+ //
+ // Check whether the physical address
+ //
+ if (!CheckAddressPhysical(EditMemRequest->Address))
+ {
+ EditMemRequest->Result = DEBUGGER_ERROR_INVALID_ADDRESS;
+ return FALSE;
+ }
+
//
// 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)));
@@ -616,10 +705,9 @@ DebuggerCommandEditMemoryVmxRoot(PDEBUGGER_EDIT_MEMORY EditMemRequest)
}
//
- // Set the resutls
+ // Set the results
//
EditMemRequest->Result = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
-
return TRUE;
}
@@ -717,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 ***
@@ -756,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 ;)
@@ -1133,7 +1221,7 @@ DebuggerCommandSearchMemory(PDEBUGGER_SEARCH_MEMORY SearchMemRequest)
//
// We support up to MaximumSearchResults search results
//
- SearchResultsStorage = CrsAllocateZeroedNonPagedPool(MaximumSearchResults * sizeof(UINT64));
+ SearchResultsStorage = PlatformMemAllocateZeroedNonPagedPool(MaximumSearchResults * sizeof(UINT64));
if (SearchResultsStorage == NULL)
{
@@ -1164,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];
@@ -1189,7 +1277,7 @@ DebuggerCommandSearchMemory(PDEBUGGER_SEARCH_MEMORY SearchMemRequest)
//
// Free the results pool
//
- CrsFreePool(SearchResultsStorage);
+ PlatformMemFreePool(SearchResultsStorage);
return STATUS_SUCCESS;
}
@@ -1416,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/hprdbgkd/code/debugger/commands/ExtensionCommands.c b/hyperdbg/hyperkd/code/debugger/commands/ExtensionCommands.c
similarity index 62%
rename from hyperdbg/hprdbgkd/code/debugger/commands/ExtensionCommands.c
rename to hyperdbg/hyperkd/code/debugger/commands/ExtensionCommands.c
index 22e7b30b..4f16b619 100644
--- a/hyperdbg/hprdbgkd/code/debugger/commands/ExtensionCommands.c
+++ b/hyperdbg/hyperkd/code/debugger/commands/ExtensionCommands.c
@@ -12,6 +12,97 @@
*/
#include "pch.h"
+/**
+ * @brief Perform actions regarding APIC
+ *
+ * @param ApicRequest
+ *
+ * @return UINT32 Size to send to the debuggee
+ */
+UINT32
+ExtensionCommandPerformActionsForApicRequests(PDEBUGGER_APIC_REQUEST ApicRequest)
+{
+ BOOLEAN IsUsingX2APIC = FALSE;
+ PLAPIC_PAGE BufferToStoreLApic = (LAPIC_PAGE *)(((CHAR *)ApicRequest) + sizeof(DEBUGGER_APIC_REQUEST));
+ PIO_APIC_ENTRY_PACKETS BufferToStoreIoApic = (IO_APIC_ENTRY_PACKETS *)(((CHAR *)ApicRequest) + sizeof(DEBUGGER_APIC_REQUEST));
+
+ if (ApicRequest->ApicType == DEBUGGER_APIC_REQUEST_TYPE_READ_LOCAL_APIC)
+ {
+ if (VmFuncApicStoreLocalApicFields(BufferToStoreLApic, &IsUsingX2APIC))
+ {
+ //
+ // The status was okay
+ //
+ ApicRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ ApicRequest->IsUsingX2APIC = IsUsingX2APIC;
+
+ return sizeof(DEBUGGER_APIC_REQUEST) + sizeof(LAPIC_PAGE);
+ }
+ else
+ {
+ //
+ // There was an error performing the action
+ //
+ ApicRequest->KernelStatus = DEBUGGER_ERROR_APIC_ACTIONS_ERROR;
+
+ return sizeof(DEBUGGER_APIC_REQUEST);
+ }
+ }
+ else if (ApicRequest->ApicType == DEBUGGER_APIC_REQUEST_TYPE_READ_IO_APIC)
+ {
+ if (VmFuncApicStoreIoApicFields(BufferToStoreIoApic))
+ {
+ //
+ // The status was okay
+ //
+ ApicRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+
+ return sizeof(DEBUGGER_APIC_REQUEST) + sizeof(IO_APIC_ENTRY_PACKETS);
+ }
+ else
+ {
+ //
+ // There was an error performing the action
+ //
+ ApicRequest->KernelStatus = DEBUGGER_ERROR_APIC_ACTIONS_ERROR;
+
+ return sizeof(DEBUGGER_APIC_REQUEST);
+ }
+ }
+ else
+ {
+ //
+ // Invalid request
+ //
+ ApicRequest->KernelStatus = DEBUGGER_ERROR_APIC_ACTIONS_ERROR;
+
+ return sizeof(DEBUGGER_APIC_REQUEST);
+ }
+}
+
+/**
+ * @brief Perform query for IDT entries
+ *
+ * @param IdtQueryRequest
+ * @param ReadFromVmxRoot
+ *
+ * @return VOID
+ */
+VOID
+ExtensionCommandPerformQueryIdtEntriesRequest(PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS IdtQueryRequest,
+ BOOLEAN ReadFromVmxRoot)
+{
+ //
+ // Perform the query
+ //
+ VmFuncIdtQueryEntries(IdtQueryRequest, ReadFromVmxRoot);
+
+ //
+ // Operation was successful
+ //
+ IdtQueryRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+}
+
/**
* @brief routines for !va2pa and !pa2va commands
*
@@ -593,3 +684,151 @@ ExtensionCommandIoBitmapResetAllCores()
//
BroadcastIoBitmapResetAllCores();
}
+
+/**
+ * @brief routines for PCIe tree
+ *
+ * @param PcitreePacket
+ * @param OperateOnVmxRoot
+ *
+ * @return VOID
+ */
+VOID
+ExtensionCommandPcitree(PDEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET PcitreePacket, BOOLEAN OperateOnVmxRoot)
+{
+ DWORD DeviceIdVendorId = 0xFFFFFFFF;
+ DWORD ClassCode = 0xFFFFFFFF;
+ UINT8 DevNum = 0;
+
+ //
+ // We currently don't use OperateOnVmxRoot, but we might in the future
+ //
+ UNREFERENCED_PARAMETER(OperateOnVmxRoot);
+
+ for (UINT8 b = 0; b < BUS_MAX_NUM; b++)
+ {
+ for (UINT8 d = 0; d < DEVICE_MAX_NUM; d++)
+ {
+ for (UINT8 f = 0; f < FUNCTION_MAX_NUM; f++)
+ {
+ DeviceIdVendorId = (DWORD)PciReadCam(b, d, f, 0, sizeof(DWORD));
+
+ if (DeviceIdVendorId != 0xFFFFFFFF)
+ {
+ PcitreePacket->DeviceInfoList[DevNum].Bus = b;
+ PcitreePacket->DeviceInfoList[DevNum].Device = d;
+ PcitreePacket->DeviceInfoList[DevNum].Function = f;
+ PcitreePacket->DeviceInfoList[DevNum].ConfigSpace.VendorId = (UINT16)(DeviceIdVendorId & 0xFFFF);
+ PcitreePacket->DeviceInfoList[DevNum].ConfigSpace.DeviceId = (UINT16)(DeviceIdVendorId >> 16);
+
+ ClassCode = (DWORD)PciReadCam(b, d, f, 0, sizeof(DWORD));
+ PcitreePacket->DeviceInfoList[DevNum].ConfigSpace.ClassCode[0] = (UINT8)((ClassCode >> 24) & 0xFF);
+ PcitreePacket->DeviceInfoList[DevNum].ConfigSpace.ClassCode[1] = (UINT8)((ClassCode >> 16) & 0xFF);
+ PcitreePacket->DeviceInfoList[DevNum].ConfigSpace.ClassCode[2] = (UINT8)((ClassCode >> 8) & 0xFF);
+
+ DevNum++;
+ if (DevNum == DEV_MAX_NUM)
+ {
+ LogError("Reached maximum number of devices (%u) that can be stored in debuggee response packet.\n", DEV_MAX_NUM);
+ break;
+ }
+ }
+ }
+ }
+ }
+ PcitreePacket->DeviceInfoListNum = DevNum;
+
+ if (PcitreePacket->DeviceInfoListNum)
+ {
+ PcitreePacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ }
+ else
+ {
+ PcitreePacket->KernelStatus = DEBUGGER_ERROR_INVALID_ADDRESS;
+ }
+}
+
+/**
+ * @brief Request PCI device info.
+ *
+ * @param PcidevinfoPacket
+ * @param OperateOnVmxRoot
+ *
+ * @return VOID
+ */
+VOID
+ExtensionCommandPcidevinfo(PDEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET PcidevinfoPacket, BOOLEAN OperateOnVmxRoot)
+{
+ DWORD DeviceIdVendorId = 0xFFFFFFFF;
+
+ //
+ // We currently don't use OperateOnVmxRoot, but we might in the future
+ //
+ UNREFERENCED_PARAMETER(OperateOnVmxRoot);
+
+ DeviceIdVendorId = (DWORD)PciReadCam(PcidevinfoPacket->DeviceInfo.Bus, PcidevinfoPacket->DeviceInfo.Device, PcidevinfoPacket->DeviceInfo.Function, 0, 4);
+ if (DeviceIdVendorId != 0xFFFFFFFF)
+ {
+ DWORD * cs = (DWORD *)&PcidevinfoPacket->DeviceInfo.ConfigSpace; // Overflows into .ConfigSpaceAdditional - no padding due to pack(0)
+ for (UINT16 i = 0; i < CAM_CONFIG_SPACE_LENGTH; i += 4)
+ {
+ *cs = (DWORD)PciReadCam(PcidevinfoPacket->DeviceInfo.Bus, PcidevinfoPacket->DeviceInfo.Device, PcidevinfoPacket->DeviceInfo.Function, (BYTE)i, 4);
+ cs++;
+ }
+
+ //
+ // For endpoints, determine MMIO BAR addressable range and size (if any).
+ // Do not determine BAR size if user has requested raw dump.
+ //
+ if ((PcidevinfoPacket->DeviceInfo.ConfigSpace.CommonHeader.HeaderType & 0x01) << 7 == 0 // Endpoint
+ && !PcidevinfoPacket->PrintRaw)
+ {
+ for (UINT8 i = 0; i < 5; i++)
+ {
+ if ((PcidevinfoPacket->DeviceInfo.ConfigSpace.DeviceHeader.ConfigSpaceEp.Bar[i] & 0x1) == 0) // Memory I/O
+ {
+ if (((PcidevinfoPacket->DeviceInfo.ConfigSpace.DeviceHeader.ConfigSpaceEp.Bar[i] & 0x6) >> 1) == 2) // 64-bit BAR
+ {
+ UINT64 BarMsb = PcidevinfoPacket->DeviceInfo.ConfigSpace.DeviceHeader.ConfigSpaceEp.Bar[i + 1];
+ UINT64 BarLsb = PcidevinfoPacket->DeviceInfo.ConfigSpace.DeviceHeader.ConfigSpaceEp.Bar[i];
+ UINT64 Bar64 = ((BarMsb & 0xFFFFFFFF) << 32) + (BarLsb & 0xFFFFFFF0);
+
+ PcidevinfoPacket->DeviceInfo.MmioBarInfo[i].Is64Bit = TRUE;
+ if (Bar64 == 0)
+ {
+ PcidevinfoPacket->DeviceInfo.MmioBarInfo[i].IsEnabled = FALSE;
+ continue;
+ }
+
+ PcidevinfoPacket->DeviceInfo.MmioBarInfo[i].Is64Bit = TRUE;
+ PcidevinfoPacket->DeviceInfo.MmioBarInfo[i].IsEnabled = TRUE;
+
+ i++;
+ }
+ else // 32-bit BAR
+ {
+ UINT32 Bar32 = (PcidevinfoPacket->DeviceInfo.ConfigSpace.DeviceHeader.ConfigSpaceEp.Bar[i] & 0xFFFFFFF0);
+
+ PcidevinfoPacket->DeviceInfo.MmioBarInfo[i].Is64Bit = FALSE;
+ if (Bar32 == 0)
+ {
+ PcidevinfoPacket->DeviceInfo.MmioBarInfo[i].IsEnabled = FALSE;
+ continue;
+ }
+
+ PcidevinfoPacket->DeviceInfo.MmioBarInfo[i].Is64Bit = FALSE;
+ PcidevinfoPacket->DeviceInfo.MmioBarInfo[i].IsEnabled = TRUE;
+ }
+ }
+ }
+ }
+
+ PcidevinfoPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ }
+ else
+ {
+ PcidevinfoPacket->DeviceInfo.ConfigSpace.CommonHeader.DeviceId = 0xFFFF;
+ PcidevinfoPacket->DeviceInfo.ConfigSpace.CommonHeader.VendorId = 0xFFFF;
+ PcidevinfoPacket->KernelStatus = DEBUGGER_ERROR_INVALID_ADDRESS;
+ }
+}
diff --git a/hyperdbg/hprdbgkd/code/debugger/communication/SerialConnection.c b/hyperdbg/hyperkd/code/debugger/communication/SerialConnection.c
similarity index 94%
rename from hyperdbg/hprdbgkd/code/debugger/communication/SerialConnection.c
rename to hyperdbg/hyperkd/code/debugger/communication/SerialConnection.c
index e1791071..f7c55d7a 100644
--- a/hyperdbg/hprdbgkd/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);
}
@@ -160,13 +160,13 @@ SerialConnectionSend(CHAR * Buffer, UINT32 Length)
if (Length + SERIAL_END_OF_BUFFER_CHARS_COUNT > MaxSerialPacketSize)
{
LogError("Err, buffer is above the maximum buffer size that can be sent to debuggee (%d > %d), "
- "for more information, please visit https://docs.hyperdbg.org/tips-and-tricks/misc/increase-communication-buffer-size",
+ "for more information, please visit https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/increase-communication-buffer-size",
Length + SERIAL_END_OF_BUFFER_CHARS_COUNT,
MaxSerialPacketSize);
return FALSE;
}
- for (size_t i = 0; i < Length; i++)
+ for (SIZE_T i = 0; i < Length; i++)
{
KdHyperDbgSendByte(Buffer[i], TRUE);
}
@@ -197,7 +197,7 @@ SerialConnectionSendTwoBuffers(CHAR * Buffer1, UINT32 Length1, CHAR * Buffer2, U
if ((Length1 + Length2 + SERIAL_END_OF_BUFFER_CHARS_COUNT) > MaxSerialPacketSize)
{
LogError("Err, buffer is above the maximum buffer size that can be sent to debuggee (%d > %d), "
- "for more information, please visit https://docs.hyperdbg.org/tips-and-tricks/misc/increase-communication-buffer-size",
+ "for more information, please visit https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/increase-communication-buffer-size",
Length1 + Length2 + SERIAL_END_OF_BUFFER_CHARS_COUNT,
MaxSerialPacketSize);
return FALSE;
@@ -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);
}
@@ -252,7 +252,7 @@ SerialConnectionSendThreeBuffers(CHAR * Buffer1,
if ((Length1 + Length2 + Length3 + SERIAL_END_OF_BUFFER_CHARS_COUNT) > MaxSerialPacketSize)
{
LogError("Err, buffer is above the maximum buffer size that can be sent to debuggee (%d > %d), "
- "for more information, please visit https://docs.hyperdbg.org/tips-and-tricks/misc/increase-communication-buffer-size",
+ "for more information, please visit https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/increase-communication-buffer-size",
Length1 + Length2 + Length3 + SERIAL_END_OF_BUFFER_CHARS_COUNT,
MaxSerialPacketSize);
return FALSE;
@@ -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/hprdbgkd/code/debugger/core/Debugger.c b/hyperdbg/hyperkd/code/debugger/core/Debugger.c
similarity index 92%
rename from hyperdbg/hprdbgkd/code/debugger/core/Debugger.c
rename to hyperdbg/hyperkd/code/debugger/core/Debugger.c
index fb714589..4b7b65ad 100644
--- a/hyperdbg/hprdbgkd/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,87 +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 = CrsAllocateNonPagedPool(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->ScriptEngineCoreSpecificLocalVariable)
- {
- CurrentDebuggerState->ScriptEngineCoreSpecificLocalVariable = CrsAllocateNonPagedPool(MAX_VAR_COUNT * sizeof(UINT64));
- }
-
- if (!CurrentDebuggerState->ScriptEngineCoreSpecificLocalVariable)
- {
- //
- // Out of resource, initialization of script engine's local variable holders failed
- //
- return FALSE;
- }
-
- if (!CurrentDebuggerState->ScriptEngineCoreSpecificTempVariable)
- {
- CurrentDebuggerState->ScriptEngineCoreSpecificTempVariable = CrsAllocateNonPagedPool(MAX_TEMP_COUNT * sizeof(UINT64));
- }
-
- if (!CurrentDebuggerState->ScriptEngineCoreSpecificTempVariable)
- {
- //
- // Out of resource, initialization of script engine's local variable holders failed
- //
- return FALSE;
- }
-
- //
- // Zero the local and temp variables memory
- //
- RtlZeroMemory(CurrentDebuggerState->ScriptEngineCoreSpecificLocalVariable, MAX_VAR_COUNT * sizeof(UINT64));
- RtlZeroMemory(CurrentDebuggerState->ScriptEngineCoreSpecificTempVariable, MAX_TEMP_COUNT * sizeof(UINT64));
- }
//
// Initialize NMI broadcasting mechanism
@@ -199,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);
@@ -222,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 ***
//
@@ -253,7 +314,7 @@ DebuggerUninitialize()
//
// Disable triggering events
//
- g_EnableDebuggerEvents = FALSE;
+ g_EnableDebuggerVmxEvents = FALSE;
//
// Clear all events (Check if the kernel debugger is enable
@@ -282,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
@@ -293,7 +373,7 @@ DebuggerUninitialize()
//
if (g_ScriptGlobalVariables != NULL)
{
- CrsFreePool(g_ScriptGlobalVariables);
+ PlatformMemFreePool(g_ScriptGlobalVariables);
g_ScriptGlobalVariables = NULL;
}
@@ -304,16 +384,10 @@ DebuggerUninitialize()
{
CurrentDebuggerState = &g_DbgState[i];
- if (CurrentDebuggerState->ScriptEngineCoreSpecificLocalVariable != NULL)
+ if (CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer != NULL)
{
- CrsFreePool(CurrentDebuggerState->ScriptEngineCoreSpecificLocalVariable);
- CurrentDebuggerState->ScriptEngineCoreSpecificLocalVariable = NULL;
- }
-
- if (CurrentDebuggerState->ScriptEngineCoreSpecificTempVariable != NULL)
- {
- CrsFreePool(CurrentDebuggerState->ScriptEngineCoreSpecificTempVariable);
- CurrentDebuggerState->ScriptEngineCoreSpecificTempVariable = NULL;
+ PlatformMemFreePool(CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer);
+ CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer = NULL;
}
}
@@ -440,7 +514,7 @@ DebuggerCreateEvent(BOOLEAN Enabled,
//
// If it's not coming from the VMX-root mode then we're allocating it from the OS buffers
//
- Event = CrsAllocateZeroedNonPagedPool(EventBufferSize);
+ Event = PlatformMemAllocateZeroedNonPagedPool(EventBufferSize);
if (!Event)
{
@@ -600,7 +674,7 @@ DebuggerAllocateSafeRequestedBuffer(SIZE_T SizeOfRequ
}
else
{
- RequestedBuffer = CrsAllocateZeroedNonPagedPool(SizeOfRequestedSafeBuffer);
+ RequestedBuffer = PlatformMemAllocateZeroedNonPagedPool(SizeOfRequestedSafeBuffer);
if (!RequestedBuffer)
{
@@ -751,7 +825,7 @@ DebuggerAddActionToEvent(PDEBUGGER_EVENT Event,
//
// If it's not coming from the VMX-root mode then we're allocating it from the OS buffers
//
- Action = CrsAllocateZeroedNonPagedPool(ActionBufferSize);
+ Action = PlatformMemAllocateZeroedNonPagedPool(ActionBufferSize);
if (Action == NULL)
{
@@ -791,7 +865,7 @@ DebuggerAddActionToEvent(PDEBUGGER_EVENT Event,
}
else
{
- CrsFreePool(Action);
+ PlatformMemFreePool(Action);
}
//
@@ -819,7 +893,7 @@ DebuggerAddActionToEvent(PDEBUGGER_EVENT Event,
}
else
{
- CrsFreePool(Action);
+ PlatformMemFreePool(Action);
}
//
@@ -859,7 +933,7 @@ DebuggerAddActionToEvent(PDEBUGGER_EVENT Event,
}
else
{
- CrsFreePool(Action);
+ PlatformMemFreePool(Action);
}
//
@@ -887,7 +961,7 @@ DebuggerAddActionToEvent(PDEBUGGER_EVENT Event,
}
else
{
- CrsFreePool(Action);
+ PlatformMemFreePool(Action);
}
//
@@ -925,11 +999,11 @@ DebuggerAddActionToEvent(PDEBUGGER_EVENT Event,
}
else
{
- CrsFreePool(Action);
+ PlatformMemFreePool(Action);
if (RequestedBuffer != NULL)
{
- CrsFreePool(RequestedBuffer);
+ PlatformMemFreePool(RequestedBuffer);
}
}
@@ -975,11 +1049,11 @@ DebuggerAddActionToEvent(PDEBUGGER_EVENT Event,
}
else
{
- CrsFreePool(Action);
+ PlatformMemFreePool(Action);
if (RequestedBuffer != 0)
{
- CrsFreePool(RequestedBuffer);
+ PlatformMemFreePool(RequestedBuffer);
}
}
@@ -997,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
@@ -1077,17 +1151,18 @@ DebuggerTriggerEvents(VMM_EVENT_TYPE_ENUM EventType,
BOOLEAN * PostEventRequired,
GUEST_REGS * Regs)
{
+ PROCESSOR_DEBUGGING_STATE * DbgState = NULL;
DebuggerCheckForCondition * ConditionFunc;
DEBUGGER_TRIGGERED_EVENT_DETAILS EventTriggerDetail = {0};
PEPT_HOOKS_CONTEXT EptContext;
- PLIST_ENTRY TempList = 0;
- PLIST_ENTRY TempList2 = 0;
- PROCESSOR_DEBUGGING_STATE * DbgState = NULL;
+ PLIST_ENTRY TempList = 0;
+ PLIST_ENTRY TempList2 = 0;
+ const PVOID OriginalContext = Context;
//
// Check if triggering debugging actions are allowed or not
//
- if (!g_EnableDebuggerEvents || g_InterceptBreakpointsAndEventsForCommandsInRemoteComputer)
+ if (!g_EnableDebuggerVmxEvents || g_InterceptBreakpointsAndEventsForCommandsInRemoteComputer)
{
//
// Debugger is not enabled
@@ -1152,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)
{
@@ -1188,14 +1264,17 @@ DebuggerTriggerEvents(VMM_EVENT_TYPE_ENUM EventType,
// we get the events for all hidden hooks in a page granularity
//
- EptContext = (PEPT_HOOKS_CONTEXT)Context;
+ //
+ // Here the OriginalContext is used because the context
+ // might be changed but the OriginalContext is constant
+ //
+ EptContext = (PEPT_HOOKS_CONTEXT)OriginalContext;
//
- // Context should be checked with hooking tag
+ // EPT context should be checked with hooking tag
// The hooking tag is same as the event tag if both
// of them match together
//
-
if (EptContext->HookingTag != CurrentEvent->Tag)
{
//
@@ -1237,6 +1316,12 @@ DebuggerTriggerEvents(VMM_EVENT_TYPE_ENUM EventType,
case HIDDEN_HOOK_EXEC_DETOURS:
+ //
+ // Here the OriginalContext is used because the context
+ // might be changed but the OriginalContext is constant
+ //
+ EptContext = (PEPT_HOOKS_CONTEXT)OriginalContext;
+
//
// Here we check if it's HIDDEN_HOOK_EXEC_DETOURS
// then it means that it's detours hidden hook exec so we have
@@ -1248,7 +1333,7 @@ DebuggerTriggerEvents(VMM_EVENT_TYPE_ENUM EventType,
// This way we are sure that no one can bypass our hook by remapping
// address to another virtual address as everything is physical
//
- if (((PEPT_HOOKS_CONTEXT)Context)->PhysicalAddress != CurrentEvent->Options.OptionalParam1)
+ if (EptContext->PhysicalAddress != CurrentEvent->Options.OptionalParam1)
{
//
// Context is the physical address
@@ -1264,7 +1349,7 @@ DebuggerTriggerEvents(VMM_EVENT_TYPE_ENUM EventType,
//
// Convert it to virtual address
//
- Context = (PVOID)(((PEPT_HOOKS_CONTEXT)Context)->VirtualAddress);
+ Context = (PVOID)(EptContext->VirtualAddress);
}
break;
@@ -1386,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;
}
@@ -1564,10 +1664,10 @@ DebuggerPerformRunScript(PROCESSOR_DEBUGGING_STATE * DbgState,
DEBUGGEE_SCRIPT_PACKET * ScriptDetails,
DEBUGGER_TRIGGERED_EVENT_DETAILS * EventTriggerDetail)
{
- SYMBOL_BUFFER CodeBuffer = {0};
- ACTION_BUFFER ActionBuffer = {0};
- SYMBOL ErrorSymbol = {0};
- SCRIPT_ENGINE_VARIABLES_LIST VariablesList = {0};
+ SYMBOL_BUFFER CodeBuffer = {0};
+ ACTION_BUFFER ActionBuffer = {0};
+ SYMBOL ErrorSymbol = {0};
+ SCRIPT_ENGINE_GENERAL_REGISTERS ScriptGeneralRegisters = {0};
if (Action != NULL)
{
@@ -1636,11 +1736,13 @@ DebuggerPerformRunScript(PROCESSOR_DEBUGGING_STATE * DbgState,
}
//
- // Fill the variables list for this run
+ // Fill the stack buffer for this run
//
- VariablesList.GlobalVariablesList = g_ScriptGlobalVariables;
- VariablesList.LocalVariablesList = DbgState->ScriptEngineCoreSpecificLocalVariable;
- VariablesList.TempList = DbgState->ScriptEngineCoreSpecificTempVariable;
+ ScriptGeneralRegisters.StackBuffer = DbgState->ScriptEngineCoreSpecificStackBuffer;
+ ScriptGeneralRegisters.GlobalVariablesList = g_ScriptGlobalVariables;
+ RtlZeroMemory(ScriptGeneralRegisters.StackBuffer, MAX_STACK_BUFFER_COUNT * sizeof(UINT64));
+
+ UINT64 EXECUTENUMBER = 0;
for (UINT64 i = 0; i < CodeBuffer.Pointer;)
{
@@ -1650,20 +1752,27 @@ DebuggerPerformRunScript(PROCESSOR_DEBUGGING_STATE * DbgState,
if (ScriptEngineExecute(DbgState->Regs,
&ActionBuffer,
- &VariablesList,
+ &ScriptGeneralRegisters,
&CodeBuffer,
&i,
- NULL,
- NULL,
- NULL,
- NULL,
&ErrorSymbol) == TRUE)
{
- CHAR NameOfOperator[MAX_FUNCTION_NAME_LENGTH] = {0};
- ScriptEngineGetOperatorName(&ErrorSymbol, NameOfOperator);
- LogInfo("Invalid returning address for operator: %s", NameOfOperator);
+ LogInfo("Err, ScriptEngineExecute, function = % s\n ",
+ FunctionNames[ErrorSymbol.Value]);
break;
}
+ else if (ScriptGeneralRegisters.StackIndx >= MAX_STACK_BUFFER_COUNT)
+ {
+ LogInfo("Err, stack buffer overflow (more information: https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/change-script-engine-limitations)\n");
+ break;
+ }
+ else if (EXECUTENUMBER >= MAX_EXECUTION_COUNT)
+ {
+ LogInfo("Err, exceeding the max execution count (more information: https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/change-script-engine-limitations)\n");
+ break;
+ }
+
+ EXECUTENUMBER++;
}
return TRUE;
@@ -1735,7 +1844,6 @@ DebuggerPerformRunTheCustomCode(PROCESSOR_DEBUGGING_STATE * DbgState,
* @param DbgState The state of the debugger on the current core
* @param Tag Tag of event
* @param Action Action object
- * @param Context Optional parameter
* @param EventTriggerDetail Event trigger detail
*
* @return VOID
@@ -1786,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;
@@ -1830,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;
@@ -1887,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;
@@ -1939,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;
@@ -2091,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:
//
@@ -2450,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;
@@ -2502,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);
//
@@ -2525,7 +2636,7 @@ DebuggerRemoveAllActionsFromEvent(PDEBUGGER_EVENT Event, BOOLEAN PoolManagerAllo
}
else
{
- CrsFreePool((PVOID)CurrentAction->RequestedBuffer.RequstBufferAddress);
+ PlatformMemFreePool((PVOID)CurrentAction->RequestedBuffer.RequstBufferAddress);
}
}
@@ -2534,14 +2645,18 @@ 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);
}
else
{
- CrsFreePool(CurrentAction);
+ PlatformMemFreePool(CurrentAction);
}
+
+ TempList = NextList;
}
//
// Remember to free the pool
@@ -2612,7 +2727,7 @@ DebuggerRemoveEvent(UINT64 Tag, BOOLEAN PoolManagerAllocatedMemory)
}
else
{
- CrsFreePool(Event);
+ PlatformMemFreePool(Event);
}
return TRUE;
@@ -2994,6 +3109,15 @@ DebuggerApplyEvent(PDEBUGGER_EVENT Event,
break;
}
+ case XSETBV_INSTRUCTION_EXECUTION:
+ {
+ //
+ // Apply the XSETBV instruction execution events
+ //
+ ApplyEventXsetbvExecutionEvent(Event, ResultsToReturn, InputFromVmxRoot);
+
+ break;
+ }
default:
{
//
@@ -3565,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/hprdbgkd/code/debugger/core/DebuggerVmcalls.c b/hyperdbg/hyperkd/code/debugger/core/DebuggerVmcalls.c
similarity index 100%
rename from hyperdbg/hprdbgkd/code/debugger/core/DebuggerVmcalls.c
rename to hyperdbg/hyperkd/code/debugger/core/DebuggerVmcalls.c
diff --git a/hyperdbg/hprdbgkd/code/debugger/core/HaltedCore.c b/hyperdbg/hyperkd/code/debugger/core/HaltedCore.c
similarity index 99%
rename from hyperdbg/hprdbgkd/code/debugger/core/HaltedCore.c
rename to hyperdbg/hyperkd/code/debugger/core/HaltedCore.c
index 2b0696d7..8cae1122 100644
--- a/hyperdbg/hprdbgkd/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/hprdbgkd/code/debugger/events/ApplyEvents.c b/hyperdbg/hyperkd/code/debugger/events/ApplyEvents.c
similarity index 87%
rename from hyperdbg/hprdbgkd/code/debugger/events/ApplyEvents.c
rename to hyperdbg/hyperkd/code/debugger/events/ApplyEvents.c
index 8e6f0d5d..1fea130a 100644
--- a/hyperdbg/hprdbgkd/code/debugger/events/ApplyEvents.c
+++ b/hyperdbg/hyperkd/code/debugger/events/ApplyEvents.c
@@ -35,12 +35,6 @@ ApplyEventMonitorEvent(PDEBUGGER_EVENT Event,
UINT64 TempStartAddress;
UINT64 TempEndAddress;
UINT64 TempNextPageAddr;
- UINT64 RemainingSizeRestore;
- UINT64 PagesBytesRestore;
- UINT64 ConstEndAddressRestore;
- UINT64 TempNextPageAddrRestore;
- UINT64 TempStartAddressRestore;
- UINT64 TempEndAddressRestore;
EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR HookingAddresses = {0};
if (InputFromVmxRoot)
@@ -140,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)
{
@@ -181,6 +175,15 @@ ApplyEventMonitorEvent(PDEBUGGER_EVENT Event,
HookingAddresses.StartAddress = TempStartAddress;
HookingAddresses.EndAddress = TempEndAddress;
+ if ((DEBUGGER_HOOK_MEMORY_TYPE)Event->InitOptions.OptionalParam3 == DEBUGGER_MEMORY_HOOK_PHYSICAL_ADDRESS)
+ {
+ HookingAddresses.MemoryType = DEBUGGER_MEMORY_HOOK_PHYSICAL_ADDRESS;
+ }
+ else
+ {
+ HookingAddresses.MemoryType = DEBUGGER_MEMORY_HOOK_VIRTUAL_ADDRESS;
+ }
+
//
// Apply the hook
//
@@ -198,85 +201,24 @@ ApplyEventMonitorEvent(PDEBUGGER_EVENT Event,
//
// Now we should restore the previously applied events (if any)
//
-
- TempStartAddressRestore = Event->InitOptions.OptionalParam1;
- TempEndAddressRestore = Event->InitOptions.OptionalParam2;
- ConstEndAddressRestore = TempEndAddressRestore;
-
- PagesBytesRestore = (UINT64)PAGE_ALIGN(TempStartAddressRestore);
- PagesBytesRestore = TempEndAddressRestore - PagesBytesRestore;
- PagesBytesRestore = PagesBytesRestore / PAGE_SIZE;
-
- RemainingSizeRestore = TempEndAddressRestore - TempStartAddressRestore;
-
- // LogInfo("Discard changes from, Start address: %llx, end address: %llx\n\n\n",
- // TempStartAddressRestore,
- // TempEndAddressRestore,
- // RemainingSizeRestore);
-
- for (size_t j = 0; j <= PagesBytesRestore; j++)
+ if (InputFromVmxRoot)
{
//
- // Check if the previous hook is applied
+ // EPT hooking tag is same as event tag, so we can use it to unhook
//
- if (j == i)
- {
- //
- // It means this index is not applied successfully,
- // so we're not needed to remove as it's not successfully applied
- //
- break;
- }
-
- if (RemainingSizeRestore >= PAGE_SIZE)
- {
- TempEndAddressRestore = (TempStartAddressRestore + ((UINT64)PAGE_ALIGN(TempStartAddressRestore + PAGE_SIZE) - TempStartAddressRestore)) - 1;
- RemainingSizeRestore = ConstEndAddressRestore - TempEndAddressRestore - 1;
- }
- else
- {
- TempNextPageAddrRestore = (UINT64)PAGE_ALIGN(TempStartAddressRestore + RemainingSizeRestore);
-
- //
- // Check if by adding the remaining size, we'll go to the next
- // page boundary or not
- //
- if (TempNextPageAddrRestore > ((UINT64)PAGE_ALIGN(TempStartAddressRestore)))
- {
- //
- // It goes to the next page boundary
- //
- TempEndAddressRestore = TempNextPageAddrRestore - 1;
- RemainingSizeRestore = RemainingSizeRestore - (TempEndAddressRestore - TempStartAddressRestore) - 1;
- }
- else
- {
- TempEndAddressRestore = TempStartAddressRestore + RemainingSizeRestore;
- RemainingSizeRestore = 0;
- }
- }
-
+ TerminateEptHookUnHookAllHooksByHookingTagFromVmxRootAndApplyInvalidation(Event->Tag);
+ }
+ else
+ {
//
- // Remove the hook
+ // EPT hooking tag is same as event tag, so we can use it to unhook
//
- if (InputFromVmxRoot)
- {
- TerminateEptHookUnHookSingleAddressFromVmxRootAndApplyInvalidation(TempStartAddressRestore,
- (UINT64)NULL);
- }
- else
- {
- ConfigureEptHookUnHookSingleAddress(TempStartAddressRestore,
- (UINT64)NULL,
- Event->ProcessId);
- }
-
- //
- // Swap the temporary start address and temporary end address
- //
- TempStartAddressRestore = TempEndAddressRestore + 1;
+ ConfigureEptHookUnHookAllByHookingTag(Event->Tag);
}
+ //
+ // Break from the loop
+ //
break;
}
else
@@ -311,19 +253,33 @@ ApplyEventMonitorEvent(PDEBUGGER_EVENT Event,
}
//
- // We convert the Event's optional parameters physical address because
- // vm-exit occurs and we have the physical address to compare in the case of
- // hidden hook rw events.
+ // Check if address is virtual or physical
//
- if (InputFromVmxRoot)
+ if ((DEBUGGER_HOOK_MEMORY_TYPE)Event->Options.OptionalParam3 == DEBUGGER_MEMORY_HOOK_PHYSICAL_ADDRESS)
{
- Event->Options.OptionalParam1 = VirtualAddressToPhysicalAddressOnTargetProcess((PVOID)Event->InitOptions.OptionalParam1);
- Event->Options.OptionalParam2 = VirtualAddressToPhysicalAddressOnTargetProcess((PVOID)Event->InitOptions.OptionalParam2);
+ //
+ // It's a physical address so we just save the addresses without conversion
+ //
+ Event->Options.OptionalParam1 = Event->InitOptions.OptionalParam1;
+ Event->Options.OptionalParam2 = Event->InitOptions.OptionalParam2;
}
else
{
- Event->Options.OptionalParam1 = VirtualAddressToPhysicalAddressByProcessId((PVOID)Event->InitOptions.OptionalParam1, TempProcessId);
- Event->Options.OptionalParam2 = VirtualAddressToPhysicalAddressByProcessId((PVOID)Event->InitOptions.OptionalParam2, TempProcessId);
+ //
+ // It's a virtual address, we convert the Event's optional parameters physical address
+ // because vm-exit occurs and we have the physical address to compare in the case of
+ // hidden hook rw events
+ //
+ if (InputFromVmxRoot)
+ {
+ Event->Options.OptionalParam1 = VirtualAddressToPhysicalAddressOnTargetProcess((PVOID)Event->InitOptions.OptionalParam1);
+ Event->Options.OptionalParam2 = VirtualAddressToPhysicalAddressOnTargetProcess((PVOID)Event->InitOptions.OptionalParam2);
+ }
+ else
+ {
+ Event->Options.OptionalParam1 = VirtualAddressToPhysicalAddressByProcessId((PVOID)Event->InitOptions.OptionalParam1, TempProcessId);
+ Event->Options.OptionalParam2 = VirtualAddressToPhysicalAddressByProcessId((PVOID)Event->InitOptions.OptionalParam2, TempProcessId);
+ }
}
//
@@ -331,6 +287,7 @@ ApplyEventMonitorEvent(PDEBUGGER_EVENT Event,
//
Event->Options.OptionalParam3 = Event->InitOptions.OptionalParam1;
Event->Options.OptionalParam4 = Event->InitOptions.OptionalParam2;
+ Event->Options.OptionalParam5 = Event->InitOptions.OptionalParam3; // This parameter shows whether the address is physical or virtual
//
// Check if we should restore the event if it was not successful
@@ -1248,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())
{
//
@@ -1326,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;
}
/**
@@ -1356,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/hprdbgkd/code/debugger/events/DebuggerEvents.c b/hyperdbg/hyperkd/code/debugger/events/DebuggerEvents.c
similarity index 100%
rename from hyperdbg/hprdbgkd/code/debugger/events/DebuggerEvents.c
rename to hyperdbg/hyperkd/code/debugger/events/DebuggerEvents.c
diff --git a/hyperdbg/hprdbgkd/code/debugger/events/Termination.c b/hyperdbg/hyperkd/code/debugger/events/Termination.c
similarity index 90%
rename from hyperdbg/hprdbgkd/code/debugger/events/Termination.c
rename to hyperdbg/hyperkd/code/debugger/events/Termination.c
index 979f3e39..b6f59de4 100644
--- a/hyperdbg/hprdbgkd/code/debugger/events/Termination.c
+++ b/hyperdbg/hyperkd/code/debugger/events/Termination.c
@@ -107,81 +107,19 @@ TerminateExternalInterruptEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
VOID
TerminateHiddenHookReadAndWriteAndExecuteEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
{
- UINT64 RemainingSize;
- UINT64 PagesBytes;
- UINT64 ConstEndAddress;
- UINT64 TempNextPageAddr;
- UINT64 TempStartAddress = Event->Options.OptionalParam3;
- UINT64 TempEndAddress = Event->Options.OptionalParam4;
- ConstEndAddress = TempEndAddress;
-
- //
- // Because there are different EPT hooks, like READ, WRITE, EXECUTE,
- // DETOURS INLINE HOOK, HIDDEN BREAKPOINT HOOK and all of them are
- // unhooked with a same routine, we will not check whether the list of
- // all of them is empty or not and instead, we remove just a single
- // hook, this way is better as hidden hooks and ept modifications are
- // not dependent to a single bit and if we remove or add any other hook
- // then it won't cause any problem for other hooks
- //
-
- PagesBytes = (UINT64)PAGE_ALIGN(TempStartAddress);
- PagesBytes = TempEndAddress - PagesBytes;
- PagesBytes = PagesBytes / PAGE_SIZE;
-
- RemainingSize = TempEndAddress - TempStartAddress;
-
- // LogInfo("Monitor termination, Start address: %llx, end address: %llx\n\n\n",
- // TempStartAddress,
- // TempEndAddress,
- // RemainingSize);
-
- for (size_t i = 0; i <= PagesBytes; i++)
+ if (InputFromVmxRoot)
{
- if (RemainingSize >= PAGE_SIZE)
- {
- TempEndAddress = (TempStartAddress + ((UINT64)PAGE_ALIGN(TempStartAddress + PAGE_SIZE) - TempStartAddress)) - 1;
- RemainingSize = ConstEndAddress - TempEndAddress - 1;
- }
- else
- {
- TempNextPageAddr = (UINT64)PAGE_ALIGN(TempStartAddress + RemainingSize);
-
- //
- // Check if by adding the remaining size, we'll go to the next
- // page boundary or not
- //
- if (TempNextPageAddr > ((UINT64)PAGE_ALIGN(TempStartAddress)))
- {
- //
- // It goes to the next page boundary
- //
- TempEndAddress = TempNextPageAddr - 1;
- RemainingSize = RemainingSize - (TempEndAddress - TempStartAddress) - 1;
- }
- else
- {
- TempEndAddress = TempStartAddress + RemainingSize;
- RemainingSize = 0;
- }
- }
-
- if (InputFromVmxRoot)
- {
- TerminateEptHookUnHookSingleAddressFromVmxRootAndApplyInvalidation((UINT64)TempStartAddress,
- (UINT64)NULL);
- }
- else
- {
- ConfigureEptHookUnHookSingleAddress((UINT64)TempStartAddress,
- (UINT64)NULL,
- Event->ProcessId);
- }
-
//
- // Swap the temporary start address and temporary end address
+ // EPT hooking tag is same as event tag, so we can use it to unhook
//
- TempStartAddress = TempEndAddress + 1;
+ TerminateEptHookUnHookAllHooksByHookingTagFromVmxRootAndApplyInvalidation(Event->Tag);
+ }
+ else
+ {
+ //
+ // EPT hooking tag is same as event tag, so we can use it to unhook
+ //
+ ConfigureEptHookUnHookAllByHookingTag(Event->Tag);
}
}
@@ -1192,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 ||
@@ -1283,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 ||
@@ -1642,11 +1580,54 @@ 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
*
- * @param VirtualAddress Virtual address to unhook
+ * @param VirtualAddress Virtual address to unhook (optional)
* @param PhysAddress Physical address to unhook (optional)
*
* @return BOOLEAN If unhook was successful it returns true or if it was not successful returns false
@@ -1698,6 +1679,69 @@ TerminateEptHookUnHookSingleAddressFromVmxRootAndApplyInvalidation(UINT64 Virtua
return FALSE;
}
+/**
+ * @brief Remove all hooks from the hooked pages list and invalidate TLB using hooking tag
+ * @details Should be called from vmx root-mode
+ *
+ * @param HookingTag The hooking tag to unhook
+ *
+ * @return BOOLEAN If unhook was successful it returns true or if it was not successful returns false
+ */
+BOOLEAN
+TerminateEptHookUnHookAllHooksByHookingTagFromVmxRootAndApplyInvalidation(UINT64 HookingTag)
+{
+ BOOLEAN Result = FALSE;
+ BOOLEAN IsAtLeastOneHookRemoved = FALSE;
+ EPT_SINGLE_HOOK_UNHOOKING_DETAILS TargetUnhookingDetails = {0};
+
+UnhookNextPossibleTag:
+ //
+ // Perform unhooking directly from VMX-root mode using hooking tag
+ //
+ Result = ConfigureEptHookUnHookSingleHookByHookingTagFromVmxRoot(HookingTag,
+ &TargetUnhookingDetails);
+
+ if (Result == TRUE)
+ {
+ //
+ // At least one hook was removed
+ //
+ IsAtLeastOneHookRemoved = TRUE;
+
+ //
+ // It's the responsibility of the caller to restore EPT entries and
+ // invalidate EPT caches
+ //
+ if (TargetUnhookingDetails.CallerNeedsToRestoreEntryAndInvalidateEpt)
+ {
+ HaltedBroadcastUnhookSinglePageAllCores(&TargetUnhookingDetails);
+ }
+
+ //
+ // It's the responsibility of the caller to clear #BPs directly from
+ // VMX-root mode if applied from VMX-root mode
+ //
+ if (TargetUnhookingDetails.RemoveBreakpointInterception)
+ {
+ //
+ // The hook was the last hook and we can broadcast to
+ // not intercept #BPs anymore
+ //
+ HaltedBroadcastUnSetExceptionBitmapAllCores(EXCEPTION_VECTOR_BREAKPOINT);
+ }
+
+ //
+ // Keep unhooking until there is no hook with the same hooking tag
+ //
+ goto UnhookNextPossibleTag;
+ }
+
+ //
+ // The result of removing EPT hook
+ //
+ return IsAtLeastOneHookRemoved;
+}
+
/**
* @brief Termination query state of debugger
*
@@ -1754,6 +1798,12 @@ TerminateQueryDebuggerResource(UINT32 CoreId,
break;
+ case PROTECTED_HV_RESOURCES_SAVE_AND_LOAD_DEBUG_CONTROLS:
+
+ Result = TerminateQueryDebuggerResourceSaveAndLoadDebugControls(CoreId, PassOver);
+
+ break;
+
default:
Result = FALSE;
@@ -1768,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/hprdbgkd/code/debugger/events/ValidateEvents.c b/hyperdbg/hyperkd/code/debugger/events/ValidateEvents.c
similarity index 83%
rename from hyperdbg/hprdbgkd/code/debugger/events/ValidateEvents.c
rename to hyperdbg/hyperkd/code/debugger/events/ValidateEvents.c
index d886915a..72f552d0 100644
--- a/hyperdbg/hprdbgkd/code/debugger/events/ValidateEvents.c
+++ b/hyperdbg/hyperkd/code/debugger/events/ValidateEvents.c
@@ -55,32 +55,55 @@ ValidateEventMonitor(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails,
// Check whether address is valid or not based on whether the event needs
// to be applied directly from VMX-root mode or not
//
- if (InputFromVmxRoot)
+ if ((DEBUGGER_HOOK_MEMORY_TYPE)EventDetails->Options.OptionalParam3 == DEBUGGER_MEMORY_HOOK_PHYSICAL_ADDRESS)
{
- if (VirtualAddressToPhysicalAddressOnTargetProcess((PVOID)EventDetails->Options.OptionalParam1) == (UINT64)NULL ||
- VirtualAddressToPhysicalAddressOnTargetProcess((PVOID)EventDetails->Options.OptionalParam2) == (UINT64)NULL)
+ //
+ // Validation of a physical address
+ //
+ if (CheckAddressPhysical(EventDetails->Options.OptionalParam1) == FALSE ||
+ CheckAddressPhysical(EventDetails->Options.OptionalParam2) == FALSE)
{
//
- // Address is invalid (Set the error)
+ // Physical address is invalid (Set the error)
//
ResultsToReturn->IsSuccessful = FALSE;
- ResultsToReturn->Error = DEBUGGER_ERROR_INVALID_ADDRESS;
+ ResultsToReturn->Error = DEBUGGER_ERROR_INVALID_PHYSICAL_ADDRESS;
return FALSE;
}
}
else
{
- if (VirtualAddressToPhysicalAddressByProcessId((PVOID)EventDetails->Options.OptionalParam1, TempPid) == (UINT64)NULL ||
- VirtualAddressToPhysicalAddressByProcessId((PVOID)EventDetails->Options.OptionalParam2, TempPid) == (UINT64)NULL)
+ //
+ // Validation of a virtual address
+ //
+ if (InputFromVmxRoot)
{
- //
- // Address is invalid (Set the error)
- //
+ if (VirtualAddressToPhysicalAddressOnTargetProcess((PVOID)EventDetails->Options.OptionalParam1) == (UINT64)NULL ||
+ VirtualAddressToPhysicalAddressOnTargetProcess((PVOID)EventDetails->Options.OptionalParam2) == (UINT64)NULL)
+ {
+ //
+ // Virtual address is invalid (Set the error)
+ //
- ResultsToReturn->IsSuccessful = FALSE;
- ResultsToReturn->Error = DEBUGGER_ERROR_INVALID_ADDRESS;
- return FALSE;
+ ResultsToReturn->IsSuccessful = FALSE;
+ ResultsToReturn->Error = DEBUGGER_ERROR_INVALID_ADDRESS;
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (VirtualAddressToPhysicalAddressByProcessId((PVOID)EventDetails->Options.OptionalParam1, TempPid) == (UINT64)NULL ||
+ VirtualAddressToPhysicalAddressByProcessId((PVOID)EventDetails->Options.OptionalParam2, TempPid) == (UINT64)NULL)
+ {
+ //
+ // Address is invalid (Set the error)
+ //
+
+ ResultsToReturn->IsSuccessful = FALSE;
+ ResultsToReturn->Error = DEBUGGER_ERROR_INVALID_ADDRESS;
+ return FALSE;
+ }
}
}
diff --git a/hyperdbg/hprdbgkd/code/debugger/kernel-level/Kd.c b/hyperdbg/hyperkd/code/debugger/kernel-level/Kd.c
similarity index 86%
rename from hyperdbg/hprdbgkd/code/debugger/kernel-level/Kd.c
rename to hyperdbg/hyperkd/code/debugger/kernel-level/Kd.c
index 1de14fd1..f3f7017b 100644
--- a/hyperdbg/hprdbgkd/code/debugger/kernel-level/Kd.c
+++ b/hyperdbg/hyperkd/code/debugger/kernel-level/Kd.c
@@ -24,9 +24,9 @@ KdInitializeKernelDebugger()
//
// Allocate DPC routine
//
- // for (size_t i = 0; i < CoreCount; i++)
+ // for (SIZE_T i = 0; i < CoreCount; i++)
// {
- // g_DbgState[i].KdDpcObject = CrsAllocateNonPagedPool(sizeof(KDPC));
+ // g_DbgState[i].KdDpcObject = PlatformMemAllocateNonPagedPool(sizeof(KDPC));
//
// if (g_DbgState[i].KdDpcObject == NULL)
// {
@@ -35,13 +35,6 @@ KdInitializeKernelDebugger()
// }
// }
- //
- // Request pages for breakpoint detail
- //
- PoolManagerRequestAllocation(sizeof(DEBUGGEE_BP_DESCRIPTOR),
- MAXIMUM_BREAKPOINTS_WITHOUT_CONTINUE,
- BREAKPOINT_DEFINITION_STRUCTURE);
-
//
// Enable vm-exit on Hardware debug exceptions and breakpoints
// so, intercept #DBs and #BP by changing exception bitmap (one core)
@@ -53,12 +46,6 @@ KdInitializeKernelDebugger()
//
RtlZeroMemory(&g_IgnoreBreaksToDebugger, sizeof(DEBUGGEE_REQUEST_TO_IGNORE_BREAKS_UNTIL_AN_EVENT));
- //
- // Initialize list of breakpoints and breakpoint id
- //
- g_MaximumBreakpointId = 0;
- InitializeListHead(&g_BreakpointsListHead);
-
//
// Initial the needed pools for instant events
//
@@ -258,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
*
@@ -414,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
*
@@ -600,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);
}
@@ -627,124 +688,37 @@ 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
*
* @param DbgState The state of the debugger on the current core
- * @param NewCore
+ * @param ChangeCorePacket
* @return BOOLEAN
*/
BOOLEAN
-KdSwitchCore(PROCESSOR_DEBUGGING_STATE * DbgState, UINT32 NewCore)
+KdSwitchCore(PROCESSOR_DEBUGGING_STATE * DbgState,
+ DEBUGGEE_CHANGE_CORE_PACKET * ChangeCorePacket)
{
ULONG ProcessorsCount = KeQueryActiveProcessorCount(0);
+ if (DbgState->CoreId == ChangeCorePacket->NewCore)
+ {
+ //
+ // The operating core and the target core is the same, no need for further action
+ //
+ ChangeCorePacket->Result = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ return FALSE; // Return FALSE to not unlock anything
+ }
+
//
// Check if core is valid or not
//
- if (NewCore >= ProcessorsCount)
+ if (ChangeCorePacket->NewCore >= ProcessorsCount)
{
//
// Invalid core count
//
+ ChangeCorePacket->Result = DEBUGGER_ERROR_PREPARING_DEBUGGEE_INVALID_CORE_IN_REMOTE_DEBUGGE;
return FALSE;
}
@@ -752,6 +726,15 @@ KdSwitchCore(PROCESSOR_DEBUGGING_STATE * DbgState, UINT32 NewCore)
// *** Core is valid ***
//
+ //
+ // Check to see whether this core is locked or not
+ //
+ if (!KdCheckTargetCoreIsLocked(ChangeCorePacket->NewCore))
+ {
+ ChangeCorePacket->Result = DEBUGGER_ERROR_TARGET_SWITCHING_CORE_IS_NOT_LOCKED;
+ return FALSE;
+ }
+
//
// Check if we should enable interrupts in this core or not
//
@@ -768,14 +751,14 @@ KdSwitchCore(PROCESSOR_DEBUGGING_STATE * DbgState, UINT32 NewCore)
//
// Set new operating core
//
- g_DbgState[NewCore].MainDebuggingCore = TRUE;
+ g_DbgState[ChangeCorePacket->NewCore].MainDebuggingCore = TRUE;
//
// Unlock the new core
// *** We should not unlock the spinlock here as the other core might
// simultaneously start sending packets and corrupt our packets ***
//
-
+ ChangeCorePacket->Result = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
return TRUE;
}
@@ -871,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
@@ -965,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 ***
@@ -980,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();
}
//
@@ -1019,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;
}
}
}
@@ -1111,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
//
@@ -1142,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
@@ -1179,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
@@ -1290,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
@@ -1400,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
@@ -1485,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
@@ -1572,9 +1558,20 @@ KdPerformRegisterEvent(PDEBUGGEE_EVENT_AND_ACTION_HEADER_FOR_REMOTE_PACKET Event
sizeof(DEBUGGEE_EVENT_AND_ACTION_HEADER_FOR_REMOTE_PACKET));
//
- // Parse event from the VMX-root mode
+ // Check to see whether all cores are halted (in instant event)
//
- DebuggerParseEvent(GeneralEventDetail, DebuggerEventAndActionResult, TRUE);
+ if (!KdCheckAllCoresAreLocked())
+ {
+ DebuggerEventAndActionResult->IsSuccessful = FALSE;
+ DebuggerEventAndActionResult->Error = DEBUGGER_ERROR_NOT_ALL_CORES_ARE_LOCKED_FOR_APPLYING_INSTANT_EVENT;
+ }
+ else
+ {
+ //
+ // Parse event from the VMX-root mode
+ //
+ DebuggerParseEvent(GeneralEventDetail, DebuggerEventAndActionResult, TRUE);
+ }
return FALSE;
@@ -1652,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,
@@ -1661,6 +1658,67 @@ KdQueryRflagTrapState()
}
}
+/**
+ * @brief Check whether all cores are locked or not
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+KdCheckAllCoresAreLocked()
+{
+ ULONG ProcessorsCount;
+
+ ProcessorsCount = KeQueryActiveProcessorCount(0);
+
+ //
+ // Query core debugging Lock info
+ //
+ for (SIZE_T i = 0; i < ProcessorsCount; i++)
+ {
+ if (!SpinlockCheckLock(&g_DbgState[i].Lock))
+ {
+ //
+ // We found one core that is not locked
+ //
+ return FALSE;
+ }
+ }
+
+ //
+ // Reaching here means all cores are locked
+ //
+ return TRUE;
+}
+
+/**
+ * @brief Check whether a specific target core is locked or not
+ * @param CoreNumber
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+KdCheckTargetCoreIsLocked(UINT32 CoreNumber)
+{
+ //
+ // Query core debugging Lock info
+ //
+
+ if (!SpinlockCheckLock(&g_DbgState[CoreNumber].Lock))
+ {
+ //
+ // This core is not locked
+ //
+ return FALSE;
+ }
+ else
+ {
+ //
+ // Target core is locked
+ //
+ return TRUE;
+ }
+}
+
/**
* @brief Query state of the system
*
@@ -1678,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))
{
@@ -1696,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)
{
@@ -2206,6 +2264,7 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState)
PDEBUGGER_SINGLE_CALLSTACK_FRAME CallstackFrameBuffer;
PDEBUGGER_DEBUGGER_TEST_QUERY_BUFFER TestQueryPacket;
PDEBUGGEE_REGISTER_READ_DESCRIPTION ReadRegisterPacket;
+ PDEBUGGEE_REGISTER_WRITE_DESCRIPTION WriteRegisterPacket;
PDEBUGGER_READ_MEMORY ReadMemoryPacket;
PDEBUGGER_EDIT_MEMORY EditMemoryPacket;
PDEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET ChangeProcessPacket;
@@ -2215,6 +2274,11 @@ 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;
PDEBUGGER_VA2PA_AND_PA2VA_COMMANDS Va2paPa2vaPacket;
PDEBUGGEE_BP_LIST_OR_MODIFY_PACKET BpListOrModifyPacket;
@@ -2228,6 +2292,8 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState)
UINT32 ReturnSize = 0;
DEBUGGEE_RESULT_OF_SEARCH_PACKET SearchPacketResult = {0};
DEBUGGER_EVENT_AND_ACTION_RESULT DebuggerEventAndActionResult = {0};
+ PDEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET PcitreePacket = {0};
+ PDEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET PcidevinfoPacket = {0};
while (TRUE)
{
@@ -2338,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
@@ -2364,9 +2433,9 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState)
//
//
- // Indicate a step
+ // Indicate a step-in
//
- KdRegularStepInInstruction(DbgState);
+ TracingRegularStepInInstruction();
//
// Unlock other cores
@@ -2409,36 +2478,20 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState)
ChangeCorePacket = (DEBUGGEE_CHANGE_CORE_PACKET *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
- if (DbgState->CoreId != ChangeCorePacket->NewCore)
+ //
+ // Switch to new core
+ //
+ if (KdSwitchCore(DbgState, ChangeCorePacket))
{
//
- // Switch to new core
+ // No need to wait for new commands
//
- if (KdSwitchCore(DbgState, ChangeCorePacket->NewCore))
- {
- //
- // No need to wait for new commands
- //
- EscapeFromTheLoop = TRUE;
+ EscapeFromTheLoop = TRUE;
- //
- // Unlock the new core
- //
- UnlockTheNewCore = TRUE;
-
- ChangeCorePacket->Result = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
- }
- else
- {
- ChangeCorePacket->Result = DEBUGGER_ERROR_PREPARING_DEBUGGEE_INVALID_CORE_IN_REMOTE_DEBUGGE;
- }
- }
- else
- {
//
- // The operating core and the target core is the same, no need for further action
+ // Unlock the new core
//
- ChangeCorePacket->Result = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ UnlockTheNewCore = TRUE;
}
//
@@ -2497,6 +2550,7 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState)
// Feel the callstack frames the buffers
//
if (CallstackWalkthroughStack(CallstackFrameBuffer,
+ &CallstackPacket->FrameCount,
CallstackPacket->BaseAddress,
CallstackPacket->Size,
CallstackPacket->Is32Bit))
@@ -2540,10 +2594,11 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState)
case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_READ_REGISTERS:
ReadRegisterPacket = (DEBUGGEE_REGISTER_READ_DESCRIPTION *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
+
//
// Read registers
//
- if (KdReadRegisters(DbgState, ReadRegisterPacket))
+ if (DebuggerCommandReadRegisters(DbgState->Regs, ReadRegisterPacket))
{
ReadRegisterPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
}
@@ -2552,7 +2607,7 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState)
ReadRegisterPacket->KernelStatus = DEBUGGER_ERROR_INVALID_REGISTER_NUMBER;
}
- if (ReadRegisterPacket->RegisterID == DEBUGGEE_SHOW_ALL_REGISTERS)
+ if (ReadRegisterPacket->RegisterId == DEBUGGEE_SHOW_ALL_REGISTERS)
{
SizeToSend = sizeof(DEBUGGEE_REGISTER_READ_DESCRIPTION) + sizeof(GUEST_REGS) + sizeof(GUEST_EXTRA_REGISTERS);
}
@@ -2570,6 +2625,32 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState)
break;
+ case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_WRITE_REGISTER:
+
+ WriteRegisterPacket = (DEBUGGEE_REGISTER_WRITE_DESCRIPTION *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
+
+ //
+ // Write register
+ //
+ if (SetRegValue(DbgState->Regs, WriteRegisterPacket->RegisterId, WriteRegisterPacket->Value))
+ {
+ WriteRegisterPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ }
+ else
+ {
+ WriteRegisterPacket->KernelStatus = DEBUGGER_ERROR_INVALID_REGISTER_NUMBER;
+ }
+
+ //
+ // Send the result of writing register back to the debuggee
+ //
+ KdResponsePacketToDebugger(DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGEE_TO_DEBUGGER,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_WRITE_REGISTER,
+ (CHAR *)WriteRegisterPacket,
+ sizeof(DEBUGGEE_REGISTER_WRITE_DESCRIPTION));
+
+ break;
+
case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_READ_MEMORY:
ReadMemoryPacket = (DEBUGGER_READ_MEMORY *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
@@ -2603,17 +2684,11 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState)
case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_EDIT_MEMORY:
EditMemoryPacket = (PDEBUGGER_EDIT_MEMORY)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
+
//
// Edit memory
//
- if (DebuggerCommandEditMemoryVmxRoot(EditMemoryPacket))
- {
- EditMemoryPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
- }
- else
- {
- EditMemoryPacket->KernelStatus = DEBUGGER_ERROR_INVALID_ADDRESS;
- }
+ DebuggerCommandEditMemoryVmxRoot(EditMemoryPacket);
//
// Send the result of reading memory back to the debuggee
@@ -2864,8 +2939,10 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState)
//
// Perform the action
+ // This is on the vmx-root mode for the kernel debugger, thus, no need to switch
+ // to the target process memory layout as we are already in it
//
- BreakpointAddNew(BpPacket);
+ BreakpointAddNew(BpPacket, FALSE);
//
// Send the result of the 'bp' back to the debuggee
@@ -2896,6 +2973,101 @@ 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));
+
+ //
+ // Call APIC handler (size to send is computed by this function)
+ //
+ SizeToSend = ExtensionCommandPerformActionsForApicRequests(ApicPacket);
+
+ //
+ // Send the result of the APIC requests back to the debuggee
+ //
+ KdResponsePacketToDebugger(DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGEE_TO_DEBUGGER,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_APIC_REQUESTS,
+ (CHAR *)ApicPacket,
+ SizeToSend);
+
+ break;
+
+ case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_READ_IDT_ENTRIES:
+
+ IdtEntryPacket = (INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
+
+ //
+ // Call IDT query handler (read from VMX root-mode)
+ //
+ ExtensionCommandPerformQueryIdtEntriesRequest(IdtEntryPacket, TRUE);
+
+ //
+ // Send the result of the IDT entries requests to the debuggee
+ //
+ KdResponsePacketToDebugger(DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGEE_TO_DEBUGGER,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_QUERY_IDT_ENTRIES_REQUESTS,
+ (CHAR *)IdtEntryPacket,
+ SIZEOF_INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS);
+
+ break;
+
case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_INJECT_PAGE_FAULT:
PageinPacket = (DEBUGGER_PAGE_IN_REQUEST *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
@@ -2941,8 +3113,9 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState)
//
// Perform the action
+ // No need to switch to the target process memory layout as we are already in it
//
- BreakpointListOrModify(BpListOrModifyPacket);
+ BreakpointListOrModify(BpListOrModifyPacket, FALSE);
//
// Send the result of modify or list breakpoints to the debuggee
@@ -2975,6 +3148,44 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState)
break;
+ case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_QUERY_PCITREE:
+
+ PcitreePacket = (DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
+
+ //
+ // Enumerate PCI tree
+ //
+ ExtensionCommandPcitree(PcitreePacket, TRUE);
+
+ //
+ // Send the result of '!pcitree' back to the debugger
+ //
+ KdResponsePacketToDebugger(DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGEE_TO_DEBUGGER,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_PCITREE,
+ (CHAR *)PcitreePacket,
+ sizeof(DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET));
+
+ break;
+
+ case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_QUERY_PCIDEVINFO:
+
+ PcidevinfoPacket = (DEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
+
+ //
+ // Retrieve PCI device info (CAM)
+ //
+ ExtensionCommandPcidevinfo(PcidevinfoPacket, TRUE);
+
+ //
+ // Send the result back to the debugger
+ //
+ KdResponsePacketToDebugger(DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGEE_TO_DEBUGGER,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_PCIDEVINFO,
+ (CHAR *)PcidevinfoPacket,
+ sizeof(DEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET));
+
+ break;
+
default:
LogError("Err, unknown packet action received from the debugger\n");
break;
diff --git a/hyperdbg/hprdbgkd/code/debugger/memory/Allocations.c b/hyperdbg/hyperkd/code/debugger/memory/Allocations.c
similarity index 87%
rename from hyperdbg/hprdbgkd/code/debugger/memory/Allocations.c
rename to hyperdbg/hyperkd/code/debugger/memory/Allocations.c
index efc12bc6..84c66297 100644
--- a/hyperdbg/hprdbgkd/code/debugger/memory/Allocations.c
+++ b/hyperdbg/hyperkd/code/debugger/memory/Allocations.c
@@ -25,7 +25,7 @@ GlobalDebuggingStateAllocateZeroedMemory(VOID)
//
// Allocate global variable to hold Debugging(s) state
//
- g_DbgState = CrsAllocateZeroedNonPagedPool(BufferSizeInByte);
+ g_DbgState = PlatformMemAllocateZeroedNonPagedPool(BufferSizeInByte);
if (!g_DbgState)
{
@@ -48,7 +48,7 @@ GlobalDebuggingStateAllocateZeroedMemory(VOID)
VOID
GlobalDebuggingStateFreeMemory(VOID)
{
- CrsFreePool(g_DbgState);
+ PlatformMemFreePool(g_DbgState);
g_DbgState = NULL;
}
@@ -65,7 +65,7 @@ GlobalEventsAllocateZeroedMemory(VOID)
//
if (!g_Events)
{
- g_Events = CrsAllocateNonPagedPool(sizeof(DEBUGGER_CORE_EVENTS));
+ g_Events = PlatformMemAllocateNonPagedPool(sizeof(DEBUGGER_CORE_EVENTS));
}
if (g_Events)
@@ -89,7 +89,7 @@ GlobalEventsFreeMemory(VOID)
{
if (g_Events != NULL)
{
- CrsFreePool(g_Events);
+ PlatformMemFreePool(g_Events);
g_Events = NULL;
}
}
diff --git a/hyperdbg/hprdbghv/code/memory/PoolManager.c b/hyperdbg/hyperkd/code/debugger/memory/PoolManager.c
similarity index 84%
rename from hyperdbg/hprdbghv/code/memory/PoolManager.c
rename to hyperdbg/hyperkd/code/debugger/memory/PoolManager.c
index 3fbcd2d7..3c195e68 100644
--- a/hyperdbg/hprdbghv/code/memory/PoolManager.c
+++ b/hyperdbg/hyperkd/code/debugger/memory/PoolManager.c
@@ -23,7 +23,7 @@ PlmgrAllocateRequestNewAllocation(SIZE_T NumberOfBytes)
//
// Allocate global requesting variable
//
- g_RequestNewAllocation = CrsAllocateZeroedNonPagedPool(NumberOfBytes);
+ g_RequestNewAllocation = PlatformMemAllocateZeroedNonPagedPool(NumberOfBytes);
if (!g_RequestNewAllocation)
{
@@ -36,7 +36,7 @@ PlmgrAllocateRequestNewAllocation(SIZE_T NumberOfBytes)
VOID
PlmgrFreeRequestNewAllocation(VOID)
{
- CrsFreePool(g_RequestNewAllocation);
+ PlatformMemFreePool(g_RequestNewAllocation);
g_RequestNewAllocation = NULL;
}
@@ -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,39 +92,51 @@ 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)
//
if (!PoolTable->AlreadyFreed)
{
- CrsFreePool((PVOID)PoolTable->Address);
+ PlatformMemFreePool((PVOID)PoolTable->Address);
}
//
// Unlink the PoolTable
//
- RemoveEntryList(&PoolTable->PoolsList);
+ RemoveEntryList(Link);
//
// Free the record itself
//
- CrsFreePool(PoolTable);
+ PlatformMemFreePool(PoolTable);
+
+ Link = Next;
}
+ InitializeListHead(&g_ListOfAllocatedPoolsHead);
+ g_IsNewRequestForDeAllocation = FALSE;
+ g_IsNewRequestForAllocationReceived = FALSE;
+
SpinlockUnlock(&LockForReadingPool);
PlmgrFreeRequestNewAllocation();
@@ -252,11 +270,11 @@ 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;
- SinglePool = CrsAllocateZeroedNonPagedPool(sizeof(POOL_TABLE));
+ SinglePool = PlatformMemAllocateZeroedNonPagedPool(sizeof(POOL_TABLE));
if (!SinglePool)
{
@@ -267,11 +285,11 @@ PoolManagerAllocateAndAddToPoolTable(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_
//
// Allocate the buffer
//
- SinglePool->Address = (UINT64)CrsAllocateZeroedNonPagedPool(Size);
+ SinglePool->Address = (UINT64)PlatformMemAllocateZeroedNonPagedPool(Size);
if (!SinglePool->Address)
{
- CrsFreePool(SinglePool);
+ PlatformMemFreePool(SinglePool);
LogError("Err, insufficient memory");
return FALSE;
@@ -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
@@ -377,21 +396,21 @@ PoolManagerCheckAndPerformAllocationAndDeallocation()
//
// This item should be freed
//
- CrsFreePool((PVOID)PoolTable->Address);
+ PlatformMemFreePool((PVOID)PoolTable->Address);
//
// Now we should remove the entry from the g_ListOfAllocatedPoolsHead
//
- RemoveEntryList(&PoolTable->PoolsList);
+ RemoveEntryList(Link);
//
// Free the structure pool
//
- CrsFreePool(PoolTable);
+ 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/hprdbgkd/code/debugger/meta-events/MetaDispatch.c b/hyperdbg/hyperkd/code/debugger/meta-events/MetaDispatch.c
similarity index 100%
rename from hyperdbg/hprdbgkd/code/debugger/meta-events/MetaDispatch.c
rename to hyperdbg/hyperkd/code/debugger/meta-events/MetaDispatch.c
diff --git a/hyperdbg/hprdbgkd/code/debugger/meta-events/Tracing.c b/hyperdbg/hyperkd/code/debugger/meta-events/Tracing.c
similarity index 78%
rename from hyperdbg/hprdbgkd/code/debugger/meta-events/Tracing.c
rename to hyperdbg/hyperkd/code/debugger/meta-events/Tracing.c
index 52af8b00..8a7837ca 100644
--- a/hyperdbg/hprdbgkd/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/hprdbgkd/code/debugger/objects/Process.c b/hyperdbg/hyperkd/code/debugger/objects/Process.c
similarity index 100%
rename from hyperdbg/hprdbgkd/code/debugger/objects/Process.c
rename to hyperdbg/hyperkd/code/debugger/objects/Process.c
diff --git a/hyperdbg/hprdbgkd/code/debugger/objects/Thread.c b/hyperdbg/hyperkd/code/debugger/objects/Thread.c
similarity index 95%
rename from hyperdbg/hprdbgkd/code/debugger/objects/Thread.c
rename to hyperdbg/hyperkd/code/debugger/objects/Thread.c
index 63bb4aa5..c209c10b 100644
--- a/hyperdbg/hprdbgkd/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
@@ -280,9 +280,9 @@ ThreadShowList(PDEBUGGEE_THREAD_LIST_NEEDED_DETAILS ThreadListSymb
SavingEntries[EnumerationCount - 1].ThreadId = HANDLE_TO_UINT32(ThreadCid.UniqueThread);
SavingEntries[EnumerationCount - 1].Ethread = Thread;
- RtlCopyMemory(&SavingEntries[EnumerationCount - 1].ImageFileName,
- CommonGetProcessNameFromProcessControlBlock((PEPROCESS)ThreadListSymbolInfo->Process),
- 15);
+ MemoryMapperReadMemorySafe((UINT64)CommonGetProcessNameFromProcessControlBlock((PEPROCESS)ThreadListSymbolInfo->Process),
+ &SavingEntries[EnumerationCount - 1].ImageFileName,
+ 15);
break;
@@ -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/script-engine/ScriptEngine.c b/hyperdbg/hyperkd/code/debugger/script-engine/ScriptEngine.c
new file mode 100644
index 00000000..90b65bba
--- /dev/null
+++ b/hyperdbg/hyperkd/code/debugger/script-engine/ScriptEngine.c
@@ -0,0 +1,123 @@
+/**
+ * @file ScriptEngine.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @author M.H. Gholamrezaei (mh@hyperdbg.org)
+ * @brief Script engine parser and wrapper functions
+ * @details
+ * @version 0.1
+ * @date 2020-10-22
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief Get current ip from the debugger frame
+ *
+ * @return UINT64 returns the rip of the current debuggee state frame
+ */
+UINT64
+ScriptEngineWrapperGetInstructionPointer()
+{
+ //
+ // Check if we are in vmx-root or not
+ //
+ if (VmFuncVmxGetCurrentExecutionMode() == TRUE)
+ {
+ return VmFuncGetRip();
+ }
+ else
+ {
+ //
+ // Otherwise $ip doesn't mean anything
+ //
+ return (UINT64)NULL;
+ }
+}
+
+/**
+ * @brief Get the address of reserved buffer
+ *
+ * @param Action Corresponding action
+ * @return UINT64 returns the requested buffer address from user
+ */
+UINT64
+ScriptEngineWrapperGetAddressOfReservedBuffer(PDEBUGGER_EVENT_ACTION Action)
+{
+ return Action->RequestedBuffer.RequstBufferAddress;
+}
+
+/**
+ * @brief Create and update the target core date and time
+ * @param DbgState The processor debugging state
+ *
+ * @return VOID
+ */
+VOID
+ScriptEngineUpdateTargetCoreDateTime(PROCESSOR_DEBUGGING_STATE * DbgState)
+{
+ LARGE_INTEGER SystemTime, LocalTime;
+ KeQuerySystemTime(&SystemTime);
+ ExSystemTimeToLocalTime(&SystemTime, &LocalTime);
+ RtlTimeToTimeFields(&LocalTime, &DbgState->DateTimeHolder.TimeFields);
+
+ sprintf_s(DbgState->DateTimeHolder.TimeBuffer,
+ RTL_NUMBER_OF(DbgState->DateTimeHolder.TimeBuffer),
+ "%02hd:%02hd:%02hd.%03hd",
+ DbgState->DateTimeHolder.TimeFields.Hour,
+ DbgState->DateTimeHolder.TimeFields.Minute,
+ DbgState->DateTimeHolder.TimeFields.Second,
+ DbgState->DateTimeHolder.TimeFields.Milliseconds);
+
+ sprintf_s(DbgState->DateTimeHolder.DateBuffer,
+ RTL_NUMBER_OF(DbgState->DateTimeHolder.DateBuffer),
+ "%04hd-%02hd-%02hd",
+ DbgState->DateTimeHolder.TimeFields.Year,
+ DbgState->DateTimeHolder.TimeFields.Month,
+ DbgState->DateTimeHolder.TimeFields.Day);
+}
+
+/**
+ * @brief Update core's date time and return time
+ *
+ * @return UINT64
+ */
+UINT64
+ScriptEngineGetTargetCoreTime()
+{
+ ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
+ PROCESSOR_DEBUGGING_STATE * DbgState = &g_DbgState[CurrentCore];
+
+ //
+ // Update the core's date time
+ //
+ ScriptEngineUpdateTargetCoreDateTime(DbgState);
+
+ //
+ // Return the time
+ //
+ return (UINT64)&DbgState->DateTimeHolder.TimeBuffer;
+}
+
+/**
+ * @brief Update core's date time and return date
+ *
+ * @return UINT64
+ */
+UINT64
+ScriptEngineGetTargetCoreDate()
+{
+ ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
+ PROCESSOR_DEBUGGING_STATE * DbgState = &g_DbgState[CurrentCore];
+
+ //
+ // Update the core's date time
+ //
+ ScriptEngineUpdateTargetCoreDateTime(DbgState);
+
+ //
+ // Return the date
+ //
+ return (UINT64)&DbgState->DateTimeHolder.DateBuffer;
+}
diff --git a/hyperdbg/hyperkd/code/debugger/tests/KernelTests.c b/hyperdbg/hyperkd/code/debugger/tests/KernelTests.c
new file mode 100644
index 00000000..03f304ba
--- /dev/null
+++ b/hyperdbg/hyperkd/code/debugger/tests/KernelTests.c
@@ -0,0 +1,29 @@
+/**
+ * @file KernelTests.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Implementation of kernel-side test functions
+ * @details
+ *
+ * @version 0.1
+ * @date 2021-04-06
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief Perform the kernel-side tests
+ *
+ * @param KernelTestRequest user-mode buffer to fill kernel test information
+ * @return VOID
+ */
+VOID
+TestKernelPerformTests(PDEBUGGER_PERFORM_KERNEL_TESTS KernelTestRequest)
+{
+ LogInfo("Starting kernel-test process...");
+
+ LogInfo("All the kernel events are triggered");
+
+ KernelTestRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+}
diff --git a/hyperdbg/hprdbgkd/code/debugger/user-level/Attaching.c b/hyperdbg/hyperkd/code/debugger/user-level/Attaching.c
similarity index 86%
rename from hyperdbg/hprdbgkd/code/debugger/user-level/Attaching.c
rename to hyperdbg/hyperkd/code/debugger/user-level/Attaching.c
index c68e75a4..7b83da01 100644
--- a/hyperdbg/hprdbgkd/code/debugger/user-level/Attaching.c
+++ b/hyperdbg/hyperkd/code/debugger/user-level/Attaching.c
@@ -93,7 +93,6 @@ AttachingInitialize()
* @param Is32Bit
* @param Eprocess
* @param PebAddressToMonitor
- * @param UsermodeReservedBuffer
* @return UINT64 returns the unique token
*/
UINT64
@@ -102,8 +101,7 @@ AttachingCreateProcessDebuggingDetails(UINT32 ProcessId,
BOOLEAN Is32Bit,
BOOLEAN CheckCallbackAtFirstInstruction,
PEPROCESS Eprocess,
- UINT64 PebAddressToMonitor,
- UINT64 UsermodeReservedBuffer)
+ UINT64 PebAddressToMonitor)
{
PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail;
@@ -111,7 +109,7 @@ AttachingCreateProcessDebuggingDetails(UINT32 ProcessId,
// Allocate the buffer
//
ProcessDebuggingDetail = (USERMODE_DEBUGGING_PROCESS_DETAILS *)
- CrsAllocateZeroedNonPagedPool(sizeof(USERMODE_DEBUGGING_PROCESS_DETAILS));
+ PlatformMemAllocateZeroedNonPagedPool(sizeof(USERMODE_DEBUGGING_PROCESS_DETAILS));
if (!ProcessDebuggingDetail)
{
@@ -132,14 +130,13 @@ AttachingCreateProcessDebuggingDetails(UINT32 ProcessId,
ProcessDebuggingDetail->CheckCallBackForInterceptingFirstInstruction = CheckCallbackAtFirstInstruction;
ProcessDebuggingDetail->Eprocess = Eprocess;
ProcessDebuggingDetail->PebAddressToMonitor = (PVOID)PebAddressToMonitor;
- ProcessDebuggingDetail->UsermodeReservedBuffer = UsermodeReservedBuffer;
//
// Allocate a thread holder buffer for this process
//
if (!ThreadHolderAssignThreadHolderToProcessDebuggingDetails(ProcessDebuggingDetail))
{
- CrsFreePool(ProcessDebuggingDetail);
+ PlatformMemFreePool(ProcessDebuggingDetail);
return (UINT64)NULL;
}
@@ -243,7 +240,7 @@ AttachingRemoveAndFreeAllProcessDebuggingDetails()
//
// Unallocate the pool
//
- CrsFreePool(ProcessDebuggingDetails);
+ PlatformMemFreePool(ProcessDebuggingDetails);
}
}
@@ -284,7 +281,7 @@ AttachingRemoveProcessDebuggingDetailsByToken(UINT64 Token)
//
// Unallocate the pool
//
- CrsFreePool(ProcessDebuggingDetails);
+ PlatformMemFreePool(ProcessDebuggingDetails);
return TRUE;
}
@@ -385,8 +382,11 @@ AttachingReachedToValidLoadedModule(PROCESSOR_DEBUGGING_STATE * DbgState
//
// Register the breakpoint
+ // Note that, even though it's a user-mode breakpoint, we are currently
+ // in the memory layout of the target process, thus, no switching memory
+ // layout is needed
//
- if (!BreakpointAddNew(&BpRequest))
+ if (!BreakpointAddNew(&BpRequest, FALSE))
{
LogError("Err, unable to set breakpoint on the entrypoint module");
return FALSE;
@@ -409,14 +409,19 @@ AttachingReachedToValidLoadedModule(PROCESSOR_DEBUGGING_STATE * DbgState
DEBUGGEE_PAUSING_REASON_DEBUGGEE_STARTING_MODULE_LOADED,
NULL);
}
- else
+ else if (g_UserDebuggerState)
{
//
// Handling state through the user-mode debugger
//
- UdCheckAndHandleBreakpointsAndDebugBreaks(DbgState,
- DEBUGGEE_PAUSING_REASON_DEBUGGEE_STARTING_MODULE_LOADED,
- NULL);
+ UdHandleInstantBreak(DbgState,
+ DEBUGGEE_PAUSING_REASON_DEBUGGEE_STARTING_MODULE_LOADED,
+ ProcessDebuggingDetail);
+ }
+ else
+ {
+ LogError("Err, no debugger is attached to handle the entrypoint interception");
+ return FALSE;
}
//
@@ -574,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)
@@ -610,45 +615,31 @@ AttachingAdjustNopSledBuffer(UINT64 ReservedBuffAddress, UINT32 ProcessId)
}
/**
- * @brief Check page-faults with user-debugger
- * @param CoreId
- * @param Address
- * @param PageFaultErrorCode
+ * @brief Check thread interceptions with user-mode debugger
*
- * @return BOOLEAN if TRUE show that the page-fault injection should be ignored
+ * @param CoreId
+ *
+ * @return BOOLEAN if TRUE show that the thread interceptin is handled otherwise FALSE
*/
BOOLEAN
-AttachingCheckPageFaultsWithUserDebugger(UINT32 CoreId,
- UINT64 Address,
- UINT32 PageFaultErrorCode)
+AttachingCheckThreadInterceptionWithUserDebugger(UINT32 CoreId)
{
- UNREFERENCED_PARAMETER(Address);
- UNREFERENCED_PARAMETER(PageFaultErrorCode);
-
- PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail;
PROCESSOR_DEBUGGING_STATE * DbgState = &g_DbgState[CoreId];
+ PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail;
//
// Check whether user-debugger is initialized or not
//
- if (g_UserDebuggerState == FALSE)
+ if (!g_UserDebuggerState)
{
return FALSE;
}
- //
- // Check if thread is in user-mode
- //
- if (VmFuncGetLastVmexitRip(CoreId) & 0xf000000000000000)
- {
- //
- // We won't intercept threads in kernel-mode
- //
- return FALSE;
- }
-
ProcessDebuggingDetail = AttachingFindProcessDebuggingDetailsByProcessId(HANDLE_TO_UINT32(PsGetCurrentProcessId()));
+ //
+ // Check if the process debugging detail is found
+ //
if (!ProcessDebuggingDetail)
{
//
@@ -658,23 +649,24 @@ AttachingCheckPageFaultsWithUserDebugger(UINT32 CoreId,
}
//
- // Check if thread is in intercepting phase
+ // Check if thread is in the intercepting phase
//
if (ProcessDebuggingDetail->IsOnThreadInterceptingPhase)
{
//
// 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);
- //
- // related to user debugger
- //
- VmFuncSuppressRipIncrement(CoreId);
-
- return TRUE;
+ return TRUE;
+ }
}
//
@@ -715,56 +707,32 @@ AttachingConfigureInterceptingThreads(UINT64 ProcessDebuggingToken, BOOLEAN Enab
return FALSE;
}
- //
- // if the user want to disable the intercepting phase, we just ignore the
- // request without a message
- //
- if (!Enable && !ProcessDebuggingDetail->IsOnThreadInterceptingPhase)
- {
- return FALSE;
- }
-
//
// We're or we're not in thread intercepting phase now
//
ProcessDebuggingDetail->IsOnThreadInterceptingPhase = Enable;
+ //
+ // Intercepting threads is enabled
+ //
if (Enable)
{
//
- // Intercept all mov 2 cr3s
+ // Add the process to the watching list to be able to intercept the threads
//
- DebuggerEventEnableMovToCr3ExitingOnAllProcessors();
+ ConfigureExecTrapAddProcessToWatchingList(ProcessDebuggingDetail->ProcessId);
}
else
{
//
- // Removing the mov to cr3 vm-exits
+ // Unpause the threads of the target process
//
- DebuggerEventDisableMovToCr3ExitingOnAllProcessors();
- }
+ ThreadHolderUnpauseAllThreadsInProcess(ProcessDebuggingDetail);
- //
- // Set the supervisor bit to 1 when we want to continue all the threads
- //
- if (!Enable)
- {
- for (size_t i = 0; i < MAX_CR3_IN_A_PROCESS; i++)
- {
- if (ProcessDebuggingDetail->InterceptedCr3[i].Flags != (UINT64)NULL)
- {
- //
- // This cr3 should not be intercepted on threads' user mode execution
- //
- if (!MemoryMapperSetSupervisorBitWithoutSwitchingByCr3(NULL,
- TRUE,
- PagingLevelPageMapLevel4,
- ProcessDebuggingDetail->InterceptedCr3[i]))
- {
- return FALSE;
- }
- }
- }
+ //
+ // Remove the process from the watching list
+ //
+ ConfigureExecTrapRemoveProcessFromWatchingList(ProcessDebuggingDetail->ProcessId);
}
return TRUE;
@@ -810,7 +778,6 @@ AttachingPerformAttachToProcess(PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS Attach
PEPROCESS SourceProcess;
UINT64 ProcessDebuggingToken;
UINT64 PebAddressToMonitor;
- UINT64 UsermodeReservedBuffer;
BOOLEAN ResultOfApplyingEvent;
BOOLEAN Is32Bit;
PUSERMODE_DEBUGGING_PROCESS_DETAILS TempProcessDebuggingDetail;
@@ -882,32 +849,6 @@ AttachingPerformAttachToProcess(PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS Attach
return FALSE;
}
- //
- // allocate memory in the target user-mode process
- //
- UsermodeReservedBuffer = MemoryMapperReserveUsermodeAddressOnTargetProcess(AttachRequest->ProcessId, TRUE);
-
- if (UsermodeReservedBuffer == (UINT64)NULL)
- {
- AttachRequest->Result = DEBUGGER_ERROR_UNABLE_TO_ATTACH_TO_TARGET_USER_MODE_PROCESS;
- return FALSE;
- }
-
- //
- // Adjust the nop sled buffer
- //
- if (!AttachingAdjustNopSledBuffer(UsermodeReservedBuffer,
- AttachRequest->ProcessId))
- {
- AttachRequest->Result = DEBUGGER_ERROR_UNABLE_TO_ATTACH_TO_TARGET_USER_MODE_PROCESS;
- return FALSE;
- }
-
- //
- // Log for test
- //
- // LogInfo("Reserved address on the target process: %llx\n", UsermodeReservedBuffer);
-
//
// Create the debugging detail for process
//
@@ -916,8 +857,7 @@ AttachingPerformAttachToProcess(PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS Attach
Is32Bit,
AttachRequest->CheckCallbackAtFirstInstruction,
SourceProcess,
- PebAddressToMonitor,
- UsermodeReservedBuffer);
+ PebAddressToMonitor);
//
// Check if we successfully get the token
@@ -1024,72 +964,6 @@ AttachingPerformAttachToProcess(PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS Attach
return TRUE;
}
-/**
- * @brief Handle the cr3 vm-exits for thread interception
- * @details this function should be called in vmx-root
- *
- * @param CoreId
- * @param NewCr3
- * @return BOOLEAN
- */
-BOOLEAN
-AttachingHandleCr3VmexitsForThreadInterception(UINT32 CoreId, CR3_TYPE NewCr3)
-{
- PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail;
-
- ProcessDebuggingDetail = AttachingFindProcessDebuggingDetailsByProcessId(HANDLE_TO_UINT32(PsGetCurrentProcessId()));
-
- //
- // Check if process is valid or if thread is in intercepting phase
- //
- if (!ProcessDebuggingDetail || !ProcessDebuggingDetail->IsOnThreadInterceptingPhase)
- {
- //
- // not related to user debugger
- //
- VmFuncUnsetExceptionBitmap(CoreId, EXCEPTION_VECTOR_PAGE_FAULT);
- return FALSE;
- }
-
- //
- // Save the cr3 for future continuing the thread
- //
- for (size_t i = 0; i < MAX_CR3_IN_A_PROCESS; i++)
- {
- if (ProcessDebuggingDetail->InterceptedCr3[i].Flags == NewCr3.Flags)
- {
- //
- // We found it saved previously, no need any further action
- //
- break;
- }
-
- if (ProcessDebuggingDetail->InterceptedCr3[i].Flags == (UINT64)NULL)
- {
- //
- // Save the cr3
- //
- ProcessDebuggingDetail->InterceptedCr3[i].Flags = NewCr3.Flags;
- break;
- }
- }
-
- //
- // This thread should be intercepted
- //
- if (!MemoryMapperSetSupervisorBitWithoutSwitchingByCr3(NULL, FALSE, PagingLevelPageMapLevel4, NewCr3))
- {
- return FALSE;
- }
-
- //
- // Intercept #PFs
- //
- VmFuncSetExceptionBitmap(CoreId, EXCEPTION_VECTOR_PAGE_FAULT);
-
- return TRUE;
-}
-
/**
* @brief handling unhandled EPT violations
* @param CoreId
@@ -1199,6 +1073,50 @@ AttachingPauseProcess(PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS PauseRequest)
}
}
+/**
+ * @brief Continues the target process
+ * @details this function should not be called in vmx-root
+ *
+ * @param ContinueRequest
+ * @return BOOLEAN
+ */
+BOOLEAN
+AttachingContinueProcess(PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS ContinueRequest)
+{
+ PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetails;
+
+ //
+ // Get the thread debugging detail
+ //
+ ProcessDebuggingDetails = AttachingFindProcessDebuggingDetailsByToken(ContinueRequest->Token);
+
+ //
+ // Check if token is valid or not
+ //
+ if (!ProcessDebuggingDetails)
+ {
+ ContinueRequest->Result = DEBUGGER_ERROR_INVALID_THREAD_DEBUGGING_TOKEN;
+ return FALSE;
+ }
+
+ //
+ // Configure the intercepting threads to be disabled
+ //
+ if (AttachingConfigureInterceptingThreads(ContinueRequest->Token, FALSE))
+ {
+ //
+ // The continuing operation was successful
+ //
+ ContinueRequest->Result = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
+ return TRUE;
+ }
+ else
+ {
+ ContinueRequest->Result = DEBUGGER_ERROR_UNABLE_TO_PAUSE_THE_PROCESS_THREADS;
+ return FALSE;
+ }
+}
+
/**
* @brief Kill the target process from kernel-mode
* @details this function should not be called in vmx-root
@@ -1332,16 +1250,9 @@ AttachingPerformDetach(PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS DetachRequest)
}
//
- // Free the reserved memory in the target process
+ // Remove the process from interception mechanisms
//
- if (!MemoryMapperFreeMemoryOnTargetProcess(DetachRequest->ProcessId,
- (PVOID)ProcessDebuggingDetail->UsermodeReservedBuffer))
- {
- //
- // Still, we continue, no need to abort the operation
- //
- LogError("Err, cannot deallocate reserved buffer in the detached process");
- }
+ AttachingConfigureInterceptingThreads(ProcessDebuggingDetail->Token, FALSE);
//
// Remove the entry from the process debugging details list
@@ -1430,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;
@@ -1510,7 +1427,11 @@ AttachingTargetProcess(PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS Request)
//
// As we're here, we need to initialize the user-mode debugger
//
- UdInitializeUserDebugger();
+ if (!UdInitializeUserDebugger())
+ {
+ Request->Result = DEBUGGER_ERROR_DEBUGGER_NOT_INITIALIZED;
+ return;
+ }
switch (Request->Action)
{
@@ -1538,6 +1459,12 @@ AttachingTargetProcess(PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS Request)
break;
+ case DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_CONTINUE_PROCESS:
+
+ AttachingContinueProcess(Request);
+
+ break;
+
case DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_PAUSE_PROCESS:
AttachingPauseProcess(Request);
diff --git a/hyperdbg/hprdbgkd/code/debugger/user-level/ThreadHolder.c b/hyperdbg/hyperkd/code/debugger/user-level/ThreadHolder.c
similarity index 89%
rename from hyperdbg/hprdbgkd/code/debugger/user-level/ThreadHolder.c
rename to hyperdbg/hyperkd/code/debugger/user-level/ThreadHolder.c
index def1abfa..0d37c3b6 100644
--- a/hyperdbg/hprdbgkd/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)
{
@@ -98,6 +98,42 @@ ThreadHolderIsAnyPausedThreadInProcess(PUSERMODE_DEBUGGING_PROCESS_DETAILS Proce
return FALSE;
}
+/**
+ * @brief Unpause all threads in the process debugging details
+ *
+ * @param ProcessDebuggingDetail
+ * @return BOOLEAN
+ */
+BOOLEAN
+ThreadHolderUnpauseAllThreadsInProcess(PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail)
+{
+ PLIST_ENTRY TempList = 0;
+ BOOLEAN AtLeastOneThreadUnpaused = FALSE;
+
+ TempList = &ProcessDebuggingDetail->ThreadsListHead;
+
+ while (&ProcessDebuggingDetail->ThreadsListHead != TempList->Flink)
+ {
+ TempList = TempList->Flink;
+ 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++)
+ {
+ if (ThreadHolder->Threads[i].ThreadId != NULL_ZERO && ThreadHolder->Threads[i].IsPaused)
+ {
+ //
+ // At least one thread is paused, let's unpause it
+ //
+ ThreadHolder->Threads[i].IsPaused = FALSE;
+ AtLeastOneThreadUnpaused = TRUE;
+ }
+ }
+ }
+
+ return AtLeastOneThreadUnpaused;
+}
+
/**
* @brief Find the active threads of the process from process id
*
@@ -129,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)
{
@@ -177,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)
{
@@ -226,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)
{
@@ -269,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)
{
@@ -301,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)
{
@@ -379,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)
{
@@ -418,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)
{
@@ -518,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)
{
@@ -595,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
new file mode 100644
index 00000000..3d0a7e84
--- /dev/null
+++ b/hyperdbg/hyperkd/code/debugger/user-level/Ud.c
@@ -0,0 +1,992 @@
+/**
+ * @file Ud.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Routines related to user mode debugging
+ * @details
+ * @version 0.1
+ * @date 2022-01-06
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief initialize user debugger
+ * @details this function should be called on vmx non-root
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+UdInitializeUserDebugger()
+{
+ //
+ // Check if it's already initialized or not, we'll ignore it if it's
+ // previously initialized
+ //
+ if (g_UserDebuggerState)
+ {
+ return TRUE;
+ }
+
+ //
+ // Configure the exec-trap on all processors
+ //
+ if (!ConfigureInitializeExecTrapOnAllProcessors())
+ {
+ return FALSE;
+ }
+
+ //
+ // Check if we have functions we need for attaching mechanism
+ //
+ if (g_PsGetProcessPeb == NULL || g_PsGetProcessWow64Process == NULL || g_ZwQueryInformationProcess == NULL)
+ {
+ LogError("Err, unable to find needed functions for user-debugger");
+ // return FALSE;
+ }
+
+ //
+ // Start the seed of user-mode debugging thread
+ //
+ g_SeedOfUserDebuggingDetails = DebuggerThreadDebuggingTagStartSeed;
+
+ //
+ // Initialize the thread debugging details list
+ //
+ InitializeListHead(&g_ProcessDebuggingDetailsListHead);
+
+ //
+ // Enable vm-exit on Hardware debug exceptions and breakpoints
+ // so, intercept #DBs and #BP by changing exception bitmap (one core)
+ //
+ BroadcastEnableDbAndBpExitingAllCores();
+
+ //
+ // Request to allocate buffers for thread holder of threads
+ //
+ ThreadHolderAllocateThreadHoldingBuffers();
+
+ //
+ // Initialize command waiting event
+ //
+ SynchronizationInitializeEvent(&g_UserDebuggerWaitingCommandEvent);
+
+ //
+ // Indicate that the user debugger is active
+ //
+ g_UserDebuggerState = TRUE;
+
+ return TRUE;
+}
+
+/**
+ * @brief uninitialize user debugger
+ * @details this function should be called on vmx non-root
+ *
+ * @return VOID
+ */
+VOID
+UdUninitializeUserDebugger()
+{
+ if (g_UserDebuggerState)
+ {
+ //
+ // Indicate that the user debugger is not active
+ //
+ g_UserDebuggerState = FALSE;
+
+ //
+ // Uninitialize the exec-trap on all processors
+ //
+ ConfigureUninitializeExecTrapOnAllProcessors();
+
+ //
+ // Free and deallocate all the buffers (pools) relating to
+ // thread debugging details
+ //
+ AttachingRemoveAndFreeAllProcessDebuggingDetails();
+ }
+}
+
+/**
+ * @brief Handle cases where we instant break is needed on the user debugger
+ *
+ * @param DbgState The state of the debugger on the current core
+ * @param Reason The reason of the pausing
+ * @param ProcessDebuggingDetail
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+UdHandleInstantBreak(PROCESSOR_DEBUGGING_STATE * DbgState,
+ DEBUGGEE_PAUSING_REASON Reason,
+ PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail)
+{
+ //
+ // Check if the process debugging details is available or not
+ //
+ if (ProcessDebuggingDetail == NULL)
+ {
+ //
+ // If the process debugging detail is not available, we should
+ // find it by the current process id
+ //
+ ProcessDebuggingDetail = AttachingFindProcessDebuggingDetailsByProcessId(HANDLE_TO_UINT32(PsGetCurrentProcessId()));
+
+ if (ProcessDebuggingDetail == NULL)
+ {
+ //
+ // If we reached here, it means that the process debugging detail is not found
+ // so, we should return FALSE to indicate that we couldn't handle the instant break
+ //
+ return FALSE;
+ }
+ }
+
+ //
+ // Add the process to the watching list to be able to intercept the threads
+ //
+ if (AttachingConfigureInterceptingThreads(ProcessDebuggingDetail->Token, TRUE))
+ {
+ //
+ // Since the adding it to the watching list will take effect from the next
+ // CR3 vm-exit, we should change the state of the core to prevent further execution
+ //
+ ConfigureExecTrapApplyMbecConfiguratinFromKernelSide(DbgState->CoreId);
+
+ //
+ // Handling state through the user-mode debugger
+ //
+ return UdCheckAndHandleBreakpointsAndDebugBreaks(DbgState,
+ Reason,
+ NULL);
+ }
+
+ //
+ // If we reached here, it means that we couldn't add the process to the
+ //
+ return FALSE;
+}
+
+/**
+ * @brief Apply hardware debug registers to all cores
+ *
+ * @param TargetAddress
+ *
+ * @return VOID
+ */
+VOID
+UdApplyHardwareDebugRegister(PVOID TargetAddress)
+{
+ SetDebugRegisters(DEBUGGER_DEBUG_REGISTER_FOR_STEP_OVER,
+ BREAK_ON_INSTRUCTION_FETCH,
+ FALSE,
+ (UINT64)TargetAddress);
+}
+
+/**
+ * @brief Send the result of formats command to the user debugger
+ * @param Value
+ *
+ * @return VOID
+ */
+VOID
+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)
+{
+ //
+ // Broadcast to all cores
+ //
+ 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:
+
+ //
+ // Apply step-in (t command)
+ //
+ TracingRegularStepInInstruction();
+
+ //
+ // Continue the debuggee process
+ //
+ 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;
+
+ //
+ // Recover the action request buffer and optional storage buffer
+ //
+ ActionRequest = (DEBUGGER_UD_COMMAND_PACKET *)g_UserDebuggerWaitingCommandBuffer;
+ RegDesc = (PDEBUGGEE_REGISTER_READ_DESCRIPTION)((UINT8 *)g_UserDebuggerWaitingCommandBuffer + sizeof(DEBUGGER_UD_COMMAND_PACKET));
+
+ //
+ // *** Here, we should read the registers and put them in the optional storage buffer ***
+ //
+ 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
+ * @param OptionalParam2
+ * @param OptionalParam3
+ * @param OptionalParam4
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+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(OptionalParam4);
+
+ //
+ // Perform the command
+ //
+ switch (UserAction)
+ {
+ case DEBUGGER_UD_COMMAND_ACTION_TYPE_REGULAR_STEP:
+
+ //
+ // Stepping through the instructions
+ //
+ 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;
+
+ default:
+
+ //
+ // Invalid user action
+ //
+ return FALSE;
+
+ break;
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Check for the user-mode commands
+ *
+ * @param DbgState The state of the debugger on the current core
+ * @param ProcessDebuggingDetail
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+UdCheckForCommand(PROCESSOR_DEBUGGING_STATE * DbgState,
+ PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail)
+{
+ PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadDebuggingDetails;
+ BOOLEAN CommandFound = FALSE;
+
+ ThreadDebuggingDetails = ThreadHolderGetProcessThreadDetailsByProcessIdAndThreadId(HANDLE_TO_UINT32(PsGetCurrentProcessId()),
+ HANDLE_TO_UINT32(PsGetCurrentThreadId()));
+
+ if (!ThreadDebuggingDetails)
+ {
+ return FALSE;
+ }
+
+ //
+ // If we reached here, the current thread is in debugger attached mechanism
+ // now we check whether it's paused or not
+ //
+ if (!ThreadDebuggingDetails->IsPaused)
+ {
+ return FALSE;
+ }
+
+ //
+ // 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++)
+ {
+ if (ThreadDebuggingDetails->UdAction[i].ActionType != DEBUGGER_UD_COMMAND_ACTION_TYPE_NONE)
+ {
+ //
+ // We found a command for this thread
+ //
+ CommandFound = TRUE;
+
+ //
+ // Perform the command
+ //
+ UdPerformCommand(DbgState,
+ ProcessDebuggingDetail,
+ ThreadDebuggingDetails,
+ ThreadDebuggingDetails->UdAction[i].ActionType,
+ ThreadDebuggingDetails->UdAction[i].OptionalParam1,
+ ThreadDebuggingDetails->UdAction[i].OptionalParam2,
+ ThreadDebuggingDetails->UdAction[i].OptionalParam3,
+ ThreadDebuggingDetails->UdAction[i].OptionalParam4);
+
+ //
+ // Remove the command
+ //
+ ThreadDebuggingDetails->UdAction[i].OptionalParam1 = (UINT64)NULL;
+ ThreadDebuggingDetails->UdAction[i].OptionalParam2 = (UINT64)NULL;
+ ThreadDebuggingDetails->UdAction[i].OptionalParam3 = (UINT64)NULL;
+ ThreadDebuggingDetails->UdAction[i].OptionalParam4 = (UINT64)NULL;
+
+ //
+ // At last disable it
+ //
+ ThreadDebuggingDetails->UdAction[i].ActionType = DEBUGGER_UD_COMMAND_ACTION_TYPE_NONE;
+
+ //
+ // only one command at a time
+ //
+ break;
+ }
+ }
+
+ //
+ // Return whether we found a command or not
+ //
+ return CommandFound;
+}
+
+/**
+ * @brief Dispatch the user-mode commands
+ *
+ * @param ActionRequest
+ * @param ActionRequestInputLength
+ * @param ActionRequestOutputLength
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+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
+ //
+ ProcessDebuggingDetails = AttachingFindProcessDebuggingDetailsByToken(ActionRequest->ProcessDebuggingDetailToken);
+
+ if (!ProcessDebuggingDetails)
+ {
+ //
+ // Token not found!
+ //
+ ActionRequest->Result = DEBUGGER_ERROR_INVALID_THREAD_DEBUGGING_TOKEN;
+
+ return FALSE;
+ }
+
+ //
+ // Check if this command needs the action request to be waited for completion or not
+ //
+ if (ActionRequest->WaitForEventCompletion)
+ {
+ //
+ // 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
+ //
+ 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;
+}
+
+/**
+ * @brief Set the thread pausing state
+ *
+ * @param ThreadDebuggingDetails
+ * @param ProcessDebuggingDetails
+ * @param InstructionBytesBuffer
+ * @param SizeOfInstruction
+ *
+ * @return VOID
+ */
+VOID
+UdSetThreadPausingState(PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadDebuggingDetails,
+ PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetails,
+ PVOID InstructionBytesBuffer,
+ UINT32 SizeOfInstruction)
+{
+ UNREFERENCED_PARAMETER(ProcessDebuggingDetails);
+
+ //
+ // Save the RIP for future return
+ //
+ 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);
+}
+
+/**
+ * @brief Handle special reasons pre-pausings
+ * @details This function can be used in vmx-root
+ *
+ * @param DbgState The state of the debugger on the current core
+ * @param ThreadDebuggingDetails
+ * @param Reason
+ * @param EventDetails
+ * @return VOID
+ */
+VOID
+UdPrePausingReasons(PROCESSOR_DEBUGGING_STATE * DbgState,
+ PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadDebuggingDetails,
+ DEBUGGEE_PAUSING_REASON Reason,
+ PDEBUGGER_TRIGGERED_EVENT_DETAILS EventDetails)
+
+{
+ UNREFERENCED_PARAMETER(DbgState);
+ UNREFERENCED_PARAMETER(ThreadDebuggingDetails);
+ UNREFERENCED_PARAMETER(EventDetails);
+
+ //
+ // *** Handle events before pausing ***
+ //
+ switch (Reason)
+ {
+ case DEBUGGEE_PAUSING_REASON_DEBUGGEE_GENERAL_DEBUG_BREAK:
+
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Handle #DBs and #BPs for kernel debugger
+ * @details This function can be used in vmx-root
+ *
+ * @param DbgState The state of the debugger on the current core
+ * @param Reason
+ * @param EventDetails
+ * @return BOOLEAN
+ */
+BOOLEAN
+UdCheckAndHandleBreakpointsAndDebugBreaks(PROCESSOR_DEBUGGING_STATE * DbgState,
+ DEBUGGEE_PAUSING_REASON Reason,
+ PDEBUGGER_TRIGGERED_EVENT_DETAILS EventDetails)
+{
+ DEBUGGEE_UD_PAUSED_PACKET PausePacket;
+ ULONG ExitInstructionLength = 0;
+ UINT32 SizeOfSafeBufferToRead = 0;
+ RFLAGS Rflags = {0};
+ PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetails = NULL;
+ PUSERMODE_DEBUGGING_THREAD_DETAILS ThreadDebuggingDetails = NULL;
+ UINT64 LastVmexitRip = VmFuncGetLastVmexitRip(DbgState->CoreId);
+
+ //
+ // Breaking only supported if user-debugger is loaded
+ //
+ if (!g_UserDebuggerState)
+ {
+ return FALSE;
+ }
+
+ //
+ // Check entry of paused thread
+ //
+ ProcessDebuggingDetails = AttachingFindProcessDebuggingDetailsByProcessId(HANDLE_TO_UINT32(PsGetCurrentProcessId()));
+
+ if (!ProcessDebuggingDetails)
+ {
+ //
+ // Token not found!
+ //
+ return FALSE;
+ }
+
+ //
+ // Find the thread entry and if not found, create one for it
+ //
+ ThreadDebuggingDetails = ThreadHolderFindOrCreateThreadDebuggingDetail(HANDLE_TO_UINT32(PsGetCurrentThreadId()), ProcessDebuggingDetails);
+
+ if (!ThreadDebuggingDetails)
+ {
+ //
+ // Sth went wrong!
+ //
+ return FALSE;
+ }
+
+ //
+ // Check if the thread is already paused or not
+ //
+ 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
+ //
+ return TRUE;
+ }
+
+ //
+ // Set it as active thread debugging
+ //
+ ProcessDebuggingDetails->ActiveThreadId = ThreadDebuggingDetails->ThreadId;
+
+ //
+ // Perform the pre-pausing tasks
+ //
+ UdPrePausingReasons(DbgState, ThreadDebuggingDetails, Reason, EventDetails);
+
+ //
+ // *** Fill the pausing structure ***
+ //
+
+ RtlZeroMemory(&PausePacket, sizeof(DEBUGGEE_UD_PAUSED_PACKET));
+
+ //
+ // Set the pausing reason
+ //
+ PausePacket.PausingReason = Reason;
+
+ //
+ // Set process debugging information
+ //
+ PausePacket.ProcessId = HANDLE_TO_UINT32(PsGetCurrentProcessId());
+ PausePacket.ThreadId = HANDLE_TO_UINT32(PsGetCurrentThreadId());
+ PausePacket.ProcessDebuggingToken = ProcessDebuggingDetails->Token;
+
+ //
+ // Set the RIP and mode of execution
+ //
+ PausePacket.Rip = LastVmexitRip;
+ PausePacket.Is32Bit = KdIsGuestOnUsermode32Bit();
+
+ //
+ // Set rflags for finding the results of conditional jumps
+ //
+ Rflags.AsUInt = VmFuncGetRflags();
+ PausePacket.Rflags = Rflags.AsUInt;
+
+ //
+ // Set the event tag (if it's an event)
+ //
+ if (EventDetails != NULL)
+ {
+ PausePacket.EventTag = EventDetails->Tag;
+ PausePacket.EventCallingStage = EventDetails->Stage;
+ }
+
+ //
+ // Read the instruction len
+ //
+ if (DbgState->InstructionLengthHint != 0)
+ {
+ ExitInstructionLength = DbgState->InstructionLengthHint;
+ }
+ else
+ {
+ //
+ // Reading instruction length (VMCS_VMEXIT_INSTRUCTION_LENGTH) proved to
+ // provide wrong results, so we won't use it
+ //
+
+ //
+ // Compute the amount of buffer we can read without problem
+ //
+ SizeOfSafeBufferToRead = (UINT32)(LastVmexitRip & 0xfff);
+ SizeOfSafeBufferToRead += MAXIMUM_INSTR_SIZE;
+
+ if (SizeOfSafeBufferToRead >= PAGE_SIZE)
+ {
+ SizeOfSafeBufferToRead = SizeOfSafeBufferToRead - PAGE_SIZE;
+ SizeOfSafeBufferToRead = MAXIMUM_INSTR_SIZE - SizeOfSafeBufferToRead;
+ }
+ else
+ {
+ SizeOfSafeBufferToRead = MAXIMUM_INSTR_SIZE;
+ }
+
+ //
+ // Set the length to notify debuggee
+ //
+ ExitInstructionLength = SizeOfSafeBufferToRead;
+ }
+
+ //
+ // Set the reading length of bytes (for instruction disassembling)
+ //
+ PausePacket.ReadInstructionLen = (UINT16)ExitInstructionLength;
+
+ //
+ // Find the current instruction
+ //
+ MemoryMapperReadMemorySafeOnTargetProcess(LastVmexitRip,
+ &PausePacket.InstructionBytesOnRip,
+ ExitInstructionLength);
+
+ //
+ // Send the pause packet, along with RIP and an indication
+ // to pause to the user debugger
+ //
+ LogCallbackSendBuffer(OPERATION_NOTIFICATION_FROM_USER_DEBUGGER_PAUSE,
+ &PausePacket,
+ sizeof(DEBUGGEE_UD_PAUSED_PACKET),
+ TRUE);
+
+ //
+ // Set the thread debugging details
+ //
+ UdSetThreadPausingState(ThreadDebuggingDetails,
+ ProcessDebuggingDetails,
+ &PausePacket.InstructionBytesOnRip,
+ ExitInstructionLength);
+
+ //
+ // Everything was okay
+ //
+ return TRUE;
+}
diff --git a/hyperdbg/hprdbgkd/code/debugger/user-level/UserAccess.c b/hyperdbg/hyperkd/code/debugger/user-level/UserAccess.c
similarity index 98%
rename from hyperdbg/hprdbgkd/code/debugger/user-level/UserAccess.c
rename to hyperdbg/hyperkd/code/debugger/user-level/UserAccess.c
index 7ccfb9a6..ea97ce52 100644
--- a/hyperdbg/hprdbgkd/code/debugger/user-level/UserAccess.c
+++ b/hyperdbg/hyperkd/code/debugger/user-level/UserAccess.c
@@ -100,7 +100,7 @@ UserAccessAllocateAndGetImagePathFromProcessId(HANDLE ProcessId,
//
// Allocate a temporary buffer to store the path name
//
- Buffer = CrsAllocateZeroedNonPagedPool(ReturnedLength);
+ Buffer = PlatformMemAllocateZeroedNonPagedPool(ReturnedLength);
if (Buffer == NULL)
{
@@ -128,7 +128,7 @@ UserAccessAllocateAndGetImagePathFromProcessId(HANDLE ProcessId,
//
ProcessImageName->Length = 0;
ProcessImageName->MaximumLength = (USHORT)SizeOfImageNameToBeAllocated;
- ProcessImageName->Buffer = (PWSTR)CrsAllocateZeroedNonPagedPool(SizeOfImageNameToBeAllocated);
+ ProcessImageName->Buffer = (PWSTR)PlatformMemAllocateZeroedNonPagedPool(SizeOfImageNameToBeAllocated);
if (ProcessImageName->Buffer == NULL)
{
@@ -145,7 +145,7 @@ UserAccessAllocateAndGetImagePathFromProcessId(HANDLE ProcessId,
//
// Free the temp buffer which stored the path
//
- CrsFreePool(Buffer);
+ PlatformMemFreePool(Buffer);
return TRUE;
}
@@ -155,7 +155,7 @@ UserAccessAllocateAndGetImagePathFromProcessId(HANDLE ProcessId,
// There was an error in ZwQueryInformationProcess
// Free the temp buffer which stored the path
//
- CrsFreePool(Buffer);
+ PlatformMemFreePool(Buffer);
return FALSE;
}
}
@@ -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/hprdbgkd/code/driver/Driver.c b/hyperdbg/hyperkd/code/driver/Driver.c
similarity index 96%
rename from hyperdbg/hprdbgkd/code/driver/Driver.c
rename to hyperdbg/hyperkd/code/driver/Driver.c
index 2cbe2ecf..053eb828 100644
--- a/hyperdbg/hprdbgkd/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
new file mode 100644
index 00000000..ddd88593
--- /dev/null
+++ b/hyperdbg/hyperkd/code/driver/Ioctl.c
@@ -0,0 +1,1814 @@
+/**
+ * @file Ioctl.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief IOCTL Functions form user mode and other parts
+ * @details
+ *
+ * @version 0.1
+ * @date 2020-06-01
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @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 Irp
+ * @param IrpStack
+ * @param DoNotChangeInformation
+ * @return NTSTATUS
+ */
+NTSTATUS
+DrvDispatchBasicIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN * DoNotChangeInformation)
+{
+ 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;
+
+ 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;
+ PDEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS DebuggerPteRequest;
+ PDEBUGGER_PAGE_IN_REQUEST DebuggerPageinRequest;
+ PDEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET PcitreeRequest;
+ PDEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET PcidevinfoRequest;
+ PDEBUGGER_VA2PA_AND_PA2VA_COMMANDS DebuggerVa2paAndPa2vaRequest;
+ PDEBUGGER_EDIT_MEMORY DebuggerEditMemoryRequest;
+ PDEBUGGER_SEARCH_MEMORY DebuggerSearchMemoryRequest;
+ PDEBUGGER_GENERAL_EVENT_DETAIL DebuggerNewEventRequest;
+ PDEBUGGER_MODIFY_EVENTS DebuggerModifyEventRequest;
+ PDEBUGGER_FLUSH_LOGGING_BUFFERS DebuggerFlushBuffersRequest;
+ PDEBUGGER_PREALLOC_COMMAND DebuggerReservePreallocPoolRequest;
+ PDEBUGGER_PREACTIVATE_COMMAND DebuggerPreactivationRequest;
+ PDEBUGGER_APIC_REQUEST DebuggerApicRequest;
+ PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS DebuggerQueryIdtRequest;
+ PDEBUGGEE_BP_PACKET DebuggerBreakpointRequest;
+ PDEBUGGER_UD_COMMAND_PACKET DebuggerUdCommandRequest;
+ PUSERMODE_LOADED_MODULE_DETAILS DebuggerUsermodeModulesRequest;
+ PDEBUGGER_QUERY_ACTIVE_PROCESSES_OR_THREADS DebuggerUsermodeProcessOrThreadQueryRequest;
+ PDEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET GetInformationProcessRequest;
+ PREVERSING_MACHINE_RECONSTRUCT_MEMORY_REQUEST RevServiceRequest;
+ PDEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET GetInformationThreadRequest;
+ PDEBUGGER_PERFORM_KERNEL_TESTS DebuggerKernelTestRequest;
+ PDEBUGGER_SEND_COMMAND_EXECUTION_FINISHED_SIGNAL DebuggerCommandExecutionFinishedRequest;
+ PDEBUGGER_SEND_USERMODE_MESSAGES_TO_DEBUGGER DebuggerSendUsermodeMessageRequest;
+ PDEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER DebuggerSendBufferFromDebuggeeToDebuggerRequest;
+ PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS DebuggerAttachOrDetachToThreadRequest;
+ PDEBUGGER_PREPARE_DEBUGGEE DebuggeeRequest;
+ PDEBUGGER_PAUSE_PACKET_RECEIVED DebuggerPauseKernelRequest;
+ PDEBUGGER_GENERAL_ACTION DebuggerNewActionRequest;
+ PSMI_OPERATION_PACKETS SmiOperationRequest;
+ PVOID BufferToStoreThreadsAndProcessesDetails;
+ ULONG InBuffLength; // Input buffer length
+ ULONG OutBuffLength; // Output buffer length
+ SIZE_T ReturnSize;
+ 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 allocated as we're in PASSIVE_LEVEL
+ //
+ PoolManagerCheckAndPerformAllocationAndDeallocation();
+
+ //
+ // 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))
+ {
+ 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
+ {
+ Status = STATUS_NOT_IMPLEMENTED;
+ }
+
+ if (Status != STATUS_PENDING)
+ {
+ Irp->IoStatus.Status = Status;
+ if (!DoNotChangeInformation)
+ {
+ Irp->IoStatus.Information = 0;
+ }
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ }
+
+ return Status;
+}
diff --git a/hyperdbg/hyperkd/code/driver/Loader.c b/hyperdbg/hyperkd/code/driver/Loader.c
new file mode 100644
index 00000000..0ae0309d
--- /dev/null
+++ b/hyperdbg/hyperkd/code/driver/Loader.c
@@ -0,0 +1,451 @@
+/**
+ * @file Loader.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief The functions used in loading the debugger and VMM
+ * @version 0.2
+ * @date 2023-01-15
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief Initialize the hyper trace module
+ *
+ * @param RunningOnHypervisorEnvironment Whether the initialization is being done for hypervisor environment or not
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+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};
+
+ //
+ // *** Fill the callbacks for the message tracer ***
+ //
+ MsgTracingCallbacks.VmxOperationCheck = VmFuncVmxGetCurrentExecutionMode;
+ MsgTracingCallbacks.CheckImmediateMessageSending = KdCheckImmediateMessagingMechanism;
+ MsgTracingCallbacks.SendImmediateMessage = KdLoggingResponsePacketToDebugger;
+
+ //
+ // 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.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.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
+ //
+ VmmCallbacks.InterceptionCallbackTriggerCr3ProcessChange = ProcessTriggerCr3ProcessChange;
+
+ //
+ // Initialize VMX
+ //
+ if (VmFuncInitVmm(&VmmCallbacks))
+ {
+ LogDebugInfo("HyperDbg's hypervisor loaded successfully");
+
+ //
+ // Initialize VMM opeartions (event related state from the debugger)
+ //
+ if (!DebuggerInitializeVmmOperations())
+ {
+ return FALSE;
+ }
+
+ //
+ // VMM module initialized
+ //
+ g_VmmInitialized = TRUE;
+
+ return TRUE;
+ }
+ else
+ {
+ 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;
+ }
+
+ //
+ // The debugger is not initialized, so we try to initialize it
+ //
+ 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
+LoaderUninitLogTracer()
+{
+#if !UseDbgPrintInsteadOfUsermodeMessageTracking
+
+ LogDebugInfo("Unloading hyperlog...\n");
+
+ //
+ // Uinitialize log buffer if it was initialized
+ //
+ if (g_HyperLogInitialized)
+ {
+ g_HyperLogInitialized = FALSE;
+ LogUnInitialize();
+ }
+#endif
+}
diff --git a/hyperdbg/hprdbgkd/header/assembly/Assembly.h b/hyperdbg/hyperkd/header/assembly/Assembly.h
similarity index 61%
rename from hyperdbg/hprdbgkd/header/assembly/Assembly.h
rename to hyperdbg/hyperkd/header/assembly/Assembly.h
index 45f19848..f68e409e 100644
--- a/hyperdbg/hprdbgkd/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/hprdbgkd/header/common/Common.h b/hyperdbg/hyperkd/header/common/Common.h
similarity index 100%
rename from hyperdbg/hprdbgkd/header/common/Common.h
rename to hyperdbg/hyperkd/header/common/Common.h
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/hprdbgkd/header/debugger/broadcast/DpcRoutines.h b/hyperdbg/hyperkd/header/debugger/broadcast/DpcRoutines.h
similarity index 89%
rename from hyperdbg/hprdbgkd/header/debugger/broadcast/DpcRoutines.h
rename to hyperdbg/hyperkd/header/debugger/broadcast/DpcRoutines.h
index 0a300664..50e24308 100644
--- a/hyperdbg/hprdbgkd/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/hprdbgkd/header/debugger/broadcast/HaltedBroadcast.h b/hyperdbg/hyperkd/header/debugger/broadcast/HaltedBroadcast.h
similarity index 100%
rename from hyperdbg/hprdbgkd/header/debugger/broadcast/HaltedBroadcast.h
rename to hyperdbg/hyperkd/header/debugger/broadcast/HaltedBroadcast.h
diff --git a/hyperdbg/hprdbgkd/header/debugger/broadcast/HaltedRoutines.h b/hyperdbg/hyperkd/header/debugger/broadcast/HaltedRoutines.h
similarity index 100%
rename from hyperdbg/hprdbgkd/header/debugger/broadcast/HaltedRoutines.h
rename to hyperdbg/hyperkd/header/debugger/broadcast/HaltedRoutines.h
diff --git a/hyperdbg/hprdbgkd/header/debugger/commands/BreakpointCommands.h b/hyperdbg/hyperkd/header/debugger/commands/BreakpointCommands.h
similarity index 82%
rename from hyperdbg/hprdbgkd/header/debugger/commands/BreakpointCommands.h
rename to hyperdbg/hyperkd/header/debugger/commands/BreakpointCommands.h
index e001a1fa..9fc7c4b5 100644
--- a/hyperdbg/hprdbgkd/header/debugger/commands/BreakpointCommands.h
+++ b/hyperdbg/hyperkd/header/debugger/commands/BreakpointCommands.h
@@ -29,10 +29,11 @@ VOID
BreakpointRemoveAllBreakpoints();
BOOLEAN
-BreakpointAddNew(PDEBUGGEE_BP_PACKET BpDescriptorArg);
+BreakpointAddNew(PDEBUGGEE_BP_PACKET BpDescriptorArg, BOOLEAN SwitchToTargetMemoryLayout);
BOOLEAN
-BreakpointListOrModify(PDEBUGGEE_BP_LIST_OR_MODIFY_PACKET ListOrModifyBreakpoints);
+BreakpointListOrModify(PDEBUGGEE_BP_LIST_OR_MODIFY_PACKET ListOrModifyBreakpoints,
+ BOOLEAN SwitchToTargetMemoryLayout);
BOOLEAN
BreakpointHandleBreakpoints(UINT32 CoreId);
@@ -44,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/hprdbgkd/header/debugger/commands/Callstack.h b/hyperdbg/hyperkd/header/debugger/commands/Callstack.h
similarity index 90%
rename from hyperdbg/hprdbgkd/header/debugger/commands/Callstack.h
rename to hyperdbg/hyperkd/header/debugger/commands/Callstack.h
index 09dc52eb..960a16bb 100644
--- a/hyperdbg/hprdbgkd/header/debugger/commands/Callstack.h
+++ b/hyperdbg/hyperkd/header/debugger/commands/Callstack.h
@@ -17,6 +17,7 @@
BOOLEAN
CallstackWalkthroughStack(PDEBUGGER_SINGLE_CALLSTACK_FRAME AddressToSaveFrames,
+ UINT32 * FrameCount,
UINT64 StackBaseAddress,
UINT32 Size,
BOOLEAN Is32Bit);
diff --git a/hyperdbg/hprdbgkd/header/debugger/commands/DebuggerCommands.h b/hyperdbg/hyperkd/header/debugger/commands/DebuggerCommands.h
similarity index 93%
rename from hyperdbg/hprdbgkd/header/debugger/commands/DebuggerCommands.h
rename to hyperdbg/hyperkd/header/debugger/commands/DebuggerCommands.h
index 586756fe..c0043a3f 100644
--- a/hyperdbg/hprdbgkd/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/hprdbgkd/header/debugger/commands/ExtensionCommands.h b/hyperdbg/hyperkd/header/debugger/commands/ExtensionCommands.h
similarity index 81%
rename from hyperdbg/hprdbgkd/header/debugger/commands/ExtensionCommands.h
rename to hyperdbg/hyperkd/header/debugger/commands/ExtensionCommands.h
index c854408f..03e27dd9 100644
--- a/hyperdbg/hprdbgkd/header/debugger/commands/ExtensionCommands.h
+++ b/hyperdbg/hyperkd/header/debugger/commands/ExtensionCommands.h
@@ -18,6 +18,12 @@
BOOLEAN
ExtensionCommandPte(PDEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS PteDetails, BOOLEAN IsOperatingInVmxRoot);
+UINT32
+ExtensionCommandPerformActionsForApicRequests(PDEBUGGER_APIC_REQUEST ApicRequest);
+
+VOID
+ExtensionCommandPerformQueryIdtEntriesRequest(PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS IdtQueryRequest, BOOLEAN ReadFromVmxRoot);
+
VOID
ExtensionCommandVa2paAndPa2va(PDEBUGGER_VA2PA_AND_PA2VA_COMMANDS AddressDetails, BOOLEAN OperateOnVmxRoot);
@@ -83,3 +89,9 @@ ExtensionCommandEnableMovControlRegisterExitingAllCores(PDEBUGGER_EVENT Event);
VOID
ExtensionCommandDisableMov2ControlRegsExitingForClearingEventsAllCores(PDEBUGGER_EVENT Event);
+
+VOID
+ExtensionCommandPcitree(PDEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET PcitreePacket, BOOLEAN OperateOnVmxRoot);
+
+VOID
+ExtensionCommandPcidevinfo(PDEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET PcidevinfoPacket, BOOLEAN OperateOnVmxRoot);
diff --git a/hyperdbg/hprdbgkd/header/debugger/communication/SerialConnection.h b/hyperdbg/hyperkd/header/debugger/communication/SerialConnection.h
similarity index 100%
rename from hyperdbg/hprdbgkd/header/debugger/communication/SerialConnection.h
rename to hyperdbg/hyperkd/header/debugger/communication/SerialConnection.h
diff --git a/hyperdbg/hprdbgkd/header/debugger/core/Debugger.h b/hyperdbg/hyperkd/header/debugger/core/Debugger.h
similarity index 97%
rename from hyperdbg/hprdbgkd/header/debugger/core/Debugger.h
rename to hyperdbg/hyperkd/header/debugger/core/Debugger.h
index c9bada08..3553e20a 100644
--- a/hyperdbg/hprdbgkd/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/hprdbgkd/header/debugger/core/DebuggerVmcalls.h b/hyperdbg/hyperkd/header/debugger/core/DebuggerVmcalls.h
similarity index 100%
rename from hyperdbg/hprdbgkd/header/debugger/core/DebuggerVmcalls.h
rename to hyperdbg/hyperkd/header/debugger/core/DebuggerVmcalls.h
diff --git a/hyperdbg/hprdbgkd/header/debugger/core/HaltedCore.h b/hyperdbg/hyperkd/header/debugger/core/HaltedCore.h
similarity index 100%
rename from hyperdbg/hprdbgkd/header/debugger/core/HaltedCore.h
rename to hyperdbg/hyperkd/header/debugger/core/HaltedCore.h
diff --git a/hyperdbg/hprdbgkd/header/debugger/core/State.h b/hyperdbg/hyperkd/header/debugger/core/State.h
similarity index 92%
rename from hyperdbg/hprdbgkd/header/debugger/core/State.h
rename to hyperdbg/hyperkd/header/debugger/core/State.h
index 77fe102e..7a41c1a0 100644
--- a/hyperdbg/hprdbgkd/header/debugger/core/State.h
+++ b/hyperdbg/hyperkd/header/debugger/core/State.h
@@ -80,7 +80,6 @@ typedef struct _DEBUGGEE_BP_DESCRIPTOR
UINT32 Core;
UINT16 InstructionLength;
BYTE PreviousByte;
- BOOLEAN SetRflagsIFBitOnMtf;
BOOLEAN AvoidReApplyBreakpoint;
BOOLEAN RemoveAfterHit;
BOOLEAN CheckForCallbacks;
@@ -106,7 +105,7 @@ typedef struct _DEBUGGER_PROCESS_THREAD_INFORMATION
{
union
{
- UINT64 asUInt;
+ UINT64 AsUInt;
struct
{
@@ -143,6 +142,18 @@ typedef struct _DEBUGGEE_HALTED_CORE_TASK
} DEBUGGEE_HALTED_CORE_TASK, *PDEBUGGEE_HALTED_CORE_TASK;
+/**
+ * @brief Timer for the core
+ *
+ */
+typedef struct _DATE_TIME_HOLDER
+{
+ TIME_FIELDS TimeFields;
+ CHAR TimeBuffer[14];
+ CHAR DateBuffer[12];
+
+} DATE_TIME_HOLDER, *PDATE_TIME_HOLDER;
+
/**
* @brief Saves the debugger state
* @details Each logical processor contains one of this structure which describes about the
@@ -157,19 +168,20 @@ typedef struct _PROCESSOR_DEBUGGING_STATE
UINT32 CoreId;
BOOLEAN ShortCircuitingEvent;
BOOLEAN IgnoreDisasmInNextPacket;
- PROCESSOR_DEBUGGING_MSR_READ_OR_WRITE MsrState;
- PDEBUGGEE_BP_DESCRIPTOR SoftwareBreakpointState;
- DEBUGGEE_INSTRUMENTATION_STEP_IN_TRACE InstrumentationStepInTrace;
+ 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;
DEBUGGEE_PROCESS_OR_THREAD_TRACING_DETAILS ThreadOrProcessTracingDetails;
KD_NMI_STATE NmiState;
DEBUGGEE_HALTED_CORE_TASK HaltedCoreTask;
- BOOLEAN BreakStarterCore;
UINT16 InstructionLengthHint;
UINT64 HardwareDebugRegisterForStepping;
- UINT64 * ScriptEngineCoreSpecificLocalVariable;
- UINT64 * ScriptEngineCoreSpecificTempVariable;
+ UINT64 * ScriptEngineCoreSpecificStackBuffer;
PKDPC KdDpcObject; // DPC object to be used in kernel debugger
CHAR KdRecvBuffer[MaxSerialPacketSize]; // Used for debugging buffers (receiving buffers from serial devices)
diff --git a/hyperdbg/hprdbgkd/header/debugger/events/ApplyEvents.h b/hyperdbg/hyperkd/header/debugger/events/ApplyEvents.h
similarity index 95%
rename from hyperdbg/hprdbgkd/header/debugger/events/ApplyEvents.h
rename to hyperdbg/hyperkd/header/debugger/events/ApplyEvents.h
index 17238173..bde54526 100644
--- a/hyperdbg/hprdbgkd/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/hprdbgkd/header/debugger/events/DebuggerEvents.h b/hyperdbg/hyperkd/header/debugger/events/DebuggerEvents.h
similarity index 100%
rename from hyperdbg/hprdbgkd/header/debugger/events/DebuggerEvents.h
rename to hyperdbg/hyperkd/header/debugger/events/DebuggerEvents.h
diff --git a/hyperdbg/hprdbgkd/header/debugger/events/Termination.h b/hyperdbg/hyperkd/header/debugger/events/Termination.h
similarity index 92%
rename from hyperdbg/hprdbgkd/header/debugger/events/Termination.h
rename to hyperdbg/hyperkd/header/debugger/events/Termination.h
index 663b5922..3e240938 100644
--- a/hyperdbg/hprdbgkd/header/debugger/events/Termination.h
+++ b/hyperdbg/hyperkd/header/debugger/events/Termination.h
@@ -74,8 +74,14 @@ BOOLEAN
TerminateEptHookUnHookSingleAddressFromVmxRootAndApplyInvalidation(UINT64 VirtualAddress,
UINT64 PhysAddress);
+BOOLEAN
+TerminateEptHookUnHookAllHooksByHookingTagFromVmxRootAndApplyInvalidation(UINT64 HookingTag);
+
BOOLEAN
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/hprdbgkd/header/debugger/events/ValidateEvents.h b/hyperdbg/hyperkd/header/debugger/events/ValidateEvents.h
similarity index 100%
rename from hyperdbg/hprdbgkd/header/debugger/events/ValidateEvents.h
rename to hyperdbg/hyperkd/header/debugger/events/ValidateEvents.h
diff --git a/hyperdbg/hprdbgkd/header/debugger/kernel-level/Kd.h b/hyperdbg/hyperkd/header/debugger/kernel-level/Kd.h
similarity index 91%
rename from hyperdbg/hprdbgkd/header/debugger/kernel-level/Kd.h
rename to hyperdbg/hyperkd/header/debugger/kernel-level/Kd.h
index 991eef82..bf98f656 100644
--- a/hyperdbg/hprdbgkd/header/debugger/kernel-level/Kd.h
+++ b/hyperdbg/hyperkd/header/debugger/kernel-level/Kd.h
@@ -113,14 +113,8 @@ 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, UINT32 NewCore);
+KdSwitchCore(PROCESSOR_DEBUGGING_STATE * DbgState,
+ DEBUGGEE_CHANGE_CORE_PACKET * ChangeCorePacket);
static VOID
KdCloseConnectionAndUnloadDebuggee();
@@ -134,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);
@@ -151,6 +139,12 @@ KdPerformAddActionToEvent(PDEBUGGEE_EVENT_AND_ACTION_HEADER_FOR_REMOTE_PACKET Ac
static VOID
KdQuerySystemState();
+static BOOLEAN
+KdCheckAllCoresAreLocked();
+
+static BOOLEAN
+KdCheckTargetCoreIsLocked(UINT32 CoreNumber);
+
static BOOLEAN
KdPerformEventQueryAndModification(PDEBUGGER_MODIFY_EVENTS ModifyAndQueryEvent);
@@ -173,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);
@@ -203,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);
@@ -241,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/hprdbgkd/header/debugger/memory/Allocations.h b/hyperdbg/hyperkd/header/debugger/memory/Allocations.h
similarity index 100%
rename from hyperdbg/hprdbgkd/header/debugger/memory/Allocations.h
rename to hyperdbg/hyperkd/header/debugger/memory/Allocations.h
diff --git a/hyperdbg/hprdbgkd/header/debugger/memory/Memory.h b/hyperdbg/hyperkd/header/debugger/memory/Memory.h
similarity index 100%
rename from hyperdbg/hprdbgkd/header/debugger/memory/Memory.h
rename to hyperdbg/hyperkd/header/debugger/memory/Memory.h
diff --git a/hyperdbg/hprdbghv/header/memory/PoolManager.h b/hyperdbg/hyperkd/header/debugger/memory/PoolManager.h
similarity index 86%
rename from hyperdbg/hprdbghv/header/memory/PoolManager.h
rename to hyperdbg/hyperkd/header/debugger/memory/PoolManager.h
index 5c5dbc7b..ef4af344 100644
--- a/hyperdbg/hprdbghv/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/hprdbgkd/header/debugger/meta-events/MetaDispatch.h b/hyperdbg/hyperkd/header/debugger/meta-events/MetaDispatch.h
similarity index 100%
rename from hyperdbg/hprdbgkd/header/debugger/meta-events/MetaDispatch.h
rename to hyperdbg/hyperkd/header/debugger/meta-events/MetaDispatch.h
diff --git a/hyperdbg/hprdbgkd/header/debugger/meta-events/Tracing.h b/hyperdbg/hyperkd/header/debugger/meta-events/Tracing.h
similarity index 89%
rename from hyperdbg/hprdbgkd/header/debugger/meta-events/Tracing.h
rename to hyperdbg/hyperkd/header/debugger/meta-events/Tracing.h
index 42eb7fb1..f444fdb8 100644
--- a/hyperdbg/hprdbgkd/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/hprdbgkd/header/debugger/objects/Process.h b/hyperdbg/hyperkd/header/debugger/objects/Process.h
similarity index 100%
rename from hyperdbg/hprdbgkd/header/debugger/objects/Process.h
rename to hyperdbg/hyperkd/header/debugger/objects/Process.h
diff --git a/hyperdbg/hprdbgkd/header/debugger/objects/Thread.h b/hyperdbg/hyperkd/header/debugger/objects/Thread.h
similarity index 94%
rename from hyperdbg/hprdbgkd/header/debugger/objects/Thread.h
rename to hyperdbg/hyperkd/header/debugger/objects/Thread.h
index 1133e68d..b68e6fc9 100644
--- a/hyperdbg/hprdbgkd/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/hprdbgkd/header/debugger/script-engine/ScriptEngine.h b/hyperdbg/hyperkd/header/debugger/script-engine/ScriptEngine.h
similarity index 73%
rename from hyperdbg/hprdbgkd/header/debugger/script-engine/ScriptEngine.h
rename to hyperdbg/hyperkd/header/debugger/script-engine/ScriptEngine.h
index 5d6626e2..7a6d065b 100644
--- a/hyperdbg/hprdbgkd/header/debugger/script-engine/ScriptEngine.h
+++ b/hyperdbg/hyperkd/header/debugger/script-engine/ScriptEngine.h
@@ -17,3 +17,12 @@ ScriptEngineWrapperGetInstructionPointer();
UINT64
ScriptEngineWrapperGetAddressOfReservedBuffer(PDEBUGGER_EVENT_ACTION Action);
+
+VOID
+ScriptEngineUpdateTargetCoreDateTime(PROCESSOR_DEBUGGING_STATE * DbgState);
+
+UINT64
+ScriptEngineGetTargetCoreTime();
+
+UINT64
+ScriptEngineGetTargetCoreDate();
diff --git a/hyperdbg/hprdbgkd/header/debugger/tests/KernelTests.h b/hyperdbg/hyperkd/header/debugger/tests/KernelTests.h
similarity index 83%
rename from hyperdbg/hprdbgkd/header/debugger/tests/KernelTests.h
rename to hyperdbg/hyperkd/header/debugger/tests/KernelTests.h
index 9c127634..ae28ea45 100644
--- a/hyperdbg/hprdbgkd/header/debugger/tests/KernelTests.h
+++ b/hyperdbg/hyperkd/header/debugger/tests/KernelTests.h
@@ -17,6 +17,3 @@
VOID
TestKernelPerformTests(PDEBUGGER_PERFORM_KERNEL_TESTS KernelTestRequest);
-
-UINT32
-TestKernelGetInformation(PDEBUGGEE_KERNEL_AND_USER_TEST_INFORMATION InfoRequest);
diff --git a/hyperdbg/hyperkd/header/debugger/user-level/Attaching.h b/hyperdbg/hyperkd/header/debugger/user-level/Attaching.h
new file mode 100644
index 00000000..465de531
--- /dev/null
+++ b/hyperdbg/hyperkd/header/debugger/user-level/Attaching.h
@@ -0,0 +1,68 @@
+/**
+ * @file Attaching.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Header for attaching and detaching for debugging user-mode processes
+ * @details
+ * @version 0.1
+ * @date 2021-12-28
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Constants //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Maximum actions in paused threads storage
+ *
+ */
+#define MAX_USER_ACTIONS_FOR_THREADS 3
+
+/**
+ * @brief Maximum threads that a process thread holder might have
+ *
+ */
+#define MAX_THREADS_IN_A_PROCESS_HOLDER 100
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+BOOLEAN
+AttachingInitialize();
+
+BOOLEAN
+AttachingCheckThreadInterceptionWithUserDebugger(UINT32 CoreId);
+
+BOOLEAN
+AttachingConfigureInterceptingThreads(UINT64 ProcessDebuggingToken, BOOLEAN Enable);
+
+VOID
+AttachingTargetProcess(PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS Request);
+
+VOID
+AttachingHandleEntrypointInterception(PROCESSOR_DEBUGGING_STATE * DbgState);
+
+VOID
+AttachingRemoveAndFreeAllProcessDebuggingDetails();
+
+PUSERMODE_DEBUGGING_PROCESS_DETAILS
+AttachingFindProcessDebuggingDetailsByToken(UINT64 Token);
+
+PUSERMODE_DEBUGGING_PROCESS_DETAILS
+AttachingFindProcessDebuggingDetailsByProcessId(UINT32 ProcessId);
+
+BOOLEAN
+AttachingQueryDetailsOfActiveDebuggingThreadsAndProcesses(PVOID BufferToStoreDetails, UINT32 BufferSize);
+
+BOOLEAN
+AttachingCheckUnhandledEptViolation(UINT32 CoreId,
+ UINT64 ViolationQualification,
+ UINT64 GuestPhysicalAddr);
+
+BOOLEAN
+AttachingReachedToValidLoadedModule(PROCESSOR_DEBUGGING_STATE * DbgState,
+ PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail);
diff --git a/hyperdbg/hprdbgkd/header/debugger/user-level/ThreadHolder.h b/hyperdbg/hyperkd/header/debugger/user-level/ThreadHolder.h
similarity index 90%
rename from hyperdbg/hprdbgkd/header/debugger/user-level/ThreadHolder.h
rename to hyperdbg/hyperkd/header/debugger/user-level/ThreadHolder.h
index f0ddd9af..7b59f644 100644
--- a/hyperdbg/hprdbgkd/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;
@@ -62,6 +65,9 @@ ThreadHolderAssignThreadHolderToProcessDebuggingDetails(PUSERMODE_DEBUGGING_PROC
BOOLEAN
ThreadHolderIsAnyPausedThreadInProcess(PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail);
+BOOLEAN
+ThreadHolderUnpauseAllThreadsInProcess(PUSERMODE_DEBUGGING_PROCESS_DETAILS ProcessDebuggingDetail);
+
PUSERMODE_DEBUGGING_THREAD_DETAILS
ThreadHolderGetProcessThreadDetailsByProcessIdAndThreadId(UINT32 ProcessId, UINT32 ThreadId);
diff --git a/hyperdbg/hyperkd/header/debugger/user-level/Ud.h b/hyperdbg/hyperkd/header/debugger/user-level/Ud.h
new file mode 100644
index 00000000..b9134e0f
--- /dev/null
+++ b/hyperdbg/hyperkd/header/debugger/user-level/Ud.h
@@ -0,0 +1,81 @@
+/**
+ * @file Ud.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Header for routines related to user mode debugging
+ * @details
+ * @version 0.1
+ * @date 2022-01-06
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Structures //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Description of each active thread in user-mode attaching
+ * mechanism
+ *
+ */
+typedef struct _USERMODE_DEBUGGING_PROCESS_DETAILS
+{
+ UINT64 Token;
+ BOOLEAN Enabled;
+ PVOID PebAddressToMonitor;
+ UINT32 ActiveThreadId; // active thread
+ GUEST_REGS Registers; // active thread
+ UINT64 Context; // $context
+ LIST_ENTRY AttachedProcessList;
+ UINT64 EntrypointOfMainModule;
+ UINT64 BaseAddressOfMainModule;
+ PEPROCESS Eprocess;
+ UINT32 ProcessId;
+ BOOLEAN Is32Bit;
+ BOOLEAN IsOnTheStartingPhase;
+ BOOLEAN IsOnThreadInterceptingPhase;
+ BOOLEAN CheckCallBackForInterceptingFirstInstruction; // checks for the callbacks for interceptions of the very first instruction (used by RE Machine)
+ LIST_ENTRY ThreadsListHead;
+
+} USERMODE_DEBUGGING_PROCESS_DETAILS, *PUSERMODE_DEBUGGING_PROCESS_DETAILS;
+
+//////////////////////////////////////////////////
+// Functions //
+//////////////////////////////////////////////////
+
+BOOLEAN
+UdInitializeUserDebugger();
+
+VOID
+UdUninitializeUserDebugger();
+
+BOOLEAN
+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,
+ UINT32 ActionRequestInputLength,
+ UINT32 ActionRequestOutputLength);
+
+BOOLEAN
+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/hprdbgkd/header/debugger/user-level/UserAccess.h b/hyperdbg/hyperkd/header/debugger/user-level/UserAccess.h
similarity index 99%
rename from hyperdbg/hprdbgkd/header/debugger/user-level/UserAccess.h
rename to hyperdbg/hyperkd/header/debugger/user-level/UserAccess.h
index cb2c8c40..4acb1b8e 100644
--- a/hyperdbg/hprdbgkd/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/hprdbgkd/header/driver/Driver.h b/hyperdbg/hyperkd/header/driver/Driver.h
similarity index 68%
rename from hyperdbg/hprdbgkd/header/driver/Driver.h
rename to hyperdbg/hyperkd/header/driver/Driver.h
index b5739220..e3233b0b 100644
--- a/hyperdbg/hprdbgkd/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/hprdbgkd/header/driver/Loader.h b/hyperdbg/hyperkd/header/driver/Loader.h
similarity index 57%
rename from hyperdbg/hprdbgkd/header/driver/Loader.h
rename to hyperdbg/hyperkd/header/driver/Loader.h
index 955231cf..6d34e67d 100644
--- a/hyperdbg/hprdbgkd/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/hprdbgkd/header/globals/Global.h b/hyperdbg/hyperkd/header/globals/Global.h
similarity index 74%
rename from hyperdbg/hprdbgkd/header/globals/Global.h
rename to hyperdbg/hyperkd/header/globals/Global.h
index 4d5828c8..02195709 100644
--- a/hyperdbg/hprdbgkd/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
@@ -151,33 +199,6 @@ BOOLEAN g_IsWaitingForReturnAndRunFromPageFault;
*/
LIST_ENTRY g_ProcessDebuggingDetailsListHead;
-/**
- * @brief Target function for kernel tests
- *
- */
-PVOID g_KernelTestTargetFunction;
-
-/**
- * @brief Tag1 for kernel tests
- *
- */
-UINT64 g_KernelTestTag1;
-
-/**
- * @brief Tag2 for kernel tests
- *
- */
-UINT64 g_KernelTestTag2;
-
-/**
- * @brief Temp registers for kernel tests
- *
- */
-UINT64 g_KernelTestR15;
-UINT64 g_KernelTestR14;
-UINT64 g_KernelTestR13;
-UINT64 g_KernelTestR12;
-
/**
* @brief Whether the thread attaching mechanism is waiting for #DB or not
*
@@ -191,3 +212,9 @@ BOOLEAN g_IsWaitingForUserModeProcessEntryToBeCalled;
*
*/
BOOLEAN g_InterceptBreakpointsAndEventsForCommandsInRemoteComputer;
+
+/**
+ * @brief Global test flag (for testing purposes)
+ *
+ */
+BOOLEAN g_TestFlag;
diff --git a/hyperdbg/hprdbgkd/header/pch.h b/hyperdbg/hyperkd/header/pch.h
similarity index 74%
rename from hyperdbg/hprdbgkd/header/pch.h
rename to hyperdbg/hyperkd/header/pch.h
index 638be9f6..630ee6b9 100644
--- a/hyperdbg/hprdbgkd/header/pch.h
+++ b/hyperdbg/hyperkd/header/pch.h
@@ -19,15 +19,21 @@
#define HYPERDBG_DEBUGGER
#define SCRIPT_ENGINE_KERNEL_MODE
+//
+// Environment headers
+//
+#include "platform/general/header/Environment.h"
+
+#ifdef HYPERDBG_ENV_WINDOWS
+
//
// General WDK headers
//
-#include
-#include
-#include
-#include
-#include
-#include
+# include
+# include
+# include
+
+#endif // HYPERDBG_ENV_WINDOWS
//
// Definition of Intel primitives (External header)
@@ -37,8 +43,8 @@
//
// Import Configuration and Definitions
//
-#include "Configuration.h"
-#include "Definition.h"
+#include "config/Configuration.h"
+#include "config/Definition.h"
//
// Macros
@@ -53,15 +59,15 @@
//
// Import HyperLog Module
//
-#include "SDK/Modules/HyperLog.h"
-#include "SDK/Imports/HyperDbgHyperLogImports.h"
-#include "SDK/Imports/HyperDbgHyperLogIntrinsics.h"
+#include "SDK/modules/HyperLog.h"
+#include "SDK/imports/kernel/HyperDbgHyperLogImports.h"
+#include "SDK/imports/kernel/HyperDbgHyperLogIntrinsics.h"
//
// Import VMM Module
//
-#include "SDK/Modules/VMM.h"
-#include "SDK/Imports/HyperDbgVmmImports.h"
+#include "SDK/modules/VMM.h"
+#include "SDK/imports/kernel/HyperDbgVmmImports.h"
//
// Local Debugger headers
@@ -75,6 +81,15 @@
//
#include "components/spinlock/header/Spinlock.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/PlatformProcess.h"
+#include "platform/kernel/header/PlatformCpu.h"
+
//
// Optimization algorithms
//
@@ -99,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"
@@ -122,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
//
@@ -140,9 +152,14 @@
//
// Script engine headers
//
-#include "../script-eval/header/ScriptEngineCommonDefinitions.h"
#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/hprdbgkd/hprdbgkd.vcxproj b/hyperdbg/hyperkd/hyperkd.vcxproj
similarity index 69%
rename from hyperdbg/hprdbgkd/hprdbgkd.vcxproj
rename to hyperdbg/hyperkd/hyperkd.vcxproj
index f1057228..b165f75d 100644
--- a/hyperdbg/hprdbgkd/hprdbgkd.vcxproj
+++ b/hyperdbg/hyperkd/hyperkd.vcxproj
@@ -1,5 +1,8 @@
+
+
+ debug
@@ -17,7 +20,7 @@
12.0Debugx64
- hprdbgkd
+ hyperkd$(LatestTargetPlatformVersion)
@@ -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
@@ -71,11 +77,12 @@
trueCreatepch.h
+ stdcpp20trueDriverEntry
- $(SolutionDir)build\bin\$(Configuration)\hyperlog.lib;$(SolutionDir)build\bin\$(Configuration)\hprdbghv.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)
@@ -89,11 +96,13 @@
trueCreatepch.h
+ stdcpp20
+ FulltrueDriverEntry
- $(SolutionDir)build\bin\$(Configuration)\hyperlog.lib;$(SolutionDir)build\bin\$(Configuration)\hprdbghv.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)
@@ -105,12 +114,18 @@
+
+
+
+
+
+
@@ -128,6 +143,7 @@
+
@@ -149,9 +165,14 @@
+
+
+
+
+
-
+
@@ -171,6 +192,7 @@
+
@@ -188,9 +210,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/hprdbgkd/hprdbgkd.vcxproj.filters b/hyperdbg/hyperkd/hyperkd.vcxproj.filters
similarity index 89%
rename from hyperdbg/hprdbgkd/hprdbgkd.vcxproj.filters
rename to hyperdbg/hyperkd/hyperkd.vcxproj.filters
index 4ad2e780..8a1a1c5b 100644
--- a/hyperdbg/hprdbgkd/hprdbgkd.vcxproj.filters
+++ b/hyperdbg/hyperkd/hyperkd.vcxproj.filters
@@ -130,6 +130,12 @@
{f308a8ae-1e28-465b-ae2f-4d307fa48177}
+
+ {63a2a7a9-943a-43a6-9c81-4831088d3628}
+
+
+ {49d6a936-9fcf-4c74-af16-445b1b3625d2}
+
@@ -255,6 +261,27 @@
code\debugger\meta-events
+
+ code\platform
+
+
+ code\common
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\debugger\memory
+
@@ -338,9 +365,6 @@
header\macros
-
- header\common
- header\assembly
@@ -383,13 +407,34 @@
header\debugger\meta-events
+
+ header\platform
+
+
+ header\common
+
+
+ header\platform
+
+
+ header\platform
+
+
+ header\platform
+
+
+ header\platform
+
+
+ header\debugger\memory
+
-
- code\assembly
- 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
new file mode 100644
index 00000000..d6e772a5
--- /dev/null
+++ b/hyperdbg/hyperlog/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"
+ "hyperlog.def"
+)
+include_directories(
+ "../include"
+ "header"
+)
+wdk_add_library(hyperlog SHARED
+ KMDF 1.15
+ ${SourceFiles}
+)
diff --git a/hyperdbg/hyperlog/code/Logging.c b/hyperdbg/hyperlog/code/Logging.c
index 66020e2e..1cc3111f 100644
--- a/hyperdbg/hyperlog/code/Logging.c
+++ b/hyperdbg/hyperlog/code/Logging.c
@@ -9,18 +9,7 @@
* @copyright This project is released under the GNU Public License v3.
*
*/
-#include
-#include
-#include
-
-#define HYPERDBG_KERNEL_MODE
-#define HYPERDBG_HYPER_LOG
-
-#include "SDK/HyperDbgSdk.h"
-#include "SDK/Modules/HyperLog.h"
-#include "SDK/Imports/HyperDbgHyperLogImports.h"
-#include "components/spinlock/header/Spinlock.h"
-#include "Logging.h"
+#include "pch.h"
/**
* @brief Checks whether the message tracing operates on vmx-root mode or not
@@ -110,47 +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 = ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(LOG_BUFFER_INFORMATION) * 2, POOLTAG);
+ g_MessageBufferInformation = PlatformMemAllocateZeroedNonPagedPool(sizeof(LOG_BUFFER_INFORMATION) * 2);
- if (!MessageBufferInformation)
+ if (!g_MessageBufferInformation)
{
return FALSE; // STATUS_INSUFFICIENT_RESOURCES
}
//
- // Zeroing the memory
+ // Allocate g_VmxTempMessage and g_VmxLogMessage
//
- RtlZeroMemory(MessageBufferInformation, sizeof(LOG_BUFFER_INFORMATION) * 2);
+ g_VmxTempMessage = NULL;
+ g_VmxTempMessage = PlatformMemAllocateZeroedNonPagedPool(PacketChunkSize * ProcessorsCount);
- //
- // Allocate VmxTempMessage and VmxLogMessage
- //
- VmxTempMessage = NULL;
- VmxTempMessage = ExAllocatePool2(POOL_FLAG_NON_PAGED, PacketChunkSize * ProcessorsCount, POOLTAG);
-
- if (!VmxTempMessage)
+ if (!g_VmxTempMessage)
{
- ExFreePoolWithTag(MessageBufferInformation, POOLTAG);
- MessageBufferInformation = NULL;
+ PlatformMemFreePool(g_MessageBufferInformation);
+ g_MessageBufferInformation = NULL;
return FALSE; // STATUS_INSUFFICIENT_RESOURCES
}
- VmxLogMessage = NULL;
- VmxLogMessage = ExAllocatePool2(POOL_FLAG_NON_PAGED, PacketChunkSize * ProcessorsCount, POOLTAG);
+ g_VmxLogMessage = NULL;
+ g_VmxLogMessage = PlatformMemAllocateZeroedNonPagedPool(PacketChunkSize * ProcessorsCount);
- if (!VmxLogMessage)
+ if (!g_VmxLogMessage)
{
- ExFreePoolWithTag(MessageBufferInformation, POOLTAG);
- MessageBufferInformation = NULL;
+ PlatformMemFreePool(g_MessageBufferInformation);
+ g_MessageBufferInformation = NULL;
- ExFreePoolWithTag(VmxTempMessage, POOLTAG);
- VmxTempMessage = NULL;
+ PlatformMemFreePool(g_VmxTempMessage);
+ g_VmxTempMessage = NULL;
return FALSE; // STATUS_INSUFFICIENT_RESOURCES
}
@@ -158,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
@@ -171,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)ExAllocatePool2(POOL_FLAG_NON_PAGED, LogBufferSize, POOLTAG);
- MessageBufferInformation[i].BufferForMultipleNonImmediateMessage = (UINT64)ExAllocatePool2(POOL_FLAG_NON_PAGED, PacketChunkSize, POOLTAG);
+ 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
}
@@ -189,9 +173,9 @@ LogInitialize(MESSAGE_TRACING_CALLBACKS * MsgTracingCallbacks)
//
// allocate the buffer for priority buffers
//
- MessageBufferInformation[i].BufferStartAddressPriority = (UINT64)ExAllocatePool2(POOL_FLAG_NON_PAGED, LogBufferSizePriority, POOLTAG);
+ g_MessageBufferInformation[i].BufferStartAddressPriority = (UINT64)PlatformMemAllocateNonPagedPool(LogBufferSizePriority);
- if (!MessageBufferInformation[i].BufferStartAddressPriority)
+ if (!g_MessageBufferInformation[i].BufferStartAddressPriority)
{
return FALSE; // STATUS_INSUFFICIENT_RESOURCES
}
@@ -199,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;
}
@@ -231,30 +215,41 @@ LogUnInitialize()
//
for (int i = 0; i < 2; i++)
{
+ //
+ // Check if the buffer is allocated or not
+ //
+ if (g_MessageBufferInformation == NULL64_ZERO)
+ {
+ continue; // No need to free the buffers
+ }
+
//
// Free each buffers
//
- if (MessageBufferInformation[i].BufferStartAddress != NULL64_ZERO)
+ if (g_MessageBufferInformation[i].BufferStartAddress != NULL64_ZERO)
{
- ExFreePoolWithTag((PVOID)MessageBufferInformation[i].BufferStartAddress, POOLTAG);
+ PlatformMemFreePool((PVOID)g_MessageBufferInformation[i].BufferStartAddress);
}
- if (MessageBufferInformation[i].BufferStartAddressPriority != NULL64_ZERO)
+ if (g_MessageBufferInformation[i].BufferStartAddressPriority != NULL64_ZERO)
{
- ExFreePoolWithTag((PVOID)MessageBufferInformation[i].BufferStartAddressPriority, POOLTAG);
+ PlatformMemFreePool((PVOID)g_MessageBufferInformation[i].BufferStartAddressPriority);
}
- if (MessageBufferInformation[i].BufferForMultipleNonImmediateMessage != NULL64_ZERO)
+ if (g_MessageBufferInformation[i].BufferForMultipleNonImmediateMessage != NULL64_ZERO)
{
- ExFreePoolWithTag((PVOID)MessageBufferInformation[i].BufferForMultipleNonImmediateMessage, POOLTAG);
+ PlatformMemFreePool((PVOID)g_MessageBufferInformation[i].BufferForMultipleNonImmediateMessage);
}
}
//
- // de-allocate buffers for trace message and data messages
+ // de-allocate buffers for trace message and data messages if they are allocated
//
- ExFreePoolWithTag((PVOID)MessageBufferInformation, POOLTAG);
- MessageBufferInformation = NULL;
+ if (g_MessageBufferInformation != NULL64_ZERO)
+ {
+ PlatformMemFreePool((PVOID)g_MessageBufferInformation);
+ g_MessageBufferInformation = NULL;
+ }
}
/**
@@ -296,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
@@ -308,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
@@ -326,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))));
}
//
@@ -389,7 +384,7 @@ LogCallbackSendBuffer(UINT32 OperationCode, PVOID Buffer, UINT32 BufferLength, B
//
// vmx non-root
//
- OldIRQL = KeRaiseIrqlToDpcLevel();
+ OldIRQL = PlatformIrqlRaiseToDpcLevel();
}
//
@@ -408,7 +403,7 @@ LogCallbackSendBuffer(UINT32 OperationCode, PVOID Buffer, UINT32 BufferLength, B
//
// vmx non-root
//
- KeLowerIrql(OldIRQL);
+ PlatformIrqlLower(OldIRQL);
}
return TRUE;
@@ -424,7 +419,7 @@ LogCallbackSendBuffer(UINT32 OperationCode, PVOID Buffer, UINT32 BufferLength, B
// Set the index
//
Index = 1;
- SpinlockLock(&VmxRootLoggingLock);
+ SpinlockLock(&g_VmxRootLoggingLock);
}
else
{
@@ -436,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);
}
//
@@ -444,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;
}
}
@@ -470,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))));
}
//
@@ -495,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;
}
//
@@ -536,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
@@ -550,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;
@@ -591,7 +586,7 @@ LogMarkAllAsRead(BOOLEAN IsVmxRoot)
//
// Acquire the lock
//
- SpinlockLock(&VmxRootLoggingLock);
+ SpinlockLock(&g_VmxRootLoggingLock);
}
else
{
@@ -603,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)
@@ -630,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;
@@ -651,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
@@ -663,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;
}
}
@@ -687,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;
@@ -730,7 +725,7 @@ LogReadBuffer(BOOLEAN IsVmxRoot, PVOID BufferToSaveMessage, UINT32 * ReturnedLen
//
// Acquire the lock
//
- SpinlockLock(&VmxRootLoggingLock);
+ SpinlockLock(&g_VmxRootLoggingLock);
}
else
{
@@ -742,7 +737,7 @@ LogReadBuffer(BOOLEAN IsVmxRoot, PVOID BufferToSaveMessage, UINT32 * ReturnedLen
//
// Acquire the lock
//
- KeAcquireSpinLock(&MessageBufferInformation[Index].BufferLock, &OldIRQL);
+ PlatformSpinlockAcquire(&g_MessageBufferInformation[Index].BufferLock, &OldIRQL);
}
//
@@ -753,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)
{
@@ -774,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;
@@ -799,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
@@ -808,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));
}
//
@@ -820,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
@@ -835,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
@@ -869,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
@@ -893,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;
}
}
@@ -912,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;
@@ -955,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)
@@ -993,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
@@ -1016,15 +1011,15 @@ LogCallbackPrepareAndSendMessageToQueueWrapper(UINT32 OperationCode,
//
if (IsVmxRootMode)
{
- LogMessage = &VmxLogMessage[CurrentCore * PacketChunkSize];
- TempMessage = &VmxTempMessage[CurrentCore * PacketChunkSize];
+ LogMessage = &g_VmxLogMessage[CurrentCore * PacketChunkSize];
+ TempMessage = &g_VmxTempMessage[CurrentCore * PacketChunkSize];
}
else
{
//
// To avoid buffer collision and buffer re-writing in VMX non-root, allocate pool
//
- LogMessage = ExAllocatePool2(POOL_FLAG_NON_PAGED, PacketChunkSize, POOLTAG);
+ LogMessage = PlatformMemAllocateNonPagedPool(PacketChunkSize);
if (LogMessage == NULL)
{
@@ -1033,14 +1028,14 @@ LogCallbackPrepareAndSendMessageToQueueWrapper(UINT32 OperationCode,
//
return FALSE;
}
- TempMessage = ExAllocatePool2(POOL_FLAG_NON_PAGED, PacketChunkSize, POOLTAG);
+ TempMessage = PlatformMemAllocateNonPagedPool(PacketChunkSize);
if (TempMessage == NULL)
{
//
// Insufficient space
//
- ExFreePoolWithTag(LogMessage, POOLTAG);
+ PlatformMemFreePool(LogMessage);
return FALSE;
}
}
@@ -1074,9 +1069,10 @@ 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
// Status = RtlStringCchPrintfA(TimeBuffer, RTL_NUMBER_OF(TimeBuffer),
@@ -1159,8 +1155,8 @@ FreeBufferAndReturn:
if (!IsVmxRootMode)
{
- ExFreePoolWithTag(LogMessage, POOLTAG);
- ExFreePoolWithTag(TempMessage, POOLTAG);
+ PlatformMemFreePool(LogMessage);
+ PlatformMemFreePool(TempMessage);
}
return Result;
@@ -1183,7 +1179,7 @@ LogCallbackPrepareAndSendMessageToQueue(UINT32 OperationCode,
BOOLEAN IsImmediateMessage,
BOOLEAN ShowCurrentSystemTime,
BOOLEAN Priority,
- const char * Fmt,
+ const CHAR * Fmt,
...)
{
va_list ArgList;
@@ -1279,7 +1275,7 @@ LogCallbackSendMessageToQueue(UINT32 OperationCode, BOOLEAN IsImmediateMessage,
// Set the index
//
Index = 1;
- SpinlockLock(&VmxRootLoggingLockForNonImmBuffers);
+ SpinlockLock(&g_VmxRootLoggingLockForNonImmBuffers);
}
else
{
@@ -1291,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
@@ -1301,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;
@@ -1394,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;
}
@@ -1432,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;
@@ -1447,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;
@@ -1463,25 +1459,25 @@ LogNotifyUsermodeCallback(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument
if (NotifyRecord != NULL)
{
- ExFreePoolWithTag(NotifyRecord, POOLTAG);
+ PlatformMemFreePool(NotifyRecord);
}
}
/**
* @brief Register a new IRP Pending thread which listens for new buffers
*
- * @param DeviceObject
- * @param Irp
- * @return NTSTATUS
+ * @param TargetIrp
+ * @param Status
+ *
+ * @return BOOLEAN
*/
-NTSTATUS
-LogRegisterIrpBasedNotification(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+BOOLEAN
+LogRegisterIrpBasedNotification(PVOID TargetIrp, LONG * Status)
{
- UNREFERENCED_PARAMETER(DeviceObject);
-
PNOTIFY_RECORD NotifyRecord;
PIO_STACK_LOCATION IrpStack;
PREGISTER_NOTIFY_BUFFER RegisterEvent;
+ PIRP Irp = (PIRP)TargetIrp;
//
// check if current core has another thread with pending IRP,
@@ -1492,28 +1488,29 @@ LogRegisterIrpBasedNotification(PDEVICE_OBJECT DeviceObject, PIRP Irp)
if (g_GlobalNotifyRecord == NULL)
{
- IrpStack = IoGetCurrentIrpStackLocation(Irp);
+ IrpStack = PlatformIoGetCurrentIrpStackLocation(Irp);
RegisterEvent = (PREGISTER_NOTIFY_BUFFER)Irp->AssociatedIrp.SystemBuffer;
//
// Allocate a record and save all the event context
//
- NotifyRecord = ExAllocatePool2(POOL_FLAG_NON_PAGED | POOL_FLAG_USE_QUOTA, sizeof(NOTIFY_RECORD), POOLTAG);
+ NotifyRecord = PlatformMemAllocateNonPagedPoolWithQuota(sizeof(NOTIFY_RECORD));
if (NULL == NotifyRecord)
{
- return STATUS_INSUFFICIENT_RESOURCES;
+ *Status = (LONG)STATUS_INSUFFICIENT_RESOURCES;
+ return FALSE;
}
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)
@@ -1530,7 +1527,7 @@ LogRegisterIrpBasedNotification(PDEVICE_OBJECT DeviceObject, PIRP Irp)
//
// Insert dpc to queue
//
- KeInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
+ PlatformDpcInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
}
else if (LogCheckForNewMessage(TRUE, TRUE))
{
@@ -1541,7 +1538,7 @@ LogRegisterIrpBasedNotification(PDEVICE_OBJECT DeviceObject, PIRP Irp)
//
// Insert dpc to queue
//
- KeInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
+ PlatformDpcInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
}
else if (LogCheckForNewMessage(FALSE, FALSE))
{
@@ -1553,7 +1550,7 @@ LogRegisterIrpBasedNotification(PDEVICE_OBJECT DeviceObject, PIRP Irp)
//
// Insert dpc to queue
//
- KeInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
+ PlatformDpcInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
}
else if (LogCheckForNewMessage(TRUE, FALSE))
{
@@ -1564,7 +1561,7 @@ LogRegisterIrpBasedNotification(PDEVICE_OBJECT DeviceObject, PIRP Irp)
//
// Insert dpc to queue
//
- KeInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
+ PlatformDpcInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
}
else
{
@@ -1576,73 +1573,75 @@ LogRegisterIrpBasedNotification(PDEVICE_OBJECT DeviceObject, PIRP Irp)
//
// We will return pending as we have marked the IRP pending
//
- return STATUS_PENDING;
+
+ *Status = (LONG)STATUS_PENDING;
+ return TRUE;
}
else
{
- return STATUS_SUCCESS;
+ *Status = (LONG)STATUS_SUCCESS;
+ return TRUE;
}
}
/**
* @brief Create an event-based usermode notifying mechanism
*
- * @param DeviceObject
- * @param Irp
- * @return NTSTATUS
+ * @param TargetIrp
+ * @return BOOLEAN
*/
-NTSTATUS
-LogRegisterEventBasedNotification(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+BOOLEAN
+LogRegisterEventBasedNotification(PVOID TargetIrp)
{
- UNREFERENCED_PARAMETER(DeviceObject);
-
PNOTIFY_RECORD NotifyRecord;
NTSTATUS Status;
PIO_STACK_LOCATION IrpStack;
PREGISTER_NOTIFY_BUFFER RegisterEvent;
+ PIRP Irp = (PIRP)TargetIrp;
- IrpStack = IoGetCurrentIrpStackLocation(Irp);
+ IrpStack = PlatformIoGetCurrentIrpStackLocation(Irp);
RegisterEvent = (PREGISTER_NOTIFY_BUFFER)Irp->AssociatedIrp.SystemBuffer;
//
// Allocate a record and save all the event context
//
- NotifyRecord = ExAllocatePool2(POOL_FLAG_NON_PAGED | POOL_FLAG_USE_QUOTA, sizeof(NOTIFY_RECORD), POOLTAG);
+ NotifyRecord = PlatformMemAllocateNonPagedPoolWithQuota(sizeof(NOTIFY_RECORD));
if (NULL == NotifyRecord)
{
- return STATUS_INSUFFICIENT_RESOURCES;
+ 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", Status);
- ExFreePoolWithTag(NotifyRecord, POOLTAG);
- return Status;
+ PlatformDbgPrint("Err, unable to reference user mode event object, status = 0x%x\n", Status);
+ PlatformMemFreePool(NotifyRecord);
+ return FALSE;
}
//
// Insert dpc to the queue
//
- KeInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
+ PlatformDpcInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
- return STATUS_SUCCESS;
+ 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 773e3b12..17cd5fec 100644
--- a/hyperdbg/hyperlog/header/pch.h
+++ b/hyperdbg/hyperlog/header/pch.h
@@ -9,10 +9,51 @@
* @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
-#include
+//
+// 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_HYPER_LOG
#include "UnloadDll.h"
+#include "SDK/HyperDbgSdk.h"
+#include "SDK/modules/HyperLog.h"
+#include "SDK/imports/kernel/HyperDbgHyperLogImports.h"
+#include "components/spinlock/header/Spinlock.h"
+#include "Logging.h"
+
+//
+// Platform independent headers
+//
+#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 31875ca9..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
@@ -66,6 +69,9 @@
$(SolutionDir)\include;$(ProjectDir)header;%(AdditionalIncludeDirectories)true
+ Create
+ pch.h
+ stdcpp20true
@@ -81,6 +87,10 @@
$(SolutionDir)\include;$(ProjectDir)header;%(AdditionalIncludeDirectories)true
+ Create
+ pch.h
+ stdcpp20
+ Fulltrue
@@ -89,24 +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 8019ed0c..b7765775 100644
--- a/hyperdbg/hyperlog/hyperlog.vcxproj.filters
+++ b/hyperdbg/hyperlog/hyperlog.vcxproj.filters
@@ -13,11 +13,12 @@
{93995380-89BD-4b04-88EB-625FBE52EBFB}h;hpp;hxx;hm;inl;inc;xsd
-
-
-
- Driver Files
-
+
+ {1ab177b4-9e6c-460e-834a-8fced04b42a3}
+
+
+ {21f0281e-fc2a-4e13-97ac-e4b35a05a31e}
+
@@ -29,6 +30,33 @@
code
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
+
+ code\platform
+
@@ -43,5 +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/Definition.h b/hyperdbg/include/Definition.h
deleted file mode 100644
index f7733598..00000000
--- a/hyperdbg/include/Definition.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * @file Definition.h
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief Header files for global definitions
- * @details This file contains definitions that are use in both user mode and
- * kernel mode Means that if you change the following files, structures or
- * enums, then these settings apply to both usermode and kernel mode
- * @version 0.1
- * @date 2020-04-10
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#pragma once
-
-//////////////////////////////////////////////////
-// Config File //
-//////////////////////////////////////////////////
-
-/**
- * @brief Config file name for HyperDbg
- *
- */
-#define CONFIG_FILE_NAME L"config.ini"
-
-//////////////////////////////////////////////////
-// Installer //
-//////////////////////////////////////////////////
-
-/**
- * @brief name of HyperDbg's VMM driver
- *
- */
-#define VMM_DRIVER_NAME "hprdbghv"
-
-/**
- * @brief name of HyperDbg's VMM driver
- *
- */
-#define KERNEL_DEBUGGER_DRIVER_NAME "hprdbgkd"
-
-//////////////////////////////////////////////////
-// Test Cases //
-//////////////////////////////////////////////////
-
-/**
- * @brief Test cases file name
- */
-#define TEST_CASE_FILE_NAME "test-cases.txt"
-
-/**
- * @brief Test cases file name
- */
-#define SCRIPT_ENGINE_TEST_CASES_DIRECTORY "script-test-cases"
-
-/**
- * @brief Maximum test cases to communicate between debugger and debuggee process
- */
-#define TEST_CASE_MAXIMUM_NUMBER_OF_KERNEL_TEST_CASES 200
-
-/**
- * @brief Maximum buffer to communicate between debugger and debuggee process
- */
-#define TEST_CASE_MAXIMUM_BUFFERS_TO_COMMUNICATE sizeof(DEBUGGEE_KERNEL_AND_USER_TEST_INFORMATION) * TEST_CASE_MAXIMUM_NUMBER_OF_KERNEL_TEST_CASES
-
-//////////////////////////////////////////////////
-// Delay Speeds //
-//////////////////////////////////////////////////
-
-/**
- * @brief The speed delay for showing messages from kernel-mode
- * to user-mode in VMI-mode, using a lower value causes the
- * HyperDbg to show messages faster but you should keep in mind,
- * not to eat all of the CPU
- */
-#define DefaultSpeedOfReadingKernelMessages 30
diff --git a/hyperdbg/include/SDK/Examples/hyperdbg_app/code/hyperdbg-app.cpp b/hyperdbg/include/SDK/Examples/hyperdbg_app/code/hyperdbg-app.cpp
deleted file mode 100644
index dd2aa152..00000000
--- a/hyperdbg/include/SDK/Examples/hyperdbg_app/code/hyperdbg-app.cpp
+++ /dev/null
@@ -1,467 +0,0 @@
-/**
- * @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"
-
-/**
- * @brief Holds the global handle of device which is used
- * to send the request to the kernel by IOCTL, this
- * handle is not used for IRP Pending of message tracing
- * this handle used in reversing machine
- *
- */
-HANDLE g_DeviceHandleReversingMachine;
-
-/**
- * @brief Handle to show that if the debugger is loaded successfully
- *
- */
-HANDLE g_IsDriverLoadedSuccessfully = NULL;
-
-/**
- * @brief Holds the global handle of device which is used
- * to send the request to the kernel by IOCTL, this
- * handle is not used for IRP Pending of message tracing
- * this handle is used in KD VMM
- *
- */
-HANDLE g_DeviceHandle;
-
-/**
- * @brief Checks whether the RM module is loaded or not
- *
- */
-BOOLEAN g_IsReversingMachineModulesLoaded;
-
-/**
- * @brief Shows whether the vmxoff process start or not
- *
- */
-BOOLEAN g_IsVmxOffProcessStart;
-
-/*
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-__declspec(dllexport) int ReversingMachineStart();
-__declspec(dllexport) int ReversingMachineStop();
-
-#ifdef __cplusplus
-}
-#endif
-*/
-
-/**
- * @brief Show messages
- *
- * @param Fmt format string message
- */
-VOID
-ShowMessages(const char * Fmt, ...)
-{
- va_list ArgList;
-
- va_start(ArgList, Fmt);
- vprintf(Fmt, ArgList);
- va_end(ArgList);
-}
-
-/**
- * @brief Read kernel buffers using IRP Pending
- *
- * @param Device Driver handle
- */
-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(
- "\\\\.\\HyperDbgReversingMachineDevice",
- 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)
- {
- //
- // 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));
-
- switch (OperationCode)
- {
- case OPERATION_LOG_NON_IMMEDIATE_MESSAGE:
-
- ShowMessages("%s", OutputBuffer + sizeof(UINT32));
-
- break;
- case OPERATION_LOG_INFO_MESSAGE:
-
- ShowMessages("%s", OutputBuffer + sizeof(UINT32));
-
- break;
- case OPERATION_LOG_ERROR_MESSAGE:
-
- ShowMessages("%s", OutputBuffer + sizeof(UINT32));
-
- break;
- case OPERATION_LOG_WARNING_MESSAGE:
-
- ShowMessages("%s", OutputBuffer + sizeof(UINT32));
-
- break;
-
- case OPERATION_HYPERVISOR_DRIVER_IS_SUCCESSFULLY_LOADED:
-
- //
- // Indicate that driver (Hypervisor) is loaded successfully
- //
- SetEvent(g_IsDriverLoadedSuccessfully);
-
- break;
-
- default:
-
- ShowMessages("err, unknown message is received in rev module\n");
-
- break;
- }
- }
- }
- 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 Unload the reversing machine driver
- *
- * @return int return zero if it was successful or non-zero if there
- * was error
- */
-int
-ReversingMachineStop()
-{
- //
- // Not implemented
- //
- return 0;
-}
-
-/**
- * @brief Load the reversing machine driver
- *
- * @return int return zero if it was successful or non-zero if there
- * was error
- */
-int
-ReversingMachineStart()
-{
- DWORD ErrorNum;
- DWORD ThreadId;
-
- if (g_DeviceHandle)
- {
- ShowMessages("handle of the driver found, if you use 'load' before, please "
- "unload it using 'unload'\n");
- return 1;
- }
-
- //
- // Make sure that this variable is false, because it might be set to
- // true as the result of a previous load
- //
- g_IsVmxOffProcessStart = FALSE;
-
- //
- // Init entering vmx
- //
- g_DeviceHandle = CreateFileA(
- "\\\\.\\HyperDbgReversingMachineDevice",
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, /// lpSecurityAttirbutes
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
- NULL); /// lpTemplateFile
-
- if (g_DeviceHandle == 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 (%x)\n", ErrorNum);
- }
-
- g_DeviceHandle = NULL;
- return 1;
- }
- //
- // Create event to show if the hypervisor is loaded or not
- //
- g_IsDriverLoadedSuccessfully = CreateEvent(NULL, FALSE, FALSE, NULL);
-
- HANDLE Thread = CreateThread(NULL, 0, IrpBasedBufferThread, NULL, 0, &ThreadId);
-
- // if (Thread)
- // {
- // ShowMessages("thread Created successfully\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);
-
- //
- // Operation was successful
- //
- return 0;
-}
-
-/**
- * @brief Unload the reversing machine driver
- *
- * @return int return zero if it was successful or non-zero if there
- * was error
- */
-int
-HyperDbgUnloadReversingMachine()
-{
- //
- // Check if driver is loaded
- //
- if (!g_IsReversingMachineModulesLoaded)
- {
- ShowMessages("handle of the driver not found, probably the driver is not loaded. Did you use 'load' command?\n");
- return 1;
- }
-
- ShowMessages("start terminating...\n");
-
- //
- // Call the unloader of the hprdbgrev module
- //
- ReversingMachineStop();
-
- ShowMessages("you're not on reversing machine's hypervisor anymore!\n");
-
- return 0;
-}
-
-/**
- * @brief Load the reversing machine driver
- *
- * @return int return zero if it was successful or non-zero if there
- * was error
- */
-int
-HyperDbgLoadReversingMachine()
-{
- char CpuId[13] = {0};
-
- if (g_DeviceHandle)
- {
- ShowMessages("handle of the driver found, if you use 'load' before, please "
- "unload it using 'unload'\n");
- return 1;
- }
-
- //
- // Read the vendor string
- //
- HyperDbgReadVendorString(CpuId);
-
- ShowMessages("current processor vendor is : %s\n", CpuId);
-
- if (strcmp(CpuId, "GenuineIntel") == 0)
- {
- ShowMessages("virtualization technology is vt-x\n");
- }
- else
- {
- ShowMessages("this program is not designed to run in a non-VT-x "
- "environment !\n");
- return 1;
- }
-
- if (HyperDbgVmxSupportDetection())
- {
- ShowMessages("vmx operation is supported by your processor\n");
- }
- else
- {
- ShowMessages("vmx operation is not supported by your processor\n");
- return 1;
- }
-
- //
- // Call hprdbgrev start function
- //
- ReversingMachineStart();
-
- return 0;
-}
-
-/**
- * @brief main function
- *
- * @return int
- */
-int
-main()
-{
- if (HyperDbgLoadReversingMachine() == 0)
- {
- //
- // HyperDbg driver loaded successfully
- //
- HyperDbgUnloadReversingMachine();
- }
- else
- {
- ShowMessages("err, in loading HyperDbg\n");
- }
-}
diff --git a/hyperdbg/include/SDK/Headers/BasicTypes.h b/hyperdbg/include/SDK/Headers/BasicTypes.h
deleted file mode 100644
index 7c426390..00000000
--- a/hyperdbg/include/SDK/Headers/BasicTypes.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/**
- * @file BasicTypes.h
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief HyperDbg's SDK Headers For Basic Datatypes
- * @details This file contains definitions of basic datatypes
- * @version 0.2
- * @date 2022-06-28
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#pragma once
-
-#pragma warning(disable : 4201) // Suppress nameless struct/union warning
-
-//////////////////////////////////////////////////
-// 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 unsigned short USHORT;
-typedef unsigned long ULONG;
-
-typedef UCHAR BOOLEAN; // winnt
-typedef BOOLEAN * PBOOLEAN; // winnt
-
-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;
-
-#define NULL_ZERO 0
-#define NULL64_ZERO 0ull
-
-#define FALSE 0
-#define TRUE 1
-
-#define UPPER_56_BITS 0xffffffffffffff00
-#define UPPER_48_BITS 0xffffffffffff0000
-#define UPPER_32_BITS 0xffffffff00000000
-#define LOWER_32_BITS 0x00000000ffffffff
-#define LOWER_16_BITS 0x000000000000ffff
-#define LOWER_8_BITS 0x00000000000000ff
-#define SECOND_LOWER_8_BITS 0x000000000000ff00
-#define UPPER_48_BITS_AND_LOWER_8_BITS 0xffffffffffff00ff
-
-//
-// DO NOT FUCKING TOUCH THIS STRUCTURE WITHOUT COORDINATION WITH SINA
-//
-typedef struct GUEST_REGS
-{
- //
- // DO NOT FUCKING TOUCH THIS STRUCTURE WITHOUT COORDINATION WITH SINA
- //
-
- UINT64 rax; // 0x00
- UINT64 rcx; // 0x08
- UINT64 rdx; // 0x10
- UINT64 rbx; // 0x18
- UINT64 rsp; // 0x20
- UINT64 rbp; // 0x28
- UINT64 rsi; // 0x30
- UINT64 rdi; // 0x38
- UINT64 r8; // 0x40
- UINT64 r9; // 0x48
- UINT64 r10; // 0x50
- UINT64 r11; // 0x58
- UINT64 r12; // 0x60
- UINT64 r13; // 0x68
- UINT64 r14; // 0x70
- UINT64 r15; // 0x78
-
- //
- // DO NOT FUCKING TOUCH THIS STRUCTURE WITHOUT COORDINATION WITH SINA
- //
-
-} GUEST_REGS, *PGUEST_REGS;
-
-/**
- * @brief struct for extra registers
- *
- */
-typedef struct GUEST_EXTRA_REGISTERS
-{
- UINT16 CS;
- UINT16 DS;
- UINT16 FS;
- UINT16 GS;
- UINT16 ES;
- UINT16 SS;
- UINT64 RFLAGS;
- UINT64 RIP;
-} GUEST_EXTRA_REGISTERS, *PGUEST_EXTRA_REGISTERS;
-
-/**
- * @brief List of different variables
- */
-typedef struct _SCRIPT_ENGINE_VARIABLES_LIST
-{
- UINT64 * TempList;
- UINT64 * GlobalVariablesList;
- UINT64 * LocalVariablesList;
-
-} SCRIPT_ENGINE_VARIABLES_LIST, *PSCRIPT_ENGINE_VARIABLES_LIST;
-
-/**
- * @brief CR3 Structure
- *
- */
-typedef struct _CR3_TYPE
-{
- union
- {
- UINT64 Flags;
-
- struct
- {
- UINT64 Pcid : 12;
- UINT64 PageFrameNumber : 36;
- UINT64 Reserved1 : 12;
- UINT64 Reserved_2 : 3;
- UINT64 PcidInvalidate : 1;
- } Fields;
- };
-} CR3_TYPE, *PCR3_TYPE;
diff --git a/hyperdbg/include/SDK/Headers/HardwareDebugger.h b/hyperdbg/include/SDK/Headers/HardwareDebugger.h
deleted file mode 100644
index 4a62700f..00000000
--- a/hyperdbg/include/SDK/Headers/HardwareDebugger.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * @file HardwareDebugger.h
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief HyperDbg's Hardware Debugger (hwdbg) types and constants
- * @details This file contains definitions of hwdbg elements
- * used in HyperDbg
- * @version 0.9
- * @date 2024-04-28
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#pragma once
-
-/**
- * @brief Different action of hwdbg
- * @warning This file should be changed along with hwdbg files
- *
- */
-typedef enum _HWDBG_ACTION_ENUMS
-{
- hwdbgActionSendVersion = 0,
- hwdbgActionSendPinInformation = 1,
- hwdbgActionConfigureScriptBuffer = 2,
-
-} HWDBG_ACTION_ENUMS;
-
-/**
- * @brief Different responses come from hwdbg
- * @warning This file should be changed along with hwdbg files
- *
- */
-typedef enum _HWDBG_RESPONSE_ENUMS
-{
- hwdbgResponseVersion = 0,
- hwdbgResponsePinInformation = 1,
- hwdbgResponseScriptBufferConfigurationResult = 2,
-
-} HWDBG_RESPONSE_ENUMS;
diff --git a/hyperdbg/include/SDK/Headers/Ioctls.h b/hyperdbg/include/SDK/Headers/Ioctls.h
deleted file mode 100644
index 62ea34a1..00000000
--- a/hyperdbg/include/SDK/Headers/Ioctls.h
+++ /dev/null
@@ -1,297 +0,0 @@
-/**
- * @file Ioctls.h
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief HyperDbg's SDK IOCTL codes
- * @details This file contains definitions of IOCTLs used in HyperDbg
- * @version 0.2
- * @date 2022-06-24
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#pragma once
-
-//////////////////////////////////////////////////
-// Definitions //
-//////////////////////////////////////////////////
-
-//
-// The following controls are mainly defined in
-//
-
-//
-// Macro definition for defining IOCTL and FSCTL function control codes. Note
-// that function codes 0-2047 are reserved for Microsoft Corporation, and
-// 2048-4095 are reserved for customers.
-//
-#ifndef CTL_CODE
-
-# define CTL_CODE(DeviceType, Function, Method, Access) ( \
- ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
-
-#endif // ! CTL_CODE
-
-#ifndef FILE_ANY_ACCESS
-
-# define FILE_ANY_ACCESS 0
-
-#endif // !FILE_ANY_ACCESS
-
-//
-// Define the method codes for how buffers are passed for I/O and FS controls
-//
-
-#ifndef METHOD_BUFFERED
-
-# define METHOD_BUFFERED 0
-
-#endif // !METHOD_BUFFERED
-
-#ifndef FILE_DEVICE_UNKNOWN
-
-# define FILE_DEVICE_UNKNOWN 0x00000022
-
-#endif // !FILE_DEVICE_UNKNOWN
-
-//////////////////////////////////////////////////
-// IOCTLs //
-//////////////////////////////////////////////////
-
-/**
- * @brief ioctl, register a new event
- *
- */
-#define IOCTL_REGISTER_EVENT \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, 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)
-
-/**
- * @brief ioctl, to terminate vmx and exit form debugger
- *
- */
-#define IOCTL_TERMINATE_VMX \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, 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)
-
-/**
- * @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)
-
-/**
- * @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)
-
-/**
- * @brief ioctl, register an event
- *
- */
-#define IOCTL_DEBUGGER_REGISTER_EVENT \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, 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)
-
-/**
- * @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)
-
-/**
- * @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)
-
-/**
- * @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)
-
-/**
- * @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)
-
-/**
- * @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)
-
-/**
- * @brief ioctl, flush the kernel buffers
- *
- */
-#define IOCTL_DEBUGGER_FLUSH_LOGGING_BUFFERS \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80d, 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)
-
-/**
- * @brief ioctl, print states (Deprecated)
- *
- *
- */
-#define IOCTL_DEBUGGER_PRINT \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80f, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-/**
- * @brief ioctl, prepare debuggee
- *
- */
-#define IOCTL_PREPARE_DEBUGGEE \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x810, 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)
-
-/**
- * @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)
-
-/**
- * @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)
-
-/**
- * @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)
-
-/**
- * @brief ioctl, collects a buffer from kernel-side testing information
- *
- */
-#define IOCTL_SEND_GET_KERNEL_SIDE_TEST_INFORMATION \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x815, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-/**
- * @brief ioctl, to perform kernel-side tests
- *
- */
-#define IOCTL_PERFROM_KERNEL_SIDE_TESTS \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x816, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-/**
- * @brief ioctl, to reserve pre-allocated pools
- *
- */
-#define IOCTL_RESERVE_PRE_ALLOCATED_POOLS \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x817, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-/**
- * @brief ioctl, to send user debugger commands
- *
- */
-#define IOCTL_SEND_USER_DEBUGGER_COMMANDS \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x818, 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, 0x819, 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, 0x81a, 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, 0x81b, 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, 0x81c, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-/**
- * @brief ioctl, query the current process details
- *
- */
-#define IOCTL_QUERY_CURRENT_PROCESS \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x81d, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-/**
- * @brief ioctl, query the current thread details
- *
- */
-#define IOCTL_QUERY_CURRENT_THREAD \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x81e, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-/**
- * @brief ioctl, request service from the reversing machine
- *
- */
-#define IOCTL_REQUEST_REV_MACHINE_SERVICE \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x81f, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-/**
- * @brief ioctl, request to bring pages in
- *
- */
-#define IOCTL_DEBUGGER_BRING_PAGES_IN \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x820, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-/**
- * @brief ioctl, to preactivate a functionality
- *
- */
-#define IOCTL_PREACTIVATE_FUNCTIONALITY \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x821, METHOD_BUFFERED, FILE_ANY_ACCESS)
diff --git a/hyperdbg/include/SDK/HyperDbgSdk.h b/hyperdbg/include/SDK/HyperDbgSdk.h
index 9fcaa386..fc53dd57 100644
--- a/hyperdbg/include/SDK/HyperDbgSdk.h
+++ b/hyperdbg/include/SDK/HyperDbgSdk.h
@@ -1,11 +1,44 @@
#pragma once
-#include "SDK/Headers/Constants.h"
-#include "SDK/Headers/BasicTypes.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"
+//
+// 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/Symbols.h"
+#include "SDK/headers/HardwareDebugger.h"
+
+//
+// Devices
+//
+#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
+//
+#include "SDK/headers/Assertions.h"
+
+//
+// Script Engine
+//
+#include "SDK/headers/ScriptEngineCommonDefinitions.h"
diff --git a/hyperdbg/include/SDK/Imports/HyperDbgCtrlImports.h b/hyperdbg/include/SDK/Imports/HyperDbgCtrlImports.h
deleted file mode 100644
index 0664cead..00000000
--- a/hyperdbg/include/SDK/Imports/HyperDbgCtrlImports.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * @file HyperDbgCtrlImports.h
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief Headers relating exported functions from controller interface
- * @version 0.2
- * @date 2023-02-02
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#pragma once
-
-#ifdef HYPERDBG_HPRDBGCTRL
-# define IMPORT_EXPORT_CTRL __declspec(dllexport)
-#else
-# define IMPORT_EXPORT_CTRL __declspec(dllimport)
-#endif
-
-//
-// Header file of HPRDBGCTRL
-// Imports
-//
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-//
-// Support Detection
-//
-IMPORT_EXPORT_CTRL bool HyperDbgVmxSupportDetection();
-IMPORT_EXPORT_CTRL void HyperDbgReadVendorString(char *);
-
-//
-// VMM Module
-//
-IMPORT_EXPORT_CTRL int HyperDbgLoadVmm();
-IMPORT_EXPORT_CTRL int HyperDbgUnloadVmm();
-IMPORT_EXPORT_CTRL int HyperDbgInstallVmmDriver();
-IMPORT_EXPORT_CTRL int HyperDbgUninstallVmmDriver();
-IMPORT_EXPORT_CTRL int HyperDbgStopVmmDriver();
-
-//
-// General imports
-//
-IMPORT_EXPORT_CTRL int HyperDbgInterpreter(char * Command);
-IMPORT_EXPORT_CTRL void HyperDbgShowSignature();
-IMPORT_EXPORT_CTRL void HyperDbgSetTextMessageCallback(Callback handler);
-IMPORT_EXPORT_CTRL int HyperDbgScriptReadFileAndExecuteCommandline(int argc, char * argv[]);
-IMPORT_EXPORT_CTRL bool HyperDbgContinuePreviousCommand();
-IMPORT_EXPORT_CTRL bool HyperDbgCheckMultilineCommand(char * CurrentCommand, bool Reset);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/hyperdbg/include/SDK/Imports/HyperDbgRevImports.h b/hyperdbg/include/SDK/Imports/HyperDbgRevImports.h
deleted file mode 100644
index 25a90cb2..00000000
--- a/hyperdbg/include/SDK/Imports/HyperDbgRevImports.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * @file HyperDbgRevImports.h
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief Headers relating exported functions from reversing machine interface
- * @version 0.2
- * @date 2023-02-02
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#pragma once
-
-//
-// Header file of hpr
-// Imports
-//
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-//
-// Reversing Machine Module
-//
-__declspec(dllimport) int ReversingMachineStart();
-__declspec(dllimport) int ReversingMachineStop();
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/hyperdbg/include/SDK/Imports/HyperDbgScriptImports.h b/hyperdbg/include/SDK/Imports/HyperDbgScriptImports.h
deleted file mode 100644
index f677985b..00000000
--- a/hyperdbg/include/SDK/Imports/HyperDbgScriptImports.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * @file HyperDbgScriptImports.h
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief Headers relating exported functions from script engine
- * @version 0.2
- * @date 2023-02-02
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#pragma once
-
-//
-// Header file of script-engine
-// Imports
-//
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-__declspec(dllimport) PSYMBOL_BUFFER ScriptEngineParse(char * str);
-__declspec(dllimport) PSYMBOL_BUFFER GetStackBuffer();
-__declspec(dllimport) void PrintSymbolBuffer(const PSYMBOL_BUFFER SymbolBuffer);
-__declspec(dllimport) void PrintSymbol(PSYMBOL Symbol);
-__declspec(dllimport) void RemoveSymbolBuffer(PSYMBOL_BUFFER SymbolBuffer);
-
-//
-// pdb parser
-//
-__declspec(dllimport) VOID
- ScriptEngineSetTextMessageCallback(PVOID Handler);
-__declspec(dllimport) VOID
- ScriptEngineSymbolAbortLoading();
-__declspec(dllimport) UINT64
- ScriptEngineConvertNameToAddress(const char * FunctionOrVariableName, PBOOLEAN WasFound);
-__declspec(dllimport) UINT32
- ScriptEngineLoadFileSymbol(UINT64 BaseAddress, const char * PdbFileName, const char * CustomModuleName);
-__declspec(dllimport) UINT32
- ScriptEngineUnloadAllSymbols();
-__declspec(dllimport) UINT32
- ScriptEngineUnloadModuleSymbol(char * ModuleName);
-__declspec(dllimport) UINT32
- ScriptEngineSearchSymbolForMask(const char * SearchMask);
-__declspec(dllimport) BOOLEAN
- ScriptEngineGetFieldOffset(CHAR * TypeName, CHAR * FieldName, UINT32 * FieldOffset);
-__declspec(dllimport) BOOLEAN
- ScriptEngineGetDataTypeSize(CHAR * TypeName, UINT64 * TypeSize);
-__declspec(dllimport) BOOLEAN
- ScriptEngineCreateSymbolTableForDisassembler(void * CallbackFunction);
-__declspec(dllimport) BOOLEAN
- ScriptEngineConvertFileToPdbPath(const char * LocalFilePath, char * ResultPath);
-__declspec(dllimport) BOOLEAN
- ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetails(const char * LocalFilePath, char * PdbFilePath, char * GuidAndAgeDetails, BOOLEAN Is32BitModule);
-__declspec(dllimport) BOOLEAN
- ScriptEngineSymbolInitLoad(PVOID BufferToStoreDetails, UINT32 StoredLength, BOOLEAN DownloadIfAvailable, const char * SymbolPath, BOOLEAN IsSilentLoad);
-__declspec(dllimport) BOOLEAN
- ScriptEngineShowDataBasedOnSymbolTypes(const char * TypeName, UINT64 Address, BOOLEAN IsStruct, PVOID BufferAddress, const char * AdditionalParameters);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/hyperdbg/include/SDK/Imports/HyperDbgSymImports.h b/hyperdbg/include/SDK/Imports/HyperDbgSymImports.h
deleted file mode 100644
index 2985523f..00000000
--- a/hyperdbg/include/SDK/Imports/HyperDbgSymImports.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * @file HyperDbgSymImports.h
- * @author Sina Karvandi (sina@hyperdbg.org)
- * @brief Headers relating exported functions from symbol parser
- * @version 0.2
- * @date 2023-02-02
- *
- * @copyright This project is released under the GNU Public License v3.
- *
- */
-#pragma once
-
-//
-// Header file of symbol-parser
-// Imports
-//
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-__declspec(dllimport) VOID
- SymSetTextMessageCallback(PVOID Handler);
-__declspec(dllimport) VOID
- SymbolAbortLoading();
-__declspec(dllimport) UINT64
- SymConvertNameToAddress(const char * FunctionOrVariableName, PBOOLEAN WasFound);
-__declspec(dllimport) UINT32
- SymLoadFileSymbol(UINT64 BaseAddress, const char * PdbFileName, const char * CustomModuleName);
-__declspec(dllimport) UINT32
- SymUnloadAllSymbols();
-__declspec(dllimport) UINT32
- SymUnloadModuleSymbol(char * ModuleName);
-__declspec(dllimport) UINT32
- SymSearchSymbolForMask(const char * SearchMask);
-__declspec(dllimport) BOOLEAN
- SymGetFieldOffset(CHAR * TypeName, CHAR * FieldName, UINT32 * FieldOffset);
-__declspec(dllimport) BOOLEAN
- SymGetDataTypeSize(CHAR * TypeName, UINT64 * TypeSize);
-__declspec(dllimport) BOOLEAN
- SymCreateSymbolTableForDisassembler(void * CallbackFunction);
-__declspec(dllimport) BOOLEAN
- SymConvertFileToPdbPath(const char * LocalFilePath, char * ResultPath);
-__declspec(dllimport) BOOLEAN
- SymConvertFileToPdbFileAndGuidAndAgeDetails(const char * LocalFilePath,
- char * PdbFilePath,
- char * GuidAndAgeDetails,
- BOOLEAN Is32BitModule);
-__declspec(dllimport) BOOLEAN
- SymbolInitLoad(PVOID BufferToStoreDetails,
- UINT32 StoredLength,
- BOOLEAN DownloadIfAvailable,
- const char * SymbolPath,
- BOOLEAN IsSilentLoad);
-__declspec(dllimport) BOOLEAN
- SymShowDataBasedOnSymbolTypes(const char * TypeName,
- UINT64 Address,
- BOOLEAN IsStruct,
- PVOID BufferAddress,
- const char * AdditionalParameters);
-__declspec(dllimport) BOOLEAN
- SymQuerySizeof(_In_ const char * StructNameOrTypeName, _Out_ UINT32 * SizeOfField);
-__declspec(dllimport) BOOLEAN
- SymCastingQueryForFiledsAndTypes(_In_ const char * StructName,
- _In_ const char * FiledOfStructName,
- _Out_ PBOOLEAN IsStructNamePointerOrNot,
- _Out_ PBOOLEAN IsFiledOfStructNamePointerOrNot,
- _Out_ char ** NewStructOrTypeName,
- _Out_ UINT32 * OffsetOfFieldFromTop,
- _Out_ UINT32 * SizeOfField);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/hyperdbg/include/SDK/headers/Assertions.h b/hyperdbg/include/SDK/headers/Assertions.h
new file mode 100644
index 00000000..6f5ea32e
--- /dev/null
+++ b/hyperdbg/include/SDK/headers/Assertions.h
@@ -0,0 +1,31 @@
+/**
+ * @file Assertions.h
+ * @author ddkwork
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief HyperDbg's assertions
+ * @details This file contains asserts and static asserts
+ * @version 0.10
+ * @date 2024-06-21
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Asserts //
+//////////////////////////////////////////////////
+
+/**
+ * @brief check so the DEBUGGEE_UD_PAUSED_PACKET should be smaller than packet size
+ *
+ */
+static_assert(sizeof(DEBUGGEE_UD_PAUSED_PACKET) < PacketChunkSize,
+ "err (static_assert), size of PacketChunkSize should be bigger than DEBUGGEE_UD_PAUSED_PACKET");
+
+/**
+ * @brief check so the DEBUGGER_UPDATE_SYMBOL_TABLE should be smaller than packet size
+ *
+ */
+static_assert(sizeof(DEBUGGER_UPDATE_SYMBOL_TABLE) < PacketChunkSize,
+ "err (static_assert), size of PacketChunkSize should be bigger than DEBUGGER_UPDATE_SYMBOL_TABLE (MODULE_SYMBOL_DETAIL)");
diff --git a/hyperdbg/include/SDK/headers/BasicTypes.h b/hyperdbg/include/SDK/headers/BasicTypes.h
new file mode 100644
index 00000000..17e5c84a
--- /dev/null
+++ b/hyperdbg/include/SDK/headers/BasicTypes.h
@@ -0,0 +1,250 @@
+/**
+ * @file BasicTypes.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief HyperDbg's SDK Headers For Basic Datatypes
+ * @details This file contains definitions of basic datatypes
+ * @version 0.2
+ * @date 2022-06-28
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#ifdef _WIN32 // Windows
+
+# pragma warning(disable : 4201) // Suppress nameless struct/union warning
+
+#endif
+
+//////////////////////////////////////////////////
+// Basic Datatypes //
+//////////////////////////////////////////////////
+
+typedef unsigned long long QWORD;
+typedef int BOOL;
+
+typedef short SHORT;
+typedef long LONG;
+
+typedef unsigned short USHORT;
+typedef unsigned long ULONG;
+
+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 __int64 INT64, *PINT64;
+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
+
+#define FALSE 0
+#define TRUE 1
+
+#define UPPER_56_BITS 0xffffffffffffff00
+#define UPPER_48_BITS 0xffffffffffff0000
+#define UPPER_32_BITS 0xffffffff00000000
+#define LOWER_32_BITS 0x00000000ffffffff
+#define LOWER_16_BITS 0x000000000000ffff
+#define LOWER_8_BITS 0x00000000000000ff
+#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
+{
+ //
+ // DO NOT FUCKING TOUCH THIS STRUCTURE WITHOUT COORDINATION WITH SINA
+ //
+
+ UINT64 rax; // 0x00
+ UINT64 rcx; // 0x08
+ UINT64 rdx; // 0x10
+ UINT64 rbx; // 0x18
+ UINT64 rsp; // 0x20
+ UINT64 rbp; // 0x28
+ UINT64 rsi; // 0x30
+ UINT64 rdi; // 0x38
+ UINT64 r8; // 0x40
+ UINT64 r9; // 0x48
+ UINT64 r10; // 0x50
+ UINT64 r11; // 0x58
+ UINT64 r12; // 0x60
+ UINT64 r13; // 0x68
+ UINT64 r14; // 0x70
+ UINT64 r15; // 0x78
+
+ //
+ // DO NOT FUCKING TOUCH THIS STRUCTURE WITHOUT COORDINATION WITH SINA
+ //
+
+} 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
+ *
+ */
+typedef struct GUEST_EXTRA_REGISTERS
+{
+ UINT16 CS;
+ UINT16 DS;
+ UINT16 FS;
+ UINT16 GS;
+ UINT16 ES;
+ UINT16 SS;
+ UINT64 RFLAGS;
+ UINT64 RIP;
+} GUEST_EXTRA_REGISTERS, *PGUEST_EXTRA_REGISTERS;
+
+/**
+ * @brief List of different variables
+ */
+typedef struct _SCRIPT_ENGINE_GENERAL_REGISTERS
+{
+ UINT64 * StackBuffer;
+ UINT64 * GlobalVariablesList;
+ UINT64 StackIndx;
+ UINT64 StackBaseIndx;
+ UINT64 ReturnValue;
+} SCRIPT_ENGINE_GENERAL_REGISTERS, *PSCRIPT_ENGINE_GENERAL_REGISTERS;
+
+/**
+ * @brief CR3 Structure
+ *
+ */
+typedef struct _CR3_TYPE
+{
+ union
+ {
+ UINT64 Flags;
+
+ struct
+ {
+ UINT64 Pcid : 12;
+ UINT64 PageFrameNumber : 36;
+ UINT64 Reserved1 : 12;
+ UINT64 Reserved_2 : 3;
+ UINT64 PcidInvalidate : 1;
+ } Fields;
+ };
+} CR3_TYPE, *PCR3_TYPE;
diff --git a/hyperdbg/include/SDK/Headers/Connection.h b/hyperdbg/include/SDK/headers/Connection.h
similarity index 85%
rename from hyperdbg/include/SDK/Headers/Connection.h
rename to hyperdbg/include/SDK/headers/Connection.h
index f416eb38..aac62f47 100644
--- a/hyperdbg/include/SDK/Headers/Connection.h
+++ b/hyperdbg/include/SDK/headers/Connection.h
@@ -95,6 +95,14 @@ typedef enum _DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_SYMBOL_QUERY_PTE,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_SET_SHORT_CIRCUITING_STATE,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_INJECT_PAGE_FAULT,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_WRITE_REGISTER,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_QUERY_PCITREE,
+ 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
@@ -127,6 +135,14 @@ typedef enum _DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_PTE,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_VA2PA_AND_PA2VA,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_BRINGING_PAGES_IN,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_WRITE_REGISTER,
+ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_PCITREE,
+ 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
similarity index 72%
rename from hyperdbg/include/SDK/Headers/Constants.h
rename to hyperdbg/include/SDK/headers/Constants.h
index ef6cb31f..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 9
+#define VERSION_MINOR 21
#define VERSION_PATCH 0
+#define BETA_VERSION FALSE
+
//
// Example of __DATE__ string: "Jul 27 2012"
// 01234567890
@@ -76,69 +79,9 @@
#define BUILD_SEC_CH0 (__TIME__[6])
#define BUILD_SEC_CH1 (__TIME__[7])
-#if VERSION_MAJOR > 100
+#ifdef __cplusplus // because it's not valid in C
-# define VERSION_MAJOR_INIT \
- ((VERSION_MAJOR / 100) + '0'), \
- (((VERSION_MAJOR % 100) / 10) + '0'), \
- ((VERSION_MAJOR % 10) + '0')
-
-#elif VERSION_MAJOR > 10
-
-# define VERSION_MAJOR_INIT \
- ((VERSION_MAJOR / 10) + '0'), \
- ((VERSION_MAJOR % 10) + '0')
-
-#else
-
-# define VERSION_MAJOR_INIT \
- (VERSION_MAJOR + '0')
-
-#endif
-
-#if VERSION_MINOR > 100
-
-# define VERSION_MINOR_INIT \
- ((VERSION_MINOR / 100) + '0'), \
- (((VERSION_MINOR % 100) / 10) + '0'), \
- ((VERSION_MINOR % 10) + '0')
-
-#elif VERSION_MINOR > 10
-
-# define VERSION_MINOR_INIT \
- ((VERSION_MINOR / 10) + '0'), \
- ((VERSION_MINOR % 10) + '0')
-
-#else
-
-# define VERSION_MINOR_INIT \
- (VERSION_MINOR + '0')
-
-#endif
-
-#if VERSION_PATCH > 100
-
-# define VERSION_PATCH_INIT \
- ((VERSION_PATCH / 100) + '0'), \
- (((VERSION_PATCH % 100) / 10) + '0'), \
- ((VERSION_PATCH % 10) + '0')
-
-#elif VERSION_PATCH > 10
-
-# define VERSION_PATCH_INIT \
- ((VERSION_PATCH / 10) + '0'), \
- ((VERSION_PATCH % 10) + '0')
-
-#else
-
-# define VERSION_PATCH_INIT \
- (VERSION_PATCH + '0')
-
-#endif
-
-#ifndef HYPERDBG_KERNEL_MODE
-
-const unsigned char BuildDateTime[] = {
+const UCHAR BuildDateTime[] = {
BUILD_YEAR_CH0,
BUILD_YEAR_CH1,
BUILD_YEAR_CH2,
@@ -161,16 +104,21 @@ const unsigned char BuildDateTime[] = {
'\0'};
-const unsigned char CompleteVersion[] = {
- 'v',
- VERSION_MAJOR_INIT,
- '.',
- VERSION_MINOR_INIT,
- '.',
- VERSION_PATCH_INIT,
- '\0'};
+// Macro to convert a number to a string
+# define STRINGIFY(x) #x
+# define TOSTRING(x) STRINGIFY(x)
-const unsigned char BuildVersion[] = {
+// Complete version as a string
+
+# 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 UCHAR CompleteVersion[] = HYPERDBG_COMPLETE_VERSION;
+
+const UCHAR BuildVersion[] = {
BUILD_YEAR_CH0,
BUILD_YEAR_CH1,
BUILD_YEAR_CH2,
@@ -187,12 +135,12 @@ const unsigned char BuildVersion[] = {
'\0'};
-const unsigned char BuildSignature[] = {
- VERSION_MAJOR_INIT,
+const UCHAR BuildSignature[] = {
+ TOSTRING(VERSION_MAJOR)[0],
'.',
- VERSION_MINOR_INIT,
+ TOSTRING(VERSION_MINOR)[0],
'.',
- VERSION_PATCH_INIT,
+ TOSTRING(VERSION_PATCH)[0],
'-',
BUILD_YEAR_CH0,
BUILD_YEAR_CH1,
@@ -210,7 +158,7 @@ const unsigned char BuildSignature[] = {
'\0'};
-#endif // SCRIPT_ENGINE_KERNEL_MODE
+#endif
//////////////////////////////////////////////////
// Message Tracing //
@@ -251,7 +199,7 @@ const unsigned char BuildSignature[] = {
* @details the maximum packet size for sending over serial
*
*/
-#define MaxSerialPacketSize 10 * NORMAL_PAGE_SIZE
+#define MaxSerialPacketSize 20 * NORMAL_PAGE_SIZE
/**
* @brief Final storage size of message tracing
@@ -429,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 //
@@ -623,7 +565,15 @@ const unsigned char BuildSignature[] = {
# define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF))
#endif // !HIBYTE
-#define MAX_TEMP_COUNT 128
+/**
+ * @brief Maximum number of stack buffer count in the script engine
+ */
+#define MAX_STACK_BUFFER_COUNT 256
+
+/**
+ * @brief Maximum number of variables that can be used in the script engine
+ */
+#define MAX_EXECUTION_COUNT 1000000
// TODO: Extract number of variables from input of ScriptEngine
// and allocate variableList Dynamically.
@@ -635,6 +585,128 @@ const unsigned char BuildSignature[] = {
// Debugger //
//////////////////////////////////////////////////
+/**
+ * @brief Segment selector registers in x86
+ *
+ */
+typedef enum _SEGMENT_REGISTERS
+{
+ ES = 0,
+ CS,
+ SS,
+ DS,
+ FS,
+ GS,
+ LDTR,
+ TR
+} SEGMENT_REGISTERS;
+
+/*
+ * @brief Windows IRQ Levels
+ */
+#define PASSIVE_LEVEL 0 // Passive release level
+#define LOW_LEVEL 0 // Lowest interrupt level
+#define APC_LEVEL 1 // APC interrupt level
+#define DISPATCH_LEVEL 2 // Dispatcher level
+#define CMCI_LEVEL 5 // CMCI handler level
+#define CLOCK_LEVEL 13 // Interval clock level
+#define IPI_LEVEL 14 // Interprocessor interrupt level
+#define DRS_LEVEL 14 // Deferred Recovery Service level
+#define POWER_LEVEL 14 // Power failure level
+#define PROFILE_LEVEL 15 // timer used for profiling.
+#define HIGH_LEVEL 15 // Highest interrupt level
+
+/**
+ * @brief Intel CPU flags in CR0
+ */
+#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 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
+ */
+#define KGDT64_NULL (0 * 16) // NULL descriptor
+#define KGDT64_R0_CODE (1 * 16) // kernel mode 64-bit code
+#define KGDT64_R0_DATA (1 * 16) + 8 // kernel mode 64-bit data (stack)
+#define KGDT64_R3_CMCODE (2 * 16) // user mode 32-bit code
+#define KGDT64_R3_DATA (2 * 16) + 8 // user mode 32-bit data
+#define KGDT64_R3_CODE (3 * 16) // user mode 64-bit code
+#define KGDT64_SYS_TSS (4 * 16) // kernel mode system task state
+#define KGDT64_R3_CMTEB (5 * 16) // user mode 32-bit TEB
+#define KGDT64_R0_CMCODE (6 * 16) // kernel mode 32-bit code
+#define KGDT64_LAST (7 * 16) // last entry
+
+/**
+ * @brief PCID Flags
+ *
+ */
+#define PCID_NONE 0x000
+#define PCID_MASK 0x003
+
+/**
+ * @brief The Microsoft Hypervisor interface defined constants
+ *
+ */
+#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
+ *
+ */
+#define CPUID_ADDR_WIDTH 0x80000008
+
+/**
+ * @brief CPUID Features
+ *
+ */
+#define CPUID_PROCESSOR_AND_PROCESSOR_FEATURE_IDENTIFIERS 0x00000001
+
+/**
+ * @brief Hypervisor reserved range for RDMSR and WRMSR
+ *
+ */
+#define RESERVED_MSR_RANGE_LOW 0x40000000
+#define RESERVED_MSR_RANGE_HI 0x400000F0
+
/**
* @brief Apply event modifications to all tags
*
diff --git a/hyperdbg/include/SDK/Headers/DataTypes.h b/hyperdbg/include/SDK/headers/DataTypes.h
similarity index 84%
rename from hyperdbg/include/SDK/Headers/DataTypes.h
rename to hyperdbg/include/SDK/headers/DataTypes.h
index 2935acdd..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 //
//////////////////////////////////////////////////
@@ -116,10 +149,17 @@ typedef enum _DEBUGGER_THREAD_PROCESS_TRACING
/**
* @brief Callback type that can be used to be used
- * as a custom ShowMessages function
+ * as a custom ShowMessages function (by passing message as a parameter)
*
*/
-typedef int (*Callback)(const char * Text);
+typedef int (*SendMessageWithParamCallback)(const char * Text);
+
+/**
+ * @brief Callback type that can be used to be used
+ * as a custom ShowMessages function (using shared buffer)
+ *
+ */
+typedef int (*SendMessageWithSharedBufferCallback)(VOID);
//////////////////////////////////////////////////
// Communications //
@@ -231,17 +271,9 @@ 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;
-/**
- * @brief check so the DEBUGGEE_UD_PAUSED_PACKET should be smaller than packet size
- *
- */
-static_assert(sizeof(DEBUGGEE_UD_PAUSED_PACKET) < PacketChunkSize,
- "err (static_assert), size of PacketChunkSize should be bigger than DEBUGGEE_UD_PAUSED_PACKET");
-
//////////////////////////////////////////////////
// Message Tracing Enums //
//////////////////////////////////////////////////
@@ -298,10 +330,37 @@ typedef struct _DIRECT_VMCALL_PARAMETERS
} DIRECT_VMCALL_PARAMETERS, *PDIRECT_VMCALL_PARAMETERS;
+//////////////////////////////////////////////////
+// Syscall Callbacks //
+//////////////////////////////////////////////////
+
+/**
+ * @brief The (optional) context parameters for the transparent-mode
+ *
+ */
+typedef struct _SYSCALL_CALLBACK_CONTEXT_PARAMS
+{
+ UINT64 OptionalParam1; // Optional parameter
+ UINT64 OptionalParam2; // Optional parameter
+ UINT64 OptionalParam3; // Optional parameter
+ UINT64 OptionalParam4; // Optional parameter
+
+} SYSCALL_CALLBACK_CONTEXT_PARAMS, *PSYSCALL_CALLBACK_CONTEXT_PARAMS;
+
//////////////////////////////////////////////////
// EPT Hook //
//////////////////////////////////////////////////
+/**
+ * @brief different type of memory addresses
+ *
+ */
+typedef enum _DEBUGGER_HOOK_MEMORY_TYPE
+{
+ DEBUGGER_MEMORY_HOOK_VIRTUAL_ADDRESS,
+ DEBUGGER_MEMORY_HOOK_PHYSICAL_ADDRESS
+} DEBUGGER_HOOK_MEMORY_TYPE;
+
/**
* @brief Temporary $context used in some EPT hook commands
*
@@ -319,12 +378,13 @@ typedef struct _EPT_HOOKS_CONTEXT
*/
typedef struct _EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR
{
- UINT64 StartAddress;
- UINT64 EndAddress;
- BOOLEAN SetHookForRead;
- BOOLEAN SetHookForWrite;
- BOOLEAN SetHookForExec;
- UINT64 Tag;
+ UINT64 StartAddress;
+ UINT64 EndAddress;
+ BOOLEAN SetHookForRead;
+ BOOLEAN SetHookForWrite;
+ BOOLEAN SetHookForExec;
+ DEBUGGER_HOOK_MEMORY_TYPE MemoryType;
+ UINT64 Tag;
} EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR, *PEPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR;
diff --git a/hyperdbg/include/SDK/Headers/ErrorCodes.h b/hyperdbg/include/SDK/headers/ErrorCodes.h
similarity index 80%
rename from hyperdbg/include/SDK/Headers/ErrorCodes.h
rename to hyperdbg/include/SDK/headers/ErrorCodes.h
index 3447c8f0..bf31a55c 100644
--- a/hyperdbg/include/SDK/Headers/ErrorCodes.h
+++ b/hyperdbg/include/SDK/headers/ErrorCodes.h
@@ -90,7 +90,7 @@
* @brief error, the debugger is already in transparent-mode
*
*/
-#define DEBUGGER_ERROR_DEBUGGER_ALREADY_UHIDE 0xc000000a
+#define DEBUGGER_ERROR_DEBUGGER_ALREADY_HIDE 0xc000000a
/**
* @brief error, invalid parameters in !e* e* commands
@@ -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
*
*/
@@ -519,6 +519,140 @@
*/
#define DEBUGGER_ERROR_THE_TARGET_EVENT_IS_DISABLED_BUT_CANNOT_BE_CLEARED_PRIRITY_BUFFER_IS_FULL 0xc000004f
+/**
+ * @brief error, not all cores are locked (probably due to a race condition in HyperDbg) in
+ * instant-event mechanism
+ *
+ */
+#define DEBUGGER_ERROR_NOT_ALL_CORES_ARE_LOCKED_FOR_APPLYING_INSTANT_EVENT 0xc0000050
+
+/**
+ * @brief error, switching to the target core is not possible because core is not locked
+ * (probably due to a race condition in HyperDbg)
+ *
+ */
+#define DEBUGGER_ERROR_TARGET_SWITCHING_CORE_IS_NOT_LOCKED 0xc0000051
+
+/**
+ * @brief error, invalid physical address
+ *
+ */
+#define DEBUGGER_ERROR_INVALID_PHYSICAL_ADDRESS 0xc0000052
+
+/**
+ * @brief error, could not perform APIC actions
+ *
+ */
+#define DEBUGGER_ERROR_APIC_ACTIONS_ERROR 0xc0000053
+
+/**
+ * @brief error, debugger is already not in the transparent-mode
+ *
+ */
+#define DEBUGGER_ERROR_DEBUGGER_ALREADY_UNHIDE 0xc0000054
+
+/**
+ * @brief error, the user debugger cannot be initialized
+ *
+ */
+#define DEBUGGER_ERROR_DEBUGGER_NOT_INITIALIZED 0xc0000055
+
+/**
+ * @brief error, cannot put EPT hooks on addresses above 512 GB
+ *
+ */
+#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
similarity index 96%
rename from hyperdbg/include/SDK/Headers/Events.h
rename to hyperdbg/include/SDK/headers/Events.h
index ce4e5678..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
*
@@ -273,6 +278,8 @@ typedef struct _DEBUGGER_EVENT_OPTIONS
UINT64 OptionalParam2; // Optional parameter
UINT64 OptionalParam3; // Optional parameter
UINT64 OptionalParam4; // Optional parameter
+ UINT64 OptionalParam5; // Optional parameter
+ UINT64 OptionalParam6; // Optional parameter
} DEBUGGER_EVENT_OPTIONS, *PDEBUGGER_EVENT_OPTIONS;
@@ -333,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;
//////////////////////////////////////////////////
@@ -350,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
@@ -394,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
@@ -413,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
new file mode 100644
index 00000000..d80122e3
--- /dev/null
+++ b/hyperdbg/include/SDK/headers/HardwareDebugger.h
@@ -0,0 +1,204 @@
+/**
+ * @file HardwareDebugger.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief HyperDbg's Hardware Debugger (hwdbg) types and constants
+ * @details This file contains definitions of hwdbg elements
+ * used in HyperDbg
+ * @version 0.9
+ * @date 2024-04-28
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Definitions //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Initial debuggee to debugger offset
+ *
+ */
+#define DEFAULT_INITIAL_DEBUGGEE_TO_DEBUGGER_OFFSET 0x200
+
+/**
+ * @brief Initial debugger to debuggee offset
+ *
+ */
+#define DEFAULT_INITIAL_DEBUGGER_TO_DEBUGGEE_OFFSET 0x0
+
+/**
+ * @brief Initial default buffer size (BRAN Size)
+ * @details Number of 4-Byte integers (256 * 4 Byte * 8 bits = 8-kilobits)
+ *
+ */
+#define DEFAULT_INITIAL_BRAM_BUFFER_SIZE 256
+
+/**
+ * @brief Path to read the sample of the instance info
+ *
+ */
+#define HWDBG_TEST_READ_INSTANCE_INFO_PATH "..\\..\\..\\..\\hwdbg\\sim\\hwdbg\\DebuggerModuleTestingBRAM\\bram_instance_info.txt"
+
+/**
+ * @brief Path to write the sample of the script buffer
+ *
+ */
+#define HWDBG_TEST_WRITE_SCRIPT_BUFFER_PATH "..\\..\\..\\..\\hwdbg\\src\\test\\bram\\script_buffer.hex.txt"
+
+/**
+ * @brief Path to write the sample of the instance info requests
+ *
+ */
+#define HWDBG_TEST_WRITE_INSTANCE_INFO_PATH "..\\..\\..\\..\\hwdbg\\src\\test\\bram\\instance_info.hex.txt"
+
+//////////////////////////////////////////////////
+// Enums //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Different action of hwdbg
+ * @warning This file should be changed along with hwdbg files
+ *
+ */
+typedef enum _HWDBG_ACTION_ENUMS
+{
+ hwdbgActionSendInstanceInfo = 1,
+ hwdbgActionConfigureScriptBuffer = 2,
+
+} HWDBG_ACTION_ENUMS;
+
+/**
+ * @brief Different responses come from hwdbg
+ * @warning This file should be changed along with hwdbg files
+ *
+ */
+typedef enum _HWDBG_RESPONSE_ENUMS
+{
+ hwdbgResponseSuccessOrErrorMessage = 1,
+ hwdbgResponseInstanceInfo = 2,
+
+} HWDBG_RESPONSE_ENUMS;
+
+/**
+ * @brief Different success or error codes in hwdbg
+ * @warning This file should be changed along with hwdbg files
+ *
+ */
+typedef enum _HWDBG_SUCCESS_OR_ERROR_ENUMS
+{
+ hwdbgOperationWasSuccessful = 0x7FFFFFFF,
+ hwdbgErrorInvalidPacket = 1,
+
+} HWDBG_SUCCESS_OR_ERROR_ENUMS;
+
+//////////////////////////////////////////////////
+// Structures //
+//////////////////////////////////////////////////
+
+/**
+ * @brief The structure of port information (each item) in hwdbg
+ *
+ */
+typedef struct _HWDBG_PORT_INFORMATION_ITEMS
+{
+ UINT32 PortSize;
+
+} HWDBG_PORT_INFORMATION_ITEMS, *PHWDBG_PORT_INFORMATION_ITEMS;
+
+/**
+ * @brief The structure of script capabilities information in hwdbg
+ *
+ */
+#pragma pack(push, 4) // This is to make sure the structure is packed (without padding alignment)
+typedef struct _HWDBG_INSTANCE_INFORMATION
+{
+ //
+ // ANY ADDITION TO THIS STRUCTURE SHOULD BE SYNCHRONIZED WITH SCALA AND INSTANCE INFO SENDER MODULE
+ //
+ UINT32 version; // Target version of HyperDbg (same as hwdbg)
+ UINT32 maximumNumberOfStages; // Number of stages that this instance of hwdbg supports (NumberOfSupportedStages == 0 means script engine is disabled)
+ UINT32 scriptVariableLength; // Maximum length of variables (and other script elements)
+ UINT32 numberOfSupportedLocalAndGlobalVariables; // Number of supported local (and global) variables
+ UINT32 numberOfSupportedTemporaryVariables; // Number of supported temporary variables
+ UINT32 maximumNumberOfSupportedGetScriptOperators; // Maximum supported GET operators in a single func
+ UINT32 maximumNumberOfSupportedSetScriptOperators; // Maximum supported SET operators in a single func
+ UINT32 sharedMemorySize; // Size of shared memory
+ UINT32 debuggerAreaOffset; // The memory offset of debugger
+ UINT32 debuggeeAreaOffset; // The memory offset of debuggee
+ UINT32 numberOfPins; // Number of pins
+ UINT32 numberOfPorts; // Number of ports
+
+ //
+ // ANY ADDITION TO THIS STRUCTURE SHOULD BE SYNCHRONIZED WITH SCALA AND INSTANCE INFO SENDER MODULE
+ //
+
+ struct _HWDBG_SCRIPT_CAPABILITIES
+ {
+ //
+ // ANY ADDITION TO THIS MASK SHOULD BE ADDED TO HwdbgInterpreterShowScriptCapabilities
+ // and HwdbgInterpreterCheckScriptBufferWithScriptCapabilities as well Scala file
+ //
+ UINT64 assign_local_global_var : 1;
+ UINT64 assign_registers : 1;
+ UINT64 assign_pseudo_registers : 1;
+ UINT64 conditional_statements_and_comparison_operators : 1;
+ UINT64 stack_assignments : 1;
+
+ UINT64 func_or : 1;
+ UINT64 func_xor : 1;
+ UINT64 func_and : 1;
+ UINT64 func_asr : 1;
+ UINT64 func_asl : 1;
+ UINT64 func_add : 1;
+ UINT64 func_sub : 1;
+ UINT64 func_mul : 1;
+ UINT64 func_div : 1;
+ UINT64 func_mod : 1;
+ UINT64 func_gt : 1;
+ UINT64 func_lt : 1;
+ UINT64 func_egt : 1;
+ UINT64 func_elt : 1;
+ UINT64 func_equal : 1;
+ UINT64 func_neq : 1;
+ UINT64 func_jmp : 1;
+ UINT64 func_jz : 1;
+ UINT64 func_jnz : 1;
+ UINT64 func_mov : 1;
+ UINT64 func_printf : 1;
+
+ //
+ // ANY ADDITION TO THIS MASK SHOULD BE ADDED TO HwdbgInterpreterShowScriptCapabilities
+ // and HwdbgInterpreterCheckScriptBufferWithScriptCapabilities as well Scala file
+ //
+
+ } scriptCapabilities;
+
+ UINT32 bramAddrWidth; // BRAM address width
+ UINT32 bramDataWidth; // BRAM data width
+
+ //
+ // Here the details of port arrangements are located (HWDBG_PORT_INFORMATION_ITEMS)
+ // As the following type:
+ // HWDBG_PORT_INFORMATION_ITEMS portsConfiguration[numberOfPorts] ; Port arrangement
+ //
+
+} HWDBG_INSTANCE_INFORMATION, *PHWDBG_INSTANCE_INFORMATION;
+#pragma pack(pop) // This is to make sure the structure is packed (without padding alignment)
+
+/**
+ * @brief The structure of script buffer in hwdbg
+ *
+ */
+typedef struct _HWDBG_SCRIPT_BUFFER
+{
+ UINT32 scriptNumberOfSymbols; // Number of symbols in the script
+
+ //
+ // Here the script buffer is located
+ //
+ // UINT8 scriptBuffer[scriptNumberOfSymbols]; // The script buffer
+ //
+
+} HWDBG_SCRIPT_BUFFER, *PHWDBG_SCRIPT_BUFFER;
diff --git a/hyperdbg/include/SDK/headers/Ioctls.h b/hyperdbg/include/SDK/headers/Ioctls.h
new file mode 100644
index 00000000..20a2057a
--- /dev/null
+++ b/hyperdbg/include/SDK/headers/Ioctls.h
@@ -0,0 +1,430 @@
+/**
+ * @file Ioctls.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief HyperDbg's SDK IOCTL codes
+ * @details This file contains definitions of IOCTLs used in HyperDbg
+ * @version 0.2
+ * @date 2022-06-24
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Definitions //
+//////////////////////////////////////////////////
+
+//
+// The following controls are mainly defined in
+//
+
+//
+// Macro definition for defining IOCTL and FSCTL function control codes. Note
+// that function codes 0-2047 are reserved for Microsoft Corporation, and
+// 2048-4095 are reserved for customers.
+//
+#ifndef CTL_CODE
+
+# define CTL_CODE(DeviceType, Function, Method, Access) ( \
+ ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
+
+#endif // ! CTL_CODE
+
+#ifndef FILE_ANY_ACCESS
+
+# define FILE_ANY_ACCESS 0
+
+#endif // !FILE_ANY_ACCESS
+
+//
+// Define the method codes for how buffers are passed for I/O and FS controls
+//
+
+#ifndef METHOD_BUFFERED
+
+# define METHOD_BUFFERED 0
+
+#endif // !METHOD_BUFFERED
+
+#ifndef FILE_DEVICE_UNKNOWN
+
+# define FILE_DEVICE_UNKNOWN 0x00000022
+
+#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
+
+//////////////////////////////////////////////////
+// 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, 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, 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, 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, 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, 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, IOCTL_VMM_IOCTL + 0x04, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+/**
+ * @brief ioctl, register an event
+ *
+ */
+#define IOCTL_DEBUGGER_REGISTER_EVENT \
+ 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, 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, 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, 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, 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, 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, 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, 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, IOCTL_VMM_IOCTL + 0x0d, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+/**
+ * @brief ioctl, print states (Deprecated)
+ *
+ *
+ */
+#define IOCTL_DEBUGGER_PRINT \
+ 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, 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, 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, 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, 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, IOCTL_VMM_IOCTL + 0x13, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+/**
+ * @brief ioctl, to perform kernel-side tests
+ *
+ */
+#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, 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, 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, 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, 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, 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, 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, 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, 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, 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, IOCTL_VMM_IOCTL + 0x1e, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+/**
+ * @brief ioctl, to preactivate a functionality
+ *
+ */
+#define IOCTL_PREACTIVATE_FUNCTIONALITY \
+ 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, IOCTL_VMM_IOCTL + 0x20, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+/**
+ * @brief ioctl, to perform actions related to APIC
+ *
+ */
+#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, 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, 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, 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/Pcie.h b/hyperdbg/include/SDK/headers/Pcie.h
new file mode 100644
index 00000000..dabfdfbe
--- /dev/null
+++ b/hyperdbg/include/SDK/headers/Pcie.h
@@ -0,0 +1,176 @@
+/**
+ * @file Pcie.h
+ * @author Bjrn Ruytenberg (bjorn@bjornweb.nl)
+ * @brief PCIe-related data structures
+ * @details
+ * @version 0.10.3
+ * @date 2024-10-30
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+#pragma pack(1)
+
+//////////////////////////////////////////////////
+// Headers //
+//////////////////////////////////////////////////
+
+//
+// TODO
+// - Add support for domains beyond 0000
+// - Add ECAM support
+//
+// PCIe Base Specification, Rev. 4.0, Version 1.0, Table 7-59: Link Address for Link Type 1
+// Bus: 0-255 (8 bit)
+// Device: 0-31 (5 bit)
+// Function: 0-7 (3 bit)
+//
+#define BUS_BIT_WIDTH 8
+#define DEVICE_BIT_WIDTH 5
+#define FUNCTION_BIT_WIDTH 3
+
+//
+// NOTE
+// On real-world systems, the number of endpoints will likely not exceed 255.
+// If increasing DEV_MAX_NUM is necessary, ensure PCI_DEV_MINIMAL[DEV_MAX_NUM] does not result in exceeding MaxSerialPacketSize.
+//
+#define DOMAIN_MAX_NUM 0
+#define BUS_MAX_NUM 255
+#define DEVICE_MAX_NUM 32
+#define FUNCTION_MAX_NUM 8
+#define DEV_MAX_NUM 255
+#define CAM_CONFIG_SPACE_LENGTH 255
+
+/**
+ * @brief PCI Common Header
+ *
+ */
+typedef struct _PORTABLE_PCI_COMMON_HEADER
+{
+ UINT16 VendorId;
+ UINT16 DeviceId;
+ UINT16 Command;
+ UINT16 Status;
+ UINT8 RevisionId;
+ UINT8 ClassCode[3];
+ UINT8 CacheLineSize;
+ UINT8 PrimaryLatencyTimer;
+ UINT8 HeaderType;
+ UINT8 Bist;
+} PORTABLE_PCI_COMMON_HEADER, *PPORTABLE_PCI_COMMON_HEADER;
+
+/**
+ * @brief PCI Device Header
+ *
+ */
+typedef union _PORTABLE_PCI_DEVICE_HEADER
+{
+ struct _PORTABLE_PCI_EP_HEADER
+ {
+ UINT32 Bar[6]; // Base Address Registers
+ UINT32 CardBusCISPtr; // CardBus CIS Pointer
+ UINT16 SubVendorId; // Subsystem Vendor ID
+ UINT16 SubSystemId; // Subsystem ID
+ UINT32 ROMBar; // Expansion ROM Base Address
+ UINT8 CapabilitiesPtr; // Capabilities Pointer
+ UINT8 Reserved[3];
+ UINT32 Reserved1;
+ UINT8 InterruptLine; // Interrupt Line
+ UINT8 InterruptPin; // Interrupt Pin
+ UINT8 MinGnt; // Min_Gnt
+ UINT8 MaxLat; // Max_Lat
+ } ConfigSpaceEp;
+
+ struct _PORTABLE_PCI_BRIDGE_HEADER
+ {
+ UINT32 Bar[2];
+ UINT8 PrimaryBusNumber;
+ UINT8 SecondaryBusNumber;
+ UINT8 SubordinateBusNumber;
+ UINT8 SecondaryLatencyTimer;
+ UINT8 IoBase;
+ UINT8 IoLimit;
+ UINT16 SecondaryStatus;
+ UINT16 MemoryBase;
+ UINT16 MemoryLimit;
+ UINT16 PrefetchableMemoryBase;
+ UINT16 PrefetchableMemoryLimit;
+ UINT32 PrefetchableBaseUpper32b;
+ UINT32 PrefetchableLimitUpper32b;
+ UINT16 IoBaseUpper16b;
+ UINT16 IoLimitUpper16b;
+ UINT8 CapabilityPtr;
+ UINT8 Reserved[3];
+ UINT32 ROMBar;
+ UINT8 InterruptLine;
+ UINT8 InterruptPin;
+ UINT16 BridgeControl;
+ } ConfigSpacePtpBridge;
+
+ // TODO: Add support for HeaderType 0x2 (PCI-to-CardBus bridge)
+} PORTABLE_PCI_DEVICE_HEADER, *PPORTABLE_PCI_DEVICE_HEADER;
+
+/**
+ * @brief PCI Configuration Space Minimal Header for !pcitree
+ *
+ */
+typedef struct _PORTABLE_PCI_CONFIG_SPACE_HEADER_MINIMAL
+{
+ //
+ // Common header
+ //
+ UINT16 VendorId;
+ UINT16 DeviceId;
+ UINT8 ClassCode[3];
+} PORTABLE_PCI_CONFIG_SPACE_HEADER_MINIMAL, *PPORTABLE_PCI_CONFIG_SPACE_HEADER_MINIMAL;
+
+/**
+ * @brief PCI Device Minimal Data Structure for !pcitree
+ *
+ */
+typedef struct _PCI_DEV_MINIMAL
+{
+ UINT8 Bus : BUS_BIT_WIDTH;
+ UINT8 Device : DEVICE_BIT_WIDTH;
+ UINT8 Function : FUNCTION_BIT_WIDTH;
+ PORTABLE_PCI_CONFIG_SPACE_HEADER_MINIMAL ConfigSpace;
+} PCI_DEV_MINIMAL, *PPCI_DEV_MINIMAL;
+
+/**
+ * @brief PCI Device MMIO BAR Metadata
+ *
+ */
+typedef struct _PCI_DEV_MMIOBAR_INFO
+{
+ BOOL Is64Bit;
+ BOOL IsEnabled;
+ UINT64 BarOffsetEnd;
+ UINT64 BarSize;
+} PCI_DEV_MMIOBAR_INFO, *PPCI_DEV_MMIOBAR_INFO;
+
+/**
+ * @brief PCI Configuration Space Header
+ *
+ */
+typedef struct _PORTABLE_PCI_CONFIG_SPACE_HEADER
+{
+ PORTABLE_PCI_COMMON_HEADER CommonHeader;
+ PORTABLE_PCI_DEVICE_HEADER DeviceHeader;
+} PORTABLE_PCI_CONFIG_SPACE_HEADER, *PPORTABLE_PCI_CONFIG_SPACE_HEADER;
+
+/**
+ * @brief PCI Device Data Structure
+ *
+ */
+typedef struct _PCI_DEV
+{
+ UINT8 Bus : BUS_BIT_WIDTH;
+ UINT8 Device : DEVICE_BIT_WIDTH;
+ UINT8 Function : FUNCTION_BIT_WIDTH;
+ PORTABLE_PCI_CONFIG_SPACE_HEADER ConfigSpace;
+ BYTE ConfigSpaceAdditional[CAM_CONFIG_SPACE_LENGTH - sizeof(PORTABLE_PCI_CONFIG_SPACE_HEADER)];
+ PCI_DEV_MMIOBAR_INFO MmioBarInfo[6];
+} PCI_DEV, *PPCI_DEV;
+
+#pragma pack()
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
similarity index 58%
rename from hyperdbg/include/SDK/Headers/RequestStructures.h
rename to hyperdbg/include/SDK/headers/RequestStructures.h
index 64e04cbe..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
@@ -10,6 +11,37 @@
*
*/
#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)
@@ -40,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)
@@ -60,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)
@@ -79,8 +110,7 @@ typedef struct _DEBUGGER_PAGE_IN_REQUEST
} DEBUGGER_PAGE_IN_REQUEST, *PDEBUGGER_PAGE_IN_REQUEST;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief different modes of reconstruct requests
@@ -121,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)
@@ -133,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
@@ -178,8 +206,7 @@ typedef struct _DEBUGGER_PREALLOC_COMMAND
} DEBUGGER_PREALLOC_COMMAND, *PDEBUGGER_PREALLOC_COMMAND;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief different types of preactivate requests
@@ -205,8 +232,7 @@ typedef struct _DEBUGGER_PREACTIVATE_COMMAND
} DEBUGGER_PREACTIVATE_COMMAND, *PDEBUGGER_PREACTIVATE_COMMAND;
-/* ==============================================================================================
- */
+// ==============================================================================================
#define SIZEOF_DEBUGGER_READ_MEMORY sizeof(DEBUGGER_READ_MEMORY)
@@ -230,6 +256,17 @@ typedef enum _DEBUGGER_READ_MEMORY_TYPE
DEBUGGER_READ_VIRTUAL_ADDRESS
} DEBUGGER_READ_MEMORY_TYPE;
+/**
+ * @brief different address mode
+ *
+ */
+typedef enum _DEBUGGER_READ_MEMORY_ADDRESS_MODE
+{
+ DEBUGGER_READ_ADDRESS_MODE_32_BIT,
+ DEBUGGER_READ_ADDRESS_MODE_64_BIT
+
+} DEBUGGER_READ_MEMORY_ADDRESS_MODE;
+
/**
* @brief the way that debugger should show
* the details of memory or disassemble them
@@ -253,17 +290,15 @@ typedef enum _DEBUGGER_SHOW_MEMORY_STYLE
*/
typedef struct _DEBUGGER_READ_MEMORY
{
- UINT32 Pid; // Read from cr3 of what process
- UINT64 Address;
- UINT32 Size;
- BOOLEAN IsForDisasm; // Debugger sets whether the read memory is for diassembler or not
- BOOLEAN Is32BitAddress; // Debuggee sets the status of address
- DEBUGGER_READ_MEMORY_TYPE MemoryType;
- DEBUGGER_READ_READING_TYPE ReadingType;
- PDEBUGGER_DT_COMMAND_OPTIONS DtDetails;
- DEBUGGER_SHOW_MEMORY_STYLE Style; // not used in local debugging
- UINT32 ReturnLength; // not used in local debugging
- UINT32 KernelStatus; // not used in local debugging
+ UINT32 Pid; // Read from cr3 of what process
+ UINT64 Address;
+ UINT32 Size;
+ BOOLEAN GetAddressMode; // Debugger sets whether the read memory is for diassembler or not
+ DEBUGGER_READ_MEMORY_ADDRESS_MODE AddressMode; // Debuggee sets the mode of address
+ DEBUGGER_READ_MEMORY_TYPE MemoryType;
+ DEBUGGER_READ_READING_TYPE ReadingType;
+ UINT32 ReturnLength; // not used in local debugging
+ UINT32 KernelStatus; // not used in local debugging
//
// Here is the target buffer (actual memory)
@@ -271,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)
@@ -289,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)
@@ -328,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)
@@ -344,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)
@@ -361,26 +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_KERNEL_AND_USER_TEST_INFORMATION \
- sizeof(DEBUGGEE_KERNEL_AND_USER_TEST_INFORMATION)
-
-/**
- * @brief request for collecting debuggee's kernel-side test information
- *
- */
-typedef struct _DEBUGGEE_KERNEL_AND_USER_TEST_INFORMATION
-{
- UINT64 Value;
- char Tag[32];
-
-} DEBUGGEE_KERNEL_AND_USER_TEST_INFORMATION,
- *PDEBUGGEE_KERNEL_AND_USER_TEST_INFORMATION;
-
-/* ==============================================================================================
- */
+// ==============================================================================================
#define SIZEOF_DEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER \
sizeof(DEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER)
@@ -403,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)
@@ -425,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)
@@ -447,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)
@@ -468,8 +479,8 @@ typedef struct _DEBUGGER_READ_AND_WRITE_ON_MSR
*/
typedef enum _DEBUGGER_EDIT_MEMORY_TYPE
{
- EDIT_PHYSICAL_MEMORY,
- EDIT_VIRTUAL_MEMORY
+ EDIT_VIRTUAL_MEMORY,
+ EDIT_PHYSICAL_MEMORY
} DEBUGGER_EDIT_MEMORY_TYPE;
/**
@@ -489,19 +500,17 @@ typedef enum _DEBUGGER_EDIT_MEMORY_BYTE_SIZE
*/
typedef struct _DEBUGGER_EDIT_MEMORY
{
- UINT32 Result; // Result from kernel
+ UINT32 Result;
UINT64 Address; // Target address to modify
UINT32 ProcessId; // specifies the process id
DEBUGGER_EDIT_MEMORY_TYPE MemoryType; // Type of memory
DEBUGGER_EDIT_MEMORY_BYTE_SIZE ByteSize; // Modification size
UINT32 CountOf64Chunks;
UINT32 FinalStructureSize;
- UINT32 KernelStatus; // not used in local debugging
} DEBUGGER_EDIT_MEMORY, *PDEBUGGER_EDIT_MEMORY;
-/* ==============================================================================================
- */
+// ==============================================================================================
#define SIZEOF_DEBUGGER_SEARCH_MEMORY sizeof(DEBUGGER_SEARCH_MEMORY)
@@ -545,8 +554,36 @@ typedef struct _DEBUGGER_SEARCH_MEMORY
} DEBUGGER_SEARCH_MEMORY, *PDEBUGGER_SEARCH_MEMORY;
-/* ==============================================================================================
+// ==============================================================================================
+
+/**
+ * @brief Windows System call values that are intercepted by transparency mode
+ *
+ * NOTE: Windows system calls can change values on each version
+ * This structure is used to keep track of the system call numbers
+ * based on the current running Windows version
+ *
*/
+typedef struct _SYSTEM_CALL_NUMBERS_INFORMATION
+{
+ UINT32 SysNtQuerySystemInformation;
+ UINT32 SysNtQuerySystemInformationEx; // On 24H2, changes on each windows version
+
+ UINT32 SysNtSystemDebugControl; // On 24H2, changes on each windows version
+ UINT32 SysNtQueryAttributesFile;
+ UINT32 SysNtOpenDirectoryObject;
+ UINT32 SysNtQueryDirectoryObject; // On 24H2, changes on each windows version
+ UINT32 SysNtQueryInformationProcess;
+ UINT32 SysNtSetInformationProcess;
+ UINT32 SysNtQueryInformationThread;
+ UINT32 SysNtSetInformationThread;
+ UINT32 SysNtOpenFile;
+ UINT32 SysNtOpenKey;
+ UINT32 SysNtOpenKeyEx; // On 24H2, changes on each windows version
+ UINT32 SysNtQueryValueKey;
+ UINT32 SysNtEnumerateKey;
+
+} SYSTEM_CALL_NUMBERS_INFORMATION, *PSYSTEM_CALL_NUMBERS_INFORMATION;
#define SIZEOF_DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE \
sizeof(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE)
@@ -559,28 +596,30 @@ typedef struct _DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE
{
BOOLEAN IsHide;
- UINT64 CpuidAverage;
- UINT64 CpuidStandardDeviation;
- UINT64 CpuidMedian;
+ // UINT64 CpuidAverage;
+ // UINT64 CpuidStandardDeviation;
+ // UINT64 CpuidMedian;
- UINT64 RdtscAverage;
- UINT64 RdtscStandardDeviation;
- UINT64 RdtscMedian;
+ // UINT64 RdtscAverage;
+ // UINT64 RdtscStandardDeviation;
+ // UINT64 RdtscMedian;
BOOLEAN TrueIfProcessIdAndFalseIfProcessName;
UINT32 ProcId;
- UINT32 LengthOfProcessName; // in the case of !hide name xxx, this parameter
- // shows the length of xxx
+ UINT32 LengthOfProcessName;
- UINT64 KernelStatus; /* DEBUGGER_OPERATION_WAS_SUCCESSFUL ,
+ SYSTEM_CALL_NUMBERS_INFORMATION SystemCallNumbersInformation; // System call numbers information
+
+ UINT32 KernelStatus; /* DEBUGGER_OPERATION_WAS_SUCCESSFUL ,
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)
@@ -592,14 +631,13 @@ typedef struct _DEBUGGER_PREPARE_DEBUGGEE
{
UINT32 PortAddress;
UINT32 Baudrate;
- UINT64 NtoskrnlBaseAddress;
+ UINT64 KernelBaseAddress;
UINT32 Result; // Result from the kernel
CHAR OsName[MAXIMUM_CHARACTER_FOR_OS_NAME];
} DEBUGGER_PREPARE_DEBUGGEE, *PDEBUGGER_PREPARE_DEBUGGEE;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief The structure of changing core packet in HyperDbg
@@ -612,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)
@@ -627,6 +665,7 @@ typedef enum _DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_TYPE
DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_DETACH,
DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_REMOVE_HOOKS,
DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_KILL_PROCESS,
+ DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_CONTINUE_PROCESS,
DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_PAUSE_PROCESS,
DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_SWITCH_BY_PROCESS_OR_THREAD,
DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_QUERY_COUNT_OF_ACTIVE_DEBUGGING_THREADS,
@@ -644,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;
@@ -653,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)
@@ -760,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
@@ -811,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)
@@ -820,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
@@ -865,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
@@ -876,8 +919,9 @@ 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_CONTINUE,
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;
@@ -905,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
@@ -942,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
@@ -990,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
@@ -1032,8 +1076,466 @@ typedef struct _DEBUGGEE_STEP_PACKET
*/
#define DEBUGGER_REMOTE_TRACKING_DEFAULT_COUNT_OF_STEPPING 0xffffffff
-/* ==============================================================================================
+// ==============================================================================================
+
+/**
+ * @brief Perform actions related to APIC
+ *
*/
+typedef enum _DEBUGGER_APIC_REQUEST_TYPE
+{
+ DEBUGGER_APIC_REQUEST_TYPE_READ_LOCAL_APIC,
+ DEBUGGER_APIC_REQUEST_TYPE_READ_IO_APIC,
+
+} DEBUGGER_APIC_REQUEST_TYPE;
+
+/**
+ * @brief The structure of actions for APIC
+ *
+ */
+typedef struct _DEBUGGER_APIC_REQUEST
+{
+ DEBUGGER_APIC_REQUEST_TYPE ApicType;
+ BOOLEAN IsUsingX2APIC;
+ UINT32 KernelStatus;
+
+} DEBUGGER_APIC_REQUEST, *PDEBUGGER_APIC_REQUEST;
+
+/**
+ * @brief Debugger size of DEBUGGER_APIC_REQUEST
+ *
+ */
+#define SIZEOF_DEBUGGER_APIC_REQUEST \
+ sizeof(DEBUGGER_APIC_REQUEST)
+
+/**
+ * @brief LAPIC structure size
+ */
+#define LAPIC_SIZE 0x400
+
+#define LAPIC_LVT_FLAG_ENTRY_MASKED (1UL << 16)
+#define LAPIC_LVT_DELIVERY_MODE_EXT_INT (7UL << 8)
+#define LAPIC_SVR_FLAG_SW_ENABLE (1UL << 8)
+
+/**
+ * @brief LAPIC structure and offsets
+ */
+typedef struct _LAPIC_PAGE
+{
+ UINT8 Reserved000[0x10];
+ UINT8 Reserved010[0x10];
+
+ UINT32 Id; // offset 0x020
+ UINT8 Reserved024[0x0C];
+
+ UINT32 Version; // offset 0x030
+ UINT8 Reserved034[0x0C];
+
+ UINT8 Reserved040[0x40];
+
+ UINT32 TPR; // offset 0x080
+ UINT8 Reserved084[0x0C];
+
+ UINT32 ArbitrationPriority; // offset 0x090
+ UINT8 Reserved094[0x0C];
+
+ UINT32 ProcessorPriority; // offset 0x0A0
+ UINT8 Reserved0A4[0x0C];
+
+ UINT32 EOI; // offset 0x0B0
+ UINT8 Reserved0B4[0x0C];
+
+ UINT32 RemoteRead; // offset 0x0C0
+ UINT8 Reserved0C4[0x0C];
+
+ UINT32 LogicalDestination; // offset 0x0D0
+ UINT8 Reserved0D4[0x0C];
+
+ UINT32 DestinationFormat; // offset 0x0E0
+ UINT8 Reserved0E4[0x0C];
+
+ UINT32 SpuriousInterruptVector; // offset 0x0F0
+ UINT8 Reserved0F4[0x0C];
+
+ UINT32 ISR[32]; // offset 0x100
+
+ UINT32 TMR[32]; // offset 0x180
+
+ UINT32 IRR[32]; // offset 0x200
+
+ UINT32 ErrorStatus; // offset 0x280
+ UINT8 Reserved284[0x0C];
+
+ UINT8 Reserved290[0x60];
+
+ UINT32 LvtCmci; // offset 0x2F0
+ UINT8 Reserved2F4[0x0C];
+
+ UINT32 IcrLow; // offset 0x300
+ UINT8 Reserved304[0x0C];
+
+ UINT32 IcrHigh; // offset 0x310
+ UINT8 Reserved314[0x0C];
+
+ UINT32 LvtTimer; // offset 0x320
+ UINT8 Reserved324[0x0C];
+
+ UINT32 LvtThermalSensor; // offset 0x330
+ UINT8 Reserved334[0x0C];
+
+ UINT32 LvtPerfMonCounters; // offset 0x340
+ UINT8 Reserved344[0x0C];
+
+ UINT32 LvtLINT0; // offset 0x350
+ UINT8 Reserved354[0x0C];
+
+ UINT32 LvtLINT1; // offset 0x360
+ UINT8 Reserved364[0x0C];
+
+ UINT32 LvtError; // offset 0x370
+ UINT8 Reserved374[0x0C];
+
+ UINT32 InitialCount; // offset 0x380
+ UINT8 Reserved384[0x0C];
+
+ UINT32 CurrentCount; // offset 0x390
+ UINT8 Reserved394[0x0C];
+
+ UINT8 Reserved3A0[0x40]; // offset 0x3A0
+
+ UINT32 DivideConfiguration; // offset 0x3E0
+ UINT8 Reserved3E4[0x0C];
+
+ UINT32 SelfIpi; // offset 0x3F0
+ UINT8 Reserved3F4[0x0C]; // valid only for X2APIC
+} LAPIC_PAGE, *PLAPIC_PAGE;
+
+// ==============================================================================================
+
+/**
+ * @brief Maximum number of I/O APIC entries
+ * @details Usually 256 entries are enough (but we allocate 400 for systems with more
+ * I/O APIC entries)
+ * We're not gonna make the packet bigger than it's needed
+ *
+ */
+#define MAX_NUMBER_OF_IO_APIC_ENTRIES 400
+
+/**
+ * @brief The structure of I/O APIC result packet in HyperDbg
+ *
+ */
+typedef struct _IO_APIC_ENTRY_PACKETS
+{
+ UINT64 ApicBasePa;
+ UINT64 ApicBaseVa;
+ UINT32 IoIdReg;
+ UINT32 IoLl;
+ UINT32 IoArbIdReg;
+ UINT64 LlLhData[MAX_NUMBER_OF_IO_APIC_ENTRIES];
+
+} IO_APIC_ENTRY_PACKETS, *PIO_APIC_ENTRY_PACKETS;
+
+/**
+ * @brief check so the IO_APIC_ENTRY_PACKETS should be smaller than packet size
+ *
+ */
+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
+ *
+ */
+#define MAX_NUMBER_OF_IDT_ENTRIES 256
+
+/**
+ * @brief The structure of IDT entries result packet in HyperDbg
+ *
+ */
+typedef struct _INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS
+{
+ UINT32 KernelStatus;
+ UINT64 IdtEntry[MAX_NUMBER_OF_IDT_ENTRIES];
+
+} INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS, *PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS;
+
+/**
+ * @brief Debugger size of INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS
+ *
+ */
+#define SIZEOF_INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS \
+ sizeof(INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS)
+
+/**
+ * @brief check so the INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS should be smaller than packet size
+ *
+ */
+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
@@ -1046,8 +1548,7 @@ typedef struct _DEBUGGEE_FORMATS_PACKET
} DEBUGGEE_FORMATS_PACKET, *PDEBUGGEE_FORMATS_PACKET;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief The structure of .sym reload packet in HyperDbg
@@ -1059,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
@@ -1078,6 +1578,13 @@ typedef struct _DEBUGGEE_BP_PACKET
} DEBUGGEE_BP_PACKET, *PDEBUGGEE_BP_PACKET;
+/**
+ * @brief Debugger size of DEBUGGEE_BP_PACKET
+ *
+ */
+#define SIZEOF_DEBUGGEE_BP_PACKET \
+ sizeof(DEBUGGEE_BP_PACKET)
+
/**
* @brief breakpoint modification types
*
@@ -1104,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
@@ -1121,8 +1627,7 @@ typedef enum _DEBUGGER_CONDITIONAL_JUMP_STATUS
} DEBUGGER_CONDITIONAL_JUMP_STATUS;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief The structure of script packet in HyperDbg
@@ -1133,6 +1638,7 @@ typedef struct _DEBUGGEE_SCRIPT_PACKET
UINT32 ScriptBufferSize;
UINT32 ScriptBufferPointer;
BOOLEAN IsFormat;
+ UINT64 FormatValue;
UINT32 Result;
//
@@ -1141,8 +1647,7 @@ typedef struct _DEBUGGEE_SCRIPT_PACKET
} DEBUGGEE_SCRIPT_PACKET, *PDEBUGGEE_SCRIPT_PACKET;
-/* ==============================================================================================
- */
+// ==============================================================================================
/**
* @brief The structure of result of search packet in HyperDbg
@@ -1155,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.
@@ -1164,11 +1668,72 @@ typedef struct _DEBUGGEE_RESULT_OF_SEARCH_PACKET
*/
typedef struct _DEBUGGEE_REGISTER_READ_DESCRIPTION
{
- UINT32 RegisterID; // the number is from REGS_ENUM
+ UINT32 RegisterId;
UINT64 Value;
UINT32 KernelStatus;
} DEBUGGEE_REGISTER_READ_DESCRIPTION, *PDEBUGGEE_REGISTER_READ_DESCRIPTION;
-/* ==============================================================================================
+// ==============================================================================================
+
+/**
+ * @brief Register Descriptor Structure to write on registers.
+ *
*/
+typedef struct _DEBUGGEE_REGISTER_WRITE_DESCRIPTION
+{
+ UINT32 RegisterId;
+ UINT64 Value;
+ UINT32 KernelStatus;
+
+} DEBUGGEE_REGISTER_WRITE_DESCRIPTION, *PDEBUGGEE_REGISTER_WRITE_DESCRIPTION;
+
+// ==============================================================================================
+
+#define SIZEOF_DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET \
+ sizeof(DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET)
+
+/**
+ * @brief Pcitree Request-Response Packet. Represents PCI device tree.
+ *
+ */
+typedef struct _DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET
+{
+ UINT32 KernelStatus;
+ UINT8 DeviceInfoListNum;
+ PCI_DEV_MINIMAL DeviceInfoList[DEV_MAX_NUM];
+
+} DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET, *PDEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET;
+
+/**
+ * @brief check so the DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET should be smaller than packet size
+ *
+ */
+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)
+
+/**
+ * @brief PCI device info Request-Response Packet, used by !pcicam and future PCI-related commands. Represents a PCI device.
+ *
+ */
+typedef struct _DEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET
+{
+ UINT32 KernelStatus;
+ BOOL PrintRaw;
+ PCI_DEV DeviceInfo;
+
+} DEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET, *PDEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET;
+
+/**
+ * @brief check so the DEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET should be smaller than packet size
+ *
+ */
+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
new file mode 100644
index 00000000..2a8f16fb
--- /dev/null
+++ b/hyperdbg/include/SDK/headers/ScriptEngineCommonDefinitions.h
@@ -0,0 +1,474 @@
+#pragma once
+#ifndef SCRIPT_ENGINE_COMMON_DEFINITIONS_H
+#define SCRIPT_ENGINE_COMMON_DEFINITIONS_H
+
+typedef struct SYMBOL
+{
+ long long unsigned Type;
+ long long unsigned Len;
+ long long unsigned Value;
+
+} SYMBOL, *PSYMBOL;
+
+#define SIZE_SYMBOL_WITHOUT_LEN sizeof(long long unsigned) * 2
+
+typedef struct HWDBG_SHORT_SYMBOL
+{
+ long long unsigned Type;
+ long long unsigned Value;
+
+} HWDBG_SHORT_SYMBOL, *PHWDBG_SHORT_SYMBOL;
+
+typedef struct SYMBOL_BUFFER {
+ PSYMBOL Head;
+ unsigned int Pointer;
+ unsigned int Size;
+ char* Message;
+} SYMBOL_BUFFER, * PSYMBOL_BUFFER;
+
+typedef struct SYMBOL_MAP
+{
+ char* Name;
+ long long unsigned Type;
+} SYMBOL_MAP, * PSYMBOL_MAP;
+
+typedef struct ACTION_BUFFER {
+ long long unsigned Tag;
+ long long unsigned CurrentAction;
+ char ImmediatelySendTheResults;
+ long long unsigned Context;
+ char CallingStage;
+} ACTION_BUFFER, *PACTION_BUFFER;
+
+#define SYMBOL_UNDEFINED 0
+#define SYMBOL_GLOBAL_ID_TYPE 1
+#define SYMBOL_LOCAL_ID_TYPE 2
+#define SYMBOL_NUM_TYPE 3
+#define SYMBOL_REGISTER_TYPE 4
+#define SYMBOL_PSEUDO_REG_TYPE 5
+#define SYMBOL_SEMANTIC_RULE_TYPE 6
+#define SYMBOL_TEMP_TYPE 7
+#define SYMBOL_STRING_TYPE 8
+#define SYMBOL_VARIABLE_COUNT_TYPE 9
+#define SYMBOL_INVALID 10
+#define SYMBOL_WSTRING_TYPE 11
+#define SYMBOL_FUNCTION_PARAMETER_ID_TYPE 12
+#define SYMBOL_RETURN_ADDRESS_TYPE 13
+#define SYMBOL_FUNCTION_PARAMETER_TYPE 14
+#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",
+"SYMBOL_GLOBAL_ID_TYPE",
+"SYMBOL_LOCAL_ID_TYPE",
+"SYMBOL_NUM_TYPE",
+"SYMBOL_REGISTER_TYPE",
+"SYMBOL_PSEUDO_REG_TYPE",
+"SYMBOL_SEMANTIC_RULE_TYPE",
+"SYMBOL_TEMP_TYPE",
+"SYMBOL_STRING_TYPE",
+"SYMBOL_VARIABLE_COUNT_TYPE",
+"SYMBOL_INVALID",
+"SYMBOL_WSTRING_TYPE",
+"SYMBOL_FUNCTION_PARAMETER_ID_TYPE",
+"SYMBOL_RETURN_ADDRESS_TYPE",
+"SYMBOL_FUNCTION_PARAMETER_TYPE",
+"SYMBOL_STACK_INDEX_TYPE",
+"SYMBOL_STACK_BASE_INDEX_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)
+#define INVALID 0x80000000
+#define LALR_ACCEPT 0x7fffffff
+
+
+
+#define FUNC_UNDEFINED 0
+#define FUNC_INC 1
+#define FUNC_DEC 2
+#define FUNC_REFERENCE 3
+#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_OR",
+"FUNC_XOR",
+"FUNC_AND",
+"FUNC_ASR",
+"FUNC_ASL",
+"FUNC_ADD",
+"FUNC_SUB",
+"FUNC_MUL",
+"FUNC_DIV",
+"FUNC_MOD",
+"FUNC_GT",
+"FUNC_LT",
+"FUNC_EGT",
+"FUNC_ELT",
+"FUNC_EQUAL",
+"FUNC_NEQ",
+"FUNC_JMP",
+"FUNC_JZ",
+"FUNC_JNZ",
+"FUNC_MOV",
+"FUNC_START_OF_DO_WHILE",
+"FUNC_START_OF_DO_WHILE_COMMANDS",
+"FUNC_END_OF_DO_WHILE",
+"FUNC_START_OF_FOR",
+"FUNC_FOR_INC_DEC",
+"FUNC_START_OF_FOR_OMMANDS",
+"FUNC_END_OF_IF",
+"FUNC_IGNORE_LVALUE",
+"FUNC_PUSH",
+"FUNC_POP",
+"FUNC_CALL",
+"FUNC_RET",
+"FUNC_PRINT",
+"FUNC_FORMATS",
+"FUNC_EVENT_ENABLE",
+"FUNC_EVENT_DISABLE",
+"FUNC_EVENT_CLEAR",
+"FUNC_TEST_STATEMENT",
+"FUNC_SPINLOCK_LOCK",
+"FUNC_SPINLOCK_UNLOCK",
+"FUNC_EVENT_SC",
+"FUNC_MICROSLEEP",
+"FUNC_PRINTF",
+"FUNC_PAUSE",
+"FUNC_FLUSH",
+"FUNC_EVENT_TRACE_STEP",
+"FUNC_EVENT_TRACE_STEP_IN",
+"FUNC_EVENT_TRACE_STEP_OUT",
+"FUNC_EVENT_TRACE_INSTRUMENTATION_STEP",
+"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",
+"FUNC_DB",
+"FUNC_DD",
+"FUNC_DW",
+"FUNC_DQ",
+"FUNC_NEG",
+"FUNC_HI",
+"FUNC_LOW",
+"FUNC_NOT",
+"FUNC_CHECK_ADDRESS",
+"FUNC_DISASSEMBLE_LEN",
+"FUNC_DISASSEMBLE_LEN32",
+"FUNC_DISASSEMBLE_LEN64",
+"FUNC_INTERLOCKED_INCREMENT",
+"FUNC_INTERLOCKED_DECREMENT",
+"FUNC_PHYSICAL_TO_VIRTUAL",
+"FUNC_VIRTUAL_TO_PHYSICAL",
+"FUNC_POI_PA",
+"FUNC_HI_PA",
+"FUNC_LOW_PA",
+"FUNC_DB_PA",
+"FUNC_DD_PA",
+"FUNC_DW_PA",
+"FUNC_DQ_PA",
+"FUNC_LBR_RESTORE_BY_FILTER",
+"FUNC_ED",
+"FUNC_EB",
+"FUNC_EQ",
+"FUNC_INTERLOCKED_EXCHANGE",
+"FUNC_INTERLOCKED_EXCHANGE_ADD",
+"FUNC_EB_PA",
+"FUNC_ED_PA",
+"FUNC_EQ_PA",
+"FUNC_INTERLOCKED_COMPARE_EXCHANGE",
+"FUNC_STRLEN",
+"FUNC_STRCMP",
+"FUNC_MEMCMP",
+"FUNC_STRNCMP",
+"FUNC_WCSLEN",
+"FUNC_WCSCMP",
+"FUNC_EVENT_INJECT_ERROR_CODE",
+"FUNC_MEMCPY",
+"FUNC_MEMCPY_PA",
+"FUNC_WCSNCMP",
+};
+
+typedef enum REGS_ENUM {
+ REGISTER_RAX = 0,
+ REGISTER_EAX = 1,
+ REGISTER_AX = 2,
+ REGISTER_AH = 3,
+ REGISTER_AL = 4,
+ REGISTER_RCX = 5,
+ REGISTER_ECX = 6,
+ REGISTER_CX = 7,
+ REGISTER_CH = 8,
+ REGISTER_CL = 9,
+ REGISTER_RDX = 10,
+ REGISTER_EDX = 11,
+ REGISTER_DX = 12,
+ REGISTER_DH = 13,
+ REGISTER_DL = 14,
+ REGISTER_RBX = 15,
+ REGISTER_EBX = 16,
+ REGISTER_BX = 17,
+ REGISTER_BH = 18,
+ REGISTER_BL = 19,
+ REGISTER_RSP = 20,
+ REGISTER_ESP = 21,
+ REGISTER_SP = 22,
+ REGISTER_SPL = 23,
+ REGISTER_RBP = 24,
+ REGISTER_EBP = 25,
+ REGISTER_BP = 26,
+ REGISTER_BPL = 27,
+ REGISTER_RSI = 28,
+ REGISTER_ESI = 29,
+ REGISTER_SI = 30,
+ REGISTER_SIL = 31,
+ REGISTER_RDI = 32,
+ REGISTER_EDI = 33,
+ REGISTER_DI = 34,
+ REGISTER_DIL = 35,
+ REGISTER_R8 = 36,
+ REGISTER_R8D = 37,
+ REGISTER_R8W = 38,
+ REGISTER_R8H = 39,
+ REGISTER_R8L = 40,
+ REGISTER_R9 = 41,
+ REGISTER_R9D = 42,
+ REGISTER_R9W = 43,
+ REGISTER_R9H = 44,
+ REGISTER_R9L = 45,
+ REGISTER_R10 = 46,
+ REGISTER_R10D = 47,
+ REGISTER_R10W = 48,
+ REGISTER_R10H = 49,
+ REGISTER_R10L = 50,
+ REGISTER_R11 = 51,
+ REGISTER_R11D = 52,
+ REGISTER_R11W = 53,
+ REGISTER_R11H = 54,
+ REGISTER_R11L = 55,
+ REGISTER_R12 = 56,
+ REGISTER_R12D = 57,
+ REGISTER_R12W = 58,
+ REGISTER_R12H = 59,
+ REGISTER_R12L = 60,
+ REGISTER_R13 = 61,
+ REGISTER_R13D = 62,
+ REGISTER_R13W = 63,
+ REGISTER_R13H = 64,
+ REGISTER_R13L = 65,
+ REGISTER_R14 = 66,
+ REGISTER_R14D = 67,
+ REGISTER_R14W = 68,
+ REGISTER_R14H = 69,
+ REGISTER_R14L = 70,
+ REGISTER_R15 = 71,
+ REGISTER_R15D = 72,
+ REGISTER_R15W = 73,
+ REGISTER_R15H = 74,
+ REGISTER_R15L = 75,
+ REGISTER_DS = 76,
+ REGISTER_ES = 77,
+ REGISTER_FS = 78,
+ REGISTER_GS = 79,
+ REGISTER_CS = 80,
+ REGISTER_SS = 81,
+ REGISTER_RFLAGS = 82,
+ REGISTER_EFLAGS = 83,
+ REGISTER_FLAGS = 84,
+ REGISTER_CF = 85,
+ REGISTER_PF = 86,
+ REGISTER_AF = 87,
+ REGISTER_ZF = 88,
+ REGISTER_SF = 89,
+ REGISTER_TF = 90,
+ REGISTER_IF = 91,
+ REGISTER_DF = 92,
+ REGISTER_OF = 93,
+ REGISTER_IOPL = 94,
+ REGISTER_NT = 95,
+ REGISTER_RF = 96,
+ REGISTER_VM = 97,
+ REGISTER_AC = 98,
+ REGISTER_VIF = 99,
+ REGISTER_VIP = 100,
+ REGISTER_ID = 101,
+ REGISTER_RIP = 102,
+ REGISTER_EIP = 103,
+ REGISTER_IP = 104,
+ REGISTER_IDTR = 105,
+ REGISTER_LDTR = 106,
+ REGISTER_GDTR = 107,
+ REGISTER_TR = 108,
+ REGISTER_CR0 = 109,
+ REGISTER_CR2 = 110,
+ REGISTER_CR3 = 111,
+ REGISTER_CR4 = 112,
+ REGISTER_CR8 = 113,
+ REGISTER_DR0 = 114,
+ REGISTER_DR1 = 115,
+ REGISTER_DR2 = 116,
+ REGISTER_DR3 = 117,
+ REGISTER_DR6 = 118,
+ REGISTER_DR7 = 119
+
+} REGS_ENUM;
+
+static const char *const RegistersNames[] = {
+"rax", "eax", "ax", "ah", "al", "rcx", "ecx", "cx",
+"ch", "cl", "rdx", "edx", "dx", "dh", "dl", "rbx",
+"ebx", "bx", "bh", "bl", "rsp", "esp", "sp", "spl",
+"rbp", "ebp", "bp", "bpl", "rsi", "esi", "si", "sil",
+"rdi", "edi", "di", "dil", "r8", "r8d", "r8w", "r8h",
+"r8l", "r9", "r9d", "r9w", "r9h", "r9l", "r10", "r10d",
+"r10w", "r10h", "r10l", "r11", "r11d", "r11w", "r11h", "r11l",
+"r12", "r12d", "r12w", "r12h", "r12l", "r13", "r13d", "r13w",
+"r13h", "r13l", "r14", "r14d", "r14w", "r14h", "r14l", "r15",
+"r15d", "r15w", "r15h", "r15l", "ds", "es", "fs", "gs",
+"cs", "ss", "rflags", "eflags", "flags", "cf", "pf", "af",
+"zf", "sf", "tf", "if", "df", "of", "iopl", "nt",
+"rf", "vm", "ac", "vif", "vip", "id", "rip", "eip",
+"ip", "idtr", "ldtr", "gdtr", "tr", "cr0", "cr2", "cr3",
+"cr4", "cr8", "dr0", "dr1", "dr2", "dr3", "dr6", "dr7"
+};
+
+#define PSEUDO_REGISTER_PID 0
+#define PSEUDO_REGISTER_TID 1
+#define PSEUDO_REGISTER_PNAME 2
+#define PSEUDO_REGISTER_CORE 3
+#define PSEUDO_REGISTER_PROC 4
+#define PSEUDO_REGISTER_THREAD 5
+#define PSEUDO_REGISTER_PEB 6
+#define PSEUDO_REGISTER_TEB 7
+#define PSEUDO_REGISTER_IP 8
+#define PSEUDO_REGISTER_BUFFER 9
+#define PSEUDO_REGISTER_CONTEXT 10
+#define PSEUDO_REGISTER_EVENT_TAG 11
+#define PSEUDO_REGISTER_EVENT_ID 12
+#define PSEUDO_REGISTER_EVENT_STAGE 13
+#define PSEUDO_REGISTER_DATE 14
+#define PSEUDO_REGISTER_TIME 15
+
+#endif
diff --git a/hyperdbg/include/SDK/Headers/Symbols.h b/hyperdbg/include/SDK/headers/Symbols.h
similarity index 89%
rename from hyperdbg/include/SDK/Headers/Symbols.h
rename to hyperdbg/include/SDK/headers/Symbols.h
index c67f3c45..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
@@ -77,13 +79,6 @@ typedef struct _DEBUGGER_UPDATE_SYMBOL_TABLE
} DEBUGGER_UPDATE_SYMBOL_TABLE, *PDEBUGGER_UPDATE_SYMBOL_TABLE;
-/**
- * @brief check so the DEBUGGER_UPDATE_SYMBOL_TABLE should be smaller than packet size
- *
- */
-static_assert(sizeof(DEBUGGER_UPDATE_SYMBOL_TABLE) < PacketChunkSize,
- "err (static_assert), size of PacketChunkSize should be bigger than DEBUGGER_UPDATE_SYMBOL_TABLE (MODULE_SYMBOL_DETAIL)");
-
/*
==============================================================================================
*/
diff --git a/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperEvade.h b/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperEvade.h
new file mode 100644
index 00000000..168167fb
--- /dev/null
+++ b/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperEvade.h
@@ -0,0 +1,59 @@
+/**
+ * @file HyperDbgHyperEvade.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Headers relating exported functions from hyperevade (transparency) module
+ * @version 0.14
+ * @date 2025-06-07
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#ifdef HYPERDBG_HYPEREVADE
+# define IMPORT_EXPORT_HYPEREVADE __declspec(dllexport)
+#else
+# define IMPORT_EXPORT_HYPEREVADE __declspec(dllimport)
+#endif
+
+//////////////////////////////////////////////////
+// hyperevade functions //
+//////////////////////////////////////////////////
+
+//
+// Initializing and uninitializing routines
+//
+IMPORT_EXPORT_HYPEREVADE BOOLEAN
+TransparentHideDebugger(HYPEREVADE_CALLBACKS * HyperevadeCallbacks,
+ DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE * TransparentModeRequest);
+
+IMPORT_EXPORT_HYPEREVADE BOOLEAN
+TransparentUnhideDebugger();
+
+//
+// VMX footprint routines
+//
+IMPORT_EXPORT_HYPEREVADE VOID
+TransparentCheckAndModifyCpuid(PGUEST_REGS Regs, INT32 CpuInfo[]);
+
+IMPORT_EXPORT_HYPEREVADE VOID
+TransparentCheckAndTrapFlagAfterVmexit();
+
+IMPORT_EXPORT_HYPEREVADE BOOLEAN
+TransparentCheckAndModifyMsrRead(PGUEST_REGS Regs, UINT32 TargetMsr);
+
+IMPORT_EXPORT_HYPEREVADE BOOLEAN
+TransparentCheckAndModifyMsrWrite(PGUEST_REGS Regs, UINT32 TargetMsr);
+
+//
+// Syscall footprint routines
+//
+IMPORT_EXPORT_HYPEREVADE VOID
+TransparentHandleSystemCallHook(GUEST_REGS * Regs);
+
+IMPORT_EXPORT_HYPEREVADE VOID
+TransparentCallbackHandleAfterSyscall(GUEST_REGS * Regs,
+ UINT32 ProcessId,
+ UINT32 ThreadId,
+ UINT64 Context,
+ SYSCALL_CALLBACK_CONTEXT_PARAMS * Params);
diff --git a/hyperdbg/include/SDK/Imports/HyperDbgHyperLogImports.h b/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperLogImports.h
similarity index 86%
rename from hyperdbg/include/SDK/Imports/HyperDbgHyperLogImports.h
rename to hyperdbg/include/SDK/imports/kernel/HyperDbgHyperLogImports.h
index ca9741c6..f3a388a3 100644
--- a/hyperdbg/include/SDK/Imports/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
@@ -57,8 +57,8 @@ LogCallbackCheckIfBufferIsFull(BOOLEAN Priority);
IMPORT_EXPORT_HYPERLOG BOOLEAN
LogCallbackSendMessageToQueue(UINT32 OperationCode, BOOLEAN IsImmediateMessage, CHAR * LogMessage, UINT32 BufferLen, BOOLEAN Priority);
-IMPORT_EXPORT_HYPERLOG NTSTATUS
-LogRegisterEventBasedNotification(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+IMPORT_EXPORT_HYPERLOG BOOLEAN
+LogRegisterEventBasedNotification(PVOID TargetIrp);
-IMPORT_EXPORT_HYPERLOG NTSTATUS
-LogRegisterIrpBasedNotification(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+IMPORT_EXPORT_HYPERLOG BOOLEAN
+LogRegisterIrpBasedNotification(PVOID TargetIrp, LONG * Status);
diff --git a/hyperdbg/include/SDK/Imports/HyperDbgHyperLogIntrinsics.h b/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperLogIntrinsics.h
similarity index 92%
rename from hyperdbg/include/SDK/Imports/HyperDbgHyperLogIntrinsics.h
rename to hyperdbg/include/SDK/imports/kernel/HyperDbgHyperLogIntrinsics.h
index 0605fefc..837fb661 100644
--- a/hyperdbg/include/SDK/Imports/HyperDbgHyperLogIntrinsics.h
+++ b/hyperdbg/include/SDK/imports/kernel/HyperDbgHyperLogIntrinsics.h
@@ -40,19 +40,19 @@ typedef enum _LOG_TYPE
DbgPrint("[+] Information (%s:%d) | " format "\n", \
__func__, \
__LINE__, \
- __VA_ARGS__)
+ ##__VA_ARGS__)
# define LogWarning(format, ...) \
DbgPrint("[-] Warning (%s:%d) | " format "\n", \
__func__, \
__LINE__, \
- __VA_ARGS__)
+ ##__VA_ARGS__)
# define LogError(format, ...) \
DbgPrint("[!] Error (%s:%d) | " format "\n", \
__func__, \
__LINE__, \
- __VA_ARGS__); \
+ ##__VA_ARGS__); \
DbgBreakPoint()
/**
@@ -60,7 +60,7 @@ typedef enum _LOG_TYPE
*
*/
# define Log(format, ...) \
- DbgPrint(format, __VA_ARGS__)
+ DbgPrint(format, ##__VA_ARGS__)
#else
@@ -76,7 +76,7 @@ typedef enum _LOG_TYPE
"[+] Information (%s:%d) | " format "\n", \
__func__, \
__LINE__, \
- __VA_ARGS__)
+ ##__VA_ARGS__)
/**
* @brief Log in the case of priority message
@@ -90,7 +90,7 @@ typedef enum _LOG_TYPE
"[+] Information (%s:%d) | " format "\n", \
__func__, \
__LINE__, \
- __VA_ARGS__)
+ ##__VA_ARGS__)
/**
* @brief Log in the case of warning
@@ -104,7 +104,7 @@ typedef enum _LOG_TYPE
"[-] Warning (%s:%d) | " format "\n", \
__func__, \
__LINE__, \
- __VA_ARGS__)
+ ##__VA_ARGS__)
/**
* @brief Log in the case of error
@@ -118,7 +118,7 @@ typedef enum _LOG_TYPE
"[!] Error (%s:%d) | " format "\n", \
__func__, \
__LINE__, \
- __VA_ARGS__); \
+ ##__VA_ARGS__); \
if (DebugMode) \
DbgBreakPoint()
@@ -132,7 +132,7 @@ typedef enum _LOG_TYPE
FALSE, \
FALSE, \
format, \
- __VA_ARGS__)
+ ##__VA_ARGS__)
/**
* @brief Log without any prefix and bypass the stack
@@ -161,4 +161,4 @@ typedef enum _LOG_TYPE
"[+] Information (%s:%d) | " format "\n", \
__func__, \
__LINE__, \
- __VA_ARGS__)
+ ##__VA_ARGS__)
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/HyperDbgVmmImports.h b/hyperdbg/include/SDK/imports/kernel/HyperDbgVmmImports.h
similarity index 83%
rename from hyperdbg/include/SDK/Imports/HyperDbgVmmImports.h
rename to hyperdbg/include/SDK/imports/kernel/HyperDbgVmmImports.h
index e15b633c..c64991a3 100644
--- a/hyperdbg/include/SDK/Imports/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);
@@ -155,6 +197,14 @@ VmFuncEnableMtfAndChangeExternalInterruptState(UINT32 CoreId);
IMPORT_EXPORT_VMM VOID
VmFuncEnableAndCheckForPreviousExternalInterrupts(UINT32 CoreId);
+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();
@@ -170,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();
@@ -183,7 +245,10 @@ 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);
IMPORT_EXPORT_VMM BOOLEAN
VmFuncNmiBroadcastRequest(UINT32 CoreId);
@@ -200,14 +265,35 @@ 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);
IMPORT_EXPORT_VMM INT32
-VmFuncVmxCompatibleWcscmp(const wchar_t * Address1, const wchar_t * Address2);
+VmFuncVmxCompatibleStrncmp(const CHAR * Address1, const CHAR * Address2, SIZE_T Num);
IMPORT_EXPORT_VMM INT32
-VmFuncVmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, size_t Count);
+VmFuncVmxCompatibleWcscmp(const WCHAR * Address1, const WCHAR * Address2);
+
+IMPORT_EXPORT_VMM INT32
+VmFuncVmxCompatibleWcsncmp(const WCHAR * Address1, const WCHAR * Address2, SIZE_T Num);
+
+IMPORT_EXPORT_VMM INT32
+VmFuncVmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, SIZE_T Count);
+
+IMPORT_EXPORT_VMM BOOLEAN
+VmFuncApicStoreLocalApicFields(PLAPIC_PAGE LocalApicBuffer, PBOOLEAN IsUsingX2APIC);
+
+IMPORT_EXPORT_VMM BOOLEAN
+VmFuncApicStoreIoApicFields(IO_APIC_ENTRY_PACKETS * IoApicPackets);
//////////////////////////////////////////////////
// Configuration Functions //
@@ -270,6 +356,9 @@ ConfigureModeBasedExecHookUninitializeOnAllProcessors();
IMPORT_EXPORT_VMM VOID
ConfigureUninitializeExecTrapOnAllProcessors();
+IMPORT_EXPORT_VMM VOID
+ConfigureExecTrapApplyMbecConfiguratinFromKernelSide(UINT32 CoreId);
+
IMPORT_EXPORT_VMM BOOLEAN
ConfigureInitializeExecTrapOnAllProcessors();
@@ -314,6 +403,13 @@ ConfigureEptHookModifyPageWriteState(UINT32 CoreId,
PVOID PhysicalAddress,
BOOLEAN IsUnset);
+IMPORT_EXPORT_VMM BOOLEAN
+ConfigureEptHookUnHookAllByHookingTag(UINT64 HookingTag);
+
+IMPORT_EXPORT_VMM BOOLEAN
+ConfigureEptHookUnHookSingleHookByHookingTagFromVmxRoot(UINT64 HookingTag,
+ EPT_SINGLE_HOOK_UNHOOKING_DETAILS * TargetUnhookingDetails);
+
IMPORT_EXPORT_VMM BOOLEAN
ConfigureEptHookUnHookSingleAddress(UINT64 VirtualAddress,
UINT64 PhysAddress,
@@ -495,6 +591,9 @@ CheckAddressValidityUsingTsx(CHAR * Address);
IMPORT_EXPORT_VMM BOOLEAN
CheckAccessValidityAndSafety(UINT64 TargetAddress, UINT32 Size);
+IMPORT_EXPORT_VMM BOOLEAN
+CheckAccessValidityAndSafetyByProcessId(UINT64 TargetAddress, UINT32 Size, UINT32 ProcessId);
+
IMPORT_EXPORT_VMM BOOLEAN
CheckAddressPhysical(UINT64 PAddr);
@@ -507,6 +606,9 @@ CheckAddressMaximumInstructionLength(PVOID Address);
IMPORT_EXPORT_VMM CR3_TYPE
LayoutGetCurrentProcessCr3();
+IMPORT_EXPORT_VMM CR3_TYPE
+LayoutGetCr3ByProcessId(UINT32 ProcessId);
+
IMPORT_EXPORT_VMM CR3_TYPE
LayoutGetExactGuestProcessCr3();
@@ -514,18 +616,6 @@ LayoutGetExactGuestProcessCr3();
// Memory Management Functions //
//////////////////////////////////////////////////
-// ----------------------------------------------------------------------------
-// Cross Platform Memory Allocate/Free Functions
-//
-IMPORT_EXPORT_VMM PVOID
-CrsAllocateNonPagedPool(SIZE_T NumberOfBytes);
-
-IMPORT_EXPORT_VMM PVOID
-CrsAllocateZeroedNonPagedPool(SIZE_T NumberOfBytes);
-
-IMPORT_EXPORT_VMM VOID
-CrsFreePool(PVOID BufferAddress);
-
// ----------------------------------------------------------------------------
// PTE-related Functions
//
@@ -574,6 +664,17 @@ MemoryMapperReadMemorySafeOnTargetProcess(_In_ UINT64 VaAddressToRead,
_Inout_ PVOID BufferToSaveMemory,
_In_ SIZE_T SizeToRead);
+IMPORT_EXPORT_VMM BOOLEAN
+MemoryMapperReadMemorySafeFromVmxNonRootByPhysicalAddress(_In_ UINT64 PaAddressToRead,
+ _Inout_ PVOID BufferToSaveMemory,
+ _In_ SIZE_T SizeToRead);
+
+IMPORT_EXPORT_VMM BOOLEAN
+MemoryMapperReadMemoryUnsafe(_In_ UINT64 VaAddressToRead,
+ _Inout_ PVOID BufferToSaveMemory,
+ _In_ SIZE_T SizeToRead,
+ _In_ UINT32 TargetProcessId);
+
// ----------------------------------------------------------------------------
// Disassembler Functions
//
@@ -583,6 +684,9 @@ DisassemblerLengthDisassembleEngine(PVOID Address, BOOLEAN Is32Bit);
IMPORT_EXPORT_VMM UINT32
DisassemblerLengthDisassembleEngineInVmxRootOnTargetProcess(PVOID Address, BOOLEAN Is32Bit);
+IMPORT_EXPORT_VMM UINT32
+DisassemblerLengthDisassembleEngineByProcessId(PVOID Address, BOOLEAN Is32Bit, UINT32 ProcessId);
+
// ----------------------------------------------------------------------------
// Writing Memory Functions
//
@@ -608,6 +712,11 @@ MemoryMapperWriteMemoryUnsafe(_Inout_ UINT64 Destination,
_In_ SIZE_T SizeToWrite,
_In_ UINT32 TargetProcessId);
+IMPORT_EXPORT_VMM BOOLEAN
+MemoryMapperWriteMemorySafeFromVmxNonRootyPhysicalAddress(_In_ UINT64 DestinationPa,
+ _In_ PVOID Source,
+ _In_ SIZE_T SizeToWrite);
+
// ----------------------------------------------------------------------------
// Reserving Memory Functions
//
@@ -641,24 +750,14 @@ MemoryMapperCheckIfPdeIsLargePageOnTargetProcess(_In_ PVOID Va);
IMPORT_EXPORT_VMM BOOLEAN
MemoryManagerReadProcessMemoryNormal(HANDLE PID, PVOID Address, DEBUGGER_READ_MEMORY_TYPE MemType, PVOID UserBuffer, SIZE_T Size, PSIZE_T ReturnSize);
-//////////////////////////////////////////////////
-// Pool Manager //
-//////////////////////////////////////////////////
+IMPORT_EXPORT_VMM BOOLEAN
+MemoryManagerWritePhysicalMemoryNormal(PVOID TargetAddress, PVOID UserBuffer, SIZE_T Size);
IMPORT_EXPORT_VMM BOOLEAN
-PoolManagerCheckAndPerformAllocationAndDeallocation();
+ReadPhysicalMemoryUsingMapIoSpace(PVOID PhysicalAddress, PVOID Buffer, SIZE_T BufferSize);
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();
+WritePhysicalMemoryUsingMapIoSpace(PVOID PhysicalAddress, PVOID Buffer, SIZE_T BufferSize);
//////////////////////////////////////////////////
// VMX Registers Modification //
@@ -830,11 +929,11 @@ SetDebugRegisters(UINT32 DebugRegNum, DEBUG_REGISTER_TYPE ActionType, BOOLEAN Ap
// Transparent Mode //
//////////////////////////////////////////////////
-IMPORT_EXPORT_VMM NTSTATUS
-TransparentHideDebugger(PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE Measurements);
+IMPORT_EXPORT_VMM BOOLEAN
+TransparentHideDebuggerWrapper(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE * TransparentModeRequest);
-IMPORT_EXPORT_VMM NTSTATUS
-TransparentUnhideDebugger();
+IMPORT_EXPORT_VMM BOOLEAN
+TransparentUnhideDebuggerWrapper(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE * TransparentModeRequest);
//////////////////////////////////////////////////
// Non-internal Broadcasting Functions //
@@ -929,3 +1028,13 @@ BroadcastEnableEferSyscallEventsOnAllProcessors();
IMPORT_EXPORT_VMM VOID
BroadcastDisableEferSyscallEventsOnAllProcessors();
+
+//////////////////////////////////////////////////
+// Device-related Functions //
+//////////////////////////////////////////////////
+
+IMPORT_EXPORT_VMM QWORD
+PciReadCam(WORD Bus, WORD Device, WORD Function, BYTE Offset, UINT8 Width);
+
+IMPORT_EXPORT_VMM BOOLEAN
+PciWriteCam(WORD Bus, WORD Device, WORD Function, BYTE Offset, UINT8 Width, QWORD Value);
diff --git a/hyperdbg/include/SDK/imports/user/HyperDbgLibImports.h b/hyperdbg/include/SDK/imports/user/HyperDbgLibImports.h
new file mode 100644
index 00000000..2491fca1
--- /dev/null
+++ b/hyperdbg/include/SDK/imports/user/HyperDbgLibImports.h
@@ -0,0 +1,369 @@
+/**
+ * @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
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#ifdef _WIN32
+// MSVC (Windows)
+# ifdef HYPERDBG_LIBHYPERDBG
+# define IMPORT_EXPORT_LIBHYPERDBG __declspec(dllexport)
+# else
+# define IMPORT_EXPORT_LIBHYPERDBG __declspec(dllimport)
+# endif
+#else
+// 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
+//
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//
+// Support Detection
+//
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+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
+//
+IMPORT_EXPORT_LIBHYPERDBG INT
+hyperdbg_u_load_vmm();
+
+IMPORT_EXPORT_LIBHYPERDBG INT
+hyperdbg_u_unload_vmm();
+
+//
+// KD (Kernel Debugger) Module
+//
+IMPORT_EXPORT_LIBHYPERDBG INT
+hyperdbg_u_unload_kd();
+
+IMPORT_EXPORT_LIBHYPERDBG INT
+hyperdbg_u_install_kd_driver();
+
+IMPORT_EXPORT_LIBHYPERDBG INT
+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
+//
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_test_command_parser(CHAR * command,
+ UINT32 number_of_tokens,
+ CHAR ** tokens_list,
+ UINT32 * failed_token_num,
+ UINT32 * failed_token_position);
+
+IMPORT_EXPORT_LIBHYPERDBG VOID
+hyperdbg_u_test_command_parser_show_tokens(CHAR * command);
+
+//
+// General imports/exports
+//
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_setup_path_for_filename(const CHAR * filename, CHAR * file_location, UINT32 buffer_len, BOOLEAN check_file_existence);
+
+IMPORT_EXPORT_LIBHYPERDBG INT
+hyperdbg_u_run_command(CHAR * command);
+
+IMPORT_EXPORT_LIBHYPERDBG VOID
+hyperdbg_u_show_signature();
+
+IMPORT_EXPORT_LIBHYPERDBG VOID
+hyperdbg_u_set_text_message_callback(PVOID handler);
+
+IMPORT_EXPORT_LIBHYPERDBG PVOID
+hyperdbg_u_set_text_message_callback_using_shared_buffer(PVOID handler);
+
+IMPORT_EXPORT_LIBHYPERDBG VOID
+hyperdbg_u_unset_text_message_callback();
+
+IMPORT_EXPORT_LIBHYPERDBG INT
+hyperdbg_u_script_read_file_and_execute_commandline(INT argc, CHAR * argv[]);
+
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_continue_previous_command();
+
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_check_multiline_command(CHAR * current_command, BOOLEAN reset);
+
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_set_custom_driver_path(CHAR * driver_file_path, CHAR * driver_name);
+
+IMPORT_EXPORT_LIBHYPERDBG VOID
+hyperdbg_u_use_default_driver_path();
+
+//
+// Connect to local or remote debugger
+// Exported functionality of the '.connect' command
+//
+IMPORT_EXPORT_LIBHYPERDBG VOID
+hyperdbg_u_connect_local_debugger();
+
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_connect_remote_debugger(const CHAR * ip, const CHAR * port);
+
+//
+// Connect to the debugger in the Debugger Mode
+//
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_connect_remote_debugger_using_com_port(const CHAR * port_name, DWORD baudrate, BOOLEAN pause_after_connection);
+
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_connect_remote_debugger_using_named_pipe(const CHAR * named_pipe, BOOLEAN pause_after_connection);
+
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_connect_current_debugger_using_com_port(const CHAR * port_name, DWORD baudrate);
+
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_debug_close_remote_debugger();
+
+//
+// Miscalenous functions
+//
+IMPORT_EXPORT_LIBHYPERDBG UINT64
+hyperdbg_u_get_kernel_base();
+
+//
+// Reading memory
+//
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_read_memory(UINT64 target_address,
+ DEBUGGER_READ_MEMORY_TYPE memory_type,
+ DEBUGGER_READ_READING_TYPE reading_Type,
+ UINT32 pid,
+ UINT32 size,
+ BOOLEAN get_address_mode,
+ DEBUGGER_READ_MEMORY_ADDRESS_MODE * address_mode,
+ BYTE * target_buffer_to_store,
+ UINT32 * return_length);
+
+IMPORT_EXPORT_LIBHYPERDBG VOID
+hyperdbg_u_show_memory_or_disassemble(DEBUGGER_SHOW_MEMORY_STYLE style,
+ UINT64 address,
+ DEBUGGER_READ_MEMORY_TYPE memory_type,
+ DEBUGGER_READ_READING_TYPE reading_type,
+ UINT32 pid,
+ UINT32 size,
+ PDEBUGGER_DT_COMMAND_OPTIONS dt_details);
+
+//
+// Writing memory
+//
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_write_memory(PVOID destination_address,
+ DEBUGGER_EDIT_MEMORY_TYPE memory_type,
+ UINT32 process_id,
+ PVOID source_address,
+ UINT32 number_of_bytes);
+
+//
+// Reading/Writing registers
+//
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_read_all_registers(GUEST_REGS * guest_registers, GUEST_EXTRA_REGISTERS * extra_registers);
+
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_read_target_register(REGS_ENUM register_id, UINT64 * target_register);
+
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_write_target_register(REGS_ENUM register_id, UINT64 value);
+
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_show_all_registers();
+
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_show_target_register(REGS_ENUM register_id);
+
+//
+// Continue debuggee
+// Exported functionality of the 'g' command
+//
+IMPORT_EXPORT_LIBHYPERDBG VOID
+hyperdbg_u_continue_debuggee();
+
+//
+// Pause debuggee
+// Exported functionality of the 'pause' command
+//
+IMPORT_EXPORT_LIBHYPERDBG VOID
+hyperdbg_u_pause_debuggee();
+
+//
+// Set breakpoint
+// Exported functionality of the 'bp' command
+//
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_set_breakpoint(UINT64 address, UINT32 pid, UINT32 tid, UINT32 core_numer);
+
+//
+// Stepping and tracing instruction
+// Exported functionality of 't', 'p', 'i', '!track', 'gu' commands
+//
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_stepping_instrumentation_step_in();
+
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_stepping_regular_step_in();
+
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_stepping_step_over();
+
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_stepping_instrumentation_step_in_for_tracking();
+
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_stepping_step_over_for_gu(BOOLEAN last_instruction);
+
+//
+// Start a process
+// Exported functionality of the '.start' command
+//
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_start_process(const WCHAR * path);
+
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_start_process_with_args(const WCHAR * path, const WCHAR * arguments);
+
+//
+// APIC related command
+// Exported functionality of the '!apic', and '!ioapic' commands
+//
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_get_local_apic(PLAPIC_PAGE local_apic, BOOLEAN * is_using_x2apic);
+
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_get_io_apic(IO_APIC_ENTRY_PACKETS * io_apic);
+
+//
+// IDT related command
+// Exported functionality of the '!idt' command
+//
+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
+//
+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();
+
+//
+// Assembler
+// Exported functionality of the 'a' command
+//
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_assemble_get_length(const CHAR * assembly_code, UINT64 start_address, UINT32 * length);
+
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hyperdbg_u_assemble(const CHAR * assembly_code, UINT64 start_address, PVOID buffer_to_store_assembled_data, UINT32 buffer_size);
+
+//
+// hwdbg functions
+// Exported functionality of the '!hw' and '!hw_*' commands
+//
+IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
+hwdbg_script_run_script(const CHAR * script,
+ const CHAR * instance_filepath_to_read,
+ const CHAR * hardware_script_file_path_to_save,
+ UINT32 initial_bram_buffer_size);
+
+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
new file mode 100644
index 00000000..1e31f6d7
--- /dev/null
+++ b/hyperdbg/include/SDK/imports/user/HyperDbgScriptImports.h
@@ -0,0 +1,138 @@
+/**
+ * @file HyperDbgScriptImports.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Headers relating exported functions from script engine
+ * @version 0.2
+ * @date 2023-02-02
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#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
+ // 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
+
+//
+// Header file of script-engine
+// Imports
+//
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//
+// Hardware scripts
+//
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE VOID
+HardwareScriptInterpreterShowScriptCapabilities(HWDBG_INSTANCE_INFORMATION * InstanceInfo);
+
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE BOOLEAN
+HardwareScriptInterpreterCheckScriptBufferWithScriptCapabilities(HWDBG_INSTANCE_INFORMATION * InstanceInfo,
+ PVOID ScriptBuffer,
+ UINT32 CountOfScriptSymbolChunks,
+ UINT32 * NumberOfStages,
+ UINT32 * NumberOfOperands,
+ UINT32 * NumberOfOperandsImplemented);
+
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE BOOLEAN
+HardwareScriptInterpreterCompressBuffer(UINT64 * Buffer,
+ SIZE_T BufferLength,
+ UINT32 ScriptVariableLength,
+ UINT32 BramDataWidth,
+ SIZE_T * NewBufferSize,
+ SIZE_T * NumberOfBytesPerChunk);
+
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE BOOLEAN
+HardwareScriptInterpreterConvertSymbolToHwdbgShortSymbolBuffer(
+ HWDBG_INSTANCE_INFORMATION * InstanceInfo,
+ SYMBOL * SymbolBuffer,
+ SIZE_T SymbolBufferLength,
+ UINT32 NumberOfStages,
+ HWDBG_SHORT_SYMBOL ** NewShortSymbolBuffer,
+ SIZE_T * NewBufferSize);
+
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE VOID
+HardwareScriptInterpreterFreeHwdbgShortSymbolBuffer(HWDBG_SHORT_SYMBOL * NewShortSymbolBuffer);
+
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE PVOID
+ScriptEngineParse(CHAR * Str);
+
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE BOOLEAN
+ScriptEngineSetHwdbgInstanceInfo(HWDBG_INSTANCE_INFORMATION * InstancInfo);
+
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE VOID
+PrintSymbolBuffer(const PVOID SymbolBuffer);
+
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE VOID
+RemoveSymbolBuffer(PVOID SymbolBuffer);
+
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE VOID
+PrintSymbol(PVOID Symbol);
+
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE UINT64
+ScriptEngineConvertNameToAddress(const CHAR * FunctionOrVariableName, PBOOLEAN WasFound);
+
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE UINT32
+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);
+
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE UINT32
+ScriptEngineSearchSymbolForMask(const CHAR * SearchMask);
+
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE BOOLEAN
+ScriptEngineGetFieldOffset(CHAR * TypeName, CHAR * FieldName, UINT32 * FieldOffset);
+
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE BOOLEAN
+ScriptEngineGetDataTypeSize(CHAR * TypeName, UINT64 * TypeSize);
+
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE BOOLEAN
+ScriptEngineCreateSymbolTableForDisassembler(PVOID CallbackFunction);
+
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE BOOLEAN
+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);
+
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE BOOLEAN
+ScriptEngineConvertLoadedModuleToPdbFileAndGuidAndAgeDetails(const BYTE * LoadedImageBytes,
+ SIZE_T LoadedImageSize,
+ 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);
+
+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();
+
+IMPORT_EXPORT_HYPERDBG_SCRIPT_ENGINE VOID
+ScriptEngineSetTextMessageCallback(PVOID Handler);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/hyperdbg/include/SDK/imports/user/HyperDbgSymImports.h b/hyperdbg/include/SDK/imports/user/HyperDbgSymImports.h
new file mode 100644
index 00000000..c5059cab
--- /dev/null
+++ b/hyperdbg/include/SDK/imports/user/HyperDbgSymImports.h
@@ -0,0 +1,111 @@
+/**
+ * @file HyperDbgSymImports.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Headers relating exported functions from symbol parser
+ * @version 0.2
+ * @date 2023-02-02
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+#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
+ // 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
+
+//
+// Header file of symbol-parser
+// Imports
+//
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER VOID
+SymSetTextMessageCallback(PVOID Handler);
+
+IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER VOID
+SymbolAbortLoading();
+
+IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER UINT64
+SymConvertNameToAddress(const CHAR * FunctionOrVariableName, PBOOLEAN WasFound);
+
+IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER UINT32
+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);
+
+IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER UINT32
+SymSearchSymbolForMask(const CHAR * SearchMask);
+
+IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN
+SymGetFieldOffset(CHAR * TypeName, CHAR * FieldName, UINT32 * FieldOffset);
+
+IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN
+SymGetDataTypeSize(CHAR * TypeName, UINT64 * TypeSize);
+
+IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN
+SymCreateSymbolTableForDisassembler(PVOID CallbackFunction);
+
+IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN
+SymConvertFileToPdbPath(const CHAR * LocalFilePath, CHAR * ResultPath, SIZE_T ResultPathSize);
+
+IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN
+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,
+ BOOLEAN IsSilentLoad);
+
+IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN
+SymShowDataBasedOnSymbolTypes(const CHAR * TypeName,
+ UINT64 Address,
+ BOOLEAN IsStruct,
+ PVOID BufferAddress,
+ const CHAR * AdditionalParameters);
+
+IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN
+SymQuerySizeof(_In_ const CHAR * StructNameOrTypeName, _Out_ UINT32 * SizeOfField);
+IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN
+SymCastingQueryForFiledsAndTypes(_In_ const CHAR * StructName,
+ _In_ const CHAR * FiledOfStructName,
+ _Out_ PBOOLEAN IsStructNamePointerOrNot,
+ _Out_ PBOOLEAN IsFiledOfStructNamePointerOrNot,
+ _Out_ CHAR ** NewStructOrTypeName,
+ _Out_ UINT32 * OffsetOfFieldFromTop,
+ _Out_ UINT32 * SizeOfField);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/hyperdbg/include/SDK/modules/HyperEvade.h b/hyperdbg/include/SDK/modules/HyperEvade.h
new file mode 100644
index 00000000..e09c7e0a
--- /dev/null
+++ b/hyperdbg/include/SDK/modules/HyperEvade.h
@@ -0,0 +1,153 @@
+/**
+ * @file HyperEvade.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief HyperDbg's SDK for hyperevade project
+ * @details This file contains definitions of HyperEvade 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 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
+ *
+ */
+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);
+
+/**
+ * @brief A function that sets the trap flag after a syscall
+ *
+ */
+typedef BOOLEAN (*SYSCALL_CALLBACK_SET_TRAP_FLAG_AFTER_SYSCALL)(GUEST_REGS * Regs,
+ UINT32 ProcessId,
+ UINT32 ThreadId,
+ UINT64 Context,
+ SYSCALL_CALLBACK_CONTEXT_PARAMS * Params);
+
+/**
+ * @brief A function that handles the trap flag
+ *
+ */
+typedef VOID (*HV_HANDLE_TRAPFLAG)();
+
+/**
+ * @brief A function that injects a general protection (#GP)
+ *
+ */
+typedef VOID (*EVENT_INJECT_GENERAL_PROTECTION)();
+
+//////////////////////////////////////////////////
+// Callback Structure //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Prototype of each function needed by hyperevade module
+ *
+ */
+typedef struct _HYPEREVADE_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;
+
+ //
+ // HyperTrace callback(s)
+ //
+ HYPERTRACE_LBR_IS_SUPPORTED HyperTraceLbrIsSupported;
+
+ //
+ // *** HYPEREVADE callbacks ***
+ //
+
+ //
+ // Memory callbacks
+ //
+ CHECK_ACCESS_VALIDITY_AND_SAFETY CheckAccessValidityAndSafety;
+ MEMORY_MAPPER_READ_MEMORY_SAFE_ON_TARGET_PROCESS MemoryMapperReadMemorySafeOnTargetProcess;
+ MEMORY_MAPPER_WRITE_MEMORY_SAFE_ON_TARGET_PROCESS MemoryMapperWriteMemorySafeOnTargetProcess;
+
+ //
+ // Common callbacks
+ //
+ COMMON_GET_PROCESS_NAME_FROM_PROCESS_CONTROL_BLOCK CommonGetProcessNameFromProcessControlBlock;
+
+ //
+ // System call callbacks
+ //
+ SYSCALL_CALLBACK_SET_TRAP_FLAG_AFTER_SYSCALL SyscallCallbackSetTrapFlagAfterSyscall;
+
+ //
+ // VMX callbacks
+ //
+ HV_HANDLE_TRAPFLAG HvHandleTrapFlag;
+ EVENT_INJECT_GENERAL_PROTECTION EventInjectGeneralProtection;
+
+} HYPEREVADE_CALLBACKS, *PHYPEREVADE_CALLBACKS;
diff --git a/hyperdbg/include/SDK/Modules/HyperLog.h b/hyperdbg/include/SDK/modules/HyperLog.h
similarity index 100%
rename from hyperdbg/include/SDK/Modules/HyperLog.h
rename to hyperdbg/include/SDK/modules/HyperLog.h
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
similarity index 67%
rename from hyperdbg/include/SDK/Modules/VMM.h
rename to hyperdbg/include/SDK/modules/VMM.h
index 569ec85f..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
*
@@ -71,24 +77,43 @@ typedef BOOLEAN (*DEBUGGING_CALLBACK_HANDLE_BREAKPOINT_EXCEPTION)(UINT32 CoreId)
typedef BOOLEAN (*DEBUGGING_CALLBACK_HANDLE_DEBUG_BREAKPOINT_EXCEPTION)(UINT32 CoreId);
/**
- * @brief Check for page-faults in user-debugger
+ * @brief Check for thread interception in user-debugger
*
*/
-typedef BOOLEAN (*DEBUGGING_CALLBACK_CONDITIONAL_PAGE_FAULT_EXCEPTION)(UINT32 CoreId,
- UINT64 Address,
- UINT32 PageFaultErrorCode);
+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
@@ -102,42 +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 to handle cr3 events for thread interception
- *
- */
-typedef BOOLEAN (*ATTACHING_HANDLE_CR3_EVENTS_FOR_THREAD_INTERCEPTION)(UINT32 CoreId, CR3_TYPE NewCr3);
-
-/**
- * @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
*
@@ -153,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
*
@@ -182,43 +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_CONDITIONAL_PAGE_FAULT_EXCEPTION DebuggingCallbackConditionalPageFaultException; // 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;
- ATTACHING_HANDLE_CR3_EVENTS_FOR_THREAD_INTERCEPTION AttachingHandleCr3VmexitsForThreadInterception;
- 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/callback/code/HyperLogCallback.c b/hyperdbg/include/components/callback/code/HyperLogCallback.c
new file mode 100644
index 00000000..2d77def5
--- /dev/null
+++ b/hyperdbg/include/components/callback/code/HyperLogCallback.c
@@ -0,0 +1,141 @@
+/**
+ * @file HyperLogCallback.c
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief VMM callback interface routines
+ * @details
+ *
+ * @version 0.2
+ * @date 2023-01-29
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief routines callback for preparing and sending message to queue
+ *
+ * @param OperationCode
+ * @param IsImmediateMessage
+ * @param ShowCurrentSystemTime
+ * @param Priority
+ * @param Fmt
+ * @param ...
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+LogCallbackPrepareAndSendMessageToQueue(UINT32 OperationCode,
+ BOOLEAN IsImmediateMessage,
+ BOOLEAN ShowCurrentSystemTime,
+ BOOLEAN Priority,
+ const CHAR * Fmt,
+ ...)
+{
+ BOOLEAN Result;
+ va_list ArgList;
+
+ if (g_Callbacks.LogCallbackPrepareAndSendMessageToQueueWrapper == NULL)
+ {
+ //
+ // Ignore sending message to queue
+ //
+ return FALSE;
+ }
+
+ va_start(ArgList, Fmt);
+
+ Result = g_Callbacks.LogCallbackPrepareAndSendMessageToQueueWrapper(OperationCode,
+ IsImmediateMessage,
+ ShowCurrentSystemTime,
+ Priority,
+ Fmt,
+ ArgList);
+ va_end(ArgList);
+
+ return Result;
+}
+
+/**
+ * @brief routines callback for sending message to queue
+ *
+ * @param OperationCode
+ * @param IsImmediateMessage
+ * @param LogMessage
+ * @param BufferLen
+ * @param Priority
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+LogCallbackSendMessageToQueue(UINT32 OperationCode,
+ BOOLEAN IsImmediateMessage,
+ CHAR * LogMessage,
+ UINT32 BufferLen,
+ BOOLEAN Priority)
+{
+ if (g_Callbacks.LogCallbackSendMessageToQueue == NULL)
+ {
+ //
+ // Ignore sending message to queue
+ //
+ return FALSE;
+ }
+
+ return g_Callbacks.LogCallbackSendMessageToQueue(OperationCode,
+ IsImmediateMessage,
+ LogMessage,
+ BufferLen,
+ Priority);
+}
+
+/**
+ * @brief routines callback for checking if buffer is full
+ *
+ * @param Priority
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+LogCallbackCheckIfBufferIsFull(BOOLEAN Priority)
+{
+ if (g_Callbacks.LogCallbackCheckIfBufferIsFull == NULL)
+ {
+ //
+ // Ignore sending message to queue
+ //
+ return FALSE;
+ }
+
+ return g_Callbacks.LogCallbackCheckIfBufferIsFull(Priority);
+}
+
+/**
+ * @brief routines callback for sending buffer
+ * @param OperationCode
+ * @param Buffer
+ * @param BufferLength
+ * @param Priority
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+LogCallbackSendBuffer(_In_ UINT32 OperationCode,
+ _In_reads_bytes_(BufferLength) PVOID Buffer,
+ _In_ UINT32 BufferLength,
+ _In_ BOOLEAN Priority)
+
+{
+ if (g_Callbacks.LogCallbackSendBuffer == NULL)
+ {
+ //
+ // Ignore sending buffer
+ //
+ return FALSE;
+ }
+
+ return g_Callbacks.LogCallbackSendBuffer(OperationCode,
+ Buffer,
+ BufferLength,
+ Priority);
+}
\ No newline at end of file
diff --git a/hyperdbg/include/components/callback/header/HyperLogCallback.h b/hyperdbg/include/components/callback/header/HyperLogCallback.h
new file mode 100644
index 00000000..b7906988
--- /dev/null
+++ b/hyperdbg/include/components/callback/header/HyperLogCallback.h
@@ -0,0 +1,41 @@
+/**
+ * @file HyperLogCallback.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Header for VMM callback interface routines
+ * @details
+ *
+ * @version 0.2
+ * @date 2023-01-29
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//
+// Log Callbacks
+//
+
+BOOLEAN
+LogCallbackPrepareAndSendMessageToQueue(UINT32 OperationCode,
+ BOOLEAN IsImmediateMessage,
+ BOOLEAN ShowCurrentSystemTime,
+ BOOLEAN Priority,
+ const CHAR * Fmt,
+ ...);
+
+BOOLEAN
+LogCallbackSendMessageToQueue(UINT32 OperationCode,
+ BOOLEAN IsImmediateMessage,
+ CHAR * LogMessage,
+ UINT32 BufferLen,
+ BOOLEAN Priority);
+
+BOOLEAN
+LogCallbackCheckIfBufferIsFull(BOOLEAN Priority);
+
+BOOLEAN
+LogCallbackSendBuffer(_In_ UINT32 OperationCode,
+ _In_reads_bytes_(BufferLength) PVOID Buffer,
+ _In_ UINT32 BufferLength,
+ _In_ BOOLEAN Priority);
diff --git a/hyperdbg/include/components/optimizations/code/InsertionSort.c b/hyperdbg/include/components/optimizations/code/InsertionSort.c
index fb6884de..949f79b2 100644
--- a/hyperdbg/include/components/optimizations/code/InsertionSort.c
+++ b/hyperdbg/include/components/optimizations/code/InsertionSort.c
@@ -16,12 +16,14 @@
*
* @param ArrayPtr
* @param NumberOfItems
+ * @param MaxNumOfItems
+ * @param Index
* @param Key
*
* @return BOOLEAN
*/
BOOLEAN
-InsertionSortInsertItem(UINT64 ArrayPtr[], UINT32 * NumberOfItems, UINT32 MaxNumOfItems, UINT64 Key)
+InsertionSortInsertItem(UINT64 ArrayPtr[], UINT32 * NumberOfItems, UINT32 MaxNumOfItems, UINT32 * Index, UINT64 Key)
{
UINT32 Idx;
@@ -45,6 +47,7 @@ InsertionSortInsertItem(UINT64 ArrayPtr[], UINT32 * NumberOfItems, UINT32 MaxNum
Idx = Idx - 1;
}
ArrayPtr[Idx] = Key;
+ *Index = Idx;
(*NumberOfItems)++;
//
@@ -73,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/optimizations/code/OptimizationsExamples.c b/hyperdbg/include/components/optimizations/code/OptimizationsExamples.c
index b3471b0e..b2c9d0b8 100644
--- a/hyperdbg/include/components/optimizations/code/OptimizationsExamples.c
+++ b/hyperdbg/include/components/optimizations/code/OptimizationsExamples.c
@@ -30,12 +30,12 @@ OptimizationExampleInsertionSortAndBinarySearch()
UINT32 NumberOfItems = 0;
UINT32 Index;
- InsertionSortInsertItem(Arr, &NumberOfItems, MAX_NUM_OF_ARRAY, 12);
- InsertionSortInsertItem(Arr, &NumberOfItems, MAX_NUM_OF_ARRAY, 11);
- InsertionSortInsertItem(Arr, &NumberOfItems, MAX_NUM_OF_ARRAY, 13);
- InsertionSortInsertItem(Arr, &NumberOfItems, MAX_NUM_OF_ARRAY, 5);
- InsertionSortInsertItem(Arr, &NumberOfItems, MAX_NUM_OF_ARRAY, 6);
- InsertionSortInsertItem(Arr, &NumberOfItems, MAX_NUM_OF_ARRAY, 8);
+ InsertionSortInsertItem(Arr, &NumberOfItems, MAX_NUM_OF_ARRAY, &Index, 12);
+ InsertionSortInsertItem(Arr, &NumberOfItems, MAX_NUM_OF_ARRAY, &Index, 11);
+ InsertionSortInsertItem(Arr, &NumberOfItems, MAX_NUM_OF_ARRAY, &Index, 13);
+ InsertionSortInsertItem(Arr, &NumberOfItems, MAX_NUM_OF_ARRAY, &Index, 5);
+ InsertionSortInsertItem(Arr, &NumberOfItems, MAX_NUM_OF_ARRAY, &Index, 6);
+ InsertionSortInsertItem(Arr, &NumberOfItems, MAX_NUM_OF_ARRAY, &Index, 8);
//
// Search for item equal to 15
diff --git a/hyperdbg/include/components/optimizations/header/InsertionSort.h b/hyperdbg/include/components/optimizations/header/InsertionSort.h
index 2fb18043..2f1e07ba 100644
--- a/hyperdbg/include/components/optimizations/header/InsertionSort.h
+++ b/hyperdbg/include/components/optimizations/header/InsertionSort.h
@@ -16,7 +16,7 @@
//////////////////////////////////////////////////
BOOLEAN
-InsertionSortInsertItem(UINT64 ArrayPtr[], UINT32 * NumberOfItems, UINT32 MaxNumOfItems, UINT64 Key);
+InsertionSortInsertItem(UINT64 ArrayPtr[], UINT32 * NumberOfItems, UINT32 MaxNumOfItems, UINT32 * Index, UINT64 Key);
BOOLEAN
InsertionSortDeleteItem(UINT64 ArrayPtr[], UINT32 * NumberOfItems, UINT32 Index);
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/Configuration.h b/hyperdbg/include/config/Configuration.h
similarity index 96%
rename from hyperdbg/include/Configuration.h
rename to hyperdbg/include/config/Configuration.h
index 95d5d6d6..9a78bc41 100644
--- a/hyperdbg/include/Configuration.h
+++ b/hyperdbg/include/config/Configuration.h
@@ -63,13 +63,18 @@
*/
#define DebugMode FALSE
+/**
+ * @brief Enable or disable the instant event mechanism
+ * @details for more information: https://docs.hyperdbg.org/tips-and-tricks/misc/instant-events
+ */
+#define EnableInstantEventMechanism TRUE
+
/**
* @brief Activates the user-mode debugger
*/
#define ActivateUserModeDebugger FALSE
/**
- * @brief Enable or disable the instant event mechanism
- * @details for more information: https://docs.hyperdbg.org/tips-and-tricks/misc/instant-events
+ * @brief Activates the hyperevade project
*/
-#define EnableInstantEventMechanism TRUE
+#define ActivateHyperEvadeProject FALSE
diff --git a/hyperdbg/include/config/Definition.h b/hyperdbg/include/config/Definition.h
new file mode 100644
index 00000000..1580f1e4
--- /dev/null
+++ b/hyperdbg/include/config/Definition.h
@@ -0,0 +1,132 @@
+/**
+ * @file Definition.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Header files for global definitions
+ * @details This file contains definitions that are use in both user mode and
+ * kernel mode Means that if you change the following files, structures or
+ * enums, then these settings apply to both usermode and kernel mode
+ * @version 0.1
+ * @date 2020-04-10
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Config File //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Config file name for HyperDbg
+ *
+ */
+#define CONFIG_FILE_NAME L"config.ini"
+
+//////////////////////////////////////////////////
+// Installer //
+//////////////////////////////////////////////////
+
+/**
+ * @brief name of HyperDbg's VMM driver
+ *
+ */
+#define VMM_DRIVER_NAME "hyperhv"
+
+/**
+ * @brief name of HyperDbg's debugger driver
+ *
+ */
+#define KERNEL_DEBUGGER_DRIVER_NAME "hyperkd"
+
+/**
+ * @brief name of HyperDbg's debugger driver + extension
+ *
+ */
+#define KERNEL_DEBUGGER_DRIVER_NAME_AND_EXTENSION "hyperkd.sys"
+
+//////////////////////////////////////////////////
+// Test Cases //
+//////////////////////////////////////////////////
+
+/**
+ * @brief Default named pipe name for communication between debugger and debuggee process
+ */
+#define TEST_DEFAULT_NAMED_PIPE "\\\\.\\pipe\\HyperDbgPipe"
+
+/**
+ * @brief Maximum buffer to communicate between debugger and debuggee process
+ */
+#define TEST_CASE_MAXIMUM_BUFFERS_TO_COMMUNICATE 0x1000
+
+/**
+ * @brief Maximum hwdbg testing pins count (for emulating the script behavior)
+ */
+#define MAX_HWDBG_TESTING_PIN_COUNT 500
+
+/**
+ * @brief Test cases file name for command parser
+ */
+#define COMMAND_PARSER_TEST_CASES_FILE "..\\..\\..\\tests\\command-parser\\command-parser-testcases.txt"
+
+/**
+ * @brief Test case parameter for testing main command parser
+ */
+#define TEST_HWDBG_FUNCTIONALITIES "test-hwdbg-functionalities"
+
+/**
+ * @brief Test case parameter for testing main command parser
+ */
+#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
+ */
+#define TEST_CASE_PARAMETER_FOR_SCRIPT_SEMANTIC_TEST_CASES "test-script-semantic-test-cases"
+
+/**
+ * @brief Test cases file name
+ */
+#define SCRIPT_ENGINE_TEST_CASES_DIRECTORY "script-test-cases"
+
+/**
+ * @brief Test cases directory name for script semantic tests
+ */
+#define SCRIPT_SEMANTIC_TEST_CASE_DIRECTORY "..\\..\\..\\tests\\script-engine-test\\semantic-test-cases"
+
+/**
+ * @brief Test cases directory name for hwdbg script (code) tests
+ */
+#define HWDBG_SCRIPT_TEST_CASE_CODE_DIRECTORY "..\\..\\..\\tests\\hwdbg-tests\\scripts\\codes"
+
+/**
+ * @brief Test cases directory name for hwdbg script (compiled-scripts) tests
+ */
+#define HWDBG_SCRIPT_TEST_CASE_COMPILED_SCRIPTS_DIRECTORY "..\\..\\..\\tests\\hwdbg-tests\\scripts\\compiled-scripts"
+
+/**
+ * @brief Test cases directory name for hwdbg script (sample-tests) tests
+ */
+#define HWDBG_SCRIPT_TEST_CASE_SAMPLE_TESTS_DIRECTORY "..\\..\\..\\tests\\hwdbg-tests\\scripts\\sample-tests"
+
+//////////////////////////////////////////////////
+// Delay Speeds //
+//////////////////////////////////////////////////
+
+/**
+ * @brief The speed delay for showing messages from kernel-mode
+ * to user-mode in VMI-mode, using a lower value causes the
+ * HyperDbg to show messages faster but you should keep in mind,
+ * not to eat all of the CPU
+ */
+#define DefaultSpeedOfReadingKernelMessages 30
diff --git a/hyperdbg/hprdbghv/header/vmm/vmx/HypervTlfs.h b/hyperdbg/include/hyper-v/HypervTlfs.h
similarity index 91%
rename from hyperdbg/hprdbghv/header/vmm/vmx/HypervTlfs.h
rename to hyperdbg/include/hyper-v/HypervTlfs.h
index b5646015..4df98634 100644
--- a/hyperdbg/hprdbghv/header/vmm/vmx/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.
*/
@@ -273,6 +296,29 @@ enum hv_isolation_type
#define HV_X64_MSR_TIME_REF_COUNT HV_REGISTER_TIME_REF_COUNT
#define HV_X64_MSR_REFERENCE_TSC HV_REGISTER_REFERENCE_TSC
+//
+// Define the synthetic timer configuration structure
+//
+typedef struct _HV_X64_MSR_STIMER_CONFIG_CONTENTS
+{
+ union
+ {
+ UINT64 AsUINT64;
+ struct
+ {
+ UINT64 Enable : 1;
+ UINT64 Periodic : 1;
+ UINT64 Lazy : 1;
+ UINT64 AutoEnable : 1;
+ UINT64 ApicVector : 8;
+ UINT64 DirectMode : 1;
+ UINT64 ReservedZ1 : 1;
+ UINT64 SINTx : 4;
+ UINT64 ReservedZ2 : 44;
+ };
+ };
+} HV_X64_MSR_STIMER_CONFIG_CONTENTS, *PHV_X64_MSR_STIMER_CONFIG_CONTENTS;
+
/* Hyper-V memory host visibility */
enum hv_mem_host_visibility
{
diff --git a/hyperdbg/include/keystone/arm.h b/hyperdbg/include/keystone/arm.h
new file mode 100644
index 00000000..f4d2489a
--- /dev/null
+++ b/hyperdbg/include/keystone/arm.h
@@ -0,0 +1,23 @@
+/* Keystone Assembler Engine */
+/* By Nguyen Anh Quynh, 2016 */
+
+#ifndef KEYSTONE_ARM_H
+#define KEYSTONE_ARM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "keystone.h"
+
+typedef enum ks_err_asm_arm {
+ KS_ERR_ASM_ARM_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_ARM_MISSINGFEATURE,
+ KS_ERR_ASM_ARM_MNEMONICFAIL,
+} ks_err_asm_arm;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/include/keystone/arm64.h b/hyperdbg/include/keystone/arm64.h
new file mode 100644
index 00000000..7a7af411
--- /dev/null
+++ b/hyperdbg/include/keystone/arm64.h
@@ -0,0 +1,23 @@
+/* Keystone Assembler Engine */
+/* By Nguyen Anh Quynh, 2016 */
+
+#ifndef KEYSTONE_ARM64_H
+#define KEYSTONE_ARM64_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "keystone.h"
+
+typedef enum ks_err_asm_arm64 {
+ KS_ERR_ASM_ARM64_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_ARM64_MISSINGFEATURE,
+ KS_ERR_ASM_ARM64_MNEMONICFAIL,
+} ks_err_asm_arm64;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/include/keystone/evm.h b/hyperdbg/include/keystone/evm.h
new file mode 100644
index 00000000..60ac408c
--- /dev/null
+++ b/hyperdbg/include/keystone/evm.h
@@ -0,0 +1,23 @@
+/* Keystone Assembler Engine */
+/* By Nguyen Anh Quynh, 2016-2018 */
+
+#ifndef KEYSTONE_EVM_H
+#define KEYSTONE_EVM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "keystone.h"
+
+typedef enum ks_err_asm_evm {
+ KS_ERR_ASM_EVM_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_EVM_MISSINGFEATURE,
+ KS_ERR_ASM_EVM_MNEMONICFAIL,
+} ks_err_asm_evm;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/include/keystone/hexagon.h b/hyperdbg/include/keystone/hexagon.h
new file mode 100644
index 00000000..e6158123
--- /dev/null
+++ b/hyperdbg/include/keystone/hexagon.h
@@ -0,0 +1,24 @@
+/* Keystone Assembler Engine */
+/* By Nguyen Anh Quynh, 2016 */
+
+#ifndef KEYSTONE_HEXAGON_H
+#define KEYSTONE_HEXAGON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "keystone.h"
+
+typedef enum ks_err_asm_hexagon {
+ KS_ERR_ASM_HEXAGON_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_HEXAGON_MISSINGFEATURE,
+ KS_ERR_ASM_HEXAGON_MNEMONICFAIL,
+} ks_err_asm_hexagon;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/include/keystone/keystone.h b/hyperdbg/include/keystone/keystone.h
new file mode 100644
index 00000000..503508c6
--- /dev/null
+++ b/hyperdbg/include/keystone/keystone.h
@@ -0,0 +1,349 @@
+/* Keystone Assembler Engine (www.keystone-engine.org) */
+/* By Nguyen Anh Quynh , 2016 */
+
+#ifndef KEYSTONE_ENGINE_H
+#define KEYSTONE_ENGINE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+#include
+#include
+
+#ifdef _MSC_VER // MSVC compiler
+# pragma warning(disable : 4201)
+# pragma warning(disable : 4100)
+# ifndef KEYSTONE_STATIC
+# define KEYSTONE_EXPORT __declspec(dllexport)
+# else
+# define KEYSTONE_EXPORT
+# endif
+#else
+# ifdef __GNUC__
+# include
+# ifndef KEYSTONE_STATIC
+# define KEYSTONE_EXPORT __attribute__((visibility("default")))
+# else
+# define KEYSTONE_EXPORT
+# endif
+# else
+# define KEYSTONE_EXPORT
+# endif
+#endif
+
+struct ks_struct;
+typedef struct ks_struct ks_engine;
+
+// Keystone API version
+#define KS_API_MAJOR 0
+#define KS_API_MINOR 9
+
+// Package version
+#define KS_VERSION_MAJOR KS_API_MAJOR
+#define KS_VERSION_MINOR KS_API_MINOR
+#define KS_VERSION_EXTRA 2
+
+/*
+ Macro to create combined version which can be compared to
+ result of ks_version() API.
+*/
+#define KS_MAKE_VERSION(major, minor) ((major << 8) + minor)
+
+// Architecture type
+typedef enum ks_arch
+{
+ KS_ARCH_ARM = 1, // ARM architecture (including Thumb, Thumb-2)
+ KS_ARCH_ARM64, // ARM-64, also called AArch64
+ KS_ARCH_MIPS, // Mips architecture
+ KS_ARCH_X86, // X86 architecture (including x86 & x86-64)
+ KS_ARCH_PPC, // PowerPC architecture (currently unsupported)
+ KS_ARCH_SPARC, // Sparc architecture
+ KS_ARCH_SYSTEMZ, // SystemZ architecture (S390X)
+ KS_ARCH_HEXAGON, // Hexagon architecture
+ KS_ARCH_EVM, // Ethereum Virtual Machine architecture
+ KS_ARCH_RISCV, // RISC-V architecture
+ KS_ARCH_MAX,
+} ks_arch;
+
+// Mode type
+typedef enum ks_mode
+{
+ KS_MODE_LITTLE_ENDIAN = 0, // little-endian mode (default mode)
+ KS_MODE_BIG_ENDIAN = 1 << 30, // big-endian mode
+ // arm / arm64
+ KS_MODE_ARM = 1 << 0, // ARM mode
+ KS_MODE_THUMB = 1 << 4, // THUMB mode (including Thumb-2)
+ KS_MODE_V8 = 1 << 6, // ARMv8 A32 encodings for ARM
+ // mips
+ KS_MODE_MICRO = 1 << 4, // MicroMips mode
+ KS_MODE_MIPS3 = 1 << 5, // Mips III ISA
+ KS_MODE_MIPS32R6 = 1 << 6, // Mips32r6 ISA
+ KS_MODE_MIPS32 = 1 << 2, // Mips32 ISA
+ KS_MODE_MIPS64 = 1 << 3, // Mips64 ISA
+ // x86 / x64
+ KS_MODE_16 = 1 << 1, // 16-bit mode
+ KS_MODE_32 = 1 << 2, // 32-bit mode
+ KS_MODE_64 = 1 << 3, // 64-bit mode
+ // ppc
+ KS_MODE_PPC32 = 1 << 2, // 32-bit mode
+ KS_MODE_PPC64 = 1 << 3, // 64-bit mode
+ KS_MODE_QPX = 1 << 4, // Quad Processing eXtensions mode
+ // riscv
+ KS_MODE_RISCV32 = 1 << 2, // 32-bit mode
+ KS_MODE_RISCV64 = 1 << 3, // 64-bit mode
+ // sparc
+ KS_MODE_SPARC32 = 1 << 2, // 32-bit mode
+ KS_MODE_SPARC64 = 1 << 3, // 64-bit mode
+ KS_MODE_V9 = 1 << 4, // SparcV9 mode
+} ks_mode;
+
+// All generic errors related to input assembly >= KS_ERR_ASM
+#define KS_ERR_ASM 128
+
+// All architecture-specific errors related to input assembly >= KS_ERR_ASM_ARCH
+#define KS_ERR_ASM_ARCH 512
+
+// All type of errors encountered by Keystone API.
+typedef enum ks_err
+{
+ KS_ERR_OK = 0, // No error: everything was fine
+ KS_ERR_NOMEM, // Out-Of-Memory error: ks_open(), ks_emulate()
+ KS_ERR_ARCH, // Unsupported architecture: ks_open()
+ KS_ERR_HANDLE, // Invalid handle
+ KS_ERR_MODE, // Invalid/unsupported mode: ks_open()
+ KS_ERR_VERSION, // Unsupported version (bindings)
+ KS_ERR_OPT_INVALID, // Unsupported option
+
+ // generic input assembly errors - parser specific
+ KS_ERR_ASM_EXPR_TOKEN = KS_ERR_ASM, // unknown token in expression
+ KS_ERR_ASM_DIRECTIVE_VALUE_RANGE, // literal value out of range for directive
+ KS_ERR_ASM_DIRECTIVE_ID, // expected identifier in directive
+ KS_ERR_ASM_DIRECTIVE_TOKEN, // unexpected token in directive
+ KS_ERR_ASM_DIRECTIVE_STR, // expected string in directive
+ KS_ERR_ASM_DIRECTIVE_COMMA, // expected comma in directive
+ KS_ERR_ASM_DIRECTIVE_RELOC_NAME, // expected relocation name in directive
+ KS_ERR_ASM_DIRECTIVE_RELOC_TOKEN, // unexpected token in .reloc directive
+ KS_ERR_ASM_DIRECTIVE_FPOINT, // invalid floating point in directive
+ KS_ERR_ASM_DIRECTIVE_UNKNOWN, // unknown directive
+ KS_ERR_ASM_DIRECTIVE_EQU, // invalid equal directive
+ KS_ERR_ASM_DIRECTIVE_INVALID, // (generic) invalid directive
+ KS_ERR_ASM_VARIANT_INVALID, // invalid variant
+ KS_ERR_ASM_EXPR_BRACKET, // brackets expression not supported on this target
+ KS_ERR_ASM_SYMBOL_MODIFIER, // unexpected symbol modifier following '@'
+ KS_ERR_ASM_SYMBOL_REDEFINED, // invalid symbol redefinition
+ KS_ERR_ASM_SYMBOL_MISSING, // cannot find a symbol
+ KS_ERR_ASM_RPAREN, // expected ')' in parentheses expression
+ KS_ERR_ASM_STAT_TOKEN, // unexpected token at start of statement
+ KS_ERR_ASM_UNSUPPORTED, // unsupported token yet
+ KS_ERR_ASM_MACRO_TOKEN, // unexpected token in macro instantiation
+ KS_ERR_ASM_MACRO_PAREN, // unbalanced parentheses in macro argument
+ KS_ERR_ASM_MACRO_EQU, // expected '=' after formal parameter identifier
+ KS_ERR_ASM_MACRO_ARGS, // too many positional arguments
+ KS_ERR_ASM_MACRO_LEVELS_EXCEED, // macros cannot be nested more than 20 levels deep
+ KS_ERR_ASM_MACRO_STR, // invalid macro string
+ KS_ERR_ASM_MACRO_INVALID, // invalid macro (generic error)
+ KS_ERR_ASM_ESC_BACKSLASH, // unexpected backslash at end of escaped string
+ KS_ERR_ASM_ESC_OCTAL, // invalid octal escape sequence (out of range)
+ KS_ERR_ASM_ESC_SEQUENCE, // invalid escape sequence (unrecognized character)
+ KS_ERR_ASM_ESC_STR, // broken escape string
+ KS_ERR_ASM_TOKEN_INVALID, // invalid token
+ KS_ERR_ASM_INSN_UNSUPPORTED, // this instruction is unsupported in this mode
+ KS_ERR_ASM_FIXUP_INVALID, // invalid fixup
+ KS_ERR_ASM_LABEL_INVALID, // invalid label
+ KS_ERR_ASM_FRAGMENT_INVALID, // invalid fragment
+
+ // generic input assembly errors - architecture specific
+ KS_ERR_ASM_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_MISSINGFEATURE,
+ KS_ERR_ASM_MNEMONICFAIL,
+} ks_err;
+
+// Resolver callback to provide value for a missing symbol in @symbol.
+// To handle a symbol, the resolver must put value of the symbol in @value,
+// then returns True.
+// If we do not resolve a missing symbol, this function must return False.
+// In that case, ks_asm() would eventually return with error KS_ERR_ASM_SYMBOL_MISSING.
+
+// To register the resolver, pass its function address to ks_option(), using
+// option KS_OPT_SYM_RESOLVER. For example, see samples/sample.c.
+typedef bool (*ks_sym_resolver)(const char * symbol, uint64_t * value);
+
+// Runtime option for the Keystone engine
+typedef enum ks_opt_type
+{
+ KS_OPT_SYNTAX = 1, // Choose syntax for input assembly
+ KS_OPT_SYM_RESOLVER, // Set symbol resolver callback
+} ks_opt_type;
+
+// Runtime option value (associated with ks_opt_type above)
+typedef enum ks_opt_value
+{
+ KS_OPT_SYNTAX_INTEL = 1 << 0, // X86 Intel syntax - default on X86 (KS_OPT_SYNTAX).
+ KS_OPT_SYNTAX_ATT = 1 << 1, // X86 ATT asm syntax (KS_OPT_SYNTAX).
+ KS_OPT_SYNTAX_NASM = 1 << 2, // X86 Nasm syntax (KS_OPT_SYNTAX).
+ KS_OPT_SYNTAX_MASM = 1 << 3, // X86 Masm syntax (KS_OPT_SYNTAX) - unsupported yet.
+ KS_OPT_SYNTAX_GAS = 1 << 4, // X86 GNU GAS syntax (KS_OPT_SYNTAX).
+ KS_OPT_SYNTAX_RADIX16 = 1 << 5, // All immediates are in hex format (i.e 12 is 0x12)
+} ks_opt_value;
+
+#include "arm64.h"
+#include "arm.h"
+#include "evm.h"
+#include "hexagon.h"
+#include "mips.h"
+#include "ppc.h"
+#include "riscv.h"
+#include "sparc.h"
+#include "systemz.h"
+#include "x86.h"
+
+/*
+ Return combined API version & major and minor version numbers.
+
+ @major: major number of API version
+ @minor: minor number of API version
+
+ @return hexical number as (major << 8 | minor), which encodes both
+ major & minor versions.
+ NOTE: This returned value can be compared with version number made
+ with macro KS_MAKE_VERSION
+
+ For example, second API version would return 1 in @major, and 1 in @minor
+ The return value would be 0x0101
+
+ NOTE: if you only care about returned value, but not major and minor values,
+ set both @major & @minor arguments to NULL.
+*/
+KEYSTONE_EXPORT
+unsigned int
+ks_version(unsigned int * major, unsigned int * minor);
+
+/*
+ Determine if the given architecture is supported by this library.
+
+ @arch: architecture type (KS_ARCH_*)
+
+ @return True if this library supports the given arch.
+*/
+KEYSTONE_EXPORT
+bool
+ks_arch_supported(ks_arch arch);
+
+/*
+ Create new instance of Keystone engine.
+
+ @arch: architecture type (KS_ARCH_*)
+ @mode: hardware mode. This is combined of KS_MODE_*
+ @ks: pointer to ks_engine, which will be updated at return time
+
+ @return KS_ERR_OK on success, or other value on failure (refer to ks_err enum
+ for detailed error).
+*/
+KEYSTONE_EXPORT
+ks_err
+ks_open(ks_arch arch, int mode, ks_engine ** ks);
+
+/*
+ Close KS instance: MUST do to release the handle when it is not used anymore.
+ NOTE: this must be called only when there is no longer usage of Keystone.
+ The reason is the this API releases some cached memory, thus access to any
+ Keystone API after ks_close() might crash your application.
+ After this, @ks is invalid, and nolonger usable.
+
+ @ks: pointer to a handle returned by ks_open()
+
+ @return KS_ERR_OK on success, or other value on failure (refer to ks_err enum
+ for detailed error).
+*/
+KEYSTONE_EXPORT
+ks_err
+ks_close(ks_engine * ks);
+
+/*
+ Report the last error number when some API function fail.
+ Like glibc's errno, ks_errno might not retain its old error once accessed.
+
+ @ks: handle returned by ks_open()
+
+ @return: error code of ks_err enum type (KS_ERR_*, see above)
+*/
+KEYSTONE_EXPORT
+ks_err
+ks_errno(ks_engine * ks);
+
+/*
+ Return a string describing given error code.
+
+ @code: error code (see KS_ERR_* above)
+
+ @return: returns a pointer to a string that describes the error code
+ passed in the argument @code
+ */
+KEYSTONE_EXPORT
+const char *
+ks_strerror(ks_err code);
+
+/*
+ Set option for Keystone engine at runtime
+
+ @ks: handle returned by ks_open()
+ @type: type of option to be set. See ks_opt_type
+ @value: option value corresponding with @type
+
+ @return: KS_ERR_OK on success, or other value on failure.
+ Refer to ks_err enum for detailed error.
+*/
+KEYSTONE_EXPORT
+ks_err
+ks_option(ks_engine * ks, ks_opt_type type, size_t value);
+
+/*
+ Assemble a string given its the buffer, size, start address and number
+ of instructions to be decoded.
+ This API dynamically allocate memory to contain assembled instruction.
+ Resulted array of bytes containing the machine code is put into @*encoding
+
+ NOTE 1: this API will automatically determine memory needed to contain
+ output bytes in *encoding.
+
+ NOTE 2: caller must free the allocated memory itself to avoid memory leaking.
+
+ @ks: handle returned by ks_open()
+ @str: NULL-terminated assembly string. Use ; or \n to separate statements.
+ @address: address of the first assembly instruction, or 0 to ignore.
+ @encoding: array of bytes containing encoding of input assembly string.
+ NOTE: *encoding will be allocated by this function, and should be freed
+ with ks_free() function.
+ @encoding_size: size of *encoding
+ @stat_count: number of statements successfully processed
+
+ @return: 0 on success, or -1 on failure.
+
+ On failure, call ks_errno() for error code.
+*/
+KEYSTONE_EXPORT
+int
+ks_asm(ks_engine * ks,
+ const char * string,
+ uint64_t address,
+ unsigned char ** encoding,
+ size_t * encoding_size,
+ size_t * stat_count);
+
+/*
+ Free memory allocated by ks_asm()
+
+ @p: memory allocated in @encoding argument of ks_asm()
+*/
+KEYSTONE_EXPORT
+void
+ks_free(unsigned char * p);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/include/keystone/mips.h b/hyperdbg/include/keystone/mips.h
new file mode 100644
index 00000000..e71c553c
--- /dev/null
+++ b/hyperdbg/include/keystone/mips.h
@@ -0,0 +1,23 @@
+/* Keystone Assembler Engine */
+/* By Nguyen Anh Quynh, 2016 */
+
+#ifndef KEYSTONE_MIPS_H
+#define KEYSTONE_MIPS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "keystone.h"
+
+typedef enum ks_err_asm_mips {
+ KS_ERR_ASM_MIPS_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_MIPS_MISSINGFEATURE,
+ KS_ERR_ASM_MIPS_MNEMONICFAIL,
+} ks_err_asm_mips;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/include/keystone/ppc.h b/hyperdbg/include/keystone/ppc.h
new file mode 100644
index 00000000..39a602c2
--- /dev/null
+++ b/hyperdbg/include/keystone/ppc.h
@@ -0,0 +1,24 @@
+/* Keystone Assembler Engine */
+/* By Nguyen Anh Quynh, 2016 */
+
+#ifndef KEYSTONE_PPC_H
+#define KEYSTONE_PPC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "keystone.h"
+
+typedef enum ks_err_asm_ppc {
+ KS_ERR_ASM_PPC_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_PPC_MISSINGFEATURE,
+ KS_ERR_ASM_PPC_MNEMONICFAIL,
+} ks_err_asm_ppc;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/include/keystone/riscv.h b/hyperdbg/include/keystone/riscv.h
new file mode 100644
index 00000000..0910f986
--- /dev/null
+++ b/hyperdbg/include/keystone/riscv.h
@@ -0,0 +1,24 @@
+/* Keystone Assembler Engine */
+/* By Nguyen Anh Quynh, 2016 */
+/* Added by Mark Juvan, 2023*/
+#ifndef KEYSTONE_RISCV_H
+#define KEYSTONE_RISCV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "keystone.h"
+
+typedef enum ks_err_asm_riscv {
+ KS_ERR_ASM_RISCV_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_RISCV_MISSINGFEATURE,
+ KS_ERR_ASM_RISCV_MNEMONICFAIL,
+} ks_err_asm_riscv;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/include/keystone/sparc.h b/hyperdbg/include/keystone/sparc.h
new file mode 100644
index 00000000..e49c4264
--- /dev/null
+++ b/hyperdbg/include/keystone/sparc.h
@@ -0,0 +1,24 @@
+/* Keystone Assembler Engine */
+/* By Nguyen Anh Quynh, 2016 */
+
+#ifndef KEYSTONE_SPARC_H
+#define KEYSTONE_SPARC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "keystone.h"
+
+typedef enum ks_err_asm_sparc {
+ KS_ERR_ASM_SPARC_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_SPARC_MISSINGFEATURE,
+ KS_ERR_ASM_SPARC_MNEMONICFAIL,
+} ks_err_asm_sparc;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/include/keystone/systemz.h b/hyperdbg/include/keystone/systemz.h
new file mode 100644
index 00000000..ec2b07a4
--- /dev/null
+++ b/hyperdbg/include/keystone/systemz.h
@@ -0,0 +1,24 @@
+/* Keystone Assembler Engine */
+/* By Nguyen Anh Quynh, 2016 */
+
+#ifndef KEYSTONE_SYSTEMZ_H
+#define KEYSTONE_SYSTEMZ_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "keystone.h"
+
+typedef enum ks_err_asm_systemz {
+ KS_ERR_ASM_SYSTEMZ_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_SYSTEMZ_MISSINGFEATURE,
+ KS_ERR_ASM_SYSTEMZ_MNEMONICFAIL,
+} ks_err_asm_systemz;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/include/keystone/x86.h b/hyperdbg/include/keystone/x86.h
new file mode 100644
index 00000000..1fac684e
--- /dev/null
+++ b/hyperdbg/include/keystone/x86.h
@@ -0,0 +1,23 @@
+/* Keystone Assembler Engine */
+/* By Nguyen Anh Quynh, 2016 */
+
+#ifndef KEYSTONE_X86_H
+#define KEYSTONE_X86_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "keystone.h"
+
+typedef enum ks_err_asm_x86 {
+ KS_ERR_ASM_X86_INVALIDOPERAND = KS_ERR_ASM_ARCH,
+ KS_ERR_ASM_X86_MISSINGFEATURE,
+ KS_ERR_ASM_X86_MNEMONICFAIL,
+} ks_err_asm_x86;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hyperdbg/include/platform/general/code/.gitkeep b/hyperdbg/include/platform/general/code/.gitkeep
new file mode 100644
index 00000000..e69de29b
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/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/hprdbghv/header/common/Dpc.h b/hyperdbg/include/platform/kernel/header/PlatformBroadcast.h
similarity index 56%
rename from hyperdbg/hprdbghv/header/common/Dpc.h
rename to hyperdbg/include/platform/kernel/header/PlatformBroadcast.h
index 30b419ec..97b2bab1 100644
--- a/hyperdbg/hprdbghv/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/Windows.h b/hyperdbg/include/platform/user/header/Windows.h
new file mode 100644
index 00000000..79f0c3a9
--- /dev/null
+++ b/hyperdbg/include/platform/user/header/Windows.h
@@ -0,0 +1,178 @@
+/**
+ * @file Windows.h
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Windows specific headers
+ * @details
+ * @version 0.10
+ * @date 2024-06-24
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#pragma once
+
+//////////////////////////////////////////////////
+// Definitions //
+//////////////////////////////////////////////////
+
+typedef struct _RTL_PROCESS_MODULE_INFORMATION
+{
+ PVOID Section;
+ PVOID MappedBase;
+ PVOID ImageBase;
+ ULONG ImageSize;
+ ULONG Flags;
+ USHORT LoadOrderIndex;
+ USHORT InitOrderIndex;
+ USHORT LoadCount;
+ USHORT OffsetToFileName;
+ UCHAR FullPathName[256];
+} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;
+
+typedef struct _RTL_PROCESS_MODULES
+{
+ ULONG NumberOfModules;
+ _Field_size_(NumberOfModules) RTL_PROCESS_MODULE_INFORMATION Modules[1];
+} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;
+
+// Linked lists
+
+FORCEINLINE VOID
+InitializeListHead(
+ _Out_ PLIST_ENTRY ListHead)
+{
+ ListHead->Flink = ListHead->Blink = ListHead;
+}
+
+_Check_return_
+FORCEINLINE BOOLEAN
+IsListEmpty(
+ _In_ PLIST_ENTRY ListHead)
+{
+ return ListHead->Flink == ListHead;
+}
+
+FORCEINLINE BOOLEAN
+RemoveEntryList(
+ _In_ PLIST_ENTRY Entry)
+{
+ PLIST_ENTRY Blink;
+ PLIST_ENTRY Flink;
+
+ Flink = Entry->Flink;
+ Blink = Entry->Blink;
+ Blink->Flink = Flink;
+ Flink->Blink = Blink;
+
+ return Flink == Blink;
+}
+
+FORCEINLINE PLIST_ENTRY
+RemoveHeadList(
+ _Inout_ PLIST_ENTRY ListHead)
+{
+ PLIST_ENTRY Flink;
+ PLIST_ENTRY Entry;
+
+ Entry = ListHead->Flink;
+ Flink = Entry->Flink;
+ ListHead->Flink = Flink;
+ Flink->Blink = ListHead;
+
+ return Entry;
+}
+
+FORCEINLINE PLIST_ENTRY
+RemoveTailList(
+ _Inout_ PLIST_ENTRY ListHead)
+{
+ PLIST_ENTRY Blink;
+ PLIST_ENTRY Entry;
+
+ Entry = ListHead->Blink;
+ Blink = Entry->Blink;
+ ListHead->Blink = Blink;
+ Blink->Flink = ListHead;
+
+ return Entry;
+}
+
+FORCEINLINE VOID
+InsertTailList(
+ _Inout_ PLIST_ENTRY ListHead,
+ _Inout_ PLIST_ENTRY Entry)
+{
+ PLIST_ENTRY Blink;
+
+ Blink = ListHead->Blink;
+ Entry->Flink = ListHead;
+ Entry->Blink = Blink;
+ Blink->Flink = Entry;
+ ListHead->Blink = Entry;
+}
+
+FORCEINLINE VOID
+InsertHeadList(
+ _Inout_ PLIST_ENTRY ListHead,
+ _Inout_ PLIST_ENTRY Entry)
+{
+ PLIST_ENTRY Flink;
+
+ Flink = ListHead->Flink;
+ Entry->Flink = Flink;
+ Entry->Blink = ListHead;
+ Flink->Blink = Entry;
+ ListHead->Flink = Entry;
+}
+
+FORCEINLINE VOID
+AppendTailList(
+ _Inout_ PLIST_ENTRY ListHead,
+ _Inout_ PLIST_ENTRY ListToAppend)
+{
+ PLIST_ENTRY ListEnd = ListHead->Blink;
+
+ ListHead->Blink->Flink = ListToAppend;
+ ListHead->Blink = ListToAppend->Blink;
+ ListToAppend->Blink->Flink = ListHead;
+ ListToAppend->Blink = ListEnd;
+}
+
+FORCEINLINE PSINGLE_LIST_ENTRY
+PopEntryList(
+ _Inout_ PSINGLE_LIST_ENTRY ListHead)
+{
+ PSINGLE_LIST_ENTRY FirstEntry;
+
+ FirstEntry = ListHead->Next;
+
+ if (FirstEntry)
+ ListHead->Next = FirstEntry->Next;
+
+ return FirstEntry;
+}
+
+FORCEINLINE VOID
+PushEntryList(
+ _Inout_ PSINGLE_LIST_ENTRY ListHead,
+ _Inout_ PSINGLE_LIST_ENTRY Entry)
+{
+ Entry->Next = ListHead->Next;
+ ListHead->Next = Entry;
+}
+
+//
+// MessageId: STATUS_UNSUCCESSFUL
+//
+// MessageText:
+//
+// {Operation Failed}
+// The requested operation was unsuccessful.
+//
+#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
+
+typedef enum _SYSTEM_INFORMATION_CLASS2
+{
+ SystemModuleInformation = 11 // q: RTL_PROCESS_MODULES
+
+} SYSTEM_INFORMATION_CLASS2;
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/include/ZycoreExportConfig.h b/hyperdbg/include/zydis/ZycoreExportConfig.h
similarity index 100%
rename from hyperdbg/include/ZycoreExportConfig.h
rename to hyperdbg/include/zydis/ZycoreExportConfig.h
diff --git a/hyperdbg/include/ZydisExportConfig.h b/hyperdbg/include/zydis/ZydisExportConfig.h
similarity index 100%
rename from hyperdbg/include/ZydisExportConfig.h
rename to hyperdbg/include/zydis/ZydisExportConfig.h
diff --git a/hyperdbg/kdserial/CMakeLists.txt b/hyperdbg/kdserial/CMakeLists.txt
new file mode 100644
index 00000000..922affe9
--- /dev/null
+++ b/hyperdbg/kdserial/CMakeLists.txt
@@ -0,0 +1,29 @@
+# Code generated by Visual Studio kit, DO NOT EDIT.
+set(SourceFiles
+ "common.c"
+ "hardware.c"
+ "ioaccess.c"
+ "uartio.c"
+ "apm88xxxx.c"
+ "bcm2835.c"
+ "msm8974.c"
+ "msm8x60.c"
+ "mx6uart.c"
+ "nvidia.c"
+ "omap.c"
+ "pl011.c"
+ "sam5250.c"
+ "sdm845.c"
+ "spimax311.c"
+ "uart16550.c"
+ "usif.c"
+ "kdcom.h"
+ "uartp.h"
+ "common.h"
+ "win11sdk.h"
+ "kdserial.def"
+)
+wdk_add_library(kdserial SHARED
+ KMDF 1.15
+ ${SourceFiles}
+)
diff --git a/hyperdbg/kdserial/kdserial.vcxproj b/hyperdbg/kdserial/kdserial.vcxproj
index 5e17ff37..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
@@ -94,6 +100,7 @@
$(IntDir);%(AdditionalIncludeDirectories);$(KM_IncludePath);$(ProjectDir)..\..\incDefaulttrue
+ stdcpp20$(DDK_LIB_PATH);%(AdditionalLibraryDirectories);$(SolutionDir)libraries\kdserial\$(PlatformTarget)
@@ -116,6 +123,8 @@
$(IntDir);%(AdditionalIncludeDirectories);$(KM_IncludePath);$(ProjectDir)..\..\inctrue
+ stdcpp20
+ Full$(DDK_LIB_PATH);%(AdditionalLibraryDirectories);$(SolutionDir)libraries\kdserial\$(PlatformTarget)
@@ -135,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
new file mode 100644
index 00000000..fac7603f
--- /dev/null
+++ b/hyperdbg/libhyperdbg/CMakeLists.txt
@@ -0,0 +1,193 @@
+# Code generated by Visual Studio kit, DO NOT EDIT.
+set(SourceFiles
+ "../include/platform/general/header/Environment.h"
+ "../include/platform/user/header/Windows.h"
+ "header/assembler.h"
+ "header/commands.h"
+ "header/common.h"
+ "header/communication.h"
+ "header/debugger.h"
+ "header/export.h"
+ "header/forwarding.h"
+ "header/globals.h"
+ "header/help.h"
+ "header/hwdbg-interpreter.h"
+ "header/inipp.h"
+ "header/install.h"
+ "header/kd.h"
+ "header/libhyperdbg.h"
+ "header/list.h"
+ "header/namedpipe.h"
+ "header/objects.h"
+ "header/pe-parser.h"
+ "header/rev-ctrl.h"
+ "header/script-engine.h"
+ "header/symbol.h"
+ "header/tests.h"
+ "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"
+ "../script-eval/code/Regs.c"
+ "../script-eval/code/ScriptEngineEval.c"
+ "code/common/spinlock.cpp"
+ "code/debugger/commands/debugging-commands/a.cpp"
+ "code/debugger/commands/debugging-commands/core.cpp"
+ "code/debugger/commands/debugging-commands/dt-struct.cpp"
+ "code/debugger/commands/debugging-commands/gu.cpp"
+ "code/debugger/commands/debugging-commands/k.cpp"
+ "code/debugger/commands/debugging-commands/preactivate.cpp"
+ "code/debugger/commands/debugging-commands/prealloc.cpp"
+ "code/debugger/commands/extension-commands/crwrite.cpp"
+ "code/debugger/commands/extension-commands/rev.cpp"
+ "code/debugger/commands/extension-commands/trace.cpp"
+ "code/debugger/commands/extension-commands/track.cpp"
+ "code/debugger/commands/extension-commands/mode.cpp"
+ "code/debugger/commands/hwdbg-commands/hw_clk.cpp"
+ "code/debugger/commands/meta-commands/dump.cpp"
+ "code/debugger/commands/meta-commands/kill.cpp"
+ "code/debugger/commands/meta-commands/pagein.cpp"
+ "code/debugger/commands/meta-commands/pe.cpp"
+ "code/debugger/commands/meta-commands/restart.cpp"
+ "code/debugger/commands/meta-commands/start.cpp"
+ "code/debugger/commands/meta-commands/switch.cpp"
+ "code/debugger/commands/meta-commands/thread.cpp"
+ "code/debugger/core/break-control.cpp"
+ "code/debugger/core/debugger.cpp"
+ "code/debugger/core/interpreter.cpp"
+ "code/debugger/kernel-level/kd.cpp"
+ "code/debugger/kernel-level/kernel-listening.cpp"
+ "code/debugger/misc/assembler.cpp"
+ "code/debugger/misc/callstack.cpp"
+ "code/debugger/misc/disassembler.cpp"
+ "code/debugger/misc/readmem.cpp"
+ "code/debugger/script-engine/script-engine-wrapper.cpp"
+ "code/debugger/script-engine/script-engine.cpp"
+ "code/debugger/script-engine/symbol.cpp"
+ "code/debugger/user-level/pe-parser.cpp"
+ "code/debugger/user-level/ud.cpp"
+ "code/debugger/user-level/user-listening.cpp"
+ "code/export/export.cpp"
+ "code/hwdbg/hwdbg-interpreter.cpp"
+ "code/objects/objects.cpp"
+ "code/rev/rev-ctrl.cpp"
+ "pch.cpp"
+ "code/app/dllmain.cpp"
+ "code/app/libhyperdbg.cpp"
+ "code/common/common.cpp"
+ "code/common/list.cpp"
+ "code/debugger/commands/debugging-commands/bc.cpp"
+ "code/debugger/commands/debugging-commands/bd.cpp"
+ "code/debugger/commands/debugging-commands/be.cpp"
+ "code/debugger/commands/debugging-commands/bl.cpp"
+ "code/debugger/commands/debugging-commands/bp.cpp"
+ "code/debugger/commands/debugging-commands/cpu.cpp"
+ "code/debugger/commands/debugging-commands/d-u.cpp"
+ "code/debugger/commands/debugging-commands/e.cpp"
+ "code/debugger/commands/debugging-commands/eval.cpp"
+ "code/debugger/commands/debugging-commands/events.cpp"
+ "code/debugger/commands/debugging-commands/exit.cpp"
+ "code/debugger/commands/debugging-commands/flush.cpp"
+ "code/debugger/commands/debugging-commands/g.cpp"
+ "code/debugger/commands/debugging-commands/i.cpp"
+ "code/debugger/commands/debugging-commands/lm.cpp"
+ "code/debugger/commands/debugging-commands/load.cpp"
+ "code/debugger/commands/debugging-commands/output.cpp"
+ "code/debugger/commands/debugging-commands/p.cpp"
+ "code/debugger/commands/debugging-commands/pause.cpp"
+ "code/debugger/commands/debugging-commands/print.cpp"
+ "code/debugger/commands/debugging-commands/r.cpp"
+ "code/debugger/commands/debugging-commands/rdmsr.cpp"
+ "code/debugger/commands/debugging-commands/s.cpp"
+ "code/debugger/commands/debugging-commands/settings.cpp"
+ "code/debugger/commands/debugging-commands/sleep.cpp"
+ "code/debugger/commands/debugging-commands/t.cpp"
+ "code/debugger/commands/debugging-commands/test.cpp"
+ "code/debugger/commands/debugging-commands/unload.cpp"
+ "code/debugger/commands/debugging-commands/wrmsr.cpp"
+ "code/debugger/commands/debugging-commands/x.cpp"
+ "code/debugger/commands/extension-commands/cpuid.cpp"
+ "code/debugger/commands/extension-commands/dr.cpp"
+ "code/debugger/commands/extension-commands/epthook.cpp"
+ "code/debugger/commands/extension-commands/epthook2.cpp"
+ "code/debugger/commands/extension-commands/exception.cpp"
+ "code/debugger/commands/extension-commands/hide.cpp"
+ "code/debugger/commands/extension-commands/interrupt.cpp"
+ "code/debugger/commands/extension-commands/ioin.cpp"
+ "code/debugger/commands/extension-commands/ioout.cpp"
+ "code/debugger/commands/extension-commands/measure.cpp"
+ "code/debugger/commands/extension-commands/monitor.cpp"
+ "code/debugger/commands/extension-commands/msrread.cpp"
+ "code/debugger/commands/extension-commands/msrwrite.cpp"
+ "code/debugger/commands/extension-commands/pa2va.cpp"
+ "code/debugger/commands/extension-commands/pmc.cpp"
+ "code/debugger/commands/extension-commands/pte.cpp"
+ "code/debugger/commands/extension-commands/syscall-sysret.cpp"
+ "code/debugger/commands/extension-commands/tsc.cpp"
+ "code/debugger/commands/extension-commands/unhide.cpp"
+ "code/debugger/commands/extension-commands/va2pa.cpp"
+ "code/debugger/commands/extension-commands/vmcall.cpp"
+ "code/debugger/commands/meta-commands/attach.cpp"
+ "code/debugger/commands/meta-commands/cls.cpp"
+ "code/debugger/commands/meta-commands/connect.cpp"
+ "code/debugger/commands/meta-commands/debug.cpp"
+ "code/debugger/commands/meta-commands/detach.cpp"
+ "code/debugger/commands/meta-commands/disconnect.cpp"
+ "code/debugger/commands/meta-commands/formats.cpp"
+ "code/debugger/commands/meta-commands/help.cpp"
+ "code/debugger/commands/meta-commands/listen.cpp"
+ "code/debugger/commands/meta-commands/logclose.cpp"
+ "code/debugger/commands/meta-commands/logopen.cpp"
+ "code/debugger/commands/meta-commands/process.cpp"
+ "code/debugger/commands/meta-commands/script.cpp"
+ "code/debugger/commands/meta-commands/status.cpp"
+ "code/debugger/commands/meta-commands/sym.cpp"
+ "code/debugger/commands/meta-commands/sympath.cpp"
+ "code/debugger/communication/forwarding.cpp"
+ "code/debugger/communication/namedpipe.cpp"
+ "code/debugger/communication/remote-connection.cpp"
+ "code/debugger/communication/tcpclient.cpp"
+ "code/debugger/communication/tcpserver.cpp"
+ "code/debugger/driver-loader/install.cpp"
+ "code/debugger/tests/tests.cpp"
+ "code/debugger/transparency/gaussian-rng.cpp"
+ "code/debugger/transparency/transparency.cpp"
+ "code/assembly/asm-vmx-checks.asm"
+)
+include_directories(
+ "../dependencies/phnt"
+ "../dependencies"
+ "../dependencies/zydis/dependencies/zycore/include"
+ "../include"
+ "../dependencies/zydis/include"
+ "."
+ "../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/hprdbgctrl/code/app/dllmain.cpp b/hyperdbg/libhyperdbg/code/app/dllmain.cpp
similarity index 100%
rename from hyperdbg/hprdbgctrl/code/app/dllmain.cpp
rename to hyperdbg/libhyperdbg/code/app/dllmain.cpp
diff --git a/hyperdbg/libhyperdbg/code/app/libhyperdbg.cpp b/hyperdbg/libhyperdbg/code/app/libhyperdbg.cpp
new file mode 100644
index 00000000..5a2c812a
--- /dev/null
+++ b/hyperdbg/libhyperdbg/code/app/libhyperdbg.cpp
@@ -0,0 +1,937 @@
+/**
+ * @file libhyperdbg.cpp
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief Main interface to connect applications to driver
+ * @details
+ * @version 0.1
+ * @date 2020-04-11
+ *
+ * @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 TCHAR g_DriverLocation[MAX_PATH];
+extern TCHAR g_DriverName[MAX_PATH];
+extern BOOLEAN g_UseCustomDriverLocation;
+extern LIST_ENTRY g_EventTrace;
+extern BOOLEAN g_IsKdModuleLoaded;
+extern BOOLEAN g_IsVmmModuleLoaded;
+extern BOOLEAN g_IsHyperTraceModuleLoaded;
+
+/**
+ * @brief Install (start) VMM driver
+ *
+ * @return INT return zero if it was successful or non-zero if there
+ * was error
+ */
+INT
+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
+ //
+
+ //
+ // If the user has not specified a custom driver location, then we
+ // need to find the driver in the same directory as the executable
+ //
+ if (!g_UseCustomDriverLocation)
+ {
+ if (!SetupPathForFileName(KERNEL_DEBUGGER_DRIVER_NAME_AND_EXTENSION, g_DriverLocation, sizeof(g_DriverLocation), TRUE))
+ {
+ return 1;
+ }
+
+ //
+ // Use default driver name
+ //
+ strcpy_s(g_DriverName, KERNEL_DEBUGGER_DRIVER_NAME);
+ }
+
+ if (HyperDbgStartDriver() != 0)
+ {
+ ShowMessages("unable to install KD driver\n");
+
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Start KD driver
+ *
+ * @return INT return zero if it was successful or non-zero if there was error
+ */
+INT
+HyperDbgStartKdDriver()
+{
+ return HyperDbgStartDriver();
+}
+
+/**
+ * @brief Stop KD driver
+ *
+ * @return INT return zero if it was successful or non-zero if there was error
+ */
+INT
+HyperDbgStopKdDriver()
+{
+ return HyperDbgStopDriver(g_DriverName);
+}
+
+/**
+ * @brief Remove the driver
+ *
+ * @return INT return zero if it was successful or non-zero if there
+ * was error
+ */
+INT
+HyperDbgUninstallDriver(LPCTSTR DriverName)
+{
+ //
+ // Unload the driver if loaded. Ignore any errors
+ //
+ if (g_DriverLocation[0] != (TCHAR)0 && ManageDriver(DriverName, g_DriverLocation, DRIVER_FUNC_REMOVE))
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+/**
+ * @brief Remove the KD (Kernel Debugger) driver
+ *
+ * @return INT return zero if it was successful or non-zero if there
+ * was error
+ */
+INT
+HyperDbgUninstallKdDriver()
+{
+ return HyperDbgUninstallDriver(g_DriverName);
+}
+
+/**
+ * @brief Initialize VMM module
+ *
+ * @return INT return zero if it was successful or non-zero if there
+ * was error
+ */
+INT
+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 the 'load' command before, please "
+ "unload it using the 'unload' command\n");
+ return 1;
+ }
+
+ //
+ // Make sure that this variable is false, because it might be set to
+ // true as the result of a previous load
+ //
+ g_IsMessageLoggingWindowClosed = FALSE;
+
+ //
+ // Init entering vmx
+ //
+ g_DeviceHandle = CreateFileA(
+ "\\\\.\\HyperDbgDebuggerDevice",
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, /// lpSecurityAttirbutes
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL); /// lpTemplateFile
+
+ if (g_DeviceHandle == 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 (%x)\n", ErrorNum);
+ }
+
+ g_DeviceHandle = NULL;
+ return 1;
+ }
+
+ //
+ // Initialize the list of events
+ //
+ InitializeListHead(&g_EventTrace);
+
+#if !UseDbgPrintInsteadOfUsermodeMessageTracking
+ HANDLE Thread = CreateThread(NULL, 0, IrpBasedBufferThread, NULL, 0, &ThreadId);
+
+ // if (Thread)
+ // {
+ // ShowMessages("thread Created successfully\n");
+ // }
+
+#endif
+
+ return 0;
+}
+
+/**
+ * @brief Unload VMM module
+ *
+ * @return INT return zero if it was successful or non-zero if there
+ * was error
+ */
+INT
+HyperDbgUnloadVmm()
+{
+ BOOL Status;
+ DWORD BytesReturned;
+
+ AssertShowMessageReturnStmt(g_IsVmmModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_VMM_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnOne);
+
+ 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
+ //
+ UdUninitializeUserDebugger();
+
+ //
+ // Send IOCTL terminate VMX
+ //
+ Status = DeviceIoControl(g_DeviceHandle, // Handle to device
+ IOCTL_TERMINATE_VMX, // 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;
+ }
+
+ //
+ // 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)
+ 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;
+ }
+
+ //
+ // Wait for a while to make sure that all IRP pending are completed and the driver is ready to be unloaded
+ //
+ Sleep(1000);
+
+ //
+ // Send IRP_MJ_CLOSE to driver to terminate Vmxs
+ //
+ if (!CloseHandle(g_DeviceHandle))
+ {
+ ShowMessages("err, closing handle 0x%x\n", GetLastError());
+ return 1;
+ };
+
+ //
+ // Null the handle to indicate that the driver's device is not ready
+ // to use
+ //
+ g_DeviceHandle = NULL;
+
+ //
+ // Debugger module is not loaded anymore
+ //
+ g_IsKdModuleLoaded = FALSE;
+
+ //
+ // Check if we found an already built symbol table
+ //
+ SymbolDeleteSymTable();
+
+ 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
+ *
+ * @return int return zero if it was successful or non-zero if there
+ */
+INT
+HyperDbgLoadVmmModule()
+{
+ //
+ // 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;
+ }
+
+ //
+ // Check if the HyperTrace module is loaded or not
+ //
+ if (g_IsHyperTraceModuleLoaded)
+ {
+ 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;
+ }
+
+ //
+ // Check if the processor is a genuine Intel processor (required for VT-x)
+ //
+ if (HyperDbgGetProcessorVendor() != GENERIC_PROCESSOR_VENDOR_INTEL)
+ {
+ 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 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
+ return 1;
+ }
+
+ //
+ // Load the KD module and create handle to it
+ //
+ if (HyperDbgLoadKdModule() == 1)
+ {
+ return 1;
+ }
+
+ //
+ // Initialize VMM module
+ //
+ if (HyperDbgInitVmmModule() == 1)
+ {
+ ShowMessages("err, initializing VMM module\n");
+
+ return 1;
+ }
+
+ //
+ // If we reach here so the module are loaded
+ //
+ 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/hprdbgctrl/code/assembly/asm-vmx-checks.asm b/hyperdbg/libhyperdbg/code/assembly/asm-vmx-checks.asm
similarity index 72%
rename from hyperdbg/hprdbgctrl/code/assembly/asm-vmx-checks.asm
rename to hyperdbg/libhyperdbg/code/assembly/asm-vmx-checks.asm
index bc2360d7..dd81a1d8 100644
--- a/hyperdbg/hprdbgctrl/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/hprdbgctrl/code/common/common.cpp b/hyperdbg/libhyperdbg/code/common/common.cpp
similarity index 82%
rename from hyperdbg/hprdbgctrl/code/common/common.cpp
rename to hyperdbg/libhyperdbg/code/common/common.cpp
index 27182631..2f494eab 100644
--- a/hyperdbg/hprdbgctrl/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 &)
@@ -435,6 +435,127 @@ ConvertStringToUInt32(string TextToConvert, PUINT32 Result)
}
}
+/**
+ * @brief check and convert command token to a 64 bit unsigned integer
+ *
+ * @param TargetToken the target command token
+ * @param Result result will be save to the pointer
+ *
+ * @return BOOLEAN shows whether the conversion was successful or not
+ */
+BOOLEAN
+ConvertTokenToUInt64(CommandToken TargetToken, PUINT64 Result)
+{
+ //
+ // Extract the token type and value from the tuple
+ //
+ std::string TargetTokenValue = std::get<1>(TargetToken);
+
+ //
+ // Convert the token value to 64 bit unsigned integer
+ //
+ return ConvertStringToUInt64(TargetTokenValue, Result);
+}
+
+/**
+ * @brief Get case sensitive string from command token
+ *
+ * @param TargetToken the target command token
+ * @return string the string value of the token
+ */
+std::string
+GetCaseSensitiveStringFromCommandToken(CommandToken TargetToken)
+{
+ //
+ // Extract the token type and value from the tuple
+ //
+ std::string TargetTokenValue = std::get<1>(TargetToken); // the first index is case sensitive
+
+ return TargetTokenValue;
+}
+
+/**
+ * @brief Get lower case string from command token
+ *
+ * @param TargetToken the target command token
+ * @return string the string value of the token
+ */
+std::string
+GetLowerStringFromCommandToken(CommandToken TargetToken)
+{
+ //
+ // Extract the token type and value from the tuple
+ //
+ std::string TargetTokenValue = std::get<2>(TargetToken); // the second index is lower case
+
+ return TargetTokenValue;
+}
+
+/**
+ * @brief Compare lower case strings
+ *
+ * @param TargetToken the target command token
+ * @param StringToCompare the string to compare
+ *
+ * @return BOOLEAN shows whether text is equal or not
+ */
+BOOLEAN
+CompareLowerCaseStrings(CommandToken TargetToken, const CHAR * StringToCompare)
+{
+ //
+ // Extract the token type and value from the tuple
+ //
+ std::string TargetTokenValue = std::get<2>(TargetToken); // the second index is lower case
+
+ //
+ // Convert the token value to 64 bit unsigned integer
+ //
+ return _stricmp(TargetTokenValue.c_str(), StringToCompare) == 0;
+}
+
+/**
+ * @brief Is token bracket string
+ *
+ * @param TargetToken the target command token
+ *
+ * @return BOOLEAN shows whether the token is bracket string or not
+ */
+BOOLEAN
+IsTokenBracketString(CommandToken TargetToken)
+{
+ //
+ // Extract the token type and value from the tuple
+ //
+ CommandParsingTokenType TargetTokenValue = std::get<0>(TargetToken);
+
+ //
+ // Check if the token is a bracket string
+ //
+ return TargetTokenValue == CommandParsingTokenType::BracketString;
+}
+
+/**
+ * @brief check and convert command token to a 32 bit unsigned integer
+ *
+ * @param TargetToken the target command token
+ * @param Result result will be save to the pointer
+ *
+ * @return BOOLEAN shows whether the conversion was successful or not
+ */
+BOOLEAN
+ConvertTokenToUInt32(CommandToken TargetToken, PUINT32 Result)
+{
+ //
+ // Extract the token type and value from the tuple
+ //
+ std::string TargetTokenValue = std::get<1>(TargetToken);
+
+ //
+ // Convert the token value to 32 bit unsigned integer
+ //
+ return ConvertStringToUInt32(TargetTokenValue, Result);
+}
+
/**
* @brief checks whether the string ends with a special string or not
*
@@ -501,8 +622,8 @@ ValidateIP(const string & ip)
* @return true if vmx is supported
* @return false if vmx is not supported
*/
-HPRDBGCTRL_API bool
-HyperDbgVmxSupportDetection()
+BOOLEAN
+VmxSupportDetection()
{
//
// Call assembly function
@@ -553,7 +674,7 @@ SetPrivilege(HANDLE Token, // access token handle
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
- ShowMessages("err, the token does not have the specified privilege (ACCESS DENIED!)\n");
+ ShowMessages("err, the token does not have the specified (debug) privilege (ACCESS DENIED!)\n");
ShowMessages("make sure to run it with administrator privileges\n");
return FALSE;
}
@@ -566,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); }));
@@ -577,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); })
@@ -590,7 +711,7 @@ rtrim(std::string & s)
*
* @param s
*/
-void
+VOID
Trim(std::string & s)
{
ltrim(s);
@@ -616,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);
@@ -629,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);
@@ -641,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')
{
@@ -651,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')
{
@@ -733,88 +854,16 @@ StringToWString(std::wstring & ws, const std::string & s)
ws = WsTmp;
}
-/**
- * @brief Split path and arguments and handle strings between quotes
- *
- * @param Qargs
- * @param Command
- * @return VOID
- */
-VOID
-SplitPathAndArgs(std::vector & Qargs, const std::string & Command)
-{
- int Len = (int)Command.length();
- bool Qot = false, Sqot = false;
- int ArgLen;
-
- for (int i = 0; i < Len; i++)
- {
- int start = i;
- if (Command[i] == '\"')
- {
- Qot = true;
- }
- else if (Command[i] == '\'')
- Sqot = true;
-
- if (Qot)
- {
- i++;
- start++;
- while (i < Len && Command[i] != '\"')
- i++;
- if (i < Len)
- Qot = false;
- ArgLen = i - start;
- i++;
- }
- else if (Sqot)
- {
- i++;
- while (i < Len && Command[i] != '\'')
- i++;
- if (i < Len)
- Sqot = false;
- ArgLen = i - start;
- i++;
- }
- else
- {
- while (i < Len && Command[i] != ' ')
- i++;
- ArgLen = i - start;
- }
-
- string Temp = Command.substr(start, ArgLen);
- if (!Temp.empty() && Temp != " ")
- {
- Qargs.push_back(Temp);
- }
- }
-
- /*
- for (int i = 0; i < Qargs.size(); i++)
- {
- std::cout << Qargs[i] << std::endl;
- }
-
- std::cout << Qargs.size();
-
- if (Qot || Sqot)
- std::cout << "One of the quotes is open\n";
- */
-}
-
/**
* @brief Find case insensitive sub string in a given substring
*
* @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);
@@ -830,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);
@@ -849,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);
}
/**
@@ -884,7 +931,7 @@ CommonCpuidInstruction(UINT32 Func, UINT32 SubFunc, int * CpuInfo)
UINT32
Getx86VirtualAddressWidth()
{
- int Regs[4];
+ INT Regs[4];
CommonCpuidInstruction(CPUID_ADDR_WIDTH, 0, Regs);
@@ -902,8 +949,8 @@ Getx86VirtualAddressWidth()
BOOLEAN
CheckCpuSupportRtm()
{
- int Regs1[4];
- int Regs2[4];
+ INT Regs1[4];
+ INT Regs2[4];
BOOLEAN Result;
//
@@ -1205,3 +1252,24 @@ CheckAccessValidityAndSafety(UINT64 TargetAddress, UINT32 Size)
//
return TRUE;
}
+
+/**
+ * @brief Function to compute log2Ceil
+ * @param n
+ *
+ * @return UINT32
+ */
+UINT32
+Log2Ceil(UINT32 n)
+{
+ if (n == 0)
+ return 0; // log2Ceil(0) is undefined, returning 0 for safety.
+
+ n--; // Decrease by 1 to check if it is a power of 2
+ UINT32 log2Floor = 0;
+ while (n >>= 1)
+ {
+ log2Floor++;
+ }
+ return log2Floor + 1;
+}
diff --git a/hyperdbg/hprdbgctrl/code/common/spinlock.cpp b/hyperdbg/libhyperdbg/code/common/spinlock.cpp
similarity index 73%
rename from hyperdbg/hprdbgctrl/code/common/spinlock.cpp
rename to hyperdbg/libhyperdbg/code/common/spinlock.cpp
index 4303a100..96cc5e0c 100644
--- a/hyperdbg/hprdbgctrl/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
new file mode 100644
index 00000000..c7aca424
--- /dev/null
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/a.cpp
@@ -0,0 +1,297 @@
+/**
+ * @file a.cpp
+ * @author Abbas Masoumi Gorji (AbbasMG@hyperdbg.org)
+ * @brief a command
+ * @details
+ * @version 0.10
+ * @date 2024-07-15
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
+
+class _CMD
+{
+public:
+ std::string CommandStr;
+ std::string AddressStr;
+ std::string AsmSnippet;
+ std::string StartAddressStr;
+ std::string ProcIdStr;
+
+ _CMD() = default;
+
+ bool isEmpty() const
+ {
+ return CommandStr.empty() &&
+ AddressStr.empty() &&
+ AsmSnippet.empty() &&
+ StartAddressStr.empty() &&
+ ProcIdStr.empty();
+ }
+};
+
+/**
+ * @brief help of a and !a command
+ *
+ * @return VOID
+ */
+VOID
+CommandAssembleHelp()
+{
+ ShowMessages("a !a : assembles snippet at specific address. symbols are supported.\n");
+ ShowMessages("\nIf you want to assemble to physical (address) memory then add '!' "
+ "at the start of the command\n");
+
+ ShowMessages("syntax : \ta [Address (hex)] [asm {AsmCmd1; AsmCmd2}] [pid ProcessId (hex)]\n");
+ ShowMessages("syntax : \t!a [Address (hex)] [asm {AsmCmd1; AsmCmd2}]\n");
+
+ ShowMessages("\n");
+ ShowMessages("\t\te.g : a fffff8077356f010 {nop; nop; nop} \n");
+ ShowMessages("\t\te.g : a nt!ExAllocatePoolWithTag+10+@rcx {jmp } \n");
+ ShowMessages("\t\te.g : a nt!ExAllocatePoolWithTag {add DWORD PTR [], 99} \n");
+ ShowMessages("\t\t note that within assembly snippet, symbols must be enclosed by \" <> \"\n");
+ ShowMessages("\t\t note that type specifier must be capital\n");
+
+ ShowMessages("\n");
+ ShowMessages("\tto merely view the byte code of an assembly snippet:\n");
+ ShowMessages("\t\ta {jmp } [StartAddress]\n");
+ ShowMessages("\t\t\"StartAddress\" is useful when dealing with relative instructions like \" jmp \" ");
+}
+
+_CMD
+ParseUserCmd(const std::string & command)
+{
+ std::vector CmdVec;
+ _CMD CMD {};
+ _CMD CmdEmpty {};
+
+ auto CmdIt = command.begin();
+ auto CmdEnd = command.end();
+
+ while (CmdIt != CmdEnd)
+ {
+ //
+ // skip leading whitespace
+ //
+ CmdIt = std::find_if_not(CmdIt, CmdEnd, ::isspace);
+ if (CmdIt == CmdEnd)
+ break;
+ if (*CmdIt == '{')
+ {
+ //
+ // find matching closing brace
+ //
+ auto CloseIt = std::find(CmdIt + 1, CmdEnd, '}');
+ if (CloseIt != CmdEnd)
+ {
+ if (CmdVec.size() < 2)
+ {
+ //
+ // if yes, asm snippet was provided right after "a" command (2nd index)
+ // i.e. no address were provided to assembling to
+ //
+ CmdVec.emplace_back(""); // empty address string
+ }
+ std::string RawAsm(CmdIt + 1, CloseIt); // remove "{}"
+ CmdVec.emplace_back(RawAsm);
+ CmdIt = CloseIt + 1;
+ }
+ else
+ {
+ //
+ // no matching brace
+ //
+ ShowMessages("err, assembly snippet is not closed.");
+ }
+ }
+ else
+ {
+ //
+ // normal text, find next space
+ //
+ auto SpaceIt = std::find_if(CmdIt, CmdEnd, ::isspace);
+ CmdVec.emplace_back(CmdIt, SpaceIt);
+ CmdIt = SpaceIt;
+ }
+ }
+
+ //
+ // Check if there is any "pid"
+ //
+ auto PidIt = std::find_if(CmdVec.begin(), CmdVec.end(), [](const std::string & s) { return s.find("pid") != std::string::npos; });
+ if (PidIt != CmdVec.end())
+ {
+ bool IsLast = (PidIt == std::prev(CmdVec.end()));
+ bool IsSecondLast = (PidIt == std::prev(CmdVec.end(), 2));
+ if (!IsLast && !IsSecondLast)
+ {
+ ShowMessages("pid must be the last argument");
+ return CmdEmpty;
+ }
+ if (g_IsSerialConnectedToRemoteDebuggee)
+ {
+ ShowMessages(ASSERT_MESSAGE_CANNOT_SPECIFY_PID);
+ return CmdEmpty;
+ }
+
+ if (std::next(PidIt) != CmdVec.end()) // is there anything after "pid"?
+ {
+ CMD.ProcIdStr = std::string(*(++PidIt));
+ }
+ else
+ {
+ ShowMessages("no hex number was provided as process id\n\n");
+ return CmdEmpty;
+ }
+ }
+ else
+ {
+ //
+ // user didn't provide pid at all. ignoring.
+ //
+ }
+
+ //
+ // fill the CMD object. will be optimized later
+ //
+ if (CmdVec.size() > 0)
+ CMD.CommandStr = CmdVec.at(0);
+ if (CmdVec.size() > 1)
+ CMD.AddressStr = CmdVec.at(1);
+ if (CmdVec.size() > 2)
+ CMD.AsmSnippet = CmdVec.at(2);
+ if (CmdVec.size() > 3)
+ CMD.StartAddressStr = CmdVec.at(3);
+ // if (CmdVec.size() > 4) CMD.ProcId_str = CmdVec.at(5); 4 is the "pid" string
+
+ return CMD;
+}
+
+/**
+ * @brief a and !a commands handler
+ *
+ * @param CommandTokens
+ * @param Command
+ * @return VOID
+ */
+VOID
+CommandAssemble(vector CommandTokens, string Command)
+{
+ DEBUGGER_EDIT_MEMORY_TYPE MemoryType {};
+ _CMD CMD {};
+ UINT64 Address {};
+ UINT64 StartAddress {};
+ UINT32 ProcId = 0;
+
+ CMD = ParseUserCmd(Command);
+
+ if (CMD.isEmpty())
+ {
+ //
+ // Error messages are already printed
+ //
+ return;
+ }
+
+ if (!CMD.ProcIdStr.empty())
+ {
+ if (!ConvertStringToUInt32(CMD.ProcIdStr, &ProcId))
+ {
+ ShowMessages("please specify a correct hex process id\n\n");
+ CommandAssembleHelp();
+ return;
+ }
+ }
+
+ if (g_ActiveProcessDebuggingState.IsActive)
+ {
+ ProcId = g_ActiveProcessDebuggingState.ProcessId;
+ }
+
+ if (CMD.AsmSnippet.empty())
+ {
+ ShowMessages("no assembly snippet provided\n");
+ CommandAssembleHelp();
+ return;
+ }
+ else if (CMD.CommandStr == "a")
+ {
+ MemoryType = EDIT_VIRTUAL_MEMORY;
+ }
+ else if (CMD.CommandStr == "!a")
+ {
+ MemoryType = EDIT_PHYSICAL_MEMORY;
+ }
+ else
+ {
+ ShowMessages("unknown assemble command\n\n");
+ CommandAssembleHelp();
+ return;
+ }
+
+ //
+ // Fetching start_address i.e. address to assemble to
+ //
+ if (!CMD.AddressStr.empty()) // was any address provided to assemble to?
+ {
+ if (!SymbolConvertNameOrExprToAddress(CMD.AddressStr, &Address))
+ {
+ ShowMessages("err, couldn't resolve Address at '%s'\n\n",
+ CMD.AddressStr.c_str());
+ CommandAssembleHelp();
+ return;
+ }
+ }
+ else if (!CMD.StartAddressStr.empty()) // was a custom start_address provided?
+ {
+ if (!SymbolConvertNameOrExprToAddress(CMD.StartAddressStr, &StartAddress))
+ {
+ ShowMessages("err, couldn't resolve Address at '%s'\n\n",
+ CMD.StartAddressStr.c_str());
+ CommandAssembleHelp();
+ return;
+ }
+ Address = StartAddress;
+ }
+ else
+ {
+ ShowMessages("warning, no start address provided to calculate relative asm commands\n\n");
+ }
+
+ AssembleData AssembleData;
+ AssembleData.AsmRaw = CMD.AsmSnippet; // third element
+ AssembleData.ParseAssemblyData();
+
+ if (AssembleData.Assemble(Address))
+ {
+ ShowMessages("err, code: '%u'\n\n", AssembleData.KsErr);
+ CommandAssembleHelp();
+ return;
+ }
+
+ if (ProcId == 0)
+ {
+ ProcId = PlatformGetCurrentProcessId();
+ }
+
+ if (Address) // was the user only trying to get the bytes?
+ {
+ if (HyperDbgWriteMemory(
+ (PVOID)Address,
+ MemoryType,
+ ProcId,
+ (PVOID)AssembleData.EncodedBytes,
+ (UINT32)AssembleData.BytesCount))
+ {
+ ShowMessages("successfully assembled at 0x%016llx address\n", static_cast(Address));
+ }
+ else
+ {
+ ShowMessages("failed to write generated assembly to memory\n");
+ }
+ }
+}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/bc.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/bc.cpp
similarity index 84%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/bc.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/bc.cpp
index bf6c6b38..4955075c 100644
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/bc.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/bc.cpp
@@ -36,12 +36,13 @@ CommandBcHelp()
/**
* @brief handler of bc command
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandBc(vector SplitCommand, string Command)
+CommandBc(vector CommandTokens, string Command)
{
UINT64 BreakpointId;
DEBUGGEE_BP_LIST_OR_MODIFY_PACKET Request = {0};
@@ -49,9 +50,10 @@ CommandBc(vector SplitCommand, string Command)
//
// Validate the commands
//
- if (SplitCommand.size() != 2)
+ if (CommandTokens.size() != 2)
{
- ShowMessages("incorrect use of the 'bc'\n\n");
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandBcHelp();
return;
}
@@ -59,7 +61,7 @@ CommandBc(vector SplitCommand, string Command)
//
// Get the breakpoint id
//
- if (!ConvertStringToUInt64(SplitCommand.at(1), &BreakpointId))
+ if (!ConvertTokenToUInt64(CommandTokens.at(1), &BreakpointId))
{
ShowMessages("please specify a correct hex value for breakpoint id\n\n");
CommandBcHelp();
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/bd.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/bd.cpp
similarity index 84%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/bd.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/bd.cpp
index f79206fc..6d10ba99 100644
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/bd.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/bd.cpp
@@ -36,12 +36,13 @@ CommandBdHelp()
/**
* @brief handler of bd command
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandBd(vector SplitCommand, string Command)
+CommandBd(vector CommandTokens, string Command)
{
UINT64 BreakpointId;
DEBUGGEE_BP_LIST_OR_MODIFY_PACKET Request = {0};
@@ -49,9 +50,10 @@ CommandBd(vector SplitCommand, string Command)
//
// Validate the commands
//
- if (SplitCommand.size() != 2)
+ if (CommandTokens.size() != 2)
{
- ShowMessages("incorrect use of the 'bd'\n\n");
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandBdHelp();
return;
}
@@ -59,7 +61,7 @@ CommandBd(vector SplitCommand, string Command)
//
// Get the breakpoint id
//
- if (!ConvertStringToUInt64(SplitCommand.at(1), &BreakpointId))
+ if (!ConvertTokenToUInt64(CommandTokens.at(1), &BreakpointId))
{
ShowMessages("please specify a correct hex value for breakpoint id\n\n");
CommandBdHelp();
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/be.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/be.cpp
similarity index 84%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/be.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/be.cpp
index 1e3a0a69..7841b03b 100644
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/be.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/be.cpp
@@ -36,12 +36,13 @@ CommandBeHelp()
/**
* @brief handler of be command
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandBe(vector SplitCommand, string Command)
+CommandBe(vector CommandTokens, string Command)
{
UINT64 BreakpointId;
DEBUGGEE_BP_LIST_OR_MODIFY_PACKET Request = {0};
@@ -49,9 +50,10 @@ CommandBe(vector SplitCommand, string Command)
//
// Validate the commands
//
- if (SplitCommand.size() != 2)
+ if (CommandTokens.size() != 2)
{
- ShowMessages("incorrect use of the 'be'\n\n");
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandBeHelp();
return;
}
@@ -59,7 +61,7 @@ CommandBe(vector SplitCommand, string Command)
//
// Get the breakpoint id
//
- if (!ConvertStringToUInt64(SplitCommand.at(1), &BreakpointId))
+ if (!ConvertTokenToUInt64(CommandTokens.at(1), &BreakpointId))
{
ShowMessages("please specify a correct hex value for breakpoint id\n\n");
CommandBeHelp();
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/bl.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/bl.cpp
similarity index 83%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/bl.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/bl.cpp
index 5339233b..a5751bbf 100644
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/bl.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/bl.cpp
@@ -32,21 +32,23 @@ CommandBlHelp()
/**
* @brief handler of the bl command
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandBl(vector SplitCommand, string Command)
+CommandBl(vector CommandTokens, string Command)
{
DEBUGGEE_BP_LIST_OR_MODIFY_PACKET Request = {0};
//
// Validate the commands
//
- if (SplitCommand.size() != 1)
+ if (CommandTokens.size() != 1)
{
- ShowMessages("incorrect use of the 'bl'\n\n");
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandBlHelp();
return;
}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/bp.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/bp.cpp
new file mode 100644
index 00000000..8beed864
--- /dev/null
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/bp.cpp
@@ -0,0 +1,346 @@
+/**
+ * @file bp.cpp
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief bp command
+ * @details
+ * @version 0.1
+ * @date 2021-10-03
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+//
+// Global Variables
+//
+extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+extern BOOLEAN g_IsVmmModuleLoaded;
+extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
+
+/**
+ * @brief help of the bp command
+ *
+ * @return VOID
+ */
+VOID
+CommandBpHelp()
+{
+ ShowMessages("bp : puts a breakpoint (0xcc).\n");
+
+ ShowMessages(
+ "Note : 'bp' is not an event, if you want to use an event version "
+ "of breakpoints use !epthook or !epthook2 instead. See "
+ "documentation for more information.\n\n");
+
+ ShowMessages("syntax : \tbp [Address (hex)] [pid ProcessId (hex)] [tid ThreadId (hex)] [core CoreId (hex)]\n");
+
+ ShowMessages("\n");
+ ShowMessages("\t\te.g : bp nt!ExAllocatePoolWithTag\n");
+ ShowMessages("\t\te.g : bp nt!ExAllocatePoolWithTag+5\n");
+ ShowMessages("\t\te.g : bp nt!ExAllocatePoolWithTag+@rcx+rbx\n");
+ ShowMessages("\t\te.g : bp fffff8077356f010\n");
+ ShowMessages("\t\te.g : bp fffff8077356f010 pid 0x4\n");
+ ShowMessages("\t\te.g : bp fffff8077356f010 tid 0x1000\n");
+ ShowMessages("\t\te.g : bp fffff8077356f010 pid 0x4 core 2\n");
+}
+
+/**
+ * @brief Apply breakpoint on the user debugger
+ * @param BpPacket
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+CommandBpPerformApplyingBreakpointOnUserDebugger(DEBUGGEE_BP_PACKET * BpPacket)
+{
+ BOOL Status;
+ ULONG ReturnedLength;
+
+ if (g_IsSerialConnectedToRemoteDebuggee)
+ {
+ //
+ // Check if the debugger is connected to a remote debuggee, this request
+ // is not for the kernel debugger
+ //
+ return FALSE;
+ }
+ else
+ {
+ 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
+ IOCTL_SET_BREAKPOINT_USER_DEBUGGER, // IO Control Code (IOCTL)
+ BpPacket, // Input Buffer to driver.
+ SIZEOF_DEBUGGEE_BP_PACKET, // Input buffer length (not used in this case)
+ BpPacket, // Output Buffer from driver.
+ SIZEOF_DEBUGGEE_BP_PACKET, // 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 (BpPacket->Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
+ {
+ return TRUE;
+ }
+ else
+ {
+ //
+ // An err occurred, no results
+ //
+ ShowErrorMessage(BpPacket->Result);
+ return FALSE;
+ }
+ }
+}
+
+/**
+ * @brief request breakpoint
+ *
+ * @param Address Address
+ * @param Pid Process Id
+ * @param Tid Thread Id
+ * @param CoreNumer Core Number
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+CommandBpRequest(UINT64 Address, UINT32 Pid, UINT32 Tid, UINT32 CoreNumer)
+{
+ DEBUGGEE_BP_PACKET BpPacket = {0};
+
+ //
+ // Check if the debugger is connected to a remote debuggee or a user-debugger is active
+ //
+ if (!g_IsSerialConnectedToRemoteDebuggee && !g_ActiveProcessDebuggingState.IsActive)
+ {
+ return FALSE;
+ }
+
+ //
+ // Set the details for the remote packet
+ //
+ BpPacket.Address = Address;
+ BpPacket.Core = CoreNumer;
+ BpPacket.Pid = Pid;
+ BpPacket.Tid = Tid;
+
+ //
+ // Send the bp packet either to the user debugger or the kernel debugger
+ //
+ if (g_ActiveProcessDebuggingState.IsActive)
+ {
+ return CommandBpPerformApplyingBreakpointOnUserDebugger(&BpPacket);
+ }
+ else if (g_IsSerialConnectedToRemoteDebuggee)
+ {
+ return KdSendBpPacketToDebuggee(&BpPacket);
+ }
+ else
+ {
+ //
+ // couldn't set breakpoint, no active process or remote debuggee
+ //
+ return FALSE;
+ }
+}
+
+/**
+ * @brief bp command handler
+ *
+ * @param CommandTokens
+ * @param Command
+ *
+ * @return VOID
+ */
+VOID
+CommandBp(vector CommandTokens, string Command)
+{
+ BOOL IsNextCoreId = FALSE;
+ BOOL IsNextPid = FALSE;
+ BOOL IsNextTid = FALSE;
+
+ BOOLEAN SetCoreId = FALSE;
+ BOOLEAN SetPid = FALSE;
+ BOOLEAN SetTid = FALSE;
+ BOOLEAN SetAddress = FALSE;
+
+ UINT32 Tid = DEBUGGEE_BP_APPLY_TO_ALL_THREADS;
+ UINT32 Pid = DEBUGGEE_BP_APPLY_TO_ALL_PROCESSES;
+ UINT32 CoreNumer = DEBUGGEE_BP_APPLY_TO_ALL_CORES;
+ UINT64 Address = NULL;
+ BOOLEAN IsFirstCommand = TRUE;
+
+ if (CommandTokens.size() >= 9)
+ {
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
+ CommandBpHelp();
+ return;
+ }
+
+ //
+// Disable user-mode debugger in this version
+//
+#if ActivateUserModeDebugger == FALSE
+
+ 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. "
+ "if you want to test the user-mode debugger in VMI Mode, you should build "
+ "HyperDbg with special instructions. But starting processes is fully supported "
+ "in the Debugger Mode.\n"
+ "(it's not recommended to use it in VMI Mode yet!)\n");
+ return;
+ }
+
+#endif // !ActivateUserModeDebugger
+
+ //
+ // If the user is debugging a process, use its pid
+ //
+ if (g_ActiveProcessDebuggingState.IsActive)
+ {
+ Pid = g_ActiveProcessDebuggingState.ProcessId;
+ }
+
+ for (auto Section : CommandTokens)
+ {
+ //
+ // Ignore the first argument as it's the command string itself (bp)
+ //
+ if (IsFirstCommand == TRUE)
+ {
+ IsFirstCommand = FALSE;
+ continue;
+ }
+
+ if (IsNextCoreId)
+ {
+ if (!ConvertTokenToUInt32(Section, &CoreNumer))
+ {
+ ShowMessages("please specify a correct hex value for core id\n\n");
+ CommandBpHelp();
+ return;
+ }
+ IsNextCoreId = FALSE;
+ continue;
+ }
+ if (IsNextPid)
+ {
+ if (!ConvertTokenToUInt32(Section, &Pid))
+ {
+ ShowMessages("please specify a correct hex value for process id\n\n");
+ CommandBpHelp();
+ return;
+ }
+ IsNextPid = FALSE;
+ continue;
+ }
+
+ if (IsNextTid)
+ {
+ if (!ConvertTokenToUInt32(Section, &Tid))
+ {
+ ShowMessages("please specify a correct hex value for thread id\n\n");
+ CommandBpHelp();
+ return;
+ }
+ IsNextTid = FALSE;
+ continue;
+ }
+
+ if (CompareLowerCaseStrings(Section, "pid"))
+ {
+ IsNextPid = TRUE;
+ continue;
+ }
+ if (CompareLowerCaseStrings(Section, "tid"))
+ {
+ IsNextTid = TRUE;
+ continue;
+ }
+ if (CompareLowerCaseStrings(Section, "core"))
+ {
+ IsNextCoreId = TRUE;
+ continue;
+ }
+
+ if (!SetAddress)
+ {
+ if (!SymbolConvertNameOrExprToAddress(GetCaseSensitiveStringFromCommandToken(Section), &Address))
+ {
+ //
+ // Couldn't resolve or unknown parameter
+ //
+ ShowMessages("err, couldn't resolve error at '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(Section).c_str());
+ CommandBpHelp();
+ return;
+ }
+ else
+ {
+ //
+ // Means that address is received
+ //
+ SetAddress = TRUE;
+ continue;
+ }
+ }
+ }
+
+ //
+ // Check if address is set or not
+ //
+ if (!SetAddress)
+ {
+ ShowMessages("please specify a correct hex value as the breakpoint address\n\n");
+ CommandBpHelp();
+ return;
+ }
+ if (IsNextPid)
+ {
+ ShowMessages("please specify a correct hex value for process id\n\n");
+ CommandBpHelp();
+ return;
+ }
+ if (IsNextCoreId)
+ {
+ ShowMessages("please specify a correct hex value for core\n\n");
+ CommandBpHelp();
+ return;
+ }
+ if (IsNextTid)
+ {
+ ShowMessages("please specify a correct hex value for thread id\n\n");
+ CommandBpHelp();
+ return;
+ }
+
+ if (!g_IsSerialConnectedToRemoteDebuggee && !g_ActiveProcessDebuggingState.IsActive)
+ {
+ ShowMessages("setting breakpoints is not possible when you're not connected "
+ "to a target debuggee (kernel debugger or user debugger)\n");
+ return;
+ }
+
+ //
+ // Request breakpoint the bp packet
+ //
+ if (!CommandBpRequest(Address, Pid, Tid, CoreNumer))
+ {
+ ShowMessages("err, couldn't set breakpoint\n");
+ }
+}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/continue.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/continue.cpp
new file mode 100644
index 00000000..af385224
--- /dev/null
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/continue.cpp
@@ -0,0 +1,58 @@
+/**
+ * @file continue.cpp
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief continue command
+ * @details
+ * @version 0.14
+ * @date 2025-06-25
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief help of the continue command
+ *
+ * @return VOID
+ */
+VOID
+CommandContinueHelp()
+{
+ ShowMessages("continue : continues debuggee or continues processing kernel messages (in test mode, it operates as a user-mode continue command).\n\n");
+
+ ShowMessages("syntax : \tcontinue \n");
+}
+
+/**
+ * @brief Request to continue
+ *
+ * @return VOID
+ */
+VOID
+CommandContinueRequest()
+{
+ CommandGRequest();
+}
+
+/**
+ * @brief handler of continue command
+ *
+ * @param CommandTokens
+ * @param Command
+ *
+ * @return VOID
+ */
+VOID
+CommandContinue(vector CommandTokens, string Command)
+{
+ if (CommandTokens.size() != 1)
+ {
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
+ CommandGHelp();
+ return;
+ }
+
+ CommandContinueRequest();
+}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/~.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/core.cpp
similarity index 76%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/~.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/core.cpp
index 650924e9..2a1852db 100644
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/~.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/core.cpp
@@ -1,5 +1,5 @@
/**
- * @file ~.cpp
+ * @file core.cpp
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief show and change processor
* @details
@@ -38,18 +38,20 @@ CommandCoreHelp()
/**
* @brief ~ command handler
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandCore(vector SplitCommand, string Command)
+CommandCore(vector CommandTokens, string Command)
{
UINT32 TargetCore = 0;
- if (SplitCommand.size() != 1 && SplitCommand.size() != 2)
+ if (CommandTokens.size() != 1 && CommandTokens.size() != 2)
{
- ShowMessages("incorrect use of the '~'\n\n");
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandCoreHelp();
return;
}
@@ -63,13 +65,13 @@ CommandCore(vector SplitCommand, string Command)
return;
}
- if (SplitCommand.size() == 1)
+ if (CommandTokens.size() == 1)
{
ShowMessages("current processor : 0x%x\n", g_CurrentRemoteCore);
}
- else if (SplitCommand.size() == 2)
+ else if (CommandTokens.size() == 2)
{
- if (!ConvertStringToUInt32(SplitCommand.at(1), &TargetCore))
+ if (!ConvertTokenToUInt32(CommandTokens.at(1), &TargetCore))
{
ShowMessages("please specify a correct hex value for the core that you "
"want to operate on it\n\n");
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/cpu.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/cpu.cpp
similarity index 95%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/cpu.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/cpu.cpp
index 3845151f..970d44ec 100644
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/cpu.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/cpu.cpp
@@ -27,19 +27,22 @@ CommandCpuHelp()
/**
* @brief cpu command handler
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandCpu(vector SplitCommand, string Command)
+CommandCpu(vector CommandTokens, string Command)
{
- if (SplitCommand.size() != 1)
+ if (CommandTokens.size() != 1)
{
- ShowMessages("incorrect use of the 'cpu'\n\n");
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandCpuHelp();
return;
}
+
ReadCpuDetails();
}
@@ -137,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);
}
@@ -186,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];
@@ -194,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);
}
@@ -243,10 +246,10 @@ const InstructionSet::InstructionSet_Internal InstructionSet::CPU_Rep;
/**
* @brief Reads the CPU vendor string
*
- * @return char *
+ * @return VOID
*/
-HPRDBGCTRL_API VOID
-HyperDbgReadVendorString(char * Result)
+VOID
+CpuReadVendorString(CHAR * Result)
{
std::string VendorString = InstructionSet::Vendor();
strcpy(Result, VendorString.c_str());
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/d-u.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/d-u.cpp
similarity index 52%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/d-u.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/d-u.cpp
index 75988c29..c853df5a 100644
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/d-u.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/d-u.cpp
@@ -64,23 +64,22 @@ CommandReadMemoryAndDisassemblerHelp()
/**
* @brief u* d* !u* !d* commands handler
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandReadMemoryAndDisassembler(vector SplitCommand, string Command)
+CommandReadMemoryAndDisassembler(vector CommandTokens, string Command)
{
- UINT32 Pid = 0;
- UINT32 Length = 0;
- UINT64 TargetAddress = 0;
- BOOLEAN IsNextProcessId = FALSE;
- BOOLEAN IsFirstCommand = TRUE;
- BOOLEAN IsNextLength = FALSE;
- vector SplitCommandCaseSensitive {Split(Command, ' ')};
- UINT32 IndexInCommandCaseSensitive = 0;
+ UINT32 Pid = 0;
+ UINT32 Length = 0;
+ UINT64 TargetAddress = 0;
+ BOOLEAN IsNextProcessId = FALSE;
+ BOOLEAN IsFirstCommand = TRUE;
+ BOOLEAN IsNextLength = FALSE;
- string FirstCommand = SplitCommand.front();
+ string FirstCommand = GetCaseSensitiveStringFromCommandToken(CommandTokens.front());
//
// By default if the user-debugger is active, we use these commands
@@ -91,20 +90,19 @@ CommandReadMemoryAndDisassembler(vector SplitCommand, string Command)
Pid = g_ActiveProcessDebuggingState.ProcessId;
}
- if (SplitCommand.size() == 1)
+ if (CommandTokens.size() == 1)
{
//
// Means that user entered one command without any parameter
//
- ShowMessages("incorrect use of the '%s' command\n\n", FirstCommand.c_str());
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandReadMemoryAndDisassemblerHelp();
return;
}
- for (auto Section : SplitCommand)
+ for (auto Section : CommandTokens)
{
- IndexInCommandCaseSensitive++;
-
if (IsFirstCommand)
{
IsFirstCommand = FALSE;
@@ -113,7 +111,7 @@ CommandReadMemoryAndDisassembler(vector SplitCommand, string Command)
if (IsNextProcessId == TRUE)
{
- if (!ConvertStringToUInt32(Section, &Pid))
+ if (!ConvertTokenToUInt32(Section, &Pid))
{
ShowMessages("err, you should enter a valid process id\n\n");
return;
@@ -124,7 +122,7 @@ CommandReadMemoryAndDisassembler(vector SplitCommand, string Command)
if (IsNextLength == TRUE)
{
- if (!ConvertStringToUInt32(Section, &Length))
+ if (!ConvertTokenToUInt32(Section, &Length))
{
ShowMessages("err, you should enter a valid length\n\n");
return;
@@ -133,13 +131,13 @@ CommandReadMemoryAndDisassembler(vector SplitCommand, string Command)
continue;
}
- if (!Section.compare("l"))
+ if (CompareLowerCaseStrings(Section, "l"))
{
IsNextLength = TRUE;
continue;
}
- if (!Section.compare("pid"))
+ if (CompareLowerCaseStrings(Section, "pid"))
{
IsNextProcessId = TRUE;
continue;
@@ -150,14 +148,13 @@ CommandReadMemoryAndDisassembler(vector SplitCommand, string Command)
//
if (TargetAddress == 0)
{
- if (!SymbolConvertNameOrExprToAddress(SplitCommandCaseSensitive.at(IndexInCommandCaseSensitive - 1),
- &TargetAddress))
+ if (!SymbolConvertNameOrExprToAddress(GetCaseSensitiveStringFromCommandToken(Section), &TargetAddress))
{
//
// Couldn't resolve or unknown parameter
//
ShowMessages("err, couldn't resolve error at '%s'\n",
- SplitCommandCaseSensitive.at(IndexInCommandCaseSensitive - 1).c_str());
+ GetCaseSensitiveStringFromCommandToken(Section).c_str());
return;
}
}
@@ -167,7 +164,7 @@ CommandReadMemoryAndDisassembler(vector SplitCommand, string Command)
// User inserts two address
//
ShowMessages("err, incorrect use of the '%s' command\n\n",
- FirstCommand.c_str());
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandReadMemoryAndDisassemblerHelp();
return;
@@ -189,10 +186,10 @@ CommandReadMemoryAndDisassembler(vector SplitCommand, string Command)
//
// Default length (user doesn't specified)
//
- if (!FirstCommand.compare("u") ||
- !FirstCommand.compare("!u") ||
- !FirstCommand.compare("u64") ||
- !FirstCommand.compare("!u64"))
+ if (CompareLowerCaseStrings(CommandTokens.at(0), "u") ||
+ CompareLowerCaseStrings(CommandTokens.at(0), "!u") ||
+ CompareLowerCaseStrings(CommandTokens.at(0), "u64") ||
+ CompareLowerCaseStrings(CommandTokens.at(0), "!u64"))
{
Length = 0x40;
}
@@ -204,7 +201,8 @@ CommandReadMemoryAndDisassembler(vector SplitCommand, string Command)
if (IsNextLength || IsNextProcessId)
{
- ShowMessages("incorrect use of the '%s' command\n\n", FirstCommand.c_str());
+ ShowMessages("incorrect use of the '%s' command\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandReadMemoryAndDisassemblerHelp();
return;
}
@@ -226,93 +224,93 @@ CommandReadMemoryAndDisassembler(vector SplitCommand, string Command)
Pid = GetCurrentProcessId();
}
- if (!FirstCommand.compare("db"))
+ if (CompareLowerCaseStrings(CommandTokens.at(0), "db"))
{
- HyperDbgReadMemoryAndDisassemble(DEBUGGER_SHOW_COMMAND_DB,
- TargetAddress,
- DEBUGGER_READ_VIRTUAL_ADDRESS,
- READ_FROM_KERNEL,
- Pid,
- Length,
- NULL);
+ HyperDbgShowMemoryOrDisassemble(DEBUGGER_SHOW_COMMAND_DB,
+ TargetAddress,
+ DEBUGGER_READ_VIRTUAL_ADDRESS,
+ READ_FROM_KERNEL,
+ Pid,
+ Length,
+ NULL);
}
- else if (!FirstCommand.compare("dc"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(0), "dc"))
{
- HyperDbgReadMemoryAndDisassemble(DEBUGGER_SHOW_COMMAND_DC,
- TargetAddress,
- DEBUGGER_READ_VIRTUAL_ADDRESS,
- READ_FROM_KERNEL,
- Pid,
- Length,
- NULL);
+ HyperDbgShowMemoryOrDisassemble(DEBUGGER_SHOW_COMMAND_DC,
+ TargetAddress,
+ DEBUGGER_READ_VIRTUAL_ADDRESS,
+ READ_FROM_KERNEL,
+ Pid,
+ Length,
+ NULL);
}
- else if (!FirstCommand.compare("dd"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(0), "dd"))
{
- HyperDbgReadMemoryAndDisassemble(DEBUGGER_SHOW_COMMAND_DD,
- TargetAddress,
- DEBUGGER_READ_VIRTUAL_ADDRESS,
- READ_FROM_KERNEL,
- Pid,
- Length,
- NULL);
+ HyperDbgShowMemoryOrDisassemble(DEBUGGER_SHOW_COMMAND_DD,
+ TargetAddress,
+ DEBUGGER_READ_VIRTUAL_ADDRESS,
+ READ_FROM_KERNEL,
+ Pid,
+ Length,
+ NULL);
}
- else if (!FirstCommand.compare("dq"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(0), "dq"))
{
- HyperDbgReadMemoryAndDisassemble(DEBUGGER_SHOW_COMMAND_DQ,
- TargetAddress,
- DEBUGGER_READ_VIRTUAL_ADDRESS,
- READ_FROM_KERNEL,
- Pid,
- Length,
- NULL);
+ HyperDbgShowMemoryOrDisassemble(DEBUGGER_SHOW_COMMAND_DQ,
+ TargetAddress,
+ DEBUGGER_READ_VIRTUAL_ADDRESS,
+ READ_FROM_KERNEL,
+ Pid,
+ Length,
+ NULL);
}
- else if (!FirstCommand.compare("!db"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(0), "!db"))
{
- HyperDbgReadMemoryAndDisassemble(DEBUGGER_SHOW_COMMAND_DB,
- TargetAddress,
- DEBUGGER_READ_PHYSICAL_ADDRESS,
- READ_FROM_KERNEL,
- Pid,
- Length,
- NULL);
+ HyperDbgShowMemoryOrDisassemble(DEBUGGER_SHOW_COMMAND_DB,
+ TargetAddress,
+ DEBUGGER_READ_PHYSICAL_ADDRESS,
+ READ_FROM_KERNEL,
+ Pid,
+ Length,
+ NULL);
}
- else if (!FirstCommand.compare("!dc"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(0), "!dc"))
{
- HyperDbgReadMemoryAndDisassemble(DEBUGGER_SHOW_COMMAND_DC,
- TargetAddress,
- DEBUGGER_READ_PHYSICAL_ADDRESS,
- READ_FROM_KERNEL,
- Pid,
- Length,
- NULL);
+ HyperDbgShowMemoryOrDisassemble(DEBUGGER_SHOW_COMMAND_DC,
+ TargetAddress,
+ DEBUGGER_READ_PHYSICAL_ADDRESS,
+ READ_FROM_KERNEL,
+ Pid,
+ Length,
+ NULL);
}
- else if (!FirstCommand.compare("!dd"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(0), "!dd"))
{
- HyperDbgReadMemoryAndDisassemble(DEBUGGER_SHOW_COMMAND_DD,
- TargetAddress,
- DEBUGGER_READ_PHYSICAL_ADDRESS,
- READ_FROM_KERNEL,
- Pid,
- Length,
- NULL);
+ HyperDbgShowMemoryOrDisassemble(DEBUGGER_SHOW_COMMAND_DD,
+ TargetAddress,
+ DEBUGGER_READ_PHYSICAL_ADDRESS,
+ READ_FROM_KERNEL,
+ Pid,
+ Length,
+ NULL);
}
- else if (!FirstCommand.compare("!dq"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(0), "!dq"))
{
- HyperDbgReadMemoryAndDisassemble(DEBUGGER_SHOW_COMMAND_DQ,
- TargetAddress,
- DEBUGGER_READ_PHYSICAL_ADDRESS,
- READ_FROM_KERNEL,
- Pid,
- Length,
- NULL);
+ HyperDbgShowMemoryOrDisassemble(DEBUGGER_SHOW_COMMAND_DQ,
+ TargetAddress,
+ DEBUGGER_READ_PHYSICAL_ADDRESS,
+ READ_FROM_KERNEL,
+ Pid,
+ Length,
+ NULL);
}
//
// Disassembler (!u or u or u2 !u2)
//
- else if (!FirstCommand.compare("u") || !FirstCommand.compare("u64"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(0), "u") || CompareLowerCaseStrings(CommandTokens.at(0), "u64"))
{
- HyperDbgReadMemoryAndDisassemble(
+ HyperDbgShowMemoryOrDisassemble(
DEBUGGER_SHOW_COMMAND_DISASSEMBLE64,
TargetAddress,
DEBUGGER_READ_VIRTUAL_ADDRESS,
@@ -321,9 +319,9 @@ CommandReadMemoryAndDisassembler(vector SplitCommand, string Command)
Length,
NULL);
}
- else if (!FirstCommand.compare("!u") || !FirstCommand.compare("!u64"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(0), "!u") || CompareLowerCaseStrings(CommandTokens.at(0), "!u64"))
{
- HyperDbgReadMemoryAndDisassemble(
+ HyperDbgShowMemoryOrDisassemble(
DEBUGGER_SHOW_COMMAND_DISASSEMBLE64,
TargetAddress,
DEBUGGER_READ_PHYSICAL_ADDRESS,
@@ -332,9 +330,9 @@ CommandReadMemoryAndDisassembler(vector SplitCommand, string Command)
Length,
NULL);
}
- else if (!FirstCommand.compare("u2") || !FirstCommand.compare("u32"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(0), "u2") || CompareLowerCaseStrings(CommandTokens.at(0), "u32"))
{
- HyperDbgReadMemoryAndDisassemble(
+ HyperDbgShowMemoryOrDisassemble(
DEBUGGER_SHOW_COMMAND_DISASSEMBLE32,
TargetAddress,
DEBUGGER_READ_VIRTUAL_ADDRESS,
@@ -343,9 +341,9 @@ CommandReadMemoryAndDisassembler(vector SplitCommand, string Command)
Length,
NULL);
}
- else if (!FirstCommand.compare("!u2") || !FirstCommand.compare("!u32"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(0), "!u2") || CompareLowerCaseStrings(CommandTokens.at(0), "!u32"))
{
- HyperDbgReadMemoryAndDisassemble(
+ HyperDbgShowMemoryOrDisassemble(
DEBUGGER_SHOW_COMMAND_DISASSEMBLE32,
TargetAddress,
DEBUGGER_READ_PHYSICAL_ADDRESS,
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/dt-struct.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/dt-struct.cpp
similarity index 75%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/dt-struct.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/dt-struct.cpp
index d43e94cf..c3c3db68 100644
--- a/hyperdbg/hprdbgctrl/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");
@@ -49,7 +49,7 @@ CommandDtHelp()
ShowMessages("\t\te.g : dt nt!_EPROCESS $proc\n");
ShowMessages("\t\te.g : dt nt!_KPROCESS @rax+@rbx+c0\n");
ShowMessages("\t\te.g : !dt nt!_EPROCESS 1f0300\n");
- ShowMessages("\t\te.g : dt nt!_MY_STRUCT 7ff00040 pid 1420\n");
+ ShowMessages("\t\te.g : dt MyModule!_MY_STRUCT 7ff00040 pid 1420\n");
ShowMessages("\t\te.g : dt nt!_EPROCESS $proc inline all\n");
ShowMessages("\t\te.g : dt nt!_EPROCESS fffff8077356f010 inline no\n");
}
@@ -75,6 +75,7 @@ CommandStructHelp()
ShowMessages("\t\te.g : struct nt!* output ntheader.h\n");
ShowMessages("\t\te.g : struct nt!* func yes output ntheader.h\n");
ShowMessages("\t\te.g : struct nt!* func yes output ntheader.h\n");
+ ShowMessages("\t\te.g : struct nt!* func yes output \"c:\\users\\sina\\desktop\\nt header.h\"\n");
}
/**
@@ -89,9 +90,9 @@ CommandStructHelp()
* @return BOOLEAN
*/
BOOLEAN
-CommandDtAndStructConvertHyperDbgArgsToPdbex(vector ExtraArgs,
- std::string & PdbexArgs,
- UINT32 * ProcessId)
+CommandDtAndStructConvertHyperDbgArgsToPdbex(vector ExtraArgs,
+ std::string & PdbexArgs,
+ UINT32 * ProcessId)
{
UINT32 TargetProcessId = NULL;
BOOLEAN NextItemIsYesNo = FALSE;
@@ -115,7 +116,7 @@ CommandDtAndStructConvertHyperDbgArgsToPdbex(vector ExtraArgs,
//
if (NextItemIsFileName)
{
- PdbexArgs += Item + " ";
+ PdbexArgs += "\"" + GetCaseSensitiveStringFromCommandToken(Item) + "\" ";
NextItemIsFileName = FALSE;
continue;
@@ -126,7 +127,7 @@ CommandDtAndStructConvertHyperDbgArgsToPdbex(vector ExtraArgs,
//
if (NextItemIsProcessId)
{
- if (!ConvertStringToUInt32(Item, &TargetProcessId))
+ if (!ConvertTokenToUInt32(Item, &TargetProcessId))
{
ShowMessages("err, you should enter a valid process id\n\n");
return FALSE;
@@ -141,11 +142,11 @@ CommandDtAndStructConvertHyperDbgArgsToPdbex(vector ExtraArgs,
//
if (NextItemIsYesNo)
{
- if (!Item.compare("yes"))
+ if (CompareLowerCaseStrings(Item, "yes"))
{
PdbexArgs += " ";
}
- else if (!Item.compare("no"))
+ else if (CompareLowerCaseStrings(Item, "no"))
{
PdbexArgs += "- ";
}
@@ -167,24 +168,24 @@ CommandDtAndStructConvertHyperDbgArgsToPdbex(vector ExtraArgs,
//
if (NextItemIsInline)
{
- if (!Item.compare("none"))
+ if (CompareLowerCaseStrings(Item, "none"))
{
PdbexArgs += "n ";
}
- else if (!Item.compare("all"))
+ else if (CompareLowerCaseStrings(Item, "all"))
{
PdbexArgs += "a ";
}
- else if (!Item.compare("unnamed") || !Item.compare("unamed"))
+ else if (CompareLowerCaseStrings(Item, "unnamed") || CompareLowerCaseStrings(Item, "unamed"))
{
PdbexArgs += "i ";
}
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;
}
@@ -197,7 +198,7 @@ CommandDtAndStructConvertHyperDbgArgsToPdbex(vector ExtraArgs,
//
if (NextItemIsString)
{
- PdbexArgs += Item + " ";
+ PdbexArgs += GetCaseSensitiveStringFromCommandToken(Item) + " ";
NextItemIsString = FALSE;
continue;
@@ -206,66 +207,66 @@ CommandDtAndStructConvertHyperDbgArgsToPdbex(vector ExtraArgs,
//
// Check for args
//
- if (!Item.compare("pid"))
+ if (CompareLowerCaseStrings(Item, "pid"))
{
NextItemIsProcessId = TRUE;
}
- else if (!Item.compare("output"))
+ else if (CompareLowerCaseStrings(Item, "output"))
{
NextItemIsFileName = TRUE;
PdbexArgs += "-o ";
}
- else if (!Item.compare("inline"))
+ else if (CompareLowerCaseStrings(Item, "inline"))
{
NextItemIsInline = TRUE;
PdbexArgs += "-e ";
}
- else if (!Item.compare("prefix"))
+ else if (CompareLowerCaseStrings(Item, "prefix"))
{
NextItemIsString = TRUE;
PdbexArgs += "-r ";
}
- else if (!Item.compare("suffix"))
+ else if (CompareLowerCaseStrings(Item, "suffix"))
{
NextItemIsString = TRUE;
PdbexArgs += "-g ";
}
- else if (!Item.compare("padding"))
+ else if (CompareLowerCaseStrings(Item, "padding"))
{
NextItemIsYesNo = TRUE;
PdbexArgs += "-p";
}
- else if (!Item.compare("offset") || !Item.compare("offsets"))
+ else if (CompareLowerCaseStrings(Item, "offset") || CompareLowerCaseStrings(Item, "offsets"))
{
NextItemIsYesNo = TRUE;
PdbexArgs += "-x";
}
- else if (!Item.compare("bitfield") || !Item.compare("bitfields"))
+ else if (CompareLowerCaseStrings(Item, "bitfield") || CompareLowerCaseStrings(Item, "bitfields"))
{
NextItemIsYesNo = TRUE;
PdbexArgs += "-b";
}
- else if (!Item.compare("native"))
+ else if (CompareLowerCaseStrings(Item, "native"))
{
NextItemIsYesNo = TRUE;
PdbexArgs += "-i";
}
- else if (!Item.compare("decl"))
+ else if (CompareLowerCaseStrings(Item, "decl"))
{
NextItemIsYesNo = TRUE;
PdbexArgs += "-n";
}
- else if (!Item.compare("def"))
+ else if (CompareLowerCaseStrings(Item, "def"))
{
NextItemIsYesNo = TRUE;
PdbexArgs += "-l";
}
- else if (!Item.compare("func"))
+ else if (CompareLowerCaseStrings(Item, "func"))
{
NextItemIsYesNo = TRUE;
PdbexArgs += "-f";
}
- else if (!Item.compare("pragma"))
+ else if (CompareLowerCaseStrings(Item, "pragma"))
{
NextItemIsYesNo = TRUE;
PdbexArgs += "-z";
@@ -275,7 +276,8 @@ CommandDtAndStructConvertHyperDbgArgsToPdbex(vector ExtraArgs,
//
// Unknown args
//
- ShowMessages("err, unknown argument at '%s'\n\n", Item.c_str());
+ ShowMessages("err, unknown argument at '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(Item).c_str());
return FALSE;
}
}
@@ -312,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;
@@ -351,7 +353,7 @@ CommandDtShowDataBasedOnSymbolTypes(
//
// Use the current process for the pid
//
- TargetPid = GetCurrentProcessId();
+ TargetPid = PlatformGetCurrentProcessId();
}
}
@@ -396,13 +398,13 @@ CommandDtShowDataBasedOnSymbolTypes(
//
// Read the memory
//
- HyperDbgReadMemoryAndDisassemble(DEBUGGER_SHOW_COMMAND_DT,
- Address,
- IsPhysicalAddress ? DEBUGGER_READ_PHYSICAL_ADDRESS : DEBUGGER_READ_VIRTUAL_ADDRESS,
- READ_FROM_KERNEL,
- TargetPid,
- (UINT32)StructureSize,
- &DtOptions);
+ HyperDbgShowMemoryOrDisassemble(DEBUGGER_SHOW_COMMAND_DT,
+ Address,
+ IsPhysicalAddress ? DEBUGGER_READ_PHYSICAL_ADDRESS : DEBUGGER_READ_VIRTUAL_ADDRESS,
+ READ_FROM_KERNEL,
+ TargetPid,
+ (UINT32)StructureSize,
+ &DtOptions);
return TRUE;
}
@@ -419,26 +421,26 @@ CommandDtShowDataBasedOnSymbolTypes(
/**
* @brief dt and struct command handler
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
* @return VOID
*/
VOID
-CommandDtAndStruct(vector SplitCommand, string Command)
+CommandDtAndStruct(vector CommandTokens, string Command)
{
- std::string TempTypeNameHolder;
- std::string PdbexArgs = "";
- BOOLEAN IsStruct = FALSE;
- UINT64 TargetAddress = NULL;
- PVOID BufferAddressRetrievedFromDebuggee = NULL;
- UINT32 TargetPid = NULL;
- BOOLEAN IsPhysicalAddress = FALSE;
+ CommandToken TempTypeNameHolder;
+ std::string PdbexArgs = "";
+ BOOLEAN IsStruct = FALSE;
+ UINT64 TargetAddress = NULL;
+ PVOID BufferAddressRetrievedFromDebuggee = NULL;
+ UINT32 TargetPid = NULL;
+ BOOLEAN IsPhysicalAddress = FALSE;
//
// Check if command is 'struct' or not
//
- if (!SplitCommand.at(0).compare("struct") ||
- !SplitCommand.at(0).compare("structure"))
+ if (CompareLowerCaseStrings(CommandTokens.at(0), "struct") ||
+ CompareLowerCaseStrings(CommandTokens.at(0), "structure"))
{
IsStruct = TRUE;
}
@@ -450,7 +452,7 @@ CommandDtAndStruct(vector SplitCommand, string Command)
//
// Check if command is '!dt' for physical address or not
//
- if (!SplitCommand.at(0).compare("!dt"))
+ if (!IsStruct && CompareLowerCaseStrings(CommandTokens.at(0), "!dt"))
{
IsPhysicalAddress = TRUE;
}
@@ -459,9 +461,10 @@ CommandDtAndStruct(vector SplitCommand, string Command)
IsPhysicalAddress = FALSE;
}
- if (SplitCommand.size() == 1)
+ if (CommandTokens.size() == 1)
{
- ShowMessages("incorrect use of the '%s'\n\n", SplitCommand.at(0).c_str());
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
if (IsStruct)
{
@@ -476,35 +479,20 @@ CommandDtAndStruct(vector SplitCommand, string Command)
}
//
- // Trim the command
+ // Create TempSplitTokens by copying elements from CommandTokens, excluding the first element
//
- Trim(Command);
-
- //
- // Remove dt, struct, or structure from it
- //
- Command.erase(0, SplitCommand.at(0).size());
-
- //
- // Trim it again
- //
- Trim(Command);
-
- //
- // Check for the first and second arguments
- //
- vector TempSplitCommand {Split(Command, ' ')};
+ std::vector TempSplitTokens(CommandTokens.begin() + 1, CommandTokens.end());
//
// If the size is zero, then it's only a type name
//
- if (TempSplitCommand.size() == 1)
+ if (TempSplitTokens.size() == 1)
{
//
// Call the dt parser wrapper, it's only a structure (type) name
// Call it with default configuration
//
- CommandDtShowDataBasedOnSymbolTypes(TempSplitCommand.at(0).c_str(),
+ CommandDtShowDataBasedOnSymbolTypes(GetCaseSensitiveStringFromCommandToken(TempSplitTokens.at(0)).c_str(),
NULL,
IsStruct,
NULL,
@@ -523,31 +511,31 @@ CommandDtAndStruct(vector SplitCommand, string Command)
//
// Check if the first parameter is an address or valid expression
//
- if (IsStruct || !SymbolConvertNameOrExprToAddress(TempSplitCommand.at(0).c_str(),
+ if (IsStruct || !SymbolConvertNameOrExprToAddress(GetCaseSensitiveStringFromCommandToken(TempSplitTokens.at(0)).c_str(),
&TargetAddress))
{
//
// No it's not, we'll get the first argument as the structure (type) name
// And we have to check whether the second argument is a buffer address or not
//
- if (IsStruct || !SymbolConvertNameOrExprToAddress(TempSplitCommand.at(1).c_str(),
+ if (IsStruct || !SymbolConvertNameOrExprToAddress(GetCaseSensitiveStringFromCommandToken(TempSplitTokens.at(1)).c_str(),
&TargetAddress))
{
//
// The second argument is also not buffer address
// probably the user entered a structure (type) name along with some params
//
- TempTypeNameHolder = TempSplitCommand.at(0);
+ TempTypeNameHolder = TempSplitTokens.at(0);
//
// Remove the first argument
//
- TempSplitCommand.erase(TempSplitCommand.begin());
+ TempSplitTokens.erase(TempSplitTokens.begin());
//
// Convert to pdbex args
//
- if (!CommandDtAndStructConvertHyperDbgArgsToPdbex(TempSplitCommand, PdbexArgs, &TargetPid))
+ if (!CommandDtAndStructConvertHyperDbgArgsToPdbex(TempSplitTokens, PdbexArgs, &TargetPid))
{
if (IsStruct)
{
@@ -564,7 +552,7 @@ CommandDtAndStruct(vector SplitCommand, string Command)
//
// Call the wrapper of pdbex
//
- CommandDtShowDataBasedOnSymbolTypes(TempTypeNameHolder.c_str(),
+ CommandDtShowDataBasedOnSymbolTypes(GetCaseSensitiveStringFromCommandToken(TempTypeNameHolder).c_str(),
TargetAddress,
IsStruct,
BufferAddressRetrievedFromDebuggee,
@@ -578,13 +566,13 @@ CommandDtAndStruct(vector SplitCommand, string Command)
// The second argument is a buffer address
// The user entered a structure (type) name along with buffer address
//
- if (TempSplitCommand.size() == 2)
+ if (TempSplitTokens.size() == 2)
{
//
// There is not parameters, only a symbol name and then a buffer address
// Call it with default configuration
//
- CommandDtShowDataBasedOnSymbolTypes(TempSplitCommand.at(0).c_str(),
+ CommandDtShowDataBasedOnSymbolTypes(GetCaseSensitiveStringFromCommandToken(TempSplitTokens.at(0)).c_str(),
TargetAddress,
IsStruct,
BufferAddressRetrievedFromDebuggee,
@@ -599,18 +587,18 @@ CommandDtAndStruct(vector SplitCommand, string Command)
// the second argument which is buffer address, there are other parameters, so
// we WON'T call it with default parameters
//
- TempTypeNameHolder = TempSplitCommand.at(0);
+ TempTypeNameHolder = TempSplitTokens.at(0);
//
// Remove the first, and the second arguments
//
- TempSplitCommand.erase(TempSplitCommand.begin());
- TempSplitCommand.erase(TempSplitCommand.begin());
+ TempSplitTokens.erase(TempSplitTokens.begin());
+ TempSplitTokens.erase(TempSplitTokens.begin());
//
// Convert to pdbex args
//
- if (!CommandDtAndStructConvertHyperDbgArgsToPdbex(TempSplitCommand, PdbexArgs, &TargetPid))
+ if (!CommandDtAndStructConvertHyperDbgArgsToPdbex(TempSplitTokens, PdbexArgs, &TargetPid))
{
if (IsStruct)
{
@@ -627,7 +615,7 @@ CommandDtAndStruct(vector SplitCommand, string Command)
//
// Call the wrapper of pdbex
//
- CommandDtShowDataBasedOnSymbolTypes(TempTypeNameHolder.c_str(),
+ CommandDtShowDataBasedOnSymbolTypes(GetCaseSensitiveStringFromCommandToken(TempTypeNameHolder).c_str(),
TargetAddress,
IsStruct,
BufferAddressRetrievedFromDebuggee,
@@ -643,13 +631,13 @@ CommandDtAndStruct(vector SplitCommand, string Command)
// The first argument is a buffer address, so we get the first argument as
// a buffer address and the second argument as the structure (type) name
//
- if (TempSplitCommand.size() == 2)
+ if (TempSplitTokens.size() == 2)
{
//
// There is not parameters, only a buffer address and then a symbol name
// Call it with default configuration
//
- CommandDtShowDataBasedOnSymbolTypes(TempSplitCommand.at(1).c_str(),
+ CommandDtShowDataBasedOnSymbolTypes(GetCaseSensitiveStringFromCommandToken(TempSplitTokens.at(1)).c_str(),
TargetAddress,
IsStruct,
BufferAddressRetrievedFromDebuggee,
@@ -664,18 +652,18 @@ CommandDtAndStruct(vector SplitCommand, string Command)
// argument which is structure (type) name, there are other parameters, so
// we WON'T call it with default parameters
//
- TempTypeNameHolder = TempSplitCommand.at(1);
+ TempTypeNameHolder = TempSplitTokens.at(1);
//
// Remove the first, and the second arguments
//
- TempSplitCommand.erase(TempSplitCommand.begin());
- TempSplitCommand.erase(TempSplitCommand.begin());
+ TempSplitTokens.erase(TempSplitTokens.begin());
+ TempSplitTokens.erase(TempSplitTokens.begin());
//
// Convert to pdbex args
//
- if (!CommandDtAndStructConvertHyperDbgArgsToPdbex(TempSplitCommand, PdbexArgs, &TargetPid))
+ if (!CommandDtAndStructConvertHyperDbgArgsToPdbex(TempSplitTokens, PdbexArgs, &TargetPid))
{
if (IsStruct)
{
@@ -692,7 +680,7 @@ CommandDtAndStruct(vector SplitCommand, string Command)
//
// Call the wrapper of pdbex
//
- CommandDtShowDataBasedOnSymbolTypes(TempTypeNameHolder.c_str(),
+ CommandDtShowDataBasedOnSymbolTypes(GetCaseSensitiveStringFromCommandToken(TempTypeNameHolder).c_str(),
TargetAddress,
IsStruct,
BufferAddressRetrievedFromDebuggee,
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/e.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/e.cpp
new file mode 100644
index 00000000..f85bf35a
--- /dev/null
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/e.cpp
@@ -0,0 +1,559 @@
+/**
+ * @file e.cpp
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief e* command
+ * @details
+ * @version 0.1
+ * @date 2020-07-27
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+//
+// Global Variables
+//
+extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+extern BOOLEAN g_IsKdModuleLoaded;
+extern BOOLEAN g_IsVmmModuleLoaded;
+extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
+
+/**
+ * @brief help of !e* and e* commands
+ *
+ * @return VOID
+ */
+VOID
+CommandEditMemoryHelp()
+{
+ ShowMessages("eb !eb ed !ed eq !eq : edits the memory at specific address \n");
+ ShowMessages("eb Byte and ASCII characters\n");
+ ShowMessages("ed Double-word values (4 bytes)\n");
+ ShowMessages("eq Quad-word values (8 bytes). \n");
+
+ ShowMessages("\n If you want to edit physical (address) memory then add '!' "
+ "at the start of the command\n");
+
+ ShowMessages("syntax : \teb [Address (hex)] [Contents (hex)] [pid ProcessId (hex)]\n");
+ ShowMessages("syntax : \ted [Address (hex)] [Contents (hex)] [pid ProcessId (hex)]\n");
+ ShowMessages("syntax : \teq [Address (hex)] [Contents (hex)] [pid ProcessId (hex)]\n");
+
+ ShowMessages("\n");
+ ShowMessages("\t\te.g : eb fffff8077356f010 90 \n");
+ ShowMessages("\t\te.g : eb nt!Kd_DEFAULT_Mask ff ff ff ff \n");
+ ShowMessages("\t\te.g : eb nt!Kd_DEFAULT_Mask+10+@rcx ff ff ff ff \n");
+ ShowMessages("\t\te.g : eb fffff8077356f010 90 90 90 90 \n");
+ ShowMessages("\t\te.g : !eq 100000 9090909090909090\n");
+ ShowMessages("\t\te.g : !eq nt!ExAllocatePoolWithTag+55 9090909090909090\n");
+ ShowMessages("\t\te.g : !eq 100000 9090909090909090 9090909090909090 "
+ "9090909090909090 9090909090909090 9090909090909090\n");
+}
+
+/**
+ * @brief Perform writing the memory content
+ *
+ * @param AddressToEdit
+ * @param MemoryType
+ * @param ByteSize
+ * @param Pid
+ * @param CountOf64Chunks
+ * @param BufferToEdit
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+WriteMemoryContent(UINT64 AddressToEdit,
+ DEBUGGER_EDIT_MEMORY_TYPE MemoryType,
+ DEBUGGER_EDIT_MEMORY_BYTE_SIZE ByteSize,
+ UINT32 Pid,
+ UINT32 CountOf64Chunks,
+ UINT64 * BufferToEdit)
+{
+ BOOL Status;
+ DWORD BytesReturned;
+ BOOLEAN StatusReturn = FALSE;
+ DEBUGGER_EDIT_MEMORY * FinalBuffer;
+ DEBUGGER_EDIT_MEMORY EditMemoryRequest = {0};
+ UINT32 FinalSize = 0;
+
+ //
+ // Check if driver is loaded if it's in VMI mode
+ //
+ if (!g_IsSerialConnectedToRemoteDebuggee)
+ {
+ AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
+ }
+
+ //
+ // Fill the structure
+ //
+ EditMemoryRequest.ProcessId = Pid;
+ EditMemoryRequest.Address = AddressToEdit;
+ EditMemoryRequest.CountOf64Chunks = CountOf64Chunks;
+ EditMemoryRequest.MemoryType = MemoryType;
+ EditMemoryRequest.ByteSize = ByteSize;
+
+ //
+ // Now it's time to put everything together in one structure
+ //
+ FinalSize = (CountOf64Chunks * sizeof(UINT64)) + SIZEOF_DEBUGGER_EDIT_MEMORY;
+
+ //
+ // Set the size
+ //
+ EditMemoryRequest.FinalStructureSize = FinalSize;
+
+ //
+ // Allocate structure + buffer
+ //
+ FinalBuffer = (DEBUGGER_EDIT_MEMORY *)malloc(FinalSize);
+
+ if (!FinalBuffer)
+ {
+ ShowMessages("unable to allocate memory\n\n");
+ return FALSE;
+ }
+
+ //
+ // Zero the buffer
+ //
+ ZeroMemory(FinalBuffer, FinalSize);
+
+ //
+ // Copy the structure on top of the allocated buffer
+ //
+ memcpy((PVOID)FinalBuffer, &EditMemoryRequest, SIZEOF_DEBUGGER_EDIT_MEMORY);
+
+ //
+ // Copy the values to the buffer
+ //
+ memcpy((UINT64 *)((UINT64)FinalBuffer + SIZEOF_DEBUGGER_EDIT_MEMORY), BufferToEdit, (CountOf64Chunks * sizeof(UINT64)));
+
+ //
+ // send the request
+ //
+ if (g_IsSerialConnectedToRemoteDebuggee)
+ {
+ if (!KdSendEditMemoryPacketToDebuggee(FinalBuffer, FinalSize))
+ {
+ free(FinalBuffer);
+ return FALSE;
+ }
+ }
+ else
+ {
+ Status = DeviceIoControl(
+ g_DeviceHandle, // Handle to device
+ IOCTL_DEBUGGER_EDIT_MEMORY, // IO Control Code (IOCTL)
+ FinalBuffer, // Input Buffer to driver.
+ FinalSize, // Input buffer length
+ FinalBuffer, // Output Buffer from driver.
+ SIZEOF_DEBUGGER_EDIT_MEMORY, // Length of output buffer in bytes.
+ &BytesReturned, // Bytes placed in buffer.
+ NULL // synchronous call
+ );
+
+ if (!Status)
+ {
+ ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
+ free(FinalBuffer);
+ return FALSE;
+ }
+ }
+
+ //
+ // Check the result
+ //
+ if (FinalBuffer->Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
+ {
+ //
+ // Was successful, nothing to do
+ //
+ free(FinalBuffer);
+ return TRUE;
+ }
+ else
+ {
+ ShowErrorMessage(FinalBuffer->Result);
+ free(FinalBuffer);
+ return FALSE;
+ }
+}
+
+/**
+ * @brief API function for writing the memory content
+ *
+ * @param AddressToEdit
+ * @param MemoryType
+ * @param ProcessId
+ * @param SourceAddress
+ * @param NumberOfBytes
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperDbgWriteMemory(PVOID DestinationAddress,
+ DEBUGGER_EDIT_MEMORY_TYPE MemoryType,
+ UINT32 ProcessId,
+ PVOID SourceAddress,
+ UINT32 NumberOfBytes)
+{
+ UINT32 RequiredBytes = 0;
+ DEBUGGER_EDIT_MEMORY_BYTE_SIZE ByteSize;
+ UINT64 * TargetBuffer;
+ UINT32 FinalSize = 0;
+ BOOLEAN Result = FALSE;
+ BYTE * BufferToEdit = (BYTE *)SourceAddress;
+
+ //
+ // Set the byte size to byte granularity
+ //
+ ByteSize = EDIT_BYTE;
+
+ //
+ // Calculate the count of 64 chunks
+ //
+ RequiredBytes = NumberOfBytes * sizeof(UINT64);
+
+ //
+ // Allocate structure + buffer
+ //
+ TargetBuffer = (UINT64 *)malloc(RequiredBytes);
+
+ if (!TargetBuffer)
+ {
+ return FALSE;
+ }
+
+ //
+ // Zero the buffer
+ //
+ ZeroMemory(TargetBuffer, FinalSize);
+
+ //
+ // Copy requested memory in 64bit chunks
+ //
+ for (SIZE_T i = 0; i < NumberOfBytes; i++)
+ {
+ TargetBuffer[i] = BufferToEdit[i];
+ }
+
+ //
+ // Perform the write operation
+ //
+ Result = WriteMemoryContent((UINT64)DestinationAddress,
+ MemoryType,
+ ByteSize,
+ ProcessId,
+ NumberOfBytes,
+ TargetBuffer);
+
+ //
+ // Free the malloc buffer
+ //
+ free(TargetBuffer);
+
+ return Result;
+}
+
+/**
+ * @brief !e* and e* commands handler
+ *
+ * @param CommandTokens
+ * @param Command
+ *
+ * @return VOID
+ */
+VOID
+CommandEditMemory(vector CommandTokens, string Command)
+{
+ UINT64 Address;
+ UINT64 * FinalBuffer;
+ vector ValuesToEdit;
+ DEBUGGER_EDIT_MEMORY_TYPE MemoryType;
+ DEBUGGER_EDIT_MEMORY_BYTE_SIZE ByteSize;
+ BOOL SetAddress = FALSE;
+ BOOL SetValue = FALSE;
+ BOOL SetProcId = FALSE;
+ BOOL NextIsProcId = FALSE;
+ UINT64 Value = 0;
+ UINT32 ProcId = 0;
+ UINT32 CountOfValues = 0;
+ UINT32 FinalSize = 0;
+ BOOLEAN IsFirstCommand = TRUE;
+
+ //
+ // By default if the user-debugger is active, we use these commands
+ // on the memory layout of the debuggee process
+ //
+ if (g_ActiveProcessDebuggingState.IsActive)
+ {
+ ProcId = g_ActiveProcessDebuggingState.ProcessId;
+ }
+
+ if (CommandTokens.size() <= 2)
+ {
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
+ CommandEditMemoryHelp();
+ return;
+ }
+
+ for (auto Section : CommandTokens)
+ {
+ if (IsFirstCommand)
+ {
+ if (CompareLowerCaseStrings(Section, "!eb"))
+ {
+ MemoryType = EDIT_PHYSICAL_MEMORY;
+ ByteSize = EDIT_BYTE;
+ }
+ else if (CompareLowerCaseStrings(Section, "!ed"))
+ {
+ MemoryType = EDIT_PHYSICAL_MEMORY;
+ ByteSize = EDIT_DWORD;
+ }
+ else if (CompareLowerCaseStrings(Section, "!eq"))
+ {
+ MemoryType = EDIT_PHYSICAL_MEMORY;
+ ByteSize = EDIT_QWORD;
+ }
+ else if (CompareLowerCaseStrings(Section, "eb"))
+ {
+ MemoryType = EDIT_VIRTUAL_MEMORY;
+ ByteSize = EDIT_BYTE;
+ }
+ else if (CompareLowerCaseStrings(Section, "ed"))
+ {
+ MemoryType = EDIT_VIRTUAL_MEMORY;
+ ByteSize = EDIT_DWORD;
+ }
+ else if (CompareLowerCaseStrings(Section, "eq"))
+ {
+ MemoryType = EDIT_VIRTUAL_MEMORY;
+ ByteSize = EDIT_QWORD;
+ }
+ else
+ {
+ //
+ // What's this? :(
+ //
+ ShowMessages("unknown error happened !\n\n");
+ CommandEditMemoryHelp();
+ return;
+ }
+
+ IsFirstCommand = FALSE;
+
+ continue;
+ }
+
+ if (NextIsProcId)
+ {
+ //
+ // It's a process id
+ //
+ NextIsProcId = FALSE;
+
+ if (!ConvertTokenToUInt32(Section, &ProcId))
+ {
+ ShowMessages("please specify a correct hex process id\n\n");
+ CommandEditMemoryHelp();
+ return;
+ }
+ else
+ {
+ //
+ // Means that the proc id is set, next we should read value
+ //
+ continue;
+ }
+ }
+
+ //
+ // Check if it's a process id or not
+ //
+ if (!SetProcId && CompareLowerCaseStrings(Section, "pid"))
+ {
+ NextIsProcId = TRUE;
+ continue;
+ }
+
+ if (!SetAddress)
+ {
+ if (!SymbolConvertNameOrExprToAddress(GetCaseSensitiveStringFromCommandToken(Section), &Address))
+ {
+ ShowMessages("err, couldn't resolve error at '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(Section).c_str());
+ CommandEditMemoryHelp();
+ return;
+ }
+ else
+ {
+ //
+ // Means that the address is set, next we should read value
+ //
+ SetAddress = TRUE;
+ continue;
+ }
+ }
+
+ if (SetAddress)
+ {
+ //
+ // Remove the hex notations
+ //
+ std::string TargetVal = GetCaseSensitiveStringFromCommandToken(Section);
+
+ if (TargetVal.rfind("0x", 0) == 0 || TargetVal.rfind("0X", 0) == 0 ||
+ TargetVal.rfind("\\x", 0) == 0 || TargetVal.rfind("\\X", 0) == 0)
+ {
+ TargetVal = TargetVal.erase(0, 2);
+ }
+ else if (TargetVal.rfind('x', 0) == 0 || TargetVal.rfind('X', 0) == 0)
+ {
+ TargetVal = TargetVal.erase(0, 1);
+ }
+
+ TargetVal.erase(remove(TargetVal.begin(), TargetVal.end(), '`'), TargetVal.end());
+
+ //
+ // Check if the value is valid based on byte counts
+ //
+ if (ByteSize == EDIT_BYTE && TargetVal.size() >= 3)
+ {
+ ShowMessages("please specify a byte (hex) value for 'eb' or '!eb'\n\n");
+ return;
+ }
+ if (ByteSize == EDIT_DWORD && TargetVal.size() >= 9)
+ {
+ ShowMessages(
+ "please specify a dword (hex) value for 'ed' or '!ed'\n\n");
+ return;
+ }
+ if (ByteSize == EDIT_QWORD && TargetVal.size() >= 17)
+ {
+ ShowMessages(
+ "please specify a qword (hex) value for 'eq' or '!eq'\n\n");
+ return;
+ }
+
+ //
+ // Qword is checked by the following function, no need to double
+ // check it above.
+ //
+
+ if (!ConvertStringToUInt64(TargetVal, &Value))
+ {
+ ShowMessages("please specify a correct hex value to change the memory "
+ "content\n\n");
+ CommandEditMemoryHelp();
+ return;
+ }
+ else
+ {
+ //
+ // Add it to the list
+ //
+
+ ValuesToEdit.push_back(Value);
+
+ //
+ // Keep track of values to modify
+ //
+ CountOfValues++;
+
+ if (!SetValue)
+ {
+ //
+ // At least on value is there
+ //
+ SetValue = TRUE;
+ }
+ continue;
+ }
+ }
+ }
+
+ //
+ // Check to prevent using process id in e* commands
+ //
+ if (g_IsSerialConnectedToRemoteDebuggee && ProcId != 0)
+ {
+ ShowMessages(ASSERT_MESSAGE_CANNOT_SPECIFY_PID);
+ return;
+ }
+
+ //
+ // Only valid for VMI Mode
+ //
+ if (ProcId == 0)
+ {
+ ProcId = GetCurrentProcessId();
+ }
+
+ //
+ // Check if address and value are set or not
+ //
+ if (!SetAddress)
+ {
+ ShowMessages("please specify a correct hex address\n\n");
+ CommandEditMemoryHelp();
+ return;
+ }
+ if (!SetValue)
+ {
+ ShowMessages(
+ "please specify a correct hex value as the content to edit\n\n");
+ CommandEditMemoryHelp();
+ return;
+ }
+ if (NextIsProcId)
+ {
+ ShowMessages("please specify a correct hex value as the process id\n\n");
+ CommandEditMemoryHelp();
+ return;
+ }
+
+ //
+ // Make the chunks for editing
+ //
+ FinalSize = (CountOfValues * sizeof(UINT64));
+
+ //
+ // Allocate structure + buffer
+ //
+ FinalBuffer = (UINT64 *)malloc(FinalSize);
+
+ if (!FinalBuffer)
+ {
+ ShowMessages("unable to allocate memory\n\n");
+ return;
+ }
+
+ //
+ // Zero the buffer
+ //
+ ZeroMemory(FinalBuffer, FinalSize);
+
+ //
+ // Put the values in 64 bit structures
+ //
+ std::copy(ValuesToEdit.begin(), ValuesToEdit.end(), FinalBuffer);
+
+ //
+ // Perform the write operation
+ //
+ WriteMemoryContent(Address,
+ MemoryType,
+ ByteSize,
+ ProcId,
+ CountOfValues,
+ FinalBuffer);
+
+ //
+ // Free the malloc buffer
+ //
+ free(FinalBuffer);
+}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/eval.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/eval.cpp
similarity index 77%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/eval.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/eval.cpp
index 94ec6492..202701cb 100644
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/eval.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/eval.cpp
@@ -11,12 +11,11 @@
*/
#include "pch.h"
-using namespace std;
-
//
// Global Variables
//
-extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
/**
* @brief help of the ? command
@@ -188,21 +187,18 @@ ErrorMessage:
/**
* @brief handler of ? command
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandEval(vector SplitCommand, string Command)
+CommandEval(vector CommandTokens, string Command)
{
- PVOID CodeBuffer;
- UINT64 BufferAddress;
- UINT32 BufferLength;
- UINT32 Pointer;
-
- if (SplitCommand.size() == 1)
+ if (CommandTokens.size() == 1)
{
- ShowMessages("incorrect use of the '?'\n\n");
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandEvalHelp();
return;
}
@@ -215,7 +211,7 @@ CommandEval(vector SplitCommand, string Command)
//
// Remove the first command from it
//
- Command.erase(0, SplitCommand.at(0).size());
+ Command.erase(0, GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).size());
//
// Trim it again
@@ -242,56 +238,25 @@ CommandEval(vector SplitCommand, 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/hprdbgctrl/code/debugger/commands/debugging-commands/events.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/events.cpp
similarity index 90%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/events.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/events.cpp
index 8620d375..27561c23 100644
--- a/hyperdbg/hprdbgctrl/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;
@@ -57,12 +58,13 @@ CommandEventsHelp()
/**
* @brief events command handler
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandEvents(vector SplitCommand, string Command)
+CommandEvents(vector CommandTokens, string Command)
{
DEBUGGER_MODIFY_EVENTS_TYPE RequestedAction;
UINT64 RequestedTag;
@@ -70,14 +72,15 @@ CommandEvents(vector SplitCommand, string Command)
//
// Validate the parameters (size)
//
- if (SplitCommand.size() != 1 && SplitCommand.size() != 3)
+ if (CommandTokens.size() != 1 && CommandTokens.size() != 3)
{
- ShowMessages("incorrect use of the '%s'\n\n", SplitCommand.at(0).c_str());
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandEventsHelp();
return;
}
- if (SplitCommand.size() == 1)
+ if (CommandTokens.size() == 1)
{
if (!g_EventTraceInitialized)
{
@@ -97,25 +100,25 @@ CommandEvents(vector SplitCommand, string Command)
// Validate second argument as it's not just a simple
// events without any parameter
//
- if (!SplitCommand.at(1).compare("e"))
+ if (CompareLowerCaseStrings(CommandTokens.at(1), "e"))
{
RequestedAction = DEBUGGER_MODIFY_EVENTS_ENABLE;
}
- else if (!SplitCommand.at(1).compare("d"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(1), "d"))
{
RequestedAction = DEBUGGER_MODIFY_EVENTS_DISABLE;
}
- else if (!SplitCommand.at(1).compare("c"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(1), "c"))
{
RequestedAction = DEBUGGER_MODIFY_EVENTS_CLEAR;
}
- else if (!SplitCommand.at(1).compare("sc"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(1), "sc"))
{
- if (!SplitCommand.at(2).compare("on"))
+ if (CompareLowerCaseStrings(CommandTokens.at(2), "on"))
{
KdSendShortCircuitingEventToDebuggee(TRUE);
}
- else if (!SplitCommand.at(2).compare("off"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(2), "off"))
{
KdSendShortCircuitingEventToDebuggee(FALSE);
}
@@ -137,7 +140,8 @@ CommandEvents(vector SplitCommand, string Command)
//
// unknown second command
//
- ShowMessages("incorrect use of the '%s'\n\n", SplitCommand.at(0).c_str());
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandEventsHelp();
return;
}
@@ -146,11 +150,11 @@ CommandEvents(vector SplitCommand, string Command)
// Validate third argument as it's not just a simple
// events without any parameter
//
- if (!SplitCommand.at(2).compare("all"))
+ if (CompareLowerCaseStrings(CommandTokens.at(2), "all"))
{
RequestedTag = DEBUGGER_MODIFY_EVENTS_APPLY_TO_ALL_TAG;
}
- else if (!ConvertStringToUInt64(SplitCommand.at(2), &RequestedTag))
+ else if (!ConvertTokenToUInt64(CommandTokens.at(2), &RequestedTag))
{
ShowMessages(
"please specify a correct hex value for tag id (event number)\n\n");
@@ -570,6 +574,19 @@ CommandEventsHandleModifiedEvent(
}
else
{
+ //
+ // If HyperDbg is operating at the Debugger Mode, we'll indicate that
+ // the event will be cleared after continuing the debuggee
+ //
+ if (g_IsSerialConnectedToRemoteDebuggee)
+ {
+ ShowMessages("%s successfully cleared, but please note in the Debugger Mode (current mode), HyperDbg "
+ "cannot clear events instantly. Instead, it first disables the events, and when "
+ "you continue the debuggee (e.g., by pressing the 'g' command), the event will be cleared. "
+ "Reapplying the same event without first continuing the debuggee may result in undefined behavior\n",
+ Tag == DEBUGGER_MODIFY_EVENTS_APPLY_TO_ALL_TAG ? "events are" : "the event is");
+ }
+
//
// The action was applied successfully
//
@@ -681,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/hprdbgctrl/code/debugger/commands/debugging-commands/exit.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/exit.cpp
similarity index 68%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/exit.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/exit.cpp
index 40b78fd3..b691c60b 100644
--- a/hyperdbg/hprdbgctrl/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
@@ -35,16 +37,18 @@ CommandExitHelp()
/**
* @brief exit command handler
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandExit(vector SplitCommand, string Command)
+CommandExit(vector CommandTokens, string Command)
{
- if (SplitCommand.size() != 1)
+ if (CommandTokens.size() != 1)
{
- ShowMessages("incorrect use of the 'exit'\n\n");
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandExitHelp();
return;
}
@@ -56,11 +60,14 @@ CommandExit(vector SplitCommand, 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/hprdbgctrl/code/debugger/commands/debugging-commands/flush.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/flush.cpp
similarity index 84%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/flush.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/flush.cpp
index dfc51942..c286207b 100644
--- a/hyperdbg/hprdbgctrl/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
@@ -101,16 +102,18 @@ CommandFlushRequestFlush()
/**
* @brief flush command handler
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandFlush(vector SplitCommand, string Command)
+CommandFlush(vector CommandTokens, string Command)
{
- if (SplitCommand.size() != 1)
+ if (CommandTokens.size() != 1)
{
- ShowMessages("incorrect use of the 'flush'\n\n");
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandFlushHelp();
return;
}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/g.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/g.cpp
similarity index 82%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/g.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/g.cpp
index eba67d26..5530df30 100644
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/g.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/g.cpp
@@ -67,7 +67,7 @@ CommandGRequest()
{
if (g_ActiveProcessDebuggingState.IsPaused)
{
- UdContinueDebuggee(g_ActiveProcessDebuggingState.ProcessDebuggingToken);
+ UdContinueProcess(g_ActiveProcessDebuggingState.ProcessDebuggingToken);
//
// Target process is running
@@ -76,7 +76,7 @@ CommandGRequest()
}
else
{
- ShowMessages("err, target process is already running\n");
+ ShowMessages("the target process is already running\n");
}
}
}
@@ -85,16 +85,18 @@ CommandGRequest()
/**
* @brief handler of g command
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandG(vector SplitCommand, string Command)
+CommandG(vector CommandTokens, string Command)
{
- if (SplitCommand.size() != 1)
+ if (CommandTokens.size() != 1)
{
- ShowMessages("incorrect use of the 'g'\n\n");
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandGHelp();
return;
}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/gg.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/gg.cpp
new file mode 100644
index 00000000..ca856e22
--- /dev/null
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/gg.cpp
@@ -0,0 +1,58 @@
+/**
+ * @file gg.cpp
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief gg command
+ * @details
+ * @version 0.11
+ * @date 2024-11-19
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+/**
+ * @brief help of the g command
+ *
+ * @return VOID
+ */
+VOID
+CommandGgHelp()
+{
+ ShowMessages("gg : shows and changes the operating processor.\n\n");
+
+ ShowMessages("syntax : \tgg\n");
+ ShowMessages("syntax : \tgg [wp]\n");
+
+ ShowMessages("\n");
+ ShowMessages("\t\te.g : gg \n");
+ ShowMessages("\t\te.g : gg wp \n");
+}
+
+/**
+ * @brief gg command handler
+ *
+ * @param CommandTokens
+ * @param Command
+ *
+ * @return VOID
+ */
+VOID
+CommandGg(vector CommandTokens, string Command)
+{
+ if (CommandTokens.size() == 1)
+ {
+ ShowMessages("Good Game! :)\n");
+ }
+ else if (CommandTokens.size() == 2 && CompareLowerCaseStrings(CommandTokens.at(1), "wp"))
+ {
+ ShowMessages("Good Game, Well Played! :)\n");
+ }
+ else
+ {
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
+ CommandGgHelp();
+ return;
+ }
+}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/gu.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/gu.cpp
similarity index 72%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/gu.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/gu.cpp
index 17aac4c7..36362c21 100644
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/gu.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/gu.cpp
@@ -43,38 +43,35 @@ CommandGuHelp()
/**
* @brief handler of gu command
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandGu(vector SplitCommand, string Command)
+CommandGu(vector CommandTokens, string Command)
{
- UINT32 StepCount;
- DEBUGGER_REMOTE_STEPPING_REQUEST RequestFormat;
- BOOLEAN BreakOnNextInstruction = FALSE;
+ UINT32 StepCount;
+ BOOLEAN LastInstruction = FALSE;
+ BOOLEAN BreakOnNextInstruction = FALSE;
//
// Validate the commands
//
- if (SplitCommand.size() != 1 && SplitCommand.size() != 2)
+ if (CommandTokens.size() != 1 && CommandTokens.size() != 2)
{
- ShowMessages("incorrect use of the 'gu'\n\n");
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandGuHelp();
return;
}
- //
- // Set type of request
- //
- RequestFormat = DEBUGGER_REMOTE_STEPPING_REQUEST_STEP_OVER_FOR_GU;
-
//
// Check if the command has a counter parameter
//
- if (SplitCommand.size() == 2)
+ if (CommandTokens.size() == 2)
{
- if (!ConvertStringToUInt32(SplitCommand.at(1), &StepCount))
+ if (!ConvertTokenToUInt32(CommandTokens.at(1), &StepCount))
{
ShowMessages("please specify a correct hex value for [count]\n\n");
CommandGuHelp();
@@ -106,7 +103,7 @@ CommandGu(vector SplitCommand, string Command)
//
g_IsInstrumentingInstructions = TRUE;
- for (size_t i = 0; i < StepCount; i++)
+ for (SIZE_T i = 0; i < StepCount; i++)
{
//
// For logging purpose
@@ -129,25 +126,13 @@ CommandGu(vector SplitCommand, string Command)
//
// It's the last instruction, so we gonna show the instruction
//
- RequestFormat = DEBUGGER_REMOTE_STEPPING_REQUEST_STEP_OVER_FOR_GU_LAST_INSTRUCTION;
+ LastInstruction = TRUE;
}
- if (g_IsSerialConnectedToRemoteDebuggee)
- {
- //
- // It's stepping over serial connection in kernel debugger
- //
- KdSendStepPacketToDebuggee(RequestFormat);
- }
- else
- {
- //
- // It's stepping over user debugger
- //
- UdSendStepPacketToDebuggee(g_ActiveProcessDebuggingState.ProcessDebuggingToken,
- g_ActiveProcessDebuggingState.ThreadId,
- RequestFormat);
- }
+ //
+ // Perform a GU step
+ //
+ SteppingStepOverForGu(LastInstruction);
//
// Check if user pressed CTRL+C
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/i.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/i.cpp
similarity index 81%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/i.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/i.cpp
index f299fe99..29fdad73 100644
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/i.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/i.cpp
@@ -47,22 +47,23 @@ CommandIHelp()
/**
* @brief handler of i command
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandI(vector SplitCommand, string Command)
+CommandI(vector CommandTokens, string Command)
{
- UINT32 StepCount;
- DEBUGGER_REMOTE_STEPPING_REQUEST RequestFormat;
+ UINT32 StepCount;
//
// Validate the commands
//
- if (SplitCommand.size() != 1 && SplitCommand.size() != 2)
+ if (CommandTokens.size() != 1 && CommandTokens.size() != 2)
{
- ShowMessages("incorrect use of the 'i'\n\n");
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandIHelp();
return;
}
@@ -76,17 +77,12 @@ CommandI(vector SplitCommand, string Command)
return;
}
- //
- // Set type of step
- //
- RequestFormat = DEBUGGER_REMOTE_STEPPING_REQUEST_INSTRUMENTATION_STEP_IN;
-
//
// Check if the command has a counter parameter
//
- if (SplitCommand.size() == 2)
+ if (CommandTokens.size() == 2)
{
- if (!ConvertStringToUInt32(SplitCommand.at(1), &StepCount))
+ if (!ConvertTokenToUInt32(CommandTokens.at(1), &StepCount))
{
ShowMessages("please specify a correct hex value for [count]\n\n");
CommandIHelp();
@@ -108,7 +104,7 @@ CommandI(vector SplitCommand, string Command)
//
g_IsInstrumentingInstructions = TRUE;
- for (size_t i = 0; i < StepCount; i++)
+ for (SIZE_T i = 0; i < StepCount; i++)
{
//
// For logging purpose
@@ -120,14 +116,15 @@ CommandI(vector SplitCommand, string Command)
//
// It's stepping over serial connection in kernel debugger
//
- KdSendStepPacketToDebuggee(RequestFormat);
+ SteppingInstrumentationStepIn();
- if (!SplitCommand.at(0).compare("ir"))
+ if (CompareLowerCaseStrings(CommandTokens.at(0), "ir"))
{
//
// Show registers
//
- ShowAllRegisters();
+ HyperDbgRegisterShowAll();
+
if (i != StepCount - 1)
{
ShowMessages("\n");
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/k.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/k.cpp
similarity index 72%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/k.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/k.cpp
index 3ea810ec..9affccd8 100644
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/k.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/k.cpp
@@ -47,26 +47,24 @@ CommandKHelp()
/**
* @brief k command handler
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandK(vector SplitCommand, string Command)
+CommandK(vector CommandTokens, string Command)
{
- UINT64 BaseAddress = NULL; // Null base address means current RSP register
- UINT32 Length = 0x100; // Default length
- vector SplitCommandCaseSensitive {Split(Command, ' ')};
- UINT32 IndexInCommandCaseSensitive = 0;
- BOOLEAN IsFirstCommand = TRUE;
- BOOLEAN IsNextBase = FALSE;
- BOOLEAN IsNextLength = FALSE;
+ UINT64 BaseAddress = NULL; // Null base address means current RSP register
+ UINT32 Length = PAGE_SIZE; // Default length
+ BOOLEAN IsFirstCommand = TRUE;
+ BOOLEAN IsNextBase = FALSE;
+ BOOLEAN IsNextLength = FALSE;
- string FirstCommand = SplitCommand.front();
-
- if (SplitCommand.size() >= 6)
+ if (CommandTokens.size() >= 6)
{
- ShowMessages("incorrect use of the '%s'\n\n", FirstCommand.c_str());
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandKHelp();
return;
}
@@ -83,17 +81,15 @@ CommandK(vector SplitCommand, string Command)
//
if (g_IsRunningInstruction32Bit)
{
- Length = 0x100;
+ Length = PAGE_SIZE;
}
else
{
- Length = 0x200;
+ Length = PAGE_SIZE * 2;
}
- for (auto Section : SplitCommand)
+ for (auto Section : CommandTokens)
{
- IndexInCommandCaseSensitive++;
-
if (IsFirstCommand)
{
IsFirstCommand = FALSE;
@@ -101,14 +97,14 @@ CommandK(vector SplitCommand, string Command)
}
if (IsNextBase == TRUE)
{
- if (!SymbolConvertNameOrExprToAddress(SplitCommandCaseSensitive.at(IndexInCommandCaseSensitive - 1),
+ if (!SymbolConvertNameOrExprToAddress(GetCaseSensitiveStringFromCommandToken(Section),
&BaseAddress))
{
//
// Couldn't resolve or unknown parameter
//
ShowMessages("err, couldn't resolve error at '%s'\n",
- SplitCommandCaseSensitive.at(IndexInCommandCaseSensitive - 1).c_str());
+ GetCaseSensitiveStringFromCommandToken(Section).c_str());
return;
}
@@ -118,7 +114,7 @@ CommandK(vector SplitCommand, string Command)
if (IsNextLength == TRUE)
{
- if (!ConvertStringToUInt32(Section, &Length))
+ if (!ConvertTokenToUInt32(Section, &Length))
{
ShowMessages("err, you should enter a valid length\n\n");
return;
@@ -127,13 +123,13 @@ CommandK(vector SplitCommand, string Command)
continue;
}
- if (!Section.compare("l"))
+ if (CompareLowerCaseStrings(Section, "l"))
{
IsNextLength = TRUE;
continue;
}
- if (!Section.compare("base"))
+ if (CompareLowerCaseStrings(Section, "base"))
{
IsNextBase = TRUE;
continue;
@@ -143,7 +139,7 @@ CommandK(vector SplitCommand, string Command)
// User inserts unexpected input
//
ShowMessages("err, incorrect use of the '%s' command\n\n",
- FirstCommand.c_str());
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandKHelp();
return;
@@ -151,7 +147,8 @@ CommandK(vector SplitCommand, string Command)
if (IsNextLength || IsNextBase)
{
- ShowMessages("incorrect use of the '%s' command\n\n", FirstCommand.c_str());
+ ShowMessages("incorrect use of the '%s' command\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandKHelp();
return;
}
@@ -160,21 +157,21 @@ CommandK(vector SplitCommand, string Command)
// Send callstack request
//
- if (!FirstCommand.compare("k"))
+ if (CompareLowerCaseStrings(CommandTokens.at(0), "k"))
{
KdSendCallStackPacketToDebuggee(BaseAddress,
Length,
DEBUGGER_CALLSTACK_DISPLAY_METHOD_WITHOUT_PARAMS,
g_IsRunningInstruction32Bit);
}
- else if (!FirstCommand.compare("kq"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(0), "kq"))
{
KdSendCallStackPacketToDebuggee(BaseAddress,
Length,
DEBUGGER_CALLSTACK_DISPLAY_METHOD_WITH_PARAMS,
FALSE);
}
- else if (!FirstCommand.compare("kd"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(0), "kd"))
{
KdSendCallStackPacketToDebuggee(BaseAddress,
Length,
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/lm.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/lm.cpp
similarity index 83%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/lm.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/lm.cpp
index bc4e0c5d..ce0cfb12 100644
--- a/hyperdbg/hprdbgctrl/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,43 +272,14 @@ CommandLmShowUserModeModule(UINT32 ProcessId, const char * SearchModule)
* @return BOOLEAN
*/
BOOLEAN
-CommandLmShowKernelModeModule(const char * SearchModule)
+CommandLmShowKernelModeModule(const CHAR * SearchModule)
{
- NTSTATUS Status = STATUS_UNSUCCESSFUL;
- PRTL_PROCESS_MODULES ModulesInfo;
- ULONG SysModuleInfoBufferSize = 0;
+ PRTL_PROCESS_MODULES ModulesInfo = NULL;
string SearchModuleString;
- //
- // Get required size of "RTL_PROCESS_MODULES" buffer
- //
- Status = NtQuerySystemInformation(SystemModuleInformation, NULL, NULL, &SysModuleInfoBufferSize);
-
- //
- // Allocate memory for the module list
- //
- ModulesInfo = (PRTL_PROCESS_MODULES)VirtualAlloc(
- NULL,
- SysModuleInfoBufferSize,
- MEM_COMMIT | MEM_RESERVE,
- PAGE_READWRITE);
-
- if (!ModulesInfo)
+ if (SymbolCheckAndAllocateModuleInformation(&ModulesInfo) == FALSE)
{
- ShowMessages("err, unable to allocate memory for module list (%x)\n",
- GetLastError());
- return FALSE;
- }
-
- Status = NtQuerySystemInformation(SystemModuleInformation,
- ModulesInfo,
- SysModuleInfoBufferSize,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- ShowMessages("err, unable to query module list (%x)\n", Status);
-
- VirtualFree(ModulesInfo, 0, MEM_RELEASE);
+ ShowMessages("err, unable get modules information\n");
return FALSE;
}
@@ -331,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)
{
@@ -346,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);
@@ -369,7 +341,7 @@ CommandLmShowKernelModeModule(const char * SearchModule)
ShowMessages("%s\n", CurrentModule->FullPathName);
}
- VirtualFree(ModulesInfo, 0, MEM_RELEASE);
+ free(ModulesInfo);
return TRUE;
}
@@ -377,12 +349,13 @@ CommandLmShowKernelModeModule(const char * SearchModule)
/**
* @brief handle lm command
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandLm(vector SplitCommand, string Command)
+CommandLm(vector CommandTokens, string Command)
{
BOOLEAN SetPid = FALSE;
BOOLEAN SetSearchFilter = FALSE;
@@ -390,35 +363,35 @@ CommandLm(vector SplitCommand, 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)
//
- for (auto Section : SplitCommand)
+ for (auto Section : CommandTokens)
{
- if (!Section.compare("lm"))
+ if (CompareLowerCaseStrings(Section, "lm"))
{
continue;
}
- else if (!Section.compare("pid") && !SetPid)
+ else if (CompareLowerCaseStrings(Section, "pid") && !SetPid)
{
SetPid = TRUE;
}
- else if (!Section.compare("m") && !SetSearchFilter)
+ else if (CompareLowerCaseStrings(Section, "m") && !SetSearchFilter)
{
SetSearchFilter = TRUE;
}
else if (SetPid)
{
- if (!ConvertStringToUInt32(Section, &TargetPid))
+ if (!ConvertTokenToUInt32(Section, &TargetPid))
{
//
// couldn't resolve or unknown parameter
//
ShowMessages("err, couldn't resolve error at '%s'\n\n",
- Section.c_str());
+ GetCaseSensitiveStringFromCommandToken(Section).c_str());
CommandLmHelp();
return;
}
@@ -426,7 +399,7 @@ CommandLm(vector SplitCommand, string Command)
}
else if (SetSearchFilter)
{
- if (Section.length() >= MAX_PATH)
+ if (GetCaseSensitiveStringFromCommandToken(Section).length() >= MAX_PATH)
{
ShowMessages("err, string is too large for search, please enter "
"smaller string\n");
@@ -435,11 +408,11 @@ CommandLm(vector SplitCommand, string Command)
}
SearchStringEntered = TRUE;
- strcpy(Search, Section.c_str());
+ strcpy(Search, GetLowerStringFromCommandToken(Section).c_str());
SetSearchFilter = FALSE;
}
- else if (!Section.compare("km"))
+ else if (CompareLowerCaseStrings(Section, "km"))
{
if (OnlyShowUserModules)
{
@@ -450,7 +423,7 @@ CommandLm(vector SplitCommand, string Command)
OnlyShowKernelModules = TRUE;
}
- else if (!Section.compare("um"))
+ else if (CompareLowerCaseStrings(Section, "um"))
{
if (OnlyShowKernelModules)
{
@@ -467,7 +440,7 @@ CommandLm(vector SplitCommand, string Command)
// Unknown parameter
//
ShowMessages("err, couldn't resolve error at '%s'\n\n",
- Section.c_str());
+ GetCaseSensitiveStringFromCommandToken(Section).c_str());
CommandLmHelp();
return;
}
diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/load.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/load.cpp
new file mode 100644
index 00000000..3ea642c4
--- /dev/null
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/load.cpp
@@ -0,0 +1,184 @@
+/**
+ * @file load.cpp
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief load command
+ * @details
+ * @version 0.1
+ * @date 2020-05-27
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+//
+// Global Variables
+//
+extern BOOLEAN g_IsConnectedToHyperDbgLocally;
+extern BOOLEAN g_IsKdModuleLoaded;
+extern BOOLEAN g_IsVmmModuleLoaded;
+extern BOOLEAN g_IsHyperTraceModuleLoaded;
+
+/**
+ * @brief help of the load command
+ *
+ * @return VOID
+ */
+VOID
+CommandLoadHelp()
+{
+ ShowMessages("load : installs drivers and load modules.\n\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");
+}
+
+/**
+ * @brief load command handler
+ *
+ * @param CommandTokens
+ * @param Command
+ *
+ * @return VOID
+ */
+VOID
+CommandLoad(vector CommandTokens, string Command)
+{
+ if (CommandTokens.size() != 2)
+ {
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
+ CommandLoadHelp();
+ return;
+ }
+
+ if (!g_IsConnectedToHyperDbgLocally)
+ {
+ ShowMessages("you're not connected to any instance of HyperDbg, did you "
+ "use '.connect'? \n");
+ return;
+ }
+
+ //
+ // Check for the module
+ //
+ if (CompareLowerCaseStrings(CommandTokens.at(1), "all") || CompareLowerCaseStrings(CommandTokens.at(1), "."))
+ {
+ //
+ // Load aa Modules
+ //
+ ShowMessages("loading the all modules\n");
+
+ if (HyperDbgInstallKdDriver() == 1 || HyperDbgLoadAllModules() == 1)
+ {
+ ShowMessages("failed to install or load drivers\n");
+ return;
+ }
+
+ //
+ // 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
+ //
+ 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;
+ }
+
+ //
+ // 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;
+ }
+
+ //
+ // 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
+ //
+ 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
+ {
+ //
+ // Module not found
+ //
+ ShowMessages("err, module not found\n");
+ }
+}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/output.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/output.cpp
similarity index 86%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/output.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/output.cpp
index 51a96c94..0fafc899 100644
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/output.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/output.cpp
@@ -28,12 +28,16 @@ CommandOutputHelp()
ShowMessages("output : creates an output instance that can be used in event "
"forwarding.\n\n");
- ShowMessages("syntax : \toutput [create Name (string)] [file|namedpipe|tcp Address (string)]\n");
+ ShowMessages("syntax : \toutput\n");
+ ShowMessages("syntax : \toutput [create Name (string)] [file|namedpipe|tcp|module Address (string)]\n");
ShowMessages("syntax : \toutput [open|close Name (string)]\n");
ShowMessages("\n");
+ ShowMessages("\t\te.g : output\n");
ShowMessages("\t\te.g : output create MyOutputName1 file "
"c:\\rev\\output.txt\n");
+ ShowMessages("\t\te.g : output create MyOutputName1 file "
+ "\"c:\\rev\\output file.txt\"\n");
ShowMessages("\t\te.g : output create MyOutputName2 tcp 192.168.1.10:8080\n");
ShowMessages("\t\te.g : output create MyOutputName3 namedpipe "
"\\\\.\\Pipe\\HyperDbgOutput\n");
@@ -46,12 +50,12 @@ CommandOutputHelp()
/**
* @brief output command handler
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
* @return VOID
*/
VOID
-CommandOutput(vector SplitCommand, string Command)
+CommandOutput(vector CommandTokens, string Command)
{
PDEBUGGER_EVENT_FORWARDING EventForwardingObject;
DEBUGGER_EVENT_FORWARDING_TYPE Type;
@@ -63,11 +67,11 @@ CommandOutput(vector SplitCommand, string Command)
HANDLE SourceHandle = INVALID_HANDLE_VALUE;
SOCKET Socket = NULL;
HMODULE Module = NULL;
- vector SplitCommandCaseSensitive {Split(Command, ' ')};
- if (SplitCommand.size() <= 2)
+ if ((CommandTokens.size() != 1 && CommandTokens.size() <= 2) || CommandTokens.size() >= 6)
{
- ShowMessages("incorrect use of the 'output'\n\n");
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandOutputHelp();
return;
}
@@ -75,7 +79,7 @@ CommandOutput(vector SplitCommand, string Command)
//
// Check if the user needs a list of outputs or not
//
- if (SplitCommand.size() == 1)
+ if (CommandTokens.size() == 1)
{
IndexToShowList = 0;
@@ -145,7 +149,7 @@ CommandOutput(vector SplitCommand, string Command)
//
// Check if it's a create, open, or close
//
- if (!SplitCommand.at(1).compare("create"))
+ if (CompareLowerCaseStrings(CommandTokens.at(1), "create"))
{
//
// It's a create
@@ -154,9 +158,10 @@ CommandOutput(vector SplitCommand, string Command)
//
// check if the parameters are okay for a create or not
//
- if (SplitCommand.size() <= 4)
+ if (CommandTokens.size() <= 4)
{
- ShowMessages("incorrect use of the 'output'\n\n");
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandOutputHelp();
return;
}
@@ -164,26 +169,26 @@ CommandOutput(vector SplitCommand, string Command)
//
// Check for the type of the output source
//
- if (!SplitCommand.at(3).compare("file"))
+ if (CompareLowerCaseStrings(CommandTokens.at(3), "file"))
{
Type = EVENT_FORWARDING_FILE;
}
- else if (!SplitCommand.at(3).compare("namedpipe"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(3), "namedpipe"))
{
Type = EVENT_FORWARDING_NAMEDPIPE;
}
- else if (!SplitCommand.at(3).compare("tcp"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(3), "tcp"))
{
Type = EVENT_FORWARDING_TCP;
}
- else if (!SplitCommand.at(3).compare("module"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(3), "module"))
{
Type = EVENT_FORWARDING_MODULE;
}
else
{
ShowMessages("incorrect type near '%s'\n\n",
- SplitCommand.at(3).c_str());
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(3)).c_str());
CommandOutputHelp();
return;
}
@@ -191,7 +196,7 @@ CommandOutput(vector SplitCommand, string Command)
//
// Check to make sure that the name doesn't exceed the maximum character
//
- if (SplitCommand.at(2).size() >=
+ if (GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2)).size() >=
MAXIMUM_CHARACTERS_FOR_EVENT_FORWARDING_NAME)
{
ShowMessages("name of the output cannot exceed form %d characters\n\n",
@@ -217,7 +222,7 @@ CommandOutput(vector SplitCommand, string Command)
CONTAINING_RECORD(TempList, DEBUGGER_EVENT_FORWARDING, OutputSourcesList);
if (strcmp(CurrentOutputSourceDetails->Name,
- SplitCommandCaseSensitive.at(2).c_str()) == 0)
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2)).c_str()) == 0)
{
//
// Indicate that we found this item
@@ -245,9 +250,7 @@ CommandOutput(vector SplitCommand, string Command)
//
// try to open the source and get the handle
//
- DetailsOfSource = Command.substr(Command.find(SplitCommandCaseSensitive.at(3)) +
- SplitCommandCaseSensitive.at(3).size() + 1,
- Command.size());
+ DetailsOfSource = GetCaseSensitiveStringFromCommandToken(CommandTokens.at(4));
SourceHandle = ForwardingCreateOutputSource(Type, DetailsOfSource, &Socket, &Module);
@@ -315,7 +318,8 @@ CommandOutput(vector SplitCommand, string Command)
//
// Move the name of the output source to the buffer
//
- strcpy_s(EventForwardingObject->Name, SplitCommandCaseSensitive.at(2).c_str());
+ strcpy_s(EventForwardingObject->Name,
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2)).c_str());
//
// Check if list is initialized or not
@@ -332,7 +336,7 @@ CommandOutput(vector SplitCommand, string Command)
InsertHeadList(&g_OutputSources,
&(EventForwardingObject->OutputSourcesList));
}
- else if (!SplitCommand.at(1).compare("open"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(1), "open"))
{
//
// It's an open
@@ -359,7 +363,7 @@ CommandOutput(vector SplitCommand, string Command)
OutputSourcesList);
if (strcmp(CurrentOutputSourceDetails->Name,
- SplitCommandCaseSensitive.at(2).c_str()) == 0)
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2)).c_str()) == 0)
{
//
// Indicate that we found this item
@@ -401,7 +405,7 @@ CommandOutput(vector SplitCommand, string Command)
return;
}
}
- else if (!SplitCommand.at(1).compare("close"))
+ else if (CompareLowerCaseStrings(CommandTokens.at(1), "close"))
{
//
// It's a close
@@ -428,7 +432,7 @@ CommandOutput(vector SplitCommand, string Command)
OutputSourcesList);
if (strcmp(CurrentOutputSourceDetails->Name,
- SplitCommandCaseSensitive.at(2).c_str()) == 0)
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2)).c_str()) == 0)
{
//
// Indicate that we found this item
@@ -475,7 +479,8 @@ CommandOutput(vector SplitCommand, string Command)
//
// Invalid argument
//
- ShowMessages("incorrect option at '%s'\n\n", SplitCommand.at(1).c_str());
+ ShowMessages("incorrect option at '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandOutputHelp();
return;
}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/p.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/p.cpp
similarity index 75%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/p.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/p.cpp
index d4a0c86b..a50a41d2 100644
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/p.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/p.cpp
@@ -44,12 +44,13 @@ CommandPHelp()
/**
* @brief handler of p command
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandP(vector SplitCommand, string Command)
+CommandP(vector CommandTokens, string Command)
{
UINT32 StepCount;
DEBUGGER_REMOTE_STEPPING_REQUEST RequestFormat;
@@ -57,9 +58,10 @@ CommandP(vector SplitCommand, string Command)
//
// Validate the commands
//
- if (SplitCommand.size() != 1 && SplitCommand.size() != 2)
+ if (CommandTokens.size() != 1 && CommandTokens.size() != 2)
{
- ShowMessages("incorrect use of the 'p'\n\n");
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandPHelp();
return;
}
@@ -72,9 +74,9 @@ CommandP(vector SplitCommand, string Command)
//
// Check if the command has a counter parameter
//
- if (SplitCommand.size() == 2)
+ if (CommandTokens.size() == 2)
{
- if (!ConvertStringToUInt32(SplitCommand.at(1), &StepCount))
+ if (!ConvertTokenToUInt32(CommandTokens.at(1), &StepCount))
{
ShowMessages("please specify a correct hex value for [count]\n\n");
CommandPHelp();
@@ -106,7 +108,7 @@ CommandP(vector SplitCommand, string Command)
//
g_IsInstrumentingInstructions = TRUE;
- for (size_t i = 0; i < StepCount; i++)
+ for (SIZE_T i = 0; i < StepCount; i++)
{
//
// For logging purpose
@@ -115,29 +117,18 @@ CommandP(vector SplitCommand, string Command)
// (float)StepCount), i);
//
- if (g_IsSerialConnectedToRemoteDebuggee)
- {
- //
- // It's stepping over serial connection in kernel debugger
- //
- KdSendStepPacketToDebuggee(RequestFormat);
- }
- else
- {
- //
- // It's stepping over user debugger
- //
- UdSendStepPacketToDebuggee(g_ActiveProcessDebuggingState.ProcessDebuggingToken,
- g_ActiveProcessDebuggingState.ThreadId,
- RequestFormat);
- }
+ //
+ // Perform Step-over
+ //
+ SteppingStepOver();
- if (!SplitCommand.at(0).compare("pr"))
+ if (CompareLowerCaseStrings(CommandTokens.at(0), "pr"))
{
//
// Show registers
//
- ShowAllRegisters();
+ HyperDbgRegisterShowAll();
+
if (i != StepCount - 1)
{
ShowMessages("\n");
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/pause.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/pause.cpp
similarity index 76%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/pause.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/pause.cpp
index 8e70bfc7..5d2246e7 100644
--- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/pause.cpp
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/pause.cpp
@@ -54,28 +54,32 @@ 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");
}
}
/**
* @brief pause command handler
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandPause(vector SplitCommand, string Command)
+CommandPause(vector CommandTokens, string Command)
{
- if (SplitCommand.size() != 1)
+ if (CommandTokens.size() != 1)
{
- ShowMessages("incorrect use of the 'pause'\n\n");
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandPauseHelp();
return;
}
+ //
+ // request to pause
+ //
CommandPauseRequest();
}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/preactivate.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/preactivate.cpp
similarity index 71%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/preactivate.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/preactivate.cpp
index 21033c5e..ee88936d 100644
--- a/hyperdbg/hprdbgctrl/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
*
@@ -34,20 +40,22 @@ CommandPreactivateHelp()
/**
* @brief preactivate command handler
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandPreactivate(vector SplitCommand, string Command)
+CommandPreactivate(vector CommandTokens, string Command)
{
BOOL Status;
ULONG ReturnedLength;
- DEBUGGER_PREACTIVATE_COMMAND PreactivateRequest = {0};
+ DEBUGGER_PREACTIVATE_COMMAND PreactivateRequest = {};
- if (SplitCommand.size() != 2)
+ if (CommandTokens.size() != 2)
{
- ShowMessages("incorrect use of the 'Preactivate'\n\n");
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandPreactivateHelp();
return;
}
@@ -55,7 +63,7 @@ CommandPreactivate(vector SplitCommand, string Command)
//
// Set the type of preactivation
//
- if (!SplitCommand.at(1).compare("mode") || !SplitCommand.at(1).compare("!mode"))
+ if (CompareLowerCaseStrings(CommandTokens.at(1), "mode") || CompareLowerCaseStrings(CommandTokens.at(1), "!mode"))
{
PreactivateRequest.Type = DEBUGGER_PREACTIVATE_COMMAND_TYPE_MODE;
}
@@ -65,16 +73,16 @@ CommandPreactivate(vector SplitCommand, string Command)
// Couldn't resolve or unknown parameter
//
ShowMessages("err, couldn't resolve error at '%s'\n",
- SplitCommand.at(1).c_str());
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(1)).c_str());
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.
@@ -88,7 +96,7 @@ CommandPreactivate(vector SplitCommand, 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/hprdbgctrl/code/debugger/commands/debugging-commands/prealloc.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/prealloc.cpp
similarity index 73%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/prealloc.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/prealloc.cpp
index 1f13b8cc..0bf9545b 100644
--- a/hyperdbg/hprdbgctrl/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
*
@@ -46,57 +51,62 @@ CommandPreallocHelp()
/**
* @brief prealloc command handler
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandPrealloc(vector SplitCommand, string Command)
+CommandPrealloc(vector CommandTokens, string Command)
{
BOOL Status;
ULONG ReturnedLength;
UINT64 Count;
- DEBUGGER_PREALLOC_COMMAND PreallocRequest = {0};
+ DEBUGGER_PREALLOC_COMMAND PreallocRequest = {};
+ string SecondParam;
- if (SplitCommand.size() != 3)
+ if (CommandTokens.size() != 3)
{
- ShowMessages("incorrect use of the 'prealloc'\n\n");
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandPreallocHelp();
return;
}
+ SecondParam = GetLowerStringFromCommandToken(CommandTokens.at(1));
+
//
// Set the type of pre-allocation
//
- if (!SplitCommand.at(1).compare("thread-interception"))
+ if (!SecondParam.compare("thread-interception"))
{
PreallocRequest.Type = DEBUGGER_PREALLOC_COMMAND_TYPE_THREAD_INTERCEPTION;
}
- else if (!SplitCommand.at(1).compare("monitor") || !SplitCommand.at(1).compare("!monitor"))
+ else if (!SecondParam.compare("monitor") || !SecondParam.compare("!monitor"))
{
PreallocRequest.Type = DEBUGGER_PREALLOC_COMMAND_TYPE_MONITOR;
}
- else if (!SplitCommand.at(1).compare("epthook") || !SplitCommand.at(1).compare("!epthook"))
+ else if (!SecondParam.compare("epthook") || !SecondParam.compare("!epthook"))
{
PreallocRequest.Type = DEBUGGER_PREALLOC_COMMAND_TYPE_EPTHOOK;
}
- else if (!SplitCommand.at(1).compare("epthook2") || !SplitCommand.at(1).compare("!epthook2"))
+ else if (!SecondParam.compare("epthook2") || !SecondParam.compare("!epthook2"))
{
PreallocRequest.Type = DEBUGGER_PREALLOC_COMMAND_TYPE_EPTHOOK2;
}
- else if (!SplitCommand.at(1).compare("regular-event"))
+ else if (!SecondParam.compare("regular-event"))
{
PreallocRequest.Type = DEBUGGER_PREALLOC_COMMAND_TYPE_REGULAR_EVENT;
}
- else if (!SplitCommand.at(1).compare("big-event"))
+ else if (!SecondParam.compare("big-event"))
{
PreallocRequest.Type = DEBUGGER_PREALLOC_COMMAND_TYPE_BIG_EVENT;
}
- else if (!SplitCommand.at(1).compare("regular-safe-buffer"))
+ else if (!SecondParam.compare("regular-safe-buffer"))
{
PreallocRequest.Type = DEBUGGER_PREALLOC_COMMAND_TYPE_REGULAR_SAFE_BUFFER;
}
- else if (!SplitCommand.at(1).compare("big-safe-buffer"))
+ else if (!SecondParam.compare("big-safe-buffer"))
{
PreallocRequest.Type = DEBUGGER_PREALLOC_COMMAND_TYPE_BIG_SAFE_BUFFER;
}
@@ -106,20 +116,20 @@ CommandPrealloc(vector SplitCommand, string Command)
// Couldn't resolve or unknown parameter
//
ShowMessages("err, couldn't resolve error at '%s'\n",
- SplitCommand.at(1).c_str());
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(1)).c_str());
return;
}
//
// Get the count of needed pre-allocated buffers
//
- if (!SymbolConvertNameOrExprToAddress(SplitCommand.at(2), &Count))
+ if (!SymbolConvertNameOrExprToAddress(GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2)), &Count))
{
//
// Couldn't resolve or unknown parameter
//
ShowMessages("err, couldn't resolve error at '%s'\n",
- SplitCommand.at(2).c_str());
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2)).c_str());
return;
}
@@ -128,12 +138,12 @@ CommandPrealloc(vector SplitCommand, 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.
@@ -147,7 +157,7 @@ CommandPrealloc(vector SplitCommand, 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
new file mode 100644
index 00000000..da7af0e0
--- /dev/null
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/print.cpp
@@ -0,0 +1,77 @@
+/**
+ * @file print.cpp
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @author M.H. Gholamrezaei (mh@hyperdbg.org)
+ * @brief print command
+ * @details
+ * @version 0.1
+ * @date 2020-10-08
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+using namespace std;
+
+/**
+ * @brief help of the print command
+ *
+ * @return VOID
+ */
+VOID
+CommandPrintHelp()
+{
+ ShowMessages("print : evaluates expressions.\n\n");
+
+ ShowMessages("syntax : \tprint [Expression (string)]\n");
+
+ ShowMessages("\n");
+ ShowMessages("\t\te.g : print dq(poi(@rcx))\n");
+}
+
+/**
+ * @brief handler of print command
+ *
+ * @param CommandTokens
+ * @param Command
+ *
+ * @return VOID
+ */
+VOID
+CommandPrint(vector CommandTokens, string Command)
+{
+ if (CommandTokens.size() == 1)
+ {
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
+ CommandPrintHelp();
+ return;
+ }
+
+ //
+ // Trim the command
+ //
+ Trim(Command);
+
+ //
+ // Remove print from it
+ //
+ Command.erase(0, GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).size());
+
+ //
+ // Trim it again
+ //
+ Trim(Command);
+
+ //
+ // Prepend and append 'print(' and ')'
+ //
+ Command.insert(0, "print(");
+ Command.append(");");
+
+ //
+ // 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
new file mode 100644
index 00000000..ca0aaa73
--- /dev/null
+++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/r.cpp
@@ -0,0 +1,574 @@
+/**
+ * @file r.cpp
+ * @author Alee Amini (alee@hyperdbg.org)
+ * @author Sina Karvandi (sina@hyperdbg.org)
+ * @brief r command
+ * @details
+ * @version 0.1
+ * @date 2021-02-27
+ *
+ * @copyright This project is released under the GNU Public License v3.
+ *
+ */
+#include "pch.h"
+
+// using namespace std;
+
+//
+// Global Variables
+//
+extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
+extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
+
+std::map RegistersMap = {
+ {"rax", REGISTER_RAX},
+ {"eax", REGISTER_EAX},
+ {"ax", REGISTER_AX},
+ {"ah", REGISTER_AH},
+ {"al", REGISTER_AL},
+ {"rbx", REGISTER_RBX},
+ {"ebx", REGISTER_EBX},
+ {"bx", REGISTER_BX},
+ {"bh", REGISTER_BH},
+ {"bl", REGISTER_BL},
+ {"rcx", REGISTER_RCX},
+ {"ecx", REGISTER_ECX},
+ {"cx", REGISTER_CX},
+ {"ch", REGISTER_CH},
+ {"cl", REGISTER_CL},
+ {"rdx", REGISTER_RDX},
+ {"edx", REGISTER_EDX},
+ {"dx", REGISTER_DX},
+ {"dh", REGISTER_DH},
+ {"dl", REGISTER_DL},
+ {"rsi", REGISTER_RSI},
+ {"esi", REGISTER_ESI},
+ {"si", REGISTER_SI},
+ {"sil", REGISTER_SIL},
+ {"rdi", REGISTER_RDI},
+ {"edi", REGISTER_EDI},
+ {"di", REGISTER_DI},
+ {"dil", REGISTER_DIL},
+ {"rbp", REGISTER_RBP},
+ {"ebp", REGISTER_EBP},
+ {"bp", REGISTER_BP},
+ {"bpl", REGISTER_BPL},
+ {"rsp", REGISTER_RSP},
+ {"esp", REGISTER_ESP},
+ {"sp", REGISTER_SP},
+ {"spl", REGISTER_SPL},
+ {"r8", REGISTER_R8},
+ {"r8d", REGISTER_R8D},
+ {"r8w", REGISTER_R8W},
+ {"r8h", REGISTER_R8H},
+ {"r8l", REGISTER_R8L},
+ {"r9", REGISTER_R9},
+ {"r9d", REGISTER_R9D},
+ {"r9w", REGISTER_R9W},
+ {"r9h", REGISTER_R9H},
+ {"r9l", REGISTER_R9L},
+ {"r10", REGISTER_R10},
+ {"r10d", REGISTER_R10D},
+ {"r10w", REGISTER_R10W},
+ {"r10h", REGISTER_R10H},
+ {"r10l", REGISTER_R10L},
+ {"r11", REGISTER_R11},
+ {"r11d", REGISTER_R11D},
+ {"r11w", REGISTER_R11W},
+ {"r11h", REGISTER_R11H},
+ {"r11l", REGISTER_R11L},
+ {"r12", REGISTER_R12},
+ {"r12d", REGISTER_R12D},
+ {"r12w", REGISTER_R12W},
+ {"r12h", REGISTER_R12H},
+ {"r12l", REGISTER_R12L},
+ {"r13", REGISTER_R13},
+ {"r13d", REGISTER_R13D},
+ {"r13w", REGISTER_R13W},
+ {"r13h", REGISTER_R13H},
+ {"r13l", REGISTER_R13L},
+ {"r14", REGISTER_R14},
+ {"r14d", REGISTER_R14D},
+ {"r14w", REGISTER_R14W},
+ {"r14h", REGISTER_R14H},
+ {"r14l", REGISTER_R14L},
+ {"r15", REGISTER_R15},
+ {"r15d", REGISTER_R15D},
+ {"r15w", REGISTER_R15W},
+ {"r15h", REGISTER_R15H},
+ {"r15l", REGISTER_R15L},
+ {"ds", REGISTER_DS},
+ {"es", REGISTER_ES},
+ {"fs", REGISTER_FS},
+ {"gs", REGISTER_GS},
+ {"cs", REGISTER_CS},
+ {"ss", REGISTER_SS},
+ {"rflags", REGISTER_RFLAGS},
+ {"eflags", REGISTER_EFLAGS},
+ {"flags", REGISTER_FLAGS},
+ {"cf", REGISTER_CF},
+ {"pf", REGISTER_PF},
+ {"af", REGISTER_AF},
+ {"zf", REGISTER_ZF},
+ {"sf", REGISTER_SF},
+ {"tf", REGISTER_TF},
+ {"if", REGISTER_IF},
+ {"df", REGISTER_DF},
+ {"of", REGISTER_OF},
+ {"iopl", REGISTER_IOPL},
+ {"nt", REGISTER_NT},
+ {"rf", REGISTER_RF},
+ {"vm", REGISTER_VM},
+ {"ac", REGISTER_AC},
+ {"vif", REGISTER_VIF},
+ {"vip", REGISTER_VIP},
+ {"id", REGISTER_ID},
+ {"idtr", REGISTER_IDTR},
+ {"gdtr", REGISTER_GDTR},
+ {"ldtr", REGISTER_LDTR},
+ {"tr", REGISTER_TR},
+ {"cr0", REGISTER_CR0},
+ {"cr2", REGISTER_CR2},
+ {"cr3", REGISTER_CR3},
+ {"cr4", REGISTER_CR4},
+ {"cr8", REGISTER_CR8},
+ {"dr0", REGISTER_DR0},
+ {"dr1", REGISTER_DR1},
+ {"dr2", REGISTER_DR2},
+ {"dr3", REGISTER_DR3},
+ {"dr6", REGISTER_DR6},
+ {"dr7", REGISTER_DR7},
+ {"rip", REGISTER_RIP},
+ {"eip", REGISTER_EIP},
+ {"ip", REGISTER_IP},
+};
+
+/**
+ * @brief help of the r command
+ *
+ * @return VOID
+ */
+VOID
+CommandRHelp()
+{
+ ShowMessages("r : reads or modifies registers.\n\n");
+
+ ShowMessages("syntax : \tr\n");
+ ShowMessages("syntax : \tr [Register (string)] [= Expr (string)]\n");
+
+ ShowMessages("\n");
+ ShowMessages("\t\te.g : r\n");
+ ShowMessages("\t\te.g : r @rax\n");
+ ShowMessages("\t\te.g : r rax\n");
+ ShowMessages("\t\te.g : r rax = 0x55\n");
+ ShowMessages("\t\te.g : r rax = @rbx + @rcx + 0n10\n");
+}
+
+/**
+ * @brief Read all registers
+ * @param GuestRegisters The guest registers
+ * @param ExtraRegisters The extra registers
+ *
+ * @return BOOLEAN Returns true if it was successful
+ */
+BOOLEAN
+HyperDbgReadAllRegisters(GUEST_REGS * GuestRegisters, GUEST_EXTRA_REGISTERS * ExtraRegisters)
+{
+ PGUEST_REGS Regs;
+ PGUEST_EXTRA_REGISTERS ExtraRegs;
+ DEBUGGEE_REGISTER_READ_DESCRIPTION * RegState = NULL;
+ UINT32 SizeOfRegState = 0;
+
+ //
+ // Calculate the size of the register state
+ //
+ SizeOfRegState = sizeof(DEBUGGEE_REGISTER_READ_DESCRIPTION) + sizeof(GUEST_REGS) + sizeof(GUEST_EXTRA_REGISTERS);
+
+ //
+ // Allocate memory for the register state
+ //
+ RegState = (DEBUGGEE_REGISTER_READ_DESCRIPTION *)malloc(SizeOfRegState);
+
+ //
+ // Check if the memory allocation was successful
+ //
+ if (RegState == NULL)
+ {
+ return FALSE;
+ }
+
+ //
+ // Set the register ID to show all registers
+ //
+ RegState->RegisterId = DEBUGGEE_SHOW_ALL_REGISTERS;
+
+ //
+ // Check whether a kernel debugger is connected or a user-mode debugger is active
+ //
+ if (g_IsSerialConnectedToRemoteDebuggee)
+ {
+ 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)
+ {
+ //
+ // Copy the registers and extra registers to the output
+ //
+ Regs = (GUEST_REGS *)(((CHAR *)RegState) + sizeof(DEBUGGEE_REGISTER_READ_DESCRIPTION));
+ ExtraRegs = (GUEST_EXTRA_REGISTERS *)(((CHAR *)RegState) + sizeof(DEBUGGEE_REGISTER_READ_DESCRIPTION) + sizeof(GUEST_REGS));
+
+ if (GuestRegisters != NULL)
+ {
+ memcpy(GuestRegisters, Regs, sizeof(GUEST_REGS));
+ }
+
+ if (ExtraRegisters != NULL)
+ {
+ memcpy(ExtraRegisters, ExtraRegs, sizeof(GUEST_EXTRA_REGISTERS));
+ }
+ }
+ else
+ {
+ ShowErrorMessage(RegState->KernelStatus);
+ free(RegState);
+ return FALSE;
+ }
+
+ free(RegState);
+ return TRUE;
+}
+
+/**
+ * @brief Read target register
+ * @param RegisterId The register ID
+ * @param TargetRegister The value of the target register
+ *
+ * @return BOOLEAN Returns true if it was successful
+ */
+BOOLEAN
+HyperDbgReadTargetRegister(REGS_ENUM RegisterId, UINT64 * TargetRegister)
+{
+ DEBUGGEE_REGISTER_READ_DESCRIPTION RegState = {0};
+
+ //
+ // Set the register ID
+ //
+ RegState.RegisterId = (UINT32)RegisterId;
+
+ if (g_IsSerialConnectedToRemoteDebuggee)
+ {
+ 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)
+ {
+ if (TargetRegister != NULL)
+ {
+ *TargetRegister = RegState.Value;
+ }
+ }
+ else
+ {
+ ShowErrorMessage(RegState.KernelStatus);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Write target register
+ * @param RegisterId The register ID
+ * @param Value The value of the target register
+ *
+ * @return BOOLEAN Returns true if it was successful
+ */
+BOOLEAN
+HyperDbgWriteTargetRegister(REGS_ENUM RegisterId, UINT64 Value)
+{
+ DEBUGGEE_REGISTER_WRITE_DESCRIPTION RegState = {0};
+
+ //
+ // Set the register ID
+ //
+ RegState.RegisterId = (UINT32)RegisterId;
+ RegState.Value = Value;
+
+ if (!KdSendWriteRegisterPacketToDebuggee(&RegState))
+ {
+ return FALSE;
+ }
+
+ if (RegState.KernelStatus == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
+ {
+ return TRUE;
+ }
+ else
+ {
+ ShowErrorMessage(RegState.KernelStatus);
+ return FALSE;
+ }
+}
+
+/**
+ * @brief handler of r show all registers
+ *
+ * @return BOOLEAN
+ */
+BOOLEAN
+HyperDbgRegisterShowAll()
+{
+ GUEST_REGS Regs = {0};
+ GUEST_EXTRA_REGISTERS ExtraRegs = {0};
+ RFLAGS Rflags = {0};
+
+ if (!HyperDbgReadAllRegisters(&Regs, &ExtraRegs))
+ {
+ return FALSE;
+ }
+
+ //
+ // Show the result of reading registers like rax=0000000000018b01
+ //
+ Rflags.AsUInt = ExtraRegs.RFLAGS;
+
+ ShowMessages(
+ "RAX=%016llx RBX=%016llx RCX=%016llx\n"
+ "RDX=%016llx RSI=% 016llx RDI=%016llx\n"
+ "RIP=%016llx RSP=%016llx RBP=%016llx\n"
+ "R8 =%016llx R9 =%016llx R10=%016llx\n"
+ "R11=%016llx R12=%016llx R13=%016llx\n"
+ "R14=%016llx R15=%016llx IOPL=%02x\n"
+ "%s %s %s %s\n%s %s %s %s\n"
+ "CS %04x SS %04x DS %04x ES %04x FS %04x GS %04x\n"
+ "RFLAGS=%016llx\n",
+ Regs.rax,
+ Regs.rbx,
+ Regs.rcx,
+ Regs.rdx,
+ Regs.rsi,
+ Regs.rdi,
+ ExtraRegs.RIP,
+ Regs.rsp,
+ Regs.rbp,
+ Regs.r8,
+ Regs.r9,
+ Regs.r10,
+ Regs.r11,
+ Regs.r12,
+ Regs.r13,
+ Regs.r14,
+ Regs.r15,
+ Rflags.IoPrivilegeLevel,
+ Rflags.OverflowFlag ? "OF 1" : "OF 0",
+ Rflags.DirectionFlag ? "DF 1" : "DF 0",
+ Rflags.InterruptEnableFlag ? "IF 1" : "IF 0",
+ Rflags.SignFlag ? "SF 1" : "SF 0",
+ Rflags.ZeroFlag ? "ZF 1" : "ZF 0",
+ Rflags.ParityFlag ? "PF 1" : "PF 0",
+ Rflags.CarryFlag ? "CF 1" : "CF 0",
+ Rflags.AuxiliaryCarryFlag ? "AXF 1" : "AXF 0",
+ ExtraRegs.CS,
+ ExtraRegs.SS,
+ ExtraRegs.DS,
+ ExtraRegs.ES,
+ ExtraRegs.FS,
+ ExtraRegs.GS,
+ ExtraRegs.RFLAGS);
+
+ return TRUE;
+}
+
+/**
+ * @brief handler of r show the target register
+ * @param RegisterId The register ID
+ *
+ * @return BOOLEAN Returns true if it was successful
+ */
+BOOLEAN
+HyperDbgRegisterShowTargetRegister(REGS_ENUM RegisterId)
+{
+ UINT64 TargetRegister = 0;
+
+ //
+ // Read target register
+ //
+ if (!HyperDbgReadTargetRegister(RegisterId, &TargetRegister))
+ {
+ return FALSE;
+ }
+
+ ShowMessages("%s=%016llx\n",
+ RegistersNames[RegisterId],
+ TargetRegister);
+
+ return TRUE;
+}
+
+/**
+ * @brief handler of r command
+ *
+ * @param CommandTokens
+ * @param Command
+ *
+ * @return VOID
+ */
+VOID
+CommandR(vector CommandTokens, string Command)
+{
+ REGS_ENUM RegKind;
+ std::vector Tmp;
+ std::string SetRegisterValue;
+
+ if (CommandTokens.size() == 1)
+ {
+ //
+ // show all registers
+ //
+ 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 or attach to a process\n");
+ }
+
+ return;
+ }
+
+ //
+ // clear additional space of the command string
+ //
+
+ //
+ // if command does not contain a '=' means user wants to read it
+ //
+ if (Command.find('=', 0) == string::npos)
+ {
+ //
+ // erase '=' from the string now we have just the name of register
+ //
+ Command.erase(0, 1);
+ ReplaceAll(Command, "@", "");
+ ReplaceAll(Command, " ", "");
+ if (RegistersMap.find(Command) != RegistersMap.end())
+ {
+ RegKind = RegistersMap[Command];
+ }
+ else
+ {
+ //
+ // set the Reg to -1(invalid register)
+ //
+ RegKind = (REGS_ENUM)-1;
+ }
+
+ if (RegKind != -1)
+ {
+ //
+ // send the request
+ //
+ 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 or attach to a process\n");
+ }
+ }
+ else
+ {
+ ShowMessages("err, invalid register\n");
+ }
+ }
+
+ //
+ // if command contains a '=' means user wants modify the register
+ //
+ else if (Command.find('=', 0) != string::npos)
+ {
+ Command.erase(0, 1);
+ Tmp = Split(Command, '=');
+ if (Tmp.size() == 2)
+ {
+ ReplaceAll(Tmp[0], " ", "");
+ string tmp = Tmp[0];
+ if (RegistersMap.find(Tmp[0]) != RegistersMap.end())
+ {
+ RegKind = RegistersMap[Tmp[0]];
+ }
+ else
+ {
+ ReplaceAll(tmp, "@", "");
+ if (RegistersMap.find(tmp) != RegistersMap.end())
+ {
+ RegKind = RegistersMap[tmp];
+ }
+ else
+ {
+ RegKind = (REGS_ENUM)-1;
+ }
+ }
+ if (RegKind != -1)
+ {
+ //
+ // send the request
+ //
+ SetRegisterValue = "@" + tmp + '=' + Tmp[1] + "; ";
+
+ //
+ // Send data to the target user debugger or kernel debugger
+ //
+ ScriptEngineExecuteSingleExpression((CHAR *)SetRegisterValue.c_str(), TRUE, FALSE);
+ }
+ else
+ {
+ //
+ // error
+ //
+ ShowMessages("err, invalid register\n");
+ }
+ }
+ }
+}
diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/rdmsr.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/rdmsr.cpp
similarity index 90%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/rdmsr.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/rdmsr.cpp
index 566a2537..b5f948f5 100644
--- a/hyperdbg/hprdbgctrl/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
*
@@ -106,12 +111,13 @@ GetWindowsNumaNumberOfCores()
/**
* @brief rdmsr command handler
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandRdmsr(vector SplitCommand, string Command)
+CommandRdmsr(vector CommandTokens, string Command)
{
BOOL Status;
SIZE_T NumCPU;
@@ -123,14 +129,15 @@ CommandRdmsr(vector SplitCommand, string Command)
UINT32 CoreNumer = DEBUGGER_READ_AND_WRITE_ON_MSR_APPLY_ALL_CORES;
BOOLEAN IsFirstCommand = TRUE;
- if (SplitCommand.size() >= 5)
+ if (CommandTokens.size() >= 5)
{
- ShowMessages("incorrect use of the 'rdmsr'\n\n");
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandRdmsrHelp();
return;
}
- for (auto Section : SplitCommand)
+ for (auto Section : CommandTokens)
{
if (IsFirstCommand == TRUE)
{
@@ -140,7 +147,7 @@ CommandRdmsr(vector SplitCommand, string Command)
if (IsNextCoreId)
{
- if (!ConvertStringToUInt32(Section, &CoreNumer))
+ if (!ConvertTokenToUInt32(Section, &CoreNumer))
{
ShowMessages("please specify a correct hex value for core id\n\n");
CommandRdmsrHelp();
@@ -150,13 +157,13 @@ CommandRdmsr(vector SplitCommand, string Command)
continue;
}
- if (!Section.compare("core"))
+ if (CompareLowerCaseStrings(Section, "core"))
{
IsNextCoreId = TRUE;
continue;
}
- if (SetMsr || !ConvertStringToUInt64(Section, &Msr))
+ if (SetMsr || !ConvertTokenToUInt64(Section, &Msr))
{
ShowMessages("please specify a correct hex value to be read\n\n");
CommandRdmsrHelp();
@@ -181,7 +188,7 @@ CommandRdmsr(vector SplitCommand, 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/hprdbgctrl/code/debugger/commands/debugging-commands/s.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/s.cpp
similarity index 81%
rename from hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/s.cpp
rename to hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/s.cpp
index 7024074b..9c3eff59 100644
--- a/hyperdbg/hprdbgctrl/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;
@@ -86,9 +88,9 @@ CommandSearchSendRequest(UINT64 * BufferToSendAsIoctl, UINT32 BufferToSendAsIoct
BufferToSendAsIoctlSize, // Input buffer length
ResultsBuffer, // Output Buffer from driver.
MaximumSearchResults *
- sizeof(UINT64), // Length of output buffer in bytes.
- NULL, // Bytes placed in buffer.
- NULL // synchronous call
+ sizeof(UINT64), // Length of output buffer in bytes.
+ &BytesReturned, // Bytes placed in buffer.
+ NULL // synchronous call
);
if (!Status)
@@ -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];
@@ -130,12 +132,13 @@ CommandSearchSendRequest(UINT64 * BufferToSendAsIoctl, UINT32 BufferToSendAsIoct
/**
* @brief !s* s* commands handler
*
- * @param SplitCommand
+ * @param CommandTokens
* @param Command
+ *
* @return VOID
*/
VOID
-CommandSearchMemory(vector SplitCommand, string Command)
+CommandSearchMemory(vector CommandTokens, string Command)
{
UINT64 Address;
vector ValuesToEdit;
@@ -152,9 +155,7 @@ CommandSearchMemory(vector SplitCommand, string Command)
UINT32 CountOfValues = 0;
UINT32 FinalSize = 0;
UINT64 * FinalBuffer = NULL;
- vector SplitCommandCaseSensitive {Split(Command, ' ')};
- UINT32 IndexInCommandCaseSensitive = 0;
- BOOLEAN IsFirstCommand = TRUE;
+ BOOLEAN IsFirstCommand = TRUE;
//
// By default if the user-debugger is active, we use these commands
@@ -165,45 +166,47 @@ CommandSearchMemory(vector SplitCommand, string Command)
ProcId = g_ActiveProcessDebuggingState.ProcessId;
}
- if (SplitCommand.size() <= 4)
+ if (CommandTokens.size() <= 4)
{
- ShowMessages("incorrect use of the 's*'\n\n");
+ ShowMessages("incorrect use of the '%s'\n\n",
+ GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
+
CommandSearchMemoryHelp();
return;
}
- for (auto Section : SplitCommand)
+ for (auto Section : CommandTokens)
{
- IndexInCommandCaseSensitive++;
-
if (IsFirstCommand == TRUE)
{
- if (!Section.compare("!sb"))
+ std::string FirstCommand = GetLowerStringFromCommandToken(Section);
+
+ if (!FirstCommand.compare("!sb"))
{
SearchMemoryRequest.MemoryType = SEARCH_PHYSICAL_MEMORY;
SearchMemoryRequest.ByteSize = SEARCH_BYTE;
}
- else if (!Section.compare("!sd"))
+ else if (!FirstCommand.compare("!sd"))
{
SearchMemoryRequest.MemoryType = SEARCH_PHYSICAL_MEMORY;
SearchMemoryRequest.ByteSize = SEARCH_DWORD;
}
- else if (!Section.compare("!sq"))
+ else if (!FirstCommand.compare("!sq"))
{
SearchMemoryRequest.MemoryType = SEARCH_PHYSICAL_MEMORY;
SearchMemoryRequest.ByteSize = SEARCH_QWORD;
}
- else if (!Section.compare("sb"))
+ else if (!FirstCommand.compare("sb"))
{
SearchMemoryRequest.MemoryType = SEARCH_VIRTUAL_MEMORY;
SearchMemoryRequest.ByteSize = SEARCH_BYTE;
}
- else if (!Section.compare("sd"))
+ else if (!FirstCommand.compare("sd"))
{
SearchMemoryRequest.MemoryType = SEARCH_VIRTUAL_MEMORY;
SearchMemoryRequest.ByteSize = SEARCH_DWORD;
}
- else if (!Section.compare("sq"))
+ else if (!FirstCommand.compare("sq"))
{
SearchMemoryRequest.MemoryType = SEARCH_VIRTUAL_MEMORY;
SearchMemoryRequest.ByteSize = SEARCH_QWORD;
@@ -213,7 +216,7 @@ CommandSearchMemory(vector SplitCommand, string Command)
//
// What's this? :(
//
- ShowMessages("unknown error happened !\n\n");
+ ShowMessages("unknown error happened!\n\n");
CommandSearchMemoryHelp();
return;
}
@@ -230,7 +233,7 @@ CommandSearchMemory(vector SplitCommand, string Command)
//
NextIsProcId = FALSE;
- if (!ConvertStringToUInt32(Section, &ProcId))
+ if (!ConvertTokenToUInt32(Section, &ProcId))
{
ShowMessages("please specify a correct hex process id\n\n");
CommandSearchMemoryHelp();
@@ -252,7 +255,7 @@ CommandSearchMemory(vector SplitCommand, string Command)
//
NextIsLength = FALSE;
- if (!ConvertStringToUInt64(Section, &Length))
+ if (!ConvertTokenToUInt64(Section, &Length))
{
ShowMessages("please specify a correct hex length\n\n");
CommandSearchMemoryHelp();
@@ -271,7 +274,7 @@ CommandSearchMemory(vector