Compare commits

...

72 commits

Author SHA1 Message Date
Sina Karvandi
bf974ffcc2 v0.21
Some checks failed
vs2026-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2026-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2026-ci / Deploy release (push) Has been cancelled
Merge pull request #634 from HyperDbg/dev
2026-07-05 15:41:02 +02:00
sina
a90513c71d update changelog for v0.21 release 2026-07-05 15:38:03 +02:00
Sina Karvandi
27838bf4e0
Merge pull request #633 from HyperDbg/pt
Pt
2026-07-05 15:25:35 +02:00
sina
9f113278ee add comment for run and trace
Some checks failed
vs2026-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2026-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2026-ci / Deploy release (push) Has been cancelled
2026-07-03 18:23:39 +02:00
sina
5739d0ee4c add PT thread helper 2026-07-03 17:26:01 +02:00
Sina Karvandi
ace4b331e7
Merge pull request #632 from HyperDbg/pt
Some checks failed
vs2026-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2026-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2026-ci / Deploy release (push) Has been cancelled
Pt
2026-07-02 22:00:48 +02:00
sina
ee01458bc4 Organized header files for the libhyperdbg project 2026-07-02 22:00:05 +02:00
sina
16aebb0c5d remove dependency on module details over global variables 2026-07-02 20:40:41 +02:00
sina
43cea334c2 add core and path interpretation of PT 2026-07-02 18:14:47 +02:00
Sina Karvandi
561ce0d559
Merge pull request #631 from HyperDbg/pt
Some checks are pending
vs2026-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2026-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2026-ci / Deploy release (push) Blocked by required conditions
Pt
2026-07-02 00:02:18 +02:00
sina
5bccbff58b fix IPT kernel structure based on the new model
Some checks are pending
vs2026-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2026-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2026-ci / Deploy release (push) Blocked by required conditions
2026-07-01 19:44:15 +02:00
sina
72a8aa325f add user mode PT parameter parser 2026-06-30 20:30:25 +02:00
sina
2b0cc18899 Fix concatenation error for hyperkd string on the hypertrace project
Some checks failed
vs2026-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2026-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2026-ci / Deploy release (push) Has been cancelled
2026-06-29 18:35:14 +02:00
sina
2b818a5116 fix load all command access denied error
Some checks are pending
vs2026-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2026-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2026-ci / Deploy release (push) Blocked by required conditions
2026-06-29 01:32:51 +02:00
sina
19e47c804f check if any module is loaded or not 2026-06-29 00:56:09 +02:00
sina
b537e36696 add hyperperf to version changer to fix CI CD and update changelog
Some checks failed
vs2026-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2026-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2026-ci / Deploy release (push) Has been cancelled
2026-06-24 18:48:56 +02:00
Sina Karvandi
e7cef36819
Merge pull request #629 from jtaw5649/fix/pool-manager-uninit-list-corruption
Fix pool manager uninit list corruption
2026-06-24 18:46:15 +02:00
jtaw5649
a0973894e8 fix: avoid pool list cursor use after free 2026-06-24 16:45:25 +01:00
sina
edf9f269d4 refactor Intel PT DPC broadcasting routines
Some checks are pending
vs2026-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2026-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2026-ci / Deploy release (push) Blocked by required conditions
2026-06-23 15:02:01 +02:00
sina
c17ebc09c4 add HyperPerf project structures
Some checks are pending
vs2026-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2026-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2026-ci / Deploy release (push) Blocked by required conditions
2026-06-22 16:19:49 +02:00
sina
7dfe5be985 change version to v0.21
Some checks are pending
vs2026-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2026-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2026-ci / Deploy release (push) Blocked by required conditions
2026-06-21 15:02:56 +02:00
Sina Karvandi
4e086328ee
v0.20-beta
Some checks failed
vs2026-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2026-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2026-ci / Deploy release (push) Has been cancelled
Merge pull request #628 from HyperDbg/dev
2026-06-21 14:31:43 +02:00
sina
aa18675760 update changelog and fix minor issues 2026-06-21 14:22:33 +02:00
Sina Karvandi
4bbb62d6fa
Merge pull request #627 from HyperDbg/linux
Linux guide and new progress
2026-06-21 13:23:43 +02:00
sina
5a0fad4901 add WDK and SDK NuGet packages and Fix CI/CD
Some checks are pending
vs2026-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2026-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2026-ci / Deploy release (push) Blocked by required conditions
2026-06-21 03:02:49 +02:00
maxraulea
3a8d8ab2d1 Add guidelines for contribution 2026-06-20 09:48:19 +02:00
maxraulea
83ae005c70 Added compatibility 2026-06-20 09:29:45 +02:00
maxraulea
81b16de62b added files for platform API 2026-06-20 09:28:37 +02:00
maxraulea
2d3941a43e signal handler platform independent API 2026-06-20 09:28:37 +02:00
sina
240feadc0c check for hyper-v as the top level hypervisor 2026-06-19 20:16:50 +02:00
Sina Karvandi
be59d1c9c2
Merge pull request #625 from Idov31/dev
Added VPID checking
2026-06-19 19:35:50 +02:00
Sina Karvandi
01106c82e0
Merge pull request #626 from HyperDbg/vs2026
Move to VS2026
2026-06-19 18:46:41 +02:00
sina
e94a86fcfb add vs2026 workflow and temporarily disabling CI CD 2026-06-19 18:45:50 +02:00
Sina Karvandi
63d509d422
Merge pull request #623 from HyperDbg/linux
Linux added new platform independent functions to the API
2026-06-19 18:22:19 +02:00
idov31
e56730ee25 Added check for whether hyper-v is the top level hypervisor 2026-06-17 20:45:32 +03:00
idov31
0f2a339e0b Added VPID check support 2026-06-17 20:34:09 +03:00
sina
70954f89b4 add v145 platform of zydis and pdbex 2026-06-15 22:55:40 +02:00
sina
622db82af5 remove old pdbex and zydis submodules 2026-06-15 22:24:36 +02:00
maxraulea
10576b064a Added typecast for wchar, mismatch on Linux and Windows 2026-06-15 16:21:12 +02:00
maxraulea
7586303ee8 revert w_char types 2026-06-15 15:57:57 +02:00
maxraulea
5e074a5cbd PE parsing compiles now 2026-06-15 15:52:50 +02:00
maxraulea
0b59876919 compiling dump.cpp and track.cpp 2026-06-15 15:18:56 +02:00
maxraulea
ced1ee94a4 Update platform-lib-calls.c 2026-06-15 14:47:42 +02:00
Sina Karvandi
b03a1f7ac2
Merge pull request #622 from HyperDbg/libipt
Some checks failed
vs2022-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2022-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2022-ci / Deploy release (push) Has been cancelled
Libipt
2026-06-15 00:06:38 +02:00
Sina Karvandi
47ee830867
Merge pull request #619 from maxraulea/gcc-libhyperdbg
Platform ioctl interface
2026-06-15 00:04:44 +02:00
sina
4db59dc013 fix changelog and pt app issues 2026-06-15 00:04:28 +02:00
Sina Karvandi
503988e3a7
Merge pull request #620 from masoudrahimi01/libipt
Fixed ioctl pt operation size bug
2026-06-14 19:16:21 +02:00
Masoud Rahimi Jafari
dabf132d31 Fixed ioctl pt operation size bug 2026-06-14 16:29:26 +02:00
maxraulea
54b5b5a42f Platform ioctl interface 2026-06-14 14:55:02 +02:00
Sina Karvandi
60ab87875c
Update CONTRIBUTING.md 2026-06-14 01:27:28 +02:00
sina
122a99a6fe commenting synthetic MSRs 2026-06-13 15:42:40 +02:00
sina
b11da036d1 fix name of example files 2026-06-13 15:22:34 +02:00
sina
e04ee4dcc3 add Intel PT libraries 2026-06-13 14:20:32 +02:00
sina
9ad48d30dc fix new form of loading and unloading in the example app
Some checks failed
vs2022-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2022-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2022-ci / Deploy release (push) Has been cancelled
2026-06-11 14:31:10 +02:00
sina
8803e6f495 remove unused DPC definitions
Some checks are pending
vs2022-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2022-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2022-ci / Deploy release (push) Blocked by required conditions
2026-06-11 00:13:25 +02:00
sina
df12e9fd79 Fix adding missing IOCTL for Intel PT 2026-06-10 23:56:36 +02:00
Sina Karvandi
ade6877a7d
Merge pull request #609 from masoudrahimi01/feat/intel-pt-integration
Feat/intel pt integration
2026-06-10 23:15:35 +02:00
Sina Karvandi
b38b43eef9
Merge branch 'dev' into feat/intel-pt-integration 2026-06-10 23:14:26 +02:00
maxraulea
f9b912d365 Fix Build files: Added new platform API filesa
Some checks are pending
vs2022-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2022-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2022-ci / Deploy release (push) Blocked by required conditions
2026-06-10 16:29:35 +02:00
maxraulea
6c97d86610 Hopefully fix build errors V2 2026-06-10 16:29:35 +02:00
maxraulea
6299161980 Hopefully fix build errors 2026-06-10 16:29:35 +02:00
maxraulea
31b514f8df Interface Linux for the serial port 2026-06-10 16:29:35 +02:00
maxraulea
853ae9d5fe added defs to linux environment 2026-06-10 16:29:35 +02:00
maxraulea
5a02c43cc1 New platform lib calls 2026-06-10 16:29:35 +02:00
maxraulea
c2c0030f1b Switching cores 2026-06-10 16:29:35 +02:00
maxraulea
e048f5b822 added call to platform api and new TODO 2026-06-10 16:29:35 +02:00
maxraulea
9c3e0ed23b added Linux distinction and pragmas together with new platform functions 2026-06-10 16:29:35 +02:00
maxraulea
0e39c24f28 updates to cmake file for linux 2026-06-10 16:29:35 +02:00
sina
25871f4e48 change version 2026-06-10 16:03:38 +02:00
Masoud Rahimi Jafari
81c8b88dc3 Added disassembler to hyperdbg app to show decoded intel pt buffers 2026-06-06 15:41:48 +02:00
Masoud Rahimi Jafari
2dc1a26f1c Added user app example for pt tracing 2026-06-04 01:55:42 +02:00
Masoud Rahimi Jafari
d6f56065d5 Changed intel pt files author email 2026-06-01 11:21:00 +02:00
166 changed files with 10406 additions and 1213 deletions

View file

@ -51,6 +51,25 @@ 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

View file

@ -1,26 +1,31 @@
name: vs2022-ci
on:
push:
branches:
- master
- dev
tags:
- 'v*'
paths-ignore:
- '.gitignore'
- '.gitattributes'
- '**.cmd'
- '**.bat'
- '**.md'
pull_request:
paths-ignore:
- '.gitignore'
- '.gitattributes'
- '**.cmd'
- '**.bat'
- '**.md'
workflow_dispatch:
# Disabled, uncomment the below line and remove the above lines to activate
# on:
# push:
# branches:
# - master
# - dev
# tags:
# - 'v*'
# paths-ignore:
# - '.gitignore'
# - '.gitattributes'
# - '**.cmd'
# - '**.bat'
# - '**.md'
#
# pull_request:
# paths-ignore:
# - '.gitignore'
# - '.gitattributes'
# - '**.cmd'
# - '**.bat'
# - '**.md'
env:
# WDK for Windows 11, version 22H2
WDK_URL: https://go.microsoft.com/fwlink/?linkid=2196230
@ -73,7 +78,7 @@ jobs:
# working-directory: ${{env.GITHUB_WORKSPACE}}
# run: msbuild /m /p:Configuration="Release MT" /p:Platform=${{matrix.PLATFORM}} /target:zydis /target:zycore /p:OutDir=${{ github.workspace }}/hyperdbg/libraries/zydis/ ${{ github.workspace }}/hyperdbg/dependencies/zydis/msvc/Zydis.sln
- name: Build Hyperdbg solution
- name: Build HyperDbg solution
working-directory: ${{env.GITHUB_WORKSPACE}}
run: msbuild /m /p:Configuration=${{matrix.BUILD_CONFIGURATION}} /p:Platform=${{matrix.PLATFORM}} ${{env.SOLUTION_FILE_PATH}}

99
.github/workflows/vs2026.yml vendored Normal file
View file

@ -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 }}

6
.gitmodules vendored
View file

@ -1,6 +1,3 @@
[submodule "hyperdbg/dependencies/pdbex"]
path = hyperdbg/dependencies/pdbex
url = https://github.com/HyperDbg/pdbex.git
[submodule "hyperdbg/tests/script-engine-test"]
path = hyperdbg/tests/script-engine-test
url = https://github.com/HyperDbg/script-engine-test.git
@ -10,6 +7,9 @@
[submodule "hyperdbg/dependencies/ia32-doc"]
path = hyperdbg/dependencies/ia32-doc
url = https://github.com/HyperDbg/ia32-doc.git
[submodule "hyperdbg/dependencies/pdbex"]
path = hyperdbg/dependencies/pdbex
url = https://github.com/HyperDbg/pdbex.git
[submodule "hyperdbg/dependencies/zydis"]
path = hyperdbg/dependencies/zydis
url = https://github.com/HyperDbg/zydis.git

View file

@ -4,6 +4,47 @@ 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.
@ -13,7 +54,7 @@ New release of the HyperDbg Debugger.
- 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/lbrdmp))
- 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

View file

@ -8,47 +8,13 @@ HyperDbg is a large-scale project that requires a lot of time and effort from th
Please make sure to create a [discussion](https://github.com/orgs/HyperDbg/discussions) or an [issue](https://github.com/HyperDbg/HyperDbg/issues), or even better, join the HyperDbg groups ([Telegram](https://t.me/HyperDbg), [Discord](https://discord.gg/anSPsGUtzN), [Matrix](https://matrix.to/#/#hyperdbg-discussion:matrix.org)) on social media. Discuss the way you want to implement your changes and inform developers, because we often see people simultaneously working on the same issue. To avoid this collision, make sure to inform us before you start developing.
### Working on an Idea or a Task
- We have a [wide range of ideas and tasks](https://github.com/orgs/HyperDbg/projects/2) that you might be interested in working on. You can choose a task and start working on it, and if you have any questions or need clarification, feel free to ask. This list will be updated frequently.
### Other Things to Work on
- Writing blog posts and creating videos about use-cases of HyperDbg (make sure to add it to the [awesome](https://github.com/HyperDbg/awesome) repository).
- Fixing unresolved GitHub [issues](https://github.com/HyperDbg/HyperDbg/issues).
- Troubleshooting problems with running on Hyper-V's nested virtualization.
- Troubleshooting problems with running on VirtualBox's nested virtualization.
- Supporting KDNET (sending data over the network).
- Enhancing HyperDbg's [Transparent Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#transparent-mode). These features should be added as an extension to the [HyperEvade](https://www.vusec.net/projects/hyperevade/) project (e.g., by bypassing [al-khaser](https://github.com/LordNoteworthy/al-khaser) and similar anti-debugging and anti-hypervisor projects).
- Adding HyperDbg to the system startup using UEFI.
- Creating a QT-based GUI.
- Creating a SoftICE-style GUI.
- Supporting nested-virtualization on HyperDbg itself.
- Protecting HyperDbg code and memory from modification using VT-x capabilities.
- Adding support for the Intel Processor Trace (PT) and event command for detecting coverage | (In progress).
- Creating a wrapper that automatically interprets the [HyperDbg SDK](https://github.com/HyperDbg/HyperDbg/tree/master/hyperdbg/include/SDK) to GO, RUST, C#, Python, etc.
- Creating syntax highlighting for dslang for different IDEs (VSCode, VIM, etc.).
- Building HyperDbg using LLVM clang.
- Helping us start supporting HyperDbg on Linux (discussion needed) | (In progress).
- Helping us start supporting HyperDbg on AMD processors (discussion needed).
- Adding digital (FPGA) modules to the hwdbg hardware debugger.
- Creating a [ret-sync](https://github.com/bootleg/ret-sync) module for HyperDbg.
- Adding fuzzing capabilities to HyperDbg (maybe integrating [AFL++](https://github.com/AFLplusplus/AFLplusplus) into HyperDbg).
- Working on live memory migration and adding support for kernel-mode time travel debugging.
- Integrating the [z3 project](https://github.com/Z3Prover/z3) into HyperDbg and adding commands based on the z3 solver.
- Adding the [Bochs emulator](https://github.com/bochs-emu/Bochs) to HyperDbg.
- Creating different examples of how to use the SDK (using different programming languages).
- Debugging and fixing bugs related to HyperDbg's physical serial communication.
- Reading symbol information from modules in memory (currently, HyperDbg opens a file which continues the debugger).
- Adding APIC virtualization.
- Reading the list of modules for the '[lm](https://docs.hyperdbg.org/commands/debugging-commands/lm)' command directly from kernel-mode.
- Detecting and fixing anti-hypervisor methods described [here](https://github.com/Ahora57/MAJESTY-technologies).
- Investigating why the symbols parser (DIA SDK) could not read symbols of the 'kernel32!*'.
- Creating the 'alias' command that converts or registers scripts as a command, for example: "alias !list .script list.dbg" (discussion needed).
- Adding support for [Hardware Performance Counters (HPC)](https://en.wikipedia.org/wiki/Hardware_performance_counter).
- Any other interesting tasks you might find!
- ~~Enhancing and adding more features to the ['.pe'](https://docs.hyperdbg.org/commands/meta-commands/.pe) command.~~ Added: [<a href="https://docs.hyperdbg.org/commands/meta-commands/.pe" target="_blank">link</a>][<a href="https://github.com/HyperDbg/HyperDbg/pull/598" target="_blank">link</a>]
- ~~Adding routines to activate and use Last Branch Record (LBR) and Branch Trace Store (BTS).~~ Added: [<a href="https://docs.hyperdbg.org/commands/extension-commands/lbr" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/extension-commands/lbrdump" target="_blank">link</a>]
- ~~Creating commands to inspect and read details of PCIe devices.~~ Added: [<a href="https://docs.hyperdbg.org/commands/extension-commands/pcitree" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/extension-commands/pcicam" target="_blank">link</a>]
- ~~Mitigating the anti-hypervisor method described [here](https://howtohypervise.blogspot.com/2019/01/a-common-missight-in-most-hypervisors.html).~~ [[Fixed](https://github.com/HyperDbg/HyperDbg/pull/497)]
- ~~Fixing the problem with [XSETBV instruction freezing](https://github.com/HyperDbg/HyperDbg/issues/429).~~ [[Fixed](https://github.com/HyperDbg/HyperDbg/pull/491)]
This list will be updated frequently.
- Any other interesting ideas you might find! (Let's have a discussion before working on them.)
## Fixing Bugs

View file

@ -34,7 +34,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
//
// DO NOT CHANGE CALLING OF THE FOLLOWING FUNCTION
//
PoolManagerCheckAndPerformAllocationAndDeallocation();
// PoolManagerCheckAndPerformAllocationAndDeallocation();
if (g_VmmInitialized)
{

View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props" Condition="Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" />
<Import Project="..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props" Condition="Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" />
<Import Project="..\..\..\hyperdbg\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props" Condition="Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="debug|x64">
<Configuration>debug</Configuration>
@ -110,7 +113,20 @@
<ClCompile Include="code\driver\Ioctl.c" />
<ClCompile Include="code\driver\Loader.c" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets" Condition="Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\hyperdbg\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props'))" />
<Error Condition="!Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props'))" />
<Error Condition="!Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets'))" />
<Error Condition="!Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props'))" />
</Target>
</Project>

View file

@ -56,4 +56,7 @@
<Filter>code\driver</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.SDK.CPP" version="10.0.28000.1839" targetFramework="native" />
<package id="Microsoft.Windows.SDK.CPP.x64" version="10.0.28000.1839" targetFramework="native" />
<package id="Microsoft.Windows.WDK.x64" version="10.0.28000.1839" targetFramework="native" />
</packages>

View file

@ -1,175 +1,58 @@
/**
* @file hyperdbg-app.cpp
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Controller of the reversing machine's module
* @details
*
* @version 0.2
* @date 2023-02-01
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#include "pch.h"
PVOID g_SharedMessageBuffer = NULL;
/**
* @brief Show messages
*
* @param Text
* @return int
*/
int
hyperdbg_show_messages(const char* Text)
static int
ShowMessages(const char * Text)
{
printf("%s", Text);
return 0;
}
/**
* @brief Show messages (shared buffer)
*
* @param Text
* @return int
*/
int
hyperdbg_show_messages_shared_buffer()
static int
LoadVmm()
{
printf("%s", (char*)g_SharedMessageBuffer);
return 0;
hyperdbg_u_set_text_message_callback((PVOID)ShowMessages);
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;
}
/**
* @brief Load the driver
*
* @return int return zero if it was successful or non-zero if there
* was error
*/
int
hyperdbg_load_debugger_mode()
main(int argc, char ** argv)
{
char CpuId[13] = { 0 };
return main2(argc, argv);
//
// Read the vendor string
//
hyperdbg_u_read_vendor_string(CpuId);
if (LoadVmm() != 0)
{
return 1;
}
printf("current processor vendor is : %s\n", CpuId);
hyperdbg_u_run_command((CHAR*)"lm");
if (strcmp(CpuId, "GenuineIntel") == 0)
{
printf("virtualization technology is vt-x\n");
}
else
{
printf("this program is not designed to run in a non-VT-x "
"environment !\n");
return 1;
}
printf("[*] unloading HyperDbg VMM...\n");
//
// Detect if the processor supports vmx operation
//
if (hyperdbg_u_detect_vmx_support())
{
printf("vmx operation is supported by your processor\n");
}
else
{
#ifdef HYPERDBG_ENV_WINDOWS
printf("vmx operation is not supported by your processor "
"(if you are using an Intel processor, it might be because VBS is not disabled!)\n");
#endif
return 1;
}
//
// Unload the driver
//
hyperdbg_u_unload_vmm();
hyperdbg_u_unload_kd();
hyperdbg_u_stop_kd_driver();
hyperdbg_u_uninstall_kd_driver();
//
// Set callback function for showing messages
//
hyperdbg_u_set_text_message_callback(hyperdbg_show_messages);
printf("[+] done\n");
//
// Test interpreter
//
hyperdbg_u_connect_remote_debugger_using_named_pipe("\\\\.\\pipe\\HyperDbgPipe", TRUE);
Sleep(10000);
hyperdbg_u_run_command((CHAR*)"r");
hyperdbg_u_run_command((CHAR*)".start path c:\\Windows\\system32\\calc.exe");
hyperdbg_u_continue_debuggee();
hyperdbg_u_continue_debuggee();
hyperdbg_u_continue_debuggee();
hyperdbg_u_continue_debuggee();
hyperdbg_u_continue_debuggee();
hyperdbg_u_continue_debuggee();
hyperdbg_u_continue_debuggee();
return 0;
}
/**
* @brief Load the driver
*
* @return int return zero if it was successful or non-zero if there
* was error
*/
int
hyperdbg_load_vmi_mode()
{
//
// Set callback function for showing messages
//
hyperdbg_u_set_text_message_callback(hyperdbg_show_messages);
//
// Test interpreter
//
if (hyperdbg_u_install_kd_driver() == 1 || hyperdbg_u_load_vmm() == 1)
{
printf("failed to install or load the driver\n");
return 1;
}
return 0;
}
/**
* @brief main function
*
* @return int
*/
int
main()
{
//
// Load the driver in the vmi mode
//
if (hyperdbg_load_vmi_mode() == 0)
{
//
// *** HyperDbg driver loaded successfully ***
//
//
// Run a test command
//
hyperdbg_u_run_command((CHAR*)"lm");
//
// Unload the driver
//
hyperdbg_u_unload_vmm();
hyperdbg_u_unload_kd();
hyperdbg_u_stop_kd_driver();
hyperdbg_u_uninstall_kd_driver();
}
else
{
printf("err, in loading HyperDbg\n");
}
return 0;
}

View file

@ -0,0 +1,583 @@
#include "pch.h"
#include <string.h>
#include <stdlib.h>
#include <dbghelp.h>
#include "../dependencies/libipt/intel-pt.h"
#include <Zydis/Zydis.h>
#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 <path-to-exe-that-exits> [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;
}

View file

@ -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);

View file

@ -38,3 +38,8 @@
//
#include "SDK/HyperDbgSdk.h"
#include "SDK/imports/user/HyperDbgLibImports.h"
//
// Other internal headers
//
#include "example-ipt.h"

View file

@ -11,9 +11,11 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="header\example-ipt.h" />
<ClInclude Include="header\pch.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="code\hyperdbg-ipt.cpp" />
<ClCompile Include="code\hyperdbg-app.cpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
@ -28,13 +30,13 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>v145</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>v145</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
@ -49,33 +51,49 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Label="UserMacros">
<!--
libipt (Intel Processor Trace decoder) install root.
Set this to the folder that contains 'include\intel-pt.h' and
'lib\libipt.lib'. 'libipt.dll' must be reachable at run time.
-->
<LibIptDir>C:\Users\masra\Desktop\libipt</LibIptDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
<OutDir>$(SolutionDir)build\bin\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
<OutDir>$(SolutionDir)build\bin\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<PostBuildEventUseInBuild>true</PostBuildEventUseInBuild>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;ZYCORE_STATIC_BUILD;ZYDIS_STATIC_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>Create</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(ProjectDir)header;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(LibIptDir)\include;$(SolutionDir)include;$(SolutionDir)dependencies\zydis\include;$(SolutionDir)dependencies\zydis\dependencies\zycore\include;$(ProjectDir)header;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>$(SolutionDir)build\bin\$(Configuration)\libhyperdbg.lib</AdditionalDependencies>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<AdditionalLibraryDirectories>$(LibIptDir)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(SolutionDir)build\bin\$(Configuration)\libhyperdbg.lib;$(SolutionDir)libraries\zydis\user\Zydis.lib;$(SolutionDir)libraries\zydis\user\Zycore.lib;$(SolutionDir)libraries\libipt\libipt.lib</AdditionalDependencies>
<TreatLinkerWarningAsErrors>false</TreatLinkerWarningAsErrors>
</Link>
<PostBuildEvent>
<Command>
</Command>
<Message>
</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
<ClCompile>
@ -83,12 +101,12 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;ZYCORE_STATIC_BUILD;ZYDIS_STATIC_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>Create</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(ProjectDir)header;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(LibIptDir)\include;$(SolutionDir)include;$(SolutionDir)dependencies\zydis\include;$(SolutionDir)dependencies\zydis\dependencies\zycore\include;$(ProjectDir)header;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<Optimization>MaxSpeed</Optimization>
</ClCompile>
@ -97,9 +115,16 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>$(SolutionDir)build\bin\$(Configuration)\libhyperdbg.lib</AdditionalDependencies>
<AdditionalLibraryDirectories>$(LibIptDir)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(SolutionDir)build\bin\$(Configuration)\libhyperdbg.lib;$(SolutionDir)libraries\zydis\user\Zydis.lib;$(SolutionDir)libraries\zydis\user\Zycore.lib;$(SolutionDir)libraries\libipt\libipt.lib</AdditionalDependencies>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
</Link>
<PostBuildEvent>
<Command>
</Command>
<Message>
</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View file

@ -15,8 +15,14 @@
<ClInclude Include="header\pch.h">
<Filter>header</Filter>
</ClInclude>
<ClInclude Include="header\example-ipt.h">
<Filter>header</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="code\hyperdbg-ipt.cpp">
<Filter>code</Filter>
</ClCompile>
<ClCompile Include="code\hyperdbg-app.cpp">
<Filter>code</Filter>
</ClCompile>

View file

@ -7,7 +7,6 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
if(LINUX)
add_subdirectory(script-engine)
message(STATUS "Building on Linux")
elseif(WIN32)
message(STATUS "Building on Windows")
@ -53,36 +52,30 @@ target_link_libraries(hyperhv Zycore Zydis)
add_subdirectory(hyperkd)
target_link_libraries(hyperkd hyperlog hyperhv kdserial)
endif()
add_subdirectory(dependencies/pdbex/Source)
#add_subdirectory(dependencies/pdbex/Source)
add_subdirectory(symbol-parser)
target_link_libraries(symbol-parser pdbex)
#add_subdirectory(symbol-parser)
#target_link_libraries(symbol-parser pdbex)
#target_link_libraries(script-engine symbol-parser)
target_link_libraries(script-engine symbol-parser)
link_directories(libraries/zydis/user libraries/keystone/release-lib)
add_subdirectory(libhyperdbg)
target_link_libraries(libhyperdbg Zycore Zydis script-engine keystone)
add_subdirectory(hyperdbg-test)
#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(symbol-parser)
#target_link_libraries(symbol-parser pdbex)
#add_subdirectory(script-engine)
#target_link_libraries(script-engine symbol-parser)
add_subdirectory(script-engine)
target_link_libraries(script-engine symbol-parser)
link_directories(libraries/zydis/user libraries/keystone/release-lib)
add_subdirectory(libhyperdbg)
target_link_libraries(libhyperdbg Zycore Zydis script-engine keystone)
endif()
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)

File diff suppressed because it is too large Load diff

@ -1 +1 @@
Subproject commit 42a9fbb821c7d140c5e00da60f5a5887c2fd8444
Subproject commit 0e1144729a5b2d737cce11d1c0e083033630fff8

@ -1 +1 @@
Subproject commit e61f59332ce49f8853006573ca853e404fafdd08
Subproject commit e910df2fa54273b1a489b39771d331036e8de2db

View file

@ -22,14 +22,14 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>v145</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>false</SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>v145</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>false</SpectreMitigation>
@ -82,15 +82,21 @@
<PostBuildEvent>
<Command>if exist "$(OutDir)SDK\" rd /q /s "$(OutDir)SDK\"
xcopy /E /I /Y "$(SolutionDir)include\SDK" "$(OutDir)SDK"
xcopy /E /I /Y "$(SolutionDir)..\examples" "$(OutDir)SDK\Examples"
mkdir "$(OutDir)SDK\Libraries"
copy "$(OutDir)pdbex.lib" "$(OutDir)SDK\Libraries\pdbex.lib"
copy "$(OutDir)kdserial.lib" "$(OutDir)SDK\Libraries\kdserial.lib"
copy "$(OutDir)libhyperdbg.dll" "$(OutDir)SDK\Libraries\libhyperdbg.dll"
copy "$(OutDir)script-engine.dll" "$(OutDir)SDK\Libraries\script-engine.dll"
copy "$(OutDir)symbol-parser.dll" "$(OutDir)SDK\Libraries\symbol-parser.dll"
copy "$(OutDir)hyperlog.dll" "$(OutDir)SDK\Libraries\hyperlog.dll"
copy "$(OutDir)hyperhv.dll" "$(OutDir)SDK\Libraries\hyperhv.dll"
xcopy /E /I /Y "$(SolutionDir)..\examples" "$(OutDir)SDK\examples"
mkdir "$(OutDir)SDK\libraries"
mkdir "$(OutDir)SDK\libraries\kernel"
mkdir "$(OutDir)SDK\libraries\user"
copy "$(OutDir)pdbex.dll" "$(OutDir)SDK\libraries\user\pdbex.dll"
copy "$(OutDir)libipt.dll" "$(OutDir)SDK\libraries\user\libipt.dll"
copy "$(OutDir)script-engine.dll" "$(OutDir)SDK\libraries\user\script-engine.dll"
copy "$(OutDir)symbol-parser.dll" "$(OutDir)SDK\libraries\user\symbol-parser.dll"
copy "$(OutDir)libhyperdbg.dll" "$(OutDir)SDK\libraries\user\libhyperdbg.dll"
copy "$(OutDir)hyperlog.dll" "$(OutDir)SDK\libraries\kernel\hyperlog.dll"
copy "$(OutDir)hyperhv.dll" "$(OutDir)SDK\libraries\kernel\hyperhv.dll"
copy "$(OutDir)hypertrace.dll" "$(OutDir)SDK\libraries\kernel\hyperevade.dll"
copy "$(OutDir)hypertrace.dll" "$(OutDir)SDK\libraries\kernel\hypertrace.dll"
copy "$(OutDir)hyperperf.dll" "$(OutDir)SDK\libraries\kernel\hyperperf.dll"
copy "$(OutDir)kdserial.dll" "$(OutDir)SDK\libraries\kernel\kdserial.dll"
if exist "$(OutDir)constants\" rd /q /s "$(OutDir)constants\"
mkdir "$(OutDir)constants"
copy "$(SolutionDir)miscellaneous\constants\pciid\pci.ids" "$(OutDir)constants\pci.ids"</Command>
@ -126,15 +132,21 @@ copy "$(SolutionDir)miscellaneous\constants\pciid\pci.ids" "$(OutDir)constants\p
<PostBuildEvent>
<Command>if exist "$(OutDir)SDK\" rd /q /s "$(OutDir)SDK\"
xcopy /E /I /Y "$(SolutionDir)include\SDK" "$(OutDir)SDK"
xcopy /E /I /Y "$(SolutionDir)..\examples" "$(OutDir)SDK\Examples"
mkdir "$(OutDir)SDK\Libraries"
copy "$(OutDir)pdbex.lib" "$(OutDir)SDK\Libraries\pdbex.lib"
copy "$(OutDir)kdserial.lib" "$(OutDir)SDK\Libraries\kdserial.lib"
copy "$(OutDir)libhyperdbg.dll" "$(OutDir)SDK\Libraries\libhyperdbg.dll"
copy "$(OutDir)script-engine.dll" "$(OutDir)SDK\Libraries\script-engine.dll"
copy "$(OutDir)symbol-parser.dll" "$(OutDir)SDK\Libraries\symbol-parser.dll"
copy "$(OutDir)hyperlog.dll" "$(OutDir)SDK\Libraries\hyperlog.dll"
copy "$(OutDir)hyperhv.dll" "$(OutDir)SDK\Libraries\hyperhv.dll"
xcopy /E /I /Y "$(SolutionDir)..\examples" "$(OutDir)SDK\examples"
mkdir "$(OutDir)SDK\libraries"
mkdir "$(OutDir)SDK\libraries\kernel"
mkdir "$(OutDir)SDK\libraries\user"
copy "$(OutDir)pdbex.dll" "$(OutDir)SDK\libraries\user\pdbex.dll"
copy "$(OutDir)libipt.dll" "$(OutDir)SDK\libraries\user\libipt.dll"
copy "$(OutDir)script-engine.dll" "$(OutDir)SDK\libraries\user\script-engine.dll"
copy "$(OutDir)symbol-parser.dll" "$(OutDir)SDK\libraries\user\symbol-parser.dll"
copy "$(OutDir)libhyperdbg.dll" "$(OutDir)SDK\libraries\user\libhyperdbg.dll"
copy "$(OutDir)hyperlog.dll" "$(OutDir)SDK\libraries\kernel\hyperlog.dll"
copy "$(OutDir)hyperhv.dll" "$(OutDir)SDK\libraries\kernel\hyperhv.dll"
copy "$(OutDir)hypertrace.dll" "$(OutDir)SDK\libraries\kernel\hyperevade.dll"
copy "$(OutDir)hypertrace.dll" "$(OutDir)SDK\libraries\kernel\hypertrace.dll"
copy "$(OutDir)hyperperf.dll" "$(OutDir)SDK\libraries\kernel\hyperperf.dll"
copy "$(OutDir)kdserial.dll" "$(OutDir)SDK\libraries\kernel\kdserial.dll"
if exist "$(OutDir)constants\" rd /q /s "$(OutDir)constants\"
mkdir "$(OutDir)constants"
copy "$(SolutionDir)miscellaneous\constants\pciid\pci.ids" "$(OutDir)constants\pci.ids"</Command>

View file

@ -21,14 +21,14 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>v145</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>false</SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>v145</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>false</SpectreMitigation>
@ -134,4 +134,4 @@
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
<Import Project="$(VCTargetsPath)\BuildCustomizations\marmasm.targets" />
</ImportGroup>
</Project>
</Project>

View file

@ -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
@ -90,6 +90,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "imports", "imports", "{B3D9
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperkd", "hyperkd\hyperkd.vcxproj", "{AFDD7028-1ED9-442E-8A3D-01CFA3AA1CAA}"
ProjectSection(ProjectDependencies) = postProject
{360E54B1-0B92-4BCA-8111-4BF384292621} = {360E54B1-0B92-4BCA-8111-4BF384292621}
{9FA45E25-DAEB-4C2D-806C-7908A180195D} = {9FA45E25-DAEB-4C2D-806C-7908A180195D}
{AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D} = {AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D}
{BB17323A-2460-4AE1-8AFE-B367400B934F} = {BB17323A-2460-4AE1-8AFE-B367400B934F}
@ -101,6 +102,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{13E4
ProjectSection(SolutionItems) = preProject
include\SDK\modules\HyperEvade.h = include\SDK\modules\HyperEvade.h
include\SDK\Modules\HyperLog.h = include\SDK\Modules\HyperLog.h
include\SDK\modules\HyperPerf.h = include\SDK\modules\HyperPerf.h
include\SDK\modules\HyperTrace.h = include\SDK\modules\HyperTrace.h
include\SDK\Modules\VMM.h = include\SDK\Modules\VMM.h
EndProjectSection
@ -207,6 +209,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "kernel", "kernel", "{947577
include\SDK\imports\kernel\HyperDbgHyperEvade.h = include\SDK\imports\kernel\HyperDbgHyperEvade.h
include\SDK\Imports\Kernel\HyperDbgHyperLogImports.h = include\SDK\Imports\Kernel\HyperDbgHyperLogImports.h
include\SDK\Imports\Kernel\HyperDbgHyperLogIntrinsics.h = include\SDK\Imports\Kernel\HyperDbgHyperLogIntrinsics.h
include\SDK\imports\kernel\HyperDbgHyperPerf.h = include\SDK\imports\kernel\HyperDbgHyperPerf.h
include\SDK\imports\kernel\HyperDbgHyperTrace.h = include\SDK\imports\kernel\HyperDbgHyperTrace.h
include\SDK\Imports\Kernel\HyperDbgVmmImports.h = include\SDK\Imports\Kernel\HyperDbgVmmImports.h
EndProjectSection
@ -327,6 +330,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "header", "header", "{CA2D9C
include\components\pe\header\pe-image-reader.h = include\components\pe\header\pe-image-reader.h
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperperf", "hyperperf\hyperperf.vcxproj", "{360E54B1-0B92-4BCA-8111-4BF384292621}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
debug|x64 = debug|x64
@ -384,6 +389,10 @@ Global
{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

View file

@ -362,7 +362,7 @@ static const PWCH HV_FILES[] = {
// HyperDbg Files
//
L"hyperhv",
L"hyperkd"
L"hyperkd",
L"hyperlog",
L"libhyperdbg",

View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" />
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" />
<Import Project="..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props" Condition="Exists('..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="debug|x64">
<Configuration>debug</Configuration>
@ -27,7 +30,7 @@
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'" Label="Configuration">
@ -36,7 +39,7 @@
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@ -122,7 +125,20 @@
<ClInclude Include="header\pch.h" />
<ClInclude Include="header\VmxFootprints.h" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props'))" />
</Target>
</Project>

View file

@ -99,4 +99,7 @@
<Filter>header\components\callback</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.SDK.CPP" version="10.0.28000.1839" targetFramework="native" />
<package id="Microsoft.Windows.SDK.CPP.x64" version="10.0.28000.1839" targetFramework="native" />
<package id="Microsoft.Windows.WDK.x64" version="10.0.28000.1839" targetFramework="native" />
</packages>

View file

@ -23,7 +23,7 @@ EptCheckFeatures(VOID)
{
IA32_VMX_EPT_VPID_CAP_REGISTER VpidRegister;
IA32_MTRR_DEF_TYPE_REGISTER MTRRDefType;
g_IsVpidSupported = FALSE;
VpidRegister.AsUInt = CpuReadMsr(IA32_VMX_EPT_VPID_CAP);
MTRRDefType.AsUInt = CpuReadMsr(IA32_MTRR_DEF_TYPE);
@ -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;

View file

@ -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;

View file

@ -96,9 +96,11 @@ MsrHandleRdmsrVmexit(VIRTUAL_MACHINE_STATE * VCpu)
// LogInfo("MSR read (RDMSR) VM-exit, MSR: %x, from: %llx",
// TargetMsr,
// VCpu->LastVmexitRip);
//
// Checking whether it is a synthetic MSR for Hyper-V.
if (MsrHandleIsHypervSyntheticMsr(TargetMsr))
// Checking whether it is a synthetic MSR for Hyper-V
//
if (g_IsTopLevelHypervisorHyperV && MsrHandleIsHypervSyntheticMsr(TargetMsr))
{
Msr.Flags = CpuReadMsr(TargetMsr);
@ -257,9 +259,11 @@ MsrHandleWrmsrVmexit(VIRTUAL_MACHINE_STATE * VCpu)
// GuestRegs->rax,
// GuestRegs->rdx,
// VCpu->LastVmexitRip);
//
// Checking whether it is a synthetic MSR for Hyper-V.
if (MsrHandleIsHypervSyntheticMsr(TargetMsr))
// Checking whether it is a synthetic MSR for Hyper-V
//
if (g_IsTopLevelHypervisorHyperV && MsrHandleIsHypervSyntheticMsr(TargetMsr))
{
CpuWriteMsr(TargetMsr, Msr.Flags);
return;

View file

@ -274,6 +274,23 @@ VmxPerformVirtualizationOnAllCores()
return FALSE;
}
//
// Check if the top level hypervisor is Hyper-V or not
//
if (VmxIsTopLevelHypervisorHyperV())
{
//
// The top-level hypervisor is hyper-v
//
g_IsTopLevelHypervisorHyperV = TRUE;
LogDebugInfo(" Hyper-V is detected as the top-level hypervisor");
}
else
{
LogDebugInfo(" Hyper-V is not detected as the top-level hypervisor");
}
//
// Allocate global variable to hold Ept State
//
@ -733,15 +750,17 @@ VmxSetupVmcs(VIRTUAL_MACHINE_STATE * VCpu, PVOID GuestStack)
LogDebugInfo("CPU Based VM Exec Controls (Based on %s) : 0x%x",
VmxBasicMsr.VmxControls ? "IA32_VMX_TRUE_PROCBASED_CTLS" : "IA32_VMX_PROCBASED_CTLS",
CpuBasedVmExecControls);
UINT32 SecondaryProcBasedVmExecControlsFlags = IA32_VMX_PROCBASED_CTLS2_ENABLE_RDTSCP_FLAG |
IA32_VMX_PROCBASED_CTLS2_ENABLE_EPT_FLAG |
IA32_VMX_PROCBASED_CTLS2_ENABLE_INVPCID_FLAG |
IA32_VMX_PROCBASED_CTLS2_ENABLE_XSAVES_FLAG |
IA32_VMX_PROCBASED_CTLS2_ENABLE_USER_WAIT_PAUSE_FLAG;
SecondaryProcBasedVmExecControls = HvAdjustControls(
IA32_VMX_PROCBASED_CTLS2_ENABLE_RDTSCP_FLAG |
IA32_VMX_PROCBASED_CTLS2_ENABLE_EPT_FLAG |
IA32_VMX_PROCBASED_CTLS2_ENABLE_INVPCID_FLAG |
IA32_VMX_PROCBASED_CTLS2_ENABLE_XSAVES_FLAG |
IA32_VMX_PROCBASED_CTLS2_ENABLE_VPID_FLAG |
IA32_VMX_PROCBASED_CTLS2_ENABLE_USER_WAIT_PAUSE_FLAG,
IA32_VMX_PROCBASED_CTLS2);
if (g_IsVpidSupported)
{
SecondaryProcBasedVmExecControlsFlags |= IA32_VMX_PROCBASED_CTLS2_ENABLE_VPID_FLAG;
}
SecondaryProcBasedVmExecControls = HvAdjustControls(SecondaryProcBasedVmExecControlsFlags, IA32_VMX_PROCBASED_CTLS2);
VmxVmwrite64(VMCS_CTRL_SECONDARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, SecondaryProcBasedVmExecControls);
@ -1755,3 +1774,28 @@ VmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, SIZE_T Count)
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;
}

View file

@ -208,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;

View file

@ -205,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 //
//////////////////////////////////////////////////
@ -229,6 +235,9 @@ typedef enum _MOV_TO_DEBUG_REG
// Functions //
//////////////////////////////////////////////////
BOOLEAN
VmxIsTopLevelHypervisorHyperV();
BOOLEAN
VmxCheckVmxSupport();

View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" />
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" />
<Import Project="..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props" Condition="Exists('..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="debug|x64">
<Configuration>debug</Configuration>
@ -28,7 +31,7 @@
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<SpectreMitigation>false</SpectreMitigation>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
@ -38,7 +41,7 @@
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<SpectreMitigation>false</SpectreMitigation>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
@ -53,13 +56,16 @@
<PropertyGroup />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
<Inf2CatUseLocalTime>
</Inf2CatUseLocalTime>
<OutDir>$(SolutionDir)build\bin\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<EnableInf2cat>false</EnableInf2cat>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
<Inf2CatUseLocalTime>
</Inf2CatUseLocalTime>
<OutDir>$(SolutionDir)build\bin\$(Configuration)\</OutDir>
<EnableInf2cat>false</EnableInf2cat>
<IntDir>$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
@ -296,8 +302,21 @@
<ClInclude Include="header\vmm\vmx\VmxRegions.h" />
<ClInclude Include="pch.h" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props'))" />
</Target>
</Project>

View file

@ -649,4 +649,7 @@
<Filter>code\assembly</Filter>
</MASM>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.SDK.CPP" version="10.0.28000.1839" targetFramework="native" />
<package id="Microsoft.Windows.SDK.CPP.x64" version="10.0.28000.1839" targetFramework="native" />
<package id="Microsoft.Windows.WDK.x64" version="10.0.28000.1839" targetFramework="native" />
</packages>

View file

@ -92,7 +92,7 @@ PoolManagerInitialize()
VOID
PoolManagerUninitialize()
{
PLIST_ENTRY ListTemp = &g_ListOfAllocatedPoolsHead;
PLIST_ENTRY Link;
//
// Pool manager is not initialized anymore
@ -101,14 +101,16 @@ PoolManagerUninitialize()
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)
@ -121,14 +123,20 @@ PoolManagerUninitialize()
//
// Unlink the PoolTable
//
RemoveEntryList(&PoolTable->PoolsList);
RemoveEntryList(Link);
//
// Free the record itself
//
PlatformMemFreePool(PoolTable);
Link = Next;
}
InitializeListHead(&g_ListOfAllocatedPoolsHead);
g_IsNewRequestForDeAllocation = FALSE;
g_IsNewRequestForAllocationReceived = FALSE;
SpinlockUnlock(&LockForReadingPool);
PlmgrFreeRequestNewAllocation();
@ -311,8 +319,7 @@ PoolManagerAllocateAndAddToPoolTable(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_
BOOLEAN
PoolManagerCheckAndPerformAllocationAndDeallocation()
{
BOOLEAN Result = TRUE;
PLIST_ENTRY ListTemp = 0;
BOOLEAN Result = TRUE;
//
// Make sure we're on vmx non-root and also we have new allocation
@ -364,16 +371,16 @@ PoolManagerCheckAndPerformAllocationAndDeallocation()
//
if (g_IsNewRequestForDeAllocation)
{
ListTemp = &g_ListOfAllocatedPoolsHead;
PLIST_ENTRY Link = g_ListOfAllocatedPoolsHead.Flink;
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
@ -394,13 +401,15 @@ PoolManagerCheckAndPerformAllocationAndDeallocation()
//
// Now we should remove the entry from the g_ListOfAllocatedPoolsHead
//
RemoveEntryList(&PoolTable->PoolsList);
RemoveEntryList(Link);
//
// Free the structure pool
//
PlatformMemFreePool(PoolTable);
}
Link = Next;
}
}

View file

@ -134,6 +134,74 @@ IoctlCheckIoctlAllowed(ULONG Ioctl)
}
}
/**
* @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)
*
@ -1500,6 +1568,7 @@ DrvDispatchHyperTraceIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN *
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;
@ -1593,6 +1662,23 @@ DrvDispatchHyperTraceIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN *
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
//
@ -1605,6 +1691,34 @@ DrvDispatchHyperTraceIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN *
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;

View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" />
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" />
<Import Project="..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props" Condition="Exists('..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="debug|x64">
<Configuration>debug</Configuration>
@ -27,7 +30,7 @@
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'" Label="Configuration">
@ -36,7 +39,7 @@
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@ -51,13 +54,16 @@
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<OutDir>$(SolutionDir)build\bin\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
<Inf2CatUseLocalTime>
</Inf2CatUseLocalTime>
<EnableInf2cat>false</EnableInf2cat>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<OutDir>$(SolutionDir)build\bin\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
<Inf2CatUseLocalTime>
</Inf2CatUseLocalTime>
<EnableInf2cat>false</EnableInf2cat>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
@ -205,7 +211,20 @@
<ItemGroup>
<MASM Include="code\assembly\AsmDebugger.asm" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props'))" />
</Target>
</Project>

View file

@ -434,4 +434,7 @@
<Filter>code\assembly</Filter>
</MASM>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.SDK.CPP" version="10.0.28000.1839" targetFramework="native" />
<package id="Microsoft.Windows.SDK.CPP.x64" version="10.0.28000.1839" targetFramework="native" />
<package id="Microsoft.Windows.WDK.x64" version="10.0.28000.1839" targetFramework="native" />
</packages>

View file

@ -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="<Your manufacturer name>" ;TODO: Replace with your manufacturer name
DiskName = "hyperlog Installation Disk"
hyperlog.DeviceDesc = "hyperlog Device"
hyperlog.SVCDESC = "hyperlog Service"

View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" />
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" />
<Import Project="..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props" Condition="Exists('..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="debug|x64">
<Configuration>debug</Configuration>
@ -27,7 +30,7 @@
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'" Label="Configuration">
@ -36,7 +39,7 @@
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@ -96,9 +99,6 @@
<ModuleDefinitionFile>hyperlog.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<Inf Include="hyperlog.inf" />
</ItemGroup>
<ItemGroup>
<FilesToPackage Include="$(TargetPath)" />
</ItemGroup>
@ -130,7 +130,20 @@
<ClInclude Include="header\pch.h" />
<ClInclude Include="header\UnloadDll.h" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props'))" />
</Target>
</Project>

View file

@ -20,11 +20,6 @@
<UniqueIdentifier>{21f0281e-fc2a-4e13-97ac-e4b35a05a31e}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<Inf Include="hyperlog.inf">
<Filter>Driver Files</Filter>
</Inf>
</ItemGroup>
<ItemGroup>
<ClCompile Include="code\Logging.c">
<Filter>code</Filter>
@ -101,4 +96,7 @@
<Filter>header\platform</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.SDK.CPP" version="10.0.28000.1839" targetFramework="native" />
<package id="Microsoft.Windows.SDK.CPP.x64" version="10.0.28000.1839" targetFramework="native" />
<package id="Microsoft.Windows.WDK.x64" version="10.0.28000.1839" targetFramework="native" />
</packages>

View file

@ -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}
)

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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
//

View file

@ -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();

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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 <ntddk.h>
# include <ntstrsafe.h>
# include <Windef.h>
#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"

View file

@ -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);

View file

@ -0,0 +1,6 @@
LIBRARY hyperperf
EXPORTS
DllInitialize PRIVATE
DllUnload PRIVATE

View file

@ -0,0 +1,145 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" />
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" />
<Import Project="..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props" Condition="Exists('..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="debug|x64">
<Configuration>debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="release|x64">
<Configuration>release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{360E54B1-0B92-4BCA-8111-4BF384292621}</ProjectGuid>
<TemplateGuid>{1bc93793-694f-48fe-9372-81e2b05556fd}</TemplateGuid>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<Configuration>Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">x64</Platform>
<RootNamespace>hyperperf</RootNamespace>
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<OutDir>$(SolutionDir)build\bin\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<EnableInf2cat>false</EnableInf2cat>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<OutDir>$(SolutionDir)build\bin\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<EnableInf2cat>false</EnableInf2cat>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
<DriverSign>
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
<ClCompile>
<AdditionalIncludeDirectories>$(SolutionDir)\include;$(ProjectDir)header;$(SolutionDir)dependencies;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<PrecompiledHeader>Create</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<EntryPointSymbol />
<NoEntryPoint>true</NoEntryPoint>
<ModuleDefinitionFile>hyperperf.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
<DriverSign>
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
<ClCompile>
<AdditionalIncludeDirectories>$(SolutionDir)\include;$(ProjectDir)header;$(SolutionDir)dependencies;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<PrecompiledHeader>Create</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<LanguageStandard>stdcpp20</LanguageStandard>
<Optimization>Full</Optimization>
</ClCompile>
<Link>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<EntryPointSymbol />
<NoEntryPoint>true</NoEntryPoint>
<ModuleDefinitionFile>hyperperf.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<FilesToPackage Include="$(TargetPath)" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\include\components\callback\code\HyperLogCallback.c" />
<ClCompile Include="..\include\platform\kernel\code\PlatformBroadcast.c" />
<ClCompile Include="..\include\platform\kernel\code\PlatformCpu.c" />
<ClCompile Include="..\include\platform\kernel\code\PlatformIntrinsics.c" />
<ClCompile Include="..\include\platform\kernel\code\PlatformMem.c" />
<ClCompile Include="code\api\PerfApi.c" />
<ClCompile Include="code\broadcast\Broadcast.c" />
<ClCompile Include="code\broadcast\DpcRoutines.c" />
<ClCompile Include="code\common\UnloadDll.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\components\callback\header\HyperLogCallback.h" />
<ClInclude Include="..\include\platform\kernel\header\PlatformBroadcast.h" />
<ClInclude Include="..\include\platform\kernel\header\PlatformCpu.h" />
<ClInclude Include="..\include\platform\kernel\header\PlatformIntrinsics.h" />
<ClInclude Include="..\include\platform\kernel\header\PlatformMem.h" />
<ClInclude Include="header\api\PerfApi.h" />
<ClInclude Include="header\broadcast\Broadcast.h" />
<ClInclude Include="header\broadcast\DpcRoutines.h" />
<ClInclude Include="header\common\UnloadDll.h" />
<ClInclude Include="header\globals\GlobalVariables.h" />
<ClInclude Include="header\pch.h" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props'))" />
</Target>
</Project>

View file

@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="code">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="header">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="header\platform">
<UniqueIdentifier>{1ab177b4-9e6c-460e-834a-8fced04b42a3}</UniqueIdentifier>
</Filter>
<Filter Include="code\platform">
<UniqueIdentifier>{21f0281e-fc2a-4e13-97ac-e4b35a05a31e}</UniqueIdentifier>
</Filter>
<Filter Include="code\api">
<UniqueIdentifier>{09d5457a-bade-4a3f-a171-641110492d57}</UniqueIdentifier>
</Filter>
<Filter Include="code\broadcast">
<UniqueIdentifier>{b8b32a09-61fb-433a-ad79-eb7cfc5f3437}</UniqueIdentifier>
</Filter>
<Filter Include="code\common">
<UniqueIdentifier>{32ea8333-847b-443d-8992-4140d54dc1d3}</UniqueIdentifier>
</Filter>
<Filter Include="header\api">
<UniqueIdentifier>{df6eb164-34b2-4f2a-9530-b88443662fb7}</UniqueIdentifier>
</Filter>
<Filter Include="header\broadcast">
<UniqueIdentifier>{cb4e742a-6e43-4798-af4a-72bcb11089c9}</UniqueIdentifier>
</Filter>
<Filter Include="header\common">
<UniqueIdentifier>{ab21116d-5f5b-4ef8-82bb-6585ac3dec95}</UniqueIdentifier>
</Filter>
<Filter Include="header\globals">
<UniqueIdentifier>{57d56081-eede-41a3-b9f0-e7019d32c986}</UniqueIdentifier>
</Filter>
<Filter Include="code\components">
<UniqueIdentifier>{4f62540b-d186-479e-83a0-1b550134f487}</UniqueIdentifier>
</Filter>
<Filter Include="code\components\callback">
<UniqueIdentifier>{9fe877a7-e261-4579-9752-a3156b6e69d9}</UniqueIdentifier>
</Filter>
<Filter Include="header\components">
<UniqueIdentifier>{8bc2336a-b1c5-4e93-9793-23a5cfdc741d}</UniqueIdentifier>
</Filter>
<Filter Include="header\components\callback">
<UniqueIdentifier>{fc73555b-2be3-4898-bcdb-df83fa3e1388}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\include\platform\kernel\code\PlatformMem.c">
<Filter>code\platform</Filter>
</ClCompile>
<ClCompile Include="code\broadcast\Broadcast.c">
<Filter>code\broadcast</Filter>
</ClCompile>
<ClCompile Include="code\broadcast\DpcRoutines.c">
<Filter>code\broadcast</Filter>
</ClCompile>
<ClCompile Include="code\common\UnloadDll.c">
<Filter>code\common</Filter>
</ClCompile>
<ClCompile Include="code\api\PerfApi.c">
<Filter>code\api</Filter>
</ClCompile>
<ClCompile Include="..\include\platform\kernel\code\PlatformIntrinsics.c">
<Filter>code\platform</Filter>
</ClCompile>
<ClCompile Include="..\include\platform\kernel\code\PlatformBroadcast.c">
<Filter>code\broadcast</Filter>
</ClCompile>
<ClCompile Include="..\include\platform\kernel\code\PlatformCpu.c">
<Filter>code\platform</Filter>
</ClCompile>
<ClCompile Include="..\include\components\callback\code\HyperLogCallback.c">
<Filter>code\components\callback</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\platform\kernel\header\PlatformMem.h">
<Filter>header\platform</Filter>
</ClInclude>
<ClInclude Include="header\broadcast\Broadcast.h">
<Filter>header\broadcast</Filter>
</ClInclude>
<ClInclude Include="header\broadcast\DpcRoutines.h">
<Filter>header\broadcast</Filter>
</ClInclude>
<ClInclude Include="header\common\UnloadDll.h">
<Filter>header\common</Filter>
</ClInclude>
<ClInclude Include="header\globals\GlobalVariables.h">
<Filter>header\globals</Filter>
</ClInclude>
<ClInclude Include="header\api\PerfApi.h">
<Filter>header\api</Filter>
</ClInclude>
<ClInclude Include="..\include\platform\kernel\header\PlatformIntrinsics.h">
<Filter>header\platform</Filter>
</ClInclude>
<ClInclude Include="..\include\platform\kernel\header\PlatformBroadcast.h">
<Filter>header\platform</Filter>
</ClInclude>
<ClInclude Include="..\include\platform\kernel\header\PlatformCpu.h">
<Filter>header\platform</Filter>
</ClInclude>
<ClInclude Include="..\include\components\callback\header\HyperLogCallback.h">
<Filter>header\components\callback</Filter>
</ClInclude>
<ClInclude Include="header\pch.h">
<Filter>header</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.SDK.CPP" version="10.0.28000.1839" targetFramework="native" />
<package id="Microsoft.Windows.SDK.CPP.x64" version="10.0.28000.1839" targetFramework="native" />
<package id="Microsoft.Windows.WDK.x64" version="10.0.28000.1839" targetFramework="native" />
</packages>

View file

@ -1,6 +1,6 @@
/**
* @file PtApi.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @author Masoud Rahimi Jafari (Masoodrahimy1379@gmail.com)
* @brief Tracing routines for HyperTrace module (Intel Processor Trace)
* @details
* @version 0.19
@ -36,26 +36,26 @@ HyperTracePtBuildConfig(const HYPERTRACE_PT_OPERATION_PACKETS * Req,
// If the request specifies neither user nor kernel, default to both
// (matches LBR behaviour when filter is empty).
//
if (Req->TraceUser || Req->TraceKernel)
if (Req->FilterOptions.TraceUser || Req->FilterOptions.TraceKernel)
{
OutCfg->TraceUser = (Req->TraceUser != 0) ? TRUE : FALSE;
OutCfg->TraceKernel = (Req->TraceKernel != 0) ? TRUE : FALSE;
OutCfg->TraceUser = (Req->FilterOptions.TraceUser != 0) ? TRUE : FALSE;
OutCfg->TraceKernel = (Req->FilterOptions.TraceKernel != 0) ? TRUE : FALSE;
}
OutCfg->TargetCr3 = Req->TargetCr3;
OutCfg->TargetCr3 = Req->EnableOptions.Cr3;
if (Req->BufferSize != 0)
{
OutCfg->BufferSize = Req->BufferSize;
}
OutCfg->NumAddrRanges = Req->NumAddrRanges;
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->AddrRanges[Copy];
OutCfg->AddrRanges[Copy] = Req->FilterOptions.AddrRanges[Copy];
}
}
@ -284,6 +284,7 @@ HyperTracePtSize(HYPERTRACE_PT_OPERATION_PACKETS * HyperTraceOperationRequest)
return FALSE;
ProcessorsCount = KeQueryActiveProcessorCount(0);
if (ProcessorsCount > PT_MAX_CPUS_FOR_MMAP)
ProcessorsCount = PT_MAX_CPUS_FOR_MMAP;
@ -405,37 +406,37 @@ HyperTracePtFlush(HYPERTRACE_PT_OPERATION_PACKETS * HyperTraceOperationRequest)
BOOLEAN
HyperTracePtFilter(HYPERTRACE_PT_OPERATION_PACKETS * Req)
{
PT_FILTER_OPTIONS FilterOptions = {0};
BOOLEAN WasEnabled = g_ProcessorTraceEnabled;
BOOLEAN BufferChanged = FALSE;
UINT64 ExistingSize = 0;
UINT32 Copy;
PT_APPLY_CORE_FILTER_REQUEST ApplyCoreFilterReq = {0};
BOOLEAN WasEnabled = g_ProcessorTraceEnabled;
BOOLEAN BufferChanged = FALSE;
UINT64 ExistingSize = 0;
//
// Translate the user-mode packet into PT_FILTER_OPTIONS — the narrow
// 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->TraceUser || Req->TraceKernel)
if (Req->FilterOptions.TraceUser || Req->FilterOptions.TraceKernel)
{
FilterOptions.TraceUser = (Req->TraceUser != 0) ? TRUE : FALSE;
FilterOptions.TraceKernel = (Req->TraceKernel != 0) ? TRUE : FALSE;
ApplyCoreFilterReq.FilterOptions.TraceUser = (Req->FilterOptions.TraceUser != 0) ? TRUE : FALSE;
ApplyCoreFilterReq.FilterOptions.TraceKernel = (Req->FilterOptions.TraceKernel != 0) ? TRUE : FALSE;
}
else
{
FilterOptions.TraceUser = TRUE;
FilterOptions.TraceKernel = TRUE;
}
FilterOptions.TargetCr3 = Req->TargetCr3;
FilterOptions.BufferSize = Req->BufferSize;
FilterOptions.NumAddrRanges = Req->NumAddrRanges;
if (FilterOptions.NumAddrRanges > PT_MAX_ADDR_RANGES)
FilterOptions.NumAddrRanges = PT_MAX_ADDR_RANGES;
for (Copy = 0; Copy < FilterOptions.NumAddrRanges; Copy++)
{
FilterOptions.AddrRanges[Copy] = Req->AddrRanges[Copy];
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.
//
@ -443,7 +444,8 @@ HyperTracePtFilter(HYPERTRACE_PT_OPERATION_PACKETS * Req)
{
ExistingSize = g_PtStateList[0].Config.BufferSize;
}
if (FilterOptions.BufferSize != 0 && FilterOptions.BufferSize != ExistingSize)
if (ApplyCoreFilterReq.BufferSize != 0 && ApplyCoreFilterReq.BufferSize != ExistingSize)
{
BufferChanged = TRUE;
}
@ -495,8 +497,8 @@ HyperTracePtFilter(HYPERTRACE_PT_OPERATION_PACKETS * Req)
// unchanged. Force FilterOptions.BufferSize=0 so PtFilter on each core
// keeps the buffer that's already allocated, then broadcast.
//
FilterOptions.BufferSize = 0;
BroadcastFilterPtOnAllCores(&FilterOptions);
ApplyCoreFilterReq.BufferSize = 0;
BroadcastFilterPtOnAllCores(&ApplyCoreFilterReq);
}
if (Req != NULL)

View file

@ -11,7 +11,7 @@
#include "pch.h"
/**
* @brief Initialize the hyper trace module callbacks
* @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

View file

@ -153,10 +153,12 @@ BroadcastFlushPtOnAllCores()
* 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_FILTER_OPTIONS * FilterOptions)
BroadcastFilterPtOnAllCores(PT_APPLY_CORE_FILTER_REQUEST * FilterRequest)
{
KeGenericCallDpc(DpcRoutineFilterPt, (PVOID)FilterOptions);
KeGenericCallDpc(DpcRoutineFilterPt, (PVOID)FilterRequest);
}

View file

@ -198,8 +198,11 @@ DpcRoutineEnablePt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO
//
PtStart();
KeSignalCallDpcSynchronize(SystemArgument2);
KeSignalCallDpcDone(SystemArgument1);
// ------------------------------------------------------------------------------
// Synchronize the end of this routine with the caller
//
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
return TRUE;
}
@ -214,8 +217,11 @@ DpcRoutineDisablePt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PV
PtStop();
KeSignalCallDpcSynchronize(SystemArgument2);
KeSignalCallDpcDone(SystemArgument1);
// ------------------------------------------------------------------------------
// Synchronize the end of this routine with the caller
//
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
return TRUE;
}
@ -230,8 +236,11 @@ DpcRoutinePausePt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOI
PtPause();
KeSignalCallDpcSynchronize(SystemArgument2);
KeSignalCallDpcDone(SystemArgument1);
// ------------------------------------------------------------------------------
// Synchronize the end of this routine with the caller
//
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
return TRUE;
}
@ -246,8 +255,11 @@ DpcRoutineResumePt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO
PtResume();
KeSignalCallDpcSynchronize(SystemArgument2);
KeSignalCallDpcDone(SystemArgument1);
// ------------------------------------------------------------------------------
// Synchronize the end of this routine with the caller
//
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
return TRUE;
}
@ -269,8 +281,11 @@ DpcRoutineSizePt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID
if (Sizes != NULL && Core < PT_MAX_CPUS_FOR_MMAP)
Sizes[Core] = PtSize();
KeSignalCallDpcSynchronize(SystemArgument2);
KeSignalCallDpcDone(SystemArgument1);
// ------------------------------------------------------------------------------
// Synchronize the end of this routine with the caller
//
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
return TRUE;
}
@ -285,8 +300,11 @@ DpcRoutineDumpPt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID
PtDump();
KeSignalCallDpcSynchronize(SystemArgument2);
KeSignalCallDpcDone(SystemArgument1);
// ------------------------------------------------------------------------------
// Synchronize the end of this routine with the caller
//
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
return TRUE;
}
@ -301,15 +319,18 @@ DpcRoutineFlushPt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOI
PtFlush();
KeSignalCallDpcSynchronize(SystemArgument2);
KeSignalCallDpcDone(SystemArgument1);
// ------------------------------------------------------------------------------
// 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_FILTER_OPTIONS * supplied by the
* 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.
*/
@ -318,9 +339,12 @@ DpcRoutineFilterPt(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO
{
UNREFERENCED_PARAMETER(Dpc);
PtFilter((const PT_FILTER_OPTIONS *)DeferredContext);
PtFilter((const PT_APPLY_CORE_FILTER_REQUEST *)DeferredContext);
// ------------------------------------------------------------------------------
// Synchronize the end of this routine with the caller
//
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
KeSignalCallDpcSynchronize(SystemArgument2);
KeSignalCallDpcDone(SystemArgument1);
return TRUE;
}

View file

@ -1,6 +1,6 @@
/**
* @file Pt.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @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
@ -348,7 +348,7 @@ PtEngineInitDefaultConfig(PT_TRACE_CONFIG * Config)
Config->TargetCr3 = 0;
Config->NumAddrRanges = 0;
Config->EnableBranch = TRUE;
Config->EnableTsc = TRUE;
Config->EnableTsc = FALSE;
Config->EnableMtc = FALSE;
Config->EnableCyc = FALSE;
Config->EnableRetCompression = FALSE;
@ -639,9 +639,9 @@ PtEngineStart(PT_PER_CPU * Cpu)
if (g_RunningOnHypervisorEnvironment)
{
IsOnVmxRootMode = g_Callbacks.VmFuncVmxGetCurrentExecutionMode();
LogInfo("PT: PtEngineStart on core %u (vmx-root=%u)\n",
KeGetCurrentProcessorNumberEx(NULL),
(UINT32)IsOnVmxRootMode);
// LogInfo("PT: PtEngineStart on core %u (vmx-root=%u)\n",
// KeGetCurrentProcessorNumberEx(NULL),
// (UINT32)IsOnVmxRootMode);
}
//
@ -826,9 +826,9 @@ PtEngineStop(PT_PER_CPU * Cpu, PT_OUTPUT_BUFFER * Out)
if (g_RunningOnHypervisorEnvironment)
{
IsOnVmxRootMode = g_Callbacks.VmFuncVmxGetCurrentExecutionMode();
LogInfo("PT: PtEngineStop on core %u (vmx-root=%u)\n",
KeGetCurrentProcessorNumberEx(NULL),
(UINT32)IsOnVmxRootMode);
// LogInfo("PT: PtEngineStop on core %u (vmx-root=%u)\n",
// KeGetCurrentProcessorNumberEx(NULL),
// (UINT32)IsOnVmxRootMode);
}
//
@ -1027,9 +1027,9 @@ PtCheck()
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");
// 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;
@ -1071,7 +1071,7 @@ PtAllocateAllCpuBuffers()
if (PtEngineAllocateBuffers(Cpu, &Cfg) != 0)
{
LogInfo("PT: buffer allocation failed on core %u\n", i);
// LogInfo("PT: buffer allocation failed on core %u\n", i);
return FALSE;
}
}
@ -1233,13 +1233,13 @@ PtStart()
// 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);
// 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);
// LogInfo("PT: PtEngineStart failed on core %u (state=%d)\n", CurrentCore, Cpu->State);
return FALSE;
}
@ -1263,7 +1263,7 @@ PtStop()
CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
Cpu = &g_PtStateList[CurrentCore];
LogInfo("PT: stopping trace on core %d\n", CurrentCore);
// LogInfo("PT: stopping trace on core %d\n", CurrentCore);
PtEngineStop(Cpu, NULL);
}
@ -1284,7 +1284,7 @@ PtPause()
CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
Cpu = &g_PtStateList[CurrentCore];
LogInfo("PT: pausing trace on core %u\n", CurrentCore);
// LogInfo("PT: pausing trace on core %u\n", CurrentCore);
PtEnginePause(Cpu);
}
@ -1304,7 +1304,7 @@ PtResume()
CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
Cpu = &g_PtStateList[CurrentCore];
LogInfo("PT: resuming trace on core %u\n", CurrentCore);
// LogInfo("PT: resuming trace on core %u\n", CurrentCore);
PtEngineResume(Cpu);
}
@ -1399,14 +1399,14 @@ PtDump()
* handles that case before broadcasting.
*/
VOID
PtFilter(const PT_FILTER_OPTIONS * FilterOptions)
PtFilter(const PT_APPLY_CORE_FILTER_REQUEST * FilterRequest)
{
UINT32 CurrentCore;
PT_PER_CPU * Cpu;
UINT32 i;
PT_CAPABILITIES Caps = {0};
if (g_PtStateList == NULL || FilterOptions == NULL)
if (g_PtStateList == NULL || FilterRequest == NULL)
return;
if (PtEngineQueryCapabilities(&Caps) != 0)
@ -1415,7 +1415,7 @@ PtFilter(const PT_FILTER_OPTIONS * FilterOptions)
CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
Cpu = &g_PtStateList[CurrentCore];
LogInfo("PT: applying filter on core %u\n", CurrentCore);
// LogInfo("PT: applying filter on core %u\n", CurrentCore);
//
// Stop tracing on this CPU first so we can safely mutate Cpu->Config
@ -1429,42 +1429,42 @@ PtFilter(const PT_FILTER_OPTIONS * FilterOptions)
//
// Apply only the user-tunable fields to this CPU's per-CPU config.
//
Cpu->Config.TraceUser = FilterOptions->TraceUser;
Cpu->Config.TraceKernel = FilterOptions->TraceKernel;
Cpu->Config.TraceUser = (BOOLEAN)FilterRequest->FilterOptions.TraceUser;
Cpu->Config.TraceKernel = (BOOLEAN)FilterRequest->FilterOptions.TraceKernel;
if (FilterOptions->TargetCr3 != 0 && !Caps.Cr3Filtering)
if (FilterRequest->EnableOptions.Cr3 != 0 && !Caps.Cr3Filtering)
{
LogInfo("PT: CR3 filtering requested but not supported by CPU\n");
// LogInfo("PT: CR3 filtering requested but not supported by CPU\n");
Cpu->Config.TargetCr3 = 0;
}
else
{
Cpu->Config.TargetCr3 = FilterOptions->TargetCr3;
Cpu->Config.TargetCr3 = FilterRequest->EnableOptions.Cr3;
}
if (FilterOptions->NumAddrRanges > Caps.NumAddrRanges)
if (FilterRequest->FilterOptions.NumAddrRanges > Caps.NumAddrRanges)
{
LogInfo("PT: requested %u IP filter ranges, but CPU only supports %u\n", 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 (FilterOptions->NumAddrRanges > 0 && !Caps.IpFiltering)
else if (FilterRequest->FilterOptions.NumAddrRanges > 0 && !Caps.IpFiltering)
{
LogInfo("PT: IP filtering requested but not supported by CPU\n");
// LogInfo("PT: IP filtering requested but not supported by CPU\n");
Cpu->Config.NumAddrRanges = 0;
}
else
{
Cpu->Config.NumAddrRanges = FilterOptions->NumAddrRanges;
Cpu->Config.NumAddrRanges = FilterRequest->FilterOptions.NumAddrRanges;
}
if (FilterOptions->BufferSize != 0)
if (FilterRequest->BufferSize != 0)
{
Cpu->Config.BufferSize = FilterOptions->BufferSize;
Cpu->Config.BufferSize = FilterRequest->BufferSize;
}
for (i = 0; i < PT_MAX_ADDR_RANGES; i++)
{
Cpu->Config.AddrRanges[i] = FilterOptions->AddrRanges[i];
Cpu->Config.AddrRanges[i] = FilterRequest->FilterOptions.AddrRanges[i];
}
//
@ -1499,7 +1499,7 @@ PtFlush()
CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
Cpu = &g_PtStateList[CurrentCore];
LogInfo("PT: flush on core %u\n", CurrentCore);
// LogInfo("PT: flush on core %u\n", CurrentCore);
if (Cpu->State == PT_STATE_TRACING || Cpu->State == PT_STATE_PAUSED)
{

View file

@ -1,6 +1,6 @@
/**
* @file PtApi.h
* @author Sina Karvandi (sina@hyperdbg.org)
* @author Masoud Rahimi Jafari (Masoodrahimy1379@gmail.com)
* @brief Header for PT tracing routines for HyperTrace module (Intel Processor Trace)
* @details
* @version 0.19

View file

@ -50,4 +50,4 @@ VOID
BroadcastFlushPtOnAllCores();
VOID
BroadcastFilterPtOnAllCores(PT_FILTER_OPTIONS * FilterOptions);
BroadcastFilterPtOnAllCores(PT_APPLY_CORE_FILTER_REQUEST * FilterRequest);

View file

@ -67,20 +67,6 @@
#include "platform/kernel/header/PlatformIo.h"
#include "platform/kernel/header/PlatformEvent.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"
//
// Unload function (to be called when the driver is unloaded)
//
@ -113,6 +99,20 @@
#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
//

View file

@ -1,6 +1,6 @@
/**
* @file Pt.h
* @author Sina Karvandi (sina@hyperdbg.org)
* @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
@ -12,42 +12,10 @@
*/
#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.
*
@ -63,6 +31,17 @@ typedef struct _PT_USER_MAPPING
} 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 //
//////////////////////////////////////////////////
@ -97,14 +76,14 @@ 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
// 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_FILTER_OPTIONS * FilterOptions);
PtFilter(const PT_APPLY_CORE_FILTER_REQUEST * FilterRequest);
//
// PASSIVE_LEVEL helpers — call before / after the per-core DPC broadcasts.

View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" />
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" />
<Import Project="..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props" Condition="Exists('..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="debug|x64">
<Configuration>debug</Configuration>
@ -27,7 +30,7 @@
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'" Label="Configuration">
@ -36,7 +39,7 @@
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@ -131,7 +134,20 @@
<ClInclude Include="header\pch.h" />
<ClInclude Include="header\pt\Pt.h" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props'))" />
</Target>
</Project>

View file

@ -149,4 +149,7 @@
<Filter>header\components\callback</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.SDK.CPP" version="10.0.28000.1839" targetFramework="native" />
<package id="Microsoft.Windows.SDK.CPP.x64" version="10.0.28000.1839" targetFramework="native" />
<package id="Microsoft.Windows.WDK.x64" version="10.0.28000.1839" targetFramework="native" />
</packages>

View file

@ -72,7 +72,8 @@ typedef wchar_t WCHAR;
typedef void VOID;
typedef size_t SIZE_T;
typedef size_t SIZE_T;
typedef SIZE_T * PSIZE_T;
typedef signed long long INT64, *PINT64;
typedef unsigned long long UINT64, *PUINT64;
@ -83,6 +84,13 @@ 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
//
@ -93,6 +101,10 @@ typedef UINT16 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

View file

@ -18,10 +18,10 @@
//////////////////////////////////////////////////
#define VERSION_MAJOR 0
#define VERSION_MINOR 19
#define VERSION_MINOR 21
#define VERSION_PATCH 0
#define BETA_VERSION 1
#define BETA_VERSION FALSE
//
// Example of __DATE__ string: "Jul 27 2012"
@ -110,7 +110,7 @@ const UCHAR BuildDateTime[] = {
// Complete version as a string
# if BETA_VERSION == 0
# 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"

View file

@ -420,3 +420,11 @@
*/
#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)

View file

@ -1,6 +1,6 @@
/**
* @file PtDefinitions.h
* @author Sina Karvandi (sina@hyperdbg.org)
* @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
@ -48,7 +48,6 @@
//////////////////////////////////////////////////
#define PT_PAGE_SIZE 0x1000ULL /* 4 KB */
#define PT_DEFAULT_BUFFER_SIZE 0x200000ULL /* 2 MB */
#define PT_OVERFLOW_SIZE PT_PAGE_SIZE /* 4 KB overflow landing zone */
#define PT_MAX_ADDR_RANGES 4

View file

@ -1356,27 +1356,78 @@ typedef enum _HYPERTRACE_PT_OPERATION_REQUEST_TYPE
HYPERTRACE_PT_OPERATION_REQUEST_TYPE_PAUSE,
HYPERTRACE_PT_OPERATION_REQUEST_TYPE_RESUME,
HYPERTRACE_PT_OPERATION_REQUEST_TYPE_SIZE,
HYPERTRACE_PT_OPERATION_REQUEST_TYPE_DUMP,
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
*
* Configuration fields (TraceUser/TraceKernel/TargetCr3/BufferSize/
* NumAddrRanges/AddrRanges) are populated by the caller for ENABLE
* and FILTER operations. For other operations they are ignored.
*
* BufferSize must be a power of two multiple of 4 KB (4KB ... 128MB).
* Pass 0 to keep the existing per-CPU value (default 2 MB on first
* enable).
*
* For SIZE operations the kernel fills NumCpus and BytesPerCpu[]
* with each CPU's current PT output position, i.e. how many bytes
* of valid trace data are currently sitting in that CPU's main +
* overflow buffer; the rest of the packet is unused on output.
*/
typedef struct _HYPERTRACE_PT_OPERATION_PACKETS
{
@ -1384,21 +1435,26 @@ typedef struct _HYPERTRACE_PT_OPERATION_PACKETS
UINT32 KernelStatus;
//
// Filter / config (used by FILTER and ENABLE)
// Enable
//
UINT32 TraceUser; /* Boolean: trace CPL > 0 */
UINT32 TraceKernel; /* Boolean: trace CPL == 0 */
UINT64 TargetCr3; /* CR3 to filter by (0 = no filter) */
UINT64 BufferSize; /* Output buffer size (0 = keep current) */
UINT32 NumAddrRanges; /* Number of valid AddrRanges entries */
UINT32 Reserved; /* Padding to keep the array 8-aligned */
PT_ADDR_RANGE AddrRanges[PT_MAX_ADDR_RANGES];
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 */
//
// SIZE output: per-CPU bytes-written snapshot
// Filter
//
UINT32 NumCpus; /* CPUs populated in BytesPerCpu */
UINT32 Reserved2; /* Padding to 8-align the array */
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;

View file

@ -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();

View file

@ -49,6 +49,9 @@ 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();
@ -306,6 +309,16 @@ hyperdbg_u_perform_smi_operation(SMI_OPERATION_PACKETS * SmiOperation);
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

View file

@ -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;

View file

@ -11,7 +11,9 @@
*/
#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
@ -46,7 +48,7 @@ typedef struct _IMAGE_FILE_HEADER
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
#define IMAGE_SIZEOF_SHORT_NAME 8
# define IMAGE_SIZEOF_SHORT_NAME 8
typedef struct _IMAGE_SECTION_HEADER
{
@ -66,7 +68,7 @@ typedef struct _IMAGE_SECTION_HEADER
DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
*/
#endif // _WIN32
typedef struct _PE_IMAGE_READER
{

View file

@ -30,11 +30,67 @@
# error "This code cannot compile on non-Windows, non-Linux, and non-BSD platforms"
#endif
// Windows source annotation language (SAL) not present in Linux, so defining them here for the compiler
#ifdef HYPERDBG_ENV_LINUX
# define _In_
# define _Out_
# define _Inout_
#endif
// 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 <wchar.h>
// POSIX sleep primitives (usleep) backing the Win32 Sleep() shim below
# include <unistd.h>
// 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

View file

@ -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 <windows.h> (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 <stddef.h> // 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

View file

@ -325,6 +325,87 @@ CpuReadTscp(UINT32 * Aux)
#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 //
//////////////////////////////////////////////////

View file

@ -17,6 +17,31 @@
# 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 ...
/////////////////////////////////////////////////

View file

@ -207,6 +207,25 @@ extern inline UINT64
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 //
//////////////////////////////////////////////////

View file

@ -22,6 +22,9 @@
// Functions //
//////////////////////////////////////////////////
INT
PlatformSprintf(char * Buffer, SIZE_T BufferSize, const char * Format, ...);
VOID
PlatformFreeMemory(PVOID Memory);

View file

@ -83,10 +83,32 @@ CpuReadTsc(VOID)
// 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
VOID
CpuPause(VOID)
{
#if defined(_WIN32) || defined(_WIN64)
@ -97,3 +119,83 @@ CpuPause(VOID)
# 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
}

View file

@ -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

View file

@ -13,6 +13,11 @@
#if defined(__linux__)
# include "../header/platform-lib-calls.h"
# include <unistd.h>
# include <sched.h>
# include <sys/syscall.h>
# include <errno.h>
# include <stdint.h>
#endif // defined(__linux__)
/**
@ -71,3 +76,538 @@ PlatformZeroMemory(PVOID Buffer, SIZE_T Size)
# 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
}

View file

@ -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

View file

@ -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 <signal.h>
# include <pthread.h>
//
// 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

View file

@ -41,6 +41,12 @@ CpuCpuIdEx(INT32 * CpuInfo, INT32 FunctionId, INT32 SubFunctionId);
UINT64
CpuReadTsc(VOID);
//
// RDTSCP
//
UINT64
CpuReadTscp(UINT32 * Aux);
//////////////////////////////////////////////////
// Misc Instructions //
//////////////////////////////////////////////////
@ -49,4 +55,26 @@ CpuReadTsc(VOID);
// PAUSE
//
VOID
CpuPause(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);

View file

@ -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);

View file

@ -35,3 +35,103 @@ PlatformStrDup(const char * Str);
//
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);

View file

@ -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);

View file

@ -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);

View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" />
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" />
<Import Project="..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props" Condition="Exists('..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="debug|x64">
<Configuration>debug</Configuration>
@ -31,6 +34,7 @@
</ItemGroup>
<ItemGroup>
<None Include="kdserial.def" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="kdcom.h" />
@ -45,7 +49,7 @@
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
<RootNamespace>kdserial</RootNamespace>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<TargetPlatformVersion>10.0.10135.0</TargetPlatformVersion>
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup>
@ -77,6 +81,7 @@
<GenerateManifest>false</GenerateManifest>
<OutDir>$(SolutionDir)build\bin\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<EnableInf2cat>false</EnableInf2cat>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
<TargetName>kdserial</TargetName>
@ -84,6 +89,7 @@
<GenerateManifest>false</GenerateManifest>
<OutDir>$(SolutionDir)build\bin\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)build\obj\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<EnableInf2cat>false</EnableInf2cat>
</PropertyGroup>
<PropertyGroup Label="Vcpkg">
<VcpkgEnabled>false</VcpkgEnabled>
@ -138,5 +144,15 @@
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props'))" />
</Target>
</Project>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.SDK.CPP" version="10.0.28000.1839" targetFramework="native" />
<package id="Microsoft.Windows.SDK.CPP.x64" version="10.0.28000.1839" targetFramework="native" />
<package id="Microsoft.Windows.WDK.x64" version="10.0.28000.1839" targetFramework="native" />
</packages>

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